From 4fd287655a72b9aea14cdac715ad5b90ed082ed2 Mon Sep 17 00:00:00 2001 From: Raghuram Subramani Date: Sun, 19 Jun 2022 19:47:51 +0530 Subject: add circuitpython code --- circuitpython/lib/README.md | 3 + .../lib/adafruit_floppy/LICENSES/CC-BY-4.0.txt | 156 + .../lib/adafruit_floppy/LICENSES/CC0-1.0.txt | 121 + circuitpython/lib/adafruit_floppy/LICENSES/MIT.txt | 9 + circuitpython/lib/adafruit_floppy/Makefile | 14 + circuitpython/lib/adafruit_floppy/README.md | 45 + .../lib/adafruit_floppy/code-of-conduct.md | 127 + .../adafruit_floppy/examples/fat_test/fat_test.ino | 157 + .../floppy_capture_track_test.ino | 112 + .../examples/greaseweazle/greaseweazle.ino | 525 + .../adafruit_floppy/examples/mfm_test/mfm_test.ino | 138 + .../adafruit_floppy/examples/msd_test/msd_test.ino | 163 + circuitpython/lib/adafruit_floppy/flux.txt | 1 + circuitpython/lib/adafruit_floppy/flux.txt.license | 3 + .../lib/adafruit_floppy/images/rabbit.png | Bin 0 -> 23110 bytes circuitpython/lib/adafruit_floppy/images/readme | 1 + .../lib/adafruit_floppy/library.properties | 10 + circuitpython/lib/adafruit_floppy/license.txt | 10 + circuitpython/lib/adafruit_floppy/mfm.license | 3 + .../lib/adafruit_floppy/src/Adafruit_Floppy.cpp | 524 + .../lib/adafruit_floppy/src/Adafruit_Floppy.h | 150 + .../adafruit_floppy/src/Adafruit_MFM_Floppy.cpp | 206 + circuitpython/lib/adafruit_floppy/src/mfm_impl.h | 266 + .../lib/adafruit_floppy/standalone/main.c | 49 + circuitpython/lib/axtls/Makefile | 185 + circuitpython/lib/axtls/README | 3 + circuitpython/lib/axtls/axtlswrap/Makefile | 68 + circuitpython/lib/axtls/axtlswrap/axtlswrap.c | 396 + circuitpython/lib/axtls/bindings/Config.in | 105 + circuitpython/lib/axtls/bindings/Makefile | 86 + circuitpython/lib/axtls/bindings/README | 43 + circuitpython/lib/axtls/bindings/csharp/Makefile | 35 + circuitpython/lib/axtls/bindings/csharp/axTLS.cs | 491 + .../lib/axtls/bindings/generate_SWIG_interface.pl | 392 + .../lib/axtls/bindings/generate_interface.pl | 322 + circuitpython/lib/axtls/bindings/java/Makefile | 94 + circuitpython/lib/axtls/bindings/java/SSL.java | 137 + circuitpython/lib/axtls/bindings/java/SSLCTX.java | 229 + .../lib/axtls/bindings/java/SSLClient.java | 81 + .../lib/axtls/bindings/java/SSLReadHolder.java | 61 + .../lib/axtls/bindings/java/SSLServer.java | 72 + circuitpython/lib/axtls/bindings/java/SSLUtil.java | 116 + circuitpython/lib/axtls/bindings/lua/Makefile | 67 + circuitpython/lib/axtls/bindings/perl/Makefile | 91 + circuitpython/lib/axtls/bindings/vbnet/Makefile | 35 + circuitpython/lib/axtls/bindings/vbnet/axTLSvb.vb | 200 + circuitpython/lib/axtls/config/Config.in | 130 + circuitpython/lib/axtls/config/JMeter.jmx | 247 + circuitpython/lib/axtls/config/Rules.mak | 221 + circuitpython/lib/axtls/config/axhttpd.aip | 136 + circuitpython/lib/axtls/config/axtls.RES | Bin 0 -> 22748 bytes circuitpython/lib/axtls/config/axtls.rc | 32 + circuitpython/lib/axtls/config/linuxconfig | 126 + circuitpython/lib/axtls/config/makefile.conf | 138 + .../lib/axtls/config/makefile.dotnet.conf | 65 + circuitpython/lib/axtls/config/makefile.java.conf | 58 + circuitpython/lib/axtls/config/makefile.post | 19 + .../config/scripts/config/Kconfig-language.txt | 255 + .../lib/axtls/config/scripts/config/Makefile | 121 + .../lib/axtls/config/scripts/config/conf.c | 583 + .../lib/axtls/config/scripts/config/confdata.c | 458 + .../lib/axtls/config/scripts/config/expr.c | 1099 ++ .../lib/axtls/config/scripts/config/expr.h | 195 + .../config/scripts/config/lex.zconf.c_shipped | 3688 ++++++ .../lib/axtls/config/scripts/config/lkc.h | 123 + .../lib/axtls/config/scripts/config/lkc_proto.h | 40 + .../config/scripts/config/lxdialog/BIG.FAT.WARNING | 4 + .../config/scripts/config/lxdialog/checklist.c | 372 + .../axtls/config/scripts/config/lxdialog/colors.h | 161 + .../axtls/config/scripts/config/lxdialog/dialog.h | 199 + .../config/scripts/config/lxdialog/inputbox.c | 240 + .../axtls/config/scripts/config/lxdialog/menubox.c | 438 + .../axtls/config/scripts/config/lxdialog/msgbox.c | 85 + .../axtls/config/scripts/config/lxdialog/textbox.c | 556 + .../axtls/config/scripts/config/lxdialog/util.c | 375 + .../axtls/config/scripts/config/lxdialog/yesno.c | 118 + .../lib/axtls/config/scripts/config/mconf.c | 977 ++ .../lib/axtls/config/scripts/config/menu.c | 390 + .../lib/axtls/config/scripts/config/mkconfigs | 67 + .../lib/axtls/config/scripts/config/symbol.c | 809 ++ .../lib/axtls/config/scripts/config/util.c | 109 + .../lib/axtls/config/scripts/config/zconf.l | 366 + .../config/scripts/config/zconf.tab.c_shipped | 2130 ++++ .../config/scripts/config/zconf.tab.h_shipped | 125 + .../lib/axtls/config/scripts/config/zconf.y | 690 ++ circuitpython/lib/axtls/config/upyconfig | 117 + circuitpython/lib/axtls/config/upyconfig.client | 116 + circuitpython/lib/axtls/config/win32config | 119 + circuitpython/lib/axtls/crypto/Makefile | 52 + circuitpython/lib/axtls/crypto/aes.c | 453 + circuitpython/lib/axtls/crypto/bigint.c | 1516 +++ circuitpython/lib/axtls/crypto/bigint.h | 99 + circuitpython/lib/axtls/crypto/bigint_impl.h | 131 + circuitpython/lib/axtls/crypto/crypto.h | 275 + circuitpython/lib/axtls/crypto/crypto_misc.c | 390 + circuitpython/lib/axtls/crypto/hmac.c | 145 + circuitpython/lib/axtls/crypto/md5.c | 433 + circuitpython/lib/axtls/crypto/os_int.h | 67 + circuitpython/lib/axtls/crypto/rc4.c | 97 + circuitpython/lib/axtls/crypto/rsa.c | 284 + circuitpython/lib/axtls/crypto/sha1.c | 249 + circuitpython/lib/axtls/crypto/sha256.c | 278 + circuitpython/lib/axtls/crypto/sha384.c | 77 + circuitpython/lib/axtls/crypto/sha512.c | 220 + circuitpython/lib/axtls/docsrc/Makefile | 39 + circuitpython/lib/axtls/docsrc/axTLS.dox | 1372 +++ circuitpython/lib/axtls/docsrc/doco_footer.html | 3 + circuitpython/lib/axtls/docsrc/images/axolotl.jpg | Bin 0 -> 3041 bytes circuitpython/lib/axtls/docsrc/images/tsbasbw.gif | Bin 0 -> 2481 bytes circuitpython/lib/axtls/httpd/Config.in | 160 + circuitpython/lib/axtls/httpd/Makefile | 130 + circuitpython/lib/axtls/httpd/axhttp.h | 156 + circuitpython/lib/axtls/httpd/axhttpd.c | 713 ++ circuitpython/lib/axtls/httpd/htpasswd.c | 142 + .../httpd/kepler-1.1-snapshot-20070521-1825.tar.gz | Bin 0 -> 768249 bytes circuitpython/lib/axtls/httpd/kepler.patch | 64 + circuitpython/lib/axtls/httpd/proc.c | 1254 ++ circuitpython/lib/axtls/httpd/tdate_parse.c | 115 + circuitpython/lib/axtls/samples/Config.in | 63 + circuitpython/lib/axtls/samples/Makefile | 62 + circuitpython/lib/axtls/samples/c/Makefile | 77 + circuitpython/lib/axtls/samples/c/axssl.c | 904 ++ circuitpython/lib/axtls/samples/csharp/Makefile | 48 + circuitpython/lib/axtls/samples/csharp/axssl.cs | 758 ++ circuitpython/lib/axtls/samples/java/Makefile | 51 + circuitpython/lib/axtls/samples/java/axssl.java | 760 ++ circuitpython/lib/axtls/samples/java/manifest.mf | 1 + circuitpython/lib/axtls/samples/lua/Makefile | 43 + circuitpython/lib/axtls/samples/lua/axssl.lua | 562 + circuitpython/lib/axtls/samples/perl/Makefile | 43 + circuitpython/lib/axtls/samples/perl/axssl.pl | 634 + circuitpython/lib/axtls/samples/vbnet/Makefile | 48 + circuitpython/lib/axtls/samples/vbnet/axssl.vb | 702 ++ circuitpython/lib/axtls/ssl/BigIntConfig.in | 145 + circuitpython/lib/axtls/ssl/Config.in | 341 + circuitpython/lib/axtls/ssl/Makefile | 125 + circuitpython/lib/axtls/ssl/asn1.c | 776 ++ circuitpython/lib/axtls/ssl/cert.h | 54 + circuitpython/lib/axtls/ssl/crypto_misc.h | 213 + circuitpython/lib/axtls/ssl/gen_cert.c | 370 + circuitpython/lib/axtls/ssl/loader.c | 492 + circuitpython/lib/axtls/ssl/openssl.c | 318 + circuitpython/lib/axtls/ssl/os_port.c | 0 circuitpython/lib/axtls/ssl/os_port.h | 7 + circuitpython/lib/axtls/ssl/p12.c | 483 + circuitpython/lib/axtls/ssl/private_key.h | 54 + circuitpython/lib/axtls/ssl/ssl.h | 539 + circuitpython/lib/axtls/ssl/test/Makefile | 100 + circuitpython/lib/axtls/ssl/test/axTLS.ca_key.pem | 27 + circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.cer | Bin 0 -> 786 bytes circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.pem | 19 + .../lib/axtls/ssl/test/axTLS.ca_x509_sha256.pem | 19 + .../lib/axtls/ssl/test/axTLS.encrypted.p8 | Bin 0 -> 673 bytes .../lib/axtls/ssl/test/axTLS.encrypted_pem.p8 | 17 + circuitpython/lib/axtls/ssl/test/axTLS.key_1024 | Bin 0 -> 609 bytes .../lib/axtls/ssl/test/axTLS.key_1024.pem | 15 + circuitpython/lib/axtls/ssl/test/axTLS.key_2048 | Bin 0 -> 1192 bytes .../lib/axtls/ssl/test/axTLS.key_2048.pem | 27 + circuitpython/lib/axtls/ssl/test/axTLS.key_4096 | Bin 0 -> 2347 bytes .../lib/axtls/ssl/test/axTLS.key_4096.pem | 51 + .../lib/axtls/ssl/test/axTLS.key_aes128.pem | 18 + .../lib/axtls/ssl/test/axTLS.key_aes256.pem | 18 + .../lib/axtls/ssl/test/axTLS.key_device.pem | 27 + .../lib/axtls/ssl/test/axTLS.key_end_chain.pem | 27 + .../axtls/ssl/test/axTLS.key_intermediate_ca.pem | 27 + .../axtls/ssl/test/axTLS.key_intermediate_ca2.pem | 27 + circuitpython/lib/axtls/ssl/test/axTLS.noname.p12 | Bin 0 -> 1612 bytes .../lib/axtls/ssl/test/axTLS.unencrypted.p8 | Bin 0 -> 635 bytes .../lib/axtls/ssl/test/axTLS.unencrypted_pem.p8 | 16 + circuitpython/lib/axtls/ssl/test/axTLS.withCA.p12 | Bin 0 -> 2521 bytes .../lib/axtls/ssl/test/axTLS.withoutCA.p12 | Bin 0 -> 1702 bytes .../lib/axtls/ssl/test/axTLS.x509_1024.cer | Bin 0 -> 604 bytes .../lib/axtls/ssl/test/axTLS.x509_1024.pem | 15 + .../lib/axtls/ssl/test/axTLS.x509_1024_sha256.pem | 15 + .../lib/axtls/ssl/test/axTLS.x509_1024_sha384.pem | 15 + .../lib/axtls/ssl/test/axTLS.x509_1024_sha512.pem | 15 + .../lib/axtls/ssl/test/axTLS.x509_2048.cer | Bin 0 -> 736 bytes .../lib/axtls/ssl/test/axTLS.x509_2048.pem | 18 + .../lib/axtls/ssl/test/axTLS.x509_4096.cer | Bin 0 -> 992 bytes .../lib/axtls/ssl/test/axTLS.x509_4096.pem | 23 + .../lib/axtls/ssl/test/axTLS.x509_aes128.pem | 15 + .../lib/axtls/ssl/test/axTLS.x509_aes256.pem | 15 + .../lib/axtls/ssl/test/axTLS.x509_bad_after.pem | 15 + .../lib/axtls/ssl/test/axTLS.x509_bad_before.pem | 15 + .../lib/axtls/ssl/test/axTLS.x509_device.cer | Bin 0 -> 466 bytes .../lib/axtls/ssl/test/axTLS.x509_device.pem | 34 + .../lib/axtls/ssl/test/axTLS.x509_end_chain.pem | 19 + .../axtls/ssl/test/axTLS.x509_end_chain_bad.pem | 19 + .../axtls/ssl/test/axTLS.x509_intermediate_ca.pem | 19 + .../axtls/ssl/test/axTLS.x509_intermediate_ca2.pem | 37 + circuitpython/lib/axtls/ssl/test/ca-bundle.crt | 3585 ++++++ .../lib/axtls/ssl/test/camster_duckdns_org.crt | 31 + circuitpython/lib/axtls/ssl/test/comodo.sha384.cer | 32 + .../lib/axtls/ssl/test/deutsche_telecom.x509_ca | Bin 0 -> 670 bytes circuitpython/lib/axtls/ssl/test/equifax.x509_ca | Bin 0 -> 646 bytes circuitpython/lib/axtls/ssl/test/gnutls.cer | Bin 0 -> 599 bytes circuitpython/lib/axtls/ssl/test/header_issue.dat | Bin 0 -> 1159 bytes circuitpython/lib/axtls/ssl/test/killgnutls.sh | 2 + circuitpython/lib/axtls/ssl/test/killopenssl.sh | 2 + circuitpython/lib/axtls/ssl/test/make_certs.sh | 253 + circuitpython/lib/axtls/ssl/test/microsoft.x509_ca | Bin 0 -> 1046 bytes .../lib/axtls/ssl/test/microsoft.x509_ca.pem | 24 + circuitpython/lib/axtls/ssl/test/ms_iis.cer | 13 + circuitpython/lib/axtls/ssl/test/perf_bigint.c | 234 + .../lib/axtls/ssl/test/qualityssl.com.der | Bin 0 -> 1385 bytes circuitpython/lib/axtls/ssl/test/socgen.cer | Bin 0 -> 980 bytes circuitpython/lib/axtls/ssl/test/ssltest.c | 2589 ++++ circuitpython/lib/axtls/ssl/test/test_axssl.sh | 163 + circuitpython/lib/axtls/ssl/test/thawte.x509_ca | Bin 0 -> 811 bytes .../lib/axtls/ssl/test/verisign.x509_ca.pem | 16 + .../lib/axtls/ssl/test/verisign.x509_my_cert.pem | 25 + circuitpython/lib/axtls/ssl/tls1.c | 2463 ++++ circuitpython/lib/axtls/ssl/tls1.h | 329 + circuitpython/lib/axtls/ssl/tls1_clnt.c | 546 + circuitpython/lib/axtls/ssl/tls1_svr.c | 537 + circuitpython/lib/axtls/ssl/x509.c | 921 ++ circuitpython/lib/axtls/www/bin/.htaccess | 2 + circuitpython/lib/axtls/www/favicon.ico | Bin 0 -> 22486 bytes circuitpython/lib/axtls/www/index.html | 7103 +++++++++++ circuitpython/lib/axtls/www/lua/download.lua | 75 + circuitpython/lib/axtls/www/lua/env.lua | 26 + circuitpython/lib/axtls/www/lua/overview.lp | 64 + circuitpython/lib/axtls/www/lua/prepara_sql2.lua | 31 + circuitpython/lib/axtls/www/lua/test_conc.lua | 38 + circuitpython/lib/axtls/www/lua/test_cookies.lp | 13 + circuitpython/lib/axtls/www/lua/test_cookies.lua | 14 + circuitpython/lib/axtls/www/lua/test_err.lua | 4 + circuitpython/lib/axtls/www/lua/test_fs.lua | 23 + circuitpython/lib/axtls/www/lua/test_htk.lua | 22 + circuitpython/lib/axtls/www/lua/test_lib.lua | 31 + circuitpython/lib/axtls/www/lua/test_main.html | 127 + circuitpython/lib/axtls/www/lua/test_main.lp | 31 + circuitpython/lib/axtls/www/lua/test_main.lua | 46 + circuitpython/lib/axtls/www/lua/test_session.lua | 43 + circuitpython/lib/axtls/www/lua/test_sql.lua | 13 + circuitpython/lib/axtls/www/lua/test_sql2.lua | 24 + circuitpython/lib/axtls/www/lua/test_variables.lp | 14 + circuitpython/lib/axtls/www/test_dir/bin/.htaccess | 1 + .../lib/axtls/www/test_dir/no_http/.htaccess | 1 + .../lib/axtls/www/test_dir/no_http/.htpasswd | 2 + .../lib/axtls/www/test_dir/no_http/index.html | 6 + .../lib/axtls/www/test_dir/no_ssl/.htaccess | 1 + .../lib/axtls/www/test_dir/no_ssl/index.html | 6 + circuitpython/lib/berkeley-db-1.xx/Makefile.inc | 10 + circuitpython/lib/berkeley-db-1.xx/PORT/Makefile | 102 + circuitpython/lib/berkeley-db-1.xx/PORT/README | 131 + .../lib/berkeley-db-1.xx/PORT/aix.3.2/Makefile | 102 + .../lib/berkeley-db-1.xx/PORT/aix.3.2/clib | 1 + .../berkeley-db-1.xx/PORT/aix.3.2/include/cdefs.h | 1 + .../berkeley-db-1.xx/PORT/aix.3.2/include/compat.h | 231 + .../lib/berkeley-db-1.xx/PORT/aix.3.2/include/db.h | 1 + .../berkeley-db-1.xx/PORT/aix.3.2/include/mpool.h | 1 + .../berkeley-db-1.xx/PORT/aix.3.2/include/ndbm.h | 1 + .../berkeley-db-1.xx/PORT/aix.3.2/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/aix.3.2/sys | 1 + .../lib/berkeley-db-1.xx/PORT/bsd.4.4/Makefile | 1 + .../lib/berkeley-db-1.xx/PORT/bsd.4.4/clib | 1 + .../berkeley-db-1.xx/PORT/bsd.4.4/include/cdefs.h | 1 + .../berkeley-db-1.xx/PORT/bsd.4.4/include/compat.h | 1 + .../lib/berkeley-db-1.xx/PORT/bsd.4.4/include/db.h | 222 + .../berkeley-db-1.xx/PORT/bsd.4.4/include/mpool.h | 1 + .../berkeley-db-1.xx/PORT/bsd.4.4/include/ndbm.h | 1 + .../berkeley-db-1.xx/PORT/bsd.4.4/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/bsd.4.4/sys | 1 + .../lib/berkeley-db-1.xx/PORT/bsdi.1.0/Makefile | 1 + .../berkeley-db-1.xx/PORT/bsdi.1.0/OTHER_PATCHES | 19 + .../lib/berkeley-db-1.xx/PORT/bsdi.1.0/clib | 1 + .../PORT/bsdi.1.0/include/assert.h | 54 + .../berkeley-db-1.xx/PORT/bsdi.1.0/include/cdefs.h | 1 + .../PORT/bsdi.1.0/include/compat.h | 231 + .../berkeley-db-1.xx/PORT/bsdi.1.0/include/db.h | 1 + .../berkeley-db-1.xx/PORT/bsdi.1.0/include/mpool.h | 1 + .../berkeley-db-1.xx/PORT/bsdi.1.0/include/ndbm.h | 1 + .../berkeley-db-1.xx/PORT/bsdi.1.0/include/queue.h | 1 + .../berkeley-db-1.xx/PORT/bsdi.1.0/local/local.h | 87 + .../berkeley-db-1.xx/PORT/bsdi.1.0/local/makebuf.c | 118 + .../berkeley-db-1.xx/PORT/bsdi.1.0/local/setvbuf.c | 148 + .../lib/berkeley-db-1.xx/PORT/bsdi.1.0/sys | 1 + .../lib/berkeley-db-1.xx/PORT/clib/memmove.c | 139 + .../lib/berkeley-db-1.xx/PORT/clib/mktemp.c | 126 + .../lib/berkeley-db-1.xx/PORT/clib/snprintf.c | 54 + .../lib/berkeley-db-1.xx/PORT/clib/strerror.c | 67 + .../lib/berkeley-db-1.xx/PORT/dgux.5.4/Makefile | 103 + .../lib/berkeley-db-1.xx/PORT/dgux.5.4/clib | 1 + .../berkeley-db-1.xx/PORT/dgux.5.4/include/cdefs.h | 1 + .../PORT/dgux.5.4/include/compat.h | 231 + .../berkeley-db-1.xx/PORT/dgux.5.4/include/db.h | 1 + .../berkeley-db-1.xx/PORT/dgux.5.4/include/mpool.h | 1 + .../berkeley-db-1.xx/PORT/dgux.5.4/include/ndbm.h | 1 + .../berkeley-db-1.xx/PORT/dgux.5.4/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/dgux.5.4/sys | 1 + circuitpython/lib/berkeley-db-1.xx/PORT/hpux.8.07 | 1 + .../lib/berkeley-db-1.xx/PORT/hpux.9.01/Makefile | 102 + .../lib/berkeley-db-1.xx/PORT/hpux.9.01/clib | 1 + .../PORT/hpux.9.01/include/cdefs.h | 1 + .../PORT/hpux.9.01/include/compat.h | 231 + .../berkeley-db-1.xx/PORT/hpux.9.01/include/db.h | 1 + .../PORT/hpux.9.01/include/mpool.h | 1 + .../berkeley-db-1.xx/PORT/hpux.9.01/include/ndbm.h | 1 + .../PORT/hpux.9.01/include/queue.h | 1 + .../PORT/hpux.9.01/local/hp_siglist.c | 75 + .../lib/berkeley-db-1.xx/PORT/hpux.9.01/sys | 1 + .../lib/berkeley-db-1.xx/PORT/include/bsd-queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/include/cdefs.h | 122 + .../lib/berkeley-db-1.xx/PORT/include/compat.h | 233 + .../lib/berkeley-db-1.xx/PORT/include/db.h | 1 + .../lib/berkeley-db-1.xx/PORT/include/filevtable.h | 1 + .../lib/berkeley-db-1.xx/PORT/include/mpool.h | 1 + .../lib/berkeley-db-1.xx/PORT/include/ndbm.h | 77 + .../lib/berkeley-db-1.xx/PORT/include/queue.h | 245 + .../lib/berkeley-db-1.xx/PORT/irix.4.05F/Makefile | 103 + .../berkeley-db-1.xx/PORT/irix.4.05F/OTHER_PATCHES | 32 + .../lib/berkeley-db-1.xx/PORT/irix.4.05F/clib | 1 + .../PORT/irix.4.05F/include/cdefs.h | 1 + .../PORT/irix.4.05F/include/compat.h | 231 + .../berkeley-db-1.xx/PORT/irix.4.05F/include/db.h | 1 + .../PORT/irix.4.05F/include/mpool.h | 1 + .../PORT/irix.4.05F/include/ndbm.h | 1 + .../PORT/irix.4.05F/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/irix.4.05F/sys | 1 + .../lib/berkeley-db-1.xx/PORT/linux/Makefile | 102 + .../lib/berkeley-db-1.xx/PORT/linux/OTHER_PATCHES | 29 + circuitpython/lib/berkeley-db-1.xx/PORT/linux/clib | 1 + .../berkeley-db-1.xx/PORT/linux/include/compat.h | 231 + .../lib/berkeley-db-1.xx/PORT/linux/include/db.h | 1 + .../berkeley-db-1.xx/PORT/linux/include/mpool.h | 1 + .../lib/berkeley-db-1.xx/PORT/linux/include/ndbm.h | 1 + circuitpython/lib/berkeley-db-1.xx/PORT/linux/sys | 1 + .../lib/berkeley-db-1.xx/PORT/osf.1.0.2/Makefile | 102 + .../lib/berkeley-db-1.xx/PORT/osf.1.0.2/clib | 1 + .../PORT/osf.1.0.2/include/cdefs.h | 1 + .../PORT/osf.1.0.2/include/compat.h | 231 + .../berkeley-db-1.xx/PORT/osf.1.0.2/include/db.h | 1 + .../PORT/osf.1.0.2/include/mpool.h | 1 + .../berkeley-db-1.xx/PORT/osf.1.0.2/include/ndbm.h | 1 + .../PORT/osf.1.0.2/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/osf.1.0.2/sys | 1 + circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.3 | 1 + circuitpython/lib/berkeley-db-1.xx/PORT/osf.2.0 | 1 + .../lib/berkeley-db-1.xx/PORT/ptx.2.0/Makefile | 104 + .../berkeley-db-1.xx/PORT/ptx.2.0/OTHER_PATCHES | 95 + .../lib/berkeley-db-1.xx/PORT/ptx.2.0/clib | 1 + .../berkeley-db-1.xx/PORT/ptx.2.0/include/cdefs.h | 1 + .../berkeley-db-1.xx/PORT/ptx.2.0/include/compat.h | 232 + .../lib/berkeley-db-1.xx/PORT/ptx.2.0/include/db.h | 1 + .../berkeley-db-1.xx/PORT/ptx.2.0/include/mpool.h | 1 + .../berkeley-db-1.xx/PORT/ptx.2.0/include/ndbm.h | 1 + .../PORT/ptx.2.0/include/pathnames.h | 45 + .../berkeley-db-1.xx/PORT/ptx.2.0/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/ptx.2.0/sys | 1 + .../lib/berkeley-db-1.xx/PORT/sinix.5.41/Makefile | 102 + .../lib/berkeley-db-1.xx/PORT/sinix.5.41/clib | 1 + .../PORT/sinix.5.41/include/cdefs.h | 1 + .../PORT/sinix.5.41/include/compat.h | 231 + .../berkeley-db-1.xx/PORT/sinix.5.41/include/db.h | 1 + .../PORT/sinix.5.41/include/mpool.h | 1 + .../PORT/sinix.5.41/include/ndbm.h | 1 + .../PORT/sinix.5.41/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/sinix.5.41/sys | 1 + .../lib/berkeley-db-1.xx/PORT/solaris.2.2 | 1 + .../lib/berkeley-db-1.xx/PORT/sunos.4.1.1/Makefile | 102 + .../lib/berkeley-db-1.xx/PORT/sunos.4.1.1/clib | 1 + .../PORT/sunos.4.1.1/include/cdefs.h | 1 + .../PORT/sunos.4.1.1/include/compat.h | 231 + .../berkeley-db-1.xx/PORT/sunos.4.1.1/include/db.h | 1 + .../PORT/sunos.4.1.1/include/mpool.h | 1 + .../PORT/sunos.4.1.1/include/ndbm.h | 1 + .../PORT/sunos.4.1.1/include/pathnames.h | 45 + .../PORT/sunos.4.1.1/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/sunos.4.1.1/sys | 1 + .../lib/berkeley-db-1.xx/PORT/sunos.4.1.2 | 1 + .../lib/berkeley-db-1.xx/PORT/sunos.4.1.3 | 1 + .../lib/berkeley-db-1.xx/PORT/sunos.5.2/Makefile | 102 + .../lib/berkeley-db-1.xx/PORT/sunos.5.2/clib | 1 + .../PORT/sunos.5.2/include/cdefs.h | 1 + .../PORT/sunos.5.2/include/compat.h | 236 + .../berkeley-db-1.xx/PORT/sunos.5.2/include/db.h | 1 + .../PORT/sunos.5.2/include/mpool.h | 1 + .../berkeley-db-1.xx/PORT/sunos.5.2/include/ndbm.h | 1 + .../PORT/sunos.5.2/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/sunos.5.2/sys | 1 + .../lib/berkeley-db-1.xx/PORT/ultrix.4.2/Makefile | 102 + .../lib/berkeley-db-1.xx/PORT/ultrix.4.2/clib | 1 + .../PORT/ultrix.4.2/include/cdefs.h | 1 + .../PORT/ultrix.4.2/include/compat.h | 231 + .../berkeley-db-1.xx/PORT/ultrix.4.2/include/db.h | 230 + .../PORT/ultrix.4.2/include/mpool.h | 1 + .../PORT/ultrix.4.2/include/ndbm.h | 1 + .../PORT/ultrix.4.2/include/queue.h | 1 + .../lib/berkeley-db-1.xx/PORT/ultrix.4.2/sys | 1 + circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.3 | 1 + circuitpython/lib/berkeley-db-1.xx/README | 40 + .../lib/berkeley-db-1.xx/btree/Makefile.inc | 7 + .../lib/berkeley-db-1.xx/btree/bt_close.c | 179 + circuitpython/lib/berkeley-db-1.xx/btree/bt_conv.c | 221 + .../lib/berkeley-db-1.xx/btree/bt_debug.c | 329 + .../lib/berkeley-db-1.xx/btree/bt_delete.c | 657 + circuitpython/lib/berkeley-db-1.xx/btree/bt_get.c | 105 + circuitpython/lib/berkeley-db-1.xx/btree/bt_open.c | 412 + .../lib/berkeley-db-1.xx/btree/bt_overflow.c | 228 + circuitpython/lib/berkeley-db-1.xx/btree/bt_page.c | 100 + circuitpython/lib/berkeley-db-1.xx/btree/bt_put.c | 321 + .../lib/berkeley-db-1.xx/btree/bt_search.c | 213 + circuitpython/lib/berkeley-db-1.xx/btree/bt_seq.c | 460 + .../lib/berkeley-db-1.xx/btree/bt_split.c | 834 ++ .../lib/berkeley-db-1.xx/btree/bt_utils.c | 260 + circuitpython/lib/berkeley-db-1.xx/btree/btree.h | 388 + circuitpython/lib/berkeley-db-1.xx/btree/extern.h | 70 + circuitpython/lib/berkeley-db-1.xx/btree/tags | 1 + circuitpython/lib/berkeley-db-1.xx/changelog | 103 + circuitpython/lib/berkeley-db-1.xx/db/Makefile.inc | 5 + circuitpython/lib/berkeley-db-1.xx/db/db.c | 99 + circuitpython/lib/berkeley-db-1.xx/db/tags | 205 + circuitpython/lib/berkeley-db-1.xx/docs/btree.3.ps | 366 + .../lib/berkeley-db-1.xx/docs/dbopen.3.ps | 508 + circuitpython/lib/berkeley-db-1.xx/docs/hash.3.ps | 292 + .../lib/berkeley-db-1.xx/docs/hash.usenix.ps | 12209 ++++++++++++++++++ .../lib/berkeley-db-1.xx/docs/libtp.usenix.ps | 12340 +++++++++++++++++++ circuitpython/lib/berkeley-db-1.xx/docs/mpool.3.ps | 320 + circuitpython/lib/berkeley-db-1.xx/docs/recno.3.ps | 341 + .../lib/berkeley-db-1.xx/hash/Makefile.inc | 6 + circuitpython/lib/berkeley-db-1.xx/hash/README | 72 + circuitpython/lib/berkeley-db-1.xx/hash/extern.h | 65 + circuitpython/lib/berkeley-db-1.xx/hash/hash.c | 994 ++ circuitpython/lib/berkeley-db-1.xx/hash/hash.h | 293 + .../lib/berkeley-db-1.xx/hash/hash_bigkey.c | 667 + circuitpython/lib/berkeley-db-1.xx/hash/hash_buf.c | 355 + .../lib/berkeley-db-1.xx/hash/hash_func.c | 212 + .../lib/berkeley-db-1.xx/hash/hash_log2.c | 54 + .../lib/berkeley-db-1.xx/hash/hash_page.c | 944 ++ circuitpython/lib/berkeley-db-1.xx/hash/hsearch.c | 107 + circuitpython/lib/berkeley-db-1.xx/hash/ndbm.c | 202 + circuitpython/lib/berkeley-db-1.xx/hash/page.h | 92 + circuitpython/lib/berkeley-db-1.xx/hash/search.h | 51 + circuitpython/lib/berkeley-db-1.xx/hash/tags | 1 + circuitpython/lib/berkeley-db-1.xx/include/db.h | 237 + .../lib/berkeley-db-1.xx/include/filevtable.h | 54 + circuitpython/lib/berkeley-db-1.xx/include/mpool.h | 101 + circuitpython/lib/berkeley-db-1.xx/include/tags | 1 + .../lib/berkeley-db-1.xx/man/Makefile.inc | 7 + circuitpython/lib/berkeley-db-1.xx/man/btree.3 | 233 + circuitpython/lib/berkeley-db-1.xx/man/dbopen.3 | 476 + circuitpython/lib/berkeley-db-1.xx/man/hash.3 | 159 + circuitpython/lib/berkeley-db-1.xx/man/mpool.3 | 219 + circuitpython/lib/berkeley-db-1.xx/man/recno.3 | 216 + .../lib/berkeley-db-1.xx/mpool/Makefile.inc | 5 + circuitpython/lib/berkeley-db-1.xx/mpool/README | 7 + circuitpython/lib/berkeley-db-1.xx/mpool/mpool.c | 452 + .../lib/berkeley-db-1.xx/mpool/mpool.libtp | 746 ++ circuitpython/lib/berkeley-db-1.xx/mpool/tags | 1 + .../lib/berkeley-db-1.xx/recno/Makefile.inc | 6 + circuitpython/lib/berkeley-db-1.xx/recno/extern.h | 54 + .../lib/berkeley-db-1.xx/recno/rec_close.c | 182 + .../lib/berkeley-db-1.xx/recno/rec_delete.c | 197 + circuitpython/lib/berkeley-db-1.xx/recno/rec_get.c | 311 + .../lib/berkeley-db-1.xx/recno/rec_open.c | 241 + circuitpython/lib/berkeley-db-1.xx/recno/rec_put.c | 280 + .../lib/berkeley-db-1.xx/recno/rec_search.c | 126 + circuitpython/lib/berkeley-db-1.xx/recno/rec_seq.c | 131 + .../lib/berkeley-db-1.xx/recno/rec_utils.c | 122 + circuitpython/lib/berkeley-db-1.xx/recno/recno.h | 39 + circuitpython/lib/berkeley-db-1.xx/recno/tags | 1 + circuitpython/lib/berkeley-db-1.xx/test/Makefile | 23 + circuitpython/lib/berkeley-db-1.xx/test/README | 74 + .../lib/berkeley-db-1.xx/test/btree.tests/main.c | 765 ++ circuitpython/lib/berkeley-db-1.xx/test/dbtest.c | 753 ++ .../lib/berkeley-db-1.xx/test/hash.tests/driver2.c | 114 + .../lib/berkeley-db-1.xx/test/hash.tests/makedb.sh | 13 + .../lib/berkeley-db-1.xx/test/hash.tests/tcreat3.c | 105 + .../lib/berkeley-db-1.xx/test/hash.tests/tdel.c | 122 + .../lib/berkeley-db-1.xx/test/hash.tests/testit | 147 + .../lib/berkeley-db-1.xx/test/hash.tests/thash4.c | 132 + .../lib/berkeley-db-1.xx/test/hash.tests/tread2.c | 105 + .../lib/berkeley-db-1.xx/test/hash.tests/tseq.c | 88 + .../lib/berkeley-db-1.xx/test/hash.tests/tverify.c | 107 + circuitpython/lib/berkeley-db-1.xx/test/run.test | 705 ++ circuitpython/lib/cmsis/inc/cmsis_armcc.h | 869 ++ circuitpython/lib/cmsis/inc/cmsis_armclang.h | 1420 +++ circuitpython/lib/cmsis/inc/cmsis_armclang_ltm.h | 1866 +++ circuitpython/lib/cmsis/inc/cmsis_compiler.h | 270 + circuitpython/lib/cmsis/inc/cmsis_gcc.h | 2101 ++++ circuitpython/lib/cmsis/inc/cmsis_iccarm.h | 940 ++ circuitpython/lib/cmsis/inc/cmsis_version.h | 39 + circuitpython/lib/cmsis/inc/core_armv81mml.h | 2967 +++++ circuitpython/lib/cmsis/inc/core_armv8mbl.h | 1918 +++ circuitpython/lib/cmsis/inc/core_armv8mml.h | 2832 +++++ circuitpython/lib/cmsis/inc/core_cm0.h | 949 ++ circuitpython/lib/cmsis/inc/core_cm0plus.h | 1082 ++ circuitpython/lib/cmsis/inc/core_cm1.h | 976 ++ circuitpython/lib/cmsis/inc/core_cm23.h | 1993 +++ circuitpython/lib/cmsis/inc/core_cm3.h | 1934 +++ circuitpython/lib/cmsis/inc/core_cm33.h | 2907 +++++ circuitpython/lib/cmsis/inc/core_cm35p.h | 2907 +++++ circuitpython/lib/cmsis/inc/core_cm4.h | 2121 ++++ circuitpython/lib/cmsis/inc/core_cm7.h | 2691 ++++ circuitpython/lib/cmsis/inc/core_sc000.h | 1022 ++ circuitpython/lib/cmsis/inc/core_sc300.h | 1915 +++ circuitpython/lib/cmsis/inc/mpu_armv7.h | 272 + circuitpython/lib/cmsis/inc/mpu_armv8.h | 345 + circuitpython/lib/cmsis/inc/tz_context.h | 70 + circuitpython/lib/crypto-algorithms/sha256.c | 160 + circuitpython/lib/crypto-algorithms/sha256.h | 35 + circuitpython/lib/libffi/.travis.yml | 22 + circuitpython/lib/libffi/ChangeLog.libffi | 584 + circuitpython/lib/libffi/ChangeLog.libffi-3.1 | 6000 +++++++++ circuitpython/lib/libffi/ChangeLog.libgcj | 40 + circuitpython/lib/libffi/ChangeLog.v1 | 764 ++ circuitpython/lib/libffi/LICENSE | 21 + circuitpython/lib/libffi/Makefile.am | 174 + circuitpython/lib/libffi/README | 450 + circuitpython/lib/libffi/acinclude.m4 | 92 + circuitpython/lib/libffi/autogen.sh | 2 + circuitpython/lib/libffi/configure.ac | 372 + circuitpython/lib/libffi/configure.host | 259 + circuitpython/lib/libffi/doc/libffi.texi | 765 ++ circuitpython/lib/libffi/doc/version.texi | 4 + .../libffi/generate-darwin-source-and-headers.py | 209 + circuitpython/lib/libffi/include/Makefile.am | 10 + circuitpython/lib/libffi/include/ffi.h.in | 503 + circuitpython/lib/libffi/include/ffi_cfi.h | 55 + circuitpython/lib/libffi/include/ffi_common.h | 132 + circuitpython/lib/libffi/libffi.pc.in | 11 + .../lib/libffi/libffi.xcodeproj/project.pbxproj | 637 + circuitpython/lib/libffi/libtool-ldflags | 106 + circuitpython/lib/libffi/libtool-version | 29 + circuitpython/lib/libffi/m4/asmcfi.m4 | 13 + circuitpython/lib/libffi/m4/ax_append_flag.m4 | 69 + circuitpython/lib/libffi/m4/ax_cc_maxopt.m4 | 181 + circuitpython/lib/libffi/m4/ax_cflags_warn_all.m4 | 122 + .../lib/libffi/m4/ax_check_compile_flag.m4 | 72 + circuitpython/lib/libffi/m4/ax_compiler_vendor.m4 | 84 + circuitpython/lib/libffi/m4/ax_configure_args.m4 | 70 + circuitpython/lib/libffi/m4/ax_enable_builddir.m4 | 301 + circuitpython/lib/libffi/m4/ax_gcc_archflag.m4 | 225 + circuitpython/lib/libffi/m4/ax_gcc_x86_cpuid.m4 | 79 + circuitpython/lib/libffi/man/Makefile.am | 8 + circuitpython/lib/libffi/man/ffi.3 | 41 + circuitpython/lib/libffi/man/ffi_call.3 | 103 + circuitpython/lib/libffi/man/ffi_prep_cif.3 | 68 + circuitpython/lib/libffi/man/ffi_prep_cif_var.3 | 73 + circuitpython/lib/libffi/msvcc.sh | 257 + circuitpython/lib/libffi/src/aarch64/ffi.c | 1152 ++ circuitpython/lib/libffi/src/aarch64/ffitarget.h | 73 + circuitpython/lib/libffi/src/aarch64/internal.h | 67 + circuitpython/lib/libffi/src/aarch64/sysv.S | 434 + circuitpython/lib/libffi/src/alpha/ffi.c | 521 + circuitpython/lib/libffi/src/alpha/ffitarget.h | 57 + circuitpython/lib/libffi/src/alpha/internal.h | 23 + circuitpython/lib/libffi/src/alpha/osf.S | 282 + circuitpython/lib/libffi/src/arc/arcompact.S | 135 + circuitpython/lib/libffi/src/arc/ffi.c | 268 + circuitpython/lib/libffi/src/arc/ffitarget.h | 53 + circuitpython/lib/libffi/src/arm/ffi.c | 1043 ++ circuitpython/lib/libffi/src/arm/ffitarget.h | 69 + circuitpython/lib/libffi/src/arm/internal.h | 7 + circuitpython/lib/libffi/src/arm/sysv.S | 335 + circuitpython/lib/libffi/src/avr32/ffi.c | 423 + circuitpython/lib/libffi/src/avr32/ffitarget.h | 55 + circuitpython/lib/libffi/src/avr32/sysv.S | 208 + circuitpython/lib/libffi/src/bfin/ffi.c | 196 + circuitpython/lib/libffi/src/bfin/ffitarget.h | 43 + circuitpython/lib/libffi/src/bfin/sysv.S | 179 + circuitpython/lib/libffi/src/closures.c | 688 ++ circuitpython/lib/libffi/src/cris/ffi.c | 386 + circuitpython/lib/libffi/src/cris/ffitarget.h | 56 + circuitpython/lib/libffi/src/cris/sysv.S | 215 + circuitpython/lib/libffi/src/debug.c | 64 + circuitpython/lib/libffi/src/dlmalloc.c | 5161 ++++++++ circuitpython/lib/libffi/src/frv/eabi.S | 128 + circuitpython/lib/libffi/src/frv/ffi.c | 292 + circuitpython/lib/libffi/src/frv/ffitarget.h | 62 + circuitpython/lib/libffi/src/ia64/ffi.c | 586 + circuitpython/lib/libffi/src/ia64/ffitarget.h | 55 + circuitpython/lib/libffi/src/ia64/ia64_flags.h | 40 + circuitpython/lib/libffi/src/ia64/unix.S | 560 + circuitpython/lib/libffi/src/java_raw_api.c | 374 + circuitpython/lib/libffi/src/m32r/ffi.c | 232 + circuitpython/lib/libffi/src/m32r/ffitarget.h | 53 + circuitpython/lib/libffi/src/m32r/sysv.S | 121 + circuitpython/lib/libffi/src/m68k/ffi.c | 362 + circuitpython/lib/libffi/src/m68k/ffitarget.h | 54 + circuitpython/lib/libffi/src/m68k/sysv.S | 330 + circuitpython/lib/libffi/src/m88k/ffi.c | 400 + circuitpython/lib/libffi/src/m88k/ffitarget.h | 49 + circuitpython/lib/libffi/src/m88k/obsd.S | 209 + circuitpython/lib/libffi/src/metag/ffi.c | 330 + circuitpython/lib/libffi/src/metag/ffitarget.h | 53 + circuitpython/lib/libffi/src/metag/sysv.S | 311 + circuitpython/lib/libffi/src/microblaze/ffi.c | 321 + .../lib/libffi/src/microblaze/ffitarget.h | 53 + circuitpython/lib/libffi/src/microblaze/sysv.S | 302 + circuitpython/lib/libffi/src/mips/ffi.c | 1050 ++ circuitpython/lib/libffi/src/mips/ffitarget.h | 247 + circuitpython/lib/libffi/src/mips/n32.S | 576 + circuitpython/lib/libffi/src/mips/o32.S | 381 + circuitpython/lib/libffi/src/moxie/eabi.S | 101 + circuitpython/lib/libffi/src/moxie/ffi.c | 272 + circuitpython/lib/libffi/src/moxie/ffitarget.h | 52 + circuitpython/lib/libffi/src/nios2/ffi.c | 304 + circuitpython/lib/libffi/src/nios2/ffitarget.h | 52 + circuitpython/lib/libffi/src/nios2/sysv.S | 136 + circuitpython/lib/libffi/src/or1k/ffi.c | 328 + circuitpython/lib/libffi/src/or1k/ffitarget.h | 58 + circuitpython/lib/libffi/src/or1k/sysv.S | 107 + circuitpython/lib/libffi/src/pa/ffi.c | 719 ++ circuitpython/lib/libffi/src/pa/ffitarget.h | 85 + circuitpython/lib/libffi/src/pa/hpux32.S | 368 + circuitpython/lib/libffi/src/pa/linux.S | 357 + circuitpython/lib/libffi/src/powerpc/aix.S | 328 + circuitpython/lib/libffi/src/powerpc/aix_closure.S | 447 + circuitpython/lib/libffi/src/powerpc/asm.h | 125 + circuitpython/lib/libffi/src/powerpc/darwin.S | 378 + .../lib/libffi/src/powerpc/darwin_closure.S | 571 + circuitpython/lib/libffi/src/powerpc/ffi.c | 173 + circuitpython/lib/libffi/src/powerpc/ffi_darwin.c | 1359 ++ circuitpython/lib/libffi/src/powerpc/ffi_linux64.c | 945 ++ circuitpython/lib/libffi/src/powerpc/ffi_powerpc.h | 94 + circuitpython/lib/libffi/src/powerpc/ffi_sysv.c | 934 ++ circuitpython/lib/libffi/src/powerpc/ffitarget.h | 195 + circuitpython/lib/libffi/src/powerpc/linux64.S | 228 + .../lib/libffi/src/powerpc/linux64_closure.S | 488 + circuitpython/lib/libffi/src/powerpc/ppc_closure.S | 397 + circuitpython/lib/libffi/src/powerpc/sysv.S | 175 + circuitpython/lib/libffi/src/prep_cif.c | 242 + circuitpython/lib/libffi/src/raw_api.c | 267 + circuitpython/lib/libffi/src/s390/ffi.c | 756 ++ circuitpython/lib/libffi/src/s390/ffitarget.h | 70 + circuitpython/lib/libffi/src/s390/internal.h | 11 + circuitpython/lib/libffi/src/s390/sysv.S | 325 + circuitpython/lib/libffi/src/sh/ffi.c | 717 ++ circuitpython/lib/libffi/src/sh/ffitarget.h | 54 + circuitpython/lib/libffi/src/sh/sysv.S | 850 ++ circuitpython/lib/libffi/src/sh64/ffi.c | 469 + circuitpython/lib/libffi/src/sh64/ffitarget.h | 58 + circuitpython/lib/libffi/src/sh64/sysv.S | 539 + circuitpython/lib/libffi/src/sparc/ffi.c | 468 + circuitpython/lib/libffi/src/sparc/ffi64.c | 608 + circuitpython/lib/libffi/src/sparc/ffitarget.h | 81 + circuitpython/lib/libffi/src/sparc/internal.h | 26 + circuitpython/lib/libffi/src/sparc/v8.S | 443 + circuitpython/lib/libffi/src/sparc/v9.S | 440 + circuitpython/lib/libffi/src/tile/ffi.c | 355 + circuitpython/lib/libffi/src/tile/ffitarget.h | 65 + circuitpython/lib/libffi/src/tile/tile.S | 360 + circuitpython/lib/libffi/src/types.c | 106 + circuitpython/lib/libffi/src/vax/elfbsd.S | 195 + circuitpython/lib/libffi/src/vax/ffi.c | 276 + circuitpython/lib/libffi/src/vax/ffitarget.h | 49 + circuitpython/lib/libffi/src/x86/ffi.c | 729 ++ circuitpython/lib/libffi/src/x86/ffi64.c | 824 ++ circuitpython/lib/libffi/src/x86/ffitarget.h | 139 + circuitpython/lib/libffi/src/x86/ffiw64.c | 281 + circuitpython/lib/libffi/src/x86/internal.h | 29 + circuitpython/lib/libffi/src/x86/internal64.h | 22 + circuitpython/lib/libffi/src/x86/sysv.S | 1040 ++ circuitpython/lib/libffi/src/x86/unix64.S | 546 + circuitpython/lib/libffi/src/x86/win64.S | 219 + circuitpython/lib/libffi/src/xtensa/ffi.c | 298 + circuitpython/lib/libffi/src/xtensa/ffitarget.h | 53 + circuitpython/lib/libffi/src/xtensa/sysv.S | 253 + circuitpython/lib/libffi/stamp-h.in | 1 + circuitpython/lib/libffi/testsuite/Makefile.am | 85 + .../lib/libffi/testsuite/config/default.exp | 1 + circuitpython/lib/libffi/testsuite/lib/libffi.exp | 431 + .../lib/libffi/testsuite/lib/target-libpath.exp | 283 + circuitpython/lib/libffi/testsuite/lib/wrapper.exp | 45 + .../lib/libffi/testsuite/libffi.call/call.exp | 30 + .../lib/libffi/testsuite/libffi.call/closure_fn0.c | 89 + .../lib/libffi/testsuite/libffi.call/closure_fn1.c | 81 + .../lib/libffi/testsuite/libffi.call/closure_fn2.c | 81 + .../lib/libffi/testsuite/libffi.call/closure_fn3.c | 82 + .../lib/libffi/testsuite/libffi.call/closure_fn4.c | 89 + .../lib/libffi/testsuite/libffi.call/closure_fn5.c | 92 + .../lib/libffi/testsuite/libffi.call/closure_fn6.c | 90 + .../libffi/testsuite/libffi.call/closure_loc_fn0.c | 95 + .../libffi/testsuite/libffi.call/closure_simple.c | 55 + .../lib/libffi/testsuite/libffi.call/cls_12byte.c | 94 + .../lib/libffi/testsuite/libffi.call/cls_16byte.c | 95 + .../lib/libffi/testsuite/libffi.call/cls_18byte.c | 96 + .../lib/libffi/testsuite/libffi.call/cls_19byte.c | 102 + .../lib/libffi/testsuite/libffi.call/cls_1_1byte.c | 89 + .../lib/libffi/testsuite/libffi.call/cls_20byte.c | 91 + .../lib/libffi/testsuite/libffi.call/cls_20byte1.c | 93 + .../lib/libffi/testsuite/libffi.call/cls_24byte.c | 113 + .../lib/libffi/testsuite/libffi.call/cls_2byte.c | 90 + .../lib/libffi/testsuite/libffi.call/cls_3_1byte.c | 95 + .../lib/libffi/testsuite/libffi.call/cls_3byte1.c | 90 + .../lib/libffi/testsuite/libffi.call/cls_3byte2.c | 90 + .../lib/libffi/testsuite/libffi.call/cls_4_1byte.c | 98 + .../lib/libffi/testsuite/libffi.call/cls_4byte.c | 90 + .../libffi/testsuite/libffi.call/cls_5_1_byte.c | 109 + .../lib/libffi/testsuite/libffi.call/cls_5byte.c | 98 + .../lib/libffi/testsuite/libffi.call/cls_64byte.c | 124 + .../libffi/testsuite/libffi.call/cls_6_1_byte.c | 113 + .../lib/libffi/testsuite/libffi.call/cls_6byte.c | 99 + .../libffi/testsuite/libffi.call/cls_7_1_byte.c | 117 + .../lib/libffi/testsuite/libffi.call/cls_7byte.c | 97 + .../lib/libffi/testsuite/libffi.call/cls_8byte.c | 88 + .../lib/libffi/testsuite/libffi.call/cls_9byte1.c | 90 + .../lib/libffi/testsuite/libffi.call/cls_9byte2.c | 91 + .../testsuite/libffi.call/cls_align_double.c | 93 + .../libffi/testsuite/libffi.call/cls_align_float.c | 91 + .../testsuite/libffi.call/cls_align_longdouble.c | 92 + .../libffi.call/cls_align_longdouble_split.c | 132 + .../libffi.call/cls_align_longdouble_split2.c | 115 + .../testsuite/libffi.call/cls_align_pointer.c | 95 + .../testsuite/libffi.call/cls_align_sint16.c | 91 + .../testsuite/libffi.call/cls_align_sint32.c | 91 + .../testsuite/libffi.call/cls_align_sint64.c | 92 + .../testsuite/libffi.call/cls_align_uint16.c | 91 + .../testsuite/libffi.call/cls_align_uint32.c | 91 + .../testsuite/libffi.call/cls_align_uint64.c | 93 + .../libffi/testsuite/libffi.call/cls_dbls_struct.c | 66 + .../lib/libffi/testsuite/libffi.call/cls_double.c | 43 + .../libffi/testsuite/libffi.call/cls_double_va.c | 61 + .../lib/libffi/testsuite/libffi.call/cls_float.c | 42 + .../libffi/testsuite/libffi.call/cls_longdouble.c | 105 + .../testsuite/libffi.call/cls_longdouble_va.c | 61 + .../testsuite/libffi.call/cls_many_mixed_args.c | 70 + .../libffi.call/cls_many_mixed_float_double.c | 55 + .../libffi/testsuite/libffi.call/cls_multi_schar.c | 74 + .../testsuite/libffi.call/cls_multi_sshort.c | 74 + .../testsuite/libffi.call/cls_multi_sshortchar.c | 86 + .../libffi/testsuite/libffi.call/cls_multi_uchar.c | 91 + .../testsuite/libffi.call/cls_multi_ushort.c | 74 + .../testsuite/libffi.call/cls_multi_ushortchar.c | 86 + .../lib/libffi/testsuite/libffi.call/cls_pointer.c | 74 + .../testsuite/libffi.call/cls_pointer_stack.c | 142 + .../lib/libffi/testsuite/libffi.call/cls_schar.c | 44 + .../lib/libffi/testsuite/libffi.call/cls_sint.c | 42 + .../lib/libffi/testsuite/libffi.call/cls_sshort.c | 42 + .../libffi/testsuite/libffi.call/cls_struct_va1.c | 114 + .../lib/libffi/testsuite/libffi.call/cls_uchar.c | 42 + .../libffi/testsuite/libffi.call/cls_uchar_va.c | 44 + .../lib/libffi/testsuite/libffi.call/cls_uint.c | 43 + .../lib/libffi/testsuite/libffi.call/cls_uint_va.c | 45 + .../libffi/testsuite/libffi.call/cls_ulong_va.c | 45 + .../libffi/testsuite/libffi.call/cls_ulonglong.c | 47 + .../lib/libffi/testsuite/libffi.call/cls_ushort.c | 43 + .../libffi/testsuite/libffi.call/cls_ushort_va.c | 44 + .../lib/libffi/testsuite/libffi.call/err_bad_abi.c | 36 + .../libffi/testsuite/libffi.call/err_bad_typedef.c | 26 + .../lib/libffi/testsuite/libffi.call/ffitest.h | 135 + .../lib/libffi/testsuite/libffi.call/float.c | 59 + .../lib/libffi/testsuite/libffi.call/float1.c | 60 + .../lib/libffi/testsuite/libffi.call/float2.c | 58 + .../lib/libffi/testsuite/libffi.call/float3.c | 74 + .../lib/libffi/testsuite/libffi.call/float4.c | 62 + .../lib/libffi/testsuite/libffi.call/float_va.c | 107 + .../lib/libffi/testsuite/libffi.call/huge_struct.c | 341 + .../lib/libffi/testsuite/libffi.call/many.c | 59 + .../lib/libffi/testsuite/libffi.call/many2.c | 57 + .../lib/libffi/testsuite/libffi.call/many_double.c | 70 + .../lib/libffi/testsuite/libffi.call/many_mixed.c | 78 + .../lib/libffi/testsuite/libffi.call/negint.c | 52 + .../libffi/testsuite/libffi.call/nested_struct.c | 152 + .../libffi/testsuite/libffi.call/nested_struct1.c | 161 + .../libffi/testsuite/libffi.call/nested_struct10.c | 133 + .../libffi/testsuite/libffi.call/nested_struct11.c | 121 + .../libffi/testsuite/libffi.call/nested_struct2.c | 110 + .../libffi/testsuite/libffi.call/nested_struct3.c | 111 + .../libffi/testsuite/libffi.call/nested_struct4.c | 111 + .../libffi/testsuite/libffi.call/nested_struct5.c | 112 + .../libffi/testsuite/libffi.call/nested_struct6.c | 131 + .../libffi/testsuite/libffi.call/nested_struct7.c | 111 + .../libffi/testsuite/libffi.call/nested_struct8.c | 131 + .../libffi/testsuite/libffi.call/nested_struct9.c | 131 + .../lib/libffi/testsuite/libffi.call/pr1172638.c | 127 + .../lib/libffi/testsuite/libffi.call/problem1.c | 90 + .../lib/libffi/testsuite/libffi.call/promotion.c | 59 + .../lib/libffi/testsuite/libffi.call/pyobjc-tc.c | 114 + .../lib/libffi/testsuite/libffi.call/return_dbl.c | 36 + .../lib/libffi/testsuite/libffi.call/return_dbl1.c | 43 + .../lib/libffi/testsuite/libffi.call/return_dbl2.c | 42 + .../lib/libffi/testsuite/libffi.call/return_fl.c | 35 + .../lib/libffi/testsuite/libffi.call/return_fl1.c | 36 + .../lib/libffi/testsuite/libffi.call/return_fl2.c | 49 + .../lib/libffi/testsuite/libffi.call/return_fl3.c | 42 + .../lib/libffi/testsuite/libffi.call/return_ldl.c | 34 + .../lib/libffi/testsuite/libffi.call/return_ll.c | 41 + .../lib/libffi/testsuite/libffi.call/return_ll1.c | 43 + .../lib/libffi/testsuite/libffi.call/return_sc.c | 36 + .../lib/libffi/testsuite/libffi.call/return_sl.c | 38 + .../lib/libffi/testsuite/libffi.call/return_uc.c | 38 + .../lib/libffi/testsuite/libffi.call/return_ul.c | 38 + .../lib/libffi/testsuite/libffi.call/stret_large.c | 145 + .../libffi/testsuite/libffi.call/stret_large2.c | 148 + .../libffi/testsuite/libffi.call/stret_medium.c | 124 + .../libffi/testsuite/libffi.call/stret_medium2.c | 125 + .../lib/libffi/testsuite/libffi.call/strlen.c | 44 + .../lib/libffi/testsuite/libffi.call/strlen2.c | 49 + .../lib/libffi/testsuite/libffi.call/strlen3.c | 49 + .../lib/libffi/testsuite/libffi.call/strlen4.c | 55 + .../lib/libffi/testsuite/libffi.call/struct1.c | 67 + .../lib/libffi/testsuite/libffi.call/struct2.c | 67 + .../lib/libffi/testsuite/libffi.call/struct3.c | 60 + .../lib/libffi/testsuite/libffi.call/struct4.c | 64 + .../lib/libffi/testsuite/libffi.call/struct5.c | 66 + .../lib/libffi/testsuite/libffi.call/struct6.c | 64 + .../lib/libffi/testsuite/libffi.call/struct7.c | 74 + .../lib/libffi/testsuite/libffi.call/struct8.c | 81 + .../lib/libffi/testsuite/libffi.call/struct9.c | 68 + .../lib/libffi/testsuite/libffi.call/testclosure.c | 70 + .../libffi/testsuite/libffi.call/uninitialized.c | 61 + .../lib/libffi/testsuite/libffi.call/unwindtest.cc | 117 + .../testsuite/libffi.call/unwindtest_ffi_call.cc | 54 + .../lib/libffi/testsuite/libffi.call/va_1.c | 196 + .../lib/libffi/testsuite/libffi.call/va_struct1.c | 121 + .../lib/libffi/testsuite/libffi.call/va_struct2.c | 123 + .../lib/libffi/testsuite/libffi.call/va_struct3.c | 125 + .../testsuite/libffi.complex/cls_align_complex.inc | 91 + .../libffi.complex/cls_align_complex_double.c | 10 + .../libffi.complex/cls_align_complex_float.c | 10 + .../libffi.complex/cls_align_complex_longdouble.c | 10 + .../testsuite/libffi.complex/cls_complex.inc | 42 + .../testsuite/libffi.complex/cls_complex_double.c | 10 + .../testsuite/libffi.complex/cls_complex_float.c | 10 + .../libffi.complex/cls_complex_longdouble.c | 10 + .../libffi.complex/cls_complex_struct.inc | 71 + .../libffi.complex/cls_complex_struct_double.c | 10 + .../libffi.complex/cls_complex_struct_float.c | 10 + .../libffi.complex/cls_complex_struct_longdouble.c | 10 + .../testsuite/libffi.complex/cls_complex_va.inc | 80 + .../libffi.complex/cls_complex_va_double.c | 10 + .../libffi.complex/cls_complex_va_float.c | 16 + .../libffi.complex/cls_complex_va_longdouble.c | 10 + .../libffi/testsuite/libffi.complex/complex.exp | 36 + .../libffi/testsuite/libffi.complex/complex.inc | 51 + .../libffi.complex/complex_defs_double.inc | 7 + .../libffi.complex/complex_defs_float.inc | 7 + .../libffi.complex/complex_defs_longdouble.inc | 7 + .../testsuite/libffi.complex/complex_double.c | 10 + .../testsuite/libffi.complex/complex_float.c | 10 + .../libffi/testsuite/libffi.complex/complex_int.c | 86 + .../testsuite/libffi.complex/complex_longdouble.c | 10 + .../lib/libffi/testsuite/libffi.complex/ffitest.h | 1 + .../testsuite/libffi.complex/many_complex.inc | 78 + .../testsuite/libffi.complex/many_complex_double.c | 10 + .../testsuite/libffi.complex/many_complex_float.c | 10 + .../libffi.complex/many_complex_longdouble.c | 10 + .../testsuite/libffi.complex/return_complex.inc | 37 + .../testsuite/libffi.complex/return_complex1.inc | 41 + .../libffi.complex/return_complex1_double.c | 10 + .../libffi.complex/return_complex1_float.c | 10 + .../libffi.complex/return_complex1_longdouble.c | 10 + .../testsuite/libffi.complex/return_complex2.inc | 44 + .../libffi.complex/return_complex2_double.c | 10 + .../libffi.complex/return_complex2_float.c | 10 + .../libffi.complex/return_complex2_longdouble.c | 10 + .../libffi.complex/return_complex_double.c | 10 + .../libffi.complex/return_complex_float.c | 10 + .../libffi.complex/return_complex_longdouble.c | 10 + .../lib/libffi/testsuite/libffi.go/aa-direct.c | 34 + .../lib/libffi/testsuite/libffi.go/closure1.c | 28 + .../lib/libffi/testsuite/libffi.go/ffitest.h | 1 + .../lib/libffi/testsuite/libffi.go/go.exp | 36 + .../lib/libffi/testsuite/libffi.go/static-chain.h | 19 + circuitpython/lib/libffi/texinfo.tex | 10079 +++++++++++++++ circuitpython/lib/libm/acoshf.c | 32 + circuitpython/lib/libm/asinfacosf.c | 130 + circuitpython/lib/libm/asinhf.c | 34 + circuitpython/lib/libm/atan2f.c | 89 + circuitpython/lib/libm/atanf.c | 100 + circuitpython/lib/libm/atanhf.c | 34 + circuitpython/lib/libm/ef_rem_pio2.c | 211 + circuitpython/lib/libm/ef_sqrt.c | 102 + circuitpython/lib/libm/erf_lgamma.c | 256 + circuitpython/lib/libm/fdlibm.h | 227 + circuitpython/lib/libm/fmodf.c | 70 + circuitpython/lib/libm/kf_cos.c | 68 + circuitpython/lib/libm/kf_rem_pio2.c | 224 + circuitpython/lib/libm/kf_sin.c | 58 + circuitpython/lib/libm/kf_tan.c | 105 + circuitpython/lib/libm/libm.h | 54 + circuitpython/lib/libm/log1pf.c | 85 + circuitpython/lib/libm/math.c | 829 ++ circuitpython/lib/libm/nearbyintf.c | 24 + circuitpython/lib/libm/roundf.c | 33 + circuitpython/lib/libm/sf_cos.c | 71 + circuitpython/lib/libm/sf_erf.c | 257 + circuitpython/lib/libm/sf_frexp.c | 70 + circuitpython/lib/libm/sf_ldexp.c | 55 + circuitpython/lib/libm/sf_modf.c | 82 + circuitpython/lib/libm/sf_sin.c | 71 + circuitpython/lib/libm/sf_tan.c | 66 + circuitpython/lib/libm/thumb_vfp_sqrtf.c | 11 + circuitpython/lib/libm/wf_lgamma.c | 96 + circuitpython/lib/libm/wf_tgamma.c | 73 + circuitpython/lib/libm_dbl/README | 36 + circuitpython/lib/libm_dbl/__cos.c | 71 + circuitpython/lib/libm_dbl/__expo2.c | 16 + circuitpython/lib/libm_dbl/__fpclassify.c | 11 + circuitpython/lib/libm_dbl/__rem_pio2.c | 177 + circuitpython/lib/libm_dbl/__rem_pio2_large.c | 442 + circuitpython/lib/libm_dbl/__signbit.c | 10 + circuitpython/lib/libm_dbl/__sin.c | 64 + circuitpython/lib/libm_dbl/__tan.c | 110 + circuitpython/lib/libm_dbl/acos.c | 101 + circuitpython/lib/libm_dbl/acosh.c | 24 + circuitpython/lib/libm_dbl/asin.c | 107 + circuitpython/lib/libm_dbl/asinh.c | 28 + circuitpython/lib/libm_dbl/atan.c | 116 + circuitpython/lib/libm_dbl/atan2.c | 107 + circuitpython/lib/libm_dbl/atanh.c | 29 + circuitpython/lib/libm_dbl/ceil.c | 31 + circuitpython/lib/libm_dbl/copysign.c | 48 + circuitpython/lib/libm_dbl/cos.c | 77 + circuitpython/lib/libm_dbl/cosh.c | 40 + circuitpython/lib/libm_dbl/erf.c | 273 + circuitpython/lib/libm_dbl/exp.c | 134 + circuitpython/lib/libm_dbl/expm1.c | 201 + circuitpython/lib/libm_dbl/floor.c | 31 + circuitpython/lib/libm_dbl/fmod.c | 68 + circuitpython/lib/libm_dbl/frexp.c | 23 + circuitpython/lib/libm_dbl/ldexp.c | 6 + circuitpython/lib/libm_dbl/lgamma.c | 8 + circuitpython/lib/libm_dbl/libm.h | 96 + circuitpython/lib/libm_dbl/log.c | 118 + circuitpython/lib/libm_dbl/log10.c | 7 + circuitpython/lib/libm_dbl/log1p.c | 122 + circuitpython/lib/libm_dbl/modf.c | 34 + circuitpython/lib/libm_dbl/nearbyint.c | 19 + circuitpython/lib/libm_dbl/pow.c | 328 + circuitpython/lib/libm_dbl/rint.c | 28 + circuitpython/lib/libm_dbl/round.c | 35 + circuitpython/lib/libm_dbl/scalbn.c | 33 + circuitpython/lib/libm_dbl/sin.c | 78 + circuitpython/lib/libm_dbl/sinh.c | 39 + circuitpython/lib/libm_dbl/sqrt.c | 185 + circuitpython/lib/libm_dbl/tan.c | 70 + circuitpython/lib/libm_dbl/tanh.c | 12 + circuitpython/lib/libm_dbl/tgamma.c | 222 + circuitpython/lib/libm_dbl/thumb_vfp_sqrt.c | 10 + circuitpython/lib/libm_dbl/trunc.c | 19 + circuitpython/lib/littlefs/README.md | 19 + circuitpython/lib/littlefs/lfs1.c | 2583 ++++ circuitpython/lib/littlefs/lfs1.h | 501 + circuitpython/lib/littlefs/lfs1_util.c | 31 + circuitpython/lib/littlefs/lfs1_util.h | 186 + circuitpython/lib/littlefs/lfs2.c | 5391 ++++++++ circuitpython/lib/littlefs/lfs2.h | 689 ++ circuitpython/lib/littlefs/lfs2_util.c | 33 + circuitpython/lib/littlefs/lfs2_util.h | 234 + circuitpython/lib/mp3/Doxyfile | 2481 ++++ circuitpython/lib/mp3/README.md | 41 + .../mp3/examples/DMA_fancy_player/.due.test.skip | 0 .../mp3/examples/DMA_fancy_player/.esp32.test.skip | 0 .../examples/DMA_fancy_player/.esp8266.test.skip | 0 .../examples/DMA_fancy_player/.leonardo.test.skip | 0 .../examples/DMA_fancy_player/.mega2560.test.skip | 0 .../mp3/examples/DMA_fancy_player/.uno.test.skip | 0 .../mp3/examples/DMA_fancy_player/.zero.test.skip | 0 .../examples/DMA_fancy_player/DMA_fancy_player.ino | 287 + .../mp3/examples/DMA_play_from_SD/.due.test.skip | 0 .../mp3/examples/DMA_play_from_SD/.esp32.test.skip | 0 .../examples/DMA_play_from_SD/.esp8266.test.skip | 0 .../examples/DMA_play_from_SD/.leonardo.test.skip | 0 .../examples/DMA_play_from_SD/.mega2560.test.skip | 0 .../mp3/examples/DMA_play_from_SD/.uno.test.skip | 0 .../mp3/examples/DMA_play_from_SD/.zero.test.skip | 0 .../examples/DMA_play_from_SD/DMA_play_from_SD.ino | 248 + .../examples/DMA_play_from_header/.due.test.skip | 0 .../examples/DMA_play_from_header/.esp32.test.skip | 0 .../DMA_play_from_header/.esp8266.test.skip | 0 .../DMA_play_from_header/.leonardo.test.skip | 0 .../DMA_play_from_header/.mega2560.test.skip | 0 .../examples/DMA_play_from_header/.uno.test.skip | 0 .../examples/DMA_play_from_header/.zero.test.skip | 0 .../DMA_play_from_header/DMA_play_from_header.ino | 106 + .../lib/mp3/examples/DMA_play_from_header/sine.h | 6730 ++++++++++ .../mp3/examples/play_from_QSPI/play_from_QSPI.ino | 113 + .../lib/mp3/examples/play_from_SD/.due.test.skip | 0 .../lib/mp3/examples/play_from_SD/.esp32.test.skip | 0 .../mp3/examples/play_from_SD/.esp8266.test.skip | 0 .../mp3/examples/play_from_SD/.leonardo.test.skip | 0 .../mp3/examples/play_from_SD/.mega2560.test.skip | 0 .../lib/mp3/examples/play_from_SD/.uno.test.skip | 0 .../lib/mp3/examples/play_from_SD/.zero.test.skip | 0 .../lib/mp3/examples/play_from_SD/play_from_SD.ino | 91 + .../mp3/examples/play_from_header/.due.test.skip | 0 .../mp3/examples/play_from_header/.esp32.test.skip | 0 .../examples/play_from_header/.esp8266.test.skip | 0 .../examples/play_from_header/.leonardo.test.skip | 0 .../examples/play_from_header/.mega2560.test.skip | 0 .../mp3/examples/play_from_header/.uno.test.skip | 0 .../mp3/examples/play_from_header/.zero.test.skip | 0 .../examples/play_from_header/play_from_header.ino | 51 + .../lib/mp3/examples/play_from_header/sine.h | 6730 ++++++++++ circuitpython/lib/mp3/examples/standalone/Makefile | 6 + circuitpython/lib/mp3/examples/standalone/main.c | 128 + circuitpython/lib/mp3/examples/test.mp3 | Bin 0 -> 59783 bytes circuitpython/lib/mp3/library.properties | 10 + circuitpython/lib/mp3/src/Adafruit_MP3.cpp | 532 + circuitpython/lib/mp3/src/Adafruit_MP3.h | 110 + circuitpython/lib/mp3/src/assembly.h | 550 + circuitpython/lib/mp3/src/bitstream.c | 389 + circuitpython/lib/mp3/src/buffers.c | 226 + circuitpython/lib/mp3/src/coder.h | 314 + circuitpython/lib/mp3/src/dct32.c | 280 + circuitpython/lib/mp3/src/dequant.c | 158 + circuitpython/lib/mp3/src/dqchan.c | 374 + circuitpython/lib/mp3/src/huffman.c | 462 + circuitpython/lib/mp3/src/hufftabs.c | 755 ++ circuitpython/lib/mp3/src/imdct.c | 784 ++ circuitpython/lib/mp3/src/mp3common.h | 131 + circuitpython/lib/mp3/src/mp3dec.c | 419 + circuitpython/lib/mp3/src/mp3dec.h | 148 + circuitpython/lib/mp3/src/mp3tabs.c | 181 + circuitpython/lib/mp3/src/mpadecobjfixpt.h | 108 + circuitpython/lib/mp3/src/polyphase.c | 304 + circuitpython/lib/mp3/src/readme.txt | 140 + circuitpython/lib/mp3/src/scalfact.c | 388 + circuitpython/lib/mp3/src/statname.h | 88 + circuitpython/lib/mp3/src/stproc.c | 296 + circuitpython/lib/mp3/src/subband.c | 94 + circuitpython/lib/mp3/src/trigtabs.c | 314 + circuitpython/lib/nrfutil/README.md | 75 + .../lib/nrfutil/binaries/win32/nrfutil.exe | Bin 0 -> 11793224 bytes .../lib/nrfutil/build/lib/nordicsemi/__init__.py | 29 + .../lib/nrfutil/build/lib/nordicsemi/__main__.py | 303 + .../build/lib/nordicsemi/bluetooth/__init__.py | 29 + .../build/lib/nordicsemi/bluetooth/hci/__init__.py | 29 + .../build/lib/nordicsemi/bluetooth/hci/codec.py | 76 + .../build/lib/nordicsemi/bluetooth/hci/slip.py | 115 + .../lib/nordicsemi/bluetooth/hci/tests/__init__.py | 29 + .../nordicsemi/bluetooth/hci/tests/test_codec.py | 81 + .../nrfutil/build/lib/nordicsemi/dfu/__init__.py | 29 + .../lib/nrfutil/build/lib/nordicsemi/dfu/crc16.py | 44 + .../lib/nrfutil/build/lib/nordicsemi/dfu/dfu.py | 234 + .../build/lib/nordicsemi/dfu/dfu_transport.py | 204 + .../build/lib/nordicsemi/dfu/dfu_transport_ble.py | 327 + .../lib/nordicsemi/dfu/dfu_transport_serial.py | 340 + .../build/lib/nordicsemi/dfu/init_packet.py | 131 + .../build/lib/nordicsemi/dfu/intelhex/__init__.py | 1286 ++ .../build/lib/nordicsemi/dfu/intelhex/compat.py | 57 + .../nrfutil/build/lib/nordicsemi/dfu/manifest.py | 239 + .../lib/nrfutil/build/lib/nordicsemi/dfu/model.py | 46 + .../lib/nrfutil/build/lib/nordicsemi/dfu/nrfhex.py | 168 + .../nrfutil/build/lib/nordicsemi/dfu/package.py | 369 + .../nrfutil/build/lib/nordicsemi/dfu/signing.py | 149 + .../build/lib/nordicsemi/dfu/tests/__init__.py | 29 + .../dfu/tests/test_dfu_transport_serial.py | 136 + .../lib/nordicsemi/dfu/tests/test_init_packet.py | 123 + .../lib/nordicsemi/dfu/tests/test_manifest.py | 201 + .../build/lib/nordicsemi/dfu/tests/test_nrfhex.py | 134 + .../build/lib/nordicsemi/dfu/tests/test_package.py | 164 + .../build/lib/nordicsemi/dfu/tests/test_signing.py | 155 + .../lib/nrfutil/build/lib/nordicsemi/dfu/util.py | 179 + .../lib/nrfutil/build/lib/nordicsemi/exceptions.py | 60 + .../build/lib/nordicsemi/utility/__init__.py | 29 + .../lib/nordicsemi/utility/target_registry.py | 121 + .../build/lib/nordicsemi/utility/tests/__init__.py | 29 + .../utility/tests/test_target_registry.py | 90 + .../lib/nrfutil/build/lib/nordicsemi/version.py | 33 + .../lib/nrfutil/dist/nrfutil-0.5.2-py2.7.egg | Bin 0 -> 149932 bytes circuitpython/lib/nrfutil/license.txt | 27 + circuitpython/lib/nrfutil/nordicsemi/__init__.py | 29 + circuitpython/lib/nrfutil/nordicsemi/__init__.pyc | Bin 0 -> 250 bytes circuitpython/lib/nrfutil/nordicsemi/__main__.py | 307 + .../lib/nrfutil/nordicsemi/bluetooth/__init__.py | 29 + .../nrfutil/nordicsemi/bluetooth/hci/__init__.py | 29 + .../lib/nrfutil/nordicsemi/bluetooth/hci/codec.py | 76 + .../lib/nrfutil/nordicsemi/bluetooth/hci/slip.py | 115 + .../nordicsemi/bluetooth/hci/tests/__init__.py | 29 + .../nordicsemi/bluetooth/hci/tests/test_codec.py | 81 + .../lib/nrfutil/nordicsemi/dfu/__init__.py | 29 + circuitpython/lib/nrfutil/nordicsemi/dfu/crc16.py | 44 + circuitpython/lib/nrfutil/nordicsemi/dfu/dfu.py | 232 + .../lib/nrfutil/nordicsemi/dfu/dfu_transport.py | 204 + .../nrfutil/nordicsemi/dfu/dfu_transport_ble.py | 327 + .../nrfutil/nordicsemi/dfu/dfu_transport_serial.py | 337 + .../lib/nrfutil/nordicsemi/dfu/init_packet.py | 131 + .../nrfutil/nordicsemi/dfu/intelhex/__init__.py | 1286 ++ .../lib/nrfutil/nordicsemi/dfu/intelhex/compat.py | 57 + .../lib/nrfutil/nordicsemi/dfu/manifest.py | 239 + circuitpython/lib/nrfutil/nordicsemi/dfu/model.py | 46 + circuitpython/lib/nrfutil/nordicsemi/dfu/nrfhex.py | 168 + .../lib/nrfutil/nordicsemi/dfu/package.py | 369 + .../lib/nrfutil/nordicsemi/dfu/signing.py | 149 + .../lib/nrfutil/nordicsemi/dfu/tests/__init__.py | 29 + .../nrfutil/nordicsemi/dfu/tests/firmwares/bar.hex | 828 ++ .../nordicsemi/dfu/tests/firmwares/bar_wanted.bin | Bin 0 -> 13192 bytes .../nrfutil/nordicsemi/dfu/tests/firmwares/foo.hex | 4835 ++++++++ .../nordicsemi/dfu/tests/firmwares/foo_wanted.bin | Bin 0 -> 73152 bytes .../dfu/tests/firmwares/foobar_wanted.bin | Bin 0 -> 86344 bytes .../firmwares/pca10028_nrf51422_xxac_blinky.bin | Bin 0 -> 676 bytes .../dfu/tests/firmwares/s130_nrf51_mini.hex | 894 ++ .../dfu/tests/firmwares/s132_nrf52_mini.hex | 910 ++ .../lib/nrfutil/nordicsemi/dfu/tests/key.pem | 5 + .../dfu/tests/test_dfu_transport_serial.py | 136 + .../nordicsemi/dfu/tests/test_init_packet.py | 123 + .../nrfutil/nordicsemi/dfu/tests/test_manifest.py | 201 + .../nrfutil/nordicsemi/dfu/tests/test_nrfhex.py | 134 + .../nrfutil/nordicsemi/dfu/tests/test_package.py | 164 + .../nrfutil/nordicsemi/dfu/tests/test_signing.py | 155 + circuitpython/lib/nrfutil/nordicsemi/dfu/util.py | 179 + circuitpython/lib/nrfutil/nordicsemi/exceptions.py | 60 + .../lib/nrfutil/nordicsemi/utility/__init__.py | 29 + .../nrfutil/nordicsemi/utility/target_registry.py | 121 + .../nrfutil/nordicsemi/utility/tests/__init__.py | 29 + .../utility/tests/test_target_registry.py | 90 + .../nordicsemi/utility/tests/test_targets.json | 17 + circuitpython/lib/nrfutil/nordicsemi/version.py | 33 + circuitpython/lib/nrfutil/nordicsemi/version.pyc | Bin 0 -> 300 bytes .../lib/nrfutil/nrfutil.egg-info/PKG-INFO | 11 + .../lib/nrfutil/nrfutil.egg-info/SOURCES.txt | 43 + .../nrfutil/nrfutil.egg-info/dependency_links.txt | 1 + .../lib/nrfutil/nrfutil.egg-info/entry_points.txt | 4 + .../lib/nrfutil/nrfutil.egg-info/not-zip-safe | 1 + .../lib/nrfutil/nrfutil.egg-info/top_level.txt | 1 + circuitpython/lib/nrfutil/requirements.txt | 5 + circuitpython/lib/nrfutil/setup.py | 133 + circuitpython/lib/nrfutil/tests/bdd/environment.py | 37 + .../tests/bdd/genpkg_generate_dfu_package.feature | 673 + .../tests/bdd/genpkg_help_information.feature | 10 + .../lib/nrfutil/tests/bdd/steps/common_steps.py | 84 + .../bdd/steps/genpkg_generate_dfu_package_steps.py | 250 + .../bdd/steps/genpkg_help_information_steps.py | 64 + circuitpython/lib/nrfutil/tests/bdd/steps/util.py | 154 + .../lib/nrfutil/tests/resources/blinky.bin | Bin 0 -> 676 bytes .../tests/resources/dfu_test_app_hrm_s110.hex | 1229 ++ .../tests/resources/dfu_test_app_hrm_s130.hex | 1287 ++ .../tests/resources/dfu_test_bootloader_b.hex | 8 + .../tests/resources/dfu_test_softdevice_b.hex | 3 + circuitpython/lib/nrfutil/tests/resources/test.pem | 5 + circuitpython/lib/oofatfs/diskio.h | 81 + circuitpython/lib/oofatfs/ff.c | 5971 +++++++++ circuitpython/lib/oofatfs/ff.h | 400 + circuitpython/lib/oofatfs/ffconf.h | 378 + circuitpython/lib/oofatfs/ffunicode.c | 627 + circuitpython/lib/protomatter/README.md | 117 + .../examples/animated_gif/.matrixportal.test.only | 0 .../examples/animated_gif/animated_gif.ino | 376 + .../doublebuffer_scrolltext.ino | 180 + .../protomatter/examples/pixeldust/pixeldust.ino | 140 + .../lib/protomatter/examples/simple/simple.ino | 298 + .../lib/protomatter/examples/tiled/tiled.ino | 136 + circuitpython/lib/protomatter/library.properties | 10 + .../lib/protomatter/src/Adafruit_Protomatter.cpp | 141 + .../lib/protomatter/src/Adafruit_Protomatter.h | 152 + circuitpython/lib/protomatter/src/arch/arch.h | 209 + circuitpython/lib/protomatter/src/arch/esp32.h | 215 + circuitpython/lib/protomatter/src/arch/nrf52.h | 216 + circuitpython/lib/protomatter/src/arch/rp2040.h | 245 + .../lib/protomatter/src/arch/samd-common.h | 98 + circuitpython/lib/protomatter/src/arch/samd21.h | 150 + circuitpython/lib/protomatter/src/arch/samd51.h | 216 + circuitpython/lib/protomatter/src/arch/stm32.h | 146 + circuitpython/lib/protomatter/src/arch/teensy4.h | 172 + circuitpython/lib/protomatter/src/core.c | 1302 ++ circuitpython/lib/protomatter/src/core.h | 274 + circuitpython/lib/quirc/LICENSE | 19 + circuitpython/lib/quirc/Makefile | 103 + circuitpython/lib/quirc/README.md | 247 + circuitpython/lib/quirc/demo/camera.c | 591 + circuitpython/lib/quirc/demo/camera.h | 104 + circuitpython/lib/quirc/demo/convert.c | 103 + circuitpython/lib/quirc/demo/convert.h | 39 + circuitpython/lib/quirc/demo/demo.c | 333 + circuitpython/lib/quirc/demo/demo_opencv.cxx | 263 + circuitpython/lib/quirc/demo/demoutil.c | 71 + circuitpython/lib/quirc/demo/demoutil.h | 42 + circuitpython/lib/quirc/demo/dthash.c | 139 + circuitpython/lib/quirc/demo/dthash.h | 61 + circuitpython/lib/quirc/demo/mjpeg.c | 284 + circuitpython/lib/quirc/demo/mjpeg.h | 54 + circuitpython/lib/quirc/demo/scanner.c | 214 + circuitpython/lib/quirc/lib/decode.c | 978 ++ circuitpython/lib/quirc/lib/identify.c | 1140 ++ circuitpython/lib/quirc/lib/quirc.c | 165 + circuitpython/lib/quirc/lib/quirc.h | 178 + circuitpython/lib/quirc/lib/quirc_internal.h | 145 + circuitpython/lib/quirc/lib/version_db.c | 421 + circuitpython/lib/quirc/tests/dbgutil.c | 307 + circuitpython/lib/quirc/tests/dbgutil.h | 48 + circuitpython/lib/quirc/tests/inspect.c | 264 + circuitpython/lib/quirc/tests/qrtest.c | 309 + circuitpython/lib/re1.5/charclass.c | 33 + circuitpython/lib/re1.5/compilecode.c | 275 + circuitpython/lib/re1.5/dumpcode.c | 65 + circuitpython/lib/re1.5/re1.5.h | 156 + circuitpython/lib/re1.5/recursiveloop.c | 87 + circuitpython/lib/sdmmc/CMakeLists.txt | 9 + circuitpython/lib/sdmmc/component.mk | 0 circuitpython/lib/sdmmc/include/sdmmc_cmd.h | 274 + circuitpython/lib/sdmmc/include/sdmmc_defs.h | 498 + circuitpython/lib/sdmmc/include/sdmmc_types.h | 199 + circuitpython/lib/sdmmc/sdmmc_cmd.c | 501 + circuitpython/lib/sdmmc/sdmmc_common.c | 314 + circuitpython/lib/sdmmc/sdmmc_common.h | 132 + circuitpython/lib/sdmmc/sdmmc_init.c | 123 + circuitpython/lib/sdmmc/sdmmc_io.c | 639 + circuitpython/lib/sdmmc/sdmmc_mmc.c | 251 + circuitpython/lib/sdmmc/sdmmc_sd.c | 343 + circuitpython/lib/sdmmc/test/CMakeLists.txt | 4 + circuitpython/lib/sdmmc/test/component.mk | 1 + circuitpython/lib/sdmmc/test/test_sd.c | 584 + circuitpython/lib/sdmmc/test/test_sdio.c | 388 + circuitpython/lib/tinytest/README | 17 + circuitpython/lib/tinytest/tinytest.c | 473 + circuitpython/lib/tinytest/tinytest.h | 98 + circuitpython/lib/tinytest/tinytest_macros.h | 184 + circuitpython/lib/tinyusb/.readthedocs.yaml | 18 + circuitpython/lib/tinyusb/CODE_OF_CONDUCT.rst | 88 + circuitpython/lib/tinyusb/CONTRIBUTORS.rst | 205 + circuitpython/lib/tinyusb/LICENSE | 21 + circuitpython/lib/tinyusb/README.rst | 146 + circuitpython/lib/tinyusb/docs/assets/logo.svg | 18 + circuitpython/lib/tinyusb/docs/assets/stack.svg | 1 + circuitpython/lib/tinyusb/docs/conf.py | 41 + .../tinyusb/docs/contributing/code_of_conduct.rst | 1 + .../lib/tinyusb/docs/contributing/index.rst | 23 + .../lib/tinyusb/docs/contributing/porting.rst | 241 + .../lib/tinyusb/docs/contributing/structure.rst | 59 + circuitpython/lib/tinyusb/docs/index.rst | 25 + circuitpython/lib/tinyusb/docs/info/changelog.rst | 661 + .../lib/tinyusb/docs/info/contributors.rst | 1 + circuitpython/lib/tinyusb/docs/info/index.rst | 13 + circuitpython/lib/tinyusb/docs/info/uses.rst | 17 + .../lib/tinyusb/docs/reference/concurrency.rst | 42 + .../lib/tinyusb/docs/reference/getting_started.rst | 202 + circuitpython/lib/tinyusb/docs/reference/index.rst | 59 + .../lib/tinyusb/docs/reference/supported.rst | 390 + circuitpython/lib/tinyusb/docs/requirements.txt | 3 + .../lib/tinyusb/examples/device/99-tinyusb.rules | 21 + .../lib/tinyusb/examples/device/CMakeLists.txt | 28 + .../device/audio_4_channel_mic/CMakeLists.txt | 28 + .../examples/device/audio_4_channel_mic/Makefile | 12 + .../examples/device/audio_4_channel_mic/skip.txt | 3 + .../examples/device/audio_4_channel_mic/src/main.c | 458 + .../audio_4_channel_mic/src/plot_audio_samples.py | 34 + .../device/audio_4_channel_mic/src/tusb_config.h | 114 + .../audio_4_channel_mic/src/usb_descriptors.c | 165 + .../examples/device/audio_test/CMakeLists.txt | 28 + .../tinyusb/examples/device/audio_test/Makefile | 12 + .../tinyusb/examples/device/audio_test/skip.txt | 3 + .../tinyusb/examples/device/audio_test/src/main.c | 446 + .../device/audio_test/src/plot_audio_samples.py | 34 + .../examples/device/audio_test/src/tusb_config.h | 107 + .../device/audio_test/src/usb_descriptors.c | 165 + .../examples/device/board_test/CMakeLists.txt | 42 + .../tinyusb/examples/device/board_test/Makefile | 18 + .../examples/device/board_test/sdkconfig.defaults | 3 + .../examples/device/board_test/src/CMakeLists.txt | 17 + .../tinyusb/examples/device/board_test/src/main.c | 79 + .../examples/device/board_test/src/tusb_config.h | 85 + .../examples/device/cdc_dual_ports/CMakeLists.txt | 28 + .../examples/device/cdc_dual_ports/Makefile | 12 + .../examples/device/cdc_dual_ports/src/main.c | 100 + .../device/cdc_dual_ports/src/tusb_config.h | 110 + .../device/cdc_dual_ports/src/usb_descriptors.c | 253 + .../tinyusb/examples/device/cdc_msc/CMakeLists.txt | 29 + .../lib/tinyusb/examples/device/cdc_msc/Makefile | 12 + .../lib/tinyusb/examples/device/cdc_msc/skip.txt | 1 + .../lib/tinyusb/examples/device/cdc_msc/src/main.c | 165 + .../tinyusb/examples/device/cdc_msc/src/msc_disk.c | 272 + .../examples/device/cdc_msc/src/tusb_config.h | 114 + .../examples/device/cdc_msc/src/usb_descriptors.c | 288 + .../device/cdc_msc_freertos/.skip.MCU_F1C100S | 0 .../device/cdc_msc_freertos/CMakeLists.txt | 22 + .../examples/device/cdc_msc_freertos/Makefile | 38 + .../device/cdc_msc_freertos/sdkconfig.defaults | 3 + .../examples/device/cdc_msc_freertos/skip.txt | 10 + .../device/cdc_msc_freertos/src/CMakeLists.txt | 35 + .../src/FreeRTOSConfig/FreeRTOSConfig.h | 191 + .../device/cdc_msc_freertos/src/freertos_hook.c | 114 + .../examples/device/cdc_msc_freertos/src/main.c | 238 + .../device/cdc_msc_freertos/src/msc_disk.c | 250 + .../device/cdc_msc_freertos/src/tusb_config.h | 124 + .../device/cdc_msc_freertos/src/usb_descriptors.c | 264 + .../lib/tinyusb/examples/device/dfu/CMakeLists.txt | 28 + .../lib/tinyusb/examples/device/dfu/Makefile | 12 + .../lib/tinyusb/examples/device/dfu/skip.txt | 2 + .../lib/tinyusb/examples/device/dfu/src/main.c | 219 + .../tinyusb/examples/device/dfu/src/tusb_config.h | 84 + .../examples/device/dfu/src/usb_descriptors.c | 171 + .../examples/device/dfu_runtime/CMakeLists.txt | 28 + .../tinyusb/examples/device/dfu_runtime/Makefile | 12 + .../tinyusb/examples/device/dfu_runtime/src/main.c | 135 + .../examples/device/dfu_runtime/src/tusb_config.h | 82 + .../device/dfu_runtime/src/usb_descriptors.c | 166 + .../device/dynamic_configuration/CMakeLists.txt | 29 + .../examples/device/dynamic_configuration/Makefile | 12 + .../examples/device/dynamic_configuration/skip.txt | 1 + .../device/dynamic_configuration/src/main.c | 217 + .../device/dynamic_configuration/src/msc_disk.c | 250 + .../device/dynamic_configuration/src/tusb_config.h | 114 + .../dynamic_configuration/src/usb_descriptors.c | 243 + .../device/hid_boot_interface/CMakeLists.txt | 28 + .../examples/device/hid_boot_interface/Makefile | 15 + .../examples/device/hid_boot_interface/src/main.c | 255 + .../device/hid_boot_interface/src/tusb_config.h | 106 + .../hid_boot_interface/src/usb_descriptors.c | 180 + .../hid_boot_interface/src/usb_descriptors.h | 35 + .../examples/device/hid_composite/CMakeLists.txt | 28 + .../tinyusb/examples/device/hid_composite/Makefile | 12 + .../examples/device/hid_composite/src/main.c | 302 + .../device/hid_composite/src/tusb_config.h | 106 + .../device/hid_composite/src/usb_descriptors.c | 227 + .../device/hid_composite/src/usb_descriptors.h | 37 + .../hid_composite_freertos/.skip.MCU_F1C100S | 0 .../device/hid_composite_freertos/CMakeLists.txt | 17 + .../device/hid_composite_freertos/Makefile | 37 + .../hid_composite_freertos/sdkconfig.defaults | 3 + .../device/hid_composite_freertos/skip.txt | 9 + .../hid_composite_freertos/src/CMakeLists.txt | 35 + .../src/FreeRTOSConfig/FreeRTOSConfig.h | 191 + .../hid_composite_freertos/src/freertos_hook.c | 114 + .../device/hid_composite_freertos/src/main.c | 364 + .../hid_composite_freertos/src/tusb_config.h | 112 + .../hid_composite_freertos/src/usb_descriptors.c | 225 + .../hid_composite_freertos/src/usb_descriptors.h | 37 + .../device/hid_generic_inout/CMakeLists.txt | 28 + .../examples/device/hid_generic_inout/Makefile | 12 + .../examples/device/hid_generic_inout/boards.js | 4 + .../examples/device/hid_generic_inout/hid_test.js | 68 + .../examples/device/hid_generic_inout/hid_test.py | 22 + .../examples/device/hid_generic_inout/src/main.c | 171 + .../device/hid_generic_inout/src/tusb_config.h | 106 + .../device/hid_generic_inout/src/usb_descriptors.c | 170 + .../device/hid_multiple_interface/CMakeLists.txt | 28 + .../device/hid_multiple_interface/Makefile | 12 + .../device/hid_multiple_interface/src/main.c | 207 + .../hid_multiple_interface/src/tusb_config.h | 106 + .../hid_multiple_interface/src/usb_descriptors.c | 188 + .../examples/device/midi_test/CMakeLists.txt | 28 + .../lib/tinyusb/examples/device/midi_test/Makefile | 12 + .../tinyusb/examples/device/midi_test/src/main.c | 177 + .../examples/device/midi_test/src/tusb_config.h | 107 + .../device/midi_test/src/usb_descriptors.c | 183 + .../examples/device/msc_dual_lun/CMakeLists.txt | 29 + .../tinyusb/examples/device/msc_dual_lun/Makefile | 12 + .../tinyusb/examples/device/msc_dual_lun/skip.txt | 2 + .../examples/device/msc_dual_lun/src/main.c | 113 + .../device/msc_dual_lun/src/msc_disk_dual.c | 352 + .../examples/device/msc_dual_lun/src/tusb_config.h | 106 + .../device/msc_dual_lun/src/usb_descriptors.c | 185 + .../device/net_lwip_webserver/CMakeLists.txt | 81 + .../examples/device/net_lwip_webserver/Makefile | 71 + .../examples/device/net_lwip_webserver/skip.txt | 10 + .../device/net_lwip_webserver/src/arch/cc.h | 75 + .../device/net_lwip_webserver/src/lwipopts.h | 71 + .../examples/device/net_lwip_webserver/src/main.c | 263 + .../device/net_lwip_webserver/src/tusb_config.h | 103 + .../net_lwip_webserver/src/usb_descriptors.c | 248 + .../examples/device/uac2_headset/CMakeLists.txt | 28 + .../tinyusb/examples/device/uac2_headset/Makefile | 12 + .../tinyusb/examples/device/uac2_headset/skip.txt | 6 + .../examples/device/uac2_headset/src/main.c | 442 + .../examples/device/uac2_headset/src/tusb_config.h | 155 + .../device/uac2_headset/src/usb_descriptors.c | 171 + .../device/uac2_headset/src/usb_descriptors.h | 155 + .../tinyusb/examples/device/usbtmc/CMakeLists.txt | 29 + .../lib/tinyusb/examples/device/usbtmc/Makefile | 12 + .../lib/tinyusb/examples/device/usbtmc/skip.txt | 1 + .../lib/tinyusb/examples/device/usbtmc/src/main.c | 143 + .../lib/tinyusb/examples/device/usbtmc/src/main.h | 5 + .../examples/device/usbtmc/src/tusb_config.h | 84 + .../examples/device/usbtmc/src/usb_descriptors.c | 194 + .../examples/device/usbtmc/src/usbtmc_app.c | 329 + .../examples/device/usbtmc/src/usbtmc_app.h | 7 + .../tinyusb/examples/device/usbtmc/visaQuery.py | 209 + .../examples/device/video_capture/CMakeLists.txt | 28 + .../tinyusb/examples/device/video_capture/Makefile | 12 + .../tinyusb/examples/device/video_capture/skip.txt | 2 + .../examples/device/video_capture/src/images.h | 1651 +++ .../examples/device/video_capture/src/main.c | 222 + .../device/video_capture/src/tusb_config.h | 102 + .../device/video_capture/src/usb_descriptors.c | 166 + .../device/video_capture/src/usb_descriptors.h | 113 + .../examples/device/webusb_serial/CMakeLists.txt | 28 + .../tinyusb/examples/device/webusb_serial/Makefile | 12 + .../examples/device/webusb_serial/src/main.c | 300 + .../device/webusb_serial/src/tusb_config.h | 113 + .../device/webusb_serial/src/usb_descriptors.c | 252 + .../device/webusb_serial/src/usb_descriptors.h | 36 + .../lib/tinyusb/examples/host/CMakeLists.txt | 10 + .../tinyusb/examples/host/bare_api/CMakeLists.txt | 27 + .../lib/tinyusb/examples/host/bare_api/Makefile | 28 + .../lib/tinyusb/examples/host/bare_api/only.txt | 9 + .../lib/tinyusb/examples/host/bare_api/src/main.c | 102 + .../examples/host/bare_api/src/tusb_config.h | 94 + .../examples/host/cdc_msc_hid/CMakeLists.txt | 29 + .../lib/tinyusb/examples/host/cdc_msc_hid/Makefile | 26 + .../lib/tinyusb/examples/host/cdc_msc_hid/only.txt | 9 + .../examples/host/cdc_msc_hid/src/hid_app.c | 296 + .../tinyusb/examples/host/cdc_msc_hid/src/main.c | 128 + .../examples/host/cdc_msc_hid/src/msc_app.c | 106 + .../examples/host/cdc_msc_hid/src/tusb_config.h | 94 + .../examples/host/hid_controller/CMakeLists.txt | 28 + .../tinyusb/examples/host/hid_controller/Makefile | 29 + .../tinyusb/examples/host/hid_controller/only.txt | 9 + .../examples/host/hid_controller/src/hid_app.c | 255 + .../examples/host/hid_controller/src/main.c | 94 + .../examples/host/hid_controller/src/tusb_config.h | 95 + .../examples/host/hid_to_cdc/CMakeLists.txt | 28 + .../lib/tinyusb/examples/host/hid_to_cdc/Makefile | 20 + .../lib/tinyusb/examples/host/hid_to_cdc/only.txt | 2 + .../tinyusb/examples/host/hid_to_cdc/src/main.c | 315 + .../examples/host/hid_to_cdc/src/tusb_config.h | 163 + .../examples/host/hid_to_cdc/src/usb_descriptors.c | 266 + circuitpython/lib/tinyusb/examples/make.mk | 138 + circuitpython/lib/tinyusb/examples/rules.mk | 236 + circuitpython/lib/tinyusb/hw/bsp/ansi_escape.h | 97 + circuitpython/lib/tinyusb/hw/bsp/board.c | 149 + circuitpython/lib/tinyusb/hw/bsp/board.h | 147 + circuitpython/lib/tinyusb/hw/bsp/board_mcu.h | 157 + .../boards/raspberrypi_zero_w/board.h | 38 + .../boards/raspberrypi_zero_w/board.mk | 5 + .../lib/tinyusb/hw/bsp/broadcom_32bit/family.c | 156 + .../lib/tinyusb/hw/bsp/broadcom_32bit/family.mk | 46 + .../broadcom_64bit/boards/raspberrypi_cm4/board.h | 38 + .../broadcom_64bit/boards/raspberrypi_cm4/board.mk | 3 + .../boards/raspberrypi_zero2w/board.h | 38 + .../boards/raspberrypi_zero2w/board.mk | 3 + .../lib/tinyusb/hw/bsp/broadcom_64bit/family.c | 156 + .../lib/tinyusb/hw/bsp/broadcom_64bit/family.mk | 46 + .../hw/bsp/brtmm90x/boards/mm900evxb/board.h | 50 + circuitpython/lib/tinyusb/hw/bsp/brtmm90x/family.c | 215 + .../lib/tinyusb/hw/bsp/brtmm90x/family.mk | 67 + circuitpython/lib/tinyusb/hw/bsp/d5035_01/board.mk | 61 + .../lib/tinyusb/hw/bsp/d5035_01/d5035_01.c | 353 + .../tinyusb/hw/bsp/d5035_01/same51j19a_flash.ld | 163 + .../lib/tinyusb/hw/bsp/da14695_dk_usb/board.mk | 55 + .../tinyusb/hw/bsp/da14695_dk_usb/da14695_dk_usb.c | 134 + .../lib/tinyusb/hw/bsp/da14695_dk_usb/da1469x.ld | 245 + .../hw/bsp/da14695_dk_usb/gcc_startup_da1469x.S | 301 + .../hw/bsp/da14695_dk_usb/product_header.dump | Bin 0 -> 8192 bytes .../tinyusb/hw/bsp/da14695_dk_usb/syscfg/syscfg.h | 34 + .../lib/tinyusb/hw/bsp/da1469x_dk_pro/board.mk | 55 + .../tinyusb/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c | 151 + .../lib/tinyusb/hw/bsp/da1469x_dk_pro/da1469x.ld | 245 + .../hw/bsp/da1469x_dk_pro/gcc_startup_da1469x.S | 301 + .../hw/bsp/da1469x_dk_pro/product_header.dump | Bin 0 -> 8192 bytes .../tinyusb/hw/bsp/da1469x_dk_pro/syscfg/syscfg.h | 34 + circuitpython/lib/tinyusb/hw/bsp/ea4088qs/board.mk | 46 + .../lib/tinyusb/hw/bsp/ea4088qs/ea4088qs.c | 190 + .../lib/tinyusb/hw/bsp/ea4088qs/lpc4088.ld | 184 + circuitpython/lib/tinyusb/hw/bsp/ea4357/board.mk | 48 + circuitpython/lib/tinyusb/hw/bsp/ea4357/ea4357.c | 291 + circuitpython/lib/tinyusb/hw/bsp/ea4357/lpc4357.ld | 324 + circuitpython/lib/tinyusb/hw/bsp/ea4357/pca9532.c | 352 + circuitpython/lib/tinyusb/hw/bsp/ea4357/pca9532.h | 94 + .../tinyusb/hw/bsp/esp32s2/boards/CMakeLists.txt | 12 + .../boards/adafruit_feather_esp32s2/board.cmake | 17 + .../boards/adafruit_feather_esp32s2/board.h | 45 + .../boards/adafruit_magtag_29gray/board.cmake | 17 + .../esp32s2/boards/adafruit_magtag_29gray/board.h | 45 + .../boards/adafruit_metro_esp32s2/board.cmake | 17 + .../esp32s2/boards/adafruit_metro_esp32s2/board.h | 43 + .../lib/tinyusb/hw/bsp/esp32s2/boards/esp32s2.c | 153 + .../esp32s2/boards/espressif_kaluga_1/board.cmake | 17 + .../bsp/esp32s2/boards/espressif_kaluga_1/board.h | 44 + .../esp32s2/boards/espressif_saola_1/board.cmake | 17 + .../bsp/esp32s2/boards/espressif_saola_1/board.h | 45 + .../esp32s2/components/led_strip/CMakeLists.txt | 8 + .../components/led_strip/include/led_strip.h | 126 + .../led_strip/src/led_strip_rmt_ws2812.c | 171 + .../lib/tinyusb/hw/bsp/esp32s2/family.cmake | 7 + circuitpython/lib/tinyusb/hw/bsp/esp32s2/family.mk | 24 + .../tinyusb/hw/bsp/esp32s3/boards/CMakeLists.txt | 14 + .../lib/tinyusb/hw/bsp/esp32s3/boards/esp32s3.c | 153 + .../esp32s3/boards/espressif_addax_1/board.cmake | 7 + .../bsp/esp32s3/boards/espressif_addax_1/board.h | 44 + .../boards/espressif_s3_devkitc/board.cmake | 7 + .../esp32s3/boards/espressif_s3_devkitc/board.h | 43 + .../boards/espressif_s3_devkitm/board.cmake | 7 + .../esp32s3/boards/espressif_s3_devkitm/board.h | 43 + .../esp32s3/components/led_strip/CMakeLists.txt | 8 + .../components/led_strip/include/led_strip.h | 126 + .../led_strip/src/led_strip_rmt_ws2812.c | 171 + .../lib/tinyusb/hw/bsp/esp32s3/family.cmake | 7 + circuitpython/lib/tinyusb/hw/bsp/esp32s3/family.mk | 26 + circuitpython/lib/tinyusb/hw/bsp/f1c100s/README.md | 20 + circuitpython/lib/tinyusb/hw/bsp/f1c100s/board.h | 1 + circuitpython/lib/tinyusb/hw/bsp/f1c100s/board.mk | 52 + circuitpython/lib/tinyusb/hw/bsp/f1c100s/f1c100s.c | 130 + .../lib/tinyusb/hw/bsp/family_support.cmake | 100 + .../lib/tinyusb/hw/bsp/fomu/boards/fomu/board.h | 40 + .../lib/tinyusb/hw/bsp/fomu/boards/fomu/board.mk | 1 + .../lib/tinyusb/hw/bsp/fomu/crt0-vexriscv.S | 83 + circuitpython/lib/tinyusb/hw/bsp/fomu/dfu.py | 95 + circuitpython/lib/tinyusb/hw/bsp/fomu/family.mk | 30 + circuitpython/lib/tinyusb/hw/bsp/fomu/fomu.c | 120 + circuitpython/lib/tinyusb/hw/bsp/fomu/fomu.ld | 104 + .../lib/tinyusb/hw/bsp/fomu/include/csr.h | 750 ++ .../lib/tinyusb/hw/bsp/fomu/include/hw/common.h | 33 + .../lib/tinyusb/hw/bsp/fomu/include/irq.h | 71 + .../lib/tinyusb/hw/bsp/fomu/output_format.ld | 1 + circuitpython/lib/tinyusb/hw/bsp/fomu/regions.ld | 6 + .../lib/tinyusb/hw/bsp/frdm_k32l2b/board.h | 56 + .../lib/tinyusb/hw/bsp/frdm_k32l2b/board.mk | 51 + .../lib/tinyusb/hw/bsp/frdm_k32l2b/frdm_k32l2b.c | 140 + .../lib/tinyusb/hw/bsp/frdm_kl25z/board.mk | 52 + .../lib/tinyusb/hw/bsp/frdm_kl25z/frdm_kl25z.c | 176 + .../gd32vf103/boards/sipeed_longan_nano/board.h | 20 + .../gd32vf103/boards/sipeed_longan_nano/board.mk | 13 + .../lib/tinyusb/hw/bsp/gd32vf103/family.c | 197 + .../lib/tinyusb/hw/bsp/gd32vf103/family.mk | 67 + .../tinyusb/hw/bsp/gd32vf103/system_gd32vf103.c | 668 + .../hw/bsp/imxrt/boards/mimxrt1010_evk/board.h | 53 + .../hw/bsp/imxrt/boards/mimxrt1010_evk/board.mk | 11 + .../evkmimxrt1010_flexspi_nor_config.c | 48 + .../evkmimxrt1010_flexspi_nor_config.h | 267 + .../hw/bsp/imxrt/boards/mimxrt1015_evk/board.h | 51 + .../hw/bsp/imxrt/boards/mimxrt1015_evk/board.mk | 11 + .../evkmimxrt1015_flexspi_nor_config.c | 48 + .../evkmimxrt1015_flexspi_nor_config.h | 268 + .../hw/bsp/imxrt/boards/mimxrt1020_evk/board.h | 51 + .../hw/bsp/imxrt/boards/mimxrt1020_evk/board.mk | 11 + .../evkmimxrt1020_flexspi_nor_config.c | 49 + .../evkmimxrt1020_flexspi_nor_config.h | 268 + .../hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h | 51 + .../hw/bsp/imxrt/boards/mimxrt1050_evkb/board.mk | 8 + .../evkbimxrt1050_flexspi_nor_config.c | 55 + .../evkbimxrt1050_flexspi_nor_config.h | 269 + .../hw/bsp/imxrt/boards/mimxrt1060_evk/board.h | 51 + .../hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk | 14 + .../evkmimxrt1060_flexspi_nor_config.c | 49 + .../evkmimxrt1060_flexspi_nor_config.h | 268 + .../hw/bsp/imxrt/boards/mimxrt1064_evk/board.h | 52 + .../hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk | 14 + .../evkmimxrt1064_flexspi_nor_config.c | 49 + .../evkmimxrt1064_flexspi_nor_config.h | 268 + .../tinyusb/hw/bsp/imxrt/boards/teensy_40/board.h | 52 + .../tinyusb/hw/bsp/imxrt/boards/teensy_40/board.mk | 10 + .../boards/teensy_40/teensy40_flexspi_nor_config.c | 49 + .../boards/teensy_40/teensy40_flexspi_nor_config.h | 268 + circuitpython/lib/tinyusb/hw/bsp/imxrt/family.c | 207 + circuitpython/lib/tinyusb/hw/bsp/imxrt/family.mk | 63 + .../tinyusb/hw/bsp/kuiic/K32L2B31xxxxA_flash.ld | 217 + circuitpython/lib/tinyusb/hw/bsp/kuiic/board.h | 45 + circuitpython/lib/tinyusb/hw/bsp/kuiic/board.mk | 52 + circuitpython/lib/tinyusb/hw/bsp/kuiic/kuiic.c | 203 + .../hw/bsp/lpc15/boards/lpcxpresso1549/board.h | 72 + .../hw/bsp/lpc15/boards/lpcxpresso1549/board.mk | 7 + .../hw/bsp/lpc15/boards/lpcxpresso1549/lpc1549.ld | 246 + circuitpython/lib/tinyusb/hw/bsp/lpc15/family.c | 130 + circuitpython/lib/tinyusb/hw/bsp/lpc15/family.mk | 39 + .../hw/bsp/lpc18/boards/lpcxpresso18s37/board.h | 77 + .../hw/bsp/lpc18/boards/lpcxpresso18s37/board.mk | 6 + .../hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld | 404 + .../tinyusb/hw/bsp/lpc18/boards/mcb1800/board.h | 94 + .../tinyusb/hw/bsp/lpc18/boards/mcb1800/board.mk | 7 + .../tinyusb/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld | 323 + circuitpython/lib/tinyusb/hw/bsp/lpc18/family.c | 159 + circuitpython/lib/tinyusb/hw/bsp/lpc18/family.mk | 37 + .../hw/bsp/lpc54/boards/lpcxpresso54114/board.h | 59 + .../hw/bsp/lpc54/boards/lpcxpresso54114/board.mk | 13 + .../hw/bsp/lpc54/boards/lpcxpresso54628/board.h | 59 + .../hw/bsp/lpc54/boards/lpcxpresso54628/board.mk | 18 + circuitpython/lib/tinyusb/hw/bsp/lpc54/family.c | 228 + circuitpython/lib/tinyusb/hw/bsp/lpc54/family.mk | 54 + .../double_m33_express/LPC55S69_cm33_core0_uf2.ld | 234 + .../hw/bsp/lpc55/boards/double_m33_express/board.h | 63 + .../bsp/lpc55/boards/double_m33_express/board.mk | 12 + .../hw/bsp/lpc55/boards/lpcxpresso55s28/board.h | 56 + .../hw/bsp/lpc55/boards/lpcxpresso55s28/board.mk | 11 + .../hw/bsp/lpc55/boards/lpcxpresso55s69/board.h | 56 + .../hw/bsp/lpc55/boards/lpcxpresso55s69/board.mk | 11 + .../tinyusb/hw/bsp/lpc55/boards/mcu_link/board.h | 56 + .../tinyusb/hw/bsp/lpc55/boards/mcu_link/board.mk | 11 + circuitpython/lib/tinyusb/hw/bsp/lpc55/family.c | 283 + circuitpython/lib/tinyusb/hw/bsp/lpc55/family.mk | 67 + .../lib/tinyusb/hw/bsp/lpcxpresso11u37/board.mk | 46 + .../lib/tinyusb/hw/bsp/lpcxpresso11u37/lpc11u37.ld | 195 + .../hw/bsp/lpcxpresso11u37/lpcxpresso11u37.c | 208 + .../lib/tinyusb/hw/bsp/lpcxpresso11u68/board.mk | 42 + .../lib/tinyusb/hw/bsp/lpcxpresso11u68/lpc11u68.ld | 242 + .../hw/bsp/lpcxpresso11u68/lpcxpresso11u68.c | 135 + .../lib/tinyusb/hw/bsp/lpcxpresso1347/board.mk | 45 + .../lib/tinyusb/hw/bsp/lpcxpresso1347/lpc1347.ld | 225 + .../tinyusb/hw/bsp/lpcxpresso1347/lpcxpresso1347.c | 152 + .../lib/tinyusb/hw/bsp/lpcxpresso1769/board.mk | 43 + .../lib/tinyusb/hw/bsp/lpcxpresso1769/lpc1769.ld | 184 + .../tinyusb/hw/bsp/lpcxpresso1769/lpcxpresso1769.c | 209 + .../lib/tinyusb/hw/bsp/lpcxpresso51u68/board.mk | 52 + .../hw/bsp/lpcxpresso51u68/lpcxpresso51u68.c | 179 + circuitpython/lib/tinyusb/hw/bsp/mbed1768/board.mk | 45 + .../lib/tinyusb/hw/bsp/mbed1768/lpc1768.ld | 184 + .../lib/tinyusb/hw/bsp/mbed1768/mbed1768.c | 197 + .../hw/bsp/mm32/boards/mm32f327x_mb39/board.mk | 8 + .../hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld | 163 + .../mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c | 172 + circuitpython/lib/tinyusb/hw/bsp/mm32/family.mk | 36 + .../hw/bsp/msp430/boards/msp_exp430f5529lp/board.h | 46 + circuitpython/lib/tinyusb/hw/bsp/msp430/family.c | 218 + circuitpython/lib/tinyusb/hw/bsp/msp430/family.mk | 35 + .../hw/bsp/msp432e4/boards/msp_exp432e401y/board.h | 46 + circuitpython/lib/tinyusb/hw/bsp/msp432e4/family.c | 203 + .../lib/tinyusb/hw/bsp/msp432e4/family.mk | 41 + circuitpython/lib/tinyusb/hw/bsp/ngx4330/board.mk | 47 + circuitpython/lib/tinyusb/hw/bsp/ngx4330/ngx4330.c | 264 + .../lib/tinyusb/hw/bsp/ngx4330/ngx4330.ld | 343 + .../hw/bsp/nrf/boards/adafruit_clue/board.h | 52 + .../hw/bsp/nrf/boards/adafruit_clue/board.mk | 10 + .../nrf/boards/adafruit_clue/nrf52840_s140_v6.ld | 38 + .../arduino_nano33_ble/arduino_nano33_ble.ld | 32 + .../hw/bsp/nrf/boards/arduino_nano33_ble/board.h | 52 + .../hw/bsp/nrf/boards/arduino_nano33_ble/board.mk | 13 + .../nrf/boards/circuitplayground_bluefruit/board.h | 52 + .../boards/circuitplayground_bluefruit/board.mk | 10 + .../nrf52840_s140_v6.ld | 38 + .../nrf/boards/feather_nrf52840_express/board.h | 52 + .../nrf/boards/feather_nrf52840_express/board.mk | 10 + .../feather_nrf52840_express/nrf52840_s140_v6.ld | 38 + .../bsp/nrf/boards/feather_nrf52840_sense/board.h | 52 + .../bsp/nrf/boards/feather_nrf52840_sense/board.mk | 10 + .../feather_nrf52840_sense/nrf52840_s140_v6.ld | 38 + .../hw/bsp/nrf/boards/itsybitsy_nrf52840/board.h | 52 + .../hw/bsp/nrf/boards/itsybitsy_nrf52840/board.mk | 10 + .../boards/itsybitsy_nrf52840/nrf52840_s140_v6.ld | 38 + .../hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.h | 52 + .../hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.mk | 15 + .../nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld | 13 + .../lib/tinyusb/hw/bsp/nrf/boards/pca10056/board.h | 50 + .../tinyusb/hw/bsp/nrf/boards/pca10056/board.mk | 7 + .../lib/tinyusb/hw/bsp/nrf/boards/pca10059/board.h | 52 + .../tinyusb/hw/bsp/nrf/boards/pca10059/board.mk | 15 + .../tinyusb/hw/bsp/nrf/boards/pca10059/pca10059.ld | 13 + .../lib/tinyusb/hw/bsp/nrf/boards/pca10100/board.h | 52 + .../tinyusb/hw/bsp/nrf/boards/pca10100/board.mk | 7 + .../hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.h | 52 + .../hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.mk | 7 + circuitpython/lib/tinyusb/hw/bsp/nrf/family.c | 224 + circuitpython/lib/tinyusb/hw/bsp/nrf/family.mk | 48 + .../lib/tinyusb/hw/bsp/nutiny_nuc121s/board.mk | 43 + .../tinyusb/hw/bsp/nutiny_nuc121s/nuc121_flash.ld | 195 + .../tinyusb/hw/bsp/nutiny_nuc121s/nutiny_nuc121.c | 121 + .../lib/tinyusb/hw/bsp/nutiny_nuc125s/board.mk | 39 + .../tinyusb/hw/bsp/nutiny_nuc125s/nuc125_flash.ld | 195 + .../tinyusb/hw/bsp/nutiny_nuc125s/nutiny_nuc125.c | 121 + .../lib/tinyusb/hw/bsp/nutiny_nuc126v/board.mk | 45 + .../tinyusb/hw/bsp/nutiny_nuc126v/nuc126_flash.ld | 195 + .../tinyusb/hw/bsp/nutiny_nuc126v/nutiny_nuc126.c | 153 + .../lib/tinyusb/hw/bsp/nutiny_sdk_nuc120/board.mk | 41 + .../hw/bsp/nutiny_sdk_nuc120/nuc120_flash.ld | 195 + .../hw/bsp/nutiny_sdk_nuc120/nutiny_sdk_nuc120.c | 133 + .../lib/tinyusb/hw/bsp/nutiny_sdk_nuc505/board.mk | 60 + .../hw/bsp/nutiny_sdk_nuc505/nuc505_flashtoram.ld | 199 + .../hw/bsp/nutiny_sdk_nuc505/nutiny_sdk_nuc505.c | 129 + .../hw/bsp/pic32mz/boards/olimex_emz64/board.mk | 5 + .../bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c | 144 + .../hw/bsp/pic32mz/boards/olimex_hmz144/board.mk | 5 + .../pic32mz/boards/olimex_hmz144/olimex_hmz144.c | 142 + circuitpython/lib/tinyusb/hw/bsp/pic32mz/family.c | 110 + circuitpython/lib/tinyusb/hw/bsp/pic32mz/family.mk | 20 + circuitpython/lib/tinyusb/hw/bsp/rp2040/board.h | 53 + .../boards/adafruit_feather_rp2040/board.cmake | 1 + .../boards/adafruit_itsybitsy_rp2040/board.cmake | 1 + .../rp2040/boards/adafruit_qtpy_rp2040/board.cmake | 1 + .../hw/bsp/rp2040/boards/pico_sdk/board.cmake | 1 + .../rp2040/boards/raspberry_pi_pico/board.cmake | 1 + circuitpython/lib/tinyusb/hw/bsp/rp2040/family.c | 199 + .../lib/tinyusb/hw/bsp/rp2040/family.cmake | 179 + circuitpython/lib/tinyusb/hw/bsp/rp2040/family.mk | 19 + .../tinyusb/hw/bsp/rp2040/pico_sdk_import.cmake | 62 + .../tinyusb/hw/bsp/rx/boards/gr_citrus/board.mk | 24 + .../tinyusb/hw/bsp/rx/boards/gr_citrus/gr_citrus.c | 275 + .../tinyusb/hw/bsp/rx/boards/gr_citrus/hwinit.c | 31 + .../hw/bsp/rx/boards/gr_citrus/r5f5631fd.ld | 127 + .../tinyusb/hw/bsp/rx/boards/rx65n_target/board.mk | 25 + .../hw/bsp/rx/boards/rx65n_target/r5f565ne.ld | 168 + .../hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 325 + circuitpython/lib/tinyusb/hw/bsp/rx/family.mk | 33 + .../tinyusb/hw/bsp/samd11/boards/luna_d11/board.h | 46 + .../tinyusb/hw/bsp/samd11/boards/luna_d11/board.mk | 11 + .../samd11/boards/luna_d11/samd11d14am_flash.ld | 144 + .../hw/bsp/samd11/boards/samd11_xplained/board.h | 46 + .../hw/bsp/samd11/boards/samd11_xplained/board.mk | 11 + .../boards/samd11_xplained/samd11d14am_flash.ld | 144 + circuitpython/lib/tinyusb/hw/bsp/samd11/family.c | 150 + circuitpython/lib/tinyusb/hw/bsp/samd11/family.mk | 40 + .../hw/bsp/samd21/boards/atsamd21_xpro/board.h | 50 + .../hw/bsp/samd21/boards/atsamd21_xpro/board.mk | 10 + .../boards/atsamd21_xpro/samd21j18a_flash.ld | 144 + .../boards/circuitplayground_express/board.h | 50 + .../boards/circuitplayground_express/board.mk | 9 + .../circuitplayground_express.ld | 146 + .../hw/bsp/samd21/boards/curiosity_nano/board.h | 50 + .../hw/bsp/samd21/boards/curiosity_nano/board.mk | 14 + .../boards/curiosity_nano/samd21g17a_flash.ld | 144 + .../bsp/samd21/boards/feather_m0_express/board.h | 50 + .../bsp/samd21/boards/feather_m0_express/board.mk | 9 + .../feather_m0_express/feather_m0_express.ld | 146 + .../hw/bsp/samd21/boards/itsybitsy_m0/board.h | 50 + .../hw/bsp/samd21/boards/itsybitsy_m0/board.mk | 9 + .../bsp/samd21/boards/itsybitsy_m0/itsybitsy_m0.ld | 146 + .../tinyusb/hw/bsp/samd21/boards/luna_d21/board.h | 46 + .../tinyusb/hw/bsp/samd21/boards/luna_d21/board.mk | 11 + .../bsp/samd21/boards/luna_d21/samd21g18a_flash.ld | 144 + .../hw/bsp/samd21/boards/metro_m0_express/board.h | 50 + .../hw/bsp/samd21/boards/metro_m0_express/board.mk | 9 + .../boards/metro_m0_express/metro_m0_express.ld | 146 + .../lib/tinyusb/hw/bsp/samd21/boards/qtpy/board.h | 46 + .../lib/tinyusb/hw/bsp/samd21/boards/qtpy/board.mk | 11 + .../lib/tinyusb/hw/bsp/samd21/boards/qtpy/qtpy.ld | 146 + .../hw/bsp/samd21/boards/seeeduino_xiao/board.h | 50 + .../hw/bsp/samd21/boards/seeeduino_xiao/board.mk | 9 + .../samd21/boards/seeeduino_xiao/seeeduino_xiao.ld | 146 + .../hw/bsp/samd21/boards/trinket_m0/board.h | 34 + .../hw/bsp/samd21/boards/trinket_m0/board.mk | 5 + .../hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld | 146 + circuitpython/lib/tinyusb/hw/bsp/samd21/family.c | 249 + circuitpython/lib/tinyusb/hw/bsp/samd21/family.mk | 49 + .../bsp/samd51/boards/feather_m4_express/board.h | 50 + .../bsp/samd51/boards/feather_m4_express/board.mk | 8 + .../feather_m4_express/feather_m4_express.ld | 166 + .../hw/bsp/samd51/boards/itsybitsy_m4/board.h | 50 + .../hw/bsp/samd51/boards/itsybitsy_m4/board.mk | 9 + .../bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld | 166 + .../hw/bsp/samd51/boards/metro_m4_express/board.h | 50 + .../hw/bsp/samd51/boards/metro_m4_express/board.mk | 10 + .../boards/metro_m4_express/metro_m4_express.ld | 166 + .../tinyusb/hw/bsp/samd51/boards/pybadge/board.h | 50 + .../tinyusb/hw/bsp/samd51/boards/pybadge/board.mk | 8 + .../hw/bsp/samd51/boards/pybadge/pybadge.ld | 166 + .../tinyusb/hw/bsp/samd51/boards/pyportal/board.h | 50 + .../tinyusb/hw/bsp/samd51/boards/pyportal/board.mk | 8 + .../hw/bsp/samd51/boards/pyportal/pyportal.ld | 166 + circuitpython/lib/tinyusb/hw/bsp/samd51/family.c | 162 + circuitpython/lib/tinyusb/hw/bsp/samd51/family.mk | 50 + .../lib/tinyusb/hw/bsp/same54xplainedpro/board.mk | 48 + .../hw/bsp/same54xplainedpro/same54p20a_flash.ld | 163 + .../hw/bsp/same54xplainedpro/same54p20a_sram.ld | 162 + .../hw/bsp/same54xplainedpro/same54xplainedpro.c | 306 + .../lib/tinyusb/hw/bsp/same70_qmtech/board.mk | 56 + .../tinyusb/hw/bsp/same70_qmtech/hpl_pmc_config.h | 1053 ++ .../hw/bsp/same70_qmtech/hpl_usart_config.h | 215 + .../hw/bsp/same70_qmtech/hpl_xdmac_config.h | 4400 +++++++ .../hw/bsp/same70_qmtech/peripheral_clk_config.h | 126 + .../tinyusb/hw/bsp/same70_qmtech/same70_qmtech.c | 159 + .../lib/tinyusb/hw/bsp/same70_xplained/board.mk | 56 + .../hw/bsp/same70_xplained/hpl_pmc_config.h | 1053 ++ .../hw/bsp/same70_xplained/hpl_usart_config.h | 215 + .../hw/bsp/same70_xplained/hpl_xdmac_config.h | 4400 +++++++ .../hw/bsp/same70_xplained/peripheral_clk_config.h | 126 + .../hw/bsp/same70_xplained/same70_xplained.c | 156 + .../lib/tinyusb/hw/bsp/samg55xplained/board.mk | 52 + .../hw/bsp/samg55xplained/hpl_usart_config.h | 215 + .../hw/bsp/samg55xplained/peripheral_clk_config.h | 85 + .../hw/bsp/samg55xplained/samg55j19_flash.ld | 158 + .../tinyusb/hw/bsp/samg55xplained/samg55xplained.c | 157 + .../hw/bsp/saml2x/boards/atsaml21_xpro/board.h | 50 + .../hw/bsp/saml2x/boards/atsaml21_xpro/board.mk | 12 + .../boards/atsaml21_xpro/saml21j18b_flash.ld | 153 + .../hw/bsp/saml2x/boards/saml22_feather/board.h | 47 + .../hw/bsp/saml2x/boards/saml22_feather/board.mk | 11 + .../saml2x/boards/saml22_feather/saml22_feather.ld | 146 + .../hw/bsp/saml2x/boards/sensorwatch_m0/board.h | 47 + .../hw/bsp/saml2x/boards/sensorwatch_m0/board.mk | 11 + .../saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld | 146 + circuitpython/lib/tinyusb/hw/bsp/saml2x/family.c | 163 + circuitpython/lib/tinyusb/hw/bsp/saml2x/family.mk | 51 + circuitpython/lib/tinyusb/hw/bsp/sltb009a/board.mk | 43 + .../lib/tinyusb/hw/bsp/sltb009a/sltb009a.c | 721 ++ .../lib/tinyusb/hw/bsp/spresense/board.mk | 74 + .../lib/tinyusb/hw/bsp/spresense/board_spresense.c | 105 + .../bsp/stm32f0/boards/stm32f070rbnucleo/board.h | 93 + .../bsp/stm32f0/boards/stm32f070rbnucleo/board.mk | 11 + .../stm32f070rbnucleo/stm32F070rbtx_flash.ld | 200 + .../boards/stm32f072disco/STM32F072RBTx_FLASH.ld | 169 + .../hw/bsp/stm32f0/boards/stm32f072disco/board.h | 85 + .../hw/bsp/stm32f0/boards/stm32f072disco/board.mk | 11 + .../boards/stm32f072eval/STM32F072VBTx_FLASH.ld | 177 + .../hw/bsp/stm32f0/boards/stm32f072eval/board.h | 102 + .../hw/bsp/stm32f0/boards/stm32f072eval/board.mk | 11 + circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.c | 182 + circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.mk | 40 + .../tinyusb/hw/bsp/stm32f0/stm32f0xx_hal_conf.h | 321 + .../boards/stm32f103_bluepill/STM32F103X8_FLASH.ld | 167 + .../bsp/stm32f1/boards/stm32f103_bluepill/board.h | 92 + .../bsp/stm32f1/boards/stm32f103_bluepill/board.mk | 11 + .../boards/stm32f103_mini_2/STM32F103XC_FLASH.ld | 167 + .../hw/bsp/stm32f1/boards/stm32f103_mini_2/board.h | 92 + .../bsp/stm32f1/boards/stm32f103_mini_2/board.mk | 11 + circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.c | 167 + circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.mk | 45 + .../tinyusb/hw/bsp/stm32f1/stm32f1xx_hal_conf.h | 379 + .../hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld | 169 + .../lib/tinyusb/hw/bsp/stm32f207nucleo/board.mk | 48 + .../hw/bsp/stm32f207nucleo/stm32f207nucleo.c | 213 + .../hw/bsp/stm32f207nucleo/stm32f2xx_hal_conf.h | 407 + .../hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld | 189 + .../lib/tinyusb/hw/bsp/stm32f303disco/board.mk | 49 + .../tinyusb/hw/bsp/stm32f303disco/stm32f303disco.c | 215 + .../hw/bsp/stm32f303disco/stm32f3xx_hal_conf.h | 357 + .../feather_stm32f405/STM32F405RGTx_FLASH.ld | 189 + .../bsp/stm32f4/boards/feather_stm32f405/board.h | 104 + .../bsp/stm32f4/boards/feather_stm32f405/board.mk | 12 + .../boards/feather_stm32f405/stm32f4xx_hal_conf.h | 491 + .../boards/pyboardv11/STM32F405RGTx_FLASH.ld | 189 + .../hw/bsp/stm32f4/boards/pyboardv11/board.h | 102 + .../hw/bsp/stm32f4/boards/pyboardv11/board.mk | 11 + .../stm32f4/boards/pyboardv11/stm32f4xx_hal_conf.h | 491 + .../stm32f401blackpill/STM32F401VCTx_FLASH.ld | 169 + .../bsp/stm32f4/boards/stm32f401blackpill/board.h | 106 + .../bsp/stm32f4/boards/stm32f401blackpill/board.mk | 12 + .../boards/stm32f401blackpill/stm32f4xx_hal_conf.h | 493 + .../boards/stm32f407disco/STM32F407VGTx_FLASH.ld | 189 + .../hw/bsp/stm32f4/boards/stm32f407disco/board.h | 105 + .../hw/bsp/stm32f4/boards/stm32f407disco/board.mk | 11 + .../boards/stm32f407disco/stm32f4xx_hal_conf.h | 493 + .../stm32f411blackpill/STM32F411CEUx_FLASH.ld | 169 + .../bsp/stm32f4/boards/stm32f411blackpill/board.h | 106 + .../bsp/stm32f4/boards/stm32f411blackpill/board.mk | 12 + .../boards/stm32f411blackpill/stm32f4xx_hal_conf.h | 493 + .../boards/stm32f411disco/STM32F411VETx_FLASH.ld | 169 + .../hw/bsp/stm32f4/boards/stm32f411disco/board.h | 104 + .../hw/bsp/stm32f4/boards/stm32f411disco/board.mk | 11 + .../boards/stm32f411disco/stm32f4xx_hal_conf.h | 493 + .../boards/stm32f412disco/STM32F412ZGTx_FLASH.ld | 169 + .../hw/bsp/stm32f4/boards/stm32f412disco/board.h | 118 + .../hw/bsp/stm32f4/boards/stm32f412disco/board.mk | 11 + .../boards/stm32f412disco/stm32f4xx_hal_conf.h | 493 + .../boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld | 169 + .../hw/bsp/stm32f4/boards/stm32f412nucleo/board.h | 119 + .../hw/bsp/stm32f4/boards/stm32f412nucleo/board.mk | 11 + .../boards/stm32f412nucleo/stm32f4xx_hal_conf.h | 493 + .../boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld | 206 + .../hw/bsp/stm32f4/boards/stm32f439nucleo/board.h | 108 + .../hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk | 11 + .../boards/stm32f439nucleo/stm32f4xx_hal_conf.h | 486 + circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.c | 201 + circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.mk | 43 + .../boards/stlinkv3mini/STM32F723xE_FLASH.ld | 167 + .../hw/bsp/stm32f7/boards/stlinkv3mini/board.h | 101 + .../hw/bsp/stm32f7/boards/stlinkv3mini/board.mk | 14 + .../boards/stlinkv3mini/stm32f7xx_hal_conf.h | 472 + .../boards/stm32f723disco/STM32F723xE_FLASH.ld | 167 + .../hw/bsp/stm32f7/boards/stm32f723disco/board.h | 105 + .../hw/bsp/stm32f7/boards/stm32f723disco/board.mk | 15 + .../boards/stm32f723disco/stm32f7xx_hal_conf.h | 472 + .../boards/stm32f746disco/STM32F746ZGTx_FLASH.ld | 167 + .../hw/bsp/stm32f7/boards/stm32f746disco/board.h | 100 + .../hw/bsp/stm32f7/boards/stm32f746disco/board.mk | 12 + .../boards/stm32f746disco/stm32f7xx_hal_conf.h | 472 + .../boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld | 167 + .../hw/bsp/stm32f7/boards/stm32f746nucleo/board.h | 98 + .../hw/bsp/stm32f7/boards/stm32f746nucleo/board.mk | 12 + .../boards/stm32f746nucleo/stm32f7xx_hal_conf.h | 472 + .../boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld | 169 + .../hw/bsp/stm32f7/boards/stm32f767nucleo/board.h | 102 + .../hw/bsp/stm32f7/boards/stm32f767nucleo/board.mk | 15 + .../boards/stm32f767nucleo/stm32f7xx_hal_conf.h | 472 + .../boards/stm32f769disco/STM32F769ZITx_FLASH.ld | 167 + .../hw/bsp/stm32f7/boards/stm32f769disco/board.h | 101 + .../hw/bsp/stm32f7/boards/stm32f769disco/board.mk | 13 + .../boards/stm32f769disco/stm32f7xx_hal_conf.h | 472 + circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.c | 314 + circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.mk | 54 + .../boards/stm32g474nucleo/STM32G474RETx_FLASH.ld | 190 + .../hw/bsp/stm32g4/boards/stm32g474nucleo/board.h | 134 + .../hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk | 10 + circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.c | 186 + circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.mk | 44 + .../tinyusb/hw/bsp/stm32g4/stm32g4xx_hal_conf.h | 381 + .../hw/bsp/stm32h7/boards/stm32h743eval/board.h | 143 + .../hw/bsp/stm32h7/boards/stm32h743eval/board.mk | 14 + .../boards/stm32h743eval/stm32h743xx_flash.ld | 173 + .../hw/bsp/stm32h7/boards/stm32h743nucleo/board.h | 122 + .../hw/bsp/stm32h7/boards/stm32h743nucleo/board.mk | 13 + .../boards/stm32h743nucleo/stm32h743xx_flash.ld | 173 + .../hw/bsp/stm32h7/boards/stm32h745disco/board.h | 139 + .../hw/bsp/stm32h7/boards/stm32h745disco/board.mk | 17 + .../waveshare_openh743i/STM32H743IITX_FLASH.ld | 175 + .../bsp/stm32h7/boards/waveshare_openh743i/board.h | 229 + .../stm32h7/boards/waveshare_openh743i/board.mk | 19 + circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.c | 268 + circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.mk | 57 + .../tinyusb/hw/bsp/stm32h7/stm32h7xx_hal_conf.h | 483 + .../hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld | 169 + .../lib/tinyusb/hw/bsp/stm32l0538disco/board.mk | 54 + .../hw/bsp/stm32l0538disco/stm32l0538disco.c | 205 + .../hw/bsp/stm32l0538disco/stm32l0xx_hal_conf.h | 331 + .../boards/stm32l476disco/STM32L476VGTx_FLASH.ld | 183 + .../hw/bsp/stm32l4/boards/stm32l476disco/board.h | 139 + .../hw/bsp/stm32l4/boards/stm32l476disco/board.mk | 10 + .../boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld | 200 + .../hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.h | 137 + .../hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.mk | 10 + .../boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld | 167 + .../hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.h | 137 + .../hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.mk | 14 + circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.c | 198 + circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.mk | 45 + .../tinyusb/hw/bsp/stm32l4/stm32l4xx_hal_conf.h | 420 + .../hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h | 122 + .../hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk | 9 + .../stm32wb55nucleo/stm32wb55xx_flash_cm4.ld | 171 + circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.c | 190 + circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.mk | 44 + .../tinyusb/hw/bsp/stm32wb/stm32wbxx_hal_conf.h | 349 + .../hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.h | 52 + .../hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.mk | 11 + .../hw/bsp/tm4c123/boards/ek-tm4c123gxl/tm4c123.ld | 65 + circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.c | 178 + circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.mk | 36 + .../hw/bsp/xmc4000/boards/xmc4500_relax/board.h | 88 + .../hw/bsp/xmc4000/boards/xmc4500_relax/board.mk | 9 + circuitpython/lib/tinyusb/hw/bsp/xmc4000/family.c | 130 + circuitpython/lib/tinyusb/hw/bsp/xmc4000/family.mk | 40 + .../lib/tinyusb/hw/mcu/bridgetek/ft9xx/Readme.md | 7 + .../tinyusb/hw/mcu/bridgetek/ft9xx/scripts/crt0.S | 286 + .../hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld | 95 + circuitpython/lib/tinyusb/hw/mcu/dialog/README.md | 9 + .../da1469x/SDK_10.0.8.105/sdk/bsp/arm_license.txt | 27 + .../SDK_10.0.8.105/sdk/bsp/include/DA1469xAB.h | 8657 +++++++++++++ .../sdk/bsp/include/cmsis_compiler.h | 271 + .../SDK_10.0.8.105/sdk/bsp/include/cmsis_gcc.h | 2102 ++++ .../SDK_10.0.8.105/sdk/bsp/include/cmsis_version.h | 39 + .../SDK_10.0.8.105/sdk/bsp/include/core_cm0.h | 950 ++ .../SDK_10.0.8.105/sdk/bsp/include/core_cm33.h | 2908 +++++ .../SDK_10.0.8.105/sdk/bsp/include/mpu_armv8.h | 347 + .../SDK_10.0.8.105/sdk/bsp/include/system_ARMCM0.h | 55 + .../sdk/bsp/include/system_DA1469x.h | 72 + .../lib/tinyusb/hw/mcu/dialog/da1469x/da1469x.ld | 228 + .../hw/mcu/dialog/da1469x/include/hal/hal_gpio.h | 184 + .../mcu/dialog/da1469x/include/mcu/da1469x_clock.h | 138 + .../mcu/dialog/da1469x/include/mcu/da1469x_hal.h | 53 + .../hw/mcu/dialog/da1469x/include/mcu/mcu.h | 165 + .../hw/mcu/dialog/da1469x/src/da1469x_clock.c | 159 + .../tinyusb/hw/mcu/dialog/da1469x/src/hal_gpio.c | 478 + .../tinyusb/hw/mcu/dialog/da1469x/src/hal_system.c | 136 + .../hw/mcu/dialog/da1469x/src/hal_system_start.c | 177 + .../hw/mcu/dialog/da1469x/src/system_da1469x.c | 61 + .../nrf5x/s140_nrf52_6.1.1_API/include/ble.h | 685 + .../nrf5x/s140_nrf52_6.1.1_API/include/ble_err.h | 93 + .../nrf5x/s140_nrf52_6.1.1_API/include/ble_gap.h | 2696 ++++ .../nrf5x/s140_nrf52_6.1.1_API/include/ble_gatt.h | 229 + .../nrf5x/s140_nrf52_6.1.1_API/include/ble_gattc.h | 715 ++ .../nrf5x/s140_nrf52_6.1.1_API/include/ble_gatts.h | 845 ++ .../nrf5x/s140_nrf52_6.1.1_API/include/ble_hci.h | 135 + .../nrf5x/s140_nrf52_6.1.1_API/include/ble_l2cap.h | 506 + .../s140_nrf52_6.1.1_API/include/ble_ranges.h | 156 + .../nrf5x/s140_nrf52_6.1.1_API/include/ble_types.h | 215 + .../s140_nrf52_6.1.1_API/include/nrf52/nrf_mbr.h | 268 + .../nrf5x/s140_nrf52_6.1.1_API/include/nrf_error.h | 90 + .../s140_nrf52_6.1.1_API/include/nrf_error_sdm.h | 70 + .../s140_nrf52_6.1.1_API/include/nrf_error_soc.h | 85 + .../nrf5x/s140_nrf52_6.1.1_API/include/nrf_nvic.h | 491 + .../nrf5x/s140_nrf52_6.1.1_API/include/nrf_sdm.h | 367 + .../nrf5x/s140_nrf52_6.1.1_API/include/nrf_soc.h | 1079 ++ .../nrf5x/s140_nrf52_6.1.1_API/include/nrf_svc.h | 90 + .../lib/tinyusb/hw/mcu/nordic/nrfx_config.h | 18 + .../lib/tinyusb/hw/mcu/nordic/nrfx_glue.h | 227 + circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_log.h | 135 + .../lib/tinyusb/hw/mcu/sony/cxd56/mkspk/Makefile | 51 + .../lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.c | 517 + .../lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.h | 65 + .../lib/tinyusb/hw/mcu/sony/cxd56/mkspk/elf32.h | 175 + .../lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.c | 383 + .../lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.h | 93 + .../cxd56/tools/__pycache__/xmodem.cpython-36.pyc | Bin 0 -> 15257 bytes .../hw/mcu/sony/cxd56/tools/flash_writer.py | 580 + .../lib/tinyusb/hw/mcu/sony/cxd56/tools/xmodem.py | 590 + .../lib/tinyusb/lib/SEGGER_RTT/License.txt | 34 + .../lib/tinyusb/lib/SEGGER_RTT/README.txt | 20 + .../lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.c | 2005 +++ .../lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.h | 321 + .../lib/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S | 235 + .../tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_Conf.h | 384 + .../tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c | 500 + .../SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_GCC.c | 120 + .../SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c | 115 + .../SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_KEIL.c | 386 + .../SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_SES.c | 247 + circuitpython/lib/tinyusb/lib/fatfs/00readme.txt | 138 + circuitpython/lib/tinyusb/lib/fatfs/ccsbcs.c | 543 + circuitpython/lib/tinyusb/lib/fatfs/diskio.c | 193 + circuitpython/lib/tinyusb/lib/fatfs/diskio.h | 95 + circuitpython/lib/tinyusb/lib/fatfs/ff.c | 4330 +++++++ circuitpython/lib/tinyusb/lib/fatfs/ff.h | 342 + circuitpython/lib/tinyusb/lib/fatfs/ffconf.h | 193 + circuitpython/lib/tinyusb/lib/fatfs/integer.h | 36 + .../lib/tinyusb/lib/networking/dhserver.c | 348 + .../lib/tinyusb/lib/networking/dhserver.h | 62 + .../lib/tinyusb/lib/networking/dnserver.c | 200 + .../lib/tinyusb/lib/networking/dnserver.h | 47 + circuitpython/lib/tinyusb/lib/networking/ndis.h | 266 + .../lib/tinyusb/lib/networking/rndis_protocol.h | 307 + .../lib/tinyusb/lib/networking/rndis_reports.c | 303 + circuitpython/lib/tinyusb/pkg.yml | 14 + circuitpython/lib/tinyusb/repository.yml | 17 + circuitpython/lib/tinyusb/src/class/audio/audio.h | 933 ++ .../lib/tinyusb/src/class/audio/audio_device.c | 2294 ++++ .../lib/tinyusb/src/class/audio/audio_device.h | 637 + .../lib/tinyusb/src/class/bth/bth_device.c | 258 + .../lib/tinyusb/src/class/bth/bth_device.h | 109 + circuitpython/lib/tinyusb/src/class/cdc/cdc.h | 409 + .../lib/tinyusb/src/class/cdc/cdc_device.c | 486 + .../lib/tinyusb/src/class/cdc/cdc_device.h | 260 + circuitpython/lib/tinyusb/src/class/cdc/cdc_host.c | 249 + circuitpython/lib/tinyusb/src/class/cdc/cdc_host.h | 134 + .../lib/tinyusb/src/class/cdc/cdc_rndis.h | 301 + .../lib/tinyusb/src/class/cdc/cdc_rndis_host.c | 289 + .../lib/tinyusb/src/class/cdc/cdc_rndis_host.h | 63 + circuitpython/lib/tinyusb/src/class/dfu/dfu.h | 119 + .../lib/tinyusb/src/class/dfu/dfu_device.c | 458 + .../lib/tinyusb/src/class/dfu/dfu_device.h | 98 + .../lib/tinyusb/src/class/dfu/dfu_rt_device.c | 128 + .../lib/tinyusb/src/class/dfu/dfu_rt_device.h | 54 + circuitpython/lib/tinyusb/src/class/hid/hid.h | 1122 ++ .../lib/tinyusb/src/class/hid/hid_device.c | 417 + .../lib/tinyusb/src/class/hid/hid_device.h | 393 + circuitpython/lib/tinyusb/src/class/hid/hid_host.c | 643 + circuitpython/lib/tinyusb/src/class/hid/hid_host.h | 152 + circuitpython/lib/tinyusb/src/class/midi/midi.h | 212 + .../lib/tinyusb/src/class/midi/midi_device.c | 545 + .../lib/tinyusb/src/class/midi/midi_device.h | 173 + circuitpython/lib/tinyusb/src/class/msc/msc.h | 382 + .../lib/tinyusb/src/class/msc/msc_device.c | 951 ++ .../lib/tinyusb/src/class/msc/msc_device.h | 162 + circuitpython/lib/tinyusb/src/class/msc/msc_host.c | 491 + circuitpython/lib/tinyusb/src/class/msc/msc_host.h | 119 + .../lib/tinyusb/src/class/net/ecm_rndis_device.c | 445 + circuitpython/lib/tinyusb/src/class/net/ncm.h | 69 + .../lib/tinyusb/src/class/net/ncm_device.c | 510 + .../lib/tinyusb/src/class/net/net_device.h | 118 + .../lib/tinyusb/src/class/usbtmc/usbtmc.h | 316 + .../lib/tinyusb/src/class/usbtmc/usbtmc_device.c | 858 ++ .../lib/tinyusb/src/class/usbtmc/usbtmc_device.h | 116 + .../lib/tinyusb/src/class/vendor/vendor_device.c | 268 + .../lib/tinyusb/src/class/vendor/vendor_device.h | 145 + .../lib/tinyusb/src/class/vendor/vendor_host.c | 146 + .../lib/tinyusb/src/class/vendor/vendor_host.h | 67 + circuitpython/lib/tinyusb/src/class/video/video.h | 480 + .../lib/tinyusb/src/class/video/video_device.c | 1149 ++ .../lib/tinyusb/src/class/video/video_device.h | 97 + circuitpython/lib/tinyusb/src/common/tusb_common.h | 407 + .../lib/tinyusb/src/common/tusb_compiler.h | 264 + circuitpython/lib/tinyusb/src/common/tusb_error.h | 77 + circuitpython/lib/tinyusb/src/common/tusb_fifo.c | 1007 ++ circuitpython/lib/tinyusb/src/common/tusb_fifo.h | 151 + circuitpython/lib/tinyusb/src/common/tusb_mcu.h | 285 + .../lib/tinyusb/src/common/tusb_timeout.h | 80 + circuitpython/lib/tinyusb/src/common/tusb_types.h | 546 + circuitpython/lib/tinyusb/src/common/tusb_verify.h | 181 + circuitpython/lib/tinyusb/src/device/dcd.h | 192 + circuitpython/lib/tinyusb/src/device/usbd.c | 1430 +++ circuitpython/lib/tinyusb/src/device/usbd.h | 853 ++ .../lib/tinyusb/src/device/usbd_control.c | 233 + circuitpython/lib/tinyusb/src/device/usbd_pvt.h | 117 + circuitpython/lib/tinyusb/src/host/hcd.h | 178 + circuitpython/lib/tinyusb/src/host/hub.c | 388 + circuitpython/lib/tinyusb/src/host/hub.h | 196 + circuitpython/lib/tinyusb/src/host/usbh.c | 1257 ++ circuitpython/lib/tinyusb/src/host/usbh.h | 130 + .../lib/tinyusb/src/host/usbh_classdriver.h | 85 + circuitpython/lib/tinyusb/src/host/usbh_control.c | 138 + circuitpython/lib/tinyusb/src/osal/osal.h | 89 + circuitpython/lib/tinyusb/src/osal/osal_freertos.h | 174 + circuitpython/lib/tinyusb/src/osal/osal_mynewt.h | 174 + circuitpython/lib/tinyusb/src/osal/osal_none.h | 179 + circuitpython/lib/tinyusb/src/osal/osal_pico.h | 187 + circuitpython/lib/tinyusb/src/osal/osal_rtthread.h | 130 + circuitpython/lib/tinyusb/src/osal/osal_rtx4.h | 170 + .../src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 1110 ++ .../src/portable/broadcom/synopsys/dcd_synopsys.c | 1267 ++ .../portable/broadcom/synopsys/synopsys_common.h | 1476 +++ .../src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 50 + .../src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h | 45 + .../src/portable/chipidea/ci_hs/ci_hs_type.h | 144 + .../src/portable/chipidea/ci_hs/dcd_ci_hs.c | 636 + .../src/portable/chipidea/ci_hs/hcd_ci_hs.c | 94 + .../src/portable/dialog/da146xx/dcd_da146xx.c | 1212 ++ circuitpython/lib/tinyusb/src/portable/ehci/ehci.c | 900 ++ circuitpython/lib/tinyusb/src/portable/ehci/ehci.h | 420 + .../lib/tinyusb/src/portable/ehci/ehci_api.h | 45 + .../src/portable/espressif/esp32sx/dcd_esp32sx.c | 853 ++ .../tinyusb/src/portable/mentor/musb/dcd_musb.c | 900 ++ .../tinyusb/src/portable/mentor/musb/hcd_musb.c | 876 ++ .../src/portable/mentor/musb/musb_msp432e.h | 40 + .../tinyusb/src/portable/mentor/musb/musb_tm4c.h | 45 + .../tinyusb/src/portable/mentor/musb/musb_type.h | 2624 ++++ .../src/portable/microchip/pic32mz/dcd_pic32mz.c | 741 ++ .../portable/microchip/pic32mz/usbhs_registers.h | 931 ++ .../tinyusb/src/portable/microchip/samd/dcd_samd.c | 419 + .../tinyusb/src/portable/microchip/samg/dcd_samg.c | 492 + .../portable/microchip/samx7x/common_usb_regs.h | 2108 ++++ .../src/portable/microchip/samx7x/dcd_samx7x.c | 768 ++ .../portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 477 + .../tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c | 1136 ++ .../src/portable/nuvoton/nuc120/dcd_nuc120.c | 500 + .../src/portable/nuvoton/nuc121/dcd_nuc121.c | 554 + .../src/portable/nuvoton/nuc505/dcd_nuc505.c | 723 ++ .../lib/tinyusb/src/portable/nxp/khci/dcd_khci.c | 557 + .../lib/tinyusb/src/portable/nxp/khci/hcd_khci.c | 626 + .../src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 589 + .../src/portable/nxp/lpc17_40/dcd_lpc17_40.h | 152 + .../src/portable/nxp/lpc17_40/hcd_lpc17_40.c | 47 + .../src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 543 + .../nxp/transdimension/common_transdimension.h | 136 + .../nxp/transdimension/dcd_transdimension.c | 664 + .../nxp/transdimension/hcd_transdimension.c | 119 + circuitpython/lib/tinyusb/src/portable/ohci/ohci.c | 657 + circuitpython/lib/tinyusb/src/portable/ohci/ohci.h | 278 + .../src/portable/raspberrypi/rp2040/dcd_rp2040.c | 510 + .../src/portable/raspberrypi/rp2040/hcd_rp2040.c | 582 + .../src/portable/raspberrypi/rp2040/rp2040_usb.c | 327 + .../src/portable/raspberrypi/rp2040/rp2040_usb.h | 96 + .../tinyusb/src/portable/renesas/usba/dcd_usba.c | 907 ++ .../tinyusb/src/portable/renesas/usba/hcd_usba.c | 870 ++ .../tinyusb/src/portable/sony/cxd56/dcd_cxd56.c | 417 + .../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 1154 ++ .../st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 422 + .../src/portable/st/synopsys/dcd_synopsys.c | 1233 ++ .../src/portable/st/synopsys/synopsys_common.h | 1465 +++ .../tinyusb/src/portable/sunxi/dcd_sunxi_musb.c | 1211 ++ .../lib/tinyusb/src/portable/sunxi/musb_def.h | 643 + .../tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c | 1307 ++ .../tinyusb/src/portable/synopsys/dwc2/dwc2_bcm.h | 88 + .../src/portable/synopsys/dwc2/dwc2_efm32.h | 87 + .../src/portable/synopsys/dwc2/dwc2_esp32.h | 94 + .../tinyusb/src/portable/synopsys/dwc2/dwc2_gd32.h | 100 + .../src/portable/synopsys/dwc2/dwc2_stm32.h | 205 + .../tinyusb/src/portable/synopsys/dwc2/dwc2_type.h | 1730 +++ .../tinyusb/src/portable/synopsys/dwc2/dwc2_xmc.h | 87 + .../src/portable/synopsys/dwc2/hwcfg_list.md | 777 ++ .../tinyusb/src/portable/template/dcd_template.c | 136 + .../src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 699 ++ .../src/portable/valentyusb/eptri/dcd_eptri.c | 649 + .../src/portable/valentyusb/eptri/dcd_eptri.h | 39 + circuitpython/lib/tinyusb/src/tusb.c | 247 + circuitpython/lib/tinyusb/src/tusb.h | 140 + circuitpython/lib/tinyusb/src/tusb_option.h | 396 + circuitpython/lib/tinyusb/test/ceedling | 3 + circuitpython/lib/tinyusb/test/project.yml | 106 + .../tinyusb/test/test/device/msc/test_msc_device.c | 273 + .../lib/tinyusb/test/test/device/usbd/test_usbd.c | 243 + .../lib/tinyusb/test/test/support/tusb_config.h | 106 + circuitpython/lib/tinyusb/test/test/test_fifo.c | 318 + .../lib/tinyusb/test/vendor/ceedling/bin/ceedling | 337 + .../test/vendor/ceedling/docs/CException.md | 292 + .../test/vendor/ceedling/docs/CMock_Summary.md | 603 + .../test/vendor/ceedling/docs/CeedlingPacket.md | 2060 ++++ .../ceedling/docs/ThrowTheSwitchCodingStandard.md | 206 + ...tSheetSuitableforPrintingandPossiblyFraming.pdf | Bin 0 -> 144467 bytes .../ceedling/docs/UnityAssertionsReference.md | 779 ++ .../ceedling/docs/UnityConfigurationGuide.md | 433 + .../ceedling/docs/UnityGettingStartedGuide.md | 192 + .../ceedling/docs/UnityHelperScriptsGuide.md | 260 + .../tinyusb/test/vendor/ceedling/lib/ceedling.rb | 99 + .../ceedling/lib/ceedling/build_invoker_utils.rb | 39 + .../vendor/ceedling/lib/ceedling/cacheinator.rb | 47 + .../ceedling/lib/ceedling/cacheinator_helper.rb | 31 + .../vendor/ceedling/lib/ceedling/cmock_builder.rb | 15 + .../vendor/ceedling/lib/ceedling/configurator.rb | 363 + .../ceedling/lib/ceedling/configurator_builder.rb | 458 + .../ceedling/lib/ceedling/configurator_plugins.rb | 111 + .../ceedling/lib/ceedling/configurator_setup.rb | 127 + .../lib/ceedling/configurator_validator.rb | 193 + .../test/vendor/ceedling/lib/ceedling/constants.rb | 97 + .../test/vendor/ceedling/lib/ceedling/defaults.rb | 418 + .../vendor/ceedling/lib/ceedling/dependinator.rb | 98 + .../vendor/ceedling/lib/ceedling/erb_wrapper.rb | 9 + .../vendor/ceedling/lib/ceedling/file_finder.rb | 149 + .../ceedling/lib/ceedling/file_finder_helper.rb | 54 + .../ceedling/lib/ceedling/file_path_utils.rb | 200 + .../ceedling/lib/ceedling/file_system_utils.rb | 69 + .../ceedling/lib/ceedling/file_system_wrapper.rb | 10 + .../vendor/ceedling/lib/ceedling/file_wrapper.rb | 83 + .../vendor/ceedling/lib/ceedling/flaginator.rb | 74 + .../test/vendor/ceedling/lib/ceedling/generator.rb | 183 + .../ceedling/lib/ceedling/generator_helper.rb | 40 + .../lib/ceedling/generator_test_results.rb | 89 + .../generator_test_results_sanity_checker.rb | 65 + .../ceedling/lib/ceedling/generator_test_runner.rb | 56 + .../test/vendor/ceedling/lib/ceedling/loginator.rb | 31 + .../test/vendor/ceedling/lib/ceedling/makefile.rb | 46 + .../test/vendor/ceedling/lib/ceedling/objects.yml | 310 + .../test/vendor/ceedling/lib/ceedling/par_map.rb | 19 + .../test/vendor/ceedling/lib/ceedling/plugin.rb | 80 + .../vendor/ceedling/lib/ceedling/plugin_builder.rb | 53 + .../vendor/ceedling/lib/ceedling/plugin_manager.rb | 107 + .../ceedling/lib/ceedling/plugin_manager_helper.rb | 19 + .../ceedling/lib/ceedling/plugin_reportinator.rb | 76 + .../lib/ceedling/plugin_reportinator_helper.rb | 51 + .../ceedling/lib/ceedling/preprocessinator.rb | 42 + .../lib/ceedling/preprocessinator_extractor.rb | 30 + .../lib/ceedling/preprocessinator_file_handler.rb | 21 + .../lib/ceedling/preprocessinator_helper.rb | 46 + .../ceedling/preprocessinator_includes_handler.rb | 181 + .../lib/ceedling/project_config_manager.rb | 46 + .../ceedling/lib/ceedling/project_file_loader.rb | 99 + .../vendor/ceedling/lib/ceedling/rake_utils.rb | 17 + .../vendor/ceedling/lib/ceedling/rake_wrapper.rb | 33 + .../test/vendor/ceedling/lib/ceedling/rakefile.rb | 86 + .../ceedling/lib/ceedling/release_invoker.rb | 73 + .../lib/ceedling/release_invoker_helper.rb | 19 + .../vendor/ceedling/lib/ceedling/reportinator.rb | 26 + .../vendor/ceedling/lib/ceedling/rules_cmock.rake | 9 + .../ceedling/lib/ceedling/rules_preprocess.rake | 26 + .../ceedling/lib/ceedling/rules_release.rake | 86 + .../ceedling/rules_release_deep_dependencies.rake | 15 + .../vendor/ceedling/lib/ceedling/rules_tests.rake | 74 + .../ceedling/rules_tests_deep_dependencies.rake | 15 + .../vendor/ceedling/lib/ceedling/setupinator.rb | 53 + .../vendor/ceedling/lib/ceedling/stream_wrapper.rb | 28 + .../vendor/ceedling/lib/ceedling/streaminator.rb | 40 + .../ceedling/lib/ceedling/streaminator_helper.rb | 15 + .../vendor/ceedling/lib/ceedling/system_utils.rb | 37 + .../vendor/ceedling/lib/ceedling/system_wrapper.rb | 80 + .../vendor/ceedling/lib/ceedling/target_loader.rb | 38 + .../vendor/ceedling/lib/ceedling/task_invoker.rb | 117 + .../vendor/ceedling/lib/ceedling/tasks_base.rake | 111 + .../ceedling/lib/ceedling/tasks_filesystem.rake | 103 + .../ceedling/lib/ceedling/tasks_release.rake | 30 + .../ceedling/tasks_release_deep_dependencies.rake | 9 + .../vendor/ceedling/lib/ceedling/tasks_tests.rake | 60 + .../ceedling/tasks_tests_deep_dependencies.rake | 9 + .../vendor/ceedling/lib/ceedling/tasks_vendor.rake | 35 + .../lib/ceedling/test_includes_extractor.rb | 85 + .../vendor/ceedling/lib/ceedling/test_invoker.rb | 188 + .../ceedling/lib/ceedling/test_invoker_helper.rb | 32 + .../vendor/ceedling/lib/ceedling/tool_executor.rb | 229 + .../ceedling/lib/ceedling/tool_executor_helper.rb | 164 + .../vendor/ceedling/lib/ceedling/verbosinator.rb | 10 + .../test/vendor/ceedling/lib/ceedling/version.rb | 36 + .../vendor/ceedling/lib/ceedling/version.rb.erb | 15 + .../vendor/ceedling/lib/ceedling/yaml_wrapper.rb | 17 + .../test/vendor/ceedling/plugins/beep/README.md | 22 + .../test/vendor/ceedling/plugins/beep/lib/beep.rb | 40 + .../ceedling/plugins/bullseye/assets/template.erb | 15 + .../vendor/ceedling/plugins/bullseye/bullseye.rake | 169 + .../ceedling/plugins/bullseye/config/defaults.yml | 57 + .../ceedling/plugins/bullseye/lib/bullseye.rb | 194 + .../vendor/ceedling/plugins/bullseye/readme.txt | 0 .../plugins/colour_report/lib/colour_report.rb | 16 + .../ceedling/plugins/command_hooks/README.md | 53 + .../plugins/command_hooks/lib/command_hooks.rb | 92 + .../plugins/fake_function_framework/README.md | 250 + .../plugins/fake_function_framework/Rakefile | 19 + .../examples/fff_example/project.yml | 71 + .../examples/fff_example/rakefile.rb | 7 + .../examples/fff_example/src/bar.c | 1 + .../examples/fff_example/src/bar.h | 14 + .../examples/fff_example/src/custom_types.h | 6 + .../examples/fff_example/src/display.c | 7 + .../examples/fff_example/src/display.h | 16 + .../examples/fff_example/src/event_processor.c | 93 + .../examples/fff_example/src/event_processor.h | 11 + .../examples/fff_example/src/foo.c | 16 + .../examples/fff_example/src/foo.h | 8 + .../examples/fff_example/src/subfolder/zzz.c | 1 + .../examples/fff_example/src/subfolder/zzz.h | 6 + .../fff_example/test/test_event_processor.c | 155 + .../examples/fff_example/test/test_foo.c | 47 + .../lib/fake_function_framework.rb | 87 + .../lib/fff_mock_generator.rb | 163 + .../spec/fff_mock_header_generator_spec.rb | 304 + .../spec/fff_mock_source_generator_spec.rb | 149 + .../spec/header_generator.rb | 51 + .../fake_function_framework/spec/spec_helper.rb | 96 + .../fake_function_framework/src/fff_unity_helper.h | 33 + .../test/vendor/ceedling/plugins/gcov/README.md | 101 + .../ceedling/plugins/gcov/assets/template.erb | 15 + .../ceedling/plugins/gcov/config/defaults.yml | 73 + .../test/vendor/ceedling/plugins/gcov/gcov.rake | 220 + .../test/vendor/ceedling/plugins/gcov/lib/gcov.rb | 113 + .../ceedling/plugins/gcov/lib/gcov_constants.rb | 19 + .../ceedling/plugins/junit_tests_report/README.md | 36 + .../junit_tests_report/lib/junit_tests_report.rb | 129 + .../module_generator/config/module_generator.yml | 4 + .../module_generator/lib/module_generator.rb | 70 + .../plugins/module_generator/module_generator.rake | 47 + .../raw_output_report/lib/raw_output_report.rb | 41 + .../assets/template.erb | 84 + .../assets/template.erb copy | 59 + .../config/stdout_gtestlike_tests_report.yml | 4 + .../lib/stdout_gtestlike_tests_report.rb | 43 + .../config/stdout_ide_tests_report.yml | 4 + .../lib/stdout_ide_tests_report.rb | 44 + .../stdout_pretty_tests_report/assets/template.erb | 59 + .../config/stdout_pretty_tests_report.yml | 4 + .../lib/stdout_pretty_tests_report.rb | 47 + .../vendor/ceedling/plugins/subprojects/README.md | 63 + .../plugins/subprojects/config/defaults.yml | 33 + .../plugins/subprojects/lib/subprojects.rb | 92 + .../ceedling/plugins/subprojects/subprojects.rake | 78 + .../config/teamcity_tests_report.yml | 4 + .../lib/teamcity_tests_report.rb | 57 + .../plugins/warnings_report/lib/warnings_report.rb | 69 + .../ceedling/plugins/xml_tests_report/README.md | 36 + .../xml_tests_report/lib/xml_tests_report.rb | 110 + .../ceedling/vendor/c_exception/lib/CException.c | 46 + .../ceedling/vendor/c_exception/lib/CException.h | 115 + .../ceedling/vendor/c_exception/release/build.info | 2 + .../vendor/c_exception/release/version.info | 2 + .../vendor/cmock/config/production_environment.rb | 14 + .../vendor/cmock/config/test_environment.rb | 16 + .../test/vendor/ceedling/vendor/cmock/lib/cmock.rb | 86 + .../ceedling/vendor/cmock/lib/cmock_config.rb | 153 + .../ceedling/vendor/cmock/lib/cmock_file_writer.rb | 44 + .../ceedling/vendor/cmock/lib/cmock_generator.rb | 268 + .../cmock/lib/cmock_generator_plugin_array.rb | 63 + .../cmock/lib/cmock_generator_plugin_callback.rb | 88 + .../cmock/lib/cmock_generator_plugin_cexception.rb | 51 + .../cmock/lib/cmock_generator_plugin_expect.rb | 103 + .../lib/cmock_generator_plugin_expect_any_args.rb | 53 + .../cmock/lib/cmock_generator_plugin_ignore.rb | 75 + .../cmock/lib/cmock_generator_plugin_ignore_arg.rb | 42 + .../lib/cmock_generator_plugin_return_thru_ptr.rb | 79 + .../vendor/cmock/lib/cmock_generator_utils.rb | 253 + .../vendor/cmock/lib/cmock_header_parser.rb | 364 + .../vendor/cmock/lib/cmock_plugin_manager.rb | 55 + .../vendor/cmock/lib/cmock_unityhelper_parser.rb | 75 + .../ceedling/vendor/cmock/release/build.info | 2 + .../ceedling/vendor/cmock/release/version.info | 2 + .../test/vendor/ceedling/vendor/cmock/src/cmock.c | 216 + .../test/vendor/ceedling/vendor/cmock/src/cmock.h | 40 + .../ceedling/vendor/cmock/src/cmock_internals.h | 91 + .../vendor/ceedling/vendor/cmock/src/meson.build | 17 + .../ceedling/vendor/deep_merge/lib/deep_merge.rb | 211 + .../test/vendor/ceedling/vendor/diy/lib/diy.rb | 403 + .../vendor/ceedling/vendor/diy/lib/diy/factory.rb | 36 + .../ceedling/vendor/unity/auto/colour_prompt.rb | 119 + .../ceedling/vendor/unity/auto/colour_reporter.rb | 39 + .../ceedling/vendor/unity/auto/generate_config.yml | 36 + .../ceedling/vendor/unity/auto/generate_module.rb | 309 + .../vendor/unity/auto/generate_test_runner.rb | 495 + .../ceedling/vendor/unity/auto/parse_output.rb | 322 + .../vendor/ceedling/vendor/unity/auto/run_test.erb | 36 + .../ceedling/vendor/unity/auto/stylize_as_junit.rb | 251 + .../ceedling/vendor/unity/auto/test_file_filter.rb | 25 + .../ceedling/vendor/unity/auto/type_sanitizer.rb | 6 + .../vendor/unity/auto/unity_test_summary.py | 139 + .../vendor/unity/auto/unity_test_summary.rb | 135 + .../ceedling/vendor/unity/auto/unity_to_junit.py | 146 + .../ceedling/vendor/unity/release/build.info | 2 + .../ceedling/vendor/unity/release/version.info | 2 + .../ceedling/vendor/unity/src/CMakeLists.txt | 22 + .../vendor/ceedling/vendor/unity/src/meson.build | 16 + .../test/vendor/ceedling/vendor/unity/src/unity.c | 2085 ++++ .../test/vendor/ceedling/vendor/unity/src/unity.h | 617 + .../ceedling/vendor/unity/src/unity_internals.h | 1002 ++ circuitpython/lib/tinyusb/tools/build_board.py | 100 + circuitpython/lib/tinyusb/tools/build_esp32sx.py | 101 + circuitpython/lib/tinyusb/tools/build_family.py | 113 + circuitpython/lib/tinyusb/tools/build_utils.py | 61 + circuitpython/lib/tinyusb/tools/iar_gen.py | 51 + circuitpython/lib/tinyusb/tools/iar_template.ipcf | 145 + circuitpython/lib/tinyusb/tools/mksunxi.py | 48 + circuitpython/lib/tinyusb/tools/top.mk | 30 + .../tools/usb_drivers/tinyusb_win_usbser.inf | 108 + circuitpython/lib/tinyusb/version.yml | 3 + circuitpython/lib/uzlib/adler32.c | 78 + circuitpython/lib/uzlib/crc32.c | 63 + circuitpython/lib/uzlib/defl_static.h | 45 + circuitpython/lib/uzlib/tinf.h | 3 + circuitpython/lib/uzlib/tinf_compat.h | 9 + circuitpython/lib/uzlib/tinfgzip.c | 110 + circuitpython/lib/uzlib/tinflate.c | 659 + circuitpython/lib/uzlib/tinfzlib.c | 66 + circuitpython/lib/uzlib/uzlib.h | 171 + circuitpython/lib/uzlib/uzlib_conf.h | 22 + 2356 files changed, 543270 insertions(+) create mode 100644 circuitpython/lib/README.md create mode 100644 circuitpython/lib/adafruit_floppy/LICENSES/CC-BY-4.0.txt create mode 100644 circuitpython/lib/adafruit_floppy/LICENSES/CC0-1.0.txt create mode 100644 circuitpython/lib/adafruit_floppy/LICENSES/MIT.txt create mode 100644 circuitpython/lib/adafruit_floppy/Makefile create mode 100644 circuitpython/lib/adafruit_floppy/README.md create mode 100644 circuitpython/lib/adafruit_floppy/code-of-conduct.md create mode 100644 circuitpython/lib/adafruit_floppy/examples/fat_test/fat_test.ino create mode 100644 circuitpython/lib/adafruit_floppy/examples/floppy_capture_track_test/floppy_capture_track_test.ino create mode 100644 circuitpython/lib/adafruit_floppy/examples/greaseweazle/greaseweazle.ino create mode 100644 circuitpython/lib/adafruit_floppy/examples/mfm_test/mfm_test.ino create mode 100644 circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino create mode 100644 circuitpython/lib/adafruit_floppy/flux.txt create mode 100644 circuitpython/lib/adafruit_floppy/flux.txt.license create mode 100644 circuitpython/lib/adafruit_floppy/images/rabbit.png create mode 100644 circuitpython/lib/adafruit_floppy/images/readme create mode 100644 circuitpython/lib/adafruit_floppy/library.properties create mode 100644 circuitpython/lib/adafruit_floppy/license.txt create mode 100644 circuitpython/lib/adafruit_floppy/mfm.license create mode 100644 circuitpython/lib/adafruit_floppy/src/Adafruit_Floppy.cpp create mode 100644 circuitpython/lib/adafruit_floppy/src/Adafruit_Floppy.h create mode 100644 circuitpython/lib/adafruit_floppy/src/Adafruit_MFM_Floppy.cpp create mode 100644 circuitpython/lib/adafruit_floppy/src/mfm_impl.h create mode 100644 circuitpython/lib/adafruit_floppy/standalone/main.c create mode 100644 circuitpython/lib/axtls/Makefile create mode 100644 circuitpython/lib/axtls/README create mode 100755 circuitpython/lib/axtls/axtlswrap/Makefile create mode 100755 circuitpython/lib/axtls/axtlswrap/axtlswrap.c create mode 100644 circuitpython/lib/axtls/bindings/Config.in create mode 100644 circuitpython/lib/axtls/bindings/Makefile create mode 100644 circuitpython/lib/axtls/bindings/README create mode 100644 circuitpython/lib/axtls/bindings/csharp/Makefile create mode 100644 circuitpython/lib/axtls/bindings/csharp/axTLS.cs create mode 100755 circuitpython/lib/axtls/bindings/generate_SWIG_interface.pl create mode 100755 circuitpython/lib/axtls/bindings/generate_interface.pl create mode 100644 circuitpython/lib/axtls/bindings/java/Makefile create mode 100644 circuitpython/lib/axtls/bindings/java/SSL.java create mode 100644 circuitpython/lib/axtls/bindings/java/SSLCTX.java create mode 100644 circuitpython/lib/axtls/bindings/java/SSLClient.java create mode 100644 circuitpython/lib/axtls/bindings/java/SSLReadHolder.java create mode 100644 circuitpython/lib/axtls/bindings/java/SSLServer.java create mode 100644 circuitpython/lib/axtls/bindings/java/SSLUtil.java create mode 100644 circuitpython/lib/axtls/bindings/lua/Makefile create mode 100644 circuitpython/lib/axtls/bindings/perl/Makefile create mode 100644 circuitpython/lib/axtls/bindings/vbnet/Makefile create mode 100644 circuitpython/lib/axtls/bindings/vbnet/axTLSvb.vb create mode 100644 circuitpython/lib/axtls/config/Config.in create mode 100755 circuitpython/lib/axtls/config/JMeter.jmx create mode 100644 circuitpython/lib/axtls/config/Rules.mak create mode 100755 circuitpython/lib/axtls/config/axhttpd.aip create mode 100644 circuitpython/lib/axtls/config/axtls.RES create mode 100644 circuitpython/lib/axtls/config/axtls.rc create mode 100644 circuitpython/lib/axtls/config/linuxconfig create mode 100644 circuitpython/lib/axtls/config/makefile.conf create mode 100644 circuitpython/lib/axtls/config/makefile.dotnet.conf create mode 100644 circuitpython/lib/axtls/config/makefile.java.conf create mode 100644 circuitpython/lib/axtls/config/makefile.post create mode 100644 circuitpython/lib/axtls/config/scripts/config/Kconfig-language.txt create mode 100644 circuitpython/lib/axtls/config/scripts/config/Makefile create mode 100644 circuitpython/lib/axtls/config/scripts/config/conf.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/confdata.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/expr.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/expr.h create mode 100644 circuitpython/lib/axtls/config/scripts/config/lex.zconf.c_shipped create mode 100644 circuitpython/lib/axtls/config/scripts/config/lkc.h create mode 100644 circuitpython/lib/axtls/config/scripts/config/lkc_proto.h create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/BIG.FAT.WARNING create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/checklist.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/colors.h create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/dialog.h create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/inputbox.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/menubox.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/msgbox.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/textbox.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/util.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/lxdialog/yesno.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/mconf.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/menu.c create mode 100755 circuitpython/lib/axtls/config/scripts/config/mkconfigs create mode 100644 circuitpython/lib/axtls/config/scripts/config/symbol.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/util.c create mode 100644 circuitpython/lib/axtls/config/scripts/config/zconf.l create mode 100644 circuitpython/lib/axtls/config/scripts/config/zconf.tab.c_shipped create mode 100644 circuitpython/lib/axtls/config/scripts/config/zconf.tab.h_shipped create mode 100644 circuitpython/lib/axtls/config/scripts/config/zconf.y create mode 100644 circuitpython/lib/axtls/config/upyconfig create mode 100644 circuitpython/lib/axtls/config/upyconfig.client create mode 100644 circuitpython/lib/axtls/config/win32config create mode 100644 circuitpython/lib/axtls/crypto/Makefile create mode 100644 circuitpython/lib/axtls/crypto/aes.c create mode 100644 circuitpython/lib/axtls/crypto/bigint.c create mode 100644 circuitpython/lib/axtls/crypto/bigint.h create mode 100644 circuitpython/lib/axtls/crypto/bigint_impl.h create mode 100644 circuitpython/lib/axtls/crypto/crypto.h create mode 100644 circuitpython/lib/axtls/crypto/crypto_misc.c create mode 100644 circuitpython/lib/axtls/crypto/hmac.c create mode 100644 circuitpython/lib/axtls/crypto/md5.c create mode 100644 circuitpython/lib/axtls/crypto/os_int.h create mode 100644 circuitpython/lib/axtls/crypto/rc4.c create mode 100644 circuitpython/lib/axtls/crypto/rsa.c create mode 100644 circuitpython/lib/axtls/crypto/sha1.c create mode 100644 circuitpython/lib/axtls/crypto/sha256.c create mode 100644 circuitpython/lib/axtls/crypto/sha384.c create mode 100644 circuitpython/lib/axtls/crypto/sha512.c create mode 100644 circuitpython/lib/axtls/docsrc/Makefile create mode 100644 circuitpython/lib/axtls/docsrc/axTLS.dox create mode 100644 circuitpython/lib/axtls/docsrc/doco_footer.html create mode 100644 circuitpython/lib/axtls/docsrc/images/axolotl.jpg create mode 100644 circuitpython/lib/axtls/docsrc/images/tsbasbw.gif create mode 100644 circuitpython/lib/axtls/httpd/Config.in create mode 100644 circuitpython/lib/axtls/httpd/Makefile create mode 100644 circuitpython/lib/axtls/httpd/axhttp.h create mode 100644 circuitpython/lib/axtls/httpd/axhttpd.c create mode 100644 circuitpython/lib/axtls/httpd/htpasswd.c create mode 100755 circuitpython/lib/axtls/httpd/kepler-1.1-snapshot-20070521-1825.tar.gz create mode 100644 circuitpython/lib/axtls/httpd/kepler.patch create mode 100644 circuitpython/lib/axtls/httpd/proc.c create mode 100644 circuitpython/lib/axtls/httpd/tdate_parse.c create mode 100644 circuitpython/lib/axtls/samples/Config.in create mode 100644 circuitpython/lib/axtls/samples/Makefile create mode 100644 circuitpython/lib/axtls/samples/c/Makefile create mode 100644 circuitpython/lib/axtls/samples/c/axssl.c create mode 100644 circuitpython/lib/axtls/samples/csharp/Makefile create mode 100644 circuitpython/lib/axtls/samples/csharp/axssl.cs create mode 100644 circuitpython/lib/axtls/samples/java/Makefile create mode 100644 circuitpython/lib/axtls/samples/java/axssl.java create mode 100644 circuitpython/lib/axtls/samples/java/manifest.mf create mode 100644 circuitpython/lib/axtls/samples/lua/Makefile create mode 100755 circuitpython/lib/axtls/samples/lua/axssl.lua create mode 100644 circuitpython/lib/axtls/samples/perl/Makefile create mode 100755 circuitpython/lib/axtls/samples/perl/axssl.pl create mode 100644 circuitpython/lib/axtls/samples/vbnet/Makefile create mode 100644 circuitpython/lib/axtls/samples/vbnet/axssl.vb create mode 100644 circuitpython/lib/axtls/ssl/BigIntConfig.in create mode 100644 circuitpython/lib/axtls/ssl/Config.in create mode 100644 circuitpython/lib/axtls/ssl/Makefile create mode 100644 circuitpython/lib/axtls/ssl/asn1.c create mode 100644 circuitpython/lib/axtls/ssl/cert.h create mode 100644 circuitpython/lib/axtls/ssl/crypto_misc.h create mode 100644 circuitpython/lib/axtls/ssl/gen_cert.c create mode 100644 circuitpython/lib/axtls/ssl/loader.c create mode 100644 circuitpython/lib/axtls/ssl/openssl.c create mode 100644 circuitpython/lib/axtls/ssl/os_port.c create mode 100644 circuitpython/lib/axtls/ssl/os_port.h create mode 100644 circuitpython/lib/axtls/ssl/p12.c create mode 100644 circuitpython/lib/axtls/ssl/private_key.h create mode 100644 circuitpython/lib/axtls/ssl/ssl.h create mode 100644 circuitpython/lib/axtls/ssl/test/Makefile create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.ca_key.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.cer create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.ca_x509_sha256.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.encrypted.p8 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.encrypted_pem.p8 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_1024 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_1024.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_2048 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_2048.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_4096 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_4096.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_aes128.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_aes256.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_device.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_end_chain.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_intermediate_ca.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.key_intermediate_ca2.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.noname.p12 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.unencrypted.p8 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.unencrypted_pem.p8 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.withCA.p12 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.withoutCA.p12 create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_1024.cer create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_1024.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha256.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha384.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha512.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_2048.cer create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_2048.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_4096.cer create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_4096.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_aes128.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_aes256.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_bad_after.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_bad_before.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_device.cer create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_device.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_end_chain.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_end_chain_bad.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_intermediate_ca.pem create mode 100644 circuitpython/lib/axtls/ssl/test/axTLS.x509_intermediate_ca2.pem create mode 100644 circuitpython/lib/axtls/ssl/test/ca-bundle.crt create mode 100644 circuitpython/lib/axtls/ssl/test/camster_duckdns_org.crt create mode 100644 circuitpython/lib/axtls/ssl/test/comodo.sha384.cer create mode 100644 circuitpython/lib/axtls/ssl/test/deutsche_telecom.x509_ca create mode 100644 circuitpython/lib/axtls/ssl/test/equifax.x509_ca create mode 100755 circuitpython/lib/axtls/ssl/test/gnutls.cer create mode 100755 circuitpython/lib/axtls/ssl/test/header_issue.dat create mode 100755 circuitpython/lib/axtls/ssl/test/killgnutls.sh create mode 100755 circuitpython/lib/axtls/ssl/test/killopenssl.sh create mode 100755 circuitpython/lib/axtls/ssl/test/make_certs.sh create mode 100644 circuitpython/lib/axtls/ssl/test/microsoft.x509_ca create mode 100644 circuitpython/lib/axtls/ssl/test/microsoft.x509_ca.pem create mode 100755 circuitpython/lib/axtls/ssl/test/ms_iis.cer create mode 100644 circuitpython/lib/axtls/ssl/test/perf_bigint.c create mode 100644 circuitpython/lib/axtls/ssl/test/qualityssl.com.der create mode 100755 circuitpython/lib/axtls/ssl/test/socgen.cer create mode 100644 circuitpython/lib/axtls/ssl/test/ssltest.c create mode 100755 circuitpython/lib/axtls/ssl/test/test_axssl.sh create mode 100644 circuitpython/lib/axtls/ssl/test/thawte.x509_ca create mode 100644 circuitpython/lib/axtls/ssl/test/verisign.x509_ca.pem create mode 100644 circuitpython/lib/axtls/ssl/test/verisign.x509_my_cert.pem create mode 100755 circuitpython/lib/axtls/ssl/tls1.c create mode 100755 circuitpython/lib/axtls/ssl/tls1.h create mode 100644 circuitpython/lib/axtls/ssl/tls1_clnt.c create mode 100644 circuitpython/lib/axtls/ssl/tls1_svr.c create mode 100644 circuitpython/lib/axtls/ssl/x509.c create mode 100644 circuitpython/lib/axtls/www/bin/.htaccess create mode 100644 circuitpython/lib/axtls/www/favicon.ico create mode 100755 circuitpython/lib/axtls/www/index.html create mode 100644 circuitpython/lib/axtls/www/lua/download.lua create mode 100644 circuitpython/lib/axtls/www/lua/env.lua create mode 100644 circuitpython/lib/axtls/www/lua/overview.lp create mode 100644 circuitpython/lib/axtls/www/lua/prepara_sql2.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_conc.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_cookies.lp create mode 100644 circuitpython/lib/axtls/www/lua/test_cookies.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_err.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_fs.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_htk.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_lib.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_main.html create mode 100644 circuitpython/lib/axtls/www/lua/test_main.lp create mode 100644 circuitpython/lib/axtls/www/lua/test_main.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_session.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_sql.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_sql2.lua create mode 100644 circuitpython/lib/axtls/www/lua/test_variables.lp create mode 100644 circuitpython/lib/axtls/www/test_dir/bin/.htaccess create mode 100644 circuitpython/lib/axtls/www/test_dir/no_http/.htaccess create mode 100644 circuitpython/lib/axtls/www/test_dir/no_http/.htpasswd create mode 100644 circuitpython/lib/axtls/www/test_dir/no_http/index.html create mode 100644 circuitpython/lib/axtls/www/test_dir/no_ssl/.htaccess create mode 100644 circuitpython/lib/axtls/www/test_dir/no_ssl/index.html create mode 100644 circuitpython/lib/berkeley-db-1.xx/Makefile.inc create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/Makefile create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/README create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/sys create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/cdefs.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/compat.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/sys create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/Makefile create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/OTHER_PATCHES create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/clib create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/assert.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/queue.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/local.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/makebuf.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/setvbuf.c create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/sys create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/clib/memmove.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/clib/mktemp.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/clib/snprintf.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/clib/strerror.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/sys create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.8.07 create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/queue.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/local/hp_siglist.c create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/sys create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/include/bsd-queue.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/include/filevtable.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/include/mpool.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/include/ndbm.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/include/queue.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/Makefile create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/OTHER_PATCHES create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/sys create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/linux/Makefile create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/linux/OTHER_PATCHES create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/linux/clib create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/linux/sys create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/sys create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.3 create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/osf.2.0 create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/Makefile create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/OTHER_PATCHES create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/ndbm.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/pathnames.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/sys create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/sys create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/solaris.2.2 create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/ndbm.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/pathnames.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/sys create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.2 create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.3 create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/compat.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/sys create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/Makefile create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/clib create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/cdefs.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/compat.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/db.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/ndbm.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/queue.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/sys create mode 120000 circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.3 create mode 100644 circuitpython/lib/berkeley-db-1.xx/README create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/Makefile.inc create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_close.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_conv.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_debug.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_delete.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_get.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_open.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_overflow.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_page.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_put.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_search.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_seq.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_split.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/bt_utils.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/btree.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/btree/extern.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/btree/tags create mode 100644 circuitpython/lib/berkeley-db-1.xx/changelog create mode 100644 circuitpython/lib/berkeley-db-1.xx/db/Makefile.inc create mode 100644 circuitpython/lib/berkeley-db-1.xx/db/db.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/db/tags create mode 100644 circuitpython/lib/berkeley-db-1.xx/docs/btree.3.ps create mode 100644 circuitpython/lib/berkeley-db-1.xx/docs/dbopen.3.ps create mode 100644 circuitpython/lib/berkeley-db-1.xx/docs/hash.3.ps create mode 100644 circuitpython/lib/berkeley-db-1.xx/docs/hash.usenix.ps create mode 100644 circuitpython/lib/berkeley-db-1.xx/docs/libtp.usenix.ps create mode 100644 circuitpython/lib/berkeley-db-1.xx/docs/mpool.3.ps create mode 100644 circuitpython/lib/berkeley-db-1.xx/docs/recno.3.ps create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/Makefile.inc create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/README create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/extern.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/hash.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/hash.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/hash_bigkey.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/hash_buf.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/hash_func.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/hash_log2.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/hash_page.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/hsearch.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/ndbm.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/page.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/hash/search.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/hash/tags create mode 100644 circuitpython/lib/berkeley-db-1.xx/include/db.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/include/filevtable.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/include/mpool.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/include/tags create mode 100644 circuitpython/lib/berkeley-db-1.xx/man/Makefile.inc create mode 100644 circuitpython/lib/berkeley-db-1.xx/man/btree.3 create mode 100644 circuitpython/lib/berkeley-db-1.xx/man/dbopen.3 create mode 100644 circuitpython/lib/berkeley-db-1.xx/man/hash.3 create mode 100644 circuitpython/lib/berkeley-db-1.xx/man/mpool.3 create mode 100644 circuitpython/lib/berkeley-db-1.xx/man/recno.3 create mode 100644 circuitpython/lib/berkeley-db-1.xx/mpool/Makefile.inc create mode 100644 circuitpython/lib/berkeley-db-1.xx/mpool/README create mode 100644 circuitpython/lib/berkeley-db-1.xx/mpool/mpool.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/mpool/mpool.libtp create mode 120000 circuitpython/lib/berkeley-db-1.xx/mpool/tags create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/Makefile.inc create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/extern.h create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/rec_close.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/rec_delete.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/rec_get.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/rec_open.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/rec_put.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/rec_search.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/rec_seq.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/rec_utils.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/recno/recno.h create mode 120000 circuitpython/lib/berkeley-db-1.xx/recno/tags create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/Makefile create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/README create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/btree.tests/main.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/dbtest.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/driver2.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/makedb.sh create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tcreat3.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tdel.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/testit create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/thash4.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tread2.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tseq.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tverify.c create mode 100644 circuitpython/lib/berkeley-db-1.xx/test/run.test create mode 100644 circuitpython/lib/cmsis/inc/cmsis_armcc.h create mode 100644 circuitpython/lib/cmsis/inc/cmsis_armclang.h create mode 100644 circuitpython/lib/cmsis/inc/cmsis_armclang_ltm.h create mode 100644 circuitpython/lib/cmsis/inc/cmsis_compiler.h create mode 100644 circuitpython/lib/cmsis/inc/cmsis_gcc.h create mode 100644 circuitpython/lib/cmsis/inc/cmsis_iccarm.h create mode 100644 circuitpython/lib/cmsis/inc/cmsis_version.h create mode 100644 circuitpython/lib/cmsis/inc/core_armv81mml.h create mode 100644 circuitpython/lib/cmsis/inc/core_armv8mbl.h create mode 100644 circuitpython/lib/cmsis/inc/core_armv8mml.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm0.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm0plus.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm1.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm23.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm3.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm33.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm35p.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm4.h create mode 100644 circuitpython/lib/cmsis/inc/core_cm7.h create mode 100644 circuitpython/lib/cmsis/inc/core_sc000.h create mode 100644 circuitpython/lib/cmsis/inc/core_sc300.h create mode 100644 circuitpython/lib/cmsis/inc/mpu_armv7.h create mode 100644 circuitpython/lib/cmsis/inc/mpu_armv8.h create mode 100644 circuitpython/lib/cmsis/inc/tz_context.h create mode 100644 circuitpython/lib/crypto-algorithms/sha256.c create mode 100644 circuitpython/lib/crypto-algorithms/sha256.h create mode 100644 circuitpython/lib/libffi/.travis.yml create mode 100644 circuitpython/lib/libffi/ChangeLog.libffi create mode 100644 circuitpython/lib/libffi/ChangeLog.libffi-3.1 create mode 100644 circuitpython/lib/libffi/ChangeLog.libgcj create mode 100644 circuitpython/lib/libffi/ChangeLog.v1 create mode 100644 circuitpython/lib/libffi/LICENSE create mode 100644 circuitpython/lib/libffi/Makefile.am create mode 100644 circuitpython/lib/libffi/README create mode 100644 circuitpython/lib/libffi/acinclude.m4 create mode 100755 circuitpython/lib/libffi/autogen.sh create mode 100644 circuitpython/lib/libffi/configure.ac create mode 100644 circuitpython/lib/libffi/configure.host create mode 100644 circuitpython/lib/libffi/doc/libffi.texi create mode 100644 circuitpython/lib/libffi/doc/version.texi create mode 100644 circuitpython/lib/libffi/generate-darwin-source-and-headers.py create mode 100644 circuitpython/lib/libffi/include/Makefile.am create mode 100644 circuitpython/lib/libffi/include/ffi.h.in create mode 100644 circuitpython/lib/libffi/include/ffi_cfi.h create mode 100644 circuitpython/lib/libffi/include/ffi_common.h create mode 100644 circuitpython/lib/libffi/libffi.pc.in create mode 100644 circuitpython/lib/libffi/libffi.xcodeproj/project.pbxproj create mode 100755 circuitpython/lib/libffi/libtool-ldflags create mode 100644 circuitpython/lib/libffi/libtool-version create mode 100644 circuitpython/lib/libffi/m4/asmcfi.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_append_flag.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_cc_maxopt.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_cflags_warn_all.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_check_compile_flag.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_compiler_vendor.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_configure_args.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_enable_builddir.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_gcc_archflag.m4 create mode 100644 circuitpython/lib/libffi/m4/ax_gcc_x86_cpuid.m4 create mode 100644 circuitpython/lib/libffi/man/Makefile.am create mode 100644 circuitpython/lib/libffi/man/ffi.3 create mode 100644 circuitpython/lib/libffi/man/ffi_call.3 create mode 100644 circuitpython/lib/libffi/man/ffi_prep_cif.3 create mode 100644 circuitpython/lib/libffi/man/ffi_prep_cif_var.3 create mode 100755 circuitpython/lib/libffi/msvcc.sh create mode 100644 circuitpython/lib/libffi/src/aarch64/ffi.c create mode 100644 circuitpython/lib/libffi/src/aarch64/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/aarch64/internal.h create mode 100644 circuitpython/lib/libffi/src/aarch64/sysv.S create mode 100644 circuitpython/lib/libffi/src/alpha/ffi.c create mode 100644 circuitpython/lib/libffi/src/alpha/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/alpha/internal.h create mode 100644 circuitpython/lib/libffi/src/alpha/osf.S create mode 100644 circuitpython/lib/libffi/src/arc/arcompact.S create mode 100644 circuitpython/lib/libffi/src/arc/ffi.c create mode 100644 circuitpython/lib/libffi/src/arc/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/arm/ffi.c create mode 100644 circuitpython/lib/libffi/src/arm/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/arm/internal.h create mode 100644 circuitpython/lib/libffi/src/arm/sysv.S create mode 100644 circuitpython/lib/libffi/src/avr32/ffi.c create mode 100644 circuitpython/lib/libffi/src/avr32/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/avr32/sysv.S create mode 100644 circuitpython/lib/libffi/src/bfin/ffi.c create mode 100644 circuitpython/lib/libffi/src/bfin/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/bfin/sysv.S create mode 100644 circuitpython/lib/libffi/src/closures.c create mode 100644 circuitpython/lib/libffi/src/cris/ffi.c create mode 100644 circuitpython/lib/libffi/src/cris/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/cris/sysv.S create mode 100644 circuitpython/lib/libffi/src/debug.c create mode 100644 circuitpython/lib/libffi/src/dlmalloc.c create mode 100644 circuitpython/lib/libffi/src/frv/eabi.S create mode 100644 circuitpython/lib/libffi/src/frv/ffi.c create mode 100644 circuitpython/lib/libffi/src/frv/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/ia64/ffi.c create mode 100644 circuitpython/lib/libffi/src/ia64/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/ia64/ia64_flags.h create mode 100644 circuitpython/lib/libffi/src/ia64/unix.S create mode 100644 circuitpython/lib/libffi/src/java_raw_api.c create mode 100644 circuitpython/lib/libffi/src/m32r/ffi.c create mode 100644 circuitpython/lib/libffi/src/m32r/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/m32r/sysv.S create mode 100644 circuitpython/lib/libffi/src/m68k/ffi.c create mode 100644 circuitpython/lib/libffi/src/m68k/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/m68k/sysv.S create mode 100644 circuitpython/lib/libffi/src/m88k/ffi.c create mode 100644 circuitpython/lib/libffi/src/m88k/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/m88k/obsd.S create mode 100644 circuitpython/lib/libffi/src/metag/ffi.c create mode 100644 circuitpython/lib/libffi/src/metag/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/metag/sysv.S create mode 100644 circuitpython/lib/libffi/src/microblaze/ffi.c create mode 100644 circuitpython/lib/libffi/src/microblaze/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/microblaze/sysv.S create mode 100644 circuitpython/lib/libffi/src/mips/ffi.c create mode 100644 circuitpython/lib/libffi/src/mips/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/mips/n32.S create mode 100644 circuitpython/lib/libffi/src/mips/o32.S create mode 100644 circuitpython/lib/libffi/src/moxie/eabi.S create mode 100644 circuitpython/lib/libffi/src/moxie/ffi.c create mode 100644 circuitpython/lib/libffi/src/moxie/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/nios2/ffi.c create mode 100644 circuitpython/lib/libffi/src/nios2/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/nios2/sysv.S create mode 100644 circuitpython/lib/libffi/src/or1k/ffi.c create mode 100644 circuitpython/lib/libffi/src/or1k/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/or1k/sysv.S create mode 100644 circuitpython/lib/libffi/src/pa/ffi.c create mode 100644 circuitpython/lib/libffi/src/pa/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/pa/hpux32.S create mode 100644 circuitpython/lib/libffi/src/pa/linux.S create mode 100644 circuitpython/lib/libffi/src/powerpc/aix.S create mode 100644 circuitpython/lib/libffi/src/powerpc/aix_closure.S create mode 100644 circuitpython/lib/libffi/src/powerpc/asm.h create mode 100644 circuitpython/lib/libffi/src/powerpc/darwin.S create mode 100644 circuitpython/lib/libffi/src/powerpc/darwin_closure.S create mode 100644 circuitpython/lib/libffi/src/powerpc/ffi.c create mode 100644 circuitpython/lib/libffi/src/powerpc/ffi_darwin.c create mode 100644 circuitpython/lib/libffi/src/powerpc/ffi_linux64.c create mode 100644 circuitpython/lib/libffi/src/powerpc/ffi_powerpc.h create mode 100644 circuitpython/lib/libffi/src/powerpc/ffi_sysv.c create mode 100644 circuitpython/lib/libffi/src/powerpc/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/powerpc/linux64.S create mode 100644 circuitpython/lib/libffi/src/powerpc/linux64_closure.S create mode 100644 circuitpython/lib/libffi/src/powerpc/ppc_closure.S create mode 100644 circuitpython/lib/libffi/src/powerpc/sysv.S create mode 100644 circuitpython/lib/libffi/src/prep_cif.c create mode 100644 circuitpython/lib/libffi/src/raw_api.c create mode 100644 circuitpython/lib/libffi/src/s390/ffi.c create mode 100644 circuitpython/lib/libffi/src/s390/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/s390/internal.h create mode 100644 circuitpython/lib/libffi/src/s390/sysv.S create mode 100644 circuitpython/lib/libffi/src/sh/ffi.c create mode 100644 circuitpython/lib/libffi/src/sh/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/sh/sysv.S create mode 100644 circuitpython/lib/libffi/src/sh64/ffi.c create mode 100644 circuitpython/lib/libffi/src/sh64/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/sh64/sysv.S create mode 100644 circuitpython/lib/libffi/src/sparc/ffi.c create mode 100644 circuitpython/lib/libffi/src/sparc/ffi64.c create mode 100644 circuitpython/lib/libffi/src/sparc/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/sparc/internal.h create mode 100644 circuitpython/lib/libffi/src/sparc/v8.S create mode 100644 circuitpython/lib/libffi/src/sparc/v9.S create mode 100644 circuitpython/lib/libffi/src/tile/ffi.c create mode 100644 circuitpython/lib/libffi/src/tile/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/tile/tile.S create mode 100644 circuitpython/lib/libffi/src/types.c create mode 100644 circuitpython/lib/libffi/src/vax/elfbsd.S create mode 100644 circuitpython/lib/libffi/src/vax/ffi.c create mode 100644 circuitpython/lib/libffi/src/vax/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/x86/ffi.c create mode 100644 circuitpython/lib/libffi/src/x86/ffi64.c create mode 100644 circuitpython/lib/libffi/src/x86/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/x86/ffiw64.c create mode 100644 circuitpython/lib/libffi/src/x86/internal.h create mode 100644 circuitpython/lib/libffi/src/x86/internal64.h create mode 100644 circuitpython/lib/libffi/src/x86/sysv.S create mode 100644 circuitpython/lib/libffi/src/x86/unix64.S create mode 100644 circuitpython/lib/libffi/src/x86/win64.S create mode 100644 circuitpython/lib/libffi/src/xtensa/ffi.c create mode 100644 circuitpython/lib/libffi/src/xtensa/ffitarget.h create mode 100644 circuitpython/lib/libffi/src/xtensa/sysv.S create mode 100644 circuitpython/lib/libffi/stamp-h.in create mode 100644 circuitpython/lib/libffi/testsuite/Makefile.am create mode 100644 circuitpython/lib/libffi/testsuite/config/default.exp create mode 100644 circuitpython/lib/libffi/testsuite/lib/libffi.exp create mode 100644 circuitpython/lib/libffi/testsuite/lib/target-libpath.exp create mode 100644 circuitpython/lib/libffi/testsuite/lib/wrapper.exp create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/call.exp create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_fn0.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_fn1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_fn2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_fn3.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_fn4.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_fn5.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_fn6.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_loc_fn0.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/closure_simple.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_12byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_16byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_18byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_19byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_1_1byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_20byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_20byte1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_24byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_2byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_3_1byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_3byte1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_3byte2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_4_1byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_4byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_5_1_byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_5byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_64byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_6_1_byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_6byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_7_1_byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_7byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_8byte.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_9byte1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_9byte2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble_split.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_pointer.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint16.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint32.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint64.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint16.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint32.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint64.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_dbls_struct.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_double_va.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_longdouble_va.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_many_mixed_args.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_schar.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_sshort.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_sshortchar.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_uchar.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_ushort.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_ushortchar.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_pointer.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_pointer_stack.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_schar.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_sint.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_sshort.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_struct_va1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_uchar.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_uchar_va.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_uint.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_uint_va.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_ulong_va.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_ulonglong.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_ushort.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/cls_ushort_va.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/err_bad_abi.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/err_bad_typedef.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/ffitest.h create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/float1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/float2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/float3.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/float4.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/float_va.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/huge_struct.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/many.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/many2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/many_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/many_mixed.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/negint.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct10.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct11.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct3.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct4.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct5.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct6.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct7.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct8.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/nested_struct9.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/pr1172638.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/problem1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/promotion.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/pyobjc-tc.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_dbl.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_dbl1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_dbl2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_fl.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_fl1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_fl2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_fl3.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_ldl.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_ll.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_ll1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_sc.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_sl.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_uc.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/return_ul.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/stret_large.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/stret_large2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/stret_medium.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/stret_medium2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/strlen.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/strlen2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/strlen3.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/strlen4.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct3.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct4.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct5.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct6.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct7.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct8.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/struct9.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/testclosure.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/uninitialized.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/unwindtest.cc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/va_1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/va_struct1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/va_struct2.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex.exp create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_double.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_float.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex_int.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/complex_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/ffitest.h create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/many_complex.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2.inc create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_double.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_float.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_longdouble.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.go/aa-direct.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.go/closure1.c create mode 100644 circuitpython/lib/libffi/testsuite/libffi.go/ffitest.h create mode 100644 circuitpython/lib/libffi/testsuite/libffi.go/go.exp create mode 100644 circuitpython/lib/libffi/testsuite/libffi.go/static-chain.h create mode 100644 circuitpython/lib/libffi/texinfo.tex create mode 100644 circuitpython/lib/libm/acoshf.c create mode 100644 circuitpython/lib/libm/asinfacosf.c create mode 100644 circuitpython/lib/libm/asinhf.c create mode 100644 circuitpython/lib/libm/atan2f.c create mode 100644 circuitpython/lib/libm/atanf.c create mode 100644 circuitpython/lib/libm/atanhf.c create mode 100644 circuitpython/lib/libm/ef_rem_pio2.c create mode 100644 circuitpython/lib/libm/ef_sqrt.c create mode 100644 circuitpython/lib/libm/erf_lgamma.c create mode 100644 circuitpython/lib/libm/fdlibm.h create mode 100644 circuitpython/lib/libm/fmodf.c create mode 100644 circuitpython/lib/libm/kf_cos.c create mode 100644 circuitpython/lib/libm/kf_rem_pio2.c create mode 100644 circuitpython/lib/libm/kf_sin.c create mode 100644 circuitpython/lib/libm/kf_tan.c create mode 100644 circuitpython/lib/libm/libm.h create mode 100644 circuitpython/lib/libm/log1pf.c create mode 100644 circuitpython/lib/libm/math.c create mode 100644 circuitpython/lib/libm/nearbyintf.c create mode 100644 circuitpython/lib/libm/roundf.c create mode 100644 circuitpython/lib/libm/sf_cos.c create mode 100644 circuitpython/lib/libm/sf_erf.c create mode 100644 circuitpython/lib/libm/sf_frexp.c create mode 100644 circuitpython/lib/libm/sf_ldexp.c create mode 100644 circuitpython/lib/libm/sf_modf.c create mode 100644 circuitpython/lib/libm/sf_sin.c create mode 100644 circuitpython/lib/libm/sf_tan.c create mode 100644 circuitpython/lib/libm/thumb_vfp_sqrtf.c create mode 100644 circuitpython/lib/libm/wf_lgamma.c create mode 100644 circuitpython/lib/libm/wf_tgamma.c create mode 100644 circuitpython/lib/libm_dbl/README create mode 100644 circuitpython/lib/libm_dbl/__cos.c create mode 100644 circuitpython/lib/libm_dbl/__expo2.c create mode 100644 circuitpython/lib/libm_dbl/__fpclassify.c create mode 100644 circuitpython/lib/libm_dbl/__rem_pio2.c create mode 100644 circuitpython/lib/libm_dbl/__rem_pio2_large.c create mode 100644 circuitpython/lib/libm_dbl/__signbit.c create mode 100644 circuitpython/lib/libm_dbl/__sin.c create mode 100644 circuitpython/lib/libm_dbl/__tan.c create mode 100644 circuitpython/lib/libm_dbl/acos.c create mode 100644 circuitpython/lib/libm_dbl/acosh.c create mode 100644 circuitpython/lib/libm_dbl/asin.c create mode 100644 circuitpython/lib/libm_dbl/asinh.c create mode 100644 circuitpython/lib/libm_dbl/atan.c create mode 100644 circuitpython/lib/libm_dbl/atan2.c create mode 100644 circuitpython/lib/libm_dbl/atanh.c create mode 100644 circuitpython/lib/libm_dbl/ceil.c create mode 100644 circuitpython/lib/libm_dbl/copysign.c create mode 100644 circuitpython/lib/libm_dbl/cos.c create mode 100644 circuitpython/lib/libm_dbl/cosh.c create mode 100644 circuitpython/lib/libm_dbl/erf.c create mode 100644 circuitpython/lib/libm_dbl/exp.c create mode 100644 circuitpython/lib/libm_dbl/expm1.c create mode 100644 circuitpython/lib/libm_dbl/floor.c create mode 100644 circuitpython/lib/libm_dbl/fmod.c create mode 100644 circuitpython/lib/libm_dbl/frexp.c create mode 100644 circuitpython/lib/libm_dbl/ldexp.c create mode 100644 circuitpython/lib/libm_dbl/lgamma.c create mode 100644 circuitpython/lib/libm_dbl/libm.h create mode 100644 circuitpython/lib/libm_dbl/log.c create mode 100644 circuitpython/lib/libm_dbl/log10.c create mode 100644 circuitpython/lib/libm_dbl/log1p.c create mode 100644 circuitpython/lib/libm_dbl/modf.c create mode 100644 circuitpython/lib/libm_dbl/nearbyint.c create mode 100644 circuitpython/lib/libm_dbl/pow.c create mode 100644 circuitpython/lib/libm_dbl/rint.c create mode 100644 circuitpython/lib/libm_dbl/round.c create mode 100644 circuitpython/lib/libm_dbl/scalbn.c create mode 100644 circuitpython/lib/libm_dbl/sin.c create mode 100644 circuitpython/lib/libm_dbl/sinh.c create mode 100644 circuitpython/lib/libm_dbl/sqrt.c create mode 100644 circuitpython/lib/libm_dbl/tan.c create mode 100644 circuitpython/lib/libm_dbl/tanh.c create mode 100644 circuitpython/lib/libm_dbl/tgamma.c create mode 100644 circuitpython/lib/libm_dbl/thumb_vfp_sqrt.c create mode 100644 circuitpython/lib/libm_dbl/trunc.c create mode 100644 circuitpython/lib/littlefs/README.md create mode 100644 circuitpython/lib/littlefs/lfs1.c create mode 100644 circuitpython/lib/littlefs/lfs1.h create mode 100644 circuitpython/lib/littlefs/lfs1_util.c create mode 100644 circuitpython/lib/littlefs/lfs1_util.h create mode 100644 circuitpython/lib/littlefs/lfs2.c create mode 100644 circuitpython/lib/littlefs/lfs2.h create mode 100644 circuitpython/lib/littlefs/lfs2_util.c create mode 100644 circuitpython/lib/littlefs/lfs2_util.h create mode 100644 circuitpython/lib/mp3/Doxyfile create mode 100644 circuitpython/lib/mp3/README.md create mode 100644 circuitpython/lib/mp3/examples/DMA_fancy_player/.due.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_fancy_player/.esp32.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_fancy_player/.esp8266.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_fancy_player/.leonardo.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_fancy_player/.mega2560.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_fancy_player/.uno.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_fancy_player/.zero.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_fancy_player/DMA_fancy_player.ino create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_SD/.due.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_SD/.esp32.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_SD/.esp8266.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_SD/.leonardo.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_SD/.mega2560.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_SD/.uno.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_SD/.zero.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_SD/DMA_play_from_SD.ino create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/.due.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/.esp32.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/.esp8266.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/.leonardo.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/.mega2560.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/.uno.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/.zero.test.skip create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/DMA_play_from_header.ino create mode 100644 circuitpython/lib/mp3/examples/DMA_play_from_header/sine.h create mode 100644 circuitpython/lib/mp3/examples/play_from_QSPI/play_from_QSPI.ino create mode 100644 circuitpython/lib/mp3/examples/play_from_SD/.due.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_SD/.esp32.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_SD/.esp8266.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_SD/.leonardo.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_SD/.mega2560.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_SD/.uno.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_SD/.zero.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_SD/play_from_SD.ino create mode 100644 circuitpython/lib/mp3/examples/play_from_header/.due.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_header/.esp32.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_header/.esp8266.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_header/.leonardo.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_header/.mega2560.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_header/.uno.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_header/.zero.test.skip create mode 100644 circuitpython/lib/mp3/examples/play_from_header/play_from_header.ino create mode 100644 circuitpython/lib/mp3/examples/play_from_header/sine.h create mode 100644 circuitpython/lib/mp3/examples/standalone/Makefile create mode 100644 circuitpython/lib/mp3/examples/standalone/main.c create mode 100644 circuitpython/lib/mp3/examples/test.mp3 create mode 100644 circuitpython/lib/mp3/library.properties create mode 100644 circuitpython/lib/mp3/src/Adafruit_MP3.cpp create mode 100644 circuitpython/lib/mp3/src/Adafruit_MP3.h create mode 100644 circuitpython/lib/mp3/src/assembly.h create mode 100644 circuitpython/lib/mp3/src/bitstream.c create mode 100644 circuitpython/lib/mp3/src/buffers.c create mode 100644 circuitpython/lib/mp3/src/coder.h create mode 100644 circuitpython/lib/mp3/src/dct32.c create mode 100644 circuitpython/lib/mp3/src/dequant.c create mode 100644 circuitpython/lib/mp3/src/dqchan.c create mode 100644 circuitpython/lib/mp3/src/huffman.c create mode 100644 circuitpython/lib/mp3/src/hufftabs.c create mode 100644 circuitpython/lib/mp3/src/imdct.c create mode 100644 circuitpython/lib/mp3/src/mp3common.h create mode 100644 circuitpython/lib/mp3/src/mp3dec.c create mode 100644 circuitpython/lib/mp3/src/mp3dec.h create mode 100644 circuitpython/lib/mp3/src/mp3tabs.c create mode 100644 circuitpython/lib/mp3/src/mpadecobjfixpt.h create mode 100644 circuitpython/lib/mp3/src/polyphase.c create mode 100644 circuitpython/lib/mp3/src/readme.txt create mode 100644 circuitpython/lib/mp3/src/scalfact.c create mode 100644 circuitpython/lib/mp3/src/statname.h create mode 100644 circuitpython/lib/mp3/src/stproc.c create mode 100644 circuitpython/lib/mp3/src/subband.c create mode 100644 circuitpython/lib/mp3/src/trigtabs.c create mode 100644 circuitpython/lib/nrfutil/README.md create mode 100644 circuitpython/lib/nrfutil/binaries/win32/nrfutil.exe create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/__main__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/bluetooth/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/bluetooth/hci/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/bluetooth/hci/codec.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/bluetooth/hci/slip.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/bluetooth/hci/tests/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/bluetooth/hci/tests/test_codec.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/crc16.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/dfu.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/dfu_transport.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/dfu_transport_ble.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/dfu_transport_serial.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/init_packet.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/intelhex/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/intelhex/compat.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/manifest.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/model.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/nrfhex.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/package.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/signing.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/tests/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/tests/test_dfu_transport_serial.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/tests/test_init_packet.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/tests/test_manifest.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/tests/test_nrfhex.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/tests/test_package.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/tests/test_signing.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/dfu/util.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/exceptions.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/utility/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/utility/target_registry.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/utility/tests/__init__.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/utility/tests/test_target_registry.py create mode 100644 circuitpython/lib/nrfutil/build/lib/nordicsemi/version.py create mode 100644 circuitpython/lib/nrfutil/dist/nrfutil-0.5.2-py2.7.egg create mode 100644 circuitpython/lib/nrfutil/license.txt create mode 100644 circuitpython/lib/nrfutil/nordicsemi/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/__init__.pyc create mode 100644 circuitpython/lib/nrfutil/nordicsemi/__main__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/bluetooth/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/codec.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/slip.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/test_codec.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/crc16.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/dfu.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport_ble.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport_serial.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/init_packet.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/intelhex/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/intelhex/compat.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/manifest.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/model.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/nrfhex.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/package.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/bar.hex create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/bar_wanted.bin create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foo.hex create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foo_wanted.bin create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foobar_wanted.bin create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/pca10028_nrf51422_xxac_blinky.bin create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/s130_nrf51_mini.hex create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/s132_nrf52_mini.hex create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/key.pem create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_dfu_transport_serial.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_init_packet.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_manifest.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_nrfhex.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_package.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_signing.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/dfu/util.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/exceptions.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/utility/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/utility/target_registry.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/utility/tests/__init__.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/utility/tests/test_target_registry.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/utility/tests/test_targets.json create mode 100644 circuitpython/lib/nrfutil/nordicsemi/version.py create mode 100644 circuitpython/lib/nrfutil/nordicsemi/version.pyc create mode 100644 circuitpython/lib/nrfutil/nrfutil.egg-info/PKG-INFO create mode 100644 circuitpython/lib/nrfutil/nrfutil.egg-info/SOURCES.txt create mode 100644 circuitpython/lib/nrfutil/nrfutil.egg-info/dependency_links.txt create mode 100644 circuitpython/lib/nrfutil/nrfutil.egg-info/entry_points.txt create mode 100644 circuitpython/lib/nrfutil/nrfutil.egg-info/not-zip-safe create mode 100644 circuitpython/lib/nrfutil/nrfutil.egg-info/top_level.txt create mode 100644 circuitpython/lib/nrfutil/requirements.txt create mode 100644 circuitpython/lib/nrfutil/setup.py create mode 100644 circuitpython/lib/nrfutil/tests/bdd/environment.py create mode 100644 circuitpython/lib/nrfutil/tests/bdd/genpkg_generate_dfu_package.feature create mode 100644 circuitpython/lib/nrfutil/tests/bdd/genpkg_help_information.feature create mode 100644 circuitpython/lib/nrfutil/tests/bdd/steps/common_steps.py create mode 100644 circuitpython/lib/nrfutil/tests/bdd/steps/genpkg_generate_dfu_package_steps.py create mode 100644 circuitpython/lib/nrfutil/tests/bdd/steps/genpkg_help_information_steps.py create mode 100644 circuitpython/lib/nrfutil/tests/bdd/steps/util.py create mode 100644 circuitpython/lib/nrfutil/tests/resources/blinky.bin create mode 100644 circuitpython/lib/nrfutil/tests/resources/dfu_test_app_hrm_s110.hex create mode 100644 circuitpython/lib/nrfutil/tests/resources/dfu_test_app_hrm_s130.hex create mode 100644 circuitpython/lib/nrfutil/tests/resources/dfu_test_bootloader_b.hex create mode 100644 circuitpython/lib/nrfutil/tests/resources/dfu_test_softdevice_b.hex create mode 100644 circuitpython/lib/nrfutil/tests/resources/test.pem create mode 100644 circuitpython/lib/oofatfs/diskio.h create mode 100644 circuitpython/lib/oofatfs/ff.c create mode 100644 circuitpython/lib/oofatfs/ff.h create mode 100644 circuitpython/lib/oofatfs/ffconf.h create mode 100644 circuitpython/lib/oofatfs/ffunicode.c create mode 100644 circuitpython/lib/protomatter/README.md create mode 100644 circuitpython/lib/protomatter/examples/animated_gif/.matrixportal.test.only create mode 100644 circuitpython/lib/protomatter/examples/animated_gif/animated_gif.ino create mode 100644 circuitpython/lib/protomatter/examples/doublebuffer_scrolltext/doublebuffer_scrolltext.ino create mode 100644 circuitpython/lib/protomatter/examples/pixeldust/pixeldust.ino create mode 100644 circuitpython/lib/protomatter/examples/simple/simple.ino create mode 100644 circuitpython/lib/protomatter/examples/tiled/tiled.ino create mode 100644 circuitpython/lib/protomatter/library.properties create mode 100644 circuitpython/lib/protomatter/src/Adafruit_Protomatter.cpp create mode 100644 circuitpython/lib/protomatter/src/Adafruit_Protomatter.h create mode 100644 circuitpython/lib/protomatter/src/arch/arch.h create mode 100644 circuitpython/lib/protomatter/src/arch/esp32.h create mode 100644 circuitpython/lib/protomatter/src/arch/nrf52.h create mode 100644 circuitpython/lib/protomatter/src/arch/rp2040.h create mode 100644 circuitpython/lib/protomatter/src/arch/samd-common.h create mode 100644 circuitpython/lib/protomatter/src/arch/samd21.h create mode 100644 circuitpython/lib/protomatter/src/arch/samd51.h create mode 100644 circuitpython/lib/protomatter/src/arch/stm32.h create mode 100644 circuitpython/lib/protomatter/src/arch/teensy4.h create mode 100644 circuitpython/lib/protomatter/src/core.c create mode 100644 circuitpython/lib/protomatter/src/core.h create mode 100644 circuitpython/lib/quirc/LICENSE create mode 100644 circuitpython/lib/quirc/Makefile create mode 100644 circuitpython/lib/quirc/README.md create mode 100644 circuitpython/lib/quirc/demo/camera.c create mode 100644 circuitpython/lib/quirc/demo/camera.h create mode 100644 circuitpython/lib/quirc/demo/convert.c create mode 100644 circuitpython/lib/quirc/demo/convert.h create mode 100644 circuitpython/lib/quirc/demo/demo.c create mode 100644 circuitpython/lib/quirc/demo/demo_opencv.cxx create mode 100644 circuitpython/lib/quirc/demo/demoutil.c create mode 100644 circuitpython/lib/quirc/demo/demoutil.h create mode 100644 circuitpython/lib/quirc/demo/dthash.c create mode 100644 circuitpython/lib/quirc/demo/dthash.h create mode 100644 circuitpython/lib/quirc/demo/mjpeg.c create mode 100644 circuitpython/lib/quirc/demo/mjpeg.h create mode 100644 circuitpython/lib/quirc/demo/scanner.c create mode 100644 circuitpython/lib/quirc/lib/decode.c create mode 100644 circuitpython/lib/quirc/lib/identify.c create mode 100644 circuitpython/lib/quirc/lib/quirc.c create mode 100644 circuitpython/lib/quirc/lib/quirc.h create mode 100644 circuitpython/lib/quirc/lib/quirc_internal.h create mode 100644 circuitpython/lib/quirc/lib/version_db.c create mode 100644 circuitpython/lib/quirc/tests/dbgutil.c create mode 100644 circuitpython/lib/quirc/tests/dbgutil.h create mode 100644 circuitpython/lib/quirc/tests/inspect.c create mode 100644 circuitpython/lib/quirc/tests/qrtest.c create mode 100644 circuitpython/lib/re1.5/charclass.c create mode 100644 circuitpython/lib/re1.5/compilecode.c create mode 100644 circuitpython/lib/re1.5/dumpcode.c create mode 100644 circuitpython/lib/re1.5/re1.5.h create mode 100644 circuitpython/lib/re1.5/recursiveloop.c create mode 100644 circuitpython/lib/sdmmc/CMakeLists.txt create mode 100644 circuitpython/lib/sdmmc/component.mk create mode 100644 circuitpython/lib/sdmmc/include/sdmmc_cmd.h create mode 100644 circuitpython/lib/sdmmc/include/sdmmc_defs.h create mode 100644 circuitpython/lib/sdmmc/include/sdmmc_types.h create mode 100644 circuitpython/lib/sdmmc/sdmmc_cmd.c create mode 100644 circuitpython/lib/sdmmc/sdmmc_common.c create mode 100644 circuitpython/lib/sdmmc/sdmmc_common.h create mode 100644 circuitpython/lib/sdmmc/sdmmc_init.c create mode 100644 circuitpython/lib/sdmmc/sdmmc_io.c create mode 100644 circuitpython/lib/sdmmc/sdmmc_mmc.c create mode 100644 circuitpython/lib/sdmmc/sdmmc_sd.c create mode 100644 circuitpython/lib/sdmmc/test/CMakeLists.txt create mode 100644 circuitpython/lib/sdmmc/test/component.mk create mode 100644 circuitpython/lib/sdmmc/test/test_sd.c create mode 100644 circuitpython/lib/sdmmc/test/test_sdio.c create mode 100644 circuitpython/lib/tinytest/README create mode 100644 circuitpython/lib/tinytest/tinytest.c create mode 100644 circuitpython/lib/tinytest/tinytest.h create mode 100644 circuitpython/lib/tinytest/tinytest_macros.h create mode 100644 circuitpython/lib/tinyusb/.readthedocs.yaml create mode 100644 circuitpython/lib/tinyusb/CODE_OF_CONDUCT.rst create mode 100644 circuitpython/lib/tinyusb/CONTRIBUTORS.rst create mode 100644 circuitpython/lib/tinyusb/LICENSE create mode 100644 circuitpython/lib/tinyusb/README.rst create mode 100644 circuitpython/lib/tinyusb/docs/assets/logo.svg create mode 100644 circuitpython/lib/tinyusb/docs/assets/stack.svg create mode 100644 circuitpython/lib/tinyusb/docs/conf.py create mode 120000 circuitpython/lib/tinyusb/docs/contributing/code_of_conduct.rst create mode 100644 circuitpython/lib/tinyusb/docs/contributing/index.rst create mode 100644 circuitpython/lib/tinyusb/docs/contributing/porting.rst create mode 100644 circuitpython/lib/tinyusb/docs/contributing/structure.rst create mode 100644 circuitpython/lib/tinyusb/docs/index.rst create mode 100644 circuitpython/lib/tinyusb/docs/info/changelog.rst create mode 120000 circuitpython/lib/tinyusb/docs/info/contributors.rst create mode 100644 circuitpython/lib/tinyusb/docs/info/index.rst create mode 100644 circuitpython/lib/tinyusb/docs/info/uses.rst create mode 100644 circuitpython/lib/tinyusb/docs/reference/concurrency.rst create mode 100644 circuitpython/lib/tinyusb/docs/reference/getting_started.rst create mode 100644 circuitpython/lib/tinyusb/docs/reference/index.rst create mode 100644 circuitpython/lib/tinyusb/docs/reference/supported.rst create mode 100644 circuitpython/lib/tinyusb/docs/requirements.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/99-tinyusb.rules create mode 100644 circuitpython/lib/tinyusb/examples/device/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_4_channel_mic/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_4_channel_mic/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_4_channel_mic/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_4_channel_mic/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_4_channel_mic/src/plot_audio_samples.py create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_4_channel_mic/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_4_channel_mic/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_test/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_test/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_test/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_test/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_test/src/plot_audio_samples.py create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_test/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/audio_test/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/board_test/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/board_test/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/board_test/sdkconfig.defaults create mode 100644 circuitpython/lib/tinyusb/examples/device/board_test/src/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/board_test/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/board_test/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_dual_ports/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_dual_ports/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_dual_ports/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_dual_ports/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_dual_ports/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc/src/msc_disk.c create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/.skip.MCU_F1C100S create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/sdkconfig.defaults create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/src/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/src/freertos_hook.c create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/src/msc_disk.c create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/cdc_msc_freertos/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu_runtime/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu_runtime/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu_runtime/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu_runtime/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/dfu_runtime/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/dynamic_configuration/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/dynamic_configuration/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/dynamic_configuration/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/dynamic_configuration/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/dynamic_configuration/src/msc_disk.c create mode 100644 circuitpython/lib/tinyusb/examples/device/dynamic_configuration/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/dynamic_configuration/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_boot_interface/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_boot_interface/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_boot_interface/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_boot_interface/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_boot_interface/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_boot_interface/src/usb_descriptors.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite/src/usb_descriptors.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/.skip.MCU_F1C100S create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/sdkconfig.defaults create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/src/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/src/freertos_hook.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_composite_freertos/src/usb_descriptors.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_generic_inout/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_generic_inout/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_generic_inout/boards.js create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_generic_inout/hid_test.js create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_generic_inout/hid_test.py create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_generic_inout/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_generic_inout/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_generic_inout/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_multiple_interface/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_multiple_interface/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_multiple_interface/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_multiple_interface/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/hid_multiple_interface/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/midi_test/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/midi_test/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/midi_test/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/midi_test/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/midi_test/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/msc_dual_lun/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/msc_dual_lun/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/msc_dual_lun/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/msc_dual_lun/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/msc_dual_lun/src/msc_disk_dual.c create mode 100644 circuitpython/lib/tinyusb/examples/device/msc_dual_lun/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/msc_dual_lun/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/net_lwip_webserver/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/net_lwip_webserver/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/net_lwip_webserver/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/net_lwip_webserver/src/arch/cc.h create mode 100644 circuitpython/lib/tinyusb/examples/device/net_lwip_webserver/src/lwipopts.h create mode 100644 circuitpython/lib/tinyusb/examples/device/net_lwip_webserver/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/net_lwip_webserver/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/net_lwip_webserver/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/uac2_headset/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/uac2_headset/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/uac2_headset/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/uac2_headset/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/uac2_headset/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/uac2_headset/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/uac2_headset/src/usb_descriptors.h create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/src/main.h create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/src/usbtmc_app.c create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/src/usbtmc_app.h create mode 100644 circuitpython/lib/tinyusb/examples/device/usbtmc/visaQuery.py create mode 100644 circuitpython/lib/tinyusb/examples/device/video_capture/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/video_capture/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/video_capture/skip.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/video_capture/src/images.h create mode 100644 circuitpython/lib/tinyusb/examples/device/video_capture/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/video_capture/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/video_capture/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/video_capture/src/usb_descriptors.h create mode 100644 circuitpython/lib/tinyusb/examples/device/webusb_serial/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/device/webusb_serial/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/device/webusb_serial/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/device/webusb_serial/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/device/webusb_serial/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/device/webusb_serial/src/usb_descriptors.h create mode 100644 circuitpython/lib/tinyusb/examples/host/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/bare_api/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/bare_api/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/host/bare_api/only.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/bare_api/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/host/bare_api/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/host/cdc_msc_hid/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/cdc_msc_hid/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/host/cdc_msc_hid/only.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/cdc_msc_hid/src/hid_app.c create mode 100644 circuitpython/lib/tinyusb/examples/host/cdc_msc_hid/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/host/cdc_msc_hid/src/msc_app.c create mode 100644 circuitpython/lib/tinyusb/examples/host/cdc_msc_hid/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_controller/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_controller/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_controller/only.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_controller/src/hid_app.c create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_controller/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_controller/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_to_cdc/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_to_cdc/Makefile create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_to_cdc/only.txt create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_to_cdc/src/main.c create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_to_cdc/src/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/examples/host/hid_to_cdc/src/usb_descriptors.c create mode 100644 circuitpython/lib/tinyusb/examples/make.mk create mode 100644 circuitpython/lib/tinyusb/examples/rules.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ansi_escape.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/board.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/board_mcu.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_32bit/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_32bit/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_64bit/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/broadcom_64bit/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/brtmm90x/boards/mm900evxb/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/brtmm90x/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/brtmm90x/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/d5035_01/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/d5035_01/d5035_01.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/d5035_01/same51j19a_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da14695_dk_usb/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da14695_dk_usb/da14695_dk_usb.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da14695_dk_usb/da1469x.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da14695_dk_usb/gcc_startup_da1469x.S create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da14695_dk_usb/product_header.dump create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da14695_dk_usb/syscfg/syscfg.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da1469x_dk_pro/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da1469x_dk_pro/da1469x.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da1469x_dk_pro/gcc_startup_da1469x.S create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da1469x_dk_pro/product_header.dump create mode 100644 circuitpython/lib/tinyusb/hw/bsp/da1469x_dk_pro/syscfg/syscfg.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ea4088qs/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ea4088qs/ea4088qs.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ea4088qs/lpc4088.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ea4357/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ea4357/ea4357.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ea4357/lpc4357.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ea4357/pca9532.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ea4357/pca9532.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/adafruit_feather_esp32s2/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/adafruit_feather_esp32s2/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/adafruit_magtag_29gray/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/adafruit_magtag_29gray/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/adafruit_metro_esp32s2/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/adafruit_metro_esp32s2/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/esp32s2.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/espressif_kaluga_1/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/espressif_kaluga_1/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/espressif_saola_1/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/boards/espressif_saola_1/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/components/led_strip/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/components/led_strip/include/led_strip.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/components/led_strip/src/led_strip_rmt_ws2812.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/family.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s2/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/boards/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/boards/esp32s3.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/boards/espressif_addax_1/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/components/led_strip/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/components/led_strip/include/led_strip.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/components/led_strip/src/led_strip_rmt_ws2812.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/family.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/esp32s3/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/f1c100s/README.md create mode 100644 circuitpython/lib/tinyusb/hw/bsp/f1c100s/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/f1c100s/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/f1c100s/f1c100s.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/family_support.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/boards/fomu/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/boards/fomu/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/crt0-vexriscv.S create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/dfu.py create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/fomu.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/fomu.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/include/csr.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/include/hw/common.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/include/irq.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/output_format.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/fomu/regions.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/frdm_k32l2b/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/frdm_k32l2b/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/frdm_k32l2b/frdm_k32l2b.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/frdm_kl25z/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/frdm_kl25z/frdm_kl25z.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/gd32vf103/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/gd32vf103/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/gd32vf103/system_gd32vf103.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1010_evk/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1010_evk/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1015_evk/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1015_evk/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1020_evk/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1020_evk/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1060_evk/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1064_evk/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/teensy_40/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/teensy_40/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/teensy_40/teensy40_flexspi_nor_config.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/boards/teensy_40/teensy40_flexspi_nor_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/imxrt/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/kuiic/K32L2B31xxxxA_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/kuiic/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/kuiic/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/kuiic/kuiic.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc15/boards/lpcxpresso1549/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc15/boards/lpcxpresso1549/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc15/boards/lpcxpresso1549/lpc1549.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc15/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc15/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc18/boards/lpcxpresso18s37/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc18/boards/mcb1800/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc18/boards/mcb1800/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc18/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc18/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc54/boards/lpcxpresso54114/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc54/boards/lpcxpresso54114/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc54/boards/lpcxpresso54628/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc54/boards/lpcxpresso54628/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc54/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc54/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/double_m33_express/LPC55S69_cm33_core0_uf2.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/double_m33_express/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/double_m33_express/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/lpcxpresso55s28/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/lpcxpresso55s28/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/lpcxpresso55s69/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/lpcxpresso55s69/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/mcu_link/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/boards/mcu_link/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpc55/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso11u37/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso11u37/lpc11u37.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso11u37/lpcxpresso11u37.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso11u68/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso11u68/lpc11u68.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso11u68/lpcxpresso11u68.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso1347/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso1347/lpc1347.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso1347/lpcxpresso1347.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso1769/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso1769/lpc1769.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso1769/lpcxpresso1769.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso51u68/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/lpcxpresso51u68/lpcxpresso51u68.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/mbed1768/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/mbed1768/lpc1768.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/mbed1768/mbed1768.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/mm32/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/msp430/boards/msp_exp430f5529lp/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/msp430/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/msp430/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/msp432e4/boards/msp_exp432e401y/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/msp432e4/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/msp432e4/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ngx4330/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ngx4330/ngx4330.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/ngx4330/ngx4330.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/adafruit_clue/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/adafruit_clue/board.mk create mode 100755 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/adafruit_clue/nrf52840_s140_v6.ld create mode 100755 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/arduino_nano33_ble/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/arduino_nano33_ble/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.mk create mode 100755 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/circuitplayground_bluefruit/nrf52840_s140_v6.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/feather_nrf52840_express/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/feather_nrf52840_express/nrf52840_s140_v6.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/feather_nrf52840_sense/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/feather_nrf52840_sense/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/feather_nrf52840_sense/nrf52840_s140_v6.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/itsybitsy_nrf52840/nrf52840_s140_v6.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/pca10056/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/pca10056/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/pca10059/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/pca10059/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/pca10059/pca10059.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/pca10100/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/pca10100/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nrf/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc121s/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc121s/nuc121_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc121s/nutiny_nuc121.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc125s/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc125s/nuc125_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc125s/nutiny_nuc125.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc126v/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc126v/nuc126_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_nuc126v/nutiny_nuc126.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_sdk_nuc120/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_sdk_nuc120/nuc120_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_sdk_nuc120/nutiny_sdk_nuc120.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_sdk_nuc505/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_sdk_nuc505/nuc505_flashtoram.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/nutiny_sdk_nuc505/nutiny_sdk_nuc505.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/pic32mz/boards/olimex_emz64/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/pic32mz/boards/olimex_hmz144/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/pic32mz/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/pic32mz/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/boards/adafruit_feather_rp2040/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/boards/adafruit_itsybitsy_rp2040/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/boards/adafruit_qtpy_rp2040/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/boards/pico_sdk/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/family.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rp2040/pico_sdk_import.cmake create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rx/boards/gr_citrus/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rx/boards/gr_citrus/gr_citrus.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rx/boards/gr_citrus/hwinit.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rx/boards/gr_citrus/r5f5631fd.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rx/boards/rx65n_target/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rx/boards/rx65n_target/r5f565ne.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rx/boards/rx65n_target/rx65n_target.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/rx/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd11/boards/luna_d11/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd11/boards/luna_d11/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd11/boards/luna_d11/samd11d14am_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd11/boards/samd11_xplained/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd11/boards/samd11_xplained/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd11/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd11/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/atsamd21_xpro/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/atsamd21_xpro/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/atsamd21_xpro/samd21j18a_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/circuitplayground_express/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/circuitplayground_express/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/circuitplayground_express/circuitplayground_express.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/curiosity_nano/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/curiosity_nano/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/curiosity_nano/samd21g17a_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/feather_m0_express/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/feather_m0_express/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/feather_m0_express/feather_m0_express.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/itsybitsy_m0/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/itsybitsy_m0/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/itsybitsy_m0/itsybitsy_m0.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/luna_d21/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/luna_d21/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/luna_d21/samd21g18a_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/metro_m0_express/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/metro_m0_express/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/metro_m0_express/metro_m0_express.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/qtpy/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/qtpy/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/qtpy/qtpy.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/seeeduino_xiao/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/seeeduino_xiao/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/seeeduino_xiao/seeeduino_xiao.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/trinket_m0/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/trinket_m0/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd21/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/feather_m4_express/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/feather_m4_express/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/itsybitsy_m4/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/itsybitsy_m4/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/metro_m4_express/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/metro_m4_express/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/pybadge/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/pybadge/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/pybadge/pybadge.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/pyportal/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/pyportal/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/boards/pyportal/pyportal.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samd51/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same54xplainedpro/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same54xplainedpro/same54p20a_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same54xplainedpro/same54p20a_sram.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same54xplainedpro/same54xplainedpro.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_qmtech/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_qmtech/hpl_pmc_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_qmtech/hpl_usart_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_qmtech/hpl_xdmac_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_qmtech/peripheral_clk_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_qmtech/same70_qmtech.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_xplained/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_xplained/hpl_pmc_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_xplained/hpl_usart_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_xplained/hpl_xdmac_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_xplained/peripheral_clk_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/same70_xplained/same70_xplained.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samg55xplained/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samg55xplained/hpl_usart_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samg55xplained/peripheral_clk_config.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samg55xplained/samg55j19_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/samg55xplained/samg55xplained.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/atsaml21_xpro/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/saml22_feather/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/saml22_feather/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/sensorwatch_m0/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/saml2x/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/sltb009a/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/sltb009a/sltb009a.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/spresense/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/spresense/board_spresense.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f070rbnucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f070rbnucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f0/stm32f0xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f1/stm32f1xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/stm32f207nucleo.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/stm32f2xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/stm32f303disco.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/stm32f3xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/stm32f7xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/stm32f7xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/stm32f7xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/stm32f7xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/stm32f7xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/stm32f7xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32g4/stm32g4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/stm32h743xx_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/stm32h743xx_flash.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h745disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h745disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/STM32H743IITX_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32h7/stm32h7xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/stm32l0538disco.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/stm32l0xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32l4/stm32l4xx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/stm32wb/stm32wbxx_hal_conf.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/tm4c123.ld create mode 100644 circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/xmc4000/boards/xmc4500_relax/board.h create mode 100644 circuitpython/lib/tinyusb/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk create mode 100644 circuitpython/lib/tinyusb/hw/bsp/xmc4000/family.c create mode 100644 circuitpython/lib/tinyusb/hw/bsp/xmc4000/family.mk create mode 100644 circuitpython/lib/tinyusb/hw/mcu/bridgetek/ft9xx/Readme.md create mode 100644 circuitpython/lib/tinyusb/hw/mcu/bridgetek/ft9xx/scripts/crt0.S create mode 100644 circuitpython/lib/tinyusb/hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/README.md create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/arm_license.txt create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/DA1469xAB.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_compiler.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_gcc.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_version.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm0.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm33.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/mpu_armv8.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_ARMCM0.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_DA1469x.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/da1469x.ld create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/hal/hal_gpio.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/mcu.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/da1469x_clock.c create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_gpio.c create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_system.c create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_system_start.c create mode 100644 circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/system_da1469x.c create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_err.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gap.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatt.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gattc.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatts.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_hci.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_l2cap.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_ranges.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_types.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf52/nrf_mbr.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_sdm.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_soc.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_nvic.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_sdm.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_soc.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_svc.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_config.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_glue.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_log.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/Makefile create mode 100644 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.c create mode 100644 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/elf32.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.c create mode 100644 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.h create mode 100644 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc create mode 100755 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/flash_writer.py create mode 100644 circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/xmodem.py create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/License.txt create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/README.txt create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.c create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.h create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_Conf.h create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_GCC.c create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_KEIL.c create mode 100644 circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_SES.c create mode 100644 circuitpython/lib/tinyusb/lib/fatfs/00readme.txt create mode 100644 circuitpython/lib/tinyusb/lib/fatfs/ccsbcs.c create mode 100644 circuitpython/lib/tinyusb/lib/fatfs/diskio.c create mode 100644 circuitpython/lib/tinyusb/lib/fatfs/diskio.h create mode 100644 circuitpython/lib/tinyusb/lib/fatfs/ff.c create mode 100644 circuitpython/lib/tinyusb/lib/fatfs/ff.h create mode 100644 circuitpython/lib/tinyusb/lib/fatfs/ffconf.h create mode 100644 circuitpython/lib/tinyusb/lib/fatfs/integer.h create mode 100644 circuitpython/lib/tinyusb/lib/networking/dhserver.c create mode 100644 circuitpython/lib/tinyusb/lib/networking/dhserver.h create mode 100644 circuitpython/lib/tinyusb/lib/networking/dnserver.c create mode 100644 circuitpython/lib/tinyusb/lib/networking/dnserver.h create mode 100644 circuitpython/lib/tinyusb/lib/networking/ndis.h create mode 100644 circuitpython/lib/tinyusb/lib/networking/rndis_protocol.h create mode 100644 circuitpython/lib/tinyusb/lib/networking/rndis_reports.c create mode 100644 circuitpython/lib/tinyusb/pkg.yml create mode 100644 circuitpython/lib/tinyusb/repository.yml create mode 100644 circuitpython/lib/tinyusb/src/class/audio/audio.h create mode 100644 circuitpython/lib/tinyusb/src/class/audio/audio_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/audio/audio_device.h create mode 100755 circuitpython/lib/tinyusb/src/class/bth/bth_device.c create mode 100755 circuitpython/lib/tinyusb/src/class/bth/bth_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/cdc/cdc.h create mode 100644 circuitpython/lib/tinyusb/src/class/cdc/cdc_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/cdc/cdc_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/cdc/cdc_host.c create mode 100644 circuitpython/lib/tinyusb/src/class/cdc/cdc_host.h create mode 100644 circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis.h create mode 100644 circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis_host.c create mode 100644 circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis_host.h create mode 100644 circuitpython/lib/tinyusb/src/class/dfu/dfu.h create mode 100644 circuitpython/lib/tinyusb/src/class/dfu/dfu_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/dfu/dfu_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/dfu/dfu_rt_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/dfu/dfu_rt_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/hid/hid.h create mode 100644 circuitpython/lib/tinyusb/src/class/hid/hid_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/hid/hid_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/hid/hid_host.c create mode 100644 circuitpython/lib/tinyusb/src/class/hid/hid_host.h create mode 100644 circuitpython/lib/tinyusb/src/class/midi/midi.h create mode 100644 circuitpython/lib/tinyusb/src/class/midi/midi_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/midi/midi_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/msc/msc.h create mode 100644 circuitpython/lib/tinyusb/src/class/msc/msc_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/msc/msc_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/msc/msc_host.c create mode 100644 circuitpython/lib/tinyusb/src/class/msc/msc_host.h create mode 100644 circuitpython/lib/tinyusb/src/class/net/ecm_rndis_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/net/ncm.h create mode 100644 circuitpython/lib/tinyusb/src/class/net/ncm_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/net/net_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc.h create mode 100644 circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/vendor/vendor_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/vendor/vendor_device.h create mode 100644 circuitpython/lib/tinyusb/src/class/vendor/vendor_host.c create mode 100644 circuitpython/lib/tinyusb/src/class/vendor/vendor_host.h create mode 100644 circuitpython/lib/tinyusb/src/class/video/video.h create mode 100644 circuitpython/lib/tinyusb/src/class/video/video_device.c create mode 100644 circuitpython/lib/tinyusb/src/class/video/video_device.h create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_common.h create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_compiler.h create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_error.h create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_fifo.c create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_fifo.h create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_mcu.h create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_timeout.h create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_types.h create mode 100644 circuitpython/lib/tinyusb/src/common/tusb_verify.h create mode 100644 circuitpython/lib/tinyusb/src/device/dcd.h create mode 100644 circuitpython/lib/tinyusb/src/device/usbd.c create mode 100644 circuitpython/lib/tinyusb/src/device/usbd.h create mode 100644 circuitpython/lib/tinyusb/src/device/usbd_control.c create mode 100644 circuitpython/lib/tinyusb/src/device/usbd_pvt.h create mode 100644 circuitpython/lib/tinyusb/src/host/hcd.h create mode 100644 circuitpython/lib/tinyusb/src/host/hub.c create mode 100644 circuitpython/lib/tinyusb/src/host/hub.h create mode 100644 circuitpython/lib/tinyusb/src/host/usbh.c create mode 100644 circuitpython/lib/tinyusb/src/host/usbh.h create mode 100644 circuitpython/lib/tinyusb/src/host/usbh_classdriver.h create mode 100644 circuitpython/lib/tinyusb/src/host/usbh_control.c create mode 100644 circuitpython/lib/tinyusb/src/osal/osal.h create mode 100644 circuitpython/lib/tinyusb/src/osal/osal_freertos.h create mode 100644 circuitpython/lib/tinyusb/src/osal/osal_mynewt.h create mode 100644 circuitpython/lib/tinyusb/src/osal/osal_none.h create mode 100644 circuitpython/lib/tinyusb/src/osal/osal_pico.h create mode 100644 circuitpython/lib/tinyusb/src/osal/osal_rtthread.h create mode 100644 circuitpython/lib/tinyusb/src/osal/osal_rtx4.h create mode 100644 circuitpython/lib/tinyusb/src/portable/bridgetek/ft9xx/dcd_ft9xx.c create mode 100644 circuitpython/lib/tinyusb/src/portable/broadcom/synopsys/dcd_synopsys.c create mode 100644 circuitpython/lib/tinyusb/src/portable/broadcom/synopsys/synopsys_common.h create mode 100644 circuitpython/lib/tinyusb/src/portable/chipidea/ci_hs/ci_hs_imxrt.h create mode 100644 circuitpython/lib/tinyusb/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h create mode 100644 circuitpython/lib/tinyusb/src/portable/chipidea/ci_hs/ci_hs_type.h create mode 100644 circuitpython/lib/tinyusb/src/portable/chipidea/ci_hs/dcd_ci_hs.c create mode 100644 circuitpython/lib/tinyusb/src/portable/chipidea/ci_hs/hcd_ci_hs.c create mode 100644 circuitpython/lib/tinyusb/src/portable/dialog/da146xx/dcd_da146xx.c create mode 100644 circuitpython/lib/tinyusb/src/portable/ehci/ehci.c create mode 100644 circuitpython/lib/tinyusb/src/portable/ehci/ehci.h create mode 100644 circuitpython/lib/tinyusb/src/portable/ehci/ehci_api.h create mode 100644 circuitpython/lib/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c create mode 100644 circuitpython/lib/tinyusb/src/portable/mentor/musb/dcd_musb.c create mode 100644 circuitpython/lib/tinyusb/src/portable/mentor/musb/hcd_musb.c create mode 100644 circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_msp432e.h create mode 100644 circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_tm4c.h create mode 100644 circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_type.h create mode 100644 circuitpython/lib/tinyusb/src/portable/microchip/pic32mz/dcd_pic32mz.c create mode 100644 circuitpython/lib/tinyusb/src/portable/microchip/pic32mz/usbhs_registers.h create mode 100644 circuitpython/lib/tinyusb/src/portable/microchip/samd/dcd_samd.c create mode 100644 circuitpython/lib/tinyusb/src/portable/microchip/samg/dcd_samg.c create mode 100644 circuitpython/lib/tinyusb/src/portable/microchip/samx7x/common_usb_regs.h create mode 100644 circuitpython/lib/tinyusb/src/portable/microchip/samx7x/dcd_samx7x.c create mode 100644 circuitpython/lib/tinyusb/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nuvoton/nuc120/dcd_nuc120.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nuvoton/nuc121/dcd_nuc121.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nuvoton/nuc505/dcd_nuc505.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/khci/dcd_khci.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/khci/hcd_khci.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/dcd_lpc17_40.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/dcd_lpc17_40.h create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/hcd_lpc17_40.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/transdimension/common_transdimension.h create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c create mode 100644 circuitpython/lib/tinyusb/src/portable/nxp/transdimension/hcd_transdimension.c create mode 100644 circuitpython/lib/tinyusb/src/portable/ohci/ohci.c create mode 100644 circuitpython/lib/tinyusb/src/portable/ohci/ohci.h create mode 100644 circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c create mode 100644 circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/hcd_rp2040.c create mode 100644 circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c create mode 100644 circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.h create mode 100644 circuitpython/lib/tinyusb/src/portable/renesas/usba/dcd_usba.c create mode 100644 circuitpython/lib/tinyusb/src/portable/renesas/usba/hcd_usba.c create mode 100644 circuitpython/lib/tinyusb/src/portable/sony/cxd56/dcd_cxd56.c create mode 100644 circuitpython/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c create mode 100644 circuitpython/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h create mode 100644 circuitpython/lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c create mode 100644 circuitpython/lib/tinyusb/src/portable/st/synopsys/synopsys_common.h create mode 100644 circuitpython/lib/tinyusb/src/portable/sunxi/dcd_sunxi_musb.c create mode 100644 circuitpython/lib/tinyusb/src/portable/sunxi/musb_def.h create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_bcm.h create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_efm32.h create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_esp32.h create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_gd32.h create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_stm32.h create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_type.h create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_xmc.h create mode 100644 circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/hwcfg_list.md create mode 100644 circuitpython/lib/tinyusb/src/portable/template/dcd_template.c create mode 100644 circuitpython/lib/tinyusb/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c create mode 100644 circuitpython/lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.c create mode 100644 circuitpython/lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.h create mode 100644 circuitpython/lib/tinyusb/src/tusb.c create mode 100644 circuitpython/lib/tinyusb/src/tusb.h create mode 100644 circuitpython/lib/tinyusb/src/tusb_option.h create mode 100644 circuitpython/lib/tinyusb/test/ceedling create mode 100644 circuitpython/lib/tinyusb/test/project.yml create mode 100644 circuitpython/lib/tinyusb/test/test/device/msc/test_msc_device.c create mode 100644 circuitpython/lib/tinyusb/test/test/device/usbd/test_usbd.c create mode 100644 circuitpython/lib/tinyusb/test/test/support/tusb_config.h create mode 100644 circuitpython/lib/tinyusb/test/test/test_fifo.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/bin/ceedling create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CException.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CMock_Summary.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CeedlingPacket.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/ThrowTheSwitchCodingStandard.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityAssertionsReference.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityConfigurationGuide.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityGettingStartedGuide.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityHelperScriptsGuide.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/build_invoker_utils.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cacheinator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cacheinator_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cmock_builder.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_builder.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_plugins.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_setup.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_validator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/constants.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/defaults.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/dependinator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/erb_wrapper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_finder.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_finder_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_path_utils.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_system_utils.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_system_wrapper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_wrapper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/flaginator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_results.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_results_sanity_checker.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_runner.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/loginator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/makefile.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/objects.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/par_map.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_builder.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_manager.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_manager_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_reportinator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_reportinator_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_extractor.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_file_handler.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_includes_handler.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/project_config_manager.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/project_file_loader.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rake_utils.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rake_wrapper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rakefile.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/release_invoker.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/release_invoker_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/reportinator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_cmock.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_preprocess.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_release.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_release_deep_dependencies.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_tests.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_tests_deep_dependencies.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/setupinator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/stream_wrapper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/streaminator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/streaminator_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/system_utils.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/system_wrapper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/target_loader.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/task_invoker.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_base.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_filesystem.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_release.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_release_deep_dependencies.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_tests.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_tests_deep_dependencies.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_vendor.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_includes_extractor.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_invoker.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_invoker_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tool_executor.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tool_executor_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/verbosinator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/version.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/version.rb.erb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/yaml_wrapper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/beep/README.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/beep/lib/beep.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/assets/template.erb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/bullseye.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/config/defaults.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/lib/bullseye.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/readme.txt create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/colour_report/lib/colour_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/command_hooks/README.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/command_hooks/lib/command_hooks.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/README.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/Rakefile create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/project.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/rakefile.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/custom_types.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_event_processor.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_foo.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_header_generator_spec.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_source_generator_spec.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/header_generator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/spec_helper.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/src/fff_unity_helper.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/README.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/assets/template.erb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/config/defaults.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/gcov.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/lib/gcov.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/lib/gcov_constants.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/junit_tests_report/README.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/junit_tests_report/lib/junit_tests_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/config/module_generator.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/lib/module_generator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/module_generator.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/raw_output_report/lib/raw_output_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/assets/template.erb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/assets/template.erb copy create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/config/stdout_gtestlike_tests_report.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/lib/stdout_gtestlike_tests_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_ide_tests_report/config/stdout_ide_tests_report.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_ide_tests_report/lib/stdout_ide_tests_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/assets/template.erb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/config/stdout_pretty_tests_report.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/lib/stdout_pretty_tests_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/README.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/config/defaults.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/lib/subprojects.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/subprojects.rake create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/teamcity_tests_report/config/teamcity_tests_report.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/teamcity_tests_report/lib/teamcity_tests_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/warnings_report/lib/warnings_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/xml_tests_report/README.md create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/xml_tests_report/lib/xml_tests_report.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/lib/CException.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/lib/CException.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/release/build.info create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/release/version.info create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/config/production_environment.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/config/test_environment.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_config.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_array.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_cexception.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect_any_args.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore_arg.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_unityhelper_parser.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/release/build.info create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/release/version.info create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock_internals.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/meson.build create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/deep_merge/lib/deep_merge.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/diy/lib/diy.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/diy/lib/diy/factory.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/colour_prompt.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/colour_reporter.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_config.yml create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_module.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/parse_output.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/run_test.erb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/stylize_as_junit.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/test_file_filter.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/type_sanitizer.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/release/build.info create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/release/version.info create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/CMakeLists.txt create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/meson.build create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity.c create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity.h create mode 100644 circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity_internals.h create mode 100644 circuitpython/lib/tinyusb/tools/build_board.py create mode 100644 circuitpython/lib/tinyusb/tools/build_esp32sx.py create mode 100644 circuitpython/lib/tinyusb/tools/build_family.py create mode 100644 circuitpython/lib/tinyusb/tools/build_utils.py create mode 100644 circuitpython/lib/tinyusb/tools/iar_gen.py create mode 100644 circuitpython/lib/tinyusb/tools/iar_template.ipcf create mode 100644 circuitpython/lib/tinyusb/tools/mksunxi.py create mode 100644 circuitpython/lib/tinyusb/tools/top.mk create mode 100644 circuitpython/lib/tinyusb/tools/usb_drivers/tinyusb_win_usbser.inf create mode 100644 circuitpython/lib/tinyusb/version.yml create mode 100644 circuitpython/lib/uzlib/adler32.c create mode 100644 circuitpython/lib/uzlib/crc32.c create mode 100644 circuitpython/lib/uzlib/defl_static.h create mode 100644 circuitpython/lib/uzlib/tinf.h create mode 100644 circuitpython/lib/uzlib/tinf_compat.h create mode 100644 circuitpython/lib/uzlib/tinfgzip.c create mode 100644 circuitpython/lib/uzlib/tinflate.c create mode 100644 circuitpython/lib/uzlib/tinfzlib.c create mode 100644 circuitpython/lib/uzlib/uzlib.h create mode 100644 circuitpython/lib/uzlib/uzlib_conf.h (limited to 'circuitpython/lib') diff --git a/circuitpython/lib/README.md b/circuitpython/lib/README.md new file mode 100644 index 0000000..fd7cba9 --- /dev/null +++ b/circuitpython/lib/README.md @@ -0,0 +1,3 @@ +This directory contains third-party, low-level C libraries and SDKs. +Libraries that do not target any specific platform are generally chosen +based on them being independent and efficient. diff --git a/circuitpython/lib/adafruit_floppy/LICENSES/CC-BY-4.0.txt b/circuitpython/lib/adafruit_floppy/LICENSES/CC-BY-4.0.txt new file mode 100644 index 0000000..13ca539 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/LICENSES/CC-BY-4.0.txt @@ -0,0 +1,156 @@ +Creative Commons Attribution 4.0 International + + Creative Commons Corporation (“Creative Commonsâ€) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is†basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. + +Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors. + +Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public. + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. + +Section 1 – Definitions. + + a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + + d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. + + g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights under this Public License. + + i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. + +Section 2 – Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. + + 3. Term. The term of this Public License is specified in Section 6(a). + + 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. + + 5. Downstream recipients. + + A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. + + B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. + + 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). + +b. Other rights. + + 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this Public License. + + 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. + +Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified form), You must: + + A. retain the following if it is supplied by the Licensor with the Licensed Material: + + i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + + v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + + B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and + + C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. + + 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. + +Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; + + b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. +For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. + +Section 5 – Disclaimer of Warranties and Limitation of Liability. + + a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You. + + b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You. + + c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. + +Section 6 – Term and Termination. + + a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + + c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. + + d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. + + e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +Section 7 – Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. + +Section 8 – Interpretation. + + a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. + + c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. + + d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. + +Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.†Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons†or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/circuitpython/lib/adafruit_floppy/LICENSES/CC0-1.0.txt b/circuitpython/lib/adafruit_floppy/LICENSES/CC0-1.0.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/circuitpython/lib/adafruit_floppy/LICENSES/MIT.txt b/circuitpython/lib/adafruit_floppy/LICENSES/MIT.txt new file mode 100644 index 0000000..2071b23 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/LICENSES/MIT.txt @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/circuitpython/lib/adafruit_floppy/Makefile b/circuitpython/lib/adafruit_floppy/Makefile new file mode 100644 index 0000000..3b6b2b6 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/Makefile @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2022 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +mfm: stand/main.c mfm_impl.h + gcc -iquote . -o $@ $< + +.PHONY: test +test: mfm + ./mfm < flux.txt + +.PHONY: clean +clean: + rm -f mfm diff --git a/circuitpython/lib/adafruit_floppy/README.md b/circuitpython/lib/adafruit_floppy/README.md new file mode 100644 index 0000000..9290f9f --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/README.md @@ -0,0 +1,45 @@ +# Adafruit Floppy [![Build Status](https://github.com/adafruit/Adafruit_Floppy/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_Floppy/actions) + +![Adafruit Floppy](./images/rabbit.png) + +This is a helper library to abstract away interfacing with floppy disk drives in a cross-platform and open source library. + +Adafruit Floppy is a project to make a flexible, full-stack, open source hardware/software device for reading, archiving, accessing and duplicating floppy disk media. It joins a family of open source hardware and software such as greaseweazle and fluxengine, and will attempt to increase the availability and accessibility of floppy disk controllers by: + +1. **porting the greaseweazle / fluxengine firmware to Arduino** so that it is less tied to specific hardware. this is important as, during 2021 we learned that silicon shortages can make specific chips extremely difficult to find - having a cross-platform firmware alleviates dependancies on specific chips. + +2. **adding firmware support for the RP2040 chip / pico**. this is an ultra low cost dev board, at $4 each - and can make for an excellent alternative to higher cost atmel/stm chips. (of course, the firmware should be able to run on many chips, but we want to make sure this is one of them!) + +3. **adding hardware support for reading apple ii disks**. many flux readers focus on 34-pin disk drives but do not have interfacing for apple disk ii drives. the drives are available and could be used for archiving a vast number of floppies out there! this will require adding an index sensor so we can image disks into 'woz' formats. currently, applesauce hardware and software can do this for apple ii disks - applesauce is amazing and an excellent tool and we recommend it to folks! at this time, it appears to be closed source hardware, firmware and software, so we are not able to integrate their design into an open source design. + +4. **adding woz/a2r support to greaseweazle / fluxengine**. once hardware support is in place, we can then add woz/a2r file format support to the open source tools in existence, which will benefit the entire community + +5. as 'extra credit' we may look into **analog flux data acquisition methods** for repair of damaged disks. + +Any hardware, firmware, or software we write is going to be fully open source under permissive licenses such as MIT, BSD or Unlicense. we will probably sell accessories, assembled PCBs, cables, etc in the Adafruit shop to help get hardware into folks hands but the designs will always be re-createable by others without any licensing agreements, NDAs, or discussion. + +https://user-images.githubusercontent.com/1685947/147865571-c9ea1d68-6603-436d-9980-bc5ade148db8.mp4 + +https://user-images.githubusercontent.com/1685947/147864181-c5885b15-1809-4e54-8680-4cfba3f54faa.mp4 + +Latest video Jan 1, 2022 - 9pm EDT + +Currently we are focusing on high-RAM (> 128KB SRAM) and high speed (> 100MHz) processors, so that we can buffer a full track of flux transitions at once, and not require the use of special peripherals such as timers. (Of course, those are welcome later!) + +Tested working on: + * SAMD51 chipset hardware - Please overclock to 180MHz, select Fastest optimization, and use TinyUSB stack for best performance + * RP2040 chipset hardware - Please use philhower core, overclock to 200MHz, and select -O3 optimization for best performance +Longer version! + +## Frequently Asked/Accused Questions + +There's a LOT of preconceptions about floppy disks and how / why we have this library. Here are some answers! + +* **How are you connecting a 3.3V logic microcontroller to a 5V Floppy Drive directly WITHOUT a level shifter, won't this destroy the board?** +Floppy drives are powered by 5V, and they use open drain outputs. That means that if the microcontroller pulls the index pin (for example) high to 3.3V, the logic level will be 3V. Is this out of spec? Maybe! But it does seem to work. Of course its always polite to use a level shifter, so if you can please add it to your hardware design. We do recommend a stronger external pullup on the READDATA line, 4.7K or so seems fine, other lines are fine with an internal pullup. +* **Did you know there are USB Floppy Drives for $10 on Amazon?** Yes, we are aware. These are recycled laptop floppy drives with a controller chip that presents a mass storage interface to the sectors on disk. They are great for basic access to 1.44MB IBM PC MFM-formatted diskettes. They will *not* work for GCR formatted diskettes (we know because we tried) and may not work with non-FAT formatted diskettes (we don't have any but the controller chip is very specialized and may freak out). USB floppy drive controllers will not get you flux-level readings, and can't cope with damaged diskettes to read sector data that does not pass CRC to perform data recovery. They are also, of course, no good with 5.25" floppy diskettes. +* **Why do you need a flux level reading of disks???** Flux level readings are essential for data recovery, restoration, archiving of damaged or copy-protected floppies. You can read more about floppy disk preservation efforts here: https://wiki.archiveteam.org/index.php/Rescuing_Floppy_Disks + +Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from [Adafruit](https://adafruit.com)! + +MIT license, all text above must be included in any redistribution. diff --git a/circuitpython/lib/adafruit_floppy/code-of-conduct.md b/circuitpython/lib/adafruit_floppy/code-of-conduct.md new file mode 100644 index 0000000..8ee6e44 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/code-of-conduct.md @@ -0,0 +1,127 @@ +# Adafruit Community Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and leaders pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level or type of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +We are committed to providing a friendly, safe and welcoming environment for +all. + +Examples of behavior that contributes to creating a positive environment +include: + +* Be kind and courteous to others +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Collaborating with other community members +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and sexual attention or advances +* The use of inappropriate images, including in a community member's avatar +* The use of inappropriate language, including in a community member's nickname +* Any spamming, flaming, baiting or other attention-stealing behavior +* Excessive or unwelcome helping; answering outside the scope of the question + asked +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate + +The goal of the standards and moderation guidelines outlined here is to build +and maintain a respectful community. We ask that you don’t just aim to be +"technically unimpeachable", but rather try to be your best self. + +We value many things beyond technical expertise, including collaboration and +supporting others within our community. Providing a positive experience for +other community members can have a much more significant impact than simply +providing the correct answer. + +## Our Responsibilities + +Project leaders are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project leaders have the right and responsibility to remove, edit, or +reject messages, comments, commits, code, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any community member for other behaviors that they deem +inappropriate, threatening, offensive, or harmful. + +## Moderation + +Instances of behaviors that violate the Adafruit Community Code of Conduct +may be reported by any member of the community. Community members are +encouraged to report these situations, including situations they witness +involving other community members. + +You may report in the following ways: + +In any situation, you may send an email to . + +On the Adafruit Discord, you may send an open message from any channel +to all Community Helpers by tagging @community helpers. You may also send an +open message from any channel, or a direct message to @kattni#1507, +@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or +@Andon#8175. + +Email and direct message reports will be kept confidential. + +In situations on Discord where the issue is particularly egregious, possibly +illegal, requires immediate action, or violates the Discord terms of service, +you should also report the message directly to Discord. + +These are the steps for upholding our community’s standards of conduct. + +1. Any member of the community may report any situation that violates the +Adafruit Community Code of Conduct. All reports will be reviewed and +investigated. +2. If the behavior is an egregious violation, the community member who +committed the violation may be banned immediately, without warning. +3. Otherwise, moderators will first respond to such behavior with a warning. +4. Moderators follow a soft "three strikes" policy - the community member may +be given another chance, if they are receptive to the warning and change their +behavior. +5. If the community member is unreceptive or unreasonable when warned by a +moderator, or the warning goes unheeded, they may be banned for a first or +second offense. Repeated offenses will result in the community member being +banned. + +## Scope + +This Code of Conduct and the enforcement policies listed above apply to all +Adafruit Community venues. This includes but is not limited to any community +spaces (both public and private), the entire Adafruit Discord server, and +Adafruit GitHub repositories. Examples of Adafruit Community spaces include +but are not limited to meet-ups, audio chats on the Adafruit Discord, or +interaction at a conference. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. As a community +member, you are representing our community, and are expected to behave +accordingly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.4, available at +, +and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). + +For other projects adopting the Adafruit Community Code of +Conduct, please contact the maintainers of those projects for enforcement. +If you wish to use this code of conduct for your own project, consider +explicitly mentioning your moderation policy or making a copy with your +own moderation policy so as to avoid confusion. diff --git a/circuitpython/lib/adafruit_floppy/examples/fat_test/fat_test.ino b/circuitpython/lib/adafruit_floppy/examples/fat_test/fat_test.ino new file mode 100644 index 0000000..f9ff9ff --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/examples/fat_test/fat_test.ino @@ -0,0 +1,157 @@ +/* + * Print size, modify date/time, and name for all files in root. + */ + +/********************************************************************* + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! +*********************************************************************/ + +#include +#include "SdFat.h" +#include + +// If using SAMD51, turn on TINYUSB USB stack +#if defined(ADAFRUIT_FEATHER_M4_EXPRESS) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN A4 // IDC 18 + #define STEP_PIN A5 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 (not used during read) + #define WRGATE_PIN 12 // IDC 24 (not used during read) + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 6 // IDC 32 + #define READY_PIN 5 // IDC 34 +#if F_CPU != 180000000L + #warning "please set CPU speed to 180MHz overclock" +#endif +#elif defined (ARDUINO_ADAFRUIT_FEATHER_RP2040) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN 24 // IDC 18 + #define STEP_PIN 25 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 (not used during read) + #define WRGATE_PIN 12 // IDC 24 (not used during read) + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 8 // IDC 32 + #define READY_PIN 7 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif +#elif defined (ARDUINO_RASPBERRY_PI_PICO) + #define DENSITY_PIN 2 // IDC 2 + #define INDEX_PIN 3 // IDC 8 + #define SELECT_PIN 4 // IDC 12 + #define MOTOR_PIN 5 // IDC 16 + #define DIR_PIN 6 // IDC 18 + #define STEP_PIN 7 // IDC 20 + #define WRDATA_PIN 8 // IDC 22 (not used during read) + #define WRGATE_PIN 9 // IDC 24 (not used during read) + #define TRK0_PIN 10 // IDC 26 + #define PROT_PIN 11 // IDC 28 + #define READ_PIN 12 // IDC 30 + #define SIDE_PIN 13 // IDC 32 + #define READY_PIN 14 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif +#else +#error "Please set up pin definitions!" +#endif + +Adafruit_Floppy floppy(DENSITY_PIN, INDEX_PIN, SELECT_PIN, + MOTOR_PIN, DIR_PIN, STEP_PIN, + WRDATA_PIN, WRGATE_PIN, TRK0_PIN, + PROT_PIN, READ_PIN, SIDE_PIN, READY_PIN); +Adafruit_MFM_Floppy mfm_floppy(&floppy); + +// file system object from SdFat +FatFileSystem fatfs; + +FatFile root; +FatFile file; + +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(115200); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + + Serial.println("Floppy FAT directory listing demo"); + + // Init floppy drive - must spin up and find index + if (! mfm_floppy.begin()) { + Serial.println("Floppy didn't initialize - check wiring and diskette!"); + } + + // Init file system on the flash + fatfs.begin(&mfm_floppy); + + if (!root.open("/")) { + Serial.println("open root failed"); + } + // Open next file in root. + // Warning, openNext starts at the current directory position + // so a rewind of the directory may be required. + while (file.openNext(&root, O_RDONLY)) { + file.printFileSize(&Serial); + Serial.write(' '); + file.printModifyDateTime(&Serial); + Serial.write(' '); + file.printName(&Serial); + if (file.isDir()) { + // Indicate a directory. + Serial.write('/'); + } + Serial.println(); + file.close(); + } + + if (root.getError()) { + Serial.println("openNext failed"); + } else { + Serial.println("Done!"); + } +} +//------------------------------------------------------------------------------ +void loop() { + Serial.print("Read a file? >"); + String filename; + do { + filename = Serial.readStringUntil('\n'); + filename.trim(); + } while (filename.length() == 0); + + Serial.print("Reading file name: "); + Serial.println(filename); + + // Open the file for reading and check that it was successfully opened. + // The FILE_READ mode will open the file for reading. + File dataFile = fatfs.open(filename, FILE_READ); + if (!dataFile) { + Serial.println("Failed to open data file! Does it exist?"); + return; + } + // File was opened, now print out data character by character until at the + // end of the file. + Serial.println("Opened file, printing contents below:"); + while (dataFile.available()) { + // Use the read function to read the next character. + // You can alternatively use other functions like readUntil, readString, etc. + // See the fatfs_full_usage example for more details. + char c = dataFile.read(); + Serial.print(c); + } +} diff --git a/circuitpython/lib/adafruit_floppy/examples/floppy_capture_track_test/floppy_capture_track_test.ino b/circuitpython/lib/adafruit_floppy/examples/floppy_capture_track_test/floppy_capture_track_test.ino new file mode 100644 index 0000000..2861b0c --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/examples/floppy_capture_track_test/floppy_capture_track_test.ino @@ -0,0 +1,112 @@ +#include + +// If using SAMD51, turn on TINYUSB USB stack +#if defined(ADAFRUIT_FEATHER_M4_EXPRESS) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN A4 // IDC 18 + #define STEP_PIN A5 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 (not used during read) + #define WRGATE_PIN 12 // IDC 24 (not used during read) + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 6 // IDC 32 + #define READY_PIN 5 // IDC 34 +#if F_CPU != 180000000L + #warning "please set CPU speed to 180MHz overclock" +#endif +#elif defined (ARDUINO_ADAFRUIT_FEATHER_RP2040) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN 24 // IDC 18 + #define STEP_PIN 25 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 (not used during read) + #define WRGATE_PIN 12 // IDC 24 (not used during read) + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 6 // IDC 32 + #define READY_PIN 5 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif +#elif defined (ARDUINO_RASPBERRY_PI_PICO) + #define DENSITY_PIN 2 // IDC 2 + #define INDEX_PIN 3 // IDC 8 + #define SELECT_PIN 4 // IDC 12 + #define MOTOR_PIN 5 // IDC 16 + #define DIR_PIN 6 // IDC 18 + #define STEP_PIN 7 // IDC 20 + #define WRDATA_PIN 8 // IDC 22 (not used during read) + #define WRGATE_PIN 9 // IDC 24 (not used during read) + #define TRK0_PIN 10 // IDC 26 + #define PROT_PIN 11 // IDC 28 + #define READ_PIN 12 // IDC 30 + #define SIDE_PIN 13 // IDC 32 + #define READY_PIN 14 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif +#else +#error "Please set up pin definitions!" +#endif + +Adafruit_Floppy floppy(DENSITY_PIN, INDEX_PIN, SELECT_PIN, + MOTOR_PIN, DIR_PIN, STEP_PIN, + WRDATA_PIN, WRGATE_PIN, TRK0_PIN, + PROT_PIN, READ_PIN, SIDE_PIN, READY_PIN); + +// WARNING! there are 150K max flux pulses per track! +uint8_t flux_transitions[MAX_FLUX_PULSE_PER_TRACK]; + +uint32_t time_stamp = 0; + + +void setup() { + Serial.begin(115200); + while (!Serial) delay(100); + + Serial.println("its time for a nice floppy transfer!"); + floppy.debug_serial = &Serial; + floppy.begin(); + + floppy.select(true); + if (! floppy.spin_motor(true)) { + Serial.println("Failed to spin up motor & find index pulse"); + while (1) yield(); + } + + Serial.print("Seeking track..."); + if (! floppy.goto_track(0)) { + Serial.println("Failed to seek to track"); + while (1) yield(); + } + Serial.println("done!"); +} + +void loop() { + uint32_t captured_flux = floppy.capture_track(flux_transitions, sizeof(flux_transitions)); + + Serial.print("Captured "); + Serial.print(captured_flux); + Serial.println(" flux transitions"); + + //floppy.print_pulses(flux_transitions, captured_flux); + floppy.print_pulse_bins(flux_transitions, captured_flux, 255); + + if ((millis() - time_stamp) > 1000) { + Serial.print("Ready? "); + Serial.println(digitalRead(READY_PIN) ? "No" : "Yes"); + Serial.print("Write Protected? "); + Serial.println(digitalRead(PROT_PIN) ? "No" : "Yes"); + Serial.print("Track 0? "); + Serial.println(digitalRead(TRK0_PIN) ? "No" : "Yes"); + time_stamp = millis(); + } + yield(); +} diff --git a/circuitpython/lib/adafruit_floppy/examples/greaseweazle/greaseweazle.ino b/circuitpython/lib/adafruit_floppy/examples/greaseweazle/greaseweazle.ino new file mode 100644 index 0000000..5ed7a4b --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/examples/greaseweazle/greaseweazle.ino @@ -0,0 +1,525 @@ +#include + +#if defined(ADAFRUIT_FEATHER_M4_EXPRESS) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN A4 // IDC 18 + #define STEP_PIN A5 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 + #define WRGATE_PIN 12 // IDC 24 + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 6 // IDC 32 + #define READY_PIN 5 // IDC 34 +#if F_CPU != 180000000L + #warning "please set CPU speed to 180MHz overclock" +#endif + #define GW_SAMPLEFREQ (F_CPU * 11/90) // samd51 is sample rate of 22MHz at 180MHz OC +#elif defined (ARDUINO_ADAFRUIT_FEATHER_RP2040) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN 24 // IDC 18 + #define STEP_PIN 25 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 + #define WRGATE_PIN 12 // IDC 24 + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 8 // IDC 32 + #define READY_PIN 7 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif + #define GW_SAMPLEFREQ 26000000UL // 26mhz for rp2040 +#elif defined (ARDUINO_RASPBERRY_PI_PICO) + #define DENSITY_PIN 2 // IDC 2 + #define INDEX_PIN 3 // IDC 8 + #define SELECT_PIN 4 // IDC 12 + #define MOTOR_PIN 5 // IDC 16 + #define DIR_PIN 6 // IDC 18 + #define STEP_PIN 7 // IDC 20 + #define WRDATA_PIN 8 // IDC 22 (not used during read) + #define WRGATE_PIN 9 // IDC 24 (not used during read) + #define TRK0_PIN 10 // IDC 26 + #define PROT_PIN 11 // IDC 28 + #define READ_PIN 12 // IDC 30 + #define SIDE_PIN 13 // IDC 32 + #define READY_PIN 14 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif + #define GW_SAMPLEFREQ 26000000UL // 26mhz for rp2040 +#else +#error "Please set up pin definitions!" +#endif + +Adafruit_Floppy floppy(DENSITY_PIN, INDEX_PIN, SELECT_PIN, + MOTOR_PIN, DIR_PIN, STEP_PIN, + WRDATA_PIN, WRGATE_PIN, TRK0_PIN, + PROT_PIN, READ_PIN, SIDE_PIN, READY_PIN); + +uint32_t time_stamp = 0; + +uint8_t cmd_buffer[32], reply_buffer[128]; +uint8_t cmd_buff_idx = 0; + +#define GW_FIRMVER_MAJOR 1 +#define GW_FIRMVER_MINOR 0 +#define GW_MAXCMD 21 +#define GW_HW_MODEL 8 // Adafruity +#define GW_HW_SUBMODEL 0 // Adafruit Floppy Generic +#define GW_USB_SPEED 0 // Full Speed + +#define GW_CMD_GETINFO 0 +#define GW_CMD_GETINFO_FIRMWARE 0 +#define GW_CMD_GETINFO_BANDWIDTH 1 +#define GW_CMD_SEEK 2 +#define GW_CMD_HEAD 3 +#define GW_CMD_SETPARAMS 4 +#define GW_CMD_GETPARAMS 5 +#define GW_CMD_GETPARAMS_DELAYS 0 +#define GW_CMD_MOTOR 6 +#define GW_CMD_READFLUX 7 +#define GW_CMD_GETFLUXSTATUS 9 +#define GW_CMD_SELECT 12 +#define GW_CMD_DESELECT 13 +#define GW_CMD_SETBUSTYPE 14 +#define GW_CMD_SETBUSTYPE_IBM 1 +#define GW_CMD_SETBUSTYPE_SHUGART 2 +#define GW_CMD_SETPIN 15 +#define GW_CMD_RESET 16 +#define GW_CMD_SOURCEBYTES 18 +#define GW_CMD_SINKBYTES 19 +#define GW_CMD_GETPIN 20 + +#define GW_ACK_OK (byte)0 +#define GW_ACK_BADCMD 1 +#define GW_ACK_NOINDEX 2 +#define GW_ACK_NOTRACK0 3 +#define GW_ACK_NOUNIT 7 + +uint32_t timestamp = 0; + +void setup() { + Serial.begin(115200); + Serial1.begin(115200); + //while (!Serial) delay(100); + Serial1.println("GrizzlyWizzly"); + + floppy.debug_serial = &Serial1; + floppy.begin(); + timestamp = millis(); +} + +uint8_t get_cmd(uint8_t *buff, uint8_t maxbuff) { + int i=0; + + if (Serial.available() < 2) return 0; + buff[i++] = Serial.read(); + buff[i++] = Serial.read(); + // wait for remaining data + while (Serial.available() < (buff[1] - 2)) { + delay(1); + yield(); + } + for (; i timestamp) && ((millis()-timestamp) > 3000)) { + Serial1.println("Timed out waiting for command, resetting motor"); + floppy.goto_track(0); + floppy.spin_motor(false); + motor_state = false; + floppy.select(false); + timestamp = millis(); + } + return; + } + timestamp = millis(); + + int i = 0; + uint8_t cmd = cmd_buffer[0]; + memset(reply_buffer, 0, sizeof(reply_buffer)); + reply_buffer[i++] = cmd; // echo back the cmd itself + + Serial1.printf("Got command 0x%02x\n\r", cmd); + + if (cmd == GW_CMD_GETINFO) { + Serial1.println("Get info"); + uint8_t sub_cmd = cmd_buffer[2]; + if (sub_cmd == GW_CMD_GETINFO_FIRMWARE) { + reply_buffer[i++] = GW_ACK_OK; + reply_buffer[i++] = GW_FIRMVER_MAJOR; // 1 byte + reply_buffer[i++] = GW_FIRMVER_MINOR; // 1 byte + reply_buffer[i++] = 1; // is main firm + reply_buffer[i++] = GW_MAXCMD; + reply_buffer[i++] = GW_SAMPLEFREQ & 0xFF; + reply_buffer[i++] = (GW_SAMPLEFREQ >> 8) & 0xFF; + reply_buffer[i++] = (GW_SAMPLEFREQ >> 16) & 0xFF; + reply_buffer[i++] = (GW_SAMPLEFREQ >> 24) & 0xFF; + reply_buffer[i++] = GW_HW_MODEL; + reply_buffer[i++] = GW_HW_SUBMODEL; + reply_buffer[i++] = GW_USB_SPEED; + Serial.write(reply_buffer, 34); + } + else if (sub_cmd == GW_CMD_GETINFO_BANDWIDTH) { + reply_buffer[i++] = GW_ACK_OK; + uint32_t min_bytes = transfered_bytes; + uint32_t max_bytes = transfered_bytes; + uint32_t min_usec = bandwidth_timer * 1000; + uint32_t max_usec = bandwidth_timer * 1000; + // TODO What is this math supposed to be?? + + reply_buffer[i++] = min_bytes & 0xFF; + reply_buffer[i++] = min_bytes >> 8; + reply_buffer[i++] = min_bytes >> 16; + reply_buffer[i++] = min_bytes >> 24; + reply_buffer[i++] = min_usec & 0xFF; + reply_buffer[i++] = min_usec >> 8; + reply_buffer[i++] = min_usec >> 16; + reply_buffer[i++] = min_usec >> 24; + reply_buffer[i++] = max_bytes & 0xFF; + reply_buffer[i++] = max_bytes >> 8; + reply_buffer[i++] = max_bytes >> 16; + reply_buffer[i++] = max_bytes >> 24; + reply_buffer[i++] = max_usec & 0xFF; + reply_buffer[i++] = max_usec >> 8; + reply_buffer[i++] = max_usec >> 16; + reply_buffer[i++] = max_usec >> 24; + + // TODO more? + Serial.write(reply_buffer, 34); + } + } + + else if (cmd == GW_CMD_GETPARAMS) { + Serial1.println("Get params"); + uint8_t sub_cmd = cmd_buffer[2]; + if (sub_cmd == GW_CMD_GETPARAMS_DELAYS) { + reply_buffer[i++] = GW_ACK_OK; + reply_buffer[i++] = floppy.select_delay_us & 0xFF; + reply_buffer[i++] = floppy.select_delay_us >> 8; + reply_buffer[i++] = floppy.step_delay_us & 0xFF; + reply_buffer[i++] = floppy.step_delay_us >> 8; + reply_buffer[i++] = floppy.settle_delay_ms & 0xFF; + reply_buffer[i++] = floppy.settle_delay_ms >> 8; + reply_buffer[i++] = floppy.motor_delay_ms & 0xFF; + reply_buffer[i++] = floppy.motor_delay_ms >> 8; + reply_buffer[i++] = floppy.watchdog_delay_ms & 0xFF; + reply_buffer[i++] = floppy.watchdog_delay_ms >> 8; + Serial.write(reply_buffer, 12); + } + } + + else if (cmd == GW_CMD_RESET) { + Serial1.println("Soft reset"); + floppy.soft_reset(); + reply_buffer[i++] = GW_ACK_OK; + Serial.write(reply_buffer, 2); + } + + else if (cmd == GW_CMD_SETBUSTYPE) { + uint8_t bustype = cmd_buffer[2]; + Serial1.printf("Set bus type %d\n\r", bustype); + // TODO: whats the diff??? + if (bustype == GW_CMD_SETBUSTYPE_IBM) { + reply_buffer[i++] = GW_ACK_OK; + } + else if (bustype == GW_CMD_SETBUSTYPE_SHUGART) { + floppy.bus_type = BUSTYPE_SHUGART; + reply_buffer[i++] = GW_ACK_OK; + } else { + reply_buffer[i++] = GW_ACK_BADCMD; + } + Serial.write(reply_buffer, 2); + } + + else if (cmd == GW_CMD_SEEK) { + uint8_t track = cmd_buffer[2]; + Serial1.printf("Seek track %d\n\r", track); + bool r = floppy.goto_track(track); + if (r) { + reply_buffer[i++] = GW_ACK_OK; + } else { + reply_buffer[i++] = GW_ACK_NOTRACK0; + } + Serial.write(reply_buffer, 2); + } + + else if (cmd == GW_CMD_HEAD) { + uint8_t head = cmd_buffer[2]; + Serial1.printf("Seek head %d\n\r", head); + floppy.side(head); + reply_buffer[i++] = GW_ACK_OK; + Serial.write(reply_buffer, 2); + } + + else if (cmd == GW_CMD_MOTOR) { + uint8_t unit = cmd_buffer[2]; + uint8_t state = cmd_buffer[3]; + Serial1.printf("Turn motor %d %s\n\r", unit, state ? "on" : "off"); + if (motor_state != state) { // we're in the opposite state + if (! floppy.spin_motor(state)) { + reply_buffer[i++] = GW_ACK_NOINDEX; + } else { + reply_buffer[i++] = GW_ACK_OK; + } + motor_state = state; + } else { + // our cached state is correct! + reply_buffer[i++] = GW_ACK_OK; + } + Serial.write(reply_buffer, 2); + } + + else if (cmd == GW_CMD_SELECT) { + uint8_t sub_cmd = cmd_buffer[2]; + Serial1.printf("Select drive %d\n\r", sub_cmd); + if (sub_cmd == 0) { + floppy.select(true); + reply_buffer[i++] = GW_ACK_OK; + } else { + reply_buffer[i++] = GW_ACK_NOUNIT; + } + Serial.write(reply_buffer, 2); + } + + else if (cmd == GW_CMD_DESELECT) { + Serial1.printf("Deselect drive\n\r"); + floppy.select(false); + reply_buffer[i++] = GW_ACK_OK; + Serial.write(reply_buffer, 2); + } + + else if (cmd == GW_CMD_READFLUX) { + uint32_t flux_ticks; + uint16_t revs; + flux_ticks = cmd_buffer[5]; + flux_ticks <<= 8; + flux_ticks |= cmd_buffer[4]; + flux_ticks <<= 8; + flux_ticks |= cmd_buffer[3]; + flux_ticks <<= 8; + flux_ticks |= cmd_buffer[2]; + revs = cmd_buffer[7]; + revs <<= 8; + revs |= cmd_buffer[6]; + revs -= 1; + + if (floppy.track() == -1) { + floppy.goto_track(0); + } + + Serial1.printf("Reading flux0rs on track %d: %u ticks and %d revs\n\r", floppy.track(), flux_ticks, revs); + reply_buffer[i++] = GW_ACK_OK; + Serial.write(reply_buffer, 2); + while (revs--) { + captured_pulses = floppy.capture_track(flux_transitions, sizeof(flux_transitions)); + Serial1.printf("Rev #%d captured %u pulses\n\r", revs, captured_pulses); + //floppy.print_pulse_bins(flux_transitions, captured_pulses, 64, Serial1); + // trim down extra long pulses + for (uint32_t f=0; f 250) { + flux_transitions[f] = 250; + } + } + // Send the index opcode, which is right at the start of this data xfer + reply_buffer[0] = 0xFF; + reply_buffer[1] = 1; // index opcode + reply_buffer[2] = 0x1; + reply_buffer[3] = 0x1; + reply_buffer[4] = 0x1; + reply_buffer[5] = 0x1; // 0 are special, so we send 1 to == 0 + Serial.write(reply_buffer, 6); + + uint8_t *flux_ptr = flux_transitions; + while (captured_pulses) { + uint32_t to_send = min(captured_pulses, (uint32_t)256); + Serial.write(flux_ptr, to_send); + //Serial1.println(to_send); + flux_ptr += to_send; + captured_pulses -= to_send; + } + } + + // send a final indexop + reply_buffer[0] = 0xFF; + reply_buffer[1] = 1; // index opcode + reply_buffer[2] = 0x1; + reply_buffer[3] = 0x1; + reply_buffer[4] = 0x1; + reply_buffer[5] = 0x1; // 0 are special, so we send 1 to == 0 + Serial.write(reply_buffer, 6); + + // flush input, to account for fluxengine bug + while (Serial.available()) Serial.read(); + Serial.write((byte)0); + } + + else if (cmd == GW_CMD_GETFLUXSTATUS) { + Serial1.println("get flux status"); + reply_buffer[i++] = GW_ACK_OK; + Serial.write(reply_buffer, 2); + } + + + else if (cmd == GW_CMD_SINKBYTES) { + uint32_t numbytes = 0; + uint32_t seed = 0; + numbytes |= cmd_buffer[5]; + numbytes <<= 8; + numbytes |= cmd_buffer[4]; + numbytes <<= 8; + numbytes |= cmd_buffer[3]; + numbytes <<= 8; + numbytes |= cmd_buffer[2]; + Serial1.printf("sink numbytes %d\n\r", numbytes); + + seed |= cmd_buffer[9]; + seed <<= 8; + seed |= cmd_buffer[8]; + seed <<= 8; + seed |= cmd_buffer[7]; + seed <<= 8; + seed |= cmd_buffer[6]; + reply_buffer[i++] = GW_ACK_OK; + Serial.write(reply_buffer, 2); + yield(); + bandwidth_timer = millis(); + transfered_bytes = numbytes; + bytes_per_sec = numbytes; + + while (numbytes != 0) { + uint32_t avail = Serial.available(); + if (avail == 0) { + //Serial1.print("-"); + yield(); + continue; + } + //Serial1.printf("%lu avail, ", avail); + uint32_t to_read = min(numbytes, min((uint32_t)sizeof(reply_buffer), avail)); + //Serial1.printf("%lu to read, ", to_read); + numbytes -= Serial.readBytes((char *)reply_buffer, to_read); + //Serial1.printf("%lu remain\n\r", numbytes); + } + bandwidth_timer = millis() - bandwidth_timer; + bytes_per_sec /= bandwidth_timer; + bytes_per_sec *= 1000; + Serial1.print("Done in "); + Serial1.print(bandwidth_timer); + Serial1.print(" ms, "); + Serial1.print(bytes_per_sec); + Serial1.println(" bytes per sec"); + Serial.write(GW_ACK_OK); + yield(); + } + else if (cmd == GW_CMD_SOURCEBYTES) { + uint32_t numbytes = 0; + uint32_t seed = 0; + numbytes |= cmd_buffer[5]; + numbytes <<= 8; + numbytes |= cmd_buffer[4]; + numbytes <<= 8; + numbytes |= cmd_buffer[3]; + numbytes <<= 8; + numbytes |= cmd_buffer[2]; + Serial1.printf("source numbytes %d\n\r", numbytes); + + seed |= cmd_buffer[9]; + seed <<= 8; + seed |= cmd_buffer[8]; + seed <<= 8; + seed |= cmd_buffer[7]; + seed <<= 8; + seed |= cmd_buffer[6]; + reply_buffer[i++] = GW_ACK_OK; + Serial.write(reply_buffer, 2); + yield(); + bandwidth_timer = millis(); + bytes_per_sec = numbytes; + transfered_bytes = numbytes; + + uint32_t randnum = seed; + while (numbytes != 0) { + uint32_t to_write = min(numbytes, sizeof(reply_buffer)); + // we dont write 'just anything'! + for (uint32_t i=0; i> 1) ^ 0x80000062; + } else { + randnum >>= 1; + } + } + numbytes -= Serial.write(reply_buffer, to_write); + } + bandwidth_timer = millis() - bandwidth_timer; + bytes_per_sec /= bandwidth_timer; + bytes_per_sec *= 1000; + Serial1.print("Done in "); + Serial1.print(bandwidth_timer); + Serial1.print(" ms, "); + Serial1.print(bytes_per_sec); + Serial1.println(" bytes per sec"); + } else if (cmd == GW_CMD_GETPIN) { + uint32_t pin = cmd_buffer[2]; + Serial1.printf("getpin %d\n\r", pin); + + switch(pin) { + case 26: + reply_buffer[i++] = GW_ACK_OK; + reply_buffer[i++] = digitalRead(TRK0_PIN); + break; + + default: + // unknown pin, don't pretend we did it right + reply_buffer[i++] = GW_ACK_BADCMD; + reply_buffer[i++] = 0; + } + Serial.write(reply_buffer, i); + } else if (cmd == GW_CMD_SETPIN) { + uint32_t pin = cmd_buffer[2]; + bool value = cmd_buffer[3]; + Serial1.printf("setpin %d to \n\r", pin, value); + + switch(pin) { + case 2: + pinMode(DENSITY_PIN, OUTPUT); + digitalWrite(DENSITY_PIN, value); + reply_buffer[i++] = GW_ACK_OK; + break; + + default: + // unknown pin, don't pretend we did it right + reply_buffer[i++] = GW_ACK_BADCMD; + } + + Serial.write(reply_buffer, i); + + /********** unknown ! ********/ + } else { + reply_buffer[i++] = GW_ACK_BADCMD; + Serial.write(reply_buffer, 2); + } + //Serial1.println("cmd complete!"); +} \ No newline at end of file diff --git a/circuitpython/lib/adafruit_floppy/examples/mfm_test/mfm_test.ino b/circuitpython/lib/adafruit_floppy/examples/mfm_test/mfm_test.ino new file mode 100644 index 0000000..07206f1 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/examples/mfm_test/mfm_test.ino @@ -0,0 +1,138 @@ +#include + + + +// If using SAMD51, turn on TINYUSB USB stack +#if defined(ADAFRUIT_FEATHER_M4_EXPRESS) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN A4 // IDC 18 + #define STEP_PIN A5 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 (not used during read) + #define WRGATE_PIN 12 // IDC 24 (not used during read) + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 6 // IDC 32 + #define READY_PIN 5 // IDC 34 +#if F_CPU != 180000000L + #warning "please set CPU speed to 180MHz overclock" +#endif +#elif defined (ARDUINO_ADAFRUIT_FEATHER_RP2040) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN 24 // IDC 18 + #define STEP_PIN 25 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 (not used during read) + #define WRGATE_PIN 12 // IDC 24 (not used during read) + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 8 // IDC 32 + #define READY_PIN 7 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif +#elif defined (ARDUINO_RASPBERRY_PI_PICO) + #define DENSITY_PIN 2 // IDC 2 + #define INDEX_PIN 3 // IDC 8 + #define SELECT_PIN 4 // IDC 12 + #define MOTOR_PIN 5 // IDC 16 + #define DIR_PIN 6 // IDC 18 + #define STEP_PIN 7 // IDC 20 + #define WRDATA_PIN 8 // IDC 22 (not used during read) + #define WRGATE_PIN 9 // IDC 24 (not used during read) + #define TRK0_PIN 10 // IDC 26 + #define PROT_PIN 11 // IDC 28 + #define READ_PIN 12 // IDC 30 + #define SIDE_PIN 13 // IDC 32 + #define READY_PIN 14 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif +#else +#error "Please set up pin definitions!" +#endif + +Adafruit_Floppy floppy(DENSITY_PIN, INDEX_PIN, SELECT_PIN, + MOTOR_PIN, DIR_PIN, STEP_PIN, + WRDATA_PIN, WRGATE_PIN, TRK0_PIN, + PROT_PIN, READ_PIN, SIDE_PIN, READY_PIN); + +// You can select IBMPC1440K or IBMPC360K (check adafruit_floppy_disk_t options!) +Adafruit_MFM_Floppy mfm_floppy(&floppy, IBMPC360K); + + +uint32_t time_stamp = 0; + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); + Serial.begin(115200); + while (!Serial) delay(100); + + delay(500); // wait for serial to open + Serial.println("its time for a nice floppy transfer!"); + + floppy.debug_serial = &Serial; + + if (! mfm_floppy.begin()) { + Serial.println("Failed to spin up motor & find index pulse"); + while (1) yield(); + } +} + +uint8_t track = 0; +bool head = 0; +void loop() { + int32_t captured_sectors; + + Serial.printf("Seeking track %d head %d\n", track, head); + captured_sectors = mfm_floppy.readTrack(track, head); + if (captured_sectors < 0) { + Serial.println("Failed to seek to track"); + while (1) yield(); + } + + Serial.printf("Captured %d sectors\n", captured_sectors); + + Serial.print("Validity: "); + for(size_t i=0; i < mfm_floppy.sectors_per_track(); i++) { + Serial.print(mfm_floppy.track_validity[i] ? "V" : "?"); + } + Serial.print("\n"); + for(size_t sector=0; sector < mfm_floppy.sectors_per_track(); sector++) { + if (!mfm_floppy.track_validity[sector]) { + continue; // skip it, not valid + } + for(size_t i=0; i<512; i+=16) { + size_t addr = sector * 512 + i; + Serial.printf("%08x", addr); + for(size_t j=0; j<16; j++) { + Serial.printf(" %02x", mfm_floppy.track_data[addr+j]); + } + Serial.print(" | "); + for(size_t j=0; j<16; j++) { + uint8_t d = mfm_floppy.track_data[addr+j]; + if (! isprint(d)) { + d = ' '; + } + Serial.write(d); + } + Serial.print("\n"); + } + } + + // advance to next track + if (!head) { // we were on side 0 + head = 1; // go to side 1 + } else { // we were on side 1? + track = (track + 1) % mfm_floppy.tracks_per_side(); // next track! + head = 0; // and side 0 + } + + delay(1000); +} \ No newline at end of file diff --git a/circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino b/circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino new file mode 100644 index 0000000..ab407cd --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino @@ -0,0 +1,163 @@ +// this example makes a lot of assumptions: MFM floppy which is already inserted +// and only reading is supported - no write yet! + +#include +#include "Adafruit_TinyUSB.h" + +Adafruit_USBD_MSC usb_msc; + +// If using SAMD51, turn on TINYUSB USB stack +#if defined(ADAFRUIT_FEATHER_M4_EXPRESS) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN A4 // IDC 18 + #define STEP_PIN A5 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 (not used during read) + #define WRGATE_PIN 12 // IDC 24 (not used during read) + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 6 // IDC 32 + #define READY_PIN 5 // IDC 34 +#if F_CPU != 180000000L + #warning "please set CPU speed to 180MHz overclock" +#endif +#elif defined (ARDUINO_ADAFRUIT_FEATHER_RP2040) + #define DENSITY_PIN A0 // IDC 2 + #define INDEX_PIN A1 // IDC 8 + #define SELECT_PIN A2 // IDC 12 + #define MOTOR_PIN A3 // IDC 16 + #define DIR_PIN 24 // IDC 18 + #define STEP_PIN 25 // IDC 20 + #define WRDATA_PIN 13 // IDC 22 (not used during read) + #define WRGATE_PIN 12 // IDC 24 (not used during read) + #define TRK0_PIN 11 // IDC 26 + #define PROT_PIN 10 // IDC 28 + #define READ_PIN 9 // IDC 30 + #define SIDE_PIN 8 // IDC 32 + #define READY_PIN 7 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif +#elif defined (ARDUINO_RASPBERRY_PI_PICO) + #define DENSITY_PIN 2 // IDC 2 + #define INDEX_PIN 3 // IDC 8 + #define SELECT_PIN 4 // IDC 12 + #define MOTOR_PIN 5 // IDC 16 + #define DIR_PIN 6 // IDC 18 + #define STEP_PIN 7 // IDC 20 + #define WRDATA_PIN 8 // IDC 22 (not used during read) + #define WRGATE_PIN 9 // IDC 24 (not used during read) + #define TRK0_PIN 10 // IDC 26 + #define PROT_PIN 11 // IDC 28 + #define READ_PIN 12 // IDC 30 + #define SIDE_PIN 13 // IDC 32 + #define READY_PIN 14 // IDC 34 +#if F_CPU != 200000000L + #warning "please set CPU speed to 200MHz overclock" +#endif +#else +#error "Please set up pin definitions!" +#endif + +Adafruit_Floppy floppy(DENSITY_PIN, INDEX_PIN, SELECT_PIN, + MOTOR_PIN, DIR_PIN, STEP_PIN, + WRDATA_PIN, WRGATE_PIN, TRK0_PIN, + PROT_PIN, READ_PIN, SIDE_PIN, READY_PIN); + +// You can select IBMPC1440K or IBMPC360K (check adafruit_floppy_disk_t options!) +Adafruit_MFM_Floppy mfm_floppy(&floppy, IBMPC1440K); + + +constexpr size_t SECTOR_SIZE = 512UL; +int8_t last_track_read = -1; // last cached track + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040) + // Manual begin() is required on core without built-in support for TinyUSB such as + // - mbed rp2040 + TinyUSB_Device_Init(0); +#endif + + // Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively + usb_msc.setID("Adafruit", "Floppy Mass Storage", "1.0"); + + // Set disk size + usb_msc.setCapacity(mfm_floppy.sectors_per_track() * mfm_floppy.tracks_per_side() * FLOPPY_HEADS, SECTOR_SIZE); + + // Set callback + usb_msc.setReadWriteCallback(msc_read_callback, msc_write_callback, msc_flush_callback); + + floppy.debug_serial = &Serial; + floppy.begin(); + // Set Lun ready + usb_msc.setUnitReady(true); + Serial.println("Ready!"); + + usb_msc.begin(); + + if (! mfm_floppy.begin()) { + Serial.println("Failed to spin up motor & find index pulse"); + while (1) yield(); + } +} + +void loop() { + delay(1000); +} + +// Callback invoked when received READ10 command. +// Copy disk's data to buffer (up to bufsize) and +// return number of copied bytes (must be multiple of block size) +int32_t msc_read_callback (uint32_t lba, void* buffer, uint32_t bufsize) +{ + Serial.printf("read call back block %d size %d\n", lba, bufsize); + + uint8_t track = lba / (2 * mfm_floppy.sectors_per_track()); + uint8_t head = (lba / mfm_floppy.sectors_per_track()) % 2; + uint8_t subsector = lba % mfm_floppy.sectors_per_track(); + + uint8_t retries = 5; + + for (int retry=0; retry +sentence=Adafruit's floppy disk drive interfacing library +paragraph=Adafruit's floppy disk drive interfacing library +category=Communication +url=https://github.com/adafruit/Adafruit_Floppy +architectures=* +depends=Adafruit BusIO, SdFat - Adafruit Fork diff --git a/circuitpython/lib/adafruit_floppy/license.txt b/circuitpython/lib/adafruit_floppy/license.txt new file mode 100644 index 0000000..6fb2072 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/license.txt @@ -0,0 +1,10 @@ +Software License Agreement (MIT License) + +Copyright (c) 2021, Limor Fried for Adafruit Industries +All rights reserved. + +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. \ No newline at end of file diff --git a/circuitpython/lib/adafruit_floppy/mfm.license b/circuitpython/lib/adafruit_floppy/mfm.license new file mode 100644 index 0000000..c8f7560 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/mfm.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2022 Jeff Epler for Adafruit Industries + +SPDX-License-Identifier: MIT \ No newline at end of file diff --git a/circuitpython/lib/adafruit_floppy/src/Adafruit_Floppy.cpp b/circuitpython/lib/adafruit_floppy/src/Adafruit_Floppy.cpp new file mode 100644 index 0000000..eef1aa0 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/src/Adafruit_Floppy.cpp @@ -0,0 +1,524 @@ +#include "Adafruit_Floppy.h" + +#define DEBUG_FLOPPY (0) + +// We need to read and write some pins at optimized speeds - use raw registers +// or native SDK API! +#ifdef BUSIO_USE_FAST_PINIO +#define read_index() (*indexPort & indexMask) +#define read_data() (*dataPort & dataMask) +#define set_debug_led() (*ledPort |= ledMask) +#define clr_debug_led() (*ledPort &= ~ledMask) +#elif defined(ARDUINO_ARCH_RP2040) +#define read_index() gpio_get(_indexpin) +#define read_data() gpio_get(_rddatapin) +#define set_debug_led() gpio_put(led_pin, 1) +#define clr_debug_led() gpio_put(led_pin, 0) +#endif + +uint32_t T2_5 = T2_5_IBMPC_HD; +uint32_t T3_5 = T3_5_IBMPC_HD; + +#if !DEBUG_FLOPPY +#undef set_debug_led +#undef clr_debug_led +#define set_debug_led() ((void)0) +#define clr_debug_led() ((void)0) +#endif + +#define MFM_IO_MMIO (1) +#include "mfm_impl.h" + +/**************************************************************************/ +/*! + @brief Create a hardware interface to a floppy drive + @param densitypin A pin connected to the floppy Density Select input + @param indexpin A pin connected to the floppy Index Sensor output + @param selectpin A pin connected to the floppy Drive Select input + @param motorpin A pin connected to the floppy Motor Enable input + @param directionpin A pin connected to the floppy Stepper Direction input + @param steppin A pin connected to the floppy Stepper input + @param wrdatapin A pin connected to the floppy Write Data input + @param wrgatepin A pin connected to the floppy Write Gate input + @param track0pin A pin connected to the floppy Track 00 Sensor output + @param protectpin A pin connected to the floppy Write Protect Sensor output + @param rddatapin A pin connected to the floppy Read Data output + @param sidepin A pin connected to the floppy Side Select input + @param readypin A pin connected to the floppy Ready/Disk Change output + +*/ +/**************************************************************************/ + +Adafruit_Floppy::Adafruit_Floppy(int8_t densitypin, int8_t indexpin, + int8_t selectpin, int8_t motorpin, + int8_t directionpin, int8_t steppin, + int8_t wrdatapin, int8_t wrgatepin, + int8_t track0pin, int8_t protectpin, + int8_t rddatapin, int8_t sidepin, + int8_t readypin) { + _densitypin = densitypin; + _indexpin = indexpin; + _selectpin = selectpin; + _motorpin = motorpin; + _directionpin = directionpin; + _steppin = steppin; + _wrdatapin = wrdatapin; + _wrgatepin = wrgatepin; + _track0pin = track0pin; + _protectpin = protectpin; + _rddatapin = rddatapin; + _sidepin = sidepin; + _readypin = readypin; +} + +/**************************************************************************/ +/*! + @brief Initializes the GPIO pins but do not start the motor or anything +*/ +/**************************************************************************/ +void Adafruit_Floppy::begin(void) { soft_reset(); } + +/**************************************************************************/ +/*! + @brief Set back the object and pins to initial state +*/ +/**************************************************************************/ +void Adafruit_Floppy::soft_reset(void) { + // deselect drive + pinMode(_selectpin, OUTPUT); + digitalWrite(_selectpin, HIGH); + + // motor enable pin, drive low to turn on motor + pinMode(_motorpin, OUTPUT); + digitalWrite(_motorpin, HIGH); + + // set motor direction (low is in, high is out) + pinMode(_directionpin, OUTPUT); + digitalWrite(_directionpin, LOW); // move inwards to start + + // step track pin, pulse low for 3us min, 3ms max per pulse + pinMode(_steppin, OUTPUT); + digitalWrite(_steppin, HIGH); + + // side selector + pinMode(_sidepin, OUTPUT); + digitalWrite(_sidepin, HIGH); // side 0 to start + + pinMode(_indexpin, INPUT_PULLUP); + pinMode(_track0pin, INPUT_PULLUP); + pinMode(_protectpin, INPUT_PULLUP); + pinMode(_readypin, INPUT_PULLUP); + pinMode(_rddatapin, INPUT_PULLUP); + + // set high density + pinMode(_densitypin, OUTPUT); + digitalWrite(_densitypin, LOW); + + // set write OFF + if (_wrdatapin >= 0) { + pinMode(_wrdatapin, OUTPUT); + digitalWrite(_wrdatapin, HIGH); + } + if (_wrgatepin >= 0) { + pinMode(_wrgatepin, OUTPUT); + digitalWrite(_wrgatepin, HIGH); + } + +#ifdef BUSIO_USE_FAST_PINIO + indexPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(_indexpin)); + indexMask = digitalPinToBitMask(_indexpin); +#endif + + select_delay_us = 10; + step_delay_us = 10000; + settle_delay_ms = 15; + motor_delay_ms = 1000; + watchdog_delay_ms = 1000; + bus_type = BUSTYPE_IBMPC; + + if (led_pin >= 0) { + pinMode(led_pin, OUTPUT); + digitalWrite(led_pin, LOW); + } +} + +/**************************************************************************/ +/*! + @brief Whether to select this drive + @param selected True to select/enable +*/ +/**************************************************************************/ +void Adafruit_Floppy::select(bool selected) { + digitalWrite(_selectpin, !selected); // Selected logic level 0! + // Select drive + delayMicroseconds(select_delay_us); +} + +/**************************************************************************/ +/*! + @brief Which head/side to read from + @param head Head 0 or 1 +*/ +/**************************************************************************/ +void Adafruit_Floppy::side(uint8_t head) { + digitalWrite(_sidepin, !head); // Head 0 is logic level 1, head 1 is logic 0! +} + +/**************************************************************************/ +/*! + @brief Turn on or off the floppy motor, if on we wait till we get an index + pulse! + @param motor_on True to turn on motor, False to turn it off + @returns False if turning motor on and no index pulse found, true otherwise +*/ +/**************************************************************************/ +bool Adafruit_Floppy::spin_motor(bool motor_on) { + digitalWrite(_motorpin, !motor_on); // Motor on is logic level 0! + if (!motor_on) + return true; // we're done, easy! + + delay(motor_delay_ms); // Main motor turn on + + uint32_t index_stamp = millis(); + bool timedout = false; + + if (debug_serial) + debug_serial->print("Waiting for index pulse..."); + + while (digitalRead(_indexpin)) { + if ((millis() - index_stamp) > 10000) { + timedout = true; // its been 10 seconds? + break; + } + } + + if (timedout) { + if (debug_serial) + debug_serial->println("Didn't find an index pulse!"); + return false; + } + if (debug_serial) + debug_serial->println("Found!"); + return true; +} + +/**************************************************************************/ +/*! + @brief Seek to the desired track, requires the motor to be spun up! + @param track_num The track to step to + @return True If we were able to get to the track location +*/ +/**************************************************************************/ +bool Adafruit_Floppy::goto_track(uint8_t track_num) { + // track 0 is a very special case because its the only one we actually know we + // got to. if we dont know where we are, or we're going to track zero, step + // back till we get there. + if ((_track < 0) || track_num == 0) { + if (debug_serial) + debug_serial->println("Going to track 0"); + + // step back a lil more than expected just in case we really seeked out + uint8_t max_steps = 100; + while (max_steps--) { + if (!digitalRead(_track0pin)) { + _track = 0; + break; + } + step(STEP_OUT, 1); + } + + if (digitalRead(_track0pin)) { + // we never got a track 0 indicator :( + // what if we try stepping in a bit?? + + max_steps = 20; + while (max_steps--) { + if (!digitalRead(_track0pin)) { + _track = 0; + break; + } + step(STEP_IN, 1); + } + + if (digitalRead(_track0pin)) { + // STILL not found! + if (debug_serial) + debug_serial->println("Could not find track 0"); + return false; // we 'timed' out, were not able to locate track 0 + } + } + } + delay(settle_delay_ms); + + // ok its a non-track 0 step, first, we cant go past 79 ok? + track_num = min(track_num, FLOPPY_IBMPC_HD_TRACKS - 1); + if (debug_serial) + debug_serial->printf("Going to track %d\n\r", track_num); + + if (_track == track_num) { // we are there already + return true; + } + + int8_t steps = (int8_t)track_num - (int8_t)_track; + if (steps > 0) { + if (debug_serial) + debug_serial->printf("Step in %d times\n\r", steps); + step(STEP_IN, steps); + } else { + steps = abs(steps); + if (debug_serial) + debug_serial->printf("Step out %d times\n\r", steps); + step(STEP_OUT, steps); + } + delay(settle_delay_ms); + _track = track_num; + + return true; +} + +/**************************************************************************/ +/*! + @brief Step the track motor + @param dir STEP_OUT or STEP_IN depending on desired direction + @param times How many steps to take +*/ +/**************************************************************************/ +void Adafruit_Floppy::step(bool dir, uint8_t times) { + digitalWrite(_directionpin, dir); + delayMicroseconds(10); // 1 microsecond, but we're generous + + while (times--) { + digitalWrite(_steppin, HIGH); + delay((step_delay_us / 1000UL) + 1); // round up to at least 1ms + digitalWrite(_steppin, LOW); + delay((step_delay_us / 1000UL) + 1); + digitalWrite(_steppin, HIGH); // end high + yield(); + } + // one more for good measure (5.25" drives seemed to like this) + delay((step_delay_us / 1000UL) + 1); +} + +/**************************************************************************/ +/*! + @brief The current track location, based on internal caching + @return The cached track location +*/ +/**************************************************************************/ +int8_t Adafruit_Floppy::track(void) { return _track; } + +/**************************************************************************/ +/*! + @brief Capture and decode one track of MFM data + @param sectors A pointer to an array of memory we can use to store into, + 512*n_sectors bytes + @param n_sectors The number of sectors (e.g., 18 for a + standard 3.5", 1.44MB format) + @param sector_validity An array of values set to 1 if the sector was + captured, 0 if not captured (no IDAM, CRC error, etc) + @return Number of sectors we actually captured +*/ +/**************************************************************************/ +uint32_t Adafruit_Floppy::read_track_mfm(uint8_t *sectors, size_t n_sectors, + uint8_t *sector_validity) { + mfm_io_t io; +#ifdef BUSIO_USE_FAST_PINIO + BusIO_PortReg *dataPort, *ledPort; + BusIO_PortMask dataMask, ledMask; + dataPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(_rddatapin)); + dataMask = digitalPinToBitMask(_rddatapin); + ledPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(led_pin)); + ledMask = digitalPinToBitMask(led_pin); + (void)ledPort; + (void)ledMask; + io.index_port = indexPort; + io.index_mask = indexMask; + io.data_port = dataPort; + io.data_mask = dataMask; +#elif defined(ARDUINO_ARCH_RP2040) + io.index_port = &sio_hw->gpio_in; + io.index_mask = 1u << _indexpin; + io.data_port = &sio_hw->gpio_in; + io.data_mask = 1u << _rddatapin; +#endif + + noInterrupts(); + int result = read_track(io, n_sectors, sectors, sector_validity); + interrupts(); + + return result; +} + +/**************************************************************************/ +/*! + @brief Capture one track's worth of flux transitions, between two falling + index pulses + @param pulses A pointer to an array of memory we can use to store into + @param max_pulses The size of the allocated pulses array + @return Number of pulses we actually captured +*/ +/**************************************************************************/ +uint32_t Adafruit_Floppy::capture_track(uint8_t *pulses, uint32_t max_pulses) { + unsigned pulse_count; + uint8_t *pulses_ptr = pulses; + uint8_t *pulses_end = pulses + max_pulses; + +#ifdef BUSIO_USE_FAST_PINIO + BusIO_PortReg *dataPort, *ledPort; + BusIO_PortMask dataMask, ledMask; + dataPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(_rddatapin)); + dataMask = digitalPinToBitMask(_rddatapin); + ledPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(led_pin)); + ledMask = digitalPinToBitMask(led_pin); + (void)ledPort; + (void)ledMask; +#endif + + memset(pulses, 0, max_pulses); // zero zem out + + noInterrupts(); + wait_for_index_pulse_low(); + + // wait for one clean flux pulse so we dont get cut off. + // don't worry about losing this pulse, we'll get it on our + // overlap run! + + // ok we have a h-to-l transition so... + bool last_index_state = read_index(); + uint8_t index_transitions = 0; + + // if data line is low, wait till it rises + if (!read_data()) { + while (!read_data()) + ; + } + // if data line is high, wait till it drops down + if (read_data()) { + while (read_data()) + ; + } + + while (true) { + bool index_state = read_index(); + // ahh a L to H transition + if (!last_index_state && index_state) { + index_transitions++; + if (index_transitions == + 2) // and its the second one, so we're done with this track! + break; + } + last_index_state = index_state; + + // muahaha, now we can read track data! + // Don't start counting at zero because we lost some time checking for + // index. Empirically, at 180MHz and -O3 on M4, this gives the most 'even' + // timings, moving the bins from 41/63/83 to 44/66/89 + pulse_count = 3; + + // while pulse is in the low pulse, count up + while (!read_data()) { + pulse_count++; + } + set_debug_led(); + + // while pulse is high, keep counting up + while (read_data()) + pulse_count++; + clr_debug_led(); + + pulses_ptr[0] = min(255u, pulse_count); + pulses_ptr++; + if (pulses_ptr == pulses_end) { + break; + } + } + // whew done + interrupts(); + return pulses_ptr - pulses; +} + +/**************************************************************************/ +/*! + @brief Busy wait until the index line goes from high to low +*/ +/**************************************************************************/ +void Adafruit_Floppy::wait_for_index_pulse_low(void) { + // initial state + bool index_state = read_index(); + bool last_index_state = index_state; + + // wait until last index state is H and current state is L + while (true) { + index_state = read_index(); + if (last_index_state && !index_state) { + return; + } + last_index_state = index_state; + } +} + +/**************************************************************************/ +/*! + @brief Pretty print the counts in a list of flux transitions + @param pulses A pointer to an array of memory containing pulse counts + @param num_pulses The size of the pulses in the array +*/ +/**************************************************************************/ +void Adafruit_Floppy::print_pulses(uint8_t *pulses, uint32_t num_pulses) { + if (!debug_serial) + return; + + for (uint32_t i = 0; i < num_pulses; i++) { + debug_serial->print(pulses[i]); + debug_serial->print(", "); + } + debug_serial->println(); +} +/**************************************************************************/ +/*! + @brief Pretty print a simple histogram of flux transitions + @param pulses A pointer to an array of memory containing pulse counts + @param num_pulses The size of the pulses in the array + @param max_bins The maximum number of histogram bins to use (default 64) +*/ +/**************************************************************************/ +void Adafruit_Floppy::print_pulse_bins(uint8_t *pulses, uint32_t num_pulses, + uint8_t max_bins) { + if (!debug_serial) + return; + + // lets bin em! + uint32_t bins[max_bins][2]; + memset(bins, 0, max_bins * 2 * sizeof(uint32_t)); + // we'll add each pulse to a bin so we can figure out the 3 buckets + for (uint32_t i = 0; i < num_pulses; i++) { + uint8_t p = pulses[i]; + // find a bin for this pulse + uint8_t bin = 0; + for (bin = 0; bin < max_bins; bin++) { + // bin already exists? increment the count! + if (bins[bin][0] == p) { + bins[bin][1]++; + break; + } + if (bins[bin][0] == 0) { + // ok we never found the bin, so lets make it this one! + bins[bin][0] = p; + bins[bin][1] = 1; + break; + } + } + if (bin == max_bins) + debug_serial->println("oof we ran out of bins but we'll keep going"); + } + // this is a very lazy way to print the bins sorted + for (uint8_t pulse_w = 1; pulse_w < 255; pulse_w++) { + for (uint8_t b = 0; b < max_bins; b++) { + if (bins[b][0] == pulse_w) { + debug_serial->print(bins[b][0]); + debug_serial->print(": "); + debug_serial->println(bins[b][1]); + } + } + } +} diff --git a/circuitpython/lib/adafruit_floppy/src/Adafruit_Floppy.h b/circuitpython/lib/adafruit_floppy/src/Adafruit_Floppy.h new file mode 100644 index 0000000..3e519eb --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/src/Adafruit_Floppy.h @@ -0,0 +1,150 @@ +#ifndef ADAFRUIT_FLOPPY_H +#define ADAFRUIT_FLOPPY_H + +#include "Arduino.h" +#include +// to implement SdFat Block Driver +#include "SdFat.h" +#include "SdFatConfig.h" + +#define FLOPPY_IBMPC_HD_TRACKS 80 +#define FLOPPY_IBMPC_DD_TRACKS 40 +#define FLOPPY_HEADS 2 + +#define MFM_IBMPC1440K_SECTORS_PER_TRACK 18 +#define MFM_IBMPC360K_SECTORS_PER_TRACK 9 +#define MFM_BYTES_PER_SECTOR 512UL + +#ifdef BUSIO_USE_FAST_PINIO +#define FLOPPYIO_SAMPLERATE (F_CPU * 11u / 90u) // empirical on SAM D51 @ 120MHz +#endif + +#if defined(ARDUINO_ARCH_RP2040) +#undef FLOPPYIO_SAMPLERATE +#define FLOPPYIO_SAMPLERATE (F_CPU * 13u / 100u) // empirical on RP2040 @ 200MHz +#endif + +#define T2_5_IBMPC_HD (FLOPPYIO_SAMPLERATE * 5 / 2 / 1000000) +#define T3_5_IBMPC_HD (FLOPPYIO_SAMPLERATE * 7 / 2 / 1000000) +#define T2_5_IBMPC_DD (T2_5_IBMPC_HD * 2) +#define T3_5_IBMPC_DD (T3_5_IBMPC_HD * 2) + +#define STEP_OUT HIGH +#define STEP_IN LOW +#define MAX_FLUX_PULSE_PER_TRACK \ + (uint32_t)(500000UL / 5 * \ + 1.5) // 500khz / 5 hz per track rotation, 1.5 rotations + +#define BUSTYPE_IBMPC 1 +#define BUSTYPE_SHUGART 2 + +typedef enum { + IBMPC1440K, + IBMPC360K, +} adafruit_floppy_disk_t; + +/**************************************************************************/ +/*! + @brief A helper class for chattin with floppy drives +*/ +/**************************************************************************/ +class Adafruit_Floppy { +public: + Adafruit_Floppy(int8_t densitypin, int8_t indexpin, int8_t selectpin, + int8_t motorpin, int8_t directionpin, int8_t steppin, + int8_t wrdatapin, int8_t wrgatepin, int8_t track0pin, + int8_t protectpin, int8_t rddatapin, int8_t sidepin, + int8_t readypin); + void begin(void); + void soft_reset(void); + + void select(bool selected); + bool spin_motor(bool motor_on); + bool goto_track(uint8_t track); + void side(uint8_t head); + int8_t track(void); + void step(bool dir, uint8_t times); + + uint32_t read_track_mfm(uint8_t *sectors, size_t n_sectors, + uint8_t *sector_validity); + uint32_t capture_track(uint8_t *pulses, uint32_t max_pulses) + __attribute__((optimize("O3"))); + void print_pulse_bins(uint8_t *pulses, uint32_t num_pulses, + uint8_t max_bins = 64); + void print_pulses(uint8_t *pulses, uint32_t num_pulses); + + int8_t led_pin = LED_BUILTIN; ///< Debug LED output for tracing + + uint16_t select_delay_us = 10; ///< delay after drive select (usecs) + uint16_t step_delay_us = 10000; ///< delay between head steps (usecs) + uint16_t settle_delay_ms = 15; ///< settle delay after seek (msecs) + uint16_t motor_delay_ms = 1000; ///< delay after motor on (msecs) + uint16_t watchdog_delay_ms = + 1000; ///< quiescent time until drives reset (msecs) + uint8_t bus_type = BUSTYPE_IBMPC; ///< what kind of floppy drive we're using + + Stream *debug_serial = NULL; ///< optional debug stream for serial output + +private: + void wait_for_index_pulse_low(void); + + // theres a lot of GPIO! + int8_t _densitypin, _indexpin, _selectpin, _motorpin, _directionpin, _steppin, + _wrdatapin, _wrgatepin, _track0pin, _protectpin, _rddatapin, _sidepin, + _readypin; + + int8_t _track = -1; + +#ifdef BUSIO_USE_FAST_PINIO + BusIO_PortReg *indexPort; + BusIO_PortMask indexMask; +#endif +}; + +/**************************************************************************/ +/*! + This class adds support for the BaseBlockDriver interface to an MFM + encoded floppy disk. This allows it to be used with SdFat's FatFileSystem + class. or for a mass storage device +*/ +/**************************************************************************/ +class Adafruit_MFM_Floppy : public BaseBlockDriver { +public: + Adafruit_MFM_Floppy(Adafruit_Floppy *floppy, + adafruit_floppy_disk_t format = IBMPC1440K); + + bool begin(void); + bool end(void); + + uint32_t size(void); + int32_t readTrack(uint8_t track, bool head); + + /**! @brief The expected number of sectors per track in this format + @returns The number of sectors per track */ + uint8_t sectors_per_track(void) { return _sectors_per_track; } + /**! @brief The expected number of tracks per side in this format + @returns The number of tracks per side */ + uint8_t tracks_per_side(void) { return _tracks_per_side; } + + //------------- SdFat BaseBlockDRiver API -------------// + virtual bool readBlock(uint32_t block, uint8_t *dst); + virtual bool writeBlock(uint32_t block, const uint8_t *src); + virtual bool syncBlocks(); + virtual bool readBlocks(uint32_t block, uint8_t *dst, size_t nb); + virtual bool writeBlocks(uint32_t block, const uint8_t *src, size_t nb); + + /**! The raw byte decoded data from the last track read */ + uint8_t track_data[MFM_IBMPC1440K_SECTORS_PER_TRACK * MFM_BYTES_PER_SECTOR]; + + /**! Which tracks from the last track-read were valid MFM/CRC! */ + uint8_t track_validity[MFM_IBMPC1440K_SECTORS_PER_TRACK]; + +private: + uint8_t _sectors_per_track = 0; + uint8_t _tracks_per_side = 0; + int8_t _last_track_read = -1; // last cached track + Adafruit_Floppy *_floppy = NULL; + adafruit_floppy_disk_t _format = IBMPC1440K; +}; + +#endif diff --git a/circuitpython/lib/adafruit_floppy/src/Adafruit_MFM_Floppy.cpp b/circuitpython/lib/adafruit_floppy/src/Adafruit_MFM_Floppy.cpp new file mode 100644 index 0000000..6128a20 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/src/Adafruit_MFM_Floppy.cpp @@ -0,0 +1,206 @@ +#include + +extern uint32_t T2_5, T3_5; + +/**************************************************************************/ +/*! + @brief Instantiate an MFM-formatted floppy + @param floppy An Adafruit_Floppy object that has the pins defined + @param format What kind of format we will be parsing out - we DO NOT + autodetect! +*/ +/**************************************************************************/ +Adafruit_MFM_Floppy::Adafruit_MFM_Floppy(Adafruit_Floppy *floppy, + adafruit_floppy_disk_t format) { + _floppy = floppy; + _format = format; + + // different formats have different 'hardcoded' sectors and tracks + if (_format == IBMPC1440K) { + _sectors_per_track = MFM_IBMPC1440K_SECTORS_PER_TRACK; + _tracks_per_side = FLOPPY_IBMPC_HD_TRACKS; + T2_5 = T2_5_IBMPC_HD; + T3_5 = T3_5_IBMPC_HD; + } else if (_format == IBMPC360K) { + _sectors_per_track = MFM_IBMPC360K_SECTORS_PER_TRACK; + _tracks_per_side = FLOPPY_IBMPC_DD_TRACKS; + T2_5 = T2_5_IBMPC_DD; + T3_5 = T3_5_IBMPC_DD; + } +} + +/**************************************************************************/ +/*! + @brief Initialize and spin up the floppy drive + @returns True if we were able to spin up and detect an index track +*/ +/**************************************************************************/ +bool Adafruit_MFM_Floppy::begin(void) { + if (!_floppy) + return false; + _floppy->begin(); + + // now's the time to tweak settings + if (_format == IBMPC360K) { + _floppy->step_delay_us = 65000UL; // lets make it max 65ms not 10ms? + _floppy->settle_delay_ms = 50; // 50ms not 15 + } + + _floppy->select(true); + + return _floppy->spin_motor(true); +} + +/**************************************************************************/ +/*! + @brief Spin down and deselect the motor and drive + @returns True always +*/ +/**************************************************************************/ +bool Adafruit_MFM_Floppy::end(void) { + _floppy->spin_motor(false); + _floppy->select(false); + return true; +} + +/**************************************************************************/ +/*! + @brief Quick calculator for expected max capacity + @returns Size of the drive in bytes +*/ +/**************************************************************************/ +uint32_t Adafruit_MFM_Floppy::size(void) { + return (uint32_t)_tracks_per_side * FLOPPY_HEADS * _sectors_per_track * + MFM_BYTES_PER_SECTOR; +} + +/**************************************************************************/ +/*! + @brief Read one track's worth of data and MFM decode it + @param track track number, 0 to whatever is the max tracks for the given + @param head which side to read, false for side 1, true for side 2 + format during instantiation (e.g. 40 for DD, 80 for HD) + @returns Number of sectors captured, or -1 if we couldn't seek +*/ +/**************************************************************************/ +int32_t Adafruit_MFM_Floppy::readTrack(uint8_t track, bool head) { + + // Serial.printf("\tSeeking track %d head %d...", track, head); + if (!_floppy->goto_track(track)) { + // Serial.println("failed to seek to track"); + return -1; + } + _floppy->side(head); + // Serial.println("done!"); + uint32_t captured_sectors = + _floppy->read_track_mfm(track_data, _sectors_per_track, track_validity); + /* + Serial.print("Captured %d sectors", captured_sectors); + + Serial.print("Validity: "); + for(size_t i=0; i +#include +#include +#include + +#pragma GCC push_options +#pragma GCC optimize("-O3") +typedef struct mfm_io mfm_io_t; + +#ifndef MFM_IO_MMIO +#define MFM_IO_MMIO (0) +#endif + +// If you have a memory mapped peripheral, define MFM_IO_MMIO to get an +// implementation of the mfm_io functions. then, just populate the fields with +// the actual registers to use and define T2_5 and T3_5 to the empirical values +// dividing between T2/3 and T3/4 pulses. +#if MFM_IO_MMIO +struct mfm_io { + const volatile uint32_t *index_port; + uint32_t index_mask; + const volatile uint32_t *data_port; + uint32_t data_mask; + unsigned index_state; + unsigned index_count; +}; +#endif + +typedef enum { pulse_10, pulse_100, pulse_1000 } mfm_io_symbol_t; + +typedef enum { odd = 0, even = 1 } mfm_state_t; + +enum { IDAM = 0xfe, DAM = 0xfb }; + +enum { blocksize = 512, overhead = 3, metadata_size = 7 }; +__attribute__((always_inline)) static inline mfm_io_symbol_t +mfm_io_read_symbol(mfm_io_t *io); +static void mfm_io_reset_sync_count(mfm_io_t *io); +__attribute__((always_inline)) static int mfm_io_get_sync_count(mfm_io_t *io); + +// Automatically generated CRC function +// polynomial: 0x11021 +static uint16_t crc16(uint8_t *data, int len, uint16_t crc) { + static const uint16_t table[256] = { + 0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50A5U, 0x60C6U, 0x70E7U, + 0x8108U, 0x9129U, 0xA14AU, 0xB16BU, 0xC18CU, 0xD1ADU, 0xE1CEU, 0xF1EFU, + 0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52B5U, 0x4294U, 0x72F7U, 0x62D6U, + 0x9339U, 0x8318U, 0xB37BU, 0xA35AU, 0xD3BDU, 0xC39CU, 0xF3FFU, 0xE3DEU, + 0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64E6U, 0x74C7U, 0x44A4U, 0x5485U, + 0xA56AU, 0xB54BU, 0x8528U, 0x9509U, 0xE5EEU, 0xF5CFU, 0xC5ACU, 0xD58DU, + 0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76D7U, 0x66F6U, 0x5695U, 0x46B4U, + 0xB75BU, 0xA77AU, 0x9719U, 0x8738U, 0xF7DFU, 0xE7FEU, 0xD79DU, 0xC7BCU, + 0x48C4U, 0x58E5U, 0x6886U, 0x78A7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U, + 0xC9CCU, 0xD9EDU, 0xE98EU, 0xF9AFU, 0x8948U, 0x9969U, 0xA90AU, 0xB92BU, + 0x5AF5U, 0x4AD4U, 0x7AB7U, 0x6A96U, 0x1A71U, 0x0A50U, 0x3A33U, 0x2A12U, + 0xDBFDU, 0xCBDCU, 0xFBBFU, 0xEB9EU, 0x9B79U, 0x8B58U, 0xBB3BU, 0xAB1AU, + 0x6CA6U, 0x7C87U, 0x4CE4U, 0x5CC5U, 0x2C22U, 0x3C03U, 0x0C60U, 0x1C41U, + 0xEDAEU, 0xFD8FU, 0xCDECU, 0xDDCDU, 0xAD2AU, 0xBD0BU, 0x8D68U, 0x9D49U, + 0x7E97U, 0x6EB6U, 0x5ED5U, 0x4EF4U, 0x3E13U, 0x2E32U, 0x1E51U, 0x0E70U, + 0xFF9FU, 0xEFBEU, 0xDFDDU, 0xCFFCU, 0xBF1BU, 0xAF3AU, 0x9F59U, 0x8F78U, + 0x9188U, 0x81A9U, 0xB1CAU, 0xA1EBU, 0xD10CU, 0xC12DU, 0xF14EU, 0xE16FU, + 0x1080U, 0x00A1U, 0x30C2U, 0x20E3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U, + 0x83B9U, 0x9398U, 0xA3FBU, 0xB3DAU, 0xC33DU, 0xD31CU, 0xE37FU, 0xF35EU, + 0x02B1U, 0x1290U, 0x22F3U, 0x32D2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U, + 0xB5EAU, 0xA5CBU, 0x95A8U, 0x8589U, 0xF56EU, 0xE54FU, 0xD52CU, 0xC50DU, + 0x34E2U, 0x24C3U, 0x14A0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U, + 0xA7DBU, 0xB7FAU, 0x8799U, 0x97B8U, 0xE75FU, 0xF77EU, 0xC71DU, 0xD73CU, + 0x26D3U, 0x36F2U, 0x0691U, 0x16B0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U, + 0xD94CU, 0xC96DU, 0xF90EU, 0xE92FU, 0x99C8U, 0x89E9U, 0xB98AU, 0xA9ABU, + 0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18C0U, 0x08E1U, 0x3882U, 0x28A3U, + 0xCB7DU, 0xDB5CU, 0xEB3FU, 0xFB1EU, 0x8BF9U, 0x9BD8U, 0xABBBU, 0xBB9AU, + 0x4A75U, 0x5A54U, 0x6A37U, 0x7A16U, 0x0AF1U, 0x1AD0U, 0x2AB3U, 0x3A92U, + 0xFD2EU, 0xED0FU, 0xDD6CU, 0xCD4DU, 0xBDAAU, 0xAD8BU, 0x9DE8U, 0x8DC9U, + 0x7C26U, 0x6C07U, 0x5C64U, 0x4C45U, 0x3CA2U, 0x2C83U, 0x1CE0U, 0x0CC1U, + 0xEF1FU, 0xFF3EU, 0xCF5DU, 0xDF7CU, 0xAF9BU, 0xBFBAU, 0x8FD9U, 0x9FF8U, + 0x6E17U, 0x7E36U, 0x4E55U, 0x5E74U, 0x2E93U, 0x3EB2U, 0x0ED1U, 0x1EF0U, + }; + + while (len > 0) { + crc = table[*data ^ (uint8_t)(crc >> 8)] ^ (crc << 8); + data++; + len--; + } + return crc; +} + +enum { triple_mark_magic = 0x09926499, triple_mark_mask = 0x0fffffff }; + +__attribute__((always_inline)) inline static bool +wait_triple_sync_mark(mfm_io_t *io) { + uint32_t state = 0; + while (mfm_io_get_sync_count(io) < 3 && state != triple_mark_magic) { + state = ((state << 2) | mfm_io_read_symbol(io)) & triple_mark_mask; + } + return state == triple_mark_magic; +} + +// Compute the MFM CRC of the data, _assuming it was preceded by three 0xa1 sync +// bytes +static int crc16_preloaded(unsigned char *buf, size_t n) { + return crc16((uint8_t *)buf, n, 0xcdb4); +} + +// Copy 'n' bytes of data into 'buf' +__attribute__((always_inline)) inline static void +receive(mfm_io_t *io, unsigned char *buf, size_t n) { + // `tmp` holds up to 9 bits of data, in bits 6..15. + unsigned tmp = 0, weight = 0x8000; + +#define PUT_BIT(x) \ + do { \ + if (x) \ + tmp |= weight; \ + weight >>= 1; \ + } while (0) + + // In MFM, flux marks can be 2, 3, or 4 "T" apart. These three signals + // stand for the bit sequences 10, 100, and 1000. However, half of the + // bits are data bits, and half are 'clock' bits. We have to keep track of + // whether [in the next symbol] we want the "even" bit(s) or the "odd" bit(s): + // + // 10 - leaves even/odd (parity) unchanged + // 100 - inverts even/odd (parity) + // 1000 - leaves even/odd (parity) unchanged + // ^ ^ data bits if state is even + // ^ ^ data bits if state is odd + + // We do this by knowing that when we arrive, we are waiting to parse the + // final '1' data bit of the MFM sync mark. This means we apply a special rule + // to the first word, starting as though in the 'even' state but not recording + // the '1' bit. + mfm_io_symbol_t s = mfm_io_read_symbol(io); + mfm_state_t state = even; + switch (s) { + case pulse_100: // first data bit is a 0, and we start in the ODD state + state = odd; + /* fallthrough */ + case pulse_1000: // first data bit is a 0, and we start in EVEN state + PUT_BIT(0); + break; + default: + break; + } + + while (n) { + s = mfm_io_read_symbol(io); + PUT_BIT(state); // 'even' is 1, so record a '1' or '0' as appropriate + if (s == pulse_1000) { + PUT_BIT(0); // the other bit recorded for a 1000 is always a '0' + } + if (s == pulse_100) { + if (state) { + PUT_BIT(0); + } // If 'even', record an additional '0' + state = (mfm_state_t)!state; // the next symbol has opposite parity + } + + *buf = tmp >> 8; // store every time to make timing more even + if (weight <= 0x80) { + tmp <<= 8; + weight <<= 8; + buf++; + n--; + } + } +} + +// Perform all the steps of receiving the next IDAM, DAM (or DDAM, but we don't +// use them) +__attribute__((always_inline)) inline static bool +wait_triple_sync_mark_receive_crc(mfm_io_t *io, void *buf, size_t n) { + if (!wait_triple_sync_mark(io)) { + return false; + } + receive(io, (uint8_t *)buf, n); + unsigned crc = crc16_preloaded((uint8_t *)buf, n); + return crc == 0; +} + +// Read a whole track, setting validity[] for each sector actually read, up to +// n_sectors indexing of validity & data is 0-based, even though IDAMs store +// sectors as 1-based +static int read_track(mfm_io_t io, int n_sectors, void *data, + uint8_t *validity) { + memset(validity, 0, n_sectors); + + int n_valid = 0; + + mfm_io_reset_sync_count(&io); + + unsigned char buf[512 + 3]; + while (mfm_io_get_sync_count(&io) < 3 && n_valid < n_sectors) { + if (!wait_triple_sync_mark_receive_crc(&io, buf, metadata_size)) { + continue; + } + if (buf[0] != IDAM) { + continue; + } + + int r = (uint8_t)buf[3] - 1; + if (r >= n_sectors) { + continue; + } + + if (validity[r]) { + continue; + } + + if (!wait_triple_sync_mark_receive_crc(&io, buf, sizeof(buf))) { + continue; + } + if (buf[0] != DAM) { + continue; + } + + memcpy((char *)data + blocksize * r, buf + 1, blocksize); + validity[r] = 1; + n_valid++; + } + return n_valid; +} + +#if MFM_IO_MMIO +#define READ_DATA() (!!(*io->data_port & io->data_mask)) +#define READ_INDEX() (!!(*io->index_port & io->index_mask)) +__attribute__((optimize("O3"), always_inline)) static inline mfm_io_symbol_t +mfm_io_read_symbol(mfm_io_t *io) { + unsigned pulse_count = 3; + while (!READ_DATA()) { + pulse_count++; + } + + unsigned index_state = (io->index_state << 1) | READ_INDEX(); + if ((index_state & 3) == 2) { // a zero-to-one transition + io->index_count++; + } + io->index_state = index_state; + + while (READ_DATA()) { + pulse_count++; + } + + int result = pulse_10; + if (pulse_count > T2_5) { + result++; + } + if (pulse_count > T3_5) { + result++; + } + + return (mfm_io_symbol_t)result; +} + +static void mfm_io_reset_sync_count(mfm_io_t *io) { io->index_count = 0; } + +__attribute__((optimize("O3"), always_inline)) inline static int +mfm_io_get_sync_count(mfm_io_t *io) { + return io->index_count; +} +#endif + +#pragma GCC pop_options diff --git a/circuitpython/lib/adafruit_floppy/standalone/main.c b/circuitpython/lib/adafruit_floppy/standalone/main.c new file mode 100644 index 0000000..fee8142 --- /dev/null +++ b/circuitpython/lib/adafruit_floppy/standalone/main.c @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: 2022 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +struct mfm_io {}; + +#include "mfm_impl.h" + +void hexdump(void *buf_in, size_t n) { + unsigned char *buf = buf_in; + size_t i = 0; + for (; i < n; i++) { + if (i % 16 == 0) { + printf("%04zx ", i); + } + printf("%02x%c", buf[i], (i % 16 == 15) ? '\n' : ' '); + } + if (i % 16 != 0) { + putchar('\n'); + } +} + +static inline mfm_io_symbol_t mfm_io_read_symbol(mfm_io_t *io) { + int c = getchar(); + return (mfm_io_symbol_t)(c - '0'); +} + +static void mfm_io_reset_sync_count(mfm_io_t *io) {} + +static inline int mfm_io_get_sync_count(mfm_io_t *io) { + return feof(stdin) ? 2 : 0; +} + +int main() { + enum { n_sectors = 18 }; + char data[n_sectors * blocksize]; + uint8_t validity[n_sectors]; + struct mfm_io io; + read_track(io, n_sectors, data, validity); + for (int i = 0; i < n_sectors; i++) { + printf("validity[% 2d] = %d\n", i, validity[i]); + if (validity[i]) { + hexdump(data + i * blocksize, blocksize); + printf("\n"); + } + } +} diff --git a/circuitpython/lib/axtls/Makefile b/circuitpython/lib/axtls/Makefile new file mode 100644 index 0000000..045e34f --- /dev/null +++ b/circuitpython/lib/axtls/Makefile @@ -0,0 +1,185 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 config/.config + +ifneq ($(strip $(HAVE_DOT_CONFIG)),y) +all: menuconfig +else +all: target +endif + +include config/makefile.conf + +target : $(STAGE) $(TARGET) + +# VERSION has to come from the command line +RELEASE=axTLS-$(VERSION) + +# standard version +target: + $(MAKE) -C crypto + $(MAKE) -C ssl +ifdef CONFIG_AXHTTPD + $(MAKE) -C httpd +endif +ifdef CONFIG_AXTLSWRAP + $(MAKE) -C axtlswrap +endif +ifdef CONFIG_BINDINGS + $(MAKE) -C bindings +endif +ifdef CONFIG_SAMPLES + $(MAKE) -C samples +endif + +$(STAGE) : ssl/version.h + @mkdir -p $(STAGE) + +# create a version file with something in it. +ssl/version.h: + @echo "#define AXTLS_VERSION \"(no version)\"" > ssl/version.h + +$(PREFIX) : + @mkdir -p $(PREFIX)/lib + @mkdir -p $(PREFIX)/bin + +release: + $(MAKE) -C config/scripts/config clean + -$(MAKE) clean + -@rm config/*.msi config/*.back.aip config/config.h config/.config* + -@rm www/index.20* + -@rm -fr $(STAGE) + @echo "#define AXTLS_VERSION \"$(VERSION)\"" > ssl/version.h + cd ../; tar cvfz $(RELEASE).tar.gz --wildcards-match-slash --exclude .svn axtls-code; cd -; + +docs: + $(MAKE) -C docsrc doco + +# build the Win32 demo release version +win32_demo: + @echo "#define AXTLS_VERSION \"$(VERSION)\"" > ssl/version.h + $(MAKE) win32releaseconf + +install: $(PREFIX) all + cp --no-dereference $(STAGE)/libax* $(PREFIX)/lib + chmod 755 $(PREFIX)/lib/libax* +ifdef CONFIG_SAMPLES + install -m 755 $(STAGE)/ax* $(PREFIX)/bin +endif +ifdef CONFIG_HTTP_HAS_AUTHORIZATION + install -m 755 $(STAGE)/htpasswd $(PREFIX)/bin +endif +ifdef CONFIG_PLATFORM_CYGWIN + install -m 755 $(STAGE)/cygaxtls.dll $(PREFIX)/bin +endif +ifdef CONFIG_PERL_BINDINGS + install -m 755 $(STAGE)/axtlsp.pm `perl -e 'use Config; print $$Config{installarchlib};'` +endif + @mkdir -p -m 755 $(PREFIX)/include/axTLS + install -m 644 crypto/*.h $(PREFIX)/include/axTLS + install -m 644 ssl/*.h $(PREFIX)/include/axTLS + -rm $(PREFIX)/include/axTLS/cert.h + -rm $(PREFIX)/include/axTLS/private_key.h + install -m 644 config/config.h $(PREFIX)/include/axTLS + +installclean: + -@rm $(PREFIX)/lib/libax* > /dev/null 2>&1 + -@rm $(PREFIX)/bin/ax* > /dev/null 2>&1 + -@rm $(PREFIX)/bin/axhttpd* > /dev/null 2>&1 + -@rm `perl -e 'use Config; print $$Config{installarchlib};'`/axtlsp.pm > /dev/null 2>&1 + +test: + cd $(STAGE); ssltest; ../ssl/test/test_axssl.sh; cd -; + +# tidy up things +clean:: + @cd crypto; $(MAKE) clean + @cd ssl; $(MAKE) clean + @cd httpd; $(MAKE) clean + @cd axtlswrap; $(MAKE) clean + @cd samples; $(MAKE) clean + @cd docsrc; $(MAKE) clean + @cd bindings; $(MAKE) clean + +# --------------------------------------------------------------------------- +# mconf stuff +# --------------------------------------------------------------------------- + +CONFIG_CONFIG_IN = config/Config.in +CONFIG_DEFCONFIG = config/defconfig + +config/scripts/config/conf: config/scripts/config/Makefile + $(MAKE) -C config/scripts/config conf + -@if [ ! -f config/.config ] ; then \ + cp $(CONFIG_DEFCONFIG) config/.config; \ + fi + +config/scripts/config/mconf: config/scripts/config/Makefile + $(MAKE) -C config/scripts/config ncurses conf mconf + -@if [ ! -f config/.config ] ; then \ + cp $(CONFIG_DEFCONFIG) .config; \ + fi + +cleanconf: + $(MAKE) -C config/scripts/config clean + @rm -f config/.config + +menuconfig: config/scripts/config/mconf + @./config/scripts/config/mconf $(CONFIG_CONFIG_IN) + +config: config/scripts/config/conf + @./config/scripts/config/conf $(CONFIG_CONFIG_IN) + +oldconfig: config/scripts/config/conf + @./config/scripts/config/conf -o $(CONFIG_CONFIG_IN) + +default: config/scripts/config/conf + @./config/scripts/config/conf -d $(CONFIG_CONFIG_IN) > /dev/null + $(MAKE) + +randconfig: config/scripts/config/conf + @./config/scripts/config/conf -r $(CONFIG_CONFIG_IN) + +allnoconfig: config/scripts/config/conf + @./config/scripts/config/conf -n $(CONFIG_CONFIG_IN) + +allyesconfig: config/scripts/config/conf + @./config/scripts/config/conf -y $(CONFIG_CONFIG_IN) + +# The special win32 release configuration +win32releaseconf: config/scripts/config/conf + @./config/scripts/config/conf -D config/win32config $(CONFIG_CONFIG_IN) > /dev/null + $(MAKE) + +# The special linux release configuration +linuxconf: config/scripts/config/conf + @./config/scripts/config/conf -D config/linuxconfig $(CONFIG_CONFIG_IN) > /dev/null + $(MAKE) diff --git a/circuitpython/lib/axtls/README b/circuitpython/lib/axtls/README new file mode 100644 index 0000000..c8926d9 --- /dev/null +++ b/circuitpython/lib/axtls/README @@ -0,0 +1,3 @@ + +See www/index.html for the README, CHANGELOG, LICENSE and other notes. + diff --git a/circuitpython/lib/axtls/axtlswrap/Makefile b/circuitpython/lib/axtls/axtlswrap/Makefile new file mode 100755 index 0000000..b14825a --- /dev/null +++ b/circuitpython/lib/axtls/axtlswrap/Makefile @@ -0,0 +1,68 @@ +# +# Copyright (c) 2009, Cameron Rich +# +# 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 axTLS project 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. +# + +all : sslwrap + +AXTLS_HOME=.. + +include $(AXTLS_HOME)/config/.config +include $(AXTLS_HOME)/config/makefile.conf + +ifdef CONFIG_PLATFORM_CYGWIN +TARGET=$(AXTLS_HOME)/$(STAGE)/axtlswrap.exe +else # linux +TARGET=$(AXTLS_HOME)/$(STAGE)/axtlswrap +endif + +ifdef CONFIG_HTTP_STATIC_BUILD +LIBS=$(AXTLS_HOME)/$(STAGE)/libaxtls.a +else +LIBS=-L$(AXTLS_HOME)/$(STAGE) -laxtls +endif + +ifndef CONFIG_AXTLSWRAP +sslwrap: +else +sslwrap : $(TARGET) + +OBJ= axtlswrap.o +include $(AXTLS_HOME)/config/makefile.post + +$(TARGET): $(OBJ) $(AXTLS_HOME)/$(STAGE)/libaxtls.a + $(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) +ifdef CONFIG_STRIP_UNWANTED_SECTIONS + $(STRIP) --remove-section=.comment $(TARGET) +endif + +endif # CONFIG_AXTLSWRAP + +clean:: + -@rm -f $(TARGET)* + diff --git a/circuitpython/lib/axtls/axtlswrap/axtlswrap.c b/circuitpython/lib/axtls/axtlswrap/axtlswrap.c new file mode 100755 index 0000000..1ab1c02 --- /dev/null +++ b/circuitpython/lib/axtls/axtlswrap/axtlswrap.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2009, Steve Bennett + * + * 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 axTLS project 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. + */ + +/* + * sslwrap re-implemented with axTLS - a way to wrap an existing webserver + * with axTLS. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "os_port.h" +#include "ssl.h" + +/* If nothing is received or sent in this many seconds, give up */ +static int opt_timeout = 60; + +static int opt_verbose = 0; + +int main(int argc, char *argv[]) +{ + int log_opts = LOG_PERROR; + int fd[2]; /* output from child */ + int df[2]; /* input to child */ + int pid; + int readlen; + unsigned char *readpt; + static unsigned char *readbuf = NULL; + int readbuf_len = 0; + + SSL_CTX *ssl_ctx; + SSL *ssl; + + /* This relies on stdin and stdout being one and the same */ + int sslfd = fileno(stdin); + + while (argc > 2 && argv[1][0] == '-') + { + if (argc > 3 && strcmp(argv[1], "-t") == 0) + { + opt_timeout = atoi(argv[2]); + argv += 2; + argc -= 2; + continue; + } + + if (strcmp(argv[1], "-q") == 0) + { + log_opts = 0; + argv++; + argc--; + continue; + } + + if (strcmp(argv[1], "-v") == 0) + { + opt_verbose++; + argv++; + argc--; + continue; + } + } + + if (argc < 2) + { + fprintf(stderr, "Usage: axtlswrap [-v] [-q] " + "[-t timeout] command ...\n"); + return 1; + } + + if (access(argv[1], X_OK) != 0) + { + fprintf(stderr, "Not an executabled: %s\n", argv[1]); + return 1; + } + + openlog("axtlswrap", LOG_PID | log_opts, LOG_DAEMON); + + /* Create an SSL context with the required options */ + ssl_ctx = ssl_ctx_new(opt_verbose > 1 ? + SSL_DISPLAY_STATES | SSL_DISPLAY_CERTS : 0, 1); + + if (ssl_ctx == NULL) + { + syslog(LOG_ERR, "Failed to create SSL ctx"); + return 1; + } + + /* And create an ssl session attached to sslfd */ + ssl = ssl_server_new(ssl_ctx, sslfd); + if (ssl == NULL) + { + syslog(LOG_ERR, "Failed to create SSL connection"); + return 1; + } + + /* Get past the handshaking */ + while ((readlen = ssl_read(ssl, &readpt)) == SSL_OK) + { + /* Still handshaking */ + } + + if (readlen < 0) + { + syslog(LOG_ERR, "SSL handshake failed: %d", readlen); + return 1; + } + + if (opt_verbose) + { + syslog(LOG_INFO, "SSL handshake OK"); + } + + /* Looks OK, we have data, so fork the child and start */ + if (pipe(fd) < 0 || pipe(df) < 0) + { + syslog(LOG_ERR, "pipe failed: %m"); + return 1; + } + + /* Give some indication to the child that we are running SSL + * It would be possible to provide other details + * too. Perhaps as in: http://httpd.apache.org/docs/2.0/mod/mod_ssl.html + */ + setenv("SSL_PROTOCOL", "TLSv1", 1); + +#ifndef NOMMU + if (opt_verbose) + { + pid = fork(); + } + else +#endif + pid = vfork(); + if (pid < 0) + { + syslog(LOG_ERR, "vfork failed: %m"); + return 1; + } + + if (pid > 0) + { + /* This is the parent */ + static unsigned char writebuf[4096]; + int writelen = 0; + struct pollfd pfd[3]; + int timeout_count = 0; + + int cwfd = df[1]; /* write to child */ + int crfd = fd[0]; /* read from child */ + + int child_alive = 1; + + /* Don't die on SIGPIPE */ + signal(SIGPIPE, SIG_IGN); + + close(df[0]); + close(fd[1]); + + pfd[0].fd = sslfd; + pfd[1].fd = cwfd; + pfd[2].fd = crfd; + + /* Need to copy any remaining read data into readbuf */ + if (readlen > readbuf_len) { + readbuf = realloc(readbuf, readlen); + readbuf_len = readlen; + } + memcpy(readbuf, readpt, readlen); + + + /* While the child is alive or there is something to return... */ + while (child_alive || writelen > 0) + { + /* Work out what to read and what to write */ + int ret; + + pfd[0].events = 0; + pfd[0].revents = 0; + + /* Only want to read ssl data if there is nothing else to do */ + if (readlen == 0) + { + /* can read ssl data */ + pfd[0].events |= POLLIN; + } + + if (writelen > 0) + { + /* can write ssl data - will block to do this */ + pfd[0].events |= POLLOUT; + } + + pfd[1].events = 0; + pfd[1].revents = 0; + + if (child_alive && readlen > 0) + { + pfd[1].events |= POLLOUT; + } + + pfd[2].events = 0; + pfd[2].revents = 0; + + if (child_alive && writelen == 0) + { + pfd[2].events |= POLLIN; + } + + /* Timeout after 1 second so we can increment timeout_count */ + ret = poll(pfd, 3, 1000); + + if (ret < 0) + { + if (errno != EAGAIN) + { + /* Kill off the child */ + kill(pid, SIGTERM); + break; + } + + continue; + } + + if (ret == 0) + { + if (++timeout_count >= opt_timeout) + { + /* Kill off the child */ + kill(pid, SIGTERM); + break; + } + + continue; + } + + timeout_count = 0; + + if (pfd[2].revents & POLLNVAL) + { + /* REVISIT: This can probably be removed */ + syslog(LOG_ERR, "Child closed output pipe"); + child_alive = 0; + } + else if (pfd[2].revents & POLLIN) + { + /* Can read from (3) */ + writelen = read(crfd, writebuf, sizeof(writebuf)); + if (writelen <= 0) + { + if (writelen < 0) + { + syslog(LOG_WARNING, "Failed to read from child: len=%d", + writelen); + } + break; + } + } + else if ((pfd[2].revents & POLLHUP) && kill(pid, 0) == 0) + { + if (opt_verbose) + { + syslog(LOG_INFO, "Child died and pipe gave POLLHUP"); + } + + child_alive = 0; + } + + if (writelen > 0) + { + const unsigned char *pt = writebuf; + while (writelen > 0) + { + ret = ssl_write(ssl, pt, writelen); + if (ret <= 0) + { + syslog(LOG_WARNING, "Failed to write ssl: ret=%d", ret); + /* Kill off the child now */ + kill(pid, SIGTERM); + writelen = -1; + break; + } + else + { + pt += ret; + writelen -= ret; + } + } + if (writelen < 0) + { + break; + } + } + else if (pfd[0].revents & POLLIN) + { + readlen = ssl_read(ssl, &readpt); + if (readlen <= 0 && opt_verbose) + { + syslog(LOG_INFO, "ssl_read() returned %d", readlen); + } + + if (readlen < 0) + { + /* Kill off the child */ + kill(pid, SIGTERM); + break; + } + } + + /* Copy read data into readbuf since ssl_write() shares a buffer with ssl_read() */ + if (readlen > readbuf_len) { + readbuf = realloc(readbuf, readlen); + readbuf_len = readlen; + } + memcpy(readbuf, readpt, readlen); + + if (pfd[1].revents & POLLNVAL) + { + /* REVISIT: This can probably be removed */ + syslog(LOG_ERR, "Child closed input pipe"); + readlen = -1; + child_alive = 0; + } + else if (pfd[1].revents & POLLOUT) + { + const unsigned char *pt = readbuf; + while (readlen > 0) + { + int len = write(cwfd, pt, readlen); + if (len <= 0) + { + syslog(LOG_WARNING, "Failed to write to child: len=%d", + len); + break; + } + + readlen -= len; + pt += len; + } + } + + } + + ssl_free(ssl); +#if 0 + fprintf(stderr, "[%d] SSL done: timeout_count=%d, readlen=%d, writelen=%d, child_alive=%d\n", + getpid(), timeout_count, readlen, writelen, child_alive); +#endif + return 0; + } + + /* Child */ + close(df[1]); + close(fd[0]); + + dup2(df[0],0); + dup2(fd[1],1); + + close(df[0]); + close(fd[1]); + + execv(argv[1], argv + 1); + _exit(1); +} diff --git a/circuitpython/lib/axtls/bindings/Config.in b/circuitpython/lib/axtls/bindings/Config.in new file mode 100644 index 0000000..443fc1a --- /dev/null +++ b/circuitpython/lib/axtls/bindings/Config.in @@ -0,0 +1,105 @@ +# +# For a description of the syntax of this configuration file, +# see scripts/config/Kconfig-language.txt +# +menu "Language Bindings" + +config CONFIG_BINDINGS + bool "Create language bindings" + default n + help + axTLS supports language bindings in C#, VB.NET, Java and Perl. + + Select Y here if you want to build the various language bindings. + +config CONFIG_CSHARP_BINDINGS + bool "Create C# bindings" + default n + depends on CONFIG_BINDINGS + help + Build C# bindings. + + This requires .NET to be installed on Win32 platforms and mono to be + installed on all other platforms. + +config CONFIG_VBNET_BINDINGS + bool "Create VB.NET bindings" + default n + depends on CONFIG_BINDINGS + help + Build VB.NET bindings. + + This requires the .NET to be installed and is only built under Win32 + platforms. + +menu ".Net Framework" +depends on CONFIG_CSHARP_BINDINGS || CONFIG_VBNET_BINDINGS +config CONFIG_DOT_NET_FRAMEWORK_BASE + string "Location of .NET Framework" + default "c:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727" +endmenu + +config CONFIG_JAVA_BINDINGS + bool "Create Java bindings" + default n + depends on CONFIG_BINDINGS + help + Build Java bindings. + + Current Issues (see README): + * Needs Java 1.4 or better. + * If building under Win32 it will use the Win32 JDK. + +menu "Java Home" +depends on CONFIG_JAVA_BINDINGS +config CONFIG_JAVA_HOME + string "Location of JDK" + default "c:\\Program Files\\Java\\jdk1.5.0_06" if CONFIG_PLATFORM_WIN32 || CONFIG_PLATFORM_CYGWIN + default "/usr/lib/jvm/java-7-openjdk-amd64" if !CONFIG_PLATFORM_WIN32 && !CONFIG_PLATFORM_CYGWIN + depends on CONFIG_JAVA_BINDINGS + help + The location of Sun's JDK. +endmenu + +config CONFIG_PERL_BINDINGS + bool "Create Perl bindings" + default n + depends on CONFIG_BINDINGS + help + Build Perl bindings. + + Current Issues (see README): + * 64 bit versions don't work at present. + * libperl.so needs to be in the shared library path. + +menu "Perl Home" +depends on CONFIG_PERL_BINDINGS && CONFIG_PLATFORM_WIN32 +config CONFIG_PERL_CORE + string "Location of Perl CORE" + default "c:\\perl\\lib\\CORE" + help: + works with ActiveState + "http://www.activestate.com/Products/ActivePerl" + +config CONFIG_PERL_LIB + string "Name of Perl Library" + default "perl58.lib" +endmenu + +config CONFIG_LUA_BINDINGS + bool "Create Lua bindings" + default n + depends on CONFIG_BINDINGS && !CONFIG_PLATFORM_WIN32 + help + Build Lua bindings (see www.lua.org). + +menu "Lua Home" +depends on CONFIG_LUA_BINDINGS +config CONFIG_LUA_CORE + string "Location of Lua CORE" + default "/usr/local" + help: + If the Lua exists on another directory then this needs to be changed +endmenu + +endmenu diff --git a/circuitpython/lib/axtls/bindings/Makefile b/circuitpython/lib/axtls/bindings/Makefile new file mode 100644 index 0000000..7654fbb --- /dev/null +++ b/circuitpython/lib/axtls/bindings/Makefile @@ -0,0 +1,86 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +all: + +include ../config/.config +include ../config/makefile.conf + +ifdef CONFIG_CSHARP_BINDINGS +all: csharp/axInterface.cs +endif + +ifdef CONFIG_VBNET_BINDINGS +all: vbnet/axInterface.vb +endif + +ifdef CONFIG_JAVA_BINDINGS +all: java/axtlsj.java +endif + +ifdef CONFIG_PERL_BINDINGS +all: perl/axTLSp_wrap.c +endif + +ifdef CONFIG_LUA_BINDINGS +all: lua/axTLSl_wrap.c +endif + +csharp/axInterface.cs: ../ssl/ssl.h + @perl ./generate_interface.pl -csharp + +vbnet/axInterface.vb: ../ssl/ssl.h + @perl ./generate_interface.pl -vbnet + +java/axTLSj.i: ../ssl/ssl.h + @perl ./generate_SWIG_interface.pl -java + +java/axtlsj.java: java/axTLSj.i $(wildcard java/SSL*.java) + @cd java; swig -java -package axTLSj axTLSj.i; $(MAKE) + +perl/axTLSp.i: ../ssl/ssl.h + @perl ./generate_SWIG_interface.pl -perl + +perl/axTLSp_wrap.c: perl/axTLSp.i + @cd perl; swig -perl5 axTLSp.i; $(MAKE) + +lua/axTLSl.i: ../ssl/ssl.h + @perl ./generate_SWIG_interface.pl -lua + +lua/axTLSl_wrap.c: lua/axTLSl.i + @cd lua; swig -lua axTLSl.i; $(MAKE) + +clean:: + $(MAKE) -C csharp clean + $(MAKE) -C vbnet clean + $(MAKE) -C java clean + $(MAKE) -C perl clean + $(MAKE) -C lua clean + diff --git a/circuitpython/lib/axtls/bindings/README b/circuitpython/lib/axtls/bindings/README new file mode 100644 index 0000000..8bc3109 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/README @@ -0,0 +1,43 @@ +=============================================================================== += Language Bindings = +=============================================================================== + +The tools to generate the various language bindings are done here. +SWIG 1.3.24 or better is required for creating the Java and Perl bindings. + +Perl scripts are used to parse ssl.h and automagically give the appropriate +bindings. + +At present, the four languages supported are: + +* C# +* VB.NET +* Java +* Perl + +To generate each binding run the following: + +C#: +> generate_interface.pl -csharp + +VB.NET: +> generate_interface.pl -vbnet + + +Java: +> generate_SWIG_interface.pl -java +> cd java; swig -java -package axTLSj -noextern axTLSj.i + +Perl: +> generate_SWIG_interface.pl -perl +> cd perl; swig -noextern -perl axTLSp.i + +Java and Perl both create a library each called libaxtlsj.so and libaxtlsp.so +(or axtlsj.dll and atlsp.dll on Win32 platforms). + +Note: the "-noextern" is deprecated in swig 1.3.27 and newer. The "-noextern" +option was required to get Win32 bindings to work (which is why is has probably +been deprecated). + +Each binding (except for Perl) has an extra helper interface to make life +easier. diff --git a/circuitpython/lib/axtls/bindings/csharp/Makefile b/circuitpython/lib/axtls/bindings/csharp/Makefile new file mode 100644 index 0000000..3414f85 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/csharp/Makefile @@ -0,0 +1,35 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 ../../config/.config +include ../../config/makefile.conf + +clean:: + @rm -f axssl* axInterface.cs diff --git a/circuitpython/lib/axtls/bindings/csharp/axTLS.cs b/circuitpython/lib/axtls/bindings/csharp/axTLS.cs new file mode 100644 index 0000000..6a2f6b0 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/csharp/axTLS.cs @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * A wrapper around the unmanaged interface to give a semi-decent C# API + */ + +using System; +using System.Runtime.InteropServices; +using System.Net.Sockets; + +/** + * @defgroup csharp_api C# API. + * + * Ensure that the appropriate Dispose() methods are called when finished with + * various objects - otherwise memory leaks will result. + * @{ + */ +namespace axTLS +{ + /** + * @class SSL + * @ingroup csharp_api + * @brief A representation of an SSL connection. + */ + public class SSL + { + public IntPtr m_ssl; /**< A pointer to the real SSL type */ + + /** + * @brief Store the reference to an SSL context. + * @param ip [in] A reference to an SSL object. + */ + public SSL(IntPtr ip) + { + m_ssl = ip; + } + + /** + * @brief Free any used resources on this connection. + * + * A "Close Notify" message is sent on this connection (if possible). + * It is up to the application to close the socket. + */ + public void Dispose() + { + axtls.ssl_free(m_ssl); + } + + /** + * @brief Return the result of a handshake. + * @return SSL_OK if the handshake is complete and ok. + * @see ssl.h for the error code list. + */ + public int HandshakeStatus() + { + return axtls.ssl_handshake_status(m_ssl); + } + + /** + * @brief Return the SSL cipher id. + * @return The cipher id which is one of: + * - SSL_AES128_SHA (0x2f) + * - SSL_AES256_SHA (0x35) + * - SSL_AES128_SHA256 (0x3c) + * - SSL_AES256_SHA256 (0x3d) + */ + public byte GetCipherId() + { + return axtls.ssl_get_cipher_id(m_ssl); + } + + /** + * @brief Get the session id for a handshake. + * + * This will be a 32 byte sequence and is available after the first + * handshaking messages are sent. + * @return The session id as a 32 byte sequence. + * @note A SSLv23 handshake may have only 16 valid bytes. + */ + public byte[] GetSessionId() + { + IntPtr ptr = axtls.ssl_get_session_id(m_ssl); + byte sess_id_size = axtls.ssl_get_session_id_size(m_ssl); + byte[] result = new byte[sess_id_size]; + Marshal.Copy(ptr, result, 0, sess_id_size); + return result; + } + + /** + * @brief Retrieve an X.509 distinguished name component. + * + * When a handshake is complete and a certificate has been exchanged, + * then the details of the remote certificate can be retrieved. + * + * This will usually be used by a client to check that the server's + * common name matches the URL. + * + * A full handshake needs to occur for this call to work. + * + * @param component [in] one of: + * - SSL_X509_CERT_COMMON_NAME + * - SSL_X509_CERT_ORGANIZATION + * - SSL_X509_CERT_ORGANIZATIONAL_NAME + * - SSL_X509_CA_CERT_COMMON_NAME + * - SSL_X509_CA_CERT_ORGANIZATION + * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME + * @return The appropriate string (or null if not defined) + */ + public string GetCertificateDN(int component) + { + return axtls.ssl_get_cert_dn(m_ssl, component); + } + } + + /** + * @class SSLUtil + * @ingroup csharp_api + * @brief Some global helper functions. + */ + public class SSLUtil + { + + /** + * @brief Return the build mode of the axTLS project. + * @return The build mode is one of: + * - SSL_BUILD_SERVER_ONLY + * - SSL_BUILD_ENABLE_VERIFICATION + * - SSL_BUILD_ENABLE_CLIENT + * - SSL_BUILD_FULL_MODE + */ + public static int BuildMode() + { + return axtls.ssl_get_config(axtls.SSL_BUILD_MODE); + } + + /** + * @brief Return the number of chained certificates that the + * client/server supports. + * @return The number of supported server certificates. + */ + public static int MaxCerts() + { + return axtls.ssl_get_config(axtls.SSL_MAX_CERT_CFG_OFFSET); + } + + /** + * @brief Return the number of CA certificates that the client/server + * supports. + * @return The number of supported CA certificates. + */ + public static int MaxCACerts() + { + return axtls.ssl_get_config(axtls.SSL_MAX_CA_CERT_CFG_OFFSET); + } + + /** + * @brief Indicate if PEM is supported. + * @return true if PEM supported. + */ + public static bool HasPEM() + { + return axtls.ssl_get_config(axtls.SSL_HAS_PEM) > 0 ? true : false; + } + + /** + * @brief Display the text string of the error. + * @param error_code [in] The integer error code. + */ + public static void DisplayError(int error_code) + { + axtls.ssl_display_error(error_code); + } + + /** + * @brief Return the version of the axTLS project. + */ + public static string Version() + { + return axtls.ssl_version(); + } + } + + /** + * @class SSLCTX + * @ingroup csharp_api + * @brief A base object for SSLServer/SSLClient. + */ + public class SSLCTX + { + /** + * @brief A reference to the real client/server context. + */ + protected IntPtr m_ctx; + + /** + * @brief Establish a new client/server context. + * + * This function is called before any client/server SSL connections are + * made. If multiple threads are used, then each thread will have its + * own SSLCTX context. Any number of connections may be made with a + * single context. + * + * Each new connection will use the this context's private key and + * certificate chain. If a different certificate chain is required, + * then a different context needs to be be used. + * + * @param options [in] Any particular options. At present the options + * supported are: + * - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if + * the server authentication fails. The certificate can be + * authenticated later with a call to VerifyCert(). + * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client + * authentication i.e. each handshake will include a "certificate + * request" message from the server. + * - SSL_DISPLAY_BYTES (full mode build only): Display the byte + * sequences during the handshake. + * - SSL_DISPLAY_STATES (full mode build only): Display the state + * changes during the handshake. + * - SSL_DISPLAY_CERTS (full mode build only): Display the + * certificates that are passed during a handshake. + * - SSL_DISPLAY_RSA (full mode build only): Display the RSA key + * details that are passed during a handshake. + * @param num_sessions [in] The number of sessions to be used for + * session caching. If this value is 0, then there is no session + * caching. + * @return A client/server context. + */ + protected SSLCTX(uint options, int num_sessions) + { + m_ctx = axtls.ssl_ctx_new(options, num_sessions); + } + + /** + * @brief Remove a client/server context. + * + * Frees any used resources used by this context. Each connection will + * be sent a "Close Notify" alert (if possible). + */ + public void Dispose() + { + axtls.ssl_ctx_free(m_ctx); + } + + /** + * @brief Read the SSL data stream. + * @param ssl [in] An SSL object reference. + * @param in_data [out] After a successful read, the decrypted data + * will be here. It will be null otherwise. + * @return The number of decrypted bytes: + * - if > 0, then the handshaking is complete and we are returning the + * number of decrypted bytes. + * - SSL_OK if the handshaking stage is successful (but not yet + * complete). + * - < 0 if an error. + * @see ssl.h for the error code list. + * @note Use in_data before doing any successive ssl calls. + */ + public int Read(SSL ssl, out byte[] in_data) + { + IntPtr ptr = IntPtr.Zero; + int ret = axtls.ssl_read(ssl.m_ssl, ref ptr); + + if (ret > axtls.SSL_OK) + { + in_data = new byte[ret]; + Marshal.Copy(ptr, in_data, 0, ret); + } + else + { + in_data = null; + } + + return ret; + } + + /** + * @brief Write to the SSL data stream. + * @param ssl [in] An SSL obect reference. + * @param out_data [in] The data to be written + * @return The number of bytes sent, or if < 0 if an error. + * @see ssl.h for the error code list. + */ + public int Write(SSL ssl, byte[] out_data) + { + return axtls.ssl_write(ssl.m_ssl, out_data, out_data.Length); + } + + /** + * @brief Write to the SSL data stream. + * @param ssl [in] An SSL obect reference. + * @param out_data [in] The data to be written + * @param out_len [in] The number of bytes to be written + * @return The number of bytes sent, or if < 0 if an error. + * @see ssl.h for the error code list. + */ + public int Write(SSL ssl, byte[] out_data, int out_len) + { + return axtls.ssl_write(ssl.m_ssl, out_data, out_len); + } + + /** + * @brief Find an ssl object based on a Socket reference. + * + * Goes through the list of SSL objects maintained in a client/server + * context to look for a socket match. + * @param s [in] A reference to a Socket object. + * @return A reference to the SSL object. Returns null if the object + * could not be found. + */ + public SSL Find(Socket s) + { + int client_fd = s.Handle.ToInt32(); + return new SSL(axtls. ssl_find(m_ctx, client_fd)); + } + + /** + * @brief Authenticate a received certificate. + * + * This call is usually made by a client after a handshake is complete + * and the context is in SSL_SERVER_VERIFY_LATER mode. + * @param ssl [in] An SSL object reference. + * @return SSL_OK if the certificate is verified. + */ + public int VerifyCert(SSL ssl) + { + return axtls.ssl_verify_cert(ssl.m_ssl); + } + + /** + * @brief Force the client to perform its handshake again. + * + * For a client this involves sending another "client hello" message. + * For the server is means sending a "hello request" message. + * + * This is a blocking call on the client (until the handshake + * completes). + * @param ssl [in] An SSL object reference. + * @return SSL_OK if renegotiation instantiation was ok + */ + public int Renegotiate(SSL ssl) + { + return axtls.ssl_renegotiate(ssl.m_ssl); + } + + /** + * @brief Load a file into memory that is in binary DER or ASCII PEM + * format. + * + * These are temporary objects that are used to load private keys, + * certificates etc into memory. + * @param obj_type [in] The format of the file. Can be one of: + * - SSL_OBJ_X509_CERT (no password required) + * - SSL_OBJ_X509_CACERT (no password required) + * - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported) + * - SSL_OBJ_P8 (RC4-128 encrypted data supported) + * - SSL_OBJ_P12 (RC4-128 encrypted data supported) + * + * PEM files are automatically detected (if supported). + * @param filename [in] The location of a file in DER/PEM format. + * @param password [in] The password used. Can be null if not required. + * @return SSL_OK if all ok + */ + public int ObjLoad(int obj_type, string filename, string password) + { + return axtls.ssl_obj_load(m_ctx, obj_type, filename, password); + } + + /** + * @brief Transfer binary data into the object loader. + * + * These are temporary objects that are used to load private keys, + * certificates etc into memory. + * @param obj_type [in] The format of the memory data. + * @param data [in] The binary data to be loaded. + * @param len [in] The amount of data to be loaded. + * @param password [in] The password used. Can be null if not required. + * @return SSL_OK if all ok + */ + public int ObjLoad(int obj_type, byte[] data, int len, string password) + { + return axtls.ssl_obj_memory_load(m_ctx, obj_type, + data, len, password); + } + } + + /** + * @class SSLServer + * @ingroup csharp_api + * @brief The server context. + * + * All server connections are started within a server context. + */ + public class SSLServer : SSLCTX + { + /** + * @brief Start a new server context. + * + * @see SSLCTX for details. + */ + public SSLServer(uint options, int num_sessions) : + base(options, num_sessions) {} + + /** + * @brief Establish a new SSL connection to an SSL client. + * + * It is up to the application to establish the initial socket + * connection. + * + * Call Dispose() when the connection is to be removed. + * @param s [in] A reference to a Socket object. + * @return An SSL object reference. + */ + public SSL Connect(Socket s) + { + int client_fd = s.Handle.ToInt32(); + return new SSL(axtls.ssl_server_new(m_ctx, client_fd)); + } + } + + /** + * @class SSLClient + * @ingroup csharp_api + * @brief The client context. + * + * All client connections are started within a client context. + */ + public class SSLClient : SSLCTX + { + /** + * @brief Start a new client context. + * + * @see SSLCTX for details. + */ + public SSLClient(uint options, int num_sessions) : + base(options, num_sessions) {} + + /** + * @brief Establish a new SSL connection to an SSL server. + * + * It is up to the application to establish the initial socket + * connection. + * + * This is a blocking call - it will finish when the handshake is + * complete (or has failed). + * + * Call Dispose() when the connection is to be removed. + * @param s [in] A reference to a Socket object. + * @param session_id [in] A 32 byte session id for session resumption. + * This can be null if no session resumption is not required. + * @return An SSL object reference. Use SSL.handshakeStatus() to check + * if a handshake succeeded. + */ + public SSL Connect(Socket s, byte[] session_id) + { + int client_fd = s.Handle.ToInt32(); + byte sess_id_size = (byte)(session_id != null ? + session_id.Length : 0); + return new SSL(axtls.ssl_client_new(m_ctx, client_fd, session_id, + sess_id_size)); + } + } +} +/** @} */ diff --git a/circuitpython/lib/axtls/bindings/generate_SWIG_interface.pl b/circuitpython/lib/axtls/bindings/generate_SWIG_interface.pl new file mode 100755 index 0000000..90c4ba3 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/generate_SWIG_interface.pl @@ -0,0 +1,392 @@ +#!/usr/bin/perl + +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +#=============================================================== +# Transforms function signature into SWIG format +sub transformSignature +{ + foreach $item (@_) + { + $line =~ s/STDCALL //g; + $line =~ s/EXP_FUNC/extern/g; + + # make API Java more 'byte' friendly + $line =~ s/uint32_t/int/g; + $line =~ s/const uint8_t \* /const unsigned char \* /g; + $line =~ s/\(void\)/()/g; + if ($ARGV[0] eq "-java") + { + $line =~ s/.*ssl_read.*//g; + $line =~ s/const uint8_t \*(\w+)/const signed char $1\[\]/g; + $line =~ s/uint8_t/signed char/g; + } + elsif ($ARGV[0] eq "-perl") + { + $line =~ s/const uint8_t \*(\w+)/const unsigned char $1\[\]/g; + $line =~ s/uint8_t/unsigned char/g; + } + else # lua + { + $line =~ s/const uint8_t \*session_id/const unsigned char session_id\[\]/g; + $line =~ s/const uint8_t \*\w+/unsigned char *INPUT/g; + $line =~ s/uint8_t/unsigned char/g; + } + } + + return $line; +} + +# Parse input file +sub parseFile +{ + foreach $line (@_) + { + next if $line =~ /ssl_x509_create/; # ignore for now + + # test for a #define + if (!$skip && $line =~ m/^#define/) + { + $splitDefine = 1 if $line =~ m/\\$/; + print DATA_OUT $line; + + # check line is not split + next if $splitDefine == 1; + } + + # pick up second line of #define statement + if ($splitDefine) + { + print DATA_OUT $line; + + # check line is not split + $splitDefine = ($line =~ m/\\$/); + next; + } + + # test for function declaration + if (!$skip && $line =~ /EXP_FUNC/ && $line !~/\/\*/) + { + $line = transformSignature($line); + $splitFunctionDeclaration = $line !~ /;/; + print DATA_OUT $line; + next; + } + + if ($splitFunctionDeclaration) + { + $line = transformSignature($line); + $splitFunctionDeclaration = $line !~ /;/; + print DATA_OUT $line; + next; + } + } +} + +#=============================================================== + +# Determine which module to build from cammand-line options +use strict; +use Getopt::Std; + +my $module; +my $interfaceFile; +my $data_file; +my $skip; +my $splitLine; +my @raw_data; + +if (not defined $ARGV[0]) +{ + die "Usage: $0 [-java | -perl | -lua]\n"; +} + +if ($ARGV[0] eq "-java") +{ + print "Generating Java interface file\n"; + $module = "axtlsj"; + $interfaceFile = "java/axTLSj.i"; +} +elsif ($ARGV[0] eq "-perl") +{ + print "Generating Perl interface file\n"; + $module = "axtlsp"; + $interfaceFile = "perl/axTLSp.i"; +} +elsif ($ARGV[0] eq "-lua") +{ + print "Generating lua interface file\n"; + $module = "axtlsl"; + $interfaceFile = "lua/axTLSl.i"; +} +else +{ + die "Usage: $0 [-java | -perl | -lua]\n"; +} + +# Input file required to generate SWIG interface file. +$data_file = "../ssl/ssl.h"; + +# Open input files +open(DATA_IN, $data_file) || die("Could not open file ($data_file)!"); +@raw_data = ; + +# Open output file +open(DATA_OUT, ">$interfaceFile") || die("Cannot Open File"); + +# +# I wish I could say it was easy to generate the Perl/Java/Lua bindings, +# but each had their own set of challenges... :-(. +# +print DATA_OUT << "END"; +%module $module\n + +/* include our own header */ +%inline %{ +#include "ssl.h" +%} + +%include "typemaps.i" +/* Some SWIG magic to make the API a bit more Java friendly */ +#ifdef SWIGJAVA + +%apply long { SSL * }; +%apply long { SSL_CTX * }; +%apply long { SSLObjLoader * }; + +/* allow "unsigned char []" to become "byte[]" */ +%include "arrays_java.i" + +/* convert these pointers to use long */ +%apply signed char[] {unsigned char *}; +%apply signed char[] {signed char *}; + +/* allow ssl_get_session_id() to return "byte[]" */ +%typemap(out) unsigned char * ssl_get_session_id \"if (result) jresult = SWIG_JavaArrayOutSchar(jenv, result, ssl_get_session_id_size((SSL const *)arg1));\" + +/* allow ssl_client_new() to have a null session_id input */ +%typemap(in) const signed char session_id[] (jbyte *jarr) { + if (jarg3 == NULL) + { + jresult = (jint)ssl_client_new(arg1,arg2,NULL,0); + return jresult; + } + + if (!SWIG_JavaArrayInSchar(jenv, &jarr, &arg3, jarg3)) return 0; +} + +/* Lot's of work required for an ssl_read() due to its various custom + * requirements. + */ +%native (ssl_read) int ssl_read(SSL *ssl, jobject in_data); +%{ +JNIEXPORT jint JNICALL Java_axTLSj_axtlsjJNI_ssl_1read(JNIEnv *jenv, jclass jcls, jint jarg1, jobject jarg2) { + jint jresult = 0 ; + SSL *arg1; + unsigned char *arg2; + jbyte *jarr; + int result; + JNIEnv e = *jenv; + jclass holder_class; + jfieldID fid; + + arg1 = (SSL *)jarg1; + result = (int)ssl_read(arg1, &arg2); + + /* find the "m_buf" entry in the SSLReadHolder class */ + if (!(holder_class = e->GetObjectClass(jenv,jarg2)) || + !(fid = e->GetFieldID(jenv,holder_class, "m_buf", "[B"))) + return SSL_NOT_OK; + + if (result > SSL_OK) + { + int i; + + /* create a new byte array to hold the read data */ + jbyteArray jarray = e->NewByteArray(jenv, result); + + /* copy the bytes across to the java byte array */ + jarr = e->GetByteArrayElements(jenv, jarray, 0); + for (i = 0; i < result; i++) + jarr[i] = (jbyte)arg2[i]; + + /* clean up and set the new m_buf object */ + e->ReleaseByteArrayElements(jenv, jarray, jarr, 0); + e->SetObjectField(jenv, jarg2, fid, jarray); + } + else /* set to null */ + e->SetObjectField(jenv, jarg2, fid, NULL); + + jresult = (jint)result; + return jresult; +} +%} + +/* Big hack to get hold of a socket's file descriptor */ +%typemap (jtype) long "Object" +%typemap (jstype) long "Object" +%native (getFd) int getFd(long sock); +%{ +JNIEXPORT jint JNICALL Java_axTLSj_axtlsjJNI_getFd(JNIEnv *env, jclass jcls, jobject sock) +{ + JNIEnv e = *env; + jfieldID fid; + jobject impl; + jobject fdesc; + + /* get the SocketImpl from the Socket */ + if (!(jcls = e->GetObjectClass(env,sock)) || + !(fid = e->GetFieldID(env,jcls,"impl","Ljava/net/SocketImpl;")) || + !(impl = e->GetObjectField(env,sock,fid))) return -1; + + /* get the FileDescriptor from the SocketImpl */ + if (!(jcls = e->GetObjectClass(env,impl)) || + !(fid = e->GetFieldID(env,jcls,"fd","Ljava/io/FileDescriptor;")) || + !(fdesc = e->GetObjectField(env,impl,fid))) return -1; + + /* get the fd from the FileDescriptor */ + if (!(jcls = e->GetObjectClass(env,fdesc)) || + !(fid = e->GetFieldID(env,jcls,"fd","I"))) return -1; + + /* return the descriptor */ + return e->GetIntField(env,fdesc,fid); +} +%} + +#endif + +/* Some SWIG magic to make the API a bit more Perl friendly */ +#ifdef SWIGPERL + +/* for ssl_session_id() */ +%typemap(out) const unsigned char * { + SV *svs = newSVpv((unsigned char *)\$1, ssl_get_session_id_size((SSL const *)arg1)); + \$result = newRV(svs); + sv_2mortal(\$result); + argvi++; +} + +/* for ssl_write() */ +%typemap(in) const unsigned char out_data[] { + SV* tempsv; + if (!SvROK(\$input)) + croak("Argument \$argnum is not a reference."); + tempsv = SvRV(\$input); + if (SvTYPE(tempsv) != SVt_PV) + croak("Argument \$argnum is not an string."); + \$1 = (unsigned char *)SvPV(tempsv, PL_na); +} + +/* for ssl_read() */ +%typemap(in) unsigned char **in_data (unsigned char *buf) { + \$1 = &buf; +} + +%typemap(argout) unsigned char **in_data { + if (result > SSL_OK) { + SV *svs = newSVpv(*\$1, result); + \$result = newRV(svs); + sv_2mortal(\$result); + argvi++; + } +} + +/* for ssl_client_new() */ +%typemap(in) const unsigned char session_id[] { + /* check for a reference */ + if (SvOK(\$input) && SvROK(\$input)) { + SV* tempsv = SvRV(\$input); + if (SvTYPE(tempsv) != SVt_PV) + croak("Argument \$argnum is not an string."); + \$1 = (unsigned char *)SvPV(tempsv, PL_na); + } + else + \$1 = NULL; +} + +#endif + +/* Some SWIG magic to make the API a bit more Lua friendly */ +#ifdef SWIGLUA +SWIG_NUMBER_TYPEMAP(unsigned char); +SWIG_TYPEMAP_NUM_ARR(uchar,unsigned char); + +/* for ssl_session_id() */ +%typemap(out) const unsigned char * { + int i; + lua_newtable(L); + for (i = 0; i < ssl_get_session_id_size((SSL const *)arg1); i++){ + lua_pushnumber(L,(lua_Number)result[i]); + lua_rawseti(L,-2,i+1); /* -1 is the number, -2 is the table */ + } + SWIG_arg++; +} + +/* for ssl_read() */ +%typemap(in) unsigned char **in_data (unsigned char *buf) { + \$1 = &buf; +} + +%typemap(argout) unsigned char **in_data { + if (result > SSL_OK) { + int i; + lua_newtable(L); + for (i = 0; i < result; i++){ + lua_pushnumber(L,(lua_Number)buf2[i]); + lua_rawseti(L,-2,i+1); /* -1 is the number, -2 is the table */ + } + SWIG_arg++; + } +} + +/* for ssl_client_new() */ +%typemap(in) const unsigned char session_id[] { + if (lua_isnil(L,\$input)) + \$1 = NULL; + else + \$1 = SWIG_get_uchar_num_array_fixed(L,\$input, ssl_get_session_id((SSL const *)\$1)); +} + +#endif + +END + +# Initialise loop variables +$skip = 1; +$splitLine = 0; + +parseFile(@raw_data); + +close(DATA_IN); +close(DATA_OUT); + +#=============================================================== + diff --git a/circuitpython/lib/axtls/bindings/generate_interface.pl b/circuitpython/lib/axtls/bindings/generate_interface.pl new file mode 100755 index 0000000..c24bff9 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/generate_interface.pl @@ -0,0 +1,322 @@ +#!/usr/bin/perl -w + +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +#=============================================================== +# This application transforms ssl.h into interfaces that can be used by +# other language bindings. It is "SWIG"-like in nature in that various +# files are generated based on the axTLS API. +# +# The file produced is axInterface.? (depending on the file extension). +# +#=============================================================== + +use strict; + +my $CSHARP = 0; +my $VBNET = 1; + +my $binding; +my $skip = 0; +my $signature_ret_type; + +# Transforms function signature into an Interface format +sub transformSignature +{ + my $item; + my ($line) = @_; + + foreach $item ($line) + { + # our very basic preprocessor + if ($binding == $CSHARP) + { + $line =~ s/STDCALL //; + $line =~ s/EXP_FUNC/ [DllImport ("axtls")]\n public static extern/; + $line =~ s/uint32_t/uint/g; + $line =~ s/uint8_t \*\*/ref IntPtr /g; + $line =~ s/const uint8_t \* /IntPtr /g; + $line =~ s/const uint8_t \*/byte[] /g; # note: subtle diff + $line =~ s/uint8_t \* ?/byte[] /g; + $line =~ s/uint8_t ?/byte /g; + $line =~ s/const char \* ?/string /g; + $line =~ s/const SSL_CTX \* ?/IntPtr /g; + $line =~ s/SSL_CTX \* ?/IntPtr /g; + $line =~ s/SSLObjLoader \* ?/IntPtr /g; + $line =~ s/const SSL \* ?/IntPtr /g; + $line =~ s/SSL \* ?/IntPtr /g; + $line =~ s/\(void\)/()/g; + } + elsif ($binding == $VBNET) + { + if ($line =~ /EXP_FUNC/) + { + # Procedure or function? + my $invariant = $line =~ /void /; + + my $proc = $invariant ? "Sub" : "Function"; + ($signature_ret_type) = $line =~ /EXP_FUNC (.*) STDCALL/; + $line =~ s/EXP_FUNC .* STDCALL / Public Shared $proc _\n /; + + $signature_ret_type =~ s/const uint8_t \*/As IntPtr/; + $signature_ret_type =~ s/const char \*/As String/; + $signature_ret_type =~ s/SSL_CTX \*/As IntPtr/; + $signature_ret_type =~ s/SSLObjLoader \*/As IntPtr/; + $signature_ret_type =~ s/SSL \*/As IntPtr/; + $signature_ret_type =~ s/uint8_t/As Byte/; + $signature_ret_type =~ s/int/As Integer/; + $signature_ret_type =~ s/void//; + $signature_ret_type .= "\n End $proc\n\n"; + } + + $line =~ s/uint32_t (\w+)/ByVal $1 As Integer/g; + $line =~ s/int (\w+)/ByVal $1 As Integer/g; + $line =~ s/uint8_t \*\* ?(\w+)/ByRef $1 As IntPtr/g; + $line =~ s/const uint8_t \* ?(\w+)/ByVal $1() As Byte/g; + $line =~ s/uint8_t \* ?(\w+)/ByVal $1() As Byte/g; + $line =~ s/uint8_t ?(\w+)/ByVal $1 As Byte/g; + $line =~ s/const char \* ?(\w+)/ByVal $1 As String/g; + $line =~ s/const SSL_CTX \* ?(\w+)/ByVal $1 As IntPtr/g; + $line =~ s/SSL_CTX \* ?(\w+)/ByVal $1 As IntPtr/g; + $line =~ s/SSLObjLoader \* ?(\w+)/ByVal $1 As IntPtr/g; + $line =~ s/const SSL \* ?(\w+)/ByVal $1 As IntPtr/g; + $line =~ s/SSL \* ?(\w+)/ByVal $1 As IntPtr/g; + $line =~ s/void \* ?(\w+)/Byval $1 As IntPtr/g; + $line =~ s/\(void\)/()/g; + $line =~ s/void//g; + $line =~ s/;\n/ $signature_ret_type;/; + } + } + + return $line; +} + +# Parse input file +sub parseFile +{ + my (@file) = @_; + my $line; + my $splitDefine = 0; + my $splitFunctionDeclaration; + my $vb_hack = " "; + my $vb_line_hack = 0; + + $skip = 0; + + foreach $line (@file) + { + next if $line =~ /sl_x509_create/; # ignore for now + + # test for a #define + if (!$skip && $line =~ m/^#define/) + { + $splitDefine = 1 if $line =~ m/\\$/; + + if ($binding == $VBNET) + { + $line =~ s/\|/Or/g; + $line =~ s/ 0x/ &H/; + } + + my ($name, $value) = $line =~ /#define (\w+) +([^\\]*)[\\]?\n/; + + if (defined $name && defined $value) + { + # C# constant translation + if ($binding == $CSHARP) + { + $line = " public const int $name = $value"; + } + # VB.NET constant translation + elsif ($binding == $VBNET) + { + $line = " Public Const $name As Integer = $value"; + } + } + + next if $line =~ /#define/; # ignore any other defines + + print DATA_OUT $line; + + # check line is not split + next if $splitDefine == 1; + print DATA_OUT ";" if $binding == $CSHARP; + print DATA_OUT "\n"; + } + + # pick up second line of #define statement + if ($splitDefine) + { + if ($line !~ /\\$/) + { + $line =~ s/$/;/ if $binding == $CSHARP; # add the ";" + } + + $line =~ s/ ?\| ?/ Or /g + if ($binding == $VBNET); + + # check line is not split + $splitDefine = ($line =~ m/\\$/); + + # ignore trailing "\" + $line =~ s/\\$// if $binding == $CSHARP; + $line =~ s/\\$/_/ if $binding == $VBNET; + print DATA_OUT $line; + next; + } + + # test for function declaration + if (!$skip && $line =~ /EXP_FUNC/ && $line !~ /\/\*/) + { + $line = transformSignature($line); + $splitFunctionDeclaration = $line !~ /;/; + $line =~ s/;// if ($binding == $VBNET); + $line =~ s/\n$/ _\n/ if ($binding == $VBNET) && + $splitFunctionDeclaration; + print DATA_OUT $line; + next; + } + + if ($splitFunctionDeclaration) + { + $line = transformSignature($line); + $splitFunctionDeclaration = $line !~ /;/; + $line =~ s/;// if ($binding == $VBNET); + $line =~ s/\n/ _\n/ if ($binding == $VBNET) && + $splitFunctionDeclaration == 1; + print DATA_OUT $line; + next; + } + } +} + +#=============================================================== + +# Determine which module to build from command-line options +use strict; +use Getopt::Std; + +my $binding_prefix; +my $binding_suffix; +my $data_file; +my @raw_data; + +if (not defined $ARGV[0]) +{ + goto ouch; +} + +if ($ARGV[0] eq "-csharp") +{ + print "Generating C# interface file\n"; + $binding_prefix = "csharp"; + $binding_suffix = "cs"; + $binding = $CSHARP; +} +elsif ($ARGV[0] eq "-vbnet") +{ + print "Generating VB.NET interface file\n"; + $binding_prefix = "vbnet"; + $binding_suffix = "vb"; + $binding = $VBNET; +} +else +{ +ouch: + die "Usage: $0 [-csharp | -vbnet]\n"; +} + +my $interfaceFile = "$binding_prefix/axInterface.$binding_suffix"; + +# Input file required to generate interface file. +$data_file = "../ssl/ssl.h"; + +# Open input files +open(DATA_IN, $data_file) || die("Could not open file ($data_file)!"); +@raw_data = ; + + +# Open output file +if ($binding == $CSHARP || $binding == $VBNET) +{ + open(DATA_OUT, ">$interfaceFile") || die("Cannot Open File"); +} + +# SPEC interface file header +if ($binding == $CSHARP) +{ + # generate the C#/C interface file + print DATA_OUT << "END"; +// The C# to C interface definition file for the axTLS project +// Do not modify - this file is generated + +using System; +using System.Runtime.InteropServices; + +namespace axTLS +{ + public class axtls + { +END +} +elsif ($binding == $VBNET) +{ + # generate the VB.NET/C interface file + print DATA_OUT << "END"; +' The VB.NET to C interface definition file for the axTLS project +' Do not modify - this file is generated + +Imports System +Imports System.Runtime.InteropServices + +Namespace axTLSvb + Public Class axtls +END +} + +parseFile(@raw_data); + +# finish up +if ($binding == $CSHARP) +{ + print DATA_OUT " };\n"; + print DATA_OUT "};\n"; +} +elsif ($binding == $VBNET) +{ + print DATA_OUT " End Class\nEnd Namespace\n"; +} + +close(DATA_IN); +close(DATA_OUT); + +#=============================================================== + diff --git a/circuitpython/lib/axtls/bindings/java/Makefile b/circuitpython/lib/axtls/bindings/java/Makefile new file mode 100644 index 0000000..8df1d0a --- /dev/null +++ b/circuitpython/lib/axtls/bindings/java/Makefile @@ -0,0 +1,94 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +AXTLS_HOME=../.. + +include $(AXTLS_HOME)/config/.config +include $(AXTLS_HOME)/config/makefile.conf +include $(AXTLS_HOME)/config/makefile.java.conf + +all: lib jar + +JAR=$(AXTLS_HOME)/$(STAGE)/axtls.jar + +ifdef CONFIG_PLATFORM_WIN32 +TARGET=$(AXTLS_HOME)/$(STAGE)/axtlsj.dll +else +TARGET=$(AXTLS_HOME)/$(STAGE)/libaxtlsj.so +endif + +lib: $(TARGET) +axTLSj_wrap.o : axTLSj_wrap.c + +JAVA_FILES= \ + axtlsjJNI.java \ + axtlsjConstants.java \ + axtlsj.java \ + SSLReadHolder.java \ + SSL.java \ + SSLUtil.java \ + SSLCTX.java \ + SSLServer.java \ + SSLClient.java + +OBJ=axTLSj_wrap.o + +JAVA_CLASSES:=$(JAVA_FILES:%.java=classes/axTLSj/%.class) + +ifdef CONFIG_PLATFORM_WIN32 +LDFLAGS += axtls.lib /libpath:"$(AXTLS_HOME)/$(STAGE)" + +include $(AXTLS_HOME)/config/makefile.post + +$(TARGET) : $(OBJ) + $(LD) $(LDFLAGS) $(LDSHARED) /out:$@ $(OBJ) +else # Not Win32 + +$(TARGET) : $(OBJ) + $(LD) $(LDFLAGS) -L $(AXTLS_HOME)/$(STAGE) $(LDSHARED) -o $@ $(OBJ) -laxtls +endif + +jar: $(OBJ) $(JAR) + +# if we are doing the samples then defer creating the jar until then +$(JAR): $(JAVA_CLASSES) +ifndef CONFIG_JAVA_SAMPLES + jar cvf $@ -C classes axTLSj +else + @if [ ! -f $(JAR) ]; then touch $(JAR); fi +endif + +classes/axTLSj/%.class : %.java + javac -d classes -classpath classes $^ + +clean:: + @rm -f $(JAR) $(TARGET) SWIG* axtls* *.i *.c + @rm -fr classes/* + diff --git a/circuitpython/lib/axtls/bindings/java/SSL.java b/circuitpython/lib/axtls/bindings/java/SSL.java new file mode 100644 index 0000000..e0400b6 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/java/SSL.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * A wrapper around the unmanaged interface to give a semi-decent Java API + */ + +package axTLSj; + +import java.io.*; +import java.util.*; + +/** + * @defgroup java_api Java API. + * + * Ensure that the appropriate dispose() methods are called when finished with + * various objects - otherwise memory leaks will result. + */ + +/** + * @class SSL + * @ingroup java_api + * @brief A representation of an SSL connection. + * + */ +public class SSL +{ + public int m_ssl; /**< A pointer to the real SSL type */ + + /** + * @brief Store the reference to an SSL context. + * @param ip [in] A reference to an SSL object. + */ + public SSL(int ip) + { + m_ssl = ip; + } + + /** + * @brief Free any used resources on this connection. + * + * A "Close Notify" message is sent on this connection (if possible). It + * is up to the application to close the socket. + */ + public void dispose() + { + axtlsj.ssl_free(m_ssl); + } + + /** + * @brief Return the result of a handshake. + * @return SSL_OK if the handshake is complete and ok. + * @see ssl.h for the error code list. + */ + public int handshakeStatus() + { + return axtlsj.ssl_handshake_status(m_ssl); + } + + /** + * @brief Return the SSL cipher id. + * @return The cipher id which is one of: + * - SSL_AES128_SHA (0x2f) + * - SSL_AES256_SHA (0x35) + * - SSL_AES128_SHA256 (0x3c) + * - SSL_AES256_SHA256 (0x3d) + */ + public byte getCipherId() + { + return axtlsj.ssl_get_cipher_id(m_ssl); + } + + /** + * @brief Get the session id for a handshake. + * + * This will be a 32 byte sequence and is available after the first + * handshaking messages are sent. + * @return The session id as a 32 byte sequence. + * @note A SSLv23 handshake may have only 16 valid bytes. + */ + public byte[] getSessionId() + { + return axtlsj.ssl_get_session_id(m_ssl); + } + + /** + * @brief Retrieve an X.509 distinguished name component. + * + * When a handshake is complete and a certificate has been exchanged, + * then the details of the remote certificate can be retrieved. + * + * This will usually be used by a client to check that the server's common + * name matches the URL. + * + * A full handshake needs to occur for this call to work. + * + * @param component [in] one of: + * - SSL_X509_CERT_COMMON_NAME + * - SSL_X509_CERT_ORGANIZATION + * - SSL_X509_CERT_ORGANIZATIONAL_NAME + * - SSL_X509_CA_CERT_COMMON_NAME + * - SSL_X509_CA_CERT_ORGANIZATION + * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME + * @return The appropriate string (or null if not defined) + */ + public String getCertificateDN(int component) + { + return axtlsj.ssl_get_cert_dn(m_ssl, component); + } +} diff --git a/circuitpython/lib/axtls/bindings/java/SSLCTX.java b/circuitpython/lib/axtls/bindings/java/SSLCTX.java new file mode 100644 index 0000000..1cd3e03 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/java/SSLCTX.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * A wrapper around the unmanaged interface to give a semi-decent Java API + */ + +package axTLSj; + +import java.net.*; + +/** + * @class SSLCTX + * @ingroup java_api + * @brief A base object for SSLServer/SSLClient. + */ +public class SSLCTX +{ + /** + * A reference to the real client/server context. + */ + protected int m_ctx; + + /** + * @brief Establish a new client/server context. + * + * This function is called before any client/server SSL connections are + * made. If multiple threads are used, then each thread will have its + * own SSLCTX context. Any number of connections may be made with a single + * context. + * + * Each new connection will use the this context's private key and + * certificate chain. If a different certificate chain is required, then a + * different context needs to be be used. + * + * @param options [in] Any particular options. At present the options + * supported are: + * - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the + * server authentication fails. The certificate can be authenticated later + * with a call to verifyCert(). + * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication + * i.e. each handshake will include a "certificate request" message from + * the server. + * - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences + * during the handshake. + * - SSL_DISPLAY_STATES (full mode build only): Display the state changes + * during the handshake. + * - SSL_DISPLAY_CERTS (full mode build only): Display the certificates that + * are passed during a handshake. + * - SSL_DISPLAY_RSA (full mode build only): Display the RSA key details + * that are passed during a handshake. + * + * @param num_sessions [in] The number of sessions to be used for session + * caching. If this value is 0, then there is no session caching. + * + * If this option is null, then the default internal private key/ + * certificate pair is used (if CONFIG_SSL_USE_DEFAULT_KEY is set). + * + * The resources used by this object are automatically freed. + * @return A client/server context. + */ + protected SSLCTX(int options, int num_sessions) + { + m_ctx = axtlsj.ssl_ctx_new(options, num_sessions); + } + + /** + * @brief Remove a client/server context. + * + * Frees any used resources used by this context. Each connection will be + * sent a "Close Notify" alert (if possible). + */ + public void dispose() + { + axtlsj.ssl_ctx_free(m_ctx); + } + + /** + * @brief Read the SSL data stream. + * @param ssl [in] An SSL object reference. + * @param rh [out] After a successful read, the decrypted data can be + * retrieved with rh.getData(). It will be null otherwise. + * @return The number of decrypted bytes: + * - if > 0, then the handshaking is complete and we are returning the + * number of decrypted bytes. + * - SSL_OK if the handshaking stage is successful (but not yet complete). + * - < 0 if an error. + * @see ssl.h for the error code list. + * @note Use rh before doing any successive ssl calls. + */ + public int read(SSL ssl, SSLReadHolder rh) + { + return axtlsj.ssl_read(ssl.m_ssl, rh); + } + + /** + * @brief Write to the SSL data stream. + * @param ssl [in] An SSL obect reference. + * @param out_data [in] The data to be written + * @return The number of bytes sent, or if < 0 if an error. + * @see ssl.h for the error code list. + */ + public int write(SSL ssl, byte[] out_data) + { + return axtlsj.ssl_write(ssl.m_ssl, out_data, out_data.length); + } + + /** + * @brief Write to the SSL data stream. + * @param ssl [in] An SSL obect reference. + * @param out_data [in] The data to be written + * @param out_len [in] The number of bytes to be written + * @return The number of bytes sent, or if < 0 if an error. + * @see ssl.h for the error code list. + */ + public int write(SSL ssl, byte[] out_data, int out_len) + { + return axtlsj.ssl_write(ssl.m_ssl, out_data, out_len); + } + + /** + * @brief Find an ssl object based on a Socket reference. + * + * Goes through the list of SSL objects maintained in a client/server + * context to look for a socket match. + * @param s [in] A reference to a Socket object. + * @return A reference to the SSL object. Returns null if the object + * could not be found. + */ + public SSL find(Socket s) + { + int client_fd = axtlsj.getFd(s); + return new SSL(axtlsj.ssl_find(m_ctx, client_fd)); + } + + /** + * @brief Authenticate a received certificate. + * + * This call is usually made by a client after a handshake is complete + * and the context is in SSL_SERVER_VERIFY_LATER mode. + * @param ssl [in] An SSL object reference. + * @return SSL_OK if the certificate is verified. + */ + public int verifyCert(SSL ssl) + { + return axtlsj.ssl_verify_cert(ssl.m_ssl); + } + + /** + * @brief Force the client to perform its handshake again. + * + * For a client this involves sending another "client hello" message. + * For the server is means sending a "hello request" message. + * + * This is a blocking call on the client (until the handshake completes). + * @param ssl [in] An SSL object reference. + * @return SSL_OK if renegotiation instantiation was ok + */ + public int renegotiate(SSL ssl) + { + return axtlsj.ssl_renegotiate(ssl.m_ssl); + } + + /** + * @brief Load a file into memory that is in binary DER or ASCII PEM format. + * + * These are temporary objects that are used to load private keys, + * certificates etc into memory. + * @param obj_type [in] The format of the file. Can be one of: + * - SSL_OBJ_X509_CERT (no password required) + * - SSL_OBJ_X509_CACERT (no password required) + * - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported) + * - SSL_OBJ_P8 (RC4-128 encrypted data supported) + * - SSL_OBJ_P12 (RC4-128 encrypted data supported) + * + * PEM files are automatically detected (if supported). + * @param filename [in] The location of a file in DER/PEM format. + * @param password [in] The password used. Can be null if not required. + * @return SSL_OK if all ok + */ + public int objLoad(int obj_type, String filename, String password) + { + return axtlsj.ssl_obj_load(m_ctx, obj_type, filename, password); + } + + /** + * @brief Transfer binary data into the object loader. + * + * These are temporary objects that are used to load private keys, + * certificates etc into memory. + * @param obj_type [in] The format of the memory data. + * @param data [in] The binary data to be loaded. + * @param len [in] The amount of data to be loaded. + * @param password [in] The password used. Can be null if not required. + * @return SSL_OK if all ok + */ + + public int objLoad(int obj_type, byte[] data, int len, String password) + { + return axtlsj.ssl_obj_memory_load(m_ctx, obj_type, data, len, password); + } +} diff --git a/circuitpython/lib/axtls/bindings/java/SSLClient.java b/circuitpython/lib/axtls/bindings/java/SSLClient.java new file mode 100644 index 0000000..f65fe9c --- /dev/null +++ b/circuitpython/lib/axtls/bindings/java/SSLClient.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * A wrapper around the unmanaged interface to give a semi-decent Java API + */ + +package axTLSj; + +import java.net.*; + +/** + * @class SSLClient + * @ingroup java_api + * @brief The client context. + * + * All client connections are started within a client context. + */ +public class SSLClient extends SSLCTX +{ + /** + * @brief Start a new client context. + * + * @see SSLCTX for details. + */ + public SSLClient(int options, int num_sessions) + { + super(options, num_sessions); + } + + /** + * @brief Establish a new SSL connection to an SSL server. + * + * It is up to the application to establish the initial socket connection. + * + * This is a blocking call - it will finish when the handshake is + * complete (or has failed). + * + * Call dispose() when the connection is to be removed. + * @param s [in] A reference to a Socket object. + * @param session_id [in] A 32 byte session id for session resumption. This + * can be null if no session resumption is not required. + * @return An SSL object reference. Use SSL.handshakeStatus() to check + * if a handshake succeeded. + */ + public SSL connect(Socket s, byte[] session_id) + { + int client_fd = axtlsj.getFd(s); + byte sess_id_size = (byte)(session_id != null ? + session_id.length : 0); + return new SSL(axtlsj.ssl_client_new(m_ctx, client_fd, session_id, + sess_id_size)); + } +} diff --git a/circuitpython/lib/axtls/bindings/java/SSLReadHolder.java b/circuitpython/lib/axtls/bindings/java/SSLReadHolder.java new file mode 100644 index 0000000..91fd76b --- /dev/null +++ b/circuitpython/lib/axtls/bindings/java/SSLReadHolder.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * A wrapper around the unmanaged interface to give a semi-decent Java API + */ + +package axTLSj; + +/** + * @class SSLReadHolder + * @ingroup java_api + * @brief A holder for data read in an SSL read. + */ +public class SSLReadHolder +{ + /** + * @brief Contruct a new read holder object. + */ + public SSLReadHolder() + { + m_buf = null; + } + + /** + * @brief Retrieve the reference to the read data. + */ + public byte[] getData() + { + return m_buf; + } + + private byte[] m_buf; +} diff --git a/circuitpython/lib/axtls/bindings/java/SSLServer.java b/circuitpython/lib/axtls/bindings/java/SSLServer.java new file mode 100644 index 0000000..514ccb0 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/java/SSLServer.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * A wrapper around the unmanaged interface to give a semi-decent Java API + */ + +package axTLSj; + +import java.net.*; + +/** + * @class SSLServer + * @ingroup java_api + * @brief The server context. + * + * All server connections are started within a server context. + */ +public class SSLServer extends SSLCTX +{ + /** + * @brief Start a new server context. + * + * @see SSLCTX for details. + */ + public SSLServer(int options, int num_sessions) + { + super(options, num_sessions); + } + + /** + * @brief Establish a new SSL connection to an SSL client. + * + * It is up to the application to establish the initial socket connection. + * + * Call dispose() when the connection is to be removed. + * @param s [in] A reference to a Socket object. + * @return An SSL object reference. + */ + public SSL connect(Socket s) + { + int client_fd = axtlsj.getFd(s); + return new SSL(axtlsj.ssl_server_new(m_ctx, client_fd)); + } +} diff --git a/circuitpython/lib/axtls/bindings/java/SSLUtil.java b/circuitpython/lib/axtls/bindings/java/SSLUtil.java new file mode 100644 index 0000000..3d53de5 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/java/SSLUtil.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * A wrapper around the unmanaged interface to give a semi-decent Java API + */ + +package axTLSj; + +import java.io.*; +import java.util.*; + +/** + * @class SSLUtil + * @ingroup java_api + * @brief Some global helper functions. + * + */ +public class SSLUtil +{ + /** + * @brief Load up the ddl/shared library + */ + static + { + System.loadLibrary("axtlsj"); + } + + /** + * @brief Return the build mode of the axTLS project. + * @return The build mode is one of: + * - SSL_BUILD_SERVER_ONLY + * - SSL_BUILD_ENABLE_VERIFICATION + * - SSL_BUILD_ENABLE_CLIENT + * - SSL_BUILD_FULL_MODE + */ + public static int buildMode() + { + return axtlsj.ssl_get_config(axtlsj.SSL_BUILD_MODE); + } + + /** + * @brief Return the number of chained certificates that the client/server + * supports. + * @return The number of supported client/server certificates. + */ + public static int maxCerts() + { + return axtlsj.ssl_get_config(axtlsj.SSL_MAX_CERT_CFG_OFFSET); + } + + /** + * @brief Return the number of CA certificates that the client/server + * supports. + * @return The number of supported CA certificates. + */ + public static int maxCACerts() + { + return axtlsj.ssl_get_config(axtlsj.SSL_MAX_CA_CERT_CFG_OFFSET); + } + + /** + * @brief Indicate if PEM is supported. + * @return true if PEM supported. + */ + public static boolean hasPEM() + { + return axtlsj.ssl_get_config(axtlsj.SSL_HAS_PEM) > 0 ? true : false; + } + + /** + * @brief Display the text string of the error. + * @param error_code [in] The integer error code. + * @see ssl.h for the error code list. + */ + public static void displayError(int error_code) + { + axtlsj.ssl_display_error(error_code); + } + + /** + * @brief Return the version of the axTLS project. + */ + public static String version() + { + return axtlsj.ssl_version(); + } +} + diff --git a/circuitpython/lib/axtls/bindings/lua/Makefile b/circuitpython/lib/axtls/bindings/lua/Makefile new file mode 100644 index 0000000..daacf92 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/lua/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +AXTLS_HOME=../.. + +include $(AXTLS_HOME)/config/.config +include $(AXTLS_HOME)/config/makefile.conf + +all: lib + + +ifdef CONFIG_PLATFORM_WIN32 +TARGET=$(AXTLS_HOME)/$(STAGE)/axtlsl.dll +else +TARGET=$(CONFIG_LUA_CORE)/lib/lua/5.1/axtlsl.so +endif + +ifneq ($(MAKECMDGOALS), clean) + +lib: $(TARGET) +OBJ:=axTLSl_wrap.o +include $(AXTLS_HOME)/config/makefile.post + +# there are a few static functions that aren't used +CFLAGS += -funit-at-a-time + +$(TARGET) : $(OBJ) + $(LD) $(LDFLAGS) $(LDSHARED) -o $@ $^ -L$(AXTLS_HOME)/$(STAGE) -L$(CONFIG_LUA_CORE)/lib -laxtls -llua + +CFLAGS += -I $(CONFIG_LUA_CORE)/include +else +CFLAGS += /I"`cygpath -w $(CONFIG_LUA_CORE)/include`" +LDFLAGS += axtls.lib /libpath:"$(AXTLS_HOME)/$(STAGE)" + +$(TARGET) : $(OBJ) + $(LD) $(LDFLAGS) $(LDSHARED) /out:$@ $(OBJ) +endif # WIN32 + +clean:: + @rm -f $(TARGET) *.i axTLSl* .depend diff --git a/circuitpython/lib/axtls/bindings/perl/Makefile b/circuitpython/lib/axtls/bindings/perl/Makefile new file mode 100644 index 0000000..92fd3c5 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/perl/Makefile @@ -0,0 +1,91 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +AXTLS_HOME=../.. + +include $(AXTLS_HOME)/config/.config +include $(AXTLS_HOME)/config/makefile.conf + +all: lib + +ifdef CONFIG_PLATFORM_WIN32 +TARGET=$(AXTLS_HOME)/$(STAGE)/axtlsp.dll +else +TARGET=$(AXTLS_HOME)/$(STAGE)/libaxtlsp.so +endif + +ifneq ($(MAKECMDGOALS), clean) + +ifdef CONFIG_PLATFORM_WIN32 +PERL5_CORE:=$(shell cygpath -w "$(CONFIG_PERL_CORE)") +else +PERL5_CORE= $(shell perl -e 'use Config; print $$Config{archlib};')/CORE +endif + +all: test_perl + +test_perl: + @if ! [ -d "$(PERL5_CORE)" ]; then \ + echo "*** Error: Perl not installed at $(CONFIG_PERL_CORE) - go to " \ + "http://www.cpan.org/authors/id/G/GR/GRAHAMC/SiePerl-5.8.0-bin-1.0-Win32.INSTALL.exe" && exit 1; \ + fi + +endif + +lib: $(TARGET) +OBJ:=axTLSp_wrap.o +include $(AXTLS_HOME)/config/makefile.post + +ifndef CONFIG_PLATFORM_WIN32 # Linux/Unix/Cygwin + +# +# Could have used libperl.a, but it increases the library to over 1MB, so just +# use libperl.so. But this needs to be in the shared library path for things to +# work. +# +$(TARGET) : $(OBJ) + $(LD) $(LDFLAGS) -L$(AXTLS_HOME)/$(STAGE) -L$(PERL5_CORE) $(LDSHARED) -o $@ $(OBJ) -laxtls -lperl +ifdef CONFIG_PLATFORM_CYGWIN + cd $(AXTLS_HOME)/$(STAGE); ln -sf $(notdir $@) axtlsp.dll +endif + @install axtlsp.pm $(AXTLS_HOME)/$(STAGE) + +CFLAGS += -D_GNU_SOURCE -I$(PERL5_CORE) +else +CFLAGS += /I"$(PERL5_CORE)" +LDFLAGS += $(CONFIG_PERL_LIB) /libpath:"$(PERL5_CORE)" axtls.lib /libpath:"$(AXTLS_HOME)/$(STAGE)" + +$(TARGET) : $(OBJ) + $(LD) $(LDFLAGS) $(LDSHARED) /out:$@ $(OBJ) + install axtlsp.pm $(AXTLS_HOME)/$(STAGE) +endif # WIN32 + +clean:: + @rm -f $(TARGET) axtls* *.i axTLSp* *.c .depend $(AXTLS_HOME)/$(STAGE)/axtlsp.pm diff --git a/circuitpython/lib/axtls/bindings/vbnet/Makefile b/circuitpython/lib/axtls/bindings/vbnet/Makefile new file mode 100644 index 0000000..7da60d0 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/vbnet/Makefile @@ -0,0 +1,35 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 ../../config/.config +include ../../config/makefile.conf + +clean:: + @rm -f axssl* axInterface.vb diff --git a/circuitpython/lib/axtls/bindings/vbnet/axTLSvb.vb b/circuitpython/lib/axtls/bindings/vbnet/axTLSvb.vb new file mode 100644 index 0000000..9388273 --- /dev/null +++ b/circuitpython/lib/axtls/bindings/vbnet/axTLSvb.vb @@ -0,0 +1,200 @@ +' +' Copyright (c) 2007, Cameron Rich +' +' 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 axTLS project 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. +' + +' +' A wrapper around the unmanaged Integererface to give a semi-decent VB.NET API +' + +Imports System +Imports System.Runtime.InteropServices +Imports System.Net.Sockets +Imports axTLSvb + +Namespace axTLSvb + Public Class SSL + Public m_ssl As IntPtr + + Public Sub New(ByRef ip As IntPtr) + m_ssl = ip + End Sub + + Public Sub Dispose() + axtls.ssl_free(m_ssl) + End Sub + + Public Function HandshakeStatus() As Integer + Return axtls.ssl_handshake_status(m_ssl) + End Function + + Public Function GetCipherId() As Byte + Return axtls.ssl_get_cipher_id(m_ssl) + End Function + + Public Function GetSessionId() As Byte() + Dim ptr As IntPtr = axtls.ssl_get_session_id(m_ssl) + Dim sess_id_size As Integer = axtls.ssl_get_session_id_size(m_ssl) + Dim result(sess_id_size-1) As Byte + Marshal.Copy(ptr, result, 0, sess_id_size) + Return result + End Function + + Public Function GetCertificateDN(component As Integer) As String + Return axtls.ssl_get_cert_dn(m_ssl, component) + End Function + End Class + + Public Class SSLUtil + Private dummy As Integer ' need something here + + Public Shared Function BuildMode() As Integer + Return axtls.ssl_get_config(axtls.SSL_BUILD_MODE) + End Function + + Public Shared Function MaxCerts() As Integer + Return axtls.ssl_get_config(axtls.SSL_MAX_CERT_CFG_OFFSET) + End Function + + Public Shared Function MaxCACerts() As Integer + Return axtls.ssl_get_config(axtls.SSL_MAX_CA_CERT_CFG_OFFSET) + End Function + + Public Shared Function HasPEM() As Boolean + If axtls.ssl_get_config(axtls.SSL_HAS_PEM) > 0 Then + Return True + Else + Return False + End If + End Function + + Public Shared Sub DisplayError(ByVal error_code As Integer) + axtls.ssl_display_error(error_code) + End Sub + + Public Shared Function Version() As String + Return axtls.ssl_version() + End Function + End Class + + Public Class SSLCTX + Protected m_ctx As IntPtr + + Protected Sub New(ByVal options As Integer, _ + ByVal num_sessions As Integer) + m_ctx = axtls.ssl_ctx_new(options, num_sessions) + End Sub + + Public Sub Dispose() + axtls.ssl_ctx_free(m_ctx) + End Sub + + Public Function Read(ByVal ssl As SSL, ByRef in_data As Byte()) As Integer + Dim ptr As IntPtr = IntPtr.Zero + Dim ret as Integer = axtls.ssl_read(ssl.m_ssl, ptr) + + If ret > axtls.SSL_OK Then + ReDim in_data(ret) + Marshal.Copy(ptr, in_data, 0, ret) + Else + in_data = Nothing + End If + + Return ret + End Function + + Public Function Write(ByVal ssl As SSL, _ + ByVal data As Byte(), len As Integer) As Integer + Return axtls.ssl_write(ssl.m_ssl, data, len) + End Function + + Public Function Find(ByVal s As Socket) As SSL + Dim client_fd As Integer = s.Handle.ToInt32() + Return New SSL(axtls.ssl_find(m_ctx, client_fd)) + End Function + + Public Function VerifyCert(ByVal ssl As SSL) As Integer + Return axtls.ssl_verify_cert(ssl.m_ssl) + End Function + + Public Function Renegotiate(ByVal ssl As SSL) As Integer + Return axtls.ssl_renegotiate(ssl.m_ssl) + End Function + + Public Function ObjLoad(ByVal obj_type As Integer, _ + ByVal filename As String, _ + password As String) As Integer + Return axtls.ssl_obj_load(m_ctx, obj_type, filename, password) + End Function + + Public Function ObjLoad(ByVal obj_type As Integer, _ + ByVal data As Byte(), ByVal len As Integer, _ + password As String) As Integer + Return axtls.ssl_obj_memory_load( _ + m_ctx, obj_type, data, len, password) + End Function + End Class + + Public Class SSLServer + Inherits SSLCTX + + Public Sub New(ByVal options As Integer, _ + ByVal num_sessions As Integer) + MyBase.New(options, num_sessions) + End Sub + + Public Function Connect(ByVal s As Socket) As SSL + Dim client_fd As Integer = s.Handle.ToInt32() + Return New SSL(axtls.ssl_server_new(m_ctx, client_fd)) + End Function + End Class + + Public Class SSLClient + Inherits SSLCTX + + Public Sub New(ByVal options As Integer, _ + ByVal num_sessions As Integer) + MyBase.New(options, num_sessions) + End Sub + + Public Function Connect(ByVal s As Socket, _ + ByVal session_id As Byte()) As SSL + Dim client_fd As Integer = s.Handle.ToInt32() + Dim sess_id_size As Byte + If session_id is Nothing Then + sess_id_size = 0 + Else + sess_id_size = session_id.Length + End If + + Return New SSL(axtls.ssl_client_new(m_ctx, client_fd, session_id, _ + sess_id_size)) + End Function + + End Class +End Namespace diff --git a/circuitpython/lib/axtls/config/Config.in b/circuitpython/lib/axtls/config/Config.in new file mode 100644 index 0000000..c42bcef --- /dev/null +++ b/circuitpython/lib/axtls/config/Config.in @@ -0,0 +1,130 @@ +# +# For a description of the syntax of this configuration file, +# see scripts/config/Kconfig-language.txt +# + +mainmenu "axTLS Configuration" + +config HAVE_DOT_CONFIG + bool + default y + +choice + prompt "Platform" + default CONFIG_PLATFORM_LINUX + +config CONFIG_PLATFORM_LINUX + bool "Linux" + +config CONFIG_PLATFORM_CYGWIN + bool "Cygwin" + +config CONFIG_PLATFORM_WIN32 + bool "Win32" + +endchoice + +menu "General Configuration" + +config PREFIX + string "axTLS installation prefix" + depends on !CONFIG_PLATFORM_WIN32 + default "/usr/local" + help + Define your directory to install axTLS files/subdirs in. + +config CONFIG_DEBUG + bool "Build axTLS with Debugging symbols" + default n + help + Say Y here if you wish to compile axTLS with debugging symbols. + This will allow you to use a debugger to examine axTLS internals. + This increases the size of the binary considerably and should only be + used when doing development. + If you are doing development and want to debug axTLS, answer Y. + + Most people should answer N. + +config CONFIG_STRIP_UNWANTED_SECTIONS + depends on !CONFIG_PLATFORM_WIN32 && !CONFIG_DEBUG + bool "Strip unwanted sections from elf binaries" + default y + help + Strip unwanted sections from the resulting binaries + +menu "Microsoft Compiler Options" +depends on CONFIG_PLATFORM_WIN32 + +choice + prompt "Compiler" + depends on CONFIG_PLATFORM_WIN32 + default CONFIG_VISUAL_STUDIO_10_0 + +config CONFIG_VISUAL_STUDIO_7_0 + bool "Visual Studio 7.0 (2003)" + help + Use Microsoft's Visual Studio 2003 platform. + +config CONFIG_VISUAL_STUDIO_8_0 + bool "Visual Studio 8.0 (2005)" + help + Use Microsoft's Visual Studio 2005 platform. + +config CONFIG_VISUAL_STUDIO_10_0 + bool "Visual Studio 10.0 (2010)" + help + Use Microsoft's Visual Studio 2010 platform. +endchoice + +config CONFIG_VISUAL_STUDIO_7_0_BASE + string "Base" + depends on CONFIG_VISUAL_STUDIO_7_0 + default "c:\\Program Files\\Microsoft Visual Studio .NET 2003" + +config CONFIG_VISUAL_STUDIO_8_0_BASE + string "Base" + depends on CONFIG_VISUAL_STUDIO_8_0 + default "c:\\Program Files\\Microsoft Visual Studio 8" + +config CONFIG_VISUAL_STUDIO_10_0_BASE + string "Base" + depends on CONFIG_VISUAL_STUDIO_10_0 + default "c:\\Program Files\\Microsoft Visual Studio 10.0" +endmenu + +config CONFIG_EXTRA_CFLAGS_OPTIONS + string "Any extra CFLAGS options for the compiler?" + help + Do you want to pass any extra CFLAGS options to the compiler as + you build axTLS? If so, this is the option for you... For + example, if you want to add some simple compiler switches (like + -march=i686), or check for warnings using -Werror, just those + options here. + +config CONFIG_EXTRA_LDFLAGS_OPTIONS + string "Any extra LDFLAGS options for the compiler?" + help + Do you want to pass any extra LDFLAGS options to the compiler? + +endmenu + +source ssl/Config.in +config CONFIG_AXTLSWRAP + depends on !CONFIG_PLATFORM_WIN32 + bool "Enable axtlswrap" + default n + help + axtlswrap is similar to sslwrap - http://www.rickk.com/sslwrap. + It enables SSL for processes that don't have native SSL support. + +config CONFIG_AXHTTPD + bool "Enable HTTP/HTTPS Web Server" + default y + help + Build the AXHTTPD web server + +source httpd/Config.in +source bindings/Config.in +source samples/Config.in +source ssl/BigIntConfig.in + diff --git a/circuitpython/lib/axtls/config/JMeter.jmx b/circuitpython/lib/axtls/config/JMeter.jmx new file mode 100755 index 0000000..f62c03f --- /dev/null +++ b/circuitpython/lib/axtls/config/JMeter.jmx @@ -0,0 +1,247 @@ + + + + + + + + true + false + + + + + 1152004173000 + + + 16 + false + + 10 + false + + 1152004173000 + stopthread + 0 + + + + /index.html + GET + true + + true + 80 + + + + + + false + 127.0.0.1 + + false + + + + + 1152004173000 + + + 16 + false + + 10 + false + + 1152004173000 + stopthread + 0 + + + + /index.html + GET + true + HTTPS + true + 443 + + + + + + false + 127.0.0.1 + + false + + + + + 1152004173000 + + + 16 + false + + 10 + false + + 1152004173000 + stopthread + 0 + + + + /index.html + GET + true + HTTPS + true + 2443 + + + + + + false + 127.0.0.1 + + false + + + + + 1152004173000 + + + 16 + false + + 10 + false + + 1152004173000 + stopthread + 0 + + + + /index.html + GET + true + HTTPS + true + 3443 + + + + + + false + 127.0.0.1 + + false + + + + + 1152004173000 + + + 16 + false + + 10 + false + + 1152004173000 + stopthread + 0 + + + + /index.html + GET + true + HTTPS + true + 1443 + + + + + + false + 127.0.0.1 + + false + + + + + + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + false + false + false + false + false + 0 + + saveConfig + + + false + + + + + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + false + false + false + false + false + 0 + + saveConfig + + + false + + + + + diff --git a/circuitpython/lib/axtls/config/Rules.mak b/circuitpython/lib/axtls/config/Rules.mak new file mode 100644 index 0000000..7b6f2b3 --- /dev/null +++ b/circuitpython/lib/axtls/config/Rules.mak @@ -0,0 +1,221 @@ +# Rules.make for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under GPLv2, see the file LICENSE in this tarball for details. +# + +# Pull in the user's busybox configuration +ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),) +-include $(top_builddir)/.config +endif + +#-------------------------------------------------------- +PROG := busybox +MAJOR_VERSION :=1 +MINOR_VERSION :=1 +SUBLEVEL_VERSION:=0 +EXTRAVERSION := +VERSION :=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL_VERSION)$(EXTRAVERSION) +BUILDTIME := $(shell TZ=UTC date -u "+%Y.%m.%d-%H:%M%z") + + +#-------------------------------------------------------- +# With a modern GNU make(1) (highly recommended, that's what all the +# developers use), all of the following configuration values can be +# overridden at the command line. For example: +# make CROSS=powerpc-linux- top_srcdir="$HOME/busybox" PREFIX=/mnt/app +#-------------------------------------------------------- + +# If you are running a cross compiler, you will want to set 'CROSS' +# to something more interesting... Target architecture is determined +# by asking the CC compiler what arch it compiles things for, so unless +# your compiler is broken, you should not need to specify TARGET_ARCH +CROSS =$(subst ",, $(strip $(CROSS_COMPILER_PREFIX))) +CC = $(CROSS)gcc +AR = $(CROSS)ar +AS = $(CROSS)as +LD = $(CROSS)ld +NM = $(CROSS)nm +STRIP = $(CROSS)strip +CPP = $(CC) -E +# MAKEFILES = $(top_builddir)/.config +RM = rm +RM_F = $(RM) -f +LN = ln +LN_S = $(LN) -s +MKDIR = mkdir +MKDIR_P = $(MKDIR) -p +MV = mv +CP = cp + + +# What OS are you compiling busybox for? This allows you to include +# OS specific things, syscall overrides, etc. +TARGET_OS=linux + +# Select the compiler needed to build binaries for your development system +HOSTCC = gcc +HOSTCFLAGS= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer + +# Ensure consistent sort order, 'gcc -print-search-dirs' behavior, etc. +LC_ALL:= C + +# If you want to add some simple compiler switches (like -march=i686), +# especially from the command line, use this instead of CFLAGS directly. +# For optimization overrides, it's better still to set OPTIMIZATION. +CFLAGS_EXTRA=$(subst ",, $(strip $(EXTRA_CFLAGS_OPTIONS))) + +# To compile vs some other alternative libc, you may need to use/adjust +# the following lines to meet your needs... +# +# If you are using Red Hat 6.x with the compatible RPMs (for developing under +# Red Hat 5.x and glibc 2.0) uncomment the following. Be sure to read about +# using the compatible RPMs (compat-*) at http://www.redhat.com ! +#LIBCDIR:=/usr/i386-glibc20-linux +# +# For other libraries, you are on your own. But these may (or may not) help... +#LDFLAGS+=-nostdlib +#LIBRARIES:=$(LIBCDIR)/lib/libc.a -lgcc +#CROSS_CFLAGS+=-nostdinc -I$(LIBCDIR)/include -I$(GCCINCDIR) -funsigned-char +#GCCINCDIR:=$(shell gcc -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp") + +WARNINGS=-Wall -Wstrict-prototypes -Wshadow +CFLAGS=-I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir) +ARFLAGS=cru + + +# gcc centric. Perhaps fiddle with findstring gcc,$(CC) for the rest +# get the CC MAJOR/MINOR version +CC_MAJOR:=$(shell printf "%02d" $(shell echo __GNUC__ | $(CC) -E -xc - | tail -n 1)) +CC_MINOR:=$(shell printf "%02d" $(shell echo __GNUC_MINOR__ | $(CC) -E -xc - | tail -n 1)) + +#-------------------------------------------------------- +export VERSION BUILDTIME HOSTCC HOSTCFLAGS CROSS CC AR AS LD NM STRIP CPP +ifeq ($(strip $(TARGET_ARCH)),) +TARGET_ARCH:=$(shell $(CC) -dumpmachine | sed -e s'/-.*//' \ + -e 's/i.86/i386/' \ + -e 's/sparc.*/sparc/' \ + -e 's/arm.*/arm/g' \ + -e 's/m68k.*/m68k/' \ + -e 's/ppc/powerpc/g' \ + -e 's/v850.*/v850/g' \ + -e 's/sh[234]/sh/' \ + -e 's/mips-.*/mips/' \ + -e 's/mipsel-.*/mipsel/' \ + -e 's/cris.*/cris/' \ + ) +endif + +# A nifty macro to make testing gcc features easier +check_gcc=$(shell \ + if [ "$(1)" != "" ]; then \ + if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \ + then echo "$(1)"; else echo "$(2)"; fi \ + fi) + +# Setup some shortcuts so that silent mode is silent like it should be +ifeq ($(subst s,,$(MAKEFLAGS)),$(MAKEFLAGS)) +export MAKE_IS_SILENT=n +SECHO=@echo +else +export MAKE_IS_SILENT=y +SECHO=-@false +endif + +CFLAGS+=$(call check_gcc,-funsigned-char,) + +#-------------------------------------------------------- +# Arch specific compiler optimization stuff should go here. +# Unless you want to override the defaults, do not set anything +# for OPTIMIZATION... + +# use '-Os' optimization if available, else use -O2 +OPTIMIZATION:=$(call check_gcc,-Os,-O2) + +# Some nice architecture specific optimizations +ifeq ($(strip $(TARGET_ARCH)),arm) + OPTIMIZATION+=-fstrict-aliasing +endif +ifeq ($(strip $(TARGET_ARCH)),i386) + OPTIMIZATION+=$(call check_gcc,-march=i386,) + OPTIMIZATION+=$(call check_gcc,-mpreferred-stack-boundary=2,) + OPTIMIZATION+=$(call check_gcc,-falign-functions=0 -falign-jumps=0 -falign-loops=0,\ + -malign-functions=0 -malign-jumps=0 -malign-loops=0) +endif +OPTIMIZATIONS:=$(OPTIMIZATION) -fomit-frame-pointer + +# +#-------------------------------------------------------- +# If you're going to do a lot of builds with a non-vanilla configuration, +# it makes sense to adjust parameters above, so you can type "make" +# by itself, instead of following it by the same half-dozen overrides +# every time. The stuff below, on the other hand, is probably less +# prone to casual user adjustment. +# + +ifeq ($(strip $(CONFIG_LFS)),y) + # For large file summit support + CFLAGS+=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +endif +ifeq ($(strip $(CONFIG_DMALLOC)),y) + # For testing mem leaks with dmalloc + CFLAGS+=-DDMALLOC + LIBRARIES:=-ldmalloc +else + ifeq ($(strip $(CONFIG_EFENCE)),y) + LIBRARIES:=-lefence + endif +endif +ifeq ($(strip $(CONFIG_DEBUG)),y) + CFLAGS +=$(WARNINGS) -g -D_GNU_SOURCE + LDFLAGS +=-Wl,-warn-common + STRIPCMD:=/bin/true -Not_stripping_since_we_are_debugging +else + CFLAGS+=$(WARNINGS) $(OPTIMIZATIONS) -D_GNU_SOURCE -DNDEBUG + LDFLAGS += -Wl,-warn-common + STRIPCMD:=echo + #$(STRIP) -s --remove-section=.note --remove-section=.comment +endif +ifeq ($(strip $(CONFIG_STATIC)),y) + LDFLAGS += --static +endif + +ifeq ($(strip $(CONFIG_SELINUX)),y) + LIBRARIES += -lselinux +endif + +ifeq ($(strip $(PREFIX)),) + PREFIX:=`pwd`/_install +endif + +# Additional complications due to support for pristine source dir. +# Include files in the build directory should take precedence over +# the copy in top_srcdir, both during the compilation phase and the +# shell script that finds the list of object files. +# Work in progress by . + + +OBJECTS:=$(APPLET_SOURCES:.c=.o) busybox.o usage.o applets.o +CFLAGS += $(CROSS_CFLAGS) +ifdef BB_INIT_SCRIPT + CFLAGS += -DINIT_SCRIPT='"$(BB_INIT_SCRIPT)"' +endif + +# Put user-supplied flags at the end, where they +# have a chance of winning. +CFLAGS += $(CFLAGS_EXTRA) + +#------------------------------------------------------------ +# Installation options +ifeq ($(strip $(CONFIG_INSTALL_APPLET_HARDLINKS)),y) +INSTALL_OPTS=--hardlinks +endif +ifeq ($(strip $(CONFIG_INSTALL_APPLET_SYMLINKS)),y) +INSTALL_OPTS=--symlinks +endif +ifeq ($(strip $(CONFIG_INSTALL_APPLET_DONT)),y) +INSTALL_OPTS= +endif + +.PHONY: dummy diff --git a/circuitpython/lib/axtls/config/axhttpd.aip b/circuitpython/lib/axtls/config/axhttpd.aip new file mode 100755 index 0000000..412fe3b --- /dev/null +++ b/circuitpython/lib/axtls/config/axhttpd.aip @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/circuitpython/lib/axtls/config/axtls.RES b/circuitpython/lib/axtls/config/axtls.RES new file mode 100644 index 0000000..2929b3b Binary files /dev/null and b/circuitpython/lib/axtls/config/axtls.RES differ diff --git a/circuitpython/lib/axtls/config/axtls.rc b/circuitpython/lib/axtls/config/axtls.rc new file mode 100644 index 0000000..0f288aa --- /dev/null +++ b/circuitpython/lib/axtls/config/axtls.rc @@ -0,0 +1,32 @@ +//Microsoft Visual C++ generated resource script. +// +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#undef APSTUDIO_HIDDEN_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE 9, 1 +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. + +IDI_AXTLS ICON "../www/favicon.ico" + + +#endif +///////////////////////////////////////////////////////////////////////////// + + + diff --git a/circuitpython/lib/axtls/config/linuxconfig b/circuitpython/lib/axtls/config/linuxconfig new file mode 100644 index 0000000..d78eaa7 --- /dev/null +++ b/circuitpython/lib/axtls/config/linuxconfig @@ -0,0 +1,126 @@ +# +# Automatically generated make config: don't edit +# +HAVE_DOT_CONFIG=y +CONFIG_PLATFORM_LINUX=y +# CONFIG_PLATFORM_CYGWIN is not set +# CONFIG_PLATFORM_WIN32 is not set + +# +# General Configuration +# +PREFIX="/usr/local" +# CONFIG_DEBUG is not set +CONFIG_STRIP_UNWANTED_SECTIONS=y +# CONFIG_VISUAL_STUDIO_7_0 is not set +# CONFIG_VISUAL_STUDIO_8_0 is not set +# CONFIG_VISUAL_STUDIO_10_0 is not set +CONFIG_VISUAL_STUDIO_7_0_BASE="" +CONFIG_VISUAL_STUDIO_8_0_BASE="" +CONFIG_VISUAL_STUDIO_10_0_BASE="" +CONFIG_EXTRA_CFLAGS_OPTIONS="" +CONFIG_EXTRA_LDFLAGS_OPTIONS="" + +# +# SSL Library +# +# CONFIG_SSL_SERVER_ONLY is not set +# CONFIG_SSL_CERT_VERIFICATION is not set +# CONFIG_SSL_ENABLE_CLIENT is not set +CONFIG_SSL_FULL_MODE=y +# CONFIG_SSL_SKELETON_MODE is not set +# CONFIG_SSL_PROT_LOW is not set +CONFIG_SSL_PROT_MEDIUM=y +# CONFIG_SSL_PROT_HIGH is not set +CONFIG_SSL_USE_DEFAULT_KEY=y +CONFIG_SSL_PRIVATE_KEY_LOCATION="" +CONFIG_SSL_PRIVATE_KEY_PASSWORD="" +CONFIG_SSL_X509_CERT_LOCATION="" +# CONFIG_SSL_GENERATE_X509_CERT is not set +CONFIG_SSL_X509_COMMON_NAME="" +CONFIG_SSL_X509_ORGANIZATION_NAME="" +CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME="" +# CONFIG_SSL_ENABLE_V23_HANDSHAKE is not set +CONFIG_SSL_HAS_PEM=y +CONFIG_SSL_USE_PKCS12=y +CONFIG_SSL_EXPIRY_TIME=24 +CONFIG_X509_MAX_CA_CERTS=150 +CONFIG_SSL_MAX_CERTS=3 +# CONFIG_SSL_CTX_MUTEXING is not set +CONFIG_USE_DEV_URANDOM=y +# CONFIG_WIN32_USE_CRYPTO_LIB is not set +# CONFIG_OPENSSL_COMPATIBLE is not set +# CONFIG_PERFORMANCE_TESTING is not set +# CONFIG_SSL_TEST is not set +# CONFIG_AXTLSWRAP is not set +CONFIG_AXHTTPD=y + +# +# Axhttpd Configuration +# +# CONFIG_HTTP_STATIC_BUILD is not set +CONFIG_HTTP_PORT=80 +CONFIG_HTTP_HTTPS_PORT=443 +CONFIG_HTTP_SESSION_CACHE_SIZE=5 +CONFIG_HTTP_WEBROOT="../www" +CONFIG_HTTP_TIMEOUT=300 + +# +# CGI +# +CONFIG_HTTP_HAS_CGI=y +CONFIG_HTTP_CGI_EXTENSIONS=".lua,.lp,.php" +CONFIG_HTTP_ENABLE_LUA=y +CONFIG_HTTP_LUA_PREFIX="/usr" +# CONFIG_HTTP_BUILD_LUA is not set +CONFIG_HTTP_CGI_LAUNCHER="/usr/bin/cgi" +CONFIG_HTTP_DIRECTORIES=y +CONFIG_HTTP_HAS_AUTHORIZATION=y +# CONFIG_HTTP_HAS_IPV6 is not set +# CONFIG_HTTP_ENABLE_DIFFERENT_USER is not set +CONFIG_HTTP_USER="" +CONFIG_HTTP_VERBOSE=y +# CONFIG_HTTP_IS_DAEMON is not set + +# +# Language Bindings +# +# CONFIG_BINDINGS is not set +# CONFIG_CSHARP_BINDINGS is not set +# CONFIG_VBNET_BINDINGS is not set +CONFIG_DOT_NET_FRAMEWORK_BASE="" +# CONFIG_JAVA_BINDINGS is not set +CONFIG_JAVA_HOME="" +# CONFIG_PERL_BINDINGS is not set +CONFIG_PERL_CORE="" +CONFIG_PERL_LIB="" +# CONFIG_LUA_BINDINGS is not set +CONFIG_LUA_CORE="" + +# +# Samples +# +CONFIG_SAMPLES=y +CONFIG_C_SAMPLES=y +# CONFIG_CSHARP_SAMPLES is not set +# CONFIG_VBNET_SAMPLES is not set +# CONFIG_JAVA_SAMPLES is not set +# CONFIG_PERL_SAMPLES is not set +# CONFIG_LUA_SAMPLES is not set + +# +# BigInt Options +# +# CONFIG_BIGINT_CLASSICAL is not set +# CONFIG_BIGINT_MONTGOMERY is not set +CONFIG_BIGINT_BARRETT=y +CONFIG_BIGINT_CRT=y +# CONFIG_BIGINT_KARATSUBA is not set +MUL_KARATSUBA_THRESH=0 +SQU_KARATSUBA_THRESH=0 +CONFIG_BIGINT_SLIDING_WINDOW=y +CONFIG_BIGINT_SQUARE=y +# CONFIG_BIGINT_CHECK_ON is not set +CONFIG_INTEGER_32BIT=y +# CONFIG_INTEGER_16BIT is not set +# CONFIG_INTEGER_8BIT is not set diff --git a/circuitpython/lib/axtls/config/makefile.conf b/circuitpython/lib/axtls/config/makefile.conf new file mode 100644 index 0000000..064458f --- /dev/null +++ b/circuitpython/lib/axtls/config/makefile.conf @@ -0,0 +1,138 @@ +# +# Copyright (c) 2007-2016, Cameron Rich +# +# 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 axTLS project 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. +# + +# +# A standard makefile for all makefiles +# + +# All executables and libraries go here +STAGE=./_stage + +ifneq ($(MAKECMDGOALS), clean) + +# Give an initial rule +all: + +# Win32 +ifdef CONFIG_PLATFORM_WIN32 + +ifdef CONFIG_VISUAL_STUDIO_7_0 +CONFIG_VISUAL_STUDIO_7_0_BASE_UNIX:=$(shell cygpath -u $(CONFIG_VISUAL_STUDIO_7_0_BASE)) +export INCLUDE=$(shell echo "$(CONFIG_VISUAL_STUDIO_7_0_BASE)\vc7\include;$(CONFIG_VISUAL_STUDIO_7_0_BASE)\vc7\platformsdk\include") +export LIB=$(shell echo "$(CONFIG_VISUAL_STUDIO_7_0_BASE)\vc7\\platformsdk\lib;$(CONFIG_VISUAL_STUDIO_7_0_BASE)\vc7\lib") +PATH:=$(CONFIG_VISUAL_STUDIO_7_0_BASE_UNIX)/vc7/bin:$(CONFIG_VISUAL_STUDIO_7_0_BASE_UNIX)/common7/ide:$(PATH) +endif +ifdef CONFIG_VISUAL_STUDIO_8_0 +CONFIG_VISUAL_STUDIO_8_0_BASE_UNIX:=$(shell cygpath -u $(CONFIG_VISUAL_STUDIO_8_0_BASE)) +export INCLUDE=$(shell echo "$(CONFIG_VISUAL_STUDIO_8_0_BASE)\vc\include;$(CONFIG_VISUAL_STUDIO_8_0_BASE)\vc\platformsdk\include") +export LIB=$(shell echo "$(CONFIG_VISUAL_STUDIO_8_0_BASE)\vc\platformsdk\lib;$(CONFIG_VISUAL_STUDIO_8_0_BASE)\vc\lib") +PATH:=$(CONFIG_VISUAL_STUDIO_8_0_BASE_UNIX)/vc/bin:$(CONFIG_VISUAL_STUDIO_8_0_BASE_UNIX)/common7/ide:$(PATH) +endif +ifdef CONFIG_VISUAL_STUDIO_10_0 +CONFIG_VISUAL_STUDIO_10_0_BASE_UNIX:=$(shell cygpath -u $(CONFIG_VISUAL_STUDIO_10_0_BASE)) +export INCLUDE=$(shell echo "$(CONFIG_VISUAL_STUDIO_10_0_BASE)\vc\include;$(CONFIG_VISUAL_STUDIO_10_0_BASE)\..\Microsoft SDKs\Windows\v7.0A\include") +export LIB=$(shell echo "$(CONFIG_VISUAL_STUDIO_10_0_BASE)\vc\lib;$(CONFIG_VISUAL_STUDIO_10_0_BASE)\..\Microsoft SDKs\Windows\v7.0A\lib") +PATH:=$(CONFIG_VISUAL_STUDIO_10_0_BASE_UNIX)/vc/bin:$(CONFIG_VISUAL_STUDIO_10_0_BASE_UNIX)/common7/ide:$(PATH) +stuff: + @echo $(INCLUDE) +endif + +CC=cl.exe +LD=link.exe +AXTLS_INCLUDE=$(shell cygpath -w $(AXTLS_HOME)) +CFLAGS+=/nologo /W3 /D"WIN32" /D"_MBCS" /D"_CONSOLE" /D"_CRT_SECURE_NO_DEPRECATE" /FD /I"$(AXTLS_INCLUDE)crypto" /I"$(AXTLS_INCLUDE)ssl" /I"$(AXTLS_INCLUDE)config" /c +LDFLAGS=/nologo /subsystem:console /machine:I386 +LDSHARED = /dll +AR=lib /nologo + +ifdef CONFIG_DEBUG + CFLAGS += /Gm /Zi /Od /D "_DEBUG" + LDFLAGS += /debug /incremental:yes +else + CFLAGS += /O2 /D "NDEBUG" + LDFLAGS += /incremental:no +endif + +else # Not Win32 + +-include .depend + +CFLAGS += -I$(AXTLS_HOME)/config -I$(AXTLS_HOME)/ssl -I$(AXTLS_HOME)/crypto $(CFLAGS_EXTRA) +LD=$(CC) +STRIP=$(CROSS)strip + +# Solaris +ifdef CONFIG_PLATFORM_SOLARIS +CFLAGS += -DCONFIG_PLATFORM_SOLARIS +LDFLAGS += -lsocket -lnsl -lc +LDSHARED = -G +# Linux/Cygwin +else +CFLAGS += -Wall -Wstrict-prototypes -Wshadow +LDSHARED = -shared + +# Linux +ifndef CONFIG_PLATFORM_CYGWIN +ifndef CONFIG_PLATFORM_NOMMU +#CFLAGS += -fPIC + +# Cygwin +else +CFLAGS += -DCONFIG_PLATFORM_CYGWIN +LDFLAGS += -enable-auto-import +endif +endif +endif + +ifdef CONFIG_DEBUG +CFLAGS += -g +else +#-m32 +# -pg +LDFLAGS += -g -Wl,--gc-sections,--print-gc-sections,-Map,map.lst -fno-unwind-tables -fno-asynchronous-unwind-tables +ifdef CONFIG_PLATFORM_SOLARIS +CFLAGS += -O +else +#-m32 +#-pg +CFLAGS += -g -Os -ffunction-sections -fdata-sections -fno-unwind-tables -fno-asynchronous-unwind-tables +endif + +endif # CONFIG_DEBUG +endif # WIN32 + +CFLAGS+=$(subst ",, $(strip $(CONFIG_EXTRA_CFLAGS_OPTIONS))) +LDFLAGS+=$(subst ",, $(strip $(CONFIG_EXTRA_LDFLAGS_OPTIONS))) + +endif # not 'clean' + +clean:: + -@rm -f *.o *.obj core* *.out *~ \.depend vc*0* + diff --git a/circuitpython/lib/axtls/config/makefile.dotnet.conf b/circuitpython/lib/axtls/config/makefile.dotnet.conf new file mode 100644 index 0000000..9cff4fd --- /dev/null +++ b/circuitpython/lib/axtls/config/makefile.dotnet.conf @@ -0,0 +1,65 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +ifneq ($(MAKECMDGOALS), clean) + +ifdef CONFIG_PLATFORM_WIN32 +GO_DOT_NET=y +endif + +ifdef CONFIG_PLATFORM_CYGWIN +GO_DOT_NET=y +endif + +ifdef GO_DOT_NET +all: test_dot_net_location + +# find out where the C# compiler is +CONFIG_DOT_NET_FRAMEWORK_BASE:=$(shell cygpath -u $(CONFIG_DOT_NET_FRAMEWORK_BASE)) + +test_dot_net_location: + @if ! [ -d "$(CONFIG_DOT_NET_FRAMEWORK_BASE)" ]; then \ + echo "*** Error: .NET path of $(CONFIG_DOT_NET_FRAMEWORK_BASE) doesn't exist" && exit 1; \ + fi + +PATH:=$(CONFIG_DOT_NET_FRAMEWORK_BASE):$(PATH) + +else # Linux? +all: test_mcs + +test_mcs: + @if ! mcs --about > /dev/null 2>&1; then \ + echo "Mono not installed! - go " \ + "to http://www.mono-project.com/Main_Page" && exit 1; \ + fi + +endif # Linux + +endif # not 'clean' diff --git a/circuitpython/lib/axtls/config/makefile.java.conf b/circuitpython/lib/axtls/config/makefile.java.conf new file mode 100644 index 0000000..9b22462 --- /dev/null +++ b/circuitpython/lib/axtls/config/makefile.java.conf @@ -0,0 +1,58 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +ifneq ($(MAKECMDGOALS), clean) + +ifdef CONFIG_PLATFORM_CYGWIN +CFLAGS += -I"$(CONFIG_JAVA_HOME)/include" +CFLAGS += -I"$(CONFIG_JAVA_HOME)/include/win32" +JAVA_BIN:=$(CONFIG_JAVA_HOME)/bin +else + +ifdef CONFIG_PLATFORM_WIN32 +CFLAGS += /I"$(shell cygpath -w $(CONFIG_JAVA_HOME)/include)" +CFLAGS += /I"$(shell cygpath -w $(CONFIG_JAVA_HOME)/include/win32)" +JAVA_BIN:=$(shell cygpath -u $(CONFIG_JAVA_HOME)/bin) +else # Linux +CFLAGS += -I$(CONFIG_JAVA_HOME)/include + +ifdef CONFIG_PLATFORM_SOLARIS +CFLAGS += -I$(CONFIG_JAVA_HOME)/include/solaris +else +CFLAGS += -I$(CONFIG_JAVA_HOME)/include/linux +endif + +JAVA_BIN:=$(CONFIG_JAVA_HOME)/bin +endif +endif + +PATH:=$(JAVA_BIN):$(PATH) + +endif # not 'clean' diff --git a/circuitpython/lib/axtls/config/makefile.post b/circuitpython/lib/axtls/config/makefile.post new file mode 100644 index 0000000..033981c --- /dev/null +++ b/circuitpython/lib/axtls/config/makefile.post @@ -0,0 +1,19 @@ + +ifneq ($(MAKECMDGOALS), clean) +ifndef CONFIG_PLATFORM_WIN32 +ifndef CONFIG_PLATFORM_SOLARIS +# do dependencies +-include .depend +all : .depend +.depend: $(wildcard *.c) + @$(CC) $(CFLAGS) -MM $^ > $@ +endif # 'not' solaris +endif # 'not' win32 + +ifdef CONFIG_PLATFORM_WIN32 +OBJ:=$(OBJ:.o=.obj) +%.obj : %.c + $(CC) $(CFLAGS) $< +endif # win32 + +endif # end of 'not' clean diff --git a/circuitpython/lib/axtls/config/scripts/config/Kconfig-language.txt b/circuitpython/lib/axtls/config/scripts/config/Kconfig-language.txt new file mode 100644 index 0000000..493749b --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/Kconfig-language.txt @@ -0,0 +1,255 @@ +Introduction +------------ + +The configuration database is collection of configuration options +organized in a tree structure: + + +- Code maturity level options + | +- Prompt for development and/or incomplete code/drivers + +- General setup + | +- Networking support + | +- System V IPC + | +- BSD Process Accounting + | +- Sysctl support + +- Loadable module support + | +- Enable loadable module support + | +- Set version information on all module symbols + | +- Kernel module loader + +- ... + +Every entry has its own dependencies. These dependencies are used +to determine the visible of an entry. Any child entry is only +visible if its parent entry is also visible. + +Menu entries +------------ + +Most entries define a config option, all other entries help to organize +them. A single configuration option is defined like this: + +config MODVERSIONS + bool "Set version information on all module symbols" + depends MODULES + help + Usually, modules have to be recompiled whenever you switch to a new + kernel. ... + +Every line starts with a key word and can be followed by multiple +arguments. "config" starts a new config entry. The following lines +define attributes for this config option. Attributes can be the type of +the config option, input prompt, dependencies, help text and default +values. A config option can be defined multiple times with the same +name, but every definition can have only a single input prompt and the +type must not conflict. + +Menu attributes +--------------- + +A menu entry can have a number of attributes. Not all of them are +applicable everywhere (see syntax). + +- type definition: "bool"/"tristate"/"string"/"hex"/"integer" + Every config option must have a type. There are only two basic types: + tristate and string, the other types base on these two. The type + definition optionally accepts an input prompt, so these two examples + are equivalent: + + bool "Networking support" + and + bool + prompt "Networking support" + +- input prompt: "prompt" ["if" ] + Every menu entry can have at most one prompt, which is used to display + to the user. Optionally dependencies only for this prompt can be added + with "if". + +- default value: "default" ["if" ] + A config option can have any number of default values. If multiple + default values are visible, only the first defined one is active. + Default values are not limited to the menu entry, where they are + defined, this means the default can be defined somewhere else or be + overriden by an earlier definition. + The default value is only assigned to the config symbol if no other + value was set by the user (via the input prompt above). If an input + prompt is visible the default value is presented to the user and can + be overridden by him. + Optionally dependencies only for this default value can be added with + "if". + +- dependencies: "depends on"/"requires" + This defines a dependency for this menu entry. If multiple + dependencies are defined they are connected with '&&'. Dependencies + are applied to all other options within this menu entry (which also + accept "if" expression), so these two examples are equivalent: + + bool "foo" if BAR + default y if BAR + and + depends on BAR + bool "foo" + default y + +- help text: "help" + This defines a help text. The end of the help text is determined by + the level indentation, this means it ends at the first line which has + a smaller indentation than the first line of the help text. + + +Menu dependencies +----------------- + +Dependencies define the visibility of a menu entry and can also reduce +the input range of tristate symbols. The tristate logic used in the +expressions uses one more state than normal boolean logic to express the +module state. Dependency expressions have the following syntax: + + ::= (1) + '=' (2) + '!=' (3) + '(' ')' (4) + '!' (5) + '||' (6) + '&&' (7) + +Expressions are listed in decreasing order of precedence. + +(1) Convert the symbol into an expression. Boolean and tristate symbols + are simply converted into the respective expression values. All + other symbol types result in 'n'. +(2) If the values of both symbols are equal, it returns 'y', + otherwise 'n'. +(3) If the values of both symbols are equal, it returns 'n', + otherwise 'y'. +(4) Returns the value of the expression. Used to override precedence. +(5) Returns the result of (2-/expr/). +(6) Returns the result of min(/expr/, /expr/). +(7) Returns the result of max(/expr/, /expr/). + +An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 +respectively for calculations). A menu entry becomes visible when it's +expression evaluates to 'm' or 'y'. + +There are two type of symbols: constant and nonconstant symbols. +Nonconstant symbols are the most common ones and are defined with the +'config' statement. Nonconstant symbols consist entirely of alphanumeric +characters or underscores. +Constant symbols are only part of expressions. Constant symbols are +always surrounded by single or double quotes. Within the quote any +other character is allowed and the quotes can be escaped using '\'. + +Menu structure +-------------- + +The position of a menu entry in the tree is determined in two ways. First +it can be specified explicitely: + +menu "Network device support" + depends NET + +config NETDEVICES + ... + +endmenu + +All entries within the "menu" ... "endmenu" block become a submenu of +"Network device support". All subentries inherit the dependencies from +the menu entry, e.g. this means the dependency "NET" is added to the +dependency list of the config option NETDEVICES. + +The other way to generate the menu structure is done by analyzing the +dependencies. If a menu entry somehow depends on the previous entry, it +can be made a submenu of it. First the the previous (parent) symbol must +be part of the dependency list and then one of these two condititions +must be true: +- the child entry must become invisible, if the parent is set to 'n' +- the child entry must only be visible, if the parent is visible + +config MODULES + bool "Enable loadable module support" + +config MODVERSIONS + bool "Set version information on all module symbols" + depends MODULES + +comment "module support disabled" + depends !MODULES + +MODVERSIONS directly depends on MODULES, this means it's only visible if +MODULES is different from 'n'. The comment on the other hand is always +visible when MODULES it's visible (the (empty) dependency of MODULES is +also part of the comment dependencies). + + +Kconfig syntax +-------------- + +The configuration file describes a series of menu entries, where every +line starts with a keyword (except help texts). The following keywords +end a menu entry: +- config +- choice/endchoice +- comment +- menu/endmenu +- if/endif +- source +The first four also start the definition of a menu entry. + +config: + + "config" + + +This defines a config symbol and accepts any of above +attributes as options. + +choices: + + "choice" + + + "endchoice" + +This defines a choice group and accepts any of above attributes as +options. A choice can only be of type bool or tristate, while a boolean +choice only allows a single config entry to be selected, a tristate +choice also allows any number of config entries to be set to 'm'. This +can be used if multiple drivers for a single hardware exists and only a +single driver can be compiled/loaded into the kernel, but all drivers +can be compiled as modules. +A choice accepts another option "optional", which allows to set the +choice to 'n' and no entry needs to be selected. + +comment: + + "comment" + + +This defines a comment which is displayed to the user during the +configuration process and is also echoed to the output files. The only +possible options are dependencies. + +menu: + + "menu" + + + "endmenu" + +This defines a menu block, see "Menu structure" above for more +information. The only possible options are dependencies. + +if: + + "if" + + "endif" + +This defines an if block. The dependency expression is appended +to all enclosed menu entries. + +source: + + "source" + +This reads the specified configuration file. This file is always parsed. diff --git a/circuitpython/lib/axtls/config/scripts/config/Makefile b/circuitpython/lib/axtls/config/scripts/config/Makefile new file mode 100644 index 0000000..7399501 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/Makefile @@ -0,0 +1,121 @@ +# Makefile for axTLS +# +# Copyright (C) 2002 Erik Andersen + +top_srcdir=../.. +top_builddir=../.. +srcdir=$(top_srcdir)/scripts/config +include $(top_srcdir)/Rules.mak + +all: ncurses conf mconf + +ifeq ($(shell uname),SunOS) +LIBS = -lcurses +else +LIBS = -lncurses +endif +ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) + HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) + HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/local/include/ncurses/ncurses.h, $(wildcard /usr/local/include/ncurses/ncurses.h)) + HOSTCFLAGS += -I/usr/local/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/local/include/ncurses/curses.h, $(wildcard /usr/local/include/ncurses/curses.h)) + HOSTCFLAGS += -I/usr/local/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) + HOSTNCURSES += -DCURSES_LOC="" +else + HOSTNCURSES += -DCURSES_LOC="" +endif +endif +endif +endif +endif + +CONF_SRC = conf.c +MCONF_SRC = mconf.c +LXD_SRC = lxdialog/checklist.c lxdialog/menubox.c lxdialog/textbox.c \ + lxdialog/yesno.c lxdialog/inputbox.c lxdialog/util.c \ + lxdialog/msgbox.c + +SHARED_SRC = zconf.tab.c +SHARED_DEPS := $(srcdir)/lkc.h $(srcdir)/lkc_proto.h \ + lkc_defs.h $(srcdir)/expr.h zconf.tab.h +CONF_OBJS = $(patsubst %.c,%.o, $(CONF_SRC)) +MCONF_OBJS = $(patsubst %.c,%.o, $(MCONF_SRC) $(LXD_SRC)) +SHARED_OBJS = $(patsubst %.c,%.o, $(SHARED_SRC)) + +conf: $(CONF_OBJS) $(SHARED_OBJS) + $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ + +mconf: $(MCONF_OBJS) $(SHARED_OBJS) + $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ $(LIBS) + +$(CONF_OBJS): %.o : $(srcdir)/%.c $(SHARED_DEPS) + $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@ + +$(MCONF_OBJS): %.o : $(srcdir)/%.c $(SHARED_DEPS) + @[ -d $(@D) ] || mkdir -v $(@D) + $(HOSTCC) $(HOSTCFLAGS) $(HOSTNCURSES) -I. -c $< -o $@ + +lkc_defs.h: $(srcdir)/lkc_proto.h + @sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' + +### +# The following requires flex/bison +# By default we use the _shipped versions, uncomment the +# following line if you are modifying the flex/bison src. +#LKC_GENPARSER := 1 + +ifdef LKC_GENPARSER + +%.tab.c %.tab.h: $(srcdir)/%.y + bison -t -d -v -b $* -p $(notdir $*) $< + +lex.%.c: $(srcdir)/%.l + flex -P$(notdir $*) -o$@ $< +else + +lex.zconf.o: lex.zconf.c $(SHARED_DEPS) + $(HOSTCC) $(HOSTCFLAGS) -I$(srcdir) -c $< -o $@ + +lex.zconf.c: $(srcdir)/lex.zconf.c_shipped + cp $< $@ + +zconf.tab.c: $(srcdir)/zconf.tab.c_shipped + cp $< $@ + +zconf.tab.h: $(srcdir)/zconf.tab.h_shipped + cp $< $@ +endif + +zconf.tab.o: zconf.tab.c lex.zconf.c $(srcdir)/confdata.c $(srcdir)/expr.c \ + $(srcdir)/symbol.c $(srcdir)/menu.c $(SHARED_DEPS) + $(HOSTCC) $(HOSTCFLAGS) -I$(srcdir) -I. -c $< -o $@ + +.PHONY: ncurses + +ncurses: + @echo "main() {}" > lxtemp.c + @if $(HOSTCC) lxtemp.c $(LIBS) ; then \ + rm -f lxtemp.c a.out; \ + else \ + rm -f lxtemp.c; \ + echo -e "\007" ;\ + echo ">> Unable to find the Ncurses libraries." ;\ + echo ">>" ;\ + echo ">> You must have Ncurses installed in order" ;\ + echo ">> to use 'make menuconfig'" ;\ + echo ;\ + exit 1 ;\ + fi + +clean: + rm -f *.o *~ ../../*~ core *.exe $(TARGETS) $(MCONF_OBJS) $(CONF_OBJS) + rm -f conf conf.exe mconf mconf.exe zconf.tab.c zconf.tab.h lex.zconf.c lkc_defs.h + rm -f ../..config.h + diff --git a/circuitpython/lib/axtls/config/scripts/config/conf.c b/circuitpython/lib/axtls/config/scripts/config/conf.c new file mode 100644 index 0000000..1524467 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/conf.c @@ -0,0 +1,583 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static void conf(struct menu *menu); +static void check_conf(struct menu *menu); + +enum { + ask_all, + ask_new, + ask_silent, + set_default, + set_yes, + set_mod, + set_no, + set_random +} input_mode = ask_all; +char *defconfig_file; + +static int indent = 1; +static int valid_stdin = 1; +static int conf_cnt; +static char line[128]; +static struct menu *rootEntry; + +static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; + +static void strip(char *str) +{ + char *p = str; + int l; + + while ((isspace(*p))) + p++; + l = strlen(p); + if (p != str) + memmove(str, p, l + 1); + if (!l) + return; + p = str + l - 1; + while ((isspace(*p))) + *p-- = 0; +} + +static void check_stdin(void) +{ + if (!valid_stdin && input_mode == ask_silent) { + printf("aborted!\n\n"); + printf("Console input/output is redirected. "); + printf("Run 'make oldconfig' to update configuration.\n\n"); + exit(1); + } +} + +static void conf_askvalue(struct symbol *sym, const char *def) +{ + enum symbol_type type = sym_get_type(sym); + tristate val; + + if (!sym_has_value(sym)) + printf("(NEW) "); + + line[0] = '\n'; + line[1] = 0; + + if (!sym_is_changable(sym)) { + printf("%s\n", def); + line[0] = '\n'; + line[1] = 0; + return; + } + + switch (input_mode) { + case ask_new: + case ask_silent: + if (sym_has_value(sym)) { + printf("%s\n", def); + return; + } + check_stdin(); + case ask_all: + fflush(stdout); + fgets(line, 128, stdin); + return; + case set_default: + printf("%s\n", def); + return; + default: + break; + } + + switch (type) { + case S_INT: + case S_HEX: + case S_STRING: + printf("%s\n", def); + return; + default: + ; + } + switch (input_mode) { + case set_yes: + if (sym_tristate_within_range(sym, yes)) { + line[0] = 'y'; + line[1] = '\n'; + line[2] = 0; + break; + } + case set_mod: + if (type == S_TRISTATE) { + if (sym_tristate_within_range(sym, mod)) { + line[0] = 'm'; + line[1] = '\n'; + line[2] = 0; + break; + } + } else { + if (sym_tristate_within_range(sym, yes)) { + line[0] = 'y'; + line[1] = '\n'; + line[2] = 0; + break; + } + } + case set_no: + if (sym_tristate_within_range(sym, no)) { + line[0] = 'n'; + line[1] = '\n'; + line[2] = 0; + break; + } + case set_random: + do { + val = (tristate)(random() % 3); + } while (!sym_tristate_within_range(sym, val)); + switch (val) { + case no: line[0] = 'n'; break; + case mod: line[0] = 'm'; break; + case yes: line[0] = 'y'; break; + } + line[1] = '\n'; + line[2] = 0; + break; + default: + break; + } + printf("%s", line); +} + +int conf_string(struct menu *menu) +{ + struct symbol *sym = menu->sym; + const char *def, *help; + + while (1) { + printf("%*s%s ", indent - 1, "", menu->prompt->text); + printf("(%s) ", sym->name); + def = sym_get_string_value(sym); + if (sym_get_string_value(sym)) + printf("[%s] ", def); + conf_askvalue(sym, def); + switch (line[0]) { + case '\n': + break; + case '?': + /* print help */ + if (line[1] == '\n') { + help = nohelp_text; + if (menu->sym->help) + help = menu->sym->help; + printf("\n%s\n", menu->sym->help); + def = NULL; + break; + } + default: + line[strlen(line)-1] = 0; + def = line; + } + if (def && sym_set_string_value(sym, def)) + return 0; + } +} + +static int conf_sym(struct menu *menu) +{ + struct symbol *sym = menu->sym; + int type; + tristate oldval, newval; + const char *help; + + while (1) { + printf("%*s%s ", indent - 1, "", menu->prompt->text); + if (sym->name) + printf("(%s) ", sym->name); + type = sym_get_type(sym); + putchar('['); + oldval = sym_get_tristate_value(sym); + switch (oldval) { + case no: + putchar('N'); + break; + case mod: + putchar('M'); + break; + case yes: + putchar('Y'); + break; + } + if (oldval != no && sym_tristate_within_range(sym, no)) + printf("/n"); + if (oldval != mod && sym_tristate_within_range(sym, mod)) + printf("/m"); + if (oldval != yes && sym_tristate_within_range(sym, yes)) + printf("/y"); + if (sym->help) + printf("/?"); + printf("] "); + conf_askvalue(sym, sym_get_string_value(sym)); + strip(line); + + switch (line[0]) { + case 'n': + case 'N': + newval = no; + if (!line[1] || !strcmp(&line[1], "o")) + break; + continue; + case 'm': + case 'M': + newval = mod; + if (!line[1]) + break; + continue; + case 'y': + case 'Y': + newval = yes; + if (!line[1] || !strcmp(&line[1], "es")) + break; + continue; + case 0: + newval = oldval; + break; + case '?': + goto help; + default: + continue; + } + if (sym_set_tristate_value(sym, newval)) + return 0; +help: + help = nohelp_text; + if (sym->help) + help = sym->help; + printf("\n%s\n", help); + } +} + +static int conf_choice(struct menu *menu) +{ + struct symbol *sym, *def_sym; + struct menu *child; + int type; + bool is_new; + + sym = menu->sym; + type = sym_get_type(sym); + is_new = !sym_has_value(sym); + if (sym_is_changable(sym)) { + conf_sym(menu); + sym_calc_value(sym); + switch (sym_get_tristate_value(sym)) { + case no: + return 1; + case mod: + return 0; + case yes: + break; + } + } else { + switch (sym_get_tristate_value(sym)) { + case no: + return 1; + case mod: + printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); + return 0; + case yes: + break; + } + } + + while (1) { + int cnt, def; + + printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); + def_sym = sym_get_choice_value(sym); + cnt = def = 0; + line[0] = '0'; + line[1] = 0; + for (child = menu->list; child; child = child->next) { + if (!menu_is_visible(child)) + continue; + if (!child->sym) { + printf("%*c %s\n", indent, '*', menu_get_prompt(child)); + continue; + } + cnt++; + if (child->sym == def_sym) { + def = cnt; + printf("%*c", indent, '>'); + } else + printf("%*c", indent, ' '); + printf(" %d. %s", cnt, menu_get_prompt(child)); + if (child->sym->name) + printf(" (%s)", child->sym->name); + if (!sym_has_value(child->sym)) + printf(" (NEW)"); + printf("\n"); + } + printf("%*schoice", indent - 1, ""); + if (cnt == 1) { + printf("[1]: 1\n"); + goto conf_childs; + } + printf("[1-%d", cnt); + if (sym->help) + printf("?"); + printf("]: "); + switch (input_mode) { + case ask_new: + case ask_silent: + if (!is_new) { + cnt = def; + printf("%d\n", cnt); + break; + } + check_stdin(); + case ask_all: + fflush(stdout); + fgets(line, 128, stdin); + strip(line); + if (line[0] == '?') { + printf("\n%s\n", menu->sym->help ? + menu->sym->help : nohelp_text); + continue; + } + if (!line[0]) + cnt = def; + else if (isdigit(line[0])) + cnt = atoi(line); + else + continue; + break; + case set_random: + def = (random() % cnt) + 1; + case set_default: + case set_yes: + case set_mod: + case set_no: + cnt = def; + printf("%d\n", cnt); + break; + } + + conf_childs: + for (child = menu->list; child; child = child->next) { + if (!child->sym || !menu_is_visible(child)) + continue; + if (!--cnt) + break; + } + if (!child) + continue; + if (line[strlen(line) - 1] == '?') { + printf("\n%s\n", child->sym->help ? + child->sym->help : nohelp_text); + continue; + } + sym_set_choice_value(sym, child->sym); + if (child->list) { + indent += 2; + conf(child->list); + indent -= 2; + } + return 1; + } +} + +static void conf(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + + if (!menu_is_visible(menu)) + return; + + sym = menu->sym; + prop = menu->prompt; + if (prop) { + const char *prompt; + + switch (prop->type) { + case P_MENU: + if (input_mode == ask_silent && rootEntry != menu) { + check_conf(menu); + return; + } + case P_COMMENT: + prompt = menu_get_prompt(menu); + if (prompt) + printf("%*c\n%*c %s\n%*c\n", + indent, '*', + indent, '*', prompt, + indent, '*'); + default: + ; + } + } + + if (!sym) + goto conf_childs; + + if (sym_is_choice(sym)) { + conf_choice(menu); + if (sym->curr.tri != mod) + return; + goto conf_childs; + } + + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + conf_string(menu); + break; + default: + conf_sym(menu); + break; + } + +conf_childs: + if (sym) + indent += 2; + for (child = menu->list; child; child = child->next) + conf(child); + if (sym) + indent -= 2; +} + +static void check_conf(struct menu *menu) +{ + struct symbol *sym; + struct menu *child; + + if (!menu_is_visible(menu)) + return; + + sym = menu->sym; + if (sym) { + if (sym_is_changable(sym) && !sym_has_value(sym)) { + if (!conf_cnt++) + printf("*\n* Restart config...\n*\n"); + rootEntry = menu_get_parent_menu(menu); + conf(rootEntry); + } + if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod) + return; + } + + for (child = menu->list; child; child = child->next) + check_conf(child); +} + +int main(int ac, char **av) +{ + int i = 1; + const char *name; + struct stat tmpstat; + + if (ac > i && av[i][0] == '-') { + switch (av[i++][1]) { + case 'o': + input_mode = ask_new; + break; + case 's': + input_mode = ask_silent; + valid_stdin = isatty(0) && isatty(1) && isatty(2); + break; + case 'd': + input_mode = set_default; + break; + case 'D': + input_mode = set_default; + defconfig_file = av[i++]; + if (!defconfig_file) { + printf("%s: No default config file specified\n", + av[0]); + exit(1); + } + break; + case 'n': + input_mode = set_no; + break; + case 'm': + input_mode = set_mod; + break; + case 'y': + input_mode = set_yes; + break; + case 'r': + input_mode = set_random; + srandom(time(NULL)); + break; + case 'h': + case '?': + printf("%s [-o|-s] config\n", av[0]); + exit(0); + } + } + name = av[i]; + if (!name) { + printf("%s: configuration file missing\n", av[0]); + } + conf_parse(name); + //zconfdump(stdout); + switch (input_mode) { + case set_default: + if (!defconfig_file) + defconfig_file = conf_get_default_confname(); + if (conf_read(defconfig_file)) { + printf("***\n" + "*** Can't find default configuration \"%s\"!\n" + "***\n", defconfig_file); + exit(1); + } + break; + case ask_silent: + if (stat(".config", &tmpstat)) { + printf("***\n" + "*** You have not yet configured axTLS!\n" + "***\n" + "*** Please run some configurator (e.g. \"make oldconfig\" or\n" + "*** \"make menuconfig\" or \"make config\").\n" + "***\n"); + exit(1); + } + case ask_all: + case ask_new: + conf_read(NULL); + break; + default: + break; + } + + if (input_mode != ask_silent) { + rootEntry = &rootmenu; + conf(&rootmenu); + if (input_mode == ask_all) { + input_mode = ask_silent; + valid_stdin = 1; + } + } + do { + conf_cnt = 0; + check_conf(&rootmenu); + } while (conf_cnt); + if (conf_write(NULL)) { + fprintf(stderr, "\n*** Error during writing of the axTLS configuration.\n\n"); + return 1; + } + return 0; +} diff --git a/circuitpython/lib/axtls/config/scripts/config/confdata.c b/circuitpython/lib/axtls/config/scripts/config/confdata.c new file mode 100644 index 0000000..a59e245 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/confdata.c @@ -0,0 +1,458 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +const char conf_def_filename[] = "config/.config"; + +const char conf_defname[] = "config/defconfig"; + +const char *conf_confnames[] = { + "config/.config", + conf_defname, + NULL, +}; + +static char *conf_expand_value(const char *in) +{ + struct symbol *sym; + const char *src; + static char res_value[SYMBOL_MAXLENGTH]; + char *dst, name[SYMBOL_MAXLENGTH]; + + res_value[0] = 0; + dst = name; + while ((src = strchr(in, '$'))) { + strncat(res_value, in, src - in); + src++; + dst = name; + while (isalnum(*src) || *src == '_') + *dst++ = *src++; + *dst = 0; + sym = sym_lookup(name, 0); + sym_calc_value(sym); + strcat(res_value, sym_get_string_value(sym)); + in = src; + } + strcat(res_value, in); + + return res_value; +} + +char *conf_get_default_confname(void) +{ + struct stat buf; + static char fullname[PATH_MAX+1]; + char *env, *name; + + name = conf_expand_value(conf_defname); + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + if (!stat(fullname, &buf)) + return fullname; + } + return name; +} + +int conf_read(const char *name) +{ + FILE *in = NULL; + char line[1024]; + char *p, *p2; + int lineno = 0; + struct symbol *sym; + struct property *prop; + struct expr *e; + int i; + + if (name) { + in = zconf_fopen(name); + } else { + const char **names = conf_confnames; + while ((name = *names++)) { + name = conf_expand_value(name); + in = zconf_fopen(name); + if (in) { + printf("#\n" + "# using defaults found in %s\n" + "#\n", name); + break; + } + } + } + + if (!in) + return 1; + + for_all_symbols(i, sym) { + sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; + sym->flags &= ~SYMBOL_VALID; + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + if (sym->user.val) + free(sym->user.val); + default: + sym->user.val = NULL; + sym->user.tri = no; + } + } + + while (fgets(line, sizeof(line), in)) { + lineno++; + sym = NULL; + switch (line[0]) { + case '#': + if (line[1]!=' ') + continue; + p = strchr(line + 2, ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; + sym = sym_find(line + 2); + if (!sym) { + fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 2); + break; + } + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; + break; + default: + ; + } + break; + + case 'A' ... 'Z': + p = strchr(line, '='); + if (!p) + continue; + *p++ = 0; + p2 = strchr(p, '\n'); + if (p2) + *p2 = 0; + sym = sym_find(line); + if (!sym) { + fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line); + break; + } + switch (sym->type) { + case S_TRISTATE: + if (p[0] == 'm') { + sym->user.tri = mod; + sym->flags &= ~SYMBOL_NEW; + break; + } + case S_BOOLEAN: + if (p[0] == 'y') { + sym->user.tri = yes; + sym->flags &= ~SYMBOL_NEW; + break; + } + if (p[0] == 'n') { + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; + break; + } + break; + case S_STRING: + if (*p++ != '"') + break; + for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { + if (*p2 == '"') { + *p2 = 0; + break; + } + memmove(p2, p2 + 1, strlen(p2)); + } + if (!p2) { + fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); + exit(1); + } + case S_INT: + case S_HEX: + if (sym_string_valid(sym, p)) { + sym->user.val = strdup(p); + sym->flags &= ~SYMBOL_NEW; + } else { + fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); + exit(1); + } + break; + default: + ; + } + break; + case '\n': + break; + default: + continue; + } + if (sym && sym_is_choice_value(sym)) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + switch (sym->user.tri) { + case no: + break; + case mod: + if (cs->user.tri == yes) + /* warn? */; + break; + case yes: + if (cs->user.tri != no) + /* warn? */; + cs->user.val = sym; + break; + } + cs->user.tri = E_OR(cs->user.tri, sym->user.tri); + cs->flags &= ~SYMBOL_NEW; + } + } + fclose(in); + + if (modules_sym) + sym_calc_value(modules_sym); + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (sym_has_value(sym) && !sym_is_choice_value(sym)) { + if (sym->visible == no) + sym->flags |= SYMBOL_NEW; + switch (sym->type) { + case S_STRING: + case S_INT: + case S_HEX: + if (!sym_string_within_range(sym, sym->user.val)) + sym->flags |= SYMBOL_NEW; + default: + break; + } + } + if (!sym_is_choice(sym)) + continue; + prop = sym_get_choice_prop(sym); + for (e = prop->expr; e; e = e->left.expr) + if (e->right.sym->visible != no) + sym->flags |= e->right.sym->flags & SYMBOL_NEW; + } + + sym_change_count = 1; + + return 0; +} + +struct menu *next_menu(struct menu *menu) +{ + if (menu->list) return menu->list; + do { + if (menu->next) { + menu = menu->next; + break; + } + } while ((menu = menu->parent)); + + return menu; +} + +#define SYMBOL_FORCEWRITE (1<<31) + +int conf_write(const char *name) +{ + FILE *out, *out_h; + struct symbol *sym; + struct menu *menu; + const char *basename; + char dirname[128], tmpname[128], newname[128]; + int type, l; + const char *str; + + dirname[0] = 0; + if (name && name[0]) { + struct stat st; + char *slash; + + if (!stat(name, &st) && S_ISDIR(st.st_mode)) { + strcpy(dirname, name); + strcat(dirname, "/"); + basename = conf_def_filename; + } else if ((slash = strrchr(name, '/'))) { + int size = slash - name + 1; + memcpy(dirname, name, size); + dirname[size] = 0; + if (slash[1]) + basename = slash + 1; + else + basename = conf_def_filename; + } else + basename = name; + } else + basename = conf_def_filename; + + sprintf(newname, "config/%s.tmpconfig.%d", dirname, (int)getpid()); + out = fopen(newname, "w"); + if (!out) + return 1; + out_h = NULL; + if (!name) { + out_h = fopen("config/.tmpconfig.h", "w"); + if (!out_h) + return 1; + } + fprintf(out, "#\n" + "# Automatically generated make config: don't edit\n" + "#\n"); + if (out_h) { + fprintf(out_h, "/*\n" + " * Automatically generated header file: don't edit\n" + " */\n\n"); +#if 0 + "/* Version Number */\n" + "#define BB_VER \"%s\"\n" + "#define BB_BT \"%s\"\n", + getenv("VERSION"), + getenv("BUILDTIME")); + if (getenv("EXTRA_VERSION")) + fprintf(out_h, "#define BB_EXTRA_VERSION \"%s\"\n", + getenv("EXTRA_VERSION")); + fprintf(out_h, "\n"); +#endif + } + + if (!sym_change_count) + sym_clear_all_valid(); + + /* Force write of all non-duplicate symbols. */ + + /* Write out everything by default. */ + for(menu = rootmenu.list; menu; menu = next_menu(menu)) + if (menu->sym) menu->sym->flags |= SYMBOL_FORCEWRITE; + + menu = rootmenu.list; + while (menu) { + sym = menu->sym; + if (!sym) { + if (!menu_is_visible(menu)) + goto next; + str = menu_get_prompt(menu); + fprintf(out, "\n" + "#\n" + "# %s\n" + "#\n", str); + if (out_h) + fprintf(out_h, "\n" + "/*\n" + " * %s\n" + " */\n", str); + } else if (!(sym->flags & SYMBOL_CHOICE)) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_FORCEWRITE)) + goto next; + + sym->flags &= ~SYMBOL_FORCEWRITE; + type = sym->type; + if (type == S_TRISTATE) { + sym_calc_value(modules_sym); + if (modules_sym->curr.tri == no) + type = S_BOOLEAN; + } + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + fprintf(out, "# %s is not set\n", sym->name); + if (out_h) + fprintf(out_h, "#undef %s\n", sym->name); + break; + case mod: +#if 0 + fprintf(out, "%s=m\n", sym->name); + if (out_h) + fprintf(out_h, "#define %s_MODULE 1\n", sym->name); +#endif + break; + case yes: + fprintf(out, "%s=y\n", sym->name); + if (out_h) + fprintf(out_h, "#define %s 1\n", sym->name); + break; + } + break; + case S_STRING: + // fix me + str = sym_get_string_value(sym); + fprintf(out, "%s=\"", sym->name); + if (out_h) + fprintf(out_h, "#define %s \"", sym->name); + do { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + if (out_h) + fwrite(str, l, 1, out_h); + } + str += l; + while (*str == '\\' || *str == '"') { + fprintf(out, "\\%c", *str); + if (out_h) + fprintf(out_h, "\\%c", *str); + str++; + } + } while (*str); + fputs("\"\n", out); + if (out_h) + fputs("\"\n", out_h); + break; + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { + fprintf(out, "%s=%s\n", sym->name, *str ? str : "0"); + if (out_h) + fprintf(out_h, "#define %s 0x%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "%s=%s\n", sym->name, *str ? str : "0"); + if (out_h) + fprintf(out_h, "#define %s %s\n", sym->name, str); + break; + } + } +next: + menu = next_menu(menu); + } + fclose(out); + if (out_h) { + fclose(out_h); + rename("config/.tmpconfig.h", "config/config.h"); + file_write_dep(NULL); + } + if (!name || basename != conf_def_filename) { + if (!name) + name = conf_def_filename; + sprintf(tmpname, "%s.old", name); + rename(name, tmpname); + } + sprintf(tmpname, "%s%s", dirname, basename); + if (rename(newname, tmpname)) + return 1; + + sym_change_count = 0; + + return 0; +} diff --git a/circuitpython/lib/axtls/config/scripts/config/expr.c b/circuitpython/lib/axtls/config/scripts/config/expr.c new file mode 100644 index 0000000..30e4f9d --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/expr.c @@ -0,0 +1,1099 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +#define DEBUG_EXPR 0 + +struct expr *expr_alloc_symbol(struct symbol *sym) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = E_SYMBOL; + e->left.sym = sym; + return e; +} + +struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.expr = ce; + return e; +} + +struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.expr = e1; + e->right.expr = e2; + return e; +} + +struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.sym = s1; + e->right.sym = s2; + return e; +} + +struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) +{ + if (!e1) + return e2; + return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; +} + +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) +{ + if (!e1) + return e2; + return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; +} + +struct expr *expr_copy(struct expr *org) +{ + struct expr *e; + + if (!org) + return NULL; + + e = malloc(sizeof(*org)); + memcpy(e, org, sizeof(*org)); + switch (org->type) { + case E_SYMBOL: + e->left = org->left; + break; + case E_NOT: + e->left.expr = expr_copy(org->left.expr); + break; + case E_EQUAL: + case E_UNEQUAL: + e->left.sym = org->left.sym; + e->right.sym = org->right.sym; + break; + case E_AND: + case E_OR: + case E_CHOICE: + e->left.expr = expr_copy(org->left.expr); + e->right.expr = expr_copy(org->right.expr); + break; + default: + printf("can't copy type %d\n", e->type); + free(e); + e = NULL; + break; + } + + return e; +} + +void expr_free(struct expr *e) +{ + if (!e) + return; + + switch (e->type) { + case E_SYMBOL: + break; + case E_NOT: + expr_free(e->left.expr); + return; + case E_EQUAL: + case E_UNEQUAL: + break; + case E_OR: + case E_AND: + expr_free(e->left.expr); + expr_free(e->right.expr); + break; + default: + printf("how to free type %d?\n", e->type); + break; + } + free(e); +} + +static int trans_count; + +#define e1 (*ep1) +#define e2 (*ep2) + +static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ + if (e1->type == type) { + __expr_eliminate_eq(type, &e1->left.expr, &e2); + __expr_eliminate_eq(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + __expr_eliminate_eq(type, &e1, &e2->left.expr); + __expr_eliminate_eq(type, &e1, &e2->right.expr); + return; + } + if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && + e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO))) + return; + if (!expr_eq(e1, e2)) + return; + trans_count++; + expr_free(e1); expr_free(e2); + switch (type) { + case E_OR: + e1 = expr_alloc_symbol(&symbol_no); + e2 = expr_alloc_symbol(&symbol_no); + break; + case E_AND: + e1 = expr_alloc_symbol(&symbol_yes); + e2 = expr_alloc_symbol(&symbol_yes); + break; + default: + ; + } +} + +void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) +{ + if (!e1 || !e2) + return; + switch (e1->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e1->type, ep1, ep2); + default: + ; + } + if (e1->type != e2->type) switch (e2->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e2->type, ep1, ep2); + default: + ; + } + e1 = expr_eliminate_yn(e1); + e2 = expr_eliminate_yn(e2); +} + +#undef e1 +#undef e2 + +int expr_eq(struct expr *e1, struct expr *e2) +{ + int res, old_count; + + if (e1->type != e2->type) + return 0; + switch (e1->type) { + case E_EQUAL: + case E_UNEQUAL: + return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; + case E_SYMBOL: + return e1->left.sym == e2->left.sym; + case E_NOT: + return expr_eq(e1->left.expr, e2->left.expr); + case E_AND: + case E_OR: + e1 = expr_copy(e1); + e2 = expr_copy(e2); + old_count = trans_count; + expr_eliminate_eq(&e1, &e2); + res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && + e1->left.sym == e2->left.sym); + expr_free(e1); + expr_free(e2); + trans_count = old_count; + return res; + case E_CHOICE: + case E_RANGE: + case E_NONE: + /* panic */; + } + + if (DEBUG_EXPR) { + expr_fprint(e1, stdout); + printf(" = "); + expr_fprint(e2, stdout); + printf(" ?\n"); + } + + return 0; +} + +struct expr *expr_eliminate_yn(struct expr *e) +{ + struct expr *tmp; + + if (e) switch (e->type) { + case E_AND: + e->left.expr = expr_eliminate_yn(e->left.expr); + e->right.expr = expr_eliminate_yn(e->right.expr); + if (e->left.expr->type == E_SYMBOL) { + if (e->left.expr->left.sym == &symbol_no) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.expr = NULL; + return e; + } else if (e->left.expr->left.sym == &symbol_yes) { + free(e->left.expr); + tmp = e->right.expr; + *e = *(e->right.expr); + free(tmp); + return e; + } + } + if (e->right.expr->type == E_SYMBOL) { + if (e->right.expr->left.sym == &symbol_no) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.expr = NULL; + return e; + } else if (e->right.expr->left.sym == &symbol_yes) { + free(e->right.expr); + tmp = e->left.expr; + *e = *(e->left.expr); + free(tmp); + return e; + } + } + break; + case E_OR: + e->left.expr = expr_eliminate_yn(e->left.expr); + e->right.expr = expr_eliminate_yn(e->right.expr); + if (e->left.expr->type == E_SYMBOL) { + if (e->left.expr->left.sym == &symbol_no) { + free(e->left.expr); + tmp = e->right.expr; + *e = *(e->right.expr); + free(tmp); + return e; + } else if (e->left.expr->left.sym == &symbol_yes) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.expr = NULL; + return e; + } + } + if (e->right.expr->type == E_SYMBOL) { + if (e->right.expr->left.sym == &symbol_no) { + free(e->right.expr); + tmp = e->left.expr; + *e = *(e->left.expr); + free(tmp); + return e; + } else if (e->right.expr->left.sym == &symbol_yes) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.expr = NULL; + return e; + } + } + break; + default: + ; + } + return e; +} + +/* + * bool FOO!=n => FOO + */ +struct expr *expr_trans_bool(struct expr *e) +{ + if (!e) + return NULL; + switch (e->type) { + case E_AND: + case E_OR: + case E_NOT: + e->left.expr = expr_trans_bool(e->left.expr); + e->right.expr = expr_trans_bool(e->right.expr); + break; + case E_UNEQUAL: + // FOO!=n -> FOO + if (e->left.sym->type == S_TRISTATE) { + if (e->right.sym == &symbol_no) { + e->type = E_SYMBOL; + e->right.sym = NULL; + } + } + break; + default: + ; + } + return e; +} + +/* + * e1 || e2 -> ? + */ +struct expr *expr_join_or(struct expr *e1, struct expr *e2) +{ + struct expr *tmp; + struct symbol *sym1, *sym2; + + if (expr_eq(e1, e2)) + return expr_copy(e1); + if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) + return NULL; + if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) + return NULL; + if (e1->type == E_NOT) { + tmp = e1->left.expr; + if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) + return NULL; + sym1 = tmp->left.sym; + } else + sym1 = e1->left.sym; + if (e2->type == E_NOT) { + if (e2->left.expr->type != E_SYMBOL) + return NULL; + sym2 = e2->left.expr->left.sym; + } else + sym2 = e2->left.sym; + if (sym1 != sym2) + return NULL; + if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) + return NULL; + if (sym1->type == S_TRISTATE) { + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || + (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { + // (a='y') || (a='m') -> (a!='n') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); + } + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { + // (a='y') || (a='n') -> (a!='m') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); + } + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { + // (a='m') || (a='n') -> (a!='y') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); + } + } + if (sym1->type == S_BOOLEAN && sym1 == sym2) { + if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || + (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) + return expr_alloc_symbol(&symbol_yes); + } + + if (DEBUG_EXPR) { + printf("optimize ("); + expr_fprint(e1, stdout); + printf(") || ("); + expr_fprint(e2, stdout); + printf(")?\n"); + } + return NULL; +} + +struct expr *expr_join_and(struct expr *e1, struct expr *e2) +{ + struct expr *tmp; + struct symbol *sym1, *sym2; + + if (expr_eq(e1, e2)) + return expr_copy(e1); + if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) + return NULL; + if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) + return NULL; + if (e1->type == E_NOT) { + tmp = e1->left.expr; + if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) + return NULL; + sym1 = tmp->left.sym; + } else + sym1 = e1->left.sym; + if (e2->type == E_NOT) { + if (e2->left.expr->type != E_SYMBOL) + return NULL; + sym2 = e2->left.expr->left.sym; + } else + sym2 = e2->left.sym; + if (sym1 != sym2) + return NULL; + if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) + return NULL; + + if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || + (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) + // (a) && (a='y') -> (a='y') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) + // (a) && (a!='n') -> (a) + return expr_alloc_symbol(sym1); + + if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) + // (a) && (a!='m') -> (a='y') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if (sym1->type == S_TRISTATE) { + if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { + // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' + sym2 = e1->right.sym; + if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) + return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) + : expr_alloc_symbol(&symbol_no); + } + if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { + // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' + sym2 = e2->right.sym; + if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) + return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) + : expr_alloc_symbol(&symbol_no); + } + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) + // (a!='y') && (a!='n') -> (a='m') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); + + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || + (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) + // (a!='y') && (a!='m') -> (a='n') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); + + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) + // (a!='m') && (a!='n') -> (a='m') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || + (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || + (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) + return NULL; + } + + if (DEBUG_EXPR) { + printf("optimize ("); + expr_fprint(e1, stdout); + printf(") && ("); + expr_fprint(e2, stdout); + printf(")?\n"); + } + return NULL; +} + +static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + struct expr *tmp; + + if (e1->type == type) { + expr_eliminate_dups1(type, &e1->left.expr, &e2); + expr_eliminate_dups1(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_eliminate_dups1(type, &e1, &e2->left.expr); + expr_eliminate_dups1(type, &e1, &e2->right.expr); + return; + } + if (e1 == e2) + return; + + switch (e1->type) { + case E_OR: case E_AND: + expr_eliminate_dups1(e1->type, &e1, &e1); + default: + ; + } + + switch (type) { + case E_OR: + tmp = expr_join_or(e1, e2); + if (tmp) { + expr_free(e1); expr_free(e2); + e1 = expr_alloc_symbol(&symbol_no); + e2 = tmp; + trans_count++; + } + break; + case E_AND: + tmp = expr_join_and(e1, e2); + if (tmp) { + expr_free(e1); expr_free(e2); + e1 = expr_alloc_symbol(&symbol_yes); + e2 = tmp; + trans_count++; + } + break; + default: + ; + } +#undef e1 +#undef e2 +} + +static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + struct expr *tmp, *tmp1, *tmp2; + + if (e1->type == type) { + expr_eliminate_dups2(type, &e1->left.expr, &e2); + expr_eliminate_dups2(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_eliminate_dups2(type, &e1, &e2->left.expr); + expr_eliminate_dups2(type, &e1, &e2->right.expr); + } + if (e1 == e2) + return; + + switch (e1->type) { + case E_OR: + expr_eliminate_dups2(e1->type, &e1, &e1); + // (FOO || BAR) && (!FOO && !BAR) -> n + tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); + tmp2 = expr_copy(e2); + tmp = expr_extract_eq_and(&tmp1, &tmp2); + if (expr_is_yes(tmp1)) { + expr_free(e1); + e1 = expr_alloc_symbol(&symbol_no); + trans_count++; + } + expr_free(tmp2); + expr_free(tmp1); + expr_free(tmp); + break; + case E_AND: + expr_eliminate_dups2(e1->type, &e1, &e1); + // (FOO && BAR) || (!FOO || !BAR) -> y + tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); + tmp2 = expr_copy(e2); + tmp = expr_extract_eq_or(&tmp1, &tmp2); + if (expr_is_no(tmp1)) { + expr_free(e1); + e1 = expr_alloc_symbol(&symbol_yes); + trans_count++; + } + expr_free(tmp2); + expr_free(tmp1); + expr_free(tmp); + break; + default: + ; + } +#undef e1 +#undef e2 +} + +struct expr *expr_eliminate_dups(struct expr *e) +{ + int oldcount; + if (!e) + return e; + + oldcount = trans_count; + while (1) { + trans_count = 0; + switch (e->type) { + case E_OR: case E_AND: + expr_eliminate_dups1(e->type, &e, &e); + expr_eliminate_dups2(e->type, &e, &e); + default: + ; + } + if (!trans_count) + break; + e = expr_eliminate_yn(e); + } + trans_count = oldcount; + return e; +} + +struct expr *expr_transform(struct expr *e) +{ + struct expr *tmp; + + if (!e) + return NULL; + switch (e->type) { + case E_EQUAL: + case E_UNEQUAL: + case E_SYMBOL: + case E_CHOICE: + break; + default: + e->left.expr = expr_transform(e->left.expr); + e->right.expr = expr_transform(e->right.expr); + } + + switch (e->type) { + case E_EQUAL: + if (e->left.sym->type != S_BOOLEAN) + break; + if (e->right.sym == &symbol_no) { + e->type = E_NOT; + e->left.expr = expr_alloc_symbol(e->left.sym); + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_mod) { + printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_yes) { + e->type = E_SYMBOL; + e->right.sym = NULL; + break; + } + break; + case E_UNEQUAL: + if (e->left.sym->type != S_BOOLEAN) + break; + if (e->right.sym == &symbol_no) { + e->type = E_SYMBOL; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_mod) { + printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_yes) { + e->type = E_NOT; + e->left.expr = expr_alloc_symbol(e->left.sym); + e->right.sym = NULL; + break; + } + break; + case E_NOT: + switch (e->left.expr->type) { + case E_NOT: + // !!a -> a + tmp = e->left.expr->left.expr; + free(e->left.expr); + free(e); + e = tmp; + e = expr_transform(e); + break; + case E_EQUAL: + case E_UNEQUAL: + // !a='x' -> a!='x' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; + break; + case E_OR: + // !(a || b) -> !a && !b + tmp = e->left.expr; + e->type = E_AND; + e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); + tmp->type = E_NOT; + tmp->right.expr = NULL; + e = expr_transform(e); + break; + case E_AND: + // !(a && b) -> !a || !b + tmp = e->left.expr; + e->type = E_OR; + e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); + tmp->type = E_NOT; + tmp->right.expr = NULL; + e = expr_transform(e); + break; + case E_SYMBOL: + if (e->left.expr->left.sym == &symbol_yes) { + // !'y' -> 'n' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + break; + } + if (e->left.expr->left.sym == &symbol_mod) { + // !'m' -> 'm' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_mod; + break; + } + if (e->left.expr->left.sym == &symbol_no) { + // !'n' -> 'y' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + break; + } + break; + default: + ; + } + break; + default: + ; + } + return e; +} + +int expr_contains_symbol(struct expr *dep, struct symbol *sym) +{ + if (!dep) + return 0; + + switch (dep->type) { + case E_AND: + case E_OR: + return expr_contains_symbol(dep->left.expr, sym) || + expr_contains_symbol(dep->right.expr, sym); + case E_SYMBOL: + return dep->left.sym == sym; + case E_EQUAL: + case E_UNEQUAL: + return dep->left.sym == sym || + dep->right.sym == sym; + case E_NOT: + return expr_contains_symbol(dep->left.expr, sym); + default: + ; + } + return 0; +} + +bool expr_depends_symbol(struct expr *dep, struct symbol *sym) +{ + if (!dep) + return false; + + switch (dep->type) { + case E_AND: + return expr_depends_symbol(dep->left.expr, sym) || + expr_depends_symbol(dep->right.expr, sym); + case E_SYMBOL: + return dep->left.sym == sym; + case E_EQUAL: + if (dep->left.sym == sym) { + if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) + return true; + } + break; + case E_UNEQUAL: + if (dep->left.sym == sym) { + if (dep->right.sym == &symbol_no) + return true; + } + break; + default: + ; + } + return false; +} + +struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) +{ + struct expr *tmp = NULL; + expr_extract_eq(E_AND, &tmp, ep1, ep2); + if (tmp) { + *ep1 = expr_eliminate_yn(*ep1); + *ep2 = expr_eliminate_yn(*ep2); + } + return tmp; +} + +struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) +{ + struct expr *tmp = NULL; + expr_extract_eq(E_OR, &tmp, ep1, ep2); + if (tmp) { + *ep1 = expr_eliminate_yn(*ep1); + *ep2 = expr_eliminate_yn(*ep2); + } + return tmp; +} + +void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + if (e1->type == type) { + expr_extract_eq(type, ep, &e1->left.expr, &e2); + expr_extract_eq(type, ep, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_extract_eq(type, ep, ep1, &e2->left.expr); + expr_extract_eq(type, ep, ep1, &e2->right.expr); + return; + } + if (expr_eq(e1, e2)) { + *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; + expr_free(e2); + if (type == E_AND) { + e1 = expr_alloc_symbol(&symbol_yes); + e2 = expr_alloc_symbol(&symbol_yes); + } else if (type == E_OR) { + e1 = expr_alloc_symbol(&symbol_no); + e2 = expr_alloc_symbol(&symbol_no); + } + } +#undef e1 +#undef e2 +} + +struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) +{ + struct expr *e1, *e2; + + if (!e) { + e = expr_alloc_symbol(sym); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + } + switch (e->type) { + case E_AND: + e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); + e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); + if (sym == &symbol_yes) + e = expr_alloc_two(E_AND, e1, e2); + if (sym == &symbol_no) + e = expr_alloc_two(E_OR, e1, e2); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + case E_OR: + e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); + e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); + if (sym == &symbol_yes) + e = expr_alloc_two(E_OR, e1, e2); + if (sym == &symbol_no) + e = expr_alloc_two(E_AND, e1, e2); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + case E_NOT: + return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); + case E_UNEQUAL: + case E_EQUAL: + if (type == E_EQUAL) { + if (sym == &symbol_yes) + return expr_copy(e); + if (sym == &symbol_mod) + return expr_alloc_symbol(&symbol_no); + if (sym == &symbol_no) + return expr_alloc_one(E_NOT, expr_copy(e)); + } else { + if (sym == &symbol_yes) + return expr_alloc_one(E_NOT, expr_copy(e)); + if (sym == &symbol_mod) + return expr_alloc_symbol(&symbol_yes); + if (sym == &symbol_no) + return expr_copy(e); + } + break; + case E_SYMBOL: + return expr_alloc_comp(type, e->left.sym, sym); + case E_CHOICE: + case E_RANGE: + case E_NONE: + /* panic */; + } + return NULL; +} + +tristate expr_calc_value(struct expr *e) +{ + tristate val1, val2; + const char *str1, *str2; + + if (!e) + return yes; + + switch (e->type) { + case E_SYMBOL: + sym_calc_value(e->left.sym); + return e->left.sym->curr.tri; + case E_AND: + val1 = expr_calc_value(e->left.expr); + val2 = expr_calc_value(e->right.expr); + return E_AND(val1, val2); + case E_OR: + val1 = expr_calc_value(e->left.expr); + val2 = expr_calc_value(e->right.expr); + return E_OR(val1, val2); + case E_NOT: + val1 = expr_calc_value(e->left.expr); + return E_NOT(val1); + case E_EQUAL: + sym_calc_value(e->left.sym); + sym_calc_value(e->right.sym); + str1 = sym_get_string_value(e->left.sym); + str2 = sym_get_string_value(e->right.sym); + return !strcmp(str1, str2) ? yes : no; + case E_UNEQUAL: + sym_calc_value(e->left.sym); + sym_calc_value(e->right.sym); + str1 = sym_get_string_value(e->left.sym); + str2 = sym_get_string_value(e->right.sym); + return !strcmp(str1, str2) ? no : yes; + default: + printf("expr_calc_value: %d?\n", e->type); + return no; + } +} + +int expr_compare_type(enum expr_type t1, enum expr_type t2) +{ +#if 0 + return 1; +#else + if (t1 == t2) + return 0; + switch (t1) { + case E_EQUAL: + case E_UNEQUAL: + if (t2 == E_NOT) + return 1; + case E_NOT: + if (t2 == E_AND) + return 1; + case E_AND: + if (t2 == E_OR) + return 1; + case E_OR: + if (t2 == E_CHOICE) + return 1; + case E_CHOICE: + if (t2 == 0) + return 1; + default: + return -1; + } + printf("[%dgt%d?]", t1, t2); + return 0; +#endif +} + +void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken) +{ + if (!e) { + fn(data, "y"); + return; + } + + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, "("); + switch (e->type) { + case E_SYMBOL: + if (e->left.sym->name) + fn(data, e->left.sym->name); + else + fn(data, ""); + break; + case E_NOT: + fn(data, "!"); + expr_print(e->left.expr, fn, data, E_NOT); + break; + case E_EQUAL: + fn(data, e->left.sym->name); + fn(data, "="); + fn(data, e->right.sym->name); + break; + case E_UNEQUAL: + fn(data, e->left.sym->name); + fn(data, "!="); + fn(data, e->right.sym->name); + break; + case E_OR: + expr_print(e->left.expr, fn, data, E_OR); + fn(data, " || "); + expr_print(e->right.expr, fn, data, E_OR); + break; + case E_AND: + expr_print(e->left.expr, fn, data, E_AND); + fn(data, " && "); + expr_print(e->right.expr, fn, data, E_AND); + break; + case E_CHOICE: + fn(data, e->right.sym->name); + if (e->left.expr) { + fn(data, " ^ "); + expr_print(e->left.expr, fn, data, E_CHOICE); + } + break; + case E_RANGE: + fn(data, "["); + fn(data, e->left.sym->name); + fn(data, " "); + fn(data, e->right.sym->name); + fn(data, "]"); + break; + default: + { + char buf[32]; + sprintf(buf, "", e->type); + fn(data, buf); + break; + } + } + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, ")"); +} + +static void expr_print_file_helper(void *data, const char *str) +{ + fwrite(str, strlen(str), 1, data); +} + +void expr_fprint(struct expr *e, FILE *out) +{ + expr_print(e, expr_print_file_helper, out, E_NONE); +} + +static void expr_print_gstr_helper(void *data, const char *str) +{ + str_append((struct gstr*)data, str); +} + +void expr_gstr_print(struct expr *e, struct gstr *gs) +{ + expr_print(e, expr_print_gstr_helper, gs, E_NONE); +} diff --git a/circuitpython/lib/axtls/config/scripts/config/expr.h b/circuitpython/lib/axtls/config/scripts/config/expr.h new file mode 100644 index 0000000..7d39ff4 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/expr.h @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef EXPR_H +#define EXPR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifndef __cplusplus +#include +#endif + +struct file { + struct file *next; + struct file *parent; + char *name; + int lineno; + int flags; +}; + +#define FILE_BUSY 0x0001 +#define FILE_SCANNED 0x0002 +#define FILE_PRINTED 0x0004 + +typedef enum tristate { + no, mod, yes +} tristate; + +enum expr_type { + E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE +}; + +union expr_data { + struct expr *expr; + struct symbol *sym; +}; + +struct expr { + enum expr_type type; + union expr_data left, right; +}; + +#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) +#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) +#define E_NOT(dep) (2-(dep)) + +struct expr_value { + struct expr *expr; + tristate tri; +}; + +struct symbol_value { + void *val; + tristate tri; +}; + +enum symbol_type { + S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER +}; + +struct symbol { + struct symbol *next; + char *name; + char *help; + enum symbol_type type; + struct symbol_value curr, user; + tristate visible; + int flags; + struct property *prop; + struct expr *dep, *dep2; + struct expr_value rev_dep; +}; + +#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) + +#define SYMBOL_YES 0x0001 +#define SYMBOL_MOD 0x0002 +#define SYMBOL_NO 0x0004 +#define SYMBOL_CONST 0x0007 +#define SYMBOL_CHECK 0x0008 +#define SYMBOL_CHOICE 0x0010 +#define SYMBOL_CHOICEVAL 0x0020 +#define SYMBOL_PRINTED 0x0040 +#define SYMBOL_VALID 0x0080 +#define SYMBOL_OPTIONAL 0x0100 +#define SYMBOL_WRITE 0x0200 +#define SYMBOL_CHANGED 0x0400 +#define SYMBOL_NEW 0x0800 +#define SYMBOL_AUTO 0x1000 +#define SYMBOL_CHECKED 0x2000 +#define SYMBOL_CHECK_DONE 0x4000 +#define SYMBOL_WARNED 0x8000 + +#define SYMBOL_MAXLENGTH 256 +#define SYMBOL_HASHSIZE 257 +#define SYMBOL_HASHMASK 0xff + +enum prop_type { + P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE +}; + +struct property { + struct property *next; + struct symbol *sym; + enum prop_type type; + const char *text; + struct expr_value visible; + struct expr *expr; + struct menu *menu; + struct file *file; + int lineno; +}; + +#define for_all_properties(sym, st, tok) \ + for (st = sym->prop; st; st = st->next) \ + if (st->type == (tok)) +#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) +#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) +#define for_all_prompts(sym, st) \ + for (st = sym->prop; st; st = st->next) \ + if (st->text) + +struct menu { + struct menu *next; + struct menu *parent; + struct menu *list; + struct symbol *sym; + struct property *prompt; + struct expr *dep; + unsigned int flags; + //char *help; + struct file *file; + int lineno; + void *data; +}; + +#define MENU_CHANGED 0x0001 +#define MENU_ROOT 0x0002 + +#ifndef SWIG + +extern struct file *file_list; +extern struct file *current_file; +struct file *lookup_file(const char *name); + +extern struct symbol symbol_yes, symbol_no, symbol_mod; +extern struct symbol *modules_sym; +extern int cdebug; +struct expr *expr_alloc_symbol(struct symbol *sym); +struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); +struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); +struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); +struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); +struct expr *expr_copy(struct expr *org); +void expr_free(struct expr *e); +int expr_eq(struct expr *e1, struct expr *e2); +void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); +tristate expr_calc_value(struct expr *e); +struct expr *expr_eliminate_yn(struct expr *e); +struct expr *expr_trans_bool(struct expr *e); +struct expr *expr_eliminate_dups(struct expr *e); +struct expr *expr_transform(struct expr *e); +int expr_contains_symbol(struct expr *dep, struct symbol *sym); +bool expr_depends_symbol(struct expr *dep, struct symbol *sym); +struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); +struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); +void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); +struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); + +void expr_fprint(struct expr *e, FILE *out); +struct gstr; /* forward */ +void expr_gstr_print(struct expr *e, struct gstr *gs); + +static inline int expr_is_yes(struct expr *e) +{ + return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); +} + +static inline int expr_is_no(struct expr *e) +{ + return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EXPR_H */ diff --git a/circuitpython/lib/axtls/config/scripts/config/lex.zconf.c_shipped b/circuitpython/lib/axtls/config/scripts/config/lex.zconf.c_shipped new file mode 100644 index 0000000..b877bb6 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lex.zconf.c_shipped @@ -0,0 +1,3688 @@ + +#line 3 "lex.zconf.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 31 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE zconfrestart(zconfin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int zconfleng; + +extern FILE *zconfin, *zconfout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up zconftext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up zconftext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via zconfrestart()), so that the user can continue scanning by + * just pointing zconfin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when zconftext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int zconfleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow zconfwrap()'s to do buffer switches + * instead of setting up a fresh zconfin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void zconfrestart (FILE *input_file ); +void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size ); +void zconf_delete_buffer (YY_BUFFER_STATE b ); +void zconf_flush_buffer (YY_BUFFER_STATE b ); +void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ); +void zconfpop_buffer_state (void ); + +static void zconfensure_buffer_stack (void ); +static void zconf_load_buffer_state (void ); +static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len ); + +void *zconfalloc (yy_size_t ); +void *zconfrealloc (void *,yy_size_t ); +void zconffree (void * ); + +#define yy_new_buffer zconf_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + zconfensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + zconfensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define zconfwrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0; + +typedef int yy_state_type; + +extern int zconflineno; + +int zconflineno = 1; + +extern char *zconftext; +#define yytext_ptr zconftext +static yyconst flex_int16_t yy_nxt[][38] = + { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + + { + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12 + }, + + { + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12 + }, + + { + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, + 21, 22, 18, 18, 23, 24, 18, 25, 18, 26, + 27, 18, 28, 29, 30, 18, 18, 16 + }, + + { + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, + 21, 22, 18, 18, 23, 24, 18, 25, 18, 26, + 27, 18, 28, 29, 30, 18, 18, 16 + + }, + + { + 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31 + }, + + { + 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31 + }, + + { + 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, + 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, + + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34 + }, + + { + 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, + 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34 + }, + + { + 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, + 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 50, 47, 47, 47, 51, + 47, 47, 47, 47, 47, 47, 47, 52 + + }, + + { + 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, + 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 50, 47, 47, 47, 51, + 47, 47, 47, 47, 47, 47, 47, 52 + }, + + { + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11 + }, + + { + 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12 + }, + + { + 11, -13, 53, 54, -13, -13, 55, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13 + }, + + { + 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14 + + }, + + { + 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56 + }, + + { + 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16 + }, + + { + 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17 + }, + + { + 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, 58, -18, -18, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -18 + }, + + { + 11, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, 58, -19, -19, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, + 58, 58, 58, 58, 58, 58, 58, -19 + + }, + + { + 11, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, 58, -20, -20, 58, 58, 58, 58, + 58, 58, 58, 58, 60, 58, 58, 58, 58, 61, + 58, 58, 58, 58, 58, 58, 58, -20 + }, + + { + 11, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, 58, -21, -21, 58, 58, 58, 58, + 58, 62, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -21 + }, + + { + 11, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, 58, -22, -22, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 63, 58, + 58, 58, 58, 58, 58, 58, 58, -22 + }, + + { + 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, 58, -23, -23, 58, 58, 58, 58, + 58, 64, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -23 + }, + + { + 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, 58, -24, -24, 58, 58, 58, 58, + 58, 58, 65, 58, 58, 58, 58, 58, 66, 58, + 58, 58, 58, 58, 58, 58, 58, -24 + + }, + + { + 11, -25, -25, -25, -25, -25, -25, -25, -25, -25, + -25, -25, -25, 58, -25, -25, 58, 67, 58, 58, + 58, 68, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -25 + }, + + { + 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, 58, -26, -26, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 69, 58, 58, 58, 58, 58, 58, -26 + }, + + { + 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, 58, -27, -27, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 70, 58, 58, 58, 58, -27 + }, + + { + 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, 58, -28, -28, 58, 71, 58, 58, + 58, 72, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -28 + }, + + { + 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, 58, -29, -29, 58, 58, 58, 58, + 58, 73, 58, 58, 58, 58, 58, 58, 58, 74, + 58, 58, 58, 58, 75, 58, 58, -29 + + }, + + { + 11, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, 58, -30, -30, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 76, 58, 58, 58, 58, -30 + }, + + { + 11, 77, 77, -31, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77 + }, + + { + 11, -32, 78, 79, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32 + }, + + { + 11, 80, -33, -33, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80 + }, + + { + 11, 81, 81, 82, 81, -34, 81, 81, -34, 81, + 81, 81, 81, 81, 81, -34, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81 + + }, + + { + 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35 + }, + + { + 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36 + }, + + { + 11, 83, 83, 84, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83 + }, + + { + 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38 + }, + + { + 11, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39 + + }, + + { + 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, + -40, -40, -40, -40, 85, -40, -40, -40, -40, -40, + -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, + -40, -40, -40, -40, -40, -40, -40, -40 + }, + + { + 11, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41 + }, + + { + 11, 86, 86, -42, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86 + }, + + { + 11, -43, -43, -43, -43, -43, -43, 87, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43 + }, + + { + 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44 + + }, + + { + 11, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45 + }, + + { + 11, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, 88, 89, 89, -46, -46, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -46 + }, + + { + 11, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, 89, 89, 89, -47, -47, 89, 89, 89, 89, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -47 + }, + + { + 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48 + }, + + { + 11, -49, -49, 90, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49 + + }, + + { + 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, 89, 89, 89, -50, -50, 89, 89, 89, 89, + 89, 89, 91, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -50 + }, + + { + 11, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, 89, 89, 89, -51, -51, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 92, 89, + 89, 89, 89, 89, 89, 89, 89, -51 + }, + + { + 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, 93 + }, + + { + 11, -53, 53, 54, -53, -53, 55, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53 + }, + + { + 11, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54 + + }, + + { + 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56 + }, + + { + 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56 + }, + + { + 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57 + }, + + { + 11, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, 58, -58, -58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -58 + }, + + { + 11, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, 58, -59, -59, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 94, + 58, 58, 58, 58, 58, 58, 58, -59 + + }, + + { + 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, 58, -60, -60, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 95, + 58, 58, 58, 58, 58, 58, 58, -60 + }, + + { + 11, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, 58, -61, -61, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 96, 97, 58, + 58, 58, 58, 58, 58, 58, 58, -61 + }, + + { + 11, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, 58, -62, -62, 58, 58, 58, 58, + + 58, 58, 98, 58, 58, 58, 58, 58, 58, 58, + 99, 58, 58, 58, 58, 58, 58, -62 + }, + + { + 11, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, 58, -63, -63, 58, 100, 58, 58, + 101, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -63 + }, + + { + 11, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, 58, -64, -64, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 102, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 103, -64 + + }, + + { + 11, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, 58, -65, -65, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -65 + }, + + { + 11, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, 58, -66, -66, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 104, 58, 58, -66 + }, + + { + 11, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, 58, -67, -67, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 105, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -67 + }, + + { + 11, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, 58, -68, -68, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 106, 58, + 58, 58, 58, 58, 58, 58, 58, -68 + }, + + { + 11, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, 58, -69, -69, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 107, 58, 58, -69 + + }, + + { + 11, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, 58, -70, -70, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 108, + 58, 58, 58, 58, 58, 58, 58, -70 + }, + + { + 11, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, 58, -71, -71, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 109, 58, + 58, 58, 58, 58, 58, 58, 58, -71 + }, + + { + 11, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, 58, -72, -72, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 110, 58, 58, 58, 58, 58, -72 + }, + + { + 11, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, 58, -73, -73, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 111, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -73 + }, + + { + 11, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, 58, -74, -74, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 112, 58, -74 + + }, + + { + 11, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, 58, -75, -75, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 113, 58, 58, 58, 58, -75 + }, + + { + 11, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, 58, -76, -76, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 114, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -76 + }, + + { + 11, 77, 77, -77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77 + }, + + { + 11, -78, 78, 79, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78 + }, + + { + 11, 80, -79, -79, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80 + + }, + + { + 11, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80 + }, + + { + 11, 81, 81, 82, 81, -81, 81, 81, -81, 81, + 81, 81, 81, 81, 81, -81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81 + }, + + { + 11, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82 + }, + + { + 11, -83, -83, 84, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83 + }, + + { + 11, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84 + + }, + + { + 11, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85 + }, + + { + 11, 86, 86, -86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86 + }, + + { + 11, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87 + }, + + { + 11, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, 115, 89, 89, -88, -88, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -88 + }, + + { + 11, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, 89, 89, 89, -89, -89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -89 + + }, + + { + 11, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90 + }, + + { + 11, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, 89, 89, 89, -91, -91, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -91 + }, + + { + 11, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, 89, 89, 89, -92, -92, 89, 89, 89, 89, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -92 + }, + + { + 11, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93 + }, + + { + 11, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, 58, -94, -94, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 116, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -94 + + }, + + { + 11, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, 58, -95, -95, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 117, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -95 + }, + + { + 11, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, 58, -96, -96, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 118, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -96 + }, + + { + 11, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, 58, -97, -97, 58, 58, 58, 58, + + 58, 58, 119, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -97 + }, + + { + 11, -98, -98, -98, -98, -98, -98, -98, -98, -98, + -98, -98, -98, 58, -98, -98, 120, 121, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -98 + }, + + { + 11, -99, -99, -99, -99, -99, -99, -99, -99, -99, + -99, -99, -99, 58, -99, -99, 58, 58, 58, 58, + 58, 122, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -99 + + }, + + { + 11, -100, -100, -100, -100, -100, -100, -100, -100, -100, + -100, -100, -100, 58, -100, -100, 58, 58, 123, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -100 + }, + + { + 11, -101, -101, -101, -101, -101, -101, -101, -101, -101, + -101, -101, -101, 58, -101, -101, 58, 58, 58, 124, + 58, 58, 58, 58, 58, 125, 58, 126, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -101 + }, + + { + 11, -102, -102, -102, -102, -102, -102, -102, -102, -102, + -102, -102, -102, 58, -102, -102, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 127, 58, 58, 58, 58, 58, 58, -102 + }, + + { + 11, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, 58, -103, -103, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -103 + }, + + { + 11, -104, -104, -104, -104, -104, -104, -104, -104, -104, + -104, -104, -104, 58, -104, -104, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -104 + + }, + + { + 11, -105, -105, -105, -105, -105, -105, -105, -105, -105, + -105, -105, -105, 58, -105, -105, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 128, 58, + 58, 58, 58, 58, 58, 58, 58, -105 + }, + + { + 11, -106, -106, -106, -106, -106, -106, -106, -106, -106, + -106, -106, -106, 58, -106, -106, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 129, 58, -106 + }, + + { + 11, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, -107, 58, -107, -107, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 130, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -107 + }, + + { + 11, -108, -108, -108, -108, -108, -108, -108, -108, -108, + -108, -108, -108, 58, -108, -108, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 131, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -108 + }, + + { + 11, -109, -109, -109, -109, -109, -109, -109, -109, -109, + -109, -109, -109, 58, -109, -109, 58, 58, 58, 58, + 58, 58, 58, 132, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -109 + + }, + + { + 11, -110, -110, -110, -110, -110, -110, -110, -110, -110, + -110, -110, -110, 58, -110, -110, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 133, 58, -110 + }, + + { + 11, -111, -111, -111, -111, -111, -111, -111, -111, -111, + -111, -111, -111, 58, -111, -111, 58, 58, 58, 58, + 58, 134, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -111 + }, + + { + 11, -112, -112, -112, -112, -112, -112, -112, -112, -112, + -112, -112, -112, 58, -112, -112, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 135, 58, 58, 58, 58, -112 + }, + + { + 11, -113, -113, -113, -113, -113, -113, -113, -113, -113, + -113, -113, -113, 58, -113, -113, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 136, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -113 + }, + + { + 11, -114, -114, -114, -114, -114, -114, -114, -114, -114, + -114, -114, -114, 58, -114, -114, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 137, 58, 58, 58, -114 + + }, + + { + 11, -115, -115, -115, -115, -115, -115, -115, -115, -115, + -115, 89, 89, 89, -115, -115, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -115 + }, + + { + 11, -116, -116, -116, -116, -116, -116, -116, -116, -116, + -116, -116, -116, 58, -116, -116, 58, 58, 58, 58, + 58, 138, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -116 + }, + + { + 11, -117, -117, -117, -117, -117, -117, -117, -117, -117, + -117, -117, -117, 58, -117, -117, 58, 58, 58, 139, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -117 + }, + + { + 11, -118, -118, -118, -118, -118, -118, -118, -118, -118, + -118, -118, -118, 58, -118, -118, 58, 58, 58, 58, + 58, 140, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -118 + }, + + { + 11, -119, -119, -119, -119, -119, -119, -119, -119, -119, + -119, -119, -119, 58, -119, -119, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 141, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -119 + + }, + + { + 11, -120, -120, -120, -120, -120, -120, -120, -120, -120, + -120, -120, -120, 58, -120, -120, 58, 58, 142, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 143, 58, 58, -120 + }, + + { + 11, -121, -121, -121, -121, -121, -121, -121, -121, -121, + -121, -121, -121, 58, -121, -121, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 144, 58, -121 + }, + + { + 11, -122, -122, -122, -122, -122, -122, -122, -122, -122, + -122, -122, -122, 58, -122, -122, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 145, 58, + 58, 58, 58, 58, 58, 58, 58, -122 + }, + + { + 11, -123, -123, -123, -123, -123, -123, -123, -123, -123, + -123, -123, -123, 58, -123, -123, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 146, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -123 + }, + + { + 11, -124, -124, -124, -124, -124, -124, -124, -124, -124, + -124, -124, -124, 58, -124, -124, 58, 58, 58, 58, + 58, 58, 58, 58, 147, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -124 + + }, + + { + 11, -125, -125, -125, -125, -125, -125, -125, -125, -125, + -125, -125, -125, 58, -125, -125, 58, 58, 58, 58, + 58, 58, 148, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -125 + }, + + { + 11, -126, -126, -126, -126, -126, -126, -126, -126, -126, + -126, -126, -126, 58, -126, -126, 58, 58, 58, 58, + 58, 149, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -126 + }, + + { + 11, -127, -127, -127, -127, -127, -127, -127, -127, -127, + -127, -127, -127, 58, -127, -127, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -127 + }, + + { + 11, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, 58, -128, -128, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 150, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -128 + }, + + { + 11, -129, -129, -129, -129, -129, -129, -129, -129, -129, + -129, -129, -129, 58, -129, -129, 58, 58, 58, 151, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -129 + + }, + + { + 11, -130, -130, -130, -130, -130, -130, -130, -130, -130, + -130, -130, -130, 58, -130, -130, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 152, + 58, 58, 58, 58, 58, 58, 58, -130 + }, + + { + 11, -131, -131, -131, -131, -131, -131, -131, -131, -131, + -131, -131, -131, 58, -131, -131, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 153, 58, 58, 58, 58, 58, 58, -131 + }, + + { + 11, -132, -132, -132, -132, -132, -132, -132, -132, -132, + -132, -132, -132, 58, -132, -132, 58, 58, 58, 58, + + 58, 154, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -132 + }, + + { + 11, -133, -133, -133, -133, -133, -133, -133, -133, -133, + -133, -133, -133, 58, -133, -133, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 155, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -133 + }, + + { + 11, -134, -134, -134, -134, -134, -134, -134, -134, -134, + -134, -134, -134, 58, -134, -134, 58, 58, 58, 156, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -134 + + }, + + { + 11, -135, -135, -135, -135, -135, -135, -135, -135, -135, + -135, -135, -135, 58, -135, -135, 58, 58, 58, 157, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -135 + }, + + { + 11, -136, -136, -136, -136, -136, -136, -136, -136, -136, + -136, -136, -136, 58, -136, -136, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 158, 58, + 58, 58, 58, 58, 58, 58, 58, -136 + }, + + { + 11, -137, -137, -137, -137, -137, -137, -137, -137, -137, + -137, -137, -137, 58, -137, -137, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 159, 58, 58, -137 + }, + + { + 11, -138, -138, -138, -138, -138, -138, -138, -138, -138, + -138, -138, -138, 58, -138, -138, 58, 160, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -138 + }, + + { + 11, -139, -139, -139, -139, -139, -139, -139, -139, -139, + -139, -139, -139, 58, -139, -139, 58, 58, 58, 58, + 58, 161, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -139 + + }, + + { + 11, -140, -140, -140, -140, -140, -140, -140, -140, -140, + -140, -140, -140, 58, -140, -140, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 162, 58, + 58, 58, 58, 58, 58, 58, 58, -140 + }, + + { + 11, -141, -141, -141, -141, -141, -141, -141, -141, -141, + -141, -141, -141, 58, -141, -141, 58, 58, 58, 58, + 58, 58, 58, 163, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -141 + }, + + { + 11, -142, -142, -142, -142, -142, -142, -142, -142, -142, + -142, -142, -142, 58, -142, -142, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 164, + 58, 58, 58, 58, 58, 58, 58, -142 + }, + + { + 11, -143, -143, -143, -143, -143, -143, -143, -143, -143, + -143, -143, -143, 58, -143, -143, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 165, 58, 58, 58, 58, -143 + }, + + { + 11, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -144, -144, -144, 58, -144, -144, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 166, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -144 + + }, + + { + 11, -145, -145, -145, -145, -145, -145, -145, -145, -145, + -145, -145, -145, 58, -145, -145, 58, 58, 58, 58, + 167, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -145 + }, + + { + 11, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, 58, -146, -146, 58, 58, 58, 58, + 58, 168, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -146 + }, + + { + 11, -147, -147, -147, -147, -147, -147, -147, -147, -147, + -147, -147, -147, 58, -147, -147, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 169, + 58, 58, 58, 58, 58, 58, 58, -147 + }, + + { + 11, -148, -148, -148, -148, -148, -148, -148, -148, -148, + -148, -148, -148, 58, -148, -148, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -148 + }, + + { + 11, -149, -149, -149, -149, -149, -149, -149, -149, -149, + -149, -149, -149, 58, -149, -149, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 170, 58, + 58, 58, 58, 58, 58, 58, 58, -149 + + }, + + { + 11, -150, -150, -150, -150, -150, -150, -150, -150, -150, + -150, -150, -150, 58, -150, -150, 58, 58, 58, 58, + 58, 171, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -150 + }, + + { + 11, -151, -151, -151, -151, -151, -151, -151, -151, -151, + -151, -151, -151, 58, -151, -151, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 172, + 58, 58, 58, 58, 58, 58, 58, -151 + }, + + { + 11, -152, -152, -152, -152, -152, -152, -152, -152, -152, + -152, -152, -152, 58, -152, -152, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 173, 58, + 58, 58, 58, 58, 58, 58, 58, -152 + }, + + { + 11, -153, -153, -153, -153, -153, -153, -153, -153, -153, + -153, -153, -153, 58, -153, -153, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 174, 58, 58, -153 + }, + + { + 11, -154, -154, -154, -154, -154, -154, -154, -154, -154, + -154, -154, -154, 58, -154, -154, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -154 + + }, + + { + 11, -155, -155, -155, -155, -155, -155, -155, -155, -155, + -155, -155, -155, 58, -155, -155, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 175, 58, 58, 58, 58, -155 + }, + + { + 11, -156, -156, -156, -156, -156, -156, -156, -156, -156, + -156, -156, -156, 58, -156, -156, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 176, 58, 58, -156 + }, + + { + 11, -157, -157, -157, -157, -157, -157, -157, -157, -157, + -157, -157, -157, 58, -157, -157, 58, 58, 58, 58, + + 58, 177, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -157 + }, + + { + 11, -158, -158, -158, -158, -158, -158, -158, -158, -158, + -158, -158, -158, 58, -158, -158, 58, 58, 58, 58, + 58, 58, 58, 178, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -158 + }, + + { + 11, -159, -159, -159, -159, -159, -159, -159, -159, -159, + -159, -159, -159, 58, -159, -159, 58, 179, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -159 + + }, + + { + 11, -160, -160, -160, -160, -160, -160, -160, -160, -160, + -160, -160, -160, 58, -160, -160, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 180, 58, + 58, 58, 58, 58, 58, 58, 58, -160 + }, + + { + 11, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, 58, -161, -161, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -161 + }, + + { + 11, -162, -162, -162, -162, -162, -162, -162, -162, -162, + -162, -162, -162, 58, -162, -162, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 181, 58, 58, -162 + }, + + { + 11, -163, -163, -163, -163, -163, -163, -163, -163, -163, + -163, -163, -163, 58, -163, -163, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -163 + }, + + { + 11, -164, -164, -164, -164, -164, -164, -164, -164, -164, + -164, -164, -164, 58, -164, -164, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 182, + 58, 58, 58, 58, 58, 58, 58, -164 + + }, + + { + 11, -165, -165, -165, -165, -165, -165, -165, -165, -165, + -165, -165, -165, 58, -165, -165, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 183, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -165 + }, + + { + 11, -166, -166, -166, -166, -166, -166, -166, -166, -166, + -166, -166, -166, 58, -166, -166, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 184, 58, 58, -166 + }, + + { + 11, -167, -167, -167, -167, -167, -167, -167, -167, -167, + -167, -167, -167, 58, -167, -167, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 185, 58, 58, 58, -167 + }, + + { + 11, -168, -168, -168, -168, -168, -168, -168, -168, -168, + -168, -168, -168, 58, -168, -168, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -168 + }, + + { + 11, -169, -169, -169, -169, -169, -169, -169, -169, -169, + -169, -169, -169, 58, -169, -169, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 186, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -169 + + }, + + { + 11, -170, -170, -170, -170, -170, -170, -170, -170, -170, + -170, -170, -170, 58, -170, -170, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 187, 58, -170 + }, + + { + 11, -171, -171, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -171, 58, -171, -171, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 188, 58, + 58, 58, 58, 58, 58, 58, 58, -171 + }, + + { + 11, -172, -172, -172, -172, -172, -172, -172, -172, -172, + -172, -172, -172, 58, -172, -172, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 189, 58, + 58, 58, 58, 58, 58, 58, 58, -172 + }, + + { + 11, -173, -173, -173, -173, -173, -173, -173, -173, -173, + -173, -173, -173, 58, -173, -173, 58, 190, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -173 + }, + + { + 11, -174, -174, -174, -174, -174, -174, -174, -174, -174, + -174, -174, -174, 58, -174, -174, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -174 + + }, + + { + 11, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -175, -175, -175, 58, -175, -175, 58, 58, 58, 58, + 58, 191, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -175 + }, + + { + 11, -176, -176, -176, -176, -176, -176, -176, -176, -176, + -176, -176, -176, 58, -176, -176, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -176 + }, + + { + 11, -177, -177, -177, -177, -177, -177, -177, -177, -177, + -177, -177, -177, 58, -177, -177, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -177 + }, + + { + 11, -178, -178, -178, -178, -178, -178, -178, -178, -178, + -178, -178, -178, 58, -178, -178, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -178 + }, + + { + 11, -179, -179, -179, -179, -179, -179, -179, -179, -179, + -179, -179, -179, 58, -179, -179, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 192, 58, 58, -179 + + }, + + { + 11, -180, -180, -180, -180, -180, -180, -180, -180, -180, + -180, -180, -180, 58, -180, -180, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -180 + }, + + { + 11, -181, -181, -181, -181, -181, -181, -181, -181, -181, + -181, -181, -181, 58, -181, -181, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -181 + }, + + { + 11, -182, -182, -182, -182, -182, -182, -182, -182, -182, + -182, -182, -182, 58, -182, -182, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 193, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -182 + }, + + { + 11, -183, -183, -183, -183, -183, -183, -183, -183, -183, + -183, -183, -183, 58, -183, -183, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 194, 58, 58, 58, -183 + }, + + { + 11, -184, -184, -184, -184, -184, -184, -184, -184, -184, + -184, -184, -184, 58, -184, -184, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -184 + + }, + + { + 11, -185, -185, -185, -185, -185, -185, -185, -185, -185, + -185, -185, -185, 58, -185, -185, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -185 + }, + + { + 11, -186, -186, -186, -186, -186, -186, -186, -186, -186, + -186, -186, -186, 58, -186, -186, 58, 58, 58, 195, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -186 + }, + + { + 11, -187, -187, -187, -187, -187, -187, -187, -187, -187, + -187, -187, -187, 58, -187, -187, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -187 + }, + + { + 11, -188, -188, -188, -188, -188, -188, -188, -188, -188, + -188, -188, -188, 58, -188, -188, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 196, 58, -188 + }, + + { + 11, -189, -189, -189, -189, -189, -189, -189, -189, -189, + -189, -189, -189, 58, -189, -189, 58, 58, 58, 58, + 58, 58, 197, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -189 + + }, + + { + 11, -190, -190, -190, -190, -190, -190, -190, -190, -190, + -190, -190, -190, 58, -190, -190, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 198, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -190 + }, + + { + 11, -191, -191, -191, -191, -191, -191, -191, -191, -191, + -191, -191, -191, 58, -191, -191, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 199, 58, 58, 58, -191 + }, + + { + 11, -192, -192, -192, -192, -192, -192, -192, -192, -192, + -192, -192, -192, 58, -192, -192, 58, 58, 58, 58, + + 58, 200, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -192 + }, + + { + 11, -193, -193, -193, -193, -193, -193, -193, -193, -193, + -193, -193, -193, 58, -193, -193, 58, 58, 58, 58, + 58, 201, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -193 + }, + + { + 11, -194, -194, -194, -194, -194, -194, -194, -194, -194, + -194, -194, -194, 58, -194, -194, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 202, 58, 58, -194 + + }, + + { + 11, -195, -195, -195, -195, -195, -195, -195, -195, -195, + -195, -195, -195, 58, -195, -195, 58, 58, 58, 58, + 58, 203, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -195 + }, + + { + 11, -196, -196, -196, -196, -196, -196, -196, -196, -196, + -196, -196, -196, 58, -196, -196, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -196 + }, + + { + 11, -197, -197, -197, -197, -197, -197, -197, -197, -197, + -197, -197, -197, 58, -197, -197, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 204, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -197 + }, + + { + 11, -198, -198, -198, -198, -198, -198, -198, -198, -198, + -198, -198, -198, 58, -198, -198, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -198 + }, + + { + 11, -199, -199, -199, -199, -199, -199, -199, -199, -199, + -199, -199, -199, 58, -199, -199, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -199 + + }, + + { + 11, -200, -200, -200, -200, -200, -200, -200, -200, -200, + -200, -200, -200, 58, -200, -200, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -200 + }, + + { + 11, -201, -201, -201, -201, -201, -201, -201, -201, -201, + -201, -201, -201, 58, -201, -201, 58, 205, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -201 + }, + + { + 11, -202, -202, -202, -202, -202, -202, -202, -202, -202, + -202, -202, -202, 58, -202, -202, 58, 206, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -202 + }, + + { + 11, -203, -203, -203, -203, -203, -203, -203, -203, -203, + -203, -203, -203, 58, -203, -203, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -203 + }, + + { + 11, -204, -204, -204, -204, -204, -204, -204, -204, -204, + -204, -204, -204, 58, -204, -204, 58, 58, 58, 58, + 58, 58, 58, 207, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -204 + + }, + + { + 11, -205, -205, -205, -205, -205, -205, -205, -205, -205, + -205, -205, -205, 58, -205, -205, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 208, 58, + 58, 58, 58, 58, 58, 58, 58, -205 + }, + + { + 11, -206, -206, -206, -206, -206, -206, -206, -206, -206, + -206, -206, -206, 58, -206, -206, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 209, 58, 58, -206 + }, + + { + 11, -207, -207, -207, -207, -207, -207, -207, -207, -207, + -207, -207, -207, 58, -207, -207, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -207 + }, + + { + 11, -208, -208, -208, -208, -208, -208, -208, -208, -208, + -208, -208, -208, 58, -208, -208, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -208 + }, + + { + 11, -209, -209, -209, -209, -209, -209, -209, -209, -209, + -209, -209, -209, 58, -209, -209, 58, 58, 58, 58, + 58, 210, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -209 + + }, + + { + 11, -210, -210, -210, -210, -210, -210, -210, -210, -210, + -210, -210, -210, 58, -210, -210, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -210 + }, + + } ; + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up zconftext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + zconfleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 64 +#define YY_END_OF_BUFFER 65 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[211] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 65, 5, 4, 3, 2, 36, 37, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 63, 60, 62, 55, 59, 58, 57, 53, 48, 42, + 47, 51, 53, 40, 41, 50, 50, 43, 53, 50, + 50, 53, 4, 3, 2, 2, 1, 35, 35, 35, + 35, 35, 35, 35, 16, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 63, 60, 62, 61, + 55, 54, 57, 56, 44, 51, 38, 50, 50, 52, + 45, 46, 39, 35, 35, 35, 35, 35, 35, 35, + + 35, 35, 30, 29, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 49, 25, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 15, 35, 7, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 17, 35, 35, + 35, 35, 35, 34, 35, 35, 35, 35, 35, 35, + 10, 35, 13, 35, 35, 35, 35, 33, 35, 35, + 35, 35, 35, 22, 35, 32, 9, 31, 35, 26, + 12, 35, 35, 21, 18, 35, 8, 35, 35, 35, + 35, 35, 27, 35, 35, 6, 35, 20, 19, 23, + + 35, 35, 11, 35, 35, 35, 14, 28, 35, 24 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 6, 1, 1, 7, 8, 9, + 10, 1, 1, 1, 11, 12, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, + 14, 1, 1, 1, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 1, 15, 1, 1, 16, 1, 17, 18, 19, 20, + + 21, 22, 23, 24, 25, 13, 13, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 13, 13, 36, + 13, 13, 1, 37, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +extern int zconf_flex_debug; +int zconf_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *zconftext; + +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +#define START_STRSIZE 16 + +char *text; +static char *text_ptr; +static int text_size, text_asize; + +struct buffer { + struct buffer *parent; + YY_BUFFER_STATE state; +}; + +struct buffer *current_buf; + +static int last_ts, first_ts; + +static void zconf_endhelp(void); +static struct buffer *zconf_endfile(void); + +void new_string(void) +{ + text = malloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_ptr = text; + text_size = 0; + *text_ptr = 0; +} + +void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + text = realloc(text, new_size); + text_asize = new_size; + text_ptr = text + text_size; + } + memcpy(text_ptr, str, size); + text_ptr += size; + text_size += size; + *text_ptr = 0; +} + +void alloc_string(const char *str, int size) +{ + text = malloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} + +#define INITIAL 0 +#define COMMAND 1 +#define HELP 2 +#define STRING 3 +#define PARAM 4 + +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int zconfwrap (void ); +#else +extern int zconfwrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( zconftext, zconfleng, 1, zconfout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + errno=0; \ + while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(zconfin); \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int zconflex (void); + +#define YY_DECL int zconflex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after zconftext and zconfleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + + int str = 0; + int ts, i; + + if ( (yy_init) ) + { + (yy_init) = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! zconfin ) + zconfin = stdin; + + if ( ! zconfout ) + zconfout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + zconfensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + zconf_create_buffer(zconfin,YY_BUF_SIZE ); + } + + zconf_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of zconftext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)] ]) > 0 ) + ++yy_cp; + + yy_current_state = -yy_current_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +current_file->lineno++; + YY_BREAK +case 2: +YY_RULE_SETUP + + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +current_file->lineno++; return T_EOL; + YY_BREAK +case 4: +YY_RULE_SETUP +{ + BEGIN(COMMAND); +} + YY_BREAK +case 5: +YY_RULE_SETUP +{ + unput(zconftext[0]); + BEGIN(COMMAND); +} + YY_BREAK + +case 6: +YY_RULE_SETUP +BEGIN(PARAM); return T_MAINMENU; + YY_BREAK +case 7: +YY_RULE_SETUP +BEGIN(PARAM); return T_MENU; + YY_BREAK +case 8: +YY_RULE_SETUP +BEGIN(PARAM); return T_ENDMENU; + YY_BREAK +case 9: +YY_RULE_SETUP +BEGIN(PARAM); return T_SOURCE; + YY_BREAK +case 10: +YY_RULE_SETUP +BEGIN(PARAM); return T_CHOICE; + YY_BREAK +case 11: +YY_RULE_SETUP +BEGIN(PARAM); return T_ENDCHOICE; + YY_BREAK +case 12: +YY_RULE_SETUP +BEGIN(PARAM); return T_COMMENT; + YY_BREAK +case 13: +YY_RULE_SETUP +BEGIN(PARAM); return T_CONFIG; + YY_BREAK +case 14: +YY_RULE_SETUP +BEGIN(PARAM); return T_MENUCONFIG; + YY_BREAK +case 15: +YY_RULE_SETUP +BEGIN(PARAM); return T_HELP; + YY_BREAK +case 16: +YY_RULE_SETUP +BEGIN(PARAM); return T_IF; + YY_BREAK +case 17: +YY_RULE_SETUP +BEGIN(PARAM); return T_ENDIF; + YY_BREAK +case 18: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEPENDS; + YY_BREAK +case 19: +YY_RULE_SETUP +BEGIN(PARAM); return T_REQUIRES; + YY_BREAK +case 20: +YY_RULE_SETUP +BEGIN(PARAM); return T_OPTIONAL; + YY_BREAK +case 21: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEFAULT; + YY_BREAK +case 22: +YY_RULE_SETUP +BEGIN(PARAM); return T_PROMPT; + YY_BREAK +case 23: +YY_RULE_SETUP +BEGIN(PARAM); return T_TRISTATE; + YY_BREAK +case 24: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEF_TRISTATE; + YY_BREAK +case 25: +YY_RULE_SETUP +BEGIN(PARAM); return T_BOOLEAN; + YY_BREAK +case 26: +YY_RULE_SETUP +BEGIN(PARAM); return T_BOOLEAN; + YY_BREAK +case 27: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEF_BOOLEAN; + YY_BREAK +case 28: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEF_BOOLEAN; + YY_BREAK +case 29: +YY_RULE_SETUP +BEGIN(PARAM); return T_INT; + YY_BREAK +case 30: +YY_RULE_SETUP +BEGIN(PARAM); return T_HEX; + YY_BREAK +case 31: +YY_RULE_SETUP +BEGIN(PARAM); return T_STRING; + YY_BREAK +case 32: +YY_RULE_SETUP +BEGIN(PARAM); return T_SELECT; + YY_BREAK +case 33: +YY_RULE_SETUP +BEGIN(PARAM); return T_SELECT; + YY_BREAK +case 34: +YY_RULE_SETUP +BEGIN(PARAM); return T_RANGE; + YY_BREAK +case 35: +YY_RULE_SETUP +{ + alloc_string(zconftext, zconfleng); + zconflval.string = text; + return T_WORD; + } + YY_BREAK +case 36: +YY_RULE_SETUP + + YY_BREAK +case 37: +/* rule 37 can match eol */ +YY_RULE_SETUP +current_file->lineno++; BEGIN(INITIAL); + YY_BREAK + +case 38: +YY_RULE_SETUP +return T_AND; + YY_BREAK +case 39: +YY_RULE_SETUP +return T_OR; + YY_BREAK +case 40: +YY_RULE_SETUP +return T_OPEN_PAREN; + YY_BREAK +case 41: +YY_RULE_SETUP +return T_CLOSE_PAREN; + YY_BREAK +case 42: +YY_RULE_SETUP +return T_NOT; + YY_BREAK +case 43: +YY_RULE_SETUP +return T_EQUAL; + YY_BREAK +case 44: +YY_RULE_SETUP +return T_UNEQUAL; + YY_BREAK +case 45: +YY_RULE_SETUP +return T_IF; + YY_BREAK +case 46: +YY_RULE_SETUP +return T_ON; + YY_BREAK +case 47: +YY_RULE_SETUP +{ + str = zconftext[0]; + new_string(); + BEGIN(STRING); + } + YY_BREAK +case 48: +/* rule 48 can match eol */ +YY_RULE_SETUP +BEGIN(INITIAL); current_file->lineno++; return T_EOL; + YY_BREAK +case 49: +YY_RULE_SETUP +/* ignore */ + YY_BREAK +case 50: +YY_RULE_SETUP +{ + alloc_string(zconftext, zconfleng); + zconflval.string = text; + return T_WORD; + } + YY_BREAK +case 51: +YY_RULE_SETUP +/* comment */ + YY_BREAK +case 52: +/* rule 52 can match eol */ +YY_RULE_SETUP +current_file->lineno++; + YY_BREAK +case 53: +YY_RULE_SETUP + + YY_BREAK +case YY_STATE_EOF(PARAM): +{ + BEGIN(INITIAL); + } + YY_BREAK + +case 54: +/* rule 54 can match eol */ +*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up zconftext again */ +YY_RULE_SETUP +{ + append_string(zconftext, zconfleng); + zconflval.string = text; + return T_WORD_QUOTE; + } + YY_BREAK +case 55: +YY_RULE_SETUP +{ + append_string(zconftext, zconfleng); + } + YY_BREAK +case 56: +/* rule 56 can match eol */ +*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up zconftext again */ +YY_RULE_SETUP +{ + append_string(zconftext + 1, zconfleng - 1); + zconflval.string = text; + return T_WORD_QUOTE; + } + YY_BREAK +case 57: +YY_RULE_SETUP +{ + append_string(zconftext + 1, zconfleng - 1); + } + YY_BREAK +case 58: +YY_RULE_SETUP +{ + if (str == zconftext[0]) { + BEGIN(PARAM); + zconflval.string = text; + return T_WORD_QUOTE; + } else + append_string(zconftext, 1); + } + YY_BREAK +case 59: +/* rule 59 can match eol */ +YY_RULE_SETUP +{ + printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); + current_file->lineno++; + BEGIN(INITIAL); + return T_EOL; + } + YY_BREAK +case YY_STATE_EOF(STRING): +{ + BEGIN(INITIAL); + } + YY_BREAK + +case 60: +YY_RULE_SETUP +{ + ts = 0; + for (i = 0; i < zconfleng; i++) { + if (zconftext[i] == '\t') + ts = (ts & ~7) + 8; + else + ts++; + } + last_ts = ts; + if (first_ts) { + if (ts < first_ts) { + zconf_endhelp(); + return T_HELPTEXT; + } + ts -= first_ts; + while (ts > 8) { + append_string(" ", 8); + ts -= 8; + } + append_string(" ", ts); + } + } + YY_BREAK +case 61: +/* rule 61 can match eol */ +*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up zconftext again */ +YY_RULE_SETUP +{ + current_file->lineno++; + zconf_endhelp(); + return T_HELPTEXT; + } + YY_BREAK +case 62: +/* rule 62 can match eol */ +YY_RULE_SETUP +{ + current_file->lineno++; + append_string("\n", 1); + } + YY_BREAK +case 63: +YY_RULE_SETUP +{ + append_string(zconftext, zconfleng); + if (!first_ts) + first_ts = last_ts; + } + YY_BREAK +case YY_STATE_EOF(HELP): +{ + zconf_endhelp(); + return T_HELPTEXT; + } + YY_BREAK + +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(COMMAND): +{ + if (current_buf) { + zconf_endfile(); + return T_EOF; + } + fclose(zconfin); + yyterminate(); +} + YY_BREAK +case 64: +YY_RULE_SETUP +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed zconfin at a new source and called + * zconflex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( zconfwrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * zconftext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of zconflex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + zconfrestart(zconfin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + + yy_current_state = yy_nxt[yy_current_state][1]; + yy_is_jam = (yy_current_state <= 0); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up zconftext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + zconfrestart(zconfin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( zconfwrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve zconftext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void zconfrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + zconfensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + zconf_create_buffer(zconfin,YY_BUF_SIZE ); + } + + zconf_init_buffer(YY_CURRENT_BUFFER,input_file ); + zconf_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * zconfpop_buffer_state(); + * zconfpush_buffer_state(new_buffer); + */ + zconfensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + zconf_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (zconfwrap()) processing, but the only time this flag + * is looked at is after zconfwrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void zconf_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + zconf_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with zconf_create_buffer() + * + */ + void zconf_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + zconffree((void *) b->yy_ch_buf ); + + zconffree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a zconfrestart() or at EOF. + */ + static void zconf_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + zconf_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then zconf_init_buffer was _probably_ + * called from zconfrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void zconf_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + zconf_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + zconfensure_buffer_stack(); + + /* This block is copied from zconf_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from zconf_switch_to_buffer. */ + zconf_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void zconfpop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + zconf_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + zconf_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void zconfensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + zconf_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to zconflex() will + * scan from a @e copy of @a str. + * @param str a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * zconf_scan_bytes() instead. + */ +YY_BUFFER_STATE zconf_scan_string (yyconst char * str ) +{ + + return zconf_scan_bytes(str,strlen(str) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) zconfalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = zconf_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up zconftext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + zconftext[zconfleng] = (yy_hold_char); \ + (yy_c_buf_p) = zconftext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + zconfleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int zconfget_lineno (void) +{ + + return zconflineno; +} + +/** Get the input stream. + * + */ +FILE *zconfget_in (void) +{ + return zconfin; +} + +/** Get the output stream. + * + */ +FILE *zconfget_out (void) +{ + return zconfout; +} + +/** Get the length of the current token. + * + */ +int zconfget_leng (void) +{ + return zconfleng; +} + +/** Get the current token. + * + */ + +char *zconfget_text (void) +{ + return zconftext; +} + +/** Set the current line number. + * @param line_number + * + */ +void zconfset_lineno (int line_number ) +{ + + zconflineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see zconf_switch_to_buffer + */ +void zconfset_in (FILE * in_str ) +{ + zconfin = in_str ; +} + +void zconfset_out (FILE * out_str ) +{ + zconfout = out_str ; +} + +int zconfget_debug (void) +{ + return zconf_flex_debug; +} + +void zconfset_debug (int bdebug ) +{ + zconf_flex_debug = bdebug ; +} + +/* zconflex_destroy is for both reentrant and non-reentrant scanners. */ +int zconflex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + zconf_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + zconfpop_buffer_state(); + } + + /* Destroy the stack itself. */ + zconffree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *zconfalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *zconfrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void zconffree (void * ptr ) +{ + free( (char *) ptr ); /* see zconfrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef yytext_ptr +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +void zconf_starthelp(void) +{ + new_string(); + last_ts = first_ts = 0; + BEGIN(HELP); +} + +static void zconf_endhelp(void) +{ + zconflval.string = text; + BEGIN(INITIAL); +} + +/* + * Try to open specified file with following names: + * ./name + * $(srctree)/name + * The latter is used when srctree is separate from objtree + * when compiling the kernel. + * Return NULL if file is not found. + */ +FILE *zconf_fopen(const char *name) +{ + char *env, fullname[PATH_MAX+1]; + FILE *f; + + f = fopen(name, "r"); + if (!f && name[0] != '/') { + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + f = fopen(fullname, "r"); + } + } + return f; +} + +void zconf_initscan(const char *name) +{ + zconfin = zconf_fopen(name); + if (!zconfin) { + printf("can't find file %s\n", name); + exit(1); + } + + current_buf = malloc(sizeof(*current_buf)); + memset(current_buf, 0, sizeof(*current_buf)); + + current_file = file_lookup(name); + current_file->lineno = 1; + current_file->flags = FILE_BUSY; +} + +void zconf_nextfile(const char *name) +{ + struct file *file = file_lookup(name); + struct buffer *buf = malloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + current_buf->state = YY_CURRENT_BUFFER; + zconfin = zconf_fopen(name); + if (!zconfin) { + printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + exit(1); + } + zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + if (file->flags & FILE_BUSY) { + printf("recursive scan (%s)?\n", name); + exit(1); + } + if (file->flags & FILE_SCANNED) { + printf("file %s already scanned?\n", name); + exit(1); + } + file->flags |= FILE_BUSY; + file->lineno = 1; + file->parent = current_file; + current_file = file; +} + +static struct buffer *zconf_endfile(void) +{ + struct buffer *parent; + + current_file->flags |= FILE_SCANNED; + current_file->flags &= ~FILE_BUSY; + current_file = current_file->parent; + + parent = current_buf->parent; + if (parent) { + fclose(zconfin); + zconf_delete_buffer(YY_CURRENT_BUFFER); + zconf_switch_to_buffer(parent->state); + } + free(current_buf); + current_buf = parent; + + return parent; +} + +int zconf_lineno(void) +{ + if (current_buf) + return current_file->lineno - 1; + else + return 0; +} + +char *zconf_curname(void) +{ + if (current_buf) + return current_file->name; + else + return ""; +} + diff --git a/circuitpython/lib/axtls/config/scripts/config/lkc.h b/circuitpython/lib/axtls/config/scripts/config/lkc.h new file mode 100644 index 0000000..b8a67fc --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lkc.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef LKC_H +#define LKC_H + +#include "expr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef LKC_DIRECT_LINK +#define P(name,type,arg) extern type name arg +#else +#include "lkc_defs.h" +#define P(name,type,arg) extern type (*name ## _p) arg +#endif +#include "lkc_proto.h" +#undef P + +#define SRCTREE "srctree" + +int zconfparse(void); +void zconfdump(FILE *out); + +extern int zconfdebug; +void zconf_starthelp(void); +FILE *zconf_fopen(const char *name); +void zconf_initscan(const char *name); +void zconf_nextfile(const char *name); +int zconf_lineno(void); +char *zconf_curname(void); + +/* confdata.c */ +extern const char conf_def_filename[]; +extern char conf_filename[]; + +char *conf_get_default_confname(void); + +/* kconfig_load.c */ +void kconfig_load(void); + +/* menu.c */ +void menu_init(void); +void menu_add_menu(void); +void menu_end_menu(void); +void menu_add_entry(struct symbol *sym); +void menu_end_entry(void); +void menu_add_dep(struct expr *dep); +struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); +void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); +void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); +void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); +void menu_finalize(struct menu *parent); +void menu_set_type(int type); + +/* util.c */ +struct file *file_lookup(const char *name); +int file_write_dep(const char *name); + +struct gstr { + size_t len; + char *s; +}; +struct gstr str_new(void); +struct gstr str_assign(const char *s); +void str_free(struct gstr *gs); +void str_append(struct gstr *gs, const char *s); +void str_printf(struct gstr *gs, const char *fmt, ...); +const char *str_get(struct gstr *gs); + +/* symbol.c */ +void sym_init(void); +void sym_clear_all_valid(void); +void sym_set_changed(struct symbol *sym); +struct symbol *sym_check_deps(struct symbol *sym); +struct property *prop_alloc(enum prop_type type, struct symbol *sym); +struct symbol *prop_get_symbol(struct property *prop); + +static inline tristate sym_get_tristate_value(struct symbol *sym) +{ + return sym->curr.tri; +} + + +static inline struct symbol *sym_get_choice_value(struct symbol *sym) +{ + return (struct symbol *)sym->curr.val; +} + +static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) +{ + return sym_set_tristate_value(chval, yes); +} + +static inline bool sym_is_choice(struct symbol *sym) +{ + return sym->flags & SYMBOL_CHOICE ? true : false; +} + +static inline bool sym_is_choice_value(struct symbol *sym) +{ + return sym->flags & SYMBOL_CHOICEVAL ? true : false; +} + +static inline bool sym_is_optional(struct symbol *sym) +{ + return sym->flags & SYMBOL_OPTIONAL ? true : false; +} + +static inline bool sym_has_value(struct symbol *sym) +{ + return sym->flags & SYMBOL_NEW ? false : true; +} + +#ifdef __cplusplus +} +#endif + +#endif /* LKC_H */ diff --git a/circuitpython/lib/axtls/config/scripts/config/lkc_proto.h b/circuitpython/lib/axtls/config/scripts/config/lkc_proto.h new file mode 100644 index 0000000..6dc6d0c --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lkc_proto.h @@ -0,0 +1,40 @@ + +/* confdata.c */ +P(conf_parse,void,(const char *name)); +P(conf_read,int,(const char *name)); +P(conf_write,int,(const char *name)); + +/* menu.c */ +P(rootmenu,struct menu,); + +P(menu_is_visible,bool,(struct menu *menu)); +P(menu_get_prompt,const char *,(struct menu *menu)); +P(menu_get_root_menu,struct menu *,(struct menu *menu)); +P(menu_get_parent_menu,struct menu *,(struct menu *menu)); + +/* symbol.c */ +P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); +P(sym_change_count,int,); + +P(sym_lookup,struct symbol *,(const char *name, int isconst)); +P(sym_find,struct symbol *,(const char *name)); +P(sym_re_search,struct symbol **,(const char *pattern)); +P(sym_type_name,const char *,(enum symbol_type type)); +P(sym_calc_value,void,(struct symbol *sym)); +P(sym_get_type,enum symbol_type,(struct symbol *sym)); +P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); +P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); +P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); +P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); +P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); +P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); +P(sym_is_changable,bool,(struct symbol *sym)); +P(sym_get_choice_prop,struct property *,(struct symbol *sym)); +P(sym_get_default_prop,struct property *,(struct symbol *sym)); +P(sym_get_string_value,const char *,(struct symbol *sym)); + +P(prop_get_type_name,const char *,(enum prop_type type)); + +/* expr.c */ +P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); +P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)); diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/BIG.FAT.WARNING b/circuitpython/lib/axtls/config/scripts/config/lxdialog/BIG.FAT.WARNING new file mode 100644 index 0000000..a8999d8 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/BIG.FAT.WARNING @@ -0,0 +1,4 @@ +This is NOT the official version of dialog. This version has been +significantly modified from the original. It is for use by the Linux +kernel configuration script. Please do not bother Savio Lam with +questions about this program. diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/checklist.c b/circuitpython/lib/axtls/config/scripts/config/lxdialog/checklist.c new file mode 100644 index 0000000..71de4a1 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/checklist.c @@ -0,0 +1,372 @@ +/* + * checklist.c -- implements the checklist box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension + * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static int list_width, check_x, item_x, checkflag; + +/* + * Print list item + */ +static void +print_item (WINDOW * win, const char *item, int status, + int choice, int selected) +{ + int i; + + /* Clear 'residue' of last item */ + wattrset (win, menubox_attr); + wmove (win, choice, 0); + for (i = 0; i < list_width; i++) + waddch (win, ' '); + + wmove (win, choice, check_x); + wattrset (win, selected ? check_selected_attr : check_attr); + if (checkflag == FLAG_CHECK) + wprintw (win, "[%c]", status ? 'X' : ' '); + else + wprintw (win, "(%c)", status ? 'X' : ' '); + + wattrset (win, selected ? tag_selected_attr : tag_attr); + mvwaddch(win, choice, item_x, item[0]); + wattrset (win, selected ? item_selected_attr : item_attr); + waddstr (win, (char *)item+1); + if (selected) { + wmove (win, choice, check_x+1); + wrefresh (win); + } +} + +/* + * Print the scroll indicators. + */ +static void +print_arrows (WINDOW * win, int choice, int item_no, int scroll, + int y, int x, int height) +{ + wmove(win, y, x); + + if (scroll > 0) { + wattrset (win, uarrow_attr); + waddch (win, ACS_UARROW); + waddstr (win, "(-)"); + } + else { + wattrset (win, menubox_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + + if ((height < item_no) && (scroll + choice < item_no - 1)) { + wattrset (win, darrow_attr); + waddch (win, ACS_DARROW); + waddstr (win, "(+)"); + } + else { + wattrset (win, menubox_border_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } +} + +/* + * Display the termination buttons + */ +static void +print_buttons( WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button (dialog, "Select", y, x, selected == 0); + print_button (dialog, " Help ", y, x + 14, selected == 1); + + wmove(dialog, y, x+1 + 14*selected); + wrefresh (dialog); +} + +/* + * Display a dialog box with a list of options that can be turned on or off + * The `flag' parameter is used to select between radiolist and checklist. + */ +int +dialog_checklist (const char *title, const char *prompt, int height, int width, + int list_height, int item_no, struct dialog_list_item ** items, + int flag) + +{ + int i, x, y, box_x, box_y; + int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; + WINDOW *dialog, *list; + + checkflag = flag; + + /* Allocate space for storing item on/off status */ + if ((status = malloc (sizeof (int) * item_no)) == NULL) { + endwin (); + fprintf (stderr, + "\nCan't allocate memory in dialog_checklist().\n"); + exit (-1); + } + + /* Initializes status */ + for (i = 0; i < item_no; i++) { + status[i] = (items[i]->selected == 1); /* ON */ + if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */ + choice = i + 1; + } + if (choice) + choice--; + + max_choice = MIN (list_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + list_width = width - 6; + box_y = height - list_height - 5; + box_x = (width - list_width) / 2 - 1; + + /* create new window for the list */ + list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1); + + keypad (list, TRUE); + + /* draw a box around the list items */ + draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2, + menubox_border_attr, menubox_attr); + + /* Find length of longest item in order to center checklist */ + check_x = 0; + for (i = 0; i < item_no; i++) + check_x = MAX (check_x, + strlen (items[i]->name) + 4); + + check_x = (list_width - check_x) / 2; + item_x = check_x + 4; + + if (choice >= list_height) { + scroll = choice - list_height + 1; + choice -= scroll; + } + + /* Print the list */ + for (i = 0; i < max_choice; i++) { + print_item (list, items[scroll + i]->name, + status[i+scroll], i, i == choice); + } + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + print_buttons(dialog, height, width, 0); + + wnoutrefresh (list); + wnoutrefresh (dialog); + doupdate (); + + while (key != ESC) { + key = wgetch (dialog); + + for (i = 0; i < max_choice; i++) + if (toupper(key) == toupper(items[scroll + i]->name[0])) + break; + + + if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || + key == '+' || key == '-' ) { + if (key == KEY_UP || key == '-') { + if (!choice) { + if (!scroll) + continue; + /* Scroll list down */ + if (list_height > 1) { + /* De-highlight current first item */ + print_item (list, items[scroll]->name, + status[scroll], 0, FALSE); + scrollok (list, TRUE); + wscrl (list, -1); + scrollok (list, FALSE); + } + scroll--; + print_item (list, items[scroll]->name, + status[scroll], 0, TRUE); + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + wrefresh (dialog); + + continue; /* wait for another key press */ + } else + i = choice - 1; + } else if (key == KEY_DOWN || key == '+') { + if (choice == max_choice - 1) { + if (scroll + choice >= item_no - 1) + continue; + /* Scroll list up */ + if (list_height > 1) { + /* De-highlight current last item before scrolling up */ + print_item (list, items[scroll + max_choice - 1]->name, + status[scroll + max_choice - 1], + max_choice - 1, FALSE); + scrollok (list, TRUE); + scroll (list); + scrollok (list, FALSE); + } + scroll++; + print_item (list, items[scroll + max_choice - 1]->name, + status[scroll + max_choice - 1], + max_choice - 1, TRUE); + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + wrefresh (dialog); + + continue; /* wait for another key press */ + } else + i = choice + 1; + } + if (i != choice) { + /* De-highlight current item */ + print_item (list, items[scroll + choice]->name, + status[scroll + choice], choice, FALSE); + /* Highlight new item */ + choice = i; + print_item (list, items[scroll + choice]->name, + status[scroll + choice], choice, TRUE); + wnoutrefresh (list); + wrefresh (dialog); + } + continue; /* wait for another key press */ + } + switch (key) { + case 'H': + case 'h': + case '?': + for (i = 0; i < item_no; i++) + items[i]->selected = 0; + items[scroll + choice]->selected = 1; + delwin (dialog); + free (status); + return 1; + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (dialog); + break; + case 'S': + case 's': + case ' ': + case '\n': + if (!button) { + if (flag == FLAG_CHECK) { + status[scroll + choice] = !status[scroll + choice]; + wmove (list, choice, check_x); + wattrset (list, check_selected_attr); + wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' '); + } else { + if (!status[scroll + choice]) { + for (i = 0; i < item_no; i++) + status[i] = 0; + status[scroll + choice] = 1; + for (i = 0; i < max_choice; i++) + print_item (list, items[scroll + i]->name, + status[scroll + i], i, i == choice); + } + } + wnoutrefresh (list); + wrefresh (dialog); + + for (i = 0; i < item_no; i++) { + items[i]->selected = status[i]; + } + } else { + for (i = 0; i < item_no; i++) + items[i]->selected = 0; + items[scroll + choice]->selected = 1; + } + delwin (dialog); + free (status); + return button; + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + + /* Now, update everything... */ + doupdate (); + } + + + delwin (dialog); + free (status); + return -1; /* ESC pressed */ +} diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/colors.h b/circuitpython/lib/axtls/config/scripts/config/lxdialog/colors.h new file mode 100644 index 0000000..d34dd37 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/colors.h @@ -0,0 +1,161 @@ +/* + * colors.h -- color attribute definitions + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +/* + * Default color definitions + * + * *_FG = foreground + * *_BG = background + * *_HL = highlight? + */ +#define SCREEN_FG COLOR_CYAN +#define SCREEN_BG COLOR_BLUE +#define SCREEN_HL TRUE + +#define SHADOW_FG COLOR_BLACK +#define SHADOW_BG COLOR_BLACK +#define SHADOW_HL TRUE + +#define DIALOG_FG COLOR_BLACK +#define DIALOG_BG COLOR_WHITE +#define DIALOG_HL FALSE + +#define TITLE_FG COLOR_YELLOW +#define TITLE_BG COLOR_WHITE +#define TITLE_HL TRUE + +#define BORDER_FG COLOR_WHITE +#define BORDER_BG COLOR_WHITE +#define BORDER_HL TRUE + +#define BUTTON_ACTIVE_FG COLOR_WHITE +#define BUTTON_ACTIVE_BG COLOR_BLUE +#define BUTTON_ACTIVE_HL TRUE + +#define BUTTON_INACTIVE_FG COLOR_BLACK +#define BUTTON_INACTIVE_BG COLOR_WHITE +#define BUTTON_INACTIVE_HL FALSE + +#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE +#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE +#define BUTTON_KEY_ACTIVE_HL TRUE + +#define BUTTON_KEY_INACTIVE_FG COLOR_RED +#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE +#define BUTTON_KEY_INACTIVE_HL FALSE + +#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW +#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE +#define BUTTON_LABEL_ACTIVE_HL TRUE + +#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK +#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE +#define BUTTON_LABEL_INACTIVE_HL TRUE + +#define INPUTBOX_FG COLOR_BLACK +#define INPUTBOX_BG COLOR_WHITE +#define INPUTBOX_HL FALSE + +#define INPUTBOX_BORDER_FG COLOR_BLACK +#define INPUTBOX_BORDER_BG COLOR_WHITE +#define INPUTBOX_BORDER_HL FALSE + +#define SEARCHBOX_FG COLOR_BLACK +#define SEARCHBOX_BG COLOR_WHITE +#define SEARCHBOX_HL FALSE + +#define SEARCHBOX_TITLE_FG COLOR_YELLOW +#define SEARCHBOX_TITLE_BG COLOR_WHITE +#define SEARCHBOX_TITLE_HL TRUE + +#define SEARCHBOX_BORDER_FG COLOR_WHITE +#define SEARCHBOX_BORDER_BG COLOR_WHITE +#define SEARCHBOX_BORDER_HL TRUE + +#define POSITION_INDICATOR_FG COLOR_YELLOW +#define POSITION_INDICATOR_BG COLOR_WHITE +#define POSITION_INDICATOR_HL TRUE + +#define MENUBOX_FG COLOR_BLACK +#define MENUBOX_BG COLOR_WHITE +#define MENUBOX_HL FALSE + +#define MENUBOX_BORDER_FG COLOR_WHITE +#define MENUBOX_BORDER_BG COLOR_WHITE +#define MENUBOX_BORDER_HL TRUE + +#define ITEM_FG COLOR_BLACK +#define ITEM_BG COLOR_WHITE +#define ITEM_HL FALSE + +#define ITEM_SELECTED_FG COLOR_WHITE +#define ITEM_SELECTED_BG COLOR_BLUE +#define ITEM_SELECTED_HL TRUE + +#define TAG_FG COLOR_YELLOW +#define TAG_BG COLOR_WHITE +#define TAG_HL TRUE + +#define TAG_SELECTED_FG COLOR_YELLOW +#define TAG_SELECTED_BG COLOR_BLUE +#define TAG_SELECTED_HL TRUE + +#define TAG_KEY_FG COLOR_YELLOW +#define TAG_KEY_BG COLOR_WHITE +#define TAG_KEY_HL TRUE + +#define TAG_KEY_SELECTED_FG COLOR_YELLOW +#define TAG_KEY_SELECTED_BG COLOR_BLUE +#define TAG_KEY_SELECTED_HL TRUE + +#define CHECK_FG COLOR_BLACK +#define CHECK_BG COLOR_WHITE +#define CHECK_HL FALSE + +#define CHECK_SELECTED_FG COLOR_WHITE +#define CHECK_SELECTED_BG COLOR_BLUE +#define CHECK_SELECTED_HL TRUE + +#define UARROW_FG COLOR_GREEN +#define UARROW_BG COLOR_WHITE +#define UARROW_HL TRUE + +#define DARROW_FG COLOR_GREEN +#define DARROW_BG COLOR_WHITE +#define DARROW_HL TRUE + +/* End of default color definitions */ + +#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y))) +#define COLOR_NAME_LEN 10 +#define COLOR_COUNT 8 + +/* + * Global variables + */ + +typedef struct { + char name[COLOR_NAME_LEN]; + int value; +} color_names_st; + +extern color_names_st color_names[]; +extern int color_table[][3]; diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/dialog.h b/circuitpython/lib/axtls/config/scripts/config/lxdialog/dialog.h new file mode 100644 index 0000000..7bab3ad --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/dialog.h @@ -0,0 +1,199 @@ + +/* + * dialog.h -- common declarations for all dialog modules + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#ifdef CURSES_LOC +#ifdef __sun__ +#define CURS_MACROS +#endif +#include CURSES_LOC + +/* + * Colors in ncurses 1.9.9e do not work properly since foreground and + * background colors are OR'd rather than separately masked. This version + * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible + * with standard curses. The simplest fix (to make this work with standard + * curses) uses the wbkgdset() function, not used in the original hack. + * Turn it off if we're building with 1.9.9e, since it just confuses things. + */ +#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) +#define OLD_NCURSES 1 +#undef wbkgdset +#define wbkgdset(w,p) /*nothing*/ +#else +#define OLD_NCURSES 0 +#endif + +#define TR(params) _tracef params + +#define ESC 27 +#define TAB 9 +#define MAX_LEN 2048 +#define BUF_SIZE (10*1024) +#define MIN(x,y) (x < y ? x : y) +#define MAX(x,y) (x > y ? x : y) + + +#ifndef ACS_ULCORNER +#define ACS_ULCORNER '+' +#endif +#ifndef ACS_LLCORNER +#define ACS_LLCORNER '+' +#endif +#ifndef ACS_URCORNER +#define ACS_URCORNER '+' +#endif +#ifndef ACS_LRCORNER +#define ACS_LRCORNER '+' +#endif +#ifndef ACS_HLINE +#define ACS_HLINE '-' +#endif +#ifndef ACS_VLINE +#define ACS_VLINE '|' +#endif +#ifndef ACS_LTEE +#define ACS_LTEE '+' +#endif +#ifndef ACS_RTEE +#define ACS_RTEE '+' +#endif +#ifndef ACS_UARROW +#define ACS_UARROW '^' +#endif +#ifndef ACS_DARROW +#define ACS_DARROW 'v' +#endif + +/* + * Attribute names + */ +#define screen_attr attributes[0] +#define shadow_attr attributes[1] +#define dialog_attr attributes[2] +#define title_attr attributes[3] +#define border_attr attributes[4] +#define button_active_attr attributes[5] +#define button_inactive_attr attributes[6] +#define button_key_active_attr attributes[7] +#define button_key_inactive_attr attributes[8] +#define button_label_active_attr attributes[9] +#define button_label_inactive_attr attributes[10] +#define inputbox_attr attributes[11] +#define inputbox_border_attr attributes[12] +#define searchbox_attr attributes[13] +#define searchbox_title_attr attributes[14] +#define searchbox_border_attr attributes[15] +#define position_indicator_attr attributes[16] +#define menubox_attr attributes[17] +#define menubox_border_attr attributes[18] +#define item_attr attributes[19] +#define item_selected_attr attributes[20] +#define tag_attr attributes[21] +#define tag_selected_attr attributes[22] +#define tag_key_attr attributes[23] +#define tag_key_selected_attr attributes[24] +#define check_attr attributes[25] +#define check_selected_attr attributes[26] +#define uarrow_attr attributes[27] +#define darrow_attr attributes[28] + +/* number of attributes */ +#define ATTRIBUTE_COUNT 29 + +/* + * Global variables + */ +extern bool use_colors; + +extern chtype attributes[]; +#endif + +extern const char *backtitle; + +struct dialog_list_item { + char *name; + int namelen; + char *tag; + int selected; /* Set to 1 by dialog_*() function. */ +}; + +/* + * Function prototypes + */ + +void init_dialog (void); +void end_dialog (void); +void dialog_clear (void); +#ifdef CURSES_LOC +void attr_clear (WINDOW * win, int height, int width, chtype attr); +void color_setup (void); +void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x); +void print_button (WINDOW * win, const char *label, int y, int x, int selected); +void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box, + chtype border); +void draw_shadow (WINDOW * win, int y, int x, int height, int width); +#endif + +int first_alpha (const char *string, const char *exempt); +int dialog_yesno (const char *title, const char *prompt, int height, int width); +int dialog_msgbox (const char *title, const char *prompt, int height, + int width, int pause); +int dialog_textbox (const char *title, const char *file, int height, int width); +int dialog_menu (const char *title, const char *prompt, int height, int width, + int menu_height, const char *choice, int item_no, + struct dialog_list_item ** items); +int dialog_checklist (const char *title, const char *prompt, int height, + int width, int list_height, int item_no, + struct dialog_list_item ** items, int flag); +extern unsigned char dialog_input_result[]; +int dialog_inputbox (const char *title, const char *prompt, int height, + int width, const char *init); + +struct dialog_list_item *first_sel_item(int item_no, + struct dialog_list_item ** items); + +/* + * This is the base for fictitious keys, which activate + * the buttons. + * + * Mouse-generated keys are the following: + * -- the first 32 are used as numbers, in addition to '0'-'9' + * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') + * -- uppercase chars are used to invoke the button (M_EVENT + 'O') + */ +#ifdef CURSES_LOC +#define M_EVENT (KEY_MAX+1) +#endif + + +/* + * The `flag' parameter in checklist is used to select between + * radiolist and checklist + */ +#define FLAG_CHECK 1 +#define FLAG_RADIO 0 diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/inputbox.c b/circuitpython/lib/axtls/config/scripts/config/lxdialog/inputbox.c new file mode 100644 index 0000000..fa7bebc --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/inputbox.c @@ -0,0 +1,240 @@ +/* + * inputbox.c -- implements the input box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +unsigned char dialog_input_result[MAX_LEN + 1]; + +/* + * Print the termination buttons + */ +static void +print_buttons(WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button (dialog, " Ok ", y, x, selected==0); + print_button (dialog, " Help ", y, x + 14, selected==1); + + wmove(dialog, y, x+1+14*selected); + wrefresh(dialog); +} + +/* + * Display a dialog box for inputing a string + */ +int +dialog_inputbox (const char *title, const char *prompt, int height, int width, + const char *init) +{ + int i, x, y, box_y, box_x, box_width; + int input_x = 0, scroll = 0, key = 0, button = -1; + unsigned char *instr = dialog_input_result; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + /* Draw the input field box */ + box_width = width - 6; + getyx (dialog, y, x); + box_y = y + 2; + box_x = (width - box_width) / 2; + draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2, + border_attr, dialog_attr); + + print_buttons(dialog, height, width, 0); + + /* Set up the initial value */ + wmove (dialog, box_y, box_x); + wattrset (dialog, inputbox_attr); + + if (!init) + instr[0] = '\0'; + else + strcpy (instr, init); + + input_x = strlen (instr); + + if (input_x >= box_width) { + scroll = input_x - box_width + 1; + input_x = box_width - 1; + for (i = 0; i < box_width - 1; i++) + waddch (dialog, instr[scroll + i]); + } else + waddstr (dialog, instr); + + wmove (dialog, box_y, box_x + input_x); + + wrefresh (dialog); + + while (key != ESC) { + key = wgetch (dialog); + + if (button == -1) { /* Input box selected */ + switch (key) { + case TAB: + case KEY_UP: + case KEY_DOWN: + break; + case KEY_LEFT: + continue; + case KEY_RIGHT: + continue; + case KEY_BACKSPACE: + case 127: + if (input_x || scroll) { + wattrset (dialog, inputbox_attr); + if (!input_x) { + scroll = scroll < box_width - 1 ? + 0 : scroll - (box_width - 1); + wmove (dialog, box_y, box_x); + for (i = 0; i < box_width; i++) + waddch (dialog, instr[scroll + input_x + i] ? + instr[scroll + input_x + i] : ' '); + input_x = strlen (instr) - scroll; + } else + input_x--; + instr[scroll + input_x] = '\0'; + mvwaddch (dialog, box_y, input_x + box_x, ' '); + wmove (dialog, box_y, input_x + box_x); + wrefresh (dialog); + } + continue; + default: + if (key < 0x100 && isprint (key)) { + if (scroll + input_x < MAX_LEN) { + wattrset (dialog, inputbox_attr); + instr[scroll + input_x] = key; + instr[scroll + input_x + 1] = '\0'; + if (input_x == box_width - 1) { + scroll++; + wmove (dialog, box_y, box_x); + for (i = 0; i < box_width - 1; i++) + waddch (dialog, instr[scroll + i]); + } else { + wmove (dialog, box_y, input_x++ + box_x); + waddch (dialog, key); + } + wrefresh (dialog); + } else + flash (); /* Alarm user about overflow */ + continue; + } + } + } + switch (key) { + case 'O': + case 'o': + delwin (dialog); + return 0; + case 'H': + case 'h': + delwin (dialog); + return 1; + case KEY_UP: + case KEY_LEFT: + switch (button) { + case -1: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 0: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove (dialog, box_y, box_x + input_x); + wrefresh (dialog); + break; + case 1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + } + break; + case TAB: + case KEY_DOWN: + case KEY_RIGHT: + switch (button) { + case -1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + case 0: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 1: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove (dialog, box_y, box_x + input_x); + wrefresh (dialog); + break; + } + break; + case ' ': + case '\n': + delwin (dialog); + return (button == -1 ? 0 : button); + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/menubox.c b/circuitpython/lib/axtls/config/scripts/config/lxdialog/menubox.c new file mode 100644 index 0000000..873dc58 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/menubox.c @@ -0,0 +1,438 @@ +/* + * menubox.c -- implements the menu box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Changes by Clifford Wolf (god@clifford.at) + * + * [ 1998-06-13 ] + * + * *) A bugfix for the Page-Down problem + * + * *) Formerly when I used Page Down and Page Up, the cursor would be set + * to the first position in the menu box. Now lxdialog is a bit + * smarter and works more like other menu systems (just have a look at + * it). + * + * *) Formerly if I selected something my scrolling would be broken because + * lxdialog is re-invoked by the Menuconfig shell script, can't + * remember the last scrolling position, and just sets it so that the + * cursor is at the bottom of the box. Now it writes the temporary file + * lxdialog.scrltmp which contains this information. The file is + * deleted by lxdialog if the user leaves a submenu or enters a new + * one, but it would be nice if Menuconfig could make another "rm -f" + * just to be sure. Just try it out - you will recognise a difference! + * + * [ 1998-06-14 ] + * + * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files + * and menus change their size on the fly. + * + * *) If for some reason the last scrolling position is not saved by + * lxdialog, it sets the scrolling so that the selected item is in the + * middle of the menu box, not at the bottom. + * + * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net) + * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus. + * This fixes a bug in Menuconfig where using ' ' to descend into menus + * would leave mis-synchronized lxdialog.scrltmp files lying around, + * fscanf would read in 'scroll', and eventually that value would get used. + */ + +#include "dialog.h" + +static int menu_width, item_x; + +/* + * Print menu item + */ +static void +print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey) +{ + int j; + char menu_item[menu_width+1]; + + strncpy(menu_item, item, menu_width); + menu_item[menu_width] = 0; + j = first_alpha(menu_item, "YyNnMmHh"); + + /* Clear 'residue' of last item */ + wattrset (win, menubox_attr); + wmove (win, choice, 0); +#if OLD_NCURSES + { + int i; + for (i = 0; i < menu_width; i++) + waddch (win, ' '); + } +#else + wclrtoeol(win); +#endif + wattrset (win, selected ? item_selected_attr : item_attr); + mvwaddstr (win, choice, item_x, menu_item); + if (hotkey) { + wattrset (win, selected ? tag_key_selected_attr : tag_key_attr); + mvwaddch(win, choice, item_x+j, menu_item[j]); + } + if (selected) { + wmove (win, choice, item_x+1); + wrefresh (win); + } +} + +/* + * Print the scroll indicators. + */ +static void +print_arrows (WINDOW * win, int item_no, int scroll, + int y, int x, int height) +{ + int cur_y, cur_x; + + getyx(win, cur_y, cur_x); + + wmove(win, y, x); + + if (scroll > 0) { + wattrset (win, uarrow_attr); + waddch (win, ACS_UARROW); + waddstr (win, "(-)"); + } + else { + wattrset (win, menubox_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + + if ((height < item_no) && (scroll + height < item_no)) { + wattrset (win, darrow_attr); + waddch (win, ACS_DARROW); + waddstr (win, "(+)"); + } + else { + wattrset (win, menubox_border_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + wmove(win, cur_y, cur_x); +} + +/* + * Display the termination buttons. + */ +static void +print_buttons (WINDOW *win, int height, int width, int selected) +{ + int x = width / 2 - 16; + int y = height - 2; + + print_button (win, "Select", y, x, selected == 0); + print_button (win, " Exit ", y, x + 12, selected == 1); + print_button (win, " Help ", y, x + 24, selected == 2); + + wmove(win, y, x+1+12*selected); + wrefresh (win); +} + +/* + * Display a menu for choosing among a number of options + */ +int +dialog_menu (const char *title, const char *prompt, int height, int width, + int menu_height, const char *current, int item_no, + struct dialog_list_item ** items) +{ + int i, j, x, y, box_x, box_y; + int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice; + WINDOW *dialog, *menu; + FILE *f; + + max_choice = MIN (menu_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + wbkgdset (dialog, dialog_attr & A_COLOR); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + menu_width = width - 6; + box_y = height - menu_height - 5; + box_x = (width - menu_width) / 2 - 1; + + /* create new window for the menu */ + menu = subwin (dialog, menu_height, menu_width, + y + box_y + 1, x + box_x + 1); + keypad (menu, TRUE); + + /* draw a box around the menu items */ + draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2, + menubox_border_attr, menubox_attr); + + /* + * Find length of longest item in order to center menu. + * Set 'choice' to default item. + */ + item_x = 0; + for (i = 0; i < item_no; i++) { + item_x = MAX (item_x, MIN(menu_width, strlen (items[i]->name) + 2)); + if (strcmp(current, items[i]->tag) == 0) choice = i; + } + + item_x = (menu_width - item_x) / 2; + + /* get the scroll info from the temp file */ + if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) { + if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) && + (scroll+max_choice > choice) && (scroll >= 0) && + (scroll+max_choice <= item_no) ) { + first_item = scroll; + choice = choice - scroll; + fclose(f); + } else { + scroll=0; + remove("lxdialog.scrltmp"); + fclose(f); + f=NULL; + } + } + if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) { + if (choice >= item_no-max_choice/2) + scroll = first_item = item_no-max_choice; + else + scroll = first_item = choice - max_choice/2; + choice = choice - scroll; + } + + /* Print the menu */ + for (i=0; i < max_choice; i++) { + print_item (menu, items[first_item + i]->name, i, i == choice, + (items[first_item + i]->tag[0] != ':')); + } + + wnoutrefresh (menu); + + print_arrows(dialog, item_no, scroll, + box_y, box_x+item_x+1, menu_height); + + print_buttons (dialog, height, width, 0); + wmove (menu, choice, item_x+1); + wrefresh (menu); + + while (key != ESC) { + key = wgetch(menu); + + if (key < 256 && isalpha(key)) key = tolower(key); + + if (strchr("ynmh", key)) + i = max_choice; + else { + for (i = choice+1; i < max_choice; i++) { + j = first_alpha(items[scroll + i]->name, "YyNnMmHh"); + if (key == tolower(items[scroll + i]->name[j])) + break; + } + if (i == max_choice) + for (i = 0; i < max_choice; i++) { + j = first_alpha(items[scroll + i]->name, "YyNnMmHh"); + if (key == tolower(items[scroll + i]->name[j])) + break; + } + } + + if (i < max_choice || + key == KEY_UP || key == KEY_DOWN || + key == '-' || key == '+' || + key == KEY_PPAGE || key == KEY_NPAGE) { + + print_item (menu, items[scroll + choice]->name, choice, FALSE, + (items[scroll + choice]->tag[0] != ':')); + + if (key == KEY_UP || key == '-') { + if (choice < 2 && scroll) { + /* Scroll menu down */ + scrollok (menu, TRUE); + wscrl (menu, -1); + scrollok (menu, FALSE); + + scroll--; + + print_item (menu, items[scroll]->name, 0, FALSE, + (items[scroll]->tag[0] != ':')); + } else + choice = MAX(choice - 1, 0); + + } else if (key == KEY_DOWN || key == '+') { + + print_item (menu, items[scroll + choice]->name, choice, FALSE, + (items[scroll + choice]->tag[0] != ':')); + + if ((choice > max_choice-3) && + (scroll + max_choice < item_no) + ) { + /* Scroll menu up */ + scrollok (menu, TRUE); + scroll (menu); + scrollok (menu, FALSE); + + scroll++; + + print_item (menu, items[scroll + max_choice - 1]->name, + max_choice-1, FALSE, + (items[scroll + max_choice - 1]->tag[0] != ':')); + } else + choice = MIN(choice+1, max_choice-1); + + } else if (key == KEY_PPAGE) { + scrollok (menu, TRUE); + for (i=0; (i < max_choice); i++) { + if (scroll > 0) { + wscrl (menu, -1); + scroll--; + print_item (menu, items[scroll]->name, 0, FALSE, + (items[scroll]->tag[0] != ':')); + } else { + if (choice > 0) + choice--; + } + } + scrollok (menu, FALSE); + + } else if (key == KEY_NPAGE) { + for (i=0; (i < max_choice); i++) { + if (scroll+max_choice < item_no) { + scrollok (menu, TRUE); + scroll(menu); + scrollok (menu, FALSE); + scroll++; + print_item (menu, items[scroll + max_choice - 1]->name, + max_choice-1, FALSE, + (items[scroll + max_choice - 1]->tag[0] != ':')); + } else { + if (choice+1 < max_choice) + choice++; + } + } + + } else + choice = i; + + print_item (menu, items[scroll + choice]->name, choice, TRUE, + (items[scroll + choice]->tag[0] != ':')); + + print_arrows(dialog, item_no, scroll, + box_y, box_x+item_x+1, menu_height); + + wnoutrefresh (dialog); + wrefresh (menu); + + continue; /* wait for another key press */ + } + + switch (key) { + case KEY_LEFT: + case TAB: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 2 : (button > 2 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (menu); + break; + case ' ': + case 's': + case 'y': + case 'n': + case 'm': + case '/': + /* save scroll info */ + if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) { + fprintf(f,"%d\n",scroll); + fclose(f); + } + delwin (dialog); + items[scroll + choice]->selected = 1; + switch (key) { + case 's': return 3; + case 'y': return 3; + case 'n': return 4; + case 'm': return 5; + case ' ': return 6; + case '/': return 7; + } + return 0; + case 'h': + case '?': + button = 2; + case '\n': + delwin (dialog); + items[scroll + choice]->selected = 1; + + remove("lxdialog.scrltmp"); + return button; + case 'e': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin (dialog); + remove("lxdialog.scrltmp"); + return -1; /* ESC pressed */ +} diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/msgbox.c b/circuitpython/lib/axtls/config/scripts/config/lxdialog/msgbox.c new file mode 100644 index 0000000..93692e1 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/msgbox.c @@ -0,0 +1,85 @@ +/* + * msgbox.c -- implements the message box and info box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +/* + * Display a message box. Program will pause and display an "OK" button + * if the parameter 'pause' is non-zero. + */ +int +dialog_msgbox (const char *title, const char *prompt, int height, int width, + int pause) +{ + int i, x, y, key = 0; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 2); + + if (pause) { + wattrset (dialog, border_attr); + mvwaddch (dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + print_button (dialog, " Ok ", + height - 2, width / 2 - 4, TRUE); + + wrefresh (dialog); + while (key != ESC && key != '\n' && key != ' ' && + key != 'O' && key != 'o' && key != 'X' && key != 'x') + key = wgetch (dialog); + } else { + key = '\n'; + wrefresh (dialog); + } + + delwin (dialog); + return key == ESC ? -1 : 0; +} diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/textbox.c b/circuitpython/lib/axtls/config/scripts/config/lxdialog/textbox.c new file mode 100644 index 0000000..a5a460b --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/textbox.c @@ -0,0 +1,556 @@ +/* + * textbox.c -- implements the text box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static void back_lines (int n); +static void print_page (WINDOW * win, int height, int width); +static void print_line (WINDOW * win, int row, int width); +static char *get_line (void); +static void print_position (WINDOW * win, int height, int width); + +static int hscroll, fd, file_size, bytes_read; +static int begin_reached = 1, end_reached, page_length; +static char *buf, *page; + +/* + * Display text from a file in a dialog box. + */ +int +dialog_textbox (const char *title, const char *file, int height, int width) +{ + int i, x, y, cur_x, cur_y, fpos, key = 0; + int passed_end; + char search_term[MAX_LEN + 1]; + WINDOW *dialog, *text; + + search_term[0] = '\0'; /* no search term entered yet */ + + /* Open input file for reading */ + if ((fd = open (file, O_RDONLY)) == -1) { + endwin (); + fprintf (stderr, + "\nCan't open input file in dialog_textbox().\n"); + exit (-1); + } + /* Get file size. Actually, 'file_size' is the real file size - 1, + since it's only the last byte offset from the beginning */ + if ((file_size = lseek (fd, 0, SEEK_END)) == -1) { + endwin (); + fprintf (stderr, "\nError getting file size in dialog_textbox().\n"); + exit (-1); + } + /* Restore file pointer to beginning of file after getting file size */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + /* Allocate space for read buffer */ + if ((buf = malloc (BUF_SIZE + 1)) == NULL) { + endwin (); + fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; /* mark end of valid data */ + page = buf; /* page is pointer to start of page to be displayed */ + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + /* Create window for text region, used for scrolling text */ + text = subwin (dialog, height - 4, width - 2, y + 1, x + 1); + wattrset (text, dialog_attr); + wbkgdset (text, dialog_attr & A_COLOR); + + keypad (text, TRUE); + + /* register the new window, along with its borders */ + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + wbkgdset (dialog, dialog_attr & A_COLOR); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE); + wnoutrefresh (dialog); + getyx (dialog, cur_y, cur_x); /* Save cursor position */ + + /* Print first page of text */ + attr_clear (text, height - 4, width - 2, dialog_attr); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + + while ((key != ESC) && (key != '\n')) { + key = wgetch (dialog); + switch (key) { + case 'E': /* Exit */ + case 'e': + case 'X': + case 'x': + delwin (dialog); + free (buf); + close (fd); + return 0; + case 'g': /* First page */ + case KEY_HOME: + if (!begin_reached) { + begin_reached = 1; + /* First page not in buffer? */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if (fpos > bytes_read) { /* Yes, we have to read it in */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, + "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } + page = buf; + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case 'G': /* Last page */ + case KEY_END: + + end_reached = 1; + /* Last page not in buffer? */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if (fpos < file_size) { /* Yes, we have to read it in */ + if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, + "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } + page = buf + bytes_read; + back_lines (height - 4); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + break; + case 'K': /* Previous line */ + case 'k': + case KEY_UP: + if (!begin_reached) { + back_lines (page_length + 1); + + /* We don't call print_page() here but use scrolling to ensure + faster screen update. However, 'end_reached' and + 'page_length' should still be updated, and 'page' should + point to start of next page. This is done by calling + get_line() in the following 'for' loop. */ + scrollok (text, TRUE); + wscrl (text, -1); /* Scroll text region down one line */ + scrollok (text, FALSE); + page_length = 0; + passed_end = 0; + for (i = 0; i < height - 4; i++) { + if (!i) { + /* print first line of page */ + print_line (text, 0, width - 2); + wnoutrefresh (text); + } else + /* Called to update 'end_reached' and 'page' */ + get_line (); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case 'B': /* Previous page */ + case 'b': + case KEY_PPAGE: + if (begin_reached) + break; + back_lines (page_length + height - 4); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case 'J': /* Next line */ + case 'j': + case KEY_DOWN: + if (!end_reached) { + begin_reached = 0; + scrollok (text, TRUE); + scroll (text); /* Scroll text region up one line */ + scrollok (text, FALSE); + print_line (text, height - 5, width - 2); + wnoutrefresh (text); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case KEY_NPAGE: /* Next page */ + case ' ': + if (end_reached) + break; + + begin_reached = 0; + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case '0': /* Beginning of line */ + case 'H': /* Scroll left */ + case 'h': + case KEY_LEFT: + if (hscroll <= 0) + break; + + if (key == '0') + hscroll = 0; + else + hscroll--; + /* Reprint current page to scroll horizontally */ + back_lines (page_length); + print_page (text, height - 4, width - 2); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case 'L': /* Scroll right */ + case 'l': + case KEY_RIGHT: + if (hscroll >= MAX_LEN) + break; + hscroll++; + /* Reprint current page to scroll horizontally */ + back_lines (page_length); + print_page (text, height - 4, width - 2); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case ESC: + break; + } + } + + delwin (dialog); + free (buf); + close (fd); + return 1; /* ESC pressed */ +} + +/* + * Go back 'n' lines in text file. Called by dialog_textbox(). + * 'page' will be updated to point to the desired line in 'buf'. + */ +static void +back_lines (int n) +{ + int i, fpos; + + begin_reached = 0; + /* We have to distinguish between end_reached and !end_reached + since at end of file, the line is not ended by a '\n'. + The code inside 'if' basically does a '--page' to move one + character backward so as to skip '\n' of the previous line */ + if (!end_reached) { + /* Either beginning of buffer or beginning of file reached? */ + if (page == buf) { + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit (-1); + } + if (fpos > bytes_read) { /* Not beginning of file yet */ + /* We've reached beginning of buffer, but not beginning of + file yet, so read previous part of file into buffer. + Note that we only move backward for BUF_SIZE/2 bytes, + but not BUF_SIZE bytes to avoid re-reading again in + print_page() later */ + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit (-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) + == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit (-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in back_lines().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + if (*(--page) != '\n') { /* '--page' here */ + /* Something's wrong... */ + endwin (); + fprintf (stderr, "\nInternal error in back_lines().\n"); + exit (-1); + } + } + /* Go back 'n' lines */ + for (i = 0; i < n; i++) + do { + if (page == buf) { + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in back_lines().\n"); + exit (-1); + } + if (fpos > bytes_read) { + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit (-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), + SEEK_CUR) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer" + " in back_lines().\n"); + exit (-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in " + "back_lines().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + } while (*(--page) != '\n'); + page++; +} + +/* + * Print a new page of text. Called by dialog_textbox(). + */ +static void +print_page (WINDOW * win, int height, int width) +{ + int i, passed_end = 0; + + page_length = 0; + for (i = 0; i < height; i++) { + print_line (win, i, width); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + wnoutrefresh (win); +} + +/* + * Print a new line of text. Called by dialog_textbox() and print_page(). + */ +static void +print_line (WINDOW * win, int row, int width) +{ + int y, x; + char *line; + + line = get_line (); + line += MIN (strlen (line), hscroll); /* Scroll horizontally */ + wmove (win, row, 0); /* move cursor to correct line */ + waddch (win, ' '); + waddnstr (win, line, MIN (strlen (line), width - 2)); + + getyx (win, y, x); + /* Clear 'residue' of previous line */ +#if OLD_NCURSES + { + int i; + for (i = 0; i < width - x; i++) + waddch (win, ' '); + } +#else + wclrtoeol(win); +#endif +} + +/* + * Return current line of text. Called by dialog_textbox() and print_line(). + * 'page' should point to start of current line before calling, and will be + * updated to point to start of next line. + */ +static char * +get_line (void) +{ + int i = 0, fpos; + static char line[MAX_LEN + 1]; + + end_reached = 0; + while (*page != '\n') { + if (*page == '\0') { + /* Either end of file or end of buffer reached */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "get_line().\n"); + exit (-1); + } + if (fpos < file_size) { /* Not end of file yet */ + /* We've reached end of buffer, but not end of file yet, + so read next part of file into buffer */ + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in get_line().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + page = buf; + } else { + if (!end_reached) + end_reached = 1; + break; + } + } else if (i < MAX_LEN) + line[i++] = *(page++); + else { + /* Truncate lines longer than MAX_LEN characters */ + if (i == MAX_LEN) + line[i++] = '\0'; + page++; + } + } + if (i <= MAX_LEN) + line[i] = '\0'; + if (!end_reached) + page++; /* move pass '\n' */ + + return line; +} + +/* + * Print current position + */ +static void +print_position (WINDOW * win, int height, int width) +{ + int fpos, percent; + + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in print_position().\n"); + exit (-1); + } + wattrset (win, position_indicator_attr); + wbkgdset (win, position_indicator_attr & A_COLOR); + percent = !file_size ? + 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; + wmove (win, height - 3, width - 9); + wprintw (win, "(%3d%%)", percent); +} diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/util.c b/circuitpython/lib/axtls/config/scripts/config/lxdialog/util.c new file mode 100644 index 0000000..6f83951 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/util.c @@ -0,0 +1,375 @@ +/* + * util.c + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + + +/* use colors by default? */ +bool use_colors = 1; + +const char *backtitle = NULL; + +const char *dialog_result; + +/* + * Attribute values, default is for mono display + */ +chtype attributes[] = +{ + A_NORMAL, /* screen_attr */ + A_NORMAL, /* shadow_attr */ + A_NORMAL, /* dialog_attr */ + A_BOLD, /* title_attr */ + A_NORMAL, /* border_attr */ + A_REVERSE, /* button_active_attr */ + A_DIM, /* button_inactive_attr */ + A_REVERSE, /* button_key_active_attr */ + A_BOLD, /* button_key_inactive_attr */ + A_REVERSE, /* button_label_active_attr */ + A_NORMAL, /* button_label_inactive_attr */ + A_NORMAL, /* inputbox_attr */ + A_NORMAL, /* inputbox_border_attr */ + A_NORMAL, /* searchbox_attr */ + A_BOLD, /* searchbox_title_attr */ + A_NORMAL, /* searchbox_border_attr */ + A_BOLD, /* position_indicator_attr */ + A_NORMAL, /* menubox_attr */ + A_NORMAL, /* menubox_border_attr */ + A_NORMAL, /* item_attr */ + A_REVERSE, /* item_selected_attr */ + A_BOLD, /* tag_attr */ + A_REVERSE, /* tag_selected_attr */ + A_BOLD, /* tag_key_attr */ + A_REVERSE, /* tag_key_selected_attr */ + A_BOLD, /* check_attr */ + A_REVERSE, /* check_selected_attr */ + A_BOLD, /* uarrow_attr */ + A_BOLD /* darrow_attr */ +}; + + +#include "colors.h" + +/* + * Table of color values + */ +int color_table[][3] = +{ + {SCREEN_FG, SCREEN_BG, SCREEN_HL}, + {SHADOW_FG, SHADOW_BG, SHADOW_HL}, + {DIALOG_FG, DIALOG_BG, DIALOG_HL}, + {TITLE_FG, TITLE_BG, TITLE_HL}, + {BORDER_FG, BORDER_BG, BORDER_HL}, + {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, + {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, + {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, + {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL}, + {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL}, + {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, + BUTTON_LABEL_INACTIVE_HL}, + {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, + {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, + {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, + {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, + {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, + {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, + {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, + {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, + {ITEM_FG, ITEM_BG, ITEM_HL}, + {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, + {TAG_FG, TAG_BG, TAG_HL}, + {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, + {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, + {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, + {CHECK_FG, CHECK_BG, CHECK_HL}, + {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, + {UARROW_FG, UARROW_BG, UARROW_HL}, + {DARROW_FG, DARROW_BG, DARROW_HL}, +}; /* color_table */ + +/* + * Set window to attribute 'attr' + */ +void +attr_clear (WINDOW * win, int height, int width, chtype attr) +{ + int i, j; + + wattrset (win, attr); + for (i = 0; i < height; i++) { + wmove (win, i, 0); + for (j = 0; j < width; j++) + waddch (win, ' '); + } + touchwin (win); +} + +void dialog_clear (void) +{ + attr_clear (stdscr, LINES, COLS, screen_attr); + /* Display background title if it exists ... - SLH */ + if (backtitle != NULL) { + int i; + + wattrset (stdscr, screen_attr); + mvwaddstr (stdscr, 0, 1, (char *)backtitle); + wmove (stdscr, 1, 1); + for (i = 1; i < COLS - 1; i++) + waddch (stdscr, ACS_HLINE); + } + wnoutrefresh (stdscr); +} + +/* + * Do some initialization for dialog + */ +void +init_dialog (void) +{ + initscr (); /* Init curses */ + keypad (stdscr, TRUE); + cbreak (); + noecho (); + + + if (use_colors) /* Set up colors */ + color_setup (); + + + dialog_clear (); +} + +/* + * Setup for color display + */ +void +color_setup (void) +{ + int i; + + if (has_colors ()) { /* Terminal supports color? */ + start_color (); + + /* Initialize color pairs */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + init_pair (i + 1, color_table[i][0], color_table[i][1]); + + /* Setup color attributes */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + attributes[i] = C_ATTR (color_table[i][2], i + 1); + } +} + +/* + * End using dialog functions. + */ +void +end_dialog (void) +{ + endwin (); +} + + +/* + * Print a string of text in a window, automatically wrap around to the + * next line if the string is too long to fit on one line. Newline + * characters '\n' are replaced by spaces. We start on a new line + * if there is no room for at least 4 nonblanks following a double-space. + */ +void +print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x) +{ + int newl, cur_x, cur_y; + int i, prompt_len, room, wlen; + char tempstr[MAX_LEN + 1], *word, *sp, *sp2; + + strcpy (tempstr, prompt); + + prompt_len = strlen(tempstr); + + /* + * Remove newlines + */ + for(i=0; i room || + (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room + && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) { + cur_y++; + cur_x = x; + } + wmove (win, cur_y, cur_x); + waddstr (win, word); + getyx (win, cur_y, cur_x); + cur_x++; + if (sp && *sp == ' ') { + cur_x++; /* double space */ + while (*++sp == ' '); + newl = 1; + } else + newl = 0; + word = sp; + } + } +} + +/* + * Print a button + */ +void +print_button (WINDOW * win, const char *label, int y, int x, int selected) +{ + int i, temp; + + wmove (win, y, x); + wattrset (win, selected ? button_active_attr : button_inactive_attr); + waddstr (win, "<"); + temp = strspn (label, " "); + label += temp; + wattrset (win, selected ? button_label_active_attr + : button_label_inactive_attr); + for (i = 0; i < temp; i++) + waddch (win, ' '); + wattrset (win, selected ? button_key_active_attr + : button_key_inactive_attr); + waddch (win, label[0]); + wattrset (win, selected ? button_label_active_attr + : button_label_inactive_attr); + waddstr (win, (char *)label + 1); + wattrset (win, selected ? button_active_attr : button_inactive_attr); + waddstr (win, ">"); + wmove (win, y, x + temp + 1); +} + +/* + * Draw a rectangular box with line drawing characters + */ +void +draw_box (WINDOW * win, int y, int x, int height, int width, + chtype box, chtype border) +{ + int i, j; + + wattrset (win, 0); + for (i = 0; i < height; i++) { + wmove (win, y + i, x); + for (j = 0; j < width; j++) + if (!i && !j) + waddch (win, border | ACS_ULCORNER); + else if (i == height - 1 && !j) + waddch (win, border | ACS_LLCORNER); + else if (!i && j == width - 1) + waddch (win, box | ACS_URCORNER); + else if (i == height - 1 && j == width - 1) + waddch (win, box | ACS_LRCORNER); + else if (!i) + waddch (win, border | ACS_HLINE); + else if (i == height - 1) + waddch (win, box | ACS_HLINE); + else if (!j) + waddch (win, border | ACS_VLINE); + else if (j == width - 1) + waddch (win, box | ACS_VLINE); + else + waddch (win, box | ' '); + } +} + +/* + * Draw shadows along the right and bottom edge to give a more 3D look + * to the boxes + */ +void +draw_shadow (WINDOW * win, int y, int x, int height, int width) +{ + int i; + + if (has_colors ()) { /* Whether terminal supports color? */ + wattrset (win, shadow_attr); + wmove (win, y + height, x + 2); + for (i = 0; i < width; i++) + waddch (win, winch (win) & A_CHARTEXT); + for (i = y + 1; i < y + height + 1; i++) { + wmove (win, i, x + width); + waddch (win, winch (win) & A_CHARTEXT); + waddch (win, winch (win) & A_CHARTEXT); + } + wnoutrefresh (win); + } +} + +/* + * Return the position of the first alphabetic character in a string. + */ +int +first_alpha(const char *string, const char *exempt) +{ + int i, in_paren=0, c; + + for (i = 0; i < strlen(string); i++) { + c = tolower(string[i]); + + if (strchr("<[(", c)) ++in_paren; + if (strchr(">])", c) && in_paren > 0) --in_paren; + + if ((! in_paren) && isalpha(c) && + strchr(exempt, c) == 0) + return i; + } + + return 0; +} + +/* + * Get the first selected item in the dialog_list_item list. + */ +struct dialog_list_item * +first_sel_item(int item_no, struct dialog_list_item ** items) +{ + int i; + + for (i = 0; i < item_no; i++) { + if (items[i]->selected) + return items[i]; + } + + return NULL; +} diff --git a/circuitpython/lib/axtls/config/scripts/config/lxdialog/yesno.c b/circuitpython/lib/axtls/config/scripts/config/lxdialog/yesno.c new file mode 100644 index 0000000..11fcc25 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/lxdialog/yesno.c @@ -0,0 +1,118 @@ +/* + * yesno.c -- implements the yes/no box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +/* + * Display termination buttons + */ +static void +print_buttons(WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 10; + int y = height - 2; + + print_button (dialog, " Yes ", y, x, selected == 0); + print_button (dialog, " No ", y, x + 13, selected == 1); + + wmove(dialog, y, x+1 + 13*selected ); + wrefresh (dialog); +} + +/* + * Display a dialog box with two buttons - Yes and No + */ +int +dialog_yesno (const char *title, const char *prompt, int height, int width) +{ + int i, x, y, key = 0, button = 0; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + print_buttons(dialog, height, width, 0); + + while (key != ESC) { + key = wgetch (dialog); + switch (key) { + case 'Y': + case 'y': + delwin (dialog); + return 0; + case 'N': + case 'n': + delwin (dialog); + return 1; + + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (dialog); + break; + case ' ': + case '\n': + delwin (dialog); + return button; + case ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/circuitpython/lib/axtls/config/scripts/config/mconf.c b/circuitpython/lib/axtls/config/scripts/config/mconf.c new file mode 100644 index 0000000..406eb29 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/mconf.c @@ -0,0 +1,977 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + * + * Introduced single menu mode (show all sub-menus in one large tree). + * 2002-11-06 Petr Baudis + * + * Directly use liblxdialog library routines. + * 2002-11-14 Petr Baudis + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lxdialog/dialog.h" + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static char menu_backtitle[128]; +static const char mconf_readme[] = +"Overview\n" +"--------\n" +"Some features may be built directly into axTLS. Some features\n" +"may be completely removed altogether. There are also certain\n" +"parameters which are not really features, but must be\n" +"entered in as decimal or hexadecimal numbers or possibly text.\n" +"\n" +"Menu items beginning with [*] or [ ] represent features\n" +"configured to be built in or removed respectively.\n" +"\n" +"To change any of these features, highlight it with the cursor\n" +"keys and press to build it in or to removed it.\n" +"You may also press the to cycle\n" +"through the available options (ie. Y->N->Y).\n" +"\n" +"Some additional keyboard hints:\n" +"\n" +"Menus\n" +"----------\n" +"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" +" you wish to change or submenu wish to select and press .\n" +" Submenus are designated by \"--->\".\n" +"\n" +" Shortcut: Press the option's highlighted letter (hotkey).\n" +" Pressing a hotkey more than once will sequence\n" +" through all visible items which use that hotkey.\n" +"\n" +" You may also use the and keys to scroll\n" +" unseen options into view.\n" +"\n" +"o To exit a menu use the cursor keys to highlight the button\n" +" and press .\n" +"\n" +" Shortcut: Press or or if there is no hotkey\n" +" using those letters. You may press a single , but\n" +" there is a delayed response which you may find annoying.\n" +"\n" +" Also, the and cursor keys will cycle between and\n" +" \n" +"\n" +"\n" +"Data Entry\n" +"-----------\n" +"o Enter the requested information and press \n" +" If you are entering hexadecimal values, it is not necessary to\n" +" add the '0x' prefix to the entry.\n" +"\n" +"o For help, use the or cursor keys to highlight the help option\n" +" and press . You can try as well.\n" +"\n" +"\n" +"Text Box (Help Window)\n" +"--------\n" +"o Use the cursor keys to scroll up/down/left/right. The VI editor\n" +" keys h,j,k,l function here as do and for those\n" +" who are familiar with less and lynx.\n" +"\n" +"o Press , , or to exit.\n" +"\n" +"\n" +"Alternate Configuration Files\n" +"-----------------------------\n" +"Menuconfig supports the use of alternate configuration files for\n" +"those who, for various reasons, find it necessary to switch\n" +"between different configurations.\n" +"\n" +"At the end of the main menu you will find two options. One is\n" +"for saving the current configuration to a file of your choosing.\n" +"The other option is for loading a previously saved alternate\n" +"configuration.\n" +"\n" +"Even if you don't use alternate configuration files, but you\n" +"find during a Menuconfig session that you have completely messed\n" +"up your settings, you may use the \"Load Alternate...\" option to\n" +"restore your previously saved settings from \".config\" without\n" +"restarting Menuconfig.\n" +"\n" +"Other information\n" +"-----------------\n" +"If you use Menuconfig in an XTERM window make sure you have your\n" +"$TERM variable set to point to a xterm definition which supports color.\n" +"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n" +"display correctly in a RXVT window because rxvt displays only one\n" +"intensity of color, bright.\n" +"\n" +"Menuconfig will display larger menus on screens or xterms which are\n" +"set to display more than the standard 25 row by 80 column geometry.\n" +"In order for this to work, the \"stty size\" command must be able to\n" +"display the screen's current row and column geometry. I STRONGLY\n" +"RECOMMEND that you make sure you do NOT have the shell variables\n" +"LINES and COLUMNS exported into your environment. Some distributions\n" +"export those variables via /etc/profile. Some ncurses programs can\n" +"become confused when those variables (LINES & COLUMNS) don't reflect\n" +"the true screen size.\n" +"\n" +"Optional personality available\n" +"------------------------------\n" +"If you prefer to have all of the options listed in a single\n" +"menu, rather than the default multimenu hierarchy, run the menuconfig\n" +"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" +"\n" +"make MENUCONFIG_MODE=single_menu menuconfig\n" +"\n" +" will then unroll the appropriate category, or enfold it if it\n" +"is already unrolled.\n" +"\n" +"Note that this mode can eventually be a little more CPU expensive\n" +"(especially with a larger number of unrolled categories) than the\n" +"default mode.\n", +menu_instructions[] = + "Arrow keys navigate the menu. " + " selects submenus --->. " + "Highlighted letters are hotkeys. " + "Pressing selectes a feature, while will exclude a feature. " + "Press to exit, for Help, for Search. " + "Legend: [*] feature is selected [ ] feature is excluded", +radiolist_instructions[] = + "Use the arrow keys to navigate this window or " + "press the hotkey of the item you wish to select " + "followed by the . " + "Press for additional information about this option.", +inputbox_instructions_int[] = + "Please enter a decimal value. " + "Fractions will not be accepted. " + "Use the key to move from the input field to the buttons below it.", +inputbox_instructions_hex[] = + "Please enter a hexadecimal value. " + "Use the key to move from the input field to the buttons below it.", +inputbox_instructions_string[] = + "Please enter a string value. " + "Use the key to move from the input field to the buttons below it.", +setmod_text[] = + "This feature depends on another which has been configured as a module.\n" + "As a result, this feature will be built as a module.", +nohelp_text[] = + "There is no help available for this option.\n", +load_config_text[] = + "Enter the name of the configuration file you wish to load. " + "Accept the name shown to restore the configuration you " + "last retrieved. Leave blank to abort.", +load_config_help[] = + "\n" + "For various reasons, one may wish to keep several different axTLS\n" + "configurations available on a single machine.\n" + "\n" + "If you have saved a previous configuration in a file other than the\n" + "axTLS's default, entering the name of the file here will allow you\n" + "to modify that configuration.\n" + "\n" + "If you are uncertain, then you have probably never used alternate\n" + "configuration files. You should therefor leave this blank to abort.\n", +save_config_text[] = + "Enter a filename to which this configuration should be saved " + "as an alternate. Leave blank to abort.", +save_config_help[] = + "\n" + "For various reasons, one may wish to keep different axTLS\n" + "configurations available on a single machine.\n" + "\n" + "Entering a file name here will allow you to later retrieve, modify\n" + "and use the current configuration as an alternate to whatever\n" + "configuration options you have selected at that time.\n" + "\n" + "If you are uncertain what all this means then you should probably\n" + "leave this blank.\n", +search_help[] = + "\n" + "Search for CONFIG_ symbols and display their relations.\n" + "Example: search for \"^FOO\"\n" + "Result:\n" + "-----------------------------------------------------------------\n" + "Symbol: FOO [=m]\n" + "Prompt: Foo bus is used to drive the bar HW\n" + "Defined at drivers/pci/Kconfig:47\n" + "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" + "Location:\n" + " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" + " -> PCI support (PCI [=y])\n" + " -> PCI access mode ( [=y])\n" + "Selects: LIBCRC32\n" + "Selected by: BAR\n" + "-----------------------------------------------------------------\n" + "o The line 'Prompt:' shows the text used in the menu structure for\n" + " this CONFIG_ symbol\n" + "o The 'Defined at' line tell at what file / line number the symbol\n" + " is defined\n" + "o The 'Depends on:' line tell what symbols needs to be defined for\n" + " this symbol to be visible in the menu (selectable)\n" + "o The 'Location:' lines tell where in the menu structure this symbol\n" + " is located\n" + " A location followed by a [=y] indicate that this is a selectable\n" + " menu item - and current value is displayed inside brackets.\n" + "o The 'Selects:' line tell what symbol will be automatically\n" + " selected if this symbol is selected (y or m)\n" + "o The 'Selected by' line tell what symbol has selected this symbol\n" + "\n" + "Only relevant lines are shown.\n" + "\n\n" + "Search examples:\n" + "Examples: USB => find all CONFIG_ symbols containing USB\n" + " ^USB => find all CONFIG_ symbols starting with USB\n" + " USB$ => find all CONFIG_ symbols ending with USB\n" + "\n"; + +static char filename[PATH_MAX+1] = ".config"; +static int indent; +static struct termios ios_org; +static int rows = 0, cols = 0; +static struct menu *current_menu; +static int child_count; +static int single_menu_mode; + +static struct dialog_list_item *items[16384]; /* FIXME: This ought to be dynamic. */ +static int item_no; + +static void conf(struct menu *menu); +static void conf_choice(struct menu *menu); +static void conf_string(struct menu *menu); +static void conf_load(void); +static void conf_save(void); +static void show_textbox(const char *title, const char *text, int r, int c); +static void show_helptext(const char *title, const char *text); +static void show_help(struct menu *menu); +static void show_file(const char *filename, const char *title, int r, int c); + +static void init_wsize(void) +{ + struct winsize ws; + char *env; + + if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) { + rows = ws.ws_row; + cols = ws.ws_col; + } + + if (!rows) { + env = getenv("LINES"); + if (env) + rows = atoi(env); + if (!rows) + rows = 24; + } + if (!cols) { + env = getenv("COLUMNS"); + if (env) + cols = atoi(env); + if (!cols) + cols = 80; + } + + if (rows < 19 || cols < 80) { + fprintf(stderr, "Your display is too small to run Menuconfig!\n"); + fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); + exit(1); + } + + rows -= 4; + cols -= 5; +} + +static void cinit(void) +{ + item_no = 0; +} + +static void cmake(void) +{ + items[item_no] = malloc(sizeof(struct dialog_list_item)); + memset(items[item_no], 0, sizeof(struct dialog_list_item)); + items[item_no]->tag = malloc(32); items[item_no]->tag[0] = 0; + items[item_no]->name = malloc(512); items[item_no]->name[0] = 0; + items[item_no]->namelen = 0; + item_no++; +} + +static int cprint_name(const char *fmt, ...) +{ + va_list ap; + int res; + + if (!item_no) + cmake(); + va_start(ap, fmt); + res = vsnprintf(items[item_no - 1]->name + items[item_no - 1]->namelen, + 512 - items[item_no - 1]->namelen, fmt, ap); + if (res > 0) + items[item_no - 1]->namelen += res; + va_end(ap); + + return res; +} + +static int cprint_tag(const char *fmt, ...) +{ + va_list ap; + int res; + + if (!item_no) + cmake(); + va_start(ap, fmt); + res = vsnprintf(items[item_no - 1]->tag, 32, fmt, ap); + va_end(ap); + + return res; +} + +static void cdone(void) +{ + int i; + + for (i = 0; i < item_no; i++) { + free(items[i]->tag); + free(items[i]->name); + free(items[i]); + } + + item_no = 0; +} + +static void get_prompt_str(struct gstr *r, struct property *prop) +{ + int i, j; + struct menu *submenu[8], *menu; + + str_printf(r, "Prompt: %s\n", prop->text); + str_printf(r, " Defined at %s:%d\n", prop->menu->file->name, + prop->menu->lineno); + if (!expr_is_yes(prop->visible.expr)) { + str_append(r, " Depends on: "); + expr_gstr_print(prop->visible.expr, r); + str_append(r, "\n"); + } + menu = prop->menu->parent; + for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) + submenu[i++] = menu; + if (i > 0) { + str_printf(r, " Location:\n"); + for (j = 4; --i >= 0; j += 2) { + menu = submenu[i]; + str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu)); + if (menu->sym) { + str_printf(r, " (%s [=%s])", menu->sym->name ? + menu->sym->name : "", + sym_get_string_value(menu->sym)); + } + str_append(r, "\n"); + } + } +} + +static void get_symbol_str(struct gstr *r, struct symbol *sym) +{ + bool hit; + struct property *prop; + + str_printf(r, "Symbol: %s [=%s]\n", sym->name, + sym_get_string_value(sym)); + for_all_prompts(sym, prop) + get_prompt_str(r, prop); + hit = false; + for_all_properties(sym, prop, P_SELECT) { + if (!hit) { + str_append(r, " Selects: "); + hit = true; + } else + str_printf(r, " && "); + expr_gstr_print(prop->expr, r); + } + if (hit) + str_append(r, "\n"); + if (sym->rev_dep.expr) { + str_append(r, " Selected by: "); + expr_gstr_print(sym->rev_dep.expr, r); + str_append(r, "\n"); + } + str_append(r, "\n\n"); +} + +static struct gstr get_relations_str(struct symbol **sym_arr) +{ + struct symbol *sym; + struct gstr res = str_new(); + int i; + + for (i = 0; sym_arr && (sym = sym_arr[i]); i++) + get_symbol_str(&res, sym); + if (!i) + str_append(&res, "No matches found.\n"); + return res; +} + +static void search_conf(void) +{ + struct symbol **sym_arr; + struct gstr res; + +again: + switch (dialog_inputbox("Search Configuration Parameter", + "Enter Keyword", 10, 75, + NULL)) { + case 0: + break; + case 1: + show_helptext("Search Configuration", search_help); + goto again; + default: + return; + } + + sym_arr = sym_re_search(dialog_input_result); + res = get_relations_str(sym_arr); + free(sym_arr); + show_textbox("Search Results", str_get(&res), 0, 0); + str_free(&res); +} + +static void build_conf(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + int type, tmp, doint = 2; + tristate val; + char ch; + + if (!menu_is_visible(menu)) + return; + + sym = menu->sym; + prop = menu->prompt; + if (!sym) { + if (prop && menu != current_menu) { + const char *prompt = menu_get_prompt(menu); + switch (prop->type) { + case P_MENU: + child_count++; + cmake(); + cprint_tag("m%p", menu); + + if (single_menu_mode) { + cprint_name("%s%*c%s", + menu->data ? "-->" : "++>", + indent + 1, ' ', prompt); + } else { + cprint_name(" %*c%s --->", indent + 1, ' ', prompt); + } + + if (single_menu_mode && menu->data) + goto conf_childs; + return; + default: + if (prompt) { + child_count++; + cmake(); + cprint_tag(":%p", menu); + cprint_name("---%*c%s", indent + 1, ' ', prompt); + } + } + } else + doint = 0; + goto conf_childs; + } + + cmake(); + type = sym_get_type(sym); + if (sym_is_choice(sym)) { + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + child_count++; + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) && child->sym == def_sym) + def_menu = child; + } + + val = sym_get_tristate_value(sym); + if (sym_is_changable(sym)) { + cprint_tag("t%p", menu); + switch (type) { + case S_BOOLEAN: + cprint_name("[%c]", val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; + } + cprint_name("<%c>", ch); + break; + } + } else { + cprint_tag("%c%p", def_menu ? 't' : ':', menu); + cprint_name(" "); + } + + cprint_name("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + if (val == yes) { + if (def_menu) { + cprint_name(" (%s)", menu_get_prompt(def_menu)); + cprint_name(" --->"); + if (def_menu->list) { + indent += 2; + build_conf(def_menu); + indent -= 2; + } + } + return; + } + } else { + if (menu == current_menu) { + cprint_tag(":%p", menu); + cprint_name("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + goto conf_childs; + } + child_count++; + val = sym_get_tristate_value(sym); + if (sym_is_choice_value(sym) && val == yes) { + cprint_tag(":%p", menu); + cprint_name(" "); + } else { + switch (type) { + case S_BOOLEAN: + cprint_tag("t%p", menu); + if (sym_is_changable(sym)) + cprint_name("[%c]", val == no ? ' ' : '*'); + else + cprint_name("---"); + break; + case S_TRISTATE: + cprint_tag("t%p", menu); + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; + } + if (sym_is_changable(sym)) + cprint_name("<%c>", ch); + else + cprint_name("---"); + break; + default: + cprint_tag("s%p", menu); + tmp = cprint_name("(%s)", sym_get_string_value(sym)); + tmp = indent - tmp + 4; + if (tmp < 0) + tmp = 0; + cprint_name("%*c%s%s", tmp, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); + goto conf_childs; + } + } + cprint_name("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); + if (menu->prompt->type == P_MENU) { + cprint_name(" --->"); + return; + } + } + +conf_childs: + indent += doint; + for (child = menu->list; child; child = child->next) + build_conf(child); + indent -= doint; +} + +static void conf(struct menu *menu) +{ + struct dialog_list_item *active_item = NULL; + struct menu *submenu; + const char *prompt = menu_get_prompt(menu); + struct symbol *sym; + char active_entry[40]; + int stat, type; + + unlink("lxdialog.scrltmp"); + active_entry[0] = 0; + while (1) { + indent = 0; + child_count = 0; + current_menu = menu; + cdone(); cinit(); + build_conf(menu); + if (!child_count) + break; + if (menu == &rootmenu) { + cmake(); cprint_tag(":"); cprint_name("--- "); + cmake(); cprint_tag("L"); cprint_name("Load an Alternate Configuration File"); + cmake(); cprint_tag("S"); cprint_name("Save Configuration to an Alternate File"); + } + dialog_clear(); + stat = dialog_menu(prompt ? prompt : "Main Menu", + menu_instructions, rows, cols, rows - 10, + active_entry, item_no, items); + if (stat < 0) + return; + + if (stat == 1 || stat == 255) + break; + + active_item = first_sel_item(item_no, items); + if (!active_item) + continue; + active_item->selected = 0; + strncpy(active_entry, active_item->tag, sizeof(active_entry)); + active_entry[sizeof(active_entry)-1] = 0; + type = active_entry[0]; + if (!type) + continue; + + sym = NULL; + submenu = NULL; + if (sscanf(active_entry + 1, "%p", &submenu) == 1) + sym = submenu->sym; + + switch (stat) { + case 0: + switch (type) { + case 'm': + if (single_menu_mode) + submenu->data = (void *) (long) !submenu->data; + else + conf(submenu); + break; + case 't': + if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) + conf_choice(submenu); + else if (submenu->prompt->type == P_MENU) + conf(submenu); + break; + case 's': + conf_string(submenu); + break; + case 'L': + conf_load(); + break; + case 'S': + conf_save(); + break; + } + break; + case 2: + if (sym) + show_help(submenu); + else + show_helptext("README", mconf_readme); + break; + case 3: + if (type == 't') { + if (sym_set_tristate_value(sym, yes)) + break; + if (sym_set_tristate_value(sym, mod)) + show_textbox(NULL, setmod_text, 6, 74); + } + break; + case 4: + if (type == 't') + sym_set_tristate_value(sym, no); + break; + case 5: + if (type == 't') + sym_set_tristate_value(sym, mod); + break; + case 6: + if (type == 't') + sym_toggle_tristate_value(sym); + else if (type == 'm') + conf(submenu); + break; + case 7: + search_conf(); + break; + } + } +} + +static void show_textbox(const char *title, const char *text, int r, int c) +{ + int fd; + + fd = creat(".help.tmp", 0777); + write(fd, text, strlen(text)); + close(fd); + show_file(".help.tmp", title, r, c); + unlink(".help.tmp"); +} + +static void show_helptext(const char *title, const char *text) +{ + show_textbox(title, text, 0, 0); +} + +static void show_help(struct menu *menu) +{ + struct gstr help = str_new(); + struct symbol *sym = menu->sym; + + if (sym->help) + { + if (sym->name) { + str_printf(&help, "%s:\n\n", sym->name); + str_append(&help, sym->help); + str_append(&help, "\n"); + } + } else { + str_append(&help, nohelp_text); + } + get_symbol_str(&help, sym); + show_helptext(menu_get_prompt(menu), str_get(&help)); + str_free(&help); +} + +static void show_file(const char *filename, const char *title, int r, int c) +{ + while (dialog_textbox(title, filename, r ? r : rows, c ? c : cols) < 0) + ; +} + +static void conf_choice(struct menu *menu) +{ + const char *prompt = menu_get_prompt(menu); + struct menu *child; + struct symbol *active; + + active = sym_get_choice_value(menu->sym); + while (1) { + current_menu = menu; + cdone(); cinit(); + for (child = menu->list; child; child = child->next) { + if (!menu_is_visible(child)) + continue; + cmake(); + cprint_tag("%p", child); + cprint_name("%s", menu_get_prompt(child)); + if (child->sym == sym_get_choice_value(menu->sym)) + items[item_no - 1]->selected = 1; /* ON */ + else if (child->sym == active) + items[item_no - 1]->selected = 2; /* SELECTED */ + else + items[item_no - 1]->selected = 0; /* OFF */ + } + + switch (dialog_checklist(prompt ? prompt : "Main Menu", + radiolist_instructions, 15, 70, 6, + item_no, items, FLAG_RADIO)) { + case 0: + if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) != 1) + break; + sym_set_tristate_value(child->sym, yes); + return; + case 1: + if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) == 1) { + show_help(child); + active = child->sym; + } else + show_help(menu); + break; + case 255: + return; + } + } +} + +static void conf_string(struct menu *menu) +{ + const char *prompt = menu_get_prompt(menu); + + while (1) { + char *heading; + + switch (sym_get_type(menu->sym)) { + case S_INT: + heading = (char *) inputbox_instructions_int; + break; + case S_HEX: + heading = (char *) inputbox_instructions_hex; + break; + case S_STRING: + heading = (char *) inputbox_instructions_string; + break; + default: + heading = "Internal mconf error!"; + /* panic? */; + } + + switch (dialog_inputbox(prompt ? prompt : "Main Menu", + heading, 10, 75, + sym_get_string_value(menu->sym))) { + case 0: + if (sym_set_string_value(menu->sym, dialog_input_result)) + return; + show_textbox(NULL, "You have made an invalid entry.", 5, 43); + break; + case 1: + show_help(menu); + break; + case 255: + return; + } + } +} + +static void conf_load(void) +{ + while (1) { + switch (dialog_inputbox(NULL, load_config_text, 11, 55, + filename)) { + case 0: + if (!dialog_input_result[0]) + return; + if (!conf_read(dialog_input_result)) + return; + show_textbox(NULL, "File does not exist!", 5, 38); + break; + case 1: + show_helptext("Load Alternate Configuration", load_config_help); + break; + case 255: + return; + } + } +} + +static void conf_save(void) +{ + while (1) { + switch (dialog_inputbox(NULL, save_config_text, 11, 55, + filename)) { + case 0: + if (!dialog_input_result[0]) + return; + if (!conf_write(dialog_input_result)) + return; + show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); + break; + case 1: + show_helptext("Save Alternate Configuration", save_config_help); + break; + case 255: + return; + } + } +} + +static void conf_cleanup(void) +{ + tcsetattr(1, TCSAFLUSH, &ios_org); + unlink(".help.tmp"); +} + +static void winch_handler(int sig) +{ + struct winsize ws; + + if (ioctl(1, TIOCGWINSZ, &ws) == -1) { + rows = 24; + cols = 80; + } else { + rows = ws.ws_row; + cols = ws.ws_col; + } + + if (rows < 19 || cols < 80) { + end_dialog(); + fprintf(stderr, "Your display is too small to run Menuconfig!\n"); + fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); + exit(1); + } + + rows -= 4; + cols -= 5; + +} + +int main(int ac, char **av) +{ + struct symbol *sym; + char *mode; + int stat; + + conf_parse(av[1]); + conf_read(NULL); + + sym = sym_lookup("VERSION", 0); + sym_calc_value(sym); + snprintf(menu_backtitle, 128, "axTLS v%s Configuration", + sym_get_string_value(sym)); + + mode = getenv("MENUCONFIG_MODE"); + if (mode) { + if (!strcasecmp(mode, "single_menu")) + single_menu_mode = 1; + } + + tcgetattr(1, &ios_org); + atexit(conf_cleanup); + init_wsize(); + init_dialog(); + signal(SIGWINCH, winch_handler); + conf(&rootmenu); + end_dialog(); + + /* Restart dialog to act more like when lxdialog was still separate */ + init_dialog(); + do { + stat = dialog_yesno(NULL, + "Do you wish to save your new axTLS configuration?", 5, 60); + } while (stat < 0); + end_dialog(); + + if (stat == 0) { + conf_write(NULL); + printf("\n\n" + "*** End of axTLS configuration.\n" + "*** Check the top-level Makefile for additional configuration options.\n\n"); + } else + printf("\n\nYour axTLS configuration changes were NOT saved.\n\n"); + + return 0; +} diff --git a/circuitpython/lib/axtls/config/scripts/config/menu.c b/circuitpython/lib/axtls/config/scripts/config/menu.c new file mode 100644 index 0000000..0c13156 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/menu.c @@ -0,0 +1,390 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +struct menu rootmenu; +static struct menu **last_entry_ptr; + +struct file *file_list; +struct file *current_file; + +static void menu_warn(struct menu *menu, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +static void prop_warn(struct property *prop, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +void menu_init(void) +{ + current_entry = current_menu = &rootmenu; + last_entry_ptr = &rootmenu.list; +} + +void menu_add_entry(struct symbol *sym) +{ + struct menu *menu; + + menu = malloc(sizeof(*menu)); + memset(menu, 0, sizeof(*menu)); + menu->sym = sym; + menu->parent = current_menu; + menu->file = current_file; + menu->lineno = zconf_lineno(); + + *last_entry_ptr = menu; + last_entry_ptr = &menu->next; + current_entry = menu; +} + +void menu_end_entry(void) +{ +} + +void menu_add_menu(void) +{ + current_menu = current_entry; + last_entry_ptr = ¤t_entry->list; +} + +void menu_end_menu(void) +{ + last_entry_ptr = ¤t_menu->next; + current_menu = current_menu->parent; +} + +struct expr *menu_check_dep(struct expr *e) +{ + if (!e) + return e; + + switch (e->type) { + case E_NOT: + e->left.expr = menu_check_dep(e->left.expr); + break; + case E_OR: + case E_AND: + e->left.expr = menu_check_dep(e->left.expr); + e->right.expr = menu_check_dep(e->right.expr); + break; + case E_SYMBOL: + /* change 'm' into 'm' && MODULES */ + if (e->left.sym == &symbol_mod) + return expr_alloc_and(e, expr_alloc_symbol(modules_sym)); + break; + default: + break; + } + return e; +} + +void menu_add_dep(struct expr *dep) +{ + current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); +} + +void menu_set_type(int type) +{ + struct symbol *sym = current_entry->sym; + + if (sym->type == type) + return; + if (sym->type == S_UNKNOWN) { + sym->type = type; + return; + } + menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n", + sym->name ? sym->name : "", + sym_type_name(sym->type), sym_type_name(type)); +} + +struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) +{ + struct property *prop = prop_alloc(type, current_entry->sym); + + prop->menu = current_entry; + prop->text = prompt; + prop->expr = expr; + prop->visible.expr = menu_check_dep(dep); + + if (prompt) { + if (current_entry->prompt) + menu_warn(current_entry, "prompt redefined\n"); + current_entry->prompt = prop; + } + + return prop; +} + +void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) +{ + menu_add_prop(type, prompt, NULL, dep); +} + +void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) +{ + menu_add_prop(type, NULL, expr, dep); +} + +void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) +{ + menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); +} + +void sym_check_prop(struct symbol *sym) +{ + struct property *prop; + struct symbol *sym2; + for (prop = sym->prop; prop; prop = prop->next) { + switch (prop->type) { + case P_DEFAULT: + if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && + prop->expr->type != E_SYMBOL) + prop_warn(prop, + "default for config symbol '%'" + " must be a single symbol", sym->name); + break; + case P_SELECT: + sym2 = prop_get_symbol(prop); + if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) + prop_warn(prop, + "config symbol '%s' uses select, but is " + "not boolean or tristate", sym->name); + else if (sym2->type == S_UNKNOWN) + prop_warn(prop, + "'select' used by config symbol '%s' " + "refer to undefined symbol '%s'", + sym->name, sym2->name); + else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE) + prop_warn(prop, + "'%s' has wrong type. 'select' only " + "accept arguments of boolean and " + "tristate type", sym2->name); + break; + case P_RANGE: + if (sym->type != S_INT && sym->type != S_HEX) + prop_warn(prop, "range is only allowed " + "for int or hex symbols"); + if (!sym_string_valid(sym, prop->expr->left.sym->name) || + !sym_string_valid(sym, prop->expr->right.sym->name)) + prop_warn(prop, "range is invalid"); + break; + default: + ; + } + } +} + +void menu_finalize(struct menu *parent) +{ + struct menu *menu, *last_menu; + struct symbol *sym; + struct property *prop; + struct expr *parentdep, *basedep, *dep, *dep2, **ep; + + sym = parent->sym; + if (parent->list) { + if (sym && sym_is_choice(sym)) { + /* find the first choice value and find out choice type */ + for (menu = parent->list; menu; menu = menu->next) { + if (menu->sym) { + current_entry = parent; + menu_set_type(menu->sym->type); + current_entry = menu; + menu_set_type(sym->type); + break; + } + } + parentdep = expr_alloc_symbol(sym); + } else if (parent->prompt) + parentdep = parent->prompt->visible.expr; + else + parentdep = parent->dep; + + for (menu = parent->list; menu; menu = menu->next) { + basedep = expr_transform(menu->dep); + basedep = expr_alloc_and(expr_copy(parentdep), basedep); + basedep = expr_eliminate_dups(basedep); + menu->dep = basedep; + if (menu->sym) + prop = menu->sym->prop; + else + prop = menu->prompt; + for (; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + dep = expr_transform(prop->visible.expr); + dep = expr_alloc_and(expr_copy(basedep), dep); + dep = expr_eliminate_dups(dep); + if (menu->sym && menu->sym->type != S_TRISTATE) + dep = expr_trans_bool(dep); + prop->visible.expr = dep; + if (prop->type == P_SELECT) { + struct symbol *es = prop_get_symbol(prop); + es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, + expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + } + } + } + for (menu = parent->list; menu; menu = menu->next) + menu_finalize(menu); + } else if (sym) { + basedep = parent->prompt ? parent->prompt->visible.expr : NULL; + basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); + basedep = expr_eliminate_dups(expr_transform(basedep)); + last_menu = NULL; + for (menu = parent->next; menu; menu = menu->next) { + dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; + if (!expr_contains_symbol(dep, sym)) + break; + if (expr_depends_symbol(dep, sym)) + goto next; + dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); + dep = expr_eliminate_dups(expr_transform(dep)); + dep2 = expr_copy(basedep); + expr_eliminate_eq(&dep, &dep2); + expr_free(dep); + if (!expr_is_yes(dep2)) { + expr_free(dep2); + break; + } + expr_free(dep2); + next: + menu_finalize(menu); + menu->parent = parent; + last_menu = menu; + } + if (last_menu) { + parent->list = parent->next; + parent->next = last_menu->next; + last_menu->next = NULL; + } + } + for (menu = parent->list; menu; menu = menu->next) { + if (sym && sym_is_choice(sym) && menu->sym) { + menu->sym->flags |= SYMBOL_CHOICEVAL; + if (!menu->prompt) + menu_warn(menu, "choice value must have a prompt"); + for (prop = menu->sym->prop; prop; prop = prop->next) { + if (prop->type == P_PROMPT && prop->menu != menu) { + prop_warn(prop, "choice values " + "currently only support a " + "single prompt"); + } + if (prop->type == P_DEFAULT) + prop_warn(prop, "defaults for choice " + "values not supported"); + } + current_entry = menu; + menu_set_type(sym->type); + menu_add_symbol(P_CHOICE, sym, NULL); + prop = sym_get_choice_prop(sym); + for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) + ; + *ep = expr_alloc_one(E_CHOICE, NULL); + (*ep)->right.sym = menu->sym; + } + if (menu->list && (!menu->prompt || !menu->prompt->text)) { + for (last_menu = menu->list; ; last_menu = last_menu->next) { + last_menu->parent = parent; + if (!last_menu->next) + break; + } + last_menu->next = menu->next; + menu->next = menu->list; + menu->list = NULL; + } + } + + if (sym && !(sym->flags & SYMBOL_WARNED)) { + if (sym->type == S_UNKNOWN) + menu_warn(parent, "config symbol defined " + "without type\n"); + + if (sym_is_choice(sym) && !parent->prompt) + menu_warn(parent, "choice must have a prompt\n"); + + /* Check properties connected to this symbol */ + sym_check_prop(sym); + sym->flags |= SYMBOL_WARNED; + } + + if (sym && !sym_is_optional(sym) && parent->prompt) { + sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, + expr_alloc_and(parent->prompt->visible.expr, + expr_alloc_symbol(&symbol_mod))); + } +} + +bool menu_is_visible(struct menu *menu) +{ + struct menu *child; + struct symbol *sym; + tristate visible; + + if (!menu->prompt) + return false; + sym = menu->sym; + if (sym) { + sym_calc_value(sym); + visible = menu->prompt->visible.tri; + } else + visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr); + + if (visible != no) + return true; + if (!sym || sym_get_tristate_value(menu->sym) == no) + return false; + + for (child = menu->list; child; child = child->next) + if (menu_is_visible(child)) + return true; + return false; +} + +const char *menu_get_prompt(struct menu *menu) +{ + if (menu->prompt) + return menu->prompt->text; + else if (menu->sym) + return menu->sym->name; + return NULL; +} + +struct menu *menu_get_root_menu(struct menu *menu) +{ + return &rootmenu; +} + +struct menu *menu_get_parent_menu(struct menu *menu) +{ + enum prop_type type; + + for (; menu != &rootmenu; menu = menu->parent) { + type = menu->prompt ? menu->prompt->type : 0; + if (type == P_MENU) + break; + } + return menu; +} + diff --git a/circuitpython/lib/axtls/config/scripts/config/mkconfigs b/circuitpython/lib/axtls/config/scripts/config/mkconfigs new file mode 100755 index 0000000..3cb7bb1 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/mkconfigs @@ -0,0 +1,67 @@ +#!/bin/sh +# +# Copyright (C) 2002 Khalid Aziz +# Copyright (C) 2002 Randy Dunlap +# Copyright (C) 2002 Al Stone +# Copyright (C) 2002 Hewlett-Packard Company +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# Busybox version by Matteo Croce <3297627799 at wind.it> +# +# Rules to generate bbconfig.h from .config: +# - Retain lines that begin with "CONFIG_" +# - Retain lines that begin with "# CONFIG_" +# - lines that use double-quotes must \\-escape-quote them + +if [ $# -lt 1 ] +then + config=.config +else config=$1 +fi + +echo "#ifndef _BBCONFIG_H" +echo "#define _BBCONFIG_H" +echo \ +"/* + * busybox configuration options. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * + * This file is generated automatically by scripts/config/mkconfigs. + * Do not edit. + * + */" + +echo "static char const bbconfig_config[] =" +echo "\"CONFIG_BEGIN=n\\n\\" +echo "`sed 's/\"/\\\\\"/g' $config | grep "^#\? \?CONFIG_" | awk '{ print $0 "\\\\n\\\\" }' `" +echo "CONFIG_END=n\\n\";" +echo "#endif /* _BBCONFIG_H */" diff --git a/circuitpython/lib/axtls/config/scripts/config/symbol.c b/circuitpython/lib/axtls/config/scripts/config/symbol.c new file mode 100644 index 0000000..ea62972 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/symbol.c @@ -0,0 +1,809 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +struct symbol symbol_yes = { + .name = "y", + .curr = { "y", yes }, + .flags = SYMBOL_YES|SYMBOL_VALID, +}, symbol_mod = { + .name = "m", + .curr = { "m", mod }, + .flags = SYMBOL_MOD|SYMBOL_VALID, +}, symbol_no = { + .name = "n", + .curr = { "n", no }, + .flags = SYMBOL_NO|SYMBOL_VALID, +}, symbol_empty = { + .name = "", + .curr = { "", no }, + .flags = SYMBOL_VALID, +}; + +int sym_change_count; +struct symbol *modules_sym; +tristate modules_val; + +void sym_add_default(struct symbol *sym, const char *def) +{ + struct property *prop = prop_alloc(P_DEFAULT, sym); + + prop->expr = expr_alloc_symbol(sym_lookup(def, 1)); +} + +void sym_init(void) +{ + struct symbol *sym; + char *p; + static bool inited = false; + + if (inited) + return; + inited = true; + + sym = sym_lookup("VERSION", 0); + sym->type = S_STRING; + sym->flags |= SYMBOL_AUTO; + p = getenv("VERSION"); + if (p) + sym_add_default(sym, p); + + sym = sym_lookup("TARGET_ARCH", 0); + sym->type = S_STRING; + sym->flags |= SYMBOL_AUTO; + p = getenv("TARGET_ARCH"); + if (p) + sym_add_default(sym, p); + +} + +enum symbol_type sym_get_type(struct symbol *sym) +{ + enum symbol_type type = sym->type; + + if (type == S_TRISTATE) { + if (sym_is_choice_value(sym) && sym->visible == yes) + type = S_BOOLEAN; + else if (modules_val == no) + type = S_BOOLEAN; + } + return type; +} + +const char *sym_type_name(enum symbol_type type) +{ + switch (type) { + case S_BOOLEAN: + return "boolean"; + case S_TRISTATE: + return "tristate"; + case S_INT: + return "integer"; + case S_HEX: + return "hex"; + case S_STRING: + return "string"; + case S_UNKNOWN: + return "unknown"; + case S_OTHER: + break; + } + return "???"; +} + +struct property *sym_get_choice_prop(struct symbol *sym) +{ + struct property *prop; + + for_all_choices(sym, prop) + return prop; + return NULL; +} + +struct property *sym_get_default_prop(struct symbol *sym) +{ + struct property *prop; + + for_all_defaults(sym, prop) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri != no) + return prop; + } + return NULL; +} + +struct property *sym_get_range_prop(struct symbol *sym) +{ + struct property *prop; + + for_all_properties(sym, prop, P_RANGE) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri != no) + return prop; + } + return NULL; +} + +static void sym_calc_visibility(struct symbol *sym) +{ + struct property *prop; + tristate tri; + + /* any prompt visible? */ + tri = no; + for_all_prompts(sym, prop) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + tri = E_OR(tri, prop->visible.tri); + } + if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) + tri = yes; + if (sym->visible != tri) { + sym->visible = tri; + sym_set_changed(sym); + } + if (sym_is_choice_value(sym)) + return; + tri = no; + if (sym->rev_dep.expr) + tri = expr_calc_value(sym->rev_dep.expr); + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) + tri = yes; + if (sym->rev_dep.tri != tri) { + sym->rev_dep.tri = tri; + sym_set_changed(sym); + } +} + +static struct symbol *sym_calc_choice(struct symbol *sym) +{ + struct symbol *def_sym; + struct property *prop; + struct expr *e; + + /* is the user choice visible? */ + def_sym = sym->user.val; + if (def_sym) { + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* any of the defaults visible? */ + for_all_defaults(sym, prop) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri == no) + continue; + def_sym = prop_get_symbol(prop); + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* just get the first visible value */ + prop = sym_get_choice_prop(sym); + for (e = prop->expr; e; e = e->left.expr) { + def_sym = e->right.sym; + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* no choice? reset tristate value */ + sym->curr.tri = no; + return NULL; +} + +void sym_calc_value(struct symbol *sym) +{ + struct symbol_value newval, oldval; + struct property *prop; + struct expr *e; + + if (!sym) + return; + + if (sym->flags & SYMBOL_VALID) + return; + sym->flags |= SYMBOL_VALID; + + oldval = sym->curr; + + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + newval = symbol_empty.curr; + break; + case S_BOOLEAN: + case S_TRISTATE: + newval = symbol_no.curr; + break; + default: + sym->curr.val = sym->name; + sym->curr.tri = no; + return; + } + if (!sym_is_choice_value(sym)) + sym->flags &= ~SYMBOL_WRITE; + + sym_calc_visibility(sym); + + /* set default if recursively called */ + sym->curr = newval; + + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym_is_choice_value(sym) && sym->visible == yes) { + prop = sym_get_choice_prop(sym); + newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; + } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { + sym->flags |= SYMBOL_WRITE; + if (sym_has_value(sym)) + newval.tri = sym->user.tri; + else if (!sym_is_choice(sym)) { + prop = sym_get_default_prop(sym); + if (prop) + newval.tri = expr_calc_value(prop->expr); + } + newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri); + } else if (!sym_is_choice(sym)) { + prop = sym_get_default_prop(sym); + if (prop) { + sym->flags |= SYMBOL_WRITE; + newval.tri = expr_calc_value(prop->expr); + } + } + if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) + newval.tri = yes; + break; + case S_STRING: + case S_HEX: + case S_INT: + if (sym->visible != no) { + sym->flags |= SYMBOL_WRITE; + if (sym_has_value(sym)) { + newval.val = sym->user.val; + break; + } + } + prop = sym_get_default_prop(sym); + if (prop) { + struct symbol *ds = prop_get_symbol(prop); + if (ds) { + sym->flags |= SYMBOL_WRITE; + sym_calc_value(ds); + newval.val = ds->curr.val; + } + } + break; + default: + ; + } + + sym->curr = newval; + if (sym_is_choice(sym) && newval.tri == yes) + sym->curr.val = sym_calc_choice(sym); + + if (memcmp(&oldval, &sym->curr, sizeof(oldval))) + sym_set_changed(sym); + if (modules_sym == sym) + modules_val = modules_sym->curr.tri; + + if (sym_is_choice(sym)) { + int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); + prop = sym_get_choice_prop(sym); + for (e = prop->expr; e; e = e->left.expr) { + e->right.sym->flags |= flags; + if (flags & SYMBOL_CHANGED) + sym_set_changed(e->right.sym); + } + } +} + +void sym_clear_all_valid(void) +{ + struct symbol *sym; + int i; + + for_all_symbols(i, sym) + sym->flags &= ~SYMBOL_VALID; + sym_change_count++; + if (modules_sym) + sym_calc_value(modules_sym); +} + +void sym_set_changed(struct symbol *sym) +{ + struct property *prop; + + sym->flags |= SYMBOL_CHANGED; + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu) + prop->menu->flags |= MENU_CHANGED; + } +} + +void sym_set_all_changed(void) +{ + struct symbol *sym; + int i; + + for_all_symbols(i, sym) + sym_set_changed(sym); +} + +bool sym_tristate_within_range(struct symbol *sym, tristate val) +{ + int type = sym_get_type(sym); + + if (sym->visible == no) + return false; + + if (type != S_BOOLEAN && type != S_TRISTATE) + return false; + + if (type == S_BOOLEAN && val == mod) + return false; + if (sym->visible <= sym->rev_dep.tri) + return false; + if (sym_is_choice_value(sym) && sym->visible == yes) + return val == yes; + return val >= sym->rev_dep.tri && val <= sym->visible; +} + +bool sym_set_tristate_value(struct symbol *sym, tristate val) +{ + tristate oldval = sym_get_tristate_value(sym); + + if (oldval != val && !sym_tristate_within_range(sym, val)) + return false; + + if (sym->flags & SYMBOL_NEW) { + sym->flags &= ~SYMBOL_NEW; + sym_set_changed(sym); + } + if (sym_is_choice_value(sym) && val == yes) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + + cs->user.val = sym; + cs->flags &= ~SYMBOL_NEW; + } + + sym->user.tri = val; + if (oldval != val) { + sym_clear_all_valid(); + if (sym == modules_sym) + sym_set_all_changed(); + } + + return true; +} + +tristate sym_toggle_tristate_value(struct symbol *sym) +{ + tristate oldval, newval; + + oldval = newval = sym_get_tristate_value(sym); + do { + switch (newval) { + case no: + newval = mod; + break; + case mod: + newval = yes; + break; + case yes: + newval = no; + break; + } + if (sym_set_tristate_value(sym, newval)) + break; + } while (oldval != newval); + return newval; +} + +bool sym_string_valid(struct symbol *sym, const char *str) +{ + signed char ch; + + switch (sym->type) { + case S_STRING: + return true; + case S_INT: + ch = *str++; + if (ch == '-') + ch = *str++; + if (!isdigit(ch)) + return false; + if (ch == '0' && *str != 0) + return false; + while ((ch = *str++)) { + if (!isdigit(ch)) + return false; + } + return true; + case S_HEX: + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) + str += 2; + ch = *str++; + do { + if (!isxdigit(ch)) + return false; + } while ((ch = *str++)); + return true; + case S_BOOLEAN: + case S_TRISTATE: + switch (str[0]) { + case 'y': case 'Y': + case 'm': case 'M': + case 'n': case 'N': + return true; + } + return false; + default: + return false; + } +} + +bool sym_string_within_range(struct symbol *sym, const char *str) +{ + struct property *prop; + int val; + + switch (sym->type) { + case S_STRING: + return sym_string_valid(sym, str); + case S_INT: + if (!sym_string_valid(sym, str)) + return false; + prop = sym_get_range_prop(sym); + if (!prop) + return true; + val = strtol(str, NULL, 10); + return val >= strtol(prop->expr->left.sym->name, NULL, 10) && + val <= strtol(prop->expr->right.sym->name, NULL, 10); + case S_HEX: + if (!sym_string_valid(sym, str)) + return false; + prop = sym_get_range_prop(sym); + if (!prop) + return true; + val = strtol(str, NULL, 16); + return val >= strtol(prop->expr->left.sym->name, NULL, 16) && + val <= strtol(prop->expr->right.sym->name, NULL, 16); + case S_BOOLEAN: + case S_TRISTATE: + switch (str[0]) { + case 'y': case 'Y': + return sym_tristate_within_range(sym, yes); + case 'm': case 'M': + return sym_tristate_within_range(sym, mod); + case 'n': case 'N': + return sym_tristate_within_range(sym, no); + } + return false; + default: + return false; + } +} + +bool sym_set_string_value(struct symbol *sym, const char *newval) +{ + const char *oldval; + char *val; + int size; + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (newval[0]) { + case 'y': case 'Y': + return sym_set_tristate_value(sym, yes); + case 'm': case 'M': + return sym_set_tristate_value(sym, mod); + case 'n': case 'N': + return sym_set_tristate_value(sym, no); + } + return false; + default: + ; + } + + if (!sym_string_within_range(sym, newval)) + return false; + + if (sym->flags & SYMBOL_NEW) { + sym->flags &= ~SYMBOL_NEW; + sym_set_changed(sym); + } + + oldval = sym->user.val; + size = strlen(newval) + 1; + if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { + size += 2; + sym->user.val = val = malloc(size); + *val++ = '0'; + *val++ = 'x'; + } else if (!oldval || strcmp(oldval, newval)) + sym->user.val = val = malloc(size); + else + return true; + + strcpy(val, newval); + free((void *)oldval); + sym_clear_all_valid(); + + return true; +} + +const char *sym_get_string_value(struct symbol *sym) +{ + tristate val; + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + val = sym_get_tristate_value(sym); + switch (val) { + case no: + return "n"; + case mod: + return "m"; + case yes: + return "y"; + } + break; + default: + ; + } + return (const char *)sym->curr.val; +} + +bool sym_is_changable(struct symbol *sym) +{ + return sym->visible > sym->rev_dep.tri; +} + +struct symbol *sym_lookup(const char *name, int isconst) +{ + struct symbol *symbol; + const char *ptr; + char *new_name; + int hash = 0; + + if (name) { + if (name[0] && !name[1]) { + switch (name[0]) { + case 'y': return &symbol_yes; + case 'm': return &symbol_mod; + case 'n': return &symbol_no; + } + } + for (ptr = name; *ptr; ptr++) + hash += *ptr; + hash &= 0xff; + + for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { + if (!strcmp(symbol->name, name)) { + if ((isconst && symbol->flags & SYMBOL_CONST) || + (!isconst && !(symbol->flags & SYMBOL_CONST))) + return symbol; + } + } + new_name = strdup(name); + } else { + new_name = NULL; + hash = 256; + } + + symbol = malloc(sizeof(*symbol)); + memset(symbol, 0, sizeof(*symbol)); + symbol->name = new_name; + symbol->type = S_UNKNOWN; + symbol->flags = SYMBOL_NEW; + if (isconst) + symbol->flags |= SYMBOL_CONST; + + symbol->next = symbol_hash[hash]; + symbol_hash[hash] = symbol; + + return symbol; +} + +struct symbol *sym_find(const char *name) +{ + struct symbol *symbol = NULL; + const char *ptr; + int hash = 0; + + if (!name) + return NULL; + + if (name[0] && !name[1]) { + switch (name[0]) { + case 'y': return &symbol_yes; + case 'm': return &symbol_mod; + case 'n': return &symbol_no; + } + } + for (ptr = name; *ptr; ptr++) + hash += *ptr; + hash &= 0xff; + + for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { + if (!strcmp(symbol->name, name) && + !(symbol->flags & SYMBOL_CONST)) + break; + } + + return symbol; +} + +struct symbol **sym_re_search(const char *pattern) +{ + struct symbol *sym, **sym_arr = NULL; + int i, cnt, size; + regex_t re; + + cnt = size = 0; + /* Skip if empty */ + if (strlen(pattern) == 0) + return NULL; + if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) + return NULL; + + for_all_symbols(i, sym) { + if (sym->flags & SYMBOL_CONST || !sym->name) + continue; + if (regexec(&re, sym->name, 0, NULL, 0)) + continue; + if (cnt + 1 >= size) { + void *tmp = sym_arr; + size += 16; + sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); + if (!sym_arr) { + free(tmp); + return NULL; + } + } + sym_arr[cnt++] = sym; + } + if (sym_arr) + sym_arr[cnt] = NULL; + regfree(&re); + + return sym_arr; +} + + +struct symbol *sym_check_deps(struct symbol *sym); + +static struct symbol *sym_check_expr_deps(struct expr *e) +{ + struct symbol *sym; + + if (!e) + return NULL; + switch (e->type) { + case E_OR: + case E_AND: + sym = sym_check_expr_deps(e->left.expr); + if (sym) + return sym; + return sym_check_expr_deps(e->right.expr); + case E_NOT: + return sym_check_expr_deps(e->left.expr); + case E_EQUAL: + case E_UNEQUAL: + sym = sym_check_deps(e->left.sym); + if (sym) + return sym; + return sym_check_deps(e->right.sym); + case E_SYMBOL: + return sym_check_deps(e->left.sym); + default: + break; + } + printf("Oops! How to check %d?\n", e->type); + return NULL; +} + +struct symbol *sym_check_deps(struct symbol *sym) +{ + struct symbol *sym2; + struct property *prop; + + if (sym->flags & SYMBOL_CHECK_DONE) + return NULL; + if (sym->flags & SYMBOL_CHECK) { + printf("Warning! Found recursive dependency: %s", sym->name); + return sym; + } + + sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + sym2 = sym_check_expr_deps(sym->rev_dep.expr); + if (sym2) + goto out; + + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->type == P_CHOICE || prop->type == P_SELECT) + continue; + sym2 = sym_check_expr_deps(prop->visible.expr); + if (sym2) + goto out; + if (prop->type != P_DEFAULT || sym_is_choice(sym)) + continue; + sym2 = sym_check_expr_deps(prop->expr); + if (sym2) + goto out; + } +out: + if (sym2) + printf(" %s", sym->name); + sym->flags &= ~SYMBOL_CHECK; + return sym2; +} + +struct property *prop_alloc(enum prop_type type, struct symbol *sym) +{ + struct property *prop; + struct property **propp; + + prop = malloc(sizeof(*prop)); + memset(prop, 0, sizeof(*prop)); + prop->type = type; + prop->sym = sym; + prop->file = current_file; + prop->lineno = zconf_lineno(); + + /* append property to the prop list of symbol */ + if (sym) { + for (propp = &sym->prop; *propp; propp = &(*propp)->next) + ; + *propp = prop; + } + + return prop; +} + +struct symbol *prop_get_symbol(struct property *prop) +{ + if (prop->expr && (prop->expr->type == E_SYMBOL || + prop->expr->type == E_CHOICE)) + return prop->expr->left.sym; + return NULL; +} + +const char *prop_get_type_name(enum prop_type type) +{ + switch (type) { + case P_PROMPT: + return "prompt"; + case P_COMMENT: + return "comment"; + case P_MENU: + return "menu"; + case P_DEFAULT: + return "default"; + case P_CHOICE: + return "choice"; + case P_SELECT: + return "select"; + case P_RANGE: + return "range"; + case P_UNKNOWN: + break; + } + return "unknown"; +} diff --git a/circuitpython/lib/axtls/config/scripts/config/util.c b/circuitpython/lib/axtls/config/scripts/config/util.c new file mode 100644 index 0000000..8fc95a2 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/util.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2002-2005 Roman Zippel + * Copyright (C) 2002-2005 Sam Ravnborg + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include "lkc.h" + +/* file already present in list? If not add it */ +struct file *file_lookup(const char *name) +{ + struct file *file; + + for (file = file_list; file; file = file->next) { + if (!strcmp(name, file->name)) + return file; + } + + file = malloc(sizeof(*file)); + memset(file, 0, sizeof(*file)); + file->name = strdup(name); + file->next = file_list; + file_list = file; + return file; +} + +/* write a dependency file as used by kbuild to track dependencies */ +int file_write_dep(const char *name) +{ + struct file *file; + FILE *out; + + if (!name) + name = "config/.config.cmd"; + out = fopen("config/.config.tmp", "w"); + if (!out) + return 1; + fprintf(out, "deps_config := \\\n"); + for (file = file_list; file; file = file->next) { + if (file->next) + fprintf(out, "\t%s \\\n", file->name); + else + fprintf(out, "\t%s\n", file->name); + } + fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n"); + fclose(out); + rename(".config.tmp", name); + return 0; +} + + +/* Allocate initial growable sting */ +struct gstr str_new(void) +{ + struct gstr gs; + gs.s = malloc(sizeof(char) * 64); + gs.len = 16; + strcpy(gs.s, "\0"); + return gs; +} + +/* Allocate and assign growable string */ +struct gstr str_assign(const char *s) +{ + struct gstr gs; + gs.s = strdup(s); + gs.len = strlen(s) + 1; + return gs; +} + +/* Free storage for growable string */ +void str_free(struct gstr *gs) +{ + if (gs->s) + free(gs->s); + gs->s = NULL; + gs->len = 0; +} + +/* Append to growable string */ +void str_append(struct gstr *gs, const char *s) +{ + size_t l = strlen(gs->s) + strlen(s) + 1; + if (l > gs->len) { + gs->s = realloc(gs->s, l); + gs->len = l; + } + strcat(gs->s, s); +} + +/* Append printf formatted string to growable string */ +void str_printf(struct gstr *gs, const char *fmt, ...) +{ + va_list ap; + char s[10000]; /* big enough... */ + va_start(ap, fmt); + vsnprintf(s, sizeof(s), fmt, ap); + str_append(gs, s); + va_end(ap); +} + +/* Retreive value of growable string */ +const char *str_get(struct gstr *gs) +{ + return gs->s; +} + diff --git a/circuitpython/lib/axtls/config/scripts/config/zconf.l b/circuitpython/lib/axtls/config/scripts/config/zconf.l new file mode 100644 index 0000000..55517b2 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/zconf.l @@ -0,0 +1,366 @@ +%option backup nostdinit noyywrap never-interactive full ecs +%option 8bit backup nodefault perf-report perf-report +%x COMMAND HELP STRING PARAM +%{ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +#define START_STRSIZE 16 + +char *text; +static char *text_ptr; +static int text_size, text_asize; + +struct buffer { + struct buffer *parent; + YY_BUFFER_STATE state; +}; + +struct buffer *current_buf; + +static int last_ts, first_ts; + +static void zconf_endhelp(void); +static struct buffer *zconf_endfile(void); + +void new_string(void) +{ + text = malloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_ptr = text; + text_size = 0; + *text_ptr = 0; +} + +void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + text = realloc(text, new_size); + text_asize = new_size; + text_ptr = text + text_size; + } + memcpy(text_ptr, str, size); + text_ptr += size; + text_size += size; + *text_ptr = 0; +} + +void alloc_string(const char *str, int size) +{ + text = malloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} +%} + +ws [ \n\t] +n [A-Za-z0-9_] + +%% + int str = 0; + int ts, i; + +[ \t]*#.*\n current_file->lineno++; +[ \t]*#.* + +[ \t]*\n current_file->lineno++; return T_EOL; + +[ \t]+ { + BEGIN(COMMAND); +} + +. { + unput(yytext[0]); + BEGIN(COMMAND); +} + + +{ + "mainmenu" BEGIN(PARAM); return T_MAINMENU; + "menu" BEGIN(PARAM); return T_MENU; + "endmenu" BEGIN(PARAM); return T_ENDMENU; + "source" BEGIN(PARAM); return T_SOURCE; + "choice" BEGIN(PARAM); return T_CHOICE; + "endchoice" BEGIN(PARAM); return T_ENDCHOICE; + "comment" BEGIN(PARAM); return T_COMMENT; + "config" BEGIN(PARAM); return T_CONFIG; + "menuconfig" BEGIN(PARAM); return T_MENUCONFIG; + "help" BEGIN(PARAM); return T_HELP; + "if" BEGIN(PARAM); return T_IF; + "endif" BEGIN(PARAM); return T_ENDIF; + "depends" BEGIN(PARAM); return T_DEPENDS; + "requires" BEGIN(PARAM); return T_REQUIRES; + "optional" BEGIN(PARAM); return T_OPTIONAL; + "default" BEGIN(PARAM); return T_DEFAULT; + "prompt" BEGIN(PARAM); return T_PROMPT; + "tristate" BEGIN(PARAM); return T_TRISTATE; + "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE; + "bool" BEGIN(PARAM); return T_BOOLEAN; + "boolean" BEGIN(PARAM); return T_BOOLEAN; + "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN; + "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN; + "int" BEGIN(PARAM); return T_INT; + "hex" BEGIN(PARAM); return T_HEX; + "string" BEGIN(PARAM); return T_STRING; + "select" BEGIN(PARAM); return T_SELECT; + "enable" BEGIN(PARAM); return T_SELECT; + "range" BEGIN(PARAM); return T_RANGE; + {n}+ { + alloc_string(yytext, yyleng); + zconflval.string = text; + return T_WORD; + } + . + \n current_file->lineno++; BEGIN(INITIAL); +} + +{ + "&&" return T_AND; + "||" return T_OR; + "(" return T_OPEN_PAREN; + ")" return T_CLOSE_PAREN; + "!" return T_NOT; + "=" return T_EQUAL; + "!=" return T_UNEQUAL; + "if" return T_IF; + "on" return T_ON; + \"|\' { + str = yytext[0]; + new_string(); + BEGIN(STRING); + } + \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; + --- /* ignore */ + ({n}|[-/.])+ { + alloc_string(yytext, yyleng); + zconflval.string = text; + return T_WORD; + } + #.* /* comment */ + \\\n current_file->lineno++; + . + <> { + BEGIN(INITIAL); + } +} + +{ + [^'"\\\n]+/\n { + append_string(yytext, yyleng); + zconflval.string = text; + return T_WORD_QUOTE; + } + [^'"\\\n]+ { + append_string(yytext, yyleng); + } + \\.?/\n { + append_string(yytext + 1, yyleng - 1); + zconflval.string = text; + return T_WORD_QUOTE; + } + \\.? { + append_string(yytext + 1, yyleng - 1); + } + \'|\" { + if (str == yytext[0]) { + BEGIN(PARAM); + zconflval.string = text; + return T_WORD_QUOTE; + } else + append_string(yytext, 1); + } + \n { + printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); + current_file->lineno++; + BEGIN(INITIAL); + return T_EOL; + } + <> { + BEGIN(INITIAL); + } +} + +{ + [ \t]+ { + ts = 0; + for (i = 0; i < yyleng; i++) { + if (yytext[i] == '\t') + ts = (ts & ~7) + 8; + else + ts++; + } + last_ts = ts; + if (first_ts) { + if (ts < first_ts) { + zconf_endhelp(); + return T_HELPTEXT; + } + ts -= first_ts; + while (ts > 8) { + append_string(" ", 8); + ts -= 8; + } + append_string(" ", ts); + } + } + [ \t]*\n/[^ \t\n] { + current_file->lineno++; + zconf_endhelp(); + return T_HELPTEXT; + } + [ \t]*\n { + current_file->lineno++; + append_string("\n", 1); + } + [^ \t\n].* { + append_string(yytext, yyleng); + if (!first_ts) + first_ts = last_ts; + } + <> { + zconf_endhelp(); + return T_HELPTEXT; + } +} + +<> { + if (current_buf) { + zconf_endfile(); + return T_EOF; + } + fclose(yyin); + yyterminate(); +} + +%% +void zconf_starthelp(void) +{ + new_string(); + last_ts = first_ts = 0; + BEGIN(HELP); +} + +static void zconf_endhelp(void) +{ + zconflval.string = text; + BEGIN(INITIAL); +} + + +/* + * Try to open specified file with following names: + * ./name + * $(srctree)/name + * The latter is used when srctree is separate from objtree + * when compiling the kernel. + * Return NULL if file is not found. + */ +FILE *zconf_fopen(const char *name) +{ + char *env, fullname[PATH_MAX+1]; + FILE *f; + + f = fopen(name, "r"); + if (!f && name[0] != '/') { + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + f = fopen(fullname, "r"); + } + } + return f; +} + +void zconf_initscan(const char *name) +{ + yyin = zconf_fopen(name); + if (!yyin) { + printf("can't find file %s\n", name); + exit(1); + } + + current_buf = malloc(sizeof(*current_buf)); + memset(current_buf, 0, sizeof(*current_buf)); + + current_file = file_lookup(name); + current_file->lineno = 1; + current_file->flags = FILE_BUSY; +} + +void zconf_nextfile(const char *name) +{ + struct file *file = file_lookup(name); + struct buffer *buf = malloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + current_buf->state = YY_CURRENT_BUFFER; + yyin = zconf_fopen(name); + if (!yyin) { + printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + exit(1); + } + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + if (file->flags & FILE_BUSY) { + printf("recursive scan (%s)?\n", name); + exit(1); + } + if (file->flags & FILE_SCANNED) { + printf("file %s already scanned?\n", name); + exit(1); + } + file->flags |= FILE_BUSY; + file->lineno = 1; + file->parent = current_file; + current_file = file; +} + +static struct buffer *zconf_endfile(void) +{ + struct buffer *parent; + + current_file->flags |= FILE_SCANNED; + current_file->flags &= ~FILE_BUSY; + current_file = current_file->parent; + + parent = current_buf->parent; + if (parent) { + fclose(yyin); + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(parent->state); + } + free(current_buf); + current_buf = parent; + + return parent; +} + +int zconf_lineno(void) +{ + if (current_buf) + return current_file->lineno - 1; + else + return 0; +} + +char *zconf_curname(void) +{ + if (current_buf) + return current_file->name; + else + return ""; +} diff --git a/circuitpython/lib/axtls/config/scripts/config/zconf.tab.c_shipped b/circuitpython/lib/axtls/config/scripts/config/zconf.tab.c_shipped new file mode 100644 index 0000000..cc68dcb --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/zconf.tab.c_shipped @@ -0,0 +1,2130 @@ +/* A Bison parser, made by GNU Bison 1.875a. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* If NAME_PREFIX is specified substitute the variables and functions + names. */ +#define yyparse zconfparse +#define yylex zconflex +#define yyerror zconferror +#define yylval zconflval +#define yychar zconfchar +#define yydebug zconfdebug +#define yynerrs zconfnerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_MAINMENU = 258, + T_MENU = 259, + T_ENDMENU = 260, + T_SOURCE = 261, + T_CHOICE = 262, + T_ENDCHOICE = 263, + T_COMMENT = 264, + T_CONFIG = 265, + T_MENUCONFIG = 266, + T_HELP = 267, + T_HELPTEXT = 268, + T_IF = 269, + T_ENDIF = 270, + T_DEPENDS = 271, + T_REQUIRES = 272, + T_OPTIONAL = 273, + T_PROMPT = 274, + T_DEFAULT = 275, + T_TRISTATE = 276, + T_DEF_TRISTATE = 277, + T_BOOLEAN = 278, + T_DEF_BOOLEAN = 279, + T_STRING = 280, + T_INT = 281, + T_HEX = 282, + T_WORD = 283, + T_WORD_QUOTE = 284, + T_UNEQUAL = 285, + T_EOF = 286, + T_EOL = 287, + T_CLOSE_PAREN = 288, + T_OPEN_PAREN = 289, + T_ON = 290, + T_SELECT = 291, + T_RANGE = 292, + T_OR = 293, + T_AND = 294, + T_EQUAL = 295, + T_NOT = 296 + }; +#endif +#define T_MAINMENU 258 +#define T_MENU 259 +#define T_ENDMENU 260 +#define T_SOURCE 261 +#define T_CHOICE 262 +#define T_ENDCHOICE 263 +#define T_COMMENT 264 +#define T_CONFIG 265 +#define T_MENUCONFIG 266 +#define T_HELP 267 +#define T_HELPTEXT 268 +#define T_IF 269 +#define T_ENDIF 270 +#define T_DEPENDS 271 +#define T_REQUIRES 272 +#define T_OPTIONAL 273 +#define T_PROMPT 274 +#define T_DEFAULT 275 +#define T_TRISTATE 276 +#define T_DEF_TRISTATE 277 +#define T_BOOLEAN 278 +#define T_DEF_BOOLEAN 279 +#define T_STRING 280 +#define T_INT 281 +#define T_HEX 282 +#define T_WORD 283 +#define T_WORD_QUOTE 284 +#define T_UNEQUAL 285 +#define T_EOF 286 +#define T_EOL 287 +#define T_CLOSE_PAREN 288 +#define T_OPEN_PAREN 289 +#define T_ON 290 +#define T_SELECT 291 +#define T_RANGE 292 +#define T_OR 293 +#define T_AND 294 +#define T_EQUAL 295 +#define T_NOT 296 + + + + +/* Copy the first part of user declarations. */ + + +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include + +#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) + +#define PRINTD 0x0001 +#define DEBUG_PARSE 0x0002 + +int cdebug = PRINTD; + +extern int zconflex(void); +static void zconfprint(const char *err, ...); +static void zconferror(const char *err); +static bool zconf_endtoken(int token, int starttoken, int endtoken); + +struct symbol *symbol_hash[257]; + +static struct menu *current_menu, *current_entry; + +#define YYERROR_VERBOSE + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) + +typedef union YYSTYPE { + int token; + char *string; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; +} YYSTYPE; +/* Line 191 of yacc.c. */ + +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +#define LKC_DIRECT_LINK +#include "lkc.h" + + +/* Line 214 of yacc.c. */ + + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || (defined (_ALLOCA_H) && defined (__GNUC__)) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC malloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 2 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 201 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 42 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 41 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 104 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 182 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 296 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 4, 7, 9, 11, 13, 17, 19, + 21, 23, 26, 28, 30, 32, 34, 36, 38, 42, + 45, 49, 52, 53, 56, 59, 62, 65, 69, 74, + 78, 83, 87, 91, 95, 100, 105, 110, 116, 119, + 122, 124, 128, 131, 132, 135, 138, 141, 144, 149, + 153, 157, 160, 165, 166, 169, 173, 175, 179, 182, + 183, 186, 189, 192, 196, 199, 201, 205, 208, 209, + 212, 215, 218, 222, 226, 228, 232, 235, 238, 241, + 242, 245, 248, 253, 257, 261, 262, 265, 267, 269, + 272, 275, 278, 280, 282, 283, 286, 288, 292, 296, + 300, 303, 307, 311, 313 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 43, 0, -1, -1, 43, 44, -1, 45, -1, 55, + -1, 66, -1, 3, 77, 79, -1, 5, -1, 15, + -1, 8, -1, 1, 79, -1, 61, -1, 71, -1, + 47, -1, 49, -1, 69, -1, 79, -1, 10, 28, + 32, -1, 46, 50, -1, 11, 28, 32, -1, 48, + 50, -1, -1, 50, 51, -1, 50, 75, -1, 50, + 73, -1, 50, 32, -1, 21, 76, 32, -1, 22, + 81, 80, 32, -1, 23, 76, 32, -1, 24, 81, + 80, 32, -1, 26, 76, 32, -1, 27, 76, 32, + -1, 25, 76, 32, -1, 19, 77, 80, 32, -1, + 20, 81, 80, 32, -1, 36, 28, 80, 32, -1, + 37, 82, 82, 80, 32, -1, 7, 32, -1, 52, + 56, -1, 78, -1, 53, 58, 54, -1, 53, 58, + -1, -1, 56, 57, -1, 56, 75, -1, 56, 73, + -1, 56, 32, -1, 19, 77, 80, 32, -1, 21, + 76, 32, -1, 23, 76, 32, -1, 18, 32, -1, + 20, 28, 80, 32, -1, -1, 58, 45, -1, 14, + 81, 32, -1, 78, -1, 59, 62, 60, -1, 59, + 62, -1, -1, 62, 45, -1, 62, 66, -1, 62, + 55, -1, 4, 77, 32, -1, 63, 74, -1, 78, + -1, 64, 67, 65, -1, 64, 67, -1, -1, 67, + 45, -1, 67, 66, -1, 67, 55, -1, 67, 1, + 32, -1, 6, 77, 32, -1, 68, -1, 9, 77, + 32, -1, 70, 74, -1, 12, 32, -1, 72, 13, + -1, -1, 74, 75, -1, 74, 32, -1, 16, 35, + 81, 32, -1, 16, 81, 32, -1, 17, 81, 32, + -1, -1, 77, 80, -1, 28, -1, 29, -1, 5, + 79, -1, 8, 79, -1, 15, 79, -1, 32, -1, + 31, -1, -1, 14, 81, -1, 82, -1, 82, 40, + 82, -1, 82, 30, 82, -1, 34, 81, 33, -1, + 41, 81, -1, 81, 38, 81, -1, 81, 39, 81, + -1, 28, -1, 29, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 94, 94, 95, 98, 99, 100, 101, 102, 103, + 104, 105, 109, 110, 111, 112, 113, 114, 120, 128, + 134, 142, 152, 154, 155, 156, 157, 160, 166, 173, + 179, 186, 192, 198, 204, 210, 216, 222, 230, 239, + 245, 254, 255, 261, 263, 264, 265, 266, 269, 275, + 281, 287, 293, 299, 301, 306, 315, 324, 325, 331, + 333, 334, 335, 340, 347, 353, 362, 363, 369, 371, + 372, 373, 374, 377, 383, 390, 397, 404, 410, 417, + 418, 419, 422, 427, 432, 440, 442, 447, 448, 451, + 452, 453, 457, 457, 459, 460, 463, 464, 465, 466, + 467, 468, 469, 472, 473 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", + "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", + "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", + "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE", + "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT", + "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL", + "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR", + "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block", + "common_block", "config_entry_start", "config_stmt", + "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", + "config_option", "choice", "choice_entry", "choice_end", "choice_stmt", + "choice_option_list", "choice_option", "choice_block", "if", "if_end", + "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt", + "menu_block", "source", "source_stmt", "comment", "comment_stmt", + "help_start", "help", "depends_list", "depends", "prompt_stmt_opt", + "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 42, 43, 43, 44, 44, 44, 44, 44, 44, + 44, 44, 45, 45, 45, 45, 45, 45, 46, 47, + 48, 49, 50, 50, 50, 50, 50, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, + 54, 55, 55, 56, 56, 56, 56, 56, 57, 57, + 57, 57, 57, 58, 58, 59, 60, 61, 61, 62, + 62, 62, 62, 63, 64, 65, 66, 66, 67, 67, + 67, 67, 67, 68, 69, 70, 71, 72, 73, 74, + 74, 74, 75, 75, 75, 76, 76, 77, 77, 78, + 78, 78, 79, 79, 80, 80, 81, 81, 81, 81, + 81, 81, 81, 82, 82 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 3, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, + 3, 2, 0, 2, 2, 2, 2, 3, 4, 3, + 4, 3, 3, 3, 4, 4, 4, 5, 2, 2, + 1, 3, 2, 0, 2, 2, 2, 2, 4, 3, + 3, 2, 4, 0, 2, 3, 1, 3, 2, 0, + 2, 2, 2, 3, 2, 1, 3, 2, 0, 2, + 2, 2, 3, 3, 1, 3, 2, 2, 2, 0, + 2, 2, 4, 3, 3, 0, 2, 1, 1, 2, + 2, 2, 1, 1, 0, 2, 1, 3, 3, 3, + 2, 3, 3, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 2, 0, 1, 0, 0, 0, 8, 0, 0, 10, + 0, 0, 0, 0, 9, 93, 92, 3, 4, 22, + 14, 22, 15, 43, 53, 5, 59, 12, 79, 68, + 6, 74, 16, 79, 13, 17, 11, 87, 88, 0, + 0, 0, 38, 0, 0, 0, 103, 104, 0, 0, + 0, 96, 19, 21, 39, 42, 58, 64, 0, 76, + 7, 63, 73, 75, 18, 20, 0, 100, 55, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 85, 0, 85, 85, 85, 26, 0, 0, 23, 0, + 25, 24, 0, 0, 0, 85, 85, 47, 44, 46, + 45, 0, 0, 0, 54, 41, 40, 60, 62, 57, + 61, 56, 81, 80, 0, 69, 71, 66, 70, 65, + 99, 101, 102, 98, 97, 77, 0, 0, 0, 94, + 94, 0, 94, 94, 0, 94, 0, 0, 0, 94, + 0, 78, 51, 94, 94, 0, 0, 89, 90, 91, + 72, 0, 83, 84, 0, 0, 0, 27, 86, 0, + 29, 0, 33, 31, 32, 0, 94, 0, 0, 49, + 50, 82, 95, 34, 35, 28, 30, 36, 0, 48, + 52, 37 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 1, 17, 18, 19, 20, 21, 22, 52, 88, + 23, 24, 105, 25, 54, 98, 55, 26, 109, 27, + 56, 28, 29, 117, 30, 58, 31, 32, 33, 34, + 89, 90, 57, 91, 131, 132, 106, 35, 155, 50, + 51 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -99 +static const short yypact[] = +{ + -99, 48, -99, 38, 46, 46, -99, 46, -29, -99, + 46, -17, -3, -11, -99, -99, -99, -99, -99, -99, + -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, + -99, -99, -99, -99, -99, -99, -99, -99, -99, 38, + 12, 15, -99, 18, 51, 62, -99, -99, -11, -11, + 4, -24, 138, 138, 160, 121, 110, -4, 81, -4, + -99, -99, -99, -99, -99, -99, -19, -99, -99, -11, + -11, 70, 70, 73, 32, -11, 46, -11, 46, -11, + 46, -11, 46, 46, 46, -99, 36, 70, -99, 95, + -99, -99, 96, 46, 106, 46, 46, -99, -99, -99, + -99, 38, 38, 38, -99, -99, -99, -99, -99, -99, + -99, -99, -99, -99, 112, -99, -99, -99, -99, -99, + -99, 117, -99, -99, -99, -99, -11, 33, 65, 131, + 1, 119, 131, 1, 136, 1, 153, 154, 155, 131, + 70, -99, -99, 131, 131, 156, 157, -99, -99, -99, + -99, 101, -99, -99, -11, 158, 159, -99, -99, 161, + -99, 162, -99, -99, -99, 163, 131, 164, 165, -99, + -99, -99, 99, -99, -99, -99, -99, -99, 166, -99, + -99, -99 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short yypgoto[] = +{ + -99, -99, -99, 111, -99, -99, -99, -99, 178, -99, + -99, -99, -99, 91, -99, -99, -99, -99, -99, -99, + -99, -99, -99, -99, 115, -99, -99, -99, -99, -99, + -99, 146, 168, 89, 27, 0, 126, -1, -98, -48, + -63 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -68 +static const short yytable[] = +{ + 66, 67, 36, 42, 39, 40, 71, 41, 123, 124, + 43, 44, 74, 75, 120, 154, 72, 46, 47, 69, + 70, 121, 122, 48, 140, 45, 127, 128, 112, 130, + 49, 133, 156, 135, 158, 159, 68, 161, 60, 69, + 70, 165, 69, 70, 61, 167, 168, 62, 2, 3, + 63, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 46, 47, 13, 14, 139, 152, 48, 126, 178, 15, + 16, 69, 70, 49, 37, 38, 129, 166, 151, 15, + 16, -67, 114, 64, -67, 5, 101, 7, 8, 102, + 10, 11, 12, 143, 65, 13, 103, 153, 46, 47, + 147, 148, 149, 69, 70, 125, 172, 134, 141, 136, + 137, 138, 15, 16, 5, 101, 7, 8, 102, 10, + 11, 12, 145, 146, 13, 103, 101, 7, 142, 102, + 10, 11, 12, 171, 144, 13, 103, 69, 70, 69, + 70, 15, 16, 100, 150, 154, 113, 108, 113, 116, + 73, 157, 15, 16, 74, 75, 70, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 104, 107, 160, 115, + 85, 110, 73, 118, 86, 87, 74, 75, 92, 93, + 94, 95, 111, 96, 119, 162, 163, 164, 169, 170, + 173, 174, 97, 175, 176, 177, 179, 180, 181, 53, + 99, 59 +}; + +static const unsigned char yycheck[] = +{ + 48, 49, 3, 32, 4, 5, 30, 7, 71, 72, + 10, 28, 16, 17, 33, 14, 40, 28, 29, 38, + 39, 69, 70, 34, 87, 28, 74, 75, 32, 77, + 41, 79, 130, 81, 132, 133, 32, 135, 39, 38, + 39, 139, 38, 39, 32, 143, 144, 32, 0, 1, + 32, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 28, 29, 14, 15, 28, 32, 34, 35, 166, 31, + 32, 38, 39, 41, 28, 29, 76, 140, 126, 31, + 32, 0, 1, 32, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 93, 32, 14, 15, 32, 28, 29, + 101, 102, 103, 38, 39, 32, 154, 80, 13, 82, + 83, 84, 31, 32, 4, 5, 6, 7, 8, 9, + 10, 11, 95, 96, 14, 15, 5, 6, 32, 8, + 9, 10, 11, 32, 28, 14, 15, 38, 39, 38, + 39, 31, 32, 54, 32, 14, 57, 56, 59, 58, + 12, 32, 31, 32, 16, 17, 39, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 55, 56, 32, 58, + 32, 56, 12, 58, 36, 37, 16, 17, 18, 19, + 20, 21, 56, 23, 58, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 21, + 54, 33 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 43, 0, 1, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 14, 15, 31, 32, 44, 45, 46, + 47, 48, 49, 52, 53, 55, 59, 61, 63, 64, + 66, 68, 69, 70, 71, 79, 79, 28, 29, 77, + 77, 77, 32, 77, 28, 28, 28, 29, 34, 41, + 81, 82, 50, 50, 56, 58, 62, 74, 67, 74, + 79, 32, 32, 32, 32, 32, 81, 81, 32, 38, + 39, 30, 40, 12, 16, 17, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 32, 36, 37, 51, 72, + 73, 75, 18, 19, 20, 21, 23, 32, 57, 73, + 75, 5, 8, 15, 45, 54, 78, 45, 55, 60, + 66, 78, 32, 75, 1, 45, 55, 65, 66, 78, + 33, 81, 81, 82, 82, 32, 35, 81, 81, 77, + 81, 76, 77, 81, 76, 81, 76, 76, 76, 28, + 82, 13, 32, 77, 28, 76, 76, 79, 79, 79, + 32, 81, 32, 32, 14, 80, 80, 32, 80, 80, + 32, 80, 32, 32, 32, 80, 82, 80, 80, 32, + 32, 32, 81, 32, 32, 32, 32, 32, 80, 32, + 32, 32 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 8: + + { zconfprint("unexpected 'endmenu' statement"); ;} + break; + + case 9: + + { zconfprint("unexpected 'endif' statement"); ;} + break; + + case 10: + + { zconfprint("unexpected 'endchoice' statement"); ;} + break; + + case 11: + + { zconfprint("syntax error"); yyerrok; ;} + break; + + case 18: + + { + struct symbol *sym = sym_lookup(yyvsp[-1].string, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); +;} + break; + + case 19: + + { + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 20: + + { + struct symbol *sym = sym_lookup(yyvsp[-1].string, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); +;} + break; + + case 21: + + { + if (current_entry->prompt) + current_entry->prompt->type = P_MENU; + else + zconfprint("warning: menuconfig statement without prompt"); + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 27: + + { + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 28: + + { + menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 29: + + { + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 30: + + { + menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 31: + + { + menu_set_type(S_INT); + printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 32: + + { + menu_set_type(S_HEX); + printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 33: + + { + menu_set_type(S_STRING); + printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 34: + + { + menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 35: + + { + menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 36: + + { + menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 37: + + { + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 38: + + { + struct symbol *sym = sym_lookup(NULL, 0); + sym->flags |= SYMBOL_CHOICE; + menu_add_entry(sym); + menu_add_expr(P_CHOICE, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 39: + + { + menu_end_entry(); + menu_add_menu(); +;} + break; + + case 40: + + { + if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 42: + + { + printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +;} + break; + + case 48: + + { + menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 49: + + { + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 50: + + { + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 51: + + { + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 52: + + { + menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 55: + + { + printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); + menu_add_entry(NULL); + menu_add_dep(yyvsp[-1].expr); + menu_end_entry(); + menu_add_menu(); +;} + break; + + case 56: + + { + if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 58: + + { + printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +;} + break; + + case 63: + + { + menu_add_entry(NULL); + menu_add_prop(P_MENU, yyvsp[-1].string, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 64: + + { + menu_end_entry(); + menu_add_menu(); +;} + break; + + case 65: + + { + if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 67: + + { + printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +;} + break; + + case 72: + + { zconfprint("invalid menu option"); yyerrok; ;} + break; + + case 73: + + { + yyval.string = yyvsp[-1].string; + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); +;} + break; + + case 74: + + { + zconf_nextfile(yyvsp[0].string); +;} + break; + + case 75: + + { + menu_add_entry(NULL); + menu_add_prop(P_COMMENT, yyvsp[-1].string, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 76: + + { + menu_end_entry(); +;} + break; + + case 77: + + { + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +;} + break; + + case 78: + + { + current_entry->sym->help = yyvsp[0].string; +;} + break; + + case 82: + + { + menu_add_dep(yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 83: + + { + menu_add_dep(yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 84: + + { + menu_add_dep(yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 86: + + { + menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr); +;} + break; + + case 89: + + { yyval.token = T_ENDMENU; ;} + break; + + case 90: + + { yyval.token = T_ENDCHOICE; ;} + break; + + case 91: + + { yyval.token = T_ENDIF; ;} + break; + + case 94: + + { yyval.expr = NULL; ;} + break; + + case 95: + + { yyval.expr = yyvsp[0].expr; ;} + break; + + case 96: + + { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;} + break; + + case 97: + + { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} + break; + + case 98: + + { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} + break; + + case 99: + + { yyval.expr = yyvsp[-1].expr; ;} + break; + + case 100: + + { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;} + break; + + case 101: + + { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 102: + + { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 103: + + { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;} + break; + + case 104: + + { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;} + break; + + + } + +/* Line 999 of yacc.c. */ + + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + + + + +void conf_parse(const char *name) +{ + struct symbol *sym; + int i; + + zconf_initscan(name); + + sym_init(); + menu_init(); + modules_sym = sym_lookup("MODULES", 0); + rootmenu.prompt = menu_add_prop(P_MENU, "axTLS Configuration", NULL, NULL); + + //zconfdebug = 1; + zconfparse(); + if (zconfnerrs) + exit(1); + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) + printf("\n"); + else + sym->flags |= SYMBOL_CHECK_DONE; + } + + sym_change_count = 1; +} + +const char *zconf_tokenname(int token) +{ + switch (token) { + case T_MENU: return "menu"; + case T_ENDMENU: return "endmenu"; + case T_CHOICE: return "choice"; + case T_ENDCHOICE: return "endchoice"; + case T_IF: return "if"; + case T_ENDIF: return "endif"; + } + return ""; +} + +static bool zconf_endtoken(int token, int starttoken, int endtoken) +{ + if (token != endtoken) { + zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + if (current_menu->file != current_file) { + zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); + zconfprint("location of the '%s'", zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + return true; +} + +static void zconfprint(const char *err, ...) +{ + va_list ap; + + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconferror(const char *err) +{ + fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); +} + +void print_quoted_string(FILE *out, const char *str) +{ + const char *p; + int len; + + putc('"', out); + while ((p = strchr(str, '"'))) { + len = p - str; + if (len) + fprintf(out, "%.*s", len, str); + fputs("\\\"", out); + str = p + 1; + } + fputs(str, out); + putc('"', out); +} + +void print_symbol(FILE *out, struct menu *menu) +{ + struct symbol *sym = menu->sym; + struct property *prop; + + if (sym_is_choice(sym)) + fprintf(out, "choice\n"); + else + fprintf(out, "config %s\n", sym->name); + switch (sym->type) { + case S_BOOLEAN: + fputs(" boolean\n", out); + break; + case S_TRISTATE: + fputs(" tristate\n", out); + break; + case S_STRING: + fputs(" string\n", out); + break; + case S_INT: + fputs(" integer\n", out); + break; + case S_HEX: + fputs(" hex\n", out); + break; + default: + fputs(" ???\n", out); + break; + } + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + switch (prop->type) { + case P_PROMPT: + fputs(" prompt ", out); + print_quoted_string(out, prop->text); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_DEFAULT: + fputs( " default ", out); + expr_fprint(prop->expr, out); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_CHOICE: + fputs(" #choice value\n", out); + break; + default: + fprintf(out, " unknown prop %d!\n", prop->type); + break; + } + } + if (sym->help) { + int len = strlen(sym->help); + while (sym->help[--len] == '\n') + sym->help[len] = 0; + fprintf(out, " help\n%s\n", sym->help); + } + fputc('\n', out); +} + +void zconfdump(FILE *out) +{ + struct property *prop; + struct symbol *sym; + struct menu *menu; + + menu = rootmenu.list; + while (menu) { + if ((sym = menu->sym)) + print_symbol(out, menu); + else if ((prop = menu->prompt)) { + switch (prop->type) { + case P_COMMENT: + fputs("\ncomment ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + case P_MENU: + fputs("\nmenu ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + default: + ; + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" depends ", out); + expr_fprint(prop->visible.expr, out); + fputc('\n', out); + } + fputs("\n", out); + } + + if (menu->list) + menu = menu->list; + else if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->prompt && menu->prompt->type == P_MENU) + fputs("\nendmenu\n", out); + if (menu->next) { + menu = menu->next; + break; + } + } + } +} + +#include "lex.zconf.c" +#include "util.c" +#include "confdata.c" +#include "expr.c" +#include "symbol.c" +#include "menu.c" + + diff --git a/circuitpython/lib/axtls/config/scripts/config/zconf.tab.h_shipped b/circuitpython/lib/axtls/config/scripts/config/zconf.tab.h_shipped new file mode 100644 index 0000000..3b191ef --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/zconf.tab.h_shipped @@ -0,0 +1,125 @@ +/* A Bison parser, made from zconf.y, by GNU bison 1.75. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef BISON_ZCONF_TAB_H +# define BISON_ZCONF_TAB_H + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_MAINMENU = 258, + T_MENU = 259, + T_ENDMENU = 260, + T_SOURCE = 261, + T_CHOICE = 262, + T_ENDCHOICE = 263, + T_COMMENT = 264, + T_CONFIG = 265, + T_HELP = 266, + T_HELPTEXT = 267, + T_IF = 268, + T_ENDIF = 269, + T_DEPENDS = 270, + T_REQUIRES = 271, + T_OPTIONAL = 272, + T_PROMPT = 273, + T_DEFAULT = 274, + T_TRISTATE = 275, + T_BOOLEAN = 276, + T_INT = 277, + T_HEX = 278, + T_WORD = 279, + T_STRING = 280, + T_UNEQUAL = 281, + T_EOF = 282, + T_EOL = 283, + T_CLOSE_PAREN = 284, + T_OPEN_PAREN = 285, + T_ON = 286, + T_OR = 287, + T_AND = 288, + T_EQUAL = 289, + T_NOT = 290 + }; +#endif +#define T_MAINMENU 258 +#define T_MENU 259 +#define T_ENDMENU 260 +#define T_SOURCE 261 +#define T_CHOICE 262 +#define T_ENDCHOICE 263 +#define T_COMMENT 264 +#define T_CONFIG 265 +#define T_HELP 266 +#define T_HELPTEXT 267 +#define T_IF 268 +#define T_ENDIF 269 +#define T_DEPENDS 270 +#define T_REQUIRES 271 +#define T_OPTIONAL 272 +#define T_PROMPT 273 +#define T_DEFAULT 274 +#define T_TRISTATE 275 +#define T_BOOLEAN 276 +#define T_INT 277 +#define T_HEX 278 +#define T_WORD 279 +#define T_STRING 280 +#define T_UNEQUAL 281 +#define T_EOF 282 +#define T_EOL 283 +#define T_CLOSE_PAREN 284 +#define T_OPEN_PAREN 285 +#define T_ON 286 +#define T_OR 287 +#define T_AND 288 +#define T_EQUAL 289 +#define T_NOT 290 + + + + +#ifndef YYSTYPE +#line 33 "zconf.y" +typedef union { + int token; + char *string; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; +} yystype; +/* Line 1281 of /usr/share/bison/yacc.c. */ +#line 118 "zconf.tab.h" +# define YYSTYPE yystype +#endif + +extern YYSTYPE zconflval; + + +#endif /* not BISON_ZCONF_TAB_H */ + diff --git a/circuitpython/lib/axtls/config/scripts/config/zconf.y b/circuitpython/lib/axtls/config/scripts/config/zconf.y new file mode 100644 index 0000000..cf45da0 --- /dev/null +++ b/circuitpython/lib/axtls/config/scripts/config/zconf.y @@ -0,0 +1,690 @@ +%{ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include + +#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) + +#define PRINTD 0x0001 +#define DEBUG_PARSE 0x0002 + +int cdebug = PRINTD; + +extern int zconflex(void); +static void zconfprint(const char *err, ...); +static void zconferror(const char *err); +static bool zconf_endtoken(int token, int starttoken, int endtoken); + +struct symbol *symbol_hash[257]; + +static struct menu *current_menu, *current_entry; + +#define YYERROR_VERBOSE +%} +%expect 40 + +%union +{ + int token; + char *string; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; +} + +%token T_MAINMENU +%token T_MENU +%token T_ENDMENU +%token T_SOURCE +%token T_CHOICE +%token T_ENDCHOICE +%token T_COMMENT +%token T_CONFIG +%token T_MENUCONFIG +%token T_HELP +%token T_HELPTEXT +%token T_IF +%token T_ENDIF +%token T_DEPENDS +%token T_REQUIRES +%token T_OPTIONAL +%token T_PROMPT +%token T_DEFAULT +%token T_TRISTATE +%token T_DEF_TRISTATE +%token T_BOOLEAN +%token T_DEF_BOOLEAN +%token T_STRING +%token T_INT +%token T_HEX +%token T_WORD +%token T_WORD_QUOTE +%token T_UNEQUAL +%token T_EOF +%token T_EOL +%token T_CLOSE_PAREN +%token T_OPEN_PAREN +%token T_ON +%token T_SELECT +%token T_RANGE + +%left T_OR +%left T_AND +%left T_EQUAL T_UNEQUAL +%nonassoc T_NOT + +%type prompt +%type source +%type symbol +%type expr +%type if_expr +%type end + +%{ +#define LKC_DIRECT_LINK +#include "lkc.h" +%} +%% +input: /* empty */ + | input block +; + +block: common_block + | choice_stmt + | menu_stmt + | T_MAINMENU prompt nl_or_eof + | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); } + | T_ENDIF { zconfprint("unexpected 'endif' statement"); } + | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); } + | error nl_or_eof { zconfprint("syntax error"); yyerrok; } +; + +common_block: + if_stmt + | comment_stmt + | config_stmt + | menuconfig_stmt + | source_stmt + | nl_or_eof +; + + +/* config/menuconfig entry */ + +config_entry_start: T_CONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +config_stmt: config_entry_start config_option_list +{ + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +menuconfig_stmt: menuconfig_entry_start config_option_list +{ + if (current_entry->prompt) + current_entry->prompt->type = P_MENU; + else + zconfprint("warning: menuconfig statement without prompt"); + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +config_option_list: + /* empty */ + | config_option_list config_option + | config_option_list depends + | config_option_list help + | config_option_list T_EOL +; + +config_option: T_TRISTATE prompt_stmt_opt T_EOL +{ + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_DEF_TRISTATE expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_BOOLEAN prompt_stmt_opt T_EOL +{ + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_DEF_BOOLEAN expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_INT prompt_stmt_opt T_EOL +{ + menu_set_type(S_INT); + printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_HEX prompt_stmt_opt T_EOL +{ + menu_set_type(S_HEX); + printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_STRING prompt_stmt_opt T_EOL +{ + menu_set_type(S_STRING); + printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_DEFAULT expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_SELECT T_WORD if_expr T_EOL +{ + menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_RANGE symbol symbol if_expr T_EOL +{ + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); + printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); +}; + +/* choice entry */ + +choice: T_CHOICE T_EOL +{ + struct symbol *sym = sym_lookup(NULL, 0); + sym->flags |= SYMBOL_CHOICE; + menu_add_entry(sym); + menu_add_expr(P_CHOICE, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); +}; + +choice_entry: choice choice_option_list +{ + menu_end_entry(); + menu_add_menu(); +}; + +choice_end: end +{ + if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); + } +}; + +choice_stmt: + choice_entry choice_block choice_end + | choice_entry choice_block +{ + printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +}; + +choice_option_list: + /* empty */ + | choice_option_list choice_option + | choice_option_list depends + | choice_option_list help + | choice_option_list T_EOL +; + +choice_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_TRISTATE prompt_stmt_opt T_EOL +{ + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_BOOLEAN prompt_stmt_opt T_EOL +{ + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_OPTIONAL T_EOL +{ + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_DEFAULT T_WORD if_expr T_EOL +{ + menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); +}; + +choice_block: + /* empty */ + | choice_block common_block +; + +/* if entry */ + +if: T_IF expr T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); + menu_add_entry(NULL); + menu_add_dep($2); + menu_end_entry(); + menu_add_menu(); +}; + +if_end: end +{ + if (zconf_endtoken($1, T_IF, T_ENDIF)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); + } +}; + +if_stmt: + if if_block if_end + | if if_block +{ + printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +}; + +if_block: + /* empty */ + | if_block common_block + | if_block menu_stmt + | if_block choice_stmt +; + +/* menu entry */ + +menu: T_MENU prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prop(P_MENU, $2, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); +}; + +menu_entry: menu depends_list +{ + menu_end_entry(); + menu_add_menu(); +}; + +menu_end: end +{ + if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); + } +}; + +menu_stmt: + menu_entry menu_block menu_end + | menu_entry menu_block +{ + printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +}; + +menu_block: + /* empty */ + | menu_block common_block + | menu_block menu_stmt + | menu_block choice_stmt + | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; } +; + +source: T_SOURCE prompt T_EOL +{ + $$ = $2; + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +source_stmt: source +{ + zconf_nextfile($1); +}; + +/* comment entry */ + +comment: T_COMMENT prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prop(P_COMMENT, $2, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); +}; + +comment_stmt: comment depends_list +{ + menu_end_entry(); +}; + +/* help option */ + +help_start: T_HELP T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +}; + +help: help_start T_HELPTEXT +{ + current_entry->sym->help = $2; +}; + +/* depends option */ + +depends_list: /* empty */ + | depends_list depends + | depends_list T_EOL +; + +depends: T_DEPENDS T_ON expr T_EOL +{ + menu_add_dep($3); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +} + | T_DEPENDS expr T_EOL +{ + menu_add_dep($2); + printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); +} + | T_REQUIRES expr T_EOL +{ + menu_add_dep($2); + printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); +}; + +/* prompt statement */ + +prompt_stmt_opt: + /* empty */ + | prompt if_expr +{ + menu_add_prop(P_PROMPT, $1, NULL, $2); +}; + +prompt: T_WORD + | T_WORD_QUOTE +; + +end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; } + | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; } + | T_ENDIF nl_or_eof { $$ = T_ENDIF; } +; + +nl_or_eof: + T_EOL | T_EOF; + +if_expr: /* empty */ { $$ = NULL; } + | T_IF expr { $$ = $2; } +; + +expr: symbol { $$ = expr_alloc_symbol($1); } + | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } + | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } + | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } + | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } + | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } + | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } +; + +symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } + | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); } +; + +%% + +void conf_parse(const char *name) +{ + struct symbol *sym; + int i; + + zconf_initscan(name); + + sym_init(); + menu_init(); + modules_sym = sym_lookup("MODULES", 0); + rootmenu.prompt = menu_add_prop(P_MENU, "axTLS Configuration", NULL, NULL); + + //zconfdebug = 1; + zconfparse(); + if (zconfnerrs) + exit(1); + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) + printf("\n"); + else + sym->flags |= SYMBOL_CHECK_DONE; + } + + sym_change_count = 1; +} + +const char *zconf_tokenname(int token) +{ + switch (token) { + case T_MENU: return "menu"; + case T_ENDMENU: return "endmenu"; + case T_CHOICE: return "choice"; + case T_ENDCHOICE: return "endchoice"; + case T_IF: return "if"; + case T_ENDIF: return "endif"; + } + return ""; +} + +static bool zconf_endtoken(int token, int starttoken, int endtoken) +{ + if (token != endtoken) { + zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + if (current_menu->file != current_file) { + zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); + zconfprint("location of the '%s'", zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + return true; +} + +static void zconfprint(const char *err, ...) +{ + va_list ap; + + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconferror(const char *err) +{ + fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); +} + +void print_quoted_string(FILE *out, const char *str) +{ + const char *p; + int len; + + putc('"', out); + while ((p = strchr(str, '"'))) { + len = p - str; + if (len) + fprintf(out, "%.*s", len, str); + fputs("\\\"", out); + str = p + 1; + } + fputs(str, out); + putc('"', out); +} + +void print_symbol(FILE *out, struct menu *menu) +{ + struct symbol *sym = menu->sym; + struct property *prop; + + if (sym_is_choice(sym)) + fprintf(out, "choice\n"); + else + fprintf(out, "config %s\n", sym->name); + switch (sym->type) { + case S_BOOLEAN: + fputs(" boolean\n", out); + break; + case S_TRISTATE: + fputs(" tristate\n", out); + break; + case S_STRING: + fputs(" string\n", out); + break; + case S_INT: + fputs(" integer\n", out); + break; + case S_HEX: + fputs(" hex\n", out); + break; + default: + fputs(" ???\n", out); + break; + } + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + switch (prop->type) { + case P_PROMPT: + fputs(" prompt ", out); + print_quoted_string(out, prop->text); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_DEFAULT: + fputs( " default ", out); + expr_fprint(prop->expr, out); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_CHOICE: + fputs(" #choice value\n", out); + break; + default: + fprintf(out, " unknown prop %d!\n", prop->type); + break; + } + } + if (sym->help) { + int len = strlen(sym->help); + while (sym->help[--len] == '\n') + sym->help[len] = 0; + fprintf(out, " help\n%s\n", sym->help); + } + fputc('\n', out); +} + +void zconfdump(FILE *out) +{ + struct property *prop; + struct symbol *sym; + struct menu *menu; + + menu = rootmenu.list; + while (menu) { + if ((sym = menu->sym)) + print_symbol(out, menu); + else if ((prop = menu->prompt)) { + switch (prop->type) { + case P_COMMENT: + fputs("\ncomment ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + case P_MENU: + fputs("\nmenu ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + default: + ; + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" depends ", out); + expr_fprint(prop->visible.expr, out); + fputc('\n', out); + } + fputs("\n", out); + } + + if (menu->list) + menu = menu->list; + else if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->prompt && menu->prompt->type == P_MENU) + fputs("\nendmenu\n", out); + if (menu->next) { + menu = menu->next; + break; + } + } + } +} + +#include "lex.zconf.c" +#include "util.c" +#include "confdata.c" +#include "expr.c" +#include "symbol.c" +#include "menu.c" diff --git a/circuitpython/lib/axtls/config/upyconfig b/circuitpython/lib/axtls/config/upyconfig new file mode 100644 index 0000000..f3a26f3 --- /dev/null +++ b/circuitpython/lib/axtls/config/upyconfig @@ -0,0 +1,117 @@ +# +# Automatically generated make config: don't edit +# +HAVE_DOT_CONFIG=y +CONFIG_PLATFORM_LINUX=y +# CONFIG_PLATFORM_CYGWIN is not set +# CONFIG_PLATFORM_WIN32 is not set + +# +# General Configuration +# +PREFIX="/usr/local" +# CONFIG_DEBUG is not set +# CONFIG_STRIP_UNWANTED_SECTIONS is not set +# CONFIG_VISUAL_STUDIO_7_0 is not set +# CONFIG_VISUAL_STUDIO_8_0 is not set +# CONFIG_VISUAL_STUDIO_10_0 is not set +CONFIG_VISUAL_STUDIO_7_0_BASE="" +CONFIG_VISUAL_STUDIO_8_0_BASE="" +CONFIG_VISUAL_STUDIO_10_0_BASE="" +CONFIG_EXTRA_CFLAGS_OPTIONS="" +CONFIG_EXTRA_LDFLAGS_OPTIONS="" + +# +# SSL Library +# +# CONFIG_SSL_SERVER_ONLY is not set +# CONFIG_SSL_CERT_VERIFICATION is not set +# CONFIG_SSL_FULL_MODE is not set +CONFIG_SSL_SKELETON_MODE=y +CONFIG_SSL_ENABLE_SERVER=y +CONFIG_SSL_ENABLE_CLIENT=y +# CONFIG_SSL_DIAGNOSTICS is not set +CONFIG_SSL_PROT_LOW=y +# CONFIG_SSL_PROT_MEDIUM is not set +# CONFIG_SSL_PROT_HIGH is not set +CONFIG_SSL_AES=y +CONFIG_SSL_USE_DEFAULT_KEY=y +CONFIG_SSL_PRIVATE_KEY_LOCATION="" +CONFIG_SSL_PRIVATE_KEY_PASSWORD="" +CONFIG_SSL_X509_CERT_LOCATION="" +# CONFIG_SSL_GENERATE_X509_CERT is not set +CONFIG_SSL_X509_COMMON_NAME="" +CONFIG_SSL_X509_ORGANIZATION_NAME="" +CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME="" +# CONFIG_SSL_ENABLE_V23_HANDSHAKE is not set +# CONFIG_SSL_HAS_PEM is not set +# CONFIG_SSL_USE_PKCS12 is not set +CONFIG_SSL_EXPIRY_TIME=0 +CONFIG_X509_MAX_CA_CERTS=0 +CONFIG_SSL_MAX_CERTS=3 +# CONFIG_SSL_CTX_MUTEXING is not set +# CONFIG_USE_DEV_URANDOM is not set +# CONFIG_WIN32_USE_CRYPTO_LIB is not set +# CONFIG_OPENSSL_COMPATIBLE is not set +# CONFIG_PERFORMANCE_TESTING is not set +# CONFIG_SSL_TEST is not set +# CONFIG_AXTLSWRAP is not set +# CONFIG_AXHTTPD is not set +# CONFIG_HTTP_STATIC_BUILD is not set +CONFIG_HTTP_PORT=0 +CONFIG_HTTP_HTTPS_PORT=0 +CONFIG_HTTP_SESSION_CACHE_SIZE=0 +CONFIG_HTTP_WEBROOT="" +CONFIG_HTTP_TIMEOUT=0 +# CONFIG_HTTP_HAS_CGI is not set +CONFIG_HTTP_CGI_EXTENSIONS="" +# CONFIG_HTTP_ENABLE_LUA is not set +CONFIG_HTTP_LUA_PREFIX="" +# CONFIG_HTTP_BUILD_LUA is not set +CONFIG_HTTP_CGI_LAUNCHER="" +# CONFIG_HTTP_DIRECTORIES is not set +# CONFIG_HTTP_HAS_AUTHORIZATION is not set +# CONFIG_HTTP_HAS_IPV6 is not set +# CONFIG_HTTP_ENABLE_DIFFERENT_USER is not set +CONFIG_HTTP_USER="" +# CONFIG_HTTP_VERBOSE is not set +# CONFIG_HTTP_IS_DAEMON is not set + +# +# Language Bindings +# +# CONFIG_BINDINGS is not set +# CONFIG_CSHARP_BINDINGS is not set +# CONFIG_VBNET_BINDINGS is not set +CONFIG_DOT_NET_FRAMEWORK_BASE="" +# CONFIG_JAVA_BINDINGS is not set +CONFIG_JAVA_HOME="" +# CONFIG_PERL_BINDINGS is not set +CONFIG_PERL_CORE="" +CONFIG_PERL_LIB="" +# CONFIG_LUA_BINDINGS is not set +CONFIG_LUA_CORE="" + +# +# Samples +# +# CONFIG_SAMPLES is not set +# CONFIG_C_SAMPLES is not set +# CONFIG_CSHARP_SAMPLES is not set +# CONFIG_VBNET_SAMPLES is not set +# CONFIG_JAVA_SAMPLES is not set +# CONFIG_PERL_SAMPLES is not set +# CONFIG_LUA_SAMPLES is not set +# CONFIG_BIGINT_CLASSICAL is not set +# CONFIG_BIGINT_MONTGOMERY is not set +# CONFIG_BIGINT_BARRETT is not set +# CONFIG_BIGINT_CRT is not set +# CONFIG_BIGINT_KARATSUBA is not set +MUL_KARATSUBA_THRESH=0 +SQU_KARATSUBA_THRESH=0 +# CONFIG_BIGINT_SLIDING_WINDOW is not set +# CONFIG_BIGINT_SQUARE is not set +# CONFIG_BIGINT_CHECK_ON is not set +# CONFIG_INTEGER_32BIT is not set +# CONFIG_INTEGER_16BIT is not set +# CONFIG_INTEGER_8BIT is not set diff --git a/circuitpython/lib/axtls/config/upyconfig.client b/circuitpython/lib/axtls/config/upyconfig.client new file mode 100644 index 0000000..6dffa19 --- /dev/null +++ b/circuitpython/lib/axtls/config/upyconfig.client @@ -0,0 +1,116 @@ +# +# Automatically generated make config: don't edit +# +HAVE_DOT_CONFIG=y +CONFIG_PLATFORM_LINUX=y +# CONFIG_PLATFORM_CYGWIN is not set +# CONFIG_PLATFORM_WIN32 is not set + +# +# General Configuration +# +PREFIX="/usr/local" +# CONFIG_DEBUG is not set +# CONFIG_STRIP_UNWANTED_SECTIONS is not set +# CONFIG_VISUAL_STUDIO_7_0 is not set +# CONFIG_VISUAL_STUDIO_8_0 is not set +# CONFIG_VISUAL_STUDIO_10_0 is not set +CONFIG_VISUAL_STUDIO_7_0_BASE="" +CONFIG_VISUAL_STUDIO_8_0_BASE="" +CONFIG_VISUAL_STUDIO_10_0_BASE="" +CONFIG_EXTRA_CFLAGS_OPTIONS="" +CONFIG_EXTRA_LDFLAGS_OPTIONS="" + +# +# SSL Library +# +# CONFIG_SSL_SERVER_ONLY is not set +# CONFIG_SSL_CERT_VERIFICATION is not set +# CONFIG_SSL_FULL_MODE is not set +CONFIG_SSL_SKELETON_MODE=y +CONFIG_SSL_ENABLE_CLIENT=y +# CONFIG_SSL_DIAGNOSTICS is not set +CONFIG_SSL_PROT_LOW=y +# CONFIG_SSL_PROT_MEDIUM is not set +# CONFIG_SSL_PROT_HIGH is not set +CONFIG_SSL_AES=y +# CONFIG_SSL_USE_DEFAULT_KEY is not set +CONFIG_SSL_PRIVATE_KEY_LOCATION="" +CONFIG_SSL_PRIVATE_KEY_PASSWORD="" +CONFIG_SSL_X509_CERT_LOCATION="" +# CONFIG_SSL_GENERATE_X509_CERT is not set +CONFIG_SSL_X509_COMMON_NAME="" +CONFIG_SSL_X509_ORGANIZATION_NAME="" +CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME="" +# CONFIG_SSL_ENABLE_V23_HANDSHAKE is not set +# CONFIG_SSL_HAS_PEM is not set +# CONFIG_SSL_USE_PKCS12 is not set +CONFIG_SSL_EXPIRY_TIME=0 +CONFIG_X509_MAX_CA_CERTS=0 +CONFIG_SSL_MAX_CERTS=3 +# CONFIG_SSL_CTX_MUTEXING is not set +# CONFIG_USE_DEV_URANDOM is not set +# CONFIG_WIN32_USE_CRYPTO_LIB is not set +# CONFIG_OPENSSL_COMPATIBLE is not set +# CONFIG_PERFORMANCE_TESTING is not set +# CONFIG_SSL_TEST is not set +# CONFIG_AXTLSWRAP is not set +# CONFIG_AXHTTPD is not set +# CONFIG_HTTP_STATIC_BUILD is not set +CONFIG_HTTP_PORT=0 +CONFIG_HTTP_HTTPS_PORT=0 +CONFIG_HTTP_SESSION_CACHE_SIZE=0 +CONFIG_HTTP_WEBROOT="" +CONFIG_HTTP_TIMEOUT=0 +# CONFIG_HTTP_HAS_CGI is not set +CONFIG_HTTP_CGI_EXTENSIONS="" +# CONFIG_HTTP_ENABLE_LUA is not set +CONFIG_HTTP_LUA_PREFIX="" +# CONFIG_HTTP_BUILD_LUA is not set +CONFIG_HTTP_CGI_LAUNCHER="" +# CONFIG_HTTP_DIRECTORIES is not set +# CONFIG_HTTP_HAS_AUTHORIZATION is not set +# CONFIG_HTTP_HAS_IPV6 is not set +# CONFIG_HTTP_ENABLE_DIFFERENT_USER is not set +CONFIG_HTTP_USER="" +# CONFIG_HTTP_VERBOSE is not set +# CONFIG_HTTP_IS_DAEMON is not set + +# +# Language Bindings +# +# CONFIG_BINDINGS is not set +# CONFIG_CSHARP_BINDINGS is not set +# CONFIG_VBNET_BINDINGS is not set +CONFIG_DOT_NET_FRAMEWORK_BASE="" +# CONFIG_JAVA_BINDINGS is not set +CONFIG_JAVA_HOME="" +# CONFIG_PERL_BINDINGS is not set +CONFIG_PERL_CORE="" +CONFIG_PERL_LIB="" +# CONFIG_LUA_BINDINGS is not set +CONFIG_LUA_CORE="" + +# +# Samples +# +# CONFIG_SAMPLES is not set +# CONFIG_C_SAMPLES is not set +# CONFIG_CSHARP_SAMPLES is not set +# CONFIG_VBNET_SAMPLES is not set +# CONFIG_JAVA_SAMPLES is not set +# CONFIG_PERL_SAMPLES is not set +# CONFIG_LUA_SAMPLES is not set +# CONFIG_BIGINT_CLASSICAL is not set +# CONFIG_BIGINT_MONTGOMERY is not set +# CONFIG_BIGINT_BARRETT is not set +# CONFIG_BIGINT_CRT is not set +# CONFIG_BIGINT_KARATSUBA is not set +MUL_KARATSUBA_THRESH=0 +SQU_KARATSUBA_THRESH=0 +# CONFIG_BIGINT_SLIDING_WINDOW is not set +# CONFIG_BIGINT_SQUARE is not set +# CONFIG_BIGINT_CHECK_ON is not set +# CONFIG_INTEGER_32BIT is not set +# CONFIG_INTEGER_16BIT is not set +# CONFIG_INTEGER_8BIT is not set diff --git a/circuitpython/lib/axtls/config/win32config b/circuitpython/lib/axtls/config/win32config new file mode 100644 index 0000000..6c8d607 --- /dev/null +++ b/circuitpython/lib/axtls/config/win32config @@ -0,0 +1,119 @@ +# +# Automatically generated make config: don't edit +# +HAVE_DOT_CONFIG=y +# CONFIG_PLATFORM_LINUX is not set +# CONFIG_PLATFORM_CYGWIN is not set +# CONFIG_PLATFORM_SOLARIS is not set +CONFIG_PLATFORM_WIN32=y + +# +# General Configuration +# +PREFIX="" +# CONFIG_DEBUG is not set +# CONFIG_STRIP_UNWANTED_SECTIONS is not set + +# +# Microsoft Compiler Options +# +# CONFIG_VISUAL_STUDIO_7_0 is not set +CONFIG_VISUAL_STUDIO_8_0=y +CONFIG_VISUAL_STUDIO_7_0_BASE="" +CONFIG_VISUAL_STUDIO_8_0_BASE="c:\\Program Files\\Microsoft Visual Studio 8" +CONFIG_EXTRA_CFLAGS_OPTIONS="" +CONFIG_EXTRA_LDFLAGS_OPTIONS="" + +# +# SSL Library +# +# CONFIG_SSL_SERVER_ONLY is not set +# CONFIG_SSL_CERT_VERIFICATION is not set +# CONFIG_SSL_ENABLE_CLIENT is not set +CONFIG_SSL_FULL_MODE=y +# CONFIG_SSL_SKELETON_MODE is not set +# CONFIG_SSL_PROT_LOW is not set +CONFIG_SSL_PROT_MEDIUM=y +# CONFIG_SSL_PROT_HIGH is not set +CONFIG_SSL_USE_DEFAULT_KEY=y +CONFIG_SSL_PRIVATE_KEY_LOCATION="" +CONFIG_SSL_PRIVATE_KEY_PASSWORD="" +CONFIG_SSL_X509_CERT_LOCATION="" +CONFIG_SSL_GENERATE_X509_CERT=y +CONFIG_SSL_X509_COMMON_NAME="" +CONFIG_SSL_X509_ORGANIZATION_NAME="" +CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME="" +CONFIG_SSL_ENABLE_V23_HANDSHAKE=y +CONFIG_SSL_HAS_PEM=y +CONFIG_SSL_USE_PKCS12=y +CONFIG_SSL_EXPIRY_TIME=24 +CONFIG_X509_MAX_CA_CERTS=4 +CONFIG_SSL_MAX_CERTS=2 +# CONFIG_SSL_CTX_MUTEXING is not set +# CONFIG_USE_DEV_URANDOM is not set +CONFIG_WIN32_USE_CRYPTO_LIB=y +# CONFIG_OPENSSL_COMPATIBLE is not set +# CONFIG_PERFORMANCE_TESTING is not set +# CONFIG_SSL_TEST is not set +CONFIG_AXHTTPD=y + +# +# Axhttpd Configuration +# +# CONFIG_HTTP_STATIC_BUILD is not set +CONFIG_HTTP_PORT=80 +CONFIG_HTTP_HTTPS_PORT=443 +CONFIG_HTTP_SESSION_CACHE_SIZE=5 +CONFIG_HTTP_WEBROOT="www" +CONFIG_HTTP_TIMEOUT=300 +# CONFIG_HTTP_HAS_CGI is not set +CONFIG_HTTP_CGI_EXTENSIONS="" +# CONFIG_HTTP_ENABLE_LUA is not set +CONFIG_HTTP_LUA_PREFIX="" +CONFIG_HTTP_LUA_CGI_LAUNCHER="" +# CONFIG_HTTP_BUILD_LUA is not set +CONFIG_HTTP_DIRECTORIES=y +CONFIG_HTTP_HAS_AUTHORIZATION=y +# CONFIG_HTTP_HAS_IPV6 is not set +CONFIG_HTTP_VERBOSE=y +# CONFIG_HTTP_IS_DAEMON is not set + +# +# Language Bindings +# +# CONFIG_BINDINGS is not set +# CONFIG_CSHARP_BINDINGS is not set +# CONFIG_VBNET_BINDINGS is not set +CONFIG_DOT_NET_FRAMEWORK_BASE="" +# CONFIG_JAVA_BINDINGS is not set +CONFIG_JAVA_HOME="" +# CONFIG_PERL_BINDINGS is not set +CONFIG_PERL_CORE="" +CONFIG_PERL_LIB="" +# CONFIG_LUA_BINDINGS is not set +CONFIG_LUA_CORE="" + +# +# Samples +# +CONFIG_SAMPLES=y +CONFIG_C_SAMPLES=y +# CONFIG_CSHARP_SAMPLES is not set +# CONFIG_VBNET_SAMPLES is not set +# CONFIG_JAVA_SAMPLES is not set +# CONFIG_PERL_SAMPLES is not set +# CONFIG_LUA_SAMPLES is not set + +# +# BigInt Options +# +# CONFIG_BIGINT_CLASSICAL is not set +# CONFIG_BIGINT_MONTGOMERY is not set +CONFIG_BIGINT_BARRETT=y +CONFIG_BIGINT_CRT=y +# CONFIG_BIGINT_KARATSUBA is not set +MUL_KARATSUBA_THRESH=0 +SQU_KARATSUBA_THRESH=0 +CONFIG_BIGINT_SLIDING_WINDOW=y +CONFIG_BIGINT_SQUARE=y +# CONFIG_BIGINT_CHECK_ON is not set diff --git a/circuitpython/lib/axtls/crypto/Makefile b/circuitpython/lib/axtls/crypto/Makefile new file mode 100644 index 0000000..126ae78 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 ../config/.config +include ../config/makefile.conf + +AXTLS_HOME=.. + +OBJ=\ + aes.o \ + bigint.o \ + crypto_misc.o \ + hmac.o \ + md5.o \ + rc4.o \ + rsa.o \ + sha1.o \ + sha256.o \ + sha384.o \ + sha512.o + +include ../config/makefile.post + +all: $(OBJ) + diff --git a/circuitpython/lib/axtls/crypto/aes.c b/circuitpython/lib/axtls/crypto/aes.c new file mode 100644 index 0000000..c260a2a --- /dev/null +++ b/circuitpython/lib/axtls/crypto/aes.c @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * AES implementation - this is a small code version. There are much faster + * versions around but they are much larger in size (i.e. they use large + * submix tables). + */ + +#include +#include "os_port.h" +#include "crypto.h" + +#define rot1(x) (((x) << 24) | ((x) >> 8)) +#define rot2(x) (((x) << 16) | ((x) >> 16)) +#define rot3(x) (((x) << 8) | ((x) >> 24)) + +/* + * This cute trick does 4 'mul by two' at once. Stolen from + * Dr B. R. Gladman but I'm sure the u-(u>>7) is + * a standard graphics trick + * The key to this is that we need to xor with 0x1b if the top bit is set. + * a 1xxx xxxx 0xxx 0xxx First we mask the 7bit, + * b 1000 0000 0000 0000 then we shift right by 7 putting the 7bit in 0bit, + * c 0000 0001 0000 0000 we then subtract (c) from (b) + * d 0111 1111 0000 0000 and now we and with our mask + * e 0001 1011 0000 0000 + */ +#define mt 0x80808080 +#define ml 0x7f7f7f7f +#define mh 0xfefefefe +#define mm 0x1b1b1b1b +#define mul2(x,t) ((t)=((x)&mt), \ + ((((x)+(x))&mh)^(((t)-((t)>>7))&mm))) + +#define inv_mix_col(x,f2,f4,f8,f9) (\ + (f2)=mul2(x,f2), \ + (f4)=mul2(f2,f4), \ + (f8)=mul2(f4,f8), \ + (f9)=(x)^(f8), \ + (f8)=((f2)^(f4)^(f8)), \ + (f2)^=(f9), \ + (f4)^=(f9), \ + (f8)^=rot3(f2), \ + (f8)^=rot2(f4), \ + (f8)^rot1(f9)) + +/* + * AES S-box + */ +static const uint8_t aes_sbox[256] = +{ + 0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5, + 0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76, + 0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0, + 0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0, + 0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC, + 0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15, + 0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A, + 0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75, + 0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0, + 0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84, + 0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B, + 0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF, + 0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85, + 0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8, + 0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5, + 0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2, + 0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17, + 0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73, + 0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88, + 0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB, + 0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C, + 0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79, + 0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9, + 0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08, + 0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6, + 0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A, + 0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E, + 0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E, + 0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94, + 0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF, + 0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68, + 0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16, +}; + +/* + * AES is-box + */ +static const uint8_t aes_isbox[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, + 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2, + 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, + 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16, + 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, + 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda, + 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, + 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a, + 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, + 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02, + 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, + 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea, + 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, + 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85, + 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, + 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89, + 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, + 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20, + 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, + 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31, + 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, + 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d, + 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, + 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 +}; + +static const unsigned char Rcon[30]= +{ + 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, + 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f, + 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4, + 0xb3,0x7d,0xfa,0xef,0xc5,0x91, +}; + +/* ----- static functions ----- */ + +/* Perform doubling in Galois Field GF(2^8) using the irreducible polynomial + x^8+x^4+x^3+x+1 */ +static unsigned char AES_xtime(uint32_t x) +{ + return (x&0x80) ? (x<<1)^0x1b : x<<1; +} + +/** + * Set up AES with the key/iv and cipher size. + */ +void AES_set_key(AES_CTX *ctx, const uint8_t *key, + const uint8_t *iv, AES_MODE mode) +{ + int i, ii; + uint32_t *W, tmp, tmp2; + const unsigned char *ip; + int words; + + switch (mode) + { + case AES_MODE_128: + i = 10; + words = 4; + break; + + case AES_MODE_256: + i = 14; + words = 8; + break; + + default: /* fail silently */ + return; + } + + ctx->rounds = i; + ctx->key_size = words; + W = ctx->ks; + for (i = 0; i < words; i+=2) + { + W[i+0]= ((uint32_t)key[ 0]<<24)| + ((uint32_t)key[ 1]<<16)| + ((uint32_t)key[ 2]<< 8)| + ((uint32_t)key[ 3] ); + W[i+1]= ((uint32_t)key[ 4]<<24)| + ((uint32_t)key[ 5]<<16)| + ((uint32_t)key[ 6]<< 8)| + ((uint32_t)key[ 7] ); + key += 8; + } + + ip = Rcon; + ii = 4 * (ctx->rounds+1); + for (i = words; i> 8)&0xff]<<16; + tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<24; + tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]; + tmp=tmp2^(((unsigned int)*ip)<<24); + ip++; + } + + if ((words == 8) && ((i % words) == 4)) + { + tmp2 =(uint32_t)aes_sbox[(tmp )&0xff] ; + tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<< 8; + tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<16; + tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]<<24; + tmp=tmp2; + } + + W[i]=W[i-words]^tmp; + } + + /* copy the iv across */ + if (iv) + { + memcpy(ctx->iv, iv, 16); + } +} + +/** + * Change a key for decryption. + */ +void AES_convert_key(AES_CTX *ctx) +{ + int i; + uint32_t *k,w,t1,t2,t3,t4; + + k = ctx->ks; + k += 4; + + for (i= ctx->rounds*4; i > 4; i--) + { + w= *k; + w = inv_mix_col(w,t1,t2,t3,t4); + *k++ =w; + } +} + +/** + * Encrypt a byte sequence (with a block size 16) using the AES cipher. + */ +void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length) +{ + int i; + uint32_t tin[4], tout[4], iv[4]; + + memcpy(iv, ctx->iv, AES_IV_SIZE); + for (i = 0; i < 4; i++) + tout[i] = ntohl(iv[i]); + + for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE) + { + uint32_t msg_32[4]; + uint32_t out_32[4]; + memcpy(msg_32, msg, AES_BLOCKSIZE); + msg += AES_BLOCKSIZE; + + for (i = 0; i < 4; i++) + tin[i] = ntohl(msg_32[i])^tout[i]; + + AES_encrypt(ctx, tin); + + for (i = 0; i < 4; i++) + { + tout[i] = tin[i]; + out_32[i] = htonl(tout[i]); + } + + memcpy(out, out_32, AES_BLOCKSIZE); + out += AES_BLOCKSIZE; + } + + for (i = 0; i < 4; i++) + iv[i] = htonl(tout[i]); + memcpy(ctx->iv, iv, AES_IV_SIZE); +} + +/** + * Decrypt a byte sequence (with a block size 16) using the AES cipher. + */ +void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length) +{ + int i; + uint32_t tin[4], xor[4], tout[4], data[4], iv[4]; + + memcpy(iv, ctx->iv, AES_IV_SIZE); + for (i = 0; i < 4; i++) + xor[i] = ntohl(iv[i]); + + for (length -= 16; length >= 0; length -= 16) + { + uint32_t msg_32[4]; + uint32_t out_32[4]; + memcpy(msg_32, msg, AES_BLOCKSIZE); + msg += AES_BLOCKSIZE; + + for (i = 0; i < 4; i++) + { + tin[i] = ntohl(msg_32[i]); + data[i] = tin[i]; + } + + AES_decrypt(ctx, data); + + for (i = 0; i < 4; i++) + { + tout[i] = data[i]^xor[i]; + xor[i] = tin[i]; + out_32[i] = htonl(tout[i]); + } + + memcpy(out, out_32, AES_BLOCKSIZE); + out += AES_BLOCKSIZE; + } + + for (i = 0; i < 4; i++) + iv[i] = htonl(xor[i]); + memcpy(ctx->iv, iv, AES_IV_SIZE); +} + +/** + * Encrypt a single block (16 bytes) of data + */ +void AES_encrypt(const AES_CTX *ctx, uint32_t *data) +{ + /* To make this code smaller, generate the sbox entries on the fly. + * This will have a really heavy effect upon performance. + */ + uint32_t tmp[4]; + uint32_t tmp1, old_a0, a0, a1, a2, a3, row; + int curr_rnd; + int rounds = ctx->rounds; + const uint32_t *k = ctx->ks; + + /* Pre-round key addition */ + for (row = 0; row < 4; row++) + data[row] ^= *(k++); + + /* Encrypt one block. */ + for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++) + { + /* Perform ByteSub and ShiftRow operations together */ + for (row = 0; row < 4; row++) + { + a0 = (uint32_t)aes_sbox[(data[row%4]>>24)&0xFF]; + a1 = (uint32_t)aes_sbox[(data[(row+1)%4]>>16)&0xFF]; + a2 = (uint32_t)aes_sbox[(data[(row+2)%4]>>8)&0xFF]; + a3 = (uint32_t)aes_sbox[(data[(row+3)%4])&0xFF]; + + /* Perform MixColumn iff not last round */ + if (curr_rnd < (rounds - 1)) + { + tmp1 = a0 ^ a1 ^ a2 ^ a3; + old_a0 = a0; + a0 ^= tmp1 ^ AES_xtime(a0 ^ a1); + a1 ^= tmp1 ^ AES_xtime(a1 ^ a2); + a2 ^= tmp1 ^ AES_xtime(a2 ^ a3); + a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0); + } + + tmp[row] = ((a0 << 24) | (a1 << 16) | (a2 << 8) | a3); + } + + /* KeyAddition - note that it is vital that this loop is separate from + the MixColumn operation, which must be atomic...*/ + for (row = 0; row < 4; row++) + data[row] = tmp[row] ^ *(k++); + } +} + +/** + * Decrypt a single block (16 bytes) of data + */ +void AES_decrypt(const AES_CTX *ctx, uint32_t *data) +{ + uint32_t tmp[4]; + uint32_t xt0,xt1,xt2,xt3,xt4,xt5,xt6; + uint32_t a0, a1, a2, a3, row; + int curr_rnd; + int rounds = ctx->rounds; + const uint32_t *k = ctx->ks + ((rounds+1)*4); + + /* pre-round key addition */ + for (row=4; row > 0;row--) + data[row-1] ^= *(--k); + + /* Decrypt one block */ + for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++) + { + /* Perform ByteSub and ShiftRow operations together */ + for (row = 4; row > 0; row--) + { + a0 = aes_isbox[(data[(row+3)%4]>>24)&0xFF]; + a1 = aes_isbox[(data[(row+2)%4]>>16)&0xFF]; + a2 = aes_isbox[(data[(row+1)%4]>>8)&0xFF]; + a3 = aes_isbox[(data[row%4])&0xFF]; + + /* Perform MixColumn iff not last round */ + if (curr_rnd<(rounds-1)) + { + /* The MDS cofefficients (0x09, 0x0B, 0x0D, 0x0E) + are quite large compared to encryption; this + operation slows decryption down noticeably. */ + xt0 = AES_xtime(a0^a1); + xt1 = AES_xtime(a1^a2); + xt2 = AES_xtime(a2^a3); + xt3 = AES_xtime(a3^a0); + xt4 = AES_xtime(xt0^xt1); + xt5 = AES_xtime(xt1^xt2); + xt6 = AES_xtime(xt4^xt5); + + xt0 ^= a1^a2^a3^xt4^xt6; + xt1 ^= a0^a2^a3^xt5^xt6; + xt2 ^= a0^a1^a3^xt4^xt6; + xt3 ^= a0^a1^a2^xt5^xt6; + tmp[row-1] = ((xt0<<24)|(xt1<<16)|(xt2<<8)|xt3); + } + else + tmp[row-1] = ((a0<<24)|(a1<<16)|(a2<<8)|a3); + } + + for (row = 4; row > 0; row--) + data[row-1] = tmp[row-1] ^ *(--k); + } +} diff --git a/circuitpython/lib/axtls/crypto/bigint.c b/circuitpython/lib/axtls/crypto/bigint.c new file mode 100644 index 0000000..9c16428 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/bigint.c @@ -0,0 +1,1516 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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 bigint_api Big Integer API + * @brief The bigint implementation as used by the axTLS project. + * + * The bigint library is for RSA encryption/decryption as well as signing. + * This code tries to minimise use of malloc/free by maintaining a small + * cache. A bigint context may maintain state by being made "permanent". + * It be be later released with a bi_depermanent() and bi_free() call. + * + * It supports the following reduction techniques: + * - Classical + * - Barrett + * - Montgomery + * + * It also implements the following: + * - Karatsuba multiplication + * - Squaring + * - Sliding window exponentiation + * - Chinese Remainder Theorem (implemented in rsa.c). + * + * All the algorithms used are pretty standard, and designed for different + * data bus sizes. Negative numbers are not dealt with at all, so a subtraction + * may need to be tested for negativity. + * + * This library steals some ideas from Jef Poskanzer + * + * and GMP . It gets most of its implementation + * detail from "The Handbook of Applied Cryptography" + * + * @{ + */ + +#include +#include +#include +#include +#include +#include "os_port.h" +#include "bigint.h" + +#define V1 v->comps[v->size-1] /**< v1 for division */ +#define V2 v->comps[v->size-2] /**< v2 for division */ +#define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */ +#define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */ + +static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i); +static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom); +static bigint *alloc(BI_CTX *ctx, int size); +static bigint *trim(bigint *bi); +static void more_comps(bigint *bi, int n); +#if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \ + defined(CONFIG_BIGINT_MONTGOMERY) +static bigint *comp_right_shift(bigint *biR, int num_shifts); +static bigint *comp_left_shift(bigint *biR, int num_shifts); +#endif + +#ifdef CONFIG_BIGINT_CHECK_ON +static void check(const bigint *bi); +#else +#define check(A) /**< disappears in normal production mode */ +#endif + + +/** + * @brief Start a new bigint context. + * @return A bigint context. + */ +BI_CTX *bi_initialize(void) +{ + /* calloc() sets everything to zero */ + BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX)); + + /* the radix */ + ctx->bi_radix = alloc(ctx, 2); + ctx->bi_radix->comps[0] = 0; + ctx->bi_radix->comps[1] = 1; + bi_permanent(ctx->bi_radix); + return ctx; +} + +/** + * @brief Close the bigint context and free any resources. + * + * Free up any used memory - a check is done if all objects were not + * properly freed. + * @param ctx [in] The bigint session context. + */ +void bi_terminate(BI_CTX *ctx) +{ + bi_depermanent(ctx->bi_radix); + bi_free(ctx, ctx->bi_radix); + + if (ctx->active_count != 0) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("bi_terminate: there were %d un-freed bigints\n", + ctx->active_count); +#endif + abort(); + } + + bi_clear_cache(ctx); + free(ctx); +} + +/** + *@brief Clear the memory cache. + */ +void bi_clear_cache(BI_CTX *ctx) +{ + bigint *p, *pn; + + if (ctx->free_list == NULL) + return; + + for (p = ctx->free_list; p != NULL; p = pn) + { + pn = p->next; + free(p->comps); + free(p); + } + + ctx->free_count = 0; + ctx->free_list = NULL; +} + +/** + * @brief Increment the number of references to this object. + * It does not do a full copy. + * @param bi [in] The bigint to copy. + * @return A reference to the same bigint. + */ +bigint *bi_copy(bigint *bi) +{ + check(bi); + if (bi->refs != PERMANENT) + bi->refs++; + return bi; +} + +/** + * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it. + * + * For this object to be freed, bi_depermanent() must be called. + * @param bi [in] The bigint to be made permanent. + */ +void bi_permanent(bigint *bi) +{ + check(bi); + if (bi->refs != 1) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("bi_permanent: refs was not 1\n"); +#endif + abort(); + } + + bi->refs = PERMANENT; +} + +/** + * @brief Take a permanent object and make it eligible for freedom. + * @param bi [in] The bigint to be made back to temporary. + */ +void bi_depermanent(bigint *bi) +{ + check(bi); + if (bi->refs != PERMANENT) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("bi_depermanent: bigint was not permanent\n"); +#endif + abort(); + } + + bi->refs = 1; +} + +/** + * @brief Free a bigint object so it can be used again. + * + * The memory itself it not actually freed, just tagged as being available + * @param ctx [in] The bigint session context. + * @param bi [in] The bigint to be freed. + */ +void bi_free(BI_CTX *ctx, bigint *bi) +{ + check(bi); + if (bi->refs == PERMANENT) + { + return; + } + + if (--bi->refs > 0) + { + return; + } + + bi->next = ctx->free_list; + ctx->free_list = bi; + ctx->free_count++; + + if (--ctx->active_count < 0) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("bi_free: active_count went negative " + "- double-freed bigint?\n"); +#endif + abort(); + } +} + +/** + * @brief Convert an (unsigned) integer into a bigint. + * @param ctx [in] The bigint session context. + * @param i [in] The (unsigned) integer to be converted. + * + */ +bigint *int_to_bi(BI_CTX *ctx, comp i) +{ + bigint *biR = alloc(ctx, 1); + biR->comps[0] = i; + return biR; +} + +/** + * @brief Do a full copy of the bigint object. + * @param ctx [in] The bigint session context. + * @param bi [in] The bigint object to be copied. + */ +bigint *bi_clone(BI_CTX *ctx, const bigint *bi) +{ + bigint *biR = alloc(ctx, bi->size); + check(bi); + memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE); + return biR; +} + +/** + * @brief Perform an addition operation between two bigints. + * @param ctx [in] The bigint session context. + * @param bia [in] A bigint. + * @param bib [in] Another bigint. + * @return The result of the addition. + */ +bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib) +{ + int n; + comp carry = 0; + comp *pa, *pb; + + check(bia); + check(bib); + + n = max(bia->size, bib->size); + more_comps(bia, n+1); + more_comps(bib, n); + pa = bia->comps; + pb = bib->comps; + + do + { + comp sl, rl, cy1; + sl = *pa + *pb++; + rl = sl + carry; + cy1 = sl < *pa; + carry = cy1 | (rl < sl); + *pa++ = rl; + } while (--n != 0); + + *pa = carry; /* do overflow */ + bi_free(ctx, bib); + return trim(bia); +} + +/** + * @brief Perform a subtraction operation between two bigints. + * @param ctx [in] The bigint session context. + * @param bia [in] A bigint. + * @param bib [in] Another bigint. + * @param is_negative [out] If defined, indicates that the result was negative. + * is_negative may be null. + * @return The result of the subtraction. The result is always positive. + */ +bigint *bi_subtract(BI_CTX *ctx, + bigint *bia, bigint *bib, int *is_negative) +{ + int n = bia->size; + comp *pa, *pb, carry = 0; + + check(bia); + check(bib); + + more_comps(bib, n); + pa = bia->comps; + pb = bib->comps; + + do + { + comp sl, rl, cy1; + sl = *pa - *pb++; + rl = sl - carry; + cy1 = sl > *pa; + carry = cy1 | (rl > sl); + *pa++ = rl; + } while (--n != 0); + + if (is_negative) /* indicate a negative result */ + { + *is_negative = carry; + } + + bi_free(ctx, trim(bib)); /* put bib back to the way it was */ + return trim(bia); +} + +/** + * Perform a multiply between a bigint an an (unsigned) integer + */ +static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b) +{ + int j = 0, n = bia->size; + bigint *biR = alloc(ctx, n + 1); + comp carry = 0; + comp *r = biR->comps; + comp *a = bia->comps; + + check(bia); + + /* clear things to start with */ + memset(r, 0, ((n+1)*COMP_BYTE_SIZE)); + + do + { + long_comp tmp = *r + (long_comp)a[j]*b + carry; + *r++ = (comp)tmp; /* downsize */ + carry = (comp)(tmp >> COMP_BIT_SIZE); + } while (++j < n); + + *r = carry; + bi_free(ctx, bia); + return trim(biR); +} + +/** + * @brief Does both division and modulo calculations. + * + * Used extensively when doing classical reduction. + * @param ctx [in] The bigint session context. + * @param u [in] A bigint which is the numerator. + * @param v [in] Either the denominator or the modulus depending on the mode. + * @param is_mod [n] Determines if this is a normal division (0) or a reduction + * (1). + * @return The result of the division/reduction. + */ +bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod) +{ + int n = v->size, m = u->size-n; + int j = 0, orig_u_size = u->size; + uint8_t mod_offset = ctx->mod_offset; + comp d; + bigint *quotient, *tmp_u; + comp q_dash; + + check(u); + check(v); + + /* if doing reduction and we are < mod, then return mod */ + if (is_mod && bi_compare(v, u) > 0) + { + bi_free(ctx, v); + return u; + } + + quotient = alloc(ctx, m+1); + tmp_u = alloc(ctx, n+1); + v = trim(v); /* make sure we have no leading 0's */ + d = (comp)((long_comp)COMP_RADIX/(V1+1)); + + /* clear things to start with */ + memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE)); + + /* normalise */ + if (d > 1) + { + u = bi_int_multiply(ctx, u, d); + + if (is_mod) + { + v = ctx->bi_normalised_mod[mod_offset]; + } + else + { + v = bi_int_multiply(ctx, v, d); + } + } + + if (orig_u_size == u->size) /* new digit position u0 */ + { + more_comps(u, orig_u_size + 1); + } + + do + { + /* get a temporary short version of u */ + memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE); + + /* calculate q' */ + if (U(0) == V1) + { + q_dash = COMP_RADIX-1; + } + else + { + q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1); + + if (v->size > 1 && V2) + { + /* we are implementing the following: + if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) - + q_dash*V1)*COMP_RADIX) + U(2))) ... */ + comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) - + (long_comp)q_dash*V1); + if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2)) + { + q_dash--; + } + } + } + + /* multiply and subtract */ + if (q_dash) + { + int is_negative; + tmp_u = bi_subtract(ctx, tmp_u, + bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative); + more_comps(tmp_u, n+1); + + Q(j) = q_dash; + + /* add back */ + if (is_negative) + { + Q(j)--; + tmp_u = bi_add(ctx, tmp_u, bi_copy(v)); + + /* lop off the carry */ + tmp_u->size--; + v->size--; + } + } + else + { + Q(j) = 0; + } + + /* copy back to u */ + memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE); + } while (++j <= m); + + bi_free(ctx, tmp_u); + bi_free(ctx, v); + + if (is_mod) /* get the remainder */ + { + bi_free(ctx, quotient); + return bi_int_divide(ctx, trim(u), d); + } + else /* get the quotient */ + { + bi_free(ctx, u); + return trim(quotient); + } +} + +/* + * Perform an integer divide on a bigint. + */ +static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom) +{ + int i = biR->size - 1; + long_comp r = 0; + + check(biR); + + do + { + r = (r<comps[i]; + biR->comps[i] = (comp)(r / denom); + r %= denom; + } while (--i >= 0); + + return trim(biR); +} + +#ifdef CONFIG_BIGINT_MONTGOMERY +/** + * There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1, + * where B^-1(B-1) mod N=1. Actually, only the least significant part of + * N' is needed, hence the definition N0'=N' mod b. We reproduce below the + * simple algorithm from an article by Dusse and Kaliski to efficiently + * find N0' from N0 and b */ +static comp modular_inverse(bigint *bim) +{ + int i; + comp t = 1; + comp two_2_i_minus_1 = 2; /* 2^(i-1) */ + long_comp two_2_i = 4; /* 2^i */ + comp N = bim->comps[0]; + + for (i = 2; i <= COMP_BIT_SIZE; i++) + { + if ((long_comp)N*t%two_2_i >= two_2_i_minus_1) + { + t += two_2_i_minus_1; + } + + two_2_i_minus_1 <<= 1; + two_2_i <<= 1; + } + + return (comp)(COMP_RADIX-t); +} +#endif + +#if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \ + defined(CONFIG_BIGINT_MONTGOMERY) +/** + * Take each component and shift down (in terms of components) + */ +static bigint *comp_right_shift(bigint *biR, int num_shifts) +{ + int i = biR->size-num_shifts; + comp *x = biR->comps; + comp *y = &biR->comps[num_shifts]; + + check(biR); + + if (i <= 0) /* have we completely right shifted? */ + { + biR->comps[0] = 0; /* return 0 */ + biR->size = 1; + return biR; + } + + do + { + *x++ = *y++; + } while (--i > 0); + + biR->size -= num_shifts; + return biR; +} + +/** + * Take each component and shift it up (in terms of components) + */ +static bigint *comp_left_shift(bigint *biR, int num_shifts) +{ + int i = biR->size-1; + comp *x, *y; + + check(biR); + + if (num_shifts <= 0) + { + return biR; + } + + more_comps(biR, biR->size + num_shifts); + + x = &biR->comps[i+num_shifts]; + y = &biR->comps[i]; + + do + { + *x-- = *y--; + } while (i--); + + memset(biR->comps, 0, num_shifts*COMP_BYTE_SIZE); /* zero LS comps */ + return biR; +} +#endif + +/** + * @brief Allow a binary sequence to be imported as a bigint. + * @param ctx [in] The bigint session context. + * @param data [in] The data to be converted. + * @param size [in] The number of bytes of data. + * @return A bigint representing this data. + */ +bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size) +{ + bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE); + int i, j = 0, offset = 0; + + memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE); + + for (i = size-1; i >= 0; i--) + { + biR->comps[offset] += (unsigned int)data[i] << (j*8); + + if (++j == COMP_BYTE_SIZE) + { + j = 0; + offset ++; + } + } + + return trim(biR); +} + +#ifdef CONFIG_SSL_FULL_MODE +/** + * @brief The testharness uses this code to import text hex-streams and + * convert them into bigints. + * @param ctx [in] The bigint session context. + * @param data [in] A string consisting of hex characters. The characters must + * be in upper case. + * @return A bigint representing this data. + */ +bigint *bi_str_import(BI_CTX *ctx, const char *data) +{ + int size = strlen(data); + bigint *biR = alloc(ctx, (size+COMP_NUM_NIBBLES-1)/COMP_NUM_NIBBLES); + int i, j = 0, offset = 0; + memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE); + + for (i = size-1; i >= 0; i--) + { + int num = (data[i] <= '9') ? (data[i] - '0') : (data[i] - 'A' + 10); + biR->comps[offset] += num << (j*4); + + if (++j == COMP_NUM_NIBBLES) + { + j = 0; + offset ++; + } + } + + return biR; +} + +void bi_print(const char *label, bigint *x) +{ + int i, j; + + if (x == NULL) + { + printf("%s: (null)\n", label); + return; + } + + printf("%s: (size %d)\n", label, x->size); + for (i = x->size-1; i >= 0; i--) + { + for (j = COMP_NUM_NIBBLES-1; j >= 0; j--) + { + comp mask = 0x0f << (j*4); + comp num = (x->comps[i] & mask) >> (j*4); + putc((num <= 9) ? (num + '0') : (num + 'A' - 10), stdout); + } + } + + printf("\n"); +} +#endif + +/** + * @brief Take a bigint and convert it into a byte sequence. + * + * This is useful after a decrypt operation. + * @param ctx [in] The bigint session context. + * @param x [in] The bigint to be converted. + * @param data [out] The converted data as a byte stream. + * @param size [in] The maximum size of the byte stream. Unused bytes will be + * zeroed. + */ +void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size) +{ + int i, j, k = size-1; + + check(x); + memset(data, 0, size); /* ensure all leading 0's are cleared */ + + for (i = 0; i < x->size; i++) + { + for (j = 0; j < COMP_BYTE_SIZE; j++) + { + comp mask = 0xff << (j*8); + int num = (x->comps[i] & mask) >> (j*8); + data[k--] = num; + + if (k < 0) + { + goto buf_done; + } + } + } +buf_done: + + bi_free(ctx, x); +} + +/** + * @brief Pre-calculate some of the expensive steps in reduction. + * + * This function should only be called once (normally when a session starts). + * When the session is over, bi_free_mod() should be called. bi_mod_power() + * relies on this function being called. + * @param ctx [in] The bigint session context. + * @param bim [in] The bigint modulus that will be used. + * @param mod_offset [in] There are three moduluii that can be stored - the + * standard modulus, and its two primes p and q. This offset refers to which + * modulus we are referring to. + * @see bi_free_mod(), bi_mod_power(). + */ +void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset) +{ + int k = bim->size; + comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1)); +#ifdef CONFIG_BIGINT_MONTGOMERY + bigint *R, *R2; +#endif + + ctx->bi_mod[mod_offset] = bim; + bi_permanent(ctx->bi_mod[mod_offset]); + ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d); + bi_permanent(ctx->bi_normalised_mod[mod_offset]); + +#if defined(CONFIG_BIGINT_MONTGOMERY) + /* set montgomery variables */ + R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1); /* R */ + R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1); /* R^2 */ + ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2); /* R^2 mod m */ + ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R); /* R mod m */ + + bi_permanent(ctx->bi_RR_mod_m[mod_offset]); + bi_permanent(ctx->bi_R_mod_m[mod_offset]); + + ctx->N0_dash[mod_offset] = modular_inverse(ctx->bi_mod[mod_offset]); + +#elif defined (CONFIG_BIGINT_BARRETT) + ctx->bi_mu[mod_offset] = + bi_divide(ctx, comp_left_shift( + bi_clone(ctx, ctx->bi_radix), k*2-1), ctx->bi_mod[mod_offset], 0); + bi_permanent(ctx->bi_mu[mod_offset]); +#endif +} + +/** + * @brief Used when cleaning various bigints at the end of a session. + * @param ctx [in] The bigint session context. + * @param mod_offset [in] The offset to use. + * @see bi_set_mod(). + */ +void bi_free_mod(BI_CTX *ctx, int mod_offset) +{ + bi_depermanent(ctx->bi_mod[mod_offset]); + bi_free(ctx, ctx->bi_mod[mod_offset]); +#if defined (CONFIG_BIGINT_MONTGOMERY) + bi_depermanent(ctx->bi_RR_mod_m[mod_offset]); + bi_depermanent(ctx->bi_R_mod_m[mod_offset]); + bi_free(ctx, ctx->bi_RR_mod_m[mod_offset]); + bi_free(ctx, ctx->bi_R_mod_m[mod_offset]); +#elif defined(CONFIG_BIGINT_BARRETT) + bi_depermanent(ctx->bi_mu[mod_offset]); + bi_free(ctx, ctx->bi_mu[mod_offset]); +#endif + bi_depermanent(ctx->bi_normalised_mod[mod_offset]); + bi_free(ctx, ctx->bi_normalised_mod[mod_offset]); +} + +/** + * Perform a standard multiplication between two bigints. + * + * Barrett reduction has no need for some parts of the product, so ignore bits + * of the multiply. This routine gives Barrett its big performance + * improvements over Classical/Montgomery reduction methods. + */ +static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib, + int inner_partial, int outer_partial) +{ + int i = 0, j; + int n = bia->size; + int t = bib->size; + bigint *biR = alloc(ctx, n + t); + comp *sr = biR->comps; + comp *sa = bia->comps; + comp *sb = bib->comps; + + check(bia); + check(bib); + + /* clear things to start with */ + memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE)); + + do + { + long_comp tmp; + comp carry = 0; + int r_index = i; + j = 0; + + if (outer_partial && outer_partial-i > 0 && outer_partial < n) + { + r_index = outer_partial-1; + j = outer_partial-i-1; + } + + do + { + if (inner_partial && r_index >= inner_partial) + { + break; + } + + tmp = sr[r_index] + ((long_comp)sa[j])*sb[i] + carry; + sr[r_index++] = (comp)tmp; /* downsize */ + carry = tmp >> COMP_BIT_SIZE; + } while (++j < n); + + sr[r_index] = carry; + } while (++i < t); + + bi_free(ctx, bia); + bi_free(ctx, bib); + return trim(biR); +} + +#ifdef CONFIG_BIGINT_KARATSUBA +/* + * Karatsuba improves on regular multiplication due to only 3 multiplications + * being done instead of 4. The additional additions/subtractions are O(N) + * rather than O(N^2) and so for big numbers it saves on a few operations + */ +static bigint *karatsuba(BI_CTX *ctx, bigint *bia, bigint *bib, int is_square) +{ + bigint *x0, *x1; + bigint *p0, *p1, *p2; + int m; + + if (is_square) + { + m = (bia->size + 1)/2; + } + else + { + m = (max(bia->size, bib->size) + 1)/2; + } + + x0 = bi_clone(ctx, bia); + x0->size = m; + x1 = bi_clone(ctx, bia); + comp_right_shift(x1, m); + bi_free(ctx, bia); + + /* work out the 3 partial products */ + if (is_square) + { + p0 = bi_square(ctx, bi_copy(x0)); + p2 = bi_square(ctx, bi_copy(x1)); + p1 = bi_square(ctx, bi_add(ctx, x0, x1)); + } + else /* normal multiply */ + { + bigint *y0, *y1; + y0 = bi_clone(ctx, bib); + y0->size = m; + y1 = bi_clone(ctx, bib); + comp_right_shift(y1, m); + bi_free(ctx, bib); + + p0 = bi_multiply(ctx, bi_copy(x0), bi_copy(y0)); + p2 = bi_multiply(ctx, bi_copy(x1), bi_copy(y1)); + p1 = bi_multiply(ctx, bi_add(ctx, x0, x1), bi_add(ctx, y0, y1)); + } + + p1 = bi_subtract(ctx, + bi_subtract(ctx, p1, bi_copy(p2), NULL), bi_copy(p0), NULL); + + comp_left_shift(p1, m); + comp_left_shift(p2, 2*m); + return bi_add(ctx, p1, bi_add(ctx, p0, p2)); +} +#endif + +/** + * @brief Perform a multiplication operation between two bigints. + * @param ctx [in] The bigint session context. + * @param bia [in] A bigint. + * @param bib [in] Another bigint. + * @return The result of the multiplication. + */ +bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib) +{ + check(bia); + check(bib); + +#ifdef CONFIG_BIGINT_KARATSUBA + if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH) + { + return regular_multiply(ctx, bia, bib, 0, 0); + } + + return karatsuba(ctx, bia, bib, 0); +#else + return regular_multiply(ctx, bia, bib, 0, 0); +#endif +} + +#ifdef CONFIG_BIGINT_SQUARE +/* + * Perform the actual square operion. It takes into account overflow. + */ +static bigint *regular_square(BI_CTX *ctx, bigint *bi) +{ + int t = bi->size; + int i = 0, j; + bigint *biR = alloc(ctx, t*2+1); + comp *w = biR->comps; + comp *x = bi->comps; + long_comp carry; + memset(w, 0, biR->size*COMP_BYTE_SIZE); + + do + { + long_comp tmp = w[2*i] + (long_comp)x[i]*x[i]; + w[2*i] = (comp)tmp; + carry = tmp >> COMP_BIT_SIZE; + + for (j = i+1; j < t; j++) + { + uint8_t c = 0; + long_comp xx = (long_comp)x[i]*x[j]; + if ((COMP_MAX-xx) < xx) + c = 1; + + tmp = (xx<<1); + + if ((COMP_MAX-tmp) < w[i+j]) + c = 1; + + tmp += w[i+j]; + + if ((COMP_MAX-tmp) < carry) + c = 1; + + tmp += carry; + w[i+j] = (comp)tmp; + carry = tmp >> COMP_BIT_SIZE; + + if (c) + carry += COMP_RADIX; + } + + tmp = w[i+t] + carry; + w[i+t] = (comp)tmp; + w[i+t+1] = tmp >> COMP_BIT_SIZE; + } while (++i < t); + + bi_free(ctx, bi); + return trim(biR); +} + +/** + * @brief Perform a square operation on a bigint. + * @param ctx [in] The bigint session context. + * @param bia [in] A bigint. + * @return The result of the multiplication. + */ +bigint *bi_square(BI_CTX *ctx, bigint *bia) +{ + check(bia); + +#ifdef CONFIG_BIGINT_KARATSUBA + if (bia->size < SQU_KARATSUBA_THRESH) + { + return regular_square(ctx, bia); + } + + return karatsuba(ctx, bia, NULL, 1); +#else + return regular_square(ctx, bia); +#endif +} +#endif + +/** + * @brief Compare two bigints. + * @param bia [in] A bigint. + * @param bib [in] Another bigint. + * @return -1 if smaller, 1 if larger and 0 if equal. + */ +int bi_compare(bigint *bia, bigint *bib) +{ + int r, i; + + check(bia); + check(bib); + + if (bia->size > bib->size) + r = 1; + else if (bia->size < bib->size) + r = -1; + else + { + comp *a = bia->comps; + comp *b = bib->comps; + + /* Same number of components. Compare starting from the high end + * and working down. */ + r = 0; + i = bia->size - 1; + + do + { + if (a[i] > b[i]) + { + r = 1; + break; + } + else if (a[i] < b[i]) + { + r = -1; + break; + } + } while (--i >= 0); + } + + return r; +} + +/* + * Allocate and zero more components. Does not consume bi. + */ +static void more_comps(bigint *bi, int n) +{ + if (n > bi->max_comps) + { + bi->max_comps = max(bi->max_comps * 2, n); + bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE); + } + + if (n > bi->size) + { + memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE); + } + + bi->size = n; +} + +/* + * Make a new empty bigint. It may just use an old one if one is available. + * Otherwise get one off the heap. + */ +static bigint *alloc(BI_CTX *ctx, int size) +{ + bigint *biR; + + /* Can we recycle an old bigint? */ + if (ctx->free_list != NULL) + { + biR = ctx->free_list; + ctx->free_list = biR->next; + ctx->free_count--; + + if (biR->refs != 0) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("alloc: refs was not 0\n"); +#endif + abort(); /* create a stack trace from a core dump */ + } + + more_comps(biR, size); + } + else + { + /* No free bigints available - create a new one. */ + biR = (bigint *)malloc(sizeof(bigint)); + biR->comps = (comp*)malloc(size * COMP_BYTE_SIZE); + biR->max_comps = size; /* give some space to spare */ + } + + biR->size = size; + biR->refs = 1; + biR->next = NULL; + ctx->active_count++; + return biR; +} + +/* + * Work out the highest '1' bit in an exponent. Used when doing sliding-window + * exponentiation. + */ +static int find_max_exp_index(bigint *biexp) +{ + int i = COMP_BIT_SIZE-1; + comp shift = COMP_RADIX/2; + comp test = biexp->comps[biexp->size-1]; /* assume no leading zeroes */ + + check(biexp); + + do + { + if (test & shift) + { + return i+(biexp->size-1)*COMP_BIT_SIZE; + } + + shift >>= 1; + } while (i-- != 0); + + return -1; /* error - must have been a leading 0 */ +} + +/* + * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window + * exponentiation. + */ +static int exp_bit_is_one(bigint *biexp, int offset) +{ + comp test = biexp->comps[offset / COMP_BIT_SIZE]; + int num_shifts = offset % COMP_BIT_SIZE; + comp shift = 1; + int i; + + check(biexp); + + for (i = 0; i < num_shifts; i++) + { + shift <<= 1; + } + + return (test & shift) != 0; +} + +#ifdef CONFIG_BIGINT_CHECK_ON +/* + * Perform a sanity check on bi. + */ +static void check(const bigint *bi) +{ + if (bi->refs <= 0) + { + printf("check: zero or negative refs in bigint\n"); + abort(); + } + + if (bi->next != NULL) + { + printf("check: attempt to use a bigint from " + "the free list\n"); + abort(); + } +} +#endif + +/* + * Delete any leading 0's (and allow for 0). + */ +static bigint *trim(bigint *bi) +{ + check(bi); + + while (bi->comps[bi->size-1] == 0 && bi->size > 1) + { + bi->size--; + } + + return bi; +} + +#if defined(CONFIG_BIGINT_MONTGOMERY) +/** + * @brief Perform a single montgomery reduction. + * @param ctx [in] The bigint session context. + * @param bixy [in] A bigint. + * @return The result of the montgomery reduction. + */ +bigint *bi_mont(BI_CTX *ctx, bigint *bixy) +{ + int i = 0, n; + uint8_t mod_offset = ctx->mod_offset; + bigint *bim = ctx->bi_mod[mod_offset]; + comp mod_inv = ctx->N0_dash[mod_offset]; + + check(bixy); + + if (ctx->use_classical) /* just use classical instead */ + { + return bi_mod(ctx, bixy); + } + + n = bim->size; + + do + { + bixy = bi_add(ctx, bixy, comp_left_shift( + bi_int_multiply(ctx, bim, bixy->comps[i]*mod_inv), i)); + } while (++i < n); + + comp_right_shift(bixy, n); + + if (bi_compare(bixy, bim) >= 0) + { + bixy = bi_subtract(ctx, bixy, bim, NULL); + } + + return bixy; +} + +#elif defined(CONFIG_BIGINT_BARRETT) +/* + * Stomp on the most significant components to give the illusion of a "mod base + * radix" operation + */ +static bigint *comp_mod(bigint *bi, int mod) +{ + check(bi); + + if (bi->size > mod) + { + bi->size = mod; + } + + return bi; +} + +/** + * @brief Perform a single Barrett reduction. + * @param ctx [in] The bigint session context. + * @param bi [in] A bigint. + * @return The result of the Barrett reduction. + */ +bigint *bi_barrett(BI_CTX *ctx, bigint *bi) +{ + bigint *q1, *q2, *q3, *r1, *r2, *r; + uint8_t mod_offset = ctx->mod_offset; + bigint *bim = ctx->bi_mod[mod_offset]; + int k = bim->size; + + check(bi); + check(bim); + + /* use Classical method instead - Barrett cannot help here */ + if (bi->size > k*2) + { + return bi_mod(ctx, bi); + } + + q1 = comp_right_shift(bi_clone(ctx, bi), k-1); + + /* do outer partial multiply */ + q2 = regular_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1); + q3 = comp_right_shift(q2, k+1); + r1 = comp_mod(bi, k+1); + + /* do inner partial multiply */ + r2 = comp_mod(regular_multiply(ctx, q3, bim, k+1, 0), k+1); + r = bi_subtract(ctx, r1, r2, NULL); + + /* if (r >= m) r = r - m; */ + if (bi_compare(r, bim) >= 0) + { + r = bi_subtract(ctx, r, bim, NULL); + } + + return r; +} +#endif /* CONFIG_BIGINT_BARRETT */ + +#ifdef CONFIG_BIGINT_SLIDING_WINDOW +/* + * Work out g1, g3, g5, g7... etc for the sliding-window algorithm + */ +static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1) +{ + int k = 1, i; + bigint *g2; + + for (i = 0; i < window-1; i++) /* compute 2^(window-1) */ + { + k <<= 1; + } + + ctx->g = (bigint **)malloc(k*sizeof(bigint *)); + ctx->g[0] = bi_clone(ctx, g1); + bi_permanent(ctx->g[0]); + g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0])); /* g^2 */ + + for (i = 1; i < k; i++) + { + ctx->g[i] = bi_residue(ctx, bi_multiply(ctx, ctx->g[i-1], bi_copy(g2))); + bi_permanent(ctx->g[i]); + } + + bi_free(ctx, g2); + ctx->window = k; +} +#endif + +/** + * @brief Perform a modular exponentiation. + * + * This function requires bi_set_mod() to have been called previously. This is + * one of the optimisations used for performance. + * @param ctx [in] The bigint session context. + * @param bi [in] The bigint on which to perform the mod power operation. + * @param biexp [in] The bigint exponent. + * @return The result of the mod exponentiation operation + * @see bi_set_mod(). + */ +bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp) +{ + int i = find_max_exp_index(biexp), j, window_size = 1; + bigint *biR = int_to_bi(ctx, 1); + +#if defined(CONFIG_BIGINT_MONTGOMERY) + uint8_t mod_offset = ctx->mod_offset; + if (!ctx->use_classical) + { + /* preconvert */ + bi = bi_mont(ctx, + bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset])); /* x' */ + bi_free(ctx, biR); + biR = ctx->bi_R_mod_m[mod_offset]; /* A */ + } +#endif + + check(bi); + check(biexp); + +#ifdef CONFIG_BIGINT_SLIDING_WINDOW + for (j = i; j > 32; j /= 5) /* work out an optimum size */ + window_size++; + + /* work out the slide constants */ + precompute_slide_window(ctx, window_size, bi); +#else /* just one constant */ + ctx->g = (bigint **)malloc(sizeof(bigint *)); + ctx->g[0] = bi_clone(ctx, bi); + ctx->window = 1; + bi_permanent(ctx->g[0]); +#endif + + /* if sliding-window is off, then only one bit will be done at a time and + * will reduce to standard left-to-right exponentiation */ + do + { +#ifdef __ets__ + void ets_loop_iter(void); + ets_loop_iter(); +#endif + if (exp_bit_is_one(biexp, i)) + { + int l = i-window_size+1; + int part_exp = 0; + + if (l < 0) /* LSB of exponent will always be 1 */ + l = 0; + else + { + while (exp_bit_is_one(biexp, l) == 0) + l++; /* go back up */ + } + + /* build up the section of the exponent */ + for (j = i; j >= l; j--) + { + biR = bi_residue(ctx, bi_square(ctx, biR)); + if (exp_bit_is_one(biexp, j)) + part_exp++; + + if (j != l) + part_exp <<= 1; + } + + part_exp = (part_exp-1)/2; /* adjust for array */ + biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp])); + i = l-1; + } + else /* square it */ + { + biR = bi_residue(ctx, bi_square(ctx, biR)); + i--; + } + } while (i >= 0); + + /* cleanup */ + for (i = 0; i < ctx->window; i++) + { + bi_depermanent(ctx->g[i]); + bi_free(ctx, ctx->g[i]); + } + + free(ctx->g); + bi_free(ctx, bi); + bi_free(ctx, biexp); +#if defined CONFIG_BIGINT_MONTGOMERY + return ctx->use_classical ? biR : bi_mont(ctx, biR); /* convert back */ +#else /* CONFIG_BIGINT_CLASSICAL or CONFIG_BIGINT_BARRETT */ + return biR; +#endif +} + +#ifdef CONFIG_SSL_CERT_VERIFICATION +/** + * @brief Perform a modular exponentiation using a temporary modulus. + * + * We need this function to check the signatures of certificates. The modulus + * of this function is temporary as it's just used for authentication. + * @param ctx [in] The bigint session context. + * @param bi [in] The bigint to perform the exp/mod. + * @param bim [in] The temporary modulus. + * @param biexp [in] The bigint exponent. + * @return The result of the mod exponentiation operation + * @see bi_set_mod(). + */ +bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp) +{ + bigint *biR, *tmp_biR; + + /* Set up a temporary bigint context and transfer what we need between + * them. We need to do this since we want to keep the original modulus + * which is already in this context. This operation is only called when + * doing peer verification, and so is not expensive :-) */ + BI_CTX *tmp_ctx = bi_initialize(); + bi_set_mod(tmp_ctx, bi_clone(tmp_ctx, bim), BIGINT_M_OFFSET); + tmp_biR = bi_mod_power(tmp_ctx, + bi_clone(tmp_ctx, bi), + bi_clone(tmp_ctx, biexp)); + biR = bi_clone(ctx, tmp_biR); + bi_free(tmp_ctx, tmp_biR); + bi_free_mod(tmp_ctx, BIGINT_M_OFFSET); + bi_terminate(tmp_ctx); + + bi_free(ctx, bi); + bi_free(ctx, bim); + bi_free(ctx, biexp); + return biR; +} +#endif + +#ifdef CONFIG_BIGINT_CRT +/** + * @brief Use the Chinese Remainder Theorem to quickly perform RSA decrypts. + * + * @param ctx [in] The bigint session context. + * @param bi [in] The bigint to perform the exp/mod. + * @param dP [in] CRT's dP bigint + * @param dQ [in] CRT's dQ bigint + * @param p [in] CRT's p bigint + * @param q [in] CRT's q bigint + * @param qInv [in] CRT's qInv bigint + * @return The result of the CRT operation + */ +bigint *bi_crt(BI_CTX *ctx, bigint *bi, + bigint *dP, bigint *dQ, + bigint *p, bigint *q, bigint *qInv) +{ + bigint *m1, *m2, *h; + + /* Montgomery has a condition the 0 < x, y < m and these products violate + * that condition. So disable Montgomery when using CRT */ +#if defined(CONFIG_BIGINT_MONTGOMERY) + ctx->use_classical = 1; +#endif + ctx->mod_offset = BIGINT_P_OFFSET; + m1 = bi_mod_power(ctx, bi_copy(bi), dP); + + ctx->mod_offset = BIGINT_Q_OFFSET; + m2 = bi_mod_power(ctx, bi, dQ); + + h = bi_subtract(ctx, bi_add(ctx, m1, p), bi_copy(m2), NULL); + h = bi_multiply(ctx, h, qInv); + ctx->mod_offset = BIGINT_P_OFFSET; + h = bi_residue(ctx, h); +#if defined(CONFIG_BIGINT_MONTGOMERY) + ctx->use_classical = 0; /* reset for any further operation */ +#endif + return bi_add(ctx, m2, bi_multiply(ctx, q, h)); +} +#endif +/** @} */ diff --git a/circuitpython/lib/axtls/crypto/bigint.h b/circuitpython/lib/axtls/crypto/bigint.h new file mode 100644 index 0000000..2966a3e --- /dev/null +++ b/circuitpython/lib/axtls/crypto/bigint.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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 BIGINT_HEADER +#define BIGINT_HEADER + +#include "crypto.h" + +BI_CTX *bi_initialize(void); +void bi_terminate(BI_CTX *ctx); +void bi_permanent(bigint *bi); +void bi_depermanent(bigint *bi); +void bi_clear_cache(BI_CTX *ctx); +void bi_free(BI_CTX *ctx, bigint *bi); +bigint *bi_copy(bigint *bi); +bigint *bi_clone(BI_CTX *ctx, const bigint *bi); +void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size); +bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len); +bigint *int_to_bi(BI_CTX *ctx, comp i); + +/* the functions that actually do something interesting */ +bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib); +bigint *bi_subtract(BI_CTX *ctx, bigint *bia, + bigint *bib, int *is_negative); +bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod); +bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib); +bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp); +bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp); +int bi_compare(bigint *bia, bigint *bib); +void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset); +void bi_free_mod(BI_CTX *ctx, int mod_offset); + +#ifdef CONFIG_SSL_FULL_MODE +void bi_print(const char *label, bigint *bi); +bigint *bi_str_import(BI_CTX *ctx, const char *data); +#endif + +/** + * @def bi_mod + * Find the residue of B. bi_set_mod() must be called before hand. + */ +#define bi_mod(A, B) bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1) + +/** + * bi_residue() is technically the same as bi_mod(), but it uses the + * appropriate reduction technique (which is bi_mod() when doing classical + * reduction). + */ +#if defined(CONFIG_BIGINT_MONTGOMERY) +#define bi_residue(A, B) bi_mont(A, B) +bigint *bi_mont(BI_CTX *ctx, bigint *bixy); +#elif defined(CONFIG_BIGINT_BARRETT) +#define bi_residue(A, B) bi_barrett(A, B) +bigint *bi_barrett(BI_CTX *ctx, bigint *bi); +#else /* if defined(CONFIG_BIGINT_CLASSICAL) */ +#define bi_residue(A, B) bi_mod(A, B) +#endif + +#ifdef CONFIG_BIGINT_SQUARE +bigint *bi_square(BI_CTX *ctx, bigint *bi); +#else +#define bi_square(A, B) bi_multiply(A, bi_copy(B), B) +#endif + +#ifdef CONFIG_BIGINT_CRT +bigint *bi_crt(BI_CTX *ctx, bigint *bi, + bigint *dP, bigint *dQ, + bigint *p, bigint *q, + bigint *qInv); +#endif + +#endif diff --git a/circuitpython/lib/axtls/crypto/bigint_impl.h b/circuitpython/lib/axtls/crypto/bigint_impl.h new file mode 100644 index 0000000..fef6e03 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/bigint_impl.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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 BIGINT_IMPL_HEADER +#define BIGINT_IMPL_HEADER + +/* Maintain a number of precomputed variables when doing reduction */ +#define BIGINT_M_OFFSET 0 /**< Normal modulo offset. */ +#ifdef CONFIG_BIGINT_CRT +#define BIGINT_P_OFFSET 1 /**< p modulo offset. */ +#define BIGINT_Q_OFFSET 2 /**< q module offset. */ +#define BIGINT_NUM_MODS 3 /**< The number of modulus constants used. */ +#else +#define BIGINT_NUM_MODS 1 +#endif + +/* Architecture specific functions for big ints */ +#if defined(CONFIG_INTEGER_8BIT) +#define COMP_RADIX 256U /**< Max component + 1 */ +#define COMP_MAX 0xFFFFU/**< (Max dbl comp -1) */ +#define COMP_BIT_SIZE 8 /**< Number of bits in a component. */ +#define COMP_BYTE_SIZE 1 /**< Number of bytes in a component. */ +#define COMP_NUM_NIBBLES 2 /**< Used For diagnostics only. */ +typedef uint8_t comp; /**< A single precision component. */ +typedef uint16_t long_comp; /**< A double precision component. */ +typedef int16_t slong_comp; /**< A signed double precision component. */ +#elif defined(CONFIG_INTEGER_16BIT) +#define COMP_RADIX 65536U /**< Max component + 1 */ +#define COMP_MAX 0xFFFFFFFFU/**< (Max dbl comp -1) */ +#define COMP_BIT_SIZE 16 /**< Number of bits in a component. */ +#define COMP_BYTE_SIZE 2 /**< Number of bytes in a component. */ +#define COMP_NUM_NIBBLES 4 /**< Used For diagnostics only. */ +typedef uint16_t comp; /**< A single precision component. */ +typedef uint32_t long_comp; /**< A double precision component. */ +typedef int32_t slong_comp; /**< A signed double precision component. */ +#else /* regular 32 bit */ +#ifdef WIN32 +#define COMP_RADIX 4294967296i64 +#define COMP_MAX 0xFFFFFFFFFFFFFFFFui64 +#else +#define COMP_RADIX 4294967296ULL /**< Max component + 1 */ +#define COMP_MAX 0xFFFFFFFFFFFFFFFFULL/**< (Max dbl comp -1) */ +#endif +#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */ +#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */ +#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */ +typedef uint32_t comp; /**< A single precision component. */ +typedef uint64_t long_comp; /**< A double precision component. */ +typedef int64_t slong_comp; /**< A signed double precision component. */ +#endif + +/** + * @struct _bigint + * @brief A big integer basic object + */ +struct _bigint +{ + struct _bigint* next; /**< The next bigint in the cache. */ + short size; /**< The number of components in this bigint. */ + short max_comps; /**< The heapsize allocated for this bigint */ + int refs; /**< An internal reference count. */ + comp* comps; /**< A ptr to the actual component data */ +}; + +typedef struct _bigint bigint; /**< An alias for _bigint */ + +/** + * Maintains the state of the cache, and a number of variables used in + * reduction. + */ +typedef struct /**< A big integer "session" context. */ +{ + bigint *active_list; /**< Bigints currently used. */ + bigint *free_list; /**< Bigints not used. */ + bigint *bi_radix; /**< The radix used. */ + bigint *bi_mod[BIGINT_NUM_MODS]; /**< modulus */ + +#if defined(CONFIG_BIGINT_MONTGOMERY) + bigint *bi_RR_mod_m[BIGINT_NUM_MODS]; /**< R^2 mod m */ + bigint *bi_R_mod_m[BIGINT_NUM_MODS]; /**< R mod m */ + comp N0_dash[BIGINT_NUM_MODS]; +#elif defined(CONFIG_BIGINT_BARRETT) + bigint *bi_mu[BIGINT_NUM_MODS]; /**< Storage for mu */ +#endif + bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */ + bigint **g; /**< Used by sliding-window. */ + int window; /**< The size of the sliding window */ + int active_count; /**< Number of active bigints. */ + int free_count; /**< Number of free bigints. */ + +#ifdef CONFIG_BIGINT_MONTGOMERY + uint8_t use_classical; /**< Use classical reduction. */ +#endif + uint8_t mod_offset; /**< The mod offset we are using */ +} BI_CTX; + +#ifndef WIN32 +#define max(a,b) ((a)>(b)?(a):(b)) /**< Find the maximum of 2 numbers. */ +#define min(a,b) ((a)<(b)?(a):(b)) /**< Find the minimum of 2 numbers. */ +#endif + +#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */ + +#endif diff --git a/circuitpython/lib/axtls/crypto/crypto.h b/circuitpython/lib/axtls/crypto/crypto.h new file mode 100644 index 0000000..df232a3 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/crypto.h @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * @file crypto.h + */ + +#ifndef HEADER_CRYPTO_H +#define HEADER_CRYPTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "bigint_impl.h" +#include "bigint.h" + +#ifndef STDCALL +#define STDCALL +#endif +#ifndef EXP_FUNC +#define EXP_FUNC +#endif + + +/* enable features based on a 'super-set' capbaility. */ +#if 0 +#if defined(CONFIG_SSL_FULL_MODE) +#define CONFIG_SSL_ENABLE_CLIENT +#define CONFIG_SSL_CERT_VERIFICATION +#elif defined(CONFIG_SSL_ENABLE_CLIENT) +#define CONFIG_SSL_CERT_VERIFICATION +#endif +#endif + +/************************************************************************** + * AES declarations + **************************************************************************/ + +#define AES_MAXROUNDS 14 +#define AES_BLOCKSIZE 16 +#define AES_IV_SIZE 16 + +typedef struct aes_key_st +{ + uint16_t rounds; + uint16_t key_size; + uint32_t ks[(AES_MAXROUNDS+1)*8]; + uint8_t iv[AES_IV_SIZE]; +} AES_CTX; + +typedef enum +{ + AES_MODE_128, + AES_MODE_256 +} AES_MODE; + +void AES_set_key(AES_CTX *ctx, const uint8_t *key, + const uint8_t *iv, AES_MODE mode); +void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, + uint8_t *out, int length); +void AES_cbc_decrypt(AES_CTX *ks, const uint8_t *in, uint8_t *out, int length); +void AES_convert_key(AES_CTX *ctx); +void AES_encrypt(const AES_CTX *ctx, uint32_t *data); +void AES_decrypt(const AES_CTX *ctx, uint32_t *data); + +/************************************************************************** + * RC4 declarations + **************************************************************************/ + +typedef struct +{ + uint8_t x, y, m[256]; +} RC4_CTX; + +void RC4_setup(RC4_CTX *s, const uint8_t *key, int length); +void RC4_crypt(RC4_CTX *s, const uint8_t *msg, uint8_t *data, int length); + +/************************************************************************** + * SHA1 declarations + **************************************************************************/ + +#define SHA1_SIZE 20 + +/* + * This structure will hold context information for the SHA-1 + * hashing operation + */ +typedef struct +{ + uint32_t Intermediate_Hash[SHA1_SIZE/4]; /* Message Digest */ + uint32_t Length_Low; /* Message length in bits */ + uint32_t Length_High; /* Message length in bits */ + uint16_t Message_Block_Index; /* Index into message block array */ + uint8_t Message_Block[64]; /* 512-bit message blocks */ +} SHA1_CTX; + +void SHA1_Init(SHA1_CTX *); +void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len); +void SHA1_Final(uint8_t *digest, SHA1_CTX *); + +/************************************************************************** + * SHA256 declarations + **************************************************************************/ + +#define SHA256_SIZE 32 + +#ifndef SHA256_CTX +#define SHA256_CTX SHA256_CTX +typedef struct +{ + uint32_t total[2]; + uint32_t state[8]; + uint8_t buffer[64]; +} SHA256_CTX; + +void SHA256_Init(SHA256_CTX *c); +void SHA256_Update(SHA256_CTX *, const uint8_t *input, int len); +void SHA256_Final(uint8_t *digest, SHA256_CTX *); +#endif + +/************************************************************************** + * SHA512 declarations + **************************************************************************/ + +#define SHA512_SIZE 64 + +typedef struct +{ + union + { + uint64_t h[8]; + uint8_t digest[64]; + } h_dig; + union + { + uint64_t w[80]; + uint8_t buffer[128]; + } w_buf; + size_t size; + uint64_t totalSize; +} SHA512_CTX; + +void SHA512_Init(SHA512_CTX *c); +void SHA512_Update(SHA512_CTX *, const uint8_t *input, int len); +void SHA512_Final(uint8_t *digest, SHA512_CTX *); + +/************************************************************************** + * SHA384 declarations + **************************************************************************/ + +#define SHA384_SIZE 48 + +typedef SHA512_CTX SHA384_CTX; +void SHA384_Init(SHA384_CTX *c); +void SHA384_Update(SHA384_CTX *, const uint8_t *input, int len); +void SHA384_Final(uint8_t *digest, SHA384_CTX *); + +/************************************************************************** + * MD5 declarations + **************************************************************************/ + +#define MD5_SIZE 16 + +typedef struct +{ + uint32_t state[4]; /* state (ABCD) */ + uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ + uint8_t buffer[64]; /* input buffer */ +} MD5_CTX; + +EXP_FUNC void STDCALL MD5_Init(MD5_CTX *); +EXP_FUNC void STDCALL MD5_Update(MD5_CTX *, const uint8_t *msg, int len); +EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *); + +/************************************************************************** + * HMAC declarations + **************************************************************************/ +void ssl_hmac_md5(const uint8_t *msg, int length, const uint8_t *key, + int key_len, uint8_t *digest); +void ssl_hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, + int key_len, uint8_t *digest); +void hmac_sha256(const uint8_t *msg, int length, const uint8_t *key, + int key_len, uint8_t *digest); + +/************************************************************************** + * RSA declarations + **************************************************************************/ + +typedef struct +{ + bigint *m; /* modulus */ + bigint *e; /* public exponent */ + bigint *d; /* private exponent */ +#ifdef CONFIG_BIGINT_CRT + bigint *p; /* p as in m = pq */ + bigint *q; /* q as in m = pq */ + bigint *dP; /* d mod (p-1) */ + bigint *dQ; /* d mod (q-1) */ + bigint *qInv; /* q^-1 mod p */ +#endif + int num_octets; + BI_CTX *bi_ctx; +} RSA_CTX; + +void RSA_priv_key_new(RSA_CTX **rsa_ctx, + const uint8_t *modulus, int mod_len, + const uint8_t *pub_exp, int pub_len, + const uint8_t *priv_exp, int priv_len +#ifdef CONFIG_BIGINT_CRT + , const uint8_t *p, int p_len, + const uint8_t *q, int q_len, + const uint8_t *dP, int dP_len, + const uint8_t *dQ, int dQ_len, + const uint8_t *qInv, int qInv_len +#endif + ); +void RSA_pub_key_new(RSA_CTX **rsa_ctx, + const uint8_t *modulus, int mod_len, + const uint8_t *pub_exp, int pub_len); +void RSA_free(RSA_CTX *ctx); +int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data, + int out_len, int is_decryption); +bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg); +// Don't bother to ifdef prototypes, let them be +//#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT) +bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len, + bigint *modulus, bigint *pub_exp); +bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg); +int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, + uint8_t *out_data, int is_signing); +void RSA_print(const RSA_CTX *ctx); +//#endif + +/************************************************************************** + * RNG declarations + **************************************************************************/ +EXP_FUNC void STDCALL RNG_initialize(void); +EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size); +EXP_FUNC void STDCALL RNG_terminate(void); +EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data); +int get_random_NZ(int num_rand_bytes, uint8_t *rand_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/axtls/crypto/crypto_misc.c b/circuitpython/lib/axtls/crypto/crypto_misc.c new file mode 100644 index 0000000..bba5a20 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/crypto_misc.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2007-2019, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Some misc. routines to help things out + */ + +#include +#include +#include +#include +#include "os_port.h" +#include "crypto_misc.h" +#ifdef CONFIG_WIN32_USE_CRYPTO_LIB +#include "wincrypt.h" +#endif + +#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM) +static int rng_fd = -1; +#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB) +static HCRYPTPROV gCryptProv; +#endif + +#if (!defined(CONFIG_USE_DEV_URANDOM) && !defined(CONFIG_WIN32_USE_CRYPTO_LIB)) +/* change to processor registers as appropriate */ +#define ENTROPY_POOL_SIZE 32 +#define ENTROPY_COUNTER1 ((((uint64_t)tv.tv_sec)<<32) | tv.tv_usec) +#define ENTROPY_COUNTER2 rand() +static uint8_t entropy_pool[ENTROPY_POOL_SIZE]; +#endif + +const char * const unsupported_str = "Error: Feature not supported\n"; + +#ifndef CONFIG_SSL_SKELETON_MODE +/** + * Retrieve a file and put it into memory + * @return The size of the file, or -1 on failure. + */ +int get_file(const char *filename, uint8_t **buf) +{ + int total_bytes = 0; + int bytes_read = 0; + int filesize; + FILE *stream = fopen(filename, "rb"); + + if (stream == NULL) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("file '%s' does not exist\n", filename); TTY_FLUSH(); +#endif + return -1; + } + + /* Win CE doesn't support stat() */ + fseek(stream, 0, SEEK_END); + filesize = ftell(stream); + *buf = (uint8_t *)malloc(filesize); + fseek(stream, 0, SEEK_SET); + + do + { + bytes_read = fread(*buf+total_bytes, 1, filesize-total_bytes, stream); + total_bytes += bytes_read; + } while (total_bytes < filesize && bytes_read > 0); + + fclose(stream); + return filesize; +} +#endif + +/** + * Initialise the Random Number Generator engine. + * - On Win32 use the platform SDK's crypto engine. + * - On Linux use /dev/urandom + * - If none of these work then use a custom RNG. + */ +#ifdef __GNUC__ +// The stack-entropy-grabbing memcpy() is tagged as an error by gcc +// -fsanitize=undefined. +__attribute__((no_sanitize_address)) +#if __GNUC__ >= 5 +__attribute__((no_sanitize_undefined)) +#endif +#endif +EXP_FUNC void STDCALL RNG_initialize() +{ +#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM) + rng_fd = open("/dev/urandom", O_RDONLY); +#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB) + if (!CryptAcquireContext(&gCryptProv, + NULL, NULL, PROV_RSA_FULL, 0)) + { + if (GetLastError() == NTE_BAD_KEYSET && + !CryptAcquireContext(&gCryptProv, + NULL, + NULL, + PROV_RSA_FULL, + CRYPT_NEWKEYSET)) + { + printf("CryptoLib: %x\n", unsupported_str, GetLastError()); + exit(1); + } + } +#elif !defined(__ets__) + /* start of with a stack to copy across */ + int i = rand(); + memcpy(entropy_pool, &i, ENTROPY_POOL_SIZE); + #ifdef __ANDROID__ + /* Later android releases have rand_r(), but classic ones, e.g. + android-3 (1.5) have jrand48(). */ + jrand48((unsigned short *)entropy_pool); + #else + rand_r((unsigned int *)entropy_pool); + #endif +#endif +} + +/** + * If no /dev/urandom, then initialise the RNG with something interesting. + */ +EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size) +{ +#if defined(WIN32) || defined(CONFIG_WIN32_USE_CRYPTO_LIB) + int i; + + for (i = 0; i < ENTROPY_POOL_SIZE && i < size; i++) + entropy_pool[i] ^= seed_buf[i]; +#endif +} + +/** + * Terminate the RNG engine. + */ +EXP_FUNC void STDCALL RNG_terminate(void) +{ +#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM) + close(rng_fd); +#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB) + CryptReleaseContext(gCryptProv, 0); +#endif +} + +/** + * Set a series of bytes with a random number. Individual bytes can be 0 + */ +EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data) +{ +#if defined(PLATFORM_RNG_U8) + while (num_rand_bytes--) { + *rand_data++ = PLATFORM_RNG_U8(); + } +#elif !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM) + /* use the Linux default - read from /dev/urandom */ + if (read(rng_fd, rand_data, num_rand_bytes) < 0) + return -1; +#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB) + /* use Microsoft Crypto Libraries */ + CryptGenRandom(gCryptProv, num_rand_bytes, rand_data); +#else /* nothing else to use, so use a custom RNG */ + /* The method we use when we've got nothing better. Use RC4, time + and a couple of random seeds to generate a random sequence */ + AES_CTX rng_ctx; + struct timeval tv; + MD5_CTX rng_digest_ctx; + uint8_t digest[MD5_SIZE]; + uint64_t *ep; + int i; + + /* A proper implementation would use counters etc for entropy */ + gettimeofday(&tv, NULL); + ep = (uint64_t *)entropy_pool; + ep[0] ^= ENTROPY_COUNTER1; + ep[1] ^= ENTROPY_COUNTER2; + + /* use a digested version of the entropy pool as a key */ + MD5_Init(&rng_digest_ctx); + MD5_Update(&rng_digest_ctx, entropy_pool, ENTROPY_POOL_SIZE); + MD5_Final(digest, &rng_digest_ctx); + + /* come up with the random sequence */ + AES_set_key(&rng_ctx, digest, (const uint8_t *)ep, AES_MODE_128); /* use as a key */ + memcpy(rand_data, entropy_pool, num_rand_bytes < ENTROPY_POOL_SIZE ? + num_rand_bytes : ENTROPY_POOL_SIZE); + AES_cbc_encrypt(&rng_ctx, rand_data, rand_data, num_rand_bytes); + + /* move things along */ + for (i = ENTROPY_POOL_SIZE-1; i >= MD5_SIZE ; i--) + entropy_pool[i] = entropy_pool[i-MD5_SIZE]; + + /* insert the digest at the start of the entropy pool */ + memcpy(entropy_pool, digest, MD5_SIZE); +#endif + return 0; +} + +/** + * Set a series of bytes with a random number. Individual bytes are not zero. + */ +int get_random_NZ(int num_rand_bytes, uint8_t *rand_data) +{ + int i; + if (get_random(num_rand_bytes, rand_data)) + return -1; + + for (i = 0; i < num_rand_bytes; i++) + { + while (rand_data[i] == 0) /* can't be 0 */ + rand_data[i] = (uint8_t)(rand()); + } + + return 0; +} + +/** + * Some useful diagnostic routines + */ +#if defined(CONFIG_SSL_DIAGNOSTICS) || defined(CONFIG_DEBUG) +int hex_finish; +int hex_index; + +static void print_hex_init(int finish) +{ + hex_finish = finish; + hex_index = 0; +} + +static void print_hex(uint8_t hex) +{ + static int column; + + if (hex_index == 0) + { + column = 0; + } + + printf("%02x ", hex); + if (++column == 8) + { + printf(": "); + } + else if (column >= 16) + { + printf("\n"); + column = 0; + } + + if (++hex_index >= hex_finish && column > 0) + { + printf("\n"); + } +} + +/** + * Spit out a blob of data for diagnostics. The data is is a nice column format + * for easy reading. + * + * @param format [in] The string (with possible embedded format characters) + * @param size [in] The number of numbers to print + * @param data [in] The start of data to use + * @param ... [in] Any additional arguments + */ +EXP_FUNC void STDCALL print_blob(const char *format, + const uint8_t *data, int size, ...) +{ + int i; + char tmp[80]; + va_list(ap); + + va_start(ap, size); + snprintf(tmp, sizeof(tmp), "%s\n", format); + vprintf(tmp, ap); + print_hex_init(size); + for (i = 0; i < size; i++) + { + print_hex(data[i]); + } + + va_end(ap); + TTY_FLUSH(); +} +#elif defined(WIN32) +/* VC6.0 doesn't handle variadic macros */ +EXP_FUNC void STDCALL print_blob(const char *format, const unsigned char *data, + int size, ...) {} +#endif + +#if defined(CONFIG_SSL_HAS_PEM) || defined(CONFIG_HTTP_HAS_AUTHORIZATION) +/* base64 to binary lookup table */ +static const uint8_t map[128] = +{ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, + 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 255, 255, 255, 255, 255 +}; + +EXP_FUNC int STDCALL base64_decode(const char *in, int len, + uint8_t *out, int *outlen) +{ + int g, t, x, y, z; + uint8_t c; + int ret = -1; + + g = 3; + for (x = y = z = t = 0; x < len; x++) + { + if ((c = map[in[x]&0x7F]) == 0xff) + continue; + + if (c == 254) /* this is the end... */ + { + c = 0; + + if (--g < 0) + goto error; + } + else if (g != 3) /* only allow = at end */ + goto error; + + t = (t<<6) | c; + + if (++y == 4) + { + out[z++] = (uint8_t)((t>>16)&255); + + if (g > 1) + out[z++] = (uint8_t)((t>>8)&255); + + if (g > 2) + out[z++] = (uint8_t)(t&255); + + y = t = 0; + } + + /* check that we don't go past the output buffer */ + if (z > *outlen) + goto error; + } + + if (y != 0) + goto error; + + *outlen = z; + ret = 0; + +error: +#ifdef CONFIG_SSL_FULL_MODE + if (ret < 0) + printf("Error: Invalid base64\n"); TTY_FLUSH(); +#endif + TTY_FLUSH(); + return ret; + +} +#endif + diff --git a/circuitpython/lib/axtls/crypto/hmac.c b/circuitpython/lib/axtls/crypto/hmac.c new file mode 100644 index 0000000..ac5bb18 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/hmac.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * HMAC implementation - This code was originally taken from RFC2104 + * See http://www.ietf.org/rfc/rfc2104.txt and + * http://www.faqs.org/rfcs/rfc2202.html + */ + +#include +#include "os_port.h" +#include "crypto.h" + +/** + * Perform HMAC-MD5 + * NOTE: does not handle keys larger than the block size. + */ +void ssl_hmac_md5(const uint8_t *msg, int length, const uint8_t *key, + int key_len, uint8_t *digest) +{ + MD5_CTX context; + uint8_t k_pad[64]; + int i; + + memset(k_pad, 0, sizeof k_pad); + memcpy(k_pad, key, key_len); + for (i = 0; i < 64; i++) + { + k_pad[i] ^= 0x36; + } + + MD5_Init(&context); + MD5_Update(&context, k_pad, 64); + MD5_Update(&context, msg, length); + MD5_Final(digest, &context); + + memset(k_pad, 0, sizeof k_pad); + memcpy(k_pad, key, key_len); + for (i = 0; i < 64; i++) + { + k_pad[i] ^= 0x5c; + } + + MD5_Init(&context); + MD5_Update(&context, k_pad, 64); + MD5_Update(&context, digest, MD5_SIZE); + MD5_Final(digest, &context); +} + +/** + * Perform HMAC-SHA1 + * NOTE: does not handle keys larger than the block size. + */ +void ssl_hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, + int key_len, uint8_t *digest) +{ + SHA1_CTX context; + uint8_t k_pad[64]; + int i; + + memset(k_pad, 0, sizeof k_pad); + memcpy(k_pad, key, key_len); + for (i = 0; i < 64; i++) + { + k_pad[i] ^= 0x36; + } + + SHA1_Init(&context); + SHA1_Update(&context, k_pad, 64); + SHA1_Update(&context, msg, length); + SHA1_Final(digest, &context); + + memset(k_pad, 0, sizeof k_pad); + memcpy(k_pad, key, key_len); + for (i = 0; i < 64; i++) + { + k_pad[i] ^= 0x5c; + } + + SHA1_Init(&context); + SHA1_Update(&context, k_pad, 64); + SHA1_Update(&context, digest, SHA1_SIZE); + SHA1_Final(digest, &context); +} + +/** + * Perform HMAC-SHA256 + * NOTE: does not handle keys larger than the block size. + */ +void hmac_sha256(const uint8_t *msg, int length, const uint8_t *key, + int key_len, uint8_t *digest) +{ + SHA256_CTX context; + uint8_t k_ipad[64]; + uint8_t k_opad[64]; + int i; + + memset(k_ipad, 0, sizeof k_ipad); + memset(k_opad, 0, sizeof k_opad); + memcpy(k_ipad, key, key_len); + memcpy(k_opad, key, key_len); + + for (i = 0; i < 64; i++) + { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + + SHA256_Init(&context); + SHA256_Update(&context, k_ipad, 64); + SHA256_Update(&context, msg, length); + SHA256_Final(digest, &context); + SHA256_Init(&context); + SHA256_Update(&context, k_opad, 64); + SHA256_Update(&context, digest, SHA256_SIZE); + SHA256_Final(digest, &context); +} + diff --git a/circuitpython/lib/axtls/crypto/md5.c b/circuitpython/lib/axtls/crypto/md5.c new file mode 100644 index 0000000..86534c8 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/md5.c @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * This file implements the MD5 algorithm as defined in RFC1321 + */ + +#include +#include "os_port.h" +#include "crypto.h" + +/* Constants for MD5Transform routine. + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +/* ----- static functions ----- */ +static void MD5Transform(uint32_t state[4], const uint8_t block[64]); +static void Encode(uint8_t *output, uint32_t *input, uint32_t len); +static void Decode(uint32_t *output, const uint8_t *input, uint32_t len); + +static const uint8_t PADDING[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* Versions for size-optimized code. */ +#define IDX(v) ((v) & 3) +#define F_(a, i) ((a[IDX(i + 1)] & a[IDX(i + 2)]) | (~a[IDX(i + 1)] & a[IDX(i + 3)])) +#define G_(a, i) ((a[IDX(i + 1)] & a[IDX(i + 3)]) | (a[IDX(i + 2)] & ~a[IDX(i + 3)])) +#define H_(a, i) (a[IDX(i + 1)] ^ a[IDX(i + 2)] ^ a[IDX(i + 3)]) +#define I_(a, i) (a[IDX(i + 2)] ^ (a[IDX(i + 1)] | ~a[IDX(i + 3)])) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + Rotation is separate from addition to prevent recomputation. */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/** + * MD5 initialization - begins an MD5 operation, writing a new ctx. + */ +EXP_FUNC void STDCALL MD5_Init(MD5_CTX *ctx) +{ + ctx->count[0] = ctx->count[1] = 0; + + /* Load magic initialization constants. + */ + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xefcdab89; + ctx->state[2] = 0x98badcfe; + ctx->state[3] = 0x10325476; +} + +/** + * Accepts an array of octets as the next portion of the message. + */ +EXP_FUNC void STDCALL MD5_Update(MD5_CTX *ctx, const uint8_t * msg, int len) +{ + uint32_t x; + int i, partLen; + + /* Compute number of bytes mod 64 */ + x = (uint32_t)((ctx->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((ctx->count[0] += ((uint32_t)len << 3)) < ((uint32_t)len << 3)) + ctx->count[1]++; + ctx->count[1] += ((uint32_t)len >> 29); + + partLen = 64 - x; + + /* Transform as many times as possible. */ + if (len >= partLen) + { + memcpy(&ctx->buffer[x], msg, partLen); + MD5Transform(ctx->state, ctx->buffer); + + for (i = partLen; i + 63 < len; i += 64) + MD5Transform(ctx->state, &msg[i]); + + x = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy(&ctx->buffer[x], &msg[i], len-i); +} + +/** + * Return the 128-bit message digest into the user's array + */ +EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *ctx) +{ + uint8_t bits[8]; + uint32_t x, padLen; + + /* Save number of bits */ + Encode(bits, ctx->count, 8); + + /* Pad out to 56 mod 64. + */ + x = (uint32_t)((ctx->count[0] >> 3) & 0x3f); + padLen = (x < 56) ? (56 - x) : (120 - x); + MD5_Update(ctx, PADDING, padLen); + + /* Append length (before padding) */ + MD5_Update(ctx, bits, 8); + + /* Store state in digest */ + Encode(digest, ctx->state, MD5_SIZE); +} + +/** + * MD5 basic transformation. Transforms state based on block. + */ +#if OPTIMIZE_FOR_SPEED + +static void MD5Transform(uint32_t state[4], const uint8_t block[64]) +{ + uint32_t a = state[0], b = state[1], c = state[2], + d = state[3], x[MD5_SIZE]; + + Decode(x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; +} + +#else + +static void MD5Transform(uint32_t state[4], const uint8_t block[64]) +{ + uint32_t arr[4], x[MD5_SIZE]; + memcpy(arr, state, sizeof(arr)); + + Decode(x, block, 64); + + static const uint32_t round_ac[] = { + 0xd76aa478, /* 1 */ + 0xe8c7b756, /* 2 */ + 0x242070db, /* 3 */ + 0xc1bdceee, /* 4 */ + 0xf57c0faf, /* 5 */ + 0x4787c62a, /* 6 */ + 0xa8304613, /* 7 */ + 0xfd469501, /* 8 */ + 0x698098d8, /* 9 */ + 0x8b44f7af, /* 10 */ + 0xffff5bb1, /* 11 */ + 0x895cd7be, /* 12 */ + 0x6b901122, /* 13 */ + 0xfd987193, /* 14 */ + 0xa679438e, /* 15 */ + 0x49b40821, /* 16 */ + 0xf61e2562, /* 17 */ + 0xc040b340, /* 18 */ + 0x265e5a51, /* 19 */ + 0xe9b6c7aa, /* 20 */ + 0xd62f105d, /* 21 */ + 0x2441453, /* 22 */ + 0xd8a1e681, /* 23 */ + 0xe7d3fbc8, /* 24 */ + 0x21e1cde6, /* 25 */ + 0xc33707d6, /* 26 */ + 0xf4d50d87, /* 27 */ + 0x455a14ed, /* 28 */ + 0xa9e3e905, /* 29 */ + 0xfcefa3f8, /* 30 */ + 0x676f02d9, /* 31 */ + 0x8d2a4c8a, /* 32 */ + 0xfffa3942, /* 33 */ + 0x8771f681, /* 34 */ + 0x6d9d6122, /* 35 */ + 0xfde5380c, /* 36 */ + 0xa4beea44, /* 37 */ + 0x4bdecfa9, /* 38 */ + 0xf6bb4b60, /* 39 */ + 0xbebfbc70, /* 40 */ + 0x289b7ec6, /* 41 */ + 0xeaa127fa, /* 42 */ + 0xd4ef3085, /* 43 */ + 0x4881d05, /* 44 */ + 0xd9d4d039, /* 45 */ + 0xe6db99e5, /* 46 */ + 0x1fa27cf8, /* 47 */ + 0xc4ac5665, /* 48 */ + 0xf4292244, /* 49 */ + 0x432aff97, /* 50 */ + 0xab9423a7, /* 51 */ + 0xfc93a039, /* 52 */ + 0x655b59c3, /* 53 */ + 0x8f0ccc92, /* 54 */ + 0xffeff47d, /* 55 */ + 0x85845dd1, /* 56 */ + 0x6fa87e4f, /* 57 */ + 0xfe2ce6e0, /* 58 */ + 0xa3014314, /* 59 */ + 0x4e0811a1, /* 60 */ + 0xf7537e82, /* 61 */ + 0xbd3af235, /* 62 */ + 0x2ad7d2bb, /* 63 */ + 0xeb86d391, /* 64 */ + }; + + static const uint8_t round1_s[] = { + 7, 12, 17, 22, + 5, 9, 14, 20, + 4, 11, 16, 23, + 6, 10, 15, 21, + }; + + static const uint8_t round_order[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, + }; + + unsigned i; + + const uint8_t *round_s = round1_s - 4; + for (i = 0; i < 64; i++) { + int off = IDX(4 - i); + uint32_t v; + + // Code size is bigger + //round_s = round1_s + (i >> 4) * 4; + if ((i & 15) == 0) { + round_s += 4; + } + + if (i < 32) { + if (i < 16) { + v = F_(arr, off); + } else { + v = G_(arr, off); + } + } else { + if (i < 48) { + v = H_(arr, off); + } else { + v = I_(arr, off); + } + } + v += arr[off]; + v += x[round_order[i]] + round_ac[i]; + v = ROTATE_LEFT(v, round_s[i & 3]); + v += arr[IDX(off + 1)]; + arr[off] = v; + } + + state[0] += arr[0]; + state[1] += arr[1]; + state[2] += arr[2]; + state[3] += arr[3]; +} +#endif // OPTIMIZE_FOR_SPEED + +/** + * Encodes input (uint32_t) into output (uint8_t). Assumes len is + * a multiple of 4. + */ +static void Encode(uint8_t *output, uint32_t *input, uint32_t len) +{ + uint32_t i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + { + output[j] = (uint8_t)(input[i] & 0xff); + output[j+1] = (uint8_t)((input[i] >> 8) & 0xff); + output[j+2] = (uint8_t)((input[i] >> 16) & 0xff); + output[j+3] = (uint8_t)((input[i] >> 24) & 0xff); + } +} + +/** + * Decodes input (uint8_t) into output (uint32_t). Assumes len is + * a multiple of 4. + */ +static void Decode(uint32_t *output, const uint8_t *input, uint32_t len) +{ + uint32_t i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | + (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24); +} diff --git a/circuitpython/lib/axtls/crypto/os_int.h b/circuitpython/lib/axtls/crypto/os_int.h new file mode 100644 index 0000000..a849e5b --- /dev/null +++ b/circuitpython/lib/axtls/crypto/os_int.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * @file os_int.h + * + * Ensure a consistent bit size + */ + +#ifndef HEADER_OS_INT_H +#define HEADER_OS_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) +typedef UINT8 uint8_t; +typedef INT8 int8_t; +typedef UINT16 uint16_t; +typedef INT16 int16_t; +typedef UINT32 uint32_t; +typedef INT32 int32_t; +typedef UINT64 uint64_t; +typedef INT64 int64_t; +#else /* Not Win32 */ + +#ifdef CONFIG_PLATFORM_SOLARIS +#include +#else +#include +#endif /* Not Solaris */ + +#endif /* Not Win32 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/axtls/crypto/rc4.c b/circuitpython/lib/axtls/crypto/rc4.c new file mode 100644 index 0000000..edfb27a --- /dev/null +++ b/circuitpython/lib/axtls/crypto/rc4.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * An implementation of the RC4/ARC4 algorithm. + * Originally written by Christophe Devine. + */ + +#include +#include "os_port.h" +#include "crypto.h" + +/* only used for PKCS12 now */ +#ifdef CONFIG_SSL_USE_PKCS12 + +/** + * Get ready for an encrypt/decrypt operation + */ +void RC4_setup(RC4_CTX *ctx, const uint8_t *key, int length) +{ + int i, j = 0, k = 0, a; + uint8_t *m; + + ctx->x = 0; + ctx->y = 0; + m = ctx->m; + + for (i = 0; i < 256; i++) + m[i] = i; + + for (i = 0; i < 256; i++) + { + a = m[i]; + j = (uint8_t)(j + a + key[k]); + m[i] = m[j]; + m[j] = a; + + if (++k >= length) + k = 0; + } +} + +/** + * Perform the encrypt/decrypt operation (can use it for either since + * this is a stream cipher). + * NOTE: *msg and *out must be the same pointer (performance tweak) + */ +void RC4_crypt(RC4_CTX *ctx, const uint8_t *msg, uint8_t *out, int length) +{ + int i; + uint8_t *m, x, y, a, b; + + x = ctx->x; + y = ctx->y; + m = ctx->m; + + for (i = 0; i < length; i++) + { + a = m[++x]; + y += a; + m[x] = b = m[y]; + m[y] = a; + out[i] ^= m[(uint8_t)(a + b)]; + } + + ctx->x = x; + ctx->y = y; +} + +#endif diff --git a/circuitpython/lib/axtls/crypto/rsa.c b/circuitpython/lib/axtls/crypto/rsa.c new file mode 100644 index 0000000..742cd71 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/rsa.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2007-2014, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Implements the RSA public encryption algorithm. Uses the bigint library to + * perform its calculations. + */ + +#include +#include +#include +#include +#include "os_port.h" +#include "crypto.h" + +void RSA_priv_key_new(RSA_CTX **ctx, + const uint8_t *modulus, int mod_len, + const uint8_t *pub_exp, int pub_len, + const uint8_t *priv_exp, int priv_len +#if CONFIG_BIGINT_CRT + , const uint8_t *p, int p_len, + const uint8_t *q, int q_len, + const uint8_t *dP, int dP_len, + const uint8_t *dQ, int dQ_len, + const uint8_t *qInv, int qInv_len +#endif + ) +{ + RSA_CTX *rsa_ctx; + BI_CTX *bi_ctx; + RSA_pub_key_new(ctx, modulus, mod_len, pub_exp, pub_len); + rsa_ctx = *ctx; + bi_ctx = rsa_ctx->bi_ctx; + rsa_ctx->d = bi_import(bi_ctx, priv_exp, priv_len); + bi_permanent(rsa_ctx->d); + +#ifdef CONFIG_BIGINT_CRT + rsa_ctx->p = bi_import(bi_ctx, p, p_len); + rsa_ctx->q = bi_import(bi_ctx, q, q_len); + rsa_ctx->dP = bi_import(bi_ctx, dP, dP_len); + rsa_ctx->dQ = bi_import(bi_ctx, dQ, dQ_len); + rsa_ctx->qInv = bi_import(bi_ctx, qInv, qInv_len); + bi_permanent(rsa_ctx->dP); + bi_permanent(rsa_ctx->dQ); + bi_permanent(rsa_ctx->qInv); + bi_set_mod(bi_ctx, rsa_ctx->p, BIGINT_P_OFFSET); + bi_set_mod(bi_ctx, rsa_ctx->q, BIGINT_Q_OFFSET); +#endif +} + +void RSA_pub_key_new(RSA_CTX **ctx, + const uint8_t *modulus, int mod_len, + const uint8_t *pub_exp, int pub_len) +{ + RSA_CTX *rsa_ctx; + BI_CTX *bi_ctx; + + if (*ctx) /* if we load multiple certs, dump the old one */ + RSA_free(*ctx); + + bi_ctx = bi_initialize(); + *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX)); + rsa_ctx = *ctx; + rsa_ctx->bi_ctx = bi_ctx; + rsa_ctx->num_octets = mod_len; + rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len); + bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET); + rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len); + bi_permanent(rsa_ctx->e); +} + +/** + * Free up any RSA context resources. + */ +void RSA_free(RSA_CTX *rsa_ctx) +{ + BI_CTX *bi_ctx; + if (rsa_ctx == NULL) /* deal with ptrs that are null */ + return; + + bi_ctx = rsa_ctx->bi_ctx; + + bi_depermanent(rsa_ctx->e); + bi_free(bi_ctx, rsa_ctx->e); + bi_free_mod(rsa_ctx->bi_ctx, BIGINT_M_OFFSET); + + if (rsa_ctx->d) + { + bi_depermanent(rsa_ctx->d); + bi_free(bi_ctx, rsa_ctx->d); +#ifdef CONFIG_BIGINT_CRT + bi_depermanent(rsa_ctx->dP); + bi_depermanent(rsa_ctx->dQ); + bi_depermanent(rsa_ctx->qInv); + bi_free(bi_ctx, rsa_ctx->dP); + bi_free(bi_ctx, rsa_ctx->dQ); + bi_free(bi_ctx, rsa_ctx->qInv); + bi_free_mod(rsa_ctx->bi_ctx, BIGINT_P_OFFSET); + bi_free_mod(rsa_ctx->bi_ctx, BIGINT_Q_OFFSET); +#endif + } + + bi_terminate(bi_ctx); + free(rsa_ctx); +} + +/** + * @brief Use PKCS1.5 for decryption/verification. + * @param ctx [in] The context + * @param in_data [in] The data to decrypt (must be < modulus size-11) + * @param out_data [out] The decrypted data. + * @param out_len [int] The size of the decrypted buffer in bytes + * @param is_decryption [in] Decryption or verify operation. + * @return The number of bytes that were originally encrypted. -1 on error. + * @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125 + */ +int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, + uint8_t *out_data, int out_len, int is_decryption) +{ + const int byte_size = ctx->num_octets; + int i = 0, size; + bigint *decrypted_bi, *dat_bi; + uint8_t *block = (uint8_t *)alloca(byte_size); + int pad_count = 0; + + if (out_len < byte_size) /* check output has enough size */ + return -1; + + memset(out_data, 0, out_len); /* initialise */ + + /* decrypt */ + dat_bi = bi_import(ctx->bi_ctx, in_data, byte_size); +#ifdef CONFIG_SSL_CERT_VERIFICATION + decrypted_bi = is_decryption ? /* decrypt or verify? */ + RSA_private(ctx, dat_bi) : RSA_public(ctx, dat_bi); +#else /* always a decryption */ + decrypted_bi = RSA_private(ctx, dat_bi); +#endif + + /* convert to a normal block */ + bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size); + + if (block[i++] != 0) /* leading 0? */ + return -1; + +#ifdef CONFIG_SSL_CERT_VERIFICATION + if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */ + { + if (block[i++] != 0x01) /* BT correct? */ + return -1; + + while (block[i++] == 0xff && i < byte_size) + pad_count++; + } + else /* PKCS1.5 encryption padding is random */ +#endif + { + if (block[i++] != 0x02) /* BT correct? */ + return -1; + + while (block[i++] && i < byte_size) + pad_count++; + } + + /* check separator byte 0x00 - and padding must be 8 or more bytes */ + if (i == byte_size || pad_count < 8) + return -1; + + size = byte_size - i; + + /* get only the bit we want */ + memcpy(out_data, &block[i], size); + return size; +} + +/** + * Performs m = c^d mod n + */ +bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg) +{ +#ifdef CONFIG_BIGINT_CRT + return bi_crt(c->bi_ctx, bi_msg, c->dP, c->dQ, c->p, c->q, c->qInv); +#else + BI_CTX *ctx = c->bi_ctx; + ctx->mod_offset = BIGINT_M_OFFSET; + return bi_mod_power(ctx, bi_msg, c->d); +#endif +} + +#ifdef CONFIG_SSL_FULL_MODE +/** + * Used for diagnostics. + */ +void RSA_print(const RSA_CTX *rsa_ctx) +{ + if (rsa_ctx == NULL) + return; + + printf("----------------- RSA DEBUG ----------------\n"); + printf("Size:\t%d\n", rsa_ctx->num_octets); + bi_print("Modulus", rsa_ctx->m); + bi_print("Public Key", rsa_ctx->e); + bi_print("Private Key", rsa_ctx->d); +} +#endif + +#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT) || (CONFIG_SSL_ENABLE_CLIENT) +/** + * Performs c = m^e mod n + */ +bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg) +{ + c->bi_ctx->mod_offset = BIGINT_M_OFFSET; + return bi_mod_power(c->bi_ctx, bi_msg, c->e); +} + +/** + * Use PKCS1.5 for encryption/signing. + * see http://www.rsasecurity.com/rsalabs/node.asp?id=2125 + */ +int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, + uint8_t *out_data, int is_signing) +{ + int byte_size = ctx->num_octets; + int num_pads_needed = byte_size-in_len-3; + bigint *dat_bi, *encrypt_bi; + + /* note: in_len+11 must be > byte_size */ + out_data[0] = 0; /* ensure encryption block is < modulus */ + + if (is_signing) + { + out_data[1] = 1; /* PKCS1.5 signing pads with "0xff"'s */ + memset(&out_data[2], 0xff, num_pads_needed); + } + else /* randomize the encryption padding with non-zero bytes */ + { + out_data[1] = 2; + if (get_random_NZ(num_pads_needed, &out_data[2]) < 0) + return -1; + } + + out_data[2+num_pads_needed] = 0; + memcpy(&out_data[3+num_pads_needed], in_data, in_len); + + /* now encrypt it */ + dat_bi = bi_import(ctx->bi_ctx, out_data, byte_size); + encrypt_bi = is_signing ? RSA_private(ctx, dat_bi) : + RSA_public(ctx, dat_bi); + bi_export(ctx->bi_ctx, encrypt_bi, out_data, byte_size); + + /* save a few bytes of memory */ + bi_clear_cache(ctx->bi_ctx); + return byte_size; +} + +#endif /* CONFIG_SSL_CERT_VERIFICATION */ diff --git a/circuitpython/lib/axtls/crypto/sha1.c b/circuitpython/lib/axtls/crypto/sha1.c new file mode 100644 index 0000000..097302a --- /dev/null +++ b/circuitpython/lib/axtls/crypto/sha1.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995. + * This code was originally taken from RFC3174 + */ + +#include +#include "os_port.h" +#include "crypto.h" + +/* + * Define the SHA1 circular left shift macro + */ +#define SHA1CircularShift(bits,word) \ + (((word) << (bits)) | ((word) >> (32-(bits)))) + +/* ----- static functions ----- */ +static void SHA1PadMessage(SHA1_CTX *ctx); +static void SHA1ProcessMessageBlock(SHA1_CTX *ctx); + +/** + * Initialize the SHA1 context + */ +void SHA1_Init(SHA1_CTX *ctx) +{ + ctx->Length_Low = 0; + ctx->Length_High = 0; + ctx->Message_Block_Index = 0; + ctx->Intermediate_Hash[0] = 0x67452301; + ctx->Intermediate_Hash[1] = 0xEFCDAB89; + ctx->Intermediate_Hash[2] = 0x98BADCFE; + ctx->Intermediate_Hash[3] = 0x10325476; + ctx->Intermediate_Hash[4] = 0xC3D2E1F0; +} + +/** + * Accepts an array of octets as the next portion of the message. + */ +void SHA1_Update(SHA1_CTX *ctx, const uint8_t *msg, int len) +{ + while (len--) + { + ctx->Message_Block[ctx->Message_Block_Index++] = (*msg & 0xFF); + ctx->Length_Low += 8; + + if (ctx->Length_Low == 0) + ctx->Length_High++; + + if (ctx->Message_Block_Index == 64) + SHA1ProcessMessageBlock(ctx); + + msg++; + } +} + +/** + * Return the 160-bit message digest into the user's array + */ +void SHA1_Final(uint8_t *digest, SHA1_CTX *ctx) +{ + int i; + + SHA1PadMessage(ctx); + memset(ctx->Message_Block, 0, 64); + ctx->Length_Low = 0; /* and clear length */ + ctx->Length_High = 0; + + for (i = 0; i < SHA1_SIZE; i++) + { + digest[i] = ctx->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ); + } +} + +/** + * Process the next 512 bits of the message stored in the array. + */ +static void SHA1ProcessMessageBlock(SHA1_CTX *ctx) +{ + const uint32_t K[] = { /* Constants defined in SHA-1 */ + 0x5A827999, + 0x6ED9EBA1, + 0x8F1BBCDC, + 0xCA62C1D6 + }; + int t; /* Loop counter */ + uint32_t temp; /* Temporary word value */ + uint32_t W[80]; /* Word sequence */ + uint32_t A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array W + */ + for (t = 0; t < 16; t++) + { + W[t] = (uint32_t)ctx->Message_Block[t * 4] << 24; + W[t] |= ctx->Message_Block[t * 4 + 1] << 16; + W[t] |= ctx->Message_Block[t * 4 + 2] << 8; + W[t] |= ctx->Message_Block[t * 4 + 3]; + } + + for (t = 16; t < 80; t++) + { + W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + } + + A = ctx->Intermediate_Hash[0]; + B = ctx->Intermediate_Hash[1]; + C = ctx->Intermediate_Hash[2]; + D = ctx->Intermediate_Hash[3]; + E = ctx->Intermediate_Hash[4]; + + for (t = 0; t < 20; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + + B = A; + A = temp; + } + + for (t = 20; t < 40; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for (t = 40; t < 60; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for (t = 60; t < 80; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + ctx->Intermediate_Hash[0] += A; + ctx->Intermediate_Hash[1] += B; + ctx->Intermediate_Hash[2] += C; + ctx->Intermediate_Hash[3] += D; + ctx->Intermediate_Hash[4] += E; + ctx->Message_Block_Index = 0; +} + +/* + * According to the standard, the message must be padded to an even + * 512 bits. The first padding bit must be a '1'. The last 64 + * bits represent the length of the original message. All bits in + * between should be 0. This function will pad the message + * according to those rules by filling the Message_Block array + * accordingly. It will also call the ProcessMessageBlock function + * provided appropriately. When it returns, it can be assumed that + * the message digest has been computed. + * + * @param ctx [in, out] The SHA1 context + */ +static void SHA1PadMessage(SHA1_CTX *ctx) +{ + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + */ + if (ctx->Message_Block_Index > 55) + { + ctx->Message_Block[ctx->Message_Block_Index++] = 0x80; + while(ctx->Message_Block_Index < 64) + { + ctx->Message_Block[ctx->Message_Block_Index++] = 0; + } + + SHA1ProcessMessageBlock(ctx); + + while (ctx->Message_Block_Index < 56) + { + ctx->Message_Block[ctx->Message_Block_Index++] = 0; + } + } + else + { + ctx->Message_Block[ctx->Message_Block_Index++] = 0x80; + while(ctx->Message_Block_Index < 56) + { + + ctx->Message_Block[ctx->Message_Block_Index++] = 0; + } + } + + /* + * Store the message length as the last 8 octets + */ + ctx->Message_Block[56] = ctx->Length_High >> 24; + ctx->Message_Block[57] = ctx->Length_High >> 16; + ctx->Message_Block[58] = ctx->Length_High >> 8; + ctx->Message_Block[59] = ctx->Length_High; + ctx->Message_Block[60] = ctx->Length_Low >> 24; + ctx->Message_Block[61] = ctx->Length_Low >> 16; + ctx->Message_Block[62] = ctx->Length_Low >> 8; + ctx->Message_Block[63] = ctx->Length_Low; + SHA1ProcessMessageBlock(ctx); +} diff --git a/circuitpython/lib/axtls/crypto/sha256.c b/circuitpython/lib/axtls/crypto/sha256.c new file mode 100644 index 0000000..e15e315 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/sha256.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2015, Cameron Rich + * + * 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 axTLS project 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 +#include "os_port.h" +#include "crypto.h" + +#ifndef SHA256_CTX + +#define GET_UINT32(n,b,i) \ +{ \ + (n) = ((uint32_t) (b)[(i) ] << 24) \ + | ((uint32_t) (b)[(i) + 1] << 16) \ + | ((uint32_t) (b)[(i) + 2] << 8) \ + | ((uint32_t) (b)[(i) + 3] ); \ +} + +#define PUT_UINT32(n,b,i) \ +{ \ + (b)[(i) ] = (uint8_t) ((n) >> 24); \ + (b)[(i) + 1] = (uint8_t) ((n) >> 16); \ + (b)[(i) + 2] = (uint8_t) ((n) >> 8); \ + (b)[(i) + 3] = (uint8_t) ((n) ); \ +} + +static const uint8_t sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/** + * Initialize the SHA256 context + */ +void SHA256_Init(SHA256_CTX *ctx) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; +} + +static void SHA256_Process(const uint8_t digest[64], SHA256_CTX *ctx) +{ + uint32_t temp1, temp2, W[64]; + uint32_t A, B, C, D, E, F, G, H; + + GET_UINT32(W[0], digest, 0); + GET_UINT32(W[1], digest, 4); + GET_UINT32(W[2], digest, 8); + GET_UINT32(W[3], digest, 12); + GET_UINT32(W[4], digest, 16); + GET_UINT32(W[5], digest, 20); + GET_UINT32(W[6], digest, 24); + GET_UINT32(W[7], digest, 28); + GET_UINT32(W[8], digest, 32); + GET_UINT32(W[9], digest, 36); + GET_UINT32(W[10], digest, 40); + GET_UINT32(W[11], digest, 44); + GET_UINT32(W[12], digest, 48); + GET_UINT32(W[13], digest, 52); + GET_UINT32(W[14], digest, 56); + GET_UINT32(W[15], digest, 60); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) \ +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + P(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); + P(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); + P(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF); + P(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5); + P(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B); + P(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1); + P(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4); + P(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5); + P(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98); + P(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01); + P(G, H, A, B, C, D, E, F, W[10], 0x243185BE); + P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); + P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); + P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); + P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); + P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); + P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); + P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); + P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); + P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); + P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); + P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); + P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); + P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA); + P(A, B, C, D, E, F, G, H, R(24), 0x983E5152); + P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D); + P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8); + P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); + P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); + P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147); + P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351); + P(B, C, D, E, F, G, H, A, R(31), 0x14292967); + P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85); + P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); + P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); + P(F, G, H, A, B, C, D, E, R(35), 0x53380D13); + P(E, F, G, H, A, B, C, D, R(36), 0x650A7354); + P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); + P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); + P(B, C, D, E, F, G, H, A, R(39), 0x92722C85); + P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); + P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B); + P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); + P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); + P(E, F, G, H, A, B, C, D, R(44), 0xD192E819); + P(D, E, F, G, H, A, B, C, R(45), 0xD6990624); + P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585); + P(B, C, D, E, F, G, H, A, R(47), 0x106AA070); + P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116); + P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08); + P(G, H, A, B, C, D, E, F, R(50), 0x2748774C); + P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); + P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); + P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); + P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); + P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); + P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE); + P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F); + P(G, H, A, B, C, D, E, F, R(58), 0x84C87814); + P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208); + P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); + P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); + P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); + P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +/** + * Accepts an array of octets as the next portion of the message. + */ +void SHA256_Update(SHA256_CTX *ctx, const uint8_t * msg, int len) +{ + uint32_t left = ctx->total[0] & 0x3F; + uint32_t fill = 64 - left; + + ctx->total[0] += len; + ctx->total[0] &= 0xFFFFFFFF; + + if (ctx->total[0] < len) + ctx->total[1]++; + + if (left && len >= fill) + { + memcpy((void *) (ctx->buffer + left), (void *)msg, fill); + SHA256_Process(ctx->buffer, ctx); + len -= fill; + msg += fill; + left = 0; + } + + while (len >= 64) + { + SHA256_Process(msg, ctx); + len -= 64; + msg += 64; + } + + if (len) + { + memcpy((void *) (ctx->buffer + left), (void *) msg, len); + } +} + +/** + * Return the 256-bit message digest into the user's array + */ +void SHA256_Final(uint8_t *digest, SHA256_CTX *ctx) +{ + uint32_t last, padn; + uint32_t high, low; + uint8_t msglen[8]; + + high = (ctx->total[0] >> 29) + | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + PUT_UINT32(high, msglen, 0); + PUT_UINT32(low, msglen, 4); + + last = ctx->total[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + SHA256_Update(ctx, sha256_padding, padn); + SHA256_Update(ctx, msglen, 8); + + PUT_UINT32(ctx->state[0], digest, 0); + PUT_UINT32(ctx->state[1], digest, 4); + PUT_UINT32(ctx->state[2], digest, 8); + PUT_UINT32(ctx->state[3], digest, 12); + PUT_UINT32(ctx->state[4], digest, 16); + PUT_UINT32(ctx->state[5], digest, 20); + PUT_UINT32(ctx->state[6], digest, 24); + PUT_UINT32(ctx->state[7], digest, 28); +} + +#endif // SHA256_CTX diff --git a/circuitpython/lib/axtls/crypto/sha384.c b/circuitpython/lib/axtls/crypto/sha384.c new file mode 100644 index 0000000..f1071be --- /dev/null +++ b/circuitpython/lib/axtls/crypto/sha384.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, Cameron Rich + * + * 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 axTLS project 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 +#include "os_port.h" +#include "crypto.h" + +/** +* Initialize the SHA384 context +*/ + void SHA384_Init(SHA384_CTX *ctx) + { + //Set initial hash value + ctx->h_dig.h[0] = 0xCBBB9D5DC1059ED8LL; + ctx->h_dig.h[1] = 0x629A292A367CD507LL; + ctx->h_dig.h[2] = 0x9159015A3070DD17LL; + ctx->h_dig.h[3] = 0x152FECD8F70E5939LL; + ctx->h_dig.h[4] = 0x67332667FFC00B31LL; + ctx->h_dig.h[5] = 0x8EB44A8768581511LL; + ctx->h_dig.h[6] = 0xDB0C2E0D64F98FA7LL; + ctx->h_dig.h[7] = 0x47B5481DBEFA4FA4LL; + + // Number of bytes in the buffer + ctx->size = 0; + // Total length of the message + ctx->totalSize = 0; + } + +/** +* Accepts an array of octets as the next portion of the message. +*/ +void SHA384_Update(SHA384_CTX *ctx, const uint8_t * msg, int len) +{ + // The function is defined in the exact same manner as SHA-512 + SHA512_Update(ctx, msg, len); +} + +/** +* Return the 384-bit message digest into the user's array +*/ +void SHA384_Final(uint8_t *digest, SHA384_CTX *ctx) +{ + // The function is defined in the exact same manner as SHA-512 + SHA512_Final(NULL, ctx); + + // Copy the resulting digest + if (digest != NULL) + memcpy(digest, ctx->h_dig.digest, SHA384_SIZE); +} + diff --git a/circuitpython/lib/axtls/crypto/sha512.c b/circuitpython/lib/axtls/crypto/sha512.c new file mode 100644 index 0000000..aa2f589 --- /dev/null +++ b/circuitpython/lib/axtls/crypto/sha512.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2015, Cameron Rich + * + * 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 axTLS project 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 +#include "os_port.h" +#include "crypto.h" + +#define SHR64(a, n) ((a) >> (n)) +#define ROR64(a, n) (((a) >> (n)) | ((a) << (64 - (n)))) +#define CH(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define MAJ(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define SIGMA1(x) (ROR64(x, 28) ^ ROR64(x, 34) ^ ROR64(x, 39)) +#define SIGMA2(x) (ROR64(x, 14) ^ ROR64(x, 18) ^ ROR64(x, 41)) +#define SIGMA3(x) (ROR64(x, 1) ^ ROR64(x, 8) ^ SHR64(x, 7)) +#define SIGMA4(x) (ROR64(x, 19) ^ ROR64(x, 61) ^ SHR64(x, 6)) +#define MIN(x, y) ((x) < (y) ? x : y) + +static const uint8_t padding[128] = +{ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint64_t k[80] = +{ + 0x428A2F98D728AE22LL, 0x7137449123EF65CDLL, 0xB5C0FBCFEC4D3B2FLL, 0xE9B5DBA58189DBBCLL, + 0x3956C25BF348B538LL, 0x59F111F1B605D019LL, 0x923F82A4AF194F9BLL, 0xAB1C5ED5DA6D8118LL, + 0xD807AA98A3030242LL, 0x12835B0145706FBELL, 0x243185BE4EE4B28CLL, 0x550C7DC3D5FFB4E2LL, + 0x72BE5D74F27B896FLL, 0x80DEB1FE3B1696B1LL, 0x9BDC06A725C71235LL, 0xC19BF174CF692694LL, + 0xE49B69C19EF14AD2LL, 0xEFBE4786384F25E3LL, 0x0FC19DC68B8CD5B5LL, 0x240CA1CC77AC9C65LL, + 0x2DE92C6F592B0275LL, 0x4A7484AA6EA6E483LL, 0x5CB0A9DCBD41FBD4LL, 0x76F988DA831153B5LL, + 0x983E5152EE66DFABLL, 0xA831C66D2DB43210LL, 0xB00327C898FB213FLL, 0xBF597FC7BEEF0EE4LL, + 0xC6E00BF33DA88FC2LL, 0xD5A79147930AA725LL, 0x06CA6351E003826FLL, 0x142929670A0E6E70LL, + 0x27B70A8546D22FFCLL, 0x2E1B21385C26C926LL, 0x4D2C6DFC5AC42AEDLL, 0x53380D139D95B3DFLL, + 0x650A73548BAF63DELL, 0x766A0ABB3C77B2A8LL, 0x81C2C92E47EDAEE6LL, 0x92722C851482353BLL, + 0xA2BFE8A14CF10364LL, 0xA81A664BBC423001LL, 0xC24B8B70D0F89791LL, 0xC76C51A30654BE30LL, + 0xD192E819D6EF5218LL, 0xD69906245565A910LL, 0xF40E35855771202ALL, 0x106AA07032BBD1B8LL, + 0x19A4C116B8D2D0C8LL, 0x1E376C085141AB53LL, 0x2748774CDF8EEB99LL, 0x34B0BCB5E19B48A8LL, + 0x391C0CB3C5C95A63LL, 0x4ED8AA4AE3418ACBLL, 0x5B9CCA4F7763E373LL, 0x682E6FF3D6B2B8A3LL, + 0x748F82EE5DEFB2FCLL, 0x78A5636F43172F60LL, 0x84C87814A1F0AB72LL, 0x8CC702081A6439ECLL, + 0x90BEFFFA23631E28LL, 0xA4506CEBDE82BDE9LL, 0xBEF9A3F7B2C67915LL, 0xC67178F2E372532BLL, + 0xCA273ECEEA26619CLL, 0xD186B8C721C0C207LL, 0xEADA7DD6CDE0EB1ELL, 0xF57D4F7FEE6ED178LL, + 0x06F067AA72176FBALL, 0x0A637DC5A2C898A6LL, 0x113F9804BEF90DAELL, 0x1B710B35131C471BLL, + 0x28DB77F523047D84LL, 0x32CAAB7B40C72493LL, 0x3C9EBE0A15C9BEBCLL, 0x431D67C49C100D4CLL, + 0x4CC5D4BECB3E42B6LL, 0x597F299CFC657E2ALL, 0x5FCB6FAB3AD6FAECLL, 0x6C44198C4A475817LL +}; + +/** +* Initialize the SHA512 context +*/ +void SHA512_Init(SHA512_CTX *ctx) +{ + ctx->h_dig.h[0] = 0x6A09E667F3BCC908LL; + ctx->h_dig.h[1] = 0xBB67AE8584CAA73BLL; + ctx->h_dig.h[2] = 0x3C6EF372FE94F82BLL; + ctx->h_dig.h[3] = 0xA54FF53A5F1D36F1LL; + ctx->h_dig.h[4] = 0x510E527FADE682D1LL; + ctx->h_dig.h[5] = 0x9B05688C2B3E6C1FLL; + ctx->h_dig.h[6] = 0x1F83D9ABFB41BD6BLL; + ctx->h_dig.h[7] = 0x5BE0CD19137E2179LL; + ctx->size = 0; + ctx->totalSize = 0; +} + +static void SHA512_Process(SHA512_CTX *ctx) +{ + int t; + uint64_t temp1; + uint64_t temp2; + + // Initialize the 8 working registers + uint64_t a = ctx->h_dig.h[0]; + uint64_t b = ctx->h_dig.h[1]; + uint64_t c = ctx->h_dig.h[2]; + uint64_t d = ctx->h_dig.h[3]; + uint64_t e = ctx->h_dig.h[4]; + uint64_t f = ctx->h_dig.h[5]; + uint64_t g = ctx->h_dig.h[6]; + uint64_t h = ctx->h_dig.h[7]; + + // Process message in 16-word blocks + uint64_t *w = ctx->w_buf.w; + + // Convert from big-endian byte order to host byte order + for (t = 0; t < 16; t++) + w[t] = be64toh(w[t]); + + // Prepare the message schedule + for (t = 16; t < 80; t++) + w[t] = SIGMA4(w[t - 2]) + w[t - 7] + SIGMA3(w[t - 15]) + w[t - 16]; + + // SHA-512 hash computation + for (t = 0; t < 80; t++) + { + // Calculate T1 and T2 + temp1 = h + SIGMA2(e) + CH(e, f, g) + k[t] + w[t]; + temp2 = SIGMA1(a) + MAJ(a, b, c); + + // Update the working registers + h = g; + g = f; + f = e; + e = d + temp1; + d = c; + c = b; + b = a; + a = temp1 + temp2; + } + + // Update the hash value + ctx->h_dig.h[0] += a; + ctx->h_dig.h[1] += b; + ctx->h_dig.h[2] += c; + ctx->h_dig.h[3] += d; + ctx->h_dig.h[4] += e; + ctx->h_dig.h[5] += f; + ctx->h_dig.h[6] += g; + ctx->h_dig.h[7] += h; + } + +/** +* Accepts an array of octets as the next portion of the message. +*/ +void SHA512_Update(SHA512_CTX *ctx, const uint8_t * msg, int len) +{ + // Process the incoming data + while (len > 0) + { + // The buffer can hold at most 128 bytes + size_t n = MIN(len, 128 - ctx->size); + + // Copy the data to the buffer + memcpy(ctx->w_buf.buffer + ctx->size, msg, n); + + // Update the SHA-512 ctx + ctx->size += n; + ctx->totalSize += n; + // Advance the data pointer + msg = (uint8_t *) msg + n; + // Remaining bytes to process + len -= n; + + // Process message in 16-word blocks + if (ctx->size == 128) + { + // Transform the 16-word block + SHA512_Process(ctx); + // Empty the buffer + ctx->size = 0; + } + } +} + +/** +* Return the 512-bit message digest into the user's array +*/ +void SHA512_Final(uint8_t *digest, SHA512_CTX *ctx) +{ + int i; + size_t paddingSize; + uint64_t totalSize; + + // Length of the original message (before padding) + totalSize = ctx->totalSize * 8; + + // Pad the message so that its length is congruent to 112 modulo 128 + paddingSize = (ctx->size < 112) ? (112 - ctx->size) : + (128 + 112 - ctx->size); + // Append padding + SHA512_Update(ctx, padding, paddingSize); + + // Append the length of the original message + ctx->w_buf.w[14] = 0; + ctx->w_buf.w[15] = be64toh(totalSize); + + // Calculate the message digest + SHA512_Process(ctx); + + // Convert from host byte order to big-endian byte order + for (i = 0; i < 8; i++) + ctx->h_dig.h[i] = be64toh(ctx->h_dig.h[i]); + + // Copy the resulting digest + if (digest != NULL) + memcpy(digest, ctx->h_dig.digest, SHA512_SIZE); + } + diff --git a/circuitpython/lib/axtls/docsrc/Makefile b/circuitpython/lib/axtls/docsrc/Makefile new file mode 100644 index 0000000..2826686 --- /dev/null +++ b/circuitpython/lib/axtls/docsrc/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 ../config/makefile.conf + +all: + +doco: + doxygen ./axTLS.dox + +clean:: + @-rm -fr html *~ diff --git a/circuitpython/lib/axtls/docsrc/axTLS.dox b/circuitpython/lib/axtls/docsrc/axTLS.dox new file mode 100644 index 0000000..bca7d81 --- /dev/null +++ b/circuitpython/lib/axtls/docsrc/axTLS.dox @@ -0,0 +1,1372 @@ +# Doxyfile 1.5.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = axTLS + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = NO + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../bindings/csharp/axTLS.cs \ + ../bindings/java/SSL.java \ + ../bindings/java/SSLUtil.java \ + ../bindings/java/SSLCTX.java \ + ../bindings/java/SSLServer.java \ + ../bindings/java/SSLClient.java \ + ../bindings/java/SSLReadHolder.java \ + ../ssl/ssl.h \ + ../crypto/bigint.c \ + ../crypto/bigint.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = images + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = doco_footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = YES + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = YES + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = CONFIG_SSL_CERT_VERIFICATION \ + CONFIG_SSL_ENABLE_CLIENT \ + CONFIG_SSL_GENERATE_X509_CERT \ + CONFIG_BIGINT_MONTGOMERY \ + CONFIG_BIGINT_BARRETT \ + CONFIG_BIGINT_CRT \ + "EXP_FUNC=" \ + "STDCALL=" + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = NO + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = NO + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = NO + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = NO + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/circuitpython/lib/axtls/docsrc/doco_footer.html b/circuitpython/lib/axtls/docsrc/doco_footer.html new file mode 100644 index 0000000..20c4e70 --- /dev/null +++ b/circuitpython/lib/axtls/docsrc/doco_footer.html @@ -0,0 +1,3 @@ +

+

+Copyright © 2007 Cameron Rich diff --git a/circuitpython/lib/axtls/docsrc/images/axolotl.jpg b/circuitpython/lib/axtls/docsrc/images/axolotl.jpg new file mode 100644 index 0000000..7352bba Binary files /dev/null and b/circuitpython/lib/axtls/docsrc/images/axolotl.jpg differ diff --git a/circuitpython/lib/axtls/docsrc/images/tsbasbw.gif b/circuitpython/lib/axtls/docsrc/images/tsbasbw.gif new file mode 100644 index 0000000..cf03b12 Binary files /dev/null and b/circuitpython/lib/axtls/docsrc/images/tsbasbw.gif differ diff --git a/circuitpython/lib/axtls/httpd/Config.in b/circuitpython/lib/axtls/httpd/Config.in new file mode 100644 index 0000000..486ae80 --- /dev/null +++ b/circuitpython/lib/axtls/httpd/Config.in @@ -0,0 +1,160 @@ +# +# For a description of the syntax of this configuration file, +# see scripts/config/Kconfig-language.txt +# + +menu "Axhttpd Configuration" +depends on CONFIG_AXHTTPD + +config CONFIG_HTTP_STATIC_BUILD + bool "Static Build" + default n + help + Select y if you want axhttpd to be a static build (i.e. don't use the + axtls shared library or dll). + +config CONFIG_HTTP_PORT + int "HTTP port" + default 80 + help + The port number of the normal HTTP server. + + You must be a root user in order to use the default port. + +config CONFIG_HTTP_HTTPS_PORT + int "HTTPS port" + default 443 + help + The port number of the HTTPS server. + + You must be a root user in order to use the default port. + +config CONFIG_HTTP_SESSION_CACHE_SIZE + int "SSL session cache size" + default 5 + help + The size of the SSL session cache. + + This is not actually related to the number of concurrent users, but + for optimum performance they should be the same (with a penalty + in memory usage). + +config CONFIG_HTTP_WEBROOT + string "Web root location" + default "../www" if !CONFIG_PLATFORM_WIN32 + default "..\\www" if CONFIG_PLATFORM_WIN32 + help + The location of the web root in relation to axhttpd. This is + the directory where index.html lives. + +config CONFIG_HTTP_TIMEOUT + int "Timeout" + default 300 + help + Set the timeout of a connection in seconds. + +menu "CGI" +depends on !CONFIG_PLATFORM_WIN32 + +config CONFIG_HTTP_HAS_CGI + bool "Enable CGI" + default y + depends on !CONFIG_PLATFORM_WIN32 + help + Enable the CGI capability. Not available on Win32 platforms. + +config CONFIG_HTTP_CGI_EXTENSIONS + string "CGI File Extension(s)" + default ".lua,.lp,.php" + depends on CONFIG_HTTP_HAS_CGI + help + Tell axhhtpd what file extension(s) are used for CGI. + + This is a comma separated list - e.g. ".php,.pl" etc + +config CONFIG_HTTP_ENABLE_LUA + bool "Enable Lua" + default y + depends on CONFIG_HTTP_HAS_CGI + help + Lua is a powerful, fast, light-weight, embeddable scripting language. + + See http://www.lua.org for details. + +config CONFIG_HTTP_LUA_PREFIX + string "Lua's Installation Prefix" + default "/usr" + depends on CONFIG_HTTP_ENABLE_LUA + + help + The location of Lua's installation prefix. + +config CONFIG_HTTP_BUILD_LUA + bool "Build Lua" + default n + depends on CONFIG_HTTP_ENABLE_LUA + help + Build Lua and install in /usr/bin by default. + +config CONFIG_HTTP_CGI_LAUNCHER + string "CGI launcher location" + default "/usr/bin/cgi" + depends on CONFIG_HTTP_HAS_CGI + help + The location of the CGI launcher application (could be /usr/bin/php5). + The default is to use Lua's CGI launcher. +endmenu + +config CONFIG_HTTP_DIRECTORIES + bool "Enable Directory Listing" + default y + help + Enable directory listing. + +config CONFIG_HTTP_HAS_AUTHORIZATION + bool "Enable authorization" + default y + help + Pages/directories can have passwords associated with them. + +config CONFIG_HTTP_HAS_IPV6 + bool "Enable IPv6" + default n + depends on !CONFIG_PLATFORM_WIN32 + help + Use IPv6 instead of IPv4. + + Does not work under Win32 + +config CONFIG_HTTP_ENABLE_DIFFERENT_USER + bool "Enable different user" + default n + depends on !CONFIG_PLATFORM_WIN32 + help + Allow the web server to be run as a different user + +config CONFIG_HTTP_USER + string "As User" + default "nobody" + depends on CONFIG_HTTP_ENABLE_DIFFERENT_USER + help + The user name that will be used to run axhttpd. + +config CONFIG_HTTP_VERBOSE + bool "Verbose Mode" + default y if CONFIG_SSL_FULL_MODE + default n if !CONFIG_SSL_FULL_MODE + help + Enable extra statements used when using axhttpd. + +config CONFIG_HTTP_IS_DAEMON + bool "Run as a daemon" + default n + depends on !CONFIG_PLATFORM_WIN32 + help + Run axhttpd as a background process. + + Does not work under Win32 + +endmenu + diff --git a/circuitpython/lib/axtls/httpd/Makefile b/circuitpython/lib/axtls/httpd/Makefile new file mode 100644 index 0000000..fbf2fae --- /dev/null +++ b/circuitpython/lib/axtls/httpd/Makefile @@ -0,0 +1,130 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +all : web_server lua + +AXTLS_HOME=.. + +include $(AXTLS_HOME)/config/.config +include $(AXTLS_HOME)/config/makefile.conf + +ifndef CONFIG_PLATFORM_WIN32 + +ifdef CONFIG_PLATFORM_CYGWIN +TARGET=$(AXTLS_HOME)/$(STAGE)/axhttpd.exe +TARGET2=$(AXTLS_HOME)/$(STAGE)/htpasswd.exe +else +TARGET=$(AXTLS_HOME)/$(STAGE)/axhttpd +TARGET2=$(AXTLS_HOME)/$(STAGE)/htpasswd +endif + +ifdef CONFIG_HTTP_STATIC_BUILD +LIBS=$(AXTLS_HOME)/$(STAGE)/libaxtls.a +else +LIBS=-L$(AXTLS_HOME)/$(STAGE) -laxtls +endif + +ifdef CONFIG_HTTP_BUILD_LUA +lua: kepler-1.1 + +kepler-1.1: + @tar xvfz kepler-1.1-snapshot-20070521-1825.tar.gz + @cat kepler.patch | patch -p0 + cd kepler-1.1; ./configure --prefix=$(CONFIG_HTTP_LUA_PREFIX) --launcher=cgi --lua-suffix= ; make install +else +lua: +endif + +else # win32 build +lua: + +TARGET=$(AXTLS_HOME)/$(STAGE)/axhttpd.exe +TARGET2=$(AXTLS_HOME)/$(STAGE)/htpasswd.exe + +ifdef CONFIG_HTTP_STATIC_BUILD +LIBS=$(AXTLS_HOME)/$(STAGE)/axtls.static.lib $(AXTLS_HOME)\\config\\axtls.res +else +LIBS=$(AXTLS_HOME)/$(STAGE)/axtls.lib $(AXTLS_HOME)\\config\\axtls.res +endif +endif + +ifndef CONFIG_AXHTTPD +web_server: +else + +web_server :: $(TARGET) + +ifdef CONFIG_HTTP_HAS_AUTHORIZATION +web_server :: $(TARGET2) +endif + +OBJ= \ + axhttpd.o \ + proc.o \ + tdate_parse.o + +include $(AXTLS_HOME)/config/makefile.post + +ifndef CONFIG_PLATFORM_WIN32 + +$(TARGET): $(OBJ) $(AXTLS_HOME)/$(STAGE)/libaxtls.a + $(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) +ifdef CONFIG_STRIP_UNWANTED_SECTIONS + $(STRIP) --remove-section=.comment $(TARGET) +endif + +$(TARGET2): htpasswd.o $(AXTLS_HOME)/$(STAGE)/libaxtls.a + $(LD) $(LDFLAGS) -o $@ htpasswd.o $(LIBS) +ifdef CONFIG_STRIP_UNWANTED_SECTIONS + $(STRIP) --remove-section=.comment $(TARGET2) +endif + +else # Win32 + +OBJ:=$(OBJ:.o=.obj) +%.obj : %.c + $(CC) $(CFLAGS) $< + +htpasswd.obj : htpasswd.c + $(CC) $(CFLAGS) $? + +$(TARGET): $(OBJ) + $(LD) $(LDFLAGS) /out:$@ $(LIBS) $? + +$(TARGET2): htpasswd.obj + $(LD) $(LDFLAGS) /out:$@ $(LIBS) $? +endif + +endif # CONFIG_AXHTTPD + +clean:: + -@rm -f $(TARGET)* + -@rm -fr kepler-1.1 + diff --git a/circuitpython/lib/axtls/httpd/axhttp.h b/circuitpython/lib/axtls/httpd/axhttp.h new file mode 100644 index 0000000..3b4b5a5 --- /dev/null +++ b/circuitpython/lib/axtls/httpd/axhttp.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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 "os_port.h" +#include "ssl.h" + +#define BACKLOG 15 +#define VERSION "1.0.0" +#ifdef CONFIG_HTTP_HAS_IPV6 +#define HAVE_IPV6 +#endif + +#define MAXPOSTDATASIZE 30000 /* adjust for file upload + size*/ +#define MAXREQUESTLENGTH 256 +#define MAXREADLENGTH 8800 /* FF3=4096, IE7=8760 */ +#define BLOCKSIZE 4096 + +#define INITIAL_CONNECTION_SLOTS 10 +#define CONFIG_HTTP_DEFAULT_SSL_OPTIONS SSL_DISPLAY_CERTS + +#define STATE_WANT_TO_READ_HEAD 1 +#define STATE_WANT_TO_SEND_HEAD 2 +#define STATE_WANT_TO_READ_FILE 3 +#define STATE_WANT_TO_SEND_FILE 4 +#define STATE_DOING_DIR 5 + +enum +{ + TYPE_GET, + TYPE_HEAD, + TYPE_POST +}; + +struct connstruct +{ + struct connstruct *next; + int state; + int reqtype; + int networkdesc; + int filedesc; + SSL *ssl; + +#if defined(CONFIG_HTTP_DIRECTORIES) +#ifdef WIN32 + HANDLE dirp; + WIN32_FIND_DATA file_data; +#else + DIR *dirp; +#endif +#endif + + time_t timeout; + char actualfile[MAXREQUESTLENGTH]; + char filereq[MAXREQUESTLENGTH]; + char dirname[MAXREQUESTLENGTH]; + char server_name[MAXREQUESTLENGTH]; + int numbytes; + char databuf[BLOCKSIZE]; + uint8_t is_ssl; + uint8_t is_v1_0; + uint8_t close_when_done; + time_t if_modified_since; + +#if defined(CONFIG_HTTP_HAS_CGI) + uint8_t is_cgi; + char cgicontenttype[MAXREQUESTLENGTH]; + int content_length; + char remote_addr[MAXREQUESTLENGTH]; + char uri_request[MAXREQUESTLENGTH]; + char uri_path_info[MAXREQUESTLENGTH]; + char uri_query[MAXREQUESTLENGTH]; + char cookie[MAXREQUESTLENGTH]; +#endif +#if defined(CONFIG_HTTP_HAS_AUTHORIZATION) + char authorization[MAXREQUESTLENGTH]; +#endif + int post_read; + int post_state; + char *post_data; +}; + +struct serverstruct +{ + struct serverstruct *next; + int sd; + int is_ssl; + SSL_CTX *ssl_ctx; +}; + +#if defined(CONFIG_HTTP_HAS_CGI) +struct cgiextstruct +{ + struct cgiextstruct *next; + char *ext; +}; +#endif + +/* global prototypes */ +extern struct serverstruct *servers; +extern struct connstruct *usedconns; +extern struct connstruct *freeconns; +extern const char * const server_version; + +#if defined(CONFIG_HTTP_HAS_CGI) +extern struct cgiextstruct *cgiexts; +#endif + +/* conn.c prototypes */ +void removeconnection(struct connstruct *cn); + +/* proc.c prototypes */ +void procdodir(struct connstruct *cn); +void procreadhead(struct connstruct *cn); +void procsendhead(struct connstruct *cn); +void procreadfile(struct connstruct *cn); +void procsendfile(struct connstruct *cn); +#if defined(CONFIG_HTTP_HAS_CGI) +void read_post_data(struct connstruct *cn); +#endif + +/* misc.c prototypes */ +char *my_strncpy(char *dest, const char *src, size_t n); +int isdir(const char *name); + +/* tdate prototypes */ +void tdate_init(void); +time_t tdate_parse(const char* str); + diff --git a/circuitpython/lib/axtls/httpd/axhttpd.c b/circuitpython/lib/axtls/httpd/axhttpd.c new file mode 100644 index 0000000..6718dd3 --- /dev/null +++ b/circuitpython/lib/axtls/httpd/axhttpd.c @@ -0,0 +1,713 @@ +/* + * Copyright (c) Cameron Rich + * + * 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 axTLS project 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 +#include +#include +#include +#include +#include + +#if !defined(WIN32) +#include +#endif +#include "axhttp.h" + +struct serverstruct *servers; +struct connstruct *usedconns; +struct connstruct *freeconns; +const char * const server_version = "axhttpd/"AXTLS_VERSION; +static const char *webroot = CONFIG_HTTP_WEBROOT; + +static void addtoservers(int sd); +static int openlistener(char *address, int port); +static void handlenewconnection(int listenfd, int is_ssl); +static void addconnection(int sd, char *ip, int is_ssl); +static void ax_chdir(void); + +#if defined(CONFIG_HTTP_HAS_CGI) +struct cgiextstruct *cgiexts; +static void addcgiext(const char *tp); + +#if !defined(WIN32) +static void reaper(int sigtype) +{ + while (wait3(NULL, WNOHANG, NULL) > 0) + continue; +} +#endif +#endif + +#ifdef CONFIG_HTTP_VERBOSE /* should really be in debug mode or something */ +/* clean up memory for valgrind */ +static void sigint_cleanup(int sig) +{ + struct serverstruct *sp; + struct connstruct *tp; + + while (servers != NULL) + { + if (servers->is_ssl) + ssl_ctx_free(servers->ssl_ctx); + + sp = servers->next; + free(servers); + servers = sp; + } + + while (freeconns != NULL) + { + tp = freeconns->next; + free(freeconns); + freeconns = tp; + } + + while (usedconns != NULL) + { + tp = usedconns->next; + free(usedconns); + usedconns = tp; + } + +#if defined(CONFIG_HTTP_HAS_CGI) + while (cgiexts) + { + struct cgiextstruct *cp = cgiexts->next; + if (cp == NULL) /* last entry */ + free(cgiexts->ext); + free(cgiexts); + cgiexts = cp; + } +#endif + + exit(0); +} + +static void die(int sigtype) +{ + exit(0); +} +#endif + +int main(int argc, char *argv[]) +{ + fd_set rfds, wfds; + struct connstruct *tp, *to; + struct serverstruct *sp; + int rnum, wnum, active; + int i = 1; + time_t currtime; + char *httpAddress = NULL; + int httpPort = CONFIG_HTTP_PORT; + char *httpsAddress = NULL; + int httpsPort = CONFIG_HTTP_HTTPS_PORT; + uint32_t options = CONFIG_HTTP_DEFAULT_SSL_OPTIONS; + char *portStr; + char *private_key = NULL; + char *cert = NULL; + +#ifdef WIN32 + WORD wVersionRequested = MAKEWORD(2, 2); + WSADATA wsaData; + WSAStartup(wVersionRequested,&wsaData); +#else + signal(SIGPIPE, SIG_IGN); +#if defined(CONFIG_HTTP_HAS_CGI) + signal(SIGCHLD, reaper); +#endif +#ifdef CONFIG_HTTP_VERBOSE + signal(SIGQUIT, die); +#endif +#endif + +#ifdef CONFIG_HTTP_VERBOSE + signal(SIGTERM, die); + signal(SIGINT, sigint_cleanup); +#endif + tdate_init(); + + /* get some command-line parameters */ + while (argv[i] != NULL) + { + if (strcmp(argv[i], "-p") == 0 && argv[i+1] != NULL) + { + if ((portStr = strchr(argv[i+1], ':')) != NULL) + { + httpAddress = argv[i+1]; + *portStr = 0; + httpPort = atoi(portStr + 1); + } + else + httpPort = atoi(argv[i+1]); + + i += 2; + continue; + } + + if (strcmp(argv[i], "-s") == 0 && argv[i+1] != NULL) + { + if ((portStr = strchr(argv[i+1], ':')) != NULL) + { + httpsAddress = argv[i+1]; + *portStr = 0; + httpsPort = atoi(portStr + 1); + } + else + httpsPort = atoi(argv[i+1]); + + i += 2; + continue; + } + + if (strcmp(argv[i], "-w") == 0 && argv[i+1] != NULL) + { + webroot = argv[i+1]; + i += 2; + continue; + } + + if (strcmp(argv[i], "-cert") == 0 && argv[i+1] != NULL) + { + cert = argv[i+1]; + i += 2; + continue; + } + + if (strcmp(argv[i], "-key") == 0 && argv[i+1] != NULL) + { + private_key = argv[i+1]; + i += 2; + continue; + } + printf("%s:\n" + " [-p [address:]httpport]\n" + " [-s [address:]httpsport]\n" + " [-key private_key]\n" + " [-cert cert]\n" + " [-w webroot]\n", argv[0]); + exit(1); + } + + for (i = 0; i < INITIAL_CONNECTION_SLOTS; i++) + { + tp = freeconns; + freeconns = (struct connstruct *)calloc(1, sizeof(struct connstruct)); + freeconns->next = tp; + } + + if ((active = openlistener(httpAddress, httpPort)) == -1) + { +#ifdef CONFIG_HTTP_VERBOSE + fprintf(stderr, "ERR: Couldn't bind to port %d\n", httpPort); +#endif + exit(1); + } + + addtoservers(active); + + if ((active = openlistener(httpsAddress, httpsPort)) == -1) + { +#ifdef CONFIG_HTTP_VERBOSE + fprintf(stderr, "ERR: Couldn't bind to port %d\n", httpsPort); +#endif + exit(1); + } + + addtoservers(active); + + if (cert != NULL && private_key != NULL) + options |= SSL_NO_DEFAULT_KEY; + + servers->ssl_ctx = ssl_ctx_new(options, CONFIG_HTTP_SESSION_CACHE_SIZE); + servers->is_ssl = 1; + + if (cert != NULL && private_key != NULL) + { + printf("YEAH\n"); + if (ssl_obj_load(servers->ssl_ctx, SSL_OBJ_RSA_KEY, private_key, + NULL)) + { +#ifdef CONFIG_HTTP_VERBOSE + fprintf(stderr, "ERR: Couldn't load private key %s\n", private_key); +#endif + exit(1); + } + + if (ssl_obj_load(servers->ssl_ctx, SSL_OBJ_X509_CERT, cert, + NULL)) + { +#ifdef CONFIG_HTTP_VERBOSE + fprintf(stderr, "ERR: Couldn't load cert %s\n", cert); +#endif + exit(1); + } + } + +#if defined(CONFIG_HTTP_HAS_CGI) + addcgiext(CONFIG_HTTP_CGI_EXTENSIONS); +#endif + +#if defined(CONFIG_HTTP_VERBOSE) +#if defined(CONFIG_HTTP_HAS_CGI) + printf("addcgiext %s\n", CONFIG_HTTP_CGI_EXTENSIONS); +#endif + printf("%s: listening on ports %d (http) and %d (https)\n", + server_version, httpPort, httpsPort); + TTY_FLUSH(); +#endif + + ax_chdir(); + +#ifdef CONFIG_HTTP_ENABLE_DIFFERENT_USER + { + struct passwd *pd = getpwnam(CONFIG_HTTP_USER); + + if (pd != NULL) + { + int res = setuid(pd->pw_uid); + res |= setgid(pd->pw_gid); + +#if defined(CONFIG_HTTP_VERBOSE) + if (res == 0) + { + printf("change to '%s' successful\n", CONFIG_HTTP_USER); + TTY_FLUSH(); + } +#endif + } + + } +#endif + +#ifndef WIN32 +#ifdef CONFIG_HTTP_IS_DAEMON + if (fork() > 0) /* parent will die */ + exit(0); + + setsid(); +#endif +#endif + + /* main loop */ + while (1) + { + struct timeval tv = { 10, 0 }; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + rnum = wnum = -1; + sp = servers; + + while (sp != NULL) /* read each server port */ + { + FD_SET(sp->sd, &rfds); + + if (sp->sd > rnum) + rnum = sp->sd; + sp = sp->next; + } + + /* Add the established sockets */ + tp = usedconns; + currtime = time(NULL); + + while (tp != NULL) + { + if (currtime > tp->timeout) /* timed out? Kill it. */ + { + to = tp; + tp = tp->next; + removeconnection(to); + continue; + } + + if (tp->state == STATE_WANT_TO_READ_HEAD) + { + FD_SET(tp->networkdesc, &rfds); + if (tp->networkdesc > rnum) + rnum = tp->networkdesc; + } + + if (tp->state == STATE_WANT_TO_SEND_HEAD) + { + FD_SET(tp->networkdesc, &wfds); + if (tp->networkdesc > wnum) + wnum = tp->networkdesc; + } + + if (tp->state == STATE_WANT_TO_READ_FILE) + { + FD_SET(tp->filedesc, &rfds); + if (tp->filedesc > rnum) + rnum = tp->filedesc; + } + + if (tp->state == STATE_WANT_TO_SEND_FILE) + { + FD_SET(tp->networkdesc, &wfds); + if (tp->networkdesc > wnum) + wnum = tp->networkdesc; + } + +#if defined(CONFIG_HTTP_DIRECTORIES) + if (tp->state == STATE_DOING_DIR) + { + FD_SET(tp->networkdesc, &wfds); + if (tp->networkdesc > wnum) + wnum = tp->networkdesc; + } +#endif + tp = tp->next; + } + + active = select(wnum > rnum ? wnum+1 : rnum+1, + rnum != -1 ? &rfds : NULL, + wnum != -1 ? &wfds : NULL, + NULL, usedconns ? &tv : NULL); + + /* timeout? */ + if (active == 0) + continue; + + /* New connection? */ + sp = servers; + while (active > 0 && sp != NULL) + { + if (FD_ISSET(sp->sd, &rfds)) + { + handlenewconnection(sp->sd, sp->is_ssl); + active--; + } + + sp = sp->next; + } + + /* Handle the established sockets */ + tp = usedconns; + + while (active > 0 && tp != NULL) + { + to = tp; + tp = tp->next; + + if (to->state == STATE_WANT_TO_READ_HEAD && + FD_ISSET(to->networkdesc, &rfds)) + { + active--; +#if defined(CONFIG_HTTP_HAS_CGI) + if (to->post_state) + read_post_data(to); + else +#endif + procreadhead(to); + } + + if (to->state == STATE_WANT_TO_SEND_HEAD && + FD_ISSET(to->networkdesc, &wfds)) + { + active--; + procsendhead(to); + } + + if (to->state == STATE_WANT_TO_READ_FILE && + FD_ISSET(to->filedesc, &rfds)) + { + active--; + procreadfile(to); + } + + if (to->state == STATE_WANT_TO_SEND_FILE && + FD_ISSET(to->networkdesc, &wfds)) + { + active--; + procsendfile(to); + } + +#if defined(CONFIG_HTTP_DIRECTORIES) + if (to->state == STATE_DOING_DIR && + FD_ISSET(to->networkdesc, &wfds)) + { + active--; + procdodir(to); + } +#endif + } + } + + return 0; +} + +#if defined(CONFIG_HTTP_HAS_CGI) +static void addcgiext(const char *cgi_exts) +{ + char *cp = strdup(cgi_exts); + + /* extenstions are comma separated */ + do + { + struct cgiextstruct *ex = (struct cgiextstruct *) + malloc(sizeof(struct cgiextstruct)); + ex->ext = cp; + ex->next = cgiexts; + cgiexts = ex; + if ((cp = strchr(cp, ',')) != NULL) + *cp++ = 0; + } while (cp != NULL); +} +#endif + +static void addtoservers(int sd) +{ + struct serverstruct *tp = (struct serverstruct *) + calloc(1, sizeof(struct serverstruct)); + tp->next = servers; + tp->sd = sd; + servers = tp; +} + +#ifdef HAVE_IPV6 +static void handlenewconnection(int listenfd, int is_ssl) +{ + struct sockaddr_in6 their_addr; + socklen_t tp = sizeof(their_addr); + char ipbuf[100]; + int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp); + + if (tp == sizeof(struct sockaddr_in6)) + inet_ntop(AF_INET6, &their_addr.sin6_addr, ipbuf, sizeof(ipbuf)); + else if (tp == sizeof(struct sockaddr_in)) + inet_ntop(AF_INET, &(((struct sockaddr_in *)&their_addr)->sin_addr), + ipbuf, sizeof(ipbuf)); + else + *ipbuf = '\0'; + + if (connfd != -1) /* check for error condition */ + addconnection(connfd, ipbuf, is_ssl); +} + +#else +static void handlenewconnection(int listenfd, int is_ssl) +{ + struct sockaddr_in their_addr; + socklen_t tp = sizeof(struct sockaddr_in); + int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp); + addconnection(connfd, inet_ntoa(their_addr.sin_addr), is_ssl); +} +#endif + +static int openlistener(char *address, int port) +{ + int sd; +#ifdef WIN32 + char tp = 1; +#else + int tp = 1; +#endif +#ifndef HAVE_IPV6 + struct sockaddr_in my_addr; + + if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + return -1; + + memset(&my_addr, 0, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons((short)port); + my_addr.sin_addr.s_addr = address == NULL ? + INADDR_ANY : inet_addr(address); +#else + struct sockaddr_in6 my_addr; + + if ((sd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) + return -1; + + my_addr.sin6_family = AF_INET6; + my_addr.sin6_port = htons(port); + + if (address == NULL) + my_addr.sin6_addr = in6addr_any; + else + inet_pton(AF_INET6, address, &my_addr.sin6_addr); +#endif + + setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &tp, sizeof(tp)); + if (bind(sd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) + { + close(sd); + return -1; + } + + listen(sd, BACKLOG); + return sd; +} + +/* Wrapper function for strncpy() that guarantees + a null-terminated string. This is to avoid any possible + issues due to strncpy()'s behaviour. + */ +char *my_strncpy(char *dest, const char *src, size_t n) +{ + strncpy(dest, src, n); + dest[n-1] = '\0'; + return dest; +} + +int isdir(const char *tpbuf) +{ + struct stat st; + char path[MAXREQUESTLENGTH]; + strcpy(path, tpbuf); + +#ifdef WIN32 /* win32 stat() can't handle trailing '\' */ + if (path[strlen(path)-1] == '\\') + path[strlen(path)-1] = 0; +#endif + + if (stat(path, &st) == -1) + return 0; + + if ((st.st_mode & S_IFMT) == S_IFDIR) + return 1; + + return 0; +} + +static void addconnection(int sd, char *ip, int is_ssl) +{ + struct connstruct *tp; + + /* Get ourselves a connstruct */ + if (freeconns == NULL) + tp = (struct connstruct *)calloc(1, sizeof(struct connstruct)); + else + { + tp = freeconns; + freeconns = tp->next; + } + + /* Attach it to the used list */ + tp->next = usedconns; + usedconns = tp; + tp->networkdesc = sd; + + if (is_ssl) + tp->ssl = ssl_server_new(servers->ssl_ctx, sd); + + tp->is_ssl = is_ssl; + tp->filedesc = -1; +#if defined(CONFIG_HTTP_HAS_DIRECTORIES) + tp->dirp = NULL; +#endif + *tp->actualfile = '\0'; + *tp->filereq = '\0'; + tp->state = STATE_WANT_TO_READ_HEAD; + tp->reqtype = TYPE_GET; + tp->close_when_done = 0; + tp->timeout = time(NULL) + CONFIG_HTTP_TIMEOUT; +#if defined(CONFIG_HTTP_HAS_CGI) + strcpy(tp->remote_addr, ip); +#endif +} + +void removeconnection(struct connstruct *cn) +{ + struct connstruct *tp; + int shouldret = 0; + + tp = usedconns; + + if (tp == NULL || cn == NULL) + shouldret = 1; + else if (tp == cn) + usedconns = tp->next; + else + { + while (tp != NULL) + { + if (tp->next == cn) + { + tp->next = (tp->next)->next; + shouldret = 0; + break; + } + + tp = tp->next; + shouldret = 1; + } + } + + if (shouldret) + return; + + /* If we did, add it to the free list */ + cn->next = freeconns; + freeconns = cn; + + /* Close it all down */ + if (cn->networkdesc != -1) + { + if (cn->is_ssl) + { + ssl_free(cn->ssl); + cn->ssl = NULL; + } + +#ifndef WIN32 + shutdown(cn->networkdesc, SHUT_WR); +#endif + SOCKET_CLOSE(cn->networkdesc); + } + + if (cn->filedesc != -1) + close(cn->filedesc); + +#if defined(CONFIG_HTTP_HAS_DIRECTORIES) + if (cn->dirp != NULL) +#ifdef WIN32 + FindClose(cn->dirp); +#else + closedir(cn->dirp); +#endif +#endif +} + +/* + * Change directories one way or the other. + */ + +static void ax_chdir(void) +{ + if (chdir(webroot)) + { +#ifdef CONFIG_HTTP_VERBOSE + fprintf(stderr, "'%s' is not a directory\n", webroot); +#endif + exit(1); + } +} + diff --git a/circuitpython/lib/axtls/httpd/htpasswd.c b/circuitpython/lib/axtls/httpd/htpasswd.c new file mode 100644 index 0000000..91feea1 --- /dev/null +++ b/circuitpython/lib/axtls/httpd/htpasswd.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) Cameron Rich + * + * 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 axTLS project 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 +#include +#include +#include "os_port.h" +#include "ssl.h" + +int tfd; + +void base64_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen) +{ + static const char b64str[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + while (inlen && outlen) + { + *out++ = b64str[(in[0] >> 2) & 0x3f]; + if (!--outlen) + break; + + *out++ = b64str[((in[0] << 4) + + (--inlen ? in[1] >> 4 : 0)) & 0x3f]; + if (!--outlen) + break; + *out++ = (inlen + ? b64str[((in[1] << 2) + + (--inlen ? in[2] >> 6 : 0)) + & 0x3f] + : '='); + if (!--outlen) + break; + *out++ = inlen ? b64str[in[2] & 0x3f] : '='; + if (!--outlen) + break; + if (inlen) + inlen--; + if (inlen) + in += 3; + } + + if (outlen) + *out = '\0'; +} + +static void usage(void) +{ + fprintf(stderr,"Usage: htpasswd username\n"); + exit(1); +} + +#ifdef WIN32 +static char * getpass(const char *prompt) +{ + static char buf[127]; + FILE *fp = stdin; + + printf(prompt); TTY_FLUSH(); +#if 0 + fp = fopen("/dev/tty", "w"); + if (fp == NULL) + { + printf("null\n"); TTY_FLUSH(); + fp = stdin; + } +#endif + + fgets(buf, sizeof(buf), fp); + while (buf[strlen(buf)-1] < ' ') + buf[strlen(buf)-1] = '\0'; + + //if (fp != stdin) + // fclose(fp); + return buf; +} +#endif + +int main(int argc, char *argv[]) +{ + char* pw; + uint8_t md5_salt[MD5_SIZE], md5_pass[MD5_SIZE]; + char b64_salt[MD5_SIZE+10], b64_pass[MD5_SIZE+10]; + MD5_CTX ctx; + + if (argc != 2) + usage(); + + pw = strdup(getpass("New password:")); + if (strcmp(pw, getpass("Re-type new password:")) != 0) + { + fprintf(stderr, "They don't match, sorry.\n" ); + exit(1); + } + + RNG_initialize(); + if (get_random(MD5_SIZE, md5_salt) < 0) + { + fprintf(stderr, "Can't get random data\n" ); + exit(1); + } + + RNG_terminate(); + base64_encode(md5_salt, MD5_SIZE, b64_salt, sizeof(b64_salt)); + + MD5_Init(&ctx); + MD5_Update(&ctx, md5_salt, MD5_SIZE); + MD5_Update(&ctx, (uint8_t *)pw, strlen(pw)); + MD5_Final(md5_pass, &ctx); + base64_encode(md5_pass, MD5_SIZE, b64_pass, sizeof(b64_pass)); + + printf("Add the following to your '.htpasswd' file\n"); + printf("%s:%s$%s\n", argv[1], b64_salt, b64_pass); + return 0; +} diff --git a/circuitpython/lib/axtls/httpd/kepler-1.1-snapshot-20070521-1825.tar.gz b/circuitpython/lib/axtls/httpd/kepler-1.1-snapshot-20070521-1825.tar.gz new file mode 100755 index 0000000..d1caec5 Binary files /dev/null and b/circuitpython/lib/axtls/httpd/kepler-1.1-snapshot-20070521-1825.tar.gz differ diff --git a/circuitpython/lib/axtls/httpd/kepler.patch b/circuitpython/lib/axtls/httpd/kepler.patch new file mode 100644 index 0000000..dbab7e5 --- /dev/null +++ b/circuitpython/lib/axtls/httpd/kepler.patch @@ -0,0 +1,64 @@ +diff -Naur kepler-1.1/launcher/cgi/Makefile kepler-1.1.new/launcher/cgi/Makefile +--- kepler-1.1/launcher/cgi/Makefile 2007-04-21 06:41:49.000000000 +1000 ++++ kepler-1.1.new/launcher/cgi/Makefile 2007-05-16 22:13:38.750000000 +1000 +@@ -16,7 +16,7 @@ + + + $T: $(CH) $(OBJS) +- $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) ++ $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) -L../../lua-5.1.2/src -llua + + build: $T + +diff -Naur kepler-1.1/luafilesystem/Makefile kepler-1.1.new/luafilesystem/Makefile +--- kepler-1.1/luafilesystem/Makefile 2007-04-21 06:41:49.000000000 +1000 ++++ kepler-1.1.new/luafilesystem/Makefile 2007-05-16 22:06:25.546875000 +1000 +@@ -12,7 +12,7 @@ + lib: src/$(LIBNAME) + + src/$(LIBNAME): $(OBJS) +- export MACOSX_DEPLOYMENT_TARGET="10.3"; $(CC) $(CFLAGS) $(LIB_OPTION) -o src/$(LIBNAME) $(OBJS) ++ export MACOSX_DEPLOYMENT_TARGET="10.3"; $(CC) $(CFLAGS) $(LIB_OPTION) -o src/$(LIBNAME) $(OBJS) -L../lua-5.1.2/src -llua + + install: src/$(LIBNAME) + mkdir -p $(LUA_LIBDIR) +diff -Naur kepler-1.1/luasocket-2.0.1/src/makefile kepler-1.1.new/luasocket-2.0.1/src/makefile +--- kepler-1.1/luasocket-2.0.1/src/makefile 2007-04-21 06:41:49.000000000 +1000 ++++ kepler-1.1.new/luasocket-2.0.1/src/makefile 2007-05-16 22:36:37.125000000 +1000 +@@ -47,10 +47,10 @@ + all: $(SOCKET_SO) $(MIME_SO) + + $(SOCKET_SO): $(SOCKET_OBJS) +- $(LD) $(LDFLAGS) -o $@ $(SOCKET_OBJS) ++ $(LD) $(LDFLAGS) -o $@ $(SOCKET_OBJS) -L../../lua-5.1.2/src -llua + + $(MIME_SO): $(MIME_OBJS) +- $(LD) $(LDFLAGS) -o $@ $(MIME_OBJS) ++ $(LD) $(LDFLAGS) -o $@ $(MIME_OBJS) -L../../lua-5.1.2/src -llua + + $(UNIX_SO): $(UNIX_OBJS) + $(LD) $(LDFLAGS) -o $@ $(UNIX_OBJS) +diff -Naur kepler-1.1/md5/Makefile kepler-1.1.new/md5/Makefile +--- kepler-1.1/md5/Makefile 2007-04-21 06:41:49.000000000 +1000 ++++ kepler-1.1.new/md5/Makefile 2007-05-16 22:06:44.593750000 +1000 +@@ -15,7 +15,7 @@ + + + src/$(LIBNAME) : $(OBJS) +- export MACOSX_DEPLOYMENT_TARGET="10.3"; $(CC) $(CFLAGS) $(LIB_OPTION) -o src/$(LIBNAME) $(OBJS) ++ export MACOSX_DEPLOYMENT_TARGET="10.3"; $(CC) $(CFLAGS) $(LIB_OPTION) -o src/$(LIBNAME) $(OBJS) -L../lua-5.1.2/src -llua + + $(COMPAT_DIR)/compat-5.1.o: $(COMPAT_DIR)/compat-5.1.c + $(CC) -c $(CFLAGS) -o $@ $(COMPAT_DIR)/compat-5.1.c +diff -Naur kepler-1.1/rings/Makefile kepler-1.1.new/rings/Makefile +--- kepler-1.1/rings/Makefile 2007-04-21 06:41:49.000000000 +1000 ++++ kepler-1.1.new/rings/Makefile 2007-05-16 22:05:28.765625000 +1000 +@@ -10,7 +10,7 @@ + OBJS= src/rings.o + + src/$(LIBNAME) : $(OBJS) +- export MACOSX_DEPLOYMENT_TARGET="10.3"; $(CC) $(CFLAGS) $(LIB_OPTION) -o src/$(LIBNAME) $(OBJS) ++ export MACOSX_DEPLOYMENT_TARGET="10.3"; $(CC) $(CFLAGS) $(LIB_OPTION) -o src/$(LIBNAME) $(OBJS) -L../lua-5.1.2/src -llua + + install: + mkdir -p $(LUA_LIBDIR) diff --git a/circuitpython/lib/axtls/httpd/proc.c b/circuitpython/lib/axtls/httpd/proc.c new file mode 100644 index 0000000..f48c275 --- /dev/null +++ b/circuitpython/lib/axtls/httpd/proc.c @@ -0,0 +1,1254 @@ +/* + * Copyright (c) Cameron Rich + * + * 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 axTLS project 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 +#include +#include +#include +#include +#include +#include +#include +#include "axhttp.h" + +#define HTTP_VERSION "HTTP/1.1" + +static const char * index_file = "index.html"; +static const char * rfc1123_format = "%a, %d %b %Y %H:%M:%S GMT"; + +static int special_read(struct connstruct *cn, void *buf, size_t count); +static int special_write(struct connstruct *cn, + const char *buf, size_t count); +static void send_error(struct connstruct *cn, int err); +static int hexit(char c); +static void urldecode(char *buf); +static void buildactualfile(struct connstruct *cn); +static int sanitizefile(const char *buf); +static int sanitizehost(char *buf); +static int htaccess_check(struct connstruct *cn); +static const char *getmimetype(const char *name); + +#if defined(CONFIG_HTTP_DIRECTORIES) +static void urlencode(const uint8_t *s, char *t); +static void procdirlisting(struct connstruct *cn); +#endif +#if defined(CONFIG_HTTP_HAS_CGI) +static void proccgi(struct connstruct *cn); +static void decode_path_info(struct connstruct *cn, char *path_info); +static int init_read_post_data(char *buf, char *data, struct connstruct *cn, int old_rv); +#endif +#ifdef CONFIG_HTTP_HAS_AUTHORIZATION +static int auth_check(struct connstruct *cn); +#endif + +#if AXDEBUG +#define AXDEBUGSTART \ + { \ + FILE *axdout; \ + axdout = fopen("/var/log/axdebug", "a"); \ + +#define AXDEBUGEND \ + fclose(axdout); \ + } +#else /* AXDEBUG */ +#define AXDEBUGSTART +#define AXDEBUGEND +#endif /* AXDEBUG */ + +/* Returns 1 if elems should continue being read, 0 otherwise */ +static int procheadelem(struct connstruct *cn, char *buf) +{ + char *delim, *value; + + if ((delim = strchr(buf, ' ')) == NULL) + return 0; + + *delim = 0; + value = delim+1; + + if (strcmp(buf, "GET") == 0 || strcmp(buf, "HEAD") == 0 || + strcmp(buf, "POST") == 0) + { + if (buf[0] == 'H') + cn->reqtype = TYPE_HEAD; + else if (buf[0] == 'P') + cn->reqtype = TYPE_POST; + + if ((delim = strchr(value, ' ')) == NULL) /* expect HTTP type */ + return 0; + + *delim++ = 0; + urldecode(value); + + if (sanitizefile(value) == 0) + { + send_error(cn, 403); + return 0; + } + +#if defined(CONFIG_HTTP_HAS_CGI) + decode_path_info(cn, value); +#else + my_strncpy(cn->filereq, value, MAXREQUESTLENGTH); +#endif + cn->if_modified_since = -1; + if (strcmp(delim, "HTTP/1.0") == 0) /* v1.0 HTTP? */ + cn->is_v1_0 = 1; + } + else if (strcasecmp(buf, "Host:") == 0) + { + if (sanitizehost(value) == 0) + { + removeconnection(cn); + return 0; + } + + my_strncpy(cn->server_name, value, MAXREQUESTLENGTH); + } + else if (strcasecmp(buf, "Connection:") == 0 && strcmp(value, "close") == 0) + { + cn->close_when_done = 1; + } + else if (strcasecmp(buf, "If-Modified-Since:") == 0) + { + cn->if_modified_since = tdate_parse(value); + } + else if (strcasecmp(buf, "Expect:") == 0) + { + /* supposed to be safe to ignore 100-continue */ + if (strcasecmp(value, "100-continue") != 0) { + send_error(cn, 417); /* expectation failed */ + return 0; + } + } +#ifdef CONFIG_HTTP_HAS_AUTHORIZATION + else if (strcasecmp(buf, "Authorization:") == 0 && + strncmp(value, "Basic ", 6) == 0) + { + int size = sizeof(cn->authorization); + if (base64_decode(&value[6], strlen(&value[6]), + (uint8_t *)cn->authorization, &size)) + cn->authorization[0] = 0; /* error */ + else + cn->authorization[size] = 0; + } +#endif +#if defined(CONFIG_HTTP_HAS_CGI) + else if (strcasecmp(buf, "Content-Length:") == 0) + { + sscanf(value, "%d", &cn->content_length); + } + else if (strcasecmp(buf, "Content-Type:") == 0) + { + my_strncpy(cn->cgicontenttype, value, MAXREQUESTLENGTH); + } + else if (strcasecmp(buf, "Cookie:") == 0) + { + my_strncpy(cn->cookie, value, MAXREQUESTLENGTH); + } +#endif + + return 1; +} + +#if defined(CONFIG_HTTP_DIRECTORIES) +static void procdirlisting(struct connstruct *cn) +{ + char buf[MAXREQUESTLENGTH]; + char actualfile[1024]; + + if (cn->reqtype == TYPE_HEAD) + { + snprintf(buf, sizeof(buf), HTTP_VERSION + " 200 OK\nContent-Type: text/html\n\n"); + if (write(cn->networkdesc, buf, strlen(buf)) < 0) + { + printf("procdirlisting: could not write"); + TTY_FLUSH(); + } + + removeconnection(cn); + return; + } + + strcpy(actualfile, cn->actualfile); + +#ifdef WIN32 + strcat(actualfile, "*"); + cn->dirp = FindFirstFile(actualfile, &cn->file_data); + + if (cn->dirp == INVALID_HANDLE_VALUE) + { + send_error(cn, 404); + return; + } +#else + if ((cn->dirp = opendir(actualfile)) == NULL) + { + send_error(cn, 404); + return; + } +#endif + + snprintf(buf, sizeof(buf), HTTP_VERSION + " 200 OK\nContent-Type: text/html\n\n" + "\nDirectory Listing\n" + "

Directory listing of %s://%s%s


\n", + cn->is_ssl ? "https" : "http", cn->server_name, cn->filereq); + special_write(cn, buf, strlen(buf)); + cn->state = STATE_DOING_DIR; +} + +void procdodir(struct connstruct *cn) +{ +#ifndef WIN32 + struct dirent *dp; +#endif + char buf[MAXREQUESTLENGTH]; + char encbuf[1024]; + char *file; + + do + { + buf[0] = 0; + +#ifdef WIN32 + if (!FindNextFile(cn->dirp, &cn->file_data)) +#else + if ((dp = readdir(cn->dirp)) == NULL) +#endif + { + snprintf(buf, sizeof(buf), "\n"); + special_write(cn, buf, strlen(buf)); + removeconnection(cn); +#ifndef WIN32 + closedir(cn->dirp); +#endif + return; + } + +#ifdef WIN32 + file = cn->file_data.cFileName; +#else + file = dp->d_name; +#endif + + /* if no index file, don't display the ".." directory */ + if (cn->filereq[0] == '/' && cn->filereq[1] == '\0' && + strcmp(file, "..") == 0) + continue; + + /* don't display files beginning with "." */ + if (file[0] == '.' && file[1] != '.') + continue; + + /* make sure a '/' is at the end of a directory */ + if (cn->filereq[strlen(cn->filereq)-1] != '/') + strcat(cn->filereq, "/"); + + /* see if the dir + file is another directory */ + snprintf(buf, sizeof(buf), "%s%s", cn->actualfile, file); + if (isdir(buf)) + strcat(file, "/"); + + urlencode((uint8_t *)file, encbuf); + snprintf(buf, sizeof(buf), "%s
\n", + cn->filereq, encbuf, file); + } while (special_write(cn, buf, strlen(buf))); +} + +/* Encode funny chars -> %xx in newly allocated storage */ +/* (preserves '/' !) */ +static void urlencode(const uint8_t *s, char *t) +{ + const uint8_t *p = s; + char *tp = t; + + for (; *p; p++) + { + if ((*p > 0x00 && *p < ',') || + (*p > '9' && *p < 'A') || + (*p > 'Z' && *p < '_') || + (*p > '_' && *p < 'a') || + (*p > 'z' && *p < 0xA1)) + { + sprintf((char *)tp, "%%%02X", *p); + tp += 3; + } + else + { + *tp = *p; + tp++; + } + } + + *tp='\0'; +} + +#endif + +void procreadhead(struct connstruct *cn) +{ + char buf[MAXREADLENGTH], *tp, *next; + int rv; + + memset(buf, 0, sizeof(buf)); + rv = special_read(cn, buf, sizeof(buf)-1); + if (rv <= 0) + { + if (rv < 0 || !cn->is_ssl) /* really dead? */ + removeconnection(cn); + return; + } + + buf[rv] = '\0'; + next = tp = buf; + +#ifdef CONFIG_HTTP_HAS_AUTHORIZATION + cn->authorization[0] = 0; +#endif + + /* Split up lines and send to procheadelem() */ + while (*next != '\0') + { + /* If we have a blank line, advance to next stage */ + if (*next == '\r' || *next == '\n') + { +#if defined(CONFIG_HTTP_HAS_CGI) + if (cn->reqtype == TYPE_POST && cn->content_length > 0) + { + if (init_read_post_data(buf, next, cn, rv) == 0) + return; + } +#endif + + buildactualfile(cn); + cn->state = STATE_WANT_TO_SEND_HEAD; + return; + } + + while (*next != '\r' && *next != '\n' && *next != '\0') + next++; + + if (*next == '\r') + { + *next = '\0'; + next += 2; + } + else if (*next == '\n') + *next++ = '\0'; + + if (procheadelem(cn, tp) == 0) + return; + + tp = next; + } +} + +/* In this function we assume that the file has been checked for + * maliciousness (".."s, etc) and has been decoded + */ +void procsendhead(struct connstruct *cn) +{ + char buf[MAXREQUESTLENGTH]; + struct stat stbuf; + time_t t_time; + struct tm *ptm; + char date[32]; + char last_modified[32]; + char expires[32]; + int file_exists; + + /* are we trying to access a file over the HTTP connection instead of a + * HTTPS connection? Or is this directory disabled? */ + if (htaccess_check(cn)) + { + send_error(cn, 403); + return; + } + +#ifdef CONFIG_HTTP_HAS_AUTHORIZATION + if (auth_check(cn)) /* see if there is a '.htpasswd' file */ + { +#ifdef CONFIG_HTTP_VERBOSE + printf("axhttpd: access to %s denied\n", cn->filereq); TTY_FLUSH(); +#endif + removeconnection(cn); + return; + } +#endif + + file_exists = stat(cn->actualfile, &stbuf); + +#if defined(CONFIG_HTTP_HAS_CGI) + if (file_exists != -1 && cn->is_cgi) + { + proccgi(cn); + return; + } +#endif + + /* look for "index.html"? */ + if (isdir(cn->actualfile)) + { + char tbuf[MAXREQUESTLENGTH]; + snprintf(tbuf, MAXREQUESTLENGTH, "%s%s", cn->actualfile, index_file); + + if ((file_exists = stat(tbuf, &stbuf)) != -1) + my_strncpy(cn->actualfile, tbuf, MAXREQUESTLENGTH); + else + { +#if defined(CONFIG_HTTP_DIRECTORIES) + /* If not, we do a directory listing of it */ + procdirlisting(cn); +#else + send_error(cn, 404); +#endif + return; + } + } + + if (file_exists == -1) + { + send_error(cn, 404); + return; + } + + + time(&t_time); + ptm = gmtime(&t_time); + strftime(date, sizeof(date), rfc1123_format, ptm); + + /* has the file been read before? */ + if (cn->if_modified_since != -1) + + { + ptm = gmtime(&stbuf.st_mtime); + t_time = mktime(ptm); + + if (cn->if_modified_since >= t_time) + { + snprintf(buf, sizeof(buf), HTTP_VERSION" 304 Not Modified\nServer: " + "%s\nDate: %s\n\n", server_version, date); + special_write(cn, buf, strlen(buf)); + cn->state = STATE_WANT_TO_READ_HEAD; + return; + } + } + + if (cn->reqtype == TYPE_HEAD) + { + removeconnection(cn); + return; + } + else + { + int flags = O_RDONLY; +#if defined(WIN32) || defined(CONFIG_PLATFORM_CYGWIN) + flags |= O_BINARY; +#endif + cn->filedesc = open(cn->actualfile, flags); + + if (cn->filedesc < 0) + { + send_error(cn, 404); + return; + } + + ptm = gmtime(&stbuf.st_mtime); + strftime(last_modified, sizeof(last_modified), rfc1123_format, ptm); + t_time += CONFIG_HTTP_TIMEOUT; + ptm = gmtime(&t_time); + strftime(expires, sizeof(expires), rfc1123_format, ptm); + + snprintf(buf, sizeof(buf), HTTP_VERSION" 200 OK\nServer: %s\n" + "Content-Type: %s\nContent-Length: %ld\n" + "Date: %s\nLast-Modified: %s\nExpires: %s\n\n", server_version, + getmimetype(cn->actualfile), (long) stbuf.st_size, + date, last_modified, expires); + + special_write(cn, buf, strlen(buf)); + +#ifdef CONFIG_HTTP_VERBOSE + printf("axhttpd: %s:/%s\n", cn->is_ssl ? "https" : "http", cn->filereq); + TTY_FLUSH(); +#endif + +#ifdef WIN32 + for (;;) + { + procreadfile(cn); + if (cn->filedesc == -1) + break; + + do + { + procsendfile(cn); + } while (cn->state != STATE_WANT_TO_READ_FILE); + } +#else + cn->state = STATE_WANT_TO_READ_FILE; +#endif + } +} + +void procreadfile(struct connstruct *cn) +{ + int rv = read(cn->filedesc, cn->databuf, BLOCKSIZE); + + if (rv <= 0) + { + close(cn->filedesc); + cn->filedesc = -1; + + if (cn->close_when_done) /* close immediately */ + removeconnection(cn); + else + { + if (cn->is_v1_0) /* die now */ + removeconnection(cn); + else /* keep socket open - HTTP 1.1 */ + { + cn->state = STATE_WANT_TO_READ_HEAD; + cn->numbytes = 0; + } + } + + return; + } + + cn->numbytes = rv; + cn->state = STATE_WANT_TO_SEND_FILE; +} + +void procsendfile(struct connstruct *cn) +{ + int rv = special_write(cn, cn->databuf, cn->numbytes); + + if (rv < 0) + removeconnection(cn); + else if (rv == cn->numbytes) + { + cn->state = STATE_WANT_TO_READ_FILE; + } + else if (rv == 0) + { + /* Do nothing */ + } + else + { + memmove(cn->databuf, cn->databuf + rv, cn->numbytes - rv); + cn->numbytes -= rv; + } +} + +#if defined(CONFIG_HTTP_HAS_CGI) +/* Should this be a bit more dynamic? It would mean more calls to malloc etc */ +#define CGI_ARG_SIZE 17 + +static void proccgi(struct connstruct *cn) +{ + int tpipe[2], spipe[2]; + char *myargs[3]; + char cgienv[CGI_ARG_SIZE][MAXREQUESTLENGTH]; + char * cgiptr[CGI_ARG_SIZE+4]; + const char *type = "HEAD"; + int cgi_index = 0, i; + pid_t pid; +#ifdef WIN32 + int tmp_stdout; +#endif + + snprintf(cgienv[0], MAXREQUESTLENGTH, + HTTP_VERSION" 200 OK\nServer: %s\n%s", + server_version, (cn->reqtype == TYPE_HEAD) ? "\n" : ""); + special_write(cn, cgienv[0], strlen(cgienv[0])); + + if (cn->reqtype == TYPE_HEAD) + { + removeconnection(cn); + return; + } + +#ifdef CONFIG_HTTP_VERBOSE + printf("[CGI]: %s:/%s\n", cn->is_ssl ? "https" : "http", cn->filereq); + TTY_FLUSH(); +#endif + + /* win32 cgi is a bit too painful */ +#ifndef WIN32 + /* set up pipe that is used for sending POST query data to CGI script*/ + if (cn->reqtype == TYPE_POST) + { + if (pipe(spipe) == -1) + { + printf("[CGI]: could not create pipe"); + TTY_FLUSH(); + return; + } + } + + if (pipe(tpipe) == -1) + { + printf("[CGI]: could not create pipe"); + TTY_FLUSH(); + return; + } + + /* + * use vfork() instead of fork() for performance + */ + if ((pid = vfork()) > 0) /* parent */ + { + /* Send POST query data to CGI script */ + if ((cn->reqtype == TYPE_POST) && (cn->content_length > 0)) + { + if (write(spipe[1], cn->post_data, cn->content_length) == -1) + { + printf("[CGI]: could write to pipe"); + TTY_FLUSH(); + return; + } + + close(spipe[0]); + close(spipe[1]); + + /* free the memory that is allocated in read_post_data() */ + free(cn->post_data); + cn->post_data = NULL; + } + + /* Close the write descriptor */ + close(tpipe[1]); + cn->filedesc = tpipe[0]; + cn->state = STATE_WANT_TO_READ_FILE; + cn->close_when_done = 1; + return; + } + + if (pid < 0) /* vfork failed */ + exit(1); + + /* The problem child... */ + + /* Our stdout/stderr goes to the socket */ + dup2(tpipe[1], 1); + dup2(tpipe[1], 2); + close(tpipe[0]); + close(tpipe[1]); + + /* If it was a POST request, send the socket data to our stdin */ + if (cn->reqtype == TYPE_POST) { + dup2(spipe[0], 0); + close(spipe[0]); + close(spipe[1]); + } else /* Otherwise we can shutdown the read side of the sock */ + shutdown(cn->networkdesc, 0); + + myargs[0] = CONFIG_HTTP_CGI_LAUNCHER; + myargs[1] = cn->actualfile; + myargs[2] = NULL; + + /* + * set the cgi args. A url is defined by: + * http://$SERVER_NAME:$SERVER_PORT$SCRIPT_NAME$PATH_INFO?$QUERY_STRING + * TODO: other CGI parameters? + */ + sprintf(cgienv[cgi_index++], "SERVER_SOFTWARE=%s", server_version); + strcpy(cgienv[cgi_index++], "DOCUMENT_ROOT=" CONFIG_HTTP_WEBROOT); + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "SERVER_NAME=%s", cn->server_name); + sprintf(cgienv[cgi_index++], "SERVER_PORT=%d", + cn->is_ssl ? CONFIG_HTTP_HTTPS_PORT : CONFIG_HTTP_PORT); + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "REQUEST_URI=%s", cn->uri_request); + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "SCRIPT_NAME=%s", cn->filereq); + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "PATH_INFO=%s", cn->uri_path_info); + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "QUERY_STRING=%s", cn->uri_query); + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "REMOTE_ADDR=%s", cn->remote_addr); + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "HTTP_COOKIE=%s", cn->cookie); /* note: small size */ +#if defined(CONFIG_HTTP_HAS_AUTHORIZATION) + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "REMOTE_USER=%s", cn->authorization); +#endif + + switch (cn->reqtype) + { + case TYPE_GET: + type = "GET"; + break; + +#if defined(CONFIG_HTTP_HAS_CGI) + case TYPE_POST: + type = "POST"; + sprintf(cgienv[cgi_index++], + "CONTENT_LENGTH=%d", cn->content_length); + snprintf(cgienv[cgi_index++], MAXREQUESTLENGTH, + "CONTENT_TYPE=%s", cn->cgicontenttype); + break; +#endif + } + + sprintf(cgienv[cgi_index++], "REQUEST_METHOD=%s", type); + + if (cn->is_ssl) + strcpy(cgienv[cgi_index++], "HTTPS=on"); + + if (cgi_index >= CGI_ARG_SIZE) + { + printf("Content-type: text/plain\n\nToo many CGI args (%d, %d)\n", + cgi_index, CGI_ARG_SIZE); + _exit(1); + } + + /* copy across the pointer indexes */ + for (i = 0; i < cgi_index; i++) + cgiptr[i] = cgienv[i]; + + cgiptr[i++] = "AUTH_TYPE=Basic"; + cgiptr[i++] = "GATEWAY_INTERFACE=CGI/1.1"; + cgiptr[i++] = "SERVER_PROTOCOL="HTTP_VERSION; + cgiptr[i] = NULL; + + execve(myargs[0], myargs, cgiptr); + printf("Content-type: text/plain\n\nshouldn't get here\n"); + _exit(1); +#endif +} + +static char * cgi_filetype_match(struct connstruct *cn, const char *fn) +{ + struct cgiextstruct *tp = cgiexts; + + while (tp != NULL) + { + char *t; + + if ((t = strstr(fn, tp->ext)) != NULL) + { + t += strlen(tp->ext); + + if (*t == '/' || *t == '\0') + return t; + else + return NULL; + + } + + tp = tp->next; + } + + return NULL; +} + +static void decode_path_info(struct connstruct *cn, char *path_info) +{ + char *cgi_delim; + +#if defined(CONFIG_HTTP_HAS_CGI) + cn->is_cgi = 0; +#endif + *cn->uri_request = '\0'; + *cn->uri_path_info = '\0'; + *cn->uri_query = '\0'; + + my_strncpy(cn->uri_request, path_info, MAXREQUESTLENGTH); + + /* query info? */ + if ((cgi_delim = strchr(path_info, '?'))) + { + *cgi_delim = '\0'; + my_strncpy(cn->uri_query, cgi_delim+1, MAXREQUESTLENGTH); + } + +#if defined(CONFIG_HTTP_HAS_CGI) + if ((cgi_delim = cgi_filetype_match(cn, path_info)) != NULL) + { + cn->is_cgi = 1; /* definitely a CGI script */ + + /* path info? */ + if (*cgi_delim != '\0') + { + my_strncpy(cn->uri_path_info, cgi_delim, MAXREQUESTLENGTH); + *cgi_delim = '\0'; + } + } +#endif + + /* the bit at the start must be the script name */ + my_strncpy(cn->filereq, path_info, MAXREQUESTLENGTH); +} + +static int init_read_post_data(char *buf, char *data, + struct connstruct *cn, int old_rv) +{ + char *next = data; + int rv = old_rv; + char *post_data; + + /* Too much Post data to send. MAXPOSTDATASIZE should be + configured (now it can be changed in the header file) */ + if (cn->content_length > MAXPOSTDATASIZE) + { + send_error(cn, 418); + return 0; + } + + /* remove CRLF */ + while ((*next == '\r' || *next == '\n') && (next < &buf[rv])) + next++; + + if (cn->post_data == NULL) + { + /* Allocate buffer for the POST data that will be used by proccgi + to send POST data to the CGI script */ + cn->post_data = (char *)calloc(1, (cn->content_length + 1)); + } + + cn->post_state = 0; + cn->post_read = 0; + post_data = cn->post_data; + + while (next < &buf[rv]) + { + /* copy POST data to buffer */ + *post_data++ = *next++; + cn->post_read++; + if (cn->post_read == cn->content_length) + { + /* No more POST data to be copied */ + *post_data = '\0'; + return 1; + } + } + + /* More POST data has to be read. read_post_data will continue with that */ + cn->post_state = 1; + return 0; +} + +void read_post_data(struct connstruct *cn) +{ + char buf[MAXREADLENGTH], *next; + char *post_data; + int rv; + + memset(buf, 0, sizeof(buf)); + rv = special_read(cn, buf, sizeof(buf)-1); + if (rv <= 0) + { + if (rv < 0 || !cn->is_ssl) /* really dead? */ + removeconnection(cn); + return; + } + + buf[rv] = '\0'; + next = buf; + post_data = &cn->post_data[cn->post_read]; + + while (next < &buf[rv]) + { + *post_data++ = *next++; + cn->post_read++; + + if (cn->post_read == cn->content_length) + { + /* No more POST data to be copied */ + *post_data='\0'; + cn->post_state = 0; + buildactualfile(cn); + cn->state = STATE_WANT_TO_SEND_HEAD; + return; + } + } + + /* More POST data to read */ +} + +#endif /* CONFIG_HTTP_HAS_CGI */ + +/* Decode string %xx -> char (in place) */ +static void urldecode(char *buf) +{ + int v; + char *p, *s, *w; + + w = p = buf; + + while (*p) + { + v = 0; + + if (*p == '%') + { + s = p; + s++; + + if (isxdigit((int) s[0]) && isxdigit((int) s[1])) + { + v = hexit(s[0])*16 + hexit(s[1]); + + if (v) + { + /* do not decode %00 to null char */ + *w = (char)v; + p = &s[1]; + } + } + + } + + if (!v) *w=*p; + p++; + w++; + } + + *w='\0'; +} + +static int hexit(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + else + return 0; +} + +static void buildactualfile(struct connstruct *cn) +{ + char *cp; + snprintf(cn->actualfile, MAXREQUESTLENGTH, ".%s", cn->filereq); + +#ifndef WIN32 + /* Add directory slash if not there */ + if (isdir(cn->actualfile) && + cn->actualfile[strlen(cn->actualfile)-1] != '/') + strcat(cn->actualfile, "/"); + + /* work out the directory name */ + strncpy(cn->dirname, cn->actualfile, MAXREQUESTLENGTH); + if ((cp = strrchr(cn->dirname, '/')) == NULL) + cn->dirname[0] = 0; + else + *cp = 0; +#else + { + char curr_dir[MAXREQUESTLENGTH]; + char path[MAXREQUESTLENGTH]; + char *t = cn->actualfile; + + GetCurrentDirectory(MAXREQUESTLENGTH, curr_dir); + + /* convert all the forward slashes to back slashes */ + while ((t = strchr(t, '/'))) + *t++ = '\\'; + + snprintf(path, MAXREQUESTLENGTH, "%s%s", curr_dir, cn->actualfile); + memcpy(cn->actualfile, path, MAXREQUESTLENGTH); + + /* Add directory slash if not there */ + if (isdir(cn->actualfile) && + cn->actualfile[strlen(cn->actualfile)-1] != '\\') + strcat(cn->actualfile, "\\"); + + /* work out the directory name */ + strncpy(cn->dirname, cn->actualfile, MAXREQUESTLENGTH); + if ((cp = strrchr(cn->dirname, '\\')) == NULL) + cn->dirname[0] = 0; + else + *cp = 0; + } +#endif +} + +static int sanitizefile(const char *buf) +{ + int len, i; + + /* Don't accept anything not starting with a / */ + if (*buf != '/') + return 0; + + len = strlen(buf); + for (i = 0; i < len; i++) + { + /* Check for "/." i.e. don't send files starting with a . */ + if (buf[i] == '/' && buf[i+1] == '.') + return 0; + } + + return 1; +} + +static int sanitizehost(char *buf) +{ + while (*buf != '\0') + { + /* Handle the port */ + if (*buf == ':') + { + *buf = '\0'; + return 1; + } + + /* Enforce some basic URL rules... */ + if ((isalnum((int)(*buf)) == 0 && *buf != '-' && *buf != '.') || + (*buf == '.' && *(buf+1) == '.') || + (*buf == '.' && *(buf+1) == '-') || + (*buf == '-' && *(buf+1) == '.')) + return 0; + + buf++; + } + + return 1; +} + +static FILE * exist_check(struct connstruct *cn, const char *check_file) +{ + char pathname[MAXREQUESTLENGTH]; + snprintf(pathname, MAXREQUESTLENGTH, "%s/%s", cn->dirname, check_file); + return fopen(pathname, "r"); +} + +#ifdef CONFIG_HTTP_HAS_AUTHORIZATION +static void send_authenticate(struct connstruct *cn, const char *realm) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), HTTP_VERSION" 401 Unauthorized\n" + "WWW-Authenticate: Basic\n" + "realm=\"%s\"\n", realm); + special_write(cn, buf, strlen(buf)); +} + +static int check_digest(char *salt, const char *msg_passwd) +{ + uint8_t b256_salt[MAXREQUESTLENGTH]; + uint8_t real_passwd[MD5_SIZE]; + int salt_size = sizeof(b256_salt); + int password_size = sizeof(real_passwd); + char *b64_passwd; + uint8_t md5_result[MD5_SIZE]; + MD5_CTX ctx; + + /* retrieve the salt */ + if ((b64_passwd = strchr(salt, '$')) == NULL) + return -1; + + *b64_passwd++ = 0; + if (base64_decode(salt, strlen(salt), b256_salt, &salt_size)) + return -1; + + if (base64_decode(b64_passwd, strlen(b64_passwd), real_passwd, + &password_size)) + return -1; + + /* very simple MD5 crypt algorithm, but then the salt we use is large */ + MD5_Init(&ctx); + MD5_Update(&ctx, b256_salt, salt_size); /* process the salt */ + MD5_Update(&ctx, (uint8_t *)msg_passwd, strlen(msg_passwd)); + MD5_Final(md5_result, &ctx); + return memcmp(md5_result, real_passwd, MD5_SIZE);/* 0 = ok */ +} + +static int auth_check(struct connstruct *cn) +{ + char line[MAXREQUESTLENGTH]; + FILE *fp; + char *cp; + + if ((fp = exist_check(cn, ".htpasswd")) == NULL) + return 0; /* no .htpasswd file, so let though */ + + if (cn->authorization[0] == 0) + goto error; + + /* cn->authorization is in form "username:password" */ + if ((cp = strchr(cn->authorization, ':')) == NULL) + goto error; + else + *cp++ = 0; /* cp becomes the password */ + + while (fgets(line, sizeof(line), fp) != NULL) + { + char *b64_file_passwd; + int l = strlen(line); + + /* nuke newline */ + if (line[l-1] == '\n') + line[l-1] = 0; + + /* line is form "username:salt(b64)$password(b64)" */ + if ((b64_file_passwd = strchr(line, ':')) == NULL) + continue; + + *b64_file_passwd++ = 0; + + if (strcmp(line, cn->authorization)) /* our user? */ + continue; + + if (check_digest(b64_file_passwd, cp) == 0) + { + fclose(fp); + return 0; + } + } + +error: + fclose(fp); + send_authenticate(cn, cn->server_name); + return -1; +} +#endif + +static int htaccess_check(struct connstruct *cn) +{ + char line[MAXREQUESTLENGTH]; + FILE *fp; + int ret = 0; + + if ((fp = exist_check(cn, ".htaccess")) == NULL) + return 0; /* no .htaccess file, so let though */ + + while (fgets(line, sizeof(line), fp) != NULL) + { + if (strstr(line, "Deny all") || /* access to this dir denied */ + /* Access will be denied unless SSL is active */ + (!cn->is_ssl && strstr(line, "SSLRequireSSL")) || + /* Access will be denied if SSL is active */ + (cn->is_ssl && strstr(line, "SSLDenySSL"))) + { + ret = -1; + break; + } + } + + fclose(fp); + return ret; +} + +static void send_error(struct connstruct *cn, int err) +{ + char buf[MAXREQUESTLENGTH]; + char *title; + char *text; + + switch (err) + { + case 403: + title = "Forbidden"; + text = "File is protected"; +#ifdef CONFIG_HTTP_VERBOSE + printf("axhttpd: access to %s denied\n", cn->filereq); TTY_FLUSH(); +#endif + break; + + case 404: + title = "Not Found"; + text = title; + break; + + case 418: + title = "POST data size is too large"; + text = title; + break; + + default: + title = "Unknown"; + text = "Unknown"; + break; + } + + snprintf(buf, sizeof(buf), HTTP_VERSION" 200 OK\n" + "Content-Type: text/html\n\n" + "\n%s\n" + "

Error %d - %s

\n\n", + title, err, text); + special_write(cn, buf, strlen(buf)); + +#ifdef CONFIG_HTTP_VERBOSE + printf("axhttpd: http error: %s [%d]\n", title, err); TTY_FLUSH(); +#endif + removeconnection(cn); +} + +static const char *getmimetype(const char *name) +{ + /* only bother with a few mime types - let the browser figure the rest out */ + if (strstr(name, ".htm")) + return "text/html"; + else if (strstr(name, ".css")) + return "text/css"; + else if (strstr(name, ".php")) + return "application/x-http-php"; + else + return "application/octet-stream"; +} + +static int special_write(struct connstruct *cn, + const char *buf, size_t count) +{ + if (cn->is_ssl) + { + SSL *ssl = cn->ssl; + return ssl ? ssl_write(ssl, (uint8_t *)buf, count) : -1; + } + else + return SOCKET_WRITE(cn->networkdesc, buf, count); +} + +static int special_read(struct connstruct *cn, void *buf, size_t count) +{ + int res; + + if (cn->is_ssl) + { + uint8_t *read_buf; + if ((res = ssl_read(cn->ssl, &read_buf)) > SSL_OK) + { + memcpy(buf, read_buf, res > (int)count ? count : res); + } + } + else + res = SOCKET_READ(cn->networkdesc, buf, count); + + return res; +} + diff --git a/circuitpython/lib/axtls/httpd/tdate_parse.c b/circuitpython/lib/axtls/httpd/tdate_parse.c new file mode 100644 index 0000000..7165bde --- /dev/null +++ b/circuitpython/lib/axtls/httpd/tdate_parse.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) Cameron Rich + * + * 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 axTLS project 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 +#include +#include +#include +#include +#include +#include "axhttp.h" + +struct day_mon_map +{ + const char* s; + uint8_t l; +}; + +static struct day_mon_map wday_tab[] = +{ + { "Sun", 0 }, { "Mon", 1 }, { "Tue", 2 }, { "Wed", 3 }, + { "Thu", 4 }, { "Fri", 5 }, { "Sat", 6 }, +}; + +static struct day_mon_map mon_tab[] = +{ + { "Jan", 0 }, { "Feb", 1 }, { "Mar", 2 }, { "Apr", 3 }, + { "May", 4 }, { "Jun", 5 }, { "Jul", 6 }, { "Aug", 7 }, + { "Sep", 8 }, { "Oct", 9 }, { "Nov", 10 }, { "Dec", 11 }, +}; + +static int day_mon_map_compare(const char *v1, const char *v2) +{ + return strcmp(((struct day_mon_map*)v1)->s, ((struct day_mon_map*)v2)->s); +} + +void tdate_init(void) +{ + qsort(wday_tab, sizeof(wday_tab)/sizeof(struct day_mon_map), + sizeof(struct day_mon_map), + (int (*)(const void *, const void *))day_mon_map_compare); + qsort(mon_tab, sizeof(mon_tab)/sizeof(struct day_mon_map), + sizeof(struct day_mon_map), + (int (*)(const void *, const void *))day_mon_map_compare); +} + +static int8_t day_mon_map_search(const char* str, + const struct day_mon_map* tab, int n) +{ + struct day_mon_map *search = bsearch(&str, tab, n, + sizeof(struct day_mon_map), + (int (*)(const void *, const void *))day_mon_map_compare); + return search ? search->l : -1; +} + +time_t tdate_parse(const char* str) +{ + struct tm tm; + char str_mon[4], str_wday[4]; + int tm_sec, tm_min, tm_hour, tm_mday, tm_year; + + /* Initialize. */ + memset(&tm, 0, sizeof(struct tm)); + + /* wdy, DD mth YY HH:MM:SS GMT */ + if (sscanf(str, "%3[a-zA-Z], %d %3[a-zA-Z] %d %d:%d:%d GMT", + str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, + &tm_sec) == 7) + { + int8_t tm_wday = day_mon_map_search(str_wday, wday_tab, + sizeof(wday_tab)/sizeof(struct day_mon_map)); + int8_t tm_mon = day_mon_map_search(str_mon, mon_tab, + sizeof(mon_tab)/sizeof(struct day_mon_map)); + + if (tm_wday < 0 || tm_mon < 0) + return -1; + + tm.tm_wday = tm_wday; + tm.tm_mon = tm_mon; + tm.tm_mday = tm_mday; + tm.tm_hour = tm_hour; + tm.tm_min = tm_min; + tm.tm_sec = tm_sec; + tm.tm_year = tm_year - 1900; + return mktime(&tm); + } + + return -1; /* error */ +} diff --git a/circuitpython/lib/axtls/samples/Config.in b/circuitpython/lib/axtls/samples/Config.in new file mode 100644 index 0000000..ecad25e --- /dev/null +++ b/circuitpython/lib/axtls/samples/Config.in @@ -0,0 +1,63 @@ +# +# For a description of the syntax of this configuration file, +# see scripts/config/Kconfig-language.txt +# +menu "Samples" + +config CONFIG_SAMPLES + bool "Create Samples" + default y + help + axTLS contains various sample code. + + Select Y here if you want to build the various samples. + +config CONFIG_C_SAMPLES + bool "axssl - C version" + default y + depends on CONFIG_SAMPLES + help + Build the "C" version of axssl. The features enabled are very + dependent on the build mode ('full' mode will give all features). + +config CONFIG_CSHARP_SAMPLES + bool "axssl - C# version" + default y + depends on CONFIG_SAMPLES && CONFIG_CSHARP_BINDINGS + help + Build the "C#" version of axssl. The features enabled are very + dependent on the build mode ('full' mode will give all features). + +config CONFIG_VBNET_SAMPLES + bool "axssl - VB.NET version" + default y + depends on CONFIG_SAMPLES && CONFIG_VBNET_BINDINGS + help + Build the "VB.NET" version of axssl. The features enabled are very + dependent on the build mode ('full' mode will give all features). + +config CONFIG_JAVA_SAMPLES + bool "axssl - Java version" + default y + depends on CONFIG_SAMPLES && CONFIG_JAVA_BINDINGS + help + Build the "Java" version of axssl. The features enabled are very + dependent on the build mode ('full' mode will give all features). + +config CONFIG_PERL_SAMPLES + bool "axssl - Perl version" + default y + depends on CONFIG_SAMPLES && CONFIG_PERL_BINDINGS + help + Build the "Perl" version of axssl. The features enabled are very + dependent on the build mode ('full' mode will give all features). + +config CONFIG_LUA_SAMPLES + bool "axssl - Lua version" + default y + depends on CONFIG_SAMPLES && CONFIG_LUA_BINDINGS + help + Build the "Lua" version of axssl. The features enabled are very + dependent on the build mode ('full' mode will give all features). +endmenu + diff --git a/circuitpython/lib/axtls/samples/Makefile b/circuitpython/lib/axtls/samples/Makefile new file mode 100644 index 0000000..afbdd43 --- /dev/null +++ b/circuitpython/lib/axtls/samples/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +all: + +include ../config/.config +include ../config/makefile.conf + +all: +ifdef CONFIG_C_SAMPLES + $(MAKE) -C c +endif +ifdef CONFIG_CSHARP_SAMPLES + $(MAKE) -C csharp +endif +ifdef CONFIG_VBNET_SAMPLES + $(MAKE) -C vbnet +endif +ifdef CONFIG_JAVA_SAMPLES + $(MAKE) -C java +endif +ifdef CONFIG_PERL_SAMPLES + $(MAKE) -C perl +endif +ifdef CONFIG_LUA_SAMPLES + $(MAKE) -C lua +endif + +clean:: + $(MAKE) -C c clean + $(MAKE) -C csharp clean + $(MAKE) -C vbnet clean + $(MAKE) -C java clean + $(MAKE) -C perl clean + $(MAKE) -C lua clean diff --git a/circuitpython/lib/axtls/samples/c/Makefile b/circuitpython/lib/axtls/samples/c/Makefile new file mode 100644 index 0000000..1966eec --- /dev/null +++ b/circuitpython/lib/axtls/samples/c/Makefile @@ -0,0 +1,77 @@ +# +# Copyright (c) 2007-2016, Cameron Rich +# +# 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 axTLS project 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. +# + +all : sample + +AXTLS_HOME=../.. + +include $(AXTLS_HOME)/config/.config +include $(AXTLS_HOME)/config/makefile.conf + +ifndef CONFIG_PLATFORM_WIN32 + +ifdef CONFIG_PLATFORM_CYGWIN +TARGET=$(AXTLS_HOME)/$(STAGE)/axssl.exe +else +TARGET=$(AXTLS_HOME)/$(STAGE)/axssl +endif # cygwin + +LIBS=$(AXTLS_HOME)/$(STAGE) +else +TARGET=$(AXTLS_HOME)/$(STAGE)/axssl.exe +endif + +ifndef CONFIG_C_SAMPLES +sample: + +else +sample : $(TARGET) +OBJ= axssl.o +include $(AXTLS_HOME)/config/makefile.post + +ifndef CONFIG_PLATFORM_WIN32 + +$(TARGET): $(OBJ) $(LIBS)/libaxtls.a + $(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)/libaxtls.a +# $(LD) $(LDFLAGS) -o $@ $(OBJ) -L$(LIBS) -laxtls (shared library) +ifdef CONFIG_STRIP_UNWANTED_SECTIONS + $(STRIP) --remove-section=.comment $(TARGET) +endif # use strip +else # Win32 + +$(TARGET): $(OBJ) + $(LD) $(LDFLAGS) $(AXTLS_HOME)/config/axtls.res /out:$@ $^ /libpath:"$(AXTLS_HOME)/$(STAGE)" axtls.lib +endif + +endif # CONFIG_C_SAMPLES + +clean:: + -@rm -f $(AXTLS_HOME)/$(STAGE)/axssl* + diff --git a/circuitpython/lib/axtls/samples/c/axssl.c b/circuitpython/lib/axtls/samples/c/axssl.c new file mode 100644 index 0000000..8de9d60 --- /dev/null +++ b/circuitpython/lib/axtls/samples/c/axssl.c @@ -0,0 +1,904 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Demonstrate the use of the axTLS library in C with a set of + * command-line parameters similar to openssl. In fact, openssl clients + * should be able to communicate with axTLS servers and visa-versa. + * + * This code has various bits enabled depending on the configuration. To enable + * the most interesting version, compile with the 'full mode' enabled. + * + * To see what options you have, run the following: + * > axssl s_server -? + * > axssl s_client -? + * + * The axtls shared library must be in the same directory or be found + * by the OS. + */ +#include +#include +#include +#include "os_port.h" +#include "ssl.h" + +/* define standard input */ +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + +static void do_server(int argc, char *argv[]); +static void print_options(char *option); +static void print_server_options(char *option); +static void do_client(int argc, char *argv[]); +static void print_client_options(char *option); +static void display_cipher(SSL *ssl); +static void display_session_id(SSL *ssl); + +/** + * Main entry point. Doesn't do much except works out whether we are a client + * or a server. + */ +int main(int argc, char *argv[]) +{ +#ifdef WIN32 + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(2, 2); + WSAStartup(wVersionRequested, &wsaData); +#elif !defined(CONFIG_PLATFORM_SOLARIS) + signal(SIGPIPE, SIG_IGN); /* ignore pipe errors */ +#endif + + if (argc == 2 && strcmp(argv[1], "version") == 0) + { + printf("axssl %s %s\n", ssl_version(), __DATE__); + exit(0); + } + + if (argc < 2 || ( + strcmp(argv[1], "s_server") && strcmp(argv[1], "s_client"))) + print_options(argc > 1 ? argv[1] : ""); + +// strcmp(argv[1], "s_server") ? + do_client(argc, argv);// : do_server(argc, argv); + return 0; +} + +/** + * Implement the SSL server logic. + */ +static void do_server(int argc, char *argv[]) +{ + int i = 2; + uint16_t port = 4433; + uint32_t options = SSL_DISPLAY_CERTS; + int client_fd; + SSL_CTX *ssl_ctx; + int server_fd, res = 0; + socklen_t client_len; +#ifndef CONFIG_SSL_SKELETON_MODE + char *private_key_file = NULL; + const char *password = NULL; + char **cert; + int cert_index = 0; + int cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET); +#endif +#ifdef WIN32 + char yes = 1; +#else + int yes = 1; +#endif + struct sockaddr_in serv_addr; + struct sockaddr_in client_addr; + int quiet = 0; +#ifdef CONFIG_SSL_CERT_VERIFICATION + int ca_cert_index = 0; + int ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET); + char **ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size); +#endif + fd_set read_set; + +#ifndef CONFIG_SSL_SKELETON_MODE + cert = (char **)calloc(1, sizeof(char *)*cert_size); +#endif + + while (i < argc) + { + if (strcmp(argv[i], "-accept") == 0) + { + if (i >= argc-1) + { + print_server_options(argv[i]); + } + + port = atoi(argv[++i]); + } +#ifndef CONFIG_SSL_SKELETON_MODE + else if (strcmp(argv[i], "-cert") == 0) + { + if (i >= argc-1 || cert_index >= cert_size) + { + print_server_options(argv[i]); + } + + cert[cert_index++] = argv[++i]; + } + else if (strcmp(argv[i], "-key") == 0) + { + if (i >= argc-1) + { + print_server_options(argv[i]); + } + + private_key_file = argv[++i]; + options |= SSL_NO_DEFAULT_KEY; + } + else if (strcmp(argv[i], "-pass") == 0) + { + if (i >= argc-1) + { + print_server_options(argv[i]); + } + + password = argv[++i]; + } +#endif + else if (strcmp(argv[i], "-quiet") == 0) + { + quiet = 1; + options &= ~SSL_DISPLAY_CERTS; + } +#ifdef CONFIG_SSL_CERT_VERIFICATION + else if (strcmp(argv[i], "-verify") == 0) + { + options |= SSL_CLIENT_AUTHENTICATION; + } + else if (strcmp(argv[i], "-CAfile") == 0) + { + if (i >= argc-1 || ca_cert_index >= ca_cert_size) + { + print_server_options(argv[i]); + } + + ca_cert[ca_cert_index++] = argv[++i]; + } +#endif +#ifdef CONFIG_SSL_FULL_MODE + else if (strcmp(argv[i], "-debug") == 0) + { + options |= SSL_DISPLAY_BYTES; + } + else if (strcmp(argv[i], "-state") == 0) + { + options |= SSL_DISPLAY_STATES; + } + else if (strcmp(argv[i], "-show-rsa") == 0) + { + options |= SSL_DISPLAY_RSA; + } +#endif + else /* don't know what this is */ + { + print_server_options(argv[i]); + } + + i++; + } + + if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_SVR_SESS)) == NULL) + { + fprintf(stderr, "Error: Server context is invalid\n"); + exit(1); + } + +#ifndef CONFIG_SSL_SKELETON_MODE + if (private_key_file) + { + int obj_type = SSL_OBJ_RSA_KEY; + + /* auto-detect the key type from the file extension */ + if (strstr(private_key_file, ".p8")) + obj_type = SSL_OBJ_PKCS8; + else if (strstr(private_key_file, ".p12")) + obj_type = SSL_OBJ_PKCS12; + + if (ssl_obj_load(ssl_ctx, obj_type, private_key_file, password)) + { + fprintf(stderr, "Error: Private key '%s' is undefined.\n", + private_key_file); + exit(1); + } + } + + for (i = 0; i < cert_index; i++) + { + if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL)) + { + printf("Certificate '%s' is undefined.\n", cert[i]); + exit(1); + } + } +#endif + +#ifdef CONFIG_SSL_CERT_VERIFICATION + for (i = 0; i < ca_cert_index; i++) + { + if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL)) + { + printf("Certificate '%s' is undefined.\n", ca_cert[i]); + exit(1); + } + } + + free(ca_cert); +#endif +#ifndef CONFIG_SSL_SKELETON_MODE + free(cert); +#endif + + /* Create socket for incoming connections */ + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + perror("socket"); + return; + } + + setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); + + /* Construct local address structure */ + memset(&serv_addr, 0, sizeof(serv_addr)); /* Zero out structure */ + serv_addr.sin_family = AF_INET; /* Internet address family */ + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + serv_addr.sin_port = htons(port); /* Local port */ + + /* Bind to the local address */ + if (bind(server_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) + { + perror("bind"); + exit(1); + } + + if (listen(server_fd, 5) < 0) + { + perror("listen"); + exit(1); + } + + client_len = sizeof(client_addr); + + /************************************************************************* + * This is where the interesting stuff happens. Up until now we've + * just been setting up sockets etc. Now we do the SSL handshake. + *************************************************************************/ + for (;;) + { + SSL *ssl; + int reconnected = 0; + + if (!quiet) + { + printf("ACCEPT\n"); + TTY_FLUSH(); + } + + if ((client_fd = accept(server_fd, + (struct sockaddr *)&client_addr, &client_len)) < 0) + { + break; + } + + ssl = ssl_server_new(ssl_ctx, client_fd); + + /* now read (and display) whatever the client sends us */ + for (;;) + { + /* allow parallel reading of client and standard input */ + FD_ZERO(&read_set); + FD_SET(client_fd, &read_set); + +#ifndef WIN32 + /* win32 doesn't like mixing up stdin and sockets */ + if (isatty(STDIN_FILENO))/* but only if we are in an active shell */ + { + FD_SET(STDIN_FILENO, &read_set); + } + + if ((res = select(client_fd+1, &read_set, NULL, NULL, NULL)) > 0) + { + uint8_t buf[1024]; + + /* read standard input? */ + if (FD_ISSET(STDIN_FILENO, &read_set)) + { + if (fgets((char *)buf, sizeof(buf), stdin) == NULL) + { + res = SSL_ERROR_CONN_LOST; + } + else + { + /* small hack to check renegotiation */ + if (buf[0] == 'r' && (buf[1] == '\n' || buf[1] == '\r')) + { + res = ssl_renegotiate(ssl); + } + else /* write our ramblings to the client */ + { + res = ssl_write(ssl, buf, strlen((char *)buf)+1); + } + } + } + else /* a socket read */ +#endif + { + /* keep reading until we get something interesting */ + uint8_t *read_buf; + + if ((res = ssl_read(ssl, &read_buf)) == SSL_OK) + { + /* are we in the middle of doing a handshake? */ + if (ssl_handshake_status(ssl) != SSL_OK) + { + reconnected = 0; + } + else if (!reconnected) + { + /* we are connected/reconnected */ + if (!quiet) + { + display_session_id(ssl); + display_cipher(ssl); + } + + reconnected = 1; + } + } + + if (res > SSL_OK) /* display our interesting output */ + { + int written = 0; + while (written < res) + { + written += write(STDOUT_FILENO, read_buf+written, + res-written); + } + TTY_FLUSH(); + } + else if (res == SSL_CLOSE_NOTIFY) + { + printf("shutting down SSL\n"); + TTY_FLUSH(); + } + else if (res < SSL_OK && !quiet) + { + ssl_display_error(res); + } + } +#ifndef WIN32 + } +#endif + + if (res < SSL_OK) + { + if (!quiet) + { + printf("CONNECTION CLOSED\n"); + TTY_FLUSH(); + } + + break; + } + } + + /* client was disconnected or the handshake failed. */ + ssl_free(ssl); + SOCKET_CLOSE(client_fd); + } + + ssl_ctx_free(ssl_ctx); +} + +/** + * Implement the SSL client logic. + */ +static void do_client(int argc, char *argv[]) +{ +#ifdef CONFIG_SSL_ENABLE_CLIENT + int res, i = 2; + uint16_t port = 4433; + uint32_t options = SSL_SERVER_VERIFY_LATER|SSL_DISPLAY_CERTS; + int client_fd; + char *private_key_file = NULL; + struct sockaddr_in client_addr; + struct hostent *hostent; + int reconnect = 0; + uint32_t sin_addr; + SSL_CTX *ssl_ctx; + SSL *ssl = NULL; + int quiet = 0; + int cert_index = 0, ca_cert_index = 0; + int cert_size, ca_cert_size; + char **ca_cert, **cert; + uint8_t session_id[SSL_SESSION_ID_SIZE]; + fd_set read_set; + const char *password = NULL; + SSL_EXTENSIONS *extensions = NULL; + + FD_ZERO(&read_set); + sin_addr = inet_addr("127.0.0.1"); + cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET); + ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET); + ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size); + cert = (char **)calloc(1, sizeof(char *)*cert_size); + + while (i < argc) + { + if (strcmp(argv[i], "-connect") == 0) + { + char *host, *ptr; + + if (i >= argc-1) + { + print_client_options(argv[i]); + } + + host = argv[++i]; + if ((ptr = strchr(host, ':')) == NULL) + { + print_client_options(argv[i]); + } + + *ptr++ = 0; + port = atoi(ptr); + hostent = gethostbyname(host); + + if (hostent == NULL) + { + print_client_options(argv[i]); + } + + sin_addr = *((uint32_t **)hostent->h_addr_list)[0]; + } + else if (strcmp(argv[i], "-cert") == 0) + { + if (i >= argc-1 || cert_index >= cert_size) + { + print_client_options(argv[i]); + } + + cert[cert_index++] = argv[++i]; + } + else if (strcmp(argv[i], "-key") == 0) + { + if (i >= argc-1) + { + print_client_options(argv[i]); + } + + private_key_file = argv[++i]; + options |= SSL_NO_DEFAULT_KEY; + } + else if (strcmp(argv[i], "-CAfile") == 0) + { + if (i >= argc-1 || ca_cert_index >= ca_cert_size) + { + print_client_options(argv[i]); + } + + ca_cert[ca_cert_index++] = argv[++i]; + } + else if (strcmp(argv[i], "-verify") == 0) + { + options &= ~SSL_SERVER_VERIFY_LATER; + } + else if (strcmp(argv[i], "-reconnect") == 0) + { + reconnect = 4; + } + else if (strcmp(argv[i], "-quiet") == 0) + { + quiet = 1; + options &= ~SSL_DISPLAY_CERTS; + } + else if (strcmp(argv[i], "-pass") == 0) + { + if (i >= argc-1) + { + print_client_options(argv[i]); + } + + password = argv[++i]; + } + else if (strcmp(argv[i], "-servername") == 0) + { + if (i >= argc-1) + { + print_client_options(argv[i]); + } + + extensions = ssl_ext_new(); + extensions->host_name = argv[++i]; + } +#ifdef CONFIG_SSL_FULL_MODE + else if (strcmp(argv[i], "-debug") == 0) + { + options |= SSL_DISPLAY_BYTES; + } + else if (strcmp(argv[i], "-state") == 0) + { + options |= SSL_DISPLAY_STATES; + } + else if (strcmp(argv[i], "-show-rsa") == 0) + { + options |= SSL_DISPLAY_RSA; + } +#endif + else /* don't know what this is */ + { + print_client_options(argv[i]); + } + + i++; + } + + if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) + { + fprintf(stderr, "Error: Client context is invalid\n"); + exit(1); + } + +#ifndef CONFIG_SSL_SKELETON_MODE + if (private_key_file) + { + int obj_type = SSL_OBJ_RSA_KEY; + + /* auto-detect the key type from the file extension */ + if (strstr(private_key_file, ".p8")) + obj_type = SSL_OBJ_PKCS8; + else if (strstr(private_key_file, ".p12")) + obj_type = SSL_OBJ_PKCS12; + + if (ssl_obj_load(ssl_ctx, obj_type, private_key_file, password)) + { + fprintf(stderr, "Error: Private key '%s' is undefined.\n", + private_key_file); + exit(1); + } + } + + for (i = 0; i < cert_index; i++) + { + if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL)) + { + printf("Certificate '%s' is undefined.\n", cert[i]); + exit(1); + } + } + + for (i = 0; i < ca_cert_index; i++) + { + if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL)) + { + printf("Certificate '%s' is undefined.\n", ca_cert[i]); + exit(1); + } + } +#endif + + free(cert); + free(ca_cert); + + /************************************************************************* + * This is where the interesting stuff happens. Up until now we've + * just been setting up sockets etc. Now we do the SSL handshake. + *************************************************************************/ + client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + memset(&client_addr, 0, sizeof(client_addr)); + client_addr.sin_family = AF_INET; + client_addr.sin_port = htons(port); + client_addr.sin_addr.s_addr = sin_addr; + + if (connect(client_fd, (struct sockaddr *)&client_addr, + sizeof(client_addr)) < 0) + { + perror("connect"); + exit(1); + } + + if (!quiet) + { + printf("CONNECTED\n"); + TTY_FLUSH(); + } + + /* Try session resumption? */ + if (reconnect) + { + while (reconnect--) + { + ssl = ssl_client_new(ssl_ctx, client_fd, session_id, + sizeof(session_id), extensions); + if ((res = ssl_handshake_status(ssl)) != SSL_OK) + { + if (!quiet) + { + ssl_display_error(res); + } + + ssl_free(ssl); + exit(1); + } + + display_session_id(ssl); + memcpy(session_id, ssl_get_session_id(ssl), SSL_SESSION_ID_SIZE); + + if (reconnect) + { + ssl_free(ssl); + SOCKET_CLOSE(client_fd); + + client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + connect(client_fd, (struct sockaddr *)&client_addr, + sizeof(client_addr)); + } + } + } + else + { + ssl = ssl_client_new(ssl_ctx, client_fd, NULL, 0, extensions); + } + + /* check the return status */ + if ((res = ssl_handshake_status(ssl)) != SSL_OK) + { + if (!quiet) + { + ssl_display_error(res); + } + + exit(1); + } + + if (!quiet) + { + display_session_id(ssl); + display_cipher(ssl); + } + + for (;;) + { + uint8_t buf[1024]; + + /* allow parallel reading of server and standard input */ + FD_SET(client_fd, &read_set); +#ifndef WIN32 + /* win32 doesn't like mixing up stdin and sockets */ + FD_SET(STDIN_FILENO, &read_set); + + if ((res = select(client_fd+1, &read_set, NULL, NULL, NULL)) > 0) + { + /* read standard input? */ + if (FD_ISSET(STDIN_FILENO, &read_set)) +#endif + { + if (fgets((char *)buf, sizeof(buf), stdin) == NULL) + { + /* bomb out of here */ + ssl_free(ssl); + break; + } + else + { + /* small hack to check renegotiation */ + if (buf[0] == 'R' && (buf[1] == '\n' || buf[1] == '\r')) + { + res = ssl_renegotiate(ssl); + } + else + { + res = ssl_write(ssl, buf, strlen((char *)buf)); + } + } + } +#ifndef WIN32 + else /* a socket read */ + { + uint8_t *read_buf; + + res = ssl_read(ssl, &read_buf); + + if (res > 0) /* display our interesting output */ + { + int written = 0; + while (written < res) + { + written += write(STDOUT_FILENO, read_buf+written, + res-written); + } + TTY_FLUSH(); + } + } + } +#endif + + if (res < 0) + { + if (!quiet) + { + ssl_display_error(res); + } + + break; /* get outta here */ + } + } + + ssl_ctx_free(ssl_ctx); + SOCKET_CLOSE(client_fd); +#else + print_client_options(argv[1]); +#endif +} + +/** + * We've had some sort of command-line error. Print out the basic options. + */ +static void print_options(char *option) +{ + printf("axssl: Error: '%s' is an invalid command.\n", option); + printf("usage: axssl [s_server|s_client|version] [args ...]\n"); + exit(1); +} + +/** + * We've had some sort of command-line error. Print out the server options. + */ +static void print_server_options(char *option) +{ +#ifndef CONFIG_SSL_SKELETON_MODE + int cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET); +#endif +#ifdef CONFIG_SSL_CERT_VERIFICATION + int ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET); +#endif + + printf("unknown option %s\n", option); + printf("usage: s_server [args ...]\n"); + printf(" -accept arg\t- port to accept on (default is 4433)\n"); +#ifndef CONFIG_SSL_SKELETON_MODE + printf(" -cert arg\t- certificate file to add (in addition to default)" + " to chain -\n" + "\t\t Can repeat up to %d times\n", cert_size); + printf(" -key arg\t- Private key file to use\n"); + printf(" -pass\t\t- private key file pass phrase source\n"); +#endif + printf(" -quiet\t\t- No server output\n"); +#ifdef CONFIG_SSL_CERT_VERIFICATION + printf(" -verify\t- turn on peer certificate verification\n"); + printf(" -CAfile arg\t- Certificate authority\n"); + printf("\t\t Can repeat up to %d times\n", ca_cert_size); +#endif +#ifdef CONFIG_SSL_FULL_MODE + printf(" -debug\t\t- Print more output\n"); + printf(" -state\t\t- Show state messages\n"); + printf(" -show-rsa\t- Show RSA state\n"); +#endif + exit(1); +} + +/** + * We've had some sort of command-line error. Print out the client options. + */ +static void print_client_options(char *option) +{ +#ifdef CONFIG_SSL_ENABLE_CLIENT + int cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET); + int ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET); +#endif + + printf("unknown option %s\n", option); +#ifdef CONFIG_SSL_ENABLE_CLIENT + printf("usage: s_client [args ...]\n"); + printf(" -connect host:port - who to connect to (default " + "is localhost:4433)\n"); + printf(" -verify\t- turn on peer certificate verification\n"); + printf(" -cert arg\t- certificate file to use\n"); + printf("\t\t Can repeat up to %d times\n", cert_size); + printf(" -key arg\t- Private key file to use\n"); + printf(" -CAfile arg\t- Certificate authority\n"); + printf("\t\t Can repeat up to %d times\n", ca_cert_size); + printf(" -quiet\t\t- No client output\n"); + printf(" -reconnect\t- Drop and re-make the connection " + "with the same Session-ID\n"); + printf(" -pass\t\t- Private key file pass phrase source\n"); + printf(" -servername\t- Set TLS extension servername in ClientHello\n"); +#ifdef CONFIG_SSL_FULL_MODE + printf(" -debug\t\t- Print more output\n"); + printf(" -state\t\t- Show state messages\n"); + printf(" -show-rsa\t- Show RSA state\n"); +#endif +#else + printf("Change configuration to allow this feature\n"); +#endif + exit(1); +} + +/** + * Display what cipher we are using + */ +static void display_cipher(SSL *ssl) +{ + printf("CIPHER is "); + switch (ssl_get_cipher_id(ssl)) + { + case SSL_AES128_SHA: + printf("AES128-SHA"); + break; + + case SSL_AES256_SHA: + printf("AES256-SHA"); + break; + + case SSL_AES128_SHA256: + printf("AES128-SHA256"); + break; + + case SSL_AES256_SHA256: + printf("AES256-SHA256"); + break; + + default: + printf("Unknown - %d", ssl_get_cipher_id(ssl)); + break; + } + + printf("\n"); + TTY_FLUSH(); +} + +/** + * Display what session id we have. + */ +static void display_session_id(SSL *ssl) +{ + int i; + const uint8_t *session_id = ssl_get_session_id(ssl); + int sess_id_size = ssl_get_session_id_size(ssl); + + if (sess_id_size > 0) + { + printf("-----BEGIN SSL SESSION PARAMETERS-----\n"); + for (i = 0; i < sess_id_size; i++) + { + printf("%02x", session_id[i]); + } + + printf("\n-----END SSL SESSION PARAMETERS-----\n"); + TTY_FLUSH(); + } +} diff --git a/circuitpython/lib/axtls/samples/csharp/Makefile b/circuitpython/lib/axtls/samples/csharp/Makefile new file mode 100644 index 0000000..46c2421 --- /dev/null +++ b/circuitpython/lib/axtls/samples/csharp/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 ../../config/.config +include ../../config/makefile.conf +include ../../config/makefile.dotnet.conf + +all : sample +TARGET=../../$(STAGE)/axssl.csharp.exe +sample : $(TARGET) + +$(TARGET): ../../bindings/csharp/axTLS.cs ../../bindings/csharp/axInterface.cs axssl.cs +ifdef GO_DOT_NET + csc.exe /nologo /t:exe /out:"`cygpath -w $@`" $(foreach file, $^, "`cygpath -w $(file)`") +else # use mono to build + mcs -out:$@ $^ + +endif # ARCH + +clean:: + -@rm -f $(TARGET) diff --git a/circuitpython/lib/axtls/samples/csharp/axssl.cs b/circuitpython/lib/axtls/samples/csharp/axssl.cs new file mode 100644 index 0000000..df3c576 --- /dev/null +++ b/circuitpython/lib/axtls/samples/csharp/axssl.cs @@ -0,0 +1,758 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Demonstrate the use of the axTLS library in C# with a set of + * command-line parameters similar to openssl. In fact, openssl clients + * should be able to communicate with axTLS servers and visa-versa. + * + * This code has various bits enabled depending on the configuration. To enable + * the most interesting version, compile with the 'full mode' enabled. + * + * To see what options you have, run the following: + * > axssl.csharp.exe s_server -? + * > axssl.csharp.exe s_client -? + * + * The axtls shared library must be in the same directory or be found + * by the OS. + */ + +using System; +using System.Net; +using System.Net.Sockets; +using axTLS; + +public class axssl +{ + /* + * Main() + */ + public static void Main(string[] args) + { + if (args.Length == 1 && args[0] == "version") + { + Console.WriteLine("axssl.csharp " + SSLUtil.Version()); + Environment.Exit(0); + } + + axssl runner = new axssl(); + + if (args.Length < 1 || (args[0] != "s_server" && args[0] != "s_client")) + runner.print_options(args.Length > 0 ? args[0] : ""); + + int build_mode = SSLUtil.BuildMode(); + + if (args[0] == "s_server") + runner.do_server(build_mode, args); + else + runner.do_client(build_mode, args); + } + + /* + * do_server() + */ + private void do_server(int build_mode, string[] args) + { + int i = 1; + int port = 4433; + uint options = axtls.SSL_DISPLAY_CERTS; + bool quiet = false; + string password = null; + string private_key_file = null; + + /* organise the cert/ca_cert lists */ + int cert_size = SSLUtil.MaxCerts(); + int ca_cert_size = SSLUtil.MaxCACerts(); + string[] cert = new string[cert_size]; + string[] ca_cert = new string[ca_cert_size]; + int cert_index = 0; + int ca_cert_index = 0; + + while (i < args.Length) + { + if (args[i] == "-accept") + { + if (i >= args.Length-1) + { + print_server_options(build_mode, args[i]); + } + + port = Int32.Parse(args[++i]); + } + else if (args[i] == "-quiet") + { + quiet = true; + options &= ~(uint)axtls.SSL_DISPLAY_CERTS; + } + else if (build_mode >= axtls.SSL_BUILD_SERVER_ONLY) + { + if (args[i] == "-cert") + { + if (i >= args.Length-1 || cert_index >= cert_size) + { + print_server_options(build_mode, args[i]); + } + + cert[cert_index++] = args[++i]; + } + else if (args[i] == "-key") + { + if (i >= args.Length-1) + { + print_server_options(build_mode, args[i]); + } + + private_key_file = args[++i]; + options |= axtls.SSL_NO_DEFAULT_KEY; + } + else if (args[i] == "-pass") + { + if (i >= args.Length-1) + { + print_server_options(build_mode, args[i]); + } + + password = args[++i]; + } + else if (build_mode >= axtls.SSL_BUILD_ENABLE_VERIFICATION) + { + if (args[i] == "-verify") + { + options |= axtls.SSL_CLIENT_AUTHENTICATION; + } + else if (args[i] == "-CAfile") + { + if (i >= args.Length-1 || ca_cert_index >= ca_cert_size) + { + print_server_options(build_mode, args[i]); + } + + ca_cert[ca_cert_index++] = args[++i]; + } + else if (build_mode == axtls.SSL_BUILD_FULL_MODE) + { + if (args[i] == "-debug") + { + options |= axtls.SSL_DISPLAY_BYTES; + } + else if (args[i] == "-state") + { + options |= axtls.SSL_DISPLAY_STATES; + } + else if (args[i] == "-show-rsa") + { + options |= axtls.SSL_DISPLAY_RSA; + } + else + print_server_options(build_mode, args[i]); + } + else + print_server_options(build_mode, args[i]); + } + else + print_server_options(build_mode, args[i]); + } + else + print_server_options(build_mode, args[i]); + + i++; + } + + /* Create socket for incoming connections */ + IPEndPoint ep = new IPEndPoint(IPAddress.Any, port); + TcpListener server_sock = new TcpListener(ep); + server_sock.Start(); + + /********************************************************************** + * This is where the interesting stuff happens. Up until now we've + * just been setting up sockets etc. Now we do the SSL handshake. + **********************************************************************/ + SSLServer ssl_ctx = new SSLServer( + options, axtls.SSL_DEFAULT_SVR_SESS); + + if (ssl_ctx == null) + { + Console.Error.WriteLine("Error: Server context is invalid"); + Environment.Exit(1); + } + + if (private_key_file != null) + { + int obj_type = axtls.SSL_OBJ_RSA_KEY; + + if (private_key_file.EndsWith(".p8")) + obj_type = axtls.SSL_OBJ_PKCS8; + else if (private_key_file.EndsWith(".p12")) + obj_type = axtls.SSL_OBJ_PKCS12; + + if (ssl_ctx.ObjLoad(obj_type, + private_key_file, password) != axtls.SSL_OK) + { + Console.Error.WriteLine("Private key '" + private_key_file + + "' is undefined."); + Environment.Exit(1); + } + } + + for (i = 0; i < cert_index; i++) + { + if (ssl_ctx.ObjLoad(axtls.SSL_OBJ_X509_CERT, + cert[i], null) != axtls.SSL_OK) + { + Console.WriteLine("Certificate '" + cert[i] + + "' is undefined."); + Environment.Exit(1); + } + } + + for (i = 0; i < ca_cert_index; i++) + { + if (ssl_ctx.ObjLoad(axtls.SSL_OBJ_X509_CACERT, + ca_cert[i], null) != axtls.SSL_OK) + { + Console.WriteLine("Certificate '" + cert[i] + + "' is undefined."); + Environment.Exit(1); + } + } + + byte[] buf = null; + int res; + + for (;;) + { + if (!quiet) + { + Console.WriteLine("ACCEPT"); + } + + Socket client_sock = server_sock.AcceptSocket(); + + SSL ssl = ssl_ctx.Connect(client_sock); + + /* do the actual SSL handshake */ + while ((res = ssl_ctx.Read(ssl, out buf)) == axtls.SSL_OK) + { + /* check when the connection has been established */ + if (ssl.HandshakeStatus() == axtls.SSL_OK) + break; + + /* could do something else here */ + } + + if (res == axtls.SSL_OK) /* connection established and ok */ + { + if (!quiet) + { + display_session_id(ssl); + display_cipher(ssl); + } + + /* now read (and display) whatever the client sends us */ + for (;;) + { + /* keep reading until we get something interesting */ + while ((res = ssl_ctx.Read(ssl, out buf)) == axtls.SSL_OK) + { + /* could do something else here */ + } + + if (res < axtls.SSL_OK) + { + if (!quiet) + { + Console.WriteLine("CONNECTION CLOSED"); + } + + break; + } + + /* convert to string */ + char[] str = new char[res]; + for (i = 0; i < res; i++) + { + str[i] = (char)buf[i]; + } + + Console.Write(str); + } + } + else if (!quiet) + { + SSLUtil.DisplayError(res); + } + + /* client was disconnected or the handshake failed. */ + ssl.Dispose(); + client_sock.Close(); + } + + /* ssl_ctx.Dispose(); */ + } + + /* + * do_client() + */ + private void do_client(int build_mode, string[] args) + { + if (build_mode < axtls.SSL_BUILD_ENABLE_CLIENT) + { + print_client_options(build_mode, args[1]); + } + + int i = 1, res; + int port = 4433; + bool quiet = false; + string password = null; + int reconnect = 0; + string private_key_file = null; + string hostname = "127.0.0.1"; + + /* organise the cert/ca_cert lists */ + int cert_index = 0; + int ca_cert_index = 0; + int cert_size = SSLUtil.MaxCerts(); + int ca_cert_size = SSLUtil.MaxCACerts(); + string[] cert = new string[cert_size]; + string[] ca_cert = new string[ca_cert_size]; + + uint options = axtls.SSL_SERVER_VERIFY_LATER|axtls.SSL_DISPLAY_CERTS; + byte[] session_id = null; + + while (i < args.Length) + { + if (args[i] == "-connect") + { + string host_port; + + if (i >= args.Length-1) + { + print_client_options(build_mode, args[i]); + } + + host_port = args[++i]; + int index_colon; + + if ((index_colon = host_port.IndexOf(':')) < 0) + print_client_options(build_mode, args[i]); + + hostname = new string(host_port.ToCharArray(), + 0, index_colon); + port = Int32.Parse(new String(host_port.ToCharArray(), + index_colon+1, host_port.Length-index_colon-1)); + } + else if (args[i] == "-cert") + { + if (i >= args.Length-1 || cert_index >= cert_size) + { + print_client_options(build_mode, args[i]); + } + + cert[cert_index++] = args[++i]; + } + else if (args[i] == "-key") + { + if (i >= args.Length-1) + { + print_client_options(build_mode, args[i]); + } + + private_key_file = args[++i]; + options |= axtls.SSL_NO_DEFAULT_KEY; + } + else if (args[i] == "-CAfile") + { + if (i >= args.Length-1 || ca_cert_index >= ca_cert_size) + { + print_client_options(build_mode, args[i]); + } + + ca_cert[ca_cert_index++] = args[++i]; + } + else if (args[i] == "-verify") + { + options &= ~(uint)axtls.SSL_SERVER_VERIFY_LATER; + } + else if (args[i] == "-reconnect") + { + reconnect = 4; + } + else if (args[i] == "-quiet") + { + quiet = true; + options &= ~(uint)axtls.SSL_DISPLAY_CERTS; + } + else if (args[i] == "-pass") + { + if (i >= args.Length-1) + { + print_client_options(build_mode, args[i]); + } + + password = args[++i]; + } + else if (build_mode == axtls.SSL_BUILD_FULL_MODE) + { + if (args[i] == "-debug") + { + options |= axtls.SSL_DISPLAY_BYTES; + } + else if (args[i] == "-state") + { + options |= axtls.SSL_DISPLAY_STATES; + } + else if (args[i] == "-show-rsa") + { + options |= axtls.SSL_DISPLAY_RSA; + } + else + print_client_options(build_mode, args[i]); + } + else /* don't know what this is */ + print_client_options(build_mode, args[i]); + + i++; + } + + // IPHostEntry hostInfo = Dns.Resolve(hostname); + IPHostEntry hostInfo = Dns.GetHostEntry(hostname); + IPAddress[] addresses = hostInfo.AddressList; + IPEndPoint ep = new IPEndPoint(addresses[0], port); + Socket client_sock = new Socket(AddressFamily.InterNetwork, + SocketType.Stream, ProtocolType.Tcp); + client_sock.Connect(ep); + + if (!client_sock.Connected) + { + Console.WriteLine("could not connect"); + Environment.Exit(1); + } + + if (!quiet) + { + Console.WriteLine("CONNECTED"); + } + + /********************************************************************** + * This is where the interesting stuff happens. Up until now we've + * just been setting up sockets etc. Now we do the SSL handshake. + **********************************************************************/ + SSLClient ssl_ctx = new SSLClient(options, + axtls.SSL_DEFAULT_CLNT_SESS); + + if (ssl_ctx == null) + { + Console.Error.WriteLine("Error: Client context is invalid"); + Environment.Exit(1); + } + + if (private_key_file != null) + { + int obj_type = axtls.SSL_OBJ_RSA_KEY; + + if (private_key_file.EndsWith(".p8")) + obj_type = axtls.SSL_OBJ_PKCS8; + else if (private_key_file.EndsWith(".p12")) + obj_type = axtls.SSL_OBJ_PKCS12; + + if (ssl_ctx.ObjLoad(obj_type, + private_key_file, password) != axtls.SSL_OK) + { + Console.Error.WriteLine("Private key '" + private_key_file + + "' is undefined."); + Environment.Exit(1); + } + } + + for (i = 0; i < cert_index; i++) + { + if (ssl_ctx.ObjLoad(axtls.SSL_OBJ_X509_CERT, + cert[i], null) != axtls.SSL_OK) + { + Console.WriteLine("Certificate '" + cert[i] + + "' is undefined."); + Environment.Exit(1); + } + } + + for (i = 0; i < ca_cert_index; i++) + { + if (ssl_ctx.ObjLoad(axtls.SSL_OBJ_X509_CACERT, + ca_cert[i], null) != axtls.SSL_OK) + { + Console.WriteLine("Certificate '" + cert[i] + + "' is undefined."); + Environment.Exit(1); + } + } + + SSL ssl = new SSL(new IntPtr(0)); /* keep compiler happy */ + + /* Try session resumption? */ + if (reconnect > 0) + { + while (reconnect-- > 0) + { + ssl = ssl_ctx.Connect(client_sock, session_id); + + if ((res = ssl.HandshakeStatus()) != axtls.SSL_OK) + { + if (!quiet) + { + SSLUtil.DisplayError(res); + } + + ssl.Dispose(); + Environment.Exit(1); + } + + display_session_id(ssl); + session_id = ssl.GetSessionId(); + + if (reconnect > 0) + { + ssl.Dispose(); + client_sock.Close(); + + /* and reconnect */ + client_sock = new Socket(AddressFamily.InterNetwork, + SocketType.Stream, ProtocolType.Tcp); + client_sock.Connect(ep); + } + } + } + else + { + ssl = ssl_ctx.Connect(client_sock, null); + } + + /* check the return status */ + if ((res = ssl.HandshakeStatus()) != axtls.SSL_OK) + { + if (!quiet) + { + SSLUtil.DisplayError(res); + } + + Environment.Exit(1); + } + + if (!quiet) + { + string common_name = + ssl.GetCertificateDN(axtls.SSL_X509_CERT_COMMON_NAME); + + if (common_name != null) + { + Console.WriteLine("Common Name:\t\t\t" + common_name); + } + + display_session_id(ssl); + display_cipher(ssl); + } + + for (;;) + { + string user_input = Console.ReadLine(); + + if (user_input == null) + break; + + byte[] buf = new byte[user_input.Length+2]; + buf[buf.Length-2] = (byte)'\n'; /* add the carriage return */ + buf[buf.Length-1] = 0; /* null terminate */ + + for (i = 0; i < buf.Length-2; i++) + { + buf[i] = (byte)user_input[i]; + } + + if ((res = ssl_ctx.Write(ssl, buf, buf.Length)) < axtls.SSL_OK) + { + if (!quiet) + { + SSLUtil.DisplayError(res); + } + + break; + } + } + + ssl_ctx.Dispose(); + } + + /** + * We've had some sort of command-line error. Print out the basic options. + */ + private void print_options(string option) + { + Console.WriteLine("axssl: Error: '" + option + + "' is an invalid command."); + Console.WriteLine("usage: axssl.csharp [s_server|" + + "s_client|version] [args ...]"); + Environment.Exit(1); + } + + /** + * We've had some sort of command-line error. Print out the server options. + */ + private void print_server_options(int build_mode, string option) + { + int cert_size = SSLUtil.MaxCerts(); + int ca_cert_size = SSLUtil.MaxCACerts(); + + Console.WriteLine("unknown option " + option); + Console.WriteLine("usage: s_server [args ...]"); + Console.WriteLine(" -accept arg\t- port to accept on (default " + + "is 4433)"); + Console.WriteLine(" -quiet\t\t- No server output"); + + if (build_mode >= axtls.SSL_BUILD_SERVER_ONLY) + { + Console.WriteLine(" -cert arg\t- certificate file to add (in " + + "addition to default) to chain -"); + Console.WriteLine("\t\t Can repeat up to " + cert_size + " times"); + Console.WriteLine(" -key arg\t- Private key file to use"); + Console.WriteLine(" -pass\t\t- private key file pass phrase source"); + } + + if (build_mode >= axtls.SSL_BUILD_ENABLE_VERIFICATION) + { + Console.WriteLine(" -verify\t- turn on peer certificate " + + "verification"); + Console.WriteLine(" -CAfile arg\t- Certificate authority."); + Console.WriteLine("\t\t Can repeat up to " + + ca_cert_size + "times"); + } + + if (build_mode == axtls.SSL_BUILD_FULL_MODE) + { + Console.WriteLine(" -debug\t\t- Print more output"); + Console.WriteLine(" -state\t\t- Show state messages"); + Console.WriteLine(" -show-rsa\t- Show RSA state"); + } + + Environment.Exit(1); + } + + /** + * We've had some sort of command-line error. Print out the client options. + */ + private void print_client_options(int build_mode, string option) + { + int cert_size = SSLUtil.MaxCerts(); + int ca_cert_size = SSLUtil.MaxCACerts(); + + Console.WriteLine("unknown option " + option); + + if (build_mode >= axtls.SSL_BUILD_ENABLE_CLIENT) + { + Console.WriteLine("usage: s_client [args ...]"); + Console.WriteLine(" -connect host:port - who to connect to " + + "(default is localhost:4433)"); + Console.WriteLine(" -verify\t- turn on peer certificate " + + "verification"); + Console.WriteLine(" -cert arg\t- certificate file to use"); + Console.WriteLine("\t\t Can repeat up to %d times", cert_size); + Console.WriteLine(" -key arg\t- Private key file to use"); + Console.WriteLine(" -CAfile arg\t- Certificate authority."); + Console.WriteLine("\t\t Can repeat up to " + ca_cert_size + + " times"); + Console.WriteLine(" -quiet\t\t- No client output"); + Console.WriteLine(" -pass\t\t- private key file pass " + + "phrase source"); + Console.WriteLine(" -reconnect\t- Drop and re-make the " + + "connection with the same Session-ID"); + + if (build_mode == axtls.SSL_BUILD_FULL_MODE) + { + Console.WriteLine(" -debug\t\t- Print more output"); + Console.WriteLine(" -state\t\t- Show state messages"); + Console.WriteLine(" -show-rsa\t- Show RSA state"); + } + } + else + { + Console.WriteLine("Change configuration to allow this feature"); + } + + Environment.Exit(1); + } + + /** + * Display what cipher we are using + */ + private void display_cipher(SSL ssl) + { + Console.Write("CIPHER is "); + + switch (ssl.GetCipherId()) + { + case axtls.SSL_AES128_SHA: + Console.WriteLine("AES128-SHA"); + break; + + case axtls.SSL_AES256_SHA: + Console.WriteLine("AES256-SHA"); + break; + + case axtls.SSL_AES128_SHA256: + Console.WriteLine("AES128-SHA256"); + break; + + case axtls.SSL_AES256_SHA256: + Console.WriteLine("AES128-SHA256"); + break; + + default: + Console.WriteLine("Unknown - " + ssl.GetCipherId()); + break; + } + } + + /** + * Display what session id we have. + */ + private void display_session_id(SSL ssl) + { + byte[] session_id = ssl.GetSessionId(); + + if (session_id.Length > 0) + { + Console.WriteLine("-----BEGIN SSL SESSION PARAMETERS-----"); + foreach (byte b in session_id) + { + Console.Write("{0:x02}", b); + } + + Console.WriteLine("\n-----END SSL SESSION PARAMETERS-----"); + } + } +} diff --git a/circuitpython/lib/axtls/samples/java/Makefile b/circuitpython/lib/axtls/samples/java/Makefile new file mode 100644 index 0000000..9c1ed6d --- /dev/null +++ b/circuitpython/lib/axtls/samples/java/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (c) 2007-2016, Cameron Rich +# +# 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 axTLS project 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 ../../config/.config +include ../../config/makefile.conf +include ../../config/makefile.java.conf + +all : sample +JAR=../../$(STAGE)/axtls.jar +CLASSES=../../bindings/java/classes +sample : $(JAR) + +$(JAR) : $(CLASSES)/axssl.class $(wildcard $(CLASSES)/axTLSj/*.class) + jar mcvf manifest.mf $@ -C $(CLASSES) axTLSj -C $(CLASSES) axssl.class + +JAVA_FILES=axssl.java +JAVA_CLASSES:=$(JAVA_FILES:%.java=$(CLASSES)/axTLSj/%.class) + +$(CLASSES)/%.class : %.java + javac -d $(CLASSES) -classpath $(CLASSES) $^ + +clean:: + -@rm -f $(TARGET) + diff --git a/circuitpython/lib/axtls/samples/java/axssl.java b/circuitpython/lib/axtls/samples/java/axssl.java new file mode 100644 index 0000000..e013c11 --- /dev/null +++ b/circuitpython/lib/axtls/samples/java/axssl.java @@ -0,0 +1,760 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * Demonstrate the use of the axTLS library in Java with a set of + * command-line parameters similar to openssl. In fact, openssl clients + * should be able to communicate with axTLS servers and visa-versa. * + * This code has various bits enabled depending on the configuration. To enable + * the most interesting version, compile with the 'full mode' enabled. + * + * To see what options you have, run the following: + * > java -jar axtls.jar s_server -? + * > java -jar axtls.jar s_client -? + * + * The axtls/axtlsj shared libraries must be in the same directory or be found + * by the OS. + */ + +import java.io.*; +import java.util.*; +import java.net.*; +import axTLSj.*; + +public class axssl +{ + /* + * Main() + */ + public static void main(String[] args) + { + if (args.length == 1 && args[0].equals("version")) + { + System.out.println("axtls.jar " + SSLUtil.version()); + System.exit(0); + } + + axssl runner = new axssl(); + + try + { + if (args.length < 1 || + (!args[0].equals("s_server") && + !args[0].equals("s_client"))) + { + runner.print_options(args.length > 0 ? args[0] : ""); + } + + int build_mode = SSLUtil.buildMode(); + + if (args[0].equals("s_server")) + runner.do_server(build_mode, args); + else + runner.do_client(build_mode, args); + } + catch (Exception e) + { + System.out.println(e); + } + } + + /* + * do_server() + */ + private void do_server(int build_mode, String[] args) + throws Exception + { + int i = 1; + int port = 4433; + int options = axtlsj.SSL_DISPLAY_CERTS; + boolean quiet = false; + String password = null; + String private_key_file = null; + + /* organise the cert/ca_cert lists */ + int cert_size = SSLUtil.maxCerts(); + int ca_cert_size = SSLUtil.maxCACerts(); + String[] cert = new String[cert_size]; + String[] ca_cert = new String[ca_cert_size]; + int cert_index = 0; + int ca_cert_index = 0; + + while (i < args.length) + { + if (args[i].equals("-accept")) + { + if (i >= args.length-1) + { + print_server_options(build_mode, args[i]); + } + + port = Integer.parseInt(args[++i]); + } + else if (args[i].equals("-quiet")) + { + quiet = true; + options &= ~(int)axtlsj.SSL_DISPLAY_CERTS; + } + else if (build_mode >= axtlsj.SSL_BUILD_SERVER_ONLY) + { + if (args[i].equals("-cert")) + { + if (i >= args.length-1 || cert_index >= cert_size) + { + print_server_options(build_mode, args[i]); + } + + cert[cert_index++] = args[++i]; + } + else if (args[i].equals("-key")) + { + if (i >= args.length-1) + { + print_server_options(build_mode, args[i]); + } + + private_key_file = args[++i]; + options |= axtlsj.SSL_NO_DEFAULT_KEY; + } + else if (args[i].equals("-pass")) + { + if (i >= args.length-1) + { + print_server_options(build_mode, args[i]); + } + + password = args[++i]; + } + else if (build_mode >= axtlsj.SSL_BUILD_ENABLE_VERIFICATION) + { + if (args[i].equals("-verify")) + { + options |= axtlsj.SSL_CLIENT_AUTHENTICATION; + } + else if (args[i].equals("-CAfile")) + { + if (i >= args.length-1 || ca_cert_index >= ca_cert_size) + { + print_server_options(build_mode, args[i]); + } + + ca_cert[ca_cert_index++] = args[++i]; + } + else if (build_mode == axtlsj.SSL_BUILD_FULL_MODE) + { + if (args[i].equals("-debug")) + { + options |= axtlsj.SSL_DISPLAY_BYTES; + } + else if (args[i].equals("-state")) + { + options |= axtlsj.SSL_DISPLAY_STATES; + } + else if (args[i].equals("-show-rsa")) + { + options |= axtlsj.SSL_DISPLAY_RSA; + } + else + print_server_options(build_mode, args[i]); + } + else + print_server_options(build_mode, args[i]); + } + else + print_server_options(build_mode, args[i]); + } + else + print_server_options(build_mode, args[i]); + + i++; + } + + /* Create socket for incoming connections */ + ServerSocket server_sock = new ServerSocket(port); + + /********************************************************************** + * This is where the interesting stuff happens. Up until now we've + * just been setting up sockets etc. Now we do the SSL handshake. + **********************************************************************/ + SSLServer ssl_ctx = new SSLServer(options, + axtlsj.SSL_DEFAULT_SVR_SESS); + + if (ssl_ctx == null) + throw new Exception("Error: Server context is invalid"); + + if (private_key_file != null) + { + int obj_type = axtlsj.SSL_OBJ_RSA_KEY; + + if (private_key_file.endsWith(".p8")) + obj_type = axtlsj.SSL_OBJ_PKCS8; + else if (private_key_file.endsWith(".p12")) + obj_type = axtlsj.SSL_OBJ_PKCS12; + + if (ssl_ctx.objLoad(obj_type, + private_key_file, password) != axtlsj.SSL_OK) + { + throw new Exception("Error: Private key '" + private_key_file + + "' is undefined."); + } + } + + for (i = 0; i < cert_index; i++) + { + if (ssl_ctx.objLoad(axtlsj.SSL_OBJ_X509_CERT, + cert[i], null) != axtlsj.SSL_OK) + { + throw new Exception("Certificate '" + cert[i] + + "' is undefined."); + } + } + + for (i = 0; i < ca_cert_index; i++) + { + if (ssl_ctx.objLoad(axtlsj.SSL_OBJ_X509_CACERT, + ca_cert[i], null) != axtlsj.SSL_OK) + { + throw new Exception("Certificate '" + ca_cert[i] + + "' is undefined."); + } + } + + int res; + SSLReadHolder rh = new SSLReadHolder(); + + for (;;) + { + if (!quiet) + { + System.out.println("ACCEPT"); + } + + Socket client_sock = server_sock.accept(); + + SSL ssl = ssl_ctx.connect(client_sock); + + while ((res = ssl_ctx.read(ssl, rh)) == axtlsj.SSL_OK) + { + /* check when the connection has been established */ + if (ssl.handshakeStatus() == axtlsj.SSL_OK) + break; + + /* could do something else here */ + } + + if (res == axtlsj.SSL_OK) /* connection established and ok */ + { + if (!quiet) + { + display_session_id(ssl); + display_cipher(ssl); + } + + /* now read (and display) whatever the client sends us */ + for (;;) + { + /* keep reading until we get something interesting */ + while ((res = ssl_ctx.read(ssl, rh)) == axtlsj.SSL_OK) + { + /* could do something else here */ + } + + if (res < axtlsj.SSL_OK) + { + if (!quiet) + { + System.out.println("CONNECTION CLOSED"); + } + + break; + } + + /* convert to String */ + byte[] buf = rh.getData(); + char[] str = new char[res]; + + for (i = 0; i < res; i++) + { + str[i] = (char)buf[i]; + } + + System.out.print(str); + } + } + else if (!quiet) + { + SSLUtil.displayError(res); + } + + /* client was disconnected or the handshake failed. */ + ssl.dispose(); + client_sock.close(); + } + + /* ssl_ctx.dispose(); */ + } + + /* + * do_client() + */ + private void do_client(int build_mode, String[] args) + throws Exception + { + if (build_mode < axtlsj.SSL_BUILD_ENABLE_CLIENT) + print_client_options(build_mode, args[1]); + + int i = 1, res; + int port = 4433; + boolean quiet = false; + String password = null; + int reconnect = 0; + String private_key_file = null; + String hostname = "127.0.0.1"; + + /* organise the cert/ca_cert lists */ + int cert_index = 0; + int ca_cert_index = 0; + int cert_size = SSLUtil.maxCerts(); + int ca_cert_size = SSLUtil.maxCACerts(); + String[] cert = new String[cert_size]; + String[] ca_cert = new String[ca_cert_size]; + + int options = axtlsj.SSL_SERVER_VERIFY_LATER|axtlsj.SSL_DISPLAY_CERTS; + byte[] session_id = null; + + while (i < args.length) + { + if (args[i].equals("-connect")) + { + String host_port; + + if (i >= args.length-1) + { + print_client_options(build_mode, args[i]); + } + + host_port = args[++i]; + int index_colon; + + if ((index_colon = host_port.indexOf(':')) < 0) + print_client_options(build_mode, args[i]); + + hostname = new String(host_port.toCharArray(), + 0, index_colon); + port = Integer.parseInt(new String(host_port.toCharArray(), + index_colon+1, host_port.length()-index_colon-1)); + } + else if (args[i].equals("-cert")) + { + if (i >= args.length-1 || cert_index >= cert_size) + { + print_client_options(build_mode, args[i]); + } + + cert[cert_index++] = args[++i]; + } + else if (args[i].equals("-CAfile")) + { + if (i >= args.length-1 || ca_cert_index >= ca_cert_size) + { + print_client_options(build_mode, args[i]); + } + + ca_cert[ca_cert_index++] = args[++i]; + } + else if (args[i].equals("-key")) + { + if (i >= args.length-1) + { + print_client_options(build_mode, args[i]); + } + + private_key_file = args[++i]; + options |= axtlsj.SSL_NO_DEFAULT_KEY; + } + else if (args[i].equals("-verify")) + { + options &= ~(int)axtlsj.SSL_SERVER_VERIFY_LATER; + } + else if (args[i].equals("-reconnect")) + { + reconnect = 4; + } + else if (args[i].equals("-quiet")) + { + quiet = true; + options &= ~(int)axtlsj.SSL_DISPLAY_CERTS; + } + else if (args[i].equals("-pass")) + { + if (i >= args.length-1) + { + print_server_options(build_mode, args[i]); + } + + password = args[++i]; + } + else if (build_mode == axtlsj.SSL_BUILD_FULL_MODE) + { + if (args[i].equals("-debug")) + { + options |= axtlsj.SSL_DISPLAY_BYTES; + } + else if (args[i].equals("-state")) + { + options |= axtlsj.SSL_DISPLAY_STATES; + } + else if (args[i].equals("-show-rsa")) + { + options |= axtlsj.SSL_DISPLAY_RSA; + } + else + print_client_options(build_mode, args[i]); + } + else /* don't know what this is */ + print_client_options(build_mode, args[i]); + + i++; + } + + Socket client_sock = new Socket(hostname, port); + + if (!client_sock.isConnected()) + { + System.out.println("could not connect"); + throw new Exception(); + } + + if (!quiet) + { + System.out.println("CONNECTED"); + } + + /********************************************************************** + * This is where the interesting stuff happens. Up until now we've + * just been setting up sockets etc. Now we do the SSL handshake. + **********************************************************************/ + SSLClient ssl_ctx = new SSLClient(options, + axtlsj.SSL_DEFAULT_CLNT_SESS); + + if (ssl_ctx == null) + { + throw new Exception("Error: Client context is invalid"); + } + + if (private_key_file != null) + { + int obj_type = axtlsj.SSL_OBJ_RSA_KEY; + + if (private_key_file.endsWith(".p8")) + obj_type = axtlsj.SSL_OBJ_PKCS8; + else if (private_key_file.endsWith(".p12")) + obj_type = axtlsj.SSL_OBJ_PKCS12; + + if (ssl_ctx.objLoad(obj_type, + private_key_file, password) != axtlsj.SSL_OK) + { + throw new Exception("Error: Private key '" + private_key_file + + "' is undefined."); + } + } + + for (i = 0; i < cert_index; i++) + { + if (ssl_ctx.objLoad(axtlsj.SSL_OBJ_X509_CERT, + cert[i], null) != axtlsj.SSL_OK) + { + throw new Exception("Certificate '" + cert[i] + + "' is undefined."); + } + } + + for (i = 0; i < ca_cert_index; i++) + { + if (ssl_ctx.objLoad(axtlsj.SSL_OBJ_X509_CACERT, + ca_cert[i], null) != axtlsj.SSL_OK) + { + throw new Exception("Certificate '" + ca_cert[i] + + "' is undefined."); + } + } + + SSL ssl = null; + + /* Try session resumption? */ + if (reconnect > 0) + { + while (reconnect-- > 0) + { + ssl = ssl_ctx.connect(client_sock, session_id); + + if ((res = ssl.handshakeStatus()) != axtlsj.SSL_OK) + { + if (!quiet) + { + SSLUtil.displayError(res); + } + + ssl.dispose(); + throw new Exception(); + } + + display_session_id(ssl); + session_id = ssl.getSessionId(); + + if (reconnect > 0) + { + ssl.dispose(); + client_sock.close(); + + /* and reconnect */ + client_sock = new Socket(hostname, port); + } + } + } + else + { + ssl = ssl_ctx.connect(client_sock, null); + } + + /* check the return status */ + if ((res = ssl.handshakeStatus()) != axtlsj.SSL_OK) + { + if (!quiet) + { + SSLUtil.displayError(res); + } + + throw new Exception(); + } + + if (!quiet) + { + String common_name = + ssl.getCertificateDN(axtlsj.SSL_X509_CERT_COMMON_NAME); + + if (common_name != null) + { + System.out.println("Common Name:\t\t\t" + common_name); + } + + display_session_id(ssl); + display_cipher(ssl); + } + + BufferedReader in = new BufferedReader( + new InputStreamReader(System.in)); + + for (;;) + { + String user_input = in.readLine(); + + if (user_input == null) + break; + + byte[] buf = new byte[user_input.length()+2]; + buf[buf.length-2] = (byte)'\n'; /* add the carriage return */ + buf[buf.length-1] = 0; /* null terminate */ + + for (i = 0; i < buf.length-2; i++) + { + buf[i] = (byte)user_input.charAt(i); + } + + if ((res = ssl_ctx.write(ssl, buf)) < axtlsj.SSL_OK) + { + if (!quiet) + { + SSLUtil.displayError(res); + } + + break; + } + } + + ssl_ctx.dispose(); + } + + /** + * We've had some sort of command-line error. Print out the basic options. + */ + private void print_options(String option) + { + System.out.println("axssl: Error: '" + option + + "' is an invalid command."); + System.out.println("usage: axtlsj.jar [s_server|s_client|version] " + + "[args ...]"); + System.exit(1); + } + + /** + * We've had some sort of command-line error. Print out the server options. + */ + private void print_server_options(int build_mode, String option) + { + int cert_size = SSLUtil.maxCerts(); + int ca_cert_size = SSLUtil.maxCACerts(); + + System.out.println("unknown option " + option); + System.out.println("usage: s_server [args ...]"); + System.out.println(" -accept arg\t- port to accept on (default " + + "is 4433)"); + System.out.println(" -quiet\t\t- No server output"); + + if (build_mode >= axtlsj.SSL_BUILD_SERVER_ONLY) + { + System.out.println(" -cert arg\t- certificate file to add (in " + + "addition to default) to chain -"); + System.out.println("\t\t Can repeat up to " + cert_size + " times"); + System.out.println(" -key arg\t- Private key file to use"); + System.out.println(" -pass\t\t- private key file pass phrase source"); + } + + if (build_mode >= axtlsj.SSL_BUILD_ENABLE_VERIFICATION) + { + System.out.println(" -verify\t- turn on peer certificate " + + "verification"); + System.out.println(" -CAfile arg\t- Certificate authority. "); + System.out.println("\t\t Can repeat up to " + + ca_cert_size + " times"); + } + + if (build_mode == axtlsj.SSL_BUILD_FULL_MODE) + { + System.out.println(" -debug\t\t- Print more output"); + System.out.println(" -state\t\t- Show state messages"); + System.out.println(" -show-rsa\t- Show RSA state"); + } + + System.exit(1); + } + + /** + * We've had some sort of command-line error. Print out the client options. + */ + private void print_client_options(int build_mode, String option) + { + int cert_size = SSLUtil.maxCerts(); + int ca_cert_size = SSLUtil.maxCACerts(); + + System.out.println("unknown option " + option); + + if (build_mode >= axtlsj.SSL_BUILD_ENABLE_CLIENT) + { + System.out.println("usage: s_client [args ...]"); + System.out.println(" -connect host:port - who to connect to " + + "(default is localhost:4433)"); + System.out.println(" -verify\t- turn on peer certificate " + + "verification"); + System.out.println(" -cert arg\t- certificate file to use"); + System.out.println(" -key arg\t- Private key file to use"); + System.out.println("\t\t Can repeat up to " + cert_size + + " times"); + System.out.println(" -CAfile arg\t- Certificate authority."); + System.out.println("\t\t Can repeat up to " + ca_cert_size + + " times"); + System.out.println(" -quiet\t\t- No client output"); + System.out.println(" -pass\t\t- private key file pass " + + "phrase source"); + System.out.println(" -reconnect\t- Drop and re-make the " + + "connection with the same Session-ID"); + + if (build_mode == axtlsj.SSL_BUILD_FULL_MODE) + { + System.out.println(" -debug\t\t- Print more output"); + System.out.println(" -state\t\t- Show state messages"); + System.out.println(" -show-rsa\t- Show RSA state"); + } + } + else + { + System.out.println("Change configuration to allow this feature"); + } + + System.exit(1); + } + + /** + * Display what cipher we are using + */ + private void display_cipher(SSL ssl) + { + System.out.print("CIPHER is "); + + byte ciph_id = ssl.getCipherId(); + + if (ciph_id == axtlsj.SSL_AES128_SHA) + System.out.println("AES128-SHA"); + else if (ciph_id == axtlsj.SSL_AES256_SHA) + System.out.println("AES256-SHA"); + else if (ciph_id == axtlsj.SSL_AES128_SHA256) + System.out.println("AES128-SHA256"); + else if (ciph_id == axtlsj.SSL_AES256_SHA256) + System.out.println("AES256-SHA256"); + else + System.out.println("Unknown - " + ssl.getCipherId()); + } + + public char toHexChar(int i) + { + if ((0 <= i) && (i <= 9 )) + return (char)('0' + i); + else + return (char)('a' + (i-10)); + } + + public void bytesToHex(byte[] data) + { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < data.length; i++ ) + { + buf.append(toHexChar((data[i]>>>4)&0x0F)); + buf.append(toHexChar(data[i]&0x0F)); + } + + System.out.println(buf); + } + + + /** + * Display what session id we have. + */ + private void display_session_id(SSL ssl) + { + byte[] session_id = ssl.getSessionId(); + + if (session_id.length > 0) + { + System.out.println("-----BEGIN SSL SESSION PARAMETERS-----"); + bytesToHex(session_id); + System.out.println("-----END SSL SESSION PARAMETERS-----"); + } + } +} diff --git a/circuitpython/lib/axtls/samples/java/manifest.mf b/circuitpython/lib/axtls/samples/java/manifest.mf new file mode 100644 index 0000000..b906ed2 --- /dev/null +++ b/circuitpython/lib/axtls/samples/java/manifest.mf @@ -0,0 +1 @@ +Main-Class: axssl diff --git a/circuitpython/lib/axtls/samples/lua/Makefile b/circuitpython/lib/axtls/samples/lua/Makefile new file mode 100644 index 0000000..a460da3 --- /dev/null +++ b/circuitpython/lib/axtls/samples/lua/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 ../../config/.config +include ../../config/makefile.conf + +all: samples +TARGET=../../$(STAGE)/axssl.lua +samples: $(TARGET) + +$(TARGET): axssl.lua + install $< $@ + +clean:: + -@rm -f $(TARGET) + diff --git a/circuitpython/lib/axtls/samples/lua/axssl.lua b/circuitpython/lib/axtls/samples/lua/axssl.lua new file mode 100755 index 0000000..b4f24ed --- /dev/null +++ b/circuitpython/lib/axtls/samples/lua/axssl.lua @@ -0,0 +1,562 @@ +#!/usr/local/bin/lua + +-- +-- Copyright (c) 2007-2016, Cameron Rich +-- +-- 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 axTLS project 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. +-- + +-- +-- Demonstrate the use of the axTLS library in Lua with a set of +-- command-line parameters similar to openssl. In fact, openssl clients +-- should be able to communicate with axTLS servers and visa-versa. +-- +-- This code has various bits enabled depending on the configuration. To enable +-- the most interesting version, compile with the 'full mode' enabled. +-- +-- To see what options you have, run the following: +-- > [lua] axssl s_server -? +-- > [lua] axssl s_client -? +-- +-- The axtls/axtlsl shared libraries must be in the same directory or be found +-- by the OS. +-- +-- +require "bit" +require("axtlsl") +local socket = require("socket") + +-- print version? +if #arg == 1 and arg[1] == "version" then + print("axssl.lua "..axtlsl.ssl_version()) + os.exit(1) +end + +-- +-- We've had some sort of command-line error. Print out the basic options. +-- +function print_options(option) + print("axssl: Error: '"..option.."' is an invalid command.") + print("usage: axssl [s_server|s_client|version] [args ...]") + os.exit(1) +end + +-- +-- We've had some sort of command-line error. Print out the server options. +-- +function print_server_options(build_mode, option) + local cert_size = axtlsl.ssl_get_config(axtlsl.SSL_MAX_CERT_CFG_OFFSET) + local ca_cert_size = axtlsl.ssl_get_config( + axtlsl.SSL_MAX_CA_CERT_CFG_OFFSET) + + print("unknown option "..option) + print("usage: s_server [args ...]") + print(" -accept\t- port to accept on (default is 4433)") + print(" -quiet\t\t- No server output") + + if build_mode >= axtlsl.SSL_BUILD_SERVER_ONLY then + print(" -cert arg\t- certificate file to add (in addition to ".. + "default) to chain -") + print("\t\t Can repeat up to "..cert_size.." times") + print(" -key arg\t- Private key file to use - default DER format") + print(" -pass\t\t- private key file pass phrase source") + end + + if build_mode >= axtlsl.SSL_BUILD_ENABLE_VERIFICATION then + print(" -verify\t- turn on peer certificate verification") + print(" -CAfile arg\t- Certificate authority - default DER format") + print("\t\t Can repeat up to "..ca_cert_size.." times") + end + + if build_mode == axtlsl.SSL_BUILD_FULL_MODE then + print(" -debug\t\t- Print more output") + print(" -state\t\t- Show state messages") + print(" -show-rsa\t- Show RSA state") + end + + os.exit(1) +end + +-- +-- We've had some sort of command-line error. Print out the client options. +-- +function print_client_options(build_mode, option) + local cert_size = axtlsl.ssl_get_config(axtlsl.SSL_MAX_CERT_CFG_OFFSET) + local ca_cert_size = axtlsl.ssl_get_config( + axtlsl.SSL_MAX_CA_CERT_CFG_OFFSET) + + print("unknown option "..option) + + if build_mode >= axtlsl.SSL_BUILD_ENABLE_CLIENT then + print("usage: s_client [args ...]") + print(" -connect host:port - who to connect to (default ".. + "is localhost:4433)") + print(" -verify\t- turn on peer certificate verification") + print(" -cert arg\t- certificate file to use - default DER format") + print(" -key arg\t- Private key file to use - default DER format") + print("\t\t Can repeat up to "..cert_size.." times") + print(" -CAfile arg\t- Certificate authority - default DER format") + print("\t\t Can repeat up to "..ca_cert_size.."times") + print(" -quiet\t\t- No client output") + print(" -pass\t\t- private key file pass phrase source") + print(" -reconnect\t- Drop and re-make the connection ".. + "with the same Session-ID") + + if build_mode == axtlsl.SSL_BUILD_FULL_MODE then + print(" -debug\t\t- Print more output") + print(" -state\t\t- Show state messages") + print(" -show-rsa\t- Show RSA state") + end + else + print("Change configuration to allow this feature") + end + + os.exit(1) +end + +-- Implement the SSL server logic. +function do_server(build_mode) + local i = 2 + local v + local port = 4433 + local options = axtlsl.SSL_DISPLAY_CERTS + local quiet = false + local password = "" + local private_key_file = nil + local cert_size = axtlsl.ssl_get_config(axtlsl.SSL_MAX_CERT_CFG_OFFSET) + local ca_cert_size = axtlsl. + ssl_get_config(axtlsl.SSL_MAX_CA_CERT_CFG_OFFSET) + local cert = {} + local ca_cert = {} + + while i <= #arg do + if arg[i] == "-accept" then + if i >= #arg then + print_server_options(build_mode, arg[i]) + end + + i = i + 1 + port = arg[i] + elseif arg[i] == "-quiet" then + quiet = true + options = bit.band(options, bit.bnot(axtlsl.SSL_DISPLAY_CERTS)) + elseif build_mode >= axtlsl.SSL_BUILD_SERVER_ONLY then + if arg[i] == "-cert" then + if i >= #arg or #cert >= cert_size then + print_server_options(build_mode, arg[i]) + end + + i = i + 1 + table.insert(cert, arg[i]) + elseif arg[i] == "-key" then + if i >= #arg then + print_server_options(build_mode, arg[i]) + end + + i = i + 1 + private_key_file = arg[i] + options = bit.bor(options, axtlsl.SSL_NO_DEFAULT_KEY) + elseif arg[i] == "-pass" then + if i >= #arg then + print_server_options(build_mode, arg[i]) + end + + i = i + 1 + password = arg[i] + elseif build_mode >= axtlsl.SSL_BUILD_ENABLE_VERIFICATION then + if arg[i] == "-verify" then + options = bit.bor(options, axtlsl.SSL_CLIENT_AUTHENTICATION) + elseif arg[i] == "-CAfile" then + if i >= #arg or #ca_cert >= ca_cert_size then + print_server_options(build_mode, arg[i]) + end + + i = i + 1 + table.insert(ca_cert, arg[i]) + elseif build_mode == axtlsl.SSL_BUILD_FULL_MODE then + if arg[i] == "-debug" then + options = bit.bor(options, axtlsl.SSL_DISPLAY_BYTES) + elseif arg[i] == "-state" then + options = bit.bor(options, axtlsl.SSL_DISPLAY_STATES) + elseif arg[i] == "-show-rsa" then + options = bit.bor(options, axtlsl.SSL_DISPLAY_RSA) + else + print_server_options(build_mode, arg[i]) + end + else + print_server_options(build_mode, arg[i]) + end + else + print_server_options(build_mode, arg[i]) + end + else + print_server_options(build_mode, arg[i]) + end + + i = i + 1 + end + + -- Create socket for incoming connections + local server_sock = socket.try(socket.bind("*", port)) + + --------------------------------------------------------------------------- + -- This is where the interesting stuff happens. Up until now we've + -- just been setting up sockets etc. Now we do the SSL handshake. + --------------------------------------------------------------------------- + local ssl_ctx = axtlsl.ssl_ctx_new(options, axtlsl.SSL_DEFAULT_SVR_SESS) + if ssl_ctx == nil then error("Error: Server context is invalid") end + + if private_key_file ~= nil then + local obj_type = axtlsl.SSL_OBJ_RSA_KEY + + if string.find(private_key_file, ".p8") then + obj_type = axtlsl.SSL_OBJ_PKCS8 + end + + if string.find(private_key_file, ".p12") then + obj_type = axtlsl.SSL_OBJ_PKCS12 + end + + if axtlsl.ssl_obj_load(ssl_ctx, obj_type, private_key_file, + password) ~= axtlsl.SSL_OK then + error("Private key '" .. private_key_file .. "' is undefined.") + end + end + + for _, v in ipairs(cert) do + if axtlsl.ssl_obj_load(ssl_ctx, axtlsl.SSL_OBJ_X509_CERT, v, "") ~= + axtlsl.SSL_OK then + error("Certificate '"..v .. "' is undefined.") + end + end + + for _, v in ipairs(ca_cert) do + if axtlsl.ssl_obj_load(ssl_ctx, axtlsl.SSL_OBJ_X509_CACERT, v, "") ~= + axtlsl.SSL_OK then + error("Certificate '"..v .."' is undefined.") + end + end + + while true do + if not quiet then print("ACCEPT") end + local client_sock = server_sock:accept(); + local ssl = axtlsl.ssl_server_new(ssl_ctx, client_sock:getfd()) + + -- do the actual SSL handshake + local connected = false + local res + local buf + + while true do + socket.select({client_sock}, nil) + res, buf = axtlsl.ssl_read(ssl) + + if res == axtlsl.SSL_OK then -- connection established and ok + if axtlsl.ssl_handshake_status(ssl) == axtlsl.SSL_OK then + if not quiet and not connected then + display_session_id(ssl) + display_cipher(ssl) + end + connected = true + end + end + + if res > axtlsl.SSL_OK then + for _, v in ipairs(buf) do + io.write(string.format("%c", v)) + end + elseif res < axtlsl.SSL_OK then + if not quiet then + axtlsl.ssl_display_error(res) + end + break + end + end + + -- client was disconnected or the handshake failed. + print("CONNECTION CLOSED") + axtlsl.ssl_free(ssl) + client_sock:close() + end + + axtlsl.ssl_ctx_free(ssl_ctx) +end + +-- +-- Implement the SSL client logic. +-- +function do_client(build_mode) + local i = 2 + local v + local port = 4433 + local options = + bit.bor(axtlsl.SSL_SERVER_VERIFY_LATER, axtlsl.SSL_DISPLAY_CERTS) + local private_key_file = nil + local reconnect = 0 + local quiet = false + local password = "" + local session_id = {} + local host = "127.0.0.1" + local cert_size = axtlsl.ssl_get_config(axtlsl.SSL_MAX_CERT_CFG_OFFSET) + local ca_cert_size = axtlsl. + ssl_get_config(axtlsl.SSL_MAX_CA_CERT_CFG_OFFSET) + local cert = {} + local ca_cert = {} + + while i <= #arg do + if arg[i] == "-connect" then + if i >= #arg then + print_client_options(build_mode, arg[i]) + end + + i = i + 1 + local t = string.find(arg[i], ":") + host = string.sub(arg[i], 1, t-1) + port = string.sub(arg[i], t+1) + elseif arg[i] == "-cert" then + if i >= #arg or #cert >= cert_size then + print_client_options(build_mode, arg[i]) + end + + i = i + 1 + table.insert(cert, arg[i]) + elseif arg[i] == "-key" then + if i >= #arg then + print_client_options(build_mode, arg[i]) + end + + i = i + 1 + private_key_file = arg[i] + options = bit.bor(options, axtlsl.SSL_NO_DEFAULT_KEY) + elseif arg[i] == "-CAfile" then + if i >= #arg or #ca_cert >= ca_cert_size then + print_client_options(build_mode, arg[i]) + end + + i = i + 1 + table.insert(ca_cert, arg[i]) + elseif arg[i] == "-verify" then + options = bit.band(options, + bit.bnot(axtlsl.SSL_SERVER_VERIFY_LATER)) + elseif arg[i] == "-reconnect" then + reconnect = 4 + elseif arg[i] == "-quiet" then + quiet = true + options = bit.band(options, bnot(axtlsl.SSL_DISPLAY_CERTS)) + elseif arg[i] == "-pass" then + if i >= #arg then + print_server_options(build_mode, arg[i]) + end + + i = i + 1 + password = arg[i] + elseif build_mode == axtlsl.SSL_BUILD_FULL_MODE then + if arg[i] == "-debug" then + options = bit.bor(options, axtlsl.SSL_DISPLAY_BYTES) + elseif arg[i] == "-state" then + options = bit.bor(axtlsl.SSL_DISPLAY_STATES) + elseif arg[i] == "-show-rsa" then + options = bit.bor(axtlsl.SSL_DISPLAY_RSA) + else -- don't know what this is + print_client_options(build_mode, arg[i]) + end + else -- don't know what this is + print_client_options(build_mode, arg[i]) + end + + i = i + 1 + end + + local client_sock = socket.try(socket.connect(host, port)) + local ssl + local res + + if not quiet then print("CONNECTED") end + + --------------------------------------------------------------------------- + -- This is where the interesting stuff happens. Up until now we've + -- just been setting up sockets etc. Now we do the SSL handshake. + --------------------------------------------------------------------------- + local ssl_ctx = axtlsl.ssl_ctx_new(options, axtlsl.SSL_DEFAULT_CLNT_SESS) + + if ssl_ctx == nil then + error("Error: Client context is invalid") + end + + if private_key_file ~= nil then + local obj_type = axtlsl.SSL_OBJ_RSA_KEY + + if string.find(private_key_file, ".p8") then + obj_type = axtlsl.SSL_OBJ_PKCS8 + end + + if string.find(private_key_file, ".p12") then + obj_type = axtlsl.SSL_OBJ_PKCS12 + end + + if axtlsl.ssl_obj_load(ssl_ctx, obj_type, private_key_file, + password) ~= axtlsl.SSL_OK then + error("Private key '"..private_key_file.."' is undefined.") + end + end + + for _, v in ipairs(cert) do + if axtlsl.ssl_obj_load(ssl_ctx, axtlsl.SSL_OBJ_X509_CERT, v, "") ~= + axtlsl.SSL_OK then + error("Certificate '"..v .. "' is undefined.") + end + end + + for _, v in ipairs(ca_cert) do + if axtlsl.ssl_obj_load(ssl_ctx, axtlsl.SSL_OBJ_X509_CACERT, v, "") ~= + axtlsl.SSL_OK then + error("Certificate '"..v .."' is undefined.") + end + end + + -- Try session resumption? + if reconnect ~= 0 then + local session_id = nil + local sess_id_size = 0 + + while reconnect > 0 do + reconnect = reconnect - 1 + ssl = axtlsl.ssl_client_new(ssl_ctx, + client_sock:getfd(), session_id, sess_id_size) + + res = axtlsl.ssl_handshake_status(ssl) + if res ~= axtlsl.SSL_OK then + if not quiet then axtlsl.ssl_display_error(res) end + axtlsl.ssl_free(ssl) + os.exit(1) + end + + display_session_id(ssl) + session_id = axtlsl.ssl_get_session_id(ssl) + sess_id_size = axtlsl.ssl_get_session_id_size(ssl) + + if reconnect > 0 then + axtlsl.ssl_free(ssl) + client_sock:close() + client_sock = socket.try(socket.connect(host, port)) + end + + end + else + ssl = axtlsl.ssl_client_new(ssl_ctx, client_sock:getfd(), nil, 0) + end + + -- check the return status + res = axtlsl.ssl_handshake_status(ssl) + if res ~= axtlsl.SSL_OK then + if not quiet then axtlsl.ssl_display_error(res) end + os.exit(1) + end + + if not quiet then + local common_name = axtlsl.ssl_get_cert_dn(ssl, + axtlsl.SSL_X509_CERT_COMMON_NAME) + + if common_name ~= nil then + print("Common Name:\t\t\t"..common_name) + end + + display_session_id(ssl) + display_cipher(ssl) + end + + while true do + local line = io.read() + if line == nil then break end + local bytes = {} + + for i = 1, #line do + bytes[i] = line.byte(line, i) + end + + bytes[#line+1] = 10 -- add carriage return, null + bytes[#line+2] = 0 + + res = axtlsl.ssl_write(ssl, bytes, #bytes) + if res < axtlsl.SSL_OK then + if not quiet then axtlsl.ssl_display_error(res) end + break + end + end + + axtlsl.ssl_ctx_free(ssl_ctx) + client_sock:close() +end + +-- +-- Display what cipher we are using +-- +function display_cipher(ssl) + io.write("CIPHER is ") + local cipher_id = axtlsl.ssl_get_cipher_id(ssl) + + if cipher_id == axtlsl.SSL_AES128_SHA then + print("AES128-SHA") + elseif cipher_id == axtlsl.SSL_AES256_SHA then + print("AES256-SHA") + elseif axtlsl.SSL_AES128_SHA256 then + print("AES128-SHA256") + elseif axtlsl.SSL_AES256_SHA256 then + print("AES256-SHA256") + else + print("Unknown - "..cipher_id) + end +end + +-- +-- Display what session id we have. +-- +function display_session_id(ssl) + local session_id = axtlsl.ssl_get_session_id(ssl) + local v + + if #session_id > 0 then + print("-----BEGIN SSL SESSION PARAMETERS-----") + for _, v in ipairs(session_id) do + io.write(string.format("%02x", v)) + end + print("\n-----END SSL SESSION PARAMETERS-----") + end +end + +-- +-- Main entry point. Doesn't do much except works out whether we are a client +-- or a server. +-- +if #arg == 0 or (arg[1] ~= "s_server" and arg[1] ~= "s_client") then + print_options(#arg > 0 and arg[1] or "") +end + +local build_mode = axtlsl.ssl_get_config(axtlsl.SSL_BUILD_MODE) +_ = arg[1] == "s_server" and do_server(build_mode) or do_client(build_mode) +os.exit(0) + diff --git a/circuitpython/lib/axtls/samples/perl/Makefile b/circuitpython/lib/axtls/samples/perl/Makefile new file mode 100644 index 0000000..5200c43 --- /dev/null +++ b/circuitpython/lib/axtls/samples/perl/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 ../../config/.config +include ../../config/makefile.conf + +all: samples +TARGET=../../$(STAGE)/axssl.pl +samples: $(TARGET) + +$(TARGET): axssl.pl + install $< $@ + +clean:: + -@rm -f $(TARGET) + diff --git a/circuitpython/lib/axtls/samples/perl/axssl.pl b/circuitpython/lib/axtls/samples/perl/axssl.pl new file mode 100755 index 0000000..f3b0449 --- /dev/null +++ b/circuitpython/lib/axtls/samples/perl/axssl.pl @@ -0,0 +1,634 @@ +#!/usr/bin/perl -w +# +# Copyright (c) 2007-2016, Cameron Rich +# +# 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 axTLS project 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. +# + +# +# Demonstrate the use of the axTLS library in Perl with a set of +# command-line parameters similar to openssl. In fact, openssl clients +# should be able to communicate with axTLS servers and visa-versa. +# +# This code has various bits enabled depending on the configuration. To enable +# the most interesting version, compile with the 'full mode' enabled. +# +# To see what options you have, run the following: +# > [perl] axssl s_server -? +# > [perl] axssl s_client -? +# +# The axtls/axtlsp shared libraries must be in the same directory or be found +# by the OS. axtlsp.pm must be in this directory or be in @INC. +# +# Under Win32, ActivePerl was used (see +# http://www.activestate.com/Products/ActivePerl/?mp=1) +# +use axtlsp; +use IO::Socket; + +# To get access to Win32 file descriptor stuff +my $is_win32 = 0; + +if ($^O eq "MSWin32") +{ + eval("use Win32API::File 0.08 qw( :ALL )"); + $is_win32 = 1; +} + +use strict; + +# +# Win32 has some problems with socket handles +# +sub get_native_sock +{ + my ($sock) = @_; + return $is_win32 ? FdGetOsFHandle($sock) : $sock; +} + +# print version? +if ($#ARGV == 0 && $ARGV[0] eq "version") +{ + printf("axssl.pl ".axtlsp::ssl_version()."\n"); + exit 0; +} + +# +# Main entry point. Doesn't do much except works out whether we are a client +# or a server. +# +print_options($#ARGV > -1 ? $ARGV[0] : "") + if ($#ARGV < 0 || ($ARGV[0] ne "s_server" && $ARGV[0] ne "s_client")); + + +# Cygwin/Win32 issue - flush our output continuously +select STDOUT; +local $|=1; + +my $build_mode = axtlsp::ssl_get_config($axtlsp::SSL_BUILD_MODE); +$ARGV[0] eq "s_server" ? do_server($build_mode) : do_client($build_mode); + +# +# Implement the SSL server logic. +# +sub do_server +{ + my ($build_mode) = @_; + my $i = 1; + my $port = 4433; + my $options = $axtlsp::SSL_DISPLAY_CERTS; + my $quiet = 0; + my $password = undef; + my $private_key_file = undef; + my $cert_size = axtlsp::ssl_get_config($axtlsp::SSL_MAX_CERT_CFG_OFFSET); + my $ca_cert_size = axtlsp::ssl_get_config( + $axtlsp::SSL_MAX_CA_CERT_CFG_OFFSET); + my @cert; + my @ca_cert; + + while ($i <= $#ARGV) + { + if ($ARGV[$i] eq "-accept") + { + print_server_options($build_mode, $ARGV[$i]) if $i >= $#ARGV; + $port = $ARGV[++$i]; + } + elsif ($ARGV[$i] eq "-quiet") + { + $quiet = 1; + $options &= ~$axtlsp::SSL_DISPLAY_CERTS; + } + elsif ($build_mode >= $axtlsp::SSL_BUILD_SERVER_ONLY) + { + if ($ARGV[$i] eq "-cert") + { + print_server_options($build_mode, $ARGV[$i]) + if $i >= $#ARGV || $#cert >= $cert_size-1; + + push @cert, $ARGV[++$i]; + } + elsif ($ARGV[$i] eq "-key") + { + print_server_options($build_mode, $ARGV[$i]) if $i >= $#ARGV; + $private_key_file = $ARGV[++$i]; + $options |= $axtlsp::SSL_NO_DEFAULT_KEY; + } + elsif ($ARGV[$i] eq "-pass") + { + print_server_options($build_mode, $ARGV[$i]) if $i >= $#ARGV; + $password = $ARGV[++$i]; + } + elsif ($build_mode >= $axtlsp::SSL_BUILD_ENABLE_VERIFICATION) + { + if ($ARGV[$i] eq "-verify") + { + $options |= $axtlsp::SSL_CLIENT_AUTHENTICATION; + } + elsif ($ARGV[$i] eq "-CAfile") + { + print_server_options($build_mode, $ARGV[$i]) + if $i >= $#ARGV || $#ca_cert >= $ca_cert_size-1; + push @ca_cert, $ARGV[++$i]; + } + elsif ($build_mode == $axtlsp::SSL_BUILD_FULL_MODE) + { + if ($ARGV[$i] eq "-debug") + { + $options |= $axtlsp::SSL_DISPLAY_BYTES; + } + elsif ($ARGV[$i] eq "-state") + { + $options |= $axtlsp::SSL_DISPLAY_STATES; + } + elsif ($ARGV[$i] eq "-show-rsa") + { + $options |= $axtlsp::SSL_DISPLAY_RSA; + } + else + { + print_server_options($build_mode, $ARGV[$i]); + } + } + else + { + print_server_options($build_mode, $ARGV[$i]); + } + } + else + { + print_server_options($build_mode, $ARGV[$i]); + } + } + else + { + print_server_options($build_mode, $ARGV[$i]); + } + + $i++; + } + + # Create socket for incoming connections + my $server_sock = IO::Socket::INET->new(Proto => 'tcp', + LocalPort => $port, + Listen => 1, + Reuse => 1) or die $!; + + ########################################################################### + # This is where the interesting stuff happens. Up until now we've + # just been setting up sockets etc. Now we do the SSL handshake. + ########################################################################### + my $ssl_ctx = axtlsp::ssl_ctx_new($options, $axtlsp::SSL_DEFAULT_SVR_SESS); + die "Error: Server context is invalid" if not defined $ssl_ctx; + + if (defined $private_key_file) + { + my $obj_type = $axtlsp::SSL_OBJ_RSA_KEY; + + $obj_type = $axtlsp::SSL_OBJ_PKCS8 if $private_key_file =~ /.p8$/; + $obj_type = $axtlsp::SSL_OBJ_PKCS12 if $private_key_file =~ /.p12$/; + + die "Private key '$private_key_file' is undefined." if + axtlsp::ssl_obj_load($ssl_ctx, $obj_type, + $private_key_file, $password); + } + + foreach (@cert) + { + die "Certificate '$_' is undefined." + if axtlsp::ssl_obj_load($ssl_ctx, $axtlsp::SSL_OBJ_X509_CERT, + $_, undef) != $axtlsp::SSL_OK; + } + + foreach (@ca_cert) + { + die "Certificate '$_' is undefined." + if axtlsp::ssl_obj_load($ssl_ctx, $axtlsp::SSL_OBJ_X509_CACERT, + $_, undef) != $axtlsp::SSL_OK; + } + + for (;;) + { + printf("ACCEPT\n") if not $quiet; + my $client_sock = $server_sock->accept; + my $native_sock = get_native_sock($client_sock->fileno); + + # This doesn't work in Win32 - need to get file descriptor from socket. + my $ssl = axtlsp::ssl_server_new($ssl_ctx, $native_sock); + + # do the actual SSL handshake + my $res; + my $buf; + my $connected = 0; + + while (1) + { + ($res, $buf) = axtlsp::ssl_read($ssl, undef); + last if $res < $axtlsp::SSL_OK; + + if ($res == $axtlsp::SSL_OK) # connection established and ok + { + if (axtlsp::ssl_handshake_status($ssl) == $axtlsp::SSL_OK) + { + if (!$quiet && !$connected) + { + display_session_id($ssl); + display_cipher($ssl); + } + + $connected = 1; + } + } + + if ($res > $axtlsp::SSL_OK) + { + printf($$buf); + } + elsif ($res < $axtlsp::SSL_OK) + { + axtlsp::ssl_display_error($res) if not $quiet; + last; + } + } + + # client was disconnected or the handshake failed. + printf("CONNECTION CLOSED\n") if not $quiet; + axtlsp::ssl_free($ssl); + $client_sock->close; + } + + axtlsp::ssl_ctx_free($ssl_ctx); +} + +# +# Implement the SSL client logic. +# +sub do_client +{ + my ($build_mode) = @_; + my $i = 1; + my $port = 4433; + my $options = $axtlsp::SSL_SERVER_VERIFY_LATER|$axtlsp::SSL_DISPLAY_CERTS; + my $private_key_file = undef; + my $reconnect = 0; + my $quiet = 0; + my $password = undef; + my @session_id; + my $host = "127.0.0.1"; + my @cert; + my @ca_cert; + my $cert_size = axtlsp::ssl_get_config( + $axtlsp::SSL_MAX_CERT_CFG_OFFSET); + my $ca_cert_size = axtlsp::ssl_get_config( + $axtlsp::SSL_MAX_CA_CERT_CFG_OFFSET); + + while ($i <= $#ARGV) + { + if ($ARGV[$i] eq "-connect") + { + print_client_options($build_mode, $ARGV[$i]) if $i >= $#ARGV; + ($host, $port) = split(':', $ARGV[++$i]); + } + elsif ($ARGV[$i] eq "-cert") + { + print_client_options($build_mode, $ARGV[$i]) + if $i >= $#ARGV || $#cert >= $cert_size-1; + + push @cert, $ARGV[++$i]; + } + elsif ($ARGV[$i] eq "-key") + { + print_client_options($build_mode, $ARGV[$i]) if $i >= $#ARGV; + $private_key_file = $ARGV[++$i]; + $options |= $axtlsp::SSL_NO_DEFAULT_KEY; + } + elsif ($ARGV[$i] eq "-CAfile") + { + print_client_options($build_mode, $ARGV[$i]) + if $i >= $#ARGV || $#ca_cert >= $ca_cert_size-1; + + push @ca_cert, $ARGV[++$i]; + } + elsif ($ARGV[$i] eq "-verify") + { + $options &= ~$axtlsp::SSL_SERVER_VERIFY_LATER; + } + elsif ($ARGV[$i] eq "-reconnect") + { + $reconnect = 4; + } + elsif ($ARGV[$i] eq "-quiet") + { + $quiet = 1; + $options &= ~$axtlsp::SSL_DISPLAY_CERTS; + } + elsif ($ARGV[$i] eq "-pass") + { + print_server_options($build_mode, $ARGV[$i]) if $i >= $#ARGV; + $password = $ARGV[++$i]; + } + elsif ($build_mode == $axtlsp::SSL_BUILD_FULL_MODE) + { + if ($ARGV[$i] eq "-debug") + { + $options |= $axtlsp::SSL_DISPLAY_BYTES; + } + elsif ($ARGV[$i] eq "-state") + { + $options |= $axtlsp::SSL_DISPLAY_STATES; + } + elsif ($ARGV[$i] eq "-show-rsa") + { + $options |= $axtlsp::SSL_DISPLAY_RSA; + } + else # don't know what this is + { + print_client_options($build_mode, $ARGV[$i]); + } + } + else # don't know what this is + { + print_client_options($build_mode, $ARGV[$i]); + } + + $i++; + } + + my $client_sock = new IO::Socket::INET ( + PeerAddr => $host, PeerPort => $port, Proto => 'tcp') + || die ("no socket: $!"); + my $ssl; + my $res; + my $native_sock = get_native_sock($client_sock->fileno); + + printf("CONNECTED\n") if not $quiet; + + ########################################################################### + # This is where the interesting stuff happens. Up until now we've + # just been setting up sockets etc. Now we do the SSL handshake. + ########################################################################### + my $ssl_ctx = axtlsp::ssl_ctx_new($options, $axtlsp::SSL_DEFAULT_CLNT_SESS); + die "Error: Client context is invalid" if not defined $ssl_ctx; + + if (defined $private_key_file) + { + my $obj_type = $axtlsp::SSL_OBJ_RSA_KEY; + + $obj_type = $axtlsp::SSL_OBJ_PKCS8 if $private_key_file =~ /.p8$/; + $obj_type = $axtlsp::SSL_OBJ_PKCS12 if $private_key_file =~ /.p12$/; + + die "Private key '$private_key_file' is undefined." if + axtlsp::ssl_obj_load($ssl_ctx, $obj_type, + $private_key_file, $password); + } + + foreach (@cert) + { + die "Certificate '$_' is undefined." + if axtlsp::ssl_obj_load($ssl_ctx, $axtlsp::SSL_OBJ_X509_CERT, + $_, undef) != $axtlsp::SSL_OK; + } + + foreach (@ca_cert) + { + die "Certificate '$_' is undefined." + if axtlsp::ssl_obj_load($ssl_ctx, $axtlsp::SSL_OBJ_X509_CACERT, + $_, undef) != $axtlsp::SSL_OK; + } + + # Try session resumption? + if ($reconnect) + { + my $session_id = undef; + my $sess_id_size = 0; + + while ($reconnect--) + { + $ssl = axtlsp::ssl_client_new($ssl_ctx, $native_sock, + $session_id, $sess_id_size); + + $res = axtlsp::ssl_handshake_status($ssl); + if ($res != $axtlsp::SSL_OK) + { + axtlsp::ssl_display_error($res) if !$quiet; + axtlsp::ssl_free($ssl); + exit 1; + } + + display_session_id($ssl); + $session_id = axtlsp::ssl_get_session_id($ssl); + + if ($reconnect) + { + axtlsp::ssl_free($ssl); + $client_sock->close; + $client_sock = new IO::Socket::INET ( + PeerAddr => $host, PeerPort => $port, Proto => 'tcp') + || die ("no socket: $!"); + + } + } + } + else + { + $ssl = axtlsp::ssl_client_new($ssl_ctx, $native_sock, undef, 0); + } + + # check the return status + $res = axtlsp::ssl_handshake_status($ssl); + if ($res != $axtlsp::SSL_OK) + { + axtlsp::ssl_display_error($res) if not $quiet; + exit 1; + } + + if (!$quiet) + { + my $common_name = axtlsp::ssl_get_cert_dn($ssl, + $axtlsp::SSL_X509_CERT_COMMON_NAME); + + printf("Common Name:\t\t\t%s\n", $common_name) if defined $common_name; + display_session_id($ssl); + display_cipher($ssl); + } + + while () + { + my $cstring = pack("a*x", $_); # add null terminator + $res = axtlsp::ssl_write($ssl, \$cstring, length($cstring)); + if ($res < $axtlsp::SSL_OK) + { + axtlsp::ssl_display_error($res) if not $quiet; + last; + } + } + + axtlsp::ssl_ctx_free($ssl_ctx); + $client_sock->close; +} + +# +# We've had some sort of command-line error. Print out the basic options. +# +sub print_options +{ + my ($option) = @_; + printf("axssl: Error: '%s' is an invalid command.\n", $option); + printf("usage: axssl [s_server|s_client|version] [args ...]\n"); + exit 1; +} + +# +# We've had some sort of command-line error. Print out the server options. +# +sub print_server_options +{ + my ($build_mode, $option) = @_; + my $cert_size = axtlsp::ssl_get_config($axtlsp::SSL_MAX_CERT_CFG_OFFSET); + my $ca_cert_size = axtlsp::ssl_get_config( + $axtlsp::SSL_MAX_CA_CERT_CFG_OFFSET); + + printf("unknown option %s\n", $option); + printf("usage: s_server [args ...]\n"); + printf(" -accept arg\t- port to accept on (default is 4433)\n"); + printf(" -quiet\t\t- No server output\n"); + + if ($build_mode >= $axtlsp::SSL_BUILD_SERVER_ONLY) + { + printf(" -cert arg\t- certificate file to add (in addition to default)". + " to chain -\n". + "\t\t Can repeat up to %d times\n", $cert_size); + printf(" -key arg\t- Private key file to use - default DER format\n"); + printf(" -pass\t\t- private key file pass phrase source\n"); + } + + if ($build_mode >= $axtlsp::SSL_BUILD_ENABLE_VERIFICATION) + { + printf(" -verify\t- turn on peer certificate verification\n"); + printf(" -CAfile arg\t- Certificate authority - default DER format\n"); + printf("\t\t Can repeat up to %d times\n", $ca_cert_size); + } + + if ($build_mode == $axtlsp::SSL_BUILD_FULL_MODE) + { + printf(" -debug\t\t- Print more output\n"); + printf(" -state\t\t- Show state messages\n"); + printf(" -show-rsa\t- Show RSA state\n"); + } + + exit 1; +} + +# +# We've had some sort of command-line error. Print out the client options. +# +sub print_client_options +{ + my ($build_mode, $option) = @_; + my $cert_size = axtlsp::ssl_get_config($axtlsp::SSL_MAX_CERT_CFG_OFFSET); + my $ca_cert_size = axtlsp::ssl_get_config( + $axtlsp::SSL_MAX_CA_CERT_CFG_OFFSET); + + printf("unknown option %s\n", $option); + + if ($build_mode >= $axtlsp::SSL_BUILD_ENABLE_CLIENT) + { + printf("usage: s_client [args ...]\n"); + printf(" -connect host:port - who to connect to (default ". + "is localhost:4433)\n"); + printf(" -verify\t- turn on peer certificate verification\n"); + printf(" -cert arg\t- certificate file to use - default DER format\n"); + printf(" -key arg\t- Private key file to use - default DER format\n"); + printf("\t\t Can repeat up to %d times\n", $cert_size); + printf(" -CAfile arg\t- Certificate authority - default DER format\n"); + printf("\t\t Can repeat up to %d times\n", $ca_cert_size); + printf(" -quiet\t\t- No client output\n"); + printf(" -pass\t\t- private key file pass phrase source\n"); + printf(" -reconnect\t- Drop and re-make the connection ". + "with the same Session-ID\n"); + + if ($build_mode == $axtlsp::SSL_BUILD_FULL_MODE) + { + printf(" -debug\t\t- Print more output\n"); + printf(" -state\t\t- Show state messages\n"); + printf(" -show-rsa\t- Show RSA state\n"); + } + } + else + { + printf("Change configuration to allow this feature\n"); + } + + exit 1; +} + +# +# Display what cipher we are using +# +sub display_cipher +{ + my ($ssl) = @_; + printf("CIPHER is "); + my $cipher_id = axtlsp::ssl_get_cipher_id($ssl); + + if ($cipher_id == $axtlsp::SSL_AES128_SHA) + { + printf("AES128-SHA"); + } + elsif ($cipher_id == $axtlsp::SSL_AES256_SHA) + { + printf("AES256-SHA"); + } + elsif ($axtlsp::SSL_AES128_SHA256) + { + printf("AES128-SHA256"); + } + elsif ($axtlsp::SSL_AES256_SHA256) + { + printf("AES256-SHA256"); + } + else + { + printf("Unknown - %d", $cipher_id); + } + + printf("\n"); +} + +# +# Display what session id we have. +# +sub display_session_id +{ + my ($ssl) = @_; + my $session_id = axtlsp::ssl_get_session_id($ssl); + if (length($$session_id) > 0) + { + printf("-----BEGIN SSL SESSION PARAMETERS-----\n"); + printf(unpack("H*", $$session_id)); + printf("\n-----END SSL SESSION PARAMETERS-----\n"); + } +} diff --git a/circuitpython/lib/axtls/samples/vbnet/Makefile b/circuitpython/lib/axtls/samples/vbnet/Makefile new file mode 100644 index 0000000..0984d4e --- /dev/null +++ b/circuitpython/lib/axtls/samples/vbnet/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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 ../../config/.config +include ../../config/makefile.conf +include ../../config/makefile.dotnet.conf + +# only build on Win32 platforms +ifdef GO_DOT_NET +all : sample +TARGET=../../$(STAGE)/axssl.vbnet.exe +sample : $(TARGET) + +$(TARGET): ../../bindings/vbnet/axTLSvb.vb ../../bindings/vbnet/axInterface.vb axssl.vb + vbc.exe /r:"`cygpath -w "$(CONFIG_DOT_NET_FRAMEWORK_BASE)/System.dll"`" /nologo /t:exe /out:"`cygpath -w $@`" $(foreach file, $^, "`cygpath -w $(file)`") + +endif # ARCH + +clean:: + -@rm -f $(TARGET) + diff --git a/circuitpython/lib/axtls/samples/vbnet/axssl.vb b/circuitpython/lib/axtls/samples/vbnet/axssl.vb new file mode 100644 index 0000000..7e5d682 --- /dev/null +++ b/circuitpython/lib/axtls/samples/vbnet/axssl.vb @@ -0,0 +1,702 @@ +' +' Copyright (c) 2007-2016, Cameron Rich +' +' 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 axTLS project 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. +' + +' +' Demonstrate the use of the axTLS library in VB.NET with a set of +' command-line parameters similar to openssl. In fact, openssl clients +' should be able to communicate with axTLS servers and visa-versa. +' +' This code has various bits enabled depending on the configuration. To enable +' the most interesting version, compile with the 'full mode' enabled. +' +' To see what options you have, run the following: +' > axssl.vbnet.exe s_server -? +' > axssl.vbnet.exe s_client -? +' +' The axtls shared library must be in the same directory or be found +' by the OS. +' + +Imports System +Imports System.Net +Imports System.Net.Sockets +Imports Microsoft.VisualBasic +Imports axTLSvb + +Public Class axssl + ' + ' do_server() + ' + Public Sub do_server(ByVal build_mode As Integer, _ + ByVal args() As String) + Dim i As Integer = 1 + Dim port As Integer = 4433 + Dim options As Integer = axtls.SSL_DISPLAY_CERTS + Dim quiet As Boolean = False + Dim password As String = Nothing + Dim private_key_file As String = Nothing + + ' organise the cert/ca_cert lists + Dim cert_size As Integer = SSLUtil.MaxCerts() + Dim ca_cert_size As Integer = SSLUtil.MaxCACerts() + Dim cert(cert_size) As String + Dim ca_cert(ca_cert_size) As String + Dim cert_index As Integer = 0 + Dim ca_cert_index As Integer = 0 + + While i < args.Length + If args(i) = "-accept" Then + If i >= args.Length-1 + print_server_options(build_mode, args(i)) + End If + + i += 1 + port = Int32.Parse(args(i)) + ElseIf args(i) = "-quiet" + quiet = True + options = options And Not axtls.SSL_DISPLAY_CERTS + ElseIf build_mode >= axtls.SSL_BUILD_SERVER_ONLY + If args(i) = "-cert" + If i >= args.Length-1 Or cert_index >= cert_size + print_server_options(build_mode, args(i)) + End If + + i += 1 + cert(cert_index) = args(i) + cert_index += 1 + ElseIf args(i) = "-key" + If i >= args.Length-1 + print_server_options(build_mode, args(i)) + End If + + i += 1 + private_key_file = args(i) + options = options Or axtls.SSL_NO_DEFAULT_KEY + ElseIf args(i) = "-pass" + If i >= args.Length-1 + print_server_options(build_mode, args(i)) + End If + + i += 1 + password = args(i) + ElseIf build_mode >= axtls.SSL_BUILD_ENABLE_VERIFICATION + If args(i) = "-verify" Then + options = options Or axtls.SSL_CLIENT_AUTHENTICATION + ElseIf args(i) = "-CAfile" + If i >= args.Length-1 Or _ + ca_cert_index >= ca_cert_size Then + print_server_options(build_mode, args(i)) + End If + + i += 1 + ca_cert(ca_cert_index) = args(i) + ca_cert_index += 1 + ElseIf build_mode = axtls.SSL_BUILD_FULL_MODE + If args(i) = "-debug" Then + options = options Or axtls.SSL_DISPLAY_BYTES + ElseIf args(i) = "-state" + options = options Or axtls.SSL_DISPLAY_STATES + ElseIf args(i) = "-show-rsa" + options = options Or axtls.SSL_DISPLAY_RSA + Else + print_server_options(build_mode, args(i)) + End If + Else + print_server_options(build_mode, args(i)) + End If + Else + print_server_options(build_mode, args(i)) + End If + End If + + i += 1 + End While + + ' Create socket for incoming connections + Dim ep As IPEndPoint = New IPEndPoint(IPAddress.Any, port) + Dim server_sock As TcpListener = New TcpListener(ep) + server_sock.Start() + + '********************************************************************* + ' This is where the interesting stuff happens. Up until now we've + ' just been setting up sockets etc. Now we do the SSL handshake. + '*********************************************************************/ + Dim ssl_ctx As SSLServer = New SSLServer(options, _ + axtls.SSL_DEFAULT_SVR_SESS) + + If ssl_ctx Is Nothing Then + Console.Error.WriteLine("Error: Server context is invalid") + Environment.Exit(1) + End If + + If private_key_file <> Nothing Then + Dim obj_type As Integer = axtls.SSL_OBJ_RSA_KEY + + If private_key_file.EndsWith(".p8") Then + obj_type = axtls.SSL_OBJ_PKCS8 + Else If (private_key_file.EndsWith(".p12")) + obj_type = axtls.SSL_OBJ_PKCS12 + End If + + If ssl_ctx.ObjLoad(obj_type, private_key_file, _ + password) <> axtls.SSL_OK Then + Console.Error.WriteLine("Error: Private key '" & _ + private_key_file & "' is undefined.") + Environment.Exit(1) + End If + End If + + For i = 0 To cert_index-1 + If ssl_ctx.ObjLoad(axtls.SSL_OBJ_X509_CERT, _ + cert(i), Nothing) <> axtls.SSL_OK Then + Console.WriteLine("Certificate '" & cert(i) & _ + "' is undefined.") + Environment.Exit(1) + End If + Next + + For i = 0 To ca_cert_index-1 + If ssl_ctx.ObjLoad(axtls.SSL_OBJ_X509_CACERT, _ + ca_cert(i), Nothing) <> axtls.SSL_OK Then + Console.WriteLine("Certificate '" & ca_cert(i) & _ + "' is undefined.") + Environment.Exit(1) + End If + Next + + Dim buf As Byte() = Nothing + Dim res As Integer + Dim ssl As SSL + + While 1 + If Not quiet Then + Console.WriteLine("ACCEPT") + End If + + Dim client_sock As Socket = server_sock.AcceptSocket() + + ssl = ssl_ctx.Connect(client_sock) + + ' do the actual SSL handshake + While 1 + res = ssl_ctx.Read(ssl, buf) + If res <> axtls.SSL_OK Then + Exit While + End If + + ' check when the connection has been established + If ssl.HandshakeStatus() = axtls.SSL_OK + Exit While + End If + + ' could do something else here + End While + + If res = axtls.SSL_OK Then ' connection established and ok + If Not quiet + display_session_id(ssl) + display_cipher(ssl) + End If + + ' now read (and display) whatever the client sends us + While 1 + ' keep reading until we get something interesting + While 1 + res = ssl_ctx.Read(ssl, buf) + If res <> axtls.SSL_OK Then + Exit While + End If + + ' could do something else here + End While + + If res < axtls.SSL_OK + If Not quiet + Console.WriteLine("CONNECTION CLOSED") + End If + + Exit While + End If + + ' convert to String + Dim str(res) As Char + For i = 0 To res-1 + str(i) = Chr(buf(i)) + Next + + Console.Write(str) + End While + ElseIf Not quiet + SSLUtil.DisplayError(res) + End If + + ' client was disconnected or the handshake failed. */ + ssl.Dispose() + client_sock.Close() + End While + + ssl_ctx.Dispose() + End Sub + + ' + ' do_client() + ' + Public Sub do_client(ByVal build_mode As Integer, _ + ByVal args() As String) + + If build_mode < axtls.SSL_BUILD_ENABLE_CLIENT Then + print_client_options(build_mode, args(1)) + End If + + Dim i As Integer = 1 + Dim res As Integer + Dim port As Integer = 4433 + Dim quiet As Boolean = False + Dim password As String = Nothing + Dim reconnect As Integer = 0 + Dim private_key_file As String = Nothing + Dim hostname As String = "127.0.0.1" + + ' organise the cert/ca_cert lists + Dim ssl As SSL = Nothing + Dim cert_size As Integer = SSLUtil.MaxCerts() + Dim ca_cert_size As Integer = SSLUtil.MaxCACerts() + Dim cert(cert_size) As String + Dim ca_cert(ca_cert_size) As String + Dim cert_index As Integer = 0 + Dim ca_cert_index As Integer = 0 + + Dim options As Integer = _ + axtls.SSL_SERVER_VERIFY_LATER Or axtls.SSL_DISPLAY_CERTS + Dim session_id As Byte() = Nothing + + While i < args.Length + If args(i) = "-connect" Then + Dim host_port As String + + If i >= args.Length-1 + print_client_options(build_mode, args(i)) + End If + + i += 1 + host_port = args(i) + + Dim index_colon As Integer = host_port.IndexOf(":"C) + If index_colon < 0 Then + print_client_options(build_mode, args(i)) + End If + + hostname = New String(host_port.ToCharArray(), _ + 0, index_colon) + port = Int32.Parse(New String(host_port.ToCharArray(), _ + index_colon+1, host_port.Length-index_colon-1)) + ElseIf args(i) = "-cert" + If i >= args.Length-1 Or cert_index >= cert_size Then + print_client_options(build_mode, args(i)) + End If + + i += 1 + cert(cert_index) = args(i) + cert_index += 1 + ElseIf args(i) = "-key" + If i >= args.Length-1 + print_client_options(build_mode, args(i)) + End If + + i += 1 + private_key_file = args(i) + options = options Or axtls.SSL_NO_DEFAULT_KEY + ElseIf args(i) = "-CAfile" + If i >= args.Length-1 Or ca_cert_index >= ca_cert_size + print_client_options(build_mode, args(i)) + End If + + i += 1 + ca_cert(ca_cert_index) = args(i) + ca_cert_index += 1 + ElseIf args(i) = "-verify" + options = options And Not axtls.SSL_SERVER_VERIFY_LATER + ElseIf args(i) = "-reconnect" + reconnect = 4 + ElseIf args(i) = "-quiet" + quiet = True + options = options And Not axtls.SSL_DISPLAY_CERTS + ElseIf args(i) = "-pass" + If i >= args.Length-1 + print_client_options(build_mode, args(i)) + End If + + i += 1 + password = args(i) + ElseIf build_mode = axtls.SSL_BUILD_FULL_MODE + If args(i) = "-debug" Then + options = options Or axtls.SSL_DISPLAY_BYTES + ElseIf args(i) = "-state" + options = options Or axtls.SSL_DISPLAY_STATES + ElseIf args(i) = "-show-rsa" + options = options Or axtls.SSL_DISPLAY_RSA + Else + print_client_options(build_mode, args(i)) + End If + Else ' don't know what this is + print_client_options(build_mode, args(i)) + End If + + i += 1 + End While + + 'Dim hostInfo As IPHostEntry = Dns.Resolve(hostname) + Dim hostInfo As IPHostEntry = Dns.GetHostEntry(hostname) + Dim addresses As IPAddress() = hostInfo.AddressList + Dim ep As IPEndPoint = New IPEndPoint(addresses(0), port) + Dim client_sock As Socket = New Socket(AddressFamily.InterNetwork, _ + SocketType.Stream, ProtocolType.Tcp) + client_sock.Connect(ep) + + If Not client_sock.Connected Then + Console.WriteLine("could not connect") + Environment.Exit(1) + End If + + If Not quiet Then + Console.WriteLine("CONNECTED") + End If + + '********************************************************************* + ' This is where the interesting stuff happens. Up until now we've + ' just been setting up sockets etc. Now we do the SSL handshake. + '*********************************************************************/ + Dim ssl_ctx As SSLClient = New SSLClient(options, _ + axtls.SSL_DEFAULT_CLNT_SESS) + + If ssl_ctx Is Nothing Then + Console.Error.WriteLine("Error: Client context is invalid") + Environment.Exit(1) + End If + + If private_key_file <> Nothing Then + Dim obj_type As Integer = axtls.SSL_OBJ_RSA_KEY + + If private_key_file.EndsWith(".p8") Then + obj_type = axtls.SSL_OBJ_PKCS8 + Else If (private_key_file.EndsWith(".p12")) + obj_type = axtls.SSL_OBJ_PKCS12 + End If + + If ssl_ctx.ObjLoad(obj_type, private_key_file, _ + password) <> axtls.SSL_OK Then + Console.Error.WriteLine("Error: Private key '" & _ + private_key_file & "' is undefined.") + Environment.Exit(1) + End If + End If + + For i = 0 To cert_index-1 + If ssl_ctx.ObjLoad(axtls.SSL_OBJ_X509_CERT, _ + cert(i), Nothing) <> axtls.SSL_OK Then + Console.WriteLine("Certificate '" & cert(i) & _ + "' is undefined.") + Environment.Exit(1) + End If + Next + + For i = 0 To ca_cert_index-1 + If ssl_ctx.ObjLoad(axtls.SSL_OBJ_X509_CACERT, _ + ca_cert(i), Nothing) <> axtls.SSL_OK Then + Console.WriteLine("Certificate '" & ca_cert(i) & _ + "' is undefined.") + Environment.Exit(1) + End If + Next + + ' Try session resumption? + If reconnect > 0 Then + While reconnect > 0 + reconnect -= 1 + ssl = ssl_ctx.Connect(client_sock, session_id) + + res = ssl.HandshakeStatus() + If res <> axtls.SSL_OK Then + If Not quiet Then + SSLUtil.DisplayError(res) + End If + + ssl.Dispose() + Environment.Exit(1) + End If + + display_session_id(ssl) + session_id = ssl.GetSessionId() + + If reconnect > 0 Then + ssl.Dispose() + client_sock.Close() + + ' and reconnect + client_sock = New Socket(AddressFamily.InterNetwork, _ + SocketType.Stream, ProtocolType.Tcp) + client_sock.Connect(ep) + End If + End While + Else + ssl = ssl_ctx.Connect(client_sock, Nothing) + End If + + ' check the return status + res = ssl.HandshakeStatus() + If res <> axtls.SSL_OK Then + If Not quiet Then + SSLUtil.DisplayError(res) + End If + + Environment.Exit(1) + End If + + If Not quiet Then + Dim common_name As String = _ + ssl.GetCertificateDN(axtls.SSL_X509_CERT_COMMON_NAME) + + If common_name <> Nothing + Console.WriteLine("Common Name:" & _ + ControlChars.Tab & ControlChars.Tab & _ + ControlChars.Tab & common_name) + End If + + display_session_id(ssl) + display_cipher(ssl) + End If + + While (1) + Dim user_input As String = Console.ReadLine() + + If user_input = Nothing Then + Exit While + End If + + Dim buf(user_input.Length+1) As Byte + buf(buf.Length-2) = Asc(ControlChars.Lf) ' add the carriage return + buf(buf.Length-1) = 0 ' null terminate + + For i = 0 To user_input.Length-1 + buf(i) = Asc(user_input.Chars(i)) + Next + + res = ssl_ctx.Write(ssl, buf, buf.Length) + If res < axtls.SSL_OK Then + If Not quiet Then + SSLUtil.DisplayError(res) + End If + + Exit While + End If + End While + + ssl_ctx.Dispose() + End Sub + + ' + ' Display what cipher we are using + ' + Private Sub display_cipher(ByVal ssl As SSL) + Console.Write("CIPHER is ") + + Select ssl.GetCipherId() + Case axtls.SSL_AES128_SHA + Console.WriteLine("AES128-SHA") + + Case axtls.SSL_AES256_SHA + Console.WriteLine("AES256-SHA") + + Case axtls.SSL_AES128_SHA256 + Console.WriteLine("AES128-SHA256") + + Case axtls.SSL_AES256_SHA256 + Console.WriteLine("AES256-SHA256") + + Case Else + Console.WriteLine("Unknown - " & ssl.GetCipherId()) + End Select + End Sub + + ' + ' Display what session id we have. + ' + Private Sub display_session_id(ByVal ssl As SSL) + Dim session_id As Byte() = ssl.GetSessionId() + + If session_id.Length > 0 Then + Console.WriteLine("-----BEGIN SSL SESSION PARAMETERS-----") + Dim b As Byte + For Each b In session_id + Console.Write("{0:x02}", b) + Next + + Console.WriteLine() + Console.WriteLine("-----END SSL SESSION PARAMETERS-----") + End If + End Sub + + ' + ' We've had some sort of command-line error. Print out the basic options. + ' + Public Sub print_options(ByVal options As String) + Console.WriteLine("axssl: Error: '" & options & _ + "' is an invalid command.") + Console.WriteLine("usage: axssl.vbnet [s_server|s_client|" & _ + "version] [args ...]") + Environment.Exit(1) + End Sub + + ' + ' We've had some sort of command-line error. Print out the server options. + ' + Private Sub print_server_options(ByVal build_mode As Integer, _ + ByVal options As String) + Dim cert_size As Integer = SSLUtil.MaxCerts() + Dim ca_cert_size As Integer = SSLUtil.MaxCACerts() + + Console.WriteLine("unknown option " & options) + Console.WriteLine("usage: s_server [args ...]") + Console.WriteLine(" -accept arg" & ControlChars.Tab & _ + "- port to accept on (default is 4433)") + Console.WriteLine(" -quiet" & ControlChars.Tab & ControlChars.Tab & _ + "- No server output") + If build_mode >= axtls.SSL_BUILD_SERVER_ONLY + Console.WriteLine(" -cert arg" & ControlChars.Tab & _ + "- certificate file to add (in addition to default) to chain -") + Console.WriteLine(ControlChars.Tab & ControlChars.Tab & _ + " Can repeat up to " & cert_size & " times") + Console.WriteLine(" -key arg" & ControlChars.Tab & _ + "- Private key file to use") + Console.WriteLine(" -pass" & ControlChars.Tab & ControlChars.Tab & _ + "- private key file pass phrase source") + End If + + If build_mode >= axtls.SSL_BUILD_ENABLE_VERIFICATION + Console.WriteLine(" -verify" & ControlChars.Tab & _ + "- turn on peer certificate verification") + Console.WriteLine(" -CAfile arg" & ControlChars.Tab & _ + "- Certificate authority") + Console.WriteLine(ControlChars.Tab & ControlChars.Tab & _ + " Can repeat up to " & ca_cert_size & " times") + End If + + If build_mode = axtls.SSL_BUILD_FULL_MODE + Console.WriteLine(" -debug" & _ + ControlChars.Tab & ControlChars.Tab & _ + "- Print more output") + Console.WriteLine(" -state" & _ + ControlChars.Tab & ControlChars.Tab & _ + "- Show state messages") + Console.WriteLine(" -show-rsa" & _ + ControlChars.Tab & "- Show RSA state") + End If + + Environment.Exit(1) + End Sub + + ' + ' We've had some sort of command-line error. Print out the client options. + ' + Private Sub print_client_options(ByVal build_mode As Integer, _ + ByVal options As String) + Dim cert_size As Integer = SSLUtil.MaxCerts() + Dim ca_cert_size As Integer = SSLUtil.MaxCACerts() + + Console.WriteLine("unknown option " & options) + + If build_mode >= axtls.SSL_BUILD_ENABLE_CLIENT Then + Console.WriteLine("usage: s_client [args ...]") + Console.WriteLine(" -connect host:port - who to connect to " & _ + "(default is localhost:4433)") + Console.WriteLine(" -verify" & ControlChars.Tab & _ + "- turn on peer certificate verification") + Console.WriteLine(" -cert arg" & ControlChars.Tab & _ + "- certificate file to use") + Console.WriteLine(ControlChars.Tab & ControlChars.Tab & _ + " Can repeat up to " & cert_size & " times") + Console.WriteLine(" -key arg" & ControlChars.Tab & _ + "- Private key file to use") + Console.WriteLine(" -CAfile arg" & ControlChars.Tab & _ + "- Certificate authority") + Console.WriteLine(ControlChars.Tab & ControlChars.Tab & _ + " Can repeat up to " & ca_cert_size & " times") + Console.WriteLine(" -quiet" & _ + ControlChars.Tab & ControlChars.Tab & "- No client output") + Console.WriteLine(" -pass" & ControlChars.Tab & _ + ControlChars.Tab & _ + "- private key file pass phrase source") + Console.WriteLine(" -reconnect" & ControlChars.Tab & _ + "- Drop and re-make the " & _ + "connection with the same Session-ID") + + If build_mode = axtls.SSL_BUILD_FULL_MODE Then + Console.WriteLine(" -debug" & _ + ControlChars.Tab & ControlChars.Tab & _ + "- Print more output") + Console.WriteLine(" -state" & _ + ControlChars.Tab & ControlChars.Tab & _ + "- Show state messages") + Console.WriteLine(" -show-rsa" & ControlChars.Tab & _ + "- Show RSA state") + End If + Else + Console.WriteLine("Change configuration to allow this feature") + End If + + Environment.Exit(1) + End Sub + +End Class + +Public Module MyMain + Function Main(ByVal args() As String) As Integer + Dim runner As axssl = New axssl() + + If args.Length = 1 And args(0) = "version" Then + Console.WriteLine("axssl.vbnet " & SSLUtil.Version()) + Environment.Exit(0) + End If + + If args.Length < 1 + runner.print_options("") + ElseIf args(0) <> "s_server" And args(0) <> "s_client" + runner.print_options(args(0)) + End If + + Dim build_mode As Integer = SSLUtil.BuildMode() + + If args(0) = "s_server" Then + runner.do_server(build_mode, args) + Else + runner.do_client(build_mode, args) + End If + End Function +End Module diff --git a/circuitpython/lib/axtls/ssl/BigIntConfig.in b/circuitpython/lib/axtls/ssl/BigIntConfig.in new file mode 100644 index 0000000..116ce17 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/BigIntConfig.in @@ -0,0 +1,145 @@ +# +# For a description of the syntax of this configuration file, +# see scripts/config/Kconfig-language.txt +# + +menu "BigInt Options" + depends on !CONFIG_SSL_SKELETON_MODE + +choice + prompt "Reduction Algorithm" + default CONFIG_BIGINT_BARRETT + +config CONFIG_BIGINT_CLASSICAL + bool "Classical" + help + Classical uses standard division. It has no limitations and is + theoretically the slowest due to the divisions used. For this particular + implementation it is surprisingly quite fast. + +config CONFIG_BIGINT_MONTGOMERY + bool "Montgomery" + help + Montgomery uses simple addition and multiplication to achieve its + performance. It has the limitation that 0 <= x, y < m, and so is not + used when CRT is active. + + This option will not be normally selected. + +config CONFIG_BIGINT_BARRETT + bool "Barrett" + help + Barrett performs expensive precomputation before reduction and partial + multiplies for computational speed. + + It is about 40% faster than Classical/Montgomery with the expense of + about 2kB, and so this option is normally selected. + +endchoice + +config CONFIG_BIGINT_CRT + bool "Chinese Remainder Theorem (CRT)" + default y + help + Allow the Chinese Remainder Theorem (CRT) to be used. + + Uses a number of extra coefficients from the private key to improve the + performance of a decryption. This feature is one of the most + significant performance improvements (it reduces a decryption time by + over 3 times). + + This option should be selected. + +config CONFIG_BIGINT_KARATSUBA + bool "Karatsuba Multiplication" + default n + help + Allow Karasuba multiplication to be used. + + Uses 3 multiplications (plus a number of additions/subtractions) + instead of 4. Multiplications are O(N^2) but addition/subtraction + is O(N) hence for large numbers is beneficial. For this project, the + effect was only useful for 4096 bit keys (for 32 bit processors). For + 8 bit processors this option might be a possibility. + + It costs about 2kB to enable it. + +config MUL_KARATSUBA_THRESH + int "Karatsuba Multiplication Theshold" + default 20 + depends on CONFIG_BIGINT_KARATSUBA + help + The minimum number of components needed before Karasuba muliplication + is used. + + This is very dependent on the speed/implementation of bi_add()/ + bi_subtract(). There is a bit of trial and error here and will be + at a different point for different architectures. + +config SQU_KARATSUBA_THRESH + int "Karatsuba Square Threshold" + default 40 + depends on CONFIG_BIGINT_KARATSUBA && CONFIG_BIGINT_SQUARE + help + The minimum number of components needed before Karatsuba squaring + is used. + + This is very dependent on the speed/implementation of bi_add()/ + bi_subtract(). There is a bit of trial and error here and will be + at a different point for different architectures. + +config CONFIG_BIGINT_SLIDING_WINDOW + bool "Sliding Window Exponentiation" + default y + help + Allow Sliding-Window Exponentiation to be used. + + Potentially processes more than 1 bit at a time when doing + exponentiation. The sliding-window technique reduces the number of + precomputations compared to other precomputed techniques. + + It results in a considerable performance improvement with it enabled + (it halves the decryption time) and so should be selected. + +config CONFIG_BIGINT_SQUARE + bool "Square Algorithm" + default y + help + Allow squaring to be used instead of a multiplication. It uses + 1/2 of the standard multiplies to obtain its performance. + It gives a 20% speed improvement overall and so should be selected. + +config CONFIG_BIGINT_CHECK_ON + bool "BigInt Integrity Checking" + default n if !CONFIG_DEBUG + default y if CONFIG_DEBUG + help + This is used when developing bigint algorithms. It performs a sanity + check on all operations at the expense of speed. + + This option is only selected when developing and should normally be + turned off. + +choice + prompt "Integer Size" + default CONFIG_INTEGER_32BIT + +config CONFIG_INTEGER_32BIT + bool "32" + help + The native integer size is 32 bits or higher. + + +config CONFIG_INTEGER_16BIT + bool "16" + help + The native integer size is 16 bits. + +config CONFIG_INTEGER_8BIT + bool "8" + help + The native integer size is 8 bits. + +endchoice +endmenu + diff --git a/circuitpython/lib/axtls/ssl/Config.in b/circuitpython/lib/axtls/ssl/Config.in new file mode 100644 index 0000000..aac4144 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/Config.in @@ -0,0 +1,341 @@ +# +# For a description of the syntax of this configuration file, +# see scripts/config/Kconfig-language.txt +# + +menu "SSL Library" + +choice + prompt "Mode" + default CONFIG_SSL_FULL_MODE + +config CONFIG_SSL_SERVER_ONLY + bool "Server only - no verification" + help + Enable server functionality (no client functionality). + This mode still supports sessions and chaining (which can be turned + off in configuration). + + The axssl sample runs with the minimum of features. + + This is the most space efficient of the modes with the library + about 45kB in size. Use this mode if you are doing standard SSL server + work. + +config CONFIG_SSL_CERT_VERIFICATION + bool "Server only - with verification" + help + Enable server functionality with client authentication (no client + functionality). + + The axssl sample runs with the "-verify" and "-CAfile" options. + + This mode produces a library about 49kB in size. Use this mode if you + have an SSL server which requires client authentication (which is + uncommon in browser applications). + + +config CONFIG_SSL_FULL_MODE + bool "Client/Server enabled with diagnostics" + help + Enable client/server functionality including diagnostics. Most of the + extra size in this mode is due to the storage of various strings that + are used. + + The axssl sample has 3 more options, "-debug", "-state" and "-show-rsa" + + This mode produces a library about 58kB in size. It is suggested that + this mode is used only during development, or systems that have more + generous memory limits. + + It is the default to demonstrate the features of axTLS. + +config CONFIG_SSL_SKELETON_MODE + bool "Skeleton mode - the smallest server mode" + help + This is an experiment to build the smallest library at the expense of + features and speed. + + * Server mode only. + * The AES cipher is disabled. + * No session resumption. + * No external keys/certificates are supported. + * The bigint library has most of the performance features disabled. + * Some other features/API calls may not work. + + This mode produces a library about 37kB in size. The main + disadvantage of this mode is speed - it will be much slower than the + other build modes. + +endchoice + +config CONFIG_SSL_ENABLE_SERVER + bool "Server enabled" + help + Enable server functionality. + +config CONFIG_SSL_ENABLE_CLIENT + bool "Client enabled" + help + Enable client functionality. + + The axssl sample runs with the "s_client" option enabled. + + This mode produces a library about 51kB in size. Use this mode if you + require axTLS to use SSL client functionality (the SSL server code + is always enabled). + +config CONFIG_SSL_DIAGNOSTICS + bool "Diagnostic messages" + help + Enable support for diagnostics of connection progress and state. + +choice + prompt "Protocol Preference" +# depends on !CONFIG_SSL_SKELETON_MODE + default CONFIG_SSL_PROT_MEDIUM + +config CONFIG_SSL_PROT_LOW + bool "Low" + help + Chooses the cipher in the order of AES128-SHA, AES128-SHA256, + AES256-SHA256. + + This will use the fastest cipher(s) but at the expense of security. + +config CONFIG_SSL_PROT_MEDIUM + bool "Medium" + help + Chooses the cipher in the order of AES128-SHA256, AES256-SHA256, + AES128-SHA + + This mode is a balance between speed and security and is the default. + +config CONFIG_SSL_PROT_HIGH + bool "High" + help + Chooses the cipher in the order of AES256-SHA256, AES128-SHA256, + AES128-SHA. + + This will use the strongest cipher(s) at the cost of speed. + +endchoice + +config CONFIG_SSL_AES + bool "Enable AES cipher" + default y + help + Enable/disable AES support. + +config CONFIG_SSL_USE_DEFAULT_KEY + bool "Enable default key" +# depends on !CONFIG_SSL_SKELETON_MODE + default y + help + Some applications will not require the default private key/certificate + that is built in. This is one way to save on a couple of kB's if an + external private key/certificate is used. + + The private key is in ssl/private_key.h and the certificate is in + ssl/cert.h. + + The advantage of a built-in private key/certificate is that no file + system is required for access. Both the certificate and the private + key will be automatically loaded on a ssl_ctx_new(). + + However this private key/certificate can never be changed (without a + code update). + + This mode is enabled by default. Disable this mode if the + built-in key/certificate is not used. + +config CONFIG_SSL_PRIVATE_KEY_LOCATION + string "Private key file location" + depends on !CONFIG_SSL_USE_DEFAULT_KEY && !CONFIG_SSL_SKELETON_MODE + help + The file location of the private key which will be automatically + loaded on a ssl_ctx_new(). + +config CONFIG_SSL_PRIVATE_KEY_PASSWORD + string "Private key password" + depends on !CONFIG_SSL_USE_DEFAULT_KEY && CONFIG_SSL_HAS_PEM + help + The password required to decrypt a PEM-encoded password file. + +config CONFIG_SSL_X509_CERT_LOCATION + string "X.509 certificate file location" + depends on !CONFIG_SSL_GENERATE_X509_CERT && !CONFIG_SSL_USE_DEFAULT_KEY && !CONFIG_SSL_SKELETON_MODE + help + The file location of the X.509 certificate which will be automatically + loaded on a ssl_ctx_new(). + +config CONFIG_SSL_GENERATE_X509_CERT + bool "Generate X.509 Certificate" + default n + help + An X.509 certificate can be automatically generated on a + ssl_ctx_new(). A private key still needs to be provided (the private + key in ss/private_key.h will be used unless + CONFIG_SSL_PRIVATE_KEY_LOCATION is set). + + The certificate is generated on the fly, and so a minor start-up time + penalty is to be expected. This feature adds around 5kB to the + library. + + This feature is disabled by default. + +config CONFIG_SSL_X509_COMMON_NAME + string "X.509 Common Name" + depends on CONFIG_SSL_GENERATE_X509_CERT + help + The common name for the X.509 certificate. This should be the fully + qualified domain name (FQDN), e.g. www.foo.com. + + If this is blank, then this will be value from gethostname() and + getdomainname(). + +config CONFIG_SSL_X509_ORGANIZATION_NAME + string "X.509 Organization Name" + depends on CONFIG_SSL_GENERATE_X509_CERT + help + The organization name for the generated X.509 certificate. + + This field is optional. + +config CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME + string "X.509 Organization Unit Name" + depends on CONFIG_SSL_GENERATE_X509_CERT + help + The organization unit name for the generated X.509 certificate. + + This field is optional. + +config CONFIG_SSL_HAS_PEM + bool "Enable PEM" + default n if !CONFIG_SSL_FULL_MODE + default y if CONFIG_SSL_FULL_MODE + depends on !CONFIG_SSL_SKELETON_MODE + help + Enable the use of PEM format for certificates and private keys. + + PEM is not normally needed - PEM files can be converted into DER files + quite easily. However they have the convenience of allowing multiple + certificates/keys in the same file. + + This feature will add a couple of kB to the library. + + Disable if PEM is not used (which will be in most cases). + +config CONFIG_SSL_USE_PKCS12 + bool "Use PKCS8/PKCS12" + default n if !CONFIG_SSL_FULL_MODE + default y if CONFIG_SSL_FULL_MODE + depends on !CONFIG_SSL_SKELETON_MODE + help + PKCS#12 certificates combine private keys and certificates together in + one file. + + PKCS#8 private keys are also suppported (as it is a subset of PKCS#12). + + The decryption of these certificates uses RC4-128 (and these + certificates must be encrypted using this cipher). The actual + algorithm is "PBE-SHA1-RC4-128". + + Disable if PKCS#12 is not used (which will be in most cases). + +config CONFIG_SSL_EXPIRY_TIME + int "Session expiry time (in hours)" + depends on !CONFIG_SSL_SKELETON_MODE + default 24 + help + The time (in hours) before a session expires. + + A longer time means that the expensive parts of a handshake don't + need to be run when a client reconnects later. + + The default is 1 day. + +config CONFIG_X509_MAX_CA_CERTS + int "Maximum number of certificate authorites" + default 150 +# depends on !CONFIG_SSL_SERVER_ONLY && !CONFIG_SSL_SKELETON_MODE + help + Determines the number of CA's allowed. + + Increase this figure if more trusted sites are allowed. Each + certificate adds about 300 bytes (when added). + + The default is to allow the Debian cert bundle to be parsed. + +config CONFIG_SSL_MAX_CERTS + int "Maximum number of chained certificates" + default 3 + help + Determines the number of certificates used in a certificate + chain. The chain length must be at least 1. + + Increase this figure if more certificates are to be added to the + chain. Each certificate adds about 300 bytes (when added). + + The default is to allow one certificate + 2 certificates in the chain. + +config CONFIG_SSL_CTX_MUTEXING + bool "Enable SSL_CTX mutexing" + default n + help + Normally mutexing is not required - each SSL_CTX object can deal with + many SSL objects (as long as each SSL_CTX object is using a single + thread). + + If the SSL_CTX object is not thread safe e.g. the case where a + new thread is created for each SSL object, then mutexing is required. + + Select y when a mutex on the SSL_CTX object is required. + +config CONFIG_USE_DEV_URANDOM + bool "Use /dev/urandom" + default y + depends on !CONFIG_PLATFORM_WIN32 + help + Use /dev/urandom. Otherwise a custom RNG is used. + + This will be the default on most Linux systems. + +config CONFIG_WIN32_USE_CRYPTO_LIB + bool "Use Win32 Crypto Library" + depends on CONFIG_PLATFORM_WIN32 + help + Microsoft produce a Crypto API which requires the Platform SDK to be + installed. It's used for the RNG. + + This will be the default on most Win32 systems. + +config CONFIG_OPENSSL_COMPATIBLE + bool "Enable openssl API compatibility" + default n + help + To ease the porting of openssl applications, a subset of the openssl + API is wrapped around the axTLS API. + + Note: not all the API is implemented, so parts may still break. And + it's definitely not 100% compatible. + +config CONFIG_PERFORMANCE_TESTING + bool "Build the bigint performance test tool" + default n + depends on CONFIG_SSL_CERT_VERIFICATION + help + Used for performance testing of bigint. + + This is a testing tool and is normally disabled. + +config CONFIG_SSL_TEST + bool "Build the SSL testing tool" + default n + depends on CONFIG_SSL_FULL_MODE && !CONFIG_SSL_GENERATE_X509_CERT + help + Used for sanity checking the SSL handshaking. + + This is a testing tool and is normally disabled. + +endmenu diff --git a/circuitpython/lib/axtls/ssl/Makefile b/circuitpython/lib/axtls/ssl/Makefile new file mode 100644 index 0000000..a222884 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/Makefile @@ -0,0 +1,125 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +AXTLS_HOME=.. + +include $(AXTLS_HOME)/config/.config +include $(AXTLS_HOME)/config/makefile.conf + +all: libs +ifdef CONFIG_PERFORMANCE_TESTING + $(MAKE) -C test +else +ifdef CONFIG_SSL_TEST + $(MAKE) -C test +endif +endif + +ifndef CONFIG_PLATFORM_WIN32 +TARGET1=$(AXTLS_HOME)/$(STAGE)/libaxtls.a +BASETARGET=libaxtls.so +CRYPTO_PATH=$(AXTLS_HOME)/crypto/ +ifdef CONFIG_PLATFORM_CYGWIN +TARGET2=$(AXTLS_HOME)/$(STAGE)/libaxtls.dll.a +else +TARGET2=$(AXTLS_HOME)/$(STAGE)/$(LIBMINOR) +endif + +# shared library major/minor numbers +LIBMAJOR=$(BASETARGET).1 +LIBMINOR=$(BASETARGET).1.2 +else +TARGET1=$(AXTLS_HOME)/$(STAGE)/axtls.lib +TARGET2=$(AXTLS_HOME)/$(STAGE)/axtls.dll +STATIC_LIB=$(AXTLS_HOME)/$(STAGE)/axtls.static.lib +CRYPTO_PATH=$(AXTLS_HOME)\\crypto\\ +endif + +libs: $(TARGET1) #$(TARGET2) + +CRYPTO_OBJ=\ + $(CRYPTO_PATH)aes.o \ + $(CRYPTO_PATH)bigint.o \ + $(CRYPTO_PATH)crypto_misc.o \ + $(CRYPTO_PATH)hmac.o \ + $(CRYPTO_PATH)md5.o \ + $(CRYPTO_PATH)rc4.o \ + $(CRYPTO_PATH)rsa.o \ + $(CRYPTO_PATH)sha1.o \ + $(CRYPTO_PATH)sha256.o \ + $(CRYPTO_PATH)sha384.o \ + $(CRYPTO_PATH)sha512.o + +OBJ=\ + asn1.o \ + gen_cert.o \ + loader.o \ + openssl.o \ + os_port.o \ + p12.o \ + tls1.o \ + tls1_svr.o \ + tls1_clnt.o \ + x509.o + +include $(AXTLS_HOME)/config/makefile.post + +ifndef CONFIG_PLATFORM_WIN32 # Linux/Unix/Cygwin + +$(TARGET1) : $(CRYPTO_OBJ) $(OBJ) + $(AR) -rcs $@ $(CRYPTO_OBJ) $(OBJ) + +$(TARGET2) : $(CRYPTO_OBJ) $(OBJ) +ifndef CONFIG_PLATFORM_CYGWIN + $(LD) $(LDFLAGS) $(LDSHARED) -Wl,-soname,$(LIBMAJOR) -o $(AXTLS_HOME)/$(STAGE)/$(LIBMINOR) $(CRYPTO_OBJ) $(OBJ) + cd $(AXTLS_HOME)/$(STAGE); ln -sf $(LIBMINOR) $(LIBMAJOR); ln -sf $(LIBMAJOR) $(BASETARGET); cd - +else + $(LD) $(LDFLAGS) $(LDSHARED) -o $(AXTLS_HOME)/$(STAGE)/cygaxtls.dll \ + -Wl,--out-implib=$(AXTLS_HOME)/$(STAGE)/libaxtls.dll.a \ + -Wl,--export-all-symbols \ + -Wl,--enable-auto-import $(CRYPTO_OBJ) $(OBJ) +endif + +else # Win32 +CRYPTO_OBJ:=$(CRYPTO_OBJ:.o=.obj) + +$(TARGET1) : $(OBJ) + $(AR) /out:$@ $(CRYPTO_OBJ) $(OBJ) + +$(TARGET2) : $(OBJ) + cp $(TARGET1) $(STATIC_LIB) + $(LD) $(LDFLAGS) $(LDSHARED) /out:$@ $(CRYPTO_OBJ) $(OBJ) + +endif + +clean:: + $(MAKE) -C test clean + -@rm -f $(AXTLS_HOME)/$(STAGE)/* *.a $(TARGET1) $(TARGET2) + diff --git a/circuitpython/lib/axtls/ssl/asn1.c b/circuitpython/lib/axtls/ssl/asn1.c new file mode 100644 index 0000000..ed28eb3 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/asn1.c @@ -0,0 +1,776 @@ +/* + * Copyright (c) 2007-2019, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Some primitive asn methods for extraction ASN.1 data. + */ + +#include +#include +#include +#include +#include "os_port.h" +#include "crypto.h" +#include "crypto_misc.h" + +/* 1.2.840.113549.1.1 OID prefix - handle the following */ +/* md5WithRSAEncryption(4) */ +/* sha1WithRSAEncryption(5) */ +/* sha256WithRSAEncryption (11) */ +/* sha384WithRSAEncryption (12) */ +/* sha512WithRSAEncryption (13) */ +static const uint8_t sig_oid_prefix[] = +{ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01 +}; + +/* 1.3.14.3.2.29 SHA1 with RSA signature */ +static const uint8_t sig_sha1WithRSAEncrypt[] = +{ + 0x2b, 0x0e, 0x03, 0x02, 0x1d +}; + +/* 2.16.840.1.101.3.4.2.1 SHA-256 */ +static const uint8_t sig_sha256[] = +{ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 +}; + +/* 2.16.840.1.101.3.4.2.2 SHA-384 */ +static const uint8_t sig_sha384[] = +{ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 +}; + +/* 2.16.840.1.101.3.4.2.3 SHA-512 */ +static const uint8_t sig_sha512[] = +{ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 +}; + +static const uint8_t sig_subject_alt_name[] = +{ + 0x55, 0x1d, 0x11 +}; + +static const uint8_t sig_basic_constraints[] = +{ + 0x55, 0x1d, 0x13 +}; + +static const uint8_t sig_key_usage[] = +{ + 0x55, 0x1d, 0x0f +}; + +/* CN, O, OU, L, C, ST */ +static const uint8_t g_dn_types[] = { 3, 10, 11, 7, 6, 8 }; + +uint32_t get_asn1_length(const uint8_t *buf, int *offset) +{ + int i; + uint32_t len; + + if (!(buf[*offset] & 0x80)) /* short form */ + { + len = buf[(*offset)++]; + } + else /* long form */ + { + int length_bytes = buf[(*offset)++]&0x7f; + if (length_bytes > 4) /* limit number of bytes */ + return 0; + + len = 0; + for (i = 0; i < length_bytes; i++) + { + len <<= 8; + len += buf[(*offset)++]; + } + } + + return len; +} + +/** + * Skip the ASN1.1 object type and its length. Get ready to read the object's + * data. + */ +int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type) +{ + if (buf[*offset] != obj_type) + return X509_NOT_OK; + + (*offset)++; + return get_asn1_length(buf, offset); +} + +/** + * Skip over an ASN.1 object type completely. Get ready to read the next + * object. + */ +int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type) +{ + int len; + + if (buf[*offset] != obj_type) + return X509_NOT_OK; + (*offset)++; + len = get_asn1_length(buf, offset); + *offset += len; + return 0; +} + +/** + * Read an integer value for ASN.1 data + * Note: This function allocates memory which must be freed by the user. + */ +int asn1_get_big_int(const uint8_t *buf, int *offset, uint8_t **object) +{ + int len; + + if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0) + goto end_big_int; + + if (len > 1 && buf[*offset] == 0x00) /* ignore the negative byte */ + { + len--; + (*offset)++; + } + + *object = (uint8_t *)malloc(len); + memcpy(*object, &buf[*offset], len); + *offset += len; + +end_big_int: + return len; +} + +/** + * Read an integer value for ASN.1 data + */ +int asn1_get_int(const uint8_t *buf, int *offset, int32_t *val) +{ + int res = X509_OK; + int len; + int i; + + if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0 || + len > sizeof(int32_t)) + { + res = X509_NOT_OK; + goto end_int; + } + + *val = 0; + for (i = 0; i < len; i++) + { + *val <<= 8; + *val |= buf[(*offset)++]; + } + +end_int: + return res; +} + +/** + * Read an boolean value for ASN.1 data + */ +int asn1_get_bool(const uint8_t *buf, int *offset, bool *val) +{ + int res = X509_OK; + + if (asn1_next_obj(buf, offset, ASN1_BOOLEAN) != 1) + { + res = X509_NOT_OK; + goto end_bool; + } + + /* DER demands that "If the encoding represents the boolean value TRUE, + its single contents octet shall have all eight bits set to one." + Thus only 0 and 255 are valid encoded values. */ + *val = buf[(*offset)++] == 0xFF; + +end_bool: + return res; +} + +/** + * Convert an ASN.1 bit string into a 32 bit integer. Used for key usage + */ +int asn1_get_bit_string_as_int(const uint8_t *buf, int *offset, uint32_t *val) +{ + int res = X509_OK; + int len, i; + + if ((len = asn1_next_obj(buf, offset, ASN1_BIT_STRING)) < 0 || len > 5) + { + res = X509_NOT_OK; + goto end_bit_string_as_int; + } + + /* number of bits left unused in the final byte of content */ + (*offset)++; + len--; + *val = 0; + + /* not sure why key usage doesn't used proper DER spec version */ + for (i = len-1; i >= 0; --i) + { + *val <<= 8; + *val |= buf[(*offset) + i]; + } + + *offset += len; + +end_bit_string_as_int: + return res; +} + +/** + * Get all the RSA private key specifics from an ASN.1 encoded file + */ +int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx) +{ + int offset = 7; + uint8_t *modulus = NULL, *priv_exp = NULL, *pub_exp = NULL; + int mod_len, priv_len, pub_len; +#ifdef CONFIG_BIGINT_CRT + uint8_t *p = NULL, *q = NULL, *dP = NULL, *dQ = NULL, *qInv = NULL; + int p_len, q_len, dP_len, dQ_len, qInv_len; +#endif + + /* not in der format */ + if (buf[0] != ASN1_SEQUENCE) /* basic sanity check */ + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: This is not a valid ASN.1 file\n"); +#endif + return X509_INVALID_PRIV_KEY; + } + + /* Use the private key to mix up the RNG if possible. */ + RNG_custom_init(buf, len); + + mod_len = asn1_get_big_int(buf, &offset, &modulus); + pub_len = asn1_get_big_int(buf, &offset, &pub_exp); + priv_len = asn1_get_big_int(buf, &offset, &priv_exp); + + if (mod_len <= 0 || pub_len <= 0 || priv_len <= 0) + return X509_INVALID_PRIV_KEY; + +#ifdef CONFIG_BIGINT_CRT + p_len = asn1_get_big_int(buf, &offset, &p); + q_len = asn1_get_big_int(buf, &offset, &q); + dP_len = asn1_get_big_int(buf, &offset, &dP); + dQ_len = asn1_get_big_int(buf, &offset, &dQ); + qInv_len = asn1_get_big_int(buf, &offset, &qInv); + + if (p_len <= 0 || q_len <= 0 || dP_len <= 0 || dQ_len <= 0 || qInv_len <= 0) + return X509_INVALID_PRIV_KEY; + + RSA_priv_key_new(rsa_ctx, + modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len, + p, p_len, q, p_len, dP, dP_len, dQ, dQ_len, qInv, qInv_len); + + free(p); + free(q); + free(dP); + free(dQ); + free(qInv); +#else + RSA_priv_key_new(rsa_ctx, + modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len); +#endif + + free(modulus); + free(priv_exp); + free(pub_exp); + return X509_OK; +} + +/** + * Get the time of a certificate. + */ +static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t) +{ + int ret = X509_NOT_OK, len, t_offset, abs_year; + struct tm tm; + + /* see http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 */ + if (buf[*offset] == ASN1_UTC_TIME) + { + (*offset)++; + + len = get_asn1_length(buf, offset); + t_offset = *offset; + + memset(&tm, 0, sizeof(struct tm)); + tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0'); + + /*if (tm.tm_year < 50) */ /* ignore 1951-2050 part of spec */ + { + tm.tm_year += 100; + } + + tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1; + tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0'); + tm.tm_hour = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0'); + tm.tm_min = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0'); + tm.tm_sec = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0'); + *t = mktime(&tm); + *offset += len; + ret = X509_OK; + } + else if (buf[*offset] == ASN1_GENERALIZED_TIME) + { + (*offset)++; + + len = get_asn1_length(buf, offset); + t_offset = *offset; + + memset(&tm, 0, sizeof(struct tm)); + abs_year = ((buf[t_offset] - '0')*1000 + + (buf[t_offset+1] - '0')*100 + (buf[t_offset+2] - '0')*10 + + (buf[t_offset+3] - '0')); + + if (abs_year <= 1901) + { + tm.tm_year = 1; + tm.tm_mon = 0; + tm.tm_mday = 1; + } + else + { + tm.tm_year = abs_year - 1900; + tm.tm_mon = (buf[t_offset+4] - '0')*10 + + (buf[t_offset+5] - '0') - 1; + tm.tm_mday = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0'); + tm.tm_hour = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0'); + tm.tm_min = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0'); + tm.tm_sec = (buf[t_offset+12] - '0')*10 + (buf[t_offset+13] - '0'); + *t = mktime(&tm); + } + + *offset += len; + ret = X509_OK; + } + + return ret; +} + +/** + * Get the version type of a certificate + */ +int asn1_version(const uint8_t *cert, int *offset, int *val) +{ + (*offset) += 2; /* get past explicit tag */ + return asn1_get_int(cert, offset, val); +} + +/** + * Retrieve the notbefore and notafter certificate times. + */ +int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) +{ + return (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || + asn1_get_utc_time(cert, offset, &x509_ctx->not_before) || + asn1_get_utc_time(cert, offset, &x509_ctx->not_after)); +} + +/** + * Get the components of a distinguished name + */ +static int asn1_get_oid_x520(const uint8_t *buf, int *offset) +{ + int dn_type = 0; + int len; + + if ((len = asn1_next_obj(buf, offset, ASN1_OID)) < 0) + goto end_oid; + + /* expect a sequence of 2.5.4.[x] where x is a one of distinguished name + components we are interested in. */ + if (len == 3 && buf[(*offset)++] == 0x55 && buf[(*offset)++] == 0x04) + dn_type = buf[(*offset)++]; + else + { + *offset += len; /* skip over it */ + } + +end_oid: + return dn_type; +} + +/** + * Obtain an ASN.1 printable string type. + */ +static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str) +{ + int len = X509_NOT_OK; + int asn1_type = buf[*offset]; + + /* some certs have this awful crud in them for some reason */ + if (asn1_type != ASN1_PRINTABLE_STR && + asn1_type != ASN1_PRINTABLE_STR2 && + asn1_type != ASN1_TELETEX_STR && + asn1_type != ASN1_IA5_STR && + asn1_type != ASN1_UNICODE_STR) + goto end_pnt_str; + + (*offset)++; + len = get_asn1_length(buf, offset); + + if (asn1_type == ASN1_UNICODE_STR) + { + int i; + *str = (char *)malloc(len/2+1); /* allow for null */ + + for (i = 0; i < len; i += 2) + (*str)[i/2] = buf[*offset + i + 1]; + + (*str)[len/2] = 0; /* null terminate */ + } + else + { + *str = (char *)malloc(len+1); /* allow for null */ + memcpy(*str, &buf[*offset], len); + (*str)[len] = 0; /* null terminate */ + } + + *offset += len; + +end_pnt_str: + return len; +} + +/** + * Get the subject name (or the issuer) of a certificate. + */ +int asn1_name(const uint8_t *cert, int *offset, char *dn[]) +{ + int ret = X509_NOT_OK; + int dn_type; + char *tmp; + + if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0) + goto end_name; + + while (asn1_next_obj(cert, offset, ASN1_SET) >= 0) + { + int i, found = 0; + + if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || + (dn_type = asn1_get_oid_x520(cert, offset)) < 0) + goto end_name; + + tmp = NULL; + + if (asn1_get_printable_str(cert, offset, &tmp) < 0) + { + free(tmp); + goto end_name; + } + + /* find the distinguished named type */ + for (i = 0; i < X509_NUM_DN_TYPES; i++) + { + if (dn_type == g_dn_types[i]) + { + if (dn[i] == NULL) + { + dn[i] = tmp; + found = 1; + break; + } + } + } + + if (found == 0) /* not found so get rid of it */ + { + free(tmp); + } + } + + ret = X509_OK; +end_name: + return ret; +} + +/** + * Read the modulus and public exponent of a certificate. + */ +int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) +{ + int ret = X509_NOT_OK, mod_len, pub_len; + uint8_t *modulus = NULL, *pub_exp = NULL; + + if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || + asn1_skip_obj(cert, offset, ASN1_SEQUENCE) || + asn1_next_obj(cert, offset, ASN1_BIT_STRING) < 0) + goto end_pub_key; + + (*offset)++; /* ignore the padding bit field */ + + if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0) + goto end_pub_key; + + mod_len = asn1_get_big_int(cert, offset, &modulus); + pub_len = asn1_get_big_int(cert, offset, &pub_exp); + + RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len); + + free(modulus); + free(pub_exp); + ret = X509_OK; + +end_pub_key: + return ret; +} + +#ifdef CONFIG_SSL_CERT_VERIFICATION +/** + * Read the signature of the certificate. + */ +int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) +{ + int ret = X509_NOT_OK; + + if (cert[(*offset)++] != ASN1_BIT_STRING) + goto end_sig; + + x509_ctx->sig_len = get_asn1_length(cert, offset)-1; + (*offset)++; /* ignore bit string padding bits */ + x509_ctx->signature = (uint8_t *)malloc(x509_ctx->sig_len); + memcpy(x509_ctx->signature, &cert[*offset], x509_ctx->sig_len); + *offset += x509_ctx->sig_len; + ret = X509_OK; + +end_sig: + return ret; +} + +/* + * Compare 2 distinguished name components for equality + * @return 0 if a match + */ +static int asn1_compare_dn_comp(const char *dn1, const char *dn2) +{ + int ret; + + if (dn1 == NULL && dn2 == NULL) + ret = 0; + else + ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 1; + + return ret; +} + +/** + * Clean up all of the CA certificates. + */ +void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx) +{ + int i = 0; + + if (ca_cert_ctx == NULL) + return; + + while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) + { + x509_free(ca_cert_ctx->cert[i]); + ca_cert_ctx->cert[i++] = NULL; + } + + free(ca_cert_ctx); +} + +/* + * Compare 2 distinguished names for equality + * @return 0 if a match + */ +int asn1_compare_dn(char * const dn1[], char * const dn2[]) +{ + int i; + + for (i = 0; i < X509_NUM_DN_TYPES; i++) + { + if (asn1_compare_dn_comp(dn1[i], dn2[i])) + return 1; + } + + return 0; /* all good */ +} + +int asn1_find_oid(const uint8_t* cert, int* offset, + const uint8_t* oid, int oid_length) +{ + int seqlen; + if ((seqlen = asn1_next_obj(cert, offset, ASN1_SEQUENCE))> 0) + { + int end = *offset + seqlen; + + while (*offset < end) + { + int type = cert[(*offset)++]; + int length = get_asn1_length(cert, offset); + int noffset = *offset + length; + + if (type == ASN1_SEQUENCE) + { + type = cert[(*offset)++]; + length = get_asn1_length(cert, offset); + + if (type == ASN1_OID && length == oid_length && + memcmp(cert + *offset, oid, oid_length) == 0) + { + *offset += oid_length; + return 1; + } + } + + *offset = noffset; + } + } + + return 0; +} + +int asn1_is_subject_alt_name(const uint8_t *cert, int offset) +{ + if (asn1_find_oid(cert, &offset, sig_subject_alt_name, + sizeof(sig_subject_alt_name))) + { + return offset; + } + + return 0; +} + +int asn1_is_basic_constraints(const uint8_t *cert, int offset) +{ + if (asn1_find_oid(cert, &offset, sig_basic_constraints, + sizeof(sig_basic_constraints))) + { + return offset; + } + + return 0; +} + +int asn1_is_key_usage(const uint8_t *cert, int offset) +{ + if (asn1_find_oid(cert, &offset, sig_key_usage, + sizeof(sig_key_usage))) + { + return offset; + } + + return 0; +} + +bool asn1_is_critical_ext(const uint8_t *buf, int *offset) +{ + /* critical is optional */ + bool res = false; + + if (asn1_next_obj(buf, offset, ASN1_BOOLEAN) == 1) + res = buf[(*offset)++] == 0xFF; + + return res; +} + +#endif /* CONFIG_SSL_CERT_VERIFICATION */ + +/** + * Read the signature type of the certificate. We only support RSA-MD5 and + * RSA-SHA1 signature types. + */ +int asn1_signature_type(const uint8_t *cert, + int *offset, X509_CTX *x509_ctx) +{ + int ret = X509_NOT_OK, len; + + if (cert[(*offset)++] != ASN1_OID) + goto end_check_sig; + + len = get_asn1_length(cert, offset); + + if (len == sizeof(sig_sha1WithRSAEncrypt) && + memcmp(sig_sha1WithRSAEncrypt, &cert[*offset], + sizeof(sig_sha1WithRSAEncrypt)) == 0) + { + x509_ctx->sig_type = SIG_TYPE_SHA1; + } + else if (len == sizeof(sig_sha256) && + memcmp(sig_sha256, &cert[*offset], + sizeof(sig_sha256)) == 0) + { + x509_ctx->sig_type = SIG_TYPE_SHA256; + } + else if (len == sizeof(sig_sha384) && + memcmp(sig_sha384, &cert[*offset], + sizeof(sig_sha384)) == 0) + { + x509_ctx->sig_type = SIG_TYPE_SHA384; + } + else if (len == sizeof(sig_sha512) && + memcmp(sig_sha512, &cert[*offset], + sizeof(sig_sha512)) == 0) + { + x509_ctx->sig_type = SIG_TYPE_SHA512; + } + else + { + if (memcmp(sig_oid_prefix, &cert[*offset], sizeof(sig_oid_prefix))) + { +#ifdef CONFIG_SSL_FULL_MODE + int i; + printf("invalid digest: "); + + for (i = 0; i < len; i++) + printf("%02x ", cert[*offset + i]); + + printf("\n"); +#endif + goto end_check_sig; /* unrecognised cert type */ + } + + x509_ctx->sig_type = cert[*offset + sizeof(sig_oid_prefix)]; + } + + *offset += len; + asn1_skip_obj(cert, offset, ASN1_NULL); /* if it's there */ + ret = X509_OK; + +end_check_sig: + return ret; +} + diff --git a/circuitpython/lib/axtls/ssl/cert.h b/circuitpython/lib/axtls/ssl/cert.h new file mode 100644 index 0000000..40234b9 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/cert.h @@ -0,0 +1,54 @@ +unsigned char default_certificate[] = { + 0x30, 0x82, 0x02, 0x58, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xa5, + 0x2a, 0xc8, 0x78, 0x87, 0xf2, 0xe7, 0xc5, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, + 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61, + 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x32, + 0x33, 0x30, 0x32, 0x31, 0x30, 0x34, 0x32, 0x37, 0x5a, 0x17, 0x0d, 0x33, + 0x30, 0x30, 0x39, 0x30, 0x38, 0x32, 0x31, 0x30, 0x34, 0x32, 0x37, 0x5a, + 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0d, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x81, + 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, + 0x81, 0x81, 0x00, 0xbd, 0x0f, 0xd4, 0x42, 0xa8, 0x74, 0x87, 0x54, 0xaa, + 0xb9, 0x3a, 0x1f, 0x8b, 0xce, 0xbd, 0xb7, 0x65, 0xfb, 0x40, 0x3d, 0xd0, + 0x11, 0x9a, 0x9c, 0xdc, 0x82, 0x7c, 0xea, 0xa8, 0x17, 0xe1, 0x74, 0xf3, + 0x05, 0x0e, 0x61, 0xc1, 0xc1, 0x78, 0x8a, 0xb2, 0xba, 0x15, 0x22, 0x5a, + 0xff, 0x9b, 0xb8, 0x7a, 0x2e, 0x0f, 0x88, 0xb7, 0x74, 0xde, 0x04, 0x99, + 0xa5, 0xa2, 0x99, 0x53, 0x8b, 0xad, 0x78, 0x5a, 0x31, 0xed, 0xbc, 0x01, + 0xe7, 0xdf, 0xe9, 0xec, 0x2f, 0xa0, 0x5d, 0x53, 0xf6, 0xe6, 0x8a, 0xa0, + 0xc8, 0x6d, 0x41, 0x45, 0x63, 0x23, 0xb3, 0xcf, 0x4e, 0x50, 0x1f, 0x28, + 0xdf, 0x36, 0xe2, 0x73, 0xdf, 0xd6, 0xa1, 0xb3, 0x46, 0x4f, 0x6e, 0xbb, + 0x0d, 0x9b, 0xef, 0xa8, 0xf9, 0x4c, 0xa5, 0x71, 0xa1, 0x88, 0xdd, 0x07, + 0xa9, 0x86, 0x0d, 0x3f, 0xcd, 0x99, 0x23, 0xa2, 0x84, 0x77, 0x0f, 0x02, + 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x32, 0xe0, 0x3c, 0x6e, 0x21, 0xe6, 0xa6, 0xf4, 0xb8, 0x10, 0x9f, 0x8a, + 0xe6, 0x0b, 0x84, 0x4e, 0x2c, 0xe5, 0x14, 0xca, 0x56, 0x81, 0x3f, 0xc0, + 0x2c, 0xa3, 0x39, 0x89, 0x24, 0xce, 0xaf, 0x47, 0x2e, 0x19, 0x62, 0xb2, + 0xe4, 0x76, 0x91, 0x25, 0xbc, 0xe1, 0xa8, 0xee, 0x6a, 0x68, 0x3a, 0x77, + 0xb9, 0xb2, 0x62, 0x97, 0x0c, 0x25, 0x3c, 0x5e, 0x13, 0x48, 0x87, 0x80, + 0xa3, 0x91, 0xd9, 0x2e, 0xe6, 0x92, 0x2b, 0x1c, 0x52, 0x24, 0xb1, 0x77, + 0xc6, 0xf6, 0xde, 0xd8, 0x9b, 0xd9, 0x57, 0x37, 0x56, 0x68, 0x17, 0x32, + 0x66, 0x01, 0x08, 0x38, 0x08, 0x9a, 0xc1, 0x8c, 0x5e, 0x3f, 0xe7, 0xc9, + 0x44, 0xcb, 0x62, 0xb9, 0x48, 0xc7, 0x89, 0xa6, 0xff, 0x8e, 0x7d, 0x3d, + 0xe1, 0x46, 0x32, 0x9c, 0x13, 0x06, 0x9a, 0xd1, 0x17, 0xab, 0x3f, 0xa9, + 0x90, 0x04, 0x33, 0x2d, 0x3f, 0x81, 0x0a, 0xa5, 0x55, 0xce, 0xb6, 0x95, + 0x54, 0xad, 0xf1, 0x4f, 0xa2, 0xca, 0xc3, 0xf6, 0x25, 0x7b, 0x71, 0xd2, + 0x68, 0x85, 0xe9, 0x72, 0xb6, 0x99, 0x34, 0x6d, 0xe5, 0x5f, 0xf6, 0x74, + 0x1c, 0xb9, 0xa2, 0xda, 0x2b, 0x04, 0xff, 0x82, 0xc5, 0x09, 0x04, 0xc4, + 0xba, 0xbc, 0x82, 0x3e, 0xb4, 0x72, 0x18, 0x8e, 0x30, 0x68, 0x48, 0x4a, + 0x0d, 0xa7, 0x3d, 0xb5, 0xf4, 0x42, 0x3a, 0x97, 0x60, 0x7d, 0xa8, 0x61, + 0x8a, 0x9e, 0x98, 0xc4, 0x7e, 0x65, 0x99, 0xea, 0x7e, 0xca, 0x75, 0xe7, + 0xdb, 0x21, 0x5d, 0xce, 0x7c, 0x66, 0x3d, 0x7e, 0xdc, 0x14, 0xfe, 0x55, + 0x04, 0x97, 0xa8, 0x64, 0x12, 0xb4, 0xb5, 0x30, 0x48, 0x72, 0xbc, 0xdb, + 0xeb, 0x5b, 0x4f, 0xa6, 0xfb, 0x87, 0x01, 0x41, 0x91, 0xec, 0x98, 0x98, + 0xf1, 0x4b, 0x38, 0xa2, 0x40, 0xf1, 0x05, 0x90, 0xbb, 0x9b, 0x5d, 0x96, + 0xb1, 0x22, 0x6b, 0x50 +}; +unsigned int default_certificate_len = 604; diff --git a/circuitpython/lib/axtls/ssl/crypto_misc.h b/circuitpython/lib/axtls/ssl/crypto_misc.h new file mode 100644 index 0000000..21b59cb --- /dev/null +++ b/circuitpython/lib/axtls/ssl/crypto_misc.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2007-2017, Cameron Rich + * + * 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 axTLS project 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. +*/ + +/** + * @file crypto_misc.h + */ + +#ifndef HEADER_CRYPTO_MISC_H +#define HEADER_CRYPTO_MISC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "crypto.h" +#include "bigint.h" + +/************************************************************************** + * X509 declarations + **************************************************************************/ +#define X509_OK 0 +#define X509_NOT_OK -1 +#define X509_VFY_ERROR_NO_TRUSTED_CERT -2 +#define X509_VFY_ERROR_BAD_SIGNATURE -3 +#define X509_VFY_ERROR_NOT_YET_VALID -4 +#define X509_VFY_ERROR_EXPIRED -5 +#define X509_VFY_ERROR_SELF_SIGNED -6 +#define X509_VFY_ERROR_INVALID_CHAIN -7 +#define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8 +#define X509_INVALID_PRIV_KEY -9 +#define X509_MAX_CERTS -10 +#define X509_VFY_ERROR_BASIC_CONSTRAINT -11 + +/* + * The Distinguished Name + */ +#define X509_NUM_DN_TYPES 6 +#define X509_COMMON_NAME 0 +#define X509_ORGANIZATION 1 +#define X509_ORGANIZATIONAL_UNIT 2 +#define X509_LOCATION 3 +#define X509_COUNTRY 4 +#define X509_STATE 5 + +/* + * Key Usage bits + */ +#define IS_SET_KEY_USAGE_FLAG(A, B) (A->key_usage & B) + +#define KEY_USAGE_DIGITAL_SIGNATURE 0x0080 +#define KEY_USAGE_NON_REPUDIATION 0x0040 +#define KEY_USAGE_KEY_ENCIPHERMENT 0x0020 +#define KEY_USAGE_DATA_ENCIPHERMENT 0x0010 +#define KEY_USAGE_KEY_AGREEMENT 0x0008 +#define KEY_USAGE_KEY_CERT_SIGN 0x0004 +#define KEY_USAGE_CRL_SIGN 0x0002 +#define KEY_USAGE_ENCIPHER_ONLY 0x0001 +#define KEY_USAGE_DECIPHER_ONLY 0x8000 + +struct _x509_ctx +{ + char *ca_cert_dn[X509_NUM_DN_TYPES]; + char *cert_dn[X509_NUM_DN_TYPES]; + char **subject_alt_dnsnames; + time_t not_before; + time_t not_after; + uint8_t *signature; + RSA_CTX *rsa_ctx; + bigint *digest; + uint16_t sig_len; + uint8_t sig_type; + bool basic_constraint_present; + bool basic_constraint_is_critical; + bool key_usage_present; + bool key_usage_is_critical; + bool subject_alt_name_present; + bool subject_alt_name_is_critical; + bool basic_constraint_cA; + int basic_constraint_pathLenConstraint; + uint32_t key_usage; + struct _x509_ctx *next; +}; + +typedef struct _x509_ctx X509_CTX; + +//#ifdef CONFIG_SSL_CERT_VERIFICATION +typedef struct +{ + X509_CTX *cert[CONFIG_X509_MAX_CA_CERTS]; +} CA_CERT_CTX; +//#endif + +int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx); +void x509_free(X509_CTX *x509_ctx); +//#ifdef CONFIG_SSL_CERT_VERIFICATION +int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert, + int *pathLenConstraint); +//#endif +//#ifdef CONFIG_SSL_FULL_MODE +void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx); +const char * x509_display_error(int error); +//#endif + +/************************************************************************** + * ASN1 declarations + **************************************************************************/ +#define ASN1_BOOLEAN 0x01 +#define ASN1_INTEGER 0x02 +#define ASN1_BIT_STRING 0x03 +#define ASN1_OCTET_STRING 0x04 +#define ASN1_NULL 0x05 +#define ASN1_PRINTABLE_STR2 0x0C +#define ASN1_OID 0x06 +#define ASN1_PRINTABLE_STR2 0x0C +#define ASN1_PRINTABLE_STR 0x13 +#define ASN1_TELETEX_STR 0x14 +#define ASN1_IA5_STR 0x16 +#define ASN1_UTC_TIME 0x17 +#define ASN1_GENERALIZED_TIME 0x18 +#define ASN1_UNICODE_STR 0x1e +#define ASN1_SEQUENCE 0x30 +#define ASN1_CONTEXT_DNSNAME 0x82 +#define ASN1_SET 0x31 +#define ASN1_V3_DATA 0xa3 +#define ASN1_IMPLICIT_TAG 0x80 +#define ASN1_CONTEXT_DNSNAME 0x82 +#define ASN1_EXPLICIT_TAG 0xa0 +#define ASN1_V3_DATA 0xa3 + +#define SIG_TYPE_MD5 0x04 +#define SIG_TYPE_SHA1 0x05 +#define SIG_TYPE_SHA256 0x0b +#define SIG_TYPE_SHA384 0x0c +#define SIG_TYPE_SHA512 0x0d + +uint32_t get_asn1_length(const uint8_t *buf, int *offset); +int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx); +int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type); +int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type); +int asn1_get_big_int(const uint8_t *buf, int *offset, uint8_t **object); +int asn1_get_int(const uint8_t *buf, int *offset, int32_t *val); +int asn1_get_bool(const uint8_t *buf, int *offset, bool *val); +int asn1_get_bit_string_as_int(const uint8_t *buf, int *offset, uint32_t *val); +int asn1_version(const uint8_t *cert, int *offset, int *val); +int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx); +int asn1_name(const uint8_t *cert, int *offset, char *dn[]); +int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx); +#ifdef CONFIG_SSL_CERT_VERIFICATION +int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx); +int asn1_compare_dn(char * const dn1[], char * const dn2[]); +int asn1_is_subject_alt_name(const uint8_t *cert, int offset); +int asn1_is_basic_constraints(const uint8_t *cert, int offset); +int asn1_is_key_usage(const uint8_t *cert, int offset); +bool asn1_is_critical_ext(const uint8_t *buf, int *offset); +#endif /* CONFIG_SSL_CERT_VERIFICATION */ +int asn1_signature_type(const uint8_t *cert, + int *offset, X509_CTX *x509_ctx); + +/************************************************************************** + * MISC declarations + **************************************************************************/ +#define SALT_SIZE 8 + +extern const char * const unsupported_str; + +typedef void (*crypt_func)(void *, const uint8_t *, uint8_t *, int); +typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key, + int key_len, uint8_t *digest); + +int get_file(const char *filename, uint8_t **buf); + +#if defined(CONFIG_SSL_DIAGNOSTICS) || defined(WIN32) || defined(CONFIG_DEBUG) +EXP_FUNC void STDCALL print_blob(const char *format, const uint8_t *data, int size, ...); +#else + #define print_blob(...) +#endif + +EXP_FUNC int STDCALL base64_decode(const char *in, int len, + uint8_t *out, int *outlen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/axtls/ssl/gen_cert.c b/circuitpython/lib/axtls/ssl/gen_cert.c new file mode 100644 index 0000000..17ad38e --- /dev/null +++ b/circuitpython/lib/axtls/ssl/gen_cert.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2007-2014, Cameron Rich + * + * 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 axTLS project 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 "config.h" + +#ifdef CONFIG_SSL_GENERATE_X509_CERT +#include +#include +#include "os_port.h" +#include "ssl.h" + +/** + * Generate a basic X.509 certificate + */ + +static uint8_t set_gen_length(int len, uint8_t *buf, int *offset) +{ + if (len < 0x80) /* short form */ + { + buf[(*offset)++] = len; + return 1; + } + else /* long form */ + { + int i, length_bytes = 0; + + if (len & 0x00FF0000) + length_bytes = 3; + else if (len & 0x0000FF00) + length_bytes = 2; + else if (len & 0x000000FF) + length_bytes = 1; + + buf[(*offset)++] = 0x80 + length_bytes; + + for (i = length_bytes-1; i >= 0; i--) + { + buf[*offset+i] = len & 0xFF; + len >>= 8; + } + + *offset += length_bytes; + return length_bytes+1; + } +} + +static int pre_adjust_with_size(uint8_t type, + int *seq_offset, uint8_t *buf, int *offset) +{ + buf[(*offset)++] = type; + *seq_offset = *offset; + *offset += 4; /* fill in later */ + return *offset; +} + +static void adjust_with_size(int seq_size, int seq_start, + uint8_t *buf, int *offset) +{ + uint8_t seq_byte_size; + int orig_seq_size = seq_size; + int orig_seq_start = seq_start; + + seq_size = *offset-seq_size; + seq_byte_size = set_gen_length(seq_size, buf, &seq_start); + + if (seq_byte_size != 4) + { + memmove(&buf[orig_seq_start+seq_byte_size], + &buf[orig_seq_size], seq_size); + *offset -= 4-seq_byte_size; + } +} + +static void gen_serial_number(uint8_t *buf, int *offset) +{ + static const uint8_t ser_oid[] = { ASN1_INTEGER, 1, 0x7F }; + memcpy(&buf[*offset], ser_oid , sizeof(ser_oid)); + *offset += sizeof(ser_oid); +} + +static void gen_signature_alg(uint8_t *buf, int *offset) +{ + /* OBJECT IDENTIFIER sha1withRSAEncryption (1 2 840 113549 1 1 5) */ + static const uint8_t sig_oid[] = + { + ASN1_SEQUENCE, 0x0d, ASN1_OID, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + ASN1_NULL, 0x00 + }; + + memcpy(&buf[*offset], sig_oid, sizeof(sig_oid)); + *offset += sizeof(sig_oid); +} + +static int gen_dn(const char *name, uint8_t dn_type, + uint8_t *buf, int *offset) +{ + int ret = X509_OK; + int name_size = strlen(name); + + if (name_size > 0x70) /* just too big */ + { + ret = X509_NOT_OK; + goto error; + } + + buf[(*offset)++] = ASN1_SET; + set_gen_length(9+name_size, buf, offset); + buf[(*offset)++] = ASN1_SEQUENCE; + set_gen_length(7+name_size, buf, offset); + buf[(*offset)++] = ASN1_OID; + buf[(*offset)++] = 3; + buf[(*offset)++] = 0x55; + buf[(*offset)++] = 0x04; + buf[(*offset)++] = dn_type; + buf[(*offset)++] = ASN1_PRINTABLE_STR; + buf[(*offset)++] = name_size; + strcpy((char *)&buf[*offset], name); + *offset += name_size; + +error: + return ret; +} + +static int gen_issuer(const char * dn[], uint8_t *buf, int *offset) +{ + int ret = X509_OK; + int seq_offset; + int seq_size = pre_adjust_with_size( + ASN1_SEQUENCE, &seq_offset, buf, offset); + char fqdn[128]; + + /* we need the common name, so if not configured, work out the fully + * qualified domain name */ + if (dn[X509_COMMON_NAME] == NULL || strlen(dn[X509_COMMON_NAME]) == 0) + { + int fqdn_len; + gethostname(fqdn, sizeof(fqdn)); + fqdn_len = strlen(fqdn); + fqdn[fqdn_len++] = '.'; + + if (getdomainname(&fqdn[fqdn_len], sizeof(fqdn)-fqdn_len) < 0) + { + ret = X509_NOT_OK; + goto error; + } + + fqdn_len = strlen(fqdn); + + if (fqdn[fqdn_len-1] == '.') /* ensure '.' is not last char */ + fqdn[fqdn_len-1] = 0; + + dn[X509_COMMON_NAME] = fqdn; + } + + if ((ret = gen_dn(dn[X509_COMMON_NAME], 3, buf, offset))) + goto error; + + if (dn[X509_ORGANIZATION] != NULL && strlen(dn[X509_ORGANIZATION]) > 0) + { + if ((ret = gen_dn(dn[X509_ORGANIZATION], 10, buf, offset))) + goto error; + } + + if (dn[X509_ORGANIZATIONAL_UNIT] != NULL && + strlen(dn[X509_ORGANIZATIONAL_UNIT]) > 0) + { + if ((ret = gen_dn(dn[X509_ORGANIZATIONAL_UNIT], 11, buf, offset))) + goto error; + } + + adjust_with_size(seq_size, seq_offset, buf, offset); + +error: + return ret; +} + +static void gen_utc_time(uint8_t *buf, int *offset) +{ + static const uint8_t time_seq[] = + { + ASN1_SEQUENCE, 30, + ASN1_UTC_TIME, 13, + '0', '7', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z', + ASN1_UTC_TIME, 13, /* make it good for 30 or so years */ + '3', '8', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z' + }; + + /* fixed time */ + memcpy(&buf[*offset], time_seq, sizeof(time_seq)); + *offset += sizeof(time_seq); +} + +static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset) +{ + static const uint8_t pub_key_seq[] = + { + ASN1_INTEGER, 0x03, 0x01, 0x00, 0x01 /* INTEGER 65537 */ + }; + + int seq_offset; + int pub_key_size = rsa_ctx->num_octets; + uint8_t *block = (uint8_t *)alloca(pub_key_size); + int seq_size = pre_adjust_with_size( + ASN1_SEQUENCE, &seq_offset, buf, offset); + buf[(*offset)++] = ASN1_INTEGER; + bi_export(rsa_ctx->bi_ctx, rsa_ctx->m, block, pub_key_size); + + if (*block & 0x80) /* make integer positive */ + { + set_gen_length(pub_key_size+1, buf, offset); + buf[(*offset)++] = 0; + } + else + set_gen_length(pub_key_size, buf, offset); + + memcpy(&buf[*offset], block, pub_key_size); + *offset += pub_key_size; + memcpy(&buf[*offset], pub_key_seq, sizeof(pub_key_seq)); + *offset += sizeof(pub_key_seq); + adjust_with_size(seq_size, seq_offset, buf, offset); +} + +static void gen_pub_key1(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset) +{ + int seq_offset; + int seq_size = pre_adjust_with_size( + ASN1_BIT_STRING, &seq_offset, buf, offset); + buf[(*offset)++] = 0; /* bit string is multiple of 8 */ + gen_pub_key2(rsa_ctx, buf, offset); + adjust_with_size(seq_size, seq_offset, buf, offset); +} + +static void gen_pub_key(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset) +{ + /* OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) */ + static const uint8_t rsa_enc_oid[] = + { + ASN1_SEQUENCE, 0x0d, ASN1_OID, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + ASN1_NULL, 0x00 + }; + + int seq_offset; + int seq_size = pre_adjust_with_size( + ASN1_SEQUENCE, &seq_offset, buf, offset); + + memcpy(&buf[*offset], rsa_enc_oid, sizeof(rsa_enc_oid)); + *offset += sizeof(rsa_enc_oid); + gen_pub_key1(rsa_ctx, buf, offset); + adjust_with_size(seq_size, seq_offset, buf, offset); +} + +static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst, + uint8_t *buf, int *offset) +{ + static const uint8_t asn1_sig[] = + { + ASN1_SEQUENCE, 0x21, ASN1_SEQUENCE, 0x09, ASN1_OID, 0x05, + 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* sha1 (1 3 14 3 2 26) */ + ASN1_NULL, 0x00, ASN1_OCTET_STRING, 0x14 + }; + + uint8_t *enc_block = (uint8_t *)alloca(rsa_ctx->num_octets); + uint8_t *block = (uint8_t *)alloca(sizeof(asn1_sig) + SHA1_SIZE); + int sig_size; + + /* add the digest as an embedded asn.1 sequence */ + memcpy(block, asn1_sig, sizeof(asn1_sig)); + memcpy(&block[sizeof(asn1_sig)], sha_dgst, SHA1_SIZE); + + sig_size = RSA_encrypt(rsa_ctx, block, + sizeof(asn1_sig) + SHA1_SIZE, enc_block, 1); + + buf[(*offset)++] = ASN1_BIT_STRING; + set_gen_length(sig_size+1, buf, offset); + buf[(*offset)++] = 0; /* bit string is multiple of 8 */ + memcpy(&buf[*offset], enc_block, sig_size); + *offset += sig_size; +} + +static int gen_tbs_cert(const char * dn[], + const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset, + uint8_t *sha_dgst) +{ + int ret = X509_OK; + SHA1_CTX sha_ctx; + int seq_offset; + int begin_tbs = *offset; + int seq_size = pre_adjust_with_size( + ASN1_SEQUENCE, &seq_offset, buf, offset); + + gen_serial_number(buf, offset); + gen_signature_alg(buf, offset); + + /* CA certicate issuer */ + if ((ret = gen_issuer(dn, buf, offset))) + goto error; + + gen_utc_time(buf, offset); + + /* certificate issuer */ + if ((ret = gen_issuer(dn, buf, offset))) + goto error; + + gen_pub_key(rsa_ctx, buf, offset); + adjust_with_size(seq_size, seq_offset, buf, offset); + + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, &buf[begin_tbs], *offset-begin_tbs); + SHA1_Final(sha_dgst, &sha_ctx); + +error: + return ret; +} + +/** + * Create a new certificate. + */ +EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data) +{ + int ret = X509_OK, offset = 0, seq_offset; + /* allocate enough space to load a new certificate */ + uint8_t *buf = (uint8_t *)alloca(ssl_ctx->rsa_ctx->num_octets*2 + 512); + uint8_t sha_dgst[SHA1_SIZE]; + int seq_size = pre_adjust_with_size(ASN1_SEQUENCE, + &seq_offset, buf, &offset); + + if ((ret = gen_tbs_cert(dn, ssl_ctx->rsa_ctx, buf, &offset, sha_dgst)) < 0) + goto error; + + gen_signature_alg(buf, &offset); + gen_signature(ssl_ctx->rsa_ctx, sha_dgst, buf, &offset); + adjust_with_size(seq_size, seq_offset, buf, &offset); + *cert_data = (uint8_t *)malloc(offset); /* create the exact memory for it */ + memcpy(*cert_data, buf, offset); + +error: + return ret < 0 ? ret : offset; +} + +#endif + diff --git a/circuitpython/lib/axtls/ssl/loader.c b/circuitpython/lib/axtls/ssl/loader.c new file mode 100644 index 0000000..38ed0bf --- /dev/null +++ b/circuitpython/lib/axtls/ssl/loader.c @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2007-2014, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Load certificates/keys into memory. These can be in many different formats. + * PEM support and other formats can be processed here. + * + * The PEM private keys may be optionally encrypted with AES128 or AES256. + * The encrypted PEM keys were generated with something like: + * + * openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 512 + */ + +#include +#include +#include +#include "os_port.h" +#include "ssl.h" + +#if CONFIG_SSL_ENABLE_SERVER + +static int do_obj(SSL_CTX *ssl_ctx, int obj_type, + SSLObjLoader *ssl_obj, const char *password); +#ifdef CONFIG_SSL_HAS_PEM +static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type, + SSLObjLoader *ssl_obj, const char *password); +#endif + +/* + * Load a file into memory that is in binary DER (or ascii PEM) format. + */ +EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, + const char *filename, const char *password) +{ +#ifndef CONFIG_SSL_SKELETON_MODE + static const char * const begin = "-----BEGIN"; + int ret = SSL_OK; + SSLObjLoader *ssl_obj = NULL; + + if (filename == NULL) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + + ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader)); + ssl_obj->len = get_file(filename, &ssl_obj->buf); + if (ssl_obj->len <= 0) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + + /* is the file a PEM file? */ + if (strstr((char *)ssl_obj->buf, begin) != NULL) + { +#ifdef CONFIG_SSL_HAS_PEM + ret = ssl_obj_PEM_load(ssl_ctx, obj_type, ssl_obj, password); +#else +#ifdef CONFIG_SSL_FULL_MODE + printf("%s", unsupported_str); +#endif + ret = SSL_ERROR_NOT_SUPPORTED; +#endif + } + else + ret = do_obj(ssl_ctx, obj_type, ssl_obj, password); + +error: + ssl_obj_free(ssl_obj); + return ret; +#else +#ifdef CONFIG_SSL_FULL_MODE + printf("%s", unsupported_str); +#endif + return SSL_ERROR_NOT_SUPPORTED; +#endif /* CONFIG_SSL_SKELETON_MODE */ +} + +/* + * Transfer binary data into the object loader. + */ +EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int mem_type, + const uint8_t *data, int len, const char *password) +{ + int ret; + SSLObjLoader *ssl_obj; + + ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader)); + ssl_obj->buf = (uint8_t *)malloc(len); + memcpy(ssl_obj->buf, data, len); + ssl_obj->len = len; + ret = do_obj(ssl_ctx, mem_type, ssl_obj, password); + ssl_obj_free(ssl_obj); + return ret; +} + +/* + * Actually work out what we are doing + */ +static int do_obj(SSL_CTX *ssl_ctx, int obj_type, + SSLObjLoader *ssl_obj, const char *password) +{ + int ret = SSL_OK; + + switch (obj_type) + { + case SSL_OBJ_RSA_KEY: + ret = add_private_key(ssl_ctx, ssl_obj); + break; + + case SSL_OBJ_X509_CERT: + ret = add_cert(ssl_ctx, ssl_obj->buf, ssl_obj->len); + break; + +#ifdef CONFIG_SSL_CERT_VERIFICATION + case SSL_OBJ_X509_CACERT: + add_cert_auth(ssl_ctx, ssl_obj->buf, ssl_obj->len); + break; +#endif + +#ifdef CONFIG_SSL_USE_PKCS12 + case SSL_OBJ_PKCS8: + ret = pkcs8_decode(ssl_ctx, ssl_obj, password); + break; + + case SSL_OBJ_PKCS12: + ret = pkcs12_decode(ssl_ctx, ssl_obj, password); + break; +#endif + default: +#ifdef CONFIG_SSL_FULL_MODE + printf("%s", unsupported_str); +#endif + ret = SSL_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +/* + * Clean up our mess. + */ +void ssl_obj_free(SSLObjLoader *ssl_obj) +{ + if (ssl_obj) + { + free(ssl_obj->buf); + free(ssl_obj); + } +} + +/* + * Support for PEM encoded keys/certificates. + */ +#ifdef CONFIG_SSL_HAS_PEM + +#define NUM_PEM_TYPES 4 +#define IV_SIZE 16 +#define IS_RSA_PRIVATE_KEY 0 +#define IS_ENCRYPTED_PRIVATE_KEY 1 +#define IS_PRIVATE_KEY 2 +#define IS_CERTIFICATE 3 + +static const char * const begins[NUM_PEM_TYPES] = +{ + "-----BEGIN RSA PRIVATE KEY-----", + "-----BEGIN ENCRYPTED PRIVATE KEY-----", + "-----BEGIN PRIVATE KEY-----", + "-----BEGIN CERTIFICATE-----", +}; + +static const char * const ends[NUM_PEM_TYPES] = +{ + "-----END RSA PRIVATE KEY-----", + "-----END ENCRYPTED PRIVATE KEY-----", + "-----END PRIVATE KEY-----", + "-----END CERTIFICATE-----", +}; + +static const char * const aes_str[2] = +{ + "DEK-Info: AES-128-CBC,", + "DEK-Info: AES-256-CBC," +}; + +/** + * Take a base64 blob of data and decrypt it (using AES) into its + * proper ASN.1 form. + */ +static int pem_decrypt(const char *where, const char *end, + const char *password, SSLObjLoader *ssl_obj) +{ + int ret = -1; + int is_aes_256 = 0; + char *start = NULL; + uint8_t iv[IV_SIZE]; + int i, pem_size; + MD5_CTX md5_ctx; + AES_CTX aes_ctx; + uint8_t key[32]; /* AES256 size */ + + if (password == NULL || strlen(password) == 0) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: Need a password for this PEM file\n"); +#endif + goto error; + } + + if ((start = strstr((const char *)where, aes_str[0]))) /* AES128? */ + { + start += strlen(aes_str[0]); + } + else if ((start = strstr((const char *)where, aes_str[1]))) /* AES256? */ + { + is_aes_256 = 1; + start += strlen(aes_str[1]); + } + else + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: Unsupported password cipher\n"); +#endif + goto error; + } + + /* convert from hex to binary - assumes uppercase hex */ + for (i = 0; i < IV_SIZE; i++) + { + char c = *start++ - '0'; + iv[i] = (c > 9 ? c + '0' - 'A' + 10 : c) << 4; + c = *start++ - '0'; + iv[i] += (c > 9 ? c + '0' - 'A' + 10 : c); + } + + while (*start == '\r' || *start == '\n') + start++; + + /* turn base64 into binary */ + pem_size = (int)(end-start); + if (base64_decode(start, pem_size, ssl_obj->buf, &ssl_obj->len) != 0) + goto error; + + /* work out the key */ + MD5_Init(&md5_ctx); + MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password)); + MD5_Update(&md5_ctx, iv, SALT_SIZE); + MD5_Final(key, &md5_ctx); + + if (is_aes_256) + { + MD5_Init(&md5_ctx); + MD5_Update(&md5_ctx, key, MD5_SIZE); + MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password)); + MD5_Update(&md5_ctx, iv, SALT_SIZE); + MD5_Final(&key[MD5_SIZE], &md5_ctx); + } + + /* decrypt using the key/iv */ + AES_set_key(&aes_ctx, key, iv, is_aes_256 ? AES_MODE_256 : AES_MODE_128); + AES_convert_key(&aes_ctx); + AES_cbc_decrypt(&aes_ctx, ssl_obj->buf, ssl_obj->buf, ssl_obj->len); + ret = 0; + +error: + return ret; +} + +/** + * Take a base64 blob of data and turn it into its proper ASN.1 form. + */ +static int new_pem_obj(SSL_CTX *ssl_ctx, int is_cacert, char *where, + int remain, const char *password) +{ + int ret = SSL_ERROR_BAD_CERTIFICATE; + SSLObjLoader *ssl_obj = NULL; + + while (remain > 0) + { + int i, pem_size, obj_type; + char *start = NULL, *end = NULL; + + for (i = 0; i < NUM_PEM_TYPES; i++) + { + if ((start = strstr(where, begins[i])) && + (end = strstr(where, ends[i]))) + { + remain -= (int)(end-where); + start += strlen(begins[i]); + pem_size = (int)(end-start); + + ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader)); + + /* 4/3 bigger than what we need but so what */ + ssl_obj->buf = (uint8_t *)calloc(1, pem_size); + ssl_obj->len = pem_size; + + if (i == IS_RSA_PRIVATE_KEY && + strstr(start, "Proc-Type:") && + strstr(start, "4,ENCRYPTED")) + { + /* check for encrypted PEM file */ + if (pem_decrypt(start, end, password, ssl_obj) < 0) + { + ret = SSL_ERROR_BAD_CERTIFICATE; + goto error; + } + } + else + { + ssl_obj->len = pem_size; + if (base64_decode(start, pem_size, + ssl_obj->buf, &ssl_obj->len) != 0) + { + ret = SSL_ERROR_BAD_CERTIFICATE; + goto error; + } + } + + switch (i) + { + case IS_RSA_PRIVATE_KEY: + obj_type = SSL_OBJ_RSA_KEY; + break; + + case IS_ENCRYPTED_PRIVATE_KEY: + case IS_PRIVATE_KEY: + obj_type = SSL_OBJ_PKCS8; + break; + + case IS_CERTIFICATE: + obj_type = is_cacert ? + SSL_OBJ_X509_CACERT : SSL_OBJ_X509_CERT; + break; + + default: + ret = SSL_ERROR_BAD_CERTIFICATE; + goto error; + } + + /* In a format we can now understand - so process it */ + if ((ret = do_obj(ssl_ctx, obj_type, ssl_obj, password))) + goto error; + + end += strlen(ends[i]); + remain -= strlen(ends[i]); + while (remain > 0 && (*end == '\r' || *end == '\n')) + { + end++; + remain--; + } + + where = end; + break; + } + } + + ssl_obj_free(ssl_obj); + ssl_obj = NULL; + if (start == NULL) + break; + } +error: + ssl_obj_free(ssl_obj); + return ret; +} + +/* + * Load a file into memory that is in ASCII PEM format. + */ +static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type, + SSLObjLoader *ssl_obj, const char *password) +{ + char *start; + + /* add a null terminator */ + ssl_obj->len++; + ssl_obj->buf = (uint8_t *)realloc(ssl_obj->buf, ssl_obj->len); + ssl_obj->buf[ssl_obj->len-1] = 0; + start = (char *)ssl_obj->buf; + return new_pem_obj(ssl_ctx, obj_type == SSL_OBJ_X509_CACERT, + start, ssl_obj->len, password); +} +#endif /* CONFIG_SSL_HAS_PEM */ + +/** + * Load the key/certificates in memory depending on compile-time and user + * options. + */ +int load_key_certs(SSL_CTX *ssl_ctx) +{ + int ret = SSL_OK; + uint32_t options = ssl_ctx->options; +#ifdef CONFIG_SSL_GENERATE_X509_CERT + uint8_t *cert_data = NULL; + int cert_size; + static const char *dn[] = + { + CONFIG_SSL_X509_COMMON_NAME, + CONFIG_SSL_X509_ORGANIZATION_NAME, + CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME + }; +#endif + + /* do the private key first */ + if (strlen(CONFIG_SSL_PRIVATE_KEY_LOCATION) > 0) + { + if ((ret = ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY, + CONFIG_SSL_PRIVATE_KEY_LOCATION, + CONFIG_SSL_PRIVATE_KEY_PASSWORD)) < 0) + goto error; + } + else if (!(options & SSL_NO_DEFAULT_KEY)) + { +#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE) + static const /* saves a few more bytes */ +#include "private_key.h" + + ssl_obj_memory_load(ssl_ctx, SSL_OBJ_RSA_KEY, default_private_key, + default_private_key_len, NULL); +#endif + } + + /* now load the certificate */ +#ifdef CONFIG_SSL_GENERATE_X509_CERT + if ((cert_size = ssl_x509_create(ssl_ctx, 0, dn, &cert_data)) < 0) + { + ret = cert_size; + goto error; + } + + ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT, cert_data, cert_size, NULL); + free(cert_data); +#else + if (strlen(CONFIG_SSL_X509_CERT_LOCATION)) + { + if ((ret = ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, + CONFIG_SSL_X509_CERT_LOCATION, NULL)) < 0) + goto error; + } + else if (!(options & SSL_NO_DEFAULT_KEY)) + { +#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE) +#include "cert.h" + ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT, + default_certificate, default_certificate_len, NULL); +#endif + } +#endif + +error: +#ifdef CONFIG_SSL_FULL_MODE + if (ret) + { + printf("Error: Certificate or key not loaded\n"); + } +#endif + + return ret; + +} + +#endif diff --git a/circuitpython/lib/axtls/ssl/openssl.c b/circuitpython/lib/axtls/ssl/openssl.c new file mode 100644 index 0000000..d0343e5 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/openssl.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * Enable a subset of openssl compatible functions. We don't aim to be 100% + * compatible - just to be able to do basic ports etc. + * + * Only really tested on mini_httpd, so I'm not too sure how extensive this + * port is. + */ + +#include "config.h" + +#ifdef CONFIG_OPENSSL_COMPATIBLE +#include +#include +#include +#include "os_port.h" +#include "ssl.h" + +#define OPENSSL_CTX_ATTR ((OPENSSL_CTX *)ssl_ctx->bonus_attr) + +static char *key_password = NULL; + +void *SSLv3_server_method(void) { return NULL; } +void *TLSv1_server_method(void) { return NULL; } +void *SSLv3_client_method(void) { return NULL; } +void *TLSv1_client_method(void) { return NULL; } + +typedef void * (*ssl_func_type_t)(void); +typedef void * (*bio_func_type_t)(void); + +typedef struct +{ + ssl_func_type_t ssl_func_type; +} OPENSSL_CTX; + +SSL_CTX * SSL_CTX_new(ssl_func_type_t meth) +{ + SSL_CTX *ssl_ctx = ssl_ctx_new(0, 5); + ssl_ctx->bonus_attr = malloc(sizeof(OPENSSL_CTX)); + OPENSSL_CTX_ATTR->ssl_func_type = meth; + return ssl_ctx; +} + +void SSL_CTX_free(SSL_CTX * ssl_ctx) +{ + free(ssl_ctx->bonus_attr); + ssl_ctx_free(ssl_ctx); +} + +SSL * SSL_new(SSL_CTX *ssl_ctx) +{ + SSL *ssl; +#ifdef CONFIG_SSL_ENABLE_CLIENT + ssl_func_type_t ssl_func_type = OPENSSL_CTX_ATTR->ssl_func_type; +#endif + + ssl = ssl_new(ssl_ctx, -1); /* fd is set later */ +#ifdef CONFIG_SSL_ENABLE_CLIENT + if (ssl_func_type == SSLv3_client_method || + ssl_func_type == TLSv1_client_method) + { + SET_SSL_FLAG(SSL_IS_CLIENT); + } + else +#endif + { + ssl->next_state = HS_CLIENT_HELLO; + } + + return ssl; +} + +int SSL_set_fd(SSL *s, int fd) +{ + s->client_fd = fd; + return 1; /* always succeeds */ +} + +int SSL_accept(SSL *ssl) +{ + while (ssl_read(ssl, NULL) == SSL_OK) + { + if (ssl->next_state == HS_CLIENT_HELLO) + return 1; /* we're done */ + } + + return -1; +} + +#ifdef CONFIG_SSL_ENABLE_CLIENT +int SSL_connect(SSL *ssl) +{ + return do_client_connect(ssl) == SSL_OK ? 1 : -1; +} +#endif + +void SSL_free(SSL *ssl) +{ + ssl_free(ssl); +} + +int SSL_read(SSL *ssl, void *buf, int num) +{ + uint8_t *read_buf; + int ret; + + while ((ret = ssl_read(ssl, &read_buf)) == SSL_OK); + + if (ret > SSL_OK) + { + memcpy(buf, read_buf, ret > num ? num : ret); + } + + return ret; +} + +int SSL_write(SSL *ssl, const void *buf, int num) +{ + return ssl_write(ssl, buf, num); +} + +int SSL_CTX_use_certificate_file(SSL_CTX *ssl_ctx, const char *file, int type) +{ + return (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, file, NULL) == SSL_OK); +} + +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ssl_ctx, const char *file, int type) +{ + return (ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY, file, key_password) == SSL_OK); +} + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ssl_ctx, int len, const uint8_t *d) +{ + return (ssl_obj_memory_load(ssl_ctx, + SSL_OBJ_X509_CERT, d, len, NULL) == SSL_OK); +} + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + return 1; +} + +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) +{ + return 1; +} + +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ssl_ctx, const char *file) +{ + return (ssl_obj_load(ssl_ctx, + SSL_OBJ_X509_CERT, file, NULL) == SSL_OK); +} + +int SSL_shutdown(SSL *ssl) +{ + return 1; +} + +/*** get/set session ***/ +SSL_SESSION *SSL_get1_session(SSL *ssl) +{ + return (SSL_SESSION *)ssl_get_session_id(ssl); /* note: wrong cast */ +} + +int SSL_set_session(SSL *ssl, SSL_SESSION *session) +{ + memcpy(ssl->session_id, (uint8_t *)session, SSL_SESSION_ID_SIZE); + return 1; +} + +void SSL_SESSION_free(SSL_SESSION *session) { } +/*** end get/set session ***/ + +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + return 0; +} + +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*verify_callback)(int, void *)) { } + +void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth) { } + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath) +{ + return 1; +} + +void *SSL_load_client_CA_file(const char *file) +{ + return (void *)file; +} + +void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file) +{ + + ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, (const char *)file, NULL); +} + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb) { } + +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) +{ + key_password = (char *)u; +} + +int SSL_peek(SSL *ssl, void *buf, int num) +{ + memcpy(buf, ssl->bm_data, num); + return num; +} + +void SSL_set_bio(SSL *ssl, void *rbio, void *wbio) { } + +long SSL_get_verify_result(const SSL *ssl) +{ + return ssl_handshake_status(ssl); +} + +int SSL_state(SSL *ssl) +{ + return 0x03; // ok state +} + +/** end of could do better list */ + +void *SSL_get_peer_certificate(const SSL *ssl) +{ + return &ssl->ssl_ctx->certs[0]; +} + +int SSL_clear(SSL *ssl) +{ + return 1; +} + + +int SSL_CTX_check_private_key(const SSL_CTX *ctx) +{ + return 1; +} + +int SSL_CTX_set_cipher_list(SSL *s, const char *str) +{ + return 1; +} + +int SSL_get_error(const SSL *ssl, int ret) +{ + ssl_display_error(ret); + return 0; /* TODO: return proper return code */ +} + +void SSL_CTX_set_options(SSL_CTX *ssl_ctx, int option) {} +int SSL_library_init(void ) { return 1; } +void SSL_load_error_strings(void ) {} +void ERR_print_errors_fp(FILE *fp) {} + +#ifndef CONFIG_SSL_SKELETON_MODE +long SSL_CTX_get_timeout(const SSL_CTX *ssl_ctx) { + return CONFIG_SSL_EXPIRY_TIME*3600; } +long SSL_CTX_set_timeout(SSL_CTX *ssl_ctx, long t) { + return SSL_CTX_get_timeout(ssl_ctx); } +#endif +void BIO_printf(FILE *f, const char *format, ...) +{ + va_list(ap); + va_start(ap, format); + vfprintf(f, format, ap); + va_end(ap); +} + +void* BIO_s_null(void) { return NULL; } +FILE *BIO_new(bio_func_type_t func) +{ + if (func == BIO_s_null) + return fopen("/dev/null", "r"); + else + return NULL; +} + +FILE *BIO_new_fp(FILE *stream, int close_flag) { return stream; } +int BIO_free(FILE *a) { if (a != stdout && a != stderr) fclose(a); return 1; } + + + +#endif diff --git a/circuitpython/lib/axtls/ssl/os_port.c b/circuitpython/lib/axtls/ssl/os_port.c new file mode 100644 index 0000000..e69de29 diff --git a/circuitpython/lib/axtls/ssl/os_port.h b/circuitpython/lib/axtls/ssl/os_port.h new file mode 100644 index 0000000..6e8fdd5 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/os_port.h @@ -0,0 +1,7 @@ +#include "config.h" + +#ifdef CONFIG_AXTLS_OS_PORT_H +#include CONFIG_AXTLS_OS_PORT_H +#else +#include "axtls_os_port.h" +#endif diff --git a/circuitpython/lib/axtls/ssl/p12.c b/circuitpython/lib/axtls/ssl/p12.c new file mode 100644 index 0000000..2c16581 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/p12.c @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Process PKCS#8/PKCS#12 keys. + * + * The decoding of a PKCS#12 key is fairly specific - this code was tested on a + * key generated with: + * + * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem + * -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 + * -name "p12_withoutCA" -out axTLS.withoutCA.p12 -password pass:abcd + * + * or with a certificate chain: + * + * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem + * -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe + * PBE-SHA1-RC4-128 -name "p12_withCA" -out axTLS.withCA.p12 -password pass:abcd + * + * Note that the PBE has to be specified with PBE-SHA1-RC4-128. The + * private/public keys/certs have to use RSA encryption. Both the integrity + * and privacy passwords are the same. + * + * The PKCS#8 files were generated with something like: + * + * PEM format: + * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1 + * PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8 + * + * DER format: + * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER + * -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8 + */ + +#include +#include +#include +#include "os_port.h" +#include "ssl.h" + +/* all commented out if not used */ +#ifdef CONFIG_SSL_USE_PKCS12 + +#define BLOCK_SIZE 64 +#define PKCS12_KEY_ID 1 +#define PKCS12_IV_ID 2 +#define PKCS12_MAC_ID 3 + +static char *make_uni_pass(const char *password, int *uni_pass_len); +static int p8_decrypt(const char *uni_pass, int uni_pass_len, + const uint8_t *salt, int iter, + uint8_t *priv_key, int priv_key_len, int id); +static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key); +static int get_pbe_params(uint8_t *buf, int *offset, + const uint8_t **salt, int *iterations); + +/* + * Take a raw pkcs8 block and then decrypt it and turn it into a normal key. + */ +int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password) +{ + uint8_t *buf = ssl_obj->buf; + int len, offset = 0; + int iterations; + int ret = SSL_NOT_OK; + uint8_t *version = NULL; + const uint8_t *salt; + uint8_t *priv_key; + int uni_pass_len; + char *uni_pass = make_uni_pass(password, &uni_pass_len); + + if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: Invalid p8 ASN.1 file\n"); +#endif + goto error; + } + + /* unencrypted key? */ + if (asn1_get_big_int(buf, &offset, &version) > 0 && *version == 0) + { + ret = p8_add_key(ssl_ctx, buf); + goto error; + } + + if (get_pbe_params(buf, &offset, &salt, &iterations) < 0) + goto error; + + if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0) + goto error; + + priv_key = &buf[offset]; + + p8_decrypt(uni_pass, uni_pass_len, salt, + iterations, priv_key, len, PKCS12_KEY_ID); + ret = p8_add_key(ssl_ctx, priv_key); + +error: + free(version); + free(uni_pass); + return ret; +} + +/* + * Take the unencrypted pkcs8 and turn it into a private key + */ +static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key) +{ + uint8_t *buf = priv_key; + int len, offset = 0; + int ret = SSL_NOT_OK; + + /* Skip the preamble and go straight to the private key. + We only support rsaEncryption (1.2.840.113549.1.1.1) */ + if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 || + asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0) + goto error; + + ret = asn1_get_private_key(&buf[offset], len, &ssl_ctx->rsa_ctx); + +error: + return ret; +} + +/* + * Create the unicode password + */ +static char *make_uni_pass(const char *password, int *uni_pass_len) +{ + int pass_len = 0, i; + char *uni_pass; + + if (password == NULL) + { + password = ""; + } + + uni_pass = (char *)malloc((strlen(password)+1)*2); + + /* modify the password into a unicode version */ + for (i = 0; i < (int)strlen(password); i++) + { + uni_pass[pass_len++] = 0; + uni_pass[pass_len++] = password[i]; + } + + uni_pass[pass_len++] = 0; /* null terminate */ + uni_pass[pass_len++] = 0; + *uni_pass_len = pass_len; + return uni_pass; +} + +/* + * Decrypt a pkcs8 block. + */ +static int p8_decrypt(const char *uni_pass, int uni_pass_len, + const uint8_t *salt, int iter, + uint8_t *priv_key, int priv_key_len, int id) +{ + uint8_t p[BLOCK_SIZE*2]; + uint8_t d[BLOCK_SIZE]; + uint8_t Ai[SHA1_SIZE]; + SHA1_CTX sha_ctx; + RC4_CTX rc4_ctx; + int i; + + for (i = 0; i < BLOCK_SIZE; i++) + { + p[i] = salt[i % SALT_SIZE]; + p[BLOCK_SIZE+i] = uni_pass[i % uni_pass_len]; + d[i] = id; + } + + /* get the key - no IV since we are using RC4 */ + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, d, sizeof(d)); + SHA1_Update(&sha_ctx, p, sizeof(p)); + SHA1_Final(Ai, &sha_ctx); + + for (i = 1; i < iter; i++) + { + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, Ai, SHA1_SIZE); + SHA1_Final(Ai, &sha_ctx); + } + + /* do the decryption */ + if (id == PKCS12_KEY_ID) + { + RC4_setup(&rc4_ctx, Ai, 16); + RC4_crypt(&rc4_ctx, priv_key, priv_key, priv_key_len); + } + else /* MAC */ + memcpy(priv_key, Ai, SHA1_SIZE); + + return 0; +} + +/* + * Take a raw pkcs12 block and the decrypt it and turn it into a certificate(s) + * and keys. + */ +int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password) +{ + uint8_t *buf = ssl_obj->buf; + int len, iterations, auth_safes_start, + auth_safes_end, auth_safes_len, key_offset, offset = 0; + int all_certs = 0; + uint8_t *version = NULL, *auth_safes = NULL, *cert, *orig_mac; + uint8_t key[SHA1_SIZE]; + uint8_t mac[SHA1_SIZE]; + const uint8_t *salt; + int uni_pass_len, ret = SSL_OK; + char *uni_pass = make_uni_pass(password, &uni_pass_len); + static const uint8_t pkcs_data[] = /* pkc7 data */ + { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01 }; + static const uint8_t pkcs_encrypted[] = /* pkc7 encrypted */ + { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06 }; + static const uint8_t pkcs8_key_bag[] = /* 1.2.840.113549.1.12.10.1.2 */ + { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02 }; + + if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: Invalid p12 ASN.1 file\n"); +#endif + goto error; + } + + if (asn1_get_big_int(buf, &offset, &version) < 0 || *version != 3) + { + ret = SSL_ERROR_INVALID_VERSION; + goto error; + } + + /* remove all the boring pcks7 bits */ + if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || + len != sizeof(pkcs_data) || + memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data))) + goto error; + + offset += len; + + if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 || + asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0) + goto error; + + /* work out the MAC start/end points (done on AuthSafes) */ + auth_safes_start = offset; + auth_safes_end = offset; + if (asn1_skip_obj(buf, &auth_safes_end, ASN1_SEQUENCE) < 0) + goto error; + + auth_safes_len = auth_safes_end - auth_safes_start; + auth_safes = malloc(auth_safes_len); + + memcpy(auth_safes, &buf[auth_safes_start], auth_safes_len); + + if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || + (len != sizeof(pkcs_encrypted) || + memcmp(&buf[offset], pkcs_encrypted, sizeof(pkcs_encrypted)))) + goto error; + + offset += len; + + if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 || + asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 || + asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || + len != sizeof(pkcs_data) || + memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data))) + goto error; + + offset += len; + + /* work out the salt for the certificate */ + if (get_pbe_params(buf, &offset, &salt, &iterations) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_IMPLICIT_TAG)) < 0) + goto error; + + /* decrypt the certificate */ + cert = &buf[offset]; + if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert, + len, PKCS12_KEY_ID)) < 0) + goto error; + + offset += len; + + /* load the certificate */ + key_offset = 0; + all_certs = asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE); + + /* keep going until all certs are loaded */ + while (key_offset < all_certs) + { + int cert_offset = key_offset; + + if (asn1_skip_obj(cert, &cert_offset, ASN1_SEQUENCE) < 0 || + asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 || + asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 || + asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 || + asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 || + asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 || + asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 || + (len = asn1_next_obj(cert, &key_offset, ASN1_OCTET_STRING)) < 0) + goto error; + + if ((ret = add_cert(ssl_ctx, &cert[key_offset], len)) < 0) + goto error; + + key_offset = cert_offset; + } + + if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || + len != sizeof(pkcs_data) || + memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data))) + goto error; + + offset += len; + + if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 || + asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0 || + asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || + (len != sizeof(pkcs8_key_bag)) || + memcmp(&buf[offset], pkcs8_key_bag, sizeof(pkcs8_key_bag))) + goto error; + + offset += len; + + /* work out the salt for the private key */ + if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 || + asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + get_pbe_params(buf, &offset, &salt, &iterations) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0) + goto error; + + /* decrypt the private key */ + cert = &buf[offset]; + if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert, + len, PKCS12_KEY_ID)) < 0) + goto error; + + offset += len; + + /* load the private key */ + if ((ret = p8_add_key(ssl_ctx, cert)) < 0) + goto error; + + /* miss out on friendly name, local key id etc */ + if (asn1_skip_obj(buf, &offset, ASN1_SET) < 0) + goto error; + + /* work out the MAC */ + if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || + len != SHA1_SIZE) + goto error; + + orig_mac = &buf[offset]; + offset += len; + + /* get the salt */ + if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8) + goto error; + + salt = &buf[offset]; + + /* work out what the mac should be */ + if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, + key, SHA1_SIZE, PKCS12_MAC_ID)) < 0) + goto error; + + ssl_hmac_sha1(auth_safes, auth_safes_len, key, SHA1_SIZE, mac); + + if (memcmp(mac, orig_mac, SHA1_SIZE)) + { + ret = SSL_ERROR_INVALID_HMAC; + goto error; + } + +error: + free(version); + free(uni_pass); + free(auth_safes); + return ret; +} + +/* + * Retrieve the salt/iteration details from a PBE block. + */ +static int get_pbe_params(uint8_t *buf, int *offset, + const uint8_t **salt, int *iterations) +{ + static const uint8_t pbeSH1RC4[] = /* pbeWithSHAAnd128BitRC4 */ + { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 }; + + int i, len; + uint8_t *iter = NULL; + int error_code = SSL_ERROR_NOT_SUPPORTED; + + /* Get the PBE type */ + if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, offset, ASN1_OID)) < 0) + goto error; + + /* we expect pbeWithSHAAnd128BitRC4 (1.2.840.113549.1.12.1.1) + which is the only algorithm we support */ + if (len != sizeof(pbeSH1RC4) || + memcmp(&buf[*offset], pbeSH1RC4, sizeof(pbeSH1RC4))) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n"); +#endif + goto error; + } + + *offset += len; + + if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 || + (len = asn1_next_obj(buf, offset, ASN1_OCTET_STRING)) < 0 || + len != 8) + goto error; + + *salt = &buf[*offset]; + *offset += len; + + if ((len = asn1_get_big_int(buf, offset, &iter)) < 0) + goto error; + + *iterations = 0; + for (i = 0; i < len; i++) + { + (*iterations) <<= 8; + (*iterations) += iter[i]; + } + + free(iter); + error_code = SSL_OK; /* got here - we are ok */ + +error: + return error_code; +} + +#endif diff --git a/circuitpython/lib/axtls/ssl/private_key.h b/circuitpython/lib/axtls/ssl/private_key.h new file mode 100644 index 0000000..f72bee2 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/private_key.h @@ -0,0 +1,54 @@ +unsigned char default_private_key[] = { + 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xbd, + 0x0f, 0xd4, 0x42, 0xa8, 0x74, 0x87, 0x54, 0xaa, 0xb9, 0x3a, 0x1f, 0x8b, + 0xce, 0xbd, 0xb7, 0x65, 0xfb, 0x40, 0x3d, 0xd0, 0x11, 0x9a, 0x9c, 0xdc, + 0x82, 0x7c, 0xea, 0xa8, 0x17, 0xe1, 0x74, 0xf3, 0x05, 0x0e, 0x61, 0xc1, + 0xc1, 0x78, 0x8a, 0xb2, 0xba, 0x15, 0x22, 0x5a, 0xff, 0x9b, 0xb8, 0x7a, + 0x2e, 0x0f, 0x88, 0xb7, 0x74, 0xde, 0x04, 0x99, 0xa5, 0xa2, 0x99, 0x53, + 0x8b, 0xad, 0x78, 0x5a, 0x31, 0xed, 0xbc, 0x01, 0xe7, 0xdf, 0xe9, 0xec, + 0x2f, 0xa0, 0x5d, 0x53, 0xf6, 0xe6, 0x8a, 0xa0, 0xc8, 0x6d, 0x41, 0x45, + 0x63, 0x23, 0xb3, 0xcf, 0x4e, 0x50, 0x1f, 0x28, 0xdf, 0x36, 0xe2, 0x73, + 0xdf, 0xd6, 0xa1, 0xb3, 0x46, 0x4f, 0x6e, 0xbb, 0x0d, 0x9b, 0xef, 0xa8, + 0xf9, 0x4c, 0xa5, 0x71, 0xa1, 0x88, 0xdd, 0x07, 0xa9, 0x86, 0x0d, 0x3f, + 0xcd, 0x99, 0x23, 0xa2, 0x84, 0x77, 0x0f, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x02, 0x81, 0x80, 0x26, 0x3f, 0xec, 0x96, 0xab, 0xd4, 0x1f, 0x89, 0x0e, + 0x9d, 0x38, 0xd8, 0x27, 0x05, 0xe5, 0xb6, 0x14, 0x08, 0xd7, 0xff, 0x69, + 0x78, 0x16, 0x4a, 0xc4, 0x06, 0x16, 0x55, 0xb7, 0x3a, 0x55, 0x9f, 0xbe, + 0x86, 0xf8, 0x58, 0xe8, 0xc5, 0x46, 0xa8, 0xf0, 0xed, 0xda, 0xd6, 0xbf, + 0x88, 0x55, 0x2d, 0xe6, 0x72, 0x29, 0x2c, 0x64, 0xc9, 0x5d, 0x1d, 0x9b, + 0x24, 0x3a, 0x98, 0x40, 0xa1, 0xd2, 0xaf, 0x5c, 0xab, 0x23, 0xe4, 0x33, + 0xd0, 0xea, 0x60, 0x52, 0xe7, 0x7a, 0x9e, 0x73, 0x5f, 0x2e, 0x80, 0xd1, + 0xdc, 0x6f, 0x47, 0x0f, 0x97, 0x80, 0x36, 0xd2, 0x30, 0x07, 0xdd, 0xd6, + 0xd7, 0x15, 0x89, 0x2b, 0x74, 0xd5, 0x7e, 0x8a, 0xbc, 0x63, 0x42, 0x0a, + 0xf2, 0x31, 0x29, 0xbf, 0xf9, 0xf9, 0xf0, 0x88, 0x8f, 0x8a, 0xc2, 0x22, + 0x6e, 0x15, 0x26, 0xb7, 0x5e, 0x5b, 0x58, 0x44, 0x1c, 0x3b, 0x79, 0x02, + 0x41, 0x00, 0xe1, 0xf1, 0xb2, 0xe5, 0xc8, 0x80, 0x93, 0x40, 0x50, 0x74, + 0x14, 0xdd, 0xb2, 0xf2, 0x27, 0x5c, 0x0c, 0x3d, 0xc0, 0x5f, 0xee, 0x9c, + 0x45, 0x6c, 0x13, 0x00, 0xdf, 0xd0, 0xd9, 0x83, 0xfa, 0x90, 0x2c, 0x84, + 0xf2, 0xaa, 0xc2, 0xdd, 0xfb, 0xcf, 0x03, 0x41, 0x88, 0x10, 0xc6, 0xbb, + 0x5e, 0xb7, 0xb6, 0x2e, 0xa6, 0x1d, 0xaa, 0xba, 0xfb, 0x4a, 0x72, 0xd8, + 0x9a, 0xad, 0x88, 0x0d, 0x6a, 0x15, 0x02, 0x41, 0x00, 0xd6, 0x36, 0x23, + 0xf3, 0x5d, 0x77, 0xc8, 0xd3, 0x49, 0xc1, 0x93, 0xfe, 0xca, 0x0d, 0xeb, + 0x9b, 0xda, 0xbd, 0x47, 0x28, 0x73, 0x97, 0xa0, 0x50, 0xd7, 0x4c, 0x24, + 0xdf, 0x9b, 0x0b, 0x37, 0xae, 0xc3, 0x31, 0xb5, 0x4f, 0x62, 0x08, 0xca, + 0xe5, 0xef, 0x97, 0x7b, 0x43, 0xa0, 0xda, 0x2b, 0x1f, 0xbf, 0xa8, 0x08, + 0x93, 0xd2, 0x16, 0x1c, 0x89, 0x99, 0xf1, 0xdf, 0x26, 0xd1, 0x42, 0x99, + 0x93, 0x02, 0x41, 0x00, 0xb1, 0x41, 0xe4, 0x7e, 0xdf, 0x20, 0xf7, 0xe4, + 0xf1, 0xf9, 0x4f, 0xd1, 0x6a, 0x2d, 0x0d, 0xf1, 0xe9, 0xec, 0x9c, 0x3a, + 0xe6, 0xc0, 0x94, 0xba, 0x27, 0xe2, 0x7c, 0xb4, 0xa5, 0xa1, 0x23, 0xf6, + 0xed, 0xe6, 0x53, 0x56, 0xe2, 0x50, 0x32, 0xd8, 0x02, 0x8e, 0xeb, 0xc7, + 0x75, 0x91, 0xd3, 0xca, 0x3e, 0xd4, 0x34, 0x20, 0x7c, 0x2b, 0xfb, 0x2f, + 0x3a, 0x10, 0x72, 0xb1, 0x07, 0x56, 0xb6, 0xcd, 0x02, 0x40, 0x1e, 0x3b, + 0xf2, 0x03, 0x0d, 0x74, 0x34, 0xb2, 0x2d, 0xbc, 0xd6, 0xc8, 0xa5, 0x78, + 0x25, 0x83, 0x0f, 0xf2, 0x9b, 0x32, 0x88, 0x6e, 0x24, 0x40, 0x84, 0xc2, + 0xc8, 0x89, 0x8e, 0xf6, 0x9c, 0x5b, 0x5c, 0x4d, 0x8d, 0xcb, 0xb0, 0x88, + 0x91, 0x2a, 0xb7, 0x10, 0x68, 0x63, 0x79, 0x36, 0x91, 0xd3, 0x9f, 0x57, + 0x76, 0x2e, 0x76, 0xfe, 0x8b, 0xf4, 0x97, 0xf7, 0xdd, 0x89, 0x3b, 0x0b, + 0xed, 0x65, 0x02, 0x41, 0x00, 0xb9, 0xaf, 0xbf, 0x09, 0xc9, 0x90, 0x26, + 0xf3, 0x72, 0x8b, 0xbf, 0xb3, 0x7c, 0xe7, 0x6f, 0x6f, 0x5b, 0xa3, 0x95, + 0xb8, 0x9e, 0x03, 0xb9, 0xcf, 0xa0, 0x53, 0xba, 0x32, 0xc1, 0xd3, 0xad, + 0x85, 0xbb, 0x79, 0x48, 0x09, 0xd6, 0x3f, 0x9c, 0xd9, 0x37, 0x91, 0x11, + 0x0d, 0x04, 0xd5, 0x3b, 0xca, 0x74, 0x5d, 0x1c, 0x91, 0x8d, 0x3d, 0xf1, + 0xf8, 0xf9, 0xbe, 0x35, 0xd7, 0xb2, 0x53, 0x50, 0x1d +}; +unsigned int default_private_key_len = 609; diff --git a/circuitpython/lib/axtls/ssl/ssl.h b/circuitpython/lib/axtls/ssl/ssl.h new file mode 100644 index 0000000..dc47c81 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/ssl.h @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * @mainpage axTLS API + * + * @image html axolotl.jpg + * + * The axTLS library has features such as: + * - The TLSv1 SSL client/server protocol + * - No requirement to use any openssl libraries. + * - A choice between AES block (128/256 bit) and RC4 (128 bit) stream ciphers. + * - RSA encryption/decryption with variable sized keys (up to 4096 bits). + * - Certificate chaining and peer authentication. + * - Session resumption, session renegotiation. + * - ASN.1, X.509, PKCS#8, PKCS#12 keys/certificates with DER/PEM encoding. + * - Highly configurable compile time options. + * - Portable across many platforms (written in ANSI C), and has language + * bindings in C, C#, VB.NET, Java, Perl and Lua. + * - Partial openssl API compatibility (via a wrapper). + * - A very small footprint (around 50-60kB for the library in 'server-only' + * mode). + * - No dependencies on sockets - can use serial connections for example. + * - A very simple API - ~ 20 functions/methods. + * + * A list of these functions/methods are described below. + * + * @ref c_api + * + * @ref bigint_api + * + * @ref csharp_api + * + * @ref java_api + */ +#ifndef HEADER_SSL_H +#define HEADER_SSL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* need to predefine before ssl_lib.h gets to it */ +#define SSL_SESSION_ID_SIZE 32 + +#include "tls1.h" + +/* The optional parameters that can be given to the client/server SSL engine */ +#define SSL_CLIENT_AUTHENTICATION 0x00010000 +#define SSL_SERVER_VERIFY_LATER 0x00020000 +#define SSL_NO_DEFAULT_KEY 0x00040000 +#define SSL_DISPLAY_STATES 0x00080000 +#define SSL_DISPLAY_BYTES 0x00100000 +#define SSL_DISPLAY_CERTS 0x00200000 +#define SSL_DISPLAY_RSA 0x00400000 +#define SSL_CONNECT_IN_PARTS 0x00800000 + +/* errors that can be generated */ +#define SSL_OK 0 +#define SSL_NOT_OK -1 +#define SSL_ERROR_DEAD -2 +#define SSL_CLOSE_NOTIFY -3 +#define SSL_EAGAIN -4 +#define SSL_ERROR_CONN_LOST -256 +#define SSL_ERROR_RECORD_OVERFLOW -257 +#define SSL_ERROR_SOCK_SETUP_FAILURE -258 +#define SSL_ERROR_INVALID_HANDSHAKE -260 +#define SSL_ERROR_INVALID_PROT_MSG -261 +#define SSL_ERROR_INVALID_HMAC -262 +#define SSL_ERROR_INVALID_VERSION -263 +#define SSL_ERROR_UNSUPPORTED_EXTENSION -264 +#define SSL_ERROR_INVALID_SESSION -265 +#define SSL_ERROR_NO_CIPHER -266 +#define SSL_ERROR_INVALID_CERT_HASH_ALG -267 +#define SSL_ERROR_BAD_CERTIFICATE -268 +#define SSL_ERROR_INVALID_KEY -269 +#define SSL_ERROR_FINISHED_INVALID -271 +#define SSL_ERROR_NO_CERT_DEFINED -272 +#define SSL_ERROR_NO_CLIENT_RENOG -273 +#define SSL_ERROR_NOT_SUPPORTED -274 +#define SSL_X509_OFFSET -512 +#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A) + +/* alert types that are recognized */ +#define SSL_ALERT_TYPE_WARNING 1 +#define SLL_ALERT_TYPE_FATAL 2 + +/* these are all the alerts that are recognized */ +#define SSL_ALERT_CLOSE_NOTIFY 0 +#define SSL_ALERT_UNEXPECTED_MESSAGE 10 +#define SSL_ALERT_BAD_RECORD_MAC 20 +#define SSL_ALERT_RECORD_OVERFLOW 22 +#define SSL_ALERT_HANDSHAKE_FAILURE 40 +#define SSL_ALERT_BAD_CERTIFICATE 42 +#define SSL_ALERT_UNSUPPORTED_CERTIFICATE 43 +#define SSL_ALERT_CERTIFICATE_EXPIRED 45 +#define SSL_ALERT_CERTIFICATE_UNKNOWN 46 +#define SSL_ALERT_ILLEGAL_PARAMETER 47 +#define SSL_ALERT_UNKNOWN_CA 48 +#define SSL_ALERT_DECODE_ERROR 50 +#define SSL_ALERT_DECRYPT_ERROR 51 +#define SSL_ALERT_INVALID_VERSION 70 +#define SSL_ALERT_NO_RENEGOTIATION 100 +#define SSL_ALERT_UNSUPPORTED_EXTENSION 110 + +/* The ciphers that are supported */ +#define SSL_AES128_SHA 0x2f +#define SSL_AES256_SHA 0x35 +#define SSL_AES128_SHA256 0x3c +#define SSL_AES256_SHA256 0x3d + +/* build mode ids' */ +#define SSL_BUILD_SKELETON_MODE 0x01 +#define SSL_BUILD_SERVER_ONLY 0x02 +#define SSL_BUILD_ENABLE_VERIFICATION 0x03 +#define SSL_BUILD_ENABLE_CLIENT 0x04 +#define SSL_BUILD_FULL_MODE 0x05 + +/* offsets to retrieve configuration information */ +#define SSL_BUILD_MODE 0 +#define SSL_MAX_CERT_CFG_OFFSET 1 +#define SSL_MAX_CA_CERT_CFG_OFFSET 2 +#define SSL_HAS_PEM 3 + +/* default session sizes */ +#define SSL_DEFAULT_SVR_SESS 5 +#define SSL_DEFAULT_CLNT_SESS 1 + +/* X.509/X.520 distinguished name types */ +#define SSL_X509_CERT_COMMON_NAME 0 +#define SSL_X509_CERT_ORGANIZATION 1 +#define SSL_X509_CERT_ORGANIZATIONAL_NAME 2 +#define SSL_X509_CERT_LOCATION 3 +#define SSL_X509_CERT_COUNTRY 4 +#define SSL_X509_CERT_STATE 5 +#define SSL_X509_CA_CERT_COMMON_NAME 6 +#define SSL_X509_CA_CERT_ORGANIZATION 7 +#define SSL_X509_CA_CERT_ORGANIZATIONAL_NAME 8 +#define SSL_X509_CA_CERT_LOCATION 9 +#define SSL_X509_CA_CERT_COUNTRY 10 +#define SSL_X509_CA_CERT_STATE 11 + +/* SSL object loader types */ +#define SSL_OBJ_X509_CERT 1 +#define SSL_OBJ_X509_CACERT 2 +#define SSL_OBJ_RSA_KEY 3 +#define SSL_OBJ_PKCS8 4 +#define SSL_OBJ_PKCS12 5 + +/** + * @defgroup c_api Standard C API + * @brief The standard interface in C. + * @{ + */ + +/** + * @brief Establish a new client/server context. + * + * This function is called before any client/server SSL connections are made. + * + * Each new connection will use the this context's private key and + * certificate chain. If a different certificate chain is required, then a + * different context needs to be be used. + * + * There are two threading models supported - a single thread with one + * SSL_CTX can support any number of SSL connections - and multiple threads can + * support one SSL_CTX object each (the default). But if a single SSL_CTX + * object uses many SSL objects in individual threads, then the + * CONFIG_SSL_CTX_MUTEXING option needs to be configured. + * + * @param options [in] Any particular options. At present the options + * supported are: + * - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server + * authentication fails. The certificate can be authenticated later with a + * call to ssl_verify_cert(). + * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication + * i.e. each handshake will include a "certificate request" message from the + * server. Only available if verification has been enabled. + * - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences + * during the handshake. + * - SSL_DISPLAY_STATES (full mode build only): Display the state changes + * during the handshake. + * - SSL_DISPLAY_CERTS (full mode build only): Display the certificates that + * are passed during a handshake. + * - SSL_DISPLAY_RSA (full mode build only): Display the RSA key details that + * are passed during a handshake. + * - SSL_CONNECT_IN_PARTS (client only): To use a non-blocking version of + * ssl_client_new(). + * @param num_sessions [in] The number of sessions to be used for session + * caching. If this value is 0, then there is no session caching. This option + * is not used in skeleton mode. + * @return A client/server context. + */ +EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions); + +/** + * @brief Remove a client/server context. + * + * Frees any used resources used by this context. Each connection will be + * sent a "Close Notify" alert (if possible). + * @param ssl_ctx [in] The client/server context. + */ +EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx); + +/** + * @brief Allocates new SSL extensions structure and returns pointer to it + * + * @return ssl_ext Pointer to SSL_EXTENSIONS structure + * + */ +EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new(void); + +/** + * @brief Frees SSL extensions structure + * + * @param ssl_ext [in] Pointer to SSL_EXTENSION structure + * + */ +EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext); + +/** + * @brief (server only) Establish a new SSL connection to an SSL client. + * + * It is up to the application to establish the logical connection (whether it + * is a socket, serial connection etc). + * @param ssl_ctx [in] The server context. + * @param client_fd [in] The client's file descriptor. + * @return An SSL object reference. + */ +EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, long client_fd); + +/** + * @brief (client only) Establish a new SSL connection to an SSL server. + * + * It is up to the application to establish the initial logical connection + * (whether it is a socket, serial connection etc). + * + * This is a normally a blocking call - it will finish when the handshake is + * complete (or has failed). To use in non-blocking mode, set + * SSL_CONNECT_IN_PARTS in ssl_ctx_new(). + * @param ssl_ctx [in] The client context. + * @param client_fd [in] The client's file descriptor. + * @param session_id [in] A 32 byte session id for session resumption. This + * can be null if no session resumption is being used or required. This option + * is not used in skeleton mode. + * @param sess_id_size The size of the session id (max 32) + * @param ssl_ext pointer to a structure with the activated SSL extensions + * and their values + * @return An SSL object reference. Use ssl_handshake_status() to check + * if a handshake succeeded. + */ +EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, long client_fd, const uint8_t *session_id, uint8_t sess_id_size, SSL_EXTENSIONS* ssl_ext); + +/** + * @brief Free any used resources on this connection. + + * A "Close Notify" message is sent on this connection (if possible). It is up + * to the application to close the socket or file descriptor. + * @param ssl [in] The ssl object reference. + */ +EXP_FUNC void STDCALL ssl_free(SSL *ssl); + +/** + * @brief Read the SSL data stream. + * If the socket is non-blocking and data is blocked then SSO_OK will be + * returned. + * @param ssl [in] An SSL object reference. + * @param in_data [out] If the read was successful, a pointer to the read + * buffer will be here. Do NOT ever free this memory as this buffer is used in + * sucessive calls. If the call was unsuccessful, this value will be null. + * @return The number of decrypted bytes: + * - if > 0, then the handshaking is complete and we are returning the number + * of decrypted bytes. + * - SSL_OK if the handshaking stage is successful (but not yet complete). + * - < 0 if an error. + * @see ssl.h for the error code list. + * @note Use in_data before doing any successive ssl calls. + */ +EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data); + +/** + * @brief Write to the SSL data stream. + * if the socket is non-blocking and data is blocked then a check is made + * to ensure that all data is sent (i.e. blocked mode is forced). + * @param ssl [in] An SSL obect reference. + * @param out_data [in] The data to be written + * @param out_len [in] The number of bytes to be written. + * @return The number of bytes sent, or if < 0 if an error. + * @see ssl.h for the error code list. + */ +EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len); + +/** + * @brief Find an ssl object based on a file descriptor. + * + * Goes through the list of SSL objects maintained in a client/server context + * to look for a file descriptor match. + * @param ssl_ctx [in] The client/server context. + * @param client_fd [in] The file descriptor. + * @return A reference to the SSL object. Returns null if the object could not + * be found. + */ +EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, long client_fd); + +/** + * @brief Get the session id for a handshake. + * + * This will be a 32 byte sequence and is available after the first + * handshaking messages are sent. + * @param ssl [in] An SSL object reference. + * @return The session id as a 32 byte sequence. + * @note A SSLv23 handshake may have only 16 valid bytes. + */ +EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl); + +/** + * @brief Get the session id size for a handshake. + * + * This will normally be 32 but could be 0 (no session id) or something else. + * @param ssl [in] An SSL object reference. + * @return The size of the session id. + */ +EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl); + +/** + * @brief Return the cipher id (in the SSL form). + * @param ssl [in] An SSL object reference. + * @return The cipher id. This will be one of the following: + * - SSL_AES128_SHA (0x2f) + * - SSL_AES256_SHA (0x35) + * - SSL_AES128_SHA256 (0x3c) + * - SSL_AES256_SHA256 (0x3d) + */ +EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl); + +/** + * @brief Return the status of the handshake. + * @param ssl [in] An SSL object reference. + * @return SSL_OK if the handshake is complete and ok. + * @see ssl.h for the error code list. + */ +EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl); + +/** + * @brief Retrieve various parameters about the axTLS engine. + * @param offset [in] The configuration offset. It will be one of the following: + * - SSL_BUILD_MODE The build mode. This will be one of the following: + * - SSL_BUILD_SERVER_ONLY (basic server mode) + * - SSL_BUILD_ENABLE_VERIFICATION (server can do client authentication) + * - SSL_BUILD_ENABLE_CLIENT (client/server capabilties) + * - SSL_BUILD_FULL_MODE (client/server with diagnostics) + * - SSL_BUILD_SKELETON_MODE (skeleton mode) + * - SSL_MAX_CERT_CFG_OFFSET The maximum number of certificates allowed. + * - SSL_MAX_CA_CERT_CFG_OFFSET The maximum number of CA certificates allowed. + * - SSL_HAS_PEM 1 if supported + * @return The value of the requested parameter. + */ +EXP_FUNC int STDCALL ssl_get_config(int offset); + +/** + * @brief Display why the handshake failed. + * + * This call is only useful in a 'full mode' build. The output is to stdout. + * @param error_code [in] An error code. + * @see ssl.h for the error code list. + */ +EXP_FUNC void STDCALL ssl_display_error(int error_code); + +/** + * @brief Authenticate a received certificate. + * + * This call is usually made by a client after a handshake is complete and the + * context is in SSL_SERVER_VERIFY_LATER mode. + * @param ssl [in] An SSL object reference. + * @return SSL_OK if the certificate is verified. + */ +EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl); + +/** + * @brief Retrieve an X.509 distinguished name component. + * + * When a handshake is complete and a certificate has been exchanged, then the + * details of the remote certificate can be retrieved. + * + * This will usually be used by a client to check that the server's common + * name matches the URL. + * + * @param ssl [in] An SSL object reference. + * @param component [in] one of: + * - SSL_X509_CERT_COMMON_NAME + * - SSL_X509_CERT_ORGANIZATION + * - SSL_X509_CERT_ORGANIZATIONAL_NAME + * - SSL_X509_CERT_LOCATION + * - SSL_X509_CERT_COUNTRY + * - SSL_X509_CERT_STATE + * - SSL_X509_CA_CERT_COMMON_NAME + * - SSL_X509_CA_CERT_ORGANIZATION + * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME + * - SSL_X509_CA_CERT_LOCATION + * - SSL_X509_CA_CERT_COUNTRY + * - SSL_X509_CA_CERT_STATE + * @return The appropriate string (or null if not defined) + * @note Verification build mode must be enabled. + */ +EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component); + +/** + * @brief Retrieve a Subject Alternative DNSName + * + * When a handshake is complete and a certificate has been exchanged, then the + * details of the remote certificate can be retrieved. + * + * This will usually be used by a client to check that the server's DNS + * name matches the URL. + * + * @param ssl [in] An SSL object reference. + * @param dnsindex [in] The index of the DNS name to retrieve. + * @return The appropriate string (or null if not defined) + * @note Verification build mode must be enabled. + */ +EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int dnsindex); + +/** + * @brief Force the client to perform its handshake again. + * + * For a client this involves sending another "client hello" message. + * For the server is means sending a "hello request" message. + * + * This is a blocking call on the client (until the handshake completes). + * + * @param ssl [in] An SSL object reference. + * @return SSL_OK if renegotiation instantiation was ok + */ +EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl); + +/** + * @brief Process a file that is in binary DER or ASCII PEM format. + * + * These are temporary objects that are used to load private keys, + * certificates etc into memory. + * @param ssl_ctx [in] The client/server context. + * @param obj_type [in] The format of the file. Can be one of: + * - SSL_OBJ_X509_CERT (no password required) + * - SSL_OBJ_X509_CACERT (no password required) + * - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported) + * - SSL_OBJ_PKCS8 (RC4-128 encrypted data supported) + * - SSL_OBJ_PKCS12 (RC4-128 encrypted data supported) + * + * PEM files are automatically detected (if supported). The object type is + * also detected, and so is not relevant for these types of files. + * @param filename [in] The location of a file in DER/PEM format. + * @param password [in] The password used. Can be null if not required. + * @return SSL_OK if all ok + * @note Not available in skeleton build mode. + */ +EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *filename, const char *password); + +/** + * @brief Process binary data. + * + * These are temporary objects that are used to load private keys, + * certificates etc into memory. + * @param ssl_ctx [in] The client/server context. + * @param obj_type [in] The format of the memory data. + * @param data [in] The binary data to be loaded. + * @param len [in] The amount of data to be loaded. + * @param password [in] The password used. Can be null if not required. + * @return SSL_OK if all ok + * @see ssl_obj_load for more details on obj_type. + */ +EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password); + +#ifdef CONFIG_SSL_GENERATE_X509_CERT +/** + * @brief Create an X.509 certificate. + * + * This certificate is a self-signed v1 cert with a fixed start/stop validity + * times. It is signed with an internal private key in ssl_ctx. + * + * @param ssl_ctx [in] The client/server context. + * @param options [in] Not used yet. + * @param dn [in] An array of distinguished name strings. The array is defined + * by: + * - SSL_X509_CERT_COMMON_NAME (0) + * - If SSL_X509_CERT_COMMON_NAME is empty or not defined, then the + * hostname will be used. + * - SSL_X509_CERT_ORGANIZATION (1) + * - If SSL_X509_CERT_ORGANIZATION is empty or not defined, then $USERNAME + * will be used. + * - SSL_X509_CERT_ORGANIZATIONAL_NAME (2) + * - SSL_X509_CERT_ORGANIZATIONAL_NAME is optional. + * @param cert_data [out] The certificate as a sequence of bytes. + * @return < 0 if an error, or the size of the certificate in bytes. + * @note cert_data must be freed when there is no more need for it. + */ +EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data); +#endif + +/** + * @brief Return the axTLS library version as a string. + */ +EXP_FUNC const char * STDCALL ssl_version(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/axtls/ssl/test/Makefile b/circuitpython/lib/axtls/ssl/test/Makefile new file mode 100644 index 0000000..b1d7538 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/Makefile @@ -0,0 +1,100 @@ +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +all: + +AXTLS_HOME=../.. + +include $(AXTLS_HOME)/config/.config +include $(AXTLS_HOME)/config/makefile.conf + +ifdef CONFIG_PERFORMANCE_TESTING +all: performance +endif + +ifdef CONFIG_SSL_TEST +all: ssltesting +endif + +include $(AXTLS_HOME)/config/makefile.post + +ifndef CONFIG_PLATFORM_WIN32 +performance: $(AXTLS_HOME)/$(STAGE)/perf_bigint +ssltesting: $(AXTLS_HOME)/$(STAGE)/ssltest +LIBS=$(AXTLS_HOME)/$(STAGE) + +$(AXTLS_HOME)/$(STAGE)/perf_bigint: perf_bigint.o $(LIBS)/libaxtls.a + $(LD) $(LDFLAGS) -o $@ $^ -L $(LIBS) -laxtls + +$(AXTLS_HOME)/$(STAGE)/ssltest: ssltest.o $(LIBS)/libaxtls.a + $(LD) $(LDFLAGS) -o $@ $^ -lpthread -L $(LIBS) -laxtls +else +performance: $(AXTLS_HOME)/$(STAGE)/perf_bigint.exe +ssltesting: $(AXTLS_HOME)/$(STAGE)/ssltest.exe + +CRYPTO_PATH="$(AXTLS_INCLUDE)crypto\\" +AXTLS_SSL_PATH="$(AXTLS_INCLUDE)ssl\\" + +CRYPTO_OBJ=\ + $(CRYPTO_PATH)aes.obj \ + $(CRYPTO_PATH)bigint.obj \ + $(CRYPTO_PATH)crypto_misc.obj \ + $(CRYPTO_PATH)hmac.obj \ + $(CRYPTO_PATH)md2.obj \ + $(CRYPTO_PATH)md5.obj \ + $(CRYPTO_PATH)rc4.obj \ + $(CRYPTO_PATH)rsa.obj \ + $(CRYPTO_PATH)sha1.obj \ + $(CRYPTO_PATH)sha256.obj \ + $(CRYPTO_PATH)sha384.obj \ + $(CRYPTO_PATH)sha512.obj + +OBJ=\ + $(AXTLS_SSL_PATH)asn1.obj \ + $(AXTLS_SSL_PATH)gen_cert.obj \ + $(AXTLS_SSL_PATH)loader.obj \ + $(AXTLS_SSL_PATH)openssl.obj \ + $(AXTLS_SSL_PATH)os_port.obj \ + $(AXTLS_SSL_PATH)p12.obj \ + $(AXTLS_SSL_PATH)x509.obj \ + $(AXTLS_SSL_PATH)tls1.obj \ + $(AXTLS_SSL_PATH)tls1_svr.obj \ + $(AXTLS_SSL_PATH)tls1_clnt.obj + +$(AXTLS_HOME)/$(STAGE)/perf_bigint.exe: perf_bigint.obj + $(LD) $(LDFLAGS) /out:$@ $? $(CRYPTO_OBJ) $(OBJ) + +$(AXTLS_HOME)/$(STAGE)/ssltest.exe: ssltest.obj + $(LD) $(LDFLAGS) /out:$@ $? $(CRYPTO_OBJ) $(OBJ) +endif + +clean:: + -@rm -f $(AXTLS_HOME)/$(STAGE)/perf_bigint* $(AXTLS_HOME)/$(STAGE)/ssltest* + diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.ca_key.pem b/circuitpython/lib/axtls/ssl/test/axTLS.ca_key.pem new file mode 100644 index 0000000..0c8c19b --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.ca_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsSMwkpYHlwIsi1oxllJLjAPjjycx9t6Q3BOzXBSoZHc1wA+r +QVuKHarpe8tYOKlNP8b79ejbCv/1U3NlVkMJJtLZUPtDwTEwUZNEG17ixS438mGI +1AbHXvwhPaoT24UymEOcbJxAZuClDfzKpN7Cl6OzN7Ox44gHmBCBSnUhRAnJYxD6 +x8wBLw8HdH0bMdoc2+H4KyW31uMGva7C9YlUCPVQGPJsTP1DLRskqy+zO1NERUTO +XytHeYLlh/X/o+NYVvUf7WKu6qC3I4HK+OZ5OW3E+EaE73oYRmUVDaVavL7bRKEf +2NSbzowU+VsFEnyXIF7YnRFp0D1yrMzaC49bDQIDAQABAoIBAQCwOrNLUunwKaCJ +b00gIXW5sfDGbhc+ZUU3Pn5V4NN7SEJ4dt5JYrnxNCWgHLkDfiQ1jFEF4QlzUx0O +TiMGhCDpuCGueJx66uYIcnvywx7XT1kn0jNfxfK6JBsqDzg8ULL6W2GXiIhmEZ8E +YHh3OIvec2WMyED1flMXzWvj2M4ksfMgZH290T9BSxzlEj9X7dZu55K4sFtu0XNi +7uJDB0vF8KfW5gLpwj6pd7i32Cm/Pgpl+7lcqMNpDHo0U2dMyWeH1EmWinS4rHxd +mGDm0N0qK4BOYAJdasq7HwRjzDZkAPuNqcH0gOzSq3aYCI2tP2E6IvprM/vbqA4I +ooo+GDJhAoGBAORiphxweuGBRTpSqoi9qEICM2WMC2NZW8bpFyWn79CuALGzvvc+ +Buw8W3LVElByUyTVWBnBQQ1iXZGe9f1x2P9q8R1Bdl0rpePg3J9ff9674VRLrcov +M85/NUHkj1fJ+2CkCx7KG5BFm3GaAb74e+7MceEW/eErMmCqtNgkR2Z5AoGBAMaO +O9SnVNd4wgnJAjVgN4fqaXWNzZz6NYWtnFVIcTTO7vU1P9t5NjgcsdF9+SnLA/jV +Ylo5Pl0fLPKg5QtIvlooZjXB8hgKVjrVGRLFt9TN0tJMeJ//11Bo88MNMOf0OQPg +i2OMWI3w/oRFJthmpeYWOgXNlLOcoSW1LsnWR0Q1AoGBALAXi+KTq3tiM+FzSb/j +E+/JSJ28bC9u/7+Pi2RiZxrsfuaFI/H4ZlgRdaVFujhC3e6hfKtnAWRzepfEDAEd +neXaLAyVo9DUzbS1dQaBGNPA400eiOJCoNxP4t1qgEd9GhB6i4Ry6uvDb8YYq832 +Q4BtLEUUeC38I3y7QnMBDfhpAoGAZ13InA54xqvhKELy2WK7xhAs0rv93MkNcAhP +qL5L4RgRoqoUEmfp6BBYKh2Qx0cfTD2aNCo04znFppJIazV1k24Qt8+9/vHyrjIe +GX3BFBIKvNx+t5zzNLNOo66MVVT5EaGmLy7zMwHRHn75mBLoLv5HOpop3c+evQiz +0POyqjkCgYA2+ql0jS7Qbk7EPyFXftQhHcD/Ld8TKjonShkASoudSEHKwuQGBuit +ftPsg/E5YfhlRpQB6p00kXb4vZsdpFV38eXkyLuLwg0kbpaLedahIujIENNvWP1w +89T/ueiafWPqvwu3M7sAkkd/ReAQ0LcPwrsBHlOk0uujq+WV+b+Xfw== +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.cer b/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.cer new file mode 100644 index 0000000..7bde7b0 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.cer differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.pem b/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.pem new file mode 100644 index 0000000..0dfd1f4 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAfagAwIBAgIJAORglrABpAToMA0GCSqGSIb3DQEBBQUAMDQxMjAwBgNV +BAoTKWF4VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X +DTE2MTIzMDIxMDQyN1oXDTMwMDkwODIxMDQyN1owNDEyMDAGA1UEChMpYXhUTFMg +UHJvamVjdCBEb2RneSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCxIzCSlgeXAiyLWjGWUkuMA+OPJzH23pDcE7Nc +FKhkdzXAD6tBW4odqul7y1g4qU0/xvv16NsK//VTc2VWQwkm0tlQ+0PBMTBRk0Qb +XuLFLjfyYYjUBsde/CE9qhPbhTKYQ5xsnEBm4KUN/Mqk3sKXo7M3s7HjiAeYEIFK +dSFECcljEPrHzAEvDwd0fRsx2hzb4fgrJbfW4wa9rsL1iVQI9VAY8mxM/UMtGySr +L7M7U0RFRM5fK0d5guWH9f+j41hW9R/tYq7qoLcjgcr45nk5bcT4RoTvehhGZRUN +pVq8vttEoR/Y1JvOjBT5WwUSfJcgXtidEWnQPXKszNoLj1sNAgMBAAGjIzAhMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IB +AQByY8+gtxSKO5ASYKArY8Sb4xJw0MNwsosARm17sT/8UTerS9CssUQXkW4LaU3T +SzFVxRUz9O+74yu87W58IaxGNq80quFkOfpS39eCtbqD2e4Y/JuC30hK/GmhBquD +gVh3z3hD8+DUXq83T1+9zgjCppLeQfaFejbaJSwQ7+K6gJn5JZNiaHVGN1GO6lT6 +5W3zqep5zU6a4T5UeZqkYyuzfTBbIkgEga0JzPaCdd5JOrwFR3UNWlICOxr7htDI +FqiTrA0RH2ZNmrmJDcM1pFWlQAPnvDoRLeMpmvWZDnGrWYDzyt0j5G0bIPL7214c +b5kxOvfGlM4E6v+lMSw/HDrI +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509_sha256.pem b/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509_sha256.pem new file mode 100644 index 0000000..0771ca6 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.ca_x509_sha256.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAfagAwIBAgIJAJRCXZlKhZeHMA0GCSqGSIb3DQEBCwUAMDQxMjAwBgNV +BAoTKWF4VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X +DTE2MTIzMDIxMDQyN1oXDTMwMDkwODIxMDQyN1owNDEyMDAGA1UEChMpYXhUTFMg +UHJvamVjdCBEb2RneSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCxIzCSlgeXAiyLWjGWUkuMA+OPJzH23pDcE7Nc +FKhkdzXAD6tBW4odqul7y1g4qU0/xvv16NsK//VTc2VWQwkm0tlQ+0PBMTBRk0Qb +XuLFLjfyYYjUBsde/CE9qhPbhTKYQ5xsnEBm4KUN/Mqk3sKXo7M3s7HjiAeYEIFK +dSFECcljEPrHzAEvDwd0fRsx2hzb4fgrJbfW4wa9rsL1iVQI9VAY8mxM/UMtGySr +L7M7U0RFRM5fK0d5guWH9f+j41hW9R/tYq7qoLcjgcr45nk5bcT4RoTvehhGZRUN +pVq8vttEoR/Y1JvOjBT5WwUSfJcgXtidEWnQPXKszNoLj1sNAgMBAAGjIzAhMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IB +AQAm3qU+APMkgTRCWhw0m4+06gc2iGaf7l+3i/Kg6EvDB9js4cI1sqzRpSdqdjTZ +BwVlIURlB6BnEMCB3hP69IF/oSnqrnIxx2KIeVJt4CCwW1mXKsBwxNMXwHYD3A02 +08eFTRkP0ofn+YBRfUYFkDFebqba4V3NBZtBW497YtQk/ssKAL1xaI0V26M4E/VH +jkJtk99mcMjfuD8HPoqjTeVBGtY2h0A3j2LQPmOJNdSxv30SJuVjvpG7vejQripq +9MW0kPMBIRKhBpUBLIthLLxm/2VBe0IHU34kpe60YpQdJqebbldtOG1Uxe4F2JpN +LfUXs2/UCNpEHS60Xl8UDJXA +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.encrypted.p8 b/circuitpython/lib/axtls/ssl/test/axTLS.encrypted.p8 new file mode 100644 index 0000000..07feaac Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.encrypted.p8 differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.encrypted_pem.p8 b/circuitpython/lib/axtls/ssl/test/axTLS.encrypted_pem.p8 new file mode 100644 index 0000000..bc28403 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.encrypted_pem.p8 @@ -0,0 +1,17 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIICnTAcBgoqhkiG9w0BDAEBMA4ECLZOmsNEeDZnAgIIAASCAnu22JX3BRRr9cTr +j4x62+iDbrqcwmhQkybM1xShFgWObY3/OQf1NJfH4DO4zGQN45ZN0X9zSUVRu8Dd +ycHls5qsROJ96PYQ8d1xnuh1C9TWmFiLieM0qUyn35raHcKPQiBl8PYHtNr3+m0K +bsql6T23hE5ZjVhbRtcRdRd9MsQeTZ6n4mdWPEhzN1+rmSPV8ybCbrtJl3/Dh1v8 +LnswXB92T6WcmHRyRiNsbAXR9SQkOaXFZ/1RUXDNqoRYZjlWPBWdcQf48mzgaDjq +3RXF1mjbOlX2x4/V4qVwH1qZADlT38fSRk/iVdRfureS+wfOuJgJ/g9Riwa0o41K +2q+sOEcTOv4rShXRGp/0ckeuwhARDdSMymlSBhgBWdf14qdgxCx0rAXYlRAc/4Ze +Zl9ErfydwdUfDJoPK+QlGZMF//hFRF+vdO/wJHleLsels4KaqN9v/sB+BrGWaeUC +ScKMISixquCwfWi2qGiqLQGsxHn0d6ejiMblZR4kTf7dcuWVWGXdf5VZqxLNP8Xg +zzjjeP59OxHRVH0ytGBUejTehcxWDKq+6ESAuujzVXa0v1+5QzZXsJ8rPyZOINzj +bdpN4Cr3tZj9ALrNzoC2oG62+OO45U7lg54cV1nyrQ2QiI4XFnt0WA06K1G1JrRW +a/y6nZkntGybbCpuuIBiWl2FfdcTepctiXcJ0vCYqVNOTT4L2Y1RwajDzALhgb7e +wOy0eA8gmOmMLNozSlMV7siL0LeE1WlotLwK+AHMU1lmPMqS7jK9nycXtZyg4IKl +eBAnW052fnKZhT4zNlfJkZqpcp6YWpCU16PWx6L+/FDzFPzswluHyfB72oVqRniI +2A== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_1024 b/circuitpython/lib/axtls/ssl/test/axTLS.key_1024 new file mode 100644 index 0000000..e39791e Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.key_1024 differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_1024.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_1024.pem new file mode 100644 index 0000000..fd8226e --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_1024.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQC9D9RCqHSHVKq5Oh+Lzr23ZftAPdARmpzcgnzqqBfhdPMFDmHB +wXiKsroVIlr/m7h6Lg+It3TeBJmloplTi614WjHtvAHn3+nsL6BdU/bmiqDIbUFF +YyOzz05QHyjfNuJz39ahs0ZPbrsNm++o+UylcaGI3Qephg0/zZkjooR3DwIDAQAB +AoGAJj/slqvUH4kOnTjYJwXlthQI1/9peBZKxAYWVbc6VZ++hvhY6MVGqPDt2ta/ +iFUt5nIpLGTJXR2bJDqYQKHSr1yrI+Qz0OpgUud6nnNfLoDR3G9HD5eANtIwB93W +1xWJK3TVfoq8Y0IK8jEpv/n58IiPisIibhUmt15bWEQcO3kCQQDh8bLlyICTQFB0 +FN2y8idcDD3AX+6cRWwTAN/Q2YP6kCyE8qrC3fvPA0GIEMa7Xre2LqYdqrr7SnLY +mq2IDWoVAkEA1jYj8113yNNJwZP+yg3rm9q9Ryhzl6BQ10wk35sLN67DMbVPYgjK +5e+Xe0Og2isfv6gIk9IWHImZ8d8m0UKZkwJBALFB5H7fIPfk8flP0WotDfHp7Jw6 +5sCUuififLSloSP27eZTVuJQMtgCjuvHdZHTyj7UNCB8K/svOhBysQdWts0CQB47 +8gMNdDSyLbzWyKV4JYMP8psyiG4kQITCyImO9pxbXE2Ny7CIkSq3EGhjeTaR059X +di52/ov0l/fdiTsL7WUCQQC5r78JyZAm83KLv7N8529vW6OVuJ4Duc+gU7oywdOt +hbt5SAnWP5zZN5ERDQTVO8p0XRyRjT3x+Pm+NdeyU1Ad +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_2048 b/circuitpython/lib/axtls/ssl/test/axTLS.key_2048 new file mode 100644 index 0000000..0098987 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.key_2048 differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_2048.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_2048.pem new file mode 100644 index 0000000..5ef719d --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_2048.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA+Vp2PKclcZoKZ3OicQZNA4XpGZbD96Gasb5E66voMPub7l+y +ln6A9CYveBna0i/cQHRCwpYuzzbHQgOjAAw7rcveiIqm8nJMxA8BFNMJCHv0knDl +RT3H28xoTt08Z/MCfCYyOXoVsJOS6BSOSdFVyzhfU6nAie5iskYnmKecmhYaFm94 +S8WWJMNgEvwzPyhdmE4rpqUBHRSu3zPgHUnRRIOfui5KdZGzKpaC+i1Gn58MOC4W +L8kguEMDCEkQD6zxFq0PX5GBgu+zVqCFByX7soxZB027FsmJUN6WNoo3hR/H1QV8 +RdXvgMbT00yymEnYVfn9ZL7nXShKI70Pi5Y11QIDAQABAoIBAQDQQBrrgPUmsW3r +BIowNwDu5lHNizrTf+ZAeBX7dbEP57NNHCN8yN5OCe4vMfis/kfGlNKEzQT/DlLP +8VWa3pyhA9kw1AumBIvUWmuexrmOmmeiPiNc9sIJ8edTpjWi4zO6F/RuSGYA+N8C +cNh9EhXDCaujpewlxjArj6fWOHXzwMewghiGCm/fW0rWri5HCQ7ec+WuHPC2KQGQ +mRDpkXUsxWzTIMIsMKe3M2jYD+pk4xkJqN1+OV/APmQfLyshkGD4EN/qG1dieMQ0 +e85HxxCxbFETOzip0+pHXMbtxY/ok25/SCdtBXkBUJK1KqAysEZdHtOWmmk4HDaz +Dx2PBbKpAoGBAP+BT/WXeVgtOv1idyv9RG34kOJCDaROtVk3g5MNLfj9mIklcwEd +SylhpFxvvrFQAWQIDFPzFkukMs8aIuC0Gm4zxH+8RF45lwhgcXlXP87IiIyW6Bqu +aglmWAM9UHol3/b2AD1UdpqGe0nvWo0rIqs4pdtGTA5BSSUYeaZXhzFDAoGBAPnW +GWqDarzSbZM4TWcrx6O+cjLnstxDW+cgSCIrm9iVq2ys+Hn5O03aN9SsklyGxXgo +ygdGvbYnnPl3ugT139KEiIeUSCBU15WP/NZejpHmtUHduDw1Y6SlBJ9T+p5CSDE+ +2kJoZu1zG7W3eBprZsyqNWtw3Dwc2N+emrF+NF8HAoGBANzErAVFq6if9E+KK/SL +cvwegXmun0DwbUu4ZuzBv45b+NfPzu4QlKgd4TmpqDhnK7x2I8jJyuLy7p/6Mla7 +5/Z+rnO8hcpwsmqfgozY8Z5HsYzgu46KU77penTaHtZcMYefCZf0ikJ8nrzEnxZJ +RjxxxwWPWRocGQp/emVbTconAoGAUClmFkr8YIGULvyNuWDOubdNpQ+6z/m87zfo +bS5Y3vGHA2OshlZ1tNEjwNVuUMndamSMDjGghWXIdDL6OMU7f6yOshHd4qHWWmLM +2WuVizLfTbb6ejcXNajNBuJHM6hIyaRFG7Gr9NxOM8weeTukzF6ArWyU/aSz4Wxe +bjz0SNkCgYBVC0xdMPauqO1Ie/Gp6SPrIx9+bDDlwEvnDki/2RN7z5IkmBnRFxPy +6wqBiMFRxJXI4q3SSSbicb+7TQlK2/Vq/bL6QfjjQM8ZEzpPenYpP/wyMQXdVxfh +1GFDTzeiAhXTvBsZVj8R64VNhNaNn4naMlC4hqxaZ2KA0wrjTRKR0g== +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_4096 b/circuitpython/lib/axtls/ssl/test/axTLS.key_4096 new file mode 100644 index 0000000..df8a8fd Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.key_4096 differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_4096.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_4096.pem new file mode 100644 index 0000000..73fb75f --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_4096.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJJwIBAAKCAgEAwApOo9f0syXI8DmEkP88eHCgZZ8FumcICcqcFe0OywR9UsXU +dQhMqKfMLi8Wlco+rNqFcDfsNyAllCDiq89dp/aNj3inCVAoXnaJuiZQ6dX9UtBR +VEW9cr/z6RjgrZQ9+MkbOx+MXVd44I8jEWVuW2oK1eQzU+FUb12dj45mTaLpL6Bx +XcXGC7e2KSeO75iWwitMyGmJQirV8fttUNa6VfKu7isxESz5jaUmuSsMZIl6Hjm/ +KxmZxkBuFv1Zm2KkKqItV/WqQYCrngil1I5zJLjHWFNjA634U63yWZo5LWQY8pp5 +wy0stC87yJD70rsszjm3zejtXAVipm27+GWe1bKI6UAVfyG3y+bEAKOGc9b6UpUJ +7iRPd32DrZCJ1xubVW3Lx+gK5YILsf7fQARPAbc1KbuJ2GJ2v9ihINzkqyT6N6FJ +ns/BcZnHAXk+KorS03xDMgI/CMKEjoc5YjFY9ioOUvvtpeg2kb0VUqvAHOm4i+DU +f5pQ82uH16tHVk2YyZqNWNVu8cbYsLAKFYPtyur9EO2TeKhCI+vAjl5FNw3TQAjy +1N4P7olDpJh1Vkx5q2fbaQvIq1HMovSmGKKvObXjjAoqlwVaiCukkr/djV1Teu1J +T50aP7tqCOOrBYBaWHO1IOB6xFOSfpAkuZVf4gqHsl2jTiLY6zDhkafJgoECAwEA +AQKCAgAlKVlyZzXY/PTXV6oJjPqcq96+C3nGSm3Jx0VREOCN9L5zqAim5QZAlMf0 +H/SU4+Ag/uBXiNrTCAt9kKeMa8JJ4HIgU06vhK1rKjEYrpV1yo0M23cBgcVZUT/X +2ZKQxGEBpZj5Ze95mJWxjsFQenpSgkC6h0BPeQkny8vTndC6MU5Cgx+s77qVReWg +LSGBx9tUk6B2H8YJ4dQo0Wij/gls3FtxhzYlhrh76nuF1Yi+Y8QX2UDfDEMvlAQ5 +uqj+YqY2AdAYd1eM+WM8X5wHd9FcR817kBdW/PFS8BQ3tppd6ELTn4T0eedurr04 +4KV6b/IJri2dUPetmPUwE4gOV0vW5LP1DSNS+sBD1OrsQ+Ytovht868GLMQ/d6M+ +82IDz2at0lDQ+6JLGBrY2rOXYi22fqGgSg2ErDENgYU1dft1Yc8sAzCTl5WC/Bhg +IxbfUChsYqURvq7faaqVfb50FcMYUcj/rAXVSLOuix2HUgLsQSj2MTtvuR7+BUgh +2KEmiCaMJy6CQyIgtOTjhmPqMr5Se/JYi1SRG0SxZpsYhGRPfjC8jg1k/VmRoAmS +pvqfhqgUMB0vAjfynoxFOZGNZIVrSR+yuC3xaORBW5UAPGvZHS1XzuxdybjpPm74 +0NB1JIc3ylAWcJEWdpnpk8OzZCAhifx0Farrq6Xauk6/ZLtd4QKCAQEA4a0DaHcp +OqFTudM8kC/N21FuE9U5MRLtJ2HP42iTEAfMi1bpZjO35giqYhfxNJiyTPnWDbkS +HVvNuSLAG58/Xs0KTuXCEgWuALBFtgg39BrPTT9Kw2CdqCgIpx5ArBwF+3lDfGIH +lIeoOhR7OKnN8a1/6l7KVOHxV4FMX9aVmom8FKKqjZYcObY86MgLObMtt50v0cKY +GgNZCy1HLoXHRGJ+3pypZEV0qxbOt2jGAhEpDf/LdX9Ez4AIYK16/a5AvUnNJlvN +d28LPgTCvPK8Mhz/m+7ms8IfZ2j0hJgm2j9jiMTK0QvyhWq57TfrU+8HWCKzsUfH +M1Riwt0z8u9HpQKCAQEA2dhE79/lyaGe3lxqJmzxdLG3Khp3wAk4/SM6CP9elN9J +4kg7UFGIE1AUs73HPwlXmoOyE1r+g6W2CaNMds5qqJKOIIS/89mrGZs68hpTLbdR +rTrNNeTLlOQcF/txNfawYEtPwAedjIxUFATKDibbDwfe0p3mRZSm/ji0N3n5ehJl +yDwfaSVsZsoHWm0GUfhMVGwu1OZjAGGpGZIf/tcjMNQ3cKAmqAvRpRrlc51eUw5M ++Z+POgRY2mnrKgTUREFzaLG62umaTVTGC6dn++QLPmFgoFuloSUJNUbRRvIg9d+a +aatn2eiusBILVarQcHGWdysuMFqxUJ9VHQqCNqI4rQKCAQBjPcZF5kEHO3KqQS5c +6ejJDaIurpGb9wq7StQ02QPzBLr6e5ngC9ZPHnhu8sBrtMqT9zoehshkiL6LL7Dz +dLBVbC2gTIFvk3fVba76Qdr5SeDnw3GJQa+TByfm9fLSvPAUilsXE7TpqE5eXCtj +26hpIzchRdYMRd/v7zg63Q6lCvTezjnaUazP5EgcxfvJv/XWzRT+VWi158r8k0i+ +OK5McFQCaTpEkhagNkNpfHW26vz23woF/ZWw+ki02xU/AaYOl6nTuIM+hmKXP1iz +5rrD/uSZGhHx8ugEfa8psA9F4qJOvtvB2lMoQKrKmtCt9GtyYrBKwZnkBLP5pXT2 +3CrRAoIBABiIz/LIH6QezLq0Y8wiFuuSnFNkmboKD94Kmp2qzSctIrAWfH+mPxIV +wc8gf5Es5y3iySp+5A1Fm4PoXVNAGikUIGevK8M175w5rGDZ8CZE8DD3X2dDdl41 +dqiIzA5M0z51HO0+rlLG9y0uAOepHqDJvSGxYN7TSB93mWxqE1vZOJddlhgMe/Hz +rPJVNxICSe50JK4bqGjBlv7nQy07Y547OGc50kC43AqhRdhIj/gAs1Cl1Mau+KbY +qQCZfKKXUH0pDydaieNNueRUHVT0MQP8iZpl1/iXKDtU13sLCAVJAqYGBPM4znvL +/HTQgRs4375aIaCWhkPTPg3AQjwO9x0CggEANIoxDPtty49prkkd8xQQceySEbnf +CeTljNd1uUEqki5DSJMfXajwuSkUrhZAnSevT7k9BjsAzqHM9sWqo3C3PQpFA2Q/ +seTA7lSIxyKvQ4bt/ZaMMeryCzC/WKH81+F35IoQ616nzJz+A7khHX/+l6ZdS9Ud +LYmYUEB1PQVd0PFQQ67dnNCJ265Hi54XLez9rzuYbuNFIb+wg4FsjV8NHUQSMow3 +LQLLMO16nqs9lQA17WdTlhyR6fYrovh6h7puGzONesSF0s9uLSyiOQ9UDKenNPPb +nBdM3Bwq5M72o11IKwTPvq95e09o2eFY0SlqwqLdqeD9lrbh/HWfO9VpWA== +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_aes128.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_aes128.pem new file mode 100644 index 0000000..470f29b --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_aes128.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,7BFA0887B7740C1BBA458D0362E75F89 + +aBIhF2zVGRMFZAWg8s11WnxoTQhGabdzchHBxPltnipEgvwOM9FGmYnVIDsFPvyb +hSA2HgmN972SPeRG4hITzrIXiRZMBOd6Lchz9p2Ui/mqkR6RUfnUBkUtkgxGymSa +oD7WAmbpNG73+7KX4gV36tevC1dM9lQzbClhhXQL9FH9LFh11cS7ZFa9L/esWHbb +sxgicR8zG919UEA+XvhLPVXpYD3AVHTcyEHbPWiGY49SIEI+GOcLi6rvxQizcXKY +pFtmlk/jM06OdZWur5/qLg3HqGP/o8GUjjA6KuAe5SIWVrmlkHCYHj6c1KFLVQJZ +7qAUNvjVaELXOc3+SE64Fl4OMP/4MiUA5WJ+gcdIKFtX/qksjywzF7goNTsxB1ZX +8g9JP6m5BF2VS/Woz+9ypekzk7DEKST4Knh8cYBNdz6yYwX73FBb93jk1aPMXv2K +SzhupTSHyAt7ddvXm+QYXBrklpZgUcuvinrkb7TNYEDcc2h3iDkLMHhI2VW0fiSF +JcL2DZWLu1UChg+Nkc43+9f8Ao76tjJHdV+IkWfINlKz8cpKthIfOiUSQWYK4Czr +0E3dyUrljIqFyKmZGokQ2QH+kdMmcm2/R+8NwL4s0Y4k1ylB0mZ5+A55t0ESaUVC +8NJtoIMrLz2pyhf2ohXMVepcjvR/Id8vNxSlLFResmIwSo4orTZOnsHBlQqm5hJl +9dr8G0o7n7WVfGbHLlpuPHoKegn1OK5xLbDbAi14HnZIi7/lUnbQHMbFFBjyS5EE +v+SMbI7JU+5zeJc34WLUTm1zll1ZNpFH/76vlP7tUWxYqVUZfKYHOndqS4b1rAs2 +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_aes256.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_aes256.pem new file mode 100644 index 0000000..5e9c5fd --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_aes256.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,5AA67B48694516B66EECE19E0F3BB048 + +eXbuyN1kJR84JMhFruS9yeJ/WnyD0V6h9w/6fhEcPfxW0HmFqgIk35IE4c4QYazZ +aMC0J1S19Yb4kKnRd7j0+92IDBw3B7zeJKjPDrcRDSo8R8K7O7+6MYwcmJJ/DZlC +yqcaHr3cJEiS4I8NS3EdffffFA37Uf2O4C26b96ewg899YZXmPtai6uOvKbF1A90 +aRV4PdCpJdJq0q69VfoSeQ5p//Wokb4RfDGWTNxpgclYr0SK2F8qfITjCNDbqR+E +r+6tRsy9VcHVRjswuewU19HOQNQzaPlIiNaoGBGvOVRHLdE0s8b1Czyh3oeuRAZi +EK/SPEdZ5JMWbtxpKi+rdqFZhW3sGE5T9QItYqAWezScOCcuZw7ivVITWj0HuAJl +YZnkL4CS2qMKfQ7oz/YBAuShDvfl/W1M2YXt8caoYIox8NWnGaifHbk+eP7sQRE3 +UMA/71gfz4AOUSKOWTNCen+qeAImyRi++6kFOVyAZnmvGAj1INv76xh6tHP9aDN+ +0ROlEMeL+4EyqEeTeRL5+i9xEGtA247hMjtwB6i8SDl2N9RZkIzGOj6GmJpWQhHK +qRSu+PvoDfSHqfHYXof0rtvCuKj6pAhYgKeL5Ycfc0FtJX6gTvErlKWENUrsJxgV +RJNcRbltxcOylmdYP2tUe/PxQCSFcYIzFbQbXJDoZ9hMgJRv086fzn/QWiZEx59o +9r8kKQrYhKjS34Aq13ghFBf/Mr+GKrB8JtO5DnlC4N9AnapVlDgeZn2NmXyVZygA +mcIq5MTJcZzCdX6PdzNVBsttRfYeItN9M8aP5q5YodBfuLXPOvFhV2J7wc5Bgt4i +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_device.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_device.pem new file mode 100644 index 0000000..5c9a845 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_device.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvV0Pomdmpxx7s19ue0itPlPusWrTSwofoWEU141dp7cS9eXc +SnQV5pfvYvvw21HsZHy+xW2cupjQBzvqPtrrqAz4p2E9VHTMuzvDSScj6GU0BUD+ +GQ3qthLkXMfh7pJZFN5DYtVqzSE+ufZlYlfBqsT1BON9eRs2fTf6OnMFApx0ANjJ +yFElu2cEf3iif/3Z6PF0iUNtKaDNDVvVBoiRa9mUuj4vxnyH4HmyzThp2bXDLMUO +Viz/WWZs9Nl/QoJduyJZGEii1UM5VS81qQnu2dT1g/E0yPXwtOQUnVgjSMPfW+CA +yJ1XTdSwVDSsyXApyxxtSEYbM81t3GGvmmCf+QIDAQABAoIBAFFO4COvmlgu1r6S +P3IYJqsYhukPIWKbGjHE6ZoUTR5ycWW8KPafGbhFjLhHzYeeiY4sMg27nwxQCSLS +CyaqAX3K9AmKqzbUYAQVCSkj8TscGVYYLgK8Awfi3MMp4Ez78dwQA4cwdAdYOwLG +VYoAfFvC7iIHPB0AHklt+7eVI5WWsYlOIf9aS6+PDVii86GVoCpBE0eNZjE3JJo7 +hC0ctcjOqSVZRPC4p5KLFI8QkwyEK3vstyIiQOKSCFbZIn5Wi0+d6A9K96WhwssM +OpmenLv3xgz4zrUkRDbv0cPAU+/e7ZVPCiIbL/Y78qk3lBjUuyztX6fwQ/eDFadw +BS6LcvECgYEA+Nlwgi1Kzcd46xKG7xryI0mYjHO4cbZMsTcB4FQK5xXkGlg6j+WD +NAi/LKDJhaKcBKIYDhYi8tY1ye7JSDmyrPfZ0WvQF8K4yprUAqidNIuwOPMASjTW +CEBgTfMwCATNYNiaQ8eRuTLyknF4I2lrc4Ifby7cYEZrJ6aLGyolvdcCgYEAws4J +rGQS8W1DmzrL9mIDlSUtMFkTWqhx7nvG4lCYWVGpMByiQwf4DRvcqmXhwPr0syaj +qE6nu8G3iuOywSx2qrPX1a6NzeoZZybOSL7poaVmnpxgtS1xXyo1Bdc5ZPPOom1T +apb1QXHIPFVFKsuKsrQvyXfYLFGlQbYh3TGrtq8CgYEAmDqT+95vI0ECNHNp/f0y +4OlVm53y2AUYF1S6Hhvra3/VwVP1xy80uvEa2dcmUEywOplaM8vQ51KpJvWfRkKd +jfg01Eqqys5AsxhR16qEOK+3Rq9InxyBThzrjOPWnyEo7jSy8gG0oGGNSI6HWspT +hB620hINmAub426bLCv1WJMCgYEAkdfBZEAT8o30BH5TfyVIO1v25fB6TfA4Q+yF +LKBcPtqlSPDXBkosClxmq2fVSS5ZDtsJwZMJfsb8C86G4JrSSOCV4VNqtNPjqtdh +rxLHRQ7YsjyvJlVcQHwP8Ex+mrbxZ6djwTQ9b36pA4pvWyfBsiK2eCXyQNPrXjPm +THzIat8CgYAXN7CO+EUKtBil/r3PTj8FpWxvfZiKMbmktiHKD9ntcN3te2hrOWVs +1SmrIzr8/eBIsh7OGS3LUZTb4wKGtY29N6fTHuoA8pYILeRcJALGZnmrsTyFDzGH +iXBSkZ94EXpywxWHAEglow028nQ9UNugKk9SIkpg42u4vrqhRitMqw== +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_end_chain.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_end_chain.pem new file mode 100644 index 0000000..7c1cb6c --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_end_chain.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA7R4S75j5ZfknrzbsAvUnqS997FNk545sGo0YraDQ7CeJXGqe +DyUTpdwtzBt8H8/axNP1BFdgNEWnF1C1HXVbhqWxq16IlakqZYkYldHJMPQgFa3Y +uRN4Y0i8sn8A1Fbe69D//57JZr1wt+qxAJWWn0anPGXmR0HlO0At1ACQkKGSE+aj +TB2TnO7UTsjKRrXPv16FdWTXkJTVHUdVuAs6IfgAKkvQQ5zA8D6IXgjWsToWdFzl +I8eTDHZqZJiw8gPg7xG0jepN9JU05JRc4NduzeVj/0WT0tdilO0jQP/+8FgikdOe +DU6wo4/e0Ta5bdZe7apqOBfdDnq3EUnHO1ZQbQIDAQABAoIBADbu47Yse4L7YQ0/ +rRfWUfTpMsQgYd0far4P+Cqpeh1r32/Qp4OctFuVkeqaZ3w7PFSjQj1aPMh/ZoGJ +ShxkBus/0dSA1yXNBix1wYNcEb9Mn25GU1I1R4vA2y6DK98FrSl2xwgickhiFQ4W +yiD3huiphq8AcIQLqR679KIL63IF+lMnHmYTrm9/rkGvO/wiW55OMhLvhuR4w7/n +5g+PMBLF4vEqtN6wEpb5f3Q8ugNCG35ykpgBMFWI6FGGmcZkYgux+xnTweZ9+Xol +tBQRrq9cY3/ouIrRX4K30e/EcaJN0eA0Cx9WerEHfYO45BWUJGySsxPab9vk6Qep +uxRnHoECgYEA+uv054HQKGQOZPjgZ9lCqfPB4wQ98T4hNSLgNwAkd85D7UtF6Wb9 +GMsEecJ5aPIQjDN6dTT6Nb45AV4e0XWtQFtxHFXP6SKfyIlf0Zcl0cd8Fvt7CX/e +ghZF6ndUxHaWtAltALVwo+Fi6LOgEN7+dsBjkAZf994cZNfqrr6B1s0CgYEA8eqY +u2p/QE7YNfw7naMUKDqgqGzo41IjF915rznYOyuO4hu+zGrL2D+7EeZnLWfSCSxl +t0uowOzDOKkm6XeungMyJFH0DnzhYEgh6K9AXMi3QF0zfgGrh7hhK5wFEt+a4nOY +hIAnqhANqISRhOOd0iT2VIt+igQhEQv8XLjAICECgYAVvkKfmQkfpuP0bfiMJzB2 +p6/Ca0iu0fJwt0/0lCeU1iPeuSoaupjuABGoN2jr5iX28DMJWwjfhVdNPgmvnuHf +dM0NZoY4ro5oAzdxYwac8gtXtn0H6rOuVB3E3ohS6e/PNA3lBNP473vxrDcPnzMv +uSYngdXpFa8iMe+dKtb3dQKBgQCAzse56q+Mvy5yODZJ7f4amXTXmP27pA1ZdKyI +90TB5KR0kg9aanbVUsG5ezNuwrvb9I7INPnKl4Yu0ioM35PTQKJfIl/PowChsmaT +rVSY0qp4E+gJ7Lu3TR44CR/Od87RSnln+5CjBV8wXj3ZQxTSQqoCRDABLseoevhJ +Knnp4QKBgEHHHpegaCXl7+kaPzD/qD38iN6AmoAya9ZUxCUH55bDmkTFu1ZGgA6S +87fuXQ2tzwFyOtaxAftPuOkSKMpZYRPJY92SalHA4WyN1pl0MhWMZQiyKOh0QQ7A +yaHjrLn5wPrhHhkpmYu2L1ZNiN+NIFDuD/j+APCX+wqb9otfbfxk +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_intermediate_ca.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_intermediate_ca.pem new file mode 100644 index 0000000..57fef36 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_intermediate_ca.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzhdv9CgZ895+JuF4J5ttgKS8HDKL5uCAYOS2B+o1OkGzYRkS +I+vA41BpPfE8D8P9lgjcbzAOrOvgYHPZneE3Ix1mhlyPwbnXesC48AahbWXeHFJL +u3Hr3EfjIVngptIHF0/FXmLtOjcxLpP/mXyUTX7bm0NMhgEvxAX34fPfgM4r6AwP +YLwxJGl0c4rrb9choDmXp7+72NnjiO/pXzrUkI0VL+fV6U/cT9ro6p6wJYewvfXA +zqV01B76xf+QhYGp6h/HSZQntTQfA2KIp3H7jhaVXgC/CyyZ/fvx1QUAVCy8pMck +Fs7YuLtVuhAOZ1KpeZzaQotwRjTEeRkF99iCxwIDAQABAoIBAFNxi+O4hOGHuV42 +tjabKNgIWx2znY+KYJBaqhVET+7ZgS6UPxMKNlwTR7lLvjzH5xnjVpUySQ7cpkmH +Ppo9AN0X31YRjicq/sL12ytcE+o+b5LaA03Oz2euN5leUaZZrYNTyh7wQQrsI96v +D7NujIFgFryjoA0118gvfnEfE+SLW5q4m+n7D4cZ2D1nolDnOo2noLhKhMVWT9jp +UVoa5sO+9/Ap71ElAaet2LawNsKbyjjRuI84544G09zQ+YUfcelADaqtXyYZpSJL +iWrmHasD1w8NfiHB84y2hWHySoiuTBfVBJFfTjg075TaxBwCtDbzzEe0ecDCVGnb +gZfkevECgYEA5+5cUFf9LXt7Cwqc/lnuIUYmX7pvTPVVZbdjEzd1MUvu12p01cRN +QYk4K41LZsQYwDrCk82TFn1+hDbVt27i5r4FPJ9GbkSh4AiqUFDkqpqE/U06ZiUX +JOosU6laI6MmguWbXAAQuv2OwK7xVA0575HdbsEK8LRP2bSTRUYNFjkCgYEA43qb +FaKixVC4KOm8dyNYFHB5oldZW0u4ieemum8B+a9wd2BEG8FdxFw6IuGnKyMQ1BWu +NVwN2wZsHbosmCYxGO7cX4OT37711hdCr4pCGQhQ3gf9eNls4ZjjykZp8EHWQnx8 +SYl7sjQMQUjhfqePKwR396IGx4KSrc/l1rxKYP8CgYEAjYPPJ+bIQFw7s30CVeAh +gIQBHh/vkZGQTcQb27nW9AFU9nOqXlSsnvRPJaPNAiNcxs4Ts4OX3/0qmRmsRYSP +RiNjpp24p8eQzdX7tY3mOIKX6saYf4LaIFgSO+n1ahE+ilf296fCjZXw6HjWH2cC +lr710YJQXpZmsnuP8JDRo2ECgYBrasL+5WydZi+ASldPnuYByNb3HO46GTiMDlKB +6Ndy8zBVfqTKwnWnurFNNWc+DHHu5En+Mnjse0zkgLx8IFTA5FI13Ckg18i4jwVT +ZSMvNOkS340G2wz6PrsaEkQGSuCFRsld5Ej/7mn3DhZFO5R0iMipq94tqe/fmbN7 +wjAROwKBgHLl/XNhPTI/ed76ZjmCpbCvQlKZeYLhNbTS4lHvKCuniHKQsPz4BxjB +fuVCUDH61yQT7WM31zIMfzQZjx9hTgFYYvnptRWj9zIBlIZJEieX3//flvEJ3Qmd +/tbSoADa/1y+Y58biKkgmM4f4qS9h0AkVe88OCbpm14Xs2u7/4Nu +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.key_intermediate_ca2.pem b/circuitpython/lib/axtls/ssl/test/axTLS.key_intermediate_ca2.pem new file mode 100644 index 0000000..5a4dbee --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.key_intermediate_ca2.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAqhp+ySEP4Oods+29nF39auqEmJ/qTUqQCz+9iWyOhp6NU5pJ +2LZiQNxVWIzasFHp9I1cvmf+4fnstMpaFl/TtdCpQnuV+eFIe7alEP6+Pc3YiFrO +zyO0XnqJcZwmmkpr5omvGcx9FbcrKflzfgmn4ZvGIdgtwkA+ZAj6WkpZHGGpzqLY +yAFz86fwANeT4I3a90aGwOEo/on+jvJA+O8KARsFx+yspxrfSZtNVTNWFfQfkIIt +7vOWnevZNAEkMnHxY8jDFq8EACNGDo3r0j+G5imRl8P0hdklpN261OS1hANVM3l2 +t2INNN/UkZjJe3/T7RW30A0VZ3Wk/nz3IgKlDwIDAQABAoIBACV6FurrPNtZ2Vd2 +DqtvzdCLgNE7klybC+dekLzBTRl9vzdnK9PyQu11XdxXlCr6sSfvKTrOIMrazHr8 +hiKd1EAfi9sY7W8TYmvXTsDSz0lAm+9Wym+6txeFudhtBdhCg0lUll6BviFVrM3f +psFjETjUoC9+uH4ut1BE5huUe9OTmOXxupLWdETcHViMc2VrpnDsNKX/lFIMFSo7 +3JDVojyTA/xdawJgkksCmQyHLICDvqJrIbLaDKxCfEiMKMyjVqgf9qwR33WAJ73e +ES8XMVtgIce2Zpzx6OITf+gNhS0ekqsxZJ56iiacOVHxpphNKk+BwSj1bBxHLRoo +narBebkCgYEA1BuLsbfr5lXAmGxE4JG1XrOZ7YtTqQNMYzy03s6fndoITqS+YpHk +dtPqM/lQ6qByqLbaPZFVEqecIb9EVRoG1m+9rIkAutiWf/vAWwr7w7yIbFID2YBH +50crmdtbK+1eoml/MkNx2grmgelqtMy5iOzwbPcFzmgXaTBzXvJvZEUCgYEAzU3F +f3QP0xgbrT0iK6138waegsuPaLoBdq+arlZ0LMzuN7T3KTKiNfkJKWbxoaECmu1p +PpJsQpG+0cQxyKU1PK9Pz+9qUXaPf/OsRKTcvpiS2kdBFXLPEgGi2JeSoPZxErYM +WuaqLIM8krYrV0JBRgGv38Pd0u0VaSbQvPx5u0MCgYEAidFoIE6IKf64CJH44w3q +EiGSt8Va06u/+48bWtZY4kEkOq1Sw0tWbltdhu3NRNaCCdvdzDldVKSxjz/vD3i8 +zqKGVNAkOEO47mnO35kwY0tiPTfBJpbyoXUeAHeGMvGmFtODgU5PcMS6Z9kZq2aG +e1CxG6waCraZ15BStnPCKx0CgYA2n7Olhp7TPn3WqQZXcq8QdTlleX2tkpfjGTPh +oNUGOnxDTB3a00L/c0QxxNcTdwB3ciVnZZPyXk7UBwxr4zD39XkZzQyPoijqFU5H +cUneWD/yXbT+XO6lTtQiJqn3s7pADTnaUbcDYuOR8XA0pkcxti8yLS3u+e+Ra6ds +MQy+ewKBgDfHrvBhbxyYskxc/xHnSeAZjrKsKoFNmV3/n9XTmms3WAVoCYydIEou +Pm3p5kDiaiTTqLBpxoa4g2tuaEXBJpgLwxq79Jod4PA1bnip45ERRrk4kRROIaFg +eHV6U0+PQTrdFhiJkvK7CgNZVr+NLiS1V1pM3x7xI81nAV9Sv4c5 +-----END RSA PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.noname.p12 b/circuitpython/lib/axtls/ssl/test/axTLS.noname.p12 new file mode 100644 index 0000000..0383293 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.noname.p12 differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.unencrypted.p8 b/circuitpython/lib/axtls/ssl/test/axTLS.unencrypted.p8 new file mode 100644 index 0000000..df7c2e2 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.unencrypted.p8 differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.unencrypted_pem.p8 b/circuitpython/lib/axtls/ssl/test/axTLS.unencrypted_pem.p8 new file mode 100644 index 0000000..dee0ed4 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.unencrypted_pem.p8 @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL0P1EKodIdUqrk6 +H4vOvbdl+0A90BGanNyCfOqoF+F08wUOYcHBeIqyuhUiWv+buHouD4i3dN4EmaWi +mVOLrXhaMe28Aeff6ewvoF1T9uaKoMhtQUVjI7PPTlAfKN824nPf1qGzRk9uuw2b +76j5TKVxoYjdB6mGDT/NmSOihHcPAgMBAAECgYAmP+yWq9QfiQ6dONgnBeW2FAjX +/2l4FkrEBhZVtzpVn76G+FjoxUao8O3a1r+IVS3mciksZMldHZskOphAodKvXKsj +5DPQ6mBS53qec18ugNHcb0cPl4A20jAH3dbXFYkrdNV+irxjQgryMSm/+fnwiI+K +wiJuFSa3XltYRBw7eQJBAOHxsuXIgJNAUHQU3bLyJ1wMPcBf7pxFbBMA39DZg/qQ +LITyqsLd+88DQYgQxrtet7Yuph2quvtKctiarYgNahUCQQDWNiPzXXfI00nBk/7K +Deub2r1HKHOXoFDXTCTfmws3rsMxtU9iCMrl75d7Q6DaKx+/qAiT0hYciZnx3ybR +QpmTAkEAsUHkft8g9+Tx+U/Rai0N8ensnDrmwJS6J+J8tKWhI/bt5lNW4lAy2AKO +68d1kdPKPtQ0IHwr+y86EHKxB1a2zQJAHjvyAw10NLItvNbIpXglgw/ymzKIbiRA +hMLIiY72nFtcTY3LsIiRKrcQaGN5NpHTn1d2Lnb+i/SX992JOwvtZQJBALmvvwnJ +kCbzcou/s3znb29bo5W4ngO5z6BTujLB062Fu3lICdY/nNk3kRENBNU7ynRdHJGN +PfH4+b4117JTUB0= +-----END PRIVATE KEY----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.withCA.p12 b/circuitpython/lib/axtls/ssl/test/axTLS.withCA.p12 new file mode 100644 index 0000000..0a89e73 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.withCA.p12 differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.withoutCA.p12 b/circuitpython/lib/axtls/ssl/test/axTLS.withoutCA.p12 new file mode 100644 index 0000000..10e28fa Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.withoutCA.p12 differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024.cer b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024.cer new file mode 100644 index 0000000..784e26f Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024.cer differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024.pem new file mode 100644 index 0000000..0a5c7a6 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQClKsh4h/LnxTANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjdaFw0zMDA5MDgyMTA0MjdaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAvQ/UQqh0h1SquTofi869t2X7QD3QEZqc3IJ86qgX4XTzBQ5hwcF4irK6FSJa +/5u4ei4PiLd03gSZpaKZU4uteFox7bwB59/p7C+gXVP25oqgyG1BRWMjs89OUB8o +3zbic9/WobNGT267DZvvqPlMpXGhiN0HqYYNP82ZI6KEdw8CAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAMuA8biHmpvS4EJ+K5guETizlFMpWgT/ALKM5iSTOr0cuGWKy +5HaRJbzhqO5qaDp3ubJilwwlPF4TSIeAo5HZLuaSKxxSJLF3xvbe2JvZVzdWaBcy +ZgEIOAiawYxeP+fJRMtiuUjHiab/jn094UYynBMGmtEXqz+pkAQzLT+BCqVVzraV +VK3xT6LKw/Yle3HSaIXpcraZNG3lX/Z0HLmi2isE/4LFCQTEuryCPrRyGI4waEhK +Dac9tfRCOpdgfahhip6YxH5lmep+ynXn2yFdznxmPX7cFP5VBJeoZBK0tTBIcrzb +61tPpvuHAUGR7JiY8Us4okDxBZC7m12WsSJrUA== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha256.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha256.pem new file mode 100644 index 0000000..b1059b4 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha256.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQClKsh4h/LnxjANBgkqhkiG9w0BAQsFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjdaFw0zMDA5MDgyMTA0MjdaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAvQ/UQqh0h1SquTofi869t2X7QD3QEZqc3IJ86qgX4XTzBQ5hwcF4irK6FSJa +/5u4ei4PiLd03gSZpaKZU4uteFox7bwB59/p7C+gXVP25oqgyG1BRWMjs89OUB8o +3zbic9/WobNGT267DZvvqPlMpXGhiN0HqYYNP82ZI6KEdw8CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAbpbFPGnc74yvFgxKiNGA8+9azns10+KionRirc6g/1X1zBnJ +7vBXW9aXwUr2y9G3jnmX82eut0YnaJ3xlU5rp2NbGSH43fQd/OvWC+6yDFBeHfJG +JqbyP9oBkrUSuaXO/svsGUr8z1YVnxvtN7A1NGt+xQmgTyNq2QWg3MSQQwVtNsQt +84mQqU0BmmyRyi14LOCi2dHxjduXFVgHIcM6XzVL8lxQ1oaabA1mP5u8dzH+n+sT +uVDMmn6ABDZsnnCo9i7WidPI8pfJ4k6xR5l0wUdcOQeY8ynwUmILBt7lhKhxtAIG +j9SHuiQYstmr5+6wIBv6LRwjuXNDEwcqdT+o1g== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha384.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha384.pem new file mode 100644 index 0000000..cbdca1d --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha384.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQClKsh4h/LnxzANBgkqhkiG9w0BAQwFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjdaFw0zMDA5MDgyMTA0MjdaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAvQ/UQqh0h1SquTofi869t2X7QD3QEZqc3IJ86qgX4XTzBQ5hwcF4irK6FSJa +/5u4ei4PiLd03gSZpaKZU4uteFox7bwB59/p7C+gXVP25oqgyG1BRWMjs89OUB8o +3zbic9/WobNGT267DZvvqPlMpXGhiN0HqYYNP82ZI6KEdw8CAwEAATANBgkqhkiG +9w0BAQwFAAOCAQEAcVYgGWa/OFtWSpsH55h4iHan1Hj8WMzhvczirWDP8EaG3N1P +WVo7LQdfhs9OvQwLlacAym3eawwsMe7ODU6Iq2vsbajeKMuF0jb5teghb7dMIiIW +UIy3zRe9pmOZZpIcwJfuzTMTXMq+UksNfSzgB8mGqnIj+4D3UPXce5KYMvxzAjYU +HAAFR9+ZkTdpratH/qFlk14DJ4CKlH69/RUpekkXcn3lk1DutfQ15kaTnaFObTUs +HvGr2pX5PsofeR7DW4NStIMbOwMvTby6thCw8zImI2yyouCv+LkilGxmxEMAV85X +ZKu5dNZXbJwfOFjkmHEtDfmISsdl8NoQxyz55A== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha512.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha512.pem new file mode 100644 index 0000000..83648e6 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_1024_sha512.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQClKsh4h/LnyDANBgkqhkiG9w0BAQ0FADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjdaFw0zMDA5MDgyMTA0MjdaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAvQ/UQqh0h1SquTofi869t2X7QD3QEZqc3IJ86qgX4XTzBQ5hwcF4irK6FSJa +/5u4ei4PiLd03gSZpaKZU4uteFox7bwB59/p7C+gXVP25oqgyG1BRWMjs89OUB8o +3zbic9/WobNGT267DZvvqPlMpXGhiN0HqYYNP82ZI6KEdw8CAwEAATANBgkqhkiG +9w0BAQ0FAAOCAQEAbrG+mMdCorMaq6VHQC071CdXzqdUGFgXM/qpVjNo3tKjqUbD +73FJOYYoSgXO7aJPebraaZTdSpgHO2vdJrifUjrJg+2RKDwIzCP853fgi3Nm4n+R +7uDsd6K/cj4xvcnhIdmQZC3TPIJFujjbMy0Tw9EQ5Zoz5rNwR0Oy++HtWoULOjTe +xsVsagshFaGajLF6RXoH+caKHIi4HANlWwJvHCBpqQYUyhUCAHUm9Pdo0+h7Viuj +evzm3SPr5rOisE8xTDU4WPOhwel3lggZWfh6nbDG7+1sWmT4qTtAkv3V1m1o1h+8 +4TeJUOV9QHm88a2UUqWIZocaLxPYB6NThoBNVg== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_2048.cer b/circuitpython/lib/axtls/ssl/test/axTLS.x509_2048.cer new file mode 100644 index 0000000..45a2912 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.x509_2048.cer differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_2048.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_2048.pem new file mode 100644 index 0000000..95bdb5a --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_2048.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3DCCAcQCCQClKsh4h/LnyTANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjdaFw0zMDA5MDgyMTA0MjdaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAPladjynJXGaCmdzonEGTQOF6RmWw/ehmrG+ROur6DD7m+5fspZ+gPQm +L3gZ2tIv3EB0QsKWLs82x0IDowAMO63L3oiKpvJyTMQPARTTCQh79JJw5UU9x9vM +aE7dPGfzAnwmMjl6FbCTkugUjknRVcs4X1OpwInuYrJGJ5innJoWGhZveEvFliTD +YBL8Mz8oXZhOK6alAR0Urt8z4B1J0USDn7ouSnWRsyqWgvotRp+fDDguFi/JILhD +AwhJEA+s8RatD1+RgYLvs1aghQcl+7KMWQdNuxbJiVDeljaKN4Ufx9UFfEXV74DG +09NMsphJ2FX5/WS+510oSiO9D4uWNdUCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +HKqK24TYW7NvGoIifLaFyaSwAQV/OODpiZmTie3X5RBHR34v9fnBk5qnBf7EZEfC +uMg/mdMQm2Fst4uBzx9q8PltfcmCaX+/1M0F5nzhEszJ3cDevMBexNl7Q4nfYNTN +QShJyhSgr9cQ/K48k9IA64RRcRP9DWtSNzt0zzA4UCqlkBvKd6TdcC+rAzOigdhT +z0e1a9KVfKSxtXxyCAQZyKdsfWlhVyXPWd2urd8IfLfHdiFMKwyyreCCc4tCDjcA +QcJkv2bfL8Cb4cUd2vtI8kic9zUBFaOWyz9tOicGG2k3SBjN99iQfBAsqbHjtGnj ++dKbDCxXy4udsNINgfE3aA== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_4096.cer b/circuitpython/lib/axtls/ssl/test/axTLS.x509_4096.cer new file mode 100644 index 0000000..f90fb1c Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.x509_4096.cer differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_4096.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_4096.pem new file mode 100644 index 0000000..e6aaf25 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_4096.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID3DCCAsQCCQClKsh4h/LnyjANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjdaFw0zMDA5MDgyMTA0MjdaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC +AgoCggIBAMAKTqPX9LMlyPA5hJD/PHhwoGWfBbpnCAnKnBXtDssEfVLF1HUITKin +zC4vFpXKPqzahXA37DcgJZQg4qvPXaf2jY94pwlQKF52ibomUOnV/VLQUVRFvXK/ +8+kY4K2UPfjJGzsfjF1XeOCPIxFlbltqCtXkM1PhVG9dnY+OZk2i6S+gcV3Fxgu3 +tiknju+YlsIrTMhpiUIq1fH7bVDWulXyru4rMREs+Y2lJrkrDGSJeh45vysZmcZA +bhb9WZtipCqiLVf1qkGAq54IpdSOcyS4x1hTYwOt+FOt8lmaOS1kGPKaecMtLLQv +O8iQ+9K7LM45t83o7VwFYqZtu/hlntWyiOlAFX8ht8vmxACjhnPW+lKVCe4kT3d9 +g62Qidcbm1Vty8foCuWCC7H+30AETwG3NSm7idhidr/YoSDc5Ksk+jehSZ7PwXGZ +xwF5PiqK0tN8QzICPwjChI6HOWIxWPYqDlL77aXoNpG9FVKrwBzpuIvg1H+aUPNr +h9erR1ZNmMmajVjVbvHG2LCwChWD7crq/RDtk3ioQiPrwI5eRTcN00AI8tTeD+6J +Q6SYdVZMeatn22kLyKtRzKL0phiirzm144wKKpcFWogrpJK/3Y1dU3rtSU+dGj+7 +agjjqwWAWlhztSDgesRTkn6QJLmVX+IKh7Jdo04i2Osw4ZGnyYKBAgMBAAEwDQYJ +KoZIhvcNAQEFBQADggEBABPkfLZVIJ5z5cIhmiN5yqjMKotzGMwi7ihiPx8YSgBc +2grI7Aqyojn/gPBTvKXGRYCGC7aXIBo69RlbnZy0VW1fLqoNo8y6+zLiryCtxsv6 +3orQmHslh2WofzzhkNyazT3WoGvzV4qhzK5KU7vkrFpHcwiLFRglBMP4ruoOq8jY +4wKDrP3FpgaSpY4NOm7ro7LiYzmVcj6A9Gci6mm55er6ZGX0yI9O1FXOZCxABPJF +kDEAk4GQScbaEDBZWjFAhkmdwYnE3n6usPnURwp08vDRkd4bGdrMT2KtP5ASNigQ +vEaYj2pQJLS8Eljwc6nEBeGrZ14fGXXaVh+p9TKrpM8= +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_aes128.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_aes128.pem new file mode 100644 index 0000000..1eeb601 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_aes128.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQClKsh4h/Ln0DANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjhaFw0zMDA5MDgyMTA0MjhaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEA8k4Lr67fner/JtPfbCJe9+RMyq4ErKmXDlxQnXDEcvn/7Mw/CcNQXDPDRTN2 +/pw0Cwb45Pgv0bqTAFPK2sWhp68QMiuyl+lIUGSrgXX69nW7B2cAp4YSNW55M8SQ +EISL3QOkzl1oHW3iuxxGeuCGuVv0i4gRxhQ1XkHdoGOc4G0CAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAPbTh7YlIYA/XOKC1Laf0SQ0HQU4hC9rd1IowBIyKYT5YlKVM +VIrmqN7B3ytUZbP3eL9ZO63G5NHmGk/i+RpxF+O0oX09uhIPWHlupZ1LeEHDwsSG +5OjZ1scU0bbIX/aBNPDL8hU7/TSTtL7NY9939cHE5LVwdSuOqndXl5nPFKxyJjfB +npworzs+UUwXLAcJSRHTruyRf6fvSfl1NdMabWiR/L7+tzDV0842+HwUsJLUlWFv +osK0avS8ER8PrFMRnKqGIK416B38ZMjn65G/J5v1j/RSHDAWjp+SYAFHaxiU0gEk +WOAZlVmG1vVlFk/ubTJ/vd+RAk0QYI+THgwlbQ== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_aes256.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_aes256.pem new file mode 100644 index 0000000..89fe526 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_aes256.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQClKsh4h/Ln0TANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjhaFw0zMDA5MDgyMTA0MjhaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAqn/ZBpw3WLD87W/rVp8rdvg2yoml5CSMfePkcXKCfbWMAkZOJJtMupPoMFC9 +CbQ5EUmSV47BHGTh0xnQK/4s4bc6lPVtkK7dJtFfonCsiTErW0p6z0q7tQfWFEd3 +NGNFv/qVIsB0hJDOJn8x30wYWCOY+gC+53KJzRVcRMoM75sCAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAqI4YkmyznQ9lE0+2cSkRX7ELJeKGedGFCCKJZaee5k9R4PBc +fg97WsEMARSl2WLzAkK3rjSQWslbRxb/u1NYhd2uBdrYGIMXgPyBIjV7sSoI0TkC +3muhke+W2yZsVp55DoJpfsX9dIfzbM0ICbaD509xuClfraIafO/6VLrw/+BzTTVM +DECTo1dCheYYXyOJPgdgdcABKKb3WkTLJPkV6SCK0D8xAHpTRR8AtT0xu60JDRoq +wcKZie02AXOgg3mEQPdvmVDb+cgOL2Cb/nyraS2OVKPRTZfQfvhve0mU3DN/TVDB +7N9bVd1WNst+bsNIE0SbnYiF/oSdnHGNQxaLGA== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_bad_after.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_bad_after.pem new file mode 100644 index 0000000..c90d630 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_bad_after.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQClKsh4h/Ln0zANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjEy +MzAyMTA0MjhaFw0xNTEyMzEyMTA0MjhaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAvQ/UQqh0h1SquTofi869t2X7QD3QEZqc3IJ86qgX4XTzBQ5hwcF4irK6FSJa +/5u4ei4PiLd03gSZpaKZU4uteFox7bwB59/p7C+gXVP25oqgyG1BRWMjs89OUB8o +3zbic9/WobNGT267DZvvqPlMpXGhiN0HqYYNP82ZI6KEdw8CAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAqk3O/LBqyketDzFqMe7L8nqmM/crpmjZ93KEwhrc7uRKJgXm +CjfTSm7D43l4xbz/NbHnNvSFnblFoioAQP23opotJV/WutmrGCIjpidLc682GvcP +DvhlOTAqoVFFWmjL6gj2iKEtIUzxCMI7K/h/znQvk/NrsfvOF0uZtpMoLqqo4o3Y +V2vogbTEPpr77952JMpsLvJYatwiYo8G7Pc8qdl86mk3tx1Kqn/Pl9CgMgj8tgFi +tcBRFePe3WvAiK7vnSqz7H4NUXrcv0RTA7f/bUXNWoRUI98GbYKVpxgIY7uFmLF8 +0jb92pWMlA9Ps0fAdMKs98c7dIaJi0buM5Mtuw== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_bad_before.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_bad_before.pem new file mode 100644 index 0000000..3d65fe6 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_bad_before.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQClKsh4h/Ln0jANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yNDEy +MzExNDAwMDBaFw0yNTEyMzExNDAwMDBaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAvQ/UQqh0h1SquTofi869t2X7QD3QEZqc3IJ86qgX4XTzBQ5hwcF4irK6FSJa +/5u4ei4PiLd03gSZpaKZU4uteFox7bwB59/p7C+gXVP25oqgyG1BRWMjs89OUB8o +3zbic9/WobNGT267DZvvqPlMpXGhiN0HqYYNP82ZI6KEdw8CAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEALWtzVdl7s7NHPKslDc0NN2N/kqd8V5Ug93s9POLPQV6Cq7fH +WPzxdU/IcLwocngqDzYEADlKJL1prRIP7IEtclRW109kVf5ge4waL7BIFogX0iII +WzjSlLTdYFo6ZK/oxwg86+zVA9UbkWbvQwSGE60Hqr8GEaqon09CxYUpFTtOq7qZ +Ikjjf1Rz/t1AAGXoN2Yls1hm2ONYFuxQq+dBME0sSL7hdhwFoOi/u3Q0QXmg4Z1Y +xe0J3Pg1mt5nsh4cY0QDNZdSbZz1p4jVY5RxQsoYzgyVYQWBeDJGKs2RN8o1CFko +EMQ4Bq65fSUs5hPnYGl4iibWmQQgAWkasKZwaw== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_device.cer b/circuitpython/lib/axtls/ssl/test/axTLS.x509_device.cer new file mode 100644 index 0000000..1dc36cd Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/axTLS.x509_device.cer differ diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_device.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_device.pem new file mode 100644 index 0000000..2ecdabe --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_device.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIICUjCCAbsCCQClKsh4h/LnyzANBgkqhkiG9w0BAQUFADAsMRYwFAYDVQQKEw1h +eFRMUyBQcm9qZWN0MRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTYxMjMwMjEwNDI3 +WhcNMzAwOTA4MjEwNDI3WjArMSkwJwYDVQQKEyBheFRMUyBQcm9qZWN0IERldmlj +ZSBDZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1d +D6JnZqcce7NfbntIrT5T7rFq00sKH6FhFNeNXae3EvXl3Ep0FeaX72L78NtR7GR8 +vsVtnLqY0Ac76j7a66gM+KdhPVR0zLs7w0knI+hlNAVA/hkN6rYS5FzH4e6SWRTe +Q2LVas0hPrn2ZWJXwarE9QTjfXkbNn03+jpzBQKcdADYychRJbtnBH94on/92ejx +dIlDbSmgzQ1b1QaIkWvZlLo+L8Z8h+B5ss04adm1wyzFDlYs/1lmbPTZf0KCXbsi +WRhIotVDOVUvNakJ7tnU9YPxNMj18LTkFJ1YI0jD31vggMidV03UsFQ0rMlwKcsc +bUhGGzPNbdxhr5pgn/kCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBX+beg1jGMSqQd +6Q/d07mQCLuEwmXmmz7hc0lgp6IumjsxulO2xLiotXie7e3GIRAVgJsd6ysRJKim +IioOMxcwUMWw0CcqjcwqorczJjsqzW99dzCd3NcDiDxx+7Pye58D8qOLHGtafC9n +TjQELV6dNIUX5IfH/18jAkPEmFcOUg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDDjCCAfagAwIBAgIJAORglrABpAToMA0GCSqGSIb3DQEBBQUAMDQxMjAwBgNV +BAoTKWF4VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X +DTE2MTIzMDIxMDQyN1oXDTMwMDkwODIxMDQyN1owNDEyMDAGA1UEChMpYXhUTFMg +UHJvamVjdCBEb2RneSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCxIzCSlgeXAiyLWjGWUkuMA+OPJzH23pDcE7Nc +FKhkdzXAD6tBW4odqul7y1g4qU0/xvv16NsK//VTc2VWQwkm0tlQ+0PBMTBRk0Qb +XuLFLjfyYYjUBsde/CE9qhPbhTKYQ5xsnEBm4KUN/Mqk3sKXo7M3s7HjiAeYEIFK +dSFECcljEPrHzAEvDwd0fRsx2hzb4fgrJbfW4wa9rsL1iVQI9VAY8mxM/UMtGySr +L7M7U0RFRM5fK0d5guWH9f+j41hW9R/tYq7qoLcjgcr45nk5bcT4RoTvehhGZRUN +pVq8vttEoR/Y1JvOjBT5WwUSfJcgXtidEWnQPXKszNoLj1sNAgMBAAGjIzAhMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IB +AQByY8+gtxSKO5ASYKArY8Sb4xJw0MNwsosARm17sT/8UTerS9CssUQXkW4LaU3T +SzFVxRUz9O+74yu87W58IaxGNq80quFkOfpS39eCtbqD2e4Y/JuC30hK/GmhBquD +gVh3z3hD8+DUXq83T1+9zgjCppLeQfaFejbaJSwQ7+K6gJn5JZNiaHVGN1GO6lT6 +5W3zqep5zU6a4T5UeZqkYyuzfTBbIkgEga0JzPaCdd5JOrwFR3UNWlICOxr7htDI +FqiTrA0RH2ZNmrmJDcM1pFWlQAPnvDoRLeMpmvWZDnGrWYDzyt0j5G0bIPL7214c +b5kxOvfGlM4E6v+lMSw/HDrI +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_end_chain.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_end_chain.pem new file mode 100644 index 0000000..c0a4eb3 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_end_chain.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJDCCAgygAwIBAgIJAKUqyHiH8ufOMA0GCSqGSIb3DQEBCwUAMCgxJjAkBgNV +BAoTHWF4VExTIFByb2plY3QgSW50ZXJtZWRpYXRlIENBMB4XDTE2MTIzMDIxMDQy +OFoXDTMwMDkwODIxMDQyOFowLDEWMBQGA1UEChMNYXhUTFMgUHJvamVjdDESMBAG +A1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +7R4S75j5ZfknrzbsAvUnqS997FNk545sGo0YraDQ7CeJXGqeDyUTpdwtzBt8H8/a +xNP1BFdgNEWnF1C1HXVbhqWxq16IlakqZYkYldHJMPQgFa3YuRN4Y0i8sn8A1Fbe +69D//57JZr1wt+qxAJWWn0anPGXmR0HlO0At1ACQkKGSE+ajTB2TnO7UTsjKRrXP +v16FdWTXkJTVHUdVuAs6IfgAKkvQQ5zA8D6IXgjWsToWdFzlI8eTDHZqZJiw8gPg +7xG0jepN9JU05JRc4NduzeVj/0WT0tdilO0jQP/+8FgikdOeDU6wo4/e0Ta5bdZe +7apqOBfdDnq3EUnHO1ZQbQIDAQABo00wSzAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB +/wQEAwIF4DArBgNVHREEJDAigg93d3cuZXhhbXBsZS5uZXSCD3d3dy5leGFtcGxl +Lm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAbPQ1Y205Ricl1K2ByVa2RHJyYGP0Qj+H +5mWj4A92N1vAb6uOrliqFYOClYINGsKKC8YDZdyA4c8ZglCKZ2RePwOSdaWIw7wi +Efhysyq3WLSlo5jEcnkO7o5dV/7V7FX/+65UEXu35ZqaE8ZY++eotmLzccnInYP3 +1e4oaF5hyZIHVNCXnywNvchSkXjN0HhvIpeLTyzC5MQkQMMEOi8EBOgTGAo4UvL9 +eau3YhhpvfnCDlrRB6N79RcTLmJyOj5g1YO/9wn/du+EMwEkKUg5QJHzwUB2+ISp +57JjKh2BQt0g/XJfRugHQcNtjUu73Ziexpl0qaXjNjb8mvsuV9RX0g== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_end_chain_bad.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_end_chain_bad.pem new file mode 100644 index 0000000..743dbc0 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_end_chain_bad.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAg6gAwIBAgIJAKUqyHiH8ufPMA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV +BAoTH2F4VExTIFByb2plY3QgSW50ZXJtZWRpYXRlIDIgQ0EwHhcNMTYxMjMwMjEw +NDI4WhcNMzAwOTA4MjEwNDI4WjAsMRYwFAYDVQQKEw1heFRMUyBQcm9qZWN0MRIw +EAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDtHhLvmPll+SevNuwC9SepL33sU2TnjmwajRitoNDsJ4lcap4PJROl3C3MG3wf +z9rE0/UEV2A0RacXULUddVuGpbGrXoiVqSpliRiV0ckw9CAVrdi5E3hjSLyyfwDU +Vt7r0P//nslmvXC36rEAlZafRqc8ZeZHQeU7QC3UAJCQoZIT5qNMHZOc7tROyMpG +tc+/XoV1ZNeQlNUdR1W4Czoh+AAqS9BDnMDwPoheCNaxOhZ0XOUjx5MMdmpkmLDy +A+DvEbSN6k30lTTklFzg127N5WP/RZPS12KU7SNA//7wWCKR054NTrCjj97RNrlt +1l7tqmo4F90OercRScc7VlBtAgMBAAGjTTBLMAwGA1UdEwEB/wQCMAAwDgYDVR0P +AQH/BAQDAgXgMCsGA1UdEQQkMCKCD3d3dy5leGFtcGxlLm5ldIIPd3d3LmV4YW1w +bGUub3JnMA0GCSqGSIb3DQEBCwUAA4IBAQBGJydzARx5fNYprptRG9c3pqecGKlX +ArxbLe+K+83wS427HnWONnuZ5LJKGkuXjIeh1G/2AfKYXJz/SMN0IPYY3ro5Lt1Z +GOPyn01qcj6OkfyiUPCDIsVFS9V0TVLTBLTMZFa1j6nMHs8Ajmm10Fkf/NQP/CVk +zEgoktjb+wLqw1iPUGqkVepVtp3wg7VQY6E07SliNp/06Q3ue6xLJnYlKqFhUQf7 +064JyRIH9W/C2WnxWbKRBjsE4gCRnMvKQrCrfR64VohCr6XvygIIufwCG/CLJogn +4OJMqz1oDkABPgSgjNhOdwnt+3dvxbjQBiRy1ERfNAJLo+V6x6aO1Gqz +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_intermediate_ca.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_intermediate_ca.pem new file mode 100644 index 0000000..4fbad81 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_intermediate_ca.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAjCCAeqgAwIBAgIJAKUqyHiH8ufMMA0GCSqGSIb3DQEBCwUAMDQxMjAwBgNV +BAoTKWF4VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X +DTE2MTIzMDIxMDQyN1oXDTMwMDkwODIxMDQyN1owKDEmMCQGA1UEChMdYXhUTFMg +UHJvamVjdCBJbnRlcm1lZGlhdGUgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDOF2/0KBnz3n4m4Xgnm22ApLwcMovm4IBg5LYH6jU6QbNhGRIj68Dj +UGk98TwPw/2WCNxvMA6s6+Bgc9md4TcjHWaGXI/Budd6wLjwBqFtZd4cUku7cevc +R+MhWeCm0gcXT8VeYu06NzEuk/+ZfJRNftubQ0yGAS/EBffh89+AzivoDA9gvDEk +aXRziutv1yGgOZenv7vY2eOI7+lfOtSQjRUv59XpT9xP2ujqnrAlh7C99cDOpXTU +HvrF/5CFganqH8dJlCe1NB8DYoincfuOFpVeAL8LLJn9+/HVBQBULLykxyQWzti4 +u1W6EA5nUql5nNpCi3BGNMR5GQX32ILHAgMBAAGjIzAhMBIGA1UdEwEB/wQIMAYB +Af8CAQAwCwYDVR0PBAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAYt1Wq1XsZjOWf +mH9XzI3k8UEtErTkBX5SXH10siY5tYmHzH02jaZVRC1yNrxQevqARhR1yj3daKg3 ++innX8foKlYRCxTfFeE/HELcm7rIt5mrIGdGAFn2fnImO5kpXxbPk6IAXRTp6lN8 +QS08Ah1Aaeh0ae2Ruzx2TOnG/IuB7ChliJxepo0KtRw6RN6ETvC2KS0glSf5fPW7 +c18UPbTesecrki12FlaGbPD/sWHOltBIpPXzgef7G8b6CiYqaX0T3T/47RLRwrMm +SAcbMerJZoyudbLd+OHGtvz5kOmYCoZYkay121MSvtFucHnR3UjEui2lUbL1Qi92 +2L3MUIVn +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/axTLS.x509_intermediate_ca2.pem b/circuitpython/lib/axtls/ssl/test/axTLS.x509_intermediate_ca2.pem new file mode 100644 index 0000000..ea8ab7d --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/axTLS.x509_intermediate_ca2.pem @@ -0,0 +1,37 @@ +-----BEGIN CERTIFICATE----- +MIIC+TCCAeGgAwIBAgIJAKUqyHiH8ufNMA0GCSqGSIb3DQEBCwUAMCgxJjAkBgNV +BAoTHWF4VExTIFByb2plY3QgSW50ZXJtZWRpYXRlIENBMB4XDTE2MTIzMDIxMDQy +N1oXDTMwMDkwODIxMDQyN1owKjEoMCYGA1UEChMfYXhUTFMgUHJvamVjdCBJbnRl +cm1lZGlhdGUgMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKoa +fskhD+DqHbPtvZxd/WrqhJif6k1KkAs/vYlsjoaejVOaSdi2YkDcVViM2rBR6fSN +XL5n/uH57LTKWhZf07XQqUJ7lfnhSHu2pRD+vj3N2Ihazs8jtF56iXGcJppKa+aJ +rxnMfRW3Kyn5c34Jp+GbxiHYLcJAPmQI+lpKWRxhqc6i2MgBc/On8ADXk+CN2vdG +hsDhKP6J/o7yQPjvCgEbBcfsrKca30mbTVUzVhX0H5CCLe7zlp3r2TQBJDJx8WPI +wxavBAAjRg6N69I/huYpkZfD9IXZJaTdutTktYQDVTN5drdiDTTf1JGYyXt/0+0V +t9ANFWd1pP589yICpQ8CAwEAAaMkMCIwEgYDVR0TAQH/BAgwBgEB/wIBCjAMBgNV +HQ8EBQMDBwWAMA0GCSqGSIb3DQEBCwUAA4IBAQBNWDjqxlO0BwMdyxfUs1wDsLiq +4hOmUFwCv8TuTFsL9aNe7OIJRT8IF2pHw07qyvAxJVEWUCLK/KLq0HrRTzRZO/tK +eNroHMHS+fBwFuHFp+1RGMK2rHLajxVVB6X0aeLWKrNKrvUQZL+Tx+NZ3dEO62rq +rANnElCrnyI1bIBKwHdUbOMOHeZAECr7H0KfvaX8F67aln4IwPzCauQM3DFf9h9Z +FvmxUdVgjRZK4e5he9k4gT/Faom0z/ApnW4DJRF8rpCPWqN872aNpL8NPZuOFtiD +Gzg5O4wJYx7OWIPa/qcQ0hTbn5waPzC68X448tlJTPiwyeKsYT3JwWqLi6o5 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDAjCCAeqgAwIBAgIJAKUqyHiH8ufMMA0GCSqGSIb3DQEBCwUAMDQxMjAwBgNV +BAoTKWF4VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X +DTE2MTIzMDIxMDQyN1oXDTMwMDkwODIxMDQyN1owKDEmMCQGA1UEChMdYXhUTFMg +UHJvamVjdCBJbnRlcm1lZGlhdGUgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDOF2/0KBnz3n4m4Xgnm22ApLwcMovm4IBg5LYH6jU6QbNhGRIj68Dj +UGk98TwPw/2WCNxvMA6s6+Bgc9md4TcjHWaGXI/Budd6wLjwBqFtZd4cUku7cevc +R+MhWeCm0gcXT8VeYu06NzEuk/+ZfJRNftubQ0yGAS/EBffh89+AzivoDA9gvDEk +aXRziutv1yGgOZenv7vY2eOI7+lfOtSQjRUv59XpT9xP2ujqnrAlh7C99cDOpXTU +HvrF/5CFganqH8dJlCe1NB8DYoincfuOFpVeAL8LLJn9+/HVBQBULLykxyQWzti4 +u1W6EA5nUql5nNpCi3BGNMR5GQX32ILHAgMBAAGjIzAhMBIGA1UdEwEB/wQIMAYB +Af8CAQAwCwYDVR0PBAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAYt1Wq1XsZjOWf +mH9XzI3k8UEtErTkBX5SXH10siY5tYmHzH02jaZVRC1yNrxQevqARhR1yj3daKg3 ++innX8foKlYRCxTfFeE/HELcm7rIt5mrIGdGAFn2fnImO5kpXxbPk6IAXRTp6lN8 +QS08Ah1Aaeh0ae2Ruzx2TOnG/IuB7ChliJxepo0KtRw6RN6ETvC2KS0glSf5fPW7 +c18UPbTesecrki12FlaGbPD/sWHOltBIpPXzgef7G8b6CiYqaX0T3T/47RLRwrMm +SAcbMerJZoyudbLd+OHGtvz5kOmYCoZYkay121MSvtFucHnR3UjEui2lUbL1Qi92 +2L3MUIVn +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/ca-bundle.crt b/circuitpython/lib/axtls/ssl/test/ca-bundle.crt new file mode 100644 index 0000000..0c00239 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/ca-bundle.crt @@ -0,0 +1,3585 @@ +-----BEGIN CERTIFICATE----- +MIIEuDCCA6CgAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBtDELMAkGA1UEBhMCQlIx +EzARBgNVBAoTCklDUC1CcmFzaWwxPTA7BgNVBAsTNEluc3RpdHV0byBOYWNpb25h +bCBkZSBUZWNub2xvZ2lhIGRhIEluZm9ybWFjYW8gLSBJVEkxETAPBgNVBAcTCEJy +YXNpbGlhMQswCQYDVQQIEwJERjExMC8GA1UEAxMoQXV0b3JpZGFkZSBDZXJ0aWZp +Y2Fkb3JhIFJhaXogQnJhc2lsZWlyYTAeFw0wMTExMzAxMjU4MDBaFw0xMTExMzAy +MzU5MDBaMIG0MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE9MDsG +A1UECxM0SW5zdGl0dXRvIE5hY2lvbmFsIGRlIFRlY25vbG9naWEgZGEgSW5mb3Jt +YWNhbyAtIElUSTERMA8GA1UEBxMIQnJhc2lsaWExCzAJBgNVBAgTAkRGMTEwLwYD +VQQDEyhBdXRvcmlkYWRlIENlcnRpZmljYWRvcmEgUmFpeiBCcmFzaWxlaXJhMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPMudwX/hvm+Uh2b/lQAcHVA +isamaLkWdkwP9/S/tOKIgRrL6Oy+ZIGlOUdd6uYtk9Ma/3pUpgcfNAj0vYm5gsyj +Qo9emsc+x6m4VWwk9iqMZSCK5EQkAq/Ut4n7KuLE1+gdftwdIgxfUsPt4CyNrY50 +QV57KM2UT8x5rrmzEjr7TICGpSUAl2gVqe6xaii+bmYR1QrmWaBSAG59LrkrjrYt +bRhFboUDe1DK+6T8s5L6k8c8okpbHpa9veMztDVC9sPJ60MWXh6anVKo1UcLcbUR +yEeNvZneVRKAAU6ouwdjDvwlsaKydFKwed0ToQ47bmUKgcm+wV3eTRk36UOnTwID +AQABo4HSMIHPME4GA1UdIARHMEUwQwYFYEwBAQAwOjA4BggrBgEFBQcCARYsaHR0 +cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0RQQ2FjcmFpei5wZGYwPQYDVR0f +BDYwNDAyoDCgLoYsaHR0cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0xDUmFj +cmFpei5jcmwwHQYDVR0OBBYEFIr68VeEERM1kEL6V0lUaQ2kxPA3MA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAZA5c1 +U/hgIh6OcgLAfiJgFWpvmDZWqlV30/bHFpj8iBobJSm5uDpt7TirYh1Uxe3fQaGl +YjJe+9zd+izPRbBqXPVQA34EXcwk4qpWuf1hHriWfdrx8AcqSqr6CuQFwSr75Fos +SzlwDADa70mT7wZjAmQhnZx2xJ6wfWlT9VQfS//JYeIc7Fue2JNLd00UOSMMaiK/ +t79enKNHEA2fupH3vEigf5Eh4bVAN5VohrTm6MY53x7XQZZr1ME7a55lFEnSeT0u +mlOAjR2mAbvSM5X5oSZNrmetdzyTj2flCM8CC7MLab0kkdngRIlUBGHF1/S5nmPb +K+9A46sd33oqK8n8 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIESzCCAzOgAwIBAgIJAJigUTEEXRQpMA0GCSqGSIb3DQEBBQUAMHYxCzAJBgNV +BAYTAkRFMQ8wDQYDVQQIEwZIZXNzZW4xDjAMBgNVBAcTBUZ1bGRhMRAwDgYDVQQK +EwdEZWJjb25mMRMwEQYDVQQDEwpEZWJjb25mIENBMR8wHQYJKoZIhvcNAQkBFhBq +b2VyZ0BkZWJpYW4ub3JnMB4XDTA1MTEwNTE3NTUxNFoXDTE1MTEwMzE3NTUxNFow +djELMAkGA1UEBhMCREUxDzANBgNVBAgTBkhlc3NlbjEOMAwGA1UEBxMFRnVsZGEx +EDAOBgNVBAoTB0RlYmNvbmYxEzARBgNVBAMTCkRlYmNvbmYgQ0ExHzAdBgkqhkiG +9w0BCQEWEGpvZXJnQGRlYmlhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCvbOo0SrIwI5IMlsshH8WF3dHB9r9JlSKhMPaybawa1EyvZspMQ3wa +F5qxNf3Sj+NElEmjseEqvCZiIIzqwerHu0Qw62cDYCdCd2+Wb5m0bPYB5CGHiyU1 +eNP0je42O0YeXG2BvUujN8AviocVo39X2YwNQ0ryy4OaqYgm2pRlbtT2ESbF+SfV +Y2iqQj/f8ymF+lHo/pz8tbAqxWcqaSiHFAVQJrdqtFhtoodoNiE3q76zJoUkZTXB +k60Yc3MJSnatZCpnsSBr/D7zpntl0THrUjjtdRWCjQVhqfhM1yZJV+ApbLdheFh0 +ZWlSxdnp25p0q0XYw/7G92ELyFDfBUUNAgMBAAGjgdswgdgwHQYDVR0OBBYEFMuV +dFNb4mCWUFbcP5LOtxFLrEVTMIGoBgNVHSMEgaAwgZ2AFMuVdFNb4mCWUFbcP5LO +txFLrEVToXqkeDB2MQswCQYDVQQGEwJERTEPMA0GA1UECBMGSGVzc2VuMQ4wDAYD +VQQHEwVGdWxkYTEQMA4GA1UEChMHRGViY29uZjETMBEGA1UEAxMKRGViY29uZiBD +QTEfMB0GCSqGSIb3DQEJARYQam9lcmdAZGViaWFuLm9yZ4IJAJigUTEEXRQpMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGZXxHg4mnkvilRIM1EQfGdY +S5b/WcyF2MYSTeTvK4aIB6VHwpZoZCnDGj2m2D3CkHT0upAD9o0zM1tdsfncLzV+ +mDT/jNmBtYo4QXx5vEPwvEIcgrWjwk7SyaEUhZjtolTkHB7ACl0oD0r71St4iEPR +qTUCEXk2E47bg1Fz58wNt/yo2+4iqiRjg1XCH4evkQuhpW+dTZnDyFNqwSYZapOE +TBA+9zBb6xD1KM2DdY7r4GiyYItN0BKLfuWbh9LXGbl1C+f4P11g+m2MPiavIeCe +1iazG5pcS3KoTLACsYlEX24TINtg4kcuS81XdllcnsV3Kdts0nIqPj6uhTTZD0k= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIRANAeQJAAAEZSAAAAAQAAAAQwDQYJKoZIhvcNAQEFBQAw +gYkxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJEQzETMBEGA1UEBxMKV2FzaGluZ3Rv +bjEXMBUGA1UEChMOQUJBLkVDT00sIElOQy4xGTAXBgNVBAMTEEFCQS5FQ09NIFJv +b3QgQ0ExJDAiBgkqhkiG9w0BCQEWFWFkbWluQGRpZ3NpZ3RydXN0LmNvbTAeFw05 +OTA3MTIxNzMzNTNaFw0wOTA3MDkxNzMzNTNaMIGJMQswCQYDVQQGEwJVUzELMAkG +A1UECBMCREMxEzARBgNVBAcTCldhc2hpbmd0b24xFzAVBgNVBAoTDkFCQS5FQ09N +LCBJTkMuMRkwFwYDVQQDExBBQkEuRUNPTSBSb290IENBMSQwIgYJKoZIhvcNAQkB +FhVhZG1pbkBkaWdzaWd0cnVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCx0xHgeVVDBwhMywVCAOINg0Y95JO6tgbTDVm9PsHOQ2cBiiGo77zM +0KLMsFWWU4RmBQDaREmA2FQKpSWGlO1jVv9wbKOhGdJ4vmgqRF4vz8wYXke8OrFG +PR7wuSw0X4x8TAgpnUBV6zx9g9618PeKgw6hTLQ6pbNfWiKX7BmbwQVo/ea3qZGU +LOR4SCQaJRk665WcOQqKz0Ky8BzVX/tr7WhWezkscjiw7pOp03t3POtxA6k4ShZs +iSrK2jMTecJVjO2cu/LLWxD4LmE1xilMKtAqY9FlWbT4zfn0AIS2V0KFnTKo+SpU ++/94Qby9cSj0u5C8/5Y0BONFnqFGKECBAgMBAAGjFjAUMBIGA1UdEwEB/wQIMAYB +Af8CAQgwDQYJKoZIhvcNAQEFBQADggEBAARvJYbk5pYntNlCwNDJALF/VD6Hsm0k +qS8Kfv2kRLD4VAe9G52dyntQJHsRW0mjpr8SdNWJt7cvmGQlFLdh6X9ggGvTZOir +vRrWUfrAtF13Gn9kCF55xgVM8XrdTX3O5kh7VNJhkoHWG9YA8A6eKHegTYjHInYZ +w8eeG6Z3ePhfm1bR8PIXrI6dWeYf/le22V7hXZ9F7GFoGUHhsiAm/lowdiT/QHI8 +eZ98IkirRs3bs4Ysj78FQdPB4xTjQRcm0HyncUwZ6EoPclgxfexgeqMiKL0ZJGA/ +O4dzwGvky663qyVDslUte6sGDnVdNOVdc22esnVApVnJTzFxiNmIf1Q= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw +MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD +VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul +CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n +tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl +dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch +PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC ++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O +BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk +ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X +7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz +43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl +pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA +WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx +MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB +ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV +BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV +6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX +GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP +dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH +1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF +62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW +BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL +MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU +cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv +b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6 +IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/ +iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh +4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm +XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1 +MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK +EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh +BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq +xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G +87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i +2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U +WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1 +0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G +A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr +pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL +ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm +aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv +hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm +hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3 +P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y +iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no +xqE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP +bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2 +MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft +ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk +hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym +1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW +OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb +2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko +O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU +AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF +Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb +LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir +oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C +MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds +sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP +bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2 +MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft +ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC +206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci +KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2 +JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9 +BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e +Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B +PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67 +Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq +Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ +o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3 ++L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj +YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj +FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn +xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2 +LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc +obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8 +CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe +IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA +DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F +AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX +Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb +AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl +Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw +RY8mkaKO/qk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx +HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh +IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyOTA2MDAwMFoXDTM3MTEyMDE1 +MDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg +SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M +IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnej8Mlo2k06AX3dLm/WpcZuS+U +0pPlLYnKhHw/EEMbjIt8hFj4JHxIzyr9wBXZGH6EGhfT257XyuTZ16pYUYfw8ItI +TuLCxFlpMGK2MKKMCxGZYTVtfu/FsRkGIBKOQuHfD5YQUqjPnF+VFNivO3ULMSAf +RC+iYkGzuxgh28pxPIzstrkNn+9R7017EvILDOGsQI93f7DKeHEMXRZxcKLXwjqF +zQ6axOAAsNUl6twr5JQtOJyJQVdkKGUZHLZEtMgxa44Be3ZZJX8VHIQIfHNlIAqh +BC4aMqiaILGcLCFZ5/vP7nAtCMpjPiybkxlqpMKX/7eGV4iFbJ4VFitNLLMCAwEA +AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUoTYwFsuGkABFgFOxj8jY +PXy+XxIwHwYDVR0jBBgwFoAUoTYwFsuGkABFgFOxj8jYPXy+XxIwDgYDVR0PAQH/ +BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQCKIBilvrMvtKaEAEAwKfq0FHNMeUWn +9nDg6H5kHgqVfGphwu9OH77/yZkfB2FK4V1Mza3u0FIy2VkyvNp5ctZ7CegCgTXT +Ct8RHcl5oIBN/lrXVtbtDyqvpxh1MwzqwWEFT2qaifKNuZ8u77BfWgDrvq2g+EQF +Z7zLBO+eZMXpyD8Fv8YvBxzDNnGGyjhmSs3WuEvGbKeXO/oTLW4jYYehY0KswsuX +n2Fozy1MBJ3XJU8KDk2QixhWqJNIV9xvrr2eZ1d3iVCzvhGbRWeDhhmH05i9CBoW +H1iCC+GWaQVLjuyDUTEH1dSf/1l7qG6Fz9NLqUmwX7A5KGgOc90lmt4S +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx +HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh +IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyOTA2MDAwMFoXDTM3MDkyODIz +NDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg +SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M +IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ +7ouZzU9AhqS2TcnZsdw8TQ2FTBVsRotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilb +m2BPJoPRYxJWSXakFsKlnUWsi4SVqBax7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOY +xFSMFkpBd4aVdQxHAWZg/BXxD+r1FHjHDtdugRxev17nOirYlxcwfACtCJ0zr7iZ +YYCLqJV+FNwSbKTQ2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2wTPDaRrbq +JS5Gr42whTg0ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fx +I2rSAG2X+Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETz +kxmlJ85per5n0/xQpCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFh +EVsVS6kkUfykXPcXnbDS+gfpj1bkGoxoigTTfFrjnqKhynFbotSg5ymFXQNoKk/S +Btc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuWCpTehTacyH+BCQJJKg71ZDIM +gtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1ExMVCgyhwn2RAu +rda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaAFE9pbQN+nZ8HGEO8txBO +1b+pxCAoMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAO/Ouyugu +h4X7ZVnnrREUpVe8WJ8kEle7+z802u6teio0cnAxa8cZmIDJgt43d15Ui47y6mdP +yXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRFASbI5Rq8NEQh3q0l/HYWdyGQgJhXnU7q +7C+qPBR7V8F+GBRn7iTGvboVsNIYvbdVgaxTwOjdaRITQrcCtQVBynlQboIOcXKT +RuidDV29rs4prWPVVRaAMCf/drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ68W/ +ClTluUI8JPu3B5wwn3la5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyB +M5kYJRF3p+v9WAksmWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQ +my8YJPamTQr5O8t1wswvziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xO +AU++CrYD062KRffaJ00psUjf5BHklka9bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT +9Y41xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4oGKQWDzH9OmwjkyB24f0H +hdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2uBOLZ8/5 +fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFajCCBFKgAwIBAgIEPLU9RjANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwli +ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMq +YmVUUlVTVGVkIFJvb3QgQ0EtQmFsdGltb3JlIEltcGxlbWVudGF0aW9uMB4XDTAy +MDQxMTA3Mzg1MVoXDTIyMDQxMTA3Mzg1MVowZjESMBAGA1UEChMJYmVUUlVTVGVk +MRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNVBAMTKmJlVFJVU1Rl +ZCBSb290IENBLUJhbHRpbW9yZSBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALx+xDmcjOPWHIb/ymKt4H8wRXqOGrO4x/nRNv8i +805qX4QQ+2aBw5R5MdKR4XeOGCrDFN5R9U+jK7wYFuK13XneIviCfsuBH/0nLI/6 +l2Qijvj/YaOcGx6Sj8CoCd8JEey3fTGaGuqDIQY8n7pc/5TqarjDa1U0Tz0yH92B +FODEPM2dMPgwqZfT7syj0B9fHBOB1BirlNFjw55/NZKeX0Tq7PQiXLfoPX2k+Ymp +kbIq2eszh+6l/ePazIjmiSZuxyuC0F6dWdsU7JGDBcNeDsYq0ATdcT0gTlgn/FP7 +eHgZFLL8kFKJOGJgB7Sg7KxrUNb9uShr71ItOrL/8QFArDcCAwEAAaOCAh4wggIa +MA8GA1UdEwEB/wQFMAMBAf8wggG1BgNVHSAEggGsMIIBqDCCAaQGDysGAQQBsT4A +AAEJKIORMTCCAY8wggFIBggrBgEFBQcCAjCCAToaggE2UmVsaWFuY2Ugb24gb3Ig +dXNlIG9mIHRoaXMgQ2VydGlmaWNhdGUgY3JlYXRlcyBhbiBhY2tub3dsZWRnbWVu +dCBhbmQgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJk +IHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgdGhlIENlcnRpZmljYXRpb24g +UHJhY3RpY2UgU3RhdGVtZW50IGFuZCB0aGUgUmVseWluZyBQYXJ0eSBBZ3JlZW1l +bnQsIHdoaWNoIGNhbiBiZSBmb3VuZCBhdCB0aGUgYmVUUlVTVGVkIHdlYiBzaXRl +LCBodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20vcHJvZHVjdHNfc2VydmljZXMvaW5k +ZXguaHRtbDBBBggrBgEFBQcCARY1aHR0cDovL3d3dy5iZXRydXN0ZWQuY29tL3By +b2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWwwHQYDVR0OBBYEFEU9w6nR3D8kVpgc +cxiIav+DR+22MB8GA1UdIwQYMBaAFEU9w6nR3D8kVpgccxiIav+DR+22MA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEASZK8o+6svfoNyYt5hhwjdrCA +WXf82n+0S9/DZEtqTg6t8n1ZdwWtColzsPq8y9yNAIiPpqCy6qxSJ7+hSHyXEHu6 +7RMdmgduyzFiEuhjA6p9beP4G3YheBufS0OM00mG9htc9i5gFdPp43t1P9ACg9AY +gkHNZTfqjjJ+vWuZXTARyNtIVBw74acT02pIk/c9jH8F6M7ziCpjBLjqflh8AXtb +4cV97yHgjQ5dUX2xZ/2jvTg2xvI4hocalmhgRvsoFEdV4aeADGvi6t9NfJBIoDa9 +CReJf8Py05yc493EG931t3GzUwWJBtDLSoDByFOQtTwxiBdQn8nEDovYqAJjDQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFLDCCBBSgAwIBAgIEOU99hzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJX +VzESMBAGA1UEChMJYmVUUlVTVGVkMRswGQYDVQQDExJiZVRSVVNUZWQgUm9vdCBD +QXMxGjAYBgNVBAMTEWJlVFJVU1RlZCBSb290IENBMB4XDTAwMDYyMDE0MjEwNFoX +DTEwMDYyMDEzMjEwNFowWjELMAkGA1UEBhMCV1cxEjAQBgNVBAoTCWJlVFJVU1Rl +ZDEbMBkGA1UEAxMSYmVUUlVTVGVkIFJvb3QgQ0FzMRowGAYDVQQDExFiZVRSVVNU +ZWQgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANS0c3oT +CjhVAb6JVuGUntS+WutKNHUbYSnE4a0IYCF4SP+00PpeQY1hRIfo7clY+vyTmt9P +6j41ffgzeubx181vSUs9Ty1uDoM6GHh3o8/n9E1z2Jo7Gh2+lVPPIJfCzz4kUmwM +jmVZxXH/YgmPqsWPzGCgc0rXOD8Vcr+il7dw6K/ifhYGTPWqZCZyByWtNfwYsSbX +2P8ZDoMbjNx4RWc0PfSvHI3kbWvtILNnmrRhyxdviTX/507AMhLn7uzf/5cwdO2N +R47rtMNE5qdMf1ZD6Li8tr76g5fmu/vEtpO+GRg+jIG5c4gW9JZDnGdzF5DYCW5j +rEq2I8QBoa2k5MUCAwEAAaOCAfgwggH0MA8GA1UdEwEB/wQFMAMBAf8wggFZBgNV +HSAEggFQMIIBTDCCAUgGCisGAQQBsT4BAAAwggE4MIIBAQYIKwYBBQUHAgIwgfQa +gfFSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1 +bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0 +ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGFuZCBjZXJ0aWZpY2F0aW9uIHBy +YWN0aWNlIHN0YXRlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IGJlVFJVU1Rl +ZCdzIHdlYiBzaXRlLCBodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0L3Rl +cm1zMDEGCCsGAQUFBwIBFiVodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0 +L3Rlcm1zMDQGA1UdHwQtMCswKaAnoCWkIzAhMRIwEAYDVQQKEwliZVRSVVNUZWQx +CzAJBgNVBAYTAldXMB0GA1UdDgQWBBQquZtpLjub2M3eKjEENGvKBxirZzAfBgNV +HSMEGDAWgBQquZtpLjub2M3eKjEENGvKBxirZzAOBgNVHQ8BAf8EBAMCAf4wDQYJ +KoZIhvcNAQEFBQADggEBAHlh26Nebhax6nZR+csVm8tpvuaBa58oH2U+3RGFktTo +Qb9+M70j5/Egv6S0phkBxoyNNXxlpE8JpNbYIxUFE6dDea/bow6be3ga8wSGWsb2 +jCBHOElQBp1yZzrwmAOtlmdE/D8QDYZN5AA7KXvOOzuZhmElQITcE2K3+spZ1gMe +1lMBzW1MaFVA4e5rxyoAAEiCswoBw2AqDPeCNe5IhpbkdNQ96gFxugR1QKepfzk5 +mlWXKWWuGVUlBXJH0+gY3Ljpr0NzARJ0o+FcXxVdJPP55PS2Z2cS52QiivalQaYc +tmBjRYoQtLpGEK5BV2VsPyMQPyEQWbfkQN0mDCP2qq4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGUTCCBTmgAwIBAgIEPLVPQDANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwli +ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMq +YmVUUlVTVGVkIFJvb3QgQ0EgLSBFbnRydXN0IEltcGxlbWVudGF0aW9uMB4XDTAy +MDQxMTA4MjQyN1oXDTIyMDQxMTA4NTQyN1owZjESMBAGA1UEChMJYmVUUlVTVGVk +MRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNVBAMTKmJlVFJVU1Rl +ZCBSb290IENBIC0gRW50cnVzdCBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALr0RAOqEmq1Q+xVkrYwfTVXDNvzDSduTPdQqJtO +K2/b9a0cS12zqcH+e0TrW6MFDR/FNCswACnxeECypP869AGIF37m1CbTukzqMvtD +d5eHI8XbQ6P1KqNRXuE70mVpflUVm3rnafdE4Fe1FehmYA8NA/uCjqPoEXtsvsdj +DheT389Lrm5zdeDzqrmkwAkbhepxKYhBMvnwKg5sCfJ0a2ZsUhMfGLzUPvfYbiCe +yv78IZTuEyhL11xeDGbu6bsPwTSxfwh28z0mcMmLJR1iJAzqHHVOwBLkuhMdMCkt +VjMFu5dZfsZJT4nXLySotohAtWSSU1Yk5KKghbNekLQSM80CAwEAAaOCAwUwggMB +MIIBtwYDVR0gBIIBrjCCAaowggGmBg8rBgEEAbE+AAACCSiDkTEwggGRMIIBSQYI +KwYBBQUHAgIwggE7GoIBN1JlbGlhbmNlIG9uIG9yIHVzZSBvZiB0aGlzIENlcnRp +ZmljYXRlIGNyZWF0ZXMgYW4gYWNrbm93bGVkZ21lbnQgYW5kIGFjY2VwdGFuY2Ug +b2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0 +aW9ucyBvZiB1c2UsIHRoZSBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dCBhbmQgdGhlIFJlbHlpbmcgUGFydHkgQWdyZWVtZW50LCB3aGljaCBjYW4gYmUg +Zm91bmQgYXQgdGhlIGJlVFJVU1RlZCB3ZWIgc2l0ZSwgaHR0cHM6Ly93d3cuYmV0 +cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMEIGCCsGAQUF +BwIBFjZodHRwczovL3d3dy5iZXRydXN0ZWQuY29tL3Byb2R1Y3RzX3NlcnZpY2Vz +L2luZGV4Lmh0bWwwEQYJYIZIAYb4QgEBBAQDAgAHMIGJBgNVHR8EgYEwfzB9oHug +eaR3MHUxEjAQBgNVBAoTCWJlVFJVU1RlZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJv +b3QgQ0FzMTMwMQYDVQQDEypiZVRSVVNUZWQgUm9vdCBDQSAtIEVudHJ1c3QgSW1w +bGVtZW50YXRpb24xDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMjA0MTEw +ODI0MjdagQ8yMDIyMDQxMTA4NTQyN1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaA +FH1w5a44iwY/qhwaj/nPJDCqhIQWMB0GA1UdDgQWBBR9cOWuOIsGP6ocGo/5zyQw +qoSEFjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIE +kDANBgkqhkiG9w0BAQUFAAOCAQEAKrgXzh8QlOu4mre5X+za95IkrNySO8cgjfKZ +5V04ocI07cUTWVwFtStPYZuR+0H8/NU8TZh2BvWBfevdkObRVlTa4y0MnxEylCIB +evZsLHRnBMylj44ss0O1lKLQfelifwa+JwGDnjr9iu6YQ0pr17WXOzq/T220Y/oz +ADQuLW2WyXvKmWO6vvT2MKAtmJbpVkQFqUSjYRDrgqFnXbxdJ3Wqiig2KjiS2d2k +XgClzMx8KSreKJCrt+G2/30lC0DYqjSjLd4H61/OCt3Kfjp9JsFiaDrmLzfzgYYh +xKlkqu9FNtEaZnz46TfW1mG+oq1I59/mdP7TbX3SJdysYlep9w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFaDCCBFCgAwIBAgIQO1nHe81bV569N1KsdrSqGjANBgkqhkiG9w0BAQUFADBi +MRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENB +czEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRp +b24wHhcNMDIwNDExMTExODEzWhcNMjIwNDEyMTEwNzI1WjBiMRIwEAYDVQQKEwli +ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEvMC0GA1UEAxMm +YmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRpb24wggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkujQwCY5X0LkGLG9uJIAiv11DpvpPrILn +HGhwhRujbrWqeNluB0s/6d/16uhUoWGKDi9pdRi3DOUUjXFumLhV/AyV0Jtu4S2I +1DpAa5LxmZZk3tv/ePTulh1HiXzUvrmIdyM6CeYEnm2qXtLIvZpOGd+J6lsOfsPk +tPDgaTuID0GQ+NRxQyTBjyZLO1bp/4xsN+lFrYWMU8NghpBKlsmzVLC7F/AcRdnU +GxlkVgoZ98zh/4avflherHqQH8koOUV7orbHnB/ahdQhhlkwk75TMzf270HPM8er +cmsl9fNTGwxMLvF1S++gh/f+ihXQbNXL+WhTuXAVE8L1LvtDNXUtAgMBAAGjggIY +MIICFDAMBgNVHRMEBTADAQH/MIIBtQYDVR0gBIIBrDCCAagwggGkBg8rBgEEAbE+ +AAADCSiDkTEwggGPMEEGCCsGAQUFBwIBFjVodHRwOi8vd3d3LmJldHJ1c3RlZC5j +b20vcHJvZHVjdHNfc2VydmljZXMvaW5kZXguaHRtbDCCAUgGCCsGAQUFBwICMIIB +OhqCATZSZWxpYW5jZSBvbiBvciB1c2Ugb2YgdGhpcyBDZXJ0aWZpY2F0ZSBjcmVh +dGVzIGFuIGFja25vd2xlZGdtZW50IGFuZCBhY2NlcHRhbmNlIG9mIHRoZSB0aGVu +IGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNl +LCB0aGUgQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQgYW5kIHRoZSBS +ZWx5aW5nIFBhcnR5IEFncmVlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IHRo +ZSBiZVRSVVNUZWQgd2ViIHNpdGUsIGh0dHA6Ly93d3cuYmV0cnVzdGVkLmNvbS9w +cm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMAsGA1UdDwQEAwIBBjAfBgNVHSME +GDAWgBSp7BR++dlDzFMrFK3P9/BZiUHNGTAdBgNVHQ4EFgQUqewUfvnZQ8xTKxSt +z/fwWYlBzRkwDQYJKoZIhvcNAQEFBQADggEBANuXsHXqDMTBmMpWBcCorSZIry0g +6IHHtt9DwSwddUvUQo3neqh03GZCWYez9Wlt2ames30cMcH1VOJZJEnl7r05pmuK +mET7m9cqg5c0Lcd9NUwtNLg+DcTsiCevnpL9UGGCqGAHFFPMZRPB9kdEadIxyKbd +LrML3kqNWz2rDcI1UqJWN8wyiyiFQpyRQHpwKzg21eFzGh/l+n5f3NacOzDq28Bb +J1zTcwfBwvNMm2+fG8oeqqg4MwlYsq78B+g23FW6L09A/nq9BqaBwZMifIYRCgZ3 +SK41ty8ymmFei74pnykkiFY5LKjSq5YDWtRIn7lAhAuYaPsBQ9Yb4gmxlxw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E +jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo +ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI +ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu +Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg +AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7 +HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA +uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa +TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg +xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q +CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x +O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs +6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp +ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow +fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV +BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM +cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S +HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 +CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk +3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz +6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV +HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv +Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw +Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww +DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 +5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI +gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ +aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl +izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 +aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla +MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD +VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW +fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt +TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL +fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW +1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 +kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G +A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v +ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo +dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu +Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ +HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS +jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ +xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn +dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV +UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL +EwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJ +BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x +ETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCg +bIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJENySZ +j9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlV +Sn5JTe2io74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCG +SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx +JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI +RFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEw +MjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5 +fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i ++DAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG +SIb3DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN +QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+ +gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6w4pl +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID2DCCAsACEQDQHkCLAAACfAAAAAIAAAABMA0GCSqGSIb3DQEBBQUAMIGpMQsw +CQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENp +dHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UE +CxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDExITAfBgkqhkiG9w0B +CQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODEyMDExODE4NTVaFw0wODExMjgx +ODE4NTVaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMO +U2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0 +IENvLjERMA8GA1UECxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDEx +ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBANLGJrbnpT3BxGjVUG9TxW9JEwm4ryxIjRRqoxdf +WvnTLnUv2Chi0ZMv/E3Uq4flCMeZ55I/db3rJbQVwZsZPdJEjdd0IG03Ao9pk1uK +xBmd9LIO/BZsubEFkoPRhSxglD5FVaDZqwgh5mDoO3TymVBRaNADLbGAvqPYUrBE +zUNKcI5YhZXhTizWLUFv1oTnyJhEykfbLCSlaSbPa7gnYsP0yXqSI+0TZ4KuRS5F +5X5yP4WdlGIQ5jyRoa13AOAV7POEgHJ6jm5gl8ckWRA0g1vhpaRptlc1HHhZxtMv +OnNn7pTKBBMFYgZwI7P0fO5F2WQLW0mqpEPOJsREEmy43XkCAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAojeyP2n714Z5VEkxlTMr89EJFEliYIalsBHiUMIdBlc+Legz +ZL6bqq1fG03UmZWii5rJYnK1aerZWKs17RWiQ9a2vAd5ZWRzfdd5ynvVWlHG4VME +lo04z6MXrDlxawHDi1M8Y+nuecDkvpIyZHqzH5eUYr3qsiAVlfuX8ngvYzZAOONG +Dx3drJXK50uQe7FLqdTF65raqtWjlBRGjS0f8zrWkzr2Pnn86Oawde3uPclwx12q +gUtGJRzHbBXjlU4PqjI3lAoXJJIThFjSY28r9+ZbYgsTF7ANUkz+/m9c4pFuHf2k +Ytdo+o56T9II2pPc8JIRetDccpMMc5NihWjQ9A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV +UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL +EwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJ +BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x +ETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC/ +k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGODVvso +LeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3o +TQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCG +SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx +JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI +RFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3 +MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6C +TShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5 +WzAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG +SIb3DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR +xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVL +B3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlihw6ID +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID2DCCAsACEQDQHkCLAAB3bQAAAAEAAAAEMA0GCSqGSIb3DQEBBQUAMIGpMQsw +CQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENp +dHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UE +CxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIxITAfBgkqhkiG9w0B +CQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODExMzAyMjQ2MTZaFw0wODExMjcy +MjQ2MTZaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMO +U2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0 +IENvLjERMA8GA1UECxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIx +ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBANx18IzAdZaawGIfJvfE4Zrq4FZzW5nNAUSoCLbV +p9oaBBg5kkp4o4HC9Xd6ULRw/5qrxsfKboNPQpj7Jgva3G3WqZlVUmfpKAOS3OWw +BZoPFflrWXJW8vo5/Kpo7g8fEIMv/J36F5bdguPmRX3AS4BEH+0s4IT9kVySVGkl +5WJp3OXuAFK9MwutdQKFp2RQLcUZGTDAJtvJ0/0uma1ZtQtN1EGuhUhDWdy3qOKi +3sOP17ihYqZoUFLkzzGnlIXan0YyF1bl8utmPRL/Q9uY73fPy4GNNLHGUEom0eQ+ +QVCvbK4iNC7Va26Dunm4dmVI2gkpZGMiuftHdoWMhkTLCdsCAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAtTYOXeFhKFoRZcA/gwN5Tb4opgsHAlKFzfiR0BBstWogWxyQ +2TA8xkieil5k+aFxd+8EJx8H6+Qm93N0yUQYGmbT4EOvkTvRyyzYdFQ6HE3K1GjN +I3wdEJ5F6fYAbqbNGf9PLCmPV03Ed5K+4EwJ+11EhmYhqLkyolbV6YyDfFk/xPEL +553snr2cGA4+wjl5KLcDDQjLxufZATdQEOzMYRZA1K8xdHv8PzGn0EdzMzkbzE5q +10mDEQb+64JYMzJM8FasHpwvVpp7wUocpf1VNs78lk30sPDst2yC7S8xmUJMqbIN +uBVd8d+6ybVK1GSYsyapMMj9puyrliGtf8J4tg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NBX0NQUyBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAw +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVu +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDcxNjE2NDBaFw0yMDAy +MDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTdLS25MVL1qFof2LV7PdRV7Ny +Spj10InJrWPNTTVRaoTUrcloeW+46xHbh65cJFET8VQlhK8pK5/jgOLZy93GRUk0 +iJBeAZfv6lOm3fzB3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKklWb1m9fkn +5JVn1j+SgF7yNH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHd +BgNVHR8EgdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0 +MUAwPgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSBy +ZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5l +dCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBDbGllbnQgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAy +MDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQDAgEGMB8GA1UdIwQY +MBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQWBBSEi3T9xY3A/ydtIDdF +fP4tzrrTfTAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4w +AwIEkDANBgkqhkiG9w0BAQQFAAOBgQBObzWAO9GK9Q6nIMstZVXQkvTnhLUGJoMS +hAusO7JE7r3PQNsgDrpuFOow4DtifH+La3xKp9U1PL6oXOpLu5OOgGarDyn9TS2/ +GpsKkMWr2tGzhtQvJFJcem3G8v7lTRowjJDyutdKPkN+1MhQGof4T4HHdguEOnKd +zmVml64mXg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UEChML +RW50cnVzdC5uZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xfQ1BTIGlu +Y29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAg +RW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJl +IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDQxNzIwMDBa +Fw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDE/MD0GA1UE +CxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p +dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVk +MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp +b24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO +8GCGD9JYf9Mzly0XonUwtZZkJi9ow0SrqHXmAGc0V55lxyKbc+bT3QgON1WqJUaB +bL3+qPZ1V1eMkGxKwz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439PmrkDQYC2 +dWcTC5/oVzbIXQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4 +QgEBBAQDAgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoT +C0VudHJ1c3QubmV0MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAw +IEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMTMUVudHJ1c3QubmV0IFNlY3Vy +ZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEw +KwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIwNDE3NTAwMFowCwYD +VR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc/vuLkpyw8m4iMB0GA1Ud +DgQWBBTLbMBr47s+y/winP77i5KcsPJuIjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2 +fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQFAAOBgQBi24GRzsia +d0Iv7L0no1MPUBvqTpLwqa+poLpIYcvvyQbvH9X07t9WLebKahlzqlO+krNQAraF +JnJj2HVQYnUUt7NQGj/KEQALhUVpbbalrlHhStyCP2yMNLJ3a9kC9n8O6mUE8c1U +yrrJzOCE98g+EZfTYAkYvAX/bIkz8OwVDw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy +MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA +vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G +CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA +WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo +oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ +h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18 +f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN +B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy +vUxFnmG6v4SBkgPR0ml8xQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50cnVzdC5u +ZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBsaW1pdHMgbGlh +Yi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBaMIHJMQswCQYDVQQGEwJVUzEU +MBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9D +bGllbnRfQ0FfSW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMq +RW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0G +CSqGSIb3DQEBAQUAA4GLADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo +6oT9n3V5z8GKUZSvx1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux +5zDeg7K6PvHViTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zm +AqTmT173iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSC +ARkwggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50 +cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5m +by9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMp +IDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQg +Q2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCyg +KqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9DbGllbnQxLmNybDArBgNV +HRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkxMDEyMTkyNDMwWjALBgNVHQ8E +BAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW/O5bs8qZdIuV6kwwHQYDVR0OBBYE +FMT7nCl7l81MlvzuW7PKmXSLlepMMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA +BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7 +pFuPeJoSSJn59DXeDDYHAmsQOokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzz +wy5E97BnRqqS5TvaHBkUODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/a +EkP/TOYGJqibGapEPHayXOw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 +MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE +ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j +b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF +bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg +U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ +I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 +wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC +AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb +oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 +BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p +dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk +MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp +b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu +dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 +MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi +E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa +MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI +hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN +95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd +2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV +UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 +MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx +dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f +BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A +cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC +AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw +ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj +IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF +MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA +A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y +7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh +1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT +ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw +MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j +LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo +RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu +WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw +Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK +eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM +zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ +WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN +/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj +dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0 +NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD +VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G +vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/ +BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C +AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX +MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl +IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw +NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq +y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF +MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA +A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy +0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1 +E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH +iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS +r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 +04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r +GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 +3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P +lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv +b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU +cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv +RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M +ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5 +1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz +dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl +IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy +bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARwxCzAJBgNVBAYTAkVT +MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE +ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE +ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEzMDEGA1UECxMq +SVBTIENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTMwMQYD +VQQDEypJUFMgQ0EgQ2hhaW5lZCBDQXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +HjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczAeFw0wMTEyMjkwMDUzNTha +Fw0yNTEyMjcwMDUzNThaMIIBHDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNl +bG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQg +cHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMu +ZXMgQy5JLkYuICBCLTYwOTI5NDUyMTMwMQYDVQQLEypJUFMgQ0EgQ2hhaW5lZCBD +QXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMzAxBgNVBAMTKklQUyBDQSBDaGFp +bmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYP +aXBzQG1haWwuaXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcVpJJ +spQgvJhPUOtopKdJC7/SMejHT8KGC/po/UNaivNgkjWZOLtNA1IhW/A3mTXhQSCB +hYEFcYGdtJUZqV92NC5jNzVXjrQfQj8VXOF6wV8TGDIxya2+o8eDZh65nAQTy2nB +Bt4wBrszo7Uf8I9vzv+W6FS+ZoCua9tBhDaiPQIDAQABo4IEQzCCBD8wHQYDVR0O +BBYEFKGtMbH5PuEXpsirNPxShwkeYlJBMIIBTgYDVR0jBIIBRTCCAUGAFKGtMbH5 +PuEXpsirNPxShwkeYlJBoYIBJKSCASAwggEcMQswCQYDVQQGEwJFUzESMBAGA1UE +CBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJ +bnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0Bt +YWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxMzAxBgNVBAsTKklQUyBDQSBD +aGFpbmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEzMDEGA1UEAxMqSVBT +IENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI +hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8E +BQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMG +CCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYB +BAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMw +EYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBC +BglghkgBhvhCAQ0ENRYzQ2hhaW5lZCBDQSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkg +aHR0cDovL3d3dy5pcHMuZXMvMCkGCWCGSAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlw +cy5lcy9pcHMyMDAyLzA3BglghkgBhvhCAQQEKhYoaHR0cDovL3d3dy5pcHMuZXMv +aXBzMjAwMi9pcHMyMDAyQ0FDLmNybDA8BglghkgBhvhCAQMELxYtaHR0cDovL3d3 +dy5pcHMuZXMvaXBzMjAwMi9yZXZvY2F0aW9uQ0FDLmh0bWw/MDkGCWCGSAGG+EIB +BwQsFipodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3JlbmV3YWxDQUMuaHRtbD8w +NwYJYIZIAYb4QgEIBCoWKGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5 +Q0FDLmh0bWwwbQYDVR0fBGYwZDAuoCygKoYoaHR0cDovL3d3dy5pcHMuZXMvaXBz +MjAwMi9pcHMyMDAyQ0FDLmNybDAyoDCgLoYsaHR0cDovL3d3d2JhY2suaXBzLmVz +L2lwczIwMDIvaXBzMjAwMkNBQy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF +BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAERyMJ1W +WKJBGyi3leGmGpVfp3hAK+/blkr8THFj2XOVvQLiogbHvpcqk4A0hgP63Ng9HgfN +HnNDJGD1HWHc3JagvPsd4+cSACczAsDAK1M92GsDgaPb1pOVIO/Tln4mkImcJpvN +b2ar7QMiRDjMWb2f2/YHogF/JsRj9SVCXmK9 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVT +MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE +ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE +ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEuMCwGA1UECxMl +SVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMl +SVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3 +DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAwNTkzOFoXDTI1MTIyNzAw +NTkzOFowggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYD +VQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5n +IFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g +IEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4FEnpwvdr9G5Q1uCN0VWcu+atsIS7ywS +zHb5BlmvXSHU0lq4oNTzav3KaY1mSPd05u42veiWkXWmcSjK5yISMmmwPh5r9FBS +YmL9Yzt9fuzuOOpi9GyocY3h6YvJP8a1zZRCb92CRTzo3wno7wpVqVZHYUxJZHMQ +KD/Kvwn/xi8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBTrsxl588GlHKzcuh9morKb +adB4CDCCAUQGA1UdIwSCATswggE3gBTrsxl588GlHKzcuh9morKbadB4CKGCARqk +ggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE +BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBT +ZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBC +LTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYD +VR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggr +BgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB +FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhC +AQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB +D2lwc0BtYWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UxIENBIENlcnRp +ZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC +BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQtFito +dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEuY3JsMD8GCWCG +SAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25D +TEFTRTEuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lw +czIwMDIvcmVuZXdhbENMQVNFMS5odG1sPzA6BglghkgBhvhCAQgELRYraHR0cDov +L3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFTRTEuaHRtbDBzBgNVHR8EbDBq +MDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEu +Y3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy +Q0xBU0UxLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9v +Y3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAK9Dr/drIyllq2tPMMi7JVBuK +Yn4VLenZMdMu9Ccj/1urxUq2ckCuU3T0vAW0xtnIyXf7t/k0f3gA+Nak5FI/LEpj +V4F1Wo7ojPsCwJTGKbqz3Bzosq/SLmJbGqmODszFV0VRFOlOHIilkfSj945RyKm+ +hjM+5i9Ibq9UkE6tsSU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVT +MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE +ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE +ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEuMCwGA1UECxMl +SVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMl +SVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3 +DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMDE0NFoXDTI1MTIyNzAx +MDE0NFowggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYD +VQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5n +IFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g +IEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxf+DrDGaBtT8FK+n/ra+osTBLsBjzLZ +H49NzjaY2uQARIwo2BNEKqRrThckQpzTiKRBgtYj+4vJhuW5qYIF3PHeH+AMmVWY +8jjsbJ0gA8DvqqPGZARRLXgNo9KoOtYkTOmWehisEyMiG3zoMRGzXwmqMHBxRiVr +SXGAK5UBsh8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBS4k/8uy9wsjqLnev42USGj +mFsMNDCCAUQGA1UdIwSCATswggE3gBS4k/8uy9wsjqLnev42USGjmFsMNKGCARqk +ggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE +BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBT +ZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBC +LTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYD +VR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggr +BgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB +FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhC +AQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB +D2lwc0BtYWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UzIENBIENlcnRp +ZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC +BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQtFito +dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMuY3JsMD8GCWCG +SAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25D +TEFTRTMuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lw +czIwMDIvcmVuZXdhbENMQVNFMy5odG1sPzA6BglghkgBhvhCAQgELRYraHR0cDov +L3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFTRTMuaHRtbDBzBgNVHR8EbDBq +MDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMu +Y3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy +Q0xBU0UzLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9v +Y3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAF2VcmZVDAyevJuXr0LMXI/dD +qsfwfewPxqmurpYPdikc4gYtfibFPPqhwYHOU7BC0ZdXGhd+pFFhxu7pXu8Fuuu9 +D6eSb9ijBmgpjnn1/7/5p6/ksc7C0YBCJwUENPjDfxZ4IwwHJPJGR607VNCv1TGy +r33I6unUVtkOE7LFRVA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVT +MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE +ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE +ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMm +SVBTIENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT +JklQUyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI +hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNTMyWhcNMjUxMjI3 +MDEwNTMyWjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ +BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp +bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G +LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMw +gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsw19zQVL01Tp/FTILq0VA8R5j8 +m2mdd81u4D/u6zJfX5/S0HnllXNEITLgCtud186Nq1KLK3jgm1t99P1tCeWu4Wwd +ByOgF9H5fahGRpEiqLJpxq339fWUoTCUvQDMRH/uxJ7JweaPCjbB/SQ9AaD1e+J8 +eGZDi09Z8pvZ+kmzAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUZyaW56G/2LUDnf47 +3P7yiuYV3TAwggFGBgNVHSMEggE9MIIBOYAUZyaW56G/2LUDnf473P7yiuYV3TCh +ggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ +BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp +bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G +LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOC +AQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUF +BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYB +BAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglg +hkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud +EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMSBD +QSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG +SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgBhvhC +AQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMS5j +cmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2 +b2NhdGlvbkNMQVNFQTEuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cu +aXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTEuaHRtbD8wOwYJYIZIAYb4QgEI +BC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5Q0xBU0VBMS5odG1s +MHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvaXBz +MjAwMkNMQVNFQTEuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz +MjAwMi9pcHMyMDAyQ0xBU0VBMS5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF +BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAH66iqyA +AIQVCtWYUQxkxZwCWINmyq0eB81+atqAB98DNEock8RLWCA1NnHtogo1EqWmZaeF +aQoO42Hu6r4okzPV7Oi+xNtff6j5YzHIa5biKcJboOeXNp13XjFr/tOn2yrb25aL +H2betgPAK7N41lUH5Y85UN4HI3LmvSAUS7SG +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVT +MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE +ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE +ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMm +SVBTIENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT +JklQUyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI +hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNzUwWhcNMjUxMjI3 +MDEwNzUwWjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ +BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp +bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G +LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMw +gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO6AAPYaZC6tasiDsYun7o/ZttvN +G7uGBiJ2MwwSbUhWYdLcgiViL5/SaTBlA0IjWLxH3GvWdV0XPOH/8lhneaDBgbHU +VqLyjRGZ/fZ98cfEXgIqmuJKtROKAP2Md4bm15T1IHUuDky/dMQ/gT6DtKM4Ninn +6Cr1jIhBqoCm42zvAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUHp9XUEe2YZM50yz8 +2l09BXW3mQIwggFGBgNVHSMEggE9MIIBOYAUHp9XUEe2YZM50yz82l09BXW3mQKh +ggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ +BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp +bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G +LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOC +AQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUF +BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYB +BAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglg +hkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud +EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMyBD +QSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG +SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgBhvhC +AQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMy5j +cmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2 +b2NhdGlvbkNMQVNFQTMuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cu +aXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTMuaHRtbD8wOwYJYIZIAYb4QgEI +BC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5Q0xBU0VBMy5odG1s +MHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvaXBz +MjAwMkNMQVNFQTMuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz +MjAwMi9pcHMyMDAyQ0xBU0VBMy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF +BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAEo9IEca +2on0eisxeewBwMwB9dbB/MjD81ACUZBYKp/nNQlbMAqBACVHr9QPDp5gJqiVp4MI +3y2s6Q73nMify5NF8bpqxmdRSmlPa/59Cy9SKcJQrSRE7SOzSMtEQMEDlQwKeAYS +AfWRMS1Jjbs/RU4s4OjNtckUFQzjB4ObJnXv +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICtzCCAiACAQAwDQYJKoZIhvcNAQEEBQAwgaMxCzAJBgNVBAYTAkVTMRIwEAYD +VQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UEChMQSVBT +IFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVzMRcwFQYDVQQD +Ew5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVz +MB4XDTk4MDEwMTIzMjEwN1oXDTA5MTIyOTIzMjEwN1owgaMxCzAJBgNVBAYTAkVT +MRIwEAYDVQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UE +ChMQSVBTIFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVzMRcw +FQYDVQQDEw5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwu +aXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsT1J0nznqjtwlxLyY +XZhkJAk8IbPMGbWOlI6H0fg3PqHILVikgDVboXVsHUUMH2Fjal5vmwpMwci4YSM1 +gf/+rHhwLWjhOgeYlQJU3c0jt4BT18g3RXIGJBK6E2Ehim51KODFDzT9NthFf+G4 +Nu+z4cYgjui0OLzhPvYR3oydAQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBACzzw3lY +JN7GO9HgQmm47mSzPWIBubOE3yN93ZjPEKn+ANgilgUTB1RXxafey9m4iEL2mdsU +dx+2/iU94aI+A6mB0i1sR/WWRowiq8jMDQ6XXotBtDvECgZAHd1G9AHduoIuPD14 +cJ58GNCr+Lh3B0Zx8coLY1xq+XKU1QFPoNtC +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIIODCCB6GgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCAR4xCzAJBgNVBAYTAkVT +MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE +ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE +ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjE0MDIGA1UECxMr +SVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE0MDIG +A1UEAxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMTAx +OFoXDTI1MTIyNzAxMTAxOFowggEeMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFy +Y2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5l +dCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlw +cy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxNDAyBgNVBAsTK0lQUyBDQSBUaW1lc3Rh +bXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxNDAyBgNVBAMTK0lQUyBDQSBU +aW1lc3RhbXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0B +CQEWD2lwc0BtYWlsLmlwcy5lczCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +vLjuVqWajOY2ycJioGaBjRrVetJznw6EZLqVtJCneK/K/lRhW86yIFcBrkSSQxA4 +Efdo/BdApWgnMjvEp+ZCccWZ73b/K5Uk9UmSGGjKALWkWi9uy9YbLA1UZ2t6KaFY +q6JaANZbuxjC3/YeE1Z2m6Vo4pjOxgOKNNtMg0GmqaMCAwEAAaOCBIAwggR8MB0G +A1UdDgQWBBSL0BBQCYHynQnVDmB4AyKiP8jKZjCCAVAGA1UdIwSCAUcwggFDgBSL +0BBQCYHynQnVDmB4AyKiP8jKZqGCASakggEiMIIBHjELMAkGA1UEBhMCRVMxEjAQ +BgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJ +UFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJp +cHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMTQwMgYDVQQLEytJUFMg +Q0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTQwMgYDVQQD +EytJUFMgQ0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4w +HAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAM +BgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIB +FgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYD +VR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlw +cy5lczBHBglghkgBhvhCAQ0EOhY4VGltZXN0YW1waW5nIENBIENlcnRpZmljYXRl +IGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgECBBwWGmh0 +dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMEAGCWCGSAGG+EIBBAQzFjFodHRwOi8v +d3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMEUGCWCG +SAGG+EIBAwQ4FjZodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25U +aW1lc3RhbXBpbmcuaHRtbD8wQgYJYIZIAYb4QgEHBDUWM2h0dHA6Ly93d3cuaXBz +LmVzL2lwczIwMDIvcmVuZXdhbFRpbWVzdGFtcGluZy5odG1sPzBABglghkgBhvhC +AQgEMxYxaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lUaW1lc3RhbXBp +bmcuaHRtbDB/BgNVHR8EeDB2MDegNaAzhjFodHRwOi8vd3d3Lmlwcy5lcy9pcHMy +MDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMDugOaA3hjVodHRwOi8vd3d3YmFj +ay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyVGltZXN0YW1waW5nLmNybDAvBggrBgEF +BQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZI +hvcNAQEFBQADgYEAZbrBzAAalZHK6Ww6vzoeFAh8+4Pua2JR0zORtWB5fgTYXXk3 +6MNbsMRnLWhasl8OCvrNPzpFoeo2zyYepxEoxZSPhExTCMWTs/zif/WN87GphV+I +3pGW7hdbrqXqcGV4LCFkAZXOzkw+UPS2Wctjjba9GNSHSl/c7+lW8AoM6HU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy +NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD +cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs +2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY +JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE +Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ +n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A +PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICXDCCAcWgAwIBAgIQCgEBAQAAAnwAAAALAAAAAjANBgkqhkiG9w0BAQUFADA6 +MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp +dHkgMTAyNCBWMzAeFw0wMTAyMjIyMTAxNDlaFw0yNjAyMjIyMDAxNDlaMDoxGTAX +BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAx +MDI0IFYzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDV3f5mCc8kPD6ugU5O +isRpgFtZO9+5TUzKtS3DJy08rwBCbbwoppbPf9dYrIMKo1W1exeQFYRMiu4mmdxY +78c4pqqv0I5CyGLXq6yp+0p9v+r+Ek3d/yYtbzZUaMjShFbuklNhCbM/OZuoyZu9 +zp9+1BlqFikYvtc6adwlWzMaUQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBTEwBykB5T9zU0B1FTapQxf3q4FWjAd +BgNVHQ4EFgQUxMAcpAeU/c1NAdRU2qUMX96uBVowDQYJKoZIhvcNAQEFBQADgYEA +Py1q4yZDlX2Jl2X7deRyHUZXxGFraZ8SmyzVWujAovBDleMf6XbN3Ou8k6BlCsdN +T1+nr6JGFLkM88y9am63nd4lQtBU/55oc2PcJOsiv6hy8l4A4Q1OOkNumU4/iXgD +mMrzVcydro7BqkWY+o8aoI2II/EVQQ2lRj6RP4vr93E= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6 +MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp +dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX +BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy +MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp +eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg +/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl +wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh +AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2 +PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu +AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR +MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc +HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/ +Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+ +f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO +rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch +6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3 +7CAFYd4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx +MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG +29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk +oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk +3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL +qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN +nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX +ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H +DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO +TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv +kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w +zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy +MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk +ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn +ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71 +9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO +hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U +tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o +BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh +SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww +OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv +cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA +7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k +/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm +eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6 +u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy +7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR +iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDXDCCAsWgAwIBAgICA+owDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRF +MRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFU +QyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJI +MSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAyIENBMSkwJwYJKoZIhvcN +AQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05ODAzMDkxMTU5NTla +Fw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVy +ZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9y +IFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1 +c3RDZW50ZXIgQ2xhc3MgMiBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVA +dHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANo46O0y +AClxgwENv4wB3NrGrTmkqYov1YtcaF9QxmL1Zr3KkSLsqh1R1z2zUbKDTl3LSbDw +TFXlay3HhQswHJJOgtTKAu33b77c4OMUuAVT8pr0VotanoWT0bSCVq5Nu6hLVxa8 +/vhYnvgpjbB7zXjJT6yLZwzxnPv8V5tXXE8NAgMBAAGjazBpMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3 +LnRydXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G +CSqGSIb3DQEBBAUAA4GBAIRS+yjf/x91AbwBvgRWl2p0QiQxg/lGsQaKic+WLDO/ +jLVfenKhhQbOhvgFjuj5Jcrag4wGrOs2bYWRNAQ29ELw+HkuCkhcq8xRT3h2oNms +Gb0q0WkEKJHKNhAngFdb0lz1wlurZIFjdFH0l7/NEij3TWZ/p/AcASZ4smZHcFFk +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDXDCCAsWgAwIBAgICA+swDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRF +MRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFU +QyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJI +MSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAzIENBMSkwJwYJKoZIhvcN +AQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05ODAzMDkxMTU5NTla +Fw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVy +ZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9y +IFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1 +c3RDZW50ZXIgQ2xhc3MgMyBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVA +dHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALa0wTUF +Lg2N7KBAahwOJ6ZQkmtQGwfeLud2zODa/ISoXoxjaitN2U4CdhHBC/KNecoAtvGw +Dtf7pBc9r6tpepYnv68zoZoqWarEtTcI8hKlMbZD9TKWcSgoq40oht+77uMMfTDW +w1Krj10nnGvAo+cFa1dJRLNu6mTP0o56UHd3AgMBAAGjazBpMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3 +LnRydXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G +CSqGSIb3DQEBBAUAA4GBABY9xs3Bu4VxhUafPiCPUSiZ7C1FIWMjWwS7TJC4iJIE +Tb19AaM/9uzO8d7+feXhPrvGq14L3T2WxMup1Pkm5gZOngylerpuw3yCGdHHsbHD +2w2Om0B8NwvxXej9H5CIpQ5ON2QhqE6NtJ/x3kit1VYYUimLRzQSCdS7kjXvD9s0 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE +SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg +Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV +BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl +cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA +vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu +Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a +0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1 +4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN +eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD +R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG +A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu +dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME +Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3 +WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw +HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ +KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO +Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX +wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ +2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89 +9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0 +jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38 +aQNiuJkFBT1reBK9sG9l +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJE +SzEMMAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEw +ODM5MzBaFw0zNzAyMTEwOTA5MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNU +REMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuHnEz9pPPEXyG9VhDr +2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0zY0s +2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItU +GBxIYXvViGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKj +dGqPqcNiKXEx5TukYBdedObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+r +TpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB5DCB4TCB3gYIKoFQgSkB +AQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBv +c2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRl +ciBmcmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEu +MS4xLiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIg +T0lEIDEuMi4yMDguMTY5LjEuMS4xLjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1Ud +HwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEMMAoGA1UEChMDVERDMRQwEgYD +VQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYmaHR0cDovL2Ny +bC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy +MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZ +J2cdUBVLc647+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqG +SIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACrom +JkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4A9G28kNBKWKnctj7fAXmMXAnVBhO +inxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYscA+UYyAFMP8uXBV2Y +caaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9AOoB +mbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQ +YqbsFbS1AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9 +BKNDLdr8C2LqL19iUw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD +VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT +ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj +IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X +DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw +EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE +ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy +dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD +QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53 +dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK +wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7 +G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF +AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7 +c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P +9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD +VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT +ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt +YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu +Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT +AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa +MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp +b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG +cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh +d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY +DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E +rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq +uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN +BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP +MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa +/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei +gQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD +VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT +ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p +dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv +bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa +QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY +BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u +IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl +bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu +Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs +Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI +Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD +ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH +b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh +KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy +dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t +MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB +MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG +A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp +b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl +cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv +bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE +VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ +ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR +uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI +hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM +pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm +MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx +MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 +dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl +cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 +DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 +yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX +L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj +EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG +7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e +QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ +qdq5snUb9kLy78fyGPmJvKP/iiMucEc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN +BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd +BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN +MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g +Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG +A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l +c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT +6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa +Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL +8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC +9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ +pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ +CayJSdM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB +kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw +IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG +EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD +VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu +dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 +E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ +D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK +4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq +lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW +bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB +o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT +MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js +LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr +BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB +AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft +Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj +j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH +KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv +2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 +mfnGV/TJVTl4uix5yaaIK/QI +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB +rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt +Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa +Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV +BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l +dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE +AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B +YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9 +hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l +L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm +SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM +1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws +6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw +Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50 +aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH +AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u +7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0 +xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ +rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim +eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk +USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe +MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v +d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh +cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn +0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ +M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a +MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd +oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI +DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy +oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy +bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF +BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli +CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE +CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t +3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS +KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCB +ozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3Qt +TmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5WhcNMTkwNzA5MTg1 +NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0 +IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYD +VQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VS +Rmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCz+5Gh5DZVhawGNFugmliy+LUPBXeDrjKxdpJo7CNKyXY/45y2 +N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4CjDUeJT1FxL+78P/m4FoCH +iZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXuOzr0hARe +YFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1 +axwiP8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6g +yN7igEL66S/ozjIEj3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQD +AgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPh +ahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9V +VE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0GCSqGSIb3DQEB +BQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y +IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6Lzs +QCv4AdRWOOTKRIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4 +ZSfP1FMa8Kxun08FDAOBp4QpxFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qM +YEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAqDbUMo2s/rn9X9R+WfN9v3YIwLGUb +QErNaLly7HF27FSOH4UMAWr6pjisH8SE +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy +NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y +LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+ +TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y +TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0 +LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW +I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw +nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy +NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY +dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 +WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS +v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v +UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu +IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC +W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh +c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05 +NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD +VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp +bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB +jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N +H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR +4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN +BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo +EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5 +FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx +lA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK +VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm +Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J +h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul +uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68 +DzFc6PLZ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4 +nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO +8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV +ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb +PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2 +6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr +n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a +qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4 +wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 +ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs +pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4 +E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh +YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7 +FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G +CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg +J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc +r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns +YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y +aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe +Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj +IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx +KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM +HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw +DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC +AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji +nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX +rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn +jBJ7xUS0rg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy +aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp +Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV +BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp +Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g +Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU +J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO +JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY +wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o +koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN +qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E +Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe +xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u +7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU +sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI +sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP +cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE +BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is +I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G +CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do +lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc +AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 +pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 +13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk +U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i +F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY +oJ2daZH9 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM +HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK +qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj +cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y +cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP +T8qAkbYp +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 +GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ ++mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd +U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm +NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY +ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ +ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 +CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq +g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm +fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c +2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ +bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG +A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD +VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0 +MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV +BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy +dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ +ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII +0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI +uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI +hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3 +YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc +1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDzTCCAzagAwIBAgIQU2GyYK7bcY6nlLMTM/QHCTANBgkqhkiG9w0BAQUFADCB +wTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTwwOgYDVQQL +EzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1 +dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmswHhcNMDAwOTI2MDAwMDAwWhcNMTAwOTI1MjM1OTU5WjCBpTEXMBUGA1UEChMO +VmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsx +OzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5j +b20vcnBhIChjKTAwMSwwKgYDVQQDEyNWZXJpU2lnbiBUaW1lIFN0YW1waW5nIEF1 +dGhvcml0eSBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0hmdZ8IAIVli +zrQJIkRpivglWtvtDbc2fk7gu5Q+kCWHwmFHKdm9VLhjzCx9abQzNvQ3B5rB3UBU +/OB4naCTuQk9I1F/RMIUdNsKvsvJMDRAmD7Q1yUQgZS9B0+c1lQn3y6ov8uQjI11 +S7zi6ESHzeZBCiVu6PQkAsVSD27smHUCAwEAAaOB3zCB3DAPBgNVHRMECDAGAQH/ +AgEAMEUGA1UdIAQ+MDwwOgYMYIZIAYb4RQEHFwEDMCowKAYIKwYBBQUHAgEWHGh0 +dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwMQYDVR0fBCowKDAmoCSgIoYgaHR0 +cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwCwYDVR0PBAQDAgEGMEIGCCsG +AQUFBwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJpc2lnbi5j +b20vb2NzcC9zdGF0dXMwDQYJKoZIhvcNAQEFBQADgYEAgnBold+2DcIBcBlK0lRW +HqzyRUyHuPU163hLBanInTsZIS5wNEqi9YngFXVF5yg3ADQnKeg3S/LvRJdrF1Ea +w1adPBqK9kpGRjeM+sv1ZFo4aC4cw+9wzrhGBha/937ntag+RaypJXUie28/sJyU +58dzq6wf7iWbwBbtt8pb8BQ= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw +CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h +dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l +cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h +2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E +lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV +ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq +299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t +vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL +dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF +AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR +zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 +LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd +7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw +++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgICAx4wDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCVVMx +DTALBgNVBAoTBFZJU0ExLzAtBgNVBAsTJlZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2 +aWNlIEFzc29jaWF0aW9uMRIwEAYDVQQDEwlHUCBSb290IDIwHhcNMDAwODE2MjI1 +MTAwWhcNMjAwODE1MjM1OTAwWjBhMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklT +QTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRp +b24xEjAQBgNVBAMTCUdQIFJvb3QgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKkBcLWqxEDwq2omYXkZAPy/mzdZDK9vZBv42pWUJGkzEXDK41Z0ohdX +ZFwgBuHW73G3O/erwWnQSaSxBNf0V2KJXLB1LRckaeNCYOTudNargFbYiCjh+20i +/SN8RnNPflRzHqgsVVh1t0zzWkWlAhr62p3DRcMiXvOL8WAp0sdftAw6UYPvMPjU +58fy+pmjIlC++QU3o63tmsPm7IgbthknGziLgE3sucfFicv8GjLtI/C1AVj59o/g +halMCXI5Etuz9c9OYmTaxhkVOmMd6RdVoUwiPDQyRvhlV7or7zaMavrZ2UT0qt2E +1w0cslSsMoW0ZA3eQbuxNMYBhjJk1Z8CAwEAAaNCMEAwHQYDVR0OBBYEFJ59SzS/ +ca3CBfYDdYDOqU8axCRMMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQAhpXYUVfmtJ3CPPPTVbMjMCqujmAuKBiPFyWHb +mQdpNSYx/scuhMKZYdQN6X0uEyt8joW2hcdLzzW2LEc9zikv2G+fiRxkk78IvXbQ +kIqUs38oW26sTTMs7WXcFsziza6kPWKSBpUmv9+55CCmc2rBvveURNZNbyoLaxhN +dBA2aGpawWqn3TYpjLgwi08hPwAuVDAHOrqK5MOeyti12HvOdUVmB/RtLdh6yumJ +ivIj2C/LbgA2T/vwLwHMD8AiZfSr4k5hLQOCfZEWtTDVFN5ex5D8ofyrEK9ca3Cn +B+8phuiyJccg/ybdd+95RBTEvd07xQObdyPsoOy7Wjm1zK0G +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIETzCCAzegAwIBAgIEO63vKTANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE +ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg +U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDEwOTIzMTQxODE3WhcNMTEw +OTIzMTMxODE3WjB1MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v +LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MR8wHQYDVQQDExZDQyBTaWdu +ZXQgLSBDQSBLbGFzYSAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4SRW9Q58g5DY1Hw7h +gCRKBEdPdGn0MFHsfw7rlu/oQm7IChI/uWd9q5wwo77YojtTDjRnpgZsjqBeynX8T90vFILqsY2K +5CF1OESalwvVr3sZiQX79lisuFKat92u6hBFikFIVxfHHB67Af+g7u0dEHdDW7lwy81MwFYxBTRy +9wIDAQABo4IBbTCCAWkwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwggEEBgNVHSAE +gfwwgfkwgfYGDSsGAQQBvj8CAQoBAQAwgeQwgZoGCCsGAQUFBwICMIGNGoGKQ2VydHlmaWthdCB3 +eXN0YXdpb255IHpnb2RuaWUgeiBkb2t1bWVudGVtOiAiUG9saXR5a2EgQ2VydHlmaWthY2ppIGRs +YSBSb290Q0EiLiBDZXJ0eWZpa2F0IHd5c3Rhd2lvbnkgcHJ6ZXogUm9vdENBIHcgaGllcmFyY2hp +aSBDQyBTaWduZXQuMEUGCCsGAQUFBwIBFjlodHRwOi8vd3d3LnNpZ25ldC5wbC9yZXBvenl0b3Jp +dW0vZG9rdW1lbnR5L3BjX3Jvb3RjYS50eHQwHwYDVR0jBBgwFoAUwJvFIw0C4aZOSGsfAOnjmhQb +sa8wHQYDVR0OBBYEFMODHtVZd1T7TftXR/nEI1zR54njMA0GCSqGSIb3DQEBBQUAA4IBAQBRIHQB +FIGh8Jpxt87AgSLwIEEk4+oGy769u3NtoaR0R3WNMdmt7fXTi0tyTQ9V4AIszxVjhnUPaKnF1KYy +f8Tl+YTzk9ZfFkZ3kCdSaILZAOIrmqWNLPmjUQ5/JiMGho0e1YmWUcMci84+pIisTsytFzVP32/W ++sz2H4FQAvOIMmxB7EJX9AdbnXn9EXZ+4nCqi0ft5z96ZqOJJiCB3vSaoYg+wdkcvb6souMJzuc2 +uptXtR1Xf3ihlHaGW+hmnpcwFA6AoNrom6Vgzk6U1ienx0Cw28BhRSKqzKkyXkuK8gRflZUx84uf +tXncwKJrMiE3lvgOOBITRzcahirLer4c +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIE9zCCA9+gAwIBAgIEPL/xoTANBgkqhkiG9w0BAQUFADB2MQswCQYDVQQGEwJQTDEfMB0GA1UE +ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg +U2lnbmV0MSAwHgYDVQQDExdDQyBTaWduZXQgLSBQQ0EgS2xhc2EgMjAeFw0wMjA0MTkxMDI5NTNa +Fw0xNzA0MTgxMjUzMDdaMHUxCzAJBgNVBAYTAlBMMR8wHQYDVQQKExZUUCBJbnRlcm5ldCBTcC4g +eiBvLm8uMSQwIgYDVQQLExtDZW50cnVtIENlcnR5ZmlrYWNqaSBTaWduZXQxHzAdBgNVBAMTFkND +IFNpZ25ldCAtIENBIEtsYXNhIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqgLJu +QqY4yavbSgHg8CyfKTx4BokNSDOVz4eD9vptUr11Kqd06ED1hlH7Sg0goBFAfntNU/QTKwSBaNui +me7C4sSEdgsKrPoAhGb4Mq8y7Ty7RqZz7mkzNMqzL2L2U4yQ2QjvpH8MH0IBqOWEcpSkpwnrCDIm +RoTfd+YlZWKi2JceQixUUYIQ45Ox8+x8hHbvvZdgqtcvo8PW27qoHkp/7hMuJ44kDAGrmxffBXl/ +OBRZp0uO1CSLcMcVJzyr2phKhy406MYdWrtNPEluGs0GFDzd0nrIctiWAO4cmct4S72S9Q6e//0G +O9f3/Ca5Kb2I1xYLj/xE+HgjHX9aD2MhAgMBAAGjggGMMIIBiDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjCB4wYDVR0gBIHbMIHYMIHVBg0rBgEEAb4/AhQKAQEAMIHDMHUGCCsGAQUF +BwICMGkaZ0NlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0 +eWthIENlcnR5ZmlrYWNqaSBQQ0EyIC0gQ2VydHlmaWthdHkgVXJ6ZWRvdyBLbGFzeSAyIi4wSgYI +KwYBBQUHAgEWPmh0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9kb2t1bWVudHkva2xh +c2EyL3BjX3BjYTIudHh0MD8GA1UdHwQ4MDYwNKAyoDCGLmh0dHA6Ly93d3cuc2lnbmV0LnBsL3Jl +cG96eXRvcml1bS9jcmwvcGNhMi5jcmwwHwYDVR0jBBgwFoAUwGxGyl2CfpYHRonE82AVXO08kMIw +HQYDVR0OBBYEFLtFBlILy4HNKVSzvHxBTM0HDowlMA0GCSqGSIb3DQEBBQUAA4IBAQBWTsCbqXrX +hBBev5v5cIuc6gJM8ww7oR0uMQRZoFSqvQUPWBYM2/TLI/f8UM9hSShUVj3zEsSj/vFHagUVmzuV +Xo5u0WK8iaqATSyEVBhADHrPG6wYcLKJlagge/ILA0m+SieyP2sjYD9MUB9KZIEyBKv0429UuDTw +6P7pslxMWJBSNyQxaLIs0SRKsqZZWkc7ZYAj2apSkBMX2Is1oHA+PwkF6jQMwCao/+CndXPUzfCF +6caa9WwW31W26MlXCvSmJgfiTPwGvm4PkPmOnmWZ3CczzhHl4q7ztHFzshJH3sZWDnrWwBFjzz5e +Pr3WHV1wA7EY6oT4zBx+2gT9XBTB +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEUzCCAzugAwIBAgIEPq+qjzANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJQTDE3MDUGA1UE +ChMuQ1ppQyBDZW50cmFzdCBTQSB3IGltaWVuaXUgTWluaXN0cmEgR29zcG9kYXJraTEZMBcGA1UE +AxMQQ1ppQyBDZW50cmFzdCBTQTAeFw0wMzA0MzAxMDUwNTVaFw0wODA0MjgxMDUwNTVaMGgxCzAJ +BgNVBAYTAlBMMR8wHQYDVQQKExZUUCBJbnRlcm5ldCBTcC4geiBvLm8uMR8wHQYDVQQDExZDQyBT +aWduZXQgLSBDQSBLbGFzYSAzMRcwFQYDVQQFEw5OdW1lciB3cGlzdTogNDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALVdeOM62cPH2NERFxbS5FIp/HSv3fgesdVsTUFxZbGtE+/E0RMl +KZQJHH9emx7vRYubsi4EOLCjYsCOTFvgGRIpZzx7R7T5c0Di5XFkRU4gjBl7aHJoKb5SLzGlWdoX +GsekVtl6keEACrizV2EafqjI8cnBWY7OxQ1ooLQp5AeFjXg+5PT0lO6TUZAubqjFbhVbxSWjqvdj +93RGfyYE76MnNn4c2xWySD07n7uno06TC0IJe6+3WSX1h+76VsIFouWBXOoM7cxxiLjoqdBVu24+ +P8e81SukE7qEvOwDPmk9ZJFtt1nBNg8a1kaixcljrA/43XwOPz6qnJ+cIj/xywECAwEAAaOCAQow +ggEGMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMDMGA1UdIAEB/wQpMCcwJQYEVR0g +ADAdMBsGCCsGAQUFBwIBFg93d3cuY2VudHJhc3QucGwwgY4GA1UdIwSBhjCBg4AU2a7r85Cp1iJN +W0Ca1LR6VG3996ShZaRjMGExCzAJBgNVBAYTAlBMMTcwNQYDVQQKEy5DWmlDIENlbnRyYXN0IFNB +IHcgaW1pZW5pdSBNaW5pc3RyYSBHb3Nwb2RhcmtpMRkwFwYDVQQDExBDWmlDIENlbnRyYXN0IFNB +ggQ9/0sQMB0GA1UdDgQWBBR7Y8wZkHq0zrY7nn1tFSdQ0PlJuTANBgkqhkiG9w0BAQUFAAOCAQEA +ldt/svO5c1MU08FKgrOXCGEbEPbQxhpM0xcd6Iv3dCo6qugEgjEs9Qm5CwUNKMnFsvR27cJWUvZb +MVcvwlwCwclOdwF6u/QRS8bC2HYErhYo9bp9yuxxzuow2A94c5fPqfVrjXy+vDouchAm6+A5Wjzv +J8wxVFDCs+9iGACmyUWr/JGXCYiQIbQkwlkRKHHlan9ymKf1NvIej/3EpeT8fKr6ywxGuhAfqofW +pg3WJY/RCB4lTzD8vZGNwfMFGkWhJkypad3i9w3lGmDVpsHaWtCgGfd0H7tUtWPkP+t7EjIRCD9J +HYnTR+wbbewc5vOI+UobR15ynGfFIaSIiMTVtQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEejCCA2KgAwIBAgIEP4vk6TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJQ +TDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2Vu +dHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MR8wHQYDVQQDExZDQyBTaWduZXQgLSBD +QSBLbGFzYSAyMB4XDTAzMTAxNDExNTgyMloXDTE3MDQxODEyNTMwN1owdzELMAkG +A1UEBhMCUEwxHzAdBgNVBAoTFlRQIEludGVybmV0IFNwLiB6IG8uby4xJDAiBgNV +BAsTG0NlbnRydW0gQ2VydHlmaWthY2ppIFNpZ25ldDEhMB8GA1UEAxMYQ0MgU2ln +bmV0IC0gT0NTUCBLbGFzYSAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo +VCsaBStblXQYVNthe3dvaCrfvKpPXngh4almm988iIlEv9CVTaAdCfaJNihvA+Vs +Qw8++ix1VqteMQE474/MV/YaXigP0Zr0QB+g+/7PWVlv+5U9Gzp9+Xx4DJay8AoI +iB7Iy5Qf9iZiHm5BiPRIuUXT4ZRbZRYPh0/76vgRsQIDAQABo4IBkjCCAY4wDgYD +VR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMJMEEGA1UdHwQ6MDgwNqA0 +oDKGMGh0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9jcmwva2xhc2Ey +LmNybDCB2AYDVR0gBIHQMIHNMIHKBg4rBgEEAb4/AoFICgwBADCBtzBsBggrBgEF +BQcCAjBgGl5DZXJ0eWZpa2F0IHd5ZGFueSB6Z29kbmllIHogZG9rdW1lbnRlbSAi +UG9saXR5a2EgQ2VydHlmaWthY2ppIC0gQ2VydHlmaWthdHkgcmVzcG9uZGVyb3cg +T0NTUCIuMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnNpZ25ldC5wbC9yZXBvenl0 +b3JpdW0vZG9rdW1lbnR5L3BjX29jc3BfMV8wLnBkZjAfBgNVHSMEGDAWgBS7RQZS +C8uBzSlUs7x8QUzNBw6MJTAdBgNVHQ4EFgQUKEVrOY7cEHvsVgvoyZdytlbtgwEw +CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAQrRg5MV6dxr0HU2IsLInxhvt +iUVmSFkIUsBCjzLoewOXA16d2oDyHhI/eE+VgAsp+2ANjZu4xRteHIHoYMsN218M +eD2MLRsYS0U9xxAFK9gDj/KscPbrrdoqLvtPSMhUb4adJS9HLhvUe6BicvBf3A71 +iCNe431axGNDWKnpuj2KUpj4CFHYsWCXky847YtTXDjri9NIwJJauazsrSjK+oXp +ngRS506mdQ7vWrtApkh8zhhWp7duCkjcCo1O8JxqYr2qEW1fXmgOISe010v2mmuv +hHxPyVwoAU4KkOw0nbXZn53yak0is5+XmAjh0wWue44AssHrjC9nUh3mkLt6eQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEezCCA2OgAwIBAgIEP4vnLzANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJQ +TDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEfMB0GA1UEAxMWQ0Mg +U2lnbmV0IC0gQ0EgS2xhc2EgMzEXMBUGA1UEBRMOTnVtZXIgd3Bpc3U6IDQwHhcN +MDMxMDE0MTIwODAwWhcNMDgwNDI4MTA1MDU1WjB3MQswCQYDVQQGEwJQTDEfMB0G +A1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBD +ZXJ0eWZpa2FjamkgU2lnbmV0MSEwHwYDVQQDExhDQyBTaWduZXQgLSBPQ1NQIEts +YXNhIDMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM/9GwvARNuCVN+PqZmO +4FqH8vTqhenUyqRkmAVT4YhLu0a9AXeLAYVDu+NTkYzsAUMAfu55rIKHNLlm6WbF +KvLiKKz4p4pbUr+ToPcwl/TDotidloUdBAxDg0SL+PmQqACZDe3seJho2IYf2vDL +/G4TLMbKmNB0mlWFuN0f4fJNAgMBAAGjggGgMIIBnDAOBgNVHQ8BAf8EBAMCB4Aw +EwYDVR0lBAwwCgYIKwYBBQUHAwkwTwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3 +dy5zaWduZXQucGwva3dhbGlmaWtvd2FuZS9yZXBvenl0b3JpdW0vY3JsL2tsYXNh +My5jcmwwgdgGA1UdIASB0DCBzTCBygYOKwYBBAG+PwKCLAoCAQAwgbcwbAYIKwYB +BQUHAgIwYBpeQ2VydHlmaWthdCB3eWRhbnkgemdvZG5pZSB6IGRva3VtZW50ZW0g +IlBvbGl0eWthIENlcnR5ZmlrYWNqaSAtIENlcnR5ZmlrYXR5IHJlc3BvbmRlcm93 +IE9DU1AiLjBHBggrBgEFBQcCARY7aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5 +dG9yaXVtL2Rva3VtZW50eS9wY19vY3NwXzFfMC5wZGYwHwYDVR0jBBgwFoAUe2PM +GZB6tM62O559bRUnUND5SbkwHQYDVR0OBBYEFG4jnCMvBALRQXtmDn9TyXQ/EKP+ +MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEBACXrKG5Def5lpRwmZom3UEDq +bl7y4U3qomG4B+ok2FVZGgPZti+ZgvrenPj7PtbYCUBPsCSTNrznKinoT3gD9lQQ +xkEHwdc6VD1GlFp+qI64u0+wS9Epatrdf7aBnizrOIB4LJd4E2TWQ6trspetjMIU +upyWls1BmYUxB91R7QkTiAUSNZ87s3auhZuG4f0V0JLVCcg2rn7AN1rfMkgxCbHk +GxiQbYWFljl6aatxR3odnnzVUe1I8uoY2JXpmmUcOG4dNGuQYziyKG3mtXCQWvug +5qi9Mf3KUh1oSTKx6HfLjjNl1+wMB5Mdb8LF0XyZLdJM9yIZh7SBRsYm9QiXevY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFGjCCBAKgAwIBAgIEPL7eEDANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE +ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg +U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDIwNDE4MTQ1NDA4WhcNMjYw +OTIxMTU0MjE5WjB2MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v +LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MSAwHgYDVQQDExdDQyBTaWdu +ZXQgLSBQQ0EgS2xhc2EgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7BrBlbN5ma +M5eg0BOTqoZ+9NBDvU8Lm5rTdrMswFTCathzpVVLK/JD4K3+4oCZ9SRAspEXE4gvwb08ASY6w5s+ +HpRkeJw8YzMFR5kDZD5adgnCAy4vDfIXYZgppXPaTQ8wnfUZ7BZ7Zfa7QBemUIcJIzJBB0UqgtxW +Ceol9IekpBRVmuuSA6QG0Jkm+pGDJ05yj2eQG8jTcBENM7sVA8rGRMyFA4skSZ+D0OG6FS2xC1i9 +JyN0ag1yII/LPx8HK5J4W9MaPRNjAEeaa2qI9EpchwrOxnyVbQfSedCG1VRJfAsE/9tT9CMUPZ3x +W20QjQcSZJqVcmGW9gVsXKQOVLsCAwEAAaOCAbMwggGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMIIBBAYDVR0gBIH8MIH5MIH2Bg0rBgEEAb4/AgEKAQEBMIHkMIGaBggrBgEFBQcC +AjCBjRqBikNlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0 +eWthIENlcnR5ZmlrYWNqaSBkbGEgUm9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6 +IFJvb3RDQSB3IGhpZXJhcmNoaWkgQ0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5z +aWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY19yb290Y2EudHh0MEQGA1UdHwQ9MDsw +OaA3oDWGM2h0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9yb290Y2Evcm9vdGNhLmNy +bDAfBgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAdBgNVHQ4EFgQUwGxGyl2CfpYHRonE +82AVXO08kMIwDQYJKoZIhvcNAQEFBQADggEBABp1TAUsa+BeVWg4cjowc8yTJ5XN3GvN96GObMkx +UGY7U9kVrLI71xBgoNVyzXTiMNDBvjh7vdPWjpl5SDiRpnnKiOFXA43HvNWzUaOkTu1mxjJsZsan +ot1Xt6j0ZDC+03FjLHdYMyM9kSWp6afb4980EPYZCcSzgM5TOGfJmNii5Tq468VFKrX+52Aou1G2 +2Ohu+EEOlOrG7ylKv1hHUJJCjwN0ZVEIn1nDbrU9FeGCz8J9ihVUvnENEBbBkU37PWqWuHitKQDV +tcwTwJJdR8cmKq3NmkwAm9fPacidQLpaw0WkuGrS+fEDhu1Nhy9xELP6NA9GRTCNxm/dXlcwnmY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFGjCCBAKgAwIBAgIEPV0tNDANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE +ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg +U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDIwODE2MTY0OTU2WhcNMjYw +OTIxMTU0MjE5WjB2MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v +LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MSAwHgYDVQQDExdDQyBTaWdu +ZXQgLSBQQ0EgS2xhc2EgMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALN3LanJtdue +Ne6geWUTFENa+lEuzqELcoqhYB+a/tJcPEkc6TX/bYPzalRRjqs+quMP6KZTU0DixOrV+K7iWaqA +iQ913HX5IBLmKDCrTVW/ZvSDpiBKbxlHfSNuJxAuVT6HdbzK7yAW38ssX+yS2tZYHZ5FhZcfqzPE +OpO94mAKcBUhk6T/ki0evXX/ZvvktwmF3hKattzwtM4JMLurAEl8SInyEYULw5JdlfcBez2Tg6Db +w34hA1A+ckTwhxzecrB8TUe2BnQKOs9vr2cCACpFFcOmPkM0Drtjctr1QHm1tYSqRFRf9VcV5tfC +3P8QqoK4ONjtLPHc9x5NE1uK/FMCAwEAAaOCAbMwggGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMIIBBAYDVR0gBIH8MIH5MIH2Bg0rBgEEAb4/AgEKAQECMIHkMIGaBggrBgEFBQcC +AjCBjRqBikNlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0 +eWthIENlcnR5ZmlrYWNqaSBkbGEgUm9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6 +IFJvb3RDQSB3IGhpZXJhcmNoaWkgQ0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5z +aWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY19yb290Y2EudHh0MEQGA1UdHwQ9MDsw +OaA3oDWGM2h0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9yb290Y2Evcm9vdGNhLmNy +bDAfBgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAdBgNVHQ4EFgQUXvthcPHlH5BgGhlM +ErJNXWlhlgAwDQYJKoZIhvcNAQEFBQADggEBACIce95Mvn710KCAISA0CuHD4aznTU6pLoCDShW4 +7OR+GTpJUm1coTcUqlBHV9mra4VFrBcBuOkHZoBLq/jmE0QJWnpSEULDcH9J3mF0nqO9SM+mWyJG +dsJF/XU/7smummgjMNQXwzQTtWORF+6v5KUbWX85anO2wR+M6YTBWC55zWpWi4RG3vkHFs5Ze2oF +JTlpuxw9ZgxTnWlwI9QR2MvEhYIUMKMOWxw1nt0kKj+5TCNQQGh/VJJ1dsiroGh/io1DOcePEhKz +1Ag52y6Wf0nJJB9yk0sFakqZH18F7eQecQImgZyyeRtsG95leNugB3BXWCW+KxwiBrtQTXv4dTE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEzzCCA7egAwIBAgIEO6ocGTANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE +ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg +U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDEwOTIwMTY0MjE5WhcNMjYw +OTIxMTU0MjE5WjBxMQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v +LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MRswGQYDVQQDExJDQyBTaWdu +ZXQgLSBSb290Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrr2vydnNpELfGW3Ks +ARiDhJvwDtUe4AbWev+OfMc3+vA29nX8ZmIwno3gmItjo5DbUCCRiCMq5c9epcGu+kg4a3BJChVX +REl8gVh0ST15rr3RKrSc4VgsvQzl0ZUraeQLl8JoRT5PLsUj3qwF78jUCQVckiiLVcnGfZtFCm+D +CJXliQBDMB9XFAUEiO/DtEBs0B7wJGx7lgJeJpQUcGiaOPjcJDYOk7rNAYmmD2gWeSlepufO8luU +YG/YDxTC4mqhRqfa4MnVO5dqy+ICj2UvUpHbZDB0KfGRibgBYeQP1kuqgIzJN4UqknVAJb0aMBSP +l+9k2fAUdchx1njlbdcbAgMBAAGjggFtMIIBaTAPBgNVHRMBAf8EBTADAQH/MIIBBAYDVR0gBIH8 +MIH5MIH2Bg0rBgEEAb4/AgEKAQEAMIHkMIGaBggrBgEFBQcCAjCBjRqBikNlcnR5ZmlrYXQgd3lz +dGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0eWthIENlcnR5ZmlrYWNqaSBkbGEg +Um9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6IFJvb3RDQSB3IGhpZXJhcmNoaWkg +Q0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5dG9yaXVt +L2Rva3VtZW50eS9wY19yb290Y2EudHh0MB0GA1UdDgQWBBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAf +BgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcN +AQEFBQADggEBAGnY5QmYqnnO9OqFOWZxxb25UHRnaRF6IV9aaGit5BZufZj2Tq3v8L3SgE34GOoI +cdRMMG5JEpEU4mN/Ef3oY6Eo+7HfqaPHI4KFmbDSPiK5s+wmf+bQSm0Yq5/h4ZOdcAESlLQeLSt1 +CQk2JoKQJ6pyAf6xJBgWEIlm4RXE4J3324PUiOp83kW6MDvaa1xY976WyInr4rwoLgxVl11LZeKW +ha0RJJxJgw/NyWpKG7LWCm1fglF8JH51vZNndGYq1iKtfnrIOvLZq6bzaCiZm1EurD8HE6P7pmAB +KK6o3C2OXlNfNIgwkDN/cDqk5TYsTkrpfriJPdxXBH8hQOkW89g= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID/TCCA2agAwIBAgIEP4/gkTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJQTDEfMB0GA1UE +ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg +U2lnbmV0MR8wHQYDVQQDExZDQyBTaWduZXQgLSBDQSBLbGFzYSAxMB4XDTAzMTAxNzEyMjkwMloX +DTExMDkyMzExMTgxN1owdjELMAkGA1UEBhMCUEwxHzAdBgNVBAoTFlRQIEludGVybmV0IFNwLiB6 +IG8uby4xJDAiBgNVBAsTG0NlbnRydW0gQ2VydHlmaWthY2ppIFNpZ25ldDEgMB4GA1UEAxMXQ0Mg +U2lnbmV0IC0gVFNBIEtsYXNhIDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOJYrISEtSsd +uHajROh5/n7NGrkpYTT9NEaPe9+ucuQ37KxIbfJwXJjgUc1dw4wCkcQ12FJarD1X6mSQ4cfN/60v +LfKI5ZD4nhJTMKlAj1pX9ScQ/MuyvKStCbn5WTkjPhjRAM0tdwXSnzuTEunfw0Oup559y3Iqxg1c +ExflB6cfAgMBAAGjggGXMIIBkzBBBgNVHR8EOjA4MDagNKAyhjBodHRwOi8vd3d3LnNpZ25ldC5w +bC9yZXBvenl0b3JpdW0vY3JsL2tsYXNhMS5jcmwwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQM +MAoGCCsGAQUFBwMIMIHaBgNVHSAEgdIwgc8wgcwGDSsGAQQBvj8CZAoRAgEwgbowbwYIKwYBBQUH +AgIwYxphQ2VydHlmaWthdCB3eXN0YXdpb255IHpnb2RuaWUgeiBkb2t1bWVudGVtICJQb2xpdHlr +YSBDZXJ0eWZpa2FjamkgQ0MgU2lnbmV0IC0gWm5ha293YW5pZSBjemFzZW0iLjBHBggrBgEFBQcC +ARY7aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY190c2ExXzJf +MS5wZGYwHwYDVR0jBBgwFoAUw4Me1Vl3VPtN+1dH+cQjXNHnieMwHQYDVR0OBBYEFJdDwEqtcavO +Yd9u9tej53vWXwNBMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADgYEAnpiQkqLCJQYXUrqMHUEz ++z3rOqS0XzSFnVVLhkVssvXc8S3FkJIiQTUrkScjI4CToCzujj3EyfNxH6yiLlMbskF8I31JxIeB +vueqV+s+o76CZm3ycu9hb0I4lswuxoT+q5ZzPR8Irrb51rZXlolR+7KtwMg4sFDJZ8RNgOf7tbA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg +b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa +MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB +ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw +IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B +AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb +unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d +BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq +7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 +0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX +roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG +A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j +aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p +26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA +BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud +EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN +BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB +AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd +p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi +1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc +XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 +eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu +tGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo +YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9 +MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy +NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G +A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA +A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0 +Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s +QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV +eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795 +B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh +z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T +AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i +ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w +TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH +MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD +VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE +VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B +AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM +bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi +ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG +VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c +ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ +AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx +ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w +MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD +VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx +FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu +ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7 +gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH +fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a +ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT +ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk +c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto +dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt +aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI +hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk +QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/ +h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR +rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2 +9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMx +IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1 +dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w +HhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTELMAkGA1UEBhMCRVMx +IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1 +dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5u +Cp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5Vj1H5WuretXDE7aTt/6MNbg9kUDGvASdY +rv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJHlShbz++AbOCQl4oBPB3z +hxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf3H5idPay +BQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcL +iam8NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcb +AgMBAAGjgZ8wgZwwKgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lv +bmFsLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0 +MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E +FgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQADggEBAEdz/o0n +VPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq +u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36m +hoEyIwOdyPdfwUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzfl +ZKG+TQyTmAyX9odtsz/ny4Cm7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBp +QWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YGVM+h4k0460tQtcsm9MracEpqoeJ5 +quGnM/b9Sh/22WA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs +IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg +R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A +PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8 +Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL +TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL +5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7 +S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe +2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap +EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td +EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv +/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN +A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0 +abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF +I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz +4iIprn2DQKi6bA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx +ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 +b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD +EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05 +OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G +A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh +Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l +dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK +gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX +iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc +Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E +BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G +SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu +b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh +bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv +Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln +aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0 +IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh +c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph +biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo +ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP +UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj +YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo +dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA +bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06 +sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa +n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS +NitjrFgBazMpUIaD8QFI +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx +ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 +b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD +EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X +DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw +DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u +c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr +TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA +OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC +2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW +RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P +AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW +ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0 +YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz +b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO +ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB +IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs +b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs +ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s +YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg +a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g +SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0 +aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg +YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg +Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY +ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g +pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4 +Fp1hBWeAyNDYpQcCNJgEjTME1A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV +MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe +TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0 +dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB +KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0 +N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC +dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu +MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL +b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD +zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi +3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8 +WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY +Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi +NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC +ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4 +QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0 +YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz +aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu +IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm +ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg +ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs +amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv +IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3 +Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6 +ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1 +YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg +dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs +b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G +CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO +xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP +0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ +QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk +f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK +8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx +ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 +b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD +EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz +aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w +MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G +A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh +Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l +dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh +bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq +eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe +r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5 +3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd +vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l +mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC +wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg +hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0 +TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh +biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg +ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg +dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6 +b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl +c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0 +ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3 +dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu +ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh +bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo +ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3 +Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u +ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA +A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ +MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+ +NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR +VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY +83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3 +macqaJVmlaut74nLYKkGEsaUR+ko +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j +ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js +LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM +BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy +dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh +cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh +YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg +dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp +bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ +YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT +TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ +9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 +jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW +FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz +ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 +ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L +EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu +L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC +O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V +um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh +NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFFjCCBH+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsDELMAkGA1UEBhMCSUwx +DzANBgNVBAgTBklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0 +Q29tIEx0ZC4xGjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS +YWRtaW5Ac3RhcnRjb20ub3JnMB4XDTA1MDMxNzE3Mzc0OFoXDTM1MDMxMDE3Mzc0 +OFowgbAxCzAJBgNVBAYTAklMMQ8wDQYDVQQIEwZJc3JhZWwxDjAMBgNVBAcTBUVp +bGF0MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMRowGAYDVQQLExFDQSBBdXRob3Jp +dHkgRGVwLjEpMCcGA1UEAxMgRnJlZSBTU0wgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkxITAfBgkqhkiG9w0BCQEWEmFkbWluQHN0YXJ0Y29tLm9yZzCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEA7YRgACOeyEpRKSfeOqE5tWmrCbIvNP1h3D3TsM+x +18LEwrHkllbEvqoUDufMOlDIOmKdw6OsWXuO7lUaHEe+o5c5s7XvIywI6Nivcy+5 +yYPo7QAPyHWlLzRMGOh2iCNJitu27Wjaw7ViKUylS7eYtAkUEKD4/mJ2IhULpNYI +LzUCAwEAAaOCAjwwggI4MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgHmMB0G +A1UdDgQWBBQcicOWzL3+MtUNjIExtpidjShkjTCB3QYDVR0jBIHVMIHSgBQcicOW +zL3+MtUNjIExtpidjShkjaGBtqSBszCBsDELMAkGA1UEBhMCSUwxDzANBgNVBAgT +BklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4x +GjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBGcmVlIFNTTCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSYWRtaW5Ac3Rh +cnRjb20ub3JnggEAMB0GA1UdEQQWMBSBEmFkbWluQHN0YXJ0Y29tLm9yZzAdBgNV +HRIEFjAUgRJhZG1pbkBzdGFydGNvbS5vcmcwEQYJYIZIAYb4QgEBBAQDAgAHMC8G +CWCGSAGG+EIBDQQiFiBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAy +BglghkgBhvhCAQQEJRYjaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL2NhLWNybC5j +cmwwKAYJYIZIAYb4QgECBBsWGWh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy8wOQYJ +YIZIAYb4QgEIBCwWKmh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9pbmRleC5waHA/ +YXBwPTExMTANBgkqhkiG9w0BAQQFAAOBgQBscSXhnjSRIe/bbL0BCFaPiNhBOlP1 +ct8nV0t2hPdopP7rPwl+KLhX6h/BquL/lp9JmeaylXOWxkjHXo0Hclb4g4+fd68p +00UOpO6wNnQt8M2YI3s3S9r+UZjEHjQ8iP2ZO1CnwYszx8JSFhKVU2Ui77qLzmLb +cCOxgN8aIDjnfg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk +MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 +YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg +Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT +AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp +Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9 +m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih +FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/ +TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F +EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco +kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu +HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF +vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo +19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC +L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW +bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX +JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw +FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc +K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf +ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik +Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB +sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e +3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR +ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip +mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH +b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf +rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms +hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y +zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6 +MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu +IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw +WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD +ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y +IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn +IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ +6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob +jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw +izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl ++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY +zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP +pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF +KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW +ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB +AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 +ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW +IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA +A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 +uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ +FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 +jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ +u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D +YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 +puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa +icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG +DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x +kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z +Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR +IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q +gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy +yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts +F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 +jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx +ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC +VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK +YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH +EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN +Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud +DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE +MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK +UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf +qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK +ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE +JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 +hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 +EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm +nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX +udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz +ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe +LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl +pYYsfPQS +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc +UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg +MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 +dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz +MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy +dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD +VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg +xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu +xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7 +XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k +heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J +YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C +urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1 +JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51 +b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV +9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7 +kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh +fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy +B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA +aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS +RGQDJereW26fyfJOrN3H +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc +UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS +S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg +SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3 +WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv +bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU +UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw +bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe +LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef +J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh +R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ +Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX +JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p +zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S +Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq +ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 +Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz +gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH +uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS +y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v +dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0 +MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww +KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G +A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13 +5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE +SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O +JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu +ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE +AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB +AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB +CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw +b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo +7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/ +0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7 +nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx +x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ +33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEFTCCA36gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBvjELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UE +ChMfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9z +dG1hc3RlcjEgMB4GA1UEAxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJTAjBgkq +hkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDMwMTE1MTYyOTE3 +WhcNMDcwMTE0MTYyOTE3WjCBvjELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0luZGlh +bmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdhcmUgaW4g +dGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEgMB4GA1UE +AxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJTAjBgkqhkiG9w0BCQEWFmhvc3Rt +YXN0ZXJAc3BpLWluYy5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPB6 +rdoiLR3RodtM22LMcfwfqb5OrJNl7fwmvskgF7yP6sdD2bOfDIXhg9852jhY8/kL +VOFe1ELAL2OyN4RAxk0rliZQVgeTgqvgkOVIBbNwgnjN6mqtuWzFiPL+NXQExq40 +I3whM+4lEiwSHaV+MYxWanMdhc+kImT50LKfkxcdAgMBAAGjggEfMIIBGzAdBgNV +HQ4EFgQUB63oQR1/vda/G4F6P4xLiN4E0vowgesGA1UdIwSB4zCB4IAUB63oQR1/ +vda/G4F6P4xLiN4E0vqhgcSkgcEwgb4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdJ +bmRpYW5hMRUwEwYDVQQHEwxJbmRpYW5hcG9saXMxKDAmBgNVBAoTH1NvZnR3YXJl +IGluIHRoZSBQdWJsaWMgSW50ZXJlc3QxEzARBgNVBAsTCmhvc3RtYXN0ZXIxIDAe +BgNVBAMTF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZo +b3N0bWFzdGVyQHNwaS1pbmMub3JnggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN +AQEEBQADgYEAm/Abn8c2y1nO3fgpAIslxvi9iNBZDhQtJ0VQZY6wgSfANyDOR4DW +iexO/AlorB49KnkFS7TjCAoLOZhcg5FaNiKnlstMI5krQmau1Qnb/vGSNsE/UGms +1ts+QYPUs0KmGEAFUri2XzLy+aQo9Kw74VBvqnxvaaMeY5yMcKNOieY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIIDjCCBfagAwIBAgIJAOiOtsn4KhQoMA0GCSqGSIb3DQEBBQUAMIG8MQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHSW5kaWFuYTEVMBMGA1UEBxMMSW5kaWFuYXBvbGlz +MSgwJgYDVQQKEx9Tb2Z0d2FyZSBpbiB0aGUgUHVibGljIEludGVyZXN0MRMwEQYD +VQQLEwpob3N0bWFzdGVyMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkx +JTAjBgkqhkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDgwNTEz +MDgwNzU2WhcNMTgwNTExMDgwNzU2WjCBvDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdh +cmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEe +MBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZo +b3N0bWFzdGVyQHNwaS1pbmMub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA3DbmR0LCxFF1KYdAw9iOIQbSGE7r7yC9kDyFEBOMKVuUY/b0LfEGQpG5 +GcRCaQi/izZF6igFM0lIoCdDkzWKQdh4s/Dvs24t3dHLfer0dSbTPpA67tfnLAS1 +fOH1fMVO73e9XKKTM5LOfYFIz2u1IiwIg/3T1c87Lf21SZBb9q1NE8re06adU1Fx +Y0b4ShZcmO4tbZoWoXaQ4mBDmdaJ1mwuepiyCwMs43pPx93jzONKao15Uvr0wa8u +jyoIyxspgpJyQ7zOiKmqp4pRQ1WFmjcDeJPI8L20QcgHQprLNZd6ioFl3h1UCAHx +ZFy3FxpRvB7DWYd2GBaY7r/2Z4GLBjXFS21ZGcfSxki+bhQog0oQnBv1b7ypjvVp +/rLBVcznFMn5WxRTUQfqzj3kTygfPGEJ1zPSbqdu1McTCW9rXRTunYkbpWry9vjQ +co7qch8vNGopCsUK7BxAhRL3pqXTT63AhYxMfHMgzFMY8bJYTAH1v+pk1Vw5xc5s +zFNaVrpBDyXfa1C2x4qgvQLCxTtVpbJkIoRRKFauMe5e+wsWTUYFkYBE7axt8Feo ++uthSKDLG7Mfjs3FIXcDhB78rKNDCGOM7fkn77SwXWfWT+3Qiz5dW8mRvZYChD3F +TbxCP3T9PF2sXEg2XocxLxhsxGjuoYvJWdAY4wCAs1QnLpnwFVMCAwEAAaOCAg8w +ggILMB0GA1UdDgQWBBQ0cdE41xU2g0dr1zdkQjuOjVKdqzCB8QYDVR0jBIHpMIHm +gBQ0cdE41xU2g0dr1zdkQjuOjVKdq6GBwqSBvzCBvDELMAkGA1UEBhMCVVMxEDAO +BgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMf +U29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1h +c3RlcjEeMBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcN +AQkBFhZob3N0bWFzdGVyQHNwaS1pbmMub3JnggkA6I62yfgqFCgwDwYDVR0TAQH/ +BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAAcwCQYDVR0SBAIwADAuBglghkgBhvhC +AQ0EIRYfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDAwBglghkgBhvhC +AQQEIxYhaHR0cHM6Ly9jYS5zcGktaW5jLm9yZy9jYS1jcmwucGVtMDIGCWCGSAGG ++EIBAwQlFiNodHRwczovL2NhLnNwaS1pbmMub3JnL2NlcnQtY3JsLnBlbTAhBgNV +HREEGjAYgRZob3N0bWFzdGVyQHNwaS1pbmMub3JnMA4GA1UdDwEB/wQEAwIBBjAN +BgkqhkiG9w0BAQUFAAOCAgEAtM294LnqsgMrfjLp3nI/yUuCXp3ir1UJogxU6M8Y +PCggHam7AwIvUjki+RfPrWeQswN/2BXja367m1YBrzXU2rnHZxeb1NUON7MgQS4M +AcRb+WU+wmHo0vBqlXDDxm/VNaSsWXLhid+hoJ0kvSl56WEq2dMeyUakCHhBknIP +qxR17QnwovBc78MKYiC3wihmrkwvLo9FYyaW8O4x5otVm6o6+YI5HYg84gd1GuEP +sTC8cTLSOv76oYnzQyzWcsR5pxVIBcDYLXIC48s9Fmq6ybgREOJJhcyWR2AFJS7v +dVkz9UcZFu/abF8HyKZQth3LZjQl/GaD68W2MEH4RkRiqMEMVObqTFoo5q7Gt/5/ +O5aoLu7HaD7dAD0prypjq1/uSSotxdz70cbT0ZdWUoa2lOvUYFG3/B6bzAKb1B+P ++UqPti4oOxfMxaYF49LTtcYDyeFIQpvLP+QX4P4NAZUJurgNceQJcHdC2E3hQqlg +g9cXiUPS1N2nGLar1CQlh7XU4vwuImm9rWgs/3K1mKoGnOcqarihk3bOsPN/nOHg +T7jYhkalMwIsJWE3KpLIrIF0aGOHM3a9BX9e1dUCbb2v/ypaqknsmHlHU5H2DjRa +yaXG67Ljxay2oHA1u8hRadDytaIybrw/oDc5fHE2pgXfDBLkFqfF1stjo5VwP+YE +o2A= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDvjCCA3ygAwIBAgIFJQaThoEwCwYHKoZIzjgEAwUAMIGFMQswCQYDVQQGEwJG +UjEPMA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczEQMA4GA1UEChMHUE0v +U0dETjEOMAwGA1UECxMFRENTU0kxDjAMBgNVBAMTBUlHQy9BMSMwIQYJKoZIhvcN +AQkBFhRpZ2NhQHNnZG4ucG0uZ291di5mcjAeFw0wMjEyMTMxNDM5MTVaFw0yMDEw +MTcxNDM5MTRaMIGFMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGRnJhbmNlMQ4wDAYD +VQQHEwVQYXJpczEQMA4GA1UEChMHUE0vU0dETjEOMAwGA1UECxMFRENTU0kxDjAM +BgNVBAMTBUlHQy9BMSMwIQYJKoZIhvcNAQkBFhRpZ2NhQHNnZG4ucG0uZ291di5m +cjCCAbYwggErBgcqhkjOOAQBMIIBHgKBgQCFkMImdk9zDzJfTO4XPdAAmLbAdWws +ZiEMZh19RyTo3CyhFqO77OIXrwY6vc1pcc3MgWJ0dgQpAgrDMtmFFxpUu4gmjVsx +8GpxQC+4VOgLY8Cvmcd/UDzYg07EIRto8BwCpPJ/JfUxwzV2V3N713aAX+cEoKZ/ +s+kgxC6nZCA7oQIVALME/JYjkdW2uKIGngsEPbXAjdhDAoGADh/uqWJx94UBm31c +9d8ZTBfRGRnmSSRVFDgPWgA69JD4BR5da8tKz+1HjfMhDXljbMH86ixpD5Ka1Z0V +pRYUPbyAoB37tsmXMJY7kjyD19d5VdaZboUjVvhH6UJy5lpNNNGSvFl4fqkxyvw+ +pq1QV0N5RcvK120hlXdfHUX+YKYDgYQAAoGAQGr7IuKJcYIvJRMjxwl43KxXY2xC +aoCiM/bv117MfI94aNf1UusGhp7CbYAY9CXuL60P0oPMAajbaTE5Z34AuITeHq3Y +CNMHwxalip8BHqSSGmGiQsXeK7T+r1rPXsccZ1c5ikGDZ4xn5gUaCyy2rCmb+fOJ +6VAfCbAbAjmNKwejdzB1MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgFGMBUG +A1UdIAQOMAwwCgYIKoF6AXkBAQEwHQYDVR0OBBYEFPkeNRcUf8idzpKblYbLNxs0 +MQhSMB8GA1UdIwQYMBaAFPkeNRcUf8idzpKblYbLNxs0MQhSMAsGByqGSM44BAMF +AAMvADAsAhRVh+CJA5eVyEYU5AO9Tm7GxX0rmQIUBCqsU5u1WxoZ5lEXicDX5/Ob +sRQ= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT +AkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ +TS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG +9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw +MTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM +BgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO +MAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2 +LmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI +s9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2 +xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4 +u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b +F8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx +Vs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd +PDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV +HSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx +NjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF +AAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ +L92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY +YLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg +Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a +NjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R +0982gaEbeC9xs/FZTEYYKKuF0mBWWg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 +IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB +IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA +Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO +BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi +MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ +ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ +8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6 +zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y +fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7 +w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc +G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k +epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q +laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ +QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU +fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826 +YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w +ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY +gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe +MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0 +IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy +dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw +czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0 +dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl +aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC +AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg +b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB +ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc +nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg +18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c +gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl +Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY +sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T +SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF +CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum +GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk +zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW +omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGCDCCA/CgAwIBAgIBATANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 +IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB +IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA +Y2FjZXJ0Lm9yZzAeFw0wNTEwMTQwNzM2NTVaFw0zMzAzMjgwNzM2NTVaMFQxFDAS +BgNVBAoTC0NBY2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2VydC5v +cmcxHDAaBgNVBAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCrSTURSHzSJn5TlM9Dqd0o10Iqi/OHeBlYfA+e2ol9 +4fvrcpANdKGWZKufoCSZc9riVXbHF3v1BKxGuMO+f2SNEGwk82GcwPKQ+lHm9WkB +Y8MPVuJKQs/iRIwlKKjFeQl9RrmK8+nzNCkIReQcn8uUBByBqBSzmGXEQ+xOgo0J +0b2qW42S0OzekMV/CsLj6+YxWl50PpczWejDAz1gM7/30W9HxM3uYoNSbi4ImqTZ +FRiRpoWSR7CuSOtttyHshRpocjWr//AQXcD0lKdq1TuSfkyQBX6TwSyLpI5idBVx +bgtxA+qvFTia1NIFcm+M+SvrWnIl+TlG43IbPgTDZCciECqKT1inA62+tC4T7V2q +SNfVfdQqe1z6RgRQ5MwOQluM7dvyz/yWk+DbETZUYjQ4jwxgmzuXVjit89Jbi6Bb +6k6WuHzX1aCGcEDTkSm3ojyt9Yy7zxqSiuQ0e8DYbF/pCsLDpyCaWt8sXVJcukfV +m+8kKHA4IC/VfynAskEDaJLM4JzMl0tF7zoQCqtwOpiVcK01seqFK6QcgCExqa5g +eoAmSAC4AcCTY1UikTxW56/bOiXzjzFU6iaLgVn5odFTEcV7nQP2dBHgbbEsPyyG +kZlxmqZ3izRg0RS0LKydr4wQ05/EavhvE/xzWfdmQnQeiuP43NJvmJzLR5iVQAX7 +6QIDAQABo4G/MIG8MA8GA1UdEwEB/wQFMAMBAf8wXQYIKwYBBQUHAQEEUTBPMCMG +CCsGAQUFBzABhhdodHRwOi8vb2NzcC5DQWNlcnQub3JnLzAoBggrBgEFBQcwAoYc +aHR0cDovL3d3dy5DQWNlcnQub3JnL2NhLmNydDBKBgNVHSAEQzBBMD8GCCsGAQQB +gZBKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZy9pbmRleC5w +aHA/aWQ9MTAwDQYJKoZIhvcNAQEEBQADggIBAH8IiKHaGlBJ2on7oQhy84r3HsQ6 +tHlbIDCxRd7CXdNlafHCXVRUPIVfuXtCkcKZ/RtRm6tGpaEQU55tiKxzbiwzpvD0 +nuB1wT6IRanhZkP+VlrRekF490DaSjrxC1uluxYG5sLnk7mFTZdPsR44Q4Dvmw2M +77inYACHV30eRBzLI++bPJmdr7UpHEV5FpZNJ23xHGzDwlVks7wU4vOkHx4y/CcV +Bc/dLq4+gmF78CEQGPZE6lM5+dzQmiDgxrvgu1pPxJnIB721vaLbLmINQjRBvP+L +ivVRIqqIMADisNS8vmW61QNXeZvo3MhN+FDtkaVSKKKs+zZYPumUK5FQhxvWXtaM +zPcPEAxSTtAWYeXlCmy/F8dyRlecmPVsYGN6b165Ti/Iubm7aoW8mA3t+T6XhDSU +rgCvoeXnkm5OvfPi2RSLXNLrAWygF6UtEOucekq9ve7O/e0iQKtwOIj1CodqwqsF +YMlIBdpTwd5Ed2qz8zw87YC8pjhKKSRf/lk7myV6VmMAZLldpGJ9VzZPrYPvH5JT +oI53V93lYRE9IwCQTDz6o2CTBKOvNfYOao9PSmCnhQVsRqGP9Md246FZV/dxssRu +FFxtbUFm3xuTsdQAw+7Lzzw9IYCpX2Nl/N3gX6T0K/CFcUHUZyX7GrGXrtaZghNB +0m6lG5kngOcLqagA +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQDHbanJEMTiye/hXQWJM8TDANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp +Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww +HhcNMDcwNTE2MTcxOTM2WhcNMjUwMzMxMTgxOTIxWjBfMQswCQYDVQQGEwJOTDES +MBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdpTm90YXIgUm9vdCBDQTEg +MB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmwwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCssFjBAL3YIQgLK5r+blYwBZ8bd5AQQVzDDYcRd46B +8cp86Yxq7Th0Nbva3/m7wAk3tJZzgX0zGpg595NvlX89ubF1h7pRSOiLcD6VBMXY +tsMW2YiwsYcdcNqGtA8Ui3rPENF0NqISe3eGSnnme98CEWilToauNFibJBN4ViIl +HgGLS1Fx+4LMWZZpiFpoU8W5DQI3y0u8ZkqQfioLBQftFl9VkHXYRskbg+IIvvEj +zJkd1ioPgyAVWCeCLvriIsJJsbkBgWqdbZ1Ad2h2TiEqbYRAhU52mXyC8/O3AlnU +JgEbjt+tUwbRrhjd4rI6y9eIOI6sWym5GdOY+RgDz0iChmYLG2kPyes4iHomGgVM +ktck1JbyrFIto0fVUvY//s6EBnCmqj6i8rZWNBhXouSBbefK8GrTx5FrAoNBfBXv +a5pkXuPQPOWx63tdhvvL5ndJzaNl3Pe5nLjkC1+Tz8wwGjIczhxjlaX56uF0i57p +K6kwe6AYHw4YC+VbqdPRbB4HZ4+RS6mKvNJmqpMBiLKR+jFc1abBUggJzQpjotMi +puih2TkGl/VujQKQjBR7P4DNG5y6xFhyI6+2Vp/GekIzKQc/gsnmHwUNzUwoNovT +yD4cxojvXu6JZOkd69qJfjKmadHdzIif0dDJZiHcBmfFlHqabWJMfczgZICynkeO +owIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wDQYJKoZIhvcNAQEFBQADggIBADsC +jcs8MOhuoK3yc7NfniUTBAXT9uOLuwt5zlPe5JbF0a9zvNXD0EBVfEB/zRtfCdXy +fJ9oHbtdzno5wozWmHvFg1Wo1X1AyuAe94leY12hE8JdiraKfADzI8PthV9xdvBo +Y6pFITlIYXg23PFDk9Qlx/KAZeFTAnVR/Ho67zerhChXDNjU1JlWbOOi/lmEtDHo +M/hklJRRl6s5xUvt2t2AC298KQ3EjopyDedTFLJgQT2EkTFoPSdE2+Xe9PpjRchM +Ppj1P0G6Tss3DbpmmPHdy59c91Q2gmssvBNhl0L4eLvMyKKfyvBovWsdst+Nbwed +2o5nx0ceyrm/KkKRt2NTZvFCo+H0Wk1Ya7XkpDOtXHAd3ODy63MUkZoDweoAZbwH +/M8SESIsrqC9OuCiKthZ6SnTGDWkrBFfGbW1G/8iSlzGeuQX7yCpp/Q/rYqnmgQl +nQ7KN+ZQ/YxCKQSa7LnPS3K94gg2ryMvYuXKAdNw23yCIywWMQzGNgeQerEfZ1jE +O1hZibCMjFCz2IbLaKPECudpSyDOwR5WS5WpI2jYMNjD67BVUc3l/Su49bsRn1NU +9jQZjHkJNsphFyUXC4KYcwx3dMPVDceoEkzHp1RxRy4sGn3J4ys7SN4nhKdjNrN9 +j6BkOSQNPXuHr2ZcdBtLc7LljPCGmbjlxd+Ewbfr +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx +IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs +cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v +dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0 +MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl +bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD +DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r +WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU +Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs +HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj +z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf +SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl +AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG +KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P +AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j +BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC +VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX +ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB +ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd +/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB +A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn +k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9 +iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv +2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/camster_duckdns_org.crt b/circuitpython/lib/axtls/ssl/test/camster_duckdns_org.crt new file mode 100644 index 0000000..453bafa --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/camster_duckdns_org.crt @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFXTCCBEWgAwIBAgIQRKGXkBbin0Hge3vNu4Z04TANBgkqhkiG9w0BAQsFADCB +kDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNjA0BgNV +BAMTLUNPTU9ETyBSU0EgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBD +QTAeFw0xNDExMTIwMDAwMDBaFw0xNzExMTEyMzU5NTlaMFcxITAfBgNVBAsTGERv +bWFpbiBDb250cm9sIFZhbGlkYXRlZDEUMBIGA1UECxMLUG9zaXRpdmVTU0wxHDAa +BgNVBAMTE2NhbXN0ZXIuZHVja2Rucy5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCvKi9/3GOq1pqgnIQR2hTxr1kv17pUzpQeAVOZVCd/q6KbMrsw +ayPj41hJd+EVtu6DV8Zd/Rxv4P6i2HTRWev9aE2+vFfTmhIZG0HUZqs3Fbq6yONn +ox8d7Dsu/vwIkyaIE9mMAYYr81bX86v8cmvCHatCO/lluwUqjnXUjYpMOpTopHjC +hNzUe63ZtUDVmXfTBHneO5GLZqhQSSX7rd33cJzkojGCoPSFP5TUhN5WGyRi+xa2 +bD+Q5xXlC4f/WVXiZxGiGPrWIpQBO5Y5o33S6Vo2ck9Bvg2g1atsR02m+yARtmH3 ++IDlvg7DeyLL3AXgUwDNHnRb0t9LVDXcYOJnAgMBAAGjggHpMIIB5TAfBgNVHSME +GDAWgBSQr2o6lFoL2JDqElZz30O0Oija5zAdBgNVHQ4EFgQUGNRX8FYKZUYa1F4+ +L7nyHOn3ArcwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYw +FAYIKwYBBQUHAwEGCCsGAQUFBwMCME8GA1UdIARIMEYwOgYLKwYBBAGyMQECAgcw +KzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwCAYG +Z4EMAQIBMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9jcmwuY29tb2RvY2EuY29t +L0NPTU9ET1JTQURvbWFpblZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYUG +CCsGAQUFBwEBBHkwdzBPBggrBgEFBQcwAoZDaHR0cDovL2NydC5jb21vZG9jYS5j +b20vQ09NT0RPUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAk +BggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMDcGA1UdEQQwMC6C +E2NhbXN0ZXIuZHVja2Rucy5vcmeCF3d3dy5jYW1zdGVyLmR1Y2tkbnMub3JnMA0G +CSqGSIb3DQEBCwUAA4IBAQBpfJIXHPyoxbXlS1Jy5V4oDpDR+vKRIXXUPDp6GlmK +6w8W7M536W7JamLrT8wbA04hKgtjQkXD8pXZPFHBNJ92Lza5fKB/KiIlObz386lK +Z9AVc10TwWlkZlFYhYVhQ+kpTtcUUdj5QI2org81s9XQoSViVOM8cxIuYk/er20g +jY3Nvdbjg4dtakH1nsITGMYLN+wJglSAq1QGSQ76fLyYhMfF25nNjPYP96SFf1Dd +XinknP2tED6ukzIgfkimlyn2/XIbnz4Xry8ouq4x/cPd8MOcffWt1QWlGIel5B8i +I1vtVHceHSsHjnnNPSkXIn0/lpc5vzVZ+bw9yLt+Lvc6 +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/comodo.sha384.cer b/circuitpython/lib/axtls/ssl/test/comodo.sha384.cer new file mode 100644 index 0000000..b52ea61 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/comodo.sha384.cer @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk +ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF +eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow +gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD +VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw +AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6 +2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr +ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt +4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq +m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/ +vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT +8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE +IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO +KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO +GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/ +s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g +JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD +AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9 +MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy +bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6 +Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ +zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj +Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY +Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5 +B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx +PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR +pu/xO28QOG8= +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/deutsche_telecom.x509_ca b/circuitpython/lib/axtls/ssl/test/deutsche_telecom.x509_ca new file mode 100644 index 0000000..0f4b96a Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/deutsche_telecom.x509_ca differ diff --git a/circuitpython/lib/axtls/ssl/test/equifax.x509_ca b/circuitpython/lib/axtls/ssl/test/equifax.x509_ca new file mode 100644 index 0000000..79b0a3f Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/equifax.x509_ca differ diff --git a/circuitpython/lib/axtls/ssl/test/gnutls.cer b/circuitpython/lib/axtls/ssl/test/gnutls.cer new file mode 100755 index 0000000..312e365 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/gnutls.cer differ diff --git a/circuitpython/lib/axtls/ssl/test/header_issue.dat b/circuitpython/lib/axtls/ssl/test/header_issue.dat new file mode 100755 index 0000000..a48d23d Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/header_issue.dat differ diff --git a/circuitpython/lib/axtls/ssl/test/killgnutls.sh b/circuitpython/lib/axtls/ssl/test/killgnutls.sh new file mode 100755 index 0000000..f910f4b --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/killgnutls.sh @@ -0,0 +1,2 @@ +#!/bin/sh +ps -ef|grep gnutls-serv | /usr/bin/awk '{print $2}' |xargs kill -9 diff --git a/circuitpython/lib/axtls/ssl/test/killopenssl.sh b/circuitpython/lib/axtls/ssl/test/killopenssl.sh new file mode 100755 index 0000000..17950fb --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/killopenssl.sh @@ -0,0 +1,2 @@ +#!/bin/sh +ps -ef|grep openssl | /usr/bin/awk '{print $2}' |xargs kill -9 diff --git a/circuitpython/lib/axtls/ssl/test/make_certs.sh b/circuitpython/lib/axtls/ssl/test/make_certs.sh new file mode 100755 index 0000000..f234b3f --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/make_certs.sh @@ -0,0 +1,253 @@ +#!/bin/sh + +# +# Copyright (c) 2007-2016, Cameron Rich +# +# 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 axTLS project 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. +# + +# +# Generate the certificates and keys for testing. +# + +PROJECT_NAME="axTLS Project" + +# Generate the openssl configuration files. +cat > ca_cert.conf << EOF +[ req ] +distinguished_name = req_distinguished_name +prompt = no +req_extensions = v3_ca + +[ req_distinguished_name ] + O = $PROJECT_NAME Dodgy Certificate Authority + +[ v3_ca ] +basicConstraints = critical, CA:true +keyUsage = critical, cRLSign, keyCertSign, digitalSignature +EOF + +cat > certs.conf << EOF +[ req ] +distinguished_name = req_distinguished_name +prompt = no +req_extensions = v3_usr_cert + +[ req_distinguished_name ] + O = $PROJECT_NAME + CN = localhost + +[ v3_usr_cert ] +basicConstraints = critical, CA:false +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = www.example.net +DNS.2 = www.example.org +EOF + +cat > device_cert.conf << EOF +[ req ] +distinguished_name = req_distinguished_name +prompt = no + +[ req_distinguished_name ] + O = $PROJECT_NAME Device Certificate +EOF + +cat > intermediate_ca.conf << EOF +[ req ] +distinguished_name = req_distinguished_name +prompt = no +req_extensions = v3_intermediate_ca + +[ req_distinguished_name ] + O = $PROJECT_NAME Intermediate CA + +[ v3_intermediate_ca ] +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = cRLSign, keyCertSign, digitalSignature +EOF + +cat > intermediate_ca2.conf << EOF +[ req ] +distinguished_name = req_distinguished_name +prompt = no +req_extensions = v3_intermediate_ca2 + +[ req_distinguished_name ] + O = $PROJECT_NAME Intermediate 2 CA + +[ v3_intermediate_ca2 ] +basicConstraints = critical, CA:true, pathlen:10 +keyUsage = encipherOnly, keyCertSign, decipherOnly +EOF + +# private key generation +openssl genrsa -out axTLS.ca_key.pem 2048 +openssl genrsa -out axTLS.key_1024.pem 1024 +openssl genrsa -out axTLS.key_2048.pem 2048 +openssl genrsa -out axTLS.key_4096.pem 4096 +openssl genrsa -out axTLS.key_device.pem 2048 +openssl genrsa -out axTLS.key_intermediate_ca.pem 2048 +openssl genrsa -out axTLS.key_intermediate_ca2.pem 2048 +openssl genrsa -out axTLS.key_end_chain.pem 2048 +openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 1024 +openssl genrsa -aes256 -passout pass:abcd -out axTLS.key_aes256.pem 1024 + +# convert private keys into DER format +openssl rsa -in axTLS.key_1024.pem -out axTLS.key_1024 -outform DER +openssl rsa -in axTLS.key_2048.pem -out axTLS.key_2048 -outform DER +openssl rsa -in axTLS.key_4096.pem -out axTLS.key_4096 -outform DER + +# cert requests +openssl req -out axTLS.ca_x509.csr -key axTLS.ca_key.pem -new \ + -config ./ca_cert.conf +openssl req -out axTLS.x509_1024.csr -key axTLS.key_1024.pem -new \ + -config ./certs.conf +openssl req -out axTLS.x509_2048.csr -key axTLS.key_2048.pem -new \ + -config ./certs.conf +openssl req -out axTLS.x509_4096.csr -key axTLS.key_4096.pem -new \ + -config ./certs.conf +openssl req -out axTLS.x509_device.csr -key axTLS.key_device.pem -new \ + -config ./device_cert.conf +openssl req -out axTLS.x509_intermediate_ca.csr \ + -key axTLS.key_intermediate_ca.pem -new \ + -config ./intermediate_ca.conf +openssl req -out axTLS.x509_intermediate_ca2.csr \ + -key axTLS.key_intermediate_ca2.pem -new \ + -config ./intermediate_ca2.conf +openssl req -out axTLS.x509_end_chain.csr -key axTLS.key_end_chain.pem -new \ + -config ./certs.conf +openssl req -out axTLS.x509_aes128.csr -key axTLS.key_aes128.pem \ + -new -config ./certs.conf -passin pass:abcd +openssl req -out axTLS.x509_aes256.csr -key axTLS.key_aes256.pem \ + -new -config ./certs.conf -passin pass:abcd + +# generate the actual certs. +openssl x509 -req -in axTLS.ca_x509.csr -out axTLS.ca_x509.pem \ + -sha1 -days 5000 -signkey axTLS.ca_key.pem \ + -CAkey axTLS.ca_key.pem -extfile ./ca_cert.conf -extensions v3_ca +openssl x509 -req -in axTLS.ca_x509.csr -out axTLS.ca_x509_sha256.pem \ + -sha256 -days 5000 -signkey axTLS.ca_key.pem \ + -CAkey axTLS.ca_key.pem -extfile ./ca_cert.conf -extensions v3_ca +openssl x509 -req -in axTLS.x509_1024.csr -out axTLS.x509_1024.pem \ + -sha1 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_1024.csr -out axTLS.x509_1024_sha256.pem \ + -sha256 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509_sha256.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_1024.csr -out axTLS.x509_1024_sha384.pem \ + -sha384 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509_sha256.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_1024.csr -out axTLS.x509_1024_sha512.pem \ + -sha512 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509_sha256.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_2048.csr -out axTLS.x509_2048.pem \ + -sha1 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_4096.csr -out axTLS.x509_4096.pem \ + -sha1 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_device.csr -out axTLS.x509_device.pem \ + -sha1 -CAcreateserial -days 5000 \ + -CA axTLS.x509_1024.pem -CAkey axTLS.key_1024.pem +openssl x509 -req -in axTLS.x509_intermediate_ca.csr -out axTLS.x509_intermediate_ca.pem \ + -sha256 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem \ + -extfile ./intermediate_ca.conf -extensions v3_intermediate_ca +openssl x509 -req -in axTLS.x509_intermediate_ca2.csr -out axTLS.x509_intermediate_ca2.pem \ + -sha256 -CAcreateserial -days 5000 \ + -CA axTLS.x509_intermediate_ca.pem \ + -CAkey axTLS.key_intermediate_ca.pem \ + -extfile ./intermediate_ca2.conf -extensions v3_intermediate_ca2 +openssl x509 -req -in axTLS.x509_end_chain.csr -out axTLS.x509_end_chain.pem \ + -sha256 -CAcreateserial -days 5000 \ + -CA axTLS.x509_intermediate_ca.pem \ + -CAkey axTLS.key_intermediate_ca.pem \ + -extfile ./certs.conf -extensions v3_usr_cert +# basic constraint path len failure +openssl x509 -req -in axTLS.x509_end_chain.csr \ + -out axTLS.x509_end_chain_bad.pem \ + -sha256 -CAcreateserial -days 5000 \ + -CA axTLS.x509_intermediate_ca2.pem \ + -CAkey axTLS.key_intermediate_ca2.pem \ + -extfile ./certs.conf -extensions v3_usr_cert +cat axTLS.x509_intermediate_ca.pem >> axTLS.x509_intermediate_ca2.pem +openssl x509 -req -in axTLS.x509_aes128.csr \ + -out axTLS.x509_aes128.pem \ + -sha1 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_aes256.csr \ + -out axTLS.x509_aes256.pem \ + -sha1 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem + +# note: must be root to do this +DATE_NOW=`date` +if date -s "Jan 1 2025"; then +openssl x509 -req -in axTLS.x509_1024.csr -out axTLS.x509_bad_before.pem \ + -sha1 -CAcreateserial -days 365 \ + -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem +date -s "$DATE_NOW" +touch axTLS.x509_bad_before.pem +fi +openssl x509 -req -in axTLS.x509_1024.csr -out axTLS.x509_bad_after.pem \ + -sha1 -CAcreateserial -days -365 \ + -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem + +# some cleanup +rm axTLS*.csr +rm *.srl +rm *.conf + +# need this for the client tests +openssl x509 -in axTLS.ca_x509.pem -outform DER -out axTLS.ca_x509.cer +openssl x509 -in axTLS.x509_1024.pem -outform DER -out axTLS.x509_1024.cer +openssl x509 -in axTLS.x509_2048.pem -outform DER -out axTLS.x509_2048.cer +openssl x509 -in axTLS.x509_4096.pem -outform DER -out axTLS.x509_4096.cer + +# generate pkcs8 files (use RC4-128 for encryption) +openssl pkcs8 -in axTLS.key_1024.pem -passout pass:abcd -topk8 -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8 +openssl pkcs8 -in axTLS.key_1024.pem -passout pass:abcd -topk8 -outform DER -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8 +openssl pkcs8 -in axTLS.key_1024.pem -nocrypt -topk8 -out axTLS.unencrypted_pem.p8 +openssl pkcs8 -in axTLS.key_1024.pem -nocrypt -topk8 -outform DER -out axTLS.unencrypted.p8 + +# generate pkcs12 files (use RC4-128 for encryption) +openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 -name "p12_with_CA" -out axTLS.withCA.p12 -password pass:abcd +openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 -name "p12_without_CA" -out axTLS.withoutCA.p12 -password pass:abcd +openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 -out axTLS.noname.p12 -password pass:abcd + +# PEM certificate chain +cat axTLS.ca_x509.pem >> axTLS.x509_device.pem + +# set default key/cert for use in the server +xxd -i axTLS.x509_1024.cer | sed -e \ + "s/axTLS_x509_1024_cer/default_certificate/" > ../../ssl/cert.h +xxd -i axTLS.key_1024 | sed -e \ + "s/axTLS_key_1024/default_private_key/" > ../../ssl/private_key.h diff --git a/circuitpython/lib/axtls/ssl/test/microsoft.x509_ca b/circuitpython/lib/axtls/ssl/test/microsoft.x509_ca new file mode 100644 index 0000000..b908034 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/microsoft.x509_ca differ diff --git a/circuitpython/lib/axtls/ssl/test/microsoft.x509_ca.pem b/circuitpython/lib/axtls/ssl/test/microsoft.x509_ca.pem new file mode 100644 index 0000000..478e60b --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/microsoft.x509_ca.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEEjCCAvqgAwIBAgIPAMEAizw8iBHRPvZj7N9AMA0GCSqGSIb3DQEBBAUAMHAx +KzApBgNVBAsTIkNvcHlyaWdodCAoYykgMTk5NyBNaWNyb3NvZnQgQ29ycC4xHjAc +BgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0 +IFJvb3QgQXV0aG9yaXR5MB4XDTk3MDExMDA3MDAwMFoXDTIwMTIzMTA3MDAwMFow +cDErMCkGA1UECxMiQ29weXJpZ2h0IChjKSAxOTk3IE1pY3Jvc29mdCBDb3JwLjEe +MBwGA1UECxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEwHwYDVQQDExhNaWNyb3Nv +ZnQgUm9vdCBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCpAr3BcOY78k4bKJ+XeF4w6qKpjSVf+P6VTKO3/p2iID58UaKboo9gMmvRQmR5 +7qx2yVTa8uuchhyPn4Rms8VremIj1h083g8BkuiWxL8tZpqaaCaZ0Dosvwy1WCbB +RucKPjiWLKkoOajsSYNC44QPu5psVWGsgnyhYC13TOmZtGQ7mlAcMQgkFJ+p55Er +GOY9mGMUYFgFZZ8dN1KH96fvlALGG9O/VUWziYC/OuxUlE6u/ad6bXROrxjMlgko +IQBXkGBpN7tLEgc8Vv9b+6RmCgim0oFWV++2O14WgXcE2va+roCV/rDNf9anGnJc +PMq88AijIjCzBoXJsyB3E4XfAgMBAAGjgagwgaUwgaIGA1UdAQSBmjCBl4AQW9Bw +72lyniNRfhSyTY7/y6FyMHAxKzApBgNVBAsTIkNvcHlyaWdodCAoYykgMTk5NyBN +aWNyb3NvZnQgQ29ycC4xHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEh +MB8GA1UEAxMYTWljcm9zb2Z0IFJvb3QgQXV0aG9yaXR5gg8AwQCLPDyIEdE+9mPs +30AwDQYJKoZIhvcNAQEEBQADggEBAJXoC8CN85cYNe24ASTYdxHzXGAyn54Lyz4F +kYiPyTrmIfLwV5MstaBHyGLv/NfMOztaqTZUaf4kbT/JzKreBXzdMY09nxBwarv+ +Ek8YacD80EPjEVogT+pie6+qGcgrNyUtvmWhEoolD2Oj91Qc+SHJ1hXzUqxuQzIH +/YIX+OVnbA1R9r3xUse958Qw/CAxCYgdlSkaTdUdAqXxgOADtFv0sd3IV+5lScdS +VLa0AygS/5DW8AiPfriXxas3LOR65Kh343agANBqP8HSNorgQRKoNWobats14dQc +BOSoRQTIWjM4bk0cDWK3CqKM09VUP0bNHFWmcNsSOoeTdZ+n0qA= +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/ms_iis.cer b/circuitpython/lib/axtls/ssl/test/ms_iis.cer new file mode 100755 index 0000000..250b926 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/ms_iis.cer @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5jCCAVOgAwIBAgIQWPe7KyA+U7lLUohulwW2HDAJBgUrDgMCHQUAMCExHzAd +BgNVBAMTFmF4dGxzLmNlcm9jY2x1Yi5jb20uYXUwHhcNMDgwMzE3MTAyMTA2WhcN +MDkwMzE3MTAyMTA2WjAhMR8wHQYDVQQDExZheHRscy5jZXJvY2NsdWIuY29tLmF1 +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9JqHlQjrQMt3JW8yxcGhFagDa +D4QiIY8+KItTt13fIBt5g1AG4VXniaylSqKKYNPwVzqSWl7WhxMmoFU73veF8o4M +G0Zc5qbVB6ukrSV4WaTgHrIO6pWkyiaQ4L/eYfCo/2pByhl0IUKkf/TMN346/rFg +JgrElx01l6QHNQrzVQIDAQABoycwJTATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNV +HQ8EBwMFALAAAAAwCQYFKw4DAh0FAAOBgQAbH94H1fryngROJ//Oa0D3vvTO8CJ3 +8VW+3gQEwrPBOWmN6RV8OM0dE6pf8wD3s7PTCcM5+/HI1Qk53nUGrNiOmKM1s0JB +bvsO9RT+UF8mtdbo/n30M0MHMWPCC76baW3R+ANBp/V/z4l1ytpUTt+MHvz0VlUs +J4uJA3s3uh23Tg== +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/perf_bigint.c b/circuitpython/lib/axtls/ssl/test/perf_bigint.c new file mode 100644 index 0000000..6336d1b --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/perf_bigint.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2007, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Some performance testing of bigint. + */ + +#include +#include +#include + +#include "os_port.h" +#include "ssl.h" + +/************************************************************************** + * BIGINT tests + * + **************************************************************************/ + +int main(int argc, char *argv[]) +{ +#ifdef CONFIG_SSL_CERT_VERIFICATION + RSA_CTX *rsa_ctx = NULL; + BI_CTX *ctx; + bigint *bi_data, *bi_res; + float diff; + int res = 1; + struct timeval tv_old, tv_new; + const char *plaintext; + uint8_t compare[MAX_KEY_BYTE_SIZE]; + int i, max_biggie = 10; /* really crank performance */ + int len; + uint8_t *buf; + + /** + * 512 bit key + */ + plaintext = /* 64 byte number */ + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"; + + len = get_file("../ssl/test/axTLS.key_512", &buf); + asn1_get_private_key(buf, len, &rsa_ctx); + ctx = rsa_ctx->bi_ctx; + bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext)); + bi_res = RSA_public(rsa_ctx, bi_data); + bi_data = bi_res; /* reuse again */ + + gettimeofday(&tv_old, NULL); + for (i = 0; i < max_biggie; i++) + { + bi_res = RSA_private(rsa_ctx, bi_copy(bi_data)); + if (i < max_biggie-1) + { + bi_free(ctx, bi_res); + } + } + + gettimeofday(&tv_new, NULL); + bi_free(ctx, bi_data); + + diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 + + (tv_new.tv_usec-tv_old.tv_usec)/1000; + printf("512 bit decrypt time: %.2fms\n", diff/max_biggie); + TTY_FLUSH(); + bi_export(ctx, bi_res, compare, 64); + RSA_free(rsa_ctx); + free(buf); + if (memcmp(plaintext, compare, 64) != 0) + goto end; + + /** + * 1024 bit key + */ + plaintext = /* 128 byte number */ + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"; + + len = get_file("../ssl/test/axTLS.key_1024", &buf); + rsa_ctx = NULL; + asn1_get_private_key(buf, len, &rsa_ctx); + ctx = rsa_ctx->bi_ctx; + bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext)); + bi_res = RSA_public(rsa_ctx, bi_data); + bi_data = bi_res; /* reuse again */ + + gettimeofday(&tv_old, NULL); + for (i = 0; i < max_biggie; i++) + { + bi_res = RSA_private(rsa_ctx, bi_copy(bi_data)); + if (i < max_biggie-1) + { + bi_free(ctx, bi_res); + } + } + + gettimeofday(&tv_new, NULL); + bi_free(ctx, bi_data); + + diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 + + (tv_new.tv_usec-tv_old.tv_usec)/1000; + printf("1024 bit decrypt time: %.2fms\n", diff/max_biggie); + TTY_FLUSH(); + bi_export(ctx, bi_res, compare, 128); + RSA_free(rsa_ctx); + free(buf); + if (memcmp(plaintext, compare, 128) != 0) + goto end; + + /** + * 2048 bit key + */ + plaintext = /* 256 byte number */ + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"; + + len = get_file("../ssl/test/axTLS.key_2048", &buf); + rsa_ctx = NULL; + asn1_get_private_key(buf, len, &rsa_ctx); + ctx = rsa_ctx->bi_ctx; + bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext)); + bi_res = RSA_public(rsa_ctx, bi_data); + bi_data = bi_res; /* reuse again */ + + gettimeofday(&tv_old, NULL); + for (i = 0; i < max_biggie; i++) + { + bi_res = RSA_private(rsa_ctx, bi_copy(bi_data)); + if (i < max_biggie-1) + { + bi_free(ctx, bi_res); + } + } + gettimeofday(&tv_new, NULL); + bi_free(ctx, bi_data); + + diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 + + (tv_new.tv_usec-tv_old.tv_usec)/1000; + printf("2048 bit decrypt time: %.2fms\n", diff/max_biggie); + TTY_FLUSH(); + bi_export(ctx, bi_res, compare, 256); + RSA_free(rsa_ctx); + free(buf); + if (memcmp(plaintext, compare, 256) != 0) + goto end; + + /** + * 4096 bit key + */ + plaintext = /* 512 byte number */ + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^" + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"; + + len = get_file("../ssl/test/axTLS.key_4096", &buf); + rsa_ctx = NULL; + asn1_get_private_key(buf, len, &rsa_ctx); + ctx = rsa_ctx->bi_ctx; + bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext)); + gettimeofday(&tv_old, NULL); + bi_res = RSA_public(rsa_ctx, bi_data); + gettimeofday(&tv_new, NULL); + diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 + + (tv_new.tv_usec-tv_old.tv_usec)/1000; + printf("4096 bit encrypt time: %.2fms\n", diff); + TTY_FLUSH(); + bi_data = bi_res; /* reuse again */ + + gettimeofday(&tv_old, NULL); + for (i = 0; i < max_biggie; i++) + { + bi_res = RSA_private(rsa_ctx, bi_copy(bi_data)); + if (i < max_biggie-1) + { + bi_free(ctx, bi_res); + } + } + + gettimeofday(&tv_new, NULL); + bi_free(ctx, bi_data); + + diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 + + (tv_new.tv_usec-tv_old.tv_usec)/1000; + printf("4096 bit decrypt time: %.2fms\n", diff/max_biggie); + TTY_FLUSH(); + bi_export(ctx, bi_res, compare, 512); + RSA_free(rsa_ctx); + free(buf); + if (memcmp(plaintext, compare, 512) != 0) + goto end; + + /* done */ + printf("Bigint performance testing complete\n"); + res = 0; + +end: + return res; +#else + return 0; +#endif +} diff --git a/circuitpython/lib/axtls/ssl/test/qualityssl.com.der b/circuitpython/lib/axtls/ssl/test/qualityssl.com.der new file mode 100644 index 0000000..c73b246 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/qualityssl.com.der differ diff --git a/circuitpython/lib/axtls/ssl/test/socgen.cer b/circuitpython/lib/axtls/ssl/test/socgen.cer new file mode 100755 index 0000000..a427870 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/socgen.cer differ diff --git a/circuitpython/lib/axtls/ssl/test/ssltest.c b/circuitpython/lib/axtls/ssl/test/ssltest.c new file mode 100644 index 0000000..ceb241e --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/ssltest.c @@ -0,0 +1,2589 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/* + * The testing of the crypto and ssl stuff goes here. Keeps the individual code + * modules from being uncluttered with test code. + * + * This is test code - I make no apologies for the quality! + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#include "os_port.h" +#include "ssl.h" + +#define DEFAULT_CERT "../ssl/test/axTLS.x509_1024.cer" +#define DEFAULT_KEY "../ssl/test/axTLS.key_1024" +//#define DEFAULT_SVR_OPTION SSL_DISPLAY_BYTES|SSL_DISPLAY_STATES +#define DEFAULT_SVR_OPTION 0 +//#define DEFAULT_CLNT_OPTION SSL_DISPLAY_BYTES|SSL_DISPLAY_STATES +#define DEFAULT_CLNT_OPTION 0 + +/* hack to remove gcc warning */ +#define SYSTEM(A) if (system(A) < 0) printf("system call error\n"); + +static int g_port = 19001; + +/************************************************************************** + * AES tests + * + * Run through a couple of the RFC3602 tests to verify that AES is correct. + **************************************************************************/ +#define TEST1_SIZE 16 +#define TEST2_SIZE 32 + +static int AES_test(BI_CTX *bi_ctx) +{ + AES_CTX aes_key; + int res = 1; + uint8_t key[TEST1_SIZE]; + uint8_t iv[TEST1_SIZE]; + + { + /* + Case #1: Encrypting 16 bytes (1 block) using AES-CBC + Key : 0x06a9214036b8a15b512e03d534120006 + IV : 0x3dafba429d9eb430b422da802c9fac41 + Plaintext : "Single block msg" + Ciphertext: 0xe353779c1079aeb82708942dbe77181a + + */ + char *in_str = "Single block msg"; + uint8_t ct[TEST1_SIZE]; + uint8_t enc_data[TEST1_SIZE]; + uint8_t dec_data[TEST1_SIZE]; + + bigint *key_bi = bi_str_import( + bi_ctx, "06A9214036B8A15B512E03D534120006"); + bigint *iv_bi = bi_str_import( + bi_ctx, "3DAFBA429D9EB430B422DA802C9FAC41"); + bigint *ct_bi = bi_str_import( + bi_ctx, "E353779C1079AEB82708942DBE77181A"); + bi_export(bi_ctx, key_bi, key, TEST1_SIZE); + bi_export(bi_ctx, iv_bi, iv, TEST1_SIZE); + bi_export(bi_ctx, ct_bi, ct, TEST1_SIZE); + + AES_set_key(&aes_key, key, iv, AES_MODE_128); + AES_cbc_encrypt(&aes_key, (const uint8_t *)in_str, + enc_data, sizeof(enc_data)); + if (memcmp(enc_data, ct, sizeof(ct))) + { + printf("Error: AES ENCRYPT #1 failed\n"); + goto end; + } + + AES_set_key(&aes_key, key, iv, AES_MODE_128); + AES_convert_key(&aes_key); + AES_cbc_decrypt(&aes_key, enc_data, dec_data, sizeof(enc_data)); + + if (memcmp(dec_data, in_str, sizeof(dec_data))) + { + printf("Error: AES DECRYPT #1 failed\n"); + goto end; + } + } + + { + /* + Case #2: Encrypting 32 bytes (2 blocks) using AES-CBC + Key : 0xc286696d887c9aa0611bbb3e2025a45a + IV : 0x562e17996d093d28ddb3ba695a2e6f58 + Plaintext : 0x000102030405060708090a0b0c0d0e0f + 101112131415161718191a1b1c1d1e1f + Ciphertext: 0xd296cd94c2cccf8a3a863028b5e1dc0a + 7586602d253cfff91b8266bea6d61ab1 + */ + uint8_t in_data[TEST2_SIZE]; + uint8_t ct[TEST2_SIZE]; + uint8_t enc_data[TEST2_SIZE]; + uint8_t dec_data[TEST2_SIZE]; + + bigint *in_bi = bi_str_import(bi_ctx, + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); + bigint *key_bi = bi_str_import( + bi_ctx, "C286696D887C9AA0611BBB3E2025A45A"); + bigint *iv_bi = bi_str_import( + bi_ctx, "562E17996D093D28DDB3BA695A2E6F58"); + bigint *ct_bi = bi_str_import(bi_ctx, + "D296CD94C2CCCF8A3A863028B5E1DC0A7586602D253CFFF91B8266BEA6D61AB1"); + bi_export(bi_ctx, in_bi, in_data, TEST2_SIZE); + bi_export(bi_ctx, key_bi, key, TEST1_SIZE); + bi_export(bi_ctx, iv_bi, iv, TEST1_SIZE); + bi_export(bi_ctx, ct_bi, ct, TEST2_SIZE); + + AES_set_key(&aes_key, key, iv, AES_MODE_128); + AES_cbc_encrypt(&aes_key, (const uint8_t *)in_data, + enc_data, sizeof(enc_data)); + + if (memcmp(enc_data, ct, sizeof(ct))) + { + printf("Error: ENCRYPT #2 failed\n"); + goto end; + } + + AES_set_key(&aes_key, key, iv, AES_MODE_128); + AES_convert_key(&aes_key); + AES_cbc_decrypt(&aes_key, enc_data, dec_data, sizeof(enc_data)); + if (memcmp(dec_data, in_data, sizeof(dec_data))) + { + printf("Error: DECRYPT #2 failed\n"); + goto end; + } + } + + res = 0; + printf("All AES tests passed\n"); + +end: + return res; +} + +/************************************************************************** + * SHA1 tests + * + * Run through a couple of the RFC3174 tests to verify that SHA1 is correct. + **************************************************************************/ +static int SHA1_test(BI_CTX *bi_ctx) +{ + SHA1_CTX ctx; + uint8_t ct[SHA1_SIZE]; + uint8_t digest[SHA1_SIZE]; + int res = 1; + + { + const char *in_str = "abc"; + bigint *ct_bi = bi_str_import(bi_ctx, + "A9993E364706816ABA3E25717850C26C9CD0D89D"); + bi_export(bi_ctx, ct_bi, ct, SHA1_SIZE); + + SHA1_Init(&ctx); + SHA1_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA1_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA1 #1 failed\n"); + goto end; + } + } + + { + const char *in_str = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + bigint *ct_bi = bi_str_import(bi_ctx, + "84983E441C3BD26EBAAE4AA1F95129E5E54670F1"); + bi_export(bi_ctx, ct_bi, ct, SHA1_SIZE); + + SHA1_Init(&ctx); + SHA1_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA1_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA1 #2 failed\n"); + goto end; + } + } + + res = 0; + printf("All SHA1 tests passed\n"); + +end: + return res; +} + +/************************************************************************** + * SHA256 tests + * + * Run through a couple of the SHA-2 tests to verify that SHA256 is correct. + **************************************************************************/ +static int SHA256_test(BI_CTX *bi_ctx) +{ + SHA256_CTX ctx; + uint8_t ct[SHA256_SIZE]; + uint8_t digest[SHA256_SIZE]; + int res = 1; + + { + const char *in_str = "abc"; + bigint *ct_bi = bi_str_import(bi_ctx, + "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"); + bi_export(bi_ctx, ct_bi, ct, SHA256_SIZE); + + SHA256_Init(&ctx); + SHA256_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA256_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA256 #1 failed\n"); + goto end; + } + } + + { + const char *in_str = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + bigint *ct_bi = bi_str_import(bi_ctx, + "248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1"); + bi_export(bi_ctx, ct_bi, ct, SHA256_SIZE); + + SHA256_Init(&ctx); + SHA256_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA256_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA256 #2 failed\n"); + goto end; + } + } + + res = 0; + printf("All SHA256 tests passed\n"); + +end: + return res; +} + +/************************************************************************** + * SHA384 tests + * + * Run through a couple of the SHA-2 tests to verify that SHA384 is correct. + **************************************************************************/ +static int SHA384_test(BI_CTX *bi_ctx) +{ + SHA384_CTX ctx; + uint8_t ct[SHA384_SIZE]; + uint8_t digest[SHA384_SIZE]; + int res = 1; + + { + const char *in_str = "abc"; + bigint *ct_bi = bi_str_import(bi_ctx, + "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7"); + bi_export(bi_ctx, ct_bi, ct, SHA384_SIZE); + + SHA384_Init(&ctx); + SHA384_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA384_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA384 #1 failed\n"); + goto end; + } + } + + { + const char *in_str = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + bigint *ct_bi = bi_str_import(bi_ctx, + "3391FDDDFC8DC7393707A65B1B4709397CF8B1D162AF05ABFE8F450DE5F36BC6B0455A8520BC4E6F5FE95B1FE3C8452B"); + bi_export(bi_ctx, ct_bi, ct, SHA384_SIZE); + + SHA384_Init(&ctx); + SHA384_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA384_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA384 #2 failed\n"); + goto end; + } + } + + res = 0; + printf("All SHA384 tests passed\n"); + +end: + return res; +} +/************************************************************************** + * SHA512 tests + * + * Run through a couple of the SHA-2 tests to verify that SHA512 is correct. + **************************************************************************/ +static int SHA512_test(BI_CTX *bi_ctx) +{ + SHA512_CTX ctx; + uint8_t ct[SHA512_SIZE]; + uint8_t digest[SHA512_SIZE]; + int res = 1; + + { + const char *in_str = "abc"; + bigint *ct_bi = bi_str_import(bi_ctx, + "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F"); + bi_export(bi_ctx, ct_bi, ct, SHA512_SIZE); + + SHA512_Init(&ctx); + SHA512_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA512_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA512 #1 failed\n"); + goto end; + } + } + + { + const char *in_str = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + bigint *ct_bi = bi_str_import(bi_ctx, + "204A8FC6DDA82F0A0CED7BEB8E08A41657C16EF468B228A8279BE331A703C33596FD15C13B1B07F9AA1D3BEA57789CA031AD85C7A71DD70354EC631238CA3445"); + bi_export(bi_ctx, ct_bi, ct, SHA512_SIZE); + + SHA512_Init(&ctx); + SHA512_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA512_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA512 #2 failed\n"); + goto end; + } + } + + res = 0; + printf("All SHA512 tests passed\n"); + +end: + return res; +} +/************************************************************************** + * MD5 tests + * + * Run through a couple of the RFC1321 tests to verify that MD5 is correct. + **************************************************************************/ +static int MD5_test(BI_CTX *bi_ctx) +{ + MD5_CTX ctx; + uint8_t ct[MD5_SIZE]; + uint8_t digest[MD5_SIZE]; + int res = 1; + + { + const char *in_str = "abc"; + bigint *ct_bi = bi_str_import(bi_ctx, + "900150983CD24FB0D6963F7D28E17F72"); + bi_export(bi_ctx, ct_bi, ct, MD5_SIZE); + + MD5_Init(&ctx); + MD5_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + MD5_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: MD5 #1 failed\n"); + goto end; + } + } + + { + const char *in_str = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + bigint *ct_bi = bi_str_import( + bi_ctx, "D174AB98D277D9F5A5611C2C9F419D9F"); + bi_export(bi_ctx, ct_bi, ct, MD5_SIZE); + + MD5_Init(&ctx); + MD5_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + MD5_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: MD5 #2 failed\n"); + goto end; + } + } + res = 0; + printf("All MD5 tests passed\n"); + +end: + return res; +} + +/************************************************************************** + * HMAC tests + * + * Run through a couple of the RFC2202 tests to verify that HMAC is correct. + **************************************************************************/ +static int HMAC_test(BI_CTX *bi_ctx) +{ + uint8_t key[SHA256_SIZE]; + uint8_t ct[SHA256_SIZE]; + uint8_t dgst[SHA256_SIZE]; + int res = 1; + const char *key_str; + + const char *data_str = "Hi There"; + bigint *key_bi = bi_str_import(bi_ctx, "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); + bigint *ct_bi = bi_str_import(bi_ctx, "9294727A3638BB1C13F48EF8158BFC9D"); + bi_export(bi_ctx, key_bi, key, MD5_SIZE); + bi_export(bi_ctx, ct_bi, ct, MD5_SIZE); + hmac_md5((const uint8_t *)data_str, 8, key, MD5_SIZE, dgst); + if (memcmp(dgst, ct, MD5_SIZE)) + { + printf("HMAC MD5 #1 failed\n"); + goto end; + } + + data_str = "what do ya want for nothing?"; + key_str = "Jefe"; + ct_bi = bi_str_import(bi_ctx, "750C783E6AB0B503EAA86E310A5DB738"); + bi_export(bi_ctx, ct_bi, ct, MD5_SIZE); + hmac_md5((const uint8_t *)data_str, 28, (const uint8_t *)key_str, 4, dgst); + if (memcmp(dgst, ct, MD5_SIZE)) + { + printf("HMAC MD5 #2 failed\n"); + goto end; + } + + data_str = "Hi There"; + key_bi = bi_str_import(bi_ctx, "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); + ct_bi = bi_str_import(bi_ctx, "B617318655057264E28BC0B6FB378C8EF146BE00"); + bi_export(bi_ctx, key_bi, key, SHA1_SIZE); + bi_export(bi_ctx, ct_bi, ct, SHA1_SIZE); + + hmac_sha1((const uint8_t *)data_str, 8, + (const uint8_t *)key, SHA1_SIZE, dgst); + if (memcmp(dgst, ct, SHA1_SIZE)) + { + printf("HMAC SHA1 #1 failed\n"); + goto end; + } + + data_str = "what do ya want for nothing?"; + key_str = "Jefe"; + ct_bi = bi_str_import(bi_ctx, "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79"); + bi_export(bi_ctx, ct_bi, ct, SHA1_SIZE); + + hmac_sha1((const uint8_t *)data_str, 28, (const uint8_t *)key_str, 4, dgst); + if (memcmp(dgst, ct, SHA1_SIZE)) + { + printf("HMAC SHA1 #2 failed\n"); + goto end; + } + + data_str = "Hi There"; + key_bi = bi_str_import(bi_ctx, "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); + ct_bi = bi_str_import(bi_ctx, + "B0344C61D8DB38535CA8AFCEAF0BF12B881DC200C9833DA726E9376C2E32CFF7"); + bi_export(bi_ctx, key_bi, key, 20); + bi_export(bi_ctx, ct_bi, ct, SHA256_SIZE); + + hmac_sha256((const uint8_t *)data_str, 8, + (const uint8_t *)key, 20, dgst); + + if (memcmp(dgst, ct, SHA256_SIZE)) + { + printf("HMAC SHA256 #1 failed\n"); + goto end; + } + + data_str = "what do ya want for nothing?"; + key_str = "Jefe"; + ct_bi = bi_str_import(bi_ctx, + "5BDCC146BF60754E6A042426089575C75A003F089D2739839DEC58B964EC3843"); + bi_export(bi_ctx, ct_bi, ct, SHA256_SIZE); + + hmac_sha256((const uint8_t *)data_str, 28, + (const uint8_t *)key_str, 4, dgst); + if (memcmp(dgst, ct, SHA256_SIZE)) + { + printf("HMAC SHA256 #2 failed\n"); + goto end; + } + + // other test + /*uint8_t secret[16]; + key_str = "9BBE436BA940F017B17652849A71DB35"; + ct_bi = bi_str_import(bi_ctx, key_str); + bi_export(bi_ctx, ct_bi, secret, 16); + + uint8_t random[26]; + data_str = "74657374206C6162656CA0BA9F936CDA311827A6F796FFD5198C"; + ct_bi = bi_str_import(bi_ctx, data_str); + bi_export(bi_ctx, ct_bi, random, 26); + + uint8_t output[256]; + p_hash_sha256(secret, 16, random, 26, output, 100); + ct_bi = bi_import(bi_ctx, output, 100); + bi_print("RESULT", ct_bi); + */ + + /*uint8_t secret[48]; + uint8_t random[256]; + uint8_t output[256]; + + key_str = + "8C6D256467157DAEC7BAEBC1371E6DABFF1AB686EFA7DCF6B65242AA6EEBFC0A7472A1E583C4F2B23F784F25A6DE05A6"; + ct_bi = bi_str_import(bi_ctx, key_str); + bi_export(bi_ctx, ct_bi, secret, 48); + + data_str = + "636C69656E742066696E697368656475F80B2E4375CFA44105D16694A5E2D232302FF27241BDF52BA681C13E2CDF9F"; + ct_bi = bi_str_import(bi_ctx, data_str); + bi_export(bi_ctx, ct_bi, random, 47); + + p_hash_sha256(secret, 48, random, 47, output, 12); + ct_bi = bi_import(bi_ctx, output, 12); + bi_print("RESULT1", ct_bi);*/ + + res = 0; + printf("All HMAC tests passed\n"); + +end: + return res; +} + +/************************************************************************** + * BIGINT tests + * + **************************************************************************/ +static int BIGINT_test(BI_CTX *ctx) +{ + int res = 1; + +#ifndef CONFIG_INTEGER_8BIT +#ifndef CONFIG_INTEGER_16BIT + bigint *bi_data, *bi_exp, *bi_res; + const char *expnt, *plaintext, *mod; + uint8_t compare[MAX_KEY_BYTE_SIZE]; + /** + * 512 bit key + */ + plaintext = /* 64 byte number */ + "01aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeeee"; + + mod = "C30773C8ABE09FCC279EE0E5343370DE" + "8B2FFDB6059271E3005A7CEEF0D35E0A" + "1F9915D95E63560836CC2EB2C289270D" + "BCAE8CAF6F5E907FC2759EE220071E1B"; + + expnt = "A1E556CD1738E10DF539E35101334E97" + "BE8D391C57A5C89A7AD9A2EA2ACA1B3D" + "F3140F5091CC535CBAA47CEC4159EE1F" + "B6A3661AFF1AB758426EAB158452A9B9"; + + bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext)); + bi_exp = int_to_bi(ctx, 0x10001); + bi_set_mod(ctx, bi_str_import(ctx, mod), 0); + bi_res = bi_mod_power(ctx, bi_data, bi_exp); + + bi_data = bi_res; /* resuse again - see if we get the original */ + + bi_exp = bi_str_import(ctx, expnt); + bi_res = bi_mod_power(ctx, bi_data, bi_exp); + bi_free_mod(ctx, 0); + + bi_export(ctx, bi_res, compare, 64); + if (memcmp(plaintext, compare, 64) != 0) + goto end; +#endif +#endif + + /* + * Multiply with psssible carry issue (8 bit) + */ + { + bigint *bi_x = bi_str_import(ctx, + "AFD5060E224B70DA99EFB385BA5C0D2BEA0AD1DAAA52686E1A02D677BC65C1DA7A496BBDCC02999E8814F10AFC4B8E0DD4E6687E0762CE717A5EA1E452B5C56065C8431F0FB9D23CFF3A4B4149798C0670AF7F9565A0EAE5CF1AB16A1F0C3DD5E485DC5ABB96EBE0B6778A15B7302CBCE358E4BF2E2E30932758AC6EFA9F5828"); + bigint *arg2 = bi_clone(ctx, bi_x); + bigint *arg3 = bi_clone(ctx, bi_x); + bigint *sqr_result = bi_square(ctx, bi_x); + bigint *mlt_result = bi_multiply(ctx, arg2, arg3); + + if (bi_compare(sqr_result, mlt_result) != 0) + { + bi_print("SQR_RESULT", sqr_result); + bi_print("MLT_RESULT", mlt_result); + bi_free(ctx, sqr_result); + bi_free(ctx, mlt_result); + goto end; + } + + bi_free(ctx, sqr_result); + bi_free(ctx, mlt_result); + } + + printf("All BIGINT tests passed\n"); + res = 0; + +end: + return res; +} + +/************************************************************************** + * RSA tests + * + * Use the results from openssl to verify PKCS1 etc + **************************************************************************/ +static int RSA_test(void) +{ + int res = 1; + const char *plaintext = /* 128 byte hex number */ + "1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeeee2" + "1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeee2\012"; + uint8_t enc_data[128], dec_data[128]; + RSA_CTX *rsa_ctx = NULL; + BI_CTX *bi_ctx; + bigint *plaintext_bi; + bigint *enc_data_bi, *dec_data_bi; + uint8_t enc_data2[128], dec_data2[128]; + int len; + uint8_t *buf; + + RNG_initialize(); + + /* extract the private key elements */ + len = get_file("../ssl/test/axTLS.key_1024", &buf); + if (asn1_get_private_key(buf, len, &rsa_ctx) < 0) + { + goto end; + } + + free(buf); + bi_ctx = rsa_ctx->bi_ctx; + plaintext_bi = bi_import(bi_ctx, + (const uint8_t *)plaintext, strlen(plaintext)); + + /* basic rsa encrypt */ + enc_data_bi = RSA_public(rsa_ctx, plaintext_bi); + bi_export(bi_ctx, bi_copy(enc_data_bi), enc_data, sizeof(enc_data)); + + /* basic rsa decrypt */ + dec_data_bi = RSA_private(rsa_ctx, enc_data_bi); + bi_export(bi_ctx, dec_data_bi, dec_data, sizeof(dec_data)); + + if (memcmp(dec_data, plaintext, strlen(plaintext))) + { + printf("Error: DECRYPT #1 failed\n"); + goto end; + } + + if (RSA_encrypt(rsa_ctx, (const uint8_t *)"abc", 3, enc_data2, 0) < 0) + { + printf("Error: ENCRYPT #2 failed\n"); + goto end; + } + + RSA_decrypt(rsa_ctx, enc_data2, dec_data2, sizeof(dec_data2), 1); + if (memcmp("abc", dec_data2, 3)) + { + printf("Error: DECRYPT #2 failed\n"); + goto end; + } + + RSA_free(rsa_ctx); + res = 0; + printf("All RSA tests passed\n"); + +end: + RNG_terminate(); + return res; +} + +/************************************************************************** + * Cert Testing + * + **************************************************************************/ +static int cert_tests(void) +{ + int res = -1, len; + X509_CTX *x509_ctx; + SSL_CTX *ssl_ctx; + uint8_t *buf; + + /* check a bunch of 3rd party certificates */ + ssl_ctx = ssl_ctx_new(0, 0); + len = get_file("../ssl/test/microsoft.x509_ca", &buf); + if ((res = add_cert_auth(ssl_ctx, buf, len)) < 0) + { + printf("Cert #1\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + free(buf); + + ssl_ctx = ssl_ctx_new(0, 0); + len = get_file("../ssl/test/thawte.x509_ca", &buf); + if ((res = add_cert_auth(ssl_ctx, buf, len)) < 0) + { + printf("Cert #2\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + free(buf); + + ssl_ctx = ssl_ctx_new(0, 0); + len = get_file("../ssl/test/deutsche_telecom.x509_ca", &buf); + if ((res = add_cert_auth(ssl_ctx, buf, len)) < 0) + { + printf("Cert #3\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + free(buf); + + ssl_ctx = ssl_ctx_new(0, 0); + len = get_file("../ssl/test/equifax.x509_ca", &buf); + if ((res = add_cert_auth(ssl_ctx, buf, len)) < 0) + { + printf("Cert #4\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + free(buf); + + ssl_ctx = ssl_ctx_new(0, 0); + len = get_file("../ssl/test/gnutls.cer", &buf); + if ((res = add_cert(ssl_ctx, buf, len)) < 0) + { + printf("Cert #5\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + free(buf); + + ssl_ctx = ssl_ctx_new(0, 0); + len = get_file("../ssl/test/socgen.cer", &buf); + if ((res = add_cert(ssl_ctx, buf, len)) < 0) + { + printf("Cert #6\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + free(buf); + + ssl_ctx = ssl_ctx_new(0, 0); + if ((res = ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, + "../ssl/test/camster_duckdns_org.crt", NULL)) != SSL_OK) + { + printf("Cert #7\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + + ssl_ctx = ssl_ctx_new(0, 0); + if ((res = ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, + "../ssl/test/comodo.sha384.cer", NULL)) != SSL_OK) + { + printf("Cert #8\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + + ssl_ctx = ssl_ctx_new(0, 0); + if ((res = ssl_obj_load(ssl_ctx, + SSL_OBJ_X509_CERT, "../ssl/test/ms_iis.cer", NULL)) != SSL_OK) + { + printf("Cert #9\n"); + ssl_display_error(res); + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + + if (get_file("../ssl/test/qualityssl.com.der", &buf) < 0 || + x509_new(buf, &len, &x509_ctx)) + { + printf("Cert #10\n"); + res = -1; + goto bad_cert; + } + + if (strcmp(x509_ctx->subject_alt_dnsnames[1], "qualityssl.com")) + { + printf("Cert #11\n"); + res = -1; + goto bad_cert; + } + x509_free(x509_ctx); + free(buf); + + // this bundle has two DSA (1.2.840.10040.4.3 invalid) certificates + ssl_ctx = ssl_ctx_new(0, 0); + if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, + "../ssl/test/ca-bundle.crt", NULL)) + { + goto bad_cert; + } + + ssl_ctx_free(ssl_ctx); + res = 0; /* all ok */ + printf("All Certificate tests passed\n"); + +bad_cert: + if (res) + printf("Error: A certificate test failed\n"); + + return res; +} + +/** + * init a server socket. + */ +static int server_socket_init(int *port) +{ + struct sockaddr_in serv_addr; + int server_fd; + char yes = 1; + + /* Create socket for incoming connections */ + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + return -1; + } + + setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); + +go_again: + /* Construct local address structure */ + memset(&serv_addr, 0, sizeof(serv_addr)); /* Zero out structure */ + serv_addr.sin_family = AF_INET; /* Internet address family */ + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + serv_addr.sin_port = htons(*port); /* Local port */ + + /* Bind to the local address */ + if (bind(server_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) + { + (*port)++; + goto go_again; + } + /* Mark the socket so it will listen for incoming connections */ + if (listen(server_fd, 3000) < 0) + { + return -1; + } + + return server_fd; +} + +/** + * init a client socket. + */ +static int client_socket_init(uint16_t port) +{ + struct sockaddr_in address; + int client_fd; + + address.sin_family = AF_INET; + address.sin_port = htons(port); + address.sin_addr.s_addr = inet_addr("127.0.0.1"); + client_fd = socket(AF_INET, SOCK_STREAM, 0); + if (connect(client_fd, (struct sockaddr *)&address, sizeof(address)) < 0) + { + perror("socket"); + SOCKET_CLOSE(client_fd); + client_fd = -1; + } + + return client_fd; +} + +/************************************************************************** + * SSL Server Testing + * + **************************************************************************/ +typedef struct +{ + /* not used as yet */ + int dummy; +} SVR_CTX; + +typedef struct +{ + const char *testname; + const char *openssl_option; +} client_t; + +static void do_client(client_t *clnt) +{ + char openssl_buf[2048]; + usleep(200000); /* allow server to start */ + + /* show the session ids in the reconnect test */ + if (strcmp(clnt->testname, "Session Reuse") == 0) + { + sprintf(openssl_buf, "echo \"hello client\" | openssl s_client " + "-connect localhost:%d %s 2>&1 | grep \"Session-ID:\"", + g_port, clnt->openssl_option); + } + else if (strstr(clnt->testname, "GNUTLS") == NULL) + { + sprintf(openssl_buf, "echo \"hello client\" | openssl s_client " +#ifdef WIN32 + "-connect localhost:%d -quiet %s", +#else + "-connect localhost:%d -quiet %s > /dev/null 2>&1", +#endif + g_port, clnt->openssl_option); + } + else /* gnutls */ + { + sprintf(openssl_buf, "echo \"hello client\" | gnutls-cli " +#ifdef WIN32 + "-p %d %s localhost", +#else + "-p %d %s localhost > /dev/null 2>&1", +#endif + g_port, clnt->openssl_option); + } + +//printf("CLIENT %s\n", openssl_buf); + SYSTEM(openssl_buf); +} + +static int SSL_server_test( + const char *testname, + const char *openssl_option, + const char *device_cert, + const char *product_cert, + const char *private_key, + const char *ca_cert, + const char *password, + int axtls_option) +{ + int server_fd, ret = 0; + SSL_CTX *ssl_ctx = NULL; + struct sockaddr_in client_addr; + uint8_t *read_buf; + socklen_t clnt_len = sizeof(client_addr); + client_t client_data; +#ifndef WIN32 + pthread_t thread; +#endif + g_port++; + + client_data.testname = testname; + client_data.openssl_option = openssl_option; + + if ((server_fd = server_socket_init(&g_port)) < 0) + goto error; + + if (private_key) + { + axtls_option |= SSL_NO_DEFAULT_KEY; + } + + if ((ssl_ctx = ssl_ctx_new(axtls_option, SSL_DEFAULT_SVR_SESS)) == NULL) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + + if (private_key) + { + int obj_type = SSL_OBJ_RSA_KEY; + + if (strstr(private_key, ".p8")) + obj_type = SSL_OBJ_PKCS8; + else if (strstr(private_key, ".p12")) + obj_type = SSL_OBJ_PKCS12; + + if (ssl_obj_load(ssl_ctx, obj_type, private_key, password)) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + } + + if (device_cert) /* test chaining */ + { + if ((ret = ssl_obj_load(ssl_ctx, + SSL_OBJ_X509_CERT, device_cert, NULL)) != SSL_OK) + goto error; + } + + if (product_cert) /* test chaining */ + { + if ((ret = ssl_obj_load(ssl_ctx, + SSL_OBJ_X509_CERT, product_cert, NULL)) != SSL_OK) + goto error; + } + + if (ca_cert) /* test adding certificate authorities */ + { + if ((ret = ssl_obj_load(ssl_ctx, + SSL_OBJ_X509_CACERT, ca_cert, NULL)) != SSL_OK) + goto error; + } + +#ifndef WIN32 + pthread_create(&thread, NULL, + (void *(*)(void *))do_client, (void *)&client_data); + pthread_detach(thread); +#else + CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_client, + (LPVOID)&client_data, 0, NULL); +#endif + + for (;;) + { + int client_fd, size = 0; + SSL *ssl; + + /* Wait for a client to connect */ + if ((client_fd = accept(server_fd, + (struct sockaddr *)&client_addr, &clnt_len)) < 0) + { + ret = SSL_ERROR_SOCK_SETUP_FAILURE; + goto error; + } + + /* we are ready to go */ + ssl = ssl_server_new(ssl_ctx, client_fd); + while ((size = ssl_read(ssl, &read_buf)) == SSL_OK); + SOCKET_CLOSE(client_fd); + + if (size == SSL_CLOSE_NOTIFY) + { + /* do nothing */ + } + else if (size < SSL_OK) /* got some alert or something nasty */ + { + ret = size; + + if (ret == SSL_ERROR_CONN_LOST) + continue; + + break; /* we've got a problem */ + } + else /* looks more promising */ + { + if (strstr("hello client", (char *)read_buf) == NULL) + { + printf("SSL server test \"%s\" passed\n", testname); + TTY_FLUSH(); + ret = 0; + break; + } + } + + ssl_free(ssl); + } + + SOCKET_CLOSE(server_fd); + +error: + ssl_ctx_free(ssl_ctx); + return ret; +} + +int SSL_server_tests(void) +{ + int ret = -1; + struct stat stat_buf; + SVR_CTX svr_test_ctx; + memset(&svr_test_ctx, 0, sizeof(SVR_CTX)); + + printf("### starting server tests\n"); TTY_FLUSH(); + + /* Go through the algorithms */ + + /* + * TLS client hello + */ + + /* + * AES128-SHA TLS1.2 + */ + if ((ret = SSL_server_test("AES128-SHA TLS1.2", + "-cipher AES128-SHA -tls1_2", + DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, + DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * AES256-SHA TLS1.2 + */ + if ((ret = SSL_server_test("AES256-SHA TLS1.2", + "-cipher AES256-SHA -tls1_2", + DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, + DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * AES128-SHA256 TLS1.2 + */ + if ((ret = SSL_server_test("AES128-SHA256 TLS1.2", + "-cipher AES128-SHA256 -tls1_2", + DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, + DEFAULT_SVR_OPTION))) + goto cleanup; + + + /* + * AES256-SHA256 TLS1.2 + */ + if ((ret = SSL_server_test("AES256-SHA256 TLS1.2", + "-cipher AES256-SHA256 -tls1_2", + DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, + DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * AES128-SHA TLS1.1 + */ + if ((ret = SSL_server_test("AES128-SHA TLS1.1", + "-cipher AES128-SHA -tls1_1", + DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, + DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * AES128-SHA TLS1.0 + */ + if ((ret = SSL_server_test("AES128-SHA TLS1.0", + "-cipher AES128-SHA -tls1", + DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, + DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * Session Reuse + * all the session id's should match for session resumption. + */ + if ((ret = SSL_server_test("Session Reuse", + "-cipher AES128-SHA -reconnect -tls1_2", + DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, + DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * 1024 bit RSA key (check certificate chaining) + */ + if ((ret = SSL_server_test("1024 bit key", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_1024.cer", NULL, + "../ssl/test/axTLS.key_1024", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * 2048 bit RSA key + */ + if ((ret = SSL_server_test("2048 bit key", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_2048.cer", NULL, + "../ssl/test/axTLS.key_2048", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * 4096 bit RSA key + */ + if ((ret = SSL_server_test("4096 bit key", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_4096.cer", NULL, + "../ssl/test/axTLS.key_4096", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * RSA1024/SHA256 + */ + if ((ret = SSL_server_test("RSA1024/SHA256", + "-tls1_2", + "../ssl/test/axTLS.x509_1024_sha256.pem" , NULL, + "../ssl/test/axTLS.key_1024", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * RSA1024/SHA384 + */ + if ((ret = SSL_server_test("RSA1024/SHA384", + "-tls1_2", + "../ssl/test/axTLS.x509_1024_sha384.pem" , NULL, + "../ssl/test/axTLS.key_1024", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * RSA1024/SHA512 + */ + if ((ret = SSL_server_test("RSA1024/SHA512", + "-tls1_2", + "../ssl/test/axTLS.x509_1024_sha512.pem" , NULL, + "../ssl/test/axTLS.key_1024", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * Client Verification + */ + if ((ret = SSL_server_test("Client Verification TLS1.2", + "-cipher AES128-SHA -tls1_2 " + "-cert ../ssl/test/axTLS.x509_2048.pem " + "-key ../ssl/test/axTLS.key_2048.pem ", + NULL, + "../ssl/test/axTLS.x509_1024.pem", + "../ssl/test/axTLS.key_1024.pem", + "../ssl/test/axTLS.ca_x509.cer", NULL, + DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION))) + goto cleanup; + + if ((ret = SSL_server_test("Client Verification TLS1.1", + "-cipher AES128-SHA -tls1_1 " + "-cert ../ssl/test/axTLS.x509_2048.pem " + "-key ../ssl/test/axTLS.key_2048.pem ", + NULL, + "../ssl/test/axTLS.x509_1024.pem", + "../ssl/test/axTLS.key_1024.pem", + "../ssl/test/axTLS.ca_x509.cer", NULL, + DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION))) + goto cleanup; + + /* this test should fail */ + if (stat("../ssl/test/axTLS.x509_bad_before.pem", &stat_buf) >= 0) + { + if ((ret = SSL_server_test("Error: Bad Before Cert", + "-cipher AES128-SHA -tls1_2 " + "-cert ../ssl/test/axTLS.x509_bad_before.pem " + "-key ../ssl/test/axTLS.key_1024.pem ", + NULL, + "../ssl/test/axTLS.x509_1024.pem", + "../ssl/test/axTLS.key_1024.pem", + "../ssl/test/axTLS.ca_x509.cer", NULL, + DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) != + SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID)) + goto cleanup; + + printf("SSL server test \"%s\" passed\n", "Bad Before Cert"); + TTY_FLUSH(); + } + + /* this test should fail */ + if ((ret = SSL_server_test("Error: Bad After Cert", + "-cipher AES128-SHA -tls1_2 " + "-cert ../ssl/test/axTLS.x509_bad_after.pem " + "-key ../ssl/test/axTLS.key_1024.pem ", + NULL, + "../ssl/test/axTLS.x509_1024.pem", + "../ssl/test/axTLS.key_1024.pem", + "../ssl/test/axTLS.ca_x509.cer", NULL, + DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) != + SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED)) + goto cleanup; + + printf("SSL server test \"%s\" passed\n", "Bad After Cert"); + TTY_FLUSH(); + + /* + * No trusted cert + */ + if ((ret = SSL_server_test("Error: No trusted certificate", + "-cipher AES128-SHA -tls1_2 " + "-cert ../ssl/test/axTLS.x509_1024.pem " + "-key ../ssl/test/axTLS.key_1024.pem ", + NULL, + "../ssl/test/axTLS.x509_1024.pem", + "../ssl/test/axTLS.key_1024.pem", + NULL, NULL, + DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) != + SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT)) + goto cleanup; + + printf("SSL server test \"%s\" passed\n", "No trusted certificate"); + TTY_FLUSH(); + + /* + * Self-signed (from the server) + */ + if ((ret = SSL_server_test("Error: Self-signed certificate (from server)", + "-cipher AES128-SHA -tls1_2 " + "-cert ../ssl/test/axTLS.x509_1024.pem " + "-key ../ssl/test/axTLS.key_1024.pem " + "-CAfile ../ssl/test/axTLS.ca_x509.pem ", + NULL, + "../ssl/test/axTLS.x509_1024.pem", + "../ssl/test/axTLS.key_1024.pem", + NULL, NULL, + DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) != + SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED)) + goto cleanup; + + printf("SSL server test \"%s\" passed\n", + "Self-signed certificate (from server)"); + TTY_FLUSH(); + + /* + * Self-signed (from the client) + */ + if ((ret = SSL_server_test("Self-signed certificate (from client)", + "-cipher AES128-SHA -tls1_2 " + "-cert ../ssl/test/axTLS.x509_1024.pem " + "-key ../ssl/test/axTLS.key_1024.pem ", + NULL, + "../ssl/test/axTLS.x509_1024.pem", + "../ssl/test/axTLS.key_1024.pem", + "../ssl/test/axTLS.ca_x509.cer", + NULL, + DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION))) + goto cleanup; + + /* + * Key in PEM format + */ + if ((ret = SSL_server_test("Key in PEM format", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_1024.cer", NULL, + "../ssl/test/axTLS.key_1024.pem", NULL, + NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * Cert in PEM format + */ + if ((ret = SSL_server_test("Cert in PEM format", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_1024.pem", NULL, + "../ssl/test/axTLS.key_1024.pem", NULL, + NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * Cert chain in PEM format + */ + if ((ret = SSL_server_test("Cert chain in PEM format", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_device.pem", + NULL, "../ssl/test/axTLS.key_device.pem", + "../ssl/test/axTLS.ca_x509.pem", NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * AES128 Encrypted key + */ + if ((ret = SSL_server_test("AES128 encrypted key", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_aes128.pem", NULL, + "../ssl/test/axTLS.key_aes128.pem", + NULL, "abcd", DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * AES256 Encrypted key + */ + if ((ret = SSL_server_test("AES256 encrypted key", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_aes256.pem", NULL, + "../ssl/test/axTLS.key_aes256.pem", + NULL, "abcd", DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * AES128 Encrypted invalid key + */ + if ((ret = SSL_server_test("AES128 encrypted invalid key", + "-cipher AES128-SHA -tls1_2", + "../ssl/test/axTLS.x509_aes128.pem", NULL, + "../ssl/test/axTLS.key_aes128.pem", + NULL, "xyz", DEFAULT_SVR_OPTION)) != SSL_ERROR_INVALID_KEY) + goto cleanup; + + printf("SSL server test \"%s\" passed\n", "AES128 encrypted invalid key"); + TTY_FLUSH(); + + /* + * PKCS#8 key (encrypted) + */ + if ((ret = SSL_server_test("pkcs#8 encrypted", + "-cipher AES128-SHA -tls1_2", + DEFAULT_CERT, NULL, "../ssl/test/axTLS.encrypted.p8", + NULL, "abcd", DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * PKCS#8 key (unencrypted DER format) + */ + if ((ret = SSL_server_test("pkcs#8 DER unencrypted", + "-cipher AES128-SHA -tls1_2", + DEFAULT_CERT, NULL, "../ssl/test/axTLS.unencrypted.p8", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * PKCS#8 key (unencrypted PEM format) + */ + if ((ret = SSL_server_test("pkcs#8 PEM unencrypted", + "-cipher AES128-SHA -tls1_2", + DEFAULT_CERT, NULL, "../ssl/test/axTLS.unencrypted_pem.p8", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * PKCS#12 key/certificate + */ + if ((ret = SSL_server_test("pkcs#12 with CA", "-cipher AES128-SHA", + NULL, NULL, "../ssl/test/axTLS.withCA.p12", + NULL, "abcd", DEFAULT_SVR_OPTION))) + goto cleanup; + + if ((ret = SSL_server_test("pkcs#12 no CA", "-cipher AES128-SHA", + DEFAULT_CERT, NULL, "../ssl/test/axTLS.withoutCA.p12", + NULL, "abcd", DEFAULT_SVR_OPTION))) + goto cleanup; + + /* + * GNUTLS + */ + if ((ret = SSL_server_test("GNUTLS client", + "", + "../ssl/test/axTLS.x509_1024.cer", NULL, + "../ssl/test/axTLS.key_1024", + NULL, NULL, DEFAULT_SVR_OPTION))) + goto cleanup; + + if ((ret = SSL_server_test("GNUTLS client with verify", + "--x509certfile ../ssl/test/axTLS.x509_1024.pem " + "--x509keyfile ../ssl/test/axTLS.key_1024.pem", + "../ssl/test/axTLS.x509_1024.cer", NULL, + "../ssl/test/axTLS.key_1024", + "../ssl/test/axTLS.ca_x509.cer", NULL, + DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION))) + goto cleanup; + ret = 0; + +cleanup: + if (ret) + { + printf("Error: A server test failed\n"); + ssl_display_error(ret); + exit(1); + } + else + { + printf("All server tests passed\n"); TTY_FLUSH(); + } + + return ret; +} + +/************************************************************************** + * SSL Client Testing + * + **************************************************************************/ +typedef struct +{ + uint8_t session_id[SSL_SESSION_ID_SIZE]; +#ifndef WIN32 + pthread_t server_thread; +#endif + int start_server; + int stop_server; + int do_reneg; +} CLNT_SESSION_RESUME_CTX; + +typedef struct +{ + const char *testname; + const char *openssl_option; + int do_gnutls; +} server_t; + +static void do_server(server_t *svr) +{ + char openssl_buf[2048]; +#ifndef WIN32 + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); +#endif + if (svr->do_gnutls) + { + sprintf(openssl_buf, "gnutls-serv " + "-p %d --quiet %s ", g_port, svr->openssl_option); + } + else + { + sprintf(openssl_buf, "openssl s_server " +#ifdef WIN32 + "-accept %d -quiet %s", +#else + "-accept %d -quiet %s > /dev/null", +#endif + g_port, svr->openssl_option); + } +//printf("SERVER %s\n", openssl_buf); + SYSTEM(openssl_buf); +} + +static int SSL_client_test( + const char *test, + SSL_CTX **ssl_ctx, + const char *openssl_option, + CLNT_SESSION_RESUME_CTX *sess_resume, + uint32_t client_options, + const char *private_key, + const char *password, + const char *cert) +{ + server_t server_data; + SSL *ssl = NULL; + int client_fd = -1; + uint8_t *session_id = NULL; + int ret = 1; +#ifndef WIN32 + pthread_t thread; +#endif + + server_data.do_gnutls = strstr(test, "GNUTLS") != NULL; + + if (sess_resume == NULL || sess_resume->start_server) + { + g_port++; + server_data.openssl_option = openssl_option; + +#ifndef WIN32 + pthread_create(&thread, NULL, + (void *(*)(void *))do_server, (void *)&server_data); + pthread_detach(thread); +#else + CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_server, + (LPVOID)&server_data, 0, NULL); +#endif + } + + usleep(200000); /* allow server to start */ + + if (*ssl_ctx == NULL) + { + if (private_key) + { + client_options |= SSL_NO_DEFAULT_KEY; + } + + if ((*ssl_ctx = ssl_ctx_new( + client_options, SSL_DEFAULT_CLNT_SESS)) == NULL) + { + ret = SSL_ERROR_INVALID_KEY; + goto client_test_exit; + } + + if (private_key) + { + int obj_type = SSL_OBJ_RSA_KEY; + + if (strstr(private_key, ".p8")) + obj_type = SSL_OBJ_PKCS8; + else if (strstr(private_key, ".p12")) + obj_type = SSL_OBJ_PKCS12; + + if (ssl_obj_load(*ssl_ctx, obj_type, private_key, password)) + { + ret = SSL_ERROR_INVALID_KEY; + goto client_test_exit; + } + } + + if (cert) + { + if ((ret = ssl_obj_load(*ssl_ctx, + SSL_OBJ_X509_CERT, cert, NULL)) != SSL_OK) + { + printf("could not add cert %s (%d)\n", cert, ret); + TTY_FLUSH(); + goto client_test_exit; + } + } + + if (ssl_obj_load(*ssl_ctx, SSL_OBJ_X509_CACERT, + "../ssl/test/axTLS.ca_x509.cer", NULL)) + { + printf("could not add cert auth\n"); TTY_FLUSH(); + goto client_test_exit; + } + } + + if (sess_resume && !sess_resume->start_server) + { + session_id = sess_resume->session_id; + } + + if ((client_fd = client_socket_init(g_port)) < 0) + { + printf("could not start socket on %d\n", g_port); TTY_FLUSH(); + goto client_test_exit; + } + + ssl = ssl_client_new(*ssl_ctx, client_fd, + session_id, sizeof(session_id), NULL); + + /* check the return status */ + if ((ret = ssl_handshake_status(ssl))) + goto client_test_exit; + + /* renegotiate client */ + if (sess_resume && sess_resume->do_reneg) + { + if (ssl_renegotiate(ssl) == -SSL_ALERT_NO_RENEGOTIATION) + ret = 0; + else + ret = -SSL_ALERT_NO_RENEGOTIATION; + + goto client_test_exit; + } + + if (sess_resume) + { + memcpy(sess_resume->session_id, + ssl_get_session_id(ssl), SSL_SESSION_ID_SIZE); + } + + if (IS_SET_SSL_FLAG(SSL_SERVER_VERIFY_LATER) && + (ret = ssl_verify_cert(ssl))) + { + goto client_test_exit; + } + + ssl_write(ssl, (uint8_t *)"hello world\n", 13); + if (sess_resume) + { + const uint8_t *sess_id = ssl_get_session_id(ssl); + int i; + + printf(" Session-ID: "); + for (i = 0; i < SSL_SESSION_ID_SIZE; i++) + { + printf("%02X", sess_id[i]); + } + printf("\n"); + TTY_FLUSH(); + } + + ret = 0; + +client_test_exit: + ssl_free(ssl); + SOCKET_CLOSE(client_fd); + usleep(200000); /* allow openssl to say something */ + + if (sess_resume) + { + if (sess_resume->stop_server) + { + ssl_ctx_free(*ssl_ctx); + *ssl_ctx = NULL; + } + else if (sess_resume->start_server) + { +#ifndef WIN32 + sess_resume->server_thread = thread; +#endif + } + } + else + { + ssl_ctx_free(*ssl_ctx); + *ssl_ctx = NULL; + } + + if (ret == 0) + { + printf("SSL client test \"%s\" passed\n", test); + TTY_FLUSH(); + } + + return ret; +} + +int SSL_client_tests(void) +{ + int ret = -1; + SSL_CTX *ssl_ctx = NULL; + CLNT_SESSION_RESUME_CTX sess_resume; + memset(&sess_resume, 0, sizeof(CLNT_SESSION_RESUME_CTX)); + + sess_resume.start_server = 1; + printf("### starting client tests\n"); + + if ((ret = SSL_client_test("1024 bit key", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_1024.pem " + "-key ../ssl/test/axTLS.key_1024.pem", + &sess_resume, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + /* all the session id's should match for session resumption */ + sess_resume.start_server = 0; + if ((ret = SSL_client_test("Client session resumption #1", + &ssl_ctx, NULL, &sess_resume, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + // no client renegotiation + sess_resume.do_reneg = 1; + // test relies on openssl killing the call + if ((ret = SSL_client_test("Client renegotiation", + &ssl_ctx, NULL, &sess_resume, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + sess_resume.do_reneg = 0; + + sess_resume.stop_server = 1; + if ((ret = SSL_client_test("Client session resumption #2", + &ssl_ctx, NULL, &sess_resume, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + if ((ret = SSL_client_test("1024 bit key", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_1024.pem " + "-key ../ssl/test/axTLS.key_1024.pem", NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + if ((ret = SSL_client_test("2048 bit key", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_2048.pem " + "-key ../ssl/test/axTLS.key_2048.pem", NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + if ((ret = SSL_client_test("4096 bit key", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_4096.pem " + "-key ../ssl/test/axTLS.key_4096.pem", NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + if ((ret = SSL_client_test("TLS 1.1", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_1024.pem " + "-key ../ssl/test/axTLS.key_1024.pem -tls1_1", NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + if ((ret = SSL_client_test("TLS 1.0", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_1024.pem " + "-key ../ssl/test/axTLS.key_1024.pem -tls1", NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + if ((ret = SSL_client_test("Basic Constraint - len OK", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_end_chain.pem -key " + "../ssl/test/axTLS.key_end_chain.pem -CAfile " + "../ssl/test/axTLS.x509_intermediate_ca.pem", + NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + if ((ret = SSL_client_test("Basic Constraint - len NOT OK", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_end_chain_bad.pem -key " + "../ssl/test/axTLS.key_end_chain.pem -CAfile " + "../ssl/test/axTLS.x509_intermediate_ca2.pem", + NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL)) + != SSL_X509_ERROR(X509_VFY_ERROR_BASIC_CONSTRAINT)) + { + printf("*** Error: %d\n", ret); + if (ret == 0) + ret = SSL_NOT_OK; + + goto cleanup; + } + + printf("SSL server test \"%s\" passed\n", "Basic Constraint - len NOT OK"); + + if ((ret = SSL_client_test("Server cert chaining", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_device.pem " + "-key ../ssl/test/axTLS.key_device.pem " + "-CAfile ../ssl/test/axTLS.x509_1024.pem ", NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL))) + goto cleanup; + + /* Check the server can verify the client */ + if ((ret = SSL_client_test("Client peer authentication", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_2048.pem " + "-key ../ssl/test/axTLS.key_2048.pem " + "-CAfile ../ssl/test/axTLS.ca_x509.pem " + "-verify 1 ", NULL, DEFAULT_CLNT_OPTION, + "../ssl/test/axTLS.key_1024", NULL, + "../ssl/test/axTLS.x509_1024.cer"))) + goto cleanup; + + /* Check the server can verify the client */ + if ((ret = SSL_client_test("Client peer authentication TLS1.1", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_2048.pem " + "-key ../ssl/test/axTLS.key_2048.pem " + "-CAfile ../ssl/test/axTLS.ca_x509.pem " + "-verify 1 -tls1_1", NULL, DEFAULT_CLNT_OPTION, + "../ssl/test/axTLS.key_1024", NULL, + "../ssl/test/axTLS.x509_1024.cer"))) + goto cleanup; + + /* Should get an "ERROR" from openssl (as the handshake fails as soon as + * the certificate verification fails) */ + if ((ret = SSL_client_test("Error: Expired cert (verify now)", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_bad_after.pem " + "-key ../ssl/test/axTLS.key_1024.pem", NULL, + DEFAULT_CLNT_OPTION, NULL, NULL, NULL)) != + SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED)) + { + printf("*** Error: %d\n", ret); + goto cleanup; + } + + printf("SSL client test \"Expired cert (verify now)\" passed\n"); + + /* There is no "ERROR" from openssl */ + if ((ret = SSL_client_test("Error: Expired cert (verify later)", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_bad_after.pem " + "-key ../ssl/test/axTLS.key_1024.pem", NULL, + DEFAULT_CLNT_OPTION|SSL_SERVER_VERIFY_LATER, NULL, + NULL, NULL)) != SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED)) + { + printf("*** Error: %d\n", ret); TTY_FLUSH(); + goto cleanup; + } + + printf("SSL client test \"Expired cert (verify later)\" passed\n"); + + /* invalid cert type */ + /*if ((ret = SSL_client_test("Error: Invalid certificate type", + &ssl_ctx, + "-cert ../ssl/test/axTLS.x509_2048.pem " + "-key ../ssl/test/axTLS.key_2048.pem " + "-CAfile ../ssl/test/axTLS.ca_x509.pem " + "-verify 1 ", NULL, DEFAULT_CLNT_OPTION, + "../ssl/test/axTLS.key_1024.pem", NULL, + "../ssl/test/axTLS.x509_1024.pem")) + != SSL_ERROR_INVALID_KEY) + { + if (ret == 0) + ret = SSL_NOT_OK; + + printf("*** Error: %d\n", ret); TTY_FLUSH(); + goto cleanup; + } + + printf("SSL client test \"Invalid certificate type\" passed\n"); */ + + if ((ret = SSL_client_test("GNUTLS client", + &ssl_ctx, + "--x509certfile ../ssl/test/axTLS.x509_1024.pem " + "--x509keyfile ../ssl/test/axTLS.key_1024.pem -g", NULL, + DEFAULT_CLNT_OPTION, + "../ssl/test/axTLS.key_1024.pem", NULL, + "../ssl/test/axTLS.x509_1024.pem"))) + goto cleanup; + + ret = 0; + + if ((ret = SSL_client_test("GNUTLS client with verify", + &ssl_ctx, + "--x509certfile ../ssl/test/axTLS.x509_1024.pem " + "--x509keyfile ../ssl/test/axTLS.key_1024.pem -r -g", NULL, + DEFAULT_CLNT_OPTION|SSL_SERVER_VERIFY_LATER, + "../ssl/test/axTLS.key_1024.pem", NULL, + "../ssl/test/axTLS.x509_1024.pem"))) + goto cleanup; + + ret = 0; + +cleanup: + if (ret) + { + ssl_display_error(ret); + printf("Error: A client test failed\n"); + SYSTEM("sh ../ssl/test/killopenssl.sh"); + SYSTEM("sh ../ssl/test/killgnutls.sh"); + exit(1); + } + else + { + printf("All client tests passed\n"); TTY_FLUSH(); + } + + ssl_ctx_free(ssl_ctx); + return ret; +} + +/************************************************************************** + * SSL Basic Testing (test a big packet handshake) + * + **************************************************************************/ +static uint8_t basic_buf[256*1024]; + +static void do_basic(void) +{ + int client_fd; + SSL *ssl_clnt; + SSL_CTX *ssl_clnt_ctx = ssl_ctx_new( + DEFAULT_CLNT_OPTION, SSL_DEFAULT_CLNT_SESS); + usleep(200000); /* allow server to start */ + + if ((client_fd = client_socket_init(g_port)) < 0) + goto error; + + if (ssl_obj_load(ssl_clnt_ctx, SSL_OBJ_X509_CACERT, + "../ssl/test/axTLS.ca_x509.cer", NULL)) + goto error; + + ssl_clnt = ssl_client_new(ssl_clnt_ctx, client_fd, NULL, 0, NULL); + + /* check the return status */ + if (ssl_handshake_status(ssl_clnt) < 0) + { + ssl_display_error(ssl_handshake_status(ssl_clnt)); + goto error; + } + + ssl_write(ssl_clnt, basic_buf, sizeof(basic_buf)); + ssl_free(ssl_clnt); + +error: + ssl_ctx_free(ssl_clnt_ctx); + SOCKET_CLOSE(client_fd); + + /* exit this thread */ +} + +static int SSL_basic_test(void) +{ + int server_fd, client_fd, ret = 0, size = 0, offset = 0; + SSL_CTX *ssl_svr_ctx = NULL; + struct sockaddr_in client_addr; + uint8_t *read_buf; + socklen_t clnt_len = sizeof(client_addr); + SSL *ssl_svr; +#ifndef WIN32 + pthread_t thread; +#endif + memset(basic_buf, 0xA5, sizeof(basic_buf)/2); + memset(&basic_buf[sizeof(basic_buf)/2], 0x5A, sizeof(basic_buf)/2); + + if ((server_fd = server_socket_init(&g_port)) < 0) + goto error; + + ssl_svr_ctx = ssl_ctx_new(DEFAULT_SVR_OPTION, SSL_DEFAULT_SVR_SESS); + if ((ret = ssl_obj_load(ssl_svr_ctx, SSL_OBJ_X509_CERT, + "../ssl/test/axTLS.x509_1024.pem", NULL)) != SSL_OK) + goto error; + + if ((ret = ssl_obj_load(ssl_svr_ctx, SSL_OBJ_RSA_KEY, + "../ssl/test/axTLS.key_1024.pem", NULL)) != SSL_OK) + goto error; +#ifndef WIN32 + pthread_create(&thread, NULL, + (void *(*)(void *))do_basic, NULL); + pthread_detach(thread); +#else + CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_basic, NULL, 0, NULL); +#endif + + /* Wait for a client to connect */ + if ((client_fd = accept(server_fd, + (struct sockaddr *) &client_addr, &clnt_len)) < 0) + { + ret = SSL_ERROR_SOCK_SETUP_FAILURE; + goto error; + } + + /* we are ready to go */ + ssl_svr = ssl_server_new(ssl_svr_ctx, client_fd); + + do + { + while ((size = ssl_read(ssl_svr, &read_buf)) == SSL_OK); + + if (size < SSL_OK) /* got some alert or something nasty */ + { + ssl_display_error(size); + ret = size; + break; + } + else /* looks more promising */ + { + if (memcmp(read_buf, &basic_buf[offset], size) != 0) + { + ret = SSL_NOT_OK; + break; + } + } + + offset += size; + } while (offset < sizeof(basic_buf)); + + printf(ret == SSL_OK && offset == sizeof(basic_buf) ? + "SSL basic test passed\n" : + "SSL basic test failed\n"); + TTY_FLUSH(); + + ssl_free(ssl_svr); + SOCKET_CLOSE(server_fd); + SOCKET_CLOSE(client_fd); + +error: + ssl_ctx_free(ssl_svr_ctx); + return ret; +} + +/************************************************************************** + * SSL unblocked case + * + **************************************************************************/ +static void do_unblocked(void) +{ + int client_fd; + SSL *ssl_clnt; + SSL_CTX *ssl_clnt_ctx = ssl_ctx_new( + DEFAULT_CLNT_OPTION, + SSL_DEFAULT_CLNT_SESS | + SSL_CONNECT_IN_PARTS); + usleep(200000); /* allow server to start */ + + if ((client_fd = client_socket_init(g_port)) < 0) + goto error; + + { +#ifdef WIN32 + u_long argp = 1; + ioctlsocket(client_fd, FIONBIO, &argp); +#else + int flags = fcntl(client_fd, F_GETFL, NULL); + fcntl(client_fd, F_SETFL, flags | O_NONBLOCK); +#endif + } + + if (ssl_obj_load(ssl_clnt_ctx, SSL_OBJ_X509_CACERT, + "../ssl/test/axTLS.ca_x509.cer", NULL)) + goto error; + + ssl_clnt = ssl_client_new(ssl_clnt_ctx, client_fd, NULL, 0, NULL); + + while (ssl_handshake_status(ssl_clnt) != SSL_OK) + { + if (ssl_read(ssl_clnt, NULL) < 0) + { + ssl_display_error(ssl_handshake_status(ssl_clnt)); + goto error; + } + } + + ssl_write(ssl_clnt, basic_buf, sizeof(basic_buf)); + ssl_free(ssl_clnt); + +error: + ssl_ctx_free(ssl_clnt_ctx); + SOCKET_CLOSE(client_fd); + + /* exit this thread */ +} + +static int SSL_unblocked_test(void) +{ + int server_fd, client_fd, ret = 0, size = 0, offset = 0; + SSL_CTX *ssl_svr_ctx = NULL; + struct sockaddr_in client_addr; + uint8_t *read_buf; + socklen_t clnt_len = sizeof(client_addr); + SSL *ssl_svr; +#ifndef WIN32 + pthread_t thread; +#endif + memset(basic_buf, 0xA5, sizeof(basic_buf)/2); + memset(&basic_buf[sizeof(basic_buf)/2], 0x5A, sizeof(basic_buf)/2); + + if ((server_fd = server_socket_init(&g_port)) < 0) + goto error; + + ssl_svr_ctx = ssl_ctx_new(DEFAULT_SVR_OPTION, SSL_DEFAULT_SVR_SESS); + if ((ret = ssl_obj_load(ssl_svr_ctx, SSL_OBJ_X509_CERT, + "../ssl/test/axTLS.x509_1024.pem", NULL)) != SSL_OK) + goto error; + + if ((ret = ssl_obj_load(ssl_svr_ctx, SSL_OBJ_RSA_KEY, + "../ssl/test/axTLS.key_1024.pem", NULL)) != SSL_OK) + goto error; + +#ifndef WIN32 + pthread_create(&thread, NULL, + (void *(*)(void *))do_unblocked, NULL); + pthread_detach(thread); +#else + CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_unblocked, + NULL, 0, NULL); +#endif + + /* Wait for a client to connect */ + if ((client_fd = accept(server_fd, + (struct sockaddr *) &client_addr, &clnt_len)) < 0) + { + ret = SSL_ERROR_SOCK_SETUP_FAILURE; + goto error; + } + + /* we are ready to go */ + ssl_svr = ssl_server_new(ssl_svr_ctx, client_fd); + + do + { + while ((size = ssl_read(ssl_svr, &read_buf)) == SSL_OK); + + if (size < SSL_OK) /* got some alert or something nasty */ + { + ssl_display_error(size); + ret = size; + break; + } + else /* looks more promising */ + { + if (memcmp(read_buf, &basic_buf[offset], size) != 0) + { + ret = SSL_NOT_OK; + break; + } + } + + offset += size; + } while (offset < sizeof(basic_buf)); + + printf(ret == SSL_OK && offset == sizeof(basic_buf) ? + "SSL unblocked test passed\n" : + "SSL unblocked test failed\n"); + TTY_FLUSH(); + + ssl_free(ssl_svr); + SOCKET_CLOSE(server_fd); + SOCKET_CLOSE(client_fd); + +error: + ssl_ctx_free(ssl_svr_ctx); + return ret; +} + +#if !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING) +/************************************************************************** + * Multi-Threading Tests + * + **************************************************************************/ +#define NUM_THREADS 100 + +typedef struct +{ + SSL_CTX *ssl_clnt_ctx; + int port; + int thread_id; +} multi_t; + +void do_multi_clnt(multi_t *multi_data) +{ + int res = 1, client_fd, i; + SSL *ssl = NULL; + char tmp[5]; + + if ((client_fd = client_socket_init(multi_data->port)) < 0) + goto client_test_exit; + + usleep(200000); + ssl = ssl_client_new(multi_data->ssl_clnt_ctx, client_fd, NULL, 0, NULL); + + if ((res = ssl_handshake_status(ssl))) + { + printf("Client "); + ssl_display_error(res); + goto client_test_exit; + } + + sprintf(tmp, "%d\n", multi_data->thread_id); + for (i = 0; i < 10; i++) + ssl_write(ssl, (uint8_t *)tmp, strlen(tmp)+1); + +client_test_exit: + ssl_free(ssl); + SOCKET_CLOSE(client_fd); + free(multi_data); +} + +void do_multi_svr(SSL *ssl) +{ + uint8_t *read_buf; + int *res_ptr = malloc(sizeof(int)); + int res; + + for (;;) + { + res = ssl_read(ssl, &read_buf); + + /* kill the client */ + if (res != SSL_OK) + { + if (res == SSL_ERROR_CONN_LOST) + { + SOCKET_CLOSE(ssl->client_fd); + ssl_free(ssl); + break; + } + else if (res > 0) + { + /* do nothing */ + } + else /* some problem */ + { + printf("Server "); + ssl_display_error(res); + goto error; + } + } + } + + res = SSL_OK; +error: + *res_ptr = res; + pthread_exit(res_ptr); +} + +int multi_thread_test(void) +{ + int server_fd = -1; + SSL_CTX *ssl_server_ctx; + SSL_CTX *ssl_clnt_ctx; + pthread_t clnt_threads[NUM_THREADS]; + pthread_t svr_threads[NUM_THREADS]; + int i, res = 0; + struct sockaddr_in client_addr; + socklen_t clnt_len = sizeof(client_addr); + + printf("Do multi-threading test (takes a minute)\n"); + + ssl_svr_ctx = ssl_ctx_new(DEFAULT_SVR_OPTION, SSL_DEFAULT_SVR_SESS); + if ((ret = ssl_obj_load(ssl_svr_ctx, SSL_OBJ_X509_CERT, + "../ssl/test/axTLS.x509_1024.pem", NULL)) != SSL_OK) + goto error; + + if ((ret = ssl_obj_load(ssl_svr_ctx, SSL_OBJ_RSA_KEY, + "../ssl/test/axTLS.key_1024.pem", NULL)) != SSL_OK) + goto error; + ssl_clnt_ctx = ssl_ctx_new(DEFAULT_CLNT_OPTION, SSL_DEFAULT_CLNT_SESS); + + if (ssl_obj_load(ssl_clnt_ctx, SSL_OBJ_X509_CACERT, + "../ssl/test/axTLS.ca_x509.cer", NULL)) + goto error; + + if ((server_fd = server_socket_init(&g_port)) < 0) + goto error; + + for (i = 0; i < NUM_THREADS; i++) + { + multi_t *multi_data = (multi_t *)malloc(sizeof(multi_t)); + multi_data->ssl_clnt_ctx = ssl_clnt_ctx; + multi_data->port = g_port; + multi_data->thread_id = i+1; + pthread_create(&clnt_threads[i], NULL, + (void *(*)(void *))do_multi_clnt, (void *)multi_data); + pthread_detach(clnt_threads[i]); + } + + for (i = 0; i < NUM_THREADS; i++) + { + SSL *ssl_svr; + int client_fd = accept(server_fd, + (struct sockaddr *)&client_addr, &clnt_len); + + if (client_fd < 0) + goto error; + + ssl_svr = ssl_server_new(ssl_server_ctx, client_fd); + + pthread_create(&svr_threads[i], NULL, + (void *(*)(void *))do_multi_svr, (void *)ssl_svr); + } + + /* make sure we've run all of the threads */ + for (i = 0; i < NUM_THREADS; i++) + { + void *thread_res; + pthread_join(svr_threads[i], &thread_res); + + if (*((int *)thread_res) != 0) + res = 1; + + free(thread_res); + } + + if (res) + goto error; + + printf("Multi-thread test passed (%d)\n", NUM_THREADS); +error: + ssl_ctx_free(ssl_svr_ctx); + ssl_ctx_free(ssl_clnt_ctx); + SOCKET_CLOSE(server_fd); + return res; +} +#endif /* !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING) */ + +/************************************************************************** + * Header issue + * + **************************************************************************/ +//static void do_header_issue(void) +//{ +// char axtls_buf[2048]; +//#ifndef WIN32 +// pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); +//#endif +// sprintf(axtls_buf, "./axssl s_client -connect localhost:%d", g_port); +// SYSTEM(axtls_buf); +//} +// +//static int header_issue(void) +//{ +// FILE *f = fopen("../ssl/test/header_issue.dat", "r"); +// int server_fd = -1, client_fd = -1, ret = 1; +// uint8_t buf[2048]; +// int size = 0; +// struct sockaddr_in client_addr; +// socklen_t clnt_len = sizeof(client_addr); +//#ifndef WIN32 +// pthread_t thread; +//#endif +// +// if (f == NULL || (server_fd = server_socket_init(&g_port)) < 0) +// goto error; +// +//#ifndef WIN32 +// pthread_create(&thread, NULL, +// (void *(*)(void *))do_header_issue, NULL); +// pthread_detach(thread); +//#else +// CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_header_issue, +// NULL, 0, NULL); +//#endif +// if ((client_fd = accept(server_fd, +// (struct sockaddr *) &client_addr, &clnt_len)) < 0) +// { +// ret = SSL_ERROR_SOCK_SETUP_FAILURE; +// goto error; +// } +// +// size = fread(buf, 1, sizeof(buf), f); +// if (SOCKET_WRITE(client_fd, buf, size) < 0) +// { +// ret = SSL_ERROR_SOCK_SETUP_FAILURE; +// goto error; +// } +// +// usleep(200000); +// +// ret = 0; +//error: +// fclose(f); +// SOCKET_CLOSE(client_fd); +// SOCKET_CLOSE(server_fd); +// TTY_FLUSH(); +// SYSTEM("killall axssl"); +// return ret; +//} + +/************************************************************************** + * main() + * + **************************************************************************/ +int main(int argc, char *argv[]) +{ + int ret = 1; + BI_CTX *bi_ctx; + int fd; + +#ifdef WIN32 + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(2, 2); + WSAStartup(wVersionRequested, &wsaData); + fd = _open("test_result.txt", O_WRONLY|O_TEMPORARY|O_CREAT, _S_IWRITE); + dup2(fd, 2); /* write stderr to this file */ +#else + fd = open("/dev/null", O_WRONLY); /* write stderr to /dev/null */ + signal(SIGPIPE, SIG_IGN); /* ignore pipe errors */ + dup2(fd, 2); +#endif + + /* can't do testing in this mode */ +#if defined CONFIG_SSL_GENERATE_X509_CERT + printf("Error: Must compile with default key/certificates\n"); + exit(1); +#endif + + bi_ctx = bi_initialize(); + + if (AES_test(bi_ctx)) + { + printf("AES tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + + if (MD5_test(bi_ctx)) + { + printf("MD5 tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + + if (SHA1_test(bi_ctx)) + { + printf("SHA1 tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + + if (SHA256_test(bi_ctx)) + { + printf("SHA256 tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + + if (SHA384_test(bi_ctx)) + { + printf("SHA384 tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + + if (SHA512_test(bi_ctx)) + { + printf("SHA512 tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + + if (HMAC_test(bi_ctx)) + { + printf("HMAC tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + + if (BIGINT_test(bi_ctx)) + { + printf("BigInt tests failed!\n"); + goto cleanup; + } + TTY_FLUSH(); + + bi_terminate(bi_ctx); + + if (RSA_test()) + { + printf("RSA tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + + if (cert_tests()) + { + printf("CERT tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + +#if !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING) + if (multi_thread_test()) + goto cleanup; +#endif + + if (SSL_basic_test()) + goto cleanup; + + SYSTEM("sh ../ssl/test/killopenssl.sh"); + + if (SSL_unblocked_test()) + goto cleanup; + + SYSTEM("sh ../ssl/test/killopenssl.sh"); + + if (SSL_client_tests()) + goto cleanup; + + SYSTEM("sh ../ssl/test/killopenssl.sh"); + SYSTEM("sh ../ssl/test/killgnutls.sh"); + + if (SSL_server_tests()) + goto cleanup; + + SYSTEM("sh ../ssl/test/killopenssl.sh"); + +// if (header_issue()) +// { +// printf("Header tests failed\n"); TTY_FLUSH(); +// goto cleanup; +// } + + ret = 0; /* all ok */ + printf("**** ALL TESTS PASSED ****\n"); TTY_FLUSH(); +cleanup: + + if (ret) + printf("Error: Some tests failed!\n"); + + close(fd); + return ret; +} diff --git a/circuitpython/lib/axtls/ssl/test/test_axssl.sh b/circuitpython/lib/axtls/ssl/test/test_axssl.sh new file mode 100755 index 0000000..acf11a6 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/test_axssl.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +# +# Copyright (c) 2007, Cameron Rich +# +# 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 axTLS project 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. +# + +# +# Test the various axssl bindings. To run it, got to the _install directory +# and run this script from there. +# + +if grep "CONFIG_PLATFORM_WIN32=y" "../config/.config" > /dev/null; then + JAVA_EXE="$JAVA_HOME/bin/java.exe" + PERL_BIN="/cygdrive/c/Perl/bin/perl" + KILL_AXSSL="kill %1" + KILL_CSHARP="kill %1" + KILL_PERL="kill %1" + KILL_JAVA="kill %1" + KILL_LUA="kill %1" +else + if grep "CONFIG_PLATFORM_CYGWIN=y" "../config/.config" > /dev/null; then + # no .net or java on cygwin + PERL_BIN=/usr/bin/perl + KILL_AXSSL="killall axssl" + KILL_PERL="killall /usr/bin/perl" + KILL_LUA="killall /usr/local/bin/lua" + else # Linux + JAVA_EXE=/usr/java/default/bin/java + PERL_BIN=/usr/bin/perl + KILL_AXSSL="killall axssl" + KILL_CSHARP="killall mono" + KILL_PERL="killall /usr/bin/perl" + RUN_CSHARP="mono" + KILL_JAVA="killall $JAVA_EXE" + KILL_LUA="killall /usr/local/bin/lua" + fi +fi + +BASE=.. +SERVER_ARGS="s_server -accept 15001 -verify -CAfile $BASE/ssl/test/axTLS.ca_x509.cer" +CLIENT_ARGS="s_client -reconnect -connect localhost:15001 -verify -CAfile $BASE/ssl/test/axTLS.ca_x509.cer -key $BASE/ssl/test/axTLS.key_1024 -cert $BASE/ssl/test/axTLS.x509_1024.cer" + +# check pem arguments +SERVER_PEM_ARGS="s_server -accept 15001 -pass abcd -key $BASE/ssl/test/axTLS.key_aes128.pem -cert $BASE/ssl/test/axTLS.x509_aes128.pem" +CLIENT_PEM_ARGS="s_client -connect localhost:15001 -CAfile $BASE/ssl/test/axTLS.ca_x509.pem -key $BASE/ssl/test/axTLS.key_1024.pem -cert $BASE/ssl/test/axTLS.x509_1024.pem" + +export LD_LIBRARY_PATH=.:`perl -e 'use Config; print $Config{archlib};'`/CORE + +if [ -x ./axssl ]; then +echo "############################# C SAMPLE ###########################" +./axssl $SERVER_ARGS & +echo "C Test passed" | ./axssl $CLIENT_ARGS +$KILL_AXSSL +sleep 1 + +./axssl $SERVER_PEM_ARGS & +echo "C Test passed" | ./axssl $CLIENT_PEM_ARGS +$KILL_AXSSL +sleep 1 +echo "### C tests complete" +fi + +if [ -f ./axtls.jar ]; then +echo "########################## JAVA SAMPLE ###########################" +"$JAVA_EXE" -jar ./axtls.jar $SERVER_ARGS & +echo "Java Test passed" | "$JAVA_EXE" -jar ./axtls.jar $CLIENT_ARGS +$KILL_JAVA +sleep 1 + +"$JAVA_EXE" -jar ./axtls.jar $SERVER_PEM_ARGS & +echo "Java Test passed" | "$JAVA_EXE" -jar ./axtls.jar $CLIENT_PEM_ARGS +$KILL_JAVA +sleep 1 + +echo "### Java tests complete" +fi + +if [ -x ./axssl.csharp.exe ]; then +echo "############################ C# SAMPLE ###########################" +$RUN_CSHARP ./axssl.csharp.exe $SERVER_ARGS & +echo "C# Test passed" | $RUN_CSHARP ./axssl.csharp.exe $CLIENT_ARGS +$KILL_CSHARP +sleep 1 + +$RUN_CSHARP ./axssl.csharp.exe $SERVER_PEM_ARGS & +echo "C# Test passed" | $RUN_CSHARP ./axssl.csharp.exe $CLIENT_PEM_ARGS +$KILL_CSHARP +sleep 1 + +echo "### C# tests complete" +fi + +if [ -x ./axssl.vbnet.exe ]; then +echo "######################## VB.NET SAMPLE ###########################" +echo $SERVER_ARGS +echo $CLIENT_ARGS +./axssl.vbnet $SERVER_ARGS & +echo "VB.NET Test passed" | ./axssl.vbnet.exe $CLIENT_ARGS +kill %1 +sleep 1 + +./axssl.vbnet $SERVER_PEM_ARGS & +echo "VB.NET Test passed" | ./axssl.vbnet.exe $CLIENT_PEM_ARGS +kill %1 +sleep 1 +echo "### VB.NET tests complete" +fi + +if [ -f ./axssl.pl ]; then +echo "########################## PERL SAMPLE ###########################" +"$PERL_BIN" ./axssl.pl $SERVER_ARGS & +echo "Perl Test passed" | "$PERL_BIN" ./axssl.pl $CLIENT_ARGS +$KILL_PERL +sleep 1 + +"$PERL_BIN" ./axssl.pl $SERVER_PEM_ARGS & +echo "Perl Test passed" | "$PERL_BIN" ./axssl.pl $CLIENT_PEM_ARGS +$KILL_PERL +sleep 1 +echo "### Perl tests complete" +fi + +if [ -f ./axssl.lua ]; then +echo "########################## LUA SAMPLE ###########################" +./axssl.lua $SERVER_ARGS & +echo "Lua Test passed" | ./axssl.lua $CLIENT_ARGS +$KILL_LUA +sleep 1 + +./axssl.lua $SERVER_PEM_ARGS & +echo "Lua Test passed" | ./axssl.lua $CLIENT_PEM_ARGS +$KILL_LUA +sleep 1 +echo "### Lua tests complete" +fi + +echo "########################## ALL TESTS COMPLETE ###########################" diff --git a/circuitpython/lib/axtls/ssl/test/thawte.x509_ca b/circuitpython/lib/axtls/ssl/test/thawte.x509_ca new file mode 100644 index 0000000..59b1059 Binary files /dev/null and b/circuitpython/lib/axtls/ssl/test/thawte.x509_ca differ diff --git a/circuitpython/lib/axtls/ssl/test/verisign.x509_ca.pem b/circuitpython/lib/axtls/ssl/test/verisign.x509_ca.pem new file mode 100644 index 0000000..d5ef5d2 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/verisign.x509_ca.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICmDCCAgECECCol67bggLewTagTia9h3MwDQYJKoZIhvcNAQECBQAwgYwxCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEwMC4GA1UECxMnRm9y +IFRlc3QgUHVycG9zZXMgT25seS4gIE5vIGFzc3VyYW5jZXMuMTIwMAYDVQQDEylW +ZXJpU2lnbiBUcmlhbCBTZWN1cmUgU2VydmVyIFRlc3QgUm9vdCBDQTAeFw0wNTAy +MDkwMDAwMDBaFw0yNTAyMDgyMzU5NTlaMIGMMQswCQYDVQQGEwJVUzEXMBUGA1UE +ChMOVmVyaVNpZ24sIEluYy4xMDAuBgNVBAsTJ0ZvciBUZXN0IFB1cnBvc2VzIE9u +bHkuICBObyBhc3N1cmFuY2VzLjEyMDAGA1UEAxMpVmVyaVNpZ24gVHJpYWwgU2Vj +dXJlIFNlcnZlciBUZXN0IFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAJ8h98U7klaZH5cEn6CSEKmGWVBsTwHIaMAAVqGqCUn7Q9C10sEOIHBznyLy +eSDjMs5M1nC/iAA7KCASf/yHz0AdlU+1IRSijwHTF/2dYSoTTxP2GCmtL1Ga4i7+ +zDDo086V7+NiFAGJj+CYey47ue4Xa33o/4YOA9PGL87oqFe7AgMBAAEwDQYJKoZI +hvcNAQECBQADgYEAOq447rP5EDqFEl3vhLhgTbnyaskNYwPvxk+0grnQyDA4sF/q +gK8nFlnvLmAOF3DmfuqW6WSr4zqTYzpwmJlsn48Om/yWirL8GuWRftit2POxTfHS +B8VmR+PZx2k24UgWUZyojDGxJtiHd3tjCdqFgTit4NK429cWOcZrh47xeOI= +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/test/verisign.x509_my_cert.pem b/circuitpython/lib/axtls/ssl/test/verisign.x509_my_cert.pem new file mode 100644 index 0000000..5b6c1ff --- /dev/null +++ b/circuitpython/lib/axtls/ssl/test/verisign.x509_my_cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEQzCCA6ygAwIBAgIQR/dXCzC/x5Ta5RvL6hKEojANBgkqhkiG9w0BAQUFADCB +jDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTAwLgYDVQQL +EydGb3IgVGVzdCBQdXJwb3NlcyBPbmx5LiAgTm8gYXNzdXJhbmNlcy4xMjAwBgNV +BAMTKVZlcmlTaWduIFRyaWFsIFNlY3VyZSBTZXJ2ZXIgVGVzdCBSb290IENBMB4X +DTA2MDExNjAwMDAwMFoXDTA2MDEzMDIzNTk1OVowgbkxCzAJBgNVBAYTAkFVMQww +CgYDVQQIEwNRbGQxETAPBgNVBAcUCEJyaXNiYW5lMRkwFwYDVQQKFBBheG9sb1RM +UyBQcm9qZWN0MRUwEwYDVQQLFAwxMDI0IGJpdCBrZXkxOjA4BgNVBAsUMVRlcm1z +IG9mIHVzZSBhdCB3d3cudmVyaXNpZ24uY29tL2Nwcy90ZXN0Y2EgKGMpMDUxGzAZ +BgNVBAMUEnd3dy5heG9sb3Rscy5jby5ucjCBnzANBgkqhkiG9w0BAQEFAAOBjQAw +gYkCgYEAttzj5S7qfOZIrh9xg8bgjTOKbSIbLBuMnxAwfGRcUrQO2EQOHd6kMjXR +hqY/cG2IG4G8AeqdV3nHlKbrbHbRa1lFgP6b0BQCE8TyxmP+tIAqn5L6/HTm+EEi +Ad1Pxjeok6e7F6UXHxJltSGHmOhAf3C5kPq/FQ6QZeG4yD/uzPkCAwEAAaOCAXUw +ggFxMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMEcGA1UdHwRAMD4wPKA6oDiGNmh0 +dHA6Ly9TVlJTZWN1cmUtY3JsLnZlcmlzaWduLmNvbS9TVlJUcmlhbFJvb3QyMDA1 +LmNybDBKBgNVHSAEQzBBMD8GCmCGSAGG+EUBBxUwMTAvBggrBgEFBQcCARYjaHR0 +cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nwcy90ZXN0Y2EwHQYDVR0lBBYwFAYIKwYB +BQUHAwEGCCsGAQUFBwMCMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0 +cDovL29jc3AudmVyaXNpZ24uY29tMG0GCCsGAQUFBwEMBGEwX6FdoFswWTBXMFUW +CWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgsexkuMCUW +I2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMA0GCSqGSIb3DQEB +BQUAA4GBACtlCTJFENCcHCQLHJfiotqr2XR+oWu0MstNm8dG6WB+zYprrT+kOPDn +1rMO7YLx76f67fC+lIXz720kQHk6LsZ8hPBQvIXnfIsKjng73DeFzBmTMFz6Qxjd ++E0FUCKplqrdwUkmR4kH6O4pdGE4AlXJNiUI2903yYdSRVMOuLuR +-----END CERTIFICATE----- diff --git a/circuitpython/lib/axtls/ssl/tls1.c b/circuitpython/lib/axtls/ssl/tls1.c new file mode 100755 index 0000000..8c21825 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/tls1.c @@ -0,0 +1,2463 @@ +/* + * Copyright (c) 2007-2019, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * Common ssl/tlsv1 code to both the client and server implementations. + */ + +#include +#include +#include +#include +#include "os_port.h" +#include "ssl.h" + +/* The session expiry time */ +#define SSL_EXPIRY_TIME (CONFIG_SSL_EXPIRY_TIME*3600) + +static const uint8_t g_hello_request[] = { HS_HELLO_REQUEST, 0, 0, 0 }; +static const uint8_t g_chg_cipher_spec_pkt[] = { 1 }; +static const char * server_finished = "server finished"; +static const char * client_finished = "client finished"; + +static int do_handshake(SSL *ssl, uint8_t *buf, int read_len); +static int set_key_block(SSL *ssl, int is_write); +static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len); +static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt); +static int send_raw_packet(SSL *ssl, uint8_t protocol); +static int check_certificate_chain(SSL *ssl); + +/** + * The server will pick the cipher based on the order that the order that the + * ciphers are listed. This order is defined at compile time. + */ +#ifndef CONFIG_SSL_SKELETON_MODE +static void session_free(SSL_SESSION *ssl_sessions[], int sess_index); +#endif + +const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] = +#ifdef CONFIG_SSL_PROT_LOW /* low security, fast speed */ +{ SSL_AES128_SHA, SSL_AES128_SHA256, SSL_AES256_SHA, SSL_AES256_SHA256 }; +#elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */ +{ SSL_AES128_SHA256, SSL_AES256_SHA256, SSL_AES256_SHA, SSL_AES128_SHA }; +#else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */ +{ SSL_AES256_SHA256, SSL_AES128_SHA256, SSL_AES256_SHA, SSL_AES128_SHA }; +#endif + +/** + * The cipher map containing all the essentials for each cipher. + */ +static const cipher_info_t cipher_info[NUM_PROTOCOLS] = +{ + { /* AES128-SHA */ + SSL_AES128_SHA, /* AES128-SHA */ + 16, /* key size */ + 16, /* iv size */ + 16, /* block padding size */ + SHA1_SIZE, /* digest size */ + 2*(SHA1_SIZE+16+16), /* key block size */ + ssl_hmac_sha1, /* hmac algorithm */ + (crypt_func)AES_cbc_encrypt, /* encrypt */ + (crypt_func)AES_cbc_decrypt /* decrypt */ + }, + { /* AES256-SHA */ + SSL_AES256_SHA, /* AES256-SHA */ + 32, /* key size */ + 16, /* iv size */ + 16, /* block padding size */ + SHA1_SIZE, /* digest size */ + 2*(SHA1_SIZE+32+16), /* key block size */ + ssl_hmac_sha1, /* hmac algorithm */ + (crypt_func)AES_cbc_encrypt, /* encrypt */ + (crypt_func)AES_cbc_decrypt /* decrypt */ + }, + { /* AES128-SHA256 */ + SSL_AES128_SHA256, /* AES128-SHA256 */ + 16, /* key size */ + 16, /* iv size */ + 16, /* block padding size */ + SHA256_SIZE, /* digest size */ + 2*(SHA256_SIZE+32+16), /* key block size */ + hmac_sha256, /* hmac algorithm */ + (crypt_func)AES_cbc_encrypt, /* encrypt */ + (crypt_func)AES_cbc_decrypt /* decrypt */ + }, + { /* AES256-SHA256 */ + SSL_AES256_SHA256, /* AES256-SHA256 */ + 32, /* key size */ + 16, /* iv size */ + 16, /* block padding size */ + SHA256_SIZE, /* digest size */ + 2*(SHA256_SIZE+32+16), /* key block size */ + hmac_sha256, /* hmac algorithm */ + (crypt_func)AES_cbc_encrypt, /* encrypt */ + (crypt_func)AES_cbc_decrypt /* decrypt */ + } +}; + +static void prf(SSL *ssl, const uint8_t *sec, int sec_len, + uint8_t *seed, int seed_len, + uint8_t *out, int olen); +static const cipher_info_t *get_cipher_info(uint8_t cipher); +static void increment_read_sequence(SSL *ssl); +static void increment_write_sequence(SSL *ssl); +static void add_hmac_digest(SSL *ssl, int snd, uint8_t *hmac_header, + const uint8_t *buf, int buf_len, uint8_t *hmac_buf); + +/* win32 VC6.0 doesn't have variadic macros */ +#if defined(WIN32) && !defined(CONFIG_SSL_FULL_MODE) +void DISPLAY_BYTES(SSL *ssl, const char *format, + const uint8_t *data, int size, ...) {} +#endif + +/** + * Allocates new SSL extensions structure and returns pointer to it + * + */ +EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new() +{ + return (SSL_EXTENSIONS *)calloc(1, sizeof(SSL_EXTENSIONS)); +} + +/** + * Allocates new SSL extensions structure and returns pointer to it + * + */ +EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext) +{ + if (ssl_ext == NULL ) + { + return; + } + + free(ssl_ext); +} + +/** + * Establish a new client/server context. + */ +EXP_FUNC SSL_CTX *STDCALL ssl_ctx_new(uint32_t options, int num_sessions) +{ + SSL_CTX *ssl_ctx = (SSL_CTX *)calloc(1, sizeof (SSL_CTX)); + ssl_ctx->options = options; + RNG_initialize(); + +#ifdef CONFIG_SSL_ENABLE_SERVER + if (load_key_certs(ssl_ctx) < 0) + { + free(ssl_ctx); /* can't load our key/certificate pair, so die */ + return NULL; + } +#endif + +#ifndef CONFIG_SSL_SKELETON_MODE + ssl_ctx->num_sessions = num_sessions; +#endif + + SSL_CTX_MUTEX_INIT(ssl_ctx->mutex); + +#ifndef CONFIG_SSL_SKELETON_MODE + if (num_sessions) + { + ssl_ctx->ssl_sessions = (SSL_SESSION **) + calloc(1, num_sessions*sizeof(SSL_SESSION *)); + } +#endif + + return ssl_ctx; +} + +/* + * Remove a client/server context. + */ +EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx) +{ + SSL *ssl; + int i; + + if (ssl_ctx == NULL) + return; + + ssl = ssl_ctx->head; + + /* clear out all the ssl entries */ + while (ssl) + { + SSL *next = ssl->next; + ssl_free(ssl); + ssl = next; + } + +#ifndef CONFIG_SSL_SKELETON_MODE + /* clear out all the sessions */ + for (i = 0; i < ssl_ctx->num_sessions; i++) + session_free(ssl_ctx->ssl_sessions, i); + + free(ssl_ctx->ssl_sessions); +#endif + + i = 0; + while (i < CONFIG_SSL_MAX_CERTS && ssl_ctx->certs[i].buf) + { + free(ssl_ctx->certs[i].buf); + ssl_ctx->certs[i++].buf = NULL; + } + +#ifdef CONFIG_SSL_CERT_VERIFICATION + remove_ca_certs(ssl_ctx->ca_cert_ctx); +#endif + ssl_ctx->chain_length = 0; + SSL_CTX_MUTEX_DESTROY(ssl_ctx->mutex); + RSA_free(ssl_ctx->rsa_ctx); + RNG_terminate(); + free(ssl_ctx); +} + +/* + * Free any used resources used by this connection. + */ +EXP_FUNC void STDCALL ssl_free(SSL *ssl) +{ + SSL_CTX *ssl_ctx; + + if (ssl == NULL) /* just ignore null pointers */ + return; + + /* only notify if we weren't notified first */ + /* spec says we must notify when we are dying */ + if (!IS_SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY)) + send_alert(ssl, SSL_ALERT_CLOSE_NOTIFY); + + ssl_ctx = ssl->ssl_ctx; + + SSL_CTX_LOCK(ssl_ctx->mutex); + + /* adjust the server SSL list */ + if (ssl->prev) + ssl->prev->next = ssl->next; + else + ssl_ctx->head = ssl->next; + + if (ssl->next) + ssl->next->prev = ssl->prev; + else + ssl_ctx->tail = ssl->prev; + + SSL_CTX_UNLOCK(ssl_ctx->mutex); + + /* may already be free - but be sure */ + free(ssl->encrypt_ctx); + ssl->encrypt_ctx = NULL; + free(ssl->decrypt_ctx); + ssl->decrypt_ctx = NULL; + disposable_free(ssl); +#ifdef CONFIG_SSL_CERT_VERIFICATION + x509_free(ssl->x509_ctx); +#endif + + ssl_ext_free(ssl->extensions); + ssl->extensions = NULL; + free(ssl); +} + +/* + * Read the SSL connection and send any alerts for various errors. + */ +EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data) +{ + int ret = basic_read(ssl, in_data); + + /* check for return code so we can send an alert */ + if (ret < SSL_OK && ret != SSL_CLOSE_NOTIFY && ret != SSL_EAGAIN) + { + if (ret != SSL_ERROR_CONN_LOST) + { + send_alert(ssl, ret); +#ifndef CONFIG_SSL_SKELETON_MODE + /* something nasty happened, so get rid of this session */ + kill_ssl_session(ssl->ssl_ctx->ssl_sessions, ssl); +#endif + } + } + + return ret; +} + +/* + * Write application data to the client + */ +EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len) +{ + int n = out_len, nw, i, tot = 0; + + /* maximum size of a TLS packet is around 16kB, so fragment */ + do + { + nw = n; + + if (nw > RT_MAX_PLAIN_LENGTH) /* fragment if necessary */ + nw = RT_MAX_PLAIN_LENGTH; + + if ((i = send_packet(ssl, PT_APP_PROTOCOL_DATA, + &out_data[tot], nw)) <= 0) + { + out_len = i; /* an error */ + break; + } + + tot += i; + n -= i; + } while (n > 0); + + return out_len; +} + +/** + * Add a certificate to the certificate chain. + */ +int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len) +{ + int ret = SSL_ERROR_NO_CERT_DEFINED, i = 0; + SSL_CERT *ssl_cert; + X509_CTX *cert = NULL; + int offset; + + while (i < CONFIG_SSL_MAX_CERTS && ssl_ctx->certs[i].buf) + i++; + + if (i == CONFIG_SSL_MAX_CERTS) /* too many certs */ + { +#ifdef CONFIG_SSL_DIAGNOSTICS + printf("Error: maximum number of certs added (%d) - change of " + "compile-time configuration required\n", + CONFIG_SSL_MAX_CERTS); +#endif + goto error; + } + + if ((ret = x509_new(buf, &offset, &cert))) + goto error; + +#if defined (CONFIG_SSL_FULL_MODE) + if (ssl_ctx->options & SSL_DISPLAY_CERTS) + x509_print(cert, NULL); +#endif + + ssl_cert = &ssl_ctx->certs[i]; + ssl_cert->size = len; + ssl_cert->buf = (uint8_t *)malloc(len); + + switch (cert->sig_type) + { + case SIG_TYPE_SHA1: + ssl_cert->hash_alg = SIG_ALG_SHA1; + break; + + case SIG_TYPE_SHA256: + ssl_cert->hash_alg = SIG_ALG_SHA256; + break; + + case SIG_TYPE_SHA384: + ssl_cert->hash_alg = SIG_ALG_SHA384; + break; + + case SIG_TYPE_SHA512: + ssl_cert->hash_alg = SIG_ALG_SHA512; + break; + } + + memcpy(ssl_cert->buf, buf, len); + ssl_ctx->chain_length++; + len -= offset; + ret = SSL_OK; /* ok so far */ + + /* recurse? */ + if (len > 0) + { + ret = add_cert(ssl_ctx, &buf[offset], len); + } + +error: + x509_free(cert); /* don't need anymore */ + return ret; +} + +#ifdef CONFIG_SSL_CERT_VERIFICATION +/** + * Add a certificate authority. + */ +int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len) +{ + int ret = X509_OK; /* ignore errors for now */ + int i = 0; + CA_CERT_CTX *ca_cert_ctx; + + if (ssl_ctx->ca_cert_ctx == NULL) + ssl_ctx->ca_cert_ctx = (CA_CERT_CTX *)calloc(1, sizeof(CA_CERT_CTX)); + + ca_cert_ctx = ssl_ctx->ca_cert_ctx; + + while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) + i++; + + while (len > 0) + { + int offset; + if (i >= CONFIG_X509_MAX_CA_CERTS) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: maximum number of CA certs added (%d) - change of " + "compile-time configuration required\n", + CONFIG_X509_MAX_CA_CERTS); +#endif + ret = X509_MAX_CERTS; + break; + } + + /* ignore the return code */ + if (x509_new(buf, &offset, &ca_cert_ctx->cert[i]) == X509_OK) + { +#if defined (CONFIG_SSL_FULL_MODE) + if (ssl_ctx->options & SSL_DISPLAY_CERTS) + x509_print(ca_cert_ctx->cert[i], NULL); +#endif + } + + i++; + len -= offset; + } + + return ret; +} + +/* + * Retrieve an X.509 distinguished name component + */ +EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component) +{ + if (ssl->x509_ctx == NULL) + return NULL; + + switch (component) + { + case SSL_X509_CERT_COMMON_NAME: + return ssl->x509_ctx->cert_dn[X509_COMMON_NAME]; + + case SSL_X509_CERT_ORGANIZATION: + return ssl->x509_ctx->cert_dn[X509_ORGANIZATION]; + + case SSL_X509_CERT_ORGANIZATIONAL_NAME: + return ssl->x509_ctx->cert_dn[X509_ORGANIZATIONAL_UNIT]; + + case SSL_X509_CERT_LOCATION: + return ssl->x509_ctx->cert_dn[X509_LOCATION]; + + case SSL_X509_CERT_COUNTRY: + return ssl->x509_ctx->cert_dn[X509_COUNTRY]; + + case SSL_X509_CERT_STATE: + return ssl->x509_ctx->cert_dn[X509_STATE]; + + case SSL_X509_CA_CERT_COMMON_NAME: + return ssl->x509_ctx->ca_cert_dn[X509_COMMON_NAME]; + + case SSL_X509_CA_CERT_ORGANIZATION: + return ssl->x509_ctx->ca_cert_dn[X509_ORGANIZATION]; + + case SSL_X509_CA_CERT_ORGANIZATIONAL_NAME: + return ssl->x509_ctx->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]; + + case SSL_X509_CA_CERT_LOCATION: + return ssl->x509_ctx->ca_cert_dn[X509_LOCATION]; + + case SSL_X509_CA_CERT_COUNTRY: + return ssl->x509_ctx->ca_cert_dn[X509_COUNTRY]; + + case SSL_X509_CA_CERT_STATE: + return ssl->x509_ctx->ca_cert_dn[X509_STATE]; + + default: + return NULL; + } +} + +/* + * Retrieve a "Subject Alternative Name" from a v3 certificate + */ +EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, + int dnsindex) +{ + int i; + + if (ssl->x509_ctx == NULL || ssl->x509_ctx->subject_alt_dnsnames == NULL) + return NULL; + + for (i = 0; i < dnsindex; ++i) + { + if (ssl->x509_ctx->subject_alt_dnsnames[i] == NULL) + return NULL; + } + + return ssl->x509_ctx->subject_alt_dnsnames[dnsindex]; +} + +#endif /* CONFIG_SSL_CERT_VERIFICATION */ + +/* + * Find an ssl object based on the client's file descriptor. + */ +EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, long client_fd) +{ + SSL *ssl; + + SSL_CTX_LOCK(ssl_ctx->mutex); + ssl = ssl_ctx->head; + + /* search through all the ssl entries */ + while (ssl) + { + if (ssl->client_fd == client_fd) + { + SSL_CTX_UNLOCK(ssl_ctx->mutex); + return ssl; + } + + ssl = ssl->next; + } + + SSL_CTX_UNLOCK(ssl_ctx->mutex); + return NULL; +} + +/* + * Force the client to perform its handshake again. + */ +EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl) +{ + int ret = SSL_OK; + + disposable_new(ssl); +#ifdef CONFIG_SSL_ENABLE_CLIENT + if (IS_SET_SSL_FLAG(SSL_IS_CLIENT)) + { + ret = do_client_connect(ssl); + } + else +#endif + { + send_packet(ssl, PT_HANDSHAKE_PROTOCOL, + g_hello_request, sizeof(g_hello_request)); + SET_SSL_FLAG(SSL_NEED_RECORD); + } + + return ret; +} + +/** + * @brief Get what we need for key info. + * @param cipher [in] The cipher information we are after + * @param key_size [out] The key size for the cipher + * @param iv_size [out] The iv size for the cipher + * @return The amount of key information we need. + */ +static const cipher_info_t *get_cipher_info(uint8_t cipher) +{ + int i; + + for (i = 0; i < NUM_PROTOCOLS; i++) + { + if (cipher_info[i].cipher == cipher) + { + return &cipher_info[i]; + } + } + + return NULL; /* error */ +} + +/* + * Get a new ssl context for a new connection. + */ +SSL *ssl_new(SSL_CTX *ssl_ctx, long client_fd) +{ + SSL *ssl = (SSL *)calloc(1, sizeof(SSL)); + ssl->ssl_ctx = ssl_ctx; + ssl->need_bytes = SSL_RECORD_SIZE; /* need a record */ + ssl->client_fd = client_fd; + ssl->flag = SSL_NEED_RECORD; + ssl->bm_data = ssl->bm_all_data+BM_RECORD_OFFSET; /* space at the start */ + ssl->hs_status = SSL_NOT_OK; /* not connected */ +#ifdef CONFIG_ENABLE_VERIFICATION + ssl->ca_cert_ctx = ssl_ctx->ca_cert_ctx; +#endif + disposable_new(ssl); + + /* a bit hacky but saves a few bytes of memory */ + ssl->flag |= ssl_ctx->options; + SSL_CTX_LOCK(ssl_ctx->mutex); + + if (ssl_ctx->head == NULL) + { + ssl_ctx->head = ssl; + ssl_ctx->tail = ssl; + } + else + { + ssl->prev = ssl_ctx->tail; + ssl_ctx->tail->next = ssl; + ssl_ctx->tail = ssl; + } + + SSL_CTX_UNLOCK(ssl_ctx->mutex); + return ssl; +} + +/* + * Add a private key to a context. + */ +int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj) +{ + int ret = SSL_OK; + + /* get the private key details */ + if (asn1_get_private_key(ssl_obj->buf, ssl_obj->len, &ssl_ctx->rsa_ctx)) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + +error: + return ret; +} + +/** + * Increment the read sequence number (as a 64 bit endian indepenent #) + */ +static void increment_read_sequence(SSL *ssl) +{ + int i; + + for (i = 7; i >= 0; i--) + { + if (++ssl->read_sequence[i]) + break; + } +} + +/** + * Increment the read sequence number (as a 64 bit endian indepenent #) + */ +static void increment_write_sequence(SSL *ssl) +{ + int i; + + for (i = 7; i >= 0; i--) + { + if (++ssl->write_sequence[i]) + break; + } +} + +/** + * Work out the HMAC digest in a packet. + */ +static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header, + const uint8_t *buf, int buf_len, uint8_t *hmac_buf) +{ + int hmac_len = buf_len + 8 + SSL_RECORD_SIZE; + uint8_t *t_buf = (uint8_t *)alloca(hmac_len); + + memcpy(t_buf, (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE) ? + ssl->write_sequence : ssl->read_sequence, 8); + memcpy(&t_buf[8], hmac_header, SSL_RECORD_SIZE); + memcpy(&t_buf[8+SSL_RECORD_SIZE], buf, buf_len); + + ssl->cipher_info->hmac(t_buf, hmac_len, + (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ? + ssl->server_mac : ssl->client_mac, + ssl->cipher_info->digest_size, hmac_buf); + +#if 0 + print_blob("record", hmac_header, SSL_RECORD_SIZE); + print_blob("buf", buf, buf_len); + if (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE) + { + print_blob("write seq", ssl->write_sequence, 8); + } + else + { + print_blob("read seq", ssl->read_sequence, 8); + } + + if (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) + { + print_blob("server mac", + ssl->server_mac, ssl->cipher_info->digest_size); + } + else + { + print_blob("client mac", + ssl->client_mac, ssl->cipher_info->digest_size); + } + print_blob("hmac", hmac_buf, ssl->cipher_info->digest_size); +#endif +} + +/** + * Verify that the digest of a packet is correct. + */ +static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len) +{ + uint8_t hmac_buf[SHA256_SIZE]; // size of largest digest + int hmac_offset; + + int last_blk_size = buf[read_len-1], i; + hmac_offset = read_len-last_blk_size-ssl->cipher_info->digest_size-1; + + /* guard against a timing attack - make sure we do the digest */ + if (hmac_offset < 0) + { + hmac_offset = 0; + } + else + { + /* already looked at last byte */ + for (i = 1; i < last_blk_size; i++) + { + if (buf[read_len-i] != last_blk_size) + { + hmac_offset = 0; + break; + } + } + } + + /* sanity check the offset */ + ssl->hmac_header[3] = hmac_offset >> 8; /* insert size */ + ssl->hmac_header[4] = hmac_offset & 0xff; + add_hmac_digest(ssl, mode, ssl->hmac_header, buf, hmac_offset, hmac_buf); + + if (memcmp(hmac_buf, &buf[hmac_offset], ssl->cipher_info->digest_size)) + { + return SSL_ERROR_INVALID_HMAC; + } + + return hmac_offset; +} + +/** + * Add a packet to the end of our sent and received packets, so that we may use + * it to calculate the hash at the end. + */ +void add_packet(SSL *ssl, const uint8_t *pkt, int len) +{ + // TLS1.2+ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2 || ssl->version == 0) + { + SHA256_Update(&ssl->dc->sha256_ctx, pkt, len); + } + + if (ssl->version < SSL_PROTOCOL_VERSION_TLS1_2 || + ssl->next_state == HS_SERVER_HELLO || + ssl->next_state == 0) + { + MD5_Update(&ssl->dc->md5_ctx, pkt, len); + SHA1_Update(&ssl->dc->sha1_ctx, pkt, len); + } +} + +/** + * Work out the MD5 PRF. + */ +static void p_hash_md5(const uint8_t *sec, int sec_len, + uint8_t *seed, int seed_len, uint8_t *out, int olen) +{ + uint8_t a1[MD5_SIZE+77]; + + /* A(1) */ + ssl_hmac_md5(seed, seed_len, sec, sec_len, a1); + memcpy(&a1[MD5_SIZE], seed, seed_len); + ssl_hmac_md5(a1, MD5_SIZE+seed_len, sec, sec_len, out); + + while (olen > MD5_SIZE) + { + uint8_t a2[MD5_SIZE]; + out += MD5_SIZE; + olen -= MD5_SIZE; + + /* A(N) */ + ssl_hmac_md5(a1, MD5_SIZE, sec, sec_len, a2); + memcpy(a1, a2, MD5_SIZE); + + /* work out the actual hash */ + ssl_hmac_md5(a1, MD5_SIZE+seed_len, sec, sec_len, out); + } +} + +/** + * Work out the SHA1 PRF. + */ +static void p_hash_sha1(const uint8_t *sec, int sec_len, + uint8_t *seed, int seed_len, uint8_t *out, int olen) +{ + uint8_t a1[SHA1_SIZE+77]; + + /* A(1) */ + ssl_hmac_sha1(seed, seed_len, sec, sec_len, a1); + memcpy(&a1[SHA1_SIZE], seed, seed_len); + ssl_hmac_sha1(a1, SHA1_SIZE+seed_len, sec, sec_len, out); + + while (olen > SHA1_SIZE) + { + uint8_t a2[SHA1_SIZE]; + out += SHA1_SIZE; + olen -= SHA1_SIZE; + + /* A(N) */ + ssl_hmac_sha1(a1, SHA1_SIZE, sec, sec_len, a2); + memcpy(a1, a2, SHA1_SIZE); + + /* work out the actual hash */ + ssl_hmac_sha1(a1, SHA1_SIZE+seed_len, sec, sec_len, out); + } +} + +/** + * Work out the SHA256 PRF. + */ +static void p_hash_sha256(const uint8_t *sec, int sec_len, + uint8_t *seed, int seed_len, uint8_t *out, int olen) +{ + uint8_t a1[SHA256_SIZE+77]; + + /* A(1) */ + hmac_sha256(seed, seed_len, sec, sec_len, a1); + memcpy(&a1[SHA256_SIZE], seed, seed_len); + hmac_sha256(a1, SHA256_SIZE+seed_len, sec, sec_len, out); + + while (olen > SHA256_SIZE) + { + uint8_t a2[SHA256_SIZE]; + out += SHA256_SIZE; + olen -= SHA256_SIZE; + + // A(N) + hmac_sha256(a1, SHA256_SIZE, sec, sec_len, a2); + memcpy(a1, a2, SHA256_SIZE); + + // work out the actual hash + hmac_sha256(a1, SHA256_SIZE+seed_len, sec, sec_len, out); + } +} + +/** + * Work out the PRF. + */ +static void prf(SSL *ssl, const uint8_t *sec, int sec_len, + uint8_t *seed, int seed_len, + uint8_t *out, int olen) +{ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + p_hash_sha256(sec, sec_len, seed, seed_len, out, olen); + } + else // TLS1.0/1.1 + { + int len, i; + const uint8_t *S1, *S2; + uint8_t xbuf[2*(SHA256_SIZE+32+16) + MD5_SIZE]; /* max keyblock */ + uint8_t ybuf[2*(SHA256_SIZE+32+16) + SHA1_SIZE]; /* max keyblock */ + + len = sec_len/2; + S1 = sec; + S2 = &sec[len]; + len += (sec_len & 1); /* add for odd, make longer */ + + p_hash_md5(S1, len, seed, seed_len, xbuf, olen); + p_hash_sha1(S2, len, seed, seed_len, ybuf, olen); + + for (i = 0; i < olen; i++) + out[i] = xbuf[i] ^ ybuf[i]; + } +} + +/** + * Generate a master secret based on the client/server random data and the + * premaster secret. + */ +void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret) +{ + uint8_t buf[77]; +//print_blob("premaster secret", premaster_secret, 48); + strcpy((char *)buf, "master secret"); + memcpy(&buf[13], ssl->dc->client_random, SSL_RANDOM_SIZE); + memcpy(&buf[45], ssl->dc->server_random, SSL_RANDOM_SIZE); + prf(ssl, premaster_secret, SSL_SECRET_SIZE, buf, 77, ssl->dc->master_secret, + SSL_SECRET_SIZE); +#if 0 + print_blob("client random", ssl->dc->client_random, 32); + print_blob("server random", ssl->dc->server_random, 32); + print_blob("master secret", ssl->dc->master_secret, 48); +#endif +} + +/** + * Generate a 'random' blob of data used for the generation of keys. + */ +static void generate_key_block(SSL *ssl, + uint8_t *client_random, uint8_t *server_random, + uint8_t *master_secret, uint8_t *key_block, int key_block_size) +{ + uint8_t buf[77]; + strcpy((char *)buf, "key expansion"); + memcpy(&buf[13], server_random, SSL_RANDOM_SIZE); + memcpy(&buf[45], client_random, SSL_RANDOM_SIZE); + prf(ssl, master_secret, SSL_SECRET_SIZE, buf, 77, + key_block, key_block_size); +} + +/** + * Calculate the digest used in the finished message. This function also + * doubles up as a certificate verify function. + */ +int finished_digest(SSL *ssl, const char *label, uint8_t *digest) +{ + uint8_t mac_buf[SHA1_SIZE+MD5_SIZE+15]; + uint8_t *q = mac_buf; + int dgst_len; + + if (label) + { + strcpy((char *)q, label); + q += strlen(label); + } + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + SHA256_CTX sha256_ctx = ssl->dc->sha256_ctx; // interim copy + SHA256_Final(q, &sha256_ctx); + q += SHA256_SIZE; + dgst_len = (int)(q-mac_buf); + } + else // TLS1.0/1.1 + { + MD5_CTX md5_ctx = ssl->dc->md5_ctx; // interim copy + SHA1_CTX sha1_ctx = ssl->dc->sha1_ctx; + + MD5_Final(q, &md5_ctx); + q += MD5_SIZE; + + SHA1_Final(q, &sha1_ctx); + q += SHA1_SIZE; + dgst_len = (int)(q-mac_buf); + } + + if (label) + { + prf(ssl, ssl->dc->master_secret, SSL_SECRET_SIZE, + mac_buf, dgst_len, digest, SSL_FINISHED_HASH_SIZE); + } + else /* for use in a certificate verify */ + { + memcpy(digest, mac_buf, dgst_len); + } + +#if 0 + printf("label: %s\n", label); + print_blob("mac_buf", mac_buf, dgst_len); + print_blob("finished digest", digest, SSL_FINISHED_HASH_SIZE); +#endif + + return dgst_len; +} + +/** + * Retrieve (and initialise) the context of a cipher. + */ +static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt) +{ + switch (ssl->cipher) + { + case SSL_AES128_SHA: + case SSL_AES128_SHA256: + { + AES_CTX *aes_ctx = (AES_CTX *)malloc(sizeof(AES_CTX)); + AES_set_key(aes_ctx, key, iv, AES_MODE_128); + + if (is_decrypt) + { + AES_convert_key(aes_ctx); + } + + return (void *)aes_ctx; + } + + case SSL_AES256_SHA: + case SSL_AES256_SHA256: + { + AES_CTX *aes_ctx = (AES_CTX *)malloc(sizeof(AES_CTX)); + AES_set_key(aes_ctx, key, iv, AES_MODE_256); + + if (is_decrypt) + { + AES_convert_key(aes_ctx); + } + + return (void *)aes_ctx; + } + + } + + return NULL; /* its all gone wrong */ +} + +/** + * Send a packet over the socket. + */ +static int send_raw_packet(SSL *ssl, uint8_t protocol) +{ + uint8_t *rec_buf = ssl->bm_all_data; + int pkt_size = SSL_RECORD_SIZE+ssl->bm_index; + int sent = 0; + int ret = SSL_OK; + + rec_buf[0] = protocol; + rec_buf[1] = 0x03; /* version = 3.1 or higher */ + rec_buf[2] = ssl->version & 0x0f; + rec_buf[3] = ssl->bm_index >> 8; + rec_buf[4] = ssl->bm_index & 0xff; + + DISPLAY_BYTES(ssl, "sending %d bytes", ssl->bm_all_data, + pkt_size, pkt_size); + + while (sent < pkt_size) + { + ret = SOCKET_WRITE(ssl->client_fd, + &ssl->bm_all_data[sent], pkt_size-sent); + + if (ret >= 0) + sent += ret; + else + { + +#ifdef WIN32 + if (GetLastError() != WSAEWOULDBLOCK) +#else + if (SOCKET_ERRNO() != EAGAIN && SOCKET_ERRNO() != EWOULDBLOCK) +#endif + return SSL_ERROR_CONN_LOST; + } + +#ifdef PORT_USE_SELECT + // TODO: This should be factored into SOCKET_WAIT_WRITABLE(), + // with semantic being waiting until socket can be written + // regardless whether it is in blocking or non-blocking mode. + /* keep going until the write buffer has some space */ + if (sent != pkt_size) + { + fd_set wfds; + FD_ZERO(&wfds); + FD_SET(ssl->client_fd, &wfds); + + /* block and wait for it */ + if (select(ssl->client_fd + 1, NULL, &wfds, NULL, NULL) < 0) + return SSL_ERROR_CONN_LOST; + } +#endif + } + + ssl->bm_index = 0; + + if (protocol != PT_APP_PROTOCOL_DATA) + { + /* always return SSL_OK during handshake */ + ret = SSL_OK; + } + + return ret; +} + +/** + * Send an encrypted packet with padding bytes if necessary. + */ +int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length) +{ + int ret, msg_length = 0; + + /* if our state is bad, don't bother */ + if (ssl->hs_status == SSL_ERROR_DEAD) + return SSL_ERROR_CONN_LOST; + + if (IS_SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY)) + return SSL_CLOSE_NOTIFY; + + if (in) /* has the buffer already been initialised? */ + { + memcpy(ssl->bm_data, in, length); + } + + msg_length += length; + + if (IS_SET_SSL_FLAG(SSL_TX_ENCRYPTED)) + { + int mode = IS_SET_SSL_FLAG(SSL_IS_CLIENT) ? + SSL_CLIENT_WRITE : SSL_SERVER_WRITE; + uint8_t hmac_header[SSL_RECORD_SIZE] = + { + protocol, + 0x03, /* version = 3.1 or higher */ + ssl->version & 0x0f, + msg_length >> 8, + msg_length & 0xff + }; + + if (protocol == PT_HANDSHAKE_PROTOCOL) + { + DISPLAY_STATE(ssl, 1, ssl->bm_data[0], 0); + + if (ssl->bm_data[0] != HS_HELLO_REQUEST) + { + add_packet(ssl, ssl->bm_data, msg_length); + } + } + + /* add the packet digest */ + add_hmac_digest(ssl, mode, hmac_header, ssl->bm_data, msg_length, + &ssl->bm_data[msg_length]); + msg_length += ssl->cipher_info->digest_size; + + /* add padding */ + { + int last_blk_size = msg_length%ssl->cipher_info->padding_size; + int pad_bytes = ssl->cipher_info->padding_size - last_blk_size; + + /* ensure we always have at least 1 padding byte */ + if (pad_bytes == 0) + pad_bytes += ssl->cipher_info->padding_size; + + memset(&ssl->bm_data[msg_length], pad_bytes-1, pad_bytes); + msg_length += pad_bytes; + } + + DISPLAY_BYTES(ssl, "unencrypted write", ssl->bm_data, msg_length); + increment_write_sequence(ssl); + + /* add the explicit IV for TLS1.1 */ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_1) + { + uint8_t iv_size = ssl->cipher_info->iv_size; + memmove(ssl->bm_data + iv_size, ssl->bm_data, msg_length); + if (get_random(iv_size, ssl->bm_data) < 0) + return SSL_NOT_OK; + + msg_length += iv_size; + } + + /* now encrypt the packet */ + ssl->cipher_info->encrypt(ssl->encrypt_ctx, ssl->bm_data, + ssl->bm_data, msg_length); + } + else if (protocol == PT_HANDSHAKE_PROTOCOL) + { + DISPLAY_STATE(ssl, 1, ssl->bm_data[0], 0); + + if (ssl->bm_data[0] != HS_HELLO_REQUEST) + { + add_packet(ssl, ssl->bm_data, length); + } + } + + ssl->bm_index = msg_length; + if ((ret = send_raw_packet(ssl, protocol)) <= 0) + return ret; + + return length; /* just return what we wanted to send */ +} + +/** + * Work out the cipher keys we are going to use for this session based on the + * master secret. + */ +static int set_key_block(SSL *ssl, int is_write) +{ + const cipher_info_t *ciph_info = get_cipher_info(ssl->cipher); + uint8_t *q; + uint8_t client_key[32], server_key[32]; /* big enough for AES256 */ + uint8_t client_iv[16], server_iv[16]; /* big enough for AES128/256 */ + int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT); + + if (ciph_info == NULL) + return -1; + + /* only do once in a handshake */ + if (!ssl->dc->key_block_generated) + { + generate_key_block(ssl, ssl->dc->client_random, ssl->dc->server_random, + ssl->dc->master_secret, ssl->dc->key_block, + ciph_info->key_block_size); +#if 0 + print_blob("master", ssl->dc->master_secret, SSL_SECRET_SIZE); + print_blob("keyblock", ssl->dc->key_block, ciph_info->key_block_size); + print_blob("client random", ssl->dc->client_random, 32); + print_blob("server random", ssl->dc->server_random, 32); +#endif + ssl->dc->key_block_generated = 1; + } + + q = ssl->dc->key_block; + + if ((is_client && is_write) || (!is_client && !is_write)) + { + memcpy(ssl->client_mac, q, ciph_info->digest_size); + } + + q += ciph_info->digest_size; + + if ((!is_client && is_write) || (is_client && !is_write)) + { + memcpy(ssl->server_mac, q, ciph_info->digest_size); + } + + q += ciph_info->digest_size; + memcpy(client_key, q, ciph_info->key_size); + q += ciph_info->key_size; + memcpy(server_key, q, ciph_info->key_size); + q += ciph_info->key_size; + + memcpy(client_iv, q, ciph_info->iv_size); + q += ciph_info->iv_size; + memcpy(server_iv, q, ciph_info->iv_size); + q += ciph_info->iv_size; +#if 0 + print_blob("client key", client_key, ciph_info->key_size); + print_blob("server key", server_key, ciph_info->key_size); + print_blob("client iv", client_iv, ciph_info->iv_size); + print_blob("server iv", server_iv, ciph_info->iv_size); +#endif + + free(is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx); + + /* now initialise the ciphers */ + if (is_client) + { + finished_digest(ssl, server_finished, ssl->dc->final_finish_mac); + + if (is_write) + ssl->encrypt_ctx = crypt_new(ssl, client_key, client_iv, 0); + else + ssl->decrypt_ctx = crypt_new(ssl, server_key, server_iv, 1); + } + else + { + finished_digest(ssl, client_finished, ssl->dc->final_finish_mac); + + if (is_write) + ssl->encrypt_ctx = crypt_new(ssl, server_key, server_iv, 0); + else + ssl->decrypt_ctx = crypt_new(ssl, client_key, client_iv, 1); + } + + ssl->cipher_info = ciph_info; + return 0; +} + +/** + * Read the SSL connection. + */ +int basic_read(SSL *ssl, uint8_t **in_data) +{ + int ret = SSL_OK; + int read_len, is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT); + uint8_t *buf = ssl->bm_data; + + if (IS_SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY)) + return SSL_CLOSE_NOTIFY; + + read_len = SOCKET_READ(ssl->client_fd, &buf[ssl->bm_read_index], + ssl->need_bytes-ssl->got_bytes); + + if (read_len < 0) + { +#ifdef WIN32 + if (GetLastError() == WSAEWOULDBLOCK) +#else + if (SOCKET_ERRNO() == EAGAIN || SOCKET_ERRNO() == EWOULDBLOCK) +#endif + return SSL_EAGAIN; + } + + /* connection has gone, so die */ + if (read_len <= 0) + { + ret = SSL_ERROR_CONN_LOST; + ssl->hs_status = SSL_ERROR_DEAD; /* make sure it stays dead */ + goto error; + } + + DISPLAY_BYTES(ssl, "received %d bytes", + &ssl->bm_data[ssl->bm_read_index], read_len, read_len); + + ssl->got_bytes += read_len; + ssl->bm_read_index += read_len; + + /* haven't quite got what we want, so try again later */ + if (ssl->got_bytes < ssl->need_bytes) + return SSL_OK; + + read_len = ssl->got_bytes; + ssl->got_bytes = 0; + + if (IS_SET_SSL_FLAG(SSL_NEED_RECORD)) + { + /* check for sslv2 "client hello" */ + if ((buf[0] & 0x80) && buf[2] == 1) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: no SSLv23 handshaking allowed\n"); +#endif + ret = SSL_ERROR_NOT_SUPPORTED; + goto error; /* not an error - just get out of here */ + } + + ssl->need_bytes = (buf[3] << 8) + buf[4]; + + /* do we violate the spec with the message size? */ + if (ssl->need_bytes > RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET) + { + printf("TLS buffer overflow, record size: %u (+5)\n", ssl->need_bytes); + ssl->need_bytes = SSL_RECORD_SIZE; + ret = SSL_ERROR_RECORD_OVERFLOW; + goto error; + } + + CLR_SSL_FLAG(SSL_NEED_RECORD); + memcpy(ssl->hmac_header, buf, 3); /* store for hmac */ + ssl->record_type = buf[0]; + goto error; /* no error, we're done */ + } + + /* for next time - just do it now in case of an error */ + SET_SSL_FLAG(SSL_NEED_RECORD); + ssl->need_bytes = SSL_RECORD_SIZE; + + /* decrypt if we need to */ + if (IS_SET_SSL_FLAG(SSL_RX_ENCRYPTED)) + { + ssl->cipher_info->decrypt(ssl->decrypt_ctx, buf, buf, read_len); + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_1) + { + buf += ssl->cipher_info->iv_size; + read_len -= ssl->cipher_info->iv_size; + } + + read_len = verify_digest(ssl, + is_client ? SSL_CLIENT_READ : SSL_SERVER_READ, buf, read_len); + + /* does the hmac work? */ + if (read_len < 0) + { + ret = read_len; + goto error; + } + + DISPLAY_BYTES(ssl, "decrypted", buf, read_len); + increment_read_sequence(ssl); + } + + /* The main part of the SSL packet */ + switch (ssl->record_type) + { + case PT_HANDSHAKE_PROTOCOL: + if (ssl->dc != NULL) + { + ssl->dc->bm_proc_index = 0; + ret = do_handshake(ssl, buf, read_len); + } + else /* no client renegotiation allowed */ + { + ret = SSL_ERROR_NO_CLIENT_RENOG; + goto error; + } + break; + + case PT_CHANGE_CIPHER_SPEC: + if (ssl->next_state != HS_FINISHED) + { + ret = SSL_ERROR_INVALID_HANDSHAKE; + goto error; + } + + if (set_key_block(ssl, 0) < 0) + { + ret = SSL_ERROR_INVALID_HANDSHAKE; + goto error; + } + + /* all encrypted from now on */ + SET_SSL_FLAG(SSL_RX_ENCRYPTED); + memset(ssl->read_sequence, 0, 8); + break; + + case PT_APP_PROTOCOL_DATA: + if (in_data && ssl->hs_status == SSL_OK) + { + *in_data = buf; /* point to the work buffer */ + (*in_data)[read_len] = 0; /* null terminate just in case */ + ret = read_len; + } + else + ret = SSL_ERROR_INVALID_PROT_MSG; + break; + + case PT_ALERT_PROTOCOL: + /* return the alert # with alert bit set */ + if (buf[0] == SSL_ALERT_TYPE_WARNING && + buf[1] == SSL_ALERT_CLOSE_NOTIFY) + { + ret = SSL_CLOSE_NOTIFY; + send_alert(ssl, SSL_ALERT_CLOSE_NOTIFY); + SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY); + } + else + { + ret = -buf[1]; + DISPLAY_ALERT(ssl, buf[1]); + } + + break; + + default: + ret = SSL_ERROR_INVALID_PROT_MSG; + break; + } + +error: + ssl->bm_read_index = 0; /* reset to go again */ + + if (ret < SSL_OK && in_data)/* if all wrong, then clear this buffer ptr */ + *in_data = NULL; + + return ret; +} + +/** + * Do some basic checking of data and then perform the appropriate handshaking. + */ +static int do_handshake(SSL *ssl, uint8_t *buf, int read_len) +{ + int hs_len = (buf[2]<<8) + buf[3]; + uint8_t handshake_type = buf[0]; + int ret = SSL_OK; + int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT); + + /* some integrity checking on the handshake */ + PARANOIA_CHECK(read_len-SSL_HS_HDR_SIZE, hs_len); + + if (handshake_type != ssl->next_state) + { + /* handle a special case on the client */ + if (!is_client || handshake_type != HS_CERT_REQ || + ssl->next_state != HS_SERVER_HELLO_DONE) + { + ret = SSL_ERROR_INVALID_HANDSHAKE; + goto error; + } + } + + hs_len += SSL_HS_HDR_SIZE; /* adjust for when adding packets */ + ssl->bm_index = hs_len; /* store the size and check later */ + DISPLAY_STATE(ssl, 0, handshake_type, 0); + + if (handshake_type != HS_CERT_VERIFY && handshake_type != HS_HELLO_REQUEST) + add_packet(ssl, buf, hs_len); + +#if defined(CONFIG_SSL_ENABLE_CLIENT) && defined(CONFIG_SSL_ENABLE_SERVER) + ret = is_client ? + do_clnt_handshake(ssl, handshake_type, buf, hs_len) : + do_svr_handshake(ssl, handshake_type, buf, hs_len); +#elif defined(CONFIG_SSL_ENABLE_CLIENT) + ret = do_clnt_handshake(ssl, handshake_type, buf, hs_len); +#else + ret = do_svr_handshake(ssl, handshake_type, buf, hs_len); +#endif + + /* just use recursion to get the rest */ + if (hs_len < read_len && ret == SSL_OK) + ret = do_handshake(ssl, &buf[hs_len], read_len-hs_len); + +error: + return ret; +} + +/** + * Sends the change cipher spec message. We have just read a finished message + * from the client. + */ +int send_change_cipher_spec(SSL *ssl) +{ + int ret = send_packet(ssl, PT_CHANGE_CIPHER_SPEC, + g_chg_cipher_spec_pkt, sizeof(g_chg_cipher_spec_pkt)); + + if (ret >= 0 && set_key_block(ssl, 1) < 0) + ret = SSL_ERROR_INVALID_HANDSHAKE; + + if (ssl->cipher_info) + SET_SSL_FLAG(SSL_TX_ENCRYPTED); + + memset(ssl->write_sequence, 0, 8); + return ret; +} + +/** + * Send a "finished" message + */ +int send_finished(SSL *ssl) +{ + uint8_t buf[SHA1_SIZE+MD5_SIZE+15+4] = { + HS_FINISHED, 0, 0, SSL_FINISHED_HASH_SIZE }; + + /* now add the finished digest mac (12 bytes) */ + finished_digest(ssl, + IS_SET_SSL_FLAG(SSL_IS_CLIENT) ? + client_finished : server_finished, &buf[4]); + +#ifndef CONFIG_SSL_SKELETON_MODE + /* store in the session cache */ + if (!IS_SET_SSL_FLAG(SSL_SESSION_RESUME) && ssl->ssl_ctx->num_sessions) + { + memcpy(ssl->session->master_secret, + ssl->dc->master_secret, SSL_SECRET_SIZE); + } +#endif + + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, + buf, SSL_FINISHED_HASH_SIZE+4); +} + +/** + * Send an alert message. + * Return 1 if the alert was an "error". + */ +int send_alert(SSL *ssl, int error_code) +{ + int alert_num = 0; + int is_warning = 0; + uint8_t buf[2]; + + /* Don't bother, we're already dead */ + if (ssl->hs_status == SSL_ERROR_DEAD) + { + return SSL_ERROR_CONN_LOST; + } + +#ifdef CONFIG_SSL_DIAGNOSTICS + if (IS_SET_SSL_FLAG(SSL_DISPLAY_STATES)) + ssl_display_error(error_code); +#endif + + switch (error_code) + { + case SSL_ALERT_CLOSE_NOTIFY: + is_warning = 1; + alert_num = SSL_ALERT_CLOSE_NOTIFY; + break; + + case SSL_ERROR_CONN_LOST: /* don't send alert just yet */ + is_warning = 1; + break; + + case SSL_ERROR_NO_CIPHER: + alert_num = SSL_ALERT_HANDSHAKE_FAILURE; + break; + + case SSL_ERROR_INVALID_HMAC: + alert_num = SSL_ALERT_BAD_RECORD_MAC; + break; + + case SSL_ERROR_FINISHED_INVALID: + case SSL_ERROR_INVALID_KEY: + alert_num = SSL_ALERT_DECRYPT_ERROR; + break; + + case SSL_ERROR_INVALID_VERSION: + alert_num = SSL_ALERT_INVALID_VERSION; + break; + + case SSL_ERROR_INVALID_SESSION: + alert_num = SSL_ALERT_ILLEGAL_PARAMETER; + break; + + case SSL_ERROR_NO_CLIENT_RENOG: + alert_num = SSL_ALERT_NO_RENEGOTIATION; + break; + + case SSL_ERROR_RECORD_OVERFLOW: + alert_num = SSL_ALERT_RECORD_OVERFLOW; + break; + + case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED): + case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID): + alert_num = SSL_ALERT_CERTIFICATE_EXPIRED; + break; + + case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT): + alert_num = SSL_ALERT_UNKNOWN_CA; + break; + + case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST): + case SSL_ERROR_INVALID_CERT_HASH_ALG: + alert_num = SSL_ALERT_UNSUPPORTED_CERTIFICATE; + break; + + case SSL_ERROR_BAD_CERTIFICATE: + case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE): + alert_num = SSL_ALERT_BAD_CERTIFICATE; + break; + + case SSL_ERROR_INVALID_HANDSHAKE: + case SSL_ERROR_INVALID_PROT_MSG: + default: + /* a catch-all for anything bad */ + alert_num = (error_code <= SSL_X509_OFFSET) ? + SSL_ALERT_CERTIFICATE_UNKNOWN: SSL_ALERT_UNEXPECTED_MESSAGE; + break; + } + + buf[0] = is_warning ? 1 : 2; + buf[1] = alert_num; + send_packet(ssl, PT_ALERT_PROTOCOL, buf, sizeof(buf)); + DISPLAY_ALERT(ssl, alert_num); + return is_warning ? 0 : 1; +} + +/** + * Process a client finished message. + */ +int process_finished(SSL *ssl, uint8_t *buf, int hs_len) +{ + int ret = SSL_OK; + int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT); + int resume = IS_SET_SSL_FLAG(SSL_SESSION_RESUME); + + PARANOIA_CHECK(ssl->bm_index, SSL_FINISHED_HASH_SIZE+4); + + /* check that we all work before we continue */ + if (memcmp(ssl->dc->final_finish_mac, &buf[4], SSL_FINISHED_HASH_SIZE)) + return SSL_ERROR_FINISHED_INVALID; + + if ((!is_client && !resume) || (is_client && resume)) + { + if ((ret = send_change_cipher_spec(ssl)) == SSL_OK) + ret = send_finished(ssl); + } + + /* if we ever renegotiate */ + ssl->next_state = is_client ? HS_HELLO_REQUEST : HS_CLIENT_HELLO; + ssl->hs_status = ret; /* set the final handshake status */ + +error: + return ret; +} + +/** + * Send a certificate. + */ +int send_certificate(SSL *ssl) +{ + int ret = SSL_OK; + int i = 0; + uint8_t *buf = ssl->bm_data; + int offset = 7; + int chain_length; + + buf[0] = HS_CERTIFICATE; + buf[1] = 0; + buf[4] = 0; + + /* spec says we must check if the hash/sig algorithm is OK */ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2 && + ((ret = check_certificate_chain(ssl)) != SSL_OK)) + { + ret = SSL_ERROR_INVALID_CERT_HASH_ALG; + goto error; + } + + while (i < ssl->ssl_ctx->chain_length) + { + SSL_CERT *cert = &ssl->ssl_ctx->certs[i]; + buf[offset++] = 0; + buf[offset++] = cert->size >> 8; /* cert 1 length */ + buf[offset++] = cert->size & 0xff; + memcpy(&buf[offset], cert->buf, cert->size); + offset += cert->size; + i++; + } + + chain_length = offset - 7; + buf[5] = chain_length >> 8; /* cert chain length */ + buf[6] = chain_length & 0xff; + chain_length += 3; + buf[2] = chain_length >> 8; /* handshake length */ + buf[3] = chain_length & 0xff; + ssl->bm_index = offset; + ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); + +error: + return ret; +} + +/** + * Create a blob of memory that we'll get rid of once the handshake is + * complete. + */ +void disposable_new(SSL *ssl) +{ + if (ssl->dc == NULL) + { + ssl->dc = (DISPOSABLE_CTX *)calloc(1, sizeof(DISPOSABLE_CTX)); + SHA256_Init(&ssl->dc->sha256_ctx); + MD5_Init(&ssl->dc->md5_ctx); + SHA1_Init(&ssl->dc->sha1_ctx); + } +} + +/** + * Remove the temporary blob of memory. + */ +void disposable_free(SSL *ssl) +{ + if (ssl->dc) + { + memset(ssl->dc, 0, sizeof(DISPOSABLE_CTX)); + free(ssl->dc); + ssl->dc = NULL; + } + +} + +#ifndef CONFIG_SSL_SKELETON_MODE /* no session resumption in this mode */ +/** + * Find if an existing session has the same session id. If so, use the + * master secret from this session for session resumption. + */ +SSL_SESSION *ssl_session_update(int max_sessions, SSL_SESSION *ssl_sessions[], + SSL *ssl, const uint8_t *session_id) +{ + time_t tm = time(NULL); + time_t oldest_sess_time = tm; + SSL_SESSION *oldest_sess = NULL; + int i; + + /* no sessions? Then bail */ + if (max_sessions == 0) + return NULL; + + SSL_CTX_LOCK(ssl->ssl_ctx->mutex); + if (session_id) + { + for (i = 0; i < max_sessions; i++) + { + if (ssl_sessions[i]) + { + /* kill off any expired sessions (including those in + the future) */ + if ((tm > ssl_sessions[i]->conn_time + SSL_EXPIRY_TIME) || + (tm < ssl_sessions[i]->conn_time)) + { + session_free(ssl_sessions, i); + continue; + } + + /* if the session id matches, it must still be less than + the expiry time */ + if (memcmp(ssl_sessions[i]->session_id, session_id, + SSL_SESSION_ID_SIZE) == 0) + { + ssl->session_index = i; + memcpy(ssl->dc->master_secret, + ssl_sessions[i]->master_secret, SSL_SECRET_SIZE); + SET_SSL_FLAG(SSL_SESSION_RESUME); + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); + return ssl_sessions[i]; /* a session was found */ + } + } + } + } + + /* If we've got here, no matching session was found - so create one */ + for (i = 0; i < max_sessions; i++) + { + if (ssl_sessions[i] == NULL) + { + /* perfect, this will do */ + ssl_sessions[i] = (SSL_SESSION *)calloc(1, sizeof(SSL_SESSION)); + ssl_sessions[i]->conn_time = tm; + ssl->session_index = i; + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); + return ssl_sessions[i]; /* return the session object */ + } + else if (ssl_sessions[i]->conn_time <= oldest_sess_time) + { + /* find the oldest session */ + oldest_sess_time = ssl_sessions[i]->conn_time; + oldest_sess = ssl_sessions[i]; + ssl->session_index = i; + } + } + + /* ok, we've used up all of our sessions. So blow the oldest session away */ + oldest_sess->conn_time = tm; + memset(oldest_sess->session_id, 0, SSL_SESSION_ID_SIZE); + memset(oldest_sess->master_secret, 0, SSL_SECRET_SIZE); + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); + return oldest_sess; +} + +/** + * Free an existing session. + */ +static void session_free(SSL_SESSION *ssl_sessions[], int sess_index) +{ + if (ssl_sessions[sess_index]) + { + free(ssl_sessions[sess_index]); + ssl_sessions[sess_index] = NULL; + } +} + +/** + * This ssl object doesn't want this session anymore. + */ +void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl) +{ + SSL_CTX_LOCK(ssl->ssl_ctx->mutex); + + if (ssl->ssl_ctx->num_sessions) + { + session_free(ssl_sessions, ssl->session_index); + ssl->session = NULL; + } + + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); +} +#endif /* CONFIG_SSL_SKELETON_MODE */ + +/* + * Get the session id for a handshake. This will be a 32 byte sequence. + */ +EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl) +{ + return ssl->session_id; +} + +/* + * Get the session id size for a handshake. + */ +EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl) +{ + return ssl->sess_id_size; +} + +/* + * Return the cipher id (in the SSL form). + */ +EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl) +{ + return ssl->cipher; +} + +/* + * Return the status of the handshake. + */ +EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl) +{ + return ssl->hs_status; +} + +/* + * Retrieve various parameters about the SSL engine. + */ +EXP_FUNC int STDCALL ssl_get_config(int offset) +{ + switch (offset) + { + /* return the appropriate build mode */ + case SSL_BUILD_MODE: +#if defined(CONFIG_SSL_FULL_MODE) + return SSL_BUILD_FULL_MODE; +#elif defined(CONFIG_SSL_ENABLE_CLIENT) + return SSL_BUILD_ENABLE_CLIENT; +#elif defined(CONFIG_ENABLE_VERIFICATION) + return SSL_BUILD_ENABLE_VERIFICATION; +#elif defined(CONFIG_SSL_SERVER_ONLY ) + return SSL_BUILD_SERVER_ONLY; +#else + return SSL_BUILD_SKELETON_MODE; +#endif + + case SSL_MAX_CERT_CFG_OFFSET: + return CONFIG_SSL_MAX_CERTS; + +#ifdef CONFIG_SSL_CERT_VERIFICATION + case SSL_MAX_CA_CERT_CFG_OFFSET: + return CONFIG_X509_MAX_CA_CERTS; +#endif +#ifdef CONFIG_SSL_HAS_PEM + case SSL_HAS_PEM: + return 1; +#endif + default: + return 0; + } +} + +/** + * Check the certificate chain to see if the certs are supported + */ +static int check_certificate_chain(SSL *ssl) +{ + int i = 0; + int ret = SSL_OK; + + while (i < ssl->ssl_ctx->chain_length) + { + int j = 0; + uint8_t found = 0; + SSL_CERT *cert = &ssl->ssl_ctx->certs[i]; + + while (j < ssl->num_sig_algs) + { + if (ssl->sig_algs[j++] == cert->hash_alg) + { + found = 1; + break; + } + } + + if (!found) + { + + ret = SSL_ERROR_INVALID_CERT_HASH_ALG; + goto error; + } + + i++; + } + +error: + return ret; +} + +#ifdef CONFIG_SSL_CERT_VERIFICATION +/** + * Authenticate a received certificate. + */ +EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl) +{ + int ret; + int pathLenConstraint = 0; + + SSL_CTX_LOCK(ssl->ssl_ctx->mutex); + ret = x509_verify(ssl->ssl_ctx->ca_cert_ctx, ssl->x509_ctx, + &pathLenConstraint); + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); + + if (ret) /* modify into an SSL error type */ + { + ret = SSL_X509_ERROR(ret); + } + + return ret; +} +#endif /* CONFIG_SSL_CERT_VERIFICATION */ + +/** + * Process a certificate message. + */ +int process_certificate(SSL *ssl, X509_CTX **x509_ctx) +{ + int ret = SSL_OK; + uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; + int pkt_size = ssl->bm_index; + int cert_size, offset = 5, offset_start; + int total_cert_len = (buf[offset]<<8) + buf[offset+1]; + int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT); + X509_CTX *chain = 0; + X509_CTX **certs = 0; + int *cert_used = 0; + int num_certs = 0; + int i = 0; + offset += 2; + + PARANOIA_CHECK(pkt_size, total_cert_len + offset); + + // record the start point for the second pass + offset_start = offset; + + // first pass - count the certificates + while (offset < total_cert_len) + { + offset++; /* skip empty char */ + cert_size = (buf[offset]<<8) + buf[offset+1]; + offset += 2; + offset += cert_size; + num_certs++; + } + + PARANOIA_CHECK(pkt_size, offset); + + certs = (X509_CTX**) calloc(num_certs, sizeof(void*)); + cert_used = (int*) calloc(num_certs, sizeof(int)); + num_certs = 0; + + // restore the offset from the saved value + offset = offset_start; + + // second pass - load the certificates + while (offset < total_cert_len) + { + offset++; /* skip empty char */ + cert_size = (buf[offset]<<8) + buf[offset+1]; + offset += 2; + + if (x509_new(&buf[offset], NULL, certs+num_certs)) + { + ret = SSL_ERROR_BAD_CERTIFICATE; + goto error; + } + +#if defined (CONFIG_SSL_FULL_MODE) + if (ssl->ssl_ctx->options & SSL_DISPLAY_CERTS) + x509_print(certs[num_certs], NULL); +#endif + num_certs++; + offset += cert_size; + } + + PARANOIA_CHECK(pkt_size, offset); + + // third pass - link certs together, assume server cert is the first + *x509_ctx = certs[0]; + chain = certs[0]; + cert_used[0] = 1; + +#ifndef CONFIG_SSL_SKELETON_MODE + // repeat until the end of the chain is found + while (1) + { + // look for CA cert + for( i = 1; i < num_certs; i++ ) + { + if (certs[i] == chain) + continue; + + if (cert_used[i]) + continue; // don't allow loops + + if (asn1_compare_dn(chain->ca_cert_dn, certs[i]->cert_dn) == 0) + { + // CA cert found, add it to the chain + cert_used[i] = 1; + chain->next = certs[i]; + chain = certs[i]; + break; + } + } + + // no CA cert found, reached the end of the chain + if (i >= num_certs) + break; + } + + // clean up any certs that aren't part of the chain + for (i = 1; i < num_certs; i++) + { + if (cert_used[i] == 0) + x509_free(certs[i]); + } + + /* if we are client we can do the verify now or later */ + if (is_client && !IS_SET_SSL_FLAG(SSL_SERVER_VERIFY_LATER)) + { + ret = ssl_verify_cert(ssl); + } +#endif + + ssl->next_state = is_client ? HS_SERVER_HELLO_DONE : HS_CLIENT_KEY_XCHG; + ssl->dc->bm_proc_index += offset; +error: + // clean up arrays + if (certs) + free(certs); + + if (cert_used) + free(cert_used); + + return ret; +} + +//#endif /* CONFIG_SSL_CERT_VERIFICATION */ + +/** + * Debugging routine to display SSL handshaking stuff. + */ +#ifdef CONFIG_SSL_DIAGNOSTICS +/** + * Debugging routine to display SSL states. + */ +void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok) +{ + const char *str; + + if (!IS_SET_SSL_FLAG(SSL_DISPLAY_STATES)) + return; + + printf(not_ok ? "Error - invalid State:\t" : "State:\t"); + printf(is_send ? "sending " : "receiving "); + + switch (state) + { + case HS_HELLO_REQUEST: + str = "Hello Request (0)"; + break; + + case HS_CLIENT_HELLO: + str = "Client Hello (1)"; + break; + + case HS_SERVER_HELLO: + str = "Server Hello (2)"; + break; + + case HS_CERTIFICATE: + str = "Certificate (11)"; + break; + + case HS_SERVER_KEY_XCHG: + str = "Certificate Request (12)"; + break; + + case HS_CERT_REQ: + str = "Certificate Request (13)"; + break; + + case HS_SERVER_HELLO_DONE: + str = "Server Hello Done (14)"; + break; + + case HS_CERT_VERIFY: + str = "Certificate Verify (15)"; + break; + + case HS_CLIENT_KEY_XCHG: + str = "Client Key Exchange (16)"; + break; + + case HS_FINISHED: + str = "Finished (16)"; + break; + + default: + str = "Error (Unknown)"; + + break; + } + + printf("%s\n", str); +} + +/** + * Debugging routine to display RSA objects + */ +void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx) +{ +#ifdef CONFIG_SSL_FULL_MODE + if (!IS_SET_SSL_FLAG(SSL_DISPLAY_RSA)) + return; + + RSA_print(rsa_ctx); + TTY_FLUSH(); +#endif +} + +/** + * Debugging routine to display SSL handshaking bytes. + */ +void DISPLAY_BYTES(SSL *ssl, const char *format, + const uint8_t *data, int size, ...) +{ + va_list(ap); + + if (!IS_SET_SSL_FLAG(SSL_DISPLAY_BYTES)) + return; + + va_start(ap, size); + print_blob(format, data, size, va_arg(ap, char *)); + va_end(ap); + TTY_FLUSH(); +} + +/** + * Debugging routine to display SSL handshaking errors. + */ +EXP_FUNC void STDCALL ssl_display_error(int error_code) +{ + if (error_code == SSL_OK) + return; + + printf("Error: "); + + /* X509 error? */ + if (error_code < SSL_X509_OFFSET) + { + printf("%s\n", x509_display_error(error_code - SSL_X509_OFFSET)); + return; + } + + /* SSL alert error code */ + if (error_code > SSL_ERROR_CONN_LOST) + { + printf("SSL error %d\n", -error_code); + return; + } + + switch (error_code) + { + case SSL_ERROR_DEAD: + printf("connection dead"); + break; + + case SSL_ERROR_RECORD_OVERFLOW: + printf("record overflow"); + break; + + case SSL_ERROR_INVALID_HANDSHAKE: + printf("invalid handshake"); + break; + + case SSL_ERROR_INVALID_PROT_MSG: + printf("invalid protocol message"); + break; + + case SSL_ERROR_INVALID_HMAC: + printf("invalid mac"); + break; + + case SSL_ERROR_INVALID_VERSION: + printf("invalid version"); + break; + + case SSL_ERROR_INVALID_SESSION: + printf("invalid session"); + break; + + case SSL_ERROR_NO_CIPHER: + printf("no cipher"); + break; + + case SSL_ERROR_INVALID_CERT_HASH_ALG: + printf("invalid cert hash algorithm"); + break; + + case SSL_ERROR_CONN_LOST: + printf("connection lost"); + break; + + case SSL_ERROR_BAD_CERTIFICATE: + printf("bad certificate"); + break; + + case SSL_ERROR_INVALID_KEY: + printf("invalid key"); + break; + + case SSL_ERROR_FINISHED_INVALID: + printf("finished invalid"); + break; + + case SSL_ERROR_NO_CERT_DEFINED: + printf("no certificate defined"); + break; + + case SSL_ERROR_NO_CLIENT_RENOG: + printf("client renegotiation not supported"); + break; + + case SSL_ERROR_NOT_SUPPORTED: + printf("Option not supported"); + break; + + default: + printf("undefined as yet - %d", error_code); + break; + } + + printf("\n"); +} + +/** + * Debugging routine to display alerts. + */ + +/** + * Debugging routine to display alerts. + */ +void DISPLAY_ALERT(SSL *ssl, int alert) +{ + if (!IS_SET_SSL_FLAG(SSL_DISPLAY_STATES)) + return; + + printf("Alert: "); + + switch (alert) + { + case SSL_ALERT_CLOSE_NOTIFY: + printf("close notify"); + break; + + case SSL_ALERT_UNEXPECTED_MESSAGE: + printf("unexpected message"); + break; + + case SSL_ALERT_BAD_RECORD_MAC: + printf("bad record mac"); + break; + + case SSL_ALERT_RECORD_OVERFLOW: + printf("record overlow"); + break; + + case SSL_ALERT_HANDSHAKE_FAILURE: + printf("handshake failure"); + break; + + case SSL_ALERT_BAD_CERTIFICATE: + printf("bad certificate"); + break; + + case SSL_ALERT_UNSUPPORTED_CERTIFICATE: + printf("unsupported certificate"); + break; + + case SSL_ALERT_CERTIFICATE_EXPIRED: + printf("certificate expired"); + break; + + case SSL_ALERT_CERTIFICATE_UNKNOWN: + printf("certificate unknown"); + break; + + case SSL_ALERT_ILLEGAL_PARAMETER: + printf("illegal parameter"); + break; + + case SSL_ALERT_UNKNOWN_CA: + printf("unknown ca"); + break; + + case SSL_ALERT_DECODE_ERROR: + printf("decode error"); + break; + + case SSL_ALERT_DECRYPT_ERROR: + printf("decrypt error"); + break; + + case SSL_ALERT_INVALID_VERSION: + printf("invalid version"); + break; + + case SSL_ALERT_NO_RENEGOTIATION: + printf("no renegotiation"); + break; + + default: + printf("alert - (unknown %d)", alert); + break; + } + + printf("\n"); +} + +#endif /* CONFIG_SSL_FULL_MODE */ + +/** + * Return the version of this library. + */ +EXP_FUNC const char * STDCALL ssl_version() +{ + static const char * axtls_version = AXTLS_VERSION; + return axtls_version; +} + +/** + * Enable the various language bindings to work regardless of the + * configuration - they just return an error statement and a bad return code. + */ +#if !defined(CONFIG_SSL_DIAGNOSTICS) +EXP_FUNC void STDCALL ssl_display_error(int error_code) {} +#endif + +#ifdef CONFIG_BINDINGS +#if !defined(CONFIG_SSL_ENABLE_CLIENT) +EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, long client_fd, + const uint8_t *session_id, uint8_t sess_id_size, + SSL_EXTENSIONS* ssl_ext) +{ + printf("%s", unsupported_str); + return NULL; +} +#endif + +#if !defined(CONFIG_SSL_CERT_VERIFICATION) +EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl) +{ + printf("%s", unsupported_str); + return -1; +} + + +EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component) +{ + printf("%s", unsupported_str); + return NULL; +} + +EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int index) +{ + printf("%s", unsupported_str); + return NULL; +} + +#endif /* CONFIG_SSL_CERT_VERIFICATION */ + +#endif /* CONFIG_BINDINGS */ + diff --git a/circuitpython/lib/axtls/ssl/tls1.h b/circuitpython/lib/axtls/ssl/tls1.h new file mode 100755 index 0000000..e8ed8a7 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/tls1.h @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * @file tls1.h + * + * @brief The definitions for the TLS library. + */ +#ifndef HEADER_SSL_LIB_H +#define HEADER_SSL_LIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "version.h" +#include "config.h" +#include "os_int.h" +#include "os_port.h" +#include "crypto.h" +#include "crypto_misc.h" + +#define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */ +#define SSL_PROTOCOL_VERSION_MAX 0x33 /* TLS v1.3 */ +#define SSL_PROTOCOL_VERSION_TLS1_1 0x32 /* TLS v1.1 */ +#define SSL_PROTOCOL_VERSION_TLS1_2 0x33 /* TLS v1.2 */ +#define SSL_RANDOM_SIZE 32 +#define SSL_SECRET_SIZE 48 +#define SSL_FINISHED_HASH_SIZE 12 +#define SSL_RECORD_SIZE 5 +#define SSL_SERVER_READ 0 +#define SSL_SERVER_WRITE 1 +#define SSL_CLIENT_READ 2 +#define SSL_CLIENT_WRITE 3 +#define SSL_HS_HDR_SIZE 4 + +/* the flags we use while establishing a connection */ +#define SSL_NEED_RECORD 0x0001 +#define SSL_TX_ENCRYPTED 0x0002 +#define SSL_RX_ENCRYPTED 0x0004 +#define SSL_SESSION_RESUME 0x0008 +#define SSL_IS_CLIENT 0x0010 +#define SSL_HAS_CERT_REQ 0x0020 +#define SSL_SENT_CLOSE_NOTIFY 0x0040 + +/* some macros to muck around with flag bits */ +#define SET_SSL_FLAG(A) (ssl->flag |= A) +#define CLR_SSL_FLAG(A) (ssl->flag &= ~A) +#define IS_SET_SSL_FLAG(A) (ssl->flag & A) + +#define MAX_KEY_BYTE_SIZE 512 /* for a 4096 bit key */ +/* On send, will send another SSL fragment if plaintext exceeds RT_MAX_PLAIN_LENGTH */ +#ifndef RT_MAX_PLAIN_LENGTH +#define RT_MAX_PLAIN_LENGTH 16384 +#endif +/* Total receive buffer is RT_MAX_PLAIN_LENGTH + RT_EXTRA */ +#ifndef RT_EXTRA +#define RT_EXTRA 1024 +#endif +#define BM_RECORD_OFFSET 5 + +#define NUM_PROTOCOLS 4 + +#define MAX_SIG_ALGORITHMS 4 +#define SIG_ALG_SHA1 2 +#define SIG_ALG_SHA256 4 +#define SIG_ALG_SHA384 5 +#define SIG_ALG_SHA512 6 +#define SIG_ALG_RSA 1 + +#define PARANOIA_CHECK(A, B) if (A < B) { \ + ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; } + +/* protocol types */ +enum +{ + PT_CHANGE_CIPHER_SPEC = 20, + PT_ALERT_PROTOCOL, + PT_HANDSHAKE_PROTOCOL, + PT_APP_PROTOCOL_DATA +}; + +/* handshaking types */ +enum +{ + HS_HELLO_REQUEST, + HS_CLIENT_HELLO, + HS_SERVER_HELLO, + HS_CERTIFICATE = 11, + HS_SERVER_KEY_XCHG, + HS_CERT_REQ, + HS_SERVER_HELLO_DONE, + HS_CERT_VERIFY, + HS_CLIENT_KEY_XCHG, + HS_FINISHED = 20 +}; + +/* SSL extension types */ +enum +{ + SSL_EXT_SERVER_NAME = 0, + SSL_EXT_MAX_FRAGMENT_SIZE, + SSL_EXT_SIG_ALG = 0x0d, +}; + +typedef struct +{ + uint8_t cipher; + uint8_t key_size; + uint8_t iv_size; + uint8_t padding_size; + uint8_t digest_size; + uint8_t key_block_size; + hmac_func hmac; + crypt_func encrypt; + crypt_func decrypt; +} cipher_info_t; + +struct _SSLObjLoader +{ + uint8_t *buf; + int len; +}; + +typedef struct _SSLObjLoader SSLObjLoader; + +typedef struct +{ + time_t conn_time; + uint8_t session_id[SSL_SESSION_ID_SIZE]; + uint8_t master_secret[SSL_SECRET_SIZE]; +} SSL_SESSION; + +typedef struct +{ + uint8_t *buf; + int size; + uint8_t hash_alg; +} SSL_CERT; + +typedef struct +{ + MD5_CTX md5_ctx; + SHA1_CTX sha1_ctx; + SHA256_CTX sha256_ctx; + uint8_t client_random[SSL_RANDOM_SIZE]; /* client's random sequence */ + uint8_t server_random[SSL_RANDOM_SIZE]; /* server's random sequence */ + uint8_t final_finish_mac[128]; + uint8_t master_secret[SSL_SECRET_SIZE]; + uint8_t key_block[256]; + uint16_t bm_proc_index; + uint8_t key_block_generated; +} DISPOSABLE_CTX; + +typedef struct +{ + const char *host_name; /* Needed for the SNI support */ + /* Needed for the Max Fragment Size Extension. + Allowed values: 2^9, 2^10 .. 2^14 */ + uint16_t max_fragment_size; +} SSL_EXTENSIONS; + +struct _SSL +{ + uint32_t flag; + uint16_t need_bytes; + uint16_t got_bytes; + uint8_t record_type; + uint8_t cipher; + uint8_t sess_id_size; + uint8_t version; + uint8_t client_version; + int16_t next_state; + int16_t hs_status; + DISPOSABLE_CTX *dc; /* temporary data which we'll get rid of soon */ + long client_fd; + const cipher_info_t *cipher_info; + void *encrypt_ctx; + void *decrypt_ctx; + uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH+RT_EXTRA]; + uint8_t *bm_data; + uint16_t bm_index; + uint16_t bm_read_index; + uint8_t sig_algs[MAX_SIG_ALGORITHMS]; + uint8_t num_sig_algs; + struct _SSL *next; /* doubly linked list */ + struct _SSL *prev; + struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */ +#ifndef CONFIG_SSL_SKELETON_MODE + uint16_t session_index; + SSL_SESSION *session; +#endif +#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_ENABLE_CLIENT) + X509_CTX *x509_ctx; +#endif + + uint8_t session_id[SSL_SESSION_ID_SIZE]; + uint8_t client_mac[SHA256_SIZE]; /* for HMAC verification */ + uint8_t server_mac[SHA256_SIZE]; /* for HMAC verification */ + uint8_t read_sequence[8]; /* 64 bit sequence number */ + uint8_t write_sequence[8]; /* 64 bit sequence number */ + uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */ + SSL_EXTENSIONS *extensions; /* Contains the SSL (client) extensions */ +}; + +typedef struct _SSL SSL; + +struct _SSL_CTX +{ + uint32_t options; + uint8_t chain_length; + RSA_CTX *rsa_ctx; +#ifdef CONFIG_SSL_CERT_VERIFICATION + CA_CERT_CTX *ca_cert_ctx; +#endif + SSL *head; + SSL *tail; + SSL_CERT certs[CONFIG_SSL_MAX_CERTS]; +#ifndef CONFIG_SSL_SKELETON_MODE + uint16_t num_sessions; + SSL_SESSION **ssl_sessions; +#endif +#ifdef CONFIG_SSL_CTX_MUTEXING + SSL_CTX_MUTEX_TYPE mutex; +#endif +#ifdef CONFIG_OPENSSL_COMPATIBLE + void *bonus_attr; +#endif +}; + +typedef struct _SSL_CTX SSL_CTX; + +/* backwards compatibility */ +typedef struct _SSL_CTX SSLCTX; + +extern const uint8_t ssl_prot_prefs[NUM_PROTOCOLS]; + +SSL *ssl_new(SSL_CTX *ssl_ctx, long client_fd); +void disposable_new(SSL *ssl); +void disposable_free(SSL *ssl); +int send_packet(SSL *ssl, uint8_t protocol, + const uint8_t *in, int length); +int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len); +int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len); +int process_finished(SSL *ssl, uint8_t *buf, int hs_len); +int process_sslv23_client_hello(SSL *ssl); +int send_alert(SSL *ssl, int error_code); +int send_finished(SSL *ssl); +int send_certificate(SSL *ssl); +int basic_read(SSL *ssl, uint8_t **in_data); +int send_change_cipher_spec(SSL *ssl); +int finished_digest(SSL *ssl, const char *label, uint8_t *digest); +void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret); +void add_packet(SSL *ssl, const uint8_t *pkt, int len); +int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len); +int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj); +void ssl_obj_free(SSLObjLoader *ssl_obj); +int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password); +int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password); +int load_key_certs(SSL_CTX *ssl_ctx); +#ifdef CONFIG_SSL_CERT_VERIFICATION +int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len); +void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx); +#endif +#ifdef CONFIG_SSL_ENABLE_CLIENT +int do_client_connect(SSL *ssl); +#endif + +#ifdef CONFIG_SSL_DIAGNOSTICS +void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok); +void DISPLAY_BYTES(SSL *ssl, const char *format, + const uint8_t *data, int size, ...); +void DISPLAY_CERT(SSL *ssl, const X509_CTX *x509_ctx); +void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx); +void DISPLAY_ALERT(SSL *ssl, int alert); +#else +#define DISPLAY_STATE(A,B,C,D) +#define DISPLAY_CERT(A,B) +#define DISPLAY_RSA(A,B) +#define DISPLAY_ALERT(A, B) +#ifdef WIN32 +void DISPLAY_BYTES(SSL *ssl, const char *format,/* win32 has no variadic macros */ + const uint8_t *data, int size, ...); +#else +#define DISPLAY_BYTES(A,B,C,D,...) +#endif +#endif + +//#ifdef CONFIG_SSL_CERT_VERIFICATION +int process_certificate(SSL *ssl, X509_CTX **x509_ctx); +//#endif + +SSL_SESSION *ssl_session_update(int max_sessions, + SSL_SESSION *ssl_sessions[], SSL *ssl, + const uint8_t *session_id); +void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/axtls/ssl/tls1_clnt.c b/circuitpython/lib/axtls/ssl/tls1_clnt.c new file mode 100644 index 0000000..667825f --- /dev/null +++ b/circuitpython/lib/axtls/ssl/tls1_clnt.c @@ -0,0 +1,546 @@ +/* + * Copyright (c) 2007-2016, Cameron Rich + * + * 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 axTLS project 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 +#include +#include +#include +#include "os_port.h" +#include "ssl.h" + +#ifdef CONFIG_SSL_ENABLE_CLIENT /* all commented out if no client */ + +/* support sha512/384/256/1 RSA */ +static const uint8_t g_sig_alg[] = { + 0x00, SSL_EXT_SIG_ALG, + 0x00, 0x0a, 0x00, 0x08, + SIG_ALG_SHA512, SIG_ALG_RSA, + SIG_ALG_SHA384, SIG_ALG_RSA, + SIG_ALG_SHA256, SIG_ALG_RSA, + SIG_ALG_SHA1, SIG_ALG_RSA +}; + +static const uint8_t g_asn1_sha256[] = +{ + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +}; + +static int send_client_hello(SSL *ssl); +static int process_server_hello(SSL *ssl); +static int process_server_hello_done(SSL *ssl); +static int send_client_key_xchg(SSL *ssl); +static int process_cert_req(SSL *ssl); +static int send_cert_verify(SSL *ssl); + +/* + * Establish a new SSL connection to an SSL server. + */ +EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, long client_fd, const + uint8_t *session_id, uint8_t sess_id_size, SSL_EXTENSIONS* ssl_ext) +{ + SSL *ssl = ssl_new(ssl_ctx, client_fd); + ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */ + +#ifndef CONFIG_SSL_SKELETON_MODE + if (session_id && ssl_ctx->num_sessions) + { + if (sess_id_size > SSL_SESSION_ID_SIZE) /* validity check */ + { + ssl_free(ssl); + return NULL; + } + + memcpy(ssl->session_id, session_id, sess_id_size); + ssl->sess_id_size = sess_id_size; + SET_SSL_FLAG(SSL_SESSION_RESUME); /* just flag for later */ + } +#endif + + ssl->extensions = ssl_ext; + + SET_SSL_FLAG(SSL_IS_CLIENT); + do_client_connect(ssl); + return ssl; +} + +/* + * Process the handshake record. + */ +int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len) +{ + int ret; + + /* To get here the state must be valid */ + switch (handshake_type) + { + case HS_SERVER_HELLO: + ret = process_server_hello(ssl); + break; + + case HS_CERTIFICATE: + ret = process_certificate(ssl, &ssl->x509_ctx); + break; + + case HS_SERVER_HELLO_DONE: + if ((ret = process_server_hello_done(ssl)) == SSL_OK) + { + if (IS_SET_SSL_FLAG(SSL_HAS_CERT_REQ)) + { + if ((ret = send_certificate(ssl)) == SSL_OK && + (ret = send_client_key_xchg(ssl)) == SSL_OK) + { + send_cert_verify(ssl); + } + } + else + { + ret = send_client_key_xchg(ssl); + } + + if (ret == SSL_OK && + (ret = send_change_cipher_spec(ssl)) == SSL_OK) + { + ret = send_finished(ssl); + } + } + break; + + case HS_CERT_REQ: + ret = process_cert_req(ssl); + break; + + case HS_FINISHED: + ret = process_finished(ssl, buf, hs_len); + disposable_free(ssl); /* free up some memory */ + /* note: client renegotiation is not allowed after this */ + break; + + case HS_HELLO_REQUEST: + disposable_new(ssl); + ret = do_client_connect(ssl); + break; + + default: + ret = SSL_ERROR_INVALID_HANDSHAKE; + break; + } + + return ret; +} + +/* + * Do the handshaking from the beginning. + */ +int do_client_connect(SSL *ssl) +{ + int ret = SSL_OK; + + send_client_hello(ssl); /* send the client hello */ + ssl->bm_read_index = 0; + ssl->next_state = HS_SERVER_HELLO; + ssl->hs_status = SSL_NOT_OK; /* not connected */ + + /* sit in a loop until it all looks good */ + if (!IS_SET_SSL_FLAG(SSL_CONNECT_IN_PARTS)) + { + while (ssl->hs_status != SSL_OK) + { + ret = ssl_read(ssl, NULL); + + if (ret < SSL_OK) + break; + } + + ssl->hs_status = ret; /* connected? */ + } + + return ret; +} + +/* + * Send the initial client hello. + */ +static int send_client_hello(SSL *ssl) +{ + uint8_t *buf = ssl->bm_data; + time_t tm = time(NULL); + uint8_t *tm_ptr = &buf[6]; /* time will go here */ + int i, offset, ext_offset; + int ext_len = 0; + + + buf[0] = HS_CLIENT_HELLO; + buf[1] = 0; + buf[2] = 0; + /* byte 3 is calculated later */ + buf[4] = 0x03; + buf[5] = ssl->version & 0x0f; + + /* client random value - spec says that 1st 4 bytes are big endian time */ + *tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24); + *tm_ptr++ = (uint8_t)(((long)tm & 0x00ff0000) >> 16); + *tm_ptr++ = (uint8_t)(((long)tm & 0x0000ff00) >> 8); + *tm_ptr++ = (uint8_t)(((long)tm & 0x000000ff)); + if (get_random(SSL_RANDOM_SIZE-4, &buf[10]) < 0) + return SSL_NOT_OK; + + memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE); + offset = 6 + SSL_RANDOM_SIZE; + + /* give session resumption a go */ + if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) /* set initially by user */ + { + buf[offset++] = ssl->sess_id_size; + memcpy(&buf[offset], ssl->session_id, ssl->sess_id_size); + offset += ssl->sess_id_size; + CLR_SSL_FLAG(SSL_SESSION_RESUME); /* clear so we can set later */ + } + else + { + /* no session id - because no session resumption just yet */ + buf[offset++] = 0; + } + + buf[offset++] = 0; /* number of ciphers */ + buf[offset++] = NUM_PROTOCOLS*2;/* number of ciphers */ + + /* put all our supported protocols in our request */ + for (i = 0; i < NUM_PROTOCOLS; i++) + { + buf[offset++] = 0; /* cipher we are using */ + buf[offset++] = ssl_prot_prefs[i]; + } + + buf[offset++] = 1; /* no compression */ + buf[offset++] = 0; + + ext_offset = offset; + + buf[offset++] = 0; /* total length of extensions */ + buf[offset++] = 0; + + /* send the signature algorithm extension for TLS 1.2+ */ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) + { + memcpy(&buf[offset], g_sig_alg, sizeof(g_sig_alg)); + offset += sizeof(g_sig_alg); + ext_len += sizeof(g_sig_alg); + } + + if (ssl->extensions != NULL) + { + /* send the host name if specified */ + if (ssl->extensions->host_name != NULL) + { + size_t host_len = strlen(ssl->extensions->host_name); + buf[offset++] = 0; + buf[offset++] = SSL_EXT_SERVER_NAME; /* server_name(0) (65535) */ + buf[offset++] = 0; + buf[offset++] = host_len + 5; /* server_name length */ + buf[offset++] = 0; + buf[offset++] = host_len + 3; /* server_list length */ + buf[offset++] = 0; /* host_name(0) (255) */ + buf[offset++] = 0; + buf[offset++] = host_len; /* host_name length */ + strncpy((char*) &buf[offset], ssl->extensions->host_name, host_len); + offset += host_len; + ext_len += host_len + 9; + } + + if (ssl->extensions->max_fragment_size) + { + buf[offset++] = 0; + buf[offset++] = SSL_EXT_MAX_FRAGMENT_SIZE; + + buf[offset++] = 0; // size of data + buf[offset++] = 2; + + buf[offset++] = (uint8_t) + ((ssl->extensions->max_fragment_size >> 8) & 0xff); + buf[offset++] = (uint8_t) + (ssl->extensions->max_fragment_size & 0xff); + ext_len += 6; + } + } + + if (ext_len > 0) + { + // update the extensions length value + buf[ext_offset] = (uint8_t) ((ext_len >> 8) & 0xff); + buf[ext_offset + 1] = (uint8_t) (ext_len & 0xff); + } + + buf[3] = offset - 4; /* handshake size */ + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); +} + +/* + * Process the server hello. + */ +static int process_server_hello(SSL *ssl) +{ + uint8_t *buf = ssl->bm_data; + int pkt_size = ssl->bm_index; +#ifndef CONFIG_SSL_SKELETON_MODE + int num_sessions = ssl->ssl_ctx->num_sessions; +#endif + uint8_t sess_id_size; + int offset, ret = SSL_OK; + + /* check that we are talking to a TLSv1 server */ + uint8_t version = (buf[4] << 4) + buf[5]; + if (version > SSL_PROTOCOL_VERSION_MAX) + { + version = SSL_PROTOCOL_VERSION_MAX; + } + else if (ssl->version < SSL_PROTOCOL_MIN_VERSION) + { + ret = SSL_ERROR_INVALID_VERSION; +#ifdef CONFIG_SSL_DIAGNOSTICS + ssl_display_error(ret); +#endif + goto error; + } + + ssl->version = version; + + /* get the server random value */ + memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE); + offset = 6 + SSL_RANDOM_SIZE; /* skip of session id size */ + sess_id_size = buf[offset++]; + + if (sess_id_size > SSL_SESSION_ID_SIZE) + { + ret = SSL_ERROR_INVALID_SESSION; + goto error; + } + +#ifndef CONFIG_SSL_SKELETON_MODE + if (num_sessions) + { + ssl->session = ssl_session_update(num_sessions, + ssl->ssl_ctx->ssl_sessions, ssl, &buf[offset]); + memcpy(ssl->session->session_id, &buf[offset], sess_id_size); + + /* pad the rest with 0's */ + if (sess_id_size < SSL_SESSION_ID_SIZE) + { + memset(&ssl->session->session_id[sess_id_size], 0, + SSL_SESSION_ID_SIZE-sess_id_size); + } + } +#endif + + memcpy(ssl->session_id, &buf[offset], sess_id_size); + ssl->sess_id_size = sess_id_size; + offset += sess_id_size; + + /* get the real cipher we are using - ignore MSB */ + ssl->cipher = buf[++offset]; + ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ? + HS_FINISHED : HS_CERTIFICATE; + + offset += 2; // ignore compression + PARANOIA_CHECK(pkt_size, offset); + + ssl->dc->bm_proc_index = offset; + PARANOIA_CHECK(pkt_size, offset); + + // no extensions +error: + return ret; +} + +/** + * Process the server hello done message. + */ +static int process_server_hello_done(SSL *ssl) +{ + ssl->next_state = HS_FINISHED; + return SSL_OK; +} + +/* + * Send a client key exchange message. + */ +static int send_client_key_xchg(SSL *ssl) +{ + uint8_t *buf = ssl->bm_data; + uint8_t premaster_secret[SSL_SECRET_SIZE]; + int enc_secret_size = -1; + + buf[0] = HS_CLIENT_KEY_XCHG; + buf[1] = 0; + + // spec says client must use the what is initially negotiated - + // and this is our current version + premaster_secret[0] = 0x03; + premaster_secret[1] = SSL_PROTOCOL_VERSION_MAX & 0x0f; + if (get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]) < 0) + return SSL_NOT_OK; + + DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx); + + /* rsa_ctx->bi_ctx is not thread-safe */ + SSL_CTX_LOCK(ssl->ssl_ctx->mutex); + enc_secret_size = RSA_encrypt(ssl->x509_ctx->rsa_ctx, premaster_secret, + SSL_SECRET_SIZE, &buf[6], 0); + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); + + buf[2] = (enc_secret_size + 2) >> 8; + buf[3] = (enc_secret_size + 2) & 0xff; + buf[4] = enc_secret_size >> 8; + buf[5] = enc_secret_size & 0xff; + + generate_master_secret(ssl, premaster_secret); + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, enc_secret_size+6); +} + +/* + * Process the certificate request. + */ +static int process_cert_req(SSL *ssl) +{ + uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; + int ret = SSL_OK; + int cert_req_size = (buf[2]<<8) + buf[3]; + int offset = 4; + int pkt_size = ssl->bm_index; + uint8_t cert_type_len, sig_alg_len; + + PARANOIA_CHECK(pkt_size, offset + cert_req_size); + ssl->dc->bm_proc_index = cert_req_size; + + /* don't do any processing - we will send back an RSA certificate anyway */ + ssl->next_state = HS_SERVER_HELLO_DONE; + SET_SSL_FLAG(SSL_HAS_CERT_REQ); + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + // supported certificate types + cert_type_len = buf[offset++]; + PARANOIA_CHECK(pkt_size, offset + cert_type_len); + offset += cert_type_len; + + // supported signature algorithms + sig_alg_len = buf[offset++] << 8; + sig_alg_len += buf[offset++]; + PARANOIA_CHECK(pkt_size, offset + sig_alg_len); + + while (sig_alg_len > 0) + { + uint8_t hash_alg = buf[offset++]; + uint8_t sig_alg = buf[offset++]; + sig_alg_len -= 2; + + if (sig_alg == SIG_ALG_RSA && + (hash_alg == SIG_ALG_SHA1 || + hash_alg == SIG_ALG_SHA256 || + hash_alg == SIG_ALG_SHA384 || + hash_alg == SIG_ALG_SHA512)) + { + ssl->sig_algs[ssl->num_sig_algs++] = hash_alg; + } + } + } + +error: + return ret; +} + +/* + * Send a certificate verify message. + */ +static int send_cert_verify(SSL *ssl) +{ + uint8_t *buf = ssl->bm_data; + uint8_t dgst[SHA1_SIZE+MD5_SIZE+15]; + RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx; + int n = 0, ret; + int offset = 0; + int dgst_len; + + if (rsa_ctx == NULL) + return SSL_OK; + + DISPLAY_RSA(ssl, rsa_ctx); + + buf[0] = HS_CERT_VERIFY; + buf[1] = 0; + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + buf[4] = SIG_ALG_SHA256; + buf[5] = SIG_ALG_RSA; + offset = 6; + memcpy(dgst, g_asn1_sha256, sizeof(g_asn1_sha256)); + dgst_len = finished_digest(ssl, NULL, &dgst[sizeof(g_asn1_sha256)]) + + sizeof(g_asn1_sha256); + } + else + { + offset = 4; + dgst_len = finished_digest(ssl, NULL, dgst); + } + + /* rsa_ctx->bi_ctx is not thread-safe */ + if (rsa_ctx) + { + SSL_CTX_LOCK(ssl->ssl_ctx->mutex); + n = RSA_encrypt(rsa_ctx, dgst, dgst_len, &buf[offset + 2], 1); + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); + + if (n == 0) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + } + + buf[offset] = n >> 8; /* add the RSA size */ + buf[offset+1] = n & 0xff; + n += 2; + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + n += 2; // sig/alg + offset -= 2; + } + + buf[2] = n >> 8; + buf[3] = n & 0xff; + ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n + offset); + +error: + return ret; +} + +#endif /* CONFIG_SSL_ENABLE_CLIENT */ diff --git a/circuitpython/lib/axtls/ssl/tls1_svr.c b/circuitpython/lib/axtls/ssl/tls1_svr.c new file mode 100644 index 0000000..8f947ed --- /dev/null +++ b/circuitpython/lib/axtls/ssl/tls1_svr.c @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2007-2017, Cameron Rich + * + * 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 axTLS project 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 +#include +#include +#include "os_port.h" +#include "ssl.h" + +#ifdef CONFIG_SSL_ENABLE_SERVER + +static const uint8_t g_hello_done[] = { HS_SERVER_HELLO_DONE, 0, 0, 0 }; +static const uint8_t g_asn1_sha256[] = +{ + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +}; + +static int process_client_hello(SSL *ssl); +static int send_server_hello_sequence(SSL *ssl); +static int send_server_hello(SSL *ssl); +static int send_server_hello_done(SSL *ssl); +static int process_client_key_xchg(SSL *ssl); +#ifdef CONFIG_SSL_CERT_VERIFICATION +static int send_certificate_request(SSL *ssl); +static int process_cert_verify(SSL *ssl); +#endif + +/* + * Establish a new SSL connection to an SSL client. + */ +EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, long client_fd) +{ + SSL *ssl; + + ssl = ssl_new(ssl_ctx, client_fd); + ssl->next_state = HS_CLIENT_HELLO; + +#ifdef CONFIG_SSL_DIAGNOSTICS + if (ssl_ctx->chain_length == 0) + printf("Warning - no server certificate defined\n"); TTY_FLUSH(); +#endif + + return ssl; +} + +/* + * Process the handshake record. + */ +int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len) +{ + int ret = SSL_OK; + ssl->hs_status = SSL_NOT_OK; /* not connected */ + + /* To get here the state must be valid */ + switch (handshake_type) + { + case HS_CLIENT_HELLO: + if ((ret = process_client_hello(ssl)) == SSL_OK) + ret = send_server_hello_sequence(ssl); + break; + +#ifdef CONFIG_SSL_CERT_VERIFICATION + case HS_CERTIFICATE:/* the client sends its cert */ + ret = process_certificate(ssl, &ssl->x509_ctx); + + if (ret == SSL_OK) /* verify the cert */ + { + int cert_res; + int pathLenConstraint = 0; + + cert_res = x509_verify(ssl->ssl_ctx->ca_cert_ctx, + ssl->x509_ctx, &pathLenConstraint); + ret = (cert_res == 0) ? SSL_OK : SSL_X509_ERROR(cert_res); + } + break; + + case HS_CERT_VERIFY: + ret = process_cert_verify(ssl); + add_packet(ssl, buf, hs_len); /* needs to be done after */ + break; +#endif + case HS_CLIENT_KEY_XCHG: + ret = process_client_key_xchg(ssl); + break; + + case HS_FINISHED: + ret = process_finished(ssl, buf, hs_len); + disposable_free(ssl); /* free up some memory */ + break; + } + + return ret; +} + +/* + * Process a client hello message. + */ +static int process_client_hello(SSL *ssl) +{ + uint8_t *buf = ssl->bm_data; + int pkt_size = ssl->bm_index; + int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE; + int ret = SSL_OK; + + uint8_t version = (buf[4] << 4) + buf[5]; + ssl->version = ssl->client_version = version; + + if (version > SSL_PROTOCOL_VERSION_MAX) + { + /* use client's version instead */ + ssl->version = SSL_PROTOCOL_VERSION_MAX; + } + else if (version < SSL_PROTOCOL_MIN_VERSION) /* old version supported? */ + { + ret = SSL_ERROR_INVALID_VERSION; +#ifdef CONFIG_SSL_DIAGNOSTICS + ssl_display_error(ret); +#endif + goto error; + } + + memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE); + + /* process the session id */ + id_len = buf[offset++]; + if (id_len > SSL_SESSION_ID_SIZE) + { + return SSL_ERROR_INVALID_SESSION; + } + +#ifndef CONFIG_SSL_SKELETON_MODE + ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions, + ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL); +#endif + + offset += id_len; + cs_len = (buf[offset]<<8) + buf[offset+1]; + offset += 2; + + PARANOIA_CHECK(pkt_size, offset + cs_len); + + /* work out what cipher suite we are going to use - client defines + the preference */ + for (i = 0; i < cs_len; i += 2) + { + /* only support ciphersuites with the form (0x00, xxxx) */ + if (buf[offset+i]) + continue; + + for (j = 0; j < NUM_PROTOCOLS; j++) + { + if (ssl_prot_prefs[j] == buf[offset+i+1]) /* got a match? */ + { + ssl->cipher = ssl_prot_prefs[j]; + goto do_compression; + } + } + } + + /* ouch! protocol is not supported */ + return SSL_ERROR_NO_CIPHER; + + /* completely ignore compression */ +do_compression: + offset += cs_len; + id_len = buf[offset++]; + offset += id_len; + PARANOIA_CHECK(pkt_size, offset + id_len); + + if (offset == pkt_size) + { + /* no extensions */ + goto error; + } + + /* extension size */ + id_len = buf[offset++] << 8; + id_len += buf[offset++]; + PARANOIA_CHECK(pkt_size, offset + id_len); + + // Check for extensions from the client - only the signature algorithm + // is supported + while (offset < pkt_size) + { + int ext = buf[offset++] << 8; + ext += buf[offset++]; + int ext_len = buf[offset++] << 8; + ext_len += buf[offset++]; + PARANOIA_CHECK(pkt_size, offset + ext_len); + + if (ext == SSL_EXT_SIG_ALG) + { + while (ext_len > 0) + { + uint8_t hash_alg = buf[offset++]; + uint8_t sig_alg = buf[offset++]; + ext_len -= 2; + + if (sig_alg == SIG_ALG_RSA && + (hash_alg == SIG_ALG_SHA1 || + hash_alg == SIG_ALG_SHA256 || + hash_alg == SIG_ALG_SHA384 || + hash_alg == SIG_ALG_SHA512)) + { + ssl->sig_algs[ssl->num_sig_algs++] = hash_alg; + } + } + } + else + { + offset += ext_len; + } + } + + /* default is RSA/SHA1 */ + if (ssl->num_sig_algs == 0) + { + ssl->sig_algs[ssl->num_sig_algs++] = SIG_ALG_SHA1; + } + +error: + return ret; +} + +/* + * Send the entire server hello sequence + */ +#if CONFIG_SSL_ENABLE_SERVER +static int send_server_hello_sequence(SSL *ssl) +{ + int ret; + + if ((ret = send_server_hello(ssl)) == SSL_OK) + { +#ifndef CONFIG_SSL_SKELETON_MODE + /* resume handshake? */ + if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) + { + if ((ret = send_change_cipher_spec(ssl)) == SSL_OK) + { + ret = send_finished(ssl); + ssl->next_state = HS_FINISHED; + } + } + else +#endif + if ((ret = send_certificate(ssl)) == SSL_OK) + { +#ifdef CONFIG_SSL_CERT_VERIFICATION + /* ask the client for its certificate */ + if (IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION)) + { + if ((ret = send_certificate_request(ssl)) == SSL_OK) + { + ret = send_server_hello_done(ssl); + ssl->next_state = HS_CERTIFICATE; + } + } + else +#endif + { + ret = send_server_hello_done(ssl); + ssl->next_state = HS_CLIENT_KEY_XCHG; + } + } + } + + return ret; +} + +/* + * Send a server hello message. + */ +static int send_server_hello(SSL *ssl) +{ + uint8_t *buf = ssl->bm_data; + int offset = 0; + + buf[0] = HS_SERVER_HELLO; + buf[1] = 0; + buf[2] = 0; + /* byte 3 is calculated later */ + buf[4] = 0x03; + buf[5] = ssl->version & 0x0f; + + /* server random value */ + if (get_random(SSL_RANDOM_SIZE, &buf[6]) < 0) + return SSL_NOT_OK; + + memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE); + offset = 6 + SSL_RANDOM_SIZE; + +#ifndef CONFIG_SSL_SKELETON_MODE + if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) + { + /* retrieve id from session cache */ + buf[offset++] = SSL_SESSION_ID_SIZE; + memcpy(&buf[offset], ssl->session->session_id, SSL_SESSION_ID_SIZE); + memcpy(ssl->session_id, ssl->session->session_id, SSL_SESSION_ID_SIZE); + ssl->sess_id_size = SSL_SESSION_ID_SIZE; + offset += SSL_SESSION_ID_SIZE; + } + else /* generate our own session id */ +#endif + { +#ifndef CONFIG_SSL_SKELETON_MODE + buf[offset++] = SSL_SESSION_ID_SIZE; + get_random(SSL_SESSION_ID_SIZE, &buf[offset]); + memcpy(ssl->session_id, &buf[offset], SSL_SESSION_ID_SIZE); + ssl->sess_id_size = SSL_SESSION_ID_SIZE; + + /* store id in session cache */ + if (ssl->ssl_ctx->num_sessions) + { + memcpy(ssl->session->session_id, + ssl->session_id, SSL_SESSION_ID_SIZE); + } + + offset += SSL_SESSION_ID_SIZE; +#else + buf[offset++] = 0; /* don't bother with session id in skelton mode */ +#endif + } + + buf[offset++] = 0; /* cipher we are using */ + buf[offset++] = ssl->cipher; + buf[offset++] = 0; /* no compression and no extensions supported */ + buf[3] = offset - 4; /* handshake size */ + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); +} + +/* + * Send the server hello done message. + */ +static int send_server_hello_done(SSL *ssl) +{ + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, + g_hello_done, sizeof(g_hello_done)); +} +#endif + +/* + * Pull apart a client key exchange message. Decrypt the pre-master key (using + * our RSA private key) and then work out the master key. Initialise the + * ciphers. + */ +static int process_client_key_xchg(SSL *ssl) +{ + uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; + int pkt_size = ssl->bm_index; + int premaster_size, secret_length = (buf[2] << 8) + buf[3]; + uint8_t premaster_secret[MAX_KEY_BYTE_SIZE]; + RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx; + int offset = 4; + int ret = SSL_OK; + + if (rsa_ctx == NULL) + { + ret = SSL_ERROR_NO_CERT_DEFINED; + goto error; + } + + /* is there an extra size field? */ + if ((secret_length - 2) == rsa_ctx->num_octets) + offset += 2; + + PARANOIA_CHECK(pkt_size, rsa_ctx->num_octets+offset); + + /* rsa_ctx->bi_ctx is not thread-safe */ + SSL_CTX_LOCK(ssl->ssl_ctx->mutex); + premaster_size = RSA_decrypt(rsa_ctx, &buf[offset], premaster_secret, + sizeof(premaster_secret), 1); + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); + + if (premaster_size != SSL_SECRET_SIZE || + premaster_secret[0] != 0x03 || /* must be the same as client + offered version */ + premaster_secret[1] != (ssl->client_version & 0x0f)) + { + /* guard against a Bleichenbacher attack */ + if (get_random(SSL_SECRET_SIZE, premaster_secret) < 0) + return SSL_NOT_OK; + + /* and continue - will die eventually when checking the mac */ + } + + generate_master_secret(ssl, premaster_secret); + +#ifdef CONFIG_SSL_CERT_VERIFICATION + ssl->next_state = IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION) ? + HS_CERT_VERIFY : HS_FINISHED; +#else + ssl->next_state = HS_FINISHED; +#endif + + ssl->dc->bm_proc_index += rsa_ctx->num_octets+offset; +error: + return ret; +} + +#ifdef CONFIG_SSL_CERT_VERIFICATION +static const uint8_t g_cert_request[] = { HS_CERT_REQ, 0, + 0, 0x0e, + 1, 1, // rsa sign + 0x00, 0x08, + SIG_ALG_SHA256, SIG_ALG_RSA, + SIG_ALG_SHA512, SIG_ALG_RSA, + SIG_ALG_SHA384, SIG_ALG_RSA, + SIG_ALG_SHA1, SIG_ALG_RSA, + 0, 0 +}; + +static const uint8_t g_cert_request_v1[] = { HS_CERT_REQ, 0, 0, 4, 1, 0, 0, 0 }; + +/* + * Send the certificate request message. + */ +static int send_certificate_request(SSL *ssl) +{ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, + g_cert_request, sizeof(g_cert_request)); + } + else + { + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, + g_cert_request_v1, sizeof(g_cert_request_v1)); + } +} + +/* + * Ensure the client has the private key by first decrypting the packet and + * then checking the packet digests. + */ +static int process_cert_verify(SSL *ssl) +{ + uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; + int pkt_size = ssl->bm_index; + uint8_t dgst_buf[MAX_KEY_BYTE_SIZE]; + uint8_t dgst[MD5_SIZE + SHA1_SIZE]; + X509_CTX *x509_ctx = ssl->x509_ctx; + int ret = SSL_OK; + int offset = 6; + int rsa_len; + int n; + + DISPLAY_RSA(ssl, x509_ctx->rsa_ctx); + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + // TODO: should really need to be able to handle other algorihms. An + // assumption is made on RSA/SHA256 and appears to be OK. + //uint8_t hash_alg = buf[4]; + //uint8_t sig_alg = buf[5]; + offset = 8; + rsa_len = (buf[6] << 8) + buf[7]; + } + else + { + rsa_len = (buf[4] << 8) + buf[5]; + } + + PARANOIA_CHECK(pkt_size, offset + rsa_len); + + /* rsa_ctx->bi_ctx is not thread-safe */ + SSL_CTX_LOCK(ssl->ssl_ctx->mutex); + n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[offset], dgst_buf, + sizeof(dgst_buf), 0); + SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + if (memcmp(dgst_buf, g_asn1_sha256, sizeof(g_asn1_sha256))) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + + finished_digest(ssl, NULL, dgst); /* calculate the digest */ + if (memcmp(&dgst_buf[sizeof(g_asn1_sha256)], dgst, SHA256_SIZE)) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + } + else // TLS1.0/1.1 + { + if (n != SHA1_SIZE + MD5_SIZE) + { + ret = SSL_ERROR_INVALID_KEY; + goto end_cert_vfy; + } + + finished_digest(ssl, NULL, dgst); /* calculate the digest */ + if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE)) + { + ret = SSL_ERROR_INVALID_KEY; + } + } + +end_cert_vfy: + ssl->next_state = HS_FINISHED; +error: + return ret; +} + +#endif + +#endif diff --git a/circuitpython/lib/axtls/ssl/x509.c b/circuitpython/lib/axtls/ssl/x509.c new file mode 100644 index 0000000..b36f205 --- /dev/null +++ b/circuitpython/lib/axtls/ssl/x509.c @@ -0,0 +1,921 @@ +/* + * Copyright (c) 2007-2017, Cameron Rich + * + * 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 axTLS project 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. + */ + +/** + * @file x509.c + * + * Certificate processing. + */ + +#include +#include +#include +#include +#include "os_port.h" +#include "crypto_misc.h" + +#ifdef CONFIG_SSL_CERT_VERIFICATION +static int x509_v3_subject_alt_name(const uint8_t *cert, int offset, + X509_CTX *x509_ctx); +static int x509_v3_basic_constraints(const uint8_t *cert, int offset, + X509_CTX *x509_ctx); +static int x509_v3_key_usage(const uint8_t *cert, int offset, + X509_CTX *x509_ctx); +#endif + +/** + * Construct a new x509 object. + * @return 0 if ok. < 0 if there was a problem. + */ +int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) +{ + int begin_tbs, end_tbs; + int ret = X509_NOT_OK, offset = 0, cert_size = 0; + int version = 0; + X509_CTX *x509_ctx; +#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ + BI_CTX *bi_ctx; +#endif + + *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX)); + x509_ctx = *ctx; + + /* get the certificate size */ + asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE); + + if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0) + goto end_cert; + + begin_tbs = offset; /* start of the tbs */ + end_tbs = begin_tbs; /* work out the end of the tbs */ + asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE); + + if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0) + goto end_cert; + + /* optional version */ + if (cert[offset] == ASN1_EXPLICIT_TAG && + asn1_version(cert, &offset, &version) == X509_NOT_OK) + goto end_cert; + + if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */ + asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0) + goto end_cert; + + /* make sure the signature is ok */ + if (asn1_signature_type(cert, &offset, x509_ctx)) + { + ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST; + goto end_cert; + } + + if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) || + asn1_validity(cert, &offset, x509_ctx) || + asn1_name(cert, &offset, x509_ctx->cert_dn) || + asn1_public_key(cert, &offset, x509_ctx)) + { + goto end_cert; + } + +#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ + bi_ctx = x509_ctx->rsa_ctx->bi_ctx; + + /* use the appropriate signature algorithm */ + switch (x509_ctx->sig_type) + { + case SIG_TYPE_MD5: + { + MD5_CTX md5_ctx; + uint8_t md5_dgst[MD5_SIZE]; + MD5_Init(&md5_ctx); + MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + MD5_Final(md5_dgst, &md5_ctx); + x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE); + } + break; + + case SIG_TYPE_SHA1: + { + SHA1_CTX sha_ctx; + uint8_t sha_dgst[SHA1_SIZE]; + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + SHA1_Final(sha_dgst, &sha_ctx); + x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE); + } + break; + + case SIG_TYPE_SHA256: + { + SHA256_CTX sha256_ctx; + uint8_t sha256_dgst[SHA256_SIZE]; + SHA256_Init(&sha256_ctx); + SHA256_Update(&sha256_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + SHA256_Final(sha256_dgst, &sha256_ctx); + x509_ctx->digest = bi_import(bi_ctx, sha256_dgst, SHA256_SIZE); + } + break; + + case SIG_TYPE_SHA384: + { + SHA384_CTX sha384_ctx; + uint8_t sha384_dgst[SHA384_SIZE]; + SHA384_Init(&sha384_ctx); + SHA384_Update(&sha384_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + SHA384_Final(sha384_dgst, &sha384_ctx); + x509_ctx->digest = bi_import(bi_ctx, sha384_dgst, SHA384_SIZE); + } + break; + + case SIG_TYPE_SHA512: + { + SHA512_CTX sha512_ctx; + uint8_t sha512_dgst[SHA512_SIZE]; + SHA512_Init(&sha512_ctx); + SHA512_Update(&sha512_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + SHA512_Final(sha512_dgst, &sha512_ctx); + x509_ctx->digest = bi_import(bi_ctx, sha512_dgst, SHA512_SIZE); + } + break; + } + + if (version == 2 && asn1_next_obj(cert, &offset, ASN1_V3_DATA) > 0) + { + x509_v3_subject_alt_name(cert, offset, x509_ctx); + x509_v3_basic_constraints(cert, offset, x509_ctx); + x509_v3_key_usage(cert, offset, x509_ctx); + } + + offset = end_tbs; /* skip the rest of v3 data */ + if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) || + asn1_signature(cert, &offset, x509_ctx)) + goto end_cert; +#endif + ret = X509_OK; +end_cert: + if (len) + { + *len = cert_size; + } + + if (ret) + { +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: Invalid X509 ASN.1 file (%s)\n", + x509_display_error(ret)); +#endif + x509_free(x509_ctx); + *ctx = NULL; + } + + return ret; +} + +#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ +static int x509_v3_subject_alt_name(const uint8_t *cert, int offset, + X509_CTX *x509_ctx) +{ + if ((offset = asn1_is_subject_alt_name(cert, offset)) > 0) + { + x509_ctx->subject_alt_name_present = true; + x509_ctx->subject_alt_name_is_critical = + asn1_is_critical_ext(cert, &offset); + + if (asn1_next_obj(cert, &offset, ASN1_OCTET_STRING) > 0) + { + int altlen; + + if ((altlen = asn1_next_obj(cert, &offset, ASN1_SEQUENCE)) > 0) + { + int endalt = offset + altlen; + int totalnames = 0; + + while (offset < endalt) + { + int type = cert[offset++]; + int dnslen = get_asn1_length(cert, &offset); + + if (type == ASN1_CONTEXT_DNSNAME) + { + /* sanity check the hostname due to +https://tools.cisco.com/security/center/viewAlert.x?alertId=18852 + */ + if (strnlen((const char *)&cert[offset], dnslen) != + dnslen) + { + return X509_VFY_ERROR_NO_TRUSTED_CERT; + } + + x509_ctx->subject_alt_dnsnames = (char**) + realloc(x509_ctx->subject_alt_dnsnames, + (totalnames + 2) * sizeof(char*)); + x509_ctx->subject_alt_dnsnames[totalnames] = + (char*)malloc(dnslen + 1); + x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL; + memcpy(x509_ctx->subject_alt_dnsnames[totalnames], + cert + offset, dnslen); + x509_ctx->subject_alt_dnsnames[totalnames][dnslen] = 0; + totalnames++; + } + + offset += dnslen; + } + } + } + } + + return X509_OK; +} + +/** + * Basic constraints - see https://tools.ietf.org/html/rfc5280#page-39 + */ +static int x509_v3_basic_constraints(const uint8_t *cert, int offset, + X509_CTX *x509_ctx) +{ + int ret = X509_OK; + int lenSeq = 0; + + if ((offset = asn1_is_basic_constraints(cert, offset)) == 0) + goto end_contraints; + + x509_ctx->basic_constraint_present = true; + x509_ctx->basic_constraint_is_critical = + asn1_is_critical_ext(cert, &offset); + + /* Assign Defaults in case not specified + basic_constraint_cA will already by zero by virtue of the calloc */ + x509_ctx->basic_constraint_cA = 0; + /* basic_constraint_pathLenConstraint is unlimited by default. + 10000 is just a large number (limits.h is not already included) */ + x509_ctx->basic_constraint_pathLenConstraint = 10000; + + if ((asn1_next_obj(cert, &offset, ASN1_OCTET_STRING) < 0) || + ((lenSeq = asn1_next_obj(cert, &offset, ASN1_SEQUENCE)) < 0)) + { + ret = X509_NOT_OK; + } + + /* If the Sequence Length is greater than zero, + continue with the basic_constraint_cA */ + if ((lenSeq>0)&&(asn1_get_bool(cert, &offset, + &x509_ctx->basic_constraint_cA) < 0)) + { + ret = X509_NOT_OK; + } + + /* If the Sequence Length is greater than 3, it has more content than + the basic_constraint_cA bool, so grab the pathLenConstraint */ + if ((lenSeq>3) && (asn1_get_int(cert, &offset, + &x509_ctx->basic_constraint_pathLenConstraint) < 0)) + { + ret = X509_NOT_OK; + } + +end_contraints: + return ret; +} + +/* + * Key usage - see https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + */ +static int x509_v3_key_usage(const uint8_t *cert, int offset, + X509_CTX *x509_ctx) +{ + int ret = X509_OK; + + if ((offset = asn1_is_key_usage(cert, offset)) == 0) + goto end_key_usage; + + x509_ctx->key_usage_present = true; + x509_ctx->key_usage_is_critical = asn1_is_critical_ext(cert, &offset); + + if (asn1_next_obj(cert, &offset, ASN1_OCTET_STRING) < 0 || + asn1_get_bit_string_as_int(cert, &offset, &x509_ctx->key_usage)) + { + ret = X509_NOT_OK; + } + +end_key_usage: + return ret; +} +#endif + +/** + * Free an X.509 object's resources. + */ +void x509_free(X509_CTX *x509_ctx) +{ + X509_CTX *next; + int i; + + if (x509_ctx == NULL) /* if already null, then don't bother */ + return; + + for (i = 0; i < X509_NUM_DN_TYPES; i++) + { + free(x509_ctx->ca_cert_dn[i]); + free(x509_ctx->cert_dn[i]); + } + + free(x509_ctx->signature); + +#ifdef CONFIG_SSL_CERT_VERIFICATION + if (x509_ctx->digest) + { + bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest); + } + + if (x509_ctx->subject_alt_dnsnames) + { + for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i) + free(x509_ctx->subject_alt_dnsnames[i]); + + free(x509_ctx->subject_alt_dnsnames); + } +#endif + + RSA_free(x509_ctx->rsa_ctx); + next = x509_ctx->next; + free(x509_ctx); + x509_free(next); /* clear the chain */ +} + +#ifdef CONFIG_SSL_CERT_VERIFICATION + +static const uint8_t sig_prefix_md5[] = {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; +static const uint8_t sig_prefix_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; +static const uint8_t sig_prefix_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; +static const uint8_t sig_prefix_sha384[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; +static const uint8_t sig_prefix_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; + +/** + * Take a signature and decrypt it. + */ +static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len, + uint8_t sig_type, bigint *modulus, bigint *pub_exp) +{ + int i; + bigint *decrypted_bi, *dat_bi; + bigint *bir = NULL; + uint8_t *block = (uint8_t *)alloca(sig_len); + + const uint8_t *sig_prefix = NULL; + uint8_t sig_prefix_size = 0, hash_len = 0; + /* adjust our expections */ + switch (sig_type) + { + case SIG_TYPE_MD5: + sig_prefix = sig_prefix_md5; + sig_prefix_size = sizeof(sig_prefix_md5); + break; + case SIG_TYPE_SHA1: + sig_prefix = sig_prefix_sha1; + sig_prefix_size = sizeof(sig_prefix_sha1); + break; + case SIG_TYPE_SHA256: + sig_prefix = sig_prefix_sha256; + sig_prefix_size = sizeof(sig_prefix_sha256); + break; + case SIG_TYPE_SHA384: + sig_prefix = sig_prefix_sha384; + sig_prefix_size = sizeof(sig_prefix_sha384); + break; + case SIG_TYPE_SHA512: + sig_prefix = sig_prefix_sha512; + sig_prefix_size = sizeof(sig_prefix_sha512); + break; + } + + if (sig_prefix) + hash_len = sig_prefix[sig_prefix_size - 1]; + + /* check length (#A) */ + if (sig_len < 2 + 8 + 1 + sig_prefix_size + hash_len) + goto err; + + /* decrypt */ + dat_bi = bi_import(ctx, sig, sig_len); + ctx->mod_offset = BIGINT_M_OFFSET; + + /* convert to a normal block */ + decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp); + + bi_export(ctx, decrypted_bi, block, sig_len); + ctx->mod_offset = BIGINT_M_OFFSET; + + /* check the first 2 bytes */ + if (block[0] != 0 || block[1] != 1) + goto err; + + /* check the padding */ + i = 2; /* start at the first padding byte */ + while (i < sig_len - 1 - sig_prefix_size - hash_len) + { /* together with (#A), we require at least 8 bytes of padding */ + if (block[i++] != 0xFF) + goto err; + } + + /* check end of padding */ + if (block[i++] != 0) + goto err; + + /* check the ASN.1 metadata */ + if (memcmp(block+i, sig_prefix, sig_prefix_size)) + goto err; + + /* now we can get the hash we need */ + bir = bi_import(ctx, block + i + sig_prefix_size, hash_len); + +err: + /* save a few bytes of memory */ + bi_clear_cache(ctx); + return bir; +} + +/** + * Do some basic checks on the certificate chain. + * + * Certificate verification consists of a number of checks: + * - The date of the certificate is after the start date. + * - The date of the certificate is before the finish date. + * - A root certificate exists in the certificate store. + * - That the certificate(s) are not self-signed. + * - The certificate chain is valid. + * - The signature of the certificate is valid. + * - Basic constraints + */ +int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert, + int *pathLenConstraint) +{ + int ret = X509_OK, i = 0; + bigint *cert_sig; + X509_CTX *next_cert = NULL; + BI_CTX *ctx = NULL; + bigint *mod = NULL, *expn = NULL; + int match_ca_cert = 0; + struct timeval tv; + uint8_t is_self_signed = 0; + + if (cert == NULL) + { + ret = X509_VFY_ERROR_NO_TRUSTED_CERT; + goto end_verify; + } + + /* a self-signed certificate that is not in the CA store - use this + to check the signature */ + if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0) + { + is_self_signed = 1; + ctx = cert->rsa_ctx->bi_ctx; + mod = cert->rsa_ctx->m; + expn = cert->rsa_ctx->e; + } + + gettimeofday(&tv, NULL); + + /* check the not before date */ + if (tv.tv_sec < cert->not_before) + { + ret = X509_VFY_ERROR_NOT_YET_VALID; + goto end_verify; + } + + /* check the not after date */ + if (tv.tv_sec > cert->not_after) + { + ret = X509_VFY_ERROR_EXPIRED; + goto end_verify; + } + + if (cert->basic_constraint_present) + { + /* If the cA boolean is not asserted, + then the keyCertSign bit in the key usage extension MUST NOT be + asserted. */ + if (!cert->basic_constraint_cA && + IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_CERT_SIGN)) + { + ret = X509_VFY_ERROR_BASIC_CONSTRAINT; + goto end_verify; + } + + /* The pathLenConstraint field is meaningful only if the cA boolean is + asserted and the key usage extension, if present, asserts the + keyCertSign bit. In this case, it gives the maximum number of + non-self-issued intermediate certificates that may follow this + certificate in a valid certification path. */ + if (cert->basic_constraint_cA && + (!cert->key_usage_present || + IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_CERT_SIGN)) && + (cert->basic_constraint_pathLenConstraint+1) < *pathLenConstraint) + { + ret = X509_VFY_ERROR_BASIC_CONSTRAINT; + goto end_verify; + } + } + + next_cert = cert->next; + + /* last cert in the chain - look for a trusted cert */ + if (next_cert == NULL) + { + if (ca_cert_ctx != NULL) + { + /* go thru the CA store */ + while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) + { + /* the extension is present but the cA boolean is not + asserted, then the certified public key MUST NOT be used + to verify certificate signatures. */ + if (cert->basic_constraint_present && + !ca_cert_ctx->cert[i]->basic_constraint_cA) + { + i++; + continue; + } + + if (asn1_compare_dn(cert->ca_cert_dn, + ca_cert_ctx->cert[i]->cert_dn) == 0) + { + /* use this CA certificate for signature verification */ + match_ca_cert = true; + ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx; + mod = ca_cert_ctx->cert[i]->rsa_ctx->m; + expn = ca_cert_ctx->cert[i]->rsa_ctx->e; + + + break; + } + + i++; + } + } + + /* couldn't find a trusted cert (& let self-signed errors + be returned) */ + if (!match_ca_cert && !is_self_signed) + { + ret = X509_VFY_ERROR_NO_TRUSTED_CERT; + goto end_verify; + } + } + else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0) + { + /* check the chain */ + ret = X509_VFY_ERROR_INVALID_CHAIN; + goto end_verify; + } + else /* use the next certificate in the chain for signature verify */ + { + ctx = next_cert->rsa_ctx->bi_ctx; + mod = next_cert->rsa_ctx->m; + expn = next_cert->rsa_ctx->e; + } + + /* cert is self signed */ + if (!match_ca_cert && is_self_signed) + { + ret = X509_VFY_ERROR_SELF_SIGNED; + goto end_verify; + } + + /* check the signature */ + cert_sig = sig_verify(ctx, cert->signature, cert->sig_len, cert->sig_type, + bi_clone(ctx, mod), bi_clone(ctx, expn)); + + if (cert_sig && cert->digest) + { + if (bi_compare(cert_sig, cert->digest) != 0) + ret = X509_VFY_ERROR_BAD_SIGNATURE; + + + bi_free(ctx, cert_sig); + } + else + { + ret = X509_VFY_ERROR_BAD_SIGNATURE; + } + + if (ret) + goto end_verify; + + /* go down the certificate chain using recursion. */ + if (next_cert != NULL) + { + (*pathLenConstraint)++; /* don't include last certificate */ + ret = x509_verify(ca_cert_ctx, next_cert, pathLenConstraint); + } + +end_verify: + return ret; +} +#endif + +#if defined (CONFIG_SSL_FULL_MODE) +/** + * Used for diagnostics. + */ +static const char *not_part_of_cert = ""; +void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx) +{ + if (cert == NULL) + return; + + printf("=== CERTIFICATE ISSUED TO ===\n"); + printf("Common Name (CN):\t\t"); + printf("%s\n", cert->cert_dn[X509_COMMON_NAME] ? + cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert); + + printf("Organization (O):\t\t"); + printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ? + cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert); + + if (cert->cert_dn[X509_ORGANIZATIONAL_UNIT]) + { + printf("Organizational Unit (OU):\t"); + printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT]); + } + + if (cert->cert_dn[X509_LOCATION]) + { + printf("Location (L):\t\t\t"); + printf("%s\n", cert->cert_dn[X509_LOCATION]); + } + + if (cert->cert_dn[X509_COUNTRY]) + { + printf("Country (C):\t\t\t"); + printf("%s\n", cert->cert_dn[X509_COUNTRY]); + } + + if (cert->cert_dn[X509_STATE]) + { + printf("State (ST):\t\t\t"); + printf("%s\n", cert->cert_dn[X509_STATE]); + } + + if (cert->basic_constraint_present) + { + printf("Basic Constraints:\t\t%sCA:%s, pathlen:%d\n", + cert->basic_constraint_is_critical ? + "critical, " : "", + cert->basic_constraint_cA? "TRUE" : "FALSE", + cert->basic_constraint_pathLenConstraint); + } + + if (cert->key_usage_present) + { + printf("Key Usage:\t\t\t%s", cert->key_usage_is_critical ? + "critical, " : ""); + bool has_started = false; + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DIGITAL_SIGNATURE)) + { + printf("Digital Signature"); + has_started = true; + } + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_NON_REPUDIATION)) + { + if (has_started) + printf(", "); + + printf("Non Repudiation"); + has_started = true; + } + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_ENCIPHERMENT)) + { + if (has_started) + printf(", "); + + printf("Key Encipherment"); + has_started = true; + } + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DATA_ENCIPHERMENT)) + { + if (has_started) + printf(", "); + + printf("Data Encipherment"); + has_started = true; + } + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_AGREEMENT)) + { + if (has_started) + printf(", "); + + printf("Key Agreement"); + has_started = true; + } + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_CERT_SIGN)) + { + if (has_started) + printf(", "); + + printf("Key Cert Sign"); + has_started = true; + } + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_CRL_SIGN)) + { + if (has_started) + printf(", "); + + printf("CRL Sign"); + has_started = true; + } + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_ENCIPHER_ONLY)) + { + if (has_started) + printf(", "); + + printf("Encipher Only"); + has_started = true; + } + + if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DECIPHER_ONLY)) + { + if (has_started) + printf(", "); + + printf("Decipher Only"); + has_started = true; + } + + printf("\n"); + } + + if (cert->subject_alt_name_present) + { + printf("Subject Alt Name:\t\t%s", cert->subject_alt_name_is_critical + ? "critical, " : ""); + if (cert->subject_alt_dnsnames) + { + int i = 0; + + while (cert->subject_alt_dnsnames[i]) + printf("%s ", cert->subject_alt_dnsnames[i++]); + } + printf("\n"); + + } + + printf("=== CERTIFICATE ISSUED BY ===\n"); + printf("Common Name (CN):\t\t"); + printf("%s\n", cert->ca_cert_dn[X509_COMMON_NAME] ? + cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert); + + printf("Organization (O):\t\t"); + printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ? + cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert); + + if (cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]) + { + printf("Organizational Unit (OU):\t"); + printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]); + } + + if (cert->ca_cert_dn[X509_LOCATION]) + { + printf("Location (L):\t\t\t"); + printf("%s\n", cert->ca_cert_dn[X509_LOCATION]); + } + + if (cert->ca_cert_dn[X509_COUNTRY]) + { + printf("Country (C):\t\t\t"); + printf("%s\n", cert->ca_cert_dn[X509_COUNTRY]); + } + + if (cert->ca_cert_dn[X509_STATE]) + { + printf("State (ST):\t\t\t"); + printf("%s\n", cert->ca_cert_dn[X509_STATE]); + } + + printf("Not Before:\t\t\t%s", ctime(&cert->not_before)); + printf("Not After:\t\t\t%s", ctime(&cert->not_after)); + printf("RSA bitsize:\t\t\t%d\n", cert->rsa_ctx->num_octets*8); + printf("Sig Type:\t\t\t"); + switch (cert->sig_type) + { + case SIG_TYPE_MD5: + printf("MD5\n"); + break; + case SIG_TYPE_SHA1: + printf("SHA1\n"); + break; + case SIG_TYPE_SHA256: + printf("SHA256\n"); + break; + case SIG_TYPE_SHA384: + printf("SHA384\n"); + break; + case SIG_TYPE_SHA512: + printf("SHA512\n"); + break; + default: + printf("Unrecognized: %d\n", cert->sig_type); + break; + } + + if (ca_cert_ctx) + { + int pathLenConstraint = 0; + printf("Verify:\t\t\t\t%s\n", + x509_display_error(x509_verify(ca_cert_ctx, cert, + &pathLenConstraint))); + } + +#if 0 + print_blob("Signature", cert->signature, cert->sig_len); + bi_print("Modulus", cert->rsa_ctx->m); + bi_print("Pub Exp", cert->rsa_ctx->e); +#endif + + if (ca_cert_ctx) + { + x509_print(cert->next, ca_cert_ctx); + } + + TTY_FLUSH(); +} +#endif + +const char * x509_display_error(int error) +{ + switch (error) + { + case X509_OK: + return "Certificate verify successful"; + + case X509_NOT_OK: + return "X509 not ok"; + + case X509_VFY_ERROR_NO_TRUSTED_CERT: + return "No trusted cert is available"; + + case X509_VFY_ERROR_BAD_SIGNATURE: + return "Bad signature"; + + case X509_VFY_ERROR_NOT_YET_VALID: + return "Cert is not yet valid"; + + case X509_VFY_ERROR_EXPIRED: + return "Cert has expired"; + + case X509_VFY_ERROR_SELF_SIGNED: + return "Cert is self-signed"; + + case X509_VFY_ERROR_INVALID_CHAIN: + return "Chain is invalid (check order of certs)"; + + case X509_VFY_ERROR_UNSUPPORTED_DIGEST: + return "Unsupported digest"; + + case X509_INVALID_PRIV_KEY: + return "Invalid private key"; + + case X509_VFY_ERROR_BASIC_CONSTRAINT: + return "Basic constraint invalid"; + + default: + return "Unknown"; + } +} +//#endif /* CONFIG_SSL_FULL_MODE */ + diff --git a/circuitpython/lib/axtls/www/bin/.htaccess b/circuitpython/lib/axtls/www/bin/.htaccess new file mode 100644 index 0000000..4496fa9 --- /dev/null +++ b/circuitpython/lib/axtls/www/bin/.htaccess @@ -0,0 +1,2 @@ +Deny all + diff --git a/circuitpython/lib/axtls/www/favicon.ico b/circuitpython/lib/axtls/www/favicon.ico new file mode 100644 index 0000000..9f6f30e Binary files /dev/null and b/circuitpython/lib/axtls/www/favicon.ico differ diff --git a/circuitpython/lib/axtls/www/index.html b/circuitpython/lib/axtls/www/index.html new file mode 100755 index 0000000..b1bc57f --- /dev/null +++ b/circuitpython/lib/axtls/www/index.html @@ -0,0 +1,7103 @@ + + + + + + + + + + + + axTLS Embedded SSL - changes, notes and errata + + + + + + + + + + + + + +
+
+
+
+
changes, notes and errata
+
Type the text for 'YourName'
+
@@bgcolor(#ff0000):color(#ffffff):Changes for 2.1.5 (2019-03-15)@@\n\n!!__SSL Library__\n* Fix for CDR#2019022742006229 (Thanks ~T-Systems)\n* Improvement of PKCS#1 RSA signature verification (Thanks Sze Yiu)\n* Date check extented past 2050 (Thanks Rex Brown)\n* Fixed X509 verification endless loop (Thanks Shiro Kawai)\n* Truncated DNS ~SANs now fail to verify (Thanks Alex Gaynor)\n* Header compile issue when "Create Language Bindings" is used (Thanks Paul Gazzillo)\n* Explicit rand() used to partly init entropy when dev urandom not used (Thanks Uwe Bonnes)\n@@bgcolor(#ff0000):color(#ffffff):Changes for 2.1.4 (2017-08-31)@@\n\n!!__SSL Library__\n* Fix for if basic constraint is missing in cert (thanks John Power)\n* host_name for SNI is now a const char * (thanks Paul Sokolovsky)\n* Both bytes for a cipher type in a hello msg are now checked (thanks Steve Bennett)\n@@bgcolor(#ff0000):color(#ffffff):Changes for 2.1.2 (2016-12-31)@@\n\n!!__SSL Library__\n* Basic constraint/key usage v3 extensions now supported\n* Test harness must now be run without built-in default cert\n@@bgcolor(#ff0000):color(#ffffff):Changes for 2.1.1 (2016-12-20)@@\n\n!!__SSL Library__\n* X509 State, country and location are now used for verification and display.\n* SNI hostname memory is now managed by the calling application\n* X509 version number is checked before processing v3 extensions.\n@@bgcolor(#ff0000):color(#ffffff):Changes for 2.1.0 (2016-12-13)@@\n\n!!__SSL Library__\n* SNI added\n* Some non-C sample code updated.\n@@bgcolor(#ff0000):color(#ffffff):Changes for 2.0.1 (2016-08-30)@@\n\n!!__SSL Library__\n* ~RC4 only used if ~PKCS12 is used.\n* Buffer sizes tightned up.\n* Buffer check on client handshake due to some incompatibilities.\n@@bgcolor(#ff0000):color(#ffffff):Changes for 2.0.0 (2016-08-17)@@\n\n!!__SSL Library__\n* Support for TLS 1.2\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.5.4 (2016-07-07)@@\n\n!!__SSL Library__\n* Fixed client certificate issue where there is no client certificate and a certificate verify msg was still being sent.\n* Tag 64-bit constants with "LL" (e.g. keep ~AVR32 gcc happy)\n* Removed ~RC4 from the list of ciphers\n* Can handle chains that are out of order (thanks Paul Johnstone)\n* Removed some printfs in skeleton mode\n* Removed endian.h as it was causing some porting issues\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.5.3 (2015-04-30)@@\n\n!!__SSL Library__\n* Added named unions to ~SHA512 code as some compilers don't support it\n* Some other porting suggesions from Chris Ghormley\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.5.2 (2015-03-10)@@\n\n!!__SSL Library__\n* ~SHA384/~SHA512 support added\n* Security issue fixed where a plain text could be injected before the handshake was completed\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.5.1 (2014-11-19)@@\n\n!!__SSL Library__\n* ~SHA256 support added\n* All padding/separator bytes checked in ~RSA_decrypt()\n* Added check to get_asn1_length() to limit the number of octets and to not allow overflow\n* ~MD2 removed\n* Return code checked for get_random()\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.5.0 (2014-10-31)@@\n\n!!__SSL Library__\n* Fixed array access out of bounds bug in add_cert() (thanks Ole Reinhardt)\n* Fix handling of return values of ~SOCKET_READ in process_sslv23_client_hello() (thanks Ole Reinhardt)\n* added generalized time for certificates\n* added printf changes from Fabian Frank to stop warnings/errors\n* Moved setting encryption flags to after handshake completion (thanks Eric Hu)\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.9@@\n\n!!__SSL Library__\n* Fixed issue where the Chrome browser could not connect. This was due to Chrome sending different version numbers in its record header and client hello. ~AxTLS has been modified to use the client hello version as part of ~RFC5246.\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.8@@\n\n!!__SSL Library__\n* Fixed issue where the stdint typedefs were not imported by default (stdint.h had to be included explicity) (thanks Anthony G. Basile)\n\n!!__axhttpd__\n* The password hash broke due to an over zealous buffer overflow check. \n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.6@@\n\n!!__SSL Library__\n* Fixed issue where the stdint typedefs were not imported by default (stdint.h had to be included explicity) (thanks Anthony G. Basile)\n* Fixed RNG initialization issue where client library was performed incorrectly (thanks Gilles Boccon~-Gibod). \n\n!!__axhttpd__\n* Now compiles properly under TCP/IP v6.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.5@@\n\n!!__SSL Library__\n* Fixed possible buffer overflow when doing base64 decoding (thanks Emil Kvarnhammar).\n* Fixed unicode parsing error in certificates (thanks Eric Hu)\n\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.4@@\n\n!!__axhttpd__\n* Allow other CGI applications (such as PHP) to call HTML files from their command line.\n\n!!__SSL Library__\n* Fixed memory leak with invalid certificates (thanks Jon Trauntvein)\n* Fixed issue with non-blocking client connections not working properly (thanks Richard Titmuss).\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.3@@\n\n!!__SSL Library__\n* axtlswrap compilation error fixed.\n\n!!__axhttpd__\n* added '-w' command-line option to set the webroot directory.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.2@@\n\n!!__SSL Library__\n* bi_export could have a buffer overrun with incorrect input (thanks Gilles ~Boccon-Gibod - 3334305)\n\n!!__axhttpd__\n* ~RFC1123 time format used in the headers.\n* Expires heading added (current time + ~CONFIG_HTTP_TIMEOUT)\n* UTC/localtime issue with ~If-Modified-Since header.\n\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.1@@\n\n!!__SSL Library__\n* Allow reading of ~PKCS8/12 unencrypted keys in PEM format and mconf will allow the option in server mode (thanks Steve Bennett).\n* Issue where comparing a null and an empty string could return a false positive for cert check (thanks Gilles ~Boccon-Gibod - 3310885).\n* -fPIC added as a Linux compile option.\n\n!!__axhttpd__\n* Killing connections on session timeout is guaranteed.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.4.0@@\n\n!!__SSL Library__\n* TLS v1.1 implemented and is enabled by default.\n* Closure alerts implemented correctly.\n* Fixed issue with ~SSLv23 hello versioning. \n \n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.3.4@@\n\n!!__SSL Library__\n* SSL 2.0 client hello is turned off by default as per RFC 4346 Appendix E.\n* Client determines the cipher suite selected rather than the server as per RFC 4346 7.4.1.2.\n* Guard against timing HMAC timing attacks as per RFC 4346 6.2.3.2.\n* Fixed ~SOCKET_WRITE buffer issue (thanks Hardy Griech - 3177419)\n* Fixed variable length MAC issue as used by gnutls.\n* Fixed version issue when TLS >=1.1 is used.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.3.2@@\n\n!!__SSL Library__\n* Loading of PEM certificate bundles now loads CA certs properly.\n* ssl_client_new() can now be broken up into an ssl_client_new() and successive ssl_read()'s now by setting the ~SSL_CONNECT_IN_PARTS as an option in ssl_ctx_new().\n* Non-blocked mode is now not a requirement but calls may still be blocked.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.3.1@@\n\n!!__SSL Library__\n* Certificate bundles which contain "invalid" certificates (i.e. invalid digests types etc) are ignored rather than cause failure.\n\n!!__axhttpd__\n* ~HTTPv1.0 packets close a connection upon completion.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.3.0@@\n\n!!__SSL Library__\n* Close notify is now sent as an error code from ssl_read(). Server code should be modified to check for ~SSL_CLOSE_NOTIFY (thanks to Eric Hu - 3132700).\n* regular_square() issue fixed (3078672)\n* partial_multiply() removed and merged with regular_multiply() (3078372).\n* Invalid session id size now returns ~SSL_ERROR_INVALID_SESSION (thanks to Hardy Griech - 3072881)\n* q-dash issue with Barrett reduction fixed (thanks to Hardy Griech - 3079291).\n* PEM file detection now looks for "-BEGIN" in any part of the file rather than at the start (3123838).\n* 8/16/32 bit native int sizes can be selected in configuration.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.2.7@@\n\n!!__SSL Library__\n* A fix to find_max_exp_index() (thanks to Hardy Griech).\n* Check is made to get_cipher_info() if the appropriate cipher is not found (thanks to Hardy Griech).\n* Extra x509_free() removed from do_client_connect().\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.2.5@@\n\n!!__SSL Library__\n* The custom RNG updated to use an entropy pool (with better hooks to use counters).\n\n!!__axhttpd__\n* Headers are case insensitive (thanks to Joe Pruett for this and the following).\n* Child zombie issue fixed.\n* EOF on ~POSTs fixed.\n* Expect is ignored.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.2.4@@\n\n!!__SSL Library__\n* Client renegotiation now results in an error. This is the result of a security flaw described in this paper http://extendedsubset.com/Renegotiating_TLS.pdf, and also is explained in detail here http://www.cupfighter.net/index.php/2009/11/tls-renegotiation-attack/.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.2.3@@\n\n!!__SSL Library__\n* v3 certificates with ~SANs now supports (thanks to Carsten Sørensen).\n* axtlswrap added - a port of sslwrap (thanks to Steve Bennett)\n\n!!__axhttpd__\n* shutdown() called before socket close in CGI (thanks to Tom Brown)\n* command-line parameters to specify the http/https port.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.2.2@@\n\n!!__axhttpd__\n* File uploads over 1kB (but under MAXPOSTDATASIZE) are now supported.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.2.1@@\n\n!!__SSL Library__\n* Certificate verification now works for Firefox.\n* Extended the openssl API.\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.2.0@@\n\n!!__SSL Library__\n* A self-signed certificate will be verified as ok provided that that it is on the certificate authority list.\n* Certificates are not verified when added as certificate authorities (since self-signed and expired certificates can be added to browsers etc)\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.9@@\n\n!!__SSL Library__\n* Now support MS IIS resource kit certificates (thanks to Carsten Sørensen).\n* Fixed a memory leak when freeing more than one CA certificate.\n* The bigint library had a problem with squaring which affected classical reduction (thanks to Manuel Klimek).\n\n!!__axhttpd__\n* Brought back setuid()/setgid() as an option.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.8@@\n\n!!__SSL Library__\n* Now using a BSD style license.\n* Self-signed certificates can now be automatically generated (the keys still need to be provided).\n* A new API call //ssl_x509_create()// can be used to programatically create the certificate.\n* Certificate/keys can be loaded automatically given a file location.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.7@@\n\n!!__SSL Library__\n\n* Variable sized session id's is now better handled for session caching. It has meant a new API call //ssl_get_session_id_size()// and a change to //ssl_client_new()// to define the session id size.\n* Muliple records with a single header are now better supported (thanks to Hervé Sibert).\n* ~MD2 added for Verisign root cert verification (thanks to Byron Rakitzis).\n* The ~MD5/~SHA1 digests are calculated incrementally to reduce memory (thanks to Byron Rakitzis).\n* The bigint cache is now cleared regularly to reduce memory.\n\n!!__axhttpd__\n\n* Improved the POST handling (thanks to Christian Melki).\n* CSS files now work properly.\n* Lua's CGI launcher location is configurable.\n* //vfork()// is now used for CGI for performance reasons.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.6@@\n\n!!__SSL Library__\n\n* ~RC4 speed improvements\n* Lua samples/bindings now work properly\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.5@@\n\n!!__SSL Library__\n\n* Session id's can now be variable lengths in server hello messages.\n* 0 length client certificates are now supported.\n* ssl_version() now returns just the version and not the date.\n* ssl_write() was not sending complete packets under load.\n\n!!__axhttpd__\n\n* Completely updated the CGI code.\n* Lua now integrated - Lua scripts and Lua Pages now run.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.4@@\n\n!!__SSL Library__\n\n* Fixed a Win32 crypto library issue with non-Administrator users\n* Removed compiler warnings that showed up in ~FC6.\n* GNU TLS certificates are now accepted.\n* Separated the send/receive headers for HMAC calculations.\n* Fixed a compilation problem with swig/perl/~FC6.\n* Fixed an issue with loading PEM CA certificates.\n\n!!__axhttpd__\n\n* Made //setuid()/setgid()// call an mconf option.\n* Made //chroot()// an mconf option. Default to //chdir()// instead.\n* Removed optional permissions checking.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.1@@\n\n!!__SSL Library__\n\n* AES should now work on 16bit processors (there was an alignment problem).\n* Various freed objects are cleared before freeing.\n* Header files now installed in ///usr/local/include/axTLS//.\n* -DCYGWIN replaced with -~DCONFIG_PLATFORM_CYGWIN (and the same for Solaris).\n* removed "-noextern" option in Swig. Fixed some other warnings in Win32.\n* SSLCTX changed to ~SSL_CTX (to be consistent with openssl). SSLCTX still exists for backwards compatibility.\n* malloc() and friends call abort() on failure.\n* Fixed a memory leak in directory listings.\n* Added openssl() compatibility functions.\n* Fixed Cygwin 'make install' issue.\n\n!!__axhttpd__\n\n* main.c now becomes axhttpd.c.\n* Header file issue fixed (in mime_types.c).\n* //chroot()// now used for better security.\n* Basic authentication implemented (via .htpasswd).\n* SSL access/denial protection implemented (via .htaccess).\n* Directory access protection implemented (via .htaccess).\n* Can now have more than one CGI file extension in mconf.\n* "~If-Modified-Since" request now handled properly.\n* Performance tweaks to remove //ssl_find()//.
[[Read Me]]
axTLS uses a BSD style license:\n\nCopyright (c) 2008, Cameron Rich All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer. Redistributions in binary\nform must reproduce the above copyright notice, this list of conditions and\nthe following disclaimer in the documentation and/or other materials\nprovided with the distribution. Neither the name of the axTLS Project nor\nthe names of its contributors may be used to endorse or promote products\nderived from this software without specific prior written permission. \n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.
[[Read Me]] \n[[Changelog]]\n[[axhttpd]]\n[[License]]
+
<div class='header' macro='gradient vert #390108 #900'>\n<div class='headerShadow'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n<div class='headerForeground'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n</div>\n<div id='mainMenu'>\n<div refresh='content' tiddler='MainMenu'></div>\n</div>\n<div id='sidebar'>\n<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>
+
!@@bgcolor(#ff0000):color(#ffffff):axTLS Quick Start Guide@@\n\nThis is a guide to get a small SSL web-server up and running quickly.\n\n!!__Introduction__\n\nThe axTLS project is an SSL client/server library using the ~TLSv1 protocol. It is designed to be small and fast, and is suited to embedded projects. A web server is included.\n\nThe basic web server + SSL library is around 60-70kB and is configurable for features or size.\n\n!!__Compilation__\n\nAll platforms require GNU make. This means on Win32 that Cygwin needs to be installed with "make" and various developer options selected.\n\nConfiguration now uses a tool called "mconf" which gives a nice way to configure options (similar to what is used in ~BusyBox and the Linux kernel).\n\nYou should be able to compile axTLS simply by extracting it, change into the extracted directory and typing:\n\n{{indent{{{{> make}}}\n\nSelect your platform type, save the configuration, exit, and then type "make" again.\n\nIf all goes well, you should end up with an executable called "axhttpd" (or axhttpd.exe) in the //_stage// directory.\n\nTo play with all the various axTLS options, type:\n\n{{indent{{{{> make menuconfig}}}\n\nSave the new configuration and rebuild.\n\n!!__Running it__\n\nTo run it, go to the //_stage// directory, and type (as superuser):\n\n{{indent{{{{> axhttpd}}}\n\nNote: you may have to set your ~LD_LIBRARY_PATH - e.g. go to //_stage// and type //export ~LD_LIBRARY_PATH=`pwd`//\n\nAnd then point your browser at https://127.0.0.1 And you should see a this html page with a padlock appearing on your browser. or type http://127.0.0.1 to see the same page unencrypted.\n\n!!__The axssl utilities__\n\nThe axssl suite of tools are the SSL test tools in the various language bindings. They are:\n\n* axssl - C sample\n* axssl.csharp - C# sample\n* axssl.vbnet - VB.NET sample\n* axtls.jar - Java sample\n* axssl.pl - Perl sample\n* axssl.lua - Lua sample\n\nAll the tools have identical command-line parameters. e.g. to run something interesting:\n\n{{indent{{{{> axssl s_server -verify -CAfile ../ssl/test/axTLS.ca_x509}}}\n\nand\n\n{{indent{{{{> axssl s_client -cert ../ssl/test/axTLS.x509_1024 -key ../ssl/test/axTLS.key_1024 -reconnect}}}\n\n!!!!C#\n\nIf building under Linux or other non-Win32 platforms, Mono must be installed and the executable is run as:\n\n{{indent{{{{> mono axssl.csharp.exe ...}}}\n\n!!!!Java\n\nThe java version is run as:\n\n{{indent{{{{> java -jar axtls.jar <options>}}}\n\n!!!!Perl\n\n{{indent{{{{> [perl] ./axssl.pl <options>}}}\n\nIf running under Win32, be sure to use the correct version of Perl (i.e. ~ActiveState's version works ok).\n\n!!!!Lua\n\n{{indent{{{{> [lua] ./axssl.lua <options>}}}\n\n!__Known Issues__\n\n* Firefox doesn't handle legacy ~SSLv2 at all well. Disabling ~SSLv2 still initiates a ~SSLv23 handshake (v1.5). And continuous pressing of the "Reload" page instigates a change to ~SSLv3 for some reason (even though the TLS 1.0 option is selected). This will cause a "Firefox and <server> cannot communicate securely because they have no common encryption algorithms" (v1.5), or "Firefox can't connect to <server> because the site uses a security protocol which isn't enabled" (v2.0). See bugzilla issues 343543 and 359484 (Comment #7). It's all broken (hopefully fixed soon).\n* Perl/Java bindings don't work on 64 bit Linux machines. I can't even compile the latest version of Perl on an ~AMD64 box (using ~FC3).\n* Java 1.4 or better is required for the Java interfaces.\n* Processes that fork can't use session resumption unless some form of IPC is used.\n* Ensure libperl.so and libaxtls.so are in the shared library path when running with the perl bindings. A way to do this is with:\n\n{{indent{{{{> export LD_LIBRARY_PATH=`perl -e 'use Config; print $Config{archlib};'`/CORE:.}}}\n* The lua sample requires the luabit library from http://luaforge.net/projects/bit.\n\n!!!!Win32 issues\n\n* Be careful about doing .NET executions on network drives - .NET complains with security exceptions on the binary. //TODO: Add a manifest file to prevent this.//\n* CGI has been removed from Win32 - it needs a lot more work to get it right.\n* The default Microsoft .NET SDK is v2.0.50727. Download from: http://msdn.microsoft.com/netframework/downloads/updates/default.aspx.\n\n!!!!Solaris issues\n\n* mconf doesn't work well - some manual tweaking is required for string values.\n* GNU make is required and needs to be in $PATH.\n* To get swig's library dependencies to work (and for the C library to be found), I needed to type:\n\n{{indent{{{{> export LD_LIBRARY_PATH=/usr/local/gcc-3.3.1/lib:.}}}\n\n!!!!Cygwin issues\n\n* The bindings all compile but don't run under Cygwin with the exception of Perl. This is due to win32 executables being incompatible with Cygwin libraries.\n\n
+
changes, notes and errata
+
axTLS Embedded SSL
+
http://axtls.cerocclub.com.au
+
/***\nhttp://tiddlystyles.com/#theme:DevFire\nAuthor: Clint Checketts\n***/\n\n/*{{{*/\nbody {\nbackground: #000;\n}\n/*}}}*/\n/***\n!Link styles /% ============================================================= %/\n***/\n/*{{{*/\na,\na.button,\n#mainMenu a.button,\n#sidebarOptions .sliderPanel a{\n color: #ffbf00;\n border: 0;\n background: transparent;\n}\n\na:hover,\na.button:hover,\n#mainMenu a.button:hover,\n#sidebarOptions .sliderPanel a:hover\n#sidebarOptions .sliderPanel a:active{\n color: #ff7f00;\n border: 0;\n border-bottom: #ff7f00 1px dashed;\n background: transparent;\n text-decoration: none;\n}\n\n#displayArea .button.highlight{\n color: #ffbf00;\n background: #4c4c4c;\n}\n/*}}}*/\n/***\n!Header styles /% ============================================================= %/\n***/\n/*{{{*/\n.header{\n border-bottom: 2px solid #ffbf00;\n color: #fff;\n}\n\n.headerForeground a {\n color: #fff;\n}\n\n.header a:hover {\n border-bottom: 1px dashed #fff;\n}\n/*}}}*/\n/***\n!Main menu styles /% ============================================================= %/\n***/\n/*{{{*/\n#mainMenu {color: #fff;}\n#mainMenu h1{\n font-size: 1.1em;\n}\n#mainMenu li,#mainMenu ul{\n list-style: none;\n margin: 0;\n padding: 0;\n}\n/*}}}*/\n/***\n!Sidebar styles /% ============================================================= %/\n***/\n/*{{{*/\n#sidebar {\n right: 0;\n color: #fff;\n border: 2px solid #ffbf00;\n border-width: 0 0 2px 2px;\n}\n#sidebarOptions {\n background-color: #4c4c4c;\n padding: 0;\n}\n\n#sidebarOptions a{\n margin: 0;\n color: #ffbf00;\n border: 0;\n}\n#sidebarOptions a:hover {\n color: #4c4c4c;\n background-color: #ffbf00;\n\n}\n\n#sidebarOptions a:active {\n color: #ffbf00;\n background-color: transparent;\n}\n\n#sidebarOptions .sliderPanel {\n background-color: #333;\n margin: 0;\n}\n\n#sidebarTabs {background-color: #4c4c4c;}\n#sidebarTabs .tabSelected {\n padding: 3px 3px;\n cursor: default;\n color: #ffbf00;\n background-color: #666;\n}\n#sidebarTabs .tabUnselected {\n color: #ffbf00;\n background-color: #5f5f5f;\n padding: 0 4px;\n}\n\n#sidebarTabs .tabUnselected:hover,\n#sidebarTabs .tabContents {\n background-color: #666;\n}\n\n.listTitle{color: #FFF;}\n#sidebarTabs .tabContents a{\n color: #ffbf00;\n}\n\n#sidebarTabs .tabContents a:hover{\n color: #ff7f00;\n background: transparent;\n}\n\n#sidebarTabs .txtMoreTab .tabSelected,\n#sidebarTabs .txtMoreTab .tab:hover,\n#sidebarTabs .txtMoreTab .tabContents{\n color: #ffbf00;\n background: #4c4c4c;\n}\n\n#sidebarTabs .txtMoreTab .tabUnselected {\n color: #ffbf00;\n background: #5f5f5f;\n}\n\n.tab.tabSelected, .tab.tabSelected:hover{color: #ffbf00; border: 0; background-color: #4c4c4c;cursor:default;}\n.tab.tabUnselected {background-color: #666;}\n.tab.tabUnselected:hover{color:#ffbf00; border: 0;background-color: #4c4c4c;}\n.tabContents {\n background-color: #4c4c4c;\n border: 0;\n}\n.tabContents .tabContents{background: #666;}\n.tabContents .tabSelected{background: #666;}\n.tabContents .tabUnselected{background: #5f5f5f;}\n.tabContents .tab:hover{background: #666;}\n/*}}}*/\n/***\n!Message area styles /% ============================================================= %/\n***/\n/*{{{*/\n#messageArea {background-color: #666; color: #fff; border: 2px solid #ffbf00;}\n#messageArea a:link, #messageArea a:visited {color: #ffbf00; text-decoration:none;}\n#messageArea a:hover {color: #ff7f00;}\n#messageArea a:active {color: #ff7f00;}\n#messageArea .messageToolbar a{\n border: 1px solid #ffbf00;\n background: #4c4c4c;\n}\n/*}}}*/\n/***\n!Popup styles /% ============================================================= %/\n***/\n/*{{{*/\n.popup {color: #fff; background-color: #4c4c4c; border: 1px solid #ffbf00;}\n.popup li.disabled{color: #fff;}\n.popup a {color: #ffbf00; }\n.popup a:hover { background: transparent; color: #ff7f00; border: 0;}\n.popup hr {color: #ffbf00; background: #ffbf00;}\n/*}}}*/\n/***\n!Tiddler Display styles /% ============================================================= %/\n***/\n/*{{{*/\n.title{color: #fff;}\nh1, h2, h3, h4, h5 {\n color: #fff;\n background-color: transparent;\n border-bottom: 1px solid #333;\n}\n\n.subtitle{\n color: #666;\n}\n\n.viewer {color: #fff; }\n\n.viewer table{background: #666; color: #fff;}\n\n.viewer th {background-color: #996; color: #fff;}\n\n.viewer pre, .viewer code {color: #ddd; background-color: #4c4c4c; border: 1px solid #ffbf00;}\n\n.viewer hr {color: #666;}\n\n.tiddler .button {color: #4c4c4c;}\n.tiddler .button:hover { color: #ffbf00; background-color: #4c4c4c;}\n.tiddler .button:active {color: #ffbf00; background-color: #4c4c4c;}\n\n.toolbar {\n color: #4c4c4c;\n}\n\n.toolbar a.button,\n.toolbar a.button:hover,\n.toolbar a.button:active,\n.editorFooter a{\n border: 0;\n}\n\n.footer {\n color: #ddd;\n}\n\n.selected .footer {\n color: #888;\n}\n\n.highlight, .marked {\n color: #000;\n background-color: #ffe72f;\n}\n.editorFooter {\n color: #aaa;\n}\n\n.tab{\n-moz-border-radius-topleft: 3px;\n-moz-border-radius-topright: 3px;\n}\n\n.tagging,\n.tagged{\n background: #4c4c4c;\n border: 1px solid #4c4c4c; \n}\n\n.selected .tagging,\n.selected .tagged{\n background-color: #333;\n border: 1px solid #ffbf00;\n}\n\n.tagging .listTitle,\n.tagged .listTitle{\n color: #fff;\n}\n\n.tagging .button,\n.tagged .button{\n color: #ffbf00;\n border: 0;\n padding: 0;\n}\n\n.tagging .button:hover,\n.tagged .button:hover{\nbackground: transparent;\n}\n\n.selected .isTag .tagging.simple,\n.selected .tagged.simple,\n.isTag .tagging.simple,\n.tagged.simple {\n float: none;\n display: inline;\n border: 0;\n background: transparent;\n color: #fff;\n margin: 0;\n}\n\n.cascade {\n background: #4c4c4c;\n color: #ddd;\n border: 1px solid #ffbf00;\n}\n/*}}}*/
+
axhttpd is a small embedded web server using the axTLS library. It is based originally on the web server written by Doug Currie which is at http://www.hcsw.org/awhttpd.\n\n!@@bgcolor(#ff0000):color(#ffffff):axhttpd Features@@ \n\n!!__Basic Authentication__\n\nBasic Authentication uses a password file called ".htpasswd", in the directory to be protected. This file is formatted as the familiar colon-separated username/encrypted-password pair, records delimited by newlines. The protection does not carry over to subdirectories. The utility program htpasswd is included to help manually edit .htpasswd files.\n\nThe encryption of this password uses a proprietary algorithm due to the dependency of many crypt libraries on DES. An example is in [[/test_dir/no_http|https://localhost/test_dir/no_http]] (username 'abcd', password is '1234').\n\n//Note: This is an mconf enabled configuration option.//\n\n!!__SSL Protection__\n\nDirectories/files can be accessed using the 'http' or 'https' uri prefix. If normal http access for a directory needs to be disabled, then put "~SSLRequireSSL" into a '.htaccess' file in the directory to be protected. \n\nConversely, use "~SSLDenySSL" to deny access to directories via SSL.\n\nAn example is in [[/test_dir/no_http|http://localhost/test_dir/no_http]] and [[/test_dir/no_ssl|https://localhost/test_dir/no_ssl]].\n\nEntire directories can be denied access with a "Deny all" directive (regardless of SSL or authentication). An example is in [[/test_dir/bin|http://localhost/test_dir/bin]]\n\n!!__CGI__\n\nMost of the CGI 1.1 variables are now placed into the script environment and should work as normal.\n\n!!__Lua and Lua Pages__\n\nThis is a small scripting language gaining popularity in embedded applications due to its small footprint and fast speed.\n\nLua has been incorporated into the build, so simply select it and it will automatically install. Try pointing your browser at [[test_main.html|http://localhost/lua/test_main.html]] to see an example of Lua Pages.\n\n//Note: This is an mconf enabled configuration option.//\n\nThe readline development library may have to be downloaded: //yum install readline-devel//\n\n!!__Directory Listing__\n\nAn mconf option. Allow the files in directories to be displayed. An example is in [[/test_dir|http://localhost/test_dir]]\n\n!!__Other Features__\n\n* Timeout - HTTP 1.1 allows for persistent connections. This is the time allowed for this connection in seconds.\n* Daemon - Puts the process in daemon mode. \n* SSL session cache size - The size of the session cache (a heavily loaded server should maintain many sessions). A session will save on expensive SSL handshaking.\n\n
+
+ + + + + diff --git a/circuitpython/lib/axtls/www/lua/download.lua b/circuitpython/lib/axtls/www/lua/download.lua new file mode 100644 index 0000000..2ee1a71 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/download.lua @@ -0,0 +1,75 @@ +#!/usr/local/bin/lua + +require"luasocket" + +function receive (connection) + connection:settimeout(0) + local s, status = connection:receive (2^10) + if status == "timeout" then + coroutine.yield (connection) + end + return s, status +end + +function download (host, file, outfile) + --local f = assert (io.open (outfile, "w")) + local c = assert (socket.connect (host, 80)) + c:send ("GET "..file.." HTTP/1.0\r\n\r\n") + while true do + local s, status = receive (c) + --f:write (s) + if status == "closed" then + break + end + end + c:close() + --f:close() +end + +local threads = {} +function get (host, file, outfile) + print (string.format ("Downloading %s from %s to %s", file, host, outfile)) + local co = coroutine.create (function () + return download (host, file, outfile) + end) + table.insert (threads, co) +end + +function dispatcher () + while true do + local n = table.getn (threads) + if n == 0 then + break + end + local connections = {} + for i = 1, n do + local status, res = coroutine.resume (threads[i]) + if not res then + table.remove (threads, i) + break + else + table.insert (connections, res) + end + end + if table.getn (connections) == n then + socket.select (connections) + end + end +end + +local url = arg[1] +if not url then + print (string.format ("usage: %s url [times]", arg[0])) + os.exit() +end +local times = arg[2] or 5 + +url = string.gsub (url, "^http.?://", "") +local _, _, host, file = string.find (url, "^([^/]+)(/.*)") +local _, _, fn = string.find (file, "([^/]+)$") + +for i = 1, times do + get (host, file, fn..i) +end + +dispatcher () diff --git a/circuitpython/lib/axtls/www/lua/env.lua b/circuitpython/lib/axtls/www/lua/env.lua new file mode 100644 index 0000000..c429847 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/env.lua @@ -0,0 +1,26 @@ +-- This file should be executed before any script in this directory +-- according to the configuration (cgilua/conf.lua). + +pcall (cgilua.enablesession) + +local put, mkurlpath = cgilua.put, cgilua.mkurlpath + +cgilua.addclosefunction (function () + put [[ +

+ +Main]] + for _, test in { + { "Get", "test_main.lua", {ab = "cd", ef = "gh"} }, + { "Cookies", "test_cookies.lua", }, + { "FileSystem", "test_fs.lua", }, + { "Libraries", "test_lib.lua", }, + { "Session", "test_session.lua", }, + { "Variables", "test_variables.lp", }, + } do + put (string.format (' · %s', + mkurlpath (test[2], test[3]), test[1])) + end + put [[ +]] +end) diff --git a/circuitpython/lib/axtls/www/lua/overview.lp b/circuitpython/lib/axtls/www/lua/overview.lp new file mode 100644 index 0000000..4d17002 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/overview.lp @@ -0,0 +1,64 @@ + + +CGILua installation overview + + +

CGILua installation overview

+ + + + + + + + + + + + + +
Version + Copyright + Description +
<%= tostring(_G[l[2]]) %> + + +
<%= idx(p,"VERSION") %> + <%= idx(p,"COPYRIGHT") %> + <%= idx(p,"DESCRIPTION") %> +
+ + + diff --git a/circuitpython/lib/axtls/www/lua/prepara_sql2.lua b/circuitpython/lib/axtls/www/lua/prepara_sql2.lua new file mode 100644 index 0000000..6a37c2f --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/prepara_sql2.lua @@ -0,0 +1,31 @@ +#!/usr/local/bin/lua + +MAX_ROWS = arg[1] or 10 + +require"postgres" + +local env = assert (luasql.postgres ()) +local conn = assert (env:connect ("luasql-test", "tomas")) + +-- Apaga restos de outros testes. +conn:execute "drop table t2" +conn:execute "drop table t1" + +-- Criando as tabelas. +assert (conn:execute [[create table t1 ( + a int, + b int +)]]) +assert (conn:execute [[create table t2 ( + c int, + d int +)]]) + +-- Preenchedo as tabelas. +for i = 1, MAX_ROWS do + local ii = 2*i + assert (conn:execute (string.format ([[ +insert into t1 values (%d, %d); +insert into t2 values (%d, %d);]], + ii, i, ii, i))) +end diff --git a/circuitpython/lib/axtls/www/lua/test_conc.lua b/circuitpython/lib/axtls/www/lua/test_conc.lua new file mode 100644 index 0000000..bbb9be7 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_conc.lua @@ -0,0 +1,38 @@ +cgilua.htmlheader() +if ap then + local pid, ppid = ap.pid () + if not ppid then + ppid = "no parent pid" + end + cgilua.put ("pid = "..pid.." ("..ppid..")".."\n") +end + +assert(type(stable.get) == "function") +assert(type(stable.set) == "function") + +cgilua.put"stable.pairs = {
\n" +for i, v in stable.pairs () do + cgilua.put (i.." = "..tostring(v).."
\n") +end +cgilua.put"}
\n" + +local counter = stable.get"counter" or 0 +stable.set ("counter", counter + 1) + +local f = stable.get"f" +if not f then + local d = os.date() + stable.set ("f", function () return d end) +else + cgilua.put ("f() = "..tostring (f ())) +end + +cgilua.put"
\n" +for i = 1,800 do + cgilua.put (i) + for ii = 1,1000 do + cgilua.put ("") + end + cgilua.put ("\n") +end +cgilua.put ("End") diff --git a/circuitpython/lib/axtls/www/lua/test_cookies.lp b/circuitpython/lib/axtls/www/lua/test_cookies.lp new file mode 100644 index 0000000..932b9c5 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_cookies.lp @@ -0,0 +1,13 @@ + + +

Testing Cookies library

+ +<%= CL_COOKIE%> = <%= tostring(test)%>
+Assigning current date to cookie!
+Reload this script to check cookie's value! diff --git a/circuitpython/lib/axtls/www/lua/test_cookies.lua b/circuitpython/lib/axtls/www/lua/test_cookies.lua new file mode 100644 index 0000000..6af935e --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_cookies.lua @@ -0,0 +1,14 @@ +local cookies = require"cgilua.cookies" +CL_COOKIE = "cgilua_cookie" + +local test = cookies.get (CL_COOKIE) +cookies.set (CL_COOKIE, os.date()) + +cgilua.htmlheader () +cgilua.put ([[ +

Testing Cookies library

+ +]]..CL_COOKIE..' = '..tostring(test)..[[
+Assigning current date to cookie!
+Reload this script to check cookie's value! +]]) diff --git a/circuitpython/lib/axtls/www/lua/test_err.lua b/circuitpython/lib/axtls/www/lua/test_err.lua new file mode 100644 index 0000000..4d6ffc9 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_err.lua @@ -0,0 +1,4 @@ +cgilua.htmlheader() +cgilua.put"Oi!" +--io.write"something\n" +cgilua.errorlog ("eca", "emerg") diff --git a/circuitpython/lib/axtls/www/lua/test_fs.lua b/circuitpython/lib/axtls/www/lua/test_fs.lua new file mode 100644 index 0000000..566ed8b --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_fs.lua @@ -0,0 +1,23 @@ +function link_dir (dir, base) + local path = base.."/"..dir + local mode = lfs.attributes (path).mode + if mode == "directory" then + return string.format ('%s', + cgilua.mkurlpath ("test_fs.lua", { dir = path }), + dir) + else + return dir + end +end + +cgilua.htmlheader () +cgilua.put ("

Testing Filesystem library

\n") +cgilua.put ("\n") +cgilua.put ("\n") +local i = 0 +local dir = cgi.dir or "." +for file in lfs.dir (dir) do + i = i+1 + cgilua.put ("\n") +end +cgilua.put ("
Testing dir
"..i..""..link_dir(file, dir).."
\n") diff --git a/circuitpython/lib/axtls/www/lua/test_htk.lua b/circuitpython/lib/axtls/www/lua/test_htk.lua new file mode 100644 index 0000000..ac1de6c --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_htk.lua @@ -0,0 +1,22 @@ +require"htk" + +local a_table = {} +for i = 1, 20 do + local l = {} + for j = 1, 20 do + table.insert (l, HTK.TD { "cell "..i..","..j }) + end + table.insert (a_table, HTK.TR (l)) +end + +cgilua.htmlheader() +cgilua.put (HTK.HTML { + HTK.HEAD { HTK.TITLE { "Titulo da Pagina" } }, + HTK.BODY { + bgcolor = "#FFFFFF", + HTK.H1 { "Titulo da Pagina" }, + HTK.P {}, + "Uma página qualquer", + HTK.TABLE (a_table), + } +}) diff --git a/circuitpython/lib/axtls/www/lua/test_lib.lua b/circuitpython/lib/axtls/www/lua/test_lib.lua new file mode 100644 index 0000000..5041253 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_lib.lua @@ -0,0 +1,31 @@ +local function getfield (t, f) + for w in string.gfind(f, "[%w_]+") do + if not t then return nil end + t = t[w] + end + return t +end + +function test_lib (libname) + local ok, err = pcall (require, libname) + if not ok then + cgilua.put ("Library "..libname.." not found
\n".. + err) + else + cgilua.put ("Library "..libname.."
\n") + local t = getfield (_G, libname) + if type(t) ~= "table" then + cgilua.put (tostring(t)) + else + for i, v in pairs (t) do + cgilua.put ("  "..tostring(i).." = "..tostring(v).."
\n") + end + end + end + cgilua.put ("\n

\n") +end + +cgilua.htmlheader () +for _, lib in ipairs { "lfs", "socket", "luasql.postgres", "luasql", "lxp", "lxp.lom", "lualdap", "htk", "xmlrpc", "xmlrpc.http" } do + test_lib (lib) +end diff --git a/circuitpython/lib/axtls/www/lua/test_main.html b/circuitpython/lib/axtls/www/lua/test_main.html new file mode 100644 index 0000000..a50dd63 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_main.html @@ -0,0 +1,127 @@ + +Test Page + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GET: +
Lua scriptmodule
HTML templatemodule
POST: +
+
+ + + + + + + + + + + + +
+ field 1:
+ field 2:
+ field 3: + op 1 + op 2 + op 3 +
Lua script + module +
HTML template + module +
+
+
POST (with upload): +
+
+ + + + + + + + + + + + +
+ field 1:
+ file (binary!):
+
Lua script + module +
HTML template + module +
+
+
Cookies: +
Lua scriptmodule
HTML templatemodule
Filesystem: +
Lua scriptmodule
Session: +
Lua scriptmodule
CGI Variables: +
HTML templatemodule
Library Overview: +
HTML templatemodule
Concurrency +
Lua scriptmodule
+ diff --git a/circuitpython/lib/axtls/www/lua/test_main.lp b/circuitpython/lib/axtls/www/lua/test_main.lp new file mode 100644 index 0000000..917ee1e --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_main.lp @@ -0,0 +1,31 @@ + +Embeded Lua Test + + +cgi = { +\n", vv, a, tostring(b)) + end + v = vv.."}" + end +?> +<%= i %> = <%= tostring(v) %>
+<% +end +%> +} +
+Remote address: <%= cgilua.servervariable"REMOTE_ADDR" %> +
+Is persistent = <%= tostring (SAPI.Info.ispersistent) %> +
+ap =
+lfcgi = <% = tostring(lfcgi) %>
+<%= (ap and ap.handler()) or "" %>
+ + + diff --git a/circuitpython/lib/axtls/www/lua/test_main.lua b/circuitpython/lib/axtls/www/lua/test_main.lua new file mode 100644 index 0000000..0e997a2 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_main.lua @@ -0,0 +1,46 @@ +cgilua.htmlheader() +cgilua.put[[ + +Script Lua Test + + +cgi = { +]] + +for i,v in pairs (cgi) do + if type(v) == "table" then + local vv = "{" + for a,b in pairs(v) do + vv = string.format ("%s%s = %s
\n", vv, a, tostring(b)) + end + v = vv.."}" + end + cgilua.put (string.format ("%s = %s
\n", i, tostring(v))) +end +cgilua.put "}
\n" +cgilua.put ("Remote address: "..cgilua.servervariable"REMOTE_ADDR") +cgilua.put "
\n" +cgilua.put ("Is persistent = "..tostring (SAPI.Info.ispersistent).."
\n") +cgilua.put ("ap="..tostring(ap).."
\n") +cgilua.put ("lfcgi="..tostring(lfcgi).."
\n") + +-- Checking Virtual Environment +local my_output = cgilua.put +cgilua.put = nil +local status, err = pcall (function () + assert (cgilua.put == nil, "cannot change cgilua.put value") +end) +cgilua.put = my_output +assert (status == true, err) + +-- Checking require +local status, err = pcall (function () require"unknown_module" end) +assert (status == false, "unknown_module loaded!") +-- assert (package == nil, "Access to package table allowed!") + +cgilua.put[[ +

+ + +]] +cgilua = nil diff --git a/circuitpython/lib/axtls/www/lua/test_session.lua b/circuitpython/lib/axtls/www/lua/test_session.lua new file mode 100644 index 0000000..d97cc45 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_session.lua @@ -0,0 +1,43 @@ +cgilua.enablesession () + +function pt (tab) + for i, v in pairs (tab) do + local vv = v + if type(v) == "table" then + vv = "" + for _i, _v in pairs (v) do + vv = vv..string.format ("%s = %q, ", _i, _v) + end + vv = '{'..vv..'}' + end + cgilua.put (string.format ("%s = %s
\n", tostring (i), tostring (vv))) + end +end + + +if cgi.field then + if not cgilua.session.data.field then + cgilua.session.data.field = {} + end + table.insert (cgilua.session.data.field, cgi.field) +end +cgilua.htmlheader() +if cgilua.session then + cgilua.put "cgi = {
\n" + pt (cgi) + cgilua.put "}
\n" + cgilua.put "cgilua.session.data = {
\n" + pt (cgilua.session.data) + cgilua.put "}
\n" + + cgilua.put [[

+ field:
+
+
]] +else + cgilua.put "Sessions library is not available or not well configured" +end diff --git a/circuitpython/lib/axtls/www/lua/test_sql.lua b/circuitpython/lib/axtls/www/lua/test_sql.lua new file mode 100644 index 0000000..085ce97 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_sql.lua @@ -0,0 +1,13 @@ +local s = require"luasql.postgres" + +local env = assert (luasql.postgres ()) +local conn = assert (env:connect ("luasql-test", "tomas")) +local cur = assert (conn:execute ("select count(*) from fetch_test")) + +cgilua.htmlheader() +cgilua.put ("Total lines at table fetch_test is "..cur:fetch()) +cgilua.put (string.format ("
\n%s == %s
\n", tostring(s), tostring(luasql))) + +cur:close() +conn:close() +env:close() diff --git a/circuitpython/lib/axtls/www/lua/test_sql2.lua b/circuitpython/lib/axtls/www/lua/test_sql2.lua new file mode 100644 index 0000000..a2f6ee1 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_sql2.lua @@ -0,0 +1,24 @@ +require"postgres" + +local env = assert (luasql.postgres ()) +local conn = assert (env:connect ("luasql-test", "tomas")) +local cur = assert (conn:execute ("select count(*) from t1")) +local total = tonumber (cur:fetch()) +cur:close() +local aleatorio = math.random(total) +local cur = assert (conn:execute ("select * from t1, t2 where b = d and a != "..2*aleatorio)) + +cgilua.htmlheader() +cgilua.put ("Aleatorio = "..aleatorio.."
\n") + +local a,b,c,d = cur:fetch() +cgilua.put ("\n") +while a do +-- cgilua.put ("") + a,b,c,d = cur:fetch() +end +cgilua.put ("
",a,"",b,"",c,"",d,"
\n") + +cur:close() +conn:close() +env:close() diff --git a/circuitpython/lib/axtls/www/lua/test_variables.lp b/circuitpython/lib/axtls/www/lua/test_variables.lp new file mode 100644 index 0000000..c1ac332 --- /dev/null +++ b/circuitpython/lib/axtls/www/lua/test_variables.lp @@ -0,0 +1,14 @@ + +<% for _, var in pairs { "SERVER_SOFTWARE", "SERVER_NAME", "GATEWAY_INTERFACE", "SERVER_PROTOCOL", "SERVER_PORT", "REQUEST_METHOD", "PATH_INFO", "PATH_TRANSLATED", "SCRIPT_NAME", "QUERY_STRING", "REMOTE_HOST", "REMOTE_ADDR", "AUTH_TYPE", "REMOTE_USER", "REMOTE_IDENT", "CONTENT_TYPE", "CONTENT_LENGTH", "HTTP_REFERER", "HTTP_COOKIE", "SCRIPT_FILENAME", "DOCUMENT_ROOT", } do %> + +<% end %> +
<%= var %>="<%= cgilua.servervariable(var) or "not defined"%>"
+ +

+ +<% for _, var in ipairs { "script_file", "script_path", "script_pdir", "script_vdir", "script_vpath", "urlpath", } do %> + +<% end %> +
<%= var %>="<%= cgilua[var] %>"
+ +

diff --git a/circuitpython/lib/axtls/www/test_dir/bin/.htaccess b/circuitpython/lib/axtls/www/test_dir/bin/.htaccess new file mode 100644 index 0000000..8fd8c46 --- /dev/null +++ b/circuitpython/lib/axtls/www/test_dir/bin/.htaccess @@ -0,0 +1 @@ +Deny all diff --git a/circuitpython/lib/axtls/www/test_dir/no_http/.htaccess b/circuitpython/lib/axtls/www/test_dir/no_http/.htaccess new file mode 100644 index 0000000..3e20076 --- /dev/null +++ b/circuitpython/lib/axtls/www/test_dir/no_http/.htaccess @@ -0,0 +1 @@ +SSLRequireSSL diff --git a/circuitpython/lib/axtls/www/test_dir/no_http/.htpasswd b/circuitpython/lib/axtls/www/test_dir/no_http/.htpasswd new file mode 100644 index 0000000..0471b01 --- /dev/null +++ b/circuitpython/lib/axtls/www/test_dir/no_http/.htpasswd @@ -0,0 +1,2 @@ +abcd:CQhgDPyy0rvEU8OMxnQIvg==$YdJfIKZimFLYxPf/rbnhtQ== +yaya:Syuss5jE2FNGVdr0kKGoHg==$WLw/SgHZFuAoOuml3GTJVw== diff --git a/circuitpython/lib/axtls/www/test_dir/no_http/index.html b/circuitpython/lib/axtls/www/test_dir/no_http/index.html new file mode 100644 index 0000000..8b86eba --- /dev/null +++ b/circuitpython/lib/axtls/www/test_dir/no_http/index.html @@ -0,0 +1,6 @@ + +axhttpd is running + +Looks like you got to this directory. + + diff --git a/circuitpython/lib/axtls/www/test_dir/no_ssl/.htaccess b/circuitpython/lib/axtls/www/test_dir/no_ssl/.htaccess new file mode 100644 index 0000000..d980d26 --- /dev/null +++ b/circuitpython/lib/axtls/www/test_dir/no_ssl/.htaccess @@ -0,0 +1 @@ +SSLDenySSL diff --git a/circuitpython/lib/axtls/www/test_dir/no_ssl/index.html b/circuitpython/lib/axtls/www/test_dir/no_ssl/index.html new file mode 100644 index 0000000..8b86eba --- /dev/null +++ b/circuitpython/lib/axtls/www/test_dir/no_ssl/index.html @@ -0,0 +1,6 @@ + +axhttpd is running + +Looks like you got to this directory. + + diff --git a/circuitpython/lib/berkeley-db-1.xx/Makefile.inc b/circuitpython/lib/berkeley-db-1.xx/Makefile.inc new file mode 100644 index 0000000..77af9c5 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/Makefile.inc @@ -0,0 +1,10 @@ +# @(#)Makefile.inc 8.2 (Berkeley) 2/21/94 +# +CFLAGS+=-D__DBINTERFACE_PRIVATE + +.include "${.CURDIR}/db/btree/Makefile.inc" +.include "${.CURDIR}/db/db/Makefile.inc" +.include "${.CURDIR}/db/hash/Makefile.inc" +.include "${.CURDIR}/db/man/Makefile.inc" +.include "${.CURDIR}/db/mpool/Makefile.inc" +.include "${.CURDIR}/db/recno/Makefile.inc" diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/Makefile new file mode 100644 index 0000000..383b259 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/README b/circuitpython/lib/berkeley-db-1.xx/PORT/README new file mode 100644 index 0000000..6d47281 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/README @@ -0,0 +1,131 @@ +# @(#)README 8.6 (Berkeley) 6/20/94 + +This is the area for building the libdb library. There are a number +of porting directories, for various architecture/OS combinations. Pick +the one that's closest to yours and try "make". For the rest of this +file, I'll use "MACH" as a fake architecture/OS name. + +To PORT to a new system, create the following subdirectories and +symbolic links. + + mkdir MACH (for example: mkdir sunos.4.0) + cd MACH + cp ../Makefile . + chmod 664 Makefile + ln -s ../clib . + mkdir include + ln -s include sys + cd include + ln -s ../../include/*.h . + rm compat.h + cp ../../include/compat.h . + chmod 664 compat.h + cd .. + +The basic idea is that you now have a local area that you can modify. +In particular, you have local copies of the Makefile and the include +file compat.h. Read through the Makefile and compat.h and make whatever +changes are appropriate to your system. If there's an architecture +that's close to yours, you probably should diff the Makefile and +compat.h in that tree against the standard ones and see what changes +were necessary, as they're probably necessary for you as well. Then, +enter "make" and see what happens! + +There are several subroutines that are found in POSIX 1003.2, ANSI +C, or 4.4BSD that you may not have. Once you get libdb.a to compile, +go through the list of undefined routines and add entries to the MISC +line in the Makefile as necessary. + +If you have to add some functions that are missing (and which aren't +in the PORT/clib directory), please don't add them in the PORT/clib +directory. Add them in a MACH/local directory, and add lines of the +form: + + function.o: local/function.o + ${CL} -Ilocal local/function.o + +to your local Makefile. + +Hopefully, over time, we'll develop a set of system directories that +are known to work. If you send me the changes that were necessary to +make your system work, this will happen much more quickly. + +In some of the system directories, you'll see a file named OTHER_PATCHES. +This is a set of patches which you'll have to make from the top-level db +directory to get libdb.a to run on this system: + + cd .. + patch < PORT/MACH/OTHER_PATCHES + +If patch prompts you for the name of the file to modify (some versions +of patch don't figure it out on their own) use the file name which patch +displays. + +Some knobs you may have to turn: + +In include/db.h: + Before attempting to build libdb, you should look through the + db.h file, and adjust it as necessary for your system. The + only adjustments that you should need to make are for the + fixed sized typedef's at the top of the file. Make sure they're + right for your system. + +In include/compat.h: + Before attempting to build libdb, you should look through the + compat.h file, and adjust it as necessary for your system. + It's possible to use the #ifndef construct to figure out if a + #ifdef has been set, but C provides no similar method to figure + out if a typedef has been done. Your compile errors should + give you a good indication of which ones you need. + +You may see warning messages about illegal pointer combinations. You may +also see lots of warning messages about #define's being redefined. These +can mostly be ignored. I usually ignore warning messages until something +doesn't work. Some systems produce thousands of lines of useless warnings, +bless their little hearts. + +The other parts of the PORT directory are as follows: + + The directory PORT/clib is a set of functions that the 4.4BSD + C library had and which your system may not have. They are + added to the MISC line of the Makefile if they aren't defined + when you try and load libdb.a. + + The directory PORT/include is header files that the 4.4BSD + system had which your system may not have. There is also + one really important extra one, named compat.h, which is a + set of compatibility work-arounds that you'll almost certainly + have to copy and modify for a new system. + + The symbolic link PORT/sys points to the PORT/include directory + so that includes of the form work. + +Some of the more common portability problems: + + If you don't have: + + memmove(3): add memmove.o + mkstemp(3): add mktemp.o + + ... to the MISC line in the Makefile. + + If you don't have snprintf/vsnprintf(3), add snprintf.o to the + MISC line in the Makefile. This workaround depends on your + system having vsprintf(3) -- if you don't, there's no workaround + other than changing the source code to not use the snprintf calls. + If you have to make that change, check to see if your vsprintf + returns a length or a char *; if it's the latter, make sure you + set VSPRINTF_CHARSTAR in the MACH/include/compat.h file. + +Installing the DB library: + + The Makefile builds a C library named libdb.a. This file needs + to be installed in a place where the loader will automatically + look for it (or, if you're building it for a single project, + wherever that project's Makefile loads it from). + + In addition, the header file PORT/include/db.h must be copied to + a directory (often /usr/include/) where programs that use the + db package can include it in their source. (If you intend to use + the ndbm interface to libdb, you'll need to copy the header file + PORT/include/ndbm.h as well.) diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/Makefile new file mode 100644 index 0000000..85b09a7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/compat.h new file mode 100644 index 0000000..2bd360a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/aix.3.2/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/compat.h new file mode 120000 index 0000000..c626d51 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/compat.h @@ -0,0 +1 @@ +../../include/compat.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/db.h new file mode 100644 index 0000000..cae13f9 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/db.h @@ -0,0 +1,222 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)db.h 8.6 (Berkeley) 6/16/94 + */ + +#ifndef _DB_H_ +#define _DB_H_ + +#include +#include + +#include + +#ifdef __DBINTERFACE_PRIVATE +#include +#endif + +#define RET_ERROR -1 /* Return values. */ +#define RET_SUCCESS 0 +#define RET_SPECIAL 1 + +#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ +typedef u_int32_t pgno_t; +#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ +typedef u_int16_t indx_t; +#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */ +typedef u_int32_t recno_t; + +/* Key/data structure -- a Data-Base Thang. */ +typedef struct { + void *data; /* data */ + size_t size; /* data length */ +} DBT; + +/* Routine flags. */ +#define R_CURSOR 1 /* del, put, seq */ +#define __R_UNUSED 2 /* UNUSED */ +#define R_FIRST 3 /* seq */ +#define R_IAFTER 4 /* put (RECNO) */ +#define R_IBEFORE 5 /* put (RECNO) */ +#define R_LAST 6 /* seq (BTREE, RECNO) */ +#define R_NEXT 7 /* seq */ +#define R_NOOVERWRITE 8 /* put */ +#define R_PREV 9 /* seq (BTREE, RECNO) */ +#define R_SETCURSOR 10 /* put (RECNO) */ +#define R_RECNOSYNC 11 /* sync (RECNO) */ + +typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; + +/* + * !!! + * The following flags are included in the dbopen(3) call as part of the + * open(2) flags. In order to avoid conflicts with the open flags, start + * at the top of the 16 or 32-bit number space and work our way down. If + * the open flags were significantly expanded in the future, it could be + * a problem. Wish I'd left another flags word in the dbopen call. + * + * !!! + * None of this stuff is implemented yet. The only reason that it's here + * is so that the access methods can skip copying the key/data pair when + * the DB_LOCK flag isn't set. + */ +#if UINT_MAX > 65535 +#define DB_LOCK 0x20000000 /* Do locking. */ +#define DB_SHMEM 0x40000000 /* Use shared memory. */ +#define DB_TXN 0x80000000 /* Do transactions. */ +#else +#define DB_LOCK 0x2000 /* Do locking. */ +#define DB_SHMEM 0x4000 /* Use shared memory. */ +#define DB_TXN 0x8000 /* Do transactions. */ +#endif + +/* Access method description structure. */ +typedef struct __db { + DBTYPE type; /* Underlying db type. */ + int (*close) __P((struct __db *)); + int (*del) __P((const struct __db *, const DBT *, u_int)); + int (*get) __P((const struct __db *, const DBT *, DBT *, u_int)); + int (*put) __P((const struct __db *, DBT *, const DBT *, u_int)); + int (*seq) __P((const struct __db *, DBT *, DBT *, u_int)); + int (*sync) __P((const struct __db *, u_int)); + void *internal; /* Access method private. */ + int (*fd) __P((const struct __db *)); +} DB; + +#define BTREEMAGIC 0x053162 +#define BTREEVERSION 3 + +/* Structure used to pass parameters to the btree routines. */ +typedef struct { +#define R_DUP 0x01 /* duplicate keys */ + u_long flags; + u_int cachesize; /* bytes to cache */ + int maxkeypage; /* maximum keys per page */ + int minkeypage; /* minimum keys per page */ + u_int psize; /* page size */ + int (*compare) /* comparison function */ + __P((const DBT *, const DBT *)); + size_t (*prefix) /* prefix function */ + __P((const DBT *, const DBT *)); + int lorder; /* byte order */ +} BTREEINFO; + +#define HASHMAGIC 0x061561 +#define HASHVERSION 2 + +/* Structure used to pass parameters to the hashing routines. */ +typedef struct { + u_int bsize; /* bucket size */ + u_int ffactor; /* fill factor */ + u_int nelem; /* number of elements */ + u_int cachesize; /* bytes to cache */ + u_int32_t /* hash function */ + (*hash) __P((const void *, size_t)); + int lorder; /* byte order */ +} HASHINFO; + +/* Structure used to pass parameters to the record routines. */ +typedef struct { +#define R_FIXEDLEN 0x01 /* fixed-length records */ +#define R_NOKEY 0x02 /* key not required */ +#define R_SNAPSHOT 0x04 /* snapshot the input */ + u_long flags; + u_int cachesize; /* bytes to cache */ + u_int psize; /* page size */ + int lorder; /* byte order */ + size_t reclen; /* record length (fixed-length records) */ + u_char bval; /* delimiting byte (variable-length records */ + char *bfname; /* btree file name */ +} RECNOINFO; + +#ifdef __DBINTERFACE_PRIVATE +/* + * Little endian <==> big endian 32-bit swap macros. + * M_32_SWAP swap a memory location + * P_32_SWAP swap a referenced memory location + * P_32_COPY swap from one location to another + */ +#define M_32_SWAP(a) { \ + u_int32_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[3]; \ + ((char *)&a)[1] = ((char *)&_tmp)[2]; \ + ((char *)&a)[2] = ((char *)&_tmp)[1]; \ + ((char *)&a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_SWAP(a) { \ + u_int32_t _tmp = *(u_int32_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[3]; \ + ((char *)a)[1] = ((char *)&_tmp)[2]; \ + ((char *)a)[2] = ((char *)&_tmp)[1]; \ + ((char *)a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[3]; \ + ((char *)&(b))[1] = ((char *)&(a))[2]; \ + ((char *)&(b))[2] = ((char *)&(a))[1]; \ + ((char *)&(b))[3] = ((char *)&(a))[0]; \ +} + +/* + * Little endian <==> big endian 16-bit swap macros. + * M_16_SWAP swap a memory location + * P_16_SWAP swap a referenced memory location + * P_16_COPY swap from one location to another + */ +#define M_16_SWAP(a) { \ + u_int16_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[1]; \ + ((char *)&a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_SWAP(a) { \ + u_int16_t _tmp = *(u_int16_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[1]; \ + ((char *)a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[1]; \ + ((char *)&(b))[1] = ((char *)&(a))[0]; \ +} +#endif + +__BEGIN_DECLS +DB *dbopen __P((const char *, int, int, DBTYPE, const void *)); + +#ifdef __DBINTERFACE_PRIVATE +DB *__bt_open __P((const char *, int, int, const BTREEINFO *, int)); +DB *__hash_open __P((const char *, int, int, const HASHINFO *, int)); +DB *__rec_open __P((const char *, int, int, const RECNOINFO *, int)); +void __dbpanic __P((DB *dbp)); +#endif +__END_DECLS +#endif /* !_DB_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsd.4.4/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/OTHER_PATCHES b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/OTHER_PATCHES new file mode 100644 index 0000000..85027c9 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/OTHER_PATCHES @@ -0,0 +1,19 @@ +*** PORT/db/recno/rec_open.c.orig Mon Aug 16 16:29:18 1993 +--- PORT/db/recno/rec_open.c Mon Aug 16 16:29:35 1993 +*************** +*** 159,165 **** + else { + t->bt_msize = sb.st_size; + if ((t->bt_smap = mmap(NULL, t->bt_msize, +! PROT_READ, MAP_PRIVATE, rfd, + (off_t)0)) == (caddr_t)-1) + goto slow; + t->bt_cmap = t->bt_smap; +--- 159,165 ---- + else { + t->bt_msize = sb.st_size; + if ((t->bt_smap = mmap(NULL, t->bt_msize, +! PROT_READ, MAP_FILE | MAP_PRIVATE, rfd, + (off_t)0)) == (caddr_t)-1) + goto slow; + t->bt_cmap = t->bt_smap; diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/assert.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/assert.h new file mode 100644 index 0000000..f455fe8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/assert.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)assert.h 4.4 (Berkeley) 4/3/91 + */ + +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#ifdef NDEBUG +#define assert(expression) +#define _assert(expression) +#else +#define assert(expression) { \ + if (!(expression)) { \ + (void)fprintf(stderr, \ + "assertion \"%s\" failed: file \"%s\", line %d\n", \ + "expression", __FILE__, __LINE__); \ + exit(2); \ + } \ +} +#define _assert(expression) assert(expression) +#endif + +#endif /* !_ASSERT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/compat.h new file mode 100644 index 0000000..ae735ef --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER LITTLE_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/local.h b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/local.h new file mode 100644 index 0000000..21966d7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/local.h @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)local.h 5.3 (Berkeley) 5/6/93 + */ + +/* + * Information local to this implementation of stdio, + * in particular, macros and private variables. + */ + +int __sflush __P((FILE *)); +FILE *__sfp __P((void)); +int __srefill __P((FILE *)); +int __sread __P((void *, char *, int)); +int __swrite __P((void *, char const *, int)); +fpos_t __sseek __P((void *, fpos_t, int)); +int __sclose __P((void *)); +void __sinit __P((void)); +void _cleanup __P((void)); +void (*__cleanup) __P((void)); +void __smakebuf __P((FILE *)); +int __swhatbuf __P((FILE *, size_t *, int *)); +int _fwalk __P((int (*)(FILE *))); +int __swsetup __P((FILE *)); +int __sflags __P((const char *, int *)); + +extern int __sdidinit; + +/* + * Return true iff the given FILE cannot be written now. + */ +#define cantwrite(fp) \ + ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \ + __swsetup(fp)) + +/* + * Test whether the given stdio file has an active ungetc buffer; + * release such a buffer, without restoring ordinary unread data. + */ +#define HASUB(fp) ((fp)->_ub._base != NULL) +#define FREEUB(fp) { \ + if ((fp)->_ub._base != (fp)->_ubuf) \ + free((char *)(fp)->_ub._base); \ + (fp)->_ub._base = NULL; \ +} + +/* + * test for an fgetline() buffer. + */ +#define HASLB(fp) ((fp)->_lb._base != NULL) +#define FREELB(fp) { \ + free((char *)(fp)->_lb._base); \ + (fp)->_lb._base = NULL; \ +} diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/makebuf.c b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/makebuf.c new file mode 100644 index 0000000..cb87e60 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/makebuf.c @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)makebuf.c 5.3 (Berkeley) 5/6/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include "local.h" + +/* + * Allocate a file buffer, or switch to unbuffered I/O. + * Per the ANSI C standard, ALL tty devices default to line buffered. + * + * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek + * optimisation) right after the fstat() that finds the buffer size. + */ +void +__smakebuf(fp) + register FILE *fp; +{ + register void *p; + register int flags; + size_t size; + int couldbetty; + + if (fp->_flags & __SNBF) { + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + return; + } + flags = __swhatbuf(fp, &size, &couldbetty); + if ((p = malloc(size)) == NULL) { + fp->_flags |= __SNBF; + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + return; + } + __cleanup = _cleanup; + flags |= __SMBF; + fp->_bf._base = fp->_p = p; + fp->_bf._size = size; + if (couldbetty && isatty(fp->_file)) + flags |= __SLBF; + fp->_flags |= flags; +} + +/* + * Internal routine to determine `proper' buffering for a file. + */ +int +__swhatbuf(fp, bufsize, couldbetty) + register FILE *fp; + size_t *bufsize; + int *couldbetty; +{ + struct stat st; + + if (fp->_file < 0 || fstat(fp->_file, &st) < 0) { + *couldbetty = 0; + *bufsize = BUFSIZ; + return (__SNPT); + } + + /* could be a tty iff it is a character device */ + *couldbetty = (st.st_mode & S_IFMT) == S_IFCHR; + if (st.st_blksize <= 0) { + *bufsize = BUFSIZ; + return (__SNPT); + } + + /* + * Optimise fseek() only if it is a regular file. (The test for + * __sseek is mainly paranoia.) It is safe to set _blksize + * unconditionally; it will only be used if __SOPT is also set. + */ + *bufsize = st.st_blksize; + fp->_blksize = st.st_blksize; + return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ? + __SOPT : __SNPT); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/setvbuf.c b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/setvbuf.c new file mode 100644 index 0000000..41bb16b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/local/setvbuf.c @@ -0,0 +1,148 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +! static char sccsid[] = "@(#)setvbuf.c 5.5 (Berkeley) 5/6/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include "local.h" + +/* + * Set one of the three kinds of buffering, optionally including + * a buffer. + */ +setvbuf(fp, buf, mode, size) + register FILE *fp; + char *buf; + register int mode; + register size_t size; +{ + register int ret, flags; + size_t iosize; + int ttyflag; + + /* + * Verify arguments. The `int' limit on `size' is due to this + * particular implementation. Note, buf and size are ignored + * when setting _IONBF. + */ + if (mode != _IONBF) + if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) + return (EOF); + + /* + * Write current buffer, if any. Discard unread input, cancel + * line buffering, and free old buffer if malloc()ed. + */ + ret = 0; + (void)__sflush(fp); + fp->_r = fp->_lbfsize = 0; + flags = fp->_flags; + if (flags & __SMBF) + free((void *)fp->_bf._base); + flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT); + + /* If setting unbuffered mode, skip all the hard work. */ + if (mode == _IONBF) + goto nbf; + + /* + * Find optimal I/O size for seek optimization. This also returns + * a `tty flag' to suggest that we check isatty(fd), but we do not + * care since our caller told us how to buffer. + */ + flags |= __swhatbuf(fp, &iosize, &ttyflag); + if (size == 0) { + buf = NULL; /* force local allocation */ + size = iosize; + } + + /* Allocate buffer if needed. */ + if (buf == NULL) { + if ((buf = malloc(size)) == NULL) { + /* + * Unable to honor user's request. We will return + * failure, but try again with file system size. + */ + ret = EOF; + if (size != iosize) { + size = iosize; + buf = malloc(size); + } + } + if (buf == NULL) { + /* No luck; switch to unbuffered I/O. */ +nbf: + fp->_flags = flags | __SNBF; + fp->_w = 0; + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + return (ret); + } + flags |= __SMBF; + } + + /* + * Kill any seek optimization if the buffer is not the + * right size. + * + * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)? + */ + if (size != iosize) + flags |= __SNPT; + + /* + * Fix up the FILE fields, and set __cleanup for output flush on + * exit (since we are buffered in some way). If in r/w mode, go + * to the intermediate state, so that everyone has to call + * __srefill or __swsetup on the first operation -- it is more + * trouble than it is worth to set things up correctly here. + */ + if (mode == _IOLBF) + flags |= __SLBF; + if (flags & __SRW) + flags &= ~(__SRD | __SWR); + fp->_w = 0; + fp->_flags = flags; + fp->_bf._base = fp->_p = (unsigned char *)buf; + fp->_bf._size = size; + fp->_lbfsize = 0; + __cleanup = _cleanup; + + return (ret); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/bsdi.1.0/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/clib/memmove.c b/circuitpython/lib/berkeley-db-1.xx/PORT/clib/memmove.c new file mode 100644 index 0000000..f90b09c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/clib/memmove.c @@ -0,0 +1,139 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * sizeof(word) MUST BE A POWER OF TWO + * SO THAT wmask BELOW IS ALL ONES + */ +typedef int word; /* "word" used for optimal copy speed */ + +#define wsize sizeof(word) +#define wmask (wsize - 1) + +/* + * Copy a block of memory, handling overlap. + * This is the routine that actually implements + * (the portable versions of) bcopy, memcpy, and memmove. + */ +#ifdef MEMCOPY +void * +memcpy(dst0, src0, length) +#else +#ifdef MEMMOVE +void * +memmove(dst0, src0, length) +#else +void +bcopy(src0, dst0, length) +#endif +#endif + void *dst0; + const void *src0; + register size_t length; +{ + register char *dst = dst0; + register const char *src = src0; + register size_t t; + + if (length == 0 || dst == src) /* nothing to do */ + goto done; + + /* + * Macros: loop-t-times; and loop-t-times, t>0 + */ +#define TLOOP(s) if (t) TLOOP1(s) +#define TLOOP1(s) do { s; } while (--t) + + if ((unsigned long)dst < (unsigned long)src) { + /* + * Copy forward. + */ + t = (int)src; /* only need low bits */ + if ((t | (int)dst) & wmask) { + /* + * Try to align operands. This cannot be done + * unless the low bits match. + */ + if ((t ^ (int)dst) & wmask || length < wsize) + t = length; + else + t = wsize - (t & wmask); + length -= t; + TLOOP1(*dst++ = *src++); + } + /* + * Copy whole words, then mop up any trailing bytes. + */ + t = length / wsize; + TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); + t = length & wmask; + TLOOP(*dst++ = *src++); + } else { + /* + * Copy backwards. Otherwise essentially the same. + * Alignment works as before, except that it takes + * (t&wmask) bytes to align, not wsize-(t&wmask). + */ + src += length; + dst += length; + t = (int)src; + if ((t | (int)dst) & wmask) { + if ((t ^ (int)dst) & wmask || length <= wsize) + t = length; + else + t &= wmask; + length -= t; + TLOOP1(*--dst = *--src); + } + t = length / wsize; + TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); + t = length & wmask; + TLOOP(*--dst = *--src); + } +done: +#if defined(MEMCOPY) || defined(MEMMOVE) + return (dst0); +#else + return; +#endif +} diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/clib/mktemp.c b/circuitpython/lib/berkeley-db-1.xx/PORT/clib/mktemp.c new file mode 100644 index 0000000..6cedd6a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/clib/mktemp.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +static int _gettemp(); + +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd) ? fd : -1); +} + +char * +mktemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); +} + +static +_gettemp(path, doopen) + char *path; + register int *doopen; +{ + extern int errno; + register char *start, *trv; + struct stat sbuf; + u_int pid; + + pid = getpid(); + for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + if (stat(path, &sbuf)) + return(0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return(0); + } + *trv = '/'; + break; + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return(1); + if (errno != EEXIST) + return(0); + } + else if (stat(path, &sbuf)) + return(errno == ENOENT ? 1 : 0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return(0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit(*trv)) + *trv = 'a'; + else + ++*trv; + break; + } + } + } + /*NOTREACHED*/ +} diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/clib/snprintf.c b/circuitpython/lib/berkeley-db-1.xx/PORT/clib/snprintf.c new file mode 100644 index 0000000..2863fa2 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/clib/snprintf.c @@ -0,0 +1,54 @@ +#include +#include + +#include + +#ifdef __STDC__ +#include +#else +#include +#endif + +int +#ifdef __STDC__ +snprintf(char *str, size_t n, const char *fmt, ...) +#else +snprintf(str, n, fmt, va_alist) + char *str; + size_t n; + const char *fmt; + va_dcl +#endif +{ + va_list ap; + char *rp; + int rval; +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif +#ifdef VSPRINTF_CHARSTAR + rp = vsprintf(str, fmt, ap); + va_end(ap); + return (strlen(rp)); +#else + rval = vsprintf(str, fmt, ap); + va_end(ap); + return (rval); +#endif +} + +int +vsnprintf(str, n, fmt, ap) + char *str; + size_t n; + const char *fmt; + va_list ap; +{ +#ifdef VSPRINTF_CHARSTAR + return (strlen(vsprintf(str, fmt, ap))); +#else + return (vsprintf(str, fmt, ap)); +#endif +} diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/clib/strerror.c b/circuitpython/lib/berkeley-db-1.xx/PORT/clib/strerror.c new file mode 100644 index 0000000..53f374b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/clib/strerror.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include + +char * +strerror(num) + int num; +{ + extern int sys_nerr; + extern char *sys_errlist[]; +#define UPREFIX "Unknown error: " + static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ + register unsigned int errnum; + register char *p, *t; + char tmp[40]; + + errnum = num; /* convert to unsigned */ + if (errnum < sys_nerr) + return(sys_errlist[errnum]); + + /* Do this by hand, so we don't include stdio(3). */ + t = tmp; + do { + *t++ = "0123456789"[errnum % 10]; + } while (errnum /= 10); + for (p = ebuf + sizeof(UPREFIX) - 1;;) { + *p++ = *--t; + if (t <= tmp) + break; + } + return(ebuf); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/Makefile new file mode 100644 index 0000000..4053c4b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/Makefile @@ -0,0 +1,103 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +CC= gcc +OORG= -O2 +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/compat.h new file mode 100644 index 0000000..2bd360a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/dgux.5.4/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.8.07 b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.8.07 new file mode 120000 index 0000000..e634b1f --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.8.07 @@ -0,0 +1 @@ +hpux.9.01 \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/Makefile new file mode 100644 index 0000000..85b09a7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/compat.h new file mode 100644 index 0000000..2bd360a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/local/hp_siglist.c b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/local/hp_siglist.c new file mode 100644 index 0000000..e65083b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/local/hp_siglist.c @@ -0,0 +1,75 @@ +/* + * Derived from: + * static char sccsid[] = "@(#)siglist.c 8.1 (Berkeley) 6/4/93"; + */ +#include + +#include + +const char *const sys_signame[NSIG] = { + "Signal 0", + "hup", /* SIGHUP */ + "int", /* SIGINT */ + "quit", /* SIGQUIT */ + "ill", /* SIGILL */ + "trap", /* SIGTRAP */ + "abrt", /* SIGABRT */ + "emt", /* SIGEMT */ + "fpe", /* SIGFPE */ + "kill", /* SIGKILL */ + "bus", /* SIGBUS */ + "segv", /* SIGSEGV */ + "sys", /* SIGSYS */ + "pipe", /* SIGPIPE */ + "alrm", /* SIGALRM */ + "term", /* SIGTERM */ + "usr1", /* SIGUSR1 */ + "usr2", /* SIGUSR2 */ + "chld", /* SIGCHLD */ + "pwr", /* SIGPWR */ + "vtalrm", /* SIGVTALRM */ + "prof", /* SIGPROF */ + "io", /* SIGIO */ + "winch", /* SIGWINCH */ + "stop", /* SIGSTOP */ + "tstp", /* SIGTSTP */ + "cont", /* SIGCONT */ + "ttin", /* SIGTTIN */ + "ttou", /* SIGTTOU */ + "urg", /* SIGURG */ + "lost", /* SIGLOST */ +}; + +const char *const sys_siglist[NSIG] = { + "Signal 0", + "Hangup", /* SIGHUP */ + "Interrupt", /* SIGINT */ + "Quit", /* SIGQUIT */ + "Illegal instruction", /* SIGILL */ + "Trace/BPT trap", /* SIGTRAP */ + "Abort trap", /* SIGABRT */ + "EMT trap", /* SIGEMT */ + "Floating point exception", /* SIGFPE */ + "Killed", /* SIGKILL */ + "Bus error", /* SIGBUS */ + "Segmentation fault", /* SIGSEGV */ + "Bad system call", /* SIGSYS */ + "Broken pipe", /* SIGPIPE */ + "Alarm clock", /* SIGALRM */ + "Terminated", /* SIGTERM */ + "User defined signal 1", /* SIGUSR1 */ + "User defined signal 2" /* SIGUSR2 */ + "Child exited", /* SIGCHLD */ + "Power failure", /* SIGPWR */ + "Virtual timer expired", /* SIGVTALRM */ + "Profiling timer expired", /* SIGPROF */ + "I/O possible", /* SIGIO */ + "Window size changes", /* SIGWINCH */ + "Suspended (signal)", /* SIGSTOP */ + "Suspended", /* SIGTSTP */ + "Continued", /* SIGCONT */ + "Stopped (tty input)", /* SIGTTIN */ + "Stopped (tty output)", /* SIGTTOU */ + "Urgent I/O condition", /* SIGURG */ + "File lock lost", /* SIGLOST */ +}; diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/hpux.9.01/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/include/bsd-queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/include/bsd-queue.h new file mode 120000 index 0000000..f28ad5d --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/include/bsd-queue.h @@ -0,0 +1 @@ +queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/include/cdefs.h new file mode 100644 index 0000000..c104b9e --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/include/cdefs.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Berkeley Software Design, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)cdefs.h 8.7 (Berkeley) 1/21/94 + */ + +#ifndef _CDEFS_H_ +#define _CDEFS_H_ + +#if defined(__cplusplus) +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS }; +#else +#define __BEGIN_DECLS +#define __END_DECLS +#endif + +/* + * The __CONCAT macro is used to concatenate parts of symbol names, e.g. + * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. + * The __CONCAT macro is a bit tricky -- make sure you don't put spaces + * in between its arguments. __CONCAT can also concatenate double-quoted + * strings produced by the __STRING macro, but this only works with ANSI C. + */ +#if defined(__STDC__) || defined(__cplusplus) +#define __P(protos) protos /* full-blown ANSI C */ +#define __CONCAT(x,y) x ## y +#define __STRING(x) #x + +#define __const const /* define reserved names to standard */ +#define __signed signed +#define __volatile volatile +#if defined(__cplusplus) +#define __inline inline /* convert to C++ keyword */ +#else +#ifndef __GNUC__ +#define __inline /* delete GCC keyword */ +#endif /* !__GNUC__ */ +#endif /* !__cplusplus */ + +#else /* !(__STDC__ || __cplusplus) */ +#define __P(protos) () /* traditional C preprocessor */ +#define __CONCAT(x,y) x/**/y +#define __STRING(x) "x" + +#ifndef __GNUC__ +#define __const /* delete pseudo-ANSI C keywords */ +#define __inline +#define __signed +#define __volatile +/* + * In non-ANSI C environments, new programs will want ANSI-only C keywords + * deleted from the program and old programs will want them left alone. + * When using a compiler other than gcc, programs using the ANSI C keywords + * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS. + * When using "gcc -traditional", we assume that this is the intent; if + * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone. + */ +#ifndef NO_ANSI_KEYWORDS +#define const /* delete ANSI C keywords */ +#define inline +#define signed +#define volatile +#endif +#endif /* !__GNUC__ */ +#endif /* !(__STDC__ || __cplusplus) */ + +/* + * GCC1 and some versions of GCC2 declare dead (non-returning) and + * pure (no side effects) functions using "volatile" and "const"; + * unfortunately, these then cause warnings under "-ansi -pedantic". + * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of + * these work for GNU C++ (modulo a slight glitch in the C++ grammar + * in the distribution version of 2.5.5). + */ +#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 5 +#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define __dead __volatile +#define __pure __const +#endif +#endif + +/* Delete pseudo-keywords wherever they are not available or needed. */ +#ifndef __dead +#define __dead +#define __pure +#endif + +#endif /* !_CDEFS_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/include/compat.h new file mode 100644 index 0000000..30cf88d --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/include/compat.h @@ -0,0 +1,233 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#ifndef memmove +#define memmove(a, b, n) bcopy(b, a, n) +#endif +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/include/filevtable.h b/circuitpython/lib/berkeley-db-1.xx/PORT/include/filevtable.h new file mode 120000 index 0000000..25306d1 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/include/filevtable.h @@ -0,0 +1 @@ +../../include/filevtable.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/include/ndbm.h new file mode 100644 index 0000000..a545bca --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/include/ndbm.h @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)ndbm.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _NDBM_H_ +#define _NDBM_H_ + +#include + +/* Map dbm interface onto db(3). */ +#define DBM_RDONLY O_RDONLY + +/* Flags to dbm_store(). */ +#define DBM_INSERT 0 +#define DBM_REPLACE 1 + +/* + * The db(3) support for ndbm(3) always appends this suffix to the + * file name to avoid overwriting the user's original database. + */ +#define DBM_SUFFIX ".db" + +typedef struct { + char *dptr; + int dsize; +} datum; + +typedef DB DBM; +#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE + +__BEGIN_DECLS +void dbm_close __P((DBM *)); +int dbm_delete __P((DBM *, datum)); +datum dbm_fetch __P((DBM *, datum)); +datum dbm_firstkey __P((DBM *)); +long dbm_forder __P((DBM *, datum)); +datum dbm_nextkey __P((DBM *)); +DBM *dbm_open __P((const char *, int, int)); +int dbm_store __P((DBM *, datum, datum, int)); +int dbm_dirfno __P((DBM *)); +__END_DECLS + +#endif /* !_NDBM_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/include/queue.h new file mode 100644 index 0000000..40d32cc --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/include/queue.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)queue.h 8.3 (Berkeley) 12/13/93 + */ + +#ifndef _QUEUE_H_ +#define _QUEUE_H_ + +/* + * This file defines three types of data structures: lists, tail queues, + * and circular queues. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list after + * an existing element or at the head of the list. A list may only be + * traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list after + * an existing element, at the head of the list, or at the end of the + * list. A tail queue may only be traversed in the forward direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ +#define LIST_INIT(head) { \ + (head)->lh_first = NULL; \ +} + +#define LIST_INSERT_AFTER(listelm, elm, field) { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} + +#define LIST_INSERT_HEAD(head, elm, field) { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} + +#define LIST_REMOVE(elm, field) { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ +} + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_INIT(head) { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} + +#define TAILQ_INSERT_HEAD(head, elm, field) { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} + +#define TAILQ_INSERT_TAIL(head, elm, field) { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} + +#define TAILQ_REMOVE(head, elm, field) { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue functions. + */ +#define CIRCLEQ_INIT(head) { \ + (head)->cqh_first = (void *)(head); \ + (head)->cqh_last = (void *)(head); \ +} + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = (void *)(head); \ + if ((head)->cqh_last == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) { \ + (elm)->field.cqe_next = (void *)(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} + +#define CIRCLEQ_REMOVE(head, elm, field) { \ + if ((elm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} +#endif /* !_QUEUE_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/Makefile new file mode 100644 index 0000000..1775095 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/Makefile @@ -0,0 +1,103 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +CC= cc -cckr -D_BSD_COMPAT +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/OTHER_PATCHES b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/OTHER_PATCHES new file mode 100644 index 0000000..46c624b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/OTHER_PATCHES @@ -0,0 +1,32 @@ +*** PORT/db/btree/bt_open.c.dist Thu Sep 16 14:42:22 1993 +--- PORT/db/btree/bt_open.c Mon Nov 8 07:03:40 1993 +*************** +*** 256,262 **** +--- 256,266 ---- + * Don't overflow the page offset type. + */ + if (b.psize == 0) { ++ #ifndef sgi + b.psize = sb.st_blksize; ++ #else ++ b.psize = 4096; ++ #endif /* sgi */ + if (b.psize < MINPSIZE) + b.psize = MINPSIZE; + if (b.psize > MAX_PAGE_OFFSET + 1) +*** PORT/db/hash/hash.c.dist Thu Nov 4 15:32:16 1993 +--- PORT/db/hash/hash.c Mon Nov 8 07:05:12 1993 +*************** +*** 301,307 **** +--- 301,311 ---- + if (file != NULL) { + if (stat(file, &statbuf)) + return (NULL); ++ #ifndef sgi + hashp->BSIZE = statbuf.st_blksize; ++ #else ++ hashp->BSIZE = 4096; ++ #endif /* sgi */ + hashp->BSHIFT = __log2(hashp->BSIZE); + } + diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/compat.h new file mode 100644 index 0000000..2bd360a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/irix.4.05F/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/linux/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/Makefile new file mode 100644 index 0000000..85b09a7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/linux/OTHER_PATCHES b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/OTHER_PATCHES new file mode 100644 index 0000000..b0387a5 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/OTHER_PATCHES @@ -0,0 +1,29 @@ +*** PORT/db/recno/rec_open.c.orig 1993/10/13 02:01:31 +--- PORT/db/recno/rec_open.c 1993/10/13 02:20:47 +*************** +*** 159,167 **** +--- 159,182 ---- + SET(t, R_EOF); + else { + t->bt_msize = sb.st_size; ++ /* ++ * hack : ++ * ++ * The Linux kernel mmap() semantics are broken : ++ * ++ * Under Linux, read only private mappings cause write only and read/write ++ * opens to fail with errno=ETXTBSY. Shared read only mappings should work ++ * fine though, but I'm not familiar enough with the code to ascertain that ++ * a MAP_SHARED mapping would be safe so I use the non-mmap'd version ++ * instead. ++ * ++ */ ++ ++ #if !defined(linux) + if ((t->bt_smap = mmap(NULL, t->bt_msize, + PROT_READ, MAP_PRIVATE, rfd, + (off_t)0)) == (caddr_t)-1) ++ #endif + goto slow; + t->bt_cmap = t->bt_smap; + t->bt_emap = t->bt_smap + sb.st_size; diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/linux/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/compat.h new file mode 100644 index 0000000..ae735ef --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER LITTLE_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/linux/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/linux/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/Makefile new file mode 100644 index 0000000..85b09a7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/compat.h new file mode 100644 index 0000000..ae735ef --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER LITTLE_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.0.2/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.3 b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.3 new file mode 120000 index 0000000..1a1d658 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.1.3 @@ -0,0 +1 @@ +osf.1.0.2 \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/osf.2.0 b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.2.0 new file mode 120000 index 0000000..1a1d658 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/osf.2.0 @@ -0,0 +1 @@ +osf.1.0.2 \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/Makefile new file mode 100644 index 0000000..e852b76 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/Makefile @@ -0,0 +1,104 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= mktemp.o snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +CC= gcc +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude \ + -DMMAP_NOT_AVAILABLE -DSTBLKSIZE_NOT_AVAILABLE -DSYS5 + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/OTHER_PATCHES b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/OTHER_PATCHES new file mode 100644 index 0000000..891cccb --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/OTHER_PATCHES @@ -0,0 +1,95 @@ +*** PORT/db/btree/bt_open.c.orig 1993/11/24 11:16:51 +--- PORT/db/btree/bt_open.c 1993/11/24 12:38:12 +*************** +*** 256,262 **** +--- 256,266 ---- + * Don't overflow the page offset type. + */ + if (b.psize == 0) { ++ #ifdef STBLKSIZE_NOT_AVAILABLE ++ b.psize = 4096; ++ #else + b.psize = sb.st_blksize; ++ #endif + if (b.psize < MINPSIZE) + b.psize = MINPSIZE; + if (b.psize > MAX_PAGE_OFFSET + 1) +*** PORT/db/recno/rec_open.c.orig 1993/11/29 18:26:26 +--- PORT/db/recno/rec_open.c 1993/11/30 11:35:21 +*************** +*** 159,164 **** +--- 159,167 ---- + SET(t, R_EOF); + else { + t->bt_msize = sb.st_size; ++ #ifdef MMAP_NOT_AVAILABLE ++ goto slow; ++ #else + if ((t->bt_smap = mmap(NULL, t->bt_msize, + PROT_READ, MAP_PRIVATE, rfd, + (off_t)0)) == (caddr_t)-1) +*************** +*** 168,173 **** +--- 171,177 ---- + t->bt_irec = ISSET(t, R_FIXLEN) ? + __rec_fmap : __rec_vmap; + SET(t, R_MEMMAPPED); ++ #endif + } + } + } +*** PORT/db/hash/hash_log2.c.orig 1993/11/24 11:10:40 +--- PORT/db/hash/hash_log2.c 1993/11/24 12:38:52 +*************** +*** 40,50 **** + + #include + +! u_int + __log2(num) +! u_int num; + { +! register u_int i, limit; + + limit = 1; + for (i = 0; limit < num; limit = limit << 1, i++); +--- 40,50 ---- + + #include + +! unsigned int + __log2(num) +! unsigned int num; + { +! register unsigned int i, limit; + + limit = 1; + for (i = 0; limit < num; limit = limit << 1, i++); +*** PORT/db/hash/hash.c.orig 1993/11/24 11:18:44 +--- PORT/db/hash/hash.c 1993/11/24 12:38:29 +*************** +*** 301,307 **** +--- 301,311 ---- + if (file != NULL) { + if (stat(file, &statbuf)) + return (NULL); ++ #ifdef STBLKSIZE_NOT_AVAILABLE ++ hashp->BSIZE = 4096; ++ #else + hashp->BSIZE = statbuf.st_blksize; ++ #endif + hashp->BSHIFT = __log2(hashp->BSIZE); + } + +*** PORT/db/hash/hash.h.orig 1993/11/24 11:20:03 +--- PORT/db/hash/hash.h 1993/11/24 12:38:38 +*************** +*** 261,266 **** +--- 261,267 ---- + #define REAL_KEY 4 + + /* Short hands for accessing structure */ ++ #undef BSIZE + #define BSIZE hdr.bsize + #define BSHIFT hdr.bshift + #define DSIZE hdr.dsize diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/compat.h new file mode 100644 index 0000000..108060d --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/compat.h @@ -0,0 +1,232 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include +#include /* For fd_set. */ + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 1 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/pathnames.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/pathnames.h new file mode 100644 index 0000000..81b9f32 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/pathnames.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)pathnames.h 8.5 (Berkeley) 12/21/93 + */ + +#define _PATH_BSHELL "/bin/sh" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_EXRC ".exrc" +#define _PATH_NEXRC ".nexrc" +#define _PATH_PRESERVE "/usr/tmp/vi.recover" +#define _PATH_SENDMAIL "/usr/lib/sendmail" +#define _PATH_SYSEXRC "/etc/vi.exrc" +#define _PATH_TAGS "tags" +#define _PATH_TMP "/tmp" +#define _PATH_TTY "/dev/tty" diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ptx.2.0/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/Makefile new file mode 100644 index 0000000..dd459ad --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= mktemp.o snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/compat.h new file mode 100644 index 0000000..2bd360a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sinix.5.41/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/solaris.2.2 b/circuitpython/lib/berkeley-db-1.xx/PORT/solaris.2.2 new file mode 120000 index 0000000..b9f1ef8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/solaris.2.2 @@ -0,0 +1 @@ +sunos.5.2 \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/Makefile new file mode 100644 index 0000000..aae1a45 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= memmove.o snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/compat.h new file mode 100644 index 0000000..62643bd --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 1 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 1 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/pathnames.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/pathnames.h new file mode 100644 index 0000000..df94cd0 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/pathnames.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)pathnames.h 8.5 (Berkeley) 12/21/93 + */ + +#define _PATH_BSHELL "/bin/sh" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_EXRC ".exrc" +#define _PATH_NEXRC ".nexrc" +#define _PATH_PRESERVE "/var/tmp/vi.recover" +#define _PATH_SENDMAIL "/usr/lib/sendmail" +#define _PATH_SYSEXRC "/etc/vi.exrc" +#define _PATH_TAGS "tags /var/db/libc.tags /sys/kern/tags" +#define _PATH_TMP "/tmp" +#define _PATH_TTY "/dev/tty" diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.1/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.2 b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.2 new file mode 120000 index 0000000..cf2aa36 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.2 @@ -0,0 +1 @@ +sunos.4.1.1 \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.3 b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.3 new file mode 120000 index 0000000..cf2aa36 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.4.1.3 @@ -0,0 +1 @@ +sunos.4.1.1 \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/Makefile new file mode 100644 index 0000000..85b09a7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/compat.h new file mode 100644 index 0000000..b302f19 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/compat.h @@ -0,0 +1,236 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +#define NO_ERRLIST + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 0 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + + +#define write _write + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/db.h new file mode 120000 index 0000000..44c1ba4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/db.h @@ -0,0 +1 @@ +../../include/db.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/sunos.5.2/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/Makefile b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/Makefile new file mode 100644 index 0000000..dd459ad --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/Makefile @@ -0,0 +1,102 @@ +# @(#)Makefile 8.9 (Berkeley) 7/14/94 + +LIBDB= libdb.a +OBJ1= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ + hsearch.o ndbm.o +OBJ2= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ + bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ + bt_utils.o +OBJ3= db.o +OBJ4= mpool.o +OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ + rec_seq.o rec_utils.o + +MISC= mktemp.o snprintf.o + +${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + rm -f $@ + ar cq $@ \ + `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` + ranlib $@ + +clean: + rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} + +OORG= -O +CL= ${CC} -c -D__DBINTERFACE_PRIVATE ${OORG} -I. -Iinclude + +hash.o: ../../hash/hash.c + ${CL} -I../../hash ../../hash/hash.c +hash_bigkey.o: ../../hash/hash_bigkey.c + ${CL} -I../../hash ../../hash/hash_bigkey.c +hash_buf.o: ../../hash/hash_buf.c + ${CL} -I../../hash ../../hash/hash_buf.c +hash_func.o: ../../hash/hash_func.c + ${CL} -I../../hash ../../hash/hash_func.c +hash_log2.o: ../../hash/hash_log2.c + ${CL} -I../../hash ../../hash/hash_log2.c +hash_page.o: ../../hash/hash_page.c + ${CL} -I../../hash ../../hash/hash_page.c +hsearch.o: ../../hash/hsearch.c + ${CL} -I../../hash ../../hash/hsearch.c +ndbm.o: ../../hash/ndbm.c + ${CL} -I../../hash ../../hash/ndbm.c + +bt_close.o: ../../btree/bt_close.c + ${CL} -I../../btree ../../btree/bt_close.c +bt_conv.o: ../../btree/bt_conv.c + ${CL} -I../../btree ../../btree/bt_conv.c +bt_debug.o: ../../btree/bt_debug.c + ${CL} -I../../btree ../../btree/bt_debug.c +bt_delete.o: ../../btree/bt_delete.c + ${CL} -I../../btree ../../btree/bt_delete.c +bt_get.o: ../../btree/bt_get.c + ${CL} -I../../btree ../../btree/bt_get.c +bt_open.o: ../../btree/bt_open.c + ${CL} -I../../btree ../../btree/bt_open.c +bt_overflow.o: ../../btree/bt_overflow.c + ${CL} -I../../btree ../../btree/bt_overflow.c +bt_page.o: ../../btree/bt_page.c + ${CL} -I../../btree ../../btree/bt_page.c +bt_put.o: ../../btree/bt_put.c + ${CL} -I../../btree ../../btree/bt_put.c +bt_search.o: ../../btree/bt_search.c + ${CL} -I../../btree ../../btree/bt_search.c +bt_seq.o: ../../btree/bt_seq.c + ${CL} -I../../btree ../../btree/bt_seq.c +bt_split.o: ../../btree/bt_split.c + ${CL} -I../../btree ../../btree/bt_split.c +bt_stack.o: ../../btree/bt_stack.c + ${CL} -I../../btree ../../btree/bt_stack.c +bt_utils.o: ../../btree/bt_utils.c + ${CL} -I../../btree ../../btree/bt_utils.c + +db.o: ../../db/db.c + ${CL} ../../db/db.c + +mpool.o: ../../mpool/mpool.c + ${CL} -I../../mpool ../../mpool/mpool.c + +rec_close.o: ../../recno/rec_close.c + ${CL} -I../../recno ../../recno/rec_close.c +rec_delete.o: ../../recno/rec_delete.c + ${CL} -I../../recno ../../recno/rec_delete.c +rec_get.o: ../../recno/rec_get.c + ${CL} -I../../recno ../../recno/rec_get.c +rec_open.o: ../../recno/rec_open.c + ${CL} -I../../recno ../../recno/rec_open.c +rec_put.o: ../../recno/rec_put.c + ${CL} -I../../recno ../../recno/rec_put.c +rec_search.o: ../../recno/rec_search.c + ${CL} -I../../recno ../../recno/rec_search.c +rec_seq.o: ../../recno/rec_seq.c + ${CL} -I../../recno ../../recno/rec_seq.c +rec_utils.o: ../../recno/rec_utils.c + ${CL} -I../../recno ../../recno/rec_utils.c + +memmove.o: + ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c +mktemp.o: + ${CC} -c -O -I. -Iinclude clib/mktemp.c +snprintf.o: + ${CC} -c -O -I. -Iinclude clib/snprintf.c diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/clib b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/clib new file mode 120000 index 0000000..f0f4f38 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/clib @@ -0,0 +1 @@ +../clib \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/cdefs.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/cdefs.h new file mode 120000 index 0000000..d248490 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/cdefs.h @@ -0,0 +1 @@ +../../include/cdefs.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/compat.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/compat.h new file mode 100644 index 0000000..46a2964 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/compat.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)compat.h 8.13 (Berkeley) 2/21/94 + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#include + +/* + * If your system doesn't typedef u_long, u_short, or u_char, change + * the 0 to a 1. + */ +#if 0 +typedef unsigned char u_char; /* 4.[34]BSD names. */ +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif + +/* If your system doesn't typedef size_t, change the 0 to a 1. */ +#if 0 +typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */ +#endif + +/* If your system doesn't typedef ssize_t, change the 0 to a 1. */ +#if 1 +typedef int ssize_t; /* POSIX names. */ +#endif + +/* + * If your system doesn't have the POSIX type for a signal mask, + * change the 0 to a 1. + */ +#if 0 /* POSIX 1003.1 signal mask type. */ +typedef unsigned int sigset_t; +#endif + +/* + * If your system's vsprintf returns a char *, not an int, + * change the 0 to a 1. + */ +#if 0 +#define VSPRINTF_CHARSTAR +#endif + +/* + * If you don't have POSIX 1003.1 signals, the signal code surrounding the + * temporary file creation is intended to block all of the possible signals + * long enough to create the file and unlink it. All of this stuff is + * intended to use old-style BSD calls to fake POSIX 1003.1 calls. + */ +#ifdef NO_POSIX_SIGNALS +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) +#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) +#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +static int __sigtemp; /* For the use of sigprocmask */ + +/* Repeated test of oset != NULL is to avoid "*0". */ +#define sigprocmask(how, set, oset) \ + ((__sigtemp = \ + (((how) == SIG_BLOCK) ? \ + sigblock(0) | *(set) : \ + (((how) == SIG_UNBLOCK) ? \ + sigblock(0) & ~(*(set)) : \ + ((how) == SIG_SETMASK ? \ + *(set) : sigblock(0))))), \ + ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \ + sigsetmask(__sigtemp)), 0) +#endif + +/* + * If your system doesn't have an include file with the appropriate + * byte order set, make sure you specify the correct one. + */ +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define BYTE_ORDER LITTLE_ENDIAN /* Set for your system. */ +#endif + +#if defined(SYSV) || defined(SYSTEM5) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) +#define bzero(a, b) memset(a, 0, b) +#define bcmp(a, b, n) memcmp(a, b, n) +#define bcopy(a, b, n) memmove(b, a, n) +#endif + +#if defined(BSD) || defined(BSD4_3) +#define strchr(a, b) index(a, b) +#define strrchr(a, b) rindex(a, b) +#define memcmp(a, b, n) bcmp(a, b, n) +#define memmove(a, b, n) bcopy(b, a, n) +#endif + +/* + * 32-bit machine. The db routines are theoretically independent of + * the size of u_shorts and u_longs, but I don't know that anyone has + * ever actually tried it. At a minimum, change the following #define's + * if you are trying to compile on a different type of system. + */ +#ifndef USHRT_MAX +#define USHRT_MAX 0xFFFF +#define ULONG_MAX 0xFFFFFFFF +#endif + +#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +/* + * If you can't provide lock values in the open(2) call. Note, this + * allows races to happen. + */ +#ifndef O_EXLOCK /* 4.4BSD extension. */ +#define O_EXLOCK 0 +#endif + +#ifndef O_SHLOCK /* 4.4BSD extension. */ +#define O_SHLOCK 0 +#endif + +#ifndef EFTYPE +#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ +#endif + +#ifndef WCOREDUMP /* 4.4BSD extension */ +#define WCOREDUMP(a) 0 +#endif + +#ifndef STDERR_FILENO +#define STDIN_FILENO 0 /* ANSI C #defines */ +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#endif + +#ifndef SEEK_END +#define SEEK_SET 0 /* POSIX 1003.1 seek values */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */ +#define _POSIX_VDISABLE 0 /* Some systems used 0. */ +#endif + +#ifndef TCSASOFT /* 4.4BSD extension. */ +#define TCSASOFT 0 +#endif + +#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */ +#define _POSIX2_RE_DUP_MAX 255 +#endif + +#ifndef NULL /* ANSI C #defines NULL everywhere. */ +#define NULL 0 +#endif + +#ifndef MAX /* Usually found in . */ +#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) +#endif +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +/* Default file permissions. */ +#ifndef DEFFILEMODE /* 4.4BSD extension. */ +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#endif + +#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */ +#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */ +#endif +#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ +#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */ +#endif + +/* The type of a va_list. */ +#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */ +#define _BSD_VA_LIST_ char * +#endif + +#endif /* !_COMPAT_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/db.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/db.h new file mode 100644 index 0000000..55f8c57 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/db.h @@ -0,0 +1,230 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)db.h 8.7 (Berkeley) 6/16/94 + */ + +#ifndef _DB_H_ +#define _DB_H_ + +#include +#include + +#include + +#ifdef __DBINTERFACE_PRIVATE +#include +#endif + +#define RET_ERROR -1 /* Return values. */ +#define RET_SUCCESS 0 +#define RET_SPECIAL 1 + +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ +typedef __signed char int8_t; +typedef unsigned char u_int8_t; +typedef short int16_t; +typedef unsigned short u_int16_t; +typedef int int32_t; +typedef unsigned int u_int32_t; +#ifdef WE_DONT_NEED_QUADS +typedef long long int64_t; +typedef unsigned long long u_int64_t; +#endif +#endif + +#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ +typedef u_int32_t pgno_t; +#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ +typedef u_int16_t indx_t; +#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */ +typedef u_int32_t recno_t; + +/* Key/data structure -- a Data-Base Thang. */ +typedef struct { + void *data; /* data */ + size_t size; /* data length */ +} DBT; + +/* Routine flags. */ +#define R_CURSOR 1 /* del, put, seq */ +#define __R_UNUSED 2 /* UNUSED */ +#define R_FIRST 3 /* seq */ +#define R_IAFTER 4 /* put (RECNO) */ +#define R_IBEFORE 5 /* put (RECNO) */ +#define R_LAST 6 /* seq (BTREE, RECNO) */ +#define R_NEXT 7 /* seq */ +#define R_NOOVERWRITE 8 /* put */ +#define R_PREV 9 /* seq (BTREE, RECNO) */ +#define R_SETCURSOR 10 /* put (RECNO) */ +#define R_RECNOSYNC 11 /* sync (RECNO) */ + +typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; + +/* + * !!! + * The following flags are included in the dbopen(3) call as part of the + * open(2) flags. In order to avoid conflicts with the open flags, start + * at the top of the 16 or 32-bit number space and work our way down. If + * the open flags were significantly expanded in the future, it could be + * a problem. Wish I'd left another flags word in the dbopen call. + * + * !!! + * None of this stuff is implemented yet. The only reason that it's here + * is so that the access methods can skip copying the key/data pair when + * the DB_LOCK flag isn't set. + */ +#define DB_LOCK 0x20000000 /* Do locking. */ +#define DB_SHMEM 0x40000000 /* Use shared memory. */ +#define DB_TXN 0x80000000 /* Do transactions. */ + +/* Access method description structure. */ +typedef struct __db { + DBTYPE type; /* Underlying db type. */ + int (*close) __P((struct __db *)); + int (*del) __P((const struct __db *, const DBT *, u_int)); + int (*get) __P((const struct __db *, const DBT *, DBT *, u_int)); + int (*put) __P((const struct __db *, DBT *, const DBT *, u_int)); + int (*seq) __P((const struct __db *, DBT *, DBT *, u_int)); + int (*sync) __P((const struct __db *, u_int)); + void *internal; /* Access method private. */ + int (*fd) __P((const struct __db *)); +} DB; + +#define BTREEMAGIC 0x053162 +#define BTREEVERSION 3 + +/* Structure used to pass parameters to the btree routines. */ +typedef struct { +#define R_DUP 0x01 /* duplicate keys */ + u_long flags; + u_int cachesize; /* bytes to cache */ + int maxkeypage; /* maximum keys per page */ + int minkeypage; /* minimum keys per page */ + u_int psize; /* page size */ + int (*compare) /* comparison function */ + __P((const DBT *, const DBT *)); + size_t (*prefix) /* prefix function */ + __P((const DBT *, const DBT *)); + int lorder; /* byte order */ +} BTREEINFO; + +#define HASHMAGIC 0x061561 +#define HASHVERSION 2 + +/* Structure used to pass parameters to the hashing routines. */ +typedef struct { + u_int bsize; /* bucket size */ + u_int ffactor; /* fill factor */ + u_int nelem; /* number of elements */ + u_int cachesize; /* bytes to cache */ + u_int32_t /* hash function */ + (*hash) __P((const void *, size_t)); + int lorder; /* byte order */ +} HASHINFO; + +/* Structure used to pass parameters to the record routines. */ +typedef struct { +#define R_FIXEDLEN 0x01 /* fixed-length records */ +#define R_NOKEY 0x02 /* key not required */ +#define R_SNAPSHOT 0x04 /* snapshot the input */ + u_long flags; + u_int cachesize; /* bytes to cache */ + u_int psize; /* page size */ + int lorder; /* byte order */ + size_t reclen; /* record length (fixed-length records) */ + u_char bval; /* delimiting byte (variable-length records */ + char *bfname; /* btree file name */ +} RECNOINFO; + +#ifdef __DBINTERFACE_PRIVATE +/* + * Little endian <==> big endian 32-bit swap macros. + * M_32_SWAP swap a memory location + * P_32_SWAP swap a referenced memory location + * P_32_COPY swap from one location to another + */ +#define M_32_SWAP(a) { \ + u_int32_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[3]; \ + ((char *)&a)[1] = ((char *)&_tmp)[2]; \ + ((char *)&a)[2] = ((char *)&_tmp)[1]; \ + ((char *)&a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_SWAP(a) { \ + u_int32_t _tmp = *(u_int32_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[3]; \ + ((char *)a)[1] = ((char *)&_tmp)[2]; \ + ((char *)a)[2] = ((char *)&_tmp)[1]; \ + ((char *)a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[3]; \ + ((char *)&(b))[1] = ((char *)&(a))[2]; \ + ((char *)&(b))[2] = ((char *)&(a))[1]; \ + ((char *)&(b))[3] = ((char *)&(a))[0]; \ +} + +/* + * Little endian <==> big endian 16-bit swap macros. + * M_16_SWAP swap a memory location + * P_16_SWAP swap a referenced memory location + * P_16_COPY swap from one location to another + */ +#define M_16_SWAP(a) { \ + u_int16_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[1]; \ + ((char *)&a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_SWAP(a) { \ + u_int16_t _tmp = *(u_int16_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[1]; \ + ((char *)a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[1]; \ + ((char *)&(b))[1] = ((char *)&(a))[0]; \ +} +#endif + +__BEGIN_DECLS +DB *dbopen __P((const char *, int, int, DBTYPE, const void *)); + +#ifdef __DBINTERFACE_PRIVATE +DB *__bt_open __P((const char *, int, int, const BTREEINFO *, int)); +DB *__hash_open __P((const char *, int, int, const HASHINFO *, int)); +DB *__rec_open __P((const char *, int, int, const RECNOINFO *, int)); +void __dbpanic __P((DB *dbp)); +#endif +__END_DECLS +#endif /* !_DB_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/mpool.h new file mode 120000 index 0000000..03f870c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/mpool.h @@ -0,0 +1 @@ +../../include/mpool.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/ndbm.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/ndbm.h new file mode 120000 index 0000000..a1a41a8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/ndbm.h @@ -0,0 +1 @@ +../../include/ndbm.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/queue.h b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/queue.h new file mode 120000 index 0000000..e54c7cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/include/queue.h @@ -0,0 +1 @@ +../../include/queue.h \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/sys b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/sys new file mode 120000 index 0000000..2996fba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.2/sys @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.3 b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.3 new file mode 120000 index 0000000..283b111 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/PORT/ultrix.4.3 @@ -0,0 +1 @@ +ultrix.4.2 \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/README b/circuitpython/lib/berkeley-db-1.xx/README new file mode 100644 index 0000000..bed2c92 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/README @@ -0,0 +1,40 @@ +# @(#)README 8.27 (Berkeley) 9/1/94 + +This is version 1.85 of the Berkeley DB code. + +For information on compiling and installing this software, see the file +PORT/README. + +Newer versions of this software will periodically be made available by +anonymous ftp from ftp.cs.berkeley.edu. An archive in compressed format +is in ucb/4bsd/db.tar.Z, or in gzip format in ucb/4bsd/db.tar.gz. If +you'd like to receive announcements of future releases of this software, +send email to the contact address below. + +Email questions may be addressed to Keith Bostic at bostic@cs.berkeley.edu. + +============================================ +Distribution contents: + +Makefile.inc Ignore this, it's the 4.4BSD subsystem Makefile. +PORT The per OS/architecture directories to use to build + libdb.a, if you're not running 4.4BSD. See the file + PORT/README for more information. +README This file. +btree The B+tree routines. +changelog List of changes, per version. +db The dbopen(3) interface routine. +docs Various USENIX papers, and the formatted manual pages. +hash The extended linear hashing routines. +man The unformatted manual pages. +mpool The memory pool routines. +recno The fixed/variable length record routines. +test Test package. + +============================================ +Debugging: + +If you're running a memory checker (e.g. Purify) on DB, make sure that +you recompile it with "-DPURIFY" in the CFLAGS, first. By default, +allocated pages are not initialized by the DB code, and they will show +up as reads of uninitialized memory in the buffer write routines. diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/Makefile.inc b/circuitpython/lib/berkeley-db-1.xx/btree/Makefile.inc new file mode 100644 index 0000000..8ed7649 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/Makefile.inc @@ -0,0 +1,7 @@ +# @(#)Makefile.inc 8.2 (Berkeley) 7/14/94 + +.PATH: ${.CURDIR}/db/btree + +SRCS+= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c \ + bt_overflow.c bt_page.c bt_put.c bt_search.c bt_seq.c bt_split.c \ + bt_utils.c diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_close.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_close.c new file mode 100644 index 0000000..523bbdb --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_close.c @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include +#include + +#include +#include "btree.h" + +static int bt_meta __P((BTREE *)); + +/* + * BT_CLOSE -- Close a btree. + * + * Parameters: + * dbp: pointer to access method + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__bt_close(dbp) + DB *dbp; +{ + BTREE *t; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Sync the tree. */ + if (__bt_sync(dbp, 0) == RET_ERROR) + return (RET_ERROR); + + /* Close the memory pool. */ + if (mpool_close(t->bt_mp) == RET_ERROR) + return (RET_ERROR); + + /* Free random memory. */ + if (t->bt_cursor.key.data != NULL) { + free(t->bt_cursor.key.data); + t->bt_cursor.key.size = 0; + t->bt_cursor.key.data = NULL; + } + if (t->bt_rkey.data) { + free(t->bt_rkey.data); + t->bt_rkey.size = 0; + t->bt_rkey.data = NULL; + } + if (t->bt_rdata.data) { + free(t->bt_rdata.data); + t->bt_rdata.size = 0; + t->bt_rdata.data = NULL; + } + + free(t); + free(dbp); + return RET_SUCCESS; +} + +/* + * BT_SYNC -- sync the btree to disk. + * + * Parameters: + * dbp: pointer to access method + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +int +__bt_sync(dbp, flags) + const DB *dbp; + u_int flags; +{ + BTREE *t; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Sync doesn't currently take any flags. */ + if (flags != 0) { + errno = EINVAL; + return (RET_ERROR); + } + + if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED)) + return (RET_SUCCESS); + + if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR) + return (RET_ERROR); + + if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS) + F_CLR(t, B_MODIFIED); + + return (status); +} + +/* + * BT_META -- write the tree meta data to disk. + * + * Parameters: + * t: tree + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +static int +bt_meta(t) + BTREE *t; +{ + BTMETA m; + void *p; + + if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL) + return (RET_ERROR); + + /* Fill in metadata. */ + m.magic = BTREEMAGIC; + m.version = BTREEVERSION; + m.psize = t->bt_psize; + m.free = t->bt_free; + m.nrecs = t->bt_nrecs; + m.flags = F_ISSET(t, SAVEMETA); + + memmove(p, &m, sizeof(BTMETA)); + mpool_put(t->bt_mp, p, MPOOL_DIRTY); + return (RET_SUCCESS); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_conv.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_conv.c new file mode 100644 index 0000000..1cb208b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_conv.c @@ -0,0 +1,221 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include + +#include +#include "btree.h" + +static void mswap __P((PAGE *)); + +/* + * __BT_BPGIN, __BT_BPGOUT -- + * Convert host-specific number layout to/from the host-independent + * format stored on disk. + * + * Parameters: + * t: tree + * pg: page number + * h: page to convert + */ +void +__bt_pgin(t, pg, pp) + void *t; + pgno_t pg; + void *pp; +{ + PAGE *h; + indx_t i, top; + u_char flags; + char *p; + + if (!F_ISSET(((BTREE *)t), B_NEEDSWAP)) + return; + if (pg == P_META) { + mswap(pp); + return; + } + + h = pp; + M_32_SWAP(h->pgno); + M_32_SWAP(h->prevpg); + M_32_SWAP(h->nextpg); + M_32_SWAP(h->flags); + M_16_SWAP(h->lower); + M_16_SWAP(h->upper); + + top = NEXTINDEX(h); + if ((h->flags & P_TYPE) == P_BINTERNAL) + for (i = 0; i < top; i++) { + M_16_SWAP(h->linp[i]); + p = (char *)GETBINTERNAL(h, i); + P_32_SWAP(p); + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(pgno_t); + if (*(u_char *)p & P_BIGKEY) { + p += sizeof(u_char); + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + } + else if ((h->flags & P_TYPE) == P_BLEAF) + for (i = 0; i < top; i++) { + M_16_SWAP(h->linp[i]); + p = (char *)GETBLEAF(h, i); + P_32_SWAP(p); + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(u_int32_t); + flags = *(u_char *)p; + if (flags & (P_BIGKEY | P_BIGDATA)) { + p += sizeof(u_char); + if (flags & P_BIGKEY) { + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + if (flags & P_BIGDATA) { + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + } + } +} + +void +__bt_pgout(t, pg, pp) + void *t; + pgno_t pg; + void *pp; +{ + PAGE *h; + indx_t i, top; + u_char flags; + char *p; + + if (!F_ISSET(((BTREE *)t), B_NEEDSWAP)) + return; + if (pg == P_META) { + mswap(pp); + return; + } + + h = pp; + top = NEXTINDEX(h); + if ((h->flags & P_TYPE) == P_BINTERNAL) + for (i = 0; i < top; i++) { + p = (char *)GETBINTERNAL(h, i); + P_32_SWAP(p); + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(pgno_t); + if (*(u_char *)p & P_BIGKEY) { + p += sizeof(u_char); + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + M_16_SWAP(h->linp[i]); + } + else if ((h->flags & P_TYPE) == P_BLEAF) + for (i = 0; i < top; i++) { + p = (char *)GETBLEAF(h, i); + P_32_SWAP(p); + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(u_int32_t); + flags = *(u_char *)p; + if (flags & (P_BIGKEY | P_BIGDATA)) { + p += sizeof(u_char); + if (flags & P_BIGKEY) { + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + if (flags & P_BIGDATA) { + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + } + M_16_SWAP(h->linp[i]); + } + + M_32_SWAP(h->pgno); + M_32_SWAP(h->prevpg); + M_32_SWAP(h->nextpg); + M_32_SWAP(h->flags); + M_16_SWAP(h->lower); + M_16_SWAP(h->upper); +} + +/* + * MSWAP -- Actually swap the bytes on the meta page. + * + * Parameters: + * p: page to convert + */ +static void +mswap(pg) + PAGE *pg; +{ + char *p; + + p = (char *)pg; + P_32_SWAP(p); /* magic */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* version */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* psize */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* free */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* nrecs */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* flags */ + p += sizeof(u_int32_t); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_debug.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_debug.c new file mode 100644 index 0000000..3aefbe7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_debug.c @@ -0,0 +1,329 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include + +#include +#include "btree.h" + +#ifdef DEBUG +/* + * BT_DUMP -- Dump the tree + * + * Parameters: + * dbp: pointer to the DB + */ +void +__bt_dump(dbp) + DB *dbp; +{ + BTREE *t; + PAGE *h; + pgno_t i; + char *sep; + + t = dbp->internal; + (void)fprintf(stderr, "%s: pgsz %d", + F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize); + if (F_ISSET(t, R_RECNO)) + (void)fprintf(stderr, " keys %lu", t->bt_nrecs); +#undef X +#define X(flag, name) \ + if (F_ISSET(t, flag)) { \ + (void)fprintf(stderr, "%s%s", sep, name); \ + sep = ", "; \ + } + if (t->flags != 0) { + sep = " flags ("; + X(R_FIXLEN, "FIXLEN"); + X(B_INMEM, "INMEM"); + X(B_NODUPS, "NODUPS"); + X(B_RDONLY, "RDONLY"); + X(R_RECNO, "RECNO"); + X(B_METADIRTY,"METADIRTY"); + (void)fprintf(stderr, ")\n"); + } +#undef X + + for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) { + __bt_dpage(h); + (void)mpool_put(t->bt_mp, h, 0); + } +} + +/* + * BT_DMPAGE -- Dump the meta page + * + * Parameters: + * h: pointer to the PAGE + */ +void +__bt_dmpage(h) + PAGE *h; +{ + BTMETA *m; + char *sep; + + m = (BTMETA *)h; + (void)fprintf(stderr, "magic %lx\n", m->magic); + (void)fprintf(stderr, "version %lu\n", m->version); + (void)fprintf(stderr, "psize %lu\n", m->psize); + (void)fprintf(stderr, "free %lu\n", m->free); + (void)fprintf(stderr, "nrecs %lu\n", m->nrecs); + (void)fprintf(stderr, "flags %lu", m->flags); +#undef X +#define X(flag, name) \ + if (m->flags & flag) { \ + (void)fprintf(stderr, "%s%s", sep, name); \ + sep = ", "; \ + } + if (m->flags) { + sep = " ("; + X(B_NODUPS, "NODUPS"); + X(R_RECNO, "RECNO"); + (void)fprintf(stderr, ")"); + } +} + +/* + * BT_DNPAGE -- Dump the page + * + * Parameters: + * n: page number to dump. + */ +void +__bt_dnpage(dbp, pgno) + DB *dbp; + pgno_t pgno; +{ + BTREE *t; + PAGE *h; + + t = dbp->internal; + if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) { + __bt_dpage(h); + (void)mpool_put(t->bt_mp, h, 0); + } +} + +/* + * BT_DPAGE -- Dump the page + * + * Parameters: + * h: pointer to the PAGE + */ +void +__bt_dpage(h) + PAGE *h; +{ + BINTERNAL *bi; + BLEAF *bl; + RINTERNAL *ri; + RLEAF *rl; + indx_t cur, top; + char *sep; + + (void)fprintf(stderr, " page %d: (", h->pgno); +#undef X +#define X(flag, name) \ + if (h->flags & flag) { \ + (void)fprintf(stderr, "%s%s", sep, name); \ + sep = ", "; \ + } + sep = ""; + X(P_BINTERNAL, "BINTERNAL") /* types */ + X(P_BLEAF, "BLEAF") + X(P_RINTERNAL, "RINTERNAL") /* types */ + X(P_RLEAF, "RLEAF") + X(P_OVERFLOW, "OVERFLOW") + X(P_PRESERVE, "PRESERVE"); + (void)fprintf(stderr, ")\n"); +#undef X + + (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg); + if (h->flags & P_OVERFLOW) + return; + + top = NEXTINDEX(h); + (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n", + h->lower, h->upper, top); + for (cur = 0; cur < top; cur++) { + (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]); + switch (h->flags & P_TYPE) { + case P_BINTERNAL: + bi = GETBINTERNAL(h, cur); + (void)fprintf(stderr, + "size %03d pgno %03d", bi->ksize, bi->pgno); + if (bi->flags & P_BIGKEY) + (void)fprintf(stderr, " (indirect)"); + else if (bi->ksize) + (void)fprintf(stderr, + " {%.*s}", (int)bi->ksize, bi->bytes); + break; + case P_RINTERNAL: + ri = GETRINTERNAL(h, cur); + (void)fprintf(stderr, "entries %03d pgno %03d", + ri->nrecs, ri->pgno); + break; + case P_BLEAF: + bl = GETBLEAF(h, cur); + if (bl->flags & P_BIGKEY) + (void)fprintf(stderr, + "big key page %lu size %u/", + *(pgno_t *)bl->bytes, + *(u_int32_t *)(bl->bytes + sizeof(pgno_t))); + else if (bl->ksize) + (void)fprintf(stderr, "%s/", bl->bytes); + if (bl->flags & P_BIGDATA) + (void)fprintf(stderr, + "big data page %lu size %u", + *(pgno_t *)(bl->bytes + bl->ksize), + *(u_int32_t *)(bl->bytes + bl->ksize + + sizeof(pgno_t))); + else if (bl->dsize) + (void)fprintf(stderr, "%.*s", + (int)bl->dsize, bl->bytes + bl->ksize); + break; + case P_RLEAF: + rl = GETRLEAF(h, cur); + if (rl->flags & P_BIGDATA) + (void)fprintf(stderr, + "big data page %lu size %u", + *(pgno_t *)rl->bytes, + *(u_int32_t *)(rl->bytes + sizeof(pgno_t))); + else if (rl->dsize) + (void)fprintf(stderr, + "%.*s", (int)rl->dsize, rl->bytes); + break; + } + (void)fprintf(stderr, "\n"); + } +} +#endif + +#ifdef STATISTICS +/* + * BT_STAT -- Gather/print the tree statistics + * + * Parameters: + * dbp: pointer to the DB + */ +void +__bt_stat(dbp) + DB *dbp; +{ + extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit; + extern u_long bt_sortsplit, bt_split; + BTREE *t; + PAGE *h; + pgno_t i, pcont, pinternal, pleaf; + u_long ifree, lfree, nkeys; + int levels; + + t = dbp->internal; + pcont = pinternal = pleaf = 0; + nkeys = ifree = lfree = 0; + for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) { + switch (h->flags & P_TYPE) { + case P_BINTERNAL: + case P_RINTERNAL: + ++pinternal; + ifree += h->upper - h->lower; + break; + case P_BLEAF: + case P_RLEAF: + ++pleaf; + lfree += h->upper - h->lower; + nkeys += NEXTINDEX(h); + break; + case P_OVERFLOW: + ++pcont; + break; + } + (void)mpool_put(t->bt_mp, h, 0); + } + + /* Count the levels of the tree. */ + for (i = P_ROOT, levels = 0 ;; ++levels) { + h = mpool_get(t->bt_mp, i, 0); + if (h->flags & (P_BLEAF|P_RLEAF)) { + if (levels == 0) + levels = 1; + (void)mpool_put(t->bt_mp, h, 0); + break; + } + i = F_ISSET(t, R_RECNO) ? + GETRINTERNAL(h, 0)->pgno : + GETBINTERNAL(h, 0)->pgno; + (void)mpool_put(t->bt_mp, h, 0); + } + + (void)fprintf(stderr, "%d level%s with %ld keys", + levels, levels == 1 ? "" : "s", nkeys); + if (F_ISSET(t, R_RECNO)) + (void)fprintf(stderr, " (%ld header count)", t->bt_nrecs); + (void)fprintf(stderr, + "\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n", + pinternal + pleaf + pcont, pleaf, pinternal, pcont); + (void)fprintf(stderr, "%ld cache hits, %ld cache misses\n", + bt_cache_hit, bt_cache_miss); + (void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n", + bt_split, bt_rootsplit, bt_sortsplit); + pleaf *= t->bt_psize - BTDATAOFF; + if (pleaf) + (void)fprintf(stderr, + "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n", + ((double)(pleaf - lfree) / pleaf) * 100, + pleaf - lfree, lfree); + pinternal *= t->bt_psize - BTDATAOFF; + if (pinternal) + (void)fprintf(stderr, + "%.0f%% internal fill (%ld bytes used, %ld bytes free\n", + ((double)(pinternal - ifree) / pinternal) * 100, + pinternal - ifree, ifree); + if (bt_pfxsaved) + (void)fprintf(stderr, "prefix checking removed %lu bytes.\n", + bt_pfxsaved); +} +#endif diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_delete.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_delete.c new file mode 100644 index 0000000..667bff5 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_delete.c @@ -0,0 +1,657 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_delete.c 8.13 (Berkeley) 7/28/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include + +#include +#include "btree.h" + +static int __bt_bdelete __P((BTREE *, const DBT *)); +static int __bt_curdel __P((BTREE *, const DBT *, PAGE *, u_int)); +static int __bt_pdelete __P((BTREE *, PAGE *)); +static int __bt_relink __P((BTREE *, PAGE *)); +static int __bt_stkacq __P((BTREE *, PAGE **, CURSOR *)); + +/* + * __bt_delete + * Delete the item(s) referenced by a key. + * + * Return RET_SPECIAL if the key is not found. + */ +int +__bt_delete(dbp, key, flags) + const DB *dbp; + const DBT *key; + u_int flags; +{ + BTREE *t; + CURSOR *c; + PAGE *h; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Check for change to a read-only tree. */ + if (F_ISSET(t, B_RDONLY)) { + errno = EPERM; + return (RET_ERROR); + } + + switch (flags) { + case 0: + status = __bt_bdelete(t, key); + break; + case R_CURSOR: + /* + * If flags is R_CURSOR, delete the cursor. Must already + * have started a scan and not have already deleted it. + */ + c = &t->bt_cursor; + if (F_ISSET(c, CURS_INIT)) { + if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE)) + return (RET_SPECIAL); + if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL) + return (RET_ERROR); + + /* + * If the page is about to be emptied, we'll need to + * delete it, which means we have to acquire a stack. + */ + if (NEXTINDEX(h) == 1) + if (__bt_stkacq(t, &h, &t->bt_cursor)) + return (RET_ERROR); + + status = __bt_dleaf(t, NULL, h, c->pg.index); + + if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) { + if (__bt_pdelete(t, h)) + return (RET_ERROR); + } else + mpool_put(t->bt_mp, + h, status == RET_SUCCESS ? MPOOL_DIRTY : 0); + break; + } + /* FALLTHROUGH */ + default: + errno = EINVAL; + return (RET_ERROR); + } + if (status == RET_SUCCESS) + F_SET(t, B_MODIFIED); + return (status); +} + +/* + * __bt_stkacq -- + * Acquire a stack so we can delete a cursor entry. + * + * Parameters: + * t: tree + * hp: pointer to current, pinned PAGE pointer + * c: pointer to the cursor + * + * Returns: + * 0 on success, 1 on failure + */ +static int +__bt_stkacq(t, hp, c) + BTREE *t; + PAGE **hp; + CURSOR *c; +{ + BINTERNAL *bi; + EPG *e; + EPGNO *parent; + PAGE *h; + indx_t index = 0; + pgno_t pgno; + recno_t nextpg, prevpg; + int exact, level; + + /* + * Find the first occurrence of the key in the tree. Toss the + * currently locked page so we don't hit an already-locked page. + */ + h = *hp; + mpool_put(t->bt_mp, h, 0); + if ((e = __bt_search(t, &c->key, &exact)) == NULL) + return (1); + h = e->page; + + /* See if we got it in one shot. */ + if (h->pgno == c->pg.pgno) + goto ret; + + /* + * Move right, looking for the page. At each move we have to move + * up the stack until we don't have to move to the next page. If + * we have to change pages at an internal level, we have to fix the + * stack back up. + */ + while (h->pgno != c->pg.pgno) { + if ((nextpg = h->nextpg) == P_INVALID) + break; + mpool_put(t->bt_mp, h, 0); + + /* Move up the stack. */ + for (level = 0; (parent = BT_POP(t)) != NULL; ++level) { + /* Get the parent page. */ + if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) + return (1); + + /* Move to the next index. */ + if (parent->index != NEXTINDEX(h) - 1) { + index = parent->index + 1; + BT_PUSH(t, h->pgno, index); + break; + } + mpool_put(t->bt_mp, h, 0); + } + + /* Restore the stack. */ + while (level--) { + /* Push the next level down onto the stack. */ + bi = GETBINTERNAL(h, index); + pgno = bi->pgno; + BT_PUSH(t, pgno, 0); + + /* Lose the currently pinned page. */ + mpool_put(t->bt_mp, h, 0); + + /* Get the next level down. */ + if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL) + return (1); + index = 0; + } + mpool_put(t->bt_mp, h, 0); + if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL) + return (1); + } + + if (h->pgno == c->pg.pgno) + goto ret; + + /* Reacquire the original stack. */ + mpool_put(t->bt_mp, h, 0); + if ((e = __bt_search(t, &c->key, &exact)) == NULL) + return (1); + h = e->page; + + /* + * Move left, looking for the page. At each move we have to move + * up the stack until we don't have to change pages to move to the + * next page. If we have to change pages at an internal level, we + * have to fix the stack back up. + */ + while (h->pgno != c->pg.pgno) { + if ((prevpg = h->prevpg) == P_INVALID) + break; + mpool_put(t->bt_mp, h, 0); + + /* Move up the stack. */ + for (level = 0; (parent = BT_POP(t)) != NULL; ++level) { + /* Get the parent page. */ + if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) + return (1); + + /* Move to the next index. */ + if (parent->index != 0) { + index = parent->index - 1; + BT_PUSH(t, h->pgno, index); + break; + } + mpool_put(t->bt_mp, h, 0); + } + + /* Restore the stack. */ + while (level--) { + /* Push the next level down onto the stack. */ + bi = GETBINTERNAL(h, index); + pgno = bi->pgno; + + /* Lose the currently pinned page. */ + mpool_put(t->bt_mp, h, 0); + + /* Get the next level down. */ + if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL) + return (1); + + index = NEXTINDEX(h) - 1; + BT_PUSH(t, pgno, index); + } + mpool_put(t->bt_mp, h, 0); + if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL) + return (1); + } + + +ret: mpool_put(t->bt_mp, h, 0); + return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL); +} + +/* + * __bt_bdelete -- + * Delete all key/data pairs matching the specified key. + * + * Parameters: + * t: tree + * key: key to delete + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. + */ +static int +__bt_bdelete(t, key) + BTREE *t; + const DBT *key; +{ + EPG *e; + PAGE *h; + int deleted, exact, redo; + + deleted = 0; + + /* Find any matching record; __bt_search pins the page. */ +loop: if ((e = __bt_search(t, key, &exact)) == NULL) + return (deleted ? RET_SUCCESS : RET_ERROR); + if (!exact) { + mpool_put(t->bt_mp, e->page, 0); + return (deleted ? RET_SUCCESS : RET_SPECIAL); + } + + /* + * Delete forward, then delete backward, from the found key. If + * there are duplicates and we reach either side of the page, do + * the key search again, so that we get them all. + */ + redo = 0; + h = e->page; + do { + if (__bt_dleaf(t, key, h, e->index)) { + mpool_put(t->bt_mp, h, 0); + return (RET_ERROR); + } + if (F_ISSET(t, B_NODUPS)) { + if (NEXTINDEX(h) == 0) { + if (__bt_pdelete(t, h)) + return (RET_ERROR); + } else + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + return (RET_SUCCESS); + } + deleted = 1; + } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0); + + /* Check for right-hand edge of the page. */ + if (e->index == NEXTINDEX(h)) + redo = 1; + + /* Delete from the key to the beginning of the page. */ + while (e->index-- > 0) { + if (__bt_cmp(t, key, e) != 0) + break; + if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) { + mpool_put(t->bt_mp, h, 0); + return (RET_ERROR); + } + if (e->index == 0) + redo = 1; + } + + /* Check for an empty page. */ + if (NEXTINDEX(h) == 0) { + if (__bt_pdelete(t, h)) + return (RET_ERROR); + goto loop; + } + + /* Put the page. */ + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + + if (redo) + goto loop; + return (RET_SUCCESS); +} + +/* + * __bt_pdelete -- + * Delete a single page from the tree. + * + * Parameters: + * t: tree + * h: leaf page + * + * Returns: + * RET_SUCCESS, RET_ERROR. + * + * Side-effects: + * mpool_put's the page + */ +static int +__bt_pdelete(t, h) + BTREE *t; + PAGE *h; +{ + BINTERNAL *bi; + PAGE *pg; + EPGNO *parent; + indx_t cnt, index, *ip, offset; + u_int32_t nksize; + char *from; + + /* + * Walk the parent page stack -- a LIFO stack of the pages that were + * traversed when we searched for the page where the delete occurred. + * Each stack entry is a page number and a page index offset. The + * offset is for the page traversed on the search. We've just deleted + * a page, so we have to delete the key from the parent page. + * + * If the delete from the parent page makes it empty, this process may + * continue all the way up the tree. We stop if we reach the root page + * (which is never deleted, it's just not worth the effort) or if the + * delete does not empty the page. + */ + while ((parent = BT_POP(t)) != NULL) { + /* Get the parent page. */ + if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) + return (RET_ERROR); + + index = parent->index; + bi = GETBINTERNAL(pg, index); + + /* Free any overflow pages. */ + if (bi->flags & P_BIGKEY && + __ovfl_delete(t, bi->bytes) == RET_ERROR) { + mpool_put(t->bt_mp, pg, 0); + return (RET_ERROR); + } + + /* + * Free the parent if it has only the one key and it's not the + * root page. If it's the rootpage, turn it back into an empty + * leaf page. + */ + if (NEXTINDEX(pg) == 1) + if (pg->pgno == P_ROOT) { + pg->lower = BTDATAOFF; + pg->upper = t->bt_psize; + pg->flags = P_BLEAF; + } else { + if (__bt_relink(t, pg) || __bt_free(t, pg)) + return (RET_ERROR); + continue; + } + else { + /* Pack remaining key items at the end of the page. */ + nksize = NBINTERNAL(bi->ksize); + from = (char *)pg + pg->upper; + memmove(from + nksize, from, (char *)bi - from); + pg->upper += nksize; + + /* Adjust indices' offsets, shift the indices down. */ + offset = pg->linp[index]; + for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip) + if (ip[0] < offset) + ip[0] += nksize; + for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip) + ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1]; + pg->lower -= sizeof(indx_t); + } + + mpool_put(t->bt_mp, pg, MPOOL_DIRTY); + break; + } + + /* Free the leaf page, as long as it wasn't the root. */ + if (h->pgno == P_ROOT) { + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + return (RET_SUCCESS); + } + return (__bt_relink(t, h) || __bt_free(t, h)); +} + +/* + * __bt_dleaf -- + * Delete a single record from a leaf page. + * + * Parameters: + * t: tree + * key: referenced key + * h: page + * index: index on page to delete + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +int +__bt_dleaf(t, key, h, index) + BTREE *t; + const DBT *key; + PAGE *h; + u_int index; +{ + BLEAF *bl; + indx_t cnt, *ip, offset; + u_int32_t nbytes; + void *to; + char *from; + + /* If this record is referenced by the cursor, delete the cursor. */ + if (F_ISSET(&t->bt_cursor, CURS_INIT) && + !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) && + t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index && + __bt_curdel(t, key, h, index)) + return (RET_ERROR); + + /* If the entry uses overflow pages, make them available for reuse. */ + to = bl = GETBLEAF(h, index); + if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR) + return (RET_ERROR); + if (bl->flags & P_BIGDATA && + __ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR) + return (RET_ERROR); + + /* Pack the remaining key/data items at the end of the page. */ + nbytes = NBLEAF(bl); + from = (char *)h + h->upper; + memmove(from + nbytes, from, (char *)to - from); + h->upper += nbytes; + + /* Adjust the indices' offsets, shift the indices down. */ + offset = h->linp[index]; + for (cnt = index, ip = &h->linp[0]; cnt--; ++ip) + if (ip[0] < offset) + ip[0] += nbytes; + for (cnt = NEXTINDEX(h) - index; --cnt; ++ip) + ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1]; + h->lower -= sizeof(indx_t); + + /* If the cursor is on this page, adjust it as necessary. */ + if (F_ISSET(&t->bt_cursor, CURS_INIT) && + !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) && + t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index) + --t->bt_cursor.pg.index; + + return (RET_SUCCESS); +} + +/* + * __bt_curdel -- + * Delete the cursor. + * + * Parameters: + * t: tree + * key: referenced key (or NULL) + * h: page + * index: index on page to delete + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +static int +__bt_curdel(t, key, h, index) + BTREE *t; + const DBT *key; + PAGE *h; + u_int index; +{ + CURSOR *c; + EPG e; + PAGE *pg; + int curcopy, status; + + /* + * If there are duplicates, move forward or backward to one. + * Otherwise, copy the key into the cursor area. + */ + c = &t->bt_cursor; + F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE); + + curcopy = 0; + if (!F_ISSET(t, B_NODUPS)) { + /* + * We're going to have to do comparisons. If we weren't + * provided a copy of the key, i.e. the user is deleting + * the current cursor position, get one. + */ + if (key == NULL) { + e.page = h; + e.index = index; + if ((status = __bt_ret(t, &e, + &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS) + return (status); + curcopy = 1; + key = &c->key; + } + /* Check previous key, if not at the beginning of the page. */ + if (index > 0) { + e.page = h; + e.index = index - 1; + if (__bt_cmp(t, key, &e) == 0) { + F_SET(c, CURS_BEFORE); + goto dup2; + } + } + /* Check next key, if not at the end of the page. */ + if (index < NEXTINDEX(h) - 1) { + e.page = h; + e.index = index + 1; + if (__bt_cmp(t, key, &e) == 0) { + F_SET(c, CURS_AFTER); + goto dup2; + } + } + /* Check previous key if at the beginning of the page. */ + if (index == 0 && h->prevpg != P_INVALID) { + if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) + return (RET_ERROR); + e.page = pg; + e.index = NEXTINDEX(pg) - 1; + if (__bt_cmp(t, key, &e) == 0) { + F_SET(c, CURS_BEFORE); + goto dup1; + } + mpool_put(t->bt_mp, pg, 0); + } + /* Check next key if at the end of the page. */ + if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) { + if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) + return (RET_ERROR); + e.page = pg; + e.index = 0; + if (__bt_cmp(t, key, &e) == 0) { + F_SET(c, CURS_AFTER); +dup1: mpool_put(t->bt_mp, pg, 0); +dup2: c->pg.pgno = e.page->pgno; + c->pg.index = e.index; + return (RET_SUCCESS); + } + mpool_put(t->bt_mp, pg, 0); + } + } + e.page = h; + e.index = index; + if (curcopy || (status = + __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) { + F_SET(c, CURS_ACQUIRE); + return (RET_SUCCESS); + } + return (status); +} + +/* + * __bt_relink -- + * Link around a deleted page. + * + * Parameters: + * t: tree + * h: page to be deleted + */ +static int +__bt_relink(t, h) + BTREE *t; + PAGE *h; +{ + PAGE *pg; + + if (h->nextpg != P_INVALID) { + if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) + return (RET_ERROR); + pg->prevpg = h->prevpg; + mpool_put(t->bt_mp, pg, MPOOL_DIRTY); + } + if (h->prevpg != P_INVALID) { + if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) + return (RET_ERROR); + pg->nextpg = h->nextpg; + mpool_put(t->bt_mp, pg, MPOOL_DIRTY); + } + return (0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_get.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_get.c new file mode 100644 index 0000000..74824c7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_get.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_get.c 8.6 (Berkeley) 7/20/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include + +#include +#include "btree.h" + +/* + * __BT_GET -- Get a record from the btree. + * + * Parameters: + * dbp: pointer to access method + * key: key to find + * data: data to return + * flag: currently unused + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. + */ +int +__bt_get(dbp, key, data, flags) + const DB *dbp; + const DBT *key; + DBT *data; + u_int flags; +{ + BTREE *t; + EPG *e; + int exact, status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Get currently doesn't take any flags. */ + if (flags) { + errno = EINVAL; + return (RET_ERROR); + } + + if ((e = __bt_search(t, key, &exact)) == NULL) + return (RET_ERROR); + if (!exact) { + mpool_put(t->bt_mp, e->page, 0); + return (RET_SPECIAL); + } + + status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0); + + /* + * If the user is doing concurrent access, we copied the + * key/data, toss the page. + */ + if (F_ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; + return (status); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_open.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_open.c new file mode 100644 index 0000000..7269ef0 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_open.c @@ -0,0 +1,412 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Implementation of btree access method for 4.4BSD. + * + * The design here was originally based on that of the btree access method + * used in the Postgres database system at UC Berkeley. This implementation + * is wholly independent of the Postgres code. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "btree.h" + +#ifdef DEBUG +#undef MINPSIZE +#define MINPSIZE 128 +#endif + +static int byteorder __P((void)); +static int nroot __P((BTREE *)); + +#ifdef BTREE_POSIX +/* Default vmethods and vtable to work with POSIX fd's. */ +static ssize_t bt_read(void *fd, void *buf, size_t size) +{ +//printf("read: %p(%lx)\n", buf, size); + return read((int)(uintptr_t)fd, buf, size); +} + +static ssize_t bt_write(void *fd, const void *buf, size_t size) +{ +//printf("write: %p(%lx)\n", buf, size); + return write((int)(uintptr_t)fd, buf, size); +} + +static off_t bt_lseek(void *fd, off_t offset, int whence) +{ +//printf("lseek: %lx(%d)\n", offset, whence); + return lseek((int)(uintptr_t)fd, offset, whence); +} + +static int bt_fsync(void *fd) +{ + return fsync((int)(uintptr_t)fd); +} + +static FILEVTABLE bt_fd_fvtable = { + bt_read, + bt_write, + bt_lseek, + bt_fsync +}; +#endif + +/* + * __BT_OPEN -- Open a btree. + * + * Creates and fills a DB struct, and calls the routine that actually + * opens the btree. + * + * Parameters: + * fname: filename (NULL for in-memory trees) + * b: BTREEINFO pointer + * + * Returns: + * NULL on failure, pointer to DB on success. + * + */ +DB * +__bt_open(file, vtable, openinfo, dflags) + virt_fd_t file; + const FILEVTABLE *vtable; + int dflags; + const BTREEINFO *openinfo; +{ + BTMETA m; + BTREE *t; + BTREEINFO b; + DB *dbp; + pgno_t ncache; + ssize_t nr; + int machine_lorder; + + t = NULL; +#ifdef BTREE_POSIX + if (vtable == NULL) + vtable = &bt_fd_fvtable; +#endif + + /* + * Intention is to make sure all of the user's selections are okay + * here and then use them without checking. Can't be complete, since + * we don't know the right page size, lorder or flags until the backing + * file is opened. Also, the file's page size can cause the cachesize + * to change. + */ + machine_lorder = byteorder(); + if (openinfo) { + b = *openinfo; + + /* Flags: R_DUP. */ + if (b.flags & ~(R_DUP)) + goto einval; + + /* + * Page size must be indx_t aligned and >= MINPSIZE. Default + * page size is set farther on, based on the underlying file + * transfer size. + */ + if (b.psize && + (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 || + b.psize & (sizeof(indx_t) - 1))) + goto einval; + + /* Minimum number of keys per page; absolute minimum is 2. */ + if (b.minkeypage) { + if (b.minkeypage < 2) + goto einval; + } else + b.minkeypage = DEFMINKEYPAGE; + + /* If no comparison, use default comparison and prefix. */ + if (b.compare == NULL) { + b.compare = __bt_defcmp; + if (b.prefix == NULL) + b.prefix = __bt_defpfx; + } + + if (b.lorder == 0) + b.lorder = machine_lorder; + } else { + b.compare = __bt_defcmp; + b.cachesize = 0; + b.flags = 0; + b.lorder = machine_lorder; + b.minkeypage = DEFMINKEYPAGE; + b.prefix = __bt_defpfx; + b.psize = 0; + } + + /* Check for the ubiquitous PDP-11. */ + if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN) + goto einval; + + /* Allocate and initialize DB and BTREE structures. */ + if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL) + goto err; + memset(t, 0, sizeof(BTREE)); + t->bt_fd = file; + t->bt_lorder = b.lorder; + t->bt_order = NOT; + t->bt_cmp = b.compare; + t->bt_pfx = b.prefix; + t->bt_rfd = -1; + + if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL) + goto err; + memset(t->bt_dbp, 0, sizeof(DB)); + if (t->bt_lorder != machine_lorder) + F_SET(t, B_NEEDSWAP); + + dbp->type = DB_BTREE; + dbp->internal = t; + dbp->close = __bt_close; + dbp->del = __bt_delete; + dbp->fd = __bt_fd; + dbp->get = __bt_get; + dbp->put = __bt_put; + dbp->seq = __bt_seq; + dbp->sync = __bt_sync; + + if ((nr = vtable->read(t->bt_fd, &m, sizeof(BTMETA))) < 0) + goto err; + if (nr != 0) { + if (nr != sizeof(BTMETA)) + goto eftype; + + /* + * Read in the meta-data. This can change the notion of what + * the lorder, page size and flags are, and, when the page size + * changes, the cachesize value can change too. If the user + * specified the wrong byte order for an existing database, we + * don't bother to return an error, we just clear the NEEDSWAP + * bit. + */ + if (m.magic == BTREEMAGIC) + F_CLR(t, B_NEEDSWAP); + else { + F_SET(t, B_NEEDSWAP); + M_32_SWAP(m.magic); + M_32_SWAP(m.version); + M_32_SWAP(m.psize); + M_32_SWAP(m.free); + M_32_SWAP(m.nrecs); + M_32_SWAP(m.flags); + } + if (m.magic != BTREEMAGIC || m.version != BTREEVERSION) + goto eftype; + if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 || + m.psize & (sizeof(indx_t) - 1)) + goto eftype; + if (m.flags & ~SAVEMETA) + goto eftype; + b.psize = m.psize; + F_SET(t, m.flags); + t->bt_free = m.free; + t->bt_nrecs = m.nrecs; + } else { + /* + * Set the page size to the best value for I/O to this file. + * Don't overflow the page offset type. + */ + if (b.psize == 0) { + b.psize = DEFPSIZE; + } + + /* Set flag if duplicates permitted. */ + if (!(b.flags & R_DUP)) + F_SET(t, B_NODUPS); + + t->bt_free = P_INVALID; + t->bt_nrecs = 0; + F_SET(t, B_METADIRTY); + } + + t->bt_psize = b.psize; + + /* Set the cache size; must be a multiple of the page size. */ + if (b.cachesize && b.cachesize & (b.psize - 1)) + b.cachesize += (~b.cachesize & (b.psize - 1)) + 1; + if (b.cachesize < b.psize * MINCACHE) + b.cachesize = b.psize * MINCACHE; + + /* Calculate number of pages to cache. */ + ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize; + + /* + * The btree data structure requires that at least two keys can fit on + * a page, but other than that there's no fixed requirement. The user + * specified a minimum number per page, and we translated that into the + * number of bytes a key/data pair can use before being placed on an + * overflow page. This calculation includes the page header, the size + * of the index referencing the leaf item and the size of the leaf item + * structure. Also, don't let the user specify a minkeypage such that + * a key/data pair won't fit even if both key and data are on overflow + * pages. + */ + t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage - + (sizeof(indx_t) + NBLEAFDBT(0, 0)); + if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t)) + t->bt_ovflsize = + NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t); + + /* Initialize the buffer pool. */ + if ((t->bt_mp = + mpool_open(NULL, t->bt_fd, vtable, t->bt_psize, ncache)) == NULL) + goto err; + if (!F_ISSET(t, B_INMEM)) + mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t); + + /* Create a root page if new tree. */ + if (nroot(t) == RET_ERROR) + goto err; + + /* Global flags. */ + if (dflags & DB_LOCK) + F_SET(t, B_DB_LOCK); + if (dflags & DB_SHMEM) + F_SET(t, B_DB_SHMEM); + if (dflags & DB_TXN) + F_SET(t, B_DB_TXN); + + return (dbp); + +einval: errno = EINVAL; + goto err; + +eftype: errno = EFTYPE; + goto err; + +err: if (t) { + if (t->bt_dbp) + free(t->bt_dbp); + free(t); + } + return (NULL); +} + +/* + * NROOT -- Create the root of a new tree. + * + * Parameters: + * t: tree + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +static int +nroot(t) + BTREE *t; +{ + PAGE *meta, *root; + pgno_t npg; + + if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) { + mpool_put(t->bt_mp, meta, 0); + return (RET_SUCCESS); + } + if (errno != EINVAL) /* It's OK to not exist. */ + return (RET_ERROR); + errno = 0; + + if ((meta = mpool_new(t->bt_mp, &npg)) == NULL) + return (RET_ERROR); + + if ((root = mpool_new(t->bt_mp, &npg)) == NULL) + return (RET_ERROR); + + if (npg != P_ROOT) + return (RET_ERROR); + root->pgno = npg; + root->prevpg = root->nextpg = P_INVALID; + root->lower = BTDATAOFF; + root->upper = t->bt_psize; + root->flags = P_BLEAF; + memset(meta, 0, t->bt_psize); + mpool_put(t->bt_mp, meta, MPOOL_DIRTY); + mpool_put(t->bt_mp, root, MPOOL_DIRTY); + return (RET_SUCCESS); +} + +static int +byteorder() +{ + u_int32_t x; + u_char *p; + + x = 0x01020304; + p = (u_char *)&x; + switch (*p) { + case 1: + return (BIG_ENDIAN); + case 4: + return (LITTLE_ENDIAN); + default: + return (0); + } +} + +int +__bt_fd(dbp) + const DB *dbp; +{ + BTREE *t; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + return -1; +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_overflow.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_overflow.c new file mode 100644 index 0000000..b1bd343 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_overflow.c @@ -0,0 +1,228 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include + +#include +#include "btree.h" + +/* + * Big key/data code. + * + * Big key and data entries are stored on linked lists of pages. The initial + * reference is byte string stored with the key or data and is the page number + * and size. The actual record is stored in a chain of pages linked by the + * nextpg field of the PAGE header. + * + * The first page of the chain has a special property. If the record is used + * by an internal page, it cannot be deleted and the P_PRESERVE bit will be set + * in the header. + * + * XXX + * A single DBT is written to each chain, so a lot of space on the last page + * is wasted. This is a fairly major bug for some data sets. + */ + +/* + * __OVFL_GET -- Get an overflow key/data item. + * + * Parameters: + * t: tree + * p: pointer to { pgno_t, u_int32_t } + * buf: storage address + * bufsz: storage size + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__ovfl_get(t, p, ssz, buf, bufsz) + BTREE *t; + void *p; + size_t *ssz; + void **buf; + size_t *bufsz; +{ + PAGE *h; + pgno_t pg; + size_t nb, plen; + u_int32_t sz; + + memcpy(&pg, p, sizeof(pgno_t)); + memcpy(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t)); + *ssz = sz; + +#ifdef DEBUG + if (pg == P_INVALID || sz == 0) + abort(); +#endif + /* Make the buffer bigger as necessary. */ + if (*bufsz < sz) { + *buf = (char *)(*buf == NULL ? malloc(sz) : realloc(*buf, sz)); + if (*buf == NULL) + return (RET_ERROR); + *bufsz = sz; + } + + /* + * Step through the linked list of pages, copying the data on each one + * into the buffer. Never copy more than the data's length. + */ + plen = t->bt_psize - BTDATAOFF; + for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + + nb = MIN(sz, plen); + memmove(p, (char *)h + BTDATAOFF, nb); + mpool_put(t->bt_mp, h, 0); + + if ((sz -= nb) == 0) + break; + } + return (RET_SUCCESS); +} + +/* + * __OVFL_PUT -- Store an overflow key/data item. + * + * Parameters: + * t: tree + * data: DBT to store + * pgno: storage page number + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__ovfl_put(t, dbt, pg) + BTREE *t; + const DBT *dbt; + pgno_t *pg; +{ + PAGE *h, *last; + void *p; + pgno_t npg; + size_t nb, plen; + u_int32_t sz; + + /* + * Allocate pages and copy the key/data record into them. Store the + * number of the first page in the chain. + */ + plen = t->bt_psize - BTDATAOFF; + for (last = NULL, p = dbt->data, sz = dbt->size;; + p = (char *)p + plen, last = h) { + if ((h = __bt_new(t, &npg)) == NULL) + return (RET_ERROR); + + h->pgno = npg; + h->nextpg = h->prevpg = P_INVALID; + h->flags = P_OVERFLOW; + h->lower = h->upper = 0; + + nb = MIN(sz, plen); + memmove((char *)h + BTDATAOFF, p, nb); + + if (last) { + last->nextpg = h->pgno; + mpool_put(t->bt_mp, last, MPOOL_DIRTY); + } else + *pg = h->pgno; + + if ((sz -= nb) == 0) { + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + break; + } + } + return (RET_SUCCESS); +} + +/* + * __OVFL_DELETE -- Delete an overflow chain. + * + * Parameters: + * t: tree + * p: pointer to { pgno_t, u_int32_t } + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__ovfl_delete(t, p) + BTREE *t; + void *p; +{ + PAGE *h; + pgno_t pg; + size_t plen; + u_int32_t sz; + + memmove(&pg, p, sizeof(pgno_t)); + memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t)); + +#ifdef DEBUG + if (pg == P_INVALID || sz == 0) + abort(); +#endif + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + + /* Don't delete chains used by internal pages. */ + if (h->flags & P_PRESERVE) { + mpool_put(t->bt_mp, h, 0); + return (RET_SUCCESS); + } + + /* Step through the chain, calling the free routine for each page. */ + for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) { + pg = h->nextpg; + __bt_free(t, h); + if (sz <= plen) + break; + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + } + return (RET_SUCCESS); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_page.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_page.c new file mode 100644 index 0000000..ce9cbf1 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_page.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_page.c 8.3 (Berkeley) 7/14/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include + +#include +#include "btree.h" + +/* + * __bt_free -- + * Put a page on the freelist. + * + * Parameters: + * t: tree + * h: page to free + * + * Returns: + * RET_ERROR, RET_SUCCESS + * + * Side-effect: + * mpool_put's the page. + */ +int +__bt_free(t, h) + BTREE *t; + PAGE *h; +{ + /* Insert the page at the head of the free list. */ + h->prevpg = P_INVALID; + h->nextpg = t->bt_free; + t->bt_free = h->pgno; + F_SET(t, B_METADIRTY); + + /* Make sure the page gets written back. */ + return (mpool_put(t->bt_mp, h, MPOOL_DIRTY)); +} + +/* + * __bt_new -- + * Get a new page, preferably from the freelist. + * + * Parameters: + * t: tree + * npg: storage for page number. + * + * Returns: + * Pointer to a page, NULL on error. + */ +PAGE * +__bt_new(t, npg) + BTREE *t; + pgno_t *npg; +{ + PAGE *h; + + if (t->bt_free != P_INVALID && + (h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) { + *npg = t->bt_free; + t->bt_free = h->nextpg; + F_SET(t, B_METADIRTY); + return (h); + } + return (mpool_new(t->bt_mp, npg)); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_put.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_put.c new file mode 100644 index 0000000..4f3bd1f --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_put.c @@ -0,0 +1,321 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_put.c 8.8 (Berkeley) 7/26/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include +#include + +#include +#include "btree.h" + +static EPG *bt_fast __P((BTREE *, const DBT *, const DBT *, int *)); + +/* + * __BT_PUT -- Add a btree item to the tree. + * + * Parameters: + * dbp: pointer to access method + * key: key + * data: data + * flag: R_NOOVERWRITE + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the + * tree and R_NOOVERWRITE specified. + */ +int +__bt_put(dbp, key, data, flags) + const DB *dbp; + DBT *key; + const DBT *data; + u_int flags; +{ + BTREE *t; + DBT tkey, tdata; + EPG *e = NULL; + PAGE *h; + indx_t index, nxtindex; + pgno_t pg; + u_int32_t nbytes; + int dflags, exact, status; + char *dest, db[NOVFLSIZE], kb[NOVFLSIZE]; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Check for change to a read-only tree. */ + if (F_ISSET(t, B_RDONLY)) { + errno = EPERM; + return (RET_ERROR); + } + + switch (flags) { + case 0: + case R_NOOVERWRITE: + break; + case R_CURSOR: + /* + * If flags is R_CURSOR, put the cursor. Must already + * have started a scan and not have already deleted it. + */ + if (F_ISSET(&t->bt_cursor, CURS_INIT) && + !F_ISSET(&t->bt_cursor, + CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE)) + break; + /* FALLTHROUGH */ + default: + errno = EINVAL; + return (RET_ERROR); + } + + /* + * If the key/data pair won't fit on a page, store it on overflow + * pages. Only put the key on the overflow page if the pair are + * still too big after moving the data to an overflow page. + * + * XXX + * If the insert fails later on, the overflow pages aren't recovered. + */ + dflags = 0; + if (key->size + data->size > t->bt_ovflsize) { + if (key->size > t->bt_ovflsize) { +storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) + return (RET_ERROR); + tkey.data = kb; + tkey.size = NOVFLSIZE; + memmove(kb, &pg, sizeof(pgno_t)); + memmove(kb + sizeof(pgno_t), + &key->size, sizeof(u_int32_t)); + dflags |= P_BIGKEY; + key = &tkey; + } + if (key->size + data->size > t->bt_ovflsize) { + if (__ovfl_put(t, data, &pg) == RET_ERROR) + return (RET_ERROR); + tdata.data = db; + tdata.size = NOVFLSIZE; + memmove(db, &pg, sizeof(pgno_t)); + memmove(db + sizeof(pgno_t), + &data->size, sizeof(u_int32_t)); + dflags |= P_BIGDATA; + data = &tdata; + } + if (key->size + data->size > t->bt_ovflsize) + goto storekey; + } + + /* Replace the cursor. */ + if (flags == R_CURSOR) { + if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL) + return (RET_ERROR); + index = t->bt_cursor.pg.index; + goto delete; + } + + /* + * Find the key to delete, or, the location at which to insert. + * Bt_fast and __bt_search both pin the returned page. + */ + if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL) + if ((e = __bt_search(t, key, &exact)) == NULL) + return (RET_ERROR); + h = e->page; + index = e->index; + + /* + * Add the key/data pair to the tree. If an identical key is already + * in the tree, and R_NOOVERWRITE is set, an error is returned. If + * R_NOOVERWRITE is not set, the key is either added (if duplicates are + * permitted) or an error is returned. + */ + switch (flags) { + case R_NOOVERWRITE: + if (!exact) + break; + mpool_put(t->bt_mp, h, 0); + return (RET_SPECIAL); + default: + if (!exact || !F_ISSET(t, B_NODUPS)) + break; + /* + * !!! + * Note, the delete may empty the page, so we need to put a + * new entry into the page immediately. + */ +delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) { + mpool_put(t->bt_mp, h, 0); + return (RET_ERROR); + } + break; + } + + /* + * If not enough room, or the user has put a ceiling on the number of + * keys permitted in the page, split the page. The split code will + * insert the key and data and unpin the current page. If inserting + * into the offset array, shift the pointers up. + */ + nbytes = NBLEAFDBT(key->size, data->size); + if (h->upper - h->lower < nbytes + sizeof(indx_t)) { + if ((status = __bt_split(t, h, key, + data, dflags, nbytes, index)) != RET_SUCCESS) + return (status); + goto success; + } + + if (index < (nxtindex = NEXTINDEX(h))) + memmove(h->linp + index + 1, h->linp + index, + (nxtindex - index) * sizeof(indx_t)); + h->lower += sizeof(indx_t); + + h->linp[index] = h->upper -= nbytes; + dest = (char *)h + h->upper; + WR_BLEAF(dest, key, data, dflags); + + /* If the cursor is on this page, adjust it as necessary. */ + if (F_ISSET(&t->bt_cursor, CURS_INIT) && + !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) && + t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= index) + ++t->bt_cursor.pg.index; + + if (t->bt_order == NOT) { + if (h->nextpg == P_INVALID) { + if (index == NEXTINDEX(h) - 1) { + t->bt_order = FORWARD; + t->bt_last.index = index; + t->bt_last.pgno = h->pgno; + } + } else if (h->prevpg == P_INVALID) { + if (index == 0) { + t->bt_order = BACK; + t->bt_last.index = 0; + t->bt_last.pgno = h->pgno; + } + } + } + + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + +success: + if (flags == R_SETCURSOR) + __bt_setcur(t, e->page->pgno, e->index); + + F_SET(t, B_MODIFIED); + return (RET_SUCCESS); +} + +#ifdef STATISTICS +u_long bt_cache_hit, bt_cache_miss; +#endif + +/* + * BT_FAST -- Do a quick check for sorted data. + * + * Parameters: + * t: tree + * key: key to insert + * + * Returns: + * EPG for new record or NULL if not found. + */ +static EPG * +bt_fast(t, key, data, exactp) + BTREE *t; + const DBT *key, *data; + int *exactp; +{ + PAGE *h; + u_int32_t nbytes; + int cmp; + + if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) { + t->bt_order = NOT; + return (NULL); + } + t->bt_cur.page = h; + t->bt_cur.index = t->bt_last.index; + + /* + * If won't fit in this page or have too many keys in this page, + * have to search to get split stack. + */ + nbytes = NBLEAFDBT(key->size, data->size); + if (h->upper - h->lower < nbytes + sizeof(indx_t)) + goto miss; + + if (t->bt_order == FORWARD) { + if (t->bt_cur.page->nextpg != P_INVALID) + goto miss; + if (t->bt_cur.index != NEXTINDEX(h) - 1) + goto miss; + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0) + goto miss; + t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index; + } else { + if (t->bt_cur.page->prevpg != P_INVALID) + goto miss; + if (t->bt_cur.index != 0) + goto miss; + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0) + goto miss; + t->bt_last.index = 0; + } + *exactp = cmp == 0; +#ifdef STATISTICS + ++bt_cache_hit; +#endif + return (&t->bt_cur); + +miss: +#ifdef STATISTICS + ++bt_cache_miss; +#endif + t->bt_order = NOT; + mpool_put(t->bt_mp, h, 0); + return (NULL); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_search.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_search.c new file mode 100644 index 0000000..485afcb --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_search.c @@ -0,0 +1,213 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include + +#include +#include "btree.h" + +static int __bt_snext __P((BTREE *, PAGE *, const DBT *, int *)); +static int __bt_sprev __P((BTREE *, PAGE *, const DBT *, int *)); + +/* + * __bt_search -- + * Search a btree for a key. + * + * Parameters: + * t: tree to search + * key: key to find + * exactp: pointer to exact match flag + * + * Returns: + * The EPG for matching record, if any, or the EPG for the location + * of the key, if it were inserted into the tree, is entered into + * the bt_cur field of the tree. A pointer to the field is returned. + */ +EPG * +__bt_search(t, key, exactp) + BTREE *t; + const DBT *key; + int *exactp; +{ + PAGE *h; + indx_t base, index, lim; + pgno_t pg; + int cmp; + + BT_CLR(t); + for (pg = P_ROOT;;) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (NULL); + + /* Do a binary search on the current page. */ + t->bt_cur.page = h; + for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) { + t->bt_cur.index = index = base + (lim >> 1); + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) { + if (h->flags & P_BLEAF) { + *exactp = 1; + return (&t->bt_cur); + } + goto next; + } + if (cmp > 0) { + base = index + 1; + --lim; + } + } + + /* + * If it's a leaf page, we're almost done. If no duplicates + * are allowed, or we have an exact match, we're done. Else, + * it's possible that there were matching keys on this page, + * which later deleted, and we're on a page with no matches + * while there are matches on other pages. If at the start or + * end of a page, check the adjacent page. + */ + if (h->flags & P_BLEAF) { + if (!F_ISSET(t, B_NODUPS)) { + if (base == 0 && + h->prevpg != P_INVALID && + __bt_sprev(t, h, key, exactp)) + return (&t->bt_cur); + if (base == NEXTINDEX(h) && + h->nextpg != P_INVALID && + __bt_snext(t, h, key, exactp)) + return (&t->bt_cur); + } + *exactp = 0; + t->bt_cur.index = base; + return (&t->bt_cur); + } + + /* + * No match found. Base is the smallest index greater than + * key and may be zero or a last + 1 index. If it's non-zero, + * decrement by one, and record the internal page which should + * be a parent page for the key. If a split later occurs, the + * inserted page will be to the right of the saved page. + */ + index = base ? base - 1 : base; + +next: BT_PUSH(t, h->pgno, index); + pg = GETBINTERNAL(h, index)->pgno; + mpool_put(t->bt_mp, h, 0); + } +} + +/* + * __bt_snext -- + * Check for an exact match after the key. + * + * Parameters: + * t: tree + * h: current page + * key: key + * exactp: pointer to exact match flag + * + * Returns: + * If an exact match found. + */ +static int +__bt_snext(t, h, key, exactp) + BTREE *t; + PAGE *h; + const DBT *key; + int *exactp; +{ + EPG e; + + /* + * Get the next page. The key is either an exact + * match, or not as good as the one we already have. + */ + if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) + return (0); + e.index = 0; + if (__bt_cmp(t, key, &e) == 0) { + mpool_put(t->bt_mp, h, 0); + t->bt_cur = e; + *exactp = 1; + return (1); + } + mpool_put(t->bt_mp, e.page, 0); + return (0); +} + +/* + * __bt_sprev -- + * Check for an exact match before the key. + * + * Parameters: + * t: tree + * h: current page + * key: key + * exactp: pointer to exact match flag + * + * Returns: + * If an exact match found. + */ +static int +__bt_sprev(t, h, key, exactp) + BTREE *t; + PAGE *h; + const DBT *key; + int *exactp; +{ + EPG e; + + /* + * Get the previous page. The key is either an exact + * match, or not as good as the one we already have. + */ + if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) + return (0); + e.index = NEXTINDEX(e.page) - 1; + if (__bt_cmp(t, key, &e) == 0) { + mpool_put(t->bt_mp, h, 0); + t->bt_cur = e; + *exactp = 1; + return (1); + } + mpool_put(t->bt_mp, e.page, 0); + return (0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_seq.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_seq.c new file mode 100644 index 0000000..d5a700d --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_seq.c @@ -0,0 +1,460 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include +#include + +#include +#include "btree.h" + +static int __bt_first __P((BTREE *, const DBT *, EPG *, int *)); +static int __bt_seqadv __P((BTREE *, EPG *, int)); +static int __bt_seqset __P((BTREE *, EPG *, DBT *, int)); + +/* + * Sequential scan support. + * + * The tree can be scanned sequentially, starting from either end of the + * tree or from any specific key. A scan request before any scanning is + * done is initialized as starting from the least node. + */ + +/* + * __bt_seq -- + * Btree sequential scan interface. + * + * Parameters: + * dbp: pointer to access method + * key: key for positioning and return value + * data: data return value + * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV. + * + * Returns: + * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. + */ +int +__bt_seq(dbp, key, data, flags) + const DB *dbp; + DBT *key, *data; + u_int flags; +{ + BTREE *t; + EPG e; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* + * If scan unitialized as yet, or starting at a specific record, set + * the scan to a specific key. Both __bt_seqset and __bt_seqadv pin + * the page the cursor references if they're successful. + */ + switch (flags) { + case R_NEXT: + case R_PREV: + if (F_ISSET(&t->bt_cursor, CURS_INIT)) { + status = __bt_seqadv(t, &e, flags); + break; + } + /* FALLTHROUGH */ + case R_FIRST: + case R_LAST: + case R_CURSOR: + status = __bt_seqset(t, &e, key, flags); + break; + default: + errno = EINVAL; + return (RET_ERROR); + } + + if (status == RET_SUCCESS) { + __bt_setcur(t, e.page->pgno, e.index); + + status = + __bt_ret(t, &e, key, &t->bt_rkey, data, &t->bt_rdata, 0); + + /* + * If the user is doing concurrent access, we copied the + * key/data, toss the page. + */ + if (F_ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e.page, 0); + else + t->bt_pinned = e.page; + } + return (status); +} + +/* + * __bt_seqset -- + * Set the sequential scan to a specific key. + * + * Parameters: + * t: tree + * ep: storage for returned key + * key: key for initial scan position + * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV + * + * Side effects: + * Pins the page the cursor references. + * + * Returns: + * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. + */ +static int +__bt_seqset(t, ep, key, flags) + BTREE *t; + EPG *ep; + DBT *key; + int flags; +{ + PAGE *h; + pgno_t pg; + int exact; + + /* + * Find the first, last or specific key in the tree and point the + * cursor at it. The cursor may not be moved until a new key has + * been found. + */ + switch (flags) { + case R_CURSOR: /* Keyed scan. */ + /* + * Find the first instance of the key or the smallest key + * which is greater than or equal to the specified key. + */ + if (key->data == NULL || key->size == 0) { + errno = EINVAL; + return (RET_ERROR); + } + return (__bt_first(t, key, ep, &exact)); + case R_FIRST: /* First record. */ + case R_NEXT: + /* Walk down the left-hand side of the tree. */ + for (pg = P_ROOT;;) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + + /* Check for an empty tree. */ + if (NEXTINDEX(h) == 0) { + mpool_put(t->bt_mp, h, 0); + return (RET_SPECIAL); + } + + if (h->flags & (P_BLEAF | P_RLEAF)) + break; + pg = GETBINTERNAL(h, 0)->pgno; + mpool_put(t->bt_mp, h, 0); + } + ep->page = h; + ep->index = 0; + break; + case R_LAST: /* Last record. */ + case R_PREV: + /* Walk down the right-hand side of the tree. */ + for (pg = P_ROOT;;) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + + /* Check for an empty tree. */ + if (NEXTINDEX(h) == 0) { + mpool_put(t->bt_mp, h, 0); + return (RET_SPECIAL); + } + + if (h->flags & (P_BLEAF | P_RLEAF)) + break; + pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno; + mpool_put(t->bt_mp, h, 0); + } + + ep->page = h; + ep->index = NEXTINDEX(h) - 1; + break; + } + return (RET_SUCCESS); +} + +/* + * __bt_seqadvance -- + * Advance the sequential scan. + * + * Parameters: + * t: tree + * flags: R_NEXT, R_PREV + * + * Side effects: + * Pins the page the new key/data record is on. + * + * Returns: + * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. + */ +static int +__bt_seqadv(t, ep, flags) + BTREE *t; + EPG *ep; + int flags; +{ + CURSOR *c; + PAGE *h; + indx_t index = 0; + pgno_t pg; + int exact; + + /* + * There are a couple of states that we can be in. The cursor has + * been initialized by the time we get here, but that's all we know. + */ + c = &t->bt_cursor; + + /* + * The cursor was deleted where there weren't any duplicate records, + * so the key was saved. Find out where that key would go in the + * current tree. It doesn't matter if the returned key is an exact + * match or not -- if it's an exact match, the record was added after + * the delete so we can just return it. If not, as long as there's + * a record there, return it. + */ + if (F_ISSET(c, CURS_ACQUIRE)) + return (__bt_first(t, &c->key, ep, &exact)); + + /* Get the page referenced by the cursor. */ + if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL) + return (RET_ERROR); + + /* + * Find the next/previous record in the tree and point the cursor at + * it. The cursor may not be moved until a new key has been found. + */ + switch (flags) { + case R_NEXT: /* Next record. */ + /* + * The cursor was deleted in duplicate records, and moved + * forward to a record that has yet to be returned. Clear + * that flag, and return the record. + */ + if (F_ISSET(c, CURS_AFTER)) + goto usecurrent; + index = c->pg.index; + if (++index == NEXTINDEX(h)) { + pg = h->nextpg; + mpool_put(t->bt_mp, h, 0); + if (pg == P_INVALID) + return (RET_SPECIAL); + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + index = 0; + } + break; + case R_PREV: /* Previous record. */ + /* + * The cursor was deleted in duplicate records, and moved + * backward to a record that has yet to be returned. Clear + * that flag, and return the record. + */ + if (F_ISSET(c, CURS_BEFORE)) { +usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE); + ep->page = h; + ep->index = c->pg.index; + return (RET_SUCCESS); + } + index = c->pg.index; + if (index == 0) { + pg = h->prevpg; + mpool_put(t->bt_mp, h, 0); + if (pg == P_INVALID) + return (RET_SPECIAL); + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + index = NEXTINDEX(h) - 1; + } else + --index; + break; + } + + ep->page = h; + ep->index = index; + return (RET_SUCCESS); +} + +/* + * __bt_first -- + * Find the first entry. + * + * Parameters: + * t: the tree + * key: the key + * erval: return EPG + * exactp: pointer to exact match flag + * + * Returns: + * The first entry in the tree greater than or equal to key, + * or RET_SPECIAL if no such key exists. + */ +static int +__bt_first(t, key, erval, exactp) + BTREE *t; + const DBT *key; + EPG *erval; + int *exactp; +{ + PAGE *h; + EPG *ep, save; + pgno_t pg; + + /* + * Find any matching record; __bt_search pins the page. + * + * If it's an exact match and duplicates are possible, walk backwards + * in the tree until we find the first one. Otherwise, make sure it's + * a valid key (__bt_search may return an index just past the end of a + * page) and return it. + */ + if ((ep = __bt_search(t, key, exactp)) == NULL) + return (RET_SPECIAL); + if (*exactp) { + if (F_ISSET(t, B_NODUPS)) { + *erval = *ep; + return (RET_SUCCESS); + } + + /* + * Walk backwards, as long as the entry matches and there are + * keys left in the tree. Save a copy of each match in case + * we go too far. + */ + save = *ep; + h = ep->page; + do { + if (save.page->pgno != ep->page->pgno) { + mpool_put(t->bt_mp, save.page, 0); + save = *ep; + } else + save.index = ep->index; + + /* + * Don't unpin the page the last (or original) match + * was on, but make sure it's unpinned if an error + * occurs. + */ + if (ep->index == 0) { + if (h->prevpg == P_INVALID) + break; + if (h->pgno != save.page->pgno) + mpool_put(t->bt_mp, h, 0); + if ((h = mpool_get(t->bt_mp, + h->prevpg, 0)) == NULL) { + if (h->pgno == save.page->pgno) + mpool_put(t->bt_mp, + save.page, 0); + return (RET_ERROR); + } + ep->page = h; + ep->index = NEXTINDEX(h); + } + --ep->index; + } while (__bt_cmp(t, key, ep) == 0); + + /* + * Reach here with the last page that was looked at pinned, + * which may or may not be the same as the last (or original) + * match page. If it's not useful, release it. + */ + if (h->pgno != save.page->pgno) + mpool_put(t->bt_mp, h, 0); + + *erval = save; + return (RET_SUCCESS); + } + + /* If at the end of a page, find the next entry. */ + if (ep->index == NEXTINDEX(ep->page)) { + h = ep->page; + pg = h->nextpg; + mpool_put(t->bt_mp, h, 0); + if (pg == P_INVALID) + return (RET_SPECIAL); + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + ep->index = 0; + ep->page = h; + } + *erval = *ep; + return (RET_SUCCESS); +} + +/* + * __bt_setcur -- + * Set the cursor to an entry in the tree. + * + * Parameters: + * t: the tree + * pgno: page number + * index: page index + */ +void +__bt_setcur(t, pgno, index) + BTREE *t; + pgno_t pgno; + u_int index; +{ + /* Lose any already deleted key. */ + if (t->bt_cursor.key.data != NULL) { + free(t->bt_cursor.key.data); + t->bt_cursor.key.size = 0; + t->bt_cursor.key.data = NULL; + } + F_CLR(&t->bt_cursor, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE); + + /* Update the cursor. */ + t->bt_cursor.pg.pgno = pgno; + t->bt_cursor.pg.index = index; + F_SET(&t->bt_cursor, CURS_INIT); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_split.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_split.c new file mode 100644 index 0000000..e743178 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_split.c @@ -0,0 +1,834 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include +#include + +#include +#include "btree.h" + +static int bt_broot __P((BTREE *, PAGE *, PAGE *, PAGE *)); +static PAGE *bt_page + __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t)); +static int bt_preserve __P((BTREE *, pgno_t)); +static PAGE *bt_psplit + __P((BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t)); +static PAGE *bt_root + __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t)); +static int bt_rroot __P((BTREE *, PAGE *, PAGE *, PAGE *)); +static recno_t rec_total __P((PAGE *)); + +#ifdef STATISTICS +u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved; +#endif + +/* + * __BT_SPLIT -- Split the tree. + * + * Parameters: + * t: tree + * sp: page to split + * key: key to insert + * data: data to insert + * flags: BIGKEY/BIGDATA flags + * ilen: insert length + * skip: index to leave open + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__bt_split(t, sp, key, data, flags, ilen, argskip) + BTREE *t; + PAGE *sp; + const DBT *key, *data; + int flags; + size_t ilen; + u_int32_t argskip; +{ + BINTERNAL *bi = NULL; + BLEAF *bl = NULL, *tbl; + DBT a, b; + EPGNO *parent; + PAGE *h, *l, *r, *lchild, *rchild; + indx_t nxtindex; + u_int16_t skip; + u_int32_t n, nbytes, nksize = 0; + int parentsplit; + char *dest; + pgno_t pg_tmp; + + /* + * Split the page into two pages, l and r. The split routines return + * a pointer to the page into which the key should be inserted and with + * skip set to the offset which should be used. Additionally, l and r + * are pinned. + */ + skip = argskip; + h = sp->pgno == P_ROOT ? + bt_root(t, sp, &l, &r, &skip, ilen) : + bt_page(t, sp, &l, &r, &skip, ilen); + if (h == NULL) + return (RET_ERROR); + + /* + * Insert the new key/data pair into the leaf page. (Key inserts + * always cause a leaf page to split first.) + */ + h->linp[skip] = h->upper -= ilen; + dest = (char *)h + h->upper; + if (F_ISSET(t, R_RECNO)) + WR_RLEAF(dest, data, flags) + else + WR_BLEAF(dest, key, data, flags) + + /* If the root page was split, make it look right. */ + if (sp->pgno == P_ROOT && + (F_ISSET(t, R_RECNO) ? + bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR) + goto err2; + + /* + * Now we walk the parent page stack -- a LIFO stack of the pages that + * were traversed when we searched for the page that split. Each stack + * entry is a page number and a page index offset. The offset is for + * the page traversed on the search. We've just split a page, so we + * have to insert a new key into the parent page. + * + * If the insert into the parent page causes it to split, may have to + * continue splitting all the way up the tree. We stop if the root + * splits or the page inserted into didn't have to split to hold the + * new key. Some algorithms replace the key for the old page as well + * as the new page. We don't, as there's no reason to believe that the + * first key on the old page is any better than the key we have, and, + * in the case of a key being placed at index 0 causing the split, the + * key is unavailable. + * + * There are a maximum of 5 pages pinned at any time. We keep the left + * and right pages pinned while working on the parent. The 5 are the + * two children, left parent and right parent (when the parent splits) + * and the root page or the overflow key page when calling bt_preserve. + * This code must make sure that all pins are released other than the + * root page or overflow page which is unlocked elsewhere. + */ + while ((parent = BT_POP(t)) != NULL) { + lchild = l; + rchild = r; + + /* Get the parent page. */ + if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) + goto err2; + + /* + * The new key goes ONE AFTER the index, because the split + * was to the right. + */ + skip = parent->index + 1; + + /* + * Calculate the space needed on the parent page. + * + * Prefix trees: space hack when inserting into BINTERNAL + * pages. Retain only what's needed to distinguish between + * the new entry and the LAST entry on the page to its left. + * If the keys compare equal, retain the entire key. Note, + * we don't touch overflow keys, and the entire key must be + * retained for the next-to-left most key on the leftmost + * page of each level, or the search will fail. Applicable + * ONLY to internal pages that have leaf pages as children. + * Further reduction of the key between pairs of internal + * pages loses too much information. + */ + switch (rchild->flags & P_TYPE) { + case P_BINTERNAL: + bi = GETBINTERNAL(rchild, 0); + nbytes = NBINTERNAL(bi->ksize); + break; + case P_BLEAF: + bl = GETBLEAF(rchild, 0); + nbytes = NBINTERNAL(bl->ksize); + if (t->bt_pfx && !(bl->flags & P_BIGKEY) && + (h->prevpg != P_INVALID || skip > 1)) { + tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1); + a.size = tbl->ksize; + a.data = tbl->bytes; + b.size = bl->ksize; + b.data = bl->bytes; + nksize = t->bt_pfx(&a, &b); + n = NBINTERNAL(nksize); + if (n < nbytes) { +#ifdef STATISTICS + bt_pfxsaved += nbytes - n; +#endif + nbytes = n; + } else + nksize = 0; + } else + nksize = 0; + break; + case P_RINTERNAL: + case P_RLEAF: + nbytes = NRINTERNAL; + break; + default: + abort(); + } + + /* Split the parent page if necessary or shift the indices. */ + if (h->upper - h->lower < nbytes + sizeof(indx_t)) { + sp = h; + h = h->pgno == P_ROOT ? + bt_root(t, h, &l, &r, &skip, nbytes) : + bt_page(t, h, &l, &r, &skip, nbytes); + if (h == NULL) + goto err1; + parentsplit = 1; + } else { + if (skip < (nxtindex = NEXTINDEX(h))) + memmove(h->linp + skip + 1, h->linp + skip, + (nxtindex - skip) * sizeof(indx_t)); + h->lower += sizeof(indx_t); + parentsplit = 0; + } + + /* Insert the key into the parent page. */ + switch (rchild->flags & P_TYPE) { + case P_BINTERNAL: + h->linp[skip] = h->upper -= nbytes; + dest = (char *)h + h->linp[skip]; + memmove(dest, bi, nbytes); + ((BINTERNAL *)dest)->pgno = rchild->pgno; + break; + case P_BLEAF: + h->linp[skip] = h->upper -= nbytes; + dest = (char *)h + h->linp[skip]; + WR_BINTERNAL(dest, nksize ? nksize : bl->ksize, + rchild->pgno, bl->flags & P_BIGKEY); + memmove(dest, bl->bytes, nksize ? nksize : bl->ksize); + /* Avoid alignment violation */ + memcpy(&pg_tmp, bl->bytes, sizeof(pgno_t)); + if (bl->flags & P_BIGKEY && + bt_preserve(t, pg_tmp) == RET_ERROR) + goto err1; + break; + case P_RINTERNAL: + /* + * Update the left page count. If split + * added at index 0, fix the correct page. + */ + if (skip > 0) + dest = (char *)h + h->linp[skip - 1]; + else + dest = (char *)l + l->linp[NEXTINDEX(l) - 1]; + ((RINTERNAL *)dest)->nrecs = rec_total(lchild); + ((RINTERNAL *)dest)->pgno = lchild->pgno; + + /* Update the right page count. */ + h->linp[skip] = h->upper -= nbytes; + dest = (char *)h + h->linp[skip]; + ((RINTERNAL *)dest)->nrecs = rec_total(rchild); + ((RINTERNAL *)dest)->pgno = rchild->pgno; + break; + case P_RLEAF: + /* + * Update the left page count. If split + * added at index 0, fix the correct page. + */ + if (skip > 0) + dest = (char *)h + h->linp[skip - 1]; + else + dest = (char *)l + l->linp[NEXTINDEX(l) - 1]; + ((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild); + ((RINTERNAL *)dest)->pgno = lchild->pgno; + + /* Update the right page count. */ + h->linp[skip] = h->upper -= nbytes; + dest = (char *)h + h->linp[skip]; + ((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild); + ((RINTERNAL *)dest)->pgno = rchild->pgno; + break; + default: + abort(); + } + + /* Unpin the held pages. */ + if (!parentsplit) { + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + break; + } + + /* If the root page was split, make it look right. */ + if (sp->pgno == P_ROOT && + (F_ISSET(t, R_RECNO) ? + bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR) + goto err1; + + mpool_put(t->bt_mp, lchild, MPOOL_DIRTY); + mpool_put(t->bt_mp, rchild, MPOOL_DIRTY); + } + + /* Unpin the held pages. */ + mpool_put(t->bt_mp, l, MPOOL_DIRTY); + mpool_put(t->bt_mp, r, MPOOL_DIRTY); + + /* Clear any pages left on the stack. */ + return (RET_SUCCESS); + + /* + * If something fails in the above loop we were already walking back + * up the tree and the tree is now inconsistent. Nothing much we can + * do about it but release any memory we're holding. + */ +err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY); + mpool_put(t->bt_mp, rchild, MPOOL_DIRTY); + +err2: mpool_put(t->bt_mp, l, 0); + mpool_put(t->bt_mp, r, 0); + __dbpanic(t->bt_dbp); + return (RET_ERROR); +} + +/* + * BT_PAGE -- Split a non-root page of a btree. + * + * Parameters: + * t: tree + * h: root page + * lp: pointer to left page pointer + * rp: pointer to right page pointer + * skip: pointer to index to leave open + * ilen: insert length + * + * Returns: + * Pointer to page in which to insert or NULL on error. + */ +static PAGE * +bt_page(t, h, lp, rp, skip, ilen) + BTREE *t; + PAGE *h, **lp, **rp; + indx_t *skip; + size_t ilen; +{ + PAGE *l, *r, *tp; + pgno_t npg; + +#ifdef STATISTICS + ++bt_split; +#endif + /* Put the new right page for the split into place. */ + if ((r = __bt_new(t, &npg)) == NULL) + return (NULL); + r->pgno = npg; + r->lower = BTDATAOFF; + r->upper = t->bt_psize; + r->nextpg = h->nextpg; + r->prevpg = h->pgno; + r->flags = h->flags & P_TYPE; + + /* + * If we're splitting the last page on a level because we're appending + * a key to it (skip is NEXTINDEX()), it's likely that the data is + * sorted. Adding an empty page on the side of the level is less work + * and can push the fill factor much higher than normal. If we're + * wrong it's no big deal, we'll just do the split the right way next + * time. It may look like it's equally easy to do a similar hack for + * reverse sorted data, that is, split the tree left, but it's not. + * Don't even try. + */ + if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) { +#ifdef STATISTICS + ++bt_sortsplit; +#endif + h->nextpg = r->pgno; + r->lower = BTDATAOFF + sizeof(indx_t); + *skip = 0; + *lp = h; + *rp = r; + return (r); + } + + /* Put the new left page for the split into place. */ + if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) { + mpool_put(t->bt_mp, r, 0); + return (NULL); + } +#ifdef PURIFY + memset(l, 0xff, t->bt_psize); +#endif + l->pgno = h->pgno; + l->nextpg = r->pgno; + l->prevpg = h->prevpg; + l->lower = BTDATAOFF; + l->upper = t->bt_psize; + l->flags = h->flags & P_TYPE; + + /* Fix up the previous pointer of the page after the split page. */ + if (h->nextpg != P_INVALID) { + if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) { + free(l); + /* XXX mpool_free(t->bt_mp, r->pgno); */ + return (NULL); + } + tp->prevpg = r->pgno; + mpool_put(t->bt_mp, tp, MPOOL_DIRTY); + } + + /* + * Split right. The key/data pairs aren't sorted in the btree page so + * it's simpler to copy the data from the split page onto two new pages + * instead of copying half the data to the right page and compacting + * the left page in place. Since the left page can't change, we have + * to swap the original and the allocated left page after the split. + */ + tp = bt_psplit(t, h, l, r, skip, ilen); + + /* Move the new left page onto the old left page. */ + memmove(h, l, t->bt_psize); + if (tp == l) + tp = h; + free(l); + + *lp = h; + *rp = r; + return (tp); +} + +/* + * BT_ROOT -- Split the root page of a btree. + * + * Parameters: + * t: tree + * h: root page + * lp: pointer to left page pointer + * rp: pointer to right page pointer + * skip: pointer to index to leave open + * ilen: insert length + * + * Returns: + * Pointer to page in which to insert or NULL on error. + */ +static PAGE * +bt_root(t, h, lp, rp, skip, ilen) + BTREE *t; + PAGE *h, **lp, **rp; + indx_t *skip; + size_t ilen; +{ + PAGE *l, *r, *tp; + pgno_t lnpg, rnpg; + +#ifdef STATISTICS + ++bt_split; + ++bt_rootsplit; +#endif + /* Put the new left and right pages for the split into place. */ + if ((l = __bt_new(t, &lnpg)) == NULL || + (r = __bt_new(t, &rnpg)) == NULL) + return (NULL); + l->pgno = lnpg; + r->pgno = rnpg; + l->nextpg = r->pgno; + r->prevpg = l->pgno; + l->prevpg = r->nextpg = P_INVALID; + l->lower = r->lower = BTDATAOFF; + l->upper = r->upper = t->bt_psize; + l->flags = r->flags = h->flags & P_TYPE; + + /* Split the root page. */ + tp = bt_psplit(t, h, l, r, skip, ilen); + + *lp = l; + *rp = r; + return (tp); +} + +/* + * BT_RROOT -- Fix up the recno root page after it has been split. + * + * Parameters: + * t: tree + * h: root page + * l: left page + * r: right page + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +static int +bt_rroot(t, h, l, r) + BTREE *t; + PAGE *h, *l, *r; +{ + char *dest; + + /* Insert the left and right keys, set the header information. */ + h->linp[0] = h->upper = t->bt_psize - NRINTERNAL; + dest = (char *)h + h->upper; + WR_RINTERNAL(dest, + l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno); + + h->linp[1] = h->upper -= NRINTERNAL; + dest = (char *)h + h->upper; + WR_RINTERNAL(dest, + r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno); + + h->lower = BTDATAOFF + 2 * sizeof(indx_t); + + /* Unpin the root page, set to recno internal page. */ + h->flags &= ~P_TYPE; + h->flags |= P_RINTERNAL; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + + return (RET_SUCCESS); +} + +/* + * BT_BROOT -- Fix up the btree root page after it has been split. + * + * Parameters: + * t: tree + * h: root page + * l: left page + * r: right page + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +static int +bt_broot(t, h, l, r) + BTREE *t; + PAGE *h, *l, *r; +{ + BINTERNAL *bi; + BLEAF *bl; + u_int32_t nbytes; + char *dest; + pgno_t pg_tmp; + + /* + * If the root page was a leaf page, change it into an internal page. + * We copy the key we split on (but not the key's data, in the case of + * a leaf page) to the new root page. + * + * The btree comparison code guarantees that the left-most key on any + * level of the tree is never used, so it doesn't need to be filled in. + */ + nbytes = NBINTERNAL(0); + h->linp[0] = h->upper = t->bt_psize - nbytes; + dest = (char *)h + h->upper; + WR_BINTERNAL(dest, 0, l->pgno, 0); + + switch (h->flags & P_TYPE) { + case P_BLEAF: + bl = GETBLEAF(r, 0); + nbytes = NBINTERNAL(bl->ksize); + h->linp[1] = h->upper -= nbytes; + dest = (char *)h + h->upper; + WR_BINTERNAL(dest, bl->ksize, r->pgno, 0); + memmove(dest, bl->bytes, bl->ksize); + + /* + * If the key is on an overflow page, mark the overflow chain + * so it isn't deleted when the leaf copy of the key is deleted. + */ + /* Avoid alignment violation */ + memcpy(&pg_tmp, bl->bytes, sizeof(pgno_t)); + if (bl->flags & P_BIGKEY && + bt_preserve(t, pg_tmp) == RET_ERROR) + return (RET_ERROR); + break; + case P_BINTERNAL: + bi = GETBINTERNAL(r, 0); + nbytes = NBINTERNAL(bi->ksize); + h->linp[1] = h->upper -= nbytes; + dest = (char *)h + h->upper; + memmove(dest, bi, nbytes); + ((BINTERNAL *)dest)->pgno = r->pgno; + break; + default: + abort(); + } + + /* There are two keys on the page. */ + h->lower = BTDATAOFF + 2 * sizeof(indx_t); + + /* Unpin the root page, set to btree internal page. */ + h->flags &= ~P_TYPE; + h->flags |= P_BINTERNAL; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + + return (RET_SUCCESS); +} + +/* + * BT_PSPLIT -- Do the real work of splitting the page. + * + * Parameters: + * t: tree + * h: page to be split + * l: page to put lower half of data + * r: page to put upper half of data + * pskip: pointer to index to leave open + * ilen: insert length + * + * Returns: + * Pointer to page in which to insert. + */ +static PAGE * +bt_psplit(t, h, l, r, pskip, ilen) + BTREE *t; + PAGE *h, *l, *r; + indx_t *pskip; + size_t ilen; +{ + BINTERNAL *bi; + BLEAF *bl; + CURSOR *c; + RLEAF *rl; + PAGE *rval; + void *src = NULL; + indx_t full, half, nxt, off, skip, top, used; + u_int32_t nbytes; + int bigkeycnt, isbigkey; + + /* + * Split the data to the left and right pages. Leave the skip index + * open. Additionally, make some effort not to split on an overflow + * key. This makes internal page processing faster and can save + * space as overflow keys used by internal pages are never deleted. + */ + bigkeycnt = 0; + skip = *pskip; + full = t->bt_psize - BTDATAOFF; + half = full / 2; + used = 0; + for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) { + if (skip == off) { + nbytes = ilen; + isbigkey = 0; /* XXX: not really known. */ + } else + switch (h->flags & P_TYPE) { + case P_BINTERNAL: + src = bi = GETBINTERNAL(h, nxt); + nbytes = NBINTERNAL(bi->ksize); + isbigkey = bi->flags & P_BIGKEY; + break; + case P_BLEAF: + src = bl = GETBLEAF(h, nxt); + nbytes = NBLEAF(bl); + isbigkey = bl->flags & P_BIGKEY; + break; + case P_RINTERNAL: + src = GETRINTERNAL(h, nxt); + nbytes = NRINTERNAL; + isbigkey = 0; + break; + case P_RLEAF: + src = rl = GETRLEAF(h, nxt); + nbytes = NRLEAF(rl); + isbigkey = 0; + break; + default: + abort(); + } + + /* + * If the key/data pairs are substantial fractions of the max + * possible size for the page, it's possible to get situations + * where we decide to try and copy too much onto the left page. + * Make sure that doesn't happen. + */ + if ((skip <= off && + used + nbytes + sizeof(indx_t) >= full) || nxt == top - 1) { + --off; + break; + } + + /* Copy the key/data pair, if not the skipped index. */ + if (skip != off) { + ++nxt; + + l->linp[off] = l->upper -= nbytes; + memmove((char *)l + l->upper, src, nbytes); + } + + used += nbytes + sizeof(indx_t); + if (used >= half) { + if (!isbigkey || bigkeycnt == 3) + break; + else + ++bigkeycnt; + } + } + + /* + * Off is the last offset that's valid for the left page. + * Nxt is the first offset to be placed on the right page. + */ + l->lower += (off + 1) * sizeof(indx_t); + + /* + * If splitting the page that the cursor was on, the cursor has to be + * adjusted to point to the same record as before the split. If the + * cursor is at or past the skipped slot, the cursor is incremented by + * one. If the cursor is on the right page, it is decremented by the + * number of records split to the left page. + */ + c = &t->bt_cursor; + if (F_ISSET(c, CURS_INIT) && c->pg.pgno == h->pgno) { + if (c->pg.index >= skip) + ++c->pg.index; + if (c->pg.index < nxt) /* Left page. */ + c->pg.pgno = l->pgno; + else { /* Right page. */ + c->pg.pgno = r->pgno; + c->pg.index -= nxt; + } + } + + /* + * If the skipped index was on the left page, just return that page. + * Otherwise, adjust the skip index to reflect the new position on + * the right page. + */ + if (skip <= off) { + skip = 0; + rval = l; + } else { + rval = r; + *pskip -= nxt; + } + + for (off = 0; nxt < top; ++off) { + if (skip == nxt) { + ++off; + skip = 0; + } + switch (h->flags & P_TYPE) { + case P_BINTERNAL: + src = bi = GETBINTERNAL(h, nxt); + nbytes = NBINTERNAL(bi->ksize); + break; + case P_BLEAF: + src = bl = GETBLEAF(h, nxt); + nbytes = NBLEAF(bl); + break; + case P_RINTERNAL: + src = GETRINTERNAL(h, nxt); + nbytes = NRINTERNAL; + break; + case P_RLEAF: + src = rl = GETRLEAF(h, nxt); + nbytes = NRLEAF(rl); + break; + default: + abort(); + } + ++nxt; + r->linp[off] = r->upper -= nbytes; + memmove((char *)r + r->upper, src, nbytes); + } + r->lower += off * sizeof(indx_t); + + /* If the key is being appended to the page, adjust the index. */ + if (skip == top) + r->lower += sizeof(indx_t); + + return (rval); +} + +/* + * BT_PRESERVE -- Mark a chain of pages as used by an internal node. + * + * Chains of indirect blocks pointed to by leaf nodes get reclaimed when the + * record that references them gets deleted. Chains pointed to by internal + * pages never get deleted. This routine marks a chain as pointed to by an + * internal page. + * + * Parameters: + * t: tree + * pg: page number of first page in the chain. + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +static int +bt_preserve(t, pg) + BTREE *t; + pgno_t pg; +{ + PAGE *h; + + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + h->flags |= P_PRESERVE; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + return (RET_SUCCESS); +} + +/* + * REC_TOTAL -- Return the number of recno entries below a page. + * + * Parameters: + * h: page + * + * Returns: + * The number of recno entries below a page. + * + * XXX + * These values could be set by the bt_psplit routine. The problem is that the + * entry has to be popped off of the stack etc. or the values have to be passed + * all the way back to bt_split/bt_rroot and it's not very clean. + */ +static recno_t +rec_total(h) + PAGE *h; +{ + recno_t recs; + indx_t nxt, top; + + for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt) + recs += GETRINTERNAL(h, nxt)->nrecs; + return (recs); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/bt_utils.c b/circuitpython/lib/berkeley-db-1.xx/btree/bt_utils.c new file mode 100644 index 0000000..9c1438e --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/bt_utils.c @@ -0,0 +1,260 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include + +#include +#include "btree.h" + +/* + * __bt_ret -- + * Build return key/data pair. + * + * Parameters: + * t: tree + * e: key/data pair to be returned + * key: user's key structure (NULL if not to be filled in) + * rkey: memory area to hold key + * data: user's data structure (NULL if not to be filled in) + * rdata: memory area to hold data + * copy: always copy the key/data item + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +int +__bt_ret(t, e, key, rkey, data, rdata, copy) + BTREE *t; + EPG *e; + DBT *key, *rkey, *data, *rdata; + int copy; +{ + BLEAF *bl; + void *p; + + bl = GETBLEAF(e->page, e->index); + + /* + * We must copy big keys/data to make them contigous. Otherwise, + * leave the page pinned and don't copy unless the user specified + * concurrent access. + */ + if (key == NULL) + goto dataonly; + + if (bl->flags & P_BIGKEY) { + if (__ovfl_get(t, bl->bytes, + &key->size, &rkey->data, &rkey->size)) + return (RET_ERROR); + key->data = rkey->data; + } else if (copy || F_ISSET(t, B_DB_LOCK)) { + if (bl->ksize > rkey->size) { + p = (void *)(rkey->data == NULL ? + malloc(bl->ksize) : realloc(rkey->data, bl->ksize)); + if (p == NULL) + return (RET_ERROR); + rkey->data = p; + rkey->size = bl->ksize; + } + memmove(rkey->data, bl->bytes, bl->ksize); + key->size = bl->ksize; + key->data = rkey->data; + } else { + key->size = bl->ksize; + key->data = bl->bytes; + } + +dataonly: + if (data == NULL) + return (RET_SUCCESS); + + if (bl->flags & P_BIGDATA) { + if (__ovfl_get(t, bl->bytes + bl->ksize, + &data->size, &rdata->data, &rdata->size)) + return (RET_ERROR); + data->data = rdata->data; + } else if (copy || F_ISSET(t, B_DB_LOCK)) { + /* Use +1 in case the first record retrieved is 0 length. */ + if (bl->dsize + 1 > rdata->size) { + p = (void *)(rdata->data == NULL ? + malloc(bl->dsize + 1) : + realloc(rdata->data, bl->dsize + 1)); + if (p == NULL) + return (RET_ERROR); + rdata->data = p; + rdata->size = bl->dsize + 1; + } + memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize); + data->size = bl->dsize; + data->data = rdata->data; + } else { + data->size = bl->dsize; + data->data = bl->bytes + bl->ksize; + } + + return (RET_SUCCESS); +} + +/* + * __BT_CMP -- Compare a key to a given record. + * + * Parameters: + * t: tree + * k1: DBT pointer of first arg to comparison + * e: pointer to EPG for comparison + * + * Returns: + * < 0 if k1 is < record + * = 0 if k1 is = record + * > 0 if k1 is > record + */ +int +__bt_cmp(t, k1, e) + BTREE *t; + const DBT *k1; + EPG *e; +{ + BINTERNAL *bi; + BLEAF *bl; + DBT k2; + PAGE *h; + void *bigkey; + + /* + * The left-most key on internal pages, at any level of the tree, is + * guaranteed by the following code to be less than any user key. + * This saves us from having to update the leftmost key on an internal + * page when the user inserts a new key in the tree smaller than + * anything we've yet seen. + */ + h = e->page; + if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF)) + return (1); + + bigkey = NULL; + if (h->flags & P_BLEAF) { + bl = GETBLEAF(h, e->index); + if (bl->flags & P_BIGKEY) + bigkey = bl->bytes; + else { + k2.data = bl->bytes; + k2.size = bl->ksize; + } + } else { + bi = GETBINTERNAL(h, e->index); + if (bi->flags & P_BIGKEY) + bigkey = bi->bytes; + else { + k2.data = bi->bytes; + k2.size = bi->ksize; + } + } + + if (bigkey) { + if (__ovfl_get(t, bigkey, + &k2.size, &t->bt_rdata.data, &t->bt_rdata.size)) + return (RET_ERROR); + k2.data = t->bt_rdata.data; + } + return ((*t->bt_cmp)(k1, &k2)); +} + +/* + * __BT_DEFCMP -- Default comparison routine. + * + * Parameters: + * a: DBT #1 + * b: DBT #2 + * + * Returns: + * < 0 if a is < b + * = 0 if a is = b + * > 0 if a is > b + */ +int +__bt_defcmp(a, b) + const DBT *a, *b; +{ + register size_t len; + register u_char *p1, *p2; + + /* + * XXX + * If a size_t doesn't fit in an int, this routine can lose. + * What we need is a integral type which is guaranteed to be + * larger than a size_t, and there is no such thing. + */ + len = MIN(a->size, b->size); + for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) + if (*p1 != *p2) + return ((int)*p1 - (int)*p2); + return ((int)a->size - (int)b->size); +} + +/* + * __BT_DEFPFX -- Default prefix routine. + * + * Parameters: + * a: DBT #1 + * b: DBT #2 + * + * Returns: + * Number of bytes needed to distinguish b from a. + */ +size_t +__bt_defpfx(a, b) + const DBT *a, *b; +{ + register u_char *p1, *p2; + register size_t cnt, len; + + cnt = 1; + len = MIN(a->size, b->size); + for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) + if (*p1 != *p2) + return (cnt); + + /* a->size must be <= b->size, or they wouldn't be in this order. */ + return (a->size < b->size ? a->size + 1 : a->size); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/btree.h b/circuitpython/lib/berkeley-db-1.xx/btree/btree.h new file mode 100644 index 0000000..062adb8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/btree.h @@ -0,0 +1,388 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)btree.h 8.11 (Berkeley) 8/17/94 + */ + +/* Macros to set/clear/test flags. */ +#define F_SET(p, f) (p)->flags |= (f) +#define F_CLR(p, f) (p)->flags &= ~(f) +#define F_ISSET(p, f) ((p)->flags & (f)) + +#include + +#define DEFMINKEYPAGE (2) /* Minimum keys per page */ +#ifndef MINCACHE +#define MINCACHE (5) /* Minimum cached pages */ +#endif +#define MINPSIZE (512) /* Minimum page size */ +#ifndef DEFPSIZE +#define DEFPSIZE (4096) /* Default page size */ +#endif + +/* + * Page 0 of a btree file contains a copy of the meta-data. This page is also + * used as an out-of-band page, i.e. page pointers that point to nowhere point + * to page 0. Page 1 is the root of the btree. + */ +#define P_INVALID 0 /* Invalid tree page number. */ +#define P_META 0 /* Tree metadata page number. */ +#define P_ROOT 1 /* Tree root page number. */ + +/* + * There are five page layouts in the btree: btree internal pages (BINTERNAL), + * btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages + * (RLEAF) and overflow pages. All five page types have a page header (PAGE). + * This implementation requires that values within structures NOT be padded. + * (ANSI C permits random padding.) If your compiler pads randomly you'll have + * to do some work to get this package to run. + */ +typedef struct _page { + pgno_t pgno; /* this page's page number */ + pgno_t prevpg; /* left sibling */ + pgno_t nextpg; /* right sibling */ + +#define P_BINTERNAL 0x01 /* btree internal page */ +#define P_BLEAF 0x02 /* leaf page */ +#define P_OVERFLOW 0x04 /* overflow page */ +#define P_RINTERNAL 0x08 /* recno internal page */ +#define P_RLEAF 0x10 /* leaf page */ +#define P_TYPE 0x1f /* type mask */ +#define P_PRESERVE 0x20 /* never delete this chain of pages */ + u_int32_t flags; + + indx_t lower; /* lower bound of free space on page */ + indx_t upper; /* upper bound of free space on page */ + indx_t linp[1]; /* indx_t-aligned VAR. LENGTH DATA */ +} PAGE; + +/* First and next index. */ +#define BTDATAOFF \ + (sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \ + sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t)) +#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t)) + +/* + * For pages other than overflow pages, there is an array of offsets into the + * rest of the page immediately following the page header. Each offset is to + * an item which is unique to the type of page. The h_lower offset is just + * past the last filled-in index. The h_upper offset is the first item on the + * page. Offsets are from the beginning of the page. + * + * If an item is too big to store on a single page, a flag is set and the item + * is a { page, size } pair such that the page is the first page of an overflow + * chain with size bytes of item. Overflow pages are simply bytes without any + * external structure. + * + * The page number and size fields in the items are pgno_t-aligned so they can + * be manipulated without copying. (This presumes that 32 bit items can be + * manipulated on this system.) + */ +#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1)) +#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t)) + +/* + * For the btree internal pages, the item is a key. BINTERNALs are {key, pgno} + * pairs, such that the key compares less than or equal to all of the records + * on that page. For a tree without duplicate keys, an internal page with two + * consecutive keys, a and b, will have all records greater than or equal to a + * and less than b stored on the page associated with a. Duplicate keys are + * somewhat special and can cause duplicate internal and leaf page records and + * some minor modifications of the above rule. + */ +typedef struct _binternal { + u_int32_t ksize; /* key size */ + pgno_t pgno; /* page number stored on */ +#define P_BIGDATA 0x01 /* overflow data */ +#define P_BIGKEY 0x02 /* overflow key */ + u_char flags; + char bytes[1]; /* data */ +} BINTERNAL; + +/* Get the page's BINTERNAL structure at index indx. */ +#define GETBINTERNAL(pg, indx) \ + ((BINTERNAL *)((char *)(pg) + (pg)->linp[indx])) + +/* Get the number of bytes in the entry. */ +#define NBINTERNAL(len) \ + LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len)) + +/* Copy a BINTERNAL entry to the page. */ +#define WR_BINTERNAL(p, size, pgno, flags) { \ + *(u_int32_t *)p = size; \ + p += sizeof(u_int32_t); \ + *(pgno_t *)p = pgno; \ + p += sizeof(pgno_t); \ + *(u_char *)p = flags; \ + p += sizeof(u_char); \ +} + +/* + * For the recno internal pages, the item is a page number with the number of + * keys found on that page and below. + */ +typedef struct _rinternal { + recno_t nrecs; /* number of records */ + pgno_t pgno; /* page number stored below */ +} RINTERNAL; + +/* Get the page's RINTERNAL structure at index indx. */ +#define GETRINTERNAL(pg, indx) \ + ((RINTERNAL *)((char *)(pg) + (pg)->linp[indx])) + +/* Get the number of bytes in the entry. */ +#define NRINTERNAL \ + LALIGN(sizeof(recno_t) + sizeof(pgno_t)) + +/* Copy a RINTERAL entry to the page. */ +#define WR_RINTERNAL(p, nrecs, pgno) { \ + *(recno_t *)p = nrecs; \ + p += sizeof(recno_t); \ + *(pgno_t *)p = pgno; \ +} + +/* For the btree leaf pages, the item is a key and data pair. */ +typedef struct _bleaf { + u_int32_t ksize; /* size of key */ + u_int32_t dsize; /* size of data */ + u_char flags; /* P_BIGDATA, P_BIGKEY */ + char bytes[1]; /* data */ +} BLEAF; + +/* Get the page's BLEAF structure at index indx. */ +#define GETBLEAF(pg, indx) \ + ((BLEAF *)((char *)(pg) + (pg)->linp[indx])) + +/* Get the number of bytes in the entry. */ +#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize) + +/* Get the number of bytes in the user's key/data pair. */ +#define NBLEAFDBT(ksize, dsize) \ + LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \ + (ksize) + (dsize)) + +/* Copy a BLEAF entry to the page. */ +#define WR_BLEAF(p, key, data, flags) { \ + *(u_int32_t *)p = key->size; \ + p += sizeof(u_int32_t); \ + *(u_int32_t *)p = data->size; \ + p += sizeof(u_int32_t); \ + *(u_char *)p = flags; \ + p += sizeof(u_char); \ + memmove(p, key->data, key->size); \ + p += key->size; \ + memmove(p, data->data, data->size); \ +} + +/* For the recno leaf pages, the item is a data entry. */ +typedef struct _rleaf { + u_int32_t dsize; /* size of data */ + u_char flags; /* P_BIGDATA */ + char bytes[1]; +} RLEAF; + +/* Get the page's RLEAF structure at index indx. */ +#define GETRLEAF(pg, indx) \ + ((RLEAF *)((char *)(pg) + (pg)->linp[indx])) + +/* Get the number of bytes in the entry. */ +#define NRLEAF(p) NRLEAFDBT((p)->dsize) + +/* Get the number of bytes from the user's data. */ +#define NRLEAFDBT(dsize) \ + LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize)) + +/* Copy a RLEAF entry to the page. */ +#define WR_RLEAF(p, data, flags) { \ + *(u_int32_t *)p = data->size; \ + p += sizeof(u_int32_t); \ + *(u_char *)p = flags; \ + p += sizeof(u_char); \ + memmove(p, data->data, data->size); \ +} + +/* + * A record in the tree is either a pointer to a page and an index in the page + * or a page number and an index. These structures are used as a cursor, stack + * entry and search returns as well as to pass records to other routines. + * + * One comment about searches. Internal page searches must find the largest + * record less than key in the tree so that descents work. Leaf page searches + * must find the smallest record greater than key so that the returned index + * is the record's correct position for insertion. + */ +typedef struct _epgno { + pgno_t pgno; /* the page number */ + indx_t index; /* the index on the page */ +} EPGNO; + +typedef struct _epg { + PAGE *page; /* the (pinned) page */ + indx_t index; /* the index on the page */ +} EPG; + +/* + * About cursors. The cursor (and the page that contained the key/data pair + * that it referenced) can be deleted, which makes things a bit tricky. If + * there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set + * or there simply aren't any duplicates of the key) we copy the key that it + * referenced when it's deleted, and reacquire a new cursor key if the cursor + * is used again. If there are duplicates keys, we move to the next/previous + * key, and set a flag so that we know what happened. NOTE: if duplicate (to + * the cursor) keys are added to the tree during this process, it is undefined + * if they will be returned or not in a cursor scan. + * + * The flags determine the possible states of the cursor: + * + * CURS_INIT The cursor references *something*. + * CURS_ACQUIRE The cursor was deleted, and a key has been saved so that + * we can reacquire the right position in the tree. + * CURS_AFTER, CURS_BEFORE + * The cursor was deleted, and now references a key/data pair + * that has not yet been returned, either before or after the + * deleted key/data pair. + * XXX + * This structure is broken out so that we can eventually offer multiple + * cursors as part of the DB interface. + */ +typedef struct _cursor { + EPGNO pg; /* B: Saved tree reference. */ + DBT key; /* B: Saved key, or key.data == NULL. */ + recno_t rcursor; /* R: recno cursor (1-based) */ + +#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */ +#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */ +#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */ +#define CURS_INIT 0x08 /* RB: Cursor initialized. */ + u_int8_t flags; +} CURSOR; + +/* + * The metadata of the tree. The nrecs field is used only by the RECNO code. + * This is because the btree doesn't really need it and it requires that every + * put or delete call modify the metadata. + */ +typedef struct _btmeta { + u_int32_t magic; /* magic number */ + u_int32_t version; /* version */ + u_int32_t psize; /* page size */ + u_int32_t free; /* page number of first free page */ + u_int32_t nrecs; /* R: number of records */ + +#define SAVEMETA (B_NODUPS | R_RECNO) + u_int32_t flags; /* bt_flags & SAVEMETA */ +} BTMETA; + +/* The in-memory btree/recno data structure. */ +typedef struct _btree { + MPOOL *bt_mp; /* memory pool cookie */ + + DB *bt_dbp; /* pointer to enclosing DB */ + + EPG bt_cur; /* current (pinned) page */ + PAGE *bt_pinned; /* page pinned across calls */ + + CURSOR bt_cursor; /* cursor */ + +#define BT_PUSH(t, p, i) { \ + t->bt_sp->pgno = p; \ + t->bt_sp->index = i; \ + ++t->bt_sp; \ +} +#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp) +#define BT_CLR(t) (t->bt_sp = t->bt_stack) + EPGNO bt_stack[50]; /* stack of parent pages */ + EPGNO *bt_sp; /* current stack pointer */ + + DBT bt_rkey; /* returned key */ + DBT bt_rdata; /* returned data */ + + virt_fd_t bt_fd; /* tree virtual file descriptor */ + + pgno_t bt_free; /* next free page */ + u_int32_t bt_psize; /* page size */ + indx_t bt_ovflsize; /* cut-off for key/data overflow */ + int bt_lorder; /* byte order */ + /* sorted order */ + enum { NOT, BACK, FORWARD } bt_order; + EPGNO bt_last; /* last insert */ + + /* B: key comparison function */ + int (*bt_cmp) __P((const DBT *, const DBT *)); + /* B: prefix comparison function */ + size_t (*bt_pfx) __P((const DBT *, const DBT *)); + /* R: recno input function */ + int (*bt_irec) __P((struct _btree *, recno_t)); + + FILE *bt_rfp; /* R: record FILE pointer */ + int bt_rfd; /* R: record file descriptor */ + + caddr_t bt_cmap; /* R: current point in mapped space */ + caddr_t bt_smap; /* R: start of mapped space */ + caddr_t bt_emap; /* R: end of mapped space */ + size_t bt_msize; /* R: size of mapped region. */ + + recno_t bt_nrecs; /* R: number of records */ + size_t bt_reclen; /* R: fixed record length */ + u_char bt_bval; /* R: delimiting byte/pad character */ + +/* + * NB: + * B_NODUPS and R_RECNO are stored on disk, and may not be changed. + */ +#define B_INMEM 0x00001 /* in-memory tree */ +#define B_METADIRTY 0x00002 /* need to write metadata */ +#define B_MODIFIED 0x00004 /* tree modified */ +#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */ +#define B_RDONLY 0x00010 /* read-only tree */ + +#define B_NODUPS 0x00020 /* no duplicate keys permitted */ +#define R_RECNO 0x00080 /* record oriented tree */ + +#define R_CLOSEFP 0x00040 /* opened a file pointer */ +#define R_EOF 0x00100 /* end of input file reached. */ +#define R_FIXLEN 0x00200 /* fixed length records */ +#define R_MEMMAPPED 0x00400 /* memory mapped file. */ +#define R_INMEM 0x00800 /* in-memory file */ +#define R_MODIFIED 0x01000 /* modified file */ +#define R_RDONLY 0x02000 /* read-only file */ + +#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */ +#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */ +#define B_DB_TXN 0x10000 /* DB_TXN specified. */ + u_int32_t flags; +} BTREE; + +#include "extern.h" diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/extern.h b/circuitpython/lib/berkeley-db-1.xx/btree/extern.h new file mode 100644 index 0000000..ebd9c54 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/extern.h @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)extern.h 8.10 (Berkeley) 7/20/94 + */ + +int __bt_close __P((DB *)); +int __bt_cmp __P((BTREE *, const DBT *, EPG *)); +int __bt_crsrdel __P((BTREE *, EPGNO *)); +int __bt_defcmp __P((const DBT *, const DBT *)); +size_t __bt_defpfx __P((const DBT *, const DBT *)); +int __bt_delete __P((const DB *, const DBT *, u_int)); +int __bt_dleaf __P((BTREE *, const DBT *, PAGE *, u_int)); +int __bt_fd __P((const DB *)); +int __bt_free __P((BTREE *, PAGE *)); +int __bt_get __P((const DB *, const DBT *, DBT *, u_int)); +PAGE *__bt_new __P((BTREE *, pgno_t *)); +void __bt_pgin __P((void *, pgno_t, void *)); +void __bt_pgout __P((void *, pgno_t, void *)); +int __bt_push __P((BTREE *, pgno_t, int)); +int __bt_put __P((const DB *dbp, DBT *, const DBT *, u_int)); +int __bt_ret __P((BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int)); +EPG *__bt_search __P((BTREE *, const DBT *, int *)); +int __bt_seq __P((const DB *, DBT *, DBT *, u_int)); +void __bt_setcur __P((BTREE *, pgno_t, u_int)); +int __bt_split __P((BTREE *, PAGE *, + const DBT *, const DBT *, int, size_t, u_int32_t)); +int __bt_sync __P((const DB *, u_int)); + +int __ovfl_delete __P((BTREE *, void *)); +int __ovfl_get __P((BTREE *, void *, size_t *, void **, size_t *)); +int __ovfl_put __P((BTREE *, const DBT *, pgno_t *)); + +#ifdef DEBUG +void __bt_dnpage __P((DB *, pgno_t)); +void __bt_dpage __P((PAGE *)); +void __bt_dump __P((DB *)); +#endif +#ifdef STATISTICS +void __bt_stat __P((DB *)); +#endif diff --git a/circuitpython/lib/berkeley-db-1.xx/btree/tags b/circuitpython/lib/berkeley-db-1.xx/btree/tags new file mode 120000 index 0000000..7ab656b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/btree/tags @@ -0,0 +1 @@ +../db/tags \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/changelog b/circuitpython/lib/berkeley-db-1.xx/changelog new file mode 100644 index 0000000..1540ca8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/changelog @@ -0,0 +1,103 @@ +1.84 -> 1.85 + recno: #ifdef out use of mmap, it's not portable enough. + +1.83 -> 1.84 Thu Aug 18 15:46:07 EDT 1994 + recno: Rework fixed-length records so that closing and reopening + the file now works. Pad short records on input. Never do + signed comparison in recno input reading functions. + +1.82 -> 1.83 Tue Jul 26 15:33:44 EDT 1994 + btree: Rework cursor deletion code yet again; bugs with + deleting empty pages that only contained the cursor + record. + +1.81 -> 1.82 Sat Jul 16 11:01:50 EDT 1994 + btree: Fix bugs introduced by new cursor/deletion code. + Replace return kbuf/dbuf with real DBT's. + +1.80 -> 1.81 + btree: Fix bugs introduced by new cursor/deletion code. + all: Add #defines for Purify. + +1.79 -> 1.80 Wed Jul 13 22:41:54 EDT 1994 + btree Change deletion to coalesce empty pages. This is a major + change, cursors and duplicate pages all had to be reworked. + Return to a fixed stack. + recno: Affected by cursor changes. New cursor structures should + permit multiple cursors in the future. + +1.78 -> 1.79 Mon Jun 20 17:36:47 EDT 1994 + all: Minor cleanups of 1.78 for porting reasons; only + major change was inlining check of NULL pointer + so that __fix_realloc goes away. + +1.77 -> 1.78 Thu Jun 16 19:06:43 EDT 1994 + all: Move "standard" size typedef's into db.h. + +1.76 -> 1.77 Thu Jun 16 16:48:38 EDT 1994 + hash: Delete __init_ routine, has special meaning to OSF 2.0. + +1.74 -> 1.76 + all: Finish up the port to the Alpha. + +1.73 -> 1.74 + recno: Don't put the record if rec_search fails, in rec_rdelete. + Create fixed-length intermediate records past "end" of DB + correctly. + Realloc bug when reading in fixed records. + all: First cut at port to Alpha (64-bit architecture) using + 4.4BSD basic integral types typedef's. + Cast allocation pointers to shut up old compilers. + Rework PORT directory into OS/machine directories. + +1.72 -> 1.73 + btree: If enough duplicate records were inserted and then deleted + that internal pages had references to empty pages of the + duplicate keys, the search function ended up on the wrong + page. + +1.7 -> 1.72 12 Oct 1993 + hash: Support NET/2 hash formats. + +1.7 -> 1.71 16 Sep 1993 + btree/recno: + Fix bug in internal search routines that caused + return of invalid pointers. + +1.6 -> 1.7 07 Sep 1993 + hash: Fixed big key overflow bugs. + test: Portability hacks, rewrite test script, Makefile. + btree/recno: + Stop copying non-overflow key/data pairs. + PORT: Break PORT directory up into per architecture/OS + subdirectories. + +1.5 -> 1.6 06 Jun 1993 + hash: In PAIRFITS, the first comparison should look at (P)[2]. + The hash_realloc function was walking off the end of memory. + The overflow page number was wrong when bumping splitpoint. + +1.4 -> 1.5 23 May 1993 + hash: Set hash default fill factor dynamically. + recno: Fixed bug in sorted page splits. + Add page size parameter support. + Allow recno to specify the name of the underlying btree; + used for vi recovery. + btree/recno: + Support 64K pages. + btree/hash/recno: + Provide access to an underlying file descriptor. + Change sync routines to take a flag argument, recno + uses this to sync out the underlying btree. + +1.3 -> 1.4 10 May 1993 + recno: Delete the R_CURSORLOG flag from the recno interface. + Zero-length record fix for non-mmap reads. + Try and make SIZE_T_MAX test in open portable. + +1.2 -> 1.3 01 May 1993 + btree: Ignore user byte-order setting when reading already + existing database. Fixes to byte-order conversions. + +1.1 -> 1.2 15 Apr 1993 + No bug fixes, only compatibility hacks. diff --git a/circuitpython/lib/berkeley-db-1.xx/db/Makefile.inc b/circuitpython/lib/berkeley-db-1.xx/db/Makefile.inc new file mode 100644 index 0000000..59478ba --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/db/Makefile.inc @@ -0,0 +1,5 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 + +.PATH: ${.CURDIR}/db/db + +SRCS+= db.c diff --git a/circuitpython/lib/berkeley-db-1.xx/db/db.c b/circuitpython/lib/berkeley-db-1.xx/db/db.c new file mode 100644 index 0000000..a18f056 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/db/db.c @@ -0,0 +1,99 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include +#include + +#include + +DB * +dbopen(fname, flags, mode, type, openinfo) + const char *fname; + int flags, mode; + DBTYPE type; + const void *openinfo; +{ + +#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN) +#define USE_OPEN_FLAGS \ + (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \ + O_RDWR | O_SHLOCK | O_TRUNC) + + if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0) + switch (type) { + case DB_BTREE: + return (__bt_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + case DB_HASH: + return (__hash_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + case DB_RECNO: + return (__rec_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + } + errno = EINVAL; + return (NULL); +} + +static int +__dberr() +{ + return (RET_ERROR); +} + +/* + * __DBPANIC -- Stop. + * + * Parameters: + * dbp: pointer to the DB structure. + */ +void +__dbpanic(dbp) + DB *dbp; +{ + /* The only thing that can succeed is a close. */ + dbp->del = (int (*)())__dberr; + dbp->fd = (int (*)())__dberr; + dbp->get = (int (*)())__dberr; + dbp->put = (int (*)())__dberr; + dbp->seq = (int (*)())__dberr; + dbp->sync = (int (*)())__dberr; +} diff --git a/circuitpython/lib/berkeley-db-1.xx/db/tags b/circuitpython/lib/berkeley-db-1.xx/db/tags new file mode 100644 index 0000000..f9c1143 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/db/tags @@ -0,0 +1,205 @@ +BT_CLR ../btree/btree.h /^#define BT_CLR(t) (t->bt_sp = t->bt_stack)$/ +BT_POP ../btree/btree.h /^#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL / +BT_PUSH ../btree/btree.h /^#define BT_PUSH(t, p, i) { \\$/ +BUCKET_TO_PAGE ../hash/hash.h /^#define BUCKET_TO_PAGE(B) \\$/ +BUF_INSERT ../hash/hash_buf.c /^#define BUF_INSERT(B, P) { \\$/ +BUF_REMOVE ../hash/hash_buf.c /^#define BUF_REMOVE(B) { \\$/ +CLRBIT ../hash/hash.h /^#define CLRBIT(A, N) ((A)[(N)\/BITS_PER_MAP] &= ~(/ +DODISK ../hash/hash.h /^#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0/ +DOMOD ../hash/hash.h /^#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x/ +FREESPACE ../hash/page.h /^#define FREESPACE(P) ((P)[(P)[0]+1])$/ +F_CLR ../btree/btree.h /^#define F_CLR(p, f) (p)->flags &= ~(f)$/ +F_ISSET ../btree/btree.h /^#define F_ISSET(p, f) ((p)->flags & (f))$/ +F_SET ../btree/btree.h /^#define F_SET(p, f) (p)->flags |= (f)$/ +GETBINTERNAL ../btree/btree.h /^#define GETBINTERNAL(pg, indx) \\$/ +GETBLEAF ../btree/btree.h /^#define GETBLEAF(pg, indx) \\$/ +GETRINTERNAL ../btree/btree.h /^#define GETRINTERNAL(pg, indx) \\$/ +GETRLEAF ../btree/btree.h /^#define GETRLEAF(pg, indx) \\$/ +HASHKEY ../include/mpool.h /^#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE)$/ +ISDISK ../hash/hash.h /^#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2)$/ +ISMOD ../hash/hash.h /^#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1)$/ +ISSET ../hash/hash.h /^#define ISSET(A, N) ((A)[(N)\/BITS_PER_MAP] & (1<siz/ +LALIGN ../btree/btree.h /^#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(/ +LRU_INSERT ../hash/hash_buf.c /^#define LRU_INSERT(B) BUF_INSERT((B), LRU)$/ +MOD ../hash/hash.c /^#define MOD(x, y) ((x) & ((y) - 1))$/ +MRU_INSERT ../hash/hash_buf.c /^#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufh/ +M_16_SWAP ../include/db.h /^#define M_16_SWAP(a) { \\$/ +M_32_SWAP ../include/db.h /^#define M_32_SWAP(a) { \\$/ +NBINTERNAL ../btree/btree.h /^#define NBINTERNAL(len) \\$/ +NBLEAF ../btree/btree.h /^#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize/ +NBLEAFDBT ../btree/btree.h /^#define NBLEAFDBT(ksize, dsize) \\$/ +NEXTINDEX ../btree/btree.h /^#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) \/ / +NRLEAF ../btree/btree.h /^#define NRLEAF(p) NRLEAFDBT((p)->dsize)$/ +NRLEAFDBT ../btree/btree.h /^#define NRLEAFDBT(dsize) \\$/ +OADDR_OF ../hash/hash.h /^#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) / +OADDR_TO_PAGE ../hash/hash.h /^#define OADDR_TO_PAGE(B) \\$/ +OFFSET ../hash/page.h /^#define OFFSET(P) ((P)[(P)[0]+2])$/ +OPAGENUM ../hash/hash.h /^#define OPAGENUM(N) ((N) & SPLITMASK)$/ +PAGE_INIT ../hash/hash_page.c /^#define PAGE_INIT(P) { \\$/ +PAGE_META ../hash/page.h /^#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t))/ +PAIRFITS ../hash/page.h /^#define PAIRFITS(P,K,D) \\$/ +PAIRSIZE ../hash/page.h /^#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->/ +PTROF ../hash/hash.h /^#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3)/ +P_16_COPY ../include/db.h /^#define P_16_COPY(a, b) { \\$/ +P_16_SWAP ../include/db.h /^#define P_16_SWAP(a) { \\$/ +P_32_COPY ../include/db.h /^#define P_32_COPY(a, b) { \\$/ +P_32_SWAP ../include/db.h /^#define P_32_SWAP(a) { \\$/ +RETURN_ERROR ../hash/hash.c /^#define RETURN_ERROR(ERR, LOC) { save_errno = ERR;/ +SETBIT ../hash/hash.h /^#define SETBIT(A, N) ((A)[(N)\/BITS_PER_MAP] |= (1/ +SPLITNUM ../hash/hash.h /^#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIF/ +WR_BINTERNAL ../btree/btree.h /^#define WR_BINTERNAL(p, size, pgno, flags) { \\/ +WR_BLEAF ../btree/btree.h /^#define WR_BLEAF(p, key, data, flags) { \\$/ +WR_RINTERNAL ../btree/btree.h /^#define WR_RINTERNAL(p, nrecs, pgno) { \\$/ +WR_RLEAF ../btree/btree.h /^#define WR_RLEAF(p, data, flags) { \\$/ +X ../btree/bt_debug.c /^#define X(flag, name) \\$/ +__add_ovflpage ../hash/hash_page.c /^__add_ovflpage(hashp, bufp)$/ +__addel ../hash/hash_page.c /^__addel(hashp, bufp, key, val)$/ +__big_delete ../hash/hash_bigkey.c /^__big_delete(hashp, bufp)$/ +__big_insert ../hash/hash_bigkey.c /^__big_insert(hashp, bufp, key, val)$/ +__big_keydata ../hash/hash_bigkey.c /^__big_keydata(hashp, bufp, key, val, set)$/ +__big_return ../hash/hash_bigkey.c /^__big_return(hashp, bufp, ndx, val, set_current)$/ +__big_split ../hash/hash_bigkey.c /^__big_split(hashp, op, np, big_keyp, addr, obucket/ +__bt_bdelete ../btree/bt_delete.c /^__bt_bdelete(t, key)$/ +__bt_close ../btree/bt_close.c /^__bt_close(dbp)$/ +__bt_cmp ../btree/bt_utils.c /^__bt_cmp(t, k1, e)$/ +__bt_curdel ../btree/bt_delete.c /^__bt_curdel(t, key, h, index)$/ +__bt_defcmp ../btree/bt_utils.c /^__bt_defcmp(a, b)$/ +__bt_defpfx ../btree/bt_utils.c /^__bt_defpfx(a, b)$/ +__bt_delete ../btree/bt_delete.c /^__bt_delete(dbp, key, flags)$/ +__bt_dleaf ../btree/bt_delete.c /^__bt_dleaf(t, key, h, index)$/ +__bt_dmpage ../btree/bt_debug.c /^__bt_dmpage(h)$/ +__bt_dnpage ../btree/bt_debug.c /^__bt_dnpage(dbp, pgno)$/ +__bt_dpage ../btree/bt_debug.c /^__bt_dpage(h)$/ +__bt_dump ../btree/bt_debug.c /^__bt_dump(dbp)$/ +__bt_fd ../btree/bt_open.c /^__bt_fd(dbp)$/ +__bt_first ../btree/bt_seq.c /^__bt_first(t, key, erval, exactp)$/ +__bt_free ../btree/bt_page.c /^__bt_free(t, h)$/ +__bt_get ../btree/bt_get.c /^__bt_get(dbp, key, data, flags)$/ +__bt_new ../btree/bt_page.c /^__bt_new(t, npg)$/ +__bt_open ../btree/bt_open.c /^__bt_open(fname, flags, mode, openinfo, dflags)$/ +__bt_pdelete ../btree/bt_delete.c /^__bt_pdelete(t, h)$/ +__bt_pgin ../btree/bt_conv.c /^__bt_pgin(t, pg, pp)$/ +__bt_pgout ../btree/bt_conv.c /^__bt_pgout(t, pg, pp)$/ +__bt_put ../btree/bt_put.c /^__bt_put(dbp, key, data, flags)$/ +__bt_relink ../btree/bt_delete.c /^__bt_relink(t, h)$/ +__bt_ret ../btree/bt_utils.c /^__bt_ret(t, e, key, rkey, data, rdata, copy)$/ +__bt_search ../btree/bt_search.c /^__bt_search(t, key, exactp)$/ +__bt_seq ../btree/bt_seq.c /^__bt_seq(dbp, key, data, flags)$/ +__bt_seqadv ../btree/bt_seq.c /^__bt_seqadv(t, ep, flags)$/ +__bt_seqset ../btree/bt_seq.c /^__bt_seqset(t, ep, key, flags)$/ +__bt_setcur ../btree/bt_seq.c /^__bt_setcur(t, pgno, index)$/ +__bt_snext ../btree/bt_search.c /^__bt_snext(t, h, key, exactp)$/ +__bt_split ../btree/bt_split.c /^__bt_split(t, sp, key, data, flags, ilen, argskip)/ +__bt_sprev ../btree/bt_search.c /^__bt_sprev(t, h, key, exactp)$/ +__bt_stat ../btree/bt_debug.c /^__bt_stat(dbp)$/ +__bt_stkacq ../btree/bt_delete.c /^__bt_stkacq(t, hp, c)$/ +__bt_sync ../btree/bt_close.c /^__bt_sync(dbp, flags)$/ +__buf_free ../hash/hash_buf.c /^__buf_free(hashp, do_free, to_disk)$/ +__buf_init ../hash/hash_buf.c /^__buf_init(hashp, nbytes)$/ +__call_hash ../hash/hash.c /^__call_hash(hashp, k, len)$/ +__dberr ../db/db.c /^__dberr()$/ +__dbpanic ../db/db.c /^__dbpanic(dbp)$/ +__delpair ../hash/hash_page.c /^__delpair(hashp, bufp, ndx)$/ +__expand_table ../hash/hash.c /^__expand_table(hashp)$/ +__find_bigpair ../hash/hash_bigkey.c /^__find_bigpair(hashp, bufp, ndx, key, size)$/ +__find_last_page ../hash/hash_bigkey.c /^__find_last_page(hashp, bpp)$/ +__free_ovflpage ../hash/hash_page.c /^__free_ovflpage(hashp, obufp)$/ +__get_buf ../hash/hash_buf.c /^__get_buf(hashp, addr, prev_bp, newpage)$/ +__get_page ../hash/hash_page.c /^__get_page(hashp, p, bucket, is_bucket, is_disk, i/ +__hash_open ../hash/hash.c /^__hash_open(file, flags, mode, info, dflags)$/ +__ibitmap ../hash/hash_page.c /^__ibitmap(hashp, pnum, nbits, ndx)$/ +__log2 ../hash/hash_log2.c /^__log2(num)$/ +__ovfl_delete ../btree/bt_overflow.c /^__ovfl_delete(t, p)$/ +__ovfl_get ../btree/bt_overflow.c /^__ovfl_get(t, p, ssz, buf, bufsz)$/ +__ovfl_put ../btree/bt_overflow.c /^__ovfl_put(t, dbt, pg)$/ +__put_page ../hash/hash_page.c /^__put_page(hashp, p, bucket, is_bucket, is_bitmap)/ +__rec_close ../recno/rec_close.c /^__rec_close(dbp)$/ +__rec_delete ../recno/rec_delete.c /^__rec_delete(dbp, key, flags)$/ +__rec_dleaf ../recno/rec_delete.c /^__rec_dleaf(t, h, index)$/ +__rec_fd ../recno/rec_open.c /^__rec_fd(dbp)$/ +__rec_fmap ../recno/rec_get.c /^__rec_fmap(t, top)$/ +__rec_fpipe ../recno/rec_get.c /^__rec_fpipe(t, top)$/ +__rec_get ../recno/rec_get.c /^__rec_get(dbp, key, data, flags)$/ +__rec_iput ../recno/rec_put.c /^__rec_iput(t, nrec, data, flags)$/ +__rec_open ../recno/rec_open.c /^__rec_open(fname, flags, mode, openinfo, dflags)$/ +__rec_put ../recno/rec_put.c /^__rec_put(dbp, key, data, flags)$/ +__rec_ret ../recno/rec_utils.c /^__rec_ret(t, e, nrec, key, data)$/ +__rec_search ../recno/rec_search.c /^__rec_search(t, recno, op)$/ +__rec_seq ../recno/rec_seq.c /^__rec_seq(dbp, key, data, flags)$/ +__rec_sync ../recno/rec_close.c /^__rec_sync(dbp, flags)$/ +__rec_vmap ../recno/rec_get.c /^__rec_vmap(t, top)$/ +__rec_vpipe ../recno/rec_get.c /^__rec_vpipe(t, top)$/ +__reclaim_buf ../hash/hash_buf.c /^__reclaim_buf(hashp, bp)$/ +__split_page ../hash/hash_page.c /^__split_page(hashp, obucket, nbucket)$/ +alloc_segs ../hash/hash.c /^alloc_segs(hashp, nsegs)$/ +bt_broot ../btree/bt_split.c /^bt_broot(t, h, l, r)$/ +bt_fast ../btree/bt_put.c /^bt_fast(t, key, data, exactp)$/ +bt_meta ../btree/bt_close.c /^bt_meta(t)$/ +bt_page ../btree/bt_split.c /^bt_page(t, h, lp, rp, skip, ilen)$/ +bt_preserve ../btree/bt_split.c /^bt_preserve(t, pg)$/ +bt_psplit ../btree/bt_split.c /^bt_psplit(t, h, l, r, pskip, ilen)$/ +bt_root ../btree/bt_split.c /^bt_root(t, h, lp, rp, skip, ilen)$/ +bt_rroot ../btree/bt_split.c /^bt_rroot(t, h, l, r)$/ +byteorder ../btree/bt_open.c /^byteorder()$/ +collect_data ../hash/hash_bigkey.c /^collect_data(hashp, bufp, len, set)$/ +collect_key ../hash/hash_bigkey.c /^collect_key(hashp, bufp, len, val, set)$/ +dbm_clearerr ../hash/ndbm.c /^dbm_clearerr(db)$/ +dbm_close ../hash/ndbm.c /^dbm_close(db)$/ +dbm_delete ../hash/ndbm.c /^dbm_delete(db, key)$/ +dbm_dirfno ../hash/ndbm.c /^dbm_dirfno(db)$/ +dbm_error ../hash/ndbm.c /^dbm_error(db)$/ +dbm_fetch ../hash/ndbm.c /^dbm_fetch(db, key)$/ +dbm_firstkey ../hash/ndbm.c /^dbm_firstkey(db)$/ +dbm_nextkey ../hash/ndbm.c /^dbm_nextkey(db)$/ +dbm_open ../hash/ndbm.c /^dbm_open(file, flags, mode)$/ +dbm_store ../hash/ndbm.c /^dbm_store(db, key, content, flags)$/ +dbopen ../db/db.c /^dbopen(fname, flags, mode, type, openinfo)$/ +dcharhash ../hash/hash_func.c /^#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x/ +fetch_bitmap ../hash/hash_page.c /^fetch_bitmap(hashp, ndx)$/ +first_free ../hash/hash_page.c /^first_free(map)$/ +flush_meta ../hash/hash.c /^flush_meta(hashp)$/ +hash2 ../hash/hash_func.c /^hash2(keyarg, len)$/ +hash3 ../hash/hash_func.c /^hash3(keyarg, len)$/ +hash4 ../hash/hash_func.c /^hash4(keyarg, len)$/ +hash_access ../hash/hash.c /^hash_access(hashp, action, key, val)$/ +hash_close ../hash/hash.c /^hash_close(dbp)$/ +hash_delete ../hash/hash.c /^hash_delete(dbp, key, flag)$/ +hash_fd ../hash/hash.c /^hash_fd(dbp)$/ +hash_get ../hash/hash.c /^hash_get(dbp, key, data, flag)$/ +hash_put ../hash/hash.c /^hash_put(dbp, key, data, flag)$/ +hash_realloc ../hash/hash.c /^hash_realloc(p_ptr, oldsize, newsize)$/ +hash_seq ../hash/hash.c /^hash_seq(dbp, key, data, flag)$/ +hash_sync ../hash/hash.c /^hash_sync(dbp, flags)$/ +hcreate ../hash/hsearch.c /^hcreate(nel)$/ +hdestroy ../hash/hash.c /^hdestroy(hashp)$/ +hsearch ../hash/hsearch.c /^hsearch(item, action)$/ +init_hash ../hash/hash.c /^init_hash(hashp, file, info)$/ +init_htab ../hash/hash.c /^init_htab(hashp, nelem)$/ +mpool_bkt ../mpool/mpool.c /^mpool_bkt(mp)$/ +mpool_close ../mpool/mpool.c /^mpool_close(mp)$/ +mpool_filter ../mpool/mpool.c /^mpool_filter(mp, pgin, pgout, pgcookie)$/ +mpool_get ../mpool/mpool.c /^mpool_get(mp, pgno, flags)$/ +mpool_look ../mpool/mpool.c /^mpool_look(mp, pgno)$/ +mpool_new ../mpool/mpool.c /^mpool_new(mp, pgnoaddr)$/ +mpool_open ../mpool/mpool.c /^mpool_open(key, fd, pagesize, maxcache)$/ +mpool_put ../mpool/mpool.c /^mpool_put(mp, page, flags)$/ +mpool_stat ../mpool/mpool.c /^mpool_stat(mp)$/ +mpool_sync ../mpool/mpool.c /^mpool_sync(mp)$/ +mpool_write ../mpool/mpool.c /^mpool_write(mp, bp)$/ +mswap ../btree/bt_conv.c /^mswap(pg)$/ +newbuf ../hash/hash_buf.c /^newbuf(hashp, addr, prev_bp)$/ +nroot ../btree/bt_open.c /^nroot(t)$/ +open_temp ../hash/hash_page.c /^open_temp(hashp)$/ +overflow_page ../hash/hash_page.c /^overflow_page(hashp)$/ +print_chain ../hash/hash_page.c /^print_chain(addr)$/ +putpair ../hash/hash_page.c /^putpair(p, key, val)$/ +rec_rdelete ../recno/rec_delete.c /^rec_rdelete(t, nrec)$/ +rec_total ../btree/bt_split.c /^rec_total(h)$/ +squeeze_key ../hash/hash_page.c /^squeeze_key(sp, key, val)$/ +swap_header ../hash/hash.c /^swap_header(hashp)$/ +swap_header_copy ../hash/hash.c /^swap_header_copy(srcp, destp)$/ +tmp ../btree/bt_open.c /^tmp()$/ +u_int32_t ../hash/extern.h /^extern u_int32_t (*__default_hash) __P((const void/ +ugly_split ../hash/hash_page.c /^ugly_split(hashp, obucket, old_bufp, new_bufp, cop/ diff --git a/circuitpython/lib/berkeley-db-1.xx/docs/btree.3.ps b/circuitpython/lib/berkeley-db-1.xx/docs/btree.3.ps new file mode 100644 index 0000000..c79c972 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/docs/btree.3.ps @@ -0,0 +1,366 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.08 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Bold +%%+ font Times-Italic +%%DocumentSuppliedResources: procset grops 1.08 0 +%%Pages: 2 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.08 0 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Bold +%%IncludeResource: font Times-Italic +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL +792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron +/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space +/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft +/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four +/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C +/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash +/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q +/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase +/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger +/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus +/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu +/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright +/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde +/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute +/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls +/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute +/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve +/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex +/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE +/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 132.34(BTREE\(3\) BSD)72 48 R(Programmer')2.5 E 2.5(sM) +-.55 G 132.34(anual BTREE\(3\))340.17 48 R/F1 9/Times-Bold@0 SF -.18(NA)72 84 S +(ME).18 E F0(btree \255 btree database access method)108 96 Q F1(SYNOPSIS)72 +112.8 Q/F2 10/Times-Bold@0 SF(#include )108 124.8 Q(#include )-.4 E F1(DESCRIPTION)72 153.6 Q F0 .198(The routine)108 165.6 R +/F3 10/Times-Italic@0 SF(dbopen)2.698 E F0 .198(is the library interf)2.698 F +.198(ace to database \214les.)-.1 F .198 +(One of the supported \214le formats is btree \214les.)5.198 F .974 +(The general description of the database access methods is in)108 177.6 R F3 +(dbopen)3.475 E F0 .975(\(3\), this manual page describes only).24 F +(the btree speci\214c information.)108 189.6 Q(The btree data structure is a s\ +orted, balanced tree structure storing associated k)108 206.4 Q -.15(ey)-.1 G +(/data pairs.).15 E .504(The btree access method speci\214c data structure pro) +108 223.2 R .504(vided to)-.15 F F3(dbopen)3.004 E F0 .503 +(is de\214ned in the include \214le as)-.4 F(follo)108 +235.2 Q(ws:)-.25 E(typedef struct {)108 252 Q(u_long \215ags;)144 264 Q +(u_int cachesize;)144 276 Q(inde)144 288 Q(x_t psize;)-.15 E(int lorder;)144 +300 Q(int mink)144 312 Q -.15(ey)-.1 G(page;).15 E +(int \(*compare\)\(const DBT *k)144 324 Q -.15(ey)-.1 G(1, const DBT *k).15 E +-.15(ey)-.1 G(2\);).15 E(int \(*pre\214x\)\(const DBT *k)144 336 Q -.15(ey)-.1 +G(1, const DBT *k).15 E -.15(ey)-.1 G(2\);).15 E 2.5(}B)108 348 S(TREEINFO;) +121.97 348 Q(The elements of this structure are as follo)108 364.8 Q(ws:)-.25 E +14.61(\215ags The)108 381.6 R(\215ag v)2.5 E(alue is speci\214ed by)-.25 E F3 +(or)2.5 E F0('ing an).73 E 2.5(yo)-.15 G 2.5(ft)313.2 381.6 S(he follo)321.81 +381.6 Q(wing v)-.25 E(alues:)-.25 E(R_DUP)144 398.4 Q 1.296(Permit duplicate k) +180 410.4 R -.15(ey)-.1 G 3.796(si).15 G 3.796(nt)275.578 410.4 S 1.296 +(he tree, i.e. permit insertion if the k)287.154 410.4 R 1.596 -.15(ey t)-.1 H +3.796(ob).15 G 3.796(ei)466.878 410.4 S 1.296(nserted already)477.894 410.4 R +-.15(ex)180 422.4 S 1.935(ists in the tree.).15 F 1.935(The def)6.935 F 1.935 +(ault beha)-.1 F(vior)-.2 E 4.435(,a)-.4 G 4.435(sd)358.215 422.4 S 1.935 +(escribed in)371.54 422.4 R F3(dbopen)4.435 E F0 1.935(\(3\), is to o).24 F +-.15(ve)-.15 G 1.935(rwrite a).15 F .148(matching k)180 434.4 R .448 -.15(ey w) +-.1 H .148(hen inserting a ne).15 F 2.649(wk)-.25 G .449 -.15(ey o)329.709 +434.4 T 2.649(rt).15 G 2.649(of)355.407 434.4 S .149(ail if the R_NOO)366.286 +434.4 R(VER)-.5 E .149(WRITE \215ag is speci-)-.55 F 5.972(\214ed. The)180 +446.4 R 3.472(R_DUP \215ag is o)5.972 F -.15(ve)-.15 G 3.472 +(rridden by the R_NOO).15 F(VER)-.5 E 3.471(WRITE \215ag, and if the)-.55 F +(R_NOO)180 458.4 Q(VER)-.5 E .781 +(WRITE \215ag is speci\214ed, attempts to insert duplicate k)-.55 F -.15(ey)-.1 +G 3.282(si).15 G .782(nto the tree will)474.604 458.4 R -.1(fa)180 470.4 S(il.) +.1 E 1.13(If the database contains duplicate k)180 487.2 R -.15(ey)-.1 G 1.129 +(s, the order of retrie).15 F -.25(va)-.25 G 3.629(lo).25 G 3.629(fk)439.644 +487.2 S -.15(ey)451.503 487.2 S 1.129(/data pairs is unde-).15 F .837 +(\214ned if the)180 499.2 R F3 -.1(ge)3.337 G(t).1 E F0 .837 +(routine is used, ho)3.337 F(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G F3(seq)3.737 +E F0 .838(routine calls with the R_CURSOR \215ag set)3.337 F(will al)180 511.2 +Q -.1(wa)-.1 G(ys return the logical `).1 E(`\214rst')-.74 E 2.5('o)-.74 G 2.5 +(fa)333.85 511.2 S .3 -.15(ny g)344.12 511.2 T(roup of duplicate k).15 E -.15 +(ey)-.1 G(s.).15 E(cachesize)108 528 Q 3.056(As)144 540 S .556 +(uggested maximum size \(in bytes\) of the memory cache.)158.166 540 R .555 +(This v)5.556 F .555(alue is)-.25 F F2(only)3.055 E F0(advisory)3.055 E 3.055 +(,a)-.65 G .555(nd the)514.725 540 R .759 +(access method will allocate more memory rather than f)144 552 R 3.259 +(ail. Since)-.1 F -2.15 -.25(ev e)3.259 H .76(ry search e).25 F .76 +(xamines the root)-.15 F .055 +(page of the tree, caching the most recently used pages substantially impro)144 +564 R -.15(ve)-.15 G 2.554(sa).15 G .054(ccess time.)459.578 564 R .054 +(In addi-)5.054 F .661(tion, ph)144 576 R .662(ysical writes are delayed as lo\ +ng as possible, so a moderate cache can reduce the number)-.05 F .601 +(of I/O operations signi\214cantly)144 588 R 5.601(.O)-.65 G -.15(bv)280.744 +588 S(iously).15 E 3.101(,u)-.65 G .601(sing a cache increases \(b)324.995 588 +R .6(ut only increases\) the lik)-.2 F(eli-)-.1 E .19(hood of corruption or lo\ +st data if the system crashes while a tree is being modi\214ed.)144 600 R(If) +5.191 E F3(cac)2.691 E(hesize)-.15 E F0(is)2.691 E 2.5(0\()144 612 S +(no size is speci\214ed\) a def)154.83 612 Q(ault cache is used.)-.1 E 12.95 +(psize P)108 628.8 R .45 +(age size is the size \(in bytes\) of the pages used for nodes in the tree.) +-.15 F .449(The minimum page size is)5.449 F .442 +(512 bytes and the maximum page size is 64K.)144 640.8 R(If)5.442 E F3(psize) +2.942 E F0 .442(is 0 \(no page size is speci\214ed\) a page size)2.942 F +(is chosen based on the underlying \214le system I/O block size.)144 652.8 Q +9.62(lorder The)108 669.6 R 1.597(byte order for inte)4.097 F 1.596 +(gers in the stored database metadata.)-.15 F 1.596 +(The number should represent the)6.596 F .688(order as an inte)144 681.6 R .689 +(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689 +(ould be the number 4,321.)-.1 F(If)5.689 E F3(lor)3.189 E(der)-.37 E F0 .689 +(is 0 \(no)3.189 F(order is speci\214ed\) the current host order is used.)144 +693.6 Q 174.135(4.4BSD June)72 732 R(4, 1993)2.5 E(1)535 732 Q EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 132.34(BTREE\(3\) BSD)72 48 R(Programmer')2.5 E 2.5(sM) +-.55 G 132.34(anual BTREE\(3\))340.17 48 R(mink)108 84 Q -.15(ey)-.1 G(page).15 +E 1.423(The minimum number of k)144 96 R -.15(ey)-.1 G 3.923(sw).15 G 1.422 +(hich will be stored on an)282.245 96 R 3.922(ys)-.15 G 1.422(ingle page.) +400.618 96 R 1.422(This v)6.422 F 1.422(alue is used to)-.25 F .257 +(determine which k)144 108 R -.15(ey)-.1 G 2.757(sw).15 G .257 +(ill be stored on o)242.001 108 R -.15(ve)-.15 G(r\215o).15 E 2.757(wp)-.25 G +.257(ages, i.e. if a k)348.006 108 R .558 -.15(ey o)-.1 H 2.758(rd).15 G .258 +(ata item is longer than the)435.11 108 R 1.102(pagesize di)144 120 R 1.102 +(vided by the mink)-.25 F -.15(ey)-.1 G 1.102(page v).15 F 1.102 +(alue, it will be stored on o)-.25 F -.15(ve)-.15 G(r\215o).15 E 3.602(wp)-.25 +G 1.102(ages instead of in the)451.164 120 R(page itself.)144 132 Q(If)5 E/F1 +10/Times-Italic@0 SF(mink)2.5 E -.3(ey)-.1 G(pa).3 E -.1(ge)-.1 G F0 +(is 0 \(no minimum number of k)2.6 E -.15(ey)-.1 G 2.5(si).15 G 2.5(ss)392.84 +132 S(peci\214ed\) a v)403.12 132 Q(alue of 2 is used.)-.25 E(compare)108 148.8 +Q .751(Compare is the k)144 160.8 R 1.051 -.15(ey c)-.1 H .751 +(omparison function.).15 F .751(It must return an inte)5.751 F .752 +(ger less than, equal to, or greater)-.15 F .913(than zero if the \214rst k)144 +172.8 R 1.213 -.15(ey a)-.1 H -.18(rg).15 G .913 +(ument is considered to be respecti).18 F -.15(ve)-.25 G .913 +(ly less than, equal to, or greater).15 F .352(than the second k)144 184.8 R +.652 -.15(ey a)-.1 H -.18(rg).15 G 2.852(ument. The).18 F .353 +(same comparison function must be used on a gi)2.852 F -.15(ve)-.25 G 2.853(nt) +.15 G .353(ree e)503.127 184.8 R -.15(ve)-.25 G(ry).15 E .817 +(time it is opened.)144 196.8 R(If)5.817 E F1(compar)3.317 E(e)-.37 E F0 .817 +(is NULL \(no comparison function is speci\214ed\), the k)3.317 F -.15(ey)-.1 G +3.316(sa).15 G .816(re com-)508.364 196.8 R(pared le)144 208.8 Q(xically)-.15 E +2.5(,w)-.65 G(ith shorter k)214.57 208.8 Q -.15(ey)-.1 G 2.5(sc).15 G +(onsidered less than longer k)282.92 208.8 Q -.15(ey)-.1 G(s.).15 E 10.17 +(pre\214x Pre\214x)108 225.6 R .291(is the pre\214x comparison function.)2.791 +F .292(If speci\214ed, this routine must return the number of bytes)5.291 F +.937(of the second k)144 237.6 R 1.237 -.15(ey a)-.1 H -.18(rg).15 G .937 +(ument which are necessary to determine that it is greater than the \214rst k) +.18 F -.15(ey)-.1 G(ar)144 249.6 Q 3.477(gument. If)-.18 F .977(the k)3.477 F +-.15(ey)-.1 G 3.477(sa).15 G .977(re equal, the k)241.898 249.6 R 1.277 -.15 +(ey l)-.1 H .978(ength should be returned.).15 F .978 +(Note, the usefulness of this)5.978 F .558(routine is v)144 261.6 R .558 +(ery data dependent, b)-.15 F .558 +(ut, in some data sets can produce signi\214cantly reduced tree sizes)-.2 F +.354(and search times.)144 273.6 R(If)5.354 E F1(pr)2.854 E(e\214x)-.37 E F0 +.354(is NULL \(no pre\214x function is speci\214ed\),)2.854 F/F2 10 +/Times-Bold@0 SF(and)2.854 E F0 .354(no comparison function)2.854 F .193 +(is speci\214ed, a def)144 285.6 R .193(ault le)-.1 F .193 +(xical comparison routine is used.)-.15 F(If)5.192 E F1(pr)2.692 E(e\214x)-.37 +E F0 .192(is NULL and a comparison rou-)2.692 F +(tine is speci\214ed, no pre\214x comparison is done.)144 297.6 Q .79 +(If the \214le already e)108 314.4 R .79(xists \(and the O_TR)-.15 F .79 +(UNC \215ag is not speci\214ed\), the v)-.4 F .79 +(alues speci\214ed for the parameters)-.25 F +(\215ags, lorder and psize are ignored in f)108 326.4 Q -.2(avo)-.1 G 2.5(ro).2 +G 2.5(ft)284.4 326.4 S(he v)293.01 326.4 Q(alues used when the tree w)-.25 E +(as created.)-.1 E -.15(Fo)108 343.2 S(rw).15 E +(ard sequential scans of a tree are from the least k)-.1 E .3 -.15(ey t)-.1 H +2.5(ot).15 G(he greatest.)348.55 343.2 Q 1.043(Space freed up by deleting k)108 +360 R -.15(ey)-.1 G 1.043(/data pairs from the tree is ne).15 F -.15(ve)-.25 G +3.543(rr).15 G 1.043(eclaimed, although it is normally made)378.686 360 R -.2 +(av)108 372 S 1.394(ailable for reuse.)-.05 F 1.394 +(This means that the btree storage structure is gro)6.394 F(w-only)-.25 E 6.395 +(.T)-.65 G 1.395(he only solutions are to)441.09 372 R -.2(avo)108 384 S(id e) +.2 E(xcessi)-.15 E .3 -.15(ve d)-.25 H +(eletions, or to create a fresh tree periodically from a scan of an e).15 E +(xisting one.)-.15 E .344(Searches, insertions, and deletions in a btree will \ +all complete in O lg base N where base is the a)108 400.8 R -.15(ve)-.2 G .343 +(rage \214ll).15 F -.1(fa)108 412.8 S(ctor).1 E 5.798(.O)-.55 G .799 +(ften, inserting ordered data into btrees results in a lo)146.188 412.8 R 3.299 +<778c>-.25 G .799(ll f)377.505 412.8 R(actor)-.1 E 5.799(.T)-.55 G .799 +(his implementation has been)423.443 412.8 R(modi\214ed to mak)108 424.8 Q 2.5 +(eo)-.1 G(rdered insertion the best case, resulting in a much better than norm\ +al page \214ll f)185.4 424.8 Q(actor)-.1 E(.)-.55 E/F3 9/Times-Bold@0 SF +(SEE ALSO)72 441.6 Q F1(dbopen)108 453.6 Q F0(\(3\),).24 E F1(hash)2.5 E F0 +(\(3\),).28 E F1(mpool)2.5 E F0(\(3\),).51 E F1 -.37(re)2.5 G(cno).37 E F0 +(\(3\)).18 E F1(The Ubiquitous B-tr)108 477.6 Q(ee)-.37 E F0 2.5(,D).18 G +(ouglas Comer)209.47 477.6 Q 2.5(,A)-.4 G(CM Comput. Surv)276.72 477.6 Q 2.5 +(.1)-.65 G(1, 2 \(June 1979\), 121-138.)360.25 477.6 Q F1(Pr)108 501.6 Q 1.588 +(e\214x B-tr)-.37 F(ees)-.37 E F0 4.088(,B).27 G 1.587(ayer and Unterauer) +177.636 501.6 R 4.087(,A)-.4 G 1.587(CM T)270.447 501.6 R 1.587 +(ransactions on Database Systems, V)-.35 F 1.587(ol. 2, 1 \(March 1977\),)-1.29 +F(11-26.)108 513.6 Q F1(The Art of Computer Pr)108 537.6 Q -.1(og)-.45 G -.15 +(ra).1 G(mming V).15 E(ol. 3: Sorting and Sear)-1.11 E -.15(ch)-.37 G(ing).15 E +F0 2.5(,D).22 G(.E. Knuth, 1968, pp 471-480.)382 537.6 Q F3 -.09(BU)72 554.4 S +(GS).09 E F0(Only big and little endian byte order is supported.)108 566.4 Q +174.135(4.4BSD June)72 732 R(4, 1993)2.5 E(2)535 732 Q EP +%%Trailer +end +%%EOF diff --git a/circuitpython/lib/berkeley-db-1.xx/docs/dbopen.3.ps b/circuitpython/lib/berkeley-db-1.xx/docs/dbopen.3.ps new file mode 100644 index 0000000..c621bef --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/docs/dbopen.3.ps @@ -0,0 +1,508 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.08 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Bold +%%+ font Times-Italic +%%DocumentSuppliedResources: procset grops 1.08 0 +%%Pages: 4 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.08 0 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Bold +%%IncludeResource: font Times-Italic +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL +792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron +/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space +/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft +/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four +/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C +/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash +/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q +/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase +/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger +/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus +/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu +/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright +/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde +/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute +/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls +/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute +/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve +/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex +/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE +/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 124.01(DBOPEN\(3\) BSD)72 48 R(Programmer')2.5 E 2.5 +(sM)-.55 G 124.01(anual DBOPEN\(3\))340.17 48 R/F1 9/Times-Bold@0 SF -.18(NA)72 +84 S(ME).18 E F0(dbopen \255 database access methods)108 96 Q F1(SYNOPSIS)72 +112.8 Q/F2 10/Times-Bold@0 SF(#include )108 124.8 Q +(#include )108 136.8 Q(#include )-.4 E(DB *)108 +172.8 Q(dbopen\(const char *\214le, int \215ags, int mode, DBTYPE type,)108 +184.8 Q(const v)158 196.8 Q(oid *openinf)-.1 E(o\);)-.25 E F1(DESCRIPTION)72 +213.6 Q/F3 10/Times-Italic@0 SF(Dbopen)108 225.6 Q F0 .032 +(is the library interf)2.532 F .031(ace to database \214les.)-.1 F .031 +(The supported \214le formats are btree, hashed and UNIX \214le)5.031 F 2.82 +(oriented. The)108 237.6 R .32 +(btree format is a representation of a sorted, balanced tree structure.)2.82 F +.321(The hashed format is an)5.321 F -.15(ex)108 249.6 S .424 +(tensible, dynamic hashing scheme.).15 F .423 +(The \215at-\214le format is a byte stream \214le with \214x)5.423 F .423 +(ed or v)-.15 F .423(ariable length)-.25 F 2.906(records. The)108 261.6 R .407 +(formats and \214le format speci\214c information are described in detail in t\ +heir respecti)2.906 F .707 -.15(ve m)-.25 H(anual).15 E(pages)108 273.6 Q F3 +(btr)2.5 E(ee)-.37 E F0(\(3\),).18 E F3(hash)2.5 E F0(\(3\) and).28 E F3 -.37 +(re)2.5 G(cno).37 E F0(\(3\).).18 E .433(Dbopen opens)108 290.4 R F3(\214le) +2.933 E F0 .433(for reading and/or writing.)2.933 F .433(Files ne)5.433 F -.15 +(ve)-.25 G 2.933(ri).15 G .433(ntended to be preserv)346.737 290.4 R .433 +(ed on disk may be created)-.15 F(by setting the \214le parameter to NULL.)108 +302.4 Q(The)108 319.2 Q F3<8d61>4.661 E(gs)-.1 E F0(and)4.661 E F3 2.161 +(mode ar)4.661 F(guments)-.37 E F0 2.161(are as speci\214ed to the)4.661 F F3 +(open)4.661 E F0 2.162(\(2\) routine, ho).24 F(we)-.25 E -.15(ve)-.25 G 2.962 +-.4(r, o).15 H 2.162(nly the O_CREA).4 F -.74(T,)-1.11 G .128 +(O_EXCL, O_EXLOCK, O_NONBLOCK, O_RDONL)108 331.2 R 2.708 -1.29(Y, O)-1 H(_RD) +1.29 E .128(WR, O_SHLOCK and O_TR)-.3 F .127(UNC \215ags are)-.4 F 2.5 +(meaningful. \(Note,)108 343.2 R(opening a database \214le O_WR)2.5 E(ONL)-.4 E +2.5(Yi)-1 G 2.5(sn)342.67 343.2 S(ot possible.\))354.06 343.2 Q(The)108 360 Q +F3(type)5.337 E F0(ar)5.337 E 2.837 +(gument is of type DBTYPE \(as de\214ned in the include \214le\) and may be set to)-.4 F(DB_BTREE, DB_HASH or DB_RECNO.) +108 372 Q(The)108 388.8 Q F3(openinfo)2.85 E F0(ar)2.85 E .349(gument is a poi\ +nter to an access method speci\214c structure described in the access method') +-.18 F(s)-.55 E .03(manual page.)108 400.8 R(If)5.03 E F3(openinfo)2.53 E F0 +.031(is NULL, each access method will use def)2.53 F .031 +(aults appropriate for the system and the)-.1 F(access method.)108 412.8 Q F3 +(Dbopen)108 429.6 Q F0 .416 +(returns a pointer to a DB structure on success and NULL on error)2.917 F 5.416 +(.T)-.55 G .416(he DB structure is de\214ned in)423.21 429.6 R(the include \214le, and contains at least the follo)-.4 E +(wing \214elds:)-.25 E(typedef struct {)108 465.6 Q(DBTYPE type;)144 477.6 Q +(int \(*close\)\(const DB *db\);)144 489.6 Q +(int \(*del\)\(const DB *db, const DBT *k)144 501.6 Q -.15(ey)-.1 G 2.5(,u)-.5 +G(_int \215ags\);)318.92 501.6 Q(int \(*fd\)\(const DB *db\);)144 513.6 Q +(int \(*get\)\(const DB *db, DBT *k)144 525.6 Q -.15(ey)-.1 G 2.5(,D)-.5 G +(BT *data, u_int \215ags\);)297.53 525.6 Q(int \(*put\)\(const DB *db, DBT *k) +144 537.6 Q -.15(ey)-.1 G 2.5(,c)-.5 G(onst DBT *data,)295.31 537.6 Q +(u_int \215ags\);)194 549.6 Q(int \(*sync\)\(const DB *db, u_int \215ags\);)144 +561.6 Q(int \(*seq\)\(const DB *db, DBT *k)144 573.6 Q -.15(ey)-.1 G 2.5(,D)-.5 +G(BT *data, u_int \215ags\);)298.64 573.6 Q 2.5(}D)108 585.6 S(B;)122.52 585.6 +Q .101 +(These elements describe a database type and a set of functions performing v) +108 602.4 R .101(arious actions.)-.25 F .101(These functions)5.101 F(tak)108 +614.4 Q 3.039(eap)-.1 G .539(ointer to a structure as returned by)140.078 614.4 +R F3(dbopen)3.038 E F0 3.038(,a).24 G .538 +(nd sometimes one or more pointers to k)323.196 614.4 R -.15(ey)-.1 G .538 +(/data struc-).15 F(tures and a \215ag v)108 626.4 Q(alue.)-.25 E 16.28 +(type The)108 643.2 R +(type of the underlying access method \(and \214le format\).)2.5 E 12.95 +(close A)108 660 R .988(pointer to a routine to \215ush an)3.488 F 3.489(yc) +-.15 G .989(ached information to disk, free an)293.968 660 R 3.489(ya)-.15 G +.989(llocated resources, and)446.662 660 R .112 +(close the underlying \214le\(s\).)144 672 R .111(Since k)5.112 F -.15(ey)-.1 G +.111(/data pairs may be cached in memory).15 F 2.611(,f)-.65 G .111 +(ailing to sync the \214le)455.666 672 R .494(with a)144 684 R F3(close)2.994 E +F0(or)2.994 E F3(sync)2.994 E F0 .495 +(function may result in inconsistent or lost information.)2.994 F F3(Close) +5.495 E F0 .495(routines return)2.995 F(4.4 Berk)72 732 Q(ele)-.1 E 2.5(yD)-.15 +G(istrib)132.57 732 Q 89.875(ution September)-.2 F(13, 1993)2.5 E(1)535 732 Q +EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 124.01(DBOPEN\(3\) BSD)72 48 R(Programmer')2.5 E 2.5 +(sM)-.55 G 124.01(anual DBOPEN\(3\))340.17 48 R(-1 on error \(setting)144 84 Q +/F1 10/Times-Italic@0 SF(errno)2.5 E F0 2.5(\)a).18 G(nd 0 on success.)254.43 +84 Q 21.28(del A)108 100.8 R(pointer to a routine to remo)2.5 E .3 -.15(ve k) +-.15 H -.15(ey).05 G(/data pairs from the database.).15 E(The parameter)144 +117.6 Q F1<8d61>2.5 E(g)-.1 E F0(may be set to the follo)2.5 E(wing v)-.25 E +(alue:)-.25 E(R_CURSOR)144 134.4 Q .289 +(Delete the record referenced by the cursor)180 146.4 R 5.288(.T)-.55 G .288 +(he cursor must ha)363.342 146.4 R .588 -.15(ve p)-.2 H(re).15 E .288 +(viously been initial-)-.25 F(ized.)180 158.4 Q F1(Delete)144 175.2 Q F0 .03 +(routines return -1 on error \(setting)2.53 F F1(errno)2.53 E F0 .03 +(\), 0 on success, and 1 if the speci\214ed).18 F F1 -.1(ke)2.53 G(y)-.2 E F0 +-.1(wa)2.53 G 2.53(sn).1 G .03(ot in)521.91 175.2 R(the \214le.)144 187.2 Q +25.17(fd A)108 204 R .451 +(pointer to a routine which returns a \214le descriptor representati)2.951 F +.75 -.15(ve o)-.25 H 2.95(ft).15 G .45(he underlying database.)431.73 204 R(A) +5.45 E .942(\214le descriptor referencing the same \214le will be returned to \ +all processes which call)144 216 R F1(dbopen)3.442 E F0(with)3.442 E 1.629 +(the same)144 228 R F1(\214le)4.129 E F0 4.129(name. This)4.129 F 1.628 +(\214le descriptor may be safely used as a ar)4.128 F 1.628(gument to the)-.18 +F F1(fcntl)4.128 E F0 1.628(\(2\) and).51 F F1(\215oc)144 240 Q(k)-.2 E F0 .425 +(\(2\) locking functions.).67 F .425 +(The \214le descriptor is not necessarily associated with an)5.425 F 2.925(yo) +-.15 G 2.925(ft)492.7 240 S .425(he under)501.735 240 R(-)-.2 E .198 +(lying \214les used by the access method.)144 252 R .198 +(No \214le descriptor is a)5.198 F -.25(va)-.2 G .198 +(ilable for in memory databases.).25 F F1(Fd)5.198 E F0 +(routines return -1 on error \(setting)144 264 Q F1(errno)2.5 E F0 +(\), and the \214le descriptor on success.).18 E 21.28(get A)108 280.8 R +(pointer to a routine which is the interf)2.5 E .001(ace for k)-.1 F -.15(ey) +-.1 G .001(ed retrie).15 F -.25(va)-.25 G 2.501(lf).25 G .001 +(rom the database.)399.755 280.8 R .001(The address and)5.001 F .061 +(length of the data associated with the speci\214ed)144 292.8 R F1 -.1(ke)2.561 +G(y)-.2 E F0 .06(are returned in the structure referenced by)2.561 F F1(data) +2.56 E F0(.).26 E F1(Get)144 304.8 Q F0(routines return -1 on error \(setting) +2.5 E F1(errno)2.5 E F0(\), 0 on success, and 1 if the).18 E F1 -.1(ke)2.5 G(y) +-.2 E F0 -.1(wa)2.5 G 2.5(sn).1 G(ot in the \214le.)471.66 304.8 Q 20.72(put A) +108 321.6 R(pointer to a routine to store k)2.5 E -.15(ey)-.1 G +(/data pairs in the database.).15 E(The parameter)144 338.4 Q F1<8d61>2.5 E(g) +-.1 E F0(may be set to one of the follo)2.5 E(wing v)-.25 E(alues:)-.25 E +(R_CURSOR)144 355.2 Q .051(Replace the k)180 367.2 R -.15(ey)-.1 G .051 +(/data pair referenced by the cursor).15 F 5.052(.T)-.55 G .052 +(he cursor must ha)393.98 367.2 R .352 -.15(ve p)-.2 H(re).15 E .052 +(viously been)-.25 F(initialized.)180 379.2 Q(R_IAFTER)144 396 Q 1.165 +(Append the data immediately after the data referenced by)180 408 R F1 -.1(ke) +3.664 G(y)-.2 E F0 3.664(,c).32 G 1.164(reating a ne)446.758 408 R 3.664(wk) +-.25 G -.15(ey)511.27 408 S(/data).15 E(pair)180 420 Q 6.065(.T)-.55 G 1.065 +(he record number of the appended k)209.675 420 R -.15(ey)-.1 G 1.065 +(/data pair is returned in the).15 F F1 -.1(ke)3.565 G(y)-.2 E F0(structure.) +3.565 E(\(Applicable only to the DB_RECNO access method.\))180 432 Q(R_IBEFORE) +144 448.8 Q 1.293(Insert the data immediately before the data referenced by)180 +460.8 R F1 -.1(ke)3.793 G(y)-.2 E F0 3.793(,c).32 G 1.293(reating a ne)446.371 +460.8 R 3.793(wk)-.25 G -.15(ey)511.27 460.8 S(/data).15 E(pair)180 472.8 Q +6.54(.T)-.55 G 1.54(he record number of the inserted k)210.15 472.8 R -.15(ey) +-.1 G 1.541(/data pair is returned in the).15 F F1 -.1(ke)4.041 G(y)-.2 E F0 +(structure.)4.041 E(\(Applicable only to the DB_RECNO access method.\))180 +484.8 Q(R_NOO)144 501.6 Q(VER)-.5 E(WRITE)-.55 E(Enter the ne)180 513.6 Q 2.5 +(wk)-.25 G -.15(ey)242.69 513.6 S(/data pair only if the k).15 E .3 -.15(ey d) +-.1 H(oes not pre).15 E(viously e)-.25 E(xist.)-.15 E(R_SETCURSOR)144 530.4 Q +1.36(Store the k)180 542.4 R -.15(ey)-.1 G 1.36(/data pair).15 F 3.86(,s)-.4 G +1.359(etting or initializing the position of the cursor to reference it.)283.94 +542.4 R(\(Applicable only to the DB_BTREE and DB_RECNO access methods.\))180 +554.4 Q .563(R_SETCURSOR is a)144 571.2 R -.25(va)-.2 G .564 +(ilable only for the DB_BTREE and DB_RECNO access methods because).25 F +(it implies that the k)144 583.2 Q -.15(ey)-.1 G 2.5(sh).15 G -2.25 -.2(av e) +241.81 583.2 T(an inherent order which does not change.)2.7 E .416 +(R_IAFTER and R_IBEFORE are a)144 600 R -.25(va)-.2 G .416 +(ilable only for the DB_RECNO access method because the).25 F(y)-.15 E 1.221 +(each imply that the access method is able to create ne)144 612 R 3.722(wk)-.25 +G -.15(ey)385.644 612 S 3.722(s. This).15 F 1.222(is only true if the k)3.722 F +-.15(ey)-.1 G 3.722(sa).15 G(re)532.23 612 Q +(ordered and independent, record numbers for e)144 624 Q(xample.)-.15 E .289 +(The def)144 640.8 R .289(ault beha)-.1 F .289(vior of the)-.2 F F1(put)2.789 E +F0 .289(routines is to enter the ne)2.789 F 2.789(wk)-.25 G -.15(ey)388.998 +640.8 S .288(/data pair).15 F 2.788(,r)-.4 G .288(eplacing an)444.284 640.8 R +2.788(yp)-.15 G(re)503.03 640.8 Q(viously)-.25 E -.15(ex)144 652.8 S(isting k) +.15 E -.15(ey)-.1 G(.)-.5 E F1(Put)144 669.6 Q F0 .37 +(routines return -1 on error \(setting)2.87 F F1(errno)2.87 E F0 .37 +(\), 0 on success, and 1 if the R_NOO).18 F(VER)-.5 E(WRITE)-.55 E F1<8d61>2.87 +E(g)-.1 E F0 -.1(wa)144 681.6 S 2.5(ss).1 G(et and the k)165.84 681.6 Q .3 -.15 +(ey a)-.1 H(lready e).15 E(xists in the \214le.)-.15 E(4.4 Berk)72 732 Q(ele) +-.1 E 2.5(yD)-.15 G(istrib)132.57 732 Q 89.875(ution September)-.2 F(13, 1993) +2.5 E(2)535 732 Q EP +%%Page: 3 3 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 124.01(DBOPEN\(3\) BSD)72 48 R(Programmer')2.5 E 2.5 +(sM)-.55 G 124.01(anual DBOPEN\(3\))340.17 48 R 20.17(seq A)108 84 R .002 +(pointer to a routine which is the interf)2.502 F .002 +(ace for sequential retrie)-.1 F -.25(va)-.25 G 2.502(lf).25 G .002 +(rom the database.)416.694 84 R .001(The address)5.001 F .219 +(and length of the k)144 96 R .519 -.15(ey a)-.1 H .219 +(re returned in the structure referenced by).15 F/F1 10/Times-Italic@0 SF -.1 +(ke)2.72 G(y)-.2 E F0 2.72(,a).32 G .22(nd the address and length of)426.42 96 +R(the data are returned in the structure referenced by)144 108 Q F1(data)2.5 E +F0(.).26 E .937(Sequential k)144 124.8 R -.15(ey)-.1 G .937(/data pair retrie) +.15 F -.25(va)-.25 G 3.437(lm).25 G .936(ay be)289.748 124.8 R .936(gin at an) +-.15 F 3.436(yt)-.15 G .936(ime, and the position of the `)359.292 124.8 R +(`cursor')-.74 E 3.436('i)-.74 G 3.436(sn)519.894 124.8 S(ot)532.22 124.8 Q(af) +144 136.8 Q 1.585(fected by calls to the)-.25 F F1(del)4.085 E F0(,).51 E F1 +-.1(ge)4.085 G(t).1 E F0(,).68 E F1(put)4.086 E F0 4.086(,o).68 G(r)308.452 +136.8 Q F1(sync)4.086 E F0 4.086(routines. Modi\214cations)4.086 F 1.586 +(to the database during a)4.086 F 1.404(sequential scan will be re\215ected in\ + the scan, i.e. records inserted behind the cursor will not be)144 148.8 R +(returned while records inserted in front of the cursor will be returned.)144 +160.8 Q(The \215ag v)144 177.6 Q(alue)-.25 E/F2 10/Times-Bold@0 SF(must)2.5 E +F0(be set to one of the follo)2.5 E(wing v)-.25 E(alues:)-.25 E(R_CURSOR)144 +194.4 Q .523(The data associated with the speci\214ed k)180 206.4 R .824 -.15 +(ey i)-.1 H 3.024(sr).15 G 3.024(eturned. This)367.236 206.4 R(dif)3.024 E .524 +(fers from the)-.25 F F1 -.1(ge)3.024 G(t).1 E F0(routines)3.024 E 1.143 +(in that it sets or initializes the cursor to the location of the k)180 218.4 R +1.443 -.15(ey a)-.1 H 3.642(sw).15 G 3.642(ell. \(Note,)464.924 218.4 R 1.142 +(for the)3.642 F 1.275(DB_BTREE access method, the returned k)180 230.4 R 1.575 +-.15(ey i)-.1 H 3.775(sn).15 G 1.276(ot necessarily an e)386.425 230.4 R 1.276 +(xact match for the)-.15 F .598(speci\214ed k)180 242.4 R -.15(ey)-.1 G 5.598 +(.T)-.5 G .598(he returned k)246.396 242.4 R .898 -.15(ey i)-.1 H 3.098(st).15 +G .598(he smallest k)325.188 242.4 R .898 -.15(ey g)-.1 H .598 +(reater than or equal to the speci\214ed).15 F -.1(ke)180 254.4 S 1.3 -.65 +(y, p)-.05 H(ermitting partial k).65 E .3 -.15(ey m)-.1 H +(atches and range searches.\)).15 E(R_FIRST)144 271.2 Q 1.043(The \214rst k)180 +283.2 R -.15(ey)-.1 G 1.044(/data pair of the database is returned, and the cu\ +rsor is set or initialized to).15 F(reference it.)180 295.2 Q(R_LAST)144 312 Q +.085(The last k)180 324 R -.15(ey)-.1 G .085(/data pair of the database is ret\ +urned, and the cursor is set or initialized to ref-).15 F(erence it.)180 336 Q +(\(Applicable only to the DB_BTREE and DB_RECNO access methods.\))5 E(R_NEXT) +144 352.8 Q(Retrie)180 364.8 Q .604 -.15(ve t)-.25 H .304(he k).15 F -.15(ey) +-.1 G .304(/data pair immediately after the cursor).15 F 5.304(.I)-.55 G 2.804 +(ft)410.622 364.8 S .305(he cursor is not yet set, this is)419.536 364.8 R +(the same as the R_FIRST \215ag.)180 376.8 Q(R_PREV)144 393.6 Q(Retrie)180 +405.6 Q .755 -.15(ve t)-.25 H .455(he k).15 F -.15(ey)-.1 G .455 +(/data pair immediately before the cursor).15 F 5.455(.I)-.55 G 2.955(ft)419.05 +405.6 S .454(he cursor is not yet set, this)428.115 405.6 R .62 +(is the same as the R_LAST \215ag.)180 417.6 R .621 +(\(Applicable only to the DB_BTREE and DB_RECNO)5.621 F(access methods.\))180 +429.6 Q .911(R_LAST and R_PREV are a)144 446.4 R -.25(va)-.2 G .911 +(ilable only for the DB_BTREE and DB_RECNO access methods).25 F(because the)144 +458.4 Q 2.5(ye)-.15 G(ach imply that the k)202.16 458.4 Q -.15(ey)-.1 G 2.5(sh) +.15 G -2.25 -.2(av e)302.18 458.4 T(an inherent order which does not change.) +2.7 E F1(Seq)144 475.2 Q F0 .061(routines return -1 on error \(setting)2.561 F +F1(errno)2.561 E F0 .061(\), 0 on success and 1 if there are no k).18 F -.15 +(ey)-.1 G .061(/data pairs less).15 F .35 +(than or greater than the speci\214ed or current k)144 487.2 R -.15(ey)-.1 G +5.349(.I)-.5 G 2.849(ft)346.467 487.2 S .349 +(he DB_RECNO access method is being used,)355.426 487.2 R .025 +(and if the database \214le is a character special \214le and no complete k)144 +499.2 R -.15(ey)-.1 G .025(/data pairs are currently a).15 F -.25(va)-.2 G(il-) +.25 E(able, the)144 511.2 Q F1(seq)2.5 E F0(routines return 2.)2.5 E 15.17 +(sync A)108 528 R .458(pointer to a routine to \215ush an)2.958 F 2.957(yc)-.15 +G .457(ached information to disk.)289.72 528 R .457 +(If the database is in memory only)5.457 F(,)-.65 E(the)144 540 Q F1(sync)2.5 E +F0(routine has no ef)2.5 E(fect and will al)-.25 E -.1(wa)-.1 G(ys succeed.).1 +E(The \215ag v)144 556.8 Q(alue may be set to the follo)-.25 E(wing v)-.25 E +(alue:)-.25 E(R_RECNOSYNC)144 573.6 Q .077(If the DB_RECNO access method is be\ +ing used, this \215ag causes the sync routine to apply)180 585.6 R .75(to the \ +btree \214le which underlies the recno \214le, not the recno \214le itself.)180 +597.6 R .75(\(See the)5.75 F F1(bfname)3.25 E F0(\214eld of the)180 609.6 Q F1 +-.37(re)2.5 G(cno).37 E F0(\(3\) manual page for more information.\)).18 E F1 +(Sync)144 626.4 Q F0(routines return -1 on error \(setting)2.5 E F1(errno)2.5 E +F0 2.5(\)a).18 G(nd 0 on success.)336.91 626.4 Q/F3 9/Times-Bold@0 SF(KEY/D)72 +643.2 Q -1.35 -.855(AT A)-.315 H -.666(PA)3.105 G(IRS).666 E F0 .134 +(Access to all \214le types is based on k)108 655.2 R -.15(ey)-.1 G .134 +(/data pairs.).15 F .134(Both k)5.134 F -.15(ey)-.1 G 2.634(sa).15 G .134 +(nd data are represented by the follo)359.078 655.2 R .135(wing data)-.25 F +(structure:)108 667.2 Q(typedef struct {)108 684 Q(4.4 Berk)72 732 Q(ele)-.1 E +2.5(yD)-.15 G(istrib)132.57 732 Q 89.875(ution September)-.2 F(13, 1993)2.5 E +(3)535 732 Q EP +%%Page: 4 4 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 124.01(DBOPEN\(3\) BSD)72 48 R(Programmer')2.5 E 2.5 +(sM)-.55 G 124.01(anual DBOPEN\(3\))340.17 48 R -.2(vo)144 84 S(id *data;).2 E +(size_t size;)144 96 Q 2.5(}D)108 108 S(BT)122.52 108 Q(;)-.55 E +(The elements of the DBT structure are de\214ned as follo)108 124.8 Q(ws:)-.25 +E 16.84(data A)108 141.6 R(pointer to a byte string.)2.5 E 17.95(size The)108 +158.4 R(length of the byte string.)2.5 E -2.15 -.25(Ke y)108 175.2 T .829(and \ +data byte strings may reference strings of essentially unlimited length althou\ +gh an)3.579 F 3.328(yt)-.15 G 1.028 -.1(wo o)492.894 175.2 T 3.328(ft).1 G(hem) +522.78 175.2 Q 1.133(must \214t into a)108 187.2 R -.25(va)-.2 G 1.134 +(ilable memory at the same time.).25 F 1.134 +(It should be noted that the access methods pro)6.134 F 1.134(vide no)-.15 F +(guarantees about byte string alignment.)108 199.2 Q/F1 9/Times-Bold@0 SF(ERR) +72 216 Q(ORS)-.27 E F0(The)108 228 Q/F2 10/Times-Italic@0 SF(dbopen)3.389 E F0 +.889(routine may f)3.389 F .889(ail and set)-.1 F F2(errno)3.388 E F0 .888 +(for an)3.388 F 3.388(yo)-.15 G 3.388(ft)324.376 228 S .888 +(he errors speci\214ed for the library routines)333.874 228 R F2(open)3.388 E +F0(\(2\)).24 E(and)108 240 Q F2(malloc)2.5 E F0(\(3\) or the follo).31 E(wing:) +-.25 E([EFTYPE])108 256.8 Q 2.5<418c>144 268.8 S(le is incorrectly formatted.) +159.28 268.8 Q([EINV)108 285.6 Q(AL])-1.35 E 2.812(Ap)144 297.6 S .313(aramete\ +r has been speci\214ed \(hash function, pad byte etc.\) that is incompatible w\ +ith the current)159.032 297.6 R .406 +(\214le speci\214cation or which is not meaningful for the function \(for e)144 +309.6 R .405(xample, use of the cursor with-)-.15 F .099 +(out prior initialization\) or there is a mismatch between the v)144 321.6 R .1 +(ersion number of \214le and the softw)-.15 F(are.)-.1 E(The)108 338.4 Q F2 +(close)3.469 E F0 .969(routines may f)3.469 F .969(ail and set)-.1 F F2(errno) +3.469 E F0 .969(for an)3.469 F 3.469(yo)-.15 G 3.469(ft)320.18 338.4 S .969 +(he errors speci\214ed for the library routines)329.759 338.4 R F2(close)3.468 +E F0(\(2\),).18 E F2 -.37(re)108 350.4 S(ad).37 E F0(\(2\),).77 E F2(write)2.5 +E F0(\(2\),).18 E F2(fr)2.5 E(ee)-.37 E F0(\(3\), or).18 E F2(fsync)2.5 E F0 +(\(2\).).31 E(The)108 367.2 Q F2(del)2.969 E F0(,).51 E F2 -.1(ge)2.969 G(t).1 +E F0(,).68 E F2(put)2.969 E F0(and)2.969 E F2(seq)2.969 E F0 .469 +(routines may f)2.969 F .469(ail and set)-.1 F F2(errno)2.97 E F0 .47(for an) +2.97 F 2.97(yo)-.15 G 2.97(ft)377.59 367.2 S .47 +(he errors speci\214ed for the library rou-)386.67 367.2 R(tines)108 379.2 Q F2 +-.37(re)2.5 G(ad).37 E F0(\(2\),).77 E F2(write)2.5 E F0(\(2\),).18 E F2(fr)2.5 +E(ee)-.37 E F0(\(3\) or).18 E F2(malloc)2.5 E F0(\(3\).).31 E(The)108 396 Q F2 +(fd)2.5 E F0(routines will f)2.5 E(ail and set)-.1 E F2(errno)2.5 E F0 +(to ENOENT for in memory databases.)2.5 E(The)108 412.8 Q F2(sync)2.5 E F0 +(routines may f)2.5 E(ail and set)-.1 E F2(errno)2.5 E F0(for an)2.5 E 2.5(yo) +-.15 G 2.5(ft)307.71 412.8 S(he errors speci\214ed for the library routine) +316.32 412.8 Q F2(fsync)2.5 E F0(\(2\).).31 E F1(SEE ALSO)72 429.6 Q F2(btr)108 +441.6 Q(ee)-.37 E F0(\(3\),).18 E F2(hash)2.5 E F0(\(3\),).28 E F2(mpool)2.5 E +F0(\(3\),).51 E F2 -.37(re)2.5 G(cno).37 E F0(\(3\)).18 E F2 .904(LIBTP: P)108 +465.6 R(ortable)-.8 E 3.404(,M)-.1 G .904(odular T)189.738 465.6 R -.15(ra)-.55 +G .904(nsactions for UNIX).15 F F0 3.404(,M).94 G(ar)328.884 465.6 Q .904 +(go Seltzer)-.18 F 3.403(,M)-.4 G .903(ichael Olson, USENIX proceedings,) +392.041 465.6 R -.4(Wi)108 477.6 S(nter 1992.).4 E F1 -.09(BU)72 494.4 S(GS).09 +E F0 .399(The typedef DBT is a mnemonic for `)108 506.4 R .399 +(`data base thang')-.74 F .399(', and w)-.74 F .399 +(as used because noone could think of a rea-)-.1 F(sonable name that w)108 +518.4 Q(asn')-.1 E 2.5(ta)-.18 G(lready used.)216.03 518.4 Q +(The \214le descriptor interf)108 535.2 Q +(ace is a kluge and will be deleted in a future v)-.1 E(ersion of the interf) +-.15 E(ace.)-.1 E(None of the access methods pro)108 552 Q(vide an)-.15 E 2.5 +(yf)-.15 G(orm of concurrent access, locking, or transactions.)275.16 552 Q +(4.4 Berk)72 732 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 732 Q 89.875 +(ution September)-.2 F(13, 1993)2.5 E(4)535 732 Q EP +%%Trailer +end +%%EOF diff --git a/circuitpython/lib/berkeley-db-1.xx/docs/hash.3.ps b/circuitpython/lib/berkeley-db-1.xx/docs/hash.3.ps new file mode 100644 index 0000000..18303cf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/docs/hash.3.ps @@ -0,0 +1,292 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.08 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Bold +%%+ font Times-Italic +%%DocumentSuppliedResources: procset grops 1.08 0 +%%Pages: 2 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.08 0 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Bold +%%IncludeResource: font Times-Italic +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL +792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron +/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space +/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft +/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four +/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C +/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash +/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q +/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase +/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger +/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus +/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu +/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright +/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde +/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute +/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls +/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute +/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve +/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex +/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE +/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 136.79(HASH\(3\) BSD)72 48 R(Programmer')2.5 E 2.5(sM) +-.55 G 136.79(anual HASH\(3\))340.17 48 R/F1 9/Times-Bold@0 SF -.18(NA)72 84 S +(ME).18 E F0(hash \255 hash database access method)108 96 Q F1(SYNOPSIS)72 +112.8 Q/F2 10/Times-Bold@0 SF(#include )108 124.8 Q(#include )-.4 E F1(DESCRIPTION)72 153.6 Q F0 .29(The routine)108 165.6 R +/F3 10/Times-Italic@0 SF(dbopen)2.79 E F0 .29(is the library interf)2.79 F .29 +(ace to database \214les.)-.1 F .29 +(One of the supported \214le formats is hash \214les.)5.29 F .974 +(The general description of the database access methods is in)108 177.6 R F3 +(dbopen)3.475 E F0 .975(\(3\), this manual page describes only).24 F +(the hash speci\214c information.)108 189.6 Q(The hash data structure is an e) +108 206.4 Q(xtensible, dynamic hashing scheme.)-.15 E .83 +(The access method speci\214c data structure pro)108 223.2 R .83(vided to)-.15 +F F3(dbopen)3.33 E F0 .83(is de\214ned in the include \214le as fol-)-.4 F(lo)108 235.2 Q(ws:)-.25 E(typedef struct {) +108 259.2 Q(int bsize;)144 271.2 Q(int cachesize;)144 283.2 Q(int f)144 295.2 Q +-.1(fa)-.25 G(ctor;).1 E(u_long \(*hash\)\(const v)144 307.2 Q +(oid *, size_t\);)-.2 E(int lorder;)144 319.2 Q(int nelem;)144 331.2 Q 2.5(}H) +108 343.2 S(ASHINFO;)122.52 343.2 Q +(The elements of this structure are as follo)108 360 Q(ws:)-.25 E(bsize)108 +376.8 Q F3(Bsize)144 376.8 Q F0 1.393(de\214nes the hash table b)3.893 F(uck) +-.2 E 1.393(et size, and is, by def)-.1 F 1.394(ault, 256 bytes.)-.1 F 1.394 +(It may be preferable to)6.394 F +(increase the page size for disk-resident tables and tables with lar)144 388.8 +Q(ge data items.)-.18 E(cachesize)108 405.6 Q 3.16(As)144 417.6 S .66 +(uggested maximum size, in bytes, of the memory cache.)158.27 417.6 R .659 +(This v)5.659 F .659(alue is)-.25 F F2(only)3.159 E F0(advisory)3.159 E 3.159 +(,a)-.65 G .659(nd the)514.621 417.6 R +(access method will allocate more memory rather than f)144 429.6 Q(ail.)-.1 E +-2.1 -.25(ff a)108 446.4 T(ctor).25 E F3(Ffactor)9.7 E F0 .482 +(indicates a desired density within the hash table.)2.981 F .482 +(It is an approximation of the number of)5.482 F -.1(ke)144 458.4 S .429 +(ys allo)-.05 F .429(wed to accumulate in an)-.25 F 2.929(yo)-.15 G .429(ne b) +291.454 458.4 R(uck)-.2 E .429(et, determining when the hash table gro)-.1 F +.428(ws or shrinks.)-.25 F(The def)144 470.4 Q(ault v)-.1 E(alue is 8.)-.25 E +(hash)108 487.2 Q F3(Hash)144 487.2 Q F0 .1(is a user de\214ned hash function.) +2.6 F .1(Since no hash function performs equally well on all possible)5.1 F +.924(data, the user may \214nd that the b)144 499.2 R .923 +(uilt-in hash function does poorly on a particular data set.)-.2 F(User)5.923 E +1.408(speci\214ed hash functions must tak)144 511.2 R 3.909(et)-.1 G 1.609 -.1 +(wo a)293.431 511.2 T -.18(rg).1 G 1.409 +(uments \(a pointer to a byte string and a length\) and).18 F +(return an u_long to be used as the hash v)144 523.2 Q(alue.)-.25 E 9.62 +(lorder The)108 540 R 1.597(byte order for inte)4.097 F 1.596 +(gers in the stored database metadata.)-.15 F 1.596 +(The number should represent the)6.596 F .688(order as an inte)144 552 R .689 +(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689 +(ould be the number 4,321.)-.1 F(If)5.689 E F3(lor)3.189 E(der)-.37 E F0 .689 +(is 0 \(no)3.189 F .822(order is speci\214ed\) the current host order is used.) +144 564 R .822(If the)5.822 F .822(\214le already e)5.822 F .821 +(xists, the speci\214ed v)-.15 F .821(alue is)-.25 F(ignored and the v)144 576 +Q(alue speci\214ed when the tree w)-.25 E(as created is used.)-.1 E(nelem)108 +592.8 Q F3(Nelem)144 592.8 Q F0 .701 +(is an estimate of the \214nal size of the hash table.)3.2 F .701 +(If not set or set too lo)5.701 F 2.001 -.65(w, h)-.25 H .701(ash tables will) +.65 F -.15(ex)144 604.8 S .448(pand gracefully as k).15 F -.15(ey)-.1 G 2.948 +(sa).15 G .448(re entered, although a slight performance de)255.912 604.8 R +.447(gradation may be noticed.)-.15 F(The def)144 616.8 Q(ault v)-.1 E +(alue is 1.)-.25 E .79(If the \214le already e)108 633.6 R .79 +(xists \(and the O_TR)-.15 F .79(UNC \215ag is not speci\214ed\), the v)-.4 F +.79(alues speci\214ed for the parameters)-.25 F(bsize, f)108 645.6 Q -.1(fa) +-.25 G(ctor).1 E 2.5(,l)-.4 G(order and nelem are ignored and the v)167.23 +645.6 Q(alues speci\214ed when the tree w)-.25 E(as created are used.)-.1 E +1.232(If a hash function is speci\214ed,)108 662.4 R F3(hash_open)3.731 E F0 +1.231(will attempt to determine if the hash function speci\214ed is the)3.731 F +(same as the one with which the database w)108 674.4 Q(as created, and will f) +-.1 E(ail if it is not.)-.1 E(Backw)108 691.2 Q .861(ard compatible interf)-.1 +F .861(aces to the routines described in)-.1 F F3(dbm)3.362 E F0 .862 +(\(3\), and).32 F F3(ndbm)3.362 E F0 .862(\(3\) are pro).32 F .862(vided, ho) +-.15 F(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G(4.4 Berk)72 732 Q(ele)-.1 E 2.5 +(yD)-.15 G(istrib)132.57 732 Q 96.815(ution August)-.2 F(17, 1993)2.5 E(1)535 +732 Q EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 136.79(HASH\(3\) BSD)72 48 R(Programmer')2.5 E 2.5(sM) +-.55 G 136.79(anual HASH\(3\))340.17 48 R(these interf)108 84 Q +(aces are not compatible with pre)-.1 E(vious \214le formats.)-.25 E/F1 9 +/Times-Bold@0 SF(SEE ALSO)72 100.8 Q/F2 10/Times-Italic@0 SF(btr)108 112.8 Q +(ee)-.37 E F0(\(3\),).18 E F2(dbopen)2.5 E F0(\(3\),).24 E F2(mpool)2.5 E F0 +(\(3\),).51 E F2 -.37(re)2.5 G(cno).37 E F0(\(3\)).18 E F2(Dynamic Hash T)108 +136.8 Q(ables)-.92 E F0 2.5(,P).27 G(er)206.79 136.8 Q(-Ak)-.2 E 2.5(eL)-.1 G +(arson, Communications of the A)242.86 136.8 Q(CM, April 1988.)-.4 E F2 2.5(AN) +108 160.8 S .3 -.15(ew H)123.28 160.8 T(ash P).15 E(ac)-.8 E(ka)-.2 E .2 -.1 +(ge f)-.1 H(or UNIX).1 E F0 2.5(,M).94 G(ar)248.41 160.8 Q(go Seltzer)-.18 E +2.5(,U)-.4 G(SENIX Proceedings, W)308.09 160.8 Q(inter 1991.)-.4 E F1 -.09(BU) +72 177.6 S(GS).09 E F0(Only big and little endian byte order is supported.)108 +189.6 Q(4.4 Berk)72 732 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 732 Q 96.815 +(ution August)-.2 F(17, 1993)2.5 E(2)535 732 Q EP +%%Trailer +end +%%EOF diff --git a/circuitpython/lib/berkeley-db-1.xx/docs/hash.usenix.ps b/circuitpython/lib/berkeley-db-1.xx/docs/hash.usenix.ps new file mode 100644 index 0000000..c884778 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/docs/hash.usenix.ps @@ -0,0 +1,12209 @@ +%!PS-Adobe-1.0 +%%Creator: utopia:margo (& Seltzer,608-13E,8072,) +%%Title: stdin (ditroff) +%%CreationDate: Tue Dec 11 15:06:45 1990 +%%EndComments +% @(#)psdit.pro 1.3 4/15/88 +% lib/psdit.pro -- prolog for psdit (ditroff) files +% Copyright (c) 1984, 1985 Adobe Systems Incorporated. All Rights Reserved. +% last edit: shore Sat Nov 23 20:28:03 1985 +% RCSID: $Header: psdit.pro,v 2.1 85/11/24 12:19:43 shore Rel $ + +% Changed by Edward Wang (edward@ucbarpa.berkeley.edu) to handle graphics, +% 17 Feb, 87. + +/$DITroff 140 dict def $DITroff begin +/fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def +/xi{0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto + /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F + /pagesave save def}def +/PB{save /psv exch def currentpoint translate + resolution 72 div dup neg scale 0 0 moveto}def +/PE{psv restore}def +/arctoobig 90 def /arctoosmall .05 def +/m1 matrix def /m2 matrix def /m3 matrix def /oldmat matrix def +/tan{dup sin exch cos div}def +/point{resolution 72 div mul}def +/dround {transform round exch round exch itransform}def +/xT{/devname exch def}def +/xr{/mh exch def /my exch def /resolution exch def}def +/xp{}def +/xs{docsave restore end}def +/xt{}def +/xf{/fontname exch def /slotno exch def fontnames slotno get fontname eq not + {fonts slotno fontname findfont put fontnames slotno fontname put}if}def +/xH{/fontheight exch def F}def +/xS{/fontslant exch def F}def +/s{/fontsize exch def /fontheight fontsize def F}def +/f{/fontnum exch def F}def +/F{fontheight 0 le{/fontheight fontsize def}if + fonts fontnum get fontsize point 0 0 fontheight point neg 0 0 m1 astore + fontslant 0 ne{1 0 fontslant tan 1 0 0 m2 astore m3 concatmatrix}if + makefont setfont .04 fontsize point mul 0 dround pop setlinewidth}def +/X{exch currentpoint exch pop moveto show}def +/N{3 1 roll moveto show}def +/Y{exch currentpoint pop exch moveto show}def +/S{show}def +/ditpush{}def/ditpop{}def +/AX{3 -1 roll currentpoint exch pop moveto 0 exch ashow}def +/AN{4 2 roll moveto 0 exch ashow}def +/AY{3 -1 roll currentpoint pop exch moveto 0 exch ashow}def +/AS{0 exch ashow}def +/MX{currentpoint exch pop moveto}def +/MY{currentpoint pop exch moveto}def +/MXY{moveto}def +/cb{pop}def % action on unknown char -- nothing for now +/n{}def/w{}def +/p{pop showpage pagesave restore /pagesave save def}def +/Dt{/Dlinewidth exch def}def 1 Dt +/Ds{/Ddash exch def}def -1 Ds +/Di{/Dstipple exch def}def 1 Di +/Dsetlinewidth{2 Dlinewidth mul setlinewidth}def +/Dsetdash{Ddash 4 eq{[8 12]}{Ddash 16 eq{[32 36]} + {Ddash 20 eq{[32 12 8 12]}{[]}ifelse}ifelse}ifelse 0 setdash}def +/Dstroke{gsave Dsetlinewidth Dsetdash 1 setlinecap stroke grestore + currentpoint newpath moveto}def +/Dl{rlineto Dstroke}def +/arcellipse{/diamv exch def /diamh exch def oldmat currentmatrix pop + currentpoint translate 1 diamv diamh div scale /rad diamh 2 div def + currentpoint exch rad add exch rad -180 180 arc oldmat setmatrix}def +/Dc{dup arcellipse Dstroke}def +/De{arcellipse Dstroke}def +/Da{/endv exch def /endh exch def /centerv exch def /centerh exch def + /cradius centerv centerv mul centerh centerh mul add sqrt def + /eradius endv endv mul endh endh mul add sqrt def + /endang endv endh atan def + /startang centerv neg centerh neg atan def + /sweep startang endang sub dup 0 lt{360 add}if def + sweep arctoobig gt + {/midang startang sweep 2 div sub def /midrad cradius eradius add 2 div def + /midh midang cos midrad mul def /midv midang sin midrad mul def + midh neg midv neg endh endv centerh centerv midh midv Da + Da} + {sweep arctoosmall ge + {/controldelt 1 sweep 2 div cos sub 3 sweep 2 div sin mul div 4 mul def + centerv neg controldelt mul centerh controldelt mul + endv neg controldelt mul centerh add endh add + endh controldelt mul centerv add endv add + centerh endh add centerv endv add rcurveto Dstroke} + {centerh endh add centerv endv add rlineto Dstroke} + ifelse} + ifelse}def +/Dpatterns[ +[%cf[widthbits] +[8<0000000000000010>] +[8<0411040040114000>] +[8<0204081020408001>] +[8<0000103810000000>] +[8<6699996666999966>] +[8<0000800100001008>] +[8<81c36666c3810000>] +[8<0f0e0c0800000000>] +[8<0000000000000010>] +[8<0411040040114000>] +[8<0204081020408001>] +[8<0000001038100000>] +[8<6699996666999966>] +[8<0000800100001008>] +[8<81c36666c3810000>] +[8<0f0e0c0800000000>] +[8<0042660000246600>] +[8<0000990000990000>] +[8<0804020180402010>] +[8<2418814242811824>] +[8<6699996666999966>] +[8<8000000008000000>] +[8<00001c3e363e1c00>] +[8<0000000000000000>] +[32<00000040000000c00000004000000040000000e0000000000000000000000000>] +[32<00000000000060000000900000002000000040000000f0000000000000000000>] +[32<000000000000000000e0000000100000006000000010000000e0000000000000>] +[32<00000000000000002000000060000000a0000000f00000002000000000000000>] +[32<0000000e0000000000000000000000000000000f000000080000000e00000001>] +[32<0000090000000600000000000000000000000000000007000000080000000e00>] +[32<00010000000200000004000000040000000000000000000000000000000f0000>] +[32<0900000006000000090000000600000000000000000000000000000006000000>]] +[%ug +[8<0000020000000000>] +[8<0000020000002000>] +[8<0004020000002000>] +[8<0004020000402000>] +[8<0004060000402000>] +[8<0004060000406000>] +[8<0006060000406000>] +[8<0006060000606000>] +[8<00060e0000606000>] +[8<00060e000060e000>] +[8<00070e000060e000>] +[8<00070e000070e000>] +[8<00070e020070e000>] +[8<00070e020070e020>] +[8<04070e020070e020>] +[8<04070e024070e020>] +[8<04070e064070e020>] +[8<04070e064070e060>] +[8<06070e064070e060>] +[8<06070e066070e060>] +[8<06070f066070e060>] +[8<06070f066070f060>] +[8<060f0f066070f060>] +[8<060f0f0660f0f060>] +[8<060f0f0760f0f060>] +[8<060f0f0760f0f070>] +[8<0e0f0f0760f0f070>] +[8<0e0f0f07e0f0f070>] +[8<0e0f0f0fe0f0f070>] +[8<0e0f0f0fe0f0f0f0>] +[8<0f0f0f0fe0f0f0f0>] +[8<0f0f0f0ff0f0f0f0>] +[8<1f0f0f0ff0f0f0f0>] +[8<1f0f0f0ff1f0f0f0>] +[8<1f0f0f8ff1f0f0f0>] +[8<1f0f0f8ff1f0f0f8>] +[8<9f0f0f8ff1f0f0f8>] +[8<9f0f0f8ff9f0f0f8>] +[8<9f0f0f9ff9f0f0f8>] +[8<9f0f0f9ff9f0f0f9>] +[8<9f8f0f9ff9f0f0f9>] +[8<9f8f0f9ff9f8f0f9>] +[8<9f8f1f9ff9f8f0f9>] +[8<9f8f1f9ff9f8f1f9>] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8]] +[%mg +[8<8000000000000000>] +[8<0822080080228000>] +[8<0204081020408001>] +[8<40e0400000000000>] +[8<66999966>] +[8<8001000010080000>] +[8<81c36666c3810000>] +[8] +[16<07c00f801f003e007c00f800f001e003c007800f001f003e007c00f801f003e0>] +[16<1f000f8007c003e001f000f8007c003e001f800fc007e003f001f8007c003e00>] +[8] +[16<0040008001000200040008001000200040008000000100020004000800100020>] +[16<0040002000100008000400020001800040002000100008000400020001000080>] +[16<1fc03fe07df0f8f8f07de03fc01f800fc01fe03ff07df8f87df03fe01fc00f80>] +[8<80>] +[8<8040201000000000>] +[8<84cc000048cc0000>] +[8<9900009900000000>] +[8<08040201804020100800020180002010>] +[8<2418814242811824>] +[8<66999966>] +[8<8000000008000000>] +[8<70f8d8f870000000>] +[8<0814224180402010>] +[8] +[8<018245aa45820100>] +[8<221c224180808041>] +[8<88000000>] +[8<0855800080550800>] +[8<2844004482440044>] +[8<0810204080412214>] +[8<00>]]]def +/Dfill{ + transform /maxy exch def /maxx exch def + transform /miny exch def /minx exch def + minx maxx gt{/minx maxx /maxx minx def def}if + miny maxy gt{/miny maxy /maxy miny def def}if + Dpatterns Dstipple 1 sub get exch 1 sub get + aload pop /stip exch def /stipw exch def /stiph 128 def + /imatrix[stipw 0 0 stiph 0 0]def + /tmatrix[stipw 0 0 stiph 0 0]def + /minx minx cvi stiph idiv stiph mul def + /miny miny cvi stipw idiv stipw mul def + gsave eoclip 0 setgray + miny stiph maxy{ + tmatrix exch 5 exch put + minx stipw maxx{ + tmatrix exch 4 exch put tmatrix setmatrix + stipw stiph true imatrix {stip} imagemask + }for + }for + grestore +}def +/Dp{Dfill Dstroke}def +/DP{Dfill currentpoint newpath moveto}def +end + +/ditstart{$DITroff begin + /nfonts 60 def % NFONTS makedev/ditroff dependent! + /fonts[nfonts{0}repeat]def + /fontnames[nfonts{()}repeat]def +/docsave save def +}def + +% character outcalls +/oc{ + /pswid exch def /cc exch def /name exch def + /ditwid pswid fontsize mul resolution mul 72000 div def + /ditsiz fontsize resolution mul 72 div def + ocprocs name known{ocprocs name get exec}{name cb}ifelse +}def +/fractm [.65 0 0 .6 0 0] def +/fraction{ + /fden exch def /fnum exch def gsave /cf currentfont def + cf fractm makefont setfont 0 .3 dm 2 copy neg rmoveto + fnum show rmoveto currentfont cf setfont(\244)show setfont fden show + grestore ditwid 0 rmoveto +}def +/oce{grestore ditwid 0 rmoveto}def +/dm{ditsiz mul}def +/ocprocs 50 dict def ocprocs begin +(14){(1)(4)fraction}def +(12){(1)(2)fraction}def +(34){(3)(4)fraction}def +(13){(1)(3)fraction}def +(23){(2)(3)fraction}def +(18){(1)(8)fraction}def +(38){(3)(8)fraction}def +(58){(5)(8)fraction}def +(78){(7)(8)fraction}def +(sr){gsave 0 .06 dm rmoveto(\326)show oce}def +(is){gsave 0 .15 dm rmoveto(\362)show oce}def +(->){gsave 0 .02 dm rmoveto(\256)show oce}def +(<-){gsave 0 .02 dm rmoveto(\254)show oce}def +(==){gsave 0 .05 dm rmoveto(\272)show oce}def +(uc){gsave currentpoint 400 .009 dm mul add translate + 8 -8 scale ucseal oce}def +end + +% an attempt at a PostScript FONT to implement ditroff special chars +% this will enable us to +% cache the little buggers +% generate faster, more compact PS out of psdit +% confuse everyone (including myself)! +50 dict dup begin +/FontType 3 def +/FontName /DIThacks def +/FontMatrix [.001 0 0 .001 0 0] def +/FontBBox [-260 -260 900 900] def% a lie but ... +/Encoding 256 array def +0 1 255{Encoding exch /.notdef put}for +Encoding + dup 8#040/space put %space + dup 8#110/rc put %right ceil + dup 8#111/lt put %left top curl + dup 8#112/bv put %bold vert + dup 8#113/lk put %left mid curl + dup 8#114/lb put %left bot curl + dup 8#115/rt put %right top curl + dup 8#116/rk put %right mid curl + dup 8#117/rb put %right bot curl + dup 8#120/rf put %right floor + dup 8#121/lf put %left floor + dup 8#122/lc put %left ceil + dup 8#140/sq put %square + dup 8#141/bx put %box + dup 8#142/ci put %circle + dup 8#143/br put %box rule + dup 8#144/rn put %root extender + dup 8#145/vr put %vertical rule + dup 8#146/ob put %outline bullet + dup 8#147/bu put %bullet + dup 8#150/ru put %rule + dup 8#151/ul put %underline + pop +/DITfd 100 dict def +/BuildChar{0 begin + /cc exch def /fd exch def + /charname fd /Encoding get cc get def + /charwid fd /Metrics get charname get def + /charproc fd /CharProcs get charname get def + charwid 0 fd /FontBBox get aload pop setcachedevice + 2 setlinejoin 40 setlinewidth + newpath 0 0 moveto gsave charproc grestore + end}def +/BuildChar load 0 DITfd put +/CharProcs 50 dict def +CharProcs begin +/space{}def +/.notdef{}def +/ru{500 0 rls}def +/rn{0 840 moveto 500 0 rls}def +/vr{0 800 moveto 0 -770 rls}def +/bv{0 800 moveto 0 -1000 rls}def +/br{0 840 moveto 0 -1000 rls}def +/ul{0 -140 moveto 500 0 rls}def +/ob{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath stroke}def +/bu{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath fill}def +/sq{80 0 rmoveto currentpoint dround newpath moveto + 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath stroke}def +/bx{80 0 rmoveto currentpoint dround newpath moveto + 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath fill}def +/ci{500 360 rmoveto currentpoint newpath 333 0 360 arc + 50 setlinewidth stroke}def + +/lt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 add exch s4 a4p stroke}def +/lb{0 800 moveto 0 -550 rlineto currx -200 2cx s4 add exch s4 a4p stroke}def +/rt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 sub exch s4 a4p stroke}def +/rb{0 800 moveto 0 -500 rlineto currx -200 2cx s4 sub exch s4 a4p stroke}def +/lk{0 800 moveto 0 300 -300 300 s4 arcto pop pop 1000 sub + 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def +/rk{0 800 moveto 0 300 s2 300 s4 arcto pop pop 1000 sub + 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def +/lf{0 800 moveto 0 -1000 rlineto s4 0 rls}def +/rf{0 800 moveto 0 -1000 rlineto s4 neg 0 rls}def +/lc{0 -200 moveto 0 1000 rlineto s4 0 rls}def +/rc{0 -200 moveto 0 1000 rlineto s4 neg 0 rls}def +end + +/Metrics 50 dict def Metrics begin +/.notdef 0 def +/space 500 def +/ru 500 def +/br 0 def +/lt 416 def +/lb 416 def +/rt 416 def +/rb 416 def +/lk 416 def +/rk 416 def +/rc 416 def +/lc 416 def +/rf 416 def +/lf 416 def +/bv 416 def +/ob 350 def +/bu 350 def +/ci 750 def +/bx 750 def +/sq 750 def +/rn 500 def +/ul 500 def +/vr 0 def +end + +DITfd begin +/s2 500 def /s4 250 def /s3 333 def +/a4p{arcto pop pop pop pop}def +/2cx{2 copy exch}def +/rls{rlineto stroke}def +/currx{currentpoint pop}def +/dround{transform round exch round exch itransform} def +end +end +/DIThacks exch definefont pop +ditstart +(psc)xT +576 1 1 xr +1(Times-Roman)xf 1 f +2(Times-Italic)xf 2 f +3(Times-Bold)xf 3 f +4(Times-BoldItalic)xf 4 f +5(Helvetica)xf 5 f +6(Helvetica-Bold)xf 6 f +7(Courier)xf 7 f +8(Courier-Bold)xf 8 f +9(Symbol)xf 9 f +10(DIThacks)xf 10 f +10 s +1 f +xi +%%EndProlog + +%%Page: 1 1 +10 s 10 xH 0 xS 1 f +3 f +22 s +1249 626(A)N +1420(N)X +1547(ew)X +1796(H)X +1933(ashing)X +2467(P)X +2574(ackage)X +3136(for)X +3405(U)X +3532(N)X +3659(IX)X +2 f +20 s +3855 562(1)N +1 f +12 s +1607 779(Margo)N +1887(Seltzer)X +9 f +2179(-)X +1 f +2256(University)X +2686(of)X +2790(California,)X +3229(Berkeley)X +2015 875(Ozan)N +2242(Yigit)X +9 f +2464(-)X +1 f +2541(York)X +2762(University)X +3 f +2331 1086(ABSTRACT)N +1 f +10 s +1152 1222(UNIX)N +1385(support)X +1657(of)X +1756(disk)X +1921(oriented)X +2216(hashing)X +2497(was)X +2654(originally)X +2997(provided)X +3314(by)X +2 f +3426(dbm)X +1 f +3595([ATT79])X +3916(and)X +1152 1310(subsequently)N +1595(improved)X +1927(upon)X +2112(in)X +2 f +2199(ndbm)X +1 f +2402([BSD86].)X +2735(In)X +2826(AT&T)X +3068(System)X +3327(V,)X +3429(in-memory)X +3809(hashed)X +1152 1398(storage)N +1420(and)X +1572(access)X +1814(support)X +2090(was)X +2251(added)X +2479(in)X +2577(the)X +2 f +2711(hsearch)X +1 f +3000(library)X +3249(routines)X +3542([ATT85].)X +3907(The)X +1152 1486(result)N +1367(is)X +1457(a)X +1530(system)X +1789(with)X +1968(two)X +2125(incompatible)X +2580(hashing)X +2865(schemes,)X +3193(each)X +3377(with)X +3555(its)X +3666(own)X +3840(set)X +3965(of)X +1152 1574(shortcomings.)N +1152 1688(This)N +1316(paper)X +1517(presents)X +1802(the)X +1922(design)X +2152(and)X +2289(performance)X +2717(characteristics)X +3198(of)X +3286(a)X +3343(new)X +3498(hashing)X +3768(package)X +1152 1776(providing)N +1483(a)X +1539(superset)X +1822(of)X +1909(the)X +2027(functionality)X +2456(provided)X +2761(by)X +2 f +2861(dbm)X +1 f +3019(and)X +2 f +3155(hsearch)X +1 f +3409(.)X +3469(The)X +3614(new)X +3768(package)X +1152 1864(uses)N +1322(linear)X +1537(hashing)X +1818(to)X +1912(provide)X +2189(ef\256cient)X +2484(support)X +2755(of)X +2853(both)X +3026(memory)X +3324(based)X +3538(and)X +3685(disk)X +3849(based)X +1152 1952(hash)N +1319(tables)X +1526(with)X +1688(performance)X +2115(superior)X +2398(to)X +2480(both)X +2 f +2642(dbm)X +1 f +2800(and)X +2 f +2936(hsearch)X +1 f +3210(under)X +3413(most)X +3588(conditions.)X +3 f +1380 2128(Introduction)N +1 f +892 2260(Current)N +1196(UNIX)X +1456(systems)X +1768(offer)X +1984(two)X +2163(forms)X +2409(of)X +720 2348(hashed)N +973(data)X +1137(access.)X +2 f +1413(Dbm)X +1 f +1599(and)X +1745(its)X +1850(derivatives)X +2231(provide)X +720 2436(keyed)N +939(access)X +1171(to)X +1259(disk)X +1418(resident)X +1698(data)X +1858(while)X +2 f +2062(hsearch)X +1 f +2342(pro-)X +720 2524(vides)N +929(access)X +1175(for)X +1309(memory)X +1616(resident)X +1910(data.)X +2124(These)X +2356(two)X +720 2612(access)N +979(methods)X +1302(are)X +1453(incompatible)X +1923(in)X +2037(that)X +2209(memory)X +720 2700(resident)N +1011(hash)X +1195(tables)X +1419(may)X +1593(not)X +1731(be)X +1843(stored)X +2075(on)X +2191(disk)X +2360(and)X +720 2788(disk)N +884(resident)X +1169(tables)X +1387(cannot)X +1632(be)X +1739(read)X +1909(into)X +2063(memory)X +2360(and)X +720 2876(accessed)N +1022(using)X +1215(the)X +1333(in-memory)X +1709(routines.)X +2 f +892 2990(Dbm)N +1 f +1091(has)X +1241(several)X +1512(shortcomings.)X +2026(Since)X +2247(data)X +2423(is)X +720 3078(assumed)N +1032(to)X +1130(be)X +1242(disk)X +1411(resident,)X +1721(each)X +1905(access)X +2146(requires)X +2440(a)X +720 3166(system)N +963(call,)X +1120(and)X +1257(almost)X +1491(certainly,)X +1813(a)X +1869(disk)X +2022(operation.)X +2365(For)X +720 3254(extremely)N +1072(large)X +1264(databases,)X +1623(where)X +1851(caching)X +2131(is)X +2214(unlikely)X +720 3342(to)N +810(be)X +914(effective,)X +1244(this)X +1386(is)X +1466(acceptable,)X +1853(however,)X +2177(when)X +2378(the)X +720 3430(database)N +1022(is)X +1100(small)X +1298(\(i.e.)X +1447(the)X +1569(password)X +1896(\256le\),)X +2069(performance)X +720 3518(improvements)N +1204(can)X +1342(be)X +1443(obtained)X +1744(through)X +2018(caching)X +2293(pages)X +720 3606(of)N +818(the)X +947(database)X +1255(in)X +1348(memory.)X +1685(In)X +1782(addition,)X +2 f +2094(dbm)X +1 f +2262(cannot)X +720 3694(store)N +902(data)X +1062(items)X +1261(whose)X +1492(total)X +1660(key)X +1802(and)X +1943(data)X +2102(size)X +2252(exceed)X +720 3782(the)N +850(page)X +1034(size)X +1191(of)X +1290(the)X +1420(hash)X +1599(table.)X +1827(Similarly,)X +2176(if)X +2257(two)X +2409(or)X +720 3870(more)N +907(keys)X +1076(produce)X +1357(the)X +1477(same)X +1664(hash)X +1833(value)X +2029(and)X +2166(their)X +2334(total)X +720 3958(size)N +876(exceeds)X +1162(the)X +1291(page)X +1474(size,)X +1650(the)X +1779(table)X +1966(cannot)X +2210(store)X +2396(all)X +720 4046(the)N +838(colliding)X +1142(keys.)X +892 4160(The)N +1050(in-memory)X +2 f +1439(hsearch)X +1 f +1725(routines)X +2015(have)X +2199(different)X +720 4248(shortcomings.)N +1219(First,)X +1413(the)X +1539(notion)X +1771(of)X +1865(a)X +1928(single)X +2146(hash)X +2320(table)X +720 4336(is)N +807(embedded)X +1171(in)X +1266(the)X +1397(interface,)X +1732(preventing)X +2108(an)X +2217(applica-)X +720 4424(tion)N +902(from)X +1116(accessing)X +1482(multiple)X +1806(tables)X +2050(concurrently.)X +720 4512(Secondly,)N +1063(the)X +1186(routine)X +1438(to)X +1525(create)X +1743(a)X +1804(hash)X +1976(table)X +2157(requires)X +2440(a)X +720 4600(parameter)N +1066(which)X +1286(declares)X +1573(the)X +1694(size)X +1842(of)X +1932(the)X +2053(hash)X +2223(table.)X +2422(If)X +720 4688(this)N +856(size)X +1001(is)X +1074(set)X +1183(too)X +1305(low,)X +1465(performance)X +1892(degradation)X +2291(or)X +2378(the)X +720 4776(inability)N +1008(to)X +1092(add)X +1230(items)X +1425(to)X +1509(the)X +1628(table)X +1805(may)X +1964(result.)X +2223(In)X +2311(addi-)X +720 4864(tion,)N +2 f +910(hsearch)X +1 f +1210(requires)X +1515(that)X +1681(the)X +1825(application)X +2226(allocate)X +720 4952(memory)N +1037(for)X +1181(the)X +1329(key)X +1495(and)X +1661(data)X +1845(items.)X +2108(Lastly,)X +2378(the)X +2 f +720 5040(hsearch)N +1 f +1013(routines)X +1310(provide)X +1594(no)X +1713(interface)X +2034(to)X +2135(store)X +2329(hash)X +720 5128(tables)N +927(on)X +1027(disk.)X +16 s +720 5593 MXY +864 0 Dl +2 f +8 s +760 5648(1)N +1 f +9 s +5673(UNIX)Y +990(is)X +1056(a)X +1106(registered)X +1408(trademark)X +1718(of)X +1796(AT&T.)X +10 s +2878 2128(The)N +3032(goal)X +3199(of)X +3295(our)X +3431(work)X +3625(was)X +3779(to)X +3870(design)X +4108(and)X +4253(imple-)X +2706 2216(ment)N +2900(a)X +2970(new)X +3138(package)X +3436(that)X +3590(provides)X +3899(a)X +3968(superset)X +4264(of)X +4364(the)X +2706 2304(functionality)N +3144(of)X +3240(both)X +2 f +3411(dbm)X +1 f +3578(and)X +2 f +3723(hsearch)X +1 f +3977(.)X +4045(The)X +4198(package)X +2706 2392(had)N +2871(to)X +2982(overcome)X +3348(the)X +3495(interface)X +3826(shortcomings)X +4306(cited)X +2706 2480(above)N +2930(and)X +3078(its)X +3185(implementation)X +3719(had)X +3867(to)X +3961(provide)X +4238(perfor-)X +2706 2568(mance)N +2942(equal)X +3142(or)X +3235(superior)X +3524(to)X +3612(that)X +3758(of)X +3851(the)X +3975(existing)X +4253(imple-)X +2706 2656(mentations.)N +3152(In)X +3274(order)X +3498(to)X +3614(provide)X +3913(a)X +4003(compact)X +4329(disk)X +2706 2744(representation,)N +3224(graceful)X +3531(table)X +3729(growth,)X +4018(and)X +4176(expected)X +2706 2832(constant)N +3033(time)X +3234(performance,)X +3720(we)X +3873(selected)X +4191(Litwin's)X +2706 2920(linear)N +2923(hashing)X +3206(algorithm)X +3551([LAR88,)X +3872(LIT80].)X +4178(We)X +4324(then)X +2706 3008(enhanced)N +3037(the)X +3161(algorithm)X +3498(to)X +3586(handle)X +3826(page)X +4004(over\257ows)X +4346(and)X +2706 3096(large)N +2900(key)X +3049(handling)X +3362(with)X +3537(a)X +3606(single)X +3830(mechanism,)X +4248(named)X +2706 3184(buddy-in-waiting.)N +3 f +2975 3338(Existing)N +3274(UNIX)X +3499(Hashing)X +3802(Techniques)X +1 f +2878 3470(Over)N +3076(the)X +3210(last)X +3357(decade,)X +3637(several)X +3901(dynamic)X +4213(hashing)X +2706 3558(schemes)N +3000(have)X +3174(been)X +3348(developed)X +3700(for)X +3816(the)X +3936(UNIX)X +4159(timeshar-)X +2706 3646(ing)N +2856(system,)X +3146(starting)X +3433(with)X +3622(the)X +3767(inclusion)X +4107(of)X +2 f +4221(dbm)X +1 f +4359(,)X +4426(a)X +2706 3734(minimal)N +3008(database)X +3321(library)X +3571(written)X +3834(by)X +3950(Ken)X +4120(Thompson)X +2706 3822([THOM90],)N +3141(in)X +3248(the)X +3391(Seventh)X +3694(Edition)X +3974(UNIX)X +4220(system.)X +2706 3910(Since)N +2916(then,)X +3106(an)X +3214(extended)X +3536(version)X +3804(of)X +3903(the)X +4032(same)X +4228(library,)X +2 f +2706 3998(ndbm)N +1 f +2884(,)X +2933(and)X +3078(a)X +3142(public-domain)X +3637(clone)X +3839(of)X +3934(the)X +4060(latter,)X +2 f +4273(sdbm)X +1 f +4442(,)X +2706 4086(have)N +2902(been)X +3098(developed.)X +3491(Another)X +3797 0.1645(interface-compatible)AX +2706 4174(library)N +2 f +2950(gdbm)X +1 f +3128(,)X +3178(was)X +3333(recently)X +3622(made)X +3826(available)X +4145(as)X +4241(part)X +4395(of)X +2706 4262(the)N +2829(Free)X +2997(Software)X +3312(Foundation's)X +3759(\(FSF\))X +3970(software)X +4271(distri-)X +2706 4350(bution.)N +2878 4464(All)N +3017(of)X +3121(these)X +3323(implementations)X +3893(are)X +4029(based)X +4248(on)X +4364(the)X +2706 4552(idea)N +2871(of)X +2969(revealing)X +3299(just)X +3445(enough)X +3711(bits)X +3856(of)X +3953(a)X +4019(hash)X +4196(value)X +4400(to)X +2706 4640(locate)N +2920(a)X +2978(page)X +3151(in)X +3234(a)X +3291(single)X +3503(access.)X +3770(While)X +2 f +3987(dbm/ndbm)X +1 f +4346(and)X +2 f +2706 4728(sdbm)N +1 f +2908(map)X +3079(the)X +3210(hash)X +3390(value)X +3597(directly)X +3874(to)X +3968(a)X +4036(disk)X +4201(address,)X +2 f +2706 4816(gdbm)N +1 f +2921(uses)X +3096(the)X +3231(hash)X +3414(value)X +3624(to)X +3722(index)X +3936(into)X +4096(a)X +2 f +4168(directory)X +1 f +2706 4904([ENB88])N +3020(containing)X +3378(disk)X +3531(addresses.)X +2878 5018(The)N +2 f +3033(hsearch)X +1 f +3317(routines)X +3605(in)X +3697(System)X +3962(V)X +4049(are)X +4177(designed)X +2706 5106(to)N +2804(provide)X +3085(memory-resident)X +3669(hash)X +3852(tables.)X +4115(Since)X +4328(data)X +2706 5194(access)N +2948(does)X +3131(not)X +3269(require)X +3533(disk)X +3702(access,)X +3964(simple)X +4213(hashing)X +2706 5282(schemes)N +3010(which)X +3238(may)X +3408(require)X +3667(multiple)X +3964(probes)X +4209(into)X +4364(the)X +2706 5370(table)N +2889(are)X +3015(used.)X +3209(A)X +3294(more)X +3486(interesting)X +3851(version)X +4114(of)X +2 f +4208(hsearch)X +1 f +2706 5458(is)N +2784(a)X +2845(public)X +3070(domain)X +3335(library,)X +2 f +3594(dynahash)X +1 f +3901(,)X +3945(that)X +4089(implements)X +2706 5546(Larson's)N +3036(in-memory)X +3440(adaptation)X +3822([LAR88])X +4164(of)X +4279(linear)X +2706 5634(hashing)N +2975([LIT80].)X +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +1 f +4424(1)X + +2 p +%%Page: 2 2 +10 s 10 xH 0 xS 1 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +2 f +1074 538(dbm)N +1 f +1232(and)X +2 f +1368(ndbm)X +1 f +604 670(The)N +2 f +760(dbm)X +1 f +928(and)X +2 f +1074(ndbm)X +1 f +1282(library)X +1526(implementations)X +2089(are)X +432 758(based)N +667(on)X +799(the)X +949(same)X +1166(algorithm)X +1529(by)X +1661(Ken)X +1846(Thompson)X +432 846([THOM90,)N +824(TOR88,)X +1113(WAL84],)X +1452(but)X +1582(differ)X +1789(in)X +1879(their)X +2054(pro-)X +432 934(grammatic)N +801(interfaces.)X +1160(The)X +1311(latter)X +1502(is)X +1581(a)X +1643(modi\256ed)X +1952(version)X +432 1022(of)N +533(the)X +665(former)X +918(which)X +1148(adds)X +1328(support)X +1601(for)X +1728(multiple)X +2027(data-)X +432 1110(bases)N +634(to)X +724(be)X +828(open)X +1011(concurrently.)X +1484(The)X +1636(discussion)X +1996(of)X +2090(the)X +432 1198(algorithm)N +774(that)X +925(follows)X +1196(is)X +1280(applicable)X +1640(to)X +1732(both)X +2 f +1904(dbm)X +1 f +2072(and)X +2 f +432 1286(ndbm)N +1 f +610(.)X +604 1400(The)N +760(basic)X +956(structure)X +1268(of)X +2 f +1366(dbm)X +1 f +1535(calls)X +1712(for)X +1836(\256xed-sized)X +432 1488(disk)N +612(blocks)X +868(\(buckets\))X +1214(and)X +1377(an)X +2 f +1499(access)X +1 f +1755(function)X +2068(that)X +432 1576(maps)N +623(a)X +681(key)X +819(to)X +902(a)X +959(bucket.)X +1234(The)X +1380(interface)X +1683(routines)X +1962(use)X +2090(the)X +2 f +432 1664(access)N +1 f +673(function)X +970(to)X +1062(obtain)X +1292(the)X +1420(appropriate)X +1816(bucket)X +2060(in)X +2152(a)X +432 1752(single)N +643(disk)X +796(access.)X +604 1866(Within)N +869(the)X +2 f +1010(access)X +1 f +1263(function,)X +1593(a)X +1672(bit-randomizing)X +432 1954(hash)N +610(function)X +2 f +8 s +877 1929(2)N +1 f +10 s +940 1954(is)N +1024(used)X +1202(to)X +1294(convert)X +1565(a)X +1631(key)X +1777(into)X +1931(a)X +1997(32-bit)X +432 2042(hash)N +605(value.)X +825(Out)X +971(of)X +1064(these)X +1254(32)X +1359(bits,)X +1519(only)X +1686(as)X +1778(many)X +1981(bits)X +2121(as)X +432 2130(necessary)N +773(are)X +900(used)X +1075(to)X +1165(determine)X +1514(the)X +1639(particular)X +1974(bucket)X +432 2218(on)N +533(which)X +750(a)X +807(key)X +944(resides.)X +1228(An)X +1347(in-memory)X +1724(bitmap)X +1967(is)X +2041(used)X +432 2306(to)N +533(determine)X +893(how)X +1070(many)X +1287(bits)X +1441(are)X +1579(required.)X +1905(Each)X +2104(bit)X +432 2394(indicates)N +746(whether)X +1033(its)X +1136(associated)X +1494(bucket)X +1736(has)X +1871(been)X +2051(split)X +432 2482(yet)N +562(\(a)X +657(0)X +728(indicating)X +1079(that)X +1230(the)X +1359(bucket)X +1604(has)X +1742(not)X +1875(yet)X +2004(split\).)X +432 2570(The)N +590(use)X +730(of)X +830(the)X +961(hash)X +1141(function)X +1441(and)X +1590(the)X +1720(bitmap)X +1974(is)X +2059(best)X +432 2658(described)N +769(by)X +878(stepping)X +1177(through)X +1454(database)X +1759(creation)X +2046(with)X +432 2746(multiple)N +718(invocations)X +1107(of)X +1194(a)X +2 f +1250(store)X +1 f +1430(operation.)X +604 2860(Initially,)N +906(the)X +1033(hash)X +1209(table)X +1394(contains)X +1690(a)X +1755(single)X +1974(bucket)X +432 2948(\(bucket)N +711(0\),)X +836(the)X +972(bit)X +1094(map)X +1270(contains)X +1575(a)X +1649(single)X +1878(bit)X +2000(\(bit)X +2148(0)X +432 3036(corresponding)N +913(to)X +997(bucket)X +1233(0\),)X +1342(and)X +1480(0)X +1542(bits)X +1699(of)X +1788(a)X +1846(hash)X +2014(value)X +432 3124(are)N +560(examined)X +901(to)X +992(determine)X +1342(where)X +1568(a)X +1633(key)X +1778(is)X +1860(placed)X +2099(\(in)X +432 3212(bucket)N +670(0\).)X +801(When)X +1017(bucket)X +1255(0)X +1319(is)X +1396(full,)X +1551(its)X +1650(bit)X +1758(in)X +1844(the)X +1966(bitmap)X +432 3300(\(bit)N +564(0\))X +652(is)X +726(set,)X +856(and)X +993(its)X +1089(contents)X +1377(are)X +1497(split)X +1655(between)X +1943(buckets)X +432 3388(0)N +499(and)X +641(1,)X +727(by)X +833(considering)X +1233(the)X +1357(0)X +2 f +7 s +3356(th)Y +10 s +1 f +1480 3388(bit)N +1590(\(the)X +1741(lowest)X +1976(bit)X +2086(not)X +432 3476(previously)N +800(examined\))X +1169(of)X +1266(the)X +1393(hash)X +1569(value)X +1772(for)X +1895(each)X +2072(key)X +432 3564(within)N +668(the)X +798(bucket.)X +1064(Given)X +1292(a)X +1359(well-designed)X +1840(hash)X +2018(func-)X +432 3652(tion,)N +613(approximately)X +1112(half)X +1273(of)X +1376(the)X +1510(keys)X +1693(will)X +1853(have)X +2041(hash)X +432 3740(values)N +666(with)X +837(the)X +964(0)X +2 f +7 s +3708(th)Y +10 s +1 f +1090 3740(bit)N +1203(set.)X +1341(All)X +1471(such)X +1646(keys)X +1821(and)X +1965(associ-)X +432 3828(ated)N +586(data)X +740(are)X +859(moved)X +1097(to)X +1179(bucket)X +1413(1,)X +1493(and)X +1629(the)X +1747(rest)X +1883(remain)X +2126(in)X +432 3916(bucket)N +666(0.)X +604 4030(After)N +804(this)X +949(split,)X +1135(the)X +1262(\256le)X +1393(now)X +1560(contains)X +1856(two)X +2005(buck-)X +432 4118(ets,)N +562(and)X +699(the)X +818(bitmap)X +1061(contains)X +1349(three)X +1530(bits:)X +1687(the)X +1805(0)X +2 f +7 s +4086(th)Y +10 s +1 f +1922 4118(bit)N +2026(is)X +2099(set)X +432 4206(to)N +525(indicate)X +810(a)X +876(bucket)X +1120(0)X +1190(split)X +1357(when)X +1561(no)X +1671(bits)X +1816(of)X +1913(the)X +2041(hash)X +432 4294(value)N +648(are)X +789(considered,)X +1199(and)X +1357(two)X +1519(more)X +1726(unset)X +1937(bits)X +2094(for)X +432 4382(buckets)N +706(0)X +775(and)X +920(1.)X +1029(The)X +1183(placement)X +1542(of)X +1638(an)X +1742(incoming)X +2072(key)X +432 4470(now)N +604(requires)X +897(examination)X +1327(of)X +1428(the)X +1560(0)X +2 f +7 s +4438(th)Y +10 s +1 f +1691 4470(bit)N +1809(of)X +1910(the)X +2041(hash)X +432 4558(value,)N +667(and)X +824(the)X +963(key)X +1119(is)X +1212(placed)X +1462(either)X +1685(in)X +1787(bucket)X +2041(0)X +2121(or)X +432 4646(bucket)N +674(1.)X +782(If)X +864(either)X +1075(bucket)X +1317(0)X +1385(or)X +1480(bucket)X +1722(1)X +1790(\256lls)X +1937(up,)X +2064(it)X +2135(is)X +432 4734(split)N +598(as)X +693(before,)X +947(its)X +1050(bit)X +1162(is)X +1243(set)X +1360(in)X +1450(the)X +1576(bitmap,)X +1846(and)X +1990(a)X +2054(new)X +432 4822(set)N +541(of)X +628(unset)X +817(bits)X +952(are)X +1071(added)X +1283(to)X +1365(the)X +1483(bitmap.)X +604 4936(Each)N +791(time)X +959(we)X +1079(consider)X +1376(a)X +1437(new)X +1596(bit)X +1705(\(bit)X +1841(n\),)X +1953(we)X +2072(add)X +432 5024(2)N +2 f +7 s +4992(n)Y +9 f +509(+)X +1 f +540(1)X +10 s +595 5024(bits)N +737(to)X +826(the)X +951(bitmap)X +1199(and)X +1341(obtain)X +1567(2)X +2 f +7 s +4992(n)Y +9 f +1644(+)X +1 f +1675(1)X +10 s +1729 5024(more)N +1920(address-)X +432 5112(able)N +595(buckets)X +869(in)X +960(the)X +1087(\256le.)X +1258(As)X +1376(a)X +1441(result,)X +1668(the)X +1795(bitmap)X +2045(con-)X +432 5200(tains)N +618(the)X +751(previous)X +1062(2)X +2 f +7 s +5168(n)Y +9 f +1139(+)X +1 f +1170(1)X +2 f +10 s +9 f +5200(-)Y +1 f +1242(1)X +1317(bits)X +1467(\(1)X +2 f +9 f +1534(+)X +1 f +1578(2)X +2 f +9 f +(+)S +1 f +1662(4)X +2 f +9 f +(+)S +1 f +1746(...)X +2 f +9 f +(+)S +1 f +1850(2)X +2 f +7 s +5168(n)Y +10 s +1 f +1931 5200(\))N +1992(which)X +432 5288(trace)N +649(the)X +807(entire)X +2 f +1050(split)X +1247(history)X +1 f +1529(of)X +1656(the)X +1813(addressable)X +16 s +432 5433 MXY +864 0 Dl +2 f +8 s +472 5488(2)N +1 f +9 s +523 5513(This)N +670(bit-randomizing)X +1153(property)X +1416(is)X +1482(important)X +1780(to)X +1854(obtain)X +2052(radi-)X +432 5593(cally)N +599(different)X +874(hash)X +1033(values)X +1244(for)X +1355(nearly)X +1562(identical)X +1836(keys,)X +2012(which)X +432 5673(in)N +506(turn)X +640(avoids)X +846(clustering)X +1148(of)X +1226(such)X +1376(keys)X +1526(in)X +1600(a)X +1650(single)X +1840(bucket.)X +10 s +2418 538(buckets.)N +2590 652(Given)N +2809(a)X +2868(key)X +3007(and)X +3146(the)X +3267(bitmap)X +3512(created)X +3768(by)X +3871(this)X +4009(algo-)X +2418 740(rithm,)N +2638(we)X +2759(\256rst)X +2910(examine)X +3209(bit)X +3320(0)X +3386(of)X +3479(the)X +3603(bitmap)X +3851(\(the)X +4002(bit)X +4112(to)X +2418 828(consult)N +2673(when)X +2871(0)X +2934(bits)X +3072(of)X +3162(the)X +3283(hash)X +3453(value)X +3650(are)X +3772(being)X +3973(exam-)X +2418 916(ined\).)N +2631(If)X +2713(it)X +2785(is)X +2866(set)X +2982(\(indicating)X +3356(that)X +3503(the)X +3628(bucket)X +3869(split\),)X +4080(we)X +2418 1004(begin)N +2617(considering)X +3012(the)X +3131(bits)X +3267(of)X +3355(the)X +3473(32-bit)X +3684(hash)X +3851(value.)X +4085(As)X +2418 1092(bit)N +2525(n)X +2587(is)X +2662(revealed,)X +2977(a)X +3035(mask)X +3226(equal)X +3422(to)X +3506(2)X +2 f +7 s +1060(n)Y +9 f +3583(+)X +1 f +3614(1)X +2 f +10 s +9 f +1092(-)Y +1 f +3686(1)X +3748(will)X +3894(yield)X +4076(the)X +2418 1180(current)N +2675(bucket)X +2918(address.)X +3228(Adding)X +3496(2)X +2 f +7 s +1148(n)Y +9 f +3573(+)X +1 f +3604(1)X +2 f +10 s +9 f +1180(-)Y +1 f +3676(1)X +3744(to)X +3834(the)X +3960(bucket)X +2418 1268(address)N +2701(identi\256es)X +3035(which)X +3272(bit)X +3397(in)X +3500(the)X +3639(bitmap)X +3902(must)X +4098(be)X +2418 1356(checked.)N +2743(We)X +2876(continue)X +3173(revealing)X +3493(bits)X +3628(of)X +3715(the)X +3833(hash)X +4000(value)X +2418 1444(until)N +2591(all)X +2698(set)X +2814(bits)X +2955(in)X +3043(the)X +3167(bitmap)X +3415(are)X +3540(exhausted.)X +3907(The)X +4058(fol-)X +2418 1532(lowing)N +2682(algorithm,)X +3055(a)X +3133(simpli\256cation)X +3614(of)X +3723(the)X +3863(algorithm)X +2418 1620(due)N +2565(to)X +2658(Ken)X +2823(Thompson)X +3196([THOM90,)X +3590(TOR88],)X +3908(uses)X +4076(the)X +2418 1708(hash)N +2625(value)X +2839(and)X +2995(the)X +3133(bitmap)X +3395(to)X +3497(calculate)X +3823(the)X +3960(bucket)X +2418 1796(address)N +2679(as)X +2766(discussed)X +3093(above.)X +0(Courier)xf 0 f +1 f +0 f +8 s +2418 2095(hash)N +2608(=)X +2684 -0.4038(calchash\(key\);)AX +2418 2183(mask)N +2608(=)X +2684(0;)X +2418 2271(while)N +2646 -0.4018(\(isbitset\(\(hash)AX +3254(&)X +3330(mask\))X +3558(+)X +3634(mask\)\))X +2706 2359(mask)N +2896(=)X +2972(\(mask)X +3200(<<)X +3314(1\))X +3428(+)X +3504(1;)X +2418 2447(bucket)N +2684(=)X +2760(hash)X +2950(&)X +3026(mask;)X +2 f +10 s +3211 2812(sdbm)N +1 f +2590 2944(The)N +2 f +2738(sdbm)X +1 f +2930(library)X +3167(is)X +3243(a)X +3302(public-domain)X +3791(clone)X +3987(of)X +4076(the)X +2 f +2418 3032(ndbm)N +1 f +2638(library,)X +2914(developed)X +3286(by)X +3408(Ozan)X +3620(Yigit)X +3826(to)X +3929(provide)X +2 f +2418 3120(ndbm)N +1 f +2596('s)X +2692(functionality)X +3139(under)X +3359(some)X +3565(versions)X +3869(of)X +3973(UNIX)X +2418 3208(that)N +2559(exclude)X +2830(it)X +2894(for)X +3008(licensing)X +3317(reasons)X +3578([YIG89].)X +3895(The)X +4040(pro-)X +2418 3296(grammer)N +2735(interface,)X +3064(and)X +3207(the)X +3332(basic)X +3524(structure)X +3832(of)X +2 f +3926(sdbm)X +1 f +4121(is)X +2418 3384(identical)N +2733(to)X +2 f +2834(ndbm)X +1 f +3051(but)X +3192(internal)X +3476(details)X +3723(of)X +3828(the)X +2 f +3964(access)X +1 f +2418 3472(function,)N +2726(such)X +2894(as)X +2982(the)X +3101(calculation)X +3474(of)X +3561(the)X +3679(bucket)X +3913(address,)X +2418 3560(and)N +2563(the)X +2690(use)X +2825(of)X +2920(different)X +3225(hash)X +3400(functions)X +3726(make)X +3928(the)X +4054(two)X +2418 3648(incompatible)N +2856(at)X +2934(the)X +3052(database)X +3349(level.)X +2590 3762(The)N +2 f +2740(sdbm)X +1 f +2934(library)X +3173(is)X +3251(based)X +3458(on)X +3562(a)X +3622(simpli\256ed)X +3965(imple-)X +2418 3850(mentation)N +2778(of)X +2885(Larson's)X +3206(1978)X +2 f +3406(dynamic)X +3717(hashing)X +1 f +4009(algo-)X +2418 3938(rithm)N +2616(including)X +2943(the)X +2 f +3066(re\256nements)X +3461(and)X +3605(variations)X +1 f +3953(of)X +4044(sec-)X +2418 4026(tion)N +2562(5)X +2622([LAR78].)X +2956(Larson's)X +3257(original)X +3526(algorithm)X +3857(calls)X +4024(for)X +4138(a)X +2418 4114(forest)N +2635(of)X +2736(binary)X +2975(hash)X +3156(trees)X +3341(that)X +3494(are)X +3626(accessed)X +3941(by)X +4054(two)X +2418 4202(hash)N +2586(functions.)X +2925(The)X +3071(\256rst)X +3216(hash)X +3384(function)X +3672(selects)X +3907(a)X +3964(partic-)X +2418 4290(ular)N +2571(tree)X +2720(within)X +2952(the)X +3078(forest.)X +3309(The)X +3462(second)X +3713(hash)X +3887(function,)X +2418 4378(which)N +2659(is)X +2757(required)X +3070(to)X +3177(be)X +3297(a)X +3377(boolean)X +3675(pseudo-random)X +2418 4466(number)N +2687(generator)X +3015(that)X +3159(is)X +3236(seeded)X +3479(by)X +3583(the)X +3705(key,)X +3865(is)X +3942(used)X +4112(to)X +2418 4554(traverse)N +2733(the)X +2890(tree)X +3070(until)X +3275(internal)X +3579(\(split\))X +3829(nodes)X +4075(are)X +2418 4642(exhausted)N +2763(and)X +2903(an)X +3003(external)X +3286(\(non-split\))X +3648(node)X +3827(is)X +3903(reached.)X +2418 4730(The)N +2571(bucket)X +2813(addresses)X +3149(are)X +3276(stored)X +3500(directly)X +3772(in)X +3861(the)X +3986(exter-)X +2418 4818(nal)N +2536(nodes.)X +2590 4932(Larson's)N +2903(re\256nements)X +3309(are)X +3440(based)X +3655(on)X +3767(the)X +3897(observa-)X +2418 5020(tion)N +2570(that)X +2718(the)X +2844(nodes)X +3059(can)X +3199(be)X +3303(represented)X +3702(by)X +3809(a)X +3872(single)X +4090(bit)X +2418 5108(that)N +2569(is)X +2653(set)X +2773(for)X +2898(internal)X +3174(nodes)X +3392(and)X +3539(not)X +3672(set)X +3791(for)X +3915(external)X +2418 5196(nodes,)N +2652(resulting)X +2959(in)X +3048(a)X +3111(radix)X +3303(search)X +3536(trie.)X +3709(Figure)X +3944(1)X +4010(illus-)X +2418 5284(trates)N +2621(this.)X +2804(Nodes)X +3037(A)X +3123(and)X +3267(B)X +3348(are)X +3475(internal)X +3748(\(split\))X +3967(nodes,)X +2418 5372(thus)N +2573(having)X +2813(no)X +2915(bucket)X +3151(addresses)X +3480(associated)X +3831(with)X +3994(them.)X +2418 5460(Instead,)N +2693(the)X +2814(external)X +3096(nodes)X +3306(\(C,)X +3429(D,)X +3530(and)X +3669(E\))X +3768(each)X +3938(need)X +4112(to)X +2418 5548(refer)N +2594(to)X +2679(a)X +2738(bucket)X +2975(address.)X +3279(These)X +3494(bucket)X +3731(addresses)X +4062(can)X +2418 5636(be)N +2529(stored)X +2760(in)X +2857(the)X +2990(trie)X +3132(itself)X +3327(where)X +3559(the)X +3691(subtries)X +3974(would)X +3 f +432 5960(2)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +3 p +%%Page: 3 3 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +720 538(live)N +862(if)X +933(they)X +1092(existed)X +1340([KNU68].)X +1709(For)X +1841(example,)X +2154(if)X +2224(nodes)X +2432(F)X +720 626(and)N +858(G)X +938(were)X +1117(the)X +1237(children)X +1522(of)X +1610(node)X +1787(C,)X +1881(the)X +2000(bucket)X +2235(address)X +720 714(L00)N +886(could)X +1101(reside)X +1330(in)X +1429(the)X +1563(bits)X +1714(that)X +1870(will)X +2030(eventually)X +2400(be)X +720 802(used)N +887(to)X +969(store)X +1145(nodes)X +1352(F)X +1416(and)X +1552(G)X +1630(and)X +1766(all)X +1866(their)X +2033(children.)X +10 f +720 890 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +1894 2247(L1)N +784 1925(A)N +1431(E)X +1106 2247(D)N +1428 1281(C)N +1109 1603(B)N +1884 1930(L01)N +1879 1286(L00)N +1221 1814(1)N +903 2131(1)N +1221 1402(0)N +903 1714(0)N +1 Dt +1397 1821 MXY +-8 -32 Dl +-5 19 Dl +-20 6 Dl +33 7 Dl +-187 -182 Dl +1397 1322 MXY +-33 7 Dl +20 6 Dl +5 19 Dl +8 -32 Dl +-187 182 Dl +1069 1639 MXY +-32 7 Dl +20 6 Dl +5 19 Dl +7 -32 Dl +-186 182 Dl +1374 1891 MXY +185 Dc +1779 2133 MXY +0 161 Dl +322 0 Dl +0 -161 Dl +-322 0 Dl +1811 MY +0 161 Dl +322 0 Dl +0 -161 Dl +-322 0 Dl +1166 MY +0 161 Dl +322 0 Dl +0 -161 Dl +-322 0 Dl +1052 2213 MXY +185 Dc +1569 MY +185 Dc +720 1881 MXY +185 Dc +1779 2213 MXY +-28 -17 Dl +10 17 Dl +-10 18 Dl +28 -18 Dl +-543 0 Dl +1769 1891 MXY +-28 -18 Dl +10 18 Dl +-10 18 Dl +28 -18 Dl +-201 0 Dl +1364 1247 MXY +185 Dc +1769 MX +-28 -18 Dl +10 18 Dl +-10 18 Dl +28 -18 Dl +-201 0 Dl +1064 2143 MXY +-7 -32 Dl +-5 19 Dl +-20 6 Dl +32 7 Dl +-181 -181 Dl +3 Dt +-1 Ds +8 s +720 2482(Figure)N +925(1:)X +1 f +1002(Radix)X +1179(search)X +1365(trie)X +1474(with)X +1612(internal)X +1831(nodes)X +2004(A)X +2074(and)X +2189(B,)X +2271(external)X +720 2570(nodes)N +891(C,)X +972(D,)X +1056(and)X +1170(E,)X +1247(and)X +1361(bucket)X +1553(addresses)X +1819(stored)X +1997(in)X +2069(the)X +2168(unused)X +2370(por-)X +720 2658(tion)N +836(of)X +905(the)X +999(trie.)X +10 s +10 f +720 2922 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 f +892 3124(Further)N +1153(simpli\256cations)X +1647(of)X +1738(the)X +1860(above)X +2076([YIG89])X +2377(are)X +720 3212(possible.)N +1038(Using)X +1265(a)X +1337(single)X +1564(radix)X +1765(trie)X +1908(to)X +2006(avoid)X +2219(the)X +2352(\256rst)X +720 3300(hash)N +904(function,)X +1227(replacing)X +1562(the)X +1696(pseudo-random)X +2231(number)X +720 3388(generator)N +1052(with)X +1222(a)X +1286(well)X +1452(designed,)X +1785(bit-randomizing)X +2329(hash)X +720 3476(function,)N +1053(and)X +1215(using)X +1434(the)X +1578(portion)X +1855(of)X +1967(the)X +2110(hash)X +2302(value)X +720 3564(exposed)N +1021(during)X +1268(the)X +1404(trie)X +1549(traversal)X +1864(as)X +1969(a)X +2042(direct)X +2262(bucket)X +720 3652(address)N +990(results)X +1228(in)X +1319(an)X +2 f +1424(access)X +1 f +1663(function)X +1959(that)X +2108(works)X +2333(very)X +720 3740(similar)N +974(to)X +1068(Thompson's)X +1499(algorithm)X +1841(above.)X +2084(The)X +2240(follow-)X +720 3828(ing)N +847(algorithm)X +1183(uses)X +1346(the)X +1469(hash)X +1641(value)X +1840(to)X +1927(traverse)X +2206(a)X +2266(linear-)X +720 3916(ized)N +874(radix)X +1059(trie)X +2 f +8 s +1166 3891(3)N +1 f +10 s +1218 3916(starting)N +1478(at)X +1556(the)X +1674(0)X +2 f +7 s +3884(th)Y +10 s +1 f +1791 3916(bit.)N +0 f +8 s +720 4215(tbit)N +910(=)X +986(0;)X +1296(/*)X +1410(radix)X +1638(trie)X +1828(index)X +2056(*/)X +720 4303(hbit)N +910(=)X +986(0;)X +1296(/*)X +1410(hash)X +1600(bit)X +1752(index)X +2056(*/)X +720 4391(mask)N +910(=)X +986(0;)X +720 4479(hash)N +910(=)X +986 -0.4038(calchash\(key\);)AX +720 4655(for)N +872(\(mask)X +1100(=)X +1176(0;)X +910 4743 -0.4018(isbitset\(tbit\);)AN +910 4831(mask)N +1100(=)X +1176(\(mask)X +1404(<<)X +1518(1\))X +1632(+)X +1708(1\))X +1008 4919(if)N +1122(\(hash)X +1350(&)X +1426(\(1)X +1540(<<)X +1654 -0.4219(hbit++\)\)\))AX +1160 5007(/*)N +1274(right)X +1502(son)X +1692(*/)X +1160 5095(tbit)N +1350(=)X +1426(2)X +1502(*)X +1578(tbit)X +1768(+)X +1844(2;)X +1008 5183(else)N +1 f +16 s +720 5353 MXY +864 0 Dl +2 f +8 s +760 5408(3)N +1 f +9 s +818 5433(A)N +896(linearized)X +1206(radix)X +1380(trie)X +1502(is)X +1576(merely)X +1802(an)X +1895(array)X +2068(representation)X +720 5513(of)N +800(the)X +908(radix)X +1076(search)X +1280(trie)X +1396(described)X +1692(above.)X +1920(The)X +2052(children)X +2308(of)X +2388(the)X +720 5593(node)N +885(with)X +1038(index)X +1223(i)X +1267(can)X +1391(be)X +1483(found)X +1675(at)X +1751(the)X +1863(nodes)X +2055(indexed)X +2307(2*i+1)X +720 5673(and)N +842(2*i+2.)X +0 f +8 s +3146 538(/*)N +3260(left)X +3450(son)X +3678(*/)X +3146 626(tbit)N +3336(=)X +3412(2)X +3488(*)X +3564(tbit)X +3754(+)X +3830(1;)X +2706 802(bucket)N +2972(=)X +3048(hash)X +3238(&)X +3314(mask;)X +2 f +10 s +3495 1167(gdbm)N +1 f +2878 1299(The)N +3027(gdbm)X +3233(\(GNU)X +3458(data)X +3616(base)X +3783(manager\))X +4111(library)X +4349(is)X +4426(a)X +2706 1387(UNIX)N +2933(database)X +3236(manager)X +3539(written)X +3792(by)X +3897(Philip)X +4112(A.)X +4215(Nelson,)X +2706 1475(and)N +2848(made)X +3048(available)X +3364(as)X +3457(a)X +3518(part)X +3668(of)X +3760(the)X +3883(FSF)X +4040(software)X +4342(dis-)X +2706 1563(tribution.)N +3052(The)X +3207(gdbm)X +3419(library)X +3663(provides)X +3969(the)X +4097(same)X +4292(func-)X +2706 1651(tionality)N +3028(of)X +3151(the)X +2 f +3304(dbm)X +1 f +3442(/)X +2 f +3464(ndbm)X +1 f +3697(libraries)X +4015([NEL90])X +4360(but)X +2706 1739(attempts)N +3018(to)X +3121(avoid)X +3340(some)X +3550(of)X +3658(their)X +3846(shortcomings.)X +4337(The)X +2706 1827(gdbm)N +2918(library)X +3162(allows)X +3401(for)X +3525(arbitrary-length)X +4059(data,)X +4242(and)X +4387(its)X +2706 1915(database)N +3027(is)X +3124(a)X +3203(singular,)X +3524(non-sparse)X +2 f +8 s +3872 1890(4)N +1 f +10 s +3947 1915(\256le.)N +4112(The)X +4280(gdbm)X +2706 2003(library)N +2947(also)X +3103(includes)X +2 f +3396(dbm)X +1 f +3560(and)X +2 f +3702(ndbm)X +1 f +3906(compatible)X +4288(inter-)X +2706 2091(faces.)N +2878 2205(The)N +3025(gdbm)X +3229(library)X +3465(is)X +3540(based)X +3745(on)X +2 f +3847(extensible)X +4189(hashing)X +1 f +4442(,)X +2706 2293(a)N +2766(dynamic)X +3066(hashing)X +3339(algorithm)X +3674(by)X +3778(Fagin)X +3984(et)X +4066(al)X +4148([FAG79].)X +2706 2381(This)N +2881(algorithm)X +3225(differs)X +3467(from)X +3655(the)X +3785(previously)X +4155(discussed)X +2706 2469(algorithms)N +3069(in)X +3152(that)X +3293(it)X +3358(uses)X +3517(a)X +2 f +3574(directory)X +1 f +3889(that)X +4030(is)X +4103(a)X +4159(collapsed)X +2706 2557(representation)N +3192([ENB88])X +3517(of)X +3615(the)X +3744(radix)X +3940(search)X +4177(trie)X +4315(used)X +2706 2645(by)N +2 f +2806(sdbm)X +1 f +2975(.)X +10 f +2706 2733 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +7 s +3572 3761(L1)N +1 Dt +3485 3738 MXY +-20 -13 Dl +7 13 Dl +-7 13 Dl +20 -13 Dl +-400 0 Dl +3180 3027 MXY +136 Dc +2706 3494 MXY +136 Dc +2950 3264 MXY +136 Dc +3738 MY +136 Dc +3485 2968 MXY +0 118 Dl +238 0 Dl +0 -118 Dl +-238 0 Dl +3442 MY +0 119 Dl +238 0 Dl +0 -119 Dl +-238 0 Dl +3679 MY +0 119 Dl +238 0 Dl +0 -119 Dl +-238 0 Dl +3187 3501 MXY +136 Dc +2963 3316 MXY +-24 5 Dl +15 4 Dl +4 15 Dl +5 -24 Dl +-137 134 Dl +3204 3083 MXY +-24 5 Dl +15 4 Dl +3 14 Dl +6 -23 Dl +-137 133 Dl +3204 3450 MXY +-6 -24 Dl +-3 14 Dl +-15 5 Dl +24 5 Dl +-137 -134 Dl +2842 3369(0)N +3075 3139(0)N +2842 3676(1)N +3075 3443(1)N +3562 3054(L00)N +3565 3528(L01)N +4197 2968 MXY +0 118 Dl +237 0 Dl +0 -118 Dl +-237 0 Dl +3205 MY +0 119 Dl +237 0 Dl +0 -119 Dl +-237 0 Dl +3561 MY +0 118 Dl +237 0 Dl +0 -118 Dl +-237 0 Dl +3960 2909 MXY +0 237 Dl +118 0 Dl +0 -237 Dl +-118 0 Dl +3146 MY +0 237 Dl +118 0 Dl +0 -237 Dl +-118 0 Dl +3383 MY +0 237 Dl +118 0 Dl +0 -237 Dl +-118 0 Dl +3620 MY +0 237 Dl +118 0 Dl +0 -237 Dl +-118 0 Dl +4197 3027 MXY +-21 -13 Dl +8 13 Dl +-8 13 Dl +21 -13 Dl +-119 0 Dl +4197 3264 MXY +-21 -13 Dl +8 13 Dl +-8 13 Dl +21 -13 Dl +-119 0 Dl +3501 MY +59 0 Dl +0 89 Dl +4078 3738 MXY +59 0 Dl +0 -88 Dl +4197 3590 MXY +-21 -13 Dl +8 13 Dl +-8 13 Dl +21 -13 Dl +-60 0 Dl +4197 3650 MXY +-21 -13 Dl +8 13 Dl +-8 13 Dl +21 -13 Dl +-60 0 Dl +3991 3050(00)N +3991 3287(01)N +3991 3524(10)N +3991 3761(11)N +4269 3050(L00)N +4269 3287(L01)N +4283 3643(L1)N +3485 3501 MXY +-20 -13 Dl +7 13 Dl +-7 13 Dl +20 -13 Dl +-155 0 Dl +3485 3027 MXY +-20 -13 Dl +7 13 Dl +-7 13 Dl +20 -13 Dl +-163 0 Dl +2967 3687 MXY +-5 -24 Dl +-4 14 Dl +-15 4 Dl +24 6 Dl +-141 -141 Dl +3 Dt +-1 Ds +8 s +2706 4033(Figure)N +2903(2:)X +1 f +2972(A)X +3034(radix)X +3181(search)X +3359(trie)X +3460(and)X +3568(a)X +3612(directory)X +3858(representing)X +4189(the)X +4283(trie.)X +10 s +10 f +2706 4209 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 f +2878 4411(In)N +2968(this)X +3106(algorithm,)X +3460(a)X +3519(directory)X +3832(consists)X +4108(of)X +4198(a)X +4256(search)X +2706 4499(trie)N +2847(of)X +2947(depth)X +2 f +3158(n)X +1 f +3211(,)X +3264(containing)X +3635(2)X +2 f +7 s +4467(n)Y +10 s +1 f +3749 4499(bucket)N +3996(addresses)X +4337(\(i.e.)X +2706 4587(each)N +2897(element)X +3194(of)X +3304(the)X +3445(trie)X +3594(is)X +3689(a)X +3767(bucket)X +4023(address\).)X +4373(To)X +2706 4675(access)N +2935(the)X +3056(hash)X +3226(table,)X +3425(a)X +3483(32-bit)X +3696(hash)X +3865(value)X +4061(is)X +4136(calculated)X +2706 4763(and)N +2 f +2861(n)X +1 f +2953(bits)X +3107(of)X +3213(the)X +3350(value)X +3563(are)X +3701(used)X +3886(to)X +3986(index)X +4202(into)X +4364(the)X +2706 4851(directory)N +3018(to)X +3102(obtain)X +3324(a)X +3382(bucket)X +3618(address.)X +3921(It)X +3992(is)X +4067(important)X +4400(to)X +2706 4939(note)N +2866(that)X +3008(multiple)X +3296(entries)X +3532(of)X +3620(this)X +3756(directory)X +4067(may)X +4226(contain)X +2706 5027(the)N +2833(same)X +3026(bucket)X +3268(address)X +3537(as)X +3632(a)X +3696(result)X +3902(of)X +3997(directory)X +4315(dou-)X +2706 5115(bling)N +2903(during)X +3145(bucket)X +3392(splitting.)X +3706(Figure)X +3948(2)X +4021(illustrates)X +4364(the)X +2706 5203(relationship)N +3126(between)X +3436(a)X +3513(typical)X +3772(\(skewed\))X +4108(search)X +4355(trie)X +2706 5291(and)N +2850(its)X +2953(directory)X +3271(representation.)X +3774(The)X +3927(formation)X +4270(of)X +4364(the)X +2706 5379(directory)N +3016(shown)X +3245(in)X +3327(the)X +3445(\256gure)X +3652(is)X +3725(as)X +3812(follows.)X +16 s +2706 5593 MXY +864 0 Dl +2 f +8 s +2746 5648(4)N +1 f +9 s +2796 5673(It)N +2858(does)X +3008(not)X +3118(contain)X +3348(holes.)X +3 f +10 s +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4424(3)X + +4 p +%%Page: 4 4 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +1 f +604 538(Initially,)N +937(there)X +1158(is)X +1271(one)X +1446(slot)X +1620(in)X +1741(the)X +1898(directory)X +432 626(addressing)N +802(a)X +865(single)X +1083(bucket.)X +1364(The)X +1515(depth)X +1719(of)X +1812(the)X +1936(trie)X +2069(is)X +2148(0)X +432 714(and)N +577(0)X +646(bits)X +790(of)X +886(each)X +1063(hash)X +1239(value)X +1442(are)X +1570(examined)X +1910(to)X +2000(deter-)X +432 802(mine)N +624(in)X +718(which)X +946(bucket)X +1192(to)X +1286(place)X +1488(a)X +1556(key;)X +1726(all)X +1837(keys)X +2015(go)X +2126(in)X +432 890(bucket)N +682(0.)X +797(When)X +1024(this)X +1174(bucket)X +1423(is)X +1511(full,)X +1677(its)X +1787(contents)X +2089(are)X +432 978(divided)N +698(between)X +992(L0)X +1107(and)X +1249(L1)X +1363(as)X +1455(was)X +1605(done)X +1786(in)X +1873(the)X +1996(previ-)X +432 1066(ously)N +664(discussed)X +1030(algorithms.)X +1471(After)X +1700(this)X +1874(split,)X +2090(the)X +432 1154(address)N +710(of)X +814(the)X +948(second)X +1207(bucket)X +1457(must)X +1648(be)X +1760(stored)X +1992(in)X +2090(the)X +432 1242(directory.)N +796(To)X +939(accommodate)X +1438(the)X +1589(new)X +1776(address,)X +2090(the)X +432 1330(directory)N +752(is)X +835(split)X +2 f +8 s +972 1305(5)N +1 f +10 s +1330(,)Y +1054(by)X +1163(doubling)X +1476(it,)X +1569(thus)X +1731(increasing)X +2090(the)X +432 1418(depth)N +630(of)X +717(the)X +835(directory)X +1145(by)X +1245(one.)X +604 1532(After)N +813(this)X +967(split,)X +1163(a)X +1237(single)X +1466(bit)X +1588(of)X +1693(the)X +1829(hash)X +2014(value)X +432 1620(needs)N +663(to)X +773(be)X +896(examined)X +1255(to)X +1364(decide)X +1621(whether)X +1927(the)X +2072(key)X +432 1708(belongs)N +711(to)X +803(L0)X +922(or)X +1019(L1.)X +1158(Once)X +1358(one)X +1504(of)X +1601(these)X +1795(buckets)X +2069(\256lls)X +432 1796(\(L0)N +578(for)X +702(example\),)X +1051(it)X +1125(is)X +1208(split)X +1375(as)X +1472(before,)X +1728(and)X +1873(the)X +2000(direc-)X +432 1884(tory)N +585(is)X +662(split)X +823(again)X +1021(to)X +1107(make)X +1305(room)X +1498(for)X +1615(the)X +1736(address)X +2000(of)X +2090(the)X +432 1972(third)N +618(bucket.)X +927(This)X +1104(splitting)X +1400(causes)X +1645(the)X +1778(addresses)X +2121(of)X +432 2060(the)N +567(non-splitting)X +1012(bucket)X +1263(\(L1\))X +1443(to)X +1541(be)X +1653(duplicated.)X +2063(The)X +432 2148(directory)N +766(now)X +948(has)X +1099(four)X +1277(entries,)X +1555(a)X +1635(depth)X +1857(of)X +1968(2,)X +2072(and)X +432 2236(indexes)N +700(the)X +821(buckets)X +1089(L00,)X +1261(L01)X +1413(and)X +1552(L1,)X +1684(as)X +1774(shown)X +2006(in)X +2090(the)X +432 2324(Figure)N +661(2.)X +604 2438(The)N +756(crucial)X +1002(part)X +1154(of)X +1247(the)X +1371(algorithm)X +1708(is)X +1787(the)X +1911(observa-)X +432 2526(tion)N +580(that)X +724(L1)X +837(is)X +914(addressed)X +1255(twice)X +1453(in)X +1539(the)X +1661(directory.)X +1995(If)X +2073(this)X +432 2614(bucket)N +679(were)X +869(to)X +964(split)X +1134(now,)X +1324(the)X +1454(directory)X +1776(already)X +2045(con-)X +432 2702(tains)N +611(room)X +808(to)X +898(hold)X +1067(the)X +1192(address)X +1460(of)X +1554(the)X +1679(new)X +1840(bucket.)X +2121(In)X +432 2790(general,)N +711(the)X +831(relationship)X +1231(between)X +1521(the)X +1641(directory)X +1953(and)X +2090(the)X +432 2878(number)N +704(of)X +798(bucket)X +1039(addresses)X +1374(contained)X +1713(therein)X +1962(is)X +2041(used)X +432 2966(to)N +517(decide)X +750(when)X +947(to)X +1031(split)X +1190(the)X +1310(directory.)X +1662(Each)X +1845(bucket)X +2081(has)X +432 3054(a)N +505(depth,)X +740(\()X +2 f +767(n)X +7 s +3070(b)Y +10 s +1 f +848 3054(\),)N +932(associated)X +1299(with)X +1478(it)X +1558(and)X +1710(appears)X +1992(in)X +2090(the)X +432 3142(directory)N +744(exactly)X +998(2)X +2 f +7 s +3106(n)Y +9 f +1075(-)X +2 f +1106(n)X +4 s +3110(b)Y +7 s +1 f +10 s +1181 3142(times.)N +1396(When)X +1610(a)X +1668(bucket)X +1904(splits,)X +2113(its)X +432 3230(depth)N +638(increases)X +961(by)X +1069(one.)X +1253(The)X +1406(directory)X +1724(must)X +1907(split)X +2072(any)X +432 3318(time)N +602(a)X +665(bucket's)X +964(depth)X +1169(exceeds)X +1451(the)X +1576(depth)X +1781(of)X +1875(the)X +2000(direc-)X +432 3406(tory.)N +630(The)X +784(following)X +1123(code)X +1303(fragment)X +1621(helps)X +1818(to)X +1908(illustrate)X +432 3494(the)N +554(extendible)X +912(hashing)X +1185(algorithm)X +1520([FAG79])X +1838(for)X +1955(access-)X +432 3582(ing)N +554(individual)X +898(buckets)X +1163(and)X +1299(maintaining)X +1701(the)X +1819(directory.)X +0 f +8 s +432 3881(hash)N +622(=)X +698 -0.4038(calchash\(key\);)AX +432 3969(mask)N +622(=)X +698 -0.4018(maskvec[depth];)AX +432 4145(bucket)N +698(=)X +774 -0.4038(directory[hash)AX +1344(&)X +1420(mask];)X +432 4321(/*)N +546(Key)X +698 -0.4219(Insertion)AX +1078(*/)X +432 4409(if)N +546 -0.4038(\(store\(bucket,)AX +1116(key,)X +1306(data\))X +1534(==)X +1648(FAIL\))X +1876({)X +720 4497(newbl)N +948(=)X +1024 -0.4167(getpage\(\);)AX +720 4585 -0.4000(bucket->depth++;)AN +720 4673 -0.4091(newbl->depth)AN +1214(=)X +1290 -0.4038(bucket->depth;)AX +720 4761(if)N +834 -0.4038(\(bucket->depth)AX +1404(>)X +1480(depth\))X +1746({)X +1008 4849(/*)N +1122(double)X +1388 -0.4219(directory)AX +1768(*/)X +1008 4937(depth++;)N +1 f +16 s +432 5033 MXY +864 0 Dl +2 f +8 s +472 5088(5)N +1 f +9 s +534 5113(This)N +692(decision)X +962(to)X +1048(split)X +1202(the)X +1319(directory)X +1608(is)X +1685(based)X +1878(on)X +1979(a)X +2040(com-)X +432 5193(parison)N +666(of)X +748(the)X +858(depth)X +1040(of)X +1121(the)X +1230(page)X +1387(being)X +1568(split)X +1713(and)X +1838(the)X +1947(depth)X +2128(of)X +432 5273(the)N +543(trie.)X +698(In)X +781(Figure)X +992(2,)X +1069(the)X +1180(depths)X +1390(of)X +1472(both)X +1622(L00)X +1760(and)X +1886(L01)X +2024(are)X +2134(2,)X +432 5353(whereas)N +689(the)X +798(depth)X +979(of)X +1060(L1)X +1161(is)X +1230(1.)X +1323(Therefore,)X +1646(if)X +1710(L1)X +1810(were)X +1970(to)X +2046(split,)X +432 5433(the)N +543(directory)X +826(would)X +1029(not)X +1144(need)X +1303(to)X +1382(split.)X +1565(In)X +1648(reality,)X +1872(a)X +1926(bucket)X +2140(is)X +432 5513(allocated)N +727(for)X +846(the)X +969(directory)X +1264(at)X +1351(the)X +1474(time)X +1637(of)X +1732(\256le)X +1858(creation)X +2124(so)X +432 5593(although)N +707(the)X +818(directory)X +1100(splits)X +1274(logically,)X +1566(physical)X +1828(splits)X +2002(do)X +2096(not)X +432 5673(occur)N +610(until)X +760(the)X +866(\256le)X +976(becomes)X +1246(quite)X +1408(large.)X +0 f +8 s +2994 538 -0.4219(directory)AN +3374(=)X +3450 -0.3971(double\(directory\);)AX +2706 626(})N +2706 714 -0.3958(splitbucket\(bucket,)AN +3466(newbl\))X +2706 802(...)N +2418 890(})N +2 f +10 s +3169 1255(hsearch)N +1 f +2590 1387(Since)N +2 f +2807(hsearch)X +1 f +3100(does)X +3286(not)X +3427(have)X +3617(to)X +3717(translate)X +4027(hash)X +2418 1475(values)N +2659(into)X +2819(disk)X +2988(addresses,)X +3352(it)X +3432(can)X +3579(use)X +3721(much)X +3934(simpler)X +2418 1563(algorithms)N +2808(than)X +2994(those)X +3211(de\256ned)X +3495(above.)X +3775(System)X +4058(V's)X +2 f +2418 1651(hsearch)N +1 f +2708(constructs)X +3069(a)X +3141(\256xed-size)X +3489(hash)X +3671(table)X +3862(\(speci\256ed)X +2418 1739(by)N +2519(the)X +2637(user)X +2791(at)X +2869(table)X +3045(creation\).)X +3391(By)X +3504(default,)X +3767(a)X +3823(multiplica-)X +2418 1827(tive)N +2570(hash)X +2748(function)X +3046(based)X +3260(on)X +3371(that)X +3522(described)X +3861(in)X +3954(Knuth,)X +2418 1915(Volume)N +2710(3,)X +2804(section)X +3065(6.4)X +3199([KNU68])X +3541(is)X +3628(used)X +3809(to)X +3905(obtain)X +4138(a)X +2418 2003(primary)N +2694(bucket)X +2930(address.)X +3233(If)X +3309(this)X +3446(bucket)X +3681(is)X +3755(full,)X +3907(a)X +3964(secon-)X +2418 2091(dary)N +2593(multiplicative)X +3069(hash)X +3248(value)X +3454(is)X +3538(computed)X +3885(to)X +3978(de\256ne)X +2418 2179(the)N +2542(probe)X +2751(interval.)X +3062(The)X +3213(probe)X +3422(interval)X +3693(is)X +3772(added)X +3989(to)X +4076(the)X +2418 2267(original)N +2712(bucket)X +2971(address)X +3257(\(modulo)X +3573(the)X +3716(table)X +3916(size\))X +4112(to)X +2418 2355(obtain)N +2658(a)X +2734(new)X +2908(bucket)X +3162(address.)X +3483(This)X +3665(process)X +3946(repeats)X +2418 2443(until)N +2588(an)X +2688(empty)X +2911(bucket)X +3148(is)X +3224(found.)X +3474(If)X +3551(no)X +3654(bucket)X +3891(is)X +3967(found,)X +2418 2531(an)N +2514(insertion)X +2814(fails)X +2972(with)X +3134(a)X +3190(``table)X +3420(full'')X +3605(condition.)X +2590 2645(The)N +2768(basic)X +2986(algorithm)X +3350(may)X +3541(be)X +3670(modi\256ed)X +4006(by)X +4138(a)X +2418 2733(number)N +2705(of)X +2813(compile)X +3112(time)X +3295(options)X +3571(available)X +3902(to)X +4005(those)X +2418 2821(users)N +2604(with)X +2767(AT&T)X +3006(source)X +3237(code.)X +3450(First,)X +3637(the)X +3756(package)X +4040(pro-)X +2418 2909(vides)N +2638(two)X +2809(options)X +3094(for)X +3238(hash)X +3435(functions.)X +3803(Users)X +4036(may)X +2418 2997(specify)N +2690(their)X +2877(own)X +3055(hash)X +3242(function)X +3549(by)X +3669(compiling)X +4032(with)X +2418 3085(``USCR'')N +2757(de\256ned)X +3016(and)X +3155(declaring)X +3477(and)X +3616(de\256ning)X +3901(the)X +4022(vari-)X +2418 3173(able)N +2 f +2578(hcompar)X +1 f +2863(,)X +2909(a)X +2971(function)X +3263(taking)X +3488(two)X +3633(string)X +3840(arguments)X +2418 3261(and)N +2560(returning)X +2880(an)X +2982(integer.)X +3271(Users)X +3480(may)X +3643(also)X +3797(request)X +4054(that)X +2418 3349(hash)N +2587(values)X +2814(be)X +2912(computed)X +3250(simply)X +3489(by)X +3590(taking)X +3811(the)X +3930(modulo)X +2418 3437(of)N +2521(key)X +2673(\(using)X +2909(division)X +3201(rather)X +3424(than)X +3597(multiplication)X +4080(for)X +2418 3525(hash)N +2589(value)X +2787(calculation\).)X +3230(If)X +3308(this)X +3447(technique)X +3783(is)X +3859(used,)X +4049(col-)X +2418 3613(lisions)N +2651(are)X +2775(resolved)X +3072(by)X +3176(scanning)X +3485(sequentially)X +3896(from)X +4076(the)X +2418 3701(selected)N +2702(bucket)X +2941(\(linear)X +3176(probing\).)X +3517(This)X +3684(option)X +3913(is)X +3991(avail-)X +2418 3789(able)N +2572(by)X +2672(de\256ning)X +2954(the)X +3072(variable)X +3351(``DIV'')X +3622(at)X +3700(compile)X +3978(time.)X +2590 3903(A)N +2720(second)X +3015(option,)X +3311(based)X +3565(on)X +3716(an)X +3863(algorithm)X +2418 3991(discovered)N +2787(by)X +2888(Richard)X +3163(P.)X +3248(Brent,)X +3466(rearranges)X +3822(the)X +3940(table)X +4116(at)X +2418 4079(the)N +2549(time)X +2724(of)X +2824(insertion)X +3137(in)X +3232(order)X +3434(to)X +3528(speed)X +3743(up)X +3855(retrievals.)X +2418 4167(The)N +2571(basic)X +2764(idea)X +2926(is)X +3007(to)X +3097(shorten)X +3361(long)X +3531(probe)X +3741(sequences)X +4094(by)X +2418 4255(lengthening)N +2833(short)X +3030(probe)X +3249(sequences.)X +3651(Once)X +3857(the)X +3991(probe)X +2418 4343(chain)N +2613(has)X +2741(exceeded)X +3062(some)X +3252(threshold)X +3571(\(Brent)X +3796(suggests)X +4087(2\),)X +2418 4431(we)N +2541(attempt)X +2809(to)X +2899(shuf\257e)X +3145(any)X +3289(colliding)X +3601(keys)X +3776(\(keys)X +3978(which)X +2418 4519(appeared)N +2734(in)X +2821(the)X +2944(probe)X +3152(sequence)X +3471(of)X +3562(the)X +3684(new)X +3842(key\).)X +4049(The)X +2418 4607(details)N +2652(of)X +2744(this)X +2884(key)X +3025(shuf\257ing)X +3333(can)X +3469(be)X +3569(found)X +3780(in)X +3866([KNU68])X +2418 4695(and)N +2576([BRE73].)X +2946(This)X +3129(algorithm)X +3481(may)X +3660(be)X +3777(obtained)X +4094(by)X +2418 4783(de\256ning)N +2700(the)X +2818(variable)X +3097(``BRENT'')X +3487(at)X +3565(compile)X +3843(time.)X +2590 4897(A)N +2698(third)X +2899(set)X +3038(of)X +3154(options,)X +3458(obtained)X +3783(by)X +3912(de\256ning)X +2418 4985(``CHAINED'',)N +2943(use)X +3086(linked)X +3321(lists)X +3484(to)X +3581(resolve)X +3848(collisions.)X +2418 5073(Either)N +2647(of)X +2747(the)X +2878(primary)X +3164(hash)X +3343(function)X +3642(described)X +3982(above)X +2418 5161(may)N +2584(be)X +2688(used,)X +2882(but)X +3011(all)X +3118(collisions)X +3451(are)X +3577(resolved)X +3876(by)X +3983(build-)X +2418 5249(ing)N +2554(a)X +2623(linked)X +2856(list)X +2986(of)X +3086(entries)X +3333(from)X +3522(the)X +3653(primary)X +3940(bucket.)X +2418 5337(By)N +2542(default,)X +2816(new)X +2981(entries)X +3226(will)X +3381(be)X +3488(added)X +3711(to)X +3804(a)X +3871(bucket)X +4116(at)X +2418 5425(the)N +2541(beginning)X +2886(of)X +2978(the)X +3101(bucket)X +3339(chain.)X +3577(However,)X +3916(compile)X +2418 5513(options)N +2706(``SORTUP'')X +3173(or)X +3293(``SORTDOWN'')X +3908(may)X +4098(be)X +2418 5601(speci\256ed)N +2723(to)X +2805(order)X +2995(the)X +3113(hash)X +3280(chains)X +3505(within)X +3729(each)X +3897(bucket.)X +3 f +432 5960(4)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +5 p +%%Page: 5 5 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +2 f +1444 538(dynahash)N +1 f +892 670(The)N +2 f +1054(dynahash)X +1 f +1398(library,)X +1669(written)X +1932(by)X +2048(Esmond)X +2346(Pitt,)X +720 758(implements)N +1183(Larson's)X +1554(linear)X +1827(hashing)X +2165(algorithm)X +720 846([LAR88])N +1097(with)X +1302(an)X +2 f +1440(hsearch)X +1 f +1756(compatible)X +2174(interface.)X +720 934(Intuitively,)N +1099(a)X +1161(hash)X +1334(table)X +1516(begins)X +1751(as)X +1844(a)X +1905(single)X +2121(bucket)X +2360(and)X +720 1022(grows)N +941(in)X +1028(generations,)X +1443(where)X +1665(a)X +1725(generation)X +2088(corresponds)X +720 1110(to)N +815(a)X +884(doubling)X +1201(in)X +1296(the)X +1427(size)X +1585(of)X +1685(the)X +1815(hash)X +1994(table.)X +2222(The)X +2379(0)X +2 f +7 s +1078(th)Y +10 s +1 f +720 1198(generation)N +1085(occurs)X +1321(as)X +1414(the)X +1538(table)X +1719(grows)X +1940(from)X +2121(one)X +2262(bucket)X +720 1286(to)N +814(two.)X +1006(In)X +1105(the)X +1235(next)X +1405(generation)X +1776(the)X +1906(table)X +2093(grows)X +2320(from)X +720 1374(two)N +862(to)X +946(four.)X +1122(During)X +1371(each)X +1541(generation,)X +1921(every)X +2121(bucket)X +2356(that)X +720 1462(existed)N +967(at)X +1045(the)X +1163(beginning)X +1503(of)X +1590(the)X +1708(generation)X +2067(is)X +2140(split.)X +892 1576(The)N +1041(table)X +1221(starts)X +1414(as)X +1505(a)X +1565(single)X +1780(bucket)X +2018(\(numbered)X +2389(0\),)X +720 1664(the)N +839(current)X +1088(split)X +1245(bucket)X +1479(is)X +1552(set)X +1661(to)X +1743(bucket)X +1977(0,)X +2057(and)X +2193(the)X +2311(max-)X +720 1752(imum)N +933(split)X +1097(point)X +1288(is)X +1368(set)X +1483(to)X +1571(twice)X +1771(the)X +1895(current)X +2149(split)X +2312(point)X +720 1840(\(0\).)N +863(When)X +1084(it)X +1157(is)X +1239(time)X +1410(for)X +1532(a)X +1596(bucket)X +1838(to)X +1928(split,)X +2113(the)X +2239(keys)X +2414(in)X +720 1928(the)N +872(current)X +1154(split)X +1345(bucket)X +1612(are)X +1764(divided)X +2057(between)X +2378(the)X +720 2016(current)N +981(split)X +1151(bucket)X +1397(and)X +1545(a)X +1613(new)X +1779(bucket)X +2025(whose)X +2262(bucket)X +720 2104(number)N +1000(is)X +1088(equal)X +1297(to)X +1394(1)X +1469(+)X +1549(current)X +1812(split)X +1984(bucket)X +2232(+)X +2311(max-)X +720 2192(imum)N +927(split)X +1085(point.)X +1310(We)X +1442(can)X +1574(determine)X +1915(which)X +2131(keys)X +2298(move)X +720 2280(to)N +807(the)X +929(new)X +1087(bucket)X +1325(by)X +1429(examining)X +1791(the)X +2 f +1913(n)X +7 s +1962 2248(th)N +10 s +1 f +2043 2280(bit)N +2151(of)X +2242(a)X +2302(key's)X +720 2368(hash)N +899(value)X +1105(where)X +1334(n)X +1406(is)X +1491(the)X +1620(generation)X +1990(number.)X +2306(After)X +720 2456(the)N +846(bucket)X +1088(at)X +1174(the)X +1300(maximum)X +1651(split)X +1815(point)X +2006(has)X +2140(been)X +2319(split,)X +720 2544(the)N +839(generation)X +1198(number)X +1463(is)X +1536(incremented,)X +1973(the)X +2091(current)X +2339(split)X +720 2632(point)N +908(is)X +985(set)X +1098(back)X +1274(to)X +1360(zero,)X +1543(and)X +1683(the)X +1805(maximum)X +2152(split)X +2312(point)X +720 2720(is)N +815(set)X +946(to)X +1050(the)X +1190(number)X +1477(of)X +1586(the)X +1725(last)X +1877(bucket)X +2132(in)X +2235(the)X +2374(\256le)X +720 2808(\(which)N +971(is)X +1052(equal)X +1253(to)X +1342(twice)X +1543(the)X +1668(old)X +1797(maximum)X +2148(split)X +2312(point)X +720 2896(plus)N +873(1\).)X +892 3010(To)N +1031(facilitate)X +1361(locating)X +1668(keys,)X +1884(we)X +2027(maintain)X +2356(two)X +720 3098(masks.)N +989(The)X +1143(low)X +1291(mask)X +1488(is)X +1569(equal)X +1771(to)X +1861(the)X +1987(maximum)X +2339(split)X +720 3186(bucket)N +967(and)X +1116(the)X +1247(high)X +1422(mask)X +1624(is)X +1710(equal)X +1917(to)X +2011(the)X +2141(next)X +2311(max-)X +720 3274(imum)N +931(split)X +1093(bucket.)X +1372(To)X +1486(locate)X +1703(a)X +1764(speci\256c)X +2033(key,)X +2193(we)X +2311(com-)X +720 3362(pute)N +881(a)X +940(32-bit)X +1154(hash)X +1324(value)X +1520(using)X +1715(a)X +1773(bit-randomizing)X +2311(algo-)X +720 3450(rithm)N +932(such)X +1118(as)X +1224(the)X +1361(one)X +1516(described)X +1862(in)X +1962([LAR88].)X +2334(This)X +720 3538(hash)N +893(value)X +1093(is)X +1172(then)X +1336(masked)X +1607(with)X +1775(the)X +1898(high)X +2065(mask.)X +2299(If)X +2378(the)X +720 3626(resulting)N +1026(number)X +1297(is)X +1376(greater)X +1626(than)X +1790(the)X +1913(maximum)X +2262(bucket)X +720 3714(in)N +823(the)X +962(table)X +1159(\(current)X +1455(split)X +1633(bucket)X +1888(+)X +1974(maximum)X +2339(split)X +720 3802(point\),)N +962(the)X +1091(hash)X +1269(value)X +1474(is)X +1558(masked)X +1834(with)X +2007(the)X +2136(low)X +2287(mask.)X +720 3890(In)N +825(either)X +1046(case,)X +1242(the)X +1377(result)X +1592(of)X +1696(the)X +1831(mask)X +2037(is)X +2127(the)X +2262(bucket)X +720 3978(number)N +989(for)X +1107(the)X +1229(given)X +1431(key.)X +1611(The)X +1759(algorithm)X +2093(below)X +2312(illus-)X +720 4066(trates)N +914(this)X +1049(process.)X +0 f +8 s +720 4365(h)N +796(=)X +872 -0.4038(calchash\(key\);)AX +720 4453(bucket)N +986(=)X +1062(h)X +1138(&)X +1214 -0.4167(high_mask;)AX +720 4541(if)N +834(\()X +910(bucket)X +1176(>)X +1252 -0.4167(max_bucket)AX +1670(\))X +1008 4629(bucket)N +1274(=)X +1350(h)X +1426(&)X +1502 -0.4219(low_mask;)AX +720 4717 -0.4018(return\(bucket\);)AN +1 f +10 s +892 5042(In)N +1013(order)X +1237(to)X +1353(decide)X +1617(when)X +1845(to)X +1961(split)X +2152(a)X +2242(bucket,)X +2 f +720 5130(dynahash)N +1 f +1050(uses)X +2 f +1210(controlled)X +1561(splitting)X +1 f +1822(.)X +1884(A)X +1964(hash)X +2133(table)X +2311(has)X +2440(a)X +720 5218(\256ll)N +837(factor)X +1054(which)X +1279(is)X +1361(expressed)X +1707(in)X +1798(terms)X +2004(of)X +2099(the)X +2225(average)X +720 5306(number)N +990(of)X +1082(keys)X +1253(in)X +1339(each)X +1511(bucket.)X +1789(Each)X +1974(time)X +2140(the)X +2262(table's)X +720 5394(total)N +885(number)X +1153(of)X +1243(keys)X +1413(divided)X +1676(by)X +1778(its)X +1875(number)X +2142(of)X +2231(buckets)X +720 5482(exceeds)N +995(this)X +1130(\256ll)X +1238(factor,)X +1466(a)X +1522(bucket)X +1756(is)X +1829(split.)X +2878 538(Since)N +3079(the)X +2 f +3200(hsearch)X +1 f +3477(create)X +3693(interface)X +3998(\()X +2 f +4025(hcreate)X +1 f +4266(\))X +4315(calls)X +2706 626(for)N +2842(an)X +2960(estimate)X +3269(of)X +3378(the)X +3518(\256nal)X +3702(size)X +3869(of)X +3978(the)X +4118(hash)X +4306(table)X +2706 714(\()N +2 f +2733(nelem)X +1 f +2925(\),)X +2 f +3007(dynahash)X +1 f +3349(uses)X +3522(this)X +3672(information)X +4085(to)X +4182(initialize)X +2706 802(the)N +2848(table.)X +3088(The)X +3257(initial)X +3486(number)X +3774(of)X +3884(buckets)X +4172(is)X +4268(set)X +4400(to)X +2 f +2706 890(nelem)N +1 f +2926(rounded)X +3217(to)X +3306(the)X +3431(next)X +3596(higher)X +3828(power)X +4056(of)X +4150(two.)X +4337(The)X +2706 978(current)N +2958(split)X +3118(point)X +3305(is)X +3381(set)X +3493(to)X +3578(0)X +3641(and)X +3780(the)X +3901(maximum)X +4248(bucket)X +2706 1066(and)N +2842(maximum)X +3186(split)X +3343(point)X +3527(are)X +3646(set)X +3755(to)X +3837(this)X +3972(rounded)X +4255(value.)X +3 f +3148 1220(The)N +3301(New)X +3473(Implementation)X +1 f +2878 1352(Our)N +3042(implementation)X +3583(is)X +3675(also)X +3842(based)X +4063(on)X +4181(Larson's)X +2706 1440(linear)N +2939(hashing)X +3238([LAR88])X +3582(algorithm)X +3943(as)X +4060(well)X +4248(as)X +4364(the)X +2 f +2706 1528(dynahash)N +1 f +3047(implementation.)X +3623(The)X +2 f +3782(dbm)X +1 f +3954(family)X +4197(of)X +4297(algo-)X +2706 1616(rithms)N +2942(decide)X +3184(dynamically)X +3612(which)X +3840(bucket)X +4085(to)X +4178(split)X +4346(and)X +2706 1704(when)N +2914(to)X +3010(split)X +3180(it)X +3257(\(when)X +3491(it)X +3568(over\257ows\))X +3944(while)X +2 f +4155(dynahash)X +1 f +2706 1792(splits)N +2933(in)X +3054(a)X +3149(prede\256ned)X +3547(order)X +3776(\(linearly\))X +4134(and)X +4309(at)X +4426(a)X +2706 1880(prede\256ned)N +3116(time)X +3328(\(when)X +3599(the)X +3767(table)X +3993(\256ll)X +4151(factor)X +4409(is)X +2706 1968(exceeded\).)N +3121(We)X +3280(use)X +3434(a)X +3517(hybrid)X +3773(of)X +3887(these)X +4099(techniques.)X +2706 2056(Splits)N +2913(occur)X +3118(in)X +3206(the)X +3330(prede\256ned)X +3695(order)X +3891(of)X +3984(linear)X +4193(hashing,)X +2706 2144(but)N +2845(the)X +2980(time)X +3159(at)X +3253(which)X +3485(pages)X +3704(are)X +3839(split)X +4012(is)X +4101(determined)X +2706 2232(both)N +2869(by)X +2970(page)X +3143(over\257ows)X +3480(\()X +2 f +3507(uncontrolled)X +3937(splitting)X +1 f +4198(\))X +4246(and)X +4382(by)X +2706 2320(exceeding)N +3052(the)X +3170(\256ll)X +3278(factor)X +3486(\()X +2 f +3513(controlled)X +3862(splitting)X +1 f +4123(\))X +2878 2434(A)N +2962(hash)X +3135(table)X +3317(is)X +3395(parameterized)X +3876(by)X +3981(both)X +4148(its)X +4248(bucket)X +2706 2522(size)N +2904(\()X +2 f +2931(bsize)X +1 f +(\))S +3191(and)X +3380(\256ll)X +3541(factor)X +3801(\()X +2 f +3828(ffactor)X +1 f +4041(\).)X +4180(Whereas)X +2 f +2706 2610(dynahash's)N +1 f +3095(buckets)X +3364(can)X +3500(be)X +3599(represented)X +3993(as)X +4083(a)X +4142(linked)X +4365(list)X +2706 2698(of)N +2798(elements)X +3108(in)X +3195(memory,)X +3507(our)X +3639(package)X +3928(needs)X +4136(to)X +4222(support)X +2706 2786(disk)N +2874(access,)X +3135(and)X +3286(must)X +3476(represent)X +3806(buckets)X +4086(in)X +4183(terms)X +4395(of)X +2706 2874(pages.)N +2955(The)X +2 f +3106(bsize)X +1 f +3291(is)X +3369(the)X +3492(size)X +3642(\(in)X +3756(bytes\))X +3977(of)X +4069(these)X +4259(pages.)X +2706 2962(As)N +2833(in)X +2933(linear)X +3154(hashing,)X +3461(the)X +3597(number)X +3879(of)X +3983(buckets)X +4265(in)X +4364(the)X +2706 3050(table)N +2906(is)X +3003(equal)X +3221(to)X +3327(the)X +3469(number)X +3758(of)X +3869(keys)X +4060(in)X +4165(the)X +4306(table)X +2706 3138(divided)N +2988(by)X +2 f +3110(ffactor)X +1 f +3323(.)X +2 f +8 s +3113(6)Y +1 f +10 s +3417 3138(The)N +3584(controlled)X +3950(splitting)X +4252(occurs)X +2706 3226(each)N +2878(time)X +3044(the)X +3166(number)X +3435(of)X +3526(keys)X +3697(in)X +3783(the)X +3905(table)X +4085(exceeds)X +4364(the)X +2706 3314(\256ll)N +2814(factor)X +3022(multiplied)X +3370(by)X +3470(the)X +3588(number)X +3853(of)X +3940(buckets.)X +2878 3428(Inserting)N +3187(keys)X +3358(and)X +3498(splitting)X +3783(buckets)X +4051(is)X +4127(performed)X +2706 3516(precisely)N +3018(as)X +3107(described)X +3437(previously)X +3796(for)X +2 f +3911(dynahash)X +1 f +4218(.)X +4279(How-)X +2706 3604(ever,)N +2897(since)X +3094(buckets)X +3371(are)X +3502(now)X +3671(comprised)X +4036(of)X +4134(pages,)X +4368(we)X +2706 3692(must)N +2883(be)X +2981(prepared)X +3284(to)X +3367(handle)X +3602(cases)X +3793(where)X +4011(the)X +4130(size)X +4276(of)X +4364(the)X +2706 3780(keys)N +2873(and)X +3009(data)X +3163(in)X +3245(a)X +3301(bucket)X +3535(exceed)X +3779(the)X +3897(bucket)X +4131(size.)X +3 f +3318 3934(Over\257ow)N +3654(Pages)X +1 f +2878 4066(There)N +3095(are)X +3223(two)X +3372(cases)X +3571(where)X +3797(a)X +3862(key)X +4007(may)X +4174(not)X +4305(\256t)X +4400(in)X +2706 4154(its)N +2802(designated)X +3166(bucket.)X +3441(In)X +3529(the)X +3647(\256rst)X +3791(case,)X +3970(the)X +4088(total)X +4250(size)X +4395(of)X +2706 4242(the)N +2833(key)X +2978(and)X +3123(data)X +3286(may)X +3453(exceed)X +3706(the)X +3833(bucket)X +4076(size.)X +4269(In)X +4364(the)X +2706 4330(second,)N +3008(addition)X +3328(of)X +3453(a)X +3547(new)X +3739(key)X +3913(could)X +4149(cause)X +4386(an)X +2706 4418(over\257ow,)N +3068(but)X +3227(the)X +3382(bucket)X +3652(in)X +3770(question)X +4097(is)X +4206(not)X +4364(yet)X +2706 4506(scheduled)N +3049(to)X +3133(be)X +3230(split.)X +3428(In)X +3516(existing)X +3790(implementations,)X +4364(the)X +2706 4594(second)N +2953(case)X +3115(never)X +3317(arises)X +3523(\(since)X +3738(buckets)X +4006(are)X +4128(split)X +4288(when)X +2706 4682(they)N +2871(over\257ow\))X +3210(and)X +3352(the)X +3476(\256rst)X +3626(case)X +3791(is)X +3870(not)X +3998(handled)X +4278(at)X +4362(all.)X +2706 4770(Although)N +3036(large)X +3225(key/data)X +3525(pair)X +3678(handling)X +3986(is)X +4066(dif\256cult)X +4346(and)X +2706 4858(expensive,)N +3083(it)X +3163(is)X +3252(essential.)X +3604(In)X +3706(a)X +3777(linear)X +3995(hashed)X +4253(imple-)X +2706 4946(mentation,)N +3087(over\257ow)X +3413(pages)X +3636(are)X +3775(required)X +4083(for)X +4217(buckets)X +2706 5034(which)N +2935(over\257ow)X +3253(before)X +3492(they)X +3662(are)X +3793(split,)X +3982(so)X +4085(we)X +4211(can)X +4355(use)X +2706 5122(the)N +2833(same)X +3027(mechanism)X +3421(for)X +3544(large)X +3734(key/data)X +4035(pairs)X +4220(that)X +4368(we)X +2706 5210(use)N +2837(for)X +2955(over\257ow)X +3264(pages.)X +3511(Logically,)X +3862(we)X +3980(chain)X +4177(over\257ow)X +16 s +2706 5353 MXY +864 0 Dl +2 f +8 s +2746 5408(6)N +1 f +9 s +2801 5433(This)N +2952(is)X +3023(not)X +3138(strictly)X +3361(true.)X +3532(The)X +3667(\256le)X +3782(does)X +3937(not)X +4052(contract)X +4306(when)X +2706 5513(keys)N +2861(are)X +2972(deleted,)X +3221(so)X +3308(the)X +3419(number)X +3662(of)X +3744(buckets)X +3986(is)X +4056(actually)X +4306(equal)X +2706 5593(to)N +2782(the)X +2890(maximum)X +3202(number)X +3441(of)X +3520(keys)X +3671(ever)X +3814(present)X +4041(in)X +4116(the)X +4223(table)X +4382(di-)X +2706 5673(vided)N +2884(by)X +2974(the)X +3080(\256ll)X +3178(factor.)X +3 f +10 s +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4424(5)X + +6 p +%%Page: 6 6 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +1 f +432 538(pages)N +639(to)X +725(the)X +847(buckets)X +1116(\(also)X +1296(called)X +1512(primary)X +1789(pages\).)X +2062(In)X +2152(a)X +432 626(memory)N +730(based)X +943(representation,)X +1448(over\257ow)X +1763(pages)X +1976(do)X +2086(not)X +432 714(pose)N +628(any)X +792(special)X +1063(problems)X +1409(because)X +1712(we)X +1854(can)X +2014(chain)X +432 802(over\257ow)N +776(pages)X +1017(to)X +1137(primary)X +1449(pages)X +1690(using)X +1921(memory)X +432 890(pointers.)N +776(However,)X +1137(mapping)X +1463(these)X +1674(over\257ow)X +2005(pages)X +432 978(into)N +584(a)X +648(disk)X +809(\256le)X +939(is)X +1019(more)X +1211(of)X +1305(a)X +1368(challenge,)X +1723(since)X +1915(we)X +2036(need)X +432 1066(to)N +547(be)X +675(able)X +861(to)X +975(address)X +1268(both)X +1462(bucket)X +1728(pages,)X +1983(whose)X +432 1154(numbers)N +729(are)X +849(growing)X +1137(linearly,)X +1422(and)X +1558(some)X +1747(indeterminate)X +432 1242(number)N +715(of)X +820(over\257ow)X +1143(pages)X +1364(without)X +1646(reorganizing)X +2090(the)X +432 1330(\256le.)N +604 1444(One)N +789(simple)X +1053(solution)X +1361(would)X +1612(be)X +1739(to)X +1852(allocate)X +2152(a)X +432 1532(separate)N +737(\256le)X +880(for)X +1015(over\257ow)X +1341(pages.)X +1604(The)X +1769(disadvantage)X +432 1620(with)N +605(such)X +783(a)X +850(technique)X +1193(is)X +1276(that)X +1426(it)X +1500(requires)X +1789(an)X +1895(extra)X +2086(\256le)X +432 1708(descriptor,)N +794(an)X +891(extra)X +1073(system)X +1316(call)X +1453(on)X +1554(open)X +1731(and)X +1867(close,)X +2072(and)X +432 1796(logically)N +739(associating)X +1122(two)X +1269(independent)X +1687(\256les.)X +1886(For)X +2023(these)X +432 1884(reasons,)N +728(we)X +857(wanted)X +1123(to)X +1219(map)X +1391(both)X +1567(primary)X +1855(pages)X +2072(and)X +432 1972(over\257ow)N +737(pages)X +940(into)X +1084(the)X +1202(same)X +1387(\256le)X +1509(space.)X +604 2086(The)N +799(buddy-in-waiting)X +1425(algorithm)X +1806(provides)X +2152(a)X +432 2174(mechanism)N +851(to)X +966(support)X +1259(multiple)X +1578(pages)X +1814(per)X +1970(logical)X +432 2262(bucket)N +685(while)X +902(retaining)X +1226(the)X +1362(simple)X +1613(split)X +1788(sequence)X +2121(of)X +432 2350(linear)N +681(hashing.)X +1015(Over\257ow)X +1383(pages)X +1631(are)X +1795(preallocated)X +432 2438(between)N +781(generations)X +1232(of)X +1379(primary)X +1713(pages.)X +1996(These)X +432 2526(over\257ow)N +759(pages)X +984(are)X +1125(used)X +1314(by)X +1436(any)X +1594(bucket)X +1850(containing)X +432 2614(more)N +646(keys)X +842(than)X +1029(\256t)X +1144(on)X +1273(the)X +1420(primary)X +1723(page)X +1924(and)X +2089(are)X +432 2702(reclaimed,)N +808(if)X +896(possible,)X +1217(when)X +1430(the)X +1567(bucket)X +1819(later)X +2000(splits.)X +432 2790(Figure)N +687(3)X +773(depicts)X +1045(the)X +1188(layout)X +1433(of)X +1545(primary)X +1844(pages)X +2072(and)X +432 2878(over\257ow)N +752(pages)X +970(within)X +1209(the)X +1342(same)X +1542(\256le.)X +1699(Over\257ow)X +2036(page)X +432 2966(use)N +586(information)X +1011(is)X +1111(recorded)X +1440(in)X +1548(bitmaps)X +1847(which)X +2089(are)X +432 3054(themselves)N +819(stored)X +1046(on)X +1157(over\257ow)X +1472(pages.)X +1725(The)X +1880(addresses)X +432 3142(of)N +520(the)X +639(bitmap)X +882(pages)X +1086(and)X +1223(the)X +1342(number)X +1608(of)X +1695(pages)X +1898(allocated)X +432 3230(at)N +515(each)X +688(split)X +850(point)X +1039(are)X +1163(stored)X +1384(in)X +1470(the)X +1592(\256le)X +1718(header.)X +1997(Using)X +432 3318(this)N +577(information,)X +1005(both)X +1177(over\257ow)X +1492(addresses)X +1829(and)X +1974(bucket)X +432 3406(addresses)N +764(can)X +900(be)X +999(mapped)X +1276(to)X +1361(disk)X +1517(addresses)X +1848(by)X +1951(the)X +2072(fol-)X +432 3494(lowing)N +674(calculation:)X +0 f +8 s +432 3793(int)N +736(bucket;)X +1192(/*)X +1306(bucket)X +1572(address)X +1876(*/)X +432 3881(u_short)N +736(oaddr;)X +1192(/*)X +1306(OVERFLOW)X +1648(address)X +1952(*/)X +432 3969(int)N +736 -0.4125(nhdr_pages;)AX +1192(/*)X +1306(npages)X +1572(in)X +1686 -112.4062(\256le)AX +1838(header)X +2104(*/)X +432 4057(int)N +736 -0.4125(spares[32];)AX +1192(/*)X +1306(npages)X +1572(at)X +1686(each)X +1876(split)X +2104(*/)X +432 4145(int)N +736(log2\(\);)X +1198(/*)X +1312(ceil\(log)X +1654(base)X +1844(2\))X +1958(*/)X +432 4321(#DEFINE)N +736 -0.3929(BUCKET_TO_PAGE\(bucket\))AX +1610(\\)X +584 4409(bucket)N +850(+)X +926 -0.4167(nhdr_pages)AX +1344(+)X +1420(\\)X +584 4497 -0.3894(\(bucket?spares[logs2\(bucket)AN +1648(+)X +1724(1\)-1]:0\))X +432 4673(#DEFINE)N +736 -0.3947(OADDR_TO_PAGE\(oaddr\))AX +1534(\\)X +584 4761 -0.3984(BUCKET_TO_PAGE\(\(1)AN +1268(<<)X +1382 -0.4091(\(oaddr>>11\)\))AX +1876(-)X +1952(1\))X +2066(+)X +2142(\\)X +584 4849(oaddr)N +812(&)X +888(0x7ff;)X +1 f +10 s +604 5262(An)N +728(over\257ow)X +1039(page)X +1217(is)X +1295(addressed)X +1637(by)X +1742(its)X +1842(split)X +2004(point,)X +432 5350(identifying)N +858(the)X +1031(generations)X +1476(between)X +1819(which)X +2090(the)X +432 5438(over\257ow)N +740(page)X +915(is)X +991(allocated,)X +1324(and)X +1463(its)X +1561(page)X +1736(number,)X +2023(iden-)X +432 5526(tifying)N +665(the)X +783(particular)X +1111(page)X +1283(within)X +1507(the)X +1625(split)X +1782(point.)X +1986(In)X +2073(this)X +432 5614(implementation,)N +983(offsets)X +1225(within)X +1457(pages)X +1668(are)X +1795(16)X +1903(bits)X +2046(long)X +432 5702(\(limiting)N +732(the)X +851(maximum)X +1196(page)X +1368(size)X +1513(to)X +1595(32K\),)X +1800(so)X +1891(we)X +2005(select)X +2418 538(an)N +2535(over\257ow)X +2860(page)X +3052(addressing)X +3435(algorithm)X +3786(that)X +3946(can)X +4098(be)X +2418 626(expressed)N +2760(in)X +2847(16)X +2952(bits)X +3091(and)X +3231(which)X +3451(allows)X +3684(quick)X +3886(retrieval.)X +2418 714(The)N +2568(top)X +2695(\256ve)X +2840(bits)X +2980(indicate)X +3258(the)X +3380(split)X +3541(point)X +3729(and)X +3869(the)X +3991(lower)X +2418 802(eleven)N +2650(indicate)X +2926(the)X +3046(page)X +3220(number)X +3487(within)X +3713(the)X +3832(split)X +3990(point.)X +2418 890(Since)N +2633(\256ve)X +2789(bits)X +2940(are)X +3075(reserved)X +3384(for)X +3514(the)X +3648(split)X +3821(point,)X +4041(\256les)X +2418 978(may)N +2578(split)X +2737(32)X +2839(times)X +3034(yielding)X +3318(a)X +3376(maximum)X +3721(\256le)X +3844(size)X +3990(of)X +4078(2)X +7 s +946(32)Y +10 s +2418 1066(buckets)N +2698(and)X +2849(32)X +2 f +(*)S +1 f +2982(2)X +7 s +1034(11)Y +10 s +3113 1066(over\257ow)N +3433(pages.)X +3691(The)X +3850(maximum)X +2418 1154(page)N +2597(size)X +2749(is)X +2829(2)X +7 s +1122(15)Y +10 s +1154(,)Y +2971(yielding)X +3259(a)X +3321(maximum)X +3671(\256le)X +3799(size)X +3950(greater)X +2418 1242(than)N +2601(131,000)X +2906(GB)X +3061(\(on)X +3212(\256le)X +3358(systems)X +3655(supporting)X +4041(\256les)X +2418 1330(larger)N +2626(than)X +2784(4GB\).)X +10 f +2418 1418 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 Dt +4014 2275 MXY +0 133 Dl +3881 2275 MXY +0 133 Dl +3748 2275 MXY +0 133 Dl +3083 2275 MXY +0 133 Dl +5 s +1 f +3523 2475(2/3)N +3390(2/2)X +3257(2/1)X +2859(1/2)X +2726(1/1)X +5 Dt +3814 1743 MXY +0 133 Dl +3282 1743 MXY +0 133 Dl +3017 1743 MXY +0 133 Dl +2884 1743 MXY +0 133 Dl +1 Dt +3681 1743 MXY +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3548 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3415 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3282 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3150 MX +0 133 Dl +132 0 Dl +0 -133 Dl +-132 0 Dl +3017 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +2884 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3 f +8 s +3017 2601(Over\257ow)N +3285(Addresses)X +3515 2833(Over\257ow)N +3783(Pages)X +2850(Buckets)X +1 Di +3349 2740 MXY + 3349 2740 lineto + 3482 2740 lineto + 3482 2873 lineto + 3349 2873 lineto + 3349 2740 lineto +closepath 3 3349 2740 3482 2873 Dp +2684 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +5 Dt +4146 2275 MXY +0 133 Dl +3216 2275 MXY +0 133 Dl +2684 2275 MXY +0 133 Dl +2551 2275 MXY +0 133 Dl +1 f +3798 1963(3)N +3266 1980(2)N +3001(1)X +2868(0)X +1 Dt +2751 1743 MXY +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3548 2275 MXY +-15 -22 Dl +2 16 Dl +-13 11 Dl +26 -5 Dl +-282 -117 Dl +3432 2275 MXY +-10 -25 Dl +-2 16 Dl +-15 8 Dl +27 1 Dl +-166 -117 Dl +3282 2275 MXY +12 -25 Dl +-14 10 Dl +-15 -6 Dl +17 21 Dl +-16 -117 Dl +2884 2275 MXY +26 7 Dl +-12 -12 Dl +3 -16 Dl +-17 21 Dl +382 -117 Dl +2751 2275 MXY +25 9 Dl +-11 -12 Dl +5 -17 Dl +-19 20 Dl +515 -117 Dl +3 f +3070 2152(Over\257ow)N +3338(Pages)X +3482 2275 MXY + 3482 2275 lineto + 3615 2275 lineto + 3615 2408 lineto + 3482 2408 lineto + 3482 2275 lineto +closepath 3 3482 2275 3615 2408 Dp +3349 MX + 3349 2275 lineto + 3482 2275 lineto + 3482 2408 lineto + 3349 2408 lineto + 3349 2275 lineto +closepath 3 3349 2275 3482 2408 Dp +3216 MX + 3216 2275 lineto + 3349 2275 lineto + 3349 2408 lineto + 3216 2408 lineto + 3216 2275 lineto +closepath 3 3216 2275 3349 2408 Dp +2817 MX + 2817 2275 lineto + 2950 2275 lineto + 2950 2408 lineto + 2817 2408 lineto + 2817 2275 lineto +closepath 3 2817 2275 2950 2408 Dp +2684 MX + 2684 2275 lineto + 2817 2275 lineto + 2817 2408 lineto + 2684 2408 lineto + 2684 2275 lineto +closepath 3 2684 2275 2817 2408 Dp +3615 MX +0 133 Dl +531 0 Dl +0 -133 Dl +-531 0 Dl +2950 MX +0 133 Dl +266 0 Dl +0 -133 Dl +-266 0 Dl +2551 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3798 1726 MXY +-21 -18 Dl +6 16 Dl +-10 13 Dl +25 -11 Dl +-599 -99 Dl +3266 1726 MXY +-1 -27 Dl +-7 15 Dl +-17 1 Dl +25 11 Dl +-67 -99 Dl +3033 1726 MXY +27 1 Dl +-14 -8 Dl +-1 -17 Dl +-12 24 Dl +166 -99 Dl +2900 1726 MXY +27 7 Dl +-13 -11 Dl +3 -17 Dl +-17 21 Dl +299 -99 Dl +3058 1621(Split)N +3203(Points)X +2418 2275 MXY +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3 Dt +-1 Ds +3137(Figure)Y +2619(3:)X +1 f +2691(Split)X +2832(points)X +3008(occur)X +3168(between)X +3399(generations)X +3712(and)X +3823(are)X +3919(numbered)X +2418 3225(from)N +2560(0.)X +2642(In)X +2713(this)X +2824(\256gure)X +2991(there)X +3136(are)X +3231(two)X +3345(over\257ow)X +3590(pages)X +3753(allocated)X +4000(at)X +4063(split)X +2418 3313(point)N +2566(1)X +2614(and)X +2722(three)X +2865(allocated)X +3111(at)X +3173(split)X +3300(point)X +3448(2.)X +10 s +10 f +2418 3489 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +2949 3731(Buffer)N +3192(Management)X +1 f +2590 3863(The)N +2744(hash)X +2920(table)X +3105(is)X +3187(stored)X +3412(in)X +3502(memory)X +3797(as)X +3892(a)X +3956(logical)X +2418 3951(array)N +2633(of)X +2749(bucket)X +3012(pointers.)X +3359(Physically,)X +3761(the)X +3907(array)X +4121(is)X +2418 4039(arranged)N +2728(in)X +2818(segments)X +3144(of)X +3239(256)X +3387(pointers.)X +3713(Initially,)X +4013(there)X +2418 4127(is)N +2530(space)X +2767(to)X +2887(allocate)X +3195(256)X +3373(segments.)X +3769(Reallocation)X +2418 4215(occurs)N +2651(when)X +2847(the)X +2967(number)X +3234(of)X +3323(buckets)X +3590(exceeds)X +3867(32K)X +4027(\(256)X +2418 4303(*)N +2508(256\).)X +2745(Primary)X +3053(pages)X +3286(may)X +3473(be)X +3598(accessed)X +3929(directly)X +2418 4391(through)N +2711(the)X +2853(array)X +3062(by)X +3185(bucket)X +3442(number)X +3730(and)X +3889(over\257ow)X +2418 4479(pages)N +2628(are)X +2754 0.4028(referenced)AX +3122(logically)X +3429(by)X +3536(their)X +3710(over\257ow)X +4022(page)X +2418 4567(address.)N +2726(For)X +2864(small)X +3063(hash)X +3236(tables,)X +3469(it)X +3539(is)X +3618(desirable)X +3934(to)X +4022(keep)X +2418 4655(all)N +2525(pages)X +2735(in)X +2823(main)X +3009(memory)X +3302(while)X +3506(on)X +3612(larger)X +3826(tables,)X +4059(this)X +2418 4743(is)N +2523(probably)X +2860(impossible.)X +3298(To)X +3438(satisfy)X +3698(both)X +3891(of)X +4009(these)X +2418 4831(requirements,)N +2900(the)X +3041(package)X +3348(includes)X +3658(buffer)X +3897(manage-)X +2418 4919(ment)N +2598(with)X +2760(LRU)X +2940(\(least)X +3134(recently)X +3413(used\))X +3607(replacement.)X +2590 5033(By)N +2730(default,)X +3020(the)X +3165(package)X +3475(allocates)X +3802(up)X +3928(to)X +4036(64K)X +2418 5121(bytes)N +2616(of)X +2712(buffered)X +3014(pages.)X +3246(All)X +3377(pages)X +3589(in)X +3680(the)X +3807(buffer)X +4032(pool)X +2418 5209(are)N +2542(linked)X +2766(in)X +2852(LRU)X +3036(order)X +3230(to)X +3316(facilitate)X +3621(fast)X +3761(replacement.)X +2418 5297(Whereas)N +2724(ef\256cient)X +3011(access)X +3241(to)X +3327(primary)X +3605(pages)X +3812(is)X +3889(provided)X +2418 5385(by)N +2521(the)X +2642(bucket)X +2879(array,)X +3087(ef\256cient)X +3372(access)X +3600(to)X +3684(over\257ow)X +3991(pages)X +2418 5473(is)N +2501(provided)X +2816(by)X +2926(linking)X +3182(over\257ow)X +3497(page)X +3679(buffers)X +3936(to)X +4027(their)X +2418 5561(predecessor)N +2827(page)X +3008(\(either)X +3247(the)X +3374(primary)X +3657(page)X +3838(or)X +3933(another)X +2418 5649(over\257ow)N +2742(page\).)X +3000(This)X +3181(means)X +3425(that)X +3584(an)X +3699(over\257ow)X +4022(page)X +3 f +432 5960(6)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +7 p +%%Page: 7 7 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +720 538(cannot)N +955(be)X +1052(present)X +1305(in)X +1388(the)X +1507(buffer)X +1724(pool)X +1886(if)X +1955(its)X +2050(primary)X +2324(page)X +720 626(is)N +804(not)X +937(present.)X +1240(This)X +1413(does)X +1591(not)X +1724(impact)X +1972(performance)X +2409(or)X +720 714(functionality,)N +1209(because)X +1524(an)X +1660(over\257ow)X +2005(page)X +2217(will)X +2400(be)X +720 802(accessed)N +1048(only)X +1236(after)X +1430(its)X +1550(predecessor)X +1975(page)X +2172(has)X +2324(been)X +720 890(accessed.)N +1068(Figure)X +1303(4)X +1369(depicts)X +1622(the)X +1746(data)X +1905(structures)X +2242(used)X +2414(to)X +720 978(manage)N +990(the)X +1108(buffer)X +1325(pool.)X +892 1092(The)N +1040(in-memory)X +1419(bucket)X +1656(array)X +1845(contains)X +2134(pointers)X +2414(to)X +720 1180(buffer)N +975(header)X +1248(structures)X +1617(which)X +1870(represent)X +2222(primary)X +720 1268(pages.)N +968(Buffer)X +1203(headers)X +1474(contain)X +1735(modi\256ed)X +2043(bits,)X +2202(the)X +2324(page)X +720 1356(address)N +995(of)X +1096(the)X +1228(buffer,)X +1479(a)X +1548(pointer)X +1808(to)X +1903(the)X +2034(actual)X +2259(buffer,)X +720 1444(and)N +875(a)X +950(pointer)X +1216(to)X +1317(the)X +1454(buffer)X +1690(header)X +1944(for)X +2077(an)X +2191(over\257ow)X +720 1532(page)N +901(if)X +979(it)X +1052(exists,)X +1283(in)X +1374(addition)X +1665(to)X +1756(the)X +1883(LRU)X +2072(links.)X +2296(If)X +2378(the)X +720 1620(buffer)N +950(corresponding)X +1442(to)X +1537(a)X +1606(particular)X +1947(bucket)X +2194(is)X +2280(not)X +2414(in)X +720 1708(memory,)N +1048(its)X +1164(pointer)X +1432(is)X +1526(NULL.)X +1801(In)X +1909(effect,)X +2154(pages)X +2377(are)X +720 1796(linked)N +950(in)X +1042(three)X +1233(ways.)X +1468(Using)X +1689(the)X +1817(buffer)X +2043(headers,)X +2338(they)X +720 1884(are)N +851(linked)X +1083(physically)X +1444(through)X +1725(the)X +1854(LRU)X +2045(links)X +2231(and)X +2378(the)X +720 1972(over\257ow)N +1036(links.)X +1241(Using)X +1462(the)X +1590(pages)X +1803(themselves,)X +2209(they)X +2377(are)X +720 2060(linked)N +943(logically)X +1246(through)X +1518(the)X +1639(over\257ow)X +1946(addresses)X +2276(on)X +2378(the)X +720 2148(page.)N +948(Since)X +1162(over\257ow)X +1482(pages)X +1700(are)X +1834(accessed)X +2151(only)X +2328(after)X +720 2236(their)N +904(predecessor)X +1321(pages,)X +1560(they)X +1734(are)X +1869(removed)X +2186(from)X +2378(the)X +720 2324(buffer)N +937(pool)X +1099(when)X +1293(their)X +1460(primary)X +1734(is)X +1807(removed.)X +10 f +720 2412 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 Dt +2309 3177 MXY +24 15 Dl +-8 -15 Dl +8 -15 Dl +-24 15 Dl +52 0 Dl +789 3160 MXY +-35 0 Dl +0 -156 Dl +1607 0 Dl +0 173 Dl +789 3091 MXY +-24 -15 Dl +9 15 Dl +-9 15 Dl +24 -15 Dl +-69 0 Dl +2309 3125 MXY +104 0 Dl +0 -155 Dl +-1693 0 Dl +0 121 Dl +927 3160 MXY +24 15 Dl +-9 -15 Dl +9 -15 Dl +-24 15 Dl +553 0 Dl +1618 3177 MXY +8 27 Dl +4 -17 Dl +16 -6 Dl +-28 -4 Dl +138 121 Dl +1895 3315 MXY +28 3 Dl +-15 -9 Dl +1 -18 Dl +-14 24 Dl +276 -138 Dl +3108 MY +-28 -3 Dl +15 10 Dl +-1 17 Dl +14 -24 Dl +-276 138 Dl +1756 3229 MXY +-8 -27 Dl +-3 17 Dl +-16 6 Dl +27 4 Dl +-138 -121 Dl +1480 MX +-24 -15 Dl +9 15 Dl +-9 15 Dl +24 -15 Dl +-553 0 Dl +3 f +5 s +1083 3073(LRU)N +1178(chain)X +4 Ds +1402 3851 MXY + 1402 3851 lineto + 1471 3851 lineto + 1471 3920 lineto + 1402 3920 lineto + 1402 3851 lineto +closepath 19 1402 3851 1471 3920 Dp +1445 3747(Over\257ow)N +1613(Address)X +1549 3609 MXY +0 69 Dl +1756 MX +-23 -15 Dl +8 15 Dl +-8 15 Dl +23 -15 Dl +-207 0 Dl +-1 Ds +3 Dt +1756 3419 MXY +-6 -28 Dl +-4 17 Dl +-17 5 Dl +27 6 Dl +-138 -138 Dl +2240 3471 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +1826 3609 MXY +15 -24 Dl +-15 9 Dl +-16 -9 Dl +16 24 Dl +0 -138 Dl +1549 MX +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +858 3471 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +2240 3056 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +1549 3056 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +858 3056 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +1 Dt +2171 3471 MXY + 2171 3471 lineto + 2448 3471 lineto + 2448 3609 lineto + 2171 3609 lineto + 2171 3471 lineto +closepath 19 2171 3471 2448 3609 Dp +1756 3609 MXY + 1756 3609 lineto + 2033 3609 lineto + 2033 3747 lineto + 1756 3747 lineto + 1756 3609 lineto +closepath 3 1756 3609 2033 3747 Dp +1480 3471 MXY + 1480 3471 lineto + 1756 3471 lineto + 1756 3609 lineto + 1480 3609 lineto + 1480 3471 lineto +closepath 19 1480 3471 1756 3609 Dp +789 MX + 789 3471 lineto + 1065 3471 lineto + 1065 3609 lineto + 789 3609 lineto + 789 3471 lineto +closepath 19 789 3471 1065 3609 Dp +962 3903(Buffer)N +1083(Header)X +849 3851 MXY + 849 3851 lineto + 918 3851 lineto + 918 3920 lineto + 849 3920 lineto + 849 3851 lineto +closepath 14 849 3851 918 3920 Dp +1756 3194 MXY + 1756 3194 lineto + 1895 3194 lineto + 1895 3471 lineto + 1756 3471 lineto + 1756 3194 lineto +closepath 14 1756 3194 1895 3471 Dp +2171 3056 MXY + 2171 3056 lineto + 2309 3056 lineto + 2309 3333 lineto + 2171 3333 lineto + 2171 3056 lineto +closepath 14 2171 3056 2309 3333 Dp +1480 MX + 1480 3056 lineto + 1618 3056 lineto + 1618 3333 lineto + 1480 3333 lineto + 1480 3056 lineto +closepath 14 1480 3056 1618 3333 Dp +789 MX + 789 3056 lineto + 927 3056 lineto + 927 3333 lineto + 789 3333 lineto + 789 3056 lineto +closepath 14 789 3056 927 3333 Dp +2780 MY +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +927 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1065 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1203 MX +0 138 Dl +139 0 Dl +0 -138 Dl +-139 0 Dl +1342 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1480 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1618 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1756 MX +0 138 Dl +139 0 Dl +0 -138 Dl +-139 0 Dl +1895 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +2033 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +2171 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +2309 MX +0 138 Dl +139 0 Dl +0 -138 Dl +-139 0 Dl +13 s +1048 2720(In)N +1173(Memory)X +1580(Bucket)X +1918(Array)X +867 3584(B0)N +1558(B5)X +2223(B10)X +1788 3722(O1/1)N +5 s +1515 3903(Primay)N +1651(Buffer)X +4 Ds +1990 3851 MXY + 1990 3851 lineto + 2059 3851 lineto + 2059 3920 lineto + 1990 3920 lineto + 1990 3851 lineto +closepath 3 1990 3851 2059 3920 Dp +2102 3903(Over\257ow)N +2270(Buffer)X +3 Dt +-1 Ds +8 s +720 4184(Figure)N +922(4:)X +1 f +996(Three)X +1164(primary)X +1386(pages)X +1551(\(B0,)X +1683(B5,)X +1794(B10\))X +1942(are)X +2039(accessed)X +2281(directly)X +720 4272(from)N +862(the)X +958(bucket)X +1146(array.)X +1326(The)X +1443(one)X +1553(over\257ow)X +1798(page)X +1935(\(O1/1\))X +2122(is)X +2182(linked)X +2359(phy-)X +720 4360(sically)N +915(from)X +1067(its)X +1155(primary)X +1384(page's)X +1577(buffer)X +1759(header)X +1955(as)X +2035(well)X +2172(as)X +2252(logically)X +720 4448(from)N +860(its)X +937(predecessor)X +1253(page)X +1389(buffer)X +1560(\(B5\).)X +10 s +10 f +720 4624 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +1191 4954(Table)N +1406(Parameterization)X +1 f +892 5086(When)N +1107(a)X +1166(hash)X +1336(table)X +1515(is)X +1590(created,)X +1865(the)X +1985(bucket)X +2221(size,)X +2388(\256ll)X +720 5174(factor,)N +953(initial)X +1164(number)X +1434(of)X +1526(elements,)X +1856(number)X +2125(of)X +2216(bytes)X +2409(of)X +720 5262(main)N +919(memory)X +1225(used)X +1411(for)X +1543(caching,)X +1851(and)X +2005(a)X +2079(user-de\256ned)X +720 5350(hash)N +892(function)X +1184(may)X +1347(be)X +1448(speci\256ed.)X +1797(The)X +1946(bucket)X +2184(size)X +2333(\(and)X +720 5438(page)N +906(size)X +1064(for)X +1191(over\257ow)X +1509(pages\))X +1752(defaults)X +2039(to)X +2134(256)X +2287(bytes.)X +720 5526(For)N +858(tables)X +1072(with)X +1241(large)X +1429(data)X +1590(items,)X +1810(it)X +1881(may)X +2046(be)X +2149(preferable)X +720 5614(to)N +803(increase)X +1088(the)X +1207(page)X +1380(size,)X +1545(and,)X +1701(conversely,)X +2089(applications)X +720 5702(storing)N +1002(small)X +1235(items)X +1467(exclusively)X +1891(in)X +2012(memory)X +2338(may)X +2706 538(bene\256t)N +2966(from)X +3164(a)X +3242(smaller)X +3520(bucket)X +3776(size.)X +3983(A)X +4082(bucket)X +4337(size)X +2706 626(smaller)N +2962(than)X +3120(64)X +3220(bytes)X +3409(is)X +3482(not)X +3604(recommended.)X +2878 740(The)N +3031(\256ll)X +3147(factor)X +3363(indicates)X +3676(a)X +3740(desired)X +4000(density)X +4258(within)X +2706 828(the)N +2833(hash)X +3009(table.)X +3234(It)X +3312(is)X +3394(an)X +3499(approximation)X +3995(of)X +4091(the)X +4217(number)X +2706 916(of)N +2815(keys)X +3004(allowed)X +3300(to)X +3404(accumulate)X +3811(in)X +3914(any)X +4071(one)X +4228(bucket,)X +2706 1004(determining)N +3119(when)X +3319(the)X +3442(hash)X +3614(table)X +3795(grows.)X +4056(Its)X +4161(default)X +4409(is)X +2706 1092(eight.)N +2953(If)X +3054(the)X +3199(user)X +3380(knows)X +3636(the)X +3781(average)X +4079(size)X +4251(of)X +4364(the)X +2706 1180(key/data)N +3008(pairs)X +3194(being)X +3402(stored)X +3627(in)X +3718(the)X +3845(table,)X +4050(near)X +4218(optimal)X +2706 1268(bucket)N +2943(sizes)X +3122(and)X +3261(\256ll)X +3372(factors)X +3614(may)X +3775(be)X +3874(selected)X +4155(by)X +4257(apply-)X +2706 1356(ing)N +2828(the)X +2946(equation:)X +0 f +8 s +2706 1655(\(1\))N +2994 -0.3938(\(\(average_pair_length)AX +3830(+)X +3906(4\))X +4020(*)X +3032 1743(ffactor\))N +3374(>=)X +3488(bsize)X +1 f +10 s +2706 2042(For)N +2859(highly)X +3104(time)X +3287(critical)X +3551(applications,)X +3999(experimenting)X +2706 2130(with)N +2919(different)X +3266(bucket)X +3550(sizes)X +3776(and)X +3962(\256ll)X +4120(factors)X +4409(is)X +2706 2218(encouraged.)N +2878 2332(Figures)N +3144(5a,b,)X +3326(and)X +3468(c)X +3530(illustrate)X +3836(the)X +3960(effects)X +4200(of)X +4292(vary-)X +2706 2420(ing)N +2841(page)X +3026(sizes)X +3215(and)X +3363(\256ll)X +3483(factors)X +3734(for)X +3860(the)X +3990(same)X +4187(data)X +4353(set.)X +2706 2508(The)N +2864(data)X +3031(set)X +3152(consisted)X +3482(of)X +3581(24474)X +3813(keys)X +3992(taken)X +4198(from)X +4386(an)X +2706 2596(online)N +2931(dictionary.)X +3301(The)X +3451(data)X +3609(value)X +3807(for)X +3925(each)X +4097(key)X +4237(was)X +4386(an)X +2706 2684(ASCII)N +2938(string)X +3143(for)X +3260(an)X +3359(integer)X +3605(from)X +3784(1)X +3847(to)X +3931(24474)X +4153(inclusive.)X +2706 2772(The)N +2867(test)X +3013(run)X +3155(consisted)X +3488(of)X +3590(creating)X +3884(a)X +3955(new)X +4124(hash)X +4306(table)X +2706 2860(\(where)N +2966(the)X +3100(ultimate)X +3398(size)X +3559(of)X +3662(the)X +3796(table)X +3987(was)X +4147(known)X +4400(in)X +2706 2948(advance\),)N +3054(entering)X +3354(each)X +3539(key/data)X +3848(pair)X +4010(into)X +4171(the)X +4306(table)X +2706 3036(and)N +2849(then)X +3014(retrieving)X +3353(each)X +3528(key/data)X +3827(pair)X +3979(from)X +4162(the)X +4286(table.)X +2706 3124(Each)N +2898(of)X +2996(the)X +3125(graphs)X +3369(shows)X +3599(the)X +3727(timings)X +3996(resulting)X +4306(from)X +2706 3212(varying)N +2973(the)X +3093(pagesize)X +3392(from)X +3570(128)X +3712(bytes)X +3903(to)X +3986(1M)X +4118(and)X +4255(the)X +4374(\256ll)X +2706 3300(factor)N +2929(from)X +3120(1)X +3195(to)X +3292(128.)X +3486(For)X +3631(each)X +3813(run,)X +3974(the)X +4106(buffer)X +4337(size)X +2706 3388(was)N +2874(set)X +3006(at)X +3106(1M.)X +3299(The)X +3466(tests)X +3650(were)X +3849(all)X +3971(run)X +4120(on)X +4242(an)X +4360(HP)X +2706 3476(9000/370)N +3077(\(33.3)X +3312(Mhz)X +3527(MC68030\),)X +3966(with)X +4176(16M)X +4395(of)X +2706 3564(memory,)N +3042(64K)X +3228(physically)X +3605(addressed)X +3970(cache,)X +4222(and)X +4386(an)X +2706 3652(HP7959S)N +3055(disk)X +3231(drive,)X +3459(running)X +3751(4.3BSD-Reno)X +4244(single-)X +2706 3740(user.)N +2878 3854(Both)N +3066(system)X +3321(time)X +3496(\(Figure)X +3764(5a\))X +3899(and)X +4047(elapsed)X +4320(time)X +2706 3942(\(Figure)N +2966(5b\))X +3097(show)X +3290(that)X +3434(for)X +3552(all)X +3655(bucket)X +3892(sizes,)X +4091(the)X +4212(greatest)X +2706 4030(performance)N +3137(gains)X +3329(are)X +3451(made)X +3648(by)X +3751(increasing)X +4104(the)X +4225(\256ll)X +4336(fac-)X +2706 4118(tor)N +2822(until)X +2995(equation)X +3298(1)X +3365(is)X +3445(satis\256ed.)X +3774(The)X +3925(user)X +4085(time)X +4253(shown)X +2706 4206(in)N +2791(Figure)X +3023(5c)X +3122(gives)X +3314(a)X +3373(more)X +3561(detailed)X +3838(picture)X +4083(of)X +4172(how)X +4332(per-)X +2706 4294(formance)N +3054(varies.)X +3330(The)X +3499(smaller)X +3778(bucket)X +4035(sizes)X +4234(require)X +2706 4382(fewer)N +2921(keys)X +3099(per)X +3233(page)X +3416(to)X +3509(satisfy)X +3749(equation)X +4056(1)X +4127(and)X +4274(there-)X +2706 4470(fore)N +2860(incur)X +3049(fewer)X +3257(collisions.)X +3607(However,)X +3946(when)X +4144(the)X +4265(buffer)X +2706 4558(pool)N +2884(size)X +3045(is)X +3134(\256xed,)X +3349(smaller)X +3620(pages)X +3838(imply)X +4059(more)X +4259(pages.)X +2706 4646(An)N +2830(increased)X +3160(number)X +3430(of)X +3522(pages)X +3730(means)X +3960(more)X +2 f +4150(malloc\(3\))X +1 f +2706 4734(calls)N +2879(and)X +3021(more)X +3212(overhead)X +3533(in)X +3621(the)X +3745(hash)X +3918(package's)X +4265(buffer)X +2706 4822(manager)N +3003(to)X +3085(manage)X +3355(the)X +3473(additional)X +3813(pages.)X +2878 4936(The)N +3028(tradeoff)X +3308(works)X +3529(out)X +3655(most)X +3834(favorably)X +4166(when)X +4364(the)X +2706 5024(page)N +2886(size)X +3039(is)X +3120(256)X +3268(and)X +3412(the)X +3538(\256ll)X +3654(factor)X +3870(is)X +3950(8.)X +4057(Similar)X +4319(con-)X +2706 5112(clusions)N +3009(were)X +3207(obtained)X +3524(if)X +3614(the)X +3753(test)X +3905(was)X +4071(run)X +4218(without)X +2706 5200(knowing)N +3007(the)X +3126(\256nal)X +3289(table)X +3466(size)X +3612(in)X +3695(advance.)X +4020(If)X +4095(the)X +4214(\256le)X +4337(was)X +2706 5288(closed)N +2942(and)X +3088(written)X +3345(to)X +3437(disk,)X +3620(the)X +3748(conclusions)X +4156(were)X +4343(still)X +2706 5376(the)N +2832(same.)X +3065(However,)X +3408(rereading)X +3740(the)X +3865(\256le)X +3994(from)X +4177(disk)X +4337(was)X +2706 5464(slightly)N +2983(faster)X +3199(if)X +3285(a)X +3358(larger)X +3583(bucket)X +3834(size)X +3996(and)X +4149(\256ll)X +4274(factor)X +2706 5552(were)N +2898(used)X +3079(\(1K)X +3238(bucket)X +3486(size)X +3645(and)X +3795(32)X +3909(\256ll)X +4031(factor\).)X +4320(This)X +2706 5640(follows)N +2987(intuitively)X +3356(from)X +3553(the)X +3691(improved)X +4038(ef\256ciency)X +4395(of)X +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4424(7)X + +8 p +%%Page: 8 8 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +1 f +432 538(performing)N +830(1K)X +965(reads)X +1172(from)X +1365(the)X +1500(disk)X +1670(rather)X +1894(than)X +2068(256)X +432 626(byte)N +609(reads.)X +857(In)X +962(general,)X +1257(performance)X +1702(for)X +1834(disk)X +2005(based)X +432 714(tables)N +639(is)X +712(best)X +861(when)X +1055(the)X +1173(page)X +1345(size)X +1490(is)X +1563(approximately)X +2046(1K.)X +10 f +432 802 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +619 2380 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +629 2437 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +648 2504 MXY +-12 25 Dl +24 0 Dl +-12 -25 Dl +686 2515 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +762 2516 MXY +-12 24 Dl +25 0 Dl +-13 -24 Dl +916 2515 MXY +-13 24 Dl +25 0 Dl +-12 -24 Dl +1222 2516 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +1834 2515 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +1 Dt +619 2392 MXY +10 57 Dl +19 67 Dl +38 11 Dl +76 1 Dl +154 -1 Dl +306 1 Dl +612 -1 Dl +8 s +1 f +1628 2522(128)N +3 Dt +607 2245 MXY +24 Dc +617 2375 MXY +23 Dc +635 2442 MXY +24 Dc +674 2525 MXY +23 Dc +750 2529 MXY +24 Dc +904 2527 MXY +23 Dc +1210 MX +23 Dc +1822 2528 MXY +23 Dc +20 Ds +1 Dt +619 2245 MXY +10 130 Dl +19 67 Dl +38 83 Dl +76 4 Dl +154 -2 Dl +306 0 Dl +612 1 Dl +678 2482(256)N +-1 Ds +3 Dt +619 2127 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +629 2191 MXY +0 25 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +648 2334 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +686 2409 MXY +0 25 Dl +0 -13 Dl +12 0 Dl +-24 0 Dl +762 2516 MXY +0 25 Dl +0 -12 Dl +13 0 Dl +-25 0 Dl +916 2516 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-25 0 Dl +1222 2515 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1834 2515 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +5 Dt +619 2139 MXY +10 65 Dl +19 142 Dl +38 75 Dl +76 108 Dl +154 -1 Dl +306 -1 Dl +612 0 Dl +694 2401(512)N +3 Dt +631 2064 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +641 2077 MXY +-24 25 Dl +12 -12 Dl +-12 -13 Dl +24 25 Dl +660 2132 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +698 2292 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +775 2382 MXY +-25 24 Dl +12 -12 Dl +-12 -12 Dl +25 24 Dl +928 2516 MXY +-25 24 Dl +13 -12 Dl +-13 -12 Dl +25 24 Dl +1234 2516 MXY +-24 25 Dl +12 -12 Dl +-12 -13 Dl +24 25 Dl +1846 2516 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +16 Ds +1 Dt +619 2076 MXY +10 14 Dl +19 54 Dl +38 160 Dl +76 90 Dl +154 134 Dl +306 1 Dl +612 -1 Dl +694 2257(1024)N +-1 Ds +3 Dt +619 1877 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +629 1855 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +648 1838 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +686 1860 MXY +12 -25 Dl +-24 0 Dl +12 25 Dl +762 1923 MXY +13 -24 Dl +-25 0 Dl +12 24 Dl +916 2087 MXY +12 -24 Dl +-25 0 Dl +13 24 Dl +1222 2256 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +1834 2541 MXY +12 -25 Dl +-24 0 Dl +12 25 Dl +619 1865 MXY +10 -22 Dl +19 -17 Dl +38 21 Dl +76 64 Dl +154 164 Dl +306 169 Dl +612 285 Dl +1645 2427(4096)N +619 1243 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +629 1196 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +648 1146 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +686 1174 MXY +0 25 Dl +0 -13 Dl +12 0 Dl +-24 0 Dl +762 1249 MXY +0 24 Dl +0 -12 Dl +13 0 Dl +-25 0 Dl +916 1371 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-25 0 Dl +1222 1680 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1834 1999 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +619 1255 MXY +10 -47 Dl +19 -50 Dl +38 28 Dl +76 75 Dl +154 122 Dl +306 309 Dl +612 319 Dl +1741 1934(8192)N +5 Dt +609 2531 MXY +1225 0 Dl +609 MX +0 -1553 Dl +2531 MY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +593 2625(0)N +-1 Ds +5 Dt +916 2531 MXY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +884 2625(32)N +-1 Ds +5 Dt +1222 2531 MXY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +1190 2625(64)N +-1 Ds +5 Dt +1528 2531 MXY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +1496 2625(96)N +-1 Ds +5 Dt +1834 2531 MXY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +1786 2625(128)N +-1 Ds +5 Dt +609 2531 MXY +-16 0 Dl +4 Ds +1 Dt +609 MX +1225 0 Dl +545 2558(0)N +-1 Ds +5 Dt +609 2013 MXY +-16 0 Dl +4 Ds +1 Dt +609 MX +1225 0 Dl +481 2040(100)N +-1 Ds +5 Dt +609 1496 MXY +-16 0 Dl +4 Ds +1 Dt +609 MX +1225 0 Dl +481 1523(200)N +-1 Ds +5 Dt +609 978 MXY +-16 0 Dl +4 Ds +1 Dt +609 MX +1225 0 Dl +481 1005(300)N +1088 2724(Fill)N +1194(Factor)X +422 1611(S)N +426 1667(e)N +426 1724(c)N +424 1780(o)N +424 1837(n)N +424 1893(d)N +428 1949(s)N +3 Dt +-1 Ds +3 f +432 2882(Figure)N +636(5a:)X +1 f +744(System)X +956(Time)X +1113(for)X +1209(dictionary)X +1490(data)X +1618(set)X +1711(with)X +1847(1M)X +1958(of)X +2033(buffer)X +432 2970(space)N +594(and)X +707(varying)X +923(bucket)X +1114(sizes)X +1259(and)X +1372(\256ll)X +1465(factors.)X +1675(Each)X +1823(line)X +1940(is)X +2004(labeled)X +432 3058(with)N +562(its)X +639(bucket)X +825(size.)X +10 s +10 f +432 3234 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +8 s +1 f +428 4381(s)N +424 4325(d)N +424 4269(n)N +424 4212(o)N +426 4156(c)N +426 4099(e)N +422 4043(S)N +1116 5156(Fill)N +1222(Factor)X +506 3437(3200)N +4 Ds +1 Dt +666 3410 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +506 3825(2400)N +4 Ds +1 Dt +666 3799 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +506 4214(1600)N +4 Ds +1 Dt +666 4186 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +538 4602(800)N +4 Ds +1 Dt +666 4575 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +602 4990(0)N +4 Ds +1 Dt +666 4963 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +1786 5057(128)N +4 Ds +1 Dt +1834 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +1510 5057(96)N +4 Ds +1 Dt +1542 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +1218 5057(64)N +4 Ds +1 Dt +1250 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +926 5057(32)N +4 Ds +1 Dt +958 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +650 5057(0)N +4 Ds +1 Dt +666 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +4963 MY +0 -1553 Dl +4963 MY +1168 0 Dl +1741 4752(8192)N +3 Dt +675 3732 MXY +9 -172 Dl +18 -118 Dl +37 128 Dl +73 -121 Dl +146 623 Dl +292 497 Dl +584 245 Dl +4802 MY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1250 4557 MXY +0 25 Dl +0 -13 Dl +12 0 Dl +-24 0 Dl +958 4060 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +812 3437 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +739 3558 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +702 3430 MXY +0 25 Dl +0 -13 Dl +13 0 Dl +-25 0 Dl +684 3548 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +675 3720 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1637 4912(4096)N +675 4307 MXY +9 -58 Dl +18 30 Dl +37 89 Dl +73 144 Dl +146 235 Dl +292 122 Dl +584 89 Dl +4970 MY +12 -24 Dl +-24 0 Dl +12 24 Dl +1250 4881 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +958 4759 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +812 4524 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +739 4380 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +702 4291 MXY +13 -24 Dl +-25 0 Dl +12 24 Dl +684 4261 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +675 4319 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +734 4662(1024)N +16 Ds +1 Dt +675 4352 MXY +9 60 Dl +18 134 Dl +37 266 Dl +73 117 Dl +146 30 Dl +292 0 Dl +584 -1 Dl +-1 Ds +3 Dt +1846 4946 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +1262 4946 MXY +-24 25 Dl +12 -12 Dl +-12 -13 Dl +24 25 Dl +970 4947 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +824 4917 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +751 4800 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +715 4534 MXY +-25 25 Dl +12 -13 Dl +-12 -12 Dl +25 25 Dl +696 4400 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +687 4339 MXY +-24 25 Dl +12 -12 Dl +-12 -13 Dl +24 25 Dl +718 4792(512)N +5 Dt +675 4422 MXY +9 137 Dl +18 278 Dl +37 105 Dl +73 18 Dl +146 -1 Dl +292 0 Dl +584 -1 Dl +3 Dt +4946 MY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1250 4946 MXY +0 25 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +958 4947 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +812 4948 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +739 4930 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +702 4824 MXY +0 25 Dl +0 -12 Dl +13 0 Dl +-25 0 Dl +684 4547 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +675 4410 MXY +0 25 Dl +0 -13 Dl +12 0 Dl +-24 0 Dl +750 4921(256)N +20 Ds +1 Dt +675 4597 MXY +9 246 Dl +18 106 Dl +37 10 Dl +73 0 Dl +146 0 Dl +292 0 Dl +584 -1 Dl +-1 Ds +3 Dt +1822 MX +23 Dc +1238 4959 MXY +23 Dc +946 MX +23 Dc +800 MX +23 Dc +727 MX +23 Dc +691 4949 MXY +23 Dc +672 4843 MXY +24 Dc +663 4597 MXY +24 Dc +1395 4961(128)N +1 Dt +675 4855 MXY +9 93 Dl +18 10 Dl +37 1 Dl +73 0 Dl +146 -1 Dl +292 0 Dl +584 0 Dl +3 Dt +4946 MY +-12 24 Dl +24 0 Dl +-12 -24 Dl +1250 MX +-12 24 Dl +24 0 Dl +-12 -24 Dl +958 MX +-12 24 Dl +24 0 Dl +-12 -24 Dl +812 MX +-12 25 Dl +24 0 Dl +-12 -25 Dl +739 4947 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +702 4946 MXY +-12 24 Dl +25 0 Dl +-13 -24 Dl +684 4936 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +675 4843 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +3 Dt +-1 Ds +3 f +432 5314(Figure)N +634(5b:)X +1 f +744(Elapsed)X +967(Time)X +1123(for)X +1218(dictionary)X +1498(data)X +1625(set)X +1717(with)X +1851(1M)X +1960(of)X +2033(buffer)X +432 5402(space)N +593(and)X +705(varying)X +920(bucket)X +1110(sizes)X +1254(and)X +1366(\256ll)X +1457(factors.)X +1681(Each)X +1827(line)X +1942(is)X +2004(labeled)X +432 5490(with)N +562(its)X +639(bucket)X +825(size.)X +10 s +2590 538(If)N +2677(an)X +2785(approximation)X +3284(of)X +3383(the)X +3513(number)X +3790(of)X +3889(elements)X +2418 626(ultimately)N +2773(to)X +2866(be)X +2973(stored)X +3200(in)X +3293(the)X +3422(hash)X +3599(table)X +3785(is)X +3868(known)X +4116(at)X +2418 714(the)N +2564(time)X +2754(of)X +2869(creation,)X +3196(the)X +3342(hash)X +3536(package)X +3847(takes)X +4059(this)X +2418 802(number)N +2688(as)X +2779(a)X +2839(parameter)X +3185(and)X +3325(uses)X +3487(it)X +3555(to)X +3641(hash)X +3812(entries)X +4050(into)X +2418 890(the)N +2541(full)X +2677(sized)X +2867(table)X +3048(rather)X +3261(than)X +3424(growing)X +3716(the)X +3838(table)X +4018(from)X +2418 978(a)N +2477(single)X +2691(bucket.)X +2968(If)X +3044(this)X +3181(number)X +3448(is)X +3523(not)X +3647(known,)X +3907(the)X +4027(hash)X +2418 1066(table)N +2632(starts)X +2859(with)X +3059(a)X +3153(single)X +3402(bucket)X +3674(and)X +3848(gracefully)X +2418 1154(expands)N +2707(as)X +2800(elements)X +3111(are)X +3236(added,)X +3474(although)X +3780(a)X +3842(slight)X +4044(per-)X +2418 1242(formance)N +2747(degradation)X +3151(may)X +3313(be)X +3413(noticed.)X +3713(Figure)X +3946(6)X +4010(illus-)X +2418 1330(trates)N +2625(the)X +2756(difference)X +3116(in)X +3211(performance)X +3651(between)X +3952(storing)X +2418 1418(keys)N +2588(in)X +2673(a)X +2732(\256le)X +2857(when)X +3054(the)X +3174(ultimate)X +3458(size)X +3605(is)X +3680(known)X +3920(\(the)X +4067(left)X +2418 1506(bars)N +2581(in)X +2672(each)X +2849(set\),)X +3014(compared)X +3360(to)X +3450(building)X +3744(the)X +3870(\256le)X +4000(when)X +2418 1594(the)N +2550(ultimate)X +2846(size)X +3005(is)X +3091(unknown)X +3422(\(the)X +3580(right)X +3764(bars)X +3931(in)X +4026(each)X +2418 1682(set\).)N +2609(Once)X +2814(the)X +2947(\256ll)X +3069(factor)X +3291(is)X +3378(suf\256ciently)X +3772(high)X +3948(for)X +4076(the)X +2418 1770(page)N +2596(size)X +2747(\(8\),)X +2887(growing)X +3180(the)X +3304(table)X +3486(dynamically)X +3908(does)X +4081(lit-)X +2418 1858(tle)N +2518(to)X +2600(degrade)X +2875(performance.)X +10 f +2418 1946 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +9 s +1 f +2413 3238(s)N +2409 3173(d)N +2409 3108(n)N +2409 3043(o)N +2411 2979(c)N +2411 2914(e)N +2407 2849(S)N +3143 4129(Fill)N +3261(Factor)X +2448 2152(15)N +4 Ds +1 Dt +2557 2122 MXY +1473 0 Dl +-1 Ds +5 Dt +2557 MX +-19 0 Dl +2448 2747(10)N +4 Ds +1 Dt +2557 2717 MXY +1473 0 Dl +-1 Ds +5 Dt +2557 MX +-19 0 Dl +2484 3343(5)N +4 Ds +1 Dt +2557 3313 MXY +1473 0 Dl +-1 Ds +5 Dt +2557 MX +-19 0 Dl +2484 3938(0)N +4 Ds +1 Dt +2557 3908 MXY +1473 0 Dl +-1 Ds +5 Dt +2557 MX +-19 0 Dl +3976 4015(128)N +4 Ds +1 Dt +4030 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +3626 4015(96)N +4 Ds +1 Dt +3662 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +3258 4015(64)N +4 Ds +1 Dt +3294 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +2889 4015(32)N +4 Ds +1 Dt +2925 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +2539 4015(0)N +4 Ds +1 Dt +2557 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +3908 MY +0 -1786 Dl +3908 MY +1473 0 Dl +4053 2378(8192)N +3 Dt +2569 2277 MXY +11 0 Dl +23 48 Dl +46 -167 Dl +92 35 Dl +184 12 Dl +369 143 Dl +736 0 Dl +2334 MY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +3294 2334 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +2925 2192 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2741 2180 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2649 2144 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2603 2311 MXY +0 27 Dl +0 -13 Dl +14 0 Dl +-28 0 Dl +2580 2263 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2569 2263 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +4053 2591(4096)N +2569 2348 MXY +11 -11 Dl +23 -96 Dl +46 71 Dl +92 72 Dl +184 226 Dl +369 48 Dl +736 -60 Dl +2612 MY +14 -28 Dl +-28 0 Dl +14 28 Dl +3294 2672 MXY +13 -28 Dl +-27 0 Dl +14 28 Dl +2925 2624 MXY +14 -28 Dl +-28 0 Dl +14 28 Dl +2741 2398 MXY +14 -28 Dl +-28 0 Dl +14 28 Dl +2649 2326 MXY +14 -27 Dl +-28 0 Dl +14 27 Dl +2603 2255 MXY +14 -28 Dl +-28 0 Dl +14 28 Dl +2580 2350 MXY +14 -27 Dl +-28 0 Dl +14 27 Dl +2569 2362 MXY +13 -28 Dl +-27 0 Dl +14 28 Dl +4053 2681(1024)N +16 Ds +1 Dt +2569 2300 MXY +11 48 Dl +23 96 Dl +46 95 Dl +92 274 Dl +184 202 Dl +369 -155 Dl +736 -190 Dl +-1 Ds +3 Dt +4044 2656 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +3307 2846 MXY +-27 28 Dl +14 -14 Dl +-14 -14 Dl +27 28 Dl +2939 3001 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2755 2799 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2663 2525 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2617 2430 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2594 2334 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2582 2287 MXY +-27 27 Dl +14 -14 Dl +-14 -13 Dl +27 27 Dl +4053 2851(512)N +5 Dt +2569 2372 MXY +11 -24 Dl +23 405 Dl +46 83 Dl +92 227 Dl +184 -72 Dl +369 -119 Dl +736 -107 Dl +3 Dt +2751 MY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +3294 2858 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +2925 2977 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2741 3049 MXY +0 27 Dl +0 -13 Dl +14 0 Dl +-28 0 Dl +2649 2823 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2603 2739 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2580 2334 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2569 2358 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +4053 2795(256)N +20 Ds +1 Dt +2569 2456 MXY +11 285 Dl +23 95 Dl +46 251 Dl +92 -60 Dl +184 -84 Dl +369 -107 Dl +736 -71 Dl +-1 Ds +3 Dt +4016 MX +27 Dc +3280 2836 MXY +27 Dc +2912 2943 MXY +27 Dc +2728 3027 MXY +27 Dc +2635 3087 MXY +28 Dc +2589 2836 MXY +28 Dc +2566 2741 MXY +27 Dc +2554 2456 MXY +28 Dc +4053 2741(128)N +1 Dt +2569 2729 MXY +11 203 Dl +23 131 Dl +46 -60 Dl +92 -119 Dl +184 -60 Dl +369 -83 Dl +736 -12 Dl +3 Dt +2716 MY +-14 27 Dl +28 0 Dl +-14 -27 Dl +3294 2727 MXY +-14 28 Dl +27 0 Dl +-13 -28 Dl +2925 2811 MXY +-14 27 Dl +28 0 Dl +-14 -27 Dl +2741 2870 MXY +-14 28 Dl +28 0 Dl +-14 -28 Dl +2649 2989 MXY +-14 28 Dl +28 0 Dl +-14 -28 Dl +2603 3049 MXY +-14 27 Dl +28 0 Dl +-14 -27 Dl +2580 2918 MXY +-14 28 Dl +28 0 Dl +-14 -28 Dl +2569 2716 MXY +-14 27 Dl +27 0 Dl +-13 -27 Dl +3 Dt +-1 Ds +3 f +8 s +2418 4286(Figure)N +2628(5c:)X +1 f +2738(User)X +2887(Time)X +3051(for)X +3154(dictionary)X +3442(data)X +3577(set)X +3677(with)X +3820(1M)X +3938(of)X +4019(buffer)X +2418 4374(space)N +2579(and)X +2691(varying)X +2906(bucket)X +3096(sizes)X +3240(and)X +3352(\256ll)X +3443(factors.)X +3667(Each)X +3813(line)X +3928(is)X +3990(labeled)X +2418 4462(with)N +2548(its)X +2625(bucket)X +2811(size.)X +10 s +10 f +2418 4638 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 f +2590 4840(Since)N +2796(no)X +2904(known)X +3150(hash)X +3325(function)X +3620(performs)X +3938(equally)X +2418 4928(well)N +2589(on)X +2702(all)X +2815(possible)X +3110(data,)X +3297(the)X +3428(user)X +3595(may)X +3766(\256nd)X +3923(that)X +4076(the)X +2418 5016(built-in)N +2678(hash)X +2849(function)X +3140(does)X +3311(poorly)X +3544(on)X +3648(a)X +3708(particular)X +4040(data)X +2418 5104(set.)N +2548(In)X +2636(this)X +2771(case,)X +2950(a)X +3006(hash)X +3173(function,)X +3480(taking)X +3700(two)X +3840(arguments)X +2418 5192(\(a)N +2507(pointer)X +2760(to)X +2848(a)X +2910(byte)X +3074(string)X +3282(and)X +3424(a)X +3486(length\))X +3739(and)X +3880(returning)X +2418 5280(an)N +2517(unsigned)X +2829(long)X +2993(to)X +3077(be)X +3175(used)X +3344(as)X +3433(the)X +3553(hash)X +3722(value,)X +3938(may)X +4098(be)X +2418 5368(speci\256ed)N +2731(at)X +2817(hash)X +2992(table)X +3176(creation)X +3463(time.)X +3673(When)X +3893(an)X +3996(exist-)X +2418 5456(ing)N +2570(hash)X +2767(table)X +2973(is)X +3076(opened)X +3358(and)X +3524(a)X +3609(hash)X +3805(function)X +4121(is)X +2418 5544(speci\256ed,)N +2752(the)X +2879(hash)X +3054(package)X +3346(will)X +3498(try)X +3615(to)X +3705(determine)X +4054(that)X +2418 5632(the)N +2546(hash)X +2723(function)X +3020(supplied)X +3321(is)X +3404(the)X +3532(one)X +3678(with)X +3850(which)X +4076(the)X +2418 5720(table)N +2630(was)X +2811(created.)X +3139(There)X +3382(are)X +3536(a)X +3627(variety)X +3905(of)X +4027(hash)X +3 f +432 5960(8)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +9 p +%%Page: 9 9 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +720 538(functions)N +1065(provided)X +1397(with)X +1586(the)X +1731(package.)X +2082(The)X +2253(default)X +720 626(function)N +1014(for)X +1135(the)X +1260(package)X +1551(is)X +1631(the)X +1755(one)X +1897(which)X +2119(offered)X +2378(the)X +720 714(best)N +875(performance)X +1308(in)X +1396(terms)X +1600(of)X +1693(cycles)X +1920(executed)X +2232(per)X +2360(call)X +720 802(\(it)N +827(did)X +965(not)X +1103(produce)X +1398(the)X +1531(fewest)X +1776(collisions)X +2117(although)X +2432(it)X +720 890(was)N +866(within)X +1091(a)X +1148(small)X +1341(percentage)X +1710(of)X +1797(the)X +1915(function)X +2202(that)X +2342(pro-)X +720 978(duced)N +947(the)X +1080(fewest)X +1324(collisions\).)X +1731(Again,)X +1981(in)X +2077(time)X +2253(critical)X +720 1066(applications,)N +1152(users)X +1342(are)X +1466(encouraged)X +1862(to)X +1949(experiment)X +2334(with)X +720 1154(a)N +783(variety)X +1032(of)X +1125(hash)X +1298(functions)X +1622(to)X +1710(achieve)X +1982(optimal)X +2252(perfor-)X +720 1242(mance.)N +10 f +720 1330 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +7 s +1038 2925(Full)N +1149(size)X +1251(table)X +1384(\(left\))X +1547 2718(Fill)N +1643(Factor)X +2268 2662(64)N +1964(32)X +1674(16)X +1384(8)X +1093(4)X +4 Ds +1 Dt +900 2280 MXY +1548 0 Dl +900 1879 MXY +1548 0 Dl +900 1506 MXY +1548 0 Dl +1563 2902 MXY +111 0 Dl +-1 Ds +900 MX +110 0 Dl +1425 2828(System)N +983(User)X +1895 2778 MXY + 1895 2778 lineto + 1950 2778 lineto + 1950 2833 lineto + 1895 2833 lineto + 1895 2778 lineto +closepath 21 1895 2778 1950 2833 Dp +1342 MX + 1342 2778 lineto + 1397 2778 lineto + 1397 2833 lineto + 1342 2833 lineto + 1342 2778 lineto +closepath 14 1342 2778 1397 2833 Dp +900 MX + 900 2778 lineto + 955 2778 lineto + 955 2833 lineto + 900 2833 lineto + 900 2778 lineto +closepath 3 900 2778 955 2833 Dp +5 Dt +2283 2211 MXY +96 0 Dl +1992 MX +97 0 Dl +1702 MX +97 0 Dl +1411 2252 MXY +97 0 Dl +4 Ds +1 Dt +2283 2211 MXY + 2283 2211 lineto + 2379 2211 lineto + 2379 2252 lineto + 2283 2252 lineto + 2283 2211 lineto +closepath 14 2283 2211 2379 2252 Dp +1992 MX + 1992 2211 lineto + 2089 2211 lineto + 2089 2252 lineto + 1992 2252 lineto + 1992 2211 lineto +closepath 14 1992 2211 2089 2252 Dp +1702 MX + 1702 2211 lineto + 1799 2211 lineto + 1799 2252 lineto + 1702 2252 lineto + 1702 2211 lineto +closepath 14 1702 2211 1799 2252 Dp +1411 2252 MXY + 1411 2252 lineto + 1508 2252 lineto + 1508 2294 lineto + 1411 2294 lineto + 1411 2252 lineto +closepath 14 1411 2252 1508 2294 Dp +2283 MX + 2283 2252 lineto + 2379 2252 lineto + 2379 2612 lineto + 2283 2612 lineto + 2283 2252 lineto +closepath 3 2283 2252 2379 2612 Dp +1992 MX + 1992 2252 lineto + 2089 2252 lineto + 2089 2612 lineto + 1992 2612 lineto + 1992 2252 lineto +closepath 3 1992 2252 2089 2612 Dp +1702 MX + 1702 2252 lineto + 1799 2252 lineto + 1799 2612 lineto + 1702 2612 lineto + 1702 2252 lineto +closepath 3 1702 2252 1799 2612 Dp +1411 2294 MXY + 1411 2294 lineto + 1508 2294 lineto + 1508 2612 lineto + 1411 2612 lineto + 1411 2294 lineto +closepath 3 1411 2294 1508 2612 Dp +-1 Ds +2158 2238 MXY + 2158 2238 lineto + 2255 2238 lineto + 2255 2252 lineto + 2158 2252 lineto + 2158 2238 lineto +closepath 21 2158 2238 2255 2252 Dp +1868 MX + 1868 2238 lineto + 1965 2238 lineto + 1965 2280 lineto + 1868 2280 lineto + 1868 2238 lineto +closepath 21 1868 2238 1965 2280 Dp +1577 MX + 1577 2238 lineto + 1674 2238 lineto + 1674 2308 lineto + 1577 2308 lineto + 1577 2238 lineto +closepath 21 1577 2238 1674 2308 Dp +1287 2308 MXY + 1287 2308 lineto + 1287 2280 lineto + 1384 2280 lineto + 1384 2308 lineto + 1287 2308 lineto +closepath 21 1287 2280 1384 2308 Dp +2158 2280 MXY + 2158 2280 lineto + 2158 2252 lineto + 2255 2252 lineto + 2255 2280 lineto + 2158 2280 lineto +closepath 14 2158 2252 2255 2280 Dp +1868 2308 MXY + 1868 2308 lineto + 1868 2280 lineto + 1965 2280 lineto + 1965 2308 lineto + 1868 2308 lineto +closepath 14 1868 2280 1965 2308 Dp +1577 2335 MXY + 1577 2335 lineto + 1577 2308 lineto + 1674 2308 lineto + 1674 2335 lineto + 1577 2335 lineto +closepath 14 1577 2308 1674 2335 Dp +1287 2363 MXY + 1287 2363 lineto + 1287 2308 lineto + 1384 2308 lineto + 1384 2363 lineto + 1287 2363 lineto +closepath 14 1287 2308 1384 2363 Dp +2158 2280 MXY + 2158 2280 lineto + 2255 2280 lineto + 2255 2612 lineto + 2158 2612 lineto + 2158 2280 lineto +closepath 3 2158 2280 2255 2612 Dp +1868 2308 MXY + 1868 2308 lineto + 1965 2308 lineto + 1965 2612 lineto + 1868 2612 lineto + 1868 2308 lineto +closepath 3 1868 2308 1965 2612 Dp +1577 2335 MXY + 1577 2335 lineto + 1674 2335 lineto + 1674 2612 lineto + 1577 2612 lineto + 1577 2335 lineto +closepath 3 1577 2335 1674 2612 Dp +1287 2363 MXY + 1287 2363 lineto + 1384 2363 lineto + 1384 2612 lineto + 1287 2612 lineto + 1287 2363 lineto +closepath 3 1287 2363 1384 2612 Dp +4 Ds +1121 2066 MXY + 1121 2066 lineto + 1218 2066 lineto + 1224 2080 lineto + 1127 2080 lineto + 1121 2066 lineto +closepath 21 1121 2066 1224 2080 Dp +2080 MY + 1121 2080 lineto + 1218 2080 lineto + 1218 2273 lineto + 1121 2273 lineto + 1121 2080 lineto +closepath 14 1121 2080 1218 2273 Dp +2273 MY + 1121 2273 lineto + 1218 2273 lineto + 1218 2612 lineto + 1121 2612 lineto + 1121 2273 lineto +closepath 3 1121 2273 1218 2612 Dp +-1 Ds +997 1589 MXY + 997 1589 lineto + 1093 1589 lineto + 1093 1644 lineto + 997 1644 lineto + 997 1589 lineto +closepath 21 997 1589 1093 1644 Dp +1644 MY + 997 1644 lineto + 1093 1644 lineto + 1093 2280 lineto + 997 2280 lineto + 997 1644 lineto +closepath 14 997 1644 1093 2280 Dp +2280 MY + 997 2280 lineto + 1093 2280 lineto + 1093 2612 lineto + 997 2612 lineto + 997 2280 lineto +closepath 3 997 2280 1093 2612 Dp +10 s +719 2093(s)N +712 2037(d)N +712 1982(n)N +714 1927(o)N +716 1872(c)N +716 1816(e)N +712 1761(S)N +804 2286(10)N +804 1899(20)N +804 1540(30)N +3 Dt +900 1506 MXY +0 1106 Dl +1548 0 Dl +7 s +1978 2828(Elapsed)N +1701 2925(Dynamically)N +2018(grown)X +2184(table)X +2317(\(right\))X +3 Dt +-1 Ds +8 s +720 3180(Figure)N +934(6:)X +1 f +1020(The)X +1152(total)X +1299(regions)X +1520(indicate)X +1755(the)X +1865(difference)X +2154(between)X +2398(the)X +720 3268(elapsed)N +931(time)X +1065(and)X +1177(the)X +1275(sum)X +1402(of)X +1475(the)X +1573(system)X +1771(and)X +1883(user)X +2008(time.)X +2173(The)X +2291(left)X +2395(bar)X +720 3356(of)N +798(each)X +939(set)X +1035(depicts)X +1241(the)X +1344(timing)X +1537(of)X +1615(the)X +1718(test)X +1831(run)X +1940(when)X +2102(the)X +2204(number)X +2423(of)X +720 3444(entries)N +910(is)X +973(known)X +1167(in)X +1237(advance.)X +1496(The)X +1614(right)X +1754(bars)X +1879(depict)X +2054(the)X +2151(timing)X +2338(when)X +720 3532(the)N +814(\256le)X +912(is)X +971(grown)X +1150(from)X +1290(a)X +1334(single)X +1503(bucket.)X +10 s +10 f +720 3708 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 f +892 3910(Since)N +1131(this)X +1307(hashing)X +1617(package)X +1942(provides)X +2279(buffer)X +720 3998(management,)N +1188(the)X +1323(amount)X +1600(of)X +1704(space)X +1920(allocated)X +2247(for)X +2378(the)X +720 4086(buffer)N +948(pool)X +1121(may)X +1290(be)X +1397(speci\256ed)X +1713(by)X +1824(the)X +1953(user.)X +2157(Using)X +2378(the)X +720 4174(same)N +910(data)X +1069(set)X +1183(and)X +1324(test)X +1459(procedure)X +1805(as)X +1896(used)X +2067(to)X +2153(derive)X +2378(the)X +720 4262(graphs)N +962(in)X +1052(Figures)X +1320(5a-c,)X +1507(Figure)X +1744(7)X +1812(shows)X +2039(the)X +2164(impact)X +2409(of)X +720 4350(varying)N +997(the)X +1126(size)X +1282(of)X +1380(the)X +1509(buffer)X +1737(pool.)X +1950(The)X +2106(bucket)X +2351(size)X +720 4438(was)N +873(set)X +989(to)X +1078(256)X +1225(bytes)X +1421(and)X +1564(the)X +1689(\256ll)X +1804(factor)X +2019(was)X +2171(set)X +2287(to)X +2376(16.)X +720 4526(The)N +869(buffer)X +1090(pool)X +1256(size)X +1404(was)X +1552(varied)X +1776(from)X +1955(0)X +2018(\(the)X +2166(minimum)X +720 4614(number)N +986(of)X +1074(pages)X +1277(required)X +1565(to)X +1647(be)X +1743(buffered\))X +2063(to)X +2145(1M.)X +2316(With)X +720 4702(1M)N +854(of)X +944(buffer)X +1164(space,)X +1386(the)X +1507(package)X +1794(performed)X +2151(no)X +2253(I/O)X +2382(for)X +720 4790(this)N +871(data)X +1040(set.)X +1204(As)X +1328(Figure)X +1572(7)X +1647(illustrates,)X +2013(increasing)X +2378(the)X +720 4878(buffer)N +944(pool)X +1113(size)X +1265(can)X +1404(have)X +1583(a)X +1646(dramatic)X +1954(affect)X +2165(on)X +2271(result-)X +720 4966(ing)N +842(performance.)X +2 f +8 s +1269 4941(7)N +1 f +16 s +720 5353 MXY +864 0 Dl +2 f +8 s +760 5408(7)N +1 f +9 s +826 5433(Some)N +1024(allocators)X +1338(are)X +1460(extremely)X +1782(inef\256cient)X +2107(at)X +2192(allocating)X +720 5513(memory.)N +1029(If)X +1110(you)X +1251(\256nd)X +1396(that)X +1536(applications)X +1916(are)X +2036(running)X +2292(out)X +2416(of)X +720 5593(memory)N +1005(before)X +1234(you)X +1386(think)X +1578(they)X +1746(should,)X +2000(try)X +2124(varying)X +2388(the)X +720 5673(pagesize)N +986(to)X +1060(get)X +1166(better)X +1348(utilization)X +1658(from)X +1816(the)X +1922(memory)X +2180(allocator.)X +10 s +2830 1975 MXY +0 -28 Dl +28 0 Dl +0 28 Dl +-28 0 Dl +2853 2004 MXY +0 -27 Dl +28 0 Dl +0 27 Dl +-28 0 Dl +2876 2016 MXY +0 -27 Dl +27 0 Dl +0 27 Dl +-27 0 Dl +2922 1998 MXY +0 -27 Dl +27 0 Dl +0 27 Dl +-27 0 Dl +2967 2025 MXY +0 -28 Dl +28 0 Dl +0 28 Dl +-28 0 Dl +3013 2031 MXY +0 -28 Dl +28 0 Dl +0 28 Dl +-28 0 Dl +3059 MX +0 -28 Dl +27 0 Dl +0 28 Dl +-27 0 Dl +3196 2052 MXY +0 -28 Dl +27 0 Dl +0 28 Dl +-27 0 Dl +3561 2102 MXY +0 -28 Dl +28 0 Dl +0 28 Dl +-28 0 Dl +4292 2105 MXY +0 -28 Dl +27 0 Dl +0 28 Dl +-27 0 Dl +4 Ds +1 Dt +2844 1961 MXY +23 30 Dl +23 12 Dl +45 -18 Dl +46 26 Dl +46 6 Dl +45 0 Dl +137 21 Dl +366 50 Dl +730 3 Dl +9 s +4227 2158(User)N +-1 Ds +3 Dt +2830 1211 MXY +27 Dc +2853 1261 MXY +27 Dc +2876 1267 MXY +27 Dc +2921 1341 MXY +27 Dc +2967 1385 MXY +27 Dc +3013 1450 MXY +27 Dc +3059 1497 MXY +27 Dc +3196 1686 MXY +27 Dc +3561 2109 MXY +27 Dc +4292 2295 MXY +27 Dc +20 Ds +1 Dt +2844 1211 MXY +23 50 Dl +23 6 Dl +45 74 Dl +46 44 Dl +46 65 Dl +45 47 Dl +137 189 Dl +366 423 Dl +730 186 Dl +4181 2270(System)N +-1 Ds +3 Dt +2844 583 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2867 672 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2890 701 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +2935 819 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-27 0 Dl +2981 849 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +3027 908 MXY +0 27 Dl +0 -13 Dl +14 0 Dl +-28 0 Dl +3072 1026 MXY +0 27 Dl +0 -13 Dl +14 0 Dl +-27 0 Dl +3209 1292 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-27 0 Dl +3575 1823 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +4305 2059 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-27 0 Dl +5 Dt +2844 597 MXY +23 88 Dl +23 30 Dl +45 118 Dl +46 30 Dl +46 59 Dl +45 118 Dl +137 265 Dl +366 532 Dl +730 236 Dl +4328 2103(Total)N +2844 2310 MXY +1461 0 Dl +2844 MX +0 -1772 Dl +2310 MY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +2826 2416(0)N +-1 Ds +5 Dt +3209 2310 MXY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +3155 2416(256)N +-1 Ds +5 Dt +3575 2310 MXY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +3521 2416(512)N +-1 Ds +5 Dt +3940 2310 MXY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +3886 2416(768)N +-1 Ds +5 Dt +4305 2310 MXY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +4233 2416(1024)N +-1 Ds +5 Dt +2844 2310 MXY +-18 0 Dl +4 Ds +1 Dt +2844 MX +1461 0 Dl +2771 2340(0)N +-1 Ds +5 Dt +2844 2014 MXY +-18 0 Dl +2844 1719 MXY +-18 0 Dl +4 Ds +1 Dt +2844 MX +1461 0 Dl +2735 1749(20)N +-1 Ds +5 Dt +2844 1423 MXY +-18 0 Dl +2844 1128 MXY +-18 0 Dl +4 Ds +1 Dt +2844 MX +1461 0 Dl +2735 1158(40)N +-1 Ds +5 Dt +2844 833 MXY +-18 0 Dl +2844 538 MXY +-18 0 Dl +4 Ds +1 Dt +2844 MX +1461 0 Dl +2735 568(60)N +3239 2529(Buffer)N +3445(Pool)X +3595(Size)X +3737(\(in)X +3835(K\))X +2695 1259(S)N +2699 1324(e)N +2699 1388(c)N +2697 1452(o)N +2697 1517(n)N +2697 1581(d)N +2701 1645(s)N +3 Dt +-1 Ds +3 f +8 s +2706 2773(Figure)N +2908(7:)X +1 f +2982(User)X +3123(time)X +3258(is)X +3322(virtually)X +3560(insensitive)X +3854(to)X +3924(the)X +4022(amount)X +4234(of)X +4307(buffer)X +2706 2861(pool)N +2852(available,)X +3130(however,)X +3396(both)X +3541(system)X +3750(time)X +3895(and)X +4018(elapsed)X +4240(time)X +4385(are)X +2706 2949(inversely)N +2960(proportional)X +3296(to)X +3366(the)X +3464(size)X +3583(of)X +3656(the)X +3753(buffer)X +3927(pool.)X +4092(Even)X +4242(for)X +4335(large)X +2706 3037(data)N +2831(sets)X +2946(where)X +3120(one)X +3230(expects)X +3439(few)X +3552(collisions,)X +3832(specifying)X +4116(a)X +4162(large)X +4307(buffer)X +2706 3125(pool)N +2836(dramatically)X +3171(improves)X +3425(performance.)X +10 s +10 f +2706 3301 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +3175 3543(Enhanced)N +3536(Functionality)X +1 f +2878 3675(This)N +3046(hashing)X +3320(package)X +3609(provides)X +3910(a)X +3971(set)X +4085(of)X +4177(compati-)X +2706 3763(bility)N +2895(routines)X +3174(to)X +3257(implement)X +3620(the)X +2 f +3739(ndbm)X +1 f +3937(interface.)X +4279(How-)X +2706 3851(ever,)N +2893(when)X +3095(the)X +3220(native)X +3443(interface)X +3752(is)X +3832(used,)X +4026(the)X +4151(following)X +2706 3939(additional)N +3046(functionality)X +3475(is)X +3548(provided:)X +10 f +2798 4071(g)N +1 f +2946(Inserts)X +3197(never)X +3413(fail)X +3556(because)X +3847(too)X +3985(many)X +4199(keys)X +2946 4159(hash)N +3113(to)X +3195(the)X +3313(same)X +3498(value.)X +10 f +2798 4247(g)N +1 f +2946(Inserts)X +3187(never)X +3393(fail)X +3527(because)X +3808(key)X +3950(and/or)X +4181(asso-)X +2946 4335(ciated)N +3158(data)X +3312(is)X +3385(too)X +3507(large)X +10 f +2798 4423(g)N +1 f +2946(Hash)X +3131(functions)X +3449(may)X +3607(be)X +3703(user-speci\256ed.)X +10 f +2798 4511(g)N +1 f +2946(Multiple)X +3268(pages)X +3498(may)X +3683(be)X +3806(cached)X +4077(in)X +4186(main)X +2946 4599(memory.)N +2706 4731(It)N +2801(also)X +2976(provides)X +3298(a)X +3380(set)X +3514(of)X +3626(compatibility)X +4097(routines)X +4400(to)X +2706 4819(implement)N +3087(the)X +2 f +3224(hsearch)X +1 f +3516(interface.)X +3876(Again,)X +4130(the)X +4266(native)X +2706 4907(interface)N +3008(offers)X +3216(enhanced)X +3540(functionality:)X +10 f +2798 5039(g)N +1 f +2946(Files)X +3121(may)X +3279(grow)X +3464(beyond)X +2 f +3720(nelem)X +1 f +3932(elements.)X +10 f +2798 5127(g)N +1 f +2946(Multiple)X +3247(hash)X +3420(tables)X +3632(may)X +3795(be)X +3896(accessed)X +4203(con-)X +2946 5215(currently.)N +10 f +2798 5303(g)N +1 f +2946(Hash)X +3134(tables)X +3344(may)X +3505(be)X +3604(stored)X +3823(and)X +3962(accessed)X +4266(on)X +2946 5391(disk.)N +10 f +2798 5479(g)N +1 f +2946(Hash)X +3155(functions)X +3497(may)X +3679(be)X +3799(user-speci\256ed)X +4288(at)X +2946 5567(runtime.)N +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4424(9)X + +10 p +%%Page: 10 10 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +459 538(Relative)N +760(Performance)X +1227(of)X +1314(the)X +1441(New)X +1613(Implementation)X +1 f +604 670(The)N +761(performance)X +1200(testing)X +1445(of)X +1544(the)X +1674(new)X +1840(package)X +2135(is)X +432 758(divided)N +711(into)X +874(two)X +1033(test)X +1183(suites.)X +1424(The)X +1588(\256rst)X +1751(suite)X +1941(of)X +2046(tests)X +432 846(requires)N +727(that)X +882(the)X +1015(tables)X +1237(be)X +1348(read)X +1522(from)X +1713(and)X +1864(written)X +2126(to)X +432 934(disk.)N +640(In)X +742(these)X +942(tests,)X +1139(the)X +1272(basis)X +1467(for)X +1595(comparison)X +2003(is)X +2090(the)X +432 1022(4.3BSD-Reno)N +908(version)X +1169(of)X +2 f +1260(ndbm)X +1 f +1438(.)X +1502(Based)X +1722(on)X +1826(the)X +1948(designs)X +432 1110(of)N +2 f +521(sdbm)X +1 f +712(and)X +2 f +850(gdbm)X +1 f +1028(,)X +1070(they)X +1230(are)X +1351(expected)X +1659(to)X +1743(perform)X +2024(simi-)X +432 1198(larly)N +605(to)X +2 f +693(ndbm)X +1 f +871(,)X +917(and)X +1059(we)X +1179(do)X +1285(not)X +1413(show)X +1608(their)X +1781(performance)X +432 1286(numbers.)N +800(The)X +977(second)X +1252(suite)X +1454(contains)X +1772(the)X +1921(memory)X +432 1374(resident)N +712(test)X +849(which)X +1071(does)X +1243(not)X +1370(require)X +1623(that)X +1768(the)X +1891(\256les)X +2049(ever)X +432 1462(be)N +533(written)X +784(to)X +870(disk,)X +1047(only)X +1213(that)X +1357(hash)X +1528(tables)X +1739(may)X +1901(be)X +2001(mani-)X +432 1550(pulated)N +692(in)X +778(main)X +961(memory.)X +1291(In)X +1381(this)X +1519(test,)X +1673(we)X +1790(compare)X +2090(the)X +432 1638(performance)N +859(to)X +941(that)X +1081(of)X +1168(the)X +2 f +1286(hsearch)X +1 f +1560(routines.)X +604 1752(For)N +760(both)X +947(suites,)X +1194(two)X +1358(different)X +1679(databases)X +2031(were)X +432 1840(used.)N +656(The)X +818(\256rst)X +979(is)X +1069(the)X +1204(dictionary)X +1566(database)X +1880(described)X +432 1928(previously.)N +836(The)X +987(second)X +1236(was)X +1386(constructed)X +1781(from)X +1962(a)X +2023(pass-)X +432 2016(word)N +647(\256le)X +799(with)X +990(approximately)X +1502(300)X +1671(accounts.)X +2041(Two)X +432 2104(records)N +700(were)X +887(constructed)X +1287(for)X +1411(each)X +1589(account.)X +1909(The)X +2064(\256rst)X +432 2192(used)N +604(the)X +727(logname)X +1028(as)X +1120(the)X +1243(key)X +1384(and)X +1525(the)X +1648(remainder)X +1999(of)X +2090(the)X +432 2280(password)N +768(entry)X +965(for)X +1091(the)X +1221(data.)X +1427(The)X +1584(second)X +1839(was)X +1996(keyed)X +432 2368(by)N +541(uid)X +672(and)X +817(contained)X +1157(the)X +1283(entire)X +1494(password)X +1825(entry)X +2018(as)X +2113(its)X +432 2456(data)N +589(\256eld.)X +794(The)X +942(tests)X +1107(were)X +1287(all)X +1389(run)X +1518(on)X +1620(the)X +1740(HP)X +1864(9000)X +2046(with)X +432 2544(the)N +574(same)X +783(con\256guration)X +1254(previously)X +1636(described.)X +2027(Each)X +432 2632(test)N +576(was)X +734(run)X +874(\256ve)X +1027(times)X +1232(and)X +1380(the)X +1510(timing)X +1750(results)X +1991(of)X +2090(the)X +432 2720(runs)N +602(were)X +791(averaged.)X +1154(The)X +1311(variance)X +1616(across)X +1849(the)X +1979(5)X +2050(runs)X +432 2808(was)N +591(approximately)X +1088(1%)X +1229(of)X +1330(the)X +1462(average)X +1746(yielding)X +2041(95%)X +432 2896(con\256dence)N +800(intervals)X +1096(of)X +1183(approximately)X +1666(2%.)X +3 f +1021 3050(Disk)N +1196(Based)X +1420(Tests)X +1 f +604 3182(In)N +693(these)X +880(tests,)X +1064(we)X +1180(use)X +1308(a)X +1365(bucket)X +1600(size)X +1746(of)X +1834(1024)X +2015(and)X +2152(a)X +432 3270(\256ll)N +540(factor)X +748(of)X +835(32.)X +3 f +432 3384(create)N +663(test)X +1 f +547 3498(The)N +703(keys)X +881(are)X +1011(entered)X +1279(into)X +1433(the)X +1561(hash)X +1738(table,)X +1944(and)X +2090(the)X +547 3586(\256le)N +669(is)X +742(\257ushed)X +993(to)X +1075(disk.)X +3 f +432 3700(read)N +608(test)X +1 f +547 3814(A)N +640(lookup)X +897(is)X +984(performed)X +1353(for)X +1481(each)X +1663(key)X +1813(in)X +1909(the)X +2041(hash)X +547 3902(table.)N +3 f +432 4016(verify)N +653(test)X +1 f +547 4130(A)N +640(lookup)X +897(is)X +984(performed)X +1353(for)X +1481(each)X +1663(key)X +1813(in)X +1909(the)X +2041(hash)X +547 4218(table,)N +759(and)X +911(the)X +1045(data)X +1215(returned)X +1519(is)X +1608(compared)X +1961(against)X +547 4306(that)N +687(originally)X +1018(stored)X +1234(in)X +1316(the)X +1434(hash)X +1601(table.)X +3 f +432 4420(sequential)N +798(retrieve)X +1 f +547 4534(All)N +674(keys)X +846(are)X +970(retrieved)X +1281(in)X +1367(sequential)X +1716(order)X +1910(from)X +2090(the)X +547 4622(hash)N +724(table.)X +950(The)X +2 f +1105(ndbm)X +1 f +1313(interface)X +1625(allows)X +1863(sequential)X +547 4710(retrieval)N +848(of)X +948(the)X +1079(keys)X +1259(from)X +1448(the)X +1578(database,)X +1907(but)X +2041(does)X +547 4798(not)N +701(return)X +945(the)X +1094(data)X +1279(associated)X +1660(with)X +1853(each)X +2052(key.)X +547 4886(Therefore,)N +929(we)X +1067(compare)X +1388(the)X +1530(performance)X +1980(of)X +2090(the)X +547 4974(new)N +703(package)X +989(to)X +1073(two)X +1215(different)X +1514(runs)X +1674(of)X +2 f +1763(ndbm)X +1 f +1941(.)X +2002(In)X +2090(the)X +547 5062(\256rst)N +697(case,)X +2 f +882(ndbm)X +1 f +1086(returns)X +1335(only)X +1503(the)X +1627(keys)X +1800(while)X +2003(in)X +2090(the)X +547 5150(second,)N +2 f +823(ndbm)X +1 f +1034(returns)X +1290(both)X +1465(the)X +1596(keys)X +1776(and)X +1924(the)X +2054(data)X +547 5238(\(requiring)N +894(a)X +956(second)X +1204(call)X +1345(to)X +1432(the)X +1555(library\).)X +1861(There)X +2074(is)X +2152(a)X +547 5326(single)N +764(run)X +897(for)X +1017(the)X +1141(new)X +1300(library)X +1539(since)X +1729(it)X +1798(returns)X +2046(both)X +547 5414(the)N +665(key)X +801(and)X +937(the)X +1055(data.)X +3 f +3014 538(In-Memory)N +3431(Test)X +1 f +2590 670(This)N +2757(test)X +2892(uses)X +3054(a)X +3114(bucket)X +3352(size)X +3501(of)X +3592(256)X +3736(and)X +3876(a)X +3936(\256ll)X +4048(fac-)X +2418 758(tor)N +2527(of)X +2614(8.)X +3 f +2418 872(create/read)N +2827(test)X +1 f +2533 986(In)N +2627(this)X +2769(test,)X +2927(a)X +2989(hash)X +3162(table)X +3344(is)X +3423(created)X +3682(by)X +3788(inserting)X +4094(all)X +2533 1074(the)N +2660(key/data)X +2961(pairs.)X +3186(Then)X +3380(a)X +3445(keyed)X +3666(retrieval)X +3963(is)X +4044(per-)X +2533 1162(formed)N +2801(for)X +2931(each)X +3115(pair,)X +3295(and)X +3446(the)X +3579(hash)X +3761(table)X +3952(is)X +4040(des-)X +2533 1250(troyed.)N +3 f +2938 1404(Performance)N +3405(Results)X +1 f +2590 1536(Figures)N +2866(8a)X +2978(and)X +3130(8b)X +3246(show)X +3451(the)X +3585(user)X +3755(time,)X +3952(system)X +2418 1624(time,)N +2608(and)X +2752(elapsed)X +3021(time)X +3191(for)X +3312(each)X +3487(test)X +3625(for)X +3746(both)X +3915(the)X +4040(new)X +2418 1712(implementation)N +2951(and)X +3098(the)X +3227(old)X +3360(implementation)X +3893(\()X +2 f +3920(hsearch)X +1 f +2418 1800(or)N +2 f +2528(ndbm)X +1 f +2706(,)X +2769(whichever)X +3147(is)X +3243(appropriate\))X +3678(as)X +3787(well)X +3967(as)X +4076(the)X +2418 1888(improvement.)N +2929(The)X +3098(improvement)X +3569(is)X +3666(expressed)X +4027(as)X +4138(a)X +2418 1976(percentage)N +2787(of)X +2874(the)X +2992(old)X +3114(running)X +3383(time:)X +0 f +8 s +2418 2275(%)N +2494(=)X +2570(100)X +2722(*)X +2798 -0.4219(\(old_time)AX +3178(-)X +3254 -0.4219(new_time\))AX +3634(/)X +3710(old_time)X +1 f +10 s +2590 2600(In)N +2700(nearly)X +2944(all)X +3067(cases,)X +3299(the)X +3439(new)X +3615(routines)X +3915(perform)X +2418 2688(better)N +2628(than)X +2793(the)X +2918(old)X +3047(routines)X +3332(\(both)X +2 f +3527(hsearch)X +1 f +3807(and)X +2 f +3949(ndbm)X +1 f +4127(\).)X +2418 2776(Although)N +2755(the)X +3 f +2888(create)X +1 f +3134(tests)X +3311(exhibit)X +3567(superior)X +3864(user)X +4032(time)X +2418 2864(performance,)N +2869(the)X +2991(test)X +3126(time)X +3292(is)X +3369(dominated)X +3731(by)X +3834(the)X +3955(cost)X +4107(of)X +2418 2952(writing)N +2677(the)X +2803(actual)X +3023(\256le)X +3153(to)X +3243(disk.)X +3444(For)X +3583(the)X +3709(large)X +3897(database)X +2418 3040(\(the)N +2564(dictionary\),)X +2957(this)X +3093(completely)X +3470(overwhelmed)X +3927(the)X +4045(sys-)X +2418 3128(tem)N +2570(time.)X +2783(However,)X +3129(for)X +3254(the)X +3383(small)X +3587(data)X +3752(base,)X +3946(we)X +4071(see)X +2418 3216(that)N +2569(differences)X +2958(in)X +3051(both)X +3224(user)X +3389(and)X +3536(system)X +3788(time)X +3960(contri-)X +2418 3304(bute)N +2576(to)X +2658(the)X +2776(superior)X +3059(performance)X +3486(of)X +3573(the)X +3691(new)X +3845(package.)X +2590 3418(The)N +3 f +2764(read)X +1 f +2920(,)X +3 f +2989(verify)X +1 f +3190(,)X +3259(and)X +3 f +3424(sequential)X +1 f +3818(results)X +4075(are)X +2418 3506(deceptive)N +2758(for)X +2883(the)X +3012(small)X +3216(database)X +3524(since)X +3720(the)X +3849(entire)X +4063(test)X +2418 3594(ran)N +2551(in)X +2643(under)X +2856(a)X +2922(second.)X +3215(However,)X +3560(on)X +3669(the)X +3796(larger)X +4013(data-)X +2418 3682(base)N +2590(the)X +3 f +2716(read)X +1 f +2900(and)X +3 f +3044(verify)X +1 f +3273(tests)X +3443(bene\256t)X +3689(from)X +3873(the)X +3999(cach-)X +2418 3770(ing)N +2546(of)X +2639(buckets)X +2910(in)X +2998(the)X +3122(new)X +3282(package)X +3571(to)X +3658(improve)X +3950(perfor-)X +2418 3858(mance)N +2666(by)X +2784(over)X +2965(80%.)X +3169(Since)X +3384(the)X +3519(\256rst)X +3 f +3680(sequential)X +1 f +4063(test)X +2418 3946(does)N +2598(not)X +2733(require)X +2 f +2994(ndbm)X +1 f +3205(to)X +3299(return)X +3523(the)X +3653(data)X +3819(values,)X +4076(the)X +2418 4034(user)N +2573(time)X +2735(is)X +2808(lower)X +3011(than)X +3169(for)X +3283(the)X +3401(new)X +3555(package.)X +3879(However)X +2418 4122(when)N +2613(we)X +2728(require)X +2977(both)X +3139(packages)X +3454(to)X +3536(return)X +3748(data,)X +3922(the)X +4040(new)X +2418 4210(package)N +2702(excels)X +2923(in)X +3005(all)X +3105(three)X +3286(timings.)X +2590 4324(The)N +2773(small)X +3003(database)X +3337(runs)X +3532(so)X +3660(quickly)X +3957(in)X +4076(the)X +2418 4412(memory-resident)N +3000(case)X +3173(that)X +3326(the)X +3457(results)X +3699(are)X +3831(uninterest-)X +2418 4500(ing.)N +2589(However,)X +2933(for)X +3056(the)X +3183(larger)X +3400(database)X +3706(the)X +3833(new)X +3995(pack-)X +2418 4588(age)N +2567(pays)X +2751(a)X +2824(small)X +3033(penalty)X +3305(in)X +3403(system)X +3661(time)X +3839(because)X +4130(it)X +2418 4676(limits)N +2636(its)X +2748(main)X +2944(memory)X +3247(utilization)X +3607(and)X +3759(swaps)X +3991(pages)X +2418 4764(out)N +2550(to)X +2642(temporary)X +3002(storage)X +3264(in)X +3356(the)X +3484(\256le)X +3616(system)X +3868(while)X +4076(the)X +2 f +2418 4852(hsearch)N +1 f +2698(package)X +2988(requires)X +3273(that)X +3419(the)X +3543(application)X +3924(allocate)X +2418 4940(enough)N +2692(space)X +2909(for)X +3041(all)X +3159(key/data)X +3468(pair.)X +3670(However,)X +4022(even)X +2418 5028(with)N +2600(the)X +2738(system)X +3000(time)X +3182(penalty,)X +3477(the)X +3614(resulting)X +3933(elapsed)X +2418 5116(time)N +2580(improves)X +2898(by)X +2998(over)X +3161(50%.)X +3 f +432 5960(10)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +11 p +%%Page: 11 11 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +10 f +908 454(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +1379 546(hash)N +1652(ndbm)X +1950(%change)X +1 f +10 f +908 550(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 642(CREATE)N +10 f +908 646(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 738(user)N +1424(6.4)X +1671(12.2)X +2073(48)X +1157 826(sys)N +1384(32.5)X +1671(34.7)X +2113(6)X +3 f +1006 914(elapsed)N +10 f +1310 922(c)N +890(c)Y +810(c)Y +730(c)Y +3 f +1384 914(90.4)N +10 f +1581 922(c)N +890(c)Y +810(c)Y +730(c)Y +3 f +1671 914(99.6)N +10 f +1883 922(c)N +890(c)Y +810(c)Y +730(c)Y +3 f +2113 914(9)N +1 f +10 f +908 910(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +908 926(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 1010(READ)N +10 f +908 1014(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 1106(user)N +1424(3.4)X +1711(6.1)X +2073(44)X +1157 1194(sys)N +1424(1.2)X +1671(15.3)X +2073(92)X +3 f +1006 1282(elapsed)N +10 f +1310 1290(c)N +1258(c)Y +1178(c)Y +1098(c)Y +3 f +1424 1282(4.0)N +10 f +1581 1290(c)N +1258(c)Y +1178(c)Y +1098(c)Y +3 f +1671 1282(21.2)N +10 f +1883 1290(c)N +1258(c)Y +1178(c)Y +1098(c)Y +3 f +2073 1282(81)N +1 f +10 f +908 1278(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +908 1294(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 1378(VERIFY)N +10 f +908 1382(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 1474(user)N +1424(3.5)X +1711(6.3)X +2073(44)X +1157 1562(sys)N +1424(1.2)X +1671(15.3)X +2073(92)X +3 f +1006 1650(elapsed)N +10 f +1310 1658(c)N +1626(c)Y +1546(c)Y +1466(c)Y +3 f +1424 1650(4.0)N +10 f +1581 1658(c)N +1626(c)Y +1546(c)Y +1466(c)Y +3 f +1671 1650(21.2)N +10 f +1883 1658(c)N +1626(c)Y +1546(c)Y +1466(c)Y +3 f +2073 1650(81)N +1 f +10 f +908 1646(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +908 1662(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 1746(SEQUENTIAL)N +10 f +908 1750(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 1842(user)N +1424(2.7)X +1711(1.9)X +2046(-42)X +1157 1930(sys)N +1424(0.7)X +1711(3.9)X +2073(82)X +3 f +1006 2018(elapsed)N +10 f +1310 2026(c)N +1994(c)Y +1914(c)Y +1834(c)Y +3 f +1424 2018(3.0)N +10 f +1581 2026(c)N +1994(c)Y +1914(c)Y +1834(c)Y +3 f +1711 2018(5.0)N +10 f +1883 2026(c)N +1994(c)Y +1914(c)Y +1834(c)Y +3 f +2073 2018(40)N +1 f +10 f +908 2014(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +908 2030(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 2114(SEQUENTIAL)N +1467(\(with)X +1656(data)X +1810(retrieval\))X +10 f +908 2118(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 2210(user)N +1424(2.7)X +1711(8.2)X +2073(67)X +1157 2298(sys)N +1424(0.7)X +1711(4.3)X +2073(84)X +3 f +1006 2386(elapsed)N +1424(3.0)X +1671(12.0)X +2073(75)X +1 f +10 f +908 2390(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +899 2394(c)N +2378(c)Y +2298(c)Y +2218(c)Y +2138(c)Y +2058(c)Y +1978(c)Y +1898(c)Y +1818(c)Y +1738(c)Y +1658(c)Y +1578(c)Y +1498(c)Y +1418(c)Y +1338(c)Y +1258(c)Y +1178(c)Y +1098(c)Y +1018(c)Y +938(c)Y +858(c)Y +778(c)Y +698(c)Y +618(c)Y +538(c)Y +1310 2394(c)N +2362(c)Y +2282(c)Y +2202(c)Y +1581 2394(c)N +2362(c)Y +2282(c)Y +2202(c)Y +1883 2394(c)N +2362(c)Y +2282(c)Y +2202(c)Y +2278 2394(c)N +2378(c)Y +2298(c)Y +2218(c)Y +2138(c)Y +2058(c)Y +1978(c)Y +1898(c)Y +1818(c)Y +1738(c)Y +1658(c)Y +1578(c)Y +1498(c)Y +1418(c)Y +1338(c)Y +1258(c)Y +1178(c)Y +1098(c)Y +1018(c)Y +938(c)Y +858(c)Y +778(c)Y +698(c)Y +618(c)Y +538(c)Y +905 2574(i)N +930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +1318 2666(hash)N +1585(hsearch)X +1953(%change)X +1 f +10 f +905 2670(i)N +930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +945 2762(CREATE/READ)N +10 f +905 2766(i)N +930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1064 2858(user)N +1343(6.6)X +1642(17.2)X +2096(62)X +1096 2946(sys)N +1343(1.1)X +1682(0.3)X +2029(-266)X +3 f +945 3034(elapsed)N +1343(7.8)X +1642(17.0)X +2096(54)X +1 f +10 f +905 3038(i)N +930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +896 3050(c)N +2978(c)Y +2898(c)Y +2818(c)Y +2738(c)Y +2658(c)Y +1249 3034(c)N +3010(c)Y +2930(c)Y +2850(c)Y +1520 3034(c)N +3010(c)Y +2930(c)Y +2850(c)Y +1886 3034(c)N +3010(c)Y +2930(c)Y +2850(c)Y +2281 3050(c)N +2978(c)Y +2898(c)Y +2818(c)Y +2738(c)Y +2658(c)Y +3 f +720 3174(Figure)N +967(8a:)X +1 f +1094(Timing)X +1349(results)X +1578(for)X +1692(the)X +1810(dictionary)X +2155(database.)X +10 f +720 3262 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +1407 3504(Conclusion)N +1 f +892 3636(This)N +1063(paper)X +1271(has)X +1407(presented)X +1744(the)X +1871(design,)X +2129(implemen-)X +720 3724(tation)N +928(and)X +1070(performance)X +1503(of)X +1596(a)X +1658(new)X +1818(hashing)X +2093(package)X +2382(for)X +720 3812(UNIX.)N +993(The)X +1150(new)X +1316(package)X +1612(provides)X +1919(a)X +1986(superset)X +2280(of)X +2378(the)X +720 3900(functionality)N +1159(of)X +1255(existing)X +1537(hashing)X +1815(packages)X +2139(and)X +2284(incor-)X +720 3988(porates)N +975(additional)X +1318(features)X +1596(such)X +1766(as)X +1855(large)X +2038(key)X +2176(handling,)X +720 4076(user)N +876(de\256ned)X +1134(hash)X +1302(functions,)X +1641(multiple)X +1928(hash)X +2096(tables,)X +2324(vari-)X +720 4164(able)N +894(sized)X +1099(pages,)X +1342(and)X +1498(linear)X +1721(hashing.)X +2050(In)X +2156(nearly)X +2396(all)X +720 4252(cases,)N +954(the)X +1096(new)X +1274(package)X +1582(provides)X +1902(improved)X +2252(perfor-)X +720 4340(mance)N +974(on)X +1098(the)X +1240(order)X +1454(of)X +1565(50-80%)X +1863(for)X +2001(the)X +2142(workloads)X +720 4428(shown.)N +990(Applications)X +1420(such)X +1588(as)X +1676(the)X +1794(loader,)X +2035(compiler,)X +2360(and)X +720 4516(mail,)N +921(which)X +1156(currently)X +1485(implement)X +1866(their)X +2051(own)X +2227(hashing)X +720 4604(routines,)N +1032(should)X +1279(be)X +1389(modi\256ed)X +1706(to)X +1801(use)X +1941(the)X +2072(generic)X +2342(rou-)X +720 4692(tines.)N +892 4806(This)N +1087(hashing)X +1389(package)X +1705(is)X +1810(one)X +1978(access)X +2236(method)X +720 4894(which)N +953(is)X +1043(part)X +1205(of)X +1309(a)X +1382(generic)X +1656(database)X +1970(access)X +2212(package)X +720 4982(being)N +955(developed)X +1342(at)X +1457(the)X +1612(University)X +2007(of)X +2131(California,)X +720 5070(Berkeley.)N +1089(It)X +1177(will)X +1340(include)X +1614(a)X +1688(btree)X +1887(access)X +2131(method)X +2409(as)X +720 5158(well)N +916(as)X +1041(\256xed)X +1259(and)X +1433(variable)X +1750(length)X +2007(record)X +2270(access)X +720 5246(methods)N +1024(in)X +1119(addition)X +1414(to)X +1509(the)X +1640(hashed)X +1896(support)X +2168(presented)X +720 5334(here.)N +948(All)X +1099(of)X +1215(the)X +1361(access)X +1615(methods)X +1934(are)X +2081(based)X +2312(on)X +2440(a)X +720 5422(key/data)N +1037(pair)X +1207(interface)X +1533(and)X +1693(appear)X +1952(identical)X +2272(to)X +2378(the)X +720 5510(application)N +1121(layer,)X +1347(allowing)X +1671(application)X +2071(implementa-)X +720 5598(tions)N +906(to)X +999(be)X +1106(largely)X +1360(independent)X +1783(of)X +1881(the)X +2010(database)X +2318(type.)X +720 5686(The)N +873(package)X +1165(is)X +1246(expected)X +1560(to)X +1650(be)X +1754(an)X +1858(integral)X +2131(part)X +2284(of)X +2378(the)X +2706 538(4.4BSD)N +3006(system,)X +3293(with)X +3479(various)X +3759(standard)X +4075(applications)X +2706 626(such)N +2879(as)X +2972(more\(1\),)X +3277(sort\(1\))X +3517(and)X +3659(vi\(1\))X +3841(based)X +4050(on)X +4156(it.)X +4266(While)X +2706 714(the)N +2833(current)X +3089(design)X +3326(does)X +3501(not)X +3631(support)X +3899(multi-user)X +4256(access)X +2706 802(or)N +2804(transactions,)X +3238(they)X +3407(could)X +3616(be)X +3723(incorporated)X +4159(relatively)X +2706 890(easily.)N +10 f +2894 938(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +3365 1030(hash)N +3638(ndbm)X +3936(%change)X +1 f +10 f +2894 1034(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 1126(CREATE)N +10 f +2894 1130(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 1222(user)N +3390(0.2)X +3677(0.4)X +4079(50)X +3143 1310(sys)N +3390(0.1)X +3677(1.0)X +4079(90)X +3 f +2992 1398(elapsed)N +10 f +3296 1406(c)N +1374(c)Y +1294(c)Y +1214(c)Y +3 f +3390 1398(0)N +10 f +3567 1406(c)N +1374(c)Y +1294(c)Y +1214(c)Y +3 f +3677 1398(3.2)N +10 f +3869 1406(c)N +1374(c)Y +1294(c)Y +1214(c)Y +3 f +4039 1398(100)N +1 f +10 f +2894 1394(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2894 1410(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 1494(READ)N +10 f +2894 1498(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 1590(user)N +3390(0.1)X +3677(0.1)X +4119(0)X +3143 1678(sys)N +3390(0.1)X +3677(0.4)X +4079(75)X +3 f +2992 1766(elapsed)N +10 f +3296 1774(c)N +1742(c)Y +1662(c)Y +1582(c)Y +3 f +3390 1766(0.0)N +10 f +3567 1774(c)N +1742(c)Y +1662(c)Y +1582(c)Y +3 f +3677 1766(0.0)N +10 f +3869 1774(c)N +1742(c)Y +1662(c)Y +1582(c)Y +3 f +4119 1766(0)N +1 f +10 f +2894 1762(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2894 1778(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 1862(VERIFY)N +10 f +2894 1866(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 1958(user)N +3390(0.1)X +3677(0.2)X +4079(50)X +3143 2046(sys)N +3390(0.1)X +3677(0.3)X +4079(67)X +3 f +2992 2134(elapsed)N +10 f +3296 2142(c)N +2110(c)Y +2030(c)Y +1950(c)Y +3 f +3390 2134(0.0)N +10 f +3567 2142(c)N +2110(c)Y +2030(c)Y +1950(c)Y +3 f +3677 2134(0.0)N +10 f +3869 2142(c)N +2110(c)Y +2030(c)Y +1950(c)Y +3 f +4119 2134(0)N +1 f +10 f +2894 2130(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2894 2146(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 2230(SEQUENTIAL)N +10 f +2894 2234(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 2326(user)N +3390(0.1)X +3677(0.0)X +4012(-100)X +3143 2414(sys)N +3390(0.1)X +3677(0.1)X +4119(0)X +3 f +2992 2502(elapsed)N +10 f +3296 2510(c)N +2478(c)Y +2398(c)Y +2318(c)Y +3 f +3390 2502(0.0)N +10 f +3567 2510(c)N +2478(c)Y +2398(c)Y +2318(c)Y +3 f +3677 2502(0.0)N +10 f +3869 2510(c)N +2478(c)Y +2398(c)Y +2318(c)Y +3 f +4119 2502(0)N +1 f +10 f +2894 2498(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2894 2514(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 2598(SEQUENTIAL)N +3453(\(with)X +3642(data)X +3796(retrieval\))X +10 f +2894 2602(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 2694(user)N +3390(0.1)X +3677(0.1)X +4119(0)X +3143 2782(sys)N +3390(0.1)X +3677(0.1)X +4119(0)X +3 f +2992 2870(elapsed)N +3390(0.0)X +3677(0.0)X +4119(0)X +1 f +10 f +2894 2874(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2885 2878(c)N +2862(c)Y +2782(c)Y +2702(c)Y +2622(c)Y +2542(c)Y +2462(c)Y +2382(c)Y +2302(c)Y +2222(c)Y +2142(c)Y +2062(c)Y +1982(c)Y +1902(c)Y +1822(c)Y +1742(c)Y +1662(c)Y +1582(c)Y +1502(c)Y +1422(c)Y +1342(c)Y +1262(c)Y +1182(c)Y +1102(c)Y +1022(c)Y +3296 2878(c)N +2846(c)Y +2766(c)Y +2686(c)Y +3567 2878(c)N +2846(c)Y +2766(c)Y +2686(c)Y +3869 2878(c)N +2846(c)Y +2766(c)Y +2686(c)Y +4264 2878(c)N +2862(c)Y +2782(c)Y +2702(c)Y +2622(c)Y +2542(c)Y +2462(c)Y +2382(c)Y +2302(c)Y +2222(c)Y +2142(c)Y +2062(c)Y +1982(c)Y +1902(c)Y +1822(c)Y +1742(c)Y +1662(c)Y +1582(c)Y +1502(c)Y +1422(c)Y +1342(c)Y +1262(c)Y +1182(c)Y +1102(c)Y +1022(c)Y +2891 3058(i)N +2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +3304 3150(hash)N +3571(hsearch)X +3939(%change)X +1 f +10 f +2891 3154(i)N +2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2931 3246(CREATE/READ)N +10 f +2891 3250(i)N +2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3050 3342(user)N +3329(0.3)X +3648(0.4)X +4048(25)X +3082 3430(sys)N +3329(0.0)X +3648(0.0)X +4088(0)X +3 f +2931 3518(elapsed)N +3329(0.0)X +3648(0.0)X +4088(0)X +1 f +10 f +2891 3522(i)N +2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2882 3534(c)N +3462(c)Y +3382(c)Y +3302(c)Y +3222(c)Y +3142(c)Y +3235 3518(c)N +3494(c)Y +3414(c)Y +3334(c)Y +3506 3518(c)N +3494(c)Y +3414(c)Y +3334(c)Y +3872 3518(c)N +3494(c)Y +3414(c)Y +3334(c)Y +4267 3534(c)N +3462(c)Y +3382(c)Y +3302(c)Y +3222(c)Y +3142(c)Y +3 f +2706 3658(Figure)N +2953(8b:)X +1 f +3084(Timing)X +3339(results)X +3568(for)X +3682(the)X +3800(password)X +4123(database.)X +10 f +2706 3746 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +3396 3988(References)N +1 f +2706 4120([ATT79])N +3058(AT&T,)X +3358(DBM\(3X\),)X +2 f +3773(Unix)X +3990(Programmer's)X +2878 4208(Manual,)N +3194(Seventh)X +3491(Edition,)X +3793(Volume)X +4085(1)X +1 f +(,)S +4192(January,)X +2878 4296(1979.)N +2706 4472([ATT85])N +3027(AT&T,)X +3296(HSEARCH\(BA_LIB\),)X +2 f +4053(Unix)X +4239(System)X +2878 4560(User's)N +3112(Manual,)X +3401(System)X +3644(V.3)X +1 f +3753(,)X +3793(pp.)X +3913(506-508,)X +4220(1985.)X +2706 4736([BRE73])N +3025(Brent,)X +3253(Richard)X +3537(P.,)X +3651(``Reducing)X +4041(the)X +4168(Retrieval)X +2878 4824(Time)N +3071(of)X +3162(Scatter)X +3409(Storage)X +3678(Techniques'',)X +2 f +4146(Commun-)X +2878 4912(ications)N +3175(of)X +3281(the)X +3422(ACM)X +1 f +3591(,)X +3654(Volume)X +3955(16,)X +4098(No.)X +4259(2,)X +4362(pp.)X +2878 5000(105-109,)N +3185(February,)X +3515(1973.)X +2706 5176([BSD86])N +3055(NDBM\(3\),)X +2 f +3469(4.3BSD)X +3775(Unix)X +3990(Programmer's)X +2878 5264(Manual)N +3155(Reference)X +3505(Guide)X +1 f +3701(,)X +3749(University)X +4114(of)X +4208(Califor-)X +2878 5352(nia,)N +3016(Berkeley,)X +3346(1986.)X +2706 5528([ENB88])N +3025(Enbody,)X +3319(R.)X +3417(J.,)X +3533(Du,)X +3676(H.)X +3779(C.,)X +3897(``Dynamic)X +4270(Hash-)X +2878 5616(ing)N +3034(Schemes'',)X +2 f +3427(ACM)X +3630(Computing)X +4019(Surveys)X +1 f +4269(,)X +4322(Vol.)X +2878 5704(20,)N +2998(No.)X +3136(2,)X +3216(pp.)X +3336(85-113,)X +3603(June)X +3770(1988.)X +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4384(11)X + +12 p +%%Page: 12 12 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +1 f +432 538([FAG79])N +776(Ronald)X +1057(Fagin,)X +1308(Jurg)X +1495(Nievergelt,)X +1903(Nicholas)X +604 626(Pippenger,)N +1003(H.)X +1135(Raymond)X +1500(Strong,)X +1787(``Extendible)X +604 714(Hashing)N +901(--)X +985(A)X +1073(Fast)X +1236(Access)X +1493(Method)X +1771(for)X +1894(Dynamic)X +604 802(Files'',)N +2 f +855(ACM)X +1046(Transactions)X +1485(on)X +1586(Database)X +1914(Systems)X +1 f +2168(,)X +604 890(Volume)N +882(4,)X +962(No.)X +1100(3.,)X +1200(September)X +1563(1979,)X +1763(pp)X +1863(315-34)X +432 1066([KNU68],)N +802(Knuth,)X +1064(D.E.,)X +2 f +1273(The)X +1434(Art)X +1577(of)X +1680(Computer)X +2041(Pro-)X +604 1154(gramming)N +971(Vol.)X +1140(3:)X +1245(Sorting)X +1518(and)X +1676(Searching)X +1 f +2001(,)X +2058(sec-)X +604 1242(tions)N +779(6.3-6.4,)X +1046(pp)X +1146(481-550.)X +432 1418([LAR78])N +747(Larson,)X +1011(Per-Ake,)X +1319(``Dynamic)X +1687(Hashing'',)X +2 f +2048(BIT)X +1 f +(,)S +604 1506(Vol.)N +764(18,)X +884(1978,)X +1084(pp.)X +1204(184-201.)X +432 1682([LAR88])N +752(Larson,)X +1021(Per-Ake,)X +1335(``Dynamic)X +1709(Hash)X +1900(Tables'',)X +2 f +604 1770(Communications)N +1183(of)X +1281(the)X +1415(ACM)X +1 f +1584(,)X +1640(Volume)X +1934(31,)X +2070(No.)X +604 1858(4.,)N +704(April)X +893(1988,)X +1093(pp)X +1193(446-457.)X +432 2034([LIT80])N +731(Witold,)X +1013(Litwin,)X +1286(``Linear)X +1590(Hashing:)X +1939(A)X +2036(New)X +604 2122(Tool)N +786(for)X +911(File)X +1065(and)X +1211(Table)X +1424(Addressing'',)X +2 f +1893(Proceed-)X +604 2210(ings)N +761(of)X +847(the)X +969(6th)X +1095(International)X +1540(Conference)X +1933(on)X +2036(Very)X +604 2298(Large)N +815(Databases)X +1 f +1153(,)X +1193(1980.)X +432 2474([NEL90])N +743(Nelson,)X +1011(Philip)X +1222(A.,)X +2 f +1341(Gdbm)X +1558(1.4)X +1679(source)X +1913(distribu-)X +604 2562(tion)N +748(and)X +888(README)X +1 f +1209(,)X +1249(August)X +1500(1990.)X +432 2738([THOM90])N +840(Ken)X +1011(Thompson,)X +1410(private)X +1670(communication,)X +604 2826(Nov.)N +782(1990.)X +432 3002([TOR87])N +790(Torek,)X +1066(C.,)X +1222(``Re:)X +1470(dbm.a)X +1751(and)X +1950(ndbm.a)X +604 3090(archives'',)N +2 f +966(USENET)X +1279(newsgroup)X +1650(comp.unix)X +1 f +2002(1987.)X +432 3266([TOR88])N +760(Torek,)X +1006(C.,)X +1133(``Re:)X +1351(questions)X +1686(regarding)X +2027(data-)X +604 3354(bases)N +826(created)X +1106(with)X +1295(dbm)X +1484(and)X +1647(ndbm)X +1876(routines'')X +2 f +604 3442(USENET)N +937(newsgroup)X +1328(comp.unix.questions)X +1 f +1982(,)X +2041(June)X +604 3530(1988.)N +432 3706([WAL84])N +773(Wales,)X +1018(R.,)X +1135(``Discussion)X +1564(of)X +1655("dbm")X +1887(data)X +2045(base)X +604 3794(system'',)N +2 f +973(USENET)X +1339(newsgroup)X +1762(unix.wizards)X +1 f +2168(,)X +604 3882(January,)N +894(1984.)X +432 4058([YIG89])N +751(Ozan)X +963(S.)X +1069(Yigit,)X +1294(``How)X +1545(to)X +1648(Roll)X +1826(Your)X +2032(Own)X +604 4146(Dbm/Ndbm'',)N +2 f +1087(unpublished)X +1504(manuscript)X +1 f +(,)S +1910(Toronto,)X +604 4234(July,)N +777(1989)X +3 f +432 5960(12)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +13 p +%%Page: 13 13 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +720 538(Margo)N +960(I.)X +1033(Seltzer)X +1282(is)X +1361(a)X +1423(Ph.D.)X +1631(student)X +1887(in)X +1974(the)X +2097(Department)X +720 626(of)N +823(Electrical)X +1167(Engineering)X +1595(and)X +1747(Computer)X +2102(Sciences)X +2418(at)X +720 714(the)N +850(University)X +1220(of)X +1318(California,)X +1694(Berkeley.)X +2055(Her)X +2207(research)X +720 802(interests)N +1017(include)X +1283(\256le)X +1415(systems,)X +1718(databases,)X +2076(and)X +2221(transac-)X +720 890(tion)N +896(processing)X +1291(systems.)X +1636(She)X +1807(spent)X +2027(several)X +2306(years)X +720 978(working)N +1026(at)X +1123(startup)X +1380(companies)X +1762(designing)X +2112(and)X +2267(imple-)X +720 1066(menting)N +1048(\256le)X +1216(systems)X +1535(and)X +1716(transaction)X +2133(processing)X +720 1154(software)N +1026(and)X +1170(designing)X +1509(microprocessors.)X +2103(Ms.)X +2253(Seltzer)X +720 1242(received)N +1057(her)X +1223(AB)X +1397(in)X +1522(Applied)X +1843(Mathematics)X +2320(from)X +720 1330 0.1953(Harvard/Radcliffe)AN +1325(College)X +1594(in)X +1676(1983.)X +720 1444(In)N +810(her)X +936(spare)X +1129(time,)X +1313(Margo)X +1549(can)X +1683(usually)X +1936(be)X +2034(found)X +2243(prepar-)X +720 1532(ing)N +868(massive)X +1171(quantities)X +1527(of)X +1639(food)X +1831(for)X +1970(hungry)X +2242(hoards,)X +720 1620(studying)N +1022(Japanese,)X +1355(or)X +1449(playing)X +1716(soccer)X +1948(with)X +2116(an)X +2218(exciting)X +720 1708(Bay)N +912(Area)X +1132(Women's)X +1507(Soccer)X +1788(team,)X +2026(the)X +2186(Berkeley)X +720 1796(Bruisers.)N +720 1910(Ozan)N +915(\()X +3 f +942(Oz)X +1 f +1040(\))X +1092(Yigit)X +1281(is)X +1358(currently)X +1672(a)X +1732(software)X +2033(engineer)X +2334(with)X +720 1998(the)N +886(Communications)X +1499(Research)X +1861(and)X +2044(Development)X +720 2086(group,)N +948(Computing)X +1328(Services,)X +1641(York)X +1826(University.)X +2224(His)X +2355(for-)X +720 2174(mative)N +967(years)X +1166(were)X +1352(also)X +1510(spent)X +1708(at)X +1795(York,)X +2009(where)X +2234(he)X +2338(held)X +720 2262(system)N +985(programmer)X +1425(and)X +1583(administrator)X +2052(positions)X +2382(for)X +720 2350(various)N +995(mixtures)X +1314(of)X +1420(of)X +1526(UNIX)X +1765(systems)X +2056(starting)X +2334(with)X +720 2438(Berkeley)N +1031(4.1)X +1151(in)X +1233(1982,)X +1433(while)X +1631(at)X +1709(the)X +1827(same)X +2012(time)X +2174(obtaining)X +720 2526(a)N +776(degree)X +1011(in)X +1093(Computer)X +1433(Science.)X +720 2640(In)N +813(his)X +931(copious)X +1205(free)X +1356(time,)X +1543(Oz)X +1662(enjoys)X +1896(working)X +2188(on)X +2293(what-)X +720 2728(ever)N +890(software)X +1197(looks)X +1400(interesting,)X +1788(which)X +2014(often)X +2209(includes)X +720 2816(language)N +1044(interpreters,)X +1464(preprocessors,)X +1960(and)X +2110(lately,)X +2342(pro-)X +720 2904(gram)N +905(generators)X +1260(and)X +1396(expert)X +1617(systems.)X +720 3018(Oz)N +836(has)X +964(authored)X +1266(several)X +1515(public-domain)X +2003(software)X +2301(tools,)X +720 3106(including)N +1069(an)X +1191(nroff-like)X +1545(text)X +1711(formatter)X +2 f +2056(proff)X +1 f +2257(that)X +2423(is)X +720 3194(apparently)N +1083(still)X +1226(used)X +1397(in)X +1483(some)X +1676(basement)X +2002(PCs.)X +2173(His)X +2307(latest)X +720 3282(obsessions)N +1143(include)X +1460(the)X +1639(incredible)X +2040(programming)X +720 3370(language)N +1030(Scheme,)X +1324(and)X +1460(Chinese)X +1738(Brush)X +1949(painting.)X +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4384(13)X + +14 p +%%Page: 14 14 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 5960(14)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +14 p +%%Trailer +xt + +xs diff --git a/circuitpython/lib/berkeley-db-1.xx/docs/libtp.usenix.ps b/circuitpython/lib/berkeley-db-1.xx/docs/libtp.usenix.ps new file mode 100644 index 0000000..ea821a9 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/docs/libtp.usenix.ps @@ -0,0 +1,12340 @@ +%!PS-Adobe-1.0 +%%Creator: utopia:margo (& Seltzer,608-13E,8072,) +%%Title: stdin (ditroff) +%%CreationDate: Thu Dec 12 15:32:11 1991 +%%EndComments +% @(#)psdit.pro 1.3 4/15/88 +% lib/psdit.pro -- prolog for psdit (ditroff) files +% Copyright (c) 1984, 1985 Adobe Systems Incorporated. All Rights Reserved. +% last edit: shore Sat Nov 23 20:28:03 1985 +% RCSID: $Header: psdit.pro,v 2.1 85/11/24 12:19:43 shore Rel $ + +% Changed by Edward Wang (edward@ucbarpa.berkeley.edu) to handle graphics, +% 17 Feb, 87. + +/$DITroff 140 dict def $DITroff begin +/fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def +/xi{0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto + /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F + /pagesave save def}def +/PB{save /psv exch def currentpoint translate + resolution 72 div dup neg scale 0 0 moveto}def +/PE{psv restore}def +/arctoobig 90 def /arctoosmall .05 def +/m1 matrix def /m2 matrix def /m3 matrix def /oldmat matrix def +/tan{dup sin exch cos div}def +/point{resolution 72 div mul}def +/dround {transform round exch round exch itransform}def +/xT{/devname exch def}def +/xr{/mh exch def /my exch def /resolution exch def}def +/xp{}def +/xs{docsave restore end}def +/xt{}def +/xf{/fontname exch def /slotno exch def fontnames slotno get fontname eq not + {fonts slotno fontname findfont put fontnames slotno fontname put}if}def +/xH{/fontheight exch def F}def +/xS{/fontslant exch def F}def +/s{/fontsize exch def /fontheight fontsize def F}def +/f{/fontnum exch def F}def +/F{fontheight 0 le{/fontheight fontsize def}if + fonts fontnum get fontsize point 0 0 fontheight point neg 0 0 m1 astore + fontslant 0 ne{1 0 fontslant tan 1 0 0 m2 astore m3 concatmatrix}if + makefont setfont .04 fontsize point mul 0 dround pop setlinewidth}def +/X{exch currentpoint exch pop moveto show}def +/N{3 1 roll moveto show}def +/Y{exch currentpoint pop exch moveto show}def +/S{show}def +/ditpush{}def/ditpop{}def +/AX{3 -1 roll currentpoint exch pop moveto 0 exch ashow}def +/AN{4 2 roll moveto 0 exch ashow}def +/AY{3 -1 roll currentpoint pop exch moveto 0 exch ashow}def +/AS{0 exch ashow}def +/MX{currentpoint exch pop moveto}def +/MY{currentpoint pop exch moveto}def +/MXY{moveto}def +/cb{pop}def % action on unknown char -- nothing for now +/n{}def/w{}def +/p{pop showpage pagesave restore /pagesave save def}def +/Dt{/Dlinewidth exch def}def 1 Dt +/Ds{/Ddash exch def}def -1 Ds +/Di{/Dstipple exch def}def 1 Di +/Dsetlinewidth{2 Dlinewidth mul setlinewidth}def +/Dsetdash{Ddash 4 eq{[8 12]}{Ddash 16 eq{[32 36]} + {Ddash 20 eq{[32 12 8 12]}{[]}ifelse}ifelse}ifelse 0 setdash}def +/Dstroke{gsave Dsetlinewidth Dsetdash 1 setlinecap stroke grestore + currentpoint newpath moveto}def +/Dl{rlineto Dstroke}def +/arcellipse{/diamv exch def /diamh exch def oldmat currentmatrix pop + currentpoint translate 1 diamv diamh div scale /rad diamh 2 div def + currentpoint exch rad add exch rad -180 180 arc oldmat setmatrix}def +/Dc{dup arcellipse Dstroke}def +/De{arcellipse Dstroke}def +/Da{/endv exch def /endh exch def /centerv exch def /centerh exch def + /cradius centerv centerv mul centerh centerh mul add sqrt def + /eradius endv endv mul endh endh mul add sqrt def + /endang endv endh atan def + /startang centerv neg centerh neg atan def + /sweep startang endang sub dup 0 lt{360 add}if def + sweep arctoobig gt + {/midang startang sweep 2 div sub def /midrad cradius eradius add 2 div def + /midh midang cos midrad mul def /midv midang sin midrad mul def + midh neg midv neg endh endv centerh centerv midh midv Da + Da} + {sweep arctoosmall ge + {/controldelt 1 sweep 2 div cos sub 3 sweep 2 div sin mul div 4 mul def + centerv neg controldelt mul centerh controldelt mul + endv neg controldelt mul centerh add endh add + endh controldelt mul centerv add endv add + centerh endh add centerv endv add rcurveto Dstroke} + {centerh endh add centerv endv add rlineto Dstroke} + ifelse} + ifelse}def +/Dpatterns[ +[%cf[widthbits] +[8<0000000000000010>] +[8<0411040040114000>] +[8<0204081020408001>] +[8<0000103810000000>] +[8<6699996666999966>] +[8<0000800100001008>] +[8<81c36666c3810000>] +[8<0f0e0c0800000000>] +[8<0000000000000010>] +[8<0411040040114000>] +[8<0204081020408001>] +[8<0000001038100000>] +[8<6699996666999966>] +[8<0000800100001008>] +[8<81c36666c3810000>] +[8<0f0e0c0800000000>] +[8<0042660000246600>] +[8<0000990000990000>] +[8<0804020180402010>] +[8<2418814242811824>] +[8<6699996666999966>] +[8<8000000008000000>] +[8<00001c3e363e1c00>] +[8<0000000000000000>] +[32<00000040000000c00000004000000040000000e0000000000000000000000000>] +[32<00000000000060000000900000002000000040000000f0000000000000000000>] +[32<000000000000000000e0000000100000006000000010000000e0000000000000>] +[32<00000000000000002000000060000000a0000000f00000002000000000000000>] +[32<0000000e0000000000000000000000000000000f000000080000000e00000001>] +[32<0000090000000600000000000000000000000000000007000000080000000e00>] +[32<00010000000200000004000000040000000000000000000000000000000f0000>] +[32<0900000006000000090000000600000000000000000000000000000006000000>]] +[%ug +[8<0000020000000000>] +[8<0000020000002000>] +[8<0004020000002000>] +[8<0004020000402000>] +[8<0004060000402000>] +[8<0004060000406000>] +[8<0006060000406000>] +[8<0006060000606000>] +[8<00060e0000606000>] +[8<00060e000060e000>] +[8<00070e000060e000>] +[8<00070e000070e000>] +[8<00070e020070e000>] +[8<00070e020070e020>] +[8<04070e020070e020>] +[8<04070e024070e020>] +[8<04070e064070e020>] +[8<04070e064070e060>] +[8<06070e064070e060>] +[8<06070e066070e060>] +[8<06070f066070e060>] +[8<06070f066070f060>] +[8<060f0f066070f060>] +[8<060f0f0660f0f060>] +[8<060f0f0760f0f060>] +[8<060f0f0760f0f070>] +[8<0e0f0f0760f0f070>] +[8<0e0f0f07e0f0f070>] +[8<0e0f0f0fe0f0f070>] +[8<0e0f0f0fe0f0f0f0>] +[8<0f0f0f0fe0f0f0f0>] +[8<0f0f0f0ff0f0f0f0>] +[8<1f0f0f0ff0f0f0f0>] +[8<1f0f0f0ff1f0f0f0>] +[8<1f0f0f8ff1f0f0f0>] +[8<1f0f0f8ff1f0f0f8>] +[8<9f0f0f8ff1f0f0f8>] +[8<9f0f0f8ff9f0f0f8>] +[8<9f0f0f9ff9f0f0f8>] +[8<9f0f0f9ff9f0f0f9>] +[8<9f8f0f9ff9f0f0f9>] +[8<9f8f0f9ff9f8f0f9>] +[8<9f8f1f9ff9f8f0f9>] +[8<9f8f1f9ff9f8f1f9>] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8]] +[%mg +[8<8000000000000000>] +[8<0822080080228000>] +[8<0204081020408001>] +[8<40e0400000000000>] +[8<66999966>] +[8<8001000010080000>] +[8<81c36666c3810000>] +[8] +[16<07c00f801f003e007c00f800f001e003c007800f001f003e007c00f801f003e0>] +[16<1f000f8007c003e001f000f8007c003e001f800fc007e003f001f8007c003e00>] +[8] +[16<0040008001000200040008001000200040008000000100020004000800100020>] +[16<0040002000100008000400020001800040002000100008000400020001000080>] +[16<1fc03fe07df0f8f8f07de03fc01f800fc01fe03ff07df8f87df03fe01fc00f80>] +[8<80>] +[8<8040201000000000>] +[8<84cc000048cc0000>] +[8<9900009900000000>] +[8<08040201804020100800020180002010>] +[8<2418814242811824>] +[8<66999966>] +[8<8000000008000000>] +[8<70f8d8f870000000>] +[8<0814224180402010>] +[8] +[8<018245aa45820100>] +[8<221c224180808041>] +[8<88000000>] +[8<0855800080550800>] +[8<2844004482440044>] +[8<0810204080412214>] +[8<00>]]]def +/Dfill{ + transform /maxy exch def /maxx exch def + transform /miny exch def /minx exch def + minx maxx gt{/minx maxx /maxx minx def def}if + miny maxy gt{/miny maxy /maxy miny def def}if + Dpatterns Dstipple 1 sub get exch 1 sub get + aload pop /stip exch def /stipw exch def /stiph 128 def + /imatrix[stipw 0 0 stiph 0 0]def + /tmatrix[stipw 0 0 stiph 0 0]def + /minx minx cvi stiph idiv stiph mul def + /miny miny cvi stipw idiv stipw mul def + gsave eoclip 0 setgray + miny stiph maxy{ + tmatrix exch 5 exch put + minx stipw maxx{ + tmatrix exch 4 exch put tmatrix setmatrix + stipw stiph true imatrix {stip} imagemask + }for + }for + grestore +}def +/Dp{Dfill Dstroke}def +/DP{Dfill currentpoint newpath moveto}def +end + +/ditstart{$DITroff begin + /nfonts 60 def % NFONTS makedev/ditroff dependent! + /fonts[nfonts{0}repeat]def + /fontnames[nfonts{()}repeat]def +/docsave save def +}def + +% character outcalls +/oc{ + /pswid exch def /cc exch def /name exch def + /ditwid pswid fontsize mul resolution mul 72000 div def + /ditsiz fontsize resolution mul 72 div def + ocprocs name known{ocprocs name get exec}{name cb}ifelse +}def +/fractm [.65 0 0 .6 0 0] def +/fraction{ + /fden exch def /fnum exch def gsave /cf currentfont def + cf fractm makefont setfont 0 .3 dm 2 copy neg rmoveto + fnum show rmoveto currentfont cf setfont(\244)show setfont fden show + grestore ditwid 0 rmoveto +}def +/oce{grestore ditwid 0 rmoveto}def +/dm{ditsiz mul}def +/ocprocs 50 dict def ocprocs begin +(14){(1)(4)fraction}def +(12){(1)(2)fraction}def +(34){(3)(4)fraction}def +(13){(1)(3)fraction}def +(23){(2)(3)fraction}def +(18){(1)(8)fraction}def +(38){(3)(8)fraction}def +(58){(5)(8)fraction}def +(78){(7)(8)fraction}def +(sr){gsave 0 .06 dm rmoveto(\326)show oce}def +(is){gsave 0 .15 dm rmoveto(\362)show oce}def +(->){gsave 0 .02 dm rmoveto(\256)show oce}def +(<-){gsave 0 .02 dm rmoveto(\254)show oce}def +(==){gsave 0 .05 dm rmoveto(\272)show oce}def +(uc){gsave currentpoint 400 .009 dm mul add translate + 8 -8 scale ucseal oce}def +end + +% an attempt at a PostScript FONT to implement ditroff special chars +% this will enable us to +% cache the little buggers +% generate faster, more compact PS out of psdit +% confuse everyone (including myself)! +50 dict dup begin +/FontType 3 def +/FontName /DIThacks def +/FontMatrix [.001 0 0 .001 0 0] def +/FontBBox [-260 -260 900 900] def% a lie but ... +/Encoding 256 array def +0 1 255{Encoding exch /.notdef put}for +Encoding + dup 8#040/space put %space + dup 8#110/rc put %right ceil + dup 8#111/lt put %left top curl + dup 8#112/bv put %bold vert + dup 8#113/lk put %left mid curl + dup 8#114/lb put %left bot curl + dup 8#115/rt put %right top curl + dup 8#116/rk put %right mid curl + dup 8#117/rb put %right bot curl + dup 8#120/rf put %right floor + dup 8#121/lf put %left floor + dup 8#122/lc put %left ceil + dup 8#140/sq put %square + dup 8#141/bx put %box + dup 8#142/ci put %circle + dup 8#143/br put %box rule + dup 8#144/rn put %root extender + dup 8#145/vr put %vertical rule + dup 8#146/ob put %outline bullet + dup 8#147/bu put %bullet + dup 8#150/ru put %rule + dup 8#151/ul put %underline + pop +/DITfd 100 dict def +/BuildChar{0 begin + /cc exch def /fd exch def + /charname fd /Encoding get cc get def + /charwid fd /Metrics get charname get def + /charproc fd /CharProcs get charname get def + charwid 0 fd /FontBBox get aload pop setcachedevice + 2 setlinejoin 40 setlinewidth + newpath 0 0 moveto gsave charproc grestore + end}def +/BuildChar load 0 DITfd put +/CharProcs 50 dict def +CharProcs begin +/space{}def +/.notdef{}def +/ru{500 0 rls}def +/rn{0 840 moveto 500 0 rls}def +/vr{0 800 moveto 0 -770 rls}def +/bv{0 800 moveto 0 -1000 rls}def +/br{0 840 moveto 0 -1000 rls}def +/ul{0 -140 moveto 500 0 rls}def +/ob{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath stroke}def +/bu{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath fill}def +/sq{80 0 rmoveto currentpoint dround newpath moveto + 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath stroke}def +/bx{80 0 rmoveto currentpoint dround newpath moveto + 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath fill}def +/ci{500 360 rmoveto currentpoint newpath 333 0 360 arc + 50 setlinewidth stroke}def + +/lt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 add exch s4 a4p stroke}def +/lb{0 800 moveto 0 -550 rlineto currx -200 2cx s4 add exch s4 a4p stroke}def +/rt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 sub exch s4 a4p stroke}def +/rb{0 800 moveto 0 -500 rlineto currx -200 2cx s4 sub exch s4 a4p stroke}def +/lk{0 800 moveto 0 300 -300 300 s4 arcto pop pop 1000 sub + 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def +/rk{0 800 moveto 0 300 s2 300 s4 arcto pop pop 1000 sub + 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def +/lf{0 800 moveto 0 -1000 rlineto s4 0 rls}def +/rf{0 800 moveto 0 -1000 rlineto s4 neg 0 rls}def +/lc{0 -200 moveto 0 1000 rlineto s4 0 rls}def +/rc{0 -200 moveto 0 1000 rlineto s4 neg 0 rls}def +end + +/Metrics 50 dict def Metrics begin +/.notdef 0 def +/space 500 def +/ru 500 def +/br 0 def +/lt 416 def +/lb 416 def +/rt 416 def +/rb 416 def +/lk 416 def +/rk 416 def +/rc 416 def +/lc 416 def +/rf 416 def +/lf 416 def +/bv 416 def +/ob 350 def +/bu 350 def +/ci 750 def +/bx 750 def +/sq 750 def +/rn 500 def +/ul 500 def +/vr 0 def +end + +DITfd begin +/s2 500 def /s4 250 def /s3 333 def +/a4p{arcto pop pop pop pop}def +/2cx{2 copy exch}def +/rls{rlineto stroke}def +/currx{currentpoint pop}def +/dround{transform round exch round exch itransform} def +end +end +/DIThacks exch definefont pop +ditstart +(psc)xT +576 1 1 xr +1(Times-Roman)xf 1 f +2(Times-Italic)xf 2 f +3(Times-Bold)xf 3 f +4(Times-BoldItalic)xf 4 f +5(Helvetica)xf 5 f +6(Helvetica-Bold)xf 6 f +7(Courier)xf 7 f +8(Courier-Bold)xf 8 f +9(Symbol)xf 9 f +10(DIThacks)xf 10 f +10 s +1 f +xi +%%EndProlog + +%%Page: 1 1 +10 s 10 xH 0 xS 1 f +3 f +14 s +1205 1206(LIBTP:)N +1633(Portable,)X +2100(M)X +2206(odular)X +2551(Transactions)X +3202(for)X +3374(UNIX)X +1 f +11 s +3661 1162(1)N +2 f +12 s +2182 1398(Margo)N +2467(Seltzer)X +2171 1494(Michael)N +2511(Olson)X +1800 1590(University)N +2225(of)X +2324(California,)X +2773(Berkeley)X +3 f +2277 1878(Abstract)N +1 f +10 s +755 2001(Transactions)N +1198(provide)X +1475(a)X +1543(useful)X +1771(programming)X +2239(paradigm)X +2574(for)X +2700(maintaining)X +3114(logical)X +3364(consistency,)X +3790(arbitrating)X +4156(con-)X +555 2091(current)N +808(access,)X +1059(and)X +1200(managing)X +1540(recovery.)X +1886(In)X +1977(traditional)X +2330(UNIX)X +2555(systems,)X +2852(the)X +2974(only)X +3140(easy)X +3307(way)X +3465(of)X +3556(using)X +3753(transactions)X +4160(is)X +4237(to)X +555 2181(purchase)N +876(a)X +947(database)X +1258(system.)X +1554(Such)X +1748(systems)X +2035(are)X +2168(often)X +2367(slow,)X +2572(costly,)X +2817(and)X +2967(may)X +3139(not)X +3275(provide)X +3554(the)X +3686(exact)X +3890(functionality)X +555 2271(desired.)N +848(This)X +1011(paper)X +1210(presents)X +1493(the)X +1611(design,)X +1860(implementation,)X +2402(and)X +2538(performance)X +2965(of)X +3052(LIBTP,)X +3314(a)X +3370(simple,)X +3623(non-proprietary)X +4147(tran-)X +555 2361(saction)N +809(library)X +1050(using)X +1249(the)X +1373(4.4BSD)X +1654(database)X +1957(access)X +2189(routines)X +2473(\()X +3 f +2500(db)X +1 f +2588(\(3\)\).)X +2775(On)X +2899(a)X +2961(conventional)X +3401(transaction)X +3779(processing)X +4148(style)X +555 2451(benchmark,)N +959(its)X +1061(performance)X +1495(is)X +1575(approximately)X +2065(85%)X +2239(that)X +2386(of)X +2480(the)X +2604(database)X +2907(access)X +3139(routines)X +3423(without)X +3693(transaction)X +4071(protec-)X +555 2541(tion,)N +725(200%)X +938(that)X +1084(of)X +1177(using)X +3 f +1376(fsync)X +1 f +1554(\(2\))X +1674(to)X +1761(commit)X +2030(modi\256cations)X +2490(to)X +2577(disk,)X +2755(and)X +2896(125%)X +3108(that)X +3253(of)X +3345(a)X +3406(commercial)X +3810(relational)X +4138(data-)X +555 2631(base)N +718(system.)X +3 f +555 2817(1.)N +655(Introduction)X +1 f +755 2940(Transactions)N +1186(are)X +1306(used)X +1474(in)X +1557(database)X +1855(systems)X +2129(to)X +2212(enable)X +2443(concurrent)X +2807(users)X +2992(to)X +3074(apply)X +3272(multi-operation)X +3790(updates)X +4055(without)X +555 3030(violating)N +863(the)X +985(integrity)X +1280(of)X +1371(the)X +1493(database.)X +1814(They)X +2003(provide)X +2271(the)X +2392(properties)X +2736(of)X +2826(atomicity,)X +3171(consistency,)X +3588(isolation,)X +3906(and)X +4045(durabil-)X +555 3120(ity.)N +701(By)X +816(atomicity,)X +1160(we)X +1276(mean)X +1472(that)X +1614(the)X +1734(set)X +1845(of)X +1934(updates)X +2200(comprising)X +2581(a)X +2638(transaction)X +3011(must)X +3187(be)X +3284(applied)X +3541(as)X +3629(a)X +3686(single)X +3898(unit;)X +4085(that)X +4226(is,)X +555 3210(they)N +714(must)X +890(either)X +1094(all)X +1195(be)X +1292(applied)X +1549(to)X +1632(the)X +1751(database)X +2049(or)X +2137(all)X +2238(be)X +2335(absent.)X +2601(Consistency)X +3013(requires)X +3293(that)X +3434(a)X +3491(transaction)X +3864(take)X +4019(the)X +4138(data-)X +555 3300(base)N +725(from)X +908(one)X +1051(logically)X +1358(consistent)X +1704(state)X +1877(to)X +1965(another.)X +2272(The)X +2423(property)X +2721(of)X +2814(isolation)X +3115(requires)X +3400(that)X +3546(concurrent)X +3916(transactions)X +555 3390(yield)N +750(results)X +994(which)X +1225(are)X +1358(indistinguishable)X +1938(from)X +2128(the)X +2260(results)X +2503(which)X +2733(would)X +2967(be)X +3077(obtained)X +3387(by)X +3501(running)X +3784(the)X +3916(transactions)X +555 3480(sequentially.)N +1002(Finally,)X +1268(durability)X +1599(requires)X +1878(that)X +2018(once)X +2190(transactions)X +2593(have)X +2765(been)X +2937(committed,)X +3319(their)X +3486(results)X +3715(must)X +3890(be)X +3986(preserved)X +555 3570(across)N +776(system)X +1018(failures)X +1279([TPCB90].)X +755 3693(Although)N +1080(these)X +1268(properties)X +1612(are)X +1734(most)X +1912(frequently)X +2265(discussed)X +2595(in)X +2680(the)X +2801(context)X +3060(of)X +3150(databases,)X +3501(they)X +3661(are)X +3782(useful)X +4000(program-)X +555 3783(ming)N +750(paradigms)X +1114(for)X +1238(more)X +1433(general)X +1700(purpose)X +1984(applications.)X +2441(There)X +2659(are)X +2788(several)X +3046(different)X +3353(situations)X +3689(where)X +3916(transactions)X +555 3873(can)N +687(be)X +783(used)X +950(to)X +1032(replace)X +1285(current)X +1533(ad-hoc)X +1772(mechanisms.)X +755 3996(One)N +910(situation)X +1206(is)X +1280(when)X +1475(multiple)X +1762(\256les)X +1916(or)X +2004(parts)X +2181(of)X +2269(\256les)X +2422(need)X +2594(to)X +2676(be)X +2772(updated)X +3046(in)X +3128(an)X +3224(atomic)X +3462(fashion.)X +3758(For)X +3889(example,)X +4201(the)X +555 4086(traditional)N +907(UNIX)X +1131(\256le)X +1256(system)X +1501(uses)X +1661(ordering)X +1955(constraints)X +2324(to)X +2408(achieve)X +2676(recoverability)X +3144(in)X +3228(the)X +3348(face)X +3505(of)X +3594(crashes.)X +3893(When)X +4107(a)X +4165(new)X +555 4176(\256le)N +678(is)X +752(created,)X +1026(its)X +1122(inode)X +1321(is)X +1395(written)X +1642(to)X +1724(disk)X +1877(before)X +2103(the)X +2221(new)X +2375(\256le)X +2497(is)X +2570(added)X +2782(to)X +2864(the)X +2982(directory)X +3292(structure.)X +3633(This)X +3795(guarantees)X +4159(that,)X +555 4266(if)N +627(the)X +748(system)X +993(crashes)X +1253(between)X +1544(the)X +1665(two)X +1808(I/O's,)X +2016(the)X +2137(directory)X +2450(does)X +2620(not)X +2744(contain)X +3002(a)X +3060 0.4531(reference)AX +3383(to)X +3467(an)X +3565(invalid)X +3809(inode.)X +4049(In)X +4138(actu-)X +555 4356(ality,)N +741(the)X +863(desired)X +1119(effect)X +1326(is)X +1402(that)X +1545(these)X +1733(two)X +1876(updates)X +2144(have)X +2319(the)X +2440(transactional)X +2873(property)X +3168(of)X +3258(atomicity)X +3583(\(either)X +3816(both)X +3981(writes)X +4200(are)X +555 4446(visible)N +790(or)X +879(neither)X +1124(is\).)X +1266(Rather)X +1501(than)X +1660(building)X +1947(special)X +2191(purpose)X +2466(recovery)X +2769(mechanisms)X +3186(into)X +3331(the)X +3450(\256le)X +3573(system)X +3816(or)X +3904(related)X +4144(tools)X +555 4536(\()N +2 f +582(e.g.)X +3 f +726(fsck)X +1 f +864(\(8\)\),)X +1033(one)X +1177(could)X +1383(use)X +1518(general)X +1783(purpose)X +2064(transaction)X +2443(recovery)X +2752(protocols)X +3077(after)X +3252(system)X +3501(failure.)X +3778(Any)X +3943(application)X +555 4626(that)N +705(needs)X +918(to)X +1010(keep)X +1192(multiple,)X +1508(related)X +1757(\256les)X +1920(\(or)X +2044(directories\))X +2440(consistent)X +2790(should)X +3032(do)X +3141(so)X +3241(using)X +3443(transactions.)X +3895(Source)X +4147(code)X +555 4716(control)N +805(systems,)X +1101(such)X +1271(as)X +1361(RCS)X +1534(and)X +1673(SCCS,)X +1910(should)X +2146(use)X +2276(transaction)X +2651(semantics)X +2990(to)X +3075(allow)X +3276(the)X +3397(``checking)X +3764(in'')X +3903(of)X +3992(groups)X +4232(of)X +555 4806(related)N +801(\256les.)X +1001(In)X +1095(this)X +1237(way,)X +1418(if)X +1493(the)X +1617 0.2841(``check-in'')AX +2028(fails,)X +2212(the)X +2336(transaction)X +2714(may)X +2878(be)X +2980(aborted,)X +3267(backing)X +3547(out)X +3675(the)X +3799(partial)X +4030(``check-)X +555 4896(in'')N +691(leaving)X +947(the)X +1065(source)X +1295(repository)X +1640(in)X +1722(a)X +1778(consistent)X +2118(state.)X +755 5019(A)N +842(second)X +1094(situation)X +1398(where)X +1624(transactions)X +2036(can)X +2177(be)X +2282(used)X +2458(to)X +2549(replace)X +2811(current)X +3068(ad-hoc)X +3316(mechanisms)X +3741(is)X +3822(in)X +3912(applications)X +555 5109(where)N +776(concurrent)X +1144(updates)X +1413(to)X +1499(a)X +1559(shared)X +1793(\256le)X +1919(are)X +2042(desired,)X +2318(but)X +2444(there)X +2629(is)X +2706(logical)X +2948(consistency)X +3345(of)X +3435(the)X +3556(data)X +3713(which)X +3932(needs)X +4138(to)X +4223(be)X +555 5199(preserved.)N +928(For)X +1059(example,)X +1371(when)X +1565(the)X +1683(password)X +2006(\256le)X +2128(is)X +2201(updated,)X +2495(\256le)X +2617(locking)X +2877(is)X +2950(used)X +3117(to)X +3199(disallow)X +3490(concurrent)X +3854(access.)X +4120(Tran-)X +555 5289(saction)N +804(semantics)X +1142(on)X +1244(the)X +1364(password)X +1689(\256les)X +1844(would)X +2066(allow)X +2266(concurrent)X +2632(updates,)X +2919(while)X +3119(preserving)X +3479(the)X +3598(logical)X +3837(consistency)X +4232(of)X +555 5379(the)N +681(password)X +1012(database.)X +1357(Similarly,)X +1702(UNIX)X +1930(utilities)X +2196(which)X +2419(rewrite)X +2674(\256les)X +2834(face)X +2996(a)X +3059(potential)X +3366(race)X +3528(condition)X +3857(between)X +4152(their)X +555 5469(rewriting)N +871(a)X +929(\256le)X +1053(and)X +1191(another)X +1453(process)X +1715(reading)X +1977(the)X +2096(\256le.)X +2259(For)X +2391(example,)X +2704(the)X +2823(compiler)X +3129(\(more)X +3342(precisely,)X +3673(the)X +3792(assembler\))X +4161(may)X +8 s +10 f +555 5541(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5619(1)N +8 s +763 5644(To)N +850(appear)X +1035(in)X +1101(the)X +2 f +1195(Proceedings)X +1530(of)X +1596(the)X +1690(1992)X +1834(Winter)X +2024(Usenix)X +1 f +2201(,)X +2233(San)X +2345(Francisco,)X +2625(CA,)X +2746(January)X +2960(1992.)X + +2 p +%%Page: 2 2 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +555 630(have)N +737(to)X +829(rewrite)X +1087(a)X +1152(\256le)X +1283(to)X +1374(which)X +1599(it)X +1672(has)X +1808(write)X +2002(permission)X +2382(in)X +2473(a)X +2538(directory)X +2857(to)X +2948(which)X +3173(it)X +3246(does)X +3422(not)X +3553(have)X +3734(write)X +3928(permission.)X +555 720(While)N +779(the)X +904(``.o'')X +1099(\256le)X +1228(is)X +1308(being)X +1513(written,)X +1787(another)X +2055(utility)X +2272(such)X +2446(as)X +3 f +2540(nm)X +1 f +2651(\(1\))X +2772(or)X +3 f +2866(ar)X +1 f +2942(\(1\))X +3063(may)X +3228(read)X +3394(the)X +3519(\256le)X +3648(and)X +3791(produce)X +4077(invalid)X +555 810(results)N +790(since)X +981(the)X +1105(\256le)X +1233(has)X +1366(not)X +1494(been)X +1672(completely)X +2054(written.)X +2347(Currently,)X +2700(some)X +2895(utilities)X +3160(use)X +3293(special)X +3542(purpose)X +3821(code)X +3998(to)X +4085(handle)X +555 900(such)N +722(cases)X +912(while)X +1110(others)X +1326(ignore)X +1551(the)X +1669(problem)X +1956(and)X +2092(force)X +2278(users)X +2463(to)X +2545(live)X +2685(with)X +2847(the)X +2965(consequences.)X +755 1023(In)N +845(this)X +983(paper,)X +1205(we)X +1322(present)X +1577(a)X +1635(simple)X +1870(library)X +2106(which)X +2324(provides)X +2622(transaction)X +2996(semantics)X +3334(\(atomicity,)X +3705(consistency,)X +4121(isola-)X +555 1113(tion,)N +720(and)X +857(durability\).)X +1236(The)X +1382(4.4BSD)X +1658(database)X +1956(access)X +2182(methods)X +2473(have)X +2645(been)X +2817(modi\256ed)X +3121(to)X +3203(use)X +3330(this)X +3465(library,)X +3719(optionally)X +4063(provid-)X +555 1203(ing)N +682(shared)X +917(buffer)X +1139(management)X +1574(between)X +1867(applications,)X +2298(locking,)X +2582(and)X +2722(transaction)X +3098(semantics.)X +3478(Any)X +3640(UNIX)X +3865(program)X +4161(may)X +555 1293(transaction)N +930(protect)X +1176(its)X +1274(data)X +1430(by)X +1532(requesting)X +1888(transaction)X +2262(protection)X +2609(with)X +2773(the)X +3 f +2893(db)X +1 f +2981(\(3\))X +3097(library)X +3333(or)X +3422(by)X +3524(adding)X +3764(appropriate)X +4152(calls)X +555 1383(to)N +646(the)X +773(transaction)X +1154(manager,)X +1480(buffer)X +1706(manager,)X +2032(lock)X +2199(manager,)X +2525(and)X +2670(log)X +2801(manager.)X +3147(The)X +3301(library)X +3543(routines)X +3829(may)X +3995(be)X +4099(linked)X +555 1473(into)N +708(the)X +834(host)X +995(application)X +1379(and)X +1523(called)X +1743(by)X +1851(subroutine)X +2217(interface,)X +2547(or)X +2642(they)X +2808(may)X +2974(reside)X +3194(in)X +3284(a)X +3348(separate)X +3640(server)X +3865(process.)X +4174(The)X +555 1563(server)N +772(architecture)X +1172(provides)X +1468(for)X +1582(network)X +1865(access)X +2091(and)X +2227(better)X +2430(protection)X +2775(mechanisms.)X +3 f +555 1749(2.)N +655(Related)X +938(Work)X +1 f +755 1872(There)N +1000(has)X +1164(been)X +1373(much)X +1608(discussion)X +1998(in)X +2117(recent)X +2371(years)X +2597(about)X +2831(new)X +3021(transaction)X +3429(models)X +3716(and)X +3888(architectures)X +555 1962 0.1172([SPEC88][NODI90][CHEN91][MOHA91].)AN +2009(Much)X +2220(of)X +2310(this)X +2448(work)X +2636(focuses)X +2900(on)X +3003(new)X +3160(ways)X +3348(to)X +3433(model)X +3656(transactions)X +4062(and)X +4201(the)X +555 2052(interactions)N +953(between)X +1245(them,)X +1449(while)X +1651(the)X +1772(work)X +1960(presented)X +2291(here)X +2453(focuses)X +2717(on)X +2820(the)X +2941(implementation)X +3466(and)X +3605(performance)X +4035(of)X +4125(tradi-)X +555 2142(tional)N +757(transaction)X +1129(techniques)X +1492(\(write-ahead)X +1919(logging)X +2183(and)X +2319(two-phase)X +2669(locking\))X +2956(on)X +3056(a)X +3112(standard)X +3404(operating)X +3727(system)X +3969(\(UNIX\).)X +755 2265(Such)N +947(traditional)X +1308(operating)X +1643(systems)X +1928(are)X +2059(often)X +2256(criticized)X +2587(for)X +2713(their)X +2892(inability)X +3190(to)X +3283(perform)X +3573(transaction)X +3956(processing)X +555 2355(adequately.)N +971([STON81])X +1342(cites)X +1517(three)X +1706(main)X +1894(areas)X +2088(of)X +2183(inadequate)X +2559(support:)X +2849(buffer)X +3074(management,)X +3532(the)X +3658(\256le)X +3788(system,)X +4058(and)X +4201(the)X +555 2445(process)N +823(structure.)X +1191(These)X +1410(arguments)X +1771(are)X +1897(summarized)X +2316(in)X +2405(table)X +2587(one.)X +2769(Fortunately,)X +3184(much)X +3388(has)X +3521(changed)X +3815(since)X +4006(1981.)X +4232(In)X +555 2535(the)N +683(area)X +848(of)X +945(buffer)X +1172(management,)X +1632(most)X +1817(UNIX)X +2048(systems)X +2331(provide)X +2606(the)X +2734(ability)X +2968(to)X +3060(memory)X +3357(map)X +3525(\256les,)X +3708(thus)X +3870(obviating)X +4201(the)X +555 2625(need)N +734(for)X +855(a)X +918(copy)X +1101(between)X +1396(kernel)X +1624(and)X +1766(user)X +1926(space.)X +2171(If)X +2251(a)X +2313(database)X +2616(system)X +2864(is)X +2943(going)X +3151(to)X +3239(use)X +3372(the)X +3496(\256le)X +3624(system)X +3872(buffer)X +4095(cache,)X +555 2715(then)N +719(a)X +781(system)X +1029(call)X +1171(is)X +1250(required.)X +1584(However,)X +1924(if)X +1998(buffering)X +2322(is)X +2400(provided)X +2710(at)X +2793(user)X +2952(level)X +3133(using)X +3331(shared)X +3566(memory,)X +3878(as)X +3970(in)X +4057(LIBTP,)X +555 2805(buffer)N +776(management)X +1210(is)X +1287(only)X +1452(as)X +1542(slow)X +1716(as)X +1806(access)X +2035(to)X +2120(shared)X +2353(memory)X +2643(and)X +2782(any)X +2921(replacement)X +3337(algorithm)X +3671(may)X +3832(be)X +3931(used.)X +4121(Since)X +555 2895(multiple)N +849(processes)X +1185(can)X +1325(access)X +1559(the)X +1685(shared)X +1923(data,)X +2105(prefetching)X +2499(may)X +2665(be)X +2769(accomplished)X +3238(by)X +3346(separate)X +3638(processes)X +3973(or)X +4067(threads)X +555 2985(whose)N +782(sole)X +932(purpose)X +1207(is)X +1281(to)X +1364(prefetch)X +1649(pages)X +1853(and)X +1990(wait)X +2149(on)X +2250(them.)X +2471(There)X +2680(is)X +2754(still)X +2894(no)X +2995(way)X +3150(to)X +3233(enforce)X +3496(write)X +3682(ordering)X +3975(other)X +4161(than)X +555 3075(keeping)N +829(pages)X +1032(in)X +1114(user)X +1268(memory)X +1555(and)X +1691(using)X +1884(the)X +3 f +2002(fsync)X +1 f +2180(\(3\))X +2294(system)X +2536(call)X +2672(to)X +2754(perform)X +3033(synchronous)X +3458(writes.)X +755 3198(In)N +845(the)X +966(area)X +1124(of)X +1214(\256le)X +1339(systems,)X +1635(the)X +1756(fast)X +1895(\256le)X +2020(system)X +2265(\(FFS\))X +2474([MCKU84])X +2871(allows)X +3103(allocation)X +3442(in)X +3527(units)X +3704(up)X +3806(to)X +3890(64KBytes)X +4232(as)X +555 3288(opposed)N +846(to)X +932(the)X +1054(4KByte)X +1327(and)X +1466(8KByte)X +1738(\256gures)X +1979(quoted)X +2220(in)X +2305([STON81].)X +2711(The)X +2859(measurements)X +3341(in)X +3426(this)X +3564(paper)X +3766(were)X +3946(taken)X +4143(from)X +555 3378(an)N +655(8KByte)X +928(FFS,)X +1104(but)X +1230(as)X +1320(LIBTP)X +1565(runs)X +1726(exclusively)X +2114(in)X +2199(user)X +2356(space,)X +2578(there)X +2762(is)X +2838(nothing)X +3105(to)X +3190(prevent)X +3454(it)X +3521(from)X +3700(being)X +3901(run)X +4031(on)X +4134(other)X +555 3468(UNIX)N +776(compatible)X +1152(\256le)X +1274(systems)X +1547(\(e.g.)X +1710(log-structured)X +2180([ROSE91],)X +2558(extent-based,)X +3004(or)X +3091(multi-block)X +3484([SELT91]\).)X +755 3591(Finally,)N +1029(with)X +1199(regard)X +1433(to)X +1523(the)X +1648(process)X +1916(structure,)X +2244(neither)X +2494(context)X +2757(switch)X +2993(time)X +3162(nor)X +3296(scheduling)X +3670(around)X +3920(semaphores)X +555 3681(seems)N +785(to)X +881(affect)X +1099(the)X +1231(system)X +1487(performance.)X +1968(However,)X +2317(the)X +2449(implementation)X +2984(of)X +3084(semaphores)X +3496(can)X +3641(impact)X +3892(performance)X +555 3771(tremendously.)N +1051(This)X +1213(is)X +1286(discussed)X +1613(in)X +1695(more)X +1880(detail)X +2078(in)X +2160(section)X +2407(4.3.)X +755 3894(The)N +908(Tuxedo)X +1181(system)X +1431(from)X +1615(AT&T)X +1861(is)X +1941(a)X +2004(transaction)X +2383(manager)X +2687(which)X +2910(coordinates)X +3307(distributed)X +3676(transaction)X +4055(commit)X +555 3984(from)N +738(a)X +801(variety)X +1051(of)X +1145(different)X +1449(local)X +1632(transaction)X +2011(managers.)X +2386(At)X +2493(this)X +2634(time,)X +2822(LIBTP)X +3070(does)X +3243(not)X +3371(have)X +3549(its)X +3650(own)X +3814(mechanism)X +4205(for)X +555 4074(distributed)N +942(commit)X +1231(processing,)X +1639(but)X +1786(could)X +2009(be)X +2130(used)X +2322(as)X +2434(a)X +2515(local)X +2716(transaction)X +3113(agent)X +3331(by)X +3455(systems)X +3752(such)X +3943(as)X +4054(Tuxedo)X +555 4164([ANDR89].)N +10 f +863 4393(i)N +870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +903 4483(Buffer)N +1133(Management)X +10 f +1672(g)X +1 f +1720(Data)X +1892(must)X +2067(be)X +2163(copied)X +2397(between)X +2685(kernel)X +2906(space)X +3105(and)X +3241(user)X +3395(space.)X +10 f +1672 4573(g)N +1 f +1720(Buffer)X +1950(pool)X +2112(access)X +2338(is)X +2411(too)X +2533(slow.)X +10 f +1672 4663(g)N +1 f +1720(There)X +1928(is)X +2001(no)X +2101(way)X +2255(to)X +2337(request)X +2589(prefetch.)X +10 f +1672 4753(g)N +1 f +1720(Replacement)X +2159(is)X +2232(usually)X +2483(LRU)X +2663(which)X +2879(may)X +3037(be)X +3133(suboptimal)X +3508(for)X +3622(databases.)X +10 f +1672 4843(g)N +1 f +1720(There)X +1928(is)X +2001(no)X +2101(way)X +2255(to)X +2337(guarantee)X +2670(write)X +2855(ordering.)X +10 f +863 4853(i)N +870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +903 4943(File)N +1047(System)X +10 f +1672(g)X +1 f +1720(Allocation)X +2078(is)X +2151(done)X +2327(in)X +2409(small)X +2602(blocks)X +2831(\(usually)X +3109(4K)X +3227(or)X +3314(8K\).)X +10 f +1672 5033(g)N +1 f +1720(Logical)X +1985(organization)X +2406(of)X +2493(\256les)X +2646(is)X +2719(redundantly)X +3122(expressed.)X +10 f +863 5043(i)N +870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +903 5133(Process)N +1168(Structure)X +10 f +1672(g)X +1 f +1720(Context)X +1993(switching)X +2324(and)X +2460(message)X +2752(passing)X +3012(are)X +3131(too)X +3253(slow.)X +10 f +1672 5223(g)N +1 f +1720(A)X +1798(process)X +2059(may)X +2217(be)X +2313(descheduled)X +2730(while)X +2928(holding)X +3192(a)X +3248(semaphore.)X +10 f +863 5233(i)N +870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +863(c)X +5193(c)Y +5113(c)Y +5033(c)Y +4953(c)Y +4873(c)Y +4793(c)Y +4713(c)Y +4633(c)Y +4553(c)Y +4473(c)Y +3990 5233(c)N +5193(c)Y +5113(c)Y +5033(c)Y +4953(c)Y +4873(c)Y +4793(c)Y +4713(c)Y +4633(c)Y +4553(c)Y +4473(c)Y +3 f +1156 5446(Table)N +1371(One:)X +1560(Shortcomings)X +2051(of)X +2138(UNIX)X +2363(transaction)X +2770(support)X +3056(cited)X +3241(in)X +3327([STON81].)X + +3 p +%%Page: 3 3 +10 s 10 xH 0 xS 3 f +1 f +755 630(The)N +901(transaction)X +1274(architecture)X +1675(presented)X +2004(in)X +2087([YOUN91])X +2474(is)X +2548(very)X +2712(similar)X +2955(to)X +3038(that)X +3179(implemented)X +3618(in)X +3701(the)X +3820(LIBTP.)X +4103(While)X +555 720([YOUN91])N +947(presents)X +1236(a)X +1298(model)X +1524(for)X +1644(providing)X +1981(transaction)X +2359(services,)X +2663(this)X +2803(paper)X +3007(focuses)X +3273(on)X +3378(the)X +3501(implementation)X +4028(and)X +4169(per-)X +555 810(formance)N +881(of)X +970(a)X +1028(particular)X +1358(system.)X +1642(In)X +1731(addition,)X +2034(we)X +2149(provide)X +2415(detailed)X +2690(comparisons)X +3116(with)X +3279(alternative)X +3639(solutions:)X +3970(traditional)X +555 900(UNIX)N +776(services)X +1055(and)X +1191(commercial)X +1590(database)X +1887(management)X +2317(systems.)X +3 f +555 1086(3.)N +655(Architecture)X +1 f +755 1209(The)N +906(library)X +1146(is)X +1224(designed)X +1534(to)X +1621(provide)X +1891(well)X +2054(de\256ned)X +2315(interfaces)X +2653(to)X +2740(the)X +2863(services)X +3147(required)X +3440(for)X +3559(transaction)X +3936(processing.)X +555 1299(These)N +777(services)X +1066(are)X +1195(recovery,)X +1527(concurrency)X +1955(control,)X +2232(and)X +2378(the)X +2506(management)X +2946(of)X +3043(shared)X +3283(data.)X +3487(First)X +3663(we)X +3787(will)X +3941(discuss)X +4201(the)X +555 1389(design)N +795(tradeoffs)X +1112(in)X +1205(the)X +1334(selection)X +1650(of)X +1748(recovery,)X +2081(concurrency)X +2510(control,)X +2787(and)X +2933(buffer)X +3160(management)X +3600(implementations,)X +4183(and)X +555 1479(then)N +713(we)X +827(will)X +971(present)X +1223(the)X +1341(overall)X +1584(library)X +1818(architecture)X +2218(and)X +2354(module)X +2614(descriptions.)X +3 f +555 1665(3.1.)N +715(Design)X +966(Tradeoffs)X +1 f +3 f +555 1851(3.1.1.)N +775(Crash)X +1004(Recovery)X +1 f +755 1974(The)N +909(recovery)X +1220(protocol)X +1516(is)X +1598(responsible)X +1992(for)X +2115(providing)X +2455(the)X +2582(transaction)X +2963(semantics)X +3308(discussed)X +3644(earlier.)X +3919(There)X +4136(are)X +4263(a)X +555 2064(wide)N +739(range)X +946(of)X +1041(recovery)X +1351(protocols)X +1677(available)X +1995([HAER83],)X +2395(but)X +2525(we)X +2647(can)X +2786(crudely)X +3054(divide)X +3281(them)X +3468(into)X +3619(two)X +3766(main)X +3953(categories.)X +555 2154(The)N +706(\256rst)X +856(category)X +1159(records)X +1422(all)X +1528(modi\256cations)X +1989(to)X +2077(the)X +2201(database)X +2504(in)X +2592(a)X +2653(separate)X +2942(\256le,)X +3089(and)X +3230(uses)X +3393(this)X +3533(\256le)X +3660(\(log\))X +3841(to)X +3928(back)X +4105(out)X +4232(or)X +555 2244(reapply)N +825(these)X +1019(modi\256cations)X +1483(if)X +1561(a)X +1626(transaction)X +2007(aborts)X +2232(or)X +2328(the)X +2455(system)X +2706(crashes.)X +3012(We)X +3153(call)X +3298(this)X +3442(set)X +3560(the)X +3 f +3687(logging)X +3963(protocols)X +1 f +4279(.)X +555 2334(The)N +703(second)X +949(category)X +1249(avoids)X +1481(the)X +1602(use)X +1732(of)X +1822(a)X +1881(log)X +2006(by)X +2109(carefully)X +2418(controlling)X +2792(when)X +2989(data)X +3146(are)X +3268(written)X +3518(to)X +3603(disk.)X +3799(We)X +3934(call)X +4073(this)X +4210(set)X +555 2424(the)N +3 f +673(non-logging)X +1096(protocols)X +1 f +1412(.)X +755 2547(Non-logging)N +1185(protocols)X +1504(hold)X +1666(dirty)X +1837(buffers)X +2085(in)X +2167(main)X +2347(memory)X +2634(or)X +2721(temporary)X +3071(\256les)X +3224(until)X +3390(commit)X +3654(and)X +3790(then)X +3948(force)X +4134(these)X +555 2637(pages)N +769(to)X +862(disk)X +1026(at)X +1115(transaction)X +1498(commit.)X +1813(While)X +2040(we)X +2165(can)X +2308(use)X +2446(temporary)X +2807(\256les)X +2971(to)X +3064(hold)X +3237(dirty)X +3418(pages)X +3631(that)X +3781(may)X +3949(need)X +4131(to)X +4223(be)X +555 2727(evicted)N +810(from)X +988(memory)X +1277(during)X +1508(a)X +1566(long-running)X +2006(transaction,)X +2400(the)X +2520(only)X +2684(user-level)X +3023(mechanism)X +3410(to)X +3494(force)X +3682(pages)X +3887(to)X +3971(disk)X +4126(is)X +4201(the)X +3 f +555 2817(fsync)N +1 f +733(\(2\))X +850(system)X +1095(call.)X +1274(Unfortunately,)X +3 f +1767(fsync)X +1 f +1945(\(2\))X +2062(is)X +2138(an)X +2237(expensive)X +2581(system)X +2826(call)X +2965(in)X +3050(that)X +3193(it)X +3260(forces)X +3480(all)X +3583(pages)X +3789(of)X +3879(a)X +3938(\256le)X +4062(to)X +4146(disk,)X +555 2907(and)N +691(transactions)X +1094(that)X +1234(manage)X +1504(more)X +1689(than)X +1847(one)X +1983(\256le)X +2105(must)X +2280(issue)X +2460(one)X +2596(call)X +2732(per)X +2855(\256le.)X +755 3030(In)N +853(addition,)X +3 f +1166(fsync)X +1 f +1344(\(2\))X +1469(provides)X +1776(no)X +1887(way)X +2051(to)X +2143(control)X +2400(the)X +2528(order)X +2728(in)X +2820(which)X +3046(dirty)X +3227(pages)X +3440(are)X +3569(written)X +3826(to)X +3918(disk.)X +4121(Since)X +555 3120(non-logging)N +976(protocols)X +1304(must)X +1489(sometimes)X +1861(order)X +2061(writes)X +2287(carefully)X +2603([SULL92],)X +2987(they)X +3155(are)X +3284(dif\256cult)X +3567(to)X +3659(implement)X +4030(on)X +4139(Unix)X +555 3210(systems.)N +868(As)X +977(a)X +1033(result,)X +1251(we)X +1365(have)X +1537(chosen)X +1780(to)X +1862(implement)X +2224(a)X +2280(logging)X +2544(protocol.)X +755 3333(Logging)N +1050(protocols)X +1372(may)X +1534(be)X +1634(categorized)X +2029(based)X +2236(on)X +2340(how)X +2502(information)X +2904(is)X +2981(logged)X +3223(\(physically)X +3602(or)X +3692(logically\))X +4022(and)X +4161(how)X +555 3423(much)N +767(is)X +854(logged)X +1106(\(before)X +1373(images,)X +1654(after)X +1836(images)X +2097(or)X +2198(both\).)X +2441(In)X +3 f +2542(physical)X +2855(logging)X +1 f +3103(,)X +3157(images)X +3417(of)X +3517(complete)X +3844(physical)X +4144(units)X +555 3513(\(pages)N +786(or)X +874(buffers\))X +1150(are)X +1270(recorded,)X +1593(while)X +1792(in)X +3 f +1875(logical)X +2118(logging)X +1 f +2387(a)X +2444(description)X +2820(of)X +2907(the)X +3025(operation)X +3348(is)X +3421(recorded.)X +3763(Therefore,)X +4121(while)X +555 3603(we)N +675(may)X +839(record)X +1071(entire)X +1280(pages)X +1489(in)X +1577(a)X +1639(physical)X +1932(log,)X +2080(we)X +2200(need)X +2378(only)X +2546(record)X +2777(the)X +2900(records)X +3162(being)X +3365(modi\256ed)X +3674(in)X +3761(a)X +3822(logical)X +4065(log.)X +4232(In)X +555 3693(fact,)N +718(physical)X +1006(logging)X +1271(can)X +1404(be)X +1501(thought)X +1766(of)X +1854(as)X +1942(a)X +1999(special)X +2243(case)X +2403(of)X +2491(logical)X +2730(logging,)X +3015(since)X +3201(the)X +3320 0.3125(``records'')AX +3686(that)X +3827(we)X +3942(log)X +4065(in)X +4148(logi-)X +555 3783(cal)N +673(logging)X +941(might)X +1151(be)X +1251(physical)X +1542(pages.)X +1789(Since)X +1991(logical)X +2233(logging)X +2501(is)X +2578(both)X +2743(more)X +2931(space-ef\256cient)X +3423(and)X +3562(more)X +3750(general,)X +4030(we)X +4147(have)X +555 3873(chosen)N +798(it)X +862(for)X +976(our)X +1103(logging)X +1367(protocol.)X +755 3996(In)N +3 f +843(before-image)X +1315(logging)X +1 f +1563(,)X +1604(we)X +1719(log)X +1842(a)X +1899(copy)X +2076(of)X +2164(the)X +2283(data)X +2438(before)X +2665(the)X +2784(update,)X +3039(while)X +3238(in)X +3 f +3321(after-image)X +3739(logging)X +1 f +3987(,)X +4027(we)X +4141(log)X +4263(a)X +555 4086(copy)N +740(of)X +836(the)X +963(data)X +1126(after)X +1303(the)X +1429(update.)X +1711(If)X +1793(we)X +1915(log)X +2045(only)X +2215(before-images,)X +2723(then)X +2889(there)X +3078(is)X +3159(suf\256cient)X +3485(information)X +3891(in)X +3981(the)X +4107(log)X +4237(to)X +555 4176(allow)N +761(us)X +860(to)X +3 f +950(undo)X +1 f +1150(the)X +1276(transaction)X +1656(\(go)X +1791(back)X +1971(to)X +2061(the)X +2187(state)X +2361(represented)X +2759(by)X +2866(the)X +2991(before-image\).)X +3514(However,)X +3876(if)X +3952(the)X +4077(system)X +555 4266(crashes)N +814(and)X +952(a)X +1010(committed)X +1374(transaction's)X +1806(changes)X +2087(have)X +2261(not)X +2385(reached)X +2658(the)X +2778(disk,)X +2953(we)X +3068(have)X +3241(no)X +3342(means)X +3568(to)X +3 f +3651(redo)X +1 f +3828(the)X +3947(transaction)X +555 4356(\(reapply)N +849(the)X +973(updates\).)X +1311(Therefore,)X +1675(logging)X +1945(only)X +2113(before-images)X +2599(necessitates)X +3004(forcing)X +3262(dirty)X +3439(pages)X +3648(at)X +3732(commit)X +4002(time.)X +4210(As)X +555 4446(mentioned)N +913(above,)X +1145(forcing)X +1397(pages)X +1600(at)X +1678(commit)X +1942(is)X +2015(considered)X +2383(too)X +2505(costly.)X +755 4569(If)N +834(we)X +953(log)X +1080(only)X +1247(after-images,)X +1694(then)X +1857(there)X +2043(is)X +2121(suf\256cient)X +2444(information)X +2847(in)X +2934(the)X +3057(log)X +3184(to)X +3271(allow)X +3474(us)X +3570(to)X +3657(redo)X +3825(the)X +3947(transaction)X +555 4659(\(go)N +687(forward)X +967(to)X +1054(the)X +1177(state)X +1348(represented)X +1743(by)X +1847(the)X +1969(after-image\),)X +2411(but)X +2537(we)X +2655(do)X +2759(not)X +2885(have)X +3061(the)X +3183(information)X +3585(required)X +3877(to)X +3963(undo)X +4147(tran-)X +555 4749(sactions)N +845(which)X +1073(aborted)X +1346(after)X +1526(dirty)X +1709(pages)X +1924(were)X +2113(written)X +2372(to)X +2466(disk.)X +2670(Therefore,)X +3039(logging)X +3314(only)X +3487(after-images)X +3920(necessitates)X +555 4839(holding)N +819(all)X +919(dirty)X +1090(buffers)X +1338(in)X +1420(main)X +1600(memory)X +1887(until)X +2053(commit)X +2317(or)X +2404(writing)X +2655(them)X +2835(to)X +2917(a)X +2973(temporary)X +3323(\256le.)X +755 4962(Since)N +956(neither)X +1202(constraint)X +1541(\(forcing)X +1823(pages)X +2029(on)X +2132(commit)X +2399(or)X +2489(buffering)X +2811(pages)X +3016(until)X +3184(commit\))X +3477(was)X +3624(feasible,)X +3916(we)X +4032(chose)X +4237(to)X +555 5052(log)N +683(both)X +851(before)X +1083(and)X +1225(after)X +1399(images.)X +1672(The)X +1823(only)X +1991(remaining)X +2342(consideration)X +2800(is)X +2879(when)X +3079(changes)X +3363(get)X +3486(written)X +3738(to)X +3825(disk.)X +4023(Changes)X +555 5142(affect)N +764(both)X +931(data)X +1090(pages)X +1298(and)X +1438(the)X +1560(log.)X +1726(If)X +1804(the)X +1926(changed)X +2218(data)X +2376(page)X +2552(is)X +2629(written)X +2880(before)X +3110(the)X +3232(log)X +3358(page,)X +3554(and)X +3694(the)X +3816(system)X +4062(crashes)X +555 5232(before)N +787(the)X +911(log)X +1039(page)X +1217(is)X +1296(written,)X +1569(the)X +1693(log)X +1820(will)X +1969(contain)X +2230(insuf\256cient)X +2615(information)X +3018(to)X +3105(undo)X +3290(the)X +3413(change.)X +3706(This)X +3873(violates)X +4147(tran-)X +555 5322(saction)N +803(semantics,)X +1160(since)X +1346(some)X +1536(changed)X +1825(data)X +1980(pages)X +2184(may)X +2343(not)X +2466(have)X +2638(been)X +2810(written,)X +3077(and)X +3213(the)X +3331(database)X +3628(cannot)X +3862(be)X +3958(restored)X +4237(to)X +555 5412(its)N +650(pre-transaction)X +1152(state.)X +755 5535(The)N +914(log)X +1050(record)X +1290(describing)X +1658(an)X +1768(update)X +2016(must)X +2205(be)X +2315(written)X +2576(to)X +2672(stable)X +2893(storage)X +3159(before)X +3398(the)X +3529(modi\256ed)X +3846(page.)X +4071(This)X +4246(is)X +3 f +555 5625(write-ahead)N +992(logging)X +1 f +1240(.)X +1307(If)X +1388(log)X +1517(records)X +1781(are)X +1907(safely)X +2126(written)X +2380(to)X +2469(disk,)X +2649(data)X +2810(pages)X +3020(may)X +3185(be)X +3288(written)X +3542(at)X +3627(any)X +3770(time)X +3939(afterwards.)X +555 5715(This)N +721(means)X +950(that)X +1094(the)X +1216(only)X +1382(\256le)X +1508(that)X +1652(ever)X +1815(needs)X +2022(to)X +2108(be)X +2208(forced)X +2438(to)X +2524(disk)X +2681(is)X +2758(the)X +2880(log.)X +3046(Since)X +3248(the)X +3370(log)X +3495(is)X +3571(append-only,)X +4015(modi\256ed)X + +4 p +%%Page: 4 4 +10 s 10 xH 0 xS 1 f +3 f +1 f +555 630(pages)N +760(always)X +1005(appear)X +1242(at)X +1322(the)X +1442(end)X +1580(and)X +1718(may)X +1878(be)X +1976(written)X +2224(to)X +2307(disk)X +2461(ef\256ciently)X +2807(in)X +2890(any)X +3027(\256le)X +3150(system)X +3393(that)X +3534(favors)X +3756(sequential)X +4102(order-)X +555 720(ing)N +677(\()X +2 f +704(e.g.)X +1 f +820(,)X +860(FFS,)X +1032(log-structured)X +1502(\256le)X +1624(system,)X +1886(or)X +1973(an)X +2069(extent-based)X +2495(system\).)X +3 f +555 906(3.1.2.)N +775(Concurrency)X +1245(Control)X +1 f +755 1029(The)N +918(concurrency)X +1354(control)X +1619(protocol)X +1923(is)X +2013(responsible)X +2415(for)X +2546(maintaining)X +2965(consistency)X +3376(in)X +3475(the)X +3610(presence)X +3929(of)X +4033(multiple)X +555 1119(accesses.)N +897(There)X +1114(are)X +1242(several)X +1499(alternative)X +1867(solutions)X +2183(such)X +2358(as)X +2453(locking,)X +2741(optimistic)X +3088(concurrency)X +3514(control)X +3769([KUNG81],)X +4183(and)X +555 1209(timestamp)N +912(ordering)X +1208([BERN80].)X +1619(Since)X +1821(optimistic)X +2164(methods)X +2459(and)X +2599(timestamp)X +2956(ordering)X +3252(are)X +3374(generally)X +3696(more)X +3884(complex)X +4183(and)X +555 1299(restrict)N +804(concurrency)X +1228(without)X +1498(eliminating)X +1888(starvation)X +2230(or)X +2323(deadlocks,)X +2690(we)X +2810(chose)X +3018(two-phase)X +3373(locking)X +3638(\(2PL\).)X +3890(Strict)X +4088(2PL)X +4246(is)X +555 1389(suboptimal)N +935(for)X +1054(certain)X +1297(data)X +1455(structures)X +1791(such)X +1962(as)X +2053(B-trees)X +2309(because)X +2588(it)X +2656(can)X +2792(limit)X +2966(concurrency,)X +3408(so)X +3503(we)X +3621(use)X +3752(a)X +3812(special)X +4059(locking)X +555 1479(protocol)N +842(based)X +1045(on)X +1145(one)X +1281(described)X +1609(in)X +1691([LEHM81].)X +755 1602(The)N +901(B-tree)X +1123(locking)X +1384(protocol)X +1672(we)X +1787(implemented)X +2226(releases)X +2502(locks)X +2691(at)X +2769(internal)X +3034(nodes)X +3241(in)X +3323(the)X +3441(tree)X +3582(as)X +3669(it)X +3733(descends.)X +4083(A)X +4161(lock)X +555 1692(on)N +658(an)X +757(internal)X +1025(page)X +1200(is)X +1276(always)X +1522(released)X +1808(before)X +2036(a)X +2094(lock)X +2254(on)X +2356(its)X +2453(child)X +2635(is)X +2710(obtained)X +3008(\(that)X +3177(is,)X +3272(locks)X +3463(are)X +3584(not)X +3 f +3708(coupled)X +1 f +3996([BAY77])X +555 1782(during)N +786(descent\).)X +1116(When)X +1330(a)X +1388(leaf)X +1531(\(or)X +1647(internal\))X +1941(page)X +2115(is)X +2190(split,)X +2369(a)X +2427(write)X +2614(lock)X +2774(is)X +2849(acquired)X +3148(on)X +3250(the)X +3370(parent)X +3593(before)X +3821(the)X +3941(lock)X +4100(on)X +4201(the)X +555 1872(just-split)N +855(page)X +1028(is)X +1102(released)X +1387(\(locks)X +1604(are)X +3 f +1724(coupled)X +1 f +2011(during)X +2241(ascent\).)X +2530(Write)X +2734(locks)X +2924(on)X +3025(internal)X +3291(pages)X +3495(are)X +3615(released)X +3899(immediately)X +555 1962(after)N +723(the)X +841(page)X +1013(is)X +1086(updated,)X +1380(but)X +1502(locks)X +1691(on)X +1791(leaf)X +1932(pages)X +2135(are)X +2254(held)X +2412(until)X +2578(the)X +2696(end)X +2832(of)X +2919(the)X +3037(transaction.)X +755 2085(Since)N +964(locks)X +1164(are)X +1294(released)X +1589(during)X +1828(descent,)X +2119(the)X +2247(structure)X +2558(of)X +2655(the)X +2783(tree)X +2934(may)X +3102(change)X +3360(above)X +3582(a)X +3648(node)X +3834(being)X +4042(used)X +4219(by)X +555 2175(some)N +752(process.)X +1061(If)X +1143(that)X +1291(process)X +1560(must)X +1743(later)X +1914(ascend)X +2161(the)X +2287(tree)X +2435(because)X +2717(of)X +2811(a)X +2874(page)X +3053(split,)X +3237(any)X +3380(such)X +3554(change)X +3809(must)X +3991(not)X +4120(cause)X +555 2265(confusion.)N +938(We)X +1077(use)X +1211(the)X +1336(technique)X +1675(described)X +2010(in)X +2099([LEHM81])X +2487(which)X +2710(exploits)X +2989(the)X +3113(ordering)X +3411(of)X +3504(data)X +3664(on)X +3770(a)X +3832(B-tree)X +4059(page)X +4237(to)X +555 2355(guarantee)N +888(that)X +1028(no)X +1128(process)X +1389(ever)X +1548(gets)X +1697(lost)X +1832(as)X +1919(a)X +1975(result)X +2173(of)X +2260(internal)X +2525(page)X +2697(updates)X +2962(made)X +3156(by)X +3256(other)X +3441(processes.)X +755 2478(If)N +836(a)X +899(transaction)X +1278(that)X +1425(updates)X +1697(a)X +1760(B-tree)X +1988(aborts,)X +2231(the)X +2356(user-visible)X +2757(changes)X +3043(to)X +3131(the)X +3255(tree)X +3402(must)X +3583(be)X +3685(rolled)X +3898(back.)X +4116(How-)X +555 2568(ever,)N +735(changes)X +1015(to)X +1097(the)X +1215(internal)X +1480(nodes)X +1687(of)X +1774(the)X +1892(tree)X +2033(need)X +2205(not)X +2327(be)X +2423(rolled)X +2630(back,)X +2822(since)X +3007(these)X +3192(pages)X +3395(contain)X +3651(no)X +3751(user-visible)X +4145(data.)X +555 2658(When)N +771(rolling)X +1008(back)X +1184(a)X +1244(transaction,)X +1640(we)X +1758(roll)X +1893(back)X +2069(all)X +2173(leaf)X +2318(page)X +2494(updates,)X +2783(but)X +2909(no)X +3013(internal)X +3281(insertions)X +3615(or)X +3705(page)X +3880(splits.)X +4111(In)X +4201(the)X +555 2748(worst)N +759(case,)X +944(this)X +1085(will)X +1235(leave)X +1431(a)X +1493(leaf)X +1640(page)X +1818(less)X +1964(than)X +2128(half)X +2279(full.)X +2456(This)X +2624(may)X +2788(cause)X +2993(poor)X +3166(space)X +3371(utilization,)X +3741(but)X +3869(does)X +4042(not)X +4170(lose)X +555 2838(user)N +709(data.)X +755 2961(Holding)N +1038(locks)X +1228(on)X +1329(leaf)X +1471(pages)X +1675(until)X +1842(transaction)X +2215(commit)X +2480(guarantees)X +2845(that)X +2986(no)X +3087(other)X +3273(process)X +3535(can)X +3668(insert)X +3866(or)X +3953(delete)X +4165(data)X +555 3051(that)N +711(has)X +854(been)X +1042(touched)X +1332(by)X +1448(this)X +1598(process.)X +1914(Rolling)X +2188(back)X +2375(insertions)X +2721(and)X +2872(deletions)X +3196(on)X +3311(leaf)X +3467(pages)X +3685(guarantees)X +4064(that)X +4219(no)X +555 3141(aborted)N +819(updates)X +1087(are)X +1209(ever)X +1371(visible)X +1607(to)X +1692(other)X +1880(transactions.)X +2326(Leaving)X +2612(page)X +2787(splits)X +2978(intact)X +3179(permits)X +3442(us)X +3536(to)X +3621(release)X +3867(internal)X +4134(write)X +555 3231(locks)N +744(early.)X +965(Thus)X +1145(transaction)X +1517(semantics)X +1853(are)X +1972(preserved,)X +2325(and)X +2461(locks)X +2650(are)X +2769(held)X +2927(for)X +3041(shorter)X +3284(periods.)X +755 3354(The)N +901(extra)X +1083(complexity)X +1464(introduced)X +1828(by)X +1929(this)X +2065(locking)X +2326(protocol)X +2614(appears)X +2881(substantial,)X +3264(but)X +3387(it)X +3452(is)X +3525(important)X +3856(for)X +3970(multi-user)X +555 3444(execution.)N +950(The)X +1118(bene\256ts)X +1410(of)X +1520(non-two-phase)X +2040(locking)X +2323(on)X +2446(B-trees)X +2721(are)X +2863(well)X +3044(established)X +3443(in)X +3548(the)X +3689(database)X +4009(literature)X +555 3534([BAY77],)N +899([LEHM81].)X +1320(If)X +1394(a)X +1450(process)X +1711(held)X +1869(locks)X +2058(until)X +2224(it)X +2288(committed,)X +2670(then)X +2828(a)X +2884(long-running)X +3322(update)X +3556(could)X +3754(lock)X +3912(out)X +4034(all)X +4134(other)X +555 3624(transactions)N +967(by)X +1076(preventing)X +1448(any)X +1593(other)X +1787(process)X +2057(from)X +2241(locking)X +2509(the)X +2635(root)X +2792(page)X +2972(of)X +3067(the)X +3193(tree.)X +3382(The)X +3535(B-tree)X +3764(locking)X +4032(protocol)X +555 3714(described)N +884(above)X +1096(guarantees)X +1460(that)X +1600(locks)X +1789(on)X +1889(internal)X +2154(pages)X +2357(are)X +2476(held)X +2634(for)X +2748(extremely)X +3089(short)X +3269(periods,)X +3545(thereby)X +3806(increasing)X +4156(con-)X +555 3804(currency.)N +3 f +555 3990(3.1.3.)N +775(Management)X +1245(of)X +1332(Shared)X +1596(Data)X +1 f +755 4113(Database)N +1075(systems)X +1353(permit)X +1587(many)X +1790(users)X +1980(to)X +2067(examine)X +2364(and)X +2505(update)X +2744(the)X +2866(same)X +3055(data)X +3213(concurrently.)X +3683(In)X +3774(order)X +3968(to)X +4054(provide)X +555 4203(this)N +702(concurrent)X +1078(access)X +1316(and)X +1464(enforce)X +1738(the)X +1868(write-ahead)X +2280(logging)X +2556(protocol)X +2855(described)X +3195(in)X +3289(section)X +3548(3.1.1,)X +3759(we)X +3884(use)X +4022(a)X +4089(shared)X +555 4293(memory)N +848(buffer)X +1071(manager.)X +1414(Not)X +1559(only)X +1726(does)X +1898(this)X +2038(provide)X +2308(the)X +2431(guarantees)X +2800(we)X +2919(require,)X +3192(but)X +3319(a)X +3380(user-level)X +3722(buffer)X +3944(manager)X +4246(is)X +555 4383(frequently)N +916(faster)X +1126(than)X +1295(using)X +1498(the)X +1626(\256le)X +1758(system)X +2010(buffer)X +2237(cache.)X +2491(Reads)X +2717(or)X +2814(writes)X +3040(involving)X +3376(the)X +3504(\256le)X +3636(system)X +3888(buffer)X +4115(cache)X +555 4473(often)N +746(require)X +1000(copying)X +1284(data)X +1444(between)X +1738(user)X +1898(and)X +2040(kernel)X +2266(space)X +2470(while)X +2673(a)X +2734(user-level)X +3076(buffer)X +3298(manager)X +3600(can)X +3737(return)X +3954(pointers)X +4237(to)X +555 4563(data)N +709(pages)X +912(directly.)X +1217(Additionally,)X +1661(if)X +1730(more)X +1915(than)X +2073(one)X +2209(process)X +2470(uses)X +2628(the)X +2746(same)X +2931(page,)X +3123(then)X +3281(fewer)X +3485(copies)X +3710(may)X +3868(be)X +3964(required.)X +3 f +555 4749(3.2.)N +715(Module)X +997(Architecture)X +1 f +755 4872(The)N +913(preceding)X +1262(sections)X +1552(described)X +1892(modules)X +2195(for)X +2321(managing)X +2669(the)X +2799(transaction)X +3183(log,)X +3337(locks,)X +3558(and)X +3706(a)X +3774(cache)X +3990(of)X +4089(shared)X +555 4962(buffers.)N +847(In)X +938(addition,)X +1244(we)X +1362(need)X +1538(to)X +1624(provide)X +1893(functionality)X +2326(for)X +2444(transaction)X +2 f +2819(begin)X +1 f +2997(,)X +2 f +3040(commit)X +1 f +3276(,)X +3319(and)X +2 f +3458(abort)X +1 f +3654(processing,)X +4040(necessi-)X +555 5052(tating)N +769(a)X +837(transaction)X +1221(manager.)X +1570(In)X +1669(order)X +1871(to)X +1965(arbitrate)X +2265(concurrent)X +2641(access)X +2879(to)X +2973(locks)X +3173(and)X +3320(buffers,)X +3599(we)X +3724(include)X +3991(a)X +4058(process)X +555 5142(management)N +995(module)X +1264(which)X +1489(manages)X +1799(a)X +1864(collection)X +2209(of)X +2305(semaphores)X +2713(used)X +2889(to)X +2980(block)X +3187(and)X +3332(release)X +3585(processes.)X +3962(Finally,)X +4237(in)X +555 5232(order)N +752(to)X +841(provide)X +1113(a)X +1176(simple,)X +1436(standard)X +1735(interface)X +2044(we)X +2165(have)X +2344(modi\256ed)X +2655(the)X +2780(database)X +3084(access)X +3317(routines)X +3602(\()X +3 f +3629(db)X +1 f +3717(\(3\)\).)X +3904(For)X +4041(the)X +4165(pur-)X +555 5322(poses)N +758(of)X +850(this)X +990(paper)X +1194(we)X +1313(call)X +1453(the)X +1575(modi\256ed)X +1883(package)X +2171(the)X +3 f +2293(Record)X +2567(Manager)X +1 f +2879(.)X +2943(Figure)X +3176(one)X +3316(shows)X +3540(the)X +3662(main)X +3846(interfaces)X +4183(and)X +555 5412(architecture)N +955(of)X +1042(LIBTP.)X + +5 p +%%Page: 5 5 +10 s 10 xH 0 xS 1 f +3 f +1 f +11 s +1851 1520(log_commit)N +2764 2077(buf_unpin)N +2764 1987(buf_get)N +3633 1408(buf_unpin)N +3633 1319(buf_pin)N +3633 1230(buf_get)N +3 f +17 s +1163 960(Txn)N +1430(M)X +1559(anager)X +2582(Record)X +3040(M)X +3169(anager)X +1 Dt +2363 726 MXY +0 355 Dl +1426 0 Dl +0 -355 Dl +-1426 0 Dl +3255 1616 MXY +0 535 Dl +534 0 Dl +0 -535 Dl +-534 0 Dl +2185 MX +0 535 Dl +535 0 Dl +0 -535 Dl +-535 0 Dl +1116 MX +0 535 Dl +534 0 Dl +0 -535 Dl +-534 0 Dl +726 MY +0 355 Dl +891 0 Dl +0 -355 Dl +-891 0 Dl +1 f +11 s +2207 1297(lock)N +2564 1386(log)N +865(unlock_all)X +1851 1609(log_unroll)N +1650 2508 MXY +0 178 Dl +1605 0 Dl +0 -178 Dl +-1605 0 Dl +1294 1616 MXY +19 -30 Dl +-19 11 Dl +-20 -11 Dl +20 30 Dl +0 -535 Dl +2319 2508 MXY +-22 -30 Dl +4 23 Dl +-18 14 Dl +36 -7 Dl +-936 -357 Dl +3277 2455(sleep_on)N +1405 1616 MXY +36 4 Dl +-18 -13 Dl +1 -22 Dl +-19 31 Dl +1070 -535 Dl +2631 2508 MXY +36 6 Dl +-18 -14 Dl +3 -22 Dl +-21 30 Dl +891 -357 Dl +1426 2455(sleep_on)N +3255 1884 MXY +-31 -20 Dl +11 20 Dl +-11 19 Dl +31 -19 Dl +-535 0 Dl +1554 2366(wake)N +3277(wake)X +2185 1884 MXY +-31 -20 Dl +12 20 Dl +-12 19 Dl +31 -19 Dl +-356 0 Dl +0 -803 Dl +3 f +17 s +1236 1851(Lock)N +1118 2030(M)N +1247(anager)X +2339 1851(Log)N +2187 2030(M)N +2316(anager)X +3333 1851(Buffer)N +3257 2030(M)N +3386(anager)X +3522 1616 MXY +20 -30 Dl +-20 11 Dl +-20 -11 Dl +20 30 Dl +0 -535 Dl +1950 2654(Process)N +2424(M)X +2553(anager)X +2542 1616 MXY +19 -30 Dl +-19 11 Dl +-20 -11 Dl +20 30 Dl +0 -535 Dl +1 f +11 s +2207 1364(unlock)N +2452 2508 MXY +20 -31 Dl +-20 11 Dl +-19 -11 Dl +19 31 Dl +0 -357 Dl +2497 2322(sleep_on)N +2497 2233(wake)N +3 Dt +-1 Ds +3 f +10 s +1790 2830(Figure)N +2037(1:)X +2144(Library)X +2435(module)X +2708(interfaces.)X +1 f +10 f +555 3010(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +3 f +555 3286(3.2.1.)N +775(The)X +928(Log)X +1081(Manager)X +1 f +755 3409(The)N +3 f +907(Log)X +1067(Manager)X +1 f +1406(enforces)X +1706(the)X +1831(write-ahead)X +2238(logging)X +2509(protocol.)X +2843(Its)X +2949(primitive)X +3268(operations)X +3628(are)X +2 f +3753(log)X +1 f +3855(,)X +2 f +3901(log_commit)X +1 f +4279(,)X +2 f +555 3499(log_read)N +1 f +844(,)X +2 f +889(log_roll)X +1 f +1171(and)X +2 f +1312(log_unroll)X +1 f +1649(.)X +1714(The)X +2 f +1864(log)X +1 f +1991(call)X +2132(performs)X +2447(a)X +2508(buffered)X +2806(write)X +2996(of)X +3088(the)X +3211(speci\256ed)X +3520(log)X +3646(record)X +3876(and)X +4016(returns)X +4263(a)X +555 3589(unique)N +809(log)X +947(sequence)X +1278(number)X +1559(\(LSN\).)X +1840(This)X +2017(LSN)X +2203(may)X +2376(then)X +2549(be)X +2660(used)X +2842(to)X +2939(retrieve)X +3220(a)X +3291(record)X +3532(from)X +3723(the)X +3856(log)X +3993(using)X +4201(the)X +2 f +555 3679(log_read)N +1 f +865(call.)X +1042(The)X +2 f +1188(log)X +1 f +1311(interface)X +1614(knows)X +1844(very)X +2008(little)X +2175(about)X +2374(the)X +2493(internal)X +2759(format)X +2993(of)X +3080(the)X +3198(log)X +3320(records)X +3577(it)X +3641(receives.)X +3965(Rather,)X +4219(all)X +555 3769(log)N +681(records)X +942(are)X +1065 0.4028(referenced)AX +1430(by)X +1534(a)X +1594(header)X +1833(structure,)X +2158(a)X +2218(log)X +2344(record)X +2574(type,)X +2756(and)X +2896(a)X +2956(character)X +3276(buffer)X +3497(containing)X +3859(the)X +3981(data)X +4138(to)X +4223(be)X +555 3859(logged.)N +834(The)X +980(log)X +1103(record)X +1330(type)X +1489(is)X +1563(used)X +1731(to)X +1814(call)X +1951(the)X +2070(appropriate)X +2457(redo)X +2621(and)X +2758(undo)X +2939(routines)X +3217(during)X +2 f +3446(abort)X +1 f +3639(and)X +2 f +3775(commit)X +1 f +4031(process-)X +555 3949(ing.)N +721(While)X +941(we)X +1059(have)X +1235(used)X +1406(the)X +3 f +1528(Log)X +1684(Manager)X +1 f +2019(to)X +2104(provide)X +2372(before)X +2601(and)X +2740(after)X +2911(image)X +3130(logging,)X +3417(it)X +3484(may)X +3645(also)X +3797(be)X +3896(used)X +4066(for)X +4183(any)X +555 4039(of)N +642(the)X +760(logging)X +1024(algorithms)X +1386(discussed.)X +755 4162(The)N +2 f +905(log_commit)X +1 f +1308(operation)X +1636(behaves)X +1920(exactly)X +2177(like)X +2322(the)X +2 f +2445(log)X +1 f +2572(operation)X +2900(but)X +3026(guarantees)X +3394(that)X +3538(the)X +3660(log)X +3786(has)X +3917(been)X +4093(forced)X +555 4252(to)N +643(disk)X +802(before)X +1034(returning.)X +1394(A)X +1478(discussion)X +1837(of)X +1930(our)X +2063(commit)X +2333(strategy)X +2613(appears)X +2884(in)X +2971(the)X +3094(implementation)X +3621(section)X +3873(\(section)X +4152(4.2\).)X +2 f +555 4342(Log_unroll)N +1 f +935(reads)X +1126(log)X +1249(records)X +1507(from)X +1684(the)X +1803(log,)X +1946(following)X +2278(backward)X +2611(transaction)X +2983(pointers)X +3261(and)X +3397(calling)X +3635(the)X +3753(appropriate)X +4139(undo)X +555 4432(routines)N +839(to)X +927(implement)X +1295(transaction)X +1673(abort.)X +1904(In)X +1997(a)X +2059(similar)X +2307(manner,)X +2 f +2594(log_roll)X +1 f +2877(reads)X +3073(log)X +3201(records)X +3464(sequentially)X +3877(forward,)X +4178(cal-)X +555 4522(ling)N +699(the)X +817(appropriate)X +1203(redo)X +1366(routines)X +1644(to)X +1726(recover)X +1988(committed)X +2350(transactions)X +2753(after)X +2921(a)X +2977(system)X +3219(crash.)X +3 f +555 4708(3.2.2.)N +775(The)X +928(Buffer)X +1171(Manager)X +1 f +755 4831(The)N +3 f +912(Buffer)X +1167(Manager)X +1 f +1511(uses)X +1681(a)X +1749(pool)X +1923(of)X +2022(shared)X +2264(memory)X +2563(to)X +2657(provide)X +2934(a)X +3002(least-recently-used)X +3641(\(LRU\))X +3886(block)X +4095(cache.)X +555 4921(Although)N +886(the)X +1013(current)X +1270(library)X +1513(provides)X +1818(an)X +1923(LRU)X +2112(cache,)X +2345(it)X +2418(would)X +2647(be)X +2752(simple)X +2994(to)X +3085(add)X +3229(alternate)X +3534(replacement)X +3955(policies)X +4232(as)X +555 5011(suggested)N +903(by)X +1015([CHOU85])X +1408(or)X +1507(to)X +1601(provide)X +1878(multiple)X +2176(buffer)X +2405(pools)X +2610(with)X +2784(different)X +3092(policies.)X +3412(Transactions)X +3853(request)X +4116(pages)X +555 5101(from)N +736(the)X +859(buffer)X +1081(manager)X +1383(and)X +1524(keep)X +1701(them)X +3 f +1886(pinned)X +1 f +2145(to)X +2232(ensure)X +2466(that)X +2610(they)X +2772(are)X +2895(not)X +3021(written)X +3272(to)X +3358(disk)X +3515(while)X +3717(they)X +3879(are)X +4002(in)X +4088(a)X +4148(logi-)X +555 5191(cally)N +732(inconsistent)X +1135(state.)X +1343(When)X +1556(page)X +1729(replacement)X +2143(is)X +2217(necessary,)X +2571(the)X +3 f +2689(Buffer)X +2932(Manager)X +1 f +3264(\256nds)X +3439(an)X +3535(unpinned)X +3853(page)X +4025(and)X +4161(then)X +555 5281(checks)N +794(with)X +956(the)X +3 f +1074(Log)X +1227(Manager)X +1 f +1559(to)X +1641(ensure)X +1871(that)X +2011(the)X +2129(write-ahead)X +2529(protocol)X +2816(is)X +2889(enforced.)X +3 f +555 5467(3.2.3.)N +775(The)X +928(Lock)X +1121(Manager)X +1 f +755 5590(The)N +3 f +901(Lock)X +1095(Manager)X +1 f +1428(supports)X +1720(general)X +1978(purpose)X +2253(locking)X +2514(\(single)X +2753(writer,)X +2986(multiple)X +3273(readers\))X +3553(which)X +3769(is)X +3842(currently)X +4152(used)X +555 5680(to)N +638(provide)X +904(two-phase)X +1254(locking)X +1514(and)X +1650(high)X +1812(concurrency)X +2230(B-tree)X +2451(locking.)X +2751(However,)X +3086(the)X +3204(general)X +3461(purpose)X +3735(nature)X +3956(of)X +4043(the)X +4161(lock)X + +6 p +%%Page: 6 6 +10 s 10 xH 0 xS 1 f +3 f +1 f +555 630(manager)N +857(provides)X +1158(the)X +1281(ability)X +1510(to)X +1597(support)X +1862(a)X +1923(variety)X +2171(of)X +2263(locking)X +2528(protocols.)X +2890(Currently,)X +3241(all)X +3345(locks)X +3538(are)X +3661(issued)X +3885(at)X +3967(the)X +4089(granu-)X +555 720(larity)N +747(of)X +837(a)X +896(page)X +1071(\(the)X +1219(size)X +1367(of)X +1457(a)X +1516(buffer)X +1736(in)X +1821(the)X +1942(buffer)X +2161(pool\))X +2352(which)X +2570(is)X +2645(identi\256ed)X +2969(by)X +3071(two)X +3213(4-byte)X +3440(integers)X +3716(\(a)X +3801(\256le)X +3925(id)X +4009(and)X +4147(page)X +555 810(number\).)N +898(This)X +1071(provides)X +1378(the)X +1507(necessary)X +1851(information)X +2259(to)X +2351(extend)X +2595(the)X +3 f +2723(Lock)X +2926(Manager)X +1 f +3268(to)X +3360(perform)X +3649(hierarchical)X +4059(locking)X +555 900([GRAY76].)N +982(The)X +1133(current)X +1387(implementation)X +1915(does)X +2088(not)X +2216(support)X +2482(locks)X +2677(at)X +2760(other)X +2950(granularities)X +3376(and)X +3517(does)X +3689(not)X +3816(promote)X +4108(locks;)X +555 990(these)N +740(are)X +859(obvious)X +1132(future)X +1344(additions)X +1657(to)X +1739(the)X +1857(system.)X +755 1113(If)N +831(an)X +929(incoming)X +1253(lock)X +1413(request)X +1667(cannot)X +1903(be)X +2001(granted,)X +2284(the)X +2404(requesting)X +2760(process)X +3023(is)X +3098(queued)X +3352(for)X +3467(the)X +3586(lock)X +3745(and)X +3882(descheduled.)X +555 1203(When)N +769(a)X +827(lock)X +987(is)X +1062(released,)X +1368(the)X +1488(wait)X +1647(queue)X +1860(is)X +1934(traversed)X +2250(and)X +2387(any)X +2524(newly)X +2741(compatible)X +3118(locks)X +3308(are)X +3428(granted.)X +3730(Locks)X +3947(are)X +4067(located)X +555 1293(via)N +680(a)X +743(\256le)X +872(and)X +1015(page)X +1194(hash)X +1368(table)X +1551(and)X +1694(are)X +1820(chained)X +2097(both)X +2266(by)X +2373(object)X +2595(and)X +2737(by)X +2843(transaction,)X +3241(facilitating)X +3614(rapid)X +3805(traversal)X +4108(of)X +4201(the)X +555 1383(lock)N +713(table)X +889(during)X +1118(transaction)X +1490(commit)X +1754(and)X +1890(abort.)X +755 1506(The)N +907(primary)X +1188(interfaces)X +1528(to)X +1617(the)X +1742(lock)X +1907(manager)X +2211(are)X +2 f +2337(lock)X +1 f +2471(,)X +2 f +2518(unlock)X +1 f +2732(,)X +2779(and)X +2 f +2922(lock_unlock_all)X +1 f +3434(.)X +2 f +3500(Lock)X +1 f +3682(obtains)X +3939(a)X +4001(new)X +4161(lock)X +555 1596(for)N +680(a)X +747(speci\256c)X +1023(object.)X +1290(There)X +1509(are)X +1638(also)X +1797(two)X +1947(variants)X +2231(of)X +2328(the)X +2 f +2456(lock)X +1 f +2620(request,)X +2 f +2902(lock_upgrade)X +1 f +3373(and)X +2 f +3519(lock_downgrade)X +1 f +4053(,)X +4103(which)X +555 1686(allow)N +755(the)X +875(caller)X +1076(to)X +1160(atomically)X +1519(trade)X +1701(a)X +1758(lock)X +1917(of)X +2005(one)X +2142(type)X +2301(for)X +2416(a)X +2473(lock)X +2632(of)X +2720(another.)X +2 f +3022(Unlock)X +1 f +3275(releases)X +3551(a)X +3608(speci\256c)X +3874(mode)X +4073(of)X +4161(lock)X +555 1776(on)N +655(a)X +711(speci\256c)X +976(object.)X +2 f +1232(Lock_unlock_all)X +1 f +1786(releases)X +2061(all)X +2161(the)X +2279(locks)X +2468(associated)X +2818(with)X +2980(a)X +3036(speci\256c)X +3301(transaction.)X +3 f +555 1962(3.2.4.)N +775(The)X +928(Process)X +1207(Manager)X +1 f +755 2085(The)N +3 f +900(Process)X +1179(Manager)X +1 f +1511(acts)X +1656(as)X +1743(a)X +1799(user-level)X +2136(scheduler)X +2464(to)X +2546(make)X +2740(processes)X +3068(wait)X +3226(on)X +3326(unavailable)X +3716(locks)X +3905(and)X +4041(pending)X +555 2175(buffer)N +778(cache)X +988(I/O.)X +1161(For)X +1297(each)X +1470(process,)X +1756(a)X +1817(semaphore)X +2190(is)X +2268(maintained)X +2649(upon)X +2834(which)X +3055(that)X +3200(process)X +3466(waits)X +3660(when)X +3859(it)X +3928(needs)X +4136(to)X +4223(be)X +555 2265(descheduled.)N +1014(When)X +1228(a)X +1286(process)X +1549(needs)X +1754(to)X +1838(be)X +1936(run,)X +2084(its)X +2180(semaphore)X +2549(is)X +2623(cleared,)X +2897(and)X +3034(the)X +3153(operating)X +3477(system)X +3720(reschedules)X +4116(it.)X +4201(No)X +555 2355(sophisticated)N +1002(scheduling)X +1378(algorithm)X +1718(is)X +1799(applied;)X +2085(if)X +2162(the)X +2288(lock)X +2454(for)X +2576(which)X +2800(a)X +2864(process)X +3133(was)X +3286(waiting)X +3554(becomes)X +3863(available,)X +4201(the)X +555 2445(process)N +824(is)X +905(made)X +1107(runnable.)X +1456(It)X +1533(would)X +1761(have)X +1941(been)X +2121(possible)X +2411(to)X +2501(change)X +2757(the)X +2883(kernel's)X +3170(process)X +3439(scheduler)X +3775(to)X +3865(interact)X +4134(more)X +555 2535(ef\256ciently)N +900(with)X +1062(the)X +1180(lock)X +1338(manager,)X +1655(but)X +1777(doing)X +1979(so)X +2070(would)X +2290(have)X +2462(compromised)X +2918(our)X +3045(commitment)X +3469(to)X +3551(a)X +3607(user-level)X +3944(package.)X +3 f +555 2721(3.2.5.)N +775(The)X +928(Transaction)X +1361(Manager)X +1 f +755 2844(The)N +3 f +901(Transaction)X +1335(Manager)X +1 f +1668(provides)X +1965(the)X +2084(standard)X +2377(interface)X +2680(of)X +2 f +2768(txn_begin)X +1 f +3084(,)X +2 f +3125(txn_commit)X +1 f +3499(,)X +3540(and)X +2 f +3676(txn_abort)X +1 f +3987(.)X +4047(It)X +4116(keeps)X +555 2934(track)N +742(of)X +835(all)X +941(active)X +1159(transactions,)X +1588(assigns)X +1845(unique)X +2089(transaction)X +2467(identi\256ers,)X +2833(and)X +2974(directs)X +3213(the)X +3336(abort)X +3526(and)X +3667(commit)X +3936(processing.)X +555 3024(When)N +772(a)X +2 f +833(txn_begin)X +1 f +1174(is)X +1252(issued,)X +1497(the)X +3 f +1620(Transaction)X +2058(Manager)X +1 f +2395(assigns)X +2651(the)X +2773(next)X +2935(available)X +3249(transaction)X +3625(identi\256er,)X +3958(allocates)X +4263(a)X +555 3114(per-process)N +948(transaction)X +1322(structure)X +1625(in)X +1709(shared)X +1941(memory,)X +2249(increments)X +2622(the)X +2741(count)X +2940(of)X +3028(active)X +3241(transactions,)X +3665(and)X +3802(returns)X +4046(the)X +4165(new)X +555 3204(transaction)N +937(identi\256er)X +1256(to)X +1348(the)X +1476(calling)X +1724(process.)X +2034(The)X +2188(in-memory)X +2573(transaction)X +2954(structure)X +3264(contains)X +3560(a)X +3625(pointer)X +3881(into)X +4034(the)X +4161(lock)X +555 3294(table)N +734(for)X +851(locks)X +1043(held)X +1204(by)X +1307(this)X +1445(transaction,)X +1840(the)X +1961(last)X +2095(log)X +2220(sequence)X +2538(number,)X +2826(a)X +2885(transaction)X +3260(state)X +3430(\()X +2 f +3457(idle)X +1 f +(,)S +2 f +3620(running)X +1 f +3873(,)X +2 f +3915(aborting)X +1 f +4190(,)X +4232(or)X +2 f +555 3384(committing\))N +1 f +942(,)X +982(an)X +1078(error)X +1255(code,)X +1447(and)X +1583(a)X +1639(semaphore)X +2007(identi\256er.)X +755 3507(At)N +859(commit,)X +1147(the)X +3 f +1269(Transaction)X +1706(Manager)X +1 f +2042(calls)X +2 f +2213(log_commit)X +1 f +2615(to)X +2700(record)X +2929(the)X +3050(end)X +3189(of)X +3279(transaction)X +3654(and)X +3793(to)X +3878(\257ush)X +4056(the)X +4177(log.)X +555 3597(Then)N +743(it)X +810(directs)X +1047(the)X +3 f +1168(Lock)X +1364(Manager)X +1 f +1699(to)X +1784(release)X +2031(all)X +2134(locks)X +2325(associated)X +2677(with)X +2841(the)X +2961(given)X +3161(transaction.)X +3575(If)X +3651(a)X +3709(transaction)X +4083(aborts,)X +555 3687(the)N +3 f +680(Transaction)X +1120(Manager)X +1 f +1459(calls)X +1633(on)X +2 f +1739(log_unroll)X +1 f +2102(to)X +2190(read)X +2355(the)X +2479(transaction's)X +2915(log)X +3043(records)X +3306(and)X +3448(undo)X +3634(any)X +3776(modi\256cations)X +4237(to)X +555 3777(the)N +673(database.)X +1010(As)X +1119(in)X +1201(the)X +1319(commit)X +1583(case,)X +1762(it)X +1826(then)X +1984(calls)X +2 f +2151(lock_unlock_all)X +1 f +2683(to)X +2765(release)X +3009(the)X +3127(transaction's)X +3557(locks.)X +3 f +555 3963(3.2.6.)N +775(The)X +928(Record)X +1198(Manager)X +1 f +755 4086(The)N +3 f +919(Record)X +1208(Manager)X +1 f +1559(supports)X +1869(the)X +2006(abstraction)X +2397(of)X +2503(reading)X +2783(and)X +2938(writing)X +3208(records)X +3484(to)X +3585(a)X +3660(database.)X +3996(We)X +4147(have)X +555 4176(modi\256ed)N +861(the)X +981(the)X +1101(database)X +1399(access)X +1626(routines)X +3 f +1905(db)X +1 f +1993(\(3\))X +2108([BSD91])X +2418(to)X +2501(call)X +2638(the)X +2757(log,)X +2900(lock,)X +3079(and)X +3216(buffer)X +3434(managers.)X +3803(In)X +3891(order)X +4082(to)X +4165(pro-)X +555 4266(vide)N +718(functionality)X +1152(to)X +1239(perform)X +1523(undo)X +1708(and)X +1849(redo,)X +2037(the)X +3 f +2160(Record)X +2434(Manager)X +1 f +2770(de\256nes)X +3021(a)X +3081(collection)X +3421(of)X +3512(log)X +3638(record)X +3868(types)X +4061(and)X +4201(the)X +555 4356(associated)N +920(undo)X +1115(and)X +1266(redo)X +1444(routines.)X +1777(The)X +3 f +1937(Log)X +2105(Manager)X +1 f +2452(performs)X +2777(a)X +2848(table)X +3039(lookup)X +3296(on)X +3411(the)X +3543(record)X +3783(type)X +3955(to)X +4051(call)X +4201(the)X +555 4446(appropriate)N +951(routines.)X +1299(For)X +1440(example,)X +1762(the)X +1890(B-tree)X +2121(access)X +2356(method)X +2625(requires)X +2913(two)X +3062(log)X +3193(record)X +3428(types:)X +3648(insert)X +3855(and)X +4000(delete.)X +4241(A)X +555 4536(replace)N +808(operation)X +1131(is)X +1204(implemented)X +1642(as)X +1729(a)X +1785(delete)X +1997(followed)X +2302(by)X +2402(an)X +2498(insert)X +2696(and)X +2832(is)X +2905(logged)X +3143(accordingly.)X +3 f +555 4722(3.3.)N +715(Application)X +1134(Architectures)X +1 f +755 4845(The)N +907(structure)X +1215(of)X +1309(LIBTP)X +1558(allows)X +1794(application)X +2177(designers)X +2507(to)X +2596(trade)X +2784(off)X +2905(performance)X +3339(and)X +3481(protection.)X +3872(Since)X +4076(a)X +4138(large)X +555 4935(portion)N +810(of)X +901(LIBTP's)X +1205(functionality)X +1638(is)X +1715(provided)X +2024(by)X +2128(managing)X +2468(structures)X +2804(in)X +2889(shared)X +3122(memory,)X +3432(its)X +3530(structures)X +3865(are)X +3987(subject)X +4237(to)X +555 5025(corruption)N +926(by)X +1043(applications)X +1467(when)X +1678(the)X +1813(library)X +2064(is)X +2154(linked)X +2391(directly)X +2673(with)X +2852(the)X +2987(application.)X +3420(For)X +3568(this)X +3720(reason,)X +3987(LIBTP)X +4246(is)X +555 5115(designed)N +864(to)X +950(allow)X +1152(compilation)X +1558(into)X +1706(a)X +1766(separate)X +2053(server)X +2273(process)X +2537(which)X +2756(may)X +2917(be)X +3016(accessed)X +3321(via)X +3442(a)X +3501(socket)X +3729(interface.)X +4094(In)X +4184(this)X +555 5205(way)N +712(LIBTP's)X +1015(data)X +1172(structures)X +1507(are)X +1629(protected)X +1951(from)X +2130(application)X +2509(code,)X +2704(but)X +2829(communication)X +3349(overhead)X +3666(is)X +3741(increased.)X +4107(When)X +555 5295(applications)N +975(are)X +1107(trusted,)X +1377(LIBTP)X +1631(may)X +1801(be)X +1909(compiled)X +2239(directly)X +2516(into)X +2672(the)X +2802(application)X +3190(providing)X +3533(improved)X +3872(performance.)X +555 5385(Figures)N +815(two)X +955(and)X +1091(three)X +1272(show)X +1461(the)X +1579(two)X +1719(alternate)X +2016(application)X +2392(architectures.)X +755 5508(There)N +964(are)X +1084(potentially)X +1447(two)X +1588(modes)X +1818(in)X +1901(which)X +2118(one)X +2255(might)X +2462(use)X +2590(LIBTP)X +2833(in)X +2916(a)X +2972(server)X +3189(based)X +3392(architecture.)X +3832(In)X +3919(the)X +4037(\256rst,)X +4201(the)X +555 5598(server)N +778(would)X +1004(provide)X +1275(the)X +1399(capability)X +1741(to)X +1829(respond)X +2109(to)X +2197(requests)X +2486(to)X +2574(each)X +2747(of)X +2839(the)X +2962(low)X +3107(level)X +3288(modules)X +3584(\(lock,)X +3794(log,)X +3941(buffer,)X +4183(and)X +555 5688(transaction)N +944(managers\).)X +1356(Unfortunately,)X +1863(the)X +1998(performance)X +2442(of)X +2546(such)X +2730(a)X +2803(system)X +3062(is)X +3152(likely)X +3371(to)X +3470(be)X +3583(blindingly)X +3947(slow)X +4134(since)X + +7 p +%%Page: 7 7 +10 s 10 xH 0 xS 1 f +3 f +1 f +1 Dt +1864 1125 MXY +15 -26 Dl +-15 10 Dl +-14 -10 Dl +14 26 Dl +0 -266 Dl +1315 1125 MXY +15 -26 Dl +-15 10 Dl +-14 -10 Dl +14 26 Dl +0 -266 Dl +3 Dt +1133 1125 MXY +0 798 Dl +931 0 Dl +0 -798 Dl +-931 0 Dl +1 Dt +1266 1257 MXY +0 133 Dl +665 0 Dl +0 -133 Dl +-665 0 Dl +3 f +8 s +1513 1351(driver)N +1502 1617(LIBTP)N +1266 1390 MXY +0 400 Dl +665 0 Dl +0 -400 Dl +-665 0 Dl +3 Dt +1133 726 MXY +0 133 Dl +931 0 Dl +0 -133 Dl +-931 0 Dl +1 f +1029 1098(txn_abort)N +964 1015(txn_commit)N +1018 932(txn_begin)N +1910 1015(db_ops)N +3 f +1308 820(Application)N +1645(Program)X +1398 1218(Server)N +1594(Process)X +1 f +1390 986(socket)N +1569(interface)X +1 Dt +1848 967 MXY +-23 -14 Dl +8 14 Dl +-8 15 Dl +23 -15 Dl +-50 0 Dl +1324 MX +23 15 Dl +-9 -15 Dl +9 -14 Dl +-23 14 Dl +50 0 Dl +3 Dt +2862 859 MXY +0 1064 Dl +932 0 Dl +0 -1064 Dl +-932 0 Dl +1 Dt +3178 1390 MXY +24 -12 Dl +-17 0 Dl +-8 -15 Dl +1 27 Dl +150 -265 Dl +3494 1390 MXY +0 -27 Dl +-8 15 Dl +-16 1 Dl +24 11 Dl +-166 -265 Dl +3 f +3232 1617(LIBTP)N +2995 1390 MXY +0 400 Dl +666 0 Dl +0 -400 Dl +-666 0 Dl +992 MY +0 133 Dl +666 0 Dl +0 -133 Dl +-666 0 Dl +3168 1086(Application)N +1 f +2939 1201(txn_begin)N +2885 1284(txn_commit)N +2950 1368(txn_abort)N +3465 1284(db_ops)N +3 f +3155 766(Single)N +3339(Process)X +3 Dt +-1 Ds +811 2100(Figure)N +1023(2:)X +1107(Server)X +1318(Architecture.)X +1 f +1727(In)X +1811(this)X +1934(con\256guration,)X +811 2190(the)N +916(library)X +1113(is)X +1183(loaded)X +1380(into)X +1507(a)X +1562(server)X +1744(process)X +1962(which)X +2145(is)X +2214(ac-)X +811 2280(cessed)N +993(via)X +1087(a)X +1131(socket)X +1310(interface.)X +3 f +2563 2100(Figure)N +2803(3:)X +2914(Single)X +3140(Process)X +3403(Architecture.)X +1 f +3839(In)X +3950(this)X +2563 2190(con\256guration,)N +2948(the)X +3053(library)X +3250(routines)X +3483(are)X +3587(loaded)X +3784(as)X +3864(part)X +3990(of)X +2563 2280(the)N +2657(application)X +2957(and)X +3065(accessed)X +3303(via)X +3397(a)X +3441(subroutine)X +3727(interface.)X +10 s +10 f +555 2403(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +1 f +555 2679(modifying)N +909(a)X +966(piece)X +1157(of)X +1245(data)X +1400(would)X +1621(require)X +1870(three)X +2051(or)X +2138(possibly)X +2424(four)X +2578(separate)X +2862(communications:)X +3433(one)X +3569(to)X +3651(lock)X +3809(the)X +3927(data,)X +4101(one)X +4237(to)X +555 2769(obtain)N +781(the)X +905(data,)X +1085(one)X +1227(to)X +1315(log)X +1443(the)X +1567(modi\256cation,)X +2017(and)X +2159(possibly)X +2451(one)X +2593(to)X +2681(transmit)X +2969(the)X +3093(modi\256ed)X +3403(data.)X +3583(Figure)X +3817(four)X +3976(shows)X +4201(the)X +555 2859(relative)N +826(performance)X +1263(for)X +1387(retrieving)X +1728(a)X +1793(single)X +2013(record)X +2248(using)X +2450(the)X +2577(record)X +2812(level)X +2997(call)X +3142(versus)X +3376(using)X +3578(the)X +3705(lower)X +3917(level)X +4102(buffer)X +555 2949(management)N +987(and)X +1125(locking)X +1387(calls.)X +1616(The)X +1763(2:1)X +1887(ratio)X +2056(observed)X +2367(in)X +2450(the)X +2569(single)X +2781(process)X +3043(case)X +3203(re\257ects)X +3456(the)X +3575(additional)X +3916(overhead)X +4232(of)X +555 3039(parsing)N +819(eight)X +1006(commands)X +1380(rather)X +1595(than)X +1760(one)X +1903(while)X +2108(the)X +2233(3:1)X +2362(ratio)X +2536(observed)X +2853(in)X +2942(the)X +3067(client/server)X +3491(architecture)X +3898(re\257ects)X +4157(both)X +555 3129(the)N +679(parsing)X +941(and)X +1083(the)X +1207(communication)X +1731(overheard.)X +2118(Although)X +2445(there)X +2631(may)X +2794(be)X +2895(applications)X +3307(which)X +3528(could)X +3731(tolerate)X +3997(such)X +4169(per-)X +555 3219(formance,)N +904(it)X +973(seems)X +1194(far)X +1309(more)X +1499(feasible)X +1774(to)X +1861(support)X +2126(a)X +2187(higher)X +2417(level)X +2597(interface,)X +2923(such)X +3094(as)X +3185(that)X +3329(provided)X +3638(by)X +3742(a)X +3802(query)X +4009(language)X +555 3309(\()N +2 f +582(e.g.)X +1 f +718(SQL)X +889([SQL86]\).)X +755 3432(Although)N +1081(LIBTP)X +1327(does)X +1498(not)X +1624(have)X +1800(an)X +1900(SQL)X +2075(parser,)X +2316(we)X +2433(have)X +2608(built)X +2777(a)X +2836(server)X +3056(application)X +3435(using)X +3631(the)X +3752(toolkit)X +3983(command)X +555 3522(language)N +882(\(TCL\))X +1124([OUST90].)X +1544(The)X +1706(server)X +1940(supports)X +2248(a)X +2321(command)X +2674(line)X +2831(interface)X +3150(similar)X +3409(to)X +3508(the)X +3643(subroutine)X +4017(interface)X +555 3612(de\256ned)N +811(in)X +3 f +893(db)X +1 f +981(\(3\).)X +1135(Since)X +1333(it)X +1397(is)X +1470(based)X +1673(on)X +1773(TCL,)X +1964(it)X +2028(provides)X +2324(control)X +2571(structures)X +2903(as)X +2990(well.)X +3 f +555 3798(4.)N +655(Implementation)X +1 f +3 f +555 3984(4.1.)N +715(Locking)X +1014(and)X +1162(Deadlock)X +1502(Detection)X +1 f +755 4107(LIBTP)N +1007(uses)X +1175(two-phase)X +1535(locking)X +1805(for)X +1929(user)X +2093(data.)X +2297(Strictly)X +2562(speaking,)X +2897(the)X +3024(two)X +3173(phases)X +3416(in)X +3507(two-phase)X +3866(locking)X +4135(are)X +4263(a)X +3 f +555 4197(grow)N +1 f +756(phase,)X +986(during)X +1221(which)X +1443(locks)X +1638(are)X +1763(acquired,)X +2086(and)X +2228(a)X +3 f +2290(shrink)X +1 f +2537(phase,)X +2766(during)X +3001(which)X +3223(locks)X +3418(are)X +3543(released.)X +3873(No)X +3997(lock)X +4161(may)X +555 4287(ever)N +720(be)X +822(acquired)X +1124(during)X +1358(the)X +1481(shrink)X +1706(phase.)X +1954(The)X +2104(grow)X +2294(phase)X +2502(lasts)X +2669(until)X +2840(the)X +2963(\256rst)X +3112(release,)X +3381(which)X +3602(marks)X +3823(the)X +3946(start)X +4109(of)X +4201(the)X +555 4377(shrink)N +780(phase.)X +1028(In)X +1120(practice,)X +1420(the)X +1543(grow)X +1733(phase)X +1941(lasts)X +2108(for)X +2227(the)X +2350(duration)X +2642(of)X +2734(a)X +2795(transaction)X +3172(in)X +3259(LIBTP)X +3506(and)X +3647(in)X +3734(commercial)X +4138(data-)X +555 4467(base)N +721(systems.)X +1037(The)X +1184(shrink)X +1406(phase)X +1611(takes)X +1798(place)X +1990(during)X +2221(transaction)X +2595(commit)X +2861(or)X +2950(abort.)X +3177(This)X +3341(means)X +3568(that)X +3710(locks)X +3901(are)X +4022(acquired)X +555 4557(on)N +655(demand)X +929(during)X +1158(the)X +1276(lifetime)X +1545(of)X +1632(a)X +1688(transaction,)X +2080(and)X +2216(held)X +2374(until)X +2540(commit)X +2804(time,)X +2986(at)X +3064(which)X +3280(point)X +3464(all)X +3564(locks)X +3753(are)X +3872(released.)X +755 4680(If)N +832(multiple)X +1121(transactions)X +1527(are)X +1649(active)X +1864(concurrently,)X +2313(deadlocks)X +2657(can)X +2792(occur)X +2994(and)X +3133(must)X +3311(be)X +3410(detected)X +3701(and)X +3840(resolved.)X +4174(The)X +555 4770(lock)N +715(table)X +893(can)X +1027(be)X +1125(thought)X +1391(of)X +1480(as)X +1569(a)X +1627(representation)X +2104(of)X +2193(a)X +2251(directed)X +2532(graph.)X +2777(The)X +2924(nodes)X +3133(in)X +3216(the)X +3335(graph)X +3539(are)X +3659(transactions.)X +4103(Edges)X +555 4860(represent)N +878(the)X +3 f +1004(waits-for)X +1 f +1340(relation)X +1613(between)X +1909(transactions;)X +2342(if)X +2419(transaction)X +2 f +2799(A)X +1 f +2876(is)X +2957(waiting)X +3225(for)X +3347(a)X +3411(lock)X +3577(held)X +3743(by)X +3851(transaction)X +2 f +4230(B)X +1 f +4279(,)X +555 4950(then)N +716(a)X +775(directed)X +1057(edge)X +1232(exists)X +1437(from)X +2 f +1616(A)X +1 f +1687(to)X +2 f +1771(B)X +1 f +1842(in)X +1926(the)X +2046(graph.)X +2291(A)X +2371(deadlock)X +2683(exists)X +2887(if)X +2958(a)X +3016(cycle)X +3208(appears)X +3476(in)X +3560(the)X +3680(graph.)X +3925(By)X +4040(conven-)X +555 5040(tion,)N +719(no)X +819(transaction)X +1191(ever)X +1350(waits)X +1539(for)X +1653(a)X +1709(lock)X +1867(it)X +1931(already)X +2188(holds,)X +2401(so)X +2492(re\257exive)X +2793(edges)X +2996(are)X +3115(impossible.)X +755 5163(A)N +836(distinguished)X +1285(process)X +1549(monitors)X +1856(the)X +1977(lock)X +2138(table,)X +2337(searching)X +2668(for)X +2785(cycles.)X +3048(The)X +3195(frequency)X +3539(with)X +3703(which)X +3921(this)X +4058(process)X +555 5253(runs)N +716(is)X +792(user-settable;)X +1243(for)X +1360(the)X +1481(multi-user)X +1833(tests)X +1998(discussed)X +2328(in)X +2413(section)X +2663(5.1.2,)X +2866(it)X +2933(has)X +3063(been)X +3238(set)X +3350(to)X +3435(wake)X +3628(up)X +3731(every)X +3932(second,)X +4197(but)X +555 5343(more)N +742(sophisticated)X +1182(schedules)X +1516(are)X +1636(certainly)X +1938(possible.)X +2261(When)X +2474(a)X +2531(cycle)X +2722(is)X +2796(detected,)X +3105(one)X +3242(of)X +3330(the)X +3449(transactions)X +3853(in)X +3936(the)X +4055(cycle)X +4246(is)X +555 5433(nominated)N +917(and)X +1057(aborted.)X +1362(When)X +1578(the)X +1700(transaction)X +2076(aborts,)X +2315(it)X +2382(rolls)X +2547(back)X +2722(its)X +2820(changes)X +3102(and)X +3241(releases)X +3519(its)X +3617(locks,)X +3829(thereby)X +4093(break-)X +555 5523(ing)N +677(the)X +795(cycle)X +985(in)X +1067(the)X +1185(graph.)X + +8 p +%%Page: 8 8 +10 s 10 xH 0 xS 1 f +3 f +1 f +4 Ds +1 Dt +1866 865 MXY +1338 0 Dl +1866 1031 MXY +1338 0 Dl +1866 1199 MXY +1338 0 Dl +1866 1366 MXY +1338 0 Dl +1866 1533 MXY +1338 0 Dl +1866 1701 MXY +1338 0 Dl +-1 Ds +5 Dt +1866 1868 MXY +1338 0 Dl +1 Dt +1 Di +2981 MX + 2981 1868 lineto + 2981 1575 lineto + 3092 1575 lineto + 3092 1868 lineto + 2981 1868 lineto +closepath 21 2981 1575 3092 1868 Dp +2646 MX + 2646 1868 lineto + 2646 949 lineto + 2758 949 lineto + 2758 1868 lineto + 2646 1868 lineto +closepath 14 2646 949 2758 1868 Dp +2312 MX + 2312 1868 lineto + 2312 1701 lineto + 2423 1701 lineto + 2423 1868 lineto + 2312 1868 lineto +closepath 3 2312 1701 2423 1868 Dp +1977 MX + 1977 1868 lineto + 1977 1512 lineto + 2089 1512 lineto + 2089 1868 lineto + 1977 1868 lineto +closepath 19 1977 1512 2089 1868 Dp +3 f +2640 2047(Client/Server)N +1957(Single)X +2185(Process)X +7 s +2957 1957(record)N +2570(component)X +2289(record)X +1890(components)X +1733 1724(.1)N +1733 1556(.2)N +1733 1389(.3)N +1733 1222(.4)N +1733 1055(.5)N +1733 889(.6)N +1590 726(Elapsed)N +1794(Time)X +1613 782(\(in)N +1693(seconds\))X +3 Dt +-1 Ds +8 s +555 2255(Figure)N +756(4:)X +829(Comparison)X +1187(of)X +1260(High)X +1416(and)X +1540(Low)X +1681(Level)X +1850(Interfaces.)X +1 f +2174(Elapsed)X +2395(time)X +2528(in)X +2597(seconds)X +2818(to)X +2887(perform)X +3111(a)X +3158(single)X +3330(record)X +3511(retrieval)X +3742(from)X +3885(a)X +3932(command)X +4203(line)X +555 2345(\(rather)N +751(than)X +888(a)X +943(procedural)X +1241(interface\))X +1510(is)X +1579(shown)X +1772(on)X +1862(the)X +1966(y)X +2024(axis.)X +2185(The)X +2310(``component'')X +2704(numbers)X +2950(re\257ect)X +3135(the)X +3239(timings)X +3458(when)X +3622(the)X +3726(record)X +3914(is)X +3983(retrieved)X +4235(by)X +555 2435(separate)N +785(calls)X +924(to)X +996(the)X +1096(lock)X +1228(manager)X +1469(and)X +1583(buffer)X +1760(manager)X +2001(while)X +2165(the)X +2264(``record'')X +2531(timings)X +2745(were)X +2889(obtained)X +3130(by)X +3215(using)X +3375(a)X +3424(single)X +3598(call)X +3711(to)X +3782(the)X +3881(record)X +4064(manager.)X +555 2525(The)N +674(2:1)X +776(ratio)X +913(observed)X +1163(for)X +1257(the)X +1355(single)X +1528(process)X +1739(case)X +1868(is)X +1930(a)X +1977(re\257ection)X +2237(of)X +2309(the)X +2406(parsing)X +2613(overhead)X +2865(for)X +2958(executing)X +3225(eight)X +3372(separate)X +3599(commands)X +3895(rather)X +4062(than)X +4191(one.)X +555 2615(The)N +673(additional)X +948(factor)X +1115(of)X +1187(one)X +1298(re\257ected)X +1536(in)X +1605(the)X +1702(3:1)X +1803(ratio)X +1939(for)X +2031(the)X +2127(client/server)X +2460(architecture)X +2794(is)X +2855(due)X +2965(to)X +3033(the)X +3129(communication)X +3545(overhead.)X +3828(The)X +3945(true)X +4062(ratios)X +4222(are)X +555 2705(actually)N +775(worse)X +945(since)X +1094(the)X +1190(component)X +1492(timings)X +1703(do)X +1785(not)X +1884(re\257ect)X +2060(the)X +2155(search)X +2334(times)X +2490(within)X +2671(each)X +2804(page)X +2941(or)X +3011(the)X +3106(time)X +3237(required)X +3466(to)X +3533(transmit)X +3760(the)X +3855(page)X +3992(between)X +4221(the)X +555 2795(two)N +667(processes.)X +10 s +10 f +555 2885(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +3 f +555 3161(4.2.)N +715(Group)X +961(Commit)X +1 f +755 3284(Since)N +959(the)X +1083(log)X +1211(must)X +1392(be)X +1494(\257ushed)X +1751(to)X +1839(disk)X +1997(at)X +2080(commit)X +2349(time,)X +2536(disk)X +2694(bandwidth)X +3057(fundamentally)X +3545(limits)X +3751(the)X +3874(rate)X +4020(at)X +4103(which)X +555 3374(transactions)N +959(complete.)X +1314(Since)X +1513(most)X +1688(transactions)X +2091(write)X +2276(only)X +2438(a)X +2494(few)X +2635(small)X +2828(records)X +3085(to)X +3167(the)X +3285(log,)X +3427(the)X +3545(last)X +3676(page)X +3848(of)X +3935(the)X +4053(log)X +4175(will)X +555 3464(be)N +658(\257ushed)X +916(once)X +1095(by)X +1202(every)X +1408(transaction)X +1787(which)X +2010(writes)X +2233(to)X +2322(it.)X +2433(In)X +2527(the)X +2652(naive)X +2853(implementation,)X +3402(these)X +3593(\257ushes)X +3841(would)X +4067(happen)X +555 3554(serially.)N +755 3677(LIBTP)N +1008(uses)X +3 f +1177(group)X +1412(commit)X +1 f +1702([DEWI84])X +2077(in)X +2170(order)X +2371(to)X +2464(amortize)X +2775(the)X +2903(cost)X +3062(of)X +3159(one)X +3305(synchronous)X +3740(disk)X +3903(write)X +4098(across)X +555 3767(multiple)N +851(transactions.)X +1304(Group)X +1539(commit)X +1812(provides)X +2117(a)X +2182(way)X +2345(for)X +2468(a)X +2533(group)X +2749(of)X +2845(transactions)X +3257(to)X +3348(commit)X +3621(simultaneously.)X +4174(The)X +555 3857(\256rst)N +709(several)X +967(transactions)X +1380(to)X +1472(commit)X +1745(write)X +1939(their)X +2115(changes)X +2403(to)X +2494(the)X +2621(in-memory)X +3006(log)X +3137(page,)X +3338(then)X +3505(sleep)X +3699(on)X +3808(a)X +3873(distinguished)X +555 3947(semaphore.)N +966(Later,)X +1179(a)X +1238(committing)X +1629(transaction)X +2004(\257ushes)X +2249(the)X +2370(page)X +2545(to)X +2630(disk,)X +2805(and)X +2943(wakes)X +3166(up)X +3268(all)X +3370(its)X +3467(sleeping)X +3756(peers.)X +3988(The)X +4135(point)X +555 4037(at)N +635(which)X +853(changes)X +1134(are)X +1255(actually)X +1531(written)X +1780(is)X +1855(determined)X +2238(by)X +2340(three)X +2523(thresholds.)X +2914(The)X +3061(\256rst)X +3207(is)X +3281(the)X +2 f +3400(group)X +3612(threshold)X +1 f +3935(and)X +4072(de\256nes)X +555 4127(the)N +674(minimum)X +1005(number)X +1271(of)X +1359(transactions)X +1763(which)X +1979(must)X +2154(be)X +2250(active)X +2462(in)X +2544(the)X +2662(system)X +2904(before)X +3130(transactions)X +3533(are)X +3652(forced)X +3878(to)X +3960(participate)X +555 4217(in)N +646(a)X +711(group)X +927(commit.)X +1240(The)X +1394(second)X +1646(is)X +1728(the)X +2 f +1855(wait)X +2021(threshold)X +1 f +2352(which)X +2577(is)X +2658(expressed)X +3003(as)X +3098(the)X +3224(percentage)X +3601(of)X +3696(active)X +3916(transactions)X +555 4307(waiting)N +826(to)X +919(be)X +1026(committed.)X +1439(The)X +1595(last)X +1737(is)X +1821(the)X +2 f +1950(logdelay)X +2257(threshold)X +1 f +2590(which)X +2816(indicates)X +3131(how)X +3299(much)X +3507(un\257ushed)X +3848(log)X +3980(should)X +4223(be)X +555 4397(allowed)N +829(to)X +911(accumulate)X +1297(before)X +1523(a)X +1579(waiting)X +1839(transaction's)X +2289(commit)X +2553(record)X +2779(is)X +2852(\257ushed.)X +755 4520(Group)N +981(commit)X +1246(can)X +1379(substantially)X +1803(improve)X +2090(performance)X +2517(for)X +2631(high-concurrency)X +3218(environments.)X +3714(If)X +3788(only)X +3950(a)X +4006(few)X +4147(tran-)X +555 4610(sactions)N +836(are)X +957(running,)X +1248(it)X +1314(is)X +1389(unlikely)X +1673(to)X +1757(improve)X +2046(things)X +2263(at)X +2343(all.)X +2485(The)X +2632(crossover)X +2962(point)X +3148(is)X +3223(the)X +3343(point)X +3529(at)X +3609(which)X +3827(the)X +3947(transaction)X +555 4700(commit)N +823(rate)X +968(is)X +1045(limited)X +1295(by)X +1399(the)X +1521(bandwidth)X +1883(of)X +1974(the)X +2096(device)X +2330(on)X +2434(which)X +2654(the)X +2776(log)X +2902(resides.)X +3189(If)X +3267(processes)X +3599(are)X +3722(trying)X +3937(to)X +4023(\257ush)X +4201(the)X +555 4790(log)N +677(faster)X +876(than)X +1034(the)X +1152(log)X +1274(disk)X +1427(can)X +1559(accept)X +1785(data,)X +1959(then)X +2117(group)X +2324(commit)X +2588(will)X +2732(increase)X +3016(the)X +3134(commit)X +3398(rate.)X +3 f +555 4976(4.3.)N +715(Kernel)X +971(Intervention)X +1418(for)X +1541(Synchronization)X +1 f +755 5099(Since)N +954(LIBTP)X +1197(uses)X +1356(data)X +1511(in)X +1594(shared)X +1825(memory)X +2113(\()X +2 f +2140(e.g.)X +1 f +2277(the)X +2395(lock)X +2553(table)X +2729(and)X +2865(buffer)X +3082(pool\))X +3271(it)X +3335(must)X +3510(be)X +3606(possible)X +3888(for)X +4002(a)X +4058(process)X +555 5189(to)N +640(acquire)X +900(exclusive)X +1226(access)X +1454(to)X +1538(shared)X +1770(data)X +1926(in)X +2010(order)X +2202(to)X +2286(prevent)X +2549(corruption.)X +2945(In)X +3034(addition,)X +3338(the)X +3458(process)X +3721(manager)X +4020(must)X +4197(put)X +555 5279(processes)N +886(to)X +971(sleep)X +1159(when)X +1356(the)X +1477(lock)X +1638(or)X +1728(buffer)X +1948(they)X +2109(request)X +2364(is)X +2440(in)X +2525(use)X +2655(by)X +2758(some)X +2950(other)X +3138(process.)X +3441(In)X +3530(the)X +3650(LIBTP)X +3894(implementa-)X +555 5385(tion)N +705(under)X +914(Ultrix)X +1131(4.0)X +7 s +5353(2)Y +10 s +5385(,)Y +1305(we)X +1424(use)X +1556(System)X +1816(V)X +1899(semaphores)X +2303(to)X +2390(provide)X +2660(this)X +2800(synchronization.)X +3377(Semaphores)X +3794(implemented)X +4237(in)X +555 5475(this)N +701(fashion)X +968(turn)X +1128(out)X +1261(to)X +1354(be)X +1461(an)X +1568(expensive)X +1920(choice)X +2161(for)X +2285(synchronization,)X +2847(because)X +3132(each)X +3310(access)X +3546(traps)X +3732(to)X +3824(the)X +3952(kernel)X +4183(and)X +8 s +10 f +555 5547(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5625(2)N +8 s +763 5650(Ultrix)N +932(and)X +1040(DEC)X +1184(are)X +1277(trademarks)X +1576(of)X +1645(Digital)X +1839(Equipment)X +2136(Corporation.)X + +9 p +%%Page: 9 9 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +555 630(executes)N +852(atomically)X +1210(there.)X +755 753(On)N +878(architectures)X +1314(that)X +1459(support)X +1724(atomic)X +1967(test-and-set,)X +2382(a)X +2443(much)X +2646(better)X +2854(choice)X +3089(would)X +3314(be)X +3415(to)X +3502(attempt)X +3767(to)X +3854(obtain)X +4079(a)X +4139(spin-)X +555 843(lock)N +714(with)X +877(a)X +934(test-and-set,)X +1345(and)X +1482(issue)X +1663(a)X +1720(system)X +1963(call)X +2100(only)X +2263(if)X +2333(the)X +2452(spinlock)X +2744(is)X +2818(unavailable.)X +3249(Since)X +3447(virtually)X +3738(all)X +3838(semaphores)X +4237(in)X +555 933(LIBTP)N +801(are)X +924(uncontested)X +1330(and)X +1469(are)X +1591(held)X +1752(for)X +1869(very)X +2035(short)X +2218(periods)X +2477(of)X +2567(time,)X +2752(this)X +2890(would)X +3113(improve)X +3403(performance.)X +3873(For)X +4007(example,)X +555 1023(processes)N +885(must)X +1062(acquire)X +1321(exclusive)X +1646(access)X +1874(to)X +1958(buffer)X +2177(pool)X +2341(metadata)X +2653(in)X +2737(order)X +2929(to)X +3013(\256nd)X +3159(and)X +3297(pin)X +3421(a)X +3479(buffer)X +3698(in)X +3781(shared)X +4012(memory.)X +555 1113(This)N +721(semaphore)X +1093(is)X +1170(requested)X +1502(most)X +1681(frequently)X +2034(in)X +2119(LIBTP.)X +2404(However,)X +2742(once)X +2917(it)X +2984(is)X +3060(acquired,)X +3380(only)X +3545(a)X +3604(few)X +3748(instructions)X +4144(must)X +555 1203(be)N +656(executed)X +966(before)X +1196(it)X +1264(is)X +1341(released.)X +1669(On)X +1791(one)X +1931(architecture)X +2335(for)X +2453(which)X +2673(we)X +2791(were)X +2972(able)X +3130(to)X +3216(gather)X +3441(detailed)X +3719(pro\256ling)X +4018(informa-)X +555 1293(tion,)N +729(the)X +857(cost)X +1015(of)X +1111(the)X +1238(semaphore)X +1615(calls)X +1791(accounted)X +2146(for)X +2269(25%)X +2445(of)X +2541(the)X +2668(total)X +2839(time)X +3010(spent)X +3208(updating)X +3517(the)X +3644(metadata.)X +4003(This)X +4174(was)X +555 1383(fairly)N +749(consistent)X +1089(across)X +1310(most)X +1485(of)X +1572(the)X +1690(critical)X +1933(sections.)X +755 1506(In)N +848(an)X +950(attempt)X +1216(to)X +1304(quantify)X +1597(the)X +1720(overhead)X +2040(of)X +2132(kernel)X +2358(synchronization,)X +2915(we)X +3034(ran)X +3162(tests)X +3329(on)X +3434(a)X +3495(version)X +3756(of)X +3848(4.3BSD-Reno)X +555 1596(which)N +786(had)X +937(been)X +1123(modi\256ed)X +1441(to)X +1537(support)X +1811(binary)X +2050(semaphore)X +2432(facilities)X +2742(similar)X +2998(to)X +3094(those)X +3297(described)X +3639(in)X +3735([POSIX91].)X +4174(The)X +555 1686(hardware)N +880(platform)X +1181(consisted)X +1504(of)X +1595(an)X +1695(HP300)X +1941(\(33MHz)X +2237(MC68030\))X +2612(workstation)X +3014(with)X +3180(16MBytes)X +3537(of)X +3628(main)X +3812(memory,)X +4123(and)X +4263(a)X +555 1776(600MByte)N +920(HP7959)X +1205(SCSI)X +1396(disk)X +1552(\(17)X +1682(ms)X +1798(average)X +2072(seek)X +2237(time\).)X +2468(We)X +2602(ran)X +2727(three)X +2910(sets)X +3052(of)X +3141(comparisons)X +3568(which)X +3786(are)X +3907(summarized)X +555 1866(in)N +645(\256gure)X +860(\256ve.)X +1028(In)X +1123(each)X +1299(comparison)X +1701(we)X +1823(ran)X +1954(two)X +2102(tests,)X +2292(one)X +2436(using)X +2637(hardware)X +2965(spinlocks)X +3295(and)X +3438(the)X +3563(other)X +3755(using)X +3955(kernel)X +4183(call)X +555 1956(synchronization.)N +1135(Since)X +1341(the)X +1467(test)X +1606(was)X +1758(run)X +1892(single-user,)X +2291(none)X +2474(of)X +2568(the)X +2693(the)X +2818(locks)X +3014(were)X +3198(contested.)X +3568(In)X +3662(the)X +3787(\256rst)X +3938(two)X +4085(sets)X +4232(of)X +555 2046(tests,)N +743(we)X +863(ran)X +992(the)X +1116(full)X +1253(transaction)X +1631(processing)X +2000(benchmark)X +2383(described)X +2717(in)X +2805(section)X +3058(5.1.)X +3223(In)X +3315(one)X +3456(case)X +3620(we)X +3739(ran)X +3867(with)X +4034(both)X +4201(the)X +555 2136(database)N +854(and)X +992(log)X +1116(on)X +1218(the)X +1338(same)X +1525(disk)X +1680(\(1)X +1769(Disk\))X +1969(and)X +2107(in)X +2191(the)X +2311(second,)X +2576(we)X +2692(ran)X +2817(with)X +2981(the)X +3101(database)X +3400(and)X +3538(log)X +3661(on)X +3762(separate)X +4047(disks)X +4232(\(2)X +555 2226(Disk\).)N +800(In)X +894(the)X +1019(last)X +1157(test,)X +1315(we)X +1436(wanted)X +1695(to)X +1784(create)X +2004(a)X +2067(CPU)X +2249(bound)X +2476(environment,)X +2928(so)X +3026(we)X +3146(used)X +3319(a)X +3381(database)X +3684(small)X +3883(enough)X +4145(to)X +4233(\256t)X +555 2316(completely)N +941(in)X +1033(the)X +1161(cache)X +1375(and)X +1521(issued)X +1751(read-only)X +2089(transactions.)X +2541(The)X +2695(results)X +2933(in)X +3024(\256gure)X +3240(\256ve)X +3389(express)X +3659(the)X +3786(kernel)X +4016(call)X +4161(syn-)X +555 2406(chronization)N +980(performance)X +1411(as)X +1502(a)X +1562(percentage)X +1935(of)X +2026(the)X +2148(spinlock)X +2443(performance.)X +2914(For)X +3049(example,)X +3365(in)X +3451(the)X +3573(1)X +3637(disk)X +3794(case,)X +3977(the)X +4098(kernel)X +555 2496(call)N +697(implementation)X +1225(achieved)X +1537(4.4)X +1662(TPS)X +1824(\(transactions)X +2259(per)X +2387(second\))X +2662(while)X +2865(the)X +2988(semaphore)X +3361(implementation)X +3888(achieved)X +4199(4.6)X +555 2586(TPS,)N +735(and)X +874(the)X +995(relative)X +1259(performance)X +1689(of)X +1779(the)X +1900(kernel)X +2123(synchronization)X +2657(is)X +2732(96%)X +2901(that)X +3043(of)X +3132(the)X +3252(spinlock)X +3545(\(100)X +3714(*)X +3776(4.4)X +3898(/)X +3942(4.6\).)X +4111(There)X +555 2676(are)N +674(two)X +814(striking)X +1078(observations)X +1503(from)X +1679(these)X +1864(results:)X +10 f +635 2799(g)N +1 f +755(even)X +927(when)X +1121(the)X +1239(system)X +1481(is)X +1554(disk)X +1707(bound,)X +1947(the)X +2065(CPU)X +2240(cost)X +2389(of)X +2476(synchronization)X +3008(is)X +3081(noticeable,)X +3451(and)X +10 f +635 2922(g)N +1 f +755(when)X +949(we)X +1063(are)X +1182(CPU)X +1357(bound,)X +1597(the)X +1715(difference)X +2062(is)X +2135(dramatic)X +2436(\(67%\).)X +3 f +555 3108(4.4.)N +715(Transaction)X +1148(Protected)X +1499(Access)X +1747(Methods)X +1 f +755 3231(The)N +903(B-tree)X +1127(and)X +1266(\256xed)X +1449(length)X +1671(recno)X +1872(\(record)X +2127(number\))X +2421(access)X +2649(methods)X +2942(have)X +3116(been)X +3290(modi\256ed)X +3596(to)X +3680(provide)X +3947(transaction)X +555 3321(protection.)N +941(Whereas)X +1244(the)X +1363(previously)X +1722(published)X +2054(interface)X +2357(to)X +2440(the)X +2559(access)X +2786(routines)X +3065(had)X +3202(separate)X +3487(open)X +3664(calls)X +3832(for)X +3946(each)X +4114(of)X +4201(the)X +10 f +555 3507(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +1 Dt +2978 5036 MXY + 2978 5036 lineto + 2978 4662 lineto + 3093 4662 lineto + 3093 5036 lineto + 2978 5036 lineto +closepath 21 2978 4662 3093 5036 Dp +2518 MX + 2518 5036 lineto + 2518 3960 lineto + 2633 3960 lineto + 2633 5036 lineto + 2518 5036 lineto +closepath 3 2518 3960 2633 5036 Dp +2059 MX + 2059 5036 lineto + 2059 3946 lineto + 2174 3946 lineto + 2174 5036 lineto + 2059 5036 lineto +closepath 1 2059 3946 2174 5036 Dp +3 f +7 s +2912 5141(Read-only)N +1426 3767(of)N +1487(Spinlock)X +1710(Throughput)X +1480 3710(Throughput)N +1786(as)X +1850(a)X +1892(%)X +11 s +1670 4843(20)N +1670 4614(40)N +1670 4384(60)N +1670 4155(80)N +1648 3925(100)N +7 s +2041 5141(1)N +2083(Disk)X +2490(2)X +2532(Disks)X +5 Dt +1829 5036 MXY +1494 0 Dl +4 Ds +1 Dt +1829 4806 MXY +1494 0 Dl +1829 4577 MXY +1494 0 Dl +1829 4347 MXY +1494 0 Dl +1829 4118 MXY +1494 0 Dl +1829 3888 MXY +1494 0 Dl +3 Dt +-1 Ds +8 s +555 5360(Figure)N +753(5:)X +823(Kernel)X +1028(Overhead)X +1315(for)X +1413(System)X +1625(Call)X +1756(Synchronization.)X +1 f +2254(The)X +2370(performance)X +2708(of)X +2778(the)X +2873(kernel)X +3049(call)X +3158(synchronization)X +3583(is)X +3643(expressed)X +3911(as)X +3980(a)X +4024(percentage)X +555 5450(of)N +625(the)X +720(spinlock)X +954(synchronization)X +1379(performance.)X +1749(In)X +1819(disk)X +1943(bound)X +2120(cases)X +2271(\(1)X +2341(Disk)X +2479(and)X +2588(2)X +2637(Disks\),)X +2837(we)X +2928(see)X +3026(that)X +3139(4-6%)X +3294(of)X +3364(the)X +3459(performance)X +3797(is)X +3857(lost)X +3966(due)X +4074(to)X +4140(kernel)X +555 5540(calls)N +688(while)X +846(in)X +912(the)X +1006(CPU)X +1147(bound)X +1323(case,)X +1464(we)X +1554(have)X +1690(lost)X +1799(67%)X +1932(of)X +2001(the)X +2095(performance)X +2432(due)X +2540(to)X +2606(kernel)X +2781(calls.)X + +10 p +%%Page: 10 10 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +555 630(access)N +781(methods,)X +1092(we)X +1206(now)X +1364(have)X +1536(an)X +1632(integrated)X +1973(open)X +2149(call)X +2285(with)X +2447(the)X +2565(following)X +2896(calling)X +3134(conventions:)X +7 f +715 753(DB)N +859(*dbopen)X +1243(\(const)X +1579(char)X +1819(*file,)X +2155(int)X +2347(flags,)X +2683(int)X +2875(mode,)X +3163(DBTYPE)X +3499(type,)X +1291 843(int)N +1483(dbflags,)X +1915(const)X +2203(void)X +2443(*openinfo\))X +1 f +555 966(where)N +2 f +774(\256le)X +1 f +894(is)X +969(the)X +1089(name)X +1285(of)X +1374(the)X +1494(\256le)X +1618(being)X +1818(opened,)X +2 f +2092(\257ags)X +1 f +2265(and)X +2 f +2402(mode)X +1 f +2597(are)X +2717(the)X +2836(standard)X +3129(arguments)X +3484(to)X +3 f +3567(open)X +1 f +3731(\(2\),)X +2 f +3866(type)X +1 f +4021(is)X +4095(one)X +4232(of)X +555 1056(the)N +680(access)X +913(method)X +1180(types,)X +2 f +1396(db\257ags)X +1 f +1654(indicates)X +1966(the)X +2091(mode)X +2296(of)X +2390(the)X +2515(buffer)X +2739(pool)X +2907(and)X +3049(transaction)X +3427(protection,)X +3798(and)X +2 f +3940(openinfo)X +1 f +4246(is)X +555 1146(the)N +681(access)X +915(method)X +1183(speci\256c)X +1456(information.)X +1902(Currently,)X +2257(the)X +2383(possible)X +2673(values)X +2906(for)X +2 f +3028(db\257ags)X +1 f +3287(are)X +3414(DB_SHARED)X +3912(and)X +4055(DB_TP)X +555 1236(indicating)N +895(that)X +1035(buffers)X +1283(should)X +1516(be)X +1612(kept)X +1770(in)X +1852(a)X +1908(shared)X +2138(buffer)X +2355(pool)X +2517(and)X +2653(that)X +2793(the)X +2911(\256le)X +3033(should)X +3266(be)X +3362(transaction)X +3734(protected.)X +755 1359(The)N +900(modi\256cations)X +1355(required)X +1643(to)X +1725(add)X +1861(transaction)X +2233(protection)X +2578(to)X +2660(an)X +2756(access)X +2982(method)X +3242(are)X +3361(quite)X +3541(simple)X +3774(and)X +3910(localized.)X +715 1482(1.)N +795(Replace)X +1074(\256le)X +2 f +1196(open)X +1 f +1372(with)X +2 f +1534(buf_open)X +1 f +1832(.)X +715 1572(2.)N +795(Replace)X +1074(\256le)X +2 f +1196(read)X +1 f +1363(and)X +2 f +1499(write)X +1 f +1683(calls)X +1850(with)X +2012(buffer)X +2229(manager)X +2526(calls)X +2693(\()X +2 f +2720(buf_get)X +1 f +(,)S +2 f +3000(buf_unpin)X +1 f +3324(\).)X +715 1662(3.)N +795(Precede)X +1070(buffer)X +1287(manager)X +1584(calls)X +1751(with)X +1913(an)X +2009(appropriate)X +2395(\(read)X +2581(or)X +2668(write\))X +2880(lock)X +3038(call.)X +715 1752(4.)N +795(Before)X +1034(updates,)X +1319(issue)X +1499(a)X +1555(logging)X +1819(operation.)X +715 1842(5.)N +795(After)X +985(data)X +1139(have)X +1311(been)X +1483(accessed,)X +1805(release)X +2049(the)X +2167(buffer)X +2384(manager)X +2681(pin.)X +715 1932(6.)N +795(Provide)X +1064(undo/redo)X +1409(code)X +1581(for)X +1695(each)X +1863(type)X +2021(of)X +2108(log)X +2230(record)X +2456(de\256ned.)X +555 2071(The)N +702(following)X +1035(code)X +1209(fragments)X +1552(show)X +1743(how)X +1903(to)X +1987(transaction)X +2361(protect)X +2606(several)X +2856(updates)X +3123(to)X +3206(a)X +3263(B-tree.)X +7 s +3484 2039(3)N +10 s +3533 2071(In)N +3621(the)X +3740(unprotected)X +4140(case,)X +555 2161(an)N +652(open)X +829(call)X +966(is)X +1040(followed)X +1346(by)X +1447(a)X +1504(read)X +1664(call)X +1801(to)X +1884(obtain)X +2105(the)X +2224(meta-data)X +2562(for)X +2677(the)X +2796(B-tree.)X +3058(Instead,)X +3331(we)X +3446(issue)X +3627(an)X +3724(open)X +3901(to)X +3984(the)X +4102(buffer)X +555 2251(manager)N +852(to)X +934(obtain)X +1154(a)X +1210(\256le)X +1332(id)X +1414(and)X +1550(a)X +1606(buffer)X +1823(request)X +2075(to)X +2157(obtain)X +2377(the)X +2495(meta-data)X +2832(as)X +2919(shown)X +3148(below.)X +7 f +715 2374(char)N +955(*path;)X +715 2464(int)N +907(fid,)X +1147(flags,)X +1483(len,)X +1723(mode;)X +715 2644(/*)N +859(Obtain)X +1195(a)X +1291(file)X +1531(id)X +1675(with)X +1915(which)X +2203(to)X +2347(access)X +2683(the)X +2875(buffer)X +3211(pool)X +3451(*/)X +715 2734(fid)N +907(=)X +1003(buf_open\(path,)X +1723(flags,)X +2059(mode\);)X +715 2914(/*)N +859(Read)X +1099(the)X +1291(meta)X +1531(data)X +1771(\(page)X +2059(0\))X +2203(for)X +2395(the)X +2587(B-tree)X +2923(*/)X +715 3004(if)N +859(\(tp_lock\(fid,)X +1531(0,)X +1675(READ_LOCK\)\))X +1003 3094(return)N +1339(error;)X +715 3184(meta_data_ptr)N +1387(=)X +1483(buf_get\(fid,)X +2107(0,)X +2251(BF_PIN,)X +2635(&len\);)X +1 f +555 3307(The)N +714(BF_PIN)X +1014(argument)X +1350(to)X +2 f +1445(buf_get)X +1 f +1718(indicates)X +2036(that)X +2189(we)X +2316(wish)X +2500(to)X +2595(leave)X +2798(this)X +2946(page)X +3131(pinned)X +3382(in)X +3477(memory)X +3777(so)X +3881(that)X +4034(it)X +4111(is)X +4197(not)X +555 3397(swapped)N +862(out)X +990(while)X +1194(we)X +1314(are)X +1439(accessing)X +1772(it.)X +1881(The)X +2031(last)X +2167(argument)X +2495(to)X +2 f +2582(buf_get)X +1 f +2847(returns)X +3095(the)X +3218(number)X +3488(of)X +3580(bytes)X +3774(on)X +3879(the)X +4002(page)X +4179(that)X +555 3487(were)N +732(valid)X +912(so)X +1003(that)X +1143(the)X +1261(access)X +1487(method)X +1747(may)X +1905(initialize)X +2205(the)X +2323(page)X +2495(if)X +2564(necessary.)X +755 3610(Next,)N +955(consider)X +1251(inserting)X +1555(a)X +1615(record)X +1845(on)X +1949(a)X +2009(particular)X +2341(page)X +2517(of)X +2608(a)X +2668(B-tree.)X +2932(In)X +3022(the)X +3143(unprotected)X +3545(case,)X +3727(we)X +3844(read)X +4006(the)X +4127(page,)X +555 3700(call)N +2 f +693(_bt_insertat)X +1 f +1079(,)X +1121(and)X +1258(write)X +1444(the)X +1563(page.)X +1776(Instead,)X +2049(we)X +2164(lock)X +2323(the)X +2442(page,)X +2635(request)X +2888(the)X +3007(buffer,)X +3245(log)X +3368(the)X +3487(change,)X +3756(modify)X +4008(the)X +4127(page,)X +555 3790(and)N +691(release)X +935(the)X +1053(buffer.)X +7 f +715 3913(int)N +907(fid,)X +1147(len,)X +1387(pageno;)X +1867(/*)X +2011(Identifies)X +2539(the)X +2731(buffer)X +3067(*/)X +715 4003(int)N +907(index;)X +1867(/*)X +2011(Location)X +2443(at)X +2587(which)X +2875(to)X +3019(insert)X +3355(the)X +3547(new)X +3739(pair)X +3979(*/)X +715 4093(DBT)N +907(*keyp,)X +1243(*datap;)X +1867(/*)X +2011(Key/Data)X +2443(pair)X +2683(to)X +2827(be)X +2971(inserted)X +3403(*/)X +715 4183(DATUM)N +1003(*d;)X +1867(/*)X +2011(Key/data)X +2443(structure)X +2923(to)X +3067(insert)X +3403(*/)X +715 4363(/*)N +859(Lock)X +1099(and)X +1291(request)X +1675(the)X +1867(buffer)X +2203(*/)X +715 4453(if)N +859(\(tp_lock\(fid,)X +1531(pageno,)X +1915(WRITE_LOCK\)\))X +1003 4543(return)N +1339(error;)X +715 4633(buffer_ptr)N +1243(=)X +1339(buf_get\(fid,)X +1963(pageno,)X +2347(BF_PIN,)X +2731(&len\);)X +715 4813(/*)N +859(Log)X +1051(and)X +1243(perform)X +1627(the)X +1819(update)X +2155(*/)X +715 4903(log_insdel\(BTREE_INSERT,)N +1915(fid,)X +2155(pageno,)X +2539(keyp,)X +2827(datap\);)X +715 4993(_bt_insertat\(buffer_ptr,)N +1915(d,)X +2059(index\);)X +715 5083(buf_unpin\(buffer_ptr\);)N +1 f +555 5206(Succinctly,)N +942(the)X +1068(algorithm)X +1407(for)X +1529(turning)X +1788(unprotected)X +2195(code)X +2375(into)X +2527(protected)X +2854(code)X +3034(is)X +3115(to)X +3205(replace)X +3466(read)X +3633(operations)X +3995(with)X +2 f +4165(lock)X +1 f +555 5296(and)N +2 f +691(buf_get)X +1 f +951(operations)X +1305(and)X +1441(write)X +1626(operations)X +1980(with)X +2 f +2142(log)X +1 f +2264(and)X +2 f +2400(buf_unpin)X +1 f +2744(operations.)X +8 s +10 f +555 5458(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5536(3)N +8 s +766 5561(The)N +884(following)X +1152(code)X +1291(fragments)X +1565(are)X +1661(examples,)X +1937(but)X +2038(do)X +2120(not)X +2220(de\256ne)X +2394(the)X +2490(\256nal)X +2622(interface.)X +2894(The)X +3011(\256nal)X +3143(interface)X +3383(will)X +3501(be)X +3579(determined)X +3884(after)X +4018(LIBTP)X +4214(has)X +555 5633(been)N +691(fully)X +828(integrated)X +1099(with)X +1229(the)X +1323(most)X +1464(recent)X +3 f +1635(db)X +1 f +1707(\(3\))X +1797(release)X +1989(from)X +2129(the)X +2223(Computer)X +2495(Systems)X +2725(Research)X +2974(Group)X +3153(at)X +3215(University)X +3501(of)X +3570(California,)X +3861(Berkeley.)X + +11 p +%%Page: 11 11 +8 s 8 xH 0 xS 1 f +10 s +3 f +555 630(5.)N +655(Performance)X +1 f +755 753(In)N +845(this)X +983(section,)X +1253(we)X +1370(present)X +1625(the)X +1746(results)X +1978(of)X +2067(two)X +2209(very)X +2374(different)X +2673(benchmarks.)X +3103(The)X +3250(\256rst)X +3396(is)X +3471(an)X +3569(online)X +3791(transaction)X +4165(pro-)X +555 843(cessing)N +824(benchmark,)X +1234(similar)X +1489(to)X +1584(the)X +1715(standard)X +2020(TPCB,)X +2272(but)X +2407(has)X +2547(been)X +2732(adapted)X +3015(to)X +3110(run)X +3250(in)X +3345(a)X +3414(desktop)X +3696(environment.)X +4174(The)X +555 933(second)N +798(emulates)X +1103(a)X +1159(computer-aided)X +1683(design)X +1912(environment)X +2337(and)X +2473(provides)X +2769(more)X +2954(complex)X +3250(query)X +3453(processing.)X +3 f +555 1119(5.1.)N +715(Transaction)X +1148(Processing)X +1533(Benchmark)X +1 f +755 1242(For)N +887(this)X +1023(section,)X +1291(all)X +1392(performance)X +1820(numbers)X +2117(shown)X +2346(except)X +2576(for)X +2690(the)X +2808(commercial)X +3207(database)X +3504(system)X +3746(were)X +3923(obtained)X +4219(on)X +555 1332(a)N +614(DECstation)X +1009(5000/200)X +1333(with)X +1497(32MBytes)X +1852(of)X +1941(memory)X +2230(running)X +2501(Ultrix)X +2714(V4.0,)X +2914(accessing)X +3244(a)X +3302(DEC)X +3484(RZ57)X +3688(1GByte)X +3959(disk)X +4114(drive.)X +555 1422(The)N +720(commercial)X +1139(relational)X +1482(database)X +1799(system)X +2061(tests)X +2242(were)X +2438(run)X +2584(on)X +2703(a)X +2778(comparable)X +3192(machine,)X +3523(a)X +3598(Sparcstation)X +4033(1+)X +4157(with)X +555 1512(32MBytes)N +915(memory)X +1209(and)X +1352(a)X +1415(1GByte)X +1691(external)X +1976(disk)X +2135(drive.)X +2366(The)X +2517(database,)X +2840(binaries)X +3120(and)X +3262(log)X +3390(resided)X +3648(on)X +3754(the)X +3878(same)X +4069(device.)X +555 1602(Reported)N +869(times)X +1062(are)X +1181(the)X +1299(means)X +1524(of)X +1611(\256ve)X +1751(tests)X +1913(and)X +2049(have)X +2221(standard)X +2513(deviations)X +2862(within)X +3086(two)X +3226(percent)X +3483(of)X +3570(the)X +3688(mean.)X +755 1725(The)N +905(test)X +1041(database)X +1343(was)X +1493(con\256gured)X +1861(according)X +2203(to)X +2290(the)X +2413(TPCB)X +2637(scaling)X +2889(rules)X +3070(for)X +3189(a)X +3250(10)X +3355(transaction)X +3732(per)X +3860(second)X +4108(\(TPS\))X +555 1815(system)N +817(with)X +999(1,000,000)X +1359(account)X +1649(records,)X +1946(100)X +2106(teller)X +2311(records,)X +2607(and)X +2762(10)X +2881(branch)X +3139(records.)X +3455(Where)X +3709(TPS)X +3885(numbers)X +4200(are)X +555 1905(reported,)N +865(we)X +981(are)X +1102(running)X +1373(a)X +1431(modi\256ed)X +1737(version)X +1995(of)X +2084(the)X +2203(industry)X +2486(standard)X +2779(transaction)X +3152(processing)X +3516(benchmark,)X +3914(TPCB.)X +4174(The)X +555 1995(TPCB)N +780(benchmark)X +1163(simulates)X +1491(a)X +1553(withdrawal)X +1940(performed)X +2301(by)X +2407(a)X +2469(hypothetical)X +2891(teller)X +3082(at)X +3166(a)X +3228(hypothetical)X +3650(bank.)X +3872(The)X +4022(database)X +555 2085(consists)N +831(of)X +921(relations)X +1220(\(\256les\))X +1430(for)X +1547(accounts,)X +1871(branches,)X +2200(tellers,)X +2439(and)X +2578(history.)X +2863(For)X +2997(each)X +3168(transaction,)X +3563(the)X +3684(account,)X +3976(teller,)X +4183(and)X +555 2175(branch)N +795(balances)X +1093(must)X +1269(be)X +1366(updated)X +1641(to)X +1724(re\257ect)X +1946(the)X +2065(withdrawal)X +2447(and)X +2584(a)X +2640(history)X +2882(record)X +3108(is)X +3181(written)X +3428(which)X +3644(contains)X +3931(the)X +4049(account)X +555 2265(id,)N +657(branch)X +896(id,)X +998(teller)X +1183(id,)X +1285(and)X +1421(the)X +1539(amount)X +1799(of)X +1886(the)X +2004(withdrawal)X +2385([TPCB90].)X +755 2388(Our)N +914(implementation)X +1450(of)X +1551(the)X +1683(benchmark)X +2074(differs)X +2317(from)X +2506(the)X +2637(speci\256cation)X +3075(in)X +3170(several)X +3431(aspects.)X +3736(The)X +3894(speci\256cation)X +555 2478(requires)N +840(that)X +985(the)X +1108(database)X +1410(keep)X +1587(redundant)X +1933(logs)X +2091(on)X +2196(different)X +2498(devices,)X +2784(but)X +2911(we)X +3030(use)X +3162(a)X +3223(single)X +3439(log.)X +3606(Furthermore,)X +4052(all)X +4157(tests)X +555 2568(were)N +734(run)X +863(on)X +965(a)X +1023(single,)X +1256(centralized)X +1631(system)X +1875(so)X +1968(there)X +2151(is)X +2226(no)X +2328(notion)X +2553(of)X +2641(remote)X +2885(accesses.)X +3219(Finally,)X +3486(we)X +3601(calculated)X +3948(throughput)X +555 2658(by)N +662(dividing)X +955(the)X +1080(total)X +1249(elapsed)X +1517(time)X +1686(by)X +1793(the)X +1918(number)X +2190(of)X +2284(transactions)X +2694(processed)X +3038(rather)X +3253(than)X +3418(by)X +3525(computing)X +3894(the)X +4018(response)X +555 2748(time)N +717(for)X +831(each)X +999(transaction.)X +755 2871(The)N +912(performance)X +1351(comparisons)X +1788(focus)X +1993(on)X +2104(traditional)X +2464(Unix)X +2655(techniques)X +3029(\(unprotected,)X +3486(using)X +3 f +3690(\257ock)X +1 f +3854(\(2\))X +3979(and)X +4126(using)X +3 f +555 2961(fsync)N +1 f +733(\(2\)\))X +884(and)X +1030(a)X +1096(commercial)X +1504(relational)X +1836(database)X +2142(system.)X +2433(Well-behaved)X +2913(applications)X +3329(using)X +3 f +3531(\257ock)X +1 f +3695(\(2\))X +3818(are)X +3946(guaranteed)X +555 3051(that)N +704(concurrent)X +1077(processes')X +1441(updates)X +1715(do)X +1824(not)X +1955(interact)X +2225(with)X +2396(one)X +2541(another,)X +2831(but)X +2962(no)X +3070(guarantees)X +3442(about)X +3648(atomicity)X +3978(are)X +4105(made.)X +555 3141(That)N +731(is,)X +833(if)X +911(the)X +1038(system)X +1289(crashes)X +1555(in)X +1646(mid-transaction,)X +2198(only)X +2369(parts)X +2554(of)X +2649(that)X +2797(transaction)X +3177(will)X +3329(be)X +3433(re\257ected)X +3738(in)X +3828(the)X +3954 0.3125(after-crash)AX +555 3231(state)N +725(of)X +815(the)X +936(database.)X +1276(The)X +1424(use)X +1554(of)X +3 f +1643(fsync)X +1 f +1821(\(2\))X +1937(at)X +2017(transaction)X +2391(commit)X +2657(time)X +2821(provides)X +3119(guarantees)X +3485(of)X +3574(durability)X +3907(after)X +4077(system)X +555 3321(failure.)N +825(However,)X +1160(there)X +1341(is)X +1414(no)X +1514(mechanism)X +1899(to)X +1981(perform)X +2260(transaction)X +2632(abort.)X +3 f +555 3507(5.1.1.)N +775(Single-User)X +1191(Tests)X +1 f +755 3630(These)N +978(tests)X +1151(compare)X +1459(LIBTP)X +1712(in)X +1804(a)X +1870(variety)X +2123(of)X +2220(con\256gurations)X +2708(to)X +2800(traditional)X +3159(UNIX)X +3390(solutions)X +3708(and)X +3854(a)X +3920(commercial)X +555 3720(relational)N +884(database)X +1187(system)X +1435(\(RDBMS\).)X +1814(To)X +1929(demonstrate)X +2347(the)X +2471(server)X +2694(architecture)X +3100(we)X +3220(built)X +3392(a)X +3454(front)X +3636(end)X +3777(test)X +3913(process)X +4179(that)X +555 3810(uses)N +732(TCL)X +922([OUST90])X +1304(to)X +1405(parse)X +1614(database)X +1930(access)X +2175(commands)X +2561(and)X +2716(call)X +2870(the)X +3006(database)X +3321(access)X +3565(routines.)X +3901(In)X +4006(one)X +4160(case)X +555 3900(\(SERVER\),)N +956(frontend)X +1249(and)X +1386(backend)X +1675(processes)X +2004(were)X +2181(created)X +2434(which)X +2650(communicated)X +3142(via)X +3260(an)X +3356(IP)X +3447(socket.)X +3712(In)X +3799(the)X +3917(second)X +4160(case)X +555 3990(\(TCL\),)N +802(a)X +860(single)X +1073(process)X +1336(read)X +1497(queries)X +1751(from)X +1929(standard)X +2223(input,)X +2429(parsed)X +2660(them,)X +2861(and)X +2998(called)X +3211(the)X +3330(database)X +3628(access)X +3855(routines.)X +4174(The)X +555 4080(performance)N +987(difference)X +1338(between)X +1630(the)X +1752(TCL)X +1927(and)X +2067(SERVER)X +2397(tests)X +2563(quanti\256es)X +2898(the)X +3020(communication)X +3542(overhead)X +3861(of)X +3952(the)X +4074(socket.)X +555 4170(The)N +732(RDBMS)X +1063(implementation)X +1617(used)X +1816(embedded)X +2198(SQL)X +2401(in)X +2515(C)X +2620(with)X +2814(stored)X +3062(database)X +3391(procedures.)X +3835(Therefore,)X +4224(its)X +555 4260(con\256guration)N +1003(is)X +1076(a)X +1132(hybrid)X +1361(of)X +1448(the)X +1566(single)X +1777(process)X +2038(architecture)X +2438(and)X +2574(the)X +2692(server)X +2909(architecture.)X +3349(The)X +3494(graph)X +3697(in)X +3779(\256gure)X +3986(six)X +4099(shows)X +555 4350(a)N +611(comparison)X +1005(of)X +1092(the)X +1210(following)X +1541(six)X +1654(con\256gurations:)X +1126 4506(LIBTP)N +1552(Uses)X +1728(the)X +1846(LIBTP)X +2088(library)X +2322(in)X +2404(a)X +2460(single)X +2671(application.)X +1126 4596(TCL)N +1552(Uses)X +1728(the)X +1846(LIBTP)X +2088(library)X +2322(in)X +2404(a)X +2460(single)X +2671(application,)X +3067(requires)X +3346(query)X +3549(parsing.)X +1126 4686(SERVER)N +1552(Uses)X +1728(the)X +1846(LIBTP)X +2088(library)X +2322(in)X +2404(a)X +2460(server)X +2677(con\256guration,)X +3144(requires)X +3423(query)X +3626(parsing.)X +1126 4776(NOTP)N +1552(Uses)X +1728(no)X +1828(locking,)X +2108(logging,)X +2392(or)X +2479(concurrency)X +2897(control.)X +1126 4866(FLOCK)N +1552(Uses)X +3 f +1728(\257ock)X +1 f +1892(\(2\))X +2006(for)X +2120(concurrency)X +2538(control)X +2785(and)X +2921(nothing)X +3185(for)X +3299(durability.)X +1126 4956(FSYNC)N +1552(Uses)X +3 f +1728(fsync)X +1 f +1906(\(2\))X +2020(for)X +2134(durability)X +2465(and)X +2601(nothing)X +2865(for)X +2979(concurrency)X +3397(control.)X +1126 5046(RDBMS)N +1552(Uses)X +1728(a)X +1784(commercial)X +2183(relational)X +2506(database)X +2803(system.)X +755 5235(The)N +902(results)X +1133(show)X +1324(that)X +1466(LIBTP,)X +1730(both)X +1894(in)X +1978(the)X +2098(procedural)X +2464(and)X +2602(parsed)X +2834(environments,)X +3312(is)X +3387(competitive)X +3787(with)X +3951(a)X +4009(commer-)X +555 5325(cial)N +692(system)X +935(\(comparing)X +1326(LIBTP,)X +1589(TCL,)X +1781(and)X +1917(RDBMS\).)X +2263(Compared)X +2617(to)X +2699(existing)X +2972(UNIX)X +3193(solutions,)X +3521(LIBTP)X +3763(is)X +3836(approximately)X +555 5415(15%)N +738(slower)X +988(than)X +1162(using)X +3 f +1371(\257ock)X +1 f +1535(\(2\))X +1665(or)X +1768(no)X +1884(protection)X +2245(but)X +2383(over)X +2562(80%)X +2745(better)X +2964(than)X +3137(using)X +3 f +3345(fsync)X +1 f +3523(\(2\))X +3652(\(comparing)X +4057(LIBTP,)X +555 5505(FLOCK,)N +857(NOTP,)X +1106(and)X +1242(FSYNC\).)X + +12 p +%%Page: 12 12 +10 s 10 xH 0 xS 1 f +3 f +8 s +3500 2184(RDBMS)N +1 Dt +3553 2085 MXY + 3553 2085 lineto + 3676 2085 lineto + 3676 1351 lineto + 3553 1351 lineto + 3553 2085 lineto +closepath 16 3553 1351 3676 2085 Dp +2018 2184(SERVER)N +1720 1168 MXY +0 917 Dl +122 0 Dl +0 -917 Dl +-122 0 Dl +1715 2184(TCL)N +2087 1534 MXY + 2087 1534 lineto + 2209 1534 lineto + 2209 2085 lineto + 2087 2085 lineto + 2087 1534 lineto +closepath 12 2087 1534 2209 2085 Dp +3187 MX + 3187 1534 lineto + 3309 1534 lineto + 3309 2085 lineto + 3187 2085 lineto + 3187 1534 lineto +closepath 19 3187 1534 3309 2085 Dp +3142 2184(FSYNC)N +2425(NOTP)X +2453 955 MXY + 2453 955 lineto + 2576 955 lineto + 2576 2085 lineto + 2453 2085 lineto + 2453 955 lineto +closepath 21 2453 955 2576 2085 Dp +2820 1000 MXY + 2820 1000 lineto + 2942 1000 lineto + 2942 2085 lineto + 2820 2085 lineto + 2820 1000 lineto +closepath 14 2820 1000 2942 2085 Dp +5 Dt +1231 2085 MXY +2567 0 Dl +4 Ds +1 Dt +1231 1840 MXY +2567 0 Dl +1231 1596 MXY +2567 0 Dl +1231 1351 MXY +2567 0 Dl +1231 1108 MXY +2567 0 Dl +1231 863 MXY +2567 0 Dl +11 s +1087 1877(2)N +1087 1633(4)N +1087 1388(6)N +1087 1145(8)N +1065 900(10)N +1028 763(TPS)N +-1 Ds +1353 2085 MXY + 1353 2085 lineto + 1353 1151 lineto + 1476 1151 lineto + 1476 2085 lineto + 1353 2085 lineto +closepath 3 1353 1151 1476 2085 Dp +8 s +1318 2184(LIBTP)N +2767(FLOCK)X +3 Dt +-1 Ds +10 s +1597 2399(Figure)N +1844(6:)X +1931(Single-User)X +2347(Performance)X +2814(Comparison.)X +1 f +10 f +555 2579(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +3 f +555 2855(5.1.2.)N +775(Multi-User)X +1174(Tests)X +1 f +755 2978(While)N +975(the)X +1097(single-user)X +1473(tests)X +1639(form)X +1819(a)X +1878(basis)X +2061(for)X +2178(comparing)X +2544(LIBTP)X +2789(to)X +2874(other)X +3062(systems,)X +3358(our)X +3488(goal)X +3649(in)X +3734(multi-user)X +4086(testing)X +555 3068(was)N +714(to)X +810(analyze)X +1089(its)X +1197(scalability.)X +1579(To)X +1701(this)X +1849(end,)X +2018(we)X +2145(have)X +2330(run)X +2470(the)X +2601(benchmark)X +2991(in)X +3086(three)X +3280(modes,)X +3542(the)X +3673(normal)X +3933(disk)X +4099(bound)X +555 3158(con\256guration)N +1010(\(\256gure)X +1252(seven\),)X +1510(a)X +1573(CPU)X +1755(bound)X +1982(con\256guration)X +2436(\(\256gure)X +2677(eight,)X +2884(READ-ONLY\),)X +3426(and)X +3569(lock)X +3734(contention)X +4099(bound)X +555 3248(\(\256gure)N +796(eight,)X +1003(NO_FSYNC\).)X +1510(Since)X +1715(the)X +1840(normal)X +2094(con\256guration)X +2548(is)X +2628(completely)X +3011(disk)X +3171(bound)X +3398(\(each)X +3600(transaction)X +3978(requires)X +4263(a)X +555 3354(random)N +823(read,)X +1005(a)X +1064(random)X +1332(write,)X +1540(and)X +1679(a)X +1738(sequential)X +2086(write)X +7 s +2251 3322(4)N +10 s +3354(\))Y +2329(we)X +2446(expect)X +2679(to)X +2764(see)X +2890(little)X +3059(performance)X +3489(improvement)X +3939(as)X +4028(the)X +4148(mul-)X +555 3444(tiprogramming)N +1064(level)X +1249(increases.)X +1613(In)X +1709(fact,)X +1879(\256gure)X +2095(seven)X +2307(reveals)X +2564(that)X +2713(we)X +2836(are)X +2964(able)X +3127(to)X +3218(overlap)X +3487(CPU)X +3670(and)X +3814(disk)X +3975(utilization)X +555 3534(slightly)N +825(producing)X +1181(approximately)X +1674(a)X +1740(10%)X +1917(performance)X +2354(improvement)X +2811(with)X +2983(two)X +3133(processes.)X +3511(After)X +3711(that)X +3861(point,)X +4075(perfor-)X +555 3624(mance)N +785(drops)X +983(off,)X +1117(and)X +1253(at)X +1331(a)X +1387(multi-programming)X +2038(level)X +2214(of)X +2301(4,)X +2381(we)X +2495(are)X +2614(performing)X +2995(worse)X +3207(than)X +3365(in)X +3447(the)X +3565(single)X +3776(process)X +4037(case.)X +755 3747(Similar)N +1021(behavior)X +1333(was)X +1489(reported)X +1787(on)X +1897(the)X +2025(commercial)X +2434(relational)X +2767(database)X +3074(system)X +3326(using)X +3529(the)X +3657(same)X +3852(con\256guration.)X +555 3837(The)N +707(important)X +1045(conclusion)X +1419(to)X +1508(draw)X +1696(from)X +1879(this)X +2021(is)X +2101(that)X +2248(you)X +2395(cannot)X +2636(attain)X +2841(good)X +3028(multi-user)X +3384(scaling)X +3638(on)X +3745(a)X +3808(badly)X +4013(balanced)X +555 3927(system.)N +839(If)X +915(multi-user)X +1266(performance)X +1695(on)X +1797(applications)X +2205(of)X +2293(this)X +2429(sort)X +2570(is)X +2644(important,)X +2996(one)X +3133(must)X +3309(have)X +3482(a)X +3539(separate)X +3824(logging)X +4089(device)X +555 4017(and)N +697(horizontally)X +1110(partition)X +1407(the)X +1531(database)X +1834(to)X +1921(allow)X +2124(a)X +2185(suf\256ciently)X +2570(high)X +2737(degree)X +2977(of)X +3069(multiprogramming)X +3698(that)X +3843(group)X +4055(commit)X +555 4107(can)N +687(amortize)X +988(the)X +1106(cost)X +1255(of)X +1342(log)X +1464(\257ushing.)X +755 4230(By)N +871(using)X +1067(a)X +1126(very)X +1292(small)X +1488(database)X +1788(\(one)X +1954(that)X +2097(can)X +2232(be)X +2331(entirely)X +2599(cached)X +2846(in)X +2930(main)X +3112(memory\))X +3428(and)X +3566(read-only)X +3896(transactions,)X +555 4320(we)N +670(generated)X +1004(a)X +1061(CPU)X +1236(bound)X +1456(environment.)X +1921(By)X +2034(using)X +2227(the)X +2345(same)X +2530(small)X +2723(database,)X +3040(the)X +3158(complete)X +3472(TPCB)X +3691(transaction,)X +4083(and)X +4219(no)X +3 f +555 4410(fsync)N +1 f +733(\(2\))X +862(on)X +977(the)X +1110(log)X +1247(at)X +1340(commit,)X +1639(we)X +1768(created)X +2036(a)X +2107(lock)X +2280(contention)X +2652(bound)X +2886(environment.)X +3365(The)X +3524(small)X +3731(database)X +4042(used)X +4223(an)X +555 4500(account)N +828(\256le)X +953(containing)X +1314(only)X +1479(1000)X +1662(records)X +1922(rather)X +2133(than)X +2294(the)X +2415(full)X +2549(1,000,000)X +2891(records)X +3150(and)X +3288(ran)X +3413(enough)X +3671(transactions)X +4076(to)X +4160(read)X +555 4590(the)N +677(entire)X +883(database)X +1183(into)X +1330(the)X +1451(buffer)X +1671(pool)X +1836(\(2000\))X +2073(before)X +2302(beginning)X +2645(measurements.)X +3147(The)X +3295(read-only)X +3626(transaction)X +4001(consisted)X +555 4680(of)N +646(three)X +831(database)X +1132(reads)X +1326(\(from)X +1533(the)X +1655(1000)X +1839(record)X +2069(account)X +2343(\256le,)X +2489(the)X +2611(100)X +2754(record)X +2983(teller)X +3171(\256le,)X +3316(and)X +3455(the)X +3576(10)X +3679(record)X +3908(branch)X +4150(\256le\).)X +555 4770(Since)N +759(no)X +865(data)X +1025(were)X +1208(modi\256ed)X +1518(and)X +1660(no)X +1766(history)X +2014(records)X +2277(were)X +2460(written,)X +2733(no)X +2839(log)X +2966(records)X +3228(were)X +3410(written.)X +3702(For)X +3838(the)X +3961(contention)X +555 4860(bound)N +780(con\256guration,)X +1252(we)X +1371(used)X +1543(the)X +1666(normal)X +1918(TPCB)X +2142(transaction)X +2519(\(against)X +2798(the)X +2920(small)X +3117(database\))X +3445(and)X +3585(disabled)X +3876(the)X +3998(log)X +4124(\257ush.)X +555 4950(Figure)N +784(eight)X +964(shows)X +1184(both)X +1346(of)X +1433(these)X +1618(results.)X +755 5073(The)N +902(read-only)X +1231(test)X +1363(indicates)X +1669(that)X +1810(we)X +1925(barely)X +2147(scale)X +2329(at)X +2408(all)X +2509(in)X +2592(the)X +2711(CPU)X +2887(bound)X +3108(case.)X +3308(The)X +3454(explanation)X +3849(for)X +3964(that)X +4105(is)X +4179(that)X +555 5163(even)N +735(with)X +905(a)X +969(single)X +1188(process,)X +1477(we)X +1599(are)X +1726(able)X +1888(to)X +1978(drive)X +2171(the)X +2297(CPU)X +2480(utilization)X +2832(to)X +2922(96%.)X +3137(As)X +3254(a)X +3317(result,)X +3542(that)X +3689(gives)X +3885(us)X +3983(very)X +4153(little)X +555 5253(room)N +753(for)X +876(improvement,)X +1352(and)X +1497(it)X +1570(takes)X +1764(a)X +1829(multiprogramming)X +2462(level)X +2647(of)X +2743(four)X +2906(to)X +2997(approach)X +3321(100%)X +3537(CPU)X +3721(saturation.)X +4106(In)X +4201(the)X +555 5343(case)N +718(where)X +939(we)X +1057(do)X +1161(perform)X +1444(writes,)X +1684(we)X +1802(are)X +1925(interested)X +2261(in)X +2347(detecting)X +2665(when)X +2863(lock)X +3025(contention)X +3387(becomes)X +3691(a)X +3750(dominant)X +4075(perfor-)X +555 5433(mance)N +787(factor.)X +1037(Contention)X +1414(will)X +1560(cause)X +1761(two)X +1903(phenomena;)X +2317(we)X +2433(will)X +2579(see)X +2704(transactions)X +3109(queueing)X +3425(behind)X +3665(frequently)X +4017(accessed)X +555 5523(data,)N +731(and)X +869(we)X +985(will)X +1131(see)X +1256(transaction)X +1629(abort)X +1815(rates)X +1988(increasing)X +2339(due)X +2476(to)X +2559(deadlock.)X +2910(Given)X +3127(that)X +3268(the)X +3387(branch)X +3627(\256le)X +3750(contains)X +4038(only)X +4201(ten)X +8 s +10 f +555 5595(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5673(4)N +8 s +763 5698(Although)N +1021(the)X +1115(log)X +1213(is)X +1272(written)X +1469(sequentially,)X +1810(we)X +1900(do)X +1980(not)X +2078(get)X +2172(the)X +2266(bene\256t)X +2456(of)X +2525(sequentiality)X +2868(since)X +3015(the)X +3109(log)X +3207(and)X +3315(database)X +3550(reside)X +3718(on)X +3798(the)X +3892(same)X +4039(disk.)X + +13 p +%%Page: 13 13 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +3187 2051 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3286 2028 MXY +0 17 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3384 1926 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3483 1910 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3581 1910 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3680 1832 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3778 1909 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3877 1883 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3975 1679 MXY +0 17 Dl +0 -8 Dl +9 0 Dl +-18 0 Dl +4074 1487 MXY +0 17 Dl +0 -8 Dl +9 0 Dl +-18 0 Dl +5 Dt +3187 2060 MXY +99 -24 Dl +98 -101 Dl +99 -16 Dl +98 0 Dl +99 -78 Dl +98 77 Dl +99 -26 Dl +98 -204 Dl +99 -192 Dl +3 f +6 s +4088 1516(SMALL)N +3 Dt +3187 2051 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3286 2051 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3384 2041 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3483 1990 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3581 1843 MXY +0 17 Dl +0 -8 Dl +9 0 Dl +-18 0 Dl +3680 1578 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3778 1496 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3877 1430 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3975 1269 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +4074 1070 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1 Dt +3187 2060 MXY +99 0 Dl +98 -10 Dl +99 -51 Dl +98 -147 Dl +99 -265 Dl +98 -82 Dl +99 -66 Dl +98 -161 Dl +99 -199 Dl +4088 1099(LARGE)N +5 Dt +3089 2060 MXY +985 0 Dl +3089 MX +0 -1174 Dl +4 Ds +1 Dt +3581 2060 MXY +0 -1174 Dl +4074 2060 MXY +0 -1174 Dl +3089 1825 MXY +985 0 Dl +9 s +2993 1855(25)N +3089 1591 MXY +985 0 Dl +2993 1621(50)N +3089 1356 MXY +985 0 Dl +2993 1386(75)N +3089 1121 MXY +985 0 Dl +2957 1151(100)N +3089 886 MXY +985 0 Dl +2957 916(125)N +3281 2199(Multiprogramming)N +3071 2152(0)N +3569(5)X +4038(10)X +2859 787(Aborts)N +3089(per)X +3211(500)X +2901 847(transactions)N +-1 Ds +3 Dt +2037 1342 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2125 1358 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2213 1341 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2301 1191 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2388 1124 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-17 0 Dl +2476 1157 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2564 1157 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2652 1161 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2740 1153 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2828 1150 MXY +0 18 Dl +0 -9 Dl +8 0 Dl +-17 0 Dl +5 Dt +2037 1351 MXY +88 16 Dl +88 -17 Dl +88 -150 Dl +87 -67 Dl +88 33 Dl +88 0 Dl +88 4 Dl +88 -8 Dl +88 -3 Dl +6 s +2685 1234(READ-ONLY)N +3 Dt +2037 1464 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2125 1640 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2213 1854 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2301 1872 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2388 1871 MXY +0 17 Dl +0 -9 Dl +9 0 Dl +-17 0 Dl +2476 1933 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2564 1914 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2652 1903 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2740 1980 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2828 2004 MXY +0 18 Dl +0 -9 Dl +8 0 Dl +-17 0 Dl +1 Dt +2037 1473 MXY +88 176 Dl +88 214 Dl +88 18 Dl +87 -2 Dl +88 63 Dl +88 -19 Dl +88 -11 Dl +88 77 Dl +88 24 Dl +2759 1997(NO-FSYNC)N +5 Dt +1949 2060 MXY +879 0 Dl +1949 MX +0 -1174 Dl +4 Ds +1 Dt +2388 2060 MXY +0 -1174 Dl +2828 2060 MXY +0 -1174 Dl +1949 1825 MXY +879 0 Dl +9 s +1842 1855(40)N +1949 1591 MXY +879 0 Dl +1842 1621(80)N +1949 1356 MXY +879 0 Dl +1806 1386(120)N +1949 1121 MXY +879 0 Dl +1806 1151(160)N +1949 886 MXY +879 0 Dl +1806 916(200)N +2088 2199(Multiprogramming)N +1844 863(in)N +1922(TPS)X +1761 792(Throughput)N +1931 2121(0)N +2370 2133(5)N +2792(10)X +6 s +1679 1833(LIBTP)N +-1 Ds +3 Dt +837 1019 MXY +0 17 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +929 878 MXY +0 17 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1021 939 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1113 1043 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1205 1314 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1297 1567 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1389 1665 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1481 1699 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1573 1828 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1665 1804 MXY +0 18 Dl +0 -9 Dl +8 0 Dl +-17 0 Dl +5 Dt +837 1027 MXY +92 -141 Dl +92 62 Dl +92 104 Dl +92 271 Dl +92 253 Dl +92 98 Dl +92 34 Dl +92 129 Dl +92 -24 Dl +745 2060 MXY +920 0 Dl +745 MX +0 -1174 Dl +4 Ds +1 Dt +1205 2060 MXY +0 -1174 Dl +1665 2060 MXY +0 -1174 Dl +745 1766 MXY +920 0 Dl +9 s +673 1796(3)N +745 1473 MXY +920 0 Dl +673 1503(5)N +745 1180 MXY +920 0 Dl +673 1210(8)N +745 886 MXY +920 0 Dl +637 916(10)N +905 2199(Multiprogramming)N +622 851(in)N +700(TPS)X +575 792(Throughput)N +733 2152(0)N +1196(5)X +1629(10)X +3 Dt +-1 Ds +8 s +655 2441(Figure)N +872(7:)X +960(Multi-user)X +1286(Performance.)X +1 f +655 2531(Since)N +825(the)X +931(con\256guration)X +1300(is)X +1371(completely)X +655 2621(disk)N +790(bound,)X +994(we)X +1096(see)X +1204(only)X +1345(a)X +1400(small)X +1566(im-)X +655 2711(provement)N +964(by)X +1064(adding)X +1274(a)X +1337(second)X +1549(pro-)X +655 2801(cess.)N +849(Adding)X +1081(any)X +1213(more)X +1383(concurrent)X +655 2891(processes)N +935(causes)X +1137(performance)X +1493(degra-)X +655 2981(dation.)N +3 f +1927 2441(Figure)N +2149(8:)X +2243(Multi-user)X +2574(Performance)X +1927 2531(on)N +2021(a)X +2079(small)X +2251(database.)X +1 f +2551(With)X +2704(one)X +2821(pro-)X +1927 2621(cess,)N +2075(we)X +2174(are)X +2276(driving)X +2486(the)X +2589(CPU)X +2739(at)X +2810(96%)X +1927 2711(utilization)N +2215(leaving)X +2430(little)X +2575(room)X +2737(for)X +2838(im-)X +1927 2801(provement)N +2238(as)X +2328(the)X +2443(multiprogramming)X +1927 2891(level)N +2091(increases.)X +2396(In)X +2489(the)X +2607(NO-FSYNC)X +1927 2981(case,)N +2076(lock)X +2209(contention)X +2502(degrades)X +2751(perfor-)X +1927 3071(mance)N +2117(as)X +2194(soon)X +2339(as)X +2416(a)X +2468(second)X +2669(process)X +2884(is)X +1927 3161(added.)N +3 f +3199 2441(Figure)N +3405(9:)X +3482(Abort)X +3669(rates)X +3827(on)X +3919(the)X +4028(TPCB)X +3199 2531(Benchmark.)N +1 f +3589(The)X +3726(abort)X +3895(rate)X +4028(climbs)X +3199 2621(more)N +3366(quickly)X +3594(for)X +3704(the)X +3818(large)X +3980(database)X +3199 2711(test)N +3324(since)X +3491(processes)X +3771(are)X +3884(descheduled)X +3199 2801(more)N +3409(frequently,)X +3766(allowing)X +4068(more)X +3199 2891(processes)N +3459(to)X +3525(vie)X +3619(for)X +3709(the)X +3803(same)X +3950(locks.)X +10 s +10 f +555 3284(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +1 f +555 3560(records,)N +835(we)X +952(expect)X +1185(contention)X +1546(to)X +1631(become)X +1904(a)X +1963(factor)X +2174(quickly)X +2437(and)X +2576(the)X +2697(NO-FSYNC)X +3120(line)X +3263(in)X +3348(\256gure)X +3557(eight)X +3739(demonstrates)X +4184(this)X +555 3650(dramatically.)N +1022(Each)X +1209(additional)X +1555(process)X +1822(causes)X +2058(both)X +2226(more)X +2417(waiting)X +2682(and)X +2823(more)X +3013(deadlocking.)X +3470(Figure)X +3704(nine)X +3867(shows)X +4092(that)X +4237(in)X +555 3740(the)N +681(small)X +882(database)X +1187(case)X +1353(\(SMALL\),)X +1725(waiting)X +1992(is)X +2072(the)X +2197(dominant)X +2526(cause)X +2732(of)X +2826(declining)X +3151(performance)X +3585(\(the)X +3737(number)X +4009(of)X +4103(aborts)X +555 3830(increases)N +878(less)X +1026(steeply)X +1281(than)X +1447(the)X +1573(performance)X +2008(drops)X +2214(off)X +2336(in)X +2426(\256gure)X +2641(eight\),)X +2876(while)X +3082(in)X +3172(the)X +3298(large)X +3487(database)X +3792(case)X +3958(\(LARGE\),)X +555 3920(deadlocking)N +967(contributes)X +1343(more)X +1528(to)X +1610(the)X +1728(declining)X +2046(performance.)X +755 4043(Deadlocks)N +1116(are)X +1237(more)X +1424(likely)X +1628(to)X +1712(occur)X +1913(in)X +1997(the)X +2116(LARGE)X +2404(test)X +2536(than)X +2695(in)X +2778(the)X +2897(SMALL)X +3189(test)X +3321(because)X +3597(there)X +3779(are)X +3899(more)X +4085(oppor-)X +555 4133(tunities)N +814(to)X +900(wait.)X +1082(In)X +1173(the)X +1295(SMALL)X +1590(case,)X +1773(processes)X +2105(never)X +2307(do)X +2410(I/O)X +2540(and)X +2679(are)X +2801(less)X +2944(likely)X +3149(to)X +3234(be)X +3333(descheduled)X +3753(during)X +3985(a)X +4044(transac-)X +555 4223(tion.)N +740(In)X +828(the)X +947(LARGE)X +1235(case,)X +1415(processes)X +1744(will)X +1889(frequently)X +2240(be)X +2337(descheduled)X +2755(since)X +2941(they)X +3100(have)X +3273(to)X +3356(perform)X +3636(I/O.)X +3804(This)X +3967(provides)X +4263(a)X +555 4313(window)N +837(where)X +1058(a)X +1118(second)X +1365(process)X +1630(can)X +1766(request)X +2022(locks)X +2215(on)X +2318(already)X +2578(locked)X +2815(pages,)X +3041(thus)X +3197(increasing)X +3550(the)X +3671(likelihood)X +4018(of)X +4108(build-)X +555 4403(ing)N +677(up)X +777(long)X +939(chains)X +1164(of)X +1251(waiting)X +1511(processes.)X +1879(Eventually,)X +2266(this)X +2401(leads)X +2586(to)X +2668(deadlock.)X +3 f +555 4589(5.2.)N +715(The)X +868(OO1)X +1052(Benchmark)X +1 f +755 4712(The)N +903(TPCB)X +1125(benchmark)X +1505(described)X +1836(in)X +1921(the)X +2042(previous)X +2341(section)X +2591(measures)X +2913(performance)X +3343(under)X +3549(a)X +3608(conventional)X +4044(transac-)X +555 4802(tion)N +706(processing)X +1076(workload.)X +1446(Other)X +1656(application)X +2039(domains,)X +2357(such)X +2531(as)X +2625(computer-aided)X +3156(design,)X +3412(have)X +3591(substantially)X +4022(different)X +555 4892(access)N +786(patterns.)X +1105(In)X +1197(order)X +1392(to)X +1479(measure)X +1772(the)X +1895(performance)X +2327(of)X +2418(LIBTP)X +2664(under)X +2871(workloads)X +3229(of)X +3320(this)X +3459(type,)X +3641(we)X +3759(implemented)X +4201(the)X +555 4982(OO1)N +731(benchmark)X +1108(described)X +1436(in)X +1518([CATT91].)X +755 5105(The)N +908(database)X +1213(models)X +1472(a)X +1535(set)X +1651(of)X +1745(electronics)X +2120(components)X +2534(with)X +2703(connections)X +3113(among)X +3358(them.)X +3585(One)X +3746(table)X +3929(stores)X +4143(parts)X +555 5195(and)N +696(another)X +962(stores)X +1174(connections.)X +1622(There)X +1835(are)X +1959(three)X +2145(connections)X +2552(originating)X +2927(at)X +3009(any)X +3149(given)X +3351(part.)X +3540(Ninety)X +3782(percent)X +4043(of)X +4134(these)X +555 5285(connections)N +960(are)X +1081(to)X +1165(nearby)X +1406(parts)X +1584(\(those)X +1802(with)X +1966(nearby)X +2 f +2207(ids)X +1 f +2300(\))X +2348(to)X +2431(model)X +2652(the)X +2771(spatial)X +3001(locality)X +3262(often)X +3448(exhibited)X +3767(in)X +3850(CAD)X +4040(applica-)X +555 5375(tions.)N +779(Ten)X +933(percent)X +1198(of)X +1293(the)X +1419(connections)X +1830(are)X +1957(randomly)X +2292(distributed)X +2662(among)X +2908(all)X +3016(other)X +3209(parts)X +3393(in)X +3483(the)X +3609(database.)X +3954(Every)X +4174(part)X +555 5465(appears)N +829(exactly)X +1089(three)X +1278(times)X +1479(in)X +1569(the)X +2 f +1695(from)X +1 f +1874(\256eld)X +2043(of)X +2137(a)X +2200(connection)X +2579(record,)X +2832(and)X +2975(zero)X +3141(or)X +3235(more)X +3427(times)X +3627(in)X +3716(the)X +2 f +3841(to)X +1 f +3930(\256eld.)X +4139(Parts)X +555 5555(have)N +2 f +727(x)X +1 f +783(and)X +2 f +919(y)X +1 f +975(locations)X +1284(set)X +1393(randomly)X +1720(in)X +1802(an)X +1898(appropriate)X +2284(range.)X + +14 p +%%Page: 14 14 +10 s 10 xH 0 xS 1 f +3 f +1 f +755 630(The)N +900(intent)X +1102(of)X +1189(OO1)X +1365(is)X +1438(to)X +1520(measure)X +1808(the)X +1926(overall)X +2169(cost)X +2318(of)X +2405(a)X +2461(query)X +2664(mix)X +2808(characteristic)X +3257(of)X +3344(engineering)X +3743(database)X +4040(applica-)X +555 720(tions.)N +770(There)X +978(are)X +1097(three)X +1278(tests:)X +10 f +635 843(g)N +2 f +755(Lookup)X +1 f +1022(generates)X +1353(1,000)X +1560(random)X +1832(part)X +2 f +1984(ids)X +1 f +2077(,)X +2124(fetches)X +2378(the)X +2502(corresponding)X +2987(parts)X +3169(from)X +3351(the)X +3475(database,)X +3798(and)X +3940(calls)X +4113(a)X +4175(null)X +755 933(procedure)N +1097(in)X +1179(the)X +1297(host)X +1450(programming)X +1906(language)X +2216(with)X +2378(the)X +2496(parts')X +2 f +2699(x)X +1 f +2755(and)X +2 f +2891(y)X +1 f +2947(positions.)X +10 f +635 1056(g)N +2 f +755(Traverse)X +1 f +1067(retrieves)X +1371(a)X +1434(random)X +1706(part)X +1858(from)X +2041(the)X +2166(database)X +2470(and)X +2613(follows)X +2880(connections)X +3290(from)X +3473(it)X +3544(to)X +3632(other)X +3823(parts.)X +4045(Each)X +4232(of)X +755 1146(those)N +947(parts)X +1126(is)X +1202(retrieved,)X +1531(and)X +1670(all)X +1773(connections)X +2179(from)X +2358(it)X +2424(followed.)X +2771(This)X +2935(procedure)X +3279(is)X +3354(repeated)X +3649(depth-\256rst)X +4000(for)X +4116(seven)X +755 1236(hops)N +930(from)X +1110(the)X +1232(original)X +1505(part,)X +1674(for)X +1792(a)X +1852(total)X +2018(of)X +2109(3280)X +2293(parts.)X +2513(Backward)X +2862(traversal)X +3162(also)X +3314(exists,)X +3539(and)X +3678(follows)X +3941(all)X +4044(connec-)X +755 1326(tions)N +930(into)X +1074(a)X +1130(given)X +1328(part)X +1473(to)X +1555(their)X +1722(origin.)X +10 f +635 1449(g)N +2 f +755(Insert)X +1 f +962(adds)X +1129(100)X +1269(new)X +1423(parts)X +1599(and)X +1735(their)X +1902(connections.)X +755 1572(The)N +913(benchmark)X +1303(is)X +1389(single-user,)X +1794(but)X +1929(multi-user)X +2291(access)X +2530(controls)X +2821(\(locking)X +3120(and)X +3268(transaction)X +3652(protection\))X +4036(must)X +4223(be)X +555 1662(enforced.)N +898(It)X +968(is)X +1042(designed)X +1348(to)X +1431(be)X +1528(run)X +1656(on)X +1757(a)X +1814(database)X +2112(with)X +2275(20,000)X +2516(parts,)X +2713(and)X +2850(on)X +2951(one)X +3087(with)X +3249(200,000)X +3529(parts.)X +3745(Because)X +4033(we)X +4147(have)X +555 1752(insuf\256cient)N +935(disk)X +1088(space)X +1287(for)X +1401(the)X +1519(larger)X +1727(database,)X +2044(we)X +2158(report)X +2370(results)X +2599(only)X +2761(for)X +2875(the)X +2993(20,000)X +3233(part)X +3378(database.)X +3 f +555 1938(5.2.1.)N +775(Implementation)X +1 f +755 2061(The)N +920(LIBTP)X +1182(implementation)X +1724(of)X +1831(OO1)X +2027(uses)X +2205(the)X +2342(TCL)X +2532([OUST90])X +2914(interface)X +3235(described)X +3582(earlier.)X +3867(The)X +4031(backend)X +555 2151(accepts)N +813(commands)X +1181(over)X +1345(an)X +1442(IP)X +1534(socket)X +1760(and)X +1897(performs)X +2208(the)X +2327(requested)X +2656(database)X +2954(actions.)X +3242(The)X +3387(frontend)X +3679(opens)X +3886(and)X +4022(executes)X +555 2241(a)N +618(TCL)X +796(script.)X +1041(This)X +1210(script)X +1415(contains)X +1709(database)X +2013(accesses)X +2313(interleaved)X +2697(with)X +2866(ordinary)X +3165(program)X +3463(control)X +3716(statements.)X +4120(Data-)X +555 2331(base)N +718(commands)X +1085(are)X +1204(submitted)X +1539(to)X +1621(the)X +1739(backend)X +2027(and)X +2163(results)X +2392(are)X +2511(bound)X +2731(to)X +2813(program)X +3105(variables.)X +755 2454(The)N +903(parts)X +1082(table)X +1261(was)X +1409(stored)X +1628(as)X +1718(a)X +1776(B-tree)X +1999(indexed)X +2275(by)X +2 f +2377(id)X +1 f +2439(.)X +2501(The)X +2648(connection)X +3022(table)X +3200(was)X +3347(stored)X +3565(as)X +3654(a)X +3712(set)X +3823(of)X +3912(\256xed-length)X +555 2544(records)N +824(using)X +1029(the)X +1159(4.4BSD)X +1446(recno)X +1657(access)X +1895(method.)X +2207(In)X +2306(addition,)X +2620(two)X +2771(B-tree)X +3003(indices)X +3261(were)X +3449(maintained)X +3836(on)X +3947(connection)X +555 2634(table)N +732(entries.)X +1007(One)X +1162(index)X +1360(mapped)X +1634(the)X +2 f +1752(from)X +1 f +1923(\256eld)X +2085(to)X +2167(a)X +2223(connection)X +2595(record)X +2821(number,)X +3106(and)X +3242(the)X +3360(other)X +3545(mapped)X +3819(the)X +2 f +3937(to)X +1 f +4019(\256eld)X +4181(to)X +4263(a)X +555 2724(connection)N +932(record)X +1163(number.)X +1473(These)X +1690(indices)X +1941(support)X +2205(fast)X +2345(lookups)X +2622(on)X +2726(connections)X +3133(in)X +3219(both)X +3385(directions.)X +3765(For)X +3900(the)X +4022(traversal)X +555 2814(tests,)N +743(the)X +867(frontend)X +1165(does)X +1338(an)X +1439(index)X +1642(lookup)X +1889(to)X +1976(discover)X +2273(the)X +2396(connected)X +2747(part's)X +2 f +2955(id)X +1 f +3017(,)X +3062(and)X +3203(then)X +3366(does)X +3538(another)X +3804(lookup)X +4051(to)X +4138(fetch)X +555 2904(the)N +673(part)X +818(itself.)X +3 f +555 3090(5.2.2.)N +775(Performance)X +1242(Measurements)X +1766(for)X +1889(OO1)X +1 f +755 3213(We)N +888(compare)X +1186(LIBTP's)X +1487(OO1)X +1664(performance)X +2092(to)X +2174(that)X +2314(reported)X +2602(in)X +2684([CATT91].)X +3087(Those)X +3303(results)X +3532(were)X +3709(collected)X +4019(on)X +4119(a)X +4175(Sun)X +555 3303(3/280)N +759(\(25)X +888(MHz)X +1075(MC68020\))X +1448(with)X +1612(16)X +1714(MBytes)X +1989(of)X +2078(memory)X +2367(and)X +2505(two)X +2647(Hitachi)X +2904(892MByte)X +3267(disks)X +3452(\(15)X +3580(ms)X +3694(average)X +3966(seek)X +4130(time\))X +555 3393(behind)N +793(an)X +889(SMD-4)X +1149(controller.)X +1521(Frontends)X +1861(ran)X +1984(on)X +2084(an)X +2180(8MByte)X +2462(Sun)X +2606(3/260.)X +755 3516(In)N +844(order)X +1036(to)X +1120(measure)X +1410(performance)X +1839(on)X +1941(a)X +1999(machine)X +2293(of)X +2382(roughly)X +2653(equivalent)X +3009(processor)X +3339(power,)X +3582(we)X +3698(ran)X +3822(one)X +3959(set)X +4069(of)X +4157(tests)X +555 3606(on)N +666(a)X +733(standalone)X +1107(MC68030-based)X +1671(HP300)X +1923(\(33MHz)X +2225(MC68030\).)X +2646(The)X +2801(database)X +3108(was)X +3263(stored)X +3489(on)X +3599(a)X +3665(300MByte)X +4037(HP7959)X +555 3696(SCSI)N +744(disk)X +898(\(17)X +1026(ms)X +1139(average)X +1410(seek)X +1573(time\).)X +1802(Since)X +2000(this)X +2135(machine)X +2427(is)X +2500(not)X +2622(connected)X +2968(to)X +3050(a)X +3106(network,)X +3409(we)X +3523(ran)X +3646(local)X +3822(tests)X +3984(where)X +4201(the)X +555 3786(frontend)N +855(and)X +999(backend)X +1295(run)X +1430(on)X +1538(the)X +1664(same)X +1856(machine.)X +2195(We)X +2334(compare)X +2638(these)X +2830(measurements)X +3316(with)X +3485(Cattell's)X +3783(local)X +3966(Sun)X +4117(3/280)X +555 3876(numbers.)N +755 3999(Because)N +1051(the)X +1177(benchmark)X +1562(requires)X +1849(remote)X +2100(access,)X +2354(we)X +2476(ran)X +2607(another)X +2876(set)X +2993(of)X +3088(tests)X +3258(on)X +3365(a)X +3428(DECstation)X +3828(5000/200)X +4157(with)X +555 4089(32M)N +732(of)X +825(memory)X +1118(running)X +1393(Ultrix)X +1610(V4.0)X +1794(and)X +1936(a)X +1998(DEC)X +2184(1GByte)X +2459(RZ57)X +2666(SCSI)X +2859(disk.)X +3057(We)X +3194(compare)X +3496(the)X +3619(local)X +3800(performance)X +4232(of)X +555 4179(OO1)N +734(on)X +837(the)X +958(DECstation)X +1354(to)X +1439(its)X +1536(remote)X +1781(performance.)X +2250(For)X +2383(the)X +2503(remote)X +2748(case,)X +2929(we)X +3045(ran)X +3170(the)X +3290(frontend)X +3584(on)X +3686(a)X +3744(DECstation)X +4139(3100)X +555 4269(with)N +717(16)X +817(MBytes)X +1090(of)X +1177(main)X +1357(memory.)X +755 4392(The)N +900(databases)X +1228(tested)X +1435(in)X +1517([CATT91])X +1880(are)X +10 f +635 4515(g)N +1 f +755(INDEX,)X +1045(a)X +1101(highly-optimized)X +1672(access)X +1898(method)X +2158(package)X +2442(developed)X +2792(at)X +2870(Sun)X +3014(Microsystems.)X +10 f +635 4638(g)N +1 f +755(OODBMS,)X +1137(a)X +1193(beta)X +1347(release)X +1591(of)X +1678(a)X +1734(commercial)X +2133(object-oriented)X +2639(database)X +2936(management)X +3366(system.)X +10 f +635 4761(g)N +1 f +755(RDBMS,)X +1076(a)X +1133(UNIX-based)X +1565(commercial)X +1965(relational)X +2289(data)X +2444(manager)X +2742(at)X +2821(production)X +3189(release.)X +3474(The)X +3620(OO1)X +3797(implementation)X +755 4851(used)N +922(embedded)X +1272(SQL)X +1443(in)X +1525(C.)X +1638(Stored)X +1867(procedures)X +2240(were)X +2417(de\256ned)X +2673(to)X +2755(reduce)X +2990(client-server)X +3412(traf\256c.)X +755 4974(Table)N +974(two)X +1130(shows)X +1366(the)X +1500(measurements)X +1995(from)X +2187([CATT91])X +2566(and)X +2718(LIBTP)X +2976(for)X +3106(a)X +3178(local)X +3370(test)X +3517(on)X +3632(the)X +3765(MC680x0-based)X +555 5064(hardware.)N +915(All)X +1037(caches)X +1272(are)X +1391(cleared)X +1644(before)X +1870(each)X +2038(test.)X +2209(All)X +2331(times)X +2524(are)X +2643(in)X +2725(seconds.)X +755 5187(Table)N +960(two)X +1102(shows)X +1324(that)X +1466(LIBTP)X +1710(outperforms)X +2123(the)X +2242(commercial)X +2642(relational)X +2966(system,)X +3229(but)X +3352(is)X +3426(slower)X +3661(than)X +3820(OODBMS)X +4183(and)X +555 5277(INDEX.)N +872(Since)X +1077(the)X +1202(caches)X +1444(were)X +1628(cleared)X +1888(at)X +1973(the)X +2098(start)X +2263(of)X +2356(each)X +2530(test,)X +2687(disk)X +2846(throughput)X +3223(is)X +3302(critical)X +3551(in)X +3639(this)X +3780(test.)X +3957(The)X +4108(single)X +555 5367(SCSI)N +749(HP)X +877(drive)X +1068(used)X +1241(by)X +1347(LIBTP)X +1595(is)X +1674(approximately)X +2163(13%)X +2336(slower)X +2576(than)X +2739(the)X +2862(disks)X +3051(used)X +3223(in)X +3310([CATT91])X +3678(which)X +3899(accounts)X +4205(for)X +555 5457(part)N +700(of)X +787(the)X +905(difference.)X +755 5580(OODBMS)N +1118(and)X +1255(INDEX)X +1525(outperform)X +1906(LIBTP)X +2148(most)X +2323(dramatically)X +2744(on)X +2844(traversal.)X +3181(This)X +3343(is)X +3416(because)X +3691(we)X +3805(use)X +3932(index)X +4130(look-)X +555 5670(ups)N +689(to)X +774(\256nd)X +921(connections,)X +1347(whereas)X +1634(the)X +1755(other)X +1942(two)X +2084(systems)X +2359(use)X +2488(a)X +2546(link)X +2692(access)X +2920(method.)X +3222(The)X +3369(index)X +3569(requires)X +3850(us)X +3943(to)X +4027(examine)X + +15 p +%%Page: 15 15 +10 s 10 xH 0 xS 1 f +3 f +1 f +10 f +555 679(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N +2 f +606 769(Measure)N +1 f +1019(INDEX)X +1389(OODBMS)X +1851(RDBMS)X +2250(LIBTP)X +10 f +555 771(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N +555 787(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N +1 f +595 869(Lookup)N +1114(5.4)X +1490(12.9)X +1950(27)X +2291(27.2)X +595 959(Traversal)N +1074(13)X +1530(9.8)X +1950(90)X +2291(47.3)X +595 1049(Insert)N +1114(7.4)X +1530(1.5)X +1950(22)X +2331(9.7)X +10 f +555 1059(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N +555(c)X +999(c)Y +919(c)Y +839(c)Y +759(c)Y +959 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +1329 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +1791 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +2190 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +2512 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +2618 679(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +2829 769(Measure)N +3401(Cache)X +3726(Local)X +4028(Remote)X +1 f +10 f +2618 771(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2618 787(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2658 869(Lookup)N +3401(cold)X +3747(15.7)X +4078(20.6)X +3401 959(warm)N +3787(7.8)X +4078(12.4)X +10 f +2618 969(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2658 1059(Forward)N +2950(traversal)X +3401(cold)X +3747(28.4)X +4078(52.6)X +3401 1149(warm)N +3747(23.5)X +4078(47.4)X +10 f +2618 1159(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2658 1249(Backward)N +3004(traversal)X +3401(cold)X +3747(24.2)X +4078(47.4)X +3401 1339(warm)N +3747(24.3)X +4078(47.6)X +10 f +2618 1349(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2658 1439(Insert)N +3401(cold)X +3787(7.5)X +4078(10.3)X +3401 1529(warm)N +3787(6.7)X +4078(10.9)X +10 f +2618 1539(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2618(c)X +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +3341 1539(c)N +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +3666 1539(c)N +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +3968 1539(c)N +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +4309 1539(c)N +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +3 f +587 1785(Table)N +823(2:)X +931(Local)X +1163(MC680x0)X +1538(Performance)X +2026(of)X +2133(Several)X +587 1875(Systems)N +883(on)X +987(OO1.)X +2667 1785(Table)N +2909(3:)X +3023(Local)X +3260(vs.)X +3397(Remote)X +3707(Performance)X +4200(of)X +2667 1875(LIBTP)N +2926(on)X +3030(OO1.)X +1 f +10 f +555 1998(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +1 f +555 2274(two)N +696(disk)X +850(pages,)X +1074(but)X +1197(the)X +1316(links)X +1492(require)X +1741(only)X +1904(one,)X +2061(regardless)X +2408(of)X +2496(database)X +2794(size.)X +2980(Cattell)X +3214(reports)X +3458(that)X +3599(lookups)X +3873(using)X +4067(B-trees)X +555 2364(instead)N +808(of)X +901(links)X +1082(makes)X +1313(traversal)X +1616(take)X +1776(twice)X +1976(as)X +2069(long)X +2237(in)X +2325(INDEX.)X +2641(Adding)X +2907(a)X +2969(link)X +3119(access)X +3351(method)X +3617(to)X +3 f +3704(db)X +1 f +3792(\(3\))X +3911(or)X +4003(using)X +4201(the)X +555 2454(existing)N +828(hash)X +995(method)X +1255(would)X +1475(apparently)X +1834(be)X +1930(a)X +1986(good)X +2166(idea.)X +755 2577(Both)N +936(OODBMS)X +1304(and)X +1446(INDEX)X +1722(issue)X +1908 0.1944(coarser-granularity)AX +2545(locks)X +2739(than)X +2902(LIBTP.)X +3189(This)X +3356(limits)X +3562(concurrency)X +3985(for)X +4104(multi-)X +555 2667(user)N +711(applications,)X +1140(but)X +1264(helps)X +1455(single-user)X +1829(applications.)X +2278(In)X +2367(addition,)X +2671(the)X +2791(fact)X +2934(that)X +3076(LIBTP)X +3319(releases)X +3595(B-tree)X +3817(locks)X +4007(early)X +4189(is)X +4263(a)X +555 2757(drawback)N +896(in)X +986(OO1.)X +1210(Since)X +1416(there)X +1605(is)X +1686(no)X +1793(concurrency)X +2218(in)X +2307(the)X +2432(benchmark,)X +2836(high-concurrency)X +3430(strategies)X +3760(only)X +3929(show)X +4125(up)X +4232(as)X +555 2847(increased)N +882(locking)X +1145(overhead.)X +1503(Finally,)X +1772(the)X +1892(architecture)X +2294(of)X +2383(the)X +2503(LIBTP)X +2747(implementation)X +3271(was)X +3418(substantially)X +3844(different)X +4143(from)X +555 2937(that)N +702(of)X +796(either)X +1006(OODBMS)X +1375(or)X +1469(INDEX.)X +1786(Both)X +1968(of)X +2062(those)X +2258(systems)X +2538(do)X +2645(the)X +2770(searches)X +3070(in)X +3159(the)X +3284(user's)X +3503(address)X +3771(space,)X +3997(and)X +4139(issue)X +555 3027(requests)N +844(for)X +964(pages)X +1173(to)X +1260(the)X +1383(server)X +1605(process.)X +1911(Pages)X +2123(are)X +2247(cached)X +2496(in)X +2583(the)X +2706(client,)X +2929(and)X +3070(many)X +3273(queries)X +3530(can)X +3667(be)X +3768(satis\256ed)X +4055(without)X +555 3117(contacting)N +910(the)X +1029(server)X +1247(at)X +1326(all.)X +1467(LIBTP)X +1710(submits)X +1979(all)X +2080(the)X +2199(queries)X +2452(to)X +2535(the)X +2653(server)X +2870(process,)X +3151(and)X +3287(receives)X +3571(database)X +3868(records)X +4125(back;)X +555 3207(it)N +619(does)X +786(no)X +886(client)X +1084(caching.)X +755 3330(The)N +911(RDBMS)X +1221(architecture)X +1632(is)X +1716(much)X +1925(closer)X +2148(to)X +2241(that)X +2392(of)X +2490(LIBTP.)X +2783(A)X +2872(server)X +3100(process)X +3372(receives)X +3667(queries)X +3930(and)X +4076(returns)X +555 3420(results)N +786(to)X +870(a)X +928(client.)X +1168(The)X +1315(timing)X +1545(results)X +1776(in)X +1860(table)X +2038(two)X +2180(clearly)X +2421(show)X +2612(that)X +2754(the)X +2874(conventional)X +3309(database)X +3607(client/server)X +4025(model)X +4246(is)X +555 3510(expensive.)N +941(LIBTP)X +1188(outperforms)X +1605(the)X +1728(RDBMS)X +2032(on)X +2136(traversal)X +2437(and)X +2577(insertion.)X +2921(We)X +3057(speculate)X +3380(that)X +3524(this)X +3663(is)X +3740(due)X +3880(in)X +3966(part)X +4115(to)X +4201(the)X +555 3600(overhead)N +870(of)X +957(query)X +1160(parsing,)X +1436(optimization,)X +1880(and)X +2016(repeated)X +2309(interpretation)X +2761(of)X +2848(the)X +2966(plan)X +3124(tree)X +3265(in)X +3347(the)X +3465(RDBMS')X +3791(query)X +3994(executor.)X +755 3723(Table)N +962(three)X +1147(shows)X +1371(the)X +1492(differences)X +1873(between)X +2164(local)X +2343(and)X +2482(remote)X +2728(execution)X +3063(of)X +3153(LIBTP's)X +3456(OO1)X +3635(implementation)X +4160(on)X +4263(a)X +555 3813(DECstation.)N +989(We)X +1122(measured)X +1451(performance)X +1879(with)X +2042(a)X +2099(populated)X +2436(\(warm\))X +2694(cache)X +2899(and)X +3036(an)X +3133(empty)X +3354(\(cold\))X +3567(cache.)X +3812(Reported)X +4126(times)X +555 3903(are)N +681(the)X +806(means)X +1037(of)X +1130(twenty)X +1374(tests,)X +1562(and)X +1704(are)X +1829(in)X +1917(seconds.)X +2237(Standard)X +2548(deviations)X +2903(were)X +3086(within)X +3316(seven)X +3525(percent)X +3788(of)X +3881(the)X +4005(mean)X +4205(for)X +555 3993(remote,)N +818(and)X +954(two)X +1094(percent)X +1351(of)X +1438(the)X +1556(mean)X +1750(for)X +1864(local.)X +755 4116(The)N +914(20ms)X +1121(overhead)X +1450(of)X +1551(TCP/IP)X +1824(on)X +1938(an)X +2048(Ethernet)X +2354(entirely)X +2633(accounts)X +2948(for)X +3076(the)X +3207(difference)X +3567(in)X +3662(speed.)X +3918(The)X +4076(remote)X +555 4206(traversal)N +857(times)X +1055(are)X +1179(nearly)X +1405(double)X +1648(the)X +1771(local)X +1952(times)X +2150(because)X +2430(we)X +2549(do)X +2653(index)X +2855(lookups)X +3132(and)X +3272(part)X +3421(fetches)X +3673(in)X +3759(separate)X +4047(queries.)X +555 4296(It)N +629(would)X +854(make)X +1053(sense)X +1252(to)X +1339(do)X +1444(indexed)X +1723(searches)X +2021(on)X +2126(the)X +2248(server,)X +2489(but)X +2615(we)X +2733(were)X +2914(unwilling)X +3244(to)X +3330(hard-code)X +3676(knowledge)X +4052(of)X +4143(OO1)X +555 4386(indices)N +803(into)X +948(our)X +1075(LIBTP)X +1317(TCL)X +1488(server.)X +1745(Cold)X +1920(and)X +2056(warm)X +2259(insertion)X +2559(times)X +2752(are)X +2871(identical)X +3167(since)X +3352(insertions)X +3683(do)X +3783(not)X +3905(bene\256t)X +4143(from)X +555 4476(caching.)N +755 4599(One)N +915(interesting)X +1279(difference)X +1632(shown)X +1867(by)X +1973(table)X +2155(three)X +2342(is)X +2421(the)X +2545(cost)X +2700(of)X +2793(forward)X +3074(versus)X +3305(backward)X +3644(traversal.)X +3987(When)X +4205(we)X +555 4689(built)N +725(the)X +847(database,)X +1168(we)X +1285(inserted)X +1562(parts)X +1741(in)X +1826(part)X +2 f +1974(id)X +1 f +2059(order.)X +2292(We)X +2427(built)X +2596(the)X +2717(indices)X +2967(at)X +3048(the)X +3169(same)X +3357(time.)X +3562(Therefore,)X +3923(the)X +4044(forward)X +555 4779(index)N +757(had)X +897(keys)X +1068(inserted)X +1346(in)X +1432(order,)X +1646(while)X +1848(the)X +1970(backward)X +2307(index)X +2509(had)X +2649(keys)X +2820(inserted)X +3098(more)X +3286(randomly.)X +3656(In-order)X +3943(insertion)X +4246(is)X +555 4885(pessimal)N +858(for)X +975(B-tree)X +1199(indices,)X +1469(so)X +1563(the)X +1684(forward)X +1962(index)X +2163(is)X +2239(much)X +2440(larger)X +2651(than)X +2812(the)X +2933(backward)X +3269(one)X +7 s +3385 4853(5)N +10 s +4885(.)Y +3476(This)X +3640(larger)X +3850(size)X +3997(shows)X +4219(up)X +555 4975(as)N +642(extra)X +823(disk)X +976(reads)X +1166(in)X +1248(the)X +1366(cold)X +1524(benchmark.)X +3 f +555 5161(6.)N +655(Conclusions)X +1 f +755 5284(LIBTP)N +1006(provides)X +1311(the)X +1438(basic)X +1632(building)X +1927(blocks)X +2165(to)X +2256(support)X +2525(transaction)X +2906(protection.)X +3300(In)X +3396(comparison)X +3799(with)X +3970(traditional)X +555 5374(Unix)N +746(libraries)X +1040(and)X +1187(commercial)X +1597(systems,)X +1900(it)X +1974(offers)X +2192(a)X +2258(variety)X +2511(of)X +2608(tradeoffs.)X +2964(Using)X +3185(complete)X +3509(transaction)X +3891(protection)X +4246(is)X +555 5464(more)N +747(complicated)X +1166(than)X +1331(simply)X +1575(adding)X +3 f +1820(fsync)X +1 f +1998(\(2\))X +2119(and)X +3 f +2262(\257ock)X +1 f +2426(\(2\))X +2547(calls)X +2721(to)X +2810(code,)X +3008(but)X +3136(it)X +3206(is)X +3285(faster)X +3490(in)X +3578(some)X +3773(cases)X +3969(and)X +4111(offers)X +8 s +10 f +555 5536(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5614(5)N +8 s +763 5639(The)N +878(next)X +1004(release)X +1196(of)X +1265(the)X +1359(4.4BSD)X +1580(access)X +1758(method)X +1966(will)X +2082(automatically)X +2446(detect)X +2614(and)X +2722(compensate)X +3039(for)X +3129(in-order)X +3350(insertion,)X +3606(eliminating)X +3914(this)X +4023(problem.)X + +16 p +%%Page: 16 16 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +555 630(stricter)N +801(guarantees)X +1168(\(atomicity,)X +1540(consistency,)X +1957(isolation,)X +2275(and)X +2414(durability\).)X +2815(If)X +2892(the)X +3013(data)X +3170(to)X +3255(be)X +3354(protected)X +3676(are)X +3798(already)X +4058(format-)X +555 720(ted)N +675(\()X +2 f +702(i.e.)X +1 f +821(use)X +949(one)X +1086(of)X +1174(the)X +1293(database)X +1591(access)X +1818(methods\),)X +2157(then)X +2316(adding)X +2555(transaction)X +2928(protection)X +3274(requires)X +3554(no)X +3655(additional)X +3996(complex-)X +555 810(ity,)N +679(but)X +801(incurs)X +1017(a)X +1073(performance)X +1500(penalty)X +1756(of)X +1843(approximately)X +2326(15%.)X +755 933(In)N +844(comparison)X +1240(with)X +1404(commercial)X +1805(database)X +2104(systems,)X +2399(the)X +2519(tradeoffs)X +2827(are)X +2948(more)X +3135(complex.)X +3473(LIBTP)X +3717(does)X +3886(not)X +4009(currently)X +555 1023(support)N +825(a)X +891(standard)X +1193(query)X +1406(language.)X +1766(The)X +1921(TCL-based)X +2312(server)X +2539(process)X +2810(allows)X +3049(a)X +3115(certain)X +3364(ease)X +3533(of)X +3630(use)X +3767(which)X +3993(would)X +4223(be)X +555 1113(enhanced)N +882(with)X +1047(a)X +1106(more)X +1294(user-friendly)X +1732(interface)X +2037(\()X +2 f +2064(e.g.)X +1 f +2203(a)X +2261(windows)X +2572(based)X +2777(query-by-form)X +3272(application\),)X +3697(for)X +3813(which)X +4031(we)X +4147(have)X +555 1203(a)N +620(working)X +916(prototype.)X +1292(When)X +1513(accesses)X +1815(do)X +1924(not)X +2055(require)X +2312(sophisticated)X +2758(query)X +2969(processing,)X +3360(the)X +3486(TCL)X +3665(interface)X +3975(is)X +4056(an)X +4160(ade-)X +555 1293(quate)N +756(solution.)X +1080(What)X +1281(LIBTP)X +1529(fails)X +1693(to)X +1781(provide)X +2052(in)X +2140(functionality,)X +2595(it)X +2665(makes)X +2896(up)X +3002(for)X +3122(in)X +3210(performance)X +3643(and)X +3785(\257exibility.)X +4161(Any)X +555 1383(application)N +931(may)X +1089(make)X +1283(use)X +1410(of)X +1497(its)X +1592(record)X +1818(interface)X +2120(or)X +2207(the)X +2325(more)X +2510(primitive)X +2823(log,)X +2965(lock,)X +3143(and)X +3279(buffer)X +3496(calls.)X +755 1506(Future)N +987(work)X +1175(will)X +1322(focus)X +1519(on)X +1621(overcoming)X +2026(some)X +2217(of)X +2306(the)X +2426(areas)X +2614(in)X +2698(which)X +2916(LIBTP)X +3160(is)X +3235(currently)X +3547(de\256cient)X +3845(and)X +3983(extending)X +555 1596(its)N +652(transaction)X +1026(model.)X +1288(The)X +1435(addition)X +1719(of)X +1808(an)X +1905(SQL)X +2077(parser)X +2295(and)X +2432(forms)X +2640(front)X +2817(end)X +2954(will)X +3099(improve)X +3387(the)X +3506(system's)X +3807(ease)X +3967(of)X +4055(use)X +4183(and)X +555 1686(make)N +750(it)X +815(more)X +1001(competitive)X +1400(with)X +1563(commercial)X +1963(systems.)X +2277(In)X +2365(the)X +2484(long)X +2647(term,)X +2835(we)X +2950(would)X +3170(like)X +3310(to)X +3392(add)X +3528(generalized)X +3919(hierarchical)X +555 1776(locking,)N +836(nested)X +1062(transactions,)X +1486(parallel)X +1748(transactions,)X +2171(passing)X +2431(of)X +2518(transactions)X +2921(between)X +3209(processes,)X +3557(and)X +3693(distributed)X +4055(commit)X +555 1866(handling.)N +900(In)X +992(the)X +1115(short)X +1300(term,)X +1492(the)X +1614(next)X +1776(step)X +1929(is)X +2006(to)X +2092(integrate)X +2397(LIBTP)X +2643(with)X +2809(the)X +2931(most)X +3110(recent)X +3331(release)X +3579(of)X +3670(the)X +3792(database)X +4093(access)X +555 1956(routines)N +833(and)X +969(make)X +1163(it)X +1227(freely)X +1435(available)X +1745(via)X +1863(anonymous)X +2252(ftp.)X +3 f +555 2142(7.)N +655(Acknowledgements)X +1 f +755 2265(We)N +888(would)X +1109(like)X +1250(to)X +1332(thank)X +1530(John)X +1701(Wilkes)X +1948(and)X +2084(Carl)X +2242(Staelin)X +2484(of)X +2571(Hewlett-Packard)X +3131(Laboratories)X +3557(and)X +3693(Jon)X +3824(Krueger.)X +4148(John)X +555 2355(and)N +694(Carl)X +855(provided)X +1162(us)X +1255(with)X +1419(an)X +1517(extra)X +1700(disk)X +1855(for)X +1971(the)X +2091(HP)X +2215(testbed)X +2464(less)X +2606(than)X +2766(24)X +2868(hours)X +3068(after)X +3238(we)X +3354(requested)X +3684(it.)X +3770(Jon)X +3903(spent)X +4094(count-)X +555 2445(less)N +699(hours)X +901(helping)X +1164(us)X +1258(understand)X +1633(the)X +1754(intricacies)X +2107(of)X +2197(commercial)X +2599(database)X +2899(products)X +3198(and)X +3337(their)X +3507(behavior)X +3811(under)X +4017(a)X +4076(variety)X +555 2535(of)N +642(system)X +884(con\256gurations.)X +3 f +555 2721(8.)N +655(References)X +1 f +555 2901([ANDR89])N +942(Andrade,)X +1265(J.,)X +1361(Carges,)X +1629(M.,)X +1765(Kovach,)X +2060(K.,)X +2183(``Building)X +2541(an)X +2642(On-Line)X +2939(Transaction)X +3343(Processing)X +3715(System)X +3975(On)X +4098(UNIX)X +727 2991(System)N +982(V'',)X +2 f +1134(CommUNIXations)X +1 f +1725(,)X +1765 0.2188(November/December)AX +2477(1989.)X +555 3171([BAY77])N +878(Bayer,)X +1110(R.,)X +1223(Schkolnick,)X +1623(M.,)X +1754(``Concurrency)X +2243(of)X +2330(Operations)X +2702(on)X +2802(B-Trees'',)X +2 f +3155(Acta)X +3322(Informatica)X +1 f +3700(,)X +3740(1977.)X +555 3351([BERN80])N +936(Bernstein,)X +1297(P.,)X +1415(Goodman,)X +1785(N.,)X +1917(``Timestamp)X +2365(Based)X +2595(Algorithms)X +2992(for)X +3119(Concurrency)X +3567(Control)X +3844(in)X +3939(Distributed)X +727 3441(Database)N +1042(Systems'',)X +2 f +1402(Proceedings)X +1823(6th)X +1945(International)X +2387(Conference)X +2777(on)X +2877(Very)X +3049(Large)X +3260(Data)X +3440(Bases)X +1 f +3627(,)X +3667(October)X +3946(1980.)X +555 3621([BSD91])N +864(DB\(3\),)X +2 f +1109(4.4BSD)X +1376(Unix)X +1552(Programmer's)X +2044(Manual)X +2313(Reference)X +2655(Guide)X +1 f +2851(,)X +2891(University)X +3249(of)X +3336(California,)X +3701(Berkeley,)X +4031(1991.)X +555 3801([CATT91])N +923(Cattell,)X +1181(R.G.G.,)X +1455(``An)X +1632(Engineering)X +2049(Database)X +2369(Benchmark'',)X +2 f +2838(The)X +2983(Benchmark)X +3373(Handbook)X +3731(for)X +3848(Database)X +4179(and)X +727 3891(Transaction)N +1133(Processing)X +1509(Systems)X +1 f +1763(,)X +1803(J.)X +1874(Gray,)X +2075(editor,)X +2302(Morgan)X +2576(Kaufman)X +2895(1991.)X +555 4071([CHEN91])N +929(Cheng,)X +1180(E.,)X +1291(Chang,)X +1542(E.,)X +1653(Klein,)X +1872(J.,)X +1964(Lee,)X +2126(D.,)X +2245(Lu,)X +2375(E.,)X +2485(Lutgardo,)X +2820(A.,)X +2939(Obermarck,)X +3342(R.,)X +3456(``An)X +3629(Open)X +3824(and)X +3961(Extensible)X +727 4161(Event-Based)N +1157(Transaction)X +1556(Manager'',)X +2 f +1936(Proceedings)X +2357(1991)X +2537(Summer)X +2820(Usenix)X +1 f +3043(,)X +3083(Nashville,)X +3430(TN,)X +3577(June)X +3744(1991.)X +555 4341([CHOU85])N +943(Chou,)X +1163(H.,)X +1288(DeWitt,)X +1570(D.,)X +1694(``An)X +1872(Evaluation)X +2245(of)X +2338(Buffer)X +2574(Management)X +3019(Strategies)X +3361(for)X +3481(Relational)X +3836(Database)X +4157(Sys-)X +727 4431(tems'',)N +2 f +972(Proceedings)X +1393(of)X +1475(the)X +1593(11th)X +1755(International)X +2197(Conference)X +2587(on)X +2687(Very)X +2859(Large)X +3070(Databases)X +1 f +3408(,)X +3448(1985.)X +555 4611([DEWI84])N +925(DeWitt,)X +1207(D.,)X +1331(Katz,)X +1529(R.,)X +1648(Olken,)X +1890(F.,)X +2000(Shapiro,)X +2295(L.,)X +2410(Stonebraker,)X +2843(M.,)X +2979(Wood,)X +3220(D.,)X +3343(``Implementation)X +3929(Techniques)X +727 4701(for)N +841(Main)X +1030(Memory)X +1326(Database)X +1641(Systems'',)X +2 f +2001(Proceedings)X +2422(of)X +2504(SIGMOD)X +1 f +2812(,)X +2852(pp.)X +2972(1-8,)X +3119(June)X +3286(1984.)X +555 4881([GRAY76])N +944(Gray,)X +1153(J.,)X +1252(Lorie,)X +1474(R.,)X +1595(Putzolu,)X +1887(F.,)X +1999(and)X +2143(Traiger,)X +2428(I.,)X +2522(``Granularity)X +2973(of)X +3067(locks)X +3263(and)X +3406(degrees)X +3679(of)X +3773(consistency)X +4174(in)X +4263(a)X +727 4971(large)N +909(shared)X +1140(data)X +1295(base'',)X +2 f +1533(Modeling)X +1861(in)X +1944(Data)X +2125(Base)X +2301(Management)X +2740(Systems)X +1 f +2994(,)X +3034(Elsevier)X +3317(North)X +3524(Holland,)X +3822(New)X +3994(York,)X +4199(pp.)X +727 5061(365-394.)N +555 5241([HAER83])N +931(Haerder,)X +1235(T.)X +1348(Reuter,)X +1606(A.)X +1728(``Principles)X +2126(of)X +2217(Transaction-Oriented)X +2928(Database)X +3246(Recovery'',)X +2 f +3651(Computing)X +4029(Surveys)X +1 f +4279(,)X +727 5331(15\(4\);)N +943(237-318,)X +1250(1983.)X +555 5511([KUNG81])N +943(Kung,)X +1162(H.)X +1261(T.,)X +1371(Richardson,)X +1777(J.,)X +1869(``On)X +2042(Optimistic)X +2400(Methods)X +2701(for)X +2816(Concurrency)X +3252(Control'',)X +2 f +3591(ACM)X +3781(Transactions)X +4219(on)X +727 5601(Database)N +1054(Systems)X +1 f +1328(6\(2\);)X +1504(213-226,)X +1811(1981.)X + +17 p +%%Page: 17 17 +10 s 10 xH 0 xS 1 f +3 f +1 f +555 630([LEHM81])N +939(Lehman,)X +1245(P.,)X +1352(Yao,)X +1529(S.,)X +1636(``Ef\256cient)X +1989(Locking)X +2279(for)X +2396(Concurrent)X +2780(Operations)X +3155(on)X +3258(B-trees'',)X +2 f +3587(ACM)X +3779(Transactions)X +4219(on)X +727 720(Database)N +1054(Systems)X +1 f +1308(,)X +1348(6\(4\),)X +1522(December)X +1873(1981.)X +555 900([MOHA91])N +964(Mohan,)X +1241(C.,)X +1364(Pirahesh,)X +1690(H.,)X +1818(``ARIES-RRH:)X +2366(Restricted)X +2721(Repeating)X +3076(of)X +3173(History)X +3442(in)X +3533(the)X +3660(ARIES)X +3920(Transaction)X +727 990(Recovery)N +1055(Method'',)X +2 f +1398(Proceedings)X +1819(7th)X +1941(International)X +2383(Conference)X +2773(on)X +2873(Data)X +3053(Engineering)X +1 f +3449(,)X +3489(Kobe,)X +3703(Japan,)X +3926(April)X +4115(1991.)X +555 1170([NODI90])N +914(Nodine,)X +1194(M.,)X +1328(Zdonik,)X +1602(S.,)X +1709(``Cooperative)X +2178(Transaction)X +2580(Hierarchies:)X +2996(A)X +3077(Transaction)X +3479(Model)X +3711(to)X +3796(Support)X +4072(Design)X +727 1260(Applications'',)N +2 f +1242(Proceedings)X +1675(16th)X +1849(International)X +2303(Conference)X +2704(on)X +2815(Very)X +2998(Large)X +3220(Data)X +3411(Bases)X +1 f +3598(,)X +3649(Brisbane,)X +3985(Australia,)X +727 1350(August)N +978(1990.)X +555 1530([OUST90])N +923(Ousterhout,)X +1324(J.,)X +1420(``Tcl:)X +1648(An)X +1771(Embeddable)X +2197(Command)X +2555(Language'',)X +2 f +2971(Proceedings)X +3396(1990)X +3580(Winter)X +3822(Usenix)X +1 f +4045(,)X +4089(Wash-)X +727 1620(ington,)N +971(D.C.,)X +1162(January)X +1432(1990.)X +555 1800([POSIX91])N +955(``Unapproved)X +1441(Draft)X +1645(for)X +1773(Realtime)X +2096(Extension)X +2450(for)X +2578(Portable)X +2879(Operating)X +3234(Systems'',)X +3608(Draft)X +3812(11,)X +3946(October)X +4239(7,)X +727 1890(1991,)N +927(IEEE)X +1121(Computer)X +1461(Society.)X +555 2070([ROSE91])N +925(Rosenblum,)X +1341(M.,)X +1484(Ousterhout,)X +1892(J.,)X +1995(``The)X +2206(Design)X +2464(and)X +2611(Implementation)X +3149(of)X +3247(a)X +3314(Log-Structured)X +3835(File)X +3990(System'',)X +2 f +727 2160(Proceedings)N +1148(of)X +1230(the)X +1348(13th)X +1510(Symposium)X +1895(on)X +1995(Operating)X +2344(Systems)X +2618(Principles)X +1 f +2947(,)X +2987(1991.)X +555 2340([SELT91])N +904(Seltzer,)X +1171(M.,)X +1306(Stonebraker,)X +1738(M.,)X +1873(``Read)X +2116(Optimized)X +2478(File)X +2626(Systems:)X +2938(A)X +3020(Performance)X +3454(Evaluation'',)X +2 f +3898(Proceedings)X +727 2430(7th)N +849(Annual)X +1100(International)X +1542(Conference)X +1932(on)X +2032(Data)X +2212(Engineering)X +1 f +2608(,)X +2648(Kobe,)X +2862(Japan,)X +3085(April)X +3274(1991.)X +555 2610([SPEC88])N +907(Spector,)X +1200(Rausch,)X +1484(Bruell,)X +1732(``Camelot:)X +2107(A)X +2192(Flexible,)X +2501(Distributed)X +2888(Transaction)X +3294(Processing)X +3668(System'',)X +2 f +4004(Proceed-)X +727 2700(ings)N +880(of)X +962(Spring)X +1195(COMPCON)X +1606(1988)X +1 f +(,)S +1806(February)X +2116(1988.)X +555 2880([SQL86])N +862(American)X +1201(National)X +1499(Standards)X +1836(Institute,)X +2139(``Database)X +2509(Language)X +2847(SQL'',)X +3093(ANSI)X +3301(X3.135-1986)X +3747(\(ISO)X +3924(9075\),)X +4152(May)X +727 2970(1986.)N +555 3150([STON81])N +919(Stonebraker,)X +1348(M.,)X +1480(``Operating)X +1876(System)X +2132(Support)X +2406(for)X +2520(Database)X +2835(Management'',)X +2 f +3348(Communications)X +3910(of)X +3992(the)X +4110(ACM)X +1 f +4279(,)X +727 3240(1981.)N +555 3420([SULL92])N +925(Sullivan,)X +1247(M.,)X +1394(Olson,)X +1641(M.,)X +1788(``An)X +1976(Index)X +2195(Implementation)X +2737(Supporting)X +3127(Fast)X +3295(Recovery)X +3638(for)X +3767(the)X +3900(POSTGRES)X +727 3510(Storage)N +1014(System'',)X +1365(to)X +1469(appear)X +1726(in)X +2 f +1830(Proceedings)X +2272(8th)X +2415(Annual)X +2687(International)X +3150(Conference)X +3561(on)X +3682(Data)X +3883(Engineering)X +1 f +4279(,)X +727 3600(Tempe,)N +990(Arizona,)X +1289(February)X +1599(1992.)X +555 3780([TPCB90])N +914(Transaction)X +1319(Processing)X +1692(Performance)X +2129(Council,)X +2428(``TPC)X +2653(Benchmark)X +3048(B'',)X +3200(Standard)X +3510(Speci\256cation,)X +3973(Waterside)X +727 3870(Associates,)N +1110(Fremont,)X +1421(CA.,)X +1592(1990.)X +555 4050([YOUN91])N +947(Young,)X +1211(M.)X +1328(W.,)X +1470(Thompson,)X +1858(D.)X +1962(S.,)X +2072(Jaffe,)X +2274(E.,)X +2388(``A)X +2525(Modular)X +2826(Architecture)X +3253(for)X +3372(Distributed)X +3757(Transaction)X +4161(Pro-)X +727 4140(cessing'',)N +2 f +1057(Proceedings)X +1478(1991)X +1658(Winter)X +1896(Usenix)X +1 f +2119(,)X +2159(Dallas,)X +2404(TX,)X +2551(January)X +2821(1991.)X +3 f +755 4263(Margo)N +1008(I.)X +1080(Seltzer)X +1 f +1338(is)X +1411(a)X +1467(Ph.D.)X +1669(student)X +1920(in)X +2002(the)X +2120(Department)X +2519(of)X +2606(Electrical)X +2934(Engineering)X +3346(and)X +3482(Computer)X +3822(Sciences)X +4123(at)X +4201(the)X +555 4353(University)N +919(of)X +1012(California,)X +1383(Berkeley.)X +1739(Her)X +1886(research)X +2181(interests)X +2474(include)X +2735(\256le)X +2862(systems,)X +3160(databases,)X +3513(and)X +3654(transaction)X +4031(process-)X +555 4443(ing)N +686(systems.)X +1008(She)X +1157(spent)X +1355(several)X +1612(years)X +1811(working)X +2107(at)X +2194(startup)X +2441(companies)X +2813(designing)X +3153(and)X +3298(implementing)X +3771(\256le)X +3902(systems)X +4183(and)X +555 4533(transaction)N +929(processing)X +1294(software)X +1592(and)X +1729(designing)X +2061(microprocessors.)X +2648(Ms.)X +2791(Seltzer)X +3035(received)X +3329(her)X +3453(AB)X +3585(in)X +3668(Applied)X +3947(Mathemat-)X +555 4623(ics)N +664(from)X +840 0.1953(Harvard/Radcliffe)AX +1445(College)X +1714(in)X +1796(1983.)X +755 4746(In)N +845(her)X +971(spare)X +1163(time,)X +1347(Margo)X +1583(can)X +1717(usually)X +1970(be)X +2068(found)X +2277(preparing)X +2607(massive)X +2887(quantities)X +3220(of)X +3309(food)X +3478(for)X +3594(hungry)X +3843(hordes,)X +4099(study-)X +555 4836(ing)N +677(Japanese,)X +1003(or)X +1090(playing)X +1350(soccer)X +1576(with)X +1738(an)X +1834(exciting)X +2112(Bay)X +2261(Area)X +2438(Women's)X +2770(Soccer)X +3009(team,)X +3205(the)X +3323(Berkeley)X +3633(Bruisers.)X +3 f +755 5049(Michael)N +1056(A.)X +1159(Olson)X +1 f +1383(is)X +1461(a)X +1522(Master's)X +1828(student)X +2084(in)X +2170(the)X +2292(Department)X +2695(of)X +2786(Electrical)X +3118(Engineering)X +3534(and)X +3674(Computer)X +4018(Sciences)X +555 5139(at)N +645(the)X +774(University)X +1143(of)X +1241(California,)X +1617(Berkeley.)X +1978(His)X +2120(primary)X +2405(interests)X +2703(are)X +2833(database)X +3141(systems)X +3425(and)X +3572(mass)X +3763(storage)X +4026(systems.)X +555 5229(Mike)N +759(spent)X +963(two)X +1118(years)X +1323(working)X +1625(for)X +1754(a)X +1825(commercial)X +2239(database)X +2551(system)X +2808(vendor)X +3066(before)X +3307(joining)X +3567(the)X +3699(Postgres)X +4004(Research)X +555 5319(Group)N +780(at)X +858(Berkeley)X +1168(in)X +1250(1988.)X +1470(He)X +1584(received)X +1877(his)X +1990(B.A.)X +2161(in)X +2243(Computer)X +2583(Science)X +2853(from)X +3029(Berkeley)X +3339(in)X +3421(May)X +3588(1991.)X +755 5442(Mike)N +945(only)X +1108(recently)X +1388(transferred)X +1758(into)X +1903(Sin)X +2030(City,)X +2208(but)X +2330(is)X +2403(rapidly)X +2650(adopting)X +2950(local)X +3126(customs)X +3408(and)X +3544(coloration.)X +3929(In)X +4016(his)X +4129(spare)X +555 5532(time,)N +742(he)X +843(organizes)X +1176(informal)X +1477(Friday)X +1711(afternoon)X +2043(study)X +2240(groups)X +2482(to)X +2568(discuss)X +2823(recent)X +3044(technical)X +3358(and)X +3498(economic)X +3834(developments.)X +555 5622(Among)N +815(his)X +928(hobbies)X +1197(are)X +1316(Charles)X +1581(Dickens,)X +1884(Red)X +2033(Rock,)X +2242(and)X +2378(speaking)X +2683(Dutch)X +2899(to)X +2981(anyone)X +3233(who)X +3391(will)X +3535(permit)X +3764(it.)X + +17 p +%%Trailer +xt + +xs + diff --git a/circuitpython/lib/berkeley-db-1.xx/docs/mpool.3.ps b/circuitpython/lib/berkeley-db-1.xx/docs/mpool.3.ps new file mode 100644 index 0000000..816c924 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/docs/mpool.3.ps @@ -0,0 +1,320 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.08 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Bold +%%+ font Times-Italic +%%DocumentSuppliedResources: procset grops 1.08 0 +%%Pages: 2 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.08 0 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Bold +%%IncludeResource: font Times-Italic +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL +792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron +/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space +/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft +/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four +/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C +/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash +/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q +/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase +/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger +/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus +/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu +/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright +/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde +/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute +/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls +/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute +/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve +/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex +/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE +/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 129.01(MPOOL\(3\) BSD)72 48 R(Programmer')2.5 E 2.5(sM) +-.55 G 129.01(anual MPOOL\(3\))340.17 48 R/F1 9/Times-Bold@0 SF -.18(NA)72 84 S +(ME).18 E F0(mpool \255 shared memory b)108 96 Q(uf)-.2 E(fer pool)-.25 E F1 +(SYNOPSIS)72 112.8 Q/F2 10/Times-Bold@0 SF(#include )-.4 E +(#include )108 136.8 Q(MPOOL *)108 160.8 Q(mpool_open \(DBT *k)108 +172.8 Q(ey)-.1 E 2.5(,i)-.55 G(nt fd, pgno_t pagesize, pgno_t maxcache\);) +216.25 172.8 Q -.1(vo)108 196.8 S(id).1 E(mpool_\214lter \(MPOOL *mp, v)108 +208.8 Q(oid \(*pgin\)\(v)-.1 E(oid *, pgno_t, v)-.1 E(oid *\),)-.1 E -.1(vo)158 +220.8 S(id \(*pgout\)\(v).1 E(oid *, pgno_t, v)-.1 E(oid *\), v)-.1 E +(oid *pgcookie\);)-.1 E -.1(vo)108 244.8 S(id *).1 E +(mpool_new \(MPOOL *mp, pgno_t *pgnoaddr\);)108 256.8 Q -.1(vo)108 280.8 S +(id *).1 E(mpool_get \(MPOOL *mp, pgno_t pgno, u_int \215ags\);)108 292.8 Q +(int)108 316.8 Q(mpool_put \(MPOOL *mp, v)108 328.8 Q(oid *pgaddr)-.1 E 2.5(,u) +-.92 G(_int \215ags\);)290.62 328.8 Q(int)108 352.8 Q +(mpool_sync \(MPOOL *mp\);)108 364.8 Q(int)108 388.8 Q +(mpool_close \(MPOOL *mp\);)108 400.8 Q F1(DESCRIPTION)72 417.6 Q/F3 10 +/Times-Italic@0 SF(Mpool)108 429.6 Q F0 1.013(is the library interf)3.513 F +1.013(ace intended to pro)-.1 F 1.013(vide page oriented b)-.15 F(uf)-.2 E +1.012(fer management of \214les.)-.25 F 1.012(The b)6.012 F(uf)-.2 E(fers)-.25 +E(may be shared between processes.)108 441.6 Q .416(The function)108 458.4 R F3 +(mpool_open)2.916 E F0 .417(initializes a memory pool.)2.917 F(The)5.417 E F3 +-.1(ke)2.917 G(y)-.2 E F0(ar)2.917 E .417(gument is the byte string used to ne) +-.18 F(gotiate)-.15 E .697(between multiple processes wishing to share b)108 +470.4 R(uf)-.2 E 3.196(fers. If)-.25 F .696(the \214le b)3.196 F(uf)-.2 E .696 +(fers are mapped in shared memory)-.25 F 3.196(,a)-.65 G(ll)534.44 470.4 Q .894 +(processes using the same k)108 482.4 R 1.194 -.15(ey w)-.1 H .894 +(ill share the b).15 F(uf)-.2 E 3.394(fers. If)-.25 F F3 -.1(ke)3.394 G(y)-.2 E +F0 .895(is NULL, the b)3.395 F(uf)-.2 E .895(fers are mapped into pri)-.25 F +-.25(va)-.25 G(te).25 E(memory)108 494.4 Q 5.116(.T)-.65 G(he)154.406 494.4 Q +F3(fd)2.616 E F0(ar)2.616 E .115(gument is a \214le descriptor for the underly\ +ing \214le, which must be seekable.)-.18 F(If)5.115 E F3 -.1(ke)2.615 G(y)-.2 E +F0 .115(is non-)2.615 F(NULL and matches a \214le already being mapped, the)108 +506.4 Q F3(fd)2.5 E F0(ar)2.5 E(gument is ignored.)-.18 E(The)108 523.2 Q F3 +(pa)3.328 E -.1(ge)-.1 G(size).1 E F0(ar)3.329 E .829 +(gument is the size, in bytes, of the pages into which the \214le is brok)-.18 +F .829(en up.)-.1 F(The)5.829 E F3(maxcac)3.329 E(he)-.15 E F0(ar)108 535.2 Q +.153(gument is the maximum number of pages from the underlying \214le to cache\ + at an)-.18 F 2.653(yo)-.15 G .153(ne time.)451.308 535.2 R .153(This v)5.153 F +.153(alue is)-.25 F .099(not relati)108 547.2 R .399 -.15(ve t)-.25 H 2.599(ot) +.15 G .099(he number of processes which share a \214le')168.727 547.2 R 2.6(sb) +-.55 G(uf)350.39 547.2 Q .1(fers, b)-.25 F .1(ut will be the lar)-.2 F .1 +(gest v)-.18 F .1(alue speci\214ed by)-.25 F(an)108 559.2 Q 2.5(yo)-.15 G 2.5 +(ft)129.79 559.2 S(he processes sharing the \214le.)138.4 559.2 Q(The)108 576 Q +F3(mpool_\214lter)3.254 E F0 .754(function is intended to mak)3.254 F 3.254(et) +-.1 G .754(ransparent input and output processing of the pages possi-)301.778 +576 R 3.095(ble. If)108 588 R(the)3.095 E F3(pgin)3.095 E F0 .596 +(function is speci\214ed, it is called each time a b)3.095 F(uf)-.2 E .596 +(fer is read into the memory pool from the)-.25 F .125(backing \214le.)108 600 +R .125(If the)5.125 F F3(pgout)2.625 E F0 .125 +(function is speci\214ed, it is called each time a b)2.625 F(uf)-.2 E .125 +(fer is written into the backing \214le.)-.25 F .276 +(Both functions are are called with the)108 612 R F3(pgcookie)2.777 E F0 +(pointer)2.777 E 2.777(,t)-.4 G .277 +(he page number and a pointer to the page to being)337.27 612 R +(read or written.)108 624 Q .124(The function)108 640.8 R F3(mpool_ne)2.624 E +(w)-.15 E F0(tak)2.624 E .123(es an MPOOL pointer and an address as ar)-.1 F +2.623(guments. If)-.18 F 2.623(an)2.623 G .623 -.25(ew p)457.568 640.8 T .123 +(age can be allo-).25 F .944(cated, a pointer to the page is returned and the \ +page number is stored into the)108 652.8 R F3(pgnoaddr)3.445 E F0 3.445 +(address. Other)3.445 F(-)-.2 E(wise, NULL is returned and errno is set.)108 +664.8 Q 1.167(The function)108 681.6 R F3(mpool_g)3.667 E(et)-.1 E F0(tak)3.667 +E 1.167(es a MPOOL pointer and a page number as ar)-.1 F 3.666(guments. If)-.18 +F 1.166(the page e)3.666 F 1.166(xists, a)-.15 F .686 +(pointer to the page is returned.)108 693.6 R .687 +(Otherwise, NULL is returned and errno is set.)5.686 F .687 +(The \215ags parameter is not)5.687 F(4.4 Berk)72 732 Q(ele)-.1 E 2.5(yD)-.15 G +(istrib)132.57 732 Q 104.595(ution June)-.2 F(4, 1993)2.5 E(1)535 732 Q EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 129.01(MPOOL\(3\) BSD)72 48 R(Programmer')2.5 E 2.5(sM) +-.55 G 129.01(anual MPOOL\(3\))340.17 48 R(currently used.)108 84 Q 1.463 +(The function)108 100.8 R/F1 10/Times-Italic@0 SF(mpool_put)3.963 E F0 1.462 +(unpins the page referenced by)3.962 F F1(pgaddr)3.962 E F0(.).73 E F1(Pgaddr) +6.462 E F0 1.462(must be an address pre)3.962 F(viously)-.25 E(returned by)108 +112.8 Q F1(mpool_g)2.5 E(et)-.1 E F0(or)2.5 E F1(mpool_ne)2.5 E(w)-.15 E F0 5 +(.T).31 G(he \215ag v)271.65 112.8 Q(alue is speci\214ed by)-.25 E F1(or)2.5 E +F0('ing an).73 E 2.5(yo)-.15 G 2.5(ft)434.74 112.8 S(he follo)443.35 112.8 Q +(wing v)-.25 E(alues:)-.25 E(MPOOL_DIR)108 129.6 Q(TY)-.6 E +(The page has been modi\214ed and needs to be written to the backing \214le.) +144 141.6 Q F1(Mpool_put)108 158.4 Q F0 +(returns 0 on success and -1 if an error occurs.)2.5 E .247(The function)108 +175.2 R F1(mpool_sync)2.747 E F0 .247(writes all modi\214ed pages associated w\ +ith the MPOOL pointer to the backing \214le.)2.747 F F1(Mpool_sync)108 187.2 Q +F0(returns 0 on success and -1 if an error occurs.)2.5 E(The)108 204 Q F1 +(mpool_close)2.698 E F0 .198(function free')2.698 F 2.698(su)-.55 G 2.698(pa) +245.432 204 S .498 -.15(ny a)257.57 204 T .198 +(llocated memory associated with the memory pool cookie.).15 F(Modi-)5.197 E +(\214ed pages are)108 216 Q/F2 10/Times-Bold@0 SF(not)2.5 E F0 +(written to the backing \214le.)2.5 E F1(Mpool_close)5 E F0 +(returns 0 on success and -1 if an error occurs.)2.5 E/F3 9/Times-Bold@0 SF +(ERR)72 232.8 Q(ORS)-.27 E F0(The)108 244.8 Q F1(mpool_open)2.938 E F0 .438 +(function may f)2.938 F .438(ail and set)-.1 F F1(errno)2.938 E F0 .438(for an) +2.938 F 2.938(yo)-.15 G 2.938(ft)344.87 244.8 S .439 +(he errors speci\214ed for the library routine)353.918 244.8 R F1(mal-)2.939 E +(loc)108 256.8 Q F0(\(3\).).31 E(The)108 273.6 Q F1(mpool_g)2.5 E(et)-.1 E F0 +(function may f)2.5 E(ail and set)-.1 E F1(errno)2.5 E F0(for the follo)2.5 E +(wing:)-.25 E([EINV)108 290.4 Q 29.98(AL] The)-1.35 F(requested record doesn') +2.5 E 2.5(te)-.18 G(xist.)305.96 290.4 Q(The)108 307.2 Q F1(mpool_ne)4.073 E(w) +-.15 E F0(and)4.073 E F1(mpool_g)4.073 E(et)-.1 E F0 1.573(functions may f) +4.073 F 1.573(ail and set)-.1 F F1(errno)4.073 E F0 1.573(for an)4.073 F 4.073 +(yo)-.15 G 4.073(ft)421.336 307.2 S 1.573(he errors speci\214ed for the)431.519 +307.2 R(library routines)108 319.2 Q F1 -.37(re)2.5 G(ad).37 E F0(\(2\)).77 E +F1 2.5(,w).54 G(rite)214.48 319.2 Q F0(\(2\)).18 E F1(,).54 E F0(and)2.5 E F1 +(malloc)2.5 E F0(\(3\).).31 E(The)108 336 Q F1(mpool_sync)4.287 E F0 1.787 +(function may f)4.287 F 1.787(ail and set)-.1 F F1(errno)4.288 E F0 1.788 +(for an)4.288 F 4.288(yo)-.15 G 4.288(ft)356.694 336 S 1.788 +(he errors speci\214ed for the library routine)367.092 336 R F1(write)108 348 Q +F0(\(2\).).18 E(The)108 364.8 Q F1(mpool_close)4.125 E F0 1.624(function may f) +4.125 F 1.624(ail and set)-.1 F F1(errno)4.124 E F0 1.624(for an)4.124 F 4.124 +(yo)-.15 G 4.124(ft)357.842 364.8 S 1.624 +(he errors speci\214ed for the library routine)368.076 364.8 R F1(fr)108 376.8 +Q(ee)-.37 E F0(\(3\).).18 E F3(SEE ALSO)72 393.6 Q F1(dbopen)108 405.6 Q F0 +(\(3\),).24 E F1(btr)2.5 E(ee)-.37 E F0(\(3\),).18 E F1(hash)2.5 E F0(\(3\),) +.28 E F1 -.37(re)2.5 G(cno).37 E F0(\(3\)).18 E(4.4 Berk)72 732 Q(ele)-.1 E 2.5 +(yD)-.15 G(istrib)132.57 732 Q 104.595(ution June)-.2 F(4, 1993)2.5 E(2)535 732 +Q EP +%%Trailer +end +%%EOF diff --git a/circuitpython/lib/berkeley-db-1.xx/docs/recno.3.ps b/circuitpython/lib/berkeley-db-1.xx/docs/recno.3.ps new file mode 100644 index 0000000..8ffccfc --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/docs/recno.3.ps @@ -0,0 +1,341 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.08 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Bold +%%+ font Times-Italic +%%DocumentSuppliedResources: procset grops 1.08 0 +%%Pages: 2 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.08 0 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Bold +%%IncludeResource: font Times-Italic +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL +792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron +/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space +/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft +/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four +/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C +/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash +/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q +/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase +/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger +/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus +/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu +/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright +/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde +/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute +/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls +/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute +/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve +/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex +/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE +/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 130.12(RECNO\(3\) BSD)72 48 R(Programmer')2.5 E 2.5(sM) +-.55 G 130.12(anual RECNO\(3\))340.17 48 R/F1 9/Times-Bold@0 SF -.18(NA)72 84 S +(ME).18 E F0(recno \255 record number database access method)108 96 Q F1 +(SYNOPSIS)72 112.8 Q/F2 10/Times-Bold@0 SF(#include )108 124.8 Q +(#include )-.4 E F1(DESCRIPTION)72 153.6 Q F0 1.158 +(The routine)108 165.6 R/F3 10/Times-Italic@0 SF(dbopen)3.658 E F0 1.158 +(is the library interf)3.658 F 1.158(ace to database \214les.)-.1 F 1.157 +(One of the supported \214le formats is record)6.158 F 1.159(number \214les.) +108 177.6 R 1.159(The general description of the database access methods is in) +6.159 F F3(dbopen)3.66 E F0 1.16(\(3\), this manual page).24 F +(describes only the recno speci\214c information.)108 189.6 Q 1.944 +(The record number data structure is either v)108 206.4 R 1.944 +(ariable or \214x)-.25 F 1.944 +(ed-length records stored in a \215at-\214le format,)-.15 F 2.04 +(accessed by the logical record number)108 218.4 R 7.04(.T)-.55 G 2.04(he e) +286.31 218.4 R 2.04(xistence of record number \214v)-.15 F 4.54(ei)-.15 G 2.04 +(mplies the e)442.1 218.4 R 2.04(xistence of)-.15 F .876 +(records one through four)108 230.4 R 3.376(,a)-.4 G .875 +(nd the deletion of record number one causes record number \214v)219.684 230.4 +R 3.375(et)-.15 G 3.375(ob)489.93 230.4 S 3.375(er)503.305 230.4 S(enum-)514.45 +230.4 Q .282(bered to record number four)108 242.4 R 2.782(,a)-.4 G 2.782(sw) +231.19 242.4 S .283(ell as the cursor)245.082 242.4 R 2.783(,i)-.4 G 2.783(fp) +316.633 242.4 S .283(ositioned after record number one, to shift do)327.746 +242.4 R .283(wn one)-.25 F(record.)108 254.4 Q .373 +(The recno access method speci\214c data structure pro)108 271.2 R .373 +(vided to)-.15 F F3(dbopen)2.873 E F0 .373(is de\214ned in the include \214le as)-.4 F(follo)108 283.2 Q(ws:)-.25 E(typedef struct {)108 +300 Q(u_long \215ags;)144 312 Q(u_int cachesize;)144 324 Q(u_int psize;)144 336 +Q(int lorder;)144 348 Q(size_t reclen;)144 360 Q(u_char b)144 372 Q -.25(va) +-.15 G(l;).25 E(char *bfname;)144 384 Q 2.5(}R)108 396 S(ECNOINFO;)121.97 396 Q +(The elements of this structure are de\214ned as follo)108 412.8 Q(ws:)-.25 E +14.61(\215ags The)108 429.6 R(\215ag v)2.5 E(alue is speci\214ed by)-.25 E F3 +(or)2.5 E F0('ing an).73 E 2.5(yo)-.15 G 2.5(ft)313.2 429.6 S(he follo)321.81 +429.6 Q(wing v)-.25 E(alues:)-.25 E(R_FIXEDLEN)144 446.4 Q .962 +(The records are \214x)180 458.4 R .963(ed-length, not byte delimited.)-.15 F +.963(The structure element)5.963 F F3 -.37(re)3.463 G(clen).37 E F0 +(speci\214es)3.463 E .345(the length of the record, and the structure element) +180 470.4 R F3(bval)2.844 E F0 .344(is used as the pad character)2.844 F 5.344 +(.A)-.55 G -.15(ny)530.15 470.4 S .739 +(records, inserted into the database, that are less than)180 482.4 R F3 -.37 +(re)3.239 G(clen).37 E F0 .74(bytes long are automatically)3.239 F(padded.)180 +494.4 Q(R_NOKEY)144 511.2 Q 2.34(In the interf)180 523.2 R 2.34 +(ace speci\214ed by)-.1 F F3(dbopen)4.84 E F0 4.84(,t).24 G 2.34 +(he sequential record retrie)344.98 523.2 R -.25(va)-.25 G 4.84<6c8c>.25 G 2.34 +(lls in both the)478.25 523.2 R(caller')180 535.2 Q 3.556(sk)-.55 G 1.357 -.15 +(ey a)217.336 535.2 T 1.057(nd data structures.).15 F 1.057 +(If the R_NOKEY \215ag is speci\214ed, the)6.057 F F3(cur)3.557 E(sor)-.1 E F0 +(routines)3.557 E .029(are not required to \214ll in the k)180 547.2 R .329 +-.15(ey s)-.1 H 2.529(tructure. This).15 F .028(permits applications to retrie) +2.529 F .328 -.15(ve r)-.25 H .028(ecords at).15 F +(the end of \214les without reading all of the interv)180 559.2 Q +(ening records.)-.15 E(R_SN)144 576 Q(APSHO)-.35 E(T)-.4 E .964 +(This \215ag requires that a snapshot of the \214le be tak)180 588 R .965 +(en when)-.1 F F3(dbopen)3.465 E F0 .965(is called, instead of)3.465 F +(permitting an)180 600 Q 2.5(yu)-.15 G +(nmodi\214ed records to be read from the original \214le.)245.96 600 Q +(cachesize)108 616.8 Q 3.16(As)144 628.8 S .66 +(uggested maximum size, in bytes, of the memory cache.)158.27 628.8 R .659 +(This v)5.659 F .659(alue is)-.25 F F2(only)3.159 E F0(advisory)3.159 E 3.159 +(,a)-.65 G .659(nd the)514.621 628.8 R .046 +(access method will allocate more memory rather than f)144 640.8 R 2.546 +(ail. If)-.1 F F3(cac)2.546 E(hesize)-.15 E F0 2.546(is 0)2.546 F .046 +(\(no size is speci\214ed\) a)2.546 F(def)144 652.8 Q(ault cache is used.)-.1 E +12.95(psize The)108 669.6 R .715 +(recno access method stores the in-memory copies of its records in a btree.) +3.216 F .715(This v)5.715 F .715(alue is the)-.25 F .805 +(size \(in bytes\) of the pages used for nodes in that tree.)144 681.6 R(If) +5.805 E F3(psize)3.305 E F0 .806(is 0 \(no page size is speci\214ed\) a)3.305 F +1.468 +(page size is chosen based on the underlying \214le system I/O block size.)144 +693.6 R(See)6.467 E F3(btr)3.967 E(ee)-.37 E F0 1.467(\(3\) for more).18 F +(4.4 Berk)72 732 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 732 Q 96.815 +(ution August)-.2 F(18, 1994)2.5 E(1)535 732 Q EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 130.12(RECNO\(3\) BSD)72 48 R(Programmer')2.5 E 2.5(sM) +-.55 G 130.12(anual RECNO\(3\))340.17 48 R(information.)144 84 Q 9.62 +(lorder The)108 100.8 R 1.596(byte order for inte)4.096 F 1.596 +(gers in the stored database metadata.)-.15 F 1.597 +(The number should represent the)6.597 F .689(order as an inte)144 112.8 R .689 +(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689 +(ould be the number 4,321.)-.1 F(If)5.689 E/F1 10/Times-Italic@0 SF(lor)3.189 E +(der)-.37 E F0 .688(is 0 \(no)3.189 F +(order is speci\214ed\) the current host order is used.)144 124.8 Q 9.07 +(reclen The)108 141.6 R(length of a \214x)2.5 E(ed-length record.)-.15 E -.15 +(bv)108 158.4 S 16.68(al The)-.1 F .182 +(delimiting byte to be used to mark the end of a record for v)2.682 F .183 +(ariable-length records, and the pad)-.25 F .809(character for \214x)144 170.4 +R .809(ed-length records.)-.15 F .809(If no v)5.809 F .809 +(alue is speci\214ed, ne)-.25 F .809(wlines \(`)-.25 F(`\\n')-.74 E .808 +('\) are used to mark the)-.74 F(end of v)144 182.4 Q +(ariable-length records and \214x)-.25 E +(ed-length records are padded with spaces.)-.15 E 3.51(bfname The)108 199.2 R +.505 +(recno access method stores the in-memory copies of its records in a btree.) +3.005 F .506(If bfname is non-)5.506 F .065(NULL, it speci\214es the name of t\ +he btree \214le, as if speci\214ed as the \214le name for a dbopen of a btree) +144 211.2 R(\214le.)144 223.2 Q .971(The data part of the k)108 240 R -.15(ey) +-.1 G .972(/data pair used by the recno access method is the same as other acc\ +ess methods.).15 F .199(The k)108 252 R .499 -.15(ey i)-.1 H 2.699(sd).15 G(if) +157.507 252 Q 2.699(ferent. The)-.25 F F1(data)2.699 E F0 .199 +(\214eld of the k)2.699 F .499 -.15(ey s)-.1 H .198 +(hould be a pointer to a memory location of type).15 F F1 -.37(re)2.698 G +(cno_t).37 E F0 2.698(,a).68 G(s)536.11 252 Q .505(de\214ned in the include \214le.)-.4 F .506(This type is normally the lar)5.506 F +.506(gest unsigned inte)-.18 F .506(gral type a)-.15 F -.25(va)-.2 G .506 +(ilable to the).25 F 2.5(implementation. The)108 276 R F1(size)2.5 E F0 +(\214eld of the k)2.5 E .3 -.15(ey s)-.1 H(hould be the size of that type.).15 +E .706(Because there can be no meta-data associated with the underlying recno \ +access method \214les, an)108 292.8 R 3.206(yc)-.15 G(hanges)512.23 292.8 Q +1.262(made to the def)108 304.8 R 1.262(ault v)-.1 F 1.262(alues \(e.g. \214x) +-.25 F 1.263(ed record length or byte separator v)-.15 F 1.263 +(alue\) must be e)-.25 F 1.263(xplicitly speci\214ed)-.15 F +(each time the \214le is opened.)108 316.8 Q .065(In the interf)108 333.6 R +.065(ace speci\214ed by)-.1 F F1(dbopen)2.564 E F0 2.564(,u).24 G .064 +(sing the)261.548 333.6 R F1(put)2.564 E F0(interf)2.564 E .064 +(ace to create a ne)-.1 F 2.564(wr)-.25 G .064 +(ecord will cause the creation of)414.44 333.6 R .755(multiple, empty records \ +if the record number is more than one greater than the lar)108 345.6 R .755 +(gest record currently in)-.18 F(the database.)108 357.6 Q/F2 9/Times-Bold@0 SF +(ERR)72 374.4 Q(ORS)-.27 E F0(The)108 386.4 Q F1 -.37(re)2.922 G(cno).37 E F0 +.421(access method routines may f)2.921 F .421(ail and set)-.1 F F1(errno)2.921 +E F0 .421(for an)2.921 F 2.921(yo)-.15 G 2.921(ft)377.933 386.4 S .421 +(he errors speci\214ed for the library rou-)386.964 386.4 R(tine)108 398.4 Q F1 +(dbopen)2.5 E F0(\(3\) or the follo).24 E(wing:)-.25 E([EINV)108 415.2 Q(AL]) +-1.35 E(An attempt w)144 427.2 Q(as made to add a record to a \214x)-.1 E +(ed-length database that w)-.15 E(as too lar)-.1 E(ge to \214t.)-.18 E F2 +(SEE ALSO)72 444 Q F1(btr)108 456 Q(ee)-.37 E F0(\(3\)).18 E F1(dbopen)2.5 E F0 +(\(3\),).24 E F1(hash)2.5 E F0(\(3\),).28 E F1(mpool)2.5 E F0(\(3\),).51 E F1 +2.754(Document Pr)108 480 R 2.754(ocessing in a Relational Database System)-.45 +F F0 5.255(,M).32 G 2.755(ichael Stonebrak)362.13 480 R(er)-.1 E 5.255(,H)-.4 G +2.755(eidi Stettner)454.06 480 R 5.255(,J)-.4 G(oseph)516.67 480 Q +(Kalash, Antonin Guttman, Nadene L)108 492 Q +(ynn, Memorandum No. UCB/ERL M82/32, May 1982.)-.55 E F2 -.09(BU)72 508.8 S(GS) +.09 E F0(Only big and little endian byte order is supported.)108 520.8 Q +(4.4 Berk)72 732 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 732 Q 96.815 +(ution August)-.2 F(18, 1994)2.5 E(2)535 732 Q EP +%%Trailer +end +%%EOF diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/Makefile.inc b/circuitpython/lib/berkeley-db-1.xx/hash/Makefile.inc new file mode 100644 index 0000000..cac96fe --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/Makefile.inc @@ -0,0 +1,6 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 + +.PATH: ${.CURDIR}/db/hash + +SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \ + hash_page.c hsearch.c ndbm.c diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/README b/circuitpython/lib/berkeley-db-1.xx/hash/README new file mode 100644 index 0000000..f29ccf7 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/README @@ -0,0 +1,72 @@ +# @(#)README 8.1 (Berkeley) 6/4/93 + +This package implements a superset of the hsearch and dbm/ndbm libraries. + +Test Programs: + All test programs which need key/data pairs expect them entered + with key and data on separate lines + + tcreat3.c + Takes + bucketsize (bsize), + fill factor (ffactor), and + initial number of elements (nelem). + Creates a hash table named hashtest containing the + keys/data pairs entered from standard in. + thash4.c + Takes + bucketsize (bsize), + fill factor (ffactor), + initial number of elements (nelem) + bytes of cache (ncached), and + file from which to read data (fname) + Creates a table from the key/data pairs on standard in and + then does a read of each key/data in fname + tdel.c + Takes + bucketsize (bsize), and + fill factor (ffactor). + file from which to read data (fname) + Reads each key/data pair from fname and deletes the + key from the hash table hashtest + tseq.c + Reads the key/data pairs in the file hashtest and writes them + to standard out. + tread2.c + Takes + butes of cache (ncached). + Reads key/data pairs from standard in and looks them up + in the file hashtest. + tverify.c + Reads key/data pairs from standard in, looks them up + in the file hashtest, and verifies that the data is + correct. + +NOTES: + +The file search.h is provided for using the hsearch compatible interface +on BSD systems. On System V derived systems, search.h should appear in +/usr/include. + +The man page ../man/db.3 explains the interface to the hashing system. +The file hash.ps is a postscript copy of a paper explaining +the history, implementation, and performance of the hash package. + +"bugs" or idiosyncracies + +If you have a lot of overflows, it is possible to run out of overflow +pages. Currently, this will cause a message to be printed on stderr. +Eventually, this will be indicated by a return error code. + +If you are using the ndbm interface and exit without flushing or closing the +file, you may lose updates since the package buffers all writes. Also, +the db interface only creates a single database file. To avoid overwriting +the user's original file, the suffix ".db" is appended to the file name +passed to dbm_open. Additionally, if your code "knows" about the historic +.dir and .pag files, it will break. + +There is a fundamental difference between this package and the old hsearch. +Hsearch requires the user to maintain the keys and data in the application's +allocated memory while hash takes care of all storage management. The down +side is that the byte strings passed in the ENTRY structure must be null +terminated (both the keys and the data). diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/extern.h b/circuitpython/lib/berkeley-db-1.xx/hash/extern.h new file mode 100644 index 0000000..3167e6d --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/extern.h @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)extern.h 8.4 (Berkeley) 6/16/94 + */ + +BUFHEAD *__add_ovflpage __P((HTAB *, BUFHEAD *)); +int __addel __P((HTAB *, BUFHEAD *, const DBT *, const DBT *)); +int __big_delete __P((HTAB *, BUFHEAD *)); +int __big_insert __P((HTAB *, BUFHEAD *, const DBT *, const DBT *)); +int __big_keydata __P((HTAB *, BUFHEAD *, DBT *, DBT *, int)); +int __big_return __P((HTAB *, BUFHEAD *, int, DBT *, int)); +int __big_split __P((HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *, + int, u_int32_t, SPLIT_RETURN *)); +int __buf_free __P((HTAB *, int, int)); +void __buf_init __P((HTAB *, int)); +u_int32_t __call_hash __P((HTAB *, char *, int)); +int __delpair __P((HTAB *, BUFHEAD *, int)); +int __expand_table __P((HTAB *)); +int __find_bigpair __P((HTAB *, BUFHEAD *, int, char *, int)); +u_int16_t __find_last_page __P((HTAB *, BUFHEAD **)); +void __free_ovflpage __P((HTAB *, BUFHEAD *)); +BUFHEAD *__get_buf __P((HTAB *, u_int32_t, BUFHEAD *, int)); +int __get_page __P((HTAB *, char *, u_int32_t, int, int, int)); +int __ibitmap __P((HTAB *, int, int, int)); +u_int32_t __log2 __P((u_int32_t)); +int __put_page __P((HTAB *, char *, u_int32_t, int, int)); +void __reclaim_buf __P((HTAB *, BUFHEAD *)); +int __split_page __P((HTAB *, u_int32_t, u_int32_t)); + +/* Default hash routine. */ +extern u_int32_t (*__default_hash) __P((const void *, size_t)); + +#ifdef HASH_STATISTICS +extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows; +#endif diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/hash.c b/circuitpython/lib/berkeley-db-1.xx/hash/hash.c new file mode 100644 index 0000000..4b7b732 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/hash.c @@ -0,0 +1,994 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif + +#include +#include "hash.h" +#include "page.h" +#include "extern.h" + +static int alloc_segs __P((HTAB *, int)); +static int flush_meta __P((HTAB *)); +static int hash_access __P((HTAB *, ACTION, DBT *, DBT *)); +static int hash_close __P((DB *)); +static int hash_delete __P((const DB *, const DBT *, u_int32_t)); +static int hash_fd __P((const DB *)); +static int hash_get __P((const DB *, const DBT *, DBT *, u_int32_t)); +static int hash_put __P((const DB *, DBT *, const DBT *, u_int32_t)); +static void *hash_realloc __P((SEGMENT **, int, int)); +static int hash_seq __P((const DB *, DBT *, DBT *, u_int32_t)); +static int hash_sync __P((const DB *, u_int32_t)); +static int hdestroy __P((HTAB *)); +static HTAB *init_hash __P((HTAB *, const char *, HASHINFO *)); +static int init_htab __P((HTAB *, int)); +#if BYTE_ORDER == LITTLE_ENDIAN +static void swap_header __P((HTAB *)); +static void swap_header_copy __P((HASHHDR *, HASHHDR *)); +#endif + +/* Fast arithmetic, relying on powers of 2, */ +#define MOD(x, y) ((x) & ((y) - 1)) + +#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; } + +/* Return values */ +#define SUCCESS (0) +#define ERROR (-1) +#define ABNORMAL (1) + +#ifdef HASH_STATISTICS +int hash_accesses, hash_collisions, hash_expansions, hash_overflows; +#endif + +/************************** INTERFACE ROUTINES ***************************/ +/* OPEN/CLOSE */ + +extern DB * +__hash_open(file, flags, mode, info, dflags) + const char *file; + int flags, mode, dflags; + const HASHINFO *info; /* Special directives for create */ +{ + HTAB *hashp; + struct stat statbuf; + DB *dbp; + int bpages, hdrsize, new_table, nsegs, save_errno; + + if ((flags & O_ACCMODE) == O_WRONLY) { + errno = EINVAL; + return (NULL); + } + + if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) + return (NULL); + hashp->fp = -1; + + /* + * Even if user wants write only, we need to be able to read + * the actual file, so we need to open it read/write. But, the + * field in the hashp structure needs to be accurate so that + * we can check accesses. + */ + hashp->flags = flags; + + new_table = 0; + if (!file || (flags & O_TRUNC) || + (stat(file, &statbuf) && (errno == ENOENT))) { + if (errno == ENOENT) + errno = 0; /* Just in case someone looks at errno */ + new_table = 1; + } + if (file) { + if ((hashp->fp = open(file, flags, mode)) == -1) + RETURN_ERROR(errno, error0); + (void)fcntl(hashp->fp, F_SETFD, 1); + } + if (new_table) { + if (!(hashp = init_hash(hashp, file, (HASHINFO *)info))) + RETURN_ERROR(errno, error1); + } else { + /* Table already exists */ + if (info && info->hash) + hashp->hash = info->hash; + else + hashp->hash = __default_hash; + + hdrsize = read(hashp->fp, &hashp->hdr, sizeof(HASHHDR)); +#if BYTE_ORDER == LITTLE_ENDIAN + swap_header(hashp); +#endif + if (hdrsize == -1) + RETURN_ERROR(errno, error1); + if (hdrsize != sizeof(HASHHDR)) + RETURN_ERROR(EFTYPE, error1); + /* Verify file type, versions and hash function */ + if (hashp->MAGIC != HASHMAGIC) + RETURN_ERROR(EFTYPE, error1); +#define OLDHASHVERSION 1 + if (hashp->VERSION != HASHVERSION && + hashp->VERSION != OLDHASHVERSION) + RETURN_ERROR(EFTYPE, error1); + if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY) + RETURN_ERROR(EFTYPE, error1); + /* + * Figure out how many segments we need. Max_Bucket is the + * maximum bucket number, so the number of buckets is + * max_bucket + 1. + */ + nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) / + hashp->SGSIZE; + hashp->nsegs = 0; + if (alloc_segs(hashp, nsegs)) + /* + * If alloc_segs fails, table will have been destroyed + * and errno will have been set. + */ + return (NULL); + /* Read in bitmaps */ + bpages = (hashp->SPARES[hashp->OVFL_POINT] + + (hashp->BSIZE << BYTE_SHIFT) - 1) >> + (hashp->BSHIFT + BYTE_SHIFT); + + hashp->nmaps = bpages; + (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *)); + } + + /* Initialize Buffer Manager */ + if (info && info->cachesize) + __buf_init(hashp, info->cachesize); + else + __buf_init(hashp, DEF_BUFSIZE); + + hashp->new_file = new_table; + hashp->save_file = file && (hashp->flags & O_RDWR); + hashp->cbucket = -1; + if (!(dbp = (DB *)malloc(sizeof(DB)))) { + save_errno = errno; + hdestroy(hashp); + errno = save_errno; + return (NULL); + } + dbp->internal = hashp; + dbp->close = hash_close; + dbp->del = hash_delete; + dbp->fd = hash_fd; + dbp->get = hash_get; + dbp->put = hash_put; + dbp->seq = hash_seq; + dbp->sync = hash_sync; + dbp->type = DB_HASH; + +#ifdef DEBUG + (void)fprintf(stderr, +"%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n", + "init_htab:", + "TABLE POINTER ", hashp, + "BUCKET SIZE ", hashp->BSIZE, + "BUCKET SHIFT ", hashp->BSHIFT, + "DIRECTORY SIZE ", hashp->DSIZE, + "SEGMENT SIZE ", hashp->SGSIZE, + "SEGMENT SHIFT ", hashp->SSHIFT, + "FILL FACTOR ", hashp->FFACTOR, + "MAX BUCKET ", hashp->MAX_BUCKET, + "OVFL POINT ", hashp->OVFL_POINT, + "LAST FREED ", hashp->LAST_FREED, + "HIGH MASK ", hashp->HIGH_MASK, + "LOW MASK ", hashp->LOW_MASK, + "NSEGS ", hashp->nsegs, + "NKEYS ", hashp->NKEYS); +#endif +#ifdef HASH_STATISTICS + hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0; +#endif + return (dbp); + +error1: + if (hashp != NULL) + (void)close(hashp->fp); + +error0: + free(hashp); + errno = save_errno; + return (NULL); +} + +static int +hash_close(dbp) + DB *dbp; +{ + HTAB *hashp; + int retval; + + if (!dbp) + return (ERROR); + + hashp = (HTAB *)dbp->internal; + retval = hdestroy(hashp); + free(dbp); + return (retval); +} + +static int +hash_fd(dbp) + const DB *dbp; +{ + HTAB *hashp; + + if (!dbp) + return (ERROR); + + hashp = (HTAB *)dbp->internal; + if (hashp->fp == -1) { + errno = ENOENT; + return (-1); + } + return (hashp->fp); +} + +/************************** LOCAL CREATION ROUTINES **********************/ +static HTAB * +init_hash(hashp, file, info) + HTAB *hashp; + const char *file; + HASHINFO *info; +{ + struct stat statbuf; + int nelem; + + nelem = 1; + hashp->NKEYS = 0; + hashp->LORDER = BYTE_ORDER; + hashp->BSIZE = DEF_BUCKET_SIZE; + hashp->BSHIFT = DEF_BUCKET_SHIFT; + hashp->SGSIZE = DEF_SEGSIZE; + hashp->SSHIFT = DEF_SEGSIZE_SHIFT; + hashp->DSIZE = DEF_DIRSIZE; + hashp->FFACTOR = DEF_FFACTOR; + hashp->hash = __default_hash; + memset(hashp->SPARES, 0, sizeof(hashp->SPARES)); + memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS)); + + /* Fix bucket size to be optimal for file system */ + if (file != NULL) { + if (stat(file, &statbuf)) + return (NULL); + hashp->BSIZE = statbuf.st_blksize; + hashp->BSHIFT = __log2(hashp->BSIZE); + } + + if (info) { + if (info->bsize) { + /* Round pagesize up to power of 2 */ + hashp->BSHIFT = __log2(info->bsize); + hashp->BSIZE = 1 << hashp->BSHIFT; + if (hashp->BSIZE > MAX_BSIZE) { + errno = EINVAL; + return (NULL); + } + } + if (info->ffactor) + hashp->FFACTOR = info->ffactor; + if (info->hash) + hashp->hash = info->hash; + if (info->nelem) + nelem = info->nelem; + if (info->lorder) { + if (info->lorder != BIG_ENDIAN && + info->lorder != LITTLE_ENDIAN) { + errno = EINVAL; + return (NULL); + } + hashp->LORDER = info->lorder; + } + } + /* init_htab should destroy the table and set errno if it fails */ + if (init_htab(hashp, nelem)) + return (NULL); + else + return (hashp); +} +/* + * This calls alloc_segs which may run out of memory. Alloc_segs will destroy + * the table and set errno, so we just pass the error information along. + * + * Returns 0 on No Error + */ +static int +init_htab(hashp, nelem) + HTAB *hashp; + int nelem; +{ + register int nbuckets, nsegs; + int l2; + + /* + * Divide number of elements by the fill factor and determine a + * desired number of buckets. Allocate space for the next greater + * power of two number of buckets. + */ + nelem = (nelem - 1) / hashp->FFACTOR + 1; + + l2 = __log2(MAX(nelem, 2)); + nbuckets = 1 << l2; + + hashp->SPARES[l2] = l2 + 1; + hashp->SPARES[l2 + 1] = l2 + 1; + hashp->OVFL_POINT = l2; + hashp->LAST_FREED = 2; + + /* First bitmap page is at: splitpoint l2 page offset 1 */ + if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0)) + return (-1); + + hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1; + hashp->HIGH_MASK = (nbuckets << 1) - 1; + hashp->HDRPAGES = ((MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >> + hashp->BSHIFT) + 1; + + nsegs = (nbuckets - 1) / hashp->SGSIZE + 1; + nsegs = 1 << __log2(nsegs); + + if (nsegs > hashp->DSIZE) + hashp->DSIZE = nsegs; + return (alloc_segs(hashp, nsegs)); +} + +/********************** DESTROY/CLOSE ROUTINES ************************/ + +/* + * Flushes any changes to the file if necessary and destroys the hashp + * structure, freeing all allocated space. + */ +static int +hdestroy(hashp) + HTAB *hashp; +{ + int i, save_errno; + + save_errno = 0; + +#ifdef HASH_STATISTICS + (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n", + hash_accesses, hash_collisions); + (void)fprintf(stderr, "hdestroy: expansions %ld\n", + hash_expansions); + (void)fprintf(stderr, "hdestroy: overflows %ld\n", + hash_overflows); + (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n", + hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs); + + for (i = 0; i < NCACHED; i++) + (void)fprintf(stderr, + "spares[%d] = %d\n", i, hashp->SPARES[i]); +#endif + /* + * Call on buffer manager to free buffers, and if required, + * write them to disk. + */ + if (__buf_free(hashp, 1, hashp->save_file)) + save_errno = errno; + if (hashp->dir) { + free(*hashp->dir); /* Free initial segments */ + /* Free extra segments */ + while (hashp->exsegs--) + free(hashp->dir[--hashp->nsegs]); + free(hashp->dir); + } + if (flush_meta(hashp) && !save_errno) + save_errno = errno; + /* Free Bigmaps */ + for (i = 0; i < hashp->nmaps; i++) + if (hashp->mapp[i]) + free(hashp->mapp[i]); + + if (hashp->fp != -1) + (void)close(hashp->fp); + + free(hashp); + + if (save_errno) { + errno = save_errno; + return (ERROR); + } + return (SUCCESS); +} +/* + * Write modified pages to disk + * + * Returns: + * 0 == OK + * -1 ERROR + */ +static int +hash_sync(dbp, flags) + const DB *dbp; + u_int32_t flags; +{ + HTAB *hashp; + + if (flags != 0) { + errno = EINVAL; + return (ERROR); + } + + if (!dbp) + return (ERROR); + + hashp = (HTAB *)dbp->internal; + if (!hashp->save_file) + return (0); + if (__buf_free(hashp, 0, 1) || flush_meta(hashp)) + return (ERROR); + hashp->new_file = 0; + return (0); +} + +/* + * Returns: + * 0 == OK + * -1 indicates that errno should be set + */ +static int +flush_meta(hashp) + HTAB *hashp; +{ + HASHHDR *whdrp; +#if BYTE_ORDER == LITTLE_ENDIAN + HASHHDR whdr; +#endif + int fp, i, wsize; + + if (!hashp->save_file) + return (0); + hashp->MAGIC = HASHMAGIC; + hashp->VERSION = HASHVERSION; + hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY)); + + fp = hashp->fp; + whdrp = &hashp->hdr; +#if BYTE_ORDER == LITTLE_ENDIAN + whdrp = &whdr; + swap_header_copy(&hashp->hdr, whdrp); +#endif + if ((lseek(fp, (off_t)0, SEEK_SET) == -1) || + ((wsize = write(fp, whdrp, sizeof(HASHHDR))) == -1)) + return (-1); + else + if (wsize != sizeof(HASHHDR)) { + errno = EFTYPE; + hashp->errno = errno; + return (-1); + } + for (i = 0; i < NCACHED; i++) + if (hashp->mapp[i]) + if (__put_page(hashp, (char *)hashp->mapp[i], + hashp->BITMAPS[i], 0, 1)) + return (-1); + return (0); +} + +/*******************************SEARCH ROUTINES *****************************/ +/* + * All the access routines return + * + * Returns: + * 0 on SUCCESS + * 1 to indicate an external ERROR (i.e. key not found, etc) + * -1 to indicate an internal ERROR (i.e. out of memory, etc) + */ +static int +hash_get(dbp, key, data, flag) + const DB *dbp; + const DBT *key; + DBT *data; + u_int32_t flag; +{ + HTAB *hashp; + + hashp = (HTAB *)dbp->internal; + if (flag) { + hashp->errno = errno = EINVAL; + return (ERROR); + } + return (hash_access(hashp, HASH_GET, (DBT *)key, data)); +} + +static int +hash_put(dbp, key, data, flag) + const DB *dbp; + DBT *key; + const DBT *data; + u_int32_t flag; +{ + HTAB *hashp; + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_NOOVERWRITE) { + hashp->errno = errno = EINVAL; + return (ERROR); + } + if ((hashp->flags & O_ACCMODE) == O_RDONLY) { + hashp->errno = errno = EPERM; + return (ERROR); + } + return (hash_access(hashp, flag == R_NOOVERWRITE ? + HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data)); +} + +static int +hash_delete(dbp, key, flag) + const DB *dbp; + const DBT *key; + u_int32_t flag; /* Ignored */ +{ + HTAB *hashp; + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_CURSOR) { + hashp->errno = errno = EINVAL; + return (ERROR); + } + if ((hashp->flags & O_ACCMODE) == O_RDONLY) { + hashp->errno = errno = EPERM; + return (ERROR); + } + return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL)); +} + +/* + * Assume that hashp has been set in wrapper routine. + */ +static int +hash_access(hashp, action, key, val) + HTAB *hashp; + ACTION action; + DBT *key, *val; +{ + register BUFHEAD *rbufp; + BUFHEAD *bufp, *save_bufp; + register u_int16_t *bp; + register int n, ndx, off, size; + register char *kp; + u_int16_t pageno; + +#ifdef HASH_STATISTICS + hash_accesses++; +#endif + + off = hashp->BSIZE; + size = key->size; + kp = (char *)key->data; + rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0); + if (!rbufp) + return (ERROR); + save_bufp = rbufp; + + /* Pin the bucket chain */ + rbufp->flags |= BUF_PIN; + for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;) + if (bp[1] >= REAL_KEY) { + /* Real key/data pair */ + if (size == off - *bp && + memcmp(kp, rbufp->page + *bp, size) == 0) + goto found; + off = bp[1]; +#ifdef HASH_STATISTICS + hash_collisions++; +#endif + bp += 2; + ndx += 2; + } else if (bp[1] == OVFLPAGE) { + rbufp = __get_buf(hashp, *bp, rbufp, 0); + if (!rbufp) { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } + /* FOR LOOP INIT */ + bp = (u_int16_t *)rbufp->page; + n = *bp++; + ndx = 1; + off = hashp->BSIZE; + } else if (bp[1] < REAL_KEY) { + if ((ndx = + __find_bigpair(hashp, rbufp, ndx, kp, size)) > 0) + goto found; + if (ndx == -2) { + bufp = rbufp; + if (!(pageno = + __find_last_page(hashp, &bufp))) { + ndx = 0; + rbufp = bufp; + break; /* FOR */ + } + rbufp = __get_buf(hashp, pageno, bufp, 0); + if (!rbufp) { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } + /* FOR LOOP INIT */ + bp = (u_int16_t *)rbufp->page; + n = *bp++; + ndx = 1; + off = hashp->BSIZE; + } else { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } + } + + /* Not found */ + switch (action) { + case HASH_PUT: + case HASH_PUTNEW: + if (__addel(hashp, rbufp, key, val)) { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } else { + save_bufp->flags &= ~BUF_PIN; + return (SUCCESS); + } + case HASH_GET: + case HASH_DELETE: + default: + save_bufp->flags &= ~BUF_PIN; + return (ABNORMAL); + } + +found: + switch (action) { + case HASH_PUTNEW: + save_bufp->flags &= ~BUF_PIN; + return (ABNORMAL); + case HASH_GET: + bp = (u_int16_t *)rbufp->page; + if (bp[ndx + 1] < REAL_KEY) { + if (__big_return(hashp, rbufp, ndx, val, 0)) + return (ERROR); + } else { + val->data = (u_char *)rbufp->page + (int)bp[ndx + 1]; + val->size = bp[ndx] - bp[ndx + 1]; + } + break; + case HASH_PUT: + if ((__delpair(hashp, rbufp, ndx)) || + (__addel(hashp, rbufp, key, val))) { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } + break; + case HASH_DELETE: + if (__delpair(hashp, rbufp, ndx)) + return (ERROR); + break; + default: + abort(); + } + save_bufp->flags &= ~BUF_PIN; + return (SUCCESS); +} + +static int +hash_seq(dbp, key, data, flag) + const DB *dbp; + DBT *key, *data; + u_int32_t flag; +{ + register u_int32_t bucket; + register BUFHEAD *bufp; + HTAB *hashp; + u_int16_t *bp, ndx; + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_FIRST && flag != R_NEXT) { + hashp->errno = errno = EINVAL; + return (ERROR); + } +#ifdef HASH_STATISTICS + hash_accesses++; +#endif + if ((hashp->cbucket < 0) || (flag == R_FIRST)) { + hashp->cbucket = 0; + hashp->cndx = 1; + hashp->cpage = NULL; + } + + for (bp = NULL; !bp || !bp[0]; ) { + if (!(bufp = hashp->cpage)) { + for (bucket = hashp->cbucket; + bucket <= hashp->MAX_BUCKET; + bucket++, hashp->cndx = 1) { + bufp = __get_buf(hashp, bucket, NULL, 0); + if (!bufp) + return (ERROR); + hashp->cpage = bufp; + bp = (u_int16_t *)bufp->page; + if (bp[0]) + break; + } + hashp->cbucket = bucket; + if (hashp->cbucket > hashp->MAX_BUCKET) { + hashp->cbucket = -1; + return (ABNORMAL); + } + } else + bp = (u_int16_t *)hashp->cpage->page; + +#ifdef DEBUG + assert(bp); + assert(bufp); +#endif + while (bp[hashp->cndx + 1] == OVFLPAGE) { + bufp = hashp->cpage = + __get_buf(hashp, bp[hashp->cndx], bufp, 0); + if (!bufp) + return (ERROR); + bp = (u_int16_t *)(bufp->page); + hashp->cndx = 1; + } + if (!bp[0]) { + hashp->cpage = NULL; + ++hashp->cbucket; + } + } + ndx = hashp->cndx; + if (bp[ndx + 1] < REAL_KEY) { + if (__big_keydata(hashp, bufp, key, data, 1)) + return (ERROR); + } else { + key->data = (u_char *)hashp->cpage->page + bp[ndx]; + key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx]; + data->data = (u_char *)hashp->cpage->page + bp[ndx + 1]; + data->size = bp[ndx] - bp[ndx + 1]; + ndx += 2; + if (ndx > bp[0]) { + hashp->cpage = NULL; + hashp->cbucket++; + hashp->cndx = 1; + } else + hashp->cndx = ndx; + } + return (SUCCESS); +} + +/********************************* UTILITIES ************************/ + +/* + * Returns: + * 0 ==> OK + * -1 ==> Error + */ +extern int +__expand_table(hashp) + HTAB *hashp; +{ + u_int32_t old_bucket, new_bucket; + int dirsize, new_segnum, spare_ndx; + +#ifdef HASH_STATISTICS + hash_expansions++; +#endif + new_bucket = ++hashp->MAX_BUCKET; + old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK); + + new_segnum = new_bucket >> hashp->SSHIFT; + + /* Check if we need a new segment */ + if (new_segnum >= hashp->nsegs) { + /* Check if we need to expand directory */ + if (new_segnum >= hashp->DSIZE) { + /* Reallocate directory */ + dirsize = hashp->DSIZE * sizeof(SEGMENT *); + if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1)) + return (-1); + hashp->DSIZE = dirsize << 1; + } + if ((hashp->dir[new_segnum] = + (SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL) + return (-1); + hashp->exsegs++; + hashp->nsegs++; + } + /* + * If the split point is increasing (MAX_BUCKET's log base 2 + * * increases), we need to copy the current contents of the spare + * split bucket to the next bucket. + */ + spare_ndx = __log2(hashp->MAX_BUCKET + 1); + if (spare_ndx > hashp->OVFL_POINT) { + hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT]; + hashp->OVFL_POINT = spare_ndx; + } + + if (new_bucket > hashp->HIGH_MASK) { + /* Starting a new doubling */ + hashp->LOW_MASK = hashp->HIGH_MASK; + hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK; + } + /* Relocate records to the new bucket */ + return (__split_page(hashp, old_bucket, new_bucket)); +} + +/* + * If realloc guarantees that the pointer is not destroyed if the realloc + * fails, then this routine can go away. + */ +static void * +hash_realloc(p_ptr, oldsize, newsize) + SEGMENT **p_ptr; + int oldsize, newsize; +{ + register void *p; + + if (p = malloc(newsize)) { + memmove(p, *p_ptr, oldsize); + memset((char *)p + oldsize, 0, newsize - oldsize); + free(*p_ptr); + *p_ptr = p; + } + return (p); +} + +extern u_int32_t +__call_hash(hashp, k, len) + HTAB *hashp; + char *k; + int len; +{ + int n, bucket; + + n = hashp->hash(k, len); + bucket = n & hashp->HIGH_MASK; + if (bucket > hashp->MAX_BUCKET) + bucket = bucket & hashp->LOW_MASK; + return (bucket); +} + +/* + * Allocate segment table. On error, destroy the table and set errno. + * + * Returns 0 on success + */ +static int +alloc_segs(hashp, nsegs) + HTAB *hashp; + int nsegs; +{ + register int i; + register SEGMENT store; + + int save_errno; + + if ((hashp->dir = + (SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) { + save_errno = errno; + (void)hdestroy(hashp); + errno = save_errno; + return (-1); + } + /* Allocate segments */ + if ((store = + (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) { + save_errno = errno; + (void)hdestroy(hashp); + errno = save_errno; + return (-1); + } + for (i = 0; i < nsegs; i++, hashp->nsegs++) + hashp->dir[i] = &store[i << hashp->SSHIFT]; + return (0); +} + +#if BYTE_ORDER == LITTLE_ENDIAN +/* + * Hashp->hdr needs to be byteswapped. + */ +static void +swap_header_copy(srcp, destp) + HASHHDR *srcp, *destp; +{ + int i; + + P_32_COPY(srcp->magic, destp->magic); + P_32_COPY(srcp->version, destp->version); + P_32_COPY(srcp->lorder, destp->lorder); + P_32_COPY(srcp->bsize, destp->bsize); + P_32_COPY(srcp->bshift, destp->bshift); + P_32_COPY(srcp->dsize, destp->dsize); + P_32_COPY(srcp->ssize, destp->ssize); + P_32_COPY(srcp->sshift, destp->sshift); + P_32_COPY(srcp->ovfl_point, destp->ovfl_point); + P_32_COPY(srcp->last_freed, destp->last_freed); + P_32_COPY(srcp->max_bucket, destp->max_bucket); + P_32_COPY(srcp->high_mask, destp->high_mask); + P_32_COPY(srcp->low_mask, destp->low_mask); + P_32_COPY(srcp->ffactor, destp->ffactor); + P_32_COPY(srcp->nkeys, destp->nkeys); + P_32_COPY(srcp->hdrpages, destp->hdrpages); + P_32_COPY(srcp->h_charkey, destp->h_charkey); + for (i = 0; i < NCACHED; i++) { + P_32_COPY(srcp->spares[i], destp->spares[i]); + P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]); + } +} + +static void +swap_header(hashp) + HTAB *hashp; +{ + HASHHDR *hdrp; + int i; + + hdrp = &hashp->hdr; + + M_32_SWAP(hdrp->magic); + M_32_SWAP(hdrp->version); + M_32_SWAP(hdrp->lorder); + M_32_SWAP(hdrp->bsize); + M_32_SWAP(hdrp->bshift); + M_32_SWAP(hdrp->dsize); + M_32_SWAP(hdrp->ssize); + M_32_SWAP(hdrp->sshift); + M_32_SWAP(hdrp->ovfl_point); + M_32_SWAP(hdrp->last_freed); + M_32_SWAP(hdrp->max_bucket); + M_32_SWAP(hdrp->high_mask); + M_32_SWAP(hdrp->low_mask); + M_32_SWAP(hdrp->ffactor); + M_32_SWAP(hdrp->nkeys); + M_32_SWAP(hdrp->hdrpages); + M_32_SWAP(hdrp->h_charkey); + for (i = 0; i < NCACHED; i++) { + M_32_SWAP(hdrp->spares[i]); + M_16_SWAP(hdrp->bitmaps[i]); + } +} +#endif diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/hash.h b/circuitpython/lib/berkeley-db-1.xx/hash/hash.h new file mode 100644 index 0000000..913e82b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/hash.h @@ -0,0 +1,293 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)hash.h 8.3 (Berkeley) 5/31/94 + */ + +/* Operations */ +typedef enum { + HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT +} ACTION; + +/* Buffer Management structures */ +typedef struct _bufhead BUFHEAD; + +struct _bufhead { + BUFHEAD *prev; /* LRU links */ + BUFHEAD *next; /* LRU links */ + BUFHEAD *ovfl; /* Overflow page buffer header */ + u_int32_t addr; /* Address of this page */ + char *page; /* Actual page data */ + char flags; +#define BUF_MOD 0x0001 +#define BUF_DISK 0x0002 +#define BUF_BUCKET 0x0004 +#define BUF_PIN 0x0008 +}; + +#define IS_BUCKET(X) ((X) & BUF_BUCKET) + +typedef BUFHEAD **SEGMENT; + +/* Hash Table Information */ +typedef struct hashhdr { /* Disk resident portion */ + int magic; /* Magic NO for hash tables */ + int version; /* Version ID */ + u_int32_t lorder; /* Byte Order */ + int bsize; /* Bucket/Page Size */ + int bshift; /* Bucket shift */ + int dsize; /* Directory Size */ + int ssize; /* Segment Size */ + int sshift; /* Segment shift */ + int ovfl_point; /* Where overflow pages are being + * allocated */ + int last_freed; /* Last overflow page freed */ + int max_bucket; /* ID of Maximum bucket in use */ + int high_mask; /* Mask to modulo into entire table */ + int low_mask; /* Mask to modulo into lower half of + * table */ + int ffactor; /* Fill factor */ + int nkeys; /* Number of keys in hash table */ + int hdrpages; /* Size of table header */ + int h_charkey; /* value of hash(CHARKEY) */ +#define NCACHED 32 /* number of bit maps and spare + * points */ + int spares[NCACHED];/* spare pages for overflow */ + u_int16_t bitmaps[NCACHED]; /* address of overflow page + * bitmaps */ +} HASHHDR; + +typedef struct htab { /* Memory resident data structure */ + HASHHDR hdr; /* Header */ + int nsegs; /* Number of allocated segments */ + int exsegs; /* Number of extra allocated + * segments */ + u_int32_t /* Hash function */ + (*hash)__P((const void *, size_t)); + int flags; /* Flag values */ + int fp; /* File pointer */ + char *tmp_buf; /* Temporary Buffer for BIG data */ + char *tmp_key; /* Temporary Buffer for BIG keys */ + BUFHEAD *cpage; /* Current page */ + int cbucket; /* Current bucket */ + int cndx; /* Index of next item on cpage */ + int errno; /* Error Number -- for DBM + * compatability */ + int new_file; /* Indicates if fd is backing store + * or no */ + int save_file; /* Indicates whether we need to flush + * file at + * exit */ + u_int32_t *mapp[NCACHED]; /* Pointers to page maps */ + int nmaps; /* Initial number of bitmaps */ + int nbufs; /* Number of buffers left to + * allocate */ + BUFHEAD bufhead; /* Header of buffer lru list */ + SEGMENT *dir; /* Hash Bucket directory */ +} HTAB; + +/* + * Constants + */ +#define MAX_BSIZE 65536 /* 2^16 */ +#define MIN_BUFFERS 6 +#define MINHDRSIZE 512 +#define DEF_BUFSIZE 65536 /* 64 K */ +#define DEF_BUCKET_SIZE 4096 +#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */ +#define DEF_SEGSIZE 256 +#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */ +#define DEF_DIRSIZE 256 +#define DEF_FFACTOR 65536 +#define MIN_FFACTOR 4 +#define SPLTMAX 8 +#define CHARKEY "%$sniglet^&" +#define NUMKEY 1038583 +#define BYTE_SHIFT 3 +#define INT_TO_BYTE 2 +#define INT_BYTE_SHIFT 5 +#define ALL_SET ((u_int32_t)0xFFFFFFFF) +#define ALL_CLEAR 0 + +#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3)) +#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1) +#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1)) +#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2) +#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2)) + +#define BITS_PER_MAP 32 + +/* Given the address of the beginning of a big map, clear/set the nth bit */ +#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP))) +#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP))) +#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP))) + +/* Overflow management */ +/* + * Overflow page numbers are allocated per split point. At each doubling of + * the table, we can allocate extra pages. So, an overflow page number has + * the top 5 bits indicate which split point and the lower 11 bits indicate + * which page at that split point is indicated (pages within split points are + * numberered starting with 1). + */ + +#define SPLITSHIFT 11 +#define SPLITMASK 0x7FF +#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT) +#define OPAGENUM(N) ((N) & SPLITMASK) +#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O)) + +#define BUCKET_TO_PAGE(B) \ + (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0) +#define OADDR_TO_PAGE(B) \ + BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B)); + +/* + * page.h contains a detailed description of the page format. + * + * Normally, keys and data are accessed from offset tables in the top of + * each page which point to the beginning of the key and data. There are + * four flag values which may be stored in these offset tables which indicate + * the following: + * + * + * OVFLPAGE Rather than a key data pair, this pair contains + * the address of an overflow page. The format of + * the pair is: + * OVERFLOW_PAGE_NUMBER OVFLPAGE + * + * PARTIAL_KEY This must be the first key/data pair on a page + * and implies that page contains only a partial key. + * That is, the key is too big to fit on a single page + * so it starts on this page and continues on the next. + * The format of the page is: + * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE + * + * KEY_OFF -- offset of the beginning of the key + * PARTIAL_KEY -- 1 + * OVFL_PAGENO - page number of the next overflow page + * OVFLPAGE -- 0 + * + * FULL_KEY This must be the first key/data pair on the page. It + * is used in two cases. + * + * Case 1: + * There is a complete key on the page but no data + * (because it wouldn't fit). The next page contains + * the data. + * + * Page format it: + * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE + * + * KEY_OFF -- offset of the beginning of the key + * FULL_KEY -- 2 + * OVFL_PAGENO - page number of the next overflow page + * OVFLPAGE -- 0 + * + * Case 2: + * This page contains no key, but part of a large + * data field, which is continued on the next page. + * + * Page format it: + * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE + * + * KEY_OFF -- offset of the beginning of the data on + * this page + * FULL_KEY -- 2 + * OVFL_PAGENO - page number of the next overflow page + * OVFLPAGE -- 0 + * + * FULL_KEY_DATA + * This must be the first key/data pair on the page. + * There are two cases: + * + * Case 1: + * This page contains a key and the beginning of the + * data field, but the data field is continued on the + * next page. + * + * Page format is: + * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF + * + * KEY_OFF -- offset of the beginning of the key + * FULL_KEY_DATA -- 3 + * OVFL_PAGENO - page number of the next overflow page + * DATA_OFF -- offset of the beginning of the data + * + * Case 2: + * This page contains the last page of a big data pair. + * There is no key, only the tail end of the data + * on this page. + * + * Page format is: + * DATA_OFF FULL_KEY_DATA + * + * DATA_OFF -- offset of the beginning of the data on + * this page + * FULL_KEY_DATA -- 3 + * OVFL_PAGENO - page number of the next overflow page + * OVFLPAGE -- 0 + * + * OVFL_PAGENO and OVFLPAGE are optional (they are + * not present if there is no next page). + */ + +#define OVFLPAGE 0 +#define PARTIAL_KEY 1 +#define FULL_KEY 2 +#define FULL_KEY_DATA 3 +#define REAL_KEY 4 + +/* Short hands for accessing structure */ +#define BSIZE hdr.bsize +#define BSHIFT hdr.bshift +#define DSIZE hdr.dsize +#define SGSIZE hdr.ssize +#define SSHIFT hdr.sshift +#define LORDER hdr.lorder +#define OVFL_POINT hdr.ovfl_point +#define LAST_FREED hdr.last_freed +#define MAX_BUCKET hdr.max_bucket +#define FFACTOR hdr.ffactor +#define HIGH_MASK hdr.high_mask +#define LOW_MASK hdr.low_mask +#define NKEYS hdr.nkeys +#define HDRPAGES hdr.hdrpages +#define SPARES hdr.spares +#define BITMAPS hdr.bitmaps +#define VERSION hdr.version +#define MAGIC hdr.magic +#define NEXT_FREE hdr.next_free +#define H_CHARKEY hdr.h_charkey diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/hash_bigkey.c b/circuitpython/lib/berkeley-db-1.xx/hash/hash_bigkey.c new file mode 100644 index 0000000..578314a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/hash_bigkey.c @@ -0,0 +1,667 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94"; +#endif /* LIBC_SCCS and not lint */ + +/* + * PACKAGE: hash + * DESCRIPTION: + * Big key/data handling for the hashing package. + * + * ROUTINES: + * External + * __big_keydata + * __big_split + * __big_insert + * __big_return + * __big_delete + * __find_last_page + * Internal + * collect_key + * collect_data + */ + +#include + +#include +#include +#include +#include + +#ifdef DEBUG +#include +#endif + +#include +#include "hash.h" +#include "page.h" +#include "extern.h" + +static int collect_key __P((HTAB *, BUFHEAD *, int, DBT *, int)); +static int collect_data __P((HTAB *, BUFHEAD *, int, int)); + +/* + * Big_insert + * + * You need to do an insert and the key/data pair is too big + * + * Returns: + * 0 ==> OK + *-1 ==> ERROR + */ +extern int +__big_insert(hashp, bufp, key, val) + HTAB *hashp; + BUFHEAD *bufp; + const DBT *key, *val; +{ + register u_int16_t *p; + int key_size, n, val_size; + u_int16_t space, move_bytes, off; + char *cp, *key_data, *val_data; + + cp = bufp->page; /* Character pointer of p. */ + p = (u_int16_t *)cp; + + key_data = (char *)key->data; + key_size = key->size; + val_data = (char *)val->data; + val_size = val->size; + + /* First move the Key */ + for (space = FREESPACE(p) - BIGOVERHEAD; key_size; + space = FREESPACE(p) - BIGOVERHEAD) { + move_bytes = MIN(space, key_size); + off = OFFSET(p) - move_bytes; + memmove(cp + off, key_data, move_bytes); + key_size -= move_bytes; + key_data += move_bytes; + n = p[0]; + p[++n] = off; + p[0] = ++n; + FREESPACE(p) = off - PAGE_META(n); + OFFSET(p) = off; + p[n] = PARTIAL_KEY; + bufp = __add_ovflpage(hashp, bufp); + if (!bufp) + return (-1); + n = p[0]; + if (!key_size) + if (FREESPACE(p)) { + move_bytes = MIN(FREESPACE(p), val_size); + off = OFFSET(p) - move_bytes; + p[n] = off; + memmove(cp + off, val_data, move_bytes); + val_data += move_bytes; + val_size -= move_bytes; + p[n - 2] = FULL_KEY_DATA; + FREESPACE(p) = FREESPACE(p) - move_bytes; + OFFSET(p) = off; + } else + p[n - 2] = FULL_KEY; + p = (u_int16_t *)bufp->page; + cp = bufp->page; + bufp->flags |= BUF_MOD; + } + + /* Now move the data */ + for (space = FREESPACE(p) - BIGOVERHEAD; val_size; + space = FREESPACE(p) - BIGOVERHEAD) { + move_bytes = MIN(space, val_size); + /* + * Here's the hack to make sure that if the data ends on the + * same page as the key ends, FREESPACE is at least one. + */ + if (space == val_size && val_size == val->size) + move_bytes--; + off = OFFSET(p) - move_bytes; + memmove(cp + off, val_data, move_bytes); + val_size -= move_bytes; + val_data += move_bytes; + n = p[0]; + p[++n] = off; + p[0] = ++n; + FREESPACE(p) = off - PAGE_META(n); + OFFSET(p) = off; + if (val_size) { + p[n] = FULL_KEY; + bufp = __add_ovflpage(hashp, bufp); + if (!bufp) + return (-1); + cp = bufp->page; + p = (u_int16_t *)cp; + } else + p[n] = FULL_KEY_DATA; + bufp->flags |= BUF_MOD; + } + return (0); +} + +/* + * Called when bufp's page contains a partial key (index should be 1) + * + * All pages in the big key/data pair except bufp are freed. We cannot + * free bufp because the page pointing to it is lost and we can't get rid + * of its pointer. + * + * Returns: + * 0 => OK + *-1 => ERROR + */ +extern int +__big_delete(hashp, bufp) + HTAB *hashp; + BUFHEAD *bufp; +{ + register BUFHEAD *last_bfp, *rbufp; + u_int16_t *bp, pageno; + int key_done, n; + + rbufp = bufp; + last_bfp = NULL; + bp = (u_int16_t *)bufp->page; + pageno = 0; + key_done = 0; + + while (!key_done || (bp[2] != FULL_KEY_DATA)) { + if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) + key_done = 1; + + /* + * If there is freespace left on a FULL_KEY_DATA page, then + * the data is short and fits entirely on this page, and this + * is the last page. + */ + if (bp[2] == FULL_KEY_DATA && FREESPACE(bp)) + break; + pageno = bp[bp[0] - 1]; + rbufp->flags |= BUF_MOD; + rbufp = __get_buf(hashp, pageno, rbufp, 0); + if (last_bfp) + __free_ovflpage(hashp, last_bfp); + last_bfp = rbufp; + if (!rbufp) + return (-1); /* Error. */ + bp = (u_int16_t *)rbufp->page; + } + + /* + * If we get here then rbufp points to the last page of the big + * key/data pair. Bufp points to the first one -- it should now be + * empty pointing to the next page after this pair. Can't free it + * because we don't have the page pointing to it. + */ + + /* This is information from the last page of the pair. */ + n = bp[0]; + pageno = bp[n - 1]; + + /* Now, bp is the first page of the pair. */ + bp = (u_int16_t *)bufp->page; + if (n > 2) { + /* There is an overflow page. */ + bp[1] = pageno; + bp[2] = OVFLPAGE; + bufp->ovfl = rbufp->ovfl; + } else + /* This is the last page. */ + bufp->ovfl = NULL; + n -= 2; + bp[0] = n; + FREESPACE(bp) = hashp->BSIZE - PAGE_META(n); + OFFSET(bp) = hashp->BSIZE - 1; + + bufp->flags |= BUF_MOD; + if (rbufp) + __free_ovflpage(hashp, rbufp); + if (last_bfp != rbufp) + __free_ovflpage(hashp, last_bfp); + + hashp->NKEYS--; + return (0); +} +/* + * Returns: + * 0 = key not found + * -1 = get next overflow page + * -2 means key not found and this is big key/data + * -3 error + */ +extern int +__find_bigpair(hashp, bufp, ndx, key, size) + HTAB *hashp; + BUFHEAD *bufp; + int ndx; + char *key; + int size; +{ + register u_int16_t *bp; + register char *p; + int ksize; + u_int16_t bytes; + char *kkey; + + bp = (u_int16_t *)bufp->page; + p = bufp->page; + ksize = size; + kkey = key; + + for (bytes = hashp->BSIZE - bp[ndx]; + bytes <= size && bp[ndx + 1] == PARTIAL_KEY; + bytes = hashp->BSIZE - bp[ndx]) { + if (memcmp(p + bp[ndx], kkey, bytes)) + return (-2); + kkey += bytes; + ksize -= bytes; + bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0); + if (!bufp) + return (-3); + p = bufp->page; + bp = (u_int16_t *)p; + ndx = 1; + } + + if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) { +#ifdef HASH_STATISTICS + ++hash_collisions; +#endif + return (-2); + } else + return (ndx); +} + +/* + * Given the buffer pointer of the first overflow page of a big pair, + * find the end of the big pair + * + * This will set bpp to the buffer header of the last page of the big pair. + * It will return the pageno of the overflow page following the last page + * of the pair; 0 if there isn't any (i.e. big pair is the last key in the + * bucket) + */ +extern u_int16_t +__find_last_page(hashp, bpp) + HTAB *hashp; + BUFHEAD **bpp; +{ + BUFHEAD *bufp; + u_int16_t *bp, pageno; + int n; + + bufp = *bpp; + bp = (u_int16_t *)bufp->page; + for (;;) { + n = bp[0]; + + /* + * This is the last page if: the tag is FULL_KEY_DATA and + * either only 2 entries OVFLPAGE marker is explicit there + * is freespace on the page. + */ + if (bp[2] == FULL_KEY_DATA && + ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp)))) + break; + + pageno = bp[n - 1]; + bufp = __get_buf(hashp, pageno, bufp, 0); + if (!bufp) + return (0); /* Need to indicate an error! */ + bp = (u_int16_t *)bufp->page; + } + + *bpp = bufp; + if (bp[0] > 2) + return (bp[3]); + else + return (0); +} + +/* + * Return the data for the key/data pair that begins on this page at this + * index (index should always be 1). + */ +extern int +__big_return(hashp, bufp, ndx, val, set_current) + HTAB *hashp; + BUFHEAD *bufp; + int ndx; + DBT *val; + int set_current; +{ + BUFHEAD *save_p; + u_int16_t *bp, len, off, save_addr; + char *tp; + + bp = (u_int16_t *)bufp->page; + while (bp[ndx + 1] == PARTIAL_KEY) { + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + ndx = 1; + } + + if (bp[ndx + 1] == FULL_KEY) { + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + save_p = bufp; + save_addr = save_p->addr; + off = bp[1]; + len = 0; + } else + if (!FREESPACE(bp)) { + /* + * This is a hack. We can't distinguish between + * FULL_KEY_DATA that contains complete data or + * incomplete data, so we require that if the data + * is complete, there is at least 1 byte of free + * space left. + */ + off = bp[bp[0]]; + len = bp[1] - off; + save_p = bufp; + save_addr = bufp->addr; + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + } else { + /* The data is all on one page. */ + tp = (char *)bp; + off = bp[bp[0]]; + val->data = (u_char *)tp + off; + val->size = bp[1] - off; + if (set_current) { + if (bp[0] == 2) { /* No more buckets in + * chain */ + hashp->cpage = NULL; + hashp->cbucket++; + hashp->cndx = 1; + } else { + hashp->cpage = __get_buf(hashp, + bp[bp[0] - 1], bufp, 0); + if (!hashp->cpage) + return (-1); + hashp->cndx = 1; + if (!((u_int16_t *) + hashp->cpage->page)[0]) { + hashp->cbucket++; + hashp->cpage = NULL; + } + } + } + return (0); + } + + val->size = collect_data(hashp, bufp, (int)len, set_current); + if (val->size == -1) + return (-1); + if (save_p->addr != save_addr) { + /* We are pretty short on buffers. */ + errno = EINVAL; /* OUT OF BUFFERS */ + return (-1); + } + memmove(hashp->tmp_buf, (save_p->page) + off, len); + val->data = (u_char *)hashp->tmp_buf; + return (0); +} +/* + * Count how big the total datasize is by recursing through the pages. Then + * allocate a buffer and copy the data as you recurse up. + */ +static int +collect_data(hashp, bufp, len, set) + HTAB *hashp; + BUFHEAD *bufp; + int len, set; +{ + register u_int16_t *bp; + register char *p; + BUFHEAD *xbp; + u_int16_t save_addr; + int mylen, totlen; + + p = bufp->page; + bp = (u_int16_t *)p; + mylen = hashp->BSIZE - bp[1]; + save_addr = bufp->addr; + + if (bp[2] == FULL_KEY_DATA) { /* End of Data */ + totlen = len + mylen; + if (hashp->tmp_buf) + free(hashp->tmp_buf); + if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL) + return (-1); + if (set) { + hashp->cndx = 1; + if (bp[0] == 2) { /* No more buckets in chain */ + hashp->cpage = NULL; + hashp->cbucket++; + } else { + hashp->cpage = + __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!hashp->cpage) + return (-1); + else if (!((u_int16_t *)hashp->cpage->page)[0]) { + hashp->cbucket++; + hashp->cpage = NULL; + } + } + } + } else { + xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!xbp || ((totlen = + collect_data(hashp, xbp, len + mylen, set)) < 1)) + return (-1); + } + if (bufp->addr != save_addr) { + errno = EINVAL; /* Out of buffers. */ + return (-1); + } + memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen); + return (totlen); +} + +/* + * Fill in the key and data for this big pair. + */ +extern int +__big_keydata(hashp, bufp, key, val, set) + HTAB *hashp; + BUFHEAD *bufp; + DBT *key, *val; + int set; +{ + key->size = collect_key(hashp, bufp, 0, val, set); + if (key->size == -1) + return (-1); + key->data = (u_char *)hashp->tmp_key; + return (0); +} + +/* + * Count how big the total key size is by recursing through the pages. Then + * collect the data, allocate a buffer and copy the key as you recurse up. + */ +static int +collect_key(hashp, bufp, len, val, set) + HTAB *hashp; + BUFHEAD *bufp; + int len; + DBT *val; + int set; +{ + BUFHEAD *xbp; + char *p; + int mylen, totlen; + u_int16_t *bp, save_addr; + + p = bufp->page; + bp = (u_int16_t *)p; + mylen = hashp->BSIZE - bp[1]; + + save_addr = bufp->addr; + totlen = len + mylen; + if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */ + if (hashp->tmp_key != NULL) + free(hashp->tmp_key); + if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL) + return (-1); + if (__big_return(hashp, bufp, 1, val, set)) + return (-1); + } else { + xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!xbp || ((totlen = + collect_key(hashp, xbp, totlen, val, set)) < 1)) + return (-1); + } + if (bufp->addr != save_addr) { + errno = EINVAL; /* MIS -- OUT OF BUFFERS */ + return (-1); + } + memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen); + return (totlen); +} + +/* + * Returns: + * 0 => OK + * -1 => error + */ +extern int +__big_split(hashp, op, np, big_keyp, addr, obucket, ret) + HTAB *hashp; + BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */ + BUFHEAD *np; /* Pointer to new bucket page */ + /* Pointer to first page containing the big key/data */ + BUFHEAD *big_keyp; + int addr; /* Address of big_keyp */ + u_int32_t obucket;/* Old Bucket */ + SPLIT_RETURN *ret; +{ + register BUFHEAD *tmpp; + register u_int16_t *tp; + BUFHEAD *bp; + DBT key, val; + u_int32_t change; + u_int16_t free_space, n, off; + + bp = big_keyp; + + /* Now figure out where the big key/data goes */ + if (__big_keydata(hashp, big_keyp, &key, &val, 0)) + return (-1); + change = (__call_hash(hashp, key.data, key.size) != obucket); + + if (ret->next_addr = __find_last_page(hashp, &big_keyp)) { + if (!(ret->nextp = + __get_buf(hashp, ret->next_addr, big_keyp, 0))) + return (-1);; + } else + ret->nextp = NULL; + + /* Now make one of np/op point to the big key/data pair */ +#ifdef DEBUG + assert(np->ovfl == NULL); +#endif + if (change) + tmpp = np; + else + tmpp = op; + + tmpp->flags |= BUF_MOD; +#ifdef DEBUG1 + (void)fprintf(stderr, + "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr, + (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0)); +#endif + tmpp->ovfl = bp; /* one of op/np point to big_keyp */ + tp = (u_int16_t *)tmpp->page; +#ifdef DEBUG + assert(FREESPACE(tp) >= OVFLSIZE); +#endif + n = tp[0]; + off = OFFSET(tp); + free_space = FREESPACE(tp); + tp[++n] = (u_int16_t)addr; + tp[++n] = OVFLPAGE; + tp[0] = n; + OFFSET(tp) = off; + FREESPACE(tp) = free_space - OVFLSIZE; + + /* + * Finally, set the new and old return values. BIG_KEYP contains a + * pointer to the last page of the big key_data pair. Make sure that + * big_keyp has no following page (2 elements) or create an empty + * following page. + */ + + ret->newp = np; + ret->oldp = op; + + tp = (u_int16_t *)big_keyp->page; + big_keyp->flags |= BUF_MOD; + if (tp[0] > 2) { + /* + * There may be either one or two offsets on this page. If + * there is one, then the overflow page is linked on normally + * and tp[4] is OVFLPAGE. If there are two, tp[4] contains + * the second offset and needs to get stuffed in after the + * next overflow page is added. + */ + n = tp[4]; + free_space = FREESPACE(tp); + off = OFFSET(tp); + tp[0] -= 2; + FREESPACE(tp) = free_space + OVFLSIZE; + OFFSET(tp) = off; + tmpp = __add_ovflpage(hashp, big_keyp); + if (!tmpp) + return (-1); + tp[4] = n; + } else + tmpp = big_keyp; + + if (change) + ret->newp = tmpp; + else + ret->oldp = tmpp; + return (0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/hash_buf.c b/circuitpython/lib/berkeley-db-1.xx/hash/hash_buf.c new file mode 100644 index 0000000..92e1f93 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/hash_buf.c @@ -0,0 +1,355 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94"; +#endif /* LIBC_SCCS and not lint */ + +/* + * PACKAGE: hash + * + * DESCRIPTION: + * Contains buffer management + * + * ROUTINES: + * External + * __buf_init + * __get_buf + * __buf_free + * __reclaim_buf + * Internal + * newbuf + */ + +#include + +#include +#include +#include +#include + +#ifdef DEBUG +#include +#endif + +#include +#include "hash.h" +#include "page.h" +#include "extern.h" + +static BUFHEAD *newbuf __P((HTAB *, u_int32_t, BUFHEAD *)); + +/* Unlink B from its place in the lru */ +#define BUF_REMOVE(B) { \ + (B)->prev->next = (B)->next; \ + (B)->next->prev = (B)->prev; \ +} + +/* Insert B after P */ +#define BUF_INSERT(B, P) { \ + (B)->next = (P)->next; \ + (B)->prev = (P); \ + (P)->next = (B); \ + (B)->next->prev = (B); \ +} + +#define MRU hashp->bufhead.next +#define LRU hashp->bufhead.prev + +#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead) +#define LRU_INSERT(B) BUF_INSERT((B), LRU) + +/* + * We are looking for a buffer with address "addr". If prev_bp is NULL, then + * address is a bucket index. If prev_bp is not NULL, then it points to the + * page previous to an overflow page that we are trying to find. + * + * CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer + * be valid. Therefore, you must always verify that its address matches the + * address you are seeking. + */ +extern BUFHEAD * +__get_buf(hashp, addr, prev_bp, newpage) + HTAB *hashp; + u_int32_t addr; + BUFHEAD *prev_bp; + int newpage; /* If prev_bp set, indicates a new overflow page. */ +{ + register BUFHEAD *bp; + register u_int32_t is_disk_mask; + register int is_disk, segment_ndx; + SEGMENT segp; + + is_disk = 0; + is_disk_mask = 0; + if (prev_bp) { + bp = prev_bp->ovfl; + if (!bp || (bp->addr != addr)) + bp = NULL; + if (!newpage) + is_disk = BUF_DISK; + } else { + /* Grab buffer out of directory */ + segment_ndx = addr & (hashp->SGSIZE - 1); + + /* valid segment ensured by __call_hash() */ + segp = hashp->dir[addr >> hashp->SSHIFT]; +#ifdef DEBUG + assert(segp != NULL); +#endif + bp = PTROF(segp[segment_ndx]); + is_disk_mask = ISDISK(segp[segment_ndx]); + is_disk = is_disk_mask || !hashp->new_file; + } + + if (!bp) { + bp = newbuf(hashp, addr, prev_bp); + if (!bp || + __get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0)) + return (NULL); + if (!prev_bp) + segp[segment_ndx] = + (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask); + } else { + BUF_REMOVE(bp); + MRU_INSERT(bp); + } + return (bp); +} + +/* + * We need a buffer for this page. Either allocate one, or evict a resident + * one (if we have as many buffers as we're allowed) and put this one in. + * + * If newbuf finds an error (returning NULL), it also sets errno. + */ +static BUFHEAD * +newbuf(hashp, addr, prev_bp) + HTAB *hashp; + u_int32_t addr; + BUFHEAD *prev_bp; +{ + register BUFHEAD *bp; /* The buffer we're going to use */ + register BUFHEAD *xbp; /* Temp pointer */ + register BUFHEAD *next_xbp; + SEGMENT segp; + int segment_ndx; + u_int16_t oaddr, *shortp; + + oaddr = 0; + bp = LRU; + /* + * If LRU buffer is pinned, the buffer pool is too small. We need to + * allocate more buffers. + */ + if (hashp->nbufs || (bp->flags & BUF_PIN)) { + /* Allocate a new one */ + if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL) + return (NULL); +#ifdef PURIFY + memset(bp, 0xff, sizeof(BUFHEAD)); +#endif + if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) { + free(bp); + return (NULL); + } +#ifdef PURIFY + memset(bp->page, 0xff, hashp->BSIZE); +#endif + if (hashp->nbufs) + hashp->nbufs--; + } else { + /* Kick someone out */ + BUF_REMOVE(bp); + /* + * If this is an overflow page with addr 0, it's already been + * flushed back in an overflow chain and initialized. + */ + if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) { + /* + * Set oaddr before __put_page so that you get it + * before bytes are swapped. + */ + shortp = (u_int16_t *)bp->page; + if (shortp[0]) + oaddr = shortp[shortp[0] - 1]; + if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page, + bp->addr, (int)IS_BUCKET(bp->flags), 0)) + return (NULL); + /* + * Update the pointer to this page (i.e. invalidate it). + * + * If this is a new file (i.e. we created it at open + * time), make sure that we mark pages which have been + * written to disk so we retrieve them from disk later, + * rather than allocating new pages. + */ + if (IS_BUCKET(bp->flags)) { + segment_ndx = bp->addr & (hashp->SGSIZE - 1); + segp = hashp->dir[bp->addr >> hashp->SSHIFT]; +#ifdef DEBUG + assert(segp != NULL); +#endif + + if (hashp->new_file && + ((bp->flags & BUF_MOD) || + ISDISK(segp[segment_ndx]))) + segp[segment_ndx] = (BUFHEAD *)BUF_DISK; + else + segp[segment_ndx] = NULL; + } + /* + * Since overflow pages can only be access by means of + * their bucket, free overflow pages associated with + * this bucket. + */ + for (xbp = bp; xbp->ovfl;) { + next_xbp = xbp->ovfl; + xbp->ovfl = 0; + xbp = next_xbp; + + /* Check that ovfl pointer is up date. */ + if (IS_BUCKET(xbp->flags) || + (oaddr != xbp->addr)) + break; + + shortp = (u_int16_t *)xbp->page; + if (shortp[0]) + /* set before __put_page */ + oaddr = shortp[shortp[0] - 1]; + if ((xbp->flags & BUF_MOD) && __put_page(hashp, + xbp->page, xbp->addr, 0, 0)) + return (NULL); + xbp->addr = 0; + xbp->flags = 0; + BUF_REMOVE(xbp); + LRU_INSERT(xbp); + } + } + } + + /* Now assign this buffer */ + bp->addr = addr; +#ifdef DEBUG1 + (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n", + bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0); +#endif + bp->ovfl = NULL; + if (prev_bp) { + /* + * If prev_bp is set, this is an overflow page, hook it in to + * the buffer overflow links. + */ +#ifdef DEBUG1 + (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n", + prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0), + (bp ? bp->addr : 0)); +#endif + prev_bp->ovfl = bp; + bp->flags = 0; + } else + bp->flags = BUF_BUCKET; + MRU_INSERT(bp); + return (bp); +} + +extern void +__buf_init(hashp, nbytes) + HTAB *hashp; + int nbytes; +{ + BUFHEAD *bfp; + int npages; + + bfp = &(hashp->bufhead); + npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT; + npages = MAX(npages, MIN_BUFFERS); + + hashp->nbufs = npages; + bfp->next = bfp; + bfp->prev = bfp; + /* + * This space is calloc'd so these are already null. + * + * bfp->ovfl = NULL; + * bfp->flags = 0; + * bfp->page = NULL; + * bfp->addr = 0; + */ +} + +extern int +__buf_free(hashp, do_free, to_disk) + HTAB *hashp; + int do_free, to_disk; +{ + BUFHEAD *bp; + + /* Need to make sure that buffer manager has been initialized */ + if (!LRU) + return (0); + for (bp = LRU; bp != &hashp->bufhead;) { + /* Check that the buffer is valid */ + if (bp->addr || IS_BUCKET(bp->flags)) { + if (to_disk && (bp->flags & BUF_MOD) && + __put_page(hashp, bp->page, + bp->addr, IS_BUCKET(bp->flags), 0)) + return (-1); + } + /* Check if we are freeing stuff */ + if (do_free) { + if (bp->page) + free(bp->page); + BUF_REMOVE(bp); + free(bp); + bp = LRU; + } else + bp = bp->prev; + } + return (0); +} + +extern void +__reclaim_buf(hashp, bp) + HTAB *hashp; + BUFHEAD *bp; +{ + bp->ovfl = 0; + bp->addr = 0; + bp->flags = 0; + BUF_REMOVE(bp); + LRU_INSERT(bp); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/hash_func.c b/circuitpython/lib/berkeley-db-1.xx/hash/hash_func.c new file mode 100644 index 0000000..a5ec434 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/hash_func.c @@ -0,0 +1,212 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include "hash.h" +#include "page.h" +#include "extern.h" + +static u_int32_t hash1 __P((const void *, size_t)); +static u_int32_t hash2 __P((const void *, size_t)); +static u_int32_t hash3 __P((const void *, size_t)); +static u_int32_t hash4 __P((const void *, size_t)); + +/* Global default hash function */ +u_int32_t (*__default_hash) __P((const void *, size_t)) = hash4; + +/* + * HASH FUNCTIONS + * + * Assume that we've already split the bucket to which this key hashes, + * calculate that bucket, and check that in fact we did already split it. + * + * This came from ejb's hsearch. + */ + +#define PRIME1 37 +#define PRIME2 1048583 + +static u_int32_t +hash1(keyarg, len) + const void *keyarg; + register size_t len; +{ + register const u_char *key; + register u_int32_t h; + + /* Convert string to integer */ + for (key = keyarg, h = 0; len--;) + h = h * PRIME1 ^ (*key++ - ' '); + h %= PRIME2; + return (h); +} + +/* + * Phong's linear congruential hash + */ +#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) + +static u_int32_t +hash2(keyarg, len) + const void *keyarg; + size_t len; +{ + register const u_char *e, *key; + register u_int32_t h; + register u_char c; + + key = keyarg; + e = key + len; + for (h = 0; key != e;) { + c = *key++; + if (!c && key > e) + break; + dcharhash(h, c); + } + return (h); +} + +/* + * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte + * units. On the first time through the loop we get the "leftover bytes" + * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle + * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If + * this routine is heavily used enough, it's worth the ugly coding. + * + * OZ's original sdbm hash + */ +static u_int32_t +hash3(keyarg, len) + const void *keyarg; + register size_t len; +{ + register const u_char *key; + register size_t loop; + register u_int32_t h; + +#define HASHC h = *key++ + 65599 * h + + h = 0; + key = keyarg; + if (len > 0) { + loop = (len + 8 - 1) >> 3; + + switch (len & (8 - 1)) { + case 0: + do { + HASHC; + /* FALLTHROUGH */ + case 7: + HASHC; + /* FALLTHROUGH */ + case 6: + HASHC; + /* FALLTHROUGH */ + case 5: + HASHC; + /* FALLTHROUGH */ + case 4: + HASHC; + /* FALLTHROUGH */ + case 3: + HASHC; + /* FALLTHROUGH */ + case 2: + HASHC; + /* FALLTHROUGH */ + case 1: + HASHC; + } while (--loop); + } + } + return (h); +} + +/* Hash function from Chris Torek. */ +static u_int32_t +hash4(keyarg, len) + const void *keyarg; + register size_t len; +{ + register const u_char *key; + register size_t loop; + register u_int32_t h; + +#define HASH4a h = (h << 5) - h + *key++; +#define HASH4b h = (h << 5) + h + *key++; +#define HASH4 HASH4b + + h = 0; + key = keyarg; + if (len > 0) { + loop = (len + 8 - 1) >> 3; + + switch (len & (8 - 1)) { + case 0: + do { + HASH4; + /* FALLTHROUGH */ + case 7: + HASH4; + /* FALLTHROUGH */ + case 6: + HASH4; + /* FALLTHROUGH */ + case 5: + HASH4; + /* FALLTHROUGH */ + case 4: + HASH4; + /* FALLTHROUGH */ + case 3: + HASH4; + /* FALLTHROUGH */ + case 2: + HASH4; + /* FALLTHROUGH */ + case 1: + HASH4; + } while (--loop); + } + } + return (h); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/hash_log2.c b/circuitpython/lib/berkeley-db-1.xx/hash/hash_log2.c new file mode 100644 index 0000000..c8c56bf --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/hash_log2.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include + +u_int32_t +__log2(num) + u_int32_t num; +{ + register u_int32_t i, limit; + + limit = 1; + for (i = 0; limit < num; limit = limit << 1, i++); + return (i); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/hash_page.c b/circuitpython/lib/berkeley-db-1.xx/hash/hash_page.c new file mode 100644 index 0000000..e1dfe6b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/hash_page.c @@ -0,0 +1,944 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94"; +#endif /* LIBC_SCCS and not lint */ + +/* + * PACKAGE: hashing + * + * DESCRIPTION: + * Page manipulation for hashing package. + * + * ROUTINES: + * + * External + * __get_page + * __add_ovflpage + * Internal + * overflow_page + * open_temp + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif + +#include +#include "hash.h" +#include "page.h" +#include "extern.h" + +static u_int32_t *fetch_bitmap __P((HTAB *, int)); +static u_int32_t first_free __P((u_int32_t)); +static int open_temp __P((HTAB *)); +static u_int16_t overflow_page __P((HTAB *)); +static void putpair __P((char *, const DBT *, const DBT *)); +static void squeeze_key __P((u_int16_t *, const DBT *, const DBT *)); +static int ugly_split + __P((HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int)); + +#define PAGE_INIT(P) { \ + ((u_int16_t *)(P))[0] = 0; \ + ((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \ + ((u_int16_t *)(P))[2] = hashp->BSIZE; \ +} + +/* + * This is called AFTER we have verified that there is room on the page for + * the pair (PAIRFITS has returned true) so we go right ahead and start moving + * stuff on. + */ +static void +putpair(p, key, val) + char *p; + const DBT *key, *val; +{ + register u_int16_t *bp, n, off; + + bp = (u_int16_t *)p; + + /* Enter the key first. */ + n = bp[0]; + + off = OFFSET(bp) - key->size; + memmove(p + off, key->data, key->size); + bp[++n] = off; + + /* Now the data. */ + off -= val->size; + memmove(p + off, val->data, val->size); + bp[++n] = off; + + /* Adjust page info. */ + bp[0] = n; + bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t)); + bp[n + 2] = off; +} + +/* + * Returns: + * 0 OK + * -1 error + */ +extern int +__delpair(hashp, bufp, ndx) + HTAB *hashp; + BUFHEAD *bufp; + register int ndx; +{ + register u_int16_t *bp, newoff; + register int n; + u_int16_t pairlen; + + bp = (u_int16_t *)bufp->page; + n = bp[0]; + + if (bp[ndx + 1] < REAL_KEY) + return (__big_delete(hashp, bufp)); + if (ndx != 1) + newoff = bp[ndx - 1]; + else + newoff = hashp->BSIZE; + pairlen = newoff - bp[ndx + 1]; + + if (ndx != (n - 1)) { + /* Hard Case -- need to shuffle keys */ + register int i; + register char *src = bufp->page + (int)OFFSET(bp); + register char *dst = src + (int)pairlen; + memmove(dst, src, bp[ndx + 1] - OFFSET(bp)); + + /* Now adjust the pointers */ + for (i = ndx + 2; i <= n; i += 2) { + if (bp[i + 1] == OVFLPAGE) { + bp[i - 2] = bp[i]; + bp[i - 1] = bp[i + 1]; + } else { + bp[i - 2] = bp[i] + pairlen; + bp[i - 1] = bp[i + 1] + pairlen; + } + } + } + /* Finally adjust the page data */ + bp[n] = OFFSET(bp) + pairlen; + bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t); + bp[0] = n - 2; + hashp->NKEYS--; + + bufp->flags |= BUF_MOD; + return (0); +} +/* + * Returns: + * 0 ==> OK + * -1 ==> Error + */ +extern int +__split_page(hashp, obucket, nbucket) + HTAB *hashp; + u_int32_t obucket, nbucket; +{ + register BUFHEAD *new_bufp, *old_bufp; + register u_int16_t *ino; + register char *np; + DBT key, val; + int n, ndx, retval; + u_int16_t copyto, diff, off, moved; + char *op; + + copyto = (u_int16_t)hashp->BSIZE; + off = (u_int16_t)hashp->BSIZE; + old_bufp = __get_buf(hashp, obucket, NULL, 0); + if (old_bufp == NULL) + return (-1); + new_bufp = __get_buf(hashp, nbucket, NULL, 0); + if (new_bufp == NULL) + return (-1); + + old_bufp->flags |= (BUF_MOD | BUF_PIN); + new_bufp->flags |= (BUF_MOD | BUF_PIN); + + ino = (u_int16_t *)(op = old_bufp->page); + np = new_bufp->page; + + moved = 0; + + for (n = 1, ndx = 1; n < ino[0]; n += 2) { + if (ino[n + 1] < REAL_KEY) { + retval = ugly_split(hashp, obucket, old_bufp, new_bufp, + (int)copyto, (int)moved); + old_bufp->flags &= ~BUF_PIN; + new_bufp->flags &= ~BUF_PIN; + return (retval); + + } + key.data = (u_char *)op + ino[n]; + key.size = off - ino[n]; + + if (__call_hash(hashp, key.data, key.size) == obucket) { + /* Don't switch page */ + diff = copyto - off; + if (diff) { + copyto = ino[n + 1] + diff; + memmove(op + copyto, op + ino[n + 1], + off - ino[n + 1]); + ino[ndx] = copyto + ino[n] - ino[n + 1]; + ino[ndx + 1] = copyto; + } else + copyto = ino[n + 1]; + ndx += 2; + } else { + /* Switch page */ + val.data = (u_char *)op + ino[n + 1]; + val.size = ino[n] - ino[n + 1]; + putpair(np, &key, &val); + moved += 2; + } + + off = ino[n + 1]; + } + + /* Now clean up the page */ + ino[0] -= moved; + FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3); + OFFSET(ino) = copyto; + +#ifdef DEBUG3 + (void)fprintf(stderr, "split %d/%d\n", + ((u_int16_t *)np)[0] / 2, + ((u_int16_t *)op)[0] / 2); +#endif + /* unpin both pages */ + old_bufp->flags &= ~BUF_PIN; + new_bufp->flags &= ~BUF_PIN; + return (0); +} + +/* + * Called when we encounter an overflow or big key/data page during split + * handling. This is special cased since we have to begin checking whether + * the key/data pairs fit on their respective pages and because we may need + * overflow pages for both the old and new pages. + * + * The first page might be a page with regular key/data pairs in which case + * we have a regular overflow condition and just need to go on to the next + * page or it might be a big key/data pair in which case we need to fix the + * big key/data pair. + * + * Returns: + * 0 ==> success + * -1 ==> failure + */ +static int +ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) + HTAB *hashp; + u_int32_t obucket; /* Same as __split_page. */ + BUFHEAD *old_bufp, *new_bufp; + int copyto; /* First byte on page which contains key/data values. */ + int moved; /* Number of pairs moved to new page. */ +{ + register BUFHEAD *bufp; /* Buffer header for ino */ + register u_int16_t *ino; /* Page keys come off of */ + register u_int16_t *np; /* New page */ + register u_int16_t *op; /* Page keys go on to if they aren't moving */ + + BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */ + DBT key, val; + SPLIT_RETURN ret; + u_int16_t n, off, ov_addr, scopyto; + char *cino; /* Character value of ino */ + + bufp = old_bufp; + ino = (u_int16_t *)old_bufp->page; + np = (u_int16_t *)new_bufp->page; + op = (u_int16_t *)old_bufp->page; + last_bfp = NULL; + scopyto = (u_int16_t)copyto; /* ANSI */ + + n = ino[0] - 1; + while (n < ino[0]) { + if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) { + if (__big_split(hashp, old_bufp, + new_bufp, bufp, bufp->addr, obucket, &ret)) + return (-1); + old_bufp = ret.oldp; + if (!old_bufp) + return (-1); + op = (u_int16_t *)old_bufp->page; + new_bufp = ret.newp; + if (!new_bufp) + return (-1); + np = (u_int16_t *)new_bufp->page; + bufp = ret.nextp; + if (!bufp) + return (0); + cino = (char *)bufp->page; + ino = (u_int16_t *)cino; + last_bfp = ret.nextp; + } else if (ino[n + 1] == OVFLPAGE) { + ov_addr = ino[n]; + /* + * Fix up the old page -- the extra 2 are the fields + * which contained the overflow information. + */ + ino[0] -= (moved + 2); + FREESPACE(ino) = + scopyto - sizeof(u_int16_t) * (ino[0] + 3); + OFFSET(ino) = scopyto; + + bufp = __get_buf(hashp, ov_addr, bufp, 0); + if (!bufp) + return (-1); + + ino = (u_int16_t *)bufp->page; + n = 1; + scopyto = hashp->BSIZE; + moved = 0; + + if (last_bfp) + __free_ovflpage(hashp, last_bfp); + last_bfp = bufp; + } + /* Move regular sized pairs of there are any */ + off = hashp->BSIZE; + for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) { + cino = (char *)ino; + key.data = (u_char *)cino + ino[n]; + key.size = off - ino[n]; + val.data = (u_char *)cino + ino[n + 1]; + val.size = ino[n] - ino[n + 1]; + off = ino[n + 1]; + + if (__call_hash(hashp, key.data, key.size) == obucket) { + /* Keep on old page */ + if (PAIRFITS(op, (&key), (&val))) + putpair((char *)op, &key, &val); + else { + old_bufp = + __add_ovflpage(hashp, old_bufp); + if (!old_bufp) + return (-1); + op = (u_int16_t *)old_bufp->page; + putpair((char *)op, &key, &val); + } + old_bufp->flags |= BUF_MOD; + } else { + /* Move to new page */ + if (PAIRFITS(np, (&key), (&val))) + putpair((char *)np, &key, &val); + else { + new_bufp = + __add_ovflpage(hashp, new_bufp); + if (!new_bufp) + return (-1); + np = (u_int16_t *)new_bufp->page; + putpair((char *)np, &key, &val); + } + new_bufp->flags |= BUF_MOD; + } + } + } + if (last_bfp) + __free_ovflpage(hashp, last_bfp); + return (0); +} + +/* + * Add the given pair to the page + * + * Returns: + * 0 ==> OK + * 1 ==> failure + */ +extern int +__addel(hashp, bufp, key, val) + HTAB *hashp; + BUFHEAD *bufp; + const DBT *key, *val; +{ + register u_int16_t *bp, *sop; + int do_expand; + + bp = (u_int16_t *)bufp->page; + do_expand = 0; + while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY)) + /* Exception case */ + if (bp[2] == FULL_KEY_DATA && bp[0] == 2) + /* This is the last page of a big key/data pair + and we need to add another page */ + break; + else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) { + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + } else + /* Try to squeeze key on this page */ + if (FREESPACE(bp) > PAIRSIZE(key, val)) { + squeeze_key(bp, key, val); + return (0); + } else { + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + } + + if (PAIRFITS(bp, key, val)) + putpair(bufp->page, key, val); + else { + do_expand = 1; + bufp = __add_ovflpage(hashp, bufp); + if (!bufp) + return (-1); + sop = (u_int16_t *)bufp->page; + + if (PAIRFITS(sop, key, val)) + putpair((char *)sop, key, val); + else + if (__big_insert(hashp, bufp, key, val)) + return (-1); + } + bufp->flags |= BUF_MOD; + /* + * If the average number of keys per bucket exceeds the fill factor, + * expand the table. + */ + hashp->NKEYS++; + if (do_expand || + (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR)) + return (__expand_table(hashp)); + return (0); +} + +/* + * + * Returns: + * pointer on success + * NULL on error + */ +extern BUFHEAD * +__add_ovflpage(hashp, bufp) + HTAB *hashp; + BUFHEAD *bufp; +{ + register u_int16_t *sp; + u_int16_t ndx, ovfl_num; +#ifdef DEBUG1 + int tmp1, tmp2; +#endif + sp = (u_int16_t *)bufp->page; + + /* Check if we are dynamically determining the fill factor */ + if (hashp->FFACTOR == DEF_FFACTOR) { + hashp->FFACTOR = sp[0] >> 1; + if (hashp->FFACTOR < MIN_FFACTOR) + hashp->FFACTOR = MIN_FFACTOR; + } + bufp->flags |= BUF_MOD; + ovfl_num = overflow_page(hashp); +#ifdef DEBUG1 + tmp1 = bufp->addr; + tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0; +#endif + if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1))) + return (NULL); + bufp->ovfl->flags |= BUF_MOD; +#ifdef DEBUG1 + (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n", + tmp1, tmp2, bufp->ovfl->addr); +#endif + ndx = sp[0]; + /* + * Since a pair is allocated on a page only if there's room to add + * an overflow page, we know that the OVFL information will fit on + * the page. + */ + sp[ndx + 4] = OFFSET(sp); + sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE; + sp[ndx + 1] = ovfl_num; + sp[ndx + 2] = OVFLPAGE; + sp[0] = ndx + 2; +#ifdef HASH_STATISTICS + hash_overflows++; +#endif + return (bufp->ovfl); +} + +/* + * Returns: + * 0 indicates SUCCESS + * -1 indicates FAILURE + */ +extern int +__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) + HTAB *hashp; + char *p; + u_int32_t bucket; + int is_bucket, is_disk, is_bitmap; +{ + register int fd, page, size; + int rsize; + u_int16_t *bp; + + fd = hashp->fp; + size = hashp->BSIZE; + + if ((fd == -1) || !is_disk) { + PAGE_INIT(p); + return (0); + } + if (is_bucket) + page = BUCKET_TO_PAGE(bucket); + else + page = OADDR_TO_PAGE(bucket); + if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) || + ((rsize = read(fd, p, size)) == -1)) + return (-1); + bp = (u_int16_t *)p; + if (!rsize) + bp[0] = 0; /* We hit the EOF, so initialize a new page */ + else + if (rsize != size) { + errno = EFTYPE; + return (-1); + } + if (!is_bitmap && !bp[0]) { + PAGE_INIT(p); + } else + if (hashp->LORDER != BYTE_ORDER) { + register int i, max; + + if (is_bitmap) { + max = hashp->BSIZE >> 2; /* divide by 4 */ + for (i = 0; i < max; i++) + M_32_SWAP(((int *)p)[i]); + } else { + M_16_SWAP(bp[0]); + max = bp[0] + 2; + for (i = 1; i <= max; i++) + M_16_SWAP(bp[i]); + } + } + return (0); +} + +/* + * Write page p to disk + * + * Returns: + * 0 ==> OK + * -1 ==>failure + */ +extern int +__put_page(hashp, p, bucket, is_bucket, is_bitmap) + HTAB *hashp; + char *p; + u_int32_t bucket; + int is_bucket, is_bitmap; +{ + register int fd, page, size; + int wsize; + + size = hashp->BSIZE; + if ((hashp->fp == -1) && open_temp(hashp)) + return (-1); + fd = hashp->fp; + + if (hashp->LORDER != BYTE_ORDER) { + register int i; + register int max; + + if (is_bitmap) { + max = hashp->BSIZE >> 2; /* divide by 4 */ + for (i = 0; i < max; i++) + M_32_SWAP(((int *)p)[i]); + } else { + max = ((u_int16_t *)p)[0] + 2; + for (i = 0; i <= max; i++) + M_16_SWAP(((u_int16_t *)p)[i]); + } + } + if (is_bucket) + page = BUCKET_TO_PAGE(bucket); + else + page = OADDR_TO_PAGE(bucket); + if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) || + ((wsize = write(fd, p, size)) == -1)) + /* Errno is set */ + return (-1); + if (wsize != size) { + errno = EFTYPE; + return (-1); + } + return (0); +} + +#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1) +/* + * Initialize a new bitmap page. Bitmap pages are left in memory + * once they are read in. + */ +extern int +__ibitmap(hashp, pnum, nbits, ndx) + HTAB *hashp; + int pnum, nbits, ndx; +{ + u_int32_t *ip; + int clearbytes, clearints; + + if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL) + return (1); + hashp->nmaps++; + clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1; + clearbytes = clearints << INT_TO_BYTE; + (void)memset((char *)ip, 0, clearbytes); + (void)memset(((char *)ip) + clearbytes, 0xFF, + hashp->BSIZE - clearbytes); + ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK); + SETBIT(ip, 0); + hashp->BITMAPS[ndx] = (u_int16_t)pnum; + hashp->mapp[ndx] = ip; + return (0); +} + +static u_int32_t +first_free(map) + u_int32_t map; +{ + register u_int32_t i, mask; + + mask = 0x1; + for (i = 0; i < BITS_PER_MAP; i++) { + if (!(mask & map)) + return (i); + mask = mask << 1; + } + return (i); +} + +static u_int16_t +overflow_page(hashp) + HTAB *hashp; +{ + register u_int32_t *freep; + register int max_free, offset, splitnum; + u_int16_t addr; + int bit, first_page, free_bit, free_page, i, in_use_bits, j; +#ifdef DEBUG2 + int tmp1, tmp2; +#endif + splitnum = hashp->OVFL_POINT; + max_free = hashp->SPARES[splitnum]; + + free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT); + free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1); + + /* Look through all the free maps to find the first free block */ + first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT); + for ( i = first_page; i <= free_page; i++ ) { + if (!(freep = (u_int32_t *)hashp->mapp[i]) && + !(freep = fetch_bitmap(hashp, i))) + return (0); + if (i == free_page) + in_use_bits = free_bit; + else + in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1; + + if (i == first_page) { + bit = hashp->LAST_FREED & + ((hashp->BSIZE << BYTE_SHIFT) - 1); + j = bit / BITS_PER_MAP; + bit = bit & ~(BITS_PER_MAP - 1); + } else { + bit = 0; + j = 0; + } + for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP) + if (freep[j] != ALL_SET) + goto found; + } + + /* No Free Page Found */ + hashp->LAST_FREED = hashp->SPARES[splitnum]; + hashp->SPARES[splitnum]++; + offset = hashp->SPARES[splitnum] - + (splitnum ? hashp->SPARES[splitnum - 1] : 0); + +#define OVMSG "HASH: Out of overflow pages. Increase page size\n" + if (offset > SPLITMASK) { + if (++splitnum >= NCACHED) { + (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + return (0); + } + hashp->OVFL_POINT = splitnum; + hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; + hashp->SPARES[splitnum-1]--; + offset = 1; + } + + /* Check if we need to allocate a new bitmap page */ + if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) { + free_page++; + if (free_page >= NCACHED) { + (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + return (0); + } + /* + * This is tricky. The 1 indicates that you want the new page + * allocated with 1 clear bit. Actually, you are going to + * allocate 2 pages from this map. The first is going to be + * the map page, the second is the overflow page we were + * looking for. The init_bitmap routine automatically, sets + * the first bit of itself to indicate that the bitmap itself + * is in use. We would explicitly set the second bit, but + * don't have to if we tell init_bitmap not to leave it clear + * in the first place. + */ + if (__ibitmap(hashp, + (int)OADDR_OF(splitnum, offset), 1, free_page)) + return (0); + hashp->SPARES[splitnum]++; +#ifdef DEBUG2 + free_bit = 2; +#endif + offset++; + if (offset > SPLITMASK) { + if (++splitnum >= NCACHED) { + (void)write(STDERR_FILENO, OVMSG, + sizeof(OVMSG) - 1); + return (0); + } + hashp->OVFL_POINT = splitnum; + hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; + hashp->SPARES[splitnum-1]--; + offset = 0; + } + } else { + /* + * Free_bit addresses the last used bit. Bump it to address + * the first available bit. + */ + free_bit++; + SETBIT(freep, free_bit); + } + + /* Calculate address of the new overflow page */ + addr = OADDR_OF(splitnum, offset); +#ifdef DEBUG2 + (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n", + addr, free_bit, free_page); +#endif + return (addr); + +found: + bit = bit + first_free(freep[j]); + SETBIT(freep, bit); +#ifdef DEBUG2 + tmp1 = bit; + tmp2 = i; +#endif + /* + * Bits are addressed starting with 0, but overflow pages are addressed + * beginning at 1. Bit is a bit addressnumber, so we need to increment + * it to convert it to a page number. + */ + bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT)); + if (bit >= hashp->LAST_FREED) + hashp->LAST_FREED = bit - 1; + + /* Calculate the split number for this page */ + for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++); + offset = (i ? bit - hashp->SPARES[i - 1] : bit); + if (offset >= SPLITMASK) + return (0); /* Out of overflow pages */ + addr = OADDR_OF(i, offset); +#ifdef DEBUG2 + (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n", + addr, tmp1, tmp2); +#endif + + /* Allocate and return the overflow page */ + return (addr); +} + +/* + * Mark this overflow page as free. + */ +extern void +__free_ovflpage(hashp, obufp) + HTAB *hashp; + BUFHEAD *obufp; +{ + register u_int16_t addr; + u_int32_t *freep; + int bit_address, free_page, free_bit; + u_int16_t ndx; + + addr = obufp->addr; +#ifdef DEBUG1 + (void)fprintf(stderr, "Freeing %d\n", addr); +#endif + ndx = (((u_int16_t)addr) >> SPLITSHIFT); + bit_address = + (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1; + if (bit_address < hashp->LAST_FREED) + hashp->LAST_FREED = bit_address; + free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT)); + free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1); + + if (!(freep = hashp->mapp[free_page])) + freep = fetch_bitmap(hashp, free_page); +#ifdef DEBUG + /* + * This had better never happen. It means we tried to read a bitmap + * that has already had overflow pages allocated off it, and we + * failed to read it from the file. + */ + if (!freep) + assert(0); +#endif + CLRBIT(freep, free_bit); +#ifdef DEBUG2 + (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n", + obufp->addr, free_bit, free_page); +#endif + __reclaim_buf(hashp, obufp); +} + +/* + * Returns: + * 0 success + * -1 failure + */ +static int +open_temp(hashp) + HTAB *hashp; +{ + sigset_t set, oset; + static char namestr[] = "_hashXXXXXX"; + + /* Block signals; make sure file goes away at process exit. */ + (void)sigfillset(&set); + (void)sigprocmask(SIG_BLOCK, &set, &oset); + if ((hashp->fp = mkstemp(namestr)) != -1) { + (void)unlink(namestr); + (void)fcntl(hashp->fp, F_SETFD, 1); + } + (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); + return (hashp->fp != -1 ? 0 : -1); +} + +/* + * We have to know that the key will fit, but the last entry on the page is + * an overflow pair, so we need to shift things. + */ +static void +squeeze_key(sp, key, val) + u_int16_t *sp; + const DBT *key, *val; +{ + register char *p; + u_int16_t free_space, n, off, pageno; + + p = (char *)sp; + n = sp[0]; + free_space = FREESPACE(sp); + off = OFFSET(sp); + + pageno = sp[n - 1]; + off -= key->size; + sp[n - 1] = off; + memmove(p + off, key->data, key->size); + off -= val->size; + sp[n] = off; + memmove(p + off, val->data, val->size); + sp[0] = n + 2; + sp[n + 1] = pageno; + sp[n + 2] = OVFLPAGE; + FREESPACE(sp) = free_space - PAIRSIZE(key, val); + OFFSET(sp) = off; +} + +static u_int32_t * +fetch_bitmap(hashp, ndx) + HTAB *hashp; + int ndx; +{ + if (ndx >= hashp->nmaps) + return (NULL); + if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL) + return (NULL); + if (__get_page(hashp, + (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) { + free(hashp->mapp[ndx]); + return (NULL); + } + return (hashp->mapp[ndx]); +} + +#ifdef DEBUG4 +int +print_chain(addr) + int addr; +{ + BUFHEAD *bufp; + short *bp, oaddr; + + (void)fprintf(stderr, "%d ", addr); + bufp = __get_buf(hashp, addr, NULL, 0); + bp = (short *)bufp->page; + while (bp[0] && ((bp[bp[0]] == OVFLPAGE) || + ((bp[0] > 2) && bp[2] < REAL_KEY))) { + oaddr = bp[bp[0] - 1]; + (void)fprintf(stderr, "%d ", (int)oaddr); + bufp = __get_buf(hashp, (int)oaddr, bufp, 0); + bp = (short *)bufp->page; + } + (void)fprintf(stderr, "\n"); +} +#endif diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/hsearch.c b/circuitpython/lib/berkeley-db-1.xx/hash/hsearch.c new file mode 100644 index 0000000..cc8f7a4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/hsearch.c @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)hsearch.c 8.4 (Berkeley) 7/21/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include + +#include +#include "search.h" + +static DB *dbp = NULL; +static ENTRY retval; + +extern int +hcreate(nel) + u_int nel; +{ + HASHINFO info; + + info.nelem = nel; + info.bsize = 256; + info.ffactor = 8; + info.cachesize = 0; + info.hash = NULL; + info.lorder = 0; + dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0); + return ((int)dbp); +} + +extern ENTRY * +hsearch(item, action) + ENTRY item; + ACTION action; +{ + DBT key, val; + int status; + + if (!dbp) + return (NULL); + key.data = (u_char *)item.key; + key.size = strlen(item.key) + 1; + + if (action == ENTER) { + val.data = (u_char *)item.data; + val.size = strlen(item.data) + 1; + status = (dbp->put)(dbp, &key, &val, R_NOOVERWRITE); + if (status) + return (NULL); + } else { + /* FIND */ + status = (dbp->get)(dbp, &key, &val, 0); + if (status) + return (NULL); + else + item.data = (char *)val.data; + } + retval.key = item.key; + retval.data = item.data; + return (&retval); +} + +extern void +hdestroy() +{ + if (dbp) { + (void)(dbp->close)(dbp); + dbp = NULL; + } +} diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/ndbm.c b/circuitpython/lib/berkeley-db-1.xx/hash/ndbm.c new file mode 100644 index 0000000..2cbbe91 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/ndbm.c @@ -0,0 +1,202 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94"; +#endif /* LIBC_SCCS and not lint */ + +/* + * This package provides a dbm compatible interface to the new hashing + * package described in db(3). + */ + +#include + +#include +#include + +#include +#include "hash.h" + +/* + * Returns: + * *DBM on success + * NULL on failure + */ +extern DBM * +dbm_open(file, flags, mode) + const char *file; + int flags, mode; +{ + HASHINFO info; + char path[MAXPATHLEN]; + + info.bsize = 4096; + info.ffactor = 40; + info.nelem = 1; + info.cachesize = 0; + info.hash = NULL; + info.lorder = 0; + (void)strcpy(path, file); + (void)strcat(path, DBM_SUFFIX); + return ((DBM *)__hash_open(path, flags, mode, &info, 0)); +} + +extern void +dbm_close(db) + DBM *db; +{ + (void)(db->close)(db); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_fetch(db, key) + DBM *db; + datum key; +{ + datum retval; + int status; + + status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0); + if (status) { + retval.dptr = NULL; + retval.dsize = 0; + } + return (retval); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_firstkey(db) + DBM *db; +{ + int status; + datum retdata, retkey; + + status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST); + if (status) + retkey.dptr = NULL; + return (retkey); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_nextkey(db) + DBM *db; +{ + int status; + datum retdata, retkey; + + status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT); + if (status) + retkey.dptr = NULL; + return (retkey); +} +/* + * Returns: + * 0 on success + * <0 failure + */ +extern int +dbm_delete(db, key) + DBM *db; + datum key; +{ + int status; + + status = (db->del)(db, (DBT *)&key, 0); + if (status) + return (-1); + else + return (0); +} + +/* + * Returns: + * 0 on success + * <0 failure + * 1 if DBM_INSERT and entry exists + */ +extern int +dbm_store(db, key, content, flags) + DBM *db; + datum key, content; + int flags; +{ + return ((db->put)(db, (DBT *)&key, (DBT *)&content, + (flags == DBM_INSERT) ? R_NOOVERWRITE : 0)); +} + +extern int +dbm_error(db) + DBM *db; +{ + HTAB *hp; + + hp = (HTAB *)db->internal; + return (hp->errno); +} + +extern int +dbm_clearerr(db) + DBM *db; +{ + HTAB *hp; + + hp = (HTAB *)db->internal; + hp->errno = 0; + return (0); +} + +extern int +dbm_dirfno(db) + DBM *db; +{ + return(((HTAB *)db->internal)->fp); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/page.h b/circuitpython/lib/berkeley-db-1.xx/hash/page.h new file mode 100644 index 0000000..0fc0d5a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/page.h @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)page.h 8.2 (Berkeley) 5/31/94 + */ + +/* + * Definitions for hashing page file format. + */ + +/* + * routines dealing with a data page + * + * page format: + * +------------------------------+ + * p | n | keyoff | datoff | keyoff | + * +------------+--------+--------+ + * | datoff | free | ptr | --> | + * +--------+---------------------+ + * | F R E E A R E A | + * +--------------+---------------+ + * | <---- - - - | data | + * +--------+-----+----+----------+ + * | key | data | key | + * +--------+----------+----------+ + * + * Pointer to the free space is always: p[p[0] + 2] + * Amount of free space on the page is: p[p[0] + 1] + */ + +/* + * How many bytes required for this pair? + * 2 shorts in the table at the top of the page + room for the + * key and room for the data + * + * We prohibit entering a pair on a page unless there is also room to append + * an overflow page. The reason for this it that you can get in a situation + * where a single key/data pair fits on a page, but you can't append an + * overflow page and later you'd have to split the key/data and handle like + * a big pair. + * You might as well do this up front. + */ + +#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->size + (D)->size) +#define BIGOVERHEAD (4*sizeof(u_int16_t)) +#define KEYSIZE(K) (4*sizeof(u_int16_t) + (K)->size); +#define OVFLSIZE (2*sizeof(u_int16_t)) +#define FREESPACE(P) ((P)[(P)[0]+1]) +#define OFFSET(P) ((P)[(P)[0]+2]) +#define PAIRFITS(P,K,D) \ + (((P)[2] >= REAL_KEY) && \ + (PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P))) +#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t)) + +typedef struct { + BUFHEAD *newp; + BUFHEAD *oldp; + BUFHEAD *nextp; + u_int16_t next_addr; +} SPLIT_RETURN; diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/search.h b/circuitpython/lib/berkeley-db-1.xx/hash/search.h new file mode 100644 index 0000000..4d3b914 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/search.h @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)search.h 8.1 (Berkeley) 6/4/93 + */ + +/* Backward compatibility to hsearch interface. */ +typedef struct entry { + char *key; + char *data; +} ENTRY; + +typedef enum { + FIND, ENTER +} ACTION; + +int hcreate __P((unsigned int)); +void hdestroy __P((void)); +ENTRY *hsearch __P((ENTRY, ACTION)); diff --git a/circuitpython/lib/berkeley-db-1.xx/hash/tags b/circuitpython/lib/berkeley-db-1.xx/hash/tags new file mode 120000 index 0000000..7ab656b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/hash/tags @@ -0,0 +1 @@ +../db/tags \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/include/db.h b/circuitpython/lib/berkeley-db-1.xx/include/db.h new file mode 100644 index 0000000..2029de5 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/include/db.h @@ -0,0 +1,237 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)db.h 8.7 (Berkeley) 6/16/94 + */ + +#ifndef _DB_H_ +#define _DB_H_ + +#include +#include + +#include + +#include +#ifdef __DBINTERFACE_PRIVATE +#include +#endif + +#define RET_ERROR -1 /* Return values. */ +#define RET_SUCCESS 0 +#define RET_SPECIAL 1 + +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ +typedef __signed char int8_t; +typedef unsigned char u_int8_t; +typedef short int16_t; +typedef unsigned short u_int16_t; +typedef int int32_t; +typedef unsigned int u_int32_t; +#ifdef WE_DONT_NEED_QUADS +typedef long long int64_t; +typedef unsigned long long u_int64_t; +#endif +#endif + +#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ +typedef u_int32_t pgno_t; +#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ +typedef u_int16_t indx_t; +#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */ +typedef u_int32_t recno_t; + +/* Key/data structure -- a Data-Base Thang. */ +typedef struct { + void *data; /* data */ + size_t size; /* data length */ +} DBT; + +/* Routine flags. */ +#define R_CURSOR 1 /* del, put, seq */ +#define __R_UNUSED 2 /* UNUSED */ +#define R_FIRST 3 /* seq */ +#define R_IAFTER 4 /* put (RECNO) */ +#define R_IBEFORE 5 /* put (RECNO) */ +#define R_LAST 6 /* seq (BTREE, RECNO) */ +#define R_NEXT 7 /* seq */ +#define R_NOOVERWRITE 8 /* put */ +#define R_PREV 9 /* seq (BTREE, RECNO) */ +#define R_SETCURSOR 10 /* put (RECNO) */ +#define R_RECNOSYNC 11 /* sync (RECNO) */ + +typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; + +/* + * !!! + * The following flags are included in the dbopen(3) call as part of the + * open(2) flags. In order to avoid conflicts with the open flags, start + * at the top of the 16 or 32-bit number space and work our way down. If + * the open flags were significantly expanded in the future, it could be + * a problem. Wish I'd left another flags word in the dbopen call. + * + * !!! + * None of this stuff is implemented yet. The only reason that it's here + * is so that the access methods can skip copying the key/data pair when + * the DB_LOCK flag isn't set. + */ +#if UINT_MAX > 65535 +#define DB_LOCK 0x20000000 /* Do locking. */ +#define DB_SHMEM 0x40000000 /* Use shared memory. */ +#define DB_TXN 0x80000000 /* Do transactions. */ +#else +#define DB_LOCK 0x2000 /* Do locking. */ +#define DB_SHMEM 0x4000 /* Use shared memory. */ +#define DB_TXN 0x8000 /* Do transactions. */ +#endif + +/* Access method description structure. */ +typedef struct __db { + DBTYPE type; /* Underlying db type. */ + int (*close) __P((struct __db *)); + int (*del) __P((const struct __db *, const DBT *, u_int)); + int (*get) __P((const struct __db *, const DBT *, DBT *, u_int)); + int (*put) __P((const struct __db *, DBT *, const DBT *, u_int)); + int (*seq) __P((const struct __db *, DBT *, DBT *, u_int)); + int (*sync) __P((const struct __db *, u_int)); + void *internal; /* Access method private. */ + int (*fd) __P((const struct __db *)); +} DB; + +#define BTREEMAGIC 0x053162 +#define BTREEVERSION 3 + +/* Structure used to pass parameters to the btree routines. */ +typedef struct { +#define R_DUP 0x01 /* duplicate keys */ + u_long flags; + u_int cachesize; /* bytes to cache */ + int maxkeypage; /* maximum keys per page */ + int minkeypage; /* minimum keys per page */ + u_int psize; /* page size */ + int (*compare) /* comparison function */ + __P((const DBT *, const DBT *)); + size_t (*prefix) /* prefix function */ + __P((const DBT *, const DBT *)); + int lorder; /* byte order */ +} BTREEINFO; + +#define HASHMAGIC 0x061561 +#define HASHVERSION 2 + +/* Structure used to pass parameters to the hashing routines. */ +typedef struct { + u_int bsize; /* bucket size */ + u_int ffactor; /* fill factor */ + u_int nelem; /* number of elements */ + u_int cachesize; /* bytes to cache */ + u_int32_t /* hash function */ + (*hash) __P((const void *, size_t)); + int lorder; /* byte order */ +} HASHINFO; + +/* Structure used to pass parameters to the record routines. */ +typedef struct { +#define R_FIXEDLEN 0x01 /* fixed-length records */ +#define R_NOKEY 0x02 /* key not required */ +#define R_SNAPSHOT 0x04 /* snapshot the input */ + u_long flags; + u_int cachesize; /* bytes to cache */ + u_int psize; /* page size */ + int lorder; /* byte order */ + size_t reclen; /* record length (fixed-length records) */ + u_char bval; /* delimiting byte (variable-length records */ + char *bfname; /* btree file name */ +} RECNOINFO; + +#ifdef __DBINTERFACE_PRIVATE +/* + * Little endian <==> big endian 32-bit swap macros. + * M_32_SWAP swap a memory location + * P_32_SWAP swap a referenced memory location + * P_32_COPY swap from one location to another + */ +#define M_32_SWAP(a) { \ + u_int32_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[3]; \ + ((char *)&a)[1] = ((char *)&_tmp)[2]; \ + ((char *)&a)[2] = ((char *)&_tmp)[1]; \ + ((char *)&a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_SWAP(a) { \ + u_int32_t _tmp = *(u_int32_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[3]; \ + ((char *)a)[1] = ((char *)&_tmp)[2]; \ + ((char *)a)[2] = ((char *)&_tmp)[1]; \ + ((char *)a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[3]; \ + ((char *)&(b))[1] = ((char *)&(a))[2]; \ + ((char *)&(b))[2] = ((char *)&(a))[1]; \ + ((char *)&(b))[3] = ((char *)&(a))[0]; \ +} + +/* + * Little endian <==> big endian 16-bit swap macros. + * M_16_SWAP swap a memory location + * P_16_SWAP swap a referenced memory location + * P_16_COPY swap from one location to another + */ +#define M_16_SWAP(a) { \ + u_int16_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[1]; \ + ((char *)&a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_SWAP(a) { \ + u_int16_t _tmp = *(u_int16_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[1]; \ + ((char *)a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[1]; \ + ((char *)&(b))[1] = ((char *)&(a))[0]; \ +} +#endif + +__BEGIN_DECLS +DB *dbopen __P((const char *, int, int, DBTYPE, const void *)); + +#ifdef __DBINTERFACE_PRIVATE +DB *__bt_open __P((virt_fd_t, const FILEVTABLE *, const BTREEINFO *, int)); +DB *__hash_open __P((const char *, int, int, const HASHINFO *, int)); +DB *__rec_open __P((const char *, int, int, const RECNOINFO *, int)); +void __dbpanic __P((DB *dbp)); +#endif +__END_DECLS +#endif /* !_DB_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/include/filevtable.h b/circuitpython/lib/berkeley-db-1.xx/include/filevtable.h new file mode 100644 index 0000000..d1f3dfe --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/include/filevtable.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 _BDB_FILEVTABLE_H_ +#define _BDB_FILEVTABLE_H_ + +#ifdef VIRT_FD_T_HEADER +#include VIRT_FD_T_HEADER +#endif +#include +#include + +#ifndef virt_fd_t +#define virt_fd_t int +#endif + +typedef struct FILEVTABLE { + ssize_t (*read) __P((virt_fd_t, void *, size_t)); + ssize_t (*write) __P((virt_fd_t, const void *, size_t)); + off_t (*lseek) __P((virt_fd_t, off_t, int)); + int (*fsync) __P((virt_fd_t)); +} FILEVTABLE; + +#endif /* _BDB_FILEVTABLE_H_ */ diff --git a/circuitpython/lib/berkeley-db-1.xx/include/mpool.h b/circuitpython/lib/berkeley-db-1.xx/include/mpool.h new file mode 100644 index 0000000..5607b49 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/include/mpool.h @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)mpool.h 8.2 (Berkeley) 7/14/94 + */ + +#include +#include + +/* + * The memory pool scheme is a simple one. Each in-memory page is referenced + * by a bucket which is threaded in up to two of three ways. All active pages + * are threaded on a hash chain (hashed by page number) and an lru chain. + * Inactive pages are threaded on a free chain. Each reference to a memory + * pool is handed an opaque MPOOL cookie which stores all of this information. + */ +#define HASHSIZE 128 +#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE) + +/* The BKT structures are the elements of the queues. */ +typedef struct _bkt { + CIRCLEQ_ENTRY(_bkt) hq; /* hash queue */ + CIRCLEQ_ENTRY(_bkt) q; /* lru queue */ + void *page; /* page */ + pgno_t pgno; /* page number */ + +#define MPOOL_DIRTY 0x01 /* page needs to be written */ +#define MPOOL_PINNED 0x02 /* page is pinned into memory */ + u_int8_t flags; /* flags */ +} BKT; + +typedef struct MPOOL { + CIRCLEQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */ + /* hash queue array */ + CIRCLEQ_HEAD(_hqh, _bkt) hqh[HASHSIZE]; + pgno_t curcache; /* current number of cached pages */ + pgno_t maxcache; /* max number of cached pages */ + pgno_t npages; /* number of pages in the file */ + u_long pagesize; /* file page size */ + virt_fd_t fd; /* virtual file descriptor */ + /* page in conversion routine */ + const FILEVTABLE *fvtable; + void (*pgin) __P((void *, pgno_t, void *)); + /* page out conversion routine */ + void (*pgout) __P((void *, pgno_t, void *)); + void *pgcookie; /* cookie for page in/out routines */ +#ifdef STATISTICS + u_long cachehit; + u_long cachemiss; + u_long pagealloc; + u_long pageflush; + u_long pageget; + u_long pagenew; + u_long pageput; + u_long pageread; + u_long pagewrite; +#endif +} MPOOL; + +__BEGIN_DECLS +MPOOL *mpool_open __P((void *, virt_fd_t, const FILEVTABLE *, pgno_t, pgno_t)); +void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *), + void (*)(void *, pgno_t, void *), void *)); +void *mpool_new __P((MPOOL *, pgno_t *)); +void *mpool_get __P((MPOOL *, pgno_t, u_int)); +int mpool_put __P((MPOOL *, void *, u_int)); +int mpool_sync __P((MPOOL *)); +int mpool_close __P((MPOOL *)); +#ifdef STATISTICS +void mpool_stat __P((MPOOL *)); +#endif +__END_DECLS diff --git a/circuitpython/lib/berkeley-db-1.xx/include/tags b/circuitpython/lib/berkeley-db-1.xx/include/tags new file mode 120000 index 0000000..7ab656b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/include/tags @@ -0,0 +1 @@ +../db/tags \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/man/Makefile.inc b/circuitpython/lib/berkeley-db-1.xx/man/Makefile.inc new file mode 100644 index 0000000..d8d93f9 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/man/Makefile.inc @@ -0,0 +1,7 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 + +.PATH: ${.CURDIR}/db/man + +# mpool.3 +MAN3+= btree.0 dbopen.0 hash.0 recno.0 +MLINKS+= dbopen.3 db.3 diff --git a/circuitpython/lib/berkeley-db-1.xx/man/btree.3 b/circuitpython/lib/berkeley-db-1.xx/man/btree.3 new file mode 100644 index 0000000..8284b21 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/man/btree.3 @@ -0,0 +1,233 @@ +.\" Copyright (c) 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. +.\" +.\" @(#)btree.3 8.4 (Berkeley) 8/18/94 +.\" +.TH BTREE 3 "August 18, 1994" +.\".UC 7 +.SH NAME +btree \- btree database access method +.SH SYNOPSIS +.nf +.ft B +#include +#include +.ft R +.fi +.SH DESCRIPTION +The routine +.IR dbopen +is the library interface to database files. +One of the supported file formats is btree files. +The general description of the database access methods is in +.IR dbopen (3), +this manual page describes only the btree specific information. +.PP +The btree data structure is a sorted, balanced tree structure storing +associated key/data pairs. +.PP +The btree access method specific data structure provided to +.I dbopen +is defined in the include file as follows: +.PP +typedef struct { +.RS +u_long flags; +.br +u_int cachesize; +.br +int maxkeypage; +.br +int minkeypage; +.br +u_int psize; +.br +int (*compare)(const DBT *key1, const DBT *key2); +.br +size_t (*prefix)(const DBT *key1, const DBT *key2); +.br +int lorder; +.RE +} BTREEINFO; +.PP +The elements of this structure are as follows: +.TP +flags +The flag value is specified by +.IR or 'ing +any of the following values: +.RS +.TP +R_DUP +Permit duplicate keys in the tree, i.e. permit insertion if the key to be +inserted already exists in the tree. +The default behavior, as described in +.IR dbopen (3), +is to overwrite a matching key when inserting a new key or to fail if +the R_NOOVERWRITE flag is specified. +The R_DUP flag is overridden by the R_NOOVERWRITE flag, and if the +R_NOOVERWRITE flag is specified, attempts to insert duplicate keys into +the tree will fail. +.IP +If the database contains duplicate keys, the order of retrieval of +key/data pairs is undefined if the +.I get +routine is used, however, +.I seq +routine calls with the R_CURSOR flag set will always return the logical +``first'' of any group of duplicate keys. +.RE +.TP +cachesize +A suggested maximum size (in bytes) of the memory cache. +This value is +.B only +advisory, and the access method will allocate more memory rather than fail. +Since every search examines the root page of the tree, caching the most +recently used pages substantially improves access time. +In addition, physical writes are delayed as long as possible, so a moderate +cache can reduce the number of I/O operations significantly. +Obviously, using a cache increases (but only increases) the likelihood of +corruption or lost data if the system crashes while a tree is being modified. +If +.I cachesize +is 0 (no size is specified) a default cache is used. +.TP +maxkeypage +The maximum number of keys which will be stored on any single page. +Not currently implemented. +.\" The maximum number of keys which will be stored on any single page. +.\" Because of the way the btree data structure works, +.\" .I maxkeypage +.\" must always be greater than or equal to 2. +.\" If +.\" .I maxkeypage +.\" is 0 (no maximum number of keys is specified) the page fill factor is +.\" made as large as possible (which is almost invariably what is wanted). +.TP +minkeypage +The minimum number of keys which will be stored on any single page. +This value is used to determine which keys will be stored on overflow +pages, i.e. if a key or data item is longer than the pagesize divided +by the minkeypage value, it will be stored on overflow pages instead +of in the page itself. +If +.I minkeypage +is 0 (no minimum number of keys is specified) a value of 2 is used. +.TP +psize +Page size is the size (in bytes) of the pages used for nodes in the tree. +The minimum page size is 512 bytes and the maximum page size is 64K. +If +.I psize +is 0 (no page size is specified) a page size is chosen based on the +underlying file system I/O block size. +.TP +compare +Compare is the key comparison function. +It must return an integer less than, equal to, or greater than zero if the +first key argument is considered to be respectively less than, equal to, +or greater than the second key argument. +The same comparison function must be used on a given tree every time it +is opened. +If +.I compare +is NULL (no comparison function is specified), the keys are compared +lexically, with shorter keys considered less than longer keys. +.TP +prefix +Prefix is the prefix comparison function. +If specified, this routine must return the number of bytes of the second key +argument which are necessary to determine that it is greater than the first +key argument. +If the keys are equal, the key length should be returned. +Note, the usefulness of this routine is very data dependent, but, in some +data sets can produce significantly reduced tree sizes and search times. +If +.I prefix +is NULL (no prefix function is specified), +.B and +no comparison function is specified, a default lexical comparison routine +is used. +If +.I prefix +is NULL and a comparison routine is specified, no prefix comparison is +done. +.TP +lorder +The byte order for integers in the stored database metadata. +The number should represent the order as an integer; for example, +big endian order would be the number 4,321. +If +.I lorder +is 0 (no order is specified) the current host order is used. +.PP +If the file already exists (and the O_TRUNC flag is not specified), the +values specified for the parameters flags, lorder and psize are ignored +in favor of the values used when the tree was created. +.PP +Forward sequential scans of a tree are from the least key to the greatest. +.PP +Space freed up by deleting key/data pairs from the tree is never reclaimed, +although it is normally made available for reuse. +This means that the btree storage structure is grow-only. +The only solutions are to avoid excessive deletions, or to create a fresh +tree periodically from a scan of an existing one. +.PP +Searches, insertions, and deletions in a btree will all complete in +O lg base N where base is the average fill factor. +Often, inserting ordered data into btrees results in a low fill factor. +This implementation has been modified to make ordered insertion the best +case, resulting in a much better than normal page fill factor. +.SH ERRORS +The +.I btree +access method routines may fail and set +.I errno +for any of the errors specified for the library routine +.IR dbopen (3). +.SH "SEE ALSO" +.IR dbopen (3), +.IR hash (3), +.IR mpool (3), +.IR recno (3) +.sp +.IR "The Ubiquitous B-tree" , +Douglas Comer, ACM Comput. Surv. 11, 2 (June 1979), 121-138. +.sp +.IR "Prefix B-trees" , +Bayer and Unterauer, ACM Transactions on Database Systems, Vol. 2, 1 +(March 1977), 11-26. +.sp +.IR "The Art of Computer Programming Vol. 3: Sorting and Searching" , +D.E. Knuth, 1968, pp 471-480. +.SH BUGS +Only big and little endian byte order is supported. diff --git a/circuitpython/lib/berkeley-db-1.xx/man/dbopen.3 b/circuitpython/lib/berkeley-db-1.xx/man/dbopen.3 new file mode 100644 index 0000000..f06a4ef --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/man/dbopen.3 @@ -0,0 +1,476 @@ +.\" Copyright (c) 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. +.\" +.\" @(#)dbopen.3 8.5 (Berkeley) 1/2/94 +.\" +.TH DBOPEN 3 "January 2, 1994" +.UC 7 +.SH NAME +dbopen \- database access methods +.SH SYNOPSIS +.nf +.ft B +#include +#include +#include + +DB * +dbopen(const char *file, int flags, int mode, DBTYPE type, +.ti +5 +const void *openinfo); +.ft R +.fi +.SH DESCRIPTION +.IR Dbopen +is the library interface to database files. +The supported file formats are btree, hashed and UNIX file oriented. +The btree format is a representation of a sorted, balanced tree structure. +The hashed format is an extensible, dynamic hashing scheme. +The flat-file format is a byte stream file with fixed or variable length +records. +The formats and file format specific information are described in detail +in their respective manual pages +.IR btree (3), +.IR hash (3) +and +.IR recno (3). +.PP +Dbopen opens +.I file +for reading and/or writing. +Files never intended to be preserved on disk may be created by setting +the file parameter to NULL. +.PP +The +.I flags +and +.I mode arguments +are as specified to the +.IR open (2) +routine, however, only the O_CREAT, O_EXCL, O_EXLOCK, O_NONBLOCK, +O_RDONLY, O_RDWR, O_SHLOCK and O_TRUNC flags are meaningful. +(Note, opening a database file O_WRONLY is not possible.) +.\"Three additional options may be specified by +.\".IR or 'ing +.\"them into the +.\".I flags +.\"argument. +.\".TP +.\"DB_LOCK +.\"Do the necessary locking in the database to support concurrent access. +.\"If concurrent access isn't needed or the database is read-only this +.\"flag should not be set, as it tends to have an associated performance +.\"penalty. +.\".TP +.\"DB_SHMEM +.\"Place the underlying memory pool used by the database in shared +.\"memory. +.\"Necessary for concurrent access. +.\".TP +.\"DB_TXN +.\"Support transactions in the database. +.\"The DB_LOCK and DB_SHMEM flags must be set as well. +.PP +The +.I type +argument is of type DBTYPE (as defined in the include file) and +may be set to DB_BTREE, DB_HASH or DB_RECNO. +.PP +The +.I openinfo +argument is a pointer to an access method specific structure described +in the access method's manual page. +If +.I openinfo +is NULL, each access method will use defaults appropriate for the system +and the access method. +.PP +.I Dbopen +returns a pointer to a DB structure on success and NULL on error. +The DB structure is defined in the include file, and contains at +least the following fields: +.sp +.nf +typedef struct { +.RS +DBTYPE type; +int (*close)(const DB *db); +int (*del)(const DB *db, const DBT *key, u_int flags); +int (*fd)(const DB *db); +int (*get)(const DB *db, DBT *key, DBT *data, u_int flags); +int (*put)(const DB *db, DBT *key, const DBT *data, +.ti +5 +u_int flags); +int (*sync)(const DB *db, u_int flags); +int (*seq)(const DB *db, DBT *key, DBT *data, u_int flags); +.RE +} DB; +.fi +.PP +These elements describe a database type and a set of functions performing +various actions. +These functions take a pointer to a structure as returned by +.IR dbopen , +and sometimes one or more pointers to key/data structures and a flag value. +.TP +type +The type of the underlying access method (and file format). +.TP +close +A pointer to a routine to flush any cached information to disk, free any +allocated resources, and close the underlying file(s). +Since key/data pairs may be cached in memory, failing to sync the file +with a +.I close +or +.I sync +function may result in inconsistent or lost information. +.I Close +routines return -1 on error (setting +.IR errno ) +and 0 on success. +.TP +del +A pointer to a routine to remove key/data pairs from the database. +.IP +The parameter +.I flag +may be set to the following value: +.RS +.TP +R_CURSOR +Delete the record referenced by the cursor. +The cursor must have previously been initialized. +.RE +.IP +.I Delete +routines return -1 on error (setting +.IR errno ), +0 on success, and 1 if the specified +.I key +was not in the file. +.TP +fd +A pointer to a routine which returns a file descriptor representative +of the underlying database. +A file descriptor referencing the same file will be returned to all +processes which call +.I dbopen +with the same +.I file +name. +This file descriptor may be safely used as an argument to the +.IR fcntl (2) +and +.IR flock (2) +locking functions. +The file descriptor is not necessarily associated with any of the +underlying files used by the access method. +No file descriptor is available for in memory databases. +.I Fd +routines return -1 on error (setting +.IR errno ), +and the file descriptor on success. +.TP +get +A pointer to a routine which is the interface for keyed retrieval from +the database. +The address and length of the data associated with the specified +.I key +are returned in the structure referenced by +.IR data . +.I Get +routines return -1 on error (setting +.IR errno ), +0 on success, and 1 if the +.I key +was not in the file. +.TP +put +A pointer to a routine to store key/data pairs in the database. +.IP +The parameter +.I flag +may be set to one of the following values: +.RS +.TP +R_CURSOR +Replace the key/data pair referenced by the cursor. +The cursor must have previously been initialized. +.TP +R_IAFTER +Append the data immediately after the data referenced by +.IR key , +creating a new key/data pair. +The record number of the appended key/data pair is returned in the +.I key +structure. +(Applicable only to the DB_RECNO access method.) +.TP +R_IBEFORE +Insert the data immediately before the data referenced by +.IR key , +creating a new key/data pair. +The record number of the inserted key/data pair is returned in the +.I key +structure. +(Applicable only to the DB_RECNO access method.) +.TP +R_NOOVERWRITE +Enter the new key/data pair only if the key does not previously exist. +.TP +R_SETCURSOR +Store the key/data pair, setting or initializing the position of the +cursor to reference it. +(Applicable only to the DB_BTREE and DB_RECNO access methods.) +.RE +.IP +R_SETCURSOR is available only for the DB_BTREE and DB_RECNO access +methods because it implies that the keys have an inherent order +which does not change. +.IP +R_IAFTER and R_IBEFORE are available only for the DB_RECNO +access method because they each imply that the access method is able to +create new keys. +This is only true if the keys are ordered and independent, record numbers +for example. +.IP +The default behavior of the +.I put +routines is to enter the new key/data pair, replacing any previously +existing key. +.IP +.I Put +routines return -1 on error (setting +.IR errno ), +0 on success, and 1 if the R_NOOVERWRITE +.I flag +was set and the key already exists in the file. +.TP +seq +A pointer to a routine which is the interface for sequential +retrieval from the database. +The address and length of the key are returned in the structure +referenced by +.IR key , +and the address and length of the data are returned in the +structure referenced +by +.IR data . +.IP +Sequential key/data pair retrieval may begin at any time, and the +position of the ``cursor'' is not affected by calls to the +.IR del , +.IR get , +.IR put , +or +.I sync +routines. +Modifications to the database during a sequential scan will be reflected +in the scan, i.e. records inserted behind the cursor will not be returned +while records inserted in front of the cursor will be returned. +.IP +The flag value +.B must +be set to one of the following values: +.RS +.TP +R_CURSOR +The data associated with the specified key is returned. +This differs from the +.I get +routines in that it sets or initializes the cursor to the location of +the key as well. +(Note, for the DB_BTREE access method, the returned key is not necessarily an +exact match for the specified key. +The returned key is the smallest key greater than or equal to the specified +key, permitting partial key matches and range searches.) +.TP +R_FIRST +The first key/data pair of the database is returned, and the cursor +is set or initialized to reference it. +.TP +R_LAST +The last key/data pair of the database is returned, and the cursor +is set or initialized to reference it. +(Applicable only to the DB_BTREE and DB_RECNO access methods.) +.TP +R_NEXT +Retrieve the key/data pair immediately after the cursor. +If the cursor is not yet set, this is the same as the R_FIRST flag. +.TP +R_PREV +Retrieve the key/data pair immediately before the cursor. +If the cursor is not yet set, this is the same as the R_LAST flag. +(Applicable only to the DB_BTREE and DB_RECNO access methods.) +.RE +.IP +R_LAST and R_PREV are available only for the DB_BTREE and DB_RECNO +access methods because they each imply that the keys have an inherent +order which does not change. +.IP +.I Seq +routines return -1 on error (setting +.IR errno ), +0 on success and 1 if there are no key/data pairs less than or greater +than the specified or current key. +If the DB_RECNO access method is being used, and if the database file +is a character special file and no complete key/data pairs are currently +available, the +.I seq +routines return 2. +.TP +sync +A pointer to a routine to flush any cached information to disk. +If the database is in memory only, the +.I sync +routine has no effect and will always succeed. +.IP +The flag value may be set to the following value: +.RS +.TP +R_RECNOSYNC +If the DB_RECNO access method is being used, this flag causes +the sync routine to apply to the btree file which underlies the +recno file, not the recno file itself. +(See the +.I bfname +field of the +.IR recno (3) +manual page for more information.) +.RE +.IP +.I Sync +routines return -1 on error (setting +.IR errno ) +and 0 on success. +.SH "KEY/DATA PAIRS" +Access to all file types is based on key/data pairs. +Both keys and data are represented by the following data structure: +.PP +typedef struct { +.RS +void *data; +.br +size_t size; +.RE +} DBT; +.PP +The elements of the DBT structure are defined as follows: +.TP +data +A pointer to a byte string. +.TP +size +The length of the byte string. +.PP +Key and data byte strings may reference strings of essentially unlimited +length although any two of them must fit into available memory at the same +time. +It should be noted that the access methods provide no guarantees about +byte string alignment. +.SH ERRORS +The +.I dbopen +routine may fail and set +.I errno +for any of the errors specified for the library routines +.IR open (2) +and +.IR malloc (3) +or the following: +.TP +[EFTYPE] +A file is incorrectly formatted. +.TP +[EINVAL] +A parameter has been specified (hash function, pad byte etc.) that is +incompatible with the current file specification or which is not +meaningful for the function (for example, use of the cursor without +prior initialization) or there is a mismatch between the version +number of file and the software. +.PP +The +.I close +routines may fail and set +.I errno +for any of the errors specified for the library routines +.IR close (2), +.IR read (2), +.IR write (2), +.IR free (3), +or +.IR fsync (2). +.PP +The +.IR del , +.IR get , +.I put +and +.I seq +routines may fail and set +.I errno +for any of the errors specified for the library routines +.IR read (2), +.IR write (2), +.IR free (3) +or +.IR malloc (3). +.PP +The +.I fd +routines will fail and set +.I errno +to ENOENT for in memory databases. +.PP +The +.I sync +routines may fail and set +.I errno +for any of the errors specified for the library routine +.IR fsync (2). +.SH "SEE ALSO" +.IR btree (3), +.IR hash (3), +.IR mpool (3), +.IR recno (3) +.sp +.IR "LIBTP: Portable, Modular Transactions for UNIX" , +Margo Seltzer, Michael Olson, USENIX proceedings, Winter 1992. +.SH BUGS +The typedef DBT is a mnemonic for ``data base thang'', and was used +because noone could think of a reasonable name that wasn't already used. +.PP +The file descriptor interface is a kluge and will be deleted in a +future version of the interface. +.PP +None of the access methods provide any form of concurrent access, +locking, or transactions. diff --git a/circuitpython/lib/berkeley-db-1.xx/man/hash.3 b/circuitpython/lib/berkeley-db-1.xx/man/hash.3 new file mode 100644 index 0000000..4367031 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/man/hash.3 @@ -0,0 +1,159 @@ +.\" Copyright (c) 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. +.\" +.\" @(#)hash.3 8.6 (Berkeley) 8/18/94 +.\" +.TH HASH 3 "August 18, 1994" +.UC 7 +.SH NAME +hash \- hash database access method +.SH SYNOPSIS +.nf +.ft B +#include +#include +.ft R +.fi +.SH DESCRIPTION +The routine +.IR dbopen +is the library interface to database files. +One of the supported file formats is hash files. +The general description of the database access methods is in +.IR dbopen (3), +this manual page describes only the hash specific information. +.PP +The hash data structure is an extensible, dynamic hashing scheme. +.PP +The access method specific data structure provided to +.I dbopen +is defined in the include file as follows: +.sp +typedef struct { +.RS +u_int bsize; +.br +u_int ffactor; +.br +u_int nelem; +.br +u_int cachesize; +.br +u_int32_t (*hash)(const void *, size_t); +.br +int lorder; +.RE +} HASHINFO; +.PP +The elements of this structure are as follows: +.TP +bsize +.I Bsize +defines the hash table bucket size, and is, by default, 256 bytes. +It may be preferable to increase the page size for disk-resident tables +and tables with large data items. +.TP +ffactor +.I Ffactor +indicates a desired density within the hash table. +It is an approximation of the number of keys allowed to accumulate in any +one bucket, determining when the hash table grows or shrinks. +The default value is 8. +.TP +nelem +.I Nelem +is an estimate of the final size of the hash table. +If not set or set too low, hash tables will expand gracefully as keys +are entered, although a slight performance degradation may be noticed. +The default value is 1. +.TP +cachesize +A suggested maximum size, in bytes, of the memory cache. +This value is +.B only +advisory, and the access method will allocate more memory rather +than fail. +.TP +hash +.I Hash +is a user defined hash function. +Since no hash function performs equally well on all possible data, the +user may find that the built-in hash function does poorly on a particular +data set. +User specified hash functions must take two arguments (a pointer to a byte +string and a length) and return a 32-bit quantity to be used as the hash +value. +.TP +lorder +The byte order for integers in the stored database metadata. +The number should represent the order as an integer; for example, +big endian order would be the number 4,321. +If +.I lorder +is 0 (no order is specified) the current host order is used. +If the file already exists, the specified value is ignored and the +value specified when the tree was created is used. +.PP +If the file already exists (and the O_TRUNC flag is not specified), the +values specified for the parameters bsize, ffactor, lorder and nelem are +ignored and the values specified when the tree was created are used. +.PP +If a hash function is specified, +.I hash_open +will attempt to determine if the hash function specified is the same as +the one with which the database was created, and will fail if it is not. +.PP +Backward compatible interfaces to the routines described in +.IR dbm (3), +and +.IR ndbm (3) +are provided, however these interfaces are not compatible with +previous file formats. +.SH ERRORS +The +.I hash +access method routines may fail and set +.I errno +for any of the errors specified for the library routine +.IR dbopen (3). +.SH "SEE ALSO" +.IR btree (3), +.IR dbopen (3), +.IR mpool (3), +.IR recno (3) +.sp +.IR "Dynamic Hash Tables" , +Per-Ake Larson, Communications of the ACM, April 1988. +.sp +.IR "A New Hash Package for UNIX" , +Margo Seltzer, USENIX Proceedings, Winter 1991. +.SH BUGS +Only big and little endian byte order is supported. diff --git a/circuitpython/lib/berkeley-db-1.xx/man/mpool.3 b/circuitpython/lib/berkeley-db-1.xx/man/mpool.3 new file mode 100644 index 0000000..c17606e --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/man/mpool.3 @@ -0,0 +1,219 @@ +.\" Copyright (c) 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. +.\" +.\" @(#)mpool.3 8.1 (Berkeley) 6/4/93 +.\" +.TH MPOOL 3 "June 4, 1993" +.UC 7 +.SH NAME +mpool \- shared memory buffer pool +.SH SYNOPSIS +.nf +.ft B +#include +#include + +MPOOL * +mpool_open (DBT *key, int fd, pgno_t pagesize, pgno_t maxcache); + +void +mpool_filter (MPOOL *mp, void (*pgin)(void *, pgno_t, void *), +.ti +5 +void (*pgout)(void *, pgno_t, void *), void *pgcookie); + +void * +mpool_new (MPOOL *mp, pgno_t *pgnoaddr); + +void * +mpool_get (MPOOL *mp, pgno_t pgno, u_int flags); + +int +mpool_put (MPOOL *mp, void *pgaddr, u_int flags); + +int +mpool_sync (MPOOL *mp); + +int +mpool_close (MPOOL *mp); +.ft R +.fi +.SH DESCRIPTION +.IR Mpool +is the library interface intended to provide page oriented buffer management +of files. +The buffers may be shared between processes. +.PP +The function +.I mpool_open +initializes a memory pool. +The +.I key +argument is the byte string used to negotiate between multiple +processes wishing to share buffers. +If the file buffers are mapped in shared memory, all processes using +the same key will share the buffers. +If +.I key +is NULL, the buffers are mapped into private memory. +The +.I fd +argument is a file descriptor for the underlying file, which must be seekable. +If +.I key +is non-NULL and matches a file already being mapped, the +.I fd +argument is ignored. +.PP +The +.I pagesize +argument is the size, in bytes, of the pages into which the file is broken up. +The +.I maxcache +argument is the maximum number of pages from the underlying file to cache +at any one time. +This value is not relative to the number of processes which share a file's +buffers, but will be the largest value specified by any of the processes +sharing the file. +.PP +The +.I mpool_filter +function is intended to make transparent input and output processing of the +pages possible. +If the +.I pgin +function is specified, it is called each time a buffer is read into the memory +pool from the backing file. +If the +.I pgout +function is specified, it is called each time a buffer is written into the +backing file. +Both functions are are called with the +.I pgcookie +pointer, the page number and a pointer to the page to being read or written. +.PP +The function +.I mpool_new +takes an MPOOL pointer and an address as arguments. +If a new page can be allocated, a pointer to the page is returned and +the page number is stored into the +.I pgnoaddr +address. +Otherwise, NULL is returned and errno is set. +.PP +The function +.I mpool_get +takes a MPOOL pointer and a page number as arguments. +If the page exists, a pointer to the page is returned. +Otherwise, NULL is returned and errno is set. +The flags parameter is not currently used. +.PP +The function +.I mpool_put +unpins the page referenced by +.IR pgaddr . +.I Pgaddr +must be an address previously returned by +.I mpool_get +or +.IR mpool_new . +The flag value is specified by +.IR or 'ing +any of the following values: +.TP +MPOOL_DIRTY +The page has been modified and needs to be written to the backing file. +.PP +.I Mpool_put +returns 0 on success and -1 if an error occurs. +.PP +The function +.I mpool_sync +writes all modified pages associated with the MPOOL pointer to the +backing file. +.I Mpool_sync +returns 0 on success and -1 if an error occurs. +.PP +The +.I mpool_close +function free's up any allocated memory associated with the memory pool +cookie. +Modified pages are +.B not +written to the backing file. +.I Mpool_close +returns 0 on success and -1 if an error occurs. +.SH ERRORS +The +.I mpool_open +function may fail and set +.I errno +for any of the errors specified for the library routine +.IR malloc (3). +.PP +The +.I mpool_get +function may fail and set +.I errno +for the following: +.TP 15 +[EINVAL] +The requested record doesn't exist. +.PP +The +.I mpool_new +and +.I mpool_get +functions may fail and set +.I errno +for any of the errors specified for the library routines +.IR read (2) , +.IR write (2) , +and +.IR malloc (3). +.PP +The +.I mpool_sync +function may fail and set +.I errno +for any of the errors specified for the library routine +.IR write (2). +.PP +The +.I mpool_close +function may fail and set +.I errno +for any of the errors specified for the library routine +.IR free (3). +.SH "SEE ALSO" +.IR dbopen (3), +.IR btree (3), +.IR hash (3), +.IR recno (3) diff --git a/circuitpython/lib/berkeley-db-1.xx/man/recno.3 b/circuitpython/lib/berkeley-db-1.xx/man/recno.3 new file mode 100644 index 0000000..516bef0 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/man/recno.3 @@ -0,0 +1,216 @@ +.\" Copyright (c) 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. +.\" +.\" @(#)recno.3 8.5 (Berkeley) 8/18/94 +.\" +.TH RECNO 3 "August 18, 1994" +.UC 7 +.SH NAME +recno \- record number database access method +.SH SYNOPSIS +.nf +.ft B +#include +#include +.ft R +.fi +.SH DESCRIPTION +The routine +.IR dbopen +is the library interface to database files. +One of the supported file formats is record number files. +The general description of the database access methods is in +.IR dbopen (3), +this manual page describes only the recno specific information. +.PP +The record number data structure is either variable or fixed-length +records stored in a flat-file format, accessed by the logical record +number. +The existence of record number five implies the existence of records +one through four, and the deletion of record number one causes +record number five to be renumbered to record number four, as well +as the cursor, if positioned after record number one, to shift down +one record. +.PP +The recno access method specific data structure provided to +.I dbopen +is defined in the include file as follows: +.PP +typedef struct { +.RS +u_long flags; +.br +u_int cachesize; +.br +u_int psize; +.br +int lorder; +.br +size_t reclen; +.br +u_char bval; +.br +char *bfname; +.RE +} RECNOINFO; +.PP +The elements of this structure are defined as follows: +.TP +flags +The flag value is specified by +.IR or 'ing +any of the following values: +.RS +.TP +R_FIXEDLEN +The records are fixed-length, not byte delimited. +The structure element +.I reclen +specifies the length of the record, and the structure element +.I bval +is used as the pad character. +Any records, inserted into the database, that are less than +.I reclen +bytes long are automatically padded. +.TP +R_NOKEY +In the interface specified by +.IR dbopen , +the sequential record retrieval fills in both the caller's key and +data structures. +If the R_NOKEY flag is specified, the +.I cursor +routines are not required to fill in the key structure. +This permits applications to retrieve records at the end of files without +reading all of the intervening records. +.TP +R_SNAPSHOT +This flag requires that a snapshot of the file be taken when +.I dbopen +is called, instead of permitting any unmodified records to be read from +the original file. +.RE +.TP +cachesize +A suggested maximum size, in bytes, of the memory cache. +This value is +.B only +advisory, and the access method will allocate more memory rather than fail. +If +.I cachesize +is 0 (no size is specified) a default cache is used. +.TP +psize +The recno access method stores the in-memory copies of its records +in a btree. +This value is the size (in bytes) of the pages used for nodes in that tree. +If +.I psize +is 0 (no page size is specified) a page size is chosen based on the +underlying file system I/O block size. +See +.IR btree (3) +for more information. +.TP +lorder +The byte order for integers in the stored database metadata. +The number should represent the order as an integer; for example, +big endian order would be the number 4,321. +If +.I lorder +is 0 (no order is specified) the current host order is used. +.TP +reclen +The length of a fixed-length record. +.TP +bval +The delimiting byte to be used to mark the end of a record for +variable-length records, and the pad character for fixed-length +records. +If no value is specified, newlines (``\en'') are used to mark the end +of variable-length records and fixed-length records are padded with +spaces. +.TP +bfname +The recno access method stores the in-memory copies of its records +in a btree. +If bfname is non-NULL, it specifies the name of the btree file, +as if specified as the file name for a dbopen of a btree file. +.PP +The data part of the key/data pair used by the recno access method +is the same as other access methods. +The key is different. +The +.I data +field of the key should be a pointer to a memory location of type +.IR recno_t , +as defined in the include file. +This type is normally the largest unsigned integral type available to +the implementation. +The +.I size +field of the key should be the size of that type. +.PP +Because there can be no meta-data associated with the underlying +recno access method files, any changes made to the default values +(e.g. fixed record length or byte separator value) must be explicitly +specified each time the file is opened. +.PP +In the interface specified by +.IR dbopen , +using the +.I put +interface to create a new record will cause the creation of multiple, +empty records if the record number is more than one greater than the +largest record currently in the database. +.SH ERRORS +The +.I recno +access method routines may fail and set +.I errno +for any of the errors specified for the library routine +.IR dbopen (3) +or the following: +.TP +[EINVAL] +An attempt was made to add a record to a fixed-length database that +was too large to fit. +.SH "SEE ALSO" +.IR btree (3) +.IR dbopen (3), +.IR hash (3), +.IR mpool (3), +.sp +.IR "Document Processing in a Relational Database System" , +Michael Stonebraker, Heidi Stettner, Joseph Kalash, Antonin Guttman, +Nadene Lynn, Memorandum No. UCB/ERL M82/32, May 1982. +.SH BUGS +Only big and little endian byte order is supported. diff --git a/circuitpython/lib/berkeley-db-1.xx/mpool/Makefile.inc b/circuitpython/lib/berkeley-db-1.xx/mpool/Makefile.inc new file mode 100644 index 0000000..93210c8 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/mpool/Makefile.inc @@ -0,0 +1,5 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 + +.PATH: ${.CURDIR}/db/mpool + +SRCS+= mpool.c diff --git a/circuitpython/lib/berkeley-db-1.xx/mpool/README b/circuitpython/lib/berkeley-db-1.xx/mpool/README new file mode 100644 index 0000000..0f01fbc --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/mpool/README @@ -0,0 +1,7 @@ +# @(#)README 8.1 (Berkeley) 6/4/93 + +These are the current memory pool routines. +They aren't ready for prime time, yet, and +the interface is expected to change. + +--keith diff --git a/circuitpython/lib/berkeley-db-1.xx/mpool/mpool.c b/circuitpython/lib/berkeley-db-1.xx/mpool/mpool.c new file mode 100644 index 0000000..2331259 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/mpool/mpool.c @@ -0,0 +1,452 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#include +#include +#include +#include + +#include + +#define __MPOOLINTERFACE_PRIVATE +#include + +static BKT *mpool_bkt __P((MPOOL *)); +static BKT *mpool_look __P((MPOOL *, pgno_t)); +static int mpool_write __P((MPOOL *, BKT *)); + +/* + * mpool_open -- + * Initialize a memory pool. + */ +MPOOL * +mpool_open(key, fd, fvtable, pagesize, maxcache) + void *key; + virt_fd_t fd; + const FILEVTABLE * fvtable; + pgno_t pagesize, maxcache; +{ + MPOOL *mp; + int entry; + + /* Allocate and initialize the MPOOL cookie. */ + if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL) + return (NULL); + CIRCLEQ_INIT(&mp->lqh); + for (entry = 0; entry < HASHSIZE; ++entry) + CIRCLEQ_INIT(&mp->hqh[entry]); + mp->maxcache = maxcache; + mp->fvtable = fvtable; + off_t file_size = mp->fvtable->lseek(fd, 0, SEEK_END); + if (file_size == (off_t)-1) + return (NULL); + mp->npages = file_size / pagesize; + mp->pagesize = pagesize; + mp->fd = fd; + return (mp); +} + +/* + * mpool_filter -- + * Initialize input/output filters. + */ +void +mpool_filter(mp, pgin, pgout, pgcookie) + MPOOL *mp; + void (*pgin) __P((void *, pgno_t, void *)); + void (*pgout) __P((void *, pgno_t, void *)); + void *pgcookie; +{ + mp->pgin = pgin; + mp->pgout = pgout; + mp->pgcookie = pgcookie; +} + +/* + * mpool_new -- + * Get a new page of memory. + */ +void * +mpool_new(mp, pgnoaddr) + MPOOL *mp; + pgno_t *pgnoaddr; +{ + struct _hqh *head; + BKT *bp; + + if (mp->npages == MAX_PAGE_NUMBER) { + mpool_error("mpool_new: page allocation overflow.\n"); + abort(); + } +#ifdef STATISTICS + ++mp->pagenew; +#endif + /* + * Get a BKT from the cache. Assign a new page number, attach + * it to the head of the hash chain, the tail of the lru chain, + * and return. + */ + if ((bp = mpool_bkt(mp)) == NULL) + return (NULL); + *pgnoaddr = bp->pgno = mp->npages++; + bp->flags = MPOOL_PINNED; + + head = &mp->hqh[HASHKEY(bp->pgno)]; + CIRCLEQ_INSERT_HEAD(head, bp, hq); + CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q); + return (bp->page); +} + +/* + * mpool_get + * Get a page. + */ +void * +mpool_get(mp, pgno, flags) + MPOOL *mp; + pgno_t pgno; + u_int flags; /* XXX not used? */ +{ + struct _hqh *head; + BKT *bp; + off_t off; + int nr; + + /* Check for attempt to retrieve a non-existent page. */ + if (pgno >= mp->npages) { + errno = EINVAL; + return (NULL); + } + +#ifdef STATISTICS + ++mp->pageget; +#endif + + /* Check for a page that is cached. */ + if ((bp = mpool_look(mp, pgno)) != NULL) { +#ifdef DEBUG + if (bp->flags & MPOOL_PINNED) { + mpool_error( + "mpool_get: page %d already pinned\n", bp->pgno); + abort(); + } +#endif + /* + * Move the page to the head of the hash chain and the tail + * of the lru chain. + */ + head = &mp->hqh[HASHKEY(bp->pgno)]; + CIRCLEQ_REMOVE(head, bp, hq); + CIRCLEQ_INSERT_HEAD(head, bp, hq); + CIRCLEQ_REMOVE(&mp->lqh, bp, q); + CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q); + + /* Return a pinned page. */ + bp->flags |= MPOOL_PINNED; + return (bp->page); + } + + /* Get a page from the cache. */ + if ((bp = mpool_bkt(mp)) == NULL) + return (NULL); + + /* Read in the contents. */ +#ifdef STATISTICS + ++mp->pageread; +#endif + off = mp->pagesize * pgno; + if (mp->fvtable->lseek(mp->fd, off, SEEK_SET) != off) + return (NULL); + if ((nr = mp->fvtable->read(mp->fd, bp->page, mp->pagesize)) != mp->pagesize) { + if (nr >= 0) + errno = EFTYPE; + return (NULL); + } + + /* Set the page number, pin the page. */ + bp->pgno = pgno; + bp->flags = MPOOL_PINNED; + + /* + * Add the page to the head of the hash chain and the tail + * of the lru chain. + */ + head = &mp->hqh[HASHKEY(bp->pgno)]; + CIRCLEQ_INSERT_HEAD(head, bp, hq); + CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q); + + /* Run through the user's filter. */ + if (mp->pgin != NULL) + (mp->pgin)(mp->pgcookie, bp->pgno, bp->page); + + return (bp->page); +} + +/* + * mpool_put + * Return a page. + */ +int +mpool_put(mp, page, flags) + MPOOL *mp; + void *page; + u_int flags; +{ + BKT *bp; + +#ifdef STATISTICS + ++mp->pageput; +#endif + bp = (BKT *)((char *)page - sizeof(BKT)); +#ifdef DEBUG + if (!(bp->flags & MPOOL_PINNED)) { + mpool_error( + "mpool_put: page %d not pinned\n", bp->pgno); + abort(); + } +#endif + bp->flags &= ~MPOOL_PINNED; + bp->flags |= flags & MPOOL_DIRTY; + return (RET_SUCCESS); +} + +/* + * mpool_close + * Close the buffer pool. + */ +int +mpool_close(mp) + MPOOL *mp; +{ + BKT *bp; + + /* Free up any space allocated to the lru pages. */ + while ((bp = mp->lqh.cqh_first) != (void *)&mp->lqh) { + CIRCLEQ_REMOVE(&mp->lqh, mp->lqh.cqh_first, q); + free(bp); + } + + /* Free the MPOOL cookie. */ + free(mp); + return (RET_SUCCESS); +} + +/* + * mpool_sync + * Sync the pool to disk. + */ +int +mpool_sync(mp) + MPOOL *mp; +{ + BKT *bp; + + /* Walk the lru chain, flushing any dirty pages to disk. */ + for (bp = mp->lqh.cqh_first; + bp != (void *)&mp->lqh; bp = bp->q.cqe_next) + if (bp->flags & MPOOL_DIRTY && + mpool_write(mp, bp) == RET_ERROR) + return (RET_ERROR); + + /* Sync the file descriptor. */ + return (mp->fvtable->fsync(mp->fd) ? RET_ERROR : RET_SUCCESS); +} + +/* + * mpool_bkt + * Get a page from the cache (or create one). + */ +static BKT * +mpool_bkt(mp) + MPOOL *mp; +{ + struct _hqh *head; + BKT *bp; + + /* If under the max cached, always create a new page. */ + if (mp->curcache < mp->maxcache) + goto new; + + /* + * If the cache is max'd out, walk the lru list for a buffer we + * can flush. If we find one, write it (if necessary) and take it + * off any lists. If we don't find anything we grow the cache anyway. + * The cache never shrinks. + */ + for (bp = mp->lqh.cqh_first; + bp != (void *)&mp->lqh; bp = bp->q.cqe_next) + if (!(bp->flags & MPOOL_PINNED)) { + /* Flush if dirty. */ + if (bp->flags & MPOOL_DIRTY && + mpool_write(mp, bp) == RET_ERROR) + return (NULL); +#ifdef STATISTICS + ++mp->pageflush; +#endif + /* Remove from the hash and lru queues. */ + head = &mp->hqh[HASHKEY(bp->pgno)]; + CIRCLEQ_REMOVE(head, bp, hq); + CIRCLEQ_REMOVE(&mp->lqh, bp, q); +#ifdef DEBUG + { void *spage; + spage = bp->page; + memset(bp, 0xff, sizeof(BKT) + mp->pagesize); + bp->page = spage; + } +#endif + return (bp); + } + +new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL) + return (NULL); +#ifdef STATISTICS + ++mp->pagealloc; +#endif +#if defined(DEBUG) || defined(PURIFY) + memset(bp, 0xff, sizeof(BKT) + mp->pagesize); +#endif + bp->page = (char *)bp + sizeof(BKT); + ++mp->curcache; + return (bp); +} + +/* + * mpool_write + * Write a page to disk. + */ +static int +mpool_write(mp, bp) + MPOOL *mp; + BKT *bp; +{ + off_t off; + +#ifdef STATISTICS + ++mp->pagewrite; +#endif + + /* Run through the user's filter. */ + if (mp->pgout) + (mp->pgout)(mp->pgcookie, bp->pgno, bp->page); + + off = mp->pagesize * bp->pgno; + if (mp->fvtable->lseek(mp->fd, off, SEEK_SET) != off) + return (RET_ERROR); + if (mp->fvtable->write(mp->fd, bp->page, mp->pagesize) != mp->pagesize) + return (RET_ERROR); + + bp->flags &= ~MPOOL_DIRTY; + return (RET_SUCCESS); +} + +/* + * mpool_look + * Lookup a page in the cache. + */ +static BKT * +mpool_look(mp, pgno) + MPOOL *mp; + pgno_t pgno; +{ + struct _hqh *head; + BKT *bp; + + head = &mp->hqh[HASHKEY(pgno)]; + for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next) + if (bp->pgno == pgno) { +#ifdef STATISTICS + ++mp->cachehit; +#endif + return (bp); + } +#ifdef STATISTICS + ++mp->cachemiss; +#endif + return (NULL); +} + +#ifdef STATISTICS +/* + * mpool_stat + * Print out cache statistics. + */ +void +mpool_stat(mp) + MPOOL *mp; +{ + BKT *bp; + int cnt; + char *sep; + + (void)fprintf(stderr, "%lu pages in the file\n", mp->npages); + (void)fprintf(stderr, + "page size %lu, cacheing %lu pages of %lu page max cache\n", + mp->pagesize, mp->curcache, mp->maxcache); + (void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n", + mp->pageput, mp->pageget, mp->pagenew); + (void)fprintf(stderr, "%lu page allocs, %lu page flushes\n", + mp->pagealloc, mp->pageflush); + if (mp->cachehit + mp->cachemiss) + (void)fprintf(stderr, + "%.0f%% cache hit rate (%lu hits, %lu misses)\n", + ((double)mp->cachehit / (mp->cachehit + mp->cachemiss)) + * 100, mp->cachehit, mp->cachemiss); + (void)fprintf(stderr, "%lu page reads, %lu page writes\n", + mp->pageread, mp->pagewrite); + + sep = ""; + cnt = 0; + for (bp = mp->lqh.cqh_first; + bp != (void *)&mp->lqh; bp = bp->q.cqe_next) { + (void)fprintf(stderr, "%s%d", sep, bp->pgno); + if (bp->flags & MPOOL_DIRTY) + (void)fprintf(stderr, "d"); + if (bp->flags & MPOOL_PINNED) + (void)fprintf(stderr, "P"); + if (++cnt == 10) { + sep = "\n"; + cnt = 0; + } else + sep = ", "; + + } + (void)fprintf(stderr, "\n"); +} +#endif diff --git a/circuitpython/lib/berkeley-db-1.xx/mpool/mpool.libtp b/circuitpython/lib/berkeley-db-1.xx/mpool/mpool.libtp new file mode 100644 index 0000000..8c0fc27 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/mpool/mpool.libtp @@ -0,0 +1,746 @@ +/****************************************************************************** + +VERSION $Id: buf.c,v 1.26 92/01/09 09:15:26 margo Exp $ +PACKAGE: User Level Shared Memory Manager + +DESCRIPTION: + This package provides a buffer pool interface implemented as + a collection of file pages mapped into shared memory. + + Based on Mark's buffer manager + +ROUTINES: + External + buf_alloc + buf_flags + buf_get + buf_init + buf_last + buf_open + buf_pin + buf_sync + buf_unpin + Internal + bf_assign_buf + bf_fid_to_fd + bf_newbuf + bf_put_page + + +******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "list.h" +#include "user.h" +#include "txn_sys.h" +#include "buf.h" +#include "semkeys.h" +#include "error.h" + +/* + we need to translate between some type of file id that the user + process passes and a file descriptor. For now, it's a nop. +*/ +#define GET_MASTER get_sem ( buf_spinlock ) +#define RELEASE_MASTER release_sem ( buf_spinlock ) + +#define LRUID *buf_lru +#define LRUP (bufhdr_table+*buf_lru) +#define MRU bufhdr_table[*buf_lru].lru.prev + +/* Global indicator that you have started reusing buffers */ +int do_statistics = 0; +/* + Process Statics (pointers into shared memory) +*/ +static BUF_T *buf_table = 0; +static BUFHDR_T *bufhdr_table; +static int *buf_hash_table; +static int *buf_lru; /* LRU is the free list */ +static int buf_spinlock; +static FINFO_T *buf_fids; +static int *buf_sp; /* Pointer to string free space */ +static char *buf_strings; + +/* Process Local FID->FD table */ +static int fds[NUM_FILE_ENTRIES]; + +/* Static routines */ +static BUFHDR_T *bf_assign_buf(); +static int bf_fid_to_fd(); +static BUFHDR_T *bf_newbuf(); +static int bf_put_page(); + +/* + Return 0 on success + 1 on failure +*/ +extern int +buf_init ( ) +{ + ADDR_T buf_region; + BUFHDR_T *bhp; + int i; + int ref_count; + int *spinlockp; + + /* + Initialize Process local structures + */ + for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) { + fds[i] = -1; + } + + buf_region = attach_region ( BUF_REGION_NAME, BUF_REGION_NUM, + BUF_REGION_SIZE, &ref_count ); + if ( !buf_region ) { + return (1); + } + error_log3 ( "Buf Region: ADDR: %d ID: %d SIZE: %d\n", buf_region, + BUF_REGION_NUM, BUF_REGION_SIZE ); + + buf_table = (BUF_T *)buf_region; + bufhdr_table = (BUFHDR_T *)(buf_table + NUM_BUFS); + buf_hash_table = (int *)(bufhdr_table + NUM_BUFS); + buf_lru = buf_hash_table + NUMTABLE_ENTRIES; + spinlockp = buf_lru + 1; + buf_fids = (FINFO_T *)(spinlockp+1); + buf_sp = (int *)(buf_fids + NUM_FILE_ENTRIES); + buf_strings = (char *)(buf_sp + 1); + + /* Create locking spinlock (gets creating holding the lock) */ + buf_spinlock = create_sem ( BUF_SPIN_NAME, BUF_SPIN_NUM, ref_count <= 1 ); + if ( buf_spinlock < 0 ) { + return(1); + } + if ( ref_count <= 1 ) { + *spinlockp = buf_spinlock; + + /* Now initialize the buffer manager */ + + /* 1. Free list */ + *buf_lru = 0; + + /* 2. Buffer headers */ + for ( i = 0, bhp = bufhdr_table; i < NUM_BUFS; bhp++, i++ ) { + bhp->lru.next = i+1; + bhp->lru.prev = i-1; + bhp->flags = 0; /* All Flags off */ + bhp->refcount = 0; + bhp->wait_proc = -1; /* No sleepers */ + LISTPE_INIT ( hash, bhp, i ); /* Hash chains */ + } + bufhdr_table[0].lru.prev = NUM_BUFS-1; + bufhdr_table[NUM_BUFS-1].lru.next = 0; + + /* 3. Hash Table */ + for ( i = 0; i < NUMTABLE_ENTRIES; i++ ) { + buf_hash_table[i] = NUM_BUFS; + } + + /* 4. File ID Table */ + for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) { + buf_fids[i].offset = -1; + buf_fids[i].npages = -1; + buf_fids[i].refcount = 0; + } + + /* 5. Free String Pointer */ + *buf_sp = (FILE_NAME_LEN*NUM_FILE_ENTRIES); + if (RELEASE_MASTER) { + return(1); + } + error_log0 ( "Initialized buffer region\n" ); + } + return (0); +} + +extern void +buf_exit() +{ + int ref; + int i; + + /* Flush Buffer Pool on Exit */ + for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) { + if ( fds[i] != -1 ) { + close ( fds[i] ); + } + } + if ( buf_table ) { + detach_region ( buf_table, BUF_REGION_NUM, BUF_REGION_SIZE, &ref ); + } + return; +} + +/* + We need an empty buffer. Find the LRU unpinned NON-Dirty page. +*/ +static BUFHDR_T * +bf_newbuf() +{ + int fd; + int lruid; + int nbytes; + int ndx; + BUFHDR_T *bhp; + + lruid = LRUID; + for ( bhp = LRUP; + bhp->flags & (BUF_PINNED|BUF_IO_IN_PROGRESS); + bhp = LISTP_NEXTP (bufhdr_table, lru, bhp ) ) { + + if ( bhp->lru.next == lruid ) { + /* OUT OF BUFFERS */ + error_log1 ( "All buffers are pinned. %s\n", + "Unable to grant buffer request" ); + return(NULL); + } + } + /* BHP can be used */ + if ( bhp->flags & BUF_DIRTY ) { + do_statistics = 1; + /* + MIS Check for log flushed appropriately + */ + fd = bf_fid_to_fd(bhp->id.file_id); + if ( fd == -1 ) { + error_log1 ("Invalid fid %d\n", bhp->id.file_id); + return(NULL); + } + if ( bf_put_page(fd, bhp) < 0 ) { + return(NULL); + } + } + /* Update Hash Pointers */ + ndx = BUF_HASH ( bhp->id.file_id, bhp->id.obj_id ); + LISTP_REMOVE(bufhdr_table, hash, bhp); + if ( buf_hash_table[ndx] == (bhp-bufhdr_table) ) { + if ( bhp->hash.next != (bhp-bufhdr_table) ) { + buf_hash_table[ndx] = bhp->hash.next; + } else { + buf_hash_table[ndx] = NUM_BUFS; + } + } + INIT_BUF(bhp); + + return(bhp); +} +/* + buf_alloc + + Add a page to a file and return a buffer for it. + +*/ +ADDR_T +buf_alloc ( fid, new_pageno ) +int fid; +int *new_pageno; +{ + BUFHDR_T *bhp; + int fd; + int len; + int ndx; + OBJ_T fobj; + + if (GET_MASTER) { + return(NULL); + } + if ( buf_fids[fid].npages == -1 ) { + /* initialize npages field */ + fd = bf_fid_to_fd ( fid ); + } + assert (fid < NUM_FILE_ENTRIES); + + *new_pageno = buf_fids[fid].npages; + if ( *new_pageno == -1 ) { + RELEASE_MASTER; + return ( NULL ); + } + buf_fids[fid].npages++; + ndx = BUF_HASH ( fid, *new_pageno ); + fobj.file_id = fid; + fobj.obj_id = *new_pageno; + bhp = bf_assign_buf ( ndx, &fobj, BF_PIN|BF_DIRTY|BF_EMPTY, &len ); + if ( RELEASE_MASTER ) { + /* Memory leak */ + return(NULL); + } + if ( bhp ) { + return ((ADDR_T)(buf_table+(bhp-bufhdr_table))); + } else { + return ( NULL ); + } +} + + +/* + Buffer Flags + BF_DIRTY Mark page as dirty + BF_EMPTY Don't initialize page, just get buffer + BF_PIN Retrieve with pin + +MIS +Might want to add a flag that sets an LSN for this buffer is the +DIRTY flag is set + +Eventually, you may want a flag that indicates the I/O and lock +request should be shipped off together, but not for now. +*/ +extern ADDR_T +buf_get ( file_id, page_id, flags, len ) +int file_id; +int page_id; +u_long flags; +int *len; /* Number of bytes read into buffer */ +{ + BUFHDR_T *bhp; + int bufid; + int fd; + int ndx; + int next_bufid; + int stat; + OBJ_T fobj; + + ndx = BUF_HASH ( file_id, page_id ); + fobj.file_id = (long) file_id; + fobj.obj_id = (long) page_id; + if ( GET_MASTER ) { + return(NULL); + } + /* + This could be a for loop, but we lose speed + by making all the cases general purpose so we + optimize for the no-collision case. + */ + bufid = buf_hash_table[ndx]; + if ( bufid < NUM_BUFS ) { + for ( bhp = bufhdr_table+bufid; + !OBJ_EQ (bhp->id, fobj) || !(bhp->flags & BUF_VALID); + bhp = LISTP_NEXTP ( bufhdr_table, hash, bhp ) ) { + + if ( bhp->hash.next == bufid ) { + goto not_found; + } + } +/* found */ + if ( flags & BF_PIN ) { + bhp->flags |= BUF_PINNED; + bhp->refcount++; +#ifdef PIN_DEBUG + fprintf(stderr, "buf_get: %X PINNED (%d)\n", + buf_table + (bhp-bufhdr_table), bhp->refcount); +#endif + } + if ( flags & BF_DIRTY ) { + bhp->flags |= BUF_DIRTY; + } + + while ( bhp->flags & BUF_IO_IN_PROGRESS ) { + /* MIS -- eventually err check here */ +#ifdef DEBUG + printf("About to sleep on %d (me: %d\n)\n", bhp->wait_proc, + my_txnp - txn_table); +#endif +#ifdef WAIT_STATS + buf_waits++; +#endif + stat = proc_sleep_on ( &(bhp->wait_proc), buf_spinlock ); + if ( stat ) { + /* Memory leak */ + return(NULL); + } + if (!( bhp->flags & BUF_IO_IN_PROGRESS) && + (!OBJ_EQ (bhp->id, fobj) || !(bhp->flags & BUF_VALID))) { + if (RELEASE_MASTER) + return(NULL); + return(buf_get ( file_id, page_id, flags, len )); + } + } + MAKE_MRU( bhp ); + *len = BUFSIZE; + } else { +not_found: + /* If you get here, the page isn't in the hash table */ + bhp = bf_assign_buf ( ndx, &fobj, flags, len ); + } + /* Common code between found and not found */ + + if ( bhp && bhp->flags & BUF_NEWPAGE ) { + *len = 0; + } + if (RELEASE_MASTER){ + /* Memory leak */ + return(NULL); + } + if ( bhp ) { + return ((ADDR_T)(buf_table+(bhp-bufhdr_table))); + } else { + return ( NULL ); + } +} + +/* + MIS - do I want to add file links to buffer pool? +*/ +extern int +buf_sync ( fid, close ) +int fid; +int close; /* should we dec refcount and possibly + invalidate all the buffers */ +{ + int i; + int fd; + int invalidate; + BUFHDR_T *bhp; + + if ( (fd = bf_fid_to_fd ( fid )) < 0 ) { + return(1); + } + if (GET_MASTER) { + return(1); + } + invalidate = (buf_fids[fid].refcount == 1 && close); + if ( invalidate ) + for ( bhp = bufhdr_table, i = 0; i < NUM_BUFS; bhp++, i++ ) { + if (bhp->id.file_id == fid) { + if ((bhp->flags & BF_DIRTY) && (bf_put_page( fd, bhp ) < 0)) { + return(1); + } + bhp->id.file_id = -1; + } + } + if (invalidate || close) + buf_fids[fid].refcount--; + + if (RELEASE_MASTER) { + return(1); + } + return(0); + + +} + +extern int +buf_flags ( addr, set_flags, unset_flags ) +ADDR_T addr; +u_long set_flags; +u_long unset_flags; +{ + int bufid; + BUFHDR_T *bhp; + +#ifdef PIN_DEBUG + fprintf(stderr, "buf_flags: %X setting %s%s%s%s%s releasing %s%s%s%s%s\n", + addr, + set_flags&BUF_DIRTY ? "DIRTY " : "", + set_flags&BUF_VALID ? "VALID " : "", + set_flags&BUF_PINNED ? "PINNED " : "", + set_flags&BUF_IO_ERROR ? "IO_ERROR " : "", + set_flags&BUF_IO_IN_PROGRESS ? "IO_IN_PROG " : "", + set_flags&BUF_NEWPAGE ? "NEWPAGE " : "", + unset_flags&BUF_DIRTY ? "DIRTY " : "", + unset_flags&BUF_VALID ? "VALID " : "", + unset_flags&BUF_PINNED ? "PINNED " : "", + unset_flags&BUF_IO_ERROR ? "IO_ERROR " : "", + unset_flags&BUF_IO_IN_PROGRESS ? "IO_IN_PROG " : "", + unset_flags&BUF_NEWPAGE ? "NEWPAGE " : "" ); +#endif + if (!ADDR_OK(addr)) { + error_log1 ( "buf_pin: Invalid Buffer Address %x\n", addr ); + return(1); + } + bufid = ((BUF_T *)addr) - buf_table; + assert ( bufid < NUM_BUFS); + bhp = &bufhdr_table[bufid]; + if (GET_MASTER) { + return(1); + } + bhp->flags |= set_flags; + if ( set_flags & BUF_PINNED ) { + bhp->refcount++; + } + if ( set_flags & BUF_DIRTY ) { + unset_flags |= BUF_NEWPAGE; + } + + if ( unset_flags & BUF_PINNED ) { + bhp->refcount--; + if ( bhp->refcount ) { + /* Turn off pin bit so it doesn't get unset */ + unset_flags &= ~BUF_PINNED; + } + } + bhp->flags &= ~unset_flags; + MAKE_MRU(bhp); + if (RELEASE_MASTER) { + return(1); + } + return(0); +} + +/* + Take a string name and produce an fid. + + returns -1 on error + + MIS -- this is a potential problem -- you keep actual names + here -- what if people run from different directories? +*/ +extern int +buf_name_lookup ( fname ) +char *fname; +{ + int i; + int fid; + int ndx; + + fid = -1; + if (GET_MASTER) { + return(-1); + } + for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) { + if ( buf_fids[i].offset == -1 ) { + fid = i; + } else { + if (!strcmp (fname, buf_strings+buf_fids[i].offset)) { + if (RELEASE_MASTER) { + return(-1); + } + buf_fids[i].refcount++; + return(i); + } + } + } + if ( fid == -1 ) { + error_log0 ( "No more file ID's\n" ); + } else { + ndx = *buf_sp - strlen(fname) - 1; + if ( ndx < 0 ) { + error_log0 ( "Out of string space\n" ); + fid = -1; + } else { + *buf_sp = ndx; + strcpy ( buf_strings+ndx, fname ); + buf_fids[fid].offset = ndx; + } + buf_fids[fid].refcount = 1; + } + if (RELEASE_MASTER) { + return(-1); + } + return(fid); +} + +static int +bf_fid_to_fd ( fid ) +int fid; +{ + struct stat sbuf; + + assert ( (fid < NUM_FILE_ENTRIES) && (buf_fids[fid].offset != -1) ); + if ( fds[fid] != -1 ) { + return(fds[fid]); + + } + fds[fid] = open ( buf_strings+buf_fids[fid].offset, O_RDWR|O_CREAT, + 0666 ); + if ( fds[fid] < 0 ) { + error_log3 ( "Error Opening File %s FID: %d FD: %d. Errno = %d\n", + buf_strings+buf_fids[fid].offset, fid, fds[fid], + errno ); + return(-1); + } + error_log3 ( "Opening File %s FID: %d FD: %d\n", + buf_strings+buf_fids[fid].offset, fid, fds[fid] ); + if ( buf_fids[fid].npages == -1 ) { + /* Initialize the npages field */ + if ( fstat ( fds[fid], &sbuf ) ) { + error_log3 ( "Error Fstating %s FID: %d. Errno = %d\n", + buf_strings+buf_fids[fid].offset, fid, errno ); + } else { + buf_fids[fid].npages = ( sbuf.st_size / BUFSIZE ); + } + } + + return ( fds[fid] ); +} + +static int +bf_put_page ( fd, bhp ) +int fd; +BUFHDR_T *bhp; +{ + int nbytes; + + assert ( (bhp-bufhdr_table) < NUM_BUFS ); + if ( lseek ( fd, bhp->id.obj_id << BUFSHIFT, L_SET ) < 0 ) { + return(-1); + } + bhp->flags |= BUF_IO_IN_PROGRESS; + if (RELEASE_MASTER) { + return(-1); + } + nbytes = write(fd, buf_table[bhp-bufhdr_table], BUFSIZE); + if (GET_MASTER) { + return(-2); + } + if ( nbytes < 0 ) { + error_log1 ("Write failed with error code %d\n", errno); + return(-1); + } else if ( nbytes != BUFSIZE ) { + error_log1 ("Short write: %d bytes of %d\n", nbytes, BUFSIZE ); + } + bhp->flags &= ~(BUF_DIRTY|BUF_IO_IN_PROGRESS); + return (0); +} + +static BUFHDR_T * +bf_assign_buf ( ndx, obj, flags, len ) +int ndx; +OBJ_T *obj; +u_long flags; +int *len; /* Number of bytes read */ +{ + BUFHDR_T *bhp; + int fd; + + assert ( obj->file_id < NUM_FILE_ENTRIES ); + bhp = bf_newbuf(); + if ( !bhp ) { + return(NULL); + } + OBJ_ASSIGN ( (*obj), bhp->id ); + if ( buf_hash_table[ndx] >= NUM_BUFS ) { + buf_hash_table[ndx] = bhp-bufhdr_table; + } else { + LISTPE_INSERT ( bufhdr_table, hash, bhp, buf_hash_table[ndx] ); + } + + bhp->flags |= BUF_VALID; + if ( flags & BF_PIN ) { + bhp->flags |= BUF_PINNED; + bhp->refcount++; +#ifdef PIN_DEBUG + fprintf(stderr, "bf_assign_buf: %X PINNED (%d)\n", + buf_table + (bhp-bufhdr_table), bhp->refcount); +#endif + } + fd = bf_fid_to_fd(obj->file_id); + if ( fd == -1 ) { + error_log1 ("Invalid fid %d\n", obj->file_id); + bhp->flags |= ~BUF_IO_ERROR; + return(NULL); + } + if ( obj->obj_id >= buf_fids[obj->file_id].npages) { + buf_fids[obj->file_id].npages = obj->obj_id+1; + *len = 0; + } else if ( flags & BF_EMPTY ) { + *len = 0; + } else { + bhp->flags |= BUF_IO_IN_PROGRESS; + if (RELEASE_MASTER) { + return(NULL); + } + if ( lseek ( fd, obj->obj_id << BUFSHIFT, L_SET ) < -1 ) { + error_log2 ("Unable to perform seek on file: %d to page %d", + obj->file_id, obj->obj_id ); + bhp->flags &= ~BUF_IO_IN_PROGRESS; + bhp->flags |= ~BUF_IO_ERROR; + return(NULL); + } + *len = read(fd, buf_table[bhp-bufhdr_table], BUFSIZE); + if ( *len < 0 ) { + error_log2 ("Unable to perform read on file: %d to page %d", + obj->file_id, obj->obj_id ); + bhp->flags &= ~BUF_IO_IN_PROGRESS; + bhp->flags |= ~BUF_IO_ERROR; + return(NULL); + } + if (GET_MASTER) { + return(NULL); + } + bhp->flags &= ~BUF_IO_IN_PROGRESS; + if ( bhp->wait_proc != -1 ) { + /* wake up waiter and anyone waiting on it */ +#ifdef DEBUG + printf("Waking transaction %d due to completed I/O\n", + bhp->wait_proc); +#endif + proc_wake_id ( bhp->wait_proc ); + bhp->wait_proc = -1; + } + MAKE_MRU(bhp); + } + + if ( flags & BF_DIRTY ) { + bhp->flags |= BUF_DIRTY; + } else if ( *len < BUFSIZE ) { + bhp->flags |= BUF_NEWPAGE; + } + return ( bhp ); +} + +int +buf_last ( fid ) +int fid; +{ + int val; + + if (GET_MASTER) { + return(-1); + } + assert ( fid < NUM_FILE_ENTRIES ); + if ( buf_fids[fid].npages == -1 ) { + /* initialize npages field */ + (void) bf_fid_to_fd ( fid ); + } + val = buf_fids[fid].npages; + if ( val ) { + val--; /* Convert to page number */ + } + if (RELEASE_MASTER) { + return(-1); + } + return(val); +} + +#ifdef DEBUG +extern void +buf_dump ( id, all ) +int id; +int all; +{ + int i; + BUFHDR_T *bhp; + + printf ( "LRU + %d\n", *buf_lru ); + if ( all ) { + printf("ID\tFID\tPID\tLNEXT\tLPREV\tHNEXT\tHPREV\tSLEEP\tFLAG\tREFS\n"); + for ( bhp = bufhdr_table, i = 0; i < NUM_BUFS; bhp++, i++ ) { + printf ( "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%x\t%d\n", i, + bhp->id.file_id, bhp->id.obj_id, + bhp->lru.next, bhp->lru.prev, + bhp->hash.next, bhp->hash.prev, + bhp->wait_proc, bhp->flags, bhp->refcount ); + } + } else { + if ( id >= NUM_BUFS ) { + printf ( "Buffer ID (%d) too high\n", id ); + return; + } + bhp = bufhdr_table+id; + printf ( "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%x\t%d\n", i, + bhp->id.file_id, bhp->id.obj_id, + bhp->lru.next, bhp->lru.prev, + bhp->hash.next, bhp->hash.prev, + bhp->wait_proc, bhp->flags, bhp->refcount ); + } + return; +} +#endif + diff --git a/circuitpython/lib/berkeley-db-1.xx/mpool/tags b/circuitpython/lib/berkeley-db-1.xx/mpool/tags new file mode 120000 index 0000000..7ab656b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/mpool/tags @@ -0,0 +1 @@ +../db/tags \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/Makefile.inc b/circuitpython/lib/berkeley-db-1.xx/recno/Makefile.inc new file mode 100644 index 0000000..e49e225 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/Makefile.inc @@ -0,0 +1,6 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 + +.PATH: ${.CURDIR}/db/recno + +SRCS+= rec_close.c rec_delete.c rec_get.c rec_open.c rec_put.c rec_search.c \ + rec_seq.c rec_utils.c diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/extern.h b/circuitpython/lib/berkeley-db-1.xx/recno/extern.h new file mode 100644 index 0000000..feed434 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/extern.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)extern.h 8.3 (Berkeley) 6/4/94 + */ + +#include "../btree/extern.h" + +int __rec_close __P((DB *)); +int __rec_delete __P((const DB *, const DBT *, u_int)); +int __rec_dleaf __P((BTREE *, PAGE *, u_int32_t)); +int __rec_fd __P((const DB *)); +int __rec_fmap __P((BTREE *, recno_t)); +int __rec_fout __P((BTREE *)); +int __rec_fpipe __P((BTREE *, recno_t)); +int __rec_get __P((const DB *, const DBT *, DBT *, u_int)); +int __rec_iput __P((BTREE *, recno_t, const DBT *, u_int)); +int __rec_put __P((const DB *dbp, DBT *, const DBT *, u_int)); +int __rec_ret __P((BTREE *, EPG *, recno_t, DBT *, DBT *)); +EPG *__rec_search __P((BTREE *, recno_t, enum SRCHOP)); +int __rec_seq __P((const DB *, DBT *, DBT *, u_int)); +int __rec_sync __P((const DB *, u_int)); +int __rec_vmap __P((BTREE *, recno_t)); +int __rec_vout __P((BTREE *)); +int __rec_vpipe __P((BTREE *, recno_t)); diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/rec_close.c b/circuitpython/lib/berkeley-db-1.xx/recno/rec_close.c new file mode 100644 index 0000000..16fb0b4 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/rec_close.c @@ -0,0 +1,182 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "recno.h" + +/* + * __REC_CLOSE -- Close a recno tree. + * + * Parameters: + * dbp: pointer to access method + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_close(dbp) + DB *dbp; +{ + BTREE *t; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + if (__rec_sync(dbp, 0) == RET_ERROR) + return (RET_ERROR); + + /* Committed to closing. */ + status = RET_SUCCESS; + if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize)) + status = RET_ERROR; + + if (!F_ISSET(t, R_INMEM)) + if (F_ISSET(t, R_CLOSEFP)) { + if (fclose(t->bt_rfp)) + status = RET_ERROR; + } else + if (close(t->bt_rfd)) + status = RET_ERROR; + + if (__bt_close(dbp) == RET_ERROR) + status = RET_ERROR; + + return (status); +} + +/* + * __REC_SYNC -- sync the recno tree to disk. + * + * Parameters: + * dbp: pointer to access method + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +int +__rec_sync(dbp, flags) + const DB *dbp; + u_int flags; +{ + struct iovec iov[2]; + BTREE *t; + DBT data, key; + off_t off; + recno_t scursor, trec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + if (flags == R_RECNOSYNC) + return (__bt_sync(dbp, 0)); + + if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED)) + return (RET_SUCCESS); + + /* Read any remaining records into the tree. */ + if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) + return (RET_ERROR); + + /* Rewind the file descriptor. */ + if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0) + return (RET_ERROR); + + /* Save the cursor. */ + scursor = t->bt_cursor.rcursor; + + key.size = sizeof(recno_t); + key.data = &trec; + + if (F_ISSET(t, R_FIXLEN)) { + /* + * We assume that fixed length records are all fixed length. + * Any that aren't are either EINVAL'd or corrected by the + * record put code. + */ + status = (dbp->seq)(dbp, &key, &data, R_FIRST); + while (status == RET_SUCCESS) { + if (write(t->bt_rfd, data.data, data.size) != data.size) + return (RET_ERROR); + status = (dbp->seq)(dbp, &key, &data, R_NEXT); + } + } else { + iov[1].iov_base = &t->bt_bval; + iov[1].iov_len = 1; + + status = (dbp->seq)(dbp, &key, &data, R_FIRST); + while (status == RET_SUCCESS) { + iov[0].iov_base = data.data; + iov[0].iov_len = data.size; + if (writev(t->bt_rfd, iov, 2) != data.size + 1) + return (RET_ERROR); + status = (dbp->seq)(dbp, &key, &data, R_NEXT); + } + } + + /* Restore the cursor. */ + t->bt_cursor.rcursor = scursor; + + if (status == RET_ERROR) + return (RET_ERROR); + if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1) + return (RET_ERROR); + if (ftruncate(t->bt_rfd, off)) + return (RET_ERROR); + F_CLR(t, R_MODIFIED); + return (RET_SUCCESS); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/rec_delete.c b/circuitpython/lib/berkeley-db-1.xx/recno/rec_delete.c new file mode 100644 index 0000000..a16593d --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/rec_delete.c @@ -0,0 +1,197 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rec_delete.c 8.7 (Berkeley) 7/14/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include + +#include +#include "recno.h" + +static int rec_rdelete __P((BTREE *, recno_t)); + +/* + * __REC_DELETE -- Delete the item(s) referenced by a key. + * + * Parameters: + * dbp: pointer to access method + * key: key to delete + * flags: R_CURSOR if deleting what the cursor references + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. + */ +int +__rec_delete(dbp, key, flags) + const DB *dbp; + const DBT *key; + u_int flags; +{ + BTREE *t; + recno_t nrec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + switch(flags) { + case 0: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + if (nrec > t->bt_nrecs) + return (RET_SPECIAL); + --nrec; + status = rec_rdelete(t, nrec); + break; + case R_CURSOR: + if (!F_ISSET(&t->bt_cursor, CURS_INIT)) + goto einval; + if (t->bt_nrecs == 0) + return (RET_SPECIAL); + status = rec_rdelete(t, t->bt_cursor.rcursor - 1); + if (status == RET_SUCCESS) + --t->bt_cursor.rcursor; + break; + default: +einval: errno = EINVAL; + return (RET_ERROR); + } + + if (status == RET_SUCCESS) + F_SET(t, B_MODIFIED | R_MODIFIED); + return (status); +} + +/* + * REC_RDELETE -- Delete the data matching the specified key. + * + * Parameters: + * tree: tree + * nrec: record to delete + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. + */ +static int +rec_rdelete(t, nrec) + BTREE *t; + recno_t nrec; +{ + EPG *e; + PAGE *h; + int status; + + /* Find the record; __rec_search pins the page. */ + if ((e = __rec_search(t, nrec, SDELETE)) == NULL) + return (RET_ERROR); + + /* Delete the record. */ + h = e->page; + status = __rec_dleaf(t, h, e->index); + if (status != RET_SUCCESS) { + mpool_put(t->bt_mp, h, 0); + return (status); + } + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + return (RET_SUCCESS); +} + +/* + * __REC_DLEAF -- Delete a single record from a recno leaf page. + * + * Parameters: + * t: tree + * index: index on current page to delete + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +int +__rec_dleaf(t, h, index) + BTREE *t; + PAGE *h; + u_int32_t index; +{ + RLEAF *rl; + indx_t *ip, cnt, offset; + u_int32_t nbytes; + char *from; + void *to; + + /* + * Delete a record from a recno leaf page. Internal records are never + * deleted from internal pages, regardless of the records that caused + * them to be added being deleted. Pages made empty by deletion are + * not reclaimed. They are, however, made available for reuse. + * + * Pack the remaining entries at the end of the page, shift the indices + * down, overwriting the deleted record and its index. If the record + * uses overflow pages, make them available for reuse. + */ + to = rl = GETRLEAF(h, index); + if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR) + return (RET_ERROR); + nbytes = NRLEAF(rl); + + /* + * Compress the key/data pairs. Compress and adjust the [BR]LEAF + * offsets. Reset the headers. + */ + from = (char *)h + h->upper; + memmove(from + nbytes, from, (char *)to - from); + h->upper += nbytes; + + offset = h->linp[index]; + for (cnt = &h->linp[index] - (ip = &h->linp[0]); cnt--; ++ip) + if (ip[0] < offset) + ip[0] += nbytes; + for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip) + ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1]; + h->lower -= sizeof(indx_t); + --t->bt_nrecs; + return (RET_SUCCESS); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/rec_get.c b/circuitpython/lib/berkeley-db-1.xx/recno/rec_get.c new file mode 100644 index 0000000..47dd773 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/rec_get.c @@ -0,0 +1,311 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "recno.h" + +/* + * __REC_GET -- Get a record from the btree. + * + * Parameters: + * dbp: pointer to access method + * key: key to find + * data: data to return + * flag: currently unused + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. + */ +int +__rec_get(dbp, key, data, flags) + const DB *dbp; + const DBT *key; + DBT *data; + u_int flags; +{ + BTREE *t; + EPG *e; + recno_t nrec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Get currently doesn't take any flags, and keys of 0 are illegal. */ + if (flags || (nrec = *(recno_t *)key->data) == 0) { + errno = EINVAL; + return (RET_ERROR); + } + + /* + * If we haven't seen this record yet, try to find it in the + * original file. + */ + if (nrec > t->bt_nrecs) { + if (F_ISSET(t, R_EOF | R_INMEM)) + return (RET_SPECIAL); + if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS) + return (status); + } + + --nrec; + if ((e = __rec_search(t, nrec, SEARCH)) == NULL) + return (RET_ERROR); + + status = __rec_ret(t, e, 0, NULL, data); + if (F_ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; + return (status); +} + +/* + * __REC_FPIPE -- Get fixed length records from a pipe. + * + * Parameters: + * t: tree + * cnt: records to read + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_fpipe(t, top) + BTREE *t; + recno_t top; +{ + DBT data; + recno_t nrec; + size_t len; + int ch; + u_char *p; + + if (t->bt_rdata.size < t->bt_reclen) { + t->bt_rdata.data = t->bt_rdata.data == NULL ? + malloc(t->bt_reclen) : + realloc(t->bt_rdata.data, t->bt_reclen); + if (t->bt_rdata.data == NULL) + return (RET_ERROR); + t->bt_rdata.size = t->bt_reclen; + } + data.data = t->bt_rdata.data; + data.size = t->bt_reclen; + + for (nrec = t->bt_nrecs; nrec < top;) { + len = t->bt_reclen; + for (p = t->bt_rdata.data;; *p++ = ch) + if ((ch = getc(t->bt_rfp)) == EOF || !--len) { + if (ch != EOF) + *p = ch; + if (len != 0) + memset(p, t->bt_bval, len); + if (__rec_iput(t, + nrec, &data, 0) != RET_SUCCESS) + return (RET_ERROR); + ++nrec; + break; + } + if (ch == EOF) + break; + } + if (nrec < top) { + F_SET(t, R_EOF); + return (RET_SPECIAL); + } + return (RET_SUCCESS); +} + +/* + * __REC_VPIPE -- Get variable length records from a pipe. + * + * Parameters: + * t: tree + * cnt: records to read + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_vpipe(t, top) + BTREE *t; + recno_t top; +{ + DBT data; + recno_t nrec; + indx_t len; + size_t sz; + int bval, ch; + u_char *p; + + bval = t->bt_bval; + for (nrec = t->bt_nrecs; nrec < top; ++nrec) { + for (p = t->bt_rdata.data, + sz = t->bt_rdata.size;; *p++ = ch, --sz) { + if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { + data.data = t->bt_rdata.data; + data.size = p - (u_char *)t->bt_rdata.data; + if (ch == EOF && data.size == 0) + break; + if (__rec_iput(t, nrec, &data, 0) + != RET_SUCCESS) + return (RET_ERROR); + break; + } + if (sz == 0) { + len = p - (u_char *)t->bt_rdata.data; + t->bt_rdata.size += (sz = 256); + t->bt_rdata.data = t->bt_rdata.data == NULL ? + malloc(t->bt_rdata.size) : + realloc(t->bt_rdata.data, t->bt_rdata.size); + if (t->bt_rdata.data == NULL) + return (RET_ERROR); + p = (u_char *)t->bt_rdata.data + len; + } + } + if (ch == EOF) + break; + } + if (nrec < top) { + F_SET(t, R_EOF); + return (RET_SPECIAL); + } + return (RET_SUCCESS); +} + +/* + * __REC_FMAP -- Get fixed length records from a file. + * + * Parameters: + * t: tree + * cnt: records to read + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_fmap(t, top) + BTREE *t; + recno_t top; +{ + DBT data; + recno_t nrec; + u_char *sp, *ep, *p; + size_t len; + + if (t->bt_rdata.size < t->bt_reclen) { + t->bt_rdata.data = t->bt_rdata.data == NULL ? + malloc(t->bt_reclen) : + realloc(t->bt_rdata.data, t->bt_reclen); + if (t->bt_rdata.data == NULL) + return (RET_ERROR); + t->bt_rdata.size = t->bt_reclen; + } + data.data = t->bt_rdata.data; + data.size = t->bt_reclen; + + sp = (u_char *)t->bt_cmap; + ep = (u_char *)t->bt_emap; + for (nrec = t->bt_nrecs; nrec < top; ++nrec) { + if (sp >= ep) { + F_SET(t, R_EOF); + return (RET_SPECIAL); + } + len = t->bt_reclen; + for (p = t->bt_rdata.data; + sp < ep && len > 0; *p++ = *sp++, --len); + if (len != 0) + memset(p, t->bt_bval, len); + if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) + return (RET_ERROR); + } + t->bt_cmap = (caddr_t)sp; + return (RET_SUCCESS); +} + +/* + * __REC_VMAP -- Get variable length records from a file. + * + * Parameters: + * t: tree + * cnt: records to read + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_vmap(t, top) + BTREE *t; + recno_t top; +{ + DBT data; + u_char *sp, *ep; + recno_t nrec; + int bval; + + sp = (u_char *)t->bt_cmap; + ep = (u_char *)t->bt_emap; + bval = t->bt_bval; + + for (nrec = t->bt_nrecs; nrec < top; ++nrec) { + if (sp >= ep) { + F_SET(t, R_EOF); + return (RET_SPECIAL); + } + for (data.data = sp; sp < ep && *sp != bval; ++sp); + data.size = sp - (u_char *)data.data; + if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) + return (RET_ERROR); + ++sp; + } + t->bt_cmap = (caddr_t)sp; + return (RET_SUCCESS); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/rec_open.c b/circuitpython/lib/berkeley-db-1.xx/recno/rec_open.c new file mode 100644 index 0000000..51d8a3c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/rec_open.c @@ -0,0 +1,241 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rec_open.c 8.10 (Berkeley) 9/1/94"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "recno.h" + +DB * +__rec_open(fname, flags, mode, openinfo, dflags) + const char *fname; + int flags, mode, dflags; + const RECNOINFO *openinfo; +{ + BTREE *t; + BTREEINFO btopeninfo; + DB *dbp; + PAGE *h; + struct stat sb; + int rfd, sverrno; + + /* Open the user's file -- if this fails, we're done. */ + if (fname != NULL && (rfd = open(fname, flags, mode)) < 0) + return (NULL); + + /* Create a btree in memory (backed by disk). */ + dbp = NULL; + if (openinfo) { + if (openinfo->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT)) + goto einval; + btopeninfo.flags = 0; + btopeninfo.cachesize = openinfo->cachesize; + btopeninfo.maxkeypage = 0; + btopeninfo.minkeypage = 0; + btopeninfo.psize = openinfo->psize; + btopeninfo.compare = NULL; + btopeninfo.prefix = NULL; + btopeninfo.lorder = openinfo->lorder; + dbp = __bt_open(openinfo->bfname, + O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags); + } else + dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags); + if (dbp == NULL) + goto err; + + /* + * Some fields in the tree structure are recno specific. Fill them + * in and make the btree structure look like a recno structure. We + * don't change the bt_ovflsize value, it's close enough and slightly + * bigger. + */ + t = dbp->internal; + if (openinfo) { + if (openinfo->flags & R_FIXEDLEN) { + F_SET(t, R_FIXLEN); + t->bt_reclen = openinfo->reclen; + if (t->bt_reclen == 0) + goto einval; + } + t->bt_bval = openinfo->bval; + } else + t->bt_bval = '\n'; + + F_SET(t, R_RECNO); + if (fname == NULL) + F_SET(t, R_EOF | R_INMEM); + else + t->bt_rfd = rfd; + + if (fname != NULL) { + /* + * In 4.4BSD, stat(2) returns true for ISSOCK on pipes. + * Unfortunately, that's not portable, so we use lseek + * and check the errno values. + */ + errno = 0; + if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) { + switch (flags & O_ACCMODE) { + case O_RDONLY: + F_SET(t, R_RDONLY); + break; + default: + goto einval; + } +slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL) + goto err; + F_SET(t, R_CLOSEFP); + t->bt_irec = + F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe; + } else { + switch (flags & O_ACCMODE) { + case O_RDONLY: + F_SET(t, R_RDONLY); + break; + case O_RDWR: + break; + default: + goto einval; + } + + if (fstat(rfd, &sb)) + goto err; + /* + * Kluge -- we'd like to test to see if the file is too + * big to mmap. Since, we don't know what size or type + * off_t's or size_t's are, what the largest unsigned + * integral type is, or what random insanity the local + * C compiler will perpetrate, doing the comparison in + * a portable way is flatly impossible. Hope that mmap + * fails if the file is too large. + */ + if (sb.st_size == 0) + F_SET(t, R_EOF); + else { +#ifdef MMAP_NOT_AVAILABLE + /* + * XXX + * Mmap doesn't work correctly on many current + * systems. In particular, it can fail subtly, + * with cache coherency problems. Don't use it + * for now. + */ + t->bt_msize = sb.st_size; + if ((t->bt_smap = mmap(NULL, t->bt_msize, + PROT_READ, MAP_PRIVATE, rfd, + (off_t)0)) == (caddr_t)-1) + goto slow; + t->bt_cmap = t->bt_smap; + t->bt_emap = t->bt_smap + sb.st_size; + t->bt_irec = F_ISSET(t, R_FIXLEN) ? + __rec_fmap : __rec_vmap; + F_SET(t, R_MEMMAPPED); +#else + goto slow; +#endif + } + } + } + + /* Use the recno routines. */ + dbp->close = __rec_close; + dbp->del = __rec_delete; + dbp->fd = __rec_fd; + dbp->get = __rec_get; + dbp->put = __rec_put; + dbp->seq = __rec_seq; + dbp->sync = __rec_sync; + + /* If the root page was created, reset the flags. */ + if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL) + goto err; + if ((h->flags & P_TYPE) == P_BLEAF) { + F_CLR(h, P_TYPE); + F_SET(h, P_RLEAF); + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + } else + mpool_put(t->bt_mp, h, 0); + + if (openinfo && openinfo->flags & R_SNAPSHOT && + !F_ISSET(t, R_EOF | R_INMEM) && + t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) + goto err; + return (dbp); + +einval: errno = EINVAL; +err: sverrno = errno; + if (dbp != NULL) + (void)__bt_close(dbp); + if (fname != NULL) + (void)close(rfd); + errno = sverrno; + return (NULL); +} + +int +__rec_fd(dbp) + const DB *dbp; +{ + BTREE *t; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* In-memory database can't have a file descriptor. */ + if (F_ISSET(t, R_INMEM)) { + errno = ENOENT; + return (-1); + } + return (t->bt_rfd); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/rec_put.c b/circuitpython/lib/berkeley-db-1.xx/recno/rec_put.c new file mode 100644 index 0000000..1afae0d --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/rec_put.c @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include +#include + +#include +#include "recno.h" + +/* + * __REC_PUT -- Add a recno item to the tree. + * + * Parameters: + * dbp: pointer to access method + * key: key + * data: data + * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is + * already in the tree and R_NOOVERWRITE specified. + */ +int +__rec_put(dbp, key, data, flags) + const DB *dbp; + DBT *key; + const DBT *data; + u_int flags; +{ + BTREE *t; + DBT fdata, tdata; + recno_t nrec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* + * If using fixed-length records, and the record is long, return + * EINVAL. If it's short, pad it out. Use the record data return + * memory, it's only short-term. + */ + if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) { + if (data->size > t->bt_reclen) + goto einval; + + if (t->bt_rdata.size < t->bt_reclen) { + t->bt_rdata.data = t->bt_rdata.data == NULL ? + malloc(t->bt_reclen) : + realloc(t->bt_rdata.data, t->bt_reclen); + if (t->bt_rdata.data == NULL) + return (RET_ERROR); + t->bt_rdata.size = t->bt_reclen; + } + memmove(t->bt_rdata.data, data->data, data->size); + memset((char *)t->bt_rdata.data + data->size, + t->bt_bval, t->bt_reclen - data->size); + fdata.data = t->bt_rdata.data; + fdata.size = t->bt_reclen; + } else { + fdata.data = data->data; + fdata.size = data->size; + } + + switch (flags) { + case R_CURSOR: + if (!F_ISSET(&t->bt_cursor, CURS_INIT)) + goto einval; + nrec = t->bt_cursor.rcursor; + break; + case R_SETCURSOR: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + break; + case R_IAFTER: + if ((nrec = *(recno_t *)key->data) == 0) { + nrec = 1; + flags = R_IBEFORE; + } + break; + case 0: + case R_IBEFORE: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + break; + case R_NOOVERWRITE: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + if (nrec <= t->bt_nrecs) + return (RET_SPECIAL); + break; + default: +einval: errno = EINVAL; + return (RET_ERROR); + } + + /* + * Make sure that records up to and including the put record are + * already in the database. If skipping records, create empty ones. + */ + if (nrec > t->bt_nrecs) { + if (!F_ISSET(t, R_EOF | R_INMEM) && + t->bt_irec(t, nrec) == RET_ERROR) + return (RET_ERROR); + if (nrec > t->bt_nrecs + 1) { + if (F_ISSET(t, R_FIXLEN)) { + if ((tdata.data = + (void *)malloc(t->bt_reclen)) == NULL) + return (RET_ERROR); + tdata.size = t->bt_reclen; + memset(tdata.data, t->bt_bval, tdata.size); + } else { + tdata.data = NULL; + tdata.size = 0; + } + while (nrec > t->bt_nrecs + 1) + if (__rec_iput(t, + t->bt_nrecs, &tdata, 0) != RET_SUCCESS) + return (RET_ERROR); + if (F_ISSET(t, R_FIXLEN)) + free(tdata.data); + } + } + + if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS) + return (status); + + if (flags == R_SETCURSOR) + t->bt_cursor.rcursor = nrec; + + F_SET(t, R_MODIFIED); + return (__rec_ret(t, NULL, nrec, key, NULL)); +} + +/* + * __REC_IPUT -- Add a recno item to the tree. + * + * Parameters: + * t: tree + * nrec: record number + * data: data + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_iput(t, nrec, data, flags) + BTREE *t; + recno_t nrec; + const DBT *data; + u_int flags; +{ + DBT tdata; + EPG *e; + PAGE *h; + indx_t index, nxtindex; + pgno_t pg; + u_int32_t nbytes; + int dflags, status; + char *dest, db[NOVFLSIZE]; + + /* + * If the data won't fit on a page, store it on indirect pages. + * + * XXX + * If the insert fails later on, these pages aren't recovered. + */ + if (data->size > t->bt_ovflsize) { + if (__ovfl_put(t, data, &pg) == RET_ERROR) + return (RET_ERROR); + tdata.data = db; + tdata.size = NOVFLSIZE; + *(pgno_t *)db = pg; + *(u_int32_t *)(db + sizeof(pgno_t)) = data->size; + dflags = P_BIGDATA; + data = &tdata; + } else + dflags = 0; + + /* __rec_search pins the returned page. */ + if ((e = __rec_search(t, nrec, + nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ? + SINSERT : SEARCH)) == NULL) + return (RET_ERROR); + + h = e->page; + index = e->index; + + /* + * Add the specified key/data pair to the tree. The R_IAFTER and + * R_IBEFORE flags insert the key after/before the specified key. + * + * Pages are split as required. + */ + switch (flags) { + case R_IAFTER: + ++index; + break; + case R_IBEFORE: + break; + default: + if (nrec < t->bt_nrecs && + __rec_dleaf(t, h, index) == RET_ERROR) { + mpool_put(t->bt_mp, h, 0); + return (RET_ERROR); + } + break; + } + + /* + * If not enough room, split the page. The split code will insert + * the key and data and unpin the current page. If inserting into + * the offset array, shift the pointers up. + */ + nbytes = NRLEAFDBT(data->size); + if (h->upper - h->lower < nbytes + sizeof(indx_t)) { + status = __bt_split(t, h, NULL, data, dflags, nbytes, index); + if (status == RET_SUCCESS) + ++t->bt_nrecs; + return (status); + } + + if (index < (nxtindex = NEXTINDEX(h))) + memmove(h->linp + index + 1, h->linp + index, + (nxtindex - index) * sizeof(indx_t)); + h->lower += sizeof(indx_t); + + h->linp[index] = h->upper -= nbytes; + dest = (char *)h + h->upper; + WR_RLEAF(dest, data, dflags); + + ++t->bt_nrecs; + F_SET(t, B_MODIFIED); + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + + return (RET_SUCCESS); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/rec_search.c b/circuitpython/lib/berkeley-db-1.xx/recno/rec_search.c new file mode 100644 index 0000000..acc109e --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/rec_search.c @@ -0,0 +1,126 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include + +#include +#include "recno.h" + +/* + * __REC_SEARCH -- Search a btree for a key. + * + * Parameters: + * t: tree to search + * recno: key to find + * op: search operation + * + * Returns: + * EPG for matching record, if any, or the EPG for the location of the + * key, if it were inserted into the tree. + * + * Returns: + * The EPG for matching record, if any, or the EPG for the location + * of the key, if it were inserted into the tree, is entered into + * the bt_cur field of the tree. A pointer to the field is returned. + */ +EPG * +__rec_search(t, recno, op) + BTREE *t; + recno_t recno; + enum SRCHOP op; +{ + register indx_t index; + register PAGE *h; + EPGNO *parent; + RINTERNAL *r; + pgno_t pg; + indx_t top; + recno_t total; + int sverrno; + + BT_CLR(t); + for (pg = P_ROOT, total = 0;;) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + goto err; + if (h->flags & P_RLEAF) { + t->bt_cur.page = h; + t->bt_cur.index = recno - total; + return (&t->bt_cur); + } + for (index = 0, top = NEXTINDEX(h);;) { + r = GETRINTERNAL(h, index); + if (++index == top || total + r->nrecs > recno) + break; + total += r->nrecs; + } + + BT_PUSH(t, pg, index - 1); + + pg = r->pgno; + switch (op) { + case SDELETE: + --GETRINTERNAL(h, (index - 1))->nrecs; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + break; + case SINSERT: + ++GETRINTERNAL(h, (index - 1))->nrecs; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + break; + case SEARCH: + mpool_put(t->bt_mp, h, 0); + break; + } + + } + /* Try and recover the tree. */ +err: sverrno = errno; + if (op != SEARCH) + while ((parent = BT_POP(t)) != NULL) { + if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) + break; + if (op == SINSERT) + --GETRINTERNAL(h, parent->index)->nrecs; + else + ++GETRINTERNAL(h, parent->index)->nrecs; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + } + errno = sverrno; + return (NULL); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/rec_seq.c b/circuitpython/lib/berkeley-db-1.xx/recno/rec_seq.c new file mode 100644 index 0000000..f80992c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/rec_seq.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char sccsid[] = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94"; +#endif /* not lint */ + +#include + +#include +#include +#include +#include + +#include +#include "recno.h" + +/* + * __REC_SEQ -- Recno sequential scan interface. + * + * Parameters: + * dbp: pointer to access method + * key: key for positioning and return value + * data: data return value + * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV. + * + * Returns: + * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. + */ +int +__rec_seq(dbp, key, data, flags) + const DB *dbp; + DBT *key, *data; + u_int flags; +{ + BTREE *t; + EPG *e; + recno_t nrec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + switch(flags) { + case R_CURSOR: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + break; + case R_NEXT: + if (F_ISSET(&t->bt_cursor, CURS_INIT)) { + nrec = t->bt_cursor.rcursor + 1; + break; + } + /* FALLTHROUGH */ + case R_FIRST: + nrec = 1; + break; + case R_PREV: + if (F_ISSET(&t->bt_cursor, CURS_INIT)) { + if ((nrec = t->bt_cursor.rcursor - 1) == 0) + return (RET_SPECIAL); + break; + } + /* FALLTHROUGH */ + case R_LAST: + if (!F_ISSET(t, R_EOF | R_INMEM) && + t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) + return (RET_ERROR); + nrec = t->bt_nrecs; + break; + default: +einval: errno = EINVAL; + return (RET_ERROR); + } + + if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) { + if (!F_ISSET(t, R_EOF | R_INMEM) && + (status = t->bt_irec(t, nrec)) != RET_SUCCESS) + return (status); + if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) + return (RET_SPECIAL); + } + + if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL) + return (RET_ERROR); + + F_SET(&t->bt_cursor, CURS_INIT); + t->bt_cursor.rcursor = nrec; + + status = __rec_ret(t, e, nrec, key, data); + if (F_ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; + return (status); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/rec_utils.c b/circuitpython/lib/berkeley-db-1.xx/recno/rec_utils.c new file mode 100644 index 0000000..baea3fa --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/rec_utils.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rec_utils.c 8.6 (Berkeley) 7/16/94"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include +#include +#include + +#include +#include "recno.h" + +/* + * __rec_ret -- + * Build return data. + * + * Parameters: + * t: tree + * e: key/data pair to be returned + * nrec: record number + * key: user's key structure + * data: user's data structure + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +int +__rec_ret(t, e, nrec, key, data) + BTREE *t; + EPG *e; + recno_t nrec; + DBT *key, *data; +{ + RLEAF *rl; + void *p; + + if (key == NULL) + goto dataonly; + + /* We have to copy the key, it's not on the page. */ + if (sizeof(recno_t) > t->bt_rkey.size) { + p = (void *)(t->bt_rkey.data == NULL ? + malloc(sizeof(recno_t)) : + realloc(t->bt_rkey.data, sizeof(recno_t))); + if (p == NULL) + return (RET_ERROR); + t->bt_rkey.data = p; + t->bt_rkey.size = sizeof(recno_t); + } + memmove(t->bt_rkey.data, &nrec, sizeof(recno_t)); + key->size = sizeof(recno_t); + key->data = t->bt_rkey.data; + +dataonly: + if (data == NULL) + return (RET_SUCCESS); + + /* + * We must copy big keys/data to make them contigous. Otherwise, + * leave the page pinned and don't copy unless the user specified + * concurrent access. + */ + rl = GETRLEAF(e->page, e->index); + if (rl->flags & P_BIGDATA) { + if (__ovfl_get(t, rl->bytes, + &data->size, &t->bt_rdata.data, &t->bt_rdata.size)) + return (RET_ERROR); + data->data = t->bt_rdata.data; + } else if (F_ISSET(t, B_DB_LOCK)) { + /* Use +1 in case the first record retrieved is 0 length. */ + if (rl->dsize + 1 > t->bt_rdata.size) { + p = (void *)(t->bt_rdata.data == NULL ? + malloc(rl->dsize + 1) : + realloc(t->bt_rdata.data, rl->dsize + 1)); + if (p == NULL) + return (RET_ERROR); + t->bt_rdata.data = p; + t->bt_rdata.size = rl->dsize + 1; + } + memmove(t->bt_rdata.data, rl->bytes, rl->dsize); + data->size = rl->dsize; + data->data = t->bt_rdata.data; + } else { + data->size = rl->dsize; + data->data = rl->bytes; + } + return (RET_SUCCESS); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/recno.h b/circuitpython/lib/berkeley-db-1.xx/recno/recno.h new file mode 100644 index 0000000..bec772c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/recno.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)recno.h 8.1 (Berkeley) 6/4/93 + */ + +enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */ + +#include "../btree/btree.h" +#include "extern.h" diff --git a/circuitpython/lib/berkeley-db-1.xx/recno/tags b/circuitpython/lib/berkeley-db-1.xx/recno/tags new file mode 120000 index 0000000..7ab656b --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/recno/tags @@ -0,0 +1 @@ +../db/tags \ No newline at end of file diff --git a/circuitpython/lib/berkeley-db-1.xx/test/Makefile b/circuitpython/lib/berkeley-db-1.xx/test/Makefile new file mode 100644 index 0000000..a5dd08a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/Makefile @@ -0,0 +1,23 @@ +# @(#)Makefile 8.15 (Berkeley) 7/28/94 + +PROG= dbtest +OBJS= dbtest.o strerror.o + +# Uncomment the STAT line get hash and btree statistical use info. This +# also forces ld to load the btree debug functions for use by gdb, which +# is useful. The db library has to be compiled with -DSTATISTICS as well. +INC= -I${PORTDIR}/include -I${PORTDIR} +OORG= -g +#STAT= -DSTATISTICS +CFLAGS= -D__DBINTERFACE_PRIVATE -DDEBUG ${STAT} ${OORG} ${INC} + +dbtest: ${OBJS} ${PORTDIR}/libdb.a + ${CC} -o $@ ${OBJS} ${PORTDIR}/libdb.a + +strerror.o: ${PORTDIR}/clib/strerror.c + ${CC} -c ${PORTDIR}/clib/strerror.c + +clean: + rm -f dbtest.core gmon.out ${OBJS} ${PROG} t1 t2 t3 + +${OBJS}: Makefile diff --git a/circuitpython/lib/berkeley-db-1.xx/test/README b/circuitpython/lib/berkeley-db-1.xx/test/README new file mode 100644 index 0000000..0c0cd13 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/README @@ -0,0 +1,74 @@ +# @(#)README 8.8 (Berkeley) 7/31/94 + +To build this portably, try something like: + + make PORTDIR="../PORT/MACH" + +where MACH is the machine, i.e. "sunos.4.1.1". + +To run the tests, enter "sh run.test". If your system dictionary isn't +in /usr/share/dict/words, edit run.test to reflect the correct place. + +Fairly large files (the command files) are built in this directory during +the test runs, and even larger files (the database files) are created in +"/var/tmp". If the latter directory doesn't exist, set the environmental +variable TMPDIR to a directory where the files can be built. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +The script file consists of lines with an initial character which is +the command for that line, or an initial character indicating a key +or data entry for a previous command. + +Legal command characters are as follows: + +c: compare a record + + must be followed by [kK][dD]; the data value in the database + associated with the specified key is compared to the specified + data value. +e: echo a string + + writes out the rest of the line into the output file; if the + last character is not a carriage-return, a newline is appended. +f: set the flags for the next command + + no value zero's the flags +g: do a get command + + must be followed by [kK] + + writes out the retrieved data DBT. +o [r]: dump [reverse] + + dump the database out, if 'r' is set, in reverse order. +p: do a put command + + must be followed by [kK][dD] +r: do a del command + + must be followed by [kK] unless R_CURSOR flag set. +S: sync the database +s: do a seq command + + must be followed by [kK] if R_CURSOR flag set. + + writes out the retrieved data DBT. + +Legal key/data characters are as follows: + +D [file]: data file + + set the current data value to the contents of the file +d [data]: + + set the current key value to the contents of the line. +K [file]: key file + + set the current key value to the contents of the file +k [data]: + + set the current key value to the contents of the line. + +Blank lines, lines with leading white space, and lines with leading +hash marks (#) are ignored. + +Options to dbtest are as follows: + + -d: Set the DB_LOCK flag. + -f: Use the file argument as the database file. + -i: Use the rest of the argument to set elements in the info + structure. If the type is btree, then "-i cachesize=10240" + will set BTREEINFO.cachesize to 10240. + -o: The rest of the argument is the output file instead of + using stdout. + -s: Don't delete the database file before opening it, i.e. + use the database file from a previous run. + +Dbtest requires two arguments, the type of access "hash", "recno" +or "btree", and the script name or "-" to indicate stdin. diff --git a/circuitpython/lib/berkeley-db-1.xx/test/btree.tests/main.c b/circuitpython/lib/berkeley-db-1.xx/test/btree.tests/main.c new file mode 100644 index 0000000..f26e193 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/btree.tests/main.c @@ -0,0 +1,765 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "btree.h" + +typedef struct cmd_table { + char *cmd; + int nargs; + int rconv; + void (*func) __P((DB *, char **)); + char *usage, *descrip; +} cmd_table; + +int stopstop; +DB *globaldb; + +void append __P((DB *, char **)); +void bstat __P((DB *, char **)); +void cursor __P((DB *, char **)); +void delcur __P((DB *, char **)); +void delete __P((DB *, char **)); +void dump __P((DB *, char **)); +void first __P((DB *, char **)); +void get __P((DB *, char **)); +void help __P((DB *, char **)); +void iafter __P((DB *, char **)); +void ibefore __P((DB *, char **)); +void icursor __P((DB *, char **)); +void insert __P((DB *, char **)); +void keydata __P((DBT *, DBT *)); +void last __P((DB *, char **)); +void list __P((DB *, char **)); +void load __P((DB *, char **)); +void mstat __P((DB *, char **)); +void next __P((DB *, char **)); +int parse __P((char *, char **, int)); +void previous __P((DB *, char **)); +void show __P((DB *, char **)); +void usage __P((void)); +void user __P((DB *)); + +cmd_table commands[] = { + "?", 0, 0, help, "help", NULL, + "a", 2, 1, append, "append key def", "append key with data def", + "b", 0, 0, bstat, "bstat", "stat btree", + "c", 1, 1, cursor, "cursor word", "move cursor to word", + "delc", 0, 0, delcur, "delcur", "delete key the cursor references", + "dele", 1, 1, delete, "delete word", "delete word", + "d", 0, 0, dump, "dump", "dump database", + "f", 0, 0, first, "first", "move cursor to first record", + "g", 1, 1, get, "get key", "locate key", + "h", 0, 0, help, "help", "print command summary", + "ia", 2, 1, iafter, "iafter key data", "insert data after key", + "ib", 2, 1, ibefore, "ibefore key data", "insert data before key", + "ic", 2, 1, icursor, "icursor key data", "replace cursor", + "in", 2, 1, insert, "insert key def", "insert key with data def", + "la", 0, 0, last, "last", "move cursor to last record", + "li", 1, 1, list, "list file", "list to a file", + "loa", 1, 0, load, "load file", NULL, + "loc", 1, 1, get, "get key", NULL, + "m", 0, 0, mstat, "mstat", "stat memory pool", + "n", 0, 0, next, "next", "move cursor forward one record", + "p", 0, 0, previous, "previous", "move cursor back one record", + "q", 0, 0, NULL, "quit", "quit", + "sh", 1, 0, show, "show page", "dump a page", + { NULL }, +}; + +int recno; /* use record numbers */ +char *dict = "words"; /* default dictionary */ +char *progname; + +int +main(argc, argv) + int argc; + char **argv; +{ + int c; + DB *db; + BTREEINFO b; + + progname = *argv; + + b.flags = 0; + b.cachesize = 0; + b.maxkeypage = 0; + b.minkeypage = 0; + b.psize = 0; + b.compare = NULL; + b.prefix = NULL; + b.lorder = 0; + + while ((c = getopt(argc, argv, "bc:di:lp:ru")) != EOF) { + switch (c) { + case 'b': + b.lorder = BIG_ENDIAN; + break; + case 'c': + b.cachesize = atoi(optarg); + break; + case 'd': + b.flags |= R_DUP; + break; + case 'i': + dict = optarg; + break; + case 'l': + b.lorder = LITTLE_ENDIAN; + break; + case 'p': + b.psize = atoi(optarg); + break; + case 'r': + recno = 1; + break; + case 'u': + b.flags = 0; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (recno) + db = dbopen(*argv == NULL ? NULL : *argv, O_RDWR, + 0, DB_RECNO, NULL); + else + db = dbopen(*argv == NULL ? NULL : *argv, O_CREAT|O_RDWR, + 0600, DB_BTREE, &b); + + if (db == NULL) { + (void)fprintf(stderr, "dbopen: %s\n", strerror(errno)); + exit(1); + } + globaldb = db; + user(db); + exit(0); + /* NOTREACHED */ +} + +void +user(db) + DB *db; +{ + FILE *ifp; + int argc, i, last; + char *lbuf, *argv[4], buf[512]; + + if ((ifp = fopen("/dev/tty", "r")) == NULL) { + (void)fprintf(stderr, + "/dev/tty: %s\n", strerror(errno)); + exit(1); + } + for (last = 0;;) { + (void)printf("> "); + (void)fflush(stdout); + if ((lbuf = fgets(&buf[0], 512, ifp)) == NULL) + break; + if (lbuf[0] == '\n') { + i = last; + goto uselast; + } + lbuf[strlen(lbuf) - 1] = '\0'; + + if (lbuf[0] == 'q') + break; + + argc = parse(lbuf, &argv[0], 3); + if (argc == 0) + continue; + + for (i = 0; commands[i].cmd != NULL; i++) + if (strncmp(commands[i].cmd, argv[0], + strlen(commands[i].cmd)) == 0) + break; + + if (commands[i].cmd == NULL) { + (void)fprintf(stderr, + "%s: command unknown ('help' for help)\n", lbuf); + continue; + } + + if (commands[i].nargs != argc - 1) { + (void)fprintf(stderr, "usage: %s\n", commands[i].usage); + continue; + } + + if (recno && commands[i].rconv) { + static recno_t nlong; + nlong = atoi(argv[1]); + argv[1] = (char *)&nlong; + } +uselast: last = i; + (*commands[i].func)(db, argv); + } + if ((db->sync)(db) == RET_ERROR) + perror("dbsync"); + else if ((db->close)(db) == RET_ERROR) + perror("dbclose"); +} + +int +parse(lbuf, argv, maxargc) + char *lbuf, **argv; + int maxargc; +{ + int argc = 0; + char *c; + + c = lbuf; + while (isspace(*c)) + c++; + while (*c != '\0' && argc < maxargc) { + *argv++ = c; + argc++; + while (!isspace(*c) && *c != '\0') { + c++; + } + while (isspace(*c)) + *c++ = '\0'; + } + return (argc); +} + +void +append(db, argv) + DB *db; + char **argv; +{ + DBT key, data; + int status; + + if (!recno) { + (void)fprintf(stderr, + "append only available for recno db's.\n"); + return; + } + key.data = argv[1]; + key.size = sizeof(recno_t); + data.data = argv[2]; + data.size = strlen(data.data); + status = (db->put)(db, &key, &data, R_APPEND); + switch (status) { + case RET_ERROR: + perror("append/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +cursor(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + status = (*db->seq)(db, &key, &data, R_CURSOR); + switch (status) { + case RET_ERROR: + perror("cursor/seq"); + break; + case RET_SPECIAL: + (void)printf("key not found\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +delcur(db, argv) + DB *db; + char **argv; +{ + int status; + + status = (*db->del)(db, NULL, R_CURSOR); + + if (status == RET_ERROR) + perror("delcur/del"); +} + +void +delete(db, argv) + DB *db; + char **argv; +{ + DBT key; + int status; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + + status = (*db->del)(db, &key, 0); + switch (status) { + case RET_ERROR: + perror("delete/del"); + break; + case RET_SPECIAL: + (void)printf("key not found\n"); + break; + case RET_SUCCESS: + break; + } +} + +void +dump(db, argv) + DB *db; + char **argv; +{ + __bt_dump(db); +} + +void +first(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + status = (*db->seq)(db, &key, &data, R_FIRST); + + switch (status) { + case RET_ERROR: + perror("first/seq"); + break; + case RET_SPECIAL: + (void)printf("no more keys\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +get(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + + status = (*db->get)(db, &key, &data, 0); + + switch (status) { + case RET_ERROR: + perror("get/get"); + break; + case RET_SPECIAL: + (void)printf("key not found\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +help(db, argv) + DB *db; + char **argv; +{ + int i; + + for (i = 0; commands[i].cmd; i++) + if (commands[i].descrip) + (void)printf("%s: %s\n", + commands[i].usage, commands[i].descrip); +} + +void +iafter(db, argv) + DB *db; + char **argv; +{ + DBT key, data; + int status; + + if (!recno) { + (void)fprintf(stderr, + "iafter only available for recno db's.\n"); + return; + } + key.data = argv[1]; + key.size = sizeof(recno_t); + data.data = argv[2]; + data.size = strlen(data.data); + status = (db->put)(db, &key, &data, R_IAFTER); + switch (status) { + case RET_ERROR: + perror("iafter/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +ibefore(db, argv) + DB *db; + char **argv; +{ + DBT key, data; + int status; + + if (!recno) { + (void)fprintf(stderr, + "ibefore only available for recno db's.\n"); + return; + } + key.data = argv[1]; + key.size = sizeof(recno_t); + data.data = argv[2]; + data.size = strlen(data.data); + status = (db->put)(db, &key, &data, R_IBEFORE); + switch (status) { + case RET_ERROR: + perror("ibefore/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +icursor(db, argv) + DB *db; + char **argv; +{ + int status; + DBT data, key; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + data.data = argv[2]; + data.size = strlen(argv[2]) + 1; + + status = (*db->put)(db, &key, &data, R_CURSOR); + switch (status) { + case RET_ERROR: + perror("icursor/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +insert(db, argv) + DB *db; + char **argv; +{ + int status; + DBT data, key; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + data.data = argv[2]; + data.size = strlen(argv[2]) + 1; + + status = (*db->put)(db, &key, &data, R_NOOVERWRITE); + switch (status) { + case RET_ERROR: + perror("insert/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +last(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + status = (*db->seq)(db, &key, &data, R_LAST); + + switch (status) { + case RET_ERROR: + perror("last/seq"); + break; + case RET_SPECIAL: + (void)printf("no more keys\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +list(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + FILE *fp; + int status; + + if ((fp = fopen(argv[1], "w")) == NULL) { + (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno)); + return; + } + status = (*db->seq)(db, &key, &data, R_FIRST); + while (status == RET_SUCCESS) { + (void)fprintf(fp, "%s\n", key.data); + status = (*db->seq)(db, &key, &data, R_NEXT); + } + if (status == RET_ERROR) + perror("list/seq"); +} + +DB *BUGdb; +void +load(db, argv) + DB *db; + char **argv; +{ + register char *p, *t; + FILE *fp; + DBT data, key; + recno_t cnt; + size_t len; + int status; + char *lp, buf[16 * 1024]; + + BUGdb = db; + if ((fp = fopen(argv[1], "r")) == NULL) { + (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno)); + return; + } + (void)printf("loading %s...\n", argv[1]); + + for (cnt = 1; (lp = fgetline(fp, &len)) != NULL; ++cnt) { + if (recno) { + key.data = &cnt; + key.size = sizeof(recno_t); + data.data = lp; + data.size = len + 1; + } else { + key.data = lp; + key.size = len + 1; + for (p = lp + len - 1, t = buf; p >= lp; *t++ = *p--); + *t = '\0'; + data.data = buf; + data.size = len + 1; + } + + status = (*db->put)(db, &key, &data, R_NOOVERWRITE); + switch (status) { + case RET_ERROR: + perror("load/put"); + exit(1); + case RET_SPECIAL: + if (recno) + (void)fprintf(stderr, + "duplicate: %ld {%s}\n", cnt, data.data); + else + (void)fprintf(stderr, + "duplicate: %ld {%s}\n", cnt, key.data); + exit(1); + case RET_SUCCESS: + break; + } + } + (void)fclose(fp); +} + +void +next(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + status = (*db->seq)(db, &key, &data, R_NEXT); + + switch (status) { + case RET_ERROR: + perror("next/seq"); + break; + case RET_SPECIAL: + (void)printf("no more keys\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +previous(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + status = (*db->seq)(db, &key, &data, R_PREV); + + switch (status) { + case RET_ERROR: + perror("previous/seq"); + break; + case RET_SPECIAL: + (void)printf("no more keys\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +show(db, argv) + DB *db; + char **argv; +{ + BTREE *t; + PAGE *h; + pgno_t pg; + + pg = atoi(argv[1]); + t = db->internal; + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) { + (void)printf("getpage of %ld failed\n", pg); + return; + } + if (pg == 0) + __bt_dmpage(h); + else + __bt_dpage(h); + mpool_put(t->bt_mp, h, 0); +} + +void +bstat(db, argv) + DB *db; + char **argv; +{ + (void)printf("BTREE\n"); + __bt_stat(db); +} + +void +mstat(db, argv) + DB *db; + char **argv; +{ + (void)printf("MPOOL\n"); + mpool_stat(((BTREE *)db->internal)->bt_mp); +} + +void +keydata(key, data) + DBT *key, *data; +{ + if (!recno && key->size > 0) + (void)printf("%s/", key->data); + if (data->size > 0) + (void)printf("%s", data->data); + (void)printf("\n"); +} + +void +usage() +{ + (void)fprintf(stderr, + "usage: %s [-bdlu] [-c cache] [-i file] [-p page] [file]\n", + progname); + exit (1); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/test/dbtest.c b/circuitpython/lib/berkeley-db-1.xx/test/dbtest.c new file mode 100644 index 0000000..4341b4c --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/dbtest.c @@ -0,0 +1,753 @@ +/*- + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char copyright[] = +"@(#) Copyright (c) 1992, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; + +void compare __P((DBT *, DBT *)); +DBTYPE dbtype __P((char *)); +void dump __P((DB *, int)); +void err __P((const char *, ...)); +void get __P((DB *, DBT *)); +void getdata __P((DB *, DBT *, DBT *)); +void put __P((DB *, DBT *, DBT *)); +void rem __P((DB *, DBT *)); +char *sflags __P((int)); +void synk __P((DB *)); +void *rfile __P((char *, size_t *)); +void seq __P((DB *, DBT *)); +u_int setflags __P((char *)); +void *setinfo __P((DBTYPE, char *)); +void usage __P((void)); +void *xmalloc __P((char *, size_t)); + +DBTYPE type; /* Database type. */ +void *infop; /* Iflags. */ +u_long lineno; /* Current line in test script. */ +u_int flags; /* Current DB flags. */ +int ofd = STDOUT_FILENO; /* Standard output fd. */ + +DB *XXdbp; /* Global for gdb. */ +int XXlineno; /* Fast breakpoint for gdb. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern int optind; + extern char *optarg; + enum S command, state; + DB *dbp; + DBT data, key, keydata; + size_t len; + int ch, oflags, sflag; + char *fname, *infoarg, *p, *t, buf[8 * 1024]; + + infoarg = NULL; + fname = NULL; + oflags = O_CREAT | O_RDWR; + sflag = 0; + while ((ch = getopt(argc, argv, "f:i:lo:s")) != EOF) + switch (ch) { + case 'f': + fname = optarg; + break; + case 'i': + infoarg = optarg; + break; + case 'l': + oflags |= DB_LOCK; + break; + case 'o': + if ((ofd = open(optarg, + O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) + err("%s: %s", optarg, strerror(errno)); + break; + case 's': + sflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + /* Set the type. */ + type = dbtype(*argv++); + + /* Open the descriptor file. */ + if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) + err("%s: %s", *argv, strerror(errno)); + + /* Set up the db structure as necessary. */ + if (infoarg == NULL) + infop = NULL; + else + for (p = strtok(infoarg, ",\t "); p != NULL; + p = strtok(0, ",\t ")) + if (*p != '\0') + infop = setinfo(type, p); + + /* + * Open the DB. Delete any preexisting copy, you almost never + * want it around, and it often screws up tests. + */ + if (fname == NULL) { + p = getenv("TMPDIR"); + if (p == NULL) + p = "/var/tmp"; + (void)sprintf(buf, "%s/__dbtest", p); + fname = buf; + (void)unlink(buf); + } else if (!sflag) + (void)unlink(fname); + + if ((dbp = dbopen(fname, + oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) + err("dbopen: %s", strerror(errno)); + XXdbp = dbp; + + state = COMMAND; + for (lineno = 1; + (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { + /* Delete the newline, displaying the key/data is easier. */ + if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) + *t = '\0'; + if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#') + continue; + + /* Convenient gdb break point. */ + if (XXlineno == lineno) + XXlineno = 1; + switch (*p) { + case 'c': /* compare */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + state = KEY; + command = COMPARE; + break; + case 'e': /* echo */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + /* Don't display the newline, if CR at EOL. */ + if (p[len - 2] == '\r') + --len; + if (write(ofd, p + 1, len - 1) != len - 1 || + write(ofd, "\n", 1) != 1) + err("write: %s", strerror(errno)); + break; + case 'g': /* get */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + state = KEY; + command = GET; + break; + case 'p': /* put */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + state = KEY; + command = PUT; + break; + case 'r': /* remove */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + if (flags == R_CURSOR) { + rem(dbp, &key); + state = COMMAND; + } else { + state = KEY; + command = REMOVE; + } + break; + case 'S': /* sync */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + synk(dbp); + state = COMMAND; + break; + case 's': /* seq */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + if (flags == R_CURSOR) { + state = KEY; + command = SEQ; + } else + seq(dbp, &key); + break; + case 'f': + flags = setflags(p + 1); + break; + case 'D': /* data file */ + if (state != DATA) + err("line %lu: not expecting data", lineno); + data.data = rfile(p + 1, &data.size); + goto ldata; + case 'd': /* data */ + if (state != DATA) + err("line %lu: not expecting data", lineno); + data.data = xmalloc(p + 1, len - 1); + data.size = len - 1; +ldata: switch (command) { + case COMPARE: + compare(&keydata, &data); + break; + case PUT: + put(dbp, &key, &data); + break; + default: + err("line %lu: command doesn't take data", + lineno); + } + if (type != DB_RECNO) + free(key.data); + free(data.data); + state = COMMAND; + break; + case 'K': /* key file */ + if (state != KEY) + err("line %lu: not expecting a key", lineno); + if (type == DB_RECNO) + err("line %lu: 'K' not available for recno", + lineno); + key.data = rfile(p + 1, &key.size); + goto lkey; + case 'k': /* key */ + if (state != KEY) + err("line %lu: not expecting a key", lineno); + if (type == DB_RECNO) { + static recno_t recno; + recno = atoi(p + 1); + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = xmalloc(p + 1, len - 1); + key.size = len - 1; + } +lkey: switch (command) { + case COMPARE: + getdata(dbp, &key, &keydata); + state = DATA; + break; + case GET: + get(dbp, &key); + if (type != DB_RECNO) + free(key.data); + state = COMMAND; + break; + case PUT: + state = DATA; + break; + case REMOVE: + rem(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + case SEQ: + seq(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + default: + err("line %lu: command doesn't take a key", + lineno); + } + break; + case 'o': + dump(dbp, p[1] == 'r'); + break; + default: + err("line %lu: %s: unknown command character", + lineno, p); + } + } +#ifdef STATISTICS + /* + * -l must be used (DB_LOCK must be set) for this to be + * used, otherwise a page will be locked and it will fail. + */ + if (type == DB_BTREE && oflags & DB_LOCK) + __bt_stat(dbp); +#endif + if (dbp->close(dbp)) + err("db->close: %s", strerror(errno)); + (void)close(ofd); + exit(0); +} + +#define NOOVERWRITE "put failed, would overwrite key\n" + +void +compare(db1, db2) + DBT *db1, *db2; +{ + register size_t len; + register u_char *p1, *p2; + + if (db1->size != db2->size) + printf("compare failed: key->data len %lu != data len %lu\n", + db1->size, db2->size); + + len = MIN(db1->size, db2->size); + for (p1 = db1->data, p2 = db2->data; len--;) + if (*p1++ != *p2++) { + printf("compare failed at offset %d\n", + p1 - (u_char *)db1->data); + break; + } +} + +void +get(dbp, kp) + DB *dbp; + DBT *kp; +{ + DBT data; + + switch (dbp->get(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err("line %lu: get: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "get failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else + (void)fprintf(stderr, "%d: %.*s: %s", + lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); +#undef NOSUCHKEY + break; + } +} + +void +getdata(dbp, kp, dp) + DB *dbp; + DBT *kp, *dp; +{ + switch (dbp->get(dbp, kp, dp, flags)) { + case 0: + return; + case -1: + err("line %lu: getdata: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: + err("line %lu: getdata failed, no such key", lineno); + /* NOTREACHED */ + } +} + +void +put(dbp, kp, dp) + DB *dbp; + DBT *kp, *dp; +{ + switch (dbp->put(dbp, kp, dp, flags)) { + case 0: + break; + case -1: + err("line %lu: put: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: + (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); + break; + } +} + +void +rem(dbp, kp) + DB *dbp; + DBT *kp; +{ + switch (dbp->del(dbp, kp, flags)) { + case 0: + break; + case -1: + err("line %lu: rem: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "rem failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags != R_CURSOR) + (void)fprintf(stderr, "%d: %.*s: %s", + lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%d: rem of cursor failed\n", lineno); +#undef NOSUCHKEY + break; + } +} + +void +synk(dbp) + DB *dbp; +{ + switch (dbp->sync(dbp, flags)) { + case 0: + break; + case -1: + err("line %lu: synk: %s", lineno, strerror(errno)); + /* NOTREACHED */ + } +} + +void +seq(dbp, kp) + DB *dbp; + DBT *kp; +{ + DBT data; + + switch (dbp->seq(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err("line %lu: seq: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "seq failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags == R_CURSOR) + (void)fprintf(stderr, "%d: %.*s: %s", + lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%d: seq (%s) failed\n", lineno, sflags(flags)); +#undef NOSUCHKEY + break; + } +} + +void +dump(dbp, rev) + DB *dbp; + int rev; +{ + DBT key, data; + int flags, nflags; + + if (rev) { + flags = R_LAST; + nflags = R_PREV; + } else { + flags = R_FIRST; + nflags = R_NEXT; + } + for (;; flags = nflags) + switch (dbp->seq(dbp, &key, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case 1: + goto done; + case -1: + err("line %lu: (dump) seq: %s", + lineno, strerror(errno)); + /* NOTREACHED */ + } +done: return; +} + +u_int +setflags(s) + char *s; +{ + char *p, *index(); + + for (; isspace(*s); ++s); + if (*s == '\n' || *s == '\0') + return (0); + if ((p = index(s, '\n')) != NULL) + *p = '\0'; + if (!strcmp(s, "R_CURSOR")) return (R_CURSOR); + if (!strcmp(s, "R_FIRST")) return (R_FIRST); + if (!strcmp(s, "R_IAFTER")) return (R_IAFTER); + if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE); + if (!strcmp(s, "R_LAST")) return (R_LAST); + if (!strcmp(s, "R_NEXT")) return (R_NEXT); + if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE); + if (!strcmp(s, "R_PREV")) return (R_PREV); + if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR); + + err("line %lu: %s: unknown flag", lineno, s); + /* NOTREACHED */ +} + +char * +sflags(flags) + int flags; +{ + switch (flags) { + case R_CURSOR: return ("R_CURSOR"); + case R_FIRST: return ("R_FIRST"); + case R_IAFTER: return ("R_IAFTER"); + case R_IBEFORE: return ("R_IBEFORE"); + case R_LAST: return ("R_LAST"); + case R_NEXT: return ("R_NEXT"); + case R_NOOVERWRITE: return ("R_NOOVERWRITE"); + case R_PREV: return ("R_PREV"); + case R_SETCURSOR: return ("R_SETCURSOR"); + } + + return ("UNKNOWN!"); +} + +DBTYPE +dbtype(s) + char *s; +{ + if (!strcmp(s, "btree")) + return (DB_BTREE); + if (!strcmp(s, "hash")) + return (DB_HASH); + if (!strcmp(s, "recno")) + return (DB_RECNO); + err("%s: unknown type (use btree, hash or recno)", s); + /* NOTREACHED */ +} + +void * +setinfo(type, s) + DBTYPE type; + char *s; +{ + static BTREEINFO ib; + static HASHINFO ih; + static RECNOINFO rh; + char *eq, *index(); + + if ((eq = index(s, '=')) == NULL) + err("%s: illegal structure set statement", s); + *eq++ = '\0'; + if (!isdigit(*eq)) + err("%s: structure set statement must be a number", s); + + switch (type) { + case DB_BTREE: + if (!strcmp("flags", s)) { + ib.flags = atoi(eq); + return (&ib); + } + if (!strcmp("cachesize", s)) { + ib.cachesize = atoi(eq); + return (&ib); + } + if (!strcmp("maxkeypage", s)) { + ib.maxkeypage = atoi(eq); + return (&ib); + } + if (!strcmp("minkeypage", s)) { + ib.minkeypage = atoi(eq); + return (&ib); + } + if (!strcmp("lorder", s)) { + ib.lorder = atoi(eq); + return (&ib); + } + if (!strcmp("psize", s)) { + ib.psize = atoi(eq); + return (&ib); + } + break; + case DB_HASH: + if (!strcmp("bsize", s)) { + ih.bsize = atoi(eq); + return (&ih); + } + if (!strcmp("ffactor", s)) { + ih.ffactor = atoi(eq); + return (&ih); + } + if (!strcmp("nelem", s)) { + ih.nelem = atoi(eq); + return (&ih); + } + if (!strcmp("cachesize", s)) { + ih.cachesize = atoi(eq); + return (&ih); + } + if (!strcmp("lorder", s)) { + ih.lorder = atoi(eq); + return (&ih); + } + break; + case DB_RECNO: + if (!strcmp("flags", s)) { + rh.flags = atoi(eq); + return (&rh); + } + if (!strcmp("cachesize", s)) { + rh.cachesize = atoi(eq); + return (&rh); + } + if (!strcmp("lorder", s)) { + rh.lorder = atoi(eq); + return (&rh); + } + if (!strcmp("reclen", s)) { + rh.reclen = atoi(eq); + return (&rh); + } + if (!strcmp("bval", s)) { + rh.bval = atoi(eq); + return (&rh); + } + if (!strcmp("psize", s)) { + rh.psize = atoi(eq); + return (&rh); + } + break; + } + err("%s: unknown structure value", s); + /* NOTREACHED */ +} + +void * +rfile(name, lenp) + char *name; + size_t *lenp; +{ + struct stat sb; + void *p; + int fd; + char *np, *index(); + + for (; isspace(*name); ++name); + if ((np = index(name, '\n')) != NULL) + *np = '\0'; + if ((fd = open(name, O_RDONLY, 0)) < 0 || + fstat(fd, &sb)) + err("%s: %s\n", name, strerror(errno)); +#ifdef NOT_PORTABLE + if (sb.st_size > (off_t)SIZE_T_MAX) + err("%s: %s\n", name, strerror(E2BIG)); +#endif + if ((p = (void *)malloc((u_int)sb.st_size)) == NULL) + err("%s", strerror(errno)); + (void)read(fd, p, (int)sb.st_size); + *lenp = sb.st_size; + (void)close(fd); + return (p); +} + +void * +xmalloc(text, len) + char *text; + size_t len; +{ + void *p; + + if ((p = (void *)malloc(len)) == NULL) + err("%s", strerror(errno)); + memmove(p, text, len); + return (p); +} + +void +usage() +{ + (void)fprintf(stderr, + "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n"); + exit(1); +} + +#if __STDC__ +#include +#else +#include +#endif + +void +#if __STDC__ +err(const char *fmt, ...) +#else +err(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "dbtest: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + exit(1); + /* NOTREACHED */ +} diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/driver2.c b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/driver2.c new file mode 100644 index 0000000..2008a28 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/driver2.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)driver2.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* + * Test driver, to try to tackle the large ugly-split problem. + */ + +#include +#include +#include "ndbm.h" + +int my_hash(key, len) + char *key; + int len; +{ + return(17); /* So I'm cruel... */ +} + +main(argc, argv) + int argc; +{ + DB *db; + DBT key, content; + char keybuf[2049]; + char contentbuf[2049]; + char buf[256]; + int i; + HASHINFO info; + + info.bsize = 1024; + info.ffactor = 5; + info.nelem = 1; + info.cachesize = NULL; +#ifdef HASH_ID_PROGRAM_SPECIFIED + info.hash_id = HASH_ID_PROGRAM_SPECIFIED; + info.hash_func = my_hash; +#else + info.hash = my_hash; +#endif + info.lorder = 0; + if (!(db = dbopen("bigtest", O_RDWR | O_CREAT, 0644, DB_HASH, &info))) { + sprintf(buf, "dbopen: failed on file bigtest"); + perror(buf); + exit(1); + } + srandom(17); + key.data = keybuf; + content.data = contentbuf; + bzero(keybuf, sizeof(keybuf)); + bzero(contentbuf, sizeof(contentbuf)); + for (i=1; i <= 500; i++) { + key.size = 128 + (random()&1023); + content.size = 128 + (random()&1023); +/* printf("%d: Key size %d, data size %d\n", i, key.size, + content.size); */ + sprintf(keybuf, "Key #%d", i); + sprintf(contentbuf, "Contents #%d", i); + if ((db->put)(db, &key, &content, R_NOOVERWRITE)) { + sprintf(buf, "dbm_store #%d", i); + perror(buf); + } + } + if ((db->close)(db)) { + perror("closing hash file"); + exit(1); + } + exit(0); +} + + + diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/makedb.sh b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/makedb.sh new file mode 100644 index 0000000..f28e281 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/makedb.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# +# @(#)makedb.sh 8.1 (Berkeley) 6/4/93 + +awk '{i++; print $0; print i;}' /usr/share/dict/words > WORDS +ls /bin /usr/bin /usr/ucb /etc | egrep '^(...|....|.....|......)$' | \ +sort | uniq | \ +awk '{ + printf "%s\n", $0 + for (i = 0; i < 1000; i++) + printf "%s+", $0 + printf "\n" +}' > LONG.DATA diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tcreat3.c b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tcreat3.c new file mode 100644 index 0000000..bd125ac --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tcreat3.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)tcreat3.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key; + DB *dbp; + HASHINFO ctl; + FILE *fp; + int trash; + + int i = 0; + + argv++; + ctl.hash = NULL; + ctl.bsize = atoi(*argv++); + ctl.ffactor = atoi(*argv++); + ctl.nelem = atoi(*argv++); + ctl.lorder = 0; + if (!(dbp = dbopen( "hashtest", + O_CREAT|O_TRUNC|O_RDWR, 0600, DB_HASH, &ctl))){ + /* create table */ + fprintf(stderr, "cannot create: hash table (size %d)\n", + INITIAL); + exit(1); + } + + key.data = wp1; + item.data = wp2; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + item.size = strlen(wp2); + +/* + * enter key/data pair into the table + */ + if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) { + fprintf(stderr, "cannot enter: key %s\n", + item.data); + exit(1); + } + } + + (dbp->close)(dbp); + exit(0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tdel.c b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tdel.c new file mode 100644 index 0000000..ed3f90a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tdel.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)tdel.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +/* Usage: thash pagesize fillfactor file */ +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key; + DB *dbp; + HASHINFO ctl; + FILE *fp; + int stat; + + int i = 0; + + argv++; + ctl.nelem = INITIAL; + ctl.hash = NULL; + ctl.bsize = atoi(*argv++); + ctl.ffactor = atoi(*argv++); + ctl.cachesize = 1024 * 1024; /* 1 MEG */ + ctl.lorder = 0; + argc -= 2; + if (!(dbp = dbopen( NULL, O_CREAT|O_RDWR, 0400, DB_HASH, &ctl))) { + /* create table */ + fprintf(stderr, "cannot create: hash table size %d)\n", + INITIAL); + exit(1); + } + + key.data = wp1; + item.data = wp2; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + item.size = strlen(wp2); + +/* + * enter key/data pair into the table + */ + if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) { + fprintf(stderr, "cannot enter: key %s\n", + item.data); + exit(1); + } + } + + if ( --argc ) { + fp = fopen ( argv[0], "r"); + i = 0; + while ( fgets(wp1, 8192, fp) && + fgets(wp2, 8192, fp) && + i++ < MAXWORDS) { + key.size = strlen(wp1); + stat = (dbp->del)(dbp, &key, 0); + if (stat) { + fprintf ( stderr, "Error retrieving %s\n", key.data ); + exit(1); + } + } + fclose(fp); + } + (dbp->close)(dbp); + exit(0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/testit b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/testit new file mode 100644 index 0000000..039457a --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/testit @@ -0,0 +1,147 @@ +#!/bin/csh -f +# +# @(#)testit 8.1 (Berkeley) 6/4/93 +# + +echo "" +echo "PAGE FILL " +set name=WORDS + set i = 256 + foreach j ( 11 14 21 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 512 + foreach j ( 21 28 43 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 1024 + foreach j ( 43 57 85 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 2048 + foreach j ( 85 114 171 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 4096 + foreach j ( 171 228 341 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 8192 + foreach j ( 341 455 683 ) + thash4 $i $j 25000 65536 $name < $name + end + echo "PAGE FILL " + set i = 256 + foreach j ( 11 14 21 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 512 + foreach j ( 21 28 43 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 1024 + foreach j ( 43 57 85 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 2048 + foreach j ( 85 114 171 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 4096 + foreach j ( 171 228 341 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 8192 + foreach j ( 341 455 683 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end +set name=LONG.DATA + set i = 1024 + foreach j ( 1 2 4 ) + echo thash4 $i $j 600 65536 $name + thash4 $i $j 600 65536 $name < $name + end + + set i = 2048 + foreach j ( 1 2 4 ) + echo thash4 $i $j 600 65536 $name + thash4 $i $j 600 65536 $name < $name + end + set i = 4096 + foreach j ( 1 2 4 ) + echo thash4 $i $j 600 65536 $name + thash4 $i $j 600 65536 $name < $name + end + set i = 8192 + foreach j ( 2 4 8 ) + echo thash4 $i $j 600 65536 $name + thash4 $i $j 600 65536 $name < $name + end + echo "PAGE FILL " + set i = 1024 + foreach j ( 1 2 4 ) + echo "$i"_"$j" + tcreat3 $i $j 600 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 2048 + foreach j ( 1 2 4 ) + echo "$i"_"$j" + tcreat3 $i $j 600 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 4096 + foreach j ( 1 2 4 ) + echo "$i"_"$j" + tcreat3 $i $j 600 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 8192 + foreach j ( 2 4 8 ) + echo "$i"_"$j" + tcreat3 $i $j 600 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end +driver2 diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/thash4.c b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/thash4.c new file mode 100644 index 0000000..9e344cb --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/thash4.c @@ -0,0 +1,132 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)thash4.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +/* Usage: thash pagesize fillfactor file */ +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key, res; + DB *dbp; + HASHINFO ctl; + FILE *fp; + int stat; + time_t t; + + int i = 0; + + argv++; + ctl.hash = NULL; + ctl.bsize = atoi(*argv++); + ctl.ffactor = atoi(*argv++); + ctl.nelem = atoi(*argv++); + ctl.cachesize = atoi(*argv++); + ctl.lorder = 0; + if (!(dbp = dbopen( NULL, O_CREAT|O_RDWR, 0400, DB_HASH, &ctl))) { + /* create table */ + fprintf(stderr, "cannot create: hash table size %d)\n", + INITIAL); + fprintf(stderr, "\terrno: %d\n", errno); + exit(1); + } + + key.data = wp1; + item.data = wp2; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + item.size = strlen(wp2); + +/* + * enter key/data pair into the table + */ + if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) { + fprintf(stderr, "cannot enter: key %s\n", + item.data); + fprintf(stderr, "\terrno: %d\n", errno); + exit(1); + } + } + + if ( --argc ) { + fp = fopen ( argv[0], "r"); + i = 0; + while ( fgets(wp1, 256, fp) && + fgets(wp2, 8192, fp) && + i++ < MAXWORDS) { + + key.size = strlen(wp1); + stat = (dbp->get)(dbp, &key, &res, 0); + if (stat < 0 ) { + fprintf ( stderr, "Error retrieving %s\n", key.data ); + fprintf(stderr, "\terrno: %d\n", errno); + exit(1); + } else if ( stat > 0 ) { + fprintf ( stderr, "%s not found\n", key.data ); + fprintf(stderr, "\terrno: %d\n", errno); + exit(1); + } + } + fclose(fp); + } + dbp->close(dbp); + exit(0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tread2.c b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tread2.c new file mode 100644 index 0000000..8f01556 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tread2.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)tread2.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +typedef struct { /* info to be stored */ + int num, siz; +} info; + +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key, res; + DB *dbp; + HASHINFO ctl; + int stat; + + int i = 0; + + ctl.nelem = INITIAL; + ctl.hash = NULL; + ctl.bsize = 64; + ctl.ffactor = 1; + ctl.cachesize = atoi(*argv++); + ctl.lorder = 0; + if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, &ctl))) { + /* create table */ + fprintf(stderr, "cannot open: hash table\n" ); + exit(1); + } + + key.data = wp1; + item.data = wp2; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + item.size = strlen(wp2); + + stat = (dbp->get)(dbp, &key, &res,0); + if (stat < 0) { + fprintf ( stderr, "Error retrieving %s\n", key.data ); + exit(1); + } else if ( stat > 0 ) { + fprintf ( stderr, "%s not found\n", key.data ); + exit(1); + } + } + (dbp->close)(dbp); + exit(0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tseq.c b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tseq.c new file mode 100644 index 0000000..f45700e --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tseq.c @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)tseq.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + + +char wp[8192]; +char cp[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key, res; + DB *dbp; + FILE *fp; + int stat; + + if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, NULL))) { + /* create table */ + fprintf(stderr, "cannot open: hash table\n" ); + exit(1); + } + +/* +* put info in structure, and structure in the item +*/ + for ( stat = (dbp->seq) (dbp, &res, &item, 1 ); + stat == 0; + stat = (dbp->seq) (dbp, &res, &item, 0 ) ) { + + bcopy ( res.data, wp, res.size ); + wp[res.size] = 0; + bcopy ( item.data, cp, item.size ); + cp[item.size] = 0; + + printf ( "%s %s\n", wp, cp ); + } + (dbp->close)(dbp); + exit(0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tverify.c b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tverify.c new file mode 100644 index 0000000..ac5d2f9 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/hash.tests/tverify.c @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)tverify.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +typedef struct { /* info to be stored */ + int num, siz; +} info; + +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT key, res; + DB *dbp; + HASHINFO ctl; + int trash; + int stat; + + int i = 0; + + ctl.nelem = INITIAL; + ctl.hash = NULL; + ctl.bsize = 64; + ctl.ffactor = 1; + ctl.cachesize = 1024 * 1024; /* 1 MEG */ + ctl.lorder = 0; + if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, &ctl))) { + /* create table */ + fprintf(stderr, "cannot open: hash table\n" ); + exit(1); + } + + key.data = wp1; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + + stat = (dbp->get)(dbp, &key, &res,0); + if (stat < 0) { + fprintf ( stderr, "Error retrieving %s\n", key.data ); + exit(1); + } else if ( stat > 0 ) { + fprintf ( stderr, "%s not found\n", key.data ); + exit(1); + } + if ( memcmp ( res.data, wp2, res.size ) ) { + fprintf ( stderr, "data for %s is incorrect. Data was %s. Should have been %s\n", key.data, res.data, wp2 ); + } + } + (dbp->close)(dbp); + exit(0); +} diff --git a/circuitpython/lib/berkeley-db-1.xx/test/run.test b/circuitpython/lib/berkeley-db-1.xx/test/run.test new file mode 100644 index 0000000..52b74c3 --- /dev/null +++ b/circuitpython/lib/berkeley-db-1.xx/test/run.test @@ -0,0 +1,705 @@ +#!/bin/sh - +# +# @(#)run.test 8.10 (Berkeley) 7/26/94 +# + +# db regression tests +main() +{ + + PROG=./dbtest + TMP1=t1 + TMP2=t2 + TMP3=t3 + + if [ -f /usr/share/dict/words ]; then + DICT=/usr/share/dict/words + elif [ -f /usr/dict/words ]; then + DICT=/usr/dict/words + else + echo 'run.test: no dictionary' + exit 1 + fi + + if [ $# -eq 0 ]; then + for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do + test$t + done + else + while [ $# -gt 0 ] + do case "$1" in + test*) + $1;; + [0-9]*) + test$1;; + btree) + for t in 1 2 3 7 8 9 10 12 13; do + test$t + done;; + hash) + for t in 1 2 3 8 13 20; do + test$t + done;; + recno) + for t in 1 2 3 4 5 6 7 10 11; do + test$t + done;; + *) + echo "run.test: unknown test $1" + echo "usage: run.test test# | type" + exit 1 + esac + shift + done + fi + rm -f $TMP1 $TMP2 $TMP3 + exit 0 +} + +# Take the first hundred entries in the dictionary, and make them +# be key/data pairs. +test1() +{ + echo "Test 1: btree, hash: small key, small data pairs" + sed 200q $DICT > $TMP1 + for type in btree hash; do + rm -f $TMP2 $TMP3 + for i in `sed 200q $DICT`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done > $TMP2 + $PROG -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test1: type $type: failed" + exit 1 + fi + done + echo "Test 1: recno: small key, small data pairs" + rm -f $TMP2 $TMP3 + sed 200q $DICT | + awk '{ + ++i; + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test1: type recno: failed" + exit 1 + fi +} + +# Take the first 200 entries in the dictionary, and give them +# each a medium size data entry. +test2() +{ + echo "Test 2: btree, hash: small key, medium data pairs" + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1 + for type in hash btree; do + rm -f $TMP2 $TMP3 + for i in `sed 200q $DICT`; do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done > $TMP2 + $PROG -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test2: type $type: failed" + exit 1 + fi + done + echo "Test 2: recno: small key, medium data pairs" + rm -f $TMP2 $TMP3 + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test2: type recno: failed" + exit 1 + fi +} + +# Insert the programs in /bin with their paths as their keys. +test3() +{ + echo "Test 3: hash: small key, big data pairs" + rm -f $TMP1 + (find /bin -type f -print | xargs cat) > $TMP1 + for type in hash; do + rm -f $TMP2 $TMP3 + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done > $TMP2 + $PROG -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test3: $type: failed" + exit 1 + fi + done + echo "Test 3: btree: small key, big data pairs" + for psize in 512 16384 65536; do + echo " page size $psize" + for type in btree; do + rm -f $TMP2 $TMP3 + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done > $TMP2 + $PROG -i psize=$psize -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test3: $type: page size $psize: failed" + exit 1 + fi + done + done + echo "Test 3: recno: big data pairs" + rm -f $TMP2 $TMP3 + find /bin -type f -print | + awk '{ + ++i; + printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i); + }' > $TMP2 + for psize in 512 16384 65536; do + echo " page size $psize" + $PROG -i psize=$psize -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test3: recno: page size $psize: failed" + exit 1 + fi + done +} + +# Do random recno entries. +test4() +{ + echo "Test 4: recno: random entries" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 37; i <= 37 + 88 * 17; i += 17) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 1; i <= 15; ++i) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 19234; i <= 19234 + 61 * 27; i += 27) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit + }' > $TMP1 + rm -f $TMP2 $TMP3 + cat $TMP1 | + awk 'BEGIN { + i = 37; + incr = 17; + } + { + printf("p\nk%d\nd%s\n", i, $0); + if (i == 19234 + 61 * 27) + exit; + if (i == 37 + 88 * 17) { + i = 1; + incr = 1; + } else if (i == 15) { + i = 19234; + incr = 27; + } else + i += incr; + } + END { + for (i = 37; i <= 37 + 88 * 17; i += 17) + printf("g\nk%d\n", i); + for (i = 1; i <= 15; ++i) + printf("g\nk%d\n", i); + for (i = 19234; i <= 19234 + 61 * 27; i += 27) + printf("g\nk%d\n", i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test4: type recno: failed" + exit 1 + fi +} + +# Do reverse order recno entries. +test5() +{ + echo "Test 5: recno: reverse order entries" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk ' { + for (i = 1500; i; --i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + cat $TMP1 | + awk 'BEGIN { + i = 1500; + } + { + printf("p\nk%d\nd%s\n", i, $0); + --i; + } + END { + for (i = 1500; i; --i) + printf("g\nk%d\n", i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test5: type recno: failed" + exit 1 + fi +} + +# Do alternating order recno entries. +test6() +{ + echo "Test 6: recno: alternating order entries" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk ' { + for (i = 1; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 2; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + cat $TMP1 | + awk 'BEGIN { + i = 1; + even = 0; + } + { + printf("p\nk%d\nd%s\n", i, $0); + i += 2; + if (i >= 1200) { + if (even == 1) + exit; + even = 1; + i = 2; + } + } + END { + for (i = 1; i < 1200; ++i) + printf("g\nk%d\n", i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + sort -o $TMP1 $TMP1 + sort -o $TMP3 $TMP3 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test6: type recno: failed" + exit 1 + fi +} + +# Delete cursor record +test7() +{ + echo "Test 7: btree, recno: delete cursor record" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 120; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + printf("%05d: input key %d: %s\n", 120, 120, $0); + printf("seq failed, no such key\n"); + printf("%05d: input key %d: %s\n", 1, 1, $0); + printf("%05d: input key %d: %s\n", 2, 2, $0); + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + + for type in btree recno; do + cat $TMP1 | + awk '{ + if (i == 120) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_NEXT\n"); + for (i = 1; i <= 120; ++i) + printf("s\n"); + printf("fR_CURSOR\ns\nk120\n"); + printf("r\n"); + printf("fR_NEXT\ns\n"); + printf("fR_CURSOR\ns\nk1\n"); + printf("r\n"); + printf("fR_FIRST\ns\n"); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test7: type $type: failed" + exit 1 + fi + done +} + +# Make sure that overflow pages are reused. +test8() +{ + echo "Test 8: btree, hash: repeated small key, big data pairs" + rm -f $TMP1 + echo "" | + awk 'BEGIN { + for (i = 1; i <= 10; ++i) { + printf("p\nkkey1\nD/bin/sh\n"); + printf("p\nkkey2\nD/bin/csh\n"); + if (i % 8 == 0) { + printf("c\nkkey2\nD/bin/csh\n"); + printf("c\nkkey1\nD/bin/sh\n"); + printf("e\t%d of 10 (comparison)\n", i); + } else + printf("e\t%d of 10 \n", i); + printf("r\nkkey1\nr\nkkey2\n"); + } + }' > $TMP1 + $PROG btree $TMP1 +# $PROG hash $TMP1 + # No explicit test for success. +} + +# Test btree duplicate keys +test9() +{ + echo "Test 9: btree: duplicate keys" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 543; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + + for type in btree; do + cat $TMP1 | + awk '{ + if (i++ % 2) + printf("p\nkduplicatekey\nd%s\n", $0); + else + printf("p\nkunique%dkey\nd%s\n", i, $0); + } + END { + printf("o\n"); + }' > $TMP2 + $PROG -iflags=1 -o $TMP3 $type $TMP2 + sort -o $TMP3 $TMP3 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test9: type $type: failed" + exit 1 + fi + done +} + +# Test use of cursor flags without initialization +test10() +{ + echo "Test 10: btree, recno: test cursor flag use" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 20; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + + # Test that R_CURSOR doesn't succeed before cursor initialized + for type in btree recno; do + cat $TMP1 | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\nr\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' > $TMP2 + $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1 + if [ -s $TMP3 ] ; then + echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED" + exit 1 + fi + done + for type in btree recno; do + cat $TMP1 | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\np\nk1\ndsome data\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' > $TMP2 + $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1 + if [ -s $TMP3 ] ; then + echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED" + exit 1 + fi + done +} + +# Test insert in reverse order. +test11() +{ + echo "Test 11: recno: reverse order insert" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 779; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + + for type in recno; do + cat $TMP1 | + awk '{ + if (i == 0) { + i = 1; + printf("p\nk1\nd%s\n", $0); + printf("%s\n", "fR_IBEFORE"); + } else + printf("p\nk1\nd%s\n", $0); + } + END { + printf("or\n"); + }' > $TMP2 + $PROG -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test11: type $type: failed" + exit 1 + fi + done +} + +# Take the first 20000 entries in the dictionary, reverse them, and give +# them each a small size data entry. Use a small page size to make sure +# the btree split code gets hammered. +test12() +{ + echo "Test 12: btree: lots of keys, small page size" + mdata=abcdefghijklmnopqrstuvwxy + echo $mdata | + awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1 + for type in btree; do + rm -f $TMP2 $TMP3 + for i in `sed 20000q $DICT | rev`; do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done > $TMP2 + $PROG -i psize=512 -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test12: type $type: failed" + exit 1 + fi + done +} + +# Test different byte orders. +test13() +{ + echo "Test 13: btree, hash: differing byte orders" + sed 50q $DICT > $TMP1 + for order in 1234 4321; do + for type in btree hash; do + rm -f byte.file $TMP2 $TMP3 + for i in `sed 50q $DICT`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done > $TMP2 + $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test13: $type/$order put failed" + exit 1 + fi + for i in `sed 50q $DICT`; do + echo g + echo k$i + done > $TMP2 + $PROG -s \ + -ilorder=$order -f byte.file -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test13: $type/$order get failed" + exit 1 + fi + done + done + rm -f byte.file +} + +# Try a variety of bucketsizes and fill factors for hashing +test20() +{ + echo\ + "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 10000; ++i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("%s\n", s); + } + exit; + }' > $TMP1 + sed 10000q $DICT | + awk 'BEGIN { + ds="abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" + } + { + if (++i % 34) + s = substr(ds, 1, i % 34); + else + s = substr(ds, 1); + printf("p\nk%s\nd%s\n", $0, s); + }' > $TMP2 + sed 10000q $DICT | + awk '{ + ++i; + printf("g\nk%s\n", $0); + }' >> $TMP2 + bsize=256 + for ffactor in 11 14 21; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=512 + for ffactor in 21 28 43; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=1024 + for ffactor in 43 57 85; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=2048 + for ffactor in 85 114 171; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=4096 + for ffactor in 171 228 341; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=8192 + for ffactor in 341 455 683; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done +} + +main $* diff --git a/circuitpython/lib/cmsis/inc/cmsis_armcc.h b/circuitpython/lib/cmsis/inc/cmsis_armcc.h new file mode 100644 index 0000000..47b114f --- /dev/null +++ b/circuitpython/lib/cmsis/inc/cmsis_armcc.h @@ -0,0 +1,869 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.5 + * @date 14. December 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/circuitpython/lib/cmsis/inc/cmsis_armclang.h b/circuitpython/lib/cmsis/inc/cmsis_armclang.h new file mode 100644 index 0000000..7c89543 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/cmsis_armclang.h @@ -0,0 +1,1420 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.1.0 + * @date 14. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/circuitpython/lib/cmsis/inc/cmsis_armclang_ltm.h b/circuitpython/lib/cmsis/inc/cmsis_armclang_ltm.h new file mode 100644 index 0000000..f556edf --- /dev/null +++ b/circuitpython/lib/cmsis/inc/cmsis_armclang_ltm.h @@ -0,0 +1,1866 @@ +/**************************************************************************//** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.0.1 + * @date 19. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2018-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/circuitpython/lib/cmsis/inc/cmsis_compiler.h b/circuitpython/lib/cmsis/inc/cmsis_compiler.h new file mode 100644 index 0000000..8f871ea --- /dev/null +++ b/circuitpython/lib/cmsis/inc/cmsis_compiler.h @@ -0,0 +1,270 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ diff --git a/circuitpython/lib/cmsis/inc/cmsis_gcc.h b/circuitpython/lib/cmsis/inc/cmsis_gcc.h new file mode 100644 index 0000000..7ffbdc0 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/cmsis_gcc.h @@ -0,0 +1,2101 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.1.0 + * @date 20. December 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/circuitpython/lib/cmsis/inc/cmsis_iccarm.h b/circuitpython/lib/cmsis/inc/cmsis_iccarm.h new file mode 100644 index 0000000..20b50ce --- /dev/null +++ b/circuitpython/lib/cmsis/inc/cmsis_iccarm.h @@ -0,0 +1,940 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.8 + * @date 04. September 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/circuitpython/lib/cmsis/inc/cmsis_version.h b/circuitpython/lib/cmsis/inc/cmsis_version.h new file mode 100644 index 0000000..660f612 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/circuitpython/lib/cmsis/inc/core_armv81mml.h b/circuitpython/lib/cmsis/inc/core_armv81mml.h new file mode 100644 index 0000000..9425dbc --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_armv81mml.h @@ -0,0 +1,2967 @@ +/**************************************************************************//** + * @file core_armv81mml.h + * @brief CMSIS Armv8.1-M Mainline Core Peripheral Access Layer Header File + * @version V1.0.0 + * @date 15. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2018-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV81MML_H_GENERIC +#define __CORE_ARMV81MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMV81MML + @{ + */ + +#include "cmsis_version.h" + +#define __ARM_ARCH_8M_MAIN__ 1 // patching for now +/* CMSIS ARMV81MML definitions */ +#define __ARMv81MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv81MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv81MML_CMSIS_VERSION ((__ARMv81MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv81MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV81MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV81MML_H_DEPENDANT +#define __CORE_ARMV81MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv81MML_REV + #define __ARMv81MML_REV 0x0000U + #warning "__ARMv81MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv81MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ +#define MPU_RLAR_PXN_Msk (0x1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV81MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_armv8mbl.h b/circuitpython/lib/cmsis/inc/core_armv8mbl.h new file mode 100644 index 0000000..57d9f66 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_armv8mbl.h @@ -0,0 +1,1918 @@ +/**************************************************************************//** + * @file core_armv8mbl.h + * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MBL_H_GENERIC +#define __CORE_ARMV8MBL_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MBL + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M ( 2U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MBL_H_DEPENDANT +#define __CORE_ARMV8MBL_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MBL_REV + #define __ARMv8MBL_REV 0x0000U + #warning "__ARMv8MBL_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MBL */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_armv8mml.h b/circuitpython/lib/cmsis/inc/core_armv8mml.h new file mode 100644 index 0000000..30aab58 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_armv8mml.h @@ -0,0 +1,2832 @@ +/**************************************************************************//** + * @file core_armv8mml.h + * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 12. September 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MML_H_GENERIC +#define __CORE_ARMV8MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS Armv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MML_H_DEPENDANT +#define __CORE_ARMV8MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MML_REV + #define __ARMv8MML_REV 0x0000U + #warning "__ARMv8MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm0.h b/circuitpython/lib/cmsis/inc/core_cm0.h new file mode 100644 index 0000000..1b0a647 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm0.h @@ -0,0 +1,949 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t vectors = 0x0U; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t vectors = 0x0U; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm0plus.h b/circuitpython/lib/cmsis/inc/core_cm0plus.h new file mode 100644 index 0000000..9eea9ed --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm0plus.h @@ -0,0 +1,1082 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t vectors = SCB->VTOR; +#else + uint32_t vectors = 0x0U; +#endif + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t vectors = SCB->VTOR; +#else + uint32_t vectors = 0x0U; +#endif + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm1.h b/circuitpython/lib/cmsis/inc/core_cm1.h new file mode 100644 index 0000000..6c12b8d --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm1.h @@ -0,0 +1,976 @@ +/**************************************************************************//** + * @file core_cm1.h + * @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File + * @version V1.0.1 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM1_H_GENERIC +#define __CORE_CM1_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M1 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM1 definitions */ +#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ + __CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (1U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM1_H_DEPENDANT +#define __CORE_CM1_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM1_REV + #define __CM1_REV 0x0100U + #warning "__CM1_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M1 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ + +#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M1 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm23.h b/circuitpython/lib/cmsis/inc/core_cm23.h new file mode 100644 index 0000000..03cb05d --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm23.h @@ -0,0 +1,1993 @@ +/**************************************************************************//** + * @file core_cm23.h + * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM23_H_GENERIC +#define __CORE_CM23_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M23 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ + __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (23U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM23_H_DEPENDANT +#define __CORE_CM23_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM23_REV + #define __CM23_REV 0x0000U + #warning "__CM23_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M23 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M23 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm3.h b/circuitpython/lib/cmsis/inc/core_cm3.h new file mode 100644 index 0000000..ea54050 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm3.h @@ -0,0 +1,1934 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (3U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ +#endif + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm33.h b/circuitpython/lib/cmsis/inc/core_cm33.h new file mode 100644 index 0000000..c5455d2 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm33.h @@ -0,0 +1,2907 @@ +/**************************************************************************//** + * @file core_cm33.h + * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM33_H_GENERIC +#define __CORE_CM33_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M33 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM33 definitions */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (33U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM33_H_DEPENDANT +#define __CORE_CM33_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM33_REV + #define __CM33_REV 0x0000U + #warning "__CM33_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M33 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm35p.h b/circuitpython/lib/cmsis/inc/core_cm35p.h new file mode 100644 index 0000000..9e2f718 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm35p.h @@ -0,0 +1,2907 @@ +/**************************************************************************//** + * @file core_cm35p.h + * @brief CMSIS Cortex-M35P Core Peripheral Access Layer Header File + * @version V1.0.0 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM35P_H_GENERIC +#define __CORE_CM35P_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M35P + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM35P definitions */ +#define __CM35P_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM35P_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM35P_CMSIS_VERSION ((__CM35P_CMSIS_VERSION_MAIN << 16U) | \ + __CM35P_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (35U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM35P_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM35P_H_DEPENDANT +#define __CORE_CM35P_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM35P_REV + #define __CM35P_REV 0x0000U + #warning "__CM35P_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M35P */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM35P_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm4.h b/circuitpython/lib/cmsis/inc/core_cm4.h new file mode 100644 index 0000000..f205b33 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm4.h @@ -0,0 +1,2121 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_cm7.h b/circuitpython/lib/cmsis/inc/core_cm7.h new file mode 100644 index 0000000..b24ac32 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_cm7.h @@ -0,0 +1,2691 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISDYNADD_Pos 26U /*!< ACTLR: DISDYNADD Position */ +#define SCnSCB_ACTLR_DISDYNADD_Msk (1UL << SCnSCB_ACTLR_DISDYNADD_Pos) /*!< ACTLR: DISDYNADD Mask */ + +#define SCnSCB_ACTLR_DISISSCH1_Pos 21U /*!< ACTLR: DISISSCH1 Position */ +#define SCnSCB_ACTLR_DISISSCH1_Msk (0x1FUL << SCnSCB_ACTLR_DISISSCH1_Pos) /*!< ACTLR: DISISSCH1 Mask */ + +#define SCnSCB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ +#define SCnSCB_ACTLR_DISDI_Msk (0x1FUL << SCnSCB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ + +#define SCnSCB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (1UL << SCnSCB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define SCnSCB_ACTLR_DISBTACALLOC_Pos 14U /*!< ACTLR: DISBTACALLOC Position */ +#define SCnSCB_ACTLR_DISBTACALLOC_Msk (1UL << SCnSCB_ACTLR_DISBTACALLOC_Pos) /*!< ACTLR: DISBTACALLOC Mask */ + +#define SCnSCB_ACTLR_DISBTACREAD_Pos 13U /*!< ACTLR: DISBTACREAD Position */ +#define SCnSCB_ACTLR_DISBTACREAD_Msk (1UL << SCnSCB_ACTLR_DISBTACREAD_Pos) /*!< ACTLR: DISBTACREAD Mask */ + +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + +#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ + + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address. + D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_sc000.h b/circuitpython/lib/cmsis/inc/core_sc000.h new file mode 100644 index 0000000..389535a --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_sc000.h @@ -0,0 +1,1022 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for SC000 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for SC000 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/core_sc300.h b/circuitpython/lib/cmsis/inc/core_sc300.h new file mode 100644 index 0000000..5478ea7 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/core_sc300.h @@ -0,0 +1,1915 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC3000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + uint32_t RESERVED1[1U]; +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/cmsis/inc/mpu_armv7.h b/circuitpython/lib/cmsis/inc/mpu_armv7.h new file mode 100644 index 0000000..4592d60 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/mpu_armv7.h @@ -0,0 +1,272 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.0 + * @date 08. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2017-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/circuitpython/lib/cmsis/inc/mpu_armv8.h b/circuitpython/lib/cmsis/inc/mpu_armv8.h new file mode 100644 index 0000000..8002738 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/mpu_armv8.h @@ -0,0 +1,345 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU + * @version V5.1.0 + * @date 08. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2017-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + ((BASE & MPU_RBAR_BASE_Msk) | \ + ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#if defined(MPU_RLAR_PXN_Pos) + +/** \brief Region Limit Address Register with PXN value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((PXN << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#endif + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif diff --git a/circuitpython/lib/cmsis/inc/tz_context.h b/circuitpython/lib/cmsis/inc/tz_context.h new file mode 100644 index 0000000..facc2c9 --- /dev/null +++ b/circuitpython/lib/cmsis/inc/tz_context.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * @file tz_context.h + * @brief Context Management for Armv8-M TrustZone + * @version V1.0.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef TZ_CONTEXT_H +#define TZ_CONTEXT_H + +#include + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + +/// \details TZ Memory ID identifies an allocated memory slot. +typedef uint32_t TZ_MemoryId_t; + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +uint32_t TZ_InitContextSystem_S (void); + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); + +#endif // TZ_CONTEXT_H diff --git a/circuitpython/lib/crypto-algorithms/sha256.c b/circuitpython/lib/crypto-algorithms/sha256.c new file mode 100644 index 0000000..1d94845 --- /dev/null +++ b/circuitpython/lib/crypto-algorithms/sha256.c @@ -0,0 +1,160 @@ +/********************************************************************* +* Source: https://github.com/B-Con/crypto-algorithms +* Filename: sha256.c +* Author: Brad Conte (brad AT bradconte.com) +* Copyright: This code is released into the public domain. +* Disclaimer: This code is presented "as is" without any guarantees. +* Details: Implementation of the SHA-256 hashing algorithm. + SHA-256 is one of the three algorithms in the SHA2 + specification. The others, SHA-384 and SHA-512, are not + offered in this implementation. + Algorithm specification can be found here: + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf + This implementation uses little endian byte order. +*********************************************************************/ + +/*************************** HEADER FILES ***************************/ +#include +#include +#include +#include "sha256.h" + +/****************************** MACROS ******************************/ +#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) +#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) + +#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) +#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) +#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) +#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) + +/**************************** VARIABLES *****************************/ +static const WORD k[64] = { + 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, + 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, + 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, + 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, + 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, + 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, + 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, + 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +}; + +/*********************** FUNCTION DEFINITIONS ***********************/ +static void sha256_transform(CRYAL_SHA256_CTX *ctx, const BYTE data[]) +{ + WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; + + for (i = 0, j = 0; i < 16; ++i, j += 4) + m[i] = ((uint32_t)data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); + for ( ; i < 64; ++i) + m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; + + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; + + for (i = 0; i < 64; ++i) { + t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; + t2 = EP0(a) + MAJ(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; +} + +void sha256_init(CRYAL_SHA256_CTX *ctx) +{ + ctx->datalen = 0; + ctx->bitlen = 0; + ctx->state[0] = 0x6a09e667; + ctx->state[1] = 0xbb67ae85; + ctx->state[2] = 0x3c6ef372; + ctx->state[3] = 0xa54ff53a; + ctx->state[4] = 0x510e527f; + ctx->state[5] = 0x9b05688c; + ctx->state[6] = 0x1f83d9ab; + ctx->state[7] = 0x5be0cd19; +} + +void sha256_update(CRYAL_SHA256_CTX *ctx, const BYTE data[], size_t len) +{ + WORD i; + + for (i = 0; i < len; ++i) { + ctx->data[ctx->datalen] = data[i]; + ctx->datalen++; + if (ctx->datalen == 64) { + sha256_transform(ctx, ctx->data); + ctx->bitlen += 512; + ctx->datalen = 0; + } + } +} + +void sha256_final(CRYAL_SHA256_CTX *ctx, BYTE hash[]) +{ + WORD i; + + i = ctx->datalen; + + // Pad whatever data is left in the buffer. + if (ctx->datalen < 56) { + ctx->data[i++] = 0x80; + while (i < 56) + ctx->data[i++] = 0x00; + } + else { + ctx->data[i++] = 0x80; + while (i < 64) + ctx->data[i++] = 0x00; + sha256_transform(ctx, ctx->data); + memset(ctx->data, 0, 56); + } + + // Append to the padding the total message's length in bits and transform. + ctx->bitlen += ctx->datalen * 8; + ctx->data[63] = ctx->bitlen; + ctx->data[62] = ctx->bitlen >> 8; + ctx->data[61] = ctx->bitlen >> 16; + ctx->data[60] = ctx->bitlen >> 24; + ctx->data[59] = ctx->bitlen >> 32; + ctx->data[58] = ctx->bitlen >> 40; + ctx->data[57] = ctx->bitlen >> 48; + ctx->data[56] = ctx->bitlen >> 56; + sha256_transform(ctx, ctx->data); + + // Since this implementation uses little endian byte ordering and SHA uses big endian, + // reverse all the bytes when copying the final state to the output hash. + for (i = 0; i < 4; ++i) { + hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; + hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; + hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; + hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; + hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; + hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; + hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; + hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; + } +} diff --git a/circuitpython/lib/crypto-algorithms/sha256.h b/circuitpython/lib/crypto-algorithms/sha256.h new file mode 100644 index 0000000..9c19472 --- /dev/null +++ b/circuitpython/lib/crypto-algorithms/sha256.h @@ -0,0 +1,35 @@ +/********************************************************************* +* Source: https://github.com/B-Con/crypto-algorithms +* Filename: sha256.h +* Author: Brad Conte (brad AT bradconte.com) +* Copyright: This code is released into the public domain. +* Disclaimer: This code is presented "as is" without any guarantees. +* Details: Defines the API for the corresponding SHA1 implementation. +*********************************************************************/ + +#ifndef SHA256_H +#define SHA256_H + +/*************************** HEADER FILES ***************************/ +#include + +/****************************** MACROS ******************************/ +#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest + +/**************************** DATA TYPES ****************************/ +typedef unsigned char BYTE; // 8-bit byte +typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines + +typedef struct { + BYTE data[64]; + WORD datalen; + unsigned long long bitlen; + WORD state[8]; +} CRYAL_SHA256_CTX; + +/*********************** FUNCTION DECLARATIONS **********************/ +void sha256_init(CRYAL_SHA256_CTX *ctx); +void sha256_update(CRYAL_SHA256_CTX *ctx, const BYTE data[], size_t len); +void sha256_final(CRYAL_SHA256_CTX *ctx, BYTE hash[]); + +#endif // SHA256_H diff --git a/circuitpython/lib/libffi/.travis.yml b/circuitpython/lib/libffi/.travis.yml new file mode 100644 index 0000000..6c14fcd --- /dev/null +++ b/circuitpython/lib/libffi/.travis.yml @@ -0,0 +1,22 @@ +language: cpp +compiler: + - gcc + - clang +env: + - + - HOST=i386-pc-linux-gnu +matrix: + exclude: + - compiler: clang + env: HOST=i386-pc-linux-gnu + +before_script: + - sudo apt-get install dejagnu texinfo + - if [ "$HOST" = i386-pc-linux-gnu ] ; then sudo apt-get install gcc-multilib g++-multilib && CC="$CC -m32" && CXX="$CXX -m32" ; fi + +script: + - ./autogen.sh + - ./configure ${HOST+--host=$HOST} + - make + - make dist + - make check diff --git a/circuitpython/lib/libffi/ChangeLog.libffi b/circuitpython/lib/libffi/ChangeLog.libffi new file mode 100644 index 0000000..49ba8da --- /dev/null +++ b/circuitpython/lib/libffi/ChangeLog.libffi @@ -0,0 +1,584 @@ +2011-02-08 Andreas Tobler + + * testsuite/lib/libffi.exp: Tweak for stand-alone mode. + +2009-12-25 Samuli Suominen + + * configure.ac: Undefine _AC_ARG_VAR_PRECIOUS for autoconf 2.64. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + +2009-06-16 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + * testsuite/libffi.call/huge_struct.c: Ad x86 XFAILs. + * testsuite/libffi.call/float2.c: Fix dg-excess-errors. + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. + +2009-06-12 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + testsuite/libffi.special/unwindtest.cc: include stdint.h. + +2009-06-11 Timothy Wall + + * Makefile.am, + configure.ac, + include/ffi.h.in, + include/ffi_common.h, + src/closures.c, + src/dlmalloc.c, + src/x86/ffi.c, + src/x86/ffitarget.h, + src/x86/win64.S (new), + README: Added win64 support (mingw or MSVC) + * Makefile.in, + include/Makefile.in, + man/Makefile.in, + testsuite/Makefile.in, + configure, + aclocal.m4: Regenerated + * ltcf-c.sh: properly escape cygwin/w32 path + * man/ffi_call.3: Clarify size requirements for return value. + * src/x86/ffi64.c: Fix filename in comment. + * src/x86/win32.S: Remove unused extern. + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/err_bad_abi.c, + testsuite/libffi.call/err_bad_typedef.c, + testsuite/libffi.call/float2.c, + testsuite/libffi.call/huge_struct.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/return_ldl.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead + of checking for MMAP. Use intptr_t instead of long casts. + +2009-06-04 Andrew Haley + + * src/powerpc/ffitarget.h: Fix misapplied merge from gcc. + +2009-06-04 Andrew Haley + + * src/mips/o32.S, + src/mips/n32.S: Fix licence formatting. + +2009-06-04 Andrew Haley + + * src/x86/darwin.S: Fix licence formatting. + src/x86/win32.S: Likewise. + src/sh64/sysv.S: Likewise. + src/sh/sysv.S: Likewise. + +2009-06-04 Andrew Haley + + * src/sh64/ffi.c: Remove lint directives. Was missing from merge + of Andreas Tobler's patch from 2006-04-22. + +2009-06-04 Andrew Haley + + * src/sh/ffi.c: Apply missing hunk from Alexandre Oliva's patch of + 2007-03-07. + +2008-12-26 Timothy Wall + + * testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected + failures on x86_64 cygwin/mingw. + +2008-12-22 Timothy Wall + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_loc_fn0.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: use portable cast from + pointer to integer (intptr_t). + * testsuite/libffi.call/cls_longdouble.c: disable for win64. + +2008-12-19 Anthony Green + + * configure.ac: Bump version to 3.0.8. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-11-11 Anthony Green + + * configure.ac: Bump version to 3.0.7. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-08-25 Andreas Tobler + + * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and + FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum. + Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT. + Adjust copyright notice. + * src/powerpc/ffi.c: Add two new flags to indicate if we have one + register or two register to use for FFI_SYSV structs. + (ffi_prep_cif_machdep): Pass the right register flag introduced above. + (ffi_closure_helper_SYSV): Fix the return type for + FFI_SYSV_TYPE_SMALL_STRUCT. Comment. + Adjust copyright notice. + +2008-07-24 Anthony Green + + * testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/err_bad_abi.c: Clean up failures from + compiler warnings. + +2008-07-17 Anthony Green + + * configure.ac: Bump version to 3.0.6. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. Add documentation. + * README: Update for new release. + +2008-07-16 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned + int. + +2008-07-16 Kaz Kojima + + * src/sh/sysv.S: Add .note.GNU-stack on Linux. + * src/sh64/sysv.S: Likewise. + +2008-04-03 Anthony Green + + * libffi.pc.in (Libs): Add -L${libdir}. + * configure.ac: Bump version to 3.0.5. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-04-03 Anthony Green + Xerces Ranby + + * include/ffi.h.in: Wrap definition of target architecture to + protect from double definitions. + +2008-03-22 Moriyoshi Koizumi + + * src/x86/ffi.c (ffi_prep_closure_loc): Fix for bug revealed in + closure_loc_fn0.c. + * testsuite/libffi.call/closure_loc_fn0.c (closure_loc_test_fn0): + New test. + +2008-03-04 Anthony Green + Blake Chaffin + hos@tamanegi.org + + * testsuite/libffi.call/cls_align_longdouble_split2.c + testsuite/libffi.call/cls_align_longdouble_split.c + testsuite/libffi.call/cls_dbls_struct.c + testsuite/libffi.call/cls_double_va.c + testsuite/libffi.call/cls_longdouble.c + testsuite/libffi.call/cls_longdouble_va.c + testsuite/libffi.call/cls_pointer.c + testsuite/libffi.call/cls_pointer_stack.c + testsuite/libffi.call/err_bad_abi.c + testsuite/libffi.call/err_bad_typedef.c + testsuite/libffi.call/huge_struct.c + testsuite/libffi.call/stret_large2.c + testsuite/libffi.call/stret_large.c + testsuite/libffi.call/stret_medium2.c + testsuite/libffi.call/stret_medium.c: New tests from Apple. + +2008-02-26 Jakub Jelinek + Anthony Green + + * src/alpha/osf.S: Add .note.GNU-stack on Linux. + * src/s390/sysv.S: Likewise. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + * src/x86/unix64.S: Likewise. + * src/x86/sysv.S: Likewise. + * src/sparc/v8.S: Likewise. + * src/sparc/v9.S: Likewise. + * src/m68k/sysv.S: Likewise. + * src/ia64/unix.S: Likewise. + * src/arm/sysv.S: Likewise. + +2008-02-26 Anthony Green + Thomas Heller + + * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C + comment. + +2008-02-26 Anthony Green + Thomas Heller + + * include/ffi.h.in: Change void (*)() to void (*)(void). + +2008-02-26 Anthony Green + Thomas Heller + + * src/alpha/ffi.c: Change void (*)() to void (*)(void). + src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c, + src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c, + src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S, + src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c, + src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c, + src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S, + src/x86/ffi64.c: Ditto. + +2008-02-24 Anthony Green + + * configure.ac: Accept openbsd*, not just openbsd. + Bump version to 3.0.4. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-02-22 Anthony Green + + * README: Clean up list of tested platforms. + +2008-02-22 Anthony Green + + * configure.ac: Bump version to 3.0.3. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. Clean up test docs. + +2008-02-22 Bjoern Koenig + Andreas Tobler + + * configure.ac: Add amd64-*-freebsd* target. + * configure: Regenerate. + +2008-02-22 Thomas Heller + + * configure.ac: Add x86 OpenBSD support. + * configure: Rebuilt. + +2008-02-21 Thomas Heller + + * README: Change "make test" to "make check". + +2008-02-21 Anthony Green + + * configure.ac: Bump version to 3.0.2. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-02-21 Björn König + + * src/x86/freebsd.S: New file. + * configure.ac: Add x86 FreeBSD support. + * Makefile.am: Ditto. + +2008-02-15 Anthony Green + + * configure.ac: Bump version to 3.0.1. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-02-15 David Daney + + * src/mips/ffi.c: Remove extra '>' from include directive. + (ffi_prep_closure_loc): Use clear_location instead of tramp. + +2008-02-15 Anthony Green + + * configure.ac: Bump version to 3.0.0. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +2008-02-15 David Daney + + * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): + Define (conditionally), and use it to include cachectl.h. + (ffi_prep_closure_loc): Fix cache flushing. + * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. + +2008-02-15 Anthony Green + + * man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3: + Update dates and remove all references to ffi_prep_closure. + * configure.ac: Bump version to 2.99.9. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +2008-02-15 Anthony Green + + * man/ffi_prep_closure.3: Delete. + * man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3. + (man_MANS): Ditto. + * man/Makefile.in: Rebuilt. + * configure.ac: Bump version to 2.99.8. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +2008-02-14 Anthony Green + + * configure.ac: Bump version to 2.99.7. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * include/ffi.h.in LICENSE src/debug.c src/closures.c + src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h + src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c + src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S + src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c + src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c + src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S + src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h + src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c + src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S + src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h + src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h + src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S + src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h + src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S + src/arm/ffitarget.h src/prep_cif.c: Update license text. + +2008-02-14 Anthony Green + + * README: Update tested platforms. + * configure.ac: Bump version to 2.99.6. + * configure: Rebuilt. + +2008-02-14 Anthony Green + + * configure.ac: Bump version to 2.99.5. + * configure: Rebuilt. + * Makefile.am (EXTRA_DIST): Add darwin64.S + * Makefile.in: Rebuilt. + * testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree. + * LICENSE: Update WARRANTY. + +2008-02-14 Anthony Green + + * libffi.pc.in (libdir): Fix libdir definition. + * configure.ac: Bump version to 2.99.4. + * configure: Rebuilt. + +2008-02-14 Anthony Green + + * README: Update. + * libffi.info: New file. + * doc/stamp-vti: New file. + * configure.ac: Bump version to 2.99.3. + * configure: Rebuilt. + +2008-02-14 Anthony Green + + * Makefile.am (SUBDIRS): Add man dir. + * Makefile.in: Rebuilt. + * configure.ac: Create Makefile. + * configure: Rebuilt. + * man/ffi_call.3 man/ffi_prep_cif.3 man/ffi_prep_closure.3 + man/Makefile.am man/Makefile.in: New files. + +2008-02-14 Tom Tromey + + * aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt. + * mdate-sh, texinfo.tex: New files. + * Makefile.am (info_TEXINFOS): New variable. + * doc/libffi.texi: New file. + * doc/version.texi: Likewise. + +2008-02-14 Anthony Green + + * Makefile.am (AM_CFLAGS): Don't compile with -D$(TARGET). + (lib_LTLIBRARIES): Define. + (toolexeclib_LIBRARIES): Undefine. + * Makefile.in: Rebuilt. + * configure.ac: Reset version to 2.99.1. + * configure.in: Rebuilt. + +2008-02-14 Anthony Green + + * libffi.pc.in: Use @PACKAGE_NAME@ and @PACKAGE_VERSION@. + * configure.ac: Reset version to 2.99.1. + * configure.in: Rebuilt. + * Makefile.am (EXTRA_DIST): Add ChangeLog.libffi. + * Makefile.in: Rebuilt. + * LICENSE: Update copyright notice. + +2008-02-14 Anthony Green + + * include/Makefile.am (nodist_includes_HEADERS): Define. Don't + distribute ffitarget.h or ffi.h from the build include dir. + * Makefile.in: Rebuilt. + +2008-02-14 Anthony Green + + * include/Makefile.am (includesdir): Install headers under libdir. + (pkgconfigdir): Define. Install libffi.pc. + * include/Makefile.in: Rebuilt. + * libffi.pc.in: Create. + * libtool-version: Increment CURRENT + * configure.ac: Add libffi.pc.in + * configure: Rebuilt. + +2008-02-03 Anthony Green + + * include/Makefile.am (includesdir): Fix header install with + DESTDIR. + * include/Makefile.in: Rebuilt. + +2008-02-03 Timothy Wall + + * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return + offset based on code pointer, not data pointer. + +2008-02-01 Anthony Green + + * include/Makefile.am: Fix header installs. + * Makefile.am: Ditto. + * include/Makefile.in: Rebuilt. + * Makefile.in: Ditto. + +2008-02-01 Anthony Green + + * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL, + FFI_INIT_TRAMPOLINE): Revert my broken changes to twall's last + patch. + +2008-01-31 Anthony Green + + * Makefile.am (EXTRA_DIST): Add missing files. + * testsuite/Makefile.am: Ditto. + * Makefile.in, testsuite/Makefile.in: Rebuilt. + +2008-01-31 Timothy Wall + + * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall + closures. + * src/x86/ffitarget.h: Increase size of trampoline for stdcall + closures. + * src/x86/win32.S: Add assembly for stdcall closure. + * src/x86/ffi.c: Initialize stdcall closure trampoline. + +2008-01-30 H.J. Lu + + PR libffi/34612 + * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when + returning struct. + + * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer" + tests. + +2008-01-30 Anthony Green + + * Makefile.am, include/Makefile.am: Move headers to + libffi_la_SOURCES for new automake. + * Makefile.in, include/Makefile.in: Rebuilt. + + * testsuite/lib/wrapper.exp: Copied from gcc tree to allow for + execution outside of gcc tree. + * testsuite/lib/target-libpath.exp: Ditto. + + * testsuite/lib/libffi-dg.exp: Many changes to allow for execution + outside of gcc tree. + diff --git a/circuitpython/lib/libffi/ChangeLog.libffi-3.1 b/circuitpython/lib/libffi/ChangeLog.libffi-3.1 new file mode 100644 index 0000000..8f7f50d --- /dev/null +++ b/circuitpython/lib/libffi/ChangeLog.libffi-3.1 @@ -0,0 +1,6000 @@ +2014-03-16 Josh Triplett + + * ChangeLog: Archive to ChangeLog.libffi-3.1 and delete. Future + changelogs will come from git, with autogenerated snapshots shipped in + distributed tarballs. + +2014-03-16 Josh Triplett + + Add support for stdcall, thiscall, and fastcall on non-Windows + x86-32. + + Linux supports the stdcall calling convention, either via + functions explicitly declared with the stdcall attribute, or via + code compiled with -mrtd which effectively makes stdcall the + default. + + This introduces FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL on + non-Windows x86-32 platforms, as non-default calling conventions. + + * Makefile.am: Compile in src/x86/win32.S on non-Windows x86-32. + * src/x86/ffitarget.h: Add FFI_STDCALL, FFI_THISCALL, and + FFI_FASTCALL on non-Windows x86-32. Increase trampoline size to + accomodate these calling conventions, and unify some ifdeffery. + * src/x86/ffi.c: Add support for FFI_STDCALL, FFI_THISCALL, and + FFI_FASTCALL on non-Windows x86-32 platforms; update ifdeffery. + * src/x86/win32.S: Support compiling on non-Windows x86-32 + platforms. On those platforms, avoid redefining the SYSV symbols + already provided by src/x86/sysv.S. + * testsuite/libffi.call/closure_stdcall.c: Run on non-Windows. + #define __stdcall if needed. + * testsuite/libffi.call/closure_thiscall.c: Run on non-Windows. + #define __fastcall if needed. + * testsuite/libffi.call/fastthis1_win32.c: Run on non-Windows. + * testsuite/libffi.call/fastthis2_win32.c: Ditto. + * testsuite/libffi.call/fastthis3_win32.c: Ditto. + * testsuite/libffi.call/many2_win32.c: Ditto. + * testsuite/libffi.call/many_win32.c: Ditto. + * testsuite/libffi.call/strlen2_win32.c: Ditto. + * testsuite/libffi.call/strlen_win32.c: Ditto. + * testsuite/libffi.call/struct1_win32.c: Ditto. + * testsuite/libffi.call/struct2_win32.c: Ditto. + +2014-03-16 Josh Triplett + + * prep_cif.c: Remove unnecessary ifdef for X86_WIN32. + ffi_prep_cif_core had a special case for X86_WIN32, checking for + FFI_THISCALL in addition to the FFI_FIRST_ABI-to-FFI_LAST_ABI + range before returning FFI_BAD_ABI. However, on X86_WIN32, + FFI_THISCALL already falls in that range, making the special case + unnecessary. Remove it. + +2014-03-16 Josh Triplett + + * testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/closure_thiscall.c: Remove fragile stack + pointer checks. These files included inline assembly to save the + stack pointer before and after the call, and compare the values. + However, compilers can and do leave the stack in different states + for these two pieces of inline assembly, such as by saving a + temporary value on the stack across the call; observed with gcc + -Os, and verified as spurious through careful inspection of + disassembly. + +2014-03-16 Josh Triplett + + * testsuite/libffi.call/many.c: Avoid spurious failure due to + excess floating-point precision. + * testsuite/libffi.call/many_win32.c: Ditto. + +2014-03-16 Josh Triplett + + * libtool-ldflags: Re-add. + +2014-03-16 Josh Triplett + + * Makefile.in, aclocal.m4, compile, config.guess, config.sub, + configure, depcomp, include/Makefile.in, install-sh, + libtool-ldflags, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, + m4/ltsugar.m4, m4/ltversion.m4, m4/lt~obsolete.m4, + man/Makefile.in, mdate-sh, missing, testsuite/Makefile.in: Delete + autogenerated files from version control. + * .gitignore: Add autogenerated files. + * autogen.sh: New script to generate the autogenerated files. + * README: Document requirement to run autogen.sh when building + directly from version control. + * .travis.yml: Run autogen.sh + +2014-03-14 Anthony Green + + * configure, Makefile.in: Rebuilt. + +2014-03-10 Mike Hommey + + * configure.ac: Allow building for mipsel with Android NDK r8. + * Makefile.am (AM_MAKEFLAGS): Replace double quotes with single + quotes. + +2014-03-10 Landry Breuil + + * configure.ac: Ensure the linker supports @unwind sections in libffi. + +2014-03-01 Anthony Green + + * Makefile.am (EXTRA_DIST): Replace old scripts with + generate-darwin-source-and-headers.py. + * Makefile.in: Rebuilt. + +2014-02-28 Anthony Green + + * Makefile.am (AM_CFLAGS): Reintroduce missing -DFFI_DEBUG for + --enable-debug builds. + * Makefile.in: Rebuilt. + +2014-02-28 Makoto Kato + + * src/closures.c: Fix build failure when using clang for Android. + +2014-02-28 Marcin Wojdyr + + * libffi.pc.in (toolexeclibdir): use -L${toolexeclibdir} instead + of -L${libdir}. + +2014-02-28 Paulo Pizarro + + * src/bfin/sysv.S: Calling functions in shared libraries requires + considering the GOT. + +2014-02-28 Josh Triplett + + * src/x86/ffi64.c (classify_argument): Handle case where + FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE. + +2014-02-28 Anthony Green + + * ltmain.sh: Generate with libtool-2.4.2.418. + * m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4: Ditto. + * configure: Rebuilt. + +2014-02-28 Dominik Vogt + + * configure.ac (AC_ARG_ENABLE struct): Fix typo in help + message. + (AC_ARG_ENABLE raw_api): Ditto. + * configure, fficonfig.h.in: Rebuilt. + +2014-02-28 Will Newton + + * src/arm/sysv.S: Initialize IP register with FP. + +2014-02-28 Yufeng Zhang + + * src/aarch64/sysv.S (ffi_closure_SYSV): Use x29 as the + main CFA reg; update cfi_rel_offset. + +2014-02-15 Marcus Comstedt + + * src/powerpc/ffi_linux64.c, src/powerpc/linux64_closure.S: Remove + assumption on contents of r11 in closure. + +2014-02-09 Heiher + + * src/mips/n32.S: Fix call floating point va function. + +2014-01-21 Zachary Waldowski + + * src/aarch64/ffi.c: Fix missing semicolons on assertions under + debug mode. + +2013-12-30 Zachary Waldowski + + * .gitignore: Exclude darwin_* generated source and build_* trees. + * src/aarch64/ffi.c, src/arm/ffi.c, src/x86/ffi.c: Inhibit Clang + previous prototype warnings. + * src/arm/ffi.c: Prevent NULL dereference, fix short type warning + * src/dlmalloc.c: Fix warnings from set_segment_flags return type, + and the native use of size_t for malloc on platforms + * src/arm/sysv.S: Use unified syntax. Clang clean-ups for + ARM_FUNC_START. + * generate-osx-source-and-headers.py: Remove. + * build-ios.sh: Remove. + * libffi.xcodeproj/project.pbxproj: Rebuild targets. Include + x86_64+aarch64 pieces in library. Export headers properly. + * src/x86/ffi64.c: More Clang warning clean-ups. + * src/closures.c (open_temp_exec_file_dir): Use size_t. + * src/prep_cif.c (ffi_prep_cif_core): Cast ALIGN result. + * src/aarch64/sysv.S: Use CNAME for global symbols. Only use + .size for ELF targets. + * src/aarch64/ffi.c: Clean up for double == long double. Clean up + from Clang warnings. Use Clang cache invalidation builtin. Use + size_t in place of unsigned in many places. Accommodate for + differences in Apple AArch64 ABI. + +2013-12-02 Daniel Rodríguez Troitiño + + * generate-darwin-source-and-headers.py: Clean up, modernize, + merged version of previous scripts. + +2013-11-21 Anthony Green + + * configure, Makefile.in, include/Makefile.in, include/ffi.h.in, + man/Makefile.in, testsuite/Makefile.in, fficonfig.h.in: Rebuilt. + +2013-11-21 Alan Modra + + * Makefile.am (EXTRA_DIST): Add new src/powerpc files. + (nodist_libffi_la_SOURCES ): Likewise. + * configure.ac (HAVE_LONG_DOUBLE_VARIANT): Define for powerpc. + * include/ffi.h.in (ffi_prep_types): Declare. + * src/prep_cif.c (ffi_prep_cif_core): Call ffi_prep_types. + * src/types.c (FFI_NONCONST_TYPEDEF): Define and use for + HAVE_LONG_DOUBLE_VARIANT. + * src/powerpc/ffi_powerpc.h: New file. + * src/powerpc/ffi.c: Split into.. + * src/powerpc/ffi_sysv.c: ..new file, and.. + * src/powerpc/ffi_linux64.c: ..new file, rewriting parts. + * src/powerpc/ffitarget.h (enum ffi_abi): Rewrite powerpc ABI + selection as bits controlling features. + * src/powerpc/linux64.S: For consistency, use POWERPC64 rather + than __powerpc64__. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. Move .note.FNU-stack + inside guard. + * src/powerpc/sysv.S: Likewise. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * Makefile.in: Regenerate. + +2013-11-20 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use + NUM_FPR_ARG_REGISTERS64 and NUM_GPR_ARG_REGISTERS64 not their + 32-bit versions for 64-bit code. + * src/powerpc/linux64_closure.S: Don't use the return value area + as a parameter save area on ELFv2. + +2013-11-18 Iain Sandoe + + * src/powerpc/darwin.S (EH): Correct use of pcrel FDE encoding. + * src/powerpc/darwin_closure.S (EH): Likewise. Modernise picbase + labels. + +2013-11-18 Anthony Green + + * src/arm/ffi.c (ffi_call): Hoist declaration of temp to top of + function. + * src/arm/ffi.c (ffi_closure_inner): Moderize function declaration + to appease compiler. + Thanks for Gregory P. Smith . + +2013-11-18 Anthony Green + + * README (tested): Mention PowerPC ELFv2. + +2013-11-16 Alan Modra + + * src/powerpc/ppc_closure.S: Move errant #endif to where it belongs. + Don't bl .Luint128. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use #if _CALL_ELF + test to select parameter save sizing for ELFv2 vs. ELFv1. + * src/powerpc/ffitarget.h (FFI_V2_TYPE_FLOAT_HOMOG, + FFI_V2_TYPE_DOUBLE_HOMOG, FFI_V2_TYPE_SMALL_STRUCT): Define. + (FFI_TRAMPOLINE_SIZE): Define variant for ELFv2. + * src/powerpc/ffi.c (FLAG_ARG_NEEDS_PSAVE): Define. + (discover_homogeneous_aggregate): New function. + (ffi_prep_args64): Adjust start of param save area for ELFv2. + Handle homogenous floating point struct parms. + (ffi_prep_cif_machdep_core): Adjust space calculation for ELFv2. + Handle ELFv2 return values. Set FLAG_ARG_NEEDS_PSAVE. Handle + homogenous floating point structs. + (ffi_call): Increase size of smst_buffer for ELFv2. Handle ELFv2. + (flush_icache): Compile for ELFv2. + (ffi_prep_closure_loc): Set up ELFv2 trampoline. + (ffi_closure_helper_LINUX64): Don't return all structs directly + to caller. Handle homogenous floating point structs. Handle + ELFv2 struct return values. + * src/powerpc/linux64.S (ffi_call_LINUX64): Set up r2 for + ELFv2. Adjust toc save location. Call function pointer using + r12. Handle FLAG_RETURNS_SMST. Don't predict branches. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Set up r2 + for ELFv2. Define ELFv2 versions of STACKFRAME, PARMSAVE, and + RETVAL. Handle possibly missing parameter save area. Handle + ELFv2 return values. + (.note.GNU-stack): Move inside outer #ifdef. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Revert 2013-02-08 + change. Do not consume an int arg when returning a small struct + for FFI_SYSV ABI. + (ffi_call): Only use bounce buffer when FLAG_RETURNS_SMST. + Properly copy bounce buffer to destination. + * src/powerpc/sysv.S: Revert 2013-02-08 change. + * src/powerpc/ppc_closure.S: Remove stray '+'. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args64): Align struct parameters + according to __STRUCT_PARM_ALIGN__. + (ffi_prep_cif_machdep_core): Likewise. + (ffi_closure_helper_LINUX64): Likewise. + +2013-11-16 Alan Modra + + * src/powerpc/linux64.S (ffi_call_LINUX64): Tweak restore of r28. + (.note.GNU-stack): Move inside outer #ifdef. + * src/powerpc/linux64_closure.S (STACKFRAME, PARMSAVE, + RETVAL): Define and use throughout. + (ffi_closure_LINUX64): Save fprs before buying stack. + (.note.GNU-stack): Move inside outer #ifdef. + +2013-11-16 Alan Modra + + * src/powerpc/ffitarget.h (FFI_TARGET_SPECIFIC_VARIADIC): Define. + (FFI_EXTRA_CIF_FIELDS): Define. + * src/powerpc/ffi.c (ffi_prep_args64): Save fprs as per the + ABI, not to both fpr and param save area. + (ffi_prep_cif_machdep_core): Renamed from ffi_prep_cif_machdep. + Keep initial flags. Formatting. Remove dead FFI_LINUX_SOFT_FLOAT + code. + (ffi_prep_cif_machdep, ffi_prep_cif_machdep_var): New functions. + (ffi_closure_helper_LINUX64): Pass floating point as per ABI, + not to both fpr and parameter save areas. + + * libffi/testsuite/libffi.call/cls_double_va.c (main): Correct + function cast and don't call ffi_prep_cif. + * libffi/testsuite/libffi.call/cls_longdouble_va.c (main): Likewise. + +2013-11-15 Andrew Haley + + * doc/libffi.texi (Closure Example): Fix the sample code. + * doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt. + +2013-11-15 Andrew Haley + + * testsuite/libffi.call/va_struct1.c (main): Fix broken test. + * testsuite/libffi.call/cls_uint_va.c (cls_ret_T_fn): Likewise + * testsuite/libffi.call/cls_struct_va1.c (test_fn): Likewise. + * testsuite/libffi.call/va_1.c (main): Likewise. + +2013-11-14 David Schneider + + * src/arm/ffi.c: Fix register allocation for mixed float and + doubles. + * testsuite/libffi.call/cls_many_mixed_float_double.c: Testcase + for many mixed float and double arguments. + +2013-11-13 Alan Modra + + * doc/libffi.texi (Simple Example): Correct example code. + * doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt. + +2013-11-13 Anthony Green + + * include/ffi_common.h: Respect HAVE_ALLOCA_H for GNU compiler + based build. (Thanks to tmr111116 on github) + +2013-11-09 Anthony Green + + * m4/libtool.m4: Refresh. + * configure, Makefile.in: Rebuilt. + * README: Add more notes about next release. + +2013-11-09 Shigeharu TAKENO + + * m4/ax_gcc_archflag.m4 (ax_gcc_arch): Don't recognize + UltraSPARC-IIi as ultrasparc3. + +2013-11-06 Mark Kettenis + + * src/x86/freebsd.S (ffi_call_SYSV): Align the stack pointer to + 16-bytes. + +2013-11-06 Konstantin Belousov + + * src/x86/freebsd.S (ffi_closure_raw_SYSV): Mark the assembler + source as not requiring executable stack. + +2013-11-02 Anthony Green + + * doc/libffi.texi (The Basics): Clarify return value buffer size + requirements. Also, NULL result buffer pointers are no longer + supported. + * doc/libffi.info: Rebuilt. + +2013-11-02 Mischa Jonker + + * Makefile.am (nodist_libffi_la_SOURCES): Fix build error. + * Makefile.in: Rebuilt. + +2013-11-02 David Schneider + + * src/arm/ffi.c: more robust argument handling for closures on arm hardfloat + * testsuite/libffi.call/many_mixed.c: New file. + * testsuite/libffi.call/cls_many_mixed_args.c: More tests. + +2013-11-02 Vitaly Budovski + + * src/x86/ffi.c (ffi_prep_cif_machdep): Don't align stack for win32. + +2013-10-23 Mark H Weaver + + * src/mips/ffi.c: Fix handling of uint32_t arguments on the + MIPS N32 ABI. + +2013-10-13 Sandra Loosemore + + * README: Add Nios II to table of supported platforms. + * Makefile.am (EXTRA_DIST): Add nios2 files. + (nodist_libffi_la_SOURCES): Likewise. + * Makefile.in: Regenerated. + * configure.ac (nios2*-linux*): New host. + (NIOS2): Add AM_CONDITIONAL. + * configure: Regenerated. + * src/nios2/ffi.c: New. + * src/nios2/ffitarget.h: New. + * src/nios2/sysv.S: New. + * src/prep_cif.c (initialize_aggregate): Handle extra structure + alignment via FFI_AGGREGATE_ALIGNMENT. + (ffi_prep_cif_core): Conditionalize structure return for NIOS2. + +2013-10-10 Sandra Loosemore + + * testsuite/libffi.call/cls_many_mixed_args.c (cls_ret_double_fn): + Fix uninitialized variable. + +2013-10-11 Marcus Shawcroft + + * testsuite/libffi.call/many.c (many): Replace * with +. + +2013-10-08 Ondřej Bílka + + * src/aarch64/ffi.c, src/aarch64/sysv.S, src/arm/ffi.c, + src/arm/gentramp.sh, src/bfin/sysv.S, src/closures.c, + src/dlmalloc.c, src/ia64/ffi.c, src/microblaze/ffi.c, + src/microblaze/sysv.S, src/powerpc/darwin_closure.S, + src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/sh/ffi.c, + src/tile/tile.S, testsuite/libffi.call/nested_struct11.c: Fix + spelling errors. + +2013-10-08 Anthony Green + + * aclocal.m4, compile, config.guess, config.sub, depcomp, + install-sh, mdate-sh, missing, texinfo.tex: Update from upstream. + * configure.ac: Update version to 3.0.14-rc0. + * Makefile.in, configure, Makefile.in, include/Makefile.in, + man/Makefile.in, testsuite/Makefile.in: Rebuilt. + * README: Mention M88K and VAX. + +2013-07-15 Miod Vallat + + * Makefile.am, + configure.ac, + src/m88k/ffi.c, + src/m88k/ffitarget.h, + src/m88k/obsd.S, + src/vax/elfbsd.S, + src/vax/ffi.c, + src/vax/ffitarget.h: Add m88k and vax support. + +2013-06-24 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration + before statements. + (ffi_prep_args64): Support little-endian. + (ffi_closure_helper_SYSV, ffi_closure_helper_LINUX64): Likewise. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Likewise. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Likewise. + +2013-06-12 Mischa Jonker + + * configure.ac: Add support for ARC. + * Makefile.am: Likewise. + * README: Add ARC details. + * src/arc/arcompact.S: New. + * src/arc/ffi.c: Likewise. + * src/arc/ffitarget.h: Likewise. + +2013-03-28 David Schneider + + * src/arm/ffi.c: Fix support for ARM hard-float calling convention. + * src/arm/sysv.S: call different methods for SYSV and VFP ABIs. + * testsuite/libffi.call/cls_many_mixed_args.c: testcase for a closure with + mixed arguments, many doubles. + * testsuite/libffi.call/many_double.c: testcase for calling a function using + more than 8 doubles. + * testcase/libffi.call/many.c: use absolute value to check result against an + epsilon + +2013-03-17 Anthony Green + + * README: Update for 3.0.13. + * configure.ac: Ditto. + * configure: Rebuilt. + * doc/*: Update version. + +2013-03-17 Dave Korn + + * src/closures.c (is_emutramp_enabled + [!FFI_MMAP_EXEC_EMUTRAMP_PAX]): Move default definition outside + enclosing #if scope. + +2013-03-17 Anthony Green + + * configure.ac: Only modify toolexecdir in certain cases. + * configure: Rebuilt. + +2013-03-16 Gilles Talis + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Don't use + fparg_count,etc on __NO_FPRS__ targets. + +2013-03-16 Alan Hourihane + + * src/m68k/sysv.S (epilogue): Don't use extb instruction on + m680000 machines. + +2013-03-16 Alex Gaynor + + * src/x86/ffi.c (ffi_prep_cif_machdep): Always align stack. + +2013-03-13 Markos Chandras + + * configure.ac: Add support for Imagination Technologies Meta. + * Makefile.am: Likewise. + * README: Add Imagination Technologies Meta details. + * src/metag/ffi.c: New. + * src/metag/ffitarget.h: Likewise. + * src/metag/sysv.S: Likewise. + +2013-02-24 Andreas Schwab + + * doc/libffi.texi (Structures): Fix missing category argument of + @deftp. + +2013-02-11 Anthony Green + + * configure.ac: Update release number to 3.0.12. + * configure: Rebuilt. + * README: Update release info. + +2013-02-10 Anthony Green + + * README: Add Moxie. + * src/moxie/ffi.c: Created. + * src/moxie/eabi.S: Created. + * src/moxie/ffitarget.h: Created. + * Makefile.am (nodist_libffi_la_SOURCES): Add Moxie. + * Makefile.in: Rebuilt. + * configure.ac: Add Moxie. + * configure: Rebuilt. + * testsuite/libffi.call/huge_struct.c: Disable format string + warnings for moxie*-*-elf tests. + +2013-02-10 Anthony Green + + * Makefile.am (LTLDFLAGS): Fix reference. + * Makefile.in: Rebuilt. + +2013-02-10 Anthony Green + + * README: Update supported platforms. Update test results link. + +2013-02-09 Anthony Green + + * testsuite/libffi.call/negint.c: Remove forced -O2. + * testsuite/libffi.call/many2.c (foo): Remove GCCism. + * testsuite/libffi.call/ffitest.h: Add default PRIuPTR definition. + + * src/sparc/v8.S (ffi_closure_v8): Import ancient ulonglong + closure return type fix developed by Martin v. Löwis for cpython + fork. + +2013-02-08 Andreas Tobler + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix small struct + support. + * src/powerpc/sysv.S: Ditto. + +2013-02-08 Anthony Green + + * testsuite/libffi.call/cls_longdouble.c: Remove xfail for + arm*-*-*. + +2013-02-08 Anthony Green + + * src/sparc/ffi.c (ffi_prep_closure_loc): Fix cache flushing for GCC. + +2013-02-08 Matthias Klose + + * man/ffi_prep_cif.3: Clean up for debian linter. + +2013-02-08 Peter Bergner + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Account for FP args pushed + on the stack. + +2013-02-08 Anthony Green + + * Makefile.am (EXTRA_DIST): Add missing files. + * testsuite/Makefile.am (EXTRA_DIST): Ditto. + * Makefile.in: Rebuilt. + +2013-02-08 Anthony Green + + * configure.ac: Move sparc asm config checks to within functions + for compatibility with sun tools. + * configure: Rebuilt. + * src/sparc/ffi.c (ffi_prep_closure_loc): Flush cache on v9 + systems. + * src/sparc/v8.S (ffi_flush_icache): Implement a sparc v9 cache + flusher. + +2013-02-08 Nathan Rossi + + * src/microblaze/ffi.c (ffi_closure_call_SYSV): Fix handling of + small big-endian structures. + (ffi_prep_args): Ditto. + +2013-02-07 Anthony Green + + * src/sparc/v8.S (ffi_call_v8): Fix typo from last patch + (effectively hiding ffi_call_v8). + +2013-02-07 Anthony Green + + * configure.ac: Update bug reporting address. + * configure.in: Rebuild. + + * src/sparc/v8.S (ffi_flush_icache): Out-of-line cache flusher for + Sun compiler. + * src/sparc/ffi.c (ffi_call): Remove warning. + Call ffi_flush_icache for non-GCC builds. + (ffi_prep_closure_loc): Use ffi_flush_icache. + + * Makefile.am (EXTRA_DIST): Add libtool-ldflags. + * Makefile.in: Rebuilt. + * libtool-ldflags: New file. + +2013-02-07 Daniel Schepler + + * configure.ac: Correctly identify x32 systems as 64-bit. + * m4/libtool.m4: Remove libtool expr error. + * aclocal.m4, configure: Rebuilt. + +2013-02-07 Anthony Green + + * configure.ac: Fix GCC usage test. + * configure: Rebuilt. + * README: Mention LLVM/GCC x86_64 issue. + * testsuite/Makefile.in: Rebuilt. + +2013-02-07 Anthony Green + + * testsuite/libffi.call/cls_double_va.c (main): Replace // style + comments with /* */ for xlc compiler. + * testsuite/libffi.call/stret_large.c (main): Ditto. + * testsuite/libffi.call/stret_large2.c (main): Ditto. + * testsuite/libffi.call/nested_struct1.c (main): Ditto. + * testsuite/libffi.call/huge_struct.c (main): Ditto. + * testsuite/libffi.call/float_va.c (main): Ditto. + * testsuite/libffi.call/cls_struct_va1.c (main): Ditto. + * testsuite/libffi.call/cls_pointer_stack.c (main): Ditto. + * testsuite/libffi.call/cls_pointer.c (main): Ditto. + * testsuite/libffi.call/cls_longdouble_va.c (main): Ditto. + +2013-02-06 Anthony Green + + * man/ffi_prep_cif.3: Clean up for debian lintian checker. + +2013-02-06 Anthony Green + + * Makefile.am (pkgconfigdir): Add missing pkgconfig install bits. + * Makefile.in: Rebuild. + +2013-02-02 Mark H Weaver + + * src/x86/ffi64.c (ffi_call): Sign-extend integer arguments passed + via general purpose registers. + +2013-01-21 Nathan Rossi + + * README: Add MicroBlaze details. + * Makefile.am: Add MicroBlaze support. + * configure.ac: Likewise. + * src/microblaze/ffi.c: New. + * src/microblaze/ffitarget.h: Likewise. + * src/microblaze/sysv.S: Likewise. + +2013-01-21 Nathan Rossi + * testsuite/libffi.call/return_uc.c: Fixed issue. + +2013-01-21 Chris Zankel + + * README: Add Xtensa support. + * Makefile.am: Likewise. + * configure.ac: Likewise. + * Makefile.in Regenerate. + * configure: Likewise. + * src/prep_cif.c: Handle Xtensa. + * src/xtensa: New directory. + * src/xtensa/ffi.c: New file. + * src/xtensa/ffitarget.h: Ditto. + * src/xtensa/sysv.S: Ditto. + +2013-01-11 Anthony Green + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Replace // style + comments with /* */ for xlc compiler. + * src/powerpc/aix.S (ffi_call_AIX): Ditto. + * testsuite/libffi.call/ffitest.h (allocate_mmap): Delete + deprecated inline function. + * testsuite/libffi.special/ffitestcxx.h: Ditto. + * README: Add update for AIX support. + +2013-01-11 Anthony Green + + * configure.ac: Robustify pc relative reloc check. + * m4/ax_cc_maxopt.m4: Don't -malign-double. This is an ABI + changing option for 32-bit x86. + * aclocal.m4, configure: Rebuilt. + * README: Update supported target list. + +2013-01-10 Anthony Green + + * README (tested): Add Compiler column to table. + +2013-01-10 Anthony Green + + * src/x86/ffi64.c (struct register_args): Make sse array and array + of unions for sunpro compiler compatibility. + +2013-01-10 Anthony Green + + * configure.ac: Test target platform size_t size. Handle both 32 + and 64-bit builds for x86_64-* and i?86-* targets (allowing for + CFLAG option to change default settings). + * configure, aclocal.m4: Rebuilt. + +2013-01-10 Anthony Green + + * testsuite/libffi.special/special.exp: Only run exception + handling tests when using GNU compiler. + + * m4/ax_compiler_vendor.m4: New file. + * configure.ac: Test for compiler vendor and don't use + AX_CFLAGS_WARN_ALL with the sun compiler. + * aclocal.m4, configure: Rebuilt. + +2013-01-10 Anthony Green + + * include/ffi_common.h: Don't use GCCisms to define types when + building with the SUNPRO compiler. + +2013-01-10 Anthony Green + + * configure.ac: Put local.exp in the right place. + * configure: Rebuilt. + + * src/x86/ffi.c: Update comment about regparm function attributes. + * src/x86/sysv.S (ffi_closure_SYSV): The SUNPRO compiler requires + that all function arguments be passed on the stack (no regparm + support). + +2013-01-08 Anthony Green + + * configure.ac: Generate local.exp. This sets CC_FOR_TARGET + when we are using the vendor compiler. + * testsuite/Makefile.am (EXTRA_DEJAGNU_SITE_CONFIG): Point to + ../local.exp. + * configure, testsuite/Makefile.in: Rebuilt. + + * testsuite/libffi.call/call.exp: Run tests with different + options, depending on whether or not we are using gcc or the + vendor compiler. + * testsuite/lib/libffi.exp (libffi-init): Set using_gcc based on + whether or not we are building/testing with gcc. + +2013-01-08 Anthony Green + + * configure.ac: Switch x86 solaris target to X86 by default. + * configure: Rebuilt. + +2013-01-08 Anthony Green + + * configure.ac: Fix test for read-only eh_frame. + * configure: Rebuilt. + +2013-01-08 Anthony Green + + * src/x86/sysv.S, src/x86/unix64.S: Only emit DWARF unwind info + when building with the GNU toolchain. + * testsuite/libffi.call/ffitest.h (CHECK): Fix for Solaris vendor + compiler. + +2013-01-07 Thorsten Glaser + + * testsuite/libffi.call/cls_uchar_va.c, + testsuite/libffi.call/cls_ushort_va.c, + testsuite/libffi.call/va_1.c: Testsuite fixes. + +2013-01-07 Thorsten Glaser + + * src/m68k/ffi.c (CIF_FLAGS_SINT8, CIF_FLAGS_SINT16): Define. + (ffi_prep_cif_machdep): Fix 8-bit and 16-bit signed calls. + * src/m68k/sysv.S (ffi_call_SYSV, ffi_closure_SYSV): Ditto. + +2013-01-04 Anthony Green + + * Makefile.am (AM_CFLAGS): Don't automatically add -fexceptions + and -Wall. This is set in the configure script after testing for + GCC. + * Makefile.in: Rebuilt. + +2013-01-02 rofl0r + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix build error on ppc + when long double == double. + +2013-01-02 Reini Urban + + * Makefile.am (libffi_la_LDFLAGS): Add -no-undefined to LDFLAGS + (required for shared libs on cygwin/mingw). + * Makefile.in: Rebuilt. + +2012-10-31 Alan Modra + + * src/powerpc/linux64_closure.S: Add new ABI support. + * src/powerpc/linux64.S: Likewise. + +2012-10-30 Magnus Granberg + Pavel Labushev + + * configure.ac: New options pax_emutramp + * configure, fficonfig.h.in: Regenerated + * src/closures.c: New function emutramp_enabled_check() and + checks. + +2012-10-30 Frederick Cheung + + * configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain + lion) and future version. + * configure: Rebuild. + +2012-10-30 James Greenhalgh + Marcus Shawcroft + + * README: Add details of aarch64 port. + * src/aarch64/ffi.c: New. + * src/aarch64/ffitarget.h: Likewise. + * src/aarch64/sysv.S: Likewise. + * Makefile.am: Support aarch64. + * configure.ac: Support aarch64. + * Makefile.in, configure: Rebuilt. + +2012-10-30 James Greenhalgh + Marcus Shawcroft + + * testsuite/lib/libffi.exp: Add support for aarch64. + * testsuite/libffi.call/cls_struct_va1.c: New. + * testsuite/libffi.call/cls_uchar_va.c: Likewise. + * testsuite/libffi.call/cls_uint_va.c: Likewise. + * testsuite/libffi.call/cls_ulong_va.c: Likewise. + * testsuite/libffi.call/cls_ushort_va.c: Likewise. + * testsuite/libffi.call/nested_struct11.c: Likewise. + * testsuite/libffi.call/uninitialized.c: Likewise. + * testsuite/libffi.call/va_1.c: Likewise. + * testsuite/libffi.call/va_struct1.c: Likewise. + * testsuite/libffi.call/va_struct2.c: Likewise. + * testsuite/libffi.call/va_struct3.c: Likewise. + +2012-10-12 Walter Lee + + * Makefile.am: Add TILE-Gx/TILEPro support. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * configure: Likewise. + * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro. + * src/tile: New directory. + * src/tile/ffi.c: New file. + * src/tile/ffitarget.h: Ditto. + * src/tile/tile.S: Ditto. + +2012-10-12 Matthias Klose + + * generate-osx-source-and-headers.py: Normalize whitespace. + +2012-09-14 David Edelsohn + + * configure: Regenerated. + +2012-08-26 Andrew Pinski + + PR libffi/53014 + * src/mips/ffi.c (ffi_prep_closure_loc): Allow n32 with soft-float and n64 with + soft-float. + +2012-08-08 Uros Bizjak + + * src/s390/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + +2012-07-18 H.J. Lu + + PR libffi/53982 + PR libffi/53973 + * src/x86/ffitarget.h: Check __ILP32__ instead of __LP64__ for x32. + (FFI_SIZEOF_JAVA_RAW): Defined to 4 for x32. + +2012-05-16 H.J. Lu + + * configure: Regenerated. + +2012-05-05 Nicolas Lelong + + * libffi.xcodeproj/project.pbxproj: Fixes. + * README: Update for iOS builds. + +2012-04-23 Alexandre Keunecke I. de Mendonca + + * configure.ac: Add Blackfin/sysv support + * Makefile.am: Add Blackfin/sysv support + * src/bfin/ffi.c: Add Blackfin/sysv support + * src/bfin/ffitarget.h: Add Blackfin/sysv support + +2012-04-11 Anthony Green + + * Makefile.am (EXTRA_DIST): Add new script. + * Makefile.in: Rebuilt. + +2012-04-11 Zachary Waldowski + + * generate-ios-source-and-headers.py, + libffi.xcodeproj/project.pbxproj: Support a Mac static library via + Xcode. Set iOS compatibility to 4.0. Move iOS trampoline + generation into an Xcode "run script" phase. Include both as + Xcode build scripts. Don't always regenerate config files. + +2012-04-10 Anthony Green + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon. + +2012-04-06 Anthony Green + + * Makefile.am (EXTRA_DIST): Add new iOS/xcode files. + * Makefile.in: Rebuilt. + +2012-04-06 Mike Lewis + + * generate-ios-source-and-headers.py: New file. + * libffi.xcodeproj/project.pbxproj: New file. + * README: Update instructions on building iOS binary. + * build-ios.sh: Delete. + +2012-04-06 Anthony Green + + * src/x86/ffi64.c (UINT128): Define differently for Intel and GNU + compilers, then use it. + +2012-04-06 H.J. Lu + + * m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32. + +2012-04-06 Anthony Green + + * testsuite/Makefile.am (EXTRA_DIST): Add missing test cases. + * testsuite/Makefile.in: Rebuilt. + +2012-04-05 Zachary Waldowski + + * include/ffi.h.in: Add missing trampoline table fields. + * src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references + in CNAME. + * src/x86/ffi.c: Wrap Windows specific code in ifdefs. + +2012-04-02 Peter Bergner + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp. + Silence casting pointer to integer of different size warning. + Delete goto to previously deleted label. + (ffi_call): Silence possibly undefined warning. + (ffi_closure_helper_SYSV): Declare variable type. + +2012-04-02 Peter Rosin + + * src/x86/win32.S (ffi_call_win32): Sign/zero extend the return + value in the Intel version as is already done for the AT&T version. + (ffi_closure_SYSV): Likewise. + (ffi_closure_raw_SYSV): Likewise. + (ffi_closure_STDCALL): Likewise. + +2012-03-29 Peter Rosin + + * src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame + generation, fix the ENDP label and remove the surplus third arg + from the 'lea' insn. + +2012-03-29 Peter Rosin + + * src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label + visible outside the PROC, so that ffi_closure_raw_THISCALL can see + it. Also instruct the assembler to add a frame to the function. + +2012-03-23 Peter Rosin + + * Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING. + * Makefile.in: Rebuilt. + * include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations + to all data exports, when compiling libffi clients using MSVC. + +2012-03-29 Peter Rosin + + * src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and + make it the default for MSVC. + (FFI_TYPE_MS_STRUCT): New structure return convention. + * src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure + return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT + instead of an ordinary FFI_TYPE_STRUCT. + (ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. + (ffi_call): Likewise. + (ffi_prep_incoming_args_SYSV): Likewise. + (ffi_raw_call): Likewise. + (ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV. + * src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT, + return a pointer to the result structure in eax and don't pop + that pointer from the stack, the caller takes care of it. + (ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. + (ffi_closure_raw_SYSV): Likewise. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline + assembly version with Intel syntax. + * testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise. + +2012-03-23 Peter Rosin + + * testsuite/libffi.call/ffitest.h: Provide abstration of + __attribute__((fastcall)) in the form of a __FASTCALL__ + define. Define it to __fastcall for MSVC. + * testsuite/libffi.call/fastthis1_win32.c: Use the above. + * testsuite/libffi.call/fastthis2_win32.c: Likewise. + * testsuite/libffi.call/fastthis3_win32.c: Likewise. + * testsuite/libffi.call/strlen2_win32.c: Likewise. + * testsuite/libffi.call/struct1_win32.c: Likewise. + * testsuite/libffi.call/struct2_win32.c: Likewise. + +2012-03-22 Peter Rosin + + * src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual + frame on function entry, MASM adds one automatically. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing + bits in the MSVC headers. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style + with no declarations after statements. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5_1_byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6_1_byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7_1_byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble_split.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_dbls_struct.c: Likewise. + * testsuite/libffi.call/cls_pointer_stack.c: Likewise. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + * testsuite/libffi.call/huge_struct.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct10.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/nested_struct4.c: Likewise. + * testsuite/libffi.call/nested_struct5.c: Likewise. + * testsuite/libffi.call/nested_struct6.c: Likewise. + * testsuite/libffi.call/nested_struct7.c: Likewise. + * testsuite/libffi.call/nested_struct8.c: Likewise. + * testsuite/libffi.call/nested_struct9.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_medium2.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + * testsuite/libffi.call/struct1_win32.c: Likewise. + * testsuite/libffi.call/struct2.c: Likewise. + * testsuite/libffi.call/struct2_win32.c: Likewise. + * testsuite/libffi.call/struct3.c: Likewise. + * testsuite/libffi.call/struct4.c: Likewise. + * testsuite/libffi.call/struct5.c: Likewise. + * testsuite/libffi.call/struct6.c: Likewise. + * testsuite/libffi.call/struct7.c: Likewise. + * testsuite/libffi.call/struct8.c: Likewise. + * testsuite/libffi.call/struct9.c: Likewise. + * testsuite/libffi.call/testclosure.c: Likewise. + +2012-03-21 Peter Rosin + + * testsuite/libffi.call/float_va.c (float_va_fn): Use %f when + printing doubles (%lf is for long doubles). + (main): Likewise. + +2012-03-21 Peter Rosin + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + (set_ld_library_path_env_vars): Add the library search dir to PATH + (and save PATH for later). + (restore_ld_library_path_env_vars): Restore PATH. + +2012-03-21 Peter Rosin + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + (set_ld_library_path_env_vars): Add the library search dir to PATH + (and save PATH for later). + (restore_ld_library_path_env_vars): Restore PATH. + +2012-03-20 Peter Rosin + + * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. + * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label + visible outside the PROC, so that ffi_closure_THISCALL can see it. + +2012-03-20 Peter Rosin + + * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. + * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label + visible outside the PROC, so that ffi_closure_THISCALL can see it. + +2012-03-19 Alan Hourihane + + * src/m68k/ffi.c: Add MINT support. + * src/m68k/sysv.S: Ditto. + +2012-03-06 Chung-Lin Tang + + * src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to + ffi_call_VFP(). + (ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of + ffi_closure_VFP. + * src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code. + +2012-03-19 chennam + + * src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure + support. + +2012-03-13 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + * src/sh64/ffi.c (ffi_prep_closure_loc): Ditto. + +2012-03-09 David Edelsohn + + * src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64 + change to return value of ffi_closure_helper_DARWIN and load type + from return type. + +2012-03-03 H.J. Lu + + * src/x86/ffi64.c (ffi_call): Cast the return value to unsigned + long. + (ffi_prep_closure_loc): Cast to 64bit address in trampoline. + (ffi_closure_unix64_inner): Cast return pointer to unsigned long + first. + + * src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32. + (ffi_arg): Set to unsigned long long for x32. + (ffi_sarg): Set to long long for x32. + +2012-03-03 H.J. Lu + + * src/prep_cif.c (ffi_prep_cif_core): Properly check bad ABI. + +2012-03-03 Andoni Morales Alastruey + + * configure.ac: Add -no-undefined for both 32- and 64-bit x86 + windows-like hosts. + * configure: Rebuilt. + +2012-02-27 Mikael Pettersson + + PR libffi/52223 + * Makefile.am (FLAGS_TO_PASS): Define. + * Makefile.in: Regenerate. + +2012-02-23 Anthony Green + + * src/*/ffitarget.h: Ensure that users never include ffitarget.h + directly. + +2012-02-23 Kai Tietz + + PR libffi/52221 + * src/x86/ffi.c (ffi_closure_raw_THISCALL): New + prototype. + (ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for + thiscall-convention. + (ffi_raw_call): Use ffi_prep_args_raw. + * src/x86/win32.S (ffi_closure_raw_THISCALL): Add + implementation for stub. + +2012-02-10 Kai Tietz + + * configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64 + windows target. + * configure: Regenerated. + +2012-02-08 Kai Tietz + + * src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32 + also FFI_THISCALL. + * src/x86/ffi.c (ffi_closure_THISCALL): Add prototype. + (FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code. + (ffi_prep_closure_loc): Add FFI_THISCALL support. + * src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size. + * src/x86/win32.S (ffi_closure_THISCALL): New closure code + for thiscall-calling convention. + * testsuite/libffi.call/closure_thiscall.c: New test. + +2012-01-28 Kai Tietz + + * src/libffi/src/x86/ffi.c (ffi_call_win32): Add new + argument to prototype for specify calling-convention. + (ffi_call): Add support for stdcall/thiscall convention. + (ffi_prep_args): Likewise. + (ffi_raw_call): Likewise. + * src/x86/ffitarget.h (ffi_abi): Add FFI_THISCALL and + FFI_FASTCALL. + * src/x86/win32.S (_ffi_call_win32): Add support for + fastcall/thiscall calling-convention calls. + * testsuite/libffi.call/fastthis1_win32.c: New test. + * testsuite/libffi.call/fastthis2_win32.c: New test. + * testsuite/libffi.call/fastthis3_win32.c: New test. + * testsuite/libffi.call/strlen2_win32.c: New test. + * testsuite/libffi.call/many2_win32.c: New test. + * testsuite/libffi.call/struct1_win32.c: New test. + * testsuite/libffi.call/struct2_win32.c: New test. + +2012-01-23 Uros Bizjak + + * src/alpha/ffi.c (ffi_prep_closure_loc): Check for bad ABI. + +2012-01-23 Anthony Green + Chris Young + + * configure.ac: Add Amiga support. + * configure: Rebuilt. + +2012-01-23 Dmitry Nadezhin + + * include/ffi_common.h (LIKELY, UNLIKELY): Fix definitions. + +2012-01-23 Andreas Schwab + + * src/m68k/sysv.S (ffi_call_SYSV): Properly test for plain + mc68000. Test for __HAVE_68881__ in addition to __MC68881__. + +2012-01-19 Jakub Jelinek + + PR rtl-optimization/48496 + * src/ia64/ffi.c (ffi_call): Fix up aliasing violations. + +2012-01-09 Rainer Orth + + * configure.ac (i?86-*-*): Set TARGET to X86_64. + * configure: Regenerate. + +2011-12-07 Andrew Pinski + + PR libffi/50051 + * src/mips/n32.S: Add ".set mips4". + +2011-11-21 Andreas Tobler + + * configure: Regenerate. + +2011-11-12 David Gilbert + + * doc/libffi.texi, include/ffi.h.in, include/ffi_common.h, + man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3, + man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h, + src/cris/ffi.c, src/prep_cif.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/float_va.c: Many changes to support variadic + function calls. + +2011-11-12 Kyle Moffett + + * src/powerpc/ffi.c, src/powerpc/ffitarget.h, + src/powerpc/ppc_closure.S, src/powerpc/sysv.S: Many changes for + softfloat powerpc variants. + +2011-11-12 Petr Salinger + + * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Fix kfreebsd support. + * configure: Rebuilt. + +2011-11-12 Timothy Wall + + * src/arm/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): Max + alignment of 4 for wince on ARM. + +2011-11-12 Kyle Moffett + Anthony Green + + * src/ppc/sysv.S, src/ppc/ffi.c: Remove use of ppc string + instructions (not available on some cores, like the PPC440). + +2011-11-12 Kimura Wataru + + * m4/ax_enable_builddir: Change from string comparison to numeric + comparison for wc output. + * configure.ac: Enable FFI_MMAP_EXEC_WRIT for darwin11 aka Mac OS + X 10.7. + * configure: Rebuilt. + +2011-11-12 Anthony Green + + * Makefile.am (AM_CCASFLAGS): Add -g option to build assembly + files with debug info. + * Makefile.in: Rebuilt. + +2011-11-12 Jasper Lievisse Adriaanse + + * README: Update list of supported OpenBSD systems. + +2011-11-12 Anthony Green + + * libtool-version: Update. + * Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if + FFI_DEBUG. + (libffi_la_SOURCES): Remove src/debug.c + (EXTRA_DIST): Add src/debug.c + * Makefile.in: Rebuilt. + * README: Update for 3.0.11. + +2011-11-10 Richard Henderson + + * configure.ac (GCC_AS_CFI_PSEUDO_OP): Use it instead of inline check. + * configure, aclocal.m4: Rebuild. + +2011-09-04 Iain Sandoe + + PR libffi/49594 + * src/powerpc/darwin_closure.S (stubs): Make the stub binding + helper reference track the architecture pointer size. + +2011-08-25 Andrew Haley + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Remove hard-coded assembly + instructions. + * src/arm/sysv.S (ffi_arm_trampoline): Put them here instead. + +2011-07-11 Andrew Haley + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache. + +2011-06-29 Rainer Orth + + * testsuite/libffi.call/cls_double_va.c: Move PR number to comment. + * testsuite/libffi.call/cls_longdouble_va.c: Likewise. + +2011-06-29 Rainer Orth + + PR libffi/46660 + * testsuite/libffi.call/cls_double_va.c: xfail dg-output on + mips-sgi-irix6*. + * testsuite/libffi.call/cls_longdouble_va.c: Likewise. + +2011-06-14 Rainer Orth + + * testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8, + PRId8 instead of %hhu, %hhd. + * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8, + PRIu8): Define. + [__sgi__] (PRId8, PRIu8): Define. + +2011-04-29 Rainer Orth + + * src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE): + Define. + Use them to handle ELF vs. ECOFF differences. + [__osf__] (_GLOBAL__F_ffi_call_osf): Define. + +2011-03-30 Timothy Wall + + * src/powerpc/darwin.S: Fix unknown FDE encoding. + * src/powerpc/darwin_closure.S: ditto. + +2011-02-25 Anthony Green + + * src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more + 32-bit ABIs. + +2011-02-15 Anthony Green + + * m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math. + * configure: Rebuilt. + +2011-02-13 Ralf Wildenhues + + * configure: Regenerate. + +2011-02-13 Anthony Green + + * include/ffi_common.h (UNLIKELY, LIKELY): Define. + * src/x86/ffi64.c (UNLIKELY, LIKELY): Remove definition. + * src/prep_cif.c (UNLIKELY, LIKELY): Remove definition. + + * src/prep_cif.c (initialize_aggregate): Convert assertion into + FFI_BAD_TYPEDEF return. Initialize arg size and alignment to 0. + + * src/pa/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + * src/arm/ffi.c (ffi_prep_closure_loc): Ditto. + * src/powerpc/ffi.c (ffi_prep_closure_loc): Ditto. + * src/mips/ffi.c (ffi_prep_closure_loc): Ditto. + * src/ia64/ffi.c (ffi_prep_closure_loc): Ditto. + * src/avr32/ffi.c (ffi_prep_closure_loc): Ditto. + +2011-02-11 Anthony Green + + * src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + +2012-02-11 Eric Botcazou + + * src/sparc/v9.S (STACKFRAME): Bump to 176. + +2011-02-09 Stuart Shelton + + http://bugs.gentoo.org/show_bug.cgi?id=286911 + * src/mips/ffitarget.h: Clean up error messages. + * src/java_raw_api.c (ffi_java_translate_args): Cast raw arg to + ffi_raw*. + * include/ffi.h.in: Add pragma for SGI compiler. + +2011-02-09 Anthony Green + + * configure.ac: Add powerpc64-*-darwin* support. + +2011-02-09 Anthony Green + + * README: Mention Interix. + +2011-02-09 Jonathan Callen + + * configure.ac: Add Interix to win32/cygwin/mingw case. + * configure: Ditto. + * src/closures.c: Treat Interix like Cygwin, instead of as a + generic win32. + +2011-02-09 Anthony Green + + * testsuite/libffi.call/err_bad_typedef.c: Remove xfail. + * testsuite/libffi.call/err_bad_abi.c: Remove xfail. + * src/x86/ffi64.c (UNLIKELY, LIKELY): Define. + (ffi_prep_closure_loc): Check for bad ABI. + * src/prep_cif.c (UNLIKELY, LIKELY): Define. + (initialize_aggregate): Check for bad types. + +2011-02-09 Landon Fuller + + * Makefile.am (EXTRA_DIST): Add build-ios.sh, src/arm/gentramp.sh, + src/arm/trampoline.S. + (nodist_libffi_la_SOURCES): Add src/arc/trampoline.S. + * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Define. + * src/arm/ffi.c (ffi_trampoline_table) + (ffi_closure_trampoline_table_page, ffi_trampoline_table_entry) + (FFI_TRAMPOLINE_CODELOC_CONFIG, FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) + (FFI_TRAMPOLINE_COUNT, ffi_trampoline_lock, ffi_trampoline_tables) + (ffi_trampoline_table_alloc, ffi_closure_alloc, ffi_closure_free): + Define for FFI_EXEC_TRAMPOLINE_TABLE case (iOS). + (ffi_prep_closure_loc): Handl FFI_EXEC_TRAMPOLINE_TABLE case + separately. + * src/arm/sysv.S: Handle Apple iOS host. + * src/closures.c: Handle FFI_EXEC_TRAMPOLINE_TABLE case. + * build-ios.sh: New file. + * fficonfig.h.in, configure, Makefile.in: Rebuilt. + * README: Mention ARM iOS. + +2011-02-08 Oren Held + + * src/dlmalloc.c (_STRUCT_MALLINFO): Define in order to avoid + redefinition of mallinfo on HP-UX. + +2011-02-08 Ginn Chen + + * src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio + aggregate return ABI. Flush cache. + (ffi_prep_closure_loc): Flush cache. + +2011-02-11 Anthony Green + + From Tom Honermann : + * src/powerpc/aix.S (ffi_call_AIX): Support for xlc toolchain on + AIX. Declare .ffi_prep_args. Insert nops after branch + instructions so that the AIX linker can insert TOC reload + instructions. + * src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN. + +2011-02-08 Ed + + * src/powerpc/asm.h: Fix grammar nit in comment. + +2011-02-08 Uli Link + + * include/ffi.h.in (FFI_64_BIT_MAX): Define and use. + +2011-02-09 Rainer Orth + + PR libffi/46661 + * testsuite/libffi.call/cls_pointer.c (main): Cast void * to + uintptr_t first. + * testsuite/libffi.call/cls_pointer_stack.c (main): Likewise. + +2011-02-08 Rafael Avila de Espindola + + * configure.ac: Fix x86 test for pc related relocs. + * configure: Rebuilt. + +2011-02-07 Joel Sherrill + + * libffi/src/m68k/ffi.c: Add RTEMS support for cache flushing. + Handle case when CPU variant does not have long double support. + * libffi/src/m68k/sysv.S: Add support for mc68000, Coldfire, + and cores with soft floating point. + +2011-02-07 Joel Sherrill + + * configure.ac: Add mips*-*-rtems* support. + * configure: Regenerate. + * src/mips/ffitarget.h: Ensure needed constants are available + for targets which do not have sgidefs.h. + +2011-01-26 Dave Korn + + PR target/40125 + * configure.ac (AM_LTLDFLAGS): Add -bindir option for windows DLLs. + * configure: Regenerate. + +2010-12-18 Iain Sandoe + + PR libffi/29152 + PR libffi/42378 + * src/powerpc/darwin_closure.S: Provide Darwin64 implementation, + update comments. + * src/powerpc/ffitarget.h (POWERPC_DARWIN64): New, + (FFI_TRAMPOLINE_SIZE): Update for Darwin64. + * src/powerpc/darwin.S: Provide Darwin64 implementation, + update comments. + * src/powerpc/ffi_darwin.c: Likewise. + +2010-12-06 Rainer Orth + + * configure.ac (libffi_cv_as_ascii_pseudo_op): Use double + backslashes. + (libffi_cv_as_string_pseudo_op): Likewise. + * configure: Regenerate. + +2010-12-03 Chung-Lin Tang + + * src/arm/sysv.S (ffi_closure_SYSV): Add UNWIND to .pad directive. + (ffi_closure_VFP): Same. + (ffi_call_VFP): Move down to before ffi_closure_VFP. Add '.fpu vfp' + directive. + +2010-12-01 Rainer Orth + + * testsuite/libffi.call/ffitest.h [__sgi] (PRId64, PRIu64): Define. + (PRIuPTR): Define. + +2010-11-29 Richard Henderson + Rainer Orth + + * src/x86/sysv.S (FDE_ENCODING, FDE_ENCODE): Define. + (.eh_frame): Use FDE_ENCODING. + (.LASFDE1, .LASFDE2, LASFDE3): Simplify with FDE_ENCODE. + +2010-11-22 Jacek Caban + + * configure.ac: Check for symbol underscores on mingw-w64. + * configure: Rebuilt. + * src/x86/win64.S: Correctly access extern symbols in respect to + underscores. + +2010-11-15 Rainer Orth + + * testsuite/lib/libffi-dg.exp: Rename ... + * testsuite/lib/libffi.exp: ... to this. + * libffi/testsuite/libffi.call/call.exp: Don't load libffi-dg.exp. + * libffi/testsuite/libffi.special/special.exp: Likewise. + +2010-10-28 Chung-Lin Tang + + * src/arm/ffi.c (ffi_prep_args): Add VFP register argument handling + code, new parameter, and return value. Update comments. + (ffi_prep_cif_machdep): Add case for VFP struct return values. Add + call to layout_vfp_args(). + (ffi_call_SYSV): Update declaration. + (ffi_call_VFP): New declaration. + (ffi_call): Add VFP struct return conditions. Call ffi_call_VFP() + when ABI is FFI_VFP. + (ffi_closure_VFP): New declaration. + (ffi_closure_SYSV_inner): Add new vfp_args parameter, update call to + ffi_prep_incoming_args_SYSV(). + (ffi_prep_incoming_args_SYSV): Update parameters. Add VFP argument + case handling. + (ffi_prep_closure_loc): Pass ffi_closure_VFP to trampoline + construction under VFP hard-float. + (rec_vfp_type_p): New function. + (vfp_type_p): Same. + (place_vfp_arg): Same. + (layout_vfp_args): Same. + * src/arm/ffitarget.h (ffi_abi): Add FFI_VFP. Define FFI_DEFAULT_ABI + based on __ARM_PCS_VFP. + (FFI_EXTRA_CIF_FIELDS): Define for adding VFP hard-float specific + fields. + (FFI_TYPE_STRUCT_VFP_FLOAT): Define internally used type code. + (FFI_TYPE_STRUCT_VFP_DOUBLE): Same. + * src/arm/sysv.S (ffi_call_SYSV): Change call of ffi_prep_args() to + direct call. Move function pointer load upwards. + (ffi_call_VFP): New function. + (ffi_closure_VFP): Same. + + * testsuite/lib/libffi-dg.exp (check-flags): New function. + (dg-skip-if): New function. + * testsuite/libffi.call/cls_double_va.c: Skip if target is arm*-*-* + and compiler options include -mfloat-abi=hard. + * testsuite/libffi.call/cls_longdouble_va.c: Same. + +2010-10-01 Jakub Jelinek + + PR libffi/45677 + * src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is + a multiple of 8. + * testsuite/libffi.call/many2.c: New test. + +2010-08-20 Mark Wielaard + + * src/closures.c (open_temp_exec_file_mnt): Check if getmntent_r + returns NULL. + +2010-08-09 Andreas Tobler + + * configure.ac: Add target powerpc64-*-freebsd*. + * configure: Regenerate. + * testsuite/libffi.call/cls_align_longdouble_split.c: Pass + -mlong-double-128 only to linux targets. + * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. + * testsuite/libffi.call/cls_longdouble.c: Likewise. + * testsuite/libffi.call/huge_struct.c: Likewise. + +2010-08-05 Dan Witte + + * Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the + debug CRT when --enable-debug is given. + * configure.ac: Define it. + * msvcc.sh: Translate -g and -DFFI_DEBUG appropriately. + +2010-08-04 Dan Witte + + * src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64 + platforms. + * src/x86/ffi.c: Remove redundant ifdef checks. + * src/prep_cif.c: Push stack space computation into src/x86/ffi.c + for X86_ANY so return value space doesn't get added twice. + +2010-08-03 Neil Rashbrooke + + * msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy. + +2010-07-22 Dan Witte + + * src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI. + * src/prep_cif.c: Fix ABI assertion. + * src/cris/ffi.c: Ditto. + +2010-07-10 Evan Phoenix + + * src/closures.c (selinux_enabled_check): Fix strncmp usage bug. + +2010-07-07 Dan Horák + + * include/ffi.h.in: Protect #define with #ifndef. + * src/powerpc/ffitarget.h: Ditto. + * src/s390/ffitarget.h: Ditto. + * src/sparc/ffitarget.h: Ditto. + +2010-07-07 Neil Roberts + + * src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to + 16-bytes. + +2010-07-02 Jakub Jelinek + + * Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes. + * Makefile.in: Regenerated. + +2010-05-19 Rainer Orth + + * configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as + output, too. + (libffi_cv_as_ascii_pseudo_op): Check for .ascii. + (libffi_cv_as_string_pseudo_op): Check for .string. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/x86/sysv.S (.eh_frame): Use .ascii, .string or error. + +2010-05-11 Dan Witte + + * doc/libffi.tex: Document previous change. + +2010-05-11 Makoto Kato + + * src/x86/ffi.c (ffi_call): Don't copy structs passed by value. + +2010-05-05 Michael Kohler + + * src/dlmalloc.c (dlfree): Fix spelling. + * src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto. + * configure.ac: Ditto. + * configure: Rebuilt. + +2010-04-13 Dan Witte + + * msvcc.sh: Build with -W3 instead of -Wall. + * src/powerpc/ffi_darwin.c: Remove build warnings. + * src/x86/ffi.c: Ditto. + * src/x86/ffitarget.h: Ditto. + +2010-04-12 Dan Witte + Walter Meinl + + * configure.ac: Add OS/2 support. + * configure: Rebuilt. + * src/closures.c: Ditto. + * src/dlmalloc.c: Ditto. + * src/x86/win32.S: Ditto. + +2010-04-07 Jakub Jelinek + + * testsuite/libffi.call/err_bad_abi.c: Remove unused args variable. + +2010-04-02 Ralf Wildenhues + + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2010-03-30 Dan Witte + + * msvcc.sh: Disable build warnings. + * README (tested): Clarify windows build procedure. + +2010-03-15 Rainer Orth + + * configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * libffi/src/x86/unix64.S (.eh_frame) + [HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type. + +2010-03-14 Matthias Klose + + * src/x86/ffi64.c: Fix typo in comment. + * src/x86/ffi.c: Use /* ... */ comment style. + +2010-02-24 Rainer Orth + + * doc/libffi.texi (The Closure API): Fix typo. + * doc/libffi.info: Remove. + +2010-02-15 Matthias Klose + + * src/arm/sysv.S (__ARM_ARCH__): Define for processor + __ARM_ARCH_7EM__. + +2010-01-15 Anthony Green + + * README: Add notes on building with Microsoft Visual C++. + +2010-01-15 Daniel Witte + + * msvcc.sh: New file. + + * src/x86/win32.S: Port assembly routines to MSVC and #ifdef. + * src/x86/ffi.c: Tweak function declaration and remove excess + parens. + * include/ffi.h.in: Add __declspec(align(8)) to typedef struct + ffi_closure. + + * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new + function ffi_call_win32 on X86_WIN32. + * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32. + (ffi_call_STDCALL): Remove. + + * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code + to ffi_prep_cif_machdep for x86. + * src/x86/ffi.c (ffi_prep_cif_machdep): To here. + +2010-01-15 Oliver Kiddle + + * src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for + Sun Studio compiler compatibility. + +2010-01-12 Conrad Irwin + + * doc/libffi.texi: Add closure example. + +2010-01-07 Rainer Orth + + PR libffi/40701 + * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL, + PRIuLL, PRId64, PRIu64, PRIuPTR): Define. + * testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on + alpha*-dec-osf*. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/return_ll1.c: Likewise. + * testsuite/libffi.call/stret_medium2.c: Likewise. + * testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast + MAP_FAILED to char *. + +2010-01-06 Rainer Orth + + * src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__. + +2009-12-31 Anthony Green + + * README: Update for libffi 3.0.9. + +2009-12-27 Matthias Klose + + * configure.ac (HAVE_LONG_DOUBLE): Define for mips when + appropriate. + * configure: Rebuilt. + +2009-12-26 Anthony Green + + * testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for + avr32*-*-*. + * testsuite/libffi.call/cls_double_va.c: Ditto. + +2009-12-26 Andreas Tobler + + * testsuite/libffi.call/ffitest.h: Conditionally include stdint.h + and inttypes.h. + * testsuite/libffi.special/unwindtest.cc: Ditto. + +2009-12-26 Andreas Tobler + + * configure.ac: Add amd64-*-openbsd*. + * configure: Rebuilt. + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Link + openbsd programs with -lpthread. + +2009-12-26 Anthony Green + + * testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for + mips*-*-* and arm*-*-*. + * testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*. + +2009-12-31 Kay Tietz + + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix + definitions. + +2009-12-31 Carlo Bramini + + * configure.ac (AM_LTLDFLAGS): Define for windows hosts. + * Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS. + * configure: Rebuilt. + * Makefile.in: Rebuilt. + +2009-12-31 Anthony Green + Blake Chaffin. + + * testsuite/libffi.call/huge_struct.c: New test case from Blake + Chaffin @ Apple. + +2009-12-28 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to + local variables. + (aix_adjust_aggregate_sizes): New function. + (ffi_prep_cif_machdep): Call it. + +2009-12-26 Andreas Tobler + + * configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets. + * configure: Regenerate. + * fficonfig.h.in: Likewise. + * src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for + Solaris/x86. + +2009-12-26 Andreas Schwab + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count + when a float arguments is passed in memory. + (ffi_closure_helper_SYSV): Mark general registers as used up when + a 64bit or soft-float long double argument is passed in memory. + +2009-12-25 Matthias Klose + + * man/ffi_call.3: Fix #include in examples. + * doc/libffi.texi: Add dircategory. + +2009-12-25 Frank Everdij + + * include/ffi.h.in: Placed '__GNUC__' ifdef around + '__attribute__((aligned(8)))' in ffi_closure, fixes compile for + IRIX MIPSPro c99. + * include/ffi_common.h: Added '__sgi' define to non + '__attribute__((__mode__()))' integer typedefs. + * src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32, + ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check. + (ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added + FFI_LONGDOUBLE support and alignment(N32 only). + * src/mips/ffitarget.h: Corrected '#include ' for IRIX and + fixed non '__attribute__((__mode__()))' integer typedefs. + * src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame' + since they are Linux/GNU Assembler specific. + +2009-12-25 Bradley Smith + + * configure.ac, Makefile.am, src/avr32/ffi.c, + src/avr32/ffitarget.h, + src/avr32/sysv.S: Add AVR32 port. + * configure, Makefile.in: Rebuilt. + +2009-12-21 Andreas Tobler + + * configure.ac: Make i?86 build on FreeBSD and OpenBSD. + * configure: Regenerate. + +2009-12-15 John David Anglin + + * testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX. + +2009-12-13 John David Anglin + + * src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE + type on HP-UX. + +2012-02-13 Kai Tietz + + PR libffi/52221 + * src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall + support for X86_WIN32. + (FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement. + +2009-12-11 Eric Botcazou + + * src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long + double' arguments. + +2009-12-11 Eric Botcazou + + * testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10. + +2009-12-10 Rainer Orth + + PR libffi/40700 + * src/closures.c [X86_64 && __sun__ && __svr4__] + (FFI_MMAP_EXEC_WRIT): Define. + +2009-12-08 David Daney + + * testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-* + * testsuite/libffi.call/cls_align_longdouble_split2.c: Same. + * testsuite/libffi.call/stret_large.c: Same. + * testsuite/libffi.call/cls_align_longdouble_split.c: Same. + * testsuite/libffi.call/stret_large2.c: Same. + * testsuite/libffi.call/stret_medium2.c: Same. + +2009-12-07 David Edelsohn + + * src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump + typo. + +2009-12-05 David Edelsohn + + * src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64 + code. + * src/powerpc/aix_closure.S: Same. + +2009-12-05 Ralf Wildenhues + + * Makefile.in: Regenerate. + * configure: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2009-12-04 David Edelsohn + + * src/powerpc/aix_closure.S: Reorganize 64-bit code to match + linux64_closure.S. + +2009-12-04 Uros Bizjak + + PR libffi/41908 + * src/x86/ffi64.c (classify_argument): Update from + gcc/config/i386/i386.c. + (ffi_closure_unix64_inner): Do not use the address of two consecutive + SSE registers directly. + * testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail + for x86_64 linux targets. + +2009-12-04 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment + pfr for long double split between fpr13 and stack. + +2009-12-03 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and + fparg_count twice for long double. + +2009-12-03 David Edelsohn + + PR libffi/42243 + * src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses. + +2009-12-03 Uros Bizjak + + * testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string. + Remove xfails for x86 linux targets. + +2009-12-02 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64 + case. + +2009-12-01 David Edelsohn + + * src/powerpc/aix.S (ffi_call_AIX): Convert to more standard + register usage. Call ffi_prep_args directly. Add long double + return value support. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment + applies to FFI_TYPE_DOUBLE. Correct fpr_base increment typo. + Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases. + (ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit + mode. + (ffi_closure_helper_DARWIN): Remove nf and ng counters. Move temp + into case. + * src/powerpc/aix_closure.S: Maintain 16 byte stack alignment. + Allocate result area between params and FPRs. + +2009-11-30 David Edelsohn + + PR target/35484 + * src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and + AIX64. + * src/powerpc/aix.S: Implement AIX64 version. + * src/powerpc/aix_closure.S: Implement AIX64 version. + (ffi_closure_ASM): Use extsb, lha and displament addresses. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64 + support. + (ffi_prep_cif_machdep): Same. + (ffi_call): Same. + (ffi_closure_helper_DARWIN): Same. + +2009-11-02 Andreas Tobler + + PR libffi/41908 + * testsuite/libffi.call/testclosure.c: New test. + +2009-09-28 Kai Tietz + + * src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu + assembly version use of ___chkstk. + +2009-09-23 Matthias Klose + + PR libffi/40242, PR libffi/41443 + * src/arm/sysv.S (__ARM_ARCH__): Define for processors + __ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__, + __ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__. + Change the conditionals to __SOFTFP__ || __ARM_EABI__ + for -mfloat-abi=softfp to work. + +2009-09-17 Loren J. Rittle + + PR testsuite/32843 (strikes again) + * src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to + enable proper extension on char and short. + +2009-09-15 David Daney + + * src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special + handling for FFI_TYPE_POINTER. + * src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT, + FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT, + FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT, + FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines. + (FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations. + (enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float. + * src/mips/n32.S (ffi_call_N32): Add handling for soft-float + structure and pointer returns. + (ffi_closure_N32): Add handling for pointer returns. + * src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags, + calc_n32_return_struct_flags): Handle soft-float. + (ffi_prep_cif_machdep): Handle soft-float, fix pointer handling. + (ffi_call_N32): Declare proper argument types. + (ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle + soft-float. + +2009-08-24 Ralf Wildenhues + + * configure.ac (AC_PREREQ): Bump to 2.64. + +2009-08-22 Ralf Wildenhues + + * Makefile.am (install-html, install-pdf): Remove. + * Makefile.in: Regenerate. + + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2011-08-22 Jasper Lievisse Adriaanse + + * configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support. + * configure: Rebuilt. + +2009-07-30 Ralf Wildenhues + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + +2009-07-24 Dave Korn + + PR libffi/40807 + * src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending + return types for X86_WIN32. + * src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types. + (_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV, + _ffi_closure_STDCALL): Likewise. + + * src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin. + (dlmmap, dlmunmap): Also use these functions on Cygwin. + +2009-07-11 Richard Sandiford + + PR testsuite/40699 + PR testsuite/40707 + PR testsuite/40709 + * testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and + 2009-06-30 commits. + +2009-07-01 Richard Sandiford + + * testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path + to "" before adding paths. (This reinstates an assignment that + was removed by my 2009-06-30 commit, but changes the initial + value from "." to "".) + +2009-07-01 H.J. Lu + + PR testsuite/40601 + * testsuite/lib/libffi-dg.exp (libffi-init): Properly set + gccdir. Adjust ld_library_path for gcc only if gccdir isn't + empty. + +2009-06-30 Richard Sandiford + + * testsuite/lib/libffi-dg.exp (libffi-init): Don't add "." + to ld_library_path. Use add_path. Add just find_libgcc_s + to ld_library_path, not every libgcc multilib directory. + +2009-06-16 Wim Lewis + + * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are + supposed to be callee-saved. + * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of + return buffer for odd-size structs. + +2009-06-16 Andreas Tobler + + PR libffi/40444 + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add + allow_stack_execute for Darwin. + +2009-06-16 Andrew Haley + + * configure.ac (TARGETDIR): Add missing blank lines. + * configure: Regenerate. + +2009-06-16 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. + +2009-06-15 Andrew Haley + + * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere. + * testsuite/libffi.call/err_bad_abi.c: Likewise. + +2009-06-12 Andrew Haley + + * Makefile.am: Remove info_TEXINFOS. + +2009-06-12 Andrew Haley + + * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + testsuite/libffi.special/unwindtest.cc: include stdint.h. + +2009-06-11 Timothy Wall + + * Makefile.am, + configure.ac, + include/ffi.h.in, + include/ffi_common.h, + src/closures.c, + src/dlmalloc.c, + src/x86/ffi.c, + src/x86/ffitarget.h, + src/x86/win64.S (new), + README: Added win64 support (mingw or MSVC) + * Makefile.in, + include/Makefile.in, + man/Makefile.in, + testsuite/Makefile.in, + configure, + aclocal.m4: Regenerated + * ltcf-c.sh: properly escape cygwin/w32 path + * man/ffi_call.3: Clarify size requirements for return value. + * src/x86/ffi64.c: Fix filename in comment. + * src/x86/win32.S: Remove unused extern. + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/err_bad_abi.c, + testsuite/libffi.call/err_bad_typedef.c, + testsuite/libffi.call/float2.c, + testsuite/libffi.call/huge_struct.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/return_ldl.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead + of checking for MMAP. Use intptr_t instead of long casts. + +2009-06-11 Kaz Kojima + + * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*. + * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + +2009-06-09 Andrew Haley + + * src/x86/freebsd.S: Add missing file. + +2009-06-08 Andrew Haley + + Import from libffi 3.0.8: + + * doc/libffi.texi: New file. + * doc/libffi.info: Likewise. + * doc/stamp-vti: Likewise. + * man/Makefile.am: New file. + * man/ffi_call.3: New file. + + * Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S, + src/dlmalloc.c. + (nodist_libffi_la_SOURCES): Add X86_FREEBSD. + + * configure.ac: Bump version to 3.0.8. + parisc*-*-linux*: Add. + i386-*-freebsd* | i386-*-openbsd*: Add. + powerpc-*-beos*: Add. + AM_CONDITIONAL X86_FREEBSD: Add. + AC_CONFIG_FILES: Add man/Makefile. + + * include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void). + +2009-06-08 Andrew Haley + + * README: Import from libffi 3.0.8. + +2009-06-08 Andrew Haley + + * testsuite/libffi.call/err_bad_abi.c: Add xfails. + * testsuite/libffi.call/cls_longdouble_va.c: Add xfails. + * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*. + * testsuite/libffi.call/err_bad_typedef.c: Add xfails. + + * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + +2008-12-26 Timothy Wall + + * testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected + failures on x86_64 cygwin/mingw. + +2008-12-22 Timothy Wall + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_loc_fn0.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: use portable cast from + pointer to integer (intptr_t). + * testsuite/libffi.call/cls_longdouble.c: disable for win64. + +2008-07-24 Anthony Green + + * testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/err_bad_abi.c: Clean up failures from + compiler warnings. + +2008-03-04 Anthony Green + Blake Chaffin + hos@tamanegi.org + + * testsuite/libffi.call/cls_align_longdouble_split2.c + testsuite/libffi.call/cls_align_longdouble_split.c + testsuite/libffi.call/cls_dbls_struct.c + testsuite/libffi.call/cls_double_va.c + testsuite/libffi.call/cls_longdouble.c + testsuite/libffi.call/cls_longdouble_va.c + testsuite/libffi.call/cls_pointer.c + testsuite/libffi.call/cls_pointer_stack.c + testsuite/libffi.call/err_bad_abi.c + testsuite/libffi.call/err_bad_typedef.c + testsuite/libffi.call/stret_large2.c + testsuite/libffi.call/stret_large.c + testsuite/libffi.call/stret_medium2.c + testsuite/libffi.call/stret_medium.c: New tests from Apple. + +2009-06-05 Andrew Haley + + * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from + libffi. + +2009-06-04 Andrew Haley + + * src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out + stdcall changes. + +2008-02-26 Anthony Green + Thomas Heller + + * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C + comment. + +2008-02-03 Timothy Wall + + * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return + offset based on code pointer, not data pointer. + +2008-01-31 Timothy Wall + + * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall + closures. + * src/x86/ffitarget.h: Increase size of trampoline for stdcall + closures. + * src/x86/win32.S: Add assembly for stdcall closure. + * src/x86/ffi.c: Initialize stdcall closure trampoline. + +2009-06-04 Andrew Haley + + * include/ffi.h.in: Change void (*)() to void (*)(void). + * src/x86/ffi.c: Likewise. + +2009-06-04 Andrew Haley + + * src/powerpc/ppc_closure.S: Insert licence header. + * src/powerpc/linux64_closure.S: Likewise. + * src/m68k/sysv.S: Likewise. + + * src/sh64/ffi.c: Change void (*)() to void (*)(void). + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/m32r/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/x86/ffi64.c: Likewise. + * src/alpha/ffi.c: Likewise. + * src/alpha/osf.S: Likewise. + * src/frv/ffi.c: Likewise. + * src/s390/ffi.c: Likewise. + * src/pa/ffi.c: Likewise. + * src/pa/hpux32.S: Likewise. + * src/ia64/unix.S: Likewise. + * src/ia64/ffi.c: Likewise. + * src/sparc/ffi.c: Likewise. + * src/mips/ffi.c: Likewise. + * src/sh/ffi.c: Likewise. + +2008-02-15 David Daney + + * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): + Define (conditionally), and use it to include cachectl.h. + (ffi_prep_closure_loc): Fix cache flushing. + * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. + +2009-06-04 Andrew Haley + + include/ffi.h.in, + src/arm/ffitarget.h, + src/arm/ffi.c, + src/arm/sysv.S, + src/powerpc/ffitarget.h, + src/closures.c, + src/sh64/ffitarget.h, + src/sh64/ffi.c, + src/sh64/sysv.S, + src/types.c, + src/x86/ffi64.c, + src/x86/ffitarget.h, + src/x86/win32.S, + src/x86/darwin.S, + src/x86/ffi.c, + src/x86/sysv.S, + src/x86/unix64.S, + src/alpha/ffitarget.h, + src/alpha/ffi.c, + src/alpha/osf.S, + src/m68k/ffitarget.h, + src/frv/ffitarget.h, + src/frv/ffi.c, + src/s390/ffitarget.h, + src/s390/sysv.S, + src/cris/ffitarget.h, + src/pa/linux.S, + src/pa/ffitarget.h, + src/pa/ffi.c, + src/raw_api.c, + src/ia64/ffitarget.h, + src/ia64/unix.S, + src/ia64/ffi.c, + src/ia64/ia64_flags.h, + src/java_raw_api.c, + src/debug.c, + src/sparc/v9.S, + src/sparc/ffitarget.h, + src/sparc/ffi.c, + src/sparc/v8.S, + src/mips/ffitarget.h, + src/mips/n32.S, + src/mips/o32.S, + src/mips/ffi.c, + src/prep_cif.c, + src/sh/ffitarget.h, + src/sh/ffi.c, + src/sh/sysv.S: Update license text. + +2009-05-22 Dave Korn + + * src/x86/win32.S (_ffi_closure_STDCALL): New function. + (.eh_frame): Add FDE for it. + +2009-05-22 Dave Korn + + * configure.ac: Also check if assembler supports pc-relative + relocs on X86_WIN32 targets. + * configure: Regenerate. + * src/x86/win32.S (ffi_prep_args): Declare extern, not global. + (_ffi_call_SYSV): Add missing function type symbol .def and + add EH markup labels. + (_ffi_call_STDCALL): Likewise. + (_ffi_closure_SYSV): Likewise. + (_ffi_closure_raw_SYSV): Likewise. + (.eh_frame): Add hand-crafted EH data. + +2009-04-09 Jakub Jelinek + + * testsuite/lib/libffi-dg.exp: Change copyright header to refer to + version 3 of the GNU General Public License and to point readers + at the COPYING3 file and the FSF's license web page. + * testsuite/libffi.call/call.exp: Likewise. + * testsuite/libffi.special/special.exp: Likewise. + +2009-03-01 Ralf Wildenhues + + * configure: Regenerate. + +2008-12-18 Rainer Orth + + PR libffi/26048 + * configure.ac (HAVE_AS_X86_PCREL): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate + RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET, + RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler. + (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. + * src/x86/unix64.S (.Lstore_table): Move to .text section. + (.Lload_table): Likewise. + (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. + +2008-12-18 Ralf Wildenhues + + * configure: Regenerate. + +2008-11-21 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for + signed/unsigned int8/16 return values. + * src/sparc/v8.S (ffi_call_v8): Likewise. + (ffi_closure_v8): Likewise. + +2008-09-26 Peter O'Gorman + Steve Ellcey + + * configure: Regenerate for new libtool. + * Makefile.in: Ditto. + * include/Makefile.in: Ditto. + * aclocal.m4: Ditto. + +2008-08-25 Andreas Tobler + + * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and + FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum. + Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT. + Adjust copyright notice. + * src/powerpc/ffi.c: Add two new flags to indicate if we have one + register or two register to use for FFI_SYSV structs. + (ffi_prep_cif_machdep): Pass the right register flag introduced above. + (ffi_closure_helper_SYSV): Fix the return type for + FFI_SYSV_TYPE_SMALL_STRUCT. Comment. + Adjust copyright notice. + +2008-07-16 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned + int. + +2008-06-17 Ralf Wildenhues + + * configure: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2008-06-07 Joseph Myers + + * configure.ac (parisc*-*-linux*, powerpc-*-sysv*, + powerpc-*-beos*): Remove. + * configure: Regenerate. + +2008-05-09 Julian Brown + + * Makefile.am (LTLDFLAGS): New. + (libffi_la_LDFLAGS): Use above. + * Makefile.in: Regenerate. + +2008-04-18 Paolo Bonzini + + PR bootstrap/35457 + * aclocal.m4: Regenerate. + * configure: Regenerate. + +2008-03-26 Kaz Kojima + + * src/sh/sysv.S: Add .note.GNU-stack on Linux. + * src/sh64/sysv.S: Likewise. + +2008-03-26 Daniel Jacobowitz + + * src/arm/sysv.S: Fix ARM comment marker. + +2008-03-26 Jakub Jelinek + + * src/alpha/osf.S: Add .note.GNU-stack on Linux. + * src/s390/sysv.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + * src/x86/unix64.S: Likewise. + * src/x86/sysv.S: Likewise. + * src/sparc/v8.S: Likewise. + * src/sparc/v9.S: Likewise. + * src/m68k/sysv.S: Likewise. + * src/arm/sysv.S: Likewise. + +2008-03-16 Ralf Wildenhues + + * aclocal.m4: Regenerate. + * configure: Likewise. + * Makefile.in: Likewise. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + +2008-02-12 Bjoern Koenig + Andreas Tobler + + * configure.ac: Add amd64-*-freebsd* target. + * configure: Regenerate. + +2008-01-30 H.J. Lu + + PR libffi/34612 + * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when + returning struct. + + * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer" + tests. + +2008-01-24 David Edelsohn + + * configure: Regenerate. + +2008-01-06 Andreas Tobler + + * src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko. + +2008-01-05 Andreas Tobler + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): Add code for + signed/unsigned int8/16 for X86_DARWIN. + Updated copyright info. + Handle one and two byte structs with special cif->flags. + * src/x86/ffitarget.h: Add special types for one and two byte structs. + Updated copyright info. + * src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like + sysv.S + Remove code to pop args from the stack after call. + Special-case signed/unsigned for int8/16, one and two byte structs. + (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, + FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, + FFI_TYPE_SINT32. + Updated copyright info. + +2007-12-08 David Daney + + * src/mips/n32.S (ffi_call_N32): Replace dadd with ADDU, dsub with + SUBU, add with ADDU and use smaller code sequences. + +2007-12-07 David Daney + + * src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return + type. + +2007-12-06 David Daney + + * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already + defined. + (ffi_java_raw): New typedef. + (ffi_java_raw_call, ffi_java_ptrarray_to_raw, + ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to + ffi_java_raw. + (ffi_java_raw_closure) : Same. + (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change + parameter types. + * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with + FFI_SIZEOF_JAVA_RAW. + (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. + Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use + sizeof(ffi_java_raw) for alignment calculations. + (ffi_java_ptrarray_to_raw): Same. + (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER + if FFI_SIZEOF_JAVA_RAW == 4. + (ffi_java_raw_to_rvalue): Same. + (ffi_java_raw_call): Change type of raw to ffi_java_raw. + (ffi_java_translate_args): Same. + (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change + parameter types. + * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. + +2007-12-06 David Daney + + * src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on + pointer values. + +2007-12-01 Andreas Tobler + + PR libffi/31937 + * src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT. + Add local FFI_TYPE_UINT128 to handle soft-float long-double-128. + * src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and + set the NUM_FPR_ARG_REGISTERS according to. + Add support for potential soft-float support under hard-float + architecture. + (ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of + FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according + to the FFI_LINUX_SOFT_FLOAT ABI. + (ffi_prep_cif_machdep): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * src/powerpc/ppc_closure.S: Make sure not to store float/double + on archs where __NO_FPRS__ is true. + Add FFI_TYPE_UINT128 support. + * src/powerpc/sysv.S: Add support for soft-float long-double-128. + Adjust copyright notice. + +2007-11-25 Andreas Tobler + + * src/closures.c: Move defintion of MAYBE_UNUSED from here to ... + * include/ffi_common.h: ... here. + Update copyright. + +2007-11-17 Andreas Tobler + + * src/powerpc/sysv.S: Load correct cr to compare if we have long double. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/ffi.c: Add a comment to show which part goes into cr6. + * testsuite/libffi.call/return_ldl.c: New test. + +2007-09-04 + + * src/arm/sysv.S (UNWIND): New. + (Whole file): Conditionally compile unwinder directives. + * src/arm/sysv.S: Add unwinder directives. + + * src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes. + Only treat r0 as a struct address if we're actually returning a + struct by address. + Only copy the bytes that are actually within a struct. + (ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes + is returned in r0, not passed by address. + (ffi_call): Allocate a word-sized temporary for the case where + a composite is returned in r0. + (ffi_prep_incoming_args_SYSV): Align as necessary. + +2007-08-05 Steven Newbury + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of + directly using the sys_cacheflush syscall. + +2007-07-27 Andrew Haley + + * src/arm/sysv.S (ffi_closure_SYSV): Add soft-float. + +2007-09-03 Maciej W. Rozycki + + * Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure: Likewise. + +2007-08-24 David Daney + + * testsuite/libffi.call/return_sl.c: New test. + +2007-08-10 David Daney + + * testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.special/unwindtest_ffi_call.cc, + testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*. + +2007-08-10 David Daney + + PR libffi/28313 + * configure.ac: Don't treat mips64 as a special case. + * Makefile.am (nodist_libffi_la_SOURCES): Add n32.S. + * configure: Regenerate + * Makefile.in: Ditto. + * fficonfig.h.in: Ditto. + * src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent. + (LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros. + (FFI_DEFAULT_ABI): Set for n64 case. + (FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases. + * src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE. + (ffi_closure_N32): New function. + (.eh_frame): New section + * src/mips/o32.S: Clean up comments. + (ffi_closure_O32): Pass ffi_closure parameter in $12. + * src/mips/ffi.c: Use FFI_MIPS_N32 instead of + _MIPS_SIM == _ABIN32 throughout. + (FFI_MIPS_STOP_HERE): New, use in place of + ffi_stop_here. + (ffi_prep_args): Use unsigned long to hold pointer values. Rewrite + to support n32/n64 ABIs. + (calc_n32_struct_flags): Rewrite. + (calc_n32_return_struct_flags): Remove unused variable. Reverse + position of flag bits. + (ffi_prep_cif_machdep): Rewrite n32 portion. + (ffi_call): Enable for n64. Add special handling for small structure + return values. + (ffi_prep_closure_loc): Add n32 and n64 support. + (ffi_closure_mips_inner_O32): Add cast to silence warning. + (copy_struct_N32, ffi_closure_mips_inner_N32): New functions. + +2007-08-08 David Daney + + * testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition. + * testsuite/libffi.call/cls_align_uint16.c (main): Use correct type + specifiers. + * testsuite/libffi.call/nested_struct1.c (main): Ditto. + * testsuite/libffi.call/cls_sint.c (main): Ditto. + * testsuite/libffi.call/nested_struct9.c (main): Ditto. + * testsuite/libffi.call/cls_20byte1.c (main): Ditto. + * testsuite/libffi.call/cls_9byte1.c (main): Ditto. + * testsuite/libffi.call/closure_fn1.c (main): Ditto. + * testsuite/libffi.call/closure_fn3.c (main): Ditto. + * testsuite/libffi.call/return_dbl2.c (main): Ditto. + * testsuite/libffi.call/cls_sshort.c (main): Ditto. + * testsuite/libffi.call/return_fl3.c (main): Ditto. + * testsuite/libffi.call/closure_fn5.c (main): Ditto. + * testsuite/libffi.call/nested_struct.c (main): Ditto. + * testsuite/libffi.call/nested_struct10.c (main): Ditto. + * testsuite/libffi.call/return_ll1.c (main): Ditto. + * testsuite/libffi.call/cls_8byte.c (main): Ditto. + * testsuite/libffi.call/cls_align_uint32.c (main): Ditto. + * testsuite/libffi.call/cls_align_sint16.c (main): Ditto. + * testsuite/libffi.call/cls_20byte.c (main): Ditto. + * testsuite/libffi.call/nested_struct2.c (main): Ditto. + * testsuite/libffi.call/cls_24byte.c (main): Ditto. + * testsuite/libffi.call/nested_struct6.c (main): Ditto. + * testsuite/libffi.call/cls_uint.c (main): Ditto. + * testsuite/libffi.call/cls_12byte.c (main): Ditto. + * testsuite/libffi.call/cls_16byte.c (main): Ditto. + * testsuite/libffi.call/closure_fn0.c (main): Ditto. + * testsuite/libffi.call/cls_9byte2.c (main): Ditto. + * testsuite/libffi.call/closure_fn2.c (main): Ditto. + * testsuite/libffi.call/return_dbl1.c (main): Ditto. + * testsuite/libffi.call/closure_fn4.c (main): Ditto. + * testsuite/libffi.call/closure_fn6.c (main): Ditto. + * testsuite/libffi.call/cls_align_sint32.c (main): Ditto. + +2007-08-07 Andrew Haley + + * src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous + checkin. + +2007-08-06 Andrew Haley + + PR testsuite/32843 + * src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, + FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, + FFI_TYPE_SINT32. + +2007-08-02 David Daney + + * testsuite/libffi.call/return_ul.c (main): Define return type as + ffi_arg. Use proper printf conversion specifier. + +2007-07-30 Andrew Haley + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for + signed/unsigned int8/16. + * src/x86/sysv.S (ffi_call_SYSV): Rewrite to: + Use a jump table. + Remove code to pop args from the stack after call. + Special-case signed/unsigned int8/16. + * testsuite/libffi.call/return_sc.c (main): Revert. + +2007-07-26 Richard Guenther + + PR testsuite/32843 + * testsuite/libffi.call/return_sc.c (main): Verify call + result as signed char, not ffi_arg. + +2007-07-16 Rainer Orth + + * configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64. + * configure: Regenerate. + +2007-07-11 David Daney + + * src/mips/ffi.c: Don't include sys/cachectl.h. + (ffi_prep_closure_loc): Use __builtin___clear_cache() instead of + cacheflush(). + +2007-05-18 Aurelien Jarno + + * src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted + from (ffi_prep_closure): ... this. + (FFI_INIT_TRAMPOLINE): Adjust. + +2005-12-31 Phil Blundell + + * src/arm/ffi.c (ffi_prep_incoming_args_SYSV, + ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support. + * src/arm/sysv.S(ffi_closure_SYSV): Likewise. + * src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_CLOSURES): Enable closure support. + +2007-07-03 Andrew Haley + + * testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.special/unwindtest_ffi_call.cc, + testsuite/libffi.special/unwindtest.cc: Enable for ARM. + +2007-07-05 H.J. Lu + + * aclocal.m4: Regenerated. + +2007-06-02 Paolo Bonzini + + * configure: Regenerate. + +2007-05-23 Steve Ellcey + + * Makefile.in: Regenerate. + * configure: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2007-05-10 Roman Zippel + + * src/m68k/ffi.c (ffi_prep_incoming_args_SYSV, + ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support. + * src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise. + * src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_CLOSURES): Enable closure support. + +2007-05-10 Roman Zippel + + * configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC, + CFI_OFFSET,CFI_DEF_CFA): New macros. + (ffi_call_SYSV): Add callframe annotation. + +2007-05-10 Roman Zippel + + * src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix + numerous test suite failures. + * src/m68k/sysv.S (ffi_call_SYSV): Likewise. + +2007-04-11 Paolo Bonzini + + * Makefile.am (EXTRA_DIST): Bring up to date. + * Makefile.in: Regenerate. + * src/frv/eabi.S: Remove RCS keyword. + +2007-04-06 Richard Henderson + + * configure.ac: Tidy target case. + (HAVE_LONG_DOUBLE): Allow the target to override. + * configure: Regenerate. + * include/ffi.h.in: Don't define ffi_type_foo if + LIBFFI_HIDE_BASIC_TYPES is defined. + (ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define + to ffi_type_double. + * types.c (LIBFFI_HIDE_BASIC_TYPES): Define. + (FFI_TYPEDEF, ffi_type_void): Mark the data const. + (ffi_type_longdouble): Special case for Alpha. Don't define + if long double == double. + + * src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value. + (ffi_prep_cif_machdep): Handle it as the 128-bit type. + (ffi_call, ffi_closure_osf_inner): Likewise. + (ffi_closure_osf_inner): Likewise. Mark hidden. + (ffi_call_osf, ffi_closure_osf): Mark hidden. + * src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition. + * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden. + (load_table): Handle 128-bit long double. + + * testsuite/libffi.call/float4.c: Add -mieee for alpha. + +2007-04-06 Tom Tromey + + PR libffi/31491: + * README: Fixed bug in example. + +2007-04-03 Jakub Jelinek + + * src/closures.c: Include sys/statfs.h. + (_GNU_SOURCE): Define on Linux. + (FFI_MMAP_EXEC_SELINUX): Define. + (selinux_enabled): New variable. + (selinux_enabled_check): New function. + (is_selinux_enabled): Define. + (dlmmap): Use it. + +2007-03-24 Uros Bizjak + + * testsuite/libffi.call/return_fl2.c (return_fl): Mark as static. + Use 'volatile float sum' to create sum of floats to avoid false + negative due to excess precision on ix86 targets. + (main): Ditto. + +2007-03-08 Alexandre Oliva + + * src/powerpc/ffi.c (flush_icache): Fix left-over from previous + patch. + (ffi_prep_closure_loc): Remove unneeded casts. Add needed ones. + +2007-03-07 Alexandre Oliva + + * include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New. + (ffi_prep_closure_loc): New. + (ffi_prep_raw_closure_loc): New. + (ffi_prep_java_raw_closure_loc): New. + * src/closures.c: New file. + * src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment): + Replace sflags with exec_offset. + [FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset, + sub_segment_exec_offset): New macros. + (get_segment_flags, set_segment_flags, check_segment_merge): New + macros. + (is_mmapped_segment, is_extern_segment): Use get_segment_flags. + (add_segment, sys_alloc, create_mspace, create_mspace_with_base, + destroy_mspace): Use new macros. + (sys_alloc): Silence warning. + * Makefile.am (libffi_la_SOURCES): Add src/closures.c. + * Makefile.in: Rebuilt. + * src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in + terms of ffi_prep_closure_loc. + * src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted + from... + (ffi_prep_raw_closure): ... this. Re-implement in terms of the + renamed version. + * src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and + adjusted from... + (ffi_prep_java_raw_closure): ... this. Re-implement in terms of + the renamed version. + * src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from + (ffi_prep_closure): ... this. + * src/pa/ffi.c: Likewise. + * src/cris/ffi.c: Likewise. Adjust. + * src/frv/ffi.c: Likewise. + * src/ia64/ffi.c: Likewise. + * src/mips/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/s390/ffi.c: Likewise. + * src/sh/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/sparc/ffi.c: Likewise. + * src/x86/ffi64.c: Likewise. + * src/x86/ffi.c: Likewise. + (FFI_INIT_TRAMPOLINE): Adjust. + (ffi_prep_raw_closure_loc): Renamed and adjusted from... + (ffi_prep_raw_closure): ... this. + * src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from + (ffi_prep_closure): ... this. + (flush_icache): Adjust. + +2007-03-07 Alexandre Oliva + + * src/dlmalloc.c: New file, imported version 2.8.3 of Doug + Lea's malloc. + +2007-03-01 Brooks Moses + + * Makefile.am: Add dummy install-pdf target. + * Makefile.in: Regenerate + +2007-02-13 Andreas Krebbel + + * src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep, + ffi_closure_helper_SYSV): Add long double handling. + +2007-02-02 Jakub Jelinek + + * src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2 + immediately after bctrl instruction. + +2007-01-18 Alexandre Oliva + + * Makefile.am (all-recursive, install-recursive, + mostlyclean-recursive, clean-recursive, distclean-recursive, + maintainer-clean-recursive): Add missing targets. + * Makefile.in: Rebuilt. + +2006-12-14 Andreas Tobler + + * configure.ac: Add TARGET for x86_64-*-darwin*. + * Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources + for X86_DARWIN. + * src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*. + * src/x86/darwin64.S: New file for x86_64-*-darwin* support. + * configure: Regenerate. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + * testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for + ffi_call only. + +2006-12-13 Andreas Tobler + + * aclocal.m4: Regenerate with aclocal -I .. as written in the + Makefile.am. + +2006-10-31 Geoffrey Keating + + * src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New. + (ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for + Darwin. + * testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL. + * testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL. + +2006-10-10 Paolo Bonzini + Sandro Tolaini + + * configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and + conditional. + * configure: Regenerated. + * Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case. + (EXTRA_DIST): Add src/x86/darwin.S. + * Makefile.in: Regenerated. + * include/Makefile.in: Regenerated. + * testsuite/Makefile.in: Regenerated. + + * src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like + X86_WIN32, and additionally align stack to 16 bytes. + * src/x86/darwin.S: New, based on sysv.S. + * src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs. + +2006-09-12 David Daney + + PR libffi/23935 + * include/Makefile.am: Install both ffi.h and ffitarget.h in + $(libdir)/gcc/$(target_alias)/$(gcc_version)/include. + * aclocal.m4: Regenerated for automake 1.9.6. + * Makefile.in: Regenerated. + * include/Makefile.in: Regenerated. + * testsuite/Makefile.in: Regenerated. + +2006-08-17 Andreas Tobler + + * include/ffi_common.h (struct): Revert accidental commit. + +2006-08-15 Andreas Tobler + + * include/ffi_common.h: Remove lint directives. + * include/ffi.h.in: Likewise. + +2006-07-25 Torsten Schoenfeld + + * include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly + for 32-bit architectures. + * testsuite/libffi.call/return_ul.c: New test case. + +2006-07-19 David Daney + + * testsuite/libffi.call/closure_fn6.c: Remove xfail for mips, + xfail remains for mips64. + +2006-05-23 Carlos O'Donell + + * Makefile.am: Add install-html target. Add install-html to .PHONY + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2006-05-18 John David Anglin + + * pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from + stack slot. + +2006-04-22 Andreas Tobler + + * README: Remove notice about 'Crazy Comments'. + * src/debug.c: Remove lint directives. Cleanup white spaces. + * src/java_raw_api.c: Likewise. + * src/prep_cif.c: Likewise. + * src/raw_api.c: Likewise. + * src/ffitest.c: Delete. No longer needed, all test cases migrated + to the testsuite. + * src/arm/ffi.c: Remove lint directives. + * src/m32r/ffi.c: Likewise. + * src/pa/ffi.c: Likewise. + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/sh/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/x86/ffi.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + +2006-04-13 Andreas Tobler + + * src/pa/hpux32.S: Correct unwind offset calculation for + ffi_closure_pa32. + * src/pa/linux.S: Likewise. + +2006-04-12 James E Wilson + + PR libgcj/26483 + * src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros. + (hfa_type_load): Call stf_spill. + (hfa_type_store): Call ldf_fill. + (ffi_call): Adjust calls to above routines. Add local temps for + macro result. + +2006-04-10 Matthias Klose + + * testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib + directory names containing underscores. + +2006-04-07 James E Wilson + + * testsuite/libffi.call/float4.c: New testcase. + +2006-04-05 John David Anglin + Andreas Tobler + + * Makefile.am: Add PA_HPUX port. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure.ac: Add PA_HPUX rules. + * configure: Regenerate. + * src/pa/ffitarget.h: Rename linux target to PA_LINUX. + Add PA_HPUX and PA64_HPUX. + Rename FFI_LINUX ABI to FFI_PA32 ABI. + (FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets. + (FFI_TYPE_SMALL_STRUCT2): Define. + (FFI_TYPE_SMALL_STRUCT4): Likewise. + (FFI_TYPE_SMALL_STRUCT8): Likewise. + (FFI_TYPE_SMALL_STRUCT3): Redefine. + (FFI_TYPE_SMALL_STRUCT5): Likewise. + (FFI_TYPE_SMALL_STRUCT6): Likewise. + (FFI_TYPE_SMALL_STRUCT7): Likewise. + * src/pa/ffi.c (ROUND_DOWN): Delete. + (fldw, fstw, fldd, fstd): Use '__asm__'. + (ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2, + FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8. + (ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment. + Simplify incrementing of stack slot variable. Change type of local + 'n' to unsigned int. + (ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long + double on PA_HPUX. + (ffi_prep_cif_machdep): Likewise. + (ffi_call): Likewise. + (ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change + return type to ffi_status. Simplify incrementing of stack slot + variable. Only copy floating point argument registers when PA_LINUX + is true. Reformat debug statement. + Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and + FFI_TYPE_SMALL_STRUCT8. + (ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to + declaration. + (ffi_prep_closure): Make linux trampoline conditional on PA_LINUX. + Add nops to cache flush. Add trampoline for PA_HPUX. + * src/pa/hpux32.S: New file. + * src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename + ffi_prep_args_LINUX to ffi_prep_args_pa32. + Localize labels. Add support for 2, 4 and 8-byte small structs. Handle + unaligned destinations in 3, 5, 6 and 7-byte small structs. Order + argument type checks so that common argument types appear first. + (ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename + ffi_closure_inner_LINUX to ffi_closure_inner_pa32. + +2006-03-24 Alan Modra + + * src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX. Default + for 32-bit using IBM extended double format. Fix FFI_LAST_ABI. + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of + FFI_TYPE_LONGDOUBLE. + (ffi_prep_args64): Assert using IBM extended double. + (ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type. + Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args. + (ffi_call): Handle FFI_LINUX. + (ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs + gpr3 return pointer as for struct return. Handle FFI_LINUX + FFI_TYPE_LONGDOUBLE return and args. Don't increment "nf" + unnecessarily. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2 + for FFI_TYPE_LONGDOUBLE. Move epilogue insns into case table. + Don't use r6 as pointer to results, instead use sp offset. Don't + make a special call to load lr with case table address, instead + use offset from previous call. + * src/powerpc/sysv.S (ffi_call_SYSV): Save long double return. + * src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double + return. + +2006-03-15 Kaz Kojima + + * src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments + passed with FP registers correctly. + (ffi_closure_helper_SYSV): Likewise. + * src/sh64/sysv.S: Likewise. + +2006-03-01 Andreas Tobler + + * testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif, + args and userdata unused. + (closure_test_fn1): Mark cif and userdata unused. + (main): Remove unused res. + +2006-02-28 Andreas Tobler + + * testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for + -O2, -O3, -Os and the warning flags -W -Wall. + * testsuite/libffi.special/special.exp: Likewise. + * testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark + unused parameter unused for gcc or else do nothing. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif + and userdata unused. + * testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise. + * testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise. + * testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise. + * testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise. + * testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise. + * testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise. + * testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise. + * testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise. + * testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise. + * testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise. + * testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise. + * testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise. + * testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise. + * testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise. + * testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise. + * testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise. + * testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise. + * testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise. + * testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise. + * testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise. + * testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise. + * testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise. + * testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise. + * testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast + void* to avoid compiler warning. + (main): Likewise. + (cls_struct_align_gn): Mark cif and userdata unused. + * testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise. + * testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise. + * testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif + and data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif + and data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and + userdata unused. + (cls_ret_schar_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and + userdata unused. + (cls_ret_sint_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and + userdata unused. + (cls_ret_sshort_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn): Mark cif and + userdata unused. + (cls_ret_uchar_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and + userdata unused. + (cls_ret_uint_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif + and userdata unused. + * testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and + userdata unused. + (cls_ret_ushort_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/float.c (floating): Remove unused parameter e. + * testsuite/libffi.call/float1.c (main): Remove unused variable i. + Cleanup white spaces. + * testsuite/libffi.call/negint.c (checking): Remove unused variable i. + * testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark + cif and userdata unused. + * testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn): + Likewise. + * testsuite/libffi.call/nested_struct10.c (B_gn): Likewise. + * testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf + formatters to silence gcc. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct4.c: Mention related PR. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct6.c: Mention related PR. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct8.c (B_gn): Likewise. + * testsuite/libffi.call/nested_struct9.c (B_gn): Likewise. + * testsuite/libffi.call/problem1.c (stub): Likewise. + * testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence + gcc. + * testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned + in the last commit for this test case in the test case itself. + * testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as + unused. + * testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise. + * testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise. + * testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise. + * testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise. + * testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise. + * testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise. + +2006-02-22 Kaz Kojima + + * src/sh/sysv.S: Fix register numbers in the FDE for + ffi_closure_SYSV. + +2006-02-20 Andreas Tobler + + * testsuite/libffi.call/return_fl2.c (return_fl): Remove static + declaration to avoid a false negative on ix86. See PR323. + +2006-02-18 Kaz Kojima + + * src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable + and cast integer to void * if needed. Update the pointer to + the FP register saved area correctly. + +2006-02-17 Andreas Tobler + + * testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630 + is fixed. + * testsuite/libffi.call/nested_struct4.c: Likewise. + +2006-02-16 Andreas Tobler + + * testsuite/libffi.call/return_dbl.c: New test case. + * testsuite/libffi.call/return_dbl1.c: Likewise. + * testsuite/libffi.call/return_dbl2.c: Likewise. + * testsuite/libffi.call/return_fl.c: Likewise. + * testsuite/libffi.call/return_fl1.c: Likewise. + * testsuite/libffi.call/return_fl2.c: Likewise. + * testsuite/libffi.call/return_fl3.c: Likewise. + * testsuite/libffi.call/closure_fn6.c: Likewise. + + * testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong + definition. + * testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition + here to be used by other test cases too. + + * testsuite/libffi.call/nested_struct10.c: New test case. + * testsuite/libffi.call/nested_struct9.c: Likewise. + * testsuite/libffi.call/nested_struct8.c: Likewise. + * testsuite/libffi.call/nested_struct7.c: Likewise. + * testsuite/libffi.call/nested_struct6.c: Likewise. + * testsuite/libffi.call/nested_struct5.c: Likewise. + * testsuite/libffi.call/nested_struct4.c: Likewise. + +2006-01-21 Andreas Tobler + + * configure.ac: Enable libffi for sparc64-*-freebsd*. + * configure: Rebuilt. + +2006-01-18 Jakub Jelinek + + * src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3, + instead do the shifting inline. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5 + shift count unconditionally. Simplify load sequences for 1, 2, 3, 4 + and 8 byte structs, for the remaining struct sizes don't call + __lshrdi3, instead do the shifting inline. + +2005-12-07 Thiemo Seufer + + * src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add + missing parentheses. + * src/mips/o32.S (ffi_call_O32): Code formatting. Define + and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations. + (ffi_closure_O32): Likewise, but with newly defined A3_OFF2, + A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2, + V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2, + FA_0_0_OFF2. + * src/mips/ffi.c (ffi_prep_args): Code formatting. Fix + endianness bugs. + (ffi_prep_closure): Improve trampoline instruction scheduling. + (ffi_closure_mips_inner_O32): Fix endianness bugs. + +2005-12-03 Alan Modra + + * src/powerpc/ffi.c: Formatting. + (ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions. + (ffi_prep_args64): Likewise. + +2005-09-30 Geoffrey Keating + + * testsuite/lib/libffi-dg.exp (libffi_target_compile): For + darwin, use -shared-libgcc not -lgcc_s, and explain why. + +2005-09-26 Tom Tromey + + * testsuite/libffi.call/float1.c (value_type): New typedef. + (CANARY): New define. + (main): Check for result buffer overflow. + * src/powerpc/linux64.S: Handle linux64 long double returns. + * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant. + (ffi_prep_cif_machdep): Handle linux64 long double returns. + +2005-08-25 Alan Modra + + PR target/23404 + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack + homed fp args. + (ffi_status ffi_prep_cif_machdep): Correct stack sizing for same. + +2005-08-11 Jakub Jelinek + + * configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test. + (AH_BOTTOM): Add FFI_HIDDEN definition. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + * src/powerpc/ffi.c (hidden): Remove. + (ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64, + ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64, + .ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden. + * src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove, + add FFI_HIDDEN to its prototype. + (ffi_closure_SYSV_inner): New. + * src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. + * src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. + +2005-08-10 Alfred M. Szmidt + + PR libffi/21819: + * configure: Rebuilt. + * configure.ac: Handle i*86-*-gnu*. + +2005-08-09 Jakub Jelinek + + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use + DW_CFA_offset_extended_sf rather than + DW_CFA_GNU_negative_offset_extended. + * src/powerpc/sysv.S (ffi_call_SYSV): Likewise. + +2005-07-22 SUGIOKA Toshinobu + + * src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly + on sh3. + (ffi_closure_SYSV): Change the stack layout for sh3 struct argument. + * src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is + partially on register. + (ffi_closure_helper_SYSV): Likewise. + (ffi_prep_cif_machdep): Don't set too many cif->flags. + +2005-07-20 Kaz Kojima + + * src/sh/ffi.c (ffi_call): Handle small structures correctly. + Remove empty line. + * src/sh64/ffi.c (simple_type): Remove. + (return_type): Handle small structures correctly. + (ffi_prep_args): Likewise. + (ffi_call): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return. + Emit position independent code if PIC and remove wrong datalabel + prefixes from EH data. + +2005-07-19 Andreas Tobler + + * Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure.ac: Add POWERPC_FREEBSD rules. + * configure: Regenerate. + * src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules. + (FFI_SYSV_TYPE_SMALL_STRUCT): Define. + * src/powerpc/ffi.c: Add flags to handle small structure returns + in ffi_call_SYSV. + (ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI. + Aka FFI_SYSV. + (ffi_closure_helper_SYSV): Likewise. + * src/powerpc/ppc_closure.S: Add return types for small structures. + * src/powerpc/sysv.S: Add bits to handle small structures for + final SYSV 4 ABI. + +2005-07-10 Andreas Tobler + + * testsuite/libffi.call/cls_5_1_byte.c: New test file. + * testsuite/libffi.call/cls_6_1_byte.c: Likewise. + * testsuite/libffi.call/cls_7_1_byte.c: Likewise. + +2005-07-05 Randolph Chung + + * src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1 + as FFI_TYPE_SMALL_STRUCT3. Break out handling for 5-7 byte + structures. Kill compilation warnings. + (ffi_closure_inner_LINUX): Print return values as hex in debug + message. Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3. + Properly handle 5-7 byte structure returns. + * src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1) + (FFI_TYPE_SMALL_STRUCT2): Remove. + (FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5) + (FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define. + * src/pa/linux.S: Mark source file as using PA1.1 assembly. + (checksmst1, checksmst2): Remove. + (checksmst3): Optimize handling of 3-byte struct returns. + (checksmst567): Properly handle 5-7 byte struct returns. + +2005-06-15 Rainer Orth + + PR libgcj/21943 + * src/mips/n32.S: Enforce PIC code. + * src/mips/o32.S: Likewise. + +2005-06-15 Rainer Orth + + * configure.ac: Treat i*86-*-solaris2.10 and up as X86_64. + * configure: Regenerate. + +2005-06-01 Alan Modra + + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET + to call ffi_closure_helper_SYSV. Append @local instead. + * src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV. + +2005-05-17 Kelley Cook + + * configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS. + Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF. + * Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config. + * aclocal.m4, configure, fficonfig.h.in, Makefile.in, + include/Makefile.in, testsuite/Makefile.in: Regenerate. + +2005-05-09 Mike Stump + + * configure: Regenerate. + +2005-05-08 Richard Henderson + + PR libffi/21285 + * src/alpha/osf.S: Update unwind into to match code. + +2005-05-04 Andreas Degert + Richard Henderson + + * src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in + bit 11 of flags. + (ffi_call): Mask return type field. Pass ssecount to ffi_call_unix64. + (ffi_prep_closure): Set carry bit if sse-used flag set. + * src/x86/unix64.S (ffi_call_unix64): Add ssecount argument. + Only load sse registers if ssecount non-zero. + (ffi_closure_unix64): Only save sse registers if carry set on entry. + +2005-04-29 Ralf Corsepius + + * configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*, + powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*. + * configure: Regenerate. + +2005-04-20 Hans-Peter Nilsson + + * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use, + have Tcl8.3-compatible intermediate variable. + +2005-04-18 Simon Posnjak + Hans-Peter Nilsson + + * Makefile.am: Add CRIS support. + * configure.ac: Likewise. + * Makefile.in, configure, testsuite/Makefile.in, + include/Makefile.in: Regenerate. + * src/cris: New directory. + * src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files. + * src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__. + + * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with + \r?\n in output tests. + +2005-04-12 Mike Stump + + * configure: Regenerate. + +2005-03-30 Hans Boehm + + * src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI. + +2005-03-30 Steve Ellcey + + * src/ia64/ffitarget.h (ffi_arg) ADD DI attribute. + (ffi_sarg) Ditto. + * src/ia64/unix.S (ffi_closure_unix): Extend gp + to 64 bits in ILP32 mode. + Load 64 bits even for short data. + +2005-03-23 Mike Stump + + * src/powerpc/darwin.S: Update for -m64 multilib. + * src/powerpc/darwin_closure.S: Likewise. + +2005-03-21 Zack Weinberg + + * configure.ac: Do not invoke TL_AC_GCC_VERSION. + Do not set tool_include_dir. + * aclocal.m4, configure, Makefile.in, testsuite/Makefile.in: + Regenerate. + * include/Makefile.am: Set gcc_version and toollibffidir. + * include/Makefile.in: Regenerate. + +2005-02-22 Andrew Haley + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to + odd-numbered register pairs for 64-bit integer types. + +2005-02-23 Andreas Tobler + + PR libffi/20104 + * testsuite/libffi.call/return_ll1.c: New test case. + +2005-02-11 Janis Johnson + + * testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options. + * testsuite/libffi.call/float.c: Ditto. + * testsuite/libffi.call/float2.c: Ditto. + * testsuite/libffi.call/float3.c: Ditto. + +2005-02-08 Andreas Tobler + + * src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv. + +2005-01-12 Eric Botcazou + + * testsuite/libffi.special/special.exp (cxx_options): Add + -shared-libgcc. + +2004-12-31 Richard Henderson + + * src/types.c (FFI_AGGREGATE_TYPEDEF): Remove. + (FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF. Replace size and + offset parameters with a type parameter; deduce size and structure + alignment. Update all users. + +2004-12-31 Richard Henderson + + * src/types.c (FFI_TYPE_POINTER): Define with sizeof. + (FFI_TYPE_LONGDOUBLE): Fix for ia64. + * src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move + into ffi_prep_closure. + * src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite + from scratch. + +2004-12-27 Richard Henderson + + * src/x86/unix64.S: Fix typo in unwind info. + +2004-12-25 Richard Henderson + + * src/x86/ffi64.c (struct register_args): Rename from stackLayout. + (enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS. + (merge_classes): Check for it. + (SSE_CLASS_P): New. + (classify_argument): Pass byte_offset by value; perform all updates + inside struct case. + (examine_argument): Add classes argument; handle + X86_64_COMPLEX_X87_CLASS. + (ffi_prep_args): Merge into ... + (ffi_call): ... here. Share stack frame with ffi_call_unix64. + (ffi_prep_cif_machdep): Setup cif->flags for proper structure return. + (ffi_fill_return_value): Remove. + (ffi_prep_closure): Remove dead assert. + (ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner. + Rewrite to use struct register_args instead of va_list. Create + flags for handling structure returns. + * src/x86/unix64.S: Remove dead strings. + (ffi_call_unix64): Rename from ffi_call_UNIX64. Rewrite to share + stack frame with ffi_call. Handle structure returns properly. + (float2sse, floatfloat2sse, double2sse): Remove. + (sse2float, sse2double, sse2floatfloat): Remove. + (ffi_closure_unix64): Rename from ffi_closure_UNIX64. Rewrite + to handle structure returns properly. + +2004-12-08 David Edelsohn + + * Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and + PICFLAG. + * Makefile.in: Regenerated. + +2004-12-02 Richard Sandiford + + * configure.ac: Use TL_AC_GCC_VERSION to set gcc_version. + * configure, aclocal.m4, Makefile.in: Regenerate. + * include/Makefile.in, testsuite/Makefile.in: Regenerate. + +2004-11-29 Kelley Cook + + * configure: Regenerate for libtool change. + +2004-11-25 Kelley Cook + + * configure: Regenerate for libtool reversion. + +2004-11-24 Kelley Cook + + * configure: Regenerate for libtool change. + +2004-11-23 John David Anglin + + * testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp. + +2004-11-23 Richard Sandiford + + * src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead + of jal. Use an absolute encoding for the frame information. + +2004-11-23 Kelley Cook + + * Makefile.am: Remove no-dependencies. Add ACLOCAL_AMFLAGS. + * acinclude.m4: Delete logic for sincludes. + * aclocal.m4, Makefile.in, configure: Regenerate. + * include/Makefile: Likewise. + * testsuite/Makefile: Likewise. + +2004-11-22 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers + on a 8-byte boundary. + * src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments. + +2004-10-27 Richard Earnshaw + + * src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return + long long values. Round stack allocation to a multiple of 8 bytes + for ATPCS compatibility. + * src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register + names. Handle returning long long types. Add Thumb and interworking + support. Improve soft-float code. + +2004-10-27 Richard Earnshaw + + * testsuite/lib/libffi-db.exp (load_gcc_lib): New function. + (libffi_exit): New function. + (libffi_init): Build the testglue wrapper if needed. + +2004-10-25 Eric Botcazou + + PR other/18138 + * testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc. + +2004-10-25 Kazuhiro Inaoka + + * src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0. + +2004-10-20 Kaz Kojima + + * src/sh/sysv.S (ffi_call_SYSV): Don't align for double data. + * testsuite/libffi.call/float3.c: New test case. + +2004-10-18 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for + the function returning a structure pointed with R2. + * src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to + the structure return value if T bit set. Emit position + independent code and EH data if PIC. + +2004-10-13 Kazuhiro Inaoka + + * Makefile.am: Add m32r support. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * confiugre: Regenerate. + * src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF + (uint64, sint64, double, longdouble) + * src/m32r: New directory. + * src/m32r/ffi.c: New file. + * src/m32r/sysv.S: Likewise. + * src/m32r/ffitarget.h: Likewise. + +2004-10-02 Kaz Kojima + + * testsuite/libffi.call/negint.c: New test case. + +2004-09-14 H.J. Lu + + PR libgcj/17465 + * testsuite/lib/libffi-dg.exp: Don't use global ld_library_path. + Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH, + LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and + DYLD_LIBRARY_PATH. + +2004-09-05 Andreas Tobler + + * testsuite/libffi.call/many_win32.c: Remove whitespaces. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup + whitespaces. + * testsuite/libffi.call/return_sc.c: Likewise. + * testsuite/libffi.call/return_uc.c: Likewise. + +2004-09-05 Andreas Tobler + + * src/powerpc/darwin.S: Fix comments and identation. + * src/powerpc/darwin_closure.S: Likewise. + +2004-09-02 Andreas Tobler + + * src/powerpc/ffi_darwin.c: Add flag for longdouble return values. + (ffi_prep_args): Handle longdouble arguments. + (ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for + longdouble. + (ffi_closure_helper_DARWIN): Add closure handling for longdouble. + * src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble + values. + * src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise. + * src/types.c: Defined longdouble size and alignment for darwin. + +2004-09-02 Andreas Tobler + + * src/powerpc/aix.S: Remove whitespaces. + * src/powerpc/aix_closure.S: Likewise. + * src/powerpc/asm.h: Likewise. + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffitarget.h: Likewise. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + +2004-08-30 Anthony Green + + * Makefile.am: Add frv support. + * Makefile.in, testsuite/Makefile.in: Rebuilt. + * configure.ac: Read configure.host. + * configure.in: Read configure.host. + * configure.host: New file. frv-elf needs libgloss. + * include/ffi.h.in: Force ffi_closure to have a nice big (8) + alignment. This is needed to frv and shouldn't harm the others. + * include/ffi_common.h (ALIGN_DOWN): New macro. + * src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files. + +2004-08-24 David Daney + + * testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_multi_schar.c: Likewise. + * testsuite/libffi.call/cls_multi_sshort.c: Likewise. + * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_uchar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushort.c: Likewise. + * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise and set return value + to zero. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + +2004-08-23 David Daney + + PR libgcj/13141 + * src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI. + * src/mips/ffi.c (ffi_prep_args): Fix alignment calculation. + (ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point + parameters and return types. + (ffi_call): Handle FFI_O32_SOFT_FLOAT ABI. + (ffi_prep_closure): Ditto. + (ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix + alignment calculations. + * src/mips/o32.S (ffi_closure_O32): Don't use floating point + instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant. + +2004-08-14 Casey Marshall + + * src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to + contain `FFI_TYPE_UINT64' as return type for any 64-bit + integer (O32 ABI only). + (ffi_prep_closure): new function. + (ffi_closure_mips_inner_O32): new function. + * src/mips/ffitarget.h: Define `FFI_CLOSURES' and + `FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32. + * src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return + 64 bit integers correctly. + (ffi_closure_O32): new function. + Added DWARF-2 unwind info for both functions. + +2004-08-10 Andrew Haley + + * src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments. + +2004-08-01 Robert Millan + + * configure.ac: Detect knetbsd-gnu and kfreebsd-gnu. + * configure: Regenerate. + +2004-07-30 Maciej W. Rozycki + + * acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for + and mmap() explicitly instead of relying on preset autoconf cache + variables. + * aclocal.m4: Regenerate. + * configure: Regenerate. + +2004-07-11 Ulrich Weigand + + * src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation. + (ffi_check_float_struct): Remove unused prototype. + +2004-06-30 Geoffrey Keating + + * src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment + character on Darwin, use '\n\t' instead. + +2004-06-26 Matthias Klose + + * libtool-version: Fix typo in revision/age. + +2004-06-17 Matthias Klose + + * libtool-version: New. + * Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname. + * Makefile.in: Regenerate. + +2004-06-15 Paolo Bonzini + + * Makefile.am: Remove useless multilib rules. + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate with automake 1.8.5. + * configure.ac: Remove useless multilib configury. + * configure: Regenerate. + +2004-06-15 Paolo Bonzini + + * .cvsignore: New file. + +2004-06-10 Jakub Jelinek + + * src/ia64/unix.S (ffi_call_unix): Insert group barrier break + fp_done. + (ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever + changed from 8. + +2004-06-06 Sean McNeil + + * configure.ac: Add x86_64-*-freebsd* support. + * configure: Regenerate. + +2004-04-26 Joe Buck + + Bug 15093 + * configure.ac: Test for existence of mmap and sys/mman.h before + checking blacklist. Fix suggested by Jim Wilson. + * configure: Regenerate. + +2004-04-26 Matt Austern + + * src/powerpc/darwin.S: Go through a non-lazy pointer for initial + FDE location. + * src/powerpc/darwin_closure.S: Likewise. + +2004-04-24 Andreas Tobler + + * testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization + error. Reported by Thomas Heller . + * testsuite/libffi.call/cls_multi_sshort.c (main): Likewise. + * testsuite/libffi.call/cls_multi_ushort.c (main): Likewise. + +2004-03-20 Matthias Klose + + * src/pa/linux.S: Fix typo. + +2004-03-19 Matthias Klose + + * Makefile.am: Update. + * Makefile.in: Regenerate. + * src/pa/ffi.h.in: Remove. + * src/pa/ffitarget.h: New file. + +2004-02-10 Randolph Chung + + * Makefile.am: Add PA support. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * configure.ac: Add PA target. + * configure: Regenerate. + * src/pa/ffi.c: New file. + * src/pa/ffi.h.in: Add PA support. + * src/pa/linux.S: New file. + * prep_cif.c: Add PA support. + +2004-03-16 Hosaka Yuji + + * src/types.c: Fix alignment size of X86_WIN32 case int64 and + double. + * src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type + with ecif->cif->flags. + (ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type + with cif->flags. + (ffi_prep_cif_machdep): Add X86_WIN32 struct case. + (ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32. + * src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b, + sc_retstruct2b): Add for 1 or 2-bytes struct case. + +2004-03-15 Kelley Cook + + * configure.in: Rename file to ... + * configure.ac: ... this. + * fficonfig.h.in: Regenerate. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2004-03-12 Matt Austern + + * src/powerpc/darwin.S: Fix EH information so it corresponds to + changes in EH format resulting from addition of linkonce support. + * src/powerpc/darwin_closure.S: Likewise. + +2004-03-11 Andreas Tobler + Paolo Bonzini + + * Makefile.am (AUTOMAKE_OPTIONS): Set them. + Remove VPATH. Remove rules for object files. Remove multilib support. + (AM_CCASFLAGS): Add. + * configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER. + (AC_PREREQ): Bump version to 2.59. + (AC_INIT): Fill with version info and bug address. + (ORIGINAL_LD_FOR_MULTILIBS): Remove. + (AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE. + De-precious CC so that the right flags are passed down to multilibs. + (AC_MSG_ERROR): Replace obsolete macro AC_ERROR. + (AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES. + (AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS. + * configure: Rebuilt. + * aclocal.m4: Likewise. + * Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise. + * fficonfig.h.in: Likewise. + +2004-03-11 Andreas Schwab + + * src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point + arguments from fp registers only for the first 8 parameter slots. + Don't convert a float parameter when passed in memory. + +2004-03-09 Hans-Peter Nilsson + + * configure: Regenerate for config/accross.m4 correction. + +2004-02-25 Matt Kraai + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Change + ecif->cif->bytes to bytes. + (ffi_prep_cif_machdep): Add braces around nested if statement. + +2004-02-09 Alan Modra + + * src/types.c (pointer): POWERPC64 has 8 byte pointers. + + * src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling. + (ffi_closure_helper_LINUX64): Fix typo. + * testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128 + for powerpc64-*-*. + * testsuite/libffi.call/float.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + +2004-02-08 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep ): Correct + long double function return and long double arg handling. + (ffi_closure_helper_LINUX64): Formatting. Delete unused "ng" var. + Use "end_pfr" instead of "nf". Correct long double handling. + Localise "temp". + * src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double + return value. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate + space for long double return value. Adjust stack frame and offsets. + Load f2 long double return. + +2004-02-07 Alan Modra + + * src/types.c: Use 16 byte long double for POWERPC64. + +2004-01-25 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array + when the structure return address is passed in %o0. + (ffi_V9_return_struct): Rename into ffi_v9_layout_struct. + (ffi_v9_layout_struct): Align the field following a nested structure + on a word boundary. Use memmove instead of memcpy. + (ffi_call): Update call to ffi_V9_return_struct. + (ffi_prep_closure): Define 'ctx' only for V8. + (ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8 + and ffi_closure_sparc_inner_v9. + (ffi_closure_sparc_inner_v8): Return long doubles by reference. + Always skip the structure return address. For structures and long + doubles, copy the argument directly. + (ffi_closure_sparc_inner_v9): Skip the structure return address only + if required. Shift the maximum floating-point slot accordingly. For + big structures, copy the argument directly; otherwise, left-justify the + argument and call ffi_v9_layout_struct to lay out the structure on + the stack. + * src/sparc/v8.S: Undef STACKFRAME before defining it. + (ffi_closure_v8): Pass the structure return address. Update call to + ffi_closure_sparc_inner_v8. Short-circuit FFI_TYPE_INT handling. + Skip the 'unimp' insn when returning long doubles and structures. + * src/sparc/v9.S: Undef STACKFRAME before defining it. + (ffi_closure_v9): Increase the frame size by 2 words. Short-circuit + FFI_TYPE_INT handling. Load structures both in integers and + floating-point registers on return. + * README: Update status of the SPARC port. + +2004-01-24 Andreas Tobler + + * testsuite/libffi.call/pyobjc-tc.c (main): Treat result value + as of type ffi_arg. + * testsuite/libffi.call/struct3.c (main): Fix CHECK. + +2004-01-22 Ulrich Weigand + + * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result + value as of type ffi_arg, not unsigned int. + +2004-01-21 Michael Ritzert + + * ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead + of the LHS. + +2004-01-12 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for + Solaris. + +2004-01-08 Rainer Orth + + * testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED + to void *. + +2003-12-10 Richard Henderson + + * testsuite/libffi.call/cls_align_pointer.c: Cast pointers to + size_t instead of int. + +2003-12-04 Hosaka Yuji + + * testsuite/libffi.call/many_win32.c: Include . + * testsuite/libffi.call/many_win32.c (main): Replace variable + int i with unsigned long ul. + + * testsuite/libffi.call/cls_align_uint64.c: New test case. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + +2003-12-02 Hosaka Yuji + + PR other/13221 + * src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): + Align arguments to 32 bits. + +2003-12-01 Andreas Tobler + + PR other/13221 + * testsuite/libffi.call/cls_multi_sshort.c: New test case. + * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_uchar.c: Likewise. + * testsuite/libffi.call/cls_multi_schar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushort.c: Likewise. + + * testsuite/libffi.special/unwindtest.cc: Cosmetics. + +2003-11-26 Kaveh R. Ghazi + + * testsuite/libffi.call/ffitest.h: Include . + * testsuite/libffi.special/ffitestcxx.h: Likewise. + +2003-11-22 Andreas Tobler + + * Makefile.in: Rebuilt. + * configure: Likewise. + * testsuite/libffi.special/unwindtest.cc: Convert the mmap to + the right type. + +2003-11-21 Andreas Jaeger + Andreas Tobler + + * acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST. + * configure.in: Call AC_FUNC_MMAP_BLACKLIST. + * Makefile.in: Rebuilt. + * aclocal.m4: Likewise. + * configure: Likewise. + * fficonfig.h.in: Likewise. + * testsuite/lib/libffi-dg.exp: Add include dir. + * testsuite/libffi.call/ffitest.h: Add MMAP definitions. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.call/closure_fn0.c: Use MMAP functionality + for ffi_closure if available. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + +2003-11-20 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional. + +2003-11-19 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin. + Add -lgcc_s to additional flags. + +2003-11-12 Andreas Tobler + + * configure.in, include/Makefile.am: PR libgcj/11147, install + the ffitarget.h header file in a gcc versioned and target + dependent place. + * configure: Regenerated. + * Makefile.in, include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + +2003-11-09 Andreas Tobler + + * testsuite/libffi.call/closure_fn0.c: Print result and check + with dg-output to make debugging easier. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + + * testsuite/libffi.special/unwindtest.cc: Make ffi_closure + static. + +2003-11-08 Andreas Tobler + + * testsuite/libffi.call/cls_9byte2.c: New test case. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + +2003-11-08 Andreas Tobler + + * testsuite/libffi.call/cls_double.c: Do a check on the result. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/return_sc.c: Cleanup whitespaces. + +2003-11-06 Andreas Tobler + + * src/prep_cif.c (ffi_prep_cif): Move the validity check after + the initialization. + +2003-10-23 Andreas Tobler + + * src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace + FFI_ASSERT(FALSE) with FFI_ASSERT(0). + +2003-10-22 David Daney + + * src/mips/ffitarget.h: Replace undefined UINT32 and friends with + __attribute__((__mode__(__SI__))) and friends. + +2003-10-22 Andreas Schwab + + * src/ia64/ffi.c: Replace FALSE/TRUE with false/true. + +2003-10-21 Andreas Tobler + + * configure.in: AC_LINK_FILES(ffitarget.h). + * configure: Regenerate. + * Makefile.in: Likewise. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * fficonfig.h.in: Likewise. + +2003-10-21 Paolo Bonzini + Richard Henderson + + Avoid that ffi.h includes fficonfig.h. + + * Makefile.am (EXTRA_DIST): Include ffitarget.h files + (TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. + (TARGET_SRC_MIPS_SGI): Removed. + (MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. + (MIPS_SGI): Removed. + (CLEANFILES): Removed. + (mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New + targets. + * acconfig.h: Removed. + * configure.in: Compute sizeofs only for double and long double. + Use them to define and subst HAVE_LONG_DOUBLE. Include comments + into AC_DEFINE instead of using acconfig.h. Create + include/ffitarget.h instead of include/fficonfig.h. Rename + MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree. + AC_DEFINE EH_FRAME_FLAGS. + * include/Makefile.am (DISTCLEANFILES): New automake macro. + (hack_DATA): Add ffitarget.h. + * include/ffi.h.in: Remove all system specific definitions. + Declare raw API even if it is not installed, why bother? + Use limits.h instead of SIZEOF_* to define ffi_type_*. Do + not define EH_FRAME_FLAGS, it is in fficonfig.h now. Include + ffitarget.h instead of fficonfig.h. Remove ALIGN macro. + (UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead. + * include/ffi_common.h (bool): Do not define. + (ffi_assert): Accept failed assertion. + (ffi_type_test): Return void and accept file/line. + (FFI_ASSERT): Pass stringized failed assertion. + (FFI_ASSERT_AT): New macro. + (FFI_ASSERT_VALID_TYPE): New macro. + (UINT8, SINT8, UINT16, SINT16, UINT32, SINT32, + UINT64, SINT64): Define here with gcc's __attribute__ macro + instead of in ffi.h + (FLOAT32, ALIGN): Define here instead of in ffi.h + * include/ffi-mips.h: Removed. Its content moved to + src/mips/ffitarget.h after separating assembly and C sections. + * src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c + src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c, + src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S, + src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c: + SIZEOF_ARG -> FFI_SIZEOF_ARG. + * src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+). + * src/debug.c (ffi_assert): Accept stringized failed assertion. + (ffi_type_test): Rewritten. + * src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call + FFI_ASSERT_VALID_TYPE. + * src/alpha/ffitarget.h, src/arm/ffitarget.h, + src/ia64/ffitarget.h, src/m68k/ffitarget.h, + src/mips/ffitarget.h, src/powerpc/ffitarget.h, + src/s390/ffitarget.h, src/sh/ffitarget.h, + src/sh64/ffitarget.h, src/sparc/ffitarget.h, + src/x86/ffitarget.h: New files. + * src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S, + src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S, + src/powerpc/aix.S, src/powerpc/darwin.S, + src/powerpc/ffi_darwin.c, src/powerpc/linux64.S, + src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S, + src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S, + src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S, + src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S: + include fficonfig.h + +2003-10-20 Rainer Orth + + * src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external + _MIPS_SIM_NABI32, _MIPS_SIM_ABI32. + +2003-10-19 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again. + Used when FFI_DEBUG = 1. + +2003-10-14 Alan Modra + + * src/types.c (double, longdouble): Default POWERPC64 to 8 byte size + and align. + +2003-10-06 Rainer Orth + + * include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs, + FFI_MIPS_O32 for O32 ABI. + +2003-10-01 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for + SPARC64. Cleanup whitespaces. + +2003-09-19 Andreas Tobler + + * testsuite/libffi.call/closure_fn0.c: Xfail mips, arm, + strongarm, xscale. Cleanup whitespaces. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + * testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces. + +2003-09-18 David Edelsohn + + * src/powerpc/aix.S: Cleanup whitespaces. + * src/powerpc/aix_closure.S: Likewise. + +2003-09-18 Andreas Tobler + + * src/powerpc/darwin.S: Cleanup whitespaces, comment formatting. + * src/powerpc/darwin_closure.S: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + +2003-09-18 Andreas Tobler + David Edelsohn + + * src/types.c (double): Add AIX and Darwin to the right TYPEDEF. + * src/powerpc/aix_closure.S: Remove the pointer to the outgoing + parameter stack. + * src/powerpc/darwin_closure.S: Likewise. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures + according to the Darwin/AIX ABI. + (ffi_prep_cif_machdep): Likewise. + (ffi_closure_helper_DARWIN): Likewise. + Remove the outgoing parameter stack logic. Simplify the evaluation + of the different CASE types. + (ffi_prep_clousure): Avoid the casts on lvalues. Change the branch + statement in the trampoline code. + +2003-09-18 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_args): Take account into the alignement + for the register size. + (ffi_closure_helper_SYSV): Handle the structure return value + address correctly. + (ffi_closure_helper_SYSV): Return the appropriate type when + the registers are used for the structure return value. + * src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for + the 64-bit return value. Update copyright years. + +2003-09-17 Rainer Orth + + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in + srcdir for ffi_mips.h. + +2003-09-12 Alan Modra + + * src/prep_cif.c (initialize_aggregate): Include tail padding in + structure size. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct + placement of float result. + * testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct + cast of "resp" for big-endian 64 bit machines. + +2003-09-11 Alan Modra + + * src/types.c (double, longdouble): Merge identical SH and ARM + typedefs, and add POWERPC64. + * src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for + struct split over gpr and rest. + (ffi_prep_cif_machdep): Correct intarg_count for structures. + * src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets. + +2003-09-09 Andreas Tobler + + * src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct + passing correctly. + +2003-09-09 Alan Modra + + * configure: Regenerate. + +2003-09-04 Andreas Tobler + + * Makefile.am: Remove build rules for ffitest. + * Makefile.in: Rebuilt. + +2003-09-04 Andreas Tobler + + * src/java_raw_api.c: Include to fix compiler warning + about implicit declaration of abort(). + +2003-09-04 Andreas Tobler + + * Makefile.am: Add dejagnu test framework. Fixes PR other/11411. + * Makefile.in: Rebuilt. + * configure.in: Add dejagnu test framework. + * configure: Rebuilt. + + * testsuite/Makefile.am: New file. + * testsuite/Makefile.in: Built + * testsuite/lib/libffi-dg.exp: New file. + * testsuite/config/default.exp: Likewise. + * testsuite/libffi.call/call.exp: Likewise. + * testsuite/libffi.call/ffitest.h: Likewise. + * testsuite/libffi.call/closure_fn0.c: Likewise. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/float.c: Likewise. + * testsuite/libffi.call/float1.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + * testsuite/libffi.call/many.c: Likewise. + * testsuite/libffi.call/many_win32.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/pyobjc-tc.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/return_ll.c: Likewise. + * testsuite/libffi.call/return_sc.c: Likewise. + * testsuite/libffi.call/return_uc.c: Likewise. + * testsuite/libffi.call/strlen.c: Likewise. + * testsuite/libffi.call/strlen_win32.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + * testsuite/libffi.call/struct2.c: Likewise. + * testsuite/libffi.call/struct3.c: Likewise. + * testsuite/libffi.call/struct4.c: Likewise. + * testsuite/libffi.call/struct5.c: Likewise. + * testsuite/libffi.call/struct6.c: Likewise. + * testsuite/libffi.call/struct7.c: Likewise. + * testsuite/libffi.call/struct8.c: Likewise. + * testsuite/libffi.call/struct9.c: Likewise. + * testsuite/libffi.special/special.exp: New file. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + + +2003-08-13 Kaz Kojima + + * src/sh/ffi.c (OFS_INT16): Set 0 for little endian case. Update + copyright years. + +2003-08-02 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc + structure passing. + (ffi_closure_helper_LINUX64): Likewise. + * src/powerpc/linux64.S: Remove code writing to parm save area. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return + address in lr from ffi_closure_helper_LINUX64 call to calculate + table address. Optimize function tail. + +2003-07-28 Andreas Tobler + + * src/sparc/ffi.c: Handle all floating point registers. + * src/sparc/v9.S: Likewise. Fixes second part of PR target/11410. + +2003-07-11 Gerald Pfeifer + + * README: Note that libffi is not part of GCC. Update the project + URL and status. + +2003-06-19 Franz Sirl + + * src/powerpc/ppc_closure.S: Include ffi.h. + +2003-06-13 Rainer Orth + + * src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives. + Use C style comments. + +2003-06-13 Kaz Kojima + + * Makefile.am: Add SHmedia support. Fix a typo of SH support. + * Makefile.in: Regenerate. + * configure.in (sh64-*-linux*, sh5*-*-linux*): Add target. + * configure: Regenerate. + * include/ffi.h.in: Add SHmedia support. + * src/sh64/ffi.c: New file. + * src/sh64/sysv.S: New file. + +2003-05-16 Jakub Jelinek + + * configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section + should be read-only. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + * include/ffi.h.in (EH_FRAME_FLAGS): Define. + * src/alpha/osf.S: Use EH_FRAME_FLAGS. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. Include ffi.h. + * src/powerpc/sysv.S: Use EH_FRAME_FLAGS. Use pcrel encoding + if -fpic/-fPIC/-mrelocatable. + * src/powerpc/powerpc_closure.S: Likewise. + * src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include + #write in .eh_frame flags. + * src/sparc/v9.S: Likewise. + * src/x86/unix64.S: Use EH_FRAME_FLAGS. + * src/x86/sysv.S: Likewise. Use pcrel encoding if -fpic/-fPIC. + * src/s390/sysv.S: Use EH_FRAME_FLAGS. Include ffi.h. + +2003-05-07 Jeff Sturm + + Fixes PR bootstrap/10656 + * configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler + support for .register pseudo-op. + * src/sparc/v8.S: Use it. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + +2003-04-18 Jakub Jelinek + + * include/ffi.h.in (POWERPC64): Define if 64-bit. + (enum ffi_abi): Add FFI_LINUX64 on POWERPC. + Make it the default on POWERPC64. + (FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64. + * configure.in: Change powerpc-*-linux* into powerpc*-*-linux*. + * configure: Rebuilt. + * src/powerpc/ffi.c (hidden): Define. + (ffi_prep_args_SYSV): Renamed from + ffi_prep_args. Cast pointers to unsigned long to shut up warnings. + (NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64, + ASM_NEEDS_REGISTERS64): New. + (ffi_prep_args64): New function. + (ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI. + (ffi_call): Likewise. + (ffi_prep_closure): Likewise. + (flush_icache): Surround by #ifndef POWERPC64. + (ffi_dblfl): New union type. + (ffi_closure_helper_SYSV): Use it to avoid aliasing problems. + (ffi_closure_helper_LINUX64): New function. + * src/powerpc/ppc_closure.S: Surround whole file by #ifndef + __powerpc64__. + * src/powerpc/sysv.S: Likewise. + (ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV. + * src/powerpc/linux64.S: New file. + * src/powerpc/linux64_closure.S: New file. + * Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and + src/powerpc/linux64_closure.S. + (TARGET_SRC_POWERPC): Likewise. + + * src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2, + closure_test_fn3): Fix result printing on big-endian 64-bit + machines. + (main): Print tst2_arg instead of uninitialized tst2_result. + + * src/ffitest.c (main): Hide what closure pointer really points to + from the compiler. + +2003-04-16 Richard Earnshaw + + * configure.in (arm-*-netbsdelf*): Add configuration. + (configure): Regenerated. + +2003-04-04 Loren J. Rittle + + * include/Makefile.in: Regenerate. + +2003-03-21 Zdenek Dvorak + + * libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32 + bit mode. + * libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): + Receive closure pointer through parameter, read args using + __builtin_dwarf_cfa. + (FFI_INIT_TRAMPOLINE): Send closure reference through eax. + +2003-03-12 Andreas Schwab + + * configure.in: Avoid trailing /. in toolexeclibdir. + * configure: Rebuilt. + +2003-03-03 Andreas Tobler + + * src/powerpc/darwin_closure.S: Recode to fit dynamic libraries. + +2003-02-06 Andreas Tobler + + * libffi/src/powerpc/darwin_closure.S: + Fix alignement bug, allocate 8 bytes for the result. + * libffi/src/powerpc/aix_closure.S: + Likewise. + * libffi/src/powerpc/ffi_darwin.c: + Update stackframe description for aix/darwin_closure.S. + +2003-02-06 Jakub Jelinek + + * src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility + attribute. + +2003-01-31 Christian Cornelssen , + Andreas Schwab + + * configure.in: Adjust command to source config-ml.in to account + for changes to the libffi_basedir definition. + (libffi_basedir): Remove ${srcdir} from value and include trailing + slash if nonempty. + + * configure: Regenerate. + +2003-01-29 Franz Sirl + + * src/powerpc/ppc_closure.S: Recode to fit shared libs. + +2003-01-28 Andrew Haley + + * include/ffi.h.in: Enable FFI_CLOSURES for x86_64. + * src/x86/ffi64.c (ffi_prep_closure): New. + (ffi_closure_UNIX64_inner): New. + * src/x86/unix64.S (ffi_closure_UNIX64): New. + +2003-01-27 Alexandre Oliva + + * configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST. + Remove USE_LIBDIR conditional. + * Makefile.am (toolexecdir, toolexeclibdir): Don't override. + * Makefile.in, configure: Rebuilt. + +2003-01027 David Edelsohn + + * Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo. + * Makefile.in: Regenerate. + +2003-01-22 Andrew Haley + + * src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to + unwind info. + +2003-01-21 Andreas Tobler + + * src/powerpc/darwin.S: Add unwind info. + * src/powerpc/darwin_closure.S: Likewise. + +2003-01-14 Andrew Haley + + * src/x86/ffi64.c (ffi_prep_args): Check for void retval. + (ffi_prep_cif_machdep): Likewise. + * src/x86/unix64.S: Add unwind info. + +2003-01-14 Andreas Jaeger + + * src/ffitest.c (main): Only use ffi_closures if those are + supported. + +2003-01-13 Andreas Tobler + + * libffi/src/ffitest.c + add closure testcases + +2003-01-13 Kevin B. Hendricks + + * libffi/src/powerpc/ffi.c + fix alignment bug for float (4 byte aligned iso 8 byte) + +2003-01-09 Geoffrey Keating + + * src/powerpc/ffi_darwin.c: Remove RCS version string. + * src/powerpc/darwin.S: Remove RCS version string. + +2003-01-03 Jeff Sturm + + * include/ffi.h.in: Add closure defines for SPARC, SPARC64. + * src/ffitest.c (main): Use static storage for closure. + * src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New. + * src/sparc/v8.S (ffi_closure_v8): New. + * src/sparc/v9.S (ffi_closure_v9): New. + +2002-11-10 Ranjit Mathew + + * include/ffi.h.in: Added FFI_STDCALL ffi_type + enumeration for X86_WIN32. + * src/x86/win32.S: Added ffi_call_STDCALL function + definition. + * src/x86/ffi.c (ffi_call/ffi_raw_call): Added + switch cases for recognising FFI_STDCALL and + calling ffi_call_STDCALL if target is X86_WIN32. + * src/ffitest.c (my_stdcall_strlen/stdcall_many): + stdcall versions of the "my_strlen" and "many" + test functions (for X86_WIN32). + Added test cases to test stdcall invocation using + these functions. + +2002-12-02 Kaz Kojima + + * src/sh/sysv.S: Add DWARF2 unwind info. + +2002-11-27 Ulrich Weigand + + * src/s390/sysv.S (.eh_frame section): Make section read-only. + +2002-11-26 Jim Wilson + + * src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64. + +2002-11-23 H.J. Lu + + * acinclude.m4: Add dummy AM_PROG_LIBTOOL. + Include ../config/accross.m4. + * aclocal.m4; Rebuild. + * configure: Likewise. + +2002-11-15 Ulrich Weigand + + * src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding. + +2002-11-11 DJ Delorie + + * configure.in: Look for common files in the right place. + +2002-10-08 Ulrich Weigand + + * src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret + raw data as _Jv_word values, not ffi_raw. + (ffi_java_ptrarray_to_raw): Likewise. + (ffi_java_rvalue_to_raw): New function. + (ffi_java_raw_call): Call it. + (ffi_java_raw_to_rvalue): New function. + (ffi_java_translate_args): Call it. + * src/ffitest.c (closure_test_fn): Interpret return value + as ffi_arg, not int. + * src/s390/ffi.c (ffi_prep_cif_machdep): Add missing + FFI_TYPE_POINTER case. + (ffi_closure_helper_SYSV): Likewise. Also, assume return + values extended to word size. + +2002-10-02 Andreas Jaeger + + * src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output. + +2002-10-01 Bo Thorsen + + * include/ffi.h.in: Fix i386 win32 compilation. + +2002-09-30 Ulrich Weigand + + * configure.in: Add s390x-*-linux-* target. + * configure: Regenerate. + * include/ffi.h.in: Define S390X for s390x targets. + (FFI_CLOSURES): Define for s390/s390x. + (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_NATIVE_RAW_API): Likewise. + * src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390. + * src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x. + * src/s390/ffi.c: Major rework of existing code. Add support for + s390x targets. Add closure support. + * src/s390/sysv.S: Likewise. + +2002-09-29 Richard Earnshaw + + * src/arm/sysv.S: Fix typo. + +2002-09-28 Richard Earnshaw + + * src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor + has defined __USER_LABEL_PREFIX__, then use it in CNAME. + (ffi_call_SYSV): Handle soft-float. + +2002-09-27 Bo Thorsen + + * include/ffi.h.in: Fix multilib x86-64 support. + +2002-09-22 Kaveh R. Ghazi + + * Makefile.am (all-multi): Fix multilib parallel build. + +2002-07-19 Kaz Kojima + + * configure.in (sh[34]*-*-linux*): Add brackets. + * configure: Regenerate. + +2002-07-18 Kaz Kojima + + * Makefile.am: Add SH support. + * Makefile.in: Regenerate. + * configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target. + * configure: Regenerate. + * include/ffi.h.in: Add SH support. + * src/sh/ffi.c: New file. + * src/sh/sysv.S: New file. + * src/types.c: Add SH support. + +2002-07-16 Bo Thorsen + + * src/x86/ffi64.c: New file that adds x86-64 support. + * src/x86/unix64.S: New file that handles argument setup for + x86-64. + * src/x86/sysv.S: Don't use this on x86-64. + * src/x86/ffi.c: Don't use this on x86-64. + Remove unused vars. + * src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation + for x86-64. + * src/ffitest.c (struct6): New test that tests a special case in + the x86-64 ABI. + (struct7): Likewise. + (struct8): Likewise. + (struct9): Likewise. + (closure_test_fn): Silence warning about this when it's not used. + (main): Add the new tests. + (main): Fix a couple of wrong casts and silence some compiler warnings. + * include/ffi.h.in: Add x86-64 ABI definition. + * fficonfig.h.in: Regenerate. + * Makefile.am: Add x86-64 support. + * configure.in: Likewise. + * Makefile.in: Regenerate. + * configure: Likewise. + +2002-06-24 Bo Thorsen + + * src/types.c: Merge settings for similar architectures. + Add x86-64 sizes and alignments. + +2002-06-23 Bo Thorsen + + * src/arm/ffi.c (ffi_prep_args): Remove unused vars. + * src/sparc/ffi.c (ffi_prep_args_v8): Likewise. + * src/mips/ffi.c (ffi_prep_args): Likewise. + * src/m68k/ffi.c (ffi_prep_args): Likewise. + +2002-07-18 H.J. Lu (hjl@gnu.org) + + * Makefile.am (TARGET_SRC_MIPS_LINUX): New. + (libffi_la_SOURCES): Support MIPS_LINUX. + (libffi_convenience_la_SOURCES): Likewise. + * Makefile.in: Regenerated. + + * configure.in (mips64*-*): Skip. + (mips*-*-linux*): New. + * configure: Regenerated. + + * src/mips/ffi.c: Include . + +2002-06-06 Ulrich Weigand + + * src/s390/sysv.S: Save/restore %r6. Add DWARF-2 unwind info. + +2002-05-27 Roger Sayle + + * src/x86/ffi.c (ffi_prep_args): Remove reference to avn. + +2002-05-27 Bo Thorsen + + * src/x86/ffi.c (ffi_prep_args): Remove unused variable and + fix formatting. + +2002-05-13 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at + beginning of function (for older apple cc). + +2002-05-08 Alexandre Oliva + + * configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at + script entry, and set LD to it when configuring multilibs. + * configure: Rebuilt. + +2002-05-05 Jason Thorpe + + * configure.in (sparc64-*-netbsd*): Add target. + (sparc-*-netbsdelf*): Likewise. + * configure: Regenerate. + +2002-04-28 David S. Miller + + * configure.in, configure: Fix SPARC test in previous change. + +2002-04-29 Gerhard Tonn + + * Makefile.am: Add Linux for S/390 support. + * Makefile.in: Regenerate. + * configure.in: Add Linux for S/390 support. + * configure: Regenerate. + * include/ffi.h.in: Add Linux for S/390 support. + * src/s390/ffi.c: New file from libffi CVS tree. + * src/s390/sysv.S: New file from libffi CVS tree. + +2002-04-28 Jakub Jelinek + + * configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working + %r_disp32(). + * src/sparc/v8.S: Use it. + * src/sparc/v9.S: Likewise. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + +2002-04-08 Hans Boehm + + * src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE + correctly. + * src/ia64/unix.S: Add unwind information. Fix comments. + Save sp in a way that's compatible with unwind info. + (ffi_call_unix): Correctly restore sp in all cases. + * src/ia64/ffi.c: Add, fix comments. + +2002-04-08 Jakub Jelinek + + * src/sparc/v8.S: Make .eh_frame dependent on target word size. + +2002-04-06 Jason Thorpe + + * configure.in (alpha*-*-netbsd*): Add target. + * configure: Regenerate. + +2002-04-04 Jeff Sturm + + * src/sparc/v8.S: Add unwind info. + * src/sparc/v9.S: Likewise. + +2002-03-30 Krister Walfridsson + + * configure.in: Enable i*86-*-netbsdelf*. + * configure: Rebuilt. + +2002-03-29 David Billinghurst + + PR other/2620 + * src/mips/n32.s: Delete + * src/mips/o32.s: Delete + +2002-03-21 Loren J. Rittle + + * configure.in: Enable alpha*-*-freebsd*. + * configure: Rebuilt. + +2002-03-17 Bryce McKinlay + + * Makefile.am: libfficonvenience -> libffi_convenience. + * Makefile.in: Rebuilt. + + * Makefile.am: Define ffitest_OBJECTS. + * Makefile.in: Rebuilt. + +2002-03-07 Andreas Tobler + David Edelsohn + + * Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files. + (TARGET_SRC_POWERPC_AIX): Add aix_closure.S. + (TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S. + * Makefile.in: Regenerate. + * include/ffi.h.in: Add AIX and Darwin closure definitions. + * src/powerpc/ffi_darwin.c (ffi_prep_closure): New function. + (flush_icache, flush_range): New functions. + (ffi_closure_helper_DARWIN): New function. + * src/powerpc/aix_closure.S: New file. + * src/powerpc/darwin_closure.S: New file. + +2002-02-24 Jeff Sturm + + * include/ffi.h.in: Add typedef for ffi_arg. + * src/ffitest.c (main): Declare rint with ffi_arg. + +2002-02-21 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate + number of GPRs for floating-point arguments. + +2002-01-31 Anthony Green + + * configure: Rebuilt. + * configure.in: Replace CHECK_SIZEOF and endian tests with + cross-compiler friendly macros. + * aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New + macros. + +2002-01-18 David Edelsohn + + * src/powerpc/darwin.S (_ffi_call_AIX): New. + * src/powerpc/aix.S (ffi_call_DARWIN): New. + +2002-01-17 David Edelsohn + + * Makefile.am (EXTRA_DIST): Add Darwin and AIX files. + (TARGET_SRC_POWERPC_AIX): New. + (POWERPC_AIX): New stanza. + * Makefile.in: Regenerate. + * configure.in: Add AIX case. + * configure: Regenerate. + * include/ffi.h.in (ffi_abi): Add FFI_AIX. + * src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame + size. Fix "long double" support. + (ffi_call): Add FFI_AIX case. + * src/powerpc/aix.S: New. + +2001-10-09 John Hornkvist + + Implement Darwin PowerPC ABI. + * configure.in: Handle powerpc-*-darwin*. + * Makefile.am: Set source files for POWERPC_DARWIN. + * configure: Rebuilt. + * Makefile.in: Rebuilt. + * include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for + POWERPC_DARWIN. + * src/powerpc/darwin.S: New file. + * src/powerpc/ffi_darwin.c: New file. + +2001-10-07 Joseph S. Myers + + * src/x86/ffi.c: Fix spelling error of "separate" as "seperate". + +2001-07-16 Rainer Orth + + * src/x86/sysv.S: Avoid gas-only .balign directive. + Use C style comments. + +2001-07-16 Rainer Orth + + * src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic. + Fixes PR bootstrap/3563. + +2001-06-26 Rainer Orth + + * src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF. + +2001-06-25 Rainer Orth + + * configure.in: Recognize sparc*-sun-* host. + * configure: Regenerate. + +2001-06-06 Andrew Haley + + * src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF. + +2001-06-03 Andrew Haley + + * src/alpha/osf.S: Add unwind info. + * src/powerpc/sysv.S: Add unwind info. + * src/powerpc/ppc_closure.S: Likewise. + +2000-05-31 Jeff Sturm + + * configure.in: Fix AC_ARG_ENABLE usage. + * configure: Rebuilt. + +2001-05-06 Bryce McKinlay + + * configure.in: Remove warning about beta code. + * configure: Rebuilt. + +2001-04-25 Hans Boehm + + * src/ia64/unix.S: Restore stack pointer when returning from + ffi_closure_UNIX. + * src/ia64/ffi.c: Fix typo in comment. + +2001-04-18 Jim Wilson + + * src/ia64/unix.S: Delete unnecessary increment and decrement of loc2 + to eliminate RAW DV. + +2001-04-12 Bryce McKinlay + + * Makefile.am: Make a libtool convenience library. + * Makefile.in: Rebuilt. + +2001-03-29 Bryce McKinlay + + * configure.in: Use different syntax for subdirectory creation. + * configure: Rebuilt. + +2001-03-27 Jon Beniston + + * configure.in: Added X86_WIN32 target (Win32, CygWin, MingW). + * configure: Rebuilt. + * Makefile.am: Added X86_WIN32 target support. + * Makefile.in: Rebuilt. + + * include/ffi.h.in: Added X86_WIN32 target support. + + * src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets. + * src/types.c: Added X86_WIN32 target support. + + * src/x86/win32.S: New file. Based on sysv.S, but with EH + stuff removed and made to work with CygWin's gas. + +2001-03-26 Bryce McKinlay + + * configure.in: Make target subdirectory in build dir. + * Makefile.am: Override suffix based rules to specify correct output + subdirectory. + * Makefile.in: Rebuilt. + * configure: Rebuilt. + +2001-03-23 Kevin B Hendricks + + * src/powerpc/ppc_closure.S: New file. + * src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug + involving long long and register pairs. + (ffi_prep_closure): New function. + (flush_icache): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * include/ffi.h.in (FFI_CLOSURES): Define on PPC. + (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_NATIVE_RAW_API): Likewise. + * Makefile.in: Rebuilt. + * Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S. + (TARGET_SRC_POWERPC): Likewise. + +2001-03-19 Tom Tromey + + * Makefile.in: Rebuilt. + * Makefile.am (ffitest_LDFLAGS): New macro. + +2001-03-02 Nick Clifton + + * include/ffi.h.in: Remove RCS ident string. + * include/ffi_mips.h: Remove RCS ident string. + * src/debug.c: Remove RCS ident string. + * src/ffitest.c: Remove RCS ident string. + * src/prep_cif.c: Remove RCS ident string. + * src/types.c: Remove RCS ident string. + * src/alpha/ffi.c: Remove RCS ident string. + * src/alpha/osf.S: Remove RCS ident string. + * src/arm/ffi.c: Remove RCS ident string. + * src/arm/sysv.S: Remove RCS ident string. + * src/mips/ffi.c: Remove RCS ident string. + * src/mips/n32.S: Remove RCS ident string. + * src/mips/o32.S: Remove RCS ident string. + * src/sparc/ffi.c: Remove RCS ident string. + * src/sparc/v8.S: Remove RCS ident string. + * src/sparc/v9.S: Remove RCS ident string. + * src/x86/ffi.c: Remove RCS ident string. + * src/x86/sysv.S: Remove RCS ident string. + +2001-02-08 Joseph S. Myers + + * include/ffi.h.in: Change sourceware.cygnus.com references to + gcc.gnu.org. + +2000-12-09 Richard Henderson + + * src/alpha/ffi.c (ffi_call): Simplify struct return test. + (ffi_closure_osf_inner): Index rather than increment avalue + and arg_types. Give ffi_closure_osf the raw return value type. + * src/alpha/osf.S (ffi_closure_osf): Handle return value type + promotion. + +2000-12-07 Richard Henderson + + * src/raw_api.c (ffi_translate_args): Fix typo. + (ffi_prep_closure): Likewise. + + * include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and + FFI_TRAMPOLINE_SIZE. + * src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal + cif->bytes for new ffi_call_osf implementation. + (ffi_prep_args): Absorb into ... + (ffi_call): ... here. Do all stack allocation here and + avoid a callback function. + (ffi_prep_closure, ffi_closure_osf_inner): New. + * src/alpha/osf.S (ffi_call_osf): Reimplement with no callback. + (ffi_closure_osf): New. + +2000-09-10 Alexandre Oliva + + * config.guess, config.sub, install-sh: Removed. + * ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise. + * Makefile.in: Rebuilt. + + * acinclude.m4: Include libtool macros from the top level. + * aclocal.m4, configure: Rebuilt. + +2000-08-22 Alexandre Oliva + + * configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set. + * configure: Rebuilt. + +2000-05-11 Scott Bambrough + + * libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to + memory correctly. Use conditional instructions, not branches where + possible. + +2000-05-04 Tom Tromey + + * configure: Rebuilt. + * configure.in: Match `arm*-*-linux-*'. + From Chris Dornan . + +2000-04-28 Jakub Jelinek + + * Makefile.am (SUBDIRS): Define. + (AM_MAKEFLAGS): Likewise. + (Multilib support.): Add section. + * Makefile.in: Rebuilt. + * ltconfig (extra_compiler_flags, extra_compiler_flags_value): + New variables. Set for gcc using -print-multi-lib. Export them + to libtool. + (sparc64-*-linux-gnu*): Use libsuff 64 for search paths. + * ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options + for -shared links. + (extra_compiler_flags_value, extra_compiler_flags): Check these + for extra compiler options which need to be passed down in + compiler_flags. + +2000-04-16 Anthony Green + + * configure: Rebuilt. + * configure.in: Change i*86-pc-linux* to i*86-*-linux*. + +2000-04-14 Jakub Jelinek + + * include/ffi.h.in (SPARC64): Define for 64bit SPARC builds. + Set SPARC FFI_DEFAULT_ABI based on SPARC64 define. + * src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args. + Replace all void * sizeofs with sizeof(int). + Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is + different than DOUBLE. + Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere). + (ffi_prep_args_v9): New function. + (ffi_prep_cif_machdep): Handle V9 ABI and long long on V8. + (ffi_V9_return_struct): New function. + (ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from + 32bit code (not yet cross-arch calls). + * src/sparc/v8.S: Add struct return delay nop. + Handle long long. + * src/sparc/v9.S: New file. + * src/prep_cif.c (ffi_prep_cif): Return structure pointer + is used on sparc64 only for structures larger than 32 bytes. + Pass by reference for structures is done for structure arguments + larger than 16 bytes. + * src/ffitest.c (main): Use 64bit rint on sparc64. + Run long long tests on sparc. + * src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and + sparc64. + (FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits + on sparc64. + * configure.in (sparc-*-linux*): New supported target. + (sparc64-*-linux*): Likewise. + * configure: Rebuilt. + * Makefile.am: Add v9.S to SPARC files. + * Makefile.in: Likewise. + (LINK): Surround $(CCLD) into double quotes, so that multilib + compiles work correctly. + +2000-04-04 Alexandre Petit-Bianco + + * configure: Rebuilt. + * configure.in: (i*86-*-solaris*): New libffi target. Patch + proposed by Bryce McKinlay. + +2000-03-20 Tom Tromey + + * Makefile.in: Hand edit for java_raw_api.lo. + +2000-03-08 Bryce McKinlay + + * config.guess, config.sub: Update from the gcc tree. + Fix for PR libgcj/168. + +2000-03-03 Tom Tromey + + * Makefile.in: Fixed ia64 by hand. + + * configure: Rebuilt. + * configure.in (--enable-multilib): New option. + (libffi_basedir): New subst. + (AC_OUTPUT): Added multilib code. + +2000-03-02 Tom Tromey + + * Makefile.in: Rebuilt. + * Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as + directory name. + +2000-02-25 Hans Boehm + + * src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New + files. + * src/raw_api.c (ffi_translate_args): Fixed typo in argument + list. + (ffi_prep_raw_closure): Use ffi_translate_args, not + ffi_closure_translate. + * src/java_raw_api.c: New file. + * src/ffitest.c (closure_test_fn): New function. + (main): Define `rint' as long long on IA64. Added new test when + FFI_CLOSURES is defined. + * include/ffi.h.in (ALIGN): Use size_t, not unsigned. + (ffi_abi): Recognize IA64. + (ffi_raw): Added `flt' field. + Added "Java raw API" code. + * configure.in: Recognize ia64. + * Makefile.am (TARGET_SRC_IA64): New macro. + (libffi_la_common_SOURCES): Added java_raw_api.c. + (libffi_la_SOURCES): Define in IA64 case. + +2000-01-04 Tom Tromey + + * Makefile.in: Rebuilt with newer automake. + +1999-12-31 Tom Tromey + + * Makefile.am (INCLUDES): Added -I$(top_srcdir)/src. + +1999-09-01 Tom Tromey + + * include/ffi.h.in: Removed PACKAGE and VERSION defines and + undefs. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + * configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE. + Use AM_PROG_LIBTOOL (automake 1.4 compatibility). + * acconfig.h: Don't #undef PACKAGE or VERSION. + +1999-08-09 Anthony Green + + * include/ffi.h.in: Try to work around messy header problem + with PACKAGE and VERSION. + + * configure: Rebuilt. + * configure.in: Change version to 2.00-beta. + + * fficonfig.h.in: Rebuilt. + * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define. + + * src/x86/ffi.c (ffi_raw_call): Rename. + +1999-08-02 Kresten Krab Thorup + + * src/x86/ffi.c (ffi_closure_SYSV): New function. + (ffi_prep_incoming_args_SYSV): Ditto. + (ffi_prep_closure): Ditto. + (ffi_closure_raw_SYSV): Ditto. + (ffi_prep_raw_closure): More ditto. + (ffi_call_raw): Final ditto. + + * include/ffi.h.in: Add definitions for closure and raw API. + + * src/x86/ffi.c (ffi_prep_cif_machdep): Added case for + FFI_TYPE_UINT64. + + * Makefile.am (libffi_la_common_SOURCES): Added raw_api.c + + * src/raw_api.c: New file. + + * include/ffi.h.in (ffi_raw): New type. + (UINT_ARG, SINT_ARG): New defines. + (ffi_closure, ffi_raw_closure): New types. + (ffi_prep_closure, ffi_prep_raw_closure): New declarations. + + * configure.in: Add check for endianness and sizeof void*. + + * src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument, + instead of directly. + + * configure: Rebuilt. + +Thu Jul 8 14:28:42 1999 Anthony Green + + * configure.in: Add x86 and powerpc BeOS configurations. + From Makoto Kato . + +1999-05-09 Anthony Green + + * configure.in: Add warning about this being beta code. + Remove src/Makefile.am from the picture. + * configure: Rebuilt. + + * Makefile.am: Move logic from src/Makefile.am. Add changes + to support libffi as a target library. + * Makefile.in: Rebuilt. + + * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh: + Upgraded to new autoconf, automake, libtool. + + * README: Tweaks. + + * LICENSE: Update copyright date. + + * src/Makefile.am, src/Makefile.in: Removed. + +1998-11-29 Anthony Green + + * include/ChangeLog: Removed. + * src/ChangeLog: Removed. + * src/mips/ChangeLog: Removed. + * src/sparc/ChangeLog: Remboved. + * src/x86/ChangeLog: Removed. + + * ChangeLog.v1: Created. diff --git a/circuitpython/lib/libffi/ChangeLog.libgcj b/circuitpython/lib/libffi/ChangeLog.libgcj new file mode 100644 index 0000000..ea5d02f --- /dev/null +++ b/circuitpython/lib/libffi/ChangeLog.libgcj @@ -0,0 +1,40 @@ +2004-01-14 Kelley Cook + + * configure.in: Add in AC_PREREQ(2.13) + +2003-02-20 Alexandre Oliva + + * configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to + config.status. + * configure: Rebuilt. + +2002-01-27 Alexandre Oliva + + * configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST. + Remove USE_LIBDIR conditional. + * Makefile.am (toolexecdir, toolexeclibdir): Don't override. + * Makefile.in, configure: Rebuilt. + +Mon Aug 9 18:33:38 1999 Rainer Orth + + * include/Makefile.in: Rebuilt. + * Makefile.in: Rebuilt + * Makefile.am (toolexeclibdir): Add $(MULTISUBDIR) even for native + builds. + Use USE_LIBDIR. + + * configure: Rebuilt. + * configure.in (USE_LIBDIR): Define for native builds. + Use lowercase in configure --help explanations. + +1999-08-08 Anthony Green + + * include/ffi.h.in (FFI_FN): Remove `...'. + +1999-08-08 Anthony Green + + * Makefile.in: Rebuilt. + * Makefile.am (AM_CFLAGS): Compile with -fexceptions. + + * src/x86/sysv.S: Add exception handling metadata. + diff --git a/circuitpython/lib/libffi/ChangeLog.v1 b/circuitpython/lib/libffi/ChangeLog.v1 new file mode 100644 index 0000000..af3a377 --- /dev/null +++ b/circuitpython/lib/libffi/ChangeLog.v1 @@ -0,0 +1,764 @@ +The libffi version 1 ChangeLog archive. + +Version 1 of libffi had per-directory ChangeLogs. Current and future +versions have a single ChangeLog file in the root directory. The +version 1 ChangeLogs have all been concatenated into this file for +future reference only. + +--- libffi ---------------------------------------------------------------- + +Mon Oct 5 02:17:50 1998 Anthony Green + + * configure.in: Boosted rev. + * configure, Makefile.in, aclocal.m4: Rebuilt. + * README: Boosted rev and updated release notes. + +Mon Oct 5 01:03:03 1998 Anthony Green + + * configure.in: Boosted rev. + * configure, Makefile.in, aclocal.m4: Rebuilt. + * README: Boosted rev and updated release notes. + +1998-07-25 Andreas Schwab + + * m68k/ffi.c (ffi_prep_cif_machdep): Use bitmask for cif->flags. + Correctly handle small structures. + (ffi_prep_args): Also handle small structures. + (ffi_call): Pass size of return type to ffi_call_SYSV. + * m68k/sysv.S: Adjust for above changes. Correctly align small + structures in the return value. + + * types.c (uint64, sint64) [M68K]: Change alignment to 4. + +Fri Apr 17 17:26:58 1998 Anthony Green + + * configure.in: Boosted rev. + * configure,Makefile.in,aclocal.m4: Rebuilt. + * README: Boosted rev and added release notes. + +Sun Feb 22 00:50:41 1998 Geoff Keating + + * configure.in: Add PowerPC config bits. + +1998-02-14 Andreas Schwab + + * configure.in: Add m68k config bits. Change AC_CANONICAL_SYSTEM + to AC_CANONICAL_HOST, this is not a compiler. Use $host instead + of $target. Remove AC_CHECK_SIZEOF(char), we already know the + result. Fix argument of AC_ARG_ENABLE. + * configure, fficonfig.h.in: Rebuilt. + +Tue Feb 10 20:53:40 1998 Richard Henderson + + * configure.in: Add Alpha config bits. + +Tue May 13 13:39:20 1997 Anthony Green + + * README: Updated dates and reworded Irix comments. + + * configure.in: Removed AC_PROG_RANLIB. + + * Makefile.in, aclocal.m4, config.guess, config.sub, configure, + ltmain.sh, */Makefile.in: libtoolized again and rebuilt with + automake and autoconf. + +Sat May 10 18:44:50 1997 Tom Tromey + + * configure, aclocal.m4: Rebuilt. + * configure.in: Don't compute EXTRADIST; now handled in + src/Makefile.in. Removed macros implied by AM_INIT_AUTOMAKE. + Don't run AM_MAINTAINER_MODE. + +Thu May 8 14:34:05 1997 Anthony Green + + * missing, ltmain.sh, ltconfig.sh: Created. These are new files + required by automake and libtool. + + * README: Boosted rev to 1.14. Added notes. + + * acconfig.h: Moved PACKAGE and VERSION for new automake. + + * configure.in: Changes for libtool. + + * Makefile.am (check): make test now make check. Uses libtool now. + + * Makefile.in, configure.in, aclocal.h, fficonfig.h.in: Rebuilt. + +Thu May 1 16:27:07 1997 Anthony Green + + * missing: Added file required by new automake. + +Tue Nov 26 14:10:42 1996 Anthony Green + + * acconfig.h: Added USING_PURIFY flag. This is defined when + --enable-purify-safety was used at configure time. + + * configure.in (allsources): Added --enable-purify-safety switch. + (VERSION): Boosted rev to 1.13. + * configure: Rebuilt. + +Fri Nov 22 06:46:12 1996 Anthony Green + + * configure.in (VERSION): Boosted rev to 1.12. + Removed special CFLAGS hack for gcc. + * configure: Rebuilt. + + * README: Boosted rev to 1.12. Added notes. + + * Many files: Cygnus Support changed to Cygnus Solutions. + +Wed Oct 30 11:15:25 1996 Anthony Green + + * configure.in (VERSION): Boosted rev to 1.11. + * configure: Rebuilt. + + * README: Boosted rev to 1.11. Added notes about GNU make. + +Tue Oct 29 12:25:12 1996 Anthony Green + + * configure.in: Fixed -Wall trick. + (VERSION): Boosted rev. + * configure: Rebuilt + + * acconfig.h: Needed for --enable-debug configure switch. + + * README: Boosted rev to 1.09. Added more notes on building + libffi, and LCLint. + + * configure.in: Added --enable-debug switch. Boosted rev to + 1.09. + * configure: Rebuilt + +Tue Oct 15 13:11:28 1996 Anthony Green + + * configure.in (VERSION): Boosted rev to 1.08 + * configure: Rebuilt. + + * README: Added n32 bug fix notes. + + * Makefile.am: Added "make lint" production. + * Makefile.in: Rebuilt. + +Mon Oct 14 10:54:46 1996 Anthony Green + + * README: Added web page reference. + + * configure.in, README: Boosted rev to 1.05 + * configure: Rebuilt. + + * README: Fixed n32 sample code. + +Fri Oct 11 17:09:28 1996 Anthony Green + + * README: Added sparc notes. + + * configure.in, README: Boosted rev to 1.04. + * configure: Rebuilt. + +Thu Oct 10 10:31:03 1996 Anthony Green + + * configure.in, README: Boosted rev to 1.03. + * configure: Rebuilt. + + * README: Added struct notes. + + * Makefile.am (EXTRA_DIST): Added LICENSE to distribution. + * Makefile.in: Rebuilt. + + * README: Removed Linux section. No special notes now + because aggregates arg/return types work. + +Wed Oct 9 16:16:42 1996 Anthony Green + + * README, configure.in (VERSION): Boosted rev to 1.02 + * configure: Rebuilt. + +Tue Oct 8 11:56:33 1996 Anthony Green + + * README (NOTE): Added n32 notes. + + * Makefile.am: Added test production. + * Makefile: Rebuilt + + * README: spell checked! + + * configure.in (VERSION): Boosted rev to 1.01 + * configure: Rebuilt. + +Mon Oct 7 15:50:22 1996 Anthony Green + + * configure.in: Added nasty bit to support SGI tools. + * configure: Rebuilt. + + * README: Added SGI notes. Added note about automake bug. + +Mon Oct 7 11:00:28 1996 Anthony Green + + * README: Rewrote intro, and fixed examples. + +Fri Oct 4 10:19:55 1996 Anthony Green + + * configure.in: -D$TARGET is no longer used as a compiler switch. + It is now inserted into ffi.h at configure time. + * configure: Rebuilt. + + * FFI_ABI and FFI_STATUS are now ffi_abi and ffi_status. + +Thu Oct 3 13:47:34 1996 Anthony Green + + * README, LICENSE: Created. Wrote some docs. + + * configure.in: Don't barf on i586-unknown-linuxaout. + Added EXTRADIST code for "make dist". + * configure: Rebuilt. + + * */Makefile.in: Rebuilt with patched automake. + +Tue Oct 1 17:12:25 1996 Anthony Green + + * Makefile.am, aclocal.m4, config.guess, config.sub, + configure.in, fficonfig.h.in, install-sh, mkinstalldirs, + stamp-h.in: Created + * Makefile.in, configure: Generated + +--- libffi/include -------------------------------------------------------- + +Tue Feb 24 13:09:36 1998 Anthony Green + + * ffi_mips.h: Updated FFI_TYPE_STRUCT_* values based on + ffi.h.in changes. This is a work-around for SGI's "simple" + assembler. + +Sun Feb 22 00:51:55 1998 Geoff Keating + + * ffi.h.in: PowerPC support. + +1998-02-14 Andreas Schwab + + * ffi.h.in: Add m68k support. + (FFI_TYPE_LONGDOUBLE): Make it a separate value. + +Tue Feb 10 20:55:16 1998 Richard Henderson + + * ffi.h.in (SIZEOF_ARG): Use a pointer type by default. + + * ffi.h.in: Alpha support. + +Fri Nov 22 06:48:45 1996 Anthony Green + + * ffi.h.in, ffi_common.h: Cygnus Support -> Cygnus Solutions. + +Wed Nov 20 22:31:01 1996 Anthony Green + + * ffi.h.in: Added ffi_type_void definition. + +Tue Oct 29 12:22:40 1996 Anthony Green + + * Makefile.am (hack_DATA): Always install ffi_mips.h. + + * ffi.h.in: Removed FFI_DEBUG. It's now in the correct + place (acconfig.h). + Added #include for size_t definition. + +Tue Oct 15 17:23:35 1996 Anthony Green + + * ffi.h.in, ffi_common.h, ffi_mips.h: More clean up. + Commented out #define of FFI_DEBUG. + +Tue Oct 15 13:01:06 1996 Anthony Green + + * ffi_common.h: Added bool definition. + + * ffi.h.in, ffi_common.h: Clean up based on LCLint output. + Added funny /*@...@*/ comments to annotate source. + +Mon Oct 14 12:29:23 1996 Anthony Green + + * ffi.h.in: Interface changes based on feedback from Jim + Blandy. + +Fri Oct 11 16:49:35 1996 Anthony Green + + * ffi.h.in: Small change for sparc support. + +Thu Oct 10 14:53:37 1996 Anthony Green + + * ffi_mips.h: Added FFI_TYPE_STRUCT_* definitions for + special structure return types. + +Wed Oct 9 13:55:57 1996 Anthony Green + + * ffi.h.in: Added SIZEOF_ARG definition for X86 + +Tue Oct 8 11:40:36 1996 Anthony Green + + * ffi.h.in (FFI_FN): Added macro for eliminating compiler warnings. + Use it to case your function pointers to the proper type. + + * ffi_mips.h (SIZEOF_ARG): Added magic to fix type promotion bug. + + * Makefile.am (EXTRA_DIST): Added ffi_mips.h to EXTRA_DIST. + * Makefile: Rebuilt. + + * ffi_mips.h: Created. Moved all common mips definitions here. + +Mon Oct 7 10:58:12 1996 Anthony Green + + * ffi.h.in: The SGI assember is very picky about parens. Redefined + some macros to avoid problems. + + * ffi.h.in: Added FFI_DEFAULT_ABI definitions. Also added + externs for pointer, and 64bit integral ffi_types. + +Fri Oct 4 09:51:37 1996 Anthony Green + + * ffi.h.in: Added FFI_ABI member to ffi_cif and changed + function prototypes accordingly. + Added #define @TARGET@. Now programs including ffi.h don't + have to specify this themselves. + +Thu Oct 3 15:36:44 1996 Anthony Green + + * ffi.h.in: Changed ffi_prep_cif's values from void* to void** + + * Makefile.am (EXTRA_DIST): Added EXTRA_DIST for "make dist" + to work. + * Makefile.in: Regenerated. + +Wed Oct 2 10:16:59 1996 Anthony Green + + * Makefile.am: Created + * Makefile.in: Generated + + * ffi_common.h: Added rcsid comment + +Tue Oct 1 17:13:51 1996 Anthony Green + + * ffi.h.in, ffi_common.h: Created + +--- libffi/src ------------------------------------------------------------ + +Mon Oct 5 02:17:50 1998 Anthony Green + + * arm/ffi.c, arm/sysv.S: Created. + + * Makefile.am: Added arm files. + * Makefile.in: Rebuilt. + +Mon Oct 5 01:41:38 1998 Anthony Green + + * Makefile.am (libffi_la_LDFLAGS): Incremented revision. + +Sun Oct 4 16:27:17 1998 Anthony Green + + * alpha/osf.S (ffi_call_osf): Patch for DU assembler. + + * ffitest.c (main): long long and long double return values work + for x86. + +Fri Apr 17 11:50:58 1998 Anthony Green + + * Makefile.in: Rebuilt. + + * ffitest.c (main): Floating point tests not executed for systems + with broken lond double (SunOS 4 w/ GCC). + + * types.c: Fixed x86 alignment info for long long types. + +Thu Apr 16 07:15:28 1998 Anthony Green + + * ffitest.c: Added more notes about GCC bugs under Irix 6. + +Wed Apr 15 08:42:22 1998 Anthony Green + + * ffitest.c (struct5): New test function. + (main): New test with struct5. + +Thu Mar 5 10:48:11 1998 Anthony Green + + * prep_cif.c (initialize_aggregate): Fix assertion for + nested structures. + +Tue Feb 24 16:33:41 1998 Anthony Green + + * prep_cif.c (ffi_prep_cif): Added long double support for sparc. + +Sun Feb 22 00:52:18 1998 Geoff Keating + + * powerpc/asm.h: New file. + * powerpc/ffi.c: New file. + * powerpc/sysv.S: New file. + * Makefile.am: PowerPC port. + * ffitest.c (main): Allow all tests to run even in presence of gcc + bug on PowerPC. + +1998-02-17 Anthony Green + + * mips/ffi.c: Fixed comment typo. + + * x86/ffi.c (ffi_prep_cif_machdep), x86/sysv.S (retfloat): + Fixed x86 long double return handling. + + * types.c: Fixed x86 long double alignment info. + +1998-02-14 Andreas Schwab + + * types.c: Add m68k support. + + * ffitest.c (floating): Add long double parameter. + (return_ll, ldblit): New functions to test long long and long + double return value. + (main): Fix type error in assignment of ts[1-4]_type.elements. + Add tests for long long and long double arguments and return + values. + + * prep_cif.c (ffi_prep_cif) [M68K]: Don't allocate argument for + struct value pointer. + + * m68k/ffi.c, m68k/sysv.S: New files. + * Makefile.am: Add bits for m68k port. Add kludge to work around + automake deficiency. + (test): Don't require "." in $PATH. + * Makefile.in: Rebuilt. + +Wed Feb 11 07:36:50 1998 Anthony Green + + * Makefile.in: Rebuilt. + +Tue Feb 10 20:56:00 1998 Richard Henderson + + * alpha/ffi.c, alpha/osf.S: New files. + * Makefile.am: Alpha port. + +Tue Nov 18 14:12:07 1997 Anthony Green + + * mips/ffi.c (ffi_prep_cif_machdep): Initialize rstruct_flag + for n32. + +Tue Jun 3 17:18:20 1997 Anthony Green + + * ffitest.c (main): Added hack to get structure tests working + correctly. + +Sat May 10 19:06:42 1997 Tom Tromey + + * Makefile.in: Rebuilt. + * Makefile.am (EXTRA_DIST): Explicitly list all distributable + files in subdirs. + (VERSION, CC): Removed. + +Thu May 8 17:19:01 1997 Anthony Green + + * Makefile.am: Many changes for new automake and libtool. + * Makefile.in: Rebuilt. + +Fri Nov 22 06:57:56 1996 Anthony Green + + * ffitest.c (main): Fixed test case for non mips machines. + +Wed Nov 20 22:31:59 1996 Anthony Green + + * types.c: Added ffi_type_void declaration. + +Tue Oct 29 13:07:19 1996 Anthony Green + + * ffitest.c (main): Fixed character constants. + (main): Emit warning for structure test 3 failure on Sun. + + * Makefile.am (VPATH): Fixed VPATH def'n so automake won't + strip it out. + Moved distdir hack from libffi to automake. + (ffitest): Added missing -c for $(COMPILE) (change in automake). + * Makefile.in: Rebuilt. + +Tue Oct 15 13:08:20 1996 Anthony Green + + * Makefile.am: Added "make lint" production. + * Makefile.in: Rebuilt. + + * prep_cif.c (STACK_ARG_SIZE): Improved STACK_ARG_SIZE macro. + Clean up based on LCLint output. Added funny /*@...@*/ comments to + annotate source. + + * ffitest.c, debug.c: Cleaned up code. + +Mon Oct 14 12:26:56 1996 Anthony Green + + * ffitest.c: Changes based on interface changes. + + * prep_cif.c (ffi_prep_cif): Cleaned up interface based on + feedback from Jim Blandy. + +Fri Oct 11 15:53:18 1996 Anthony Green + + * ffitest.c: Reordered tests while porting to sparc. + Made changes to handle lame structure passing for sparc. + Removed calls to fflush(). + + * prep_cif.c (ffi_prep_cif): Added special case for sparc + aggregate type arguments. + +Thu Oct 10 09:56:51 1996 Anthony Green + + * ffitest.c (main): Added structure passing/returning tests. + + * prep_cif.c (ffi_prep_cif): Perform proper initialization + of structure return types if needed. + (initialize_aggregate): Bug fix + +Wed Oct 9 16:04:20 1996 Anthony Green + + * types.c: Added special definitions for x86 (double doesn't + need double word alignment). + + * ffitest.c: Added many tests + +Tue Oct 8 09:19:22 1996 Anthony Green + + * prep_cif.c (ffi_prep_cif): Fixed assertion. + + * debug.c (ffi_assert): Must return a non void now. + + * Makefile.am: Added test production. + * Makefile: Rebuilt. + + * ffitest.c (main): Created. + + * types.c: Created. Stripped common code out of */ffi.c. + + * prep_cif.c: Added missing stdlib.h include. + + * debug.c (ffi_type_test): Used "a" to eliminate compiler + warnings in non-debug builds. Included ffi_common.h. + +Mon Oct 7 15:36:42 1996 Anthony Green + + * Makefile.am: Added a rule for .s -> .o + This is required by the SGI compiler. + * Makefile: Rebuilt. + +Fri Oct 4 09:51:08 1996 Anthony Green + + * prep_cif.c (initialize_aggregate): Moved abi specification + to ffi_prep_cif(). + +Thu Oct 3 15:37:37 1996 Anthony Green + + * prep_cif.c (ffi_prep_cif): Changed values from void* to void**. + (initialize_aggregate): Fixed aggregate type initialization. + + * Makefile.am (EXTRA_DIST): Added support code for "make dist". + * Makefile.in: Regenerated. + +Wed Oct 2 11:41:57 1996 Anthony Green + + * debug.c, prep_cif: Created. + + * Makefile.am: Added debug.o and prep_cif.o to OBJ. + * Makefile.in: Regenerated. + + * Makefile.am (INCLUDES): Added missing -I../include + * Makefile.in: Regenerated. + +Tue Oct 1 17:11:51 1996 Anthony Green + + * error.c, Makefile.am: Created. + * Makefile.in: Generated. + +--- libffi/src/x86 -------------------------------------------------------- + +Sun Oct 4 16:27:17 1998 Anthony Green + + * sysv.S (retlongdouble): Fixed long long return value support. + * ffi.c (ffi_prep_cif_machdep): Ditto. + +Wed May 13 04:30:33 1998 Anthony Green + + * ffi.c (ffi_prep_cif_machdep): Fixed long double return value + support. + +Wed Apr 15 08:43:20 1998 Anthony Green + + * ffi.c (ffi_prep_args): small struct support was missing. + +Thu May 8 16:53:58 1997 Anthony Green + + * objects.mak: Removed. + +Mon Dec 2 15:12:58 1996 Tom Tromey + + * sysv.S: Use .balign, for a.out Linux boxes. + +Tue Oct 15 13:06:50 1996 Anthony Green + + * ffi.c: Clean up based on LCLint output. + Added funny /*@...@*/ comments to annotate source. + +Fri Oct 11 16:43:38 1996 Anthony Green + + * ffi.c (ffi_call): Added assertion for bad ABIs. + +Wed Oct 9 13:57:27 1996 Anthony Green + + * sysv.S (retdouble): Fixed double return problems. + + * ffi.c (ffi_call): Corrected fn arg definition. + (ffi_prep_cif_machdep): Fixed double return problems + +Tue Oct 8 12:12:49 1996 Anthony Green + + * ffi.c: Moved ffi_type definitions to types.c. + (ffi_prep_args): Fixed type promotion bug. + +Mon Oct 7 15:53:06 1996 Anthony Green + + * ffi.c (FFI_*_TYPEDEF): Removed redundant ';' + +Fri Oct 4 09:54:53 1996 Anthony Green + + * ffi.c (ffi_call): Removed FFI_ABI arg, and swapped + remaining args. + +Wed Oct 2 10:07:05 1996 Anthony Green + + * ffi.c, sysv.S, objects.mak: Created. + (ffi_prep_cif): cif->rvalue no longer initialized to NULL. + (ffi_prep_cif_machdep): Moved machine independent cif processing + to src/prep_cif.c. Introduced ffi_prep_cif_machdep(). + +--- libffi/src/mips ------------------------------------------------------- + +Tue Feb 17 17:18:07 1998 Anthony Green + + * o32.S: Fixed typo in comment. + + * ffi.c (ffi_prep_cif_machdep): Fixed argument processing. + +Thu May 8 16:53:58 1997 Anthony Green + + * o32.s, n32.s: Wrappers for SGI tool support. + + * objects.mak: Removed. + +Tue Oct 29 14:37:45 1996 Anthony Green + + * ffi.c (ffi_prep_args): Changed int z to size_t z. + +Tue Oct 15 13:17:25 1996 Anthony Green + + * n32.S: Fixed bad stack munging. + + * ffi.c: Moved prototypes for ffi_call_?32() to here from + ffi_mips.h because extended_cif is not defined in ffi_mips.h. + +Mon Oct 14 12:42:02 1996 Anthony Green + + * ffi.c: Interface changes based on feedback from Jim Blandy. + +Thu Oct 10 11:22:16 1996 Anthony Green + + * n32.S, ffi.c: Lots of changes to support passing and + returning structures with the n32 calling convention. + + * n32.S: Fixed fn pointer bug. + + * ffi.c (ffi_prep_cif_machdep): Fix for o32 structure + return values. + (ffi_prep_args): Fixed n32 structure passing when structures + partially fit in registers. + +Wed Oct 9 13:49:25 1996 Anthony Green + + * objects.mak: Added n32.o. + + * n32.S: Created. + + * ffi.c (ffi_prep_args): Added magic to support proper + n32 processing. + +Tue Oct 8 10:37:35 1996 Anthony Green + + * ffi.c: Moved ffi_type definitions to types.c. + (ffi_prep_args): Fixed type promotion bug. + + * o32.S: This code is only built for o32 compiles. + A lot of the #define cruft has moved to ffi_mips.h. + + * ffi.c (ffi_prep_cif_machdep): Fixed arg flags. Second arg + is only processed if the first is either a float or double. + +Mon Oct 7 15:33:59 1996 Anthony Green + + * o32.S: Modified to compile under each of o32, n32 and n64. + + * ffi.c (FFI_*_TYPEDEF): Removed redundant ';' + +Fri Oct 4 09:53:25 1996 Anthony Green + + * ffi.c (ffi_call): Removed FFI_ABI arg, and swapped + remaining args. + +Wed Oct 2 17:41:22 1996 Anthony Green + + * o32.S: Removed crufty definitions. + +Wed Oct 2 12:53:42 1996 Anthony Green + + * ffi.c (ffi_prep_cif): cif->rvalue no longer initialized to NULL. + (ffi_prep_cif_machdep): Moved all machine independent cif processing + to src/prep_cif.c. Introduced ffi_prep_cif_machdep. Return types + of FFI_TYPE_STRUCT are no different than FFI_TYPE_INT. + +Tue Oct 1 17:11:02 1996 Anthony Green + + * ffi.c, o32.S, object.mak: Created + +--- libffi/src/sparc ------------------------------------------------------ + +Tue Feb 24 16:33:18 1998 Anthony Green + + * ffi.c (ffi_prep_args): Added long double support. + +Thu May 8 16:53:58 1997 Anthony Green + + * objects.mak: Removed. + +Thu May 1 16:07:56 1997 Anthony Green + + * v8.S: Fixed minor portability problem reported by + Russ McManus . + +Tue Nov 26 14:12:43 1996 Anthony Green + + * v8.S: Used STACKFRAME define elsewhere. + + * ffi.c (ffi_prep_args): Zero out space when USING_PURIFY + is set. + (ffi_prep_cif_machdep): Allocate the correct stack frame + space for functions with < 6 args. + +Tue Oct 29 15:08:55 1996 Anthony Green + + * ffi.c (ffi_prep_args): int z is now size_t z. + +Mon Oct 14 13:31:24 1996 Anthony Green + + * v8.S (ffi_call_V8): Gordon rewrites this again. It looks + great now. + + * ffi.c (ffi_call): The comment about hijacked registers + is no longer valid after gordoni hacked v8.S. + + * v8.S (ffi_call_V8): Rewrote with gordoni. Much simpler. + + * v8.S, ffi.c: ffi_call() had changed to accept more than + two args, so v8.S had to change (because it hijacks incoming + arg registers). + + * ffi.c: Interface changes based on feedback from Jim Blandy. + +Thu Oct 10 17:48:16 1996 Anthony Green + + * ffi.c, v8.S, objects.mak: Created. + + diff --git a/circuitpython/lib/libffi/LICENSE b/circuitpython/lib/libffi/LICENSE new file mode 100644 index 0000000..a66fab4 --- /dev/null +++ b/circuitpython/lib/libffi/LICENSE @@ -0,0 +1,21 @@ +libffi - Copyright (c) 1996-2014 Anthony Green, Red Hat, Inc and others. +See source files for details. + +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. diff --git a/circuitpython/lib/libffi/Makefile.am b/circuitpython/lib/libffi/Makefile.am new file mode 100644 index 0000000..6fb3d47 --- /dev/null +++ b/circuitpython/lib/libffi/Makefile.am @@ -0,0 +1,174 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS = foreign subdir-objects + +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = include testsuite man + +EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ + ChangeLog.libffi ChangeLog.libffi-3.1 \ + m4/libtool.m4 m4/lt~obsolete.m4 \ + m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ + m4/ltversion.m4 src/debug.c msvcc.sh \ + generate-darwin-source-and-headers.py \ + libffi.xcodeproj/project.pbxproj \ + libtool-ldflags + +info_TEXINFOS = doc/libffi.texi + +## ################################################################ + +## +## This section is for make and multilib madness. +## + +# Work around what appears to be a GNU make bug handling MAKEFLAGS +# values defined in terms of make variables, as is the case for CC and +# friends when we are called from the top level Makefile. +AM_MAKEFLAGS = \ + 'AR_FLAGS=$(AR_FLAGS)' \ + 'CC_FOR_BUILD=$(CC_FOR_BUILD)' \ + 'CFLAGS=$(CFLAGS)' \ + 'CXXFLAGS=$(CXXFLAGS)' \ + 'CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)' \ + 'CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)' \ + 'INSTALL=$(INSTALL)' \ + 'INSTALL_DATA=$(INSTALL_DATA)' \ + 'INSTALL_PROGRAM=$(INSTALL_PROGRAM)' \ + 'INSTALL_SCRIPT=$(INSTALL_SCRIPT)' \ + 'JC1FLAGS=$(JC1FLAGS)' \ + 'LDFLAGS=$(LDFLAGS)' \ + 'LIBCFLAGS=$(LIBCFLAGS)' \ + 'LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)' \ + 'MAKE=$(MAKE)' \ + 'MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)' \ + 'PICFLAG=$(PICFLAG)' \ + 'PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)' \ + 'RUNTESTFLAGS=$(RUNTESTFLAGS)' \ + 'SHELL=$(SHELL)' \ + 'exec_prefix=$(exec_prefix)' \ + 'infodir=$(infodir)' \ + 'libdir=$(libdir)' \ + 'mandir=$(mandir)' \ + 'prefix=$(prefix)' \ + 'AR=$(AR)' \ + 'AS=$(AS)' \ + 'CC=$(CC)' \ + 'CXX=$(CXX)' \ + 'LD=$(LD)' \ + 'NM=$(NM)' \ + 'RANLIB=$(RANLIB)' \ + 'DESTDIR=$(DESTDIR)' + +# Subdir rules rely on $(FLAGS_TO_PASS) +FLAGS_TO_PASS = $(AM_MAKEFLAGS) + +MAKEOVERRIDES= + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libffi.pc + +toolexeclib_LTLIBRARIES = libffi.la +noinst_LTLIBRARIES = libffi_convenience.la + +libffi_la_SOURCES = src/prep_cif.c src/types.c \ + src/raw_api.c src/java_raw_api.c src/closures.c + +if FFI_DEBUG +libffi_la_SOURCES += src/debug.c +endif + +noinst_HEADERS = \ + src/aarch64/ffitarget.h src/aarch64/internal.h \ + src/alpha/ffitarget.h src/alpha/internal.h \ + src/arc/ffitarget.h \ + src/arm/ffitarget.h src/arm/internal.h \ + src/avr32/ffitarget.h \ + src/bfin/ffitarget.h \ + src/cris/ffitarget.h \ + src/frv/ffitarget.h \ + src/ia64/ffitarget.h src/ia64/ia64_flags.h \ + src/m32r/ffitarget.h \ + src/m68k/ffitarget.h \ + src/m88k/ffitarget.h \ + src/metag/ffitarget.h \ + src/microblaze/ffitarget.h \ + src/mips/ffitarget.h \ + src/moxie/ffitarget.h \ + src/nios2/ffitarget.h \ + src/or1k/ffitarget.h \ + src/pa/ffitarget.h \ + src/powerpc/ffitarget.h src/powerpc/asm.h src/powerpc/ffi_powerpc.h \ + src/s390/ffitarget.h \ + src/sh/ffitarget.h \ + src/sh64/ffitarget.h \ + src/sparc/ffitarget.h src/sparc/internal.h \ + src/tile/ffitarget.h \ + src/vax/ffitarget.h \ + src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h \ + src/xtensa/ffitarget.h \ + src/dlmalloc.c + +EXTRA_libffi_la_SOURCES = \ + src/aarch64/ffi.c src/aarch64/sysv.S \ + src/alpha/ffi.c src/alpha/osf.S \ + src/arc/ffi.c src/arc/arcompact.S \ + src/arm/ffi.c src/arm/sysv.S \ + src/avr32/ffi.c src/avr32/sysv.S \ + src/bfin/ffi.c src/bfin/sysv.S \ + src/cris/ffi.c src/cris/sysv.S \ + src/frv/ffi.c src/frv/eabi.S \ + src/ia64/ffi.c src/ia64/unix.S \ + src/m32r/ffi.c src/m32r/sysv.S \ + src/m68k/ffi.c src/m68k/sysv.S \ + src/m88k/ffi.c src/m88k/obsd.S \ + src/metag/ffi.c src/metag/sysv.S \ + src/microblaze/ffi.c src/microblaze/sysv.S \ + src/mips/ffi.c src/mips/o32.S src/mips/n32.S \ + src/moxie/ffi.c src/moxie/eabi.S \ + src/nios2/ffi.c src/nios2/sysv.S \ + src/or1k/ffi.c src/or1k/sysv.S \ + src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \ + src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c \ + src/powerpc/sysv.S src/powerpc/linux64.S \ + src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S \ + src/powerpc/aix.S src/powerpc/darwin.S src/powerpc/aix_closure.S \ + src/powerpc/darwin_closure.S src/powerpc/ffi_darwin.c \ + src/s390/ffi.c src/s390/sysv.S \ + src/sh/ffi.c src/sh/sysv.S \ + src/sh64/ffi.c src/sh64/sysv.S \ + src/sparc/ffi.c src/sparc/ffi64.c src/sparc/v8.S src/sparc/v9.S \ + src/tile/ffi.c src/tile/tile.S \ + src/vax/ffi.c src/vax/elfbsd.S \ + src/x86/ffi.c src/x86/sysv.S \ + src/x86/ffiw64.c src/x86/win64.S \ + src/x86/ffi64.c src/x86/unix64.S \ + src/xtensa/ffi.c src/xtensa/sysv.S + +TARGET_OBJ = @TARGET_OBJ@ +libffi_la_LIBADD = $(TARGET_OBJ) +libffi_la_DEPENDENCIES = $(TARGET_OBJ) + +libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) +EXTRA_libffi_convenience_la_SOURCES = $(EXTRA_libffi_la_SOURCES) +libffi_convenience_la_LIBADD = $(libffi_la_LIBADD) +libffi_convenience_la_DEPENDENCIES = $(libffi_la_DEPENDENCIES) +nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) + +LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS)) + +AM_CFLAGS = +if FFI_DEBUG +# Build debug. Define FFI_DEBUG on the commandline so that, when building with +# MSVC, it can link against the debug CRT. +AM_CFLAGS += -DFFI_DEBUG +endif + +libffi_la_LDFLAGS = -no-undefined -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS) + +AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src +AM_CCASFLAGS = $(AM_CPPFLAGS) + +dist-hook: + if [ -d $(top_srcdir)/.git ] ; then (cd $(top_srcdir); git log --no-decorate) ; else echo 'See git log for history.' ; fi > $(distdir)/ChangeLog diff --git a/circuitpython/lib/libffi/README b/circuitpython/lib/libffi/README new file mode 100644 index 0000000..c072101 --- /dev/null +++ b/circuitpython/lib/libffi/README @@ -0,0 +1,450 @@ +Status +====== + +libffi-4?? was released on TBD. Check the libffi web +page for updates: . + + +What is libffi? +=============== + +Compilers for high level languages generate code that follow certain +conventions. These conventions are necessary, in part, for separate +compilation to work. One such convention is the "calling +convention". The "calling convention" is essentially a set of +assumptions made by the compiler about where function arguments will +be found on entry to a function. A "calling convention" also specifies +where the return value for a function is found. + +Some programs may not know at the time of compilation what arguments +are to be passed to a function. For instance, an interpreter may be +told at run-time about the number and types of arguments used to call +a given function. Libffi can be used in such programs to provide a +bridge from the interpreter program to compiled code. + +The libffi library provides a portable, high level programming +interface to various calling conventions. This allows a programmer to +call any function specified by a call interface description at run +time. + +FFI stands for Foreign Function Interface. A foreign function +interface is the popular name for the interface that allows code +written in one language to call code written in another language. The +libffi library really only provides the lowest, machine dependent +layer of a fully featured foreign function interface. A layer must +exist above libffi that handles type conversions for values passed +between the two languages. + + +Supported Platforms +=================== + +Libffi has been ported to many different platforms. +For specific configuration details and testing status, please +refer to the wiki page here: + + http://www.moxielogic.org/wiki/index.php?title=Libffi_3.2 + +At the time of release, the following basic configurations have been +tested: + +|-----------------+------------------+-------------------------| +| Architecture | Operating System | Compiler | +|-----------------+------------------+-------------------------| +| AArch64 (ARM64) | iOS | Clang | +| AArch64 | Linux | GCC | +| Alpha | Linux | GCC | +| Alpha | Tru64 | GCC | +| ARC | Linux | GCC | +| ARM | Linux | GCC | +| ARM | iOS | GCC | +| AVR32 | Linux | GCC | +| Blackfin | uClinux | GCC | +| HPPA | HPUX | GCC | +| IA-64 | Linux | GCC | +| M68K | FreeMiNT | GCC | +| M68K | Linux | GCC | +| M68K | RTEMS | GCC | +| M88K | OpenBSD/mvme88k | GCC | +| Meta | Linux | GCC | +| MicroBlaze | Linux | GCC | +| MIPS | IRIX | GCC | +| MIPS | Linux | GCC | +| MIPS | RTEMS | GCC | +| MIPS64 | Linux | GCC | +| Moxie | Bare metal | GCC | +| Nios II | Linux | GCC | +| OpenRISC | Linux | GCC | +| PowerPC 32-bit | AIX | IBM XL C | +| PowerPC 64-bit | AIX | IBM XL C | +| PowerPC | AMIGA | GCC | +| PowerPC | Linux | GCC | +| PowerPC | Mac OSX | GCC | +| PowerPC | FreeBSD | GCC | +| PowerPC 64-bit | FreeBSD | GCC | +| PowerPC 64-bit | Linux ELFv1 | GCC | +| PowerPC 64-bit | Linux ELFv2 | GCC | +| S390 | Linux | GCC | +| S390X | Linux | GCC | +| SPARC | Linux | GCC | +| SPARC | Solaris | GCC | +| SPARC | Solaris | Oracle Solaris Studio C | +| SPARC64 | Linux | GCC | +| SPARC64 | FreeBSD | GCC | +| SPARC64 | Solaris | Oracle Solaris Studio C | +| TILE-Gx/TILEPro | Linux | GCC | +| VAX | OpenBSD/vax | GCC | +| X86 | FreeBSD | GCC | +| X86 | GNU HURD | GCC | +| X86 | Interix | GCC | +| X86 | kFreeBSD | GCC | +| X86 | Linux | GCC | +| X86 | Mac OSX | GCC | +| X86 | OpenBSD | GCC | +| X86 | OS/2 | GCC | +| X86 | Solaris | GCC | +| X86 | Solaris | Oracle Solaris Studio C | +| X86 | Windows/Cygwin | GCC | +| X86 | Windows/MingW | GCC | +| X86-64 | FreeBSD | GCC | +| X86-64 | Linux | GCC | +| X86-64 | Linux/x32 | GCC | +| X86-64 | OpenBSD | GCC | +| X86-64 | Solaris | Oracle Solaris Studio C | +| X86-64 | Windows/Cygwin | GCC | +| X86-64 | Windows/MingW | GCC | +| Xtensa | Linux | GCC | +|-----------------+------------------+-------------------------| + +Please send additional platform test results to +libffi-discuss@sourceware.org and feel free to update the wiki page +above. + +Installing libffi +================= + +First you must configure the distribution for your particular +system. Go to the directory you wish to build libffi in and run the +"configure" program found in the root directory of the libffi source +distribution. + +If you're building libffi directly from version control, configure won't +exist yet; run ./autogen.sh first. + +You may want to tell configure where to install the libffi library and +header files. To do that, use the --prefix configure switch. Libffi +will install under /usr/local by default. + +If you want to enable extra run-time debugging checks use the the +--enable-debug configure switch. This is useful when your program dies +mysteriously while using libffi. + +Another useful configure switch is --enable-purify-safety. Using this +will add some extra code which will suppress certain warnings when you +are using Purify with libffi. Only use this switch when using +Purify, as it will slow down the library. + +It's also possible to build libffi on Windows platforms with +Microsoft's Visual C++ compiler. In this case, use the msvcc.sh +wrapper script during configuration like so: + +path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP="cl -nologo -EP" + +For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64" and +CXX="path/to/msvcc.sh -m64". You may also need to specify --build +appropriately. + +It is also possible to build libffi on Windows platforms with the LLVM +project's clang-cl compiler, like below: + +path/to/configure CC="path/to/msvcc.sh -clang-cl" CXX="path/to/msvcc.sh -clang-cl" LD=link CPP="clang-cl -EP" + +When building with MSVC under a MingW environment, you may need to +remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath' +command. ('cygpath' is not present in MingW, and is not required when +using MingW-style paths.) + +For iOS builds, the 'libffi.xcodeproj' Xcode project is available. + +Configure has many other options. Use "configure --help" to see them all. + +Once configure has finished, type "make". Note that you must be using +GNU make. You can ftp GNU make from ftp.gnu.org:/pub/gnu/make . + +To ensure that libffi is working as advertised, type "make check". +This will require that you have DejaGNU installed. + +To install the library and header files, type "make install". + + +History +======= + +See the git log for details at http://github.com/atgreen/libffi. + +4.0 TBD + New API in support of GO closures. + +3.2.1 Nov-12-14 + Build fix for non-iOS AArch64 targets. + +3.2 Nov-11-14 + Add C99 Complex Type support (currently only supported on + s390). + Add support for PASCAL and REGISTER calling conventions on x86 + Windows/Linux. + Add OpenRISC and Cygwin-64 support. + Bug fixes. + +3.1 May-19-14 + Add AArch64 (ARM64) iOS support. + Add Nios II support. + Add m88k and DEC VAX support. + Add support for stdcall, thiscall, and fastcall on non-Windows + 32-bit x86 targets such as Linux. + Various Android, MIPS N32, x86, FreeBSD and UltraSPARC IIi + fixes. + Make the testsuite more robust: eliminate several spurious + failures, and respect the $CC and $CXX environment variables. + Archive off the manually maintained ChangeLog in favor of git + log. + +3.0.13 Mar-17-13 + Add Meta support. + Add missing Moxie bits. + Fix stack alignment bug on 32-bit x86. + Build fix for m68000 targets. + Build fix for soft-float Power targets. + Fix the install dir location for some platforms when building + with GCC (OS X, Solaris). + Fix Cygwin regression. + +3.0.12 Feb-11-13 + Add Moxie support. + Add AArch64 support. + Add Blackfin support. + Add TILE-Gx/TILEPro support. + Add MicroBlaze support. + Add Xtensa support. + Add support for PaX enabled kernels with MPROTECT. + Add support for native vendor compilers on + Solaris and AIX. + Work around LLVM/GCC interoperability issue on x86_64. + +3.0.11 Apr-11-12 + Lots of build fixes. + Add support for variadic functions (ffi_prep_cif_var). + Add Linux/x32 support. + Add thiscall, fastcall and MSVC cdecl support on Windows. + Add Amiga and newer MacOS support. + Add m68k FreeMiNT support. + Integration with iOS' xcode build tools. + Fix Octeon and MC68881 support. + Fix code pessimizations. + +3.0.10 Aug-23-11 + Add support for Apple's iOS. + Add support for ARM VFP ABI. + Add RTEMS support for MIPS and M68K. + Fix instruction cache clearing problems on + ARM and SPARC. + Fix the N64 build on mips-sgi-irix6.5. + Enable builds with Microsoft's compiler. + Enable x86 builds with Oracle's Solaris compiler. + Fix support for calling code compiled with Oracle's Sparc + Solaris compiler. + Testsuite fixes for Tru64 Unix. + Additional platform support. + +3.0.9 Dec-31-09 + Add AVR32 and win64 ports. Add ARM softfp support. + Many fixes for AIX, Solaris, HP-UX, *BSD. + Several PowerPC and x86-64 bug fixes. + Build DLL for windows. + +3.0.8 Dec-19-08 + Add *BSD, BeOS, and PA-Linux support. + +3.0.7 Nov-11-08 + Fix for ppc FreeBSD. + (thanks to Andreas Tobler) + +3.0.6 Jul-17-08 + Fix for closures on sh. + Mark the sh/sh64 stack as non-executable. + (both thanks to Kaz Kojima) + +3.0.5 Apr-3-08 + Fix libffi.pc file. + Fix #define ARM for IcedTea users. + Fix x86 closure bug. + +3.0.4 Feb-24-08 + Fix x86 OpenBSD configury. + +3.0.3 Feb-22-08 + Enable x86 OpenBSD thanks to Thomas Heller, and + x86-64 FreeBSD thanks to Björn König and Andreas Tobler. + Clean up test instruction in README. + +3.0.2 Feb-21-08 + Improved x86 FreeBSD support. + Thanks to Björn König. + +3.0.1 Feb-15-08 + Fix instruction cache flushing bug on MIPS. + Thanks to David Daney. + +3.0.0 Feb-15-08 + Many changes, mostly thanks to the GCC project. + Cygnus Solutions is now Red Hat. + + [10 years go by...] + +1.20 Oct-5-98 + Raffaele Sena produces ARM port. + +1.19 Oct-5-98 + Fixed x86 long double and long long return support. + m68k bug fixes from Andreas Schwab. + Patch for DU assembler compatibility for the Alpha from Richard + Henderson. + +1.18 Apr-17-98 + Bug fixes and MIPS configuration changes. + +1.17 Feb-24-98 + Bug fixes and m68k port from Andreas Schwab. PowerPC port from + Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes. + +1.16 Feb-11-98 + Richard Henderson produces Alpha port. + +1.15 Dec-4-97 + Fixed an n32 ABI bug. New libtool, auto* support. + +1.14 May-13-97 + libtool is now used to generate shared and static libraries. + Fixed a minor portability problem reported by Russ McManus + . + +1.13 Dec-2-96 + Added --enable-purify-safety to keep Purify from complaining + about certain low level code. + Sparc fix for calling functions with < 6 args. + Linux x86 a.out fix. + +1.12 Nov-22-96 + Added missing ffi_type_void, needed for supporting void return + types. Fixed test case for non MIPS machines. Cygnus Support + is now Cygnus Solutions. + +1.11 Oct-30-96 + Added notes about GNU make. + +1.10 Oct-29-96 + Added configuration fix for non GNU compilers. + +1.09 Oct-29-96 + Added --enable-debug configure switch. Clean-ups based on LCLint + feedback. ffi_mips.h is always installed. Many configuration + fixes. Fixed ffitest.c for sparc builds. + +1.08 Oct-15-96 + Fixed n32 problem. Many clean-ups. + +1.07 Oct-14-96 + Gordon Irlam rewrites v8.S again. Bug fixes. + +1.06 Oct-14-96 + Gordon Irlam improved the sparc port. + +1.05 Oct-14-96 + Interface changes based on feedback. + +1.04 Oct-11-96 + Sparc port complete (modulo struct passing bug). + +1.03 Oct-10-96 + Passing struct args, and returning struct values works for + all architectures/calling conventions. Expanded tests. + +1.02 Oct-9-96 + Added SGI n32 support. Fixed bugs in both o32 and Linux support. + Added "make test". + +1.01 Oct-8-96 + Fixed float passing bug in mips version. Restructured some + of the code. Builds cleanly with SGI tools. + +1.00 Oct-7-96 + First release. No public announcement. + + +Authors & Credits +================= + +libffi was originally written by Anthony Green . + +The developers of the GNU Compiler Collection project have made +innumerable valuable contributions. See the ChangeLog file for +details. + +Some of the ideas behind libffi were inspired by Gianni Mariani's free +gencall library for Silicon Graphics machines. + +The closure mechanism was designed and implemented by Kresten Krab +Thorup. + +Major processor architecture ports were contributed by the following +developers: + +aarch64 Marcus Shawcroft, James Greenhalgh +alpha Richard Henderson +arm Raffaele Sena +blackfin Alexandre Keunecke I. de Mendonca +cris Simon Posnjak, Hans-Peter Nilsson +frv Anthony Green +ia64 Hans Boehm +m32r Kazuhiro Inaoka +m68k Andreas Schwab +m88k Miod Vallat +microblaze Nathan Rossi +mips Anthony Green, Casey Marshall +mips64 David Daney +moxie Anthony Green +nios ii Sandra Loosemore +openrisc Sebastian Macke +pa Randolph Chung, Dave Anglin, Andreas Tobler +powerpc Geoffrey Keating, Andreas Tobler, + David Edelsohn, John Hornkvist +powerpc64 Jakub Jelinek +s390 Gerhard Tonn, Ulrich Weigand +sh Kaz Kojima +sh64 Kaz Kojima +sparc Anthony Green, Gordon Irlam +tile-gx/tilepro Walter Lee +vax Miod Vallat +x86 Anthony Green, Jon Beniston +x86-64 Bo Thorsen +xtensa Chris Zankel + +Jesper Skov and Andrew Haley both did more than their fair share of +stepping through the code and tracking down bugs. + +Thanks also to Tom Tromey for bug fixes, documentation and +configuration help. + +Thanks to Jim Blandy, who provided some useful feedback on the libffi +interface. + +Andreas Tobler has done a tremendous amount of work on the testsuite. + +Alex Oliva solved the executable page problem for SElinux. + +The list above is almost certainly incomplete and inaccurate. I'm +happy to make corrections or additions upon request. + +If you have a problem, or have found a bug, please send a note to the +author at green@moxielogic.com, or the project mailing list at +libffi-discuss@sourceware.org. diff --git a/circuitpython/lib/libffi/acinclude.m4 b/circuitpython/lib/libffi/acinclude.m4 new file mode 100644 index 0000000..3e8f8ba --- /dev/null +++ b/circuitpython/lib/libffi/acinclude.m4 @@ -0,0 +1,92 @@ +# mmap(2) blacklisting. Some platforms provide the mmap library routine +# but don't support all of the features we need from it. +AC_DEFUN([AC_FUNC_MMAP_BLACKLIST], +[ +AC_CHECK_HEADER([sys/mman.h], + [libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no]) +AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no]) +if test "$libffi_header_sys_mman_h" != yes \ + || test "$libffi_func_mmap" != yes; then + ac_cv_func_mmap_file=no + ac_cv_func_mmap_dev_zero=no + ac_cv_func_mmap_anon=no +else + AC_CACHE_CHECK([whether read-only mmap of a plain file works], + ac_cv_func_mmap_file, + [# Add a system to this blacklist if + # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a + # memory area containing the same data that you'd get if you applied + # read() to the same fd. The only system known to have a problem here + # is VMS, where text files have record structure. + case "$host_os" in + vms* | ultrix*) + ac_cv_func_mmap_file=no ;; + *) + ac_cv_func_mmap_file=yes;; + esac]) + AC_CACHE_CHECK([whether mmap from /dev/zero works], + ac_cv_func_mmap_dev_zero, + [# Add a system to this blacklist if it has mmap() but /dev/zero + # does not exist, or if mmapping /dev/zero does not give anonymous + # zeroed pages with both the following properties: + # 1. If you map N consecutive pages in with one call, and then + # unmap any subset of those pages, the pages that were not + # explicitly unmapped remain accessible. + # 2. If you map two adjacent blocks of memory and then unmap them + # both at once, they must both go away. + # Systems known to be in this category are Windows (all variants), + # VMS, and Darwin. + case "$host_os" in + vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00) + ac_cv_func_mmap_dev_zero=no ;; + *) + ac_cv_func_mmap_dev_zero=yes;; + esac]) + + # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for. + AC_CACHE_CHECK([for MAP_ANON(YMOUS)], ac_cv_decl_map_anon, + [AC_TRY_COMPILE( +[#include +#include +#include + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif +], +[int n = MAP_ANONYMOUS;], + ac_cv_decl_map_anon=yes, + ac_cv_decl_map_anon=no)]) + + if test $ac_cv_decl_map_anon = no; then + ac_cv_func_mmap_anon=no + else + AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works], + ac_cv_func_mmap_anon, + [# Add a system to this blacklist if it has mmap() and MAP_ANON or + # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) + # doesn't give anonymous zeroed pages with the same properties listed + # above for use of /dev/zero. + # Systems known to be in this category are Windows, VMS, and SCO Unix. + case "$host_os" in + vms* | cygwin* | pe | mingw* | sco* | udk* ) + ac_cv_func_mmap_anon=no ;; + *) + ac_cv_func_mmap_anon=yes;; + esac]) + fi +fi + +if test $ac_cv_func_mmap_file = yes; then + AC_DEFINE(HAVE_MMAP_FILE, 1, + [Define if read-only mmap of a plain file works.]) +fi +if test $ac_cv_func_mmap_dev_zero = yes; then + AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1, + [Define if mmap of /dev/zero works.]) +fi +if test $ac_cv_func_mmap_anon = yes; then + AC_DEFINE(HAVE_MMAP_ANON, 1, + [Define if mmap with MAP_ANON(YMOUS) works.]) +fi +]) diff --git a/circuitpython/lib/libffi/autogen.sh b/circuitpython/lib/libffi/autogen.sh new file mode 100755 index 0000000..d270b98 --- /dev/null +++ b/circuitpython/lib/libffi/autogen.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exec autoreconf -v -f -i diff --git a/circuitpython/lib/libffi/configure.ac b/circuitpython/lib/libffi/configure.ac new file mode 100644 index 0000000..445c589 --- /dev/null +++ b/circuitpython/lib/libffi/configure.ac @@ -0,0 +1,372 @@ +dnl Process this with autoconf to create configure + +AC_PREREQ(2.68) + +AC_INIT([libffi], [3.99999], [http://github.com/atgreen/libffi/issues]) +AC_CONFIG_HEADERS([fficonfig.h]) + +AC_CANONICAL_SYSTEM +target_alias=${target_alias-$host_alias} + +case "${host}" in + frv*-elf) + LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/ + ;; +esac + +AX_ENABLE_BUILDDIR + +AM_INIT_AUTOMAKE + +# The same as in boehm-gc and libstdc++. Have to borrow it from there. +# We must force CC to /not/ be precious variables; otherwise +# the wrong, non-multilib-adjusted value will be used in multilibs. +# As a side effect, we have to subst CFLAGS ourselves. +# Also save and restore CFLAGS, since AC_PROG_CC will come up with +# defaults of its own if none are provided. + +m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) +m4_define([_AC_ARG_VAR_PRECIOUS],[]) +save_CFLAGS=$CFLAGS +AC_PROG_CC +AC_PROG_CXX +CFLAGS=$save_CFLAGS +m4_undefine([_AC_ARG_VAR_PRECIOUS]) +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) + +AC_SUBST(CFLAGS) + +AM_PROG_AS +AM_PROG_CC_C_O +AC_PROG_LIBTOOL +AC_CONFIG_MACRO_DIR([m4]) + +# Test for 64-bit build. +AC_CHECK_SIZEOF([size_t]) + +AX_COMPILER_VENDOR +AX_CC_MAXOPT +# The AX_CFLAGS_WARN_ALL macro doesn't currently work for sunpro +# compiler. +if test "$ax_cv_c_compiler_vendor" != "sun"; then + AX_CFLAGS_WARN_ALL +fi + +if test "x$GCC" = "xyes"; then + CFLAGS="$CFLAGS -fexceptions" +fi + +cat > local.exp < conftest.s + if $CC $CFLAGS -c conftest.s > /dev/null 2>&1; then + libffi_cv_as_x86_pcrel=yes + fi + ]) + if test "x$libffi_cv_as_x86_pcrel" = xyes; then + AC_DEFINE(HAVE_AS_X86_PCREL, 1, + [Define if your assembler supports PC relative relocs.]) + fi + ;; + + S390) + AC_CACHE_CHECK([compiler uses zarch features], + libffi_cv_as_s390_zarch, [ + libffi_cv_as_s390_zarch=no + echo 'void foo(void) { bar(); bar(); }' > conftest.c + if $CC $CFLAGS -S conftest.c > /dev/null 2>&1; then + if grep -q brasl conftest.s; then + libffi_cv_as_s390_zarch=yes + fi + fi + ]) + if test "x$libffi_cv_as_s390_zarch" = xyes; then + AC_DEFINE(HAVE_AS_S390_ZARCH, 1, + [Define if the compiler uses zarch features.]) + fi + ;; +esac + +# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. +AC_ARG_ENABLE(pax_emutramp, + [ --enable-pax_emutramp enable pax emulated trampolines, for we can't use PROT_EXEC], + if test "$enable_pax_emutramp" = "yes"; then + AC_DEFINE(FFI_MMAP_EXEC_EMUTRAMP_PAX, 1, + [Define this if you want to enable pax emulated trampolines]) + fi) + +LT_SYS_SYMBOL_USCORE +if test "x$sys_symbol_underscore" = xyes; then + AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.]) +fi + +FFI_EXEC_TRAMPOLINE_TABLE=0 +case "$target" in + *arm*-apple-darwin* | aarch64-apple-darwin*) + FFI_EXEC_TRAMPOLINE_TABLE=1 + AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1, + [Cannot use PROT_EXEC on this target, so, we revert to + alternative means]) + ;; + *-apple-darwin1* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*) + AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1, + [Cannot use malloc on this target, so, we revert to + alternative means]) + ;; +esac +AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1) +AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE) + +if test x$TARGET = xX86_64; then + AC_CACHE_CHECK([toolchain supports unwind section type], + libffi_cv_as_x86_64_unwind_section_type, [ + cat > conftest1.s << EOF +.text +.globl foo +foo: +jmp bar +.section .eh_frame,"a",@unwind +bar: +EOF + + cat > conftest2.c << EOF +extern void foo(); +int main(){foo();} +EOF + + libffi_cv_as_x86_64_unwind_section_type=no + # we ensure that we can compile _and_ link an assembly file containing an @unwind section + # since the compiler can support it and not the linker (ie old binutils) + if $CC -Wa,--fatal-warnings $CFLAGS -c conftest1.s > /dev/null 2>&1 && \ + $CC conftest2.c conftest1.o > /dev/null 2>&1 ; then + libffi_cv_as_x86_64_unwind_section_type=yes + fi + ]) + if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then + AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1, + [Define if your assembler supports unwind section type.]) + fi +fi + +if test "x$GCC" = "xyes"; then + AC_CACHE_CHECK([whether .eh_frame section should be read-only], + libffi_cv_ro_eh_frame, [ + libffi_cv_ro_eh_frame=no + echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c + if $CC $CFLAGS -c -fpic -fexceptions -o conftest.o conftest.c > /dev/null 2>&1; then + objdump -h conftest.o > conftest.dump 2>&1 + libffi_eh_frame_line=`grep -n eh_frame conftest.dump | cut -d: -f 1` + if test "x$libffi_eh_frame_line" != "x"; then + libffi_test_line=`expr $libffi_eh_frame_line + 1`p + sed -n $libffi_test_line conftest.dump > conftest.line + if grep READONLY conftest.line > /dev/null; then + libffi_cv_ro_eh_frame=yes + fi + fi + fi + rm -f conftest.* + ]) + if test "x$libffi_cv_ro_eh_frame" = xyes; then + AC_DEFINE(HAVE_RO_EH_FRAME, 1, + [Define if .eh_frame sections should be read-only.]) + AC_DEFINE(EH_FRAME_FLAGS, "a", + [Define to the flags needed for the .section .eh_frame directive. ]) + else + AC_DEFINE(EH_FRAME_FLAGS, "aw", + [Define to the flags needed for the .section .eh_frame directive. ]) + fi + + AC_CACHE_CHECK([for __attribute__((visibility("hidden")))], + libffi_cv_hidden_visibility_attribute, [ + echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1 ; }' > conftest.c + libffi_cv_hidden_visibility_attribute=no + if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + libffi_cv_hidden_visibility_attribute=yes + fi + fi + rm -f conftest.* + ]) + if test $libffi_cv_hidden_visibility_attribute = yes; then + AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1, + [Define if __attribute__((visibility("hidden"))) is supported.]) + fi +fi + +AH_BOTTOM([ +#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE +#ifdef LIBFFI_ASM +#define FFI_HIDDEN(name) .hidden name +#else +#define FFI_HIDDEN __attribute__ ((visibility ("hidden"))) +#endif +#else +#ifdef LIBFFI_ASM +#define FFI_HIDDEN(name) +#else +#define FFI_HIDDEN +#endif +#endif +]) + +AC_SUBST(TARGET) +AC_SUBST(TARGETDIR) + +changequote(<,>) +TARGET_OBJ= +for i in $SOURCES; do + TARGET_OBJ="${TARGET_OBJ} src/${TARGETDIR}/"`echo $i | sed 's/[cS]$/lo/'` +done +changequote([,]) +AC_SUBST(TARGET_OBJ) + +AC_SUBST(SHELL) + +AC_ARG_ENABLE(debug, +[ --enable-debug debugging mode], + if test "$enable_debug" = "yes"; then + AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.]) + fi) +AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes") + +AC_ARG_ENABLE(structs, +[ --disable-structs omit code for struct support], + if test "$enable_structs" = "no"; then + AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this if you do not want support for aggregate types.]) + fi) +AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes") + +AC_ARG_ENABLE(raw-api, +[ --disable-raw-api make the raw api unavailable], + if test "$enable_raw_api" = "no"; then + AC_DEFINE(FFI_NO_RAW_API, 1, [Define this if you do not want support for the raw API.]) + fi) + +AC_ARG_ENABLE(purify-safety, +[ --enable-purify-safety purify-safe mode], + if test "$enable_purify_safety" = "yes"; then + AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.]) + fi) + +# These variables are only ever used when we cross-build to X86_WIN32. +# And we only support this with GCC, so... +if test "x$GCC" = "xyes"; then + if test -n "$with_cross_host" && + test x"$with_cross_host" != x"no"; then + toolexecdir="${exec_prefix}"/'$(target_alias)' + toolexeclibdir="${toolexecdir}"/lib + else + toolexecdir="${libdir}"/gcc-lib/'$(target_alias)' + toolexeclibdir="${libdir}" + fi + multi_os_directory=`$CC $CFLAGS -print-multi-os-directory` + case $multi_os_directory in + .) ;; # Avoid trailing /. + ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;; + esac + AC_SUBST(toolexecdir) +else + toolexeclibdir="${libdir}" +fi +AC_SUBST(toolexeclibdir) + +AC_CONFIG_COMMANDS(include, [test -d include || mkdir include]) +AC_CONFIG_COMMANDS(src, [ +test -d src || mkdir src +test -d src/$TARGETDIR || mkdir src/$TARGETDIR +], [TARGETDIR="$TARGETDIR"]) + +AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h) + +AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc) + +AC_OUTPUT diff --git a/circuitpython/lib/libffi/configure.host b/circuitpython/lib/libffi/configure.host new file mode 100644 index 0000000..c6f6a02 --- /dev/null +++ b/circuitpython/lib/libffi/configure.host @@ -0,0 +1,259 @@ +# configure.host +# +# This shell script handles all host based configuration for libffi. +# + +# THIS TABLE IS SORTED. KEEP IT THAT WAY. +# Most of the time we can define all the variables all at once... +case "${host}" in + aarch64*-*-*) + TARGET=AARCH64; TARGETDIR=aarch64 + SOURCES="ffi.c sysv.S" + ;; + + alpha*-*-*) + TARGET=ALPHA; TARGETDIR=alpha; + # Support 128-bit long double, changeable via command-line switch. + HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' + SOURCES="ffi.c osf.S" + ;; + + arc*-*-*) + TARGET=ARC; TARGETDIR=arc + SOURCES="ffi.c arcompact.S" + ;; + + arm*-*-*) + TARGET=ARM; TARGETDIR=arm + SOURCES="ffi.c sysv.S" + ;; + + avr32*-*-*) + TARGET=AVR32; TARGETDIR=avr32 + SOURCES="ffi.c sysv.S" + ;; + + bfin*) + TARGET=BFIN; TARGETDIR=bfin + SOURCES="ffi.c sysv.S" + ;; + + cris-*-*) + TARGET=LIBFFI_CRIS; TARGETDIR=cris + SOURCES="ffi.c sysv.S" + ;; + + frv-*-*) + TARGET=FRV; TARGETDIR=frv + SOURCES="ffi.c eabi.S" + ;; + + hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*) + TARGET=PA_LINUX; TARGETDIR=pa + SOURCES="ffi.c linux.S" + ;; + hppa*64-*-hpux*) + TARGET=PA64_HPUX; TARGETDIR=pa + ;; + hppa*-*-hpux*) + TARGET=PA_HPUX; TARGETDIR=pa + SOURCES="ffi.c hpux32.S" + ;; + + i?86-*-freebsd* | i?86-*-openbsd*) + TARGET=X86_FREEBSD; TARGETDIR=x86 + ;; + + i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix* \ + | x86_64-*-cygwin* | x86_64-*-mingw*) + TARGETDIR=x86 + if test $ac_cv_sizeof_size_t = 4; then + TARGET=X86_WIN32 + else + TARGET=X86_WIN64 + fi + # All mingw/cygwin/win32 builds require -no-undefined for sharedlib. + # We must also check with_cross_host to decide if this is a native + # or cross-build and select where to install dlls appropriately. + if test -n "$with_cross_host" && + test x"$with_cross_host" != x"no"; then + AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"'; + else + AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"'; + fi + ;; + + i?86-*-darwin* | x86_64-*-darwin*) + TARGETDIR=x86 + if test $ac_cv_sizeof_size_t = 4; then + TARGET=X86_DARWIN + else + TARGET=X86_64 + fi + ;; + + i?86-*-* | x86_64-*-* | amd64-*) + TARGETDIR=x86 + if test $ac_cv_sizeof_size_t = 4; then + case "$host" in + *-gnux32) + TARGET=X86_64 + ;; + *) + TARGET=X86 + ;; + esac + else + TARGET=X86_64; + fi + ;; + + ia64*-*-*) + TARGET=IA64; TARGETDIR=ia64 + SOURCES="ffi.c unix.S" + ;; + + m32r*-*-*) + TARGET=M32R; TARGETDIR=m32r + SOURCES="ffi.c sysv.S" + ;; + + m68k-*-*) + TARGET=M68K; TARGETDIR=m68k + SOURCES="ffi.c sysv.S" + ;; + + m88k-*-*) + TARGET=M88K; TARGETDIR=m88k + SOURCES="ffi.c obsd.S" + ;; + + microblaze*-*-*) + TARGET=MICROBLAZE; TARGETDIR=microblaze + SOURCES="ffi.c sysv.S" + ;; + + moxie-*-*) + TARGET=MOXIE; TARGETDIR=moxie + SOURCES="ffi.c eabi.S" + ;; + + metag-*-*) + TARGET=METAG; TARGETDIR=metag + SOURCES="ffi.c sysv.S" + ;; + + mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) + TARGET=MIPS; TARGETDIR=mips + ;; + mips*-*linux* | mips*-*-openbsd*) + # Support 128-bit long double for NewABI. + HAVE_LONG_DOUBLE='defined(__mips64)' + TARGET=MIPS; TARGETDIR=mips + ;; + + nios2*-linux*) + TARGET=NIOS2; TARGETDIR=nios2 + SOURCES="ffi.c sysv.S" + ;; + + or1k*-linux*) + TARGET=OR1K; TARGETDIR=or1k + SOURCES="ffi.c sysv.S" + ;; + + powerpc*-*-linux* | powerpc-*-sysv*) + TARGET=POWERPC; TARGETDIR=powerpc + HAVE_LONG_DOUBLE_VARIANT=1 + ;; + powerpc-*-amigaos*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + powerpc-*-beos*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + powerpc-*-darwin* | powerpc64-*-darwin*) + TARGET=POWERPC_DARWIN; TARGETDIR=powerpc + ;; + powerpc-*-aix* | rs6000-*-aix*) + TARGET=POWERPC_AIX; TARGETDIR=powerpc + ;; + powerpc-*-freebsd* | powerpc-*-openbsd* | powerpc-*-netbsd*) + TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc + HAVE_LONG_DOUBLE_VARIANT=1 + ;; + powerpc64-*-freebsd*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + powerpc*-*-rtems*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + + s390-*-* | s390x-*-*) + TARGET=S390; TARGETDIR=s390 + SOURCES="ffi.c sysv.S" + ;; + + sh-*-* | sh[34]*-*-*) + TARGET=SH; TARGETDIR=sh + SOURCES="ffi.c sysv.S" + ;; + sh64-*-* | sh5*-*-*) + TARGET=SH64; TARGETDIR=sh64 + SOURCES="ffi.c sysv.S" + ;; + + sparc*-*-*) + TARGET=SPARC; TARGETDIR=sparc + SOURCES="ffi.c ffi64.c v8.S v9.S" + ;; + + tile*-*) + TARGET=TILE; TARGETDIR=tile + SOURCES="ffi.c tile.S" + ;; + + vax-*-*) + TARGET=VAX; TARGETDIR=vax + SOURCES="ffi.c elfbsd.S" + ;; + + xtensa*-*) + TARGET=XTENSA; TARGETDIR=xtensa + SOURCES="ffi.c sysv.S" + ;; +esac + +# ... but some of the cases above share configury. +case "${TARGET}" in + MIPS) + SOURCES="ffi.c o32.S n32.S" + ;; + POWERPC) + SOURCES="ffi.c ffi_sysv.c ffi_linux64.c sysv.S ppc_closure.S" + SOURCES="${SOURCES} linux64.S linux64_closure.S" + ;; + POWERPC_AIX) + SOURCES="ffi_darwin.c aix.S aix_closure.S" + ;; + POWERPC_DARWIN) + SOURCES="ffi_darwin.c darwin.S darwin_closure.S" + ;; + POWERPC_FREEBSD) + SOURCES="ffi.c ffi_sysv.c sysv.S ppc_closure.S" + ;; + X86 | X86_DARWIN | X86_FREEBSD | X86_WIN32) + SOURCES="ffi.c sysv.S" + ;; + X86_64) + SOURCES="ffi64.c unix64.S" + ;; + X86_WIN64) + SOURCES="ffiw64.c win64.S" + ;; +esac + +# If we failed to configure SOURCES, we can't do anything. +if test -z "${SOURCES}"; then + UNSUPPORTED=1 +fi diff --git a/circuitpython/lib/libffi/doc/libffi.texi b/circuitpython/lib/libffi/doc/libffi.texi new file mode 100644 index 0000000..ff72e58 --- /dev/null +++ b/circuitpython/lib/libffi/doc/libffi.texi @@ -0,0 +1,765 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename libffi.info +@settitle libffi +@setchapternewpage off +@c %**end of header + +@c Merge the standard indexes into a single one. +@syncodeindex fn cp +@syncodeindex vr cp +@syncodeindex ky cp +@syncodeindex pg cp +@syncodeindex tp cp + +@include version.texi + +@copying + +This manual is for Libffi, a portable foreign-function interface +library. + +Copyright @copyright{} 2008, 2010, 2011 Red Hat, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. A copy of the license is included in the +section entitled ``GNU General Public License''. + +@end quotation +@end copying + +@dircategory Development +@direntry +* libffi: (libffi). Portable foreign-function interface library. +@end direntry + +@titlepage +@title Libffi +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + + +@ifnottex +@node Top +@top libffi + +@insertcopying + +@menu +* Introduction:: What is libffi? +* Using libffi:: How to use libffi. +* Missing Features:: Things libffi can't do. +* Index:: Index. +@end menu + +@end ifnottex + + +@node Introduction +@chapter What is libffi? + +Compilers for high level languages generate code that follow certain +conventions. These conventions are necessary, in part, for separate +compilation to work. One such convention is the @dfn{calling +convention}. The calling convention is a set of assumptions made by +the compiler about where function arguments will be found on entry to +a function. A calling convention also specifies where the return +value for a function is found. The calling convention is also +sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}. +@cindex calling convention +@cindex ABI +@cindex Application Binary Interface + +Some programs may not know at the time of compilation what arguments +are to be passed to a function. For instance, an interpreter may be +told at run-time about the number and types of arguments used to call +a given function. @samp{Libffi} can be used in such programs to +provide a bridge from the interpreter program to compiled code. + +The @samp{libffi} library provides a portable, high level programming +interface to various calling conventions. This allows a programmer to +call any function specified by a call interface description at run +time. + +@acronym{FFI} stands for Foreign Function Interface. A foreign +function interface is the popular name for the interface that allows +code written in one language to call code written in another language. +The @samp{libffi} library really only provides the lowest, machine +dependent layer of a fully featured foreign function interface. A +layer must exist above @samp{libffi} that handles type conversions for +values passed between the two languages. +@cindex FFI +@cindex Foreign Function Interface + + +@node Using libffi +@chapter Using libffi + +@menu +* The Basics:: The basic libffi API. +* Simple Example:: A simple example. +* Types:: libffi type descriptions. +* Multiple ABIs:: Different passing styles on one platform. +* The Closure API:: Writing a generic function. +* Closure Example:: A closure example. +@end menu + + +@node The Basics +@section The Basics + +@samp{Libffi} assumes that you have a pointer to the function you wish +to call and that you know the number and types of arguments to pass +it, as well as the return type of the function. + +The first thing you must do is create an @code{ffi_cif} object that +matches the signature of the function you wish to call. This is a +separate step because it is common to make multiple calls using a +single @code{ffi_cif}. The @dfn{cif} in @code{ffi_cif} stands for +Call InterFace. To prepare a call interface object, use the function +@code{ffi_prep_cif}. +@cindex cif + +@findex ffi_prep_cif +@defun ffi_status ffi_prep_cif (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes}) +This initializes @var{cif} according to the given parameters. + +@var{abi} is the ABI to use; normally @code{FFI_DEFAULT_ABI} is what +you want. @ref{Multiple ABIs} for more information. + +@var{nargs} is the number of arguments that this function accepts. + +@var{rtype} is a pointer to an @code{ffi_type} structure that +describes the return type of the function. @xref{Types}. + +@var{argtypes} is a vector of @code{ffi_type} pointers. +@var{argtypes} must have @var{nargs} elements. If @var{nargs} is 0, +this argument is ignored. + +@code{ffi_prep_cif} returns a @code{libffi} status code, of type +@code{ffi_status}. This will be either @code{FFI_OK} if everything +worked properly; @code{FFI_BAD_TYPEDEF} if one of the @code{ffi_type} +objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter +is invalid. +@end defun + +If the function being called is variadic (varargs) then +@code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}. + +@findex ffi_prep_cif_var +@defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nfixedargs}, unsigned int @var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes}) +This initializes @var{cif} according to the given parameters for +a call to a variadic function. In general it's operation is the +same as for @code{ffi_prep_cif} except that: + +@var{nfixedargs} is the number of fixed arguments, prior to any +variadic arguments. It must be greater than zero. + +@var{ntotalargs} the total number of arguments, including variadic +and fixed arguments. @var{argtypes} must have this many elements. + +Note that, different cif's must be prepped for calls to the same +function when different numbers of arguments are passed. + +Also note that a call to @code{ffi_prep_cif_var} with +@var{nfixedargs}=@var{nototalargs} is NOT equivalent to a call to +@code{ffi_prep_cif}. + +@end defun + + +To call a function using an initialized @code{ffi_cif}, use the +@code{ffi_call} function: + +@findex ffi_call +@defun void ffi_call (ffi_cif *@var{cif}, void *@var{fn}, void *@var{rvalue}, void **@var{avalues}) +This calls the function @var{fn} according to the description given in +@var{cif}. @var{cif} must have already been prepared using +@code{ffi_prep_cif}. + +@var{rvalue} is a pointer to a chunk of memory that will hold the +result of the function call. This must be large enough to hold the +result, no smaller than the system register size (generally 32 or 64 +bits), and must be suitably aligned; it is the caller's responsibility +to ensure this. If @var{cif} declares that the function returns +@code{void} (using @code{ffi_type_void}), then @var{rvalue} is +ignored. + +@var{avalues} is a vector of @code{void *} pointers that point to the +memory locations holding the argument values for a call. If @var{cif} +declares that the function has no arguments (i.e., @var{nargs} was 0), +then @var{avalues} is ignored. Note that argument values may be +modified by the callee (for instance, structs passed by value); the +burden of copying pass-by-value arguments is placed on the caller. +@end defun + + +@node Simple Example +@section Simple Example + +Here is a trivial example that calls @code{puts} a few times. + +@example +#include +#include + +int main() +@{ + ffi_cif cif; + ffi_type *args[1]; + void *values[1]; + char *s; + ffi_arg rc; + + /* Initialize the argument info vectors */ + args[0] = &ffi_type_pointer; + values[0] = &s; + + /* Initialize the cif */ + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, args) == FFI_OK) + @{ + s = "Hello World!"; + ffi_call(&cif, puts, &rc, values); + /* rc now holds the result of the call to puts */ + + /* values holds a pointer to the function's arg, so to + call puts() again all we need to do is change the + value of s */ + s = "This is cool!"; + ffi_call(&cif, puts, &rc, values); + @} + + return 0; +@} +@end example + + +@node Types +@section Types + +@menu +* Primitive Types:: Built-in types. +* Structures:: Structure types. +* Type Example:: Structure type example. +* Complex:: Complex types. +* Complex Type Example:: Complex type example. +@end menu + +@node Primitive Types +@subsection Primitive Types + +@code{Libffi} provides a number of built-in type descriptors that can +be used to describe argument and return types: + +@table @code +@item ffi_type_void +@tindex ffi_type_void +The type @code{void}. This cannot be used for argument types, only +for return values. + +@item ffi_type_uint8 +@tindex ffi_type_uint8 +An unsigned, 8-bit integer type. + +@item ffi_type_sint8 +@tindex ffi_type_sint8 +A signed, 8-bit integer type. + +@item ffi_type_uint16 +@tindex ffi_type_uint16 +An unsigned, 16-bit integer type. + +@item ffi_type_sint16 +@tindex ffi_type_sint16 +A signed, 16-bit integer type. + +@item ffi_type_uint32 +@tindex ffi_type_uint32 +An unsigned, 32-bit integer type. + +@item ffi_type_sint32 +@tindex ffi_type_sint32 +A signed, 32-bit integer type. + +@item ffi_type_uint64 +@tindex ffi_type_uint64 +An unsigned, 64-bit integer type. + +@item ffi_type_sint64 +@tindex ffi_type_sint64 +A signed, 64-bit integer type. + +@item ffi_type_float +@tindex ffi_type_float +The C @code{float} type. + +@item ffi_type_double +@tindex ffi_type_double +The C @code{double} type. + +@item ffi_type_uchar +@tindex ffi_type_uchar +The C @code{unsigned char} type. + +@item ffi_type_schar +@tindex ffi_type_schar +The C @code{signed char} type. (Note that there is not an exact +equivalent to the C @code{char} type in @code{libffi}; ordinarily you +should either use @code{ffi_type_schar} or @code{ffi_type_uchar} +depending on whether @code{char} is signed.) + +@item ffi_type_ushort +@tindex ffi_type_ushort +The C @code{unsigned short} type. + +@item ffi_type_sshort +@tindex ffi_type_sshort +The C @code{short} type. + +@item ffi_type_uint +@tindex ffi_type_uint +The C @code{unsigned int} type. + +@item ffi_type_sint +@tindex ffi_type_sint +The C @code{int} type. + +@item ffi_type_ulong +@tindex ffi_type_ulong +The C @code{unsigned long} type. + +@item ffi_type_slong +@tindex ffi_type_slong +The C @code{long} type. + +@item ffi_type_longdouble +@tindex ffi_type_longdouble +On platforms that have a C @code{long double} type, this is defined. +On other platforms, it is not. + +@item ffi_type_pointer +@tindex ffi_type_pointer +A generic @code{void *} pointer. You should use this for all +pointers, regardless of their real type. + +@item ffi_type_complex_float +@tindex ffi_type_complex_float +The C @code{_Complex float} type. + +@item ffi_type_complex_double +@tindex ffi_type_complex_double +The C @code{_Complex double} type. + +@item ffi_type_complex_longdouble +@tindex ffi_type_complex_longdouble +The C @code{_Complex long double} type. +On platforms that have a C @code{long double} type, this is defined. +On other platforms, it is not. +@end table + +Each of these is of type @code{ffi_type}, so you must take the address +when passing to @code{ffi_prep_cif}. + + +@node Structures +@subsection Structures + +Although @samp{libffi} has no special support for unions or +bit-fields, it is perfectly happy passing structures back and forth. +You must first describe the structure to @samp{libffi} by creating a +new @code{ffi_type} object for it. + +@tindex ffi_type +@deftp {Data type} ffi_type +The @code{ffi_type} has the following members: +@table @code +@item size_t size +This is set by @code{libffi}; you should initialize it to zero. + +@item unsigned short alignment +This is set by @code{libffi}; you should initialize it to zero. + +@item unsigned short type +For a structure, this should be set to @code{FFI_TYPE_STRUCT}. + +@item ffi_type **elements +This is a @samp{NULL}-terminated array of pointers to @code{ffi_type} +objects. There is one element per field of the struct. +@end table +@end deftp + + +@node Type Example +@subsection Type Example + +The following example initializes a @code{ffi_type} object +representing the @code{tm} struct from Linux's @file{time.h}. + +Here is how the struct is defined: + +@example +struct tm @{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + /* Those are for future use. */ + long int __tm_gmtoff__; + __const char *__tm_zone__; +@}; +@end example + +Here is the corresponding code to describe this struct to +@code{libffi}: + +@example + @{ + ffi_type tm_type; + ffi_type *tm_type_elements[12]; + int i; + + tm_type.size = tm_type.alignment = 0; + tm_type.type = FFI_TYPE_STRUCT; + tm_type.elements = &tm_type_elements; + + for (i = 0; i < 9; i++) + tm_type_elements[i] = &ffi_type_sint; + + tm_type_elements[9] = &ffi_type_slong; + tm_type_elements[10] = &ffi_type_pointer; + tm_type_elements[11] = NULL; + + /* tm_type can now be used to represent tm argument types and + return types for ffi_prep_cif() */ + @} +@end example + +@node Complex +@subsection Complex Types + +@samp{libffi} supports the complex types defined by the C99 +standard (@code{_Complex float}, @code{_Complex double} and +@code{_Complex long double} with the built-in type descriptors +@code{ffi_type_complex_float}, @code{ffi_type_complex_double} and +@code{ffi_type_complex_longdouble}. + +Custom complex types like @code{_Complex int} can also be used. +An @code{ffi_type} object has to be defined to describe the +complex type to @samp{libffi}. + +@tindex ffi_type +@deftp {Data type} ffi_type +@table @code +@item size_t size +This must be manually set to the size of the complex type. + +@item unsigned short alignment +This must be manually set to the alignment of the complex type. + +@item unsigned short type +For a complex type, this must be set to @code{FFI_TYPE_COMPLEX}. + +@item ffi_type **elements + +This is a @samp{NULL}-terminated array of pointers to +@code{ffi_type} objects. The first element is set to the +@code{ffi_type} of the complex's base type. The second element +must be set to @code{NULL}. +@end table +@end deftp + +The section @ref{Complex Type Example} shows a way to determine +the @code{size} and @code{alignment} members in a platform +independent way. + +For platforms that have no complex support in @code{libffi} yet, +the functions @code{ffi_prep_cif} and @code{ffi_prep_args} abort +the program if they encounter a complex type. + +@node Complex Type Example +@subsection Complex Type Example + +This example demonstrates how to use complex types: + +@example +#include +#include +#include + +void complex_fn(_Complex float cf, + _Complex double cd, + _Complex long double cld) +@{ + printf("cf=%f+%fi\ncd=%f+%fi\ncld=%f+%fi\n", + (float)creal (cf), (float)cimag (cf), + (float)creal (cd), (float)cimag (cd), + (float)creal (cld), (float)cimag (cld)); +@} + +int main() +@{ + ffi_cif cif; + ffi_type *args[3]; + void *values[3]; + _Complex float cf; + _Complex double cd; + _Complex long double cld; + + /* Initialize the argument info vectors */ + args[0] = &ffi_type_complex_float; + args[1] = &ffi_type_complex_double; + args[2] = &ffi_type_complex_longdouble; + values[0] = &cf; + values[1] = &cd; + values[2] = &cld; + + /* Initialize the cif */ + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &ffi_type_void, args) == FFI_OK) + @{ + cf = 1.0 + 20.0 * I; + cd = 300.0 + 4000.0 * I; + cld = 50000.0 + 600000.0 * I; + /* Call the function */ + ffi_call(&cif, (void (*)(void))complex_fn, 0, values); + @} + + return 0; +@} +@end example + +This is an example for defining a custom complex type descriptor +for compilers that support them: + +@example +/* + * This macro can be used to define new complex type descriptors + * in a platform independent way. + * + * name: Name of the new descriptor is ffi_type_complex_. + * type: The C base type of the complex type. + */ +#define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \ + static ffi_type *ffi_elements_complex_##name [2] = @{ \ + (ffi_type *)(&ffitype), NULL \ + @}; \ + struct struct_align_complex_##name @{ \ + char c; \ + _Complex type x; \ + @}; \ + ffi_type ffi_type_complex_##name = @{ \ + sizeof(_Complex type), \ + offsetof(struct struct_align_complex_##name, x), \ + FFI_TYPE_COMPLEX, \ + (ffi_type **)ffi_elements_complex_##name \ + @} + +/* Define new complex type descriptors using the macro: */ +/* ffi_type_complex_sint */ +FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint); +/* ffi_type_complex_uchar */ +FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8); +@end example + +The new type descriptors can then be used like one of the built-in +type descriptors in the previous example. + +@node Multiple ABIs +@section Multiple ABIs + +A given platform may provide multiple different ABIs at once. For +instance, the x86 platform has both @samp{stdcall} and @samp{fastcall} +functions. + +@code{libffi} provides some support for this. However, this is +necessarily platform-specific. + +@c FIXME: document the platforms + +@node The Closure API +@section The Closure API + +@code{libffi} also provides a way to write a generic function -- a +function that can accept and decode any combination of arguments. +This can be useful when writing an interpreter, or to provide wrappers +for arbitrary functions. + +This facility is called the @dfn{closure API}. Closures are not +supported on all platforms; you can check the @code{FFI_CLOSURES} +define to determine whether they are supported on the current +platform. +@cindex closures +@cindex closure API +@findex FFI_CLOSURES + +Because closures work by assembling a tiny function at runtime, they +require special allocation on platforms that have a non-executable +heap. Memory management for closures is handled by a pair of +functions: + +@findex ffi_closure_alloc +@defun void *ffi_closure_alloc (size_t @var{size}, void **@var{code}) +Allocate a chunk of memory holding @var{size} bytes. This returns a +pointer to the writable address, and sets *@var{code} to the +corresponding executable address. + +@var{size} should be sufficient to hold a @code{ffi_closure} object. +@end defun + +@findex ffi_closure_free +@defun void ffi_closure_free (void *@var{writable}) +Free memory allocated using @code{ffi_closure_alloc}. The argument is +the writable address that was returned. +@end defun + + +Once you have allocated the memory for a closure, you must construct a +@code{ffi_cif} describing the function call. Finally you can prepare +the closure function: + +@findex ffi_prep_closure_loc +@defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc}) +Prepare a closure function. + +@var{closure} is the address of a @code{ffi_closure} object; this is +the writable address returned by @code{ffi_closure_alloc}. + +@var{cif} is the @code{ffi_cif} describing the function parameters. + +@var{user_data} is an arbitrary datum that is passed, uninterpreted, +to your closure function. + +@var{codeloc} is the executable address returned by +@code{ffi_closure_alloc}. + +@var{fun} is the function which will be called when the closure is +invoked. It is called with the arguments: +@table @var +@item cif +The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}. + +@item ret +A pointer to the memory used for the function's return value. +@var{fun} must fill this, unless the function is declared as returning +@code{void}. +@c FIXME: is this NULL for void-returning functions? + +@item args +A vector of pointers to memory holding the arguments to the function. + +@item user_data +The same @var{user_data} that was passed to +@code{ffi_prep_closure_loc}. +@end table + +@code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything +went ok, and something else on error. +@c FIXME: what? + +After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc} +to the appropriate pointer-to-function type. +@end defun + +You may see old code referring to @code{ffi_prep_closure}. This +function is deprecated, as it cannot handle the need for separate +writable and executable addresses. + +@node Closure Example +@section Closure Example + +A trivial example that creates a new @code{puts} by binding +@code{fputs} with @code{stdout}. + +@example +#include +#include + +/* Acts like puts with the file given at time of enclosure. */ +void puts_binding(ffi_cif *cif, void *ret, void* args[], + void *stream) +@{ + *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream); +@} + +typedef int (*puts_t)(char *); + +int main() +@{ + ffi_cif cif; + ffi_type *args[1]; + ffi_closure *closure; + + void *bound_puts; + int rc; + + /* Allocate closure and bound_puts */ + closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts); + + if (closure) + @{ + /* Initialize the argument info vectors */ + args[0] = &ffi_type_pointer; + + /* Initialize the cif */ + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, args) == FFI_OK) + @{ + /* Initialize the closure, setting stream to stdout */ + if (ffi_prep_closure_loc(closure, &cif, puts_binding, + stdout, bound_puts) == FFI_OK) + @{ + rc = ((puts_t)bound_puts)("Hello World!"); + /* rc now holds the result of the call to fputs */ + @} + @} + @} + + /* Deallocate both closure, and bound_puts */ + ffi_closure_free(closure); + + return 0; +@} + +@end example + + +@node Missing Features +@chapter Missing Features + +@code{libffi} is missing a few features. We welcome patches to add +support for these. + +@itemize @bullet +@item +Variadic closures. + +@item +There is no support for bit fields in structures. + +@item +The ``raw'' API is undocumented. +@c argument promotion? +@c unions? +@c anything else? +@end itemize + +Note that variadic support is very new and tested on a relatively +small number of platforms. + +@node Index +@unnumbered Index + +@printindex cp + +@bye diff --git a/circuitpython/lib/libffi/doc/version.texi b/circuitpython/lib/libffi/doc/version.texi new file mode 100644 index 0000000..ccef70f --- /dev/null +++ b/circuitpython/lib/libffi/doc/version.texi @@ -0,0 +1,4 @@ +@set UPDATED 8 November 2014 +@set UPDATED-MONTH November 2014 +@set EDITION 3.2.1 +@set VERSION 3.2.1 diff --git a/circuitpython/lib/libffi/generate-darwin-source-and-headers.py b/circuitpython/lib/libffi/generate-darwin-source-and-headers.py new file mode 100644 index 0000000..f551c35 --- /dev/null +++ b/circuitpython/lib/libffi/generate-darwin-source-and-headers.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +import subprocess +import os +import errno +import collections +import glob +import argparse + +class Platform(object): + pass + +class simulator_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphonesimulator' + arch = 'i386' + triple = 'i386-apple-darwin11' + version_min = '-miphoneos-version-min=7.0' + + prefix = "#ifdef __i386__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['sysv.S', 'ffi.c'] + + +class simulator64_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphonesimulator' + arch = 'x86_64' + triple = 'x86_64-apple-darwin13' + version_min = '-miphoneos-version-min=7.0' + + prefix = "#ifdef __x86_64__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['unix64.S', 'ffi64.c'] + + +class device_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphoneos' + arch = 'armv7' + triple = 'arm-apple-darwin11' + version_min = '-miphoneos-version-min=7.0' + + prefix = "#ifdef __arm__\n\n" + suffix = "\n\n#endif" + src_dir = 'arm' + src_files = ['sysv.S', 'trampoline.S', 'ffi.c'] + + +class device64_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphoneos' + arch = 'arm64' + triple = 'aarch64-apple-darwin13' + version_min = '-miphoneos-version-min=7.0' + + prefix = "#ifdef __arm64__\n\n" + suffix = "\n\n#endif" + src_dir = 'aarch64' + src_files = ['sysv.S', 'ffi.c'] + + +class desktop32_platform(Platform): + directory = 'darwin_osx' + sdk = 'macosx' + arch = 'i386' + triple = 'i386-apple-darwin10' + version_min = '-mmacosx-version-min=10.6' + src_dir = 'x86' + src_files = ['sysv.S', 'ffi.c'] + + prefix = "#ifdef __i386__\n\n" + suffix = "\n\n#endif" + + +class desktop64_platform(Platform): + directory = 'darwin_osx' + sdk = 'macosx' + arch = 'x86_64' + triple = 'x86_64-apple-darwin10' + version_min = '-mmacosx-version-min=10.6' + + prefix = "#ifdef __x86_64__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['unix64.S', 'ffi64.c'] + + +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: # Python >2.5 + if exc.errno == errno.EEXIST: + pass + else: + raise + + +def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): + mkdir_p(dst_dir) + out_filename = filename + + if file_suffix: + split_name = os.path.splitext(filename) + out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) + + with open(os.path.join(src_dir, filename)) as in_file: + with open(os.path.join(dst_dir, out_filename), 'w') as out_file: + if prefix: + out_file.write(prefix) + + out_file.write(in_file.read()) + + if suffix: + out_file.write(suffix) + + +def list_files(src_dir, pattern=None, filelist=None): + if pattern: filelist = glob.iglob(os.path.join(src_dir, pattern)) + for file in filelist: + yield os.path.basename(file) + + +def copy_files(src_dir, dst_dir, pattern=None, filelist=None, file_suffix=None, prefix=None, suffix=None): + for filename in list_files(src_dir, pattern=pattern, filelist=filelist): + move_file(src_dir, dst_dir, filename, file_suffix=file_suffix, prefix=prefix, suffix=suffix) + + +def copy_src_platform_files(platform): + src_dir = os.path.join('src', platform.src_dir) + dst_dir = os.path.join(platform.directory, 'src', platform.src_dir) + copy_files(src_dir, dst_dir, filelist=platform.src_files, file_suffix=platform.arch, prefix=platform.prefix, suffix=platform.suffix) + + +def build_target(platform, platform_headers): + def xcrun_cmd(cmd): + return 'xcrun -sdk %s %s -arch %s' % (platform.sdk, cmd, platform.arch) + + tag='%s-%s' % (platform.sdk, platform.arch) + build_dir = 'build_%s' % tag + mkdir_p(build_dir) + env = dict(CC=xcrun_cmd('clang'), + LD=xcrun_cmd('ld'), + CFLAGS='%s' % (platform.version_min)) + working_dir = os.getcwd() + try: + os.chdir(build_dir) + subprocess.check_call(['../configure', '-host', platform.triple], env=env) + finally: + os.chdir(working_dir) + + for src_dir in [build_dir, os.path.join(build_dir, 'include')]: + copy_files(src_dir, + os.path.join(platform.directory, 'include'), + pattern='*.h', + file_suffix=platform.arch, + prefix=platform.prefix, + suffix=platform.suffix) + + for filename in list_files(src_dir, pattern='*.h'): + platform_headers[filename].add((platform.prefix, platform.arch, platform.suffix)) + + +def make_tramp(): + with open('src/arm/trampoline.S', 'w') as tramp_out: + p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out) + p.wait() + + +def generate_source_and_headers(generate_osx=True, generate_ios=True): + copy_files('src', 'darwin_common/src', pattern='*.c') + copy_files('include', 'darwin_common/include', pattern='*.h') + + if generate_ios: + make_tramp() + copy_src_platform_files(simulator_platform) + copy_src_platform_files(simulator64_platform) + copy_src_platform_files(device_platform) + copy_src_platform_files(device64_platform) + if generate_osx: + copy_src_platform_files(desktop32_platform) + copy_src_platform_files(desktop64_platform) + + platform_headers = collections.defaultdict(set) + + if generate_ios: + build_target(simulator_platform, platform_headers) + build_target(simulator64_platform, platform_headers) + build_target(device_platform, platform_headers) + build_target(device64_platform, platform_headers) + if generate_osx: + build_target(desktop32_platform, platform_headers) + build_target(desktop64_platform, platform_headers) + + mkdir_p('darwin_common/include') + for header_name, tag_tuples in platform_headers.iteritems(): + basename, suffix = os.path.splitext(header_name) + with open(os.path.join('darwin_common/include', header_name), 'w') as header: + for tag_tuple in tag_tuples: + header.write('%s#include <%s_%s%s>\n%s\n' % (tag_tuple[0], basename, tag_tuple[1], suffix, tag_tuple[2])) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--only-ios', action='store_true', default=False) + parser.add_argument('--only-osx', action='store_true', default=False) + args = parser.parse_args() + + generate_source_and_headers(generate_osx=not args.only_ios, generate_ios=not args.only_osx) diff --git a/circuitpython/lib/libffi/include/Makefile.am b/circuitpython/lib/libffi/include/Makefile.am new file mode 100644 index 0000000..bb241e8 --- /dev/null +++ b/circuitpython/lib/libffi/include/Makefile.am @@ -0,0 +1,10 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS=foreign + +DISTCLEANFILES=ffitarget.h +noinst_HEADERS=ffi_common.h ffi_cfi.h +EXTRA_DIST=ffi.h.in + +includesdir = $(libdir)/@PACKAGE_NAME@-@PACKAGE_VERSION@/include +nodist_includes_HEADERS = ffi.h ffitarget.h diff --git a/circuitpython/lib/libffi/include/ffi.h.in b/circuitpython/lib/libffi/include/ffi.h.in new file mode 100644 index 0000000..c43d52f --- /dev/null +++ b/circuitpython/lib/libffi/include/ffi.h.in @@ -0,0 +1,503 @@ +/* -----------------------------------------------------------------*-C-*- + libffi @VERSION@ - Copyright (c) 2011, 2014 Anthony Green + - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc. + + 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. + + ----------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------- + The basic API is described in the README file. + + The raw API is designed to bypass some of the argument packing + and unpacking on architectures for which it can be avoided. + + The closure API allows interpreted functions to be packaged up + inside a C function pointer, so that they can be called as C functions, + with no understanding on the client side that they are interpreted. + It can also be used in other cases in which it is necessary to package + up a user specified parameter and a function pointer as a single + function pointer. + + The closure API must be implemented in order to get its functionality, + e.g. for use by gij. Routines are provided to emulate the raw API + if the underlying platform doesn't allow faster implementation. + + More details on the raw and cloure API can be found in: + + http://gcc.gnu.org/ml/java/1999-q3/msg00138.html + + and + + http://gcc.gnu.org/ml/java/1999-q3/msg00174.html + -------------------------------------------------------------------- */ + +#ifndef LIBFFI_H +#define LIBFFI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Specify which architecture libffi is configured for. */ +#ifndef @TARGET@ +#define @TARGET@ +#endif + +/* ---- System configuration information --------------------------------- */ + +#include + +#ifndef LIBFFI_ASM + +#if defined(_MSC_VER) && !defined(__clang__) +#define __attribute__(X) +#endif + +#include +#include + +/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). + But we can find it either under the correct ANSI name, or under GNU + C's internal name. */ + +#define FFI_64_BIT_MAX 9223372036854775807 + +#ifdef LONG_LONG_MAX +# define FFI_LONG_LONG_MAX LONG_LONG_MAX +#else +# ifdef LLONG_MAX +# define FFI_LONG_LONG_MAX LLONG_MAX +# ifdef _AIX52 /* or newer has C99 LLONG_MAX */ +# undef FFI_64_BIT_MAX +# define FFI_64_BIT_MAX 9223372036854775807LL +# endif /* _AIX52 or newer */ +# else +# ifdef __GNUC__ +# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ +# endif +# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */ +# ifndef __PPC64__ +# if defined (__IBMC__) || defined (__IBMCPP__) +# define FFI_LONG_LONG_MAX LONGLONG_MAX +# endif +# endif /* __PPC64__ */ +# undef FFI_64_BIT_MAX +# define FFI_64_BIT_MAX 9223372036854775807LL +# endif +# endif +#endif + +/* The closure code assumes that this works on pointers, i.e. a size_t */ +/* can hold a pointer. */ + +typedef struct _ffi_type +{ + size_t size; + unsigned short alignment; + unsigned short type; + struct _ffi_type **elements; +} ffi_type; + +#ifndef LIBFFI_HIDE_BASIC_TYPES +#if SCHAR_MAX == 127 +# define ffi_type_uchar ffi_type_uint8 +# define ffi_type_schar ffi_type_sint8 +#else + #error "char size not supported" +#endif + +#if SHRT_MAX == 32767 +# define ffi_type_ushort ffi_type_uint16 +# define ffi_type_sshort ffi_type_sint16 +#elif SHRT_MAX == 2147483647 +# define ffi_type_ushort ffi_type_uint32 +# define ffi_type_sshort ffi_type_sint32 +#else + #error "short size not supported" +#endif + +#if INT_MAX == 32767 +# define ffi_type_uint ffi_type_uint16 +# define ffi_type_sint ffi_type_sint16 +#elif INT_MAX == 2147483647 +# define ffi_type_uint ffi_type_uint32 +# define ffi_type_sint ffi_type_sint32 +#elif INT_MAX == 9223372036854775807 +# define ffi_type_uint ffi_type_uint64 +# define ffi_type_sint ffi_type_sint64 +#else + #error "int size not supported" +#endif + +#if LONG_MAX == 2147483647 +# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX + #error "no 64-bit data type supported" +# endif +#elif LONG_MAX != FFI_64_BIT_MAX + #error "long size not supported" +#endif + +#if LONG_MAX == 2147483647 +# define ffi_type_ulong ffi_type_uint32 +# define ffi_type_slong ffi_type_sint32 +#elif LONG_MAX == FFI_64_BIT_MAX +# define ffi_type_ulong ffi_type_uint64 +# define ffi_type_slong ffi_type_sint64 +#else + #error "long size not supported" +#endif + +/* Need minimal decorations for DLLs to works on Windows. */ +/* GCC has autoimport and autoexport. Rely on Libtool to */ +/* help MSVC export from a DLL, but always declare data */ +/* to be imported for MSVC clients. This costs an extra */ +/* indirection for MSVC clients using the static version */ +/* of the library, but don't worry about that. Besides, */ +/* as a workaround, they can define FFI_BUILDING if they */ +/* *know* they are going to link with the static library. */ +#if defined _MSC_VER && !defined FFI_BUILDING +#define FFI_EXTERN extern __declspec(dllimport) +#else +#define FFI_EXTERN extern +#endif + +/* These are defined in types.c */ +FFI_EXTERN ffi_type ffi_type_void; +FFI_EXTERN ffi_type ffi_type_uint8; +FFI_EXTERN ffi_type ffi_type_sint8; +FFI_EXTERN ffi_type ffi_type_uint16; +FFI_EXTERN ffi_type ffi_type_sint16; +FFI_EXTERN ffi_type ffi_type_uint32; +FFI_EXTERN ffi_type ffi_type_sint32; +FFI_EXTERN ffi_type ffi_type_uint64; +FFI_EXTERN ffi_type ffi_type_sint64; +FFI_EXTERN ffi_type ffi_type_float; +FFI_EXTERN ffi_type ffi_type_double; +FFI_EXTERN ffi_type ffi_type_pointer; + +#if @HAVE_LONG_DOUBLE@ +FFI_EXTERN ffi_type ffi_type_longdouble; +#else +#define ffi_type_longdouble ffi_type_double +#endif + +#ifdef FFI_TARGET_HAS_COMPLEX_TYPE +FFI_EXTERN ffi_type ffi_type_complex_float; +FFI_EXTERN ffi_type ffi_type_complex_double; +#if @HAVE_LONG_DOUBLE@ +FFI_EXTERN ffi_type ffi_type_complex_longdouble; +#else +#define ffi_type_complex_longdouble ffi_type_complex_double +#endif +#endif +#endif /* LIBFFI_HIDE_BASIC_TYPES */ + +typedef enum { + FFI_OK = 0, + FFI_BAD_TYPEDEF, + FFI_BAD_ABI +} ffi_status; + +typedef unsigned FFI_TYPE; + +typedef struct { + ffi_abi abi; + unsigned nargs; + ffi_type **arg_types; + ffi_type *rtype; + unsigned bytes; + unsigned flags; +#ifdef FFI_EXTRA_CIF_FIELDS + FFI_EXTRA_CIF_FIELDS; +#endif +} ffi_cif; + +#if @HAVE_LONG_DOUBLE_VARIANT@ +/* Used to adjust size/alignment of ffi types. */ +void ffi_prep_types (ffi_abi abi); +#endif + +/* Used internally, but overridden by some architectures */ +ffi_status ffi_prep_cif_core(ffi_cif *cif, + ffi_abi abi, + unsigned int isvariadic, + unsigned int nfixedargs, + unsigned int ntotalargs, + ffi_type *rtype, + ffi_type **atypes); + +/* ---- Definitions for the raw API -------------------------------------- */ + +#ifndef FFI_SIZEOF_ARG +# if LONG_MAX == 2147483647 +# define FFI_SIZEOF_ARG 4 +# elif LONG_MAX == FFI_64_BIT_MAX +# define FFI_SIZEOF_ARG 8 +# endif +#endif + +#ifndef FFI_SIZEOF_JAVA_RAW +# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG +#endif + +typedef union { + ffi_sarg sint; + ffi_arg uint; + float flt; + char data[FFI_SIZEOF_ARG]; + void* ptr; +} ffi_raw; + +#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8 +/* This is a special case for mips64/n32 ABI (and perhaps others) where + sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */ +typedef union { + signed int sint; + unsigned int uint; + float flt; + char data[FFI_SIZEOF_JAVA_RAW]; + void* ptr; +} ffi_java_raw; +#else +typedef ffi_raw ffi_java_raw; +#endif + + +void ffi_raw_call (ffi_cif *cif, + void (*fn)(void), + void *rvalue, + ffi_raw *avalue); + +void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); +void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); +size_t ffi_raw_size (ffi_cif *cif); + +/* This is analogous to the raw API, except it uses Java parameter */ +/* packing, even on 64-bit machines. I.e. on 64-bit machines */ +/* longs and doubles are followed by an empty 64-bit word. */ + +void ffi_java_raw_call (ffi_cif *cif, + void (*fn)(void), + void *rvalue, + ffi_java_raw *avalue); + +void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw); +void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args); +size_t ffi_java_raw_size (ffi_cif *cif); + +/* ---- Definitions for closures ----------------------------------------- */ + +#if FFI_CLOSURES + +#ifdef _MSC_VER +__declspec(align(8)) +#endif +typedef struct { +#if @FFI_EXEC_TRAMPOLINE_TABLE@ + void *trampoline_table; + void *trampoline_table_entry; +#else + char tramp[FFI_TRAMPOLINE_SIZE]; +#endif + ffi_cif *cif; + void (*fun)(ffi_cif*,void*,void**,void*); + void *user_data; +#ifdef __GNUC__ +} ffi_closure __attribute__((aligned (8))); +#else +} ffi_closure; +# ifdef __sgi +# pragma pack 0 +# endif +#endif + +void *ffi_closure_alloc (size_t size, void **code); +void ffi_closure_free (void *); + +ffi_status +ffi_prep_closure (ffi_closure*, + ffi_cif *, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data); + +ffi_status +ffi_prep_closure_loc (ffi_closure*, + ffi_cif *, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void*codeloc); + +#ifdef __sgi +# pragma pack 8 +#endif +typedef struct { +#if @FFI_EXEC_TRAMPOLINE_TABLE@ + void *trampoline_table; + void *trampoline_table_entry; +#else + char tramp[FFI_TRAMPOLINE_SIZE]; +#endif + ffi_cif *cif; + +#if !FFI_NATIVE_RAW_API + + /* if this is enabled, then a raw closure has the same layout + as a regular closure. We use this to install an intermediate + handler to do the transaltion, void** -> ffi_raw*. */ + + void (*translate_args)(ffi_cif*,void*,void**,void*); + void *this_closure; + +#endif + + void (*fun)(ffi_cif*,void*,ffi_raw*,void*); + void *user_data; + +} ffi_raw_closure; + +typedef struct { +#if @FFI_EXEC_TRAMPOLINE_TABLE@ + void *trampoline_table; + void *trampoline_table_entry; +#else + char tramp[FFI_TRAMPOLINE_SIZE]; +#endif + + ffi_cif *cif; + +#if !FFI_NATIVE_RAW_API + + /* if this is enabled, then a raw closure has the same layout + as a regular closure. We use this to install an intermediate + handler to do the transaltion, void** -> ffi_raw*. */ + + void (*translate_args)(ffi_cif*,void*,void**,void*); + void *this_closure; + +#endif + + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*); + void *user_data; + +} ffi_java_raw_closure; + +ffi_status +ffi_prep_raw_closure (ffi_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data); + +ffi_status +ffi_prep_raw_closure_loc (ffi_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc); + +ffi_status +ffi_prep_java_raw_closure (ffi_java_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), + void *user_data); + +ffi_status +ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), + void *user_data, + void *codeloc); + +#endif /* FFI_CLOSURES */ + +#if FFI_GO_CLOSURES + +typedef struct { + void *tramp; + ffi_cif *cif; + void (*fun)(ffi_cif*,void*,void**,void*); +} ffi_go_closure; + +ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *, + void (*fun)(ffi_cif*,void*,void**,void*)); + +void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure); + +#endif /* FFI_GO_CLOSURES */ + +/* ---- Public interface definition -------------------------------------- */ + +ffi_status ffi_prep_cif(ffi_cif *cif, + ffi_abi abi, + unsigned int nargs, + ffi_type *rtype, + ffi_type **atypes); + +ffi_status ffi_prep_cif_var(ffi_cif *cif, + ffi_abi abi, + unsigned int nfixedargs, + unsigned int ntotalargs, + ffi_type *rtype, + ffi_type **atypes); + +void ffi_call(ffi_cif *cif, + void (*fn)(void), + void *rvalue, + void **avalue); + +/* Useful for eliminating compiler warnings */ +#define FFI_FN(f) ((void (*)(void))f) + +/* ---- Definitions shared with assembly code ---------------------------- */ + +#endif + +/* If these change, update src/mips/ffitarget.h. */ +#define FFI_TYPE_VOID 0 +#define FFI_TYPE_INT 1 +#define FFI_TYPE_FLOAT 2 +#define FFI_TYPE_DOUBLE 3 +#if @HAVE_LONG_DOUBLE@ +#define FFI_TYPE_LONGDOUBLE 4 +#else +#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE +#endif +#define FFI_TYPE_UINT8 5 +#define FFI_TYPE_SINT8 6 +#define FFI_TYPE_UINT16 7 +#define FFI_TYPE_SINT16 8 +#define FFI_TYPE_UINT32 9 +#define FFI_TYPE_SINT32 10 +#define FFI_TYPE_UINT64 11 +#define FFI_TYPE_SINT64 12 +#define FFI_TYPE_STRUCT 13 +#define FFI_TYPE_POINTER 14 +#define FFI_TYPE_COMPLEX 15 + +/* This should always refer to the last type code (for sanity checks) */ +#define FFI_TYPE_LAST FFI_TYPE_COMPLEX + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/libffi/include/ffi_cfi.h b/circuitpython/lib/libffi/include/ffi_cfi.h new file mode 100644 index 0000000..244ce57 --- /dev/null +++ b/circuitpython/lib/libffi/include/ffi_cfi.h @@ -0,0 +1,55 @@ +/* ----------------------------------------------------------------------- + ffi_cfi.h - Copyright (c) 2014 Red Hat, Inc. + + Conditionally assemble cfi directives. Only necessary for building libffi. + ----------------------------------------------------------------------- */ + +#ifndef FFI_CFI_H +#define FFI_CFI_H + +#ifdef HAVE_AS_CFI_PSEUDO_OP + +# define cfi_startproc .cfi_startproc +# define cfi_endproc .cfi_endproc +# define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off +# define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg +# define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off +# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off +# define cfi_offset(reg, off) .cfi_offset reg, off +# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off +# define cfi_register(r1, r2) .cfi_register r1, r2 +# define cfi_return_column(reg) .cfi_return_column reg +# define cfi_restore(reg) .cfi_restore reg +# define cfi_same_value(reg) .cfi_same_value reg +# define cfi_undefined(reg) .cfi_undefined reg +# define cfi_remember_state .cfi_remember_state +# define cfi_restore_state .cfi_restore_state +# define cfi_window_save .cfi_window_save +# define cfi_personality(enc, exp) .cfi_personality enc, exp +# define cfi_lsda(enc, exp) .cfi_lsda enc, exp +# define cfi_escape(...) .cfi_escape __VA_ARGS__ + +#else + +# define cfi_startproc +# define cfi_endproc +# define cfi_def_cfa(reg, off) +# define cfi_def_cfa_register(reg) +# define cfi_def_cfa_offset(off) +# define cfi_adjust_cfa_offset(off) +# define cfi_offset(reg, off) +# define cfi_rel_offset(reg, off) +# define cfi_register(r1, r2) +# define cfi_return_column(reg) +# define cfi_restore(reg) +# define cfi_same_value(reg) +# define cfi_undefined(reg) +# define cfi_remember_state +# define cfi_restore_state +# define cfi_window_save +# define cfi_personality(enc, exp) +# define cfi_lsda(enc, exp) +# define cfi_escape(...) + +#endif /* HAVE_AS_CFI_PSEUDO_OP */ +#endif /* FFI_CFI_H */ diff --git a/circuitpython/lib/libffi/include/ffi_common.h b/circuitpython/lib/libffi/include/ffi_common.h new file mode 100644 index 0000000..37f5a9e --- /dev/null +++ b/circuitpython/lib/libffi/include/ffi_common.h @@ -0,0 +1,132 @@ +/* ----------------------------------------------------------------------- + ffi_common.h - Copyright (C) 2011, 2012, 2013 Anthony Green + Copyright (C) 2007 Free Software Foundation, Inc + Copyright (c) 1996 Red Hat, Inc. + + Common internal definitions and macros. Only necessary for building + libffi. + ----------------------------------------------------------------------- */ + +#ifndef FFI_COMMON_H +#define FFI_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Do not move this. Some versions of AIX are very picky about where + this is positioned. */ +#ifdef __GNUC__ +# if HAVE_ALLOCA_H +# include +# else + /* mingw64 defines this already in malloc.h. */ +# ifndef alloca +# define alloca __builtin_alloca +# endif +# endif +# define MAYBE_UNUSED __attribute__((__unused__)) +#else +# define MAYBE_UNUSED +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX +# pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +# ifdef _MSC_VER +# define alloca _alloca +# else +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +/* Check for the existence of memcpy. */ +#if STDC_HEADERS +# include +#else +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#if defined(FFI_DEBUG) +#include +#endif + +#ifdef FFI_DEBUG +void ffi_assert(char *expr, char *file, int line); +void ffi_stop_here(void); +void ffi_type_test(ffi_type *a, char *file, int line); + +#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) +#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) +#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) +#else +#define FFI_ASSERT(x) +#define FFI_ASSERT_AT(x, f, l) +#define FFI_ASSERT_VALID_TYPE(x) +#endif + +#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) +#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a) + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif); +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, + unsigned int nfixedargs, unsigned int ntotalargs); + +/* Extended cif, used in callback from assembly routine */ +typedef struct +{ + ffi_cif *cif; + void *rvalue; + void **avalue; +} extended_cif; + +/* Terse sized type definitions. */ +#if defined(_MSC_VER) || defined(__sgi) || defined(__SUNPRO_C) +typedef unsigned char UINT8; +typedef signed char SINT8; +typedef unsigned short UINT16; +typedef signed short SINT16; +typedef unsigned int UINT32; +typedef signed int SINT32; +# ifdef _MSC_VER +typedef unsigned __int64 UINT64; +typedef signed __int64 SINT64; +# else +# include +typedef uint64_t UINT64; +typedef int64_t SINT64; +# endif +#else +typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); +typedef signed int SINT8 __attribute__((__mode__(__QI__))); +typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); +typedef signed int SINT16 __attribute__((__mode__(__HI__))); +typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); +typedef signed int SINT32 __attribute__((__mode__(__SI__))); +typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); +typedef signed int SINT64 __attribute__((__mode__(__DI__))); +#endif + +typedef float FLOAT32; + +#ifndef __GNUC__ +#define __builtin_expect(x, expected_value) (x) +#endif +#define LIKELY(x) __builtin_expect(!!(x),1) +#define UNLIKELY(x) __builtin_expect((x)!=0,0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/libffi/libffi.pc.in b/circuitpython/lib/libffi/libffi.pc.in new file mode 100644 index 0000000..edf6fde --- /dev/null +++ b/circuitpython/lib/libffi/libffi.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +toolexeclibdir=@toolexeclibdir@ +includedir=${libdir}/@PACKAGE_NAME@-@PACKAGE_VERSION@/include + +Name: @PACKAGE_NAME@ +Description: Library supporting Foreign Function Interfaces +Version: @PACKAGE_VERSION@ +Libs: -L${toolexeclibdir} -lffi +Cflags: -I${includedir} diff --git a/circuitpython/lib/libffi/libffi.xcodeproj/project.pbxproj b/circuitpython/lib/libffi/libffi.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1cf396f --- /dev/null +++ b/circuitpython/lib/libffi/libffi.xcodeproj/project.pbxproj @@ -0,0 +1,637 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + DBFA714A187F1D8600A76262 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; }; + DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713F187F1D8600A76262 /* ffi_common.h */; }; + DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7140187F1D8600A76262 /* fficonfig.h */; }; + DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; }; + DBFA714E187F1D8600A76262 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; }; + DBFA714F187F1D8600A76262 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; }; + DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; }; + DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; }; + DBFA7158187F1D8600A76262 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; }; + DBFA7159187F1D8600A76262 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; }; + DBFA715A187F1D8600A76262 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; }; + DBFA715B187F1D8600A76262 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; }; + DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716C187F1D9B00A76262 /* ffi_arm64.c */; }; + DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716D187F1D9B00A76262 /* sysv_arm64.S */; }; + DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716F187F1D9B00A76262 /* ffi_armv7.c */; }; + DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7170187F1D9B00A76262 /* sysv_armv7.S */; }; + DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */; }; + DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */; }; + DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7174187F1D9B00A76262 /* darwin_i386.S */; }; + DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */; }; + DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7176187F1D9B00A76262 /* ffi_i386.c */; }; + DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7182187F1DA100A76262 /* ffi_i386.h */; }; + DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7183187F1DA100A76262 /* ffi_x86_64.h */; }; + DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7184187F1DA100A76262 /* fficonfig_i386.h */; }; + DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */; }; + DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7186187F1DA100A76262 /* ffitarget_i386.h */; }; + DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */; }; + DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */; }; + DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* darwin_i386.S */; }; + DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */; }; + DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718D187F1DA100A76262 /* ffi_i386.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + DB13B1641849DF1E0010F42D /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + DB13B1661849DF1E0010F42D /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DB13B1911849DF510010F42D /* ffi.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ffi.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + DBFA713E187F1D8600A76262 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; + DBFA713F187F1D8600A76262 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; + DBFA7140187F1D8600A76262 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; + DBFA7141187F1D8600A76262 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; + DBFA7143187F1D8600A76262 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = closures.c; sourceTree = ""; }; + DBFA7145187F1D8600A76262 /* dlmalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dlmalloc.c; sourceTree = ""; }; + DBFA7147187F1D8600A76262 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = prep_cif.c; sourceTree = ""; }; + DBFA7148187F1D8600A76262 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_api.c; sourceTree = ""; }; + DBFA7149187F1D8600A76262 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = types.c; sourceTree = ""; }; + DBFA715E187F1D9B00A76262 /* ffi_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_arm64.h; sourceTree = ""; }; + DBFA715F187F1D9B00A76262 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = ""; }; + DBFA7160187F1D9B00A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; + DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; + DBFA7162187F1D9B00A76262 /* fficonfig_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_arm64.h; sourceTree = ""; }; + DBFA7163187F1D9B00A76262 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = ""; }; + DBFA7164187F1D9B00A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; + DBFA7165187F1D9B00A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; + DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm64.h; sourceTree = ""; }; + DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = ""; }; + DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; + DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; + DBFA716C187F1D9B00A76262 /* ffi_arm64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_arm64.c; sourceTree = ""; }; + DBFA716D187F1D9B00A76262 /* sysv_arm64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_arm64.S; sourceTree = ""; }; + DBFA716F187F1D9B00A76262 /* ffi_armv7.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_armv7.c; sourceTree = ""; }; + DBFA7170187F1D9B00A76262 /* sysv_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_armv7.S; sourceTree = ""; }; + DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline_armv7.S; sourceTree = ""; }; + DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = ""; }; + DBFA7174187F1D9B00A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = ""; }; + DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = ""; }; + DBFA7176187F1D9B00A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = ""; }; + DBFA7182187F1DA100A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; + DBFA7183187F1DA100A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; + DBFA7184187F1DA100A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; + DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; + DBFA7186187F1DA100A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; + DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; + DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = ""; }; + DBFA718B187F1DA100A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = ""; }; + DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = ""; }; + DBFA718D187F1DA100A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + DB13B15B1849DEB70010F42D = { + isa = PBXGroup; + children = ( + DBFA713C187F1D8600A76262 /* darwin_common */, + DBFA715C187F1D9B00A76262 /* darwin_ios */, + DBFA7180187F1DA100A76262 /* darwin_osx */, + DB13B1671849DF1E0010F42D /* Products */, + ); + sourceTree = ""; + }; + DB13B1671849DF1E0010F42D /* Products */ = { + isa = PBXGroup; + children = ( + DB13B1661849DF1E0010F42D /* libffi.a */, + DB13B1911849DF510010F42D /* ffi.dylib */, + ); + name = Products; + sourceTree = ""; + }; + DBFA713C187F1D8600A76262 /* darwin_common */ = { + isa = PBXGroup; + children = ( + DBFA713D187F1D8600A76262 /* include */, + DBFA7142187F1D8600A76262 /* src */, + ); + path = "darwin_common"; + sourceTree = ""; + }; + DBFA713D187F1D8600A76262 /* include */ = { + isa = PBXGroup; + children = ( + DBFA713E187F1D8600A76262 /* ffi.h */, + DBFA713F187F1D8600A76262 /* ffi_common.h */, + DBFA7140187F1D8600A76262 /* fficonfig.h */, + DBFA7141187F1D8600A76262 /* ffitarget.h */, + ); + path = include; + sourceTree = ""; + }; + DBFA7142187F1D8600A76262 /* src */ = { + isa = PBXGroup; + children = ( + DBFA7143187F1D8600A76262 /* closures.c */, + DBFA7145187F1D8600A76262 /* dlmalloc.c */, + DBFA7147187F1D8600A76262 /* prep_cif.c */, + DBFA7148187F1D8600A76262 /* raw_api.c */, + DBFA7149187F1D8600A76262 /* types.c */, + ); + path = src; + sourceTree = ""; + }; + DBFA715C187F1D9B00A76262 /* darwin_ios */ = { + isa = PBXGroup; + children = ( + DBFA715D187F1D9B00A76262 /* include */, + DBFA716A187F1D9B00A76262 /* src */, + ); + path = "darwin_ios"; + sourceTree = ""; + }; + DBFA715D187F1D9B00A76262 /* include */ = { + isa = PBXGroup; + children = ( + DBFA715E187F1D9B00A76262 /* ffi_arm64.h */, + DBFA715F187F1D9B00A76262 /* ffi_armv7.h */, + DBFA7160187F1D9B00A76262 /* ffi_i386.h */, + DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */, + DBFA7162187F1D9B00A76262 /* fficonfig_arm64.h */, + DBFA7163187F1D9B00A76262 /* fficonfig_armv7.h */, + DBFA7164187F1D9B00A76262 /* fficonfig_i386.h */, + DBFA7165187F1D9B00A76262 /* fficonfig_x86_64.h */, + DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */, + DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */, + DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */, + DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */, + ); + path = include; + sourceTree = ""; + }; + DBFA716A187F1D9B00A76262 /* src */ = { + isa = PBXGroup; + children = ( + DBFA716B187F1D9B00A76262 /* aarch64 */, + DBFA716E187F1D9B00A76262 /* arm */, + DBFA7172187F1D9B00A76262 /* x86 */, + ); + path = src; + sourceTree = ""; + }; + DBFA716B187F1D9B00A76262 /* aarch64 */ = { + isa = PBXGroup; + children = ( + DBFA716C187F1D9B00A76262 /* ffi_arm64.c */, + DBFA716D187F1D9B00A76262 /* sysv_arm64.S */, + ); + path = aarch64; + sourceTree = ""; + }; + DBFA716E187F1D9B00A76262 /* arm */ = { + isa = PBXGroup; + children = ( + DBFA716F187F1D9B00A76262 /* ffi_armv7.c */, + DBFA7170187F1D9B00A76262 /* sysv_armv7.S */, + DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */, + ); + path = arm; + sourceTree = ""; + }; + DBFA7172187F1D9B00A76262 /* x86 */ = { + isa = PBXGroup; + children = ( + DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */, + DBFA7174187F1D9B00A76262 /* darwin_i386.S */, + DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */, + DBFA7176187F1D9B00A76262 /* ffi_i386.c */, + ); + path = x86; + sourceTree = ""; + }; + DBFA7180187F1DA100A76262 /* darwin_osx */ = { + isa = PBXGroup; + children = ( + DBFA7181187F1DA100A76262 /* include */, + DBFA7188187F1DA100A76262 /* src */, + ); + path = "darwin_osx"; + sourceTree = ""; + }; + DBFA7181187F1DA100A76262 /* include */ = { + isa = PBXGroup; + children = ( + DBFA7182187F1DA100A76262 /* ffi_i386.h */, + DBFA7183187F1DA100A76262 /* ffi_x86_64.h */, + DBFA7184187F1DA100A76262 /* fficonfig_i386.h */, + DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */, + DBFA7186187F1DA100A76262 /* ffitarget_i386.h */, + DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */, + ); + path = include; + sourceTree = ""; + }; + DBFA7188187F1DA100A76262 /* src */ = { + isa = PBXGroup; + children = ( + DBFA7189187F1DA100A76262 /* x86 */, + ); + path = src; + sourceTree = ""; + }; + DBFA7189187F1DA100A76262 /* x86 */ = { + isa = PBXGroup; + children = ( + DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */, + DBFA718B187F1DA100A76262 /* darwin_i386.S */, + DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */, + DBFA718D187F1DA100A76262 /* ffi_i386.c */, + ); + path = x86; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + DB13B18F1849DF510010F42D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */, + DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */, + DBFA714A187F1D8600A76262 /* ffi.h in Headers */, + DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */, + DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */, + DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */, + DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */, + DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */, + DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */, + DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + DB13B1651849DF1E0010F42D /* libffi-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */; + buildPhases = ( + DB13B3051849E01C0010F42D /* ShellScript */, + DB13B1621849DF1E0010F42D /* Sources */, + DB13B1641849DF1E0010F42D /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libffi-iOS"; + productName = ffi; + productReference = DB13B1661849DF1E0010F42D /* libffi.a */; + productType = "com.apple.product-type.library.static"; + }; + DB13B1901849DF510010F42D /* libffi-Mac */ = { + isa = PBXNativeTarget; + buildConfigurationList = DB13B1B01849DF520010F42D /* Build configuration list for PBXNativeTarget "libffi-Mac" */; + buildPhases = ( + DB13B3061849E0490010F42D /* ShellScript */, + DB13B18D1849DF510010F42D /* Sources */, + DB13B18F1849DF510010F42D /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libffi-Mac"; + productName = ffi; + productReference = DB13B1911849DF510010F42D /* ffi.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DB13B15C1849DEB70010F42D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + }; + buildConfigurationList = DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = DB13B15B1849DEB70010F42D; + productRefGroup = DB13B1671849DF1E0010F42D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DB13B1651849DF1E0010F42D /* libffi-iOS */, + DB13B1901849DF510010F42D /* libffi-Mac */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXShellScriptBuildPhase section */ + DB13B3051849E01C0010F42D /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-ios"; + }; + DB13B3061849E0490010F42D /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-osx"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + DB13B1621849DF1E0010F42D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */, + DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */, + DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */, + DBFA714E187F1D8600A76262 /* closures.c in Sources */, + DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */, + DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */, + DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */, + DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */, + DBFA7158187F1D8600A76262 /* raw_api.c in Sources */, + DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */, + DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */, + DBFA715A187F1D8600A76262 /* types.c in Sources */, + DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DB13B18D1849DF510010F42D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */, + DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */, + DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */, + DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */, + DBFA715B187F1D8600A76262 /* types.c in Sources */, + DBFA7159187F1D8600A76262 /* raw_api.c in Sources */, + DBFA714F187F1D8600A76262 /* closures.c in Sources */, + DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + DB13B1601849DEB70010F42D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_common/include", + ); + ONLY_ACTIVE_ARCH = YES; + }; + name = Debug; + }; + DB13B1611849DEB70010F42D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_common/include", + ); + }; + name = Release; + }; + DB13B1871849DF1E0010F42D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ffi.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_ios/include", + ); + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + "IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = ffi; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + DB13B1881849DF1E0010F42D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ffi.dst; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_ios/include", + ); + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + "IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = ffi; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + DB13B1B11849DF520010F42D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_osx/include", + ); + MACOSX_DEPLOYMENT_TARGET = 10.6; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "-Wl,-no_compact_unwind"; + PRODUCT_NAME = ffi; + SDKROOT = macosx; + }; + name = Debug; + }; + DB13B1B21849DF520010F42D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_osx/include", + ); + MACOSX_DEPLOYMENT_TARGET = 10.6; + OTHER_LDFLAGS = "-Wl,-no_compact_unwind"; + PRODUCT_NAME = ffi; + SDKROOT = macosx; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB13B1601849DEB70010F42D /* Debug */, + DB13B1611849DEB70010F42D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB13B1871849DF1E0010F42D /* Debug */, + DB13B1881849DF1E0010F42D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DB13B1B01849DF520010F42D /* Build configuration list for PBXNativeTarget "libffi-Mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB13B1B11849DF520010F42D /* Debug */, + DB13B1B21849DF520010F42D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = DB13B15C1849DEB70010F42D /* Project object */; +} diff --git a/circuitpython/lib/libffi/libtool-ldflags b/circuitpython/lib/libffi/libtool-ldflags new file mode 100755 index 0000000..e32e37b --- /dev/null +++ b/circuitpython/lib/libffi/libtool-ldflags @@ -0,0 +1,106 @@ +#! /bin/sh + +# Script to translate LDFLAGS into a form suitable for use with libtool. + +# Copyright (C) 2005 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +# Contributed by CodeSourcery, LLC. + +# This script is designed to be used from a Makefile that uses libtool +# to build libraries as follows: +# +# LTLDFLAGS = $(shell libtool-ldflags $(LDFLAGS)) +# +# Then, use (LTLDFLAGS) in place of $(LDFLAGS) in your link line. + +# The output of the script. This string is built up as we process the +# arguments. +result= +prev_arg= + +for arg +do + case $arg in + -f*|--*) + # Libtool does not ascribe any special meaning options + # that begin with -f or with a double-dash. So, it will + # think these options are linker options, and prefix them + # with "-Wl,". Then, the compiler driver will ignore the + # options. So, we prefix these options with -Xcompiler to + # make clear to libtool that they are in fact compiler + # options. + case $prev_arg in + -Xpreprocessor|-Xcompiler|-Xlinker) + # This option is already prefixed; don't prefix it again. + ;; + *) + result="$result -Xcompiler" + ;; + esac + ;; + *) + # We do not want to add -Xcompiler to other options because + # that would prevent libtool itself from recognizing them. + ;; + esac + prev_arg=$arg + + # If $(LDFLAGS) is (say): + # a "b'c d" e + # then the user expects that: + # $(LD) $(LDFLAGS) + # will pass three arguments to $(LD): + # 1) a + # 2) b'c d + # 3) e + # We must ensure, therefore, that the arguments are appropriately + # quoted so that using: + # libtool --mode=link ... $(LTLDFLAGS) + # will result in the same number of arguments being passed to + # libtool. In other words, when this script was invoked, the shell + # removed one level of quoting, present in $(LDFLAGS); we have to put + # it back. + + # Quote any embedded single quotes. + case $arg in + *"'"*) + # The following command creates the script: + # 1s,^X,,;s|'|'"'"'|g + # which removes a leading X, and then quotes and embedded single + # quotes. + sed_script="1s,^X,,;s|'|'\"'\"'|g" + # Add a leading "X" so that if $arg starts with a dash, + # the echo command will not try to interpret the argument + # as a command-line option. + arg="X$arg" + # Generate the quoted string. + quoted_arg=`echo "$arg" | sed -e "$sed_script"` + ;; + *) + quoted_arg=$arg + ;; + esac + # Surround the entire argument with single quotes. + quoted_arg="'"$quoted_arg"'" + + # Add it to the string. + result="$result $quoted_arg" +done + +# Output the string we have built up. +echo "$result" diff --git a/circuitpython/lib/libffi/libtool-version b/circuitpython/lib/libffi/libtool-version new file mode 100644 index 0000000..149a51a --- /dev/null +++ b/circuitpython/lib/libffi/libtool-version @@ -0,0 +1,29 @@ +# This file is used to maintain libtool version info for libffi. See +# the libtool manual to understand the meaning of the fields. This is +# a separate file so that version updates don't involve re-running +# automake. +# +# Here are a set of rules to help you update your library version +# information: +# +# 1. Start with version information of `0:0:0' for each libtool library. +# +# 2. Update the version information only immediately before a public +# release of your software. More frequent updates are unnecessary, +# and only guarantee that the current interface number gets larger +# faster. +# +# 3. If the library source code has changed at all since the last +# update, then increment revision (`c:r:a' becomes `c:r+1:a'). +# +# 4. If any interfaces have been added, removed, or changed since the +# last update, increment current, and set revision to 0. +# +# 5. If any interfaces have been added since the last public release, +# then increment age. +# +# 6. If any interfaces have been removed since the last public +# release, then set age to 0. +# +# CURRENT:REVISION:AGE +6:4:0 diff --git a/circuitpython/lib/libffi/m4/asmcfi.m4 b/circuitpython/lib/libffi/m4/asmcfi.m4 new file mode 100644 index 0000000..dbf73a0 --- /dev/null +++ b/circuitpython/lib/libffi/m4/asmcfi.m4 @@ -0,0 +1,13 @@ +AC_DEFUN([GCC_AS_CFI_PSEUDO_OP], +[AC_CACHE_CHECK([assembler .cfi pseudo-op support], + gcc_cv_as_cfi_pseudo_op, [ + gcc_cv_as_cfi_pseudo_op=unknown + AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],, + [gcc_cv_as_cfi_pseudo_op=yes], + [gcc_cv_as_cfi_pseudo_op=no]) + ]) + if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then + AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1, + [Define if your assembler supports .cfi_* directives.]) + fi +]) diff --git a/circuitpython/lib/libffi/m4/ax_append_flag.m4 b/circuitpython/lib/libffi/m4/ax_append_flag.m4 new file mode 100644 index 0000000..1d38b76 --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_append_flag.m4 @@ -0,0 +1,69 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) +# +# DESCRIPTION +# +# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space +# added in between. +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains +# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly +# FLAG. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_APPEND_FLAG], +[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl +AS_VAR_SET_IF(FLAGS, + [case " AS_VAR_GET(FLAGS) " in + *" $1 "*) + AC_RUN_LOG([: FLAGS already contains $1]) + ;; + *) + AC_RUN_LOG([: FLAGS="$FLAGS $1"]) + AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) + ;; + esac], + [AS_VAR_SET(FLAGS,["$1"])]) +AS_VAR_POPDEF([FLAGS])dnl +])dnl AX_APPEND_FLAG diff --git a/circuitpython/lib/libffi/m4/ax_cc_maxopt.m4 b/circuitpython/lib/libffi/m4/ax_cc_maxopt.m4 new file mode 100644 index 0000000..62e3b53 --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_cc_maxopt.m4 @@ -0,0 +1,181 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cc_maxopt.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CC_MAXOPT +# +# DESCRIPTION +# +# Try to turn on "good" C optimization flags for various compilers and +# architectures, for some definition of "good". (In our case, good for +# FFTW and hopefully for other scientific codes. Modify as needed.) +# +# The user can override the flags by setting the CFLAGS environment +# variable. The user can also specify --enable-portable-binary in order to +# disable any optimization flags that might result in a binary that only +# runs on the host architecture. +# +# Note also that the flags assume that ANSI C aliasing rules are followed +# by the code (e.g. for gcc's -fstrict-aliasing), and that floating-point +# computations can be re-ordered as needed. +# +# Requires macros: AX_CHECK_COMPILE_FLAG, AX_COMPILER_VENDOR, +# AX_GCC_ARCHFLAG, AX_GCC_X86_CPUID. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 13 + +AC_DEFUN([AX_CC_MAXOPT], +[ +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AX_COMPILER_VENDOR]) +AC_REQUIRE([AC_CANONICAL_HOST]) + +AC_ARG_ENABLE(portable-binary, [AS_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])], + acx_maxopt_portable=$enableval, acx_maxopt_portable=no) + +# Try to determine "good" native compiler flags if none specified via CFLAGS +if test "$ac_test_CFLAGS" != "set"; then + CFLAGS="" + case $ax_cv_c_compiler_vendor in + dec) CFLAGS="-newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host" + if test "x$acx_maxopt_portable" = xno; then + CFLAGS="$CFLAGS -arch host" + fi;; + + sun) CFLAGS="-native -fast -xO5 -dalign" + if test "x$acx_maxopt_portable" = xyes; then + CFLAGS="$CFLAGS -xarch=generic" + fi;; + + hp) CFLAGS="+Oall +Optrs_ansi +DSnative" + if test "x$acx_maxopt_portable" = xyes; then + CFLAGS="$CFLAGS +DAportable" + fi;; + + ibm) if test "x$acx_maxopt_portable" = xno; then + xlc_opt="-qarch=auto -qtune=auto" + else + xlc_opt="-qtune=auto" + fi + AX_CHECK_COMPILE_FLAG($xlc_opt, + CFLAGS="-O3 -qansialias -w $xlc_opt", + [CFLAGS="-O3 -qansialias -w" + echo "******************************************************" + echo "* You seem to have the IBM C compiler. It is *" + echo "* recommended for best performance that you use: *" + echo "* *" + echo "* CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *" + echo "* ^^^ ^^^ *" + echo "* where xxx is pwr2, pwr3, 604, or whatever kind of *" + echo "* CPU you have. (Set the CFLAGS environment var. *" + echo "* and re-run configure.) For more info, man cc. *" + echo "******************************************************"]) + ;; + + intel) CFLAGS="-O3 -ansi_alias" + if test "x$acx_maxopt_portable" = xno; then + icc_archflag=unknown + icc_flags="" + case $host_cpu in + i686*|x86_64*) + # icc accepts gcc assembly syntax, so these should work: + AX_GCC_X86_CPUID(0) + AX_GCC_X86_CPUID(1) + case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG + *:756e6547:*:*) # Intel + case $ax_cv_gcc_x86_cpuid_1 in + *6a?:*[[234]]:*:*|*6[[789b]]?:*:*:*) icc_flags="-xK";; + *f3[[347]]:*:*:*|*f4[1347]:*:*:*) icc_flags="-xP -xN -xW -xK";; + *f??:*:*:*) icc_flags="-xN -xW -xK";; + esac ;; + esac ;; + esac + if test "x$icc_flags" != x; then + for flag in $icc_flags; do + AX_CHECK_COMPILE_FLAG($flag, [icc_archflag=$flag; break]) + done + fi + AC_MSG_CHECKING([for icc architecture flag]) + AC_MSG_RESULT($icc_archflag) + if test "x$icc_archflag" != xunknown; then + CFLAGS="$CFLAGS $icc_archflag" + fi + fi + ;; + + gnu) + # default optimization flags for gcc on all systems + CFLAGS="-O3 -fomit-frame-pointer" + + # -malign-double for x86 systems + # LIBFFI -- DON'T DO THIS - CHANGES ABI + # AX_CHECK_COMPILE_FLAG(-malign-double, CFLAGS="$CFLAGS -malign-double") + + # -fstrict-aliasing for gcc-2.95+ + AX_CHECK_COMPILE_FLAG(-fstrict-aliasing, + CFLAGS="$CFLAGS -fstrict-aliasing") + + # note that we enable "unsafe" fp optimization with other compilers, too + AX_CHECK_COMPILE_FLAG(-ffast-math, CFLAGS="$CFLAGS -ffast-math") + + AX_GCC_ARCHFLAG($acx_maxopt_portable) + ;; + esac + + if test -z "$CFLAGS"; then + echo "" + echo "********************************************************" + echo "* WARNING: Don't know the best CFLAGS for this system *" + echo "* Use ./configure CFLAGS=... to specify your own flags *" + echo "* (otherwise, a default of CFLAGS=-O3 will be used) *" + echo "********************************************************" + echo "" + CFLAGS="-O3" + fi + + AX_CHECK_COMPILE_FLAG($CFLAGS, [], [ + echo "" + echo "********************************************************" + echo "* WARNING: The guessed CFLAGS don't seem to work with *" + echo "* your compiler. *" + echo "* Use ./configure CFLAGS=... to specify your own flags *" + echo "********************************************************" + echo "" + CFLAGS="" + ]) + +fi +]) diff --git a/circuitpython/lib/libffi/m4/ax_cflags_warn_all.m4 b/circuitpython/lib/libffi/m4/ax_cflags_warn_all.m4 new file mode 100644 index 0000000..0fa3e18 --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_cflags_warn_all.m4 @@ -0,0 +1,122 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] +# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] +# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] +# +# DESCRIPTION +# +# Try to find a compiler option that enables most reasonable warnings. +# +# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result +# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default. +# +# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX, +# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and +# Intel compilers. For a given compiler, the Fortran flags are much more +# experimental than their C equivalents. +# +# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS +# - $2 add-value-if-not-found : nothing +# - $3 action-if-found : add value to shellvariable +# - $4 action-if-not-found : nothing +# +# NOTE: These macros depend on AX_APPEND_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2010 Rhys Ulerich +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 14 + +AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl +AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], +VAR,[VAR="no, unknown" +ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-warn all % -warn all" dnl Intel + "-pedantic % -Wall" dnl GCC + "-xstrconst % -v" dnl Solaris C + "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix + "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX + "-ansi -ansiE % -fullwarn" dnl IRIX + "+ESlit % +w1" dnl HP-UX C + "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) + "-h conform % -h msglevel 2" dnl Cray C (Unicos) + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done +FLAGS="$ac_save_[]FLAGS" +]) +AS_VAR_POPDEF([FLAGS])dnl +AC_REQUIRE([AX_APPEND_FLAG]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; + *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +])dnl AX_FLAGS_WARN_ALL +dnl implementation tactics: +dnl the for-argument contains a list of options. The first part of +dnl these does only exist to detect the compiler - usually it is +dnl a global option to enable -ansi or -extrawarnings. All other +dnl compilers will fail about it. That was needed since a lot of +dnl compilers will give false positives for some option-syntax +dnl like -Woption or -Xoption as they think of it is a pass-through +dnl to later compile stages or something. The "%" is used as a +dnl delimiter. A non-option comment can be given after "%%" marks +dnl which will be shown but not added to the respective C/CXXFLAGS. + +AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl +AC_LANG_PUSH([C]) +AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) +AC_LANG_POP([C]) +]) + +AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl +AC_LANG_PUSH([C++]) +AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) +AC_LANG_POP([C++]) +]) + +AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl +AC_LANG_PUSH([Fortran]) +AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) +AC_LANG_POP([Fortran]) +]) diff --git a/circuitpython/lib/libffi/m4/ax_check_compile_flag.m4 b/circuitpython/lib/libffi/m4/ax_check_compile_flag.m4 new file mode 100644 index 0000000..c3a8d69 --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_check_compile_flag.m4 @@ -0,0 +1,72 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/circuitpython/lib/libffi/m4/ax_compiler_vendor.m4 b/circuitpython/lib/libffi/m4/ax_compiler_vendor.m4 new file mode 100644 index 0000000..73e32ea --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_compiler_vendor.m4 @@ -0,0 +1,84 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_VENDOR +# +# DESCRIPTION +# +# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun, +# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft, +# watcom, etc. The vendor is returned in the cache variable +# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 11 + +AC_DEFUN([AX_COMPILER_VENDOR], +[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, + [# note: don't check for gcc first since some other compilers define __GNUC__ + vendors="intel: __ICC,__ECC,__INTEL_COMPILER + ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__ + pathscale: __PATHCC__,__PATHSCALE__ + clang: __clang__ + gnu: __GNUC__ + sun: __SUNPRO_C,__SUNPRO_CC + hp: __HP_cc,__HP_aCC + dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER + borland: __BORLANDC__,__TURBOC__ + comeau: __COMO__ + cray: _CRAYC + kai: __KCC + lcc: __LCC__ + sgi: __sgi,sgi + microsoft: _MSC_VER + metrowerks: __MWERKS__ + watcom: __WATCOMC__ + portland: __PGI + unknown: UNKNOWN" + for ventest in $vendors; do + case $ventest in + *:) vendor=$ventest; continue ;; + *) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;; + esac + AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ + #if !($vencpp) + thisisanerror; + #endif + ])], [break]) + done + ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1` + ]) +]) diff --git a/circuitpython/lib/libffi/m4/ax_configure_args.m4 b/circuitpython/lib/libffi/m4/ax_configure_args.m4 new file mode 100644 index 0000000..0726b1b --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_configure_args.m4 @@ -0,0 +1,70 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_configure_args.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CONFIGURE_ARGS +# +# DESCRIPTION +# +# Helper macro for AX_ENABLE_BUILDDIR. +# +# The traditional way of starting a subdir-configure is running the script +# with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have +# to rely on eval'ing $ac_configure_args however some old autoconf +# versions do not provide that. To ensure maximum portability of autoconf +# extension macros this helper can be AC_REQUIRE'd so that +# $ac_configure_args will alsways be present. +# +# Sadly, the traditional "exec $SHELL" of the enable_builddir macros is +# spoiled now and must be replaced by "eval + exit $?". +# +# Example: +# +# AC_DEFUN([AX_ENABLE_SUBDIR],[dnl +# AC_REQUIRE([AX_CONFIGURE_ARGS])dnl +# eval $SHELL $ac_configure_args || exit $? +# ...]) +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 9 + +AC_DEFUN([AX_CONFIGURE_ARGS],[ + # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args + if test "${ac_configure_args+set}" != "set" ; then + ac_configure_args= + for ac_arg in ${1+"[$]@"}; do + ac_configure_args="$ac_configure_args '$ac_arg'" + done + fi +]) diff --git a/circuitpython/lib/libffi/m4/ax_enable_builddir.m4 b/circuitpython/lib/libffi/m4/ax_enable_builddir.m4 new file mode 100644 index 0000000..3cb2093 --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_enable_builddir.m4 @@ -0,0 +1,301 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_ENABLE_BUILDDIR [(dirstring-or-command [,Makefile.mk [,-all]])] +# +# DESCRIPTION +# +# If the current configure was run within the srcdir then we move all +# configure-files into a subdir and let the configure steps continue +# there. We provide an option --disable-builddir to suppress the move into +# a separate builddir. +# +# Defaults: +# +# $1 = $host (overridden with $HOST) +# $2 = Makefile.mk +# $3 = -all +# +# This macro must be called before AM_INIT_AUTOMAKE. It creates a default +# toplevel srcdir Makefile from the information found in the created +# toplevel builddir Makefile. It just copies the variables and +# rule-targets, each extended with a default rule-execution that recurses +# into the build directory of the current "HOST". You can override the +# auto-dection through `config.guess` and build-time of course, as in +# +# make HOST=i386-mingw-cross +# +# which can of course set at configure time as well using +# +# configure --host=i386-mingw-cross +# +# After the default has been created, additional rules can be appended +# that will not just recurse into the subdirectories and only ever exist +# in the srcdir toplevel makefile - these parts are read from the $2 = +# Makefile.mk file +# +# The automatic rules are usually scanning the toplevel Makefile for lines +# like '#### $host |$builddir' to recognize the place where to recurse +# into. Usually, the last one is the only one used. However, almost all +# targets have an additional "*-all" rule which makes the script to +# recurse into _all_ variants of the current HOST (!!) setting. The "-all" +# suffix can be overriden for the macro as well. +# +# a special rule is only given for things like "dist" that will copy the +# tarball from the builddir to the sourcedir (or $(PUB)) for reason of +# convenience. +# +# LICENSE +# +# Copyright (c) 2009 Guido U. Draheim +# Copyright (c) 2009 Alan Jenkins +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 23 + +AC_DEFUN([AX_ENABLE_BUILDDIR],[ +AC_REQUIRE([AC_CANONICAL_HOST])[]dnl +AC_REQUIRE([AX_CONFIGURE_ARGS])[]dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])[]dnl +AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl +AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl +AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl +AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl +SUB="." +AC_ARG_ENABLE([builddir], AS_HELP_STRING( + [--disable-builddir],[disable automatic build in subdir of sources]) + ,[SUB="$enableval"], [SUB="auto"]) +if test ".$ac_srcdir_defaulted" != ".no" ; then +if test ".$srcdir" = ".." ; then + if test -f config.status ; then + AC_MSG_NOTICE(toplevel srcdir already configured... skipping subdir build) + else + test ".$SUB" = "." && SUB="." + test ".$SUB" = ".no" && SUB="." + test ".$TARGET" = "." && TARGET="$target" + test ".$SUB" = ".auto" && SUB="m4_ifval([$1], [$1],[$TARGET])" + if test ".$SUB" != ".." ; then # we know where to go and + AS_MKDIR_P([$SUB]) + echo __.$SUB.__ > $SUB/conftest.tmp + cd $SUB + if grep __.$SUB.__ conftest.tmp >/dev/null 2>/dev/null ; then + rm conftest.tmp + AC_MSG_RESULT([continue configure in default builddir "./$SUB"]) + else + AC_MSG_ERROR([could not change to default builddir "./$SUB"]) + fi + srcdir=`echo "$SUB" | + sed -e 's,^\./,,;s,[[^/]]$,&/,;s,[[^/]]*/,../,g;s,[[/]]$,,;'` + # going to restart from subdirectory location + test -f $srcdir/config.log && mv $srcdir/config.log . + test -f $srcdir/confdefs.h && mv $srcdir/confdefs.h . + test -f $srcdir/conftest.log && mv $srcdir/conftest.log . + test -f $srcdir/$cache_file && mv $srcdir/$cache_file . + AC_MSG_RESULT(....exec $SHELL $srcdir/[$]0 "--srcdir=$srcdir" "--enable-builddir=$SUB" ${1+"[$]@"}) + case "[$]0" in # restart + [[\\/]]* | ?:[[\\/]]*) # Asbolute name + eval $SHELL "'[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;; + *) eval $SHELL "'$srcdir/[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;; + esac ; exit $? + fi + fi +fi fi +test ".$SUB" = ".auto" && SUB="." +dnl ac_path_prog uses "set dummy" to override $@ which would defeat the "exec" +AC_PATH_PROG(SED,gsed sed, sed) +AUX="$am_aux_dir" +AS_VAR_POPDEF([SED])dnl +AS_VAR_POPDEF([AUX])dnl +AS_VAR_POPDEF([SUB])dnl +AC_CONFIG_COMMANDS([buildir],[dnl .............. config.status .............. +AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl +AS_VAR_PUSHDEF([TOP],[top_srcdir])dnl +AS_VAR_PUSHDEF([SRC],[ac_top_srcdir])dnl +AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl +AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl +pushdef([END],[Makefile.mk])dnl +pushdef([_ALL],[ifelse([$3],,[-all],[$3])])dnl + SRC="$ax_enable_builddir_srcdir" + if test ".$SUB" = ".." ; then + if test -f "$TOP/Makefile" ; then + AC_MSG_NOTICE([skipping TOP/Makefile - left untouched]) + else + AC_MSG_NOTICE([skipping TOP/Makefile - not created]) + fi + else + if test -f "$SRC/Makefile" ; then + a=`grep "^VERSION " "$SRC/Makefile"` ; b=`grep "^VERSION " Makefile` + test "$a" != "$b" && rm "$SRC/Makefile" + fi + if test -f "$SRC/Makefile" ; then + echo "$SRC/Makefile : $SRC/Makefile.in" > $tmp/conftemp.mk + echo " []@ echo 'REMOVED,,,' >\$[]@" >> $tmp/conftemp.mk + eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null" + if grep '^REMOVED,,,' "$SRC/Makefile" >/dev/null + then rm $SRC/Makefile ; fi + cp $tmp/conftemp.mk $SRC/makefiles.mk~ ## DEBUGGING + fi + if test ! -f "$SRC/Makefile" ; then + AC_MSG_NOTICE([create TOP/Makefile guessed from local Makefile]) + x='`' ; cat >$tmp/conftemp.sed <<_EOF +/^\$/n +x +/^\$/bS +x +/\\\\\$/{H;d;} +{H;s/.*//;x;} +bM +:S +x +/\\\\\$/{h;d;} +{h;s/.*//;x;} +:M +s/\\(\\n\\) /\\1 /g +/^ /d +/^[[ ]]*[[\\#]]/d +/^VPATH *=/d +s/^srcdir *=.*/srcdir = ./ +s/^top_srcdir *=.*/top_srcdir = ./ +/[[:=]]/!d +/^\\./d +dnl Now handle rules (i.e. lines containing ":" but not " = "). +/ = /b +/ .= /b +/:/!b +s/:.*/:/ +s/ / /g +s/ \\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/ \\1 \\1[]_ALL\\2/g +s/^\\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/\\1 \\1[]_ALL\\2/ +s/ / /g +/^all all[]_ALL[[ :]]/i\\ +all-configured : all[]_ALL +dnl dist-all exists... and would make for dist-all-all +s/ [[a-zA-Z0-9-]]*[]_ALL [[a-zA-Z0-9-]]*[]_ALL[]_ALL//g +/[]_ALL[]_ALL/d +a\\ + @ HOST="\$(HOST)\" \\\\\\ + ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\ + ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\ + ; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\ + ; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" -eq "0" ; then : \\\\\\ + ; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\ + ; test ".\$\$BUILD" = "." && BUILD="." \\\\\\ + ; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\ + ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ + ; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done +dnl special rule add-on: "dist" copies the tarball to $(PUB). (source tree) +/dist[]_ALL *:/a\\ + @ HOST="\$(HOST)\" \\\\\\ + ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\ + ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\ + ; found=$x echo \$\$BUILD | wc -w $x \\\\\\ + ; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\ + ; if test "\$\$found" -eq "0" ; then : \\\\\\ + ; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\ + ; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ + ; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\ + ; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done +dnl special rule add-on: "dist-foo" copies all the archives to $(PUB). (source tree) +/dist-[[a-zA-Z0-9]]*[]_ALL *:/a\\ + @ HOST="\$(HOST)\" \\\\\\ + ; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\ + ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\ + ; found=$x echo \$\$BUILD | wc -w $x \\\\\\ + ; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\ + ; if test "\$\$found" -eq "0" ; then : \\\\\\ + ; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\ + ; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ + ; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\ + ; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done +dnl special rule add-on: "distclean" removes all local builddirs completely +/distclean[]_ALL *:/a\\ + @ HOST="\$(HOST)\" \\\\\\ + ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\ + ; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\ + ; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\ + ; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\ + ; test ".\$\$BUILD" = "." && BUILD="." \\\\\\ + ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ + ; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\ + ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ + ; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\ + ; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\ + ; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile +_EOF + cp "$tmp/conftemp.sed" "$SRC/makefile.sed~" ## DEBUGGING + $SED -f $tmp/conftemp.sed Makefile >$SRC/Makefile + if test -f "$SRC/m4_ifval([$2],[$2],[END])" ; then + AC_MSG_NOTICE([extend TOP/Makefile with TOP/m4_ifval([$2],[$2],[END])]) + cat $SRC/END >>$SRC/Makefile + fi ; xxxx="####" + echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$SRC/Makefile + # sanity check + if grep '^; echo "MAKE ' $SRC/Makefile >/dev/null ; then + AC_MSG_NOTICE([buggy sed found - it deletes tab in "a" text parts]) + $SED -e '/^@ HOST=/s/^/ /' -e '/^; /s/^/ /' $SRC/Makefile \ + >$SRC/Makefile~ + (test -s $SRC/Makefile~ && mv $SRC/Makefile~ $SRC/Makefile) 2>/dev/null + fi + else + xxxx="\\#\\#\\#\\#" + # echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed + echo "s!^$xxxx [[^|]]* | *$SUB *\$!$xxxx ...... $SUB!" >$tmp/conftemp.sed + $SED -f "$tmp/conftemp.sed" "$SRC/Makefile" >$tmp/mkfile.tmp + cp "$tmp/conftemp.sed" "$SRC/makefiles.sed~" ## DEBUGGING + cp "$tmp/mkfile.tmp" "$SRC/makefiles.out~" ## DEBUGGING + if cmp -s "$SRC/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then + AC_MSG_NOTICE([keeping TOP/Makefile from earlier configure]) + rm "$tmp/mkfile.tmp" + else + AC_MSG_NOTICE([reusing TOP/Makefile from earlier configure]) + mv "$tmp/mkfile.tmp" "$SRC/Makefile" + fi + fi + AC_MSG_NOTICE([build in $SUB (HOST=$ax_enable_builddir_host)]) + xxxx="####" + echo "$xxxx" "$ax_enable_builddir_host" "|$SUB" >>$SRC/Makefile + fi +popdef([END])dnl +AS_VAR_POPDEF([SED])dnl +AS_VAR_POPDEF([AUX])dnl +AS_VAR_POPDEF([SRC])dnl +AS_VAR_POPDEF([TOP])dnl +AS_VAR_POPDEF([SUB])dnl +],[dnl +ax_enable_builddir_srcdir="$srcdir" # $srcdir +ax_enable_builddir_host="$HOST" # $HOST / $host +ax_enable_builddir_version="$VERSION" # $VERSION +ax_enable_builddir_package="$PACKAGE" # $PACKAGE +ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX +ax_enable_builddir_sed="$ax_enable_builddir_sed" # $SED +ax_enable_builddir="$ax_enable_builddir" # $SUB +])dnl +]) diff --git a/circuitpython/lib/libffi/m4/ax_gcc_archflag.m4 b/circuitpython/lib/libffi/m4/ax_gcc_archflag.m4 new file mode 100644 index 0000000..aab2661 --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_gcc_archflag.m4 @@ -0,0 +1,225 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE]) +# +# DESCRIPTION +# +# This macro tries to guess the "native" arch corresponding to the target +# architecture for use with gcc's -march=arch or -mtune=arch flags. If +# found, the cache variable $ax_cv_gcc_archflag is set to this flag and +# ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is set to +# "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is +# to add $ax_cv_gcc_archflag to the end of $CFLAGS. +# +# PORTABLE? should be either [yes] (default) or [no]. In the former case, +# the flag is set to -mtune (or equivalent) so that the architecture is +# only used for tuning, but the instruction set used is still portable. In +# the latter case, the flag is set to -march (or equivalent) so that +# architecture-specific instructions are enabled. +# +# The user can specify --with-gcc-arch= in order to override the +# macro's choice of architecture, or --without-gcc-arch to disable this. +# +# When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is +# called unless the user specified --with-gcc-arch manually. +# +# Requires macros: AX_CHECK_COMPILE_FLAG, AX_GCC_X86_CPUID +# +# (The main emphasis here is on recent CPUs, on the principle that doing +# high-performance computing on old hardware is uncommon.) +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# Copyright (c) 2012 Tsukasa Oi +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 11 + +AC_DEFUN([AX_GCC_ARCHFLAG], +[AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_CANONICAL_HOST]) + +AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=], [use architecture for gcc -march/-mtune, instead of guessing])], + ax_gcc_arch=$withval, ax_gcc_arch=yes) + +AC_MSG_CHECKING([for gcc architecture flag]) +AC_MSG_RESULT([]) +AC_CACHE_VAL(ax_cv_gcc_archflag, +[ +ax_cv_gcc_archflag="unknown" + +if test "$GCC" = yes; then + +if test "x$ax_gcc_arch" = xyes; then +ax_gcc_arch="" +if test "$cross_compiling" = no; then +case $host_cpu in + i[[3456]]86*|x86_64*) # use cpuid codes + AX_GCC_X86_CPUID(0) + AX_GCC_X86_CPUID(1) + case $ax_cv_gcc_x86_cpuid_0 in + *:756e6547:*:*) # Intel + case $ax_cv_gcc_x86_cpuid_1 in + *5[[48]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;; + *5??:*:*:*) ax_gcc_arch=pentium ;; + *0?6[[3456]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;; + *0?6a?:*[[01]]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;; + *0?6a?:*[[234]]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;; + *0?6[[9de]]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;; + *0?6[[78b]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;; + *0?6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;; + *1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;; + *1?6[[aef]]?:*:*:*|*2?6[[5cef]]?:*:*:*) ax_gcc_arch="corei7 core2 pentium-m pentium3 pentiumpro" ;; + *1?6c?:*:*:*|*[[23]]?66?:*:*:*) ax_gcc_arch="atom core2 pentium-m pentium3 pentiumpro" ;; + *2?6[[ad]]?:*:*:*) ax_gcc_arch="corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *0?6??:*:*:*) ax_gcc_arch=pentiumpro ;; + *6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;; + ?000?f3[[347]]:*:*:*|?000?f4[1347]:*:*:*|?000?f6?:*:*:*) + case $host_cpu in + x86_64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;; + *) ax_gcc_arch="prescott pentium4 pentiumpro" ;; + esac ;; + ?000?f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro";; + esac ;; + *:68747541:*:*) # AMD + case $ax_cv_gcc_x86_cpuid_1 in + *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;; + *5[[8d]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;; + *5[[9]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;; + *60?:*:*:*) ax_gcc_arch=k7 ;; + *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;; + *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;; + *67?:*:*:*) ax_gcc_arch="athlon-4 athlon k7" ;; + *6[[68a]]?:*:*:*) + AX_GCC_X86_CPUID(0x80000006) # L2 cache size + case $ax_cv_gcc_x86_cpuid_0x80000006 in + *:*:*[[1-9a-f]]??????:*) # (L2 = ecx >> 16) >= 256 + ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;; + *) ax_gcc_arch="athlon-4 athlon k7" ;; + esac ;; + ?00??f[[4cef8b]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;; + ?00??f5?:*:*:*) ax_gcc_arch="opteron k8" ;; + ?00??f7?:*:*:*) ax_gcc_arch="athlon-fx opteron k8" ;; + ?00??f??:*:*:*) ax_gcc_arch="k8" ;; + ?05??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; + ?06??f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; + *f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;; + esac ;; + *:746e6543:*:*) # IDT + case $ax_cv_gcc_x86_cpuid_1 in + *54?:*:*:*) ax_gcc_arch=winchip-c6 ;; + *58?:*:*:*) ax_gcc_arch=winchip2 ;; + *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;; + *69?:*:*:*) ax_gcc_arch="c3-2 c3" ;; + esac ;; + esac + if test x"$ax_gcc_arch" = x; then # fallback + case $host_cpu in + i586*) ax_gcc_arch=pentium ;; + i686*) ax_gcc_arch=pentiumpro ;; + esac + fi + ;; + + sparc*) + AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/]) + cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` + cputype=`echo "$cputype" | tr -d ' -' | sed 's/SPARCIIi/SPARCII/' | tr $as_cr_LETTERS $as_cr_letters` + case $cputype in + *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; + *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; + *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;; + *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;; + *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;; + *cypress*) ax_gcc_arch=cypress ;; + esac ;; + + alphaev5) ax_gcc_arch=ev5 ;; + alphaev56) ax_gcc_arch=ev56 ;; + alphapca56) ax_gcc_arch="pca56 ev56" ;; + alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;; + alphaev6) ax_gcc_arch=ev6 ;; + alphaev67) ax_gcc_arch=ev67 ;; + alphaev68) ax_gcc_arch="ev68 ev67" ;; + alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;; + alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;; + alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;; + + powerpc*) + cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | sed 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null` + cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'` + case $cputype in + *750*) ax_gcc_arch="750 G3" ;; + *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;; + *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;; + *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;; + *970*) ax_gcc_arch="970 G5 power4";; + *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";; + *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";; + 603ev|8240) ax_gcc_arch="$cputype 603e 603";; + *) ax_gcc_arch=$cputype ;; + esac + ax_gcc_arch="$ax_gcc_arch powerpc" + ;; +esac +fi # not cross-compiling +fi # guess arch + +if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then +for arch in $ax_gcc_arch; do + if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code + flags="-mtune=$arch" + # -mcpu=$arch and m$arch generate nonportable code on every arch except + # x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr. + case $host_cpu in i*86|x86_64*) flags="$flags -mcpu=$arch -m$arch";; esac + else + flags="-march=$arch -mcpu=$arch -m$arch" + fi + for flag in $flags; do + AX_CHECK_COMPILE_FLAG($flag, [ax_cv_gcc_archflag=$flag; break]) + done + test "x$ax_cv_gcc_archflag" = xunknown || break +done +fi + +fi # $GCC=yes +]) +AC_MSG_CHECKING([for gcc architecture flag]) +AC_MSG_RESULT($ax_cv_gcc_archflag) +if test "x$ax_cv_gcc_archflag" = xunknown; then + m4_default([$3],:) +else + m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"]) +fi +]) diff --git a/circuitpython/lib/libffi/m4/ax_gcc_x86_cpuid.m4 b/circuitpython/lib/libffi/m4/ax_gcc_x86_cpuid.m4 new file mode 100644 index 0000000..7d46fee --- /dev/null +++ b/circuitpython/lib/libffi/m4/ax_gcc_x86_cpuid.m4 @@ -0,0 +1,79 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_X86_CPUID(OP) +# +# DESCRIPTION +# +# On Pentium and later x86 processors, with gcc or a compiler that has a +# compatible syntax for inline assembly instructions, run a small program +# that executes the cpuid instruction with input OP. This can be used to +# detect the CPU type. +# +# On output, the values of the eax, ebx, ecx, and edx registers are stored +# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable +# ax_cv_gcc_x86_cpuid_OP. +# +# If the cpuid instruction fails (because you are running a +# cross-compiler, or because you are not using gcc, or because you are on +# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP +# is set to the string "unknown". +# +# This macro mainly exists to be used in AX_GCC_ARCHFLAG. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 7 + +AC_DEFUN([AX_GCC_X86_CPUID], +[AC_REQUIRE([AC_PROG_CC]) +AC_LANG_PUSH([C]) +AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1, + [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include ], [ + int op = $1, eax, ebx, ecx, edx; + FILE *f; + __asm__("cpuid" + : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op)); + f = fopen("conftest_cpuid", "w"); if (!f) return 1; + fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); + fclose(f); + return 0; +])], + [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid], + [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid], + [ax_cv_gcc_x86_cpuid_$1=unknown])]) +AC_LANG_POP([C]) +]) diff --git a/circuitpython/lib/libffi/man/Makefile.am b/circuitpython/lib/libffi/man/Makefile.am new file mode 100644 index 0000000..afcbfb6 --- /dev/null +++ b/circuitpython/lib/libffi/man/Makefile.am @@ -0,0 +1,8 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS=foreign + +EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 + +man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 + diff --git a/circuitpython/lib/libffi/man/ffi.3 b/circuitpython/lib/libffi/man/ffi.3 new file mode 100644 index 0000000..1f1d303 --- /dev/null +++ b/circuitpython/lib/libffi/man/ffi.3 @@ -0,0 +1,41 @@ +.Dd February 15, 2008 +.Dt FFI 3 +.Sh NAME +.Nm FFI +.Nd Foreign Function Interface +.Sh LIBRARY +libffi, -lffi +.Sh SYNOPSIS +.In ffi.h +.Ft ffi_status +.Fo ffi_prep_cif +.Fa "ffi_cif *cif" +.Fa "ffi_abi abi" +.Fa "unsigned int nargs" +.Fa "ffi_type *rtype" +.Fa "ffi_type **atypes" +.Fc +.Ft void +.Fo ffi_prep_cif_var +.Fa "ffi_cif *cif" +.Fa "ffi_abi abi" +.Fa "unsigned int nfixedargs" +.Fa "unsigned int ntotalargs" +.Fa "ffi_type *rtype" +.Fa "ffi_type **atypes" +.Fc +.Ft void +.Fo ffi_call +.Fa "ffi_cif *cif" +.Fa "void (*fn)(void)" +.Fa "void *rvalue" +.Fa "void **avalue" +.Fc +.Sh DESCRIPTION +The foreign function interface provides a mechanism by which a function can +generate a call to another function at runtime without requiring knowledge of +the called function's interface at compile time. +.Sh SEE ALSO +.Xr ffi_prep_cif 3 , +.Xr ffi_prep_cif_var 3 , +.Xr ffi_call 3 diff --git a/circuitpython/lib/libffi/man/ffi_call.3 b/circuitpython/lib/libffi/man/ffi_call.3 new file mode 100644 index 0000000..5351513 --- /dev/null +++ b/circuitpython/lib/libffi/man/ffi_call.3 @@ -0,0 +1,103 @@ +.Dd February 15, 2008 +.Dt ffi_call 3 +.Sh NAME +.Nm ffi_call +.Nd Invoke a foreign function. +.Sh SYNOPSIS +.In ffi.h +.Ft void +.Fo ffi_call +.Fa "ffi_cif *cif" +.Fa "void (*fn)(void)" +.Fa "void *rvalue" +.Fa "void **avalue" +.Fc +.Sh DESCRIPTION +The +.Nm ffi_call +function provides a simple mechanism for invoking a function without +requiring knowledge of the function's interface at compile time. +.Fa fn +is called with the values retrieved from the pointers in the +.Fa avalue +array. The return value from +.Fa fn +is placed in storage pointed to by +.Fa rvalue . +.Fa cif +contains information describing the data types, sizes and alignments of the +arguments to and return value from +.Fa fn , +and must be initialized with +.Nm ffi_prep_cif +before it is used with +.Nm ffi_call . +.Pp +.Fa rvalue +must point to storage that is sizeof(ffi_arg) or larger for non-floating point +types. For smaller-sized return value types, the +.Nm ffi_arg +or +.Nm ffi_sarg +integral type must be used to hold +the return value. +.Sh EXAMPLES +.Bd -literal +#include +#include + +unsigned char +foo(unsigned int, float); + +int +main(int argc, const char **argv) +{ + ffi_cif cif; + ffi_type *arg_types[2]; + void *arg_values[2]; + ffi_status status; + + // Because the return value from foo() is smaller than sizeof(long), it + // must be passed as ffi_arg or ffi_sarg. + ffi_arg result; + + // Specify the data type of each argument. Available types are defined + // in . + arg_types[0] = &ffi_type_uint; + arg_types[1] = &ffi_type_float; + + // Prepare the ffi_cif structure. + if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, + 2, &ffi_type_uint8, arg_types)) != FFI_OK) + { + // Handle the ffi_status error. + } + + // Specify the values of each argument. + unsigned int arg1 = 42; + float arg2 = 5.1; + + arg_values[0] = &arg1; + arg_values[1] = &arg2; + + // Invoke the function. + ffi_call(&cif, FFI_FN(foo), &result, arg_values); + + // The ffi_arg 'result' now contains the unsigned char returned from foo(), + // which can be accessed by a typecast. + printf("result is %hhu", (unsigned char)result); + + return 0; +} + +// The target function. +unsigned char +foo(unsigned int x, float y) +{ + unsigned char result = x - y; + return result; +} +.Ed +.Sh SEE ALSO +.Xr ffi 3 , +.Xr ffi_prep_cif 3 diff --git a/circuitpython/lib/libffi/man/ffi_prep_cif.3 b/circuitpython/lib/libffi/man/ffi_prep_cif.3 new file mode 100644 index 0000000..ab2be8a --- /dev/null +++ b/circuitpython/lib/libffi/man/ffi_prep_cif.3 @@ -0,0 +1,68 @@ +.Dd February 15, 2008 +.Dt ffi_prep_cif 3 +.Sh NAME +.Nm ffi_prep_cif +.Nd Prepare a +.Nm ffi_cif +structure for use with +.Nm ffi_call +. +.Sh SYNOPSIS +.In ffi.h +.Ft ffi_status +.Fo ffi_prep_cif +.Fa "ffi_cif *cif" +.Fa "ffi_abi abi" +.Fa "unsigned int nargs" +.Fa "ffi_type *rtype" +.Fa "ffi_type **atypes" +.Fc +.Sh DESCRIPTION +The +.Nm ffi_prep_cif +function prepares a +.Nm ffi_cif +structure for use with +.Nm ffi_call +. +.Fa abi +specifies a set of calling conventions to use. +.Fa atypes +is an array of +.Fa nargs +pointers to +.Nm ffi_type +structs that describe the data type, size and alignment of each argument. +.Fa rtype +points to an +.Nm ffi_type +that describes the data type, size and alignment of the +return value. Note that to call a variadic function +.Nm ffi_prep_cif_var +must be used instead. +.Sh RETURN VALUES +Upon successful completion, +.Nm ffi_prep_cif +returns +.Nm FFI_OK . +It will return +.Nm FFI_BAD_TYPEDEF +if +.Fa cif +is +.Nm NULL +or +.Fa atypes +or +.Fa rtype +is malformed. If +.Fa abi +does not refer to a valid ABI, +.Nm FFI_BAD_ABI +will be returned. Available ABIs are +defined in +.Nm . +.Sh SEE ALSO +.Xr ffi 3 , +.Xr ffi_call 3 , +.Xr ffi_prep_cif_var 3 diff --git a/circuitpython/lib/libffi/man/ffi_prep_cif_var.3 b/circuitpython/lib/libffi/man/ffi_prep_cif_var.3 new file mode 100644 index 0000000..7e19d0b --- /dev/null +++ b/circuitpython/lib/libffi/man/ffi_prep_cif_var.3 @@ -0,0 +1,73 @@ +.Dd January 25, 2011 +.Dt ffi_prep_cif_var 3 +.Sh NAME +.Nm ffi_prep_cif_var +.Nd Prepare a +.Nm ffi_cif +structure for use with +.Nm ffi_call +for variadic functions. +.Sh SYNOPSIS +.In ffi.h +.Ft ffi_status +.Fo ffi_prep_cif_var +.Fa "ffi_cif *cif" +.Fa "ffi_abi abi" +.Fa "unsigned int nfixedargs" +.Fa "unsigned int ntotalargs" +.Fa "ffi_type *rtype" +.Fa "ffi_type **atypes" +.Fc +.Sh DESCRIPTION +The +.Nm ffi_prep_cif_var +function prepares a +.Nm ffi_cif +structure for use with +.Nm ffi_call +for variadic functions. +.Fa abi +specifies a set of calling conventions to use. +.Fa atypes +is an array of +.Fa ntotalargs +pointers to +.Nm ffi_type +structs that describe the data type, size and alignment of each argument. +.Fa rtype +points to an +.Nm ffi_type +that describes the data type, size and alignment of the +return value. +.Fa nfixedargs +must contain the number of fixed (non-variadic) arguments. +Note that to call a non-variadic function +.Nm ffi_prep_cif +must be used. +.Sh RETURN VALUES +Upon successful completion, +.Nm ffi_prep_cif_var +returns +.Nm FFI_OK . +It will return +.Nm FFI_BAD_TYPEDEF +if +.Fa cif +is +.Nm NULL +or +.Fa atypes +or +.Fa rtype +is malformed. If +.Fa abi +does not refer to a valid ABI, +.Nm FFI_BAD_ABI +will be returned. Available ABIs are +defined in +.Nm +. +.Sh SEE ALSO +.Xr ffi 3 , +.Xr ffi_call 3 , +.Xr ffi_prep_cif 3 diff --git a/circuitpython/lib/libffi/msvcc.sh b/circuitpython/lib/libffi/msvcc.sh new file mode 100755 index 0000000..65fbfef --- /dev/null +++ b/circuitpython/lib/libffi/msvcc.sh @@ -0,0 +1,257 @@ +#!/bin/sh + +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the MSVC wrappificator. +# +# The Initial Developer of the Original Code is +# Timothy Wall . +# Portions created by the Initial Developer are Copyright (C) 2009 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Daniel Witte +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +# +# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC +# format and translated into something sensible for cl or ml. +# + +args_orig=$@ +args="-nologo -W3" +static_crt= +debug_crt= +cl="cl" +ml="ml" +safeseh="-safeseh" +output= + +while [ $# -gt 0 ] +do + case $1 + in + -fexceptions) + # Don't enable exceptions for now. + #args="$args -EHac" + shift 1 + ;; + -m32) + shift 1 + ;; + -m64) + ml="ml64" # "$MSVC/x86_amd64/ml64" + safeseh= + shift 1 + ;; + -clang-cl) + cl="clang-cl" + safeseh= + shift 1 + ;; + -O0) + args="$args -Od" + shift 1 + ;; + -O*) + # Runtime error checks (enabled by setting -RTC1 in the -DFFI_DEBUG + # case below) are not compatible with optimization flags and will + # cause the build to fail. Therefore, drop the optimization flag if + # -DFFI_DEBUG is also set. + case $args_orig in + *-DFFI_DEBUG*) + args="$args" + ;; + *) + # The ax_cc_maxopt.m4 macro from the upstream autoconf-archive + # project doesn't support MSVC and therefore ends up trying to + # use -O3. Use the equivalent "max optimization" flag for MSVC + # instead of erroring out. + case $1 in + -O3) + args="$args -O2" + ;; + *) + args="$args $1" + ;; + esac + opt="true" + ;; + esac + shift 1 + ;; + -g) + # Enable debug symbol generation. + args="$args -Zi" + shift 1 + ;; + -DFFI_DEBUG) + # Enable runtime error checks. + args="$args -RTC1" + defines="$defines $1" + shift 1 + ;; + -DUSE_STATIC_RTL) + # Link against static CRT. + static_crt=1 + shift 1 + ;; + -DUSE_DEBUG_RTL) + # Link against debug CRT. + debug_crt=1 + shift 1 + ;; + -c) + args="$args -c" + args="$(echo $args | sed 's%/Fe%/Fo%g')" + single="-c" + shift 1 + ;; + -D*=*) + name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')" + value="$(echo $1|sed 's/-D[^=][^=]*=//g')" + args="$args -D${name}='$value'" + defines="$defines -D${name}='$value'" + shift 1 + ;; + -D*) + args="$args $1" + defines="$defines $1" + shift 1 + ;; + -I) + args="$args -I$2" + includes="$includes -I$2" + shift 2 + ;; + -I*) + args="$args $1" + includes="$includes $1" + shift 1 + ;; + -W|-Wextra) + # TODO map extra warnings + shift 1 + ;; + -Wall) + # -Wall on MSVC is overzealous, and we already build with -W3. Nothing + # to do here. + shift 1 + ;; + -pedantic) + # libffi tests -pedantic with -Wall, so drop it also. + shift 1 + ;; + -Werror) + args="$args -WX" + shift 1 + ;; + -W*) + # TODO map specific warnings + shift 1 + ;; + -S) + args="$args -FAs" + shift 1 + ;; + -o) + outdir="$(dirname $2)" + base="$(basename $2|sed 's/\.[^.]*//g')" + if [ -n "$single" ]; then + output="-Fo$2" + else + output="-Fe$2" + fi + if [ -n "$assembly" ]; then + args="$args $output" + else + args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base" + fi + shift 2 + ;; + *.S) + src=$1 + assembly="true" + shift 1 + ;; + *.c) + args="$args $1" + shift 1 + ;; + *) + # Assume it's an MSVC argument, and pass it through. + args="$args $1" + shift 1 + ;; + esac +done + +# If -Zi is specified, certain optimizations are implicitly disabled +# by MSVC. Add back those optimizations if this is an optimized build. +# NOTE: These arguments must come after all others. +if [ -n "$opt" ]; then + args="$args -link -OPT:REF -OPT:ICF -INCREMENTAL:NO" +fi + +if [ -n "$static_crt" ]; then + md=-MT +else + md=-MD +fi + +if [ -n "$debug_crt" ]; then + md="${md}d" +fi + +if [ -n "$assembly" ]; then + if [ -z "$outdir" ]; then + outdir="." + fi + ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')" + echo "$cl -nologo -EP $includes $defines $src > $ppsrc" + "$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $? + output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')" + args="-nologo $safeseh $single $output $ppsrc" + + echo "$ml $args" + eval "\"$ml\" $args" + result=$? + + # required to fix ml64 broken output? + #mv *.obj $outdir +else + args="$md $args" + echo "$cl $args" + # Return an error code of 1 if an invalid command line parameter is passed + # instead of just ignoring it. + eval "(\"$cl\" $args 2>&1 1>&3 | \ + awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1" + result=$? +fi + +exit $result + diff --git a/circuitpython/lib/libffi/src/aarch64/ffi.c b/circuitpython/lib/libffi/src/aarch64/ffi.c new file mode 100644 index 0000000..f79602b --- /dev/null +++ b/circuitpython/lib/libffi/src/aarch64/ffi.c @@ -0,0 +1,1152 @@ +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. + +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 +#include +#include +#include +#include +#include "internal.h" + +/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; + all further uses in this file will refer to the 128-bit type. */ +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE +# if FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +#else +# undef FFI_TYPE_LONGDOUBLE +# define FFI_TYPE_LONGDOUBLE 4 +#endif + +union _d +{ + UINT64 d; + UINT32 s[2]; +}; + +struct _v +{ + union _d d[2] __attribute__((aligned(16))); +}; + +struct call_context +{ + struct _v v[N_V_ARG_REG]; + UINT64 x[N_X_ARG_REG]; +}; + +#if defined (__clang__) && defined (__APPLE__) +extern void sys_icache_invalidate (void *start, size_t len); +#endif + +static inline void +ffi_clear_cache (void *start, void *end) +{ +#if defined (__clang__) && defined (__APPLE__) + sys_icache_invalidate (start, (char *)end - (char *)start); +#elif defined (__GNUC__) + __builtin___clear_cache (start, end); +#else +#error "Missing builtin to flush instruction cache" +#endif +} + +/* A subroutine of is_vfp_type. Given a structure type, return the type code + of the first non-structure element. Recurse for structure elements. + Return -1 if the structure is in fact empty, i.e. no nested elements. */ + +static int +is_hfa0 (const ffi_type *ty) +{ + ffi_type **elements = ty->elements; + int i, ret = -1; + + if (elements != NULL) + for (i = 0; elements[i]; ++i) + { + ret = elements[i]->type; + if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX) + { + ret = is_hfa0 (elements[i]); + if (ret < 0) + continue; + } + break; + } + + return ret; +} + +/* A subroutine of is_vfp_type. Given a structure type, return true if all + of the non-structure elements are the same as CANDIDATE. */ + +static int +is_hfa1 (const ffi_type *ty, int candidate) +{ + ffi_type **elements = ty->elements; + int i; + + if (elements != NULL) + for (i = 0; elements[i]; ++i) + { + int t = elements[i]->type; + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX) + { + if (!is_hfa1 (elements[i], candidate)) + return 0; + } + else if (t != candidate) + return 0; + } + + return 1; +} + +/* Determine if TY may be allocated to the FP registers. This is both an + fp scalar type as well as an homogenous floating point aggregate (HFA). + That is, a structure consisting of 1 to 4 members of all the same type, + where that type is an fp scalar. + + Returns non-zero iff TY is an HFA. The result is the AARCH64_RET_* + constant for the type. */ + +static int +is_vfp_type (const ffi_type *ty) +{ + ffi_type **elements; + int candidate, i; + size_t size, ele_count; + + /* Quickest tests first. */ + candidate = ty->type; + switch (candidate) + { + default: + return 0; + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + ele_count = 1; + goto done; + case FFI_TYPE_COMPLEX: + candidate = ty->elements[0]->type; + switch (candidate) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + ele_count = 2; + goto done; + } + return 0; + case FFI_TYPE_STRUCT: + break; + } + + /* No HFA types are smaller than 4 bytes, or larger than 64 bytes. */ + size = ty->size; + if (size < 4 || size > 64) + return 0; + + /* Find the type of the first non-structure member. */ + elements = ty->elements; + candidate = elements[0]->type; + if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX) + { + for (i = 0; ; ++i) + { + candidate = is_hfa0 (elements[i]); + if (candidate >= 0) + break; + } + } + + /* If the first member is not a floating point type, it's not an HFA. + Also quickly re-check the size of the structure. */ + switch (candidate) + { + case FFI_TYPE_FLOAT: + ele_count = size / sizeof(float); + if (size != ele_count * sizeof(float)) + return 0; + break; + case FFI_TYPE_DOUBLE: + ele_count = size / sizeof(double); + if (size != ele_count * sizeof(double)) + return 0; + break; + case FFI_TYPE_LONGDOUBLE: + ele_count = size / sizeof(long double); + if (size != ele_count * sizeof(long double)) + return 0; + break; + default: + return 0; + } + if (ele_count > 4) + return 0; + + /* Finally, make sure that all scalar elements are the same type. */ + for (i = 0; elements[i]; ++i) + { + int t = elements[i]->type; + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX) + { + if (!is_hfa1 (elements[i], candidate)) + return 0; + } + else if (t != candidate) + return 0; + } + + /* All tests succeeded. Encode the result. */ + done: + return candidate * 4 + (4 - ele_count); +} + +/* Representation of the procedure call argument marshalling + state. + + The terse state variable names match the names used in the AARCH64 + PCS. */ + +struct arg_state +{ + unsigned ngrn; /* Next general-purpose register number. */ + unsigned nsrn; /* Next vector register number. */ + size_t nsaa; /* Next stack offset. */ + +#if defined (__APPLE__) + unsigned allocating_variadic; +#endif +}; + +/* Initialize a procedure call argument marshalling state. */ +static void +arg_init (struct arg_state *state) +{ + state->ngrn = 0; + state->nsrn = 0; + state->nsaa = 0; +#if defined (__APPLE__) + state->allocating_variadic = 0; +#endif +} + +/* Allocate an aligned slot on the stack and return a pointer to it. */ +static void * +allocate_to_stack (struct arg_state *state, void *stack, + size_t alignment, size_t size) +{ + size_t nsaa = state->nsaa; + + /* Round up the NSAA to the larger of 8 or the natural + alignment of the argument's type. */ +#if defined (__APPLE__) + if (state->allocating_variadic && alignment < 8) + alignment = 8; +#else + if (alignment < 8) + alignment = 8; +#endif + + nsaa = ALIGN (nsaa, alignment); + state->nsaa = nsaa + size; + + return (char *)stack + nsaa; +} + +static ffi_arg +extend_integer_type (void *source, int type) +{ + switch (type) + { + case FFI_TYPE_UINT8: + return *(UINT8 *) source; + case FFI_TYPE_SINT8: + return *(SINT8 *) source; + case FFI_TYPE_UINT16: + return *(UINT16 *) source; + case FFI_TYPE_SINT16: + return *(SINT16 *) source; + case FFI_TYPE_UINT32: + return *(UINT32 *) source; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + return *(SINT32 *) source; + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + return *(UINT64 *) source; + break; + case FFI_TYPE_POINTER: + return *(uintptr_t *) source; + default: + abort(); + } +} + +static void +extend_hfa_type (void *dest, void *src, int h) +{ + int f = h - AARCH64_RET_S4; + void *x0; + + asm volatile ( + "adr %0, 0f\n" +" add %0, %0, %1\n" +" br %0\n" +"0: ldp s16, s17, [%3]\n" /* S4 */ +" ldp s18, s19, [%3, #8]\n" +" b 4f\n" +" ldp s16, s17, [%3]\n" /* S3 */ +" ldr s18, [%3, #8]\n" +" b 3f\n" +" ldp s16, s17, [%3]\n" /* S2 */ +" b 2f\n" +" nop\n" +" ldr s16, [%3]\n" /* S1 */ +" b 1f\n" +" nop\n" +" ldp d16, d17, [%3]\n" /* D4 */ +" ldp d18, d19, [%3, #16]\n" +" b 4f\n" +" ldp d16, d17, [%3]\n" /* D3 */ +" ldr d18, [%3, #16]\n" +" b 3f\n" +" ldp d16, d17, [%3]\n" /* D2 */ +" b 2f\n" +" nop\n" +" ldr d16, [%3]\n" /* D1 */ +" b 1f\n" +" nop\n" +" ldp q16, q17, [%3]\n" /* Q4 */ +" ldp q18, q19, [%3, #16]\n" +" b 4f\n" +" ldp q16, q17, [%3]\n" /* Q3 */ +" ldr q18, [%3, #16]\n" +" b 3f\n" +" ldp q16, q17, [%3]\n" /* Q2 */ +" b 2f\n" +" nop\n" +" ldr q16, [%3]\n" /* Q1 */ +" b 1f\n" +"4: str q19, [%2, #48]\n" +"3: str q18, [%2, #32]\n" +"2: str q17, [%2, #16]\n" +"1: str q16, [%2]" + : "=&r"(x0) + : "r"(f * 12), "r"(dest), "r"(src) + : "memory", "v16", "v17", "v18", "v19"); +} + +static void * +compress_hfa_type (void *dest, void *reg, int h) +{ + switch (h) + { + case AARCH64_RET_S1: + if (dest == reg) + { +#ifdef __AARCH64EB__ + dest += 12; +#endif + } + else + *(float *)dest = *(float *)reg; + break; + case AARCH64_RET_S2: + asm ("ldp q16, q17, [%1]\n\t" + "st2 { v16.s, v17.s }[0], [%0]" + : : "r"(dest), "r"(reg) : "memory", "v16", "v17"); + break; + case AARCH64_RET_S3: + asm ("ldp q16, q17, [%1]\n\t" + "ldr q18, [%1, #32]\n\t" + "st3 { v16.s, v17.s, v18.s }[0], [%0]" + : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18"); + break; + case AARCH64_RET_S4: + asm ("ldp q16, q17, [%1]\n\t" + "ldp q18, q19, [%1, #32]\n\t" + "st4 { v16.s, v17.s, v18.s, v19.s }[0], [%0]" + : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19"); + break; + + case AARCH64_RET_D1: + if (dest == reg) + { +#ifdef __AARCH64EB__ + dest += 8; +#endif + } + else + *(double *)dest = *(double *)reg; + break; + case AARCH64_RET_D2: + asm ("ldp q16, q17, [%1]\n\t" + "st2 { v16.d, v17.d }[0], [%0]" + : : "r"(dest), "r"(reg) : "memory", "v16", "v17"); + break; + case AARCH64_RET_D3: + asm ("ldp q16, q17, [%1]\n\t" + "ldr q18, [%1, #32]\n\t" + "st3 { v16.d, v17.d, v18.d }[0], [%0]" + : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18"); + break; + case AARCH64_RET_D4: + asm ("ldp q16, q17, [%1]\n\t" + "ldp q18, q19, [%1, #32]\n\t" + "st4 { v16.d, v17.d, v18.d, v19.d }[0], [%0]" + : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19"); + break; + + default: + if (dest != reg) + return memcpy (dest, reg, 16 * (4 - (h & 3))); + break; + } + return dest; +} + +/* Either allocate an appropriate register for the argument type, or if + none are available, allocate a stack slot and return a pointer + to the allocated space. */ + +static void * +allocate_int_to_reg_or_stack (struct call_context *context, + struct arg_state *state, + void *stack, size_t size) +{ + if (state->ngrn < N_X_ARG_REG) + return &context->x[state->ngrn++]; + + state->ngrn = N_X_ARG_REG; + return allocate_to_stack (state, stack, size, size); +} + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + ffi_type *rtype = cif->rtype; + size_t bytes = cif->bytes; + int flags, i, n; + + switch (rtype->type) + { + case FFI_TYPE_VOID: + flags = AARCH64_RET_VOID; + break; + case FFI_TYPE_UINT8: + flags = AARCH64_RET_UINT8; + break; + case FFI_TYPE_UINT16: + flags = AARCH64_RET_UINT16; + break; + case FFI_TYPE_UINT32: + flags = AARCH64_RET_UINT32; + break; + case FFI_TYPE_SINT8: + flags = AARCH64_RET_SINT8; + break; + case FFI_TYPE_SINT16: + flags = AARCH64_RET_SINT16; + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + flags = AARCH64_RET_SINT32; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + flags = AARCH64_RET_INT64; + break; + case FFI_TYPE_POINTER: + flags = (sizeof(void *) == 4 ? AARCH64_RET_UINT32 : AARCH64_RET_INT64); + break; + + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: + flags = is_vfp_type (rtype); + if (flags == 0) + { + size_t s = rtype->size; + if (s > 16) + { + flags = AARCH64_RET_VOID | AARCH64_RET_IN_MEM; + bytes += 8; + } + else if (s == 16) + flags = AARCH64_RET_INT128; + else if (s == 8) + flags = AARCH64_RET_INT64; + else + flags = AARCH64_RET_INT128 | AARCH64_RET_NEED_COPY; + } + break; + + default: + abort(); + } + + for (i = 0, n = cif->nargs; i < n; i++) + if (is_vfp_type (cif->arg_types[i])) + { + flags |= AARCH64_FLAG_ARG_V; + break; + } + + /* Round the stack up to a multiple of the stack alignment requirement. */ + cif->bytes = ALIGN(bytes, 16); + cif->flags = flags; +#if defined (__APPLE__) + cif->aarch64_nfixedargs = 0; +#endif + + return FFI_OK; +} + +#if defined (__APPLE__) +/* Perform Apple-specific cif processing for variadic calls */ +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, + unsigned int nfixedargs, + unsigned int ntotalargs) +{ + ffi_status status = ffi_prep_cif_machdep (cif); + cif->aarch64_nfixedargs = nfixedargs; + return status; +} +#endif /* __APPLE__ */ + +extern void ffi_call_SYSV (struct call_context *context, void *frame, + void (*fn)(void), void *rvalue, int flags, + void *closure) FFI_HIDDEN; + +/* Call a function with the provided arguments and capture the return + value. */ +static void +ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue, + void **avalue, void *closure) +{ + struct call_context *context; + void *stack, *frame, *rvalue; + struct arg_state state; + size_t stack_bytes, rtype_size, rsize; + int i, nargs, flags; + ffi_type *rtype; + + flags = cif->flags; + rtype = cif->rtype; + rtype_size = rtype->size; + stack_bytes = cif->bytes; + + /* If the target function returns a structure via hidden pointer, + then we cannot allow a null rvalue. Otherwise, mash a null + rvalue to void return type. */ + rsize = 0; + if (flags & AARCH64_RET_IN_MEM) + { + if (orig_rvalue == NULL) + rsize = rtype_size; + } + else if (orig_rvalue == NULL) + flags &= AARCH64_FLAG_ARG_V; + else if (flags & AARCH64_RET_NEED_COPY) + rsize = 16; + + /* Allocate consectutive stack for everything we'll need. */ + context = alloca (sizeof(struct call_context) + stack_bytes + 32 + rsize); + stack = context + 1; + frame = stack + stack_bytes; + rvalue = (rsize ? frame + 32 : orig_rvalue); + + arg_init (&state); + for (i = 0, nargs = cif->nargs; i < nargs; i++) + { + ffi_type *ty = cif->arg_types[i]; + size_t s = ty->size; + void *a = avalue[i]; + int h, t; + + t = ty->type; + switch (t) + { + case FFI_TYPE_VOID: + FFI_ASSERT (0); + break; + + /* If the argument is a basic type the argument is allocated to an + appropriate register, or if none are available, to the stack. */ + case FFI_TYPE_INT: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + do_pointer: + { + ffi_arg ext = extend_integer_type (a, t); + if (state.ngrn < N_X_ARG_REG) + context->x[state.ngrn++] = ext; + else + { + void *d = allocate_to_stack (&state, stack, ty->alignment, s); + state.ngrn = N_X_ARG_REG; + /* Note that the default abi extends each argument + to a full 64-bit slot, while the iOS abi allocates + only enough space. */ +#ifdef __APPLE__ + memcpy(d, a, s); +#else + *(ffi_arg *)d = ext; +#endif + } + } + break; + + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: + { + void *dest; + + h = is_vfp_type (ty); + if (h) + { + int elems = 4 - (h & 3); + if (state.nsrn + elems <= N_V_ARG_REG) + { + dest = &context->v[state.nsrn]; + state.nsrn += elems; + extend_hfa_type (dest, a, h); + break; + } + state.nsrn = N_V_ARG_REG; + dest = allocate_to_stack (&state, stack, ty->alignment, s); + } + else if (s > 16) + { + /* If the argument is a composite type that is larger than 16 + bytes, then the argument has been copied to memory, and + the argument is replaced by a pointer to the copy. */ + a = &avalue[i]; + t = FFI_TYPE_POINTER; + goto do_pointer; + } + else + { + size_t n = (s + 7) / 8; + if (state.ngrn + n <= N_X_ARG_REG) + { + /* If the argument is a composite type and the size in + double-words is not more than the number of available + X registers, then the argument is copied into + consecutive X registers. */ + dest = &context->x[state.ngrn]; + state.ngrn += n; + } + else + { + /* Otherwise, there are insufficient X registers. Further + X register allocations are prevented, the NSAA is + adjusted and the argument is copied to memory at the + adjusted NSAA. */ + state.ngrn = N_X_ARG_REG; + dest = allocate_to_stack (&state, stack, ty->alignment, s); + } + } + memcpy (dest, a, s); + } + break; + + default: + abort(); + } + +#if defined (__APPLE__) + if (i + 1 == cif->aarch64_nfixedargs) + { + state.ngrn = N_X_ARG_REG; + state.nsrn = N_V_ARG_REG; + state.allocating_variadic = 1; + } +#endif + } + + ffi_call_SYSV (context, frame, fn, rvalue, flags, closure); + + if (flags & AARCH64_RET_NEED_COPY) + memcpy (orig_rvalue, rvalue, rtype_size); +} + +void +ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +#ifdef FFI_GO_CLOSURES +void +ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} +#endif /* FFI_GO_CLOSURES */ + +/* Build a trampoline. */ + +extern void ffi_closure_SYSV (void) FFI_HIDDEN; +extern void ffi_closure_SYSV_V (void) FFI_HIDDEN; + +#if FFI_EXEC_TRAMPOLINE_TABLE + +#include +#include +#include +#include + +extern void *ffi_closure_trampoline_table_page; + +typedef struct ffi_trampoline_table ffi_trampoline_table; +typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry; + +struct ffi_trampoline_table +{ + /* contiguous writable and executable pages */ + vm_address_t config_page; + vm_address_t trampoline_page; + + /* free list tracking */ + uint16_t free_count; + ffi_trampoline_table_entry *free_list; + ffi_trampoline_table_entry *free_list_pool; + + ffi_trampoline_table *prev; + ffi_trampoline_table *next; +}; + +struct ffi_trampoline_table_entry +{ + void *(*trampoline) (); + ffi_trampoline_table_entry *next; +}; + +/* The trampoline configuration is placed a page prior to the trampoline's entry point */ +#define FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc) ((void **) (((uint8_t *) codeloc) - PAGE_SIZE)); + +/* Total number of trampolines that fit in one trampoline table */ +#define FFI_TRAMPOLINE_COUNT (PAGE_SIZE / FFI_TRAMPOLINE_SIZE) + +static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER; +static ffi_trampoline_table *ffi_trampoline_tables = NULL; + +static ffi_trampoline_table * +ffi_trampoline_table_alloc () +{ + ffi_trampoline_table *table = NULL; + + /* Loop until we can allocate two contiguous pages */ + while (table == NULL) + { + vm_address_t config_page = 0x0; + kern_return_t kt; + + /* Try to allocate two pages */ + kt = + vm_allocate (mach_task_self (), &config_page, PAGE_SIZE * 2, + VM_FLAGS_ANYWHERE); + if (kt != KERN_SUCCESS) + { + fprintf (stderr, "vm_allocate() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + break; + } + + /* Now drop the second half of the allocation to make room for the trampoline table */ + vm_address_t trampoline_page = config_page + PAGE_SIZE; + kt = vm_deallocate (mach_task_self (), trampoline_page, PAGE_SIZE); + if (kt != KERN_SUCCESS) + { + fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + break; + } + + /* Remap the trampoline table to directly follow the config page */ + vm_prot_t cur_prot; + vm_prot_t max_prot; + + kt = + vm_remap (mach_task_self (), &trampoline_page, PAGE_SIZE, 0x0, FALSE, + mach_task_self (), + (vm_address_t) & ffi_closure_trampoline_table_page, FALSE, + &cur_prot, &max_prot, VM_INHERIT_SHARE); + + /* If we lost access to the destination trampoline page, drop our config allocation mapping and retry */ + if (kt != KERN_SUCCESS) + { + /* Log unexpected failures */ + if (kt != KERN_NO_SPACE) + { + fprintf (stderr, "vm_remap() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + } + + vm_deallocate (mach_task_self (), config_page, PAGE_SIZE); + continue; + } + + /* We have valid trampoline and config pages */ + table = calloc (1, sizeof (ffi_trampoline_table)); + table->free_count = FFI_TRAMPOLINE_COUNT; + table->config_page = config_page; + table->trampoline_page = trampoline_page; + + /* Create and initialize the free list */ + table->free_list_pool = + calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry)); + + uint16_t i; + for (i = 0; i < table->free_count; i++) + { + ffi_trampoline_table_entry *entry = &table->free_list_pool[i]; + entry->trampoline = + (void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE)); + + if (i < table->free_count - 1) + entry->next = &table->free_list_pool[i + 1]; + } + + table->free_list = table->free_list_pool; + } + + return table; +} + +void * +ffi_closure_alloc (size_t size, void **code) +{ + /* Create the closure */ + ffi_closure *closure = malloc (size); + if (closure == NULL) + return NULL; + + pthread_mutex_lock (&ffi_trampoline_lock); + + /* Check for an active trampoline table with available entries. */ + ffi_trampoline_table *table = ffi_trampoline_tables; + if (table == NULL || table->free_list == NULL) + { + table = ffi_trampoline_table_alloc (); + if (table == NULL) + { + free (closure); + return NULL; + } + + /* Insert the new table at the top of the list */ + table->next = ffi_trampoline_tables; + if (table->next != NULL) + table->next->prev = table; + + ffi_trampoline_tables = table; + } + + /* Claim the free entry */ + ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list; + ffi_trampoline_tables->free_list = entry->next; + ffi_trampoline_tables->free_count--; + entry->next = NULL; + + pthread_mutex_unlock (&ffi_trampoline_lock); + + /* Initialize the return values */ + *code = entry->trampoline; + closure->trampoline_table = table; + closure->trampoline_table_entry = entry; + + return closure; +} + +void +ffi_closure_free (void *ptr) +{ + ffi_closure *closure = ptr; + + pthread_mutex_lock (&ffi_trampoline_lock); + + /* Fetch the table and entry references */ + ffi_trampoline_table *table = closure->trampoline_table; + ffi_trampoline_table_entry *entry = closure->trampoline_table_entry; + + /* Return the entry to the free list */ + entry->next = table->free_list; + table->free_list = entry; + table->free_count++; + + /* If all trampolines within this table are free, and at least one other table exists, deallocate + * the table */ + if (table->free_count == FFI_TRAMPOLINE_COUNT + && ffi_trampoline_tables != table) + { + /* Remove from the list */ + if (table->prev != NULL) + table->prev->next = table->next; + + if (table->next != NULL) + table->next->prev = table->prev; + + /* Deallocate pages */ + kern_return_t kt; + kt = vm_deallocate (mach_task_self (), table->config_page, PAGE_SIZE); + if (kt != KERN_SUCCESS) + fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + + kt = + vm_deallocate (mach_task_self (), table->trampoline_page, PAGE_SIZE); + if (kt != KERN_SUCCESS) + fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + + /* Deallocate free list */ + free (table->free_list_pool); + free (table); + } + else if (ffi_trampoline_tables != table) + { + /* Otherwise, bump this table to the top of the list */ + table->prev = NULL; + table->next = ffi_trampoline_tables; + if (ffi_trampoline_tables != NULL) + ffi_trampoline_tables->prev = table; + + ffi_trampoline_tables = table; + } + + pthread_mutex_unlock (&ffi_trampoline_lock); + + /* Free the closure */ + free (closure); +} + +#endif + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + void (*start)(void); + + if (cif->flags & AARCH64_FLAG_ARG_V) + start = ffi_closure_SYSV_V; + else + start = ffi_closure_SYSV; + +#if FFI_EXEC_TRAMPOLINE_TABLE + void **config = FFI_TRAMPOLINE_CODELOC_CONFIG (codeloc); + config[0] = closure; + config[1] = start; +#else + static const unsigned char trampoline[16] = { + 0x90, 0x00, 0x00, 0x58, /* ldr x16, tramp+16 */ + 0xf1, 0xff, 0xff, 0x10, /* adr x17, tramp+0 */ + 0x00, 0x02, 0x1f, 0xd6 /* br x16 */ + }; + char *tramp = closure->tramp; + + memcpy (tramp, trampoline, sizeof(trampoline)); + + *(UINT64 *)(tramp + 16) = (uintptr_t)start; + + ffi_clear_cache(tramp, tramp + FFI_TRAMPOLINE_SIZE); +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +#ifdef FFI_GO_CLOSURES +extern void ffi_go_closure_SYSV (void) FFI_HIDDEN; +extern void ffi_go_closure_SYSV_V (void) FFI_HIDDEN; + +ffi_status +ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*)) +{ + void (*start)(void); + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + if (cif->flags & AARCH64_FLAG_ARG_V) + start = ffi_go_closure_SYSV_V; + else + start = ffi_go_closure_SYSV; + + closure->tramp = start; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} +#endif /* FFI_GO_CLOSURES */ + +/* Primary handler to setup and invoke a function within a closure. + + A closure when invoked enters via the assembler wrapper + ffi_closure_SYSV(). The wrapper allocates a call context on the + stack, saves the interesting registers (from the perspective of + the calling convention) into the context then passes control to + ffi_closure_SYSV_inner() passing the saved context and a pointer to + the stack at the point ffi_closure_SYSV() was invoked. + + On the return path the assembler wrapper will reload call context + registers. + + ffi_closure_SYSV_inner() marshalls the call context into ffi value + descriptors, invokes the wrapped function, then marshalls the return + value back into the call context. */ + +int FFI_HIDDEN +ffi_closure_SYSV_inner (ffi_cif *cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + struct call_context *context, + void *stack, void *rvalue, void *struct_rvalue) +{ + void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); + int i, h, nargs, flags; + struct arg_state state; + + arg_init (&state); + + for (i = 0, nargs = cif->nargs; i < nargs; i++) + { + ffi_type *ty = cif->arg_types[i]; + int t = ty->type; + size_t n, s = ty->size; + + switch (t) + { + case FFI_TYPE_VOID: + FFI_ASSERT (0); + break; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + avalue[i] = allocate_int_to_reg_or_stack (context, &state, stack, s); + break; + + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: + h = is_vfp_type (ty); + if (h) + { + n = 4 - (h & 3); + if (state.nsrn + n <= N_V_ARG_REG) + { + void *reg = &context->v[state.nsrn]; + state.nsrn += n; + + /* Eeek! We need a pointer to the structure, however the + homogeneous float elements are being passed in individual + registers, therefore for float and double the structure + is not represented as a contiguous sequence of bytes in + our saved register context. We don't need the original + contents of the register storage, so we reformat the + structure into the same memory. */ + avalue[i] = compress_hfa_type (reg, reg, h); + } + else + { + state.nsrn = N_V_ARG_REG; + avalue[i] = allocate_to_stack (&state, stack, + ty->alignment, s); + } + } + else if (s > 16) + { + /* Replace Composite type of size greater than 16 with a + pointer. */ + avalue[i] = *(void **) + allocate_int_to_reg_or_stack (context, &state, stack, + sizeof (void *)); + } + else + { + n = (s + 7) / 8; + if (state.ngrn + n <= N_X_ARG_REG) + { + avalue[i] = &context->x[state.ngrn]; + state.ngrn += n; + } + else + { + state.ngrn = N_X_ARG_REG; + avalue[i] = allocate_to_stack (&state, stack, + ty->alignment, s); + } + } + break; + + default: + abort(); + } + } + + flags = cif->flags; + if (flags & AARCH64_RET_IN_MEM) + rvalue = struct_rvalue; + + fun (cif, rvalue, avalue, user_data); + + return flags; +} diff --git a/circuitpython/lib/libffi/src/aarch64/ffitarget.h b/circuitpython/lib/libffi/src/aarch64/ffitarget.h new file mode 100644 index 0000000..2862ec7 --- /dev/null +++ b/circuitpython/lib/libffi/src/aarch64/ffitarget.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +``Software''), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +#ifdef __ILP32__ +#define FFI_SIZEOF_ARG 8 +typedef unsigned long long ffi_arg; +typedef signed long long ffi_sarg; +#else +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; +#endif + +typedef enum ffi_abi + { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV + } ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#if defined (__APPLE__) +#define FFI_TRAMPOLINE_SIZE 20 +#define FFI_TRAMPOLINE_CLOSURE_OFFSET 16 +#else +#define FFI_TRAMPOLINE_SIZE 24 +#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE +#endif +#define FFI_NATIVE_RAW_API 0 + +/* ---- Internal ---- */ + +#if defined (__APPLE__) +#define FFI_TARGET_SPECIFIC_VARIADIC +#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs +#else +/* iOS reserves x18 for the system. Disable Go closures until + a new static chain is chosen. */ +#define FFI_GO_CLOSURES 1 +#endif + +#define FFI_TARGET_HAS_COMPLEX_TYPE + +#endif diff --git a/circuitpython/lib/libffi/src/aarch64/internal.h b/circuitpython/lib/libffi/src/aarch64/internal.h new file mode 100644 index 0000000..9c3e077 --- /dev/null +++ b/circuitpython/lib/libffi/src/aarch64/internal.h @@ -0,0 +1,67 @@ +/* +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 AARCH64_RET_VOID 0 +#define AARCH64_RET_INT64 1 +#define AARCH64_RET_INT128 2 + +#define AARCH64_RET_UNUSED3 3 +#define AARCH64_RET_UNUSED4 4 +#define AARCH64_RET_UNUSED5 5 +#define AARCH64_RET_UNUSED6 6 +#define AARCH64_RET_UNUSED7 7 + +/* Note that FFI_TYPE_FLOAT == 2, _DOUBLE == 3, _LONGDOUBLE == 4, + so _S4 through _Q1 are layed out as (TYPE * 4) + (4 - COUNT). */ +#define AARCH64_RET_S4 8 +#define AARCH64_RET_S3 9 +#define AARCH64_RET_S2 10 +#define AARCH64_RET_S1 11 + +#define AARCH64_RET_D4 12 +#define AARCH64_RET_D3 13 +#define AARCH64_RET_D2 14 +#define AARCH64_RET_D1 15 + +#define AARCH64_RET_Q4 16 +#define AARCH64_RET_Q3 17 +#define AARCH64_RET_Q2 18 +#define AARCH64_RET_Q1 19 + +/* Note that each of the sub-64-bit integers gets two entries. */ +#define AARCH64_RET_UINT8 20 +#define AARCH64_RET_UINT16 22 +#define AARCH64_RET_UINT32 24 + +#define AARCH64_RET_SINT8 26 +#define AARCH64_RET_SINT16 28 +#define AARCH64_RET_SINT32 30 + +#define AARCH64_RET_MASK 31 + +#define AARCH64_RET_IN_MEM (1 << 5) +#define AARCH64_RET_NEED_COPY (1 << 6) + +#define AARCH64_FLAG_ARG_V_BIT 7 +#define AARCH64_FLAG_ARG_V (1 << AARCH64_FLAG_ARG_V_BIT) + +#define N_X_ARG_REG 8 +#define N_V_ARG_REG 8 +#define CALL_CONTEXT_SIZE (N_V_ARG_REG * 16 + N_X_ARG_REG * 8) diff --git a/circuitpython/lib/libffi/src/aarch64/sysv.S b/circuitpython/lib/libffi/src/aarch64/sysv.S new file mode 100644 index 0000000..c1bf9b9 --- /dev/null +++ b/circuitpython/lib/libffi/src/aarch64/sysv.S @@ -0,0 +1,434 @@ +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. + +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 LIBFFI_ASM +#include +#include +#include +#include "internal.h" + +#ifdef HAVE_MACHINE_ASM_H +#include +#else +#ifdef __USER_LABEL_PREFIX__ +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ +#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x) +#else +#define CNAME(x) x +#endif +#endif + +#ifdef __AARCH64EB__ +# define BE(X) X +#else +# define BE(X) 0 +#endif + +#ifdef __ILP32__ +#define PTR_REG(n) w##n +#else +#define PTR_REG(n) x##n +#endif + +#ifdef __ILP32__ +#define PTR_SIZE 4 +#else +#define PTR_SIZE 8 +#endif + + .text + .align 4 + +/* ffi_call_SYSV + extern void ffi_call_SYSV (void *stack, void *frame, + void (*fn)(void), void *rvalue, + int flags, void *closure); + + Therefore on entry we have: + + x0 stack + x1 frame + x2 fn + x3 rvalue + x4 flags + x5 closure +*/ + + cfi_startproc +CNAME(ffi_call_SYSV): + /* Use a stack frame allocated by our caller. */ + cfi_def_cfa(x1, 32); + stp x29, x30, [x1] + mov x29, x1 + mov sp, x0 + cfi_def_cfa_register(x29) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) + + mov x9, x2 /* save fn */ + mov x8, x3 /* install structure return */ +#ifdef FFI_GO_CLOSURES + mov x18, x5 /* install static chain */ +#endif + stp x3, x4, [x29, #16] /* save rvalue and flags */ + + /* Load the vector argument passing registers, if necessary. */ + tbz w4, #AARCH64_FLAG_ARG_V_BIT, 1f + ldp q0, q1, [sp, #0] + ldp q2, q3, [sp, #32] + ldp q4, q5, [sp, #64] + ldp q6, q7, [sp, #96] +1: + /* Load the core argument passing registers, including + the structure return pointer. */ + ldp x0, x1, [sp, #16*N_V_ARG_REG + 0] + ldp x2, x3, [sp, #16*N_V_ARG_REG + 16] + ldp x4, x5, [sp, #16*N_V_ARG_REG + 32] + ldp x6, x7, [sp, #16*N_V_ARG_REG + 48] + + /* Deallocate the context, leaving the stacked arguments. */ + add sp, sp, #CALL_CONTEXT_SIZE + + blr x9 /* call fn */ + + ldp x3, x4, [x29, #16] /* reload rvalue and flags */ + + /* Partially deconstruct the stack frame. */ + mov sp, x29 + cfi_def_cfa_register (sp) + ldp x29, x30, [x29] + + /* Save the return value as directed. */ + adr x5, 0f + and w4, w4, #AARCH64_RET_MASK + add x5, x5, x4, lsl #3 + br x5 + + /* Note that each table entry is 2 insns, and thus 8 bytes. + For integer data, note that we're storing into ffi_arg + and therefore we want to extend to 64 bits; these types + have two consecutive entries allocated for them. */ + .align 4 +0: ret /* VOID */ + nop +1: str x0, [x3] /* INT64 */ + ret +2: stp x0, x1, [x3] /* INT128 */ + ret +3: brk #1000 /* UNUSED */ + ret +4: brk #1000 /* UNUSED */ + ret +5: brk #1000 /* UNUSED */ + ret +6: brk #1000 /* UNUSED */ + ret +7: brk #1000 /* UNUSED */ + ret +8: st4 { v0.s, v1.s, v2.s, v3.s }[0], [x3] /* S4 */ + ret +9: st3 { v0.s, v1.s, v2.s }[0], [x3] /* S3 */ + ret +10: stp s0, s1, [x3] /* S2 */ + ret +11: str s0, [x3] /* S1 */ + ret +12: st4 { v0.d, v1.d, v2.d, v3.d }[0], [x3] /* D4 */ + ret +13: st3 { v0.d, v1.d, v2.d }[0], [x3] /* D3 */ + ret +14: stp d0, d1, [x3] /* D2 */ + ret +15: str d0, [x3] /* D1 */ + ret +16: str q3, [x3, #48] /* Q4 */ + nop +17: str q2, [x3, #32] /* Q3 */ + nop +18: stp q0, q1, [x3] /* Q2 */ + ret +19: str q0, [x3] /* Q1 */ + ret +20: uxtb w0, w0 /* UINT8 */ + str x0, [x3] +21: ret /* reserved */ + nop +22: uxth w0, w0 /* UINT16 */ + str x0, [x3] +23: ret /* reserved */ + nop +24: mov w0, w0 /* UINT32 */ + str x0, [x3] +25: ret /* reserved */ + nop +26: sxtb x0, w0 /* SINT8 */ + str x0, [x3] +27: ret /* reserved */ + nop +28: sxth x0, w0 /* SINT16 */ + str x0, [x3] +29: ret /* reserved */ + nop +30: sxtw x0, w0 /* SINT32 */ + str x0, [x3] +31: ret /* reserved */ + nop + + cfi_endproc + + .globl CNAME(ffi_call_SYSV) +#ifdef __ELF__ + .type CNAME(ffi_call_SYSV), #function + .hidden CNAME(ffi_call_SYSV) + .size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV) +#endif + +/* ffi_closure_SYSV + + Closure invocation glue. This is the low level code invoked directly by + the closure trampoline to setup and call a closure. + + On entry x17 points to a struct ffi_closure, x16 has been clobbered + all other registers are preserved. + + We allocate a call context and save the argument passing registers, + then invoked the generic C ffi_closure_SYSV_inner() function to do all + the real work, on return we load the result passing registers back from + the call context. +*/ + +#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64) + + .align 4 +CNAME(ffi_closure_SYSV_V): + cfi_startproc + stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! + cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) + + /* Save the argument passing vector registers. */ + stp q0, q1, [sp, #16 + 0] + stp q2, q3, [sp, #16 + 32] + stp q4, q5, [sp, #16 + 64] + stp q6, q7, [sp, #16 + 96] + b 0f + cfi_endproc + + .globl CNAME(ffi_closure_SYSV_V) +#ifdef __ELF__ + .type CNAME(ffi_closure_SYSV_V), #function + .hidden CNAME(ffi_closure_SYSV_V) + .size CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V) +#endif + + .align 4 + cfi_startproc +CNAME(ffi_closure_SYSV): + stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! + cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) +0: + mov x29, sp + + /* Save the argument passing core registers. */ + stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0] + stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16] + stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32] + stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48] + + /* Load ffi_closure_inner arguments. */ + ldp PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET] /* load cif, fn */ + ldr PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2] /* load user_data */ +.Ldo_closure: + add x3, sp, #16 /* load context */ + add x4, sp, #ffi_closure_SYSV_FS /* load stack */ + add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */ + mov x6, x8 /* load struct_rval */ + bl CNAME(ffi_closure_SYSV_inner) + + /* Load the return value as directed. */ + adr x1, 0f + and w0, w0, #AARCH64_RET_MASK + add x1, x1, x0, lsl #3 + add x3, sp, #16+CALL_CONTEXT_SIZE + br x1 + + /* Note that each table entry is 2 insns, and thus 8 bytes. */ + .align 4 +0: b 99f /* VOID */ + nop +1: ldr x0, [x3] /* INT64 */ + b 99f +2: ldp x0, x1, [x3] /* INT128 */ + b 99f +3: brk #1000 /* UNUSED */ + nop +4: brk #1000 /* UNUSED */ + nop +5: brk #1000 /* UNUSED */ + nop +6: brk #1000 /* UNUSED */ + nop +7: brk #1000 /* UNUSED */ + nop +8: ldr s3, [x3, #12] /* S4 */ + nop +9: ldr s2, [x2, #8] /* S3 */ + nop +10: ldp s0, s1, [x3] /* S2 */ + b 99f +11: ldr s0, [x3] /* S1 */ + b 99f +12: ldr d3, [x3, #24] /* D4 */ + nop +13: ldr d2, [x3, #16] /* D3 */ + nop +14: ldp d0, d1, [x3] /* D2 */ + b 99f +15: ldr d0, [x3] /* D1 */ + b 99f +16: ldr q3, [x3, #48] /* Q4 */ + nop +17: ldr q2, [x3, #32] /* Q3 */ + nop +18: ldp q0, q1, [x3] /* Q2 */ + b 99f +19: ldr q0, [x3] /* Q1 */ + b 99f +20: ldrb w0, [x3, #BE(7)] /* UINT8 */ + b 99f +21: brk #1000 /* reserved */ + nop +22: ldrh w0, [x3, #BE(6)] /* UINT16 */ + b 99f +23: brk #1000 /* reserved */ + nop +24: ldr w0, [x3, #BE(4)] /* UINT32 */ + b 99f +25: brk #1000 /* reserved */ + nop +26: ldrsb x0, [x3, #BE(7)] /* SINT8 */ + b 99f +27: brk #1000 /* reserved */ + nop +28: ldrsh x0, [x3, #BE(6)] /* SINT16 */ + b 99f +29: brk #1000 /* reserved */ + nop +30: ldrsw x0, [x3, #BE(4)] /* SINT32 */ + nop +31: /* reserved */ +99: ldp x29, x30, [sp], #ffi_closure_SYSV_FS + cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS) + cfi_restore (x29) + cfi_restore (x30) + ret + cfi_endproc + + .globl CNAME(ffi_closure_SYSV) +#ifdef __ELF__ + .type CNAME(ffi_closure_SYSV), #function + .hidden CNAME(ffi_closure_SYSV) + .size CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV) +#endif + +#if FFI_EXEC_TRAMPOLINE_TABLE + .align 12 +CNAME(ffi_closure_trampoline_table_page): + .rept 16384 / FFI_TRAMPOLINE_SIZE + adr x17, -16384 + adr x16, -16380 + ldr x16, [x16] + ldr x17, [x17] + br x16 + .endr + + .globl CNAME(ffi_closure_trampoline_table_page) + #ifdef __ELF__ + .type CNAME(ffi_closure_trampoline_table_page), #function + .hidden CNAME(ffi_closure_trampoline_table_page) + .size CNAME(ffi_closure_trampoline_table_page), . - CNAME(ffi_closure_trampoline_table_page) + #endif +#endif + +#ifdef FFI_GO_CLOSURES + .align 4 +CNAME(ffi_go_closure_SYSV_V): + cfi_startproc + stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! + cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) + + /* Save the argument passing vector registers. */ + stp q0, q1, [sp, #16 + 0] + stp q2, q3, [sp, #16 + 32] + stp q4, q5, [sp, #16 + 64] + stp q6, q7, [sp, #16 + 96] + b 0f + cfi_endproc + + .globl CNAME(ffi_go_closure_SYSV_V) +#ifdef __ELF__ + .type CNAME(ffi_go_closure_SYSV_V), #function + .hidden CNAME(ffi_go_closure_SYSV_V) + .size CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V) +#endif + + .align 4 + cfi_startproc +CNAME(ffi_go_closure_SYSV): + stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! + cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) +0: + mov x29, sp + + /* Save the argument passing core registers. */ + stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0] + stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16] + stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32] + stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48] + + /* Load ffi_closure_inner arguments. */ + ldp PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */ + mov x2, x18 /* load user_data */ + b .Ldo_closure + cfi_endproc + + .globl CNAME(ffi_go_closure_SYSV) +#ifdef __ELF__ + .type CNAME(ffi_go_closure_SYSV), #function + .hidden CNAME(ffi_go_closure_SYSV) + .size CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV) +#endif +#endif /* FFI_GO_CLOSURES */ + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",%progbits +#endif + diff --git a/circuitpython/lib/libffi/src/alpha/ffi.c b/circuitpython/lib/libffi/src/alpha/ffi.c new file mode 100644 index 0000000..efae4cc --- /dev/null +++ b/circuitpython/lib/libffi/src/alpha/ffi.c @@ -0,0 +1,521 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2012 Anthony Green + Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc. + + Alpha Foreign Function Interface + + 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 +#include +#include +#include "internal.h" + +/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; + all further uses in this file will refer to the 128-bit type. */ +#if defined(__LONG_DOUBLE_128__) +# if FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +#else +# undef FFI_TYPE_LONGDOUBLE +# define FFI_TYPE_LONGDOUBLE 4 +#endif + +extern void ffi_call_osf(void *stack, void *frame, unsigned flags, + void *raddr, void (*fn)(void), void *closure) + FFI_HIDDEN; +extern void ffi_closure_osf(void) FFI_HIDDEN; +extern void ffi_go_closure_osf(void) FFI_HIDDEN; + +/* Promote a float value to its in-register double representation. + Unlike actually casting to double, this does not trap on NaN. */ +static inline UINT64 lds(void *ptr) +{ + UINT64 ret; + asm("lds %0,%1" : "=f"(ret) : "m"(*(UINT32 *)ptr)); + return ret; +} + +/* And the reverse. */ +static inline void sts(void *ptr, UINT64 val) +{ + asm("sts %1,%0" : "=m"(*(UINT32 *)ptr) : "f"(val)); +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep(ffi_cif *cif) +{ + size_t bytes = 0; + int flags, i, avn; + ffi_type *rtype, *itype; + + if (cif->abi != FFI_OSF) + return FFI_BAD_ABI; + + /* Compute the size of the argument area. */ + for (i = 0, avn = cif->nargs; i < avn; i++) + { + itype = cif->arg_types[i]; + switch (itype->type) + { + case FFI_TYPE_INT: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + /* All take one 8 byte slot. */ + bytes += 8; + break; + + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + /* Passed by value in N slots. */ + bytes += ALIGN(itype->size, FFI_SIZEOF_ARG); + break; + + case FFI_TYPE_COMPLEX: + /* _Complex long double passed by reference; others in 2 slots. */ + if (itype->elements[0]->type == FFI_TYPE_LONGDOUBLE) + bytes += 8; + else + bytes += 16; + break; + + default: + abort(); + } + } + + /* Set the return type flag */ + rtype = cif->rtype; + switch (rtype->type) + { + case FFI_TYPE_VOID: + flags = ALPHA_FLAGS(ALPHA_ST_VOID, ALPHA_LD_VOID); + break; + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT32); + break; + case FFI_TYPE_FLOAT: + flags = ALPHA_FLAGS(ALPHA_ST_FLOAT, ALPHA_LD_FLOAT); + break; + case FFI_TYPE_DOUBLE: + flags = ALPHA_FLAGS(ALPHA_ST_DOUBLE, ALPHA_LD_DOUBLE); + break; + case FFI_TYPE_UINT8: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT8); + break; + case FFI_TYPE_SINT8: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT8); + break; + case FFI_TYPE_UINT16: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT16); + break; + case FFI_TYPE_SINT16: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT16); + break; + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64); + break; + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_STRUCT: + /* Passed in memory, with a hidden pointer. */ + flags = ALPHA_RET_IN_MEM; + break; + case FFI_TYPE_COMPLEX: + itype = rtype->elements[0]; + switch (itype->type) + { + case FFI_TYPE_FLOAT: + flags = ALPHA_FLAGS(ALPHA_ST_CPLXF, ALPHA_LD_CPLXF); + break; + case FFI_TYPE_DOUBLE: + flags = ALPHA_FLAGS(ALPHA_ST_CPLXD, ALPHA_LD_CPLXD); + break; + default: + if (rtype->size <= 8) + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64); + else + flags = ALPHA_RET_IN_MEM; + break; + } + break; + default: + abort(); + } + cif->flags = flags; + + /* Include the hidden structure pointer in args requirement. */ + if (flags == ALPHA_RET_IN_MEM) + bytes += 8; + /* Minimum size is 6 slots, so that ffi_call_osf can pop them. */ + if (bytes < 6*8) + bytes = 6*8; + cif->bytes = bytes; + + return FFI_OK; +} + +static unsigned long +extend_basic_type(void *valp, int type, int argn) +{ + switch (type) + { + case FFI_TYPE_SINT8: + return *(SINT8 *)valp; + case FFI_TYPE_UINT8: + return *(UINT8 *)valp; + case FFI_TYPE_SINT16: + return *(SINT16 *)valp; + case FFI_TYPE_UINT16: + return *(UINT16 *)valp; + + case FFI_TYPE_FLOAT: + if (argn < 6) + return lds(valp); + /* FALLTHRU */ + + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + /* Note that unsigned 32-bit quantities are sign extended. */ + return *(SINT32 *)valp; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + case FFI_TYPE_DOUBLE: + return *(UINT64 *)valp; + + default: + abort(); + } +} + +static void +ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + unsigned long *argp; + long i, avn, argn, flags = cif->flags; + ffi_type **arg_types; + void *frame; + + /* If the return value is a struct and we don't have a return + value address then we need to make one. */ + if (rvalue == NULL && flags == ALPHA_RET_IN_MEM) + rvalue = alloca(cif->rtype->size); + + /* Allocate the space for the arguments, plus 4 words of temp + space for ffi_call_osf. */ + argp = frame = alloca(cif->bytes + 4*FFI_SIZEOF_ARG); + frame += cif->bytes; + + argn = 0; + if (flags == ALPHA_RET_IN_MEM) + argp[argn++] = (unsigned long)rvalue; + + avn = cif->nargs; + arg_types = cif->arg_types; + + for (i = 0, avn = cif->nargs; i < avn; i++) + { + ffi_type *ty = arg_types[i]; + void *valp = avalue[i]; + int type = ty->type; + size_t size; + + switch (type) + { + case FFI_TYPE_INT: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + argp[argn] = extend_basic_type(valp, type, argn); + argn++; + break; + + case FFI_TYPE_LONGDOUBLE: + by_reference: + /* Note that 128-bit long double is passed by reference. */ + argp[argn++] = (unsigned long)valp; + break; + + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + size = ty->size; + memcpy(argp + argn, valp, size); + argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + break; + + case FFI_TYPE_COMPLEX: + type = ty->elements[0]->type; + if (type == FFI_TYPE_LONGDOUBLE) + goto by_reference; + + /* Most complex types passed as two separate arguments. */ + size = ty->elements[0]->size; + argp[argn] = extend_basic_type(valp, type, argn); + argp[argn + 1] = extend_basic_type(valp + size, type, argn + 1); + argn += 2; + break; + + default: + abort(); + } + } + + flags = (flags >> ALPHA_ST_SHIFT) & 0xff; + ffi_call_osf(argp, frame, flags, rvalue, fn, closure); +} + +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_call_int(cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int(cif, fn, rvalue, avalue, closure); +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp; + + if (cif->abi != FFI_OSF) + return FFI_BAD_ABI; + + tramp = (unsigned int *) &closure->tramp[0]; + tramp[0] = 0x47fb0401; /* mov $27,$1 */ + tramp[1] = 0xa77b0010; /* ldq $27,16($27) */ + tramp[2] = 0x6bfb0000; /* jmp $31,($27),0 */ + tramp[3] = 0x47ff041f; /* nop */ + *(void **) &tramp[4] = ffi_closure_osf; + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + /* Flush the Icache. + + Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal + instead, since both Compaq as and gas can handle it. + + 0x86 is PAL_imb in Tru64 UNIX . */ + asm volatile ("call_pal 0x86" : : : "memory"); + + return FFI_OK; +} + +ffi_status +ffi_prep_go_closure (ffi_go_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*)) +{ + if (cif->abi != FFI_OSF) + return FFI_BAD_ABI; + + closure->tramp = (void *)ffi_go_closure_osf; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} + +long FFI_HIDDEN +ffi_closure_osf_inner (ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *rvalue, unsigned long *argp) +{ + void **avalue; + ffi_type **arg_types; + long i, avn, argn, flags; + + avalue = alloca(cif->nargs * sizeof(void *)); + flags = cif->flags; + argn = 0; + + /* Copy the caller's structure return address to that the closure + returns the data directly to the caller. */ + if (flags == ALPHA_RET_IN_MEM) + { + rvalue = (void *) argp[0]; + argn = 1; + } + + arg_types = cif->arg_types; + + /* Grab the addresses of the arguments from the stack frame. */ + for (i = 0, avn = cif->nargs; i < avn; i++) + { + ffi_type *ty = arg_types[i]; + int type = ty->type; + void *valp = &argp[argn]; + size_t size; + + switch (type) + { + case FFI_TYPE_INT: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + argn += 1; + break; + + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + size = ty->size; + argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + break; + + case FFI_TYPE_FLOAT: + /* Floats coming from registers need conversion from double + back to float format. */ + if (argn < 6) + { + valp = &argp[argn - 6]; + sts(valp, argp[argn - 6]); + } + argn += 1; + break; + + case FFI_TYPE_DOUBLE: + if (argn < 6) + valp = &argp[argn - 6]; + argn += 1; + break; + + case FFI_TYPE_LONGDOUBLE: + by_reference: + /* 128-bit long double is passed by reference. */ + valp = (void *)argp[argn]; + argn += 1; + break; + + case FFI_TYPE_COMPLEX: + type = ty->elements[0]->type; + switch (type) + { + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + /* Passed as separate arguments, but they wind up sequential. */ + break; + + case FFI_TYPE_INT: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + /* Passed as separate arguments. Disjoint, but there's room + enough in one slot to hold the pair. */ + size = ty->elements[0]->size; + memcpy(valp + size, valp + 8, size); + break; + + case FFI_TYPE_FLOAT: + /* Passed as separate arguments. Disjoint, and each piece + may need conversion back to float. */ + if (argn < 6) + { + valp = &argp[argn - 6]; + sts(valp, argp[argn - 6]); + } + if (argn + 1 < 6) + sts(valp + 4, argp[argn + 1 - 6]); + else + *(UINT32 *)(valp + 4) = argp[argn + 1]; + break; + + case FFI_TYPE_DOUBLE: + /* Passed as separate arguments. Only disjoint if one part + is in fp regs and the other is on the stack. */ + if (argn < 5) + valp = &argp[argn - 6]; + else if (argn == 5) + { + valp = alloca(16); + ((UINT64 *)valp)[0] = argp[5 - 6]; + ((UINT64 *)valp)[1] = argp[6]; + } + break; + + case FFI_TYPE_LONGDOUBLE: + goto by_reference; + + default: + abort(); + } + argn += 2; + break; + + default: + abort (); + } + + avalue[i] = valp; + } + + /* Invoke the closure. */ + fun (cif, rvalue, avalue, user_data); + + /* Tell ffi_closure_osf how to perform return type promotions. */ + return (flags >> ALPHA_LD_SHIFT) & 0xff; +} diff --git a/circuitpython/lib/libffi/src/alpha/ffitarget.h b/circuitpython/lib/libffi/src/alpha/ffitarget.h new file mode 100644 index 0000000..a02dbd0 --- /dev/null +++ b/circuitpython/lib/libffi/src/alpha/ffitarget.h @@ -0,0 +1,57 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for Alpha. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_OSF, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_OSF +} ffi_abi; +#endif + +#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION +#define FFI_TARGET_HAS_COMPLEX_TYPE + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_GO_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 24 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/alpha/internal.h b/circuitpython/lib/libffi/src/alpha/internal.h new file mode 100644 index 0000000..44da192 --- /dev/null +++ b/circuitpython/lib/libffi/src/alpha/internal.h @@ -0,0 +1,23 @@ +#define ALPHA_ST_VOID 0 +#define ALPHA_ST_INT 1 +#define ALPHA_ST_FLOAT 2 +#define ALPHA_ST_DOUBLE 3 +#define ALPHA_ST_CPLXF 4 +#define ALPHA_ST_CPLXD 5 + +#define ALPHA_LD_VOID 0 +#define ALPHA_LD_INT64 1 +#define ALPHA_LD_INT32 2 +#define ALPHA_LD_UINT16 3 +#define ALPHA_LD_SINT16 4 +#define ALPHA_LD_UINT8 5 +#define ALPHA_LD_SINT8 6 +#define ALPHA_LD_FLOAT 7 +#define ALPHA_LD_DOUBLE 8 +#define ALPHA_LD_CPLXF 9 +#define ALPHA_LD_CPLXD 10 + +#define ALPHA_ST_SHIFT 0 +#define ALPHA_LD_SHIFT 8 +#define ALPHA_RET_IN_MEM 0x10000 +#define ALPHA_FLAGS(S, L) (((L) << ALPHA_LD_SHIFT) | (S)) diff --git a/circuitpython/lib/libffi/src/alpha/osf.S b/circuitpython/lib/libffi/src/alpha/osf.S new file mode 100644 index 0000000..b031828 --- /dev/null +++ b/circuitpython/lib/libffi/src/alpha/osf.S @@ -0,0 +1,282 @@ +/* ----------------------------------------------------------------------- + osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat + + Alpha/OSF Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include +#include +#include "internal.h" + + .arch ev6 + .text + +/* Aid in building a direct addressed jump table, 4 insns per entry. */ +.macro E index + .align 4 + .org 99b + \index * 16 +.endm + +/* ffi_call_osf (void *stack, void *frame, unsigned flags, + void *raddr, void (*fnaddr)(void), void *closure) + + Bit o trickiness here -- FRAME is the base of the stack frame + for this function. This has been allocated by ffi_call. We also + deallocate some of the stack that has been alloca'd. */ + + .align 4 + .globl ffi_call_osf + .ent ffi_call_osf + FFI_HIDDEN(ffi_call_osf) + +ffi_call_osf: + cfi_startproc + cfi_def_cfa($17, 32) + mov $16, $30 + stq $26, 0($17) + stq $15, 8($17) + mov $17, $15 + .prologue 0 + cfi_def_cfa_register($15) + cfi_rel_offset($26, 0) + cfi_rel_offset($15, 8) + + stq $18, 16($17) # save flags into frame + stq $19, 24($17) # save rvalue into frame + mov $20, $27 # fn into place for call + mov $21, $1 # closure into static chain + + # Load up all of the (potential) argument registers. + ldq $16, 0($30) + ldt $f16, 0($30) + ldt $f17, 8($30) + ldq $17, 8($30) + ldt $f18, 16($30) + ldq $18, 16($30) + ldt $f19, 24($30) + ldq $19, 24($30) + ldt $f20, 32($30) + ldq $20, 32($30) + ldt $f21, 40($30) + ldq $21, 40($30) + + # Deallocate the register argument area. + lda $30, 48($30) + + jsr $26, ($27), 0 +0: + ldah $29, 0($26) !gpdisp!1 + ldq $2, 24($15) # reload rvalue + lda $29, 0($29) !gpdisp!1 + ldq $3, 16($15) # reload flags + lda $1, 99f-0b($26) + ldq $26, 0($15) + ldq $15, 8($15) + cfi_restore($26) + cfi_restore($15) + cfi_def_cfa($sp, 0) + cmoveq $2, ALPHA_ST_VOID, $3 # mash null rvalue to void + addq $3, $3, $3 + s8addq $3, $1, $1 # 99f + stcode * 16 + jmp $31, ($1), $st_int + + .align 4 +99: +E ALPHA_ST_VOID + ret +E ALPHA_ST_INT +$st_int: + stq $0, 0($2) + ret +E ALPHA_ST_FLOAT + sts $f0, 0($2) + ret +E ALPHA_ST_DOUBLE + stt $f0, 0($2) + ret +E ALPHA_ST_CPLXF + sts $f0, 0($2) + sts $f1, 4($2) + ret +E ALPHA_ST_CPLXD + stt $f0, 0($2) + stt $f1, 8($2) + ret + + cfi_endproc + .end ffi_call_osf + +/* ffi_closure_osf(...) + + Receives the closure argument in $1. */ + +#define CLOSURE_FS (16*8) + + .align 4 + .globl ffi_go_closure_osf + .ent ffi_go_closure_osf + FFI_HIDDEN(ffi_go_closure_osf) + +ffi_go_closure_osf: + cfi_startproc + ldgp $29, 0($27) + subq $30, CLOSURE_FS, $30 + cfi_adjust_cfa_offset(CLOSURE_FS) + stq $26, 0($30) + .prologue 1 + cfi_rel_offset($26, 0) + + stq $16, 10*8($30) + stq $17, 11*8($30) + stq $18, 12*8($30) + + ldq $16, 8($1) # load cif + ldq $17, 16($1) # load fun + mov $1, $18 # closure is user_data + br $do_closure + + cfi_endproc + .end ffi_go_closure_osf + + .align 4 + .globl ffi_closure_osf + .ent ffi_closure_osf + FFI_HIDDEN(ffi_closure_osf) + +ffi_closure_osf: + cfi_startproc + ldgp $29, 0($27) + subq $30, CLOSURE_FS, $30 + cfi_adjust_cfa_offset(CLOSURE_FS) + stq $26, 0($30) + .prologue 1 + cfi_rel_offset($26, 0) + + # Store all of the potential argument registers in va_list format. + stq $16, 10*8($30) + stq $17, 11*8($30) + stq $18, 12*8($30) + + ldq $16, 24($1) # load cif + ldq $17, 32($1) # load fun + ldq $18, 40($1) # load user_data + +$do_closure: + stq $19, 13*8($30) + stq $20, 14*8($30) + stq $21, 15*8($30) + stt $f16, 4*8($30) + stt $f17, 5*8($30) + stt $f18, 6*8($30) + stt $f19, 7*8($30) + stt $f20, 8*8($30) + stt $f21, 9*8($30) + + # Call ffi_closure_osf_inner to do the bulk of the work. + lda $19, 2*8($30) + lda $20, 10*8($30) + jsr $26, ffi_closure_osf_inner +0: + ldah $29, 0($26) !gpdisp!2 + lda $2, 99f-0b($26) + s4addq $0, 0, $1 # ldcode * 4 + ldq $0, 16($30) # preload return value + s4addq $1, $2, $1 # 99f + ldcode * 16 + lda $29, 0($29) !gpdisp!2 + ldq $26, 0($30) + cfi_restore($26) + jmp $31, ($1), $load_32 + +.macro epilogue + addq $30, CLOSURE_FS, $30 + cfi_adjust_cfa_offset(-CLOSURE_FS) + ret + .align 4 + cfi_adjust_cfa_offset(CLOSURE_FS) +.endm + + .align 4 +99: +E ALPHA_LD_VOID + epilogue + +E ALPHA_LD_INT64 + epilogue + +E ALPHA_LD_INT32 +$load_32: + sextl $0, $0 + epilogue + +E ALPHA_LD_UINT16 + zapnot $0, 3, $0 + epilogue + +E ALPHA_LD_SINT16 +#ifdef __alpha_bwx__ + sextw $0, $0 +#else + sll $0, 48, $0 + sra $0, 48, $0 +#endif + epilogue + +E ALPHA_LD_UINT8 + and $0, 0xff, $0 + epilogue + +E ALPHA_LD_SINT8 +#ifdef __alpha_bwx__ + sextb $0, $0 +#else + sll $0, 56, $0 + sra $0, 56, $0 +#endif + epilogue + +E ALPHA_LD_FLOAT + lds $f0, 16($sp) + epilogue + +E ALPHA_LD_DOUBLE + ldt $f0, 16($sp) + epilogue + +E ALPHA_LD_CPLXF + lds $f0, 16($sp) + lds $f1, 20($sp) + epilogue + +E ALPHA_LD_CPLXD + ldt $f0, 16($sp) + ldt $f1, 24($sp) + epilogue + + cfi_endproc + .end ffi_closure_osf + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/arc/arcompact.S b/circuitpython/lib/libffi/src/arc/arcompact.S new file mode 100644 index 0000000..03715fd --- /dev/null +++ b/circuitpython/lib/libffi/src/arc/arcompact.S @@ -0,0 +1,135 @@ +/* ----------------------------------------------------------------------- + arcompact.S - Copyright (c) 2013 Synposys, Inc. (www.synopsys.com) + + ARCompact Foreign Function Interface + + 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 RENESAS TECHNOLOGY 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 LIBFFI_ASM +#include +#include +#ifdef HAVE_MACHINE_ASM_H +#include +#else +#define CNAME(x) x +#define ENTRY(x) .globl CNAME(x)` .type CNAME(x),%function` CNAME(x): +#endif + +.text + + /* R0: ffi_prep_args */ + /* R1: &ecif */ + /* R2: cif->bytes */ + /* R3: fig->flags */ + /* R4: ecif.rvalue */ + /* R5: fn */ +ENTRY(ffi_call_ARCompact) + /* Save registers. */ + st.a fp, [sp, -4] /* fp + 20, fp */ + push_s blink /* fp + 16, blink */ + st.a r4, [sp, -4] /* fp + 12, ecif.rvalue */ + push_s r3 /* fp + 8, fig->flags */ + st.a r5, [sp, -4] /* fp + 4, fn */ + push_s r2 /* fp + 0, cif->bytes */ + mov fp, sp + + /* Make room for all of the new args. */ + sub sp, sp, r2 + + /* Place all of the ffi_prep_args in position. */ + /* ffi_prep_args(char *stack, extended_cif *ecif) */ + /* R1 already set. */ + + /* And call. */ + jl_s.d [r0] + mov_s r0, sp + + ld.ab r12, [fp, 4] /* cif->bytes */ + ld.ab r11, [fp, 4] /* fn */ + + /* Move first 8 parameters in registers... */ + ld_s r0, [sp] + ld_s r1, [sp, 4] + ld_s r2, [sp, 8] + ld_s r3, [sp, 12] + ld r4, [sp, 16] + ld r5, [sp, 20] + ld r6, [sp, 24] + ld r7, [sp, 28] + + /* ...and adjust the stack. */ + min r12, r12, 32 + + /* Call the function. */ + jl.d [r11] + add sp, sp, r12 + + mov sp, fp + pop_s r3 /* fig->flags, return type */ + pop_s r2 /* ecif.rvalue, pointer for return value */ + + /* If the return value pointer is NULL, assume no return value. */ + breq.d r2, 0, epilogue + pop_s blink + + /* Return INT. */ + brne r3, FFI_TYPE_INT, return_double + b.d epilogue + st_s r0, [r2] + +return_double: + brne r3, FFI_TYPE_DOUBLE, epilogue + st_s r0, [r2] + st_s r1, [r2,4] + +epilogue: + j_s.d [blink] + ld.ab fp, [sp, 4] + +ENTRY(ffi_closure_ARCompact) + st.a r0, [sp, -32] + st_s r1, [sp, 4] + st_s r2, [sp, 8] + st_s r3, [sp, 12] + st r4, [sp, 16] + st r5, [sp, 20] + st r6, [sp, 24] + st r7, [sp, 28] + + /* pointer to arguments */ + mov_s r2, sp + + /* return value goes here */ + sub sp, sp, 8 + mov_s r1, sp + + push_s blink + + bl.d ffi_closure_inner_ARCompact + mov_s r0, r8 /* codeloc, set by trampoline */ + + pop_s blink + + /* set return value to r1:r0 */ + pop_s r0 + pop_s r1 + j_s.d [blink] + add_s sp, sp, 32 diff --git a/circuitpython/lib/libffi/src/arc/ffi.c b/circuitpython/lib/libffi/src/arc/ffi.c new file mode 100644 index 0000000..32f82a7 --- /dev/null +++ b/circuitpython/lib/libffi/src/arc/ffi.c @@ -0,0 +1,268 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com) + + ARC Foreign Function Interface + + 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 RENESAS TECHNOLOGY 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 +#include + +#include +#include + +#include + +/* for little endian ARC, the code is in fact stored as mixed endian for + performance reasons */ +#if __BIG_ENDIAN__ +#define CODE_ENDIAN(x) (x) +#else +#define CODE_ENDIAN(x) ( (((uint32_t) (x)) << 16) | (((uint32_t) (x)) >> 16)) +#endif + +/* ffi_prep_args is called by the assembly routine once stack + space has been allocated for the function's arguments. */ + +void +ffi_prep_args (char *stack, extended_cif * ecif) +{ + unsigned int i; + int tmp; + void **p_argv; + char *argp; + ffi_type **p_arg; + + tmp = 0; + argp = stack; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += 4; + } + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); i--, p_arg++) + { + size_t z; + int alignment; + + /* align alignment to 4 */ + alignment = (((*p_arg)->alignment - 1) | 3) + 1; + + /* Align if necessary. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + z = (*p_arg)->size; + if (z < sizeof (int)) + { + z = sizeof (int); + + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) (*p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) (*p_argv); + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, (*p_arg)->size); + break; + + default: + FFI_ASSERT (0); + } + } + else if (z == sizeof (int)) + { + *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv); + } + else + { + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + memcpy (argp, *p_argv, z); + } + else + { + /* Double or long long 64bit. */ + memcpy (argp, *p_argv, z); + } + } + p_argv++; + argp += z; + } + + return; +} + +/* Perform machine dependent cif processing. */ +ffi_status +ffi_prep_cif_machdep (ffi_cif * cif) +{ + /* Set the return type flag. */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_STRUCT: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + cif->flags = FFI_TYPE_DOUBLE; + break; + + case FFI_TYPE_FLOAT: + default: + cif->flags = FFI_TYPE_INT; + break; + } + + return FFI_OK; +} + +extern void ffi_call_ARCompact (void (*)(char *, extended_cif *), + extended_cif *, unsigned, unsigned, + unsigned *, void (*fn) (void)); + +void +ffi_call (ffi_cif * cif, void (*fn) (void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have + a return value address then we need to make one. */ + if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca (cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_ARCOMPACT: + ffi_call_ARCompact (ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +int +ffi_closure_inner_ARCompact (ffi_closure * closure, void *rvalue, + ffi_arg * args) +{ + void **arg_area, **p_argv; + ffi_cif *cif = closure->cif; + char *argp = (char *) args; + ffi_type **p_argt; + int i; + + arg_area = (void **) alloca (cif->nargs * sizeof (void *)); + + /* handle hidden argument */ + if (cif->flags == FFI_TYPE_STRUCT) + { + rvalue = *(void **) argp; + argp += 4; + } + + p_argv = arg_area; + + for (i = 0, p_argt = cif->arg_types; i < cif->nargs; + i++, p_argt++, p_argv++) + { + size_t z; + int alignment; + + /* align alignment to 4 */ + alignment = (((*p_argt)->alignment - 1) | 3) + 1; + + /* Align if necessary. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + z = (*p_argt)->size; + *p_argv = (void *) argp; + argp += z; + } + + (closure->fun) (cif, rvalue, arg_area, closure->user_data); + + return cif->flags; +} + +extern void ffi_closure_ARCompact (void); + +ffi_status +ffi_prep_closure_loc (ffi_closure * closure, ffi_cif * cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + uint32_t *tramp = (uint32_t *) & (closure->tramp[0]); + + switch (cif->abi) + { + case FFI_ARCOMPACT: + FFI_ASSERT (tramp == codeloc); + tramp[0] = CODE_ENDIAN (0x200a1fc0); /* mov r8, pcl */ + tramp[1] = CODE_ENDIAN (0x20200f80); /* j [long imm] */ + tramp[2] = CODE_ENDIAN (ffi_closure_ARCompact); + break; + + default: + return FFI_BAD_ABI; + } + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + cacheflush (codeloc, FFI_TRAMPOLINE_SIZE, BCACHE); + + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/arc/ffitarget.h b/circuitpython/lib/libffi/src/arc/ffitarget.h new file mode 100644 index 0000000..bf8311b --- /dev/null +++ b/circuitpython/lib/libffi/src/arc/ffitarget.h @@ -0,0 +1,53 @@ +/* ----------------------------------------------------------------------- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com) + Target configuration macros for ARC. + + 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 RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi +{ + FFI_FIRST_ABI = 0, + FFI_ARCOMPACT, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_ARCOMPACT +} ffi_abi; +#endif + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 12 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/arm/ffi.c b/circuitpython/lib/libffi/src/arm/ffi.c new file mode 100644 index 0000000..9c8732d --- /dev/null +++ b/circuitpython/lib/libffi/src/arm/ffi.c @@ -0,0 +1,1043 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2011 Timothy Wall + Copyright (c) 2011 Plausible Labs Cooperative, Inc. + Copyright (c) 2011 Anthony Green + Copyright (c) 2011 Free Software Foundation + Copyright (c) 1998, 2008, 2011 Red Hat, Inc. + + ARM Foreign Function Interface + + 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 +#include +#include +#include "internal.h" + +/* Forward declares. */ +static int vfp_type_p (const ffi_type *); +static void layout_vfp_args (ffi_cif *); + +static void * +ffi_align (ffi_type *ty, void *p) +{ + /* Align if necessary */ + size_t alignment; +#ifdef _WIN32_WCE + alignment = 4; +#else + alignment = ty->alignment; + if (alignment < 4) + alignment = 4; +#endif + return (void *) ALIGN (p, alignment); +} + +static size_t +ffi_put_arg (ffi_type *ty, void *src, void *dst) +{ + size_t z = ty->size; + + switch (ty->type) + { + case FFI_TYPE_SINT8: + *(UINT32 *)dst = *(SINT8 *)src; + break; + case FFI_TYPE_UINT8: + *(UINT32 *)dst = *(UINT8 *)src; + break; + case FFI_TYPE_SINT16: + *(UINT32 *)dst = *(SINT16 *)src; + break; + case FFI_TYPE_UINT16: + *(UINT32 *)dst = *(UINT16 *)src; + break; + + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + case FFI_TYPE_FLOAT: + *(UINT32 *)dst = *(UINT32 *)src; + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + *(UINT64 *)dst = *(UINT64 *)src; + break; + + case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: + memcpy (dst, src, z); + break; + + default: + abort(); + } + + return ALIGN (z, 4); +} + +/* ffi_prep_args is called once stack space has been allocated + for the function's arguments. + + The vfp_space parameter is the load area for VFP regs, the return + value is cif->vfp_used (word bitset of VFP regs used for passing + arguments). These are only used for the VFP hard-float ABI. +*/ +static void +ffi_prep_args_SYSV (ffi_cif *cif, int flags, void *rvalue, + void **avalue, char *argp) +{ + ffi_type **arg_types = cif->arg_types; + int i, n; + + if (flags == ARM_TYPE_STRUCT) + { + *(void **) argp = rvalue; + argp += 4; + } + + for (i = 0, n = cif->nargs; i < n; i++) + { + ffi_type *ty = arg_types[i]; + argp = ffi_align (ty, argp); + argp += ffi_put_arg (ty, avalue[i], argp); + } +} + +static void +ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue, + void **avalue, char *stack, char *vfp_space) +{ + ffi_type **arg_types = cif->arg_types; + int i, n, vi = 0; + char *argp, *regp, *eo_regp; + char stack_used = 0; + char done_with_regs = 0; + + /* The first 4 words on the stack are used for values + passed in core registers. */ + regp = stack; + eo_regp = argp = regp + 16; + + /* If the function returns an FFI_TYPE_STRUCT in memory, + that address is passed in r0 to the function. */ + if (flags == ARM_TYPE_STRUCT) + { + *(void **) regp = rvalue; + regp += 4; + } + + for (i = 0, n = cif->nargs; i < n; i++) + { + ffi_type *ty = arg_types[i]; + void *a = avalue[i]; + int is_vfp_type = vfp_type_p (ty); + + /* Allocated in VFP registers. */ + if (vi < cif->vfp_nargs && is_vfp_type) + { + char *vfp_slot = vfp_space + cif->vfp_args[vi++] * 4; + ffi_put_arg (ty, a, vfp_slot); + continue; + } + /* Try allocating in core registers. */ + else if (!done_with_regs && !is_vfp_type) + { + char *tregp = ffi_align (ty, regp); + size_t size = ty->size; + size = (size < 4) ? 4 : size; // pad + /* Check if there is space left in the aligned register + area to place the argument. */ + if (tregp + size <= eo_regp) + { + regp = tregp + ffi_put_arg (ty, a, tregp); + done_with_regs = (regp == argp); + // ensure we did not write into the stack area + FFI_ASSERT (regp <= argp); + continue; + } + /* In case there are no arguments in the stack area yet, + the argument is passed in the remaining core registers + and on the stack. */ + else if (!stack_used) + { + stack_used = 1; + done_with_regs = 1; + argp = tregp + ffi_put_arg (ty, a, tregp); + FFI_ASSERT (eo_regp < argp); + continue; + } + } + /* Base case, arguments are passed on the stack */ + stack_used = 1; + argp = ffi_align (ty, argp); + argp += ffi_put_arg (ty, a, argp); + } +} + +/* Perform machine dependent cif processing */ +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + int flags = 0, cabi = cif->abi; + size_t bytes = cif->bytes; + + /* Map out the register placements of VFP register args. The VFP + hard-float calling conventions are slightly more sophisticated + than the base calling conventions, so we do it here instead of + in ffi_prep_args(). */ + if (cabi == FFI_VFP) + layout_vfp_args (cif); + + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + flags = ARM_TYPE_VOID; + break; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + flags = ARM_TYPE_INT; + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + flags = ARM_TYPE_INT64; + break; + + case FFI_TYPE_FLOAT: + flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_S : ARM_TYPE_INT); + break; + case FFI_TYPE_DOUBLE: + flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_D : ARM_TYPE_INT64); + break; + + case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: + if (cabi == FFI_VFP) + { + int h = vfp_type_p (cif->rtype); + + flags = ARM_TYPE_VFP_N; + if (h == 0x100 + FFI_TYPE_FLOAT) + flags = ARM_TYPE_VFP_S; + if (h == 0x100 + FFI_TYPE_DOUBLE) + flags = ARM_TYPE_VFP_D; + if (h != 0) + break; + } + + /* A Composite Type not larger than 4 bytes is returned in r0. + A Composite Type larger than 4 bytes, or whose size cannot + be determined statically ... is stored in memory at an + address passed [in r0]. */ + if (cif->rtype->size <= 4) + flags = ARM_TYPE_INT; + else + { + flags = ARM_TYPE_STRUCT; + bytes += 4; + } + break; + + default: + abort(); + } + + /* Round the stack up to a multiple of 8 bytes. This isn't needed + everywhere, but it is on some platforms, and it doesn't harm anything + when it isn't needed. */ + bytes = ALIGN (bytes, 8); + + /* Minimum stack space is the 4 register arguments that we pop. */ + if (bytes < 4*4) + bytes = 4*4; + + cif->bytes = bytes; + cif->flags = flags; + + return FFI_OK; +} + +/* Perform machine dependent cif processing for variadic calls */ +ffi_status +ffi_prep_cif_machdep_var (ffi_cif * cif, + unsigned int nfixedargs, unsigned int ntotalargs) +{ + /* VFP variadic calls actually use the SYSV ABI */ + if (cif->abi == FFI_VFP) + cif->abi = FFI_SYSV; + + return ffi_prep_cif_machdep (cif); +} + +/* Prototypes for assembly functions, in sysv.S. */ + +struct call_frame +{ + void *fp; + void *lr; + void *rvalue; + int flags; + void *closure; +}; + +extern void ffi_call_SYSV (void *stack, struct call_frame *, + void (*fn) (void)) FFI_HIDDEN; +extern void ffi_call_VFP (void *vfp_space, struct call_frame *, + void (*fn) (void), unsigned vfp_used) FFI_HIDDEN; + +static void +ffi_call_int (ffi_cif * cif, void (*fn) (void), void *rvalue, + void **avalue, void *closure) +{ + int flags = cif->flags; + ffi_type *rtype = cif->rtype; + size_t bytes, rsize, vfp_size; + char *stack, *vfp_space, *new_rvalue; + struct call_frame *frame; + + rsize = 0; + if (rvalue == NULL) + { + /* If the return value is a struct and we don't have a return + value address then we need to make one. Otherwise the return + value is in registers and we can ignore them. */ + if (flags == ARM_TYPE_STRUCT) + rsize = rtype->size; + else + flags = ARM_TYPE_VOID; + } + else if (flags == ARM_TYPE_VFP_N) + { + /* Largest case is double x 4. */ + rsize = 32; + } + else if (flags == ARM_TYPE_INT && rtype->type == FFI_TYPE_STRUCT) + rsize = 4; + + /* Largest case. */ + vfp_size = (cif->abi == FFI_VFP && cif->vfp_used ? 8*8: 0); + + bytes = cif->bytes; + stack = alloca (vfp_size + bytes + sizeof(struct call_frame) + rsize); + + vfp_space = NULL; + if (vfp_size) + { + vfp_space = stack; + stack += vfp_size; + } + + frame = (struct call_frame *)(stack + bytes); + + new_rvalue = rvalue; + if (rsize) + new_rvalue = (void *)(frame + 1); + + frame->rvalue = new_rvalue; + frame->flags = flags; + frame->closure = closure; + + if (vfp_space) + { + ffi_prep_args_VFP (cif, flags, new_rvalue, avalue, stack, vfp_space); + ffi_call_VFP (vfp_space, frame, fn, cif->vfp_used); + } + else + { + ffi_prep_args_SYSV (cif, flags, new_rvalue, avalue, stack); + ffi_call_SYSV (stack, frame, fn); + } + + if (rvalue && rvalue != new_rvalue) + memcpy (rvalue, new_rvalue, rtype->size); +} + +void +ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} + +static void * +ffi_prep_incoming_args_SYSV (ffi_cif *cif, void *rvalue, + char *argp, void **avalue) +{ + ffi_type **arg_types = cif->arg_types; + int i, n; + + if (cif->flags == ARM_TYPE_STRUCT) + { + rvalue = *(void **) argp; + argp += 4; + } + + for (i = 0, n = cif->nargs; i < n; i++) + { + ffi_type *ty = arg_types[i]; + size_t z = ty->size; + + argp = ffi_align (ty, argp); + avalue[i] = (void *) argp; + argp += z; + } + + return rvalue; +} + +static void * +ffi_prep_incoming_args_VFP (ffi_cif *cif, void *rvalue, char *stack, + char *vfp_space, void **avalue) +{ + ffi_type **arg_types = cif->arg_types; + int i, n, vi = 0; + char *argp, *regp, *eo_regp; + char done_with_regs = 0; + char stack_used = 0; + + regp = stack; + eo_regp = argp = regp + 16; + + if (cif->flags == ARM_TYPE_STRUCT) + { + rvalue = *(void **) regp; + regp += 4; + } + + for (i = 0, n = cif->nargs; i < n; i++) + { + ffi_type *ty = arg_types[i]; + int is_vfp_type = vfp_type_p (ty); + size_t z = ty->size; + + if (vi < cif->vfp_nargs && is_vfp_type) + { + avalue[i] = vfp_space + cif->vfp_args[vi++] * 4; + continue; + } + else if (!done_with_regs && !is_vfp_type) + { + char *tregp = ffi_align (ty, regp); + + z = (z < 4) ? 4 : z; // pad + + /* If the arguments either fits into the registers or uses registers + and stack, while we haven't read other things from the stack */ + if (tregp + z <= eo_regp || !stack_used) + { + /* Because we're little endian, this is what it turns into. */ + avalue[i] = (void *) tregp; + regp = tregp + z; + + /* If we read past the last core register, make sure we + have not read from the stack before and continue + reading after regp. */ + if (regp > eo_regp) + { + FFI_ASSERT (!stack_used); + argp = regp; + } + if (regp >= eo_regp) + { + done_with_regs = 1; + stack_used = 1; + } + continue; + } + } + + stack_used = 1; + argp = ffi_align (ty, argp); + avalue[i] = (void *) argp; + argp += z; + } + + return rvalue; +} + +struct closure_frame +{ + char vfp_space[8*8] __attribute__((aligned(8))); + char result[8*4]; + char argp[]; +}; + +int FFI_HIDDEN +ffi_closure_inner_SYSV (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + struct closure_frame *frame) +{ + void **avalue = (void **) alloca (cif->nargs * sizeof (void *)); + void *rvalue = ffi_prep_incoming_args_SYSV (cif, frame->result, + frame->argp, avalue); + fun (cif, rvalue, avalue, user_data); + return cif->flags; +} + +int FFI_HIDDEN +ffi_closure_inner_VFP (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + struct closure_frame *frame) +{ + void **avalue = (void **) alloca (cif->nargs * sizeof (void *)); + void *rvalue = ffi_prep_incoming_args_VFP (cif, frame->result, frame->argp, + frame->vfp_space, avalue); + fun (cif, rvalue, avalue, user_data); + return cif->flags; +} + +void ffi_closure_SYSV (void) FFI_HIDDEN; +void ffi_closure_VFP (void) FFI_HIDDEN; +void ffi_go_closure_SYSV (void) FFI_HIDDEN; +void ffi_go_closure_VFP (void) FFI_HIDDEN; + +#if FFI_EXEC_TRAMPOLINE_TABLE + +#include +#include +#include +#include + +extern void *ffi_closure_trampoline_table_page; + +typedef struct ffi_trampoline_table ffi_trampoline_table; +typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry; + +struct ffi_trampoline_table +{ + /* contiguous writable and executable pages */ + vm_address_t config_page; + vm_address_t trampoline_page; + + /* free list tracking */ + uint16_t free_count; + ffi_trampoline_table_entry *free_list; + ffi_trampoline_table_entry *free_list_pool; + + ffi_trampoline_table *prev; + ffi_trampoline_table *next; +}; + +struct ffi_trampoline_table_entry +{ + void *(*trampoline) (); + ffi_trampoline_table_entry *next; +}; + +/* Override the standard architecture trampoline size */ +// XXX TODO - Fix +#undef FFI_TRAMPOLINE_SIZE +#define FFI_TRAMPOLINE_SIZE 12 + +/* The trampoline configuration is placed at 4080 bytes prior to the trampoline's entry point */ +#define FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc) ((void **) (((uint8_t *) codeloc) - 4080)); + +/* The first 16 bytes of the config page are unused, as they are unaddressable from the trampoline page. */ +#define FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET 16 + +/* Total number of trampolines that fit in one trampoline table */ +#define FFI_TRAMPOLINE_COUNT ((PAGE_SIZE - FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) / FFI_TRAMPOLINE_SIZE) + +static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER; +static ffi_trampoline_table *ffi_trampoline_tables = NULL; + +static ffi_trampoline_table * +ffi_trampoline_table_alloc () +{ + ffi_trampoline_table *table = NULL; + + /* Loop until we can allocate two contiguous pages */ + while (table == NULL) + { + vm_address_t config_page = 0x0; + kern_return_t kt; + + /* Try to allocate two pages */ + kt = + vm_allocate (mach_task_self (), &config_page, PAGE_SIZE * 2, + VM_FLAGS_ANYWHERE); + if (kt != KERN_SUCCESS) + { + fprintf (stderr, "vm_allocate() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + break; + } + + /* Now drop the second half of the allocation to make room for the trampoline table */ + vm_address_t trampoline_page = config_page + PAGE_SIZE; + kt = vm_deallocate (mach_task_self (), trampoline_page, PAGE_SIZE); + if (kt != KERN_SUCCESS) + { + fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + break; + } + + /* Remap the trampoline table to directly follow the config page */ + vm_prot_t cur_prot; + vm_prot_t max_prot; + + kt = + vm_remap (mach_task_self (), &trampoline_page, PAGE_SIZE, 0x0, FALSE, + mach_task_self (), + (vm_address_t) & ffi_closure_trampoline_table_page, FALSE, + &cur_prot, &max_prot, VM_INHERIT_SHARE); + + /* If we lost access to the destination trampoline page, drop our config allocation mapping and retry */ + if (kt != KERN_SUCCESS) + { + /* Log unexpected failures */ + if (kt != KERN_NO_SPACE) + { + fprintf (stderr, "vm_remap() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + } + + vm_deallocate (mach_task_self (), config_page, PAGE_SIZE); + continue; + } + + /* We have valid trampoline and config pages */ + table = calloc (1, sizeof (ffi_trampoline_table)); + table->free_count = FFI_TRAMPOLINE_COUNT; + table->config_page = config_page; + table->trampoline_page = trampoline_page; + + /* Create and initialize the free list */ + table->free_list_pool = + calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry)); + + uint16_t i; + for (i = 0; i < table->free_count; i++) + { + ffi_trampoline_table_entry *entry = &table->free_list_pool[i]; + entry->trampoline = + (void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE)); + + if (i < table->free_count - 1) + entry->next = &table->free_list_pool[i + 1]; + } + + table->free_list = table->free_list_pool; + } + + return table; +} + +void * +ffi_closure_alloc (size_t size, void **code) +{ + /* Create the closure */ + ffi_closure *closure = malloc (size); + if (closure == NULL) + return NULL; + + pthread_mutex_lock (&ffi_trampoline_lock); + + /* Check for an active trampoline table with available entries. */ + ffi_trampoline_table *table = ffi_trampoline_tables; + if (table == NULL || table->free_list == NULL) + { + table = ffi_trampoline_table_alloc (); + if (table == NULL) + { + free (closure); + return NULL; + } + + /* Insert the new table at the top of the list */ + table->next = ffi_trampoline_tables; + if (table->next != NULL) + table->next->prev = table; + + ffi_trampoline_tables = table; + } + + /* Claim the free entry */ + ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list; + ffi_trampoline_tables->free_list = entry->next; + ffi_trampoline_tables->free_count--; + entry->next = NULL; + + pthread_mutex_unlock (&ffi_trampoline_lock); + + /* Initialize the return values */ + *code = entry->trampoline; + closure->trampoline_table = table; + closure->trampoline_table_entry = entry; + + return closure; +} + +void +ffi_closure_free (void *ptr) +{ + ffi_closure *closure = ptr; + + pthread_mutex_lock (&ffi_trampoline_lock); + + /* Fetch the table and entry references */ + ffi_trampoline_table *table = closure->trampoline_table; + ffi_trampoline_table_entry *entry = closure->trampoline_table_entry; + + /* Return the entry to the free list */ + entry->next = table->free_list; + table->free_list = entry; + table->free_count++; + + /* If all trampolines within this table are free, and at least one other table exists, deallocate + * the table */ + if (table->free_count == FFI_TRAMPOLINE_COUNT + && ffi_trampoline_tables != table) + { + /* Remove from the list */ + if (table->prev != NULL) + table->prev->next = table->next; + + if (table->next != NULL) + table->next->prev = table->prev; + + /* Deallocate pages */ + kern_return_t kt; + kt = vm_deallocate (mach_task_self (), table->config_page, PAGE_SIZE); + if (kt != KERN_SUCCESS) + fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + + kt = + vm_deallocate (mach_task_self (), table->trampoline_page, PAGE_SIZE); + if (kt != KERN_SUCCESS) + fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, + __FILE__, __LINE__); + + /* Deallocate free list */ + free (table->free_list_pool); + free (table); + } + else if (ffi_trampoline_tables != table) + { + /* Otherwise, bump this table to the top of the list */ + table->prev = NULL; + table->next = ffi_trampoline_tables; + if (ffi_trampoline_tables != NULL) + ffi_trampoline_tables->prev = table; + + ffi_trampoline_tables = table; + } + + pthread_mutex_unlock (&ffi_trampoline_lock); + + /* Free the closure */ + free (closure); +} + +#else + +extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN; + +#endif + +/* the cif must already be prep'ed */ + +ffi_status +ffi_prep_closure_loc (ffi_closure * closure, + ffi_cif * cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + void (*closure_func) (void) = ffi_closure_SYSV; + + if (cif->abi == FFI_VFP) + { + /* We only need take the vfp path if there are vfp arguments. */ + if (cif->vfp_used) + closure_func = ffi_closure_VFP; + } + else if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + +#if FFI_EXEC_TRAMPOLINE_TABLE + void **config = FFI_TRAMPOLINE_CODELOC_CONFIG (codeloc); + config[0] = closure; + config[1] = closure_func; +#else + memcpy (closure->tramp, ffi_arm_trampoline, 8); + __clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */ + __clear_cache(codeloc, codeloc + 8); /* clear insn map */ + *(void (**)(void))(closure->tramp + 8) = closure_func; +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +ffi_status +ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *)) +{ + void (*closure_func) (void) = ffi_go_closure_SYSV; + + if (cif->abi == FFI_VFP) + { + /* We only need take the vfp path if there are vfp arguments. */ + if (cif->vfp_used) + closure_func = ffi_go_closure_VFP; + } + else if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + closure->tramp = closure_func; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} + +/* Below are routines for VFP hard-float support. */ + +/* A subroutine of vfp_type_p. Given a structure type, return the type code + of the first non-structure element. Recurse for structure elements. + Return -1 if the structure is in fact empty, i.e. no nested elements. */ + +static int +is_hfa0 (const ffi_type *ty) +{ + ffi_type **elements = ty->elements; + int i, ret = -1; + + if (elements != NULL) + for (i = 0; elements[i]; ++i) + { + ret = elements[i]->type; + if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX) + { + ret = is_hfa0 (elements[i]); + if (ret < 0) + continue; + } + break; + } + + return ret; +} + +/* A subroutine of vfp_type_p. Given a structure type, return true if all + of the non-structure elements are the same as CANDIDATE. */ + +static int +is_hfa1 (const ffi_type *ty, int candidate) +{ + ffi_type **elements = ty->elements; + int i; + + if (elements != NULL) + for (i = 0; elements[i]; ++i) + { + int t = elements[i]->type; + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX) + { + if (!is_hfa1 (elements[i], candidate)) + return 0; + } + else if (t != candidate) + return 0; + } + + return 1; +} + +/* Determine if TY is an homogenous floating point aggregate (HFA). + That is, a structure consisting of 1 to 4 members of all the same type, + where that type is a floating point scalar. + + Returns non-zero iff TY is an HFA. The result is an encoded value where + bits 0-7 contain the type code, and bits 8-10 contain the element count. */ + +static int +vfp_type_p (const ffi_type *ty) +{ + ffi_type **elements; + int candidate, i; + size_t size, ele_count; + + /* Quickest tests first. */ + candidate = ty->type; + switch (ty->type) + { + default: + return 0; + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + ele_count = 1; + goto done; + case FFI_TYPE_COMPLEX: + candidate = ty->elements[0]->type; + if (candidate != FFI_TYPE_FLOAT && candidate != FFI_TYPE_DOUBLE) + return 0; + ele_count = 2; + goto done; + case FFI_TYPE_STRUCT: + break; + } + + /* No HFA types are smaller than 4 bytes, or larger than 32 bytes. */ + size = ty->size; + if (size < 4 || size > 32) + return 0; + + /* Find the type of the first non-structure member. */ + elements = ty->elements; + candidate = elements[0]->type; + if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX) + { + for (i = 0; ; ++i) + { + candidate = is_hfa0 (elements[i]); + if (candidate >= 0) + break; + } + } + + /* If the first member is not a floating point type, it's not an HFA. + Also quickly re-check the size of the structure. */ + switch (candidate) + { + case FFI_TYPE_FLOAT: + ele_count = size / sizeof(float); + if (size != ele_count * sizeof(float)) + return 0; + break; + case FFI_TYPE_DOUBLE: + ele_count = size / sizeof(double); + if (size != ele_count * sizeof(double)) + return 0; + break; + default: + return 0; + } + if (ele_count > 4) + return 0; + + /* Finally, make sure that all scalar elements are the same type. */ + for (i = 0; elements[i]; ++i) + { + int t = elements[i]->type; + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX) + { + if (!is_hfa1 (elements[i], candidate)) + return 0; + } + else if (t != candidate) + return 0; + } + + /* All tests succeeded. Encode the result. */ + done: + return (ele_count << 8) | candidate; +} + +static int +place_vfp_arg (ffi_cif *cif, int h) +{ + unsigned short reg = cif->vfp_reg_free; + int align = 1, nregs = h >> 8; + + if ((h & 0xff) == FFI_TYPE_DOUBLE) + align = 2, nregs *= 2; + + /* Align register number. */ + if ((reg & 1) && align == 2) + reg++; + + while (reg + nregs <= 16) + { + int s, new_used = 0; + for (s = reg; s < reg + nregs; s++) + { + new_used |= (1 << s); + if (cif->vfp_used & (1 << s)) + { + reg += align; + goto next_reg; + } + } + /* Found regs to allocate. */ + cif->vfp_used |= new_used; + cif->vfp_args[cif->vfp_nargs++] = reg; + + /* Update vfp_reg_free. */ + if (cif->vfp_used & (1 << cif->vfp_reg_free)) + { + reg += nregs; + while (cif->vfp_used & (1 << reg)) + reg += 1; + cif->vfp_reg_free = reg; + } + return 0; + next_reg:; + } + // done, mark all regs as used + cif->vfp_reg_free = 16; + cif->vfp_used = 0xFFFF; + return 1; +} + +static void +layout_vfp_args (ffi_cif * cif) +{ + int i; + /* Init VFP fields */ + cif->vfp_used = 0; + cif->vfp_nargs = 0; + cif->vfp_reg_free = 0; + memset (cif->vfp_args, -1, 16); /* Init to -1. */ + + for (i = 0; i < cif->nargs; i++) + { + int h = vfp_type_p (cif->arg_types[i]); + if (h && place_vfp_arg (cif, h) == 1) + break; + } +} diff --git a/circuitpython/lib/libffi/src/arm/ffitarget.h b/circuitpython/lib/libffi/src/arm/ffitarget.h new file mode 100644 index 0000000..4f473f9 --- /dev/null +++ b/circuitpython/lib/libffi/src/arm/ffitarget.h @@ -0,0 +1,69 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 2010 CodeSourcery + Copyright (c) 1996-2003 Red Hat, Inc. + + Target configuration macros for ARM. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_VFP, + FFI_LAST_ABI, +#ifdef __ARM_PCS_VFP + FFI_DEFAULT_ABI = FFI_VFP, +#else + FFI_DEFAULT_ABI = FFI_SYSV, +#endif +} ffi_abi; +#endif + +#define FFI_EXTRA_CIF_FIELDS \ + int vfp_used; \ + unsigned short vfp_reg_free, vfp_nargs; \ + signed char vfp_args[16] \ + +#define FFI_TARGET_SPECIFIC_VARIADIC +#define FFI_TARGET_HAS_COMPLEX_TYPE + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_GO_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 12 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/arm/internal.h b/circuitpython/lib/libffi/src/arm/internal.h new file mode 100644 index 0000000..6cf0b2a --- /dev/null +++ b/circuitpython/lib/libffi/src/arm/internal.h @@ -0,0 +1,7 @@ +#define ARM_TYPE_VFP_S 0 +#define ARM_TYPE_VFP_D 1 +#define ARM_TYPE_VFP_N 2 +#define ARM_TYPE_INT64 3 +#define ARM_TYPE_INT 4 +#define ARM_TYPE_VOID 5 +#define ARM_TYPE_STRUCT 6 diff --git a/circuitpython/lib/libffi/src/arm/sysv.S b/circuitpython/lib/libffi/src/arm/sysv.S new file mode 100644 index 0000000..fd16589 --- /dev/null +++ b/circuitpython/lib/libffi/src/arm/sysv.S @@ -0,0 +1,335 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc. + Copyright (c) 2011 Plausible Labs Cooperative, Inc. + + ARM Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include +#include +#include "internal.h" + +/* GCC 4.8 provides __ARM_ARCH; construct it otherwise. */ +#ifndef __ARM_ARCH +# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7EM__) +# define __ARM_ARCH 7 +# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_6M__) +# define __ARM_ARCH 6 +# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) +# define __ARM_ARCH 5 +# else +# define __ARM_ARCH 4 +# endif +#endif + +/* Conditionally compile unwinder directives. */ +.macro UNWIND text:vararg +#ifdef __ARM_EABI__ + \text +#endif +.endm +#if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__ARM_EABI__) + .cfi_sections .debug_frame +#endif + +#define CONCAT(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +#ifdef __USER_LABEL_PREFIX__ +# define CNAME(X) CONCAT (__USER_LABEL_PREFIX__, X) +#else +# define CNAME(X) X +#endif +#ifdef __ELF__ +# define SIZE(X) .size CNAME(X), . - CNAME(X) +# define TYPE(X, Y) .type CNAME(X), Y +#else +# define SIZE(X) +# define TYPE(X, Y) +#endif + +#define ARM_FUNC_START(name, gl) \ + .align 3; \ + .ifne gl; .globl CNAME(name); FFI_HIDDEN(CNAME(name)); .endif; \ + TYPE(name, %function); \ + CNAME(name): + +#define ARM_FUNC_END(name) \ + SIZE(name) + +/* Aid in defining a jump table with 8 bytes between entries. */ +.macro E index + .if . - 0b - 8*\index + .error "type table out of sync" + .endif +.endm + + .text + .syntax unified + .arm + + /* We require interworking on LDM, which implies ARMv5T, + which implies the existance of BLX. */ + .arch armv5t + + /* Note that we use STC and LDC to encode VFP instructions, + so that we do not need ".fpu vfp", nor get that added to + the object file attributes. These will not be executed + unless the FFI_VFP abi is used. */ + + @ r0: stack + @ r1: frame + @ r2: fn + @ r3: vfp_used + +ARM_FUNC_START(ffi_call_VFP, 1) + UNWIND .fnstart + cfi_startproc + + cmp r3, #3 @ load only d0 if possible + ldcle p11, cr0, [r0] @ vldrle d0, [sp] + ldcgt p11, cr0, [r0], {16} @ vldmgt sp, {d0-d7} + add r0, r0, #64 @ discard the vfp register args + /* FALLTHRU */ +ARM_FUNC_END(ffi_call_VFP) + +ARM_FUNC_START(ffi_call_SYSV, 1) + stm r1, {fp, lr} + mov fp, r1 + + @ This is a bit of a lie wrt the origin of the unwind info, but + @ now we've got the usual frame pointer and two saved registers. + UNWIND .save {fp,lr} + UNWIND .setfp fp, sp + cfi_def_cfa(fp, 8) + cfi_rel_offset(fp, 0) + cfi_rel_offset(lr, 4) + + mov sp, r0 @ install the stack pointer + mov lr, r2 @ move the fn pointer out of the way + ldr ip, [fp, #16] @ install the static chain + ldmia sp!, {r0-r3} @ move first 4 parameters in registers. + blx lr @ call fn + + @ Load r2 with the pointer to storage for the return value + @ Load r3 with the return type code + ldr r2, [fp, #8] + ldr r3, [fp, #12] + + @ Deallocate the stack with the arguments. + mov sp, fp + cfi_def_cfa_register(sp) + + @ Store values stored in registers. + .align 3 + add pc, pc, r3, lsl #3 + nop +0: +E ARM_TYPE_VFP_S + stc p10, cr0, [r2] @ vstr s0, [r2] + pop {fp,pc} +E ARM_TYPE_VFP_D + stc p11, cr0, [r2] @ vstr d0, [r2] + pop {fp,pc} +E ARM_TYPE_VFP_N + stc p11, cr0, [r2], {8} @ vstm r2, {d0-d3} + pop {fp,pc} +E ARM_TYPE_INT64 + str r1, [r2, #4] + nop +E ARM_TYPE_INT + str r0, [r2] + pop {fp,pc} +E ARM_TYPE_VOID + pop {fp,pc} + nop +E ARM_TYPE_STRUCT + pop {fp,pc} + + cfi_endproc + UNWIND .fnend +ARM_FUNC_END(ffi_call_SYSV) + + +/* + int ffi_closure_inner_* (cif, fun, user_data, frame) +*/ + +ARM_FUNC_START(ffi_go_closure_SYSV, 1) + cfi_startproc + stmdb sp!, {r0-r3} @ save argument regs + cfi_adjust_cfa_offset(16) + ldr r0, [ip, #4] @ load cif + ldr r1, [ip, #8] @ load fun + mov r2, ip @ load user_data + b 0f + cfi_endproc +ARM_FUNC_END(ffi_go_closure_SYSV) + +ARM_FUNC_START(ffi_closure_SYSV, 1) + UNWIND .fnstart + cfi_startproc + stmdb sp!, {r0-r3} @ save argument regs + cfi_adjust_cfa_offset(16) + ldr r0, [ip, #FFI_TRAMPOLINE_SIZE] @ load cif + ldr r1, [ip, #FFI_TRAMPOLINE_SIZE+4] @ load fun + ldr r2, [ip, #FFI_TRAMPOLINE_SIZE+8] @ load user_data +0: + add ip, sp, #16 @ compute entry sp + sub sp, sp, #64+32 @ allocate frame + cfi_adjust_cfa_offset(64+32) + stmdb sp!, {ip,lr} + + /* Remember that EABI unwind info only applies at call sites. + We need do nothing except note the save of the stack pointer + and the link registers. */ + UNWIND .save {sp,lr} + cfi_adjust_cfa_offset(8) + cfi_rel_offset(lr, 4) + + add r3, sp, #8 @ load frame + bl CNAME(ffi_closure_inner_SYSV) + + @ Load values returned in registers. + add r2, sp, #8+64 @ load result + adr r3, CNAME(ffi_closure_ret) + add pc, r3, r0, lsl #3 + cfi_endproc + UNWIND .fnend +ARM_FUNC_END(ffi_closure_SYSV) + +ARM_FUNC_START(ffi_go_closure_VFP, 1) + cfi_startproc + stmdb sp!, {r0-r3} @ save argument regs + cfi_adjust_cfa_offset(16) + ldr r0, [ip, #4] @ load cif + ldr r1, [ip, #8] @ load fun + mov r2, ip @ load user_data + b 0f + cfi_endproc +ARM_FUNC_END(ffi_go_closure_VFP) + +ARM_FUNC_START(ffi_closure_VFP, 1) + UNWIND .fnstart + cfi_startproc + stmdb sp!, {r0-r3} @ save argument regs + cfi_adjust_cfa_offset(16) + ldr r0, [ip, #FFI_TRAMPOLINE_SIZE] @ load cif + ldr r1, [ip, #FFI_TRAMPOLINE_SIZE+4] @ load fun + ldr r2, [ip, #FFI_TRAMPOLINE_SIZE+8] @ load user_data +0: + add ip, sp, #16 + sub sp, sp, #64+32 @ allocate frame + cfi_adjust_cfa_offset(64+32) + stc p11, cr0, [sp], {16} @ vstm sp, {d0-d7} + stmdb sp!, {ip,lr} + + /* See above. */ + UNWIND .save {sp,lr} + cfi_adjust_cfa_offset(8) + cfi_rel_offset(lr, 4) + + add r3, sp, #8 @ load frame + bl CNAME(ffi_closure_inner_VFP) + + @ Load values returned in registers. + add r2, sp, #8+64 @ load result + adr r3, CNAME(ffi_closure_ret) + add pc, r3, r0, lsl #3 + cfi_endproc + UNWIND .fnend +ARM_FUNC_END(ffi_closure_VFP) + +/* Load values returned in registers for both closure entry points. + Note that we use LDM with SP in the register set. This is deprecated + by ARM, but not yet unpredictable. */ + +ARM_FUNC_START(ffi_closure_ret, 0) + cfi_startproc + cfi_rel_offset(sp, 0) + cfi_rel_offset(lr, 4) +0: +E ARM_TYPE_VFP_S + ldc p10, cr0, [r2] @ vldr s0, [r2] + ldm sp, {sp,pc} +E ARM_TYPE_VFP_D + ldc p11, cr0, [r2] @ vldr d0, [r2] + ldm sp, {sp,pc} +E ARM_TYPE_VFP_N + ldc p11, cr0, [r2], {8} @ vldm r2, {d0-d3} + ldm sp, {sp,pc} +E ARM_TYPE_INT64 + ldr r1, [r2, #4] + nop +E ARM_TYPE_INT + ldr r0, [r2] + ldm sp, {sp,pc} +E ARM_TYPE_VOID + ldm sp, {sp,pc} + nop +E ARM_TYPE_STRUCT + ldm sp, {sp,pc} + cfi_endproc +ARM_FUNC_END(ffi_closure_ret) + +#if FFI_EXEC_TRAMPOLINE_TABLE + +/* ??? The iOS support should be updated. The first insn used to + be STMFD, but that's been moved into ffi_closure_SYSV. If the + writable page is put after this one we can make use of the + pc+8 feature of the architecture. We can also reduce the size + of the thunk to 8 and pack more of these into the page. + + In the meantime, simply replace the STMFD with a NOP so as to + keep all the magic numbers the same within ffi.c. */ + + .align 12 +ARM_FUNC_START(ffi_closure_trampoline_table_page) +.rept 4096 / 12 + nop + ldr ip, [pc, #-4092] + ldr pc, [pc, #-4092] +.endr + +#else + +ARM_FUNC_START(ffi_arm_trampoline, 1) +0: adr ip, 0b + ldr pc, 1f +1: .long 0 +ARM_FUNC_END(ffi_arm_trampoline) + +#endif /* FFI_EXEC_TRAMPOLINE_TABLE */ + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",%progbits +#endif diff --git a/circuitpython/lib/libffi/src/avr32/ffi.c b/circuitpython/lib/libffi/src/avr32/ffi.c new file mode 100644 index 0000000..3d43397 --- /dev/null +++ b/circuitpython/lib/libffi/src/avr32/ffi.c @@ -0,0 +1,423 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2011 Anthony Green + Copyright (c) 2009 Bradley Smith + + AVR32 Foreign Function Interface + + 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 +#include + +#include +#include +#include +#include + +/* #define DEBUG */ + +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned int, unsigned int, unsigned int*, unsigned int, + void (*fn)(void)); +extern void ffi_closure_SYSV (ffi_closure *); + +unsigned int pass_struct_on_stack(ffi_type *type) +{ + if(type->type != FFI_TYPE_STRUCT) + return 0; + + if(type->alignment < type->size && + !(type->size == 4 || type->size == 8) && + !(type->size == 8 && type->alignment >= 4)) + return 1; + + if(type->size == 3 || type->size == 5 || type->size == 6 || + type->size == 7) + return 1; + + return 0; +} + +/* ffi_prep_args is called by the assembly routine once stack space + * has been allocated for the function's arguments + * + * This is annoyingly complex since we need to keep track of used + * registers. + */ + +void ffi_prep_args(char *stack, extended_cif *ecif) +{ + unsigned int i; + void **p_argv; + ffi_type **p_arg; + char *reg_base = stack; + char *stack_base = stack + 20; + unsigned int stack_offset = 0; + unsigned int reg_mask = 0; + + p_argv = ecif->avalue; + + /* If cif->flags is struct then we know it's not passed in registers */ + if(ecif->cif->flags == FFI_TYPE_STRUCT) + { + *(void**)reg_base = ecif->rvalue; + reg_mask |= 1; + } + + for(i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; + i++, p_arg++) + { + size_t z = (*p_arg)->size; + int alignment = (*p_arg)->alignment; + int type = (*p_arg)->type; + char *addr = 0; + + if(z % 4 != 0) + z += (4 - z % 4); + + if(reg_mask != 0x1f) + { + if(pass_struct_on_stack(*p_arg)) + { + addr = stack_base + stack_offset; + stack_offset += z; + } + else if(z == sizeof(int)) + { + char index = 0; + + while((reg_mask >> index) & 1) + index++; + + addr = reg_base + (index * 4); + reg_mask |= (1 << index); + } + else if(z == 2 * sizeof(int)) + { + if(!((reg_mask >> 1) & 1)) + { + addr = reg_base + 4; + reg_mask |= (3 << 1); + } + else if(!((reg_mask >> 3) & 1)) + { + addr = reg_base + 12; + reg_mask |= (3 << 3); + } + } + } + + if(!addr) + { + addr = stack_base + stack_offset; + stack_offset += z; + } + + if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] == NULL) + type = (*p_arg)->elements[0]->type; + + switch(type) + { + case FFI_TYPE_UINT8: + *(unsigned int *)addr = (unsigned int)*(UINT8 *)(*p_argv); + break; + case FFI_TYPE_SINT8: + *(signed int *)addr = (signed int)*(SINT8 *)(*p_argv); + break; + case FFI_TYPE_UINT16: + *(unsigned int *)addr = (unsigned int)*(UINT16 *)(*p_argv); + break; + case FFI_TYPE_SINT16: + *(signed int *)addr = (signed int)*(SINT16 *)(*p_argv); + break; + default: + memcpy(addr, *p_argv, z); + } + + p_argv++; + } + +#ifdef DEBUG + /* Debugging */ + for(i = 0; i < 5; i++) + { + if((reg_mask & (1 << i)) == 0) + printf("r%d: (unused)\n", 12 - i); + else + printf("r%d: 0x%08x\n", 12 - i, ((unsigned int*)reg_base)[i]); + } + + for(i = 0; i < stack_offset / 4; i++) + { + printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack_base)[i]); + } +#endif +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* Round the stack up to a multiple of 8 bytes. This isn't needed + * everywhere, but it is on some platforms, and it doesn't harm + * anything when it isn't needed. */ + cif->bytes = (cif->bytes + 7) & ~7; + + /* Flag to indicate that he return value is in fact a struct */ + cif->rstruct_flag = 0; + + /* Set the return type flag */ + switch(cif->rtype->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + cif->flags = (unsigned)FFI_TYPE_UINT8; + break; + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + cif->flags = (unsigned)FFI_TYPE_UINT16; + break; + case FFI_TYPE_FLOAT: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + cif->flags = (unsigned)FFI_TYPE_UINT32; + break; + case FFI_TYPE_DOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags = (unsigned)FFI_TYPE_UINT64; + break; + case FFI_TYPE_STRUCT: + cif->rstruct_flag = 1; + if(!pass_struct_on_stack(cif->rtype)) + { + if(cif->rtype->size <= 1) + cif->flags = (unsigned)FFI_TYPE_UINT8; + else if(cif->rtype->size <= 2) + cif->flags = (unsigned)FFI_TYPE_UINT16; + else if(cif->rtype->size <= 4) + cif->flags = (unsigned)FFI_TYPE_UINT32; + else if(cif->rtype->size <= 8) + cif->flags = (unsigned)FFI_TYPE_UINT64; + else + cif->flags = (unsigned)cif->rtype->type; + } + else + cif->flags = (unsigned)cif->rtype->type; + break; + default: + cif->flags = (unsigned)cif->rtype->type; + break; + } + + return FFI_OK; +} + +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + unsigned int size = 0, i = 0; + ffi_type **p_arg; + + ecif.cif = cif; + ecif.avalue = avalue; + + for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++) + size += (*p_arg)->size + (4 - (*p_arg)->size % 4); + + /* If the return value is a struct and we don't have a return value + * address then we need to make one */ + + /* If cif->flags is struct then it's not suitable for registers */ + if((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT)) + ecif.rvalue = alloca(cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch(cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args, &ecif, size, cif->flags, + ecif.rvalue, cif->rstruct_flag, fn); + break; + default: + FFI_ASSERT(0); + break; + } +} + +static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, + void **avalue, ffi_cif *cif) +{ + register unsigned int i, reg_mask = 0; + register void **p_argv; + register ffi_type **p_arg; + register char *reg_base = stack; + register char *stack_base = stack + 20; + register unsigned int stack_offset = 0; + +#ifdef DEBUG + /* Debugging */ + for(i = 0; i < cif->nargs + 7; i++) + { + printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack)[i]); + } +#endif + + /* If cif->flags is struct then we know it's not passed in registers */ + if(cif->flags == FFI_TYPE_STRUCT) + { + *rvalue = *(void **)reg_base; + reg_mask |= 1; + } + + p_argv = avalue; + + for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++) + { + size_t z = (*p_arg)->size; + int alignment = (*p_arg)->alignment; + + *p_argv = 0; + + if(z % 4 != 0) + z += (4 - z % 4); + + if(reg_mask != 0x1f) + { + if(pass_struct_on_stack(*p_arg)) + { + *p_argv = (void*)stack_base + stack_offset; + stack_offset += z; + } + else if(z <= sizeof(int)) + { + char index = 0; + + while((reg_mask >> index) & 1) + index++; + + *p_argv = (void*)reg_base + (index * 4); + reg_mask |= (1 << index); + } + else if(z == 2 * sizeof(int)) + { + if(!((reg_mask >> 1) & 1)) + { + *p_argv = (void*)reg_base + 4; + reg_mask |= (3 << 1); + } + else if(!((reg_mask >> 3) & 1)) + { + *p_argv = (void*)reg_base + 12; + reg_mask |= (3 << 3); + } + } + } + + if(!*p_argv) + { + *p_argv = (void*)stack_base + stack_offset; + stack_offset += z; + } + + if((*p_arg)->type != FFI_TYPE_STRUCT || + (*p_arg)->elements[1] == NULL) + { + if(alignment == 1) + **(unsigned int**)p_argv <<= 24; + else if(alignment == 2) + **(unsigned int**)p_argv <<= 16; + } + + p_argv++; + } + +#ifdef DEBUG + /* Debugging */ + for(i = 0; i < cif->nargs; i++) + { + printf("sp+%d: 0x%08x\n", i*4, *(((unsigned int**)avalue)[i])); + } +#endif +} + +/* This function is jumped to by the trampoline */ + +unsigned int ffi_closure_SYSV_inner(ffi_closure *closure, void **respp, + void *args) +{ + ffi_cif *cif; + void **arg_area; + unsigned int i, size = 0; + ffi_type **p_arg; + + cif = closure->cif; + + for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++) + size += (*p_arg)->size + (4 - (*p_arg)->size % 4); + + arg_area = (void **)alloca(size); + + /* this call will initialize ARG_AREA, such that each element in that + * array points to the corresponding value on the stack; and if the + * function returns a structure, it will re-set RESP to point to the + * structure return address. */ + + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); + + (closure->fun)(cif, *respp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), void *user_data, + void *codeloc) +{ + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + unsigned char *__tramp = (unsigned char*)(&closure->tramp[0]); + unsigned int __fun = (unsigned int)(&ffi_closure_SYSV); + unsigned int __ctx = (unsigned int)(codeloc); + unsigned int __rstruct_flag = (unsigned int)(cif->rstruct_flag); + unsigned int __inner = (unsigned int)(&ffi_closure_SYSV_inner); + *(unsigned int*) &__tramp[0] = 0xebcd1f00; /* pushm r8-r12 */ + *(unsigned int*) &__tramp[4] = 0xfefc0010; /* ld.w r12, pc[16] */ + *(unsigned int*) &__tramp[8] = 0xfefb0010; /* ld.w r11, pc[16] */ + *(unsigned int*) &__tramp[12] = 0xfefa0010; /* ld.w r10, pc[16] */ + *(unsigned int*) &__tramp[16] = 0xfeff0010; /* ld.w pc, pc[16] */ + *(unsigned int*) &__tramp[20] = __ctx; + *(unsigned int*) &__tramp[24] = __rstruct_flag; + *(unsigned int*) &__tramp[28] = __inner; + *(unsigned int*) &__tramp[32] = __fun; + syscall(__NR_cacheflush, 0, (&__tramp[0]), 36); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + diff --git a/circuitpython/lib/libffi/src/avr32/ffitarget.h b/circuitpython/lib/libffi/src/avr32/ffitarget.h new file mode 100644 index 0000000..d0c7586 --- /dev/null +++ b/circuitpython/lib/libffi/src/avr32/ffitarget.h @@ -0,0 +1,55 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 2009 Bradley Smith + Target configuration macros for AVR32. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +#define FFI_EXTRA_CIF_FIELDS unsigned int rstruct_flag + +/* Definitions for closures */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 36 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/avr32/sysv.S b/circuitpython/lib/libffi/src/avr32/sysv.S new file mode 100644 index 0000000..a984b3c --- /dev/null +++ b/circuitpython/lib/libffi/src/avr32/sysv.S @@ -0,0 +1,208 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2009 Bradley Smith + + AVR32 Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + + /* r12: ffi_prep_args + * r11: &ecif + * r10: size + * r9: cif->flags + * r8: ecif.rvalue + * sp+0: cif->rstruct_flag + * sp+4: fn */ + + .text + .align 1 + .globl ffi_call_SYSV + .type ffi_call_SYSV, @function +ffi_call_SYSV: + stm --sp, r0,r1,lr + stm --sp, r8-r12 + mov r0, sp + + /* Make room for all of the new args. */ + sub sp, r10 + /* Pad to make way for potential skipped registers */ + sub sp, 20 + + /* Call ffi_prep_args(stack, &ecif). */ + /* r11 already set */ + mov r1, r12 + mov r12, sp + icall r1 + + /* Save new argument size */ + mov r1, r12 + + /* Move first 5 parameters in registers. */ + ldm sp++, r8-r12 + + /* call (fn) (...). */ + ld.w r1, r0[36] + icall r1 + + /* Remove the space we pushed for the args. */ + mov sp, r0 + + /* Load r1 with the rstruct flag. */ + ld.w r1, sp[32] + + /* Load r9 with the return type code. */ + ld.w r9, sp[12] + + /* Load r8 with the return value pointer. */ + ld.w r8, sp[16] + + /* If the return value pointer is NULL, assume no return value. */ + cp.w r8, 0 + breq .Lend + + /* Check if return type is actually a struct */ + cp.w r1, 0 + breq 1f + + /* Return 8bit */ + cp.w r9, FFI_TYPE_UINT8 + breq .Lstore8 + + /* Return 16bit */ + cp.w r9, FFI_TYPE_UINT16 + breq .Lstore16 + +1: + /* Return 32bit */ + cp.w r9, FFI_TYPE_UINT32 + breq .Lstore32 + cp.w r9, FFI_TYPE_UINT16 + breq .Lstore32 + cp.w r9, FFI_TYPE_UINT8 + breq .Lstore32 + + /* Return 64bit */ + cp.w r9, FFI_TYPE_UINT64 + breq .Lstore64 + + /* Didn't match anything */ + bral .Lend + +.Lstore64: + st.w r8[0], r11 + st.w r8[4], r10 + bral .Lend + +.Lstore32: + st.w r8[0], r12 + bral .Lend + +.Lstore16: + st.h r8[0], r12 + bral .Lend + +.Lstore8: + st.b r8[0], r12 + bral .Lend + +.Lend: + sub sp, -20 + ldm sp++, r0,r1,pc + + .size ffi_call_SYSV, . - ffi_call_SYSV + + + /* r12: __ctx + * r11: __rstruct_flag + * r10: __inner */ + + .align 1 + .globl ffi_closure_SYSV + .type ffi_closure_SYSV, @function +ffi_closure_SYSV: + stm --sp, r0,lr + mov r0, r11 + mov r8, r10 + sub r10, sp, -8 + sub sp, 12 + st.w sp[8], sp + sub r11, sp, -8 + icall r8 + + /* Check if return type is actually a struct */ + cp.w r0, 0 + breq 1f + + /* Return 8bit */ + cp.w r12, FFI_TYPE_UINT8 + breq .Lget8 + + /* Return 16bit */ + cp.w r12, FFI_TYPE_UINT16 + breq .Lget16 + +1: + /* Return 32bit */ + cp.w r12, FFI_TYPE_UINT32 + breq .Lget32 + cp.w r12, FFI_TYPE_UINT16 + breq .Lget32 + cp.w r12, FFI_TYPE_UINT8 + breq .Lget32 + + /* Return 64bit */ + cp.w r12, FFI_TYPE_UINT64 + breq .Lget64 + + /* Didn't match anything */ + bral .Lclend + +.Lget64: + ld.w r11, sp[0] + ld.w r10, sp[4] + bral .Lclend + +.Lget32: + ld.w r12, sp[0] + bral .Lclend + +.Lget16: + ld.uh r12, sp[0] + bral .Lclend + +.Lget8: + ld.ub r12, sp[0] + bral .Lclend + +.Lclend: + sub sp, -12 + ldm sp++, r0,lr + sub sp, -20 + mov pc, lr + + .size ffi_closure_SYSV, . - ffi_closure_SYSV + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/bfin/ffi.c b/circuitpython/lib/libffi/src/bfin/ffi.c new file mode 100644 index 0000000..22a2acd --- /dev/null +++ b/circuitpython/lib/libffi/src/bfin/ffi.c @@ -0,0 +1,196 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2012 Alexandre K. I. de Mendonca , + Paulo Pizarro + + Blackfin Foreign Function Interface + + 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 +#include + +#include +#include + +/* Maximum number of GPRs available for argument passing. */ +#define MAX_GPRARGS 3 + +/* + * Return types + */ +#define FFIBFIN_RET_VOID 0 +#define FFIBFIN_RET_BYTE 1 +#define FFIBFIN_RET_HALFWORD 2 +#define FFIBFIN_RET_INT64 3 +#define FFIBFIN_RET_INT32 4 + +/*====================================================================*/ +/* PROTOTYPE * + /*====================================================================*/ +void ffi_prep_args(unsigned char *, extended_cif *); + +/*====================================================================*/ +/* Externals */ +/* (Assembly) */ +/*====================================================================*/ + +extern void ffi_call_SYSV(unsigned, extended_cif *, void(*)(unsigned char *, extended_cif *), unsigned, void *, void(*fn)(void)); + +/*====================================================================*/ +/* Implementation */ +/* */ +/*====================================================================*/ + + +/* + * This function calculates the return type (size) based on type. + */ + +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* --------------------------------------* + * Return handling * + * --------------------------------------*/ + switch (cif->rtype->type) { + case FFI_TYPE_VOID: + cif->flags = FFIBFIN_RET_VOID; + break; + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + cif->flags = FFIBFIN_RET_HALFWORD; + break; + case FFI_TYPE_UINT8: + cif->flags = FFIBFIN_RET_BYTE; + break; + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_FLOAT: + case FFI_TYPE_POINTER: + case FFI_TYPE_SINT8: + cif->flags = FFIBFIN_RET_INT32; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + cif->flags = FFIBFIN_RET_INT64; + break; + case FFI_TYPE_STRUCT: + if (cif->rtype->size <= 4){ + cif->flags = FFIBFIN_RET_INT32; + }else if (cif->rtype->size == 8){ + cif->flags = FFIBFIN_RET_INT64; + }else{ + //it will return via a hidden pointer in P0 + cif->flags = FFIBFIN_RET_VOID; + } + break; + default: + FFI_ASSERT(0); + break; + } + return FFI_OK; +} + +/* + * This will prepare the arguments and will call the assembly routine + * cif = the call interface + * fn = the function to be called + * rvalue = the return value + * avalue = the arguments + */ +void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue) +{ + int ret_type = cif->flags; + extended_cif ecif; + ecif.cif = cif; + ecif.avalue = avalue; + ecif.rvalue = rvalue; + + switch (cif->abi) { + case FFI_SYSV: + ffi_call_SYSV(cif->bytes, &ecif, ffi_prep_args, ret_type, ecif.rvalue, fn); + break; + default: + FFI_ASSERT(0); + break; + } +} + + +/* +* This function prepares the parameters (copies them from the ecif to the stack) +* to call the function (ffi_prep_args is called by the assembly routine in file +* sysv.S, which also calls the actual function) +*/ +void ffi_prep_args(unsigned char *stack, extended_cif *ecif) +{ + register unsigned int i = 0; + void **p_argv; + unsigned char *argp; + ffi_type **p_arg; + argp = stack; + p_argv = ecif->avalue; + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); + i--, p_arg++) { + size_t z; + z = (*p_arg)->size; + if (z < sizeof(int)) { + z = sizeof(int); + switch ((*p_arg)->type) { + case FFI_TYPE_SINT8: { + signed char v = *(SINT8 *)(* p_argv); + signed int t = v; + *(signed int *) argp = t; + } + break; + case FFI_TYPE_UINT8: { + unsigned char v = *(UINT8 *)(* p_argv); + unsigned int t = v; + *(unsigned int *) argp = t; + } + break; + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) * (SINT16 *)(* p_argv); + break; + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) * (UINT16 *)(* p_argv); + break; + case FFI_TYPE_STRUCT: + memcpy(argp, *p_argv, (*p_arg)->size); + break; + default: + FFI_ASSERT(0); + break; + } + } else if (z == sizeof(int)) { + *(unsigned int *) argp = (unsigned int) * (UINT32 *)(* p_argv); + } else { + memcpy(argp, *p_argv, z); + } + p_argv++; + argp += z; + } +} + + + diff --git a/circuitpython/lib/libffi/src/bfin/ffitarget.h b/circuitpython/lib/libffi/src/bfin/ffitarget.h new file mode 100644 index 0000000..2175c01 --- /dev/null +++ b/circuitpython/lib/libffi/src/bfin/ffitarget.h @@ -0,0 +1,43 @@ +/* ----------------------------------------------------------------------- + ffitarget.h - Copyright (c) 2012 Alexandre K. I. de Mendonca + + Blackfin Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +#endif + diff --git a/circuitpython/lib/libffi/src/bfin/sysv.S b/circuitpython/lib/libffi/src/bfin/sysv.S new file mode 100644 index 0000000..f4278be --- /dev/null +++ b/circuitpython/lib/libffi/src/bfin/sysv.S @@ -0,0 +1,179 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca , + Paulo Pizarro + + Blackfin Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + +.text +.align 4 + + /* + There is a "feature" in the bfin toolchain that it puts a _ before function names + that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV + */ + .global _ffi_call_SYSV; + .type _ffi_call_SYSV, STT_FUNC; + .func ffi_call_SYSV + + /* + cif->bytes = R0 (fp+8) + &ecif = R1 (fp+12) + ffi_prep_args = R2 (fp+16) + ret_type = stack (fp+20) + ecif.rvalue = stack (fp+24) + fn = stack (fp+28) + got (fp+32) + + There is room for improvement here (we can use temporary registers + instead of saving the values in the memory) + REGS: + P5 => Stack pointer (function arguments) + R5 => cif->bytes + R4 => ret->type + + FP-20 = P3 + FP-16 = SP (parameters area) + FP-12 = SP (temp) + FP-08 = function return part 1 [R0] + FP-04 = function return part 2 [R1] + */ + +_ffi_call_SYSV: +.prologue: + LINK 20; + [FP-20] = P3; + [FP+8] = R0; + [FP+12] = R1; + [FP+16] = R2; + +.allocate_stack: + //alocate cif->bytes into the stack + R1 = [FP+8]; + R0 = SP; + R0 = R0 - R1; + R1 = 4; + R0 = R0 - R1; + [FP-12] = SP; + SP = R0; + [FP-16] = SP; + +.call_prep_args: + //get the addr of prep_args + P0 = [P3 + _ffi_prep_args@FUNCDESC_GOT17M4]; + P1 = [P0]; + P3 = [P0+4]; + R0 = [FP-16];//SP (parameter area) + R1 = [FP+12];//ecif + call (P1); + +.call_user_function: + //ajust SP so as to allow the user function access the parameters on the stack + SP = [FP-16]; //point to function parameters + R0 = [SP]; + R1 = [SP+4]; + R2 = [SP+8]; + //load user function address + P0 = FP; + P0 +=28; + P1 = [P0]; + P1 = [P1]; + P3 = [P0+4]; + /* + For functions returning aggregate values (struct) occupying more than 8 bytes, + the caller allocates the return value object on the stack and the address + of this object is passed to the callee as a hidden argument in register P0. + */ + P0 = [FP+24]; + + call (P1); + SP = [FP-12]; +.compute_return: + P2 = [FP-20]; + [FP-8] = R0; + [FP-4] = R1; + + R0 = [FP+20]; + R1 = R0 << 2; + + R0 = [P2+.rettable@GOT17M4]; + R0 = R1 + R0; + P2 = R0; + R1 = [P2]; + + P2 = [FP+-20]; + R0 = [P2+.rettable@GOT17M4]; + R0 = R1 + R0; + P2 = R0; + R0 = [FP-8]; + R1 = [FP-4]; + jump (P2); + +/* +#define FFIBFIN_RET_VOID 0 +#define FFIBFIN_RET_BYTE 1 +#define FFIBFIN_RET_HALFWORD 2 +#define FFIBFIN_RET_INT64 3 +#define FFIBFIN_RET_INT32 4 +*/ +.align 4 +.align 4 +.rettable: + .dd .epilogue - .rettable + .dd .rbyte - .rettable; + .dd .rhalfword - .rettable; + .dd .rint64 - .rettable; + .dd .rint32 - .rettable; + +.rbyte: + P0 = [FP+24]; + R0 = R0.B (Z); + [P0] = R0; + JUMP .epilogue +.rhalfword: + P0 = [FP+24]; + R0 = R0.L; + [P0] = R0; + JUMP .epilogue +.rint64: + P0 = [FP+24];// &rvalue + [P0] = R0; + [P0+4] = R1; + JUMP .epilogue +.rint32: + P0 = [FP+24]; + [P0] = R0; +.epilogue: + R0 = [FP+8]; + R1 = [FP+12]; + R2 = [FP+16]; + P3 = [FP-20]; + UNLINK; + RTS; + +.size _ffi_call_SYSV,.-_ffi_call_SYSV; +.endfunc diff --git a/circuitpython/lib/libffi/src/closures.c b/circuitpython/lib/libffi/src/closures.c new file mode 100644 index 0000000..721ff00 --- /dev/null +++ b/circuitpython/lib/libffi/src/closures.c @@ -0,0 +1,688 @@ +/* ----------------------------------------------------------------------- + closures.c - Copyright (c) 2007, 2009, 2010 Red Hat, Inc. + Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc + Copyright (c) 2011 Plausible Labs Cooperative, Inc. + + Code to allocate and deallocate memory for closures. + + 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. + ----------------------------------------------------------------------- */ + +#if defined __linux__ && !defined _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include + +#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE +# if __gnu_linux__ && !defined(__ANDROID__) +/* This macro indicates it may be forbidden to map anonymous memory + with both write and execute permission. Code compiled when this + option is defined will attempt to map such pages once, but if it + fails, it falls back to creating a temporary file in a writable and + executable filesystem and mapping pages from it into separate + locations in the virtual memory space, one location writable and + another executable. */ +# define FFI_MMAP_EXEC_WRIT 1 +# define HAVE_MNTENT 1 +# endif +# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__) +/* Windows systems may have Data Execution Protection (DEP) enabled, + which requires the use of VirtualMalloc/VirtualFree to alloc/free + executable memory. */ +# define FFI_MMAP_EXEC_WRIT 1 +# endif +#endif + +#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX +# ifdef __linux__ +/* When defined to 1 check for SELinux and if SELinux is active, + don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that + might cause audit messages. */ +# define FFI_MMAP_EXEC_SELINUX 1 +# endif +#endif + +#if FFI_CLOSURES + +# if FFI_EXEC_TRAMPOLINE_TABLE + +// Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations. + +# elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */ + +#define USE_LOCKS 1 +#define USE_DL_PREFIX 1 +#ifdef __GNUC__ +#ifndef USE_BUILTIN_FFS +#define USE_BUILTIN_FFS 1 +#endif +#endif + +/* We need to use mmap, not sbrk. */ +#define HAVE_MORECORE 0 + +/* We could, in theory, support mremap, but it wouldn't buy us anything. */ +#define HAVE_MREMAP 0 + +/* We have no use for this, so save some code and data. */ +#define NO_MALLINFO 1 + +/* We need all allocations to be in regular segments, otherwise we + lose track of the corresponding code address. */ +#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T + +/* Don't allocate more than a page unless needed. */ +#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize) + +#if FFI_CLOSURE_TEST +/* Don't release single pages, to avoid a worst-case scenario of + continuously allocating and releasing single pages, but release + pairs of pages, which should do just as well given that allocations + are likely to be small. */ +#define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize) +#endif + +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include +#if !defined(X86_WIN32) && !defined(X86_WIN64) +#ifdef HAVE_MNTENT +#include +#endif /* HAVE_MNTENT */ +#include +#include + +/* We don't want sys/mman.h to be included after we redefine mmap and + dlmunmap. */ +#include +#define LACKS_SYS_MMAN_H 1 + +#if FFI_MMAP_EXEC_SELINUX +#include +#include + +static int selinux_enabled = -1; + +static int +selinux_enabled_check (void) +{ + struct statfs sfs; + FILE *f; + char *buf = NULL; + size_t len = 0; + + if (statfs ("/selinux", &sfs) >= 0 + && (unsigned int) sfs.f_type == 0xf97cff8cU) + return 1; + f = fopen ("/proc/mounts", "r"); + if (f == NULL) + return 0; + while (getline (&buf, &len, f) >= 0) + { + char *p = strchr (buf, ' '); + if (p == NULL) + break; + p = strchr (p + 1, ' '); + if (p == NULL) + break; + if (strncmp (p + 1, "selinuxfs ", 10) == 0) + { + free (buf); + fclose (f); + return 1; + } + } + free (buf); + fclose (f); + return 0; +} + +#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \ + : (selinux_enabled = selinux_enabled_check ())) + +#else + +#define is_selinux_enabled() 0 + +#endif /* !FFI_MMAP_EXEC_SELINUX */ + +/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */ +#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX +#include + +static int emutramp_enabled = -1; + +static int +emutramp_enabled_check (void) +{ + char *buf = NULL; + size_t len = 0; + FILE *f; + int ret; + f = fopen ("/proc/self/status", "r"); + if (f == NULL) + return 0; + ret = 0; + + while (getline (&buf, &len, f) != -1) + if (!strncmp (buf, "PaX:", 4)) + { + char emutramp; + if (sscanf (buf, "%*s %*c%c", &emutramp) == 1) + ret = (emutramp == 'E'); + break; + } + free (buf); + fclose (f); + return ret; +} + +#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \ + : (emutramp_enabled = emutramp_enabled_check ())) +#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ + +#elif defined (__CYGWIN__) || defined(__INTERIX) + +#include + +/* Cygwin is Linux-like, but not quite that Linux-like. */ +#define is_selinux_enabled() 0 + +#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */ + +#ifndef FFI_MMAP_EXEC_EMUTRAMP_PAX +#define is_emutramp_enabled() 0 +#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ + +/* Declare all functions defined in dlmalloc.c as static. */ +static void *dlmalloc(size_t); +static void dlfree(void*); +static void *dlcalloc(size_t, size_t) MAYBE_UNUSED; +static void *dlrealloc(void *, size_t) MAYBE_UNUSED; +static void *dlmemalign(size_t, size_t) MAYBE_UNUSED; +static void *dlvalloc(size_t) MAYBE_UNUSED; +static int dlmallopt(int, int) MAYBE_UNUSED; +static size_t dlmalloc_footprint(void) MAYBE_UNUSED; +static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED; +static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED; +static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED; +static void *dlpvalloc(size_t) MAYBE_UNUSED; +static int dlmalloc_trim(size_t) MAYBE_UNUSED; +static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED; +static void dlmalloc_stats(void) MAYBE_UNUSED; + +#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) +/* Use these for mmap and munmap within dlmalloc.c. */ +static void *dlmmap(void *, size_t, int, int, int, off_t); +static int dlmunmap(void *, size_t); +#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */ + +#define mmap dlmmap +#define munmap dlmunmap + +#include "dlmalloc.c" + +#undef mmap +#undef munmap + +#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) + +/* A mutex used to synchronize access to *exec* variables in this file. */ +static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* A file descriptor of a temporary file from which we'll map + executable pages. */ +static int execfd = -1; + +/* The amount of space already allocated from the temporary file. */ +static size_t execsize = 0; + +/* Open a temporary file name, and immediately unlink it. */ +static int +open_temp_exec_file_name (char *name, int flags) +{ + int fd; + +#ifdef HAVE_MKOSTEMP + fd = mkostemp (name, flags); +#else + fd = mkstemp (name); +#endif + + if (fd != -1) + unlink (name); + + return fd; +} + +/* Open a temporary file in the named directory. */ +static int +open_temp_exec_file_dir (const char *dir) +{ + static const char suffix[] = "/ffiXXXXXX"; + int lendir, flags; + char *tempname; +#ifdef O_TMPFILE + int fd; +#endif + +#ifdef O_CLOEXEC + flags = O_CLOEXEC; +#else + flags = 0; +#endif + +#ifdef O_TMPFILE + fd = open (dir, flags | O_RDWR | O_EXCL | O_TMPFILE, 0700); + /* If the running system does not support the O_TMPFILE flag then retry without it. */ + if (fd != -1 || (errno != EINVAL && errno != EISDIR && errno != EOPNOTSUPP)) { + return fd; + } else { + errno = 0; + } +#endif + + lendir = strlen (dir); + tempname = __builtin_alloca (lendir + sizeof (suffix)); + + if (!tempname) + return -1; + + memcpy (tempname, dir, lendir); + memcpy (tempname + lendir, suffix, sizeof (suffix)); + + return open_temp_exec_file_name (tempname, flags); +} + +/* Open a temporary file in the directory in the named environment + variable. */ +static int +open_temp_exec_file_env (const char *envvar) +{ + const char *value = getenv (envvar); + + if (!value) + return -1; + + return open_temp_exec_file_dir (value); +} + +#ifdef HAVE_MNTENT +/* Open a temporary file in an executable and writable mount point + listed in the mounts file. Subsequent calls with the same mounts + keep searching for mount points in the same file. Providing NULL + as the mounts file closes the file. */ +static int +open_temp_exec_file_mnt (const char *mounts) +{ + static const char *last_mounts; + static FILE *last_mntent; + + if (mounts != last_mounts) + { + if (last_mntent) + endmntent (last_mntent); + + last_mounts = mounts; + + if (mounts) + last_mntent = setmntent (mounts, "r"); + else + last_mntent = NULL; + } + + if (!last_mntent) + return -1; + + for (;;) + { + int fd; + struct mntent mnt; + char buf[MAXPATHLEN * 3]; + + if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL) + return -1; + + if (hasmntopt (&mnt, "ro") + || hasmntopt (&mnt, "noexec") + || access (mnt.mnt_dir, W_OK)) + continue; + + fd = open_temp_exec_file_dir (mnt.mnt_dir); + + if (fd != -1) + return fd; + } +} +#endif /* HAVE_MNTENT */ + +/* Instructions to look for a location to hold a temporary file that + can be mapped in for execution. */ +static struct +{ + int (*func)(const char *); + const char *arg; + int repeat; +} open_temp_exec_file_opts[] = { + { open_temp_exec_file_env, "TMPDIR", 0 }, + { open_temp_exec_file_dir, "/tmp", 0 }, + { open_temp_exec_file_dir, "/var/tmp", 0 }, + { open_temp_exec_file_dir, "/dev/shm", 0 }, + { open_temp_exec_file_env, "HOME", 0 }, +#ifdef HAVE_MNTENT + { open_temp_exec_file_mnt, "/etc/mtab", 1 }, + { open_temp_exec_file_mnt, "/proc/mounts", 1 }, +#endif /* HAVE_MNTENT */ +}; + +/* Current index into open_temp_exec_file_opts. */ +static int open_temp_exec_file_opts_idx = 0; + +/* Reset a current multi-call func, then advances to the next entry. + If we're at the last, go back to the first and return nonzero, + otherwise return zero. */ +static int +open_temp_exec_file_opts_next (void) +{ + if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat) + open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL); + + open_temp_exec_file_opts_idx++; + if (open_temp_exec_file_opts_idx + == (sizeof (open_temp_exec_file_opts) + / sizeof (*open_temp_exec_file_opts))) + { + open_temp_exec_file_opts_idx = 0; + return 1; + } + + return 0; +} + +/* Return a file descriptor of a temporary zero-sized file in a + writable and executable filesystem. */ +static int +open_temp_exec_file (void) +{ + int fd; + + do + { + fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func + (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg); + + if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat + || fd == -1) + { + if (open_temp_exec_file_opts_next ()) + break; + } + } + while (fd == -1); + + return fd; +} + +/* Map in a chunk of memory from the temporary exec file into separate + locations in the virtual memory address space, one writable and one + executable. Returns the address of the writable portion, after + storing an offset to the corresponding executable portion at the + last word of the requested chunk. */ +static void * +dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset) +{ + void *ptr; + + if (execfd == -1) + { + open_temp_exec_file_opts_idx = 0; + retry_open: + execfd = open_temp_exec_file (); + if (execfd == -1) + return MFAIL; + } + + offset = execsize; + + if (ftruncate (execfd, offset + length)) + return MFAIL; + + flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS); + flags |= MAP_SHARED; + + ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC, + flags, execfd, offset); + if (ptr == MFAIL) + { + if (!offset) + { + close (execfd); + goto retry_open; + } + ftruncate (execfd, offset); + return MFAIL; + } + else if (!offset + && open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat) + open_temp_exec_file_opts_next (); + + start = mmap (start, length, prot, flags, execfd, offset); + + if (start == MFAIL) + { + munmap (ptr, length); + ftruncate (execfd, offset); + return start; + } + + mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start; + + execsize += length; + + return start; +} + +/* Map in a writable and executable chunk of memory if possible. + Failing that, fall back to dlmmap_locked. */ +static void * +dlmmap (void *start, size_t length, int prot, + int flags, int fd, off_t offset) +{ + void *ptr; + + assert (start == NULL && length % malloc_getpagesize == 0 + && prot == (PROT_READ | PROT_WRITE) + && flags == (MAP_PRIVATE | MAP_ANONYMOUS) + && fd == -1 && offset == 0); + +#if FFI_CLOSURE_TEST + printf ("mapping in %zi\n", length); +#endif + + if (execfd == -1 && is_emutramp_enabled ()) + { + ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset); + return ptr; + } + + if (execfd == -1 && !is_selinux_enabled ()) + { + ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset); + + if (ptr != MFAIL || (errno != EPERM && errno != EACCES)) + /* Cool, no need to mess with separate segments. */ + return ptr; + + /* If MREMAP_DUP is ever introduced and implemented, try mmap + with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with + MREMAP_DUP and prot at this point. */ + } + + if (execsize == 0 || execfd == -1) + { + pthread_mutex_lock (&open_temp_exec_file_mutex); + ptr = dlmmap_locked (start, length, prot, flags, offset); + pthread_mutex_unlock (&open_temp_exec_file_mutex); + + return ptr; + } + + return dlmmap_locked (start, length, prot, flags, offset); +} + +/* Release memory at the given address, as well as the corresponding + executable page if it's separate. */ +static int +dlmunmap (void *start, size_t length) +{ + /* We don't bother decreasing execsize or truncating the file, since + we can't quite tell whether we're unmapping the end of the file. + We don't expect frequent deallocation anyway. If we did, we + could locate pages in the file by writing to the pages being + deallocated and checking that the file contents change. + Yuck. */ + msegmentptr seg = segment_holding (gm, start); + void *code; + +#if FFI_CLOSURE_TEST + printf ("unmapping %zi\n", length); +#endif + + if (seg && (code = add_segment_exec_offset (start, seg)) != start) + { + int ret = munmap (code, length); + if (ret) + return ret; + } + + return munmap (start, length); +} + +#if FFI_CLOSURE_FREE_CODE +/* Return segment holding given code address. */ +static msegmentptr +segment_holding_code (mstate m, char* addr) +{ + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= add_segment_exec_offset (sp->base, sp) + && addr < add_segment_exec_offset (sp->base, sp) + sp->size) + return sp; + if ((sp = sp->next) == 0) + return 0; + } +} +#endif + +#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */ + +/* Allocate a chunk of memory with the given size. Returns a pointer + to the writable address, and sets *CODE to the executable + corresponding virtual address. */ +void * +ffi_closure_alloc (size_t size, void **code) +{ + void *ptr; + + if (!code) + return NULL; + + ptr = dlmalloc (size); + + if (ptr) + { + msegmentptr seg = segment_holding (gm, ptr); + + *code = add_segment_exec_offset (ptr, seg); + } + + return ptr; +} + +/* Release a chunk of memory allocated with ffi_closure_alloc. If + FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the + writable or the executable address given. Otherwise, only the + writable address can be provided here. */ +void +ffi_closure_free (void *ptr) +{ +#if FFI_CLOSURE_FREE_CODE + msegmentptr seg = segment_holding_code (gm, ptr); + + if (seg) + ptr = sub_segment_exec_offset (ptr, seg); +#endif + + dlfree (ptr); +} + + +#if FFI_CLOSURE_TEST +/* Do some internal sanity testing to make sure allocation and + deallocation of pages are working as intended. */ +int main () +{ + void *p[3]; +#define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0) +#define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0) + GET (0, malloc_getpagesize / 2); + GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*)); + PUT (1); + GET (1, 2 * malloc_getpagesize); + GET (2, malloc_getpagesize / 2); + PUT (1); + PUT (0); + PUT (2); + return 0; +} +#endif /* FFI_CLOSURE_TEST */ +# else /* ! FFI_MMAP_EXEC_WRIT */ + +/* On many systems, memory returned by malloc is writable and + executable, so just use it. */ + +#include + +void * +ffi_closure_alloc (size_t size, void **code) +{ + if (!code) + return NULL; + + return *code = malloc (size); +} + +void +ffi_closure_free (void *ptr) +{ + free (ptr); +} + +# endif /* ! FFI_MMAP_EXEC_WRIT */ +#endif /* FFI_CLOSURES */ diff --git a/circuitpython/lib/libffi/src/cris/ffi.c b/circuitpython/lib/libffi/src/cris/ffi.c new file mode 100644 index 0000000..aaca5b1 --- /dev/null +++ b/circuitpython/lib/libffi/src/cris/ffi.c @@ -0,0 +1,386 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 1998 Cygnus Solutions + Copyright (c) 2004 Simon Posnjak + Copyright (c) 2005 Axis Communications AB + Copyright (C) 2007 Free Software Foundation, Inc. + + CRIS Foreign Function Interface + + 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 SIMON POSNJAK 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 +#include + +#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) + +static ffi_status +initialize_aggregate_packed_struct (ffi_type * arg) +{ + ffi_type **ptr; + + FFI_ASSERT (arg != NULL); + + FFI_ASSERT (arg->elements != NULL); + FFI_ASSERT (arg->size == 0); + FFI_ASSERT (arg->alignment == 0); + + ptr = &(arg->elements[0]); + + while ((*ptr) != NULL) + { + if (((*ptr)->size == 0) + && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + FFI_ASSERT (ffi_type_test ((*ptr))); + + arg->size += (*ptr)->size; + + arg->alignment = (arg->alignment > (*ptr)->alignment) ? + arg->alignment : (*ptr)->alignment; + + ptr++; + } + + if (arg->size == 0) + return FFI_BAD_TYPEDEF; + else + return FFI_OK; +} + +int +ffi_prep_args (char *stack, extended_cif * ecif) +{ + unsigned int i; + unsigned int struct_count = 0; + void **p_argv; + char *argp; + ffi_type **p_arg; + + argp = stack; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); i--, p_arg++) + { + size_t z; + + switch ((*p_arg)->type) + { + case FFI_TYPE_STRUCT: + { + z = (*p_arg)->size; + if (z <= 4) + { + memcpy (argp, *p_argv, z); + z = 4; + } + else if (z <= 8) + { + memcpy (argp, *p_argv, z); + z = 8; + } + else + { + unsigned int uiLocOnStack; + z = sizeof (void *); + uiLocOnStack = 4 * ecif->cif->nargs + struct_count; + struct_count = struct_count + (*p_arg)->size; + *(unsigned int *) argp = + (unsigned int) (UINT32 *) (stack + uiLocOnStack); + memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size); + } + break; + } + default: + z = (*p_arg)->size; + if (z < sizeof (int)) + { + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = + (unsigned int) *(UINT8 *) (*p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = + (unsigned int) *(UINT16 *) (*p_argv); + break; + + default: + FFI_ASSERT (0); + } + z = sizeof (int); + } + else if (z == sizeof (int)) + *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv); + else + memcpy (argp, *p_argv, z); + break; + } + p_argv++; + argp += z; + } + + return (struct_count); +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_core (ffi_cif * cif, + ffi_abi abi, unsigned int isvariadic, + unsigned int nfixedargs, unsigned int ntotalargs, + ffi_type * rtype, ffi_type ** atypes) +{ + unsigned bytes = 0; + unsigned int i; + ffi_type **ptr; + + FFI_ASSERT (cif != NULL); + FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); + FFI_ASSERT(nfixedargs <= ntotalargs); + FFI_ASSERT (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI); + + cif->abi = abi; + cif->arg_types = atypes; + cif->nargs = ntotalargs; + cif->rtype = rtype; + + cif->flags = 0; + + if ((cif->rtype->size == 0) + && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + FFI_ASSERT_VALID_TYPE (cif->rtype); + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + if (((*ptr)->size == 0) + && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + FFI_ASSERT_VALID_TYPE (*ptr); + + if (((*ptr)->alignment - 1) & bytes) + bytes = ALIGN (bytes, (*ptr)->alignment); + if ((*ptr)->type == FFI_TYPE_STRUCT) + { + if ((*ptr)->size > 8) + { + bytes += (*ptr)->size; + bytes += sizeof (void *); + } + else + { + if ((*ptr)->size > 4) + bytes += 8; + else + bytes += 4; + } + } + else + bytes += STACK_ARG_SIZE ((*ptr)->size); + } + + cif->bytes = bytes; + + return ffi_prep_cif_machdep (cif); +} + +ffi_status +ffi_prep_cif_machdep (ffi_cif * cif) +{ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags = (unsigned) cif->rtype->type; + break; + + default: + cif->flags = FFI_TYPE_INT; + break; + } + + return FFI_OK; +} + +extern void ffi_call_SYSV (int (*)(char *, extended_cif *), + extended_cif *, + unsigned, unsigned, unsigned *, void (*fn) ()) + __attribute__ ((__visibility__ ("hidden"))); + +void +ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca (cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; + default: + FFI_ASSERT (0); + break; + } +} + +/* Because the following variables are not exported outside libffi, we + mark them hidden. */ + +/* Assembly code for the jump stub. */ +extern const char ffi_cris_trampoline_template[] + __attribute__ ((__visibility__ ("hidden"))); + +/* Offset into ffi_cris_trampoline_template of where to put the + ffi_prep_closure_inner function. */ +extern const int ffi_cris_trampoline_fn_offset + __attribute__ ((__visibility__ ("hidden"))); + +/* Offset into ffi_cris_trampoline_template of where to put the + closure data. */ +extern const int ffi_cris_trampoline_closure_offset + __attribute__ ((__visibility__ ("hidden"))); + +/* This function is sibling-called (jumped to) by the closure + trampoline. We get R10..R13 at PARAMS[0..3] and a copy of [SP] at + PARAMS[4] to simplify handling of a straddling parameter. A copy + of R9 is at PARAMS[5] and SP at PARAMS[6]. These parameters are + put at the appropriate place in CLOSURE which is then executed and + the return value is passed back to the caller. */ + +static unsigned long long +ffi_prep_closure_inner (void **params, ffi_closure* closure) +{ + char *register_args = (char *) params; + void *struct_ret = params[5]; + char *stack_args = params[6]; + char *ptr = register_args; + ffi_cif *cif = closure->cif; + ffi_type **arg_types = cif->arg_types; + + /* Max room needed is number of arguments as 64-bit values. */ + void **avalue = alloca (closure->cif->nargs * sizeof(void *)); + int i; + int doing_regs; + long long llret = 0; + + /* Find the address of each argument. */ + for (i = 0, doing_regs = 1; i < cif->nargs; i++) + { + /* Types up to and including 8 bytes go by-value. */ + if (arg_types[i]->size <= 4) + { + avalue[i] = ptr; + ptr += 4; + } + else if (arg_types[i]->size <= 8) + { + avalue[i] = ptr; + ptr += 8; + } + else + { + FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT); + + /* Passed by-reference, so copy the pointer. */ + avalue[i] = *(void **) ptr; + ptr += 4; + } + + /* If we've handled more arguments than fit in registers, start + looking at the those passed on the stack. Step over the + first one if we had a straddling parameter. */ + if (doing_regs && ptr >= register_args + 4*4) + { + ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0); + doing_regs = 0; + } + } + + /* Invoke the closure. */ + (closure->fun) (cif, + + cif->rtype->type == FFI_TYPE_STRUCT + /* The caller allocated space for the return + structure, and passed a pointer to this space in + R9. */ + ? struct_ret + + /* We take advantage of being able to ignore that + the high part isn't set if the return value is + not in R10:R11, but in R10 only. */ + : (void *) &llret, + + avalue, closure->user_data); + + return llret; +} + +/* API function: Prepare the trampoline. */ + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif *, void *, void **, void*), + void *user_data, + void *codeloc) +{ + void *innerfn = ffi_prep_closure_inner; + FFI_ASSERT (cif->abi == FFI_SYSV); + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + memcpy (closure->tramp, ffi_cris_trampoline_template, + FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE); + memcpy (closure->tramp + ffi_cris_trampoline_fn_offset, + &innerfn, sizeof (void *)); + memcpy (closure->tramp + ffi_cris_trampoline_closure_offset, + &codeloc, sizeof (void *)); + + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/cris/ffitarget.h b/circuitpython/lib/libffi/src/cris/ffitarget.h new file mode 100644 index 0000000..b837e97 --- /dev/null +++ b/circuitpython/lib/libffi/src/cris/ffitarget.h @@ -0,0 +1,56 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for CRIS. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36 +#define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4) +#define FFI_TRAMPOLINE_SIZE \ + (FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE) +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/cris/sysv.S b/circuitpython/lib/libffi/src/cris/sysv.S new file mode 100644 index 0000000..79abaee --- /dev/null +++ b/circuitpython/lib/libffi/src/cris/sysv.S @@ -0,0 +1,215 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2004 Simon Posnjak + Copyright (c) 2005 Axis Communications AB + + CRIS Foreign Function Interface + + 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 SIMON POSNJAK 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 LIBFFI_ASM +#include +#define CONCAT(x,y) x ## y +#define XCONCAT(x,y) CONCAT (x, y) +#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x) + + .text + + ;; OK, when we get called we should have this (according to + ;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3). + ;; + ;; R10: ffi_prep_args (func. pointer) + ;; R11: &ecif + ;; R12: cif->bytes + ;; R13: fig->flags + ;; sp+0: ecif.rvalue + ;; sp+4: fn (function pointer to the function that we need to call) + + .globl L(ffi_call_SYSV) + .type L(ffi_call_SYSV),@function + .hidden L(ffi_call_SYSV) + +L(ffi_call_SYSV): + ;; Save the regs to the stack. + push $srp + ;; Used for stack pointer saving. + push $r6 + ;; Used for function address pointer. + push $r7 + ;; Used for stack pointer saving. + push $r8 + ;; We save fig->flags to stack we will need them after we + ;; call The Function. + push $r13 + + ;; Saving current stack pointer. + move.d $sp,$r8 + move.d $sp,$r6 + + ;; Move address of ffi_prep_args to r13. + move.d $r10,$r13 + + ;; Make room on the stack for the args of fn. + sub.d $r12,$sp + + ;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are: + ;; r10 <-- stack pointer + ;; r11 <-- &ecif (already there) + move.d $sp,$r10 + + ;; Call the function. + jsr $r13 + + ;; Save the size of the structures which are passed on stack. + move.d $r10,$r7 + + ;; Move first four args in to r10..r13. + move.d [$sp+0],$r10 + move.d [$sp+4],$r11 + move.d [$sp+8],$r12 + move.d [$sp+12],$r13 + + ;; Adjust the stack and check if any parameters are given on stack. + addq 16,$sp + sub.d $r7,$r6 + cmp.d $sp,$r6 + + bpl go_on + nop + +go_on_no_params_on_stack: + move.d $r6,$sp + +go_on: + ;; Discover if we need to put rval address in to r9. + move.d [$r8+0],$r7 + cmpq FFI_TYPE_STRUCT,$r7 + bne call_now + nop + + ;; Move rval address to $r9. + move.d [$r8+20],$r9 + +call_now: + ;; Move address of The Function in to r7. + move.d [$r8+24],$r7 + + ;; Call The Function. + jsr $r7 + + ;; Reset stack. + move.d $r8,$sp + + ;; Load rval type (fig->flags) in to r13. + pop $r13 + + ;; Detect rval type. + cmpq FFI_TYPE_VOID,$r13 + beq epilogue + + cmpq FFI_TYPE_STRUCT,$r13 + beq epilogue + + cmpq FFI_TYPE_DOUBLE,$r13 + beq return_double_or_longlong + + cmpq FFI_TYPE_UINT64,$r13 + beq return_double_or_longlong + + cmpq FFI_TYPE_SINT64,$r13 + beq return_double_or_longlong + nop + + ;; Just return the 32 bit value. + ba return + nop + +return_double_or_longlong: + ;; Load half of the rval to r10 and the other half to r11. + move.d [$sp+16],$r13 + move.d $r10,[$r13] + addq 4,$r13 + move.d $r11,[$r13] + ba epilogue + nop + +return: + ;; Load the rval to r10. + move.d [$sp+16],$r13 + move.d $r10,[$r13] + +epilogue: + pop $r8 + pop $r7 + pop $r6 + Jump [$sp+] + + .size ffi_call_SYSV,.-ffi_call_SYSV + +/* Save R10..R13 into an array, somewhat like varargs. Copy the next + argument too, to simplify handling of any straddling parameter. + Save R9 and SP after those. Jump to function handling the rest. + Since this is a template, copied and the main function filled in by + the user. */ + + .globl L(ffi_cris_trampoline_template) + .type L(ffi_cris_trampoline_template),@function + .hidden L(ffi_cris_trampoline_template) + +L(ffi_cris_trampoline_template): +0: + /* The value we get for "PC" is right after the prefix instruction, + two bytes from the beginning, i.e. 0b+2. */ + move.d $r10,[$pc+2f-(0b+2)] + move.d $pc,$r10 +1: + addq 2f-1b+4,$r10 + move.d $r11,[$r10+] + move.d $r12,[$r10+] + move.d $r13,[$r10+] + move.d [$sp],$r11 + move.d $r11,[$r10+] + move.d $r9,[$r10+] + move.d $sp,[$r10+] + subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10 + move.d 0,$r11 +3: + jump 0 +2: + .size ffi_cris_trampoline_template,.-0b + +/* This macro create a constant usable as "extern const int \name" in + C from within libffi, when \name has no prefix decoration. */ + + .macro const name,value + .globl \name + .type \name,@object + .hidden \name +\name: + .dword \value + .size \name,4 + .endm + +/* Constants for offsets within the trampoline. We could do this with + just symbols, avoiding memory contents and memory accesses, but the + C usage code would look a bit stranger. */ + + const L(ffi_cris_trampoline_fn_offset),2b-4-0b + const L(ffi_cris_trampoline_closure_offset),3b-4-0b diff --git a/circuitpython/lib/libffi/src/debug.c b/circuitpython/lib/libffi/src/debug.c new file mode 100644 index 0000000..f3172b1 --- /dev/null +++ b/circuitpython/lib/libffi/src/debug.c @@ -0,0 +1,64 @@ +/* ----------------------------------------------------------------------- + debug.c - Copyright (c) 1996 Red Hat, Inc. + + 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 +#include +#include +#include + +/* General debugging routines */ + +void ffi_stop_here(void) +{ + /* This function is only useful for debugging purposes. + Place a breakpoint on ffi_stop_here to be notified of + significant events. */ +} + +/* This function should only be called via the FFI_ASSERT() macro */ + +void ffi_assert(char *expr, char *file, int line) +{ + fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line); + ffi_stop_here(); + abort(); +} + +/* Perform a sanity check on an ffi_type structure */ + +void ffi_type_test(ffi_type *a, char *file, int line) +{ + FFI_ASSERT_AT(a != NULL, file, line); + + FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line); + FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line); + FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line); + FFI_ASSERT_AT((a->type != FFI_TYPE_STRUCT && a->type != FFI_TYPE_COMPLEX) + || a->elements != NULL, file, line); + FFI_ASSERT_AT(a->type != FFI_TYPE_COMPLEX + || (a->elements != NULL + && a->elements[0] != NULL && a->elements[1] == NULL), + file, line); + +} diff --git a/circuitpython/lib/libffi/src/dlmalloc.c b/circuitpython/lib/libffi/src/dlmalloc.c new file mode 100644 index 0000000..7e4ea83 --- /dev/null +++ b/circuitpython/lib/libffi/src/dlmalloc.c @@ -0,0 +1,5161 @@ +/* + This is a version (aka dlmalloc) of malloc/free/realloc written by + Doug Lea and released to the public domain, as explained at + http://creativecommons.org/licenses/publicdomain. Send questions, + comments, complaints, performance data, etc to dl@cs.oswego.edu + +* Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) + + Note: There may be an updated version of this malloc obtainable at + ftp://gee.cs.oswego.edu/pub/misc/malloc.c + Check before installing! + +* Quickstart + + This library is all in one file to simplify the most common usage: + ftp it, compile it (-O3), and link it into another program. All of + the compile-time options default to reasonable values for use on + most platforms. You might later want to step through various + compile-time and dynamic tuning options. + + For convenience, an include file for code using this malloc is at: + ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h + You don't really need this .h file unless you call functions not + defined in your system include files. The .h file contains only the + excerpts from this file needed for using this malloc on ANSI C/C++ + systems, so long as you haven't changed compile-time options about + naming and tuning parameters. If you do, then you can create your + own malloc.h that does include all settings by cutting at the point + indicated below. Note that you may already by default be using a C + library containing a malloc that is based on some version of this + malloc (for example in linux). You might still want to use the one + in this file to customize settings or to avoid overheads associated + with library versions. + +* Vital statistics: + + Supported pointer/size_t representation: 4 or 8 bytes + size_t MUST be an unsigned type of the same width as + pointers. (If you are using an ancient system that declares + size_t as a signed type, or need it to be a different width + than pointers, you can use a previous release of this malloc + (e.g. 2.7.2) supporting these.) + + Alignment: 8 bytes (default) + This suffices for nearly all current machines and C compilers. + However, you can define MALLOC_ALIGNMENT to be wider than this + if necessary (up to 128bytes), at the expense of using more space. + + Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) + 8 or 16 bytes (if 8byte sizes) + Each malloced chunk has a hidden word of overhead holding size + and status information, and additional cross-check word + if FOOTERS is defined. + + Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) + 8-byte ptrs: 32 bytes (including overhead) + + Even a request for zero bytes (i.e., malloc(0)) returns a + pointer to something of the minimum allocatable size. + The maximum overhead wastage (i.e., number of extra bytes + allocated than were requested in malloc) is less than or equal + to the minimum size, except for requests >= mmap_threshold that + are serviced via mmap(), where the worst case wastage is about + 32 bytes plus the remainder from a system page (the minimal + mmap unit); typically 4096 or 8192 bytes. + + Security: static-safe; optionally more or less + The "security" of malloc refers to the ability of malicious + code to accentuate the effects of errors (for example, freeing + space that is not currently malloc'ed or overwriting past the + ends of chunks) in code that calls malloc. This malloc + guarantees not to modify any memory locations below the base of + heap, i.e., static variables, even in the presence of usage + errors. The routines additionally detect most improper frees + and reallocs. All this holds as long as the static bookkeeping + for malloc itself is not corrupted by some other means. This + is only one aspect of security -- these checks do not, and + cannot, detect all possible programming errors. + + If FOOTERS is defined nonzero, then each allocated chunk + carries an additional check word to verify that it was malloced + from its space. These check words are the same within each + execution of a program using malloc, but differ across + executions, so externally crafted fake chunks cannot be + freed. This improves security by rejecting frees/reallocs that + could corrupt heap memory, in addition to the checks preventing + writes to statics that are always on. This may further improve + security at the expense of time and space overhead. (Note that + FOOTERS may also be worth using with MSPACES.) + + By default detected errors cause the program to abort (calling + "abort()"). You can override this to instead proceed past + errors by defining PROCEED_ON_ERROR. In this case, a bad free + has no effect, and a malloc that encounters a bad address + caused by user overwrites will ignore the bad address by + dropping pointers and indices to all known memory. This may + be appropriate for programs that should continue if at all + possible in the face of programming errors, although they may + run out of memory because dropped memory is never reclaimed. + + If you don't like either of these options, you can define + CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything + else. And if if you are sure that your program using malloc has + no errors or vulnerabilities, you can define INSECURE to 1, + which might (or might not) provide a small performance improvement. + + Thread-safety: NOT thread-safe unless USE_LOCKS defined + When USE_LOCKS is defined, each public call to malloc, free, + etc is surrounded with either a pthread mutex or a win32 + spinlock (depending on WIN32). This is not especially fast, and + can be a major bottleneck. It is designed only to provide + minimal protection in concurrent environments, and to provide a + basis for extensions. If you are using malloc in a concurrent + program, consider instead using ptmalloc, which is derived from + a version of this malloc. (See http://www.malloc.de). + + System requirements: Any combination of MORECORE and/or MMAP/MUNMAP + This malloc can use unix sbrk or any emulation (invoked using + the CALL_MORECORE macro) and/or mmap/munmap or any emulation + (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system + memory. On most unix systems, it tends to work best if both + MORECORE and MMAP are enabled. On Win32, it uses emulations + based on VirtualAlloc. It also uses common C library functions + like memset. + + Compliance: I believe it is compliant with the Single Unix Specification + (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably + others as well. + +* Overview of algorithms + + This is not the fastest, most space-conserving, most portable, or + most tunable malloc ever written. However it is among the fastest + while also being among the most space-conserving, portable and + tunable. Consistent balance across these factors results in a good + general-purpose allocator for malloc-intensive programs. + + In most ways, this malloc is a best-fit allocator. Generally, it + chooses the best-fitting existing chunk for a request, with ties + broken in approximately least-recently-used order. (This strategy + normally maintains low fragmentation.) However, for requests less + than 256bytes, it deviates from best-fit when there is not an + exactly fitting available chunk by preferring to use space adjacent + to that used for the previous small request, as well as by breaking + ties in approximately most-recently-used order. (These enhance + locality of series of small allocations.) And for very large requests + (>= 256Kb by default), it relies on system memory mapping + facilities, if supported. (This helps avoid carrying around and + possibly fragmenting memory used only for large chunks.) + + All operations (except malloc_stats and mallinfo) have execution + times that are bounded by a constant factor of the number of bits in + a size_t, not counting any clearing in calloc or copying in realloc, + or actions surrounding MORECORE and MMAP that have times + proportional to the number of non-contiguous regions returned by + system allocation routines, which is often just 1. + + The implementation is not very modular and seriously overuses + macros. Perhaps someday all C compilers will do as good a job + inlining modular code as can now be done by brute-force expansion, + but now, enough of them seem not to. + + Some compilers issue a lot of warnings about code that is + dead/unreachable only on some platforms, and also about intentional + uses of negation on unsigned types. All known cases of each can be + ignored. + + For a longer but out of date high-level description, see + http://gee.cs.oswego.edu/dl/html/malloc.html + +* MSPACES + If MSPACES is defined, then in addition to malloc, free, etc., + this file also defines mspace_malloc, mspace_free, etc. These + are versions of malloc routines that take an "mspace" argument + obtained using create_mspace, to control all internal bookkeeping. + If ONLY_MSPACES is defined, only these versions are compiled. + So if you would like to use this allocator for only some allocations, + and your system malloc for others, you can compile with + ONLY_MSPACES and then do something like... + static mspace mymspace = create_mspace(0,0); // for example + #define mymalloc(bytes) mspace_malloc(mymspace, bytes) + + (Note: If you only need one instance of an mspace, you can instead + use "USE_DL_PREFIX" to relabel the global malloc.) + + You can similarly create thread-local allocators by storing + mspaces as thread-locals. For example: + static __thread mspace tlms = 0; + void* tlmalloc(size_t bytes) { + if (tlms == 0) tlms = create_mspace(0, 0); + return mspace_malloc(tlms, bytes); + } + void tlfree(void* mem) { mspace_free(tlms, mem); } + + Unless FOOTERS is defined, each mspace is completely independent. + You cannot allocate from one and free to another (although + conformance is only weakly checked, so usage errors are not always + caught). If FOOTERS is defined, then each chunk carries around a tag + indicating its originating mspace, and frees are directed to their + originating spaces. + + ------------------------- Compile-time options --------------------------- + +Be careful in setting #define values for numerical constants of type +size_t. On some systems, literal values are not automatically extended +to size_t precision unless they are explicitly casted. + +WIN32 default: defined if _WIN32 defined + Defining WIN32 sets up defaults for MS environment and compilers. + Otherwise defaults are for unix. + +MALLOC_ALIGNMENT default: (size_t)8 + Controls the minimum alignment for malloc'ed chunks. It must be a + power of two and at least 8, even on machines for which smaller + alignments would suffice. It may be defined as larger than this + though. Note however that code and data structures are optimized for + the case of 8-byte alignment. + +MSPACES default: 0 (false) + If true, compile in support for independent allocation spaces. + This is only supported if HAVE_MMAP is true. + +ONLY_MSPACES default: 0 (false) + If true, only compile in mspace versions, not regular versions. + +USE_LOCKS default: 0 (false) + Causes each call to each public routine to be surrounded with + pthread or WIN32 mutex lock/unlock. (If set true, this can be + overridden on a per-mspace basis for mspace versions.) + +FOOTERS default: 0 + If true, provide extra checking and dispatching by placing + information in the footers of allocated chunks. This adds + space and time overhead. + +INSECURE default: 0 + If true, omit checks for usage errors and heap space overwrites. + +USE_DL_PREFIX default: NOT defined + Causes compiler to prefix all public routines with the string 'dl'. + This can be useful when you only want to use this malloc in one part + of a program, using your regular system malloc elsewhere. + +ABORT default: defined as abort() + Defines how to abort on failed checks. On most systems, a failed + check cannot die with an "assert" or even print an informative + message, because the underlying print routines in turn call malloc, + which will fail again. Generally, the best policy is to simply call + abort(). It's not very useful to do more than this because many + errors due to overwriting will show up as address faults (null, odd + addresses etc) rather than malloc-triggered checks, so will also + abort. Also, most compilers know that abort() does not return, so + can better optimize code conditionally calling it. + +PROCEED_ON_ERROR default: defined as 0 (false) + Controls whether detected bad addresses cause them to bypassed + rather than aborting. If set, detected bad arguments to free and + realloc are ignored. And all bookkeeping information is zeroed out + upon a detected overwrite of freed heap space, thus losing the + ability to ever return it from malloc again, but enabling the + application to proceed. If PROCEED_ON_ERROR is defined, the + static variable malloc_corruption_error_count is compiled in + and can be examined to see if errors have occurred. This option + generates slower code than the default abort policy. + +DEBUG default: NOT defined + The DEBUG setting is mainly intended for people trying to modify + this code or diagnose problems when porting to new platforms. + However, it may also be able to better isolate user errors than just + using runtime checks. The assertions in the check routines spell + out in more detail the assumptions and invariants underlying the + algorithms. The checking is fairly extensive, and will slow down + execution noticeably. Calling malloc_stats or mallinfo with DEBUG + set will attempt to check every non-mmapped allocated and free chunk + in the course of computing the summaries. + +ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) + Debugging assertion failures can be nearly impossible if your + version of the assert macro causes malloc to be called, which will + lead to a cascade of further failures, blowing the runtime stack. + ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), + which will usually make debugging easier. + +MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 + The action to take before "return 0" when malloc fails to be able to + return memory because there is none available. + +HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES + True if this system supports sbrk or an emulation of it. + +MORECORE default: sbrk + The name of the sbrk-style system routine to call to obtain more + memory. See below for guidance on writing custom MORECORE + functions. The type of the argument to sbrk/MORECORE varies across + systems. It cannot be size_t, because it supports negative + arguments, so it is normally the signed type of the same width as + size_t (sometimes declared as "intptr_t"). It doesn't much matter + though. Internally, we only call it with arguments less than half + the max value of a size_t, which should work across all reasonable + possibilities, although sometimes generating compiler warnings. See + near the end of this file for guidelines for creating a custom + version of MORECORE. + +MORECORE_CONTIGUOUS default: 1 (true) + If true, take advantage of fact that consecutive calls to MORECORE + with positive arguments always return contiguous increasing + addresses. This is true of unix sbrk. It does not hurt too much to + set it true anyway, since malloc copes with non-contiguities. + Setting it false when definitely non-contiguous saves time + and possibly wasted space it would take to discover this though. + +MORECORE_CANNOT_TRIM default: NOT defined + True if MORECORE cannot release space back to the system when given + negative arguments. This is generally necessary only if you are + using a hand-crafted MORECORE function that cannot handle negative + arguments. + +HAVE_MMAP default: 1 (true) + True if this system supports mmap or an emulation of it. If so, and + HAVE_MORECORE is not true, MMAP is used for all system + allocation. If set and HAVE_MORECORE is true as well, MMAP is + primarily used to directly allocate very large blocks. It is also + used as a backup strategy in cases where MORECORE fails to provide + space from system. Note: A single call to MUNMAP is assumed to be + able to unmap memory that may have be allocated using multiple calls + to MMAP, so long as they are adjacent. + +HAVE_MREMAP default: 1 on linux, else 0 + If true realloc() uses mremap() to re-allocate large blocks and + extend or shrink allocation spaces. + +MMAP_CLEARS default: 1 on unix + True if mmap clears memory so calloc doesn't need to. This is true + for standard unix mmap using /dev/zero. + +USE_BUILTIN_FFS default: 0 (i.e., not used) + Causes malloc to use the builtin ffs() function to compute indices. + Some compilers may recognize and intrinsify ffs to be faster than the + supplied C version. Also, the case of x86 using gcc is special-cased + to an asm instruction, so is already as fast as it can be, and so + this setting has no effect. (On most x86s, the asm version is only + slightly faster than the C version.) + +malloc_getpagesize default: derive from system includes, or 4096. + The system page size. To the extent possible, this malloc manages + memory from the system in page-size units. This may be (and + usually is) a function rather than a constant. This is ignored + if WIN32, where page size is determined using getSystemInfo during + initialization. + +USE_DEV_RANDOM default: 0 (i.e., not used) + Causes malloc to use /dev/random to initialize secure magic seed for + stamping footers. Otherwise, the current time is used. + +NO_MALLINFO default: 0 + If defined, don't compile "mallinfo". This can be a simple way + of dealing with mismatches between system declarations and + those in this file. + +MALLINFO_FIELD_TYPE default: size_t + The type of the fields in the mallinfo struct. This was originally + defined as "int" in SVID etc, but is more usefully defined as + size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set + +REALLOC_ZERO_BYTES_FREES default: not defined + This should be set if a call to realloc with zero bytes should + be the same as a call to free. Some people think it should. Otherwise, + since this malloc returns a unique pointer for malloc(0), so does + realloc(p, 0). + +LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H +LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H +LACKS_STDLIB_H default: NOT defined unless on WIN32 + Define these if your system does not have these header files. + You might need to manually insert some of the declarations they provide. + +DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, + system_info.dwAllocationGranularity in WIN32, + otherwise 64K. + Also settable using mallopt(M_GRANULARITY, x) + The unit for allocating and deallocating memory from the system. On + most systems with contiguous MORECORE, there is no reason to + make this more than a page. However, systems with MMAP tend to + either require or encourage larger granularities. You can increase + this value to prevent system allocation functions to be called so + often, especially if they are slow. The value must be at least one + page and must be a power of two. Setting to 0 causes initialization + to either page size or win32 region size. (Note: In previous + versions of malloc, the equivalent of this option was called + "TOP_PAD") + +DEFAULT_TRIM_THRESHOLD default: 2MB + Also settable using mallopt(M_TRIM_THRESHOLD, x) + The maximum amount of unused top-most memory to keep before + releasing via malloc_trim in free(). Automatic trimming is mainly + useful in long-lived programs using contiguous MORECORE. Because + trimming via sbrk can be slow on some systems, and can sometimes be + wasteful (in cases where programs immediately afterward allocate + more large chunks) the value should be high enough so that your + overall system performance would improve by releasing this much + memory. As a rough guide, you might set to a value close to the + average size of a process (program) running on your system. + Releasing this much memory would allow such a process to run in + memory. Generally, it is worth tuning trim thresholds when a + program undergoes phases where several large chunks are allocated + and released in ways that can reuse each other's storage, perhaps + mixed with phases where there are no such chunks at all. The trim + value must be greater than page size to have any useful effect. To + disable trimming completely, you can set to MAX_SIZE_T. Note that the trick + some people use of mallocing a huge space and then freeing it at + program startup, in an attempt to reserve system memory, doesn't + have the intended effect under automatic trimming, since that memory + will immediately be returned to the system. + +DEFAULT_MMAP_THRESHOLD default: 256K + Also settable using mallopt(M_MMAP_THRESHOLD, x) + The request size threshold for using MMAP to directly service a + request. Requests of at least this size that cannot be allocated + using already-existing space will be serviced via mmap. (If enough + normal freed space already exists it is used instead.) Using mmap + segregates relatively large chunks of memory so that they can be + individually obtained and released from the host system. A request + serviced through mmap is never reused by any other request (at least + not directly; the system may just so happen to remap successive + requests to the same locations). Segregating space in this way has + the benefits that: Mmapped space can always be individually released + back to the system, which helps keep the system level memory demands + of a long-lived program low. Also, mapped memory doesn't become + `locked' between other chunks, as can happen with normally allocated + chunks, which means that even trimming via malloc_trim would not + release them. However, it has the disadvantage that the space + cannot be reclaimed, consolidated, and then used to service later + requests, as happens with normal chunks. The advantages of mmap + nearly always outweigh disadvantages for "large" chunks, but the + value of "large" may vary across systems. The default is an + empirically derived value that works well in most systems. You can + disable mmap by setting to MAX_SIZE_T. + +*/ + +#ifndef WIN32 +#ifdef _WIN32 +#define WIN32 1 +#endif /* _WIN32 */ +#endif /* WIN32 */ +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#define HAVE_MMAP 1 +#define HAVE_MORECORE 0 +#define LACKS_UNISTD_H +#define LACKS_SYS_PARAM_H +#define LACKS_SYS_MMAN_H +#define LACKS_STRING_H +#define LACKS_STRINGS_H +#define LACKS_SYS_TYPES_H +#define LACKS_ERRNO_H +#define MALLOC_FAILURE_ACTION +#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */ +#endif /* WIN32 */ + +#ifdef __OS2__ +#define INCL_DOS +#include +#define HAVE_MMAP 1 +#define HAVE_MORECORE 0 +#define LACKS_SYS_MMAN_H +#endif /* __OS2__ */ + +#if defined(DARWIN) || defined(_DARWIN) +/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ +#ifndef HAVE_MORECORE +#define HAVE_MORECORE 0 +#define HAVE_MMAP 1 +#endif /* HAVE_MORECORE */ +#endif /* DARWIN */ + +#ifndef LACKS_SYS_TYPES_H +#include /* For size_t */ +#endif /* LACKS_SYS_TYPES_H */ + +/* The maximum possible size_t value has all bits set */ +#define MAX_SIZE_T (~(size_t)0) + +#ifndef ONLY_MSPACES +#define ONLY_MSPACES 0 +#endif /* ONLY_MSPACES */ +#ifndef MSPACES +#if ONLY_MSPACES +#define MSPACES 1 +#else /* ONLY_MSPACES */ +#define MSPACES 0 +#endif /* ONLY_MSPACES */ +#endif /* MSPACES */ +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT ((size_t)8U) +#endif /* MALLOC_ALIGNMENT */ +#ifndef FOOTERS +#define FOOTERS 0 +#endif /* FOOTERS */ +#ifndef ABORT +#define ABORT abort() +#endif /* ABORT */ +#ifndef ABORT_ON_ASSERT_FAILURE +#define ABORT_ON_ASSERT_FAILURE 1 +#endif /* ABORT_ON_ASSERT_FAILURE */ +#ifndef PROCEED_ON_ERROR +#define PROCEED_ON_ERROR 0 +#endif /* PROCEED_ON_ERROR */ +#ifndef USE_LOCKS +#define USE_LOCKS 0 +#endif /* USE_LOCKS */ +#ifndef INSECURE +#define INSECURE 0 +#endif /* INSECURE */ +#ifndef HAVE_MMAP +#define HAVE_MMAP 1 +#endif /* HAVE_MMAP */ +#ifndef MMAP_CLEARS +#define MMAP_CLEARS 1 +#endif /* MMAP_CLEARS */ +#ifndef HAVE_MREMAP +#ifdef linux +#define HAVE_MREMAP 1 +#else /* linux */ +#define HAVE_MREMAP 0 +#endif /* linux */ +#endif /* HAVE_MREMAP */ +#ifndef MALLOC_FAILURE_ACTION +#define MALLOC_FAILURE_ACTION errno = ENOMEM; +#endif /* MALLOC_FAILURE_ACTION */ +#ifndef HAVE_MORECORE +#if ONLY_MSPACES +#define HAVE_MORECORE 0 +#else /* ONLY_MSPACES */ +#define HAVE_MORECORE 1 +#endif /* ONLY_MSPACES */ +#endif /* HAVE_MORECORE */ +#if !HAVE_MORECORE +#define MORECORE_CONTIGUOUS 0 +#else /* !HAVE_MORECORE */ +#ifndef MORECORE +#define MORECORE sbrk +#endif /* MORECORE */ +#ifndef MORECORE_CONTIGUOUS +#define MORECORE_CONTIGUOUS 1 +#endif /* MORECORE_CONTIGUOUS */ +#endif /* HAVE_MORECORE */ +#ifndef DEFAULT_GRANULARITY +#if MORECORE_CONTIGUOUS +#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ +#else /* MORECORE_CONTIGUOUS */ +#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) +#endif /* MORECORE_CONTIGUOUS */ +#endif /* DEFAULT_GRANULARITY */ +#ifndef DEFAULT_TRIM_THRESHOLD +#ifndef MORECORE_CANNOT_TRIM +#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) +#else /* MORECORE_CANNOT_TRIM */ +#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T +#endif /* MORECORE_CANNOT_TRIM */ +#endif /* DEFAULT_TRIM_THRESHOLD */ +#ifndef DEFAULT_MMAP_THRESHOLD +#if HAVE_MMAP +#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) +#else /* HAVE_MMAP */ +#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T +#endif /* HAVE_MMAP */ +#endif /* DEFAULT_MMAP_THRESHOLD */ +#ifndef USE_BUILTIN_FFS +#define USE_BUILTIN_FFS 0 +#endif /* USE_BUILTIN_FFS */ +#ifndef USE_DEV_RANDOM +#define USE_DEV_RANDOM 0 +#endif /* USE_DEV_RANDOM */ +#ifndef NO_MALLINFO +#define NO_MALLINFO 0 +#endif /* NO_MALLINFO */ +#ifndef MALLINFO_FIELD_TYPE +#define MALLINFO_FIELD_TYPE size_t +#endif /* MALLINFO_FIELD_TYPE */ + +/* + mallopt tuning options. SVID/XPG defines four standard parameter + numbers for mallopt, normally defined in malloc.h. None of these + are used in this malloc, so setting them has no effect. But this + malloc does support the following options. +*/ + +#define M_TRIM_THRESHOLD (-1) +#define M_GRANULARITY (-2) +#define M_MMAP_THRESHOLD (-3) + +/* ------------------------ Mallinfo declarations ------------------------ */ + +#if !NO_MALLINFO +/* + This version of malloc supports the standard SVID/XPG mallinfo + routine that returns a struct containing usage properties and + statistics. It should work on any system that has a + /usr/include/malloc.h defining struct mallinfo. The main + declaration needed is the mallinfo struct that is returned (by-copy) + by mallinfo(). The malloinfo struct contains a bunch of fields that + are not even meaningful in this version of malloc. These fields are + are instead filled by mallinfo() with other numbers that might be of + interest. + + HAVE_USR_INCLUDE_MALLOC_H should be set if you have a + /usr/include/malloc.h file that includes a declaration of struct + mallinfo. If so, it is included; else a compliant version is + declared below. These must be precisely the same for mallinfo() to + work. The original SVID version of this struct, defined on most + systems with mallinfo, declares all fields as ints. But some others + define as unsigned long. If your system defines the fields using a + type of different width than listed here, you MUST #include your + system version and #define HAVE_USR_INCLUDE_MALLOC_H. +*/ + +/* #define HAVE_USR_INCLUDE_MALLOC_H */ + +#ifdef HAVE_USR_INCLUDE_MALLOC_H +#include "/usr/include/malloc.h" +#else /* HAVE_USR_INCLUDE_MALLOC_H */ + +/* HP-UX's stdlib.h redefines mallinfo unless _STRUCT_MALLINFO is defined */ +#define _STRUCT_MALLINFO + +struct mallinfo { + MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ + MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ + MALLINFO_FIELD_TYPE smblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ + MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ + MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ + MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ + MALLINFO_FIELD_TYPE fordblks; /* total free space */ + MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ +}; + +#endif /* HAVE_USR_INCLUDE_MALLOC_H */ +#endif /* NO_MALLINFO */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if !ONLY_MSPACES + +/* ------------------- Declarations of public routines ------------------- */ + +#ifndef USE_DL_PREFIX +#define dlcalloc calloc +#define dlfree free +#define dlmalloc malloc +#define dlmemalign memalign +#define dlrealloc realloc +#define dlvalloc valloc +#define dlpvalloc pvalloc +#define dlmallinfo mallinfo +#define dlmallopt mallopt +#define dlmalloc_trim malloc_trim +#define dlmalloc_stats malloc_stats +#define dlmalloc_usable_size malloc_usable_size +#define dlmalloc_footprint malloc_footprint +#define dlmalloc_max_footprint malloc_max_footprint +#define dlindependent_calloc independent_calloc +#define dlindependent_comalloc independent_comalloc +#endif /* USE_DL_PREFIX */ + + +/* + malloc(size_t n) + Returns a pointer to a newly allocated chunk of at least n bytes, or + null if no space is available, in which case errno is set to ENOMEM + on ANSI C systems. + + If n is zero, malloc returns a minimum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 32 bytes on 64bit + systems.) Note that size_t is an unsigned type, so calls with + arguments that would be negative if signed are interpreted as + requests for huge amounts of space, which will often fail. The + maximum supported value of n differs across systems, but is in all + cases less than the maximum representable value of a size_t. +*/ +void* dlmalloc(size_t); + +/* + free(void* p) + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. If p was not malloced or already + freed, free(p) will by default cause the current program to abort. +*/ +void dlfree(void*); + +/* + calloc(size_t n_elements, size_t element_size); + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +void* dlcalloc(size_t, size_t); + +/* + realloc(void* p, size_t n) + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p in most cases when possible, otherwise it + employs the equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + if n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. realloc with a size + argument of zero (re)allocates a minimum-sized chunk. + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ + +void* dlrealloc(void*, size_t); + +/* + memalign(size_t alignment, size_t n); + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +void* dlmemalign(size_t, size_t); + +/* + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +void* dlvalloc(size_t); + +/* + mallopt(int parameter_number, int parameter_value) + Sets tunable parameters The format is to provide a + (parameter-number, parameter-value) pair. mallopt then sets the + corresponding parameter to the argument value if it can (i.e., so + long as the value is meaningful), and returns 1 if successful else + 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, + normally defined in malloc.h. None of these are use in this malloc, + so setting them has no effect. But this malloc also supports other + options in mallopt. See below for details. Briefly, supported + parameters are as follows (listed defaults are for "typical" + configurations). + + Symbol param # default allowed param values + M_TRIM_THRESHOLD -1 2*1024*1024 any (MAX_SIZE_T disables) + M_GRANULARITY -2 page size any power of 2 >= page size + M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) +*/ +int dlmallopt(int, int); + +/* + malloc_footprint(); + Returns the number of bytes obtained from the system. The total + number of bytes allocated by malloc, realloc etc., is less than this + value. Unlike mallinfo, this function returns only a precomputed + result, so can be called frequently to monitor memory consumption. + Even if locks are otherwise defined, this function does not use them, + so results might not be up to date. +*/ +size_t dlmalloc_footprint(void); + +/* + malloc_max_footprint(); + Returns the maximum number of bytes obtained from the system. This + value will be greater than current footprint if deallocated space + has been reclaimed by the system. The peak number of bytes allocated + by malloc, realloc etc., is less than this value. Unlike mallinfo, + this function returns only a precomputed result, so can be called + frequently to monitor memory consumption. Even if locks are + otherwise defined, this function does not use them, so results might + not be up to date. +*/ +size_t dlmalloc_max_footprint(void); + +#if !NO_MALLINFO +/* + mallinfo() + Returns (by copy) a struct containing various summary statistics: + + arena: current total non-mmapped bytes allocated from system + ordblks: the number of free chunks + smblks: always zero. + hblks: current number of mmapped regions + hblkhd: total bytes held in mmapped regions + usmblks: the maximum total allocated space. This will be greater + than current total if trimming has occurred. + fsmblks: always zero + uordblks: current total allocated space (normal or mmapped) + fordblks: total free space + keepcost: the maximum number of bytes that could ideally be released + back to system via malloc_trim. ("ideally" means that + it ignores page restrictions etc.) + + Because these fields are ints, but internal bookkeeping may + be kept as longs, the reported values may wrap around zero and + thus be inaccurate. +*/ +struct mallinfo dlmallinfo(void); +#endif /* NO_MALLINFO */ + +/* + independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); + + independent_calloc is similar to calloc, but instead of returning a + single cleared space, it returns an array of pointers to n_elements + independent elements that can hold contents of size elem_size, each + of which starts out cleared, and can be independently freed, + realloc'ed etc. The elements are guaranteed to be adjacently + allocated (this is not guaranteed to occur with multiple callocs or + mallocs), which may also improve cache locality in some + applications. + + The "chunks" argument is optional (i.e., may be null, which is + probably the most typical usage). If it is null, the returned array + is itself dynamically allocated and should also be freed when it is + no longer needed. Otherwise, the chunks array must be of at least + n_elements in length. It is filled in with the pointers to the + chunks. + + In either case, independent_calloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and "chunks" + is null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be individually freed when it is no longer + needed. If you'd like to instead be able to free all at once, you + should instead use regular calloc and assign pointers into this + space to represent elements. (In this case though, you cannot + independently free elements.) + + independent_calloc simplifies and speeds up implementations of many + kinds of pools. It may also be useful when constructing large data + structures that initially have a fixed number of fixed-sized nodes, + but the number is not known at compile time, and some of the nodes + may later need to be freed. For example: + + struct Node { int item; struct Node* next; }; + + struct Node* build_list() { + struct Node** pool; + int n = read_number_of_nodes_needed(); + if (n <= 0) return 0; + pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + if (pool == 0) die(); + // organize into a linked list... + struct Node* first = pool[0]; + for (i = 0; i < n-1; ++i) + pool[i]->next = pool[i+1]; + free(pool); // Can now free the array (or not, if it is needed later) + return first; + } +*/ +void** dlindependent_calloc(size_t, size_t, void**); + +/* + independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); + + independent_comalloc allocates, all at once, a set of n_elements + chunks with sizes indicated in the "sizes" array. It returns + an array of pointers to these elements, each of which can be + independently freed, realloc'ed etc. The elements are guaranteed to + be adjacently allocated (this is not guaranteed to occur with + multiple callocs or mallocs), which may also improve cache locality + in some applications. + + The "chunks" argument is optional (i.e., may be null). If it is null + the returned array is itself dynamically allocated and should also + be freed when it is no longer needed. Otherwise, the chunks array + must be of at least n_elements in length. It is filled in with the + pointers to the chunks. + + In either case, independent_comalloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and chunks is + null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be individually freed when it is no longer + needed. If you'd like to instead be able to free all at once, you + should instead use a single regular malloc, and assign pointers at + particular offsets in the aggregate space. (In this case though, you + cannot independently free elements.) + + independent_comallac differs from independent_calloc in that each + element may have a different size, and also that it does not + automatically clear elements. + + independent_comalloc can be used to speed up allocation in cases + where several structs or objects must always be allocated at the + same time. For example: + + struct Head { ... } + struct Foot { ... } + + void send_message(char* msg) { + int msglen = strlen(msg); + size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + void* chunks[3]; + if (independent_comalloc(3, sizes, chunks) == 0) + die(); + struct Head* head = (struct Head*)(chunks[0]); + char* body = (char*)(chunks[1]); + struct Foot* foot = (struct Foot*)(chunks[2]); + // ... + } + + In general though, independent_comalloc is worth using only for + larger values of n_elements. For small values, you probably won't + detect enough difference from series of malloc calls to bother. + + Overuse of independent_comalloc can increase overall memory usage, + since it cannot reuse existing noncontiguous small chunks that + might be available for some of the elements. +*/ +void** dlindependent_comalloc(size_t, size_t*, void**); + + +/* + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +void* dlpvalloc(size_t); + +/* + malloc_trim(size_t pad); + + If possible, gives memory back to the system (via negative arguments + to sbrk) if there is unused memory at the `high' end of the malloc + pool or in unused MMAP segments. You can call this after freeing + large blocks of memory to potentially reduce the system-level memory + requirements of a program. However, it cannot guarantee to reduce + memory. Under some allocation patterns, some large free blocks of + memory will be locked between two used chunks, so they cannot be + given back to the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, only + the minimum amount of memory to maintain internal data structures + will be left. Non-zero arguments can be supplied to maintain enough + trailing space to service future expected allocations without having + to re-obtain memory from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. +*/ +int dlmalloc_trim(size_t); + +/* + malloc_usable_size(void* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); +*/ +size_t dlmalloc_usable_size(void*); + +/* + malloc_stats(); + Prints on stderr the amount of space obtained from the system (both + via sbrk and mmap), the maximum amount (which may be more than + current if malloc_trim and/or munmap got called), and the current + number of bytes allocated via malloc (or realloc, etc) but not yet + freed. Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead. Because it includes + alignment wastage as being in use, this figure may be greater than + zero even when no user-level chunks are allocated. + + The reported current and maximum system memory can be inaccurate if + a program makes other calls to system memory allocation functions + (normally sbrk) outside of malloc. + + malloc_stats prints only the most commonly interesting statistics. + More information can be obtained by calling mallinfo. +*/ +void dlmalloc_stats(void); + +#endif /* ONLY_MSPACES */ + +#if MSPACES + +/* + mspace is an opaque type representing an independent + region of space that supports mspace_malloc, etc. +*/ +typedef void* mspace; + +/* + create_mspace creates and returns a new independent space with the + given initial capacity, or, if 0, the default granularity size. It + returns null if there is no system memory available to create the + space. If argument locked is non-zero, the space uses a separate + lock to control access. The capacity of the space will grow + dynamically as needed to service mspace_malloc requests. You can + control the sizes of incremental increases of this space by + compiling with a different DEFAULT_GRANULARITY or dynamically + setting with mallopt(M_GRANULARITY, value). +*/ +mspace create_mspace(size_t capacity, int locked); + +/* + destroy_mspace destroys the given space, and attempts to return all + of its memory back to the system, returning the total number of + bytes freed. After destruction, the results of access to all memory + used by the space become undefined. +*/ +size_t destroy_mspace(mspace msp); + +/* + create_mspace_with_base uses the memory supplied as the initial base + of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this + space is used for bookkeeping, so the capacity must be at least this + large. (Otherwise 0 is returned.) When this initial space is + exhausted, additional memory will be obtained from the system. + Destroying this space will deallocate all additionally allocated + space (if possible) but not the initial base. +*/ +mspace create_mspace_with_base(void* base, size_t capacity, int locked); + +/* + mspace_malloc behaves as malloc, but operates within + the given space. +*/ +void* mspace_malloc(mspace msp, size_t bytes); + +/* + mspace_free behaves as free, but operates within + the given space. + + If compiled with FOOTERS==1, mspace_free is not actually needed. + free may be called instead of mspace_free because freed chunks from + any space are handled by their originating spaces. +*/ +void mspace_free(mspace msp, void* mem); + +/* + mspace_realloc behaves as realloc, but operates within + the given space. + + If compiled with FOOTERS==1, mspace_realloc is not actually + needed. realloc may be called instead of mspace_realloc because + realloced chunks from any space are handled by their originating + spaces. +*/ +void* mspace_realloc(mspace msp, void* mem, size_t newsize); + +/* + mspace_calloc behaves as calloc, but operates within + the given space. +*/ +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); + +/* + mspace_memalign behaves as memalign, but operates within + the given space. +*/ +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); + +/* + mspace_independent_calloc behaves as independent_calloc, but + operates within the given space. +*/ +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]); + +/* + mspace_independent_comalloc behaves as independent_comalloc, but + operates within the given space. +*/ +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]); + +/* + mspace_footprint() returns the number of bytes obtained from the + system for this space. +*/ +size_t mspace_footprint(mspace msp); + +/* + mspace_max_footprint() returns the peak number of bytes obtained from the + system for this space. +*/ +size_t mspace_max_footprint(mspace msp); + + +#if !NO_MALLINFO +/* + mspace_mallinfo behaves as mallinfo, but reports properties of + the given space. +*/ +struct mallinfo mspace_mallinfo(mspace msp); +#endif /* NO_MALLINFO */ + +/* + mspace_malloc_stats behaves as malloc_stats, but reports + properties of the given space. +*/ +void mspace_malloc_stats(mspace msp); + +/* + mspace_trim behaves as malloc_trim, but + operates within the given space. +*/ +int mspace_trim(mspace msp, size_t pad); + +/* + An alias for mallopt. +*/ +int mspace_mallopt(int, int); + +#endif /* MSPACES */ + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif /* __cplusplus */ + +/* + ======================================================================== + To make a fully customizable malloc.h header file, cut everything + above this line, put into file malloc.h, edit to suit, and #include it + on the next line, as well as in programs that use this malloc. + ======================================================================== +*/ + +/* #include "malloc.h" */ + +/*------------------------------ internal #includes ---------------------- */ + +#ifdef _MSC_VER +#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ +#endif /* _MSC_VER */ + +#include /* for printing in malloc_stats */ + +#ifndef LACKS_ERRNO_H +#include /* for MALLOC_FAILURE_ACTION */ +#endif /* LACKS_ERRNO_H */ +#if FOOTERS +#include /* for magic initialization */ +#endif /* FOOTERS */ +#ifndef LACKS_STDLIB_H +#include /* for abort() */ +#endif /* LACKS_STDLIB_H */ +#ifdef DEBUG +#if ABORT_ON_ASSERT_FAILURE +#define assert(x) if(!(x)) ABORT +#else /* ABORT_ON_ASSERT_FAILURE */ +#include +#endif /* ABORT_ON_ASSERT_FAILURE */ +#else /* DEBUG */ +#define assert(x) +#endif /* DEBUG */ +#ifndef LACKS_STRING_H +#include /* for memset etc */ +#endif /* LACKS_STRING_H */ +#if USE_BUILTIN_FFS +#ifndef LACKS_STRINGS_H +#include /* for ffs */ +#endif /* LACKS_STRINGS_H */ +#endif /* USE_BUILTIN_FFS */ +#if HAVE_MMAP +#ifndef LACKS_SYS_MMAN_H +#include /* for mmap */ +#endif /* LACKS_SYS_MMAN_H */ +#ifndef LACKS_FCNTL_H +#include +#endif /* LACKS_FCNTL_H */ +#endif /* HAVE_MMAP */ +#if HAVE_MORECORE +#ifndef LACKS_UNISTD_H +#include /* for sbrk */ +#else /* LACKS_UNISTD_H */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +extern void* sbrk(ptrdiff_t); +#endif /* FreeBSD etc */ +#endif /* LACKS_UNISTD_H */ +#endif /* HAVE_MMAP */ + +#ifndef WIN32 +#ifndef malloc_getpagesize +# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ +# ifndef _SC_PAGE_SIZE +# define _SC_PAGE_SIZE _SC_PAGESIZE +# endif +# endif +# ifdef _SC_PAGE_SIZE +# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) +# else +# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) + extern size_t getpagesize(); +# define malloc_getpagesize getpagesize() +# else +# ifdef WIN32 /* use supplied emulation of getpagesize */ +# define malloc_getpagesize getpagesize() +# else +# ifndef LACKS_SYS_PARAM_H +# include +# endif +# ifdef EXEC_PAGESIZE +# define malloc_getpagesize EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define malloc_getpagesize NBPG +# else +# define malloc_getpagesize (NBPG * CLSIZE) +# endif +# else +# ifdef NBPC +# define malloc_getpagesize NBPC +# else +# ifdef PAGESIZE +# define malloc_getpagesize PAGESIZE +# else /* just guess */ +# define malloc_getpagesize ((size_t)4096U) +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif +#endif + +/* ------------------- size_t and alignment properties -------------------- */ + +/* The byte and bit size of a size_t */ +#define SIZE_T_SIZE (sizeof(size_t)) +#define SIZE_T_BITSIZE (sizeof(size_t) << 3) + +/* Some constants coerced to size_t */ +/* Annoying but necessary to avoid errors on some platforms */ +#define SIZE_T_ZERO ((size_t)0) +#define SIZE_T_ONE ((size_t)1) +#define SIZE_T_TWO ((size_t)2) +#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) +#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) +#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) +#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) + +/* The bit mask value corresponding to MALLOC_ALIGNMENT */ +#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) + +/* True if address a has acceptable alignment */ +#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) + +/* the number of bytes to offset an address to align it */ +#define align_offset(A)\ + ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ + ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) + +/* -------------------------- MMAP preliminaries ------------------------- */ + +/* + If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and + checks to fail so compiler optimizer can delete code rather than + using so many "#if"s. +*/ + + +/* MORECORE and MMAP must return MFAIL on failure */ +#define MFAIL ((void*)(MAX_SIZE_T)) +#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ + +#if !HAVE_MMAP +#define IS_MMAPPED_BIT (SIZE_T_ZERO) +#define USE_MMAP_BIT (SIZE_T_ZERO) +#define CALL_MMAP(s) MFAIL +#define CALL_MUNMAP(a, s) (-1) +#define DIRECT_MMAP(s) MFAIL + +#else /* HAVE_MMAP */ +#define IS_MMAPPED_BIT (SIZE_T_ONE) +#define USE_MMAP_BIT (SIZE_T_ONE) + +#if !defined(WIN32) && !defined (__OS2__) +#define CALL_MUNMAP(a, s) munmap((a), (s)) +#define MMAP_PROT (PROT_READ|PROT_WRITE) +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +#define MAP_ANONYMOUS MAP_ANON +#endif /* MAP_ANON */ +#ifdef MAP_ANONYMOUS +#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) +#define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) +#else /* MAP_ANONYMOUS */ +/* + Nearly all versions of mmap support MAP_ANONYMOUS, so the following + is unlikely to be needed, but is supplied just in case. +*/ +#define MMAP_FLAGS (MAP_PRIVATE) +static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ +#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \ + (dev_zero_fd = open("/dev/zero", O_RDWR), \ + mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ + mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) +#endif /* MAP_ANONYMOUS */ + +#define DIRECT_MMAP(s) CALL_MMAP(s) + +#elif defined(__OS2__) + +/* OS/2 MMAP via DosAllocMem */ +static void* os2mmap(size_t size) { + void* ptr; + if (DosAllocMem(&ptr, size, OBJ_ANY|PAG_COMMIT|PAG_READ|PAG_WRITE) && + DosAllocMem(&ptr, size, PAG_COMMIT|PAG_READ|PAG_WRITE)) + return MFAIL; + return ptr; +} + +#define os2direct_mmap(n) os2mmap(n) + +/* This function supports releasing coalesed segments */ +static int os2munmap(void* ptr, size_t size) { + while (size) { + ULONG ulSize = size; + ULONG ulFlags = 0; + if (DosQueryMem(ptr, &ulSize, &ulFlags) != 0) + return -1; + if ((ulFlags & PAG_BASE) == 0 ||(ulFlags & PAG_COMMIT) == 0 || + ulSize > size) + return -1; + if (DosFreeMem(ptr) != 0) + return -1; + ptr = ( void * ) ( ( char * ) ptr + ulSize ); + size -= ulSize; + } + return 0; +} + +#define CALL_MMAP(s) os2mmap(s) +#define CALL_MUNMAP(a, s) os2munmap((a), (s)) +#define DIRECT_MMAP(s) os2direct_mmap(s) + +#else /* WIN32 */ + +/* Win32 MMAP via VirtualAlloc */ +static void* win32mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); + return (ptr != 0)? ptr: MFAIL; +} + +/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ +static void* win32direct_mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, + PAGE_EXECUTE_READWRITE); + return (ptr != 0)? ptr: MFAIL; +} + +/* This function supports releasing coalesed segments */ +static int win32munmap(void* ptr, size_t size) { + MEMORY_BASIC_INFORMATION minfo; + char* cptr = ptr; + while (size) { + if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) + return -1; + if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || + minfo.State != MEM_COMMIT || minfo.RegionSize > size) + return -1; + if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) + return -1; + cptr += minfo.RegionSize; + size -= minfo.RegionSize; + } + return 0; +} + +#define CALL_MMAP(s) win32mmap(s) +#define CALL_MUNMAP(a, s) win32munmap((a), (s)) +#define DIRECT_MMAP(s) win32direct_mmap(s) +#endif /* WIN32 */ +#endif /* HAVE_MMAP */ + +#if HAVE_MMAP && HAVE_MREMAP +#define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) +#else /* HAVE_MMAP && HAVE_MREMAP */ +#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL +#endif /* HAVE_MMAP && HAVE_MREMAP */ + +#if HAVE_MORECORE +#define CALL_MORECORE(S) MORECORE(S) +#else /* HAVE_MORECORE */ +#define CALL_MORECORE(S) MFAIL +#endif /* HAVE_MORECORE */ + +/* mstate bit set if contiguous morecore disabled or failed */ +#define USE_NONCONTIGUOUS_BIT (4U) + +/* segment bit set in create_mspace_with_base */ +#define EXTERN_BIT (8U) + + +/* --------------------------- Lock preliminaries ------------------------ */ + +#if USE_LOCKS + +/* + When locks are defined, there are up to two global locks: + + * If HAVE_MORECORE, morecore_mutex protects sequences of calls to + MORECORE. In many cases sys_alloc requires two calls, that should + not be interleaved with calls by other threads. This does not + protect against direct calls to MORECORE by other threads not + using this lock, so there is still code to cope the best we can on + interference. + + * magic_init_mutex ensures that mparams.magic and other + unique mparams values are initialized only once. +*/ + +#if !defined(WIN32) && !defined(__OS2__) +/* By default use posix locks */ +#include +#define MLOCK_T pthread_mutex_t +#define INITIAL_LOCK(l) pthread_mutex_init(l, NULL) +#define ACQUIRE_LOCK(l) pthread_mutex_lock(l) +#define RELEASE_LOCK(l) pthread_mutex_unlock(l) + +#if HAVE_MORECORE +static MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif /* HAVE_MORECORE */ + +static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER; + +#elif defined(__OS2__) +#define MLOCK_T HMTX +#define INITIAL_LOCK(l) DosCreateMutexSem(0, l, 0, FALSE) +#define ACQUIRE_LOCK(l) DosRequestMutexSem(*l, SEM_INDEFINITE_WAIT) +#define RELEASE_LOCK(l) DosReleaseMutexSem(*l) +#if HAVE_MORECORE +static MLOCK_T morecore_mutex; +#endif /* HAVE_MORECORE */ +static MLOCK_T magic_init_mutex; + +#else /* WIN32 */ +/* + Because lock-protected regions have bounded times, and there + are no recursive lock calls, we can use simple spinlocks. +*/ + +#define MLOCK_T long +static int win32_acquire_lock (MLOCK_T *sl) { + for (;;) { +#ifdef InterlockedCompareExchangePointer + if (!InterlockedCompareExchange(sl, 1, 0)) + return 0; +#else /* Use older void* version */ + if (!InterlockedCompareExchange((void**)sl, (void*)1, (void*)0)) + return 0; +#endif /* InterlockedCompareExchangePointer */ + Sleep (0); + } +} + +static void win32_release_lock (MLOCK_T *sl) { + InterlockedExchange (sl, 0); +} + +#define INITIAL_LOCK(l) *(l)=0 +#define ACQUIRE_LOCK(l) win32_acquire_lock(l) +#define RELEASE_LOCK(l) win32_release_lock(l) +#if HAVE_MORECORE +static MLOCK_T morecore_mutex; +#endif /* HAVE_MORECORE */ +static MLOCK_T magic_init_mutex; +#endif /* WIN32 */ + +#define USE_LOCK_BIT (2U) +#else /* USE_LOCKS */ +#define USE_LOCK_BIT (0U) +#define INITIAL_LOCK(l) +#endif /* USE_LOCKS */ + +#if USE_LOCKS && HAVE_MORECORE +#define ACQUIRE_MORECORE_LOCK() ACQUIRE_LOCK(&morecore_mutex); +#define RELEASE_MORECORE_LOCK() RELEASE_LOCK(&morecore_mutex); +#else /* USE_LOCKS && HAVE_MORECORE */ +#define ACQUIRE_MORECORE_LOCK() +#define RELEASE_MORECORE_LOCK() +#endif /* USE_LOCKS && HAVE_MORECORE */ + +#if USE_LOCKS +#define ACQUIRE_MAGIC_INIT_LOCK() ACQUIRE_LOCK(&magic_init_mutex); +#define RELEASE_MAGIC_INIT_LOCK() RELEASE_LOCK(&magic_init_mutex); +#else /* USE_LOCKS */ +#define ACQUIRE_MAGIC_INIT_LOCK() +#define RELEASE_MAGIC_INIT_LOCK() +#endif /* USE_LOCKS */ + + +/* ----------------------- Chunk representations ------------------------ */ + +/* + (The following includes lightly edited explanations by Colin Plumb.) + + The malloc_chunk declaration below is misleading (but accurate and + necessary). It declares a "view" into memory allowing access to + necessary fields at known offsets from a given base. + + Chunks of memory are maintained using a `boundary tag' method as + originally described by Knuth. (See the paper by Paul Wilson + ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such + techniques.) Sizes of free chunks are stored both in the front of + each chunk and at the end. This makes consolidating fragmented + chunks into bigger chunks fast. The head fields also hold bits + representing whether chunks are free or in use. + + Here are some pictures to make it clearer. They are "exploded" to + show that the state of a chunk can be thought of as extending from + the high 31 bits of the head field of its header through the + prev_foot and PINUSE_BIT bit of the following chunk header. + + A chunk that's in use looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk (if P = 1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 1| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + +- -+ + | | + +- -+ + | : + +- size - sizeof(size_t) available payload bytes -+ + : | + chunk-> +- -+ + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| + | Size of next chunk (may or may not be in use) | +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + And if it's free, it looks like this: + + chunk-> +- -+ + | User payload (must be in use, or we would have merged!) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 0| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Prev pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- size - sizeof(struct chunk) unused bytes -+ + : | + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| + | Size of next chunk (must be in use, or we would have merged)| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- User payload -+ + : | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |0| + +-+ + Note that since we always merge adjacent free chunks, the chunks + adjacent to a free chunk must be in use. + + Given a pointer to a chunk (which can be derived trivially from the + payload pointer) we can, in O(1) time, find out whether the adjacent + chunks are free, and if so, unlink them from the lists that they + are on and merge them with the current chunk. + + Chunks always begin on even word boundaries, so the mem portion + (which is returned to the user) is also on an even word boundary, and + thus at least double-word aligned. + + The P (PINUSE_BIT) bit, stored in the unused low-order bit of the + chunk size (which is always a multiple of two words), is an in-use + bit for the *previous* chunk. If that bit is *clear*, then the + word before the current chunk size contains the previous chunk + size, and can be used to find the front of the previous chunk. + The very first chunk allocated always has this bit set, preventing + access to non-existent (or non-owned) memory. If pinuse is set for + any given chunk, then you CANNOT determine the size of the + previous chunk, and might even get a memory addressing fault when + trying to do so. + + The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of + the chunk size redundantly records whether the current chunk is + inuse. This redundancy enables usage checks within free and realloc, + and reduces indirection when freeing and consolidating chunks. + + Each freshly allocated chunk must have both cinuse and pinuse set. + That is, each allocated chunk borders either a previously allocated + and still in-use chunk, or the base of its memory arena. This is + ensured by making all allocations from the the `lowest' part of any + found chunk. Further, no free chunk physically borders another one, + so each free chunk is known to be preceded and followed by either + inuse chunks or the ends of memory. + + Note that the `foot' of the current chunk is actually represented + as the prev_foot of the NEXT chunk. This makes it easier to + deal with alignments etc but can be very confusing when trying + to extend or adapt this code. + + The exceptions to all this are + + 1. The special chunk `top' is the top-most available chunk (i.e., + the one bordering the end of available memory). It is treated + specially. Top is never included in any bin, is used only if + no other chunk is available, and is released back to the + system if it is very large (see M_TRIM_THRESHOLD). In effect, + the top chunk is treated as larger (and thus less well + fitting) than any other available chunk. The top chunk + doesn't update its trailing size field since there is no next + contiguous chunk that would have to index off it. However, + space is still allocated for it (TOP_FOOT_SIZE) to enable + separation or merging when space is extended. + + 3. Chunks allocated via mmap, which have the lowest-order bit + (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set + PINUSE_BIT in their head fields. Because they are allocated + one-by-one, each must carry its own prev_foot field, which is + also used to hold the offset this chunk has within its mmapped + region, which is needed to preserve alignment. Each mmapped + chunk is trailed by the first two fields of a fake next-chunk + for sake of usage checks. + +*/ + +struct malloc_chunk { + size_t prev_foot; /* Size of previous chunk (if free). */ + size_t head; /* Size and inuse bits. */ + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; +}; + +typedef struct malloc_chunk mchunk; +typedef struct malloc_chunk* mchunkptr; +typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ +typedef size_t bindex_t; /* Described below */ +typedef unsigned int binmap_t; /* Described below */ +typedef unsigned int flag_t; /* The type of various bit flag sets */ + +/* ------------------- Chunks sizes and alignments ----------------------- */ + +#define MCHUNK_SIZE (sizeof(mchunk)) + +#if FOOTERS +#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +#else /* FOOTERS */ +#define CHUNK_OVERHEAD (SIZE_T_SIZE) +#endif /* FOOTERS */ + +/* MMapped chunks need a second word of overhead ... */ +#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +/* ... and additional padding for fake next-chunk at foot */ +#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) + +/* The smallest size we can malloc is an aligned minimal chunk */ +#define MIN_CHUNK_SIZE\ + ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* conversion from malloc headers to user pointers, and back */ +#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) +#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) +/* chunk associated with aligned address A */ +#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) + +/* Bounds on request (not chunk) sizes. */ +#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) +#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) + +/* pad request bytes into a usable size */ +#define pad_request(req) \ + (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* pad request, checking for minimum (but not maximum) */ +#define request2size(req) \ + (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) + + +/* ------------------ Operations on head and foot fields ----------------- */ + +/* + The head field of a chunk is or'ed with PINUSE_BIT when previous + adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in + use. If the chunk was obtained with mmap, the prev_foot field has + IS_MMAPPED_BIT set, otherwise holding the offset of the base of the + mmapped region to the base of the chunk. +*/ + +#define PINUSE_BIT (SIZE_T_ONE) +#define CINUSE_BIT (SIZE_T_TWO) +#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) + +/* Head value for fenceposts */ +#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) + +/* extraction of fields from head words */ +#define cinuse(p) ((p)->head & CINUSE_BIT) +#define pinuse(p) ((p)->head & PINUSE_BIT) +#define chunksize(p) ((p)->head & ~(INUSE_BITS)) + +#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) +#define clear_cinuse(p) ((p)->head &= ~CINUSE_BIT) + +/* Treat space at ptr +/- offset as a chunk */ +#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) +#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) + +/* Ptr to next or previous physical malloc_chunk. */ +#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~INUSE_BITS))) +#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) + +/* extract next chunk's pinuse bit */ +#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) + +/* Get/set size at footer */ +#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) +#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) + +/* Set size, pinuse bit, and foot */ +#define set_size_and_pinuse_of_free_chunk(p, s)\ + ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) + +/* Set size, pinuse bit, foot, and clear next pinuse */ +#define set_free_with_pinuse(p, s, n)\ + (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) + +#define is_mmapped(p)\ + (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT)) + +/* Get the internal overhead associated with chunk p */ +#define overhead_for(p)\ + (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) + +/* Return true if malloced space is not necessarily cleared */ +#if MMAP_CLEARS +#define calloc_must_clear(p) (!is_mmapped(p)) +#else /* MMAP_CLEARS */ +#define calloc_must_clear(p) (1) +#endif /* MMAP_CLEARS */ + +/* ---------------------- Overlaid data structures ----------------------- */ + +/* + When chunks are not in use, they are treated as nodes of either + lists or trees. + + "Small" chunks are stored in circular doubly-linked lists, and look + like this: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space (may be 0 bytes long) . + . . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Larger chunks are kept in a form of bitwise digital trees (aka + tries) keyed on chunksizes. Because malloc_tree_chunks are only for + free chunks greater than 256 bytes, their size doesn't impose any + constraints on user chunk sizes. Each node looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to left child (child[0]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to right child (child[1]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to parent | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | bin index of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Each tree holding treenodes is a tree of unique chunk sizes. Chunks + of the same size are arranged in a circularly-linked list, with only + the oldest chunk (the next to be used, in our FIFO ordering) + actually in the tree. (Tree members are distinguished by a non-null + parent pointer.) If a chunk with the same size an an existing node + is inserted, it is linked off the existing node using pointers that + work in the same way as fd/bk pointers of small chunks. + + Each tree contains a power of 2 sized range of chunk sizes (the + smallest is 0x100 <= x < 0x180), which is is divided in half at each + tree level, with the chunks in the smaller half of the range (0x100 + <= x < 0x140 for the top nose) in the left subtree and the larger + half (0x140 <= x < 0x180) in the right subtree. This is, of course, + done by inspecting individual bits. + + Using these rules, each node's left subtree contains all smaller + sizes than its right subtree. However, the node at the root of each + subtree has no particular ordering relationship to either. (The + dividing line between the subtree sizes is based on trie relation.) + If we remove the last chunk of a given size from the interior of the + tree, we need to replace it with a leaf node. The tree ordering + rules permit a node to be replaced by any leaf below it. + + The smallest chunk in a tree (a common operation in a best-fit + allocator) can be found by walking a path to the leftmost leaf in + the tree. Unlike a usual binary tree, where we follow left child + pointers until we reach a null, here we follow the right child + pointer any time the left one is null, until we reach a leaf with + both child pointers null. The smallest chunk in the tree will be + somewhere along that path. + + The worst case number of steps to add, find, or remove a node is + bounded by the number of bits differentiating chunks within + bins. Under current bin calculations, this ranges from 6 up to 21 + (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case + is of course much better. +*/ + +struct malloc_tree_chunk { + /* The first four fields must be compatible with malloc_chunk */ + size_t prev_foot; + size_t head; + struct malloc_tree_chunk* fd; + struct malloc_tree_chunk* bk; + + struct malloc_tree_chunk* child[2]; + struct malloc_tree_chunk* parent; + bindex_t index; +}; + +typedef struct malloc_tree_chunk tchunk; +typedef struct malloc_tree_chunk* tchunkptr; +typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ + +/* A little helper macro for trees */ +#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) + +/* ----------------------------- Segments -------------------------------- */ + +/* + Each malloc space may include non-contiguous segments, held in a + list headed by an embedded malloc_segment record representing the + top-most space. Segments also include flags holding properties of + the space. Large chunks that are directly allocated by mmap are not + included in this list. They are instead independently created and + destroyed without otherwise keeping track of them. + + Segment management mainly comes into play for spaces allocated by + MMAP. Any call to MMAP might or might not return memory that is + adjacent to an existing segment. MORECORE normally contiguously + extends the current space, so this space is almost always adjacent, + which is simpler and faster to deal with. (This is why MORECORE is + used preferentially to MMAP when both are available -- see + sys_alloc.) When allocating using MMAP, we don't use any of the + hinting mechanisms (inconsistently) supported in various + implementations of unix mmap, or distinguish reserving from + committing memory. Instead, we just ask for space, and exploit + contiguity when we get it. It is probably possible to do + better than this on some systems, but no general scheme seems + to be significantly better. + + Management entails a simpler variant of the consolidation scheme + used for chunks to reduce fragmentation -- new adjacent memory is + normally prepended or appended to an existing segment. However, + there are limitations compared to chunk consolidation that mostly + reflect the fact that segment processing is relatively infrequent + (occurring only when getting memory from system) and that we + don't expect to have huge numbers of segments: + + * Segments are not indexed, so traversal requires linear scans. (It + would be possible to index these, but is not worth the extra + overhead and complexity for most programs on most platforms.) + * New segments are only appended to old ones when holding top-most + memory; if they cannot be prepended to others, they are held in + different segments. + + Except for the top-most segment of an mstate, each segment record + is kept at the tail of its segment. Segments are added by pushing + segment records onto the list headed by &mstate.seg for the + containing mstate. + + Segment flags control allocation/merge/deallocation policies: + * If EXTERN_BIT set, then we did not allocate this segment, + and so should not try to deallocate or merge with others. + (This currently holds only for the initial segment passed + into create_mspace_with_base.) + * If IS_MMAPPED_BIT set, the segment may be merged with + other surrounding mmapped segments and trimmed/de-allocated + using munmap. + * If neither bit is set, then the segment was obtained using + MORECORE so can be merged with surrounding MORECORE'd segments + and deallocated/trimmed using MORECORE with negative arguments. +*/ + +struct malloc_segment { + char* base; /* base address */ + size_t size; /* allocated size */ + struct malloc_segment* next; /* ptr to next segment */ +#if FFI_MMAP_EXEC_WRIT + /* The mmap magic is supposed to store the address of the executable + segment at the very end of the requested block. */ + +# define mmap_exec_offset(b,s) (*(ptrdiff_t*)((b)+(s)-sizeof(ptrdiff_t))) + + /* We can only merge segments if their corresponding executable + segments are at identical offsets. */ +# define check_segment_merge(S,b,s) \ + (mmap_exec_offset((b),(s)) == (S)->exec_offset) + +# define add_segment_exec_offset(p,S) ((char*)(p) + (S)->exec_offset) +# define sub_segment_exec_offset(p,S) ((char*)(p) - (S)->exec_offset) + + /* The removal of sflags only works with HAVE_MORECORE == 0. */ + +# define get_segment_flags(S) (IS_MMAPPED_BIT) +# define set_segment_flags(S,v) \ + (((v) != IS_MMAPPED_BIT) ? (ABORT, (v)) : \ + (((S)->exec_offset = \ + mmap_exec_offset((S)->base, (S)->size)), \ + (mmap_exec_offset((S)->base + (S)->exec_offset, (S)->size) != \ + (S)->exec_offset) ? (ABORT, (v)) : \ + (mmap_exec_offset((S)->base, (S)->size) = 0), (v))) + + /* We use an offset here, instead of a pointer, because then, when + base changes, we don't have to modify this. On architectures + with segmented addresses, this might not work. */ + ptrdiff_t exec_offset; +#else + +# define get_segment_flags(S) ((S)->sflags) +# define set_segment_flags(S,v) ((S)->sflags = (v)) +# define check_segment_merge(S,b,s) (1) + + flag_t sflags; /* mmap and extern flag */ +#endif +}; + +#define is_mmapped_segment(S) (get_segment_flags(S) & IS_MMAPPED_BIT) +#define is_extern_segment(S) (get_segment_flags(S) & EXTERN_BIT) + +typedef struct malloc_segment msegment; +typedef struct malloc_segment* msegmentptr; + +/* ---------------------------- malloc_state ----------------------------- */ + +/* + A malloc_state holds all of the bookkeeping for a space. + The main fields are: + + Top + The topmost chunk of the currently active segment. Its size is + cached in topsize. The actual size of topmost space is + topsize+TOP_FOOT_SIZE, which includes space reserved for adding + fenceposts and segment records if necessary when getting more + space from the system. The size at which to autotrim top is + cached from mparams in trim_check, except that it is disabled if + an autotrim fails. + + Designated victim (dv) + This is the preferred chunk for servicing small requests that + don't have exact fits. It is normally the chunk split off most + recently to service another small request. Its size is cached in + dvsize. The link fields of this chunk are not maintained since it + is not kept in a bin. + + SmallBins + An array of bin headers for free chunks. These bins hold chunks + with sizes less than MIN_LARGE_SIZE bytes. Each bin contains + chunks of all the same size, spaced 8 bytes apart. To simplify + use in double-linked lists, each bin header acts as a malloc_chunk + pointing to the real first node, if it exists (else pointing to + itself). This avoids special-casing for headers. But to avoid + waste, we allocate only the fd/bk pointers of bins, and then use + repositioning tricks to treat these as the fields of a chunk. + + TreeBins + Treebins are pointers to the roots of trees holding a range of + sizes. There are 2 equally spaced treebins for each power of two + from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything + larger. + + Bin maps + There is one bit map for small bins ("smallmap") and one for + treebins ("treemap). Each bin sets its bit when non-empty, and + clears the bit when empty. Bit operations are then used to avoid + bin-by-bin searching -- nearly all "search" is done without ever + looking at bins that won't be selected. The bit maps + conservatively use 32 bits per map word, even if on 64bit system. + For a good description of some of the bit-based techniques used + here, see Henry S. Warren Jr's book "Hacker's Delight" (and + supplement at http://hackersdelight.org/). Many of these are + intended to reduce the branchiness of paths through malloc etc, as + well as to reduce the number of memory locations read or written. + + Segments + A list of segments headed by an embedded malloc_segment record + representing the initial space. + + Address check support + The least_addr field is the least address ever obtained from + MORECORE or MMAP. Attempted frees and reallocs of any address less + than this are trapped (unless INSECURE is defined). + + Magic tag + A cross-check field that should always hold same value as mparams.magic. + + Flags + Bits recording whether to use MMAP, locks, or contiguous MORECORE + + Statistics + Each space keeps track of current and maximum system memory + obtained via MORECORE or MMAP. + + Locking + If USE_LOCKS is defined, the "mutex" lock is acquired and released + around every public call using this mspace. +*/ + +/* Bin types, widths and sizes */ +#define NSMALLBINS (32U) +#define NTREEBINS (32U) +#define SMALLBIN_SHIFT (3U) +#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) +#define TREEBIN_SHIFT (8U) +#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) +#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) +#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) + +struct malloc_state { + binmap_t smallmap; + binmap_t treemap; + size_t dvsize; + size_t topsize; + char* least_addr; + mchunkptr dv; + mchunkptr top; + size_t trim_check; + size_t magic; + mchunkptr smallbins[(NSMALLBINS+1)*2]; + tbinptr treebins[NTREEBINS]; + size_t footprint; + size_t max_footprint; + flag_t mflags; +#if USE_LOCKS + MLOCK_T mutex; /* locate lock among fields that rarely change */ +#endif /* USE_LOCKS */ + msegment seg; +}; + +typedef struct malloc_state* mstate; + +/* ------------- Global malloc_state and malloc_params ------------------- */ + +/* + malloc_params holds global properties, including those that can be + dynamically set using mallopt. There is a single instance, mparams, + initialized in init_mparams. +*/ + +struct malloc_params { + size_t magic; + size_t page_size; + size_t granularity; + size_t mmap_threshold; + size_t trim_threshold; + flag_t default_mflags; +}; + +static struct malloc_params mparams; + +/* The global malloc_state used for all non-"mspace" calls */ +static struct malloc_state _gm_; +#define gm (&_gm_) +#define is_global(M) ((M) == &_gm_) +#define is_initialized(M) ((M)->top != 0) + +/* -------------------------- system alloc setup ------------------------- */ + +/* Operations on mflags */ + +#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) +#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) +#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) + +#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) +#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) +#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) + +#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) +#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) + +#define set_lock(M,L)\ + ((M)->mflags = (L)?\ + ((M)->mflags | USE_LOCK_BIT) :\ + ((M)->mflags & ~USE_LOCK_BIT)) + +/* page-align a size */ +#define page_align(S)\ + (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE)) + +/* granularity-align a size */ +#define granularity_align(S)\ + (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE)) + +#define is_page_aligned(S)\ + (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) +#define is_granularity_aligned(S)\ + (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) + +/* True if segment S holds address A */ +#define segment_holds(S, A)\ + ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) + +/* Return segment holding given address */ +static msegmentptr segment_holding(mstate m, char* addr) { + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= sp->base && addr < sp->base + sp->size) + return sp; + if ((sp = sp->next) == 0) + return 0; + } +} + +/* Return true if segment contains a segment link */ +static int has_segment_link(mstate m, msegmentptr ss) { + msegmentptr sp = &m->seg; + for (;;) { + if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) + return 1; + if ((sp = sp->next) == 0) + return 0; + } +} + +#ifndef MORECORE_CANNOT_TRIM +#define should_trim(M,s) ((s) > (M)->trim_check) +#else /* MORECORE_CANNOT_TRIM */ +#define should_trim(M,s) (0) +#endif /* MORECORE_CANNOT_TRIM */ + +/* + TOP_FOOT_SIZE is padding at the end of a segment, including space + that may be needed to place segment records and fenceposts when new + noncontiguous segments are added. +*/ +#define TOP_FOOT_SIZE\ + (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) + + +/* ------------------------------- Hooks -------------------------------- */ + +/* + PREACTION should be defined to return 0 on success, and nonzero on + failure. If you are not using locking, you can redefine these to do + anything you like. +*/ + +#if USE_LOCKS + +/* Ensure locks are initialized */ +#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams()) + +#define PREACTION(M) ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) +#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } +#else /* USE_LOCKS */ + +#ifndef PREACTION +#define PREACTION(M) (0) +#endif /* PREACTION */ + +#ifndef POSTACTION +#define POSTACTION(M) +#endif /* POSTACTION */ + +#endif /* USE_LOCKS */ + +/* + CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. + USAGE_ERROR_ACTION is triggered on detected bad frees and + reallocs. The argument p is an address that might have triggered the + fault. It is ignored by the two predefined actions, but might be + useful in custom actions that try to help diagnose errors. +*/ + +#if PROCEED_ON_ERROR + +/* A count of the number of corruption errors causing resets */ +int malloc_corruption_error_count; + +/* default corruption action */ +static void reset_on_error(mstate m); + +#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) +#define USAGE_ERROR_ACTION(m, p) + +#else /* PROCEED_ON_ERROR */ + +#ifndef CORRUPTION_ERROR_ACTION +#define CORRUPTION_ERROR_ACTION(m) ABORT +#endif /* CORRUPTION_ERROR_ACTION */ + +#ifndef USAGE_ERROR_ACTION +#define USAGE_ERROR_ACTION(m,p) ABORT +#endif /* USAGE_ERROR_ACTION */ + +#endif /* PROCEED_ON_ERROR */ + +/* -------------------------- Debugging setup ---------------------------- */ + +#if ! DEBUG + +#define check_free_chunk(M,P) +#define check_inuse_chunk(M,P) +#define check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) +#define check_malloc_state(M) +#define check_top_chunk(M,P) + +#else /* DEBUG */ +#define check_free_chunk(M,P) do_check_free_chunk(M,P) +#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) +#define check_top_chunk(M,P) do_check_top_chunk(M,P) +#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) +#define check_malloc_state(M) do_check_malloc_state(M) + +static void do_check_any_chunk(mstate m, mchunkptr p); +static void do_check_top_chunk(mstate m, mchunkptr p); +static void do_check_mmapped_chunk(mstate m, mchunkptr p); +static void do_check_inuse_chunk(mstate m, mchunkptr p); +static void do_check_free_chunk(mstate m, mchunkptr p); +static void do_check_malloced_chunk(mstate m, void* mem, size_t s); +static void do_check_tree(mstate m, tchunkptr t); +static void do_check_treebin(mstate m, bindex_t i); +static void do_check_smallbin(mstate m, bindex_t i); +static void do_check_malloc_state(mstate m); +static int bin_find(mstate m, mchunkptr x); +static size_t traverse_and_check(mstate m); +#endif /* DEBUG */ + +/* ---------------------------- Indexing Bins ---------------------------- */ + +#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) +#define small_index(s) ((s) >> SMALLBIN_SHIFT) +#define small_index2size(i) ((i) << SMALLBIN_SHIFT) +#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) + +/* addressing by index. See above about smallbin repositioning */ +#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) +#define treebin_at(M,i) (&((M)->treebins[i])) + +/* assign tree index for size S to variable I */ +#if defined(__GNUC__) && defined(__i386__) +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K;\ + __asm__("bsrl %1,%0\n\t" : "=r" (K) : "rm" (X));\ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} +#else /* GNUC */ +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int Y = (unsigned int)X;\ + unsigned int N = ((Y - 0x100) >> 16) & 8;\ + unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ + N += K;\ + N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ + K = 14 - N + ((Y <<= K) >> 15);\ + I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ + }\ +} +#endif /* GNUC */ + +/* Bit representing maximum resolved size in a treebin at i */ +#define bit_for_tree_index(i) \ + (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) + +/* Shift placing maximum resolved bit in a treebin at i as sign bit */ +#define leftshift_for_tree_index(i) \ + ((i == NTREEBINS-1)? 0 : \ + ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) + +/* The size of the smallest chunk held in bin with index i */ +#define minsize_for_tree_index(i) \ + ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ + (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) + + +/* ------------------------ Operations on bin maps ----------------------- */ + +/* bit corresponding to given index */ +#define idx2bit(i) ((binmap_t)(1) << (i)) + +/* Mark/Clear bits with given index */ +#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) +#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) +#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) + +#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) +#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) +#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) + +/* index corresponding to given bit */ + +#if defined(__GNUC__) && defined(__i386__) +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + __asm__("bsfl %1,%0\n\t" : "=r" (J) : "rm" (X));\ + I = (bindex_t)J;\ +} + +#else /* GNUC */ +#if USE_BUILTIN_FFS +#define compute_bit2idx(X, I) I = ffs(X)-1 + +#else /* USE_BUILTIN_FFS */ +#define compute_bit2idx(X, I)\ +{\ + unsigned int Y = X - 1;\ + unsigned int K = Y >> (16-4) & 16;\ + unsigned int N = K; Y >>= K;\ + N += K = Y >> (8-3) & 8; Y >>= K;\ + N += K = Y >> (4-2) & 4; Y >>= K;\ + N += K = Y >> (2-1) & 2; Y >>= K;\ + N += K = Y >> (1-0) & 1; Y >>= K;\ + I = (bindex_t)(N + Y);\ +} +#endif /* USE_BUILTIN_FFS */ +#endif /* GNUC */ + +/* isolate the least set bit of a bitmap */ +#define least_bit(x) ((x) & -(x)) + +/* mask with all bits to left of least bit of x on */ +#define left_bits(x) ((x<<1) | -(x<<1)) + +/* mask with all bits to left of or equal to least bit of x on */ +#define same_or_left_bits(x) ((x) | -(x)) + + +/* ----------------------- Runtime Check Support ------------------------- */ + +/* + For security, the main invariant is that malloc/free/etc never + writes to a static address other than malloc_state, unless static + malloc_state itself has been corrupted, which cannot occur via + malloc (because of these checks). In essence this means that we + believe all pointers, sizes, maps etc held in malloc_state, but + check all of those linked or offsetted from other embedded data + structures. These checks are interspersed with main code in a way + that tends to minimize their run-time cost. + + When FOOTERS is defined, in addition to range checking, we also + verify footer fields of inuse chunks, which can be used guarantee + that the mstate controlling malloc/free is intact. This is a + streamlined version of the approach described by William Robertson + et al in "Run-time Detection of Heap-based Overflows" LISA'03 + http://www.usenix.org/events/lisa03/tech/robertson.html The footer + of an inuse chunk holds the xor of its mstate and a random seed, + that is checked upon calls to free() and realloc(). This is + (probablistically) unguessable from outside the program, but can be + computed by any code successfully malloc'ing any chunk, so does not + itself provide protection against code that has already broken + security through some other means. Unlike Robertson et al, we + always dynamically check addresses of all offset chunks (previous, + next, etc). This turns out to be cheaper than relying on hashes. +*/ + +#if !INSECURE +/* Check if address a is at least as high as any from MORECORE or MMAP */ +#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) +/* Check if address of next chunk n is higher than base chunk p */ +#define ok_next(p, n) ((char*)(p) < (char*)(n)) +/* Check if p has its cinuse bit on */ +#define ok_cinuse(p) cinuse(p) +/* Check if p has its pinuse bit on */ +#define ok_pinuse(p) pinuse(p) + +#else /* !INSECURE */ +#define ok_address(M, a) (1) +#define ok_next(b, n) (1) +#define ok_cinuse(p) (1) +#define ok_pinuse(p) (1) +#endif /* !INSECURE */ + +#if (FOOTERS && !INSECURE) +/* Check if (alleged) mstate m has expected magic field */ +#define ok_magic(M) ((M)->magic == mparams.magic) +#else /* (FOOTERS && !INSECURE) */ +#define ok_magic(M) (1) +#endif /* (FOOTERS && !INSECURE) */ + + +/* In gcc, use __builtin_expect to minimize impact of checks */ +#if !INSECURE +#if defined(__GNUC__) && __GNUC__ >= 3 +#define RTCHECK(e) __builtin_expect(e, 1) +#else /* GNUC */ +#define RTCHECK(e) (e) +#endif /* GNUC */ +#else /* !INSECURE */ +#define RTCHECK(e) (1) +#endif /* !INSECURE */ + +/* macros to set up inuse chunks with or without footers */ + +#if !FOOTERS + +#define mark_inuse_foot(M,p,s) + +/* Set cinuse bit and pinuse bit of next chunk */ +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set size, cinuse and pinuse bit of this chunk */ +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) + +#else /* FOOTERS */ + +/* Set foot of inuse chunk to be xor of mstate and seed */ +#define mark_inuse_foot(M,p,s)\ + (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) + +#define get_mstate_for(p)\ + ((mstate)(((mchunkptr)((char*)(p) +\ + (chunksize(p))))->prev_foot ^ mparams.magic)) + +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ + mark_inuse_foot(M,p,s)) + +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ + mark_inuse_foot(M,p,s)) + +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + mark_inuse_foot(M, p, s)) + +#endif /* !FOOTERS */ + +/* ---------------------------- setting mparams -------------------------- */ + +/* Initialize mparams */ +static int init_mparams(void) { + if (mparams.page_size == 0) { + size_t s; + + mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; + mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; +#if MORECORE_CONTIGUOUS + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; +#else /* MORECORE_CONTIGUOUS */ + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; +#endif /* MORECORE_CONTIGUOUS */ + +#if (FOOTERS && !INSECURE) + { +#if USE_DEV_RANDOM + int fd; + unsigned char buf[sizeof(size_t)]; + /* Try to use /dev/urandom, else fall back on using time */ + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && + read(fd, buf, sizeof(buf)) == sizeof(buf)) { + s = *((size_t *) buf); + close(fd); + } + else +#endif /* USE_DEV_RANDOM */ + s = (size_t)(time(0) ^ (size_t)0x55555555U); + + s |= (size_t)8U; /* ensure nonzero */ + s &= ~(size_t)7U; /* improve chances of fault for bad values */ + + } +#else /* (FOOTERS && !INSECURE) */ + s = (size_t)0x58585858U; +#endif /* (FOOTERS && !INSECURE) */ + ACQUIRE_MAGIC_INIT_LOCK(); + if (mparams.magic == 0) { + mparams.magic = s; + /* Set up lock for main malloc area */ + INITIAL_LOCK(&gm->mutex); + gm->mflags = mparams.default_mflags; + } + RELEASE_MAGIC_INIT_LOCK(); + +#if !defined(WIN32) && !defined(__OS2__) + mparams.page_size = malloc_getpagesize; + mparams.granularity = ((DEFAULT_GRANULARITY != 0)? + DEFAULT_GRANULARITY : mparams.page_size); +#elif defined (__OS2__) + /* if low-memory is used, os2munmap() would break + if it were anything other than 64k */ + mparams.page_size = 4096u; + mparams.granularity = 65536u; +#else /* WIN32 */ + { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + mparams.page_size = system_info.dwPageSize; + mparams.granularity = system_info.dwAllocationGranularity; + } +#endif /* WIN32 */ + + /* Sanity-check configuration: + size_t must be unsigned and as wide as pointer type. + ints must be at least 4 bytes. + alignment must be at least 8. + Alignment, min chunk size, and page size must all be powers of 2. + */ + if ((sizeof(size_t) != sizeof(char*)) || + (MAX_SIZE_T < MIN_CHUNK_SIZE) || + (sizeof(int) < 4) || + (MALLOC_ALIGNMENT < (size_t)8U) || + ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || + ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || + ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) || + ((mparams.page_size & (mparams.page_size-SIZE_T_ONE)) != 0)) + ABORT; + } + return 0; +} + +/* support for mallopt */ +static int change_mparam(int param_number, int value) { + size_t val = (size_t)value; + init_mparams(); + switch(param_number) { + case M_TRIM_THRESHOLD: + mparams.trim_threshold = val; + return 1; + case M_GRANULARITY: + if (val >= mparams.page_size && ((val & (val-1)) == 0)) { + mparams.granularity = val; + return 1; + } + else + return 0; + case M_MMAP_THRESHOLD: + mparams.mmap_threshold = val; + return 1; + default: + return 0; + } +} + +#if DEBUG +/* ------------------------- Debugging Support --------------------------- */ + +/* Check properties of any chunk, whether free, inuse, mmapped etc */ +static void do_check_any_chunk(mstate m, mchunkptr p) { + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); +} + +/* Check properties of top chunk */ +static void do_check_top_chunk(mstate m, mchunkptr p) { + msegmentptr sp = segment_holding(m, (char*)p); + size_t sz = chunksize(p); + assert(sp != 0); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(sz == m->topsize); + assert(sz > 0); + assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); + assert(pinuse(p)); + assert(!next_pinuse(p)); +} + +/* Check properties of (inuse) mmapped chunks */ +static void do_check_mmapped_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD); + assert(is_mmapped(p)); + assert(use_mmap(m)); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(!is_small(sz)); + assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); + assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); + assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); +} + +/* Check properties of inuse chunks */ +static void do_check_inuse_chunk(mstate m, mchunkptr p) { + do_check_any_chunk(m, p); + assert(cinuse(p)); + assert(next_pinuse(p)); + /* If not pinuse and not mmapped, previous chunk has OK offset */ + assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); + if (is_mmapped(p)) + do_check_mmapped_chunk(m, p); +} + +/* Check properties of free chunks */ +static void do_check_free_chunk(mstate m, mchunkptr p) { + size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT); + mchunkptr next = chunk_plus_offset(p, sz); + do_check_any_chunk(m, p); + assert(!cinuse(p)); + assert(!next_pinuse(p)); + assert (!is_mmapped(p)); + if (p != m->dv && p != m->top) { + if (sz >= MIN_CHUNK_SIZE) { + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(is_aligned(chunk2mem(p))); + assert(next->prev_foot == sz); + assert(pinuse(p)); + assert (next == m->top || cinuse(next)); + assert(p->fd->bk == p); + assert(p->bk->fd == p); + } + else /* markers are always of size SIZE_T_SIZE */ + assert(sz == SIZE_T_SIZE); + } +} + +/* Check properties of malloced chunks at the point they are malloced */ +static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT); + do_check_inuse_chunk(m, p); + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(sz >= MIN_CHUNK_SIZE); + assert(sz >= s); + /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ + assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); + } +} + +/* Check a tree and its subtrees. */ +static void do_check_tree(mstate m, tchunkptr t) { + tchunkptr head = 0; + tchunkptr u = t; + bindex_t tindex = t->index; + size_t tsize = chunksize(t); + bindex_t idx; + compute_tree_index(tsize, idx); + assert(tindex == idx); + assert(tsize >= MIN_LARGE_SIZE); + assert(tsize >= minsize_for_tree_index(idx)); + assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); + + do { /* traverse through chain of same-sized nodes */ + do_check_any_chunk(m, ((mchunkptr)u)); + assert(u->index == tindex); + assert(chunksize(u) == tsize); + assert(!cinuse(u)); + assert(!next_pinuse(u)); + assert(u->fd->bk == u); + assert(u->bk->fd == u); + if (u->parent == 0) { + assert(u->child[0] == 0); + assert(u->child[1] == 0); + } + else { + assert(head == 0); /* only one node on chain has parent */ + head = u; + assert(u->parent != u); + assert (u->parent->child[0] == u || + u->parent->child[1] == u || + *((tbinptr*)(u->parent)) == u); + if (u->child[0] != 0) { + assert(u->child[0]->parent == u); + assert(u->child[0] != u); + do_check_tree(m, u->child[0]); + } + if (u->child[1] != 0) { + assert(u->child[1]->parent == u); + assert(u->child[1] != u); + do_check_tree(m, u->child[1]); + } + if (u->child[0] != 0 && u->child[1] != 0) { + assert(chunksize(u->child[0]) < chunksize(u->child[1])); + } + } + u = u->fd; + } while (u != t); + assert(head != 0); +} + +/* Check all the chunks in a treebin. */ +static void do_check_treebin(mstate m, bindex_t i) { + tbinptr* tb = treebin_at(m, i); + tchunkptr t = *tb; + int empty = (m->treemap & (1U << i)) == 0; + if (t == 0) + assert(empty); + if (!empty) + do_check_tree(m, t); +} + +/* Check all the chunks in a smallbin. */ +static void do_check_smallbin(mstate m, bindex_t i) { + sbinptr b = smallbin_at(m, i); + mchunkptr p = b->bk; + unsigned int empty = (m->smallmap & (1U << i)) == 0; + if (p == b) + assert(empty); + if (!empty) { + for (; p != b; p = p->bk) { + size_t size = chunksize(p); + mchunkptr q; + /* each chunk claims to be free */ + do_check_free_chunk(m, p); + /* chunk belongs in bin */ + assert(small_index(size) == i); + assert(p->bk == b || chunksize(p->bk) == chunksize(p)); + /* chunk is followed by an inuse chunk */ + q = next_chunk(p); + if (q->head != FENCEPOST_HEAD) + do_check_inuse_chunk(m, q); + } + } +} + +/* Find x in a bin. Used in other check functions. */ +static int bin_find(mstate m, mchunkptr x) { + size_t size = chunksize(x); + if (is_small(size)) { + bindex_t sidx = small_index(size); + sbinptr b = smallbin_at(m, sidx); + if (smallmap_is_marked(m, sidx)) { + mchunkptr p = b; + do { + if (p == x) + return 1; + } while ((p = p->fd) != b); + } + } + else { + bindex_t tidx; + compute_tree_index(size, tidx); + if (treemap_is_marked(m, tidx)) { + tchunkptr t = *treebin_at(m, tidx); + size_t sizebits = size << leftshift_for_tree_index(tidx); + while (t != 0 && chunksize(t) != size) { + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + sizebits <<= 1; + } + if (t != 0) { + tchunkptr u = t; + do { + if (u == (tchunkptr)x) + return 1; + } while ((u = u->fd) != t); + } + } + } + return 0; +} + +/* Traverse each chunk and check it; return total */ +static size_t traverse_and_check(mstate m) { + size_t sum = 0; + if (is_initialized(m)) { + msegmentptr s = &m->seg; + sum += m->topsize + TOP_FOOT_SIZE; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + mchunkptr lastq = 0; + assert(pinuse(q)); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + sum += chunksize(q); + if (cinuse(q)) { + assert(!bin_find(m, q)); + do_check_inuse_chunk(m, q); + } + else { + assert(q == m->dv || bin_find(m, q)); + assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */ + do_check_free_chunk(m, q); + } + lastq = q; + q = next_chunk(q); + } + s = s->next; + } + } + return sum; +} + +/* Check all properties of malloc_state. */ +static void do_check_malloc_state(mstate m) { + bindex_t i; + size_t total; + /* check bins */ + for (i = 0; i < NSMALLBINS; ++i) + do_check_smallbin(m, i); + for (i = 0; i < NTREEBINS; ++i) + do_check_treebin(m, i); + + if (m->dvsize != 0) { /* check dv chunk */ + do_check_any_chunk(m, m->dv); + assert(m->dvsize == chunksize(m->dv)); + assert(m->dvsize >= MIN_CHUNK_SIZE); + assert(bin_find(m, m->dv) == 0); + } + + if (m->top != 0) { /* check top chunk */ + do_check_top_chunk(m, m->top); + assert(m->topsize == chunksize(m->top)); + assert(m->topsize > 0); + assert(bin_find(m, m->top) == 0); + } + + total = traverse_and_check(m); + assert(total <= m->footprint); + assert(m->footprint <= m->max_footprint); +} +#endif /* DEBUG */ + +/* ----------------------------- statistics ------------------------------ */ + +#if !NO_MALLINFO +static struct mallinfo internal_mallinfo(mstate m) { + struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + if (!PREACTION(m)) { + check_malloc_state(m); + if (is_initialized(m)) { + size_t nfree = SIZE_T_ONE; /* top always free */ + size_t mfree = m->topsize + TOP_FOOT_SIZE; + size_t sum = mfree; + msegmentptr s = &m->seg; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + size_t sz = chunksize(q); + sum += sz; + if (!cinuse(q)) { + mfree += sz; + ++nfree; + } + q = next_chunk(q); + } + s = s->next; + } + + nm.arena = sum; + nm.ordblks = nfree; + nm.hblkhd = m->footprint - sum; + nm.usmblks = m->max_footprint; + nm.uordblks = m->footprint - mfree; + nm.fordblks = mfree; + nm.keepcost = m->topsize; + } + + POSTACTION(m); + } + return nm; +} +#endif /* !NO_MALLINFO */ + +static void internal_malloc_stats(mstate m) { + if (!PREACTION(m)) { + size_t maxfp = 0; + size_t fp = 0; + size_t used = 0; + check_malloc_state(m); + if (is_initialized(m)) { + msegmentptr s = &m->seg; + maxfp = m->max_footprint; + fp = m->footprint; + used = fp - (m->topsize + TOP_FOOT_SIZE); + + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + if (!cinuse(q)) + used -= chunksize(q); + q = next_chunk(q); + } + s = s->next; + } + } + + fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); + fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); + fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); + + POSTACTION(m); + } +} + +/* ----------------------- Operations on smallbins ----------------------- */ + +/* + Various forms of linking and unlinking are defined as macros. Even + the ones for trees, which are very long but have very short typical + paths. This is ugly but reduces reliance on inlining support of + compilers. +*/ + +/* Link a free chunk into a smallbin */ +#define insert_small_chunk(M, P, S) {\ + bindex_t I = small_index(S);\ + mchunkptr B = smallbin_at(M, I);\ + mchunkptr F = B;\ + assert(S >= MIN_CHUNK_SIZE);\ + if (!smallmap_is_marked(M, I))\ + mark_smallmap(M, I);\ + else if (RTCHECK(ok_address(M, B->fd)))\ + F = B->fd;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + B->fd = P;\ + F->bk = P;\ + P->fd = F;\ + P->bk = B;\ +} + +/* Unlink a chunk from a smallbin */ +#define unlink_small_chunk(M, P, S) {\ + mchunkptr F = P->fd;\ + mchunkptr B = P->bk;\ + bindex_t I = small_index(S);\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (F == B)\ + clear_smallmap(M, I);\ + else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\ + (B == smallbin_at(M,I) || ok_address(M, B)))) {\ + F->bk = B;\ + B->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Unlink the first chunk from a smallbin */ +#define unlink_first_small_chunk(M, B, P, I) {\ + mchunkptr F = P->fd;\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (B == F)\ + clear_smallmap(M, I);\ + else if (RTCHECK(ok_address(M, F))) {\ + B->fd = F;\ + F->bk = B;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Replace dv node, binning the old one */ +/* Used only when dvsize known to be small */ +#define replace_dv(M, P, S) {\ + size_t DVS = M->dvsize;\ + if (DVS != 0) {\ + mchunkptr DV = M->dv;\ + assert(is_small(DVS));\ + insert_small_chunk(M, DV, DVS);\ + }\ + M->dvsize = S;\ + M->dv = P;\ +} + +/* ------------------------- Operations on trees ------------------------- */ + +/* Insert chunk into tree */ +#define insert_large_chunk(M, X, S) {\ + tbinptr* H;\ + bindex_t I;\ + compute_tree_index(S, I);\ + H = treebin_at(M, I);\ + X->index = I;\ + X->child[0] = X->child[1] = 0;\ + if (!treemap_is_marked(M, I)) {\ + mark_treemap(M, I);\ + *H = X;\ + X->parent = (tchunkptr)H;\ + X->fd = X->bk = X;\ + }\ + else {\ + tchunkptr T = *H;\ + size_t K = S << leftshift_for_tree_index(I);\ + for (;;) {\ + if (chunksize(T) != S) {\ + tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ + K <<= 1;\ + if (*C != 0)\ + T = *C;\ + else if (RTCHECK(ok_address(M, C))) {\ + *C = X;\ + X->parent = T;\ + X->fd = X->bk = X;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + else {\ + tchunkptr F = T->fd;\ + if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ + T->fd = F->bk = X;\ + X->fd = F;\ + X->bk = T;\ + X->parent = 0;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + }\ + }\ +} + +/* + Unlink steps: + + 1. If x is a chained node, unlink it from its same-sized fd/bk links + and choose its bk node as its replacement. + 2. If x was the last node of its size, but not a leaf node, it must + be replaced with a leaf node (not merely one with an open left or + right), to make sure that lefts and rights of descendants + correspond properly to bit masks. We use the rightmost descendant + of x. We could use any other leaf, but this is easy to locate and + tends to counteract removal of leftmosts elsewhere, and so keeps + paths shorter than minimally guaranteed. This doesn't loop much + because on average a node in a tree is near the bottom. + 3. If x is the base of a chain (i.e., has parent links) relink + x's parent and children to x's replacement (or null if none). +*/ + +#define unlink_large_chunk(M, X) {\ + tchunkptr XP = X->parent;\ + tchunkptr R;\ + if (X->bk != X) {\ + tchunkptr F = X->fd;\ + R = X->bk;\ + if (RTCHECK(ok_address(M, F))) {\ + F->bk = R;\ + R->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else {\ + tchunkptr* RP;\ + if (((R = *(RP = &(X->child[1]))) != 0) ||\ + ((R = *(RP = &(X->child[0]))) != 0)) {\ + tchunkptr* CP;\ + while ((*(CP = &(R->child[1])) != 0) ||\ + (*(CP = &(R->child[0])) != 0)) {\ + R = *(RP = CP);\ + }\ + if (RTCHECK(ok_address(M, RP)))\ + *RP = 0;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + }\ + if (XP != 0) {\ + tbinptr* H = treebin_at(M, X->index);\ + if (X == *H) {\ + if ((*H = R) == 0) \ + clear_treemap(M, X->index);\ + }\ + else if (RTCHECK(ok_address(M, XP))) {\ + if (XP->child[0] == X) \ + XP->child[0] = R;\ + else \ + XP->child[1] = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + if (R != 0) {\ + if (RTCHECK(ok_address(M, R))) {\ + tchunkptr C0, C1;\ + R->parent = XP;\ + if ((C0 = X->child[0]) != 0) {\ + if (RTCHECK(ok_address(M, C0))) {\ + R->child[0] = C0;\ + C0->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + if ((C1 = X->child[1]) != 0) {\ + if (RTCHECK(ok_address(M, C1))) {\ + R->child[1] = C1;\ + C1->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ +} + +/* Relays to large vs small bin operations */ + +#define insert_chunk(M, P, S)\ + if (is_small(S)) insert_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } + +#define unlink_chunk(M, P, S)\ + if (is_small(S)) unlink_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } + + +/* Relays to internal calls to malloc/free from realloc, memalign etc */ + +#if ONLY_MSPACES +#define internal_malloc(m, b) mspace_malloc(m, b) +#define internal_free(m, mem) mspace_free(m,mem); +#else /* ONLY_MSPACES */ +#if MSPACES +#define internal_malloc(m, b)\ + (m == gm)? dlmalloc(b) : mspace_malloc(m, b) +#define internal_free(m, mem)\ + if (m == gm) dlfree(mem); else mspace_free(m,mem); +#else /* MSPACES */ +#define internal_malloc(m, b) dlmalloc(b) +#define internal_free(m, mem) dlfree(mem) +#endif /* MSPACES */ +#endif /* ONLY_MSPACES */ + +/* ----------------------- Direct-mmapping chunks ----------------------- */ + +/* + Directly mmapped chunks are set up with an offset to the start of + the mmapped region stored in the prev_foot field of the chunk. This + allows reconstruction of the required argument to MUNMAP when freed, + and also allows adjustment of the returned chunk to meet alignment + requirements (especially in memalign). There is also enough space + allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain + the PINUSE bit so frees can be checked. +*/ + +/* Malloc using mmap */ +static void* mmap_alloc(mstate m, size_t nb) { + size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + if (mmsize > nb) { /* Check for wrap around 0 */ + char* mm = (char*)(DIRECT_MMAP(mmsize)); + if (mm != CMFAIL) { + size_t offset = align_offset(chunk2mem(mm)); + size_t psize = mmsize - offset - MMAP_FOOT_PAD; + mchunkptr p = (mchunkptr)(mm + offset); + p->prev_foot = offset | IS_MMAPPED_BIT; + (p)->head = (psize|CINUSE_BIT); + mark_inuse_foot(m, p, psize); + chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; + + if (mm < m->least_addr) + m->least_addr = mm; + if ((m->footprint += mmsize) > m->max_footprint) + m->max_footprint = m->footprint; + assert(is_aligned(chunk2mem(p))); + check_mmapped_chunk(m, p); + return chunk2mem(p); + } + } + return 0; +} + +/* Realloc using mmap */ +static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) { + size_t oldsize = chunksize(oldp); + if (is_small(nb)) /* Can't shrink mmap regions below small size */ + return 0; + /* Keep old chunk if big enough but not too big */ + if (oldsize >= nb + SIZE_T_SIZE && + (oldsize - nb) <= (mparams.granularity << 1)) + return oldp; + else { + size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT; + size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; + size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES + + CHUNK_ALIGN_MASK); + char* cp = (char*)CALL_MREMAP((char*)oldp - offset, + oldmmsize, newmmsize, 1); + if (cp != CMFAIL) { + mchunkptr newp = (mchunkptr)(cp + offset); + size_t psize = newmmsize - offset - MMAP_FOOT_PAD; + newp->head = (psize|CINUSE_BIT); + mark_inuse_foot(m, newp, psize); + chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; + + if (cp < m->least_addr) + m->least_addr = cp; + if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) + m->max_footprint = m->footprint; + check_mmapped_chunk(m, newp); + return newp; + } + } + return 0; +} + +/* -------------------------- mspace management -------------------------- */ + +/* Initialize top chunk and its size */ +static void init_top(mstate m, mchunkptr p, size_t psize) { + /* Ensure alignment */ + size_t offset = align_offset(chunk2mem(p)); + p = (mchunkptr)((char*)p + offset); + psize -= offset; + + m->top = p; + m->topsize = psize; + p->head = psize | PINUSE_BIT; + /* set size of fake trailing chunk holding overhead space only once */ + chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; + m->trim_check = mparams.trim_threshold; /* reset on each update */ +} + +/* Initialize bins for a new mstate that is otherwise zeroed out */ +static void init_bins(mstate m) { + /* Establish circular links for smallbins */ + bindex_t i; + for (i = 0; i < NSMALLBINS; ++i) { + sbinptr bin = smallbin_at(m,i); + bin->fd = bin->bk = bin; + } +} + +#if PROCEED_ON_ERROR + +/* default corruption action */ +static void reset_on_error(mstate m) { + int i; + ++malloc_corruption_error_count; + /* Reinitialize fields to forget about all memory */ + m->smallbins = m->treebins = 0; + m->dvsize = m->topsize = 0; + m->seg.base = 0; + m->seg.size = 0; + m->seg.next = 0; + m->top = m->dv = 0; + for (i = 0; i < NTREEBINS; ++i) + *treebin_at(m, i) = 0; + init_bins(m); +} +#endif /* PROCEED_ON_ERROR */ + +/* Allocate chunk and prepend remainder with chunk in successor base. */ +static void* prepend_alloc(mstate m, char* newbase, char* oldbase, + size_t nb) { + mchunkptr p = align_as_chunk(newbase); + mchunkptr oldfirst = align_as_chunk(oldbase); + size_t psize = (char*)oldfirst - (char*)p; + mchunkptr q = chunk_plus_offset(p, nb); + size_t qsize = psize - nb; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + + assert((char*)oldfirst > (char*)q); + assert(pinuse(oldfirst)); + assert(qsize >= MIN_CHUNK_SIZE); + + /* consolidate remainder with first chunk of old base */ + if (oldfirst == m->top) { + size_t tsize = m->topsize += qsize; + m->top = q; + q->head = tsize | PINUSE_BIT; + check_top_chunk(m, q); + } + else if (oldfirst == m->dv) { + size_t dsize = m->dvsize += qsize; + m->dv = q; + set_size_and_pinuse_of_free_chunk(q, dsize); + } + else { + if (!cinuse(oldfirst)) { + size_t nsize = chunksize(oldfirst); + unlink_chunk(m, oldfirst, nsize); + oldfirst = chunk_plus_offset(oldfirst, nsize); + qsize += nsize; + } + set_free_with_pinuse(q, qsize, oldfirst); + insert_chunk(m, q, qsize); + check_free_chunk(m, q); + } + + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); +} + + +/* Add a segment to hold a new noncontiguous region */ +static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { + /* Determine locations and sizes of segment, fenceposts, old top */ + char* old_top = (char*)m->top; + msegmentptr oldsp = segment_holding(m, old_top); + char* old_end = oldsp->base + oldsp->size; + size_t ssize = pad_request(sizeof(struct malloc_segment)); + char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + size_t offset = align_offset(chunk2mem(rawsp)); + char* asp = rawsp + offset; + char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; + mchunkptr sp = (mchunkptr)csp; + msegmentptr ss = (msegmentptr)(chunk2mem(sp)); + mchunkptr tnext = chunk_plus_offset(sp, ssize); + mchunkptr p = tnext; + int nfences = 0; + + /* reset top to new space */ + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + + /* Set up segment record */ + assert(is_aligned(ss)); + set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); + *ss = m->seg; /* Push current record */ + m->seg.base = tbase; + m->seg.size = tsize; + (void)set_segment_flags(&m->seg, mmapped); + m->seg.next = ss; + + /* Insert trailing fenceposts */ + for (;;) { + mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); + p->head = FENCEPOST_HEAD; + ++nfences; + if ((char*)(&(nextp->head)) < old_end) + p = nextp; + else + break; + } + assert(nfences >= 2); + + /* Insert the rest of old top into a bin as an ordinary free chunk */ + if (csp != old_top) { + mchunkptr q = (mchunkptr)old_top; + size_t psize = csp - old_top; + mchunkptr tn = chunk_plus_offset(q, psize); + set_free_with_pinuse(q, psize, tn); + insert_chunk(m, q, psize); + } + + check_top_chunk(m, m->top); +} + +/* -------------------------- System allocation -------------------------- */ + +/* Get memory from system using MORECORE or MMAP */ +static void* sys_alloc(mstate m, size_t nb) { + char* tbase = CMFAIL; + size_t tsize = 0; + flag_t mmap_flag = 0; + + init_mparams(); + + /* Directly map large chunks */ + if (use_mmap(m) && nb >= mparams.mmap_threshold) { + void* mem = mmap_alloc(m, nb); + if (mem != 0) + return mem; + } + + /* + Try getting memory in any of three ways (in most-preferred to + least-preferred order): + 1. A call to MORECORE that can normally contiguously extend memory. + (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or + or main space is mmapped or a previous contiguous call failed) + 2. A call to MMAP new space (disabled if not HAVE_MMAP). + Note that under the default settings, if MORECORE is unable to + fulfill a request, and HAVE_MMAP is true, then mmap is + used as a noncontiguous system allocator. This is a useful backup + strategy for systems with holes in address spaces -- in this case + sbrk cannot contiguously expand the heap, but mmap may be able to + find space. + 3. A call to MORECORE that cannot usually contiguously extend memory. + (disabled if not HAVE_MORECORE) + */ + + if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { + char* br = CMFAIL; + msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); + size_t asize = 0; + ACQUIRE_MORECORE_LOCK(); + + if (ss == 0) { /* First time through or recovery */ + char* base = (char*)CALL_MORECORE(0); + if (base != CMFAIL) { + asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); + /* Adjust to end on a page boundary */ + if (!is_page_aligned(base)) + asize += (page_align((size_t)base) - (size_t)base); + /* Can't call MORECORE if size is negative when treated as signed */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == base) { + tbase = base; + tsize = asize; + } + } + } + else { + /* Subtract out existing available top space from MORECORE request. */ + asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE); + /* Use mem here only if it did continuously extend old space */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { + tbase = br; + tsize = asize; + } + } + + if (tbase == CMFAIL) { /* Cope with partial failure */ + if (br != CMFAIL) { /* Try to use/extend the space we did get */ + if (asize < HALF_MAX_SIZE_T && + asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { + size_t esize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize); + if (esize < HALF_MAX_SIZE_T) { + char* end = (char*)CALL_MORECORE(esize); + if (end != CMFAIL) + asize += esize; + else { /* Can't use; try to release */ + (void)CALL_MORECORE(-asize); + br = CMFAIL; + } + } + } + } + if (br != CMFAIL) { /* Use the space we did get */ + tbase = br; + tsize = asize; + } + else + disable_contiguous(m); /* Don't try contiguous path in the future */ + } + + RELEASE_MORECORE_LOCK(); + } + + if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ + size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE; + size_t rsize = granularity_align(req); + if (rsize > nb) { /* Fail if wraps around zero */ + char* mp = (char*)(CALL_MMAP(rsize)); + if (mp != CMFAIL) { + tbase = mp; + tsize = rsize; + mmap_flag = IS_MMAPPED_BIT; + } + } + } + + if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ + size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); + if (asize < HALF_MAX_SIZE_T) { + char* br = CMFAIL; + char* end = CMFAIL; + ACQUIRE_MORECORE_LOCK(); + br = (char*)(CALL_MORECORE(asize)); + end = (char*)(CALL_MORECORE(0)); + RELEASE_MORECORE_LOCK(); + if (br != CMFAIL && end != CMFAIL && br < end) { + size_t ssize = end - br; + if (ssize > nb + TOP_FOOT_SIZE) { + tbase = br; + tsize = ssize; + } + } + } + } + + if (tbase != CMFAIL) { + + if ((m->footprint += tsize) > m->max_footprint) + m->max_footprint = m->footprint; + + if (!is_initialized(m)) { /* first-time initialization */ + m->seg.base = m->least_addr = tbase; + m->seg.size = tsize; + (void)set_segment_flags(&m->seg, mmap_flag); + m->magic = mparams.magic; + init_bins(m); + if (is_global(m)) + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + else { + /* Offset top by embedded malloc_state */ + mchunkptr mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); + } + } + + else { + /* Try to merge with an existing segment */ + msegmentptr sp = &m->seg; + while (sp != 0 && tbase != sp->base + sp->size) + sp = sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + check_segment_merge(sp, tbase, tsize) && + (get_segment_flags(sp) & IS_MMAPPED_BIT) == mmap_flag && + segment_holds(sp, m->top)) { /* append */ + sp->size += tsize; + init_top(m, m->top, m->topsize + tsize); + } + else { + if (tbase < m->least_addr) + m->least_addr = tbase; + sp = &m->seg; + while (sp != 0 && sp->base != tbase + tsize) + sp = sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + check_segment_merge(sp, tbase, tsize) && + (get_segment_flags(sp) & IS_MMAPPED_BIT) == mmap_flag) { + char* oldbase = sp->base; + sp->base = tbase; + sp->size += tsize; + return prepend_alloc(m, tbase, oldbase, nb); + } + else + add_segment(m, tbase, tsize, mmap_flag); + } + } + + if (nb < m->topsize) { /* Allocate from new or extended top space */ + size_t rsize = m->topsize -= nb; + mchunkptr p = m->top; + mchunkptr r = m->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + check_top_chunk(m, m->top); + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); + } + } + + MALLOC_FAILURE_ACTION; + return 0; +} + +/* ----------------------- system deallocation -------------------------- */ + +/* Unmap and unlink any mmapped segments that don't contain used chunks */ +static size_t release_unused_segments(mstate m) { + size_t released = 0; + msegmentptr pred = &m->seg; + msegmentptr sp = pred->next; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + msegmentptr next = sp->next; + if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { + mchunkptr p = align_as_chunk(base); + size_t psize = chunksize(p); + /* Can unmap if first chunk holds entire segment and not pinned */ + if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { + tchunkptr tp = (tchunkptr)p; + assert(segment_holds(sp, (char*)sp)); + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } + else { + unlink_large_chunk(m, tp); + } + if (CALL_MUNMAP(base, size) == 0) { + released += size; + m->footprint -= size; + /* unlink obsoleted record */ + sp = pred; + sp->next = next; + } + else { /* back out if cannot unmap */ + insert_large_chunk(m, tp, psize); + } + } + } + pred = sp; + sp = next; + } + return released; +} + +static int sys_trim(mstate m, size_t pad) { + size_t released = 0; + if (pad < MAX_REQUEST && is_initialized(m)) { + pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ + + if (m->topsize > pad) { + /* Shrink top space in granularity-size units, keeping at least one */ + size_t unit = mparams.granularity; + size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - + SIZE_T_ONE) * unit; + msegmentptr sp = segment_holding(m, (char*)m->top); + + if (!is_extern_segment(sp)) { + if (is_mmapped_segment(sp)) { + if (HAVE_MMAP && + sp->size >= extra && + !has_segment_link(m, sp)) { /* can't shrink if pinned */ + size_t newsize = sp->size - extra; + /* Prefer mremap, fall back to munmap */ + if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || + (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { + released = extra; + } + } + } + else if (HAVE_MORECORE) { + if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ + extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; + ACQUIRE_MORECORE_LOCK(); + { + /* Make sure end of memory is where we last set it. */ + char* old_br = (char*)(CALL_MORECORE(0)); + if (old_br == sp->base + sp->size) { + char* rel_br = (char*)(CALL_MORECORE(-extra)); + char* new_br = (char*)(CALL_MORECORE(0)); + if (rel_br != CMFAIL && new_br < old_br) + released = old_br - new_br; + } + } + RELEASE_MORECORE_LOCK(); + } + } + + if (released != 0) { + sp->size -= released; + m->footprint -= released; + init_top(m, m->top, m->topsize - released); + check_top_chunk(m, m->top); + } + } + + /* Unmap any unused mmapped segments */ + if (HAVE_MMAP) + released += release_unused_segments(m); + + /* On failure, disable autotrim to avoid repeated failed future calls */ + if (released == 0) + m->trim_check = MAX_SIZE_T; + } + + return (released != 0)? 1 : 0; +} + +/* ---------------------------- malloc support --------------------------- */ + +/* allocate a large request from the best fitting chunk in a treebin */ +static void* tmalloc_large(mstate m, size_t nb) { + tchunkptr v = 0; + size_t rsize = -nb; /* Unsigned negation */ + tchunkptr t; + bindex_t idx; + compute_tree_index(nb, idx); + + if ((t = *treebin_at(m, idx)) != 0) { + /* Traverse tree for this bin looking for node with size == nb */ + size_t sizebits = nb << leftshift_for_tree_index(idx); + tchunkptr rst = 0; /* The deepest untaken right subtree */ + for (;;) { + tchunkptr rt; + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + v = t; + if ((rsize = trem) == 0) + break; + } + rt = t->child[1]; + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + if (rt != 0 && rt != t) + rst = rt; + if (t == 0) { + t = rst; /* set t to least subtree holding sizes > nb */ + break; + } + sizebits <<= 1; + } + } + + if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ + binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; + if (leftbits != 0) { + bindex_t i; + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + t = *treebin_at(m, i); + } + } + + while (t != 0) { /* find smallest of tree or subtree */ + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + t = leftmost_child(t); + } + + /* If dv is a better fit, return 0 so malloc will use it */ + if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { + if (RTCHECK(ok_address(m, v))) { /* split */ + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + insert_chunk(m, r, rsize); + } + return chunk2mem(v); + } + } + CORRUPTION_ERROR_ACTION(m); + } + return 0; +} + +/* allocate a small request from the best fitting chunk in a treebin */ +static void* tmalloc_small(mstate m, size_t nb) { + tchunkptr t, v; + size_t rsize; + bindex_t i; + binmap_t leastbit = least_bit(m->treemap); + compute_bit2idx(leastbit, i); + + v = t = *treebin_at(m, i); + rsize = chunksize(t) - nb; + + while ((t = leftmost_child(t)) != 0) { + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + } + + if (RTCHECK(ok_address(m, v))) { + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(m, r, rsize); + } + return chunk2mem(v); + } + } + + CORRUPTION_ERROR_ACTION(m); + return 0; +} + +/* --------------------------- realloc support --------------------------- */ + +static void* internal_realloc(mstate m, void* oldmem, size_t bytes) { + if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + return 0; + } + if (!PREACTION(m)) { + mchunkptr oldp = mem2chunk(oldmem); + size_t oldsize = chunksize(oldp); + mchunkptr next = chunk_plus_offset(oldp, oldsize); + mchunkptr newp = 0; + void* extra = 0; + + /* Try to either shrink or extend into top. Else malloc-copy-free */ + + if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) && + ok_next(oldp, next) && ok_pinuse(next))) { + size_t nb = request2size(bytes); + if (is_mmapped(oldp)) + newp = mmap_resize(m, oldp, nb); + else if (oldsize >= nb) { /* already big enough */ + size_t rsize = oldsize - nb; + newp = oldp; + if (rsize >= MIN_CHUNK_SIZE) { + mchunkptr remainder = chunk_plus_offset(newp, nb); + set_inuse(m, newp, nb); + set_inuse(m, remainder, rsize); + extra = chunk2mem(remainder); + } + } + else if (next == m->top && oldsize + m->topsize > nb) { + /* Expand into top */ + size_t newsize = oldsize + m->topsize; + size_t newtopsize = newsize - nb; + mchunkptr newtop = chunk_plus_offset(oldp, nb); + set_inuse(m, oldp, nb); + newtop->head = newtopsize |PINUSE_BIT; + m->top = newtop; + m->topsize = newtopsize; + newp = oldp; + } + } + else { + USAGE_ERROR_ACTION(m, oldmem); + POSTACTION(m); + return 0; + } + + POSTACTION(m); + + if (newp != 0) { + if (extra != 0) { + internal_free(m, extra); + } + check_inuse_chunk(m, newp); + return chunk2mem(newp); + } + else { + void* newmem = internal_malloc(m, bytes); + if (newmem != 0) { + size_t oc = oldsize - overhead_for(oldp); + memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); + internal_free(m, oldmem); + } + return newmem; + } + } + return 0; +} + +/* --------------------------- memalign support -------------------------- */ + +static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { + if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ + return internal_malloc(m, bytes); + if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ + alignment = MIN_CHUNK_SIZE; + if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ + size_t a = MALLOC_ALIGNMENT << 1; + while (a < alignment) a <<= 1; + alignment = a; + } + + if (bytes >= MAX_REQUEST - alignment) { + if (m != 0) { /* Test isn't needed but avoids compiler warning */ + MALLOC_FAILURE_ACTION; + } + } + else { + size_t nb = request2size(bytes); + size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; + char* mem = (char*)internal_malloc(m, req); + if (mem != 0) { + void* leader = 0; + void* trailer = 0; + mchunkptr p = mem2chunk(mem); + + if (PREACTION(m)) return 0; + if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */ + /* + Find an aligned spot inside chunk. Since we need to give + back leading space in a chunk of at least MIN_CHUNK_SIZE, if + the first calculation places us at a spot with less than + MIN_CHUNK_SIZE leader, we can move to the next aligned spot. + We've allocated enough total room so that this is always + possible. + */ + char* br = (char*)mem2chunk((size_t)(((size_t)(mem + + alignment - + SIZE_T_ONE)) & + -alignment)); + char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? + br : br+alignment; + mchunkptr newp = (mchunkptr)pos; + size_t leadsize = pos - (char*)(p); + size_t newsize = chunksize(p) - leadsize; + + if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ + newp->prev_foot = p->prev_foot + leadsize; + newp->head = (newsize|CINUSE_BIT); + } + else { /* Otherwise, give back leader, use the rest */ + set_inuse(m, newp, newsize); + set_inuse(m, p, leadsize); + leader = chunk2mem(p); + } + p = newp; + } + + /* Give back spare room at the end */ + if (!is_mmapped(p)) { + size_t size = chunksize(p); + if (size > nb + MIN_CHUNK_SIZE) { + size_t remainder_size = size - nb; + mchunkptr remainder = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, remainder, remainder_size); + trailer = chunk2mem(remainder); + } + } + + assert (chunksize(p) >= nb); + assert((((size_t)(chunk2mem(p))) % alignment) == 0); + check_inuse_chunk(m, p); + POSTACTION(m); + if (leader != 0) { + internal_free(m, leader); + } + if (trailer != 0) { + internal_free(m, trailer); + } + return chunk2mem(p); + } + } + return 0; +} + +/* ------------------------ comalloc/coalloc support --------------------- */ + +static void** ialloc(mstate m, + size_t n_elements, + size_t* sizes, + int opts, + void* chunks[]) { + /* + This provides common support for independent_X routines, handling + all of the combinations that can result. + + The opts arg has: + bit 0 set if all elements are same size (using sizes[0]) + bit 1 set if elements should be zeroed + */ + + size_t element_size; /* chunksize of each element, if all same */ + size_t contents_size; /* total size of elements */ + size_t array_size; /* request size of pointer array */ + void* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + size_t remainder_size; /* remaining bytes while splitting */ + void** marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + flag_t was_enabled; /* to disable mmap */ + size_t size; + size_t i; + + /* compute array length, if needed */ + if (chunks != 0) { + if (n_elements == 0) + return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } + else { + /* if empty req, must still return chunk representing empty array */ + if (n_elements == 0) + return (void**)internal_malloc(m, 0); + marray = 0; + array_size = request2size(n_elements * (sizeof(void*))); + } + + /* compute total element size */ + if (opts & 0x1) { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } + else { /* add up all the sizes */ + element_size = 0; + contents_size = 0; + for (i = 0; i != n_elements; ++i) + contents_size += request2size(sizes[i]); + } + + size = contents_size + array_size; + + /* + Allocate the aggregate chunk. First disable direct-mmapping so + malloc won't use it, since we would not be able to later + free/realloc space internal to a segregated mmap region. + */ + was_enabled = use_mmap(m); + disable_mmap(m); + mem = internal_malloc(m, size - CHUNK_OVERHEAD); + if (was_enabled) + enable_mmap(m); + if (mem == 0) + return 0; + + if (PREACTION(m)) return 0; + p = mem2chunk(mem); + remainder_size = chunksize(p); + + assert(!is_mmapped(p)); + + if (opts & 0x2) { /* optionally clear the elements */ + memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); + } + + /* If not provided, allocate the pointer array as final part of chunk */ + if (marray == 0) { + size_t array_chunk_size; + array_chunk = chunk_plus_offset(p, contents_size); + array_chunk_size = remainder_size - contents_size; + marray = (void**) (chunk2mem(array_chunk)); + set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); + remainder_size = contents_size; + } + + /* split out elements */ + for (i = 0; ; ++i) { + marray[i] = chunk2mem(p); + if (i != n_elements-1) { + if (element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_size_and_pinuse_of_inuse_chunk(m, p, size); + p = chunk_plus_offset(p, size); + } + else { /* the final element absorbs any overallocation slop */ + set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); + break; + } + } + +#if DEBUG + if (marray != chunks) { + /* final element must have exactly exhausted chunk */ + if (element_size != 0) { + assert(remainder_size == element_size); + } + else { + assert(remainder_size == request2size(sizes[i])); + } + check_inuse_chunk(m, mem2chunk(marray)); + } + for (i = 0; i != n_elements; ++i) + check_inuse_chunk(m, mem2chunk(marray[i])); + +#endif /* DEBUG */ + + POSTACTION(m); + return marray; +} + + +/* -------------------------- public routines ---------------------------- */ + +#if !ONLY_MSPACES + +void* dlmalloc(size_t bytes) { + /* + Basic algorithm: + If a small request (< 256 bytes minus per-chunk overhead): + 1. If one exists, use a remainderless chunk in associated smallbin. + (Remainderless means that there are too few excess bytes to + represent as a chunk.) + 2. If it is big enough, use the dv chunk, which is normally the + chunk adjacent to the one used for the most recent small request. + 3. If one exists, split the smallest available chunk in a bin, + saving remainder in dv. + 4. If it is big enough, use the top chunk. + 5. If available, get memory from system and use it + Otherwise, for a large request: + 1. Find the smallest available binned chunk that fits, and use it + if it is better fitting than dv chunk, splitting if necessary. + 2. If better fitting than any binned chunk, use the dv chunk. + 3. If it is big enough, use the top chunk. + 4. If request size >= mmap threshold, try to directly mmap this chunk. + 5. If available, get memory from system and use it + + The ugly goto's here ensure that postaction occurs along all paths. + */ + + if (!PREACTION(gm)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = gm->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(gm, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(gm, b, p, idx); + set_inuse_and_pinuse(gm, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb > gm->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(gm, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(gm, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(gm, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(gm, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + + if (nb <= gm->dvsize) { + size_t rsize = gm->dvsize - nb; + mchunkptr p = gm->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = gm->dv = chunk_plus_offset(p, nb); + gm->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + } + else { /* exhaust dv */ + size_t dvs = gm->dvsize; + gm->dvsize = 0; + gm->dv = 0; + set_inuse_and_pinuse(gm, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb < gm->topsize) { /* Split top */ + size_t rsize = gm->topsize -= nb; + mchunkptr p = gm->top; + mchunkptr r = gm->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + mem = chunk2mem(p); + check_top_chunk(gm, gm->top); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + mem = sys_alloc(gm, nb); + + postaction: + POSTACTION(gm); + return mem; + } + + return 0; +} + +void dlfree(void* mem) { + /* + Consolidate freed chunks with preceding or succeeding bordering + free chunks, if they exist, and then place in a bin. Intermixed + with special cases for top, dv, mmapped chunks, and usage errors. + */ + + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } +#else /* FOOTERS */ +#define fm gm +#endif /* FOOTERS */ + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if ((prevsize & IS_MMAPPED_BIT) != 0) { + prevsize &= ~IS_MMAPPED_BIT; + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + insert_chunk(fm, p, psize); + check_free_chunk(fm, p); + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +#if !FOOTERS +#undef fm +#endif /* FOOTERS */ +} + +void* dlcalloc(size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = dlmalloc(req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; +} + +void* dlrealloc(void* oldmem, size_t bytes) { + if (oldmem == 0) + return dlmalloc(bytes); +#ifdef REALLOC_ZERO_BYTES_FREES + if (bytes == 0) { + dlfree(oldmem); + return 0; + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { +#if ! FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(mem2chunk(oldmem)); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + return internal_realloc(m, oldmem, bytes); + } +} + +void* dlmemalign(size_t alignment, size_t bytes) { + return internal_memalign(gm, alignment, bytes); +} + +void** dlindependent_calloc(size_t n_elements, size_t elem_size, + void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + return ialloc(gm, n_elements, &sz, 3, chunks); +} + +void** dlindependent_comalloc(size_t n_elements, size_t sizes[], + void* chunks[]) { + return ialloc(gm, n_elements, sizes, 0, chunks); +} + +void* dlvalloc(size_t bytes) { + size_t pagesz; + init_mparams(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, bytes); +} + +void* dlpvalloc(size_t bytes) { + size_t pagesz; + init_mparams(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); +} + +int dlmalloc_trim(size_t pad) { + int result = 0; + if (!PREACTION(gm)) { + result = sys_trim(gm, pad); + POSTACTION(gm); + } + return result; +} + +size_t dlmalloc_footprint(void) { + return gm->footprint; +} + +size_t dlmalloc_max_footprint(void) { + return gm->max_footprint; +} + +#if !NO_MALLINFO +struct mallinfo dlmallinfo(void) { + return internal_mallinfo(gm); +} +#endif /* NO_MALLINFO */ + +void dlmalloc_stats() { + internal_malloc_stats(gm); +} + +size_t dlmalloc_usable_size(void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (cinuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; +} + +int dlmallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +#endif /* !ONLY_MSPACES */ + +/* ----------------------------- user mspaces ---------------------------- */ + +#if MSPACES + +static mstate init_user_mstate(char* tbase, size_t tsize) { + size_t msize = pad_request(sizeof(struct malloc_state)); + mchunkptr mn; + mchunkptr msp = align_as_chunk(tbase); + mstate m = (mstate)(chunk2mem(msp)); + memset(m, 0, msize); + INITIAL_LOCK(&m->mutex); + msp->head = (msize|PINUSE_BIT|CINUSE_BIT); + m->seg.base = m->least_addr = tbase; + m->seg.size = m->footprint = m->max_footprint = tsize; + m->magic = mparams.magic; + m->mflags = mparams.default_mflags; + disable_contiguous(m); + init_bins(m); + mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); + check_top_chunk(m, m->top); + return m; +} + +mspace create_mspace(size_t capacity, int locked) { + mstate m = 0; + size_t msize = pad_request(sizeof(struct malloc_state)); + init_mparams(); /* Ensure pagesize etc initialized */ + + if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + size_t rs = ((capacity == 0)? mparams.granularity : + (capacity + TOP_FOOT_SIZE + msize)); + size_t tsize = granularity_align(rs); + char* tbase = (char*)(CALL_MMAP(tsize)); + if (tbase != CMFAIL) { + m = init_user_mstate(tbase, tsize); + set_segment_flags(&m->seg, IS_MMAPPED_BIT); + set_lock(m, locked); + } + } + return (mspace)m; +} + +mspace create_mspace_with_base(void* base, size_t capacity, int locked) { + mstate m = 0; + size_t msize = pad_request(sizeof(struct malloc_state)); + init_mparams(); /* Ensure pagesize etc initialized */ + + if (capacity > msize + TOP_FOOT_SIZE && + capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + m = init_user_mstate((char*)base, capacity); + set_segment_flags(&m->seg, EXTERN_BIT); + set_lock(m, locked); + } + return (mspace)m; +} + +size_t destroy_mspace(mspace msp) { + size_t freed = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + msegmentptr sp = &ms->seg; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + flag_t flag = get_segment_flags(sp); + sp = sp->next; + if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) && + CALL_MUNMAP(base, size) == 0) + freed += size; + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return freed; +} + +/* + mspace versions of routines are near-clones of the global + versions. This is not so nice but better than the alternatives. +*/ + + +void* mspace_malloc(mspace msp, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (!PREACTION(ms)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = ms->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(ms, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(ms, b, p, idx); + set_inuse_and_pinuse(ms, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb > ms->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(ms, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(ms, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(ms, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(ms, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + + if (nb <= ms->dvsize) { + size_t rsize = ms->dvsize - nb; + mchunkptr p = ms->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = ms->dv = chunk_plus_offset(p, nb); + ms->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + } + else { /* exhaust dv */ + size_t dvs = ms->dvsize; + ms->dvsize = 0; + ms->dv = 0; + set_inuse_and_pinuse(ms, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb < ms->topsize) { /* Split top */ + size_t rsize = ms->topsize -= nb; + mchunkptr p = ms->top; + mchunkptr r = ms->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + mem = chunk2mem(p); + check_top_chunk(ms, ms->top); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + mem = sys_alloc(ms, nb); + + postaction: + POSTACTION(ms); + return mem; + } + + return 0; +} + +void mspace_free(mspace msp, void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); +#else /* FOOTERS */ + mstate fm = (mstate)msp; +#endif /* FOOTERS */ + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if ((prevsize & IS_MMAPPED_BIT) != 0) { + prevsize &= ~IS_MMAPPED_BIT; + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + insert_chunk(fm, p, psize); + check_free_chunk(fm, p); + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +} + +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = internal_malloc(ms, req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; +} + +void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { + if (oldmem == 0) + return mspace_malloc(msp, bytes); +#ifdef REALLOC_ZERO_BYTES_FREES + if (bytes == 0) { + mspace_free(msp, oldmem); + return 0; + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { +#if FOOTERS + mchunkptr p = mem2chunk(oldmem); + mstate ms = get_mstate_for(p); +#else /* FOOTERS */ + mstate ms = (mstate)msp; +#endif /* FOOTERS */ + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return internal_realloc(ms, oldmem, bytes); + } +} + +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return internal_memalign(ms, alignment, bytes); +} + +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, &sz, 3, chunks); +} + +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, sizes, 0, chunks); +} + +int mspace_trim(mspace msp, size_t pad) { + int result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (!PREACTION(ms)) { + result = sys_trim(ms, pad); + POSTACTION(ms); + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +void mspace_malloc_stats(mspace msp) { + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + internal_malloc_stats(ms); + } + else { + USAGE_ERROR_ACTION(ms,ms); + } +} + +size_t mspace_footprint(mspace msp) { + size_t result; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->footprint; + } + USAGE_ERROR_ACTION(ms,ms); + return result; +} + + +size_t mspace_max_footprint(mspace msp) { + size_t result; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->max_footprint; + } + USAGE_ERROR_ACTION(ms,ms); + return result; +} + + +#if !NO_MALLINFO +struct mallinfo mspace_mallinfo(mspace msp) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + } + return internal_mallinfo(ms); +} +#endif /* NO_MALLINFO */ + +int mspace_mallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +#endif /* MSPACES */ + +/* -------------------- Alternative MORECORE functions ------------------- */ + +/* + Guidelines for creating a custom version of MORECORE: + + * For best performance, MORECORE should allocate in multiples of pagesize. + * MORECORE may allocate more memory than requested. (Or even less, + but this will usually result in a malloc failure.) + * MORECORE must not allocate memory when given argument zero, but + instead return one past the end address of memory from previous + nonzero call. + * For best performance, consecutive calls to MORECORE with positive + arguments should return increasing addresses, indicating that + space has been contiguously extended. + * Even though consecutive calls to MORECORE need not return contiguous + addresses, it must be OK for malloc'ed chunks to span multiple + regions in those cases where they do happen to be contiguous. + * MORECORE need not handle negative arguments -- it may instead + just return MFAIL when given negative arguments. + Negative arguments are always multiples of pagesize. MORECORE + must not misinterpret negative args as large positive unsigned + args. You can suppress all such calls from even occurring by defining + MORECORE_CANNOT_TRIM, + + As an example alternative MORECORE, here is a custom allocator + kindly contributed for pre-OSX macOS. It uses virtually but not + necessarily physically contiguous non-paged memory (locked in, + present and won't get swapped out). You can use it by uncommenting + this section, adding some #includes, and setting up the appropriate + defines above: + + #define MORECORE osMoreCore + + There is also a shutdown routine that should somehow be called for + cleanup upon program exit. + + #define MAX_POOL_ENTRIES 100 + #define MINIMUM_MORECORE_SIZE (64 * 1024U) + static int next_os_pool; + void *our_os_pools[MAX_POOL_ENTRIES]; + + void *osMoreCore(int size) + { + void *ptr = 0; + static void *sbrk_top = 0; + + if (size > 0) + { + if (size < MINIMUM_MORECORE_SIZE) + size = MINIMUM_MORECORE_SIZE; + if (CurrentExecutionLevel() == kTaskLevel) + ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); + if (ptr == 0) + { + return (void *) MFAIL; + } + // save ptrs so they can be freed during cleanup + our_os_pools[next_os_pool] = ptr; + next_os_pool++; + ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); + sbrk_top = (char *) ptr + size; + return ptr; + } + else if (size < 0) + { + // we don't currently support shrink behavior + return (void *) MFAIL; + } + else + { + return sbrk_top; + } + } + + // cleanup any allocated memory pools + // called as last thing before shutting down driver + + void osCleanupMem(void) + { + void **ptr; + + for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) + if (*ptr) + { + PoolDeallocate(*ptr); + *ptr = 0; + } + } + +*/ + + +/* ----------------------------------------------------------------------- +History: + V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) + * Add max_footprint functions + * Ensure all appropriate literals are size_t + * Fix conditional compilation problem for some #define settings + * Avoid concatenating segments with the one provided + in create_mspace_with_base + * Rename some variables to avoid compiler shadowing warnings + * Use explicit lock initialization. + * Better handling of sbrk interference. + * Simplify and fix segment insertion, trimming and mspace_destroy + * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x + * Thanks especially to Dennis Flanagan for help on these. + + V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) + * Fix memalign brace error. + + V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) + * Fix improper #endif nesting in C++ + * Add explicit casts needed for C++ + + V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) + * Use trees for large bins + * Support mspaces + * Use segments to unify sbrk-based and mmap-based system allocation, + removing need for emulation on most platforms without sbrk. + * Default safety checks + * Optional footer checks. Thanks to William Robertson for the idea. + * Internal code refactoring + * Incorporate suggestions and platform-specific changes. + Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, + Aaron Bachmann, Emery Berger, and others. + * Speed up non-fastbin processing enough to remove fastbins. + * Remove useless cfree() to avoid conflicts with other apps. + * Remove internal memcpy, memset. Compilers handle builtins better. + * Remove some options that no one ever used and rename others. + + V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) + * Fix malloc_state bitmap array misdeclaration + + V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) + * Allow tuning of FIRST_SORTED_BIN_SIZE + * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. + * Better detection and support for non-contiguousness of MORECORE. + Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger + * Bypass most of malloc if no frees. Thanks To Emery Berger. + * Fix freeing of old top non-contiguous chunk im sysmalloc. + * Raised default trim and map thresholds to 256K. + * Fix mmap-related #defines. Thanks to Lubos Lunak. + * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. + * Branch-free bin calculation + * Default trim and mmap thresholds now 256K. + + V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) + * Introduce independent_comalloc and independent_calloc. + Thanks to Michael Pachos for motivation and help. + * Make optional .h file available + * Allow > 2GB requests on 32bit systems. + * new WIN32 sbrk, mmap, munmap, lock code from . + Thanks also to Andreas Mueller , + and Anonymous. + * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for + helping test this.) + * memalign: check alignment arg + * realloc: don't try to shift chunks backwards, since this + leads to more fragmentation in some programs and doesn't + seem to help in any others. + * Collect all cases in malloc requiring system memory into sysmalloc + * Use mmap as backup to sbrk + * Place all internal state in malloc_state + * Introduce fastbins (although similar to 2.5.1) + * Many minor tunings and cosmetic improvements + * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK + * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS + Thanks to Tony E. Bennett and others. + * Include errno.h to support default failure action. + + V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) + * return null for negative arguments + * Added Several WIN32 cleanups from Martin C. Fong + * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' + (e.g. WIN32 platforms) + * Cleanup header file inclusion for WIN32 platforms + * Cleanup code to avoid Microsoft Visual C++ compiler complaints + * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing + memory allocation routines + * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) + * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to + usage of 'assert' in non-WIN32 code + * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to + avoid infinite loop + * Always call 'fREe()' rather than 'free()' + + V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) + * Fixed ordering problem with boundary-stamping + + V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) + * Added pvalloc, as recommended by H.J. Liu + * Added 64bit pointer support mainly from Wolfram Gloger + * Added anonymously donated WIN32 sbrk emulation + * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen + * malloc_extend_top: fix mask error that caused wastage after + foreign sbrks + * Add linux mremap support code from HJ Liu + + V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) + * Integrated most documentation with the code. + * Add support for mmap, with help from + Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Use last_remainder in more cases. + * Pack bins using idea from colin@nyx10.cs.du.edu + * Use ordered bins instead of best-fit threshold + * Eliminate block-local decls to simplify tracing and debugging. + * Support another case of realloc via move into top + * Fix error occurring when initial sbrk_base not word-aligned. + * Rely on page size for units instead of SBRK_UNIT to + avoid surprises about sbrk alignment conventions. + * Add mallinfo, mallopt. Thanks to Raymond Nijssen + (raymond@es.ele.tue.nl) for the suggestion. + * Add `pad' argument to malloc_trim and top_pad mallopt parameter. + * More precautions for cases where other routines call sbrk, + courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Added macros etc., allowing use in linux libc from + H.J. Lu (hjl@gnu.ai.mit.edu) + * Inverted this history list + + V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) + * Re-tuned and fixed to behave more nicely with V2.6.0 changes. + * Removed all preallocation code since under current scheme + the work required to undo bad preallocations exceeds + the work saved in good cases for most test programs. + * No longer use return list or unconsolidated bins since + no scheme using them consistently outperforms those that don't + given above changes. + * Use best fit for very large chunks to prevent some worst-cases. + * Added some support for debugging + + V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) + * Removed footers when chunks are in use. Thanks to + Paul Wilson (wilson@cs.texas.edu) for the suggestion. + + V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) + * Added malloc_trim, with help from Wolfram Gloger + (wmglo@Dent.MED.Uni-Muenchen.DE). + + V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) + + V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) + * realloc: try to expand in both directions + * malloc: swap order of clean-bin strategy; + * realloc: only conditionally expand backwards + * Try not to scavenge used bins + * Use bin counts as a guide to preallocation + * Occasionally bin return list chunks in first scan + * Add a few optimizations from colin@nyx10.cs.du.edu + + V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) + * faster bin computation & slightly different binning + * merged all consolidations to one part of malloc proper + (eliminating old malloc_find_space & malloc_clean_bin) + * Scan 2 returns chunks (not just 1) + * Propagate failure in realloc if malloc returns 0 + * Add stuff to allow compilation on non-ANSI compilers + from kpv@research.att.com + + V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) + * removed potential for odd address access in prev_chunk + * removed dependency on getpagesize.h + * misc cosmetics and a bit more internal documentation + * anticosmetics: mangled names in macros to evade debugger strangeness + * tested on sparc, hp-700, dec-mips, rs6000 + with gcc & native cc (hp, dec only) allowing + Detlefs & Zorn comparison study (in SIGPLAN Notices.) + + Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) + * Based loosely on libg++-1.2X malloc. (It retains some of the overall + structure of old version, but most details differ.) + +*/ diff --git a/circuitpython/lib/libffi/src/frv/eabi.S b/circuitpython/lib/libffi/src/frv/eabi.S new file mode 100644 index 0000000..379ea4b --- /dev/null +++ b/circuitpython/lib/libffi/src/frv/eabi.S @@ -0,0 +1,128 @@ +/* ----------------------------------------------------------------------- + eabi.S - Copyright (c) 2004 Anthony Green + + FR-V Assembly glue. + + 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 AUTHOR 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 LIBFFI_ASM +#include +#include + + .globl ffi_prep_args_EABI + + .text + .p2align 4 + .globl ffi_call_EABI + .type ffi_call_EABI, @function + + # gr8 : ffi_prep_args + # gr9 : &ecif + # gr10: cif->bytes + # gr11: fig->flags + # gr12: ecif.rvalue + # gr13: fn + +ffi_call_EABI: + addi sp, #-80, sp + sti fp, @(sp, #24) + addi sp, #24, fp + movsg lr, gr5 + + /* Make room for the new arguments. */ + /* subi sp, fp, gr10 */ + + /* Store return address and incoming args on stack. */ + sti gr5, @(fp, #8) + sti gr8, @(fp, #-4) + sti gr9, @(fp, #-8) + sti gr10, @(fp, #-12) + sti gr11, @(fp, #-16) + sti gr12, @(fp, #-20) + sti gr13, @(fp, #-24) + + sub sp, gr10, sp + + /* Call ffi_prep_args. */ + ldi @(fp, #-4), gr4 + addi sp, #0, gr8 + ldi @(fp, #-8), gr9 +#ifdef __FRV_FDPIC__ + ldd @(gr4, gr0), gr14 + calll @(gr14, gr0) +#else + calll @(gr4, gr0) +#endif + + /* ffi_prep_args returns the new stack pointer. */ + mov gr8, gr4 + + ldi @(sp, #0), gr8 + ldi @(sp, #4), gr9 + ldi @(sp, #8), gr10 + ldi @(sp, #12), gr11 + ldi @(sp, #16), gr12 + ldi @(sp, #20), gr13 + + /* Always copy the return value pointer into the hidden + parameter register. This is only strictly necessary + when we're returning an aggregate type, but it doesn't + hurt to do this all the time, and it saves a branch. */ + ldi @(fp, #-20), gr3 + + /* Use the ffi_prep_args return value for the new sp. */ + mov gr4, sp + + /* Call the target function. */ + ldi @(fp, -24), gr4 +#ifdef __FRV_FDPIC__ + ldd @(gr4, gr0), gr14 + calll @(gr14, gr0) +#else + calll @(gr4, gr0) +#endif + + /* Store the result. */ + ldi @(fp, #-16), gr10 /* fig->flags */ + ldi @(fp, #-20), gr4 /* ecif.rvalue */ + + /* Is the return value stored in two registers? */ + cmpi gr10, #8, icc0 + bne icc0, 0, .L2 + /* Yes, save them. */ + sti gr8, @(gr4, #0) + sti gr9, @(gr4, #4) + bra .L3 +.L2: + /* Is the return value a structure? */ + cmpi gr10, #-1, icc0 + beq icc0, 0, .L3 + /* No, save a 4 byte return value. */ + sti gr8, @(gr4, #0) +.L3: + + /* Restore the stack, and return. */ + ldi @(fp, 8), gr5 + ld @(fp, gr0), fp + addi sp,#80,sp + jmpl @(gr5,gr0) + .size ffi_call_EABI, .-ffi_call_EABI + diff --git a/circuitpython/lib/libffi/src/frv/ffi.c b/circuitpython/lib/libffi/src/frv/ffi.c new file mode 100644 index 0000000..5698c89 --- /dev/null +++ b/circuitpython/lib/libffi/src/frv/ffi.c @@ -0,0 +1,292 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (C) 2004 Anthony Green + Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2008 Red Hat, Inc. + + FR-V Foreign Function Interface + + 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 +#include + +#include + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +void *ffi_prep_args(char *stack, extended_cif *ecif) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + register int count = 0; + + p_argv = ecif->avalue; + argp = stack; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); + i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + z = sizeof(void*); + *(void **) argp = *p_argv; + } + /* if ((*p_arg)->type == FFI_TYPE_FLOAT) + { + if (count > 24) + { + // This is going on the stack. Turn it into a double. + *(double *) argp = (double) *(float*)(* p_argv); + z = sizeof(double); + } + else + *(void **) argp = *(void **)(* p_argv); + } */ + else if (z < sizeof(int)) + { + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + } + else if (z == sizeof(int)) + { + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + } + else + { + memcpy(argp, *p_argv, z); + } + p_argv++; + argp += z; + count += z; + } + + return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8))); +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + if (cif->rtype->type == FFI_TYPE_STRUCT) + cif->flags = -1; + else + cif->flags = cif->rtype->size; + + cif->bytes = ALIGN (cif->bytes, 8); + + return FFI_OK; +} + +extern void ffi_call_EABI(void *(*)(char *, extended_cif *), + extended_cif *, + unsigned, unsigned, + unsigned *, + void (*fn)(void)); + +void ffi_call(ffi_cif *cif, + void (*fn)(void), + void *rvalue, + void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { + case FFI_EABI: + ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; + default: + FFI_ASSERT(0); + break; + } +} + +void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, + unsigned arg4, unsigned arg5, unsigned arg6) +{ + /* This function is called by a trampoline. The trampoline stows a + pointer to the ffi_closure object in gr7. We must save this + pointer in a place that will persist while we do our work. */ + register ffi_closure *creg __asm__ ("gr7"); + ffi_closure *closure = creg; + + /* Arguments that don't fit in registers are found on the stack + at a fixed offset above the current frame pointer. */ + register char *frame_pointer __asm__ ("fp"); + char *stack_args = frame_pointer + 16; + + /* Lay the register arguments down in a continuous chunk of memory. */ + unsigned register_args[6] = + { arg1, arg2, arg3, arg4, arg5, arg6 }; + + ffi_cif *cif = closure->cif; + ffi_type **arg_types = cif->arg_types; + void **avalue = alloca (cif->nargs * sizeof(void *)); + char *ptr = (char *) register_args; + int i; + + /* Find the address of each argument. */ + for (i = 0; i < cif->nargs; i++) + { + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + avalue[i] = ptr + 3; + break; + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + avalue[i] = ptr + 2; + break; + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_FLOAT: + avalue[i] = ptr; + break; + case FFI_TYPE_STRUCT: + avalue[i] = *(void**)ptr; + break; + default: + /* This is an 8-byte value. */ + avalue[i] = ptr; + ptr += 4; + break; + } + ptr += 4; + + /* If we've handled more arguments than fit in registers, + start looking at the those passed on the stack. */ + if (ptr == ((char *)register_args + (6*4))) + ptr = stack_args; + } + + /* Invoke the closure. */ + if (cif->rtype->type == FFI_TYPE_STRUCT) + { + /* The caller allocates space for the return structure, and + passes a pointer to this space in gr3. Use this value directly + as the return value. */ + register void *return_struct_ptr __asm__("gr3"); + (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data); + } + else + { + /* Allocate space for the return value and call the function. */ + long long rvalue; + (closure->fun) (cif, &rvalue, avalue, closure->user_data); + + /* Functions return 4-byte or smaller results in gr8. 8-byte + values also use gr9. We fill the both, even for small return + values, just to avoid a branch. */ + asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue)); + asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1])); + } +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + unsigned long fn = (long) ffi_closure_eabi; + unsigned long cls = (long) codeloc; +#ifdef __FRV_FDPIC__ + register void *got __asm__("gr15"); +#endif + int i; + + fn = (unsigned long) ffi_closure_eabi; + +#ifdef __FRV_FDPIC__ + tramp[0] = &((unsigned int *)codeloc)[2]; + tramp[1] = got; + tramp[2] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */ + tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */ + tramp[4] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */ + tramp[5] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */ + tramp[6] = 0x9cc86000; /* ldi @(gr6, #0), gr14 */ + tramp[7] = 0x8030e000; /* jmpl @(gr14, gr0) */ +#else + tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */ + tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */ + tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */ + tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */ + tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */ +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + /* Cache flushing. */ + for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++) + __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i), + "r" (codeloc)); + + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/frv/ffitarget.h b/circuitpython/lib/libffi/src/frv/ffitarget.h new file mode 100644 index 0000000..d42540e --- /dev/null +++ b/circuitpython/lib/libffi/src/frv/ffitarget.h @@ -0,0 +1,62 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2004 Red Hat, Inc. + Target configuration macros for FR-V + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- System specific configurations ----------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_EABI, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_EABI +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 + +#ifdef __FRV_FDPIC__ +/* Trampolines are 8 4-byte instructions long. */ +#define FFI_TRAMPOLINE_SIZE (8*4) +#else +/* Trampolines are 5 4-byte instructions long. */ +#define FFI_TRAMPOLINE_SIZE (5*4) +#endif + +#endif diff --git a/circuitpython/lib/libffi/src/ia64/ffi.c b/circuitpython/lib/libffi/src/ia64/ffi.c new file mode 100644 index 0000000..b77a836 --- /dev/null +++ b/circuitpython/lib/libffi/src/ia64/ffi.c @@ -0,0 +1,586 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 1998, 2007, 2008, 2012 Red Hat, Inc. + Copyright (c) 2000 Hewlett Packard Company + Copyright (c) 2011 Anthony Green + + IA64 Foreign Function Interface + + 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 +#include + +#include +#include +#include + +#include "ia64_flags.h" + +/* A 64-bit pointer value. In LP64 mode, this is effectively a plain + pointer. In ILP32 mode, it's a pointer that's been extended to + 64 bits by "addp4". */ +typedef void *PTR64 __attribute__((mode(DI))); + +/* Memory image of fp register contents. This is the implementation + specific format used by ldf.fill/stf.spill. All we care about is + that it wants a 16 byte aligned slot. */ +typedef struct +{ + UINT64 x[2] __attribute__((aligned(16))); +} fpreg; + + +/* The stack layout given to ffi_call_unix and ffi_closure_unix_inner. */ + +struct ia64_args +{ + fpreg fp_regs[8]; /* Contents of 8 fp arg registers. */ + UINT64 gp_regs[8]; /* Contents of 8 gp arg registers. */ + UINT64 other_args[]; /* Arguments passed on stack, variable size. */ +}; + + +/* Adjust ADDR, a pointer to an 8 byte slot, to point to the low LEN bytes. */ + +static inline void * +endian_adjust (void *addr, size_t len) +{ +#ifdef __BIG_ENDIAN__ + return addr + (8 - len); +#else + return addr; +#endif +} + +/* Store VALUE to ADDR in the current cpu implementation's fp spill format. + This is a macro instead of a function, so that it works for all 3 floating + point types without type conversions. Type conversion to long double breaks + the denorm support. */ + +#define stf_spill(addr, value) \ + asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value)); + +/* Load a value from ADDR, which is in the current cpu implementation's + fp spill format. As above, this must also be a macro. */ + +#define ldf_fill(result, addr) \ + asm ("ldf.fill %0 = %1%P1" : "=f"(result) : "m"(*addr)); + +/* Return the size of the C type associated with with TYPE. Which will + be one of the FFI_IA64_TYPE_HFA_* values. */ + +static size_t +hfa_type_size (int type) +{ + switch (type) + { + case FFI_IA64_TYPE_HFA_FLOAT: + return sizeof(float); + case FFI_IA64_TYPE_HFA_DOUBLE: + return sizeof(double); + case FFI_IA64_TYPE_HFA_LDOUBLE: + return sizeof(__float80); + default: + abort (); + } +} + +/* Load from ADDR a value indicated by TYPE. Which will be one of + the FFI_IA64_TYPE_HFA_* values. */ + +static void +hfa_type_load (fpreg *fpaddr, int type, void *addr) +{ + switch (type) + { + case FFI_IA64_TYPE_HFA_FLOAT: + stf_spill (fpaddr, *(float *) addr); + return; + case FFI_IA64_TYPE_HFA_DOUBLE: + stf_spill (fpaddr, *(double *) addr); + return; + case FFI_IA64_TYPE_HFA_LDOUBLE: + stf_spill (fpaddr, *(__float80 *) addr); + return; + default: + abort (); + } +} + +/* Load VALUE into ADDR as indicated by TYPE. Which will be one of + the FFI_IA64_TYPE_HFA_* values. */ + +static void +hfa_type_store (int type, void *addr, fpreg *fpaddr) +{ + switch (type) + { + case FFI_IA64_TYPE_HFA_FLOAT: + { + float result; + ldf_fill (result, fpaddr); + *(float *) addr = result; + break; + } + case FFI_IA64_TYPE_HFA_DOUBLE: + { + double result; + ldf_fill (result, fpaddr); + *(double *) addr = result; + break; + } + case FFI_IA64_TYPE_HFA_LDOUBLE: + { + __float80 result; + ldf_fill (result, fpaddr); + *(__float80 *) addr = result; + break; + } + default: + abort (); + } +} + +/* Is TYPE a struct containing floats, doubles, or extended doubles, + all of the same fp type? If so, return the element type. Return + FFI_TYPE_VOID if not. */ + +static int +hfa_element_type (ffi_type *type, int nested) +{ + int element = FFI_TYPE_VOID; + + switch (type->type) + { + case FFI_TYPE_FLOAT: + /* We want to return VOID for raw floating-point types, but the + synthetic HFA type if we're nested within an aggregate. */ + if (nested) + element = FFI_IA64_TYPE_HFA_FLOAT; + break; + + case FFI_TYPE_DOUBLE: + /* Similarly. */ + if (nested) + element = FFI_IA64_TYPE_HFA_DOUBLE; + break; + + case FFI_TYPE_LONGDOUBLE: + /* Similarly, except that that HFA is true for double extended, + but not quad precision. Both have sizeof == 16, so tell the + difference based on the precision. */ + if (LDBL_MANT_DIG == 64 && nested) + element = FFI_IA64_TYPE_HFA_LDOUBLE; + break; + + case FFI_TYPE_STRUCT: + { + ffi_type **ptr = &type->elements[0]; + + for (ptr = &type->elements[0]; *ptr ; ptr++) + { + int sub_element = hfa_element_type (*ptr, 1); + if (sub_element == FFI_TYPE_VOID) + return FFI_TYPE_VOID; + + if (element == FFI_TYPE_VOID) + element = sub_element; + else if (element != sub_element) + return FFI_TYPE_VOID; + } + } + break; + + default: + return FFI_TYPE_VOID; + } + + return element; +} + + +/* Perform machine dependent cif processing. */ + +ffi_status +ffi_prep_cif_machdep(ffi_cif *cif) +{ + int flags; + + /* Adjust cif->bytes to include space for the bits of the ia64_args frame + that precedes the integer register portion. The estimate that the + generic bits did for the argument space required is good enough for the + integer component. */ + cif->bytes += offsetof(struct ia64_args, gp_regs[0]); + if (cif->bytes < sizeof(struct ia64_args)) + cif->bytes = sizeof(struct ia64_args); + + /* Set the return type flag. */ + flags = cif->rtype->type; + switch (cif->rtype->type) + { + case FFI_TYPE_LONGDOUBLE: + /* Leave FFI_TYPE_LONGDOUBLE as meaning double extended precision, + and encode quad precision as a two-word integer structure. */ + if (LDBL_MANT_DIG != 64) + flags = FFI_IA64_TYPE_SMALL_STRUCT | (16 << 8); + break; + + case FFI_TYPE_STRUCT: + { + size_t size = cif->rtype->size; + int hfa_type = hfa_element_type (cif->rtype, 0); + + if (hfa_type != FFI_TYPE_VOID) + { + size_t nelts = size / hfa_type_size (hfa_type); + if (nelts <= 8) + flags = hfa_type | (size << 8); + } + else + { + if (size <= 32) + flags = FFI_IA64_TYPE_SMALL_STRUCT | (size << 8); + } + } + break; + + default: + break; + } + cif->flags = flags; + + return FFI_OK; +} + +extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64); + +void +ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + struct ia64_args *stack; + long i, avn, gpcount, fpcount; + ffi_type **p_arg; + + FFI_ASSERT (cif->abi == FFI_UNIX); + + /* If we have no spot for a return value, make one. */ + if (rvalue == NULL && cif->rtype->type != FFI_TYPE_VOID) + rvalue = alloca (cif->rtype->size); + + /* Allocate the stack frame. */ + stack = alloca (cif->bytes); + + gpcount = fpcount = 0; + avn = cif->nargs; + for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) + { + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + stack->gp_regs[gpcount++] = *(SINT8 *)avalue[i]; + break; + case FFI_TYPE_UINT8: + stack->gp_regs[gpcount++] = *(UINT8 *)avalue[i]; + break; + case FFI_TYPE_SINT16: + stack->gp_regs[gpcount++] = *(SINT16 *)avalue[i]; + break; + case FFI_TYPE_UINT16: + stack->gp_regs[gpcount++] = *(UINT16 *)avalue[i]; + break; + case FFI_TYPE_SINT32: + stack->gp_regs[gpcount++] = *(SINT32 *)avalue[i]; + break; + case FFI_TYPE_UINT32: + stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i]; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i]; + break; + + case FFI_TYPE_POINTER: + stack->gp_regs[gpcount++] = (UINT64)(PTR64) *(void **)avalue[i]; + break; + + case FFI_TYPE_FLOAT: + if (gpcount < 8 && fpcount < 8) + stf_spill (&stack->fp_regs[fpcount++], *(float *)avalue[i]); + { + UINT32 tmp; + memcpy (&tmp, avalue[i], sizeof (UINT32)); + stack->gp_regs[gpcount++] = tmp; + } + break; + + case FFI_TYPE_DOUBLE: + if (gpcount < 8 && fpcount < 8) + stf_spill (&stack->fp_regs[fpcount++], *(double *)avalue[i]); + memcpy (&stack->gp_regs[gpcount++], avalue[i], sizeof (UINT64)); + break; + + case FFI_TYPE_LONGDOUBLE: + if (gpcount & 1) + gpcount++; + if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8) + stf_spill (&stack->fp_regs[fpcount++], *(__float80 *)avalue[i]); + memcpy (&stack->gp_regs[gpcount], avalue[i], 16); + gpcount += 2; + break; + + case FFI_TYPE_STRUCT: + { + size_t size = (*p_arg)->size; + size_t align = (*p_arg)->alignment; + int hfa_type = hfa_element_type (*p_arg, 0); + + FFI_ASSERT (align <= 16); + if (align == 16 && (gpcount & 1)) + gpcount++; + + if (hfa_type != FFI_TYPE_VOID) + { + size_t hfa_size = hfa_type_size (hfa_type); + size_t offset = 0; + size_t gp_offset = gpcount * 8; + + while (fpcount < 8 + && offset < size + && gp_offset < 8 * 8) + { + hfa_type_load (&stack->fp_regs[fpcount], hfa_type, + avalue[i] + offset); + offset += hfa_size; + gp_offset += hfa_size; + fpcount += 1; + } + } + + memcpy (&stack->gp_regs[gpcount], avalue[i], size); + gpcount += (size + 7) / 8; + } + break; + + default: + abort (); + } + } + + ffi_call_unix (stack, rvalue, fn, cif->flags); +} + +/* Closures represent a pair consisting of a function pointer, and + some user data. A closure is invoked by reinterpreting the closure + as a function pointer, and branching to it. Thus we can make an + interpreted function callable as a C function: We turn the + interpreter itself, together with a pointer specifying the + interpreted procedure, into a closure. + + For IA64, function pointer are already pairs consisting of a code + pointer, and a gp pointer. The latter is needed to access global + variables. Here we set up such a pair as the first two words of + the closure (in the "trampoline" area), but we replace the gp + pointer with a pointer to the closure itself. We also add the real + gp pointer to the closure. This allows the function entry code to + both retrieve the user data, and to restore the correct gp pointer. */ + +extern void ffi_closure_unix (); + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + /* The layout of a function descriptor. A C function pointer really + points to one of these. */ + struct ia64_fd + { + UINT64 code_pointer; + UINT64 gp; + }; + + struct ffi_ia64_trampoline_struct + { + UINT64 code_pointer; /* Pointer to ffi_closure_unix. */ + UINT64 fake_gp; /* Pointer to closure, installed as gp. */ + UINT64 real_gp; /* Real gp value. */ + }; + + struct ffi_ia64_trampoline_struct *tramp; + struct ia64_fd *fd; + + if (cif->abi != FFI_UNIX) + return FFI_BAD_ABI; + + tramp = (struct ffi_ia64_trampoline_struct *)closure->tramp; + fd = (struct ia64_fd *)(void *)ffi_closure_unix; + + tramp->code_pointer = fd->code_pointer; + tramp->real_gp = fd->gp; + tramp->fake_gp = (UINT64)(PTR64)codeloc; + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + + +UINT64 +ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, + void *rvalue, void *r8) +{ + ffi_cif *cif; + void **avalue; + ffi_type **p_arg; + long i, avn, gpcount, fpcount; + + cif = closure->cif; + avn = cif->nargs; + avalue = alloca (avn * sizeof (void *)); + + /* If the structure return value is passed in memory get that location + from r8 so as to pass the value directly back to the caller. */ + if (cif->flags == FFI_TYPE_STRUCT) + rvalue = r8; + + gpcount = fpcount = 0; + for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) + { + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 1); + break; + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 2); + break; + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 4); + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + avalue[i] = &stack->gp_regs[gpcount++]; + break; + case FFI_TYPE_POINTER: + avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], sizeof(void*)); + break; + + case FFI_TYPE_FLOAT: + if (gpcount < 8 && fpcount < 8) + { + fpreg *addr = &stack->fp_regs[fpcount++]; + float result; + avalue[i] = addr; + ldf_fill (result, addr); + *(float *)addr = result; + } + else + avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4); + gpcount++; + break; + + case FFI_TYPE_DOUBLE: + if (gpcount < 8 && fpcount < 8) + { + fpreg *addr = &stack->fp_regs[fpcount++]; + double result; + avalue[i] = addr; + ldf_fill (result, addr); + *(double *)addr = result; + } + else + avalue[i] = &stack->gp_regs[gpcount]; + gpcount++; + break; + + case FFI_TYPE_LONGDOUBLE: + if (gpcount & 1) + gpcount++; + if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8) + { + fpreg *addr = &stack->fp_regs[fpcount++]; + __float80 result; + avalue[i] = addr; + ldf_fill (result, addr); + *(__float80 *)addr = result; + } + else + avalue[i] = &stack->gp_regs[gpcount]; + gpcount += 2; + break; + + case FFI_TYPE_STRUCT: + { + size_t size = (*p_arg)->size; + size_t align = (*p_arg)->alignment; + int hfa_type = hfa_element_type (*p_arg, 0); + + FFI_ASSERT (align <= 16); + if (align == 16 && (gpcount & 1)) + gpcount++; + + if (hfa_type != FFI_TYPE_VOID) + { + size_t hfa_size = hfa_type_size (hfa_type); + size_t offset = 0; + size_t gp_offset = gpcount * 8; + void *addr = alloca (size); + + avalue[i] = addr; + + while (fpcount < 8 + && offset < size + && gp_offset < 8 * 8) + { + hfa_type_store (hfa_type, addr + offset, + &stack->fp_regs[fpcount]); + offset += hfa_size; + gp_offset += hfa_size; + fpcount += 1; + } + + if (offset < size) + memcpy (addr + offset, (char *)stack->gp_regs + gp_offset, + size - offset); + } + else + avalue[i] = &stack->gp_regs[gpcount]; + + gpcount += (size + 7) / 8; + } + break; + + default: + abort (); + } + } + + closure->fun (cif, rvalue, avalue, closure->user_data); + + return cif->flags; +} diff --git a/circuitpython/lib/libffi/src/ia64/ffitarget.h b/circuitpython/lib/libffi/src/ia64/ffitarget.h new file mode 100644 index 0000000..e68cea6 --- /dev/null +++ b/circuitpython/lib/libffi/src/ia64/ffitarget.h @@ -0,0 +1,55 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for IA-64. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long long ffi_arg; +typedef signed long long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_UNIX, /* Linux and all Unix variants use the same conventions */ + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_UNIX +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */ + /* can be interpreted as a C function */ + /* descriptor: */ + +#endif + diff --git a/circuitpython/lib/libffi/src/ia64/ia64_flags.h b/circuitpython/lib/libffi/src/ia64/ia64_flags.h new file mode 100644 index 0000000..9d652ce --- /dev/null +++ b/circuitpython/lib/libffi/src/ia64/ia64_flags.h @@ -0,0 +1,40 @@ +/* ----------------------------------------------------------------------- + ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company + + IA64/unix Foreign Function Interface + + Original author: Hans Boehm, HP Labs + + 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. + ----------------------------------------------------------------------- */ + +/* "Type" codes used between assembly and C. When used as a part of + a cfi->flags value, the low byte will be these extra type codes, + and bits 8-31 will be the actual size of the type. */ + +/* Small structures containing N words in integer registers. */ +#define FFI_IA64_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 1) + +/* Homogeneous Floating Point Aggregates (HFAs) which are returned + in FP registers. */ +#define FFI_IA64_TYPE_HFA_FLOAT (FFI_TYPE_LAST + 2) +#define FFI_IA64_TYPE_HFA_DOUBLE (FFI_TYPE_LAST + 3) +#define FFI_IA64_TYPE_HFA_LDOUBLE (FFI_TYPE_LAST + 4) diff --git a/circuitpython/lib/libffi/src/ia64/unix.S b/circuitpython/lib/libffi/src/ia64/unix.S new file mode 100644 index 0000000..4d2a86d --- /dev/null +++ b/circuitpython/lib/libffi/src/ia64/unix.S @@ -0,0 +1,560 @@ +/* ----------------------------------------------------------------------- + unix.S - Copyright (c) 1998, 2008 Red Hat, Inc. + Copyright (c) 2000 Hewlett Packard Company + + IA64/unix Foreign Function Interface + + Primary author: Hans Boehm, HP Labs + + Loosely modeled on Cygnus code for other platforms. + + 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 LIBFFI_ASM +#include +#include +#include "ia64_flags.h" + + .pred.safe_across_calls p1-p5,p16-p63 +.text + +/* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue, + void (*fn)(void), int flags); + */ + + .align 16 + .global ffi_call_unix + .proc ffi_call_unix +ffi_call_unix: + .prologue + /* Bit o trickiness. We actually share a stack frame with ffi_call. + Rely on the fact that ffi_call uses a vframe and don't bother + tracking one here at all. */ + .fframe 0 + .save ar.pfs, r36 // loc0 + alloc loc0 = ar.pfs, 4, 3, 8, 0 + .save rp, loc1 + mov loc1 = b0 + .body + add r16 = 16, in0 + mov loc2 = gp + mov r8 = in1 + ;; + + /* Load up all of the argument registers. */ + ldf.fill f8 = [in0], 32 + ldf.fill f9 = [r16], 32 + ;; + ldf.fill f10 = [in0], 32 + ldf.fill f11 = [r16], 32 + ;; + ldf.fill f12 = [in0], 32 + ldf.fill f13 = [r16], 32 + ;; + ldf.fill f14 = [in0], 32 + ldf.fill f15 = [r16], 24 + ;; + ld8 out0 = [in0], 16 + ld8 out1 = [r16], 16 + ;; + ld8 out2 = [in0], 16 + ld8 out3 = [r16], 16 + ;; + ld8 out4 = [in0], 16 + ld8 out5 = [r16], 16 + ;; + ld8 out6 = [in0] + ld8 out7 = [r16] + ;; + + /* Deallocate the register save area from the stack frame. */ + mov sp = in0 + + /* Call the target function. */ + ld8 r16 = [in2], 8 + ;; + ld8 gp = [in2] + mov b6 = r16 + br.call.sptk.many b0 = b6 + ;; + + /* Dispatch to handle return value. */ + mov gp = loc2 + zxt1 r16 = in3 + ;; + mov ar.pfs = loc0 + addl r18 = @ltoffx(.Lst_table), gp + ;; + ld8.mov r18 = [r18], .Lst_table + mov b0 = loc1 + ;; + shladd r18 = r16, 3, r18 + ;; + ld8 r17 = [r18] + shr in3 = in3, 8 + ;; + add r17 = r17, r18 + ;; + mov b6 = r17 + br b6 + ;; + +.Lst_void: + br.ret.sptk.many b0 + ;; +.Lst_uint8: + zxt1 r8 = r8 + ;; + st8 [in1] = r8 + br.ret.sptk.many b0 + ;; +.Lst_sint8: + sxt1 r8 = r8 + ;; + st8 [in1] = r8 + br.ret.sptk.many b0 + ;; +.Lst_uint16: + zxt2 r8 = r8 + ;; + st8 [in1] = r8 + br.ret.sptk.many b0 + ;; +.Lst_sint16: + sxt2 r8 = r8 + ;; + st8 [in1] = r8 + br.ret.sptk.many b0 + ;; +.Lst_uint32: + zxt4 r8 = r8 + ;; + st8 [in1] = r8 + br.ret.sptk.many b0 + ;; +.Lst_sint32: + sxt4 r8 = r8 + ;; + st8 [in1] = r8 + br.ret.sptk.many b0 + ;; +.Lst_int64: + st8 [in1] = r8 + br.ret.sptk.many b0 + ;; +.Lst_float: + stfs [in1] = f8 + br.ret.sptk.many b0 + ;; +.Lst_double: + stfd [in1] = f8 + br.ret.sptk.many b0 + ;; +.Lst_ldouble: + stfe [in1] = f8 + br.ret.sptk.many b0 + ;; + +.Lst_small_struct: + add sp = -16, sp + cmp.lt p6, p0 = 8, in3 + cmp.lt p7, p0 = 16, in3 + cmp.lt p8, p0 = 24, in3 + ;; + add r16 = 8, sp + add r17 = 16, sp + add r18 = 24, sp + ;; + st8 [sp] = r8 +(p6) st8 [r16] = r9 + mov out0 = in1 +(p7) st8 [r17] = r10 +(p8) st8 [r18] = r11 + mov out1 = sp + mov out2 = in3 + br.call.sptk.many b0 = memcpy# + ;; + mov ar.pfs = loc0 + mov b0 = loc1 + mov gp = loc2 + br.ret.sptk.many b0 + +.Lst_hfa_float: + add r16 = 4, in1 + cmp.lt p6, p0 = 4, in3 + ;; + stfs [in1] = f8, 8 +(p6) stfs [r16] = f9, 8 + cmp.lt p7, p0 = 8, in3 + cmp.lt p8, p0 = 12, in3 + ;; +(p7) stfs [in1] = f10, 8 +(p8) stfs [r16] = f11, 8 + cmp.lt p9, p0 = 16, in3 + cmp.lt p10, p0 = 20, in3 + ;; +(p9) stfs [in1] = f12, 8 +(p10) stfs [r16] = f13, 8 + cmp.lt p6, p0 = 24, in3 + cmp.lt p7, p0 = 28, in3 + ;; +(p6) stfs [in1] = f14 +(p7) stfs [r16] = f15 + br.ret.sptk.many b0 + ;; + +.Lst_hfa_double: + add r16 = 8, in1 + cmp.lt p6, p0 = 8, in3 + ;; + stfd [in1] = f8, 16 +(p6) stfd [r16] = f9, 16 + cmp.lt p7, p0 = 16, in3 + cmp.lt p8, p0 = 24, in3 + ;; +(p7) stfd [in1] = f10, 16 +(p8) stfd [r16] = f11, 16 + cmp.lt p9, p0 = 32, in3 + cmp.lt p10, p0 = 40, in3 + ;; +(p9) stfd [in1] = f12, 16 +(p10) stfd [r16] = f13, 16 + cmp.lt p6, p0 = 48, in3 + cmp.lt p7, p0 = 56, in3 + ;; +(p6) stfd [in1] = f14 +(p7) stfd [r16] = f15 + br.ret.sptk.many b0 + ;; + +.Lst_hfa_ldouble: + add r16 = 16, in1 + cmp.lt p6, p0 = 16, in3 + ;; + stfe [in1] = f8, 32 +(p6) stfe [r16] = f9, 32 + cmp.lt p7, p0 = 32, in3 + cmp.lt p8, p0 = 48, in3 + ;; +(p7) stfe [in1] = f10, 32 +(p8) stfe [r16] = f11, 32 + cmp.lt p9, p0 = 64, in3 + cmp.lt p10, p0 = 80, in3 + ;; +(p9) stfe [in1] = f12, 32 +(p10) stfe [r16] = f13, 32 + cmp.lt p6, p0 = 96, in3 + cmp.lt p7, p0 = 112, in3 + ;; +(p6) stfe [in1] = f14 +(p7) stfe [r16] = f15 + br.ret.sptk.many b0 + ;; + + .endp ffi_call_unix + + .align 16 + .global ffi_closure_unix + .proc ffi_closure_unix + +#define FRAME_SIZE (8*16 + 8*8 + 8*16) + +ffi_closure_unix: + .prologue + .save ar.pfs, r40 // loc0 + alloc loc0 = ar.pfs, 8, 4, 4, 0 + .fframe FRAME_SIZE + add r12 = -FRAME_SIZE, r12 + .save rp, loc1 + mov loc1 = b0 + .save ar.unat, loc2 + mov loc2 = ar.unat + .body + + /* Retrieve closure pointer and real gp. */ +#ifdef _ILP32 + addp4 out0 = 0, gp + addp4 gp = 16, gp +#else + mov out0 = gp + add gp = 16, gp +#endif + ;; + ld8 gp = [gp] + + /* Spill all of the possible argument registers. */ + add r16 = 16 + 8*16, sp + add r17 = 16 + 8*16 + 16, sp + ;; + stf.spill [r16] = f8, 32 + stf.spill [r17] = f9, 32 + mov loc3 = gp + ;; + stf.spill [r16] = f10, 32 + stf.spill [r17] = f11, 32 + ;; + stf.spill [r16] = f12, 32 + stf.spill [r17] = f13, 32 + ;; + stf.spill [r16] = f14, 32 + stf.spill [r17] = f15, 24 + ;; + .mem.offset 0, 0 + st8.spill [r16] = in0, 16 + .mem.offset 8, 0 + st8.spill [r17] = in1, 16 + add out1 = 16 + 8*16, sp + ;; + .mem.offset 0, 0 + st8.spill [r16] = in2, 16 + .mem.offset 8, 0 + st8.spill [r17] = in3, 16 + add out2 = 16, sp + ;; + .mem.offset 0, 0 + st8.spill [r16] = in4, 16 + .mem.offset 8, 0 + st8.spill [r17] = in5, 16 + mov out3 = r8 + ;; + .mem.offset 0, 0 + st8.spill [r16] = in6 + .mem.offset 8, 0 + st8.spill [r17] = in7 + + /* Invoke ffi_closure_unix_inner for the hard work. */ + br.call.sptk.many b0 = ffi_closure_unix_inner + ;; + + /* Dispatch to handle return value. */ + mov gp = loc3 + zxt1 r16 = r8 + ;; + addl r18 = @ltoffx(.Lld_table), gp + mov ar.pfs = loc0 + ;; + ld8.mov r18 = [r18], .Lld_table + mov b0 = loc1 + ;; + shladd r18 = r16, 3, r18 + mov ar.unat = loc2 + ;; + ld8 r17 = [r18] + shr r8 = r8, 8 + ;; + add r17 = r17, r18 + add r16 = 16, sp + ;; + mov b6 = r17 + br b6 + ;; + .label_state 1 + +.Lld_void: + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; +.Lld_int: + .body + .copy_state 1 + ld8 r8 = [r16] + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; +.Lld_float: + .body + .copy_state 1 + ldfs f8 = [r16] + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; +.Lld_double: + .body + .copy_state 1 + ldfd f8 = [r16] + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; +.Lld_ldouble: + .body + .copy_state 1 + ldfe f8 = [r16] + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; + +.Lld_small_struct: + .body + .copy_state 1 + add r17 = 8, r16 + cmp.lt p6, p0 = 8, r8 + cmp.lt p7, p0 = 16, r8 + cmp.lt p8, p0 = 24, r8 + ;; + ld8 r8 = [r16], 16 +(p6) ld8 r9 = [r17], 16 + ;; +(p7) ld8 r10 = [r16] +(p8) ld8 r11 = [r17] + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; + +.Lld_hfa_float: + .body + .copy_state 1 + add r17 = 4, r16 + cmp.lt p6, p0 = 4, r8 + ;; + ldfs f8 = [r16], 8 +(p6) ldfs f9 = [r17], 8 + cmp.lt p7, p0 = 8, r8 + cmp.lt p8, p0 = 12, r8 + ;; +(p7) ldfs f10 = [r16], 8 +(p8) ldfs f11 = [r17], 8 + cmp.lt p9, p0 = 16, r8 + cmp.lt p10, p0 = 20, r8 + ;; +(p9) ldfs f12 = [r16], 8 +(p10) ldfs f13 = [r17], 8 + cmp.lt p6, p0 = 24, r8 + cmp.lt p7, p0 = 28, r8 + ;; +(p6) ldfs f14 = [r16] +(p7) ldfs f15 = [r17] + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; + +.Lld_hfa_double: + .body + .copy_state 1 + add r17 = 8, r16 + cmp.lt p6, p0 = 8, r8 + ;; + ldfd f8 = [r16], 16 +(p6) ldfd f9 = [r17], 16 + cmp.lt p7, p0 = 16, r8 + cmp.lt p8, p0 = 24, r8 + ;; +(p7) ldfd f10 = [r16], 16 +(p8) ldfd f11 = [r17], 16 + cmp.lt p9, p0 = 32, r8 + cmp.lt p10, p0 = 40, r8 + ;; +(p9) ldfd f12 = [r16], 16 +(p10) ldfd f13 = [r17], 16 + cmp.lt p6, p0 = 48, r8 + cmp.lt p7, p0 = 56, r8 + ;; +(p6) ldfd f14 = [r16] +(p7) ldfd f15 = [r17] + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; + +.Lld_hfa_ldouble: + .body + .copy_state 1 + add r17 = 16, r16 + cmp.lt p6, p0 = 16, r8 + ;; + ldfe f8 = [r16], 32 +(p6) ldfe f9 = [r17], 32 + cmp.lt p7, p0 = 32, r8 + cmp.lt p8, p0 = 48, r8 + ;; +(p7) ldfe f10 = [r16], 32 +(p8) ldfe f11 = [r17], 32 + cmp.lt p9, p0 = 64, r8 + cmp.lt p10, p0 = 80, r8 + ;; +(p9) ldfe f12 = [r16], 32 +(p10) ldfe f13 = [r17], 32 + cmp.lt p6, p0 = 96, r8 + cmp.lt p7, p0 = 112, r8 + ;; +(p6) ldfe f14 = [r16] +(p7) ldfe f15 = [r17] + .restore sp + add sp = FRAME_SIZE, sp + br.ret.sptk.many b0 + ;; + + .endp ffi_closure_unix + + .section .rodata + .align 8 +.Lst_table: + data8 @pcrel(.Lst_void) // FFI_TYPE_VOID + data8 @pcrel(.Lst_sint32) // FFI_TYPE_INT + data8 @pcrel(.Lst_float) // FFI_TYPE_FLOAT + data8 @pcrel(.Lst_double) // FFI_TYPE_DOUBLE + data8 @pcrel(.Lst_ldouble) // FFI_TYPE_LONGDOUBLE + data8 @pcrel(.Lst_uint8) // FFI_TYPE_UINT8 + data8 @pcrel(.Lst_sint8) // FFI_TYPE_SINT8 + data8 @pcrel(.Lst_uint16) // FFI_TYPE_UINT16 + data8 @pcrel(.Lst_sint16) // FFI_TYPE_SINT16 + data8 @pcrel(.Lst_uint32) // FFI_TYPE_UINT32 + data8 @pcrel(.Lst_sint32) // FFI_TYPE_SINT32 + data8 @pcrel(.Lst_int64) // FFI_TYPE_UINT64 + data8 @pcrel(.Lst_int64) // FFI_TYPE_SINT64 + data8 @pcrel(.Lst_void) // FFI_TYPE_STRUCT + data8 @pcrel(.Lst_int64) // FFI_TYPE_POINTER + data8 @pcrel(.Lst_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT + data8 @pcrel(.Lst_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT + data8 @pcrel(.Lst_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE + data8 @pcrel(.Lst_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE + +.Lld_table: + data8 @pcrel(.Lld_void) // FFI_TYPE_VOID + data8 @pcrel(.Lld_int) // FFI_TYPE_INT + data8 @pcrel(.Lld_float) // FFI_TYPE_FLOAT + data8 @pcrel(.Lld_double) // FFI_TYPE_DOUBLE + data8 @pcrel(.Lld_ldouble) // FFI_TYPE_LONGDOUBLE + data8 @pcrel(.Lld_int) // FFI_TYPE_UINT8 + data8 @pcrel(.Lld_int) // FFI_TYPE_SINT8 + data8 @pcrel(.Lld_int) // FFI_TYPE_UINT16 + data8 @pcrel(.Lld_int) // FFI_TYPE_SINT16 + data8 @pcrel(.Lld_int) // FFI_TYPE_UINT32 + data8 @pcrel(.Lld_int) // FFI_TYPE_SINT32 + data8 @pcrel(.Lld_int) // FFI_TYPE_UINT64 + data8 @pcrel(.Lld_int) // FFI_TYPE_SINT64 + data8 @pcrel(.Lld_void) // FFI_TYPE_STRUCT + data8 @pcrel(.Lld_int) // FFI_TYPE_POINTER + data8 @pcrel(.Lld_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT + data8 @pcrel(.Lld_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT + data8 @pcrel(.Lld_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE + data8 @pcrel(.Lld_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/java_raw_api.c b/circuitpython/lib/libffi/src/java_raw_api.c new file mode 100644 index 0000000..127123d --- /dev/null +++ b/circuitpython/lib/libffi/src/java_raw_api.c @@ -0,0 +1,374 @@ +/* ----------------------------------------------------------------------- + java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc. + + Cloned from raw_api.c + + Raw_api.c author: Kresten Krab Thorup + Java_raw_api.c author: Hans-J. Boehm + + $Id $ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +/* This defines a Java- and 64-bit specific variant of the raw API. */ +/* It assumes that "raw" argument blocks look like Java stacks on a */ +/* 64-bit machine. Arguments that can be stored in a single stack */ +/* stack slots (longs, doubles) occupy 128 bits, but only the first */ +/* 64 bits are actually used. */ + +#include +#include +#include + +#if !defined(NO_JAVA_RAW_API) + +size_t +ffi_java_raw_size (ffi_cif *cif) +{ + size_t result = 0; + int i; + + ffi_type **at = cif->arg_types; + + for (i = cif->nargs-1; i >= 0; i--, at++) + { + switch((*at) -> type) { + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_DOUBLE: + result += 2 * FFI_SIZEOF_JAVA_RAW; + break; + case FFI_TYPE_STRUCT: + /* No structure parameters in Java. */ + abort(); + case FFI_TYPE_COMPLEX: + /* Not supported yet. */ + abort(); + default: + result += FFI_SIZEOF_JAVA_RAW; + } + } + + return result; +} + + +void +ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) +{ + unsigned i; + ffi_type **tp = cif->arg_types; + +#if WORDS_BIGENDIAN + + for (i = 0; i < cif->nargs; i++, tp++, args++) + { + switch ((*tp)->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + *args = (void*) ((char*)(raw++) + 3); + break; + + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + *args = (void*) ((char*)(raw++) + 2); + break; + +#if FFI_SIZEOF_JAVA_RAW == 8 + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_DOUBLE: + *args = (void *)raw; + raw += 2; + break; +#endif + + case FFI_TYPE_POINTER: + *args = (void*) &(raw++)->ptr; + break; + + case FFI_TYPE_COMPLEX: + /* Not supported yet. */ + abort(); + + default: + *args = raw; + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); + } + } + +#else /* WORDS_BIGENDIAN */ + +#if !PDP + + /* then assume little endian */ + for (i = 0; i < cif->nargs; i++, tp++, args++) + { +#if FFI_SIZEOF_JAVA_RAW == 8 + switch((*tp)->type) { + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_DOUBLE: + *args = (void*) raw; + raw += 2; + break; + case FFI_TYPE_COMPLEX: + /* Not supported yet. */ + abort(); + default: + *args = (void*) raw++; + } +#else /* FFI_SIZEOF_JAVA_RAW != 8 */ + *args = (void*) raw; + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); +#endif /* FFI_SIZEOF_JAVA_RAW == 8 */ + } + +#else +#error "pdp endian not supported" +#endif /* ! PDP */ + +#endif /* WORDS_BIGENDIAN */ +} + +void +ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) +{ + unsigned i; + ffi_type **tp = cif->arg_types; + + for (i = 0; i < cif->nargs; i++, tp++, args++) + { + switch ((*tp)->type) + { + case FFI_TYPE_UINT8: +#if WORDS_BIGENDIAN + *(UINT32*)(raw++) = *(UINT8*) (*args); +#else + (raw++)->uint = *(UINT8*) (*args); +#endif + break; + + case FFI_TYPE_SINT8: +#if WORDS_BIGENDIAN + *(SINT32*)(raw++) = *(SINT8*) (*args); +#else + (raw++)->sint = *(SINT8*) (*args); +#endif + break; + + case FFI_TYPE_UINT16: +#if WORDS_BIGENDIAN + *(UINT32*)(raw++) = *(UINT16*) (*args); +#else + (raw++)->uint = *(UINT16*) (*args); +#endif + break; + + case FFI_TYPE_SINT16: +#if WORDS_BIGENDIAN + *(SINT32*)(raw++) = *(SINT16*) (*args); +#else + (raw++)->sint = *(SINT16*) (*args); +#endif + break; + + case FFI_TYPE_UINT32: +#if WORDS_BIGENDIAN + *(UINT32*)(raw++) = *(UINT32*) (*args); +#else + (raw++)->uint = *(UINT32*) (*args); +#endif + break; + + case FFI_TYPE_SINT32: +#if WORDS_BIGENDIAN + *(SINT32*)(raw++) = *(SINT32*) (*args); +#else + (raw++)->sint = *(SINT32*) (*args); +#endif + break; + + case FFI_TYPE_FLOAT: + (raw++)->flt = *(FLOAT32*) (*args); + break; + +#if FFI_SIZEOF_JAVA_RAW == 8 + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_DOUBLE: + raw->uint = *(UINT64*) (*args); + raw += 2; + break; +#endif + + case FFI_TYPE_POINTER: + (raw++)->ptr = **(void***) args; + break; + + default: +#if FFI_SIZEOF_JAVA_RAW == 8 + FFI_ASSERT(0); /* Should have covered all cases */ +#else + memcpy ((void*) raw->data, (void*)*args, (*tp)->size); + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); +#endif + } + } +} + +#if !FFI_NATIVE_RAW_API + +static void +ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue) +{ +#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8 + switch (cif->rtype->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_UINT32: + *(UINT64 *)rvalue <<= 32; + break; + + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_INT: +#if FFI_SIZEOF_JAVA_RAW == 4 + case FFI_TYPE_POINTER: +#endif + *(SINT64 *)rvalue <<= 32; + break; + + case FFI_TYPE_COMPLEX: + /* Not supported yet. */ + abort(); + + default: + break; + } +#endif +} + +static void +ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue) +{ +#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8 + switch (cif->rtype->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_UINT32: + *(UINT64 *)rvalue >>= 32; + break; + + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_INT: + *(SINT64 *)rvalue >>= 32; + break; + + case FFI_TYPE_COMPLEX: + /* Not supported yet. */ + abort(); + + default: + break; + } +#endif +} + +/* This is a generic definition of ffi_raw_call, to be used if the + * native system does not provide a machine-specific implementation. + * Having this, allows code to be written for the raw API, without + * the need for system-specific code to handle input in that format; + * these following couple of functions will handle the translation forth + * and back automatically. */ + +void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, + ffi_java_raw *raw) +{ + void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); + ffi_java_raw_to_ptrarray (cif, raw, avalue); + ffi_call (cif, fn, rvalue, avalue); + ffi_java_rvalue_to_raw (cif, rvalue); +} + +#if FFI_CLOSURES /* base system provides closures */ + +static void +ffi_java_translate_args (ffi_cif *cif, void *rvalue, + void **avalue, void *user_data) +{ + ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif)); + ffi_raw_closure *cl = (ffi_raw_closure*)user_data; + + ffi_java_ptrarray_to_raw (cif, avalue, raw); + (*cl->fun) (cif, rvalue, (ffi_raw*)raw, cl->user_data); + ffi_java_raw_to_rvalue (cif, rvalue); +} + +ffi_status +ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), + void *user_data, + void *codeloc) +{ + ffi_status status; + + status = ffi_prep_closure_loc ((ffi_closure*) cl, + cif, + &ffi_java_translate_args, + codeloc, + codeloc); + if (status == FFI_OK) + { + cl->fun = fun; + cl->user_data = user_data; + } + + return status; +} + +/* Again, here is the generic version of ffi_prep_raw_closure, which + * will install an intermediate "hub" for translation of arguments from + * the pointer-array format, to the raw format */ + +ffi_status +ffi_prep_java_raw_closure (ffi_java_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), + void *user_data) +{ + return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl); +} + +#endif /* FFI_CLOSURES */ +#endif /* !FFI_NATIVE_RAW_API */ +#endif /* !NO_JAVA_RAW_API */ diff --git a/circuitpython/lib/libffi/src/m32r/ffi.c b/circuitpython/lib/libffi/src/m32r/ffi.c new file mode 100644 index 0000000..3000063 --- /dev/null +++ b/circuitpython/lib/libffi/src/m32r/ffi.c @@ -0,0 +1,232 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2004 Renesas Technology + Copyright (c) 2008 Red Hat, Inc. + + M32R Foreign Function Interface + + 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 RENESAS TECHNOLOGY 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 +#include + +#include + +/* ffi_prep_args is called by the assembly routine once stack + space has been allocated for the function's arguments. */ + +void ffi_prep_args(char *stack, extended_cif *ecif) +{ + unsigned int i; + int tmp; + unsigned int avn; + void **p_argv; + char *argp; + ffi_type **p_arg; + + tmp = 0; + argp = stack; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 8) + { + *(void **) argp = ecif->rvalue; + argp += 4; + } + + avn = ecif->cif->nargs; + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0) && (avn != 0); + i--, p_arg++) + { + size_t z; + + /* Align if necessary. */ + if (((*p_arg)->alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, (*p_arg)->alignment); + + if (avn != 0) + { + avn--; + z = (*p_arg)->size; + if (z < sizeof (int)) + { + z = sizeof (int); + + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_STRUCT: + z = (*p_arg)->size; + if ((*p_arg)->alignment != 1) + memcpy (argp, *p_argv, z); + else + memcpy (argp + 4 - z, *p_argv, z); + z = sizeof (int); + break; + + default: + FFI_ASSERT(0); + } + } + else if (z == sizeof (int)) + { + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + } + else + { + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + if (z > 8) + { + *(unsigned int *) argp = (unsigned int)(void *)(* p_argv); + z = sizeof(void *); + } + else + { + memcpy(argp, *p_argv, z); + z = 8; + } + } + else + { + /* Double or long long 64bit. */ + memcpy (argp, *p_argv, z); + } + } + p_argv++; + argp += z; + } + } + + return; +} + +/* Perform machine dependent cif processing. */ +ffi_status +ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* Set the return type flag. */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->size <= 4) + cif->flags = FFI_TYPE_INT; + + else if (cif->rtype->size <= 8) + cif->flags = FFI_TYPE_DOUBLE; + + else + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + cif->flags = FFI_TYPE_DOUBLE; + break; + + case FFI_TYPE_FLOAT: + default: + cif->flags = FFI_TYPE_INT; + break; + } + + return FFI_OK; +} + +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)(void)); + +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have + a return value address then we need to make one. */ + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca (cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + if (cif->rtype->type == FFI_TYPE_STRUCT) + { + int size = cif->rtype->size; + int align = cif->rtype->alignment; + + if (size < 4) + { + if (align == 1) + *(unsigned long *)(ecif.rvalue) <<= (4 - size) * 8; + } + else if (4 < size && size < 8) + { + if (align == 1) + { + memcpy (ecif.rvalue, ecif.rvalue + 8-size, size); + } + else if (align == 2) + { + if (size & 1) + size += 1; + + if (size != 8) + memcpy (ecif.rvalue, ecif.rvalue + 8-size, size); + } + } + } + break; + + default: + FFI_ASSERT(0); + break; + } +} diff --git a/circuitpython/lib/libffi/src/m32r/ffitarget.h b/circuitpython/lib/libffi/src/m32r/ffitarget.h new file mode 100644 index 0000000..6c34801 --- /dev/null +++ b/circuitpython/lib/libffi/src/m32r/ffitarget.h @@ -0,0 +1,53 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 2004 Renesas Technology. + Target configuration macros for M32R. + + 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 RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi + { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV + } ffi_abi; +#endif + +#define FFI_CLOSURES 0 +#define FFI_TRAMPOLINE_SIZE 24 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/m32r/sysv.S b/circuitpython/lib/libffi/src/m32r/sysv.S new file mode 100644 index 0000000..06b75c2 --- /dev/null +++ b/circuitpython/lib/libffi/src/m32r/sysv.S @@ -0,0 +1,121 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2004 Renesas Technology + + M32R Foreign Function Interface + + 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 RENESAS TECHNOLOGY 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 LIBFFI_ASM +#include +#include +#ifdef HAVE_MACHINE_ASM_H +#include +#else +/* XXX these lose for some platforms, I'm sure. */ +#define CNAME(x) x +#define ENTRY(x) .globl CNAME(x)! .type CNAME(x),%function! CNAME(x): +#endif + +.text + + /* R0: ffi_prep_args */ + /* R1: &ecif */ + /* R2: cif->bytes */ + /* R3: fig->flags */ + /* sp+0: ecif.rvalue */ + /* sp+4: fn */ + + /* This assumes we are using gas. */ +ENTRY(ffi_call_SYSV) + /* Save registers. */ + push fp + push lr + push r3 + push r2 + push r1 + push r0 + mv fp, sp + + /* Make room for all of the new args. */ + sub sp, r2 + + /* Place all of the ffi_prep_args in position. */ + mv lr, r0 + mv r0, sp + /* R1 already set. */ + + /* And call. */ + jl lr + + /* Move first 4 parameters in registers... */ + ld r0, @(0,sp) + ld r1, @(4,sp) + ld r2, @(8,sp) + ld r3, @(12,sp) + + /* ...and adjust the stack. */ + ld lr, @(8,fp) + cmpi lr, #16 + bc adjust_stack + ldi lr, #16 +adjust_stack: + add sp, lr + + /* Call the function. */ + ld lr, @(28,fp) + jl lr + + /* Remove the space we pushed for the args. */ + mv sp, fp + + /* Load R2 with the pointer to storage for the return value. */ + ld r2, @(24,sp) + + /* Load R3 with the return type code. */ + ld r3, @(12,sp) + + /* If the return value pointer is NULL, assume no return value. */ + beqz r2, epilogue + + /* Return INT. */ + ldi r4, #FFI_TYPE_INT + bne r3, r4, return_double + st r0, @r2 + bra epilogue + +return_double: + /* Return DOUBLE or LONGDOUBLE. */ + ldi r4, #FFI_TYPE_DOUBLE + bne r3, r4, epilogue + st r0, @r2 + st r1, @(4,r2) + +epilogue: + pop r0 + pop r1 + pop r2 + pop r3 + pop lr + pop fp + jmp lr + +.ffi_call_SYSV_end: + .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) diff --git a/circuitpython/lib/libffi/src/m68k/ffi.c b/circuitpython/lib/libffi/src/m68k/ffi.c new file mode 100644 index 0000000..0dee938 --- /dev/null +++ b/circuitpython/lib/libffi/src/m68k/ffi.c @@ -0,0 +1,362 @@ +/* ----------------------------------------------------------------------- + ffi.c + + m68k Foreign Function Interface + ----------------------------------------------------------------------- */ + +#include +#include + +#include +#include +#ifdef __rtems__ +void rtems_cache_flush_multiple_data_lines( const void *, size_t ); +#else +#include +#ifdef __MINT__ +#include +#include +#else +#include +#endif +#endif + +void ffi_call_SYSV (extended_cif *, + unsigned, unsigned, + void *, void (*fn) ()); +void *ffi_prep_args (void *stack, extended_cif *ecif); +void ffi_closure_SYSV (ffi_closure *); +void ffi_closure_struct_SYSV (ffi_closure *); +unsigned int ffi_closure_SYSV_inner (ffi_closure *closure, + void *resp, void *args); + +/* ffi_prep_args is called by the assembly routine once stack space has + been allocated for the function's arguments. */ + +void * +ffi_prep_args (void *stack, extended_cif *ecif) +{ + unsigned int i; + void **p_argv; + char *argp; + ffi_type **p_arg; + void *struct_value_ptr; + + argp = stack; + + if ( +#ifdef __MINT__ + (ecif->cif->rtype->type == FFI_TYPE_LONGDOUBLE) || +#endif + (((ecif->cif->rtype->type == FFI_TYPE_STRUCT) + && !ecif->cif->flags))) + struct_value_ptr = ecif->rvalue; + else + struct_value_ptr = NULL; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z = (*p_arg)->size; + int type = (*p_arg)->type; + + if (z < sizeof (int)) + { + switch (type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; + break; + + case FFI_TYPE_STRUCT: +#ifdef __MINT__ + if (z == 1 || z == 2) + memcpy (argp + 2, *p_argv, z); + else + memcpy (argp, *p_argv, z); +#else + memcpy (argp + sizeof (int) - z, *p_argv, z); +#endif + break; + + default: + FFI_ASSERT (0); + } + z = sizeof (int); + } + else + { + memcpy (argp, *p_argv, z); + + /* Align if necessary. */ + if ((sizeof(int) - 1) & z) + z = ALIGN(z, sizeof(int)); + } + + p_argv++; + argp += z; + } + + return struct_value_ptr; +} + +#define CIF_FLAGS_INT 1 +#define CIF_FLAGS_DINT 2 +#define CIF_FLAGS_FLOAT 4 +#define CIF_FLAGS_DOUBLE 8 +#define CIF_FLAGS_LDOUBLE 16 +#define CIF_FLAGS_POINTER 32 +#define CIF_FLAGS_STRUCT1 64 +#define CIF_FLAGS_STRUCT2 128 +#define CIF_FLAGS_SINT8 256 +#define CIF_FLAGS_SINT16 512 + +/* Perform machine dependent cif processing */ +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = 0; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT && + cif->rtype->elements[1]) + { + cif->flags = 0; + break; + } + + switch (cif->rtype->size) + { + case 1: +#ifdef __MINT__ + cif->flags = CIF_FLAGS_STRUCT2; +#else + cif->flags = CIF_FLAGS_STRUCT1; +#endif + break; + case 2: + cif->flags = CIF_FLAGS_STRUCT2; + break; +#ifdef __MINT__ + case 3: +#endif + case 4: + cif->flags = CIF_FLAGS_INT; + break; +#ifdef __MINT__ + case 7: +#endif + case 8: + cif->flags = CIF_FLAGS_DINT; + break; + default: + cif->flags = 0; + break; + } + break; + + case FFI_TYPE_FLOAT: + cif->flags = CIF_FLAGS_FLOAT; + break; + + case FFI_TYPE_DOUBLE: + cif->flags = CIF_FLAGS_DOUBLE; + break; + +#if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE) + case FFI_TYPE_LONGDOUBLE: +#ifdef __MINT__ + cif->flags = 0; +#else + cif->flags = CIF_FLAGS_LDOUBLE; +#endif + break; +#endif + + case FFI_TYPE_POINTER: + cif->flags = CIF_FLAGS_POINTER; + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags = CIF_FLAGS_DINT; + break; + + case FFI_TYPE_SINT16: + cif->flags = CIF_FLAGS_SINT16; + break; + + case FFI_TYPE_SINT8: + cif->flags = CIF_FLAGS_SINT8; + break; + + default: + cif->flags = CIF_FLAGS_INT; + break; + } + + return FFI_OK; +} + +void +ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return value + address then we need to make one. */ + + if (rvalue == NULL + && cif->rtype->type == FFI_TYPE_STRUCT + && cif->rtype->size > 8) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV (&ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +static void +ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif) +{ + unsigned int i; + void **p_argv; + char *argp; + ffi_type **p_arg; + + argp = stack; + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; +#ifdef __MINT__ + if (cif->flags && + cif->rtype->type == FFI_TYPE_STRUCT && + (z == 1 || z == 2)) + { + *p_argv = (void *) (argp + 2); + + z = 4; + } + else + if (cif->flags && + cif->rtype->type == FFI_TYPE_STRUCT && + (z == 3 || z == 4)) + { + *p_argv = (void *) (argp); + + z = 4; + } + else +#endif + if (z <= 4) + { + *p_argv = (void *) (argp + 4 - z); + + z = 4; + } + else + { + *p_argv = (void *) argp; + + /* Align if necessary */ + if ((sizeof(int) - 1) & z) + z = ALIGN(z, sizeof(int)); + } + + p_argv++; + argp += z; + } +} + +unsigned int +ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_incoming_args_SYSV(args, arg_area, cif); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + *(unsigned short *)closure->tramp = 0x207c; + *(void **)(closure->tramp + 2) = codeloc; + *(unsigned short *)(closure->tramp + 6) = 0x4ef9; + + if ( +#ifdef __MINT__ + (cif->rtype->type == FFI_TYPE_LONGDOUBLE) || +#endif + (((cif->rtype->type == FFI_TYPE_STRUCT) + && !cif->flags))) + *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV; + else + *(void **)(closure->tramp + 8) = ffi_closure_SYSV; + +#ifdef __rtems__ + rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE ); +#elif defined(__MINT__) + Ssystem(S_FLUSHCACHE, codeloc, FFI_TRAMPOLINE_SIZE); +#else + syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE, + FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE); +#endif + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/m68k/ffitarget.h b/circuitpython/lib/libffi/src/m68k/ffitarget.h new file mode 100644 index 0000000..e81dde2 --- /dev/null +++ b/circuitpython/lib/libffi/src/m68k/ffitarget.h @@ -0,0 +1,54 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for Motorola 68K. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 16 +#define FFI_NATIVE_RAW_API 0 + +#endif + diff --git a/circuitpython/lib/libffi/src/m68k/sysv.S b/circuitpython/lib/libffi/src/m68k/sysv.S new file mode 100644 index 0000000..ec2b14f --- /dev/null +++ b/circuitpython/lib/libffi/src/m68k/sysv.S @@ -0,0 +1,330 @@ +/* ----------------------------------------------------------------------- + + sysv.S - Copyright (c) 2012 Alan Hourihane + Copyright (c) 1998, 2012 Andreas Schwab + Copyright (c) 2008 Red Hat, Inc. + Copyright (c) 2012 Thorsten Glaser + + m68k Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + +#ifdef HAVE_AS_CFI_PSEUDO_OP +#define CFI_STARTPROC() .cfi_startproc +#define CFI_OFFSET(reg,off) .cfi_offset reg,off +#define CFI_DEF_CFA(reg,off) .cfi_def_cfa reg,off +#define CFI_ENDPROC() .cfi_endproc +#else +#define CFI_STARTPROC() +#define CFI_OFFSET(reg,off) +#define CFI_DEF_CFA(reg,off) +#define CFI_ENDPROC() +#endif + +#ifdef __MINT__ +#define CALLFUNC(funcname) _ ## funcname +#else +#define CALLFUNC(funcname) funcname +#endif + + .text + + .globl CALLFUNC(ffi_call_SYSV) + .type CALLFUNC(ffi_call_SYSV),@function + .align 4 + +CALLFUNC(ffi_call_SYSV): + CFI_STARTPROC() + link %fp,#0 + CFI_OFFSET(14,-8) + CFI_DEF_CFA(14,8) + move.l %d2,-(%sp) + CFI_OFFSET(2,-12) + + | Make room for all of the new args. + sub.l 12(%fp),%sp + + | Call ffi_prep_args + move.l 8(%fp),-(%sp) + pea 4(%sp) +#if !defined __PIC__ + jsr CALLFUNC(ffi_prep_args) +#else + bsr.l CALLFUNC(ffi_prep_args@PLTPC) +#endif + addq.l #8,%sp + + | Pass pointer to struct value, if any +#ifdef __MINT__ + move.l %d0,%a1 +#else + move.l %a0,%a1 +#endif + + | Call the function + move.l 24(%fp),%a0 + jsr (%a0) + + | Remove the space we pushed for the args + add.l 12(%fp),%sp + + | Load the pointer to storage for the return value + move.l 20(%fp),%a1 + + | Load the return type code + move.l 16(%fp),%d2 + + | If the return value pointer is NULL, assume no return value. + | NOTE: On the mc68000, tst on an address register is not supported. +#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__) + cmp.w #0, %a1 +#else + tst.l %a1 +#endif + jbeq noretval + + btst #0,%d2 + jbeq retlongint + move.l %d0,(%a1) + jbra epilogue + +retlongint: + btst #1,%d2 + jbeq retfloat + move.l %d0,(%a1) + move.l %d1,4(%a1) + jbra epilogue + +retfloat: + btst #2,%d2 + jbeq retdouble +#if defined(__MC68881__) || defined(__HAVE_68881__) + fmove.s %fp0,(%a1) +#else + move.l %d0,(%a1) +#endif + jbra epilogue + +retdouble: + btst #3,%d2 + jbeq retlongdouble +#if defined(__MC68881__) || defined(__HAVE_68881__) + fmove.d %fp0,(%a1) +#else + move.l %d0,(%a1)+ + move.l %d1,(%a1) +#endif + jbra epilogue + +retlongdouble: + btst #4,%d2 + jbeq retpointer +#if defined(__MC68881__) || defined(__HAVE_68881__) + fmove.x %fp0,(%a1) +#else + move.l %d0,(%a1)+ + move.l %d1,(%a1)+ + move.l %d2,(%a1) +#endif + jbra epilogue + +retpointer: + btst #5,%d2 + jbeq retstruct1 +#ifdef __MINT__ + move.l %d0,(%a1) +#else + move.l %a0,(%a1) +#endif + jbra epilogue + +retstruct1: + btst #6,%d2 + jbeq retstruct2 + move.b %d0,(%a1) + jbra epilogue + +retstruct2: + btst #7,%d2 + jbeq retsint8 + move.w %d0,(%a1) + jbra epilogue + +retsint8: + btst #8,%d2 + jbeq retsint16 + | NOTE: On the mc68000, extb is not supported. 8->16, then 16->32. +#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__) + ext.w %d0 + ext.l %d0 +#else + extb.l %d0 +#endif + move.l %d0,(%a1) + jbra epilogue + +retsint16: + btst #9,%d2 + jbeq noretval + ext.l %d0 + move.l %d0,(%a1) + +noretval: +epilogue: + move.l (%sp)+,%d2 + unlk %fp + rts + CFI_ENDPROC() + .size CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV) + + .globl CALLFUNC(ffi_closure_SYSV) + .type CALLFUNC(ffi_closure_SYSV), @function + .align 4 + +CALLFUNC(ffi_closure_SYSV): + CFI_STARTPROC() + link %fp,#-12 + CFI_OFFSET(14,-8) + CFI_DEF_CFA(14,8) + move.l %sp,-12(%fp) + pea 8(%fp) + pea -12(%fp) + move.l %a0,-(%sp) +#if !defined __PIC__ + jsr CALLFUNC(ffi_closure_SYSV_inner) +#else + bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC) +#endif + + lsr.l #1,%d0 + jne 1f + jcc .Lcls_epilogue + | CIF_FLAGS_INT + move.l -12(%fp),%d0 +.Lcls_epilogue: + | no CIF_FLAGS_* + unlk %fp + rts +1: + lea -12(%fp),%a0 + lsr.l #2,%d0 + jne 1f + jcs .Lcls_ret_float + | CIF_FLAGS_DINT + move.l (%a0)+,%d0 + move.l (%a0),%d1 + jra .Lcls_epilogue +.Lcls_ret_float: +#if defined(__MC68881__) || defined(__HAVE_68881__) + fmove.s (%a0),%fp0 +#else + move.l (%a0),%d0 +#endif + jra .Lcls_epilogue +1: + lsr.l #2,%d0 + jne 1f + jcs .Lcls_ret_ldouble + | CIF_FLAGS_DOUBLE +#if defined(__MC68881__) || defined(__HAVE_68881__) + fmove.d (%a0),%fp0 +#else + move.l (%a0)+,%d0 + move.l (%a0),%d1 +#endif + jra .Lcls_epilogue +.Lcls_ret_ldouble: +#if defined(__MC68881__) || defined(__HAVE_68881__) + fmove.x (%a0),%fp0 +#else + move.l (%a0)+,%d0 + move.l (%a0)+,%d1 + move.l (%a0),%d2 +#endif + jra .Lcls_epilogue +1: + lsr.l #2,%d0 + jne 1f + jcs .Lcls_ret_struct1 + | CIF_FLAGS_POINTER + move.l (%a0),%a0 + move.l %a0,%d0 + jra .Lcls_epilogue +.Lcls_ret_struct1: + move.b (%a0),%d0 + jra .Lcls_epilogue +1: + lsr.l #2,%d0 + jne 1f + jcs .Lcls_ret_sint8 + | CIF_FLAGS_STRUCT2 + move.w (%a0),%d0 + jra .Lcls_epilogue +.Lcls_ret_sint8: + move.l (%a0),%d0 + | NOTE: On the mc68000, extb is not supported. 8->16, then 16->32. +#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__) + ext.w %d0 + ext.l %d0 +#else + extb.l %d0 +#endif + jra .Lcls_epilogue +1: + | CIF_FLAGS_SINT16 + move.l (%a0),%d0 + ext.l %d0 + jra .Lcls_epilogue + CFI_ENDPROC() + + .size CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV) + + .globl CALLFUNC(ffi_closure_struct_SYSV) + .type CALLFUNC(ffi_closure_struct_SYSV), @function + .align 4 + +CALLFUNC(ffi_closure_struct_SYSV): + CFI_STARTPROC() + link %fp,#0 + CFI_OFFSET(14,-8) + CFI_DEF_CFA(14,8) + move.l %sp,-12(%fp) + pea 8(%fp) + move.l %a1,-(%sp) + move.l %a0,-(%sp) +#if !defined __PIC__ + jsr CALLFUNC(ffi_closure_SYSV_inner) +#else + bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC) +#endif + unlk %fp + rts + CFI_ENDPROC() + .size CALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV) + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/m88k/ffi.c b/circuitpython/lib/libffi/src/m88k/ffi.c new file mode 100644 index 0000000..68df494 --- /dev/null +++ b/circuitpython/lib/libffi/src/m88k/ffi.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * m88k Foreign Function Interface + * + * This file attempts to provide all the FFI entry points which can reliably + * be implemented in C. + * + * Only OpenBSD/m88k is currently supported; other platforms (such as + * Motorola's SysV/m88k) could be supported with the following tweaks: + * + * - non-OpenBSD systems use an `outgoing parameter area' as part of the + * 88BCS calling convention, which is not supported under OpenBSD from + * release 3.6 onwards. Supporting it should be as easy as taking it + * into account when adjusting the stack, in the assembly code. + * + * - the logic deciding whether a function argument gets passed through + * registers, or on the stack, has changed several times in OpenBSD in + * edge cases (especially for structs larger than 32 bytes being passed + * by value). The code below attemps to match the logic used by the + * system compiler of OpenBSD 5.3, i.e. gcc 3.3.6 with many m88k backend + * fixes. + */ + +#include +#include + +#include +#include + +void ffi_call_OBSD (unsigned int, extended_cif *, unsigned int, void *, + void (*fn) ()); +void *ffi_prep_args (void *, extended_cif *); +void ffi_closure_OBSD (ffi_closure *); +void ffi_closure_struct_OBSD (ffi_closure *); +unsigned int ffi_closure_OBSD_inner (ffi_closure *, void *, unsigned int *, + char *); +void ffi_cacheflush_OBSD (unsigned int, unsigned int); + +#define CIF_FLAGS_INT (1 << 0) +#define CIF_FLAGS_DINT (1 << 1) + +/* + * Foreign Function Interface API + */ + +/* ffi_prep_args is called by the assembly routine once stack space has + been allocated for the function's arguments. */ + +void * +ffi_prep_args (void *stack, extended_cif *ecif) +{ + unsigned int i; + void **p_argv; + char *argp, *stackp; + unsigned int *regp; + unsigned int regused; + ffi_type **p_arg; + void *struct_value_ptr; + + regp = (unsigned int *)stack; + stackp = (char *)(regp + 8); + regused = 0; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && !ecif->cif->flags) + struct_value_ptr = ecif->rvalue; + else + struct_value_ptr = NULL; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + unsigned short t, a; + + z = (*p_arg)->size; + t = (*p_arg)->type; + a = (*p_arg)->alignment; + + /* + * Figure out whether the argument can be passed through registers + * or on the stack. + * The rule is that registers can only receive simple types not larger + * than 64 bits, or structs the exact size of a register and aligned to + * the size of a register. + */ + if (t == FFI_TYPE_STRUCT) + { + if (z == sizeof (int) && a == sizeof (int) && regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + else + { + if (z > sizeof (int) && regused < 8 - 1) + { + /* align to an even register pair */ + if (regused & 1) + { + regp++; + regused++; + } + } + if (regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + + /* Enforce proper stack alignment of 64-bit types */ + if (argp == stackp && a > sizeof (int)) + { + stackp = (char *) ALIGN(stackp, a); + argp = stackp; + } + + switch (t) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; + break; + + case FFI_TYPE_INT: + case FFI_TYPE_FLOAT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + *(unsigned int *) argp = *(unsigned int *) *p_argv; + break; + + case FFI_TYPE_DOUBLE: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, z); + break; + + default: + FFI_ASSERT (0); + } + + /* Align if necessary. */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + + /* Be careful, once all registers are filled, and about to continue + on stack, regp == stackp. Therefore the check for regused as well. */ + if (argp == (char *)regp && regused < 8) + { + regp += z / sizeof (int); + regused += z / sizeof (int); + } + else + stackp += z; + } + + return struct_value_ptr; +} + +/* Perform machine dependent cif processing */ +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = 0; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->size == sizeof (int) && + cif->rtype->alignment == sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else + cif->flags = 0; + break; + + case FFI_TYPE_DOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags = CIF_FLAGS_DINT; + break; + + default: + cif->flags = CIF_FLAGS_INT; + break; + } + + return FFI_OK; +} + +void +ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return value + address then we need to make one. */ + + if (rvalue == NULL + && cif->rtype->type == FFI_TYPE_STRUCT + && (cif->rtype->size != sizeof (int) + || cif->rtype->alignment != sizeof (int))) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_OBSD: + ffi_call_OBSD (cif->bytes, &ecif, cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +/* + * Closure API + */ + +static void +ffi_prep_closure_args_OBSD (ffi_cif *cif, void **avalue, unsigned int *regp, + char *stackp) +{ + unsigned int i; + void **p_argv; + char *argp; + unsigned int regused; + ffi_type **p_arg; + + regused = 0; + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + unsigned short t, a; + + z = (*p_arg)->size; + t = (*p_arg)->type; + a = (*p_arg)->alignment; + + /* + * Figure out whether the argument has been passed through registers + * or on the stack. + * The rule is that registers can only receive simple types not larger + * than 64 bits, or structs the exact size of a register and aligned to + * the size of a register. + */ + if (t == FFI_TYPE_STRUCT) + { + if (z == sizeof (int) && a == sizeof (int) && regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + else + { + if (z > sizeof (int) && regused < 8 - 1) + { + /* align to an even register pair */ + if (regused & 1) + { + regp++; + regused++; + } + } + if (regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + + /* Enforce proper stack alignment of 64-bit types */ + if (argp == stackp && a > sizeof (int)) + { + stackp = (char *) ALIGN(stackp, a); + argp = stackp; + } + + if (z < sizeof (int) && t != FFI_TYPE_STRUCT) + *p_argv = (void *) (argp + sizeof (int) - z); + else + *p_argv = (void *) argp; + + /* Align if necessary */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + + /* Be careful, once all registers are exhausted, and about to fetch from + stack, regp == stackp. Therefore the check for regused as well. */ + if (argp == (char *)regp && regused < 8) + { + regp += z / sizeof (int); + regused += z / sizeof (int); + } + else + stackp += z; + } +} + +unsigned int +ffi_closure_OBSD_inner (ffi_closure *closure, void *resp, unsigned int *regp, + char *stackp) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_closure_args_OBSD(cif, arg_area, regp, stackp); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, void *codeloc) +{ + unsigned int *tramp = (unsigned int *) codeloc; + void *fn; + + FFI_ASSERT (cif->abi == FFI_OBSD); + + if (cif->rtype->type == FFI_TYPE_STRUCT && !cif->flags) + fn = &ffi_closure_struct_OBSD; + else + fn = &ffi_closure_OBSD; + + /* or.u %r10, %r0, %hi16(fn) */ + tramp[0] = 0x5d400000 | (((unsigned int)fn) >> 16); + /* or.u %r13, %r0, %hi16(closure) */ + tramp[1] = 0x5da00000 | ((unsigned int)closure >> 16); + /* or %r10, %r10, %lo16(fn) */ + tramp[2] = 0x594a0000 | (((unsigned int)fn) & 0xffff); + /* jmp.n %r10 */ + tramp[3] = 0xf400c40a; + /* or %r13, %r13, %lo16(closure) */ + tramp[4] = 0x59ad0000 | ((unsigned int)closure & 0xffff); + + ffi_cacheflush_OBSD((unsigned int)codeloc, FFI_TRAMPOLINE_SIZE); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/m88k/ffitarget.h b/circuitpython/lib/libffi/src/m88k/ffitarget.h new file mode 100644 index 0000000..e52bf9f --- /dev/null +++ b/circuitpython/lib/libffi/src/m88k/ffitarget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * m88k Foreign Function Interface + */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_OBSD, + FFI_DEFAULT_ABI = FFI_OBSD, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 0x14 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/m88k/obsd.S b/circuitpython/lib/libffi/src/m88k/obsd.S new file mode 100644 index 0000000..1944a23 --- /dev/null +++ b/circuitpython/lib/libffi/src/m88k/obsd.S @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * m88k Foreign Function Interface + */ + +#define LIBFFI_ASM +#include +#include + + .text + +/* + * ffi_cacheflush_OBSD(unsigned int addr, %r2 + * unsigned int size); %r3 + */ + .align 4 + .globl ffi_cacheflush_OBSD + .type ffi_cacheflush_OBSD,@function +ffi_cacheflush_OBSD: + tb0 0, %r0, 451 + or %r0, %r0, %r0 + jmp %r1 + .size ffi_cacheflush_OBSD, . - ffi_cacheflush_OBSD + +/* + * ffi_call_OBSD(unsigned bytes, %r2 + * extended_cif *ecif, %r3 + * unsigned flags, %r4 + * void *rvalue, %r5 + * void (*fn)()); %r6 + */ + .align 4 + .globl ffi_call_OBSD + .type ffi_call_OBSD,@function +ffi_call_OBSD: + subu %r31, %r31, 32 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 32 + + | Save the few arguments we'll need after ffi_prep_args() + st.d %r4, %r31, 8 + st %r6, %r31, 16 + + | Allocate room for the image of r2-r9, and the stack space for + | the args (rounded to a 16-byte boundary) + addu %r2, %r2, (8 * 4) + 15 + clr %r2, %r2, 4<0> + subu %r31, %r31, %r2 + + | Fill register and stack image + or %r2, %r31, %r0 +#ifdef PIC + bsr ffi_prep_args#plt +#else + bsr ffi_prep_args +#endif + + | Save pointer to return struct address, if any + or %r12, %r2, %r0 + + | Get function pointer + subu %r4, %r30, 32 + ld %r1, %r4, 16 + + | Fetch the register arguments + ld.d %r2, %r31, (0 * 4) + ld.d %r4, %r31, (2 * 4) + ld.d %r6, %r31, (4 * 4) + ld.d %r8, %r31, (6 * 4) + addu %r31, %r31, (8 * 4) + + | Invoke the function + jsr %r1 + + | Restore stack now that we don't need the args anymore + subu %r31, %r30, 32 + + | Figure out what to return as the function's return value + ld %r5, %r31, 12 | rvalue + ld %r4, %r31, 8 | flags + + bcnd eq0, %r5, 9f + + bb0 0, %r4, 1f | CIF_FLAGS_INT + st %r2, %r5, 0 + br 9f + +1: + bb0 1, %r4, 1f | CIF_FLAGS_DINT + st.d %r2, %r5, 0 + br 9f + +1: +9: + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 32 + .size ffi_call_OBSD, . - ffi_call_OBSD + +/* + * ffi_closure_OBSD(ffi_closure *closure); %r13 + */ + .align 4 + .globl ffi_closure_OBSD + .type ffi_closure_OBSD, @function +ffi_closure_OBSD: + subu %r31, %r31, 16 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 16 + + | Make room on the stack for saved register arguments and return + | value + subu %r31, %r31, (8 * 4) + (2 * 4) + st.d %r2, %r31, (0 * 4) + st.d %r4, %r31, (2 * 4) + st.d %r6, %r31, (4 * 4) + st.d %r8, %r31, (6 * 4) + + | Invoke the closure function + or %r5, %r30, 0 | calling stack + addu %r4, %r31, 0 | saved registers + addu %r3, %r31, (8 * 4) | return value + or %r2, %r13, %r0 | closure +#ifdef PIC + bsr ffi_closure_OBSD_inner#plt +#else + bsr ffi_closure_OBSD_inner +#endif + + | Figure out what to return as the function's return value + bb0 0, %r2, 1f | CIF_FLAGS_INT + ld %r2, %r31, (8 * 4) + br 9f + +1: + bb0 1, %r2, 1f | CIF_FLAGS_DINT + ld.d %r2, %r31, (8 * 4) + br 9f + +1: +9: + subu %r31, %r30, 16 + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 16 + .size ffi_closure_OBSD,.-ffi_closure_OBSD + +/* + * ffi_closure_struct_OBSD(ffi_closure *closure); %r13 + */ + .align 4 + .globl ffi_closure_struct_OBSD + .type ffi_closure_struct_OBSD, @function +ffi_closure_struct_OBSD: + subu %r31, %r31, 16 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 16 + + | Make room on the stack for saved register arguments + subu %r31, %r31, (8 * 4) + st.d %r2, %r31, (0 * 4) + st.d %r4, %r31, (2 * 4) + st.d %r6, %r31, (4 * 4) + st.d %r8, %r31, (6 * 4) + + | Invoke the closure function + or %r5, %r30, 0 | calling stack + addu %r4, %r31, 0 | saved registers + or %r3, %r12, 0 | return value + or %r2, %r13, %r0 | closure +#ifdef PIC + bsr ffi_closure_OBSD_inner#plt +#else + bsr ffi_closure_OBSD_inner +#endif + + subu %r31, %r30, 16 + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 16 + .size ffi_closure_struct_OBSD,.-ffi_closure_struct_OBSD diff --git a/circuitpython/lib/libffi/src/metag/ffi.c b/circuitpython/lib/libffi/src/metag/ffi.c new file mode 100644 index 0000000..46b383e --- /dev/null +++ b/circuitpython/lib/libffi/src/metag/ffi.c @@ -0,0 +1,330 @@ +/* ---------------------------------------------------------------------- + ffi.c - Copyright (c) 2013 Imagination Technologies + + Meta Foreign Function Interface + 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 SIMON POSNJAK 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 +#include + +#include + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +/* + * ffi_prep_args is called by the assembly routine once stack space has been + * allocated for the function's arguments + */ + +unsigned int ffi_prep_args(char *stack, extended_cif *ecif) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + + /* Store return value */ + if ( ecif->cif->flags == FFI_TYPE_STRUCT ) { + argp -= 4; + *(void **) argp = ecif->rvalue; + } + + p_argv = ecif->avalue; + + /* point to next location */ + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; (i != 0); i--, p_arg++, p_argv++) + { + size_t z; + + /* Move argp to address of argument */ + z = (*p_arg)->size; + argp -= z; + + /* Align if necessary */ + argp = (char *) ALIGN_DOWN(ALIGN_DOWN(argp, (*p_arg)->alignment), 4); + + if (z < sizeof(int)) { + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + case FFI_TYPE_STRUCT: + memcpy(argp, *p_argv, (*p_arg)->size); + break; + default: + FFI_ASSERT(0); + } + } else if ( z == sizeof(int)) { + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + } else { + memcpy(argp, *p_argv, z); + } + } + + /* return the size of the arguments to be passed in registers, + padded to an 8 byte boundary to preserve stack alignment */ + return ALIGN(MIN(stack - argp, 6*4), 8); +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + ffi_type **ptr; + unsigned i, bytes = 0; + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) { + if ((*ptr)->size == 0) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type, do this + check after the initialization. */ + FFI_ASSERT_VALID_TYPE(*ptr); + + /* Add any padding if necessary */ + if (((*ptr)->alignment - 1) & bytes) + bytes = ALIGN(bytes, (*ptr)->alignment); + + bytes += ALIGN((*ptr)->size, 4); + } + + /* Ensure arg space is aligned to an 8-byte boundary */ + bytes = ALIGN(bytes, 8); + + /* Make space for the return structure pointer */ + if (cif->rtype->type == FFI_TYPE_STRUCT) { + bytes += sizeof(void*); + + /* Ensure stack is aligned to an 8-byte boundary */ + bytes = ALIGN(bytes, 8); + } + + cif->bytes = bytes; + + /* Set the return type flag */ + switch (cif->rtype->type) { + case FFI_TYPE_VOID: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + cif->flags = (unsigned) cif->rtype->type; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags = (unsigned) FFI_TYPE_SINT64; + break; + case FFI_TYPE_STRUCT: + /* Meta can store return values which are <= 64 bits */ + if (cif->rtype->size <= 4) + /* Returned to D0Re0 as 32-bit value */ + cif->flags = (unsigned)FFI_TYPE_INT; + else if ((cif->rtype->size > 4) && (cif->rtype->size <= 8)) + /* Returned valued is stored to D1Re0|R0Re0 */ + cif->flags = (unsigned)FFI_TYPE_DOUBLE; + else + /* value stored in memory */ + cif->flags = (unsigned)FFI_TYPE_STRUCT; + break; + default: + cif->flags = (unsigned)FFI_TYPE_INT; + break; + } + return FFI_OK; +} + +extern void ffi_call_SYSV(void (*fn)(void), extended_cif *, unsigned, unsigned, double *); + +/* + * Exported in API. Entry point + * cif -> ffi_cif object + * fn -> function pointer + * rvalue -> pointer to return value + * avalue -> vector of void * pointers pointing to memory locations holding the + * arguments + */ +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + int small_struct = (((cif->flags == FFI_TYPE_INT) || (cif->flags == FFI_TYPE_DOUBLE)) && (cif->rtype->type == FFI_TYPE_STRUCT)); + ecif.cif = cif; + ecif.avalue = avalue; + + double temp; + + /* + * If the return value is a struct and we don't have a return value address + * then we need to make one + */ + + if ((rvalue == NULL ) && (cif->flags == FFI_TYPE_STRUCT)) + ecif.rvalue = alloca(cif->rtype->size); + else if (small_struct) + ecif.rvalue = &temp; + else + ecif.rvalue = rvalue; + + switch (cif->abi) { + case FFI_SYSV: + ffi_call_SYSV(fn, &ecif, cif->bytes, cif->flags, ecif.rvalue); + break; + default: + FFI_ASSERT(0); + break; + } + + if (small_struct) + memcpy (rvalue, &temp, cif->rtype->size); +} + +/* private members */ + +static void ffi_prep_incoming_args_SYSV (char *, void **, void **, + ffi_cif*, float *); + +void ffi_closure_SYSV (ffi_closure *); + +/* Do NOT change that without changing the FFI_TRAMPOLINE_SIZE */ +extern unsigned int ffi_metag_trampoline[10]; /* 10 instructions */ + +/* end of private members */ + +/* + * __tramp: trampoline memory location + * __fun: assembly routine + * __ctx: memory location for wrapper + * + * At this point, tramp[0] == __ctx ! + */ +void ffi_init_trampoline(unsigned char *__tramp, unsigned int __fun, unsigned int __ctx) { + memcpy (__tramp, ffi_metag_trampoline, sizeof(ffi_metag_trampoline)); + *(unsigned int*) &__tramp[40] = __ctx; + *(unsigned int*) &__tramp[44] = __fun; + /* This will flush the instruction cache */ + __builtin_meta2_cachewd(&__tramp[0], 1); + __builtin_meta2_cachewd(&__tramp[47], 1); +} + + + +/* the cif must already be prepared */ + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + void (*closure_func)(ffi_closure*) = NULL; + + if (cif->abi == FFI_SYSV) + closure_func = &ffi_closure_SYSV; + else + return FFI_BAD_ABI; + + ffi_init_trampoline( + (unsigned char*)&closure->tramp[0], + (unsigned int)closure_func, + (unsigned int)codeloc); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + + +/* This function is jumped to by the trampoline */ +unsigned int ffi_closure_SYSV_inner (closure, respp, args, vfp_args) + ffi_closure *closure; + void **respp; + void *args; + void *vfp_args; +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void*)); + + /* + * This call will initialize ARG_AREA, such that each + * element in that array points to the corresponding + * value on the stack; and if the function returns + * a structure, it will re-set RESP to point to the + * structure return address. + */ + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args); + + (closure->fun) ( cif, *respp, arg_area, closure->user_data); + + return cif->flags; +} + +static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, + void **avalue, ffi_cif *cif, + float *vfp_stack) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + /* stack points to original arguments */ + argp = stack; + + /* Store return value */ + if ( cif->flags == FFI_TYPE_STRUCT ) { + argp -= 4; + *rvalue = *(void **) argp; + } + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) { + size_t z; + size_t alignment; + + alignment = (*p_arg)->alignment; + if (alignment < 4) + alignment = 4; + if ((alignment - 1) & (unsigned)argp) + argp = (char *) ALIGN(argp, alignment); + + z = (*p_arg)->size; + *p_argv = (void*) argp; + p_argv++; + argp -= z; + } + return; +} diff --git a/circuitpython/lib/libffi/src/metag/ffitarget.h b/circuitpython/lib/libffi/src/metag/ffitarget.h new file mode 100644 index 0000000..7b9dbeb --- /dev/null +++ b/circuitpython/lib/libffi/src/metag/ffitarget.h @@ -0,0 +1,53 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2013 Imagination Technologies Ltd. + Target configuration macros for Meta + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_DEFAULT_ABI = FFI_SYSV, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1, +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 48 +#define FFI_NATIVE_RAW_API 0 + +#endif + diff --git a/circuitpython/lib/libffi/src/metag/sysv.S b/circuitpython/lib/libffi/src/metag/sysv.S new file mode 100644 index 0000000..b4b2a3b --- /dev/null +++ b/circuitpython/lib/libffi/src/metag/sysv.S @@ -0,0 +1,311 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2013 Imagination Technologies Ltd. + + Meta Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include +#ifdef HAVE_MACHINE_ASM_H +#include +#else +#ifdef __USER_LABEL_PREFIX__ +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ +#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x) +#else +#define CNAME(x) x +#endif +#define ENTRY(x) .globl CNAME(x); .type CNAME(x), %function; CNAME(x): +#endif + +#ifdef __ELF__ +#define LSYM(x) .x +#else +#define LSYM(x) x +#endif + +.macro call_reg x= + .text + .balign 4 + mov D1RtP, \x + swap D1RtP, PC +.endm + +! Save register arguments +.macro SAVE_ARGS + .text + .balign 4 + setl [A0StP++], D0Ar6, D1Ar5 + setl [A0StP++], D0Ar4, D1Ar3 + setl [A0StP++], D0Ar2, D1Ar1 +.endm + +! Save retrun, frame pointer and other regs +.macro SAVE_REGS regs= + .text + .balign 4 + setl [A0StP++], D0FrT, D1RtP + ! Needs to be a pair of regs + .ifnc "\regs","" + setl [A0StP++], \regs + .endif +.endm + +! Declare a global function +.macro METAG_FUNC_START name + .text + .balign 4 + ENTRY(\name) +.endm + +! Return registers from the stack. Reverse SAVE_REGS operation +.macro RET_REGS regs=, cond= + .ifnc "\regs", "" + getl \regs, [--A0StP] + .endif + getl D0FrT, D1RtP, [--A0StP] +.endm + +! Return arguments +.macro RET_ARGS + getl D0Ar2, D1Ar1, [--A0StP] + getl D0Ar4, D1Ar3, [--A0StP] + getl D0Ar6, D1Ar5, [--A0StP] +.endm + + + ! D1Ar1: fn + ! D0Ar2: &ecif + ! D1Ar3: cif->bytes + ! D0Ar4: fig->flags + ! D1Ar5: ecif.rvalue + + ! This assumes we are using GNU as +METAG_FUNC_START ffi_call_SYSV + ! Save argument registers + + SAVE_ARGS + + ! new frame + mov D0FrT, A0FrP + add A0FrP, A0StP, #0 + + ! Preserve the old frame pointer + SAVE_REGS "D1.5, D0.5" + + ! Make room for new args. cifs->bytes is the total space for input + ! and return arguments + + add A0StP, A0StP, D1Ar3 + + ! Preserve cifs->bytes & fn + mov D0.5, D1Ar3 + mov D1.5, D1Ar1 + + ! Place all of the ffi_prep_args in position + mov D1Ar1, A0StP + + ! Call ffi_prep_args(stack, &ecif) +#ifdef __PIC__ + callr D1RtP, CNAME(ffi_prep_args@PLT) +#else + callr D1RtP, CNAME(ffi_prep_args) +#endif + + ! Restore fn pointer + + ! The foreign stack should look like this + ! XXXXX XXXXXX <--- stack pointer + ! FnArgN rvalue + ! FnArgN+2 FnArgN+1 + ! FnArgN+4 FnArgN+3 + ! .... + ! + + ! A0StP now points to the first (or return) argument + 4 + + ! Preserve cif->bytes + getl D0Ar2, D1Ar1, [--A0StP] + getl D0Ar4, D1Ar3, [--A0StP] + getl D0Ar6, D1Ar5, [--A0StP] + + ! Place A0StP to the first argument again + add A0StP, A0StP, #24 ! That's because we loaded 6 regs x 4 byte each + + ! A0FrP points to the initial stack without the reserved space for the + ! cifs->bytes, whilst A0StP points to the stack after the space allocation + + ! fn was the first argument of ffi_call_SYSV. + ! The stack at this point looks like this: + ! + ! A0StP(on entry to _SYSV) -> Arg6 Arg5 | low + ! Arg4 Arg3 | + ! Arg2 Arg1 | + ! A0FrP ----> D0FrtP D1RtP | + ! D1.5 D0.5 | + ! A0StP(bf prep_args) -> FnArgn FnArgn-1 | + ! FnArgn-2FnArgn-3 | + ! ................ | <= cifs->bytes + ! FnArg4 FnArg3 | + ! A0StP (prv_A0StP+cifs->bytes) FnArg2 FnArg1 | high + ! + ! fn was in Arg1 so it's located in in A0FrP+#-0xC + ! + + ! D0Re0 contains the size of arguments stored in registers + sub A0StP, A0StP, D0Re0 + + ! Arg1 is the function pointer for the foreign call. This has been + ! preserved in D1.5 + + ! Time to call (fn). Arguments should be like this: + ! Arg1-Arg6 are loaded to regs + ! The rest of the arguments are stored in stack pointed by A0StP + + call_reg D1.5 + + ! Reset stack. + + mov A0StP, A0FrP + + ! Load Arg1 with the pointer to storage for the return type + ! This was stored in Arg5 + + getd D1Ar1, [A0FrP+#-20] + + ! Load D0Ar2 with the return type code. This was stored in Arg4 (flags) + + getd D0Ar2, [A0FrP+#-16] + + ! We are ready to start processing the return value + ! D0Re0 (and D1Re0) hold the return value + + ! If the return value is NULL, assume no return value + cmp D1Ar1, #0 + beq LSYM(Lepilogue) + + ! return INT + cmp D0Ar2, #FFI_TYPE_INT + ! Sadly, there is no setd{cc} instruction so we need to workaround that + bne .INT64 + setd [D1Ar1], D0Re0 + b LSYM(Lepilogue) + + ! return INT64 +.INT64: + cmp D0Ar2, #FFI_TYPE_SINT64 + setleq [D1Ar1], D0Re0, D1Re0 + + ! return DOUBLE + cmp D0Ar2, #FFI_TYPE_DOUBLE + setl [D1AR1++], D0Re0, D1Re0 + +LSYM(Lepilogue): + ! At this point, the stack pointer points right after the argument + ! saved area. We need to restore 4 regs, therefore we need to move + ! 16 bytes ahead. + add A0StP, A0StP, #16 + RET_REGS "D1.5, D0.5" + RET_ARGS + getd D0Re0, [A0StP] + mov A0FrP, D0FrT + swap D1RtP, PC + +.ffi_call_SYSV_end: + .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) + + +/* + (called by ffi_metag_trampoline) + void ffi_closure_SYSV (ffi_closure*) + + (called by ffi_closure_SYSV) + unsigned int FFI_HIDDEN + ffi_closure_SYSV_inner (closure,respp, args) + ffi_closure *closure; + void **respp; + void *args; +*/ + +METAG_FUNC_START ffi_closure_SYSV + ! We assume that D1Ar1 holds the address of the + ! ffi_closure struct. We will use that to fetch the + ! arguments. The stack pointer points to an empty space + ! and it is ready to store more data. + + ! D1Ar1 is ready + ! Allocate stack space for return value + add A0StP, A0StP, #8 + ! Store it to D0Ar2 + sub D0Ar2, A0StP, #8 + + sub D1Ar3, A0FrP, #4 + + ! D1Ar3 contains the address of the original D1Ar1 argument + ! We need to subtract #4 later on + + ! Preverve D0Ar2 + mov D0.5, D0Ar2 + +#ifdef __PIC__ + callr D1RtP, CNAME(ffi_closure_SYSV_inner@PLT) +#else + callr D1RtP, CNAME(ffi_closure_SYSV_inner) +#endif + + ! Check the return value and store it to D0.5 + cmp D0Re0, #FFI_TYPE_INT + beq .Lretint + cmp D0Re0, #FFI_TYPE_DOUBLE + beq .Lretdouble +.Lclosure_epilogue: + sub A0StP, A0StP, #8 + RET_REGS "D1.5, D0.5" + RET_ARGS + swap D1RtP, PC + +.Lretint: + setd [D0.5], D0Re0 + b .Lclosure_epilogue +.Lretdouble: + setl [D0.5++], D0Re0, D1Re0 + b .Lclosure_epilogue +.ffi_closure_SYSV_end: +.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) + + +ENTRY(ffi_metag_trampoline) + SAVE_ARGS + ! New frame + mov A0FrP, A0StP + SAVE_REGS "D1.5, D0.5" + mov D0.5, PC + ! Load D1Ar1 the value of ffi_metag_trampoline + getd D1Ar1, [D0.5 + #8] + ! Jump to ffi_closure_SYSV + getd PC, [D0.5 + #12] diff --git a/circuitpython/lib/libffi/src/microblaze/ffi.c b/circuitpython/lib/libffi/src/microblaze/ffi.c new file mode 100644 index 0000000..ea962ea --- /dev/null +++ b/circuitpython/lib/libffi/src/microblaze/ffi.c @@ -0,0 +1,321 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2012, 2013 Xilinx, Inc + + MicroBlaze Foreign Function Interface + + 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 +#include + +extern void ffi_call_SYSV(void (*)(void*, extended_cif*), extended_cif*, + unsigned int, unsigned int, unsigned int*, void (*fn)(void), + unsigned int, unsigned int); + +extern void ffi_closure_SYSV(void); + +#define WORD_SIZE sizeof(unsigned int) +#define ARGS_REGISTER_SIZE (WORD_SIZE * 6) +#define WORD_ALIGN(x) ALIGN(x, WORD_SIZE) + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ +void ffi_prep_args(void* stack, extended_cif* ecif) +{ + unsigned int i; + ffi_type** p_arg; + void** p_argv; + void* stack_args_p = stack; + + p_argv = ecif->avalue; + + if (ecif == NULL || ecif->cif == NULL) { + return; /* no description to prepare */ + } + + if ((ecif->cif->rtype != NULL) && + (ecif->cif->rtype->type == FFI_TYPE_STRUCT)) + { + /* if return type is a struct which is referenced on the stack/reg5, + * by a pointer. Stored the return value pointer in r5. + */ + char* addr = stack_args_p; + memcpy(addr, &(ecif->rvalue), WORD_SIZE); + stack_args_p += WORD_SIZE; + } + + if (ecif->avalue == NULL) { + return; /* no arguments to prepare */ + } + + for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; + i++, p_arg++) + { + size_t size = (*p_arg)->size; + int type = (*p_arg)->type; + void* value = p_argv[i]; + char* addr = stack_args_p; + int aligned_size = WORD_ALIGN(size); + + /* force word alignment on the stack */ + stack_args_p += aligned_size; + + switch (type) + { + case FFI_TYPE_UINT8: + *(unsigned int *)addr = (unsigned int)*(UINT8*)(value); + break; + case FFI_TYPE_SINT8: + *(signed int *)addr = (signed int)*(SINT8*)(value); + break; + case FFI_TYPE_UINT16: + *(unsigned int *)addr = (unsigned int)*(UINT16*)(value); + break; + case FFI_TYPE_SINT16: + *(signed int *)addr = (signed int)*(SINT16*)(value); + break; + case FFI_TYPE_STRUCT: +#if __BIG_ENDIAN__ + /* + * MicroBlaze toolchain appears to emit: + * bsrli r5, r5, 8 (caller) + * ... + * + * ... + * bslli r5, r5, 8 (callee) + * + * For structs like "struct a { uint8_t a[3]; };", when passed + * by value. + * + * Structs like "struct b { uint16_t a; };" are also expected + * to be packed strangely in registers. + * + * This appears to be because the microblaze toolchain expects + * "struct b == uint16_t", which is only any issue for big + * endian. + * + * The following is a work around for big-endian only, for the + * above mentioned case, it will re-align the contents of a + * <= 3-byte struct value. + */ + if (size < WORD_SIZE) + { + memcpy (addr + (WORD_SIZE - size), value, size); + break; + } +#endif + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_FLOAT: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + default: + memcpy(addr, value, aligned_size); + } + } +} + +ffi_status ffi_prep_cif_machdep(ffi_cif* cif) +{ + /* check ABI */ + switch (cif->abi) + { + case FFI_SYSV: + break; + default: + return FFI_BAD_ABI; + } + return FFI_OK; +} + +void ffi_call(ffi_cif* cif, void (*fn)(void), void* rvalue, void** avalue) +{ + extended_cif ecif; + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { + ecif.rvalue = alloca(cif->rtype->size); + } else { + ecif.rvalue = rvalue; + } + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn, cif->rtype->type, cif->rtype->size); + break; + default: + FFI_ASSERT(0); + break; + } +} + +void ffi_closure_call_SYSV(void* register_args, void* stack_args, + ffi_closure* closure, void* rvalue, + unsigned int* rtype, unsigned int* rsize) +{ + /* prepare arguments for closure call */ + ffi_cif* cif = closure->cif; + ffi_type** arg_types = cif->arg_types; + + /* re-allocate data for the args. This needs to be done in order to keep + * multi-word objects (e.g. structs) in contiguous memory. Callers are not + * required to store the value of args in the lower 6 words in the stack + * (although they are allocated in the stack). + */ + char* stackclone = alloca(cif->bytes); + void** avalue = alloca(cif->nargs * sizeof(void*)); + void* struct_rvalue = NULL; + char* ptr = stackclone; + int i; + + /* copy registers into stack clone */ + int registers_used = cif->bytes; + if (registers_used > ARGS_REGISTER_SIZE) { + registers_used = ARGS_REGISTER_SIZE; + } + memcpy(stackclone, register_args, registers_used); + + /* copy stack allocated args into stack clone */ + if (cif->bytes > ARGS_REGISTER_SIZE) { + int stack_used = cif->bytes - ARGS_REGISTER_SIZE; + memcpy(stackclone + ARGS_REGISTER_SIZE, stack_args, stack_used); + } + + /* preserve struct type return pointer passing */ + if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { + struct_rvalue = *((void**)ptr); + ptr += WORD_SIZE; + } + + /* populate arg pointer list */ + for (i = 0; i < cif->nargs; i++) + { + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: +#ifdef __BIG_ENDIAN__ + avalue[i] = ptr + 3; +#else + avalue[i] = ptr; +#endif + break; + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: +#ifdef __BIG_ENDIAN__ + avalue[i] = ptr + 2; +#else + avalue[i] = ptr; +#endif + break; + case FFI_TYPE_STRUCT: +#if __BIG_ENDIAN__ + /* + * Work around strange ABI behaviour. + * (see info in ffi_prep_args) + */ + if (arg_types[i]->size < WORD_SIZE) + { + memcpy (ptr, ptr + (WORD_SIZE - arg_types[i]->size), arg_types[i]->size); + } +#endif + avalue[i] = (void*)ptr; + break; + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_DOUBLE: + avalue[i] = ptr; + break; + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_FLOAT: + default: + /* default 4-byte argument */ + avalue[i] = ptr; + break; + } + ptr += WORD_ALIGN(arg_types[i]->size); + } + + /* set the return type info passed back to the wrapper */ + *rsize = cif->rtype->size; + *rtype = cif->rtype->type; + if (struct_rvalue != NULL) { + closure->fun(cif, struct_rvalue, avalue, closure->user_data); + /* copy struct return pointer value into function return value */ + *((void**)rvalue) = struct_rvalue; + } else { + closure->fun(cif, rvalue, avalue, closure->user_data); + } +} + +ffi_status ffi_prep_closure_loc( + ffi_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void* user_data, void* codeloc) +{ + unsigned long* tramp = (unsigned long*)&(closure->tramp[0]); + unsigned long cls = (unsigned long)codeloc; + unsigned long fn = 0; + unsigned long fn_closure_call_sysv = (unsigned long)ffi_closure_call_SYSV; + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + switch (cif->abi) + { + case FFI_SYSV: + fn = (unsigned long)ffi_closure_SYSV; + + /* load r11 (temp) with fn */ + /* imm fn(upper) */ + tramp[0] = 0xb0000000 | ((fn >> 16) & 0xffff); + /* addik r11, r0, fn(lower) */ + tramp[1] = 0x31600000 | (fn & 0xffff); + + /* load r12 (temp) with cls */ + /* imm cls(upper) */ + tramp[2] = 0xb0000000 | ((cls >> 16) & 0xffff); + /* addik r12, r0, cls(lower) */ + tramp[3] = 0x31800000 | (cls & 0xffff); + + /* load r3 (temp) with ffi_closure_call_SYSV */ + /* imm fn_closure_call_sysv(upper) */ + tramp[4] = 0xb0000000 | ((fn_closure_call_sysv >> 16) & 0xffff); + /* addik r3, r0, fn_closure_call_sysv(lower) */ + tramp[5] = 0x30600000 | (fn_closure_call_sysv & 0xffff); + /* branch/jump to address stored in r11 (fn) */ + tramp[6] = 0x98085800; /* bra r11 */ + + break; + default: + return FFI_BAD_ABI; + } + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/microblaze/ffitarget.h b/circuitpython/lib/libffi/src/microblaze/ffitarget.h new file mode 100644 index 0000000..c6fa5a4 --- /dev/null +++ b/circuitpython/lib/libffi/src/microblaze/ffitarget.h @@ -0,0 +1,53 @@ +/* ----------------------------------------------------------------------- + ffitarget.h - Copyright (c) 2012, 2013 Xilinx, Inc + + Target configuration macros for MicroBlaze. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +/* Definitions for closures */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 + +#define FFI_TRAMPOLINE_SIZE (4*8) + +#endif diff --git a/circuitpython/lib/libffi/src/microblaze/sysv.S b/circuitpython/lib/libffi/src/microblaze/sysv.S new file mode 100644 index 0000000..ea43e9d --- /dev/null +++ b/circuitpython/lib/libffi/src/microblaze/sysv.S @@ -0,0 +1,302 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2012, 2013 Xilinx, Inc + + MicroBlaze Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + + /* + * arg[0] (r5) = ffi_prep_args, + * arg[1] (r6) = &ecif, + * arg[2] (r7) = cif->bytes, + * arg[3] (r8) = cif->flags, + * arg[4] (r9) = ecif.rvalue, + * arg[5] (r10) = fn + * arg[6] (sp[0]) = cif->rtype->type + * arg[7] (sp[4]) = cif->rtype->size + */ + .text + .globl ffi_call_SYSV + .type ffi_call_SYSV, @function +ffi_call_SYSV: + /* push callee saves */ + addik r1, r1, -20 + swi r19, r1, 0 /* Frame Pointer */ + swi r20, r1, 4 /* PIC register */ + swi r21, r1, 8 /* PIC register */ + swi r22, r1, 12 /* save for locals */ + swi r23, r1, 16 /* save for locals */ + + /* save the r5-r10 registers in the stack */ + addik r1, r1, -24 /* increment sp to store 6x 32-bit words */ + swi r5, r1, 0 + swi r6, r1, 4 + swi r7, r1, 8 + swi r8, r1, 12 + swi r9, r1, 16 + swi r10, r1, 20 + + /* save function pointer */ + addik r3, r5, 0 /* copy ffi_prep_args into r3 */ + addik r22, r1, 0 /* save sp for unallocated args into r22 (callee-saved) */ + addik r23, r10, 0 /* save function address into r23 (callee-saved) */ + + /* prepare stack with allocation for n (bytes = r7) args */ + rsub r1, r7, r1 /* subtract bytes from sp */ + + /* prep args for ffi_prep_args call */ + addik r5, r1, 0 /* store stack pointer into arg[0] */ + /* r6 still holds ecif for arg[1] */ + + /* Call ffi_prep_args(stack, &ecif). */ + addik r1, r1, -4 + swi r15, r1, 0 /* store the link register in the frame */ + brald r15, r3 + nop /* branch has delay slot */ + lwi r15, r1, 0 + addik r1, r1, 4 /* restore the link register from the frame */ + /* returns calling stack pointer location */ + + /* prepare args for fn call, prep_args populates them onto the stack */ + lwi r5, r1, 0 /* arg[0] */ + lwi r6, r1, 4 /* arg[1] */ + lwi r7, r1, 8 /* arg[2] */ + lwi r8, r1, 12 /* arg[3] */ + lwi r9, r1, 16 /* arg[4] */ + lwi r10, r1, 20 /* arg[5] */ + + /* call (fn) (...). */ + addik r1, r1, -4 + swi r15, r1, 0 /* store the link register in the frame */ + brald r15, r23 + nop /* branch has delay slot */ + lwi r15, r1, 0 + addik r1, r1, 4 /* restore the link register from the frame */ + + /* Remove the space we pushed for the args. */ + addik r1, r22, 0 /* restore old SP */ + + /* restore this functions parameters */ + lwi r5, r1, 0 /* arg[0] */ + lwi r6, r1, 4 /* arg[1] */ + lwi r7, r1, 8 /* arg[2] */ + lwi r8, r1, 12 /* arg[3] */ + lwi r9, r1, 16 /* arg[4] */ + lwi r10, r1, 20 /* arg[5] */ + addik r1, r1, 24 /* decrement sp to de-allocate 6x 32-bit words */ + + /* If the return value pointer is NULL, assume no return value. */ + beqi r9, ffi_call_SYSV_end + + lwi r22, r1, 48 /* get return type (20 for locals + 28 for arg[6]) */ + lwi r23, r1, 52 /* get return size (20 for locals + 32 for arg[7]) */ + + /* Check if return type is actually a struct, do nothing */ + rsubi r11, r22, FFI_TYPE_STRUCT + beqi r11, ffi_call_SYSV_end + + /* Return 8bit */ + rsubi r11, r23, 1 + beqi r11, ffi_call_SYSV_store8 + + /* Return 16bit */ + rsubi r11, r23, 2 + beqi r11, ffi_call_SYSV_store16 + + /* Return 32bit */ + rsubi r11, r23, 4 + beqi r11, ffi_call_SYSV_store32 + + /* Return 64bit */ + rsubi r11, r23, 8 + beqi r11, ffi_call_SYSV_store64 + + /* Didn't match anything */ + bri ffi_call_SYSV_end + +ffi_call_SYSV_store64: + swi r3, r9, 0 /* store word r3 into return value */ + swi r4, r9, 4 /* store word r4 into return value */ + bri ffi_call_SYSV_end + +ffi_call_SYSV_store32: + swi r3, r9, 0 /* store word r3 into return value */ + bri ffi_call_SYSV_end + +ffi_call_SYSV_store16: +#ifdef __BIG_ENDIAN__ + shi r3, r9, 2 /* store half-word r3 into return value */ +#else + shi r3, r9, 0 /* store half-word r3 into return value */ +#endif + bri ffi_call_SYSV_end + +ffi_call_SYSV_store8: +#ifdef __BIG_ENDIAN__ + sbi r3, r9, 3 /* store byte r3 into return value */ +#else + sbi r3, r9, 0 /* store byte r3 into return value */ +#endif + bri ffi_call_SYSV_end + +ffi_call_SYSV_end: + /* callee restores */ + lwi r19, r1, 0 /* frame pointer */ + lwi r20, r1, 4 /* PIC register */ + lwi r21, r1, 8 /* PIC register */ + lwi r22, r1, 12 + lwi r23, r1, 16 + addik r1, r1, 20 + + /* return from sub-routine (with delay slot) */ + rtsd r15, 8 + nop + + .size ffi_call_SYSV, . - ffi_call_SYSV + +/* ------------------------------------------------------------------------- */ + + /* + * args passed into this function, are passed down to the callee. + * this function is the target of the closure trampoline, as such r12 is + * a pointer to the closure object. + */ + .text + .globl ffi_closure_SYSV + .type ffi_closure_SYSV, @function +ffi_closure_SYSV: + /* push callee saves */ + addik r11, r1, 28 /* save stack args start location (excluding regs/link) */ + addik r1, r1, -12 + swi r19, r1, 0 /* Frame Pointer */ + swi r20, r1, 4 /* PIC register */ + swi r21, r1, 8 /* PIC register */ + + /* store register args on stack */ + addik r1, r1, -24 + swi r5, r1, 0 + swi r6, r1, 4 + swi r7, r1, 8 + swi r8, r1, 12 + swi r9, r1, 16 + swi r10, r1, 20 + + /* setup args */ + addik r5, r1, 0 /* register_args */ + addik r6, r11, 0 /* stack_args */ + addik r7, r12, 0 /* closure object */ + addik r1, r1, -8 /* allocate return value */ + addik r8, r1, 0 /* void* rvalue */ + addik r1, r1, -8 /* allocate for return type/size values */ + addik r9, r1, 0 /* void* rtype */ + addik r10, r1, 4 /* void* rsize */ + + /* call the wrap_call function */ + addik r1, r1, -28 /* allocate args + link reg */ + swi r15, r1, 0 /* store the link register in the frame */ + brald r15, r3 + nop /* branch has delay slot */ + lwi r15, r1, 0 + addik r1, r1, 28 /* restore the link register from the frame */ + +ffi_closure_SYSV_prepare_return: + lwi r9, r1, 0 /* rtype */ + lwi r10, r1, 4 /* rsize */ + addik r1, r1, 8 /* de-allocate return info values */ + + /* Check if return type is actually a struct, store 4 bytes */ + rsubi r11, r9, FFI_TYPE_STRUCT + beqi r11, ffi_closure_SYSV_store32 + + /* Return 8bit */ + rsubi r11, r10, 1 + beqi r11, ffi_closure_SYSV_store8 + + /* Return 16bit */ + rsubi r11, r10, 2 + beqi r11, ffi_closure_SYSV_store16 + + /* Return 32bit */ + rsubi r11, r10, 4 + beqi r11, ffi_closure_SYSV_store32 + + /* Return 64bit */ + rsubi r11, r10, 8 + beqi r11, ffi_closure_SYSV_store64 + + /* Didn't match anything */ + bri ffi_closure_SYSV_end + +ffi_closure_SYSV_store64: + lwi r3, r1, 0 /* store word r3 into return value */ + lwi r4, r1, 4 /* store word r4 into return value */ + /* 64 bits == 2 words, no sign extend occurs */ + bri ffi_closure_SYSV_end + +ffi_closure_SYSV_store32: + lwi r3, r1, 0 /* store word r3 into return value */ + /* 32 bits == 1 word, no sign extend occurs */ + bri ffi_closure_SYSV_end + +ffi_closure_SYSV_store16: +#ifdef __BIG_ENDIAN__ + lhui r3, r1, 2 /* store half-word r3 into return value */ +#else + lhui r3, r1, 0 /* store half-word r3 into return value */ +#endif + rsubi r11, r9, FFI_TYPE_SINT16 + bnei r11, ffi_closure_SYSV_end + sext16 r3, r3 /* fix sign extend of sint8 */ + bri ffi_closure_SYSV_end + +ffi_closure_SYSV_store8: +#ifdef __BIG_ENDIAN__ + lbui r3, r1, 3 /* store byte r3 into return value */ +#else + lbui r3, r1, 0 /* store byte r3 into return value */ +#endif + rsubi r11, r9, FFI_TYPE_SINT8 + bnei r11, ffi_closure_SYSV_end + sext8 r3, r3 /* fix sign extend of sint8 */ + bri ffi_closure_SYSV_end + +ffi_closure_SYSV_end: + addik r1, r1, 8 /* de-allocate return value */ + + /* de-allocate stored args */ + addik r1, r1, 24 + + /* callee restores */ + lwi r19, r1, 0 /* frame pointer */ + lwi r20, r1, 4 /* PIC register */ + lwi r21, r1, 8 /* PIC register */ + addik r1, r1, 12 + + /* return from sub-routine (with delay slot) */ + rtsd r15, 8 + nop + + .size ffi_closure_SYSV, . - ffi_closure_SYSV diff --git a/circuitpython/lib/libffi/src/mips/ffi.c b/circuitpython/lib/libffi/src/mips/ffi.c new file mode 100644 index 0000000..5d0dd70 --- /dev/null +++ b/circuitpython/lib/libffi/src/mips/ffi.c @@ -0,0 +1,1050 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2011 Anthony Green + Copyright (c) 2008 David Daney + Copyright (c) 1996, 2007, 2008, 2011 Red Hat, Inc. + + MIPS Foreign Function Interface + + 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 +#include + +#include + +#ifdef __GNUC__ +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) +# define USE__BUILTIN___CLEAR_CACHE 1 +# endif +#endif + +#ifndef USE__BUILTIN___CLEAR_CACHE +# if defined(__OpenBSD__) +# include +# else +# include +# endif +#endif + +#ifdef FFI_DEBUG +# define FFI_MIPS_STOP_HERE() ffi_stop_here() +#else +# define FFI_MIPS_STOP_HERE() do {} while(0) +#endif + +#ifdef FFI_MIPS_N32 +#define FIX_ARGP \ +FFI_ASSERT(argp <= &stack[bytes]); \ +if (argp == &stack[bytes]) \ +{ \ + argp = stack; \ + FFI_MIPS_STOP_HERE(); \ +} +#else +#define FIX_ARGP +#endif + + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +static void ffi_prep_args(char *stack, + extended_cif *ecif, + int bytes, + int flags) +{ + int i; + void **p_argv; + char *argp; + ffi_type **p_arg; + +#ifdef FFI_MIPS_N32 + /* If more than 8 double words are used, the remainder go + on the stack. We reorder stuff on the stack here to + support this easily. */ + if (bytes > 8 * sizeof(ffi_arg)) + argp = &stack[bytes - (8 * sizeof(ffi_arg))]; + else + argp = stack; +#else + argp = stack; +#endif + + memset(stack, 0, bytes); + +#ifdef FFI_MIPS_N32 + if ( ecif->cif->rstruct_flag != 0 ) +#else + if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) +#endif + { + *(ffi_arg *) argp = (ffi_arg) ecif->rvalue; + argp += sizeof(ffi_arg); + FIX_ARGP; + } + + p_argv = ecif->avalue; + + for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++) + { + size_t z; + unsigned int a; + + /* Align if necessary. */ + a = (*p_arg)->alignment; + if (a < sizeof(ffi_arg)) + a = sizeof(ffi_arg); + + if ((a - 1) & (unsigned long) argp) + { + argp = (char *) ALIGN(argp, a); + FIX_ARGP; + } + + z = (*p_arg)->size; + if (z <= sizeof(ffi_arg)) + { + int type = (*p_arg)->type; + z = sizeof(ffi_arg); + + /* The size of a pointer depends on the ABI */ + if (type == FFI_TYPE_POINTER) + type = (ecif->cif->abi == FFI_N64 + || ecif->cif->abi == FFI_N64_SOFT_FLOAT) + ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; + + if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT + || ecif->cif->abi == FFI_N64_SOFT_FLOAT)) + { + switch (type) + { + case FFI_TYPE_FLOAT: + type = FFI_TYPE_UINT32; + break; + case FFI_TYPE_DOUBLE: + type = FFI_TYPE_UINT64; + break; + default: + break; + } + } + switch (type) + { + case FFI_TYPE_SINT8: + *(ffi_arg *)argp = *(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(ffi_arg *)argp = *(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(ffi_arg *)argp = *(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(ffi_arg *)argp = *(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_SINT32: + *(ffi_arg *)argp = *(SINT32 *)(* p_argv); + break; + + case FFI_TYPE_UINT32: +#ifdef FFI_MIPS_N32 + /* The N32 ABI requires that 32-bit integers + be sign-extended to 64-bits, regardless of + whether they are signed or unsigned. */ + *(ffi_arg *)argp = *(SINT32 *)(* p_argv); +#else + *(ffi_arg *)argp = *(UINT32 *)(* p_argv); +#endif + break; + + /* This can only happen with 64bit slots. */ + case FFI_TYPE_FLOAT: + *(float *) argp = *(float *)(* p_argv); + break; + + /* Handle structures. */ + default: + memcpy(argp, *p_argv, (*p_arg)->size); + break; + } + } + else + { +#ifdef FFI_MIPS_O32 + memcpy(argp, *p_argv, z); +#else + { + unsigned long end = (unsigned long) argp + z; + unsigned long cap = (unsigned long) stack + bytes; + + /* Check if the data will fit within the register space. + Handle it if it doesn't. */ + + if (end <= cap) + memcpy(argp, *p_argv, z); + else + { + unsigned long portion = cap - (unsigned long)argp; + + memcpy(argp, *p_argv, portion); + argp = stack; + z -= portion; + memcpy(argp, (void*)((unsigned long)(*p_argv) + portion), + z); + } + } +#endif + } + p_argv++; + argp += z; + FIX_ARGP; + } +} + +#ifdef FFI_MIPS_N32 + +/* The n32 spec says that if "a chunk consists solely of a double + float field (but not a double, which is part of a union), it + is passed in a floating point register. Any other chunk is + passed in an integer register". This code traverses structure + definitions and generates the appropriate flags. */ + +static unsigned +calc_n32_struct_flags(int soft_float, ffi_type *arg, + unsigned *loc, unsigned *arg_reg) +{ + unsigned flags = 0; + unsigned index = 0; + + ffi_type *e; + + if (soft_float) + return 0; + + while ((e = arg->elements[index])) + { + /* Align this object. */ + *loc = ALIGN(*loc, e->alignment); + if (e->type == FFI_TYPE_DOUBLE) + { + /* Already aligned to FFI_SIZEOF_ARG. */ + *arg_reg = *loc / FFI_SIZEOF_ARG; + if (*arg_reg > 7) + break; + flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS)); + *loc += e->size; + } + else + *loc += e->size; + index++; + } + /* Next Argument register at alignment of FFI_SIZEOF_ARG. */ + *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + + return flags; +} + +static unsigned +calc_n32_return_struct_flags(int soft_float, ffi_type *arg) +{ + unsigned flags = 0; + unsigned small = FFI_TYPE_SMALLSTRUCT; + ffi_type *e; + + /* Returning structures under n32 is a tricky thing. + A struct with only one or two floating point fields + is returned in $f0 (and $f2 if necessary). Any other + struct results at most 128 bits are returned in $2 + (the first 64 bits) and $3 (remainder, if necessary). + Larger structs are handled normally. */ + + if (arg->size > 16) + return 0; + + if (arg->size > 8) + small = FFI_TYPE_SMALLSTRUCT2; + + e = arg->elements[0]; + + if (e->type == FFI_TYPE_DOUBLE) + flags = FFI_TYPE_DOUBLE; + else if (e->type == FFI_TYPE_FLOAT) + flags = FFI_TYPE_FLOAT; + + if (flags && (e = arg->elements[1])) + { + if (e->type == FFI_TYPE_DOUBLE) + flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS; + else if (e->type == FFI_TYPE_FLOAT) + flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS; + else + return small; + + if (flags && (arg->elements[2])) + { + /* There are three arguments and the first two are + floats! This must be passed the old way. */ + return small; + } + if (soft_float) + flags += FFI_TYPE_STRUCT_SOFT; + } + else + if (!flags) + return small; + + return flags; +} + +#endif + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + cif->flags = 0; + +#ifdef FFI_MIPS_O32 + /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT + * does not have special handling for floating point args. + */ + + if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32) + { + if (cif->nargs > 0) + { + switch ((cif->arg_types)[0]->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + cif->flags += (cif->arg_types)[0]->type; + break; + + default: + break; + } + + if (cif->nargs > 1) + { + /* Only handle the second argument if the first + is a float or double. */ + if (cif->flags) + { + switch ((cif->arg_types)[1]->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS; + break; + + default: + break; + } + } + } + } + } + + /* Set the return type flag */ + + if (cif->abi == FFI_O32_SOFT_FLOAT) + { + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2); + break; + + case FFI_TYPE_FLOAT: + default: + cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); + break; + } + } + else + { + /* FFI_O32 */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2); + break; + + default: + cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); + break; + } + } +#endif + +#ifdef FFI_MIPS_N32 + /* Set the flags necessary for N32 processing */ + { + int type; + unsigned arg_reg = 0; + unsigned loc = 0; + unsigned count = (cif->nargs < 8) ? cif->nargs : 8; + unsigned index = 0; + + unsigned struct_flags = 0; + int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT + || cif->abi == FFI_N64_SOFT_FLOAT); + + if (cif->rtype->type == FFI_TYPE_STRUCT) + { + struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype); + + if (struct_flags == 0) + { + /* This means that the structure is being passed as + a hidden argument */ + + arg_reg = 1; + count = (cif->nargs < 7) ? cif->nargs : 7; + + cif->rstruct_flag = !0; + } + else + cif->rstruct_flag = 0; + } + else + cif->rstruct_flag = 0; + + while (count-- > 0 && arg_reg < 8) + { + type = (cif->arg_types)[index]->type; + if (soft_float) + { + switch (type) + { + case FFI_TYPE_FLOAT: + type = FFI_TYPE_UINT32; + break; + case FFI_TYPE_DOUBLE: + type = FFI_TYPE_UINT64; + break; + default: + break; + } + } + switch (type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + cif->flags += + ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS)); + arg_reg++; + break; + case FFI_TYPE_LONGDOUBLE: + /* Align it. */ + arg_reg = ALIGN(arg_reg, 2); + /* Treat it as two adjacent doubles. */ + if (soft_float) + { + arg_reg += 2; + } + else + { + cif->flags += + (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); + arg_reg++; + cif->flags += + (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); + arg_reg++; + } + break; + + case FFI_TYPE_STRUCT: + loc = arg_reg * FFI_SIZEOF_ARG; + cif->flags += calc_n32_struct_flags(soft_float, + (cif->arg_types)[index], + &loc, &arg_reg); + break; + + default: + arg_reg++; + break; + } + + index++; + } + + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_STRUCT: + { + if (struct_flags == 0) + { + /* The structure is returned through a hidden + first argument. Do nothing, 'cause FFI_TYPE_VOID + is 0 */ + } + else + { + /* The structure is returned via some tricky + mechanism */ + cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); + cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8)); + } + break; + } + + case FFI_TYPE_VOID: + /* Do nothing, 'cause FFI_TYPE_VOID is 0 */ + break; + + case FFI_TYPE_POINTER: + if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32) + cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8); + else + cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); + break; + + case FFI_TYPE_FLOAT: + if (soft_float) + { + cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8); + break; + } + /* else fall through */ + case FFI_TYPE_DOUBLE: + if (soft_float) + cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); + else + cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); + break; + + case FFI_TYPE_LONGDOUBLE: + /* Long double is returned as if it were a struct containing + two doubles. */ + if (soft_float) + { + cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); + cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8)); + } + else + { + cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); + cif->flags += (FFI_TYPE_DOUBLE + + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS)) + << (4 + (FFI_FLAG_BITS * 8)); + } + break; + default: + cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); + break; + } + } +#endif + + return FFI_OK; +} + +/* Low level routine for calling O32 functions */ +extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), + extended_cif *, unsigned, + unsigned, unsigned *, void (*)(void)); + +/* Low level routine for calling N32 functions */ +extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), + extended_cif *, unsigned, + unsigned, void *, void (*)(void)); + +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + ecif.rvalue = alloca(cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { +#ifdef FFI_MIPS_O32 + case FFI_O32: + case FFI_O32_SOFT_FLOAT: + ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; +#endif + +#ifdef FFI_MIPS_N32 + case FFI_N32: + case FFI_N32_SOFT_FLOAT: + case FFI_N64: + case FFI_N64_SOFT_FLOAT: + { + int copy_rvalue = 0; + int copy_offset = 0; + char *rvalue_copy = ecif.rvalue; + if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16) + { + /* For structures smaller than 16 bytes we clobber memory + in 8 byte increments. Make a copy so we don't clobber + the callers memory outside of the struct bounds. */ + rvalue_copy = alloca(16); + copy_rvalue = 1; + } + else if (cif->rtype->type == FFI_TYPE_FLOAT + && (cif->abi == FFI_N64_SOFT_FLOAT + || cif->abi == FFI_N32_SOFT_FLOAT)) + { + rvalue_copy = alloca (8); + copy_rvalue = 1; +#if defined(__MIPSEB__) || defined(_MIPSEB) + copy_offset = 4; +#endif + } + ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, + cif->flags, rvalue_copy, fn); + if (copy_rvalue) + memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size); + } + break; +#endif + + default: + FFI_ASSERT(0); + break; + } +} + +#if FFI_CLOSURES +#if defined(FFI_MIPS_O32) +extern void ffi_closure_O32(void); +#else +extern void ffi_closure_N32(void); +#endif /* FFI_MIPS_O32 */ + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + void * fn; + char *clear_location = (char *) codeloc; + +#if defined(FFI_MIPS_O32) + if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT) + return FFI_BAD_ABI; + fn = ffi_closure_O32; +#else +#if _MIPS_SIM ==_ABIN32 + if (cif->abi != FFI_N32 + && cif->abi != FFI_N32_SOFT_FLOAT) + return FFI_BAD_ABI; +#else + if (cif->abi != FFI_N64 + && cif->abi != FFI_N64_SOFT_FLOAT) + return FFI_BAD_ABI; +#endif + fn = ffi_closure_N32; +#endif /* FFI_MIPS_O32 */ + +#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32) + /* lui $25,high(fn) */ + tramp[0] = 0x3c190000 | ((unsigned)fn >> 16); + /* ori $25,low(fn) */ + tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff); + /* lui $12,high(codeloc) */ + tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16); + /* jr $25 */ + tramp[3] = 0x03200008; + /* ori $12,low(codeloc) */ + tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff); +#else + /* N64 has a somewhat larger trampoline. */ + /* lui $25,high(fn) */ + tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48); + /* lui $12,high(codeloc) */ + tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48); + /* ori $25,mid-high(fn) */ + tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff); + /* ori $12,mid-high(codeloc) */ + tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff); + /* dsll $25,$25,16 */ + tramp[4] = 0x0019cc38; + /* dsll $12,$12,16 */ + tramp[5] = 0x000c6438; + /* ori $25,mid-low(fn) */ + tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff); + /* ori $12,mid-low(codeloc) */ + tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff); + /* dsll $25,$25,16 */ + tramp[8] = 0x0019cc38; + /* dsll $12,$12,16 */ + tramp[9] = 0x000c6438; + /* ori $25,low(fn) */ + tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff); + /* jr $25 */ + tramp[11] = 0x03200008; + /* ori $12,low(codeloc) */ + tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff); + +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + +#ifdef USE__BUILTIN___CLEAR_CACHE + __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE); +#else + cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE); +#endif + return FFI_OK; +} + +/* + * Decodes the arguments to a function, which will be stored on the + * stack. AR is the pointer to the beginning of the integer arguments + * (and, depending upon the arguments, some floating-point arguments + * as well). FPR is a pointer to the area where floating point + * registers have been saved, if any. + * + * RVALUE is the location where the function return value will be + * stored. CLOSURE is the prepared closure to invoke. + * + * This function should only be called from assembly, which is in + * turn called from a trampoline. + * + * Returns the function return type. + * + * Based on the similar routine for sparc. + */ +int +ffi_closure_mips_inner_O32 (ffi_closure *closure, + void *rvalue, ffi_arg *ar, + double *fpr) +{ + ffi_cif *cif; + void **avaluep; + ffi_arg *avalue; + ffi_type **arg_types; + int i, avn, argn, seen_int; + + cif = closure->cif; + avalue = alloca (cif->nargs * sizeof (ffi_arg)); + avaluep = alloca (cif->nargs * sizeof (ffi_arg)); + + seen_int = (cif->abi == FFI_O32_SOFT_FLOAT); + argn = 0; + + if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT) + { + rvalue = (void *)(UINT32)ar[0]; + argn = 1; + } + + i = 0; + avn = cif->nargs; + arg_types = cif->arg_types; + + while (i < avn) + { + if (i < 2 && !seen_int && + (arg_types[i]->type == FFI_TYPE_FLOAT || + arg_types[i]->type == FFI_TYPE_DOUBLE || + arg_types[i]->type == FFI_TYPE_LONGDOUBLE)) + { +#if defined(__MIPSEB__) || defined(_MIPSEB) + if (arg_types[i]->type == FFI_TYPE_FLOAT) + avaluep[i] = ((char *) &fpr[i]) + sizeof (float); + else +#endif + avaluep[i] = (char *) &fpr[i]; + } + else + { + if (arg_types[i]->alignment == 8 && (argn & 0x1)) + argn++; + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + avaluep[i] = &avalue[i]; + *(SINT8 *) &avalue[i] = (SINT8) ar[argn]; + break; + + case FFI_TYPE_UINT8: + avaluep[i] = &avalue[i]; + *(UINT8 *) &avalue[i] = (UINT8) ar[argn]; + break; + + case FFI_TYPE_SINT16: + avaluep[i] = &avalue[i]; + *(SINT16 *) &avalue[i] = (SINT16) ar[argn]; + break; + + case FFI_TYPE_UINT16: + avaluep[i] = &avalue[i]; + *(UINT16 *) &avalue[i] = (UINT16) ar[argn]; + break; + + default: + avaluep[i] = (char *) &ar[argn]; + break; + } + seen_int = 1; + } + argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + i++; + } + + /* Invoke the closure. */ + (closure->fun) (cif, rvalue, avaluep, closure->user_data); + + if (cif->abi == FFI_O32_SOFT_FLOAT) + { + switch (cif->rtype->type) + { + case FFI_TYPE_FLOAT: + return FFI_TYPE_INT; + case FFI_TYPE_DOUBLE: + return FFI_TYPE_UINT64; + default: + return cif->rtype->type; + } + } + else + { + return cif->rtype->type; + } +} + +#if defined(FFI_MIPS_N32) + +static void +copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type, + int argn, unsigned arg_offset, ffi_arg *ar, + ffi_arg *fpr, int soft_float) +{ + ffi_type **elt_typep = type->elements; + while(*elt_typep) + { + ffi_type *elt_type = *elt_typep; + unsigned o; + char *tp; + char *argp; + char *fpp; + + o = ALIGN(offset, elt_type->alignment); + arg_offset += o - offset; + offset = o; + argn += arg_offset / sizeof(ffi_arg); + arg_offset = arg_offset % sizeof(ffi_arg); + + argp = (char *)(ar + argn); + fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn); + + tp = target + offset; + + if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float) + *(double *)tp = *(double *)fpp; + else + memcpy(tp, argp + arg_offset, elt_type->size); + + offset += elt_type->size; + arg_offset += elt_type->size; + elt_typep++; + argn += arg_offset / sizeof(ffi_arg); + arg_offset = arg_offset % sizeof(ffi_arg); + } +} + +/* + * Decodes the arguments to a function, which will be stored on the + * stack. AR is the pointer to the beginning of the integer + * arguments. FPR is a pointer to the area where floating point + * registers have been saved. + * + * RVALUE is the location where the function return value will be + * stored. CLOSURE is the prepared closure to invoke. + * + * This function should only be called from assembly, which is in + * turn called from a trampoline. + * + * Returns the function return flags. + * + */ +int +ffi_closure_mips_inner_N32 (ffi_closure *closure, + void *rvalue, ffi_arg *ar, + ffi_arg *fpr) +{ + ffi_cif *cif; + void **avaluep; + ffi_arg *avalue; + ffi_type **arg_types; + int i, avn, argn; + int soft_float; + ffi_arg *argp; + + cif = closure->cif; + soft_float = cif->abi == FFI_N64_SOFT_FLOAT + || cif->abi == FFI_N32_SOFT_FLOAT; + avalue = alloca (cif->nargs * sizeof (ffi_arg)); + avaluep = alloca (cif->nargs * sizeof (ffi_arg)); + + argn = 0; + + if (cif->rstruct_flag) + { +#if _MIPS_SIM==_ABIN32 + rvalue = (void *)(UINT32)ar[0]; +#else /* N64 */ + rvalue = (void *)ar[0]; +#endif + argn = 1; + } + + i = 0; + avn = cif->nargs; + arg_types = cif->arg_types; + + while (i < avn) + { + if (arg_types[i]->type == FFI_TYPE_FLOAT + || arg_types[i]->type == FFI_TYPE_DOUBLE + || arg_types[i]->type == FFI_TYPE_LONGDOUBLE) + { + argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn; + if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1))) + { + argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment); + argn++; + } +#if defined(__MIPSEB__) || defined(_MIPSEB) + if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8) + avaluep[i] = ((char *) argp) + sizeof (float); + else +#endif + avaluep[i] = (char *) argp; + } + else + { + unsigned type = arg_types[i]->type; + + if (arg_types[i]->alignment > sizeof(ffi_arg)) + argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg)); + + argp = ar + argn; + + /* The size of a pointer depends on the ABI */ + if (type == FFI_TYPE_POINTER) + type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT) + ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; + + if (soft_float && type == FFI_TYPE_FLOAT) + type = FFI_TYPE_UINT32; + + switch (type) + { + case FFI_TYPE_SINT8: + avaluep[i] = &avalue[i]; + *(SINT8 *) &avalue[i] = (SINT8) *argp; + break; + + case FFI_TYPE_UINT8: + avaluep[i] = &avalue[i]; + *(UINT8 *) &avalue[i] = (UINT8) *argp; + break; + + case FFI_TYPE_SINT16: + avaluep[i] = &avalue[i]; + *(SINT16 *) &avalue[i] = (SINT16) *argp; + break; + + case FFI_TYPE_UINT16: + avaluep[i] = &avalue[i]; + *(UINT16 *) &avalue[i] = (UINT16) *argp; + break; + + case FFI_TYPE_SINT32: + avaluep[i] = &avalue[i]; + *(SINT32 *) &avalue[i] = (SINT32) *argp; + break; + + case FFI_TYPE_UINT32: + avaluep[i] = &avalue[i]; + *(UINT32 *) &avalue[i] = (UINT32) *argp; + break; + + case FFI_TYPE_STRUCT: + if (argn < 8) + { + /* Allocate space for the struct as at least part of + it was passed in registers. */ + avaluep[i] = alloca(arg_types[i]->size); + copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i], + argn, 0, ar, fpr, soft_float); + + break; + } + /* Else fall through. */ + default: + avaluep[i] = (char *) argp; + break; + } + } + argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg); + i++; + } + + /* Invoke the closure. */ + (closure->fun) (cif, rvalue, avaluep, closure->user_data); + + return cif->flags >> (FFI_FLAG_BITS * 8); +} + +#endif /* FFI_MIPS_N32 */ + +#endif /* FFI_CLOSURES */ diff --git a/circuitpython/lib/libffi/src/mips/ffitarget.h b/circuitpython/lib/libffi/src/mips/ffitarget.h new file mode 100644 index 0000000..717d659 --- /dev/null +++ b/circuitpython/lib/libffi/src/mips/ffitarget.h @@ -0,0 +1,247 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for MIPS. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifdef linux +# include +#elif defined(__rtems__) +/* + * Subprogram calling convention - copied from sgidefs.h + */ +#define _MIPS_SIM_ABI32 1 +#define _MIPS_SIM_NABI32 2 +#define _MIPS_SIM_ABI64 3 +#elif !defined(__OpenBSD__) +# include +#endif + +# ifndef _ABIN32 +# define _ABIN32 _MIPS_SIM_NABI32 +# endif +# ifndef _ABI64 +# define _ABI64 _MIPS_SIM_ABI64 +# endif +# ifndef _ABIO32 +# define _ABIO32 _MIPS_SIM_ABI32 +# endif + +#if !defined(_MIPS_SIM) +# error -- something is very wrong -- +#else +# if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64)) +# define FFI_MIPS_N32 +# else +# if (_MIPS_SIM==_ABIO32 && defined(_ABIO32)) +# define FFI_MIPS_O32 +# else +# error -- this is an unsupported platform -- +# endif +# endif +#endif + +#ifdef FFI_MIPS_O32 +/* O32 stack frames have 32bit integer args */ +# define FFI_SIZEOF_ARG 4 +#else +/* N32 and N64 frames have 64bit integer args */ +# define FFI_SIZEOF_ARG 8 +# if _MIPS_SIM == _ABIN32 +# define FFI_SIZEOF_JAVA_RAW 4 +# endif +#endif + +#define FFI_FLAG_BITS 2 + +/* SGI's strange assembler requires that we multiply by 4 rather + than shift left by FFI_FLAG_BITS */ + +#define FFI_ARGS_D FFI_TYPE_DOUBLE +#define FFI_ARGS_F FFI_TYPE_FLOAT +#define FFI_ARGS_DD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE +#define FFI_ARGS_FF FFI_TYPE_FLOAT * 4 + FFI_TYPE_FLOAT +#define FFI_ARGS_FD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT +#define FFI_ARGS_DF FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE + +/* Needed for N32 structure returns */ +#define FFI_TYPE_SMALLSTRUCT FFI_TYPE_UINT8 +#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8 + +#if 0 +/* The SGI assembler can't handle this.. */ +#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT +/* (and so on) */ +#else +/* ...so we calculate these by hand! */ +#define FFI_TYPE_STRUCT_D 61 +#define FFI_TYPE_STRUCT_F 45 +#define FFI_TYPE_STRUCT_DD 253 +#define FFI_TYPE_STRUCT_FF 173 +#define FFI_TYPE_STRUCT_FD 237 +#define FFI_TYPE_STRUCT_DF 189 +#define FFI_TYPE_STRUCT_SMALL 93 +#define FFI_TYPE_STRUCT_SMALL2 109 + +/* and for n32 soft float, add 16 * 2^4 */ +#define FFI_TYPE_STRUCT_D_SOFT 317 +#define FFI_TYPE_STRUCT_F_SOFT 301 +#define FFI_TYPE_STRUCT_DD_SOFT 509 +#define FFI_TYPE_STRUCT_FF_SOFT 429 +#define FFI_TYPE_STRUCT_FD_SOFT 493 +#define FFI_TYPE_STRUCT_DF_SOFT 445 +#define FFI_TYPE_STRUCT_SOFT 16 +#endif + +#ifdef LIBFFI_ASM +#define v0 $2 +#define v1 $3 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define a4 $8 +#define a5 $9 +#define a6 $10 +#define a7 $11 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define t8 $24 +#define t9 $25 +#define ra $31 + +#ifdef FFI_MIPS_O32 +# define REG_L lw +# define REG_S sw +# define SUBU subu +# define ADDU addu +# define SRL srl +# define LI li +#else /* !FFI_MIPS_O32 */ +# define REG_L ld +# define REG_S sd +# define SUBU dsubu +# define ADDU daddu +# define SRL dsrl +# define LI dli +# if (_MIPS_SIM==_ABI64) +# define LA dla +# define EH_FRAME_ALIGN 3 +# define FDE_ADDR_BYTES .8byte +# else +# define LA la +# define EH_FRAME_ALIGN 2 +# define FDE_ADDR_BYTES .4byte +# endif /* _MIPS_SIM==_ABI64 */ +#endif /* !FFI_MIPS_O32 */ +#else /* !LIBFFI_ASM */ +# ifdef __GNUC__ +# ifdef FFI_MIPS_O32 +/* O32 stack frames have 32bit integer args */ +typedef unsigned int ffi_arg __attribute__((__mode__(__SI__))); +typedef signed int ffi_sarg __attribute__((__mode__(__SI__))); +#else +/* N32 and N64 frames have 64bit integer args */ +typedef unsigned int ffi_arg __attribute__((__mode__(__DI__))); +typedef signed int ffi_sarg __attribute__((__mode__(__DI__))); +# endif +# else +# ifdef FFI_MIPS_O32 +/* O32 stack frames have 32bit integer args */ +typedef __uint32_t ffi_arg; +typedef __int32_t ffi_sarg; +# else +/* N32 and N64 frames have 64bit integer args */ +typedef __uint64_t ffi_arg; +typedef __int64_t ffi_sarg; +# endif +# endif /* __GNUC__ */ + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_O32, + FFI_N32, + FFI_N64, + FFI_O32_SOFT_FLOAT, + FFI_N32_SOFT_FLOAT, + FFI_N64_SOFT_FLOAT, + FFI_LAST_ABI, + +#ifdef FFI_MIPS_O32 +#ifdef __mips_soft_float + FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT +#else + FFI_DEFAULT_ABI = FFI_O32 +#endif +#else +# if _MIPS_SIM==_ABI64 +# ifdef __mips_soft_float + FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT +# else + FFI_DEFAULT_ABI = FFI_N64 +# endif +# else +# ifdef __mips_soft_float + FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT +# else + FFI_DEFAULT_ABI = FFI_N32 +# endif +# endif +#endif +} ffi_abi; + +#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag +#endif /* !LIBFFI_ASM */ + +/* ---- Definitions for closures ----------------------------------------- */ + +#if defined(FFI_MIPS_O32) +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 20 +#else +/* N32/N64. */ +# define FFI_CLOSURES 1 +#if _MIPS_SIM==_ABI64 +#define FFI_TRAMPOLINE_SIZE 52 +#else +#define FFI_TRAMPOLINE_SIZE 20 +#endif +#endif /* FFI_MIPS_O32 */ +#define FFI_NATIVE_RAW_API 0 + +#endif + diff --git a/circuitpython/lib/libffi/src/mips/n32.S b/circuitpython/lib/libffi/src/mips/n32.S new file mode 100644 index 0000000..c6985d3 --- /dev/null +++ b/circuitpython/lib/libffi/src/mips/n32.S @@ -0,0 +1,576 @@ +/* ----------------------------------------------------------------------- + n32.S - Copyright (c) 1996, 1998, 2005, 2007, 2009, 2010 Red Hat, Inc. + + MIPS Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + +/* Only build this code if we are compiling for n32 */ + +#if defined(FFI_MIPS_N32) + +#define callback a0 +#define bytes a2 +#define flags a3 +#define raddr a4 +#define fn a5 + +#define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG ) + +#ifdef __GNUC__ + .abicalls +#endif + .set mips4 + .text + .align 2 + .globl ffi_call_N32 + .ent ffi_call_N32 +ffi_call_N32: +.LFB3: + .frame $fp, SIZEOF_FRAME, ra + .mask 0xc0000000,-FFI_SIZEOF_ARG + .fmask 0x00000000,0 + + # Prologue + SUBU $sp, SIZEOF_FRAME # Frame size +.LCFI0: + REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer + REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address +.LCFI1: + move $fp, $sp +.LCFI3: + move t9, callback # callback function pointer + REG_S bytes, 2*FFI_SIZEOF_ARG($fp) # bytes + REG_S flags, 3*FFI_SIZEOF_ARG($fp) # flags + REG_S raddr, 4*FFI_SIZEOF_ARG($fp) # raddr + REG_S fn, 5*FFI_SIZEOF_ARG($fp) # fn + + # Allocate at least 4 words in the argstack + move v0, bytes + bge bytes, 4 * FFI_SIZEOF_ARG, bigger + LI v0, 4 * FFI_SIZEOF_ARG + b sixteen + + bigger: + ADDU t4, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned + and v0, t4, -2 * FFI_SIZEOF_ARG # to a proper boundry. + +sixteen: + SUBU $sp, $sp, v0 # move the stack pointer to reflect the + # arg space + + move a0, $sp # 4 * FFI_SIZEOF_ARG + ADDU a3, $fp, 3 * FFI_SIZEOF_ARG + + # Call ffi_prep_args + jal t9 + + # Copy the stack pointer to t9 + move t9, $sp + + # Fix the stack if there are more than 8 64bit slots worth + # of arguments. + + # Load the number of bytes + REG_L t6, 2*FFI_SIZEOF_ARG($fp) + + # Is it bigger than 8 * FFI_SIZEOF_ARG? + daddiu t8, t6, -(8 * FFI_SIZEOF_ARG) + bltz t8, loadregs + + ADDU t9, t9, t8 + +loadregs: + + REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6. + + and t4, t6, ((1< +#include + +/* Only build this code if we are compiling for o32 */ + +#if defined(FFI_MIPS_O32) + +#define callback a0 +#define bytes a2 +#define flags a3 + +#define SIZEOF_FRAME (4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG) +#define A3_OFF (SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG) +#define FP_OFF (SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG) +#define RA_OFF (SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG) + + .abicalls + .text + .align 2 + .globl ffi_call_O32 + .ent ffi_call_O32 +ffi_call_O32: +$LFB0: + # Prologue + SUBU $sp, SIZEOF_FRAME # Frame size +$LCFI0: + REG_S $fp, FP_OFF($sp) # Save frame pointer +$LCFI1: + REG_S ra, RA_OFF($sp) # Save return address +$LCFI2: + move $fp, $sp + +$LCFI3: + move t9, callback # callback function pointer + REG_S flags, A3_OFF($fp) # flags + + # Allocate at least 4 words in the argstack + LI v0, 4 * FFI_SIZEOF_ARG + blt bytes, v0, sixteen + + ADDU v0, bytes, 7 # make sure it is aligned + and v0, -8 # to an 8 byte boundry + +sixteen: + SUBU $sp, v0 # move the stack pointer to reflect the + # arg space + + ADDU a0, $sp, 4 * FFI_SIZEOF_ARG + + jalr t9 + + REG_L t0, A3_OFF($fp) # load the flags word + SRL t2, t0, 4 # shift our arg info + and t0, ((1<<4)-1) # mask out the return type + + ADDU $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args + + bnez t0, pass_d # make it quick for int + REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the + REG_L a1, 1*FFI_SIZEOF_ARG($sp) # four regs. + REG_L a2, 2*FFI_SIZEOF_ARG($sp) + REG_L a3, 3*FFI_SIZEOF_ARG($sp) + b call_it + +pass_d: + bne t0, FFI_ARGS_D, pass_f + l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args + REG_L a2, 2*FFI_SIZEOF_ARG($sp) # passing a double + REG_L a3, 3*FFI_SIZEOF_ARG($sp) + b call_it + +pass_f: + bne t0, FFI_ARGS_F, pass_d_d + l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args + REG_L a1, 1*FFI_SIZEOF_ARG($sp) # passing a float + REG_L a2, 2*FFI_SIZEOF_ARG($sp) + REG_L a3, 3*FFI_SIZEOF_ARG($sp) + b call_it + +pass_d_d: + bne t0, FFI_ARGS_DD, pass_f_f + l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args + l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing two doubles + b call_it + +pass_f_f: + bne t0, FFI_ARGS_FF, pass_d_f + l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args + l.s $f14, 1*FFI_SIZEOF_ARG($sp) # passing two floats + REG_L a2, 2*FFI_SIZEOF_ARG($sp) + REG_L a3, 3*FFI_SIZEOF_ARG($sp) + b call_it + +pass_d_f: + bne t0, FFI_ARGS_DF, pass_f_d + l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args + l.s $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float + REG_L a3, 3*FFI_SIZEOF_ARG($sp) + b call_it + +pass_f_d: + # assume that the only other combination must be float then double + # bne t0, FFI_ARGS_F_D, call_it + l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args + l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float + +call_it: + # Load the function pointer + REG_L t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp) + + # If the return value pointer is NULL, assume no return value. + REG_L t1, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) + beqz t1, noretval + + bne t2, FFI_TYPE_INT, retlonglong + jalr t9 + REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) + REG_S v0, 0(t0) + b epilogue + +retlonglong: + # Really any 64-bit int, signed or not. + bne t2, FFI_TYPE_UINT64, retfloat + jalr t9 + REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) + REG_S v1, 4(t0) + REG_S v0, 0(t0) + b epilogue + +retfloat: + bne t2, FFI_TYPE_FLOAT, retdouble + jalr t9 + REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) + s.s $f0, 0(t0) + b epilogue + +retdouble: + bne t2, FFI_TYPE_DOUBLE, noretval + jalr t9 + REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) + s.d $f0, 0(t0) + b epilogue + +noretval: + jalr t9 + + # Epilogue +epilogue: + move $sp, $fp + REG_L $fp, FP_OFF($sp) # Restore frame pointer + REG_L ra, RA_OFF($sp) # Restore return address + ADDU $sp, SIZEOF_FRAME # Fix stack pointer + j ra + +$LFE0: + .end ffi_call_O32 + + +/* ffi_closure_O32. Expects address of the passed-in ffi_closure + in t4 ($12). Stores any arguments passed in registers onto the + stack, then calls ffi_closure_mips_inner_O32, which + then decodes them. + + Stack layout: + + 3 - a3 save + 2 - a2 save + 1 - a1 save + 0 - a0 save, original sp + -1 - ra save + -2 - fp save + -3 - $16 (s0) save + -4 - cprestore + -5 - return value high (v1) + -6 - return value low (v0) + -7 - f14 (le high, be low) + -8 - f14 (le low, be high) + -9 - f12 (le high, be low) + -10 - f12 (le low, be high) + -11 - Called function a3 save + -12 - Called function a2 save + -13 - Called function a1 save + -14 - Called function a0 save, our sp and fp point here + */ + +#define SIZEOF_FRAME2 (14 * FFI_SIZEOF_ARG) +#define A3_OFF2 (SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG) +#define A2_OFF2 (SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG) +#define A1_OFF2 (SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG) +#define A0_OFF2 (SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG) +#define RA_OFF2 (SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG) +#define FP_OFF2 (SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG) +#define S0_OFF2 (SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG) +#define GP_OFF2 (SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG) +#define V1_OFF2 (SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG) +#define V0_OFF2 (SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG) +#define FA_1_1_OFF2 (SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG) +#define FA_1_0_OFF2 (SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG) +#define FA_0_1_OFF2 (SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG) +#define FA_0_0_OFF2 (SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG) + + .text + .align 2 + .globl ffi_closure_O32 + .ent ffi_closure_O32 +ffi_closure_O32: +$LFB1: + # Prologue + .frame $fp, SIZEOF_FRAME2, ra + .set noreorder + .cpload t9 + .set reorder + SUBU $sp, SIZEOF_FRAME2 + .cprestore GP_OFF2 +$LCFI4: + REG_S $16, S0_OFF2($sp) # Save s0 + REG_S $fp, FP_OFF2($sp) # Save frame pointer + REG_S ra, RA_OFF2($sp) # Save return address +$LCFI6: + move $fp, $sp + +$LCFI7: + # Store all possible argument registers. If there are more than + # four arguments, then they are stored above where we put a3. + REG_S a0, A0_OFF2($fp) + REG_S a1, A1_OFF2($fp) + REG_S a2, A2_OFF2($fp) + REG_S a3, A3_OFF2($fp) + + # Load ABI enum to s0 + REG_L $16, 20($12) # cif pointer follows tramp. + REG_L $16, 0($16) # abi is first member. + + li $13, 1 # FFI_O32 + bne $16, $13, 1f # Skip fp save if FFI_O32_SOFT_FLOAT + + # Store all possible float/double registers. + s.d $f12, FA_0_0_OFF2($fp) + s.d $f14, FA_1_0_OFF2($fp) +1: + # Call ffi_closure_mips_inner_O32 to do the work. + la t9, ffi_closure_mips_inner_O32 + move a0, $12 # Pointer to the ffi_closure + addu a1, $fp, V0_OFF2 + addu a2, $fp, A0_OFF2 + addu a3, $fp, FA_0_0_OFF2 + jalr t9 + + # Load the return value into the appropriate register. + move $8, $2 + li $9, FFI_TYPE_VOID + beq $8, $9, closure_done + + li $13, 1 # FFI_O32 + bne $16, $13, 1f # Skip fp restore if FFI_O32_SOFT_FLOAT + + li $9, FFI_TYPE_FLOAT + l.s $f0, V0_OFF2($fp) + beq $8, $9, closure_done + + li $9, FFI_TYPE_DOUBLE + l.d $f0, V0_OFF2($fp) + beq $8, $9, closure_done +1: + REG_L $3, V1_OFF2($fp) + REG_L $2, V0_OFF2($fp) + +closure_done: + # Epilogue + move $sp, $fp + REG_L $16, S0_OFF2($sp) # Restore s0 + REG_L $fp, FP_OFF2($sp) # Restore frame pointer + REG_L ra, RA_OFF2($sp) # Restore return address + ADDU $sp, SIZEOF_FRAME2 + j ra +$LFE1: + .end ffi_closure_O32 + +/* DWARF-2 unwind info. */ + + .section .eh_frame,"a",@progbits +$Lframe0: + .4byte $LECIE0-$LSCIE0 # Length of Common Information Entry +$LSCIE0: + .4byte 0x0 # CIE Identifier Tag + .byte 0x1 # CIE Version + .ascii "zR\0" # CIE Augmentation + .uleb128 0x1 # CIE Code Alignment Factor + .sleb128 4 # CIE Data Alignment Factor + .byte 0x1f # CIE RA Column + .uleb128 0x1 # Augmentation size + .byte 0x00 # FDE Encoding (absptr) + .byte 0xc # DW_CFA_def_cfa + .uleb128 0x1d + .uleb128 0x0 + .align 2 +$LECIE0: +$LSFDE0: + .4byte $LEFDE0-$LASFDE0 # FDE Length +$LASFDE0: + .4byte $LASFDE0-$Lframe0 # FDE CIE offset + .4byte $LFB0 # FDE initial location + .4byte $LFE0-$LFB0 # FDE address range + .uleb128 0x0 # Augmentation size + .byte 0x4 # DW_CFA_advance_loc4 + .4byte $LCFI0-$LFB0 + .byte 0xe # DW_CFA_def_cfa_offset + .uleb128 0x18 + .byte 0x4 # DW_CFA_advance_loc4 + .4byte $LCFI2-$LCFI0 + .byte 0x11 # DW_CFA_offset_extended_sf + .uleb128 0x1e # $fp + .sleb128 -2 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) + .byte 0x11 # DW_CFA_offset_extended_sf + .uleb128 0x1f # $ra + .sleb128 -1 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) + .byte 0x4 # DW_CFA_advance_loc4 + .4byte $LCFI3-$LCFI2 + .byte 0xc # DW_CFA_def_cfa + .uleb128 0x1e + .uleb128 0x18 + .align 2 +$LEFDE0: +$LSFDE1: + .4byte $LEFDE1-$LASFDE1 # FDE Length +$LASFDE1: + .4byte $LASFDE1-$Lframe0 # FDE CIE offset + .4byte $LFB1 # FDE initial location + .4byte $LFE1-$LFB1 # FDE address range + .uleb128 0x0 # Augmentation size + .byte 0x4 # DW_CFA_advance_loc4 + .4byte $LCFI4-$LFB1 + .byte 0xe # DW_CFA_def_cfa_offset + .uleb128 0x38 + .byte 0x4 # DW_CFA_advance_loc4 + .4byte $LCFI6-$LCFI4 + .byte 0x11 # DW_CFA_offset_extended_sf + .uleb128 0x10 # $16 + .sleb128 -3 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) + .byte 0x11 # DW_CFA_offset_extended_sf + .uleb128 0x1e # $fp + .sleb128 -2 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) + .byte 0x11 # DW_CFA_offset_extended_sf + .uleb128 0x1f # $ra + .sleb128 -1 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) + .byte 0x4 # DW_CFA_advance_loc4 + .4byte $LCFI7-$LCFI6 + .byte 0xc # DW_CFA_def_cfa + .uleb128 0x1e + .uleb128 0x38 + .align 2 +$LEFDE1: + +#endif diff --git a/circuitpython/lib/libffi/src/moxie/eabi.S b/circuitpython/lib/libffi/src/moxie/eabi.S new file mode 100644 index 0000000..ac7aceb --- /dev/null +++ b/circuitpython/lib/libffi/src/moxie/eabi.S @@ -0,0 +1,101 @@ +/* ----------------------------------------------------------------------- + eabi.S - Copyright (c) 2012, 2013 Anthony Green + + Moxie Assembly glue. + + 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 AUTHOR 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 LIBFFI_ASM +#include +#include + + .globl ffi_prep_args_EABI + + .text + .p2align 4 + .globl ffi_call_EABI + .type ffi_call_EABI, @function + + # $r0 : ffi_prep_args + # $r1 : &ecif + # $r2 : cif->bytes + # $r3 : fig->flags + # $r4 : ecif.rvalue + # $r5 : fn + +ffi_call_EABI: + push $sp, $r6 + push $sp, $r7 + push $sp, $r8 + dec $sp, 24 + + /* Store incoming args on stack. */ + sto.l 0($sp), $r0 /* ffi_prep_args */ + sto.l 4($sp), $r1 /* ecif */ + sto.l 8($sp), $r2 /* bytes */ + sto.l 12($sp), $r3 /* flags */ + sto.l 16($sp), $r4 /* &rvalue */ + sto.l 20($sp), $r5 /* fn */ + + /* Call ffi_prep_args. */ + mov $r6, $r4 /* Save result buffer */ + mov $r7, $r5 /* Save the target fn */ + mov $r8, $r3 /* Save the flags */ + sub.l $sp, $r2 /* Allocate stack space */ + mov $r0, $sp /* We can stomp over $r0 */ + /* $r1 is already set up */ + jsra ffi_prep_args + + /* Load register arguments. */ + ldo.l $r0, 0($sp) + ldo.l $r1, 4($sp) + ldo.l $r2, 8($sp) + ldo.l $r3, 12($sp) + ldo.l $r4, 16($sp) + ldo.l $r5, 20($sp) + + /* Call the target function. */ + jsr $r7 + + ldi.l $r7, 0xffffffff + cmp $r8, $r7 + beq retstruct + + ldi.l $r7, 4 + cmp $r8, $r7 + bgt ret2reg + + st.l ($r6), $r0 + jmpa retdone + +ret2reg: + st.l ($r6), $r0 + sto.l 4($r6), $r1 + +retstruct: +retdone: + /* Return. */ + ldo.l $r6, -4($fp) + ldo.l $r7, -8($fp) + ldo.l $r8, -12($fp) + ret + .size ffi_call_EABI, .-ffi_call_EABI + diff --git a/circuitpython/lib/libffi/src/moxie/ffi.c b/circuitpython/lib/libffi/src/moxie/ffi.c new file mode 100644 index 0000000..540a042 --- /dev/null +++ b/circuitpython/lib/libffi/src/moxie/ffi.c @@ -0,0 +1,272 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (C) 2012, 2013 Anthony Green + + Moxie Foreign Function Interface + + 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 +#include + +#include + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +void *ffi_prep_args(char *stack, extended_cif *ecif) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + register int count = 0; + + p_argv = ecif->avalue; + argp = stack; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += 4; + } + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); + i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + z = sizeof(void*); + *(void **) argp = *p_argv; + } + else if (z < sizeof(int)) + { + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + } + else if (z == sizeof(int)) + { + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + } + else + { + memcpy(argp, *p_argv, z); + } + p_argv++; + argp += z; + count += z; + } + + return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8))); +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + if (cif->rtype->type == FFI_TYPE_STRUCT) + cif->flags = -1; + else + cif->flags = cif->rtype->size; + + cif->bytes = ALIGN (cif->bytes, 8); + + return FFI_OK; +} + +extern void ffi_call_EABI(void *(*)(char *, extended_cif *), + extended_cif *, + unsigned, unsigned, + unsigned *, + void (*fn)(void)); + +void ffi_call(ffi_cif *cif, + void (*fn)(void), + void *rvalue, + void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_EABI: + ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; + default: + FFI_ASSERT(0); + break; + } +} + +void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, + unsigned arg4, unsigned arg5, unsigned arg6) +{ + /* This function is called by a trampoline. The trampoline stows a + pointer to the ffi_closure object in $r7. We must save this + pointer in a place that will persist while we do our work. */ + register ffi_closure *creg __asm__ ("$r12"); + ffi_closure *closure = creg; + + /* Arguments that don't fit in registers are found on the stack + at a fixed offset above the current frame pointer. */ + register char *frame_pointer __asm__ ("$fp"); + + /* Pointer to a struct return value. */ + void *struct_rvalue = (void *) arg1; + + /* 6 words reserved for register args + 3 words from jsr */ + char *stack_args = frame_pointer + 9*4; + + /* Lay the register arguments down in a continuous chunk of memory. */ + unsigned register_args[6] = + { arg1, arg2, arg3, arg4, arg5, arg6 }; + char *register_args_ptr = (char *) register_args; + + ffi_cif *cif = closure->cif; + ffi_type **arg_types = cif->arg_types; + void **avalue = alloca (cif->nargs * sizeof(void *)); + char *ptr = (char *) register_args; + int i; + + /* preserve struct type return pointer passing */ + if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { + ptr += 4; + register_args_ptr = (char *)®ister_args[1]; + } + + /* Find the address of each argument. */ + for (i = 0; i < cif->nargs; i++) + { + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + avalue[i] = ptr + 3; + break; + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + avalue[i] = ptr + 2; + break; + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_FLOAT: + case FFI_TYPE_POINTER: + avalue[i] = ptr; + break; + case FFI_TYPE_STRUCT: + avalue[i] = *(void**)ptr; + break; + default: + /* This is an 8-byte value. */ + avalue[i] = ptr; + ptr += 4; + break; + } + ptr += 4; + + /* If we've handled more arguments than fit in registers, + start looking at the those passed on the stack. */ + if (ptr == ®ister_args[6]) + ptr = stack_args; + } + + /* Invoke the closure. */ + if (cif->rtype && (cif->rtype->type == FFI_TYPE_STRUCT)) + { + (closure->fun) (cif, struct_rvalue, avalue, closure->user_data); + } + else + { + /* Allocate space for the return value and call the function. */ + long long rvalue; + (closure->fun) (cif, &rvalue, avalue, closure->user_data); + asm ("mov $r12, %0\n ld.l $r0, ($r12)\n ldo.l $r1, 4($r12)" : : "r" (&rvalue)); + } +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned short *tramp = (unsigned short *) &closure->tramp[0]; + unsigned long fn = (long) ffi_closure_eabi; + unsigned long cls = (long) codeloc; + + if (cif->abi != FFI_EABI) + return FFI_BAD_ABI; + + fn = (unsigned long) ffi_closure_eabi; + + tramp[0] = 0x01e0; /* ldi.l $r7, .... */ + tramp[1] = cls >> 16; + tramp[2] = cls & 0xffff; + tramp[3] = 0x1a00; /* jmpa .... */ + tramp[4] = fn >> 16; + tramp[5] = fn & 0xffff; + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/moxie/ffitarget.h b/circuitpython/lib/libffi/src/moxie/ffitarget.h new file mode 100644 index 0000000..623e3ec --- /dev/null +++ b/circuitpython/lib/libffi/src/moxie/ffitarget.h @@ -0,0 +1,52 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012, 2013 Anthony Green + Target configuration macros for Moxie + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +/* ---- System specific configurations ----------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_EABI, + FFI_DEFAULT_ABI = FFI_EABI, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 + +/* Trampolines are 12-bytes long. See ffi_prep_closure_loc. */ +#define FFI_TRAMPOLINE_SIZE (12) + +#endif diff --git a/circuitpython/lib/libffi/src/nios2/ffi.c b/circuitpython/lib/libffi/src/nios2/ffi.c new file mode 100644 index 0000000..2efa033 --- /dev/null +++ b/circuitpython/lib/libffi/src/nios2/ffi.c @@ -0,0 +1,304 @@ +/* libffi support for Altera Nios II. + + Copyright (c) 2013 Mentor Graphics. + + 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 +#include + +#include + +/* The Nios II Processor Reference Handbook defines the procedure call + ABI as follows. + + Arguments are passed as if a structure containing the types of + the arguments were constructed. The first 16 bytes are passed in r4 + through r7, the remainder on the stack. The first 16 bytes of a function + taking variable arguments are passed in r4-r7 in the same way. + + Return values of types up to 8 bytes are returned in r2 and r3. For + return values greater than 8 bytes, the caller must allocate memory for + the result and pass the address as if it were argument 0. + + While this isn't specified explicitly in the ABI documentation, GCC + promotes integral arguments smaller than int size to 32 bits. + + Also of note, the ABI specifies that all structure objects are + aligned to 32 bits even if all their fields have a smaller natural + alignment. See FFI_AGGREGATE_ALIGNMENT. */ + + +/* Declare the assembly language hooks. */ + +extern UINT64 ffi_call_sysv (void (*) (char *, extended_cif *), + extended_cif *, + unsigned, + void (*fn) (void)); +extern void ffi_closure_sysv (void); + +/* Perform machine-dependent cif processing. */ + +ffi_status ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* We always want at least 16 bytes in the parameter block since it + simplifies the low-level call function. Also round the parameter + block size up to a multiple of 4 bytes to preserve + 32-bit alignment of the stack pointer. */ + if (cif->bytes < 16) + cif->bytes = 16; + else + cif->bytes = (cif->bytes + 3) & ~3; + + return FFI_OK; +} + + +/* ffi_prep_args is called by the assembly routine to transfer arguments + to the stack using the pointers in the ecif array. + Note that the stack buffer is big enough to fit all the arguments, + but the first 16 bytes will be copied to registers for the actual + call. */ + +void ffi_prep_args (char *stack, extended_cif *ecif) +{ + char *argp = stack; + unsigned int i; + + /* The implicit return value pointer is passed as if it were a hidden + first argument. */ + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && ecif->cif->rtype->size > 8) + { + (*(void **) argp) = ecif->rvalue; + argp += 4; + } + + for (i = 0; i < ecif->cif->nargs; i++) + { + void *avalue = ecif->avalue[i]; + ffi_type *atype = ecif->cif->arg_types[i]; + size_t size = atype->size; + size_t alignment = atype->alignment; + + /* Align argp as appropriate for the argument type. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + /* Copy the argument, promoting integral types smaller than a + word to word size. */ + if (size < sizeof (int)) + { + size = sizeof (int); + switch (atype->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) avalue; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) avalue; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) avalue; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) avalue; + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, avalue, atype->size); + break; + + default: + FFI_ASSERT(0); + } + } + else if (size == sizeof (int)) + *(unsigned int *) argp = (unsigned int) *(UINT32 *) avalue; + else + memcpy (argp, avalue, size); + argp += size; + } +} + + +/* Call FN using the prepared CIF. RVALUE points to space allocated by + the caller for the return value, and AVALUE is an array of argument + pointers. */ + +void ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + + extended_cif ecif; + UINT64 result; + + /* If bigret is true, this is the case where a return value of larger + than 8 bytes is handled by being passed by reference as an implicit + argument. */ + int bigret = (cif->rtype->type == FFI_TYPE_STRUCT + && cif->rtype->size > 8); + + ecif.cif = cif; + ecif.avalue = avalue; + + /* Allocate space for return value if this is the pass-by-reference case + and the caller did not provide a buffer. */ + if (rvalue == NULL && bigret) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + result = ffi_call_sysv (ffi_prep_args, &ecif, cif->bytes, fn); + + /* Now result contains the 64 bit contents returned from fn in + r2 and r3. Copy the value of the appropriate size to the user-provided + rvalue buffer. */ + if (rvalue && !bigret) + switch (cif->rtype->size) + { + case 1: + *(UINT8 *)rvalue = (UINT8) result; + break; + case 2: + *(UINT16 *)rvalue = (UINT16) result; + break; + case 4: + *(UINT32 *)rvalue = (UINT32) result; + break; + case 8: + *(UINT64 *)rvalue = (UINT64) result; + break; + default: + memcpy (rvalue, (void *)&result, cif->rtype->size); + break; + } +} + +/* This function is invoked from the closure trampoline to invoke + CLOSURE with argument block ARGS. Parse ARGS according to + CLOSURE->cfi and invoke CLOSURE->fun. */ + +static UINT64 +ffi_closure_helper (unsigned char *args, + ffi_closure *closure) +{ + ffi_cif *cif = closure->cif; + unsigned char *argp = args; + void **parsed_args = alloca (cif->nargs * sizeof (void *)); + UINT64 result; + void *retptr; + unsigned int i; + + /* First figure out what to do about the return type. If this is the + big-structure-return case, the first arg is the hidden return buffer + allocated by the caller. */ + if (cif->rtype->type == FFI_TYPE_STRUCT + && cif->rtype->size > 8) + { + retptr = *((void **) argp); + argp += 4; + } + else + retptr = (void *) &result; + + /* Fill in the array of argument pointers. */ + for (i = 0; i < cif->nargs; i++) + { + size_t size = cif->arg_types[i]->size; + size_t alignment = cif->arg_types[i]->alignment; + + /* Align argp as appropriate for the argument type. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + /* Arguments smaller than an int are promoted to int. */ + if (size < sizeof (int)) + size = sizeof (int); + + /* Store the pointer. */ + parsed_args[i] = argp; + argp += size; + } + + /* Call the user-supplied function. */ + (closure->fun) (cif, retptr, parsed_args, closure->user_data); + return result; +} + + +/* Initialize CLOSURE with a trampoline to call FUN with + CIF and USER_DATA. */ +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun) (ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + int i; + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + /* The trampoline looks like: + movhi r8, %hi(ffi_closure_sysv) + ori r8, r8, %lo(ffi_closure_sysv) + movhi r9, %hi(ffi_closure_helper) + ori r0, r9, %lo(ffi_closure_helper) + movhi r10, %hi(closure) + ori r10, r10, %lo(closure) + jmp r8 + and then ffi_closure_sysv retrieves the closure pointer out of r10 + in addition to the arguments passed in the normal way for the call, + and invokes ffi_closure_helper. We encode the pointer to + ffi_closure_helper in the trampoline because making a PIC call + to it in ffi_closure_sysv would be messy (it would have to indirect + through the GOT). */ + +#define HI(x) ((((unsigned int) (x)) >> 16) & 0xffff) +#define LO(x) (((unsigned int) (x)) & 0xffff) + tramp[0] = (0 << 27) | (8 << 22) | (HI (ffi_closure_sysv) << 6) | 0x34; + tramp[1] = (8 << 27) | (8 << 22) | (LO (ffi_closure_sysv) << 6) | 0x14; + tramp[2] = (0 << 27) | (9 << 22) | (HI (ffi_closure_helper) << 6) | 0x34; + tramp[3] = (9 << 27) | (9 << 22) | (LO (ffi_closure_helper) << 6) | 0x14; + tramp[4] = (0 << 27) | (10 << 22) | (HI (closure) << 6) | 0x34; + tramp[5] = (10 << 27) | (10 << 22) | (LO (closure) << 6) | 0x14; + tramp[6] = (8 << 27) | (0x0d << 11) | 0x3a; +#undef HI +#undef LO + + /* Flush the caches. + See Example 9-4 in the Nios II Software Developer's Handbook. */ + for (i = 0; i < 7; i++) + asm volatile ("flushd 0(%0); flushi %0" :: "r"(tramp + i) : "memory"); + asm volatile ("flushp" ::: "memory"); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + diff --git a/circuitpython/lib/libffi/src/nios2/ffitarget.h b/circuitpython/lib/libffi/src/nios2/ffitarget.h new file mode 100644 index 0000000..134d118 --- /dev/null +++ b/circuitpython/lib/libffi/src/nios2/ffitarget.h @@ -0,0 +1,52 @@ +/* libffi target includes for Altera Nios II. + + Copyright (c) 2013 Mentor Graphics. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +/* Structures have a 4-byte alignment even if all the fields have lesser + alignment requirements. */ +#define FFI_AGGREGATE_ALIGNMENT 4 + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 28 /* 7 instructions */ +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/nios2/sysv.S b/circuitpython/lib/libffi/src/nios2/sysv.S new file mode 100644 index 0000000..75f442b --- /dev/null +++ b/circuitpython/lib/libffi/src/nios2/sysv.S @@ -0,0 +1,136 @@ +/* Low-level libffi support for Altera Nios II. + + Copyright (c) 2013 Mentor Graphics. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* This function is declared on the C side as + + extern UINT64 ffi_call_sysv (void (*arghook) (char *, extended_cif *), + extended_cif *ecif, + unsigned nbytes, + void (*fn) (void)); + + On input, the arguments appear as + r4 = arghook + r5 = ecif + r6 = nbytes + r7 = fn +*/ + + .section .text + .align 2 + .global ffi_call_sysv + .type ffi_call_sysv, @function + +ffi_call_sysv: + .cfi_startproc + + /* Create the stack frame, saving r16 so we can use it locally. */ + addi sp, sp, -12 + .cfi_def_cfa_offset 12 + stw ra, 8(sp) + stw fp, 4(sp) + stw r16, 0(sp) + .cfi_offset 31, -4 + .cfi_offset 28, -8 + .cfi_offset 16, -12 + mov fp, sp + .cfi_def_cfa_register 28 + mov r16, r7 + + /* Adjust the stack pointer to create the argument buffer + nbytes long. */ + sub sp, sp, r6 + + /* Call the arghook function. */ + mov r2, r4 /* fn */ + mov r4, sp /* argbuffer */ + callr r2 /* r5 already contains ecif */ + + /* Pop off the first 16 bytes of the argument buffer on the stack, + transferring the contents to the argument registers. */ + ldw r4, 0(sp) + ldw r5, 4(sp) + ldw r6, 8(sp) + ldw r7, 12(sp) + addi sp, sp, 16 + + /* Call the user function, which leaves its result in r2 and r3. */ + callr r16 + + /* Pop off the stack frame. */ + mov sp, fp + ldw ra, 8(sp) + ldw fp, 4(sp) + ldw r16, 0(sp) + addi sp, sp, 12 + ret + .cfi_endproc + .size ffi_call_sysv, .-ffi_call_sysv + + +/* Closure trampolines jump here after putting the C helper address + in r9 and the closure pointer in r10. The user-supplied arguments + to the closure are in the normal places, in r4-r7 and on the + stack. Push the register arguments on the stack too and then call the + C helper function to deal with them. */ + + .section .text + .align 2 + .global ffi_closure_sysv + .type ffi_closure_sysv, @function + +ffi_closure_sysv: + .cfi_startproc + + /* Create the stack frame, pushing the register args on the stack + just below the stack args. This is the same trick illustrated + in Figure 7-3 in the Nios II Processor Reference Handbook, used + for variable arguments and structures passed by value. */ + addi sp, sp, -20 + .cfi_def_cfa_offset 20 + stw ra, 0(sp) + .cfi_offset 31, -20 + stw r4, 4(sp) + .cfi_offset 4, -16 + stw r5, 8(sp) + .cfi_offset 5, -12 + stw r6, 12(sp) + .cfi_offset 6, -8 + stw r7, 16(sp) + .cfi_offset 7, -4 + + /* Call the helper. + r4 = pointer to arguments on stack + r5 = closure pointer (loaded in r10 by the trampoline) + r9 = address of helper function (loaded by trampoline) */ + addi r4, sp, 4 + mov r5, r10 + callr r9 + + /* Pop the stack and return. */ + ldw ra, 0(sp) + addi sp, sp, 20 + .cfi_def_cfa_offset -20 + ret + .cfi_endproc + .size ffi_closure_sysv, .-ffi_closure_sysv + diff --git a/circuitpython/lib/libffi/src/or1k/ffi.c b/circuitpython/lib/libffi/src/or1k/ffi.c new file mode 100644 index 0000000..2bad938 --- /dev/null +++ b/circuitpython/lib/libffi/src/or1k/ffi.c @@ -0,0 +1,328 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2014 Sebastian Macke + + OpenRISC Foreign Function Interface + + 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 +#include "ffi_common.h" + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +void* ffi_prep_args(char *stack, extended_cif *ecif) +{ + char *stacktemp = stack; + int i, s; + ffi_type **arg; + int count = 0; + int nfixedargs; + + nfixedargs = ecif->cif->nfixedargs; + arg = ecif->cif->arg_types; + void **argv = ecif->avalue; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) + { + *(void **) stack = ecif->rvalue; + stack += 4; + count = 4; + } + for(i=0; icif->nargs; i++) + { + + /* variadic args are saved on stack */ + if ((nfixedargs == 0) && (count < 24)) + { + count = 24; + stack = stacktemp + 24; + } + nfixedargs--; + + s = 4; + switch((*arg)->type) + { + case FFI_TYPE_STRUCT: + *(void **)stack = *argv; + break; + + case FFI_TYPE_SINT8: + *(signed int *) stack = (signed int)*(SINT8 *)(* argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) stack = (unsigned int)*(UINT8 *)(* argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) stack = (signed int)*(SINT16 *)(* argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) stack = (unsigned int)*(UINT16 *)(* argv); + break; + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_FLOAT: + case FFI_TYPE_POINTER: + *(int *)stack = *(int*)(*argv); + break; + + default: /* 8 byte types */ + if (count == 20) /* never split arguments */ + { + stack += 4; + count += 4; + } + s = (*arg)->size; + memcpy(stack, *argv, s); + break; + } + + stack += s; + count += s; + argv++; + arg++; + } + return stacktemp + ((count>24)?24:0); +} + +extern void ffi_call_SYSV(unsigned, + extended_cif *, + void *(*)(int *, extended_cif *), + unsigned *, + void (*fn)(void), + unsigned); + + +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + int i; + int size; + ffi_type **arg; + + /* Calculate size to allocate on stack */ + + for(i = 0, arg = cif->arg_types, size=0; i < cif->nargs; i++, arg++) + { + if ((*arg)->type == FFI_TYPE_STRUCT) + size += 4; + else + if ((*arg)->size <= 4) + size += 4; + else + size += 8; + } + + /* for variadic functions more space is needed on the stack */ + if (cif->nargs != cif->nfixedargs) + size += 24; + + if (cif->rtype->type == FFI_TYPE_STRUCT) + size += 4; + + + extended_cif ecif; + ecif.cif = cif; + ecif.avalue = avalue; + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV(size, &ecif, ffi_prep_args, rvalue, fn, cif->flags); + break; + default: + FFI_ASSERT(0); + break; + } +} + + +void ffi_closure_SYSV(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, unsigned long r8) +{ + register int *sp __asm__ ("r17"); + register int *r13 __asm__ ("r13"); + + ffi_closure* closure = (ffi_closure*) r13; + char *stack_args = sp; + + /* Lay the register arguments down in a continuous chunk of memory. */ + unsigned register_args[6] = + { r3, r4, r5, r6, r7, r8 }; + + /* Pointer to a struct return value. */ + void *struct_rvalue = (void *) r3; + + ffi_cif *cif = closure->cif; + ffi_type **arg_types = cif->arg_types; + void **avalue = alloca (cif->nargs * sizeof(void *)); + char *ptr = (char *) register_args; + int count = 0; + int nfixedargs = cif->nfixedargs; + int i; + + /* preserve struct type return pointer passing */ + + if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ptr += 4; + count = 4; + } + + /* Find the address of each argument. */ + for (i = 0; i < cif->nargs; i++) + { + + /* variadic args are saved on stack */ + if ((nfixedargs == 0) && (count < 24)) + { + ptr = stack_args; + count = 24; + } + nfixedargs--; + + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + avalue[i] = ptr + 3; + break; + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + avalue[i] = ptr + 2; + break; + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_FLOAT: + case FFI_TYPE_POINTER: + avalue[i] = ptr; + break; + + case FFI_TYPE_STRUCT: + avalue[i] = *(void**)ptr; + break; + + default: + /* 8-byte values */ + + /* arguments are never splitted */ + if (ptr == ®ister_args[5]) + ptr = stack_args; + avalue[i] = ptr; + ptr += 4; + count += 4; + break; + } + ptr += 4; + count += 4; + + /* If we've handled more arguments than fit in registers, + start looking at the those passed on the stack. */ + + if (count == 24) + ptr = stack_args; + } + + if (cif->rtype && (cif->rtype->type == FFI_TYPE_STRUCT)) + { + (closure->fun) (cif, struct_rvalue, avalue, closure->user_data); + } else + { + long long rvalue; + (closure->fun) (cif, &rvalue, avalue, closure->user_data); + if (cif->rtype) + asm ("l.ori r12, %0, 0x0\n l.lwz r11, 0(r12)\n l.lwz r12, 4(r12)" : : "r" (&rvalue)); + } +} + + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + unsigned short *tramp = (unsigned short *) closure->tramp; + unsigned long fn = (unsigned long) ffi_closure_SYSV; + unsigned long cls = (unsigned long) codeloc; + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + /* write pointers to temporary registers */ + tramp[0] = (0x6 << 10) | (13 << 5); /* l.movhi r13, ... */ + tramp[1] = cls >> 16; + tramp[2] = (0x2a << 10) | (13 << 5) | 13; /* l.ori r13, r13, ... */ + tramp[3] = cls & 0xFFFF; + + tramp[4] = (0x6 << 10) | (15 << 5); /* l.movhi r15, ... */ + tramp[5] = fn >> 16; + tramp[6] = (0x2a << 10) | (15 << 5) | 15; /* l.ori r15, r15 ... */ + tramp[7] = fn & 0xFFFF; + + tramp[8] = (0x11 << 10); /* l.jr r15 */ + tramp[9] = 15 << 11; + + tramp[10] = (0x2a << 10) | (17 << 5) | 1; /* l.ori r17, r1, ... */ + tramp[11] = 0x0; + + return FFI_OK; +} + + +ffi_status ffi_prep_cif_machdep (ffi_cif *cif) +{ + cif->flags = 0; + + /* structures are returned as pointers */ + if (cif->rtype->type == FFI_TYPE_STRUCT) + cif->flags = FFI_TYPE_STRUCT; + else + if (cif->rtype->size > 4) + cif->flags = FFI_TYPE_UINT64; + + cif->nfixedargs = cif->nargs; + + return FFI_OK; +} + + +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, + unsigned int nfixedargs, unsigned int ntotalargs) +{ + ffi_status status; + + status = ffi_prep_cif_machdep (cif); + cif->nfixedargs = nfixedargs; + return status; +} diff --git a/circuitpython/lib/libffi/src/or1k/ffitarget.h b/circuitpython/lib/libffi/src/or1k/ffitarget.h new file mode 100644 index 0000000..e55da28 --- /dev/null +++ b/circuitpython/lib/libffi/src/or1k/ffitarget.h @@ -0,0 +1,58 @@ +/* ----------------------------------------------------------------------- + ffitarget.h - Copyright (c) 2014 Sebastian Macke + + OpenRISC Target configuration macros + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- System specific configurations ----------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 +#define FFI_TRAMPOLINE_SIZE (24) + +#define FFI_TARGET_SPECIFIC_VARIADIC 1 +#define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs; + +#endif + diff --git a/circuitpython/lib/libffi/src/or1k/sysv.S b/circuitpython/lib/libffi/src/or1k/sysv.S new file mode 100644 index 0000000..df6570b --- /dev/null +++ b/circuitpython/lib/libffi/src/or1k/sysv.S @@ -0,0 +1,107 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2014 Sebastian Macke + + OpenRISC Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + +.text + .globl ffi_call_SYSV + .type ffi_call_SYSV, @function +/* + r3: size to allocate on stack + r4: extended cif structure + r5: function pointer ffi_prep_args + r6: ret address + r7: function to call + r8: flag for return type +*/ + +ffi_call_SYSV: + /* Store registers used on stack */ + l.sw -4(r1), r9 /* return address */ + l.sw -8(r1), r1 /* stack address */ + l.sw -12(r1), r14 /* callee saved registers */ + l.sw -16(r1), r16 + l.sw -20(r1), r18 + l.sw -24(r1), r20 + + l.ori r14, r1, 0x0 /* save stack pointer */ + l.addi r1, r1, -24 + + l.ori r16, r7, 0x0 /* save function address */ + l.ori r18, r6, 0x0 /* save ret address */ + l.ori r20, r8, 0x0 /* save flag */ + + l.sub r1, r1, r3 /* reserve space on stack */ + + /* Call ffi_prep_args */ + l.ori r3, r1, 0x0 /* first argument stack address, second already ecif */ + l.jalr r5 + l.nop + + /* Load register arguments and call*/ + + l.lwz r3, 0(r1) + l.lwz r4, 4(r1) + l.lwz r5, 8(r1) + l.lwz r6, 12(r1) + l.lwz r7, 16(r1) + l.lwz r8, 20(r1) + l.ori r1, r11, 0x0 /* new stack pointer */ + l.jalr r16 + l.nop + + /* handle return values */ + + l.sfeqi r20, FFI_TYPE_STRUCT + l.bf ret /* structs don't return an rvalue */ + l.nop + + /* copy ret address */ + + l.sfeqi r20, FFI_TYPE_UINT64 + l.bnf four_byte_ret /* 8 byte value is returned */ + l.nop + + l.sw 4(r18), r12 + +four_byte_ret: + l.sw 0(r18), r11 + +ret: + /* return */ + l.ori r1, r14, 0x0 /* reset stack pointer */ + l.lwz r9, -4(r1) + l.lwz r1, -8(r1) + l.lwz r14, -12(r1) + l.lwz r16, -16(r1) + l.lwz r18, -20(r1) + l.lwz r20, -24(r1) + l.jr r9 + l.nop + +.size ffi_call_SYSV, .-ffi_call_SYSV diff --git a/circuitpython/lib/libffi/src/pa/ffi.c b/circuitpython/lib/libffi/src/pa/ffi.c new file mode 100644 index 0000000..4ce2bc6 --- /dev/null +++ b/circuitpython/lib/libffi/src/pa/ffi.c @@ -0,0 +1,719 @@ +/* ----------------------------------------------------------------------- + ffi.c - (c) 2011 Anthony Green + (c) 2008 Red Hat, Inc. + (c) 2006 Free Software Foundation, Inc. + (c) 2003-2004 Randolph Chung + + HPPA Foreign Function Interface + HP-UX PA ABI support + + 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 +#include + +#include +#include + +#define ROUND_UP(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1)) + +#define MIN_STACK_SIZE 64 +#define FIRST_ARG_SLOT 9 +#define DEBUG_LEVEL 0 + +#define fldw(addr, fpreg) \ + __asm__ volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg) +#define fstw(fpreg, addr) \ + __asm__ volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr)) +#define fldd(addr, fpreg) \ + __asm__ volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg) +#define fstd(fpreg, addr) \ + __asm__ volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr)) + +#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0) + +static inline int ffi_struct_type(ffi_type *t) +{ + size_t sz = t->size; + + /* Small structure results are passed in registers, + larger ones are passed by pointer. Note that + small structures of size 2, 4 and 8 differ from + the corresponding integer types in that they have + different alignment requirements. */ + + if (sz <= 1) + return FFI_TYPE_UINT8; + else if (sz == 2) + return FFI_TYPE_SMALL_STRUCT2; + else if (sz == 3) + return FFI_TYPE_SMALL_STRUCT3; + else if (sz == 4) + return FFI_TYPE_SMALL_STRUCT4; + else if (sz == 5) + return FFI_TYPE_SMALL_STRUCT5; + else if (sz == 6) + return FFI_TYPE_SMALL_STRUCT6; + else if (sz == 7) + return FFI_TYPE_SMALL_STRUCT7; + else if (sz <= 8) + return FFI_TYPE_SMALL_STRUCT8; + else + return FFI_TYPE_STRUCT; /* else, we pass it by pointer. */ +} + +/* PA has a downward growing stack, which looks like this: + + Offset + [ Variable args ] + SP = (4*(n+9)) arg word N + ... + SP-52 arg word 4 + [ Fixed args ] + SP-48 arg word 3 + SP-44 arg word 2 + SP-40 arg word 1 + SP-36 arg word 0 + [ Frame marker ] + ... + SP-20 RP + SP-4 previous SP + + The first four argument words on the stack are reserved for use by + the callee. Instead, the general and floating registers replace + the first four argument slots. Non FP arguments are passed solely + in the general registers. FP arguments are passed in both general + and floating registers when using libffi. + + Non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23. + Non-FP 64-bit args are passed in register pairs, starting + on an odd numbered register (i.e. r25+r26 and r23+r24). + FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L. + FP 64-bit arguments are passed in fr5 and fr7. + + The registers are allocated in the same manner as stack slots. + This allows the callee to save its arguments on the stack if + necessary: + + arg word 3 -> gr23 or fr7L + arg word 2 -> gr24 or fr6L or fr7R + arg word 1 -> gr25 or fr5L + arg word 0 -> gr26 or fr4L or fr5R + + Note that fr4R and fr6R are never used for arguments (i.e., + doubles are not passed in fr4 or fr6). + + The rest of the arguments are passed on the stack starting at SP-52, + but 64-bit arguments need to be aligned to an 8-byte boundary + + This means we can have holes either in the register allocation, + or in the stack. */ + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments + + The following code will put everything into the stack frame + (which was allocated by the asm routine), and on return + the asm routine will load the arguments that should be + passed by register into the appropriate registers + + NOTE: We load floating point args in this function... that means we + assume gcc will not mess with fp regs in here. */ + +void ffi_prep_args_pa32(UINT32 *stack, extended_cif *ecif, unsigned bytes) +{ + register unsigned int i; + register ffi_type **p_arg; + register void **p_argv; + unsigned int slot = FIRST_ARG_SLOT; + char *dest_cpy; + size_t len; + + debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack, + ecif, bytes); + + p_arg = ecif->cif->arg_types; + p_argv = ecif->avalue; + + for (i = 0; i < ecif->cif->nargs; i++) + { + int type = (*p_arg)->type; + + switch (type) + { + case FFI_TYPE_SINT8: + *(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv); + break; + + case FFI_TYPE_UINT8: + *(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv); + break; + + case FFI_TYPE_SINT16: + *(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv); + break; + + case FFI_TYPE_UINT16: + *(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv); + break; + + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv), + slot); + *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv); + break; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + /* Align slot for 64-bit type. */ + slot += (slot & 1) ? 1 : 2; + *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv); + break; + + case FFI_TYPE_FLOAT: + /* First 4 args go in fr4L - fr7L. */ + debug(3, "Storing UINT32(float) in slot %u\n", slot); + *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv); + switch (slot - FIRST_ARG_SLOT) + { + /* First 4 args go in fr4L - fr7L. */ + case 0: fldw(stack - slot, fr4); break; + case 1: fldw(stack - slot, fr5); break; + case 2: fldw(stack - slot, fr6); break; + case 3: fldw(stack - slot, fr7); break; + } + break; + + case FFI_TYPE_DOUBLE: + /* Align slot for 64-bit type. */ + slot += (slot & 1) ? 1 : 2; + debug(3, "Storing UINT64(double) at slot %u\n", slot); + *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv); + switch (slot - FIRST_ARG_SLOT) + { + /* First 2 args go in fr5, fr7. */ + case 1: fldd(stack - slot, fr5); break; + case 3: fldd(stack - slot, fr7); break; + } + break; + +#ifdef PA_HPUX + case FFI_TYPE_LONGDOUBLE: + /* Long doubles are passed in the same manner as structures + larger than 8 bytes. */ + *(UINT32 *)(stack - slot) = (UINT32)(*p_argv); + break; +#endif + + case FFI_TYPE_STRUCT: + + /* Structs smaller or equal than 4 bytes are passed in one + register. Structs smaller or equal 8 bytes are passed in two + registers. Larger structures are passed by pointer. */ + + len = (*p_arg)->size; + if (len <= 4) + { + dest_cpy = (char *)(stack - slot) + 4 - len; + memcpy(dest_cpy, (char *)*p_argv, len); + } + else if (len <= 8) + { + slot += (slot & 1) ? 1 : 2; + dest_cpy = (char *)(stack - slot) + 8 - len; + memcpy(dest_cpy, (char *)*p_argv, len); + } + else + *(UINT32 *)(stack - slot) = (UINT32)(*p_argv); + break; + + default: + FFI_ASSERT(0); + } + + slot++; + p_arg++; + p_argv++; + } + + /* Make sure we didn't mess up and scribble on the stack. */ + { + unsigned int n; + + debug(5, "Stack setup:\n"); + for (n = 0; n < (bytes + 3) / 4; n++) + { + if ((n%4) == 0) { debug(5, "\n%08x: ", (unsigned int)(stack - n)); } + debug(5, "%08x ", *(stack - n)); + } + debug(5, "\n"); + } + + FFI_ASSERT(slot * 4 <= bytes); + + return; +} + +static void ffi_size_stack_pa32(ffi_cif *cif) +{ + ffi_type **ptr; + int i; + int z = 0; /* # stack slots */ + + for (ptr = cif->arg_types, i = 0; i < cif->nargs; ptr++, i++) + { + int type = (*ptr)->type; + + switch (type) + { + case FFI_TYPE_DOUBLE: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + z += 2 + (z & 1); /* must start on even regs, so we may waste one */ + break; + +#ifdef PA_HPUX + case FFI_TYPE_LONGDOUBLE: +#endif + case FFI_TYPE_STRUCT: + z += 1; /* pass by ptr, callee will copy */ + break; + + default: /* <= 32-bit values */ + z++; + } + } + + /* We can fit up to 6 args in the default 64-byte stack frame, + if we need more, we need more stack. */ + if (z <= 6) + cif->bytes = MIN_STACK_SIZE; /* min stack size */ + else + cif->bytes = 64 + ROUND_UP((z - 6) * sizeof(UINT32), MIN_STACK_SIZE); + + debug(3, "Calculated stack size is %u bytes\n", cif->bytes); +} + +/* Perform machine dependent cif processing. */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + cif->flags = (unsigned) cif->rtype->type; + break; + +#ifdef PA_HPUX + case FFI_TYPE_LONGDOUBLE: + /* Long doubles are treated like a structure. */ + cif->flags = FFI_TYPE_STRUCT; + break; +#endif + + case FFI_TYPE_STRUCT: + /* For the return type we have to check the size of the structures. + If the size is smaller or equal 4 bytes, the result is given back + in one register. If the size is smaller or equal 8 bytes than we + return the result in two registers. But if the size is bigger than + 8 bytes, we work with pointers. */ + cif->flags = ffi_struct_type(cif->rtype); + break; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + cif->flags = FFI_TYPE_UINT64; + break; + + default: + cif->flags = FFI_TYPE_INT; + break; + } + + /* Lucky us, because of the unique PA ABI we get to do our + own stack sizing. */ + switch (cif->abi) + { + case FFI_PA32: + ffi_size_stack_pa32(cif); + break; + + default: + FFI_ASSERT(0); + break; + } + + return FFI_OK; +} + +extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned), + extended_cif *, unsigned, unsigned, unsigned *, + void (*fn)(void)); + +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return + value address then we need to make one. */ + + if (rvalue == NULL +#ifdef PA_HPUX + && (cif->rtype->type == FFI_TYPE_STRUCT + || cif->rtype->type == FFI_TYPE_LONGDOUBLE)) +#else + && cif->rtype->type == FFI_TYPE_STRUCT) +#endif + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { + case FFI_PA32: + debug(3, "Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn); + ffi_call_pa32(ffi_prep_args_pa32, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT(0); + break; + } +} + +#if FFI_CLOSURES +/* This is more-or-less an inverse of ffi_call -- we have arguments on + the stack, and we need to fill them into a cif structure and invoke + the user function. This really ought to be in asm to make sure + the compiler doesn't do things we don't expect. */ +ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack) +{ + ffi_cif *cif; + void **avalue; + void *rvalue; + UINT32 ret[2]; /* function can return up to 64-bits in registers */ + ffi_type **p_arg; + char *tmp; + int i, avn; + unsigned int slot = FIRST_ARG_SLOT; + register UINT32 r28 asm("r28"); + + cif = closure->cif; + + /* If returning via structure, callee will write to our pointer. */ + if (cif->flags == FFI_TYPE_STRUCT) + rvalue = (void *)r28; + else + rvalue = &ret[0]; + + avalue = (void **)alloca(cif->nargs * FFI_SIZEOF_ARG); + avn = cif->nargs; + p_arg = cif->arg_types; + + for (i = 0; i < avn; i++) + { + int type = (*p_arg)->type; + + switch (type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size; + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + slot += (slot & 1) ? 1 : 2; + avalue[i] = (void *)(stack - slot); + break; + + case FFI_TYPE_FLOAT: +#ifdef PA_LINUX + /* The closure call is indirect. In Linux, floating point + arguments in indirect calls with a prototype are passed + in the floating point registers instead of the general + registers. So, we need to replace what was previously + stored in the current slot with the value in the + corresponding floating point register. */ + switch (slot - FIRST_ARG_SLOT) + { + case 0: fstw(fr4, (void *)(stack - slot)); break; + case 1: fstw(fr5, (void *)(stack - slot)); break; + case 2: fstw(fr6, (void *)(stack - slot)); break; + case 3: fstw(fr7, (void *)(stack - slot)); break; + } +#endif + avalue[i] = (void *)(stack - slot); + break; + + case FFI_TYPE_DOUBLE: + slot += (slot & 1) ? 1 : 2; +#ifdef PA_LINUX + /* See previous comment for FFI_TYPE_FLOAT. */ + switch (slot - FIRST_ARG_SLOT) + { + case 1: fstd(fr5, (void *)(stack - slot)); break; + case 3: fstd(fr7, (void *)(stack - slot)); break; + } +#endif + avalue[i] = (void *)(stack - slot); + break; + +#ifdef PA_HPUX + case FFI_TYPE_LONGDOUBLE: + /* Long doubles are treated like a big structure. */ + avalue[i] = (void *) *(stack - slot); + break; +#endif + + case FFI_TYPE_STRUCT: + /* Structs smaller or equal than 4 bytes are passed in one + register. Structs smaller or equal 8 bytes are passed in two + registers. Larger structures are passed by pointer. */ + if((*p_arg)->size <= 4) + { + avalue[i] = (void *)(stack - slot) + sizeof(UINT32) - + (*p_arg)->size; + } + else if ((*p_arg)->size <= 8) + { + slot += (slot & 1) ? 1 : 2; + avalue[i] = (void *)(stack - slot) + sizeof(UINT64) - + (*p_arg)->size; + } + else + avalue[i] = (void *) *(stack - slot); + break; + + default: + FFI_ASSERT(0); + } + + slot++; + p_arg++; + } + + /* Invoke the closure. */ + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0], + ret[1]); + + /* Store the result using the lower 2 bytes of the flags. */ + switch (cif->flags) + { + case FFI_TYPE_UINT8: + *(stack - FIRST_ARG_SLOT) = (UINT8)(ret[0] >> 24); + break; + case FFI_TYPE_SINT8: + *(stack - FIRST_ARG_SLOT) = (SINT8)(ret[0] >> 24); + break; + case FFI_TYPE_UINT16: + *(stack - FIRST_ARG_SLOT) = (UINT16)(ret[0] >> 16); + break; + case FFI_TYPE_SINT16: + *(stack - FIRST_ARG_SLOT) = (SINT16)(ret[0] >> 16); + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + *(stack - FIRST_ARG_SLOT) = ret[0]; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + *(stack - FIRST_ARG_SLOT) = ret[0]; + *(stack - FIRST_ARG_SLOT - 1) = ret[1]; + break; + + case FFI_TYPE_DOUBLE: + fldd(rvalue, fr4); + break; + + case FFI_TYPE_FLOAT: + fldw(rvalue, fr4); + break; + + case FFI_TYPE_STRUCT: + /* Don't need a return value, done by caller. */ + break; + + case FFI_TYPE_SMALL_STRUCT2: + case FFI_TYPE_SMALL_STRUCT3: + case FFI_TYPE_SMALL_STRUCT4: + tmp = (void*)(stack - FIRST_ARG_SLOT); + tmp += 4 - cif->rtype->size; + memcpy((void*)tmp, &ret[0], cif->rtype->size); + break; + + case FFI_TYPE_SMALL_STRUCT5: + case FFI_TYPE_SMALL_STRUCT6: + case FFI_TYPE_SMALL_STRUCT7: + case FFI_TYPE_SMALL_STRUCT8: + { + unsigned int ret2[2]; + int off; + + /* Right justify ret[0] and ret[1] */ + switch (cif->flags) + { + case FFI_TYPE_SMALL_STRUCT5: off = 3; break; + case FFI_TYPE_SMALL_STRUCT6: off = 2; break; + case FFI_TYPE_SMALL_STRUCT7: off = 1; break; + default: off = 0; break; + } + + memset (ret2, 0, sizeof (ret2)); + memcpy ((char *)ret2 + off, ret, 8 - off); + + *(stack - FIRST_ARG_SLOT) = ret2[0]; + *(stack - FIRST_ARG_SLOT - 1) = ret2[1]; + } + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_VOID: + break; + + default: + debug(0, "assert with cif->flags: %d\n",cif->flags); + FFI_ASSERT(0); + break; + } + return FFI_OK; +} + +/* Fill in a closure to refer to the specified fun and user_data. + cif specifies the argument and result types for fun. + The cif must already be prep'ed. */ + +extern void ffi_closure_pa32(void); + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + UINT32 *tramp = (UINT32 *)(closure->tramp); +#ifdef PA_HPUX + UINT32 *tmp; +#endif + + if (cif->abi != FFI_PA32) + return FFI_BAD_ABI; + + /* Make a small trampoline that will branch to our + handler function. Use PC-relative addressing. */ + +#ifdef PA_LINUX + tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */ + tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */ + tramp[2] = 0x4aa10028; /* ldw 20(%r21),%r1 ; load plabel */ + tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21 ; get closure addr */ + tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */ + tramp[5] = 0xeac0c000; /* bv%r0(%r22) ; branch to handler */ + tramp[6] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */ + tramp[7] = ((UINT32)(ffi_closure_pa32) & ~2); + + /* Flush d/icache -- have to flush up 2 two lines because of + alignment. */ + __asm__ volatile( + "fdc 0(%0)\n\t" + "fdc %1(%0)\n\t" + "fic 0(%%sr4, %0)\n\t" + "fic %1(%%sr4, %0)\n\t" + "sync\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n" + : + : "r"((unsigned long)tramp & ~31), + "r"(32 /* stride */) + : "memory"); +#endif + +#ifdef PA_HPUX + tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */ + tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */ + tramp[2] = 0x4aa10038; /* ldw 28(%r21),%r1 ; load plabel */ + tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21 ; get closure addr */ + tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */ + tramp[5] = 0x02c010b4; /* ldsid (%r22),%r20 ; load space id */ + tramp[6] = 0x00141820; /* mtsp %r20,%sr0 ; into %sr0 */ + tramp[7] = 0xe2c00000; /* be 0(%sr0,%r22) ; branch to handler */ + tramp[8] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */ + tramp[9] = ((UINT32)(ffi_closure_pa32) & ~2); + + /* Flush d/icache -- have to flush three lines because of alignment. */ + __asm__ volatile( + "copy %1,%0\n\t" + "fdc,m %2(%0)\n\t" + "fdc,m %2(%0)\n\t" + "fdc,m %2(%0)\n\t" + "ldsid (%1),%0\n\t" + "mtsp %0,%%sr0\n\t" + "copy %1,%0\n\t" + "fic,m %2(%%sr0,%0)\n\t" + "fic,m %2(%%sr0,%0)\n\t" + "fic,m %2(%%sr0,%0)\n\t" + "sync\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n" + : "=&r" ((unsigned long)tmp) + : "r" ((unsigned long)tramp & ~31), + "r" (32/* stride */) + : "memory"); +#endif + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} +#endif diff --git a/circuitpython/lib/libffi/src/pa/ffitarget.h b/circuitpython/lib/libffi/src/pa/ffitarget.h new file mode 100644 index 0000000..fff4c6b --- /dev/null +++ b/circuitpython/lib/libffi/src/pa/ffitarget.h @@ -0,0 +1,85 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for hppa. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- System specific configurations ----------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + +#ifdef PA_LINUX + FFI_PA32, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_PA32 +#endif + +#ifdef PA_HPUX + FFI_PA32, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_PA32 +#endif + +#ifdef PA64_HPUX +#error "PA64_HPUX FFI is not yet implemented" + FFI_PA64, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_PA64 +#endif +} ffi_abi; +#endif + +#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 + +#ifdef PA_LINUX +#define FFI_TRAMPOLINE_SIZE 32 +#else +#define FFI_TRAMPOLINE_SIZE 40 +#endif + +#define FFI_TYPE_SMALL_STRUCT2 -1 +#define FFI_TYPE_SMALL_STRUCT3 -2 +#define FFI_TYPE_SMALL_STRUCT4 -3 +#define FFI_TYPE_SMALL_STRUCT5 -4 +#define FFI_TYPE_SMALL_STRUCT6 -5 +#define FFI_TYPE_SMALL_STRUCT7 -6 +#define FFI_TYPE_SMALL_STRUCT8 -7 +#endif diff --git a/circuitpython/lib/libffi/src/pa/hpux32.S b/circuitpython/lib/libffi/src/pa/hpux32.S new file mode 100644 index 0000000..40528ba --- /dev/null +++ b/circuitpython/lib/libffi/src/pa/hpux32.S @@ -0,0 +1,368 @@ +/* ----------------------------------------------------------------------- + hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc. + (c) 2008 Red Hat, Inc. + based on src/pa/linux.S + + HP-UX PA Foreign Function Interface + + 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 AUTHOR 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 LIBFFI_ASM +#include +#include + + .LEVEL 1.1 + .SPACE $PRIVATE$ + .IMPORT $global$,DATA + .IMPORT $$dyncall,MILLICODE + .SUBSPA $DATA$ + .align 4 + + /* void ffi_call_pa32(void (*)(char *, extended_cif *), + extended_cif *ecif, + unsigned bytes, + unsigned flags, + unsigned *rvalue, + void (*fn)(void)); + */ + + .export ffi_call_pa32,ENTRY,PRIV_LEV=3 + .import ffi_prep_args_pa32,CODE + + .SPACE $TEXT$ + .SUBSPA $CODE$ + .align 4 + +L$FB1 +ffi_call_pa32 + .proc + .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4 + .entry + stw %rp, -20(%sp) + copy %r3, %r1 +L$CFI11 + copy %sp, %r3 +L$CFI12 + + /* Setup the stack for calling prep_args... + We want the stack to look like this: + + [ Previous stack ] <- %r3 + + [ 64-bytes register save area ] <- %r4 + + [ Stack space for actual call, passed as ] <- %arg0 + [ arg0 to ffi_prep_args_pa32 ] + + [ Stack for calling prep_args ] <- %sp + */ + + stwm %r1, 64(%sp) + stw %r4, 12(%r3) +L$CFI13 + copy %sp, %r4 + + addl %arg2, %r4, %arg0 ; arg stack + stw %arg3, -48(%r3) ; save flags we need it later + + /* Call prep_args: + %arg0(stack) -- set up above + %arg1(ecif) -- same as incoming param + %arg2(bytes) -- same as incoming param */ + bl ffi_prep_args_pa32,%r2 + ldo 64(%arg0), %sp + ldo -64(%sp), %sp + + /* now %sp should point where %arg0 was pointing. */ + + /* Load the arguments that should be passed in registers + The fp args are loaded by the prep_args function. */ + ldw -36(%sp), %arg0 + ldw -40(%sp), %arg1 + ldw -44(%sp), %arg2 + ldw -48(%sp), %arg3 + + /* in case the function is going to return a structure + we need to give it a place to put the result. */ + ldw -52(%r3), %ret0 ; %ret0 <- rvalue + ldw -56(%r3), %r22 ; %r22 <- function to call + bl $$dyncall, %r31 ; Call the user function + copy %r31, %rp + + /* Prepare to store the result; we need to recover flags and rvalue. */ + ldw -48(%r3), %r21 ; r21 <- flags + ldw -52(%r3), %r20 ; r20 <- rvalue + + /* Store the result according to the return type. The most + likely types should come first. */ + +L$checkint + comib,<>,n FFI_TYPE_INT, %r21, L$checkint8 + b L$done + stw %ret0, 0(%r20) + +L$checkint8 + comib,<>,n FFI_TYPE_UINT8, %r21, L$checkint16 + b L$done + stb %ret0, 0(%r20) + +L$checkint16 + comib,<>,n FFI_TYPE_UINT16, %r21, L$checkdbl + b L$done + sth %ret0, 0(%r20) + +L$checkdbl + comib,<>,n FFI_TYPE_DOUBLE, %r21, L$checkfloat + b L$done + fstd %fr4,0(%r20) + +L$checkfloat + comib,<>,n FFI_TYPE_FLOAT, %r21, L$checkll + b L$done + fstw %fr4L,0(%r20) + +L$checkll + comib,<>,n FFI_TYPE_UINT64, %r21, L$checksmst2 + stw %ret0, 0(%r20) + b L$done + stw %ret1, 4(%r20) + +L$checksmst2 + comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, L$checksmst3 + /* 2-byte structs are returned in ret0 as ????xxyy. */ + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b L$done + stb %ret0, 0(%r20) + +L$checksmst3 + comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, L$checksmst4 + /* 3-byte structs are returned in ret0 as ??xxyyzz. */ + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b L$done + stb %ret0, 0(%r20) + +L$checksmst4 + comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, L$checksmst5 + /* 4-byte structs are returned in ret0 as wwxxyyzz. */ + extru %ret0, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b L$done + stb %ret0, 0(%r20) + +L$checksmst5 + comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, L$checksmst6 + /* 5 byte values are returned right justified: + ret0 ret1 + 5: ??????aa bbccddee */ + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b L$done + stb %ret1, 0(%r20) + +L$checksmst6 + comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, L$checksmst7 + /* 6 byte values are returned right justified: + ret0 ret1 + 6: ????aabb ccddeeff */ + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b L$done + stb %ret1, 0(%r20) + +L$checksmst7 + comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, L$checksmst8 + /* 7 byte values are returned right justified: + ret0 ret1 + 7: ??aabbcc ddeeffgg */ + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b L$done + stb %ret1, 0(%r20) + +L$checksmst8 + comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, L$done + /* 8 byte values are returned right justified: + ret0 ret1 + 8: aabbccdd eeffgghh */ + extru %ret0, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stb %ret1, 0(%r20) + +L$done + /* all done, return */ + copy %r4, %sp ; pop arg stack + ldw 12(%r3), %r4 + ldwm -64(%sp), %r3 ; .. and pop stack + ldw -20(%sp), %rp + bv %r0(%rp) + nop + .exit + .procend +L$FE1 + + /* void ffi_closure_pa32(void); + Called with closure argument in %r21 */ + + .SPACE $TEXT$ + .SUBSPA $CODE$ + .export ffi_closure_pa32,ENTRY,PRIV_LEV=3,RTNVAL=GR + .import ffi_closure_inner_pa32,CODE + .align 4 +L$FB2 +ffi_closure_pa32 + .proc + .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3 + .entry + + stw %rp, -20(%sp) + copy %r3, %r1 +L$CFI21 + copy %sp, %r3 +L$CFI22 + stwm %r1, 64(%sp) + + /* Put arguments onto the stack and call ffi_closure_inner. */ + stw %arg0, -36(%r3) + stw %arg1, -40(%r3) + stw %arg2, -44(%r3) + stw %arg3, -48(%r3) + + copy %r21, %arg0 + bl ffi_closure_inner_pa32, %r2 + copy %r3, %arg1 + ldwm -64(%sp), %r3 + ldw -20(%sp), %rp + ldw -36(%sp), %ret0 + bv %r0(%rp) + ldw -40(%sp), %ret1 + .exit + .procend +L$FE2: + + .SPACE $PRIVATE$ + .SUBSPA $DATA$ + + .align 4 + .EXPORT _GLOBAL__F_ffi_call_pa32,DATA +_GLOBAL__F_ffi_call_pa32 +L$frame1: + .word L$ECIE1-L$SCIE1 ;# Length of Common Information Entry +L$SCIE1: + .word 0x0 ;# CIE Identifier Tag + .byte 0x1 ;# CIE Version + .ascii "\0" ;# CIE Augmentation + .uleb128 0x1 ;# CIE Code Alignment Factor + .sleb128 4 ;# CIE Data Alignment Factor + .byte 0x2 ;# CIE RA Column + .byte 0xc ;# DW_CFA_def_cfa + .uleb128 0x1e + .uleb128 0x0 + .align 4 +L$ECIE1: +L$SFDE1: + .word L$EFDE1-L$ASFDE1 ;# FDE Length +L$ASFDE1: + .word L$ASFDE1-L$frame1 ;# FDE CIE offset + .word L$FB1 ;# FDE initial location + .word L$FE1-L$FB1 ;# FDE address range + + .byte 0x4 ;# DW_CFA_advance_loc4 + .word L$CFI11-L$FB1 + .byte 0x83 ;# DW_CFA_offset, column 0x3 + .uleb128 0x0 + .byte 0x11 ;# DW_CFA_offset_extended_sf; save r2 at [r30-20] + .uleb128 0x2 + .sleb128 -5 + + .byte 0x4 ;# DW_CFA_advance_loc4 + .word L$CFI12-L$CFI11 + .byte 0xd ;# DW_CFA_def_cfa_register = r3 + .uleb128 0x3 + + .byte 0x4 ;# DW_CFA_advance_loc4 + .word L$CFI13-L$CFI12 + .byte 0x84 ;# DW_CFA_offset, column 0x4 + .uleb128 0x3 + + .align 4 +L$EFDE1: + +L$SFDE2: + .word L$EFDE2-L$ASFDE2 ;# FDE Length +L$ASFDE2: + .word L$ASFDE2-L$frame1 ;# FDE CIE offset + .word L$FB2 ;# FDE initial location + .word L$FE2-L$FB2 ;# FDE address range + .byte 0x4 ;# DW_CFA_advance_loc4 + .word L$CFI21-L$FB2 + .byte 0x83 ;# DW_CFA_offset, column 0x3 + .uleb128 0x0 + .byte 0x11 ;# DW_CFA_offset_extended_sf + .uleb128 0x2 + .sleb128 -5 + + .byte 0x4 ;# DW_CFA_advance_loc4 + .word L$CFI22-L$CFI21 + .byte 0xd ;# DW_CFA_def_cfa_register = r3 + .uleb128 0x3 + + .align 4 +L$EFDE2: diff --git a/circuitpython/lib/libffi/src/pa/linux.S b/circuitpython/lib/libffi/src/pa/linux.S new file mode 100644 index 0000000..f11ae76 --- /dev/null +++ b/circuitpython/lib/libffi/src/pa/linux.S @@ -0,0 +1,357 @@ +/* ----------------------------------------------------------------------- + linux.S - (c) 2003-2004 Randolph Chung + (c) 2008 Red Hat, Inc. + + HPPA Foreign Function Interface + + 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 RENESAS TECHNOLOGY 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 LIBFFI_ASM +#include +#include + + .text + .level 1.1 + .align 4 + + /* void ffi_call_pa32(void (*)(char *, extended_cif *), + extended_cif *ecif, + unsigned bytes, + unsigned flags, + unsigned *rvalue, + void (*fn)(void)); + */ + + .export ffi_call_pa32,code + .import ffi_prep_args_pa32,code + + .type ffi_call_pa32, @function +.LFB1: +ffi_call_pa32: + .proc + .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4 + .entry + stw %rp, -20(%sp) + copy %r3, %r1 +.LCFI11: + + copy %sp, %r3 +.LCFI12: + + /* Setup the stack for calling prep_args... + We want the stack to look like this: + + [ Previous stack ] <- %r3 + + [ 64-bytes register save area ] <- %r4 + + [ Stack space for actual call, passed as ] <- %arg0 + [ arg0 to ffi_prep_args_pa32 ] + + [ Stack for calling prep_args ] <- %sp + */ + + stwm %r1, 64(%sp) + stw %r4, 12(%r3) +.LCFI13: + copy %sp, %r4 + + addl %arg2, %r4, %arg0 /* arg stack */ + stw %arg3, -48(%r3) /* save flags; we need it later */ + + /* Call prep_args: + %arg0(stack) -- set up above + %arg1(ecif) -- same as incoming param + %arg2(bytes) -- same as incoming param */ + bl ffi_prep_args_pa32,%r2 + ldo 64(%arg0), %sp + ldo -64(%sp), %sp + + /* now %sp should point where %arg0 was pointing. */ + + /* Load the arguments that should be passed in registers + The fp args were loaded by the prep_args function. */ + ldw -36(%sp), %arg0 + ldw -40(%sp), %arg1 + ldw -44(%sp), %arg2 + ldw -48(%sp), %arg3 + + /* in case the function is going to return a structure + we need to give it a place to put the result. */ + ldw -52(%r3), %ret0 /* %ret0 <- rvalue */ + ldw -56(%r3), %r22 /* %r22 <- function to call */ + bl $$dyncall, %r31 /* Call the user function */ + copy %r31, %rp + + /* Prepare to store the result; we need to recover flags and rvalue. */ + ldw -48(%r3), %r21 /* r21 <- flags */ + ldw -52(%r3), %r20 /* r20 <- rvalue */ + + /* Store the result according to the return type. */ + +.Lcheckint: + comib,<>,n FFI_TYPE_INT, %r21, .Lcheckint8 + b .Ldone + stw %ret0, 0(%r20) + +.Lcheckint8: + comib,<>,n FFI_TYPE_UINT8, %r21, .Lcheckint16 + b .Ldone + stb %ret0, 0(%r20) + +.Lcheckint16: + comib,<>,n FFI_TYPE_UINT16, %r21, .Lcheckdbl + b .Ldone + sth %ret0, 0(%r20) + +.Lcheckdbl: + comib,<>,n FFI_TYPE_DOUBLE, %r21, .Lcheckfloat + b .Ldone + fstd %fr4,0(%r20) + +.Lcheckfloat: + comib,<>,n FFI_TYPE_FLOAT, %r21, .Lcheckll + b .Ldone + fstw %fr4L,0(%r20) + +.Lcheckll: + comib,<>,n FFI_TYPE_UINT64, %r21, .Lchecksmst2 + stw %ret0, 0(%r20) + b .Ldone + stw %ret1, 4(%r20) + +.Lchecksmst2: + comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, .Lchecksmst3 + /* 2-byte structs are returned in ret0 as ????xxyy. */ + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret0, 0(%r20) + +.Lchecksmst3: + comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, .Lchecksmst4 + /* 3-byte structs are returned in ret0 as ??xxyyzz. */ + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret0, 0(%r20) + +.Lchecksmst4: + comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, .Lchecksmst5 + /* 4-byte structs are returned in ret0 as wwxxyyzz. */ + extru %ret0, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret0, 0(%r20) + +.Lchecksmst5: + comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, .Lchecksmst6 + /* 5 byte values are returned right justified: + ret0 ret1 + 5: ??????aa bbccddee */ + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret1, 0(%r20) + +.Lchecksmst6: + comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, .Lchecksmst7 + /* 6 byte values are returned right justified: + ret0 ret1 + 6: ????aabb ccddeeff */ + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret1, 0(%r20) + +.Lchecksmst7: + comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, .Lchecksmst8 + /* 7 byte values are returned right justified: + ret0 ret1 + 7: ??aabbcc ddeeffgg */ + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret1, 0(%r20) + +.Lchecksmst8: + comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, .Ldone + /* 8 byte values are returned right justified: + ret0 ret1 + 8: aabbccdd eeffgghh */ + extru %ret0, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stb %ret1, 0(%r20) + +.Ldone: + /* all done, return */ + copy %r4, %sp /* pop arg stack */ + ldw 12(%r3), %r4 + ldwm -64(%sp), %r3 /* .. and pop stack */ + ldw -20(%sp), %rp + bv %r0(%rp) + nop + .exit + .procend +.LFE1: + + /* void ffi_closure_pa32(void); + Called with closure argument in %r21 */ + .export ffi_closure_pa32,code + .import ffi_closure_inner_pa32,code + + .type ffi_closure_pa32, @function +.LFB2: +ffi_closure_pa32: + .proc + .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3 + .entry + + stw %rp, -20(%sp) +.LCFI20: + copy %r3, %r1 +.LCFI21: + copy %sp, %r3 +.LCFI22: + stwm %r1, 64(%sp) + + /* Put arguments onto the stack and call ffi_closure_inner. */ + stw %arg0, -36(%r3) + stw %arg1, -40(%r3) + stw %arg2, -44(%r3) + stw %arg3, -48(%r3) + + copy %r21, %arg0 + bl ffi_closure_inner_pa32, %r2 + copy %r3, %arg1 + + ldwm -64(%sp), %r3 + ldw -20(%sp), %rp + ldw -36(%sp), %ret0 + bv %r0(%r2) + ldw -40(%sp), %ret1 + + .exit + .procend +.LFE2: + + .section ".eh_frame",EH_FRAME_FLAGS,@progbits +.Lframe1: + .word .LECIE1-.LSCIE1 ;# Length of Common Information Entry +.LSCIE1: + .word 0x0 ;# CIE Identifier Tag + .byte 0x1 ;# CIE Version + .ascii "\0" ;# CIE Augmentation + .uleb128 0x1 ;# CIE Code Alignment Factor + .sleb128 4 ;# CIE Data Alignment Factor + .byte 0x2 ;# CIE RA Column + .byte 0xc ;# DW_CFA_def_cfa + .uleb128 0x1e + .uleb128 0x0 + .align 4 +.LECIE1: +.LSFDE1: + .word .LEFDE1-.LASFDE1 ;# FDE Length +.LASFDE1: + .word .LASFDE1-.Lframe1 ;# FDE CIE offset + .word .LFB1 ;# FDE initial location + .word .LFE1-.LFB1 ;# FDE address range + + .byte 0x4 ;# DW_CFA_advance_loc4 + .word .LCFI11-.LFB1 + .byte 0x83 ;# DW_CFA_offset, column 0x3 + .uleb128 0x0 + .byte 0x11 ;# DW_CFA_offset_extended_sf; save r2 at [r30-20] + .uleb128 0x2 + .sleb128 -5 + + .byte 0x4 ;# DW_CFA_advance_loc4 + .word .LCFI12-.LCFI11 + .byte 0xd ;# DW_CFA_def_cfa_register = r3 + .uleb128 0x3 + + .byte 0x4 ;# DW_CFA_advance_loc4 + .word .LCFI13-.LCFI12 + .byte 0x84 ;# DW_CFA_offset, column 0x4 + .uleb128 0x3 + + .align 4 +.LEFDE1: + +.LSFDE2: + .word .LEFDE2-.LASFDE2 ;# FDE Length +.LASFDE2: + .word .LASFDE2-.Lframe1 ;# FDE CIE offset + .word .LFB2 ;# FDE initial location + .word .LFE2-.LFB2 ;# FDE address range + .byte 0x4 ;# DW_CFA_advance_loc4 + .word .LCFI21-.LFB2 + .byte 0x83 ;# DW_CFA_offset, column 0x3 + .uleb128 0x0 + .byte 0x11 ;# DW_CFA_offset_extended_sf + .uleb128 0x2 + .sleb128 -5 + + .byte 0x4 ;# DW_CFA_advance_loc4 + .word .LCFI22-.LCFI21 + .byte 0xd ;# DW_CFA_def_cfa_register = r3 + .uleb128 0x3 + + .align 4 +.LEFDE2: diff --git a/circuitpython/lib/libffi/src/powerpc/aix.S b/circuitpython/lib/libffi/src/powerpc/aix.S new file mode 100644 index 0000000..349e78c --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/aix.S @@ -0,0 +1,328 @@ +/* ----------------------------------------------------------------------- + aix.S - Copyright (c) 2002, 2009 Free Software Foundation, Inc. + based on darwin.S by John Hornkvist + + PowerPC Assembly glue. + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + + .set r0,0 + .set r1,1 + .set r2,2 + .set r3,3 + .set r4,4 + .set r5,5 + .set r6,6 + .set r7,7 + .set r8,8 + .set r9,9 + .set r10,10 + .set r11,11 + .set r12,12 + .set r13,13 + .set r14,14 + .set r15,15 + .set r16,16 + .set r17,17 + .set r18,18 + .set r19,19 + .set r20,20 + .set r21,21 + .set r22,22 + .set r23,23 + .set r24,24 + .set r25,25 + .set r26,26 + .set r27,27 + .set r28,28 + .set r29,29 + .set r30,30 + .set r31,31 + .set f0,0 + .set f1,1 + .set f2,2 + .set f3,3 + .set f4,4 + .set f5,5 + .set f6,6 + .set f7,7 + .set f8,8 + .set f9,9 + .set f10,10 + .set f11,11 + .set f12,12 + .set f13,13 + .set f14,14 + .set f15,15 + .set f16,16 + .set f17,17 + .set f18,18 + .set f19,19 + .set f20,20 + .set f21,21 + + .extern .ffi_prep_args + +#define LIBFFI_ASM +#include +#include +#define JUMPTARGET(name) name +#define L(x) x + .file "aix.S" + .toc + + /* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes, + * unsigned int flags, unsigned int *rvalue, + * void (*fn)(), + * void (*prep_args)(extended_cif*, unsigned *const)); + * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args + */ + +.csect .text[PR] + .align 2 + .globl ffi_call_AIX + .globl .ffi_call_AIX +.csect ffi_call_AIX[DS] +ffi_call_AIX: +#ifdef __64BIT__ + .llong .ffi_call_AIX, TOC[tc0], 0 + .csect .text[PR] +.ffi_call_AIX: + /* Save registers we use. */ + mflr r0 + + std r28,-32(r1) + std r29,-24(r1) + std r30,-16(r1) + std r31, -8(r1) + + std r0, 16(r1) + mr r28, r1 /* our AP. */ + stdux r1, r1, r4 + + /* Save arguments over call... */ + mr r31, r5 /* flags, */ + mr r30, r6 /* rvalue, */ + mr r29, r7 /* function address. */ + std r2, 40(r1) + + /* Call ffi_prep_args. */ + mr r4, r1 + bl .ffi_prep_args + nop + + /* Now do the call. */ + ld r0, 0(r29) + ld r2, 8(r29) + ld r11, 16(r29) + /* Set up cr1 with bits 4-7 of the flags. */ + mtcrf 0x40, r31 + mtctr r0 + /* Load all those argument registers. */ + /* We have set up a nice stack frame, just load it into registers. */ + ld r3, 40+(1*8)(r1) + ld r4, 40+(2*8)(r1) + ld r5, 40+(3*8)(r1) + ld r6, 40+(4*8)(r1) + nop + ld r7, 40+(5*8)(r1) + ld r8, 40+(6*8)(r1) + ld r9, 40+(7*8)(r1) + ld r10,40+(8*8)(r1) + +L1: + /* Load all the FP registers. */ + bf 6,L2 /* 2f + 0x18 */ + lfd f1,-32-(13*8)(r28) + lfd f2,-32-(12*8)(r28) + lfd f3,-32-(11*8)(r28) + lfd f4,-32-(10*8)(r28) + nop + lfd f5,-32-(9*8)(r28) + lfd f6,-32-(8*8)(r28) + lfd f7,-32-(7*8)(r28) + lfd f8,-32-(6*8)(r28) + nop + lfd f9,-32-(5*8)(r28) + lfd f10,-32-(4*8)(r28) + lfd f11,-32-(3*8)(r28) + lfd f12,-32-(2*8)(r28) + nop + lfd f13,-32-(1*8)(r28) + +L2: + /* Make the call. */ + bctrl + ld r2, 40(r1) + + /* Now, deal with the return value. */ + mtcrf 0x01, r31 + + bt 30, L(done_return_value) + bt 29, L(fp_return_value) + std r3, 0(r30) + + /* Fall through... */ + +L(done_return_value): + /* Restore the registers we used and return. */ + mr r1, r28 + ld r0, 16(r28) + ld r28, -32(r1) + mtlr r0 + ld r29, -24(r1) + ld r30, -16(r1) + ld r31, -8(r1) + blr + +L(fp_return_value): + bf 28, L(float_return_value) + stfd f1, 0(r30) + bf 31, L(done_return_value) + stfd f2, 8(r30) + b L(done_return_value) +L(float_return_value): + stfs f1, 0(r30) + b L(done_return_value) + +#else /* ! __64BIT__ */ + + .long .ffi_call_AIX, TOC[tc0], 0 + .csect .text[PR] +.ffi_call_AIX: + /* Save registers we use. */ + mflr r0 + + stw r28,-16(r1) + stw r29,-12(r1) + stw r30, -8(r1) + stw r31, -4(r1) + + stw r0, 8(r1) + mr r28, r1 /* out AP. */ + stwux r1, r1, r4 + + /* Save arguments over call... */ + mr r31, r5 /* flags, */ + mr r30, r6 /* rvalue, */ + mr r29, r7 /* function address, */ + stw r2, 20(r1) + + /* Call ffi_prep_args. */ + mr r4, r1 + bl .ffi_prep_args + nop + + /* Now do the call. */ + lwz r0, 0(r29) + lwz r2, 4(r29) + lwz r11, 8(r29) + /* Set up cr1 with bits 4-7 of the flags. */ + mtcrf 0x40, r31 + mtctr r0 + /* Load all those argument registers. */ + /* We have set up a nice stack frame, just load it into registers. */ + lwz r3, 20+(1*4)(r1) + lwz r4, 20+(2*4)(r1) + lwz r5, 20+(3*4)(r1) + lwz r6, 20+(4*4)(r1) + nop + lwz r7, 20+(5*4)(r1) + lwz r8, 20+(6*4)(r1) + lwz r9, 20+(7*4)(r1) + lwz r10,20+(8*4)(r1) + +L1: + /* Load all the FP registers. */ + bf 6,L2 /* 2f + 0x18 */ + lfd f1,-16-(13*8)(r28) + lfd f2,-16-(12*8)(r28) + lfd f3,-16-(11*8)(r28) + lfd f4,-16-(10*8)(r28) + nop + lfd f5,-16-(9*8)(r28) + lfd f6,-16-(8*8)(r28) + lfd f7,-16-(7*8)(r28) + lfd f8,-16-(6*8)(r28) + nop + lfd f9,-16-(5*8)(r28) + lfd f10,-16-(4*8)(r28) + lfd f11,-16-(3*8)(r28) + lfd f12,-16-(2*8)(r28) + nop + lfd f13,-16-(1*8)(r28) + +L2: + /* Make the call. */ + bctrl + lwz r2, 20(r1) + + /* Now, deal with the return value. */ + mtcrf 0x01, r31 + + bt 30, L(done_return_value) + bt 29, L(fp_return_value) + stw r3, 0(r30) + bf 28, L(done_return_value) + stw r4, 4(r30) + + /* Fall through... */ + +L(done_return_value): + /* Restore the registers we used and return. */ + mr r1, r28 + lwz r0, 8(r28) + lwz r28,-16(r1) + mtlr r0 + lwz r29,-12(r1) + lwz r30, -8(r1) + lwz r31, -4(r1) + blr + +L(fp_return_value): + bf 28, L(float_return_value) + stfd f1, 0(r30) + b L(done_return_value) +L(float_return_value): + stfs f1, 0(r30) + b L(done_return_value) +#endif + .long 0 + .byte 0,0,0,1,128,4,0,0 +/* END(ffi_call_AIX) */ + +.csect .text[PR] + .align 2 + .globl ffi_call_DARWIN + .globl .ffi_call_DARWIN +.csect ffi_call_DARWIN[DS] +ffi_call_DARWIN: +#ifdef __64BIT__ + .llong .ffi_call_DARWIN, TOC[tc0], 0 +#else + .long .ffi_call_DARWIN, TOC[tc0], 0 +#endif + .csect .text[PR] +.ffi_call_DARWIN: + blr + .long 0 + .byte 0,0,0,0,0,0,0,0 +/* END(ffi_call_DARWIN) */ diff --git a/circuitpython/lib/libffi/src/powerpc/aix_closure.S b/circuitpython/lib/libffi/src/powerpc/aix_closure.S new file mode 100644 index 0000000..aabd3c3 --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/aix_closure.S @@ -0,0 +1,447 @@ +/* ----------------------------------------------------------------------- + aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc. + based on darwin_closure.S + + PowerPC Assembly glue. + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + + .set r0,0 + .set r1,1 + .set r2,2 + .set r3,3 + .set r4,4 + .set r5,5 + .set r6,6 + .set r7,7 + .set r8,8 + .set r9,9 + .set r10,10 + .set r11,11 + .set r12,12 + .set r13,13 + .set r14,14 + .set r15,15 + .set r16,16 + .set r17,17 + .set r18,18 + .set r19,19 + .set r20,20 + .set r21,21 + .set r22,22 + .set r23,23 + .set r24,24 + .set r25,25 + .set r26,26 + .set r27,27 + .set r28,28 + .set r29,29 + .set r30,30 + .set r31,31 + .set f0,0 + .set f1,1 + .set f2,2 + .set f3,3 + .set f4,4 + .set f5,5 + .set f6,6 + .set f7,7 + .set f8,8 + .set f9,9 + .set f10,10 + .set f11,11 + .set f12,12 + .set f13,13 + .set f14,14 + .set f15,15 + .set f16,16 + .set f17,17 + .set f18,18 + .set f19,19 + .set f20,20 + .set f21,21 + + .extern .ffi_closure_helper_DARWIN + +#define LIBFFI_ASM +#define JUMPTARGET(name) name +#define L(x) x + .file "aix_closure.S" + .toc +LC..60: + .tc L..60[TC],L..60 + .csect .text[PR] + .align 2 + +.csect .text[PR] + .align 2 + .globl ffi_closure_ASM + .globl .ffi_closure_ASM +.csect ffi_closure_ASM[DS] +ffi_closure_ASM: +#ifdef __64BIT__ + .llong .ffi_closure_ASM, TOC[tc0], 0 + .csect .text[PR] +.ffi_closure_ASM: +/* we want to build up an area for the parameters passed */ +/* in registers (both floating point and integer) */ + + /* we store gpr 3 to gpr 10 (aligned to 4) + in the parents outgoing area */ + std r3, 48+(0*8)(r1) + std r4, 48+(1*8)(r1) + std r5, 48+(2*8)(r1) + std r6, 48+(3*8)(r1) + mflr r0 + + std r7, 48+(4*8)(r1) + std r8, 48+(5*8)(r1) + std r9, 48+(6*8)(r1) + std r10, 48+(7*8)(r1) + std r0, 16(r1) /* save the return address */ + + + /* 48 Bytes (Linkage Area) */ + /* 64 Bytes (params) */ + /* 16 Bytes (result) */ + /* 104 Bytes (13*8 from FPR) */ + /* 8 Bytes (alignment) */ + /* 240 Bytes */ + + stdu r1, -240(r1) /* skip over caller save area + keep stack aligned to 16 */ + + /* next save fpr 1 to fpr 13 (aligned to 8) */ + stfd f1, 128+(0*8)(r1) + stfd f2, 128+(1*8)(r1) + stfd f3, 128+(2*8)(r1) + stfd f4, 128+(3*8)(r1) + stfd f5, 128+(4*8)(r1) + stfd f6, 128+(5*8)(r1) + stfd f7, 128+(6*8)(r1) + stfd f8, 128+(7*8)(r1) + stfd f9, 128+(8*8)(r1) + stfd f10, 128+(9*8)(r1) + stfd f11, 128+(10*8)(r1) + stfd f12, 128+(11*8)(r1) + stfd f13, 128+(12*8)(r1) + + /* set up registers for the routine that actually does the work */ + /* get the context pointer from the trampoline */ + mr r3, r11 + + /* now load up the pointer to the result storage */ + addi r4, r1, 112 + + /* now load up the pointer to the saved gpr registers */ + addi r5, r1, 288 + + /* now load up the pointer to the saved fpr registers */ + addi r6, r1, 128 + + /* make the call */ + bl .ffi_closure_helper_DARWIN + nop + + /* now r3 contains the return type */ + /* so use it to look up in a table */ + /* so we know how to deal with each type */ + + /* look up the proper starting point in table */ + /* by using return type as offset */ + lhz r3, 10(r3) /* load type from return type */ + ld r4, LC..60(2) /* get address of jump table */ + sldi r3, r3, 4 /* now multiply return type by 16 */ + ld r0, 240+16(r1) /* load return address */ + add r3, r3, r4 /* add contents of table to table address */ + mtctr r3 + bctr /* jump to it */ + +/* Each fragment must be exactly 16 bytes long (4 instructions). + Align to 16 byte boundary for cache and dispatch efficiency. */ + .align 4 + +L..60: +/* case FFI_TYPE_VOID */ + mtlr r0 + addi r1, r1, 240 + blr + nop + +/* case FFI_TYPE_INT */ + lwa r3, 112+4(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_FLOAT */ + lfs f1, 112+0(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_DOUBLE */ + lfd f1, 112+0(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_LONGDOUBLE */ + lfd f1, 112+0(r1) + mtlr r0 + lfd f2, 112+8(r1) + b L..finish + +/* case FFI_TYPE_UINT8 */ + lbz r3, 112+7(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_SINT8 */ + lbz r3, 112+7(r1) + mtlr r0 + extsb r3, r3 + b L..finish + +/* case FFI_TYPE_UINT16 */ + lhz r3, 112+6(r1) + mtlr r0 +L..finish: + addi r1, r1, 240 + blr + +/* case FFI_TYPE_SINT16 */ + lha r3, 112+6(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_UINT32 */ + lwz r3, 112+4(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_SINT32 */ + lwa r3, 112+4(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_UINT64 */ + ld r3, 112+0(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_SINT64 */ + ld r3, 112+0(r1) + mtlr r0 + addi r1, r1, 240 + blr + +/* case FFI_TYPE_STRUCT */ + mtlr r0 + addi r1, r1, 240 + blr + nop + +/* case FFI_TYPE_POINTER */ + ld r3, 112+0(r1) + mtlr r0 + addi r1, r1, 240 + blr + +#else /* ! __64BIT__ */ + + .long .ffi_closure_ASM, TOC[tc0], 0 + .csect .text[PR] +.ffi_closure_ASM: +/* we want to build up an area for the parameters passed */ +/* in registers (both floating point and integer) */ + + /* we store gpr 3 to gpr 10 (aligned to 4) + in the parents outgoing area */ + stw r3, 24+(0*4)(r1) + stw r4, 24+(1*4)(r1) + stw r5, 24+(2*4)(r1) + stw r6, 24+(3*4)(r1) + mflr r0 + + stw r7, 24+(4*4)(r1) + stw r8, 24+(5*4)(r1) + stw r9, 24+(6*4)(r1) + stw r10, 24+(7*4)(r1) + stw r0, 8(r1) + + /* 24 Bytes (Linkage Area) */ + /* 32 Bytes (params) */ + /* 16 Bytes (result) */ + /* 104 Bytes (13*8 from FPR) */ + /* 176 Bytes */ + + stwu r1, -176(r1) /* skip over caller save area + keep stack aligned to 16 */ + + /* next save fpr 1 to fpr 13 (aligned to 8) */ + stfd f1, 72+(0*8)(r1) + stfd f2, 72+(1*8)(r1) + stfd f3, 72+(2*8)(r1) + stfd f4, 72+(3*8)(r1) + stfd f5, 72+(4*8)(r1) + stfd f6, 72+(5*8)(r1) + stfd f7, 72+(6*8)(r1) + stfd f8, 72+(7*8)(r1) + stfd f9, 72+(8*8)(r1) + stfd f10, 72+(9*8)(r1) + stfd f11, 72+(10*8)(r1) + stfd f12, 72+(11*8)(r1) + stfd f13, 72+(12*8)(r1) + + /* set up registers for the routine that actually does the work */ + /* get the context pointer from the trampoline */ + mr r3, r11 + + /* now load up the pointer to the result storage */ + addi r4, r1, 56 + + /* now load up the pointer to the saved gpr registers */ + addi r5, r1, 200 + + /* now load up the pointer to the saved fpr registers */ + addi r6, r1, 72 + + /* make the call */ + bl .ffi_closure_helper_DARWIN + nop + + /* now r3 contains the return type */ + /* so use it to look up in a table */ + /* so we know how to deal with each type */ + + /* look up the proper starting point in table */ + /* by using return type as offset */ + lhz r3, 6(r3) /* load type from return type */ + lwz r4, LC..60(2) /* get address of jump table */ + slwi r3, r3, 4 /* now multiply return type by 16 */ + lwz r0, 176+8(r1) /* load return address */ + add r3, r3, r4 /* add contents of table to table address */ + mtctr r3 + bctr /* jump to it */ + +/* Each fragment must be exactly 16 bytes long (4 instructions). + Align to 16 byte boundary for cache and dispatch efficiency. */ + .align 4 + +L..60: +/* case FFI_TYPE_VOID */ + mtlr r0 + addi r1, r1, 176 + blr + nop + +/* case FFI_TYPE_INT */ + lwz r3, 56+0(r1) + mtlr r0 + addi r1, r1, 176 + blr + +/* case FFI_TYPE_FLOAT */ + lfs f1, 56+0(r1) + mtlr r0 + addi r1, r1, 176 + blr + +/* case FFI_TYPE_DOUBLE */ + lfd f1, 56+0(r1) + mtlr r0 + addi r1, r1, 176 + blr + +/* case FFI_TYPE_LONGDOUBLE */ + lfd f1, 56+0(r1) + mtlr r0 + lfd f2, 56+8(r1) + b L..finish + +/* case FFI_TYPE_UINT8 */ + lbz r3, 56+3(r1) + mtlr r0 + addi r1, r1, 176 + blr + +/* case FFI_TYPE_SINT8 */ + lbz r3, 56+3(r1) + mtlr r0 + extsb r3, r3 + b L..finish + +/* case FFI_TYPE_UINT16 */ + lhz r3, 56+2(r1) + mtlr r0 + addi r1, r1, 176 + blr + +/* case FFI_TYPE_SINT16 */ + lha r3, 56+2(r1) + mtlr r0 + addi r1, r1, 176 + blr + +/* case FFI_TYPE_UINT32 */ + lwz r3, 56+0(r1) + mtlr r0 + addi r1, r1, 176 + blr + +/* case FFI_TYPE_SINT32 */ + lwz r3, 56+0(r1) + mtlr r0 + addi r1, r1, 176 + blr + +/* case FFI_TYPE_UINT64 */ + lwz r3, 56+0(r1) + mtlr r0 + lwz r4, 56+4(r1) + b L..finish + +/* case FFI_TYPE_SINT64 */ + lwz r3, 56+0(r1) + mtlr r0 + lwz r4, 56+4(r1) + b L..finish + +/* case FFI_TYPE_STRUCT */ + mtlr r0 + addi r1, r1, 176 + blr + nop + +/* case FFI_TYPE_POINTER */ + lwz r3, 56+0(r1) + mtlr r0 +L..finish: + addi r1, r1, 176 + blr +#endif +/* END(ffi_closure_ASM) */ diff --git a/circuitpython/lib/libffi/src/powerpc/asm.h b/circuitpython/lib/libffi/src/powerpc/asm.h new file mode 100644 index 0000000..994f62d --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/asm.h @@ -0,0 +1,125 @@ +/* ----------------------------------------------------------------------- + asm.h - Copyright (c) 1998 Geoffrey Keating + + PowerPC Assembly glue. + + 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 AUTHOR 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_GLOBAL_DIRECTIVE .globl + + +#define C_SYMBOL_NAME(name) name +/* Macro for a label. */ +#ifdef __STDC__ +#define C_LABEL(name) name##: +#else +#define C_LABEL(name) name/**/: +#endif + +/* This seems to always be the case on PPC. */ +#define ALIGNARG(log2) log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +/* If compiled for profiling, call `_mcount' at the start of each function. */ +#ifdef PROF +/* The mcount code relies on the return address being on the stack + to locate our caller and so it can restore it; so store one just + for its benefit. */ +#ifdef PIC +#define CALL_MCOUNT \ + .pushsection; \ + .section ".data"; \ + .align ALIGNARG(2); \ +0:.long 0; \ + .previous; \ + mflr %r0; \ + stw %r0,4(%r1); \ + bl _GLOBAL_OFFSET_TABLE_@local-4; \ + mflr %r11; \ + lwz %r0,0b@got(%r11); \ + bl JUMPTARGET(_mcount); +#else /* PIC */ +#define CALL_MCOUNT \ + .section ".data"; \ + .align ALIGNARG(2); \ +0:.long 0; \ + .previous; \ + mflr %r0; \ + lis %r11,0b@ha; \ + stw %r0,4(%r1); \ + addi %r0,%r11,0b@l; \ + bl JUMPTARGET(_mcount); +#endif /* PIC */ +#else /* PROF */ +#define CALL_MCOUNT /* Do nothing. */ +#endif /* PROF */ + +#define ENTRY(name) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ + .align ALIGNARG(2); \ + C_LABEL(name) \ + CALL_MCOUNT + +#define EALIGN_W_0 /* No words to insert. */ +#define EALIGN_W_1 nop +#define EALIGN_W_2 nop;nop +#define EALIGN_W_3 nop;nop;nop +#define EALIGN_W_4 EALIGN_W_3;nop +#define EALIGN_W_5 EALIGN_W_4;nop +#define EALIGN_W_6 EALIGN_W_5;nop +#define EALIGN_W_7 EALIGN_W_6;nop + +/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes + past a 2^align boundary. */ +#ifdef PROF +#define EALIGN(name, alignt, words) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ + .align ALIGNARG(2); \ + C_LABEL(name) \ + CALL_MCOUNT \ + b 0f; \ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + 0: +#else /* PROF */ +#define EALIGN(name, alignt, words) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + C_LABEL(name) +#endif + +#define END(name) \ + ASM_SIZE_DIRECTIVE(name) + +#ifdef PIC +#define JUMPTARGET(name) name##@plt +#else +#define JUMPTARGET(name) name +#endif + +/* Local labels stripped out by the linker. */ +#define L(x) .L##x diff --git a/circuitpython/lib/libffi/src/powerpc/darwin.S b/circuitpython/lib/libffi/src/powerpc/darwin.S new file mode 100644 index 0000000..066eb82 --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/darwin.S @@ -0,0 +1,378 @@ +/* ----------------------------------------------------------------------- + darwin.S - Copyright (c) 2000 John Hornkvist + Copyright (c) 2004, 2010 Free Software Foundation, Inc. + + PowerPC Assembly glue. + + 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 AUTHOR 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 LIBFFI_ASM +#if defined(__ppc64__) +#define MODE_CHOICE(x, y) y +#else +#define MODE_CHOICE(x, y) x +#endif + +#define machine_choice MODE_CHOICE(ppc7400,ppc64) + +; Define some pseudo-opcodes for size-independent load & store of GPRs ... +#define lgu MODE_CHOICE(lwzu, ldu) +#define lg MODE_CHOICE(lwz,ld) +#define sg MODE_CHOICE(stw,std) +#define sgu MODE_CHOICE(stwu,stdu) +#define sgux MODE_CHOICE(stwux,stdux) + +; ... and the size of GPRs and their storage indicator. +#define GPR_BYTES MODE_CHOICE(4,8) +#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ +#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ + +; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04. +#define LINKAGE_SIZE MODE_CHOICE(24,48) +#define PARAM_AREA MODE_CHOICE(32,64) +#define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */ + +/* If there is any FP stuff we make space for all of the regs. */ +#define SAVED_FPR_COUNT 13 +#define FPR_SIZE 8 +#define RESULT_BYTES 16 + +/* This should be kept in step with the same value in ffi_darwin.c. */ +#define ASM_NEEDS_REGISTERS 4 +#define SAVE_REGS_SIZE (ASM_NEEDS_REGISTERS * GPR_BYTES) + +#include +#include + +#define JUMPTARGET(name) name +#define L(x) x + + .text + .align 2 + .globl _ffi_prep_args + + .align 2 + .globl _ffi_call_DARWIN + + /* We arrive here with: + r3 = ptr to extended cif. + r4 = -bytes. + r5 = cif flags. + r6 = ptr to return value. + r7 = fn pointer (user func). + r8 = fn pointer (ffi_prep_args). + r9 = ffi_type* for the ret val. */ + +_ffi_call_DARWIN: +Lstartcode: + mr r12,r8 /* We only need r12 until the call, + so it does not have to be saved. */ +LFB1: + /* Save the old stack pointer as AP. */ + mr r8,r1 +LCFI0: + + /* Save the retval type in parents frame. */ + sg r9,(LINKAGE_SIZE+6*GPR_BYTES)(r8) + + /* Allocate the stack space we need. */ + sgux r1,r1,r4 + + /* Save registers we use. */ + mflr r9 + sg r9,SAVED_LR_OFFSET(r8) + + sg r28,-(4 * GPR_BYTES)(r8) + sg r29,-(3 * GPR_BYTES)(r8) + sg r30,-(2 * GPR_BYTES)(r8) + sg r31,-( GPR_BYTES)(r8) + +#if !defined(POWERPC_DARWIN) + /* The TOC slot is reserved in the Darwin ABI and r2 is volatile. */ + sg r2,(5 * GPR_BYTES)(r1) +#endif + +LCFI1: + + /* Save arguments over call. */ + mr r31,r5 /* flags, */ + mr r30,r6 /* rvalue, */ + mr r29,r7 /* function address, */ + mr r28,r8 /* our AP. */ +LCFI2: + /* Call ffi_prep_args. r3 = extended cif, r4 = stack ptr copy. */ + mr r4,r1 + li r9,0 + + mtctr r12 /* r12 holds address of _ffi_prep_args. */ + bctrl + +#if !defined(POWERPC_DARWIN) + /* The TOC slot is reserved in the Darwin ABI and r2 is volatile. */ + lg r2,(5 * GPR_BYTES)(r1) +#endif + /* Now do the call. + Set up cr1 with bits 4-7 of the flags. */ + mtcrf 0x40,r31 + /* Get the address to call into CTR. */ + mtctr r29 + /* Load all those argument registers. + We have set up a nice stack frame, just load it into registers. */ + lg r3, (LINKAGE_SIZE )(r1) + lg r4, (LINKAGE_SIZE + GPR_BYTES)(r1) + lg r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r1) + lg r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r1) + nop + lg r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r1) + lg r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r1) + lg r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r1) + lg r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r1) + +L1: + /* ... Load all the FP registers. */ + bf 6,L2 /* No floats to load. */ + lfd f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28) + lfd f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28) + lfd f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28) + lfd f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28) + nop + lfd f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28) + lfd f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28) + lfd f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28) + lfd f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28) + nop + lfd f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28) + lfd f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28) + lfd f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28) + lfd f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28) + nop + lfd f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28) + +L2: + mr r12,r29 /* Put the target address in r12 as specified. */ + mtctr r12 + nop + nop + + /* Make the call. */ + bctrl + + /* Now, deal with the return value. */ + + /* m64 structure returns can occupy the same set of registers as + would be used to pass such a structure as arg0 - so take care + not to step on any possibly hot regs. */ + + /* Get the flags.. */ + mtcrf 0x03,r31 ; we need c6 & cr7 now. + ; FLAG_RETURNS_NOTHING also covers struct ret-by-ref. + bt 30,L(done_return_value) ; FLAG_RETURNS_NOTHING + bf 27,L(scalar_return_value) ; not FLAG_RETURNS_STRUCT + + /* OK, so we have a struct. */ +#if defined(__ppc64__) + bt 31,L(maybe_return_128) ; FLAG_RETURNS_128BITS, special case + + /* OK, we have to map the return back to a mem struct. + We are about to trample the parents param area, so recover the + return type. r29 is free, since the call is done. */ + lg r29,(LINKAGE_SIZE + 6 * GPR_BYTES)(r28) + + sg r3, (LINKAGE_SIZE )(r28) + sg r4, (LINKAGE_SIZE + GPR_BYTES)(r28) + sg r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r28) + sg r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r28) + nop + sg r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r28) + sg r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r28) + sg r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r28) + sg r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28) + /* OK, so do the block move - we trust that memcpy will not trample + the fprs... */ + mr r3,r30 ; dest + addi r4,r28,LINKAGE_SIZE ; source + /* The size is a size_t, should be long. */ + lg r5,0(r29) + /* Figure out small structs */ + cmpi 0,r5,4 + bgt L3 ; 1, 2 and 4 bytes have special rules. + cmpi 0,r5,3 + beq L3 ; not 3 + addi r4,r4,8 + subf r4,r5,r4 +L3: + bl _memcpy + + /* ... do we need the FP registers? - recover the flags.. */ + mtcrf 0x03,r31 ; we need c6 & cr7 now. + bf 29,L(done_return_value) /* No floats in the struct. */ + stfd f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28) + stfd f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28) + stfd f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28) + stfd f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28) + nop + stfd f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28) + stfd f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28) + stfd f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28) + stfd f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28) + nop + stfd f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28) + stfd f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28) + stfd f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28) + stfd f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28) + nop + stfd f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28) + + mr r3,r29 ; ffi_type * + mr r4,r30 ; dest + addi r5,r28,-SAVE_REGS_SIZE-(13*FPR_SIZE) ; fprs + xor r6,r6,r6 + sg r6,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28) + addi r6,r28,(LINKAGE_SIZE + 7 * GPR_BYTES) ; point to a zeroed counter. + bl _darwin64_struct_floats_to_mem + + b L(done_return_value) +#else + stw r3,0(r30) ; m32 the only struct return in reg is 4 bytes. +#endif + b L(done_return_value) + +L(fp_return_value): + /* Do we have long double to store? */ + bf 31,L(fd_return_value) ; FLAG_RETURNS_128BITS + stfd f1,0(r30) + stfd f2,FPR_SIZE(r30) + b L(done_return_value) + +L(fd_return_value): + /* Do we have double to store? */ + bf 28,L(float_return_value) + stfd f1,0(r30) + b L(done_return_value) + +L(float_return_value): + /* We only have a float to store. */ + stfs f1,0(r30) + b L(done_return_value) + +L(scalar_return_value): + bt 29,L(fp_return_value) ; FLAG_RETURNS_FP + ; ffi_arg is defined as unsigned long. + sg r3,0(r30) ; Save the reg. + bf 28,L(done_return_value) ; not FLAG_RETURNS_64BITS + +#if defined(__ppc64__) +L(maybe_return_128): + std r3,0(r30) + bf 31,L(done_return_value) ; not FLAG_RETURNS_128BITS + std r4,8(r30) +#else + stw r4,4(r30) +#endif + + /* Fall through. */ + /* We want this at the end to simplify eh epilog computation. */ + +L(done_return_value): + /* Restore the registers we used and return. */ + lg r29,SAVED_LR_OFFSET(r28) + ; epilog + lg r31,-(1 * GPR_BYTES)(r28) + mtlr r29 + lg r30,-(2 * GPR_BYTES)(r28) + lg r29,-(3 * GPR_BYTES)(r28) + lg r28,-(4 * GPR_BYTES)(r28) + lg r1,0(r1) + blr +LFE1: + .align 1 +/* END(_ffi_call_DARWIN) */ + +/* Provide a null definition of _ffi_call_AIX. */ + .text + .globl _ffi_call_AIX + .align 2 +_ffi_call_AIX: + blr +/* END(_ffi_call_AIX) */ + +/* EH stuff. */ + +#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78) + + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 ; Length of Common Information Entry +LSCIE1: + .long 0x0 ; CIE Identifier Tag + .byte 0x1 ; CIE Version + .ascii "zR\0" ; CIE Augmentation + .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor + .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor + .byte 0x41 ; CIE RA Column + .byte 0x1 ; uleb128 0x1; Augmentation size + .byte 0x10 ; FDE Encoding (pcrel) + .byte 0xc ; DW_CFA_def_cfa + .byte 0x1 ; uleb128 0x1 + .byte 0x0 ; uleb128 0x0 + .align LOG2_GPR_BYTES +LECIE1: + + .globl _ffi_call_DARWIN.eh +_ffi_call_DARWIN.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 ; FDE Length +LASFDE1: + .long LASFDE1-EH_frame1 ; FDE CIE offset + .g_long Lstartcode-. ; FDE initial location + .set L$set$3,LFE1-Lstartcode + .g_long L$set$3 ; FDE address range + .byte 0x0 ; uleb128 0x0; Augmentation size + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$4,LCFI0-Lstartcode + .long L$set$4 + .byte 0xd ; DW_CFA_def_cfa_register + .byte 0x08 ; uleb128 0x08 + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$5,LCFI1-LCFI0 + .long L$set$5 + .byte 0x11 ; DW_CFA_offset_extended_sf + .byte 0x41 ; uleb128 0x41 + .byte 0x7e ; sleb128 -2 + .byte 0x9f ; DW_CFA_offset, column 0x1f + .byte 0x1 ; uleb128 0x1 + .byte 0x9e ; DW_CFA_offset, column 0x1e + .byte 0x2 ; uleb128 0x2 + .byte 0x9d ; DW_CFA_offset, column 0x1d + .byte 0x3 ; uleb128 0x3 + .byte 0x9c ; DW_CFA_offset, column 0x1c + .byte 0x4 ; uleb128 0x4 + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$6,LCFI2-LCFI1 + .long L$set$6 + .byte 0xd ; DW_CFA_def_cfa_register + .byte 0x1c ; uleb128 0x1c + .align LOG2_GPR_BYTES +LEFDE1: + .align 1 + diff --git a/circuitpython/lib/libffi/src/powerpc/darwin_closure.S b/circuitpython/lib/libffi/src/powerpc/darwin_closure.S new file mode 100644 index 0000000..c7734d4 --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/darwin_closure.S @@ -0,0 +1,571 @@ +/* ----------------------------------------------------------------------- + darwin_closure.S - Copyright (c) 2002, 2003, 2004, 2010, + Free Software Foundation, Inc. + based on ppc_closure.S + + PowerPC Assembly glue. + + 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 AUTHOR 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 LIBFFI_ASM +#define L(x) x + +#if defined(__ppc64__) +#define MODE_CHOICE(x, y) y +#else +#define MODE_CHOICE(x, y) x +#endif + +#define machine_choice MODE_CHOICE(ppc7400,ppc64) + +; Define some pseudo-opcodes for size-independent load & store of GPRs ... +#define lgu MODE_CHOICE(lwzu, ldu) +#define lg MODE_CHOICE(lwz,ld) +#define sg MODE_CHOICE(stw,std) +#define sgu MODE_CHOICE(stwu,stdu) + +; ... and the size of GPRs and their storage indicator. +#define GPR_BYTES MODE_CHOICE(4,8) +#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ +#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ + +; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04. +#define LINKAGE_SIZE MODE_CHOICE(24,48) +#define PARAM_AREA MODE_CHOICE(32,64) + +#define SAVED_CR_OFFSET MODE_CHOICE(4,8) /* save position for CR */ +#define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */ + +/* WARNING: if ffi_type is changed... here be monsters. + Offsets of items within the result type. */ +#define FFI_TYPE_TYPE MODE_CHOICE(6,10) +#define FFI_TYPE_ELEM MODE_CHOICE(8,16) + +#define SAVED_FPR_COUNT 13 +#define FPR_SIZE 8 +/* biggest m64 struct ret is 8GPRS + 13FPRS = 168 bytes - rounded to 16bytes = 176. */ +#define RESULT_BYTES MODE_CHOICE(16,176) + +; The whole stack frame **MUST** be 16byte-aligned. +#define SAVE_SIZE (((LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES)+15) & -16LL) +#define PAD_SIZE (SAVE_SIZE-(LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES)) + +#define PARENT_PARM_BASE (SAVE_SIZE+LINKAGE_SIZE) +#define FP_SAVE_BASE (LINKAGE_SIZE+PARAM_AREA) + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 +; We no longer need the pic symbol stub for Darwin >= 9. +#define BLCLS_HELP _ffi_closure_helper_DARWIN +#define STRUCT_RETVALUE_P _darwin64_struct_ret_by_value_p +#define PASS_STR_FLOATS _darwin64_pass_struct_floats +#undef WANT_STUB +#else +#define BLCLS_HELP L_ffi_closure_helper_DARWIN$stub +#define STRUCT_RETVALUE_P L_darwin64_struct_ret_by_value_p$stub +#define PASS_STR_FLOATS L_darwin64_pass_struct_floats$stub +#define WANT_STUB +#endif + +/* m32/m64 + + The stack layout looks like this: + + | Additional params... | | Higher address + ~ ~ ~ + | Parameters (at least 8*4/8=32/64) | | NUM_GPR_ARG_REGISTERS + |--------------------------------------------| | + | TOC=R2 (AIX) Reserved (Darwin) 4/8 | | + |--------------------------------------------| | + | Reserved 2*4/8 | | + |--------------------------------------------| | + | Space for callee`s LR 4/8 | | + |--------------------------------------------| | + | Saved CR [low word for m64] 4/8 | | + |--------------------------------------------| | + | Current backchain pointer 4/8 |-/ Parent`s frame. + |--------------------------------------------| <+ <<< on entry to + | Result Bytes 16/176 | | + |--------------------------------------------| | + ~ padding to 16-byte alignment ~ ~ + |--------------------------------------------| | + | NUM_FPR_ARG_REGISTERS slots | | + | here fp13 .. fp1 13*8 | | + |--------------------------------------------| | + | R3..R10 8*4/8=32/64 | | NUM_GPR_ARG_REGISTERS + |--------------------------------------------| | + | TOC=R2 (AIX) Reserved (Darwin) 4/8 | | + |--------------------------------------------| | stack | + | Reserved [compiler,binder] 2*4/8 | | grows | + |--------------------------------------------| | down V + | Space for callees LR 4/8 | | + |--------------------------------------------| | lower addresses + | Saved CR [low word for m64] 4/8 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 4/8 |-/ during + |--------------------------------------------| <<< call. + +*/ + + .file "darwin_closure.S" + + .machine machine_choice + + .text + .globl _ffi_closure_ASM + .align LOG2_GPR_BYTES +_ffi_closure_ASM: +LFB1: +Lstartcode: + mflr r0 /* extract return address */ + sg r0,SAVED_LR_OFFSET(r1) /* save the return address */ +LCFI0: + sgu r1,-SAVE_SIZE(r1) /* skip over caller save area + keep stack aligned to 16. */ +LCFI1: + /* We want to build up an area for the parameters passed + in registers. (both floating point and integer) */ + + /* Put gpr 3 to gpr 10 in the parents outgoing area... + ... the remainder of any params that overflowed the regs will + follow here. */ + sg r3, (PARENT_PARM_BASE )(r1) + sg r4, (PARENT_PARM_BASE + GPR_BYTES )(r1) + sg r5, (PARENT_PARM_BASE + GPR_BYTES * 2)(r1) + sg r6, (PARENT_PARM_BASE + GPR_BYTES * 3)(r1) + sg r7, (PARENT_PARM_BASE + GPR_BYTES * 4)(r1) + sg r8, (PARENT_PARM_BASE + GPR_BYTES * 5)(r1) + sg r9, (PARENT_PARM_BASE + GPR_BYTES * 6)(r1) + sg r10,(PARENT_PARM_BASE + GPR_BYTES * 7)(r1) + + /* We save fpr 1 to fpr 14 in our own save frame. */ + stfd f1, (FP_SAVE_BASE )(r1) + stfd f2, (FP_SAVE_BASE + FPR_SIZE )(r1) + stfd f3, (FP_SAVE_BASE + FPR_SIZE * 2 )(r1) + stfd f4, (FP_SAVE_BASE + FPR_SIZE * 3 )(r1) + stfd f5, (FP_SAVE_BASE + FPR_SIZE * 4 )(r1) + stfd f6, (FP_SAVE_BASE + FPR_SIZE * 5 )(r1) + stfd f7, (FP_SAVE_BASE + FPR_SIZE * 6 )(r1) + stfd f8, (FP_SAVE_BASE + FPR_SIZE * 7 )(r1) + stfd f9, (FP_SAVE_BASE + FPR_SIZE * 8 )(r1) + stfd f10,(FP_SAVE_BASE + FPR_SIZE * 9 )(r1) + stfd f11,(FP_SAVE_BASE + FPR_SIZE * 10)(r1) + stfd f12,(FP_SAVE_BASE + FPR_SIZE * 11)(r1) + stfd f13,(FP_SAVE_BASE + FPR_SIZE * 12)(r1) + + /* Set up registers for the routine that actually does the work + get the context pointer from the trampoline. */ + mr r3,r11 + + /* Now load up the pointer to the result storage. */ + addi r4,r1,(SAVE_SIZE-RESULT_BYTES) + + /* Now load up the pointer to the saved gpr registers. */ + addi r5,r1,PARENT_PARM_BASE + + /* Now load up the pointer to the saved fpr registers. */ + addi r6,r1,FP_SAVE_BASE + + /* Make the call. */ + bl BLCLS_HELP + + /* r3 contains the rtype pointer... save it since we will need + it later. */ + sg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type + lg r0,0(r3) ; size => r0 + lhz r3,FFI_TYPE_TYPE(r3) ; type => r3 + + /* The helper will have intercepted structure returns and inserted + the caller`s destination address for structs returned by ref. */ + + /* r3 contains the return type so use it to look up in a table + so we know how to deal with each type. */ + + addi r5,r1,(SAVE_SIZE-RESULT_BYTES) /* Otherwise, our return is here. */ + bl Lget_ret_type0_addr /* Get pointer to Lret_type0 into LR. */ + mflr r4 /* Move to r4. */ + slwi r3,r3,4 /* Now multiply return type by 16. */ + add r3,r3,r4 /* Add contents of table to table address. */ + mtctr r3 + bctr /* Jump to it. */ +LFE1: +/* Each of the ret_typeX code fragments has to be exactly 16 bytes long + (4 instructions). For cache effectiveness we align to a 16 byte boundary + first. */ + + .align 4 + + nop + nop + nop +Lget_ret_type0_addr: + blrl + +/* case FFI_TYPE_VOID */ +Lret_type0: + b Lfinish + nop + nop + nop + +/* case FFI_TYPE_INT */ +Lret_type1: + lg r3,0(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_FLOAT */ +Lret_type2: + lfs f1,0(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_DOUBLE */ +Lret_type3: + lfd f1,0(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_LONGDOUBLE */ +Lret_type4: + lfd f1,0(r5) + lfd f2,8(r5) + b Lfinish + nop + +/* case FFI_TYPE_UINT8 */ +Lret_type5: +#if defined(__ppc64__) + lbz r3,7(r5) +#else + lbz r3,3(r5) +#endif + b Lfinish + nop + nop + +/* case FFI_TYPE_SINT8 */ +Lret_type6: +#if defined(__ppc64__) + lbz r3,7(r5) +#else + lbz r3,3(r5) +#endif + extsb r3,r3 + b Lfinish + nop + +/* case FFI_TYPE_UINT16 */ +Lret_type7: +#if defined(__ppc64__) + lhz r3,6(r5) +#else + lhz r3,2(r5) +#endif + b Lfinish + nop + nop + +/* case FFI_TYPE_SINT16 */ +Lret_type8: +#if defined(__ppc64__) + lha r3,6(r5) +#else + lha r3,2(r5) +#endif + b Lfinish + nop + nop + +/* case FFI_TYPE_UINT32 */ +Lret_type9: +#if defined(__ppc64__) + lwz r3,4(r5) +#else + lwz r3,0(r5) +#endif + b Lfinish + nop + nop + +/* case FFI_TYPE_SINT32 */ +Lret_type10: +#if defined(__ppc64__) + lwz r3,4(r5) +#else + lwz r3,0(r5) +#endif + b Lfinish + nop + nop + +/* case FFI_TYPE_UINT64 */ +Lret_type11: +#if defined(__ppc64__) + lg r3,0(r5) + b Lfinish + nop +#else + lwz r3,0(r5) + lwz r4,4(r5) + b Lfinish +#endif + nop + +/* case FFI_TYPE_SINT64 */ +Lret_type12: +#if defined(__ppc64__) + lg r3,0(r5) + b Lfinish + nop +#else + lwz r3,0(r5) + lwz r4,4(r5) + b Lfinish +#endif + nop + +/* case FFI_TYPE_STRUCT */ +Lret_type13: +#if defined(__ppc64__) + lg r3,0(r5) ; we need at least this... + cmpi 0,r0,4 + bgt Lstructend ; not a special small case + b Lsmallstruct ; see if we need more. +#else + cmpi 0,r0,4 + bgt Lfinish ; not by value + lg r3,0(r5) + b Lfinish +#endif +/* case FFI_TYPE_POINTER */ +Lret_type14: + lg r3,0(r5) + b Lfinish + nop + nop + +#if defined(__ppc64__) +Lsmallstruct: + beq Lfour ; continuation of Lret13. + cmpi 0,r0,3 + beq Lfinish ; don`t adjust this - can`t be any floats here... + srdi r3,r3,48 + cmpi 0,r0,2 + beq Lfinish ; .. or here .. + srdi r3,r3,8 + b Lfinish ; .. or here. + +Lfour: + lg r6,LINKAGE_SIZE(r1) ; get the result type + lg r6,FFI_TYPE_ELEM(r6) ; elements array pointer + lg r6,0(r6) ; first element + lhz r0,FFI_TYPE_TYPE(r6) ; OK go the type + cmpi 0,r0,2 ; FFI_TYPE_FLOAT + bne Lfourint + lfs f1,0(r5) ; just one float in the struct. + b Lfinish + +Lfourint: + srdi r3,r3,32 ; four bytes. + b Lfinish + +Lstructend: + lg r3,LINKAGE_SIZE(r1) ; get the result type + bl STRUCT_RETVALUE_P + cmpi 0,r3,0 + beq Lfinish ; nope. + /* Recover a pointer to the results. */ + addi r11,r1,(SAVE_SIZE-RESULT_BYTES) + lg r3,0(r11) ; we need at least this... + lg r4,8(r11) + cmpi 0,r0,16 + beq Lfinish ; special case 16 bytes we don't consider floats. + + /* OK, frustratingly, the process of saving the struct to mem might have + messed with the FPRs, so we have to re-load them :(. + We`ll use our FPRs space again - calling: + void darwin64_pass_struct_floats (ffi_type *s, char *src, + unsigned *nfpr, double **fprs) + We`ll temporarily pinch the first two slots of the param area for local + vars used by the routine. */ + xor r6,r6,r6 + addi r5,r1,PARENT_PARM_BASE ; some space + sg r6,0(r5) ; *nfpr zeroed. + addi r6,r5,8 ; **fprs + addi r3,r1,FP_SAVE_BASE ; pointer to FPRs space + sg r3,0(r6) + mr r4,r11 ; the struct is here... + lg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type. + bl PASS_STR_FLOATS ; get struct floats into FPR save space. + /* See if we used any floats */ + lwz r0,(SAVE_SIZE-RESULT_BYTES)(r1) + cmpi 0,r0,0 + beq Lstructints ; nope. + /* OK load `em up... */ + lfd f1, (FP_SAVE_BASE )(r1) + lfd f2, (FP_SAVE_BASE + FPR_SIZE )(r1) + lfd f3, (FP_SAVE_BASE + FPR_SIZE * 2 )(r1) + lfd f4, (FP_SAVE_BASE + FPR_SIZE * 3 )(r1) + lfd f5, (FP_SAVE_BASE + FPR_SIZE * 4 )(r1) + lfd f6, (FP_SAVE_BASE + FPR_SIZE * 5 )(r1) + lfd f7, (FP_SAVE_BASE + FPR_SIZE * 6 )(r1) + lfd f8, (FP_SAVE_BASE + FPR_SIZE * 7 )(r1) + lfd f9, (FP_SAVE_BASE + FPR_SIZE * 8 )(r1) + lfd f10,(FP_SAVE_BASE + FPR_SIZE * 9 )(r1) + lfd f11,(FP_SAVE_BASE + FPR_SIZE * 10)(r1) + lfd f12,(FP_SAVE_BASE + FPR_SIZE * 11)(r1) + lfd f13,(FP_SAVE_BASE + FPR_SIZE * 12)(r1) + + /* point back at our saved struct. */ +Lstructints: + addi r11,r1,(SAVE_SIZE-RESULT_BYTES) + lg r3,0(r11) ; we end up picking the + lg r4,8(r11) ; first two again. + lg r5,16(r11) + lg r6,24(r11) + lg r7,32(r11) + lg r8,40(r11) + lg r9,48(r11) + lg r10,56(r11) +#endif + +/* case done */ +Lfinish: + addi r1,r1,SAVE_SIZE /* Restore stack pointer. */ + lg r0,SAVED_LR_OFFSET(r1) /* Get return address. */ + mtlr r0 /* Reset link register. */ + blr +Lendcode: + .align 1 + +/* END(ffi_closure_ASM) */ + +/* EH frame stuff. */ +#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78) +/* 176, 400 */ +#define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90) +#define EH_FRAME_OFFSETB MODE_CHOICE(1,3) + + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 ; Length of Common Information Entry +LSCIE1: + .long 0x0 ; CIE Identifier Tag + .byte 0x1 ; CIE Version + .ascii "zR\0" ; CIE Augmentation + .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor + .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor + .byte 0x41 ; CIE RA Column + .byte 0x1 ; uleb128 0x1; Augmentation size + .byte 0x10 ; FDE Encoding (pcrel) + .byte 0xc ; DW_CFA_def_cfa + .byte 0x1 ; uleb128 0x1 + .byte 0x0 ; uleb128 0x0 + .align LOG2_GPR_BYTES +LECIE1: + .globl _ffi_closure_ASM.eh +_ffi_closure_ASM.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 ; FDE Length + +LASFDE1: + .long LASFDE1-EH_frame1 ; FDE CIE offset + .g_long Lstartcode-. ; FDE initial location + .set L$set$3,LFE1-Lstartcode + .g_long L$set$3 ; FDE address range + .byte 0x0 ; uleb128 0x0; Augmentation size + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$3,LCFI1-LCFI0 + .long L$set$3 + .byte 0xe ; DW_CFA_def_cfa_offset + .byte EH_FRAME_OFFSETA,EH_FRAME_OFFSETB ; uleb128 176,1/190,3 + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$4,LCFI0-Lstartcode + .long L$set$4 + .byte 0x11 ; DW_CFA_offset_extended_sf + .byte 0x41 ; uleb128 0x41 + .byte 0x7e ; sleb128 -2 + .align LOG2_GPR_BYTES +LEFDE1: + .align 1 + +#ifdef WANT_STUB + .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align 5 +L_ffi_closure_helper_DARWIN$stub: + .indirect_symbol _ffi_closure_helper_DARWIN + mflr r0 + bcl 20,31,"L1$spb" +"L1$spb": + mflr r11 + addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb") + mtlr r0 + lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")(r11) + mtctr r12 + bctr + .lazy_symbol_pointer +L_ffi_closure_helper_DARWIN$lazy_ptr: + .indirect_symbol _ffi_closure_helper_DARWIN + .g_long dyld_stub_binding_helper + +#if defined(__ppc64__) + .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align 5 +L_darwin64_struct_ret_by_value_p$stub: + .indirect_symbol _darwin64_struct_ret_by_value_p + mflr r0 + bcl 20,31,"L2$spb" +"L2$spb": + mflr r11 + addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb") + mtlr r0 + lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")(r11) + mtctr r12 + bctr + .lazy_symbol_pointer +L_darwin64_struct_ret_by_value_p$lazy_ptr: + .indirect_symbol _darwin64_struct_ret_by_value_p + .g_long dyld_stub_binding_helper + + .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align 5 +L_darwin64_pass_struct_floats$stub: + .indirect_symbol _darwin64_pass_struct_floats + mflr r0 + bcl 20,31,"L3$spb" +"L3$spb": + mflr r11 + addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb") + mtlr r0 + lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")(r11) + mtctr r12 + bctr + .lazy_symbol_pointer +L_darwin64_pass_struct_floats$lazy_ptr: + .indirect_symbol _darwin64_pass_struct_floats + .g_long dyld_stub_binding_helper +# endif +#endif diff --git a/circuitpython/lib/libffi/src/powerpc/ffi.c b/circuitpython/lib/libffi/src/powerpc/ffi.c new file mode 100644 index 0000000..7eb543e --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/ffi.c @@ -0,0 +1,173 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC Foreign Function Interface + + 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 AUTHOR 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 "ffi.h" +#include "ffi_common.h" +#include "ffi_powerpc.h" + +#if HAVE_LONG_DOUBLE_VARIANT +/* Adjust ffi_type_longdouble. */ +void FFI_HIDDEN +ffi_prep_types (ffi_abi abi) +{ +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +# ifdef POWERPC64 + ffi_prep_types_linux64 (abi); +# else + ffi_prep_types_sysv (abi); +# endif +# endif +} +#endif + +/* Perform machine dependent cif processing */ +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep (ffi_cif *cif) +{ +#ifdef POWERPC64 + return ffi_prep_cif_linux64 (cif); +#else + return ffi_prep_cif_sysv (cif); +#endif +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep_var (ffi_cif *cif, + unsigned int nfixedargs MAYBE_UNUSED, + unsigned int ntotalargs MAYBE_UNUSED) +{ +#ifdef POWERPC64 + return ffi_prep_cif_linux64_var (cif, nfixedargs, ntotalargs); +#else + return ffi_prep_cif_sysv (cif); +#endif +} + +static void +ffi_call_int (ffi_cif *cif, + void (*fn) (void), + void *rvalue, + void **avalue, + void *closure) +{ + /* The final SYSV ABI says that structures smaller or equal 8 bytes + are returned in r3/r4. A draft ABI used by linux instead returns + them in memory. + + We bounce-buffer SYSV small struct return values so that sysv.S + can write r3 and r4 to memory without worrying about struct size. + + For ELFv2 ABI, use a bounce buffer for homogeneous structs too, + for similar reasons. */ + unsigned long smst_buffer[8]; + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + ecif.rvalue = rvalue; + if ((cif->flags & FLAG_RETURNS_SMST) != 0) + ecif.rvalue = smst_buffer; + /* Ensure that we have a valid struct return value. + FIXME: Isn't this just papering over a user problem? */ + else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT) + ecif.rvalue = alloca (cif->rtype->size); + +#ifdef POWERPC64 + ffi_call_LINUX64 (&ecif, fn, ecif.rvalue, cif->flags, closure, + -(long) cif->bytes); +#else + ffi_call_SYSV (&ecif, fn, ecif.rvalue, cif->flags, closure, -cif->bytes); +#endif + + /* Check for a bounce-buffered return value */ + if (rvalue && ecif.rvalue == smst_buffer) + { + unsigned int rsize = cif->rtype->size; +#ifndef __LITTLE_ENDIAN__ + /* The SYSV ABI returns a structure of up to 4 bytes in size + left-padded in r3. */ +# ifndef POWERPC64 + if (rsize <= 4) + memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize); + else +# endif + /* The SYSV ABI returns a structure of up to 8 bytes in size + left-padded in r3/r4, and the ELFv2 ABI similarly returns a + structure of up to 8 bytes in size left-padded in r3. */ + if (rsize <= 8) + memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize); + else +#endif + memcpy (rvalue, smst_buffer, rsize); + } +} + +void +ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, + void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) +{ +#ifdef POWERPC64 + return ffi_prep_closure_loc_linux64 (closure, cif, fun, user_data, codeloc); +#else + return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc); +#endif +} + +ffi_status +ffi_prep_go_closure (ffi_go_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *)) +{ +#ifdef POWERPC64 + closure->tramp = ffi_go_closure_linux64; +#else + closure->tramp = ffi_go_closure_sysv; +#endif + closure->cif = cif; + closure->fun = fun; + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/powerpc/ffi_darwin.c b/circuitpython/lib/libffi/src/powerpc/ffi_darwin.c new file mode 100644 index 0000000..cf6fb6d --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/ffi_darwin.c @@ -0,0 +1,1359 @@ +/* ----------------------------------------------------------------------- + ffi_darwin.c + + Copyright (C) 1998 Geoffrey Keating + Copyright (C) 2001 John Hornkvist + Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. + + FFI support for Darwin and AIX. + + 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 AUTHOR 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 +#include + +#include + +extern void ffi_closure_ASM (void); + +enum { + /* The assembly depends on these exact flags. + For Darwin64 (when FLAG_RETURNS_STRUCT is set): + FLAG_RETURNS_FP indicates that the structure embeds FP data. + FLAG_RETURNS_128BITS signals a special struct size that is not + expanded for float content. */ + FLAG_RETURNS_128BITS = 1 << (31-31), /* These go in cr7 */ + FLAG_RETURNS_NOTHING = 1 << (31-30), + FLAG_RETURNS_FP = 1 << (31-29), + FLAG_RETURNS_64BITS = 1 << (31-28), + + FLAG_RETURNS_STRUCT = 1 << (31-27), /* This goes in cr6 */ + + FLAG_ARG_NEEDS_COPY = 1 << (31- 7), + FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ + FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), + FLAG_RETVAL_REFERENCE = 1 << (31- 4) +}; + +/* About the DARWIN ABI. */ +enum { + NUM_GPR_ARG_REGISTERS = 8, + NUM_FPR_ARG_REGISTERS = 13, + LINKAGE_AREA_GPRS = 6 +}; + +enum { ASM_NEEDS_REGISTERS = 4 }; /* r28-r31 */ + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments. + + m32/m64 + + The stack layout we want looks like this: + + | Return address from ffi_call_DARWIN | higher addresses + |--------------------------------------------| + | Previous backchain pointer 4/8 | stack pointer here + |--------------------------------------------|<+ <<< on entry to + | ASM_NEEDS_REGISTERS=r28-r31 4*(4/8) | | ffi_call_DARWIN + |--------------------------------------------| | + | When we have any FP activity... the | | + | FPRs occupy NUM_FPR_ARG_REGISTERS slots | | + | here fp13 .. fp1 from high to low addr. | | + ~ ~ ~ + | Parameters (at least 8*4/8=32/64) | | NUM_GPR_ARG_REGISTERS + |--------------------------------------------| | + | TOC=R2 (AIX) Reserved (Darwin) 4/8 | | + |--------------------------------------------| | stack | + | Reserved 2*4/8 | | grows | + |--------------------------------------------| | down V + | Space for callee's LR 4/8 | | + |--------------------------------------------| | lower addresses + | Saved CR [low word for m64] 4/8 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 4/8 |-/ during + |--------------------------------------------| <<< ffi_call_DARWIN + + */ + +#if defined(POWERPC_DARWIN64) +static void +darwin64_pass_struct_by_value + (ffi_type *, char *, unsigned, unsigned *, double **, unsigned long **); +#endif + +/* This depends on GPR_SIZE = sizeof (unsigned long) */ + +void +ffi_prep_args (extended_cif *ecif, unsigned long *const stack) +{ + const unsigned bytes = ecif->cif->bytes; + const unsigned flags = ecif->cif->flags; + const unsigned nargs = ecif->cif->nargs; +#if !defined(POWERPC_DARWIN64) + const ffi_abi abi = ecif->cif->abi; +#endif + + /* 'stacktop' points at the previous backchain pointer. */ + unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long)); + + /* 'fpr_base' points at the space for fpr1, and grows upwards as + we use FPR registers. */ + double *fpr_base = (double *) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS; + int gp_count = 0, fparg_count = 0; + + /* 'next_arg' grows up as we put parameters in it. */ + unsigned long *next_arg = stack + LINKAGE_AREA_GPRS; /* 6 reserved positions. */ + + int i; + double double_tmp; + void **p_argv = ecif->avalue; + unsigned long gprvalue; + ffi_type** ptr = ecif->cif->arg_types; +#if !defined(POWERPC_DARWIN64) + char *dest_cpy; +#endif + unsigned size_al = 0; + + /* Check that everything starts aligned properly. */ + FFI_ASSERT(((unsigned) (char *) stack & 0xF) == 0); + FFI_ASSERT(((unsigned) (char *) stacktop & 0xF) == 0); + FFI_ASSERT((bytes & 0xF) == 0); + + /* Deal with return values that are actually pass-by-reference. + Rule: + Return values are referenced by r3, so r4 is the first parameter. */ + + if (flags & FLAG_RETVAL_REFERENCE) + *next_arg++ = (unsigned long) (char *) ecif->rvalue; + + /* Now for the arguments. */ + for (i = nargs; i > 0; i--, ptr++, p_argv++) + { + switch ((*ptr)->type) + { + /* If a floating-point parameter appears before all of the general- + purpose registers are filled, the corresponding GPRs that match + the size of the floating-point parameter are skipped. */ + case FFI_TYPE_FLOAT: + double_tmp = *(float *) *p_argv; + if (fparg_count < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = double_tmp; +#if defined(POWERPC_DARWIN) + *(float *)next_arg = *(float *) *p_argv; +#else + *(double *)next_arg = double_tmp; +#endif + next_arg++; + gp_count++; + fparg_count++; + FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_DOUBLE: + double_tmp = *(double *) *p_argv; + if (fparg_count < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = double_tmp; + *(double *)next_arg = double_tmp; +#ifdef POWERPC64 + next_arg++; + gp_count++; +#else + next_arg += 2; + gp_count += 2; +#endif + fparg_count++; + FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + + case FFI_TYPE_LONGDOUBLE: +# if defined(POWERPC64) && !defined(POWERPC_DARWIN64) + /* ??? This will exceed the regs count when the value starts at fp13 + and it will not put the extra bit on the stack. */ + if (fparg_count < NUM_FPR_ARG_REGISTERS) + *(long double *) fpr_base++ = *(long double *) *p_argv; + else + *(long double *) next_arg = *(long double *) *p_argv; + next_arg += 2; + fparg_count += 2; +# else + double_tmp = ((double *) *p_argv)[0]; + if (fparg_count < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = double_tmp; + *(double *) next_arg = double_tmp; +# if defined(POWERPC_DARWIN64) + next_arg++; + gp_count++; +# else + next_arg += 2; + gp_count += 2; +# endif + fparg_count++; + double_tmp = ((double *) *p_argv)[1]; + if (fparg_count < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = double_tmp; + *(double *) next_arg = double_tmp; +# if defined(POWERPC_DARWIN64) + next_arg++; + gp_count++; +# else + next_arg += 2; + gp_count += 2; +# endif + fparg_count++; +# endif + FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + break; +#endif + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: +#ifdef POWERPC64 + gprvalue = *(long long *) *p_argv; + goto putgpr; +#else + *(long long *) next_arg = *(long long *) *p_argv; + next_arg += 2; + gp_count += 2; +#endif + break; + case FFI_TYPE_POINTER: + gprvalue = *(unsigned long *) *p_argv; + goto putgpr; + case FFI_TYPE_UINT8: + gprvalue = *(unsigned char *) *p_argv; + goto putgpr; + case FFI_TYPE_SINT8: + gprvalue = *(signed char *) *p_argv; + goto putgpr; + case FFI_TYPE_UINT16: + gprvalue = *(unsigned short *) *p_argv; + goto putgpr; + case FFI_TYPE_SINT16: + gprvalue = *(signed short *) *p_argv; + goto putgpr; + + case FFI_TYPE_STRUCT: + size_al = (*ptr)->size; +#if defined(POWERPC_DARWIN64) + next_arg = (unsigned long *)ALIGN((char *)next_arg, (*ptr)->alignment); + darwin64_pass_struct_by_value (*ptr, (char *) *p_argv, + (unsigned) size_al, + (unsigned int *) &fparg_count, + &fpr_base, &next_arg); +#else + dest_cpy = (char *) next_arg; + + /* If the first member of the struct is a double, then include enough + padding in the struct size to align it to double-word. */ + if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE) + size_al = ALIGN((*ptr)->size, 8); + +# if defined(POWERPC64) + FFI_ASSERT (abi != FFI_DARWIN); + memcpy ((char *) dest_cpy, (char *) *p_argv, size_al); + next_arg += (size_al + 7) / 8; +# else + /* Structures that match the basic modes (QI 1 byte, HI 2 bytes, + SI 4 bytes) are aligned as if they were those modes. + Structures with 3 byte in size are padded upwards. */ + if (size_al < 3 && abi == FFI_DARWIN) + dest_cpy += 4 - size_al; + + memcpy((char *) dest_cpy, (char *) *p_argv, size_al); + next_arg += (size_al + 3) / 4; +# endif +#endif + break; + + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + gprvalue = *(signed int *) *p_argv; + goto putgpr; + + case FFI_TYPE_UINT32: + gprvalue = *(unsigned int *) *p_argv; + putgpr: + *next_arg++ = gprvalue; + gp_count++; + break; + default: + break; + } + } + + /* Check that we didn't overrun the stack... */ + /* FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); + FFI_ASSERT((unsigned *)fpr_base + <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); + FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); */ +} + +#if defined(POWERPC_DARWIN64) + +/* See if we can put some of the struct into fprs. + This should not be called for structures of size 16 bytes, since these are not + broken out this way. */ +static void +darwin64_scan_struct_for_floats (ffi_type *s, unsigned *nfpr) +{ + int i; + + FFI_ASSERT (s->type == FFI_TYPE_STRUCT) + + for (i = 0; s->elements[i] != NULL; i++) + { + ffi_type *p = s->elements[i]; + switch (p->type) + { + case FFI_TYPE_STRUCT: + darwin64_scan_struct_for_floats (p, nfpr); + break; + case FFI_TYPE_LONGDOUBLE: + (*nfpr) += 2; + break; + case FFI_TYPE_DOUBLE: + case FFI_TYPE_FLOAT: + (*nfpr) += 1; + break; + default: + break; + } + } +} + +static int +darwin64_struct_size_exceeds_gprs_p (ffi_type *s, char *src, unsigned *nfpr) +{ + unsigned struct_offset=0, i; + + for (i = 0; s->elements[i] != NULL; i++) + { + char *item_base; + ffi_type *p = s->elements[i]; + /* Find the start of this item (0 for the first one). */ + if (i > 0) + struct_offset = ALIGN(struct_offset, p->alignment); + + item_base = src + struct_offset; + + switch (p->type) + { + case FFI_TYPE_STRUCT: + if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr)) + return 1; + break; + case FFI_TYPE_LONGDOUBLE: + if (*nfpr >= NUM_FPR_ARG_REGISTERS) + return 1; + (*nfpr) += 1; + item_base += 8; + /* FALL THROUGH */ + case FFI_TYPE_DOUBLE: + if (*nfpr >= NUM_FPR_ARG_REGISTERS) + return 1; + (*nfpr) += 1; + break; + case FFI_TYPE_FLOAT: + if (*nfpr >= NUM_FPR_ARG_REGISTERS) + return 1; + (*nfpr) += 1; + break; + default: + /* If we try and place any item, that is non-float, once we've + exceeded the 8 GPR mark, then we can't fit the struct. */ + if ((unsigned long)item_base >= 8*8) + return 1; + break; + } + /* now count the size of what we just used. */ + struct_offset += p->size; + } + return 0; +} + +/* Can this struct be returned by value? */ +int +darwin64_struct_ret_by_value_p (ffi_type *s) +{ + unsigned nfp = 0; + + FFI_ASSERT (s && s->type == FFI_TYPE_STRUCT); + + /* The largest structure we can return is 8long + 13 doubles. */ + if (s->size > 168) + return 0; + + /* We can't pass more than 13 floats. */ + darwin64_scan_struct_for_floats (s, &nfp); + if (nfp > 13) + return 0; + + /* If there are not too many floats, and the struct is + small enough to accommodate in the GPRs, then it must be OK. */ + if (s->size <= 64) + return 1; + + /* Well, we have to look harder. */ + nfp = 0; + if (darwin64_struct_size_exceeds_gprs_p (s, NULL, &nfp)) + return 0; + + return 1; +} + +void +darwin64_pass_struct_floats (ffi_type *s, char *src, + unsigned *nfpr, double **fprs) +{ + int i; + double *fpr_base = *fprs; + unsigned struct_offset = 0; + + /* We don't assume anything about the alignment of the source. */ + for (i = 0; s->elements[i] != NULL; i++) + { + char *item_base; + ffi_type *p = s->elements[i]; + /* Find the start of this item (0 for the first one). */ + if (i > 0) + struct_offset = ALIGN(struct_offset, p->alignment); + item_base = src + struct_offset; + + switch (p->type) + { + case FFI_TYPE_STRUCT: + darwin64_pass_struct_floats (p, item_base, nfpr, + &fpr_base); + break; + case FFI_TYPE_LONGDOUBLE: + if (*nfpr < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = *(double *)item_base; + (*nfpr) += 1; + item_base += 8; + /* FALL THROUGH */ + case FFI_TYPE_DOUBLE: + if (*nfpr < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = *(double *)item_base; + (*nfpr) += 1; + break; + case FFI_TYPE_FLOAT: + if (*nfpr < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = (double) *(float *)item_base; + (*nfpr) += 1; + break; + default: + break; + } + /* now count the size of what we just used. */ + struct_offset += p->size; + } + /* Update the scores. */ + *fprs = fpr_base; +} + +/* Darwin64 special rules. + Break out a struct into params and float registers. */ +static void +darwin64_pass_struct_by_value (ffi_type *s, char *src, unsigned size, + unsigned *nfpr, double **fprs, unsigned long **arg) +{ + unsigned long *next_arg = *arg; + char *dest_cpy = (char *)next_arg; + + FFI_ASSERT (s->type == FFI_TYPE_STRUCT) + + if (!size) + return; + + /* First... special cases. */ + if (size < 3 + || (size == 4 + && s->elements[0] + && s->elements[0]->type != FFI_TYPE_FLOAT)) + { + /* Must be at least one GPR, padding is unspecified in value, + let's make it zero. */ + *next_arg = 0UL; + dest_cpy += 8 - size; + memcpy ((char *) dest_cpy, src, size); + next_arg++; + } + else if (size == 16) + { + memcpy ((char *) dest_cpy, src, size); + next_arg += 2; + } + else + { + /* now the general case, we consider embedded floats. */ + memcpy ((char *) dest_cpy, src, size); + darwin64_pass_struct_floats (s, src, nfpr, fprs); + next_arg += (size+7)/8; + } + + *arg = next_arg; +} + +double * +darwin64_struct_floats_to_mem (ffi_type *s, char *dest, double *fprs, unsigned *nf) +{ + int i; + unsigned struct_offset = 0; + + /* We don't assume anything about the alignment of the source. */ + for (i = 0; s->elements[i] != NULL; i++) + { + char *item_base; + ffi_type *p = s->elements[i]; + /* Find the start of this item (0 for the first one). */ + if (i > 0) + struct_offset = ALIGN(struct_offset, p->alignment); + item_base = dest + struct_offset; + + switch (p->type) + { + case FFI_TYPE_STRUCT: + fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf); + break; + case FFI_TYPE_LONGDOUBLE: + if (*nf < NUM_FPR_ARG_REGISTERS) + { + *(double *)item_base = *fprs++ ; + (*nf) += 1; + } + item_base += 8; + /* FALL THROUGH */ + case FFI_TYPE_DOUBLE: + if (*nf < NUM_FPR_ARG_REGISTERS) + { + *(double *)item_base = *fprs++ ; + (*nf) += 1; + } + break; + case FFI_TYPE_FLOAT: + if (*nf < NUM_FPR_ARG_REGISTERS) + { + *(float *)item_base = (float) *fprs++ ; + (*nf) += 1; + } + break; + default: + break; + } + /* now count the size of what we just used. */ + struct_offset += p->size; + } + return fprs; +} + +#endif + +/* Adjust the size of S to be correct for Darwin. + On Darwin m32, the first field of a structure has natural alignment. + On Darwin m64, all fields have natural alignment. */ + +static void +darwin_adjust_aggregate_sizes (ffi_type *s) +{ + int i; + + if (s->type != FFI_TYPE_STRUCT) + return; + + s->size = 0; + for (i = 0; s->elements[i] != NULL; i++) + { + ffi_type *p; + int align; + + p = s->elements[i]; + if (p->type == FFI_TYPE_STRUCT) + darwin_adjust_aggregate_sizes (p); +#if defined(POWERPC_DARWIN64) + /* Natural alignment for all items. */ + align = p->alignment; +#else + /* Natural alignment for the first item... */ + if (i == 0) + align = p->alignment; + else if (p->alignment == 16 || p->alignment < 4) + /* .. subsequent items with vector or align < 4 have natural align. */ + align = p->alignment; + else + /* .. or align is 4. */ + align = 4; +#endif + /* Pad, if necessary, before adding the current item. */ + s->size = ALIGN(s->size, align) + p->size; + } + + s->size = ALIGN(s->size, s->alignment); + + /* This should not be necessary on m64, but harmless. */ + if (s->elements[0]->type == FFI_TYPE_UINT64 + || s->elements[0]->type == FFI_TYPE_SINT64 + || s->elements[0]->type == FFI_TYPE_DOUBLE + || s->elements[0]->alignment == 8) + s->alignment = s->alignment > 8 ? s->alignment : 8; + /* Do not add additional tail padding. */ +} + +/* Adjust the size of S to be correct for AIX. + Word-align double unless it is the first member of a structure. */ + +static void +aix_adjust_aggregate_sizes (ffi_type *s) +{ + int i; + + if (s->type != FFI_TYPE_STRUCT) + return; + + s->size = 0; + for (i = 0; s->elements[i] != NULL; i++) + { + ffi_type *p; + int align; + + p = s->elements[i]; + aix_adjust_aggregate_sizes (p); + align = p->alignment; + if (i != 0 && p->type == FFI_TYPE_DOUBLE) + align = 4; + s->size = ALIGN(s->size, align) + p->size; + } + + s->size = ALIGN(s->size, s->alignment); + + if (s->elements[0]->type == FFI_TYPE_UINT64 + || s->elements[0]->type == FFI_TYPE_SINT64 + || s->elements[0]->type == FFI_TYPE_DOUBLE + || s->elements[0]->alignment == 8) + s->alignment = s->alignment > 8 ? s->alignment : 8; + /* Do not add additional tail padding. */ +} + +/* Perform machine dependent cif processing. */ +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* All this is for the DARWIN ABI. */ + unsigned i; + ffi_type **ptr; + unsigned bytes; + unsigned fparg_count = 0, intarg_count = 0; + unsigned flags = 0; + unsigned size_al = 0; + + /* All the machine-independent calculation of cif->bytes will be wrong. + All the calculation of structure sizes will also be wrong. + Redo the calculation for DARWIN. */ + + if (cif->abi == FFI_DARWIN) + { + darwin_adjust_aggregate_sizes (cif->rtype); + for (i = 0; i < cif->nargs; i++) + darwin_adjust_aggregate_sizes (cif->arg_types[i]); + } + + if (cif->abi == FFI_AIX) + { + aix_adjust_aggregate_sizes (cif->rtype); + for (i = 0; i < cif->nargs; i++) + aix_adjust_aggregate_sizes (cif->arg_types[i]); + } + + /* Space for the frame pointer, callee's LR, CR, etc, and for + the asm's temp regs. */ + + bytes = (LINKAGE_AREA_GPRS + ASM_NEEDS_REGISTERS) * sizeof(unsigned long); + + /* Return value handling. + The rules m32 are as follows: + - 32-bit (or less) integer values are returned in gpr3; + - structures of size <= 4 bytes also returned in gpr3; + - 64-bit integer values [??? and structures between 5 and 8 bytes] are + returned in gpr3 and gpr4; + - Single/double FP values are returned in fpr1; + - Long double FP (if not equivalent to double) values are returned in + fpr1 and fpr2; + m64: + - 64-bit or smaller integral values are returned in GPR3 + - Single/double FP values are returned in fpr1; + - Long double FP values are returned in fpr1 and fpr2; + m64 Structures: + - If the structure could be accommodated in registers were it to be the + first argument to a routine, then it is returned in those registers. + m32/m64 structures otherwise: + - Larger structures values are allocated space and a pointer is passed + as the first argument. */ + switch (cif->rtype->type) + { + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + flags |= FLAG_RETURNS_128BITS; + flags |= FLAG_RETURNS_FP; + break; +#endif + + case FFI_TYPE_DOUBLE: + flags |= FLAG_RETURNS_64BITS; + /* Fall through. */ + case FFI_TYPE_FLOAT: + flags |= FLAG_RETURNS_FP; + break; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: +#ifdef POWERPC64 + case FFI_TYPE_POINTER: +#endif + flags |= FLAG_RETURNS_64BITS; + break; + + case FFI_TYPE_STRUCT: +#if defined(POWERPC_DARWIN64) + { + /* Can we fit the struct into regs? */ + if (darwin64_struct_ret_by_value_p (cif->rtype)) + { + unsigned nfpr = 0; + flags |= FLAG_RETURNS_STRUCT; + if (cif->rtype->size != 16) + darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ; + else + flags |= FLAG_RETURNS_128BITS; + /* Will be 0 for 16byte struct. */ + if (nfpr) + flags |= FLAG_RETURNS_FP; + } + else /* By ref. */ + { + flags |= FLAG_RETVAL_REFERENCE; + flags |= FLAG_RETURNS_NOTHING; + intarg_count++; + } + } +#elif defined(DARWIN_PPC) + if (cif->rtype->size <= 4) + flags |= FLAG_RETURNS_STRUCT; + else /* else by reference. */ + { + flags |= FLAG_RETVAL_REFERENCE; + flags |= FLAG_RETURNS_NOTHING; + intarg_count++; + } +#else /* assume we pass by ref. */ + flags |= FLAG_RETVAL_REFERENCE; + flags |= FLAG_RETURNS_NOTHING; + intarg_count++; +#endif + break; + case FFI_TYPE_VOID: + flags |= FLAG_RETURNS_NOTHING; + break; + + default: + /* Returns 32-bit integer, or similar. Nothing to do here. */ + break; + } + + /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the + first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest + goes on the stack. + ??? Structures are passed as a pointer to a copy of the structure. + Stuff on the stack needs to keep proper alignment. + For m64 the count is effectively of half-GPRs. */ + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + unsigned align_words; + switch ((*ptr)->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + fparg_count++; +#if !defined(POWERPC_DARWIN64) + /* If this FP arg is going on the stack, it must be + 8-byte-aligned. */ + if (fparg_count > NUM_FPR_ARG_REGISTERS + && (intarg_count & 0x01) != 0) + intarg_count++; +#endif + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + fparg_count += 2; + /* If this FP arg is going on the stack, it must be + 16-byte-aligned. */ + if (fparg_count >= NUM_FPR_ARG_REGISTERS) +#if defined (POWERPC64) + intarg_count = ALIGN(intarg_count, 2); +#else + intarg_count = ALIGN(intarg_count, 4); +#endif + break; +#endif + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: +#if defined(POWERPC64) + intarg_count++; +#else + /* 'long long' arguments are passed as two words, but + either both words must fit in registers or both go + on the stack. If they go on the stack, they must + be 8-byte-aligned. */ + if (intarg_count == NUM_GPR_ARG_REGISTERS-1 + || (intarg_count >= NUM_GPR_ARG_REGISTERS + && (intarg_count & 0x01) != 0)) + intarg_count++; + intarg_count += 2; +#endif + break; + + case FFI_TYPE_STRUCT: + size_al = (*ptr)->size; +#if defined(POWERPC_DARWIN64) + align_words = (*ptr)->alignment >> 3; + if (align_words) + intarg_count = ALIGN(intarg_count, align_words); + /* Base size of the struct. */ + intarg_count += (size_al + 7) / 8; + /* If 16 bytes then don't worry about floats. */ + if (size_al != 16) + /* Scan through for floats to be placed in regs. */ + darwin64_scan_struct_for_floats (*ptr, &fparg_count) ; +#else + align_words = (*ptr)->alignment >> 2; + if (align_words) + intarg_count = ALIGN(intarg_count, align_words); + /* If the first member of the struct is a double, then align + the struct to double-word. + if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE) + size_al = ALIGN((*ptr)->size, 8); */ +# ifdef POWERPC64 + intarg_count += (size_al + 7) / 8; +# else + intarg_count += (size_al + 3) / 4; +# endif +#endif + break; + + default: + /* Everything else is passed as a 4-byte word in a GPR, either + the object itself or a pointer to it. */ + intarg_count++; + break; + } + } + + if (fparg_count != 0) + flags |= FLAG_FP_ARGUMENTS; + +#if defined(POWERPC_DARWIN64) + /* Space to image the FPR registers, if needed - which includes when they might be + used in a struct return. */ + if (fparg_count != 0 + || ((flags & FLAG_RETURNS_STRUCT) + && (flags & FLAG_RETURNS_FP))) + bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); +#else + /* Space for the FPR registers, if needed. */ + if (fparg_count != 0) + bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); +#endif + + /* Stack space. */ +#ifdef POWERPC64 + if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS) + bytes += (intarg_count + fparg_count) * sizeof(long); +#else + if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS) + bytes += (intarg_count + 2 * fparg_count) * sizeof(long); +#endif + else + bytes += NUM_GPR_ARG_REGISTERS * sizeof(long); + + /* The stack space allocated needs to be a multiple of 16 bytes. */ + bytes = ALIGN(bytes, 16) ; + + cif->flags = flags; + cif->bytes = bytes; + + return FFI_OK; +} + +extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *, + void (*fn)(void), void (*fn2)(void)); + +extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *, + void (*fn)(void), void (*fn2)(void), ffi_type*); + +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return + value address then we need to make one. */ + + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca (cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_AIX: + ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn, + FFI_FN(ffi_prep_args)); + break; + case FFI_DARWIN: + ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn, + FFI_FN(ffi_prep_args), cif->rtype); + break; + default: + FFI_ASSERT(0); + break; + } +} + +static void flush_icache(char *); +static void flush_range(char *, int); + +/* The layout of a function descriptor. A C function pointer really + points to one of these. */ + +typedef struct aix_fd_struct { + void *code_pointer; + void *toc; +} aix_fd; + +/* here I'd like to add the stack frame layout we use in darwin_closure.S + and aix_closure.S + + m32/m64 + + The stack layout looks like this: + + | Additional params... | | Higher address + ~ ~ ~ + | Parameters (at least 8*4/8=32/64) | | NUM_GPR_ARG_REGISTERS + |--------------------------------------------| | + | TOC=R2 (AIX) Reserved (Darwin) 4/8 | | + |--------------------------------------------| | + | Reserved 2*4/8 | | + |--------------------------------------------| | + | Space for callee's LR 4/8 | | + |--------------------------------------------| | + | Saved CR [low word for m64] 4/8 | | + |--------------------------------------------| | + | Current backchain pointer 4/8 |-/ Parent's frame. + |--------------------------------------------| <+ <<< on entry to ffi_closure_ASM + | Result Bytes 16 | | + |--------------------------------------------| | + ~ padding to 16-byte alignment ~ ~ + |--------------------------------------------| | + | NUM_FPR_ARG_REGISTERS slots | | + | here fp13 .. fp1 13*8 | | + |--------------------------------------------| | + | R3..R10 8*4/8=32/64 | | NUM_GPR_ARG_REGISTERS + |--------------------------------------------| | + | TOC=R2 (AIX) Reserved (Darwin) 4/8 | | + |--------------------------------------------| | stack | + | Reserved [compiler,binder] 2*4/8 | | grows | + |--------------------------------------------| | down V + | Space for callee's LR 4/8 | | + |--------------------------------------------| | lower addresses + | Saved CR [low word for m64] 4/8 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 4/8 |-/ during + |--------------------------------------------| <<< ffi_closure_ASM. + +*/ + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp; + struct ffi_aix_trampoline_struct *tramp_aix; + aix_fd *fd; + + switch (cif->abi) + { + case FFI_DARWIN: + + FFI_ASSERT (cif->abi == FFI_DARWIN); + + tramp = (unsigned int *) &closure->tramp[0]; +#if defined(POWERPC_DARWIN64) + tramp[0] = 0x7c0802a6; /* mflr r0 */ + tramp[1] = 0x429f0015; /* bcl- 20,4*cr7+so, +0x18 (L1) */ + /* We put the addresses here. */ + tramp[6] = 0x7d6802a6; /*L1: mflr r11 */ + tramp[7] = 0xe98b0000; /* ld r12,0(r11) function address */ + tramp[8] = 0x7c0803a6; /* mtlr r0 */ + tramp[9] = 0x7d8903a6; /* mtctr r12 */ + tramp[10] = 0xe96b0008; /* lwz r11,8(r11) static chain */ + tramp[11] = 0x4e800420; /* bctr */ + + *((unsigned long *)&tramp[2]) = (unsigned long) ffi_closure_ASM; /* function */ + *((unsigned long *)&tramp[4]) = (unsigned long) codeloc; /* context */ +#else + tramp[0] = 0x7c0802a6; /* mflr r0 */ + tramp[1] = 0x429f000d; /* bcl- 20,4*cr7+so,0x10 */ + tramp[4] = 0x7d6802a6; /* mflr r11 */ + tramp[5] = 0x818b0000; /* lwz r12,0(r11) function address */ + tramp[6] = 0x7c0803a6; /* mtlr r0 */ + tramp[7] = 0x7d8903a6; /* mtctr r12 */ + tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */ + tramp[9] = 0x4e800420; /* bctr */ + tramp[2] = (unsigned long) ffi_closure_ASM; /* function */ + tramp[3] = (unsigned long) codeloc; /* context */ +#endif + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + /* Flush the icache. Only necessary on Darwin. */ + flush_range(codeloc, FFI_TRAMPOLINE_SIZE); + + break; + + case FFI_AIX: + + tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp); + fd = (aix_fd *)(void *)ffi_closure_ASM; + + FFI_ASSERT (cif->abi == FFI_AIX); + + tramp_aix->code_pointer = fd->code_pointer; + tramp_aix->toc = fd->toc; + tramp_aix->static_chain = codeloc; + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + break; + + default: + return FFI_BAD_ABI; + break; + } + return FFI_OK; +} + +static void +flush_icache(char *addr) +{ +#ifndef _AIX + __asm__ volatile ( + "dcbf 0,%0\n" + "\tsync\n" + "\ticbi 0,%0\n" + "\tsync\n" + "\tisync" + : : "r"(addr) : "memory"); +#endif +} + +static void +flush_range(char * addr1, int size) +{ +#define MIN_LINE_SIZE 32 + int i; + for (i = 0; i < size; i += MIN_LINE_SIZE) + flush_icache(addr1+i); + flush_icache(addr1+size-1); +} + +typedef union +{ + float f; + double d; +} ffi_dblfl; + +ffi_type * +ffi_closure_helper_DARWIN (ffi_closure *, void *, + unsigned long *, ffi_dblfl *); + +/* Basically the trampoline invokes ffi_closure_ASM, and on + entry, r11 holds the address of the closure. + After storing the registers that could possibly contain + parameters to be passed into the stack frame and setting + up space for a return value, ffi_closure_ASM invokes the + following helper function to do most of the work. */ + +ffi_type * +ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue, + unsigned long *pgr, ffi_dblfl *pfr) +{ + /* rvalue is the pointer to space for return value in closure assembly + pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM + pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */ + + typedef double ldbits[2]; + + union ldu + { + ldbits lb; + long double ld; + }; + + void ** avalue; + ffi_type ** arg_types; + long i, avn; + ffi_cif * cif; + ffi_dblfl * end_pfr = pfr + NUM_FPR_ARG_REGISTERS; + unsigned size_al; +#if defined(POWERPC_DARWIN64) + unsigned fpsused = 0; +#endif + + cif = closure->cif; + avalue = alloca (cif->nargs * sizeof(void *)); + + if (cif->rtype->type == FFI_TYPE_STRUCT) + { +#if defined(POWERPC_DARWIN64) + if (!darwin64_struct_ret_by_value_p (cif->rtype)) + { + /* Won't fit into the regs - return by ref. */ + rvalue = (void *) *pgr; + pgr++; + } +#elif defined(DARWIN_PPC) + if (cif->rtype->size > 4) + { + rvalue = (void *) *pgr; + pgr++; + } +#else /* assume we return by ref. */ + rvalue = (void *) *pgr; + pgr++; +#endif + } + + i = 0; + avn = cif->nargs; + arg_types = cif->arg_types; + + /* Grab the addresses of the arguments from the stack frame. */ + while (i < avn) + { + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: +#if defined(POWERPC64) + avalue[i] = (char *) pgr + 7; +#else + avalue[i] = (char *) pgr + 3; +#endif + pgr++; + break; + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: +#if defined(POWERPC64) + avalue[i] = (char *) pgr + 6; +#else + avalue[i] = (char *) pgr + 2; +#endif + pgr++; + break; + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: +#if defined(POWERPC64) + avalue[i] = (char *) pgr + 4; +#else + case FFI_TYPE_POINTER: + avalue[i] = pgr; +#endif + pgr++; + break; + + case FFI_TYPE_STRUCT: + size_al = arg_types[i]->size; +#if defined(POWERPC_DARWIN64) + pgr = (unsigned long *)ALIGN((char *)pgr, arg_types[i]->alignment); + if (size_al < 3 || size_al == 4) + { + avalue[i] = ((char *)pgr)+8-size_al; + if (arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT + && fpsused < NUM_FPR_ARG_REGISTERS) + { + *(float *)pgr = (float) *(double *)pfr; + pfr++; + fpsused++; + } + } + else + { + if (size_al != 16) + pfr = (ffi_dblfl *) + darwin64_struct_floats_to_mem (arg_types[i], (char *)pgr, + (double *)pfr, &fpsused); + avalue[i] = pgr; + } + pgr += (size_al + 7) / 8; +#else + /* If the first member of the struct is a double, then align + the struct to double-word. */ + if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE) + size_al = ALIGN(arg_types[i]->size, 8); +# if defined(POWERPC64) + FFI_ASSERT (cif->abi != FFI_DARWIN); + avalue[i] = pgr; + pgr += (size_al + 7) / 8; +# else + /* Structures that match the basic modes (QI 1 byte, HI 2 bytes, + SI 4 bytes) are aligned as if they were those modes. */ + if (size_al < 3 && cif->abi == FFI_DARWIN) + avalue[i] = (char*) pgr + 4 - size_al; + else + avalue[i] = pgr; + pgr += (size_al + 3) / 4; +# endif +#endif + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: +#if defined(POWERPC64) + case FFI_TYPE_POINTER: + avalue[i] = pgr; + pgr++; + break; +#else + /* Long long ints are passed in two gpr's. */ + avalue[i] = pgr; + pgr += 2; + break; +#endif + + case FFI_TYPE_FLOAT: + /* A float value consumes a GPR. + There are 13 64bit floating point registers. */ + if (pfr < end_pfr) + { + double temp = pfr->d; + pfr->f = (float) temp; + avalue[i] = pfr; + pfr++; + } + else + { + avalue[i] = pgr; + } + pgr++; + break; + + case FFI_TYPE_DOUBLE: + /* A double value consumes two GPRs. + There are 13 64bit floating point registers. */ + if (pfr < end_pfr) + { + avalue[i] = pfr; + pfr++; + } + else + { + avalue[i] = pgr; + } +#ifdef POWERPC64 + pgr++; +#else + pgr += 2; +#endif + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + + case FFI_TYPE_LONGDOUBLE: +#ifdef POWERPC64 + if (pfr + 1 < end_pfr) + { + avalue[i] = pfr; + pfr += 2; + } + else + { + if (pfr < end_pfr) + { + *pgr = *(unsigned long *) pfr; + pfr++; + } + avalue[i] = pgr; + } + pgr += 2; +#else /* POWERPC64 */ + /* A long double value consumes four GPRs and two FPRs. + There are 13 64bit floating point registers. */ + if (pfr + 1 < end_pfr) + { + avalue[i] = pfr; + pfr += 2; + } + /* Here we have the situation where one part of the long double + is stored in fpr13 and the other part is already on the stack. + We use a union to pass the long double to avalue[i]. */ + else if (pfr + 1 == end_pfr) + { + union ldu temp_ld; + memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits)); + memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits)); + avalue[i] = &temp_ld.ld; + pfr++; + } + else + { + avalue[i] = pgr; + } + pgr += 4; +#endif /* POWERPC64 */ + break; +#endif + default: + FFI_ASSERT(0); + } + i++; + } + + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + /* Tell ffi_closure_ASM to perform return type promotions. */ + return cif->rtype; +} diff --git a/circuitpython/lib/libffi/src/powerpc/ffi_linux64.c b/circuitpython/lib/libffi/src/powerpc/ffi_linux64.c new file mode 100644 index 0000000..b84b91f --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/ffi_linux64.c @@ -0,0 +1,945 @@ +/* ----------------------------------------------------------------------- + ffi_linux64.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC Foreign Function Interface + + 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 AUTHOR 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 "ffi.h" + +#ifdef POWERPC64 +#include "ffi_common.h" +#include "ffi_powerpc.h" + + +/* About the LINUX64 ABI. */ +enum { + NUM_GPR_ARG_REGISTERS64 = 8, + NUM_FPR_ARG_REGISTERS64 = 13 +}; +enum { ASM_NEEDS_REGISTERS64 = 4 }; + + +#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +/* Adjust size of ffi_type_longdouble. */ +void FFI_HIDDEN +ffi_prep_types_linux64 (ffi_abi abi) +{ + if ((abi & (FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128)) == FFI_LINUX) + { + ffi_type_longdouble.size = 8; + ffi_type_longdouble.alignment = 8; + } + else + { + ffi_type_longdouble.size = 16; + ffi_type_longdouble.alignment = 16; + } +} +#endif + + +#if _CALL_ELF == 2 +static unsigned int +discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum) +{ + switch (t->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + *elnum = 1; + return (int) t->type; + + case FFI_TYPE_STRUCT:; + { + unsigned int base_elt = 0, total_elnum = 0; + ffi_type **el = t->elements; + while (*el) + { + unsigned int el_elt, el_elnum = 0; + el_elt = discover_homogeneous_aggregate (*el, &el_elnum); + if (el_elt == 0 + || (base_elt && base_elt != el_elt)) + return 0; + base_elt = el_elt; + total_elnum += el_elnum; + if (total_elnum > 8) + return 0; + el++; + } + *elnum = total_elnum; + return base_elt; + } + + default: + return 0; + } +} +#endif + + +/* Perform machine dependent cif processing */ +static ffi_status +ffi_prep_cif_linux64_core (ffi_cif *cif) +{ + ffi_type **ptr; + unsigned bytes; + unsigned i, fparg_count = 0, intarg_count = 0; + unsigned flags = cif->flags; +#if _CALL_ELF == 2 + unsigned int elt, elnum; +#endif + +#if FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE + /* If compiled without long double support.. */ + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + return FFI_BAD_ABI; +#endif + + /* The machine-independent calculation of cif->bytes doesn't work + for us. Redo the calculation. */ +#if _CALL_ELF == 2 + /* Space for backchain, CR, LR, TOC and the asm's temp regs. */ + bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long); + + /* Space for the general registers. */ + bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long); +#else + /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp + regs. */ + bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long); + + /* Space for the mandatory parm save area and general registers. */ + bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long); +#endif + + /* Return value handling. */ + switch (cif->rtype->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + flags |= FLAG_RETURNS_64BITS; + /* Fall through. */ + case FFI_TYPE_FLOAT: + flags |= FLAG_RETURNS_FP; + break; + + case FFI_TYPE_UINT128: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags |= FLAG_RETURNS_64BITS; + break; + + case FFI_TYPE_STRUCT: +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (cif->rtype, &elnum); + if (elt) + { + if (elt == FFI_TYPE_DOUBLE) + flags |= FLAG_RETURNS_64BITS; + flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST; + break; + } + if (cif->rtype->size <= 16) + { + flags |= FLAG_RETURNS_SMST; + break; + } +#endif + intarg_count++; + flags |= FLAG_RETVAL_REFERENCE; + /* Fall through. */ + case FFI_TYPE_VOID: + flags |= FLAG_RETURNS_NOTHING; + break; + + default: + /* Returns 32-bit integer, or similar. Nothing to do here. */ + break; + } + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + unsigned int align; + + switch ((*ptr)->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + fparg_count++; + intarg_count++; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + case FFI_TYPE_FLOAT: + fparg_count++; + intarg_count++; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + break; + + case FFI_TYPE_STRUCT: + if ((cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = (*ptr)->alignment; + if (align > 16) + align = 16; + align = align / 8; + if (align > 1) + intarg_count = ALIGN (intarg_count, align); + } + intarg_count += ((*ptr)->size + 7) / 8; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (*ptr, &elnum); + if (elt) + { + fparg_count += elnum; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + } + else +#endif + { + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + } + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + /* Everything else is passed as a 8-byte word in a GPR, either + the object itself or a pointer to it. */ + intarg_count++; + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + break; + default: + FFI_ASSERT (0); + } + } + + if (fparg_count != 0) + flags |= FLAG_FP_ARGUMENTS; + if (intarg_count > 4) + flags |= FLAG_4_GPR_ARGUMENTS; + + /* Space for the FPR registers, if needed. */ + if (fparg_count != 0) + bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double); + + /* Stack space. */ +#if _CALL_ELF == 2 + if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0) + bytes += intarg_count * sizeof (long); +#else + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long); +#endif + + /* The stack space allocated needs to be a multiple of 16 bytes. */ + bytes = (bytes + 15) & ~0xF; + + cif->flags = flags; + cif->bytes = bytes; + + return FFI_OK; +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_linux64 (ffi_cif *cif) +{ + if ((cif->abi & FFI_LINUX) != 0) + cif->nfixedargs = cif->nargs; +#if _CALL_ELF != 2 + else if (cif->abi == FFI_COMPAT_LINUX64) + { + /* This call is from old code. Don't touch cif->nfixedargs + since old code will be using a smaller cif. */ + cif->flags |= FLAG_COMPAT; + /* Translate to new abi value. */ + cif->abi = FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128; + } +#endif + else + return FFI_BAD_ABI; + return ffi_prep_cif_linux64_core (cif); +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_linux64_var (ffi_cif *cif, + unsigned int nfixedargs, + unsigned int ntotalargs MAYBE_UNUSED) +{ + if ((cif->abi & FFI_LINUX) != 0) + cif->nfixedargs = nfixedargs; +#if _CALL_ELF != 2 + else if (cif->abi == FFI_COMPAT_LINUX64) + { + /* This call is from old code. Don't touch cif->nfixedargs + since old code will be using a smaller cif. */ + cif->flags |= FLAG_COMPAT; + /* Translate to new abi value. */ + cif->abi = FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128; + } +#endif + else + return FFI_BAD_ABI; +#if _CALL_ELF == 2 + cif->flags |= FLAG_ARG_NEEDS_PSAVE; +#endif + return ffi_prep_cif_linux64_core (cif); +} + + +/* ffi_prep_args64 is called by the assembly routine once stack space + has been allocated for the function's arguments. + + The stack layout we want looks like this: + + | Ret addr from ffi_call_LINUX64 8bytes | higher addresses + |--------------------------------------------| + | CR save area 8bytes | + |--------------------------------------------| + | Previous backchain pointer 8 | stack pointer here + |--------------------------------------------|<+ <<< on entry to + | Saved r28-r31 4*8 | | ffi_call_LINUX64 + |--------------------------------------------| | + | GPR registers r3-r10 8*8 | | + |--------------------------------------------| | + | FPR registers f1-f13 (optional) 13*8 | | + |--------------------------------------------| | + | Parameter save area | | + |--------------------------------------------| | + | TOC save area 8 | | + |--------------------------------------------| | stack | + | Linker doubleword 8 | | grows | + |--------------------------------------------| | down V + | Compiler doubleword 8 | | + |--------------------------------------------| | lower addresses + | Space for callee's LR 8 | | + |--------------------------------------------| | + | CR save area 8 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 8 |-/ during + |--------------------------------------------| <<< ffi_call_LINUX64 + +*/ + +void FFI_HIDDEN +ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack) +{ + const unsigned long bytes = ecif->cif->bytes; + const unsigned long flags = ecif->cif->flags; + + typedef union + { + char *c; + unsigned long *ul; + float *f; + double *d; + size_t p; + } valp; + + /* 'stacktop' points at the previous backchain pointer. */ + valp stacktop; + + /* 'next_arg' points at the space for gpr3, and grows upwards as + we use GPR registers, then continues at rest. */ + valp gpr_base; + valp gpr_end; + valp rest; + valp next_arg; + + /* 'fpr_base' points at the space for fpr3, and grows upwards as + we use FPR registers. */ + valp fpr_base; + unsigned int fparg_count; + + unsigned int i, words, nargs, nfixedargs; + ffi_type **ptr; + double double_tmp; + union + { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + signed int **si; + unsigned int **ui; + unsigned long **ul; + float **f; + double **d; + } p_argv; + unsigned long gprvalue; + unsigned long align; + + stacktop.c = (char *) stack + bytes; + gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64; + gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64; +#if _CALL_ELF == 2 + rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64; +#else + rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64; +#endif + fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64; + fparg_count = 0; + next_arg.ul = gpr_base.ul; + + /* Check that everything starts aligned properly. */ + FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); + FFI_ASSERT ((bytes & 0xF) == 0); + + /* Deal with return values that are actually pass-by-reference. */ + if (flags & FLAG_RETVAL_REFERENCE) + *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue; + + /* Now for the arguments. */ + p_argv.v = ecif->avalue; + nargs = ecif->cif->nargs; +#if _CALL_ELF != 2 + nfixedargs = (unsigned) -1; + if ((flags & FLAG_COMPAT) == 0) +#endif + nfixedargs = ecif->cif->nfixedargs; + for (ptr = ecif->cif->arg_types, i = 0; + i < nargs; + i++, ptr++, p_argv.v++) + { +#if _CALL_ELF == 2 + unsigned int elt, elnum; +#endif + + switch ((*ptr)->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + double_tmp = (*p_argv.d)[0]; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +# if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +# endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + double_tmp = (*p_argv.d)[1]; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +# if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +# endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (__LDBL_MANT_DIG__ == 106); + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + double_tmp = **p_argv.d; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +#if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +#endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_FLOAT: + double_tmp = **p_argv.f; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +#if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.f = (float) double_tmp; +#endif + } + else + *next_arg.f = (float) double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_STRUCT: + if ((ecif->cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = (*ptr)->alignment; + if (align > 16) + align = 16; + if (align > 1) + next_arg.p = ALIGN (next_arg.p, align); + } +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (*ptr, &elnum); + if (elt) + { + union { + void *v; + float *f; + double *d; + } arg; + + arg.v = *p_argv.v; + if (elt == FFI_TYPE_FLOAT) + { + do + { + double_tmp = *arg.f++; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 + && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.f = (float) double_tmp; + if (++next_arg.f == gpr_end.f) + next_arg.f = rest.f; + fparg_count++; + } + while (--elnum != 0); + if ((next_arg.p & 3) != 0) + { + if (++next_arg.f == gpr_end.f) + next_arg.f = rest.f; + } + } + else + do + { + double_tmp = *arg.d++; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.d = double_tmp; + if (++next_arg.d == gpr_end.d) + next_arg.d = rest.d; + fparg_count++; + } + while (--elnum != 0); + } + else +#endif + { + words = ((*ptr)->size + 7) / 8; + if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul) + { + size_t first = gpr_end.c - next_arg.c; + memcpy (next_arg.c, *p_argv.c, first); + memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first); + next_arg.c = rest.c + words * 8 - first; + } + else + { + char *where = next_arg.c; + +#ifndef __LITTLE_ENDIAN__ + /* Structures with size less than eight bytes are passed + left-padded. */ + if ((*ptr)->size < 8) + where += 8 - (*ptr)->size; +#endif + memcpy (where, *p_argv.c, (*ptr)->size); + next_arg.ul += words; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + } + } + break; + + case FFI_TYPE_UINT8: + gprvalue = **p_argv.uc; + goto putgpr; + case FFI_TYPE_SINT8: + gprvalue = **p_argv.sc; + goto putgpr; + case FFI_TYPE_UINT16: + gprvalue = **p_argv.us; + goto putgpr; + case FFI_TYPE_SINT16: + gprvalue = **p_argv.ss; + goto putgpr; + case FFI_TYPE_UINT32: + gprvalue = **p_argv.ui; + goto putgpr; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + gprvalue = **p_argv.si; + goto putgpr; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + gprvalue = **p_argv.ul; + putgpr: + *next_arg.ul++ = gprvalue; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + break; + } + } + + FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS + || (next_arg.ul >= gpr_base.ul + && next_arg.ul <= gpr_base.ul + 4)); +} + + +#if _CALL_ELF == 2 +#define MIN_CACHE_LINE_SIZE 8 + +static void +flush_icache (char *wraddr, char *xaddr, int size) +{ + int i; + for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" + : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" + : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) + : "memory"); +} +#endif + + +ffi_status FFI_HIDDEN +ffi_prep_closure_loc_linux64 (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) +{ +#if _CALL_ELF == 2 + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + + if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + tramp[0] = 0xe96c0018; /* 0: ld 11,2f-0b(12) */ + tramp[1] = 0xe98c0010; /* ld 12,1f-0b(12) */ + tramp[2] = 0x7d8903a6; /* mtctr 12 */ + tramp[3] = 0x4e800420; /* bctr */ + /* 1: .quad function_addr */ + /* 2: .quad context */ + *(void **) &tramp[4] = (void *) ffi_closure_LINUX64; + *(void **) &tramp[6] = codeloc; + flush_icache ((char *) tramp, (char *) codeloc, 4 * 4); +#else + void **tramp = (void **) &closure->tramp[0]; + + if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + /* Copy function address and TOC from ffi_closure_LINUX64 OPD. */ + memcpy (&tramp[0], (void **) ffi_closure_LINUX64, sizeof (void *)); + tramp[1] = codeloc; + memcpy (&tramp[2], (void **) ffi_closure_LINUX64 + 1, sizeof (void *)); +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + + +int FFI_HIDDEN +ffi_closure_helper_LINUX64 (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *rvalue, + unsigned long *pst, + ffi_dblfl *pfr) +{ + /* rvalue is the pointer to space for return value in closure assembly */ + /* pst is the pointer to parameter save area + (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */ + /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */ + + void **avalue; + ffi_type **arg_types; + unsigned long i, avn, nfixedargs; + ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64; + unsigned long align; + + avalue = alloca (cif->nargs * sizeof (void *)); + + /* Copy the caller's structure return value address so that the + closure returns the data directly to the caller. */ + if (cif->rtype->type == FFI_TYPE_STRUCT + && (cif->flags & FLAG_RETURNS_SMST) == 0) + { + rvalue = (void *) *pst; + pst++; + } + + i = 0; + avn = cif->nargs; +#if _CALL_ELF != 2 + nfixedargs = (unsigned) -1; + if ((cif->flags & FLAG_COMPAT) == 0) +#endif + nfixedargs = cif->nfixedargs; + arg_types = cif->arg_types; + + /* Grab the addresses of the arguments from the stack frame. */ + while (i < avn) + { + unsigned int elt, elnum; + + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 7; + pst++; + break; +#endif + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 6; + pst++; + break; +#endif + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 4; + pst++; + break; +#endif + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + avalue[i] = pst; + pst++; + break; + + case FFI_TYPE_STRUCT: + if ((cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = arg_types[i]->alignment; + if (align > 16) + align = 16; + if (align > 1) + pst = (unsigned long *) ALIGN ((size_t) pst, align); + } + elt = 0; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (arg_types[i], &elnum); +#endif + if (elt) + { + union { + void *v; + unsigned long *ul; + float *f; + double *d; + size_t p; + } to, from; + + /* Repackage the aggregate from its parts. The + aggregate size is not greater than the space taken by + the registers so store back to the register/parameter + save arrays. */ + if (pfr + elnum <= end_pfr) + to.v = pfr; + else + to.v = pst; + + avalue[i] = to.v; + from.ul = pst; + if (elt == FFI_TYPE_FLOAT) + { + do + { + if (pfr < end_pfr && i < nfixedargs) + { + *to.f = (float) pfr->d; + pfr++; + } + else + *to.f = *from.f; + to.f++; + from.f++; + } + while (--elnum != 0); + } + else + { + do + { + if (pfr < end_pfr && i < nfixedargs) + { + *to.d = pfr->d; + pfr++; + } + else + *to.d = *from.d; + to.d++; + from.d++; + } + while (--elnum != 0); + } + } + else + { +#ifndef __LITTLE_ENDIAN__ + /* Structures with size less than eight bytes are passed + left-padded. */ + if (arg_types[i]->size < 8) + avalue[i] = (char *) pst + 8 - arg_types[i]->size; + else +#endif + avalue[i] = pst; + } + pst += (arg_types[i]->size + 7) / 8; + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + if (pfr + 1 < end_pfr && i + 1 < nfixedargs) + { + avalue[i] = pfr; + pfr += 2; + } + else + { + if (pfr < end_pfr && i < nfixedargs) + { + /* Passed partly in f13 and partly on the stack. + Move it all to the stack. */ + *pst = *(unsigned long *) pfr; + pfr++; + } + avalue[i] = pst; + } + pst += 2; + break; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + /* On the outgoing stack all values are aligned to 8 */ + /* there are 13 64bit floating point registers */ + + if (pfr < end_pfr && i < nfixedargs) + { + avalue[i] = pfr; + pfr++; + } + else + avalue[i] = pst; + pst++; + break; + + case FFI_TYPE_FLOAT: + if (pfr < end_pfr && i < nfixedargs) + { + /* Float values are stored as doubles in the + ffi_closure_LINUX64 code. Fix them here. */ + pfr->f = (float) pfr->d; + avalue[i] = pfr; + pfr++; + } + else + avalue[i] = pst; + pst++; + break; + + default: + FFI_ASSERT (0); + } + + i++; + } + + (*fun) (cif, rvalue, avalue, user_data); + + /* Tell ffi_closure_LINUX64 how to perform return type promotions. */ + if ((cif->flags & FLAG_RETURNS_SMST) != 0) + { + if ((cif->flags & FLAG_RETURNS_FP) == 0) + return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1; + else if ((cif->flags & FLAG_RETURNS_64BITS) != 0) + return FFI_V2_TYPE_DOUBLE_HOMOG; + else + return FFI_V2_TYPE_FLOAT_HOMOG; + } + return cif->rtype->type; +} +#endif diff --git a/circuitpython/lib/libffi/src/powerpc/ffi_powerpc.h b/circuitpython/lib/libffi/src/powerpc/ffi_powerpc.h new file mode 100644 index 0000000..3dcd6b5 --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/ffi_powerpc.h @@ -0,0 +1,94 @@ +/* ----------------------------------------------------------------------- + ffi_powerpc.h - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC Foreign Function Interface + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + +enum { + /* The assembly depends on these exact flags. */ + /* These go in cr7 */ + FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */ + FLAG_RETURNS_NOTHING = 1 << (31-30), + FLAG_RETURNS_FP = 1 << (31-29), + FLAG_RETURNS_64BITS = 1 << (31-28), + + /* This goes in cr6 */ + FLAG_RETURNS_128BITS = 1 << (31-27), + + FLAG_COMPAT = 1 << (31- 8), /* Not used by assembly */ + + /* These go in cr1 */ + FLAG_ARG_NEEDS_COPY = 1 << (31- 7), /* Used by sysv code */ + FLAG_ARG_NEEDS_PSAVE = FLAG_ARG_NEEDS_COPY, /* Used by linux64 code */ + FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ + FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), + FLAG_RETVAL_REFERENCE = 1 << (31- 4) +}; + +typedef union +{ + float f; + double d; +} ffi_dblfl; + +void FFI_HIDDEN ffi_closure_SYSV (void); +void FFI_HIDDEN ffi_go_closure_sysv (void); +void FFI_HIDDEN ffi_call_SYSV(extended_cif *, void (*)(void), void *, + unsigned, void *, int); + +void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi); +ffi_status FFI_HIDDEN ffi_prep_cif_sysv (ffi_cif *); +ffi_status FFI_HIDDEN ffi_prep_closure_loc_sysv (ffi_closure *, + ffi_cif *, + void (*) (ffi_cif *, void *, + void **, void *), + void *, void *); +int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_cif *, + void (*) (ffi_cif *, void *, + void **, void *), + void *, void *, unsigned long *, + ffi_dblfl *, unsigned long *); + +void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, void (*) (void), void *, + unsigned long, void *, long); +void FFI_HIDDEN ffi_closure_LINUX64 (void); +void FFI_HIDDEN ffi_go_closure_linux64 (void); + +void FFI_HIDDEN ffi_prep_types_linux64 (ffi_abi); +ffi_status FFI_HIDDEN ffi_prep_cif_linux64 (ffi_cif *); +ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int, + unsigned int); +void FFI_HIDDEN ffi_prep_args64 (extended_cif *, unsigned long *const); +ffi_status FFI_HIDDEN ffi_prep_closure_loc_linux64 (ffi_closure *, ffi_cif *, + void (*) (ffi_cif *, void *, + void **, void *), + void *, void *); +int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_cif *, + void (*) (ffi_cif *, void *, + void **, void *), + void *, void *, + unsigned long *, ffi_dblfl *); diff --git a/circuitpython/lib/libffi/src/powerpc/ffi_sysv.c b/circuitpython/lib/libffi/src/powerpc/ffi_sysv.c new file mode 100644 index 0000000..646c340 --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/ffi_sysv.c @@ -0,0 +1,934 @@ +/* ----------------------------------------------------------------------- + ffi_sysv.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC Foreign Function Interface + + 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 AUTHOR 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 "ffi.h" + +#ifndef POWERPC64 +#include "ffi_common.h" +#include "ffi_powerpc.h" + + +/* About the SYSV ABI. */ +#define ASM_NEEDS_REGISTERS 6 +#define NUM_GPR_ARG_REGISTERS 8 +#define NUM_FPR_ARG_REGISTERS 8 + + +#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +/* Adjust size of ffi_type_longdouble. */ +void FFI_HIDDEN +ffi_prep_types_sysv (ffi_abi abi) +{ + if ((abi & (FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128)) == FFI_SYSV) + { + ffi_type_longdouble.size = 8; + ffi_type_longdouble.alignment = 8; + } + else + { + ffi_type_longdouble.size = 16; + ffi_type_longdouble.alignment = 16; + } +} +#endif + +/* Transform long double, double and float to other types as per abi. */ +static int +translate_float (int abi, int type) +{ +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (type == FFI_TYPE_LONGDOUBLE + && (abi & FFI_SYSV_LONG_DOUBLE_128) == 0) + type = FFI_TYPE_DOUBLE; +#endif + if ((abi & FFI_SYSV_SOFT_FLOAT) != 0) + { + if (type == FFI_TYPE_FLOAT) + type = FFI_TYPE_UINT32; + else if (type == FFI_TYPE_DOUBLE) + type = FFI_TYPE_UINT64; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + else if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_UINT128; + } + else if ((abi & FFI_SYSV_IBM_LONG_DOUBLE) == 0) + { + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + } + return type; +} + +/* Perform machine dependent cif processing */ +static ffi_status +ffi_prep_cif_sysv_core (ffi_cif *cif) +{ + ffi_type **ptr; + unsigned bytes; + unsigned i, fparg_count = 0, intarg_count = 0; + unsigned flags = cif->flags; + unsigned struct_copy_size = 0; + unsigned type = cif->rtype->type; + unsigned size = cif->rtype->size; + + /* The machine-independent calculation of cif->bytes doesn't work + for us. Redo the calculation. */ + + /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ + bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int); + + /* Space for the GPR registers. */ + bytes += NUM_GPR_ARG_REGISTERS * sizeof (int); + + /* Return value handling. The rules for SYSV are as follows: + - 32-bit (or less) integer values are returned in gpr3; + - Structures of size <= 4 bytes also returned in gpr3; + - 64-bit integer values and structures between 5 and 8 bytes are returned + in gpr3 and gpr4; + - Larger structures are allocated space and a pointer is passed as + the first argument. + - Single/double FP values are returned in fpr1; + - long doubles (if not equivalent to double) are returned in + fpr1,fpr2 for Linux and as for large structs for SysV. */ + + type = translate_float (cif->abi, type); + + switch (type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + flags |= FLAG_RETURNS_64BITS; + /* Fall through. */ + case FFI_TYPE_FLOAT: + flags |= FLAG_RETURNS_FP; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_UINT128: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags |= FLAG_RETURNS_64BITS; + break; + + case FFI_TYPE_STRUCT: + /* The final SYSV ABI says that structures smaller or equal 8 bytes + are returned in r3/r4. A draft ABI used by linux instead + returns them in memory. */ + if ((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8) + { + flags |= FLAG_RETURNS_SMST; + break; + } + intarg_count++; + flags |= FLAG_RETVAL_REFERENCE; + /* Fall through. */ + case FFI_TYPE_VOID: + flags |= FLAG_RETURNS_NOTHING; + break; + + default: + /* Returns 32-bit integer, or similar. Nothing to do here. */ + break; + } + + /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the + first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest + goes on the stack. Structures and long doubles (if not equivalent + to double) are passed as a pointer to a copy of the structure. + Stuff on the stack needs to keep proper alignment. */ + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + unsigned short typenum = (*ptr)->type; + + typenum = translate_float (cif->abi, typenum); + + switch (typenum) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + fparg_count++; + /* Fall thru */ +#endif + case FFI_TYPE_DOUBLE: + fparg_count++; + /* If this FP arg is going on the stack, it must be + 8-byte-aligned. */ + if (fparg_count > NUM_FPR_ARG_REGISTERS + && intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + intarg_count++; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_FLOAT: + fparg_count++; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_UINT128: + /* A long double in FFI_LINUX_SOFT_FLOAT can use only a set + of four consecutive gprs. If we do not have enough, we + have to adjust the intarg_count value. */ + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3 + && intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count = NUM_GPR_ARG_REGISTERS; + intarg_count += 4; + break; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + /* 'long long' arguments are passed as two words, but + either both words must fit in registers or both go + on the stack. If they go on the stack, they must + be 8-byte-aligned. + + Also, only certain register pairs can be used for + passing long long int -- specifically (r3,r4), (r5,r6), + (r7,r8), (r9,r10). */ + if (intarg_count == NUM_GPR_ARG_REGISTERS-1 + || intarg_count % 2 != 0) + intarg_count++; + intarg_count += 2; + break; + + case FFI_TYPE_STRUCT: + /* We must allocate space for a copy of these to enforce + pass-by-value. Pad the space up to a multiple of 16 + bytes (the maximum alignment required for anything under + the SYSV ABI). */ + struct_copy_size += ((*ptr)->size + 15) & ~0xF; + /* Fall through (allocate space for the pointer). */ + + case FFI_TYPE_POINTER: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + /* Everything else is passed as a 4-byte word in a GPR, either + the object itself or a pointer to it. */ + intarg_count++; + break; + + default: + FFI_ASSERT (0); + } + } + + if (fparg_count != 0) + flags |= FLAG_FP_ARGUMENTS; + if (intarg_count > 4) + flags |= FLAG_4_GPR_ARGUMENTS; + if (struct_copy_size != 0) + flags |= FLAG_ARG_NEEDS_COPY; + + /* Space for the FPR registers, if needed. */ + if (fparg_count != 0) + bytes += NUM_FPR_ARG_REGISTERS * sizeof (double); + + /* Stack space. */ + if (intarg_count > NUM_GPR_ARG_REGISTERS) + bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int); + if (fparg_count > NUM_FPR_ARG_REGISTERS) + bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double); + + /* The stack space allocated needs to be a multiple of 16 bytes. */ + bytes = (bytes + 15) & ~0xF; + + /* Add in the space for the copied structures. */ + bytes += struct_copy_size; + + cif->flags = flags; + cif->bytes = bytes; + + return FFI_OK; +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_sysv (ffi_cif *cif) +{ + if ((cif->abi & FFI_SYSV) == 0) + { + /* This call is from old code. Translate to new ABI values. */ + cif->flags |= FLAG_COMPAT; + switch (cif->abi) + { + default: + return FFI_BAD_ABI; + + case FFI_COMPAT_SYSV: + cif->abi = FFI_SYSV | FFI_SYSV_STRUCT_RET | FFI_SYSV_LONG_DOUBLE_128; + break; + + case FFI_COMPAT_GCC_SYSV: + cif->abi = FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128; + break; + + case FFI_COMPAT_LINUX: + cif->abi = (FFI_SYSV | FFI_SYSV_IBM_LONG_DOUBLE + | FFI_SYSV_LONG_DOUBLE_128); + break; + + case FFI_COMPAT_LINUX_SOFT_FLOAT: + cif->abi = (FFI_SYSV | FFI_SYSV_SOFT_FLOAT | FFI_SYSV_IBM_LONG_DOUBLE + | FFI_SYSV_LONG_DOUBLE_128); + break; + } + } + return ffi_prep_cif_sysv_core (cif); +} + +/* ffi_prep_args_SYSV is called by the assembly routine once stack space + has been allocated for the function's arguments. + + The stack layout we want looks like this: + + | Return address from ffi_call_SYSV 4bytes | higher addresses + |--------------------------------------------| + | Previous backchain pointer 4 | stack pointer here + |--------------------------------------------|<+ <<< on entry to + | Saved r28-r31 4*4 | | ffi_call_SYSV + |--------------------------------------------| | + | GPR registers r3-r10 8*4 | | ffi_call_SYSV + |--------------------------------------------| | + | FPR registers f1-f8 (optional) 8*8 | | + |--------------------------------------------| | stack | + | Space for copied structures | | grows | + |--------------------------------------------| | down V + | Parameters that didn't fit in registers | | + |--------------------------------------------| | lower addresses + | Space for callee's LR 4 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 4 |-/ during + |--------------------------------------------| <<< ffi_call_SYSV + +*/ + +void FFI_HIDDEN +ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack) +{ + const unsigned bytes = ecif->cif->bytes; + const unsigned flags = ecif->cif->flags; + + typedef union + { + char *c; + unsigned *u; + long long *ll; + float *f; + double *d; + } valp; + + /* 'stacktop' points at the previous backchain pointer. */ + valp stacktop; + + /* 'gpr_base' points at the space for gpr3, and grows upwards as + we use GPR registers. */ + valp gpr_base; + int intarg_count; + +#ifndef __NO_FPRS__ + /* 'fpr_base' points at the space for fpr1, and grows upwards as + we use FPR registers. */ + valp fpr_base; + int fparg_count; +#endif + + /* 'copy_space' grows down as we put structures in it. It should + stay 16-byte aligned. */ + valp copy_space; + + /* 'next_arg' grows up as we put parameters in it. */ + valp next_arg; + + int i; + ffi_type **ptr; +#ifndef __NO_FPRS__ + double double_tmp; +#endif + union + { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + unsigned int **ui; + long long **ll; + float **f; + double **d; + } p_argv; + size_t struct_copy_size; + unsigned gprvalue; + + stacktop.c = (char *) stack + bytes; + gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; + intarg_count = 0; +#ifndef __NO_FPRS__ + fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS; + fparg_count = 0; + copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c); +#else + copy_space.c = gpr_base.c; +#endif + next_arg.u = stack + 2; + + /* Check that everything starts aligned properly. */ + FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0); + FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); + FFI_ASSERT ((bytes & 0xF) == 0); + FFI_ASSERT (copy_space.c >= next_arg.c); + + /* Deal with return values that are actually pass-by-reference. */ + if (flags & FLAG_RETVAL_REFERENCE) + { + *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue; + intarg_count++; + } + + /* Now for the arguments. */ + p_argv.v = ecif->avalue; + for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; + i > 0; + i--, ptr++, p_argv.v++) + { + unsigned int typenum = (*ptr)->type; + + typenum = translate_float (ecif->cif->abi, typenum); + + /* Now test the translated value */ + switch (typenum) + { +#ifndef __NO_FPRS__ +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + double_tmp = (*p_argv.d)[0]; + + if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1) + { + if (intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.d = double_tmp; + next_arg.u += 2; + double_tmp = (*p_argv.d)[1]; + *next_arg.d = double_tmp; + next_arg.u += 2; + } + else + { + *fpr_base.d++ = double_tmp; + double_tmp = (*p_argv.d)[1]; + *fpr_base.d++ = double_tmp; + } + + fparg_count += 2; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; +# endif + case FFI_TYPE_DOUBLE: + double_tmp = **p_argv.d; + + if (fparg_count >= NUM_FPR_ARG_REGISTERS) + { + if (intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.d = double_tmp; + next_arg.u += 2; + } + else + *fpr_base.d++ = double_tmp; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_FLOAT: + double_tmp = **p_argv.f; + if (fparg_count >= NUM_FPR_ARG_REGISTERS) + { + *next_arg.f = (float) double_tmp; + next_arg.u += 1; + intarg_count++; + } + else + *fpr_base.d++ = double_tmp; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; +#endif /* have FPRs */ + + case FFI_TYPE_UINT128: + /* The soft float ABI for long doubles works like this, a long double + is passed in four consecutive GPRs if available. A maximum of 2 + long doubles can be passed in gprs. If we do not have 4 GPRs + left, the long double is passed on the stack, 4-byte aligned. */ + { + unsigned int int_tmp; + unsigned int ii; + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) + { + if (intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count = NUM_GPR_ARG_REGISTERS; + for (ii = 0; ii < 4; ii++) + { + int_tmp = (*p_argv.ui)[ii]; + *next_arg.u++ = int_tmp; + } + } + else + { + for (ii = 0; ii < 4; ii++) + { + int_tmp = (*p_argv.ui)[ii]; + *gpr_base.u++ = int_tmp; + } + } + intarg_count += 4; + break; + } + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + if (intarg_count == NUM_GPR_ARG_REGISTERS-1) + intarg_count++; + if (intarg_count >= NUM_GPR_ARG_REGISTERS) + { + if (intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.ll = **p_argv.ll; + next_arg.u += 2; + } + else + { + /* The abi states only certain register pairs can be + used for passing long long int specifically (r3,r4), + (r5,r6), (r7,r8), (r9,r10). If next arg is long long + but not correct starting register of pair then skip + until the proper starting register. */ + if (intarg_count % 2 != 0) + { + intarg_count ++; + gpr_base.u++; + } + *gpr_base.ll++ = **p_argv.ll; + } + intarg_count += 2; + break; + + case FFI_TYPE_STRUCT: + struct_copy_size = ((*ptr)->size + 15) & ~0xF; + copy_space.c -= struct_copy_size; + memcpy (copy_space.c, *p_argv.c, (*ptr)->size); + + gprvalue = (unsigned long) copy_space.c; + + FFI_ASSERT (copy_space.c > next_arg.c); + FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY); + goto putgpr; + + case FFI_TYPE_UINT8: + gprvalue = **p_argv.uc; + goto putgpr; + case FFI_TYPE_SINT8: + gprvalue = **p_argv.sc; + goto putgpr; + case FFI_TYPE_UINT16: + gprvalue = **p_argv.us; + goto putgpr; + case FFI_TYPE_SINT16: + gprvalue = **p_argv.ss; + goto putgpr; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + + gprvalue = **p_argv.ui; + + putgpr: + if (intarg_count >= NUM_GPR_ARG_REGISTERS) + *next_arg.u++ = gprvalue; + else + *gpr_base.u++ = gprvalue; + intarg_count++; + break; + } + } + + /* Check that we didn't overrun the stack... */ + FFI_ASSERT (copy_space.c >= next_arg.c); + FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS); + /* The assert below is testing that the number of integer arguments agrees + with the number found in ffi_prep_cif_machdep(). However, intarg_count + is incremented whenever we place an FP arg on the stack, so account for + that before our assert test. */ +#ifndef __NO_FPRS__ + if (fparg_count > NUM_FPR_ARG_REGISTERS) + intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS; + FFI_ASSERT (fpr_base.u + <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); +#endif + FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); +} + +#define MIN_CACHE_LINE_SIZE 8 + +static void +flush_icache (char *wraddr, char *xaddr, int size) +{ + int i; + for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" + : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" + : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) + : "memory"); +} + +ffi_status FFI_HIDDEN +ffi_prep_closure_loc_sysv (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) +{ + unsigned int *tramp; + + if (cif->abi < FFI_SYSV || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + tramp = (unsigned int *) &closure->tramp[0]; + tramp[0] = 0x7c0802a6; /* mflr r0 */ + tramp[1] = 0x429f0005; /* bcl 20,31,.+4 */ + tramp[2] = 0x7d6802a6; /* mflr r11 */ + tramp[3] = 0x7c0803a6; /* mtlr r0 */ + tramp[4] = 0x800b0018; /* lwz r0,24(r11) */ + tramp[5] = 0x816b001c; /* lwz r11,28(r11) */ + tramp[6] = 0x7c0903a6; /* mtctr r0 */ + tramp[7] = 0x4e800420; /* bctr */ + *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */ + *(void **) &tramp[9] = codeloc; /* context */ + + /* Flush the icache. */ + flush_icache ((char *)tramp, (char *)codeloc, 8 * 4); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +/* Basically the trampoline invokes ffi_closure_SYSV, and on + entry, r11 holds the address of the closure. + After storing the registers that could possibly contain + parameters to be passed into the stack frame and setting + up space for a return value, ffi_closure_SYSV invokes the + following helper function to do most of the work. */ + +int +ffi_closure_helper_SYSV (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *rvalue, + unsigned long *pgr, + ffi_dblfl *pfr, + unsigned long *pst) +{ + /* rvalue is the pointer to space for return value in closure assembly */ + /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */ + /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */ + /* pst is the pointer to outgoing parameter stack in original caller */ + + void ** avalue; + ffi_type ** arg_types; + long i, avn; +#ifndef __NO_FPRS__ + long nf = 0; /* number of floating registers already used */ +#endif + long ng = 0; /* number of general registers already used */ + + unsigned size = cif->rtype->size; + unsigned short rtypenum = cif->rtype->type; + + avalue = alloca (cif->nargs * sizeof (void *)); + + /* First translate for softfloat/nonlinux */ + rtypenum = translate_float (cif->abi, rtypenum); + + /* Copy the caller's structure return value address so that the closure + returns the data directly to the caller. + For FFI_SYSV the result is passed in r3/r4 if the struct size is less + or equal 8 bytes. */ + if (rtypenum == FFI_TYPE_STRUCT + && !((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)) + { + rvalue = (void *) *pgr; + ng++; + pgr++; + } + + i = 0; + avn = cif->nargs; + arg_types = cif->arg_types; + + /* Grab the addresses of the arguments from the stack frame. */ + while (i < avn) { + unsigned short typenum = arg_types[i]->type; + + /* We may need to handle some values depending on ABI. */ + typenum = translate_float (cif->abi, typenum); + + switch (typenum) + { +#ifndef __NO_FPRS__ + case FFI_TYPE_FLOAT: + /* Unfortunately float values are stored as doubles + in the ffi_closure_SYSV code (since we don't check + the type in that routine). */ + if (nf < NUM_FPR_ARG_REGISTERS) + { + /* FIXME? here we are really changing the values + stored in the original calling routines outgoing + parameter stack. This is probably a really + naughty thing to do but... */ + double temp = pfr->d; + pfr->f = (float) temp; + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + avalue[i] = pst; + pst += 1; + } + break; + + case FFI_TYPE_DOUBLE: + if (nf < NUM_FPR_ARG_REGISTERS) + { + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; + } + break; + +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if (nf < NUM_FPR_ARG_REGISTERS - 1) + { + avalue[i] = pfr; + pfr += 2; + nf += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 4; + nf = 8; + } + break; +# endif +#endif + + case FFI_TYPE_UINT128: + /* Test if for the whole long double, 4 gprs are available. + otherwise the stuff ends up on the stack. */ + if (ng < NUM_GPR_ARG_REGISTERS - 3) + { + avalue[i] = pgr; + pgr += 4; + ng += 4; + } + else + { + avalue[i] = pst; + pst += 4; + ng = 8+4; + } + break; + + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (char *) pgr + 3; + ng++; + pgr++; + } + else + { + avalue[i] = (char *) pst + 3; + pst++; + } + break; +#endif + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (char *) pgr + 2; + ng++; + pgr++; + } + else + { + avalue[i] = (char *) pst + 2; + pst++; + } + break; +#endif + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = pgr; + ng++; + pgr++; + } + else + { + avalue[i] = pst; + pst++; + } + break; + + case FFI_TYPE_STRUCT: + /* Structs are passed by reference. The address will appear in a + gpr if it is one of the first 8 arguments. */ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (void *) *pgr; + ng++; + pgr++; + } + else + { + avalue[i] = (void *) *pst; + pst++; + } + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + /* Passing long long ints are complex, they must + be passed in suitable register pairs such as + (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) + and if the entire pair aren't available then the outgoing + parameter stack is used for both but an alignment of 8 + must will be kept. So we must either look in pgr + or pst to find the correct address for this type + of parameter. */ + if (ng < NUM_GPR_ARG_REGISTERS - 1) + { + if (ng & 1) + { + /* skip r4, r6, r8 as starting points */ + ng++; + pgr++; + } + avalue[i] = pgr; + ng += 2; + pgr += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; + ng = NUM_GPR_ARG_REGISTERS; + } + break; + + default: + FFI_ASSERT (0); + } + + i++; + } + + (*fun) (cif, rvalue, avalue, user_data); + + /* Tell ffi_closure_SYSV how to perform return type promotions. + Because the FFI_SYSV ABI returns the structures <= 8 bytes in + r3/r4 we have to tell ffi_closure_SYSV how to treat them. We + combine the base type FFI_SYSV_TYPE_SMALL_STRUCT with the size of + the struct less one. We never have a struct with size zero. + See the comment in ffitarget.h about ordering. */ + if (rtypenum == FFI_TYPE_STRUCT + && (cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8) + return FFI_SYSV_TYPE_SMALL_STRUCT - 1 + size; + return rtypenum; +} +#endif diff --git a/circuitpython/lib/libffi/src/powerpc/ffitarget.h b/circuitpython/lib/libffi/src/powerpc/ffitarget.h new file mode 100644 index 0000000..0f66d31 --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/ffitarget.h @@ -0,0 +1,195 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc + Copyright (c) 1996-2003 Red Hat, Inc. + + Target configuration macros for PowerPC. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- System specific configurations ----------------------------------- */ + +#if defined (POWERPC) && defined (__powerpc64__) /* linux64 */ +#ifndef POWERPC64 +#define POWERPC64 +#endif +#elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin64 */ +#ifndef POWERPC64 +#define POWERPC64 +#endif +#ifndef POWERPC_DARWIN64 +#define POWERPC_DARWIN64 +#endif +#elif defined (POWERPC_AIX) && defined (__64BIT__) /* AIX64 */ +#ifndef POWERPC64 +#define POWERPC64 +#endif +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + +#if defined (POWERPC_AIX) + FFI_AIX, + FFI_DARWIN, + FFI_DEFAULT_ABI = FFI_AIX, + FFI_LAST_ABI + +#elif defined (POWERPC_DARWIN) + FFI_AIX, + FFI_DARWIN, + FFI_DEFAULT_ABI = FFI_DARWIN, + FFI_LAST_ABI + +#else + /* The FFI_COMPAT values are used by old code. Since libffi may be + a shared library we have to support old values for backwards + compatibility. */ + FFI_COMPAT_SYSV, + FFI_COMPAT_GCC_SYSV, + FFI_COMPAT_LINUX64, + FFI_COMPAT_LINUX, + FFI_COMPAT_LINUX_SOFT_FLOAT, + +# if defined (POWERPC64) + /* This bit, always set in new code, must not be set in any of the + old FFI_COMPAT values that might be used for 64-bit linux. We + only need worry about FFI_COMPAT_LINUX64, but to be safe avoid + all old values. */ + FFI_LINUX = 8, + /* This and following bits can reuse FFI_COMPAT values. */ + FFI_LINUX_STRUCT_ALIGN = 1, + FFI_LINUX_LONG_DOUBLE_128 = 2, + FFI_DEFAULT_ABI = (FFI_LINUX +# ifdef __STRUCT_PARM_ALIGN__ + | FFI_LINUX_STRUCT_ALIGN +# endif +# ifdef __LONG_DOUBLE_128__ + | FFI_LINUX_LONG_DOUBLE_128 +# endif + ), + FFI_LAST_ABI = 12 + +# else + /* This bit, always set in new code, must not be set in any of the + old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd. */ + FFI_SYSV = 8, + /* This and following bits can reuse FFI_COMPAT values. */ + FFI_SYSV_SOFT_FLOAT = 1, + FFI_SYSV_STRUCT_RET = 2, + FFI_SYSV_IBM_LONG_DOUBLE = 4, + FFI_SYSV_LONG_DOUBLE_128 = 16, + + FFI_DEFAULT_ABI = (FFI_SYSV +# ifdef __NO_FPRS__ + | FFI_SYSV_SOFT_FLOAT +# endif +# if (defined (__SVR4_STRUCT_RETURN) \ + || defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN)) + | FFI_SYSV_STRUCT_RET +# endif +# if __LDBL_MANT_DIG__ == 106 + | FFI_SYSV_IBM_LONG_DOUBLE +# endif +# ifdef __LONG_DOUBLE_128__ + | FFI_SYSV_LONG_DOUBLE_128 +# endif + ), + FFI_LAST_ABI = 32 +# endif +#endif + +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 +#if defined (POWERPC) || defined (POWERPC_FREEBSD) +# define FFI_GO_CLOSURES 1 +# define FFI_TARGET_SPECIFIC_VARIADIC 1 +# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs +#endif + +/* ppc_closure.S and linux64_closure.S expect this. */ +#define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER + +/* We define additional types below. If generic types are added that + must be supported by powerpc libffi then it is likely that + FFI_PPC_TYPE_LAST needs increasing *and* the jump tables in + ppc_closure.S and linux64_closure.S be extended. */ + +#if !(FFI_TYPE_LAST == FFI_PPC_TYPE_LAST \ + || (FFI_TYPE_LAST == FFI_TYPE_COMPLEX \ + && !defined FFI_TARGET_HAS_COMPLEX_TYPE)) +# error "You likely have a broken powerpc libffi" +#endif + +/* Needed for soft-float long-double-128 support. */ +#define FFI_TYPE_UINT128 (FFI_PPC_TYPE_LAST + 1) + +/* Needed for FFI_SYSV small structure returns. */ +#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 2) + +/* Used by ELFv2 for homogenous structure returns. */ +#define FFI_V2_TYPE_FLOAT_HOMOG (FFI_PPC_TYPE_LAST + 1) +#define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_PPC_TYPE_LAST + 2) +#define FFI_V2_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 3) + +#if _CALL_ELF == 2 +# define FFI_TRAMPOLINE_SIZE 32 +#else +# if defined(POWERPC64) || defined(POWERPC_AIX) +# if defined(POWERPC_DARWIN64) +# define FFI_TRAMPOLINE_SIZE 48 +# else +# define FFI_TRAMPOLINE_SIZE 24 +# endif +# else /* POWERPC || POWERPC_AIX */ +# define FFI_TRAMPOLINE_SIZE 40 +# endif +#endif + +#ifndef LIBFFI_ASM +#if defined(POWERPC_DARWIN) || defined(POWERPC_AIX) +struct ffi_aix_trampoline_struct { + void * code_pointer; /* Pointer to ffi_closure_ASM */ + void * toc; /* TOC */ + void * static_chain; /* Pointer to closure */ +}; +#endif +#endif + +#endif diff --git a/circuitpython/lib/libffi/src/powerpc/linux64.S b/circuitpython/lib/libffi/src/powerpc/linux64.S new file mode 100644 index 0000000..b2ae60e --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/linux64.S @@ -0,0 +1,228 @@ +/* ----------------------------------------------------------------------- + sysv.h - Copyright (c) 2003 Jakub Jelinek + Copyright (c) 2008 Red Hat, Inc. + + PowerPC64 Assembly glue. + + 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 LIBFFI_ASM +#include +#include + +#ifdef POWERPC64 + .hidden ffi_call_LINUX64 + .globl ffi_call_LINUX64 + .text + .cfi_startproc +# if _CALL_ELF == 2 +ffi_call_LINUX64: + addis %r2, %r12, .TOC.-ffi_call_LINUX64@ha + addi %r2, %r2, .TOC.-ffi_call_LINUX64@l + .localentry ffi_call_LINUX64, . - ffi_call_LINUX64 +# else + .section ".opd","aw" + .align 3 +ffi_call_LINUX64: +# ifdef _CALL_LINUX + .quad .L.ffi_call_LINUX64,.TOC.@tocbase,0 + .type ffi_call_LINUX64,@function + .text +.L.ffi_call_LINUX64: +# else + .hidden .ffi_call_LINUX64 + .globl .ffi_call_LINUX64 + .quad .ffi_call_LINUX64,.TOC.@tocbase,0 + .size ffi_call_LINUX64,24 + .type .ffi_call_LINUX64,@function + .text +.ffi_call_LINUX64: +# endif +# endif + mflr %r0 + std %r28, -32(%r1) + std %r29, -24(%r1) + std %r30, -16(%r1) + std %r31, -8(%r1) + std %r7, 8(%r1) /* closure, saved in cr field. */ + std %r0, 16(%r1) + + mr %r28, %r1 /* our AP. */ + .cfi_def_cfa_register 28 + .cfi_offset 65, 16 + .cfi_offset 31, -8 + .cfi_offset 30, -16 + .cfi_offset 29, -24 + .cfi_offset 28, -32 + + stdux %r1, %r1, %r8 + mr %r31, %r6 /* flags, */ + mr %r30, %r5 /* rvalue, */ + mr %r29, %r4 /* function address. */ +/* Save toc pointer, not for the ffi_prep_args64 call, but for the later + bctrl function call. */ +# if _CALL_ELF == 2 + std %r2, 24(%r1) +# else + std %r2, 40(%r1) +# endif + + /* Call ffi_prep_args64. */ + mr %r4, %r1 +# if defined _CALL_LINUX || _CALL_ELF == 2 + bl ffi_prep_args64 +# else + bl .ffi_prep_args64 +# endif + +# if _CALL_ELF == 2 + mr %r12, %r29 +# else + ld %r12, 0(%r29) + ld %r2, 8(%r29) +# endif + /* Now do the call. */ + /* Set up cr1 with bits 4-7 of the flags. */ + mtcrf 0x40, %r31 + + /* Get the address to call into CTR. */ + mtctr %r12 + /* Load all those argument registers. */ + ld %r3, -32-(8*8)(%r28) + ld %r4, -32-(7*8)(%r28) + ld %r5, -32-(6*8)(%r28) + ld %r6, -32-(5*8)(%r28) + bf- 5, 1f + ld %r7, -32-(4*8)(%r28) + ld %r8, -32-(3*8)(%r28) + ld %r9, -32-(2*8)(%r28) + ld %r10, -32-(1*8)(%r28) +1: + + /* Load all the FP registers. */ + bf- 6, 2f + lfd %f1, -32-(21*8)(%r28) + lfd %f2, -32-(20*8)(%r28) + lfd %f3, -32-(19*8)(%r28) + lfd %f4, -32-(18*8)(%r28) + lfd %f5, -32-(17*8)(%r28) + lfd %f6, -32-(16*8)(%r28) + lfd %f7, -32-(15*8)(%r28) + lfd %f8, -32-(14*8)(%r28) + lfd %f9, -32-(13*8)(%r28) + lfd %f10, -32-(12*8)(%r28) + lfd %f11, -32-(11*8)(%r28) + lfd %f12, -32-(10*8)(%r28) + lfd %f13, -32-(9*8)(%r28) +2: + + /* Make the call. */ + ld %r11, 8(%r28) + bctrl + + /* This must follow the call immediately, the unwinder + uses this to find out if r2 has been saved or not. */ +# if _CALL_ELF == 2 + ld %r2, 24(%r1) +# else + ld %r2, 40(%r1) +# endif + + /* Now, deal with the return value. */ + mtcrf 0x01, %r31 + bt 31, .Lstruct_return_value + bt 30, .Ldone_return_value + bt 29, .Lfp_return_value + std %r3, 0(%r30) + /* Fall through... */ + +.Ldone_return_value: + /* Restore the registers we used and return. */ + mr %r1, %r28 + .cfi_def_cfa_register 1 + ld %r0, 16(%r28) + ld %r28, -32(%r28) + mtlr %r0 + ld %r29, -24(%r1) + ld %r30, -16(%r1) + ld %r31, -8(%r1) + blr + +.Lfp_return_value: + .cfi_def_cfa_register 28 + bf 28, .Lfloat_return_value + stfd %f1, 0(%r30) + mtcrf 0x02, %r31 /* cr6 */ + bf 27, .Ldone_return_value + stfd %f2, 8(%r30) + b .Ldone_return_value +.Lfloat_return_value: + stfs %f1, 0(%r30) + b .Ldone_return_value + +.Lstruct_return_value: + bf 29, .Lsmall_struct + bf 28, .Lfloat_homog_return_value + stfd %f1, 0(%r30) + stfd %f2, 8(%r30) + stfd %f3, 16(%r30) + stfd %f4, 24(%r30) + stfd %f5, 32(%r30) + stfd %f6, 40(%r30) + stfd %f7, 48(%r30) + stfd %f8, 56(%r30) + b .Ldone_return_value + +.Lfloat_homog_return_value: + stfs %f1, 0(%r30) + stfs %f2, 4(%r30) + stfs %f3, 8(%r30) + stfs %f4, 12(%r30) + stfs %f5, 16(%r30) + stfs %f6, 20(%r30) + stfs %f7, 24(%r30) + stfs %f8, 28(%r30) + b .Ldone_return_value + +.Lsmall_struct: + std %r3, 0(%r30) + std %r4, 8(%r30) + b .Ldone_return_value + + .cfi_endproc +# if _CALL_ELF == 2 + .size ffi_call_LINUX64,.-ffi_call_LINUX64 +# else +# ifdef _CALL_LINUX + .size ffi_call_LINUX64,.-.L.ffi_call_LINUX64 +# else + .long 0 + .byte 0,12,0,1,128,4,0,0 + .size .ffi_call_LINUX64,.-.ffi_call_LINUX64 +# endif +# endif + +#endif + +#if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/powerpc/linux64_closure.S b/circuitpython/lib/libffi/src/powerpc/linux64_closure.S new file mode 100644 index 0000000..6487d2a --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/linux64_closure.S @@ -0,0 +1,488 @@ +/* ----------------------------------------------------------------------- + sysv.h - Copyright (c) 2003 Jakub Jelinek + Copyright (c) 2008 Red Hat, Inc. + + PowerPC64 Assembly glue. + + 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 LIBFFI_ASM +#include +#include + + .file "linux64_closure.S" + +#ifdef POWERPC64 + FFI_HIDDEN (ffi_closure_LINUX64) + .globl ffi_closure_LINUX64 + .text + .cfi_startproc +# if _CALL_ELF == 2 +ffi_closure_LINUX64: + addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha + addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l + .localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64 +# else + .section ".opd","aw" + .align 3 +ffi_closure_LINUX64: +# ifdef _CALL_LINUX + .quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0 + .type ffi_closure_LINUX64,@function + .text +.L.ffi_closure_LINUX64: +# else + FFI_HIDDEN (.ffi_closure_LINUX64) + .globl .ffi_closure_LINUX64 + .quad .ffi_closure_LINUX64,.TOC.@tocbase,0 + .size ffi_closure_LINUX64,24 + .type .ffi_closure_LINUX64,@function + .text +.ffi_closure_LINUX64: +# endif +# endif + +# if _CALL_ELF == 2 +# 32 byte special reg save area + 64 byte parm save area +# + 64 byte retval area + 13*8 fpr save area + round to 16 +# define STACKFRAME 272 +# define PARMSAVE 32 +# define RETVAL PARMSAVE+64 +# else +# 48 bytes special reg save area + 64 bytes parm save area +# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16 +# define STACKFRAME 240 +# define PARMSAVE 48 +# define RETVAL PARMSAVE+64 +# endif + +# if _CALL_ELF == 2 + ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif + mflr %r0 + lwz %r12, 28(%r12) # cif->flags + mtcrf 0x40, %r12 + addi %r12, %r1, PARMSAVE + bt 7, 0f + # Our caller has not allocated a parameter save area. + # We need to allocate one here and use it to pass gprs to + # ffi_closure_helper_LINUX64. + addi %r12, %r1, -STACKFRAME+PARMSAVE +0: + # Save general regs into parm save area + std %r3, 0(%r12) + std %r4, 8(%r12) + std %r5, 16(%r12) + std %r6, 24(%r12) + std %r7, 32(%r12) + std %r8, 40(%r12) + std %r9, 48(%r12) + std %r10, 56(%r12) + + # load up the pointer to the parm save area + mr %r7, %r12 +# else + # copy r2 to r11 and load TOC into r2 + mr %r11, %r2 + ld %r2, 16(%r2) + + mflr %r0 + # Save general regs into parm save area + # This is the parameter save area set up by our caller. + std %r3, PARMSAVE+0(%r1) + std %r4, PARMSAVE+8(%r1) + std %r5, PARMSAVE+16(%r1) + std %r6, PARMSAVE+24(%r1) + std %r7, PARMSAVE+32(%r1) + std %r8, PARMSAVE+40(%r1) + std %r9, PARMSAVE+48(%r1) + std %r10, PARMSAVE+56(%r1) + + # load up the pointer to the parm save area + addi %r7, %r1, PARMSAVE +# endif + std %r0, 16(%r1) + + # closure->cif + ld %r3, FFI_TRAMPOLINE_SIZE(%r11) + # closure->fun + ld %r4, FFI_TRAMPOLINE_SIZE+8(%r11) + # closure->user_data + ld %r5, FFI_TRAMPOLINE_SIZE+16(%r11) + +.Ldoclosure: + # next save fpr 1 to fpr 13 + stfd %f1, -104+(0*8)(%r1) + stfd %f2, -104+(1*8)(%r1) + stfd %f3, -104+(2*8)(%r1) + stfd %f4, -104+(3*8)(%r1) + stfd %f5, -104+(4*8)(%r1) + stfd %f6, -104+(5*8)(%r1) + stfd %f7, -104+(6*8)(%r1) + stfd %f8, -104+(7*8)(%r1) + stfd %f9, -104+(8*8)(%r1) + stfd %f10, -104+(9*8)(%r1) + stfd %f11, -104+(10*8)(%r1) + stfd %f12, -104+(11*8)(%r1) + stfd %f13, -104+(12*8)(%r1) + + # load up the pointer to the saved fpr registers */ + addi %r8, %r1, -104 + + # load up the pointer to the result storage + addi %r6, %r1, -STACKFRAME+RETVAL + + stdu %r1, -STACKFRAME(%r1) + .cfi_def_cfa_offset STACKFRAME + .cfi_offset 65, 16 + + # make the call +# if defined _CALL_LINUX || _CALL_ELF == 2 + bl ffi_closure_helper_LINUX64 +# else + bl .ffi_closure_helper_LINUX64 +# endif +.Lret: + + # now r3 contains the return type + # so use it to look up in a table + # so we know how to deal with each type + + # look up the proper starting point in table + # by using return type as offset + ld %r0, STACKFRAME+16(%r1) + cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + bge .Lsmall + mflr %r4 # move address of .Lret to r4 + sldi %r3, %r3, 4 # now multiply return type by 16 + addi %r4, %r4, .Lret_type0 - .Lret + add %r3, %r3, %r4 # add contents of table to table address + mtctr %r3 + bctr # jump to it + +# Each of the ret_typeX code fragments has to be exactly 16 bytes long +# (4 instructions). For cache effectiveness we align to a 16 byte boundary +# first. + .align 4 + +.Lret_type0: +# case FFI_TYPE_VOID + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME + nop +# case FFI_TYPE_INT +# ifdef __LITTLE_ENDIAN__ + lwa %r3, RETVAL+0(%r1) +# else + lwa %r3, RETVAL+4(%r1) +# endif + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_FLOAT + lfs %f1, RETVAL+0(%r1) + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_DOUBLE + lfd %f1, RETVAL+0(%r1) + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_LONGDOUBLE + lfd %f1, RETVAL+0(%r1) + mtlr %r0 + lfd %f2, RETVAL+8(%r1) + b .Lfinish +# case FFI_TYPE_UINT8 +# ifdef __LITTLE_ENDIAN__ + lbz %r3, RETVAL+0(%r1) +# else + lbz %r3, RETVAL+7(%r1) +# endif + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_SINT8 +# ifdef __LITTLE_ENDIAN__ + lbz %r3, RETVAL+0(%r1) +# else + lbz %r3, RETVAL+7(%r1) +# endif + extsb %r3,%r3 + mtlr %r0 + b .Lfinish +# case FFI_TYPE_UINT16 +# ifdef __LITTLE_ENDIAN__ + lhz %r3, RETVAL+0(%r1) +# else + lhz %r3, RETVAL+6(%r1) +# endif + mtlr %r0 +.Lfinish: + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_SINT16 +# ifdef __LITTLE_ENDIAN__ + lha %r3, RETVAL+0(%r1) +# else + lha %r3, RETVAL+6(%r1) +# endif + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_UINT32 +# ifdef __LITTLE_ENDIAN__ + lwz %r3, RETVAL+0(%r1) +# else + lwz %r3, RETVAL+4(%r1) +# endif + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_SINT32 +# ifdef __LITTLE_ENDIAN__ + lwa %r3, RETVAL+0(%r1) +# else + lwa %r3, RETVAL+4(%r1) +# endif + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_UINT64 + ld %r3, RETVAL+0(%r1) + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_SINT64 + ld %r3, RETVAL+0(%r1) + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_TYPE_STRUCT + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME + nop +# case FFI_TYPE_POINTER + ld %r3, RETVAL+0(%r1) + mtlr %r0 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +# case FFI_V2_TYPE_FLOAT_HOMOG + lfs %f1, RETVAL+0(%r1) + lfs %f2, RETVAL+4(%r1) + lfs %f3, RETVAL+8(%r1) + b .Lmorefloat +# case FFI_V2_TYPE_DOUBLE_HOMOG + lfd %f1, RETVAL+0(%r1) + lfd %f2, RETVAL+8(%r1) + lfd %f3, RETVAL+16(%r1) + lfd %f4, RETVAL+24(%r1) + mtlr %r0 + lfd %f5, RETVAL+32(%r1) + lfd %f6, RETVAL+40(%r1) + lfd %f7, RETVAL+48(%r1) + lfd %f8, RETVAL+56(%r1) + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +.Lmorefloat: + lfs %f4, RETVAL+12(%r1) + mtlr %r0 + lfs %f5, RETVAL+16(%r1) + lfs %f6, RETVAL+20(%r1) + lfs %f7, RETVAL+24(%r1) + lfs %f8, RETVAL+28(%r1) + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +.Lsmall: +# ifdef __LITTLE_ENDIAN__ + ld %r3,RETVAL+0(%r1) + mtlr %r0 + ld %r4,RETVAL+8(%r1) + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr +# else + # A struct smaller than a dword is returned in the low bits of r3 + # ie. right justified. Larger structs are passed left justified + # in r3 and r4. The return value area on the stack will have + # the structs as they are usually stored in memory. + cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes? + neg %r5, %r3 + ld %r3,RETVAL+0(%r1) + blt .Lsmalldown + mtlr %r0 + ld %r4,RETVAL+8(%r1) + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset STACKFRAME +.Lsmalldown: + addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7 + mtlr %r0 + sldi %r5, %r5, 3 + addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 + srd %r3, %r3, %r5 + blr +# endif + + .cfi_endproc +# if _CALL_ELF == 2 + .size ffi_closure_LINUX64,.-ffi_closure_LINUX64 +# else +# ifdef _CALL_LINUX + .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 +# else + .long 0 + .byte 0,12,0,1,128,0,0,0 + .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 +# endif +# endif + + + FFI_HIDDEN (ffi_go_closure_linux64) + .globl ffi_go_closure_linux64 + .text + .cfi_startproc +# if _CALL_ELF == 2 +ffi_go_closure_linux64: + addis %r2, %r12, .TOC.-ffi_go_closure_linux64@ha + addi %r2, %r2, .TOC.-ffi_go_closure_linux64@l + .localentry ffi_go_closure_linux64, . - ffi_go_closure_linux64 +# else + .section ".opd","aw" + .align 3 +ffi_go_closure_linux64: +# ifdef _CALL_LINUX + .quad .L.ffi_go_closure_linux64,.TOC.@tocbase,0 + .type ffi_go_closure_linux64,@function + .text +.L.ffi_go_closure_linux64: +# else + FFI_HIDDEN (.ffi_go_closure_linux64) + .globl .ffi_go_closure_linux64 + .quad .ffi_go_closure_linux64,.TOC.@tocbase,0 + .size ffi_go_closure_linux64,24 + .type .ffi_go_closure_linux64,@function + .text +.ffi_go_closure_linux64: +# endif +# endif + +# if _CALL_ELF == 2 + ld %r12, 8(%r11) # closure->cif + mflr %r0 + lwz %r12, 28(%r12) # cif->flags + mtcrf 0x40, %r12 + addi %r12, %r1, PARMSAVE + bt 7, 0f + # Our caller has not allocated a parameter save area. + # We need to allocate one here and use it to pass gprs to + # ffi_closure_helper_LINUX64. + addi %r12, %r1, -STACKFRAME+PARMSAVE +0: + # Save general regs into parm save area + std %r3, 0(%r12) + std %r4, 8(%r12) + std %r5, 16(%r12) + std %r6, 24(%r12) + std %r7, 32(%r12) + std %r8, 40(%r12) + std %r9, 48(%r12) + std %r10, 56(%r12) + + # load up the pointer to the parm save area + mr %r7, %r12 +# else + mflr %r0 + # Save general regs into parm save area + # This is the parameter save area set up by our caller. + std %r3, PARMSAVE+0(%r1) + std %r4, PARMSAVE+8(%r1) + std %r5, PARMSAVE+16(%r1) + std %r6, PARMSAVE+24(%r1) + std %r7, PARMSAVE+32(%r1) + std %r8, PARMSAVE+40(%r1) + std %r9, PARMSAVE+48(%r1) + std %r10, PARMSAVE+56(%r1) + + # load up the pointer to the parm save area + addi %r7, %r1, PARMSAVE +# endif + std %r0, 16(%r1) + + # closure->cif + ld %r3, 8(%r11) + # closure->fun + ld %r4, 16(%r11) + # user_data + mr %r5, %r11 + b .Ldoclosure + + .cfi_endproc +# if _CALL_ELF == 2 + .size ffi_go_closure_linux64,.-ffi_go_closure_linux64 +# else +# ifdef _CALL_LINUX + .size ffi_go_closure_linux64,.-.L.ffi_go_closure_linux64 +# else + .long 0 + .byte 0,12,0,1,128,0,0,0 + .size .ffi_go_closure_linux64,.-.ffi_go_closure_linux64 +# endif +# endif +#endif + +#if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/powerpc/ppc_closure.S b/circuitpython/lib/libffi/src/powerpc/ppc_closure.S new file mode 100644 index 0000000..b6d209d --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/ppc_closure.S @@ -0,0 +1,397 @@ +/* ----------------------------------------------------------------------- + sysv.h - Copyright (c) 2003 Jakub Jelinek + Copyright (c) 2008 Red Hat, Inc. + + PowerPC Assembly glue. + + 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 LIBFFI_ASM +#include +#include +#include + + .file "ppc_closure.S" + +#ifndef POWERPC64 + +FFI_HIDDEN(ffi_closure_SYSV) +ENTRY(ffi_closure_SYSV) + .cfi_startproc + stwu %r1,-144(%r1) + .cfi_def_cfa_offset 144 + mflr %r0 + stw %r0,148(%r1) + .cfi_offset 65, 4 + +# we want to build up an areas for the parameters passed +# in registers (both floating point and integer) + + # so first save gpr 3 to gpr 10 (aligned to 4) + stw %r3, 16(%r1) + stw %r4, 20(%r1) + stw %r5, 24(%r1) + + # set up registers for the routine that does the work + + # closure->cif + lwz %r3,FFI_TRAMPOLINE_SIZE(%r11) + # closure->fun + lwz %r4,FFI_TRAMPOLINE_SIZE+4(%r11) + # closure->user_data + lwz %r5,FFI_TRAMPOLINE_SIZE+8(%r11) + +.Ldoclosure: + stw %r6, 28(%r1) + stw %r7, 32(%r1) + stw %r8, 36(%r1) + stw %r9, 40(%r1) + stw %r10,44(%r1) + +#ifndef __NO_FPRS__ + # next save fpr 1 to fpr 8 (aligned to 8) + stfd %f1, 48(%r1) + stfd %f2, 56(%r1) + stfd %f3, 64(%r1) + stfd %f4, 72(%r1) + stfd %f5, 80(%r1) + stfd %f6, 88(%r1) + stfd %f7, 96(%r1) + stfd %f8, 104(%r1) +#endif + + # pointer to the result storage + addi %r6,%r1,112 + + # pointer to the saved gpr registers + addi %r7,%r1,16 + + # pointer to the saved fpr registers + addi %r8,%r1,48 + + # pointer to the outgoing parameter save area in the previous frame + # i.e. the previous frame pointer + 8 + addi %r9,%r1,152 + + # make the call + bl ffi_closure_helper_SYSV@local +.Lret: + # now r3 contains the return type + # so use it to look up in a table + # so we know how to deal with each type + + # look up the proper starting point in table + # by using return type as offset + + mflr %r4 # move address of .Lret to r4 + slwi %r3,%r3,4 # now multiply return type by 16 + addi %r4, %r4, .Lret_type0 - .Lret + lwz %r0,148(%r1) + add %r3,%r3,%r4 # add contents of table to table address + mtctr %r3 + bctr # jump to it + +# Each of the ret_typeX code fragments has to be exactly 16 bytes long +# (4 instructions). For cache effectiveness we align to a 16 byte boundary +# first. + .align 4 +# case FFI_TYPE_VOID +.Lret_type0: + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + nop + +# case FFI_TYPE_INT + lwz %r3,112+0(%r1) + mtlr %r0 +.Lfinish: + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_FLOAT +#ifndef __NO_FPRS__ + lfs %f1,112+0(%r1) +#else + nop +#endif + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_DOUBLE +#ifndef __NO_FPRS__ + lfd %f1,112+0(%r1) +#else + nop +#endif + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_LONGDOUBLE +#ifndef __NO_FPRS__ + lfd %f1,112+0(%r1) + lfd %f2,112+8(%r1) + mtlr %r0 + b .Lfinish +#else + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + nop +#endif + +# case FFI_TYPE_UINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else + lbz %r3,112+3(%r1) +#endif + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_SINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else + lbz %r3,112+3(%r1) +#endif + extsb %r3,%r3 + mtlr %r0 + b .Lfinish + +# case FFI_TYPE_UINT16 +#ifdef __LITTLE_ENDIAN__ + lhz %r3,112+0(%r1) +#else + lhz %r3,112+2(%r1) +#endif + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_SINT16 +#ifdef __LITTLE_ENDIAN__ + lha %r3,112+0(%r1) +#else + lha %r3,112+2(%r1) +#endif + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_UINT32 + lwz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_SINT32 + lwz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_UINT64 + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + mtlr %r0 + b .Lfinish + +# case FFI_TYPE_SINT64 + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + mtlr %r0 + b .Lfinish + +# case FFI_TYPE_STRUCT + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + nop + +# case FFI_TYPE_POINTER + lwz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_TYPE_UINT128 + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + lwz %r5,112+8(%r1) + b .Luint128 + +# The return types below are only used when the ABI type is FFI_SYSV. +# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct. + lbz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct. + lhz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. + lwz %r3,112+0(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 +#else + srwi %r3,%r3,8 + mtlr %r0 + b .Lfinish +#endif + +# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct. + lwz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 + +# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else + li %r5,24 + b .Lstruct567 +#endif + +# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct. + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else + li %r5,16 + b .Lstruct567 +#endif + +# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct. + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else + li %r5,8 + b .Lstruct567 +#endif + +# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct. + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + mtlr %r0 + b .Lfinish + +#ifndef __LITTLE_ENDIAN__ +.Lstruct567: + subfic %r6,%r5,32 + srw %r4,%r4,%r5 + slw %r6,%r3,%r6 + srw %r3,%r3,%r5 + or %r4,%r6,%r4 + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_def_cfa_offset 144 +#endif + +.Luint128: + lwz %r6,112+12(%r1) + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 + blr + .cfi_endproc +END(ffi_closure_SYSV) + + +FFI_HIDDEN(ffi_go_closure_sysv) +ENTRY(ffi_go_closure_sysv) + .cfi_startproc + stwu %r1,-144(%r1) + .cfi_def_cfa_offset 144 + mflr %r0 + stw %r0,148(%r1) + .cfi_offset 65, 4 + + stw %r3, 16(%r1) + stw %r4, 20(%r1) + stw %r5, 24(%r1) + + # closure->cif + lwz %r3,4(%r11) + # closure->fun + lwz %r4,8(%r11) + # user_data + mr %r5,%r11 + b .Ldoclosure + .cfi_endproc +END(ffi_go_closure_sysv) + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif +#endif diff --git a/circuitpython/lib/libffi/src/powerpc/sysv.S b/circuitpython/lib/libffi/src/powerpc/sysv.S new file mode 100644 index 0000000..1474ce7 --- /dev/null +++ b/circuitpython/lib/libffi/src/powerpc/sysv.S @@ -0,0 +1,175 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 1998 Geoffrey Keating + Copyright (C) 2007 Free Software Foundation, Inc + + PowerPC Assembly glue. + + 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 LIBFFI_ASM +#include +#include +#include + +#ifndef POWERPC64 +FFI_HIDDEN(ffi_call_SYSV) +ENTRY(ffi_call_SYSV) + .cfi_startproc + /* Save the old stack pointer as AP. */ + mr %r10,%r1 + .cfi_def_cfa_register 10 + + /* Allocate the stack space we need. */ + stwux %r1,%r1,%r8 + /* Save registers we use. */ + mflr %r9 + stw %r28,-16(%r10) + stw %r29,-12(%r10) + stw %r30, -8(%r10) + stw %r31, -4(%r10) + stw %r9, 4(%r10) + .cfi_offset 65, 4 + .cfi_offset 31, -4 + .cfi_offset 30, -8 + .cfi_offset 29, -12 + .cfi_offset 28, -16 + + /* Save arguments over call... */ + stw %r7, -20(%r10) /* closure, */ + mr %r31,%r6 /* flags, */ + mr %r30,%r5 /* rvalue, */ + mr %r29,%r4 /* function address, */ + mr %r28,%r10 /* our AP. */ + .cfi_def_cfa_register 28 + + /* Call ffi_prep_args_SYSV. */ + mr %r4,%r1 + bl ffi_prep_args_SYSV@local + + /* Now do the call. */ + /* Set up cr1 with bits 4-7 of the flags. */ + mtcrf 0x40,%r31 + /* Get the address to call into CTR. */ + mtctr %r29 + /* Load all those argument registers. */ + lwz %r3,-24-(8*4)(%r28) + lwz %r4,-24-(7*4)(%r28) + lwz %r5,-24-(6*4)(%r28) + lwz %r6,-24-(5*4)(%r28) + bf- 5,1f + nop + lwz %r7,-24-(4*4)(%r28) + lwz %r8,-24-(3*4)(%r28) + lwz %r9,-24-(2*4)(%r28) + lwz %r10,-24-(1*4)(%r28) + nop +1: + +#ifndef __NO_FPRS__ + /* Load all the FP registers. */ + bf- 6,2f + lfd %f1,-24-(8*4)-(8*8)(%r28) + lfd %f2,-24-(8*4)-(7*8)(%r28) + lfd %f3,-24-(8*4)-(6*8)(%r28) + lfd %f4,-24-(8*4)-(5*8)(%r28) + nop + lfd %f5,-24-(8*4)-(4*8)(%r28) + lfd %f6,-24-(8*4)-(3*8)(%r28) + lfd %f7,-24-(8*4)-(2*8)(%r28) + lfd %f8,-24-(8*4)-(1*8)(%r28) +#endif +2: + + /* Make the call. */ + lwz %r11, -20(%r28) + bctrl + + /* Now, deal with the return value. */ + mtcrf 0x01,%r31 /* cr7 */ + bt- 31,L(small_struct_return_value) + bt- 30,L(done_return_value) +#ifndef __NO_FPRS__ + bt- 29,L(fp_return_value) +#endif + stw %r3,0(%r30) + bf+ 28,L(done_return_value) + stw %r4,4(%r30) + mtcrf 0x02,%r31 /* cr6 */ + bf 27,L(done_return_value) + stw %r5,8(%r30) + stw %r6,12(%r30) + /* Fall through... */ + +L(done_return_value): + /* Restore the registers we used and return. */ + lwz %r9, 4(%r28) + lwz %r31, -4(%r28) + mtlr %r9 + lwz %r30, -8(%r28) + lwz %r29,-12(%r28) + lwz %r28,-16(%r28) + .cfi_remember_state + /* At this point we don't have a cfa register. Say all our + saved regs have been restored. */ + .cfi_same_value 65 + .cfi_same_value 31 + .cfi_same_value 30 + .cfi_same_value 29 + .cfi_same_value 28 + /* Hopefully this works.. */ + .cfi_def_cfa_register 1 + .cfi_offset 1, 0 + lwz %r1,0(%r1) + .cfi_same_value 1 + blr + +#ifndef __NO_FPRS__ +L(fp_return_value): + .cfi_restore_state + bf 28,L(float_return_value) + stfd %f1,0(%r30) + mtcrf 0x02,%r31 /* cr6 */ + bf 27,L(done_return_value) + stfd %f2,8(%r30) + b L(done_return_value) +L(float_return_value): + stfs %f1,0(%r30) + b L(done_return_value) +#endif + +L(small_struct_return_value): + /* + * The C code always allocates a properly-aligned 8-byte bounce + * buffer to make this assembly code very simple. Just write out + * r3 and r4 to the buffer to allow the C code to handle the rest. + */ + stw %r3, 0(%r30) + stw %r4, 4(%r30) + b L(done_return_value) + .cfi_endproc + +END(ffi_call_SYSV) + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif +#endif diff --git a/circuitpython/lib/libffi/src/prep_cif.c b/circuitpython/lib/libffi/src/prep_cif.c new file mode 100644 index 0000000..5881ceb --- /dev/null +++ b/circuitpython/lib/libffi/src/prep_cif.c @@ -0,0 +1,242 @@ +/* ----------------------------------------------------------------------- + prep_cif.c - Copyright (c) 2011, 2012 Anthony Green + Copyright (c) 1996, 1998, 2007 Red Hat, Inc. + + 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 +#include +#include + +/* Round up to FFI_SIZEOF_ARG. */ + +#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) + +/* Perform machine independent initialization of aggregate type + specifications. */ + +static ffi_status initialize_aggregate(ffi_type *arg) +{ + ffi_type **ptr; + + if (UNLIKELY(arg == NULL || arg->elements == NULL)) + return FFI_BAD_TYPEDEF; + + arg->size = 0; + arg->alignment = 0; + + ptr = &(arg->elements[0]); + + if (UNLIKELY(ptr == 0)) + return FFI_BAD_TYPEDEF; + + while ((*ptr) != NULL) + { + if (UNLIKELY(((*ptr)->size == 0) + && (initialize_aggregate((*ptr)) != FFI_OK))) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type */ + FFI_ASSERT_VALID_TYPE(*ptr); + + arg->size = ALIGN(arg->size, (*ptr)->alignment); + arg->size += (*ptr)->size; + + arg->alignment = (arg->alignment > (*ptr)->alignment) ? + arg->alignment : (*ptr)->alignment; + + ptr++; + } + + /* Structure size includes tail padding. This is important for + structures that fit in one register on ABIs like the PowerPC64 + Linux ABI that right justify small structs in a register. + It's also needed for nested structure layout, for example + struct A { long a; char b; }; struct B { struct A x; char y; }; + should find y at an offset of 2*sizeof(long) and result in a + total size of 3*sizeof(long). */ + arg->size = ALIGN (arg->size, arg->alignment); + + /* On some targets, the ABI defines that structures have an additional + alignment beyond the "natural" one based on their elements. */ +#ifdef FFI_AGGREGATE_ALIGNMENT + if (FFI_AGGREGATE_ALIGNMENT > arg->alignment) + arg->alignment = FFI_AGGREGATE_ALIGNMENT; +#endif + + if (arg->size == 0) + return FFI_BAD_TYPEDEF; + else + return FFI_OK; +} + +#ifndef __CRIS__ +/* The CRIS ABI specifies structure elements to have byte + alignment only, so it completely overrides this functions, + which assumes "natural" alignment and padding. */ + +/* Perform machine independent ffi_cif preparation, then call + machine dependent routine. */ + +/* For non variadic functions isvariadic should be 0 and + nfixedargs==ntotalargs. + + For variadic calls, isvariadic should be 1 and nfixedargs + and ntotalargs set as appropriate. nfixedargs must always be >=1 */ + + +ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, + unsigned int isvariadic, + unsigned int nfixedargs, + unsigned int ntotalargs, + ffi_type *rtype, ffi_type **atypes) +{ + unsigned bytes = 0; + unsigned int i; + ffi_type **ptr; + + FFI_ASSERT(cif != NULL); + FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); + FFI_ASSERT(nfixedargs <= ntotalargs); + + if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) + return FFI_BAD_ABI; + + cif->abi = abi; + cif->arg_types = atypes; + cif->nargs = ntotalargs; + cif->rtype = rtype; + + cif->flags = 0; + +#if HAVE_LONG_DOUBLE_VARIANT + ffi_prep_types (abi); +#endif + + /* Initialize the return type if necessary */ + if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) + return FFI_BAD_TYPEDEF; + +#ifndef FFI_TARGET_HAS_COMPLEX_TYPE + if (rtype->type == FFI_TYPE_COMPLEX) + abort(); +#endif + /* Perform a sanity check on the return type */ + FFI_ASSERT_VALID_TYPE(cif->rtype); + + /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */ +#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION + /* Make space for the return structure pointer */ + if (cif->rtype->type == FFI_TYPE_STRUCT +#ifdef TILE + && (cif->rtype->size > 10 * FFI_SIZEOF_ARG) +#endif +#ifdef XTENSA + && (cif->rtype->size > 16) +#endif +#ifdef NIOS2 + && (cif->rtype->size > 8) +#endif + ) + bytes = STACK_ARG_SIZE(sizeof(void*)); +#endif + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + + /* Initialize any uninitialized aggregate type definitions */ + if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + +#ifndef FFI_TARGET_HAS_COMPLEX_TYPE + if ((*ptr)->type == FFI_TYPE_COMPLEX) + abort(); +#endif + /* Perform a sanity check on the argument type, do this + check after the initialization. */ + FFI_ASSERT_VALID_TYPE(*ptr); + +#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION + { + /* Add any padding if necessary */ + if (((*ptr)->alignment - 1) & bytes) + bytes = (unsigned)ALIGN(bytes, (*ptr)->alignment); + +#ifdef TILE + if (bytes < 10 * FFI_SIZEOF_ARG && + bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG) + { + /* An argument is never split between the 10 parameter + registers and the stack. */ + bytes = 10 * FFI_SIZEOF_ARG; + } +#endif +#ifdef XTENSA + if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4) + bytes = 6*4; +#endif + + bytes += STACK_ARG_SIZE((*ptr)->size); + } +#endif + } + + cif->bytes = bytes; + + /* Perform machine dependent cif processing */ +#ifdef FFI_TARGET_SPECIFIC_VARIADIC + if (isvariadic) + return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs); +#endif + + return ffi_prep_cif_machdep(cif); +} +#endif /* not __CRIS__ */ + +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, + ffi_type *rtype, ffi_type **atypes) +{ + return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes); +} + +ffi_status ffi_prep_cif_var(ffi_cif *cif, + ffi_abi abi, + unsigned int nfixedargs, + unsigned int ntotalargs, + ffi_type *rtype, + ffi_type **atypes) +{ + return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes); +} + +#if FFI_CLOSURES + +ffi_status +ffi_prep_closure (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data) +{ + return ffi_prep_closure_loc (closure, cif, fun, user_data, closure); +} + +#endif diff --git a/circuitpython/lib/libffi/src/raw_api.c b/circuitpython/lib/libffi/src/raw_api.c new file mode 100644 index 0000000..276cb22 --- /dev/null +++ b/circuitpython/lib/libffi/src/raw_api.c @@ -0,0 +1,267 @@ +/* ----------------------------------------------------------------------- + raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc. + + Author: Kresten Krab Thorup + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +/* This file defines generic functions for use with the raw api. */ + +#include +#include + +#if !FFI_NO_RAW_API + +size_t +ffi_raw_size (ffi_cif *cif) +{ + size_t result = 0; + int i; + + ffi_type **at = cif->arg_types; + + for (i = cif->nargs-1; i >= 0; i--, at++) + { +#if !FFI_NO_STRUCTS + if ((*at)->type == FFI_TYPE_STRUCT) + result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG); + else +#endif + result += ALIGN ((*at)->size, FFI_SIZEOF_ARG); + } + + return result; +} + + +void +ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) +{ + unsigned i; + ffi_type **tp = cif->arg_types; + +#if WORDS_BIGENDIAN + + for (i = 0; i < cif->nargs; i++, tp++, args++) + { + switch ((*tp)->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1); + break; + + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2); + break; + +#if FFI_SIZEOF_ARG >= 4 + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4); + break; +#endif + +#if !FFI_NO_STRUCTS + case FFI_TYPE_STRUCT: + *args = (raw++)->ptr; + break; +#endif + + case FFI_TYPE_COMPLEX: + *args = (raw++)->ptr; + break; + + case FFI_TYPE_POINTER: + *args = (void*) &(raw++)->ptr; + break; + + default: + *args = raw; + raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + } + } + +#else /* WORDS_BIGENDIAN */ + +#if !PDP + + /* then assume little endian */ + for (i = 0; i < cif->nargs; i++, tp++, args++) + { +#if !FFI_NO_STRUCTS + if ((*tp)->type == FFI_TYPE_STRUCT) + { + *args = (raw++)->ptr; + } + else +#endif + if ((*tp)->type == FFI_TYPE_COMPLEX) + { + *args = (raw++)->ptr; + } + else + { + *args = (void*) raw; + raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); + } + } + +#else +#error "pdp endian not supported" +#endif /* ! PDP */ + +#endif /* WORDS_BIGENDIAN */ +} + +void +ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) +{ + unsigned i; + ffi_type **tp = cif->arg_types; + + for (i = 0; i < cif->nargs; i++, tp++, args++) + { + switch ((*tp)->type) + { + case FFI_TYPE_UINT8: + (raw++)->uint = *(UINT8*) (*args); + break; + + case FFI_TYPE_SINT8: + (raw++)->sint = *(SINT8*) (*args); + break; + + case FFI_TYPE_UINT16: + (raw++)->uint = *(UINT16*) (*args); + break; + + case FFI_TYPE_SINT16: + (raw++)->sint = *(SINT16*) (*args); + break; + +#if FFI_SIZEOF_ARG >= 4 + case FFI_TYPE_UINT32: + (raw++)->uint = *(UINT32*) (*args); + break; + + case FFI_TYPE_SINT32: + (raw++)->sint = *(SINT32*) (*args); + break; +#endif + +#if !FFI_NO_STRUCTS + case FFI_TYPE_STRUCT: + (raw++)->ptr = *args; + break; +#endif + + case FFI_TYPE_COMPLEX: + (raw++)->ptr = *args; + break; + + case FFI_TYPE_POINTER: + (raw++)->ptr = **(void***) args; + break; + + default: + memcpy ((void*) raw->data, (void*)*args, (*tp)->size); + raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + } + } +} + +#if !FFI_NATIVE_RAW_API + + +/* This is a generic definition of ffi_raw_call, to be used if the + * native system does not provide a machine-specific implementation. + * Having this, allows code to be written for the raw API, without + * the need for system-specific code to handle input in that format; + * these following couple of functions will handle the translation forth + * and back automatically. */ + +void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw) +{ + void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); + ffi_raw_to_ptrarray (cif, raw, avalue); + ffi_call (cif, fn, rvalue, avalue); +} + +#if FFI_CLOSURES /* base system provides closures */ + +static void +ffi_translate_args (ffi_cif *cif, void *rvalue, + void **avalue, void *user_data) +{ + ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif)); + ffi_raw_closure *cl = (ffi_raw_closure*)user_data; + + ffi_ptrarray_to_raw (cif, avalue, raw); + (*cl->fun) (cif, rvalue, raw, cl->user_data); +} + +ffi_status +ffi_prep_raw_closure_loc (ffi_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc) +{ + ffi_status status; + + status = ffi_prep_closure_loc ((ffi_closure*) cl, + cif, + &ffi_translate_args, + codeloc, + codeloc); + if (status == FFI_OK) + { + cl->fun = fun; + cl->user_data = user_data; + } + + return status; +} + +#endif /* FFI_CLOSURES */ +#endif /* !FFI_NATIVE_RAW_API */ + +#if FFI_CLOSURES + +/* Again, here is the generic version of ffi_prep_raw_closure, which + * will install an intermediate "hub" for translation of arguments from + * the pointer-array format, to the raw format */ + +ffi_status +ffi_prep_raw_closure (ffi_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data) +{ + return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl); +} + +#endif /* FFI_CLOSURES */ + +#endif /* !FFI_NO_RAW_API */ diff --git a/circuitpython/lib/libffi/src/s390/ffi.c b/circuitpython/lib/libffi/src/s390/ffi.c new file mode 100644 index 0000000..4035b6e --- /dev/null +++ b/circuitpython/lib/libffi/src/s390/ffi.c @@ -0,0 +1,756 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2000, 2007 Software AG + Copyright (c) 2008 Red Hat, Inc + + S390 Foreign Function Interface + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ +/*====================================================================*/ +/* Includes */ +/* -------- */ +/*====================================================================*/ + +#include +#include +#include +#include "internal.h" + +/*====================== End of Includes =============================*/ + +/*====================================================================*/ +/* Defines */ +/* ------- */ +/*====================================================================*/ + +/* Maximum number of GPRs available for argument passing. */ +#define MAX_GPRARGS 5 + +/* Maximum number of FPRs available for argument passing. */ +#ifdef __s390x__ +#define MAX_FPRARGS 4 +#else +#define MAX_FPRARGS 2 +#endif + +/* Round to multiple of 16. */ +#define ROUND_SIZE(size) (((size) + 15) & ~15) + +/*===================== End of Defines ===============================*/ + +/*====================================================================*/ +/* Externals */ +/* --------- */ +/*====================================================================*/ + +struct call_frame +{ + void *back_chain; + void *eos; + unsigned long gpr_args[5]; + unsigned long gpr_save[9]; + unsigned long long fpr_args[4]; +}; + +extern void FFI_HIDDEN ffi_call_SYSV(struct call_frame *, unsigned, void *, + void (*fn)(void), void *); + +extern void ffi_closure_SYSV(void); +extern void ffi_go_closure_SYSV(void); + +/*====================== End of Externals ============================*/ + +/*====================================================================*/ +/* */ +/* Name - ffi_check_struct_type. */ +/* */ +/* Function - Determine if a structure can be passed within a */ +/* general purpose or floating point register. */ +/* */ +/*====================================================================*/ + +static int +ffi_check_struct_type (ffi_type *arg) +{ + size_t size = arg->size; + + /* If the struct has just one element, look at that element + to find out whether to consider the struct as floating point. */ + while (arg->type == FFI_TYPE_STRUCT + && arg->elements[0] && !arg->elements[1]) + arg = arg->elements[0]; + + /* Structs of size 1, 2, 4, and 8 are passed in registers, + just like the corresponding int/float types. */ + switch (size) + { + case 1: + return FFI_TYPE_UINT8; + + case 2: + return FFI_TYPE_UINT16; + + case 4: + if (arg->type == FFI_TYPE_FLOAT) + return FFI_TYPE_FLOAT; + else + return FFI_TYPE_UINT32; + + case 8: + if (arg->type == FFI_TYPE_DOUBLE) + return FFI_TYPE_DOUBLE; + else + return FFI_TYPE_UINT64; + + default: + break; + } + + /* Other structs are passed via a pointer to the data. */ + return FFI_TYPE_POINTER; +} + +/*======================== End of Routine ============================*/ + +/*====================================================================*/ +/* */ +/* Name - ffi_prep_cif_machdep. */ +/* */ +/* Function - Perform machine dependent CIF processing. */ +/* */ +/*====================================================================*/ + +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep(ffi_cif *cif) +{ + size_t struct_size = 0; + int n_gpr = 0; + int n_fpr = 0; + int n_ov = 0; + + ffi_type **ptr; + int i; + + /* Determine return value handling. */ + + switch (cif->rtype->type) + { + /* Void is easy. */ + case FFI_TYPE_VOID: + cif->flags = FFI390_RET_VOID; + break; + + /* Structures and complex are returned via a hidden pointer. */ + case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: + cif->flags = FFI390_RET_STRUCT; + n_gpr++; /* We need one GPR to pass the pointer. */ + break; + + /* Floating point values are returned in fpr 0. */ + case FFI_TYPE_FLOAT: + cif->flags = FFI390_RET_FLOAT; + break; + + case FFI_TYPE_DOUBLE: + cif->flags = FFI390_RET_DOUBLE; + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + cif->flags = FFI390_RET_STRUCT; + n_gpr++; + break; +#endif + /* Integer values are returned in gpr 2 (and gpr 3 + for 64-bit values on 31-bit machines). */ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + cif->flags = FFI390_RET_INT64; + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + /* These are to be extended to word size. */ +#ifdef __s390x__ + cif->flags = FFI390_RET_INT64; +#else + cif->flags = FFI390_RET_INT32; +#endif + break; + + default: + FFI_ASSERT (0); + break; + } + + /* Now for the arguments. */ + + for (ptr = cif->arg_types, i = cif->nargs; + i > 0; + i--, ptr++) + { + int type = (*ptr)->type; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + /* 16-byte long double is passed like a struct. */ + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + + /* Check how a structure type is passed. */ + if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX) + { + if (type == FFI_TYPE_COMPLEX) + type = FFI_TYPE_POINTER; + else + type = ffi_check_struct_type (*ptr); + + /* If we pass the struct via pointer, we must reserve space + to copy its data for proper call-by-value semantics. */ + if (type == FFI_TYPE_POINTER) + struct_size += ROUND_SIZE ((*ptr)->size); + } + + /* Now handle all primitive int/float data types. */ + switch (type) + { + /* The first MAX_FPRARGS floating point arguments + go in FPRs, the rest overflow to the stack. */ + + case FFI_TYPE_DOUBLE: + if (n_fpr < MAX_FPRARGS) + n_fpr++; + else + n_ov += sizeof (double) / sizeof (long); + break; + + case FFI_TYPE_FLOAT: + if (n_fpr < MAX_FPRARGS) + n_fpr++; + else + n_ov++; + break; + + /* On 31-bit machines, 64-bit integers are passed in GPR pairs, + if one is still available, or else on the stack. If only one + register is free, skip the register (it won't be used for any + subsequent argument either). */ + +#ifndef __s390x__ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + if (n_gpr == MAX_GPRARGS-1) + n_gpr = MAX_GPRARGS; + if (n_gpr < MAX_GPRARGS) + n_gpr += 2; + else + n_ov += 2; + break; +#endif + + /* Everything else is passed in GPRs (until MAX_GPRARGS + have been used) or overflows to the stack. */ + + default: + if (n_gpr < MAX_GPRARGS) + n_gpr++; + else + n_ov++; + break; + } + } + + /* Total stack space as required for overflow arguments + and temporary structure copies. */ + + cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size; + + return FFI_OK; +} + +/*======================== End of Routine ============================*/ + +/*====================================================================*/ +/* */ +/* Name - ffi_call. */ +/* */ +/* Function - Call the FFI routine. */ +/* */ +/*====================================================================*/ + +static void +ffi_call_int(ffi_cif *cif, + void (*fn)(void), + void *rvalue, + void **avalue, + void *closure) +{ + int ret_type = cif->flags; + size_t rsize = 0, bytes = cif->bytes; + unsigned char *stack, *p_struct; + struct call_frame *frame; + unsigned long *p_ov, *p_gpr; + unsigned long long *p_fpr; + int n_fpr, n_gpr, n_ov, i, n; + ffi_type **arg_types; + + FFI_ASSERT (cif->abi == FFI_SYSV); + + /* If we don't have a return value, we need to fake one. */ + if (rvalue == NULL) + { + if (ret_type & FFI390_RET_IN_MEM) + rsize = cif->rtype->size; + else + ret_type = FFI390_RET_VOID; + } + + /* The stack space will be filled with those areas: + + dummy structure return (highest addresses) + FPR argument register save area + GPR argument register save area + stack frame for ffi_call_SYSV + temporary struct copies + overflow argument area (lowest addresses) + + We set up the following pointers: + + p_fpr: bottom of the FPR area (growing upwards) + p_gpr: bottom of the GPR area (growing upwards) + p_ov: bottom of the overflow area (growing upwards) + p_struct: top of the struct copy area (growing downwards) + + All areas are kept aligned to twice the word size. + + Note that we're going to create the stack frame for both + ffi_call_SYSV _and_ the target function right here. This + works because we don't make any function calls with more + than 5 arguments (indeed only memcpy and ffi_call_SYSV), + and thus we don't have any stacked outgoing parameters. */ + + stack = alloca (bytes + sizeof(struct call_frame) + rsize); + frame = (struct call_frame *)(stack + bytes); + if (rsize) + rvalue = frame + 1; + + /* Link the new frame back to the one from this function. */ + frame->back_chain = __builtin_frame_address (0); + + /* Fill in all of the argument stuff. */ + p_ov = (unsigned long *)stack; + p_struct = (unsigned char *)frame; + p_gpr = frame->gpr_args; + p_fpr = frame->fpr_args; + n_fpr = n_gpr = n_ov = 0; + + /* If we returning a structure then we set the first parameter register + to the address of where we are returning this structure. */ + if (cif->flags & FFI390_RET_IN_MEM) + p_gpr[n_gpr++] = (uintptr_t) rvalue; + + /* Now for the arguments. */ + arg_types = cif->arg_types; + for (i = 0, n = cif->nargs; i < n; ++i) + { + ffi_type *ty = arg_types[i]; + void *arg = avalue[i]; + int type = ty->type; + ffi_arg val; + + restart: + switch (type) + { + case FFI_TYPE_SINT8: + val = *(SINT8 *)arg; + goto do_int; + case FFI_TYPE_UINT8: + val = *(UINT8 *)arg; + goto do_int; + case FFI_TYPE_SINT16: + val = *(SINT16 *)arg; + goto do_int; + case FFI_TYPE_UINT16: + val = *(UINT16 *)arg; + goto do_int; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + val = *(SINT32 *)arg; + goto do_int; + case FFI_TYPE_UINT32: + val = *(UINT32 *)arg; + goto do_int; + case FFI_TYPE_POINTER: + val = *(uintptr_t *)arg; + do_int: + *(n_gpr < MAX_GPRARGS ? p_gpr + n_gpr++ : p_ov + n_ov++) = val; + break; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: +#ifdef __s390x__ + val = *(UINT64 *)arg; + goto do_int; +#else + if (n_gpr == MAX_GPRARGS-1) + n_gpr = MAX_GPRARGS; + if (n_gpr < MAX_GPRARGS) + p_gpr[n_gpr++] = ((UINT32 *) arg)[0], + p_gpr[n_gpr++] = ((UINT32 *) arg)[1]; + else + p_ov[n_ov++] = ((UINT32 *) arg)[0], + p_ov[n_ov++] = ((UINT32 *) arg)[1]; +#endif + break; + + case FFI_TYPE_DOUBLE: + if (n_fpr < MAX_FPRARGS) + p_fpr[n_fpr++] = *(UINT64 *) arg; + else + { +#ifdef __s390x__ + p_ov[n_ov++] = *(UINT64 *) arg; +#else + p_ov[n_ov++] = ((UINT32 *) arg)[0], + p_ov[n_ov++] = ((UINT32 *) arg)[1]; +#endif + } + break; + + case FFI_TYPE_FLOAT: + val = *(UINT32 *)arg; + if (n_fpr < MAX_FPRARGS) + p_fpr[n_fpr++] = (UINT64)val << 32; + else + p_ov[n_ov++] = val; + break; + + case FFI_TYPE_STRUCT: + /* Check how a structure type is passed. */ + type = ffi_check_struct_type (ty); + /* Some structures are passed via a type they contain. */ + if (type != FFI_TYPE_POINTER) + goto restart; + /* ... otherwise, passed by reference. fallthru. */ + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + /* 16-byte long double is passed via reference. */ +#endif + case FFI_TYPE_COMPLEX: + /* Complex types are passed via reference. */ + p_struct -= ROUND_SIZE (ty->size); + memcpy (p_struct, arg, ty->size); + val = (uintptr_t)p_struct; + goto do_int; + + default: + FFI_ASSERT (0); + break; + } + } + + ffi_call_SYSV (frame, ret_type & FFI360_RET_MASK, rvalue, fn, closure); +} + +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_call_int(cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int(cif, fn, rvalue, avalue, closure); +} + +/*======================== End of Routine ============================*/ + +/*====================================================================*/ +/* */ +/* Name - ffi_closure_helper_SYSV. */ +/* */ +/* Function - Call a FFI closure target function. */ +/* */ +/*====================================================================*/ + +void FFI_HIDDEN +ffi_closure_helper_SYSV (ffi_cif *cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + unsigned long *p_gpr, + unsigned long long *p_fpr, + unsigned long *p_ov) +{ + unsigned long long ret_buffer; + + void *rvalue = &ret_buffer; + void **avalue; + void **p_arg; + + int n_gpr = 0; + int n_fpr = 0; + int n_ov = 0; + + ffi_type **ptr; + int i; + + /* Allocate buffer for argument list pointers. */ + p_arg = avalue = alloca (cif->nargs * sizeof (void *)); + + /* If we returning a structure, pass the structure address + directly to the target function. Otherwise, have the target + function store the return value to the GPR save area. */ + if (cif->flags & FFI390_RET_IN_MEM) + rvalue = (void *) p_gpr[n_gpr++]; + + /* Now for the arguments. */ + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++) + { + int deref_struct_pointer = 0; + int type = (*ptr)->type; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + /* 16-byte long double is passed like a struct. */ + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + + /* Check how a structure type is passed. */ + if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX) + { + if (type == FFI_TYPE_COMPLEX) + type = FFI_TYPE_POINTER; + else + type = ffi_check_struct_type (*ptr); + + /* If we pass the struct via pointer, remember to + retrieve the pointer later. */ + if (type == FFI_TYPE_POINTER) + deref_struct_pointer = 1; + } + + /* Pointers are passed like UINTs of the same size. */ + if (type == FFI_TYPE_POINTER) + { +#ifdef __s390x__ + type = FFI_TYPE_UINT64; +#else + type = FFI_TYPE_UINT32; +#endif + } + + /* Now handle all primitive int/float data types. */ + switch (type) + { + case FFI_TYPE_DOUBLE: + if (n_fpr < MAX_FPRARGS) + *p_arg = &p_fpr[n_fpr++]; + else + *p_arg = &p_ov[n_ov], + n_ov += sizeof (double) / sizeof (long); + break; + + case FFI_TYPE_FLOAT: + if (n_fpr < MAX_FPRARGS) + *p_arg = &p_fpr[n_fpr++]; + else + *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4; + break; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: +#ifdef __s390x__ + if (n_gpr < MAX_GPRARGS) + *p_arg = &p_gpr[n_gpr++]; + else + *p_arg = &p_ov[n_ov++]; +#else + if (n_gpr == MAX_GPRARGS-1) + n_gpr = MAX_GPRARGS; + if (n_gpr < MAX_GPRARGS) + *p_arg = &p_gpr[n_gpr], n_gpr += 2; + else + *p_arg = &p_ov[n_ov], n_ov += 2; +#endif + break; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + if (n_gpr < MAX_GPRARGS) + *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4; + else + *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4; + break; + + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + if (n_gpr < MAX_GPRARGS) + *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2; + else + *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2; + break; + + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + if (n_gpr < MAX_GPRARGS) + *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1; + else + *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1; + break; + + default: + FFI_ASSERT (0); + break; + } + + /* If this is a struct passed via pointer, we need to + actually retrieve that pointer. */ + if (deref_struct_pointer) + *p_arg = *(void **)*p_arg; + } + + + /* Call the target function. */ + (fun) (cif, rvalue, avalue, user_data); + + /* Convert the return value. */ + switch (cif->rtype->type) + { + /* Void is easy, and so is struct. */ + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: +#endif + break; + + /* Floating point values are returned in fpr 0. */ + case FFI_TYPE_FLOAT: + p_fpr[0] = (long long) *(unsigned int *) rvalue << 32; + break; + + case FFI_TYPE_DOUBLE: + p_fpr[0] = *(unsigned long long *) rvalue; + break; + + /* Integer values are returned in gpr 2 (and gpr 3 + for 64-bit values on 31-bit machines). */ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: +#ifdef __s390x__ + p_gpr[0] = *(unsigned long *) rvalue; +#else + p_gpr[0] = ((unsigned long *) rvalue)[0], + p_gpr[1] = ((unsigned long *) rvalue)[1]; +#endif + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_UINT8: + p_gpr[0] = *(unsigned long *) rvalue; + break; + + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_SINT16: + case FFI_TYPE_SINT8: + p_gpr[0] = *(signed long *) rvalue; + break; + + default: + FFI_ASSERT (0); + break; + } +} + +/*======================== End of Routine ============================*/ + +/*====================================================================*/ +/* */ +/* Name - ffi_prep_closure_loc. */ +/* */ +/* Function - Prepare a FFI closure. */ +/* */ +/*====================================================================*/ + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) +{ + static unsigned short const template[] = { + 0x0d10, /* basr %r1,0 */ +#ifndef __s390x__ + 0x9801, 0x1006, /* lm %r0,%r1,6(%r1) */ +#else + 0xeb01, 0x100e, 0x0004, /* lmg %r0,%r1,14(%r1) */ +#endif + 0x07f1 /* br %r1 */ + }; + + unsigned long *tramp = (unsigned long *)&closure->tramp; + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + memcpy (tramp, template, sizeof(template)); + tramp[2] = (unsigned long)codeloc; + tramp[3] = (unsigned long)&ffi_closure_SYSV; + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +/*======================== End of Routine ============================*/ + +/* Build a Go language closure. */ + +ffi_status +ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif, + void (*fun)(ffi_cif*,void*,void**,void*)) +{ + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + closure->tramp = ffi_go_closure_SYSV; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/s390/ffitarget.h b/circuitpython/lib/libffi/src/s390/ffitarget.h new file mode 100644 index 0000000..d8a4ee4 --- /dev/null +++ b/circuitpython/lib/libffi/src/s390/ffitarget.h @@ -0,0 +1,70 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for S390. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#if defined (__s390x__) +#ifndef S390X +#define S390X +#endif +#endif + +/* ---- System specific configurations ----------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION +#define FFI_TARGET_HAS_COMPLEX_TYPE + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_GO_CLOSURES 1 +#ifdef S390X +#define FFI_TRAMPOLINE_SIZE 32 +#else +#define FFI_TRAMPOLINE_SIZE 16 +#endif +#define FFI_NATIVE_RAW_API 0 + +#endif + diff --git a/circuitpython/lib/libffi/src/s390/internal.h b/circuitpython/lib/libffi/src/s390/internal.h new file mode 100644 index 0000000..b875578 --- /dev/null +++ b/circuitpython/lib/libffi/src/s390/internal.h @@ -0,0 +1,11 @@ +/* If these values change, sysv.S must be adapted! */ +#define FFI390_RET_DOUBLE 0 +#define FFI390_RET_FLOAT 1 +#define FFI390_RET_INT64 2 +#define FFI390_RET_INT32 3 +#define FFI390_RET_VOID 4 + +#define FFI360_RET_MASK 7 +#define FFI390_RET_IN_MEM 8 + +#define FFI390_RET_STRUCT (FFI390_RET_VOID | FFI390_RET_IN_MEM) diff --git a/circuitpython/lib/libffi/src/s390/sysv.S b/circuitpython/lib/libffi/src/s390/sysv.S new file mode 100644 index 0000000..c4b5006 --- /dev/null +++ b/circuitpython/lib/libffi/src/s390/sysv.S @@ -0,0 +1,325 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2000 Software AG + Copyright (c) 2008 Red Hat, Inc. + + S390 Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + + .text + +#ifndef __s390x__ + + # r2: frame + # r3: ret_type + # r4: ret_addr + # r5: fun + # r6: closure + + # This assumes we are using gas. + .balign 8 + .globl ffi_call_SYSV + FFI_HIDDEN(ffi_call_SYSV) + .type ffi_call_SYSV,%function +ffi_call_SYSV: + .cfi_startproc + st %r6,44(%r2) # Save registers + stm %r12,%r14,48(%r2) + lr %r13,%r2 # Install frame pointer + .cfi_rel_offset r6, 44 + .cfi_rel_offset r12, 48 + .cfi_rel_offset r13, 52 + .cfi_rel_offset r14, 56 + .cfi_def_cfa_register r13 + st %r2,0(%r15) # Set up back chain + sla %r3,3 # ret_type *= 8 + lr %r12,%r4 # Save ret_addr + lr %r1,%r5 # Save fun + lr %r0,%r6 # Install static chain + + # Set return address, so that there is only one indirect jump. +#ifdef HAVE_AS_S390_ZARCH + larl %r14,.Ltable + ar %r14,%r3 +#else + basr %r14,0 +0: la %r14,.Ltable-0b(%r14,%r3) +#endif + + lm %r2,%r6,8(%r13) # Load arguments + ld %f0,64(%r13) + ld %f2,72(%r13) + br %r1 # ... and call function + + .balign 8 +.Ltable: +# FFI390_RET_DOUBLE + std %f0,0(%r12) + j .Ldone + + .balign 8 +# FFI390_RET_FLOAT + ste %f0,0(%r12) + j .Ldone + + .balign 8 +# FFI390_RET_INT64 + st %r3,4(%r12) + nop + # fallthru + + .balign 8 +# FFI390_RET_INT32 + st %r2,0(%r12) + nop + # fallthru + + .balign 8 +# FFI390_RET_VOID +.Ldone: + l %r14,56(%r13) + l %r12,48(%r13) + l %r6,44(%r13) + l %r13,52(%r13) + .cfi_restore 14 + .cfi_restore 13 + .cfi_restore 12 + .cfi_restore 6 + .cfi_def_cfa r15, 96 + br %r14 + .cfi_endproc + .size ffi_call_SYSV,.-ffi_call_SYSV + + + .balign 8 + .globl ffi_go_closure_SYSV + FFI_HIDDEN(ffi_go_closure_SYSV) + .type ffi_go_closure_SYSV,%function +ffi_go_closure_SYSV: + .cfi_startproc + stm %r2,%r6,8(%r15) # Save arguments + lr %r4,%r0 # Load closure -> user_data + l %r2,4(%r4) # ->cif + l %r3,8(%r4) # ->fun + j .Ldoclosure + .cfi_endproc + + .balign 8 + .globl ffi_closure_SYSV + FFI_HIDDEN(ffi_closure_SYSV) + .type ffi_closure_SYSV,%function +ffi_closure_SYSV: + .cfi_startproc + stm %r2,%r6,8(%r15) # Save arguments + lr %r4,%r0 # Closure + l %r2,16(%r4) # ->cif + l %r3,20(%r4) # ->fun + l %r4,24(%r4) # ->user_data +.Ldoclosure: + stm %r12,%r15,48(%r15) # Save registers + lr %r12,%r15 + .cfi_def_cfa_register r12 + .cfi_rel_offset r6, 24 + .cfi_rel_offset r12, 48 + .cfi_rel_offset r13, 52 + .cfi_rel_offset r14, 56 + .cfi_rel_offset r15, 60 +#ifndef HAVE_AS_S390_ZARCH + basr %r13,0 # Set up base register +.Lcbase: + l %r1,.Lchelper-.Lcbase(%r13) # Get helper function +#endif + ahi %r15,-96-8 # Set up stack frame + st %r12,0(%r15) # Set up back chain + + std %f0,64(%r12) # Save fp arguments + std %f2,72(%r12) + + la %r5,96(%r12) # Overflow + st %r5,96(%r15) + la %r6,64(%r12) # FPRs + la %r5,8(%r12) # GPRs +#ifdef HAVE_AS_S390_ZARCH + brasl %r14,ffi_closure_helper_SYSV +#else + bas %r14,0(%r1,%r13) # Call helper +#endif + + lr %r15,%r12 + .cfi_def_cfa_register r15 + lm %r12,%r14,48(%r12) # Restore saved registers + l %r6,24(%r15) + ld %f0,64(%r15) # Load return registers + lm %r2,%r3,8(%r15) + br %r14 + .cfi_endproc + +#ifndef HAVE_AS_S390_ZARCH + .align 4 +.Lchelper: + .long ffi_closure_helper_SYSV-.Lcbase +#endif + + .size ffi_closure_SYSV,.-ffi_closure_SYSV + +#else + + # r2: frame + # r3: ret_type + # r4: ret_addr + # r5: fun + # r6: closure + + # This assumes we are using gas. + .balign 8 + .globl ffi_call_SYSV + FFI_HIDDEN(ffi_call_SYSV) + .type ffi_call_SYSV,%function +ffi_call_SYSV: + .cfi_startproc + stg %r6,88(%r2) # Save registers + stmg %r12,%r14,96(%r2) + lgr %r13,%r2 # Install frame pointer + .cfi_rel_offset r6, 88 + .cfi_rel_offset r12, 96 + .cfi_rel_offset r13, 104 + .cfi_rel_offset r14, 112 + .cfi_def_cfa_register r13 + stg %r2,0(%r15) # Set up back chain + larl %r14,.Ltable # Set up return address + slag %r3,%r3,3 # ret_type *= 8 + lgr %r12,%r4 # Save ret_addr + lgr %r1,%r5 # Save fun + lgr %r0,%r6 # Install static chain + agr %r14,%r3 + lmg %r2,%r6,16(%r13) # Load arguments + ld %f0,128(%r13) + ld %f2,136(%r13) + ld %f4,144(%r13) + ld %f6,152(%r13) + br %r1 # ... and call function + + .balign 8 +.Ltable: +# FFI390_RET_DOUBLE + std %f0,0(%r12) + j .Ldone + + .balign 8 +# FFI390_RET_DOUBLE + ste %f0,0(%r12) + j .Ldone + + .balign 8 +# FFI390_RET_INT64 + stg %r2,0(%r12) + + .balign 8 +# FFI390_RET_INT32 + # Never used, as we always store type ffi_arg. + # But the stg above is 6 bytes and we cannot + # jump around this case, so fall through. + nop + nop + + .balign 8 +# FFI390_RET_VOID +.Ldone: + lg %r14,112(%r13) + lg %r12,96(%r13) + lg %r6,88(%r13) + lg %r13,104(%r13) + .cfi_restore r14 + .cfi_restore r13 + .cfi_restore r12 + .cfi_restore r6 + .cfi_def_cfa r15, 160 + br %r14 + .cfi_endproc + .size ffi_call_SYSV,.-ffi_call_SYSV + + + .balign 8 + .globl ffi_go_closure_SYSV + FFI_HIDDEN(ffi_go_closure_SYSV) + .type ffi_go_closure_SYSV,%function +ffi_go_closure_SYSV: + .cfi_startproc + stmg %r2,%r6,16(%r15) # Save arguments + lgr %r4,%r0 # Load closure -> user_data + lg %r2,8(%r4) # ->cif + lg %r3,16(%r4) # ->fun + j .Ldoclosure + .cfi_endproc + .size ffi_go_closure_SYSV,.-ffi_go_closure_SYSV + + + .balign 8 + .globl ffi_closure_SYSV + FFI_HIDDEN(ffi_closure_SYSV) + .type ffi_closure_SYSV,%function +ffi_closure_SYSV: + .cfi_startproc + stmg %r2,%r6,16(%r15) # Save arguments + lgr %r4,%r0 # Load closure + lg %r2,32(%r4) # ->cif + lg %r3,40(%r4) # ->fun + lg %r4,48(%r4) # ->user_data +.Ldoclosure: + stmg %r13,%r15,104(%r15) # Save registers + lgr %r13,%r15 + .cfi_def_cfa_register r13 + .cfi_rel_offset r6, 48 + .cfi_rel_offset r13, 104 + .cfi_rel_offset r14, 112 + .cfi_rel_offset r15, 120 + aghi %r15,-160-16 # Set up stack frame + stg %r13,0(%r15) # Set up back chain + + std %f0,128(%r13) # Save fp arguments + std %f2,136(%r13) + std %f4,144(%r13) + std %f6,152(%r13) + la %r5,160(%r13) # Overflow + stg %r5,160(%r15) + la %r6,128(%r13) # FPRs + la %r5,16(%r13) # GPRs + brasl %r14,ffi_closure_helper_SYSV # Call helper + + lgr %r15,%r13 + .cfi_def_cfa_register r15 + lmg %r13,%r14,104(%r13) # Restore saved registers + lg %r6,48(%r15) + ld %f0,128(%r15) # Load return registers + lg %r2,16(%r15) + br %r14 + .cfi_endproc + .size ffi_closure_SYSV,.-ffi_closure_SYSV +#endif /* !s390x */ + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/sh/ffi.c b/circuitpython/lib/libffi/src/sh/ffi.c new file mode 100644 index 0000000..9ec86bf --- /dev/null +++ b/circuitpython/lib/libffi/src/sh/ffi.c @@ -0,0 +1,717 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2002-2008, 2012 Kaz Kojima + Copyright (c) 2008 Red Hat, Inc. + + SuperH Foreign Function Interface + + 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 +#include + +#include + +#define NGREGARG 4 +#if defined(__SH4__) +#define NFREGARG 8 +#endif + +#if defined(__HITACHI__) +#define STRUCT_VALUE_ADDRESS_WITH_ARG 1 +#else +#define STRUCT_VALUE_ADDRESS_WITH_ARG 0 +#endif + +/* If the structure has essentially an unique element, return its type. */ +static int +simple_type (ffi_type *arg) +{ + if (arg->type != FFI_TYPE_STRUCT) + return arg->type; + else if (arg->elements[1]) + return FFI_TYPE_STRUCT; + + return simple_type (arg->elements[0]); +} + +static int +return_type (ffi_type *arg) +{ + unsigned short type; + + if (arg->type != FFI_TYPE_STRUCT) + return arg->type; + + type = simple_type (arg->elements[0]); + if (! arg->elements[1]) + { + switch (type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + return FFI_TYPE_INT; + + default: + return type; + } + } + + /* gcc uses r0/r1 pair for some kind of structures. */ + if (arg->size <= 2 * sizeof (int)) + { + int i = 0; + ffi_type *e; + + while ((e = arg->elements[i++])) + { + type = simple_type (e); + switch (type) + { + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_INT: + case FFI_TYPE_FLOAT: + return FFI_TYPE_UINT64; + + default: + break; + } + } + } + + return FFI_TYPE_STRUCT; +} + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +void ffi_prep_args(char *stack, extended_cif *ecif) +{ + register unsigned int i; + register int tmp; + register unsigned int avn; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + int greg, ireg; +#if defined(__SH4__) + int freg = 0; +#endif + + tmp = 0; + argp = stack; + + if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += 4; + ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0; + } + else + ireg = 0; + + /* Set arguments for registers. */ + greg = ireg; + avn = ecif->cif->nargs; + p_argv = ecif->avalue; + + for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++) + { + size_t z; + + z = (*p_arg)->size; + if (z < sizeof(int)) + { + if (greg++ >= NGREGARG) + continue; + + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_STRUCT: + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + argp += z; + } + else if (z == sizeof(int)) + { +#if defined(__SH4__) + if ((*p_arg)->type == FFI_TYPE_FLOAT) + { + if (freg++ >= NFREGARG) + continue; + } + else +#endif + { + if (greg++ >= NGREGARG) + continue; + } + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + argp += z; + } +#if defined(__SH4__) + else if ((*p_arg)->type == FFI_TYPE_DOUBLE) + { + if (freg + 1 >= NFREGARG) + continue; + freg = (freg + 1) & ~1; + freg += 2; + memcpy (argp, *p_argv, z); + argp += z; + } +#endif + else + { + int n = (z + sizeof (int) - 1) / sizeof (int); +#if defined(__SH4__) + if (greg + n - 1 >= NGREGARG) + continue; +#else + if (greg >= NGREGARG) + continue; +#endif + greg += n; + memcpy (argp, *p_argv, z); + argp += n * sizeof (int); + } + } + + /* Set arguments on stack. */ + greg = ireg; +#if defined(__SH4__) + freg = 0; +#endif + p_argv = ecif->avalue; + + for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++) + { + size_t z; + + z = (*p_arg)->size; + if (z < sizeof(int)) + { + if (greg++ < NGREGARG) + continue; + + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_STRUCT: + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + argp += z; + } + else if (z == sizeof(int)) + { +#if defined(__SH4__) + if ((*p_arg)->type == FFI_TYPE_FLOAT) + { + if (freg++ < NFREGARG) + continue; + } + else +#endif + { + if (greg++ < NGREGARG) + continue; + } + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + argp += z; + } +#if defined(__SH4__) + else if ((*p_arg)->type == FFI_TYPE_DOUBLE) + { + if (freg + 1 < NFREGARG) + { + freg = (freg + 1) & ~1; + freg += 2; + continue; + } + memcpy (argp, *p_argv, z); + argp += z; + } +#endif + else + { + int n = (z + sizeof (int) - 1) / sizeof (int); + if (greg + n - 1 < NGREGARG) + { + greg += n; + continue; + } +#if (! defined(__SH4__)) + else if (greg < NGREGARG) + { + greg = NGREGARG; + continue; + } +#endif + memcpy (argp, *p_argv, z); + argp += n * sizeof (int); + } + } + + return; +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + int i, j; + int size, type; + int n, m; + int greg; +#if defined(__SH4__) + int freg = 0; +#endif + + cif->flags = 0; + + greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) && + STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0; + +#if defined(__SH4__) + for (i = j = 0; i < cif->nargs && j < 12; i++) + { + type = (cif->arg_types)[i]->type; + switch (type) + { + case FFI_TYPE_FLOAT: + if (freg >= NFREGARG) + continue; + freg++; + cif->flags += ((cif->arg_types)[i]->type) << (2 * j); + j++; + break; + + case FFI_TYPE_DOUBLE: + if ((freg + 1) >= NFREGARG) + continue; + freg = (freg + 1) & ~1; + freg += 2; + cif->flags += ((cif->arg_types)[i]->type) << (2 * j); + j++; + break; + + default: + size = (cif->arg_types)[i]->size; + n = (size + sizeof (int) - 1) / sizeof (int); + if (greg + n - 1 >= NGREGARG) + continue; + greg += n; + for (m = 0; m < n; m++) + cif->flags += FFI_TYPE_INT << (2 * j++); + break; + } + } +#else + for (i = j = 0; i < cif->nargs && j < 4; i++) + { + size = (cif->arg_types)[i]->size; + n = (size + sizeof (int) - 1) / sizeof (int); + if (greg >= NGREGARG) + continue; + else if (greg + n - 1 >= NGREGARG) + n = NGREGARG - greg; + greg += n; + for (m = 0; m < n; m++) + cif->flags += FFI_TYPE_INT << (2 * j++); + } +#endif + + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_STRUCT: + cif->flags += (unsigned) (return_type (cif->rtype)) << 24; + break; + + case FFI_TYPE_VOID: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags += (unsigned) cif->rtype->type << 24; + break; + + default: + cif->flags += FFI_TYPE_INT << 24; + break; + } + + return FFI_OK; +} + +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)(void)); + +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + UINT64 trvalue; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if (cif->rtype->type == FFI_TYPE_STRUCT + && return_type (cif->rtype) != FFI_TYPE_STRUCT) + ecif.rvalue = &trvalue; + else if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, + fn); + break; + default: + FFI_ASSERT(0); + break; + } + + if (rvalue + && cif->rtype->type == FFI_TYPE_STRUCT + && return_type (cif->rtype) != FFI_TYPE_STRUCT) + memcpy (rvalue, &trvalue, cif->rtype->size); +} + +extern void ffi_closure_SYSV (void); +#if defined(__SH4__) +extern void __ic_invalidate (void *line); +#endif + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp; + unsigned int insn; + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + tramp = (unsigned int *) &closure->tramp[0]; + /* Set T bit if the function returns a struct pointed with R2. */ + insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT + ? 0x0018 /* sett */ + : 0x0008 /* clrt */); + +#ifdef __LITTLE_ENDIAN__ + tramp[0] = 0xd301d102; + tramp[1] = 0x0000412b | (insn << 16); +#else + tramp[0] = 0xd102d301; + tramp[1] = 0x412b0000 | insn; +#endif + *(void **) &tramp[2] = (void *)codeloc; /* ctx */ + *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */ + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + +#if defined(__SH4__) + /* Flush the icache. */ + __ic_invalidate(codeloc); +#endif + + return FFI_OK; +} + +/* Basically the trampoline invokes ffi_closure_SYSV, and on + * entry, r3 holds the address of the closure. + * After storing the registers that could possibly contain + * parameters to be passed into the stack frame and setting + * up space for a return value, ffi_closure_SYSV invokes the + * following helper function to do most of the work. + */ + +#ifdef __LITTLE_ENDIAN__ +#define OFS_INT8 0 +#define OFS_INT16 0 +#else +#define OFS_INT8 3 +#define OFS_INT16 2 +#endif + +int +ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, + unsigned long *pgr, unsigned long *pfr, + unsigned long *pst) +{ + void **avalue; + ffi_type **p_arg; + int i, avn; + int ireg, greg = 0; +#if defined(__SH4__) + int freg = 0; +#endif + ffi_cif *cif; + + cif = closure->cif; + avalue = alloca(cif->nargs * sizeof(void *)); + + /* Copy the caller's structure return value address so that the closure + returns the data directly to the caller. */ + if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG) + { + rvalue = (void *) *pgr++; + ireg = 1; + } + else + ireg = 0; + + cif = closure->cif; + greg = ireg; + avn = cif->nargs; + + /* Grab the addresses of the arguments from the stack frame. */ + for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + if (z < sizeof(int)) + { + if (greg++ >= NGREGARG) + continue; + + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + avalue[i] = (((char *)pgr) + OFS_INT8); + break; + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + avalue[i] = (((char *)pgr) + OFS_INT16); + break; + + case FFI_TYPE_STRUCT: + avalue[i] = pgr; + break; + + default: + FFI_ASSERT(0); + } + pgr++; + } + else if (z == sizeof(int)) + { +#if defined(__SH4__) + if ((*p_arg)->type == FFI_TYPE_FLOAT) + { + if (freg++ >= NFREGARG) + continue; + avalue[i] = pfr; + pfr++; + } + else +#endif + { + if (greg++ >= NGREGARG) + continue; + avalue[i] = pgr; + pgr++; + } + } +#if defined(__SH4__) + else if ((*p_arg)->type == FFI_TYPE_DOUBLE) + { + if (freg + 1 >= NFREGARG) + continue; + if (freg & 1) + pfr++; + freg = (freg + 1) & ~1; + freg += 2; + avalue[i] = pfr; + pfr += 2; + } +#endif + else + { + int n = (z + sizeof (int) - 1) / sizeof (int); +#if defined(__SH4__) + if (greg + n - 1 >= NGREGARG) + continue; +#else + if (greg >= NGREGARG) + continue; +#endif + greg += n; + avalue[i] = pgr; + pgr += n; + } + } + + greg = ireg; +#if defined(__SH4__) + freg = 0; +#endif + + for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + if (z < sizeof(int)) + { + if (greg++ < NGREGARG) + continue; + + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + avalue[i] = (((char *)pst) + OFS_INT8); + break; + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + avalue[i] = (((char *)pst) + OFS_INT16); + break; + + case FFI_TYPE_STRUCT: + avalue[i] = pst; + break; + + default: + FFI_ASSERT(0); + } + pst++; + } + else if (z == sizeof(int)) + { +#if defined(__SH4__) + if ((*p_arg)->type == FFI_TYPE_FLOAT) + { + if (freg++ < NFREGARG) + continue; + } + else +#endif + { + if (greg++ < NGREGARG) + continue; + } + avalue[i] = pst; + pst++; + } +#if defined(__SH4__) + else if ((*p_arg)->type == FFI_TYPE_DOUBLE) + { + if (freg + 1 < NFREGARG) + { + freg = (freg + 1) & ~1; + freg += 2; + continue; + } + avalue[i] = pst; + pst += 2; + } +#endif + else + { + int n = (z + sizeof (int) - 1) / sizeof (int); + if (greg + n - 1 < NGREGARG) + { + greg += n; + continue; + } +#if (! defined(__SH4__)) + else if (greg < NGREGARG) + { + greg += n; + pst += greg - NGREGARG; + continue; + } +#endif + avalue[i] = pst; + pst += n; + } + } + + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + /* Tell ffi_closure_SYSV how to perform return type promotions. */ + return return_type (cif->rtype); +} diff --git a/circuitpython/lib/libffi/src/sh/ffitarget.h b/circuitpython/lib/libffi/src/sh/ffitarget.h new file mode 100644 index 0000000..a36bf42 --- /dev/null +++ b/circuitpython/lib/libffi/src/sh/ffitarget.h @@ -0,0 +1,54 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for SuperH. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 16 +#define FFI_NATIVE_RAW_API 0 + +#endif + diff --git a/circuitpython/lib/libffi/src/sh/sysv.S b/circuitpython/lib/libffi/src/sh/sysv.S new file mode 100644 index 0000000..5be7516 --- /dev/null +++ b/circuitpython/lib/libffi/src/sh/sysv.S @@ -0,0 +1,850 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2002, 2003, 2004, 2006, 2008 Kaz Kojima + + SuperH Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include +#ifdef HAVE_MACHINE_ASM_H +#include +#else +/* XXX these lose for some platforms, I'm sure. */ +#define CNAME(x) x +#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): +#endif + +#if defined(__HITACHI__) +#define STRUCT_VALUE_ADDRESS_WITH_ARG 1 +#else +#define STRUCT_VALUE_ADDRESS_WITH_ARG 0 +#endif + +.text + + # r4: ffi_prep_args + # r5: &ecif + # r6: bytes + # r7: flags + # sp+0: rvalue + # sp+4: fn + + # This assumes we are using gas. +ENTRY(ffi_call_SYSV) + # Save registers +.LFB1: + mov.l r8,@-r15 +.LCFI0: + mov.l r9,@-r15 +.LCFI1: + mov.l r10,@-r15 +.LCFI2: + mov.l r12,@-r15 +.LCFI3: + mov.l r14,@-r15 +.LCFI4: + sts.l pr,@-r15 +.LCFI5: + mov r15,r14 +.LCFI6: +#if defined(__SH4__) + mov r6,r8 + mov r7,r9 + + sub r6,r15 + add #-16,r15 + mov #~7,r0 + and r0,r15 + + mov r4,r0 + jsr @r0 + mov r15,r4 + + mov r9,r1 + shlr8 r9 + shlr8 r9 + shlr8 r9 + + mov #FFI_TYPE_STRUCT,r2 + cmp/eq r2,r9 + bf 1f +#if STRUCT_VALUE_ADDRESS_WITH_ARG + mov.l @r15+,r4 + bra 2f + mov #5,r2 +#else + mov.l @r15+,r10 +#endif +1: + mov #4,r2 +2: + mov #4,r3 + +L_pass: + cmp/pl r8 + bf L_call_it + + mov r1,r0 + and #3,r0 + +L_pass_d: + cmp/eq #FFI_TYPE_DOUBLE,r0 + bf L_pass_f + + mov r3,r0 + and #1,r0 + tst r0,r0 + bt 1f + add #1,r3 +1: + mov #12,r0 + cmp/hs r0,r3 + bt/s 3f + shlr2 r1 + bsr L_pop_d + nop +3: + add #2,r3 + bra L_pass + add #-8,r8 + +L_pop_d: + mov r3,r0 + add r0,r0 + add r3,r0 + add #-12,r0 + braf r0 + nop +#ifdef __LITTLE_ENDIAN__ + fmov.s @r15+,fr5 + rts + fmov.s @r15+,fr4 + fmov.s @r15+,fr7 + rts + fmov.s @r15+,fr6 + fmov.s @r15+,fr9 + rts + fmov.s @r15+,fr8 + fmov.s @r15+,fr11 + rts + fmov.s @r15+,fr10 +#else + fmov.s @r15+,fr4 + rts + fmov.s @r15+,fr5 + fmov.s @r15+,fr6 + rts + fmov.s @r15+,fr7 + fmov.s @r15+,fr8 + rts + fmov.s @r15+,fr9 + fmov.s @r15+,fr10 + rts + fmov.s @r15+,fr11 +#endif + +L_pass_f: + cmp/eq #FFI_TYPE_FLOAT,r0 + bf L_pass_i + + mov #12,r0 + cmp/hs r0,r3 + bt/s 2f + shlr2 r1 + bsr L_pop_f + nop +2: + add #1,r3 + bra L_pass + add #-4,r8 + +L_pop_f: + mov r3,r0 + shll2 r0 + add #-16,r0 + braf r0 + nop +#ifdef __LITTLE_ENDIAN__ + rts + fmov.s @r15+,fr5 + rts + fmov.s @r15+,fr4 + rts + fmov.s @r15+,fr7 + rts + fmov.s @r15+,fr6 + rts + fmov.s @r15+,fr9 + rts + fmov.s @r15+,fr8 + rts + fmov.s @r15+,fr11 + rts + fmov.s @r15+,fr10 +#else + rts + fmov.s @r15+,fr4 + rts + fmov.s @r15+,fr5 + rts + fmov.s @r15+,fr6 + rts + fmov.s @r15+,fr7 + rts + fmov.s @r15+,fr8 + rts + fmov.s @r15+,fr9 + rts + fmov.s @r15+,fr10 + rts + fmov.s @r15+,fr11 +#endif + +L_pass_i: + cmp/eq #FFI_TYPE_INT,r0 + bf L_call_it + + mov #8,r0 + cmp/hs r0,r2 + bt/s 2f + shlr2 r1 + bsr L_pop_i + nop +2: + add #1,r2 + bra L_pass + add #-4,r8 + +L_pop_i: + mov r2,r0 + shll2 r0 + add #-16,r0 + braf r0 + nop + rts + mov.l @r15+,r4 + rts + mov.l @r15+,r5 + rts + mov.l @r15+,r6 + rts + mov.l @r15+,r7 + +L_call_it: + # call function +#if (! STRUCT_VALUE_ADDRESS_WITH_ARG) + mov r10, r2 +#endif + mov.l @(28,r14),r1 + jsr @r1 + nop + +L_ret_d: + mov #FFI_TYPE_DOUBLE,r2 + cmp/eq r2,r9 + bf L_ret_ll + + mov.l @(24,r14),r1 +#ifdef __LITTLE_ENDIAN__ + fmov.s fr1,@r1 + add #4,r1 + bra L_epilogue + fmov.s fr0,@r1 +#else + fmov.s fr0,@r1 + add #4,r1 + bra L_epilogue + fmov.s fr1,@r1 +#endif + +L_ret_ll: + mov #FFI_TYPE_SINT64,r2 + cmp/eq r2,r9 + bt/s 1f + mov #FFI_TYPE_UINT64,r2 + cmp/eq r2,r9 + bf L_ret_f + +1: + mov.l @(24,r14),r2 + mov.l r0,@r2 + bra L_epilogue + mov.l r1,@(4,r2) + +L_ret_f: + mov #FFI_TYPE_FLOAT,r2 + cmp/eq r2,r9 + bf L_ret_i + + mov.l @(24,r14),r1 + bra L_epilogue + fmov.s fr0,@r1 + +L_ret_i: + mov #FFI_TYPE_INT,r2 + cmp/eq r2,r9 + bf L_epilogue + + mov.l @(24,r14),r1 + bra L_epilogue + mov.l r0,@r1 + +L_epilogue: + # Remove the space we pushed for the args + mov r14,r15 + + lds.l @r15+,pr + mov.l @r15+,r14 + mov.l @r15+,r12 + mov.l @r15+,r10 + mov.l @r15+,r9 + rts + mov.l @r15+,r8 +#else + mov r6,r8 + mov r7,r9 + + sub r6,r15 + add #-16,r15 + mov #~7,r0 + and r0,r15 + + mov r4,r0 + jsr @r0 + mov r15,r4 + + mov r9,r3 + shlr8 r9 + shlr8 r9 + shlr8 r9 + + mov #FFI_TYPE_STRUCT,r2 + cmp/eq r2,r9 + bf 1f +#if STRUCT_VALUE_ADDRESS_WITH_ARG + mov.l @r15+,r4 + bra 2f + mov #5,r2 +#else + mov.l @r15+,r10 +#endif +1: + mov #4,r2 +2: + +L_pass: + cmp/pl r8 + bf L_call_it + + mov r3,r0 + and #3,r0 + +L_pass_d: + cmp/eq #FFI_TYPE_DOUBLE,r0 + bf L_pass_i + + mov r15,r0 + and #7,r0 + tst r0,r0 + bt 1f + add #4,r15 +1: + mov #8,r0 + cmp/hs r0,r2 + bt/s 2f + shlr2 r3 + bsr L_pop_d + nop +2: + add #2,r2 + bra L_pass + add #-8,r8 + +L_pop_d: + mov r2,r0 + add r0,r0 + add r2,r0 + add #-12,r0 + add r0,r0 + braf r0 + nop + mov.l @r15+,r4 + rts + mov.l @r15+,r5 + mov.l @r15+,r5 + rts + mov.l @r15+,r6 + mov.l @r15+,r6 + rts + mov.l @r15+,r7 + rts + mov.l @r15+,r7 + +L_pass_i: + cmp/eq #FFI_TYPE_INT,r0 + bf L_call_it + + mov #8,r0 + cmp/hs r0,r2 + bt/s 2f + shlr2 r3 + bsr L_pop_i + nop +2: + add #1,r2 + bra L_pass + add #-4,r8 + +L_pop_i: + mov r2,r0 + shll2 r0 + add #-16,r0 + braf r0 + nop + rts + mov.l @r15+,r4 + rts + mov.l @r15+,r5 + rts + mov.l @r15+,r6 + rts + mov.l @r15+,r7 + +L_call_it: + # call function +#if (! STRUCT_VALUE_ADDRESS_WITH_ARG) + mov r10, r2 +#endif + mov.l @(28,r14),r1 + jsr @r1 + nop + +L_ret_d: + mov #FFI_TYPE_DOUBLE,r2 + cmp/eq r2,r9 + bf L_ret_ll + + mov.l @(24,r14),r2 + mov.l r0,@r2 + bra L_epilogue + mov.l r1,@(4,r2) + +L_ret_ll: + mov #FFI_TYPE_SINT64,r2 + cmp/eq r2,r9 + bt/s 1f + mov #FFI_TYPE_UINT64,r2 + cmp/eq r2,r9 + bf L_ret_i + +1: + mov.l @(24,r14),r2 + mov.l r0,@r2 + bra L_epilogue + mov.l r1,@(4,r2) + +L_ret_i: + mov #FFI_TYPE_FLOAT,r2 + cmp/eq r2,r9 + bt 1f + mov #FFI_TYPE_INT,r2 + cmp/eq r2,r9 + bf L_epilogue +1: + mov.l @(24,r14),r1 + bra L_epilogue + mov.l r0,@r1 + +L_epilogue: + # Remove the space we pushed for the args + mov r14,r15 + + lds.l @r15+,pr + mov.l @r15+,r14 + mov.l @r15+,r12 + mov.l @r15+,r10 + mov.l @r15+,r9 + rts + mov.l @r15+,r8 +#endif +.LFE1: +.ffi_call_SYSV_end: + .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) + +.globl ffi_closure_helper_SYSV + +ENTRY(ffi_closure_SYSV) +.LFB2: + mov.l r7,@-r15 +.LCFI7: + mov.l r6,@-r15 +.LCFI8: + mov.l r5,@-r15 +.LCFI9: + mov.l r4,@-r15 +.LCFIA: + mov.l r14,@-r15 +.LCFIB: + sts.l pr,@-r15 + + /* Stack layout: + xx bytes (on stack parameters) + 16 bytes (register parameters) + 4 bytes (saved frame pointer) + 4 bytes (saved return address) + 32 bytes (floating register parameters, SH-4 only) + 8 bytes (result) + 4 bytes (pad) + 4 bytes (5th arg) + <- new stack pointer + */ +.LCFIC: +#if defined(__SH4__) + add #-48,r15 +#else + add #-16,r15 +#endif +.LCFID: + mov r15,r14 +.LCFIE: + +#if defined(__SH4__) + mov r14,r1 + add #48,r1 +#ifdef __LITTLE_ENDIAN__ + fmov.s fr10,@-r1 + fmov.s fr11,@-r1 + fmov.s fr8,@-r1 + fmov.s fr9,@-r1 + fmov.s fr6,@-r1 + fmov.s fr7,@-r1 + fmov.s fr4,@-r1 + fmov.s fr5,@-r1 +#else + fmov.s fr11,@-r1 + fmov.s fr10,@-r1 + fmov.s fr9,@-r1 + fmov.s fr8,@-r1 + fmov.s fr7,@-r1 + fmov.s fr6,@-r1 + fmov.s fr5,@-r1 + fmov.s fr4,@-r1 +#endif + mov r1,r7 + mov r14,r6 + add #56,r6 +#else + mov r14,r6 + add #24,r6 +#endif + + bt/s 10f + mov r2, r5 + mov r14,r1 + add #8,r1 + mov r1,r5 +10: + + mov r14,r1 +#if defined(__SH4__) + add #72,r1 +#else + add #40,r1 +#endif + mov.l r1,@r14 + +#ifdef PIC + mov.l L_got,r1 + mova L_got,r0 + add r0,r1 + mov.l L_helper,r0 + add r1,r0 +#else + mov.l L_helper,r0 +#endif + jsr @r0 + mov r3,r4 + + shll r0 + mov r0,r1 + mova L_table,r0 + add r1,r0 + mov.w @r0,r0 + mov r14,r2 + braf r0 + add #8,r2 +0: + .align 2 +#ifdef PIC +L_got: + .long _GLOBAL_OFFSET_TABLE_ +L_helper: + .long ffi_closure_helper_SYSV@GOTOFF +#else +L_helper: + .long ffi_closure_helper_SYSV +#endif +L_table: + .short L_case_v - 0b /* FFI_TYPE_VOID */ + .short L_case_i - 0b /* FFI_TYPE_INT */ +#if defined(__SH4__) + .short L_case_f - 0b /* FFI_TYPE_FLOAT */ + .short L_case_d - 0b /* FFI_TYPE_DOUBLE */ + .short L_case_d - 0b /* FFI_TYPE_LONGDOUBLE */ +#else + .short L_case_i - 0b /* FFI_TYPE_FLOAT */ + .short L_case_ll - 0b /* FFI_TYPE_DOUBLE */ + .short L_case_ll - 0b /* FFI_TYPE_LONGDOUBLE */ +#endif + .short L_case_uq - 0b /* FFI_TYPE_UINT8 */ + .short L_case_q - 0b /* FFI_TYPE_SINT8 */ + .short L_case_uh - 0b /* FFI_TYPE_UINT16 */ + .short L_case_h - 0b /* FFI_TYPE_SINT16 */ + .short L_case_i - 0b /* FFI_TYPE_UINT32 */ + .short L_case_i - 0b /* FFI_TYPE_SINT32 */ + .short L_case_ll - 0b /* FFI_TYPE_UINT64 */ + .short L_case_ll - 0b /* FFI_TYPE_SINT64 */ + .short L_case_v - 0b /* FFI_TYPE_STRUCT */ + .short L_case_i - 0b /* FFI_TYPE_POINTER */ + +#if defined(__SH4__) +L_case_d: +#ifdef __LITTLE_ENDIAN__ + fmov.s @r2+,fr1 + bra L_case_v + fmov.s @r2,fr0 +#else + fmov.s @r2+,fr0 + bra L_case_v + fmov.s @r2,fr1 +#endif + +L_case_f: + bra L_case_v + fmov.s @r2,fr0 +#endif + +L_case_ll: + mov.l @r2+,r0 + bra L_case_v + mov.l @r2,r1 + +L_case_i: + bra L_case_v + mov.l @r2,r0 + +L_case_q: +#ifdef __LITTLE_ENDIAN__ +#else + add #3,r2 +#endif + bra L_case_v + mov.b @r2,r0 + +L_case_uq: +#ifdef __LITTLE_ENDIAN__ +#else + add #3,r2 +#endif + mov.b @r2,r0 + bra L_case_v + extu.b r0,r0 + +L_case_h: +#ifdef __LITTLE_ENDIAN__ +#else + add #2,r2 +#endif + bra L_case_v + mov.w @r2,r0 + +L_case_uh: +#ifdef __LITTLE_ENDIAN__ +#else + add #2,r2 +#endif + mov.w @r2,r0 + extu.w r0,r0 + /* fall through */ + +L_case_v: +#if defined(__SH4__) + add #48,r15 +#else + add #16,r15 +#endif + lds.l @r15+,pr + mov.l @r15+,r14 + rts + add #16,r15 +.LFE2: +.ffi_closure_SYSV_end: + .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif + + .section ".eh_frame","aw",@progbits +__FRAME_BEGIN__: + .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */ +.LSCIE1: + .4byte 0x0 /* CIE Identifier Tag */ + .byte 0x1 /* CIE Version */ +#ifdef PIC + .ascii "zR\0" /* CIE Augmentation */ +#else + .byte 0x0 /* CIE Augmentation */ +#endif + .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */ + .byte 0x7c /* sleb128 -4; CIE Data Alignment Factor */ + .byte 0x11 /* CIE RA Column */ +#ifdef PIC + .uleb128 0x1 /* Augmentation size */ + .byte 0x10 /* FDE Encoding (pcrel) */ +#endif + .byte 0xc /* DW_CFA_def_cfa */ + .byte 0xf /* uleb128 0xf */ + .byte 0x0 /* uleb128 0x0 */ + .align 2 +.LECIE1: +.LSFDE1: + .4byte .LEFDE1-.LASFDE1 /* FDE Length */ +.LASFDE1: + .4byte .LASFDE1-__FRAME_BEGIN__ /* FDE CIE offset */ +#ifdef PIC + .4byte .LFB1-. /* FDE initial location */ +#else + .4byte .LFB1 /* FDE initial location */ +#endif + .4byte .LFE1-.LFB1 /* FDE address range */ +#ifdef PIC + .uleb128 0x0 /* Augmentation size */ +#endif + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI0-.LFB1 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x4 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI1-.LCFI0 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x8 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI2-.LCFI1 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0xc /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI3-.LCFI2 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x10 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI4-.LCFI3 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x14 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI5-.LCFI4 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x18 /* uleb128 0x4 */ + .byte 0x91 /* DW_CFA_offset, column 0x11 */ + .byte 0x6 /* uleb128 0x6 */ + .byte 0x8e /* DW_CFA_offset, column 0xe */ + .byte 0x5 /* uleb128 0x5 */ + .byte 0x8c /* DW_CFA_offset, column 0xc */ + .byte 0x4 /* uleb128 0x4 */ + .byte 0x8a /* DW_CFA_offset, column 0xa */ + .byte 0x3 /* uleb128 0x3 */ + .byte 0x89 /* DW_CFA_offset, column 0x9 */ + .byte 0x2 /* uleb128 0x2 */ + .byte 0x88 /* DW_CFA_offset, column 0x8 */ + .byte 0x1 /* uleb128 0x1 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI6-.LCFI5 + .byte 0xd /* DW_CFA_def_cfa_register */ + .byte 0xe /* uleb128 0xe */ + .align 2 +.LEFDE1: + +.LSFDE3: + .4byte .LEFDE3-.LASFDE3 /* FDE Length */ +.LASFDE3: + .4byte .LASFDE3-__FRAME_BEGIN__ /* FDE CIE offset */ +#ifdef PIC + .4byte .LFB2-. /* FDE initial location */ +#else + .4byte .LFB2 /* FDE initial location */ +#endif + .4byte .LFE2-.LFB2 /* FDE address range */ +#ifdef PIC + .uleb128 0x0 /* Augmentation size */ +#endif + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI7-.LFB2 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x4 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI8-.LCFI7 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x8 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFI9-.LCFI8 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0xc /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFIA-.LCFI9 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x10 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFIB-.LCFIA + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x14 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFIC-.LCFIB + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x18 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFID-.LCFIC + .byte 0xe /* DW_CFA_def_cfa_offset */ +#if defined(__SH4__) + .byte 24+48 /* uleb128 24+48 */ +#else + .byte 24+16 /* uleb128 24+16 */ +#endif + .byte 0x91 /* DW_CFA_offset, column 0x11 */ + .byte 0x6 /* uleb128 0x6 */ + .byte 0x8e /* DW_CFA_offset, column 0xe */ + .byte 0x5 /* uleb128 0x5 */ + .byte 0x84 /* DW_CFA_offset, column 0x4 */ + .byte 0x4 /* uleb128 0x4 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 */ + .byte 0x3 /* uleb128 0x3 */ + .byte 0x86 /* DW_CFA_offset, column 0x6 */ + .byte 0x2 /* uleb128 0x2 */ + .byte 0x87 /* DW_CFA_offset, column 0x7 */ + .byte 0x1 /* uleb128 0x1 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFIE-.LCFID + .byte 0xd /* DW_CFA_def_cfa_register */ + .byte 0xe /* uleb128 0xe */ + .align 2 +.LEFDE3: diff --git a/circuitpython/lib/libffi/src/sh64/ffi.c b/circuitpython/lib/libffi/src/sh64/ffi.c new file mode 100644 index 0000000..123b87a --- /dev/null +++ b/circuitpython/lib/libffi/src/sh64/ffi.c @@ -0,0 +1,469 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2003, 2004, 2006, 2007, 2012 Kaz Kojima + Copyright (c) 2008 Anthony Green + + SuperH SHmedia Foreign Function Interface + + 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 +#include + +#include + +#define NGREGARG 8 +#define NFREGARG 12 + +static int +return_type (ffi_type *arg) +{ + + if (arg->type != FFI_TYPE_STRUCT) + return arg->type; + + /* gcc uses r2 if the result can be packed in on register. */ + if (arg->size <= sizeof (UINT8)) + return FFI_TYPE_UINT8; + else if (arg->size <= sizeof (UINT16)) + return FFI_TYPE_UINT16; + else if (arg->size <= sizeof (UINT32)) + return FFI_TYPE_UINT32; + else if (arg->size <= sizeof (UINT64)) + return FFI_TYPE_UINT64; + + return FFI_TYPE_STRUCT; +} + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +void ffi_prep_args(char *stack, extended_cif *ecif) +{ + register unsigned int i; + register unsigned int avn; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + + if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += sizeof (UINT64); + } + + avn = ecif->cif->nargs; + p_argv = ecif->avalue; + + for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++) + { + size_t z; + int align; + + z = (*p_arg)->size; + align = (*p_arg)->alignment; + if (z < sizeof (UINT32)) + { + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(SINT64 *) argp = (SINT64) *(SINT8 *)(*p_argv); + break; + + case FFI_TYPE_UINT8: + *(UINT64 *) argp = (UINT64) *(UINT8 *)(*p_argv); + break; + + case FFI_TYPE_SINT16: + *(SINT64 *) argp = (SINT64) *(SINT16 *)(*p_argv); + break; + + case FFI_TYPE_UINT16: + *(UINT64 *) argp = (UINT64) *(UINT16 *)(*p_argv); + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, z); + break; + + default: + FFI_ASSERT(0); + } + argp += sizeof (UINT64); + } + else if (z == sizeof (UINT32) && align == sizeof (UINT32)) + { + switch ((*p_arg)->type) + { + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv); + break; + + case FFI_TYPE_FLOAT: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT32: + case FFI_TYPE_STRUCT: + *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv); + break; + + default: + FFI_ASSERT(0); + break; + } + argp += sizeof (UINT64); + } + else if (z == sizeof (UINT64) + && align == sizeof (UINT64) + && ((int) *p_argv & (sizeof (UINT64) - 1)) == 0) + { + *(UINT64 *) argp = *(UINT64 *) (*p_argv); + argp += sizeof (UINT64); + } + else + { + int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64); + + memcpy (argp, *p_argv, z); + argp += n * sizeof (UINT64); + } + } + + return; +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + int i, j; + int size, type; + int n, m; + int greg; + int freg; + int fpair = -1; + + greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0); + freg = 0; + cif->flags2 = 0; + + for (i = j = 0; i < cif->nargs; i++) + { + type = (cif->arg_types)[i]->type; + switch (type) + { + case FFI_TYPE_FLOAT: + greg++; + cif->bytes += sizeof (UINT64) - sizeof (float); + if (freg >= NFREGARG - 1) + continue; + if (fpair < 0) + { + fpair = freg; + freg += 2; + } + else + fpair = -1; + cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++); + break; + + case FFI_TYPE_DOUBLE: + if (greg++ >= NGREGARG && (freg + 1) >= NFREGARG) + continue; + if ((freg + 1) < NFREGARG) + { + freg += 2; + cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++); + } + else + cif->flags2 += FFI_TYPE_INT << (2 * j++); + break; + + default: + size = (cif->arg_types)[i]->size; + if (size < sizeof (UINT64)) + cif->bytes += sizeof (UINT64) - size; + n = (size + sizeof (UINT64) - 1) / sizeof (UINT64); + if (greg >= NGREGARG) + continue; + else if (greg + n - 1 >= NGREGARG) + greg = NGREGARG; + else + greg += n; + for (m = 0; m < n; m++) + cif->flags2 += FFI_TYPE_INT << (2 * j++); + break; + } + } + + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_STRUCT: + cif->flags = return_type (cif->rtype); + break; + + case FFI_TYPE_VOID: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags = cif->rtype->type; + break; + + default: + cif->flags = FFI_TYPE_INT; + break; + } + + return FFI_OK; +} + +/*@-declundef@*/ +/*@-exportheader@*/ +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), + /*@out@*/ extended_cif *, + unsigned, unsigned, long long, + /*@out@*/ unsigned *, + void (*fn)(void)); +/*@=declundef@*/ +/*@=exportheader@*/ + +void ffi_call(/*@dependent@*/ ffi_cif *cif, + void (*fn)(void), + /*@out@*/ void *rvalue, + /*@dependent@*/ void **avalue) +{ + extended_cif ecif; + UINT64 trvalue; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if (cif->rtype->type == FFI_TYPE_STRUCT + && return_type (cif->rtype) != FFI_TYPE_STRUCT) + ecif.rvalue = &trvalue; + else if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, cif->flags2, + ecif.rvalue, fn); + break; + default: + FFI_ASSERT(0); + break; + } + + if (rvalue + && cif->rtype->type == FFI_TYPE_STRUCT + && return_type (cif->rtype) != FFI_TYPE_STRUCT) + memcpy (rvalue, &trvalue, cif->rtype->size); +} + +extern void ffi_closure_SYSV (void); +extern void __ic_invalidate (void *line); + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp; + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + tramp = (unsigned int *) &closure->tramp[0]; + /* Since ffi_closure is an aligned object, the ffi trampoline is + called as an SHcompact code. Sigh. + SHcompact part: + mova @(1,pc),r0; add #1,r0; jmp @r0; nop; + SHmedia part: + movi fnaddr >> 16,r1; shori fnaddr,r1; ptabs/l r1,tr0 + movi cxt >> 16,r1; shori cxt,r1; blink tr0,r63 */ +#ifdef __LITTLE_ENDIAN__ + tramp[0] = 0x7001c701; + tramp[1] = 0x0009402b; +#else + tramp[0] = 0xc7017001; + tramp[1] = 0x402b0009; +#endif + tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10; + tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10; + tramp[4] = 0x6bf10600; + tramp[5] = 0xcc000010 | (((UINT32) codeloc) >> 16) << 10; + tramp[6] = 0xc8000010 | (((UINT32) codeloc) & 0xffff) << 10; + tramp[7] = 0x4401fff0; + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + /* Flush the icache. */ + asm volatile ("ocbwb %0,0; synco; icbi %1,0; synci" : : "r" (tramp), + "r"(codeloc)); + + return FFI_OK; +} + +/* Basically the trampoline invokes ffi_closure_SYSV, and on + * entry, r3 holds the address of the closure. + * After storing the registers that could possibly contain + * parameters to be passed into the stack frame and setting + * up space for a return value, ffi_closure_SYSV invokes the + * following helper function to do most of the work. + */ + +int +ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, + UINT64 *pgr, UINT64 *pfr, UINT64 *pst) +{ + void **avalue; + ffi_type **p_arg; + int i, avn; + int greg, freg; + ffi_cif *cif; + int fpair = -1; + + cif = closure->cif; + avalue = alloca (cif->nargs * sizeof (void *)); + + /* Copy the caller's structure return value address so that the closure + returns the data directly to the caller. */ + if (return_type (cif->rtype) == FFI_TYPE_STRUCT) + { + rvalue = (UINT64 *) *pgr; + greg = 1; + } + else + greg = 0; + + freg = 0; + cif = closure->cif; + avn = cif->nargs; + + /* Grab the addresses of the arguments from the stack frame. */ + for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) + { + size_t z; + void *p; + + z = (*p_arg)->size; + if (z < sizeof (UINT32)) + { + p = pgr + greg++; + + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + case FFI_TYPE_STRUCT: +#ifdef __LITTLE_ENDIAN__ + avalue[i] = p; +#else + avalue[i] = ((char *) p) + sizeof (UINT32) - z; +#endif + break; + + default: + FFI_ASSERT(0); + } + } + else if (z == sizeof (UINT32)) + { + if ((*p_arg)->type == FFI_TYPE_FLOAT) + { + if (freg < NFREGARG - 1) + { + if (fpair >= 0) + { + avalue[i] = (UINT32 *) pfr + fpair; + fpair = -1; + } + else + { +#ifdef __LITTLE_ENDIAN__ + fpair = freg; + avalue[i] = (UINT32 *) pfr + (1 ^ freg); +#else + fpair = 1 ^ freg; + avalue[i] = (UINT32 *) pfr + freg; +#endif + freg += 2; + } + } + else +#ifdef __LITTLE_ENDIAN__ + avalue[i] = pgr + greg; +#else + avalue[i] = (UINT32 *) (pgr + greg) + 1; +#endif + } + else +#ifdef __LITTLE_ENDIAN__ + avalue[i] = pgr + greg; +#else + avalue[i] = (UINT32 *) (pgr + greg) + 1; +#endif + greg++; + } + else if ((*p_arg)->type == FFI_TYPE_DOUBLE) + { + if (freg + 1 >= NFREGARG) + avalue[i] = pgr + greg; + else + { + avalue[i] = pfr + (freg >> 1); + freg += 2; + } + greg++; + } + else + { + int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64); + + avalue[i] = pgr + greg; + greg += n; + } + } + + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + /* Tell ffi_closure_SYSV how to perform return type promotions. */ + return return_type (cif->rtype); +} + diff --git a/circuitpython/lib/libffi/src/sh64/ffitarget.h b/circuitpython/lib/libffi/src/sh64/ffitarget.h new file mode 100644 index 0000000..08a6fe9 --- /dev/null +++ b/circuitpython/lib/libffi/src/sh64/ffitarget.h @@ -0,0 +1,58 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for SuperH - SHmedia. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; + +#define FFI_EXTRA_CIF_FIELDS long long flags2 +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 32 +#define FFI_NATIVE_RAW_API 0 + +#endif + diff --git a/circuitpython/lib/libffi/src/sh64/sysv.S b/circuitpython/lib/libffi/src/sh64/sysv.S new file mode 100644 index 0000000..c4587d5 --- /dev/null +++ b/circuitpython/lib/libffi/src/sh64/sysv.S @@ -0,0 +1,539 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2003, 2004, 2006, 2008 Kaz Kojima + + SuperH SHmedia Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include +#ifdef HAVE_MACHINE_ASM_H +#include +#else +/* XXX these lose for some platforms, I'm sure. */ +#define CNAME(x) x +#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): +#endif + +#ifdef __LITTLE_ENDIAN__ +#define OFS_FLT 0 +#else +#define OFS_FLT 4 +#endif + + .section .text..SHmedia32,"ax" + + # r2: ffi_prep_args + # r3: &ecif + # r4: bytes + # r5: flags + # r6: flags2 + # r7: rvalue + # r8: fn + + # This assumes we are using gas. + .align 5 +ENTRY(ffi_call_SYSV) + # Save registers +.LFB1: + addi.l r15, -48, r15 +.LCFI0: + st.q r15, 40, r32 + st.q r15, 32, r31 + st.q r15, 24, r30 + st.q r15, 16, r29 + st.q r15, 8, r28 + st.l r15, 4, r18 + st.l r15, 0, r14 +.LCFI1: + add.l r15, r63, r14 +.LCFI2: +# add r4, r63, r28 + add r5, r63, r29 + add r6, r63, r30 + add r7, r63, r31 + add r8, r63, r32 + + addi r4, (64 + 7), r4 + andi r4, ~7, r4 + sub.l r15, r4, r15 + + ptabs/l r2, tr0 + add r15, r63, r2 + blink tr0, r18 + + addi r15, 64, r22 + movi 0, r0 + movi 0, r1 + movi -1, r23 + + pt/l 1f, tr1 + bnei/l r29, FFI_TYPE_STRUCT, tr1 + ld.l r15, 0, r19 + addi r15, 8, r15 + addi r0, 1, r0 +1: + +.L_pass: + andi r30, 3, r20 + shlri r30, 2, r30 + + pt/l .L_call_it, tr0 + pt/l .L_pass_i, tr1 + pt/l .L_pass_f, tr2 + + beqi/l r20, FFI_TYPE_VOID, tr0 + beqi/l r20, FFI_TYPE_INT, tr1 + beqi/l r20, FFI_TYPE_FLOAT, tr2 + +.L_pass_d: + addi r0, 1, r0 + pt/l 3f, tr0 + movi 12, r20 + bge/l r1, r20, tr0 + + pt/l .L_pop_d, tr1 + pt/l 2f, tr0 + blink tr1, r63 +2: + addi.l r15, 8, r15 +3: + pt/l .L_pass, tr0 + addi r1, 2, r1 + blink tr0, r63 + +.L_pop_d: + pt/l .L_pop_d_tbl, tr1 + gettr tr1, r20 + shlli r1, 2, r21 + add r20, r21, r20 + ptabs/l r20, tr1 + blink tr1, r63 + +.L_pop_d_tbl: + fld.d r15, 0, dr0 + blink tr0, r63 + fld.d r15, 0, dr2 + blink tr0, r63 + fld.d r15, 0, dr4 + blink tr0, r63 + fld.d r15, 0, dr6 + blink tr0, r63 + fld.d r15, 0, dr8 + blink tr0, r63 + fld.d r15, 0, dr10 + blink tr0, r63 + +.L_pass_f: + addi r0, 1, r0 + pt/l 3f, tr0 + movi 12, r20 + bge/l r1, r20, tr0 + + pt/l .L_pop_f, tr1 + pt/l 2f, tr0 + blink tr1, r63 +2: + addi.l r15, 8, r15 +3: + pt/l .L_pass, tr0 + blink tr0, r63 + +.L_pop_f: + pt/l .L_pop_f_tbl, tr1 + pt/l 5f, tr2 + gettr tr1, r20 + bge/l r23, r63, tr2 + add r1, r63, r23 + shlli r1, 3, r21 + addi r1, 2, r1 + add r20, r21, r20 + ptabs/l r20, tr1 + blink tr1, r63 +5: + addi r23, 1, r21 + movi -1, r23 + shlli r21, 3, r21 + add r20, r21, r20 + ptabs/l r20, tr1 + blink tr1, r63 + +.L_pop_f_tbl: + fld.s r15, OFS_FLT, fr0 + blink tr0, r63 + fld.s r15, OFS_FLT, fr1 + blink tr0, r63 + fld.s r15, OFS_FLT, fr2 + blink tr0, r63 + fld.s r15, OFS_FLT, fr3 + blink tr0, r63 + fld.s r15, OFS_FLT, fr4 + blink tr0, r63 + fld.s r15, OFS_FLT, fr5 + blink tr0, r63 + fld.s r15, OFS_FLT, fr6 + blink tr0, r63 + fld.s r15, OFS_FLT, fr7 + blink tr0, r63 + fld.s r15, OFS_FLT, fr8 + blink tr0, r63 + fld.s r15, OFS_FLT, fr9 + blink tr0, r63 + fld.s r15, OFS_FLT, fr10 + blink tr0, r63 + fld.s r15, OFS_FLT, fr11 + blink tr0, r63 + +.L_pass_i: + pt/l 3f, tr0 + movi 8, r20 + bge/l r0, r20, tr0 + + pt/l .L_pop_i, tr1 + pt/l 2f, tr0 + blink tr1, r63 +2: + addi.l r15, 8, r15 +3: + pt/l .L_pass, tr0 + addi r0, 1, r0 + blink tr0, r63 + +.L_pop_i: + pt/l .L_pop_i_tbl, tr1 + gettr tr1, r20 + shlli r0, 3, r21 + add r20, r21, r20 + ptabs/l r20, tr1 + blink tr1, r63 + +.L_pop_i_tbl: + ld.q r15, 0, r2 + blink tr0, r63 + ld.q r15, 0, r3 + blink tr0, r63 + ld.q r15, 0, r4 + blink tr0, r63 + ld.q r15, 0, r5 + blink tr0, r63 + ld.q r15, 0, r6 + blink tr0, r63 + ld.q r15, 0, r7 + blink tr0, r63 + ld.q r15, 0, r8 + blink tr0, r63 + ld.q r15, 0, r9 + blink tr0, r63 + +.L_call_it: + # call function + pt/l 1f, tr1 + bnei/l r29, FFI_TYPE_STRUCT, tr1 + add r19, r63, r2 +1: + add r22, r63, r15 + ptabs/l r32, tr0 + blink tr0, r18 + + pt/l .L_ret_i, tr0 + pt/l .L_ret_ll, tr1 + pt/l .L_ret_d, tr2 + pt/l .L_ret_f, tr3 + pt/l .L_epilogue, tr4 + + beqi/l r29, FFI_TYPE_INT, tr0 + beqi/l r29, FFI_TYPE_UINT32, tr0 + beqi/l r29, FFI_TYPE_SINT64, tr1 + beqi/l r29, FFI_TYPE_UINT64, tr1 + beqi/l r29, FFI_TYPE_DOUBLE, tr2 + beqi/l r29, FFI_TYPE_FLOAT, tr3 + + pt/l .L_ret_q, tr0 + pt/l .L_ret_h, tr1 + + beqi/l r29, FFI_TYPE_UINT8, tr0 + beqi/l r29, FFI_TYPE_UINT16, tr1 + blink tr4, r63 + +.L_ret_d: + fst.d r31, 0, dr0 + blink tr4, r63 + +.L_ret_ll: + st.q r31, 0, r2 + blink tr4, r63 + +.L_ret_f: + fst.s r31, OFS_FLT, fr0 + blink tr4, r63 + +.L_ret_q: + st.b r31, 0, r2 + blink tr4, r63 + +.L_ret_h: + st.w r31, 0, r2 + blink tr4, r63 + +.L_ret_i: + st.l r31, 0, r2 + # Fall + +.L_epilogue: + # Remove the space we pushed for the args + add r14, r63, r15 + + ld.l r15, 0, r14 + ld.l r15, 4, r18 + ld.q r15, 8, r28 + ld.q r15, 16, r29 + ld.q r15, 24, r30 + ld.q r15, 32, r31 + ld.q r15, 40, r32 + addi.l r15, 48, r15 + ptabs r18, tr0 + blink tr0, r63 + +.LFE1: +.ffi_call_SYSV_end: + .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) + + .align 5 +ENTRY(ffi_closure_SYSV) +.LFB2: + addi.l r15, -136, r15 +.LCFI3: + st.l r15, 12, r18 + st.l r15, 8, r14 + st.l r15, 4, r12 +.LCFI4: + add r15, r63, r14 +.LCFI5: + /* Stack layout: + ... + 64 bytes (register parameters) + 48 bytes (floating register parameters) + 8 bytes (result) + 4 bytes (r18) + 4 bytes (r14) + 4 bytes (r12) + 4 bytes (for align) + <- new stack pointer + */ + fst.d r14, 24, dr0 + fst.d r14, 32, dr2 + fst.d r14, 40, dr4 + fst.d r14, 48, dr6 + fst.d r14, 56, dr8 + fst.d r14, 64, dr10 + st.q r14, 72, r2 + st.q r14, 80, r3 + st.q r14, 88, r4 + st.q r14, 96, r5 + st.q r14, 104, r6 + st.q r14, 112, r7 + st.q r14, 120, r8 + st.q r14, 128, r9 + + add r1, r63, r2 + addi r14, 16, r3 + addi r14, 72, r4 + addi r14, 24, r5 + addi r14, 136, r6 +#ifdef PIC + movi (((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12 + shori ((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12 +.LPCS0: ptrel/u r12, tr0 + movi ((ffi_closure_helper_SYSV@GOTPLT) & 65535), r1 + gettr tr0, r12 + ldx.l r1, r12, r1 + ptabs r1, tr0 +#else + pt/l ffi_closure_helper_SYSV, tr0 +#endif + blink tr0, r18 + + shlli r2, 1, r1 + movi (((datalabel .L_table) >> 16) & 65535), r2 + shori ((datalabel .L_table) & 65535), r2 + ldx.w r2, r1, r1 + add r1, r2, r1 + pt/l .L_case_v, tr1 + ptabs r1, tr0 + blink tr0, r63 + + .align 2 +.L_table: + .word .L_case_v - datalabel .L_table /* FFI_TYPE_VOID */ + .word .L_case_i - datalabel .L_table /* FFI_TYPE_INT */ + .word .L_case_f - datalabel .L_table /* FFI_TYPE_FLOAT */ + .word .L_case_d - datalabel .L_table /* FFI_TYPE_DOUBLE */ + .word .L_case_d - datalabel .L_table /* FFI_TYPE_LONGDOUBLE */ + .word .L_case_uq - datalabel .L_table /* FFI_TYPE_UINT8 */ + .word .L_case_q - datalabel .L_table /* FFI_TYPE_SINT8 */ + .word .L_case_uh - datalabel .L_table /* FFI_TYPE_UINT16 */ + .word .L_case_h - datalabel .L_table /* FFI_TYPE_SINT16 */ + .word .L_case_i - datalabel .L_table /* FFI_TYPE_UINT32 */ + .word .L_case_i - datalabel .L_table /* FFI_TYPE_SINT32 */ + .word .L_case_ll - datalabel .L_table /* FFI_TYPE_UINT64 */ + .word .L_case_ll - datalabel .L_table /* FFI_TYPE_SINT64 */ + .word .L_case_v - datalabel .L_table /* FFI_TYPE_STRUCT */ + .word .L_case_i - datalabel .L_table /* FFI_TYPE_POINTER */ + + .align 2 +.L_case_d: + fld.d r14, 16, dr0 + blink tr1, r63 +.L_case_f: + fld.s r14, 16, fr0 + blink tr1, r63 +.L_case_ll: + ld.q r14, 16, r2 + blink tr1, r63 +.L_case_i: + ld.l r14, 16, r2 + blink tr1, r63 +.L_case_q: + ld.b r14, 16, r2 + blink tr1, r63 +.L_case_uq: + ld.ub r14, 16, r2 + blink tr1, r63 +.L_case_h: + ld.w r14, 16, r2 + blink tr1, r63 +.L_case_uh: + ld.uw r14, 16, r2 + blink tr1, r63 +.L_case_v: + add.l r14, r63, r15 + ld.l r15, 4, r12 + ld.l r15, 8, r14 + ld.l r15, 12, r18 + addi.l r15, 136, r15 + ptabs r18, tr0 + blink tr0, r63 + +.LFE2: +.ffi_closure_SYSV_end: + .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif + + .section ".eh_frame","aw",@progbits +__FRAME_BEGIN__: + .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */ +.LSCIE1: + .4byte 0x0 /* CIE Identifier Tag */ + .byte 0x1 /* CIE Version */ +#ifdef PIC + .ascii "zR\0" /* CIE Augmentation */ +#else + .byte 0x0 /* CIE Augmentation */ +#endif + .uleb128 0x1 /* CIE Code Alignment Factor */ + .sleb128 -4 /* CIE Data Alignment Factor */ + .byte 0x12 /* CIE RA Column */ +#ifdef PIC + .uleb128 0x1 /* Augmentation size */ + .byte 0x10 /* FDE Encoding (pcrel) */ +#endif + .byte 0xc /* DW_CFA_def_cfa */ + .uleb128 0xf + .uleb128 0x0 + .align 2 +.LECIE1: +.LSFDE1: + .4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */ +.LASFDE1: + .4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__ +#ifdef PIC + .4byte .LFB1-. /* FDE initial location */ +#else + .4byte .LFB1 /* FDE initial location */ +#endif + .4byte datalabel .LFE1-datalabel .LFB1 /* FDE address range */ +#ifdef PIC + .uleb128 0x0 /* Augmentation size */ +#endif + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte datalabel .LCFI0-datalabel .LFB1 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .uleb128 0x30 + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte datalabel .LCFI1-datalabel .LCFI0 + .byte 0x8e /* DW_CFA_offset, column 0xe */ + .uleb128 0xc + .byte 0x92 /* DW_CFA_offset, column 0x12 */ + .uleb128 0xb + .byte 0x9c /* DW_CFA_offset, column 0x1c */ + .uleb128 0xa + .byte 0x9d /* DW_CFA_offset, column 0x1d */ + .uleb128 0x8 + .byte 0x9e /* DW_CFA_offset, column 0x1e */ + .uleb128 0x6 + .byte 0x9f /* DW_CFA_offset, column 0x1f */ + .uleb128 0x4 + .byte 0xa0 /* DW_CFA_offset, column 0x20 */ + .uleb128 0x2 + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte datalabel .LCFI2-datalabel .LCFI1 + .byte 0xd /* DW_CFA_def_cfa_register */ + .uleb128 0xe + .align 2 +.LEFDE1: + +.LSFDE3: + .4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */ +.LASFDE3: + .4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__ +#ifdef PIC + .4byte .LFB2-. /* FDE initial location */ +#else + .4byte .LFB2 /* FDE initial location */ +#endif + .4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */ +#ifdef PIC + .uleb128 0x0 /* Augmentation size */ +#endif + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte datalabel .LCFI3-datalabel .LFB2 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .uleb128 0x88 + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte datalabel .LCFI4-datalabel .LCFI3 + .byte 0x8c /* DW_CFA_offset, column 0xc */ + .uleb128 0x21 + .byte 0x8e /* DW_CFA_offset, column 0xe */ + .uleb128 0x20 + .byte 0x92 /* DW_CFA_offset, column 0x12 */ + .uleb128 0x1f + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte datalabel .LCFI5-datalabel .LCFI4 + .byte 0xd /* DW_CFA_def_cfa_register */ + .uleb128 0xe + .align 2 +.LEFDE3: diff --git a/circuitpython/lib/libffi/src/sparc/ffi.c b/circuitpython/lib/libffi/src/sparc/ffi.c new file mode 100644 index 0000000..d5212d8 --- /dev/null +++ b/circuitpython/lib/libffi/src/sparc/ffi.c @@ -0,0 +1,468 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2011, 2013 Anthony Green + Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc. + + SPARC Foreign Function Interface + + 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 +#include +#include +#include "internal.h" + +#ifndef SPARC64 + +/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; + all further uses in this file will refer to the 128-bit type. */ +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +# if FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +#else +# undef FFI_TYPE_LONGDOUBLE +# define FFI_TYPE_LONGDOUBLE 4 +#endif + +/* Perform machine dependent cif processing */ +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep(ffi_cif *cif) +{ + ffi_type *rtype = cif->rtype; + int rtt = rtype->type; + size_t bytes; + int i, n, flags; + + /* Set the return type flag */ + switch (rtt) + { + case FFI_TYPE_VOID: + flags = SPARC_RET_VOID; + break; + case FFI_TYPE_FLOAT: + flags = SPARC_RET_F_1; + break; + case FFI_TYPE_DOUBLE: + flags = SPARC_RET_F_2; + break; + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_STRUCT: + flags = (rtype->size & 0xfff) << SPARC_SIZEMASK_SHIFT; + flags |= SPARC_RET_STRUCT; + break; + case FFI_TYPE_SINT8: + flags = SPARC_RET_SINT8; + break; + case FFI_TYPE_UINT8: + flags = SPARC_RET_UINT8; + break; + case FFI_TYPE_SINT16: + flags = SPARC_RET_SINT16; + break; + case FFI_TYPE_UINT16: + flags = SPARC_RET_UINT16; + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + flags = SPARC_RET_UINT32; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + flags = SPARC_RET_INT64; + break; + case FFI_TYPE_COMPLEX: + rtt = rtype->elements[0]->type; + switch (rtt) + { + case FFI_TYPE_FLOAT: + flags = SPARC_RET_F_2; + break; + case FFI_TYPE_DOUBLE: + flags = SPARC_RET_F_4; + break; + case FFI_TYPE_LONGDOUBLE: + flags = SPARC_RET_F_8; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + flags = SPARC_RET_INT128; + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + flags = SPARC_RET_INT64; + break; + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + flags = SP_V8_RET_CPLX16; + break; + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + flags = SP_V8_RET_CPLX8; + break; + default: + abort(); + } + break; + default: + abort(); + } + cif->flags = flags; + + bytes = 0; + for (i = 0, n = cif->nargs; i < n; ++i) + { + ffi_type *ty = cif->arg_types[i]; + size_t z = ty->size; + int tt = ty->type; + + switch (tt) + { + case FFI_TYPE_STRUCT: + case FFI_TYPE_LONGDOUBLE: + by_reference: + /* Passed by reference. */ + z = 4; + break; + + case FFI_TYPE_COMPLEX: + tt = ty->elements[0]->type; + if (tt == FFI_TYPE_FLOAT || z > 8) + goto by_reference; + /* FALLTHRU */ + + default: + z = ALIGN(z, 4); + } + bytes += z; + } + + /* Sparc call frames require that space is allocated for 6 args, + even if they aren't used. Make that space if necessary. */ + if (bytes < 6 * 4) + bytes = 6 * 4; + + /* The ABI always requires space for the struct return pointer. */ + bytes += 4; + + /* The stack must be 2 word aligned, so round bytes up appropriately. */ + bytes = ALIGN(bytes, 2 * 4); + + /* Include the call frame to prep_args. */ + bytes += 4*16 + 4*8; + cif->bytes = bytes; + + return FFI_OK; +} + +extern void ffi_call_v8(ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, size_t bytes, void *closure) FFI_HIDDEN; + +int FFI_HIDDEN +ffi_prep_args_v8(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue) +{ + ffi_type **p_arg; + int flags = cif->flags; + int i, nargs; + + if (rvalue == NULL) + { + if ((flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT) + { + /* Since we pass the pointer to the callee, we need a value. + We allowed for this space in ffi_call, before ffi_call_v8 + alloca'd the space. */ + rvalue = (char *)argp + cif->bytes; + } + else + { + /* Otherwise, we can ignore the return value. */ + flags = SPARC_RET_VOID; + } + } + + /* This could only really be done when we are returning a structure. + However, the space is reserved so we can do it unconditionally. */ + *argp++ = (unsigned long)rvalue; + +#ifdef USING_PURIFY + /* Purify will probably complain in our assembly routine, + unless we zero out this memory. */ + memset(argp, 0, 6*4); +#endif + + p_arg = cif->arg_types; + for (i = 0, nargs = cif->nargs; i < nargs; i++) + { + ffi_type *ty = p_arg[i]; + void *a = avalue[i]; + int tt = ty->type; + size_t z; + + switch (tt) + { + case FFI_TYPE_STRUCT: + case FFI_TYPE_LONGDOUBLE: + by_reference: + *argp++ = (unsigned long)a; + break; + + case FFI_TYPE_DOUBLE: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + memcpy(argp, a, 8); + argp += 2; + break; + + case FFI_TYPE_INT: + case FFI_TYPE_FLOAT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + *argp++ = *(unsigned *)a; + break; + + case FFI_TYPE_UINT8: + *argp++ = *(UINT8 *)a; + break; + case FFI_TYPE_SINT8: + *argp++ = *(SINT8 *)a; + break; + case FFI_TYPE_UINT16: + *argp++ = *(UINT16 *)a; + break; + case FFI_TYPE_SINT16: + *argp++ = *(SINT16 *)a; + break; + + case FFI_TYPE_COMPLEX: + tt = ty->elements[0]->type; + z = ty->size; + if (tt == FFI_TYPE_FLOAT || z > 8) + goto by_reference; + if (z < 4) + { + memcpy((char *)argp + 4 - z, a, z); + argp++; + } + else + { + memcpy(argp, a, z); + argp += z / 4; + } + break; + + default: + abort(); + } + } + + return flags; +} + +static void +ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + size_t bytes = cif->bytes; + + FFI_ASSERT (cif->abi == FFI_V8); + + /* If we've not got a return value, we need to create one if we've + got to pass the return value to the callee. Otherwise ignore it. */ + if (rvalue == NULL + && (cif->flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT) + bytes += ALIGN (cif->rtype->size, 8); + + ffi_call_v8(cif, fn, rvalue, avalue, -bytes, closure); +} + +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} + +#ifdef __GNUC__ +static inline void +ffi_flush_icache (void *p) +{ + /* SPARC v8 requires 5 instructions for flush to be visible */ + asm volatile ("iflush %0; iflush %0+8; nop; nop; nop; nop; nop" + : : "r" (p) : "memory"); +} +#else +extern void ffi_flush_icache (void *) FFI_HIDDEN; +#endif + +extern void ffi_closure_v8(void) FFI_HIDDEN; +extern void ffi_go_closure_v8(void) FFI_HIDDEN; + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + unsigned long ctx = (unsigned long) closure; + unsigned long fn = (unsigned long) ffi_closure_v8; + + if (cif->abi != FFI_V8) + return FFI_BAD_ABI; + + tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */ + tramp[1] = 0x05000000 | ctx >> 10; /* sethi %hi(ctx), %g2 */ + tramp[2] = 0x81c06000 | (fn & 0x3ff); /* jmp %g1+%lo(fn) */ + tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or %g2, %lo(ctx) */ + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + ffi_flush_icache (closure); + + return FFI_OK; +} + +ffi_status +ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*)) +{ + if (cif->abi != FFI_V8) + return FFI_BAD_ABI; + + closure->tramp = ffi_go_closure_v8; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} + +int FFI_HIDDEN +ffi_closure_sparc_inner_v8(ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, void *rvalue, + unsigned long *argp) +{ + ffi_type **arg_types; + void **avalue; + int i, nargs, flags; + + arg_types = cif->arg_types; + nargs = cif->nargs; + flags = cif->flags; + avalue = alloca(nargs * sizeof(void *)); + + /* Copy the caller's structure return address so that the closure + returns the data directly to the caller. Also install it so we + can return the address in %o0. */ + if ((flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT) + { + void *new_rvalue = (void *)*argp; + *(void **)rvalue = new_rvalue; + rvalue = new_rvalue; + } + + /* Always skip the structure return address. */ + argp++; + + /* Grab the addresses of the arguments from the stack frame. */ + for (i = 0; i < nargs; i++) + { + ffi_type *ty = arg_types[i]; + int tt = ty->type; + void *a = argp; + size_t z; + + switch (tt) + { + case FFI_TYPE_STRUCT: + case FFI_TYPE_LONGDOUBLE: + by_reference: + /* Straight copy of invisible reference. */ + a = (void *)*argp; + break; + + case FFI_TYPE_DOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + if ((unsigned long)a & 7) + { + /* Align on a 8-byte boundary. */ + UINT64 *tmp = alloca(8); + *tmp = ((UINT64)argp[0] << 32) | argp[1]; + a = tmp; + } + argp++; + break; + + case FFI_TYPE_INT: + case FFI_TYPE_FLOAT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + break; + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + a += 2; + break; + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + a += 3; + break; + + case FFI_TYPE_COMPLEX: + tt = ty->elements[0]->type; + z = ty->size; + if (tt == FFI_TYPE_FLOAT || z > 8) + goto by_reference; + if (z < 4) + a += 4 - z; + else if (z > 4) + argp++; + break; + + default: + abort(); + } + argp++; + avalue[i] = a; + } + + /* Invoke the closure. */ + fun (cif, rvalue, avalue, user_data); + + /* Tell ffi_closure_sparc how to perform return type promotions. */ + return flags; +} +#endif /* !SPARC64 */ diff --git a/circuitpython/lib/libffi/src/sparc/ffi64.c b/circuitpython/lib/libffi/src/sparc/ffi64.c new file mode 100644 index 0000000..340b198 --- /dev/null +++ b/circuitpython/lib/libffi/src/sparc/ffi64.c @@ -0,0 +1,608 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2011, 2013 Anthony Green + Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc. + + SPARC Foreign Function Interface + + 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 +#include +#include +#include "internal.h" + +/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; + all further uses in this file will refer to the 128-bit type. */ +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +# if FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +#else +# undef FFI_TYPE_LONGDOUBLE +# define FFI_TYPE_LONGDOUBLE 4 +#endif + +#ifdef SPARC64 + +/* Flatten the contents of a structure to the parts that are passed in + floating point registers. The return is a bit mask wherein bit N + set means bytes [4*n, 4*n+3] are passed in %fN. + + We encode both the (running) size (maximum 32) and mask (maxumum 255) + into one integer. The size is placed in the low byte, so that align + and addition work correctly. The mask is placed in the second byte. */ + +static int +ffi_struct_float_mask (ffi_type *outer_type, int size_mask) +{ + ffi_type **elts; + ffi_type *t; + + if (outer_type->type == FFI_TYPE_COMPLEX) + { + int m = 0, tt = outer_type->elements[0]->type; + size_t z = outer_type->size; + + if (tt == FFI_TYPE_FLOAT + || tt == FFI_TYPE_DOUBLE + || tt == FFI_TYPE_LONGDOUBLE) + m = (1 << (z / 4)) - 1; + return (m << 8) | z; + } + FFI_ASSERT (outer_type->type == FFI_TYPE_STRUCT); + + for (elts = outer_type->elements; (t = *elts) != NULL; elts++) + { + size_t z = t->size; + int o, m, tt; + + size_mask = ALIGN(size_mask, t->alignment); + switch (t->type) + { + case FFI_TYPE_STRUCT: + size_mask = ffi_struct_float_mask (t, size_mask); + continue; + case FFI_TYPE_COMPLEX: + tt = t->elements[0]->type; + if (tt != FFI_TYPE_FLOAT + && tt != FFI_TYPE_DOUBLE + && tt != FFI_TYPE_LONGDOUBLE) + break; + /* FALLTHRU */ + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + m = (1 << (z / 4)) - 1; /* compute mask for type */ + o = (size_mask >> 2) & 0x3f; /* extract word offset */ + size_mask |= m << (o + 8); /* insert mask into place */ + break; + } + size_mask += z; + } + + size_mask = ALIGN(size_mask, outer_type->alignment); + FFI_ASSERT ((size_mask & 0xff) == outer_type->size); + + return size_mask; +} + +/* Merge floating point data into integer data. If the structure is + entirely floating point, simply return a pointer to the fp data. */ + +static void * +ffi_struct_float_merge (int size_mask, void *vi, void *vf) +{ + int size = size_mask & 0xff; + int mask = size_mask >> 8; + int n = size >> 2; + + if (mask == 0) + return vi; + else if (mask == (1 << n) - 1) + return vf; + else + { + unsigned int *wi = vi, *wf = vf; + int i; + + for (i = 0; i < n; ++i) + if ((mask >> i) & 1) + wi[i] = wf[i]; + + return vi; + } +} + +/* Similar, but place the data into VD in the end. */ + +void FFI_HIDDEN +ffi_struct_float_copy (int size_mask, void *vd, void *vi, void *vf) +{ + int size = size_mask & 0xff; + int mask = size_mask >> 8; + int n = size >> 2; + + if (mask == 0) + ; + else if (mask == (1 << n) - 1) + vi = vf; + else + { + unsigned int *wd = vd, *wi = vi, *wf = vf; + int i; + + for (i = 0; i < n; ++i) + wd[i] = ((mask >> i) & 1 ? wf : wi)[i]; + return; + } + memcpy (vd, vi, size); +} + +/* Perform machine dependent cif processing */ + +static ffi_status +ffi_prep_cif_machdep_core(ffi_cif *cif) +{ + ffi_type *rtype = cif->rtype; + int rtt = rtype->type; + size_t bytes = 0; + int i, n, flags; + + /* Set the return type flag */ + switch (rtt) + { + case FFI_TYPE_VOID: + flags = SPARC_RET_VOID; + break; + case FFI_TYPE_FLOAT: + flags = SPARC_RET_F_1; + break; + case FFI_TYPE_DOUBLE: + flags = SPARC_RET_F_2; + break; + case FFI_TYPE_LONGDOUBLE: + flags = SPARC_RET_F_4; + break; + + case FFI_TYPE_COMPLEX: + case FFI_TYPE_STRUCT: + if (rtype->size > 32) + { + flags = SPARC_RET_VOID | SPARC_FLAG_RET_IN_MEM; + bytes = 8; + } + else + { + int size_mask = ffi_struct_float_mask (rtype, 0); + int word_size = (size_mask >> 2) & 0x3f; + int all_mask = (1 << word_size) - 1; + int fp_mask = size_mask >> 8; + + flags = (size_mask << SPARC_SIZEMASK_SHIFT) | SPARC_RET_STRUCT; + + /* For special cases of all-int or all-fp, we can return + the value directly without popping through a struct copy. */ + if (fp_mask == 0) + { + if (rtype->alignment >= 8) + { + if (rtype->size == 8) + flags = SPARC_RET_INT64; + else if (rtype->size == 16) + flags = SPARC_RET_INT128; + } + } + else if (fp_mask == all_mask) + switch (word_size) + { + case 1: flags = SPARC_RET_F_1; break; + case 2: flags = SPARC_RET_F_2; break; + case 3: flags = SP_V9_RET_F_3; break; + case 4: flags = SPARC_RET_F_4; break; + /* 5 word structures skipped; handled via RET_STRUCT. */ + case 6: flags = SPARC_RET_F_6; break; + /* 7 word structures skipped; handled via RET_STRUCT. */ + case 8: flags = SPARC_RET_F_8; break; + } + } + break; + + case FFI_TYPE_SINT8: + flags = SPARC_RET_SINT8; + break; + case FFI_TYPE_UINT8: + flags = SPARC_RET_UINT8; + break; + case FFI_TYPE_SINT16: + flags = SPARC_RET_SINT16; + break; + case FFI_TYPE_UINT16: + flags = SPARC_RET_UINT16; + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + flags = SP_V9_RET_SINT32; + break; + case FFI_TYPE_UINT32: + flags = SPARC_RET_UINT32; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + flags = SPARC_RET_INT64; + break; + + default: + abort(); + } + + bytes = 0; + for (i = 0, n = cif->nargs; i < n; ++i) + { + ffi_type *ty = cif->arg_types[i]; + size_t z = ty->size; + size_t a = ty->alignment; + + switch (ty->type) + { + case FFI_TYPE_COMPLEX: + case FFI_TYPE_STRUCT: + /* Large structs passed by reference. */ + if (z > 16) + { + a = z = 8; + break; + } + /* Small structs may be passed in integer or fp regs or both. */ + if (bytes >= 16*8) + break; + if ((ffi_struct_float_mask (ty, 0) & 0xff00) == 0) + break; + /* FALLTHRU */ + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + flags |= SPARC_FLAG_FP_ARGS; + break; + } + bytes = ALIGN(bytes, a); + bytes += ALIGN(z, 8); + } + + /* Sparc call frames require that space is allocated for 6 args, + even if they aren't used. Make that space if necessary. */ + if (bytes < 6 * 8) + bytes = 6 * 8; + + /* The stack must be 2 word aligned, so round bytes up appropriately. */ + bytes = ALIGN(bytes, 16); + + /* Include the call frame to prep_args. */ + bytes += 8*16 + 8*8; + + cif->bytes = bytes; + cif->flags = flags; + return FFI_OK; +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep(ffi_cif *cif) +{ + cif->nfixedargs = cif->nargs; + return ffi_prep_cif_machdep_core(cif); +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned nfixedargs, unsigned ntotalargs) +{ + cif->nfixedargs = nfixedargs; + return ffi_prep_cif_machdep_core(cif); +} + +extern void ffi_call_v9(ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, size_t bytes, void *closure) FFI_HIDDEN; + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +int FFI_HIDDEN +ffi_prep_args_v9(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue) +{ + ffi_type **p_arg; + int flags = cif->flags; + int i, nargs; + + if (rvalue == NULL) + { + if (flags & SPARC_FLAG_RET_IN_MEM) + { + /* Since we pass the pointer to the callee, we need a value. + We allowed for this space in ffi_call, before ffi_call_v8 + alloca'd the space. */ + rvalue = (char *)argp + cif->bytes; + } + else + { + /* Otherwise, we can ignore the return value. */ + flags = SPARC_RET_VOID; + } + } + +#ifdef USING_PURIFY + /* Purify will probably complain in our assembly routine, + unless we zero out this memory. */ + memset(argp, 0, 6*8); +#endif + + if (flags & SPARC_FLAG_RET_IN_MEM) + *argp++ = (unsigned long)rvalue; + + p_arg = cif->arg_types; + for (i = 0, nargs = cif->nargs; i < nargs; i++) + { + ffi_type *ty = p_arg[i]; + void *a = avalue[i]; + size_t z; + + switch (ty->type) + { + case FFI_TYPE_SINT8: + *argp++ = *(SINT8 *)a; + break; + case FFI_TYPE_UINT8: + *argp++ = *(UINT8 *)a; + break; + case FFI_TYPE_SINT16: + *argp++ = *(SINT16 *)a; + break; + case FFI_TYPE_UINT16: + *argp++ = *(UINT16 *)a; + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + *argp++ = *(SINT32 *)a; + break; + case FFI_TYPE_UINT32: + case FFI_TYPE_FLOAT: + *argp++ = *(UINT32 *)a; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + case FFI_TYPE_DOUBLE: + *argp++ = *(UINT64 *)a; + break; + + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_COMPLEX: + case FFI_TYPE_STRUCT: + z = ty->size; + if (z > 16) + { + /* For structures larger than 16 bytes we pass reference. */ + *argp++ = (unsigned long)a; + break; + } + if (((unsigned long)argp & 15) && ty->alignment > 8) + argp++; + memcpy(argp, a, z); + argp += ALIGN(z, 8) / 8; + break; + + default: + abort(); + } + } + + return flags; +} + +static void +ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + size_t bytes = cif->bytes; + + FFI_ASSERT (cif->abi == FFI_V9); + + if (rvalue == NULL && (cif->flags & SPARC_FLAG_RET_IN_MEM)) + bytes += ALIGN (cif->rtype->size, 16); + + ffi_call_v9(cif, fn, rvalue, avalue, -bytes, closure); +} + +void +ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_call_int(cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go(ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int(cif, fn, rvalue, avalue, closure); +} + +#ifdef __GNUC__ +static inline void +ffi_flush_icache (void *p) +{ + asm volatile ("flush %0; flush %0+8" : : "r" (p) : "memory"); +} +#else +extern void ffi_flush_icache (void *) FFI_HIDDEN; +#endif + +extern void ffi_closure_v9(void) FFI_HIDDEN; +extern void ffi_go_closure_v9(void) FFI_HIDDEN; + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + unsigned long fn; + + if (cif->abi != FFI_V9) + return FFI_BAD_ABI; + + /* Trampoline address is equal to the closure address. We take advantage + of that to reduce the trampoline size by 8 bytes. */ + fn = (unsigned long) ffi_closure_v9; + tramp[0] = 0x83414000; /* rd %pc, %g1 */ + tramp[1] = 0xca586010; /* ldx [%g1+16], %g5 */ + tramp[2] = 0x81c14000; /* jmp %g5 */ + tramp[3] = 0x01000000; /* nop */ + *((unsigned long *) &tramp[4]) = fn; + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + ffi_flush_icache (closure); + + return FFI_OK; +} + +ffi_status +ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*)) +{ + if (cif->abi != FFI_V9) + return FFI_BAD_ABI; + + closure->tramp = ffi_go_closure_v9; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} + +int FFI_HIDDEN +ffi_closure_sparc_inner_v9(ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, void *rvalue, + unsigned long *gpr, unsigned long *fpr) +{ + ffi_type **arg_types; + void **avalue; + int i, argn, argx, nargs, flags, nfixedargs; + + arg_types = cif->arg_types; + nargs = cif->nargs; + flags = cif->flags; + nfixedargs = cif->nfixedargs; + + avalue = alloca(nargs * sizeof(void *)); + + /* Copy the caller's structure return address so that the closure + returns the data directly to the caller. */ + if (flags & SPARC_FLAG_RET_IN_MEM) + { + rvalue = (void *) gpr[0]; + /* Skip the structure return address. */ + argn = 1; + } + else + argn = 0; + + /* Grab the addresses of the arguments from the stack frame. */ + for (i = 0; i < nargs; i++, argn = argx) + { + int named = i < nfixedargs; + ffi_type *ty = arg_types[i]; + void *a = &gpr[argn]; + size_t z; + + argx = argn + 1; + switch (ty->type) + { + case FFI_TYPE_COMPLEX: + case FFI_TYPE_STRUCT: + z = ty->size; + if (z > 16) + a = *(void **)a; + else + { + argx = argn + ALIGN (z, 8) / 8; + if (named && argn < 16) + { + int size_mask = ffi_struct_float_mask (ty, 0); + int argn_mask = (0xffff00 >> argn) & 0xff00; + + /* Eliminate fp registers off the end. */ + size_mask = (size_mask & 0xff) | (size_mask & argn_mask); + a = ffi_struct_float_merge (size_mask, gpr+argn, fpr+argn); + } + } + break; + + case FFI_TYPE_LONGDOUBLE: + argn = ALIGN (argn, 2); + a = (named && argn < 16 ? fpr : gpr) + argn; + argx = argn + 2; + break; + case FFI_TYPE_DOUBLE: + if (named && argn < 16) + a = fpr + argn; + break; + case FFI_TYPE_FLOAT: + if (named && argn < 16) + a = fpr + argn; + a += 4; + break; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + break; + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + a += 4; + break; + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + a += 6; + break; + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + a += 7; + break; + + default: + abort(); + } + avalue[i] = a; + } + + /* Invoke the closure. */ + fun (cif, rvalue, avalue, user_data); + + /* Tell ffi_closure_sparc how to perform return type promotions. */ + return flags; +} +#endif /* SPARC64 */ diff --git a/circuitpython/lib/libffi/src/sparc/ffitarget.h b/circuitpython/lib/libffi/src/sparc/ffitarget.h new file mode 100644 index 0000000..2f4cd9a --- /dev/null +++ b/circuitpython/lib/libffi/src/sparc/ffitarget.h @@ -0,0 +1,81 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for SPARC. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- System specific configurations ----------------------------------- */ + +#if defined(__arch64__) || defined(__sparcv9) +#ifndef SPARC64 +#define SPARC64 +#endif +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, +#ifdef SPARC64 + FFI_V9, + FFI_DEFAULT_ABI = FFI_V9, +#else + FFI_V8, + FFI_DEFAULT_ABI = FFI_V8, +#endif + FFI_LAST_ABI +} ffi_abi; +#endif + +#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 1 +#define FFI_TARGET_HAS_COMPLEX_TYPE 1 + +#ifdef SPARC64 +# define FFI_TARGET_SPECIFIC_VARIADIC 1 +# define FFI_EXTRA_CIF_FIELDS unsigned int nfixedargs +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_GO_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 + +#ifdef SPARC64 +#define FFI_TRAMPOLINE_SIZE 24 +#else +#define FFI_TRAMPOLINE_SIZE 16 +#endif + +#endif + diff --git a/circuitpython/lib/libffi/src/sparc/internal.h b/circuitpython/lib/libffi/src/sparc/internal.h new file mode 100644 index 0000000..0a66472 --- /dev/null +++ b/circuitpython/lib/libffi/src/sparc/internal.h @@ -0,0 +1,26 @@ +#define SPARC_RET_VOID 0 +#define SPARC_RET_STRUCT 1 +#define SPARC_RET_UINT8 2 +#define SPARC_RET_SINT8 3 +#define SPARC_RET_UINT16 4 +#define SPARC_RET_SINT16 5 +#define SPARC_RET_UINT32 6 +#define SP_V9_RET_SINT32 7 /* v9 only */ +#define SP_V8_RET_CPLX16 7 /* v8 only */ +#define SPARC_RET_INT64 8 +#define SPARC_RET_INT128 9 + +/* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT. */ +#define SPARC_RET_F_8 10 +#define SPARC_RET_F_6 11 +#define SPARC_RET_F_4 12 +#define SPARC_RET_F_2 13 +#define SP_V9_RET_F_3 14 /* v9 only */ +#define SP_V8_RET_CPLX8 14 /* v8 only */ +#define SPARC_RET_F_1 15 + +#define SPARC_FLAG_RET_MASK 15 +#define SPARC_FLAG_RET_IN_MEM 32 +#define SPARC_FLAG_FP_ARGS 64 + +#define SPARC_SIZEMASK_SHIFT 8 diff --git a/circuitpython/lib/libffi/src/sparc/v8.S b/circuitpython/lib/libffi/src/sparc/v8.S new file mode 100644 index 0000000..a2e4908 --- /dev/null +++ b/circuitpython/lib/libffi/src/sparc/v8.S @@ -0,0 +1,443 @@ +/* ----------------------------------------------------------------------- + v8.S - Copyright (c) 2013 The Written Word, Inc. + Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc. + + SPARC Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include +#include "internal.h" + +#ifndef SPARC64 + +#define C2(X, Y) X ## Y +#define C1(X, Y) C2(X, Y) + +#ifdef __USER_LABEL_PREFIX__ +# define C(Y) C1(__USER_LABEL_PREFIX__, Y) +#else +# define C(Y) Y +#endif +#define L(Y) C1(.L, Y) + + .text + +#ifndef __GNUC__ + .align 8 + .globl C(ffi_flush_icache) + .type C(ffi_flush_icache),#function + FFI_HIDDEN(C(ffi_flush_icache)) + +C(ffi_flush_icache): +1: iflush %o0 + iflush %o+8 + nop + nop + nop + nop + nop + retl + nop + .size C(ffi_flush_icache), . - C(ffi_flush_icache) +#endif + +#if defined(__sun__) && defined(__svr4__) +# define E(INDEX) .align 16 +#else +# define E(INDEX) .align 16; .org 2b + INDEX * 16 +#endif + + .align 8 + .globl C(ffi_call_v8) + .type C(ffi_call_v8),#function + FFI_HIDDEN(C(ffi_call_v8)) + +C(ffi_call_v8): +.LUW0: + ! Allocate a stack frame sized by ffi_call. + save %sp, %o4, %sp +.LUW1: + mov %i0, %o0 ! copy cif + add %sp, 64+32, %o1 ! load args area + mov %i2, %o2 ! copy rvalue + call C(ffi_prep_args_v8) + mov %i3, %o3 ! copy avalue + + add %sp, 32, %sp ! deallocate prep frame + and %o0, SPARC_FLAG_RET_MASK, %l0 ! save return type + srl %o0, SPARC_SIZEMASK_SHIFT, %l1 ! save return size + ld [%sp+64+4], %o0 ! load all argument registers + ld [%sp+64+8], %o1 + ld [%sp+64+12], %o2 + ld [%sp+64+16], %o3 + cmp %l0, SPARC_RET_STRUCT ! struct return needs an unimp 4 + ld [%sp+64+20], %o4 + be 8f + ld [%sp+64+24], %o5 + + ! Call foreign function + call %i1 + mov %i5, %g2 ! load static chain + +0: call 1f ! load pc in %o7 + sll %l0, 4, %l0 +1: add %o7, %l0, %o7 ! o7 = 0b + ret_type*16 + jmp %o7+(2f-0b) + nop + + ! Note that each entry is 4 insns, enforced by the E macro. + .align 16 +2: +E(SPARC_RET_VOID) + ret + restore +E(SPARC_RET_STRUCT) + unimp +E(SPARC_RET_UINT8) + and %o0, 0xff, %o0 + st %o0, [%i2] + ret + restore +E(SPARC_RET_SINT8) + sll %o0, 24, %o0 + b 7f + sra %o0, 24, %o0 +E(SPARC_RET_UINT16) + sll %o0, 16, %o0 + b 7f + srl %o0, 16, %o0 +E(SPARC_RET_SINT16) + sll %o0, 16, %o0 + b 7f + sra %o0, 16, %o0 +E(SPARC_RET_UINT32) +7: st %o0, [%i2] + ret + restore +E(SP_V8_RET_CPLX16) + sth %o0, [%i2+2] + b 9f + srl %o0, 16, %o0 +E(SPARC_RET_INT64) + st %o0, [%i2] + st %o1, [%i2+4] + ret + restore +E(SPARC_RET_INT128) + std %o0, [%i2] + std %o2, [%i2+8] + ret + restore +E(SPARC_RET_F_8) + st %f7, [%i2+7*4] + nop + st %f6, [%i2+6*4] + nop +E(SPARC_RET_F_6) + st %f5, [%i2+5*4] + nop + st %f4, [%i2+4*4] + nop +E(SPARC_RET_F_4) + st %f3, [%i2+3*4] + nop + st %f2, [%i2+2*4] + nop +E(SPARC_RET_F_2) + st %f1, [%i2+4] + st %f0, [%i2] + ret + restore +E(SP_V8_RET_CPLX8) + stb %o0, [%i2+1] + b 0f + srl %o0, 8, %o0 +E(SPARC_RET_F_1) + st %f0, [%i2] + ret + restore + + .align 8 +9: sth %o0, [%i2] + ret + restore + .align 8 +0: stb %o0, [%i2] + ret + restore + + ! Struct returning functions expect and skip the unimp here. + ! To make it worse, conforming callees examine the unimp and + ! make sure the low 12 bits of the unimp match the size of + ! the struct being returned. + .align 8 +8: call 1f ! load pc in %o7 + sll %l1, 2, %l0 ! size * 4 +1: sll %l1, 4, %l1 ! size * 16 + add %l0, %l1, %l0 ! size * 20 + add %o7, %l0, %o7 ! o7 = 8b + size*20 + jmp %o7+(2f-8b) + mov %i5, %g2 ! load static chain +2: + +/* The Sun assembler doesn't understand .rept 0x1000. */ +#define rept1 \ + call %i1; \ + nop; \ + unimp (. - 2b) / 20; \ + ret; \ + restore + +#define rept16 \ + rept1; rept1; rept1; rept1; \ + rept1; rept1; rept1; rept1; \ + rept1; rept1; rept1; rept1; \ + rept1; rept1; rept1; rept1 + +#define rept256 \ + rept16; rept16; rept16; rept16; \ + rept16; rept16; rept16; rept16; \ + rept16; rept16; rept16; rept16; \ + rept16; rept16; rept16; rept16 + + rept256; rept256; rept256; rept256 + rept256; rept256; rept256; rept256 + rept256; rept256; rept256; rept256 + rept256; rept256; rept256; rept256 + +.LUW2: + .size C(ffi_call_v8),. - C(ffi_call_v8) + + +/* 16*4 register window + 1*4 struct return + 6*4 args backing store + + 8*4 return storage + 1*4 alignment. */ +#define STACKFRAME (16*4 + 4 + 6*4 + 8*4 + 4) + +/* ffi_closure_v8(...) + + Receives the closure argument in %g2. */ + +#ifdef HAVE_AS_REGISTER_PSEUDO_OP + .register %g2, #scratch +#endif + + .align 8 + .globl C(ffi_go_closure_v8) + .type C(ffi_go_closure_v8),#function + FFI_HIDDEN(C(ffi_go_closure_v8)) + +C(ffi_go_closure_v8): +.LUW3: + save %sp, -STACKFRAME, %sp +.LUW4: + ld [%g2+4], %o0 ! load cif + ld [%g2+8], %o1 ! load fun + b 0f + mov %g2, %o2 ! load user_data +.LUW5: + .size C(ffi_go_closure_v8), . - C(ffi_go_closure_v8) + + .align 8 + .globl C(ffi_closure_v8) + .type C(ffi_closure_v8),#function + FFI_HIDDEN(C(ffi_closure_v8)) + +C(ffi_closure_v8): +.LUW6: + save %sp, -STACKFRAME, %sp +.LUW7: + ld [%g2+FFI_TRAMPOLINE_SIZE], %o0 ! load cif + ld [%g2+FFI_TRAMPOLINE_SIZE+4], %o1 ! load fun + ld [%g2+FFI_TRAMPOLINE_SIZE+8], %o2 ! load user_data +0: + ! Store all of the potential argument registers in va_list format. + st %i0, [%fp+68+0] + st %i1, [%fp+68+4] + st %i2, [%fp+68+8] + st %i3, [%fp+68+12] + st %i4, [%fp+68+16] + st %i5, [%fp+68+20] + + ! Call ffi_closure_sparc_inner to do the bulk of the work. + add %fp, -8*4, %o3 + call ffi_closure_sparc_inner_v8 + add %fp, 64, %o4 + +0: call 1f + and %o0, SPARC_FLAG_RET_MASK, %o0 +1: sll %o0, 4, %o0 ! o0 = o0 * 16 + add %o7, %o0, %o7 ! o7 = 0b + o0*16 + jmp %o7+(2f-0b) + add %fp, -8*4, %i2 + + ! Note that each entry is 4 insns, enforced by the E macro. + .align 16 +2: +E(SPARC_RET_VOID) + ret + restore +E(SPARC_RET_STRUCT) + ld [%i2], %i0 + jmp %i7+12 + restore +E(SPARC_RET_UINT8) + ldub [%i2+3], %i0 + ret + restore +E(SPARC_RET_SINT8) + ldsb [%i2+3], %i0 + ret + restore +E(SPARC_RET_UINT16) + lduh [%i2+2], %i0 + ret + restore +E(SPARC_RET_SINT16) + ldsh [%i2+2], %i0 + ret + restore +E(SPARC_RET_UINT32) + ld [%i2], %i0 + ret + restore +E(SP_V8_RET_CPLX16) + ld [%i2], %i0 + ret + restore +E(SPARC_RET_INT64) + ldd [%i2], %i0 + ret + restore +E(SPARC_RET_INT128) + ldd [%i2], %i0 + ldd [%i2+8], %i2 + ret + restore +E(SPARC_RET_F_8) + ld [%i2+7*4], %f7 + nop + ld [%i2+6*4], %f6 + nop +E(SPARC_RET_F_6) + ld [%i2+5*4], %f5 + nop + ld [%i2+4*4], %f4 + nop +E(SPARC_RET_F_4) + ld [%i2+3*4], %f3 + nop + ld [%i2+2*4], %f2 + nop +E(SPARC_RET_F_2) + ldd [%i2], %f0 + ret + restore +E(SP_V8_RET_CPLX8) + lduh [%i2], %i0 + ret + restore +E(SPARC_RET_F_1) + ld [%i2], %f0 + ret + restore + +.LUW8: + .size C(ffi_closure_v8), . - C(ffi_closure_v8) + +#ifdef HAVE_RO_EH_FRAME + .section ".eh_frame",#alloc +#else + .section ".eh_frame",#alloc,#write +#endif + +#ifdef HAVE_AS_SPARC_UA_PCREL +# define FDE_ADDR(X) %r_disp32(X) +#else +# define FDE_ADDR(X) X +#endif + + .align 4 +.LCIE: + .long .LECIE - .LSCIE ! CIE Length +.LSCIE: + .long 0 ! CIE Identifier Tag + .byte 1 ! CIE Version + .ascii "zR\0" ! CIE Augmentation + .byte 4 ! CIE Code Alignment Factor + .byte 0x7c ! CIE Data Alignment Factor + .byte 15 ! CIE RA Column + .byte 1 ! Augmentation size +#ifdef HAVE_AS_SPARC_UA_PCREL + .byte 0x1b ! FDE Encoding (pcrel sdata4) +#else + .byte 0x50 ! FDE Encoding (aligned absolute) +#endif + .byte 0xc, 14, 0 ! DW_CFA_def_cfa, %o6, offset 0 + .align 4 +.LECIE: + + .long .LEFDE1 - .LSFDE1 ! FDE Length +.LSFDE1: + .long .LSFDE1 - .LCIE ! FDE CIE offset + .long FDE_ADDR(.LUW0) ! Initial location + .long .LUW2 - .LUW0 ! Address range + .byte 0 ! Augmentation size + .byte 0x40+1 ! DW_CFA_advance_loc 4 + .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6 + .byte 0x2d ! DW_CFA_GNU_window_save + .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7 + .align 4 +.LEFDE1: + + .long .LEFDE2 - .LSFDE2 ! FDE Length +.LSFDE2: + .long .LSFDE2 - .LCIE ! FDE CIE offset + .long FDE_ADDR(.LUW3) ! Initial location + .long .LUW5 - .LUW3 ! Address range + .byte 0 ! Augmentation size + .byte 0x40+1 ! DW_CFA_advance_loc 4 + .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6 + .byte 0x2d ! DW_CFA_GNU_window_save + .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7 + .align 4 +.LEFDE2: + + .long .LEFDE3 - .LSFDE3 ! FDE Length +.LSFDE3: + .long .LSFDE3 - .LCIE ! FDE CIE offset + .long FDE_ADDR(.LUW6) ! Initial location + .long .LUW8 - .LUW6 ! Address range + .byte 0 ! Augmentation size + .byte 0x40+1 ! DW_CFA_advance_loc 4 + .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6 + .byte 0x2d ! DW_CFA_GNU_window_save + .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7 + .align 4 +.LEFDE3: + +#endif /* !SPARC64 */ +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/sparc/v9.S b/circuitpython/lib/libffi/src/sparc/v9.S new file mode 100644 index 0000000..55f8f43 --- /dev/null +++ b/circuitpython/lib/libffi/src/sparc/v9.S @@ -0,0 +1,440 @@ +/* ----------------------------------------------------------------------- + v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc. + + SPARC 64-bit Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include +#include "internal.h" + +#ifdef SPARC64 + +#define C2(X, Y) X ## Y +#define C1(X, Y) C2(X, Y) + +#ifdef __USER_LABEL_PREFIX__ +# define C(Y) C1(__USER_LABEL_PREFIX__, Y) +#else +# define C(Y) Y +#endif +#define L(Y) C1(.L, Y) + +#if defined(__sun__) && defined(__svr4__) +# define E(INDEX) .align 16 +#else +# define E(INDEX) .align 16; .org 2b + INDEX * 16 +#endif + +#define STACK_BIAS 2047 + + .text + .align 8 + .globl C(ffi_call_v9) + .type C(ffi_call_v9),#function + FFI_HIDDEN(C(ffi_call_v9)) + +C(ffi_call_v9): +.LUW0: + save %sp, %o4, %sp +.LUW1: + mov %i0, %o0 ! copy cif + add %sp, STACK_BIAS+128+48, %o1 ! load args area + mov %i2, %o2 ! copy rvalue + call C(ffi_prep_args_v9) + mov %i3, %o3 ! copy avalue + + andcc %o0, SPARC_FLAG_FP_ARGS, %g0 ! need fp regs? + add %sp, 48, %sp ! deallocate prep frame + be,pt %xcc, 1f + mov %o0, %l0 ! save flags + + ldd [%sp+STACK_BIAS+128], %f0 ! load all fp arg regs + ldd [%sp+STACK_BIAS+128+8], %f2 + ldd [%sp+STACK_BIAS+128+16], %f4 + ldd [%sp+STACK_BIAS+128+24], %f6 + ldd [%sp+STACK_BIAS+128+32], %f8 + ldd [%sp+STACK_BIAS+128+40], %f10 + ldd [%sp+STACK_BIAS+128+48], %f12 + ldd [%sp+STACK_BIAS+128+56], %f14 + ldd [%sp+STACK_BIAS+128+64], %f16 + ldd [%sp+STACK_BIAS+128+72], %f18 + ldd [%sp+STACK_BIAS+128+80], %f20 + ldd [%sp+STACK_BIAS+128+88], %f22 + ldd [%sp+STACK_BIAS+128+96], %f24 + ldd [%sp+STACK_BIAS+128+104], %f26 + ldd [%sp+STACK_BIAS+128+112], %f28 + ldd [%sp+STACK_BIAS+128+120], %f30 + +1: ldx [%sp+STACK_BIAS+128], %o0 ! load all int arg regs + ldx [%sp+STACK_BIAS+128+8], %o1 + ldx [%sp+STACK_BIAS+128+16], %o2 + ldx [%sp+STACK_BIAS+128+24], %o3 + ldx [%sp+STACK_BIAS+128+32], %o4 + ldx [%sp+STACK_BIAS+128+40], %o5 + call %i1 + mov %i5, %g5 ! load static chain + +0: call 1f ! load pc in %o7 + and %l0, SPARC_FLAG_RET_MASK, %l1 +1: sll %l1, 4, %l1 + add %o7, %l1, %o7 ! o7 = 0b + ret_type*16 + jmp %o7+(2f-0b) + nop + + .align 16 +2: +E(SPARC_RET_VOID) + return %i7+8 + nop +E(SPARC_RET_STRUCT) + add %sp, STACK_BIAS-64+128+48, %l2 + sub %sp, 64, %sp + b 8f + stx %o0, [%l2] +E(SPARC_RET_UINT8) + and %o0, 0xff, %i0 + return %i7+8 + stx %o0, [%o2] +E(SPARC_RET_SINT8) + sll %o0, 24, %o0 + sra %o0, 24, %i0 + return %i7+8 + stx %o0, [%o2] +E(SPARC_RET_UINT16) + sll %o0, 16, %o0 + srl %o0, 16, %i0 + return %i7+8 + stx %o0, [%o2] +E(SPARC_RET_SINT16) + sll %o0, 16, %o0 + sra %o0, 16, %i0 + return %i7+8 + stx %o0, [%o2] +E(SPARC_RET_UINT32) + srl %o0, 0, %i0 + return %i7+8 + stx %o0, [%o2] +E(SP_V9_RET_SINT32) + sra %o0, 0, %i0 + return %i7+8 + stx %o0, [%o2] +E(SPARC_RET_INT64) + stx %o0, [%i2] + return %i7+8 + nop +E(SPARC_RET_INT128) + stx %o0, [%i2] + stx %o1, [%i2+8] + return %i7+8 + nop +E(SPARC_RET_F_8) + st %f7, [%i2+7*4] + nop + st %f6, [%i2+6*4] + nop +E(SPARC_RET_F_6) + st %f5, [%i2+5*4] + nop + st %f4, [%i2+4*4] + nop +E(SPARC_RET_F_4) + std %f2, [%i2+2*4] + return %i7+8 + std %f0, [%o2] +E(SPARC_RET_F_2) + return %i7+8 + std %f0, [%o2] +E(SP_V9_RET_F_3) + st %f2, [%i2+2*4] + nop + st %f1, [%i2+1*4] + nop +E(SPARC_RET_F_1) + return %i7+8 + st %f0, [%o2] + + ! Finish the SPARC_RET_STRUCT sequence. + .align 8 +8: stx %o1, [%l2+8] + stx %o2, [%l2+16] + stx %o3, [%l2+24] + std %f0, [%l2+32] + std %f2, [%l2+40] + std %f4, [%l2+48] + std %f6, [%l2+56] + + ! Copy the structure into place. + srl %l0, SPARC_SIZEMASK_SHIFT, %o0 ! load size_mask + mov %i2, %o1 ! load dst + mov %l2, %o2 ! load src_gp + call C(ffi_struct_float_copy) + add %l2, 32, %o3 ! load src_fp + + return %i7+8 + nop + +.LUW2: + .size C(ffi_call_v9), . - C(ffi_call_v9) + + +#undef STACKFRAME +#define STACKFRAME 336 /* 16*8 register window + + 6*8 args backing store + + 20*8 locals */ +#define FP %fp+STACK_BIAS + +/* ffi_closure_v9(...) + + Receives the closure argument in %g1. */ + + .align 8 + .globl C(ffi_go_closure_v9) + .type C(ffi_go_closure_v9),#function + FFI_HIDDEN(C(ffi_go_closure_v9)) + +C(ffi_go_closure_v9): +.LUW3: + save %sp, -STACKFRAME, %sp +.LUW4: + ldx [%g5+8], %o0 + ldx [%g5+16], %o1 + b 0f + mov %g5, %o2 + +.LUW5: + .size C(ffi_go_closure_v9), . - C(ffi_go_closure_v9) + + .align 8 + .globl C(ffi_closure_v9) + .type C(ffi_closure_v9),#function + FFI_HIDDEN(C(ffi_closure_v9)) + +C(ffi_closure_v9): +.LUW6: + save %sp, -STACKFRAME, %sp +.LUW7: + ldx [%g1+FFI_TRAMPOLINE_SIZE], %o0 + ldx [%g1+FFI_TRAMPOLINE_SIZE+8], %o1 + ldx [%g1+FFI_TRAMPOLINE_SIZE+16], %o2 +0: + ! Store all of the potential argument registers in va_list format. + stx %i0, [FP+128+0] + stx %i1, [FP+128+8] + stx %i2, [FP+128+16] + stx %i3, [FP+128+24] + stx %i4, [FP+128+32] + stx %i5, [FP+128+40] + + ! Store possible floating point argument registers too. + std %f0, [FP-128] + std %f2, [FP-120] + std %f4, [FP-112] + std %f6, [FP-104] + std %f8, [FP-96] + std %f10, [FP-88] + std %f12, [FP-80] + std %f14, [FP-72] + std %f16, [FP-64] + std %f18, [FP-56] + std %f20, [FP-48] + std %f22, [FP-40] + std %f24, [FP-32] + std %f26, [FP-24] + std %f28, [FP-16] + std %f30, [FP-8] + + ! Call ffi_closure_sparc_inner to do the bulk of the work. + add %fp, STACK_BIAS-160, %o3 + add %fp, STACK_BIAS+128, %o4 + call C(ffi_closure_sparc_inner_v9) + add %fp, STACK_BIAS-128, %o5 + +0: call 1f ! load pc in %o7 + and %o0, SPARC_FLAG_RET_MASK, %o0 +1: sll %o0, 4, %o0 ! o2 = i2 * 16 + add %o7, %o0, %o7 ! o7 = 0b + i2*16 + jmp %o7+(2f-0b) + nop + + ! Note that we cannot load the data in the delay slot of + ! the return insn because the data is in the stack frame + ! that is deallocated by the return. + .align 16 +2: +E(SPARC_RET_VOID) + return %i7+8 + nop +E(SPARC_RET_STRUCT) + ldx [FP-160], %i0 + ldd [FP-160], %f0 + b 8f + ldx [FP-152], %i1 +E(SPARC_RET_UINT8) + ldub [FP-160+7], %i0 + return %i7+8 + nop +E(SPARC_RET_SINT8) + ldsb [FP-160+7], %i0 + return %i7+8 + nop +E(SPARC_RET_UINT16) + lduh [FP-160+6], %i0 + return %i7+8 + nop +E(SPARC_RET_SINT16) + ldsh [FP-160+6], %i0 + return %i7+8 + nop +E(SPARC_RET_UINT32) + lduw [FP-160+4], %i0 + return %i7+8 + nop +E(SP_V9_RET_SINT32) + ldsw [FP-160+4], %i0 + return %i7+8 + nop +E(SPARC_RET_INT64) + ldx [FP-160], %i0 + return %i7+8 + nop +E(SPARC_RET_INT128) + ldx [FP-160], %i0 + ldx [FP-160+8], %i1 + return %i7+8 + nop +E(SPARC_RET_F_8) + ld [FP-160+7*4], %f7 + nop + ld [FP-160+6*4], %f6 + nop +E(SPARC_RET_F_6) + ld [FP-160+5*4], %f5 + nop + ld [FP-160+4*4], %f4 + nop +E(SPARC_RET_F_4) + ldd [FP-160], %f0 + ldd [FP-160+8], %f2 + return %i7+8 + nop +E(SPARC_RET_F_2) + ldd [FP-160], %f0 + return %i7+8 + nop +E(SP_V9_RET_F_3) + ld [FP-160+2*4], %f2 + nop + ld [FP-160+1*4], %f1 + nop +E(SPARC_RET_F_1) + ld [FP-160], %f0 + return %i7+8 + nop + + ! Finish the SPARC_RET_STRUCT sequence. + .align 8 +8: ldd [FP-152], %f2 + ldx [FP-144], %i2 + ldd [FP-144], %f4 + ldx [FP-136], %i3 + ldd [FP-136], %f6 + return %i7+8 + nop + +.LUW8: + .size C(ffi_closure_v9), . - C(ffi_closure_v9) + +#ifdef HAVE_RO_EH_FRAME + .section ".eh_frame",#alloc +#else + .section ".eh_frame",#alloc,#write +#endif + +#ifdef HAVE_AS_SPARC_UA_PCREL +# define FDE_RANGE(B, E) .long %r_disp32(B), E - B +#else +# define FDE_RANGE(B, E) .align 8; .xword B, E - B +#endif + + .align 8 +.LCIE: + .long .LECIE - .LSCIE ! CIE Length +.LSCIE: + .long 0 ! CIE Identifier Tag + .byte 1 ! CIE Version + .ascii "zR\0" ! CIE Augmentation + .byte 4 ! CIE Code Alignment Factor + .byte 0x78 ! CIE Data Alignment Factor + .byte 15 ! CIE RA Column + .byte 1 ! Augmentation size +#ifdef HAVE_AS_SPARC_UA_PCREL + .byte 0x1b ! FDE Encoding (pcrel sdata4) +#else + .byte 0x50 ! FDE Encoding (aligned absolute) +#endif + .byte 0xc, 14, 0xff, 0xf ! DW_CFA_def_cfa, %o6, offset 0x7ff + .align 8 +.LECIE: + + .long .LEFDE1 - .LSFDE1 ! FDE Length +.LSFDE1: + .long .LSFDE1 - .LCIE ! FDE CIE offset + FDE_RANGE(.LUW0, .LUW2) + .byte 0 ! Augmentation size + .byte 0x40+1 ! DW_CFA_advance_loc 4 + .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6 + .byte 0x2d ! DW_CFA_GNU_window_save + .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7 + .align 8 +.LEFDE1: + + .long .LEFDE2 - .LSFDE2 ! FDE Length +.LSFDE2: + .long .LSFDE2 - .LCIE ! FDE CIE offset + FDE_RANGE(.LUW3, .LUW5) + .byte 0 ! Augmentation size + .byte 0x40+1 ! DW_CFA_advance_loc 4 + .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6 + .byte 0x2d ! DW_CFA_GNU_window_save + .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7 + .align 8 +.LEFDE2: + + .long .LEFDE3 - .LSFDE3 ! FDE Length +.LSFDE3: + .long .LSFDE3 - .LCIE ! FDE CIE offset + FDE_RANGE(.LUW6, .LUW8) + .byte 0 ! Augmentation size + .byte 0x40+1 ! DW_CFA_advance_loc 4 + .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6 + .byte 0x2d ! DW_CFA_GNU_window_save + .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7 + .align 8 +.LEFDE3: + +#endif /* SPARC64 */ +#ifdef __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/tile/ffi.c b/circuitpython/lib/libffi/src/tile/ffi.c new file mode 100644 index 0000000..3a94469 --- /dev/null +++ b/circuitpython/lib/libffi/src/tile/ffi.c @@ -0,0 +1,355 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2012 Tilera Corp. + + TILE Foreign Function Interface + + 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 +#include +#include +#include +#include +#include +#include +#include + + +/* The first 10 registers are used to pass arguments and return values. */ +#define NUM_ARG_REGS 10 + +/* Performs a raw function call with the given NUM_ARG_REGS register arguments + and the specified additional stack arguments (if any). */ +extern void ffi_call_tile(ffi_sarg reg_args[NUM_ARG_REGS], + const ffi_sarg *stack_args, + size_t stack_args_bytes, + void (*fnaddr)(void)) + FFI_HIDDEN; + +/* This handles the raw call from the closure stub, cleaning up the + parameters and delegating to ffi_closure_tile_inner. */ +extern void ffi_closure_tile(void) FFI_HIDDEN; + + +ffi_status +ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* We always allocate room for all registers. Even if we don't + use them as parameters, they get returned in the same array + as struct return values so we need to make room. */ + if (cif->bytes < NUM_ARG_REGS * FFI_SIZEOF_ARG) + cif->bytes = NUM_ARG_REGS * FFI_SIZEOF_ARG; + + if (cif->rtype->size > NUM_ARG_REGS * FFI_SIZEOF_ARG) + cif->flags = FFI_TYPE_STRUCT; + else + cif->flags = FFI_TYPE_INT; + + /* Nothing to do. */ + return FFI_OK; +} + + +static long +assign_to_ffi_arg(ffi_sarg *out, void *in, const ffi_type *type, + int write_to_reg) +{ + switch (type->type) + { + case FFI_TYPE_SINT8: + *out = *(SINT8 *)in; + return 1; + + case FFI_TYPE_UINT8: + *out = *(UINT8 *)in; + return 1; + + case FFI_TYPE_SINT16: + *out = *(SINT16 *)in; + return 1; + + case FFI_TYPE_UINT16: + *out = *(UINT16 *)in; + return 1; + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: +#ifndef __LP64__ + case FFI_TYPE_POINTER: +#endif + /* Note that even unsigned 32-bit quantities are sign extended + on tilegx when stored in a register. */ + *out = *(SINT32 *)in; + return 1; + + case FFI_TYPE_FLOAT: +#ifdef __tilegx__ + if (write_to_reg) + { + /* Properly sign extend the value. */ + union { float f; SINT32 s32; } val; + val.f = *(float *)in; + *out = val.s32; + } + else +#endif + { + *(float *)out = *(float *)in; + } + return 1; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: +#ifdef __LP64__ + case FFI_TYPE_POINTER: +#endif + *(UINT64 *)out = *(UINT64 *)in; + return sizeof(UINT64) / FFI_SIZEOF_ARG; + + case FFI_TYPE_STRUCT: + memcpy(out, in, type->size); + return (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; + + case FFI_TYPE_VOID: + /* Must be a return type. Nothing to do. */ + return 0; + + default: + FFI_ASSERT(0); + return -1; + } +} + + +void +ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_sarg * const arg_mem = alloca(cif->bytes); + ffi_sarg * const reg_args = arg_mem; + ffi_sarg * const stack_args = ®_args[NUM_ARG_REGS]; + ffi_sarg *argp = arg_mem; + ffi_type ** const arg_types = cif->arg_types; + const long num_args = cif->nargs; + long i; + + if (cif->flags == FFI_TYPE_STRUCT) + { + /* Pass a hidden pointer to the return value. We make sure there + is scratch space for the callee to store the return value even if + our caller doesn't care about it. */ + *argp++ = (intptr_t)(rvalue ? rvalue : alloca(cif->rtype->size)); + + /* No more work needed to return anything. */ + rvalue = NULL; + } + + for (i = 0; i < num_args; i++) + { + ffi_type *type = arg_types[i]; + void * const arg_in = avalue[i]; + ptrdiff_t arg_word = argp - arg_mem; + +#ifndef __tilegx__ + /* Doubleword-aligned values are always in an even-number register + pair, or doubleword-aligned stack slot if out of registers. */ + long align = arg_word & (type->alignment > FFI_SIZEOF_ARG); + argp += align; + arg_word += align; +#endif + + if (type->type == FFI_TYPE_STRUCT) + { + const size_t arg_size_in_words = + (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; + + if (arg_word < NUM_ARG_REGS && + arg_word + arg_size_in_words > NUM_ARG_REGS) + { + /* Args are not allowed to span registers and the stack. */ + argp = stack_args; + } + + memcpy(argp, arg_in, type->size); + argp += arg_size_in_words; + } + else + { + argp += assign_to_ffi_arg(argp, arg_in, arg_types[i], 1); + } + } + + /* Actually do the call. */ + ffi_call_tile(reg_args, stack_args, + cif->bytes - (NUM_ARG_REGS * FFI_SIZEOF_ARG), fn); + + if (rvalue != NULL) + assign_to_ffi_arg(rvalue, reg_args, cif->rtype, 0); +} + + +/* Template code for closure. */ +extern const UINT64 ffi_template_tramp_tile[] FFI_HIDDEN; + + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ +#ifdef __tilegx__ + /* TILE-Gx */ + SINT64 c; + SINT64 h; + int s; + UINT64 *out; + + if (cif->abi != FFI_UNIX) + return FFI_BAD_ABI; + + out = (UINT64 *)closure->tramp; + + c = (intptr_t)closure; + h = (intptr_t)ffi_closure_tile; + s = 0; + + /* Find the smallest shift count that doesn't lose information + (i.e. no need to explicitly insert high bits of the address that + are just the sign extension of the low bits). */ + while ((c >> s) != (SINT16)(c >> s) || (h >> s) != (SINT16)(h >> s)) + s += 16; + +#define OPS(a, b, shift) \ + (create_Imm16_X0((a) >> (shift)) | create_Imm16_X1((b) >> (shift))) + + /* Emit the moveli. */ + *out++ = ffi_template_tramp_tile[0] | OPS(c, h, s); + for (s -= 16; s >= 0; s -= 16) + *out++ = ffi_template_tramp_tile[1] | OPS(c, h, s); + +#undef OPS + + *out++ = ffi_template_tramp_tile[2]; + +#else + /* TILEPro */ + UINT64 *out; + intptr_t delta; + + if (cif->abi != FFI_UNIX) + return FFI_BAD_ABI; + + out = (UINT64 *)closure->tramp; + delta = (intptr_t)ffi_closure_tile - (intptr_t)codeloc; + + *out++ = ffi_template_tramp_tile[0] | create_JOffLong_X1(delta >> 3); +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + invalidate_icache(closure->tramp, (char *)out - closure->tramp, + getpagesize()); + + return FFI_OK; +} + + +/* This is called by the assembly wrapper for closures. This does + all of the work. On entry reg_args[0] holds the values the registers + had when the closure was invoked. On return reg_args[1] holds the register + values to be returned to the caller (many of which may be garbage). */ +void FFI_HIDDEN +ffi_closure_tile_inner(ffi_closure *closure, + ffi_sarg reg_args[2][NUM_ARG_REGS], + ffi_sarg *stack_args) +{ + ffi_cif * const cif = closure->cif; + void ** const avalue = alloca(cif->nargs * sizeof(void *)); + void *rvalue; + ffi_type ** const arg_types = cif->arg_types; + ffi_sarg * const reg_args_in = reg_args[0]; + ffi_sarg * const reg_args_out = reg_args[1]; + ffi_sarg * argp; + long i, arg_word, nargs = cif->nargs; + /* Use a union to guarantee proper alignment for double. */ + union { ffi_sarg arg[NUM_ARG_REGS]; double d; UINT64 u64; } closure_ret; + + /* Start out reading register arguments. */ + argp = reg_args_in; + + /* Copy the caller's structure return address to that the closure + returns the data directly to the caller. */ + if (cif->flags == FFI_TYPE_STRUCT) + { + /* Return by reference via hidden pointer. */ + rvalue = (void *)(intptr_t)*argp++; + arg_word = 1; + } + else + { + /* Return the value in registers. */ + rvalue = &closure_ret; + arg_word = 0; + } + + /* Grab the addresses of the arguments. */ + for (i = 0; i < nargs; i++) + { + ffi_type * const type = arg_types[i]; + const size_t arg_size_in_words = + (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; + +#ifndef __tilegx__ + /* Doubleword-aligned values are always in an even-number register + pair, or doubleword-aligned stack slot if out of registers. */ + long align = arg_word & (type->alignment > FFI_SIZEOF_ARG); + argp += align; + arg_word += align; +#endif + + if (arg_word == NUM_ARG_REGS || + (arg_word < NUM_ARG_REGS && + arg_word + arg_size_in_words > NUM_ARG_REGS)) + { + /* Switch to reading arguments from the stack. */ + argp = stack_args; + arg_word = NUM_ARG_REGS; + } + + avalue[i] = argp; + argp += arg_size_in_words; + arg_word += arg_size_in_words; + } + + /* Invoke the closure. */ + closure->fun(cif, rvalue, avalue, closure->user_data); + + if (cif->flags != FFI_TYPE_STRUCT) + { + /* Canonicalize for register representation. */ + assign_to_ffi_arg(reg_args_out, &closure_ret, cif->rtype, 1); + } +} diff --git a/circuitpython/lib/libffi/src/tile/ffitarget.h b/circuitpython/lib/libffi/src/tile/ffitarget.h new file mode 100644 index 0000000..679fb5d --- /dev/null +++ b/circuitpython/lib/libffi/src/tile/ffitarget.h @@ -0,0 +1,65 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Tilera Corp. + Target configuration macros for TILE. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM + +#include + +typedef uint_reg_t ffi_arg; +typedef int_reg_t ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_UNIX, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_UNIX +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ +#define FFI_CLOSURES 1 + +#ifdef __tilegx__ +/* We always pass 8-byte values, even in -m32 mode. */ +# define FFI_SIZEOF_ARG 8 +# ifdef __LP64__ +# define FFI_TRAMPOLINE_SIZE (8 * 5) /* 5 bundles */ +# else +# define FFI_TRAMPOLINE_SIZE (8 * 3) /* 3 bundles */ +# endif +#else +# define FFI_SIZEOF_ARG 4 +# define FFI_TRAMPOLINE_SIZE 8 /* 1 bundle */ +#endif +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/tile/tile.S b/circuitpython/lib/libffi/src/tile/tile.S new file mode 100644 index 0000000..d1f82cb --- /dev/null +++ b/circuitpython/lib/libffi/src/tile/tile.S @@ -0,0 +1,360 @@ +/* ----------------------------------------------------------------------- + tile.S - Copyright (c) 2011 Tilera Corp. + + Tilera TILEPro and TILE-Gx Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + +/* Number of bytes in a register. */ +#define REG_SIZE FFI_SIZEOF_ARG + +/* Number of bytes in stack linkage area for backtracing. + + A note about the ABI: on entry to a procedure, sp points to a stack + slot where it must spill the return address if it's not a leaf. + REG_SIZE bytes beyond that is a slot owned by the caller which + contains the sp value that the caller had when it was originally + entered (i.e. the caller's frame pointer). */ +#define LINKAGE_SIZE (2 * REG_SIZE) + +/* The first 10 registers are used to pass arguments and return values. */ +#define NUM_ARG_REGS 10 + +#ifdef __tilegx__ +#define SW st +#define LW ld +#define BGZT bgtzt +#else +#define SW sw +#define LW lw +#define BGZT bgzt +#endif + + +/* void ffi_call_tile (int_reg_t reg_args[NUM_ARG_REGS], + const int_reg_t *stack_args, + unsigned long stack_args_bytes, + void (*fnaddr)(void)); + + On entry, REG_ARGS contain the outgoing register values, + and STACK_ARGS contains STACK_ARG_BYTES of additional values + to be passed on the stack. If STACK_ARG_BYTES is zero, then + STACK_ARGS is ignored. + + When the invoked function returns, the values of r0-r9 are + blindly stored back into REG_ARGS for the caller to examine. */ + + .section .text.ffi_call_tile, "ax", @progbits + .align 8 + .globl ffi_call_tile + FFI_HIDDEN(ffi_call_tile) +ffi_call_tile: + +/* Incoming arguments. */ +#define REG_ARGS r0 +#define INCOMING_STACK_ARGS r1 +#define STACK_ARG_BYTES r2 +#define ORIG_FNADDR r3 + +/* Temporary values. */ +#define FRAME_SIZE r10 +#define TMP r11 +#define TMP2 r12 +#define OUTGOING_STACK_ARGS r13 +#define REG_ADDR_PTR r14 +#define RETURN_REG_ADDR r15 +#define FNADDR r16 + + .cfi_startproc + { + /* Save return address. */ + SW sp, lr + .cfi_offset lr, 0 + /* Prepare to spill incoming r52. */ + addi TMP, sp, -REG_SIZE + /* Increase frame size to have room to spill r52 and REG_ARGS. + The +7 is to round up mod 8. */ + addi FRAME_SIZE, STACK_ARG_BYTES, \ + REG_SIZE + REG_SIZE + LINKAGE_SIZE + 7 + } + { + /* Round stack frame size to a multiple of 8 to satisfy ABI. */ + andi FRAME_SIZE, FRAME_SIZE, -8 + /* Compute where to spill REG_ARGS value. */ + addi TMP2, sp, -(REG_SIZE * 2) + } + { + /* Spill incoming r52. */ + SW TMP, r52 + .cfi_offset r52, -REG_SIZE + /* Set up our frame pointer. */ + move r52, sp + .cfi_def_cfa_register r52 + /* Push stack frame. */ + sub sp, sp, FRAME_SIZE + } + { + /* Prepare to set up stack linkage. */ + addi TMP, sp, REG_SIZE + /* Prepare to memcpy stack args. */ + addi OUTGOING_STACK_ARGS, sp, LINKAGE_SIZE + /* Save REG_ARGS which we will need after we call the subroutine. */ + SW TMP2, REG_ARGS + } + { + /* Set up linkage info to hold incoming stack pointer. */ + SW TMP, r52 + } + { + /* Skip stack args memcpy if we don't have any stack args (common). */ + blezt STACK_ARG_BYTES, .Ldone_stack_args_memcpy + } + +.Lmemcpy_stack_args: + { + /* Load incoming argument from stack_args. */ + LW TMP, INCOMING_STACK_ARGS + addi INCOMING_STACK_ARGS, INCOMING_STACK_ARGS, REG_SIZE + } + { + /* Store stack argument into outgoing stack argument area. */ + SW OUTGOING_STACK_ARGS, TMP + addi OUTGOING_STACK_ARGS, OUTGOING_STACK_ARGS, REG_SIZE + addi STACK_ARG_BYTES, STACK_ARG_BYTES, -REG_SIZE + } + { + BGZT STACK_ARG_BYTES, .Lmemcpy_stack_args + } +.Ldone_stack_args_memcpy: + + { + /* Copy aside ORIG_FNADDR so we can overwrite its register. */ + move FNADDR, ORIG_FNADDR + /* Prepare to load argument registers. */ + addi REG_ADDR_PTR, r0, REG_SIZE + /* Load outgoing r0. */ + LW r0, r0 + } + + /* Load up argument registers from the REG_ARGS array. */ +#define LOAD_REG(REG, PTR) \ + { \ + LW REG, PTR ; \ + addi PTR, PTR, REG_SIZE \ + } + + LOAD_REG(r1, REG_ADDR_PTR) + LOAD_REG(r2, REG_ADDR_PTR) + LOAD_REG(r3, REG_ADDR_PTR) + LOAD_REG(r4, REG_ADDR_PTR) + LOAD_REG(r5, REG_ADDR_PTR) + LOAD_REG(r6, REG_ADDR_PTR) + LOAD_REG(r7, REG_ADDR_PTR) + LOAD_REG(r8, REG_ADDR_PTR) + LOAD_REG(r9, REG_ADDR_PTR) + + { + /* Call the subroutine. */ + jalr FNADDR + } + + { + /* Restore original lr. */ + LW lr, r52 + /* Prepare to recover ARGS, which we spilled earlier. */ + addi TMP, r52, -(2 * REG_SIZE) + } + { + /* Restore ARGS, so we can fill it in with the return regs r0-r9. */ + LW RETURN_REG_ADDR, TMP + /* Prepare to restore original r52. */ + addi TMP, r52, -REG_SIZE + } + + { + /* Pop stack frame. */ + move sp, r52 + /* Restore original r52. */ + LW r52, TMP + } + +#define STORE_REG(REG, PTR) \ + { \ + SW PTR, REG ; \ + addi PTR, PTR, REG_SIZE \ + } + + /* Return all register values by reference. */ + STORE_REG(r0, RETURN_REG_ADDR) + STORE_REG(r1, RETURN_REG_ADDR) + STORE_REG(r2, RETURN_REG_ADDR) + STORE_REG(r3, RETURN_REG_ADDR) + STORE_REG(r4, RETURN_REG_ADDR) + STORE_REG(r5, RETURN_REG_ADDR) + STORE_REG(r6, RETURN_REG_ADDR) + STORE_REG(r7, RETURN_REG_ADDR) + STORE_REG(r8, RETURN_REG_ADDR) + STORE_REG(r9, RETURN_REG_ADDR) + + { + jrp lr + } + + .cfi_endproc + .size ffi_call_tile, .-ffi_call_tile + +/* ffi_closure_tile(...) + + On entry, lr points to the closure plus 8 bytes, and r10 + contains the actual return address. + + This function simply dumps all register parameters into a stack array + and passes the closure, the registers array, and the stack arguments + to C code that does all of the actual closure processing. */ + + .section .text.ffi_closure_tile, "ax", @progbits + .align 8 + .globl ffi_closure_tile + FFI_HIDDEN(ffi_closure_tile) + + .cfi_startproc +/* Room to spill all NUM_ARG_REGS incoming registers, plus frame linkage. */ +#define CLOSURE_FRAME_SIZE (((NUM_ARG_REGS * REG_SIZE * 2 + LINKAGE_SIZE) + 7) & -8) +ffi_closure_tile: + { +#ifdef __tilegx__ + st sp, lr + .cfi_offset lr, 0 +#else + /* Save return address (in r10 due to closure stub wrapper). */ + SW sp, r10 + .cfi_return_column r10 + .cfi_offset r10, 0 +#endif + /* Compute address for stack frame linkage. */ + addli r10, sp, -(CLOSURE_FRAME_SIZE - REG_SIZE) + } + { + /* Save incoming stack pointer in linkage area. */ + SW r10, sp + .cfi_offset sp, -(CLOSURE_FRAME_SIZE - REG_SIZE) + /* Push a new stack frame. */ + addli sp, sp, -CLOSURE_FRAME_SIZE + .cfi_adjust_cfa_offset CLOSURE_FRAME_SIZE + } + + { + /* Create pointer to where to start spilling registers. */ + addi r10, sp, LINKAGE_SIZE + } + + /* Spill all the incoming registers. */ + STORE_REG(r0, r10) + STORE_REG(r1, r10) + STORE_REG(r2, r10) + STORE_REG(r3, r10) + STORE_REG(r4, r10) + STORE_REG(r5, r10) + STORE_REG(r6, r10) + STORE_REG(r7, r10) + STORE_REG(r8, r10) + { + /* Save r9. */ + SW r10, r9 +#ifdef __tilegx__ + /* Pointer to closure is passed in r11. */ + move r0, r11 +#else + /* Compute pointer to the closure object. Because the closure + starts with a "jal ffi_closure_tile", we can just take the + value of lr (a phony return address pointing into the closure) + and subtract 8. */ + addi r0, lr, -8 +#endif + /* Compute a pointer to the register arguments we just spilled. */ + addi r1, sp, LINKAGE_SIZE + } + { + /* Compute a pointer to the extra stack arguments (if any). */ + addli r2, sp, CLOSURE_FRAME_SIZE + LINKAGE_SIZE + /* Call C code to deal with all of the grotty details. */ + jal ffi_closure_tile_inner + } + { + addli r10, sp, CLOSURE_FRAME_SIZE + } + { + /* Restore the return address. */ + LW lr, r10 + /* Compute pointer to registers array. */ + addli r10, sp, LINKAGE_SIZE + (NUM_ARG_REGS * REG_SIZE) + } + /* Return all the register values, which C code may have set. */ + LOAD_REG(r0, r10) + LOAD_REG(r1, r10) + LOAD_REG(r2, r10) + LOAD_REG(r3, r10) + LOAD_REG(r4, r10) + LOAD_REG(r5, r10) + LOAD_REG(r6, r10) + LOAD_REG(r7, r10) + LOAD_REG(r8, r10) + LOAD_REG(r9, r10) + { + /* Pop the frame. */ + addli sp, sp, CLOSURE_FRAME_SIZE + jrp lr + } + + .cfi_endproc + .size ffi_closure_tile, . - ffi_closure_tile + + +/* What follows are code template instructions that get copied to the + closure trampoline by ffi_prep_closure_loc. The zeroed operands + get replaced by their proper values at runtime. */ + + .section .text.ffi_template_tramp_tile, "ax", @progbits + .align 8 + .globl ffi_template_tramp_tile + FFI_HIDDEN(ffi_template_tramp_tile) +ffi_template_tramp_tile: +#ifdef __tilegx__ + { + moveli r11, 0 /* backpatched to address of containing closure. */ + moveli r10, 0 /* backpatched to ffi_closure_tile. */ + } + /* Note: the following bundle gets generated multiple times + depending on the pointer value (esp. useful for -m32 mode). */ + { shl16insli r11, r11, 0 ; shl16insli r10, r10, 0 } + { info 2+8 /* for backtracer: -> pc in lr, frame size 0 */ ; jr r10 } +#else + /* 'jal .' yields a PC-relative offset of zero so we can OR in the + right offset at runtime. */ + { move r10, lr ; jal . /* ffi_closure_tile */ } +#endif + + .size ffi_template_tramp_tile, . - ffi_template_tramp_tile diff --git a/circuitpython/lib/libffi/src/types.c b/circuitpython/lib/libffi/src/types.c new file mode 100644 index 0000000..7e80aec --- /dev/null +++ b/circuitpython/lib/libffi/src/types.c @@ -0,0 +1,106 @@ +/* ----------------------------------------------------------------------- + types.c - Copyright (c) 1996, 1998 Red Hat, Inc. + + Predefined ffi_types needed by libffi. + + 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. + ----------------------------------------------------------------------- */ + +/* Hide the basic type definitions from the header file, so that we + can redefine them here as "const". */ +#define LIBFFI_HIDE_BASIC_TYPES + +#include +#include + +/* Type definitions */ + +#define FFI_TYPEDEF(name, type, id, maybe_const)\ +struct struct_align_##name { \ + char c; \ + type x; \ +}; \ +maybe_const ffi_type ffi_type_##name = { \ + sizeof(type), \ + offsetof(struct struct_align_##name, x), \ + id, NULL \ +} + +#define FFI_COMPLEX_TYPEDEF(name, type, maybe_const) \ +static ffi_type *ffi_elements_complex_##name [2] = { \ + (ffi_type *)(&ffi_type_##name), NULL \ +}; \ +struct struct_align_complex_##name { \ + char c; \ + _Complex type x; \ +}; \ +maybe_const ffi_type ffi_type_complex_##name = { \ + sizeof(_Complex type), \ + offsetof(struct struct_align_complex_##name, x), \ + FFI_TYPE_COMPLEX, \ + (ffi_type **)ffi_elements_complex_##name \ +} + +/* Size and alignment are fake here. They must not be 0. */ +const ffi_type ffi_type_void = { + 1, 1, FFI_TYPE_VOID, NULL +}; + +FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8, const); +FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8, const); +FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16, const); +FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16, const); +FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32, const); +FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32, const); +FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64, const); +FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64, const); + +FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER, const); + +FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT, const); +FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE, const); + +#if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__ +#define FFI_LDBL_CONST const +#else +#define FFI_LDBL_CONST +#endif + +#ifdef __alpha__ +/* Even if we're not configured to default to 128-bit long double, + maintain binary compatibility, as -mlong-double-128 can be used + at any time. */ +/* Validate the hard-coded number below. */ +# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL }; +#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE, FFI_LDBL_CONST); +#endif + +#ifdef FFI_TARGET_HAS_COMPLEX_TYPE +FFI_COMPLEX_TYPEDEF(float, float, const); +FFI_COMPLEX_TYPEDEF(double, double, const); +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +FFI_COMPLEX_TYPEDEF(longdouble, long double, FFI_LDBL_CONST); +#endif +#endif diff --git a/circuitpython/lib/libffi/src/vax/elfbsd.S b/circuitpython/lib/libffi/src/vax/elfbsd.S new file mode 100644 index 0000000..01ca313 --- /dev/null +++ b/circuitpython/lib/libffi/src/vax/elfbsd.S @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * vax Foreign Function Interface + */ + +#define LIBFFI_ASM +#include +#include + + .text + +/* + * void * %r0 + * ffi_call_elfbsd(extended_cif *ecif, 4(%ap) + * unsigned bytes, 8(%ap) + * unsigned flags, 12(%ap) + * void *rvalue, 16(%ap) + * void (*fn)()); 20(%ap) + */ + .globl ffi_call_elfbsd + .type ffi_call_elfbsd,@function + .align 2 +ffi_call_elfbsd: + .word 0x00c # save R2 and R3 + + # Allocate stack space for the args + subl2 8(%ap), %sp + + # Call ffi_prep_args + pushl %sp + pushl 4(%ap) + calls $2, ffi_prep_args + + # Get function pointer + movl 20(%ap), %r1 + + # Build a CALLS frame + ashl $-2, 8(%ap), %r0 + pushl %r0 # argument stack usage + movl %sp, %r0 # future %ap + # saved registers + bbc $11, 0(%r1), 1f + pushl %r11 +1: bbc $10, 0(%r1), 1f + pushl %r10 +1: bbc $9, 0(%r1), 1f + pushl %r9 +1: bbc $8, 0(%r1), 1f + pushl %r8 +1: bbc $7, 0(%r1), 1f + pushl %r7 +1: bbc $6, 0(%r1), 1f + pushl %r6 +1: bbc $5, 0(%r1), 1f + pushl %r5 +1: bbc $4, 0(%r1), 1f + pushl %r4 +1: bbc $3, 0(%r1), 1f + pushl %r3 +1: bbc $2, 0(%r1), 1f + pushl %r2 +1: + pushal 9f + pushl %fp + pushl %ap + movl 16(%ap), %r3 # struct return address, if needed + movl %r0, %ap + movzwl 4(%fp), %r0 # previous PSW, without the saved registers mask + bisl2 $0x20000000, %r0 # calls frame + movzwl 0(%r1), %r2 + bicw2 $0xf003, %r2 # only keep R11-R2 + ashl $16, %r2, %r2 + bisl2 %r2, %r0 # saved register mask of the called function + pushl %r0 + pushl $0 + movl %sp, %fp + + # Invoke the function + pushal 2(%r1) # skip procedure entry mask + movl %r3, %r1 + bicpsw $0x000f + rsb + +9: + # Copy return value if necessary + tstl 16(%ap) + jeql 9f + movl 16(%ap), %r2 + + bbc $0, 12(%ap), 1f # CIF_FLAGS_CHAR + movb %r0, 0(%r2) + brb 9f +1: + bbc $1, 12(%ap), 1f # CIF_FLAGS_SHORT + movw %r0, 0(%r2) + brb 9f +1: + bbc $2, 12(%ap), 1f # CIF_FLAGS_INT + movl %r0, 0(%r2) + brb 9f +1: + bbc $3, 12(%ap), 1f # CIF_FLAGS_DINT + movq %r0, 0(%r2) + brb 9f +1: + movl %r1, %r0 # might have been a struct + #brb 9f + +9: + ret + +/* + * ffi_closure_elfbsd(void); + * invoked with %r0: ffi_closure *closure + */ + .globl ffi_closure_elfbsd + .type ffi_closure_elfbsd, @function + .align 2 +ffi_closure_elfbsd: + .word 0 + + # Allocate room on stack for return value + subl2 $8, %sp + + # Invoke the closure function + pushal 4(%ap) # calling stack + pushal 4(%sp) # return value + pushl %r0 # closure + calls $3, ffi_closure_elfbsd_inner + + # Copy return value if necessary + bitb $1, %r0 # CIF_FLAGS_CHAR + beql 1f + movb 0(%sp), %r0 + brb 9f +1: + bitb $2, %r0 # CIF_FLAGS_SHORT + beql 1f + movw 0(%sp), %r0 + brb 9f +1: + bitb $4, %r0 # CIF_FLAGS_INT + beql 1f + movl 0(%sp), %r0 + brb 9f +1: + bitb $8, %r0 # CIF_FLAGS_DINT + beql 1f + movq 0(%sp), %r0 + #brb 9f +1: + +9: + ret + +/* + * ffi_closure_struct_elfbsd(void); + * invoked with %r0: ffi_closure *closure + * %r1: struct return address + */ + .globl ffi_closure_struct_elfbsd + .type ffi_closure_struct_elfbsd, @function + .align 2 +ffi_closure_struct_elfbsd: + .word 0 + + # Invoke the closure function + pushal 4(%ap) # calling stack + pushl %r1 # return value + pushl %r0 # closure + calls $3, ffi_closure_elfbsd_inner + + ret diff --git a/circuitpython/lib/libffi/src/vax/ffi.c b/circuitpython/lib/libffi/src/vax/ffi.c new file mode 100644 index 0000000..f4d6bbb --- /dev/null +++ b/circuitpython/lib/libffi/src/vax/ffi.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * vax Foreign Function Interface + * + * This file attempts to provide all the FFI entry points which can reliably + * be implemented in C. + */ + +#include +#include + +#include +#include + +#define CIF_FLAGS_CHAR 1 /* for struct only */ +#define CIF_FLAGS_SHORT 2 /* for struct only */ +#define CIF_FLAGS_INT 4 +#define CIF_FLAGS_DINT 8 + +/* + * Foreign Function Interface API + */ + +void ffi_call_elfbsd (extended_cif *, unsigned, unsigned, void *, + void (*) ()); +void *ffi_prep_args (extended_cif *ecif, void *stack); + +void * +ffi_prep_args (extended_cif *ecif, void *stack) +{ + unsigned int i; + void **p_argv; + char *argp; + ffi_type **p_arg; + void *struct_value_ptr; + + argp = stack; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && !ecif->cif->flags) + struct_value_ptr = ecif->rvalue; + else + struct_value_ptr = NULL; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + if (z < sizeof (int)) + { + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, z); + break; + + default: + FFI_ASSERT (0); + } + z = sizeof (int); + } + else + { + memcpy (argp, *p_argv, z); + + /* Align if necessary. */ + if ((sizeof(int) - 1) & z) + z = ALIGN(z, sizeof(int)); + } + + p_argv++; + argp += z; + } + + return struct_value_ptr; +} + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = 0; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT && + cif->rtype->elements[1]) + { + cif->flags = 0; + break; + } + + if (cif->rtype->size == sizeof (char)) + cif->flags = CIF_FLAGS_CHAR; + else if (cif->rtype->size == sizeof (short)) + cif->flags = CIF_FLAGS_SHORT; + else if (cif->rtype->size == sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else if (cif->rtype->size == 2 * sizeof (int)) + cif->flags = CIF_FLAGS_DINT; + else + cif->flags = 0; + break; + + default: + if (cif->rtype->size <= sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else + cif->flags = CIF_FLAGS_DINT; + break; + } + + return FFI_OK; +} + +void +ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return value + address then we need to make one. */ + + if (rvalue == NULL + && cif->rtype->type == FFI_TYPE_STRUCT + && cif->flags == 0) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_ELFBSD: + ffi_call_elfbsd (&ecif, cif->bytes, cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +/* + * Closure API + */ + +void ffi_closure_elfbsd (void); +void ffi_closure_struct_elfbsd (void); +unsigned int ffi_closure_elfbsd_inner (ffi_closure *, void *, char *); + +static void +ffi_prep_closure_elfbsd (ffi_cif *cif, void **avalue, char *stackp) +{ + unsigned int i; + void **p_argv; + ffi_type **p_arg; + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + *p_argv = stackp; + + /* Align if necessary */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + stackp += z; + } +} + +unsigned int +ffi_closure_elfbsd_inner (ffi_closure *closure, void *resp, char *stack) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void **) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_closure_elfbsd (cif, arg_area, stack); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, + void (*fun)(ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + char *tramp = (char *) codeloc; + void *fn; + + FFI_ASSERT (cif->abi == FFI_ELFBSD); + + /* entry mask */ + *(unsigned short *)(tramp + 0) = 0x0000; + /* movl #closure, r0 */ + tramp[2] = 0xd0; + tramp[3] = 0x8f; + *(unsigned int *)(tramp + 4) = (unsigned int) closure; + tramp[8] = 0x50; + + if (cif->rtype->type == FFI_TYPE_STRUCT + && !cif->flags) + fn = &ffi_closure_struct_elfbsd; + else + fn = &ffi_closure_elfbsd; + + /* jmpl #fn */ + tramp[9] = 0x17; + tramp[10] = 0xef; + *(unsigned int *)(tramp + 11) = (unsigned int)fn + 2 - + (unsigned int)tramp - 9 - 6; + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} diff --git a/circuitpython/lib/libffi/src/vax/ffitarget.h b/circuitpython/lib/libffi/src/vax/ffitarget.h new file mode 100644 index 0000000..2fc9488 --- /dev/null +++ b/circuitpython/lib/libffi/src/vax/ffitarget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * vax Foreign Function Interface + */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_ELFBSD, + FFI_DEFAULT_ABI = FFI_ELFBSD, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 15 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/circuitpython/lib/libffi/src/x86/ffi.c b/circuitpython/lib/libffi/src/x86/ffi.c new file mode 100644 index 0000000..feb5cbb --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/ffi.c @@ -0,0 +1,729 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc. + Copyright (c) 2002 Ranjit Mathew + Copyright (c) 2002 Bo Thorsen + Copyright (c) 2002 Roger Sayle + Copyright (C) 2008, 2010 Free Software Foundation, Inc. + + x86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef __x86_64__ +#include +#include +#include +#include "internal.h" + +/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; + all further uses in this file will refer to the 80-bit type. */ +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +# if FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +#else +# undef FFI_TYPE_LONGDOUBLE +# define FFI_TYPE_LONGDOUBLE 4 +#endif + +#if defined(__GNUC__) && !defined(__declspec) +# define __declspec(x) __attribute__((x)) +#endif + +/* Perform machine dependent cif processing. */ +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep(ffi_cif *cif) +{ + size_t bytes = 0; + int i, n, flags, cabi = cif->abi; + + switch (cabi) + { + case FFI_SYSV: + case FFI_STDCALL: + case FFI_THISCALL: + case FFI_FASTCALL: + case FFI_MS_CDECL: + case FFI_PASCAL: + case FFI_REGISTER: + break; + default: + return FFI_BAD_ABI; + } + + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + flags = X86_RET_VOID; + break; + case FFI_TYPE_FLOAT: + flags = X86_RET_FLOAT; + break; + case FFI_TYPE_DOUBLE: + flags = X86_RET_DOUBLE; + break; + case FFI_TYPE_LONGDOUBLE: + flags = X86_RET_LDOUBLE; + break; + case FFI_TYPE_UINT8: + flags = X86_RET_UINT8; + break; + case FFI_TYPE_UINT16: + flags = X86_RET_UINT16; + break; + case FFI_TYPE_SINT8: + flags = X86_RET_SINT8; + break; + case FFI_TYPE_SINT16: + flags = X86_RET_SINT16; + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + flags = X86_RET_INT32; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + flags = X86_RET_INT64; + break; + case FFI_TYPE_STRUCT: +#ifndef X86 + /* ??? This should be a different ABI rather than an ifdef. */ + if (cif->rtype->size == 1) + flags = X86_RET_STRUCT_1B; + else if (cif->rtype->size == 2) + flags = X86_RET_STRUCT_2B; + else if (cif->rtype->size == 4) + flags = X86_RET_INT32; + else if (cif->rtype->size == 8) + flags = X86_RET_INT64; + else +#endif + { + do_struct: + switch (cabi) + { + case FFI_THISCALL: + case FFI_FASTCALL: + case FFI_STDCALL: + case FFI_MS_CDECL: + flags = X86_RET_STRUCTARG; + break; + default: + flags = X86_RET_STRUCTPOP; + break; + } + /* Allocate space for return value pointer. */ + bytes += ALIGN (sizeof(void*), FFI_SIZEOF_ARG); + } + break; + case FFI_TYPE_COMPLEX: + switch (cif->rtype->elements[0]->type) + { + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + goto do_struct; + case FFI_TYPE_FLOAT: + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + flags = X86_RET_INT64; + break; + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + flags = X86_RET_INT32; + break; + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + flags = X86_RET_STRUCT_2B; + break; + default: + return FFI_BAD_TYPEDEF; + } + break; + default: + return FFI_BAD_TYPEDEF; + } + cif->flags = flags; + + for (i = 0, n = cif->nargs; i < n; i++) + { + ffi_type *t = cif->arg_types[i]; + + bytes = ALIGN (bytes, t->alignment); + bytes += ALIGN (t->size, FFI_SIZEOF_ARG); + } + cif->bytes = ALIGN (bytes, 16); + + return FFI_OK; +} + +static ffi_arg +extend_basic_type(void *arg, int type) +{ + switch (type) + { + case FFI_TYPE_SINT8: + return *(SINT8 *)arg; + case FFI_TYPE_UINT8: + return *(UINT8 *)arg; + case FFI_TYPE_SINT16: + return *(SINT16 *)arg; + case FFI_TYPE_UINT16: + return *(UINT16 *)arg; + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + case FFI_TYPE_FLOAT: + return *(UINT32 *)arg; + + default: + abort(); + } +} + +struct call_frame +{ + void *ebp; /* 0 */ + void *retaddr; /* 4 */ + void (*fn)(void); /* 8 */ + int flags; /* 12 */ + void *rvalue; /* 16 */ + unsigned regs[3]; /* 20-28 */ +}; + +struct abi_params +{ + int dir; /* parameter growth direction */ + int static_chain; /* the static chain register used by gcc */ + int nregs; /* number of register parameters */ + int regs[3]; +}; + +static const struct abi_params abi_params[FFI_LAST_ABI] = { + [FFI_SYSV] = { 1, R_ECX, 0 }, + [FFI_THISCALL] = { 1, R_EAX, 1, { R_ECX } }, + [FFI_FASTCALL] = { 1, R_EAX, 2, { R_ECX, R_EDX } }, + [FFI_STDCALL] = { 1, R_ECX, 0 }, + [FFI_PASCAL] = { -1, R_ECX, 0 }, + /* ??? No defined static chain; gcc does not support REGISTER. */ + [FFI_REGISTER] = { -1, R_ECX, 3, { R_EAX, R_EDX, R_ECX } }, + [FFI_MS_CDECL] = { 1, R_ECX, 0 } +}; + +extern void ffi_call_i386(struct call_frame *, char *) +#if HAVE_FASTCALL + __declspec(fastcall) +#endif + FFI_HIDDEN; + +static void +ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + size_t rsize, bytes; + struct call_frame *frame; + char *stack, *argp; + ffi_type **arg_types; + int flags, cabi, i, n, dir, narg_reg; + const struct abi_params *pabi; + + flags = cif->flags; + cabi = cif->abi; + pabi = &abi_params[cabi]; + dir = pabi->dir; + + rsize = 0; + if (rvalue == NULL) + { + switch (flags) + { + case X86_RET_FLOAT: + case X86_RET_DOUBLE: + case X86_RET_LDOUBLE: + case X86_RET_STRUCTPOP: + case X86_RET_STRUCTARG: + /* The float cases need to pop the 387 stack. + The struct cases need to pass a valid pointer to the callee. */ + rsize = cif->rtype->size; + break; + default: + /* We can pretend that the callee returns nothing. */ + flags = X86_RET_VOID; + break; + } + } + + bytes = cif->bytes; + stack = alloca(bytes + sizeof(*frame) + rsize); + argp = (dir < 0 ? stack + bytes : stack); + frame = (struct call_frame *)(stack + bytes); + if (rsize) + rvalue = frame + 1; + + frame->fn = fn; + frame->flags = flags; + frame->rvalue = rvalue; + frame->regs[pabi->static_chain] = (unsigned)closure; + + narg_reg = 0; + switch (flags) + { + case X86_RET_STRUCTARG: + /* The pointer is passed as the first argument. */ + if (pabi->nregs > 0) + { + frame->regs[pabi->regs[0]] = (unsigned)rvalue; + narg_reg = 1; + break; + } + /* fallthru */ + case X86_RET_STRUCTPOP: + *(void **)argp = rvalue; + argp += sizeof(void *); + break; + } + + arg_types = cif->arg_types; + for (i = 0, n = cif->nargs; i < n; i++) + { + ffi_type *ty = arg_types[i]; + void *valp = avalue[i]; + size_t z = ty->size; + int t = ty->type; + + if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT) + { + ffi_arg val = extend_basic_type (valp, t); + + if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs) + frame->regs[pabi->regs[narg_reg++]] = val; + else if (dir < 0) + { + argp -= 4; + *(ffi_arg *)argp = val; + } + else + { + *(ffi_arg *)argp = val; + argp += 4; + } + } + else + { + size_t za = ALIGN (z, FFI_SIZEOF_ARG); + size_t align = FFI_SIZEOF_ARG; + + /* Alignment rules for arguments are quite complex. Vectors and + structures with 16 byte alignment get it. Note that long double + on Darwin does have 16 byte alignment, and does not get this + alignment if passed directly; a structure with a long double + inside, however, would get 16 byte alignment. Since libffi does + not support vectors, we need non concern ourselves with other + cases. */ + if (t == FFI_TYPE_STRUCT && ty->alignment >= 16) + align = 16; + + if (dir < 0) + { + /* ??? These reverse argument ABIs are probably too old + to have cared about alignment. Someone should check. */ + argp -= za; + memcpy (argp, valp, z); + } + else + { + argp = (char *)ALIGN (argp, align); + memcpy (argp, valp, z); + argp += za; + } + } + } + FFI_ASSERT (dir > 0 || argp == stack); + + ffi_call_i386 (frame, stack); +} + +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} + +/** private members **/ + +void FFI_HIDDEN ffi_closure_i386(void); +void FFI_HIDDEN ffi_closure_STDCALL(void); +void FFI_HIDDEN ffi_closure_REGISTER(void); + +struct closure_frame +{ + unsigned rettemp[4]; /* 0 */ + unsigned regs[3]; /* 16-24 */ + ffi_cif *cif; /* 28 */ + void (*fun)(ffi_cif*,void*,void**,void*); /* 32 */ + void *user_data; /* 36 */ +}; + +int FFI_HIDDEN +#if HAVE_FASTCALL +__declspec(fastcall) +#endif +ffi_closure_inner (struct closure_frame *frame, char *stack) +{ + ffi_cif *cif = frame->cif; + int cabi, i, n, flags, dir, narg_reg; + const struct abi_params *pabi; + ffi_type **arg_types; + char *argp; + void *rvalue; + void **avalue; + + cabi = cif->abi; + flags = cif->flags; + narg_reg = 0; + rvalue = frame->rettemp; + pabi = &abi_params[cabi]; + dir = pabi->dir; + argp = (dir < 0 ? stack + cif->bytes : stack); + + switch (flags) + { + case X86_RET_STRUCTARG: + if (pabi->nregs > 0) + { + rvalue = (void *)frame->regs[pabi->regs[0]]; + narg_reg = 1; + frame->rettemp[0] = (unsigned)rvalue; + break; + } + /* fallthru */ + case X86_RET_STRUCTPOP: + rvalue = *(void **)argp; + argp += sizeof(void *); + frame->rettemp[0] = (unsigned)rvalue; + break; + } + + n = cif->nargs; + avalue = alloca(sizeof(void *) * n); + + arg_types = cif->arg_types; + for (i = 0; i < n; ++i) + { + ffi_type *ty = arg_types[i]; + size_t z = ty->size; + int t = ty->type; + void *valp; + + if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT) + { + if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs) + valp = &frame->regs[pabi->regs[narg_reg++]]; + else if (dir < 0) + { + argp -= 4; + valp = argp; + } + else + { + valp = argp; + argp += 4; + } + } + else + { + size_t za = ALIGN (z, FFI_SIZEOF_ARG); + size_t align = FFI_SIZEOF_ARG; + + /* See the comment in ffi_call_int. */ + if (t == FFI_TYPE_STRUCT && ty->alignment >= 16) + align = 16; + + if (dir < 0) + { + /* ??? These reverse argument ABIs are probably too old + to have cared about alignment. Someone should check. */ + argp -= za; + valp = argp; + } + else + { + argp = (char *)ALIGN (argp, align); + valp = argp; + argp += za; + } + } + + avalue[i] = valp; + } + + frame->fun (cif, rvalue, avalue, frame->user_data); + + if (cabi == FFI_STDCALL) + return flags + (cif->bytes << X86_RET_POP_SHIFT); + else + return flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + char *tramp = closure->tramp; + void (*dest)(void); + int op = 0xb8; /* movl imm, %eax */ + + switch (cif->abi) + { + case FFI_SYSV: + case FFI_THISCALL: + case FFI_FASTCALL: + case FFI_MS_CDECL: + dest = ffi_closure_i386; + break; + case FFI_STDCALL: + case FFI_PASCAL: + dest = ffi_closure_STDCALL; + break; + case FFI_REGISTER: + dest = ffi_closure_REGISTER; + op = 0x68; /* pushl imm */ + default: + return FFI_BAD_ABI; + } + + /* movl or pushl immediate. */ + tramp[0] = op; + *(void **)(tramp + 1) = codeloc; + + /* jmp dest */ + tramp[5] = 0xe9; + *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +void FFI_HIDDEN ffi_go_closure_EAX(void); +void FFI_HIDDEN ffi_go_closure_ECX(void); +void FFI_HIDDEN ffi_go_closure_STDCALL(void); + +ffi_status +ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*)) +{ + void (*dest)(void); + + switch (cif->abi) + { + case FFI_SYSV: + case FFI_MS_CDECL: + dest = ffi_go_closure_ECX; + break; + case FFI_THISCALL: + case FFI_FASTCALL: + dest = ffi_go_closure_EAX; + break; + case FFI_STDCALL: + case FFI_PASCAL: + dest = ffi_go_closure_STDCALL; + break; + case FFI_REGISTER: + default: + return FFI_BAD_ABI; + } + + closure->tramp = dest; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} + +/* ------- Native raw API support -------------------------------- */ + +#if !FFI_NO_RAW_API + +void FFI_HIDDEN ffi_closure_raw_SYSV(void); +void FFI_HIDDEN ffi_closure_raw_THISCALL(void); + +ffi_status +ffi_prep_raw_closure_loc (ffi_raw_closure *closure, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc) +{ + char *tramp = closure->tramp; + void (*dest)(void); + int i; + + /* We currently don't support certain kinds of arguments for raw + closures. This should be implemented by a separate assembly + language routine, since it would require argument processing, + something we don't do now for performance. */ + for (i = cif->nargs-1; i >= 0; i--) + switch (cif->arg_types[i]->type) + { + case FFI_TYPE_STRUCT: + case FFI_TYPE_LONGDOUBLE: + return FFI_BAD_TYPEDEF; + } + + switch (cif->abi) + { + case FFI_THISCALL: + dest = ffi_closure_raw_THISCALL; + break; + case FFI_SYSV: + dest = ffi_closure_raw_SYSV; + break; + default: + return FFI_BAD_ABI; + } + + /* movl imm, %eax. */ + tramp[0] = 0xb8; + *(void **)(tramp + 1) = codeloc; + + /* jmp dest */ + tramp[5] = 0xe9; + *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +void +ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue) +{ + size_t rsize, bytes; + struct call_frame *frame; + char *stack, *argp; + ffi_type **arg_types; + int flags, cabi, i, n, narg_reg; + const struct abi_params *pabi; + + flags = cif->flags; + cabi = cif->abi; + pabi = &abi_params[cabi]; + + rsize = 0; + if (rvalue == NULL) + { + switch (flags) + { + case X86_RET_FLOAT: + case X86_RET_DOUBLE: + case X86_RET_LDOUBLE: + case X86_RET_STRUCTPOP: + case X86_RET_STRUCTARG: + /* The float cases need to pop the 387 stack. + The struct cases need to pass a valid pointer to the callee. */ + rsize = cif->rtype->size; + break; + default: + /* We can pretend that the callee returns nothing. */ + flags = X86_RET_VOID; + break; + } + } + + bytes = cif->bytes; + argp = stack = alloca(bytes + sizeof(*frame) + rsize); + frame = (struct call_frame *)(stack + bytes); + if (rsize) + rvalue = frame + 1; + + frame->fn = fn; + frame->flags = flags; + frame->rvalue = rvalue; + + narg_reg = 0; + switch (flags) + { + case X86_RET_STRUCTARG: + /* The pointer is passed as the first argument. */ + if (pabi->nregs > 0) + { + frame->regs[pabi->regs[0]] = (unsigned)rvalue; + narg_reg = 1; + break; + } + /* fallthru */ + case X86_RET_STRUCTPOP: + *(void **)argp = rvalue; + argp += sizeof(void *); + bytes -= sizeof(void *); + break; + } + + arg_types = cif->arg_types; + for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++) + { + ffi_type *ty = arg_types[i]; + size_t z = ty->size; + int t = ty->type; + + if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT) + { + ffi_arg val = extend_basic_type (avalue, t); + frame->regs[pabi->regs[narg_reg++]] = val; + z = FFI_SIZEOF_ARG; + } + else + { + memcpy (argp, avalue, z); + z = ALIGN (z, FFI_SIZEOF_ARG); + argp += z; + } + avalue += z; + bytes -= z; + } + if (i < n) + memcpy (argp, avalue, bytes); + + ffi_call_i386 (frame, stack); +} +#endif /* !FFI_NO_RAW_API */ +#endif /* !__x86_64__ */ diff --git a/circuitpython/lib/libffi/src/x86/ffi64.c b/circuitpython/lib/libffi/src/x86/ffi64.c new file mode 100644 index 0000000..131b5e3 --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/ffi64.c @@ -0,0 +1,824 @@ +/* ----------------------------------------------------------------------- + ffi64.c - Copyright (c) 2013 The Written Word, Inc. + Copyright (c) 2011 Anthony Green + Copyright (c) 2008, 2010 Red Hat, Inc. + Copyright (c) 2002, 2007 Bo Thorsen + + x86-64 Foreign Function Interface + + 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 +#include + +#include +#include +#include +#include "internal64.h" + +#ifdef __x86_64__ + +#define MAX_GPR_REGS 6 +#define MAX_SSE_REGS 8 + +#if defined(__INTEL_COMPILER) +#include "xmmintrin.h" +#define UINT128 __m128 +#else +#if defined(__SUNPRO_C) +#include +#define UINT128 __m128i +#else +#define UINT128 __int128_t +#endif +#endif + +union big_int_union +{ + UINT32 i32; + UINT64 i64; + UINT128 i128; +}; + +struct register_args +{ + /* Registers for argument passing. */ + UINT64 gpr[MAX_GPR_REGS]; + union big_int_union sse[MAX_SSE_REGS]; + UINT64 rax; /* ssecount */ + UINT64 r10; /* static chain */ +}; + +extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, + void *raddr, void (*fnaddr)(void)) FFI_HIDDEN; + +/* All reference to register classes here is identical to the code in + gcc/config/i386/i386.c. Do *not* change one without the other. */ + +/* Register class used for passing given 64bit part of the argument. + These represent classes as documented by the PS ABI, with the + exception of SSESF, SSEDF classes, that are basically SSE class, + just gcc will use SF or DFmode move instead of DImode to avoid + reformatting penalties. + + Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves + whenever possible (upper half does contain padding). */ +enum x86_64_reg_class + { + X86_64_NO_CLASS, + X86_64_INTEGER_CLASS, + X86_64_INTEGERSI_CLASS, + X86_64_SSE_CLASS, + X86_64_SSESF_CLASS, + X86_64_SSEDF_CLASS, + X86_64_SSEUP_CLASS, + X86_64_X87_CLASS, + X86_64_X87UP_CLASS, + X86_64_COMPLEX_X87_CLASS, + X86_64_MEMORY_CLASS + }; + +#define MAX_CLASSES 4 + +#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS) + +/* x86-64 register passing implementation. See x86-64 ABI for details. Goal + of this code is to classify each 8bytes of incoming argument by the register + class and assign registers accordingly. */ + +/* Return the union class of CLASS1 and CLASS2. + See the x86-64 PS ABI for details. */ + +static enum x86_64_reg_class +merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2) +{ + /* Rule #1: If both classes are equal, this is the resulting class. */ + if (class1 == class2) + return class1; + + /* Rule #2: If one of the classes is NO_CLASS, the resulting class is + the other class. */ + if (class1 == X86_64_NO_CLASS) + return class2; + if (class2 == X86_64_NO_CLASS) + return class1; + + /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */ + if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS) + return X86_64_MEMORY_CLASS; + + /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */ + if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS) + || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS)) + return X86_64_INTEGERSI_CLASS; + if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS + || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS) + return X86_64_INTEGER_CLASS; + + /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class, + MEMORY is used. */ + if (class1 == X86_64_X87_CLASS + || class1 == X86_64_X87UP_CLASS + || class1 == X86_64_COMPLEX_X87_CLASS + || class2 == X86_64_X87_CLASS + || class2 == X86_64_X87UP_CLASS + || class2 == X86_64_COMPLEX_X87_CLASS) + return X86_64_MEMORY_CLASS; + + /* Rule #6: Otherwise class SSE is used. */ + return X86_64_SSE_CLASS; +} + +/* Classify the argument of type TYPE and mode MODE. + CLASSES will be filled by the register class used to pass each word + of the operand. The number of words is returned. In case the parameter + should be passed in memory, 0 is returned. As a special case for zero + sized containers, classes[0] will be NO_CLASS and 1 is returned. + + See the x86-64 PS ABI for details. +*/ +static size_t +classify_argument (ffi_type *type, enum x86_64_reg_class classes[], + size_t byte_offset) +{ + switch (type->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + do_integer: + { + size_t size = byte_offset + type->size; + + if (size <= 4) + { + classes[0] = X86_64_INTEGERSI_CLASS; + return 1; + } + else if (size <= 8) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (size <= 12) + { + classes[0] = X86_64_INTEGER_CLASS; + classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else if (size <= 16) + { + classes[0] = classes[1] = X86_64_INTEGER_CLASS; + return 2; + } + else + FFI_ASSERT (0); + } + case FFI_TYPE_FLOAT: + if (!(byte_offset % 8)) + classes[0] = X86_64_SSESF_CLASS; + else + classes[0] = X86_64_SSE_CLASS; + return 1; + case FFI_TYPE_DOUBLE: + classes[0] = X86_64_SSEDF_CLASS; + return 1; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + classes[0] = X86_64_X87_CLASS; + classes[1] = X86_64_X87UP_CLASS; + return 2; +#endif + case FFI_TYPE_STRUCT: + { + const size_t UNITS_PER_WORD = 8; + size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + ffi_type **ptr; + int i; + enum x86_64_reg_class subclasses[MAX_CLASSES]; + + /* If the struct is larger than 32 bytes, pass it on the stack. */ + if (type->size > 32) + return 0; + + for (i = 0; i < words; i++) + classes[i] = X86_64_NO_CLASS; + + /* Zero sized arrays or structures are NO_CLASS. We return 0 to + signalize memory class, so handle it as special case. */ + if (!words) + { + case FFI_TYPE_VOID: + classes[0] = X86_64_NO_CLASS; + return 1; + } + + /* Merge the fields of structure. */ + for (ptr = type->elements; *ptr != NULL; ptr++) + { + size_t num; + + byte_offset = ALIGN (byte_offset, (*ptr)->alignment); + + num = classify_argument (*ptr, subclasses, byte_offset % 8); + if (num == 0) + return 0; + for (i = 0; i < num; i++) + { + size_t pos = byte_offset / 8; + classes[i + pos] = + merge_classes (subclasses[i], classes[i + pos]); + } + + byte_offset += (*ptr)->size; + } + + if (words > 2) + { + /* When size > 16 bytes, if the first one isn't + X86_64_SSE_CLASS or any other ones aren't + X86_64_SSEUP_CLASS, everything should be passed in + memory. */ + if (classes[0] != X86_64_SSE_CLASS) + return 0; + + for (i = 1; i < words; i++) + if (classes[i] != X86_64_SSEUP_CLASS) + return 0; + } + + /* Final merger cleanup. */ + for (i = 0; i < words; i++) + { + /* If one class is MEMORY, everything should be passed in + memory. */ + if (classes[i] == X86_64_MEMORY_CLASS) + return 0; + + /* The X86_64_SSEUP_CLASS should be always preceded by + X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */ + if (classes[i] == X86_64_SSEUP_CLASS + && classes[i - 1] != X86_64_SSE_CLASS + && classes[i - 1] != X86_64_SSEUP_CLASS) + { + /* The first one should never be X86_64_SSEUP_CLASS. */ + FFI_ASSERT (i != 0); + classes[i] = X86_64_SSE_CLASS; + } + + /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS, + everything should be passed in memory. */ + if (classes[i] == X86_64_X87UP_CLASS + && (classes[i - 1] != X86_64_X87_CLASS)) + { + /* The first one should never be X86_64_X87UP_CLASS. */ + FFI_ASSERT (i != 0); + return 0; + } + } + return words; + } + case FFI_TYPE_COMPLEX: + { + ffi_type *inner = type->elements[0]; + switch (inner->type) + { + case FFI_TYPE_INT: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + goto do_integer; + + case FFI_TYPE_FLOAT: + classes[0] = X86_64_SSE_CLASS; + if (byte_offset % 8) + { + classes[1] = X86_64_SSESF_CLASS; + return 2; + } + return 1; + case FFI_TYPE_DOUBLE: + classes[0] = classes[1] = X86_64_SSEDF_CLASS; + return 2; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + classes[0] = X86_64_COMPLEX_X87_CLASS; + return 1; +#endif + } + } + } + abort(); +} + +/* Examine the argument and return set number of register required in each + class. Return zero iff parameter should be passed in memory, otherwise + the number of registers. */ + +static size_t +examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES], + _Bool in_return, int *pngpr, int *pnsse) +{ + size_t n; + int i, ngpr, nsse; + + n = classify_argument (type, classes, 0); + if (n == 0) + return 0; + + ngpr = nsse = 0; + for (i = 0; i < n; ++i) + switch (classes[i]) + { + case X86_64_INTEGER_CLASS: + case X86_64_INTEGERSI_CLASS: + ngpr++; + break; + case X86_64_SSE_CLASS: + case X86_64_SSESF_CLASS: + case X86_64_SSEDF_CLASS: + nsse++; + break; + case X86_64_NO_CLASS: + case X86_64_SSEUP_CLASS: + break; + case X86_64_X87_CLASS: + case X86_64_X87UP_CLASS: + case X86_64_COMPLEX_X87_CLASS: + return in_return != 0; + default: + abort (); + } + + *pngpr = ngpr; + *pnsse = nsse; + + return n; +} + +/* Perform machine dependent cif processing. */ + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + int gprcount, ssecount, i, avn, ngpr, nsse, flags; + enum x86_64_reg_class classes[MAX_CLASSES]; + size_t bytes, n, rtype_size; + ffi_type *rtype; + + if (cif->abi != FFI_UNIX64) + return FFI_BAD_ABI; + + gprcount = ssecount = 0; + + rtype = cif->rtype; + rtype_size = rtype->size; + switch (rtype->type) + { + case FFI_TYPE_VOID: + flags = UNIX64_RET_VOID; + break; + case FFI_TYPE_UINT8: + flags = UNIX64_RET_UINT8; + break; + case FFI_TYPE_SINT8: + flags = UNIX64_RET_SINT8; + break; + case FFI_TYPE_UINT16: + flags = UNIX64_RET_UINT16; + break; + case FFI_TYPE_SINT16: + flags = UNIX64_RET_SINT16; + break; + case FFI_TYPE_UINT32: + flags = UNIX64_RET_UINT32; + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + flags = UNIX64_RET_SINT32; + break; + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags = UNIX64_RET_INT64; + break; + case FFI_TYPE_POINTER: + flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64); + break; + case FFI_TYPE_FLOAT: + flags = UNIX64_RET_XMM32; + break; + case FFI_TYPE_DOUBLE: + flags = UNIX64_RET_XMM64; + break; + case FFI_TYPE_LONGDOUBLE: + flags = UNIX64_RET_X87; + break; + case FFI_TYPE_STRUCT: + n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); + if (n == 0) + { + /* The return value is passed in memory. A pointer to that + memory is the first argument. Allocate a register for it. */ + gprcount++; + /* We don't have to do anything in asm for the return. */ + flags = UNIX64_RET_VOID | UNIX64_FLAG_RET_IN_MEM; + } + else + { + _Bool sse0 = SSE_CLASS_P (classes[0]); + + if (rtype_size == 4 && sse0) + flags = UNIX64_RET_XMM32; + else if (rtype_size == 8) + flags = sse0 ? UNIX64_RET_XMM64 : UNIX64_RET_INT64; + else + { + _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]); + if (sse0 && sse1) + flags = UNIX64_RET_ST_XMM0_XMM1; + else if (sse0) + flags = UNIX64_RET_ST_XMM0_RAX; + else if (sse1) + flags = UNIX64_RET_ST_RAX_XMM0; + else + flags = UNIX64_RET_ST_RAX_RDX; + flags |= rtype_size << UNIX64_SIZE_SHIFT; + } + } + break; + case FFI_TYPE_COMPLEX: + switch (rtype->elements[0]->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags = UNIX64_RET_ST_RAX_RDX | (rtype_size << UNIX64_SIZE_SHIFT); + break; + case FFI_TYPE_FLOAT: + flags = UNIX64_RET_XMM64; + break; + case FFI_TYPE_DOUBLE: + flags = UNIX64_RET_ST_XMM0_XMM1 | (16 << UNIX64_SIZE_SHIFT); + break; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + flags = UNIX64_RET_X87_2; + break; +#endif + default: + return FFI_BAD_TYPEDEF; + } + break; + default: + return FFI_BAD_TYPEDEF; + } + + /* Go over all arguments and determine the way they should be passed. + If it's in a register and there is space for it, let that be so. If + not, add it's size to the stack byte count. */ + for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++) + { + if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = cif->arg_types[i]->alignment; + + if (align < 8) + align = 8; + + bytes = ALIGN (bytes, align); + bytes += cif->arg_types[i]->size; + } + else + { + gprcount += ngpr; + ssecount += nsse; + } + } + if (ssecount) + flags |= UNIX64_FLAG_XMM_ARGS; + + cif->flags = flags; + cif->bytes = ALIGN (bytes, 8); + + return FFI_OK; +} + +static void +ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + enum x86_64_reg_class classes[MAX_CLASSES]; + char *stack, *argp; + ffi_type **arg_types; + int gprcount, ssecount, ngpr, nsse, i, avn, flags; + struct register_args *reg_args; + + /* Can't call 32-bit mode from 64-bit mode. */ + FFI_ASSERT (cif->abi == FFI_UNIX64); + + /* If the return value is a struct and we don't have a return value + address then we need to make one. Otherwise we can ignore it. */ + flags = cif->flags; + if (rvalue == NULL) + { + if (flags & UNIX64_FLAG_RET_IN_MEM) + rvalue = alloca (cif->rtype->size); + else + flags = UNIX64_RET_VOID; + } + + /* Allocate the space for the arguments, plus 4 words of temp space. */ + stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8); + reg_args = (struct register_args *) stack; + argp = stack + sizeof (struct register_args); + + reg_args->r10 = (uintptr_t) closure; + + gprcount = ssecount = 0; + + /* If the return value is passed in memory, add the pointer as the + first integer argument. */ + if (flags & UNIX64_FLAG_RET_IN_MEM) + reg_args->gpr[gprcount++] = (unsigned long) rvalue; + + avn = cif->nargs; + arg_types = cif->arg_types; + + for (i = 0; i < avn; ++i) + { + size_t n, size = arg_types[i]->size; + + n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); + if (n == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = arg_types[i]->alignment; + + /* Stack arguments are *always* at least 8 byte aligned. */ + if (align < 8) + align = 8; + + /* Pass this argument in memory. */ + argp = (void *) ALIGN (argp, align); + memcpy (argp, avalue[i], size); + argp += size; + } + else + { + /* The argument is passed entirely in registers. */ + char *a = (char *) avalue[i]; + int j; + + for (j = 0; j < n; j++, a += 8, size -= 8) + { + switch (classes[j]) + { + case X86_64_NO_CLASS: + case X86_64_SSEUP_CLASS: + break; + case X86_64_INTEGER_CLASS: + case X86_64_INTEGERSI_CLASS: + /* Sign-extend integer arguments passed in general + purpose registers, to cope with the fact that + LLVM incorrectly assumes that this will be done + (the x86-64 PS ABI does not specify this). */ + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + reg_args->gpr[gprcount] = (SINT64) *((SINT8 *) a); + break; + case FFI_TYPE_SINT16: + reg_args->gpr[gprcount] = (SINT64) *((SINT16 *) a); + break; + case FFI_TYPE_SINT32: + reg_args->gpr[gprcount] = (SINT64) *((SINT32 *) a); + break; + default: + reg_args->gpr[gprcount] = 0; + memcpy (®_args->gpr[gprcount], a, size); + } + gprcount++; + break; + case X86_64_SSE_CLASS: + case X86_64_SSEDF_CLASS: + reg_args->sse[ssecount++].i64 = *(UINT64 *) a; + break; + case X86_64_SSESF_CLASS: + reg_args->sse[ssecount++].i32 = *(UINT32 *) a; + break; + default: + abort(); + } + } + } + } + reg_args->rax = ssecount; + + ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args), + flags, rvalue, fn); +} + +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} + +extern void ffi_closure_unix64(void) FFI_HIDDEN; +extern void ffi_closure_unix64_sse(void) FFI_HIDDEN; + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + static const unsigned char trampoline[16] = { + /* leaq -0x7(%rip),%r10 # 0x0 */ + 0x4c, 0x8d, 0x15, 0xf9, 0xff, 0xff, 0xff, + /* jmpq *0x3(%rip) # 0x10 */ + 0xff, 0x25, 0x03, 0x00, 0x00, 0x00, + /* nopl (%rax) */ + 0x0f, 0x1f, 0x00 + }; + void (*dest)(void); + char *tramp = closure->tramp; + + if (cif->abi != FFI_UNIX64) + return FFI_BAD_ABI; + + if (cif->flags & UNIX64_FLAG_XMM_ARGS) + dest = ffi_closure_unix64_sse; + else + dest = ffi_closure_unix64; + + memcpy (tramp, trampoline, sizeof(trampoline)); + *(UINT64 *)(tramp + 16) = (uintptr_t)dest; + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +int FFI_HIDDEN +ffi_closure_unix64_inner(ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *rvalue, + struct register_args *reg_args, + char *argp) +{ + void **avalue; + ffi_type **arg_types; + long i, avn; + int gprcount, ssecount, ngpr, nsse; + int flags; + + avn = cif->nargs; + flags = cif->flags; + avalue = alloca(avn * sizeof(void *)); + gprcount = ssecount = 0; + + if (flags & UNIX64_FLAG_RET_IN_MEM) + { + /* On return, %rax will contain the address that was passed + by the caller in %rdi. */ + void *r = (void *)(uintptr_t)reg_args->gpr[gprcount++]; + *(void **)rvalue = r; + rvalue = r; + flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64); + } + + arg_types = cif->arg_types; + for (i = 0; i < avn; ++i) + { + enum x86_64_reg_class classes[MAX_CLASSES]; + size_t n; + + n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); + if (n == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = arg_types[i]->alignment; + + /* Stack arguments are *always* at least 8 byte aligned. */ + if (align < 8) + align = 8; + + /* Pass this argument in memory. */ + argp = (void *) ALIGN (argp, align); + avalue[i] = argp; + argp += arg_types[i]->size; + } + /* If the argument is in a single register, or two consecutive + integer registers, then we can use that address directly. */ + else if (n == 1 + || (n == 2 && !(SSE_CLASS_P (classes[0]) + || SSE_CLASS_P (classes[1])))) + { + /* The argument is in a single register. */ + if (SSE_CLASS_P (classes[0])) + { + avalue[i] = ®_args->sse[ssecount]; + ssecount += n; + } + else + { + avalue[i] = ®_args->gpr[gprcount]; + gprcount += n; + } + } + /* Otherwise, allocate space to make them consecutive. */ + else + { + char *a = alloca (16); + int j; + + avalue[i] = a; + for (j = 0; j < n; j++, a += 8) + { + if (SSE_CLASS_P (classes[j])) + memcpy (a, ®_args->sse[ssecount++], 8); + else + memcpy (a, ®_args->gpr[gprcount++], 8); + } + } + } + + /* Invoke the closure. */ + fun (cif, rvalue, avalue, user_data); + + /* Tell assembly how to perform return type promotions. */ + return flags; +} + +extern void ffi_go_closure_unix64(void) FFI_HIDDEN; +extern void ffi_go_closure_unix64_sse(void) FFI_HIDDEN; + +ffi_status +ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*)) +{ + if (cif->abi != FFI_UNIX64) + return FFI_BAD_ABI; + + closure->tramp = (cif->flags & UNIX64_FLAG_XMM_ARGS + ? ffi_go_closure_unix64_sse + : ffi_go_closure_unix64); + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} + +#endif /* __x86_64__ */ diff --git a/circuitpython/lib/libffi/src/x86/ffitarget.h b/circuitpython/lib/libffi/src/x86/ffitarget.h new file mode 100644 index 0000000..8c1dcac --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/ffitarget.h @@ -0,0 +1,139 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012, 2014 Anthony Green + Copyright (c) 1996-2003, 2010 Red Hat, Inc. + Copyright (C) 2008 Free Software Foundation, Inc. + + Target configuration macros for x86 and x86-64. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- System specific configurations ----------------------------------- */ + +/* For code common to all platforms on x86 and x86_64. */ +#define X86_ANY + +#if defined (X86_64) && defined (__i386__) +#undef X86_64 +#define X86 +#endif + +#ifdef X86_WIN64 +#define FFI_SIZEOF_ARG 8 +#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */ +#endif + +#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION +#ifndef _MSC_VER +#define FFI_TARGET_HAS_COMPLEX_TYPE +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM +#ifdef X86_WIN64 +#ifdef _MSC_VER +typedef unsigned __int64 ffi_arg; +typedef __int64 ffi_sarg; +#else +typedef unsigned long long ffi_arg; +typedef long long ffi_sarg; +#endif +#else +#if defined __x86_64__ && defined __ILP32__ +#define FFI_SIZEOF_ARG 8 +#define FFI_SIZEOF_JAVA_RAW 4 +typedef unsigned long long ffi_arg; +typedef long long ffi_sarg; +#else +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; +#endif +#endif + +typedef enum ffi_abi { +#if defined(X86_WIN64) + FFI_FIRST_ABI = 0, + FFI_WIN64, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_WIN64 + +#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) + FFI_FIRST_ABI = 1, + FFI_UNIX64, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_UNIX64 + +#elif defined(X86_WIN32) + FFI_FIRST_ABI = 0, + FFI_SYSV = 1, + FFI_STDCALL = 2, + FFI_THISCALL = 3, + FFI_FASTCALL = 4, + FFI_MS_CDECL = 5, + FFI_PASCAL = 6, + FFI_REGISTER = 7, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_MS_CDECL +#else + FFI_FIRST_ABI = 0, + FFI_SYSV = 1, + FFI_THISCALL = 3, + FFI_FASTCALL = 4, + FFI_STDCALL = 5, + FFI_PASCAL = 6, + FFI_REGISTER = 7, + FFI_MS_CDECL = 8, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +#endif +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_GO_CLOSURES 1 + +#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) +#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) +#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) +#define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) + +#if defined (X86_64) || defined(X86_WIN64) \ + || (defined (__x86_64__) && defined (X86_DARWIN)) +# define FFI_TRAMPOLINE_SIZE 24 +# define FFI_NATIVE_RAW_API 0 +#else +# define FFI_TRAMPOLINE_SIZE 12 +# define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ +#endif + +#endif + diff --git a/circuitpython/lib/libffi/src/x86/ffiw64.c b/circuitpython/lib/libffi/src/x86/ffiw64.c new file mode 100644 index 0000000..8a33a6c --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/ffiw64.c @@ -0,0 +1,281 @@ +/* ----------------------------------------------------------------------- + ffiw64.c - Copyright (c) 2014 Red Hat, Inc. + + x86 win64 Foreign Function Interface + + 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 +#include +#include +#include + +#ifdef X86_WIN64 + +struct win64_call_frame +{ + UINT64 rbp; /* 0 */ + UINT64 retaddr; /* 8 */ + UINT64 fn; /* 16 */ + UINT64 flags; /* 24 */ + UINT64 rvalue; /* 32 */ +}; + +extern void ffi_call_win64 (void *stack, struct win64_call_frame *, + void *closure) FFI_HIDDEN; + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + int flags, n; + + if (cif->abi != FFI_WIN64) + return FFI_BAD_ABI; + + flags = cif->rtype->type; + switch (flags) + { + default: + break; + case FFI_TYPE_LONGDOUBLE: + flags = FFI_TYPE_STRUCT; + break; + case FFI_TYPE_COMPLEX: + flags = FFI_TYPE_STRUCT; + /* FALLTHRU */ + case FFI_TYPE_STRUCT: + switch (cif->rtype->size) + { + case 8: + flags = FFI_TYPE_UINT64; + break; + case 4: + flags = FFI_TYPE_SMALL_STRUCT_4B; + break; + case 2: + flags = FFI_TYPE_SMALL_STRUCT_2B; + break; + case 1: + flags = FFI_TYPE_SMALL_STRUCT_1B; + break; + } + break; + } + cif->flags = flags; + + /* Each argument either fits in a register, an 8 byte slot, or is + passed by reference with the pointer in the 8 byte slot. */ + n = cif->nargs; + n += (flags == FFI_TYPE_STRUCT); + if (n < 4) + n = 4; + cif->bytes = n * 8; + + return FFI_OK; +} + +static void +ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + int i, j, n, flags; + UINT64 *stack; + size_t rsize; + struct win64_call_frame *frame; + + FFI_ASSERT(cif->abi == FFI_WIN64); + + flags = cif->flags; + rsize = 0; + + /* If we have no return value for a structure, we need to create one. + Otherwise we can ignore the return type entirely. */ + if (rvalue == NULL) + { + if (flags == FFI_TYPE_STRUCT) + rsize = cif->rtype->size; + else + flags = FFI_TYPE_VOID; + } + + stack = alloca(cif->bytes + sizeof(struct win64_call_frame) + rsize); + frame = (struct win64_call_frame *)((char *)stack + cif->bytes); + if (rsize) + rvalue = frame + 1; + + frame->fn = (uintptr_t)fn; + frame->flags = flags; + frame->rvalue = (uintptr_t)rvalue; + + j = 0; + if (flags == FFI_TYPE_STRUCT) + { + stack[0] = (uintptr_t)rvalue; + j = 1; + } + + for (i = 0, n = cif->nargs; i < n; ++i, ++j) + { + switch (cif->arg_types[i]->size) + { + case 8: + stack[j] = *(UINT64 *)avalue[i]; + break; + case 4: + stack[j] = *(UINT32 *)avalue[i]; + break; + case 2: + stack[j] = *(UINT16 *)avalue[i]; + break; + case 1: + stack[j] = *(UINT8 *)avalue[i]; + break; + default: + stack[j] = (uintptr_t)avalue[i]; + break; + } + } + + ffi_call_win64 (stack, frame, closure); +} + +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} + + +extern void ffi_closure_win64(void) FFI_HIDDEN; +extern void ffi_go_closure_win64(void) FFI_HIDDEN; + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + static const unsigned char trampoline[16] = { + /* leaq -0x7(%rip),%r10 # 0x0 */ + 0x4c, 0x8d, 0x15, 0xf9, 0xff, 0xff, 0xff, + /* jmpq *0x3(%rip) # 0x10 */ + 0xff, 0x25, 0x03, 0x00, 0x00, 0x00, + /* nopl (%rax) */ + 0x0f, 0x1f, 0x00 + }; + unsigned char *tramp = closure->tramp; + + if (cif->abi != FFI_WIN64) + return FFI_BAD_ABI; + + memcpy (tramp, trampoline, sizeof(trampoline)); + *(UINT64 *)(tramp + 16) = (uintptr_t)ffi_closure_win64; + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +ffi_status +ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*)) +{ + if (cif->abi != FFI_WIN64) + return FFI_BAD_ABI; + + closure->tramp = ffi_go_closure_win64; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} + +struct win64_closure_frame +{ + UINT64 rvalue[2]; + UINT64 fargs[4]; + UINT64 retaddr; + UINT64 args[]; +}; + +int FFI_HIDDEN +ffi_closure_win64_inner(ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + struct win64_closure_frame *frame) +{ + void **avalue; + void *rvalue; + int i, n, nreg, flags; + + avalue = alloca(cif->nargs * sizeof(void *)); + rvalue = frame->rvalue; + nreg = 0; + + /* When returning a structure, the address is in the first argument. + We must also be prepared to return the same address in eax, so + install that address in the frame and pretend we return a pointer. */ + flags = cif->flags; + if (flags == FFI_TYPE_STRUCT) + { + rvalue = (void *)(uintptr_t)frame->args[0]; + frame->rvalue[0] = frame->args[0]; + nreg = 1; + } + + for (i = 0, n = cif->nargs; i < n; ++i, ++nreg) + { + size_t size = cif->arg_types[i]->size; + size_t type = cif->arg_types[i]->type; + void *a; + + if (type == FFI_TYPE_DOUBLE || type == FFI_TYPE_FLOAT) + { + if (nreg < 4) + a = &frame->fargs[nreg]; + else + a = &frame->args[nreg]; + } + else if (size == 1 || size == 2 || size == 4 || size == 8) + a = &frame->args[nreg]; + else + a = (void *)(uintptr_t)frame->args[nreg]; + + avalue[i] = a; + } + + /* Invoke the closure. */ + fun (cif, rvalue, avalue, user_data); + return flags; +} + +#endif /* X86_WIN64 */ diff --git a/circuitpython/lib/libffi/src/x86/internal.h b/circuitpython/lib/libffi/src/x86/internal.h new file mode 100644 index 0000000..09771ba --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/internal.h @@ -0,0 +1,29 @@ +#define X86_RET_FLOAT 0 +#define X86_RET_DOUBLE 1 +#define X86_RET_LDOUBLE 2 +#define X86_RET_SINT8 3 +#define X86_RET_SINT16 4 +#define X86_RET_UINT8 5 +#define X86_RET_UINT16 6 +#define X86_RET_INT64 7 +#define X86_RET_INT32 8 +#define X86_RET_VOID 9 +#define X86_RET_STRUCTPOP 10 +#define X86_RET_STRUCTARG 11 +#define X86_RET_STRUCT_1B 12 +#define X86_RET_STRUCT_2B 13 +#define X86_RET_UNUSED14 14 +#define X86_RET_UNUSED15 15 + +#define X86_RET_TYPE_MASK 15 +#define X86_RET_POP_SHIFT 4 + +#define R_EAX 0 +#define R_EDX 1 +#define R_ECX 2 + +#ifdef __PCC__ +# define HAVE_FASTCALL 0 +#else +# define HAVE_FASTCALL 1 +#endif diff --git a/circuitpython/lib/libffi/src/x86/internal64.h b/circuitpython/lib/libffi/src/x86/internal64.h new file mode 100644 index 0000000..512e955 --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/internal64.h @@ -0,0 +1,22 @@ +#define UNIX64_RET_VOID 0 +#define UNIX64_RET_UINT8 1 +#define UNIX64_RET_UINT16 2 +#define UNIX64_RET_UINT32 3 +#define UNIX64_RET_SINT8 4 +#define UNIX64_RET_SINT16 5 +#define UNIX64_RET_SINT32 6 +#define UNIX64_RET_INT64 7 +#define UNIX64_RET_XMM32 8 +#define UNIX64_RET_XMM64 9 +#define UNIX64_RET_X87 10 +#define UNIX64_RET_X87_2 11 +#define UNIX64_RET_ST_XMM0_RAX 12 +#define UNIX64_RET_ST_RAX_XMM0 13 +#define UNIX64_RET_ST_XMM0_XMM1 14 +#define UNIX64_RET_ST_RAX_RDX 15 + +#define UNIX64_RET_LAST 15 + +#define UNIX64_FLAG_RET_IN_MEM (1 << 10) +#define UNIX64_FLAG_XMM_ARGS (1 << 11) +#define UNIX64_SIZE_SHIFT 12 diff --git a/circuitpython/lib/libffi/src/x86/sysv.S b/circuitpython/lib/libffi/src/x86/sysv.S new file mode 100644 index 0000000..78f245b --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/sysv.S @@ -0,0 +1,1040 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2013 The Written Word, Inc. + - Copyright (c) 1996,1998,2001-2003,2005,2008,2010 Red Hat, Inc. + + X86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef __x86_64__ + +#define LIBFFI_ASM +#include +#include +#include "internal.h" + +#define C2(X, Y) X ## Y +#define C1(X, Y) C2(X, Y) +#ifdef __USER_LABEL_PREFIX__ +# define C(X) C1(__USER_LABEL_PREFIX__, X) +#else +# define C(X) X +#endif + +#ifdef X86_DARWIN +# define L(X) C1(L, X) +#else +# define L(X) C1(.L, X) +#endif + +#ifdef __ELF__ +# define ENDF(X) .type X,@function; .size X, . - X +#else +# define ENDF(X) +#endif + +/* Handle win32 fastcall name mangling. */ +#ifdef X86_WIN32 +# define ffi_call_i386 @ffi_call_i386@8 +# define ffi_closure_inner @ffi_closure_inner@8 +#else +# define ffi_call_i386 C(ffi_call_i386) +# define ffi_closure_inner C(ffi_closure_inner) +#endif + +/* This macro allows the safe creation of jump tables without an + actual table. The entry points into the table are all 8 bytes. + The use of ORG asserts that we're at the correct location. */ +/* ??? The clang assembler doesn't handle .org with symbolic expressions. */ +#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__)) +# define E(BASE, X) .balign 8 +#else +# define E(BASE, X) .balign 8; .org BASE + X * 8 +#endif + + .text + .balign 16 + .globl ffi_call_i386 + FFI_HIDDEN(ffi_call_i386) + +/* This is declared as + + void ffi_call_i386(struct call_frame *frame, char *argp) + __attribute__((fastcall)); + + Thus the arguments are present in + + ecx: frame + edx: argp +*/ + +ffi_call_i386: +L(UW0): + # cfi_startproc +#if !HAVE_FASTCALL + movl 4(%esp), %ecx + movl 8(%esp), %edx +#endif + movl (%esp), %eax /* move the return address */ + movl %ebp, (%ecx) /* store %ebp into local frame */ + movl %eax, 4(%ecx) /* store retaddr into local frame */ + + /* New stack frame based off ebp. This is a itty bit of unwind + trickery in that the CFA *has* changed. There is no easy way + to describe it correctly on entry to the function. Fortunately, + it doesn't matter too much since at all points we can correctly + unwind back to ffi_call. Note that the location to which we + moved the return address is (the new) CFA-4, so from the + perspective of the unwind info, it hasn't moved. */ + movl %ecx, %ebp +L(UW1): + # cfi_def_cfa(%ebp, 8) + # cfi_rel_offset(%ebp, 0) + + movl %edx, %esp /* set outgoing argument stack */ + movl 20+R_EAX*4(%ebp), %eax /* set register arguments */ + movl 20+R_EDX*4(%ebp), %edx + movl 20+R_ECX*4(%ebp), %ecx + + call *8(%ebp) + + movl 12(%ebp), %ecx /* load return type code */ + movl %ebx, 8(%ebp) /* preserve %ebx */ +L(UW2): + # cfi_rel_offset(%ebx, 8) + + andl $X86_RET_TYPE_MASK, %ecx +#ifdef __PIC__ + call C(__x86.get_pc_thunk.bx) +L(pc1): + leal L(store_table)-L(pc1)(%ebx, %ecx, 8), %ebx +#else + leal L(store_table)(,%ecx, 8), %ebx +#endif + movl 16(%ebp), %ecx /* load result address */ + jmp *%ebx + + .balign 8 +L(store_table): +E(L(store_table), X86_RET_FLOAT) + fstps (%ecx) + jmp L(e1) +E(L(store_table), X86_RET_DOUBLE) + fstpl (%ecx) + jmp L(e1) +E(L(store_table), X86_RET_LDOUBLE) + fstpt (%ecx) + jmp L(e1) +E(L(store_table), X86_RET_SINT8) + movsbl %al, %eax + mov %eax, (%ecx) + jmp L(e1) +E(L(store_table), X86_RET_SINT16) + movswl %ax, %eax + mov %eax, (%ecx) + jmp L(e1) +E(L(store_table), X86_RET_UINT8) + movzbl %al, %eax + mov %eax, (%ecx) + jmp L(e1) +E(L(store_table), X86_RET_UINT16) + movzwl %ax, %eax + mov %eax, (%ecx) + jmp L(e1) +E(L(store_table), X86_RET_INT64) + movl %edx, 4(%ecx) + /* fallthru */ +E(L(store_table), X86_RET_INT32) + movl %eax, (%ecx) + /* fallthru */ +E(L(store_table), X86_RET_VOID) +L(e1): + movl 8(%ebp), %ebx + movl %ebp, %esp + popl %ebp +L(UW3): + # cfi_remember_state + # cfi_def_cfa(%esp, 4) + # cfi_restore(%ebx) + # cfi_restore(%ebp) + ret +L(UW4): + # cfi_restore_state + +E(L(store_table), X86_RET_STRUCTPOP) + jmp L(e1) +E(L(store_table), X86_RET_STRUCTARG) + jmp L(e1) +E(L(store_table), X86_RET_STRUCT_1B) + movb %al, (%ecx) + jmp L(e1) +E(L(store_table), X86_RET_STRUCT_2B) + movw %ax, (%ecx) + jmp L(e1) + + /* Fill out the table so that bad values are predictable. */ +E(L(store_table), X86_RET_UNUSED14) + ud2 +E(L(store_table), X86_RET_UNUSED15) + ud2 + +L(UW5): + # cfi_endproc +ENDF(ffi_call_i386) + +/* The inner helper is declared as + + void ffi_closure_inner(struct closure_frame *frame, char *argp) + __attribute_((fastcall)) + + Thus the arguments are placed in + + ecx: frame + edx: argp +*/ + +/* Macros to help setting up the closure_data structure. */ + +#if HAVE_FASTCALL +# define closure_FS (40 + 4) +# define closure_CF 0 +#else +# define closure_FS (8 + 40 + 12) +# define closure_CF 8 +#endif + +#define FFI_CLOSURE_SAVE_REGS \ + movl %eax, closure_CF+16+R_EAX*4(%esp); \ + movl %edx, closure_CF+16+R_EDX*4(%esp); \ + movl %ecx, closure_CF+16+R_ECX*4(%esp) + +#define FFI_CLOSURE_COPY_TRAMP_DATA \ + movl FFI_TRAMPOLINE_SIZE(%eax), %edx; /* copy cif */ \ + movl FFI_TRAMPOLINE_SIZE+4(%eax), %ecx; /* copy fun */ \ + movl FFI_TRAMPOLINE_SIZE+8(%eax), %eax; /* copy user_data */ \ + movl %edx, closure_CF+28(%esp); \ + movl %ecx, closure_CF+32(%esp); \ + movl %eax, closure_CF+36(%esp) + +#if HAVE_FASTCALL +# define FFI_CLOSURE_PREP_CALL \ + movl %esp, %ecx; /* load closure_data */ \ + leal closure_FS+4(%esp), %edx; /* load incoming stack */ +#else +# define FFI_CLOSURE_PREP_CALL \ + leal closure_CF(%esp), %ecx; /* load closure_data */ \ + leal closure_FS+4(%esp), %edx; /* load incoming stack */ \ + movl %ecx, (%esp); \ + movl %edx, 4(%esp) +#endif + +#define FFI_CLOSURE_CALL_INNER(UWN) \ + call ffi_closure_inner + +#define FFI_CLOSURE_MASK_AND_JUMP(N, UW) \ + andl $X86_RET_TYPE_MASK, %eax; \ + leal L(C1(load_table,N))(, %eax, 8), %edx; \ + movl closure_CF(%esp), %eax; /* optimiztic load */ \ + jmp *%edx + +#ifdef __PIC__ +# if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE +# undef FFI_CLOSURE_MASK_AND_JUMP +# define FFI_CLOSURE_MASK_AND_JUMP(N, UW) \ + andl $X86_RET_TYPE_MASK, %eax; \ + call C(__x86.get_pc_thunk.dx); \ +L(C1(pc,N)): \ + leal L(C1(load_table,N))-L(C1(pc,N))(%edx, %eax, 8), %edx; \ + movl closure_CF(%esp), %eax; /* optimiztic load */ \ + jmp *%edx +# else +# define FFI_CLOSURE_CALL_INNER_SAVE_EBX +# undef FFI_CLOSURE_CALL_INNER +# define FFI_CLOSURE_CALL_INNER(UWN) \ + movl %ebx, 40(%esp); /* save ebx */ \ +L(C1(UW,UWN)): \ + # cfi_rel_offset(%ebx, 40); \ + call C(__x86.get_pc_thunk.bx); /* load got register */ \ + addl $C(_GLOBAL_OFFSET_TABLE_), %ebx; \ + call ffi_closure_inner@PLT +# undef FFI_CLOSURE_MASK_AND_JUMP +# define FFI_CLOSURE_MASK_AND_JUMP(N, UWN) \ + andl $X86_RET_TYPE_MASK, %eax; \ + leal L(C1(load_table,N))@GOTOFF(%ebx, %eax, 8), %edx; \ + movl 40(%esp), %ebx; /* restore ebx */ \ +L(C1(UW,UWN)): \ + # cfi_restore(%ebx); \ + movl closure_CF(%esp), %eax; /* optimiztic load */ \ + jmp *%edx +# endif /* DARWIN || HIDDEN */ +#endif /* __PIC__ */ + + .balign 16 + .globl C(ffi_go_closure_EAX) + FFI_HIDDEN(C(ffi_go_closure_EAX)) +C(ffi_go_closure_EAX): +L(UW6): + # cfi_startproc + subl $closure_FS, %esp +L(UW7): + # cfi_def_cfa_offset(closure_FS + 4) + FFI_CLOSURE_SAVE_REGS + movl 4(%eax), %edx /* copy cif */ + movl 8(%eax), %ecx /* copy fun */ + movl %edx, closure_CF+28(%esp) + movl %ecx, closure_CF+32(%esp) + movl %eax, closure_CF+36(%esp) /* closure is user_data */ + jmp L(do_closure_i386) +L(UW8): + # cfi_endproc +ENDF(C(ffi_go_closure_EAX)) + + .balign 16 + .globl C(ffi_go_closure_ECX) + FFI_HIDDEN(C(ffi_go_closure_ECX)) +C(ffi_go_closure_ECX): +L(UW9): + # cfi_startproc + subl $closure_FS, %esp +L(UW10): + # cfi_def_cfa_offset(closure_FS + 4) + FFI_CLOSURE_SAVE_REGS + movl 4(%ecx), %edx /* copy cif */ + movl 8(%ecx), %eax /* copy fun */ + movl %edx, closure_CF+28(%esp) + movl %eax, closure_CF+32(%esp) + movl %ecx, closure_CF+36(%esp) /* closure is user_data */ + jmp L(do_closure_i386) +L(UW11): + # cfi_endproc +ENDF(C(ffi_go_closure_ECX)) + +/* The closure entry points are reached from the ffi_closure trampoline. + On entry, %eax contains the address of the ffi_closure. */ + + .balign 16 + .globl C(ffi_closure_i386) + FFI_HIDDEN(C(ffi_closure_i386)) + +C(ffi_closure_i386): +L(UW12): + # cfi_startproc + subl $closure_FS, %esp +L(UW13): + # cfi_def_cfa_offset(closure_FS + 4) + + FFI_CLOSURE_SAVE_REGS + FFI_CLOSURE_COPY_TRAMP_DATA + + /* Entry point from preceeding Go closures. */ +L(do_closure_i386): + + FFI_CLOSURE_PREP_CALL + FFI_CLOSURE_CALL_INNER(14) + FFI_CLOSURE_MASK_AND_JUMP(2, 15) + + .balign 8 +L(load_table2): +E(L(load_table2), X86_RET_FLOAT) + flds closure_CF(%esp) + jmp L(e2) +E(L(load_table2), X86_RET_DOUBLE) + fldl closure_CF(%esp) + jmp L(e2) +E(L(load_table2), X86_RET_LDOUBLE) + fldt closure_CF(%esp) + jmp L(e2) +E(L(load_table2), X86_RET_SINT8) + movsbl %al, %eax + jmp L(e2) +E(L(load_table2), X86_RET_SINT16) + movswl %ax, %eax + jmp L(e2) +E(L(load_table2), X86_RET_UINT8) + movzbl %al, %eax + jmp L(e2) +E(L(load_table2), X86_RET_UINT16) + movzwl %ax, %eax + jmp L(e2) +E(L(load_table2), X86_RET_INT64) + movl closure_CF+4(%esp), %edx + jmp L(e2) +E(L(load_table2), X86_RET_INT32) + nop + /* fallthru */ +E(L(load_table2), X86_RET_VOID) +L(e2): + addl $closure_FS, %esp +L(UW16): + # cfi_adjust_cfa_offset(-closure_FS) + ret +L(UW17): + # cfi_adjust_cfa_offset(closure_FS) +E(L(load_table2), X86_RET_STRUCTPOP) + addl $closure_FS, %esp +L(UW18): + # cfi_adjust_cfa_offset(-closure_FS) + ret $4 +L(UW19): + # cfi_adjust_cfa_offset(closure_FS) +E(L(load_table2), X86_RET_STRUCTARG) + jmp L(e2) +E(L(load_table2), X86_RET_STRUCT_1B) + movzbl %al, %eax + jmp L(e2) +E(L(load_table2), X86_RET_STRUCT_2B) + movzwl %ax, %eax + jmp L(e2) + + /* Fill out the table so that bad values are predictable. */ +E(L(load_table2), X86_RET_UNUSED14) + ud2 +E(L(load_table2), X86_RET_UNUSED15) + ud2 + +L(UW20): + # cfi_endproc +ENDF(C(ffi_closure_i386)) + + .balign 16 + .globl C(ffi_go_closure_STDCALL) + FFI_HIDDEN(C(ffi_go_closure_STDCALL)) +C(ffi_go_closure_STDCALL): +L(UW21): + # cfi_startproc + subl $closure_FS, %esp +L(UW22): + # cfi_def_cfa_offset(closure_FS + 4) + FFI_CLOSURE_SAVE_REGS + movl 4(%ecx), %edx /* copy cif */ + movl 8(%ecx), %eax /* copy fun */ + movl %edx, closure_CF+28(%esp) + movl %eax, closure_CF+32(%esp) + movl %ecx, closure_CF+36(%esp) /* closure is user_data */ + jmp L(do_closure_STDCALL) +L(UW23): + # cfi_endproc +ENDF(C(ffi_go_closure_STDCALL)) + +/* For REGISTER, we have no available parameter registers, and so we + enter here having pushed the closure onto the stack. */ + + .balign 16 + .globl C(ffi_closure_REGISTER) + FFI_HIDDEN(C(ffi_closure_REGISTER)) +C(ffi_closure_REGISTER): +L(UW24): + # cfi_startproc + # cfi_def_cfa(%esp, 8) + # cfi_offset(%eip, -8) + subl $closure_FS-4, %esp +L(UW25): + # cfi_def_cfa_offset(closure_FS + 4) + FFI_CLOSURE_SAVE_REGS + movl closure_FS-4(%esp), %ecx /* load retaddr */ + movl closure_FS(%esp), %eax /* load closure */ + movl %ecx, closure_FS(%esp) /* move retaddr */ + jmp L(do_closure_REGISTER) +L(UW26): + # cfi_endproc +ENDF(C(ffi_closure_REGISTER)) + +/* For STDCALL (and others), we need to pop N bytes of arguments off + the stack following the closure. The amount needing to be popped + is returned to us from ffi_closure_inner. */ + + .balign 16 + .globl C(ffi_closure_STDCALL) + FFI_HIDDEN(C(ffi_closure_STDCALL)) +C(ffi_closure_STDCALL): +L(UW27): + # cfi_startproc + subl $closure_FS, %esp +L(UW28): + # cfi_def_cfa_offset(closure_FS + 4) + + FFI_CLOSURE_SAVE_REGS + + /* Entry point from ffi_closure_REGISTER. */ +L(do_closure_REGISTER): + + FFI_CLOSURE_COPY_TRAMP_DATA + + /* Entry point from preceeding Go closure. */ +L(do_closure_STDCALL): + + FFI_CLOSURE_PREP_CALL + FFI_CLOSURE_CALL_INNER(29) + + movl %eax, %ecx + shrl $X86_RET_POP_SHIFT, %ecx /* isolate pop count */ + leal closure_FS(%esp, %ecx), %ecx /* compute popped esp */ + movl closure_FS(%esp), %edx /* move return address */ + movl %edx, (%ecx) + + /* From this point on, the value of %esp upon return is %ecx+4, + and we've copied the return address to %ecx to make return easy. + There's no point in representing this in the unwind info, as + there is always a window between the mov and the ret which + will be wrong from one point of view or another. */ + + FFI_CLOSURE_MASK_AND_JUMP(3, 30) + + .balign 8 +L(load_table3): +E(L(load_table3), X86_RET_FLOAT) + flds closure_CF(%esp) + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_DOUBLE) + fldl closure_CF(%esp) + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_LDOUBLE) + fldt closure_CF(%esp) + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_SINT8) + movsbl %al, %eax + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_SINT16) + movswl %ax, %eax + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_UINT8) + movzbl %al, %eax + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_UINT16) + movzwl %ax, %eax + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_INT64) + movl closure_CF+4(%esp), %edx + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_INT32) + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_VOID) + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_STRUCTPOP) + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_STRUCTARG) + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_STRUCT_1B) + movzbl %al, %eax + movl %ecx, %esp + ret +E(L(load_table3), X86_RET_STRUCT_2B) + movzwl %ax, %eax + movl %ecx, %esp + ret + + /* Fill out the table so that bad values are predictable. */ +E(L(load_table3), X86_RET_UNUSED14) + ud2 +E(L(load_table3), X86_RET_UNUSED15) + ud2 + +L(UW31): + # cfi_endproc +ENDF(C(ffi_closure_STDCALL)) + +#if !FFI_NO_RAW_API + +#define raw_closure_S_FS (16+16+12) + + .balign 16 + .globl C(ffi_closure_raw_SYSV) + FFI_HIDDEN(C(ffi_closure_raw_SYSV)) +C(ffi_closure_raw_SYSV): +L(UW32): + # cfi_startproc + subl $raw_closure_S_FS, %esp +L(UW33): + # cfi_def_cfa_offset(raw_closure_S_FS + 4) + movl %ebx, raw_closure_S_FS-4(%esp) +L(UW34): + # cfi_rel_offset(%ebx, raw_closure_S_FS-4) + + movl FFI_TRAMPOLINE_SIZE+8(%eax), %edx /* load cl->user_data */ + movl %edx, 12(%esp) + leal raw_closure_S_FS+4(%esp), %edx /* load raw_args */ + movl %edx, 8(%esp) + leal 16(%esp), %edx /* load &res */ + movl %edx, 4(%esp) + movl FFI_TRAMPOLINE_SIZE(%eax), %ebx /* load cl->cif */ + movl %ebx, (%esp) + call *FFI_TRAMPOLINE_SIZE+4(%eax) /* call cl->fun */ + + movl 20(%ebx), %eax /* load cif->flags */ + andl $X86_RET_TYPE_MASK, %eax +#ifdef __PIC__ + call C(__x86.get_pc_thunk.bx) +L(pc4): + leal L(load_table4)-L(pc4)(%ebx, %eax, 8), %ecx +#else + leal L(load_table4)(,%eax, 8), %ecx +#endif + movl raw_closure_S_FS-4(%esp), %ebx +L(UW35): + # cfi_restore(%ebx) + movl 16(%esp), %eax /* Optimistic load */ + jmp *%ecx + + .balign 8 +L(load_table4): +E(L(load_table4), X86_RET_FLOAT) + flds 16(%esp) + jmp L(e4) +E(L(load_table4), X86_RET_DOUBLE) + fldl 16(%esp) + jmp L(e4) +E(L(load_table4), X86_RET_LDOUBLE) + fldt 16(%esp) + jmp L(e4) +E(L(load_table4), X86_RET_SINT8) + movsbl %al, %eax + jmp L(e4) +E(L(load_table4), X86_RET_SINT16) + movswl %ax, %eax + jmp L(e4) +E(L(load_table4), X86_RET_UINT8) + movzbl %al, %eax + jmp L(e4) +E(L(load_table4), X86_RET_UINT16) + movzwl %ax, %eax + jmp L(e4) +E(L(load_table4), X86_RET_INT64) + movl 16+4(%esp), %edx + jmp L(e4) +E(L(load_table4), X86_RET_INT32) + nop + /* fallthru */ +E(L(load_table4), X86_RET_VOID) +L(e4): + addl $raw_closure_S_FS, %esp +L(UW36): + # cfi_adjust_cfa_offset(-raw_closure_S_FS) + ret +L(UW37): + # cfi_adjust_cfa_offset(raw_closure_S_FS) +E(L(load_table4), X86_RET_STRUCTPOP) + addl $raw_closure_S_FS, %esp +L(UW38): + # cfi_adjust_cfa_offset(-raw_closure_S_FS) + ret $4 +L(UW39): + # cfi_adjust_cfa_offset(raw_closure_S_FS) +E(L(load_table4), X86_RET_STRUCTARG) + jmp L(e4) +E(L(load_table4), X86_RET_STRUCT_1B) + movzbl %al, %eax + jmp L(e4) +E(L(load_table4), X86_RET_STRUCT_2B) + movzwl %ax, %eax + jmp L(e4) + + /* Fill out the table so that bad values are predictable. */ +E(L(load_table4), X86_RET_UNUSED14) + ud2 +E(L(load_table4), X86_RET_UNUSED15) + ud2 + +L(UW40): + # cfi_endproc +ENDF(C(ffi_closure_raw_SYSV)) + +#define raw_closure_T_FS (16+16+8) + + .balign 16 + .globl C(ffi_closure_raw_THISCALL) + FFI_HIDDEN(C(ffi_closure_raw_THISCALL)) +C(ffi_closure_raw_THISCALL): +L(UW41): + # cfi_startproc + /* Rearrange the stack such that %ecx is the first argument. + This means moving the return address. */ + popl %edx +L(UW42): + # cfi_def_cfa_offset(0) + # cfi_register(%eip, %edx) + pushl %ecx +L(UW43): + # cfi_adjust_cfa_offset(4) + pushl %edx +L(UW44): + # cfi_adjust_cfa_offset(4) + # cfi_rel_offset(%eip, 0) + subl $raw_closure_T_FS, %esp +L(UW45): + # cfi_adjust_cfa_offset(raw_closure_T_FS) + movl %ebx, raw_closure_T_FS-4(%esp) +L(UW46): + # cfi_rel_offset(%ebx, raw_closure_T_FS-4) + + movl FFI_TRAMPOLINE_SIZE+8(%eax), %edx /* load cl->user_data */ + movl %edx, 12(%esp) + leal raw_closure_T_FS+4(%esp), %edx /* load raw_args */ + movl %edx, 8(%esp) + leal 16(%esp), %edx /* load &res */ + movl %edx, 4(%esp) + movl FFI_TRAMPOLINE_SIZE(%eax), %ebx /* load cl->cif */ + movl %ebx, (%esp) + call *FFI_TRAMPOLINE_SIZE+4(%eax) /* call cl->fun */ + + movl 20(%ebx), %eax /* load cif->flags */ + andl $X86_RET_TYPE_MASK, %eax +#ifdef __PIC__ + call C(__x86.get_pc_thunk.bx) +L(pc5): + leal L(load_table5)-L(pc5)(%ebx, %eax, 8), %ecx +#else + leal L(load_table5)(,%eax, 8), %ecx +#endif + movl raw_closure_T_FS-4(%esp), %ebx +L(UW47): + # cfi_restore(%ebx) + movl 16(%esp), %eax /* Optimistic load */ + jmp *%ecx + + .balign 8 +L(load_table5): +E(L(load_table5), X86_RET_FLOAT) + flds 16(%esp) + jmp L(e5) +E(L(load_table5), X86_RET_DOUBLE) + fldl 16(%esp) + jmp L(e5) +E(L(load_table5), X86_RET_LDOUBLE) + fldt 16(%esp) + jmp L(e5) +E(L(load_table5), X86_RET_SINT8) + movsbl %al, %eax + jmp L(e5) +E(L(load_table5), X86_RET_SINT16) + movswl %ax, %eax + jmp L(e5) +E(L(load_table5), X86_RET_UINT8) + movzbl %al, %eax + jmp L(e5) +E(L(load_table5), X86_RET_UINT16) + movzwl %ax, %eax + jmp L(e5) +E(L(load_table5), X86_RET_INT64) + movl 16+4(%esp), %edx + jmp L(e5) +E(L(load_table5), X86_RET_INT32) + nop + /* fallthru */ +E(L(load_table5), X86_RET_VOID) +L(e5): + addl $raw_closure_T_FS, %esp +L(UW48): + # cfi_adjust_cfa_offset(-raw_closure_T_FS) + /* Remove the extra %ecx argument we pushed. */ + ret $4 +L(UW49): + # cfi_adjust_cfa_offset(raw_closure_T_FS) +E(L(load_table5), X86_RET_STRUCTPOP) + addl $raw_closure_T_FS, %esp +L(UW50): + # cfi_adjust_cfa_offset(-raw_closure_T_FS) + ret $8 +L(UW51): + # cfi_adjust_cfa_offset(raw_closure_T_FS) +E(L(load_table5), X86_RET_STRUCTARG) + jmp L(e5) +E(L(load_table5), X86_RET_STRUCT_1B) + movzbl %al, %eax + jmp L(e5) +E(L(load_table5), X86_RET_STRUCT_2B) + movzwl %ax, %eax + jmp L(e5) + + /* Fill out the table so that bad values are predictable. */ +E(L(load_table5), X86_RET_UNUSED14) + ud2 +E(L(load_table5), X86_RET_UNUSED15) + ud2 + +L(UW52): + # cfi_endproc +ENDF(C(ffi_closure_raw_THISCALL)) + +#endif /* !FFI_NO_RAW_API */ + +#ifdef X86_DARWIN +# define COMDAT(X) \ + .section __TEXT,__textcoal_nt,coalesced,pure_instructions; \ + .weak_definition X; \ + .private_extern X +#elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__)) +# define COMDAT(X) \ + .section .text.X,"axG",@progbits,X,comdat; \ + .globl X; \ + FFI_HIDDEN(X) +#else +# define COMDAT(X) +#endif + +#if defined(__PIC__) + COMDAT(C(__x86.get_pc_thunk.bx)) +C(__x86.get_pc_thunk.bx): + movl (%esp), %ebx + ret +ENDF(C(__x86.get_pc_thunk.bx)) +# if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE + COMDAT(C(__x86.get_pc_thunk.dx)) +C(__x86.get_pc_thunk.dx): + movl (%esp), %edx + ret +ENDF(C(__x86.get_pc_thunk.dx)) +#endif /* DARWIN || HIDDEN */ +#endif /* __PIC__ */ + +/* Sadly, OSX cctools-as doesn't understand .cfi directives at all. */ + +#ifdef __APPLE__ +.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EHFrame0: +#elif defined(X86_WIN32) +.section .eh_frame,"r" +#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE) +.section .eh_frame,EH_FRAME_FLAGS,@unwind +#else +.section .eh_frame,EH_FRAME_FLAGS,@progbits +#endif + +#ifdef HAVE_AS_X86_PCREL +# define PCREL(X) X - . +#else +# define PCREL(X) X@rel +#endif + +/* Simplify advancing between labels. Assume DW_CFA_advance_loc1 fits. */ +#define ADV(N, P) .byte 2, L(N)-L(P) + + .balign 4 +L(CIE): + .set L(set0),L(ECIE)-L(SCIE) + .long L(set0) /* CIE Length */ +L(SCIE): + .long 0 /* CIE Identifier Tag */ + .byte 1 /* CIE Version */ + .ascii "zR\0" /* CIE Augmentation */ + .byte 1 /* CIE Code Alignment Factor */ + .byte 0x7c /* CIE Data Alignment Factor */ + .byte 0x8 /* CIE RA Column */ + .byte 1 /* Augmentation size */ + .byte 0x1b /* FDE Encoding (pcrel sdata4) */ + .byte 0xc, 4, 4 /* DW_CFA_def_cfa, %esp offset 4 */ + .byte 0x80+8, 1 /* DW_CFA_offset, %eip offset 1*-4 */ + .balign 4 +L(ECIE): + + .set L(set1),L(EFDE1)-L(SFDE1) + .long L(set1) /* FDE Length */ +L(SFDE1): + .long L(SFDE1)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW0)) /* Initial location */ + .long L(UW5)-L(UW0) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW1, UW0) + .byte 0xc, 5, 8 /* DW_CFA_def_cfa, %ebp 8 */ + .byte 0x80+5, 2 /* DW_CFA_offset, %ebp 2*-4 */ + ADV(UW2, UW1) + .byte 0x80+3, 0 /* DW_CFA_offset, %ebx 0*-4 */ + ADV(UW3, UW2) + .byte 0xa /* DW_CFA_remember_state */ + .byte 0xc, 4, 4 /* DW_CFA_def_cfa, %esp 4 */ + .byte 0xc0+3 /* DW_CFA_restore, %ebx */ + .byte 0xc0+5 /* DW_CFA_restore, %ebp */ + ADV(UW4, UW3) + .byte 0xb /* DW_CFA_restore_state */ + .balign 4 +L(EFDE1): + + .set L(set2),L(EFDE2)-L(SFDE2) + .long L(set2) /* FDE Length */ +L(SFDE2): + .long L(SFDE2)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW6)) /* Initial location */ + .long L(UW8)-L(UW6) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW7, UW6) + .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */ + .balign 4 +L(EFDE2): + + .set L(set3),L(EFDE3)-L(SFDE3) + .long L(set3) /* FDE Length */ +L(SFDE3): + .long L(SFDE3)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW9)) /* Initial location */ + .long L(UW11)-L(UW9) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW10, UW9) + .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */ + .balign 4 +L(EFDE3): + + .set L(set4),L(EFDE4)-L(SFDE4) + .long L(set4) /* FDE Length */ +L(SFDE4): + .long L(SFDE4)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW12)) /* Initial location */ + .long L(UW20)-L(UW12) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW13, UW12) + .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */ +#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX + ADV(UW14, UW13) + .byte 0x80+3, (40-(closure_FS+4))/-4 /* DW_CFA_offset %ebx */ + ADV(UW15, UW14) + .byte 0xc0+3 /* DW_CFA_restore %ebx */ + ADV(UW16, UW15) +#else + ADV(UW16, UW13) +#endif + .byte 0xe, 4 /* DW_CFA_def_cfa_offset */ + ADV(UW17, UW16) + .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */ + ADV(UW18, UW17) + .byte 0xe, 4 /* DW_CFA_def_cfa_offset */ + ADV(UW19, UW18) + .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */ + .balign 4 +L(EFDE4): + + .set L(set5),L(EFDE5)-L(SFDE5) + .long L(set5) /* FDE Length */ +L(SFDE5): + .long L(SFDE5)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW21)) /* Initial location */ + .long L(UW23)-L(UW21) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW22, UW21) + .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */ + .balign 4 +L(EFDE5): + + .set L(set6),L(EFDE6)-L(SFDE6) + .long L(set6) /* FDE Length */ +L(SFDE6): + .long L(SFDE6)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW24)) /* Initial location */ + .long L(UW26)-L(UW24) /* Address range */ + .byte 0 /* Augmentation size */ + .byte 0xe, 8 /* DW_CFA_def_cfa_offset */ + .byte 0x80+8, 2 /* DW_CFA_offset %eip, 2*-4 */ + ADV(UW25, UW24) + .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */ + .balign 4 +L(EFDE6): + + .set L(set7),L(EFDE7)-L(SFDE7) + .long L(set7) /* FDE Length */ +L(SFDE7): + .long L(SFDE7)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW27)) /* Initial location */ + .long L(UW31)-L(UW27) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW28, UW27) + .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */ +#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX + ADV(UW29, UW28) + .byte 0x80+3, (40-(closure_FS+4))/-4 /* DW_CFA_offset %ebx */ + ADV(UW30, UW29) + .byte 0xc0+3 /* DW_CFA_restore %ebx */ +#endif + .balign 4 +L(EFDE7): + +#if !FFI_NO_RAW_API + .set L(set8),L(EFDE8)-L(SFDE8) + .long L(set8) /* FDE Length */ +L(SFDE8): + .long L(SFDE8)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW32)) /* Initial location */ + .long L(UW40)-L(UW32) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW33, UW32) + .byte 0xe, raw_closure_S_FS+4 /* DW_CFA_def_cfa_offset */ + ADV(UW34, UW33) + .byte 0x80+3, 2 /* DW_CFA_offset %ebx 2*-4 */ + ADV(UW35, UW34) + .byte 0xc0+3 /* DW_CFA_restore %ebx */ + ADV(UW36, UW35) + .byte 0xe, 4 /* DW_CFA_def_cfa_offset */ + ADV(UW37, UW36) + .byte 0xe, raw_closure_S_FS+4 /* DW_CFA_def_cfa_offset */ + ADV(UW38, UW37) + .byte 0xe, 4 /* DW_CFA_def_cfa_offset */ + ADV(UW39, UW38) + .byte 0xe, raw_closure_S_FS+4 /* DW_CFA_def_cfa_offset */ + .balign 4 +L(EFDE8): + + .set L(set9),L(EFDE9)-L(SFDE9) + .long L(set9) /* FDE Length */ +L(SFDE9): + .long L(SFDE9)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW41)) /* Initial location */ + .long L(UW52)-L(UW41) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW42, UW41) + .byte 0xe, 0 /* DW_CFA_def_cfa_offset */ + .byte 0x9, 8, 2 /* DW_CFA_register %eip, %edx */ + ADV(UW43, UW42) + .byte 0xe, 4 /* DW_CFA_def_cfa_offset */ + ADV(UW44, UW43) + .byte 0xe, 8 /* DW_CFA_def_cfa_offset */ + .byte 0x80+8, 2 /* DW_CFA_offset %eip 2*-4 */ + ADV(UW45, UW44) + .byte 0xe, raw_closure_T_FS+8 /* DW_CFA_def_cfa_offset */ + ADV(UW46, UW45) + .byte 0x80+3, 3 /* DW_CFA_offset %ebx 3*-4 */ + ADV(UW47, UW46) + .byte 0xc0+3 /* DW_CFA_restore %ebx */ + ADV(UW48, UW47) + .byte 0xe, 8 /* DW_CFA_def_cfa_offset */ + ADV(UW49, UW48) + .byte 0xe, raw_closure_T_FS+8 /* DW_CFA_def_cfa_offset */ + ADV(UW50, UW49) + .byte 0xe, 8 /* DW_CFA_def_cfa_offset */ + ADV(UW51, UW50) + .byte 0xe, raw_closure_T_FS+8 /* DW_CFA_def_cfa_offset */ + .balign 4 +L(EFDE9): +#endif /* !FFI_NO_RAW_API */ + +#endif /* ifndef __x86_64__ */ + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/x86/unix64.S b/circuitpython/lib/libffi/src/x86/unix64.S new file mode 100644 index 0000000..c83010c --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/unix64.S @@ -0,0 +1,546 @@ +/* ----------------------------------------------------------------------- + unix64.S - Copyright (c) 2013 The Written Word, Inc. + - Copyright (c) 2008 Red Hat, Inc + - Copyright (c) 2002 Bo Thorsen + + x86-64 Foreign Function Interface + + 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. + ----------------------------------------------------------------------- */ + +#ifdef __x86_64__ +#define LIBFFI_ASM +#include +#include +#include "internal64.h" + + .text + +#define C2(X, Y) X ## Y +#define C1(X, Y) C2(X, Y) +#ifdef __USER_LABEL_PREFIX__ +# define C(X) C1(__USER_LABEL_PREFIX__, X) +#else +# define C(X) X +#endif + +#ifdef __APPLE__ +# define L(X) C1(L, X) +#else +# define L(X) C1(.L, X) +#endif + +#ifdef __ELF__ +# define PLT(X) X@PLT +# define ENDF(X) .type X,@function; .size X, . - X +#else +# define PLT(X) X +# define ENDF(X) +#endif + +/* This macro allows the safe creation of jump tables without an + actual table. The entry points into the table are all 8 bytes. + The use of ORG asserts that we're at the correct location. */ +/* ??? The clang assembler doesn't handle .org with symbolic expressions. */ +#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__)) +# define E(BASE, X) .balign 8 +#else +# define E(BASE, X) .balign 8; .org BASE + X * 8 +#endif + +/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, + void *raddr, void (*fnaddr)(void)); + + Bit o trickiness here -- ARGS+BYTES is the base of the stack frame + for this function. This has been allocated by ffi_call. We also + deallocate some of the stack that has been alloca'd. */ + + .balign 8 + .globl C(ffi_call_unix64) + FFI_HIDDEN(C(ffi_call_unix64)) + +C(ffi_call_unix64): +L(UW0): + movq (%rsp), %r10 /* Load return address. */ + leaq (%rdi, %rsi), %rax /* Find local stack base. */ + movq %rdx, (%rax) /* Save flags. */ + movq %rcx, 8(%rax) /* Save raddr. */ + movq %rbp, 16(%rax) /* Save old frame pointer. */ + movq %r10, 24(%rax) /* Relocate return address. */ + movq %rax, %rbp /* Finalize local stack frame. */ + + /* New stack frame based off rbp. This is a itty bit of unwind + trickery in that the CFA *has* changed. There is no easy way + to describe it correctly on entry to the function. Fortunately, + it doesn't matter too much since at all points we can correctly + unwind back to ffi_call. Note that the location to which we + moved the return address is (the new) CFA-8, so from the + perspective of the unwind info, it hasn't moved. */ +L(UW1): + /* cfi_def_cfa(%rbp, 32) */ + /* cfi_rel_offset(%rbp, 16) */ + + movq %rdi, %r10 /* Save a copy of the register area. */ + movq %r8, %r11 /* Save a copy of the target fn. */ + movl %r9d, %eax /* Set number of SSE registers. */ + + /* Load up all argument registers. */ + movq (%r10), %rdi + movq 0x08(%r10), %rsi + movq 0x10(%r10), %rdx + movq 0x18(%r10), %rcx + movq 0x20(%r10), %r8 + movq 0x28(%r10), %r9 + movl 0xb0(%r10), %eax + testl %eax, %eax + jnz L(load_sse) +L(ret_from_load_sse): + + /* Deallocate the reg arg area, except for r10, then load via pop. */ + leaq 0xb8(%r10), %rsp + popq %r10 + + /* Call the user function. */ + call *%r11 + + /* Deallocate stack arg area; local stack frame in redzone. */ + leaq 24(%rbp), %rsp + + movq 0(%rbp), %rcx /* Reload flags. */ + movq 8(%rbp), %rdi /* Reload raddr. */ + movq 16(%rbp), %rbp /* Reload old frame pointer. */ +L(UW2): + /* cfi_remember_state */ + /* cfi_def_cfa(%rsp, 8) */ + /* cfi_restore(%rbp) */ + + /* The first byte of the flags contains the FFI_TYPE. */ + cmpb $UNIX64_RET_LAST, %cl + movzbl %cl, %r10d + leaq L(store_table)(%rip), %r11 + ja L(sa) + leaq (%r11, %r10, 8), %r10 + + /* Prep for the structure cases: scratch area in redzone. */ + leaq -20(%rsp), %rsi + jmp *%r10 + + .balign 8 +L(store_table): +E(L(store_table), UNIX64_RET_VOID) + ret +E(L(store_table), UNIX64_RET_UINT8) + movzbl %al, %eax + movq %rax, (%rdi) + ret +E(L(store_table), UNIX64_RET_UINT16) + movzwl %ax, %eax + movq %rax, (%rdi) + ret +E(L(store_table), UNIX64_RET_UINT32) + movl %eax, %eax + movq %rax, (%rdi) + ret +E(L(store_table), UNIX64_RET_SINT8) + movsbq %al, %rax + movq %rax, (%rdi) + ret +E(L(store_table), UNIX64_RET_SINT16) + movswq %ax, %rax + movq %rax, (%rdi) + ret +E(L(store_table), UNIX64_RET_SINT32) + cltq + movq %rax, (%rdi) + ret +E(L(store_table), UNIX64_RET_INT64) + movq %rax, (%rdi) + ret +E(L(store_table), UNIX64_RET_XMM32) + movd %xmm0, (%rdi) + ret +E(L(store_table), UNIX64_RET_XMM64) + movq %xmm0, (%rdi) + ret +E(L(store_table), UNIX64_RET_X87) + fstpt (%rdi) + ret +E(L(store_table), UNIX64_RET_X87_2) + fstpt (%rdi) + fstpt 16(%rdi) + ret +E(L(store_table), UNIX64_RET_ST_XMM0_RAX) + movq %rax, 8(%rsi) + jmp L(s3) +E(L(store_table), UNIX64_RET_ST_RAX_XMM0) + movq %xmm0, 8(%rsi) + jmp L(s2) +E(L(store_table), UNIX64_RET_ST_XMM0_XMM1) + movq %xmm1, 8(%rsi) + jmp L(s3) +E(L(store_table), UNIX64_RET_ST_RAX_RDX) + movq %rdx, 8(%rsi) +L(s2): + movq %rax, (%rsi) + shrl $UNIX64_SIZE_SHIFT, %ecx + rep movsb + ret + .balign 8 +L(s3): + movq %xmm0, (%rsi) + shrl $UNIX64_SIZE_SHIFT, %ecx + rep movsb + ret + +L(sa): call PLT(C(abort)) + + /* Many times we can avoid loading any SSE registers at all. + It's not worth an indirect jump to load the exact set of + SSE registers needed; zero or all is a good compromise. */ + .balign 2 +L(UW3): + /* cfi_restore_state */ +L(load_sse): + movdqa 0x30(%r10), %xmm0 + movdqa 0x40(%r10), %xmm1 + movdqa 0x50(%r10), %xmm2 + movdqa 0x60(%r10), %xmm3 + movdqa 0x70(%r10), %xmm4 + movdqa 0x80(%r10), %xmm5 + movdqa 0x90(%r10), %xmm6 + movdqa 0xa0(%r10), %xmm7 + jmp L(ret_from_load_sse) + +L(UW4): +ENDF(C(ffi_call_unix64)) + +/* 6 general registers, 8 vector registers, + 32 bytes of rvalue, 8 bytes of alignment. */ +#define ffi_closure_OFS_G 0 +#define ffi_closure_OFS_V (6*8) +#define ffi_closure_OFS_RVALUE (ffi_closure_OFS_V + 8*16) +#define ffi_closure_FS (ffi_closure_OFS_RVALUE + 32 + 8) + +/* The location of rvalue within the red zone after deallocating the frame. */ +#define ffi_closure_RED_RVALUE (ffi_closure_OFS_RVALUE - ffi_closure_FS) + + .balign 2 + .globl C(ffi_closure_unix64_sse) + FFI_HIDDEN(C(ffi_closure_unix64_sse)) + +C(ffi_closure_unix64_sse): +L(UW5): + subq $ffi_closure_FS, %rsp +L(UW6): + /* cfi_adjust_cfa_offset(ffi_closure_FS) */ + + movdqa %xmm0, ffi_closure_OFS_V+0x00(%rsp) + movdqa %xmm1, ffi_closure_OFS_V+0x10(%rsp) + movdqa %xmm2, ffi_closure_OFS_V+0x20(%rsp) + movdqa %xmm3, ffi_closure_OFS_V+0x30(%rsp) + movdqa %xmm4, ffi_closure_OFS_V+0x40(%rsp) + movdqa %xmm5, ffi_closure_OFS_V+0x50(%rsp) + movdqa %xmm6, ffi_closure_OFS_V+0x60(%rsp) + movdqa %xmm7, ffi_closure_OFS_V+0x70(%rsp) + jmp L(sse_entry1) + +L(UW7): +ENDF(C(ffi_closure_unix64_sse)) + + .balign 2 + .globl C(ffi_closure_unix64) + FFI_HIDDEN(C(ffi_closure_unix64)) + +C(ffi_closure_unix64): +L(UW8): + subq $ffi_closure_FS, %rsp +L(UW9): + /* cfi_adjust_cfa_offset(ffi_closure_FS) */ +L(sse_entry1): + movq %rdi, ffi_closure_OFS_G+0x00(%rsp) + movq %rsi, ffi_closure_OFS_G+0x08(%rsp) + movq %rdx, ffi_closure_OFS_G+0x10(%rsp) + movq %rcx, ffi_closure_OFS_G+0x18(%rsp) + movq %r8, ffi_closure_OFS_G+0x20(%rsp) + movq %r9, ffi_closure_OFS_G+0x28(%rsp) + +#ifdef __ILP32__ + movl FFI_TRAMPOLINE_SIZE(%r10), %edi /* Load cif */ + movl FFI_TRAMPOLINE_SIZE+4(%r10), %esi /* Load fun */ + movl FFI_TRAMPOLINE_SIZE+8(%r10), %edx /* Load user_data */ +#else + movq FFI_TRAMPOLINE_SIZE(%r10), %rdi /* Load cif */ + movq FFI_TRAMPOLINE_SIZE+8(%r10), %rsi /* Load fun */ + movq FFI_TRAMPOLINE_SIZE+16(%r10), %rdx /* Load user_data */ +#endif +L(do_closure): + leaq ffi_closure_OFS_RVALUE(%rsp), %rcx /* Load rvalue */ + movq %rsp, %r8 /* Load reg_args */ + leaq ffi_closure_FS+8(%rsp), %r9 /* Load argp */ + call C(ffi_closure_unix64_inner) + + /* Deallocate stack frame early; return value is now in redzone. */ + addq $ffi_closure_FS, %rsp +L(UW10): + /* cfi_adjust_cfa_offset(-ffi_closure_FS) */ + + /* The first byte of the return value contains the FFI_TYPE. */ + cmpb $UNIX64_RET_LAST, %al + movzbl %al, %r10d + leaq L(load_table)(%rip), %r11 + ja L(la) + leaq (%r11, %r10, 8), %r10 + leaq ffi_closure_RED_RVALUE(%rsp), %rsi + jmp *%r10 + + .balign 8 +L(load_table): +E(L(load_table), UNIX64_RET_VOID) + ret +E(L(load_table), UNIX64_RET_UINT8) + movzbl (%rsi), %eax + ret +E(L(load_table), UNIX64_RET_UINT16) + movzwl (%rsi), %eax + ret +E(L(load_table), UNIX64_RET_UINT32) + movl (%rsi), %eax + ret +E(L(load_table), UNIX64_RET_SINT8) + movsbl (%rsi), %eax + ret +E(L(load_table), UNIX64_RET_SINT16) + movswl (%rsi), %eax + ret +E(L(load_table), UNIX64_RET_SINT32) + movl (%rsi), %eax + ret +E(L(load_table), UNIX64_RET_INT64) + movq (%rsi), %rax + ret +E(L(load_table), UNIX64_RET_XMM32) + movd (%rsi), %xmm0 + ret +E(L(load_table), UNIX64_RET_XMM64) + movq (%rsi), %xmm0 + ret +E(L(load_table), UNIX64_RET_X87) + fldt (%rsi) + ret +E(L(load_table), UNIX64_RET_X87_2) + fldt 16(%rsi) + fldt (%rsi) + ret +E(L(load_table), UNIX64_RET_ST_XMM0_RAX) + movq 8(%rsi), %rax + jmp L(l3) +E(L(load_table), UNIX64_RET_ST_RAX_XMM0) + movq 8(%rsi), %xmm0 + jmp L(l2) +E(L(load_table), UNIX64_RET_ST_XMM0_XMM1) + movq 8(%rsi), %xmm1 + jmp L(l3) +E(L(load_table), UNIX64_RET_ST_RAX_RDX) + movq 8(%rsi), %rdx +L(l2): + movq (%rsi), %rax + ret + .balign 8 +L(l3): + movq (%rsi), %xmm0 + ret + +L(la): call PLT(C(abort)) + +L(UW11): +ENDF(C(ffi_closure_unix64)) + + .balign 2 + .globl C(ffi_go_closure_unix64_sse) + FFI_HIDDEN(C(ffi_go_closure_unix64_sse)) + +C(ffi_go_closure_unix64_sse): +L(UW12): + subq $ffi_closure_FS, %rsp +L(UW13): + /* cfi_adjust_cfa_offset(ffi_closure_FS) */ + + movdqa %xmm0, ffi_closure_OFS_V+0x00(%rsp) + movdqa %xmm1, ffi_closure_OFS_V+0x10(%rsp) + movdqa %xmm2, ffi_closure_OFS_V+0x20(%rsp) + movdqa %xmm3, ffi_closure_OFS_V+0x30(%rsp) + movdqa %xmm4, ffi_closure_OFS_V+0x40(%rsp) + movdqa %xmm5, ffi_closure_OFS_V+0x50(%rsp) + movdqa %xmm6, ffi_closure_OFS_V+0x60(%rsp) + movdqa %xmm7, ffi_closure_OFS_V+0x70(%rsp) + jmp L(sse_entry2) + +L(UW14): +ENDF(C(ffi_go_closure_unix64_sse)) + + .balign 2 + .globl C(ffi_go_closure_unix64) + FFI_HIDDEN(C(ffi_go_closure_unix64)) + +C(ffi_go_closure_unix64): +L(UW15): + subq $ffi_closure_FS, %rsp +L(UW16): + /* cfi_adjust_cfa_offset(ffi_closure_FS) */ +L(sse_entry2): + movq %rdi, ffi_closure_OFS_G+0x00(%rsp) + movq %rsi, ffi_closure_OFS_G+0x08(%rsp) + movq %rdx, ffi_closure_OFS_G+0x10(%rsp) + movq %rcx, ffi_closure_OFS_G+0x18(%rsp) + movq %r8, ffi_closure_OFS_G+0x20(%rsp) + movq %r9, ffi_closure_OFS_G+0x28(%rsp) + +#ifdef __ILP32__ + movl 4(%r10), %edi /* Load cif */ + movl 8(%r10), %esi /* Load fun */ + movl %r10d, %edx /* Load closure (user_data) */ +#else + movq 8(%r10), %rdi /* Load cif */ + movq 16(%r10), %rsi /* Load fun */ + movq %r10, %rdx /* Load closure (user_data) */ +#endif + jmp L(do_closure) + +L(UW17): +ENDF(C(ffi_go_closure_unix64)) + +/* Sadly, OSX cctools-as doesn't understand .cfi directives at all. */ + +#ifdef __APPLE__ +.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EHFrame0: +#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE) +.section .eh_frame,"a",@unwind +#else +.section .eh_frame,"a",@progbits +#endif + +#ifdef HAVE_AS_X86_PCREL +# define PCREL(X) X - . +#else +# define PCREL(X) X@rel +#endif + +/* Simplify advancing between labels. Assume DW_CFA_advance_loc1 fits. */ +#define ADV(N, P) .byte 2, L(N)-L(P) + + .balign 8 +L(CIE): + .set L(set0),L(ECIE)-L(SCIE) + .long L(set0) /* CIE Length */ +L(SCIE): + .long 0 /* CIE Identifier Tag */ + .byte 1 /* CIE Version */ + .ascii "zR\0" /* CIE Augmentation */ + .byte 1 /* CIE Code Alignment Factor */ + .byte 0x78 /* CIE Data Alignment Factor */ + .byte 0x10 /* CIE RA Column */ + .byte 1 /* Augmentation size */ + .byte 0x1b /* FDE Encoding (pcrel sdata4) */ + .byte 0xc, 7, 8 /* DW_CFA_def_cfa, %rsp offset 8 */ + .byte 0x80+16, 1 /* DW_CFA_offset, %rip offset 1*-8 */ + .balign 8 +L(ECIE): + + .set L(set1),L(EFDE1)-L(SFDE1) + .long L(set1) /* FDE Length */ +L(SFDE1): + .long L(SFDE1)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW0)) /* Initial location */ + .long L(UW4)-L(UW0) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW1, UW0) + .byte 0xc, 6, 32 /* DW_CFA_def_cfa, %rbp 32 */ + .byte 0x80+6, 2 /* DW_CFA_offset, %rbp 2*-8 */ + ADV(UW2, UW1) + .byte 0xa /* DW_CFA_remember_state */ + .byte 0xc, 7, 8 /* DW_CFA_def_cfa, %rsp 8 */ + .byte 0xc0+6 /* DW_CFA_restore, %rbp */ + ADV(UW3, UW2) + .byte 0xb /* DW_CFA_restore_state */ + .balign 8 +L(EFDE1): + + .set L(set2),L(EFDE2)-L(SFDE2) + .long L(set2) /* FDE Length */ +L(SFDE2): + .long L(SFDE2)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW5)) /* Initial location */ + .long L(UW7)-L(UW5) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW6, UW5) + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */ + .balign 8 +L(EFDE2): + + .set L(set3),L(EFDE3)-L(SFDE3) + .long L(set3) /* FDE Length */ +L(SFDE3): + .long L(SFDE3)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW8)) /* Initial location */ + .long L(UW11)-L(UW8) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW9, UW8) + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */ + ADV(UW10, UW9) + .byte 0xe, 8 /* DW_CFA_def_cfa_offset 8 */ +L(EFDE3): + + .set L(set4),L(EFDE4)-L(SFDE4) + .long L(set4) /* FDE Length */ +L(SFDE4): + .long L(SFDE4)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW12)) /* Initial location */ + .long L(UW14)-L(UW12) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW13, UW12) + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */ + .balign 8 +L(EFDE4): + + .set L(set5),L(EFDE5)-L(SFDE5) + .long L(set5) /* FDE Length */ +L(SFDE5): + .long L(SFDE5)-L(CIE) /* FDE CIE offset */ + .long PCREL(L(UW15)) /* Initial location */ + .long L(UW17)-L(UW15) /* Address range */ + .byte 0 /* Augmentation size */ + ADV(UW16, UW15) + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */ + .balign 8 +L(EFDE5): +#ifdef __APPLE__ + .subsections_via_symbols +#endif + +#endif /* __x86_64__ */ +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/circuitpython/lib/libffi/src/x86/win64.S b/circuitpython/lib/libffi/src/x86/win64.S new file mode 100644 index 0000000..a5a20b6 --- /dev/null +++ b/circuitpython/lib/libffi/src/x86/win64.S @@ -0,0 +1,219 @@ +#define LIBFFI_ASM +#include +#include +#include + +#if defined(HAVE_AS_CFI_PSEUDO_OP) + .cfi_sections .debug_frame +#endif + +#define arg0 %rcx +#define arg1 %rdx +#define arg2 %r8 +#define arg3 %r9 + +#ifdef SYMBOL_UNDERSCORE +#define SYMBOL_NAME(name) _##name +#else +#define SYMBOL_NAME(name) name +#endif + +.macro E which + .align 8 + .org 0b + \which * 8 +.endm + + .text + +/* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10) + + Bit o trickiness here -- FRAME is the base of the stack frame + for this function. This has been allocated by ffi_call. We also + deallocate some of the stack that has been alloca'd. */ + + .align 8 + .globl ffi_call_win64 + + .seh_proc ffi_call_win64 +ffi_call_win64: + cfi_startproc + /* Set up the local stack frame and install it in rbp/rsp. */ + movq (%rsp), %rax + movq %rbp, (arg1) + movq %rax, 8(arg1) + movq arg1, %rbp + cfi_def_cfa(%rbp, 16) + cfi_rel_offset(%rbp, 0) + .seh_pushreg %rbp + .seh_setframe %rbp, 0 + .seh_endprologue + movq arg0, %rsp + + movq arg2, %r10 + + /* Load all slots into both general and xmm registers. */ + movq (%rsp), %rcx + movsd (%rsp), %xmm0 + movq 8(%rsp), %rdx + movsd 8(%rsp), %xmm1 + movq 16(%rsp), %r8 + movsd 16(%rsp), %xmm2 + movq 24(%rsp), %r9 + movsd 24(%rsp), %xmm3 + + call *16(%rbp) + + movl 24(%rbp), %ecx + movq 32(%rbp), %r8 + leaq 0f(%rip), %r10 + cmpl $FFI_TYPE_SMALL_STRUCT_4B, %ecx + leaq (%r10, %rcx, 8), %r10 + ja 99f + jmp *%r10 + +/* Below, we're space constrained most of the time. Thus we eschew the + modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes). */ +.macro epilogue + leaveq + cfi_remember_state + cfi_def_cfa(%rsp, 8) + cfi_restore(%rbp) + ret + cfi_restore_state +.endm + + .align 8 +0: +E FFI_TYPE_VOID + epilogue +E FFI_TYPE_INT + movslq %eax, %rax + movq %rax, (%r8) + epilogue +E FFI_TYPE_FLOAT + movss %xmm0, (%r8) + epilogue +E FFI_TYPE_DOUBLE + movsd %xmm0, (%r8) + epilogue +E FFI_TYPE_LONGDOUBLE + call abort +E FFI_TYPE_UINT8 + movzbl %al, %eax + movq %rax, (%r8) + epilogue +E FFI_TYPE_SINT8 + movsbq %al, %rax + jmp 98f +E FFI_TYPE_UINT16 + movzwl %ax, %eax + movq %rax, (%r8) + epilogue +E FFI_TYPE_SINT16 + movswq %ax, %rax + jmp 98f +E FFI_TYPE_UINT32 + movl %eax, %eax + movq %rax, (%r8) + epilogue +E FFI_TYPE_SINT32 + movslq %eax, %rax + movq %rax, (%r8) + epilogue +E FFI_TYPE_UINT64 +98: movq %rax, (%r8) + epilogue +E FFI_TYPE_SINT64 + movq %rax, (%r8) + epilogue +E FFI_TYPE_STRUCT + epilogue +E FFI_TYPE_POINTER + movq %rax, (%r8) + epilogue +E FFI_TYPE_COMPLEX + call abort +E FFI_TYPE_SMALL_STRUCT_1B + movb %al, (%r8) + epilogue +E FFI_TYPE_SMALL_STRUCT_2B + movw %ax, (%r8) + epilogue +E FFI_TYPE_SMALL_STRUCT_4B + movl %eax, (%r8) + epilogue + + .align 8 +99: call abort + +.purgem epilogue + + cfi_endproc + .seh_endproc + + +/* 32 bytes of outgoing register stack space, 8 bytes of alignment, + 16 bytes of result, 32 bytes of xmm registers. */ +#define ffi_clo_FS (32+8+16+32) +#define ffi_clo_OFF_R (32+8) +#define ffi_clo_OFF_X (32+8+16) + + .align 8 + .globl ffi_go_closure_win64 + + .seh_proc ffi_go_closure_win64 +ffi_go_closure_win64: + cfi_startproc + /* Save all integer arguments into the incoming reg stack space. */ + movq arg0, 8(%rsp) + movq arg1, 16(%rsp) + movq arg2, 24(%rsp) + movq arg3, 32(%rsp) + + movq 8(%r10), arg0 /* load cif */ + movq 16(%r10), arg1 /* load fun */ + movq %r10, arg2 /* closure is user_data */ + jmp 0f + cfi_endproc + .seh_endproc + + .align 8 + .globl ffi_closure_win64 + + .seh_proc ffi_closure_win64 +ffi_closure_win64: + cfi_startproc + /* Save all integer arguments into the incoming reg stack space. */ + movq arg0, 8(%rsp) + movq arg1, 16(%rsp) + movq arg2, 24(%rsp) + movq arg3, 32(%rsp) + + movq FFI_TRAMPOLINE_SIZE(%r10), arg0 /* load cif */ + movq FFI_TRAMPOLINE_SIZE+8(%r10), arg1 /* load fun */ + movq FFI_TRAMPOLINE_SIZE+16(%r10), arg2 /* load user_data */ +0: + subq $ffi_clo_FS, %rsp + cfi_adjust_cfa_offset(ffi_clo_FS) + .seh_stackalloc ffi_clo_FS + .seh_endprologue + + /* Save all sse arguments into the stack frame. */ + movsd %xmm0, ffi_clo_OFF_X(%rsp) + movsd %xmm1, ffi_clo_OFF_X+8(%rsp) + movsd %xmm2, ffi_clo_OFF_X+16(%rsp) + movsd %xmm3, ffi_clo_OFF_X+24(%rsp) + + leaq ffi_clo_OFF_R(%rsp), arg3 + call ffi_closure_win64_inner + + /* Load the result into both possible result registers. */ + movq ffi_clo_OFF_R(%rsp), %rax + movsd ffi_clo_OFF_R(%rsp), %xmm0 + + addq $ffi_clo_FS, %rsp + cfi_adjust_cfa_offset(-ffi_clo_FS) + ret + + cfi_endproc + .seh_endproc diff --git a/circuitpython/lib/libffi/src/xtensa/ffi.c b/circuitpython/lib/libffi/src/xtensa/ffi.c new file mode 100644 index 0000000..fd94daf --- /dev/null +++ b/circuitpython/lib/libffi/src/xtensa/ffi.c @@ -0,0 +1,298 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2013 Tensilica, Inc. + + XTENSA Foreign Function Interface + + 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 +#include + +/* + |----------------------------------------| + | | + on entry to ffi_call ----> |----------------------------------------| + | caller stack frame for registers a0-a3 | + |----------------------------------------| + | | + | additional arguments | + entry of the function ---> |----------------------------------------| + | copy of function arguments a2-a7 | + | - - - - - - - - - - - - - | + | | + + The area below the entry line becomes the new stack frame for the function. + +*/ + + +#define FFI_TYPE_STRUCT_REGS FFI_TYPE_LAST + + +extern void ffi_call_SYSV(void *rvalue, unsigned rsize, unsigned flags, + void(*fn)(void), unsigned nbytes, extended_cif*); +extern void ffi_closure_SYSV(void) FFI_HIDDEN; + +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + switch(cif->rtype->type) { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + cif->flags = cif->rtype->type; + break; + case FFI_TYPE_VOID: + case FFI_TYPE_FLOAT: + cif->flags = FFI_TYPE_UINT32; + break; + case FFI_TYPE_DOUBLE: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + cif->flags = FFI_TYPE_UINT64; // cif->rtype->type; + break; + case FFI_TYPE_STRUCT: + cif->flags = FFI_TYPE_STRUCT; //_REGS; + /* Up to 16 bytes are returned in registers */ + if (cif->rtype->size > 4 * 4) { + /* returned structure is referenced by a register; use 8 bytes + (including 4 bytes for potential additional alignment) */ + cif->flags = FFI_TYPE_STRUCT; + cif->bytes += 8; + } + break; + + default: + cif->flags = FFI_TYPE_UINT32; + break; + } + + /* Round the stack up to a full 4 register frame, just in case + (we use this size in movsp). This way, it's also a multiple of + 8 bytes for 64-bit arguments. */ + cif->bytes = ALIGN(cif->bytes, 16); + + return FFI_OK; +} + +void ffi_prep_args(extended_cif *ecif, unsigned char* stack) +{ + unsigned int i; + unsigned long *addr; + ffi_type **ptr; + + union { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + unsigned int **i; + long long **ll; + float **f; + double **d; + } p_argv; + + /* Verify that everything is aligned up properly */ + FFI_ASSERT (((unsigned long) stack & 0x7) == 0); + + p_argv.v = ecif->avalue; + addr = (unsigned long*)stack; + + /* structures with a size greater than 16 bytes are passed in memory */ + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 16) + { + *addr++ = (unsigned long)ecif->rvalue; + } + + for (i = ecif->cif->nargs, ptr = ecif->cif->arg_types; + i > 0; + i--, ptr++, p_argv.v++) + { + switch ((*ptr)->type) + { + case FFI_TYPE_SINT8: + *addr++ = **p_argv.sc; + break; + case FFI_TYPE_UINT8: + *addr++ = **p_argv.uc; + break; + case FFI_TYPE_SINT16: + *addr++ = **p_argv.ss; + break; + case FFI_TYPE_UINT16: + *addr++ = **p_argv.us; + break; + case FFI_TYPE_FLOAT: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + *addr++ = **p_argv.i; + break; + case FFI_TYPE_DOUBLE: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + if (((unsigned long)addr & 4) != 0) + addr++; + *(unsigned long long*)addr = **p_argv.ll; + addr += sizeof(unsigned long long) / sizeof (addr); + break; + + case FFI_TYPE_STRUCT: + { + unsigned long offs; + unsigned long size; + + if (((unsigned long)addr & 4) != 0 && (*ptr)->alignment > 4) + addr++; + + offs = (unsigned long) addr - (unsigned long) stack; + size = (*ptr)->size; + + /* Entire structure must fit the argument registers or referenced */ + if (offs < FFI_REGISTER_NARGS * 4 + && offs + size > FFI_REGISTER_NARGS * 4) + addr = (unsigned long*) (stack + FFI_REGISTER_NARGS * 4); + + memcpy((char*) addr, *p_argv.c, size); + addr += (size + 3) / 4; + break; + } + + default: + FFI_ASSERT(0); + } + } +} + + +void ffi_call(ffi_cif* cif, void(*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + unsigned long rsize = cif->rtype->size; + int flags = cif->flags; + void *alloc = NULL; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* Note that for structures that are returned in registers (size <= 16 bytes) + we allocate a temporary buffer and use memcpy to copy it to the final + destination. The reason is that the target address might be misaligned or + the length not a multiple of 4 bytes. Handling all those cases would be + very complex. */ + + if (flags == FFI_TYPE_STRUCT && (rsize <= 16 || rvalue == NULL)) + { + alloc = alloca(ALIGN(rsize, 4)); + ecif.rvalue = alloc; + } + else + { + ecif.rvalue = rvalue; + } + + if (cif->abi != FFI_SYSV) + FFI_ASSERT(0); + + ffi_call_SYSV (ecif.rvalue, rsize, cif->flags, fn, cif->bytes, &ecif); + + if (alloc != NULL && rvalue != NULL) + memcpy(rvalue, alloc, rsize); +} + +extern void ffi_trampoline(); +extern void ffi_cacheflush(void* start, void* end); + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + /* copye trampoline to stack and patch 'ffi_closure_SYSV' pointer */ + memcpy(closure->tramp, ffi_trampoline, FFI_TRAMPOLINE_SIZE); + *(unsigned int*)(&closure->tramp[8]) = (unsigned int)ffi_closure_SYSV; + + // Do we have this function? + // __builtin___clear_cache(closer->tramp, closer->tramp + FFI_TRAMPOLINE_SIZE) + ffi_cacheflush(closure->tramp, closure->tramp + FFI_TRAMPOLINE_SIZE); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + return FFI_OK; +} + + +long FFI_HIDDEN +ffi_closure_SYSV_inner(ffi_closure *closure, void **values, void *rvalue) +{ + ffi_cif *cif; + ffi_type **arg_types; + void **avalue; + int i, areg; + + cif = closure->cif; + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + areg = 0; + + int rtype = cif->rtype->type; + if (rtype == FFI_TYPE_STRUCT && cif->rtype->size > 4 * 4) + { + rvalue = *values; + areg++; + } + + cif = closure->cif; + arg_types = cif->arg_types; + avalue = alloca(cif->nargs * sizeof(void *)); + + for (i = 0; i < cif->nargs; i++) + { + if (arg_types[i]->alignment == 8 && (areg & 1) != 0) + areg++; + + // skip the entry 16,a1 framework, add 16 bytes (4 registers) + if (areg == FFI_REGISTER_NARGS) + areg += 4; + + if (arg_types[i]->type == FFI_TYPE_STRUCT) + { + int numregs = ((arg_types[i]->size + 3) & ~3) / 4; + if (areg < FFI_REGISTER_NARGS && areg + numregs > FFI_REGISTER_NARGS) + areg = FFI_REGISTER_NARGS + 4; + } + + avalue[i] = &values[areg]; + areg += (arg_types[i]->size + 3) / 4; + } + + (closure->fun)(cif, rvalue, avalue, closure->user_data); + + return rtype; +} diff --git a/circuitpython/lib/libffi/src/xtensa/ffitarget.h b/circuitpython/lib/libffi/src/xtensa/ffitarget.h new file mode 100644 index 0000000..0ba728b --- /dev/null +++ b/circuitpython/lib/libffi/src/xtensa/ffitarget.h @@ -0,0 +1,53 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2013 Tensilica, Inc. + Target configuration macros for XTENSA. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +#define FFI_REGISTER_NARGS 6 + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 +#define FFI_TRAMPOLINE_SIZE 24 + +#endif diff --git a/circuitpython/lib/libffi/src/xtensa/sysv.S b/circuitpython/lib/libffi/src/xtensa/sysv.S new file mode 100644 index 0000000..64e6a09 --- /dev/null +++ b/circuitpython/lib/libffi/src/xtensa/sysv.S @@ -0,0 +1,253 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2013 Tensilica, Inc. + + XTENSA Foreign Function Interface + + 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 LIBFFI_ASM +#include +#include + +#define ENTRY(name) .text; .globl name; .type name,@function; .align 4; name: +#define END(name) .size name , . - name + +/* Assert that the table below is in sync with ffi.h. */ + +#if FFI_TYPE_UINT8 != 5 \ + || FFI_TYPE_SINT8 != 6 \ + || FFI_TYPE_UINT16 != 7 \ + || FFI_TYPE_SINT16 != 8 \ + || FFI_TYPE_UINT32 != 9 \ + || FFI_TYPE_SINT32 != 10 \ + || FFI_TYPE_UINT64 != 11 +#error "xtensa/sysv.S out of sync with ffi.h" +#endif + + +/* ffi_call_SYSV (rvalue, rbytes, flags, (*fnaddr)(), bytes, ecif) + void *rvalue; a2 + unsigned long rbytes; a3 + unsigned flags; a4 + void (*fnaddr)(); a5 + unsigned long bytes; a6 + extended_cif* ecif) a7 +*/ + +ENTRY(ffi_call_SYSV) + + entry a1, 32 # 32 byte frame for using call8 below + + mov a10, a7 # a10(->arg0): ecif + sub a11, a1, a6 # a11(->arg1): stack pointer + mov a7, a1 # fp + movsp a1, a11 # set new sp = old_sp - bytes + + movi a8, ffi_prep_args + callx8 a8 # ffi_prep_args(ecif, stack) + + # prepare to move stack pointer back up to 6 arguments + # note that 'bytes' is already aligned + + movi a10, 6*4 + sub a11, a6, a10 + movgez a6, a10, a11 + add a6, a1, a6 + + + # we can pass up to 6 arguments in registers + # for simplicity, just load 6 arguments + # (the stack size is at least 32 bytes, so no risk to cross boundaries) + + l32i a10, a1, 0 + l32i a11, a1, 4 + l32i a12, a1, 8 + l32i a13, a1, 12 + l32i a14, a1, 16 + l32i a15, a1, 20 + + # move stack pointer + + movsp a1, a6 + + callx8 a5 # (*fn)(args...) + + # Handle return value(s) + + beqz a2, .Lexit + + movi a5, FFI_TYPE_STRUCT + bne a4, a5, .Lstore + movi a5, 16 + blt a5, a3, .Lexit + + s32i a10, a2, 0 + blti a3, 5, .Lexit + addi a3, a3, -1 + s32i a11, a2, 4 + blti a3, 8, .Lexit + s32i a12, a2, 8 + blti a3, 12, .Lexit + s32i a13, a2, 12 + +.Lexit: retw + +.Lstore: + addi a4, a4, -FFI_TYPE_UINT8 + bgei a4, 7, .Lexit # should never happen + movi a6, store_calls + add a4, a4, a4 + addx4 a6, a4, a6 # store_table + idx * 8 + jx a6 + + .align 8 +store_calls: + # UINT8 + s8i a10, a2, 0 + retw + + # SINT8 + .align 8 + s8i a10, a2, 0 + retw + + # UINT16 + .align 8 + s16i a10, a2, 0 + retw + + # SINT16 + .align 8 + s16i a10, a2, 0 + retw + + # UINT32 + .align 8 + s32i a10, a2, 0 + retw + + # SINT32 + .align 8 + s32i a10, a2, 0 + retw + + # UINT64 + .align 8 + s32i a10, a2, 0 + s32i a11, a2, 4 + retw + +END(ffi_call_SYSV) + + +/* + * void ffi_cacheflush (unsigned long start, unsigned long end) + */ + +#define EXTRA_ARGS_SIZE 24 + +ENTRY(ffi_cacheflush) + + entry a1, 16 + +1: dhwbi a2, 0 + ihi a2, 0 + addi a2, a2, 4 + blt a2, a3, 1b + + retw + +END(ffi_cacheflush) + +/* ffi_trampoline is copied to the stack */ + +ENTRY(ffi_trampoline) + + entry a1, 16 + (FFI_REGISTER_NARGS * 4) + (4 * 4) # [ 0] + j 2f # [ 3] + .align 4 # [ 6] +1: .long 0 # [ 8] +2: l32r a15, 1b # [12] + _mov a14, a0 # [15] + callx0 a15 # [18] + # [21] +END(ffi_trampoline) + +/* + * ffi_closure() + * + * a0: closure + 21 + * a14: return address (a0) + */ + +ENTRY(ffi_closure_SYSV) + + /* intentionally omitting entry here */ + + # restore return address (a0) and move pointer to closure to a10 + addi a10, a0, -21 + mov a0, a14 + + # allow up to 4 arguments as return values + addi a11, a1, 4 * 4 + + # save up to 6 arguments to stack (allocated by entry below) + s32i a2, a11, 0 + s32i a3, a11, 4 + s32i a4, a11, 8 + s32i a5, a11, 12 + s32i a6, a11, 16 + s32i a7, a11, 20 + + movi a8, ffi_closure_SYSV_inner + mov a12, a1 + callx8 a8 # .._inner(*closure, **avalue, *rvalue) + + # load up to four return arguments + l32i a2, a1, 0 + l32i a3, a1, 4 + l32i a4, a1, 8 + l32i a5, a1, 12 + + # (sign-)extend return value + movi a11, FFI_TYPE_UINT8 + bne a10, a11, 1f + extui a2, a2, 0, 8 + retw + +1: movi a11, FFI_TYPE_SINT8 + bne a10, a11, 1f + sext a2, a2, 7 + retw + +1: movi a11, FFI_TYPE_UINT16 + bne a10, a11, 1f + extui a2, a2, 0, 16 + retw + +1: movi a11, FFI_TYPE_SINT16 + bne a10, a11, 1f + sext a2, a2, 15 + +1: retw + +END(ffi_closure_SYSV) diff --git a/circuitpython/lib/libffi/stamp-h.in b/circuitpython/lib/libffi/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/circuitpython/lib/libffi/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/circuitpython/lib/libffi/testsuite/Makefile.am b/circuitpython/lib/libffi/testsuite/Makefile.am new file mode 100644 index 0000000..da10465 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/Makefile.am @@ -0,0 +1,85 @@ +## Process this file with automake to produce Makefile.in. + +AUTOMAKE_OPTIONS = foreign dejagnu + +EXTRA_DEJAGNU_SITE_CONFIG=../local.exp + +CLEANFILES = *.exe core* *.log *.sum + +EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ +libffi.call/cls_align_longdouble_split.c \ +libffi.call/closure_loc_fn0.c libffi.call/cls_schar.c \ +libffi.call/closure_fn1.c \ +libffi.call/return_ul.c libffi.call/cls_align_double.c \ +libffi.call/return_fl2.c libffi.call/cls_1_1byte.c \ +libffi.call/cls_64byte.c libffi.call/nested_struct7.c \ +libffi.call/cls_align_sint32.c libffi.call/nested_struct2.c \ +libffi.call/ffitest.h libffi.call/nested_struct4.c \ +libffi.call/cls_multi_ushort.c libffi.call/struct3.c \ +libffi.call/cls_3byte1.c libffi.call/cls_16byte.c \ +libffi.call/struct8.c libffi.call/nested_struct8.c \ +libffi.call/cls_multi_sshort.c libffi.call/cls_3byte2.c \ +libffi.call/cls_pointer.c \ +libffi.call/err_bad_typedef.c libffi.call/cls_4_1byte.c \ +libffi.call/cls_9byte2.c libffi.call/cls_multi_schar.c \ +libffi.call/stret_medium2.c libffi.call/cls_5_1_byte.c \ +libffi.call/call.exp libffi.call/cls_double.c \ +libffi.call/cls_align_sint16.c libffi.call/cls_uint.c \ +libffi.call/return_ll1.c libffi.call/nested_struct3.c \ +libffi.call/cls_20byte1.c libffi.call/closure_fn4.c \ +libffi.call/cls_uchar.c libffi.call/struct2.c libffi.call/cls_7byte.c \ +libffi.call/strlen.c libffi.call/many.c libffi.call/testclosure.c \ +libffi.call/return_fl.c libffi.call/struct5.c \ +libffi.call/cls_12byte.c libffi.call/cls_multi_sshortchar.c \ +libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ +libffi.call/return_fl3.c libffi.call/stret_medium.c \ +libffi.call/nested_struct6.c libffi.call/closure_fn3.c \ +libffi.call/float3.c libffi.call/many2.c \ +libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ +libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ +libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ +libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ +libffi.call/cls_sshort.c \ +libffi.call/nested_struct.c libffi.call/cls_20byte.c \ +libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ +libffi.call/return_uc.c \ +libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ +libffi.call/promotion.c \ +libffi.call/return_dbl.c libffi.call/cls_24byte.c \ +libffi.call/struct4.c libffi.call/cls_6byte.c \ +libffi.call/cls_align_uint32.c libffi.call/float.c \ +libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ +libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ +libffi.call/cls_align_float.c libffi.call/return_fl1.c \ +libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ +libffi.call/cls_align_sint64.c \ +libffi.call/stret_large2.c libffi.call/return_sl.c \ +libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ +libffi.call/cls_2byte.c libffi.call/float2.c \ +libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \ +libffi.call/stret_large.c libffi.call/cls_ulonglong.c \ +libffi.call/cls_ushort.c libffi.call/nested_struct1.c \ +libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \ +libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ +libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ +libffi.call/struct1.c libffi.call/nested_struct9.c \ +libffi.call/huge_struct.c libffi.call/problem1.c \ +libffi.call/float4.c \ +libffi.call/return_ldl.c \ +libffi.call/closure_fn5.c \ +libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c \ +libffi.call/return_sc.c libffi.call/struct7.c \ +libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c \ +libffi.call/cls_6_1_byte.c \ +libffi.call/cls_7_1_byte.c libffi.call/unwindtest.cc \ +libffi.call/unwindtest_ffi_call.cc \ +lib/wrapper.exp lib/target-libpath.exp \ +lib/libffi.exp libffi.call/cls_struct_va1.c \ +libffi.call/cls_uchar_va.c libffi.call/cls_uint_va.c \ +libffi.call/cls_ulong_va.c libffi.call/cls_ushort_va.c \ +libffi.call/nested_struct11.c libffi.call/uninitialized.c \ +libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c \ +libffi.call/va_struct3.c \ +libffi.call/strlen2.c \ +libffi.call/strlen3.c \ +libffi.call/strlen4.c diff --git a/circuitpython/lib/libffi/testsuite/config/default.exp b/circuitpython/lib/libffi/testsuite/config/default.exp new file mode 100644 index 0000000..90967cc --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/config/default.exp @@ -0,0 +1 @@ +load_lib "standard.exp" diff --git a/circuitpython/lib/libffi/testsuite/lib/libffi.exp b/circuitpython/lib/libffi/testsuite/lib/libffi.exp new file mode 100644 index 0000000..1b8b008 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/lib/libffi.exp @@ -0,0 +1,431 @@ +# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# . + +proc load_gcc_lib { filename } { + global srcdir + load_file $srcdir/lib/$filename +} + +load_lib dg.exp +load_lib libgloss.exp +load_gcc_lib target-libpath.exp +load_gcc_lib wrapper.exp + + +# Define libffi callbacks for dg.exp. + +proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } { + + # To get all \n in dg-output test strings to match printf output + # in a system that outputs it as \015\012 (i.e. not just \012), we + # need to change all \n into \r?\n. As there is no dejagnu flag + # or hook to do that, we simply change the text being tested. + # Unfortunately, we have to know that the variable is called + # dg-output-text and lives in the caller of libffi-dg-test, which + # is two calls up. Overriding proc dg-output would be longer and + # would necessarily have the same assumption. + upvar 2 dg-output-text output_match + + if { [llength $output_match] > 1 } { + regsub -all "\n" [lindex $output_match 1] "\r?\n" x + set output_match [lreplace $output_match 1 1 $x] + } + + # Set up the compiler flags, based on what we're going to do. + + set options [list] + switch $do_what { + "compile" { + set compile_type "assembly" + set output_file "[file rootname [file tail $prog]].s" + } + "link" { + set compile_type "executable" + set output_file "[file rootname [file tail $prog]].exe" + # The following line is needed for targets like the i960 where + # the default output file is b.out. Sigh. + } + "run" { + set compile_type "executable" + # FIXME: "./" is to cope with "." not being in $PATH. + # Should this be handled elsewhere? + # YES. + set output_file "./[file rootname [file tail $prog]].exe" + # This is the only place where we care if an executable was + # created or not. If it was, dg.exp will try to run it. + remote_file build delete $output_file; + } + default { + perror "$do_what: not a valid dg-do keyword" + return "" + } + } + + if { $extra_tool_flags != "" } { + lappend options "additional_flags=$extra_tool_flags" + } + + set comp_output [libffi_target_compile "$prog" "$output_file" "$compile_type" $options]; + + + return [list $comp_output $output_file] +} + + +proc libffi-dg-test { prog do_what extra_tool_flags } { + return [libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags] +} + +proc libffi-init { args } { + global gluefile wrap_flags; + global srcdir + global blddirffi + global objdir + global TOOL_OPTIONS + global tool + global libffi_include + global libffi_link_flags + global tool_root_dir + global ld_library_path + global compiler_vendor + + set blddirffi [pwd]/.. + verbose "libffi $blddirffi" + + # Which compiler are we building with? + set tmp [grep ../config.log "^ax_cv_c_compiler_vendor.*$"] + regexp -- {^[^=]*=(.*)$} $tmp nil compiler_vendor + + if { [string match $compiler_vendor "gnu"] } { + set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] + if {$gccdir != ""} { + set gccdir [file dirname $gccdir] + } + verbose "gccdir $gccdir" + + set ld_library_path "." + append ld_library_path ":${gccdir}" + + set compiler "${gccdir}/xgcc" + if { [is_remote host] == 0 && [which $compiler] != 0 } { + foreach i "[exec $compiler --print-multi-lib]" { + set mldir "" + regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir + set mldir [string trimright $mldir "\;@"] + if { "$mldir" == "." } { + continue + } + if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } { + append ld_library_path ":${gccdir}/${mldir}" + } + } + } + } + + # add the library path for libffi. + append ld_library_path ":${blddirffi}/.libs" + + verbose "ld_library_path: $ld_library_path" + + # Point to the Libffi headers in libffi. + set libffi_include "${blddirffi}/include" + verbose "libffi_include $libffi_include" + + set libffi_dir "${blddirffi}/.libs" + verbose "libffi_dir $libffi_dir" + if { $libffi_dir != "" } { + set libffi_dir [file dirname ${libffi_dir}] + set libffi_link_flags "-L${libffi_dir}/.libs" + } + + set_ld_library_path_env_vars + libffi_maybe_build_wrapper "${objdir}/testglue.o" +} + +proc libffi_exit { } { + global gluefile; + + if [info exists gluefile] { + file_on_build delete $gluefile; + unset gluefile; + } +} + +proc libffi_target_compile { source dest type options } { + global gluefile wrap_flags; + global srcdir + global blddirffi + global TOOL_OPTIONS + global libffi_link_flags + global libffi_include + global target_triplet + + + if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=$wrap_flags" + } + + # TOOL_OPTIONS must come first, so that it doesn't override testcase + # specific options. + if [info exists TOOL_OPTIONS] { + lappend options [concat "additional_flags=$TOOL_OPTIONS" $options]; + } + + # search for ffi_mips.h in srcdir, too + lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.." + lappend options "additional_flags=${libffi_link_flags}" + + # Darwin needs a stack execution allowed flag. + + if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"] + || [istarget "*-*-darwin2*"] } { + lappend options "additional_flags=-Wl,-allow_stack_execute" + } + + # If you're building the compiler with --prefix set to a place + # where it's not yet installed, then the linker won't be able to + # find the libgcc used by libffi.dylib. We could pass the + # -dylib_file option, but that's complicated, and it's much easier + # to just make the linker find libgcc using -L options. + if { [string match "*-*-darwin*" $target_triplet] } { + lappend options "libs= -shared-libgcc" + } + + if { [string match "*-*-openbsd*" $target_triplet] } { + lappend options "libs= -lpthread" + } + + lappend options "libs= -lffi" + + if { [string match "aarch64*-*-linux*" $target_triplet] } { + lappend options "libs= -lpthread" + } + + if { [string match "*.cc" $source] } { + lappend options "c++" + } + + verbose "options: $options" + return [target_compile $source $dest $type $options] +} + +# TEST should be a preprocessor condition. Returns true if it holds. +proc libffi_feature_test { test } { + set src "ffitest.c" + + set f [open $src "w"] + puts $f "#include " + puts $f $test + puts $f "xyzzy" + puts $f "#endif" + close $f + + set lines [libffi_target_compile $src "" "preprocess" ""] + file delete $src + + set last [lindex $lines end] + return [regexp -- "xyzzy" $last] +} + +# Utility routines. + +# +# search_for -- looks for a string match in a file +# +proc search_for { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + if [string match "*$pattern*" $cur_line] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc libffi-dg-runtest { testcases default-extra-flags } { + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $test "for*("]+[search_for $test "while*("]] { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags $option_list { + verbose "Testing $nshort, $flags" 1 + dg-test $test $flags ${default-extra-flags} + } + } +} + +proc run-many-tests { testcases extra_flags } { + global compiler_vendor + switch $compiler_vendor { + "clang" { + set common "-W -Wall" + set optimizations { "-O0" "-O1" "-O2" "-O3" "-Os" } + } + "gnu" { + set common "-W -Wall -Wno-psabi" + set optimizations { "-O0" "-O2" "-O3" "-Os" "-O2 -fomit-frame-pointer" } + } + default { + # Assume we are using the vendor compiler. + set common "" + set optimizations { "" } + } + } + + set targetabis { "" } + if [string match $compiler_vendor "gnu"] { + if [istarget "i?86-*-*"] { + set targetabis { + "" + "-DABI_NUM=FFI_STDCALL -DABI_ATTR=__STDCALL__" + "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__" + "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__" + } + } + } + + set common [ concat $common $extra_flags ] + foreach test $testcases { + set testname [file tail $test] + if [search_for $test "ABI_NUM"] { + set abis $targetabis + } else { + set abis { "" } + } + foreach opt $optimizations { + foreach abi $abis { + set options [concat $common $opt $abi] + verbose "Testing $testname, $options" 1 + dg-test $test $options "" + } + } + } +} + +# Like check_conditional_xfail, but callable from a dg test. + +proc dg-xfail-if { args } { + set args [lreplace $args 0 0] + set selector "target [join [lindex $args 1]]" + if { [dg-process-target $selector] == "S" } { + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data $args + } +} + +proc check-flags { args } { + + # The args are within another list; pull them out. + set args [lindex $args 0] + + # The next two arguments are optional. If they were not specified, + # use the defaults. + if { [llength $args] == 2 } { + lappend $args [list "*"] + } + if { [llength $args] == 3 } { + lappend $args [list ""] + } + + # If the option strings are the defaults, or the same as the + # defaults, there is no need to call check_conditional_xfail to + # compare them to the actual options. + if { [string compare [lindex $args 2] "*"] == 0 + && [string compare [lindex $args 3] "" ] == 0 } { + set result 1 + } else { + # The target list might be an effective-target keyword, so replace + # the original list with "*-*-*", since we already know it matches. + set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]] + } + + return $result +} + +proc dg-skip-if { args } { + # Verify the number of arguments. The last two are optional. + set args [lreplace $args 0 0] + if { [llength $args] < 2 || [llength $args] > 4 } { + error "dg-skip-if 2: need 2, 3, or 4 arguments" + } + + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + set selector [list target [lindex $args 1]] + if { [dg-process-target $selector] == "S" } { + if [check-flags $args] { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } + } +} + +# We need to make sure that additional_files and additional_sources +# are both cleared out after every test. It is not enough to clear +# them out *before* the next test run because gcc-target-compile gets +# run directly from some .exp files (outside of any test). (Those +# uses should eventually be eliminated.) + +# Because the DG framework doesn't provide a hook that is run at the +# end of a test, we must replace dg-test with a wrapper. + +if { [info procs saved-dg-test] == [list] } { + rename dg-test saved-dg-test + + proc dg-test { args } { + global additional_files + global additional_sources + global errorInfo + + if { [ catch { eval saved-dg-test $args } errmsg ] } { + set saved_info $errorInfo + set additional_files "" + set additional_sources "" + error $errmsg $saved_info + } + set additional_files "" + set additional_sources "" + } +} + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/circuitpython/lib/libffi/testsuite/lib/target-libpath.exp b/circuitpython/lib/libffi/testsuite/lib/target-libpath.exp new file mode 100644 index 0000000..6b7beba --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/lib/target-libpath.exp @@ -0,0 +1,283 @@ +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This file was contributed by John David Anglin (dave.anglin@nrc-cnrc.gc.ca) + +set orig_environment_saved 0 +set orig_ld_library_path_saved 0 +set orig_ld_run_path_saved 0 +set orig_shlib_path_saved 0 +set orig_ld_libraryn32_path_saved 0 +set orig_ld_library64_path_saved 0 +set orig_ld_library_path_32_saved 0 +set orig_ld_library_path_64_saved 0 +set orig_dyld_library_path_saved 0 +set orig_path_saved 0 + +####################################### +# proc set_ld_library_path_env_vars { } +####################################### + +proc set_ld_library_path_env_vars { } { + global ld_library_path + global orig_environment_saved + global orig_ld_library_path_saved + global orig_ld_run_path_saved + global orig_shlib_path_saved + global orig_ld_libraryn32_path_saved + global orig_ld_library64_path_saved + global orig_ld_library_path_32_saved + global orig_ld_library_path_64_saved + global orig_dyld_library_path_saved + global orig_path_saved + global orig_ld_library_path + global orig_ld_run_path + global orig_shlib_path + global orig_ld_libraryn32_path + global orig_ld_library64_path + global orig_ld_library_path_32 + global orig_ld_library_path_64 + global orig_dyld_library_path + global orig_path + global GCC_EXEC_PREFIX + + # Set the relocated compiler prefix, but only if the user hasn't specified one. + if { [info exists GCC_EXEC_PREFIX] && ![info exists env(GCC_EXEC_PREFIX)] } { + setenv GCC_EXEC_PREFIX "$GCC_EXEC_PREFIX" + } + + # Setting the ld library path causes trouble when testing cross-compilers. + if { [is_remote target] } { + return + } + + if { $orig_environment_saved == 0 } { + global env + + set orig_environment_saved 1 + + # Save the original environment. + if [info exists env(LD_LIBRARY_PATH)] { + set orig_ld_library_path "$env(LD_LIBRARY_PATH)" + set orig_ld_library_path_saved 1 + } + if [info exists env(LD_RUN_PATH)] { + set orig_ld_run_path "$env(LD_RUN_PATH)" + set orig_ld_run_path_saved 1 + } + if [info exists env(SHLIB_PATH)] { + set orig_shlib_path "$env(SHLIB_PATH)" + set orig_shlib_path_saved 1 + } + if [info exists env(LD_LIBRARYN32_PATH)] { + set orig_ld_libraryn32_path "$env(LD_LIBRARYN32_PATH)" + set orig_ld_libraryn32_path_saved 1 + } + if [info exists env(LD_LIBRARY64_PATH)] { + set orig_ld_library64_path "$env(LD_LIBRARY64_PATH)" + set orig_ld_library64_path_saved 1 + } + if [info exists env(LD_LIBRARY_PATH_32)] { + set orig_ld_library_path_32 "$env(LD_LIBRARY_PATH_32)" + set orig_ld_library_path_32_saved 1 + } + if [info exists env(LD_LIBRARY_PATH_64)] { + set orig_ld_library_path_64 "$env(LD_LIBRARY_PATH_64)" + set orig_ld_library_path_64_saved 1 + } + if [info exists env(DYLD_LIBRARY_PATH)] { + set orig_dyld_library_path "$env(DYLD_LIBRARY_PATH)" + set orig_dyld_library_path_saved 1 + } + if [info exists env(PATH)] { + set orig_path "$env(PATH)" + set orig_path_saved 1 + } + } + + # We need to set ld library path in the environment. Currently, + # unix.exp doesn't set the environment correctly for all systems. + # It only sets SHLIB_PATH and LD_LIBRARY_PATH when it executes a + # program. We also need the environment set for compilations, etc. + # + # On IRIX 6, we have to set variables akin to LD_LIBRARY_PATH, but + # called LD_LIBRARYN32_PATH (for the N32 ABI) and LD_LIBRARY64_PATH + # (for the 64-bit ABI). The same applies to Darwin (DYLD_LIBRARY_PATH), + # Solaris 32 bit (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64), + # and HP-UX (SHLIB_PATH). In some cases, the variables are independent + # of LD_LIBRARY_PATH, and in other cases LD_LIBRARY_PATH is used if the + # variable is not defined. + # + # Doing this is somewhat of a hack as ld_library_path gets repeated in + # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables. + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH "$ld_library_path" + } + if { $orig_ld_run_path_saved } { + setenv LD_RUN_PATH "$ld_library_path:$orig_ld_run_path" + } else { + setenv LD_RUN_PATH "$ld_library_path" + } + # The default shared library dynamic path search for 64-bit + # HP-UX executables searches LD_LIBRARY_PATH before SHLIB_PATH. + # LD_LIBRARY_PATH isn't used for 32-bit executables. Thus, we + # set LD_LIBRARY_PATH and SHLIB_PATH as if they were independent. + if { $orig_shlib_path_saved } { + setenv SHLIB_PATH "$ld_library_path:$orig_shlib_path" + } else { + setenv SHLIB_PATH "$ld_library_path" + } + if { $orig_ld_libraryn32_path_saved } { + setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_libraryn32_path" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARYN32_PATH "$ld_library_path" + } + if { $orig_ld_library64_path_saved } { + setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library64_path" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY64_PATH "$ld_library_path" + } + if { $orig_ld_library_path_32_saved } { + setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path_32" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH_32 "$ld_library_path" + } + if { $orig_ld_library_path_64_saved } { + setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path_64" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH_64 "$ld_library_path" + } + if { $orig_dyld_library_path_saved } { + setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path" + } else { + setenv DYLD_LIBRARY_PATH "$ld_library_path" + } + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + if { $orig_path_saved } { + setenv PATH "$ld_library_path:$orig_path" + } else { + setenv PATH "$ld_library_path" + } + } + + verbose -log "set_ld_library_path_env_vars: ld_library_path=$ld_library_path" +} + +####################################### +# proc restore_ld_library_path_env_vars { } +####################################### + +proc restore_ld_library_path_env_vars { } { + global orig_environment_saved + global orig_ld_library_path_saved + global orig_ld_run_path_saved + global orig_shlib_path_saved + global orig_ld_libraryn32_path_saved + global orig_ld_library64_path_saved + global orig_ld_library_path_32_saved + global orig_ld_library_path_64_saved + global orig_dyld_library_path_saved + global orig_path_saved + global orig_ld_library_path + global orig_ld_run_path + global orig_shlib_path + global orig_ld_libraryn32_path + global orig_ld_library64_path + global orig_ld_library_path_32 + global orig_ld_library_path_64 + global orig_dyld_library_path + global orig_path + + if { $orig_environment_saved == 0 } { + return + } + + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$orig_ld_library_path" + } elseif [info exists env(LD_LIBRARY_PATH)] { + unsetenv LD_LIBRARY_PATH + } + if { $orig_ld_run_path_saved } { + setenv LD_RUN_PATH "$orig_ld_run_path" + } elseif [info exists env(LD_RUN_PATH)] { + unsetenv LD_RUN_PATH + } + if { $orig_shlib_path_saved } { + setenv SHLIB_PATH "$orig_shlib_path" + } elseif [info exists env(SHLIB_PATH)] { + unsetenv SHLIB_PATH + } + if { $orig_ld_libraryn32_path_saved } { + setenv LD_LIBRARYN32_PATH "$orig_ld_libraryn32_path" + } elseif [info exists env(LD_LIBRARYN32_PATH)] { + unsetenv LD_LIBRARYN32_PATH + } + if { $orig_ld_library64_path_saved } { + setenv LD_LIBRARY64_PATH "$orig_ld_library64_path" + } elseif [info exists env(LD_LIBRARY64_PATH)] { + unsetenv LD_LIBRARY64_PATH + } + if { $orig_ld_library_path_32_saved } { + setenv LD_LIBRARY_PATH_32 "$orig_ld_library_path_32" + } elseif [info exists env(LD_LIBRARY_PATH_32)] { + unsetenv LD_LIBRARY_PATH_32 + } + if { $orig_ld_library_path_64_saved } { + setenv LD_LIBRARY_PATH_64 "$orig_ld_library_path_64" + } elseif [info exists env(LD_LIBRARY_PATH_64)] { + unsetenv LD_LIBRARY_PATH_64 + } + if { $orig_dyld_library_path_saved } { + setenv DYLD_LIBRARY_PATH "$orig_dyld_library_path" + } elseif [info exists env(DYLD_LIBRARY_PATH)] { + unsetenv DYLD_LIBRARY_PATH + } + if { $orig_path_saved } { + setenv PATH "$orig_path" + } elseif [info exists env(PATH)] { + unsetenv PATH + } +} + +####################################### +# proc get_shlib_extension { } +####################################### + +proc get_shlib_extension { } { + global shlib_ext + + if { [ istarget *-*-darwin* ] } { + set shlib_ext "dylib" + } elseif { [ istarget *-*-cygwin* ] || [ istarget *-*-mingw* ] } { + set shlib_ext "dll" + } elseif { [ istarget hppa*-*-hpux* ] } { + set shlib_ext "sl" + } else { + set shlib_ext "so" + } + return $shlib_ext +} + diff --git a/circuitpython/lib/libffi/testsuite/lib/wrapper.exp b/circuitpython/lib/libffi/testsuite/lib/wrapper.exp new file mode 100644 index 0000000..4e5ae43 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/lib/wrapper.exp @@ -0,0 +1,45 @@ +# Copyright (C) 2004, 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This file contains GCC-specifics for status wrappers for test programs. + +# ${tool}_maybe_build_wrapper -- Build wrapper object if the target +# needs it. FILENAME is the path to the wrapper file. If there are +# additional arguments, they are command-line options to provide to +# the compiler when compiling FILENAME. + +proc ${tool}_maybe_build_wrapper { filename args } { + global gluefile wrap_flags + + if { [target_info needs_status_wrapper] != "" \ + && [target_info needs_status_wrapper] != "0" \ + && ![info exists gluefile] } { + set saved_wrap_compile_flags [target_info wrap_compile_flags] + set flags [join $args " "] + # The wrapper code may contain code that gcc objects on. This + # became true for dejagnu-1.4.4. The set of warnings and code + # that gcc objects on may change, so just make sure -w is always + # passed to turn off all warnings. + set_currtarget_info wrap_compile_flags \ + "$saved_wrap_compile_flags -w $flags" + set result [build_wrapper $filename] + set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags" + if { $result != "" } { + set gluefile [lindex $result 0] + set wrap_flags [lindex $result 1] + } + } +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/call.exp b/circuitpython/lib/libffi/testsuite/libffi.call/call.exp new file mode 100644 index 0000000..46fb1eb --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/call.exp @@ -0,0 +1,30 @@ +# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# . + +dg-init +libffi-init + +global srcdir subdir + +set tlist [lsearch -inline -all -not -glob [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] *complex*] + +run-many-tests $tlist "" + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn0.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn0.c new file mode 100644 index 0000000..a579ff6 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn0.c @@ -0,0 +1,89 @@ +/* Area: closure_call + Purpose: Check multiple values passing from different type. + Also, exceed the limit of gpr and fpr registers on PowerPC + Darwin. + Limitations: none. + PR: none. + Originator: 20030828 */ + + + + +/* { dg-do run } */ +#include "ffitest.h" + +static void +closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) +{ + *(ffi_arg*)resp = + (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) + + (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] + + (int)(*(signed short *)args[4]) + + (int)(*(unsigned long long *)args[5]) + + (int)*(int *)args[6] + (int)(*(int *)args[7]) + + (int)(*(double *)args[8]) + (int)*(int *)args[9] + + (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + + (int)*(int *)args[12] + (int)(*(int *)args[13]) + + (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]), + (int)(*(unsigned long long *)args[2]), + (int)*(int *)args[3], (int)(*(signed short *)args[4]), + (int)(*(unsigned long long *)args[5]), + (int)*(int *)args[6], (int)(*(int *)args[7]), + (int)(*(double *)args[8]), (int)*(int *)args[9], + (int)(*(int *)args[10]), (int)(*(float *)args[11]), + (int)*(int *)args[12], (int)(*(int *)args[13]), + (int)(*(int *)args[14]),*(int *)args[15], + (int)(intptr_t)userdata, (int)*(ffi_arg *)resp); + +} + +typedef int (*closure_test_type0)(unsigned long long, int, unsigned long long, + int, signed short, unsigned long long, int, + int, double, int, int, float, int, int, + int, int); + +int main (void) +{ + ffi_cif cif; + void * code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + int res; + + cl_arg_types[0] = &ffi_type_uint64; + cl_arg_types[1] = &ffi_type_sint; + cl_arg_types[2] = &ffi_type_uint64; + cl_arg_types[3] = &ffi_type_sint; + cl_arg_types[4] = &ffi_type_sshort; + cl_arg_types[5] = &ffi_type_uint64; + cl_arg_types[6] = &ffi_type_sint; + cl_arg_types[7] = &ffi_type_sint; + cl_arg_types[8] = &ffi_type_double; + cl_arg_types[9] = &ffi_type_sint; + cl_arg_types[10] = &ffi_type_sint; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_sint; + cl_arg_types[14] = &ffi_type_sint; + cl_arg_types[15] = &ffi_type_sint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0, + (void *) 3 /* userdata */, code) == FFI_OK); + + res = (*((closure_test_type0)code)) + (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13, + 19, 21, 1); + /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 680" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn1.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn1.c new file mode 100644 index 0000000..9123173 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn1.c @@ -0,0 +1,81 @@ +/* Area: closure_call. + Purpose: Check multiple values passing from different type. + Also, exceed the limit of gpr and fpr registers on PowerPC + Darwin. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + + +static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) +{ + *(ffi_arg*)resp = + (int)*(float *)args[0] +(int)(*(float *)args[1]) + + (int)(*(float *)args[2]) + (int)*(float *)args[3] + + (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) + + (int)*(float *)args[6] + (int)(*(int *)args[7]) + + (int)(*(double*)args[8]) + (int)*(int *)args[9] + + (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + + (int)*(int *)args[12] + (int)(*(int *)args[13]) + + (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(float *)args[0], (int)(*(float *)args[1]), + (int)(*(float *)args[2]), (int)*(float *)args[3], + (int)(*(signed short *)args[4]), (int)(*(float *)args[5]), + (int)*(float *)args[6], (int)(*(int *)args[7]), + (int)(*(double *)args[8]), (int)*(int *)args[9], + (int)(*(int *)args[10]), (int)(*(float *)args[11]), + (int)*(int *)args[12], (int)(*(int *)args[13]), + (int)(*(int *)args[14]), *(int *)args[15], + (int)(intptr_t)userdata, (int)*(ffi_arg *)resp); +} + +typedef int (*closure_test_type1)(float, float, float, float, signed short, + float, float, int, double, int, int, float, + int, int, int, int); +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + int res; + + cl_arg_types[0] = &ffi_type_float; + cl_arg_types[1] = &ffi_type_float; + cl_arg_types[2] = &ffi_type_float; + cl_arg_types[3] = &ffi_type_float; + cl_arg_types[4] = &ffi_type_sshort; + cl_arg_types[5] = &ffi_type_float; + cl_arg_types[6] = &ffi_type_float; + cl_arg_types[7] = &ffi_type_sint; + cl_arg_types[8] = &ffi_type_double; + cl_arg_types[9] = &ffi_type_sint; + cl_arg_types[10] = &ffi_type_sint; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_sint; + cl_arg_types[14] = &ffi_type_sint; + cl_arg_types[15] = &ffi_type_sint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1, + (void *) 3 /* userdata */, code) == FFI_OK); + + res = (*((closure_test_type1)code)) + (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13, + 19, 21, 1); + /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 255" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn2.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn2.c new file mode 100644 index 0000000..08ff9d9 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn2.c @@ -0,0 +1,81 @@ +/* Area: closure_call + Purpose: Check multiple values passing from different type. + Also, exceed the limit of gpr and fpr registers on PowerPC + Darwin. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) +{ + *(ffi_arg*)resp = + (int)*(double *)args[0] +(int)(*(double *)args[1]) + + (int)(*(double *)args[2]) + (int)*(double *)args[3] + + (int)(*(signed short *)args[4]) + (int)(*(double *)args[5]) + + (int)*(double *)args[6] + (int)(*(int *)args[7]) + + (int)(*(double *)args[8]) + (int)*(int *)args[9] + + (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + + (int)*(int *)args[12] + (int)(*(float *)args[13]) + + (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(double *)args[0], (int)(*(double *)args[1]), + (int)(*(double *)args[2]), (int)*(double *)args[3], + (int)(*(signed short *)args[4]), (int)(*(double *)args[5]), + (int)*(double *)args[6], (int)(*(int *)args[7]), + (int)(*(double*)args[8]), (int)*(int *)args[9], + (int)(*(int *)args[10]), (int)(*(float *)args[11]), + (int)*(int *)args[12], (int)(*(float *)args[13]), + (int)(*(int *)args[14]), *(int *)args[15], (int)(intptr_t)userdata, + (int)*(ffi_arg *)resp); +} + +typedef int (*closure_test_type2)(double, double, double, double, signed short, + double, double, int, double, int, int, float, + int, float, int, int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + int res; + + cl_arg_types[0] = &ffi_type_double; + cl_arg_types[1] = &ffi_type_double; + cl_arg_types[2] = &ffi_type_double; + cl_arg_types[3] = &ffi_type_double; + cl_arg_types[4] = &ffi_type_sshort; + cl_arg_types[5] = &ffi_type_double; + cl_arg_types[6] = &ffi_type_double; + cl_arg_types[7] = &ffi_type_sint; + cl_arg_types[8] = &ffi_type_double; + cl_arg_types[9] = &ffi_type_sint; + cl_arg_types[10] = &ffi_type_sint; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_float; + cl_arg_types[14] = &ffi_type_sint; + cl_arg_types[15] = &ffi_type_sint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn2, + (void *) 3 /* userdata */, code) == FFI_OK); + + res = (*((closure_test_type2)code)) + (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13, + 19.0, 21, 1); + /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 255" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn3.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn3.c new file mode 100644 index 0000000..9b54d80 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn3.c @@ -0,0 +1,82 @@ +/* Area: closure_call + Purpose: Check multiple values passing from different type. + Also, exceed the limit of gpr and fpr registers on PowerPC + Darwin. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) + { + *(ffi_arg*)resp = + (int)*(float *)args[0] +(int)(*(float *)args[1]) + + (int)(*(float *)args[2]) + (int)*(float *)args[3] + + (int)(*(float *)args[4]) + (int)(*(float *)args[5]) + + (int)*(float *)args[6] + (int)(*(float *)args[7]) + + (int)(*(double *)args[8]) + (int)*(int *)args[9] + + (int)(*(float *)args[10]) + (int)(*(float *)args[11]) + + (int)*(int *)args[12] + (int)(*(float *)args[13]) + + (int)(*(float *)args[14]) + *(int *)args[15] + (intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(float *)args[0], (int)(*(float *)args[1]), + (int)(*(float *)args[2]), (int)*(float *)args[3], + (int)(*(float *)args[4]), (int)(*(float *)args[5]), + (int)*(float *)args[6], (int)(*(float *)args[7]), + (int)(*(double *)args[8]), (int)*(int *)args[9], + (int)(*(float *)args[10]), (int)(*(float *)args[11]), + (int)*(int *)args[12], (int)(*(float *)args[13]), + (int)(*(float *)args[14]), *(int *)args[15], (int)(intptr_t)userdata, + (int)*(ffi_arg *)resp); + + } + +typedef int (*closure_test_type3)(float, float, float, float, float, float, + float, float, double, int, float, float, int, + float, float, int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + int res; + + cl_arg_types[0] = &ffi_type_float; + cl_arg_types[1] = &ffi_type_float; + cl_arg_types[2] = &ffi_type_float; + cl_arg_types[3] = &ffi_type_float; + cl_arg_types[4] = &ffi_type_float; + cl_arg_types[5] = &ffi_type_float; + cl_arg_types[6] = &ffi_type_float; + cl_arg_types[7] = &ffi_type_float; + cl_arg_types[8] = &ffi_type_double; + cl_arg_types[9] = &ffi_type_sint; + cl_arg_types[10] = &ffi_type_float; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_float; + cl_arg_types[14] = &ffi_type_float; + cl_arg_types[15] = &ffi_type_sint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn3, + (void *) 3 /* userdata */, code) == FFI_OK); + + res = (*((closure_test_type3)code)) + (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13, + 19.19, 21.21, 1); + /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 19 21 1 3: 135" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 135" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn4.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn4.c new file mode 100644 index 0000000..d4a1530 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn4.c @@ -0,0 +1,89 @@ +/* Area: closure_call + Purpose: Check multiple long long values passing. + Also, exceed the limit of gpr and fpr registers on PowerPC + Darwin. + Limitations: none. + PR: none. + Originator: 20031026 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static void +closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) +{ + *(ffi_arg*)resp = + (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] + + (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] + + (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] + + (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] + + (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] + + (int)*(unsigned long long *)args[10] + + (int)*(unsigned long long *)args[11] + + (int)*(unsigned long long *)args[12] + + (int)*(unsigned long long *)args[13] + + (int)*(unsigned long long *)args[14] + + *(int *)args[15] + (intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(unsigned long long *)args[0], + (int)*(unsigned long long *)args[1], + (int)*(unsigned long long *)args[2], + (int)*(unsigned long long *)args[3], + (int)*(unsigned long long *)args[4], + (int)*(unsigned long long *)args[5], + (int)*(unsigned long long *)args[6], + (int)*(unsigned long long *)args[7], + (int)*(unsigned long long *)args[8], + (int)*(unsigned long long *)args[9], + (int)*(unsigned long long *)args[10], + (int)*(unsigned long long *)args[11], + (int)*(unsigned long long *)args[12], + (int)*(unsigned long long *)args[13], + (int)*(unsigned long long *)args[14], + *(int *)args[15], + (int)(intptr_t)userdata, (int)*(ffi_arg *)resp); + +} + +typedef int (*closure_test_type0)(unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + int i, res; + + for (i = 0; i < 15; i++) { + cl_arg_types[i] = &ffi_type_uint64; + } + cl_arg_types[15] = &ffi_type_sint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0, + (void *) 3 /* userdata */, code) == FFI_OK); + + res = (*((closure_test_type0)code)) + (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL, + 13LL, 19LL, 21LL, 1); + /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 680" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn5.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn5.c new file mode 100644 index 0000000..9907442 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn5.c @@ -0,0 +1,92 @@ +/* Area: closure_call + Purpose: Check multiple long long values passing. + Exceed the limit of gpr registers on PowerPC + Darwin. + Limitations: none. + PR: none. + Originator: 20031026 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void +closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) +{ + *(ffi_arg*)resp = + (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] + + (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] + + (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] + + (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] + + (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] + + (int)*(int *)args[10] + + (int)*(unsigned long long *)args[11] + + (int)*(unsigned long long *)args[12] + + (int)*(unsigned long long *)args[13] + + (int)*(unsigned long long *)args[14] + + *(int *)args[15] + (intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(unsigned long long *)args[0], + (int)*(unsigned long long *)args[1], + (int)*(unsigned long long *)args[2], + (int)*(unsigned long long *)args[3], + (int)*(unsigned long long *)args[4], + (int)*(unsigned long long *)args[5], + (int)*(unsigned long long *)args[6], + (int)*(unsigned long long *)args[7], + (int)*(unsigned long long *)args[8], + (int)*(unsigned long long *)args[9], + (int)*(int *)args[10], + (int)*(unsigned long long *)args[11], + (int)*(unsigned long long *)args[12], + (int)*(unsigned long long *)args[13], + (int)*(unsigned long long *)args[14], + *(int *)args[15], + (int)(intptr_t)userdata, (int)*(ffi_arg *)resp); + +} + +typedef int (*closure_test_type0)(unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, unsigned long long, + int, unsigned long long, + unsigned long long, unsigned long long, + unsigned long long, int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + int i, res; + + for (i = 0; i < 10; i++) { + cl_arg_types[i] = &ffi_type_uint64; + } + cl_arg_types[10] = &ffi_type_sint; + for (i = 11; i < 15; i++) { + cl_arg_types[i] = &ffi_type_uint64; + } + cl_arg_types[15] = &ffi_type_sint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn5, + (void *) 3 /* userdata */, code) == FFI_OK); + + res = (*((closure_test_type0)code)) + (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11, 12LL, + 13LL, 19LL, 21LL, 1); + /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 680" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn6.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn6.c new file mode 100644 index 0000000..73c54fd --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_fn6.c @@ -0,0 +1,90 @@ +/* Area: closure_call + Purpose: Check multiple values passing from different type. + Also, exceed the limit of gpr and fpr registers on PowerPC. + Limitations: none. + PR: PR23404 + Originator: 20050830 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void +closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) +{ + *(ffi_arg*)resp = + (int)*(unsigned long long *)args[0] + + (int)(*(unsigned long long *)args[1]) + + (int)(*(unsigned long long *)args[2]) + + (int)*(unsigned long long *)args[3] + + (int)(*(int *)args[4]) + (int)(*(double *)args[5]) + + (int)*(double *)args[6] + (int)(*(float *)args[7]) + + (int)(*(double *)args[8]) + (int)*(double *)args[9] + + (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + + (int)*(int *)args[12] + (int)(*(int *)args[13]) + + (int)(*(double *)args[14]) + (int)*(double *)args[15] + + (intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(unsigned long long *)args[0], + (int)(*(unsigned long long *)args[1]), + (int)(*(unsigned long long *)args[2]), + (int)*(unsigned long long *)args[3], + (int)(*(int *)args[4]), (int)(*(double *)args[5]), + (int)*(double *)args[6], (int)(*(float *)args[7]), + (int)(*(double *)args[8]), (int)*(double *)args[9], + (int)(*(int *)args[10]), (int)(*(float *)args[11]), + (int)*(int *)args[12], (int)(*(int *)args[13]), + (int)(*(double *)args[14]), (int)(*(double *)args[15]), + (int)(intptr_t)userdata, (int)*(ffi_arg *)resp); + +} + +typedef int (*closure_test_type0)(unsigned long long, + unsigned long long, + unsigned long long, + unsigned long long, + int, double, double, float, double, double, + int, float, int, int, double, double); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + int res; + + cl_arg_types[0] = &ffi_type_uint64; + cl_arg_types[1] = &ffi_type_uint64; + cl_arg_types[2] = &ffi_type_uint64; + cl_arg_types[3] = &ffi_type_uint64; + cl_arg_types[4] = &ffi_type_sint; + cl_arg_types[5] = &ffi_type_double; + cl_arg_types[6] = &ffi_type_double; + cl_arg_types[7] = &ffi_type_float; + cl_arg_types[8] = &ffi_type_double; + cl_arg_types[9] = &ffi_type_double; + cl_arg_types[10] = &ffi_type_sint; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_sint; + cl_arg_types[14] = &ffi_type_double; + cl_arg_types[15] = &ffi_type_double; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0, + (void *) 3 /* userdata */, code) == FFI_OK); + + res = (*((closure_test_type0)code)) + (1, 2, 3, 4, 127, 429., 7., 8., 9.5, 10., 11, 12., 13, + 19, 21., 1.); + /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 680" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_loc_fn0.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_loc_fn0.c new file mode 100644 index 0000000..b3afa0b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_loc_fn0.c @@ -0,0 +1,95 @@ +/* Area: closure_call + Purpose: Check multiple values passing from different type. + Also, exceed the limit of gpr and fpr registers on PowerPC + Darwin. + Limitations: none. + PR: none. + Originator: 20030828 */ + + + + +/* { dg-do run } */ +#include "ffitest.h" + +static void +closure_loc_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) +{ + *(ffi_arg*)resp = + (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) + + (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] + + (int)(*(signed short *)args[4]) + + (int)(*(unsigned long long *)args[5]) + + (int)*(int *)args[6] + (int)(*(int *)args[7]) + + (int)(*(double *)args[8]) + (int)*(int *)args[9] + + (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + + (int)*(int *)args[12] + (int)(*(int *)args[13]) + + (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]), + (int)(*(unsigned long long *)args[2]), + (int)*(int *)args[3], (int)(*(signed short *)args[4]), + (int)(*(unsigned long long *)args[5]), + (int)*(int *)args[6], (int)(*(int *)args[7]), + (int)(*(double *)args[8]), (int)*(int *)args[9], + (int)(*(int *)args[10]), (int)(*(float *)args[11]), + (int)*(int *)args[12], (int)(*(int *)args[13]), + (int)(*(int *)args[14]),*(int *)args[15], + (int)(intptr_t)userdata, (int)*(ffi_arg *)resp); + +} + +typedef int (*closure_loc_test_type0)(unsigned long long, int, unsigned long long, + int, signed short, unsigned long long, int, + int, double, int, int, float, int, int, + int, int); + +int main (void) +{ + ffi_cif cif; + ffi_closure *pcl; + ffi_type * cl_arg_types[17]; + int res; + void *codeloc; + + cl_arg_types[0] = &ffi_type_uint64; + cl_arg_types[1] = &ffi_type_sint; + cl_arg_types[2] = &ffi_type_uint64; + cl_arg_types[3] = &ffi_type_sint; + cl_arg_types[4] = &ffi_type_sshort; + cl_arg_types[5] = &ffi_type_uint64; + cl_arg_types[6] = &ffi_type_sint; + cl_arg_types[7] = &ffi_type_sint; + cl_arg_types[8] = &ffi_type_double; + cl_arg_types[9] = &ffi_type_sint; + cl_arg_types[10] = &ffi_type_sint; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_sint; + cl_arg_types[14] = &ffi_type_sint; + cl_arg_types[15] = &ffi_type_sint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + pcl = ffi_closure_alloc(sizeof(ffi_closure), &codeloc); + CHECK(pcl != NULL); + CHECK(codeloc != NULL); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_loc_test_fn0, + (void *) 3 /* userdata */, codeloc) == FFI_OK); + + CHECK(memcmp(pcl, codeloc, sizeof(*pcl)) == 0); + + res = (*((closure_loc_test_type0)codeloc)) + (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13, + 19, 21, 1); + /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 680" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/closure_simple.c b/circuitpython/lib/libffi/testsuite/libffi.call/closure_simple.c new file mode 100644 index 0000000..5a4e728 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/closure_simple.c @@ -0,0 +1,55 @@ +/* Area: closure_call + Purpose: Check simple closure handling with all ABIs + Limitations: none. + PR: none. + Originator: */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void +closure_test(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata) +{ + *(ffi_arg*)resp = + (int)*(int *)args[0] + (int)(*(int *)args[1]) + + (int)(*(int *)args[2]) + (int)(*(int *)args[3]) + + (int)(intptr_t)userdata; + + printf("%d %d %d %d: %d\n", + (int)*(int *)args[0], (int)(*(int *)args[1]), + (int)(*(int *)args[2]), (int)(*(int *)args[3]), + (int)*(ffi_arg *)resp); + +} + +typedef int (ABI_ATTR *closure_test_type0)(int, int, int, int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + int res; + + cl_arg_types[0] = &ffi_type_uint; + cl_arg_types[1] = &ffi_type_uint; + cl_arg_types[2] = &ffi_type_uint; + cl_arg_types[3] = &ffi_type_uint; + cl_arg_types[4] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test, + (void *) 3 /* userdata */, code) == FFI_OK); + + res = (*(closure_test_type0)code)(0, 1, 2, 3); + /* { dg-output "0 1 2 3: 9" } */ + + printf("res: %d\n",res); + /* { dg-output "\nres: 9" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_12byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_12byte.c new file mode 100644 index 0000000..ea0825d --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_12byte.c @@ -0,0 +1,94 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_12byte { + int a; + int b; + int c; +} cls_struct_12byte; + +cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1, + struct cls_struct_12byte b2) +{ + struct cls_struct_12byte result; + + result.a = b1.a + b2.a; + result.b = b1.b + b2.b; + result.c = b1.c + b2.c; + + printf("%d %d %d %d %d %d: %d %d %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c, + result.a, result.b, result.c); + + return result; +} + +static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args , void* userdata __UNUSED__) +{ + struct cls_struct_12byte b1, b2; + + b1 = *(struct cls_struct_12byte*)(args[0]); + b2 = *(struct cls_struct_12byte*)(args[1]); + + *(cls_struct_12byte*)resp = cls_struct_12byte_fn(b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_12byte h_dbl = { 7, 4, 9 }; + struct cls_struct_12byte j_dbl = { 1, 5, 3 }; + struct cls_struct_12byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_sint; + cls_struct_fields[1] = &ffi_type_sint; + cls_struct_fields[2] = &ffi_type_sint; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &h_dbl; + args_dbl[1] = &j_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_12byte_fn), &res_dbl, args_dbl); + /* { dg-output "7 4 9 1 5 3: 8 9 12" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 8 9 12" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_12byte_gn, NULL, code) == FFI_OK); + + res_dbl.a = 0; + res_dbl.b = 0; + res_dbl.c = 0; + + res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(code))(h_dbl, j_dbl); + /* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 8 9 12" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_16byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_16byte.c new file mode 100644 index 0000000..89a08a2 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_16byte.c @@ -0,0 +1,95 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_16byte { + int a; + double b; + int c; +} cls_struct_16byte; + +cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1, + struct cls_struct_16byte b2) +{ + struct cls_struct_16byte result; + + result.a = b1.a + b2.a; + result.b = b1.b + b2.b; + result.c = b1.c + b2.c; + + printf("%d %g %d %d %g %d: %d %g %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c, + result.a, result.b, result.c); + + return result; +} + +static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + struct cls_struct_16byte b1, b2; + + b1 = *(struct cls_struct_16byte*)(args[0]); + b2 = *(struct cls_struct_16byte*)(args[1]); + + *(cls_struct_16byte*)resp = cls_struct_16byte_fn(b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_16byte h_dbl = { 7, 8.0, 9 }; + struct cls_struct_16byte j_dbl = { 1, 9.0, 3 }; + struct cls_struct_16byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_sint; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_sint; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &h_dbl; + args_dbl[1] = &j_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl); + /* { dg-output "7 8 9 1 9 3: 8 17 12" } */ + printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 8 17 12" } */ + + res_dbl.a = 0; + res_dbl.b = 0.0; + res_dbl.c = 0; + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_16byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(code))(h_dbl, j_dbl); + /* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */ + printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 8 17 12" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_18byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_18byte.c new file mode 100644 index 0000000..9f75da8 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_18byte.c @@ -0,0 +1,96 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Double alignment check on darwin. + Limitations: none. + PR: none. + Originator: 20030915 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_18byte { + double a; + unsigned char b; + unsigned char c; + double d; +} cls_struct_18byte; + +cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1, + struct cls_struct_18byte a2) +{ + struct cls_struct_18byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + result.d = a1.d + a2.d; + + + printf("%g %d %d %g %g %d %d %g: %g %d %d %g\n", a1.a, a1.b, a1.c, a1.d, + a2.a, a2.b, a2.c, a2.d, + result.a, result.b, result.c, result.d); + return result; +} + +static void +cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_18byte a1, a2; + + a1 = *(struct cls_struct_18byte*)(args[0]); + a2 = *(struct cls_struct_18byte*)(args[1]); + + *(cls_struct_18byte*)resp = cls_struct_18byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[5]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[3]; + + struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 }; + struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 }; + struct cls_struct_18byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_18byte_fn), &res_dbl, args_dbl); + /* { dg-output "1 127 126 3 4 125 124 5: 5 252 250 8" } */ + printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 5 252 250 8" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_18byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */ + printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 5 252 250 8" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_19byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_19byte.c new file mode 100644 index 0000000..278794b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_19byte.c @@ -0,0 +1,102 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Double alignment check on darwin. + Limitations: none. + PR: none. + Originator: 20030915 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_19byte { + double a; + unsigned char b; + unsigned char c; + double d; + unsigned char e; +} cls_struct_19byte; + +cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1, + struct cls_struct_19byte a2) +{ + struct cls_struct_19byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + result.d = a1.d + a2.d; + result.e = a1.e + a2.e; + + + printf("%g %d %d %g %d %g %d %d %g %d: %g %d %d %g %d\n", + a1.a, a1.b, a1.c, a1.d, a1.e, + a2.a, a2.b, a2.c, a2.d, a2.e, + result.a, result.b, result.c, result.d, result.e); + return result; +} + +static void +cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_19byte a1, a2; + + a1 = *(struct cls_struct_19byte*)(args[0]); + a2 = *(struct cls_struct_19byte*)(args[1]); + + *(cls_struct_19byte*)resp = cls_struct_19byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[6]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[3]; + + struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 }; + struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 }; + struct cls_struct_19byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_uchar; + cls_struct_fields[5] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_19byte_fn), &res_dbl, args_dbl); + /* { dg-output "1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */ + printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e); + /* { dg-output "\nres: 5 252 250 8 239" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_19byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */ + printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e); + /* { dg-output "\nres: 5 252 250 8 239" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_1_1byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_1_1byte.c new file mode 100644 index 0000000..82492c0 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_1_1byte.c @@ -0,0 +1,89 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Especially with small structures which may fit in one + register. Depending on the ABI. + Limitations: none. + PR: none. + Originator: 20030902 */ + + + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_1_1byte { + unsigned char a; +} cls_struct_1_1byte; + +cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1, + struct cls_struct_1_1byte a2) +{ + struct cls_struct_1_1byte result; + + result.a = a1.a + a2.a; + + printf("%d %d: %d\n", a1.a, a2.a, result.a); + + return result; +} + +static void +cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_1_1byte a1, a2; + + a1 = *(struct cls_struct_1_1byte*)(args[0]); + a2 = *(struct cls_struct_1_1byte*)(args[1]); + + *(cls_struct_1_1byte*)resp = cls_struct_1_1byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[2]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_1_1byte g_dbl = { 12 }; + struct cls_struct_1_1byte f_dbl = { 178 }; + struct cls_struct_1_1byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl); + /* { dg-output "12 178: 190" } */ + printf("res: %d\n", res_dbl.a); + /* { dg-output "\nres: 190" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_1_1byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 178: 190" } */ + printf("res: %d\n", res_dbl.a); + /* { dg-output "\nres: 190" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_20byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_20byte.c new file mode 100644 index 0000000..3f8bb28 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_20byte.c @@ -0,0 +1,91 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_20byte { + double a; + double b; + int c; +} cls_struct_20byte; + +cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1, + struct cls_struct_20byte a2) +{ + struct cls_struct_20byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%g %g %d %g %g %d: %g %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, + result.a, result.b, result.c); + return result; +} + +static void +cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_20byte a1, a2; + + a1 = *(struct cls_struct_20byte*)(args[0]); + a2 = *(struct cls_struct_20byte*)(args[1]); + + *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 }; + struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 }; + struct cls_struct_20byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_sint; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl); + /* { dg-output "1 2 3 4 5 7: 5 7 10" } */ + printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 5 7 10" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */ + printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 5 7 10" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_20byte1.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_20byte1.c new file mode 100644 index 0000000..6562727 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_20byte1.c @@ -0,0 +1,93 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + + + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_20byte { + int a; + double b; + double c; +} cls_struct_20byte; + +cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1, + struct cls_struct_20byte a2) +{ + struct cls_struct_20byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %g %g %d %g %g: %d %g %g\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, + result.a, result.b, result.c); + return result; +} + +static void +cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_20byte a1, a2; + + a1 = *(struct cls_struct_20byte*)(args[0]); + a2 = *(struct cls_struct_20byte*)(args[1]); + + *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[3]; + + struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 }; + struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 }; + struct cls_struct_20byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_sint; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl); + /* { dg-output "1 2 3 4 5 7: 5 7 10" } */ + printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 5 7 10" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */ + printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 5 7 10" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_24byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_24byte.c new file mode 100644 index 0000000..1d82f6e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_24byte.c @@ -0,0 +1,113 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_24byte { + double a; + double b; + int c; + float d; +} cls_struct_24byte; + +cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0, + struct cls_struct_24byte b1, + struct cls_struct_24byte b2, + struct cls_struct_24byte b3) +{ + struct cls_struct_24byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + + printf("%g %g %d %g %g %g %d %g %g %g %d %g %g %g %d %g: %g %g %d %g\n", + b0.a, b0.b, b0.c, b0.d, + b1.a, b1.b, b1.c, b1.d, + b2.a, b2.b, b2.c, b2.d, + b3.a, b3.b, b3.c, b2.d, + result.a, result.b, result.c, result.d); + + return result; +} + +static void +cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_24byte b0, b1, b2, b3; + + b0 = *(struct cls_struct_24byte*)(args[0]); + b1 = *(struct cls_struct_24byte*)(args[1]); + b2 = *(struct cls_struct_24byte*)(args[2]); + b3 = *(struct cls_struct_24byte*)(args[3]); + + *(cls_struct_24byte*)resp = cls_struct_24byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[5]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 }; + struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 }; + struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 }; + struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 }; + struct cls_struct_24byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_sint; + cls_struct_fields[3] = &ffi_type_float; + cls_struct_fields[4] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_24byte_fn), &res_dbl, args_dbl); + /* { dg-output "9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */ + printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 22 15 17 25" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_24byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte, + cls_struct_24byte, + cls_struct_24byte, + cls_struct_24byte)) + (code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */ + printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 22 15 17 25" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_2byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_2byte.c new file mode 100644 index 0000000..81bb0a6 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_2byte.c @@ -0,0 +1,90 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Especially with small structures which may fit in one + register. Depending on the ABI. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_2byte { + unsigned char a; + unsigned char b; +} cls_struct_2byte; + +cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1, + struct cls_struct_2byte a2) +{ + struct cls_struct_2byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + + printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b); + + return result; +} + +static void +cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_2byte a1, a2; + + a1 = *(struct cls_struct_2byte*)(args[0]); + a2 = *(struct cls_struct_2byte*)(args[1]); + + *(cls_struct_2byte*)resp = cls_struct_2byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_2byte g_dbl = { 12, 127 }; + struct cls_struct_2byte f_dbl = { 1, 13 }; + struct cls_struct_2byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_2byte_fn), &res_dbl, args_dbl); + /* { dg-output "12 127 1 13: 13 140" } */ + printf("res: %d %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 13 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_2byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 127 1 13: 13 140" } */ + printf("res: %d %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 13 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_3_1byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_3_1byte.c new file mode 100644 index 0000000..b782746 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_3_1byte.c @@ -0,0 +1,95 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Especially with small structures which may fit in one + register. Depending on the ABI. + Limitations: none. + PR: none. + Originator: 20030902 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_3_1byte { + unsigned char a; + unsigned char b; + unsigned char c; +} cls_struct_3_1byte; + +cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1, + struct cls_struct_3_1byte a2) +{ + struct cls_struct_3_1byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, + a2.a, a2.b, a2.c, + result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_3_1byte a1, a2; + + a1 = *(struct cls_struct_3_1byte*)(args[0]); + a2 = *(struct cls_struct_3_1byte*)(args[1]); + + *(cls_struct_3_1byte*)resp = cls_struct_3_1byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_3_1byte g_dbl = { 12, 13, 14 }; + struct cls_struct_3_1byte f_dbl = { 178, 179, 180 }; + struct cls_struct_3_1byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_3_1byte_fn), &res_dbl, args_dbl); + /* { dg-output "12 13 14 178 179 180: 190 192 194" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 190 192 194" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3_1byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 190 192 194" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_3byte1.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_3byte1.c new file mode 100644 index 0000000..a02c463 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_3byte1.c @@ -0,0 +1,90 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Especially with small structures which may fit in one + register. Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_3byte { + unsigned short a; + unsigned char b; +} cls_struct_3byte; + +cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1, + struct cls_struct_3byte a2) +{ + struct cls_struct_3byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + + printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b); + + return result; +} + +static void +cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_3byte a1, a2; + + a1 = *(struct cls_struct_3byte*)(args[0]); + a2 = *(struct cls_struct_3byte*)(args[1]); + + *(cls_struct_3byte*)resp = cls_struct_3byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_3byte g_dbl = { 12, 119 }; + struct cls_struct_3byte f_dbl = { 1, 15 }; + struct cls_struct_3byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_ushort; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl); + /* { dg-output "12 119 1 15: 13 134" } */ + printf("res: %d %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 13 134" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 119 1 15: 13 134" } */ + printf("res: %d %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 13 134" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_3byte2.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_3byte2.c new file mode 100644 index 0000000..c7251ce --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_3byte2.c @@ -0,0 +1,90 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Especially with small structures which may fit in one + register. Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_3byte_1 { + unsigned char a; + unsigned short b; +} cls_struct_3byte_1; + +cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1, + struct cls_struct_3byte_1 a2) +{ + struct cls_struct_3byte_1 result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + + printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b); + + return result; +} + +static void +cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_3byte_1 a1, a2; + + a1 = *(struct cls_struct_3byte_1*)(args[0]); + a2 = *(struct cls_struct_3byte_1*)(args[1]); + + *(cls_struct_3byte_1*)resp = cls_struct_3byte_fn1(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_3byte_1 g_dbl = { 15, 125 }; + struct cls_struct_3byte_1 f_dbl = { 9, 19 }; + struct cls_struct_3byte_1 res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_ushort; + cls_struct_fields[2] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl); + /* { dg-output "15 125 9 19: 24 144" } */ + printf("res: %d %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 24 144" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn1, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(code))(g_dbl, f_dbl); + /* { dg-output "\n15 125 9 19: 24 144" } */ + printf("res: %d %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 24 144" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_4_1byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_4_1byte.c new file mode 100644 index 0000000..2d6d8b6 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_4_1byte.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Especially with small structures which may fit in one + register. Depending on the ABI. + Limitations: none. + PR: none. + Originator: 20030902 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_4_1byte { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; +} cls_struct_4_1byte; + +cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1, + struct cls_struct_4_1byte a2) +{ + struct cls_struct_4_1byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + result.d = a1.d + a2.d; + + printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d, + a2.a, a2.b, a2.c, a2.d, + result.a, result.b, result.c, result.d); + + return result; +} + +static void +cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_4_1byte a1, a2; + + a1 = *(struct cls_struct_4_1byte*)(args[0]); + a2 = *(struct cls_struct_4_1byte*)(args[1]); + + *(cls_struct_4_1byte*)resp = cls_struct_4_1byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[5]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 }; + struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 }; + struct cls_struct_4_1byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = &ffi_type_uchar; + cls_struct_fields[4] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl); + /* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */ + printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 190 192 194 196" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4_1byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */ + printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 190 192 194 196" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_4byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_4byte.c new file mode 100644 index 0000000..4ac3787 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_4byte.c @@ -0,0 +1,90 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +typedef struct cls_struct_4byte { + unsigned short a; + unsigned short b; +} cls_struct_4byte; + +cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1, + struct cls_struct_4byte a2) +{ + struct cls_struct_4byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + + printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b); + + return result; +} + +static void +cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_4byte a1, a2; + + a1 = *(struct cls_struct_4byte*)(args[0]); + a2 = *(struct cls_struct_4byte*)(args[1]); + + *(cls_struct_4byte*)resp = cls_struct_4byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_4byte g_dbl = { 127, 120 }; + struct cls_struct_4byte f_dbl = { 12, 128 }; + struct cls_struct_4byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_ushort; + cls_struct_fields[1] = &ffi_type_ushort; + cls_struct_fields[2] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_4byte_fn), &res_dbl, args_dbl); + /* { dg-output "127 120 12 128: 139 248" } */ + printf("res: %d %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 139 248" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n127 120 12 128: 139 248" } */ + printf("res: %d %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 139 248" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_5_1_byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_5_1_byte.c new file mode 100644 index 0000000..ad9d51c --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_5_1_byte.c @@ -0,0 +1,109 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20050708 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_5byte { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; +} cls_struct_5byte; + +cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1, + struct cls_struct_5byte a2) +{ + struct cls_struct_5byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + result.d = a1.d + a2.d; + result.e = a1.e + a2.e; + + printf("%d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d\n", + a1.a, a1.b, a1.c, a1.d, a1.e, + a2.a, a2.b, a2.c, a2.d, a2.e, + result.a, result.b, result.c, result.d, result.e); + + return result; +} + +static void +cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_5byte a1, a2; + + a1 = *(struct cls_struct_5byte*)(args[0]); + a2 = *(struct cls_struct_5byte*)(args[1]); + + *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[6]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 }; + struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 }; + struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 }; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = &ffi_type_uchar; + cls_struct_fields[4] = &ffi_type_uchar; + cls_struct_fields[5] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl); + /* { dg-output "127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */ + printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e); + /* { dg-output "\nres: 139 248 10 6 8" } */ + + res_dbl.a = 0; + res_dbl.b = 0; + res_dbl.c = 0; + res_dbl.d = 0; + res_dbl.e = 0; + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */ + printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e); + /* { dg-output "\nres: 139 248 10 6 8" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_5byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_5byte.c new file mode 100644 index 0000000..4e0c000 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_5byte.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_5byte { + unsigned short a; + unsigned short b; + unsigned char c; +} cls_struct_5byte; + +cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1, + struct cls_struct_5byte a2) +{ + struct cls_struct_5byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, + a2.a, a2.b, a2.c, + result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_5byte a1, a2; + + a1 = *(struct cls_struct_5byte*)(args[0]); + a2 = *(struct cls_struct_5byte*)(args[1]); + + *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_5byte g_dbl = { 127, 120, 1 }; + struct cls_struct_5byte f_dbl = { 12, 128, 9 }; + struct cls_struct_5byte res_dbl = { 0, 0, 0 }; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_ushort; + cls_struct_fields[1] = &ffi_type_ushort; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl); + /* { dg-output "127 120 1 12 128 9: 139 248 10" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 139 248 10" } */ + + res_dbl.a = 0; + res_dbl.b = 0; + res_dbl.c = 0; + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n127 120 1 12 128 9: 139 248 10" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 139 248 10" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_64byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_64byte.c new file mode 100644 index 0000000..a55edc2 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_64byte.c @@ -0,0 +1,124 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_64byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; +} cls_struct_64byte; + +cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0, + struct cls_struct_64byte b1, + struct cls_struct_64byte b2, + struct cls_struct_64byte b3) +{ + struct cls_struct_64byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + + printf("%g %g %g %g %g %g %g %g\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h); + + return result; +} + +static void +cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_64byte b0, b1, b2, b3; + + b0 = *(struct cls_struct_64byte*)(args[0]); + b1 = *(struct cls_struct_64byte*)(args[1]); + b2 = *(struct cls_struct_64byte*)(args[2]); + b3 = *(struct cls_struct_64byte*)(args[3]); + + *(cls_struct_64byte*)resp = cls_struct_64byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[9]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 }; + struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 }; + struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 }; + struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 }; + struct cls_struct_64byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_64byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18" } */ + printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_64byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_64byte(*)(cls_struct_64byte, + cls_struct_64byte, + cls_struct_64byte, + cls_struct_64byte)) + (code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18" } */ + printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_6_1_byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_6_1_byte.c new file mode 100644 index 0000000..b4dcdba --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_6_1_byte.c @@ -0,0 +1,113 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20050708 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_6byte { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; +} cls_struct_6byte; + +cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1, + struct cls_struct_6byte a2) +{ + struct cls_struct_6byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + result.d = a1.d + a2.d; + result.e = a1.e + a2.e; + result.f = a1.f + a2.f; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d\n", + a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, + a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, + result.a, result.b, result.c, result.d, result.e, result.f); + + return result; +} + +static void +cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_6byte a1, a2; + + a1 = *(struct cls_struct_6byte*)(args[0]); + a2 = *(struct cls_struct_6byte*)(args[1]); + + *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[7]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 }; + struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 }; + struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 }; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = &ffi_type_uchar; + cls_struct_fields[4] = &ffi_type_uchar; + cls_struct_fields[5] = &ffi_type_uchar; + cls_struct_fields[6] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl); + /* { dg-output "127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */ + printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f); + /* { dg-output "\nres: 139 248 10 6 8 10" } */ + + res_dbl.a = 0; + res_dbl.b = 0; + res_dbl.c = 0; + res_dbl.d = 0; + res_dbl.e = 0; + res_dbl.f = 0; + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */ + printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f); + /* { dg-output "\nres: 139 248 10 6 8 10" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_6byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_6byte.c new file mode 100644 index 0000000..7406780 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_6byte.c @@ -0,0 +1,99 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_6byte { + unsigned short a; + unsigned short b; + unsigned char c; + unsigned char d; +} cls_struct_6byte; + +cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1, + struct cls_struct_6byte a2) +{ + struct cls_struct_6byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + result.d = a1.d + a2.d; + + printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d, + a2.a, a2.b, a2.c, a2.d, + result.a, result.b, result.c, result.d); + + return result; +} + +static void +cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_6byte a1, a2; + + a1 = *(struct cls_struct_6byte*)(args[0]); + a2 = *(struct cls_struct_6byte*)(args[1]); + + *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[5]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 }; + struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 }; + struct cls_struct_6byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_ushort; + cls_struct_fields[1] = &ffi_type_ushort; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = &ffi_type_uchar; + cls_struct_fields[4] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl); + /* { dg-output "127 120 1 128 12 128 9 127: 139 248 10 255" } */ + printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 139 248 10 255" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n127 120 1 128 12 128 9 127: 139 248 10 255" } */ + printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 139 248 10 255" } */ + + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_7_1_byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_7_1_byte.c new file mode 100644 index 0000000..14a7e96 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_7_1_byte.c @@ -0,0 +1,117 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20050708 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_7byte { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; +} cls_struct_7byte; + +cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1, + struct cls_struct_7byte a2) +{ + struct cls_struct_7byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + result.d = a1.d + a2.d; + result.e = a1.e + a2.e; + result.f = a1.f + a2.f; + result.g = a1.g + a2.g; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d %d\n", + a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g, + a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g, + result.a, result.b, result.c, result.d, result.e, result.f, result.g); + + return result; +} + +static void +cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_7byte a1, a2; + + a1 = *(struct cls_struct_7byte*)(args[0]); + a2 = *(struct cls_struct_7byte*)(args[1]); + + *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[8]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 }; + struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 }; + struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 }; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = &ffi_type_uchar; + cls_struct_fields[4] = &ffi_type_uchar; + cls_struct_fields[5] = &ffi_type_uchar; + cls_struct_fields[6] = &ffi_type_uchar; + cls_struct_fields[7] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl); + /* { dg-output "127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */ + printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g); + /* { dg-output "\nres: 139 248 10 6 8 10 12" } */ + + res_dbl.a = 0; + res_dbl.b = 0; + res_dbl.c = 0; + res_dbl.d = 0; + res_dbl.e = 0; + res_dbl.f = 0; + res_dbl.g = 0; + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */ + printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g); + /* { dg-output "\nres: 139 248 10 6 8 10 12" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_7byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_7byte.c new file mode 100644 index 0000000..1645cc6 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_7byte.c @@ -0,0 +1,97 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_7byte { + unsigned short a; + unsigned short b; + unsigned char c; + unsigned short d; +} cls_struct_7byte; + +cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1, + struct cls_struct_7byte a2) +{ + struct cls_struct_7byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + result.d = a1.d + a2.d; + + printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d, + a2.a, a2.b, a2.c, a2.d, + result.a, result.b, result.c, result.d); + + return result; +} + +static void +cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_7byte a1, a2; + + a1 = *(struct cls_struct_7byte*)(args[0]); + a2 = *(struct cls_struct_7byte*)(args[1]); + + *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[5]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 }; + struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 }; + struct cls_struct_7byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_ushort; + cls_struct_fields[1] = &ffi_type_ushort; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = &ffi_type_ushort; + cls_struct_fields[4] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl); + /* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */ + printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 139 248 10 509" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */ + printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); + /* { dg-output "\nres: 139 248 10 509" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_8byte.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_8byte.c new file mode 100644 index 0000000..f6c1ea5 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_8byte.c @@ -0,0 +1,88 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_8byte { + int a; + float b; +} cls_struct_8byte; + +cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1, + struct cls_struct_8byte a2) +{ + struct cls_struct_8byte result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + + printf("%d %g %d %g: %d %g\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b); + + return result; +} + +static void +cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_8byte a1, a2; + + a1 = *(struct cls_struct_8byte*)(args[0]); + a2 = *(struct cls_struct_8byte*)(args[1]); + + *(cls_struct_8byte*)resp = cls_struct_8byte_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_8byte g_dbl = { 1, 2.0 }; + struct cls_struct_8byte f_dbl = { 4, 5.0 }; + struct cls_struct_8byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_sint; + cls_struct_fields[1] = &ffi_type_float; + cls_struct_fields[2] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_8byte_fn), &res_dbl, args_dbl); + /* { dg-output "1 2 4 5: 5 7" } */ + printf("res: %d %g\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 5 7" } */ + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_8byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(code))(g_dbl, f_dbl); + /* { dg-output "\n1 2 4 5: 5 7" } */ + printf("res: %d %g\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 5 7" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_9byte1.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_9byte1.c new file mode 100644 index 0000000..0b85722 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_9byte1.c @@ -0,0 +1,90 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Darwin/AIX do double-word + alignment of the struct if the first element is a double. + Check that it does not here. + Limitations: none. + PR: none. + Originator: 20030914 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_9byte { + int a; + double b; +} cls_struct_9byte; + +cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1, + struct cls_struct_9byte b2) +{ + struct cls_struct_9byte result; + + result.a = b1.a + b2.a; + result.b = b1.b + b2.b; + + printf("%d %g %d %g: %d %g\n", b1.a, b1.b, b2.a, b2.b, + result.a, result.b); + + return result; +} + +static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + struct cls_struct_9byte b1, b2; + + b1 = *(struct cls_struct_9byte*)(args[0]); + b2 = *(struct cls_struct_9byte*)(args[1]); + + *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[3]; + + struct cls_struct_9byte h_dbl = { 7, 8.0}; + struct cls_struct_9byte j_dbl = { 1, 9.0}; + struct cls_struct_9byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_sint; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &h_dbl; + args_dbl[1] = &j_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl); + /* { dg-output "7 8 1 9: 8 17" } */ + printf("res: %d %g\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 8 17" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl); + /* { dg-output "\n7 8 1 9: 8 17" } */ + printf("res: %d %g\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 8 17" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_9byte2.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_9byte2.c new file mode 100644 index 0000000..edf991d --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_9byte2.c @@ -0,0 +1,91 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Darwin/AIX do double-word + alignment of the struct if the first element is a double. + Check that it does here. + Limitations: none. + PR: none. + Originator: 20030914 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_9byte { + double a; + int b; +} cls_struct_9byte; + +cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1, + struct cls_struct_9byte b2) +{ + struct cls_struct_9byte result; + + result.a = b1.a + b2.a; + result.b = b1.b + b2.b; + + printf("%g %d %g %d: %g %d\n", b1.a, b1.b, b2.a, b2.b, + result.a, result.b); + + return result; +} + +static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + struct cls_struct_9byte b1, b2; + + b1 = *(struct cls_struct_9byte*)(args[0]); + b2 = *(struct cls_struct_9byte*)(args[1]); + + *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[3]; + + struct cls_struct_9byte h_dbl = { 7.0, 8}; + struct cls_struct_9byte j_dbl = { 1.0, 9}; + struct cls_struct_9byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_sint; + cls_struct_fields[2] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &h_dbl; + args_dbl[1] = &j_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl); + /* { dg-output "7 8 1 9: 8 17" } */ + printf("res: %g %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 8 17" } */ + + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl); + /* { dg-output "\n7 8 1 9: 8 17" } */ + printf("res: %g %d\n", res_dbl.a, res_dbl.b); + /* { dg-output "\nres: 8 17" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_double.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_double.c new file mode 100644 index 0000000..aad5f3c --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_double.c @@ -0,0 +1,93 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of double. + Limitations: none. + PR: none. + Originator: 20031203 */ + + + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + double b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_float.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_float.c new file mode 100644 index 0000000..37e0855 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_float.c @@ -0,0 +1,91 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of float. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + float b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_float; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble.c new file mode 100644 index 0000000..b3322d8 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble.c @@ -0,0 +1,92 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of long double. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + long double b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_longdouble; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble_split.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble_split.c new file mode 100644 index 0000000..cc1c43b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble_split.c @@ -0,0 +1,132 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of long double. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ + +#include "ffitest.h" + +typedef struct cls_struct_align { + long double a; + long double b; + long double c; + long double d; + long double e; + long double f; + long double g; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn( + cls_struct_align a1, + cls_struct_align a2) +{ + struct cls_struct_align r; + + r.a = a1.a + a2.a; + r.b = a1.b + a2.b; + r.c = a1.c + a2.c; + r.d = a1.d + a2.d; + r.e = a1.e + a2.e; + r.f = a1.f + a2.f; + r.g = a1.g + a2.g; + + printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: " + "%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", + a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g, + a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g, + r.a, r.b, r.c, r.d, r.e, r.f, r.g); + + return r; +} + +cls_struct_align cls_struct_align_fn2( + cls_struct_align a1) +{ + struct cls_struct_align r; + + r.a = a1.a + 1; + r.b = a1.b + 1; + r.c = a1.c + 1; + r.d = a1.d + 1; + r.e = a1.e + 1; + r.f = a1.f + 1; + r.g = a1.g + 1; + + printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg: " + "%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", + a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g, + r.a, r.b, r.c, r.d, r.e, r.f, r.g); + + return r; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[8]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[3]; + + struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 }; + struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_longdouble; + cls_struct_fields[1] = &ffi_type_longdouble; + cls_struct_fields[2] = &ffi_type_longdouble; + cls_struct_fields[3] = &ffi_type_longdouble; + cls_struct_fields[4] = &ffi_type_longdouble; + cls_struct_fields[5] = &ffi_type_longdouble; + cls_struct_fields[6] = &ffi_type_longdouble; + cls_struct_fields[7] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */ + printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g); + /* { dg-output "\nres: 9 11 13 15 17 19 21" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */ + printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g); + /* { dg-output "\nres: 9 11 13 15 17 19 21" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c new file mode 100644 index 0000000..5d3bec0 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c @@ -0,0 +1,115 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of long double. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/18/2007 +*/ + +/* { dg-do run { xfail strongarm*-*-* } } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ + +#include "ffitest.h" + +typedef struct cls_struct_align { + long double a; + long double b; + long double c; + long double d; + long double e; + double f; + long double g; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn( + cls_struct_align a1, + cls_struct_align a2) +{ + struct cls_struct_align r; + + r.a = a1.a + a2.a; + r.b = a1.b + a2.b; + r.c = a1.c + a2.c; + r.d = a1.d + a2.d; + r.e = a1.e + a2.e; + r.f = a1.f + a2.f; + r.g = a1.g + a2.g; + + printf("%Lg %Lg %Lg %Lg %Lg %g %Lg %Lg %Lg %Lg %Lg %Lg %g %Lg: " + "%Lg %Lg %Lg %Lg %Lg %g %Lg\n", + a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g, + a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g, + r.a, r.b, r.c, r.d, r.e, r.f, r.g); + + return r; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[8]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[3]; + + struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 }; + struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_longdouble; + cls_struct_fields[1] = &ffi_type_longdouble; + cls_struct_fields[2] = &ffi_type_longdouble; + cls_struct_fields[3] = &ffi_type_longdouble; + cls_struct_fields[4] = &ffi_type_longdouble; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_longdouble; + cls_struct_fields[7] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */ + printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g); + /* { dg-output "\nres: 9 11 13 15 17 19 21" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */ + printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g); + /* { dg-output "\nres: 9 11 13 15 17 19 21" } */ + + exit(0); +} + + + diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_pointer.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_pointer.c new file mode 100644 index 0000000..8fbf36a --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_pointer.c @@ -0,0 +1,95 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of pointer. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + void *b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = (void *)((uintptr_t)a1.b + (uintptr_t)a2.b); + result.c = a1.c + a2.c; + + printf("%d %" PRIuPTR " %d %d %" PRIuPTR " %d: %d %" PRIuPTR " %d\n", + a1.a, (uintptr_t)a1.b, a1.c, + a2.a, (uintptr_t)a2.b, a2.c, + result.a, (uintptr_t)result.b, + result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, (void *)4951, 127 }; + struct cls_struct_align f_dbl = { 1, (void *)9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_pointer; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint16.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint16.c new file mode 100644 index 0000000..039b874 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint16.c @@ -0,0 +1,91 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of sint16. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + signed short b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_sshort; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint32.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint32.c new file mode 100644 index 0000000..c96c6d1 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint32.c @@ -0,0 +1,91 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of sint32. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + signed int b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_sint; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint64.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint64.c new file mode 100644 index 0000000..9aa7bdd --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_sint64.c @@ -0,0 +1,92 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of sint64. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + signed long long b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_sint64; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint16.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint16.c new file mode 100644 index 0000000..97620b7 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint16.c @@ -0,0 +1,91 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of uint16. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + unsigned short b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_ushort; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint32.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint32.c new file mode 100644 index 0000000..5766fad --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint32.c @@ -0,0 +1,91 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of uint32. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + unsigned int b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uint; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint64.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint64.c new file mode 100644 index 0000000..a52cb89 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_align_uint64.c @@ -0,0 +1,93 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of uint64. + Limitations: none. + PR: none. + Originator: 20031203 */ + + +/* { dg-do run } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ +#include "ffitest.h" + +typedef struct cls_struct_align { + unsigned char a; + unsigned long long b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, + struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uint64; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &g_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); + /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl); + /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ + printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_dbls_struct.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_dbls_struct.c new file mode 100644 index 0000000..d663791 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_dbls_struct.c @@ -0,0 +1,66 @@ +/* Area: ffi_call, closure_call + Purpose: Check double arguments in structs. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/23/2007 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +typedef struct Dbls { + double x; + double y; +} Dbls; + +void +closure_test_fn(Dbls p) +{ + printf("%.1f %.1f\n", p.x, p.y); +} + +void +closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args, void* userdata __UNUSED__) +{ + closure_test_fn(*(Dbls*)args[0]); +} + +int main(int argc __UNUSED__, char** argv __UNUSED__) +{ + ffi_cif cif; + + void *code; + ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type* cl_arg_types[1]; + + ffi_type ts1_type; + ffi_type* ts1_type_elements[4]; + + Dbls arg = { 1.0, 2.0 }; + + ts1_type.size = 0; + ts1_type.alignment = 0; + ts1_type.type = FFI_TYPE_STRUCT; + ts1_type.elements = ts1_type_elements; + + ts1_type_elements[0] = &ffi_type_double; + ts1_type_elements[1] = &ffi_type_double; + ts1_type_elements[2] = NULL; + + cl_arg_types[0] = &ts1_type; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_void, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK); + + ((void*(*)(Dbls))(code))(arg); + /* { dg-output "1.0 2.0\n" } */ + + closure_test_fn(arg); + /* { dg-output "1.0 2.0\n" } */ + + return 0; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_double.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_double.c new file mode 100644 index 0000000..84ad4cb --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_double.c @@ -0,0 +1,43 @@ +/* Area: closure_call + Purpose: Check return value double. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(double *)resp = *(double *)args[0]; + + printf("%f: %f\n",*(double *)args[0], + *(double *)resp); + } +typedef double (*cls_ret_double)(double); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + double res; + + cl_arg_types[0] = &ffi_type_double; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_double, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_double)code))(21474.789); + /* { dg-output "21474.789000: 21474.789000" } */ + printf("res: %.6f\n", res); + /* { dg-output "\nres: 21474.789000" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_double_va.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_double_va.c new file mode 100644 index 0000000..e077f92 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_double_va.c @@ -0,0 +1,61 @@ +/* Area: ffi_call, closure_call + Purpose: Test doubles passed in variable argument lists. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/6/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-output "" { xfail avr32*-*-* } } */ +/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */ + +#include "ffitest.h" + +static void +cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + char* format = *(char**)args[0]; + double doubleValue = *(double*)args[1]; + + *(ffi_arg*)resp = printf(format, doubleValue); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[3]; + ffi_type* arg_types[3]; + + char* format = "%.1f\n"; + double doubleArg = 7; + ffi_arg res = 0; + + arg_types[0] = &ffi_type_pointer; + arg_types[1] = &ffi_type_double; + arg_types[2] = NULL; + + /* This printf call is variadic */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, + arg_types) == FFI_OK); + + args[0] = &format; + args[1] = &doubleArg; + args[2] = NULL; + + ffi_call(&cif, FFI_FN(printf), &res, args); + /* { dg-output "7.0" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 4" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, + code) == FFI_OK); + + res = ((int(*)(char*, ...))(code))(format, doubleArg); + /* { dg-output "\n7.0" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 4" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_float.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_float.c new file mode 100644 index 0000000..0090fed --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_float.c @@ -0,0 +1,42 @@ +/* Area: closure_call + Purpose: Check return value float. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(float *)resp = *(float *)args[0]; + + printf("%g: %g\n",*(float *)args[0], + *(float *)resp); + } + +typedef float (*cls_ret_float)(float); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + float res; + + cl_arg_types[0] = &ffi_type_float; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_float, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_float_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_float)code)(-2122.12))); + /* { dg-output "\\-2122.12: \\-2122.12" } */ + printf("res: %.6f\n", res); + /* { dg-output "\nres: \-2122.120117" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_longdouble.c new file mode 100644 index 0000000..d24e72e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_longdouble.c @@ -0,0 +1,105 @@ +/* Area: ffi_call, closure_call + Purpose: Check long double arguments. + Limitations: none. + PR: none. + Originator: Blake Chaffin */ + +/* This test is known to PASS on armv7l-unknown-linux-gnueabihf, so I have + remove the xfail for arm*-*-* below, until we know more. */ +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ + +#include "ffitest.h" + +long double cls_ldouble_fn( + long double a1, + long double a2, + long double a3, + long double a4, + long double a5, + long double a6, + long double a7, + long double a8) +{ + long double r = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8; + + printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: %Lg\n", + a1, a2, a3, a4, a5, a6, a7, a8, r); + + return r; +} + +static void +cls_ldouble_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + long double a1 = *(long double*)args[0]; + long double a2 = *(long double*)args[1]; + long double a3 = *(long double*)args[2]; + long double a4 = *(long double*)args[3]; + long double a5 = *(long double*)args[4]; + long double a6 = *(long double*)args[5]; + long double a7 = *(long double*)args[6]; + long double a8 = *(long double*)args[7]; + + *(long double*)resp = cls_ldouble_fn( + a1, a2, a3, a4, a5, a6, a7, a8); +} + +int main(void) +{ + ffi_cif cif; + void* code; + ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[9]; + ffi_type* arg_types[9]; + long double res = 0; + + long double arg1 = 1; + long double arg2 = 2; + long double arg3 = 3; + long double arg4 = 4; + long double arg5 = 5; + long double arg6 = 6; + long double arg7 = 7; + long double arg8 = 8; + + arg_types[0] = &ffi_type_longdouble; + arg_types[1] = &ffi_type_longdouble; + arg_types[2] = &ffi_type_longdouble; + arg_types[3] = &ffi_type_longdouble; + arg_types[4] = &ffi_type_longdouble; + arg_types[5] = &ffi_type_longdouble; + arg_types[6] = &ffi_type_longdouble; + arg_types[7] = &ffi_type_longdouble; + arg_types[8] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 8, &ffi_type_longdouble, + arg_types) == FFI_OK); + + args[0] = &arg1; + args[1] = &arg2; + args[2] = &arg3; + args[3] = &arg4; + args[4] = &arg5; + args[5] = &arg6; + args[6] = &arg7; + args[7] = &arg8; + args[8] = NULL; + + ffi_call(&cif, FFI_FN(cls_ldouble_fn), &res, args); + /* { dg-output "1 2 3 4 5 6 7 8: 36" } */ + printf("res: %Lg\n", res); + /* { dg-output "\nres: 36" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ldouble_gn, NULL, code) == FFI_OK); + + res = ((long double(*)(long double, long double, long double, long double, + long double, long double, long double, long double))(code))(arg1, arg2, + arg3, arg4, arg5, arg6, arg7, arg8); + /* { dg-output "\n1 2 3 4 5 6 7 8: 36" } */ + printf("res: %Lg\n", res); + /* { dg-output "\nres: 36" } */ + + return 0; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_longdouble_va.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_longdouble_va.c new file mode 100644 index 0000000..39b438b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_longdouble_va.c @@ -0,0 +1,61 @@ +/* Area: ffi_call, closure_call + Purpose: Test long doubles passed in variable argument lists. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/6/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */ +/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */ + +#include "ffitest.h" + +static void +cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + char* format = *(char**)args[0]; + long double ldValue = *(long double*)args[1]; + + *(ffi_arg*)resp = printf(format, ldValue); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[3]; + ffi_type* arg_types[3]; + + char* format = "%.1Lf\n"; + long double ldArg = 7; + ffi_arg res = 0; + + arg_types[0] = &ffi_type_pointer; + arg_types[1] = &ffi_type_longdouble; + arg_types[2] = NULL; + + /* This printf call is variadic */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, + arg_types) == FFI_OK); + + args[0] = &format; + args[1] = &ldArg; + args[2] = NULL; + + ffi_call(&cif, FFI_FN(printf), &res, args); + /* { dg-output "7.0" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 4" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, + code) == FFI_OK); + + res = ((int(*)(char*, ...))(code))(format, ldArg); + /* { dg-output "\n7.0" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 4" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_many_mixed_args.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_many_mixed_args.c new file mode 100644 index 0000000..7fd6c82 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_many_mixed_args.c @@ -0,0 +1,70 @@ +/* Area: closure_call + Purpose: Check closures called with many args of mixed types + Limitations: none. + PR: none. + Originator: */ + +/* { dg-do run } */ +#include "ffitest.h" +#include +#include + +#define NARGS 16 + +static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + int i; + double r = 0; + double t; + for(i = 0; i < NARGS; i++) + { + if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15) + { + t = *(long int *)args[i]; + CHECK(t == i+1); + } + else + { + t = *(double *)args[i]; + CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON); + } + r += t; + } + *(double *)resp = r; +} +typedef double (*cls_ret_double)(double, double, double, double, long int, +double, double, double, double, long int, double, long int, double, long int, +double, long int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[NARGS]; + double res; + int i; + double expected = 64.9; + + for(i = 0; i < NARGS; i++) + { + if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15) + cl_arg_types[i] = &ffi_type_slong; + else + cl_arg_types[i] = &ffi_type_double; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS, + &ffi_type_double, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK); + + res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10, + 1.1, 12, 1.3, 14, 1.5, 16); + if (fabs(res - expected) < FLT_EPSILON) + exit(0); + else + abort(); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c new file mode 100644 index 0000000..62b0697 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c @@ -0,0 +1,55 @@ +/* Area: closure_call + Purpose: Check register allocation for closure calls with many float and double arguments + Limitations: none. + PR: none. + Originator: */ + +/* { dg-do run } */ +#include "ffitest.h" +#include +#include + +#define NARGS 16 + +static void cls_mixed_float_double_fn(ffi_cif* cif , void* ret, void** args, + void* userdata __UNUSED__) +{ + double r = 0; + unsigned int i; + double t; + for(i=0; i < cif->nargs; i++) + { + if(cif->arg_types[i] == &ffi_type_double) { + t = *(((double**)(args))[i]); + } else { + t = *(((float**)(args))[i]); + } + r += t; + } + *((double*)ret) = r; +} +typedef double (*cls_mixed)(double, float, double, double, double, double, double, float, float, double, float, float); + +int main (void) +{ + ffi_cif cif; + ffi_closure *closure; + void* code; + ffi_type *argtypes[12] = {&ffi_type_double, &ffi_type_float, &ffi_type_double, + &ffi_type_double, &ffi_type_double, &ffi_type_double, + &ffi_type_double, &ffi_type_float, &ffi_type_float, + &ffi_type_double, &ffi_type_float, &ffi_type_float}; + + + closure = ffi_closure_alloc(sizeof(ffi_closure), (void**)&code); + if(closure ==NULL) + abort(); + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, argtypes) == FFI_OK); + CHECK(ffi_prep_closure_loc(closure, &cif, cls_mixed_float_double_fn, NULL, code) == FFI_OK); + double ret = ((cls_mixed)code)(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2); + ffi_closure_free(closure); + if(fabs(ret - 7.8) < FLT_EPSILON) + exit(0); + else + abort(); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_schar.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_schar.c new file mode 100644 index 0000000..71df7b6 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_schar.c @@ -0,0 +1,74 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple signed char values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run } */ +#include "ffitest.h" + +signed char test_func_fn(signed char a1, signed char a2) +{ + signed char result; + + result = a1 + a2; + + printf("%d %d: %d\n", a1, a2, result); + + return result; + +} + +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) +{ + signed char a1, a2; + + a1 = *(signed char *)avals[0]; + a2 = *(signed char *)avals[1]; + + *(ffi_arg *)rval = test_func_fn(a1, a2); + +} + +typedef signed char (*test_type)(signed char, signed char); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void * args_dbl[3]; + ffi_type * cl_arg_types[3]; + ffi_arg res_call; + signed char a, b, res_closure; + + a = 2; + b = 125; + + args_dbl[0] = &a; + args_dbl[1] = &b; + args_dbl[2] = NULL; + + cl_arg_types[0] = &ffi_type_schar; + cl_arg_types[1] = &ffi_type_schar; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, + &ffi_type_schar, cl_arg_types) == FFI_OK); + + ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); + /* { dg-output "2 125: 127" } */ + printf("res: %d\n", (signed char)res_call); + /* { dg-output "\nres: 127" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); + + res_closure = (*((test_type)code))(2, 125); + /* { dg-output "\n2 125: 127" } */ + printf("res: %d\n", res_closure); + /* { dg-output "\nres: 127" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_sshort.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_sshort.c new file mode 100644 index 0000000..4c39153 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_sshort.c @@ -0,0 +1,74 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple signed short values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run } */ +#include "ffitest.h" + +signed short test_func_fn(signed short a1, signed short a2) +{ + signed short result; + + result = a1 + a2; + + printf("%d %d: %d\n", a1, a2, result); + + return result; + +} + +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) +{ + signed short a1, a2; + + a1 = *(signed short *)avals[0]; + a2 = *(signed short *)avals[1]; + + *(ffi_arg *)rval = test_func_fn(a1, a2); + +} + +typedef signed short (*test_type)(signed short, signed short); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void * args_dbl[3]; + ffi_type * cl_arg_types[3]; + ffi_arg res_call; + unsigned short a, b, res_closure; + + a = 2; + b = 32765; + + args_dbl[0] = &a; + args_dbl[1] = &b; + args_dbl[2] = NULL; + + cl_arg_types[0] = &ffi_type_sshort; + cl_arg_types[1] = &ffi_type_sshort; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, + &ffi_type_sshort, cl_arg_types) == FFI_OK); + + ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); + /* { dg-output "2 32765: 32767" } */ + printf("res: %d\n", (unsigned short)res_call); + /* { dg-output "\nres: 32767" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); + + res_closure = (*((test_type)code))(2, 32765); + /* { dg-output "\n2 32765: 32767" } */ + printf("res: %d\n", res_closure); + /* { dg-output "\nres: 32767" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_sshortchar.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_sshortchar.c new file mode 100644 index 0000000..1c3aeb5 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_sshortchar.c @@ -0,0 +1,86 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple signed short/char values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run } */ +#include "ffitest.h" + +signed short test_func_fn(signed char a1, signed short a2, + signed char a3, signed short a4) +{ + signed short result; + + result = a1 + a2 + a3 + a4; + + printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result); + + return result; + +} + +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) +{ + signed char a1, a3; + signed short a2, a4; + + a1 = *(signed char *)avals[0]; + a2 = *(signed short *)avals[1]; + a3 = *(signed char *)avals[2]; + a4 = *(signed short *)avals[3]; + + *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4); + +} + +typedef signed short (*test_type)(signed char, signed short, + signed char, signed short); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void * args_dbl[5]; + ffi_type * cl_arg_types[5]; + ffi_arg res_call; + signed char a, c; + signed short b, d, res_closure; + + a = 1; + b = 32765; + c = 127; + d = -128; + + args_dbl[0] = &a; + args_dbl[1] = &b; + args_dbl[2] = &c; + args_dbl[3] = &d; + args_dbl[4] = NULL; + + cl_arg_types[0] = &ffi_type_schar; + cl_arg_types[1] = &ffi_type_sshort; + cl_arg_types[2] = &ffi_type_schar; + cl_arg_types[3] = &ffi_type_sshort; + cl_arg_types[4] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_sshort, cl_arg_types) == FFI_OK); + + ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); + /* { dg-output "1 32765 127 -128: 32765" } */ + printf("res: %d\n", (signed short)res_call); + /* { dg-output "\nres: 32765" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); + + res_closure = (*((test_type)code))(1, 32765, 127, -128); + /* { dg-output "\n1 32765 127 -128: 32765" } */ + printf("res: %d\n", res_closure); + /* { dg-output "\nres: 32765" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_uchar.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_uchar.c new file mode 100644 index 0000000..009c02c --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_uchar.c @@ -0,0 +1,91 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple unsigned char values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run } */ +#include "ffitest.h" + +unsigned char test_func_fn(unsigned char a1, unsigned char a2, + unsigned char a3, unsigned char a4) +{ + unsigned char result; + + result = a1 + a2 + a3 + a4; + + printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result); + + return result; + +} + +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) +{ + unsigned char a1, a2, a3, a4; + + a1 = *(unsigned char *)avals[0]; + a2 = *(unsigned char *)avals[1]; + a3 = *(unsigned char *)avals[2]; + a4 = *(unsigned char *)avals[3]; + + *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4); + +} + +typedef unsigned char (*test_type)(unsigned char, unsigned char, + unsigned char, unsigned char); + +void test_func(ffi_cif *cif __UNUSED__, void *rval __UNUSED__, void **avals, + void *data __UNUSED__) +{ + printf("%d %d %d %d\n", *(unsigned char *)avals[0], + *(unsigned char *)avals[1], *(unsigned char *)avals[2], + *(unsigned char *)avals[3]); +} +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void * args_dbl[5]; + ffi_type * cl_arg_types[5]; + ffi_arg res_call; + unsigned char a, b, c, d, res_closure; + + a = 1; + b = 2; + c = 127; + d = 125; + + args_dbl[0] = &a; + args_dbl[1] = &b; + args_dbl[2] = &c; + args_dbl[3] = &d; + args_dbl[4] = NULL; + + cl_arg_types[0] = &ffi_type_uchar; + cl_arg_types[1] = &ffi_type_uchar; + cl_arg_types[2] = &ffi_type_uchar; + cl_arg_types[3] = &ffi_type_uchar; + cl_arg_types[4] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_uchar, cl_arg_types) == FFI_OK); + + ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); + /* { dg-output "1 2 127 125: 255" } */ + printf("res: %d\n", (unsigned char)res_call); + /* { dg-output "\nres: 255" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); + + res_closure = (*((test_type)code))(1, 2, 127, 125); + /* { dg-output "\n1 2 127 125: 255" } */ + printf("res: %d\n", res_closure); + /* { dg-output "\nres: 255" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_ushort.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_ushort.c new file mode 100644 index 0000000..dd10ca7 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_ushort.c @@ -0,0 +1,74 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple unsigned short values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run } */ +#include "ffitest.h" + +unsigned short test_func_fn(unsigned short a1, unsigned short a2) +{ + unsigned short result; + + result = a1 + a2; + + printf("%d %d: %d\n", a1, a2, result); + + return result; + +} + +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) +{ + unsigned short a1, a2; + + a1 = *(unsigned short *)avals[0]; + a2 = *(unsigned short *)avals[1]; + + *(ffi_arg *)rval = test_func_fn(a1, a2); + +} + +typedef unsigned short (*test_type)(unsigned short, unsigned short); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void * args_dbl[3]; + ffi_type * cl_arg_types[3]; + ffi_arg res_call; + unsigned short a, b, res_closure; + + a = 2; + b = 32765; + + args_dbl[0] = &a; + args_dbl[1] = &b; + args_dbl[2] = NULL; + + cl_arg_types[0] = &ffi_type_ushort; + cl_arg_types[1] = &ffi_type_ushort; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, + &ffi_type_ushort, cl_arg_types) == FFI_OK); + + ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); + /* { dg-output "2 32765: 32767" } */ + printf("res: %d\n", (unsigned short)res_call); + /* { dg-output "\nres: 32767" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); + + res_closure = (*((test_type)code))(2, 32765); + /* { dg-output "\n2 32765: 32767" } */ + printf("res: %d\n", res_closure); + /* { dg-output "\nres: 32767" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_ushortchar.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_ushortchar.c new file mode 100644 index 0000000..2588e97 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_multi_ushortchar.c @@ -0,0 +1,86 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple unsigned short/char values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run } */ +#include "ffitest.h" + +unsigned short test_func_fn(unsigned char a1, unsigned short a2, + unsigned char a3, unsigned short a4) +{ + unsigned short result; + + result = a1 + a2 + a3 + a4; + + printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result); + + return result; + +} + +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) +{ + unsigned char a1, a3; + unsigned short a2, a4; + + a1 = *(unsigned char *)avals[0]; + a2 = *(unsigned short *)avals[1]; + a3 = *(unsigned char *)avals[2]; + a4 = *(unsigned short *)avals[3]; + + *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4); + +} + +typedef unsigned short (*test_type)(unsigned char, unsigned short, + unsigned char, unsigned short); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void * args_dbl[5]; + ffi_type * cl_arg_types[5]; + ffi_arg res_call; + unsigned char a, c; + unsigned short b, d, res_closure; + + a = 1; + b = 2; + c = 127; + d = 128; + + args_dbl[0] = &a; + args_dbl[1] = &b; + args_dbl[2] = &c; + args_dbl[3] = &d; + args_dbl[4] = NULL; + + cl_arg_types[0] = &ffi_type_uchar; + cl_arg_types[1] = &ffi_type_ushort; + cl_arg_types[2] = &ffi_type_uchar; + cl_arg_types[3] = &ffi_type_ushort; + cl_arg_types[4] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_ushort, cl_arg_types) == FFI_OK); + + ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); + /* { dg-output "1 2 127 128: 258" } */ + printf("res: %d\n", (unsigned short)res_call); + /* { dg-output "\nres: 258" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); + + res_closure = (*((test_type)code))(1, 2, 127, 128); + /* { dg-output "\n1 2 127 128: 258" } */ + printf("res: %d\n", res_closure); + /* { dg-output "\nres: 258" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_pointer.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_pointer.c new file mode 100644 index 0000000..d82a87a --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_pointer.c @@ -0,0 +1,74 @@ +/* Area: ffi_call, closure_call + Purpose: Check pointer arguments. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/6/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +void* cls_pointer_fn(void* a1, void* a2) +{ + void* result = (void*)((intptr_t)a1 + (intptr_t)a2); + + printf("0x%08x 0x%08x: 0x%08x\n", + (unsigned int)(uintptr_t) a1, + (unsigned int)(uintptr_t) a2, + (unsigned int)(uintptr_t) result); + + return result; +} + +static void +cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + void* a1 = *(void**)(args[0]); + void* a2 = *(void**)(args[1]); + + *(void**)resp = cls_pointer_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[3]; + /* ffi_type cls_pointer_type; */ + ffi_type* arg_types[3]; + +/* cls_pointer_type.size = sizeof(void*); + cls_pointer_type.alignment = 0; + cls_pointer_type.type = FFI_TYPE_POINTER; + cls_pointer_type.elements = NULL;*/ + + void* arg1 = (void*)0x12345678; + void* arg2 = (void*)0x89abcdef; + ffi_arg res = 0; + + arg_types[0] = &ffi_type_pointer; + arg_types[1] = &ffi_type_pointer; + arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, + arg_types) == FFI_OK); + + args[0] = &arg1; + args[1] = &arg2; + args[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_pointer_fn), &res, args); + /* { dg-output "0x12345678 0x89abcdef: 0x9be02467" } */ + printf("res: 0x%08x\n", (unsigned int) res); + /* { dg-output "\nres: 0x9be02467" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK); + + res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2); + /* { dg-output "\n0x12345678 0x89abcdef: 0x9be02467" } */ + printf("res: 0x%08x\n", (unsigned int) res); + /* { dg-output "\nres: 0x9be02467" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_pointer_stack.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_pointer_stack.c new file mode 100644 index 0000000..1f1d915 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_pointer_stack.c @@ -0,0 +1,142 @@ +/* Area: ffi_call, closure_call + Purpose: Check pointer arguments across multiple hideous stack frames. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/7/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static long dummyVar; + +long dummy_func( + long double a1, char b1, + long double a2, char b2, + long double a3, char b3, + long double a4, char b4) +{ + return a1 + b1 + a2 + b2 + a3 + b3 + a4 + b4; +} + +void* cls_pointer_fn2(void* a1, void* a2) +{ + long double trample1 = (intptr_t)a1 + (intptr_t)a2; + char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0]; + long double trample3 = (intptr_t)trample1 + (intptr_t)a1; + char trample4 = trample2 + ((char*)&a1)[1]; + long double trample5 = (intptr_t)trample3 + (intptr_t)a2; + char trample6 = trample4 + ((char*)&a2)[1]; + long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; + char trample8 = trample6 + trample2; + void* result; + + dummyVar = dummy_func(trample1, trample2, trample3, trample4, + trample5, trample6, trample7, trample8); + + result = (void*)((intptr_t)a1 + (intptr_t)a2); + + printf("0x%08x 0x%08x: 0x%08x\n", + (unsigned int)(uintptr_t) a1, + (unsigned int)(uintptr_t) a2, + (unsigned int)(uintptr_t) result); + + return result; +} + +void* cls_pointer_fn1(void* a1, void* a2) +{ + long double trample1 = (intptr_t)a1 + (intptr_t)a2; + char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0]; + long double trample3 = (intptr_t)trample1 + (intptr_t)a1; + char trample4 = trample2 + ((char*)&a1)[1]; + long double trample5 = (intptr_t)trample3 + (intptr_t)a2; + char trample6 = trample4 + ((char*)&a2)[1]; + long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; + char trample8 = trample6 + trample2; + void* result; + + dummyVar = dummy_func(trample1, trample2, trample3, trample4, + trample5, trample6, trample7, trample8); + + result = (void*)((intptr_t)a1 + (intptr_t)a2); + + printf("0x%08x 0x%08x: 0x%08x\n", + (unsigned int)(intptr_t) a1, + (unsigned int)(intptr_t) a2, + (unsigned int)(intptr_t) result); + + result = cls_pointer_fn2(result, a1); + + return result; +} + +static void +cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + void* a1 = *(void**)(args[0]); + void* a2 = *(void**)(args[1]); + + long double trample1 = (intptr_t)a1 + (intptr_t)a2; + char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0]; + long double trample3 = (intptr_t)trample1 + (intptr_t)a1; + char trample4 = trample2 + ((char*)&a1)[1]; + long double trample5 = (intptr_t)trample3 + (intptr_t)a2; + char trample6 = trample4 + ((char*)&a2)[1]; + long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; + char trample8 = trample6 + trample2; + + dummyVar = dummy_func(trample1, trample2, trample3, trample4, + trample5, trample6, trample7, trample8); + + *(void**)resp = cls_pointer_fn1(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[3]; + /* ffi_type cls_pointer_type; */ + ffi_type* arg_types[3]; + +/* cls_pointer_type.size = sizeof(void*); + cls_pointer_type.alignment = 0; + cls_pointer_type.type = FFI_TYPE_POINTER; + cls_pointer_type.elements = NULL;*/ + + void* arg1 = (void*)0x01234567; + void* arg2 = (void*)0x89abcdef; + ffi_arg res = 0; + + arg_types[0] = &ffi_type_pointer; + arg_types[1] = &ffi_type_pointer; + arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, + arg_types) == FFI_OK); + + args[0] = &arg1; + args[1] = &arg2; + args[2] = NULL; + + printf("\n"); + ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args); + + printf("res: 0x%08x\n", (unsigned int) res); + /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */ + /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */ + /* { dg-output "\nres: 0x8bf258bd" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK); + + res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2); + + printf("res: 0x%08x\n", (unsigned int) res); + /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */ + /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */ + /* { dg-output "\nres: 0x8bf258bd" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_schar.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_schar.c new file mode 100644 index 0000000..82986b1 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_schar.c @@ -0,0 +1,44 @@ +/* Area: closure_call + Purpose: Check return value schar. + Limitations: none. + PR: none. + Originator: 20031108 */ + + + +/* { dg-do run } */ +#include "ffitest.h" + +static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + *(ffi_arg*)resp = *(signed char *)args[0]; + printf("%d: %d\n",*(signed char *)args[0], + (int)*(ffi_arg *)(resp)); +} +typedef signed char (*cls_ret_schar)(signed char); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + signed char res; + + cl_arg_types[0] = &ffi_type_schar; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_schar, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_schar_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_schar)code))(127); + /* { dg-output "127: 127" } */ + printf("res: %d\n", res); + /* { dg-output "\nres: 127" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_sint.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_sint.c new file mode 100644 index 0000000..c7e13b7 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_sint.c @@ -0,0 +1,42 @@ +/* Area: closure_call + Purpose: Check return value sint32. + Limitations: none. + PR: none. + Originator: 20031108 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + *(ffi_arg*)resp = *(signed int *)args[0]; + printf("%d: %d\n",*(signed int *)args[0], + (int)*(ffi_arg *)(resp)); +} +typedef signed int (*cls_ret_sint)(signed int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + signed int res; + + cl_arg_types[0] = &ffi_type_sint; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sint_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_sint)code))(65534); + /* { dg-output "65534: 65534" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 65534" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_sshort.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_sshort.c new file mode 100644 index 0000000..846d57e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_sshort.c @@ -0,0 +1,42 @@ +/* Area: closure_call + Purpose: Check return value sshort. + Limitations: none. + PR: none. + Originator: 20031108 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + *(ffi_arg*)resp = *(signed short *)args[0]; + printf("%d: %d\n",*(signed short *)args[0], + (int)*(ffi_arg *)(resp)); +} +typedef signed short (*cls_ret_sshort)(signed short); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + signed short res; + + cl_arg_types[0] = &ffi_type_sshort; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sshort, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sshort_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_sshort)code))(255); + /* { dg-output "255: 255" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 255" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_struct_va1.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_struct_va1.c new file mode 100644 index 0000000..6d1fdae --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_struct_va1.c @@ -0,0 +1,114 @@ +/* Area: ffi_call, closure_call + Purpose: Test doubles passed in variable argument lists. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/6/2007 */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ +#include "ffitest.h" + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static void +test_fn (ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + int n = *(int*)args[0]; + struct small_tag s1 = * (struct small_tag *) args[1]; + struct large_tag l1 = * (struct large_tag *) args[2]; + struct small_tag s2 = * (struct small_tag *) args[3]; + + printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b, + l1.a, l1.b, l1.c, l1.d, l1.e, + s2.a, s2.b); + * (ffi_arg*) resp = 42; +} + +int +main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code); + ffi_type* arg_types[5]; + + ffi_arg res = 0; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int si; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint, + arg_types) == FFI_OK); + + si = 4; + s1.a = 5; + s1.b = 6; + + s2.a = 20; + s2.b = 21; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK); + + res = ((int (*)(int, ...))(code))(si, s1, l1, s2); + /* { dg-output "4 5 6 10 11 12 13 14 20 21" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 42" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_uchar.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_uchar.c new file mode 100644 index 0000000..c1317e7 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_uchar.c @@ -0,0 +1,42 @@ +/* Area: closure_call + Purpose: Check return value uchar. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + *(ffi_arg*)resp = *(unsigned char *)args[0]; + printf("%d: %d\n",*(unsigned char *)args[0], + (int)*(ffi_arg *)(resp)); +} +typedef unsigned char (*cls_ret_uchar)(unsigned char); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + unsigned char res; + + cl_arg_types[0] = &ffi_type_uchar; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_uchar, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uchar_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_uchar)code))(127); + /* { dg-output "127: 127" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 127" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_uchar_va.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_uchar_va.c new file mode 100644 index 0000000..6491c5b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_uchar_va.c @@ -0,0 +1,44 @@ +/* Area: closure_call + Purpose: Test anonymous unsigned char argument. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef unsigned char T; + +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(ffi_arg *)resp = *(T *)args[0]; + + printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]); + } + +typedef T (*cls_ret_T)(T, ...); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[3]; + T res; + + cl_arg_types[0] = &ffi_type_uchar; + cl_arg_types[1] = &ffi_type_uchar; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, + &ffi_type_uchar, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_T)code)(67, 4))); + /* { dg-output "67: 67 4" } */ + printf("res: %d\n", res); + /* { dg-output "\nres: 67" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_uint.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_uint.c new file mode 100644 index 0000000..885cff5 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_uint.c @@ -0,0 +1,43 @@ +/* Area: closure_call + Purpose: Check return value uint. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + *(ffi_arg *)resp = *(unsigned int *)args[0]; + + printf("%d: %d\n",*(unsigned int *)args[0], + (int)*(ffi_arg *)(resp)); +} +typedef unsigned int (*cls_ret_uint)(unsigned int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + unsigned int res; + + cl_arg_types[0] = &ffi_type_uint; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_uint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uint_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_uint)code))(2147483647); + /* { dg-output "2147483647: 2147483647" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 2147483647" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_uint_va.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_uint_va.c new file mode 100644 index 0000000..b04cfd1 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_uint_va.c @@ -0,0 +1,45 @@ +/* Area: closure_call + Purpose: Test anonymous unsigned int argument. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ + +#include "ffitest.h" + +typedef unsigned int T; + +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(ffi_arg *)resp = *(T *)args[0]; + + printf("%d: %d %d\n", (int)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]); + } + +typedef T (*cls_ret_T)(T, ...); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[3]; + T res; + + cl_arg_types[0] = &ffi_type_uint; + cl_arg_types[1] = &ffi_type_uint; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, + &ffi_type_uint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_T)code)(67, 4))); + /* { dg-output "67: 67 4" } */ + printf("res: %d\n", res); + /* { dg-output "\nres: 67" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_ulong_va.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_ulong_va.c new file mode 100644 index 0000000..0315082 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_ulong_va.c @@ -0,0 +1,45 @@ +/* Area: closure_call + Purpose: Test anonymous unsigned long argument. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ + +#include "ffitest.h" + +typedef unsigned long T; + +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(T *)resp = *(T *)args[0]; + + printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]); + } + +typedef T (*cls_ret_T)(T, ...); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[3]; + T res; + + cl_arg_types[0] = &ffi_type_ulong; + cl_arg_types[1] = &ffi_type_ulong; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, + &ffi_type_ulong, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_T)code)(67, 4))); + /* { dg-output "67: 67 4" } */ + printf("res: %ld\n", res); + /* { dg-output "\nres: 67" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_ulonglong.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_ulonglong.c new file mode 100644 index 0000000..62f2cae --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_ulonglong.c @@ -0,0 +1,47 @@ +/* Area: closure_call + Purpose: Check return value long long. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ +#include "ffitest.h" + +static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + *(unsigned long long *)resp= 0xfffffffffffffffLL ^ *(unsigned long long *)args[0]; + + printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0], + *(unsigned long long *)(resp)); +} +typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + unsigned long long res; + + cl_arg_types[0] = &ffi_type_uint64; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_uint64, cl_arg_types) == FFI_OK); + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code) == FFI_OK); + res = (*((cls_ret_ulonglong)code))(214LL); + /* { dg-output "214: 1152921504606846761" } */ + printf("res: %" PRIdLL "\n", res); + /* { dg-output "\nres: 1152921504606846761" } */ + + res = (*((cls_ret_ulonglong)code))(9223372035854775808LL); + /* { dg-output "\n9223372035854775808: 8070450533247928831" } */ + printf("res: %" PRIdLL "\n", res); + /* { dg-output "\nres: 8070450533247928831" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_ushort.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_ushort.c new file mode 100644 index 0000000..a00100e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_ushort.c @@ -0,0 +1,43 @@ +/* Area: closure_call + Purpose: Check return value ushort. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + *(ffi_arg*)resp = *(unsigned short *)args[0]; + + printf("%d: %d\n",*(unsigned short *)args[0], + (int)*(ffi_arg *)(resp)); +} +typedef unsigned short (*cls_ret_ushort)(unsigned short); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + unsigned short res; + + cl_arg_types[0] = &ffi_type_ushort; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_ushort, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ushort_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_ushort)code))(65535); + /* { dg-output "65535: 65535" } */ + printf("res: %d\n",res); + /* { dg-output "\nres: 65535" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/cls_ushort_va.c b/circuitpython/lib/libffi/testsuite/libffi.call/cls_ushort_va.c new file mode 100644 index 0000000..37aa106 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/cls_ushort_va.c @@ -0,0 +1,44 @@ +/* Area: closure_call + Purpose: Test anonymous unsigned short argument. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef unsigned short T; + +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(ffi_arg *)resp = *(T *)args[0]; + + printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]); + } + +typedef T (*cls_ret_T)(T, ...); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[3]; + T res; + + cl_arg_types[0] = &ffi_type_ushort; + cl_arg_types[1] = &ffi_type_ushort; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, + &ffi_type_ushort, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_T)code)(67, 4))); + /* { dg-output "67: 67 4" } */ + printf("res: %d\n", res); + /* { dg-output "\nres: 67" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/err_bad_abi.c b/circuitpython/lib/libffi/testsuite/libffi.call/err_bad_abi.c new file mode 100644 index 0000000..f5a7317 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/err_bad_abi.c @@ -0,0 +1,36 @@ +/* Area: ffi_prep_cif, ffi_prep_closure + Purpose: Test error return for bad ABIs. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/6/2007 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static void +dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args __UNUSED__, void* userdata __UNUSED__) +{} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type* arg_types[1]; + + arg_types[0] = NULL; + + CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void, + arg_types) == FFI_BAD_ABI); + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void, + arg_types) == FFI_OK); + + cif.abi= 255; + + CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/err_bad_typedef.c b/circuitpython/lib/libffi/testsuite/libffi.call/err_bad_typedef.c new file mode 100644 index 0000000..bf60161 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/err_bad_typedef.c @@ -0,0 +1,26 @@ +/* Area: ffi_prep_cif + Purpose: Test error return for bad typedefs. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/6/2007 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +int main (void) +{ + ffi_cif cif; + ffi_type* arg_types[1]; + + ffi_type badType = ffi_type_void; + + arg_types[0] = NULL; + + badType.size = 0; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType, + arg_types) == FFI_BAD_TYPEDEF); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/ffitest.h b/circuitpython/lib/libffi/testsuite/libffi.call/ffitest.h new file mode 100644 index 0000000..15d5e44 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/ffitest.h @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include "fficonfig.h" + +#if defined HAVE_STDINT_H +#include +#endif + +#if defined HAVE_INTTYPES_H +#include +#endif + +#define MAX_ARGS 256 + +#define CHECK(x) (void)(!(x) ? (abort(), 1) : 0) + +/* Define macros so that compilers other than gcc can run the tests. */ +#undef __UNUSED__ +#if defined(__GNUC__) +#define __UNUSED__ __attribute__((__unused__)) +#define __STDCALL__ __attribute__((stdcall)) +#define __THISCALL__ __attribute__((thiscall)) +#define __FASTCALL__ __attribute__((fastcall)) +#else +#define __UNUSED__ +#define __STDCALL__ __stdcall +#define __THISCALL__ __thiscall +#define __FASTCALL__ __fastcall +#endif + +#ifndef ABI_NUM +#define ABI_NUM FFI_DEFAULT_ABI +#define ABI_ATTR +#endif + +/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a + file open. */ +#ifdef HAVE_MMAP_ANON +# undef HAVE_MMAP_DEV_ZERO + +# include +# ifndef MAP_FAILED +# define MAP_FAILED -1 +# endif +# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +# endif +# define USING_MMAP + +#endif + +#ifdef HAVE_MMAP_DEV_ZERO + +# include +# ifndef MAP_FAILED +# define MAP_FAILED -1 +# endif +# define USING_MMAP + +#endif + +/* MinGW kludge. */ +#ifdef _WIN64 +#define PRIdLL "I64d" +#define PRIuLL "I64u" +#else +#define PRIdLL "lld" +#define PRIuLL "llu" +#endif + +/* Tru64 UNIX kludge. */ +#if defined(__alpha__) && defined(__osf__) +/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */ +#undef PRIdLL +#define PRIdLL "ld" +#undef PRIuLL +#define PRIuLL "lu" +#define PRId8 "hd" +#define PRIu8 "hu" +#define PRId64 "ld" +#define PRIu64 "lu" +#define PRIuPTR "lu" +#endif + +/* PA HP-UX kludge. */ +#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR) +#define PRIuPTR "lu" +#endif + +/* IRIX kludge. */ +#if defined(__sgi) +/* IRIX 6.5 provides all definitions, but only for C99 + compilations. */ +#define PRId8 "hhd" +#define PRIu8 "hhu" +#if (_MIPS_SZLONG == 32) +#define PRId64 "lld" +#define PRIu64 "llu" +#endif +/* This doesn't match , which always has "lld" here, but the + arguments are uint64_t, int64_t, which are unsigned long, long for + 64-bit in . */ +#if (_MIPS_SZLONG == 64) +#define PRId64 "ld" +#define PRIu64 "lu" +#endif +/* This doesn't match , which has "u" here, but the arguments + are uintptr_t, which is always unsigned long. */ +#define PRIuPTR "lu" +#endif + +/* Solaris < 10 kludge. */ +#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR) +#if defined(__arch64__) || defined (__x86_64__) +#define PRIuPTR "lu" +#else +#define PRIuPTR "u" +#endif +#endif + +/* MSVC kludge. */ +#if defined _MSC_VER +#define PRIuPTR "lu" +#define PRIu8 "u" +#define PRId8 "d" +#define PRIu64 "I64u" +#define PRId64 "I64d" +#endif + +#ifndef PRIuPTR +#define PRIuPTR "u" +#endif diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/float.c b/circuitpython/lib/libffi/testsuite/libffi.call/float.c new file mode 100644 index 0000000..fbc272d --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/float.c @@ -0,0 +1,59 @@ +/* Area: ffi_call + Purpose: Check return value float. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static int floating(int a, float b, double c, long double d) +{ + int i; + + i = (int) ((float)a/b + ((float)c/(float)d)); + + return i; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + + float f; + signed int si1; + double d; + long double ld; + + args[0] = &ffi_type_sint; + values[0] = &si1; + args[1] = &ffi_type_float; + values[1] = &f; + args[2] = &ffi_type_double; + values[2] = &d; + args[3] = &ffi_type_longdouble; + values[3] = &ld; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_sint, args) == FFI_OK); + + si1 = 6; + f = 3.14159; + d = (double)1.0/(double)3.0; + ld = 2.71828182846L; + + floating (si1, f, d, ld); + + ffi_call(&cif, FFI_FN(floating), &rint, values); + + printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld)); + + CHECK((int)rint == floating(si1, f, d, ld)); + + exit (0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/float1.c b/circuitpython/lib/libffi/testsuite/libffi.call/float1.c new file mode 100644 index 0000000..c48493c --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/float1.c @@ -0,0 +1,60 @@ +/* Area: ffi_call + Purpose: Check return value double. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" +#include "float.h" + +#include + +typedef union +{ + double d; + unsigned char c[sizeof (double)]; +} value_type; + +#define CANARY 0xba + +static double dblit(float f) +{ + return f/3.0; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + float f; + value_type result[2]; + unsigned int i; + + args[0] = &ffi_type_float; + values[0] = &f; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_double, args) == FFI_OK); + + f = 3.14159; + + /* Put a canary in the return array. This is a regression test for + a buffer overrun. */ + memset(result[1].c, CANARY, sizeof (double)); + + ffi_call(&cif, FFI_FN(dblit), &result[0].d, values); + + /* These are not always the same!! Check for a reasonable delta */ + + CHECK(fabs(result[0].d - dblit(f)) < DBL_EPSILON); + + /* Check the canary. */ + for (i = 0; i < sizeof (double); ++i) + CHECK(result[1].c[i] == CANARY); + + exit(0); + +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/float2.c b/circuitpython/lib/libffi/testsuite/libffi.call/float2.c new file mode 100644 index 0000000..20a8c40 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/float2.c @@ -0,0 +1,58 @@ +/* Area: ffi_call + Purpose: Check return value long double. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ +/* { dg-do run } */ + +#include "ffitest.h" +#include "float.h" + +#include + +static long double ldblit(float f) +{ + return (long double) (((long double) f)/ (long double) 3.0); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + float f; + long double ld; + + args[0] = &ffi_type_float; + values[0] = &f; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_longdouble, args) == FFI_OK); + + f = 3.14159; + +#if 1 + /* This is ifdef'd out for now. long double support under SunOS/gcc + is pretty much non-existent. You'll get the odd bus error in library + routines like printf(). */ + printf ("%Lf\n", ldblit(f)); +#endif + ld = 666; + ffi_call(&cif, FFI_FN(ldblit), &ld, values); + +#if 1 + /* This is ifdef'd out for now. long double support under SunOS/gcc + is pretty much non-existent. You'll get the odd bus error in library + routines like printf(). */ + printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON); +#endif + + /* These are not always the same!! Check for a reasonable delta */ + if (fabsl(ld - ldblit(f)) < LDBL_EPSILON) + puts("long double return value tests ok!"); + else + CHECK(0); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/float3.c b/circuitpython/lib/libffi/testsuite/libffi.call/float3.c new file mode 100644 index 0000000..bab3206 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/float3.c @@ -0,0 +1,74 @@ +/* Area: ffi_call + Purpose: Check float arguments with different orders. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ + +#include "ffitest.h" +#include "float.h" + +#include + +static double floating_1(float a, double b, long double c) +{ + return (double) a + b + (double) c; +} + +static double floating_2(long double a, double b, float c) +{ + return (double) a + b + (double) c; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + double rd; + + float f; + double d; + long double ld; + + args[0] = &ffi_type_float; + values[0] = &f; + args[1] = &ffi_type_double; + values[1] = &d; + args[2] = &ffi_type_longdouble; + values[2] = &ld; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &ffi_type_double, args) == FFI_OK); + + f = 3.14159; + d = (double)1.0/(double)3.0; + ld = 2.71828182846L; + + floating_1 (f, d, ld); + + ffi_call(&cif, FFI_FN(floating_1), &rd, values); + + CHECK(fabs(rd - floating_1(f, d, ld)) < DBL_EPSILON); + + args[0] = &ffi_type_longdouble; + values[0] = &ld; + args[1] = &ffi_type_double; + values[1] = &d; + args[2] = &ffi_type_float; + values[2] = &f; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &ffi_type_double, args) == FFI_OK); + + floating_2 (ld, d, f); + + ffi_call(&cif, FFI_FN(floating_2), &rd, values); + + CHECK(fabs(rd - floating_2(ld, d, f)) < DBL_EPSILON); + + exit (0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/float4.c b/circuitpython/lib/libffi/testsuite/libffi.call/float4.c new file mode 100644 index 0000000..0dd6d85 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/float4.c @@ -0,0 +1,62 @@ +/* Area: ffi_call + Purpose: Check denorm double value. + Limitations: none. + PR: PR26483. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +/* { dg-options "-mieee" { target alpha*-*-* } } */ + +#include "ffitest.h" +#include "float.h" + +typedef union +{ + double d; + unsigned char c[sizeof (double)]; +} value_type; + +#define CANARY 0xba + +static double dblit(double d) +{ + return d; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + double d; + value_type result[2]; + unsigned int i; + + args[0] = &ffi_type_double; + values[0] = &d; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_double, args) == FFI_OK); + + d = DBL_MIN / 2; + + /* Put a canary in the return array. This is a regression test for + a buffer overrun. */ + memset(result[1].c, CANARY, sizeof (double)); + + ffi_call(&cif, FFI_FN(dblit), &result[0].d, values); + + /* The standard delta check doesn't work for denorms. Since we didn't do + any arithmetic, we should get the original result back, and hence an + exact check should be OK here. */ + + CHECK(result[0].d == dblit(d)); + + /* Check the canary. */ + for (i = 0; i < sizeof (double); ++i) + CHECK(result[1].c[i] == CANARY); + + exit(0); + +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/float_va.c b/circuitpython/lib/libffi/testsuite/libffi.call/float_va.c new file mode 100644 index 0000000..5acff91 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/float_va.c @@ -0,0 +1,107 @@ +/* Area: fp and variadics + Purpose: check fp inputs and returns work on variadics, even the fixed params + Limitations: None + PR: none + Originator: 2011-01-25 + + Intended to stress the difference in ABI on ARM vfp +*/ + +/* { dg-do run } */ + +#include + +#include "ffitest.h" + +/* prints out all the parameters, and returns the sum of them all. + * 'x' is the number of variadic parameters all of which are double in this test + */ +double float_va_fn(unsigned int x, double y,...) +{ + double total=0.0; + va_list ap; + unsigned int i; + + total+=(double)x; + total+=y; + + printf("%u: %.1f :", x, y); + + va_start(ap, y); + for(i=0;i +#include +#include + +static float ABI_ATTR many(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13) +{ +#if 0 + printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", + (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, + (double) f6, (double) f7, (double) f8, (double) f9, (double) f10, + (double) f11, (double) f12, (double) f13); +#endif + + return f1+f2+f3+f4+f5+f6+f7+f8+f9+f10+f11+f12+f13; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[13]; + void *values[13]; + float fa[13]; + float f, ff; + int i; + + for (i = 0; i < 13; i++) + { + args[i] = &ffi_type_float; + values[i] = &fa[i]; + fa[i] = (float) i; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 13, + &ffi_type_float, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(many), &f, values); + + ff = many(fa[0], fa[1], + fa[2], fa[3], + fa[4], fa[5], + fa[6], fa[7], + fa[8], fa[9], + fa[10],fa[11],fa[12]); + + if (fabs(f - ff) < FLT_EPSILON) + exit(0); + else + abort(); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/many2.c b/circuitpython/lib/libffi/testsuite/libffi.call/many2.c new file mode 100644 index 0000000..1c85746 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/many2.c @@ -0,0 +1,57 @@ +/* Area: ffi_call + Purpose: Check uint8_t arguments. + Limitations: none. + PR: PR45677. + Originator: Dan Witte 20100916 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +#define NARGS 7 + +typedef unsigned char u8; + +#ifdef __GNUC__ +__attribute__((noinline)) +#endif +uint8_t +foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d, + uint8_t e, uint8_t f, uint8_t g) +{ + return a + b + c + d + e + f + g; +} + +uint8_t ABI_ATTR +bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d, + uint8_t e, uint8_t f, uint8_t g) +{ + return foo (a, b, c, d, e, f, g); +} + +int +main (void) +{ + ffi_type *ffitypes[NARGS]; + int i; + ffi_cif cif; + ffi_arg result = 0; + uint8_t args[NARGS]; + void *argptrs[NARGS]; + + for (i = 0; i < NARGS; ++i) + ffitypes[i] = &ffi_type_uint8; + + CHECK (ffi_prep_cif (&cif, ABI_NUM, NARGS, + &ffi_type_uint8, ffitypes) == FFI_OK); + + for (i = 0; i < NARGS; ++i) + { + args[i] = i; + argptrs[i] = &args[i]; + } + ffi_call (&cif, FFI_FN (bar), &result, argptrs); + + CHECK (result == 21); + return 0; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/many_double.c b/circuitpython/lib/libffi/testsuite/libffi.call/many_double.c new file mode 100644 index 0000000..4ef8c8a --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/many_double.c @@ -0,0 +1,70 @@ +/* Area: ffi_call + Purpose: Check return value double, with many arguments + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +#include +#include +#include + +static double many(double f1, + double f2, + double f3, + double f4, + double f5, + double f6, + double f7, + double f8, + double f9, + double f10, + double f11, + double f12, + double f13) +{ +#if 0 + printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", + (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, + (double) f6, (double) f7, (double) f8, (double) f9, (double) f10, + (double) f11, (double) f12, (double) f13); +#endif + + return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[13]; + void *values[13]; + double fa[13]; + double f, ff; + int i; + + for (i = 0; i < 13; i++) + { + args[i] = &ffi_type_double; + values[i] = &fa[i]; + fa[i] = (double) i; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, + &ffi_type_double, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(many), &f, values); + + ff = many(fa[0], fa[1], + fa[2], fa[3], + fa[4], fa[5], + fa[6], fa[7], + fa[8], fa[9], + fa[10],fa[11],fa[12]); + if (fabs(f - ff) < FLT_EPSILON) + exit(0); + else + abort(); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/many_mixed.c b/circuitpython/lib/libffi/testsuite/libffi.call/many_mixed.c new file mode 100644 index 0000000..85ec36e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/many_mixed.c @@ -0,0 +1,78 @@ +/* Area: ffi_call + Purpose: Check return value double, with many arguments + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +#include +#include +#include + +static double many(double f1, + double f2, + long int i1, + double f3, + double f4, + long int i2, + double f5, + double f6, + long int i3, + double f7, + double f8, + long int i4, + double f9, + double f10, + long int i5, + double f11, + double f12, + long int i6, + double f13) +{ + return ((double) (i1 + i2 + i3 + i4 + i5 + i6) + (f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[19]; + void *values[19]; + double fa[19]; + long int la[19]; + double f, ff; + int i; + + for (i = 0; i < 19; i++) + { + if( (i - 2) % 3 == 0) { + args[i] = &ffi_type_slong; + la[i] = (long int) i; + values[i] = &la[i]; + } + else { + args[i] = &ffi_type_double; + fa[i] = (double) i; + values[i] = &fa[i]; + } + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 19, + &ffi_type_double, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(many), &f, values); + + ff = many(fa[0], fa[1], la[2], + fa[3], fa[4], la[5], + fa[6], fa[7], la[8], + fa[9], fa[10], la[11], + fa[12], fa[13], la[14], + fa[15], fa[16], la[17], + fa[18]); + if (fabs(f - ff) < FLT_EPSILON) + exit(0); + else + abort(); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/negint.c b/circuitpython/lib/libffi/testsuite/libffi.call/negint.c new file mode 100644 index 0000000..6e2f26f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/negint.c @@ -0,0 +1,52 @@ +/* Area: ffi_call + Purpose: Check that negative integers are passed correctly. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static int checking(int a, short b, signed char c) +{ + + return (a < 0 && b < 0 && c < 0); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + + signed int si; + signed short ss; + signed char sc; + + args[0] = &ffi_type_sint; + values[0] = &si; + args[1] = &ffi_type_sshort; + values[1] = &ss; + args[2] = &ffi_type_schar; + values[2] = ≻ + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &ffi_type_sint, args) == FFI_OK); + + si = -6; + ss = -12; + sc = -1; + + checking (si, ss, sc); + + ffi_call(&cif, FFI_FN(checking), &rint, values); + + printf ("%d vs %d\n", (int)rint, checking (si, ss, sc)); + + CHECK(rint != 0); + + exit (0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct.c new file mode 100644 index 0000000..c15e3a0 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct.c @@ -0,0 +1,152 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_16byte1 { + double a; + float b; + int c; +} cls_struct_16byte1; + +typedef struct cls_struct_16byte2 { + int ii; + double dd; + float ff; +} cls_struct_16byte2; + +typedef struct cls_struct_combined { + cls_struct_16byte1 d; + cls_struct_16byte2 e; +} cls_struct_combined; + +cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0, + struct cls_struct_16byte2 b1, + struct cls_struct_combined b2) +{ + struct cls_struct_combined result; + + result.d.a = b0.a + b1.dd + b2.d.a; + result.d.b = b0.b + b1.ff + b2.d.b; + result.d.c = b0.c + b1.ii + b2.d.c; + result.e.ii = b0.c + b1.ii + b2.e.ii; + result.e.dd = b0.a + b1.dd + b2.e.dd; + result.e.ff = b0.b + b1.ff + b2.e.ff; + + printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n", + b0.a, b0.b, b0.c, + b1.ii, b1.dd, b1.ff, + b2.d.a, b2.d.b, b2.d.c, + b2.e.ii, b2.e.dd, b2.e.ff, + result.d.a, result.d.b, result.d.c, + result.e.ii, result.e.dd, result.e.ff); + + return result; +} + +static void +cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_16byte1 b0; + struct cls_struct_16byte2 b1; + struct cls_struct_combined b2; + + b0 = *(struct cls_struct_16byte1*)(args[0]); + b1 = *(struct cls_struct_16byte2*)(args[1]); + b2 = *(struct cls_struct_combined*)(args[2]); + + + *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[5]; + ffi_type* cls_struct_fields1[5]; + ffi_type* cls_struct_fields2[5]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6}; + struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0}; + struct cls_struct_combined g_dbl = {{4.0, 5.0, 6}, + {3, 1.0, 8.0}}; + struct cls_struct_combined res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_float; + cls_struct_fields[2] = &ffi_type_sint; + cls_struct_fields[3] = NULL; + + cls_struct_fields1[0] = &ffi_type_sint; + cls_struct_fields1[1] = &ffi_type_double; + cls_struct_fields1[2] = &ffi_type_float; + cls_struct_fields1[3] = NULL; + + cls_struct_fields2[0] = &cls_struct_type; + cls_struct_fields2[1] = &cls_struct_type1; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl); + /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */ + CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); + CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); + CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); + CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); + CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); + CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1, + cls_struct_16byte2, + cls_struct_combined)) + (code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */ + CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); + CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); + CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); + CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); + CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); + CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct1.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct1.c new file mode 100644 index 0000000..477a6b9 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct1.c @@ -0,0 +1,161 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_16byte1 { + double a; + float b; + int c; +} cls_struct_16byte1; + +typedef struct cls_struct_16byte2 { + int ii; + double dd; + float ff; +} cls_struct_16byte2; + +typedef struct cls_struct_combined { + cls_struct_16byte1 d; + cls_struct_16byte2 e; +} cls_struct_combined; + +cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0, + struct cls_struct_16byte2 b1, + struct cls_struct_combined b2, + struct cls_struct_16byte1 b3) +{ + struct cls_struct_combined result; + + result.d.a = b0.a + b1.dd + b2.d.a; + result.d.b = b0.b + b1.ff + b2.d.b; + result.d.c = b0.c + b1.ii + b2.d.c; + result.e.ii = b0.c + b1.ii + b2.e.ii; + result.e.dd = b0.a + b1.dd + b2.e.dd; + result.e.ff = b0.b + b1.ff + b2.e.ff; + + printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n", + b0.a, b0.b, b0.c, + b1.ii, b1.dd, b1.ff, + b2.d.a, b2.d.b, b2.d.c, + b2.e.ii, b2.e.dd, b2.e.ff, + b3.a, b3.b, b3.c, + result.d.a, result.d.b, result.d.c, + result.e.ii, result.e.dd, result.e.ff); + + return result; +} + +static void +cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_16byte1 b0; + struct cls_struct_16byte2 b1; + struct cls_struct_combined b2; + struct cls_struct_16byte1 b3; + + b0 = *(struct cls_struct_16byte1*)(args[0]); + b1 = *(struct cls_struct_16byte2*)(args[1]); + b2 = *(struct cls_struct_combined*)(args[2]); + b3 = *(struct cls_struct_16byte1*)(args[3]); + + + *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[5]; + ffi_type* cls_struct_fields1[5]; + ffi_type* cls_struct_fields2[5]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6}; + struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0}; + struct cls_struct_combined g_dbl = {{4.0, 5.0, 6}, + {3, 1.0, 8.0}}; + struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4}; + struct cls_struct_combined res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_float; + cls_struct_fields[2] = &ffi_type_sint; + cls_struct_fields[3] = NULL; + + cls_struct_fields1[0] = &ffi_type_sint; + cls_struct_fields1[1] = &ffi_type_double; + cls_struct_fields1[2] = &ffi_type_float; + cls_struct_fields1[3] = NULL; + + cls_struct_fields2[0] = &cls_struct_type; + cls_struct_fields2[1] = &cls_struct_type1; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl); + /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */ + CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); + CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); + CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); + CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); + CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); + CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1, + cls_struct_16byte2, + cls_struct_combined, + cls_struct_16byte1)) + (code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */ + CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); + CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); + CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); + CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); + CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); + CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); + /* CHECK( 1 == 0); */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct10.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct10.c new file mode 100644 index 0000000..34a74e7 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct10.c @@ -0,0 +1,133 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long long a; + unsigned char b; +} A; + +typedef struct B { + unsigned char y; + struct A x; + unsigned int z; +} B; + +typedef struct C { + unsigned long long d; + unsigned char e; +} C; + +static B B_fn(struct A b2, struct B b3, struct C b4) +{ + struct B result; + + result.x.a = b2.a + b3.x.a + b3.z + b4.d; + result.x.b = b2.b + b3.x.b + b3.y + b4.e; + result.y = b2.b + b3.x.b + b4.e; + + printf("%d %d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, b3.z, (int)b4.d, b4.e, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + struct C b2; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + b2 = *(struct C*)(args[2]); + + *(B*)resp = B_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[4]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[4]; + ffi_type* cls_struct_fields2[3]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[4]; + + struct A e_dbl = { 1LL, 7}; + struct B f_dbl = { 99, {12LL , 127}, 255}; + struct C g_dbl = { 2LL, 9}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_uint64; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &ffi_type_uchar; + cls_struct_fields1[1] = &cls_struct_type; + cls_struct_fields1[2] = &ffi_type_uint; + cls_struct_fields1[3] = NULL; + + cls_struct_fields2[0] = &ffi_type_uint64; + cls_struct_fields2[1] = &ffi_type_uchar; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99 255 2 9: 270 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct11.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct11.c new file mode 100644 index 0000000..3510493 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct11.c @@ -0,0 +1,121 @@ +/* Area: ffi_call, closure_call + Purpose: Check parameter passing with nested structs + of a single type. This tests the special cases + for homogeneous floating-point aggregates in the + AArch64 PCS. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + float a_x; + float a_y; +} A; + +typedef struct B { + float b_x; + float b_y; +} B; + +typedef struct C { + A a; + B b; +} C; + +static C C_fn (int x, int y, int z, C source, int i, int j, int k) +{ + C result; + result.a.a_x = source.a.a_x; + result.a.a_y = source.a.a_y; + result.b.b_x = source.b.b_x; + result.b.b_y = source.b.b_y; + + printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k); + + printf ("%.1f, %.1f, %.1f, %.1f, " + "%.1f, %.1f, %.1f, %.1f\n", + source.a.a_x, source.a.a_y, + source.b.b_x, source.b.b_y, + result.a.a_x, result.a.a_y, + result.b.b_x, result.b.b_y); + + return result; +} + +int main (void) +{ + ffi_cif cif; + + ffi_type* struct_fields_source_a[3]; + ffi_type* struct_fields_source_b[3]; + ffi_type* struct_fields_source_c[3]; + ffi_type* arg_types[8]; + + ffi_type struct_type_a, struct_type_b, struct_type_c; + + struct A source_fld_a = {1.0, 2.0}; + struct B source_fld_b = {4.0, 8.0}; + int k = 1; + + struct C result; + struct C source = {source_fld_a, source_fld_b}; + + struct_type_a.size = 0; + struct_type_a.alignment = 0; + struct_type_a.type = FFI_TYPE_STRUCT; + struct_type_a.elements = struct_fields_source_a; + + struct_type_b.size = 0; + struct_type_b.alignment = 0; + struct_type_b.type = FFI_TYPE_STRUCT; + struct_type_b.elements = struct_fields_source_b; + + struct_type_c.size = 0; + struct_type_c.alignment = 0; + struct_type_c.type = FFI_TYPE_STRUCT; + struct_type_c.elements = struct_fields_source_c; + + struct_fields_source_a[0] = &ffi_type_float; + struct_fields_source_a[1] = &ffi_type_float; + struct_fields_source_a[2] = NULL; + + struct_fields_source_b[0] = &ffi_type_float; + struct_fields_source_b[1] = &ffi_type_float; + struct_fields_source_b[2] = NULL; + + struct_fields_source_c[0] = &struct_type_a; + struct_fields_source_c[1] = &struct_type_b; + struct_fields_source_c[2] = NULL; + + arg_types[0] = &ffi_type_sint32; + arg_types[1] = &ffi_type_sint32; + arg_types[2] = &ffi_type_sint32; + arg_types[3] = &struct_type_c; + arg_types[4] = &ffi_type_sint32; + arg_types[5] = &ffi_type_sint32; + arg_types[6] = &ffi_type_sint32; + arg_types[7] = NULL; + + void *args[7]; + args[0] = &k; + args[1] = &k; + args[2] = &k; + args[3] = &source; + args[4] = &k; + args[5] = &k; + args[6] = &k; + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c, + arg_types) == FFI_OK); + + ffi_call (&cif, FFI_FN (C_fn), &result, args); + /* { dg-output "1, 1, 1, 1, 1, 1\n" } */ + /* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */ + CHECK (result.a.a_x == source.a.a_x); + CHECK (result.a.a_y == source.a.a_y); + CHECK (result.b.b_x == source.b.b_x); + CHECK (result.b.b_y == source.b.b_y); + exit (0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct2.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct2.c new file mode 100644 index 0000000..69268cd --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct2.c @@ -0,0 +1,110 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20030911 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +B B_fn(struct A b0, struct B b1) +{ + struct B result; + + result.x.a = b0.a + b1.x.a; + result.x.b = b0.b + b1.x.b + b1.y; + result.y = b0.b + b1.x.b; + + printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y, + result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1, 7}; + struct B f_dbl = {{12 , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_ulong; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct3.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct3.c new file mode 100644 index 0000000..ab18cad --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct3.c @@ -0,0 +1,111 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20030911 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long long a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +B B_fn(struct A b0, struct B b1) +{ + struct B result; + + result.x.a = b0.a + b1.x.a; + result.x.b = b0.b + b1.x.b + b1.y; + result.y = b0.b + b1.x.b; + + printf("%d %d %d %d %d: %d %d %d\n", (int)b0.a, b0.b, + (int)b1.x.a, b1.x.b, b1.y, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1LL, 7}; + struct B f_dbl = {{12LL , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_uint64; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct4.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct4.c new file mode 100644 index 0000000..2ffb4d6 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct4.c @@ -0,0 +1,111 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: PR 25630. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + double a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +static B B_fn(struct A b2, struct B b3) +{ + struct B result; + + result.x.a = b2.a + b3.x.a; + result.x.b = b2.b + b3.x.b + b3.y; + result.y = b2.b + b3.x.b; + + printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1.0, 7}; + struct B f_dbl = {{12.0 , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct5.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct5.c new file mode 100644 index 0000000..6c79845 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct5.c @@ -0,0 +1,112 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + long double a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +static B B_fn(struct A b2, struct B b3) +{ + struct B result; + + result.x.a = b2.a + b3.x.a; + result.x.b = b2.b + b3.x.b + b3.y; + result.y = b2.b + b3.x.b; + + printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1.0, 7}; + struct B f_dbl = {{12.0 , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_longdouble; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct6.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct6.c new file mode 100644 index 0000000..59d3579 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct6.c @@ -0,0 +1,131 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: PR 25630. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + double a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +typedef struct C { + long d; + unsigned char e; +} C; + +static B B_fn(struct A b2, struct B b3, struct C b4) +{ + struct B result; + + result.x.a = b2.a + b3.x.a + b4.d; + result.x.b = b2.b + b3.x.b + b3.y + b4.e; + result.y = b2.b + b3.x.b + b4.e; + + printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + struct C b2; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + b2 = *(struct C*)(args[2]); + + *(B*)resp = B_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[4]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type* cls_struct_fields2[3]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[4]; + + struct A e_dbl = { 1.0, 7}; + struct B f_dbl = {{12.0 , 127}, 99}; + struct C g_dbl = { 2, 9}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + cls_struct_fields2[0] = &ffi_type_slong; + cls_struct_fields2[1] = &ffi_type_uchar; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct7.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct7.c new file mode 100644 index 0000000..27595e6 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct7.c @@ -0,0 +1,111 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long long a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +static B B_fn(struct A b2, struct B b3) +{ + struct B result; + + result.x.a = b2.a + b3.x.a; + result.x.b = b2.b + b3.x.b + b3.y; + result.y = b2.b + b3.x.b; + + printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1LL, 7}; + struct B f_dbl = {{12.0 , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_uint64; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct8.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct8.c new file mode 100644 index 0000000..0e6c682 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct8.c @@ -0,0 +1,131 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long long a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +typedef struct C { + unsigned long long d; + unsigned char e; +} C; + +static B B_fn(struct A b2, struct B b3, struct C b4) +{ + struct B result; + + result.x.a = b2.a + b3.x.a + b4.d; + result.x.b = b2.b + b3.x.b + b3.y + b4.e; + result.y = b2.b + b3.x.b + b4.e; + + printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + struct C b2; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + b2 = *(struct C*)(args[2]); + + *(B*)resp = B_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[4]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type* cls_struct_fields2[3]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[4]; + + struct A e_dbl = { 1LL, 7}; + struct B f_dbl = {{12LL , 127}, 99}; + struct C g_dbl = { 2LL, 9}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_uint64; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + cls_struct_fields2[0] = &ffi_type_uint64; + cls_struct_fields2[1] = &ffi_type_uchar; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct9.c b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct9.c new file mode 100644 index 0000000..5f7ac67 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/nested_struct9.c @@ -0,0 +1,131 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned char a; + unsigned long long b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +typedef struct C { + unsigned long d; + unsigned char e; +} C; + +static B B_fn(struct A b2, struct B b3, struct C b4) +{ + struct B result; + + result.x.a = b2.a + b3.x.a + b4.d; + result.x.b = b2.b + b3.x.b + b3.y + b4.e; + result.y = b2.b + b3.x.b + b4.e; + + printf("%d %d %d %d %d %d %d: %d %d %d\n", b2.a, (int)b2.b, + b3.x.a, (int)b3.x.b, b3.y, (int)b4.d, b4.e, + result.x.a, (int)result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + struct C b2; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + b2 = *(struct C*)(args[2]); + + *(B*)resp = B_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[4]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type* cls_struct_fields2[3]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[4]; + + struct A e_dbl = { 1, 7LL}; + struct B f_dbl = {{12.0 , 127}, 99}; + struct C g_dbl = { 2, 9}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uint64; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + cls_struct_fields2[0] = &ffi_type_ulong; + cls_struct_fields2[1] = &ffi_type_uchar; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/pr1172638.c b/circuitpython/lib/libffi/testsuite/libffi.call/pr1172638.c new file mode 100644 index 0000000..7da1621 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/pr1172638.c @@ -0,0 +1,127 @@ +/* Area: ffi_call + Purpose: Reproduce bug found in python ctypes + Limitations: none. + PR: Fedora 1174037 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct { + long x; + long y; +} POINT; + +typedef struct { + long left; + long top; + long right; + long bottom; +} RECT; + +static RECT ABI_ATTR pr_test(int i __UNUSED__, RECT ar __UNUSED__, + RECT* br __UNUSED__, POINT cp __UNUSED__, + RECT dr __UNUSED__, RECT *er __UNUSED__, + POINT fp, RECT gr __UNUSED__) +{ + RECT result; + + result.left = fp.x; + result.right = fp.y; + result.top = fp.x; + result.bottom = fp.y; + + return result; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type point_type, rect_type; + ffi_type *point_type_elements[3]; + ffi_type *rect_type_elements[5]; + + int i; + POINT cp, fp; + RECT ar, br, dr, er, gr; + RECT *p1, *p2; + + /* This is a hack to get a properly aligned result buffer */ + RECT *rect_result = + (RECT *) malloc (sizeof(RECT)); + + point_type.size = 0; + point_type.alignment = 0; + point_type.type = FFI_TYPE_STRUCT; + point_type.elements = point_type_elements; + point_type_elements[0] = &ffi_type_slong; + point_type_elements[1] = &ffi_type_slong; + point_type_elements[2] = NULL; + + rect_type.size = 0; + rect_type.alignment = 0; + rect_type.type = FFI_TYPE_STRUCT; + rect_type.elements = rect_type_elements; + rect_type_elements[0] = &ffi_type_slong; + rect_type_elements[1] = &ffi_type_slong; + rect_type_elements[2] = &ffi_type_slong; + rect_type_elements[3] = &ffi_type_slong; + rect_type_elements[4] = NULL; + + args[0] = &ffi_type_sint; + args[1] = &rect_type; + args[2] = &ffi_type_pointer; + args[3] = &point_type; + args[4] = &rect_type; + args[5] = &ffi_type_pointer; + args[6] = &point_type; + args[7] = &rect_type; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 8, &rect_type, args) == FFI_OK); + + i = 1; + ar.left = 2; + ar.right = 3; + ar.top = 4; + ar.bottom = 5; + br.left = 6; + br.right = 7; + br.top = 8; + br.bottom = 9; + cp.x = 10; + cp.y = 11; + dr.left = 12; + dr.right = 13; + dr.top = 14; + dr.bottom = 15; + er.left = 16; + er.right = 17; + er.top = 18; + er.bottom = 19; + fp.x = 20; + fp.y = 21; + gr.left = 22; + gr.right = 23; + gr.top = 24; + gr.bottom = 25; + + values[0] = &i; + values[1] = &ar; + p1 = &br; + values[2] = &p1; + values[3] = &cp; + values[4] = &dr; + p2 = &er; + values[5] = &p2; + values[6] = &fp; + values[7] = &gr; + + ffi_call (&cif, FFI_FN(pr_test), rect_result, values); + + CHECK(rect_result->top == 20); + + free (rect_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/problem1.c b/circuitpython/lib/libffi/testsuite/libffi.call/problem1.c new file mode 100644 index 0000000..6a91555 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/problem1.c @@ -0,0 +1,90 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct my_ffi_struct { + double a; + double b; + double c; +} my_ffi_struct; + +my_ffi_struct callee(struct my_ffi_struct a1, struct my_ffi_struct a2) +{ + struct my_ffi_struct result; + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + + printf("%g %g %g %g %g %g: %g %g %g\n", a1.a, a1.b, a1.c, + a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +void stub(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct my_ffi_struct a1; + struct my_ffi_struct a2; + + a1 = *(struct my_ffi_struct*)(args[0]); + a2 = *(struct my_ffi_struct*)(args[1]); + + *(my_ffi_struct *)resp = callee(a1, a2); +} + + +int main(void) +{ + ffi_type* my_ffi_struct_fields[4]; + ffi_type my_ffi_struct_type; + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[4]; + ffi_type* arg_types[3]; + + struct my_ffi_struct g = { 1.0, 2.0, 3.0 }; + struct my_ffi_struct f = { 1.0, 2.0, 3.0 }; + struct my_ffi_struct res; + + my_ffi_struct_type.size = 0; + my_ffi_struct_type.alignment = 0; + my_ffi_struct_type.type = FFI_TYPE_STRUCT; + my_ffi_struct_type.elements = my_ffi_struct_fields; + + my_ffi_struct_fields[0] = &ffi_type_double; + my_ffi_struct_fields[1] = &ffi_type_double; + my_ffi_struct_fields[2] = &ffi_type_double; + my_ffi_struct_fields[3] = NULL; + + arg_types[0] = &my_ffi_struct_type; + arg_types[1] = &my_ffi_struct_type; + arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type, + arg_types) == FFI_OK); + + args[0] = &g; + args[1] = &f; + args[2] = NULL; + ffi_call(&cif, FFI_FN(callee), &res, args); + /* { dg-output "1 2 3 1 2 3: 2 4 6" } */ + printf("res: %g %g %g\n", res.a, res.b, res.c); + /* { dg-output "\nres: 2 4 6" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, stub, NULL, code) == FFI_OK); + + res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(code))(g, f); + /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */ + printf("res: %g %g %g\n", res.a, res.b, res.c); + /* { dg-output "\nres: 2 4 6" } */ + + exit(0);; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/promotion.c b/circuitpython/lib/libffi/testsuite/libffi.call/promotion.c new file mode 100644 index 0000000..4456161 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/promotion.c @@ -0,0 +1,59 @@ +/* Area: ffi_call + Purpose: Promotion test. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" +static int promotion(signed char sc, signed short ss, + unsigned char uc, unsigned short us) +{ + int r = (int) sc + (int) ss + (int) uc + (int) us; + + return r; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + signed char sc; + unsigned char uc; + signed short ss; + unsigned short us; + unsigned long ul; + + args[0] = &ffi_type_schar; + args[1] = &ffi_type_sshort; + args[2] = &ffi_type_uchar; + args[3] = &ffi_type_ushort; + values[0] = ≻ + values[1] = &ss; + values[2] = &uc; + values[3] = &us; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_sint, args) == FFI_OK); + + us = 0; + ul = 0; + + for (sc = (signed char) -127; + sc <= (signed char) 120; sc += 1) + for (ss = -30000; ss <= 30000; ss += 10000) + for (uc = (unsigned char) 0; + uc <= (unsigned char) 200; uc += 20) + for (us = 0; us <= 60000; us += 10000) + { + ul++; + ffi_call(&cif, FFI_FN(promotion), &rint, values); + CHECK((int)rint == (signed char) sc + (signed short) ss + + (unsigned char) uc + (unsigned short) us); + } + printf("%lu promotion tests run\n", ul); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/pyobjc-tc.c b/circuitpython/lib/libffi/testsuite/libffi.call/pyobjc-tc.c new file mode 100644 index 0000000..e29bd6c --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/pyobjc-tc.c @@ -0,0 +1,114 @@ +/* Area: ffi_call + Purpose: Check different structures. + Limitations: none. + PR: none. + Originator: Ronald Oussoren 20030824 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct Point { + float x; + float y; +} Point; + +typedef struct Size { + float h; + float w; +} Size; + +typedef struct Rect { + Point o; + Size s; +} Rect; + +int doit(int o, char* s, Point p, Rect r, int last) +{ + printf("CALLED WITH %d %s {%f %f} {{%f %f} {%f %f}} %d\n", + o, s, p.x, p.y, r.o.x, r.o.y, r.s.h, r.s.w, last); + return 42; +} + + +int main(void) +{ + ffi_type point_type; + ffi_type size_type; + ffi_type rect_type; + ffi_cif cif; + ffi_type* arglist[6]; + void* values[6]; + int r; + + /* + * First set up FFI types for the 3 struct types + */ + + point_type.size = 0; /*sizeof(Point);*/ + point_type.alignment = 0; /*__alignof__(Point);*/ + point_type.type = FFI_TYPE_STRUCT; + point_type.elements = malloc(3 * sizeof(ffi_type*)); + point_type.elements[0] = &ffi_type_float; + point_type.elements[1] = &ffi_type_float; + point_type.elements[2] = NULL; + + size_type.size = 0;/* sizeof(Size);*/ + size_type.alignment = 0;/* __alignof__(Size);*/ + size_type.type = FFI_TYPE_STRUCT; + size_type.elements = malloc(3 * sizeof(ffi_type*)); + size_type.elements[0] = &ffi_type_float; + size_type.elements[1] = &ffi_type_float; + size_type.elements[2] = NULL; + + rect_type.size = 0;/*sizeof(Rect);*/ + rect_type.alignment =0;/* __alignof__(Rect);*/ + rect_type.type = FFI_TYPE_STRUCT; + rect_type.elements = malloc(3 * sizeof(ffi_type*)); + rect_type.elements[0] = &point_type; + rect_type.elements[1] = &size_type; + rect_type.elements[2] = NULL; + + /* + * Create a CIF + */ + arglist[0] = &ffi_type_sint; + arglist[1] = &ffi_type_pointer; + arglist[2] = &point_type; + arglist[3] = &rect_type; + arglist[4] = &ffi_type_sint; + arglist[5] = NULL; + + r = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, + 5, &ffi_type_sint, arglist); + if (r != FFI_OK) { + abort(); + } + + + /* And call the function through the CIF */ + + { + Point p = { 1.0, 2.0 }; + Rect r = { { 9.0, 10.0}, { -1.0, -2.0 } }; + int o = 0; + int l = 42; + char* m = "myMethod"; + ffi_arg result; + + values[0] = &o; + values[1] = &m; + values[2] = &p; + values[3] = &r; + values[4] = &l; + values[5] = NULL; + + printf("CALLING WITH %d %s {%f %f} {{%f %f} {%f %f}} %d\n", + o, m, p.x, p.y, r.o.x, r.o.y, r.s.h, r.s.w, l); + + ffi_call(&cif, FFI_FN(doit), &result, values); + + printf ("The result is %d\n", (int)result); + + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl.c new file mode 100644 index 0000000..fd07e50 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl.c @@ -0,0 +1,36 @@ +/* Area: ffi_call + Purpose: Check return value double. + Limitations: none. + PR: none. + Originator: 20050212 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static double return_dbl(double dbl) +{ + printf ("%f\n", dbl); + return 2 * dbl; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + double dbl, rdbl; + + args[0] = &ffi_type_double; + values[0] = &dbl; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_double, args) == FFI_OK); + + for (dbl = -127.3; dbl < 127; dbl++) + { + ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values); + printf ("%f vs %f\n", rdbl, return_dbl(dbl)); + CHECK(rdbl == 2 * dbl); + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl1.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl1.c new file mode 100644 index 0000000..0ea5d50 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl1.c @@ -0,0 +1,43 @@ +/* Area: ffi_call + Purpose: Check return value double. + Limitations: none. + PR: none. + Originator: 20050212 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static double return_dbl(double dbl1, float fl2, unsigned int in3, double dbl4) +{ + return dbl1 + fl2 + in3 + dbl4; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + double dbl1, dbl4, rdbl; + float fl2; + unsigned int in3; + args[0] = &ffi_type_double; + args[1] = &ffi_type_float; + args[2] = &ffi_type_uint; + args[3] = &ffi_type_double; + values[0] = &dbl1; + values[1] = &fl2; + values[2] = &in3; + values[3] = &dbl4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_double, args) == FFI_OK); + dbl1 = 127.0; + fl2 = 128.0; + in3 = 255; + dbl4 = 512.7; + + ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values); + printf ("%f vs %f\n", rdbl, return_dbl(dbl1, fl2, in3, dbl4)); + CHECK(rdbl == dbl1 + fl2 + in3 + dbl4); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl2.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl2.c new file mode 100644 index 0000000..b3818f8 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_dbl2.c @@ -0,0 +1,42 @@ +/* Area: ffi_call + Purpose: Check return value double. + Limitations: none. + PR: none. + Originator: 20050212 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static double return_dbl(double dbl1, double dbl2, unsigned int in3, double dbl4) +{ + return dbl1 + dbl2 + in3 + dbl4; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + double dbl1, dbl2, dbl4, rdbl; + unsigned int in3; + args[0] = &ffi_type_double; + args[1] = &ffi_type_double; + args[2] = &ffi_type_uint; + args[3] = &ffi_type_double; + values[0] = &dbl1; + values[1] = &dbl2; + values[2] = &in3; + values[3] = &dbl4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_double, args) == FFI_OK); + dbl1 = 127.0; + dbl2 = 128.0; + in3 = 255; + dbl4 = 512.7; + + ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values); + printf ("%f vs %f\n", rdbl, return_dbl(dbl1, dbl2, in3, dbl4)); + CHECK(rdbl == dbl1 + dbl2 + in3 + dbl4); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_fl.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_fl.c new file mode 100644 index 0000000..fb8a09e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_fl.c @@ -0,0 +1,35 @@ +/* Area: ffi_call + Purpose: Check return value float. + Limitations: none. + PR: none. + Originator: 20050212 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static float return_fl(float fl) +{ + return 2 * fl; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + float fl, rfl; + + args[0] = &ffi_type_float; + values[0] = &fl; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_float, args) == FFI_OK); + + for (fl = -127.0; fl < 127; fl++) + { + ffi_call(&cif, FFI_FN(return_fl), &rfl, values); + printf ("%f vs %f\n", rfl, return_fl(fl)); + CHECK(rfl == 2 * fl); + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_fl1.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_fl1.c new file mode 100644 index 0000000..c3d92c2 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_fl1.c @@ -0,0 +1,36 @@ +/* Area: ffi_call + Purpose: Check return value float. + Limitations: none. + PR: none. + Originator: 20050212 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static float return_fl(float fl1, float fl2) +{ + return fl1 + fl2; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + float fl1, fl2, rfl; + + args[0] = &ffi_type_float; + args[1] = &ffi_type_float; + values[0] = &fl1; + values[1] = &fl2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, + &ffi_type_float, args) == FFI_OK); + fl1 = 127.0; + fl2 = 128.0; + + ffi_call(&cif, FFI_FN(return_fl), &rfl, values); + printf ("%f vs %f\n", rfl, return_fl(fl1, fl2)); + CHECK(rfl == fl1 + fl2); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_fl2.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_fl2.c new file mode 100644 index 0000000..ddb976c --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_fl2.c @@ -0,0 +1,49 @@ +/* Area: ffi_call + Purpose: Check return value float. + Limitations: none. + PR: none. + Originator: 20050212 */ + +/* { dg-do run } */ +#include "ffitest.h" + +/* Use volatile float to avoid false negative on ix86. See PR target/323. */ +static float return_fl(float fl1, float fl2, float fl3, float fl4) +{ + volatile float sum; + + sum = fl1 + fl2 + fl3 + fl4; + return sum; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + float fl1, fl2, fl3, fl4, rfl; + volatile float sum; + + args[0] = &ffi_type_float; + args[1] = &ffi_type_float; + args[2] = &ffi_type_float; + args[3] = &ffi_type_float; + values[0] = &fl1; + values[1] = &fl2; + values[2] = &fl3; + values[3] = &fl4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_float, args) == FFI_OK); + fl1 = 127.0; + fl2 = 128.0; + fl3 = 255.1; + fl4 = 512.7; + + ffi_call(&cif, FFI_FN(return_fl), &rfl, values); + printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, fl3, fl4)); + + sum = fl1 + fl2 + fl3 + fl4; + CHECK(rfl == sum); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_fl3.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_fl3.c new file mode 100644 index 0000000..c37877b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_fl3.c @@ -0,0 +1,42 @@ +/* Area: ffi_call + Purpose: Check return value float. + Limitations: none. + PR: none. + Originator: 20050212 */ + +/* { dg-do run } */ +#include "ffitest.h" + +static float return_fl(float fl1, float fl2, unsigned int in3, float fl4) +{ + return fl1 + fl2 + in3 + fl4; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + float fl1, fl2, fl4, rfl; + unsigned int in3; + args[0] = &ffi_type_float; + args[1] = &ffi_type_float; + args[2] = &ffi_type_uint; + args[3] = &ffi_type_float; + values[0] = &fl1; + values[1] = &fl2; + values[2] = &in3; + values[3] = &fl4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_float, args) == FFI_OK); + fl1 = 127.0; + fl2 = 128.0; + in3 = 255; + fl4 = 512.7; + + ffi_call(&cif, FFI_FN(return_fl), &rfl, values); + printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, in3, fl4)); + CHECK(rfl == fl1 + fl2 + in3 + fl4); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_ldl.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_ldl.c new file mode 100644 index 0000000..52a92fe --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_ldl.c @@ -0,0 +1,34 @@ +/* Area: ffi_call + Purpose: Check return value long double. + Limitations: none. + PR: none. + Originator: 20071113 */ +/* { dg-do run } */ + +#include "ffitest.h" + +static long double return_ldl(long double ldl) +{ + return 2*ldl; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + long double ldl, rldl; + + args[0] = &ffi_type_longdouble; + values[0] = &ldl; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_longdouble, args) == FFI_OK); + + for (ldl = -127.0; ldl < 127.0; ldl++) + { + ffi_call(&cif, FFI_FN(return_ldl), &rldl, values); + CHECK(rldl == 2 * ldl); + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_ll.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_ll.c new file mode 100644 index 0000000..ea4a1e4 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_ll.c @@ -0,0 +1,41 @@ +/* Area: ffi_call + Purpose: Check return value long long. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" +static long long return_ll(long long ll) +{ + return ll; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + long long rlonglong; + long long ll; + + args[0] = &ffi_type_sint64; + values[0] = ≪ + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint64, args) == FFI_OK); + + for (ll = 0LL; ll < 100LL; ll++) + { + ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); + CHECK(rlonglong == ll); + } + + for (ll = 55555555555000LL; ll < 55555555555100LL; ll++) + { + ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); + CHECK(rlonglong == ll); + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_ll1.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_ll1.c new file mode 100644 index 0000000..593e8a3 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_ll1.c @@ -0,0 +1,43 @@ +/* Area: ffi_call + Purpose: Check if long long are passed in the corresponding regs on ppc. + Limitations: none. + PR: 20104. + Originator: 20050222 */ + +/* { dg-do run } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ +#include "ffitest.h" +static long long return_ll(int ll0, long long ll1, int ll2) +{ + return ll0 + ll1 + ll2; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + long long rlonglong; + long long ll1; + unsigned ll0, ll2; + + args[0] = &ffi_type_sint; + args[1] = &ffi_type_sint64; + args[2] = &ffi_type_sint; + values[0] = &ll0; + values[1] = &ll1; + values[2] = &ll2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &ffi_type_sint64, args) == FFI_OK); + + ll0 = 11111111; + ll1 = 11111111111000LL; + ll2 = 11111111; + + ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); + printf("res: %" PRIdLL ", %" PRIdLL "\n", rlonglong, ll0 + ll1 + ll2); + /* { dg-output "res: 11111133333222, 11111133333222" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_sc.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_sc.c new file mode 100644 index 0000000..a36cf3e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_sc.c @@ -0,0 +1,36 @@ +/* Area: ffi_call + Purpose: Check return value signed char. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +static signed char return_sc(signed char sc) +{ + return sc; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + signed char sc; + + args[0] = &ffi_type_schar; + values[0] = ≻ + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_schar, args) == FFI_OK); + + for (sc = (signed char) -127; + sc < (signed char) 127; sc++) + { + ffi_call(&cif, FFI_FN(return_sc), &rint, values); + CHECK((signed char)rint == sc); + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_sl.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_sl.c new file mode 100644 index 0000000..f0fd345 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_sl.c @@ -0,0 +1,38 @@ +/* Area: ffi_call + Purpose: Check if long as return type is handled correctly. + Limitations: none. + PR: none. + */ + +/* { dg-do run } */ +#include "ffitest.h" +static long return_sl(long l1, long l2) +{ + return l1 - l2; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg res; + unsigned long l1, l2; + + args[0] = &ffi_type_slong; + args[1] = &ffi_type_slong; + values[0] = &l1; + values[1] = &l2; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, + &ffi_type_slong, args) == FFI_OK); + + l1 = 1073741823L; + l2 = 1073741824L; + + ffi_call(&cif, FFI_FN(return_sl), &res, values); + printf("res: %ld, %ld\n", (long)res, l1 - l2); + /* { dg-output "res: -1, -1" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_uc.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_uc.c new file mode 100644 index 0000000..6fe5546 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_uc.c @@ -0,0 +1,38 @@ +/* Area: ffi_call + Purpose: Check return value unsigned char. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +static unsigned char return_uc(unsigned char uc) +{ + return uc; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + + unsigned char uc; + + args[0] = &ffi_type_uchar; + values[0] = &uc; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_uchar, args) == FFI_OK); + + for (uc = (unsigned char) '\x00'; + uc < (unsigned char) '\xff'; uc++) + { + ffi_call(&cif, FFI_FN(return_uc), &rint, values); + CHECK((unsigned char)rint == uc); + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/return_ul.c b/circuitpython/lib/libffi/testsuite/libffi.call/return_ul.c new file mode 100644 index 0000000..12b266f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/return_ul.c @@ -0,0 +1,38 @@ +/* Area: ffi_call + Purpose: Check if unsigned long as return type is handled correctly. + Limitations: none. + PR: none. + Originator: 20060724 */ + +/* { dg-do run } */ +#include "ffitest.h" +static unsigned long return_ul(unsigned long ul1, unsigned long ul2) +{ + return ul1 + ul2; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg res; + unsigned long ul1, ul2; + + args[0] = &ffi_type_ulong; + args[1] = &ffi_type_ulong; + values[0] = &ul1; + values[1] = &ul2; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, + &ffi_type_ulong, args) == FFI_OK); + + ul1 = 1073741823L; + ul2 = 1073741824L; + + ffi_call(&cif, FFI_FN(return_ul), &res, values); + printf("res: %lu, %lu\n", (unsigned long)res, ul1 + ul2); + /* { dg-output "res: 2147483647, 2147483647" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/stret_large.c b/circuitpython/lib/libffi/testsuite/libffi.call/stret_large.c new file mode 100644 index 0000000..71c2469 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/stret_large.c @@ -0,0 +1,145 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure returning with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/21/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +/* 13 FPRs: 104 bytes */ +/* 14 FPRs: 112 bytes */ + +typedef struct struct_108byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double i; + double j; + double k; + double l; + double m; + int n; +} struct_108byte; + +struct_108byte cls_struct_108byte_fn( + struct_108byte b0, + struct_108byte b1, + struct_108byte b2, + struct_108byte b3) +{ + struct_108byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + result.i = b0.i + b1.i + b2.i + b3.i; + result.j = b0.j + b1.j + b2.j + b3.j; + result.k = b0.k + b1.k + b2.k + b3.k; + result.l = b0.l + b1.l + b2.l + b3.l; + result.m = b0.m + b1.m + b2.m + b3.m; + result.n = b0.n + b1.n + b2.n + b3.n; + + printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h, result.i, + result.j, result.k, result.l, result.m, result.n); + + return result; +} + +static void +cls_struct_108byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + struct_108byte b0, b1, b2, b3; + + b0 = *(struct_108byte*)(args[0]); + b1 = *(struct_108byte*)(args[1]); + b2 = *(struct_108byte*)(args[2]); + b3 = *(struct_108byte*)(args[3]); + + *(struct_108byte*)resp = cls_struct_108byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[15]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 }; + struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 }; + struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 }; + struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 }; + struct_108byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = &ffi_type_double; + cls_struct_fields[9] = &ffi_type_double; + cls_struct_fields[10] = &ffi_type_double; + cls_struct_fields[11] = &ffi_type_double; + cls_struct_fields[12] = &ffi_type_double; + cls_struct_fields[13] = &ffi_type_sint32; + cls_struct_fields[14] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_108byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, + res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_108byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((struct_108byte(*)(struct_108byte, struct_108byte, + struct_108byte, struct_108byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, + res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/stret_large2.c b/circuitpython/lib/libffi/testsuite/libffi.call/stret_large2.c new file mode 100644 index 0000000..d9c750e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/stret_large2.c @@ -0,0 +1,148 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure returning with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/21/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +/* 13 FPRs: 104 bytes */ +/* 14 FPRs: 112 bytes */ + +typedef struct struct_116byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double i; + double j; + double k; + double l; + double m; + double n; + int o; +} struct_116byte; + +struct_116byte cls_struct_116byte_fn( + struct_116byte b0, + struct_116byte b1, + struct_116byte b2, + struct_116byte b3) +{ + struct_116byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + result.i = b0.i + b1.i + b2.i + b3.i; + result.j = b0.j + b1.j + b2.j + b3.j; + result.k = b0.k + b1.k + b2.k + b3.k; + result.l = b0.l + b1.l + b2.l + b3.l; + result.m = b0.m + b1.m + b2.m + b3.m; + result.n = b0.n + b1.n + b2.n + b3.n; + result.o = b0.o + b1.o + b2.o + b3.o; + + printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h, result.i, + result.j, result.k, result.l, result.m, result.n, result.o); + + return result; +} + +static void +cls_struct_116byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + struct_116byte b0, b1, b2, b3; + + b0 = *(struct_116byte*)(args[0]); + b1 = *(struct_116byte*)(args[1]); + b2 = *(struct_116byte*)(args[2]); + b3 = *(struct_116byte*)(args[3]); + + *(struct_116byte*)resp = cls_struct_116byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[16]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 }; + struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 }; + struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 }; + struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 }; + struct_116byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = &ffi_type_double; + cls_struct_fields[9] = &ffi_type_double; + cls_struct_fields[10] = &ffi_type_double; + cls_struct_fields[11] = &ffi_type_double; + cls_struct_fields[12] = &ffi_type_double; + cls_struct_fields[13] = &ffi_type_double; + cls_struct_fields[14] = &ffi_type_sint32; + cls_struct_fields[15] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_116byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, + res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_116byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((struct_116byte(*)(struct_116byte, struct_116byte, + struct_116byte, struct_116byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, + res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/stret_medium.c b/circuitpython/lib/libffi/testsuite/libffi.call/stret_medium.c new file mode 100644 index 0000000..973ee02 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/stret_medium.c @@ -0,0 +1,124 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure returning with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/21/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +typedef struct struct_72byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double i; +} struct_72byte; + +struct_72byte cls_struct_72byte_fn( + struct_72byte b0, + struct_72byte b1, + struct_72byte b2, + struct_72byte b3) +{ + struct_72byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + result.i = b0.i + b1.i + b2.i + b3.i; + + printf("%g %g %g %g %g %g %g %g %g\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h, result.i); + + return result; +} + +static void +cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + struct_72byte b0, b1, b2, b3; + + b0 = *(struct_72byte*)(args[0]); + b1 = *(struct_72byte*)(args[1]); + b2 = *(struct_72byte*)(args[2]); + b3 = *(struct_72byte*)(args[3]); + + *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[10]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 }; + struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 }; + struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 }; + struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 }; + struct_72byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = &ffi_type_double; + cls_struct_fields[9] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte, + struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/stret_medium2.c b/circuitpython/lib/libffi/testsuite/libffi.call/stret_medium2.c new file mode 100644 index 0000000..84323d1 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/stret_medium2.c @@ -0,0 +1,125 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure returning with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/21/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ +#include "ffitest.h" + +typedef struct struct_72byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + long long i; +} struct_72byte; + +struct_72byte cls_struct_72byte_fn( + struct_72byte b0, + struct_72byte b1, + struct_72byte b2, + struct_72byte b3) +{ + struct_72byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + result.i = b0.i + b1.i + b2.i + b3.i; + + printf("%g %g %g %g %g %g %g %g %" PRIdLL "\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h, result.i); + + return result; +} + +static void +cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + struct_72byte b0, b1, b2, b3; + + b0 = *(struct_72byte*)(args[0]); + b1 = *(struct_72byte*)(args[1]); + b2 = *(struct_72byte*)(args[2]); + b3 = *(struct_72byte*)(args[3]); + + *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[10]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 }; + struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 }; + struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 }; + struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 }; + struct_72byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = &ffi_type_sint64; + cls_struct_fields[9] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18 16" } */ + printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte, + struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */ + printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/strlen.c b/circuitpython/lib/libffi/testsuite/libffi.call/strlen.c new file mode 100644 index 0000000..35b70ea --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/strlen.c @@ -0,0 +1,44 @@ +/* Area: ffi_call + Purpose: Check strlen function call. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +static size_t ABI_ATTR my_strlen(char *s) +{ + return (strlen(s)); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + char *s; + + args[0] = &ffi_type_pointer; + values[0] = (void*) &s; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, + &ffi_type_sint, args) == FFI_OK); + + s = "a"; + ffi_call(&cif, FFI_FN(my_strlen), &rint, values); + CHECK(rint == 1); + + s = "1234567"; + ffi_call(&cif, FFI_FN(my_strlen), &rint, values); + CHECK(rint == 7); + + s = "1234567890123456789012345"; + ffi_call(&cif, FFI_FN(my_strlen), &rint, values); + CHECK(rint == 25); + + exit (0); +} + diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/strlen2.c b/circuitpython/lib/libffi/testsuite/libffi.call/strlen2.c new file mode 100644 index 0000000..96282bc --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/strlen2.c @@ -0,0 +1,49 @@ +/* Area: ffi_call + Purpose: Check strlen function call with additional arguments. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static size_t ABI_ATTR my_f(char *s, float a) +{ + return (size_t) ((int) strlen(s) + (int) a); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + char *s; + float v2; + args[0] = &ffi_type_pointer; + args[1] = &ffi_type_float; + values[0] = (void*) &s; + values[1] = (void*) &v2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, + &ffi_type_sint, args) == FFI_OK); + + s = "a"; + v2 = 0.0; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 1); + + s = "1234567"; + v2 = -1.0; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 6); + + s = "1234567890123456789012345"; + v2 = 1.0; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 26); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/strlen3.c b/circuitpython/lib/libffi/testsuite/libffi.call/strlen3.c new file mode 100644 index 0000000..beba86e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/strlen3.c @@ -0,0 +1,49 @@ +/* Area: ffi_call + Purpose: Check strlen function call with additional arguments. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static size_t ABI_ATTR my_f(float a, char *s) +{ + return (size_t) ((int) strlen(s) + (int) a); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + char *s; + float v2; + args[1] = &ffi_type_pointer; + args[0] = &ffi_type_float; + values[1] = (void*) &s; + values[0] = (void*) &v2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, + &ffi_type_sint, args) == FFI_OK); + + s = "a"; + v2 = 0.0; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 1); + + s = "1234567"; + v2 = -1.0; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 6); + + s = "1234567890123456789012345"; + v2 = 1.0; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 26); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/strlen4.c b/circuitpython/lib/libffi/testsuite/libffi.call/strlen4.c new file mode 100644 index 0000000..d5d42b4 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/strlen4.c @@ -0,0 +1,55 @@ +/* Area: ffi_call + Purpose: Check strlen function call with additional arguments. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static size_t ABI_ATTR my_f(float a, char *s, int i) +{ + return (size_t) ((int) strlen(s) + (int) a + i); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + char *s; + int v1; + float v2; + args[2] = &ffi_type_sint; + args[1] = &ffi_type_pointer; + args[0] = &ffi_type_float; + values[2] = (void*) &v1; + values[1] = (void*) &s; + values[0] = (void*) &v2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 3, + &ffi_type_sint, args) == FFI_OK); + + s = "a"; + v1 = 1; + v2 = 0.0; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 2); + + s = "1234567"; + v2 = -1.0; + v1 = -2; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 4); + + s = "1234567890123456789012345"; + v2 = 1.0; + v1 = 2; + ffi_call(&cif, FFI_FN(my_f), &rint, values); + CHECK(rint == 28); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct1.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct1.c new file mode 100644 index 0000000..c13e23f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct1.c @@ -0,0 +1,67 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct +{ + unsigned char uc; + double d; + unsigned int ui; +} test_structure_1; + +static test_structure_1 ABI_ATTR struct1(test_structure_1 ts) +{ + ts.uc++; + ts.d--; + ts.ui++; + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type ts1_type; + ffi_type *ts1_type_elements[4]; + + test_structure_1 ts1_arg; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_1 *ts1_result = + (test_structure_1 *) malloc (sizeof(test_structure_1)); + + ts1_type.size = 0; + ts1_type.alignment = 0; + ts1_type.type = FFI_TYPE_STRUCT; + ts1_type.elements = ts1_type_elements; + ts1_type_elements[0] = &ffi_type_uchar; + ts1_type_elements[1] = &ffi_type_double; + ts1_type_elements[2] = &ffi_type_uint; + ts1_type_elements[3] = NULL; + + args[0] = &ts1_type; + values[0] = &ts1_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, + &ts1_type, args) == FFI_OK); + + ts1_arg.uc = '\x01'; + ts1_arg.d = 3.14159; + ts1_arg.ui = 555; + + ffi_call(&cif, FFI_FN(struct1), ts1_result, values); + + CHECK(ts1_result->ui == 556); + CHECK(ts1_result->d == 3.14159 - 1); + + free (ts1_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct2.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct2.c new file mode 100644 index 0000000..5077a5e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct2.c @@ -0,0 +1,67 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct +{ + double d1; + double d2; +} test_structure_2; + +static test_structure_2 ABI_ATTR struct2(test_structure_2 ts) +{ + ts.d1--; + ts.d2--; + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + test_structure_2 ts2_arg; + ffi_type ts2_type; + ffi_type *ts2_type_elements[3]; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_2 *ts2_result = + (test_structure_2 *) malloc (sizeof(test_structure_2)); + + ts2_type.size = 0; + ts2_type.alignment = 0; + ts2_type.type = FFI_TYPE_STRUCT; + ts2_type.elements = ts2_type_elements; + ts2_type_elements[0] = &ffi_type_double; + ts2_type_elements[1] = &ffi_type_double; + ts2_type_elements[2] = NULL; + + args[0] = &ts2_type; + values[0] = &ts2_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts2_type, args) == FFI_OK); + + ts2_arg.d1 = 5.55; + ts2_arg.d2 = 6.66; + + printf ("%g\n", ts2_arg.d1); + printf ("%g\n", ts2_arg.d2); + + ffi_call(&cif, FFI_FN(struct2), ts2_result, values); + + printf ("%g\n", ts2_result->d1); + printf ("%g\n", ts2_result->d2); + + CHECK(ts2_result->d1 == 5.55 - 1); + CHECK(ts2_result->d2 == 6.66 - 1); + + free (ts2_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct3.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct3.c new file mode 100644 index 0000000..7eba0ea --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct3.c @@ -0,0 +1,60 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct +{ + int si; +} test_structure_3; + +static test_structure_3 ABI_ATTR struct3(test_structure_3 ts) +{ + ts.si = -(ts.si*2); + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + int compare_value; + ffi_type ts3_type; + ffi_type *ts3_type_elements[2]; + + test_structure_3 ts3_arg; + test_structure_3 *ts3_result = + (test_structure_3 *) malloc (sizeof(test_structure_3)); + + ts3_type.size = 0; + ts3_type.alignment = 0; + ts3_type.type = FFI_TYPE_STRUCT; + ts3_type.elements = ts3_type_elements; + ts3_type_elements[0] = &ffi_type_sint; + ts3_type_elements[1] = NULL; + + args[0] = &ts3_type; + values[0] = &ts3_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, + &ts3_type, args) == FFI_OK); + + ts3_arg.si = -123; + compare_value = ts3_arg.si; + + ffi_call(&cif, FFI_FN(struct3), ts3_result, values); + + printf ("%d %d\n", ts3_result->si, -(compare_value*2)); + + CHECK(ts3_result->si == -(compare_value*2)); + + free (ts3_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct4.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct4.c new file mode 100644 index 0000000..66a9551 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct4.c @@ -0,0 +1,64 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct +{ + unsigned ui1; + unsigned ui2; + unsigned ui3; +} test_structure_4; + +static test_structure_4 ABI_ATTR struct4(test_structure_4 ts) +{ + ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3; + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type ts4_type; + ffi_type *ts4_type_elements[4]; + + test_structure_4 ts4_arg; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_4 *ts4_result = + (test_structure_4 *) malloc (sizeof(test_structure_4)); + + ts4_type.size = 0; + ts4_type.alignment = 0; + ts4_type.type = FFI_TYPE_STRUCT; + ts4_type.elements = ts4_type_elements; + ts4_type_elements[0] = &ffi_type_uint; + ts4_type_elements[1] = &ffi_type_uint; + ts4_type_elements[2] = &ffi_type_uint; + ts4_type_elements[3] = NULL; + + args[0] = &ts4_type; + values[0] = &ts4_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts4_type, args) == FFI_OK); + + ts4_arg.ui1 = 2; + ts4_arg.ui2 = 3; + ts4_arg.ui3 = 4; + + ffi_call (&cif, FFI_FN(struct4), ts4_result, values); + + CHECK(ts4_result->ui3 == 2U * 3U * 4U); + + + free (ts4_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct5.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct5.c new file mode 100644 index 0000000..23e2a3f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct5.c @@ -0,0 +1,66 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" +typedef struct +{ + char c1; + char c2; +} test_structure_5; + +static test_structure_5 ABI_ATTR struct5(test_structure_5 ts1, test_structure_5 ts2) +{ + ts1.c1 += ts2.c1; + ts1.c2 -= ts2.c2; + + return ts1; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type ts5_type; + ffi_type *ts5_type_elements[3]; + + test_structure_5 ts5_arg1, ts5_arg2; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_5 *ts5_result = + (test_structure_5 *) malloc (sizeof(test_structure_5)); + + ts5_type.size = 0; + ts5_type.alignment = 0; + ts5_type.type = FFI_TYPE_STRUCT; + ts5_type.elements = ts5_type_elements; + ts5_type_elements[0] = &ffi_type_schar; + ts5_type_elements[1] = &ffi_type_schar; + ts5_type_elements[2] = NULL; + + args[0] = &ts5_type; + args[1] = &ts5_type; + values[0] = &ts5_arg1; + values[1] = &ts5_arg2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts5_type, args) == FFI_OK); + + ts5_arg1.c1 = 2; + ts5_arg1.c2 = 6; + ts5_arg2.c1 = 5; + ts5_arg2.c2 = 3; + + ffi_call (&cif, FFI_FN(struct5), ts5_result, values); + + CHECK(ts5_result->c1 == 7); + CHECK(ts5_result->c2 == 3); + + + free (ts5_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct6.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct6.c new file mode 100644 index 0000000..173c66e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct6.c @@ -0,0 +1,64 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" +typedef struct +{ + float f; + double d; +} test_structure_6; + +static test_structure_6 ABI_ATTR struct6 (test_structure_6 ts) +{ + ts.f += 1; + ts.d += 1; + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type ts6_type; + ffi_type *ts6_type_elements[3]; + + test_structure_6 ts6_arg; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_6 *ts6_result = + (test_structure_6 *) malloc (sizeof(test_structure_6)); + + ts6_type.size = 0; + ts6_type.alignment = 0; + ts6_type.type = FFI_TYPE_STRUCT; + ts6_type.elements = ts6_type_elements; + ts6_type_elements[0] = &ffi_type_float; + ts6_type_elements[1] = &ffi_type_double; + ts6_type_elements[2] = NULL; + + args[0] = &ts6_type; + values[0] = &ts6_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts6_type, args) == FFI_OK); + + ts6_arg.f = 5.55f; + ts6_arg.d = 6.66; + + printf ("%g\n", ts6_arg.f); + printf ("%g\n", ts6_arg.d); + + ffi_call(&cif, FFI_FN(struct6), ts6_result, values); + + CHECK(ts6_result->f == 5.55f + 1); + CHECK(ts6_result->d == 6.66 + 1); + + free (ts6_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct7.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct7.c new file mode 100644 index 0000000..badc7e0 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct7.c @@ -0,0 +1,74 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" +typedef struct +{ + float f1; + float f2; + double d; +} test_structure_7; + +static test_structure_7 ABI_ATTR struct7 (test_structure_7 ts) +{ + ts.f1 += 1; + ts.f2 += 1; + ts.d += 1; + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type ts7_type; + ffi_type *ts7_type_elements[4]; + + test_structure_7 ts7_arg; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_7 *ts7_result = + (test_structure_7 *) malloc (sizeof(test_structure_7)); + + ts7_type.size = 0; + ts7_type.alignment = 0; + ts7_type.type = FFI_TYPE_STRUCT; + ts7_type.elements = ts7_type_elements; + ts7_type_elements[0] = &ffi_type_float; + ts7_type_elements[1] = &ffi_type_float; + ts7_type_elements[2] = &ffi_type_double; + ts7_type_elements[3] = NULL; + + args[0] = &ts7_type; + values[0] = &ts7_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts7_type, args) == FFI_OK); + + ts7_arg.f1 = 5.55f; + ts7_arg.f2 = 55.5f; + ts7_arg.d = 6.66; + + printf ("%g\n", ts7_arg.f1); + printf ("%g\n", ts7_arg.f2); + printf ("%g\n", ts7_arg.d); + + ffi_call(&cif, FFI_FN(struct7), ts7_result, values); + + printf ("%g\n", ts7_result->f1); + printf ("%g\n", ts7_result->f2); + printf ("%g\n", ts7_result->d); + + CHECK(ts7_result->f1 == 5.55f + 1); + CHECK(ts7_result->f2 == 55.5f + 1); + CHECK(ts7_result->d == 6.66 + 1); + + free (ts7_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct8.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct8.c new file mode 100644 index 0000000..ef204ec --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct8.c @@ -0,0 +1,81 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" +typedef struct +{ + float f1; + float f2; + float f3; + float f4; +} test_structure_8; + +static test_structure_8 ABI_ATTR struct8 (test_structure_8 ts) +{ + ts.f1 += 1; + ts.f2 += 1; + ts.f3 += 1; + ts.f4 += 1; + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type ts8_type; + ffi_type *ts8_type_elements[5]; + + test_structure_8 ts8_arg; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_8 *ts8_result = + (test_structure_8 *) malloc (sizeof(test_structure_8)); + + ts8_type.size = 0; + ts8_type.alignment = 0; + ts8_type.type = FFI_TYPE_STRUCT; + ts8_type.elements = ts8_type_elements; + ts8_type_elements[0] = &ffi_type_float; + ts8_type_elements[1] = &ffi_type_float; + ts8_type_elements[2] = &ffi_type_float; + ts8_type_elements[3] = &ffi_type_float; + ts8_type_elements[4] = NULL; + + args[0] = &ts8_type; + values[0] = &ts8_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts8_type, args) == FFI_OK); + + ts8_arg.f1 = 5.55f; + ts8_arg.f2 = 55.5f; + ts8_arg.f3 = -5.55f; + ts8_arg.f4 = -55.5f; + + printf ("%g\n", ts8_arg.f1); + printf ("%g\n", ts8_arg.f2); + printf ("%g\n", ts8_arg.f3); + printf ("%g\n", ts8_arg.f4); + + ffi_call(&cif, FFI_FN(struct8), ts8_result, values); + + printf ("%g\n", ts8_result->f1); + printf ("%g\n", ts8_result->f2); + printf ("%g\n", ts8_result->f3); + printf ("%g\n", ts8_result->f4); + + CHECK(ts8_result->f1 == 5.55f + 1); + CHECK(ts8_result->f2 == 55.5f + 1); + CHECK(ts8_result->f3 == -5.55f + 1); + CHECK(ts8_result->f4 == -55.5f + 1); + + free (ts8_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/struct9.c b/circuitpython/lib/libffi/testsuite/libffi.call/struct9.c new file mode 100644 index 0000000..4a13b81 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/struct9.c @@ -0,0 +1,68 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct +{ + float f; + int i; +} test_structure_9; + +static test_structure_9 ABI_ATTR struct9 (test_structure_9 ts) +{ + ts.f += 1; + ts.i += 1; + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type ts9_type; + ffi_type *ts9_type_elements[3]; + + test_structure_9 ts9_arg; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_9 *ts9_result = + (test_structure_9 *) malloc (sizeof(test_structure_9)); + + ts9_type.size = 0; + ts9_type.alignment = 0; + ts9_type.type = FFI_TYPE_STRUCT; + ts9_type.elements = ts9_type_elements; + ts9_type_elements[0] = &ffi_type_float; + ts9_type_elements[1] = &ffi_type_sint; + ts9_type_elements[2] = NULL; + + args[0] = &ts9_type; + values[0] = &ts9_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts9_type, args) == FFI_OK); + + ts9_arg.f = 5.55f; + ts9_arg.i = 5; + + printf ("%g\n", ts9_arg.f); + printf ("%d\n", ts9_arg.i); + + ffi_call(&cif, FFI_FN(struct9), ts9_result, values); + + printf ("%g\n", ts9_result->f); + printf ("%d\n", ts9_result->i); + + CHECK(ts9_result->f == 5.55f + 1); + CHECK(ts9_result->i == 5 + 1); + + free (ts9_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/testclosure.c b/circuitpython/lib/libffi/testsuite/libffi.call/testclosure.c new file mode 100644 index 0000000..ca31056 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/testclosure.c @@ -0,0 +1,70 @@ +/* Area: closure_call + Purpose: Check return value float. + Limitations: none. + PR: 41908. + Originator: 20091102 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_combined { + float a; + float b; + float c; + float d; +} cls_struct_combined; + +void cls_struct_combined_fn(struct cls_struct_combined arg) +{ + printf("%g %g %g %g\n", + arg.a, arg.b, + arg.c, arg.d); + fflush(stdout); +} + +static void +cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args, void* userdata __UNUSED__) +{ + struct cls_struct_combined a0; + + a0 = *(struct cls_struct_combined*)(args[0]); + + cls_struct_combined_fn(a0); +} + + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type* cls_struct_fields0[5]; + ffi_type cls_struct_type0; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0}; + + cls_struct_type0.size = 0; + cls_struct_type0.alignment = 0; + cls_struct_type0.type = FFI_TYPE_STRUCT; + cls_struct_type0.elements = cls_struct_fields0; + + cls_struct_fields0[0] = &ffi_type_float; + cls_struct_fields0[1] = &ffi_type_float; + cls_struct_fields0[2] = &ffi_type_float; + cls_struct_fields0[3] = &ffi_type_float; + cls_struct_fields0[4] = NULL; + + dbl_arg_types[0] = &cls_struct_type0; + dbl_arg_types[1] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, + dbl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); + + ((void(*)(cls_struct_combined)) (code))(g_dbl); + /* { dg-output "4 5 1 8" } */ + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/uninitialized.c b/circuitpython/lib/libffi/testsuite/libffi.call/uninitialized.c new file mode 100644 index 0000000..f00d830 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/uninitialized.c @@ -0,0 +1,61 @@ +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct +{ + unsigned char uc; + double d; + unsigned int ui; +} test_structure_1; + +static test_structure_1 struct1(test_structure_1 ts) +{ + ts.uc++; + ts.d--; + ts.ui++; + + return ts; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_type ts1_type; + ffi_type *ts1_type_elements[4]; + + memset(&cif, 1, sizeof(cif)); + ts1_type.size = 0; + ts1_type.alignment = 0; + ts1_type.type = FFI_TYPE_STRUCT; + ts1_type.elements = ts1_type_elements; + ts1_type_elements[0] = &ffi_type_uchar; + ts1_type_elements[1] = &ffi_type_double; + ts1_type_elements[2] = &ffi_type_uint; + ts1_type_elements[3] = NULL; + + test_structure_1 ts1_arg; + /* This is a hack to get a properly aligned result buffer */ + test_structure_1 *ts1_result = + (test_structure_1 *) malloc (sizeof(test_structure_1)); + + args[0] = &ts1_type; + values[0] = &ts1_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ts1_type, args) == FFI_OK); + + ts1_arg.uc = '\x01'; + ts1_arg.d = 3.14159; + ts1_arg.ui = 555; + + ffi_call(&cif, FFI_FN(struct1), ts1_result, values); + + CHECK(ts1_result->ui == 556); + CHECK(ts1_result->d == 3.14159 - 1); + + free (ts1_result); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/unwindtest.cc b/circuitpython/lib/libffi/testsuite/libffi.call/unwindtest.cc new file mode 100644 index 0000000..67cfefe --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/unwindtest.cc @@ -0,0 +1,117 @@ +/* Area: ffi_closure, unwind info + Purpose: Check if the unwind information is passed correctly. + Limitations: none. + PR: none. + Originator: Jeff Sturm */ + +/* { dg-do run } */ + +#include "ffitest.h" + +void ABI_ATTR +closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args __UNUSED__, void* userdata __UNUSED__) +{ + throw 9; +} + +typedef void (*closure_test_type)(); + +void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) + { + *(ffi_arg*)resp = + (int)*(float *)args[0] +(int)(*(float *)args[1]) + + (int)(*(float *)args[2]) + (int)*(float *)args[3] + + (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) + + (int)*(float *)args[6] + (int)(*(int *)args[7]) + + (int)(*(double*)args[8]) + (int)*(int *)args[9] + + (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + + (int)*(int *)args[12] + (int)(*(int *)args[13]) + + (int)(*(int *)args[14]) + *(int *)args[15] + (int)(intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(float *)args[0], (int)(*(float *)args[1]), + (int)(*(float *)args[2]), (int)*(float *)args[3], + (int)(*(signed short *)args[4]), (int)(*(float *)args[5]), + (int)*(float *)args[6], (int)(*(int *)args[7]), + (int)(*(double *)args[8]), (int)*(int *)args[9], + (int)(*(int *)args[10]), (int)(*(float *)args[11]), + (int)*(int *)args[12], (int)(*(int *)args[13]), + (int)(*(int *)args[14]), *(int *)args[15], + (int)(intptr_t)userdata, (int)*(ffi_arg*)resp); + + throw (int)*(ffi_arg*)resp; +} + +typedef int (*closure_test_type1)(float, float, float, float, signed short, + float, float, int, double, int, int, float, + int, int, int, int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + + { + cl_arg_types[1] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, + &ffi_type_void, cl_arg_types) == FFI_OK); + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn, NULL, code) == FFI_OK); + + try + { + (*((closure_test_type)(code)))(); + } catch (int exception_code) + { + CHECK(exception_code == 9); + } + + printf("part one OK\n"); + /* { dg-output "part one OK" } */ + } + + { + + cl_arg_types[0] = &ffi_type_float; + cl_arg_types[1] = &ffi_type_float; + cl_arg_types[2] = &ffi_type_float; + cl_arg_types[3] = &ffi_type_float; + cl_arg_types[4] = &ffi_type_sshort; + cl_arg_types[5] = &ffi_type_float; + cl_arg_types[6] = &ffi_type_float; + cl_arg_types[7] = &ffi_type_uint; + cl_arg_types[8] = &ffi_type_double; + cl_arg_types[9] = &ffi_type_uint; + cl_arg_types[10] = &ffi_type_uint; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_uint; + cl_arg_types[13] = &ffi_type_uint; + cl_arg_types[14] = &ffi_type_uint; + cl_arg_types[15] = &ffi_type_uint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1, + (void *) 3 /* userdata */, code) == FFI_OK); + try + { + (*((closure_test_type1)code)) + (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13, + 19, 21, 1); + /* { dg-output "\n1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */ + } catch (int exception_code) + { + CHECK(exception_code == 255); + } + printf("part two OK\n"); + /* { dg-output "\npart two OK" } */ + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc b/circuitpython/lib/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc new file mode 100644 index 0000000..ec61164 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc @@ -0,0 +1,54 @@ +/* Area: ffi_call, unwind info + Purpose: Check if the unwind information is passed correctly. + Limitations: none. + PR: none. + Originator: Andreas Tobler 20061213 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static int checking(int a __UNUSED__, short b __UNUSED__, + signed char c __UNUSED__) +{ + throw 9; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + + signed int si; + signed short ss; + signed char sc; + + args[0] = &ffi_type_sint; + values[0] = &si; + args[1] = &ffi_type_sshort; + values[1] = &ss; + args[2] = &ffi_type_schar; + values[2] = ≻ + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &ffi_type_sint, args) == FFI_OK); + + si = -6; + ss = -12; + sc = -1; + { + try + { + ffi_call(&cif, FFI_FN(checking), &rint, values); + } catch (int exception_code) + { + CHECK(exception_code == 9); + } + printf("part one OK\n"); + /* { dg-output "part one OK" } */ + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/va_1.c b/circuitpython/lib/libffi/testsuite/libffi.call/va_1.c new file mode 100644 index 0000000..7f96809 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/va_1.c @@ -0,0 +1,196 @@ +/* Area: ffi_call + Purpose: Test passing struct in variable argument lists. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ + +#include "ffitest.h" +#include + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static int +test_fn (int n, ...) +{ + va_list ap; + struct small_tag s1; + struct small_tag s2; + struct large_tag l; + unsigned char uc; + signed char sc; + unsigned short us; + signed short ss; + unsigned int ui; + signed int si; + unsigned long ul; + signed long sl; + float f; + double d; + + va_start (ap, n); + s1 = va_arg (ap, struct small_tag); + l = va_arg (ap, struct large_tag); + s2 = va_arg (ap, struct small_tag); + + uc = va_arg (ap, unsigned); + sc = va_arg (ap, signed); + + us = va_arg (ap, unsigned); + ss = va_arg (ap, signed); + + ui = va_arg (ap, unsigned int); + si = va_arg (ap, signed int); + + ul = va_arg (ap, unsigned long); + sl = va_arg (ap, signed long); + + f = va_arg (ap, double); /* C standard promotes float->double + when anonymous */ + d = va_arg (ap, double); + + printf ("%u %u %u %u %u %u %u %u %u uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n", + s1.a, s1.b, l.a, l.b, l.c, l.d, l.e, + s2.a, s2.b, + uc, sc, + us, ss, + ui, si, + ul, sl, + f, d); + va_end (ap); + return n + 1; +} + +int +main (void) +{ + ffi_cif cif; + void* args[15]; + ffi_type* arg_types[15]; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int n; + ffi_arg res; + + unsigned char uc; + signed char sc; + unsigned short us; + signed short ss; + unsigned int ui; + signed int si; + unsigned long ul; + signed long sl; + double d1; + double f1; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = &ffi_type_uchar; + arg_types[5] = &ffi_type_schar; + arg_types[6] = &ffi_type_ushort; + arg_types[7] = &ffi_type_sshort; + arg_types[8] = &ffi_type_uint; + arg_types[9] = &ffi_type_sint; + arg_types[10] = &ffi_type_ulong; + arg_types[11] = &ffi_type_slong; + arg_types[12] = &ffi_type_double; + arg_types[13] = &ffi_type_double; + arg_types[14] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 14, &ffi_type_sint, arg_types) == FFI_OK); + + s1.a = 5; + s1.b = 6; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + s2.a = 7; + s2.b = 8; + + n = 41; + + uc = 9; + sc = 10; + us = 11; + ss = 12; + ui = 13; + si = 14; + ul = 15; + sl = 16; + f1 = 2.12; + d1 = 3.13; + + args[0] = &n; + args[1] = &s1; + args[2] = &l1; + args[3] = &s2; + args[4] = &uc; + args[5] = ≻ + args[6] = &us; + args[7] = &ss; + args[8] = &ui; + args[9] = &si; + args[10] = &ul; + args[11] = &sl; + args[12] = &f1; + args[13] = &d1; + args[14] = NULL; + + ffi_call(&cif, FFI_FN(test_fn), &res, args); + /* { dg-output "5 6 10 11 12 13 14 7 8 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 42" } */ + + return 0; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/va_struct1.c b/circuitpython/lib/libffi/testsuite/libffi.call/va_struct1.c new file mode 100644 index 0000000..e645206 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/va_struct1.c @@ -0,0 +1,121 @@ +/* Area: ffi_call + Purpose: Test passing struct in variable argument lists. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ + +#include "ffitest.h" +#include + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static int +test_fn (int n, ...) +{ + va_list ap; + struct small_tag s1; + struct small_tag s2; + struct large_tag l; + + va_start (ap, n); + s1 = va_arg (ap, struct small_tag); + l = va_arg (ap, struct large_tag); + s2 = va_arg (ap, struct small_tag); + printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e, + s2.a, s2.b); + va_end (ap); + return n + 1; +} + +int +main (void) +{ + ffi_cif cif; + void* args[5]; + ffi_type* arg_types[5]; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int n; + ffi_arg res; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint, arg_types) == FFI_OK); + + s1.a = 5; + s1.b = 6; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + s2.a = 7; + s2.b = 8; + + n = 41; + + args[0] = &n; + args[1] = &s1; + args[2] = &l1; + args[3] = &s2; + args[4] = NULL; + + ffi_call(&cif, FFI_FN(test_fn), &res, args); + /* { dg-output "5 6 10 11 12 13 14 7 8" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 42" } */ + + return 0; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/va_struct2.c b/circuitpython/lib/libffi/testsuite/libffi.call/va_struct2.c new file mode 100644 index 0000000..56f5b9c --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/va_struct2.c @@ -0,0 +1,123 @@ +/* Area: ffi_call + Purpose: Test passing struct in variable argument lists. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ + +#include "ffitest.h" +#include + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static struct small_tag +test_fn (int n, ...) +{ + va_list ap; + struct small_tag s1; + struct small_tag s2; + struct large_tag l; + + va_start (ap, n); + s1 = va_arg (ap, struct small_tag); + l = va_arg (ap, struct large_tag); + s2 = va_arg (ap, struct small_tag); + printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e, + s2.a, s2.b); + va_end (ap); + s1.a += s2.a; + s1.b += s2.b; + return s1; +} + +int +main (void) +{ + ffi_cif cif; + void* args[5]; + ffi_type* arg_types[5]; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int n; + struct small_tag res; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &s_type, arg_types) == FFI_OK); + + s1.a = 5; + s1.b = 6; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + s2.a = 7; + s2.b = 8; + + n = 41; + + args[0] = &n; + args[1] = &s1; + args[2] = &l1; + args[3] = &s2; + args[4] = NULL; + + ffi_call(&cif, FFI_FN(test_fn), &res, args); + /* { dg-output "5 6 10 11 12 13 14 7 8" } */ + printf("res: %d %d\n", res.a, res.b); + /* { dg-output "\nres: 12 14" } */ + + return 0; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c b/circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c new file mode 100644 index 0000000..9a27e7f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c @@ -0,0 +1,125 @@ +/* Area: ffi_call + Purpose: Test passing struct in variable argument lists. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ + +#include "ffitest.h" +#include + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static struct large_tag +test_fn (int n, ...) +{ + va_list ap; + struct small_tag s1; + struct small_tag s2; + struct large_tag l; + + va_start (ap, n); + s1 = va_arg (ap, struct small_tag); + l = va_arg (ap, struct large_tag); + s2 = va_arg (ap, struct small_tag); + printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e, + s2.a, s2.b); + va_end (ap); + l.a += s1.a; + l.b += s1.b; + l.c += s2.a; + l.d += s2.b; + return l; +} + +int +main (void) +{ + ffi_cif cif; + void* args[5]; + ffi_type* arg_types[5]; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int n; + struct large_tag res; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &l_type, arg_types) == FFI_OK); + + s1.a = 5; + s1.b = 6; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + s2.a = 7; + s2.b = 8; + + n = 41; + + args[0] = &n; + args[1] = &s1; + args[2] = &l1; + args[3] = &s2; + args[4] = NULL; + + ffi_call(&cif, FFI_FN(test_fn), &res, args); + /* { dg-output "5 6 10 11 12 13 14 7 8" } */ + printf("res: %d %d %d %d %d\n", res.a, res.b, res.c, res.d, res.e); + /* { dg-output "\nres: 15 17 19 21 14" } */ + + return 0; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex.inc new file mode 100644 index 0000000..4a812ed --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex.inc @@ -0,0 +1,91 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include + +typedef struct cls_struct_align { + unsigned char a; + _Complex T_C_TYPE b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn( + struct cls_struct_align a1, struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %f,%fi %d %d %f,%fi %d: %d %f,%fi %d\n", + a1.a, T_CONV creal (a1.b), T_CONV cimag (a1.b), a1.c, + a2.a, T_CONV creal (a2.b), T_CONV cimag (a2.b), a2.c, + result.a, T_CONV creal (result.b), T_CONV cimag (result.b), result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_c[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* c_arg_types[5]; + + struct cls_struct_align g_c = { 12, 4951 + 7 * I, 127 }; + struct cls_struct_align f_c = { 1, 9320 + 1 * I, 13 }; + struct cls_struct_align res_c; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &T_FFI_TYPE; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + c_arg_types[0] = &cls_struct_type; + c_arg_types[1] = &cls_struct_type; + c_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + c_arg_types) == FFI_OK); + + args_c[0] = &g_c; + args_c[1] = &f_c; + args_c[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_c, args_c); + /* { dg-output "12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */ + printf("res: %d %f,%fi %d\n", + res_c.a, T_CONV creal (res_c.b), T_CONV cimag (res_c.b), res_c.c); + /* { dg-output "\nres: 13 14271,8i 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_c = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_c, f_c); + /* { dg-output "\n12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */ + printf("res: %d %f,%fi %d\n", + res_c.a, T_CONV creal (res_c.b), T_CONV cimag (res_c.b), res_c.c); + /* { dg-output "\nres: 13 14271,8i 140" } */ + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_double.c new file mode 100644 index 0000000..0dff23a --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_align_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_float.c new file mode 100644 index 0000000..0affbd0 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_align_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c new file mode 100644 index 0000000..7889ba8 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_align_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex.inc new file mode 100644 index 0000000..f937404 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex.inc @@ -0,0 +1,42 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include + +static void cls_ret_complex_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + _Complex T_C_TYPE *pa; + _Complex T_C_TYPE *pr; + pa = (_Complex T_C_TYPE *)args[0]; + pr = (_Complex T_C_TYPE *)resp; + *pr = *pa; + + printf("%.6f,%.6fi: %.6f,%.6fi\n", + T_CONV creal (*pa), T_CONV cimag (*pa), + T_CONV creal (*pr), T_CONV cimag (*pr)); + } +typedef _Complex T_C_TYPE (*cls_ret_complex)(_Complex T_C_TYPE); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + _Complex T_C_TYPE res; + + cl_arg_types[0] = &T_FFI_TYPE; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &T_FFI_TYPE, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_complex_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_complex)code))(0.125 + 128.0 * I); + printf("res: %.6f,%.6fi\n", T_CONV creal (res), T_CONV cimag (res)); + CHECK (res == (0.125 + 128.0 * I)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_double.c new file mode 100644 index 0000000..05e3534 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_double.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_float.c new file mode 100644 index 0000000..5df7849 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_float.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_longdouble.c new file mode 100644 index 0000000..2b1c320 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct.inc new file mode 100644 index 0000000..df8708d --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct.inc @@ -0,0 +1,71 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include + +typedef struct Cs { + _Complex T_C_TYPE x; + _Complex T_C_TYPE y; +} Cs; + +Cs gc; + +void +closure_test_fn(Cs p) +{ + printf("%.1f,%.1fi %.1f,%.1fi\n", + T_CONV creal (p.x), T_CONV cimag (p.x), + T_CONV creal (p.y), T_CONV cimag (p.y)); + gc = p; +} + +void +closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args, void* userdata __UNUSED__) +{ + closure_test_fn(*(Cs*)args[0]); +} + +int main(int argc __UNUSED__, char** argv __UNUSED__) +{ + ffi_cif cif; + + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type *cl_arg_types[1]; + + ffi_type ts1_type; + ffi_type* ts1_type_elements[4]; + + Cs arg = { 1.0 + 11.0 * I, 2.0 + 22.0 * I}; + + ts1_type.size = 0; + ts1_type.alignment = 0; + ts1_type.type = FFI_TYPE_STRUCT; + ts1_type.elements = ts1_type_elements; + + ts1_type_elements[0] = &T_FFI_TYPE; + ts1_type_elements[1] = &T_FFI_TYPE; + ts1_type_elements[2] = NULL; + + cl_arg_types[0] = &ts1_type; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_void, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK); + + gc.x = 0.0 + 0.0 * I; + gc.y = 0.0 + 0.0 * I; + ((void*(*)(Cs))(code))(arg); + /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */ + CHECK (gc.x == arg.x && gc.y == arg.y); + + gc.x = 0.0 + 0.0 * I; + gc.y = 0.0 + 0.0 * I; + closure_test_fn(arg); + /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */ + CHECK (gc.x == arg.x && gc.y == arg.y); + + return 0; +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_double.c new file mode 100644 index 0000000..ec71346 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex_struct.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_float.c new file mode 100644 index 0000000..96fdf75 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_complex_struct.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c new file mode 100644 index 0000000..005b467 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex_struct.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va.inc new file mode 100644 index 0000000..8a3e15f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va.inc @@ -0,0 +1,80 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include +#include +#include +#include + +static _Complex T_C_TYPE gComplexValue1 = 1 + 2 * I; +static _Complex T_C_TYPE gComplexValue2 = 3 + 4 * I; + +static int cls_variadic(const char *format, ...) +{ + va_list ap; + _Complex T_C_TYPE p1, p2; + + va_start (ap, format); + p1 = va_arg (ap, _Complex T_C_TYPE); + p2 = va_arg (ap, _Complex T_C_TYPE); + va_end (ap); + + return printf(format, T_CONV creal (p1), T_CONV cimag (p1), + T_CONV creal (p2), T_CONV cimag (p2)); +} + +static void +cls_complex_va_fn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + char* format = *(char**)args[0]; + gComplexValue1 = *(_Complex T_C_TYPE*)args[1]; + gComplexValue2 = *(_Complex T_C_TYPE*)args[2]; + + *(ffi_arg*)resp = + printf(format, + T_CONV creal (gComplexValue1), T_CONV cimag (gComplexValue1), + T_CONV creal (gComplexValue2), T_CONV cimag (gComplexValue2)); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[4]; + ffi_type* arg_types[4]; + char *format = "%.1f,%.1fi %.1f,%.1fi\n"; + + _Complex T_C_TYPE complexArg1 = 1.0 + 22.0 *I; + _Complex T_C_TYPE complexArg2 = 333.0 + 4444.0 *I; + ffi_arg res = 0; + + arg_types[0] = &ffi_type_pointer; + arg_types[1] = &T_FFI_TYPE; + arg_types[2] = &T_FFI_TYPE; + arg_types[3] = NULL; + + /* This printf call is variadic */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 3, &ffi_type_sint, + arg_types) == FFI_OK); + + args[0] = &format; + args[1] = &complexArg1; + args[2] = &complexArg2; + args[3] = NULL; + + ffi_call(&cif, FFI_FN(cls_variadic), &res, args); + printf("res: %d\n", (int) res); + CHECK (res == 24); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_complex_va_fn, NULL, code) + == FFI_OK); + + res = ((int(*)(char *, ...))(code))(format, complexArg1, complexArg2); + CHECK (gComplexValue1 == complexArg1); + CHECK (gComplexValue2 == complexArg2); + printf("res: %d\n", (int) res); + CHECK (res == 24); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_double.c new file mode 100644 index 0000000..879ccf3 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex_va.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_float.c new file mode 100644 index 0000000..2b17826 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_float.c @@ -0,0 +1,16 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +/* Alpha splits _Complex into two arguments. It's illegal to pass + float through varargs, so _Complex float goes badly. In sort of + gets passed as _Complex double, but the compiler doesn't agree + with itself on this issue. */ +/* { dg-do run { xfail alpha*-*-* } } */ + +#include "complex_defs_float.inc" +#include "cls_complex_va.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c new file mode 100644 index 0000000..6eca965 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex_va.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex.exp b/circuitpython/lib/libffi/testsuite/libffi.complex/complex.exp new file mode 100644 index 0000000..4631db2 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex.exp @@ -0,0 +1,36 @@ +# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# . + +dg-init +libffi-init + +global srcdir subdir + +set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] + +if { [libffi_feature_test "#ifdef FFI_TARGET_HAS_COMPLEX_TYPE"] } { + run-many-tests $tlist "" +} else { + foreach test $tlist { + unsupported "$test" + } +} + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/complex.inc new file mode 100644 index 0000000..515ae3e --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex.inc @@ -0,0 +1,51 @@ +/* -*-c-*-*/ +#include "ffitest.h" +#include + +static _Complex T_C_TYPE f_complex(_Complex T_C_TYPE c, int x, int *py) +{ + c = -(2 * creal (c)) + (cimag (c) + 1)* I; + *py += x; + + return c; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + + _Complex T_C_TYPE tc_arg; + _Complex T_C_TYPE tc_result; + int tc_int_arg_x; + int tc_y; + int *tc_ptr_arg_y = &tc_y; + + args[0] = &T_FFI_TYPE; + args[1] = &ffi_type_sint; + args[2] = &ffi_type_pointer; + values[0] = &tc_arg; + values[1] = &tc_int_arg_x; + values[2] = &tc_ptr_arg_y; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &T_FFI_TYPE, args) == FFI_OK); + + tc_arg = 1 + 7 * I; + tc_int_arg_x = 1234; + tc_y = 9876; + ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); + + printf ("%f,%fi %f,%fi, x %d 1234, y %d 11110\n", + T_CONV creal (tc_result), T_CONV cimag (tc_result), + T_CONV creal (2.0), T_CONV creal (8.0), tc_int_arg_x, tc_y); + + CHECK (creal (tc_result) == -2); + CHECK (cimag (tc_result) == 8); + CHECK (tc_int_arg_x == 1234); + CHECK (*tc_ptr_arg_y == 11110); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_double.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_double.inc new file mode 100644 index 0000000..3583e16 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_double.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_double +/* C type corresponding to the base type. */ +#define T_C_TYPE double +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_float.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_float.inc new file mode 100644 index 0000000..bbd9375 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_float.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_float +/* C type corresponding to the base type. */ +#define T_C_TYPE float +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV (double) diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc new file mode 100644 index 0000000..14b9f24 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_longdouble +/* C type corresponding to the base type. */ +#define T_C_TYPE long double +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_double.c new file mode 100644 index 0000000..8a3297b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_float.c new file mode 100644 index 0000000..5044ebb --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex_int.c b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_int.c new file mode 100644 index 0000000..bac3190 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_int.c @@ -0,0 +1,86 @@ +/* Area: ffi_call + Purpose: Check non-standard complex types. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "ffitest.h" +#include "ffi.h" +#include + +_Complex int f_complex(_Complex int c, int x, int *py) +{ + __real__ c = -2 * __real__ c; + __imag__ c = __imag__ c + 1; + *py += x; + return c; +} + +/* + * This macro can be used to define new complex type descriptors + * in a platform independent way. + * + * name: Name of the new descriptor is ffi_type_complex_. + * type: The C base type of the complex type. + */ +#define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \ + static ffi_type *ffi_elements_complex_##name [2] = { \ + (ffi_type *)(&ffitype), NULL \ + }; \ + struct struct_align_complex_##name { \ + char c; \ + _Complex type x; \ + }; \ + ffi_type ffi_type_complex_##name = { \ + sizeof(_Complex type), \ + offsetof(struct struct_align_complex_##name, x), \ + FFI_TYPE_COMPLEX, \ + (ffi_type **)ffi_elements_complex_##name \ + } + +/* Define new complex type descriptors using the macro: */ +/* ffi_type_complex_sint */ +FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint); +/* ffi_type_complex_uchar */ +FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8); + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + + _Complex int tc_arg; + _Complex int tc_result; + int tc_int_arg_x; + int tc_y; + int *tc_ptr_arg_y = &tc_y; + + args[0] = &ffi_type_complex_sint; + args[1] = &ffi_type_sint; + args[2] = &ffi_type_pointer; + values[0] = &tc_arg; + values[1] = &tc_int_arg_x; + values[2] = &tc_ptr_arg_y; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_complex_sint, args) + == FFI_OK); + + tc_arg = 1 + 7 * I; + tc_int_arg_x = 1234; + tc_y = 9876; + ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); + + printf ("%d,%di %d,%di, x %d 1234, y %d 11110\n", + (int)tc_result, (int)(tc_result * -I), 2, 8, tc_int_arg_x, tc_y); + /* dg-output "-2,8i 2,8i, x 1234 1234, y 11110 11110" */ + CHECK (creal (tc_result) == -2); + CHECK (cimag (tc_result) == 8); + CHECK (tc_int_arg_x == 1234); + CHECK (*tc_ptr_arg_y == 11110); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/complex_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_longdouble.c new file mode 100644 index 0000000..7e78366 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/ffitest.h b/circuitpython/lib/libffi/testsuite/libffi.complex/ffitest.h new file mode 100644 index 0000000..d27d362 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/ffitest.h @@ -0,0 +1 @@ +#include "../libffi.call/ffitest.h" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex.inc new file mode 100644 index 0000000..e37a774 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex.inc @@ -0,0 +1,78 @@ +/* -*-c-*- */ +#include "ffitest.h" + +#include +#include + +static _Complex T_C_TYPE many(_Complex T_C_TYPE c1, + _Complex T_C_TYPE c2, + _Complex T_C_TYPE c3, + _Complex T_C_TYPE c4, + _Complex T_C_TYPE c5, + _Complex T_C_TYPE c6, + _Complex T_C_TYPE c7, + _Complex T_C_TYPE c8, + _Complex T_C_TYPE c9, + _Complex T_C_TYPE c10, + _Complex T_C_TYPE c11, + _Complex T_C_TYPE c12, + _Complex T_C_TYPE c13) +{ + printf("0 :%f,%fi\n" + "1 :%f,%fi\n" + "2 :%f,%fi\n" + "3 :%f,%fi\n" + "4 :%f,%fi\n" + "5 :%f,%fi\n" + "6 :%f,%fi\n" + "7 :%f,%fi\n" + "8 :%f,%fi\n" + "9 :%f,%fi\n" + "10:%f,%fi\n" + "11:%f,%fi\n" + "12:%f,%fi\n", + T_CONV creal (c1), T_CONV cimag (c1), + T_CONV creal (c2), T_CONV cimag (c2), + T_CONV creal (c3), T_CONV cimag (c3), + T_CONV creal (c4), T_CONV cimag (c4), + T_CONV creal (c5), T_CONV cimag (c5), + T_CONV creal (c6), T_CONV cimag (c6), + T_CONV creal (c7), T_CONV cimag (c7), + T_CONV creal (c8), T_CONV cimag (c8), + T_CONV creal (c9), T_CONV cimag (c9), + T_CONV creal (c10), T_CONV cimag (c10), + T_CONV creal (c11), T_CONV cimag (c11), + T_CONV creal (c12), T_CONV cimag (c12), + T_CONV creal (c13), T_CONV cimag (c13)); + + return (c1+c2-c3-c4+c5+c6+c7-c8-c9-c10-c11+c12+c13); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[13]; + void *values[13]; + _Complex T_C_TYPE ca[13]; + _Complex T_C_TYPE c, cc; + int i; + + for (i = 0; i < 13; i++) + { + args[i] = &T_FFI_TYPE; + values[i] = &ca[i]; + ca[i] = i + (-20 - i) * I; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, &T_FFI_TYPE, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(many), &c, values); + + cc = many(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7], ca[8], + ca[9], ca[10], ca[11], ca[12]); + CHECK(creal (cc) == creal (c)); + CHECK(cimag (cc) == cimag (c)); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_double.c new file mode 100644 index 0000000..3fd53c3 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "many_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_float.c new file mode 100644 index 0000000..c43d21c --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "many_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_longdouble.c new file mode 100644 index 0000000..dbab723 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/many_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "many_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex.inc new file mode 100644 index 0000000..8bf0c1f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex.inc @@ -0,0 +1,37 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include + +static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c) +{ + printf ("%f,%fi\n", T_CONV creal (c), T_CONV cimag (c)); + return 2 * c; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c, rc, rc2; + T_C_TYPE cr, ci; + + args[0] = &T_FFI_TYPE; + values[0] = &c; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &T_FFI_TYPE, args) == FFI_OK); + + for (cr = -127.0; cr < 127; cr++) + { + ci = 1000.0 - cr; + c = cr + ci * I; + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == 2 * c); + } + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1.inc new file mode 100644 index 0000000..7cecc0f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1.inc @@ -0,0 +1,41 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include + +static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c1, float fl2, unsigned int in3, _Complex T_C_TYPE c4) +{ + return c1 + fl2 + in3 + c4; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c1, c4, rc, rc2; + float fl2; + unsigned int in3; + args[0] = &T_FFI_TYPE; + args[1] = &ffi_type_float; + args[2] = &ffi_type_uint; + args[3] = &T_FFI_TYPE; + values[0] = &c1; + values[1] = &fl2; + values[2] = &in3; + values[3] = &c4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &T_FFI_TYPE, args) == FFI_OK); + c1 = 127.0 + 255.0 * I; + fl2 = 128.0; + in3 = 255; + c4 = 512.7 + 1024.1 * I; + + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c1, fl2, in3, c4); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == rc2); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_double.c new file mode 100644 index 0000000..727410d --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex1.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_float.c new file mode 100644 index 0000000..a2aeada --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex1.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_longdouble.c new file mode 100644 index 0000000..103504b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex1_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex1.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2.inc b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2.inc new file mode 100644 index 0000000..265170b --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2.inc @@ -0,0 +1,44 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include + +_Complex T_C_TYPE +return_c(_Complex T_C_TYPE c1, _Complex T_C_TYPE c2, + unsigned int in3, _Complex T_C_TYPE c4) +{ + volatile _Complex T_C_TYPE r = c1 + c2 + in3 + c4; + return r; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c1, c2, c4, rc, rc2; + unsigned int in3; + args[0] = &T_FFI_TYPE; + args[1] = &T_FFI_TYPE; + args[2] = &ffi_type_uint; + args[3] = &T_FFI_TYPE; + values[0] = &c1; + values[1] = &c2; + values[2] = &in3; + values[3] = &c4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &T_FFI_TYPE, args) == FFI_OK); + c1 = 127.0 + 255.0 * I; + c2 = 128.0 + 256.0; + in3 = 255; + c4 = 512.7 + 1024.1 * I; + + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c1, c2, in3, c4); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == rc2); + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_double.c new file mode 100644 index 0000000..ab9efac --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex2.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_float.c new file mode 100644 index 0000000..d7f22c2 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex2.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_longdouble.c new file mode 100644 index 0000000..3edea62 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex2_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex2.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_double.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_double.c new file mode 100644 index 0000000..e2497cc --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_float.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_float.c new file mode 100644 index 0000000..a35528f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_longdouble.c b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_longdouble.c new file mode 100644 index 0000000..142d7be --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.complex/return_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: . */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex.inc" diff --git a/circuitpython/lib/libffi/testsuite/libffi.go/aa-direct.c b/circuitpython/lib/libffi/testsuite/libffi.go/aa-direct.c new file mode 100644 index 0000000..b00c404 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.go/aa-direct.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ + +#include "static-chain.h" + +#if defined(__GNUC__) && !defined(__clang__) && defined(STATIC_CHAIN_REG) + +#include "ffitest.h" + +/* Blatent assumption here that the prologue doesn't clobber the + static chain for trivial functions. If this is not true, don't + define STATIC_CHAIN_REG, and we'll test what we can via other tests. */ +void *doit(void) +{ + register void *chain __asm__(STATIC_CHAIN_REG); + return chain; +} + +int main() +{ + ffi_cif cif; + void *result; + + CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK); + + ffi_call_go(&cif, FFI_FN(doit), &result, NULL, &result); + + CHECK(result == &result); + + return 0; +} + +#else /* UNSUPPORTED */ +int main() { return 0; } +#endif diff --git a/circuitpython/lib/libffi/testsuite/libffi.go/closure1.c b/circuitpython/lib/libffi/testsuite/libffi.go/closure1.c new file mode 100644 index 0000000..7b34afc --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.go/closure1.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#include "ffitest.h" + +void doit(ffi_cif *cif, void *rvalue, void **avalue, void *closure) +{ + (void)cif; + (void)avalue; + *(void **)rvalue = closure; +} + +typedef void * (*FN)(void); + +int main() +{ + ffi_cif cif; + ffi_go_closure cl; + void *result; + + CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK); + CHECK(ffi_prep_go_closure(&cl, &cif, doit) == FFI_OK); + + ffi_call_go(&cif, FFI_FN(*(FN *)&cl), &result, NULL, &cl); + + CHECK(result == &cl); + + exit(0); +} diff --git a/circuitpython/lib/libffi/testsuite/libffi.go/ffitest.h b/circuitpython/lib/libffi/testsuite/libffi.go/ffitest.h new file mode 100644 index 0000000..d27d362 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.go/ffitest.h @@ -0,0 +1 @@ +#include "../libffi.call/ffitest.h" diff --git a/circuitpython/lib/libffi/testsuite/libffi.go/go.exp b/circuitpython/lib/libffi/testsuite/libffi.go/go.exp new file mode 100644 index 0000000..100c5e7 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.go/go.exp @@ -0,0 +1,36 @@ +# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# . + +dg-init +libffi-init + +global srcdir subdir + +set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] + +if { [libffi_feature_test "#ifdef FFI_GO_CLOSURES"] } { + run-many-tests $tlist "" +} else { + foreach test $tlist { + unsupported "$test" + } +} + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/circuitpython/lib/libffi/testsuite/libffi.go/static-chain.h b/circuitpython/lib/libffi/testsuite/libffi.go/static-chain.h new file mode 100644 index 0000000..3675b40 --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.go/static-chain.h @@ -0,0 +1,19 @@ +#ifdef __aarch64__ +# define STATIC_CHAIN_REG "x18" +#elif defined(__alpha__) +# define STATIC_CHAIN_REG "$1" +#elif defined(__arm__) +# define STATIC_CHAIN_REG "ip" +#elif defined(__sparc__) +# if defined(__arch64__) || defined(__sparcv9) +# define STATIC_CHAIN_REG "g5" +# else +# define STATIC_CHAIN_REG "g2" +# endif +#elif defined(__x86_64__) +# define STATIC_CHAIN_REG "r10" +#elif defined(__i386__) +# ifndef ABI_NUM +# define STATIC_CHAIN_REG "ecx" /* FFI_DEFAULT_ABI only */ +# endif +#endif diff --git a/circuitpython/lib/libffi/texinfo.tex b/circuitpython/lib/libffi/texinfo.tex new file mode 100644 index 0000000..85f184c --- /dev/null +++ b/circuitpython/lib/libffi/texinfo.tex @@ -0,0 +1,10079 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{2013-02-01.11} +% +% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +% 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. +% +% This texinfo.tex file is free software: you can redistribute it and/or +% modify it under the terms of the GNU General Public License as +% published by the Free Software Foundation, either version 3 of the +% License, or (at your option) any later version. +% +% This texinfo.tex file is distributed in the hope that it will be +% useful, but WITHOUT ANY WARRANTY; without even the implied warranty +% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . +% +% As a special exception, when this file is read by TeX when processing +% a Texinfo source document, you may use the result without +% restriction. This Exception is an additional permission under section 7 +% of the GNU General Public License, version 3 ("GPLv3"). +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or +% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or +% http://www.gnu.org/software/texinfo/ (the Texinfo home page) +% The texinfo.tex in any given distribution could well be out +% of date, so if that's what you're using, please check. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever; this makes foo.ps. +% The extra TeX runs get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages, to some +% extent. You can get the existing language-specific files from the +% full Texinfo distribution. +% +% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. + + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +\chardef\other=12 + +% We never want plain's \outer definition of \+ in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +% Save some plain tex macros whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexfootnote=\footnote +\let\ptexgtr=> +\let\ptexhat=^ +\let\ptexi=\i +\let\ptexindent=\indent +\let\ptexinsert=\insert +\let\ptexlbrace=\{ +\let\ptexless=< +\let\ptexnewwrite\newwrite +\let\ptexnoindent=\noindent +\let\ptexplus=+ +\let\ptexraggedright=\raggedright +\let\ptexrbrace=\} +\let\ptexslash=\/ +\let\ptexstar=\* +\let\ptext=\t +\let\ptextop=\top +{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Pre-3.0. +\else + \def\linenumber{l.\the\inputlineno:\space} +\fi + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putworderror\undefined \gdef\putworderror{error}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi + +% Since the category of space is not known, we have to be careful. +\chardef\spacecat = 10 +\def\spaceisspace{\catcode`\ =\spacecat} + +% sometimes characters are active, so we need control sequences. +\chardef\ampChar = `\& +\chardef\colonChar = `\: +\chardef\commaChar = `\, +\chardef\dashChar = `\- +\chardef\dotChar = `\. +\chardef\exclamChar= `\! +\chardef\hashChar = `\# +\chardef\lquoteChar= `\` +\chardef\questChar = `\? +\chardef\rquoteChar= `\' +\chardef\semiChar = `\; +\chardef\slashChar = `\/ +\chardef\underChar = `\_ + +% Ignore a token. +% +\def\gobble#1{} + +% The following is used inside several \edef's. +\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} + +% Hyphenation fixes. +\hyphenation{ + Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script + ap-pen-dix bit-map bit-maps + data-base data-bases eshell fall-ing half-way long-est man-u-script + man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm + par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces + spell-ing spell-ings + stand-alone strong-est time-stamp time-stamps which-ever white-space + wide-spread wrap-around +} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt } + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. We also make +% some effort to order the tracing commands to reduce output in the log +% file; cf. trace.sty in LaTeX. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{% + \tracingstats2 + \tracingpages1 + \tracinglostchars2 % 2 gives us more in etex + \tracingparagraphs1 + \tracingoutput1 + \tracingmacros2 + \tracingrestores1 + \showboxbreadth\maxdimen \showboxdepth\maxdimen + \ifx\eTeXversion\thisisundefined\else % etex gives us more logging + \tracingscantokens1 + \tracingifs1 + \tracinggroups1 + \tracingnesting2 + \tracingassigns1 + \fi + \tracingcommands3 % 3 gives us more in etex + \errorcontextlines16 +}% + +% @errormsg{MSG}. Do the index-like expansions on MSG, but if things +% aren't perfect, it's not the end of the world, being an error message, +% after all. +% +\def\errormsg{\begingroup \indexnofonts \doerrormsg} +\def\doerrormsg#1{\errmessage{#1}} + +% add check for \lastpenalty to plain's definitions. If the last thing +% we did was a \nobreak, we don't want to insert more space. +% +\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount + \removelastskip\penalty-50\smallskip\fi\fi} +\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount + \removelastskip\penalty-100\medskip\fi\fi} +\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount + \removelastskip\penalty-200\bigskip\fi\fi} + +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Output a mark which sets \thischapter, \thissection and \thiscolor. +% We dump everything together because we only have one kind of mark. +% This works because we only use \botmark / \topmark, not \firstmark. +% +% A mark contains a subexpression of the \ifcase ... \fi construct. +% \get*marks macros below extract the needed part using \ifcase. +% +% Another complication is to let the user choose whether \thischapter +% (\thissection) refers to the chapter (section) in effect at the top +% of a page, or that at the bottom of a page. The solution is +% described on page 260 of The TeXbook. It involves outputting two +% marks for the sectioning macros, one before the section break, and +% one after. I won't pretend I can describe this better than DEK... +\def\domark{% + \toks0=\expandafter{\lastchapterdefs}% + \toks2=\expandafter{\lastsectiondefs}% + \toks4=\expandafter{\prevchapterdefs}% + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% + \the\toks0 \the\toks2 + \noexpand\or \the\toks4 \the\toks6 + \noexpand\else \the\toks8 + }% +} +% \topmark doesn't work for the very first chapter (after the title +% page or the contents), so we use \firstmark there -- this gets us +% the mark with the chapter defs, unless the user sneaks in, e.g., +% @setcolor (or @url, or @link, etc.) between @contents and the very +% first @chapter. +\def\gettopheadingmarks{% + \ifcase0\topmark\fi + \ifx\thischapter\empty \ifcase0\firstmark\fi \fi +} +\def\getbottomheadingmarks{\ifcase1\botmark\fi} +\def\getcolormarks{\ifcase2\topmark\fi} + +% Avoid "undefined control sequence" errors. +\def\lastchapterdefs{} +\def\lastsectiondefs{} +\def\prevchapterdefs{} +\def\prevsectiondefs{} +\def\lastcolordefs{} + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + % We don't want .vr (or whatever) entries like this: + % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} + % "\acronym" won't work when it's read back in; + % it needs to be + % {\code {{\tt \backslashcurfont }acronym} + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingyyy.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 24pt + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \indexdummies + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1\relax \unvbox#1\relax +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg{\parseargusing{}} +\def\parseargusing#1#2{% + \def\argtorun{#2}% + \begingroup + \obeylines + \spaceisspace + #1% + \parseargline\empty% Insert the \empty token, see \finishparsearg below. +} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + \argremovecomment #1\comment\ArgTerm% + }% +} + +% First remove any @comment, then any @c comment. +\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} +\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} + +% Each occurrence of `\^^M' or `\^^M' is replaced by a single space. +% +% \argremovec might leave us with trailing space, e.g., +% @end itemize @c foo +% This space token undergoes the same procedure and is eventually removed +% by \finishparsearg. +% +\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} +\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} +\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% + \def\temp{#3}% + \ifx\temp\empty + % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: + \let\temp\finishparsearg + \else + \let\temp\argcheckspaces + \fi + % Put the space token in: + \temp#1 #3\ArgTerm +} + +% If a _delimited_ argument is enclosed in braces, they get stripped; so +% to get _exactly_ the rest of the line, we had to prevent such situation. +% We prepended an \empty token at the very beginning and we expand it now, +% just before passing the control to \argtorun. +% (Similarly, we have to think about #3 of \argcheckspacesY above: it is +% either the null string, or it ends with \^^M---thus there is no danger +% that a pair of braces would be stripped. +% +% But first, we have to remove the trailing space token. +% +\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} + +% \parseargdef\foo{...} +% is roughly equivalent to +% \def\foo{\parsearg\Xfoo} +% \def\Xfoo#1{...} +% +% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my +% favourite TeX trick. --kasal, 16nov03 + +\def\parseargdef#1{% + \expandafter \doparseargdef \csname\string#1\endcsname #1% +} +\def\doparseargdef#1#2{% + \def#2{\parsearg#1}% + \def#1##1% +} + +% Several utility definitions with active space: +{ + \obeyspaces + \gdef\obeyedspace{ } + + % Make each space character in the input produce a normal interword + % space in the output. Don't allow a line break at this space, as this + % is used only in environments like @example, where each line of input + % should produce a line of output anyway. + % + \gdef\sepspaces{\obeyspaces\let =\tie} + + % If an index command is used in an @example environment, any spaces + % therein should become regular spaces in the raw index file, not the + % expansion of \tie (\leavevmode \penalty \@M \ ). + \gdef\unsepspaces{\let =\space} +} + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +% Define the framework for environments in texinfo.tex. It's used like this: +% +% \envdef\foo{...} +% \def\Efoo{...} +% +% It's the responsibility of \envdef to insert \begingroup before the +% actual body; @end closes the group after calling \Efoo. \envdef also +% defines \thisenv, so the current environment is known; @end checks +% whether the environment name matches. The \checkenv macro can also be +% used to check whether the current environment is the one expected. +% +% Non-false conditionals (@iftex, @ifset) don't fit into this, so they +% are not treated as environments; they don't open a group. (The +% implementation of @end takes care not to call \endgroup in this +% special case.) + + +% At run-time, environments start with this: +\def\startenvironment#1{\begingroup\def\thisenv{#1}} +% initialize +\let\thisenv\empty + +% ... but they get defined via ``\envdef\foo{...}'': +\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} +\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} + +% Check whether we're in the right environment: +\def\checkenv#1{% + \def\temp{#1}% + \ifx\thisenv\temp + \else + \badenverr + \fi +} + +% Environment mismatch, #1 expected: +\def\badenverr{% + \errhelp = \EMsimple + \errmessage{This command can appear only \inenvironment\temp, + not \inenvironment\thisenv}% +} +\def\inenvironment#1{% + \ifx#1\empty + outside of any environment% + \else + in environment \expandafter\string#1% + \fi +} + +% @end foo executes the definition of \Efoo. +% But first, it executes a specialized version of \checkenv +% +\parseargdef\end{% + \if 1\csname iscond.#1\endcsname + \else + % The general wording of \badenverr may not be ideal. + \expandafter\checkenv\csname#1\endcsname + \csname E#1\endcsname + \endgroup + \fi +} + +\newhelp\EMsimple{Press RETURN to continue.} + + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\unskip\hfil\break\hbox{}\ignorespaces} + +% @/ allows a line break. +\let\/=\allowbreak + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=\endofsentencespacefactor\space} + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=\endofsentencespacefactor\space} + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=\endofsentencespacefactor\space} + +% @frenchspacing on|off says whether to put extra space after punctuation. +% +\def\onword{on} +\def\offword{off} +% +\parseargdef\frenchspacing{% + \def\temp{#1}% + \ifx\temp\onword \plainfrenchspacing + \else\ifx\temp\offword \plainnonfrenchspacing + \else + \errhelp = \EMsimple + \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% + \fi\fi +} + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +% Another complication is that the group might be very large. This can +% cause the glue on the previous page to be unduly stretched, because it +% does not have much material. In this case, it's better to add an +% explicit \vfill so that the extra space is at the bottom. The +% threshold for doing this is if the group is more than \vfilllimit +% percent of a page (\vfilllimit can be changed inside of @tex). +% +\newbox\groupbox +\def\vfilllimit{0.7} +% +\envdef\group{% + \ifnum\catcode`\^^M=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + \startsavinginserts + % + \setbox\groupbox = \vtop\bgroup + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% The \vtop produces a box with normal height and large depth; thus, TeX puts +% \baselineskip glue before it, and (when the next line of text is done) +% \lineskip glue after it. Thus, space below is not quite equal to space +% above. But it's pretty close. +\def\Egroup{% + % To get correct interline space between the last line of the group + % and the first line afterwards, we have to propagate \prevdepth. + \endgraf % Not \par, as it may have been set to \lisppar. + \global\dimen1 = \prevdepth + \egroup % End the \vtop. + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \pageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\pageheight + \page + \fi + \fi + \box\groupbox + \prevdepth = \dimen1 + \checkinserts +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\parseargdef\need{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break (and is undocumented). + +\let\br = \par + +% @page forces the start of a new page. +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} + +% This defn is used inside nofill environments such as @example. +\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount + \leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current +% paragraph. For more general purposes, use the \margin insertion +% class. WHICH is `l' or `r'. Not documented, written for gawk manual. +% +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} +% +\def\doinmargin#1#2{\strut\vadjust{% + \nobreak + \kern-\strutdepth + \vtop to \strutdepth{% + \baselineskip=\strutdepth + \vss + % if you have multiple lines of stuff to put here, you'll need to + % make the vbox yourself of the appropriate size. + \ifx#1l% + \llap{\ignorespaces #2\hskip\inmarginspacing}% + \else + \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% + \fi + \null + }% +}} +\def\inleftmargin{\doinmargin l} +\def\inrightmargin{\doinmargin r} +% +% @inmargin{TEXT [, RIGHT-TEXT]} +% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; +% else use TEXT for both). +% +\def\inmargin#1{\parseinmargin #1,,\finish} +\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \def\lefttext{#1}% have both texts + \def\righttext{#2}% + \else + \def\lefttext{#1}% have only one text + \def\righttext{#1}% + \fi + % + \ifodd\pageno + \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin + \else + \def\temp{\inleftmargin\lefttext}% + \fi + \temp +} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). This command +% is not documented, not supported, and doesn't work. +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% @include FILE -- \input text of FILE. +% +\def\include{\parseargusing\filenamecatcodes\includezzz} +\def\includezzz#1{% + \pushthisfilestack + \def\thisfile{#1}% + {% + \makevalueexpandable % we want to expand any @value in FILE. + \turnoffactive % and allow special characters in the expansion + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @include of #1^^J}% + \edef\temp{\noexpand\input #1 }% + % + % This trickery is to read FILE outside of a group, in case it makes + % definitions, etc. + \expandafter + }\temp + \popthisfilestack +} +\def\filenamecatcodes{% + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \catcode`-=\other + \catcode`\`=\other + \catcode`\'=\other +} + +\def\pushthisfilestack{% + \expandafter\pushthisfilestackX\popthisfilestack\StackTerm +} +\def\pushthisfilestackX{% + \expandafter\pushthisfilestackY\thisfile\StackTerm +} +\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% + \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% +} + +\def\popthisfilestack{\errthisfilestackempty} +\def\errthisfilestackempty{\errmessage{Internal error: + the stack of filenames is empty.}} +% +\def\thisfile{} + +% @center line +% outputs that line, centered. +% +\parseargdef\center{% + \ifhmode + \let\centersub\centerH + \else + \let\centersub\centerV + \fi + \centersub{\hfil \ignorespaces#1\unskip \hfil}% + \let\centersub\relax % don't let the definition persist, just in case +} +\def\centerH#1{{% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break +}} +% +\newcount\centerpenalty +\def\centerV#1{% + % The idea here is the same as in \startdefun, \cartouche, etc.: if + % @center is the first thing after a section heading, we need to wipe + % out the negative parskip inserted by \sectionheading, but still + % prevent a page break here. + \centerpenalty = \lastpenalty + \ifnum\centerpenalty>10000 \vskip\parskip \fi + \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi + \line{\kern\leftskip #1\kern\rightskip}% +} + +% @sp n outputs n lines of vertical space +% +\parseargdef\sp{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment +% +\def\comment{\begingroup \catcode`\^^M=\other% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} +% +\let\c=\comment + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% NCHARS can also be the word `asis' or `none'. +% We cannot feasibly implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\parseargdef\paragraphindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\parseargdef\exampleindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @firstparagraphindent WORD +% If WORD is `none', then suppress indentation of the first paragraph +% after a section heading. If WORD is `insert', then do indent at such +% paragraphs. +% +% The paragraph indentation is suppressed or not by calling +% \suppressfirstparagraphindent, which the sectioning commands do. +% We switch the definition of this back and forth according to WORD. +% By default, we suppress indentation. +% +\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +\def\insertword{insert} +% +\parseargdef\firstparagraphindent{% + \def\temp{#1}% + \ifx\temp\noneword + \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent + \else\ifx\temp\insertword + \let\suppressfirstparagraphindent = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @firstparagraphindent option `\temp'}% + \fi\fi +} + +% Here is how we actually suppress indentation. Redefine \everypar to +% \kern backwards by \parindent, and then reset itself to empty. +% +% We also make \indent itself not actually do anything until the next +% paragraph. +% +\gdef\dosuppressfirstparagraphindent{% + \gdef\indent{% + \restorefirstparagraphindent + \indent + }% + \gdef\noindent{% + \restorefirstparagraphindent + \noindent + }% + \global\everypar = {% + \kern -\parindent + \restorefirstparagraphindent + }% +} + +\gdef\restorefirstparagraphindent{% + \global \let \indent = \ptexindent + \global \let \noindent = \ptexnoindent + \global \everypar = {}% +} + + +% @refill is a no-op. +\let\refill=\relax + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi % \openindices needs to do some work in any case. + \openindices + \let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + \openin 1 texinfo.cnf + \ifeof 1 \else \input texinfo.cnf \fi + \closein 1 + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined +\else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi +\fi + +% PDF uses PostScript string constants for the names of xref targets, +% for display in the outlines, and in other places. Thus, we have to +% double any backslashes. Otherwise, a name like "\node" will be +% interpreted as a newline (\n), followed by o, d, e. Not good. +% +% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +% related messages. The final outcome is that it is up to the TeX user +% to double the backslashes and otherwise make the string valid, so +% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to +% do this reliably, so we use it. + +% #1 is a control sequence in which to do the replacements, +% which we \xdef. +\def\txiescapepdf#1{% + \ifx\pdfescapestring\thisisundefined + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \else + % The expandable \pdfescapestring primitive escapes parentheses, + % backslashes, and other special chars. + \xdef#1{\pdfescapestring{#1}}% + \fi +} + +\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images +with PDF output, and none of those formats could be found. (.eps cannot +be supported due to the design of the PDF format; use regular TeX (DVI +output) for that.)} + +\ifpdf + % + % Color manipulation macros based on pdfcolor.tex, + % except using rgb instead of cmyk; the latter is said to render as a + % very dark gray on-screen and a very dark halftone in print, instead + % of actual black. + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + % k sets the color for filling (usual text, etc.); + % K sets the color for stroking (thin rules, e.g., normal _'s). + \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % + \pdfcatalog{/PageMode /UseOutlines} + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\dopdfimage#1#2#3{% + \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\pdfimgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errhelp = \nopdfimagehelp + \errmessage{Could not find image file #1 for pdf}% + \else \gdef\pdfimgext{JPG}% + \fi + \else \gdef\pdfimgext{jpeg}% + \fi + \else \gdef\pdfimgext{jpg}% + \fi + \else \gdef\pdfimgext{png}% + \fi + \else \gdef\pdfimgext{PDF}% + \fi + \else \gdef\pdfimgext{pdf}% + \fi + \closein 1 + \endgroup + % + % without \immediate, ancient pdftex seg faults when the same image is + % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) + \ifnum\pdftexversion < 14 + \immediate\pdfimage + \else + \immediate\pdfximage + \fi + \ifdim \wd0 >0pt width \pdfimagewidth \fi + \ifdim \wd2 >0pt height \pdfimageheight \fi + \ifnum\pdftexversion<13 + #1.\pdfimgext + \else + {#1.\pdfimgext}% + \fi + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + % + \def\pdfmkdest#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \turnoffactive + \makevalueexpandable + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + }} + % + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % + % by default, use a color that is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. + \def\urlcolor{\rgbDarkRed} + \def\linkcolor{\rgbDarkRed} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by 1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + % + % #1 is the section text, which is what will be displayed in the + % outline by the pdf viewer. #2 is the pdf expression for the number + % of subentries (or empty, for subsubsections). #3 is the node text, + % which might be empty if this toc entry had no corresponding node. + % #4 is the page number + % + \def\dopdfoutline#1#2#3#4{% + % Generate a link to the node text if that exists; else, use the + % page number. We could generate a destination for the section + % text in the case where a section has no node, but it doesn't + % seem worth the trouble, since most documents are normally structured. + \edef\pdfoutlinedest{#3}% + \ifx\pdfoutlinedest\empty + \def\pdfoutlinedest{#4}% + \else + \txiescapepdf\pdfoutlinedest + \fi + % + % Also escape PDF chars in the display string. + \edef\pdfoutlinetext{#1}% + \txiescapepdf\pdfoutlinetext + % + \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% + } + % + \def\pdfmakeoutlines{% + \begingroup + % Read toc silently, to get counts of subentries for \pdfoutline. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \def\thischapnum{##2}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + }% + \def\numsecentry##1##2##3##4{% + \advancenumber{chap\thischapnum}% + \def\thissecnum{##2}% + \def\thissubsecnum{0}% + }% + \def\numsubsecentry##1##2##3##4{% + \advancenumber{sec\thissecnum}% + \def\thissubsecnum{##2}% + }% + \def\numsubsubsecentry##1##2##3##4{% + \advancenumber{subsec\thissubsecnum}% + }% + \def\thischapnum{0}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + % + % use \def rather than \let here because we redefine \chapentry et + % al. a second time, below. + \def\appentry{\numchapentry}% + \def\appsecentry{\numsecentry}% + \def\appsubsecentry{\numsubsecentry}% + \def\appsubsubsecentry{\numsubsubsecentry}% + \def\unnchapentry{\numchapentry}% + \def\unnsecentry{\numsecentry}% + \def\unnsubsecentry{\numsubsecentry}% + \def\unnsubsubsecentry{\numsubsubsecentry}% + \readdatafile{toc}% + % + % Read toc second time, this time actually producing the outlines. + % The `-' means take the \expnumber as the absolute number of + % subentries, which we calculated on our first read of the .toc above. + % + % We use the node names as the destinations. + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% count is always zero + \dopdfoutline{##1}{}{##3}{##4}}% + % + % PDF outlines are displayed using system fonts, instead of + % document fonts. Therefore we cannot use special characters, + % since the encoding is unknown. For example, the eogonek from + % Latin 2 (0xea) gets translated to a | character. Info from + % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. + % + % TODO this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Too + % much work for too little return. Just use the ASCII equivalents + % we use for the index sort strings. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + % + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\else + % non-pdf mode + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\setcolor = \gobble + \let\pdfsetcolor = \gobble + \let\pdfmakeoutlines = \relax +\fi % \ifx\pdfoutput + + +\message{fonts,} + +% Change the current font style to #1, remembering it in \curfontstyle. +% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +% italics, not bold italics. +% +\def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname ten#1\endcsname % change the current font +} + +% Select #1 fonts with the current style. +% +\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} + +\def\rm{\fam=0 \setfontstyle{rm}} +\def\it{\fam=\itfam \setfontstyle{it}} +\def\sl{\fam=\slfam \setfontstyle{sl}} +\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +\def\tt{\fam=\ttfam \setfontstyle{tt}} + +% Unfortunately, we have to override this for titles and the like, since +% in those cases "rm" is bold. Sigh. +\def\rmisbold{\rm\def\curfontstyle{bf}} + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf. +\newfam\sffam +\def\sf{\fam=\sffam \setfontstyle{sf}} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this font style. +\def\ttsl{\setfontstyle{ttsl}} + + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +% can get a sort of poor man's double spacing by redefining this. +\def\baselinefactor{1} +% +\newdimen\textleading +\def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% PDF CMaps. See also LaTeX's t1.cmap. +% +% do nothing with this by default. +\expandafter\let\csname cmapOT1\endcsname\gobble +\expandafter\let\csname cmapOT1IT\endcsname\gobble +\expandafter\let\csname cmapOT1TT\endcsname\gobble + +% if we are producing pdf, and we have \pdffontattr, then define cmaps. +% (\pdffontattr was introduced many years ago, but people still run +% older pdftex's; it's easy to conditionalize, so we do.) +\ifpdf \ifx\pdffontattr\thisisundefined \else + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1-0) +%%Title: (TeX-OT1-0 TeX OT1 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1) +/Supplement 0 +>> def +/CMapName /TeX-OT1-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<23> <26> <0023> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +40 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1IT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1IT-0) +%%Title: (TeX-OT1IT-0 TeX OT1IT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1IT) +/Supplement 0 +>> def +/CMapName /TeX-OT1IT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<25> <26> <0025> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +42 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<23> <0023> +<24> <00A3> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1IT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1TT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1TT-0) +%%Title: (TeX-OT1TT-0 TeX OT1TT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1TT) +/Supplement 0 +>> def +/CMapName /TeX-OT1TT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +5 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<21> <26> <0021> +<28> <5F> <0028> +<61> <7E> <0061> +endbfrange +32 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <2191> +<0C> <2193> +<0D> <0027> +<0E> <00A1> +<0F> <00BF> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<20> <2423> +<27> <2019> +<60> <2018> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1TT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +\fi\fi + + +% Set the font macro #1 to the font named \fontprefix#2. +% #3 is the font's design size, #4 is a scale factor, #5 is the CMap +% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). +% Example: +% #1 = \textrm +% #2 = \rmshape +% #3 = 10 +% #4 = \mainmagstep +% #5 = OT1 +% +\def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% +} +% This is what gets called when #5 of \setfont is empty. +\let\cmap\gobble +% +% (end of cmaps) + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\thisisundefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} % where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +% Definitions for a main text size of 11pt. (The default in Texinfo.) +% +\def\definetextfontsizexi{% +% Text fonts (11.2pt, magstep1). +\def\textnominalsize{11pt} +\edef\mainmagstep{\magstephalf} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1095} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstep1}{OT1} +\setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter (and unnumbered) fonts (17.28pt). +\def\chapnominalsize{17pt} +\setfont\chaprm\rmbshape{12}{\magstep2}{OT1} +\setfont\chapit\itbshape{10}{\magstep3}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep3}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} +\setfont\chapsf\sfbshape{17}{1000}{OT1} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3}{OT1} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 +\def\chapecsize{1728} + +% Section fonts (14.4pt). +\def\secnominalsize{14pt} +\setfont\secrm\rmbshape{12}{\magstep1}{OT1} +\setfont\secit\itbshape{10}{\magstep2}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep2}{OT1} +\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\secsf\sfbshape{12}{\magstep1}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2}{OT1} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 +\def\sececsize{1440} + +% Subsection fonts (13.15pt). +\def\ssecnominalsize{13pt} +\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} +\setfont\ssecit\itbshape{10}{1315}{OT1IT} +\setfont\ssecsl\slbshape{10}{1315}{OT1} +\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} +\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1315}{OT1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +\def\ssececsize{1200} + +% Reduced fonts for @acro in text (10pt). +\def\reducednominalsize{10pt} +\setfont\reducedrm\rmshape{10}{1000}{OT1} +\setfont\reducedtt\ttshape{10}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{1000}{OT1} +\setfont\reducedit\itshape{10}{1000}{OT1IT} +\setfont\reducedsl\slshape{10}{1000}{OT1} +\setfont\reducedsf\sfshape{10}{1000}{OT1} +\setfont\reducedsc\scshape{10}{1000}{OT1} +\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} +\font\reducedi=cmmi10 +\font\reducedsy=cmsy10 +\def\reducedecsize{1000} + +\textleading = 13.2pt % line spacing for 11pt CM +\textfonts % reset the current fonts +\rm +} % end of 11pt text font size definitions, \definetextfontsizexi + + +% Definitions to make the main text be 10pt Computer Modern, with +% section, chapter, etc., sizes following suit. This is for the GNU +% Press printing of the Emacs 22 manual. Maybe other manuals in the +% future. Used with @smallbook, which sets the leading to 12pt. +% +\def\definetextfontsizex{% +% Text fonts (10pt). +\def\textnominalsize{10pt} +\edef\mainmagstep{1000} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1000} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstephalf}{OT1} +\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter fonts (14.4pt). +\def\chapnominalsize{14pt} +\setfont\chaprm\rmbshape{12}{\magstep1}{OT1} +\setfont\chapit\itbshape{10}{\magstep2}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep2}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\chapsf\sfbshape{12}{\magstep1}{OT1} +\let\chapbf\chaprm +\setfont\chapsc\scbshape{10}{\magstep2}{OT1} +\font\chapi=cmmi12 scaled \magstep1 +\font\chapsy=cmsy10 scaled \magstep2 +\def\chapecsize{1440} + +% Section fonts (12pt). +\def\secnominalsize{12pt} +\setfont\secrm\rmbshape{12}{1000}{OT1} +\setfont\secit\itbshape{10}{\magstep1}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep1}{OT1} +\setfont\sectt\ttbshape{12}{1000}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} +\setfont\secsf\sfbshape{12}{1000}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep1}{OT1} +\font\seci=cmmi12 +\font\secsy=cmsy10 scaled \magstep1 +\def\sececsize{1200} + +% Subsection fonts (10pt). +\def\ssecnominalsize{10pt} +\setfont\ssecrm\rmbshape{10}{1000}{OT1} +\setfont\ssecit\itbshape{10}{1000}{OT1IT} +\setfont\ssecsl\slbshape{10}{1000}{OT1} +\setfont\ssectt\ttbshape{10}{1000}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} +\setfont\ssecsf\sfbshape{10}{1000}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1000}{OT1} +\font\sseci=cmmi10 +\font\ssecsy=cmsy10 +\def\ssececsize{1000} + +% Reduced fonts for @acro in text (9pt). +\def\reducednominalsize{9pt} +\setfont\reducedrm\rmshape{9}{1000}{OT1} +\setfont\reducedtt\ttshape{9}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{900}{OT1} +\setfont\reducedit\itshape{9}{1000}{OT1IT} +\setfont\reducedsl\slshape{9}{1000}{OT1} +\setfont\reducedsf\sfshape{9}{1000}{OT1} +\setfont\reducedsc\scshape{10}{900}{OT1} +\setfont\reducedttsl\ttslshape{10}{900}{OT1TT} +\font\reducedi=cmmi9 +\font\reducedsy=cmsy9 +\def\reducedecsize{0900} + +\divide\parskip by 2 % reduce space between paragraphs +\textleading = 12pt % line spacing for 10pt CM +\textfonts % reset the current fonts +\rm +} % end of 10pt text font size definitions, \definetextfontsizex + + +% We provide the user-level command +% @fonttextsize 10 +% (or 11) to redefine the text font size. pt is assumed. +% +\def\xiword{11} +\def\xword{10} +\def\xwordpt{10pt} +% +\parseargdef\fonttextsize{% + \def\textsizearg{#1}% + %\wlog{doing @fonttextsize \textsizearg}% + % + % Set \globaldefs so that documents can use this inside @tex, since + % makeinfo 4.8 does not support it, but we need it nonetheless. + % + \begingroup \globaldefs=1 + \ifx\textsizearg\xword \definetextfontsizex + \else \ifx\textsizearg\xiword \definetextfontsizexi + \else + \errhelp=\EMsimple + \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} + \fi\fi + \endgroup +} + + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts except +% in the main text, we don't bother to reset \scriptfont and +% \scriptscriptfont (which would also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy + \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf + \textfont\ttfam=\tentt \textfont\sffam=\tensf +} + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this because \STYLE needs to also set the +% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire +% \tenSTYLE to set the current font. +% +% Each font-changing command also sets the names \lsize (one size lower) +% and \lllsize (three sizes lower). These relative commands are used in +% the LaTeX logo and acronyms. +% +% This all needs generalizing, badly. +% +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy + \let\tenttsl=\textttsl + \def\curfontsize{text}% + \def\lsize{reduced}\def\lllsize{smaller}% + \resetmathfonts \setleading{\textleading}} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \def\curfontsize{title}% + \def\lsize{chap}\def\lllsize{subsec}% + \resetmathfonts \setleading{27pt}} +\def\titlefont#1{{\titlefonts\rmisbold #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy + \let\tenttsl=\chapttsl + \def\curfontsize{chap}% + \def\lsize{sec}\def\lllsize{text}% + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy + \let\tenttsl=\secttsl + \def\curfontsize{sec}% + \def\lsize{subsec}\def\lllsize{reduced}% + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy + \let\tenttsl=\ssecttsl + \def\curfontsize{ssec}% + \def\lsize{text}\def\lllsize{small}% + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts +\def\reducedfonts{% + \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl + \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc + \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy + \let\tenttsl=\reducedttsl + \def\curfontsize{reduced}% + \def\lsize{small}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} +\def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \def\curfontsize{small}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} +\def\smallerfonts{% + \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl + \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc + \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy + \let\tenttsl=\smallerttsl + \def\curfontsize{smaller}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{9.5pt}} + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} + +% Define these just so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Set the fonts to use with the @small... environments. +\let\smallexamplefonts = \smallfonts + +% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample +% can fit this many characters: +% 8.5x11=86 smallbook=72 a4=90 a5=69 +% If we use \scriptfonts (8pt), then we can fit this many characters: +% 8.5x11=90+ smallbook=80 a4=90+ a5=77 +% For me, subjectively, the few extra characters that fit aren't worth +% the additional smallness of 8pt. So I'm making the default 9pt. +% +% By the way, for comparison, here's what fits with @example (10pt): +% 8.5x11=71 smallbook=60 a4=75 a5=58 +% --karl, 24jan03. + +% Set up the default fonts, so we can use them for creating boxes. +% +\definetextfontsizexi + + +\message{markup,} + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will +% define and register \INITMACRO to be called on markup style changes. +% \INITMACRO can check \currentmarkupstyle for the innermost +% style and the set of \ifmarkupSTYLE switches for all styles +% currently in effect. +\newif\ifmarkupvar +\newif\ifmarkupsamp +\newif\ifmarkupkey +%\newif\ifmarkupfile % @file == @samp. +%\newif\ifmarkupoption % @option == @samp. +\newif\ifmarkupcode +\newif\ifmarkupkbd +%\newif\ifmarkupenv % @env == @code. +%\newif\ifmarkupcommand % @command == @code. +\newif\ifmarkuptex % @tex (and part of @math, for now). +\newif\ifmarkupexample +\newif\ifmarkupverb +\newif\ifmarkupverbatim + +\let\currentmarkupstyle\empty + +\def\setupmarkupstyle#1{% + \csname markup#1true\endcsname + \def\currentmarkupstyle{#1}% + \markupstylesetup +} + +\let\markupstylesetup\empty + +\def\defmarkupstylesetup#1{% + \expandafter\def\expandafter\markupstylesetup + \expandafter{\markupstylesetup #1}% + \def#1% +} + +% Markup style setup for left and right quotes. +\defmarkupstylesetup\markupsetuplq{% + \expandafter\let\expandafter \temp + \csname markupsetuplq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuplqdefault \else \temp \fi +} + +\defmarkupstylesetup\markupsetuprq{% + \expandafter\let\expandafter \temp + \csname markupsetuprq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuprqdefault \else \temp \fi +} + +{ +\catcode`\'=\active +\catcode`\`=\active + +\gdef\markupsetuplqdefault{\let`\lq} +\gdef\markupsetuprqdefault{\let'\rq} + +\gdef\markupsetcodequoteleft{\let`\codequoteleft} +\gdef\markupsetcodequoteright{\let'\codequoteright} +} + +\let\markupsetuplqcode \markupsetcodequoteleft +\let\markupsetuprqcode \markupsetcodequoteright +% +\let\markupsetuplqexample \markupsetcodequoteleft +\let\markupsetuprqexample \markupsetcodequoteright +% +\let\markupsetuplqkbd \markupsetcodequoteleft +\let\markupsetuprqkbd \markupsetcodequoteright +% +\let\markupsetuplqsamp \markupsetcodequoteleft +\let\markupsetuprqsamp \markupsetcodequoteright +% +\let\markupsetuplqverb \markupsetcodequoteleft +\let\markupsetuprqverb \markupsetcodequoteright +% +\let\markupsetuplqverbatim \markupsetcodequoteleft +\let\markupsetuprqverbatim \markupsetcodequoteright + +% Allow an option to not use regular directed right quote/apostrophe +% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). +% The undirected quote is ugly, so don't make it the default, but it +% works for pasting with more pdf viewers (at least evince), the +% lilypond developers report. xpdf does work with the regular 0x27. +% +\def\codequoteright{% + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi + \else \char'15 \fi +} +% +% and a similar option for the left quote char vs. a grave accent. +% Modern fonts display ASCII 0x60 as a grave accent, so some people like +% the code environments to do likewise. +% +\def\codequoteleft{% + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% + \else \char'22 \fi + \else \char'22 \fi +} + +% Commands to set the quote options. +% +\parseargdef\codequoteundirected{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% + \fi\fi +} +% +\parseargdef\codequotebacktick{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% + \fi\fi +} + +% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. +\def\noligaturesquoteleft{\relax\lq} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Font commands. + +% #1 is the font command (\sl or \it), #2 is the text to slant. +% If we are in a monospaced environment, however, 1) always use \ttsl, +% and 2) do not add an italic correction. +\def\dosmartslant#1#2{% + \ifusingtt + {{\ttsl #2}\let\next=\relax}% + {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% + \next +} +\def\smartslanted{\dosmartslant\sl} +\def\smartitalic{\dosmartslant\it} + +% Output an italic correction unless \next (presumed to be the following +% character) is such as not to need one. +\def\smartitaliccorrection{% + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% + \else\ptexslash + \fi\fi\fi + \aftersmartic +} + +% Unconditional use \ttsl, and no ic. @var is set to this for defuns. +\def\ttslanted#1{{\ttsl #1}} + +% @cite is like \smartslanted except unconditionally use \sl. We never want +% ttsl for book titles, do we? +\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} + +\def\aftersmartic{} +\def\var#1{% + \let\saveaftersmartic = \aftersmartic + \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% + \smartslanted{#1}% +} + +\let\i=\smartitalic +\let\slanted=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @b, explicit bold. Also @strong. +\def\b#1{{\bf #1}} +\let\strong=\b + +% @sansserif, explicit sans. +\def\sansserif#1{{\sf #1}} + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +% Set sfcode to normal for the chars that usually have another value. +% Can't use plain's \frenchspacing because it uses the `\x notation, and +% sometimes \x has an active definition that messes things up. +% +\catcode`@=11 + \def\plainfrenchspacing{% + \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m + \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m + \def\endofsentencespacefactor{1000}% for @. and friends + } + \def\plainnonfrenchspacing{% + \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 + \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 + \def\endofsentencespacefactor{3000}% for @. and friends + } +\catcode`@=\other +\def\endofsentencespacefactor{3000}% default + +% @t, explicit typewriter. +\def\t#1{% + {\tt \rawbackslash \plainfrenchspacing #1}% + \null +} + +% @samp. +\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} + +% @indicateurl is \samp, that is, with quotes. +\let\indicateurl=\samp + +% @code (and similar) prints in typewriter, but with spaces the same +% size as normal in the surrounding text, without hyphenation, etc. +% This is a subroutine for that. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \plainfrenchspacing + #1% + }% + \null % reset spacefactor to 1000 +} + +% We *must* turn on hyphenation at `-' and `_' in @code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. +% +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active + \global\let'=\rq \global\let`=\lq % default definitions + % + \global\def\code{\begingroup + \setupmarkupstyle{code}% + % The following should really be moved into \setupmarkupstyle handlers. + \catcode\dashChar=\active \catcode\underChar=\active + \ifallowcodebreaks + \let-\codedash + \let_\codeunder + \else + \let-\normaldash + \let_\realunder + \fi + \codex + } +} + +\def\codex #1{\tclose{#1}\endgroup} + +\def\normaldash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% +} + +% An additional complication: the above will allow breaks after, e.g., +% each of the four underscores in __typeof__. This is bad. +% @allowcodebreaks provides a document-level way to turn breaking at - +% and _ on and off. +% +\newif\ifallowcodebreaks \allowcodebreakstrue + +\def\keywordtrue{true} +\def\keywordfalse{false} + +\parseargdef\allowcodebreaks{% + \def\txiarg{#1}% + \ifx\txiarg\keywordtrue + \allowcodebreakstrue + \else\ifx\txiarg\keywordfalse + \allowcodebreaksfalse + \else + \errhelp = \EMsimple + \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% + \fi\fi +} + +% For @command, @env, @file, @option quotes seem unnecessary, +% so use \code rather than \samp. +\let\command=\code +\let\env=\code +\let\file=\code +\let\option=\code + +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. +% (This \urefnobreak definition isn't used now, leaving it for a while +% for comparison.) +\def\urefnobreak#1{\dourefnobreak #1,,,\finish} +\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% This \urefbreak definition is the active one. +\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} +\let\uref=\urefbreak +\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} +\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \urefcode{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% Allow line breaks around only a few characters (only). +\def\urefcatcodes{% + \catcode\ampChar=\active \catcode\dotChar=\active + \catcode\hashChar=\active \catcode\questChar=\active + \catcode\slashChar=\active +} +{ + \urefcatcodes + % + \global\def\urefcode{\begingroup + \setupmarkupstyle{code}% + \urefcatcodes + \let&\urefcodeamp + \let.\urefcodedot + \let#\urefcodehash + \let?\urefcodequest + \let/\urefcodeslash + \codex + } + % + % By default, they are just regular characters. + \global\def&{\normalamp} + \global\def.{\normaldot} + \global\def#{\normalhash} + \global\def?{\normalquest} + \global\def/{\normalslash} +} + +% we put a little stretch before and after the breakable chars, to help +% line breaking of long url's. The unequal skips make look better in +% cmtt at least, especially for dots. +\def\urefprestretch{\urefprebreak \hskip0pt plus.13em } +\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em } +% +\def\urefcodeamp{\urefprestretch \&\urefpoststretch} +\def\urefcodedot{\urefprestretch .\urefpoststretch} +\def\urefcodehash{\urefprestretch \#\urefpoststretch} +\def\urefcodequest{\urefprestretch ?\urefpoststretch} +\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} +{ + \catcode`\/=\active + \global\def\urefcodeslashfinish{% + \urefprestretch \slashChar + % Allow line break only after the final / in a sequence of + % slashes, to avoid line break between the slashes in http://. + \ifx\next/\else \urefpoststretch \fi + } +} + +% One more complication: by default we'll break after the special +% characters, but some people like to break before the special chars, so +% allow that. Also allow no breaking at all, for manual control. +% +\parseargdef\urefbreakstyle{% + \def\txiarg{#1}% + \ifx\txiarg\wordnone + \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordbefore + \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordafter + \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} + \else + \errhelp = \EMsimple + \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\wordafter{after} +\def\wordbefore{before} +\def\wordnone{none} + +\urefbreakstyle after + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\parseargdef\kbdinputstyle{% + \def\txiarg{#1}% + \ifx\txiarg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\txiarg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\txiarg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is `distinct'. +\kbdinputstyle distinct + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} + +\def\xkey{\key} +\def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +} + +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\font\keysy=cmsy9 +%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +% \vbox{\hrule\kern-0.4pt +% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +% \kern-0.4pt\hrule}% +% \kern-.06em\raise0.4pt\hbox{\angleright}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} + +% @clicksequence{File @click{} Open ...} +\def\clicksequence#1{\begingroup #1\endgroup} + +% @clickstyle @arrow (by default) +\parseargdef\clickstyle{\def\click{#1}} +\def\click{\arrow} + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% @acronym for "FBI", "NATO", and the like. +% We print this one point size smaller, since it's intended for +% all-uppercase. +% +\def\acronym#1{\doacronym #1,,\finish} +\def\doacronym#1,#2,#3\finish{% + {\selectfonts\lsize #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @abbr for "Comput. J." and the like. +% No font change, but don't do end-of-sentence spacing. +% +\def\abbr#1{\doabbr #1,,\finish} +\def\doabbr#1,#2,#3\finish{% + {\plainfrenchspacing #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a math (or tt) \. +% FYI, plain.tex uses \\ as a temporary control sequence (for no +% particular reason), but this is not advertised and we don't care. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + $\finishmath +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% ctrl is no longer a Texinfo command, but leave this definition for fun. +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. +% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, +% except specified as a normal braced arg, so no newlines to worry about. +% +\def\outfmtnametex{tex} +% +\long\def\inlinefmt#1{\doinlinefmt #1,\finish} +\long\def\doinlinefmt#1,#2,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi +} +% For raw, must switch into @tex before parsing the argument, to avoid +% setting catcodes prematurely. Doing it this way means that, for +% example, @inlineraw{html, foo{bar} gets a parse error instead of being +% ignored. But this isn't important because if people want a literal +% *right* brace they would have to use a command anyway, so they may as +% well use a command to get a left brace too. We could re-use the +% delimiter character idea from \verb, but it seems like overkill. +% +\long\def\inlineraw{\tex \doinlineraw} +\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} +\def\doinlinerawtwo#1,#2,\finish{% + \def\inlinerawname{#1}% + \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi + \endgroup % close group opened by \tex. +} + + +\message{glyphs,} +% and logos. + +% @@ prints an @, as does @atchar{}. +\def\@{\char64 } +\let\atchar=\@ + +% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. +% Unless we're in typewriter, use \ecfont because the CM text fonts do +% not have braces, and we don't want to switch into math. +\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}} +\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}} +\let\{=\mylbrace \let\lbracechar=\{ +\let\}=\myrbrace \let\rbracechar=\} +\begingroup + % Definitions to produce \{ and \} commands for indices, + % and @{ and @} for the aux/toc files. + \catcode`\{ = \other \catcode`\} = \other + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\! = 0 \catcode`\\ = \other + !gdef!lbracecmd[\{]% + !gdef!rbracecmd[\}]% + !gdef!lbraceatcmd[@{]% + !gdef!rbraceatcmd[@}]% +!endgroup + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \ptexc +\let\dotaccent = \ptexdot +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \ptext +\let\ubaraccent = \ptexb +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{% + \ifx\textnominalsize\xwordpt + % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX. + % Revert to plain's \scriptsize, which is 7pt. + \count255=\the\fam $\fam\count255 \scriptstyle A$% + \else + % For 11pt, we can use our lllsize. + \selectfonts\lllsize A% + \fi + }% + \vss + }}% + \kern-.15em + \TeX +} + +% Some math mode symbols. +\def\bullet{$\ptexbullet$} +\def\geq{\ifmmode \ge\else $\ge$\fi} +\def\leq{\ifmmode \le\else $\le$\fi} +\def\minus{\ifmmode -\else $-$\fi} + +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. +% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor +} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +% +% Since these characters are used in examples, they should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% +\def\point{$\star$} +\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} +\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% The @error{} command. +% Adapted from the TeXbook's \boxit. +% +\newbox\errorbox +% +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} +% +\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{% + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} +% +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @pounds{} is a sterling sign, which Knuth put in the CM italic font. +% +\def\pounds{{\it\$}} + +% @euro{} comes from a separate font, depending on the current style. +% We use the free feym* fonts from the eurosym package by Henrik +% Theiling, which support regular, slanted, bold and bold slanted (and +% "outlined" (blackboard board, sort of) versions, which we don't need). +% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +% +% Although only regular is the truly official Euro symbol, we ignore +% that. The Euro is designed to be slightly taller than the regular +% font height. +% +% feymr - regular +% feymo - slanted +% feybr - bold +% feybo - bold slanted +% +% There is no good (free) typewriter version, to my knowledge. +% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. +% Hmm. +% +% Also doesn't work in math. Do we need to do math with euro symbols? +% Hope not. +% +% +\def\euro{{\eurofont e}} +\def\eurofont{% + % We set the font at each command, rather than predefining it in + % \textfonts and the other font-switching commands, so that + % installations which never need the symbol don't have to have the + % font installed. + % + % There is only one designed size (nominal 10pt), so we always scale + % that to the current nominal size. + % + % By the way, simply using "at 1em" works for cmr10 and the like, but + % does not work for cmbx10 and other extended/shrunken fonts. + % + \def\eurosize{\csname\curfontsize nominalsize\endcsname}% + % + \ifx\curfontstyle\bfstylename + % bold: + \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize + \else + % regular: + \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize + \fi + \thiseurofont +} + +% Glyphs from the EC fonts. We don't use \let for the aliases, because +% sometimes we redefine the original macro, and the alias should reflect +% the redefinition. +% +% Use LaTeX names for the Icelandic letters. +\def\DH{{\ecfont \char"D0}} % Eth +\def\dh{{\ecfont \char"F0}} % eth +\def\TH{{\ecfont \char"DE}} % Thorn +\def\th{{\ecfont \char"FE}} % thorn +% +\def\guillemetleft{{\ecfont \char"13}} +\def\guillemotleft{\guillemetleft} +\def\guillemetright{{\ecfont \char"14}} +\def\guillemotright{\guillemetright} +\def\guilsinglleft{{\ecfont \char"0E}} +\def\guilsinglright{{\ecfont \char"0F}} +\def\quotedblbase{{\ecfont \char"12}} +\def\quotesinglbase{{\ecfont \char"0D}} +% +% This positioning is not perfect (see the ogonek LaTeX package), but +% we have the precomposed glyphs for the most common cases. We put the +% tests to use those glyphs in the single \ogonek macro so we have fewer +% dummy definitions to worry about for index entries, etc. +% +% ogonek is also used with other letters in Lithuanian (IOU), but using +% the precomposed glyphs for those is not so easy since they aren't in +% the same EC font. +\def\ogonek#1{{% + \def\temp{#1}% + \ifx\temp\macrocharA\Aogonek + \else\ifx\temp\macrochara\aogonek + \else\ifx\temp\macrocharE\Eogonek + \else\ifx\temp\macrochare\eogonek + \else + \ecfont \setbox0=\hbox{#1}% + \ifdim\ht0=1ex\accent"0C #1% + \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% + \fi + \fi\fi\fi\fi + }% +} +\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} +\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} +\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} +\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} +% +% Use the ec* fonts (cm-super in outline format) for non-CM glyphs. +\def\ecfont{% + % We can't distinguish serif/sans and italic/slanted, but this + % is used for crude hacks anyway (like adding French and German + % quotes to documents typeset with CM, where we lose kerning), so + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% + \ifmonospace + % typewriter: + \font\thisecfont = ectt\ecsize \space at \nominalsize + \else + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi + \fi + \thisecfont +} + +% @registeredsymbol - R in a circle. The font for the R should really +% be smaller yet, but lllsize is the best we can do for now. +% Adapted from the plain.tex definition of \copyright. +% +\def\registeredsymbol{% + $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% + \hfil\crcr\Orb}}% + }$% +} + +% @textdegree - the normal degrees sign. +% +\def\textdegree{$^\circ$} + +% Laurent Siebenmann reports \Orb undefined with: +% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 +% so we'll define it if necessary. +% +\ifx\Orb\thisisundefined +\def\Orb{\mathhexbox20D} +\fi + +% Quotes. +\chardef\quotedblleft="5C +\chardef\quotedblright=`\" +\chardef\quoteleft=`\` +\chardef\quoteright=`\' + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + +\parseargdef\shorttitlepage{% + \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\envdef\titlepage{% + % Open one extra group, as we want to close it in the middle of \Etitlepage. + \begingroup + \parindent=0pt \textfonts + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \let\page = \oldpage + \page + \null + }% +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +% Settings used for typesetting titles: no hyphenation, no indentation, +% don't worry much about spacing, ragged right. This should be used +% inside a \vbox, and fonts need to be set appropriately first. Because +% it is always used for titles, nothing else, we call \rmisbold. \par +% should be specified before the end of the \vbox, since a vbox is a group. +% +\def\raggedtitlesettings{% + \rmisbold + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright +} + +% Macros to be used within @titlepage: + +\let\subtitlerm=\tenrm +\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} + +\parseargdef\title{% + \checkenv\titlepage + \vbox{\titlefonts \raggedtitlesettings #1\par}% + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt +} + +\parseargdef\subtitle{% + \checkenv\titlepage + {\subtitlefont \rightline{#1}}% +} + +% @author should come last, but may come many times. +% It can also be used inside @quotation. +% +\parseargdef\author{% + \def\temp{\quotation}% + \ifx\thisenv\temp + \def\quotationauthor{#1}% printed in \Equotation. + \else + \checkenv\titlepage + \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi + {\secfonts\rmisbold \leftline{#1}}% + \fi +} + + +% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make TeX use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + + +\def\evenheading{\parsearg\evenheadingxxx} +\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} +\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddheading{\parsearg\oddheadingxxx} +\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} +\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} +\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddfooting{\parsearg\oddfootingxxx} +\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} +\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -12pt + \global\advance\vsize by -12pt +} + +\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} + +% @evenheadingmarks top \thischapter <- chapter at the top of a page +% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page +% +% The same set of arguments for: +% +% @oddheadingmarks +% @evenfootingmarks +% @oddfootingmarks +% @everyheadingmarks +% @everyfootingmarks + +\def\evenheadingmarks{\headingmarks{even}{heading}} +\def\oddheadingmarks{\headingmarks{odd}{heading}} +\def\evenfootingmarks{\headingmarks{even}{footing}} +\def\oddfootingmarks{\headingmarks{odd}{footing}} +\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} + \headingmarks{odd}{heading}{#1} } +\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} + \headingmarks{odd}{footing}{#1} } +% #1 = even/odd, #2 = heading/footing, #3 = top/bottom. +\def\headingmarks#1#2#3 {% + \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname + \global\expandafter\let\csname get#1#2marks\endcsname \temp +} + +\everyheadingmarks bottom +\everyfootingmarks bottom + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\headingsoff{% non-global headings elimination + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% +} + +\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting +\HEADINGSoff % it's the default + +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% This produces Day Month Year style of output. +% Only define if not already defined, in case a txi-??.tex file has set +% up a different format (e.g., txi-cs.tex does this). +\ifx\today\thisisundefined +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} +\fi + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg{\gdef\thistitle}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @ftable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemindicate{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil\relax + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. However, if + % what follows is an environment such as @example, there will be no + % \parskip glue; then the negative vskip we just inserted would + % cause the example and the item to crash together. So we use this + % bizarre value of 10001 as a signal to \aboveenvbreak to insert + % \parskip glue after all. Section titles are handled this way also. + % + \penalty 10001 + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a list environment}} +\def\itemx{\errmessage{@itemx while not in a list environment}} + +% @table, @ftable, @vtable. +\envdef\table{% + \let\itemindex\gobble + \tablecheck{table}% +} +\envdef\ftable{% + \def\itemindex ##1{\doind {fn}{\code{##1}}}% + \tablecheck{ftable}% +} +\envdef\vtable{% + \def\itemindex ##1{\doind {vr}{\code{##1}}}% + \tablecheck{vtable}% +} +\def\tablecheck#1{% + \ifnum \the\catcode`\^^M=\active + \endgroup + \errmessage{This command won't work in this context; perhaps the problem is + that we are \inenvironment\thisenv}% + \def\next{\doignore{#1}}% + \else + \let\next\tablex + \fi + \next +} +\def\tablex#1{% + \def\itemindicate{#1}% + \parsearg\tabley +} +\def\tabley#1{% + {% + \makevalueexpandable + \edef\temp{\noexpand\tablez #1\space\space\space}% + \expandafter + }\temp \endtablez +} +\def\tablez #1 #2 #3 #4\endtablez{% + \aboveenvbreak + \ifnum 0#1>0 \advance \leftskip by #1\mil \fi + \ifnum 0#2>0 \tableindent=#2\mil \fi + \ifnum 0#3>0 \advance \rightskip by #3\mil \fi + \itemmax=\tableindent + \advance \itemmax by -\itemmargin + \advance \leftskip by \tableindent + \exdentamount=\tableindent + \parindent = 0pt + \parskip = \smallskipamount + \ifdim \parskip=0pt \parskip=2pt \fi + \let\item = \internalBitem + \let\itemx = \internalBitemx +} +\def\Etable{\endgraf\afterenvbreak} +\let\Eftable\Etable +\let\Evtable\Etable +\let\Eitemize\Etable +\let\Eenumerate\Etable + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\envdef\itemize{\parsearg\doitemize} + +\def\doitemize#1{% + \aboveenvbreak + \itemmax=\itemindent + \advance\itemmax by -\itemmargin + \advance\leftskip by \itemindent + \exdentamount=\itemindent + \parindent=0pt + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + % + % Try typesetting the item mark that if the document erroneously says + % something like @itemize @samp (intending @table), there's an error + % right away at the @itemize. It's not the best error message in the + % world, but it's better than leaving it to the @item. This means if + % the user wants an empty mark, they have to say @w{} not just @w. + \def\itemcontents{#1}% + \setbox0 = \hbox{\itemcontents}% + % + % @itemize with no arg is equivalent to @itemize @bullet. + \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi + % + \let\item=\itemizeitem +} + +% Definition of @item while inside @itemize and @enumerate. +% +\def\itemizeitem{% + \advance\itemno by 1 % for enumerations + {\let\par=\endgraf \smallbreak}% reasonable place to break + {% + % If the document has an @itemize directly after a section title, a + % \nobreak will be last on the list, and \sectionheading will have + % done a \vskip-\parskip. In that case, we don't want to zero + % parskip, or the item text will crash with the heading. On the + % other hand, when there is normal text preceding the item (as there + % usually is), we do want to zero parskip, or there would be too much + % space. In that case, we won't have a \nobreak before. At least + % that's the theory. + \ifnum\lastpenalty<10000 \parskip=0in \fi + \noindent + \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% + % + \vadjust{\penalty 1200}}% not good to break after first line of item. + \flushcr +} + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call \doitemize, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \doitemize{#1.}\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab do not need to be on their own lines, but it will not hurt +% if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the @columnfraction, usually a decimal number like .5, but might +% be just 1. We just use it, whatever it is. +% +\def\pickupwholefraction#1 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a + % separator; typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% multitable-only commands. +% +% @headitem starts a heading row, which we typeset in bold. +% Assignments have to be global since we are inside the implicit group +% of an alignment entry. \everycr resets \everytab so we don't have to +% undo it ourselves. +\def\headitemfont{\b}% for people to use in the template row; not changeable +\def\headitem{% + \checkenv\multitable + \crcr + \global\everytab={\bf}% can't use \headitemfont since the parsing differs + \the\everytab % for the first item +}% +% +% A \tab used to include \hskip1sp. But then the space in a template +% line is not enough. That is bad. So let's go back to just `&' until +% we again encounter the problem the 1sp was intended to solve. +% --karl, nathan@acm.org, 20apr99. +\def\tab{\checkenv\multitable &\the\everytab}% + +% @multitable ... @end multitable definitions: +% +\newtoks\everytab % insert after every tab. +% +\envdef\multitable{% + \vskip\parskip + \startsavinginserts + % + % @item within a multitable starts a normal row. + % We use \def instead of \let so that if one of the multitable entries + % contains an @itemize, we don't choke on the \item (seen as \crcr aka + % \endtemplate) expanding \doitemize. + \def\item{\crcr}% + % + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + % + \everycr = {% + \noalign{% + \global\everytab={}% + \global\colcount=0 % Reset the column counter. + % Check for saved footnotes, etc. + \checkinserts + % Keeps underfull box messages off when table breaks over pages. + %\filbreak + % Maybe so, but it also creates really weird page breaks when the + % table breaks over pages. Wouldn't \vfil be better? Wait until the + % problem manifests itself, so it can be fixed for real --karl. + }% + }% + % + \parsearg\domultitable +} +\def\domultitable#1{% + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup &% + \global\advance\colcount by 1 + \multistrut + \vtop{% + % Use the current \colcount to find the correct column width: + \hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively + % marking characters. + \noindent\ignorespaces##\unskip\multistrut + }\cr +} +\def\Emultitable{% + \crcr + \egroup % end the \halign + \global\setpercentfalse +} + +\def\setmultitablespacing{% + \def\multistrut{\strut}% just use the standard line spacing + % + % Compute \multitablelinespace (if not defined by user) for use in + % \multitableparskip calculation. We used define \multistrut based on + % this, but (ironically) that caused the spacing to be off. + % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +\fi +% Test to see if parskip is larger than space between lines of +% table. If not, do nothing. +% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi} + + +\message{conditionals,} + +% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, +% @ifnotxml always succeed. They currently do nothing; we don't +% attempt to check whether the conditionals are properly nested. But we +% have to remember that they are conditionals, so that @end doesn't +% attempt to close an environment group. +% +\def\makecond#1{% + \expandafter\let\csname #1\endcsname = \relax + \expandafter\let\csname iscond.#1\endcsname = 1 +} +\makecond{iftex} +\makecond{ifnotdocbook} +\makecond{ifnothtml} +\makecond{ifnotinfo} +\makecond{ifnotplaintext} +\makecond{ifnotxml} + +% Ignore @ignore, @ifhtml, @ifinfo, and the like. +% +\def\direntry{\doignore{direntry}} +\def\documentdescription{\doignore{documentdescription}} +\def\docbook{\doignore{docbook}} +\def\html{\doignore{html}} +\def\ifdocbook{\doignore{ifdocbook}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifinfo{\doignore{ifinfo}} +\def\ifnottex{\doignore{ifnottex}} +\def\ifplaintext{\doignore{ifplaintext}} +\def\ifxml{\doignore{ifxml}} +\def\ignore{\doignore{ignore}} +\def\menu{\doignore{menu}} +\def\xml{\doignore{xml}} + +% Ignore text until a line `@end #1', keeping track of nested conditionals. +% +% A count to remember the depth of nesting. +\newcount\doignorecount + +\def\doignore#1{\begingroup + % Scan in ``verbatim'' mode: + \obeylines + \catcode`\@ = \other + \catcode`\{ = \other + \catcode`\} = \other + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \spaceisspace + % + % Count number of #1's that we've seen. + \doignorecount = 0 + % + % Swallow text until we reach the matching `@end #1'. + \dodoignore{#1}% +} + +{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. + \obeylines % + % + \gdef\dodoignore#1{% + % #1 contains the command name as a string, e.g., `ifinfo'. + % + % Define a command to find the next `@end #1'. + \long\def\doignoretext##1^^M@end #1{% + \doignoretextyyy##1^^M@#1\_STOP_}% + % + % And this command to find another #1 command, at the beginning of a + % line. (Otherwise, we would consider a line `@c @ifset', for + % example, to count as an @ifset for nesting.) + \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% + % + % And now expand that command. + \doignoretext ^^M% + }% +} + +\def\doignoreyyy#1{% + \def\temp{#1}% + \ifx\temp\empty % Nothing found. + \let\next\doignoretextzzz + \else % Found a nested condition, ... + \advance\doignorecount by 1 + \let\next\doignoretextyyy % ..., look for another. + % If we're here, #1 ends with ^^M\ifinfo (for example). + \fi + \next #1% the token \_STOP_ is present just after this macro. +} + +% We have to swallow the remaining "\_STOP_". +% +\def\doignoretextzzz#1{% + \ifnum\doignorecount = 0 % We have just found the outermost @end. + \let\next\enddoignore + \else % Still inside a nested condition. + \advance\doignorecount by -1 + \let\next\doignoretext % Look for the next @end. + \fi + \next +} + +% Finish off ignored text. +{ \obeylines% + % Ignore anything after the last `@end #1'; this matters in verbatim + % environments, where otherwise the newline after an ignored conditional + % would result in a blank line in the output. + \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% +} + + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. +% We rely on the fact that \parsearg sets \catcode`\ =10. +% +\parseargdef\set{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + {% + \makevalueexpandable + \def\temp{#2}% + \edef\next{\gdef\makecsname{SET#1}}% + \ifx\temp\empty + \next{}% + \else + \setzzz#2\endsetzzz + \fi + }% +} +% Remove the trailing space \setxxx inserted. +\def\setzzz#1 \endsetzzz{\next{#1}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\parseargdef\clear{% + {% + \makevalueexpandable + \global\expandafter\let\csname SET#1\endcsname=\relax + }% +} + +% @value{foo} gets the text saved in variable foo. +\def\value{\begingroup\makevalueexpandable\valuexxx} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} +{ + \catcode`\- = \active \catcode`\_ = \active + % + \gdef\makevalueexpandable{% + \let\value = \expandablevalue + % We don't want these characters active, ... + \catcode`\-=\other \catcode`\_=\other + % ..., but we might end up with active ones in the argument if + % we're called from @code, as @code{@value{foo-bar_}}, though. + % So \let them to their normal equivalents. + \let-\normaldash \let_\normalunderscore + } +} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we call \makevalueexpandable in \indexdummies). +% The command has to be fully expandable (if the variable is set), since +% the result winds up in the index file. This means that if the +% variable's value contains other Texinfo commands, it's almost certain +% it will fail (although perhaps we could fix that with sufficient work +% to do a one-level expansion on the result, instead of complete). +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \message{Variable `#1', used in @value, is not set.}% + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +% To get special treatment of `@end ifset,' call \makeond and the redefine. +% +\makecond{ifset} +\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} +\def\doifset#1#2{% + {% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname SET#2\endcsname\relax + #1% If not set, redefine \next. + \fi + \expandafter + }\next +} +\def\ifsetfail{\doignore{ifset}} + +% @ifclear VAR ... @end executes the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +% The `\else' inside the `\doifset' parameter is a trick to reuse the +% above code: if the variable is not set, do nothing, if it is set, +% then redefine \next to \ifclearfail. +% +\makecond{ifclear} +\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} +\def\ifclearfail{\doignore{ifclear}} + +% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +% without the @) is in fact defined. We can only feasibly check at the +% TeX level, so something like `mathcode' is going to considered +% defined even though it is not a Texinfo command. +% +\makecond{ifcommanddefined} +\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +% +\def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next +} +\def\ifcmddefinedfail{\doignore{ifcommanddefined}} + +% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +\makecond{ifcommandnotdefined} +\def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + +% Set the `txicommandconditionals' variable, so documents have a way to +% test if the @ifcommand...defined conditionals are available. +\set txicommandconditionals + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory=\comment + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within macros and \if's. +\edef\newwrite{\makecsname{ptexnewwrite}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} +% +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. +% +\def\defcodeindex{\parsearg\newcodeindex} +% +\def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}}% +} + + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +% +\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} +\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} + +% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), +% #3 the target index (bar). +\def\dosynindex#1#2#3{% + % Only do \closeout if we haven't already done it, else we'll end up + % closing the target index. + \expandafter \ifx\csname donesynindex#2\endcsname \relax + % The \closeout helps reduce unnecessary open files; the limit on the + % Acorn RISC OS is a mere 16 files. + \expandafter\closeout\csname#2indfile\endcsname + \expandafter\let\csname donesynindex#2\endcsname = 1 + \fi + % redefine \fooindfile: + \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname + \expandafter\let\csname#2indfile\endcsname=\temp + % redefine \fooindex: + \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +% Take care of Texinfo commands that can appear in an index entry. +% Since there are some commands we want to expand, and others we don't, +% we have to laboriously prevent expansion for those that we don't. +% +\def\indexdummies{% + \escapechar = `\\ % use backslash in output files. + \def\@{@}% change to @@ when we switch to @ as escape char in index files. + \def\ {\realbackslash\space }% + % + % Need these unexpandable (because we define \tt as a dummy) + % definitions when @{ or @} appear in index entry text. Also, more + % complicated, when \tex is in effect and \{ is a \delimiter again. + % We can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. Perhaps we + % should define @lbrace and @rbrace commands a la @comma. + \def\{{{\tt\char123}}% + \def\}{{\tt\char125}}% + % + % I don't entirely understand this, but when an index entry is + % generated from a macro call, the \endinput which \scanmacro inserts + % causes processing to be prematurely terminated. This is, + % apparently, because \indexsorttmp is fully expanded, and \endinput + % is an expandable command. The redefinition below makes \endinput + % disappear altogether for that purpose -- although logging shows that + % processing continues to some further point. On the other hand, it + % seems \endinput does not hurt in the printed index arg, since that + % is still getting written without apparent harm. + % + % Sample source (mac-idx3.tex, reported by Graham Percival to + % help-texinfo, 22may06): + % @macro funindex {WORD} + % @findex xyz + % @end macro + % ... + % @funindex commtest + % + % The above is not enough to reproduce the bug, but it gives the flavor. + % + % Sample whatsit resulting: + % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} + % + % So: + \let\endinput = \empty + % + % Do the redefinitions. + \commondummies +} + +% For the aux and toc files, @ is the escape character. So we want to +% redefine everything using @ as the escape character (instead of +% \realbackslash, still used for index files). When everything uses @, +% this will be simpler. +% +\def\atdummies{% + \def\@{@@}% + \def\ {@ }% + \let\{ = \lbraceatcmd + \let\} = \rbraceatcmd + % + % Do the redefinitions. + \commondummies + \otherbackslash +} + +% Called from \indexdummies and \atdummies. +% +\def\commondummies{% + % + % \definedummyword defines \#1 as \string\#1\space, thus effectively + % preventing its expansion. This is used only for control words, + % not control letters, because the \space would be incorrect for + % control characters, but is needed to separate the control word + % from whatever follows. + % + % For control letters, we have \definedummyletter, which omits the + % space. + % + % These can be used both for control words that take an argument and + % those that do not. If it is followed by {arg} in the input, then + % that will dutifully get written to the index (or wherever). + % + \def\definedummyword ##1{\def##1{\string##1\space}}% + \def\definedummyletter##1{\def##1{\string##1}}% + \let\definedummyaccent\definedummyletter + % + \commondummiesnofonts + % + \definedummyletter\_% + \definedummyletter\-% + % + % Non-English letters. + \definedummyword\AA + \definedummyword\AE + \definedummyword\DH + \definedummyword\L + \definedummyword\O + \definedummyword\OE + \definedummyword\TH + \definedummyword\aa + \definedummyword\ae + \definedummyword\dh + \definedummyword\exclamdown + \definedummyword\l + \definedummyword\o + \definedummyword\oe + \definedummyword\ordf + \definedummyword\ordm + \definedummyword\questiondown + \definedummyword\ss + \definedummyword\th + % + % Although these internal commands shouldn't show up, sometimes they do. + \definedummyword\bf + \definedummyword\gtr + \definedummyword\hat + \definedummyword\less + \definedummyword\sf + \definedummyword\sl + \definedummyword\tclose + \definedummyword\tt + % + \definedummyword\LaTeX + \definedummyword\TeX + % + % Assorted special characters. + \definedummyword\arrow + \definedummyword\bullet + \definedummyword\comma + \definedummyword\copyright + \definedummyword\registeredsymbol + \definedummyword\dots + \definedummyword\enddots + \definedummyword\entrybreak + \definedummyword\equiv + \definedummyword\error + \definedummyword\euro + \definedummyword\expansion + \definedummyword\geq + \definedummyword\guillemetleft + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright + \definedummyword\lbracechar + \definedummyword\leq + \definedummyword\minus + \definedummyword\ogonek + \definedummyword\pounds + \definedummyword\point + \definedummyword\print + \definedummyword\quotedblbase + \definedummyword\quotedblleft + \definedummyword\quotedblright + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase + \definedummyword\rbracechar + \definedummyword\result + \definedummyword\textdegree + % + % We want to disable all macros so that they are not expanded by \write. + \macrolist + % + \normalturnoffactive + % + % Handle some cases of @value -- where it does not contain any + % (non-fully-expandable) commands. + \makevalueexpandable +} + +% \commondummiesnofonts: common to \commondummies and \indexnofonts. +% +\def\commondummiesnofonts{% + % Control letters and accents. + \definedummyletter\!% + \definedummyaccent\"% + \definedummyaccent\'% + \definedummyletter\*% + \definedummyaccent\,% + \definedummyletter\.% + \definedummyletter\/% + \definedummyletter\:% + \definedummyaccent\=% + \definedummyletter\?% + \definedummyaccent\^% + \definedummyaccent\`% + \definedummyaccent\~% + \definedummyword\u + \definedummyword\v + \definedummyword\H + \definedummyword\dotaccent + \definedummyword\ogonek + \definedummyword\ringaccent + \definedummyword\tieaccent + \definedummyword\ubaraccent + \definedummyword\udotaccent + \definedummyword\dotless + % + % Texinfo font commands. + \definedummyword\b + \definedummyword\i + \definedummyword\r + \definedummyword\sansserif + \definedummyword\sc + \definedummyword\slanted + \definedummyword\t + % + % Commands that take arguments. + \definedummyword\abbr + \definedummyword\acronym + \definedummyword\anchor + \definedummyword\cite + \definedummyword\code + \definedummyword\command + \definedummyword\dfn + \definedummyword\dmn + \definedummyword\email + \definedummyword\emph + \definedummyword\env + \definedummyword\file + \definedummyword\image + \definedummyword\indicateurl + \definedummyword\inforef + \definedummyword\kbd + \definedummyword\key + \definedummyword\math + \definedummyword\option + \definedummyword\pxref + \definedummyword\ref + \definedummyword\samp + \definedummyword\strong + \definedummyword\tie + \definedummyword\uref + \definedummyword\url + \definedummyword\var + \definedummyword\verb + \definedummyword\w + \definedummyword\xref +} + +% \indexnofonts is used when outputting the strings to sort the index +% by, and when constructing control sequence names. It eliminates all +% control sequences and just writes whatever the best ASCII sort string +% would be for a given command (usually its argument). +% +\def\indexnofonts{% + % Accent commands should become @asis. + \def\definedummyaccent##1{\let##1\asis}% + % We can just ignore other control letters. + \def\definedummyletter##1{\let##1\empty}% + % All control words become @asis by default; overrides below. + \let\definedummyword\definedummyaccent + % + \commondummiesnofonts + % + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis + % + \def\ { }% + \def\@{@}% + \def\_{\normalunderscore}% + \def\-{}% @- shouldn't affect sorting + % + % Unfortunately, texindex is not prepared to handle braces in the + % content at all. So for index sorting, we map @{ and @} to strings + % starting with |, since that ASCII character is between ASCII { and }. + \def\{{|a}% + \def\lbracechar{|a}% + % + \def\}{|b}% + \def\rbracechar{|b}% + % + % Non-English letters. + \def\AA{AA}% + \def\AE{AE}% + \def\DH{DZZ}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\TH{ZZZ}% + \def\aa{aa}% + \def\ae{ae}% + \def\dh{dzz}% + \def\exclamdown{!}% + \def\l{l}% + \def\oe{oe}% + \def\ordf{a}% + \def\ordm{o}% + \def\o{o}% + \def\questiondown{?}% + \def\ss{ss}% + \def\th{zzz}% + % + \def\LaTeX{LaTeX}% + \def\TeX{TeX}% + % + % Assorted special characters. + % (The following {} will end up in the sort string, but that's ok.) + \def\arrow{->}% + \def\bullet{bullet}% + \def\comma{,}% + \def\copyright{copyright}% + \def\dots{...}% + \def\enddots{...}% + \def\equiv{==}% + \def\error{error}% + \def\euro{euro}% + \def\expansion{==>}% + \def\geq{>=}% + \def\guillemetleft{<<}% + \def\guillemetright{>>}% + \def\guilsinglleft{<}% + \def\guilsinglright{>}% + \def\leq{<=}% + \def\minus{-}% + \def\point{.}% + \def\pounds{pounds}% + \def\print{-|}% + \def\quotedblbase{"}% + \def\quotedblleft{"}% + \def\quotedblright{"}% + \def\quoteleft{`}% + \def\quoteright{'}% + \def\quotesinglbase{,}% + \def\registeredsymbol{R}% + \def\result{=>}% + \def\textdegree{o}% + % + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax + \else \indexlquoteignore \fi + % + % We need to get rid of all macros, leaving only the arguments (if present). + % Of course this is not nearly correct, but it is the best we can do for now. + % makeinfo does not expand macros in the argument to @deffn, which ends up + % writing an index entry, and texindex isn't prepared for an index sort entry + % that starts with \. + % + % Since macro invocations are followed by braces, we can just redefine them + % to take a single TeX argument. The case of a macro invocation that + % goes to end-of-line is not handled. + % + \macrolist +} + +% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us +% ignore left quotes in the sort term. +{\catcode`\`=\active + \gdef\indexlquoteignore{\let`=\empty}} + +\let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% Most index entries go through here, but \dosubind is the general case. +% #1 is the index name, #2 is the entry text. +\def\doind#1#2{\dosubind{#1}{#2}{}} + +% Workhorse for all \fooindexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% empty if called from \doind, as we usually are (the main exception +% is with most defuns, which call us directly). +% +\def\dosubind#1#2#3{% + \iflinks + {% + % Store the main index entry text (including the third arg). + \toks0 = {#2}% + % If third arg is present, precede it with a space. + \def\thirdarg{#3}% + \ifx\thirdarg\empty \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + \edef\writeto{\csname#1indfile\endcsname}% + % + \safewhatsit\dosubindwrite + }% + \fi +} + +% Write the entry in \toks0 to the index file: +% +\def\dosubindwrite{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi + % + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + % Process the index entry with all font commands turned off, to + % get the string to sort by. + {\indexnofonts + \edef\temp{\the\toks0}% need full expansion + \xdef\indexsorttmp{\temp}% + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\writeto{% + \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% + }% + \temp +} + +% Take care of unwanted page breaks/skips around a whatsit: +% +% If a skip is the last thing on the list now, preserve it +% by backing up by \lastskip, doing the \write, then inserting +% the skip again. Otherwise, the whatsit generated by the +% \write or \pdfdest will make \lastskip zero. The result is that +% sequences like this: +% @end defun +% @tindex whatever +% @defun ... +% will have extra space inserted, because the \medbreak in the +% start of the @defun won't see the skip inserted by the @end of +% the previous defun. +% +% But don't do any of this if we're not in vertical mode. We +% don't want to do a \vskip and prematurely end a paragraph. +% +% Avoid page breaks due to these extra skips, too. +% +% But wait, there is a catch there: +% We'll have to check whether \lastskip is zero skip. \ifdim is not +% sufficient for this purpose, as it ignores stretch and shrink parts +% of the skip. The only way seems to be to check the textual +% representation of the skip. +% +% The following is almost like \def\zeroskipmacro{0.0pt} except that +% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). +% +\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} +% +\newskip\whatsitskip +\newcount\whatsitpenalty +% +% ..., ready, GO: +% +\def\safewhatsit#1{\ifhmode + #1% + \else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% + \whatsitpenalty = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\whatsitskip glue we're inserting is preceded by a + % non-discardable item, therefore it is not a potential + % breakpoint, therefore no \nobreak needed. + \ifx\lastskipmacro\zeroskipmacro + \else + \vskip-\whatsitskip + \fi + % + #1% + % + \ifx\lastskipmacro\zeroskipmacro + % If \lastskip was zero, perhaps the last item was a penalty, and + % perhaps it was >=10000, e.g., a \nobreak. In that case, we want + % to re-insert the same penalty (values >10000 are used for various + % signals); since we just inserted a non-discardable item, any + % following glue (such as a \parskip) would be a breakpoint. For example: + % @deffn deffn-whatever + % @vindex index-whatever + % Description. + % would allow a break between the index-whatever whatsit + % and the "Description." paragraph. + \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi + \else + % On the other hand, if we had a nonzero \lastskip, + % this make-up glue would be preceded by a non-discardable item + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\whatsitskip + \fi +\fi} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\parseargdef\printindex{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \plainfrenchspacing + \everypar = {}% don't want the \kern\-parindent from indentation suppression. + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\backslashcurfont}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \nobreak + \vskip 0pt plus 3\baselineskip + \penalty 0 + \vskip 0pt plus -3\baselineskip + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + % Do our best not to break after the initial. + \nobreak + \vskip .33\baselineskip plus .1\baselineskip +}} + +% \entry typesets a paragraph consisting of the text (#1), dot leaders, and +% then page number (#2) flushed to the right margin. It is used for index +% and table of contents entries. The paragraph is indented by \leftskip. +% +% A straightforward implementation would start like this: +% \def\entry#1#2{... +% But this freezes the catcodes in the argument, and can cause problems to +% @code, which sets - active. This problem was fixed by a kludge--- +% ``-'' was active throughout whole index, but this isn't really right. +% The right solution is to prevent \entry from swallowing the whole text. +% --kasal, 21nov03 +\def\entry{% + \begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing + % columns. + \vskip 0pt plus1pt + % + % When reading the text of entry, convert explicit line breaks + % from @* into spaces. The user might give these in long section + % titles, for instance. + \def\*{\unskip\space\ignorespaces}% + \def\entrybreak{\hfil\break}% + % + % Swallow the left brace of the text (first parameter): + \afterassignment\doentry + \let\temp = +} +\def\entrybreak{\unskip\space\ignorespaces}% +\def\doentry{% + \bgroup % Instead of the swallowed brace. + \noindent + \aftergroup\finishentry + % And now comes the text of the entry. +} +\def\finishentry#1{% + % #1 is the page number. + % + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \setbox\boxA = \hbox{#1}% + \ifdim\wd\boxA = 0pt + \ % + \else + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#1.% + \ \the\toksA + \else + \ #1% + \fi + \fi + \par + \endgroup +} + +% Like plain.tex's \dotfill, except uses up at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm +\def\secondary#1#2{{% + \parfillskip=0in + \parskip=0in + \hangindent=1in + \hangafter=1 + \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + #2 + \fi + \par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + }% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \vsize = 2\vsize +} + +% The double-column output routine for all double-column pages except +% the last. +% +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + \advance\dimen@ by -\ht\partialpage + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +% +% Re-output the contents of the output page -- any previous material, +% followed by the two boxes we just split, in box0 and box2. +\def\pagesofar{% + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% +} +% +% All done with double columns. +\def\enddoublecolumns{% + % The following penalty ensures that the page builder is exercised + % _before_ we change the output routine. This is necessary in the + % following situation: + % + % The last section of the index consists only of a single entry. + % Before this section, \pagetotal is less than \pagegoal, so no + % break occurs before the last section starts. However, the last + % section, consisting of \initial and the single \entry, does not + % fit on the page and has to be broken off. Without the following + % penalty the page builder will not be exercised until \eject + % below, and by that time we'll already have changed the output + % routine to the \balancecolumns version, so the next-to-last + % double-column page will be processed with \balancecolumns, which + % is wrong: The two columns will go to the main vertical list, with + % the broken-off section in the recent contributions. As soon as + % the output routine finishes, TeX starts reconsidering the page + % break. The two columns and the broken-off section both fit on the + % page, because the two columns now take up only half of the page + % goal. When TeX sees \eject from below which follows the final + % section, it invokes the new output routine that we've set after + % \balancecolumns below; \onepageout will try to fit the two columns + % and the final section into the vbox of \pageheight (see + % \pagebody), causing an overfull box. + % + % Note that glue won't work here, because glue does not exercise the + % page builder, unlike penalties (see The TeXbook, pp. 280-281). + \penalty0 + % + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize +} +% +% Called at the end of the double column material. +\def\balancecolumns{% + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +% Let's start with @part. +\outer\parseargdef\part{\partzzz{#1}} +\def\partzzz#1{% + \chapoddpage + \null + \vskip.3\vsize % move it down on the page a bit + \begingroup + \noindent \titlefonts\rmisbold #1\par % the text + \let\lastnode=\empty % no node to associate with + \writetocentry{part}{#1}{}% but put it in the toc + \headingsoff % no headline or footline on the part page + \chapoddpage + \endgroup +} + +% \unnumberedno is an oxymoron. But we count the unnumbered +% sections so that we can refer to them unambiguously in the pdf +% outlines by their "section number". We avoid collisions with chapter +% numbers by starting them at 10000. (If a document ever has 10000 +% chapters, we're in trouble anyway, I'm sure.) +\newcount\unnumberedno \unnumberedno = 10000 +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% +% \def\appendixletter{\char\the\appendixno} +% We do the following ugly conditional instead of the above simple +% construct for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +% +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines these (using marks) as the number+name, number +% and name of the chapter. Page headings and footings can use +% these. @section does likewise. +\def\thischapter{} +\def\thischapternum{} +\def\thischaptername{} +\def\thissection{} +\def\thissectionnum{} +\def\thissectionname{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% we only have subsub. +\chardef\maxseclevel = 3 +% +% A numbered section within an unnumbered changes to unnumbered too. +% To achieve this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unnlevel = \maxseclevel +% +% Trace whether the current chapter is an appendix or not: +% \chapheadtype is "N" or "A", unnumbered chapters are ignored. +\def\chapheadtype{N} + +% Choose a heading macro +% #1 is heading type +% #2 is heading level +% #3 is text for heading +\def\genhead#1#2#3{% + % Compute the abs. sec. level: + \absseclevel=#2 + \advance\absseclevel by \secbase + % Make sure \absseclevel doesn't fall outside the range: + \ifnum \absseclevel < 0 + \absseclevel = 0 + \else + \ifnum \absseclevel > 3 + \absseclevel = 3 + \fi + \fi + % The heading type: + \def\headtype{#1}% + \if \headtype U% + \ifnum \absseclevel < \unnlevel + \chardef\unnlevel = \absseclevel + \fi + \else + % Check for appendix sections: + \ifnum \absseclevel = 0 + \edef\chapheadtype{\headtype}% + \else + \if \headtype A\if \chapheadtype N% + \errmessage{@appendix... within a non-appendix chapter}% + \fi\fi + \fi + % Check for numbered within unnumbered: + \ifnum \absseclevel > \unnlevel + \def\headtype{U}% + \else + \chardef\unnlevel = 3 + \fi + \fi + % Now print the heading: + \if \headtype U% + \ifcase\absseclevel + \unnumberedzzz{#3}% + \or \unnumberedseczzz{#3}% + \or \unnumberedsubseczzz{#3}% + \or \unnumberedsubsubseczzz{#3}% + \fi + \else + \if \headtype A% + \ifcase\absseclevel + \appendixzzz{#3}% + \or \appendixsectionzzz{#3}% + \or \appendixsubseczzz{#3}% + \or \appendixsubsubseczzz{#3}% + \fi + \else + \ifcase\absseclevel + \chapterzzz{#3}% + \or \seczzz{#3}% + \or \numberedsubseczzz{#3}% + \or \numberedsubsubseczzz{#3}% + \fi + \fi + \fi + \suppressfirstparagraphindent +} + +% an interface: +\def\numhead{\genhead N} +\def\apphead{\genhead A} +\def\unnmhead{\genhead U} + +% @chapter, @appendix, @unnumbered. Increment top-level counter, reset +% all lower-level sectioning counters to zero. +% +% Also set \chaplevelprefix, which we prepend to @float sequence numbers +% (e.g., figures), q.v. By default (before any chapter), that is empty. +\let\chaplevelprefix = \empty +% +\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz#1{% + % section resetting is \global in case the chapter is in a group, such + % as an @include file. + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\chapno by 1 + % + % Used for \float. + \gdef\chaplevelprefix{\the\chapno.}% + \resetallfloatnos + % + % \putwordChapter can contain complex things in translations. + \toks0=\expandafter{\putwordChapter}% + \message{\the\toks0 \space \the\chapno}% + % + % Write the actual heading. + \chapmacro{#1}{Ynumbered}{\the\chapno}% + % + % So @section and the like are numbered underneath this chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec +} + +\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz +% +\def\appendixzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\appendixno by 1 + \gdef\chaplevelprefix{\appendixletter.}% + \resetallfloatnos + % + % \putwordAppendix can contain complex things in translations. + \toks0=\expandafter{\putwordAppendix}% + \message{\the\toks0 \space \appendixletter}% + % + \chapmacro{#1}{Yappendix}{\appendixletter}% + % + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec +} + +% normally unnmhead0 calls unnumberedzzz: +\outer\parseargdef\unnumbered{\unnmhead0{#1}} +\def\unnumberedzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\unnumberedno by 1 + % + % Since an unnumbered has no number, no prefix for figures. + \global\let\chaplevelprefix = \empty + \resetallfloatnos + % + % This used to be simply \message{#1}, but TeX fully expands the + % argument to \message. Therefore, if #1 contained @-commands, TeX + % expanded them. For example, in `@unnumbered The @cite{Book}', TeX + % expanded @cite (which turns out to cause errors because \cite is meant + % to be executed, not expanded). + % + % Anyway, we don't want the fully-expanded definition of @cite to appear + % as a result of the \message, we just want `@cite' itself. We use + % \the to achieve this: TeX expands \the only once, + % simply yielding the contents of . (We also do this for + % the toc entries.) + \toks0 = {#1}% + \message{(\the\toks0)}% + % + \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\parseargdef\centerchap{% + % Well, we could do the following in a group, but that would break + % an assumption that \chapmacro is called at the outermost level. + % Thus we are safer this way: --kasal, 24feb04 + \let\centerparametersmaybe = \centerparameters + \unnmhead0{#1}% + \let\centerparametersmaybe = \relax +} + +% @top is like @unnumbered. +\let\top\unnumbered + +% Sections. +% +\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz +\def\seczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% +} + +% normally calls appendixsectionzzz: +\outer\parseargdef\appendixsection{\apphead1{#1}} +\def\appendixsectionzzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% +} +\let\appendixsec\appendixsection + +% normally calls unnumberedseczzz: +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} +\def\unnumberedseczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +} + +% Subsections. +% +% normally calls numberedsubseczzz: +\outer\parseargdef\numberedsubsec{\numhead2{#1}} +\def\numberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% +} + +% normally calls appendixsubseczzz: +\outer\parseargdef\appendixsubsec{\apphead2{#1}} +\def\appendixsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno}% +} + +% normally calls unnumberedsubseczzz: +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} +\def\unnumberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno}% +} + +% Subsubsections. +% +% normally numberedsubsubseczzz: +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} +\def\numberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynumbered}% + {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally appendixsubsubseczzz: +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} +\def\appendixsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally unnumberedsubsubseczzz: +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} +\def\unnumberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\let\section = \numberedsec +\let\subsection = \numberedsubsec +\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +\def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz +} + +\def\chapheading{\chapbreak \parsearg\chapheadingzzz} +\def\chapheadingzzz#1{% + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak + \suppressfirstparagraphindent +} + +% @heading, @subheading, @subsubheading. +\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +% Parameter controlling skip before chapter headings (if needed) +\newskip\chapheadingskip + +% Define plain chapter starts, and page on/off switching for it. +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +% Because \domark is called before \chapoddpage, the filler page will +% get the headings for the next chapter, which is wrong. But we don't +% care -- we just disable all headings on the filler page. +\def\chapoddpage{% + \chappager + \ifodd\pageno \else + \begingroup + \headingsoff + \null + \chappager + \endgroup + \fi +} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{% +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +% Chapter opening. +% +% #1 is the text, #2 is the section type (Ynumbered, Ynothing, +% Yappendix, Yomitfromtoc), #3 the chapter number. +% +% To test against our argument. +\def\Ynothingkeyword{Ynothing} +\def\Yomitfromtockeyword{Yomitfromtoc} +\def\Yappendixkeyword{Yappendix} +% +\def\chapmacro#1#2#3{% + % Insert the first mark before the heading break (see notes for \domark). + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% + \gdef\thissection{}}% + % + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{\thischaptername}}% + \else\ifx\temptype\Yomitfromtockeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{}}% + \else\ifx\temptype\Yappendixkeyword + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\appendixletter}% + % \noexpand\putwordAppendix avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \else + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\the\chapno}% + % \noexpand\putwordChapter avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordChapter{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert the chapter heading break. + \pchapsepmacro + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \domark + % + {% + \chapfonts \rmisbold + % + % Have to define \lastsection before calling \donoderef, because the + % xref code eventually uses it. On the other hand, it has to be called + % after \pchapsepmacro, or the headline will change too soon. + \gdef\lastsection{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \fi\fi\fi + % + % Write the toc entry for this chapter. Must come before the + % \donoderef, because we include the current node name in the toc + % entry, and \donoderef resets it to empty. + \writetocentry{\toctype}{#1}{#3}% + % + % For pdftex, we have to write out the node definition (aka, make + % the pdfdest) after any page break, but before the actual text has + % been typeset. If the destination for the pdf outline is after the + % text, then jumping from the outline may wind up with the text not + % being visible, for instance under high magnification. + \donoderef{#2}% + % + % Typeset the actual heading. + \nobreak % Avoid page breaks at the interline glue. + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerparameters{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt +} + + +% I don't think this chapter style is supported any more, so I'm not +% updating it with the new noderef stuff. We'll see. --karl, 11aug03. +% +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} +% +\def\unnchfopen #1{% + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip\nobreak +} +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} +\def\centerchfopen #1{% + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% + \nobreak\bigskip \nobreak +} +\def\CHAPFopen{% + \global\let\chapmacro=\chfopen + \global\let\centerchapmacro=\centerchfopen} + + +% Section titles. These macros combine the section number parts and +% call the generic \sectionheading to do the printing. +% +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip{-1000}} + +% Subsection titles. +\newskip\subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} + +% Subsubsection titles. +\def\subsubsecheadingskip{\subsecheadingskip} +\def\subsubsecheadingbreak{\subsecheadingbreak} + + +% Print any size, any type, section title. +% +% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is +% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the +% section number. +% +\def\seckeyword{sec} +% +\def\sectionheading#1#2#3#4{% + {% + \checkenv{}% should not be in an environment. + % + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rmisbold + % + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + % Insert first mark before the heading break (see notes for \domark). + \let\prevsectiondefs=\lastsectiondefs + \ifx\temptype\Ynothingkeyword + \ifx\sectionlevel\seckeyword + \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% + \gdef\thissection{\thissectionname}}% + \fi + \else\ifx\temptype\Yomitfromtockeyword + % Don't redefine \thissection. + \else\ifx\temptype\Yappendixkeyword + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \else + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \fi\fi\fi + % + % Go into vertical mode. Usually we'll already be there, but we + % don't want the following whatsit to end up in a preceding paragraph + % if the document didn't happen to have a blank line. + \par + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\lastsection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \lastsection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\lastsection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\lastsection{#1}% + \fi\fi\fi + % + % Write the toc entry (before \donoderef). See comments in \chapmacro. + \writetocentry{\toctype\sectionlevel}{#1}{#4}% + % + % Write the node reference (= pdf destination for pdftex). + % Again, see comments in \chapmacro. + \donoderef{#3}% + % + % Interline glue will be inserted when the vbox is completed. + % That glue will be a valid breakpoint for the page, since it'll be + % preceded by a whatsit (usually from the \donoderef, or from the + % \writetocentry if there was no node). We don't want to allow that + % break, since then the whatsits could end up on page n while the + % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. + \nobreak + % + % Output the actual section heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright + \hangindent=\wd0 % zero if no section number + \unhbox0 #1}% + }% + % Add extra space after the heading -- half of whatever came above it. + % Don't allow stretch, though. + \kern .5 \csname #2headingskip\endcsname + % + % Do not let the kern be a potential breakpoint, as it would be if it + % was followed by glue. + \nobreak + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a + % discardable item.) However, when a paragraph is not started next + % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out + % or the negative glue will cause weirdly wrong output, typically + % obscuring the section heading with something else. + \vskip-\parskip + % + % This is so the last item on the main vertical list is a known + % \penalty > 10000, so \startdefun, etc., can recognize the situation + % and do the needful. + \penalty 10001 +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. +% +% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} +% We append the current node name (if any) and page number as additional +% arguments for the \{chap,sec,...}entry macros which will eventually +% read this. The node name is used in the pdf outlines as the +% destination to jump to. +% +% We open the .toc file for writing here instead of at @setfilename (or +% any other fixed time) so that @contents can be anywhere in the document. +% But if #1 is `omit', then we don't do anything. This is used for the +% table of contents chapter openings themselves. +% +\newif\iftocfileopened +\def\omitkeyword{omit}% +% +\def\writetocentry#1#2#3{% + \edef\writetoctype{#1}% + \ifx\writetoctype\omitkeyword \else + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + {\atdummies + \edef\temp{% + \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% + \temp + }% + \fi + \fi + % + % Tell \shipout to create a pdf destination on each page, if we're + % writing pdf. These are used in the table of contents. We can't + % just write one on every page because the title pages are numbered + % 1 and 2 (the page numbers aren't printed), and so are the first + % two pages of the document. Thus, we'd have two destinations named + % `1', and two named `2'. + \ifpdf \global\pdfmakepagedesttrue \fi +} + + +% These characters do not print properly in the Computer Modern roman +% fonts, so we must take special care. This is more or less redundant +% with the Texinfo input format setup at the end of this file. +% +\def\activecatcodes{% + \catcode`\"=\active + \catcode`\$=\active + \catcode`\<=\active + \catcode`\>=\active + \catcode`\\=\active + \catcode`\^=\active + \catcode`\_=\active + \catcode`\|=\active + \catcode`\~=\active +} + + +% Read the toc file, which is essentially Texinfo input. +\def\readtocfile{% + \setupdatafile + \activecatcodes + \input \tocreadfilename +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Prepare to read what we've written to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \chapmacro{#1}{Yomitfromtoc}{}% + % + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi +} + +% redefined for the two-volume lispref. We always output on +% \jobname.toc even if this is redefined. +% +\def\tocreadfilename{\jobname.toc} + +% Normal (long) toc. +% +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \ifeof 1 \else + \pdfmakeoutlines + \fi + \closein 1 + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\partentry = \shortpartentry + \let\numchapentry = \shortchapentry + \let\appentry = \shortchapentry + \let\unnchapentry = \shortunnchapentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\numsecentry##1##2##3##4{} + \let\appsecentry = \numsecentry + \let\unnsecentry = \numsecentry + \let\numsubsecentry = \numsecentry + \let\appsubsecentry = \numsecentry + \let\unnsubsecentry = \numsecentry + \let\numsubsubsecentry = \numsecentry + \let\appsubsubsecentry = \numsecentry + \let\unnsubsubsecentry = \numsecentry + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \closein 1 + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} +\let\shortcontents = \summarycontents + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g., `A' for an appendix, or `3' for a chapter. +% +\def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + % + % We'd like to right-justify chapter numbers, but that looks strange + % with appendix letters. And right-justifying numbers and + % left-justifying letters looks strange when there is less than 10 + % chapters. Have to read the whole toc once to know how many chapters + % there are before deciding ... + \hbox to 1em{#1\hss}% +} + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Parts, in the main contents. Replace the part number, which doesn't +% exist, with an empty box. Let's hope all the numbers have the same width. +% Also ignore the page number, which is conventionally not printed. +\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} +\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} +% +% Parts, in the short toc. +\def\shortpartentry#1#2#3#4{% + \penalty-300 + \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip + \shortchapentry{{\bf #1}}{\numeralbox}{}{}% +} + +% Chapters, in the main contents. +\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} +% +% Chapters, in the short toc. +% See comments in \dochapentry re vbox and related settings. +\def\shortchapentry#1#2#3#4{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +} + +% Appendices, in the main contents. +% Need the word Appendix, and a fixed-size box. +% +\def\appendixbox#1{% + % We use M since it's probably the widest letter. + \setbox0 = \hbox{\putwordAppendix{} M}% + \hbox to \wd0{\putwordAppendix{} #1\hss}} +% +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} + +% Unnumbered chapters. +\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} +\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} + +% Sections. +\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +\let\appsecentry=\numsecentry +\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} + +% Subsections. +\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +\let\appsubsecentry=\numsubsecentry +\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} + +% And subsubsections. +\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +\let\appsubsubsecentry=\numsubsubsecentry +\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} + +% This parameter controls the indentation of the various levels. +% Same as \defaultparindent. +\newdimen\tocindent \tocindent = 15pt + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% We use the same \entry macro as for the index entries. +\let\tocentry = \entry + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\def\subsecentryfonts{\textfonts} +\def\subsubsecentryfonts{\textfonts} + + +\message{environments,} +% @foo ... @end foo. + +% @tex ... @end tex escapes into raw TeX temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain @ character. + +\envdef\tex{% + \setupmarkupstyle{tex}% + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie + \catcode `\%=14 + \catcode `\+=\other + \catcode `\"=\other + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other + \catcode`\`=\other + \catcode`\'=\other + \escapechar=`\\ + % + % ' is active in math mode (mathcode"8000). So reset it, and all our + % other math active characters (just in case), to plain's definitions. + \mathactive + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\/=\ptexslash + \let\*=\ptexstar + \let\t=\ptext + \expandafter \let\csname top\endcsname=\ptextop % outer + \let\frenchspacing=\plainfrenchspacing + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +} +% There is no need to define \Etex. + +% Define @lisp ... @end lisp. +% @lisp environment forms a group so it can rebind things, +% including the definition of @end lisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip. +% +\def\aboveenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + % it's not a good place to break if the last penalty was \nobreak + % or better ... + \ifnum\lastpenalty<10000 \penalty-50 \fi + \vskip\envskipamount + \fi + \fi +}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will +% also clear it, so that its embedded environments do the narrowing again. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\envdef\cartouche{% + \ifhmode\par\fi % can't be in the midst of a paragraph. + \startsavinginserts + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt % we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either + % side, and for 6pt waste from + % each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing = t% + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. + \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \kern3pt + \hsize=\cartinner + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip + \comment % For explanation, see the end of def\group. +} +\def\Ecartouche{% + \ifhmode\par\fi + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup + \checkinserts +} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\newdimen\nonfillparindent +\def\nonfillstart{% + \aboveenvbreak + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + % Turn off paragraph indentation but redefine \indent to emulate + % the normal \indent. + \nonfillparindent=\parindent + \parindent = 0pt + \let\indent\nonfillindent + % + \emergencystretch = 0pt % don't try to avoid overfull boxes + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \else + \let\nonarrowing = \relax + \fi + \let\exdent=\nofillexdent +} + +\begingroup +\obeyspaces +% We want to swallow spaces (but not other tokens) after the fake +% @indent in our nonfill-environments, where spaces are normally +% active and set to @tie, resulting in them not being ignored after +% @indent. +\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% +\gdef\nonfillindentcheck{% +\ifx\temp % +\expandafter\nonfillindentgobble% +\else% +\leavevmode\nonfillindentbox% +\fi% +}% +\endgroup +\def\nonfillindentgobble#1{\nonfillindent} +\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} + +% If you want all examples etc. small: @set dispenvsize small. +% If you want even small examples the full size: @set dispenvsize nosmall. +% This affects the following displayed environments: +% @example, @display, @format, @lisp +% +\def\smallword{small} +\def\nosmallword{nosmall} +\let\SETdispenvsize\relax +\def\setnormaldispenv{% + \ifx\SETdispenvsize\smallword + % end paragraph for sake of leading, in case document has no blank + % line. This is redundant with what happens in \aboveenvbreak, but + % we need to do it before changing the fonts, and it's inconvenient + % to change the fonts afterward. + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} +\def\setsmalldispenv{% + \ifx\SETdispenvsize\nosmallword + \else + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} + +% We often define two environments, @foo and @smallfoo. +% Let's do it in one command. #1 is the env name, #2 the definition. +\def\makedispenvdef#1#2{% + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% + \expandafter\let\csname E#1\endcsname \afterenvbreak + \expandafter\let\csname Esmall#1\endcsname \afterenvbreak +} + +% Define two environment synonyms (#1 and #2) for an environment. +\def\maketwodispenvdef#1#2#3{% + \makedispenvdef{#1}{#3}% + \makedispenvdef{#2}{#3}% +} +% +% @lisp: indented, narrowed, typewriter font; +% @example: same as @lisp. +% +% @smallexample and @smalllisp: use smaller fonts. +% Originally contributed by Pavel@xerox. +% +\maketwodispenvdef{lisp}{example}{% + \nonfillstart + \tt\setupmarkupstyle{example}% + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} +% @display/@smalldisplay: same as @lisp except keep current font. +% +\makedispenvdef{display}{% + \nonfillstart + \gobble +} + +% @format/@smallformat: same as @display except don't narrow margins. +% +\makedispenvdef{format}{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} + +% @flushleft: same as @format, but doesn't obey \SETdispenvsize. +\envdef\flushleft{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} +\let\Eflushleft = \afterenvbreak + +% @flushright. +% +\envdef\flushright{% + \let\nonarrowing = t% + \nonfillstart + \advance\leftskip by 0pt plus 1fill\relax + \gobble +} +\let\Eflushright = \afterenvbreak + + +% @raggedright does more-or-less normal line breaking but no right +% justification. From plain.tex. +\envdef\raggedright{% + \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax +} +\let\Eraggedright\par + +\envdef\raggedleft{% + \parindent=0pt \leftskip0pt plus2em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedleft\par + +\envdef\raggedcenter{% + \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedcenter\par + + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. We keep \parskip nonzero in general, since +% we're doing normal filling. So, when using \aboveenvbreak and +% \afterenvbreak, temporarily make \parskip 0. +% +\makedispenvdef{quotation}{\quotationstart} +% +\def\quotationstart{% + \indentedblockstart % same as \indentedblock, but increase right margin too. + \ifx\nonarrowing\relax + \advance\rightskip by \lispnarrowing + \fi + \parsearg\quotationlabel +} + +% We have retained a nonzero parskip for the environment, since we're +% doing normal filling. +% +\def\Equotation{% + \par + \ifx\quotationauthor\thisisundefined\else + % indent a bit. + \leftline{\kern 2\leftskip \sl ---\quotationauthor}% + \fi + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallquotation{\Equotation} + +% If we're given an argument, typeset it in bold with a colon after. +\def\quotationlabel#1{% + \def\temp{#1}% + \ifx\temp\empty \else + {\bf #1: }% + \fi +} + +% @indentedblock is like @quotation, but indents only on the left and +% has no optional argument. +% +\makedispenvdef{indentedblock}{\indentedblockstart} +% +\def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi +} + +% Keep a nonzero parskip for the environment, since we're doing normal filling. +% +\def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallindentedblock{\Eindentedblock} + + +% LaTeX-like @verbatim...@end verbatim and @verb{...} +% If we want to allow any as delimiter, +% we need the curly braces so that makeinfo sees the @verb command, eg: +% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org +% +% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. +% +% [Knuth] p.344; only we need to do the other characters Texinfo sets +% active too. Otherwise, they get lost as the first character on a +% verbatim line. +\def\dospecials{% + \do\ \do\\\do\{\do\}\do\$\do\&% + \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% + \do\<\do\>\do\|\do\@\do+\do\"% + % Don't do the quotes -- if we do, @set txicodequoteundirected and + % @set txicodequotebacktick will not have effect on @verb and + % @verbatim, and ?` and !` ligatures won't get disabled. + %\do\`\do\'% +} +% +% [Knuth] p. 380 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1=\other}\dospecials} +% +% Setup for the @verb command. +% +% Eight spaces for a tab +\begingroup + \catcode`\^^I=\active + \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} +\endgroup +% +\def\setupverb{% + \tt % easiest (and conventionally used) font for verbatim + \def\par{\leavevmode\endgraf}% + \setupmarkupstyle{verb}% + \tabeightspaces + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces +} + +% Setup for the @verbatim environment +% +% Real tab expansion. +\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount +% +% We typeset each line of the verbatim in an \hbox, so we can handle +% tabs. The \global is in case the verbatim line starts with an accent, +% or some other command that starts with a begin-group. Otherwise, the +% entire \verbbox would disappear at the corresponding end-group, before +% it is typeset. Meanwhile, we can't have nested verbatim commands +% (can we?), so the \global won't be overwriting itself. +\newbox\verbbox +\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} +% +\begingroup + \catcode`\^^I=\active + \gdef\tabexpand{% + \catcode`\^^I=\active + \def^^I{\leavevmode\egroup + \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab + \divide\dimen\verbbox by\tabw + \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw + \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw + \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox + }% + } +\endgroup + +% start the verbatim environment. +\def\setupverbatim{% + \let\nonarrowing = t% + \nonfillstart + \tt % easiest (and conventionally used) font for verbatim + % The \leavevmode here is for blank lines. Otherwise, we would + % never \starttabox and the \egroup would end verbatim mode. + \def\par{\leavevmode\egroup\box\verbbox\endgraf}% + \tabexpand + \setupmarkupstyle{verbatim}% + % Respect line breaks, + % print special symbols as themselves, and + % make each space count. + % Must do in this order: + \obeylines \uncatcodespecials \sepspaces + \everypar{\starttabbox}% +} + +% Do the @verb magic: verbatim text is quoted by unique +% delimiter characters. Before first delimiter expect a +% right brace, after last delimiter expect closing brace: +% +% \def\doverb'{'#1'}'{#1} +% +% [Knuth] p. 382; only eat outer {} +\begingroup + \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other + \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] +\endgroup +% +\def\verb{\begingroup\setupverb\doverb} +% +% +% Do the @verbatim magic: define the macro \doverbatim so that +% the (first) argument ends when '@end verbatim' is reached, ie: +% +% \def\doverbatim#1@end verbatim{#1} +% +% For Texinfo it's a lot easier than for LaTeX, +% because texinfo's \verbatim doesn't stop at '\end{verbatim}': +% we need not redefine '\', '{' and '}'. +% +% Inspired by LaTeX's verbatim command set [latex.ltx] +% +\begingroup + \catcode`\ =\active + \obeylines % + % ignore everything up to the first ^^M, that's the newline at the end + % of the @verbatim input line itself. Otherwise we get an extra blank + % line in the output. + \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% + % We really want {...\end verbatim} in the body of the macro, but + % without the active space; thus we have to use \xdef and \gobble. +\endgroup +% +\envdef\verbatim{% + \setupverbatim\doverbatim +} +\let\Everbatim = \afterenvbreak + + +% @verbatiminclude FILE - insert text of file in verbatim environment. +% +\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} +% +\def\doverbatiminclude#1{% + {% + \makevalueexpandable + \setupverbatim + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% + \input #1 + \afterenvbreak + }% +} + +% @copying ... @end copying. +% Save the text away for @insertcopying later. +% +% We save the uninterpreted tokens, rather than creating a box. +% Saving the text in a box would be much easier, but then all the +% typesetting commands (@smallbook, font changes, etc.) have to be done +% beforehand -- and a) we want @copying to be done first in the source +% file; b) letting users define the frontmatter in as flexible order as +% possible is very desirable. +% +\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} +\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} +% +\def\insertcopying{% + \begingroup + \parindent = 0pt % paragraph indentation looks wrong on title page + \scanexp\copyingtext + \endgroup +} + + +\message{defuns,} +% @defun etc. + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deflastargmargin \deflastargmargin=18pt +\newcount\defunpenalty + +% Start the processing of @deffn: +\def\startdefun{% + \ifnum\lastpenalty<10000 + \medbreak + \defunpenalty=10003 % Will keep this @deffn together with the + % following @def command, see below. + \else + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we need to allow a + % break somewhere. Check specifically for penalty 10002, inserted + % by \printdefunline, instead of 10000, since the sectioning + % commands also insert a nobreak penalty, and we don't want to allow + % a break between a section heading and a defun. + % + % As a further refinement, we avoid "club" headers by signalling + % with penalty of 10003 after the very first @deffn in the + % sequence (see above), and penalty of 10002 after any following + % @def command. + \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi + % + % Similarly, after a section heading, do not allow a break. + % But do insert the glue. + \medskip % preceded by discardable penalty, so not a breakpoint + \fi + % + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent +} + +\def\dodefunx#1{% + % First, check whether we are in the right environment: + \checkenv#1% + % + % As above, allow line break if we have multiple x headers in a row. + % It's not a great place, though. + \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi + % + % And now, it's time to reuse the body of the original defun: + \expandafter\gobbledefun#1% +} +\def\gobbledefun#1\startdefun{} + +% \printdefunline \deffnheader{text} +% +\def\printdefunline#1#2{% + \begingroup + % call \deffnheader: + #1#2 \endheader + % common ending: + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil\relax + \endgraf + \nobreak\vskip -\parskip + \penalty\defunpenalty % signal to \startdefun and \dodefunx + % Some of the @defun-type tags do not enable magic parentheses, + % rendering the following check redundant. But we don't optimize. + \checkparencounts + \endgroup +} + +\def\Edefun{\endgraf\medbreak} + +% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; +% the only thing remaining is to define \deffnheader. +% +\def\makedefun#1{% + \expandafter\let\csname E#1\endcsname = \Edefun + \edef\temp{\noexpand\domakedefun + \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% + \temp +} + +% \domakedefun \deffn \deffnx \deffnheader +% +% Define \deffn and \deffnx, without parameters. +% \deffnheader has to be defined explicitly. +% +\def\domakedefun#1#2#3{% + \envdef#1{% + \startdefun + \doingtypefnfalse % distinguish typed functions from all else + \parseargusing\activeparens{\printdefunline#3}% + }% + \def#2{\dodefunx#1}% + \def#3% +} + +\newif\ifdoingtypefn % doing typed function? +\newif\ifrettypeownline % typeset return type on its own line? + +% @deftypefnnewline on|off says whether the return type of typed functions +% are printed on their own line. This affects @deftypefn, @deftypefun, +% @deftypeop, and @deftypemethod. +% +\parseargdef\deftypefnnewline{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @txideftypefnnl value `\temp', + must be on|off}% + \fi\fi +} + +% Untyped functions: + +% @deffn category name args +\makedefun{deffn}{\deffngeneral{}} + +% @deffn category class name args +\makedefun{defop}#1 {\defopon{#1\ \putwordon}} + +% \defopon {category on}class name args +\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deffngeneral {subind}category name args +% +\def\deffngeneral#1#2 #3 #4\endheader{% + % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. + \dosubind{fn}{\code{#3}}{#1}% + \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% +} + +% Typed functions: + +% @deftypefn category type name args +\makedefun{deftypefn}{\deftypefngeneral{}} + +% @deftypeop category class type name args +\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} + +% \deftypeopon {category on}class type name args +\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deftypefngeneral {subind}category type name args +% +\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% + \dosubind{fn}{\code{#4}}{#1}% + \doingtypefntrue + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Typed variables: + +% @deftypevr category type var args +\makedefun{deftypevr}{\deftypecvgeneral{}} + +% @deftypecv category class type var args +\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} + +% \deftypecvof {category of}class type var args +\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } + +% \deftypecvgeneral {subind}category type var args +% +\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% + \dosubind{vr}{\code{#4}}{#1}% + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Untyped variables: + +% @defvr category var args +\makedefun{defvr}#1 {\deftypevrheader{#1} {} } + +% @defcv category class var args +\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} + +% \defcvof {category of}class var args +\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } + +% Types: + +% @deftp category name args +\makedefun{deftp}#1 #2 #3\endheader{% + \doind{tp}{\code{#2}}% + \defname{#1}{}{#2}\defunargs{#3\unskip}% +} + +% Remaining @defun-like shortcuts: +\makedefun{defun}{\deffnheader{\putwordDeffunc} } +\makedefun{defmac}{\deffnheader{\putwordDefmac} } +\makedefun{defspec}{\deffnheader{\putwordDefspec} } +\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } +\makedefun{defvar}{\defvrheader{\putwordDefvar} } +\makedefun{defopt}{\defvrheader{\putwordDefopt} } +\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } +\makedefun{defmethod}{\defopon\putwordMethodon} +\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} +\makedefun{defivar}{\defcvof\putwordInstanceVariableof} +\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} + +% \defname, which formats the name of the @def (not the args). +% #1 is the category, such as "Function". +% #2 is the return type, if any. +% #3 is the function name. +% +% We are followed by (but not passed) the arguments, if any. +% +\def\defname#1#2#3{% + \par + % Get the values of \leftskip and \rightskip as they were outside the @def... + \advance\leftskip by -\defbodyindent + % + % Determine if we are typesetting the return type of a typed function + % on a line by itself. + \rettypeownlinefalse + \ifdoingtypefn % doing a typed function specifically? + % then check user option for putting return type on its own line: + \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else + \rettypeownlinetrue + \fi + \fi + % + % How we'll format the category name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \def\temp{#1}% + \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} + % + % Figure out line sizes for the paragraph shape. We'll always have at + % least two. + \tempnum = 2 + % + % The first line needs space for \box0; but if \rightskip is nonzero, + % we need only space for the part of \box0 which exceeds it: + \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % + % If doing a return type on its own line, we'll have another line. + \ifrettypeownline + \advance\tempnum by 1 + \def\maybeshapeline{0in \hsize}% + \else + \def\maybeshapeline{}% + \fi + % + % The continuations: + \dimen2=\hsize \advance\dimen2 by -\defargsindent + % + % The final paragraph shape: + \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 + % + % Put the category name at the right margin. + \noindent + \hbox to 0pt{% + \hfil\box0 \kern-\hsize + % \hsize has to be shortened this way: + \kern\leftskip + % Intentionally do not respect \rightskip, since we need the space. + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \exdentamount=\defbodyindent + {% + % defun fonts. We use typewriter by default (used to be bold) because: + % . we're printing identifiers, they should be in tt in principle. + % . in languages with many accents, such as Czech or French, it's + % common to leave accents off identifiers. The result looks ok in + % tt, but exceedingly strange in rm. + % . we don't want -- and --- to be treated as ligatures. + % . this still does not fix the ?` and !` ligatures, but so far no + % one has made identifiers using them :). + \df \tt + \def\temp{#2}% text of the return type + \ifx\temp\empty\else + \tclose{\temp}% typeset the return type + \ifrettypeownline + % put return type on its own line; prohibit line break following: + \hfil\vadjust{\nobreak}\break + \else + \space % type on same line, so just followed by a space + \fi + \fi % no return type + #3% output function name + }% + {\rm\enskip}% hskip 0.5 em of \tenrm + % + \boldbrax + % arguments will be output next, if any. +} + +% Print arguments in slanted roman (not ttsl), inconsistently with using +% tt for the name. This is because literal text is sometimes needed in +% the argument list (groff manual), and ttsl and tt are not very +% distinguishable. Prevent hyphenation at `-' chars. +% +\def\defunargs#1{% + % use sl by default (not ttsl), + % tt for the names. + \df \sl \hyphenchar\font=0 + % + % On the other hand, if an argument has two dashes (for instance), we + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. + \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + #1% + \sl\hyphenchar\font=45 +} + +% We want ()&[] to print specially on the defun line. +% +\def\activeparens{% + \catcode`\(=\active \catcode`\)=\active + \catcode`\[=\active \catcode`\]=\active + \catcode`\&=\active +} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +{ + \activeparens + \global\let(=\lparen \global\let)=\rparen + \global\let[=\lbrack \global\let]=\rbrack + \global\let& = \& + + \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + \gdef\magicamp{\let&=\amprm} +} + +\newcount\parencount + +% If we encounter &foo, then turn on ()-hacking afterwards +\newif\ifampseen +\def\amprm#1 {\ampseentrue{\bf\ }} + +\def\parenfont{% + \ifampseen + % At the first level, print parens in roman, + % otherwise use the default font. + \ifnum \parencount=1 \rm \fi + \else + % The \sf parens (in \boldbrax) actually are a little bolder than + % the contained text. This is especially needed for [ and ] . + \sf + \fi +} +\def\infirstlevel#1{% + \ifampseen + \ifnum\parencount=1 + #1% + \fi + \fi +} +\def\bfafterword#1 {#1 \bf} + +\def\opnr{% + \global\advance\parencount by 1 + {\parenfont(}% + \infirstlevel \bfafterword +} +\def\clnr{% + {\parenfont)}% + \infirstlevel \sl + \global\advance\parencount by -1 +} + +\newcount\brackcount +\def\lbrb{% + \global\advance\brackcount by 1 + {\bf[}% +} +\def\rbrb{% + {\bf]}% + \global\advance\brackcount by -1 +} + +\def\checkparencounts{% + \ifnum\parencount=0 \else \badparencount \fi + \ifnum\brackcount=0 \else \badbrackcount \fi +} +% these should not use \errmessage; the glibc manual, at least, actually +% has such constructs (when documenting function pointers). +\def\badparencount{% + \message{Warning: unbalanced parentheses in @def...}% + \global\parencount=0 +} +\def\badbrackcount{% + \message{Warning: unbalanced square brackets in @def...}% + \global\brackcount=0 +} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\thisisundefined + \newwrite\macscribble + \def\scantokens#1{% + \toks0={#1}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \input \jobname.tmp + } +\fi + +\def\scanmacro#1{\begingroup + \newlinechar`\^^M + \let\xeatspaces\eatspaces + % + % Undo catcode changes of \startcontents and \doprintindex + % When called from @insertcopying or (short)caption, we need active + % backslash to get it printed correctly. Previously, we had + % \catcode`\\=\other instead. We'll see whether a problem appears + % with macro expansion. --kasal, 19aug04 + \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ + % + % ... and for \example: + \spaceisspace + % + % The \empty here causes a following catcode 5 newline to be eaten as + % part of reading whitespace after a control sequence. It does not + % eat a catcode 13 newline. There's no good way to handle the two + % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX + % would then have different behavior). See the Macro Details node in + % the manual for the workaround we recommend for macros and + % line-oriented commands. + % + \scantokens{#1\empty}% +\endgroup} + +\def\scanexp#1{% + \edef\temp{\noexpand\scanmacro{#1}}% + \temp +} + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? + +% List of all defined macros in the form +% \definedummyword\macro1\definedummyword\macro2... +% Currently is also contains all @aliases; the list can be split +% if there is a need. +\def\macrolist{} + +% Add the macro to \macrolist +\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} +\def\addtomacrolistxxx#1{% + \toks0 = \expandafter{\macrolist\definedummyword#1}% + \xdef\macrolist{\the\toks0}% +} + +% Utility routines. +% This does \let #1 = #2, with \csnames; that is, +% \let \csname#1\endcsname = \csname#2\endcsname +% (except of course we have to play expansion games). +% +\def\cslet#1#2{% + \expandafter\let + \csname#1\expandafter\endcsname + \csname#2\endcsname +} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=\other \catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \ +% to recognize macro arguments; this is the job of \mbodybackslash. +% +% Non-ASCII encodings make 8-bit characters active, so un-activate +% them to avoid their expansion. Must do this non-globally, to +% confine the change to the current group. +% +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. +% +\def\scanctxt{% used as subroutine + \catcode`\"=\other + \catcode`\+=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\@=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\~=\other + \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi +} + +\def\scanargctxt{% used for copying and captions, not macros. + \scanctxt + \catcode`\\=\other + \catcode`\^^M=\other +} + +\def\macrobodyctxt{% used for @macro definitions + \scanctxt + \catcode`\{=\other + \catcode`\}=\other + \catcode`\^^M=\other + \usembodybackslash +} + +\def\macroargctxt{% used when scanning invocations + \scanctxt + \catcode`\\=0 +} +% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes" +% for the single characters \ { }. Thus, we end up with the "commands" +% that would be written @\ @{ @} in a Texinfo document. +% +% We already have @{ and @}. For @\, we define it here, and only for +% this purpose, to produce a typewriter backslash (so, the @\ that we +% define for @math can't be used with @macro calls): +% +\def\\{\normalbackslash}% +% +% We would like to do this for \, too, since that is what makeinfo does. +% But it is not possible, because Texinfo already has a command @, for a +% cedilla accent. Documents must use @comma{} instead. +% +% \anythingelse will almost certainly be an error of some kind. + + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. +% +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\margbackslash#1{\char`\#1 } + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0\relax + \else + \expandafter\parsemargdef \argl;% + \if\paramno>256\relax + \ifx\eTeXversion\thisisundefined + \errhelp = \EMsimple + \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} + \fi + \fi + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{Macro name \the\macname\space already defined}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + \addtomacrolist{\the\macname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\parseargdef\unmacro{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist: + \begingroup + \expandafter\let\csname#1\endcsname \relax + \let\definedummyword\unmacrodo + \xdef\macrolist{\macrolist}% + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% Called by \do from \dounmacro on each macro. The idea is to omit any +% macro definitions that have been changed to \relax. +% +\def\unmacrodo#1{% + \ifx #1\relax + % remove this + \else + \noexpand\definedummyword \noexpand#1% + \fi +} + +% This makes use of the obscure feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname#1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} + +% For macro processing make @ a letter so that we can make Texinfo private macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH +% in the params list to some hook where the argument si to be expanded. If +% there are less than 10 arguments that hook is to be replaced by ##N where N +% is the position in that list, that is to say the macro arguments are to be +% defined `a la TeX in the macro body. +% +% That gets used by \mbodybackslash (above). +% +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. +% +% The same technique is used to protect \eatspaces till just before +% the macro is used. +% +% If there are 10 or more arguments, a different technique is used, where the +% hook remains in the body, and when macro is to be expanded the body is +% processed again to replace the arguments. +% +% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +% argument N value and then \edef the body (nothing else will expand because of +% the catcode regime underwhich the body was input). +% +% If you compile with TeX (not eTeX), and you have macros with 10 or more +% arguments, you need that no macro has more than 256 arguments, otherwise an +% error is produced. +\def\parsemargdef#1;{% + \paramno=0\def\paramlist{}% + \let\hash\relax + \let\xeatspaces\relax + \parsemargdefxxx#1,;,% + % In case that there are 10 or more arguments we parse again the arguments + % list to set new definitions for the \macarg.BLAH macros corresponding to + % each BLAH argument. It was anyhow needed to parse already once this list + % in order to count the arguments, and as macros with at most 9 arguments + % are by far more frequent than macro with 10 or more arguments, defining + % twice the \macarg.BLAH macros does not cost too much processing power. + \ifnum\paramno<10\relax\else + \paramno0\relax + \parsemmanyargdef@@#1,;,% 10 or more arguments + \fi +} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1 + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +\def\parsemmanyargdef@@#1,{% + \if#1;\let\next=\relax + \else + \let\next=\parsemmanyargdef@@ + \edef\tempb{\eatspaces{#1}}% + \expandafter\def\expandafter\tempa + \expandafter{\csname macarg.\tempb\endcsname}% + % Note that we need some extra \noexpand\noexpand, this is because we + % don't want \the to be expanded in the \parsermacbody as it uses an + % \xdef . + \expandafter\edef\tempa + {\noexpand\noexpand\noexpand\the\toks\the\paramno}% + \advance\paramno by 1\relax + \fi\next} + +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) +% + +\catcode `\@\texiatcatcode +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\catcode `\@=11\relax + +\let\endargs@\relax +\let\nil@\relax +\def\nilm@{\nil@}% +\long\def\nillm@{\nil@}% + +% This macro is expanded during the Texinfo macro expansion, not during its +% definition. It gets all the arguments values and assigns them to macros +% macarg.ARGNAME +% +% #1 is the macro name +% #2 is the list of argument names +% #3 is the list of argument values +\def\getargvals@#1#2#3{% + \def\macargdeflist@{}% + \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. + \def\paramlist{#2,\nil@}% + \def\macroname{#1}% + \begingroup + \macroargctxt + \def\argvaluelist{#3,\nil@}% + \def\@tempa{#3}% + \ifx\@tempa\empty + \setemptyargvalues@ + \else + \getargvals@@ + \fi +} + +% +\def\getargvals@@{% + \ifx\paramlist\nilm@ + % Some sanity check needed here that \argvaluelist is also empty. + \ifx\argvaluelist\nillm@ + \else + \errhelp = \EMsimple + \errmessage{Too many arguments in macro `\macroname'!}% + \fi + \let\next\macargexpandinbody@ + \else + \ifx\argvaluelist\nillm@ + % No more arguments values passed to macro. Set remaining named-arg + % macros to empty. + \let\next\setemptyargvalues@ + \else + % pop current arg name into \@tempb + \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% + \expandafter\@tempa\expandafter{\paramlist}% + % pop current argument value into \@tempc + \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% + \expandafter\@tempa\expandafter{\argvaluelist}% + % Here \@tempb is the current arg name and \@tempc is the current arg value. + % First place the new argument macro definition into \@tempd + \expandafter\macname\expandafter{\@tempc}% + \expandafter\let\csname macarg.\@tempb\endcsname\relax + \expandafter\def\expandafter\@tempe\expandafter{% + \csname macarg.\@tempb\endcsname}% + \edef\@tempd{\long\def\@tempe{\the\macname}}% + \push@\@tempd\macargdeflist@ + \let\next\getargvals@@ + \fi + \fi + \next +} + +\def\push@#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter#1#2}% +} + +% Replace arguments by their values in the macro body, and place the result +% in macro \@tempa +\def\macvalstoargs@{% + % To do this we use the property that token registers that are \the'ed + % within an \edef expand only once. So we are going to place all argument + % values into respective token registers. + % + % First we save the token context, and initialize argument numbering. + \begingroup + \paramno0\relax + % Then, for each argument number #N, we place the corresponding argument + % value into a new token list register \toks#N + \expandafter\putargsintokens@\saveparamlist@,;,% + % Then, we expand the body so that argument are replaced by their + % values. The trick for values not to be expanded themselves is that they + % are within tokens and that tokens expand only once in an \edef . + \edef\@tempc{\csname mac.\macroname .body\endcsname}% + % Now we restore the token stack pointer to free the token list registers + % which we have used, but we make sure that expanded body is saved after + % group. + \expandafter + \endgroup + \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% + } + +\def\macargexpandinbody@{% + %% Define the named-macro outside of this group and then close this group. + \expandafter + \endgroup + \macargdeflist@ + % First the replace in body the macro arguments by their values, the result + % is in \@tempa . + \macvalstoargs@ + % Then we point at the \norecurse or \gobble (for recursive) macro value + % with \@tempb . + \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname + % Depending on whether it is recursive or not, we need some tailing + % \egroup . + \ifx\@tempb\gobble + \let\@tempc\relax + \else + \let\@tempc\egroup + \fi + % And now we do the real job: + \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% + \@tempd +} + +\def\putargsintokens@#1,{% + \if#1;\let\next\relax + \else + \let\next\putargsintokens@ + % First we allocate the new token list register, and give it a temporary + % alias \@tempb . + \toksdef\@tempb\the\paramno + % Then we place the argument value into that token list register. + \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname + \expandafter\@tempb\expandafter{\@tempa}% + \advance\paramno by 1\relax + \fi + \next +} + +% Save the token stack pointer into macro #1 +\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}} +% Restore the token stack pointer from number in macro #1 +\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax} +% newtoks that can be used non \outer . +\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi} + +% Tailing missing arguments are set to empty +\def\setemptyargvalues@{% + \ifx\paramlist\nilm@ + \let\next\macargexpandinbody@ + \else + \expandafter\setemptyargvaluesparser@\paramlist\endargs@ + \let\next\setemptyargvalues@ + \fi + \next +} + +\def\setemptyargvaluesparser@#1,#2\endargs@{% + \expandafter\def\expandafter\@tempa\expandafter{% + \expandafter\def\csname macarg.#1\endcsname{}}% + \push@\@tempa\macargdeflist@ + \def\paramlist{#2}% +} + +% #1 is the element target macro +% #2 is the list macro +% #3,#4\endargs@ is the list value +\def\pop@#1#2#3,#4\endargs@{% + \def#1{#3}% + \def#2{#4}% +} +\long\def\longpop@#1#2#3,#4\endargs@{% + \long\def#1{#3}% + \long\def#2{#4}% +} + +% This defines a Texinfo @macro. There are eight cases: recursive and +% nonrecursive macros of zero, one, up to nine, and many arguments. +% Much magic with \expandafter here. +% \xdef is used so that macro definitions will survive the file +% they're defined in; @include reads the file inside a group. +% +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else + \ifnum\paramno<10\relax % at most 9 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \else % 10 or more + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \fi + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % at most 9 + \ifnum\paramno<10\relax + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % 10 or more: + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse + \fi + \fi + \fi} + +\catcode `\@\texiatcatcode\relax + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg). +% +\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \macnamexxx} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Make them active and then expand them all to nothing. +% +\def\alias{\parseargusing\obeyspaces\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{% + {% + \expandafter\let\obeyedspace=\empty + \addtomacrolist{#1}% + \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% + }% + \next +} + + +\message{cross references,} + +\newwrite\auxfile +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{% + \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's only job in TeX is to define \lastnode, which is used in +% cross-references. The @node line might or might not have commas, and +% might or might not have spaces before the first comma, like: +% @node foo , bar , ... +% We don't want such trailing spaces in the node name. +% +\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} +% +% also remove a trailing comma, in case of something like this: +% @node Help-Cross, , , Cross-refs +\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} +\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} + +\let\nwnode=\node +\let\lastnode=\empty + +% Write a cross-reference definition for the current node. #1 is the +% type (Ynumbered, Yappendix, Ynothing). +% +\def\donoderef#1{% + \ifx\lastnode\empty\else + \setref{\lastnode}{#1}% + \global\let\lastnode=\empty + \fi +} + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +% +\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an +% anchor), which consists of three parts: +% 1) NAME-title - the current sectioning name taken from \lastsection, +% or the anchor name. +% 2) NAME-snt - section number and type, passed as the SNT arg, or +% empty for anchors. +% 3) NAME-pg - the page number. +% +% This is called from \donoderef, \anchor, and \dofloat. In the case of +% floats, there is an additional part, which is not written here: +% 4) NAME-lof - the text as it should appear in a @listoffloats. +% +\def\setref#1#2{% + \pdfmkdest{#1}% + \iflinks + {% + \atdummies % preserve commands, but don't expand them + \edef\writexrdef##1##2{% + \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef + ##1}{##2}}% these are parameters of \writexrdef + }% + \toks0 = \expandafter{\lastsection}% + \immediate \writexrdef{title}{\the\toks0 }% + \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout + }% + \fi +} + +% @xrefautosectiontitle on|off says whether @section(ing) names are used +% automatically in xrefs, if the third arg is not explicitly specified. +% This was provided as a "secret" @set xref-automatic-section-title +% variable, now it's official. +% +\parseargdef\xrefautomaticsectiontitle{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', + must be on|off}% + \fi\fi +} + +% +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +% +\newbox\toprefbox +\newbox\printedrefnamebox +\newbox\infofilenamebox +\newbox\printedmanualbox +% +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + % + % Get args without leading/trailing spaces. + \def\printedrefname{\ignorespaces #3}% + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\infofilename{\ignorespaces #4}% + \setbox\infofilenamebox = \hbox{\infofilename\unskip}% + % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #3) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. + \def\printedrefname{\ignorespaces #1}% + \else + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. + \def\printedrefname{\ignorespaces #1}% + \else + \ifhavexrefs + % We (should) know the real title if we have the xref values. + \def\printedrefname{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printedrefname{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % Make link in pdf output. + \ifpdf + {\indexnofonts + \turnoffactive + \makevalueexpandable + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \edef\pdfxrefdest{#1}% + \ifx\pdfxrefdest\empty + \def\pdfxrefdest{Top}% no empty targets + \else + \txiescapepdf\pdfxrefdest % escape PDF special chars + \fi + % + \leavevmode + \startlink attr{/Border [0 0 0]}% + \ifnum\filenamelength>0 + goto file{\the\filename.pdf} name{\pdfxrefdest}% + \else + goto name{\pdfmkpgn{\pdfxrefdest}}% + \fi + }% + \setcolor{\linkcolor}% + \fi + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". We distinguish them by the + % LABEL-title being set to a magic string. + {% + % Have to otherify everything special to allow the \csname to + % include an _ in the xref name, etc. + \indexnofonts + \turnoffactive + \expandafter\global\expandafter\let\expandafter\Xthisreftitle + \csname XR#1-title\endcsname + }% + \iffloat\Xthisreftitle + % If the user specified the print name (third arg) to the ref, + % print it instead of our usual "Figure 1.2". + \ifdim\wd\printedrefnamebox = 0pt + \refx{#1-snt}{}% + \else + \printedrefname + \fi + % + % If the user also gave the printed manual name (fifth arg), append + % "in MANUALNAME". + \ifdim \wd\printedmanualbox > 0pt + \space \putwordin{} \cite{\printedmanual}% + \fi + \else + % node/anchor (non-float) references. + % + % If we use \unhbox to print the node names, TeX does not insert + % empty discretionaries after hyphens, which means that it will not + % find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, + % this is a loss. Therefore, we give the text of the node name + % again, so it is as if TeX is seeing it for the first time. + % + \ifdim \wd\printedmanualbox > 0pt + % Cross-manual reference with a printed manual name. + % + \crossmanualxref{\cite{\printedmanual\unskip}}% + % + \else\ifdim \wd\infofilenamebox > 0pt + % Cross-manual reference with only an info filename (arg 4), no + % printed manual name (arg 5). This is essentially the same as + % the case above; we output the filename, since we have nothing else. + % + \crossmanualxref{\code{\infofilename\unskip}}% + % + \else + % Reference within this manual. + % + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via the macro below so it can be overridden. + \xrefprintnodename\printedrefname + % + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi\fi + \fi + \endlink +\endgroup} + +% Output a cross-manual xref to #1. Used just above (twice). +% +% Only include the text "Section ``foo'' in" if the foo is neither +% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply +% "see The Foo Manual", the idea being to refer to the whole manual. +% +% But, this being TeX, we can't easily compare our node name against the +% string "Top" while ignoring the possible spaces before and after in +% the input. By adding the arbitrary 7sp below, we make it much less +% likely that a real node name would have the same width as "Top" (e.g., +% in a monospaced font). Hopefully it will never happen in practice. +% +% For the same basic reason, we retypeset the "Top" at every +% reference, since the current font is indeterminate. +% +\def\crossmanualxref#1{% + \setbox\toprefbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp % nonempty? + \ifdim \wd2 = \wd\toprefbox \else % same as Top? + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + #1% +} + +% This macro is called from \xrefX for the `[nodename]' part of xref +% output. It's a separate macro only so it can be changed more easily, +% since square brackets don't work well in some documents. Particularly +% one that Bob is working on :). +% +\def\xrefprintnodename#1{[#1]} + +% Things referred to by \setref. +% +\def\Ynothing{} +\def\Yomitfromtoc{} +\def\Ynumbered{% + \ifnum\secno=0 + \putwordChapter@tie \the\chapno + \else \ifnum\subsecno=0 + \putwordSection@tie \the\chapno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno + \else + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} +\def\Yappendix{% + \ifnum\secno=0 + \putwordAppendix@tie @char\the\appendixno{}% + \else \ifnum\subsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno + \else + \putwordSection@tie + @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. +% +\def\refx#1#2{% + {% + \indexnofonts + \otherbackslash + \expandafter\global\expandafter\let\expandafter\thisrefX + \csname XR#1\endcsname + }% + \ifx\thisrefX\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + {\toks0 = {#1}% avoid expansion of possibly-complex value + \message{\linenumber Undefined cross reference `\the\toks0'.}}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \thisrefX + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. Usually it's +% just a \def (we prepend XR to the control sequence name to avoid +% collisions). But if this is a float type, we have more work to do. +% +\def\xrdef#1#2{% + {% The node name might contain 8-bit characters, which in our current + % implementation are changed to commands like @'e. Don't let these + % mess up the control sequence name. + \indexnofonts + \turnoffactive + \xdef\safexrefname{#1}% + }% + % + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref + % + % Was that xref control sequence that we just defined for a float? + \expandafter\iffloat\csname XR\safexrefname\endcsname + % it was a float, and we have the (safe) float type in \iffloattype. + \expandafter\let\expandafter\floatlist + \csname floatlist\iffloattype\endcsname + % + % Is this the first time we've seen this float type? + \expandafter\ifx\floatlist\relax + \toks0 = {\do}% yes, so just \do + \else + % had it before, so preserve previous elements in list. + \toks0 = \expandafter{\floatlist\do}% + \fi + % + % Remember this xref in the control sequence \floatlistFLOATTYPE, + % for later use in \listoffloats. + \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 + {\safexrefname}}% + \fi +} + +% Read the last existing aux file, if any. No error if none exists. +% +\def\tryauxfile{% + \openin 1 \jobname.aux + \ifeof 1 \else + \readdatafile{aux}% + \global\havexrefstrue + \fi + \closein 1 +} + +\def\setupdatafile{% + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\^=\other + % + % Special characters. Should be turned off anyway, but... + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`\%=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % + % This is to support \ in node names and titles, since the \ + % characters end up in a \csname. It's easier than + % leaving it active and making its active definition an actual \ + % character. What I don't understand is why it works in the *value* + % of the xrdef. Seems like it should be a catcode12 \, and that + % should not typeset properly. But it works, so I'm moving on for + % now. --karl, 15jan04. + \catcode`\\=\other + % + % Make the characters 128-255 be printing characters. + {% + \count1=128 + \def\loop{% + \catcode\count1=\other + \advance\count1 by 1 + \ifnum \count1<256 \loop \fi + }% + }% + % + % @ is our escape character in .aux files, and we need braces. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\@=0 +} + +\def\readdatafile#1{% +\begingroup + \setupdatafile + \input\jobname.#1 +\endgroup} + + +\message{insertions,} +% including footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for Info output only. +\let\footnotestyle=\comment + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \dofootnote +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset (and anything else that uses +% \parseargline) fails inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\gdef\dofootnote{% + \insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \hsize=\pagewidth + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Because we use hanging indentation in footnotes, a @noindent appears + % to exdent this text, so make it be a no-op. makeinfo does not use + % hanging indentation so @noindent can still be needed within footnote + % text after an @example or the like (not that this is good style). + \let\noindent = \relax + % + % Hang the footnote text off the number. Use \everypar in case the + % footnote extends for more than one paragraph. + \everypar = {\hang}% + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + % + % Invoke rest of plain TeX footnote routine. + \futurelet\next\fo@t +} +}%end \catcode `\@=11 + +% In case a @footnote appears in a vbox, save the footnote text and create +% the real \insert just after the vbox finished. Otherwise, the insertion +% would be lost. +% Similarly, if a @footnote appears inside an alignment, save the footnote +% text to a box and make the \insert when a row of the table is finished. +% And the same can be done for other insert classes. --kasal, 16nov03. + +% Replace the \insert primitive by a cheating macro. +% Deeper inside, just make sure that the saved insertions are not spilled +% out prematurely. +% +\def\startsavinginserts{% + \ifx \insert\ptexinsert + \let\insert\saveinsert + \else + \let\checkinserts\relax + \fi +} + +% This \insert replacement works for both \insert\footins{foo} and +% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. +% +\def\saveinsert#1{% + \edef\next{\noexpand\savetobox \makeSAVEname#1}% + \afterassignment\next + % swallow the left brace + \let\temp = +} +\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} +\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} + +\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} + +\def\placesaveins#1{% + \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname + {\box#1}% +} + +% eat @SAVE -- beware, all of them have catcode \other: +{ + \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) + \gdef\gobblesave @SAVE{} +} + +% initialization: +\def\newsaveins #1{% + \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% + \next +} +\def\newsaveinsX #1{% + \csname newbox\endcsname #1% + \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts + \checksaveins #1}% +} + +% initialize: +\let\checkinserts\empty +\newsaveins\footins +\newsaveins\margin + + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + % Do not bother showing banner with epsf.tex v2.7k (available in + % doc/epsf.tex and on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +\closein 1 +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\thisisundefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is (ignored optional) html alt text. +% #5 is (ignored optional) extension. +% #6 is just the usual extra ignored arg for parsing stuff. +\newif\ifimagevmode +\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup + \catcode`\^^M = 5 % in case we're inside an example + \normalturnoffactive % allow _ et al. in names + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue + \else \ifx\centersub\centerV + % for @center @image, we need a vbox so we can have our vertical space + \imagevmodetrue + \vbox\bgroup % vbox has better behavior than vtop herev + \fi\fi + % + \ifimagevmode + \nobreak\medskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \fi + % + % Leave vertical mode so that indentation from an enclosing + % environment such as @quotation is respected. + % However, if we're at the top level, we don't want the + % normal paragraph indentation. + % On the other hand, if we are in the case of @center @image, we don't + % want to start a paragraph, which will create a hsize-width box and + % eradicate the centering. + \ifx\centersub\centerV\else \noindent \fi + % + % Output the image. + \ifpdf + \dopdfimage{#1}{#2}{#3}% + \else + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \fi + % + \ifimagevmode + \medskip % space after a standalone image + \fi + \ifx\centersub\centerV \egroup \fi +\endgroup} + + +% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, +% etc. We don't actually implement floating yet, we always include the +% float "here". But it seemed the best name for the future. +% +\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} + +% There may be a space before second and/or third parameter; delete it. +\def\eatcommaspace#1, {#1,} + +% #1 is the optional FLOATTYPE, the text label for this float, typically +% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, +% this float will not be numbered and cannot be referred to. +% +% #2 is the optional xref label. Also must be present for the float to +% be referable. +% +% #3 is the optional positioning argument; for now, it is ignored. It +% will somehow specify the positions allowed to float to (here, top, bottom). +% +% We keep a separate counter for each FLOATTYPE, which we reset at each +% chapter-level command. +\let\resetallfloatnos=\empty +% +\def\dofloat#1,#2,#3,#4\finish{% + \let\thiscaption=\empty + \let\thisshortcaption=\empty + % + % don't lose footnotes inside @float. + % + % BEWARE: when the floats start float, we have to issue warning whenever an + % insert appears inside a float which could possibly float. --kasal, 26may04 + % + \startsavinginserts + % + % We can't be used inside a paragraph. + \par + % + \vtop\bgroup + \def\floattype{#1}% + \def\floatlabel{#2}% + \def\floatloc{#3}% we do nothing with this yet. + % + \ifx\floattype\empty + \let\safefloattype=\empty + \else + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + \fi + % + % If label is given but no type, we handle that as the empty type. + \ifx\floatlabel\empty \else + % We want each FLOATTYPE to be numbered separately (Figure 1, + % Table 1, Figure 2, ...). (And if no label, no number.) + % + \expandafter\getfloatno\csname\safefloattype floatno\endcsname + \global\advance\floatno by 1 + % + {% + % This magic value for \lastsection is output by \setref as the + % XREFLABEL-title value. \xrefX uses it to distinguish float + % labels (which have a completely different output format) from + % node and anchor labels. And \xrdef uses it to construct the + % lists of floats. + % + \edef\lastsection{\floatmagic=\safefloattype}% + \setref{\floatlabel}{Yfloat}% + }% + \fi + % + % start with \parskip glue, I guess. + \vskip\parskip + % + % Don't suppress indentation if a float happens to start a section. + \restorefirstparagraphindent +} + +% we have these possibilities: +% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap +% @float Foo,lbl & no caption: Foo 1.1 +% @float Foo & @caption{Cap}: Foo: Cap +% @float Foo & no caption: Foo +% @float ,lbl & Caption{Cap}: 1.1: Cap +% @float ,lbl & no caption: 1.1 +% @float & @caption{Cap}: Cap +% @float & no caption: +% +\def\Efloat{% + \let\floatident = \empty + % + % In all cases, if we have a float type, it comes first. + \ifx\floattype\empty \else \def\floatident{\floattype}\fi + % + % If we have an xref label, the number comes next. + \ifx\floatlabel\empty \else + \ifx\floattype\empty \else % if also had float type, need tie first. + \appendtomacro\floatident{\tie}% + \fi + % the number. + \appendtomacro\floatident{\chaplevelprefix\the\floatno}% + \fi + % + % Start the printed caption with what we've constructed in + % \floatident, but keep it separate; we need \floatident again. + \let\captionline = \floatident + % + \ifx\thiscaption\empty \else + \ifx\floatident\empty \else + \appendtomacro\captionline{: }% had ident, so need a colon between + \fi + % + % caption text. + \appendtomacro\captionline{\scanexp\thiscaption}% + \fi + % + % If we have anything to print, print it, with space before. + % Eventually this needs to become an \insert. + \ifx\captionline\empty \else + \vskip.5\parskip + \captionline + % + % Space below caption. + \vskip\parskip + \fi + % + % If have an xref label, write the list of floats info. Do this + % after the caption, to avoid chance of it being a breakpoint. + \ifx\floatlabel\empty \else + % Write the text that goes in the lof to the aux file as + % \floatlabel-lof. Besides \floatident, we include the short + % caption if specified, else the full caption if specified, else nothing. + {% + \atdummies + % + % since we read the caption text in the macro world, where ^^M + % is turned into a normal character, we have to scan it back, so + % we don't write the literal three characters "^^M" into the aux file. + \scanexp{% + \xdef\noexpand\gtemp{% + \ifx\thisshortcaption\empty + \thiscaption + \else + \thisshortcaption + \fi + }% + }% + \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident + \ifx\gtemp\empty \else : \gtemp \fi}}% + }% + \fi + \egroup % end of \vtop + % + % place the captured inserts + % + % BEWARE: when the floats start floating, we have to issue warning + % whenever an insert appears inside a float which could possibly + % float. --kasal, 26may04 + % + \checkinserts +} + +% Append the tokens #2 to the definition of macro #1, not expanding either. +% +\def\appendtomacro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% +} + +% @caption, @shortcaption +% +\def\caption{\docaption\thiscaption} +\def\shortcaption{\docaption\thisshortcaption} +\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} +\def\defcaption#1#2{\egroup \def#1{#2}} + +% The parameter is the control sequence identifying the counter we are +% going to use. Create it if it doesn't exist and assign it to \floatno. +\def\getfloatno#1{% + \ifx#1\relax + % Haven't seen this figure type before. + \csname newcount\endcsname #1% + % + % Remember to reset this floatno at the next chap. + \expandafter\gdef\expandafter\resetallfloatnos + \expandafter{\resetallfloatnos #1=0 }% + \fi + \let\floatno#1% +} + +% \setref calls this to get the XREFLABEL-snt value. We want an @xref +% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we +% first read the @float command. +% +\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% + +% Magic string used for the XREFLABEL-title value, so \xrefX can +% distinguish floats from other xref types. +\def\floatmagic{!!float!!} + +% #1 is the control sequence we are passed; we expand into a conditional +% which is true if #1 represents a float ref. That is, the magic +% \lastsection value which we \setref above. +% +\def\iffloat#1{\expandafter\doiffloat#1==\finish} +% +% #1 is (maybe) the \floatmagic string. If so, #2 will be the +% (safe) float type for this float. We set \iffloattype to #2. +% +\def\doiffloat#1=#2=#3\finish{% + \def\temp{#1}% + \def\iffloattype{#2}% + \ifx\temp\floatmagic +} + +% @listoffloats FLOATTYPE - print a list of floats like a table of contents. +% +\parseargdef\listoffloats{% + \def\floattype{#1}% floattype + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + % + % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. + \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax + \ifhavexrefs + % if the user said @listoffloats foo but never @float foo. + \message{\linenumber No `\safefloattype' floats to list.}% + \fi + \else + \begingroup + \leftskip=\tocindent % indent these entries like a toc + \let\do=\listoffloatsdo + \csname floatlist\safefloattype\endcsname + \endgroup + \fi +} + +% This is called on each entry in a list of floats. We're passed the +% xref label, in the form LABEL-title, which is how we save it in the +% aux file. We strip off the -title and look up \XRLABEL-lof, which +% has the text we're supposed to typeset here. +% +% Figures without xref labels will not be included in the list (since +% they won't appear in the aux file). +% +\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} +\def\listoffloatsdoentry#1-title\finish{{% + % Can't fully expand XR#1-lof because it can contain anything. Just + % pass the control sequence. On the other hand, XR#1-pg is just the + % page number, and we want to fully expand that so we can get a link + % in pdf output. + \toksA = \expandafter{\csname XR#1-lof\endcsname}% + % + % use the same \entry macro we use to generate the TOC and index. + \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% + \writeentry +}} + + +\message{localization,} + +% For single-language documents, @documentlanguage is usually given very +% early, just after @documentencoding. Single argument is the language +% (de) or locale (de_DE) abbreviation. +% +{ + \catcode`\_ = \active + \globaldefs=1 +\parseargdef\documentlanguage{\begingroup + \let_=\normalunderscore % normal _ character for filenames + \tex % read txi-??.tex file in plain TeX. + % Read the file by the name they passed if it exists. + \openin 1 txi-#1.tex + \ifeof 1 + \documentlanguagetrywithoutunderscore{#1_\finish}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 + \endgroup % end raw TeX +\endgroup} +% +% If they passed de_DE, and txi-de_DE.tex doesn't exist, +% try txi-de.tex. +% +\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% + \openin 1 txi-#1.tex + \ifeof 1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 +} +}% end of special _ catcode +% +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? Putting it in the current +directory should work if nowhere else does.} + +% This macro is called from txi-??.tex files; the first argument is the +% \language name to set (without the "\lang@" prefix), the second and +% third args are \{left,right}hyphenmin. +% +% The language names to pass are determined when the format is built. +% See the etex.log file created at that time, e.g., +% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. +% +% With TeX Live 2008, etex now includes hyphenation patterns for all +% available languages. This means we can support hyphenation in +% Texinfo, at least to some extent. (This still doesn't solve the +% accented characters problem.) +% +\catcode`@=11 +\def\txisetlanguage#1#2#3{% + % do not set the language if the name is undefined in the current TeX. + \expandafter\ifx\csname lang@#1\endcsname \relax + \message{no patterns for #1}% + \else + \global\language = \csname lang@#1\endcsname + \fi + % but there is no harm in adjusting the hyphenmin values regardless. + \global\lefthyphenmin = #2\relax + \global\righthyphenmin = #3\relax +} + +% Helpers for encodings. +% Set the catcode of characters 128 through 255 to the specified number. +% +\def\setnonasciicharscatcode#1{% + \count255=128 + \loop\ifnum\count255<256 + \global\catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +\def\setnonasciicharscatcodenonglobal#1{% + \count255=128 + \loop\ifnum\count255<256 + \catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +% @documentencoding sets the definition of non-ASCII characters +% according to the specified encoding. +% +\parseargdef\documentencoding{% + % Encoding being declared for the document. + \def\declaredencoding{\csname #1.enc\endcsname}% + % + % Supported encodings: names converted to tokens in order to be able + % to compare them with \ifx. + \def\ascii{\csname US-ASCII.enc\endcsname}% + \def\latnine{\csname ISO-8859-15.enc\endcsname}% + \def\latone{\csname ISO-8859-1.enc\endcsname}% + \def\lattwo{\csname ISO-8859-2.enc\endcsname}% + \def\utfeight{\csname UTF-8.enc\endcsname}% + % + \ifx \declaredencoding \ascii + \asciichardefs + % + \else \ifx \declaredencoding \lattwo + \setnonasciicharscatcode\active + \lattwochardefs + % + \else \ifx \declaredencoding \latone + \setnonasciicharscatcode\active + \latonechardefs + % + \else \ifx \declaredencoding \latnine + \setnonasciicharscatcode\active + \latninechardefs + % + \else \ifx \declaredencoding \utfeight + \setnonasciicharscatcode\active + \utfeightchardefs + % + \else + \message{Unknown document encoding #1, ignoring.}% + % + \fi % utfeight + \fi % latnine + \fi % latone + \fi % lattwo + \fi % ascii +} + +% A message to be logged when using a character that isn't available +% the default font encoding (OT1). +% +\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} + +% Take account of \c (plain) vs. \, (Texinfo) difference. +\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} + +% First, make active non-ASCII characters in order for them to be +% correctly categorized when TeX reads the replacement text of +% macros containing the character definitions. +\setnonasciicharscatcode\active +% +% Latin1 (ISO-8859-1) character definitions. +\def\latonechardefs{% + \gdef^^a0{\tie} + \gdef^^a1{\exclamdown} + \gdef^^a2{\missingcharmsg{CENT SIGN}} + \gdef^^a3{{\pounds}} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\missingcharmsg{YEN SIGN}} + \gdef^^a6{\missingcharmsg{BROKEN BAR}} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\copyright} + \gdef^^aa{\ordf} + \gdef^^ab{\guillemetleft} + \gdef^^ac{$\lnot$} + \gdef^^ad{\-} + \gdef^^ae{\registeredsymbol} + \gdef^^af{\={}} + % + \gdef^^b0{\textdegree} + \gdef^^b1{$\pm$} + \gdef^^b2{$^2$} + \gdef^^b3{$^3$} + \gdef^^b4{\'{}} + \gdef^^b5{$\mu$} + \gdef^^b6{\P} + % + \gdef^^b7{$^.$} + \gdef^^b8{\cedilla\ } + \gdef^^b9{$^1$} + \gdef^^ba{\ordm} + % + \gdef^^bb{\guillemetright} + \gdef^^bc{$1\over4$} + \gdef^^bd{$1\over2$} + \gdef^^be{$3\over4$} + \gdef^^bf{\questiondown} + % + \gdef^^c0{\`A} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\~A} + \gdef^^c4{\"A} + \gdef^^c5{\ringaccent A} + \gdef^^c6{\AE} + \gdef^^c7{\cedilla C} + \gdef^^c8{\`E} + \gdef^^c9{\'E} + \gdef^^ca{\^E} + \gdef^^cb{\"E} + \gdef^^cc{\`I} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\"I} + % + \gdef^^d0{\DH} + \gdef^^d1{\~N} + \gdef^^d2{\`O} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\~O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\O} + \gdef^^d9{\`U} + \gdef^^da{\'U} + \gdef^^db{\^U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\TH} + \gdef^^df{\ss} + % + \gdef^^e0{\`a} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\~a} + \gdef^^e4{\"a} + \gdef^^e5{\ringaccent a} + \gdef^^e6{\ae} + \gdef^^e7{\cedilla c} + \gdef^^e8{\`e} + \gdef^^e9{\'e} + \gdef^^ea{\^e} + \gdef^^eb{\"e} + \gdef^^ec{\`{\dotless i}} + \gdef^^ed{\'{\dotless i}} + \gdef^^ee{\^{\dotless i}} + \gdef^^ef{\"{\dotless i}} + % + \gdef^^f0{\dh} + \gdef^^f1{\~n} + \gdef^^f2{\`o} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\~o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\o} + \gdef^^f9{\`u} + \gdef^^fa{\'u} + \gdef^^fb{\^u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\th} + \gdef^^ff{\"y} +} + +% Latin9 (ISO-8859-15) encoding character definitions. +\def\latninechardefs{% + % Encoding is almost identical to Latin1. + \latonechardefs + % + \gdef^^a4{\euro} + \gdef^^a6{\v S} + \gdef^^a8{\v s} + \gdef^^b4{\v Z} + \gdef^^b8{\v z} + \gdef^^bc{\OE} + \gdef^^bd{\oe} + \gdef^^be{\"Y} +} + +% Latin2 (ISO-8859-2) character definitions. +\def\lattwochardefs{% + \gdef^^a0{\tie} + \gdef^^a1{\ogonek{A}} + \gdef^^a2{\u{}} + \gdef^^a3{\L} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\v L} + \gdef^^a6{\'S} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\v S} + \gdef^^aa{\cedilla S} + \gdef^^ab{\v T} + \gdef^^ac{\'Z} + \gdef^^ad{\-} + \gdef^^ae{\v Z} + \gdef^^af{\dotaccent Z} + % + \gdef^^b0{\textdegree} + \gdef^^b1{\ogonek{a}} + \gdef^^b2{\ogonek{ }} + \gdef^^b3{\l} + \gdef^^b4{\'{}} + \gdef^^b5{\v l} + \gdef^^b6{\'s} + \gdef^^b7{\v{}} + \gdef^^b8{\cedilla\ } + \gdef^^b9{\v s} + \gdef^^ba{\cedilla s} + \gdef^^bb{\v t} + \gdef^^bc{\'z} + \gdef^^bd{\H{}} + \gdef^^be{\v z} + \gdef^^bf{\dotaccent z} + % + \gdef^^c0{\'R} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\u A} + \gdef^^c4{\"A} + \gdef^^c5{\'L} + \gdef^^c6{\'C} + \gdef^^c7{\cedilla C} + \gdef^^c8{\v C} + \gdef^^c9{\'E} + \gdef^^ca{\ogonek{E}} + \gdef^^cb{\"E} + \gdef^^cc{\v E} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\v D} + % + \gdef^^d0{\DH} + \gdef^^d1{\'N} + \gdef^^d2{\v N} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\H O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\v R} + \gdef^^d9{\ringaccent U} + \gdef^^da{\'U} + \gdef^^db{\H U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\cedilla T} + \gdef^^df{\ss} + % + \gdef^^e0{\'r} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\u a} + \gdef^^e4{\"a} + \gdef^^e5{\'l} + \gdef^^e6{\'c} + \gdef^^e7{\cedilla c} + \gdef^^e8{\v c} + \gdef^^e9{\'e} + \gdef^^ea{\ogonek{e}} + \gdef^^eb{\"e} + \gdef^^ec{\v e} + \gdef^^ed{\'{\dotless{i}}} + \gdef^^ee{\^{\dotless{i}}} + \gdef^^ef{\v d} + % + \gdef^^f0{\dh} + \gdef^^f1{\'n} + \gdef^^f2{\v n} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\H o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\v r} + \gdef^^f9{\ringaccent u} + \gdef^^fa{\'u} + \gdef^^fb{\H u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\cedilla t} + \gdef^^ff{\dotaccent{}} +} + +% UTF-8 character definitions. +% +% This code to support UTF-8 is based on LaTeX's utf8.def, with some +% changes for Texinfo conventions. It is included here under the GPL by +% permission from Frank Mittelbach and the LaTeX team. +% +\newcount\countUTFx +\newcount\countUTFy +\newcount\countUTFz + +\gdef\UTFviiiTwoOctets#1#2{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\endcsname} +% +\gdef\UTFviiiThreeOctets#1#2#3{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} +% +\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} + +\gdef\UTFviiiDefined#1{% + \ifx #1\relax + \message{\linenumber Unicode char \string #1 not defined for Texinfo}% + \else + \expandafter #1% + \fi +} + +\begingroup + \catcode`\~13 + \catcode`\"12 + + \def\UTFviiiLoop{% + \global\catcode\countUTFx\active + \uccode`\~\countUTFx + \uppercase\expandafter{\UTFviiiTmp}% + \advance\countUTFx by 1 + \ifnum\countUTFx < \countUTFy + \expandafter\UTFviiiLoop + \fi} + + \countUTFx = "C2 + \countUTFy = "E0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiTwoOctets\string~}} + \UTFviiiLoop + + \countUTFx = "E0 + \countUTFy = "F0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiThreeOctets\string~}} + \UTFviiiLoop + + \countUTFx = "F0 + \countUTFy = "F4 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiFourOctets\string~}} + \UTFviiiLoop +\endgroup + +\begingroup + \catcode`\"=12 + \catcode`\<=12 + \catcode`\.=12 + \catcode`\,=12 + \catcode`\;=12 + \catcode`\!=12 + \catcode`\~=13 + + \gdef\DeclareUnicodeCharacter#1#2{% + \countUTFz = "#1\relax + %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% + \begingroup + \parseXMLCharref + \def\UTFviiiTwoOctets##1##2{% + \csname u8:##1\string ##2\endcsname}% + \def\UTFviiiThreeOctets##1##2##3{% + \csname u8:##1\string ##2\string ##3\endcsname}% + \def\UTFviiiFourOctets##1##2##3##4{% + \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter + \gdef\UTFviiiTmp{#2}% + \endgroup} + + \gdef\parseXMLCharref{% + \ifnum\countUTFz < "A0\relax + \errhelp = \EMsimple + \errmessage{Cannot define Unicode char value < 00A0}% + \else\ifnum\countUTFz < "800\relax + \parseUTFviiiA,% + \parseUTFviiiB C\UTFviiiTwoOctets.,% + \else\ifnum\countUTFz < "10000\relax + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% + \else + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiA!% + \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% + \fi\fi\fi + } + + \gdef\parseUTFviiiA#1{% + \countUTFx = \countUTFz + \divide\countUTFz by 64 + \countUTFy = \countUTFz + \multiply\countUTFz by 64 + \advance\countUTFx by -\countUTFz + \advance\countUTFx by 128 + \uccode `#1\countUTFx + \countUTFz = \countUTFy} + + \gdef\parseUTFviiiB#1#2#3#4{% + \advance\countUTFz by "#10\relax + \uccode `#3\countUTFz + \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} +\endgroup + +\def\utfeightchardefs{% + \DeclareUnicodeCharacter{00A0}{\tie} + \DeclareUnicodeCharacter{00A1}{\exclamdown} + \DeclareUnicodeCharacter{00A3}{\pounds} + \DeclareUnicodeCharacter{00A8}{\"{ }} + \DeclareUnicodeCharacter{00A9}{\copyright} + \DeclareUnicodeCharacter{00AA}{\ordf} + \DeclareUnicodeCharacter{00AB}{\guillemetleft} + \DeclareUnicodeCharacter{00AD}{\-} + \DeclareUnicodeCharacter{00AE}{\registeredsymbol} + \DeclareUnicodeCharacter{00AF}{\={ }} + + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} + \DeclareUnicodeCharacter{00B4}{\'{ }} + \DeclareUnicodeCharacter{00B8}{\cedilla{ }} + \DeclareUnicodeCharacter{00BA}{\ordm} + \DeclareUnicodeCharacter{00BB}{\guillemetright} + \DeclareUnicodeCharacter{00BF}{\questiondown} + + \DeclareUnicodeCharacter{00C0}{\`A} + \DeclareUnicodeCharacter{00C1}{\'A} + \DeclareUnicodeCharacter{00C2}{\^A} + \DeclareUnicodeCharacter{00C3}{\~A} + \DeclareUnicodeCharacter{00C4}{\"A} + \DeclareUnicodeCharacter{00C5}{\AA} + \DeclareUnicodeCharacter{00C6}{\AE} + \DeclareUnicodeCharacter{00C7}{\cedilla{C}} + \DeclareUnicodeCharacter{00C8}{\`E} + \DeclareUnicodeCharacter{00C9}{\'E} + \DeclareUnicodeCharacter{00CA}{\^E} + \DeclareUnicodeCharacter{00CB}{\"E} + \DeclareUnicodeCharacter{00CC}{\`I} + \DeclareUnicodeCharacter{00CD}{\'I} + \DeclareUnicodeCharacter{00CE}{\^I} + \DeclareUnicodeCharacter{00CF}{\"I} + + \DeclareUnicodeCharacter{00D0}{\DH} + \DeclareUnicodeCharacter{00D1}{\~N} + \DeclareUnicodeCharacter{00D2}{\`O} + \DeclareUnicodeCharacter{00D3}{\'O} + \DeclareUnicodeCharacter{00D4}{\^O} + \DeclareUnicodeCharacter{00D5}{\~O} + \DeclareUnicodeCharacter{00D6}{\"O} + \DeclareUnicodeCharacter{00D8}{\O} + \DeclareUnicodeCharacter{00D9}{\`U} + \DeclareUnicodeCharacter{00DA}{\'U} + \DeclareUnicodeCharacter{00DB}{\^U} + \DeclareUnicodeCharacter{00DC}{\"U} + \DeclareUnicodeCharacter{00DD}{\'Y} + \DeclareUnicodeCharacter{00DE}{\TH} + \DeclareUnicodeCharacter{00DF}{\ss} + + \DeclareUnicodeCharacter{00E0}{\`a} + \DeclareUnicodeCharacter{00E1}{\'a} + \DeclareUnicodeCharacter{00E2}{\^a} + \DeclareUnicodeCharacter{00E3}{\~a} + \DeclareUnicodeCharacter{00E4}{\"a} + \DeclareUnicodeCharacter{00E5}{\aa} + \DeclareUnicodeCharacter{00E6}{\ae} + \DeclareUnicodeCharacter{00E7}{\cedilla{c}} + \DeclareUnicodeCharacter{00E8}{\`e} + \DeclareUnicodeCharacter{00E9}{\'e} + \DeclareUnicodeCharacter{00EA}{\^e} + \DeclareUnicodeCharacter{00EB}{\"e} + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} + + \DeclareUnicodeCharacter{00F0}{\dh} + \DeclareUnicodeCharacter{00F1}{\~n} + \DeclareUnicodeCharacter{00F2}{\`o} + \DeclareUnicodeCharacter{00F3}{\'o} + \DeclareUnicodeCharacter{00F4}{\^o} + \DeclareUnicodeCharacter{00F5}{\~o} + \DeclareUnicodeCharacter{00F6}{\"o} + \DeclareUnicodeCharacter{00F8}{\o} + \DeclareUnicodeCharacter{00F9}{\`u} + \DeclareUnicodeCharacter{00FA}{\'u} + \DeclareUnicodeCharacter{00FB}{\^u} + \DeclareUnicodeCharacter{00FC}{\"u} + \DeclareUnicodeCharacter{00FD}{\'y} + \DeclareUnicodeCharacter{00FE}{\th} + \DeclareUnicodeCharacter{00FF}{\"y} + + \DeclareUnicodeCharacter{0100}{\=A} + \DeclareUnicodeCharacter{0101}{\=a} + \DeclareUnicodeCharacter{0102}{\u{A}} + \DeclareUnicodeCharacter{0103}{\u{a}} + \DeclareUnicodeCharacter{0104}{\ogonek{A}} + \DeclareUnicodeCharacter{0105}{\ogonek{a}} + \DeclareUnicodeCharacter{0106}{\'C} + \DeclareUnicodeCharacter{0107}{\'c} + \DeclareUnicodeCharacter{0108}{\^C} + \DeclareUnicodeCharacter{0109}{\^c} + \DeclareUnicodeCharacter{0118}{\ogonek{E}} + \DeclareUnicodeCharacter{0119}{\ogonek{e}} + \DeclareUnicodeCharacter{010A}{\dotaccent{C}} + \DeclareUnicodeCharacter{010B}{\dotaccent{c}} + \DeclareUnicodeCharacter{010C}{\v{C}} + \DeclareUnicodeCharacter{010D}{\v{c}} + \DeclareUnicodeCharacter{010E}{\v{D}} + + \DeclareUnicodeCharacter{0112}{\=E} + \DeclareUnicodeCharacter{0113}{\=e} + \DeclareUnicodeCharacter{0114}{\u{E}} + \DeclareUnicodeCharacter{0115}{\u{e}} + \DeclareUnicodeCharacter{0116}{\dotaccent{E}} + \DeclareUnicodeCharacter{0117}{\dotaccent{e}} + \DeclareUnicodeCharacter{011A}{\v{E}} + \DeclareUnicodeCharacter{011B}{\v{e}} + \DeclareUnicodeCharacter{011C}{\^G} + \DeclareUnicodeCharacter{011D}{\^g} + \DeclareUnicodeCharacter{011E}{\u{G}} + \DeclareUnicodeCharacter{011F}{\u{g}} + + \DeclareUnicodeCharacter{0120}{\dotaccent{G}} + \DeclareUnicodeCharacter{0121}{\dotaccent{g}} + \DeclareUnicodeCharacter{0124}{\^H} + \DeclareUnicodeCharacter{0125}{\^h} + \DeclareUnicodeCharacter{0128}{\~I} + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} + \DeclareUnicodeCharacter{012A}{\=I} + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} + \DeclareUnicodeCharacter{012C}{\u{I}} + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} + + \DeclareUnicodeCharacter{0130}{\dotaccent{I}} + \DeclareUnicodeCharacter{0131}{\dotless{i}} + \DeclareUnicodeCharacter{0132}{IJ} + \DeclareUnicodeCharacter{0133}{ij} + \DeclareUnicodeCharacter{0134}{\^J} + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} + \DeclareUnicodeCharacter{0139}{\'L} + \DeclareUnicodeCharacter{013A}{\'l} + + \DeclareUnicodeCharacter{0141}{\L} + \DeclareUnicodeCharacter{0142}{\l} + \DeclareUnicodeCharacter{0143}{\'N} + \DeclareUnicodeCharacter{0144}{\'n} + \DeclareUnicodeCharacter{0147}{\v{N}} + \DeclareUnicodeCharacter{0148}{\v{n}} + \DeclareUnicodeCharacter{014C}{\=O} + \DeclareUnicodeCharacter{014D}{\=o} + \DeclareUnicodeCharacter{014E}{\u{O}} + \DeclareUnicodeCharacter{014F}{\u{o}} + + \DeclareUnicodeCharacter{0150}{\H{O}} + \DeclareUnicodeCharacter{0151}{\H{o}} + \DeclareUnicodeCharacter{0152}{\OE} + \DeclareUnicodeCharacter{0153}{\oe} + \DeclareUnicodeCharacter{0154}{\'R} + \DeclareUnicodeCharacter{0155}{\'r} + \DeclareUnicodeCharacter{0158}{\v{R}} + \DeclareUnicodeCharacter{0159}{\v{r}} + \DeclareUnicodeCharacter{015A}{\'S} + \DeclareUnicodeCharacter{015B}{\'s} + \DeclareUnicodeCharacter{015C}{\^S} + \DeclareUnicodeCharacter{015D}{\^s} + \DeclareUnicodeCharacter{015E}{\cedilla{S}} + \DeclareUnicodeCharacter{015F}{\cedilla{s}} + + \DeclareUnicodeCharacter{0160}{\v{S}} + \DeclareUnicodeCharacter{0161}{\v{s}} + \DeclareUnicodeCharacter{0162}{\cedilla{t}} + \DeclareUnicodeCharacter{0163}{\cedilla{T}} + \DeclareUnicodeCharacter{0164}{\v{T}} + + \DeclareUnicodeCharacter{0168}{\~U} + \DeclareUnicodeCharacter{0169}{\~u} + \DeclareUnicodeCharacter{016A}{\=U} + \DeclareUnicodeCharacter{016B}{\=u} + \DeclareUnicodeCharacter{016C}{\u{U}} + \DeclareUnicodeCharacter{016D}{\u{u}} + \DeclareUnicodeCharacter{016E}{\ringaccent{U}} + \DeclareUnicodeCharacter{016F}{\ringaccent{u}} + + \DeclareUnicodeCharacter{0170}{\H{U}} + \DeclareUnicodeCharacter{0171}{\H{u}} + \DeclareUnicodeCharacter{0174}{\^W} + \DeclareUnicodeCharacter{0175}{\^w} + \DeclareUnicodeCharacter{0176}{\^Y} + \DeclareUnicodeCharacter{0177}{\^y} + \DeclareUnicodeCharacter{0178}{\"Y} + \DeclareUnicodeCharacter{0179}{\'Z} + \DeclareUnicodeCharacter{017A}{\'z} + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} + \DeclareUnicodeCharacter{017C}{\dotaccent{z}} + \DeclareUnicodeCharacter{017D}{\v{Z}} + \DeclareUnicodeCharacter{017E}{\v{z}} + + \DeclareUnicodeCharacter{01C4}{D\v{Z}} + \DeclareUnicodeCharacter{01C5}{D\v{z}} + \DeclareUnicodeCharacter{01C6}{d\v{z}} + \DeclareUnicodeCharacter{01C7}{LJ} + \DeclareUnicodeCharacter{01C8}{Lj} + \DeclareUnicodeCharacter{01C9}{lj} + \DeclareUnicodeCharacter{01CA}{NJ} + \DeclareUnicodeCharacter{01CB}{Nj} + \DeclareUnicodeCharacter{01CC}{nj} + \DeclareUnicodeCharacter{01CD}{\v{A}} + \DeclareUnicodeCharacter{01CE}{\v{a}} + \DeclareUnicodeCharacter{01CF}{\v{I}} + + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} + \DeclareUnicodeCharacter{01D1}{\v{O}} + \DeclareUnicodeCharacter{01D2}{\v{o}} + \DeclareUnicodeCharacter{01D3}{\v{U}} + \DeclareUnicodeCharacter{01D4}{\v{u}} + + \DeclareUnicodeCharacter{01E2}{\={\AE}} + \DeclareUnicodeCharacter{01E3}{\={\ae}} + \DeclareUnicodeCharacter{01E6}{\v{G}} + \DeclareUnicodeCharacter{01E7}{\v{g}} + \DeclareUnicodeCharacter{01E8}{\v{K}} + \DeclareUnicodeCharacter{01E9}{\v{k}} + + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} + \DeclareUnicodeCharacter{01F1}{DZ} + \DeclareUnicodeCharacter{01F2}{Dz} + \DeclareUnicodeCharacter{01F3}{dz} + \DeclareUnicodeCharacter{01F4}{\'G} + \DeclareUnicodeCharacter{01F5}{\'g} + \DeclareUnicodeCharacter{01F8}{\`N} + \DeclareUnicodeCharacter{01F9}{\`n} + \DeclareUnicodeCharacter{01FC}{\'{\AE}} + \DeclareUnicodeCharacter{01FD}{\'{\ae}} + \DeclareUnicodeCharacter{01FE}{\'{\O}} + \DeclareUnicodeCharacter{01FF}{\'{\o}} + + \DeclareUnicodeCharacter{021E}{\v{H}} + \DeclareUnicodeCharacter{021F}{\v{h}} + + \DeclareUnicodeCharacter{0226}{\dotaccent{A}} + \DeclareUnicodeCharacter{0227}{\dotaccent{a}} + \DeclareUnicodeCharacter{0228}{\cedilla{E}} + \DeclareUnicodeCharacter{0229}{\cedilla{e}} + \DeclareUnicodeCharacter{022E}{\dotaccent{O}} + \DeclareUnicodeCharacter{022F}{\dotaccent{o}} + + \DeclareUnicodeCharacter{0232}{\=Y} + \DeclareUnicodeCharacter{0233}{\=y} + \DeclareUnicodeCharacter{0237}{\dotless{j}} + + \DeclareUnicodeCharacter{02DB}{\ogonek{ }} + + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} + + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} + + \DeclareUnicodeCharacter{1E20}{\=G} + \DeclareUnicodeCharacter{1E21}{\=g} + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} + \DeclareUnicodeCharacter{1E26}{\"H} + \DeclareUnicodeCharacter{1E27}{\"h} + + \DeclareUnicodeCharacter{1E30}{\'K} + \DeclareUnicodeCharacter{1E31}{\'k} + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} + \DeclareUnicodeCharacter{1E3E}{\'M} + \DeclareUnicodeCharacter{1E3F}{\'m} + + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} + + \DeclareUnicodeCharacter{1E54}{\'P} + \DeclareUnicodeCharacter{1E55}{\'p} + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} + + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} + + \DeclareUnicodeCharacter{1E7C}{\~V} + \DeclareUnicodeCharacter{1E7D}{\~v} + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} + + \DeclareUnicodeCharacter{1E80}{\`W} + \DeclareUnicodeCharacter{1E81}{\`w} + \DeclareUnicodeCharacter{1E82}{\'W} + \DeclareUnicodeCharacter{1E83}{\'w} + \DeclareUnicodeCharacter{1E84}{\"W} + \DeclareUnicodeCharacter{1E85}{\"w} + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} + \DeclareUnicodeCharacter{1E8C}{\"X} + \DeclareUnicodeCharacter{1E8D}{\"x} + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} + + \DeclareUnicodeCharacter{1E90}{\^Z} + \DeclareUnicodeCharacter{1E91}{\^z} + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} + \DeclareUnicodeCharacter{1E97}{\"t} + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} + + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} + + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} + \DeclareUnicodeCharacter{1EBC}{\~E} + \DeclareUnicodeCharacter{1EBD}{\~e} + + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} + + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} + + \DeclareUnicodeCharacter{1EF2}{\`Y} + \DeclareUnicodeCharacter{1EF3}{\`y} + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} + + \DeclareUnicodeCharacter{1EF8}{\~Y} + \DeclareUnicodeCharacter{1EF9}{\~y} + + \DeclareUnicodeCharacter{2013}{--} + \DeclareUnicodeCharacter{2014}{---} + \DeclareUnicodeCharacter{2018}{\quoteleft} + \DeclareUnicodeCharacter{2019}{\quoteright} + \DeclareUnicodeCharacter{201A}{\quotesinglbase} + \DeclareUnicodeCharacter{201C}{\quotedblleft} + \DeclareUnicodeCharacter{201D}{\quotedblright} + \DeclareUnicodeCharacter{201E}{\quotedblbase} + \DeclareUnicodeCharacter{2022}{\bullet} + \DeclareUnicodeCharacter{2026}{\dots} + \DeclareUnicodeCharacter{2039}{\guilsinglleft} + \DeclareUnicodeCharacter{203A}{\guilsinglright} + \DeclareUnicodeCharacter{20AC}{\euro} + + \DeclareUnicodeCharacter{2192}{\expansion} + \DeclareUnicodeCharacter{21D2}{\result} + + \DeclareUnicodeCharacter{2212}{\minus} + \DeclareUnicodeCharacter{2217}{\point} + \DeclareUnicodeCharacter{2261}{\equiv} +}% end of \utfeightchardefs + + +% US-ASCII character definitions. +\def\asciichardefs{% nothing need be done + \relax +} + +% Make non-ASCII characters printable again for compatibility with +% existing Texinfo documents that may use them, even without declaring a +% document encoding. +% +\setnonasciicharscatcode \other + + +\message{formatting,} + +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be very finicky about underfull hboxes, either. +\hbadness = 6666 + +% Following George Bush, get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; +% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; +% 7) physical page height; 8) physical page width. +% +% We also call \setleading{\textleading}, so the caller should define +% \textleading. The caller should also set \parskip. +% +\def\internalpagesizes#1#2#3#4#5#6#7#8{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \ifpdf + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % if we don't reset these, they will remain at "1 true in" of + % whatever layout pdftex was dumped with. + \pdfhorigin = 1 true in + \pdfvorigin = 1 true in + \fi + % + \setleading{\textleading} + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % If page is nothing but text, make it come out even. + \internalpagesizes{607.2pt}{6in}% that's 46 lines + {\voffset}{.25in}% + {\bindingoffset}{36pt}% + {11in}{8.5in}% +}} + +% Use @smallbook to reset parameters for 7x9.25 trim size. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.5in}{5in}% + {-.2in}{0in}% + {\bindingoffset}{16pt}% + {9.25in}{7in}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .5cm +}} + +% Use @smallerbook to reset parameters for 6x9 trim size. +% (Just testing, parameters still in flux.) +\def\smallerbook{{\globaldefs = 1 + \parskip = 1.5pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.4in}{4.8in}% + {-.2in}{-.4in}% + {0pt}{14pt}% + {9in}{6in}% + % + \lispnarrowing = 0.25in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .4cm +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % Double-side printing via postscript on Laserjet 4050 + % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. + % To change the settings for a different printer or situation, adjust + % \normaloffset until the front-side and back-side texts align. Then + % do the same for \bindingoffset. You can set these for testing in + % your texinfo source file like this: + % @tex + % \global\normaloffset = -6mm + % \global\bindingoffset = 10mm + % @end tex + \internalpagesizes{673.2pt}{160mm}% that's 51 lines + {\voffset}{\hoffset}% + {\bindingoffset}{44pt}% + {297mm}{210mm}% + % + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = 5mm +}} + +% Use @afivepaper to print on European A5 paper. +% From romildo@urano.iceb.ufop.br, 2 July 2000. +% He also recommends making @example and @lisp be small. +\def\afivepaper{{\globaldefs = 1 + \parskip = 2pt plus 1pt minus 0.1pt + \textleading = 12.5pt + % + \internalpagesizes{160mm}{120mm}% + {\voffset}{\hoffset}% + {\bindingoffset}{8pt}% + {210mm}{148mm}% + % + \lispnarrowing = 0.2in + \tolerance = 800 + \hfuzz = 1.2pt + \contentsrightmargin = 0pt + \defbodyindent = 2mm + \tableindent = 12mm +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. +\def\afourlatex{{\globaldefs = 1 + \afourpaper + \internalpagesizes{237mm}{150mm}% + {\voffset}{4.6mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + % + % Must explicitly reset to 0 because we call \afourpaper. + \globaldefs = 0 +}} + +% Use @afourwide to print on A4 paper in landscape format. +\def\afourwide{{\globaldefs = 1 + \afourpaper + \internalpagesizes{241mm}{165mm}% + {\voffset}{-2.95mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + \globaldefs = 0 +}} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{\textleading}% + % + \dimen0 = #1\relax + \advance\dimen0 by \voffset + % + \dimen2 = \hsize + \advance\dimen2 by \normaloffset + % + \internalpagesizes{#1}{\hsize}% + {\voffset}{\normaloffset}% + {\bindingoffset}{44pt}% + {\dimen0}{\dimen2}% +}} + +% Set default to letter. +% +\letterpaper + + +\message{and turning on texinfo input format.} + +\def^^L{\par} % remove \outer, so ^L can appear in an @comment + +% DEL is a comment character, in case @c does not suffice. +\catcode`\^^? = 14 + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other \def\normaldoublequote{"} +\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix +\catcode`\+=\other \def\normalplus{+} +\catcode`\<=\other \def\normalless{<} +\catcode`\>=\other \def\normalgreater{>} +\catcode`\^=\other \def\normalcaret{^} +\catcode`\_=\other \def\normalunderscore{_} +\catcode`\|=\other \def\normalverticalbar{|} +\catcode`\~=\other \def\normaltilde{~} + +% This macro is used to make a character print one way in \tt +% (where it can probably be output as-is), and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +\let\realunder=_ +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } + +\catcode`\|=\active +\def|{{\tt\char124}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +\catcode`\$=\active +\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +% Used sometimes to turn off (effectively) the active characters even after +% parsing them. +\def\turnoffactive{% + \normalturnoffactive + \otherbackslash +} + +\catcode`\@=0 + +% \backslashcurfont outputs one backslash character in current font, +% as in \char`\\. +\global\chardef\backslashcurfont=`\\ +\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work + +% \realbackslash is an actual character `\' with catcode other, and +% \doublebackslash is two of them (for the pdf outlines). +{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} + +% In texinfo, backslash is an active character; it prints the backslash +% in fixed width font. +\catcode`\\=\active % @ for escape char from now on. + +% The story here is that in math mode, the \char of \backslashcurfont +% ends up printing the roman \ from the math symbol font (because \char +% in math mode uses the \mathcode, and plain.tex sets +% \mathcode`\\="026E). It seems better for @backslashchar{} to always +% print a typewriter backslash, hence we use an explicit \mathchar, +% which is the decimal equivalent of "715c (class 7, e.g., use \fam; +% ignored family value; char position "5C). We can't use " for the +% usual hex value because it has already been made active. +@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents. + +% On startup, @fixbackslash assigns: +% @let \ = @normalbackslash +% \rawbackslash defines an active \ to do \backslashcurfont. +% \otherbackslash defines an active \ to be a literal `\' character with +% catcode other. We switch back and forth between these. +@gdef@rawbackslash{@let\=@backslashcurfont} +@gdef@otherbackslash{@let\=@realbackslash} + +% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +% the literal character `\'. Also revert - to its normal character, in +% case the active - from code has slipped in. +% +{@catcode`- = @active + @gdef@normalturnoffactive{% + @let-=@normaldash + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let\=@normalbackslash + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces + } +} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\' in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also turn back on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active + @catcode`@_=@active +} + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These (along with & and #) are made active for url-breaking, so need +% active definitions as the normal characters. +@def@normaldot{.} +@def@normalquest{?} +@def@normalslash{/} + +% These look ok in all fonts, so just make them not special. +% @hashchar{} gets its own user-level command, because of #line. +@catcode`@& = @other @def@normalamp{&} +@catcode`@# = @other @def@normalhash{#} +@catcode`@% = @other @def@normalpercent{%} + +@let @hashchar = @normalhash + +@c Finally, make ` and ' active, so that txicodequoteundirected and +@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we +@c don't make ` and ' active, @code will not get them as active chars. +@c Do this last of all since we use ` in the previous @catcode assignments. +@catcode`@'=@active +@catcode`@`=@active +@markupsetuplqdefault +@markupsetuprqdefault + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: + +@c vim:sw=2: + +@ignore + arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 +@end ignore diff --git a/circuitpython/lib/libm/acoshf.c b/circuitpython/lib/libm/acoshf.c new file mode 100644 index 0000000..8a8409f --- /dev/null +++ b/circuitpython/lib/libm/acoshf.c @@ -0,0 +1,32 @@ +/*****************************************************************************/ +/*****************************************************************************/ +// acoshf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +#include "libm.h" + +#if FLT_EVAL_METHOD==2 +#undef sqrtf +#define sqrtf sqrtl +#elif FLT_EVAL_METHOD==1 +#undef sqrtf +#define sqrtf sqrt +#endif + +/* acosh(x) = log(x + sqrt(x*x-1)) */ +float acoshf(float x) +{ + union {float f; uint32_t i;} u = {x}; + uint32_t a = u.i & 0x7fffffff; + + if (a < 0x3f800000+(1<<23)) + /* |x| < 2, invalid if x < 1 or nan */ + /* up to 2ulp error in [1,1.125] */ + return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1))); + if (a < 0x3f800000+(12<<23)) + /* |x| < 0x1p12 */ + return logf(2*x - 1/(x+sqrtf(x*x-1))); + /* x >= 0x1p12 */ + return logf(x) + 0.693147180559945309417232121458176568f; +} diff --git a/circuitpython/lib/libm/asinfacosf.c b/circuitpython/lib/libm/asinfacosf.c new file mode 100644 index 0000000..22dbb3d --- /dev/null +++ b/circuitpython/lib/libm/asinfacosf.c @@ -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+00f, /* 0x3fc90fda */ +pio2_lo = 7.5497894159e-08f; /* 0x33a22168 */ + +static const float +/* coefficients for R(x^2) */ +pS0 = 1.6666586697e-01f, +pS1 = -4.2743422091e-02f, +pS2 = -8.6563630030e-03f, +qS1 = -7.0662963390e-01f; + +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); +} diff --git a/circuitpython/lib/libm/asinhf.c b/circuitpython/lib/libm/asinhf.c new file mode 100644 index 0000000..4bcb3f9 --- /dev/null +++ b/circuitpython/lib/libm/asinhf.c @@ -0,0 +1,34 @@ +/*****************************************************************************/ +/*****************************************************************************/ +// asinhf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +#include "libm.h" + +/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */ +float asinhf(float x) +{ + union {float f; uint32_t i;} u = {.f = x}; + uint32_t i = u.i & 0x7fffffff; + unsigned s = u.i >> 31; + + /* |x| */ + u.i = i; + x = u.f; + + if (i >= 0x3f800000 + (12<<23)) { + /* |x| >= 0x1p12 or inf or nan */ + x = logf(x) + 0.693147180559945309417232121458176568f; + } else if (i >= 0x3f800000 + (1<<23)) { + /* |x| >= 2 */ + x = logf(2*x + 1/(sqrtf(x*x+1)+x)); + } else if (i >= 0x3f800000 - (12<<23)) { + /* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */ + x = log1pf(x + x*x/(sqrtf(x*x+1)+1)); + } else { + /* |x| < 0x1p-12, raise inexact if x!=0 */ + FORCE_EVAL(x + 0x1p120f); + } + return s ? -x : x; +} diff --git a/circuitpython/lib/libm/atan2f.c b/circuitpython/lib/libm/atan2f.c new file mode 100644 index 0000000..dcbaf82 --- /dev/null +++ b/circuitpython/lib/libm/atan2f.c @@ -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+00f, /* 0x40490fdb */ +pi_lo = -8.7422776573e-08f; /* 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(-,-) */ + } +} diff --git a/circuitpython/lib/libm/atanf.c b/circuitpython/lib/libm/atanf.c new file mode 100644 index 0000000..40bc363 --- /dev/null +++ b/circuitpython/lib/libm/atanf.c @@ -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-01f, /* atan(0.5)hi 0x3eed6338 */ + 7.8539812565e-01f, /* atan(1.0)hi 0x3f490fda */ + 9.8279368877e-01f, /* atan(1.5)hi 0x3f7b985e */ + 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ +}; + +static const float atanlo[] = { + 5.0121582440e-09f, /* atan(0.5)lo 0x31ac3769 */ + 3.7748947079e-08f, /* atan(1.0)lo 0x33222168 */ + 3.4473217170e-08f, /* atan(1.5)lo 0x33140fb4 */ + 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ +}; + +static const float aT[] = { + 3.3333328366e-01f, + -1.9999158382e-01f, + 1.4253635705e-01f, + -1.0648017377e-01f, + 6.1687607318e-02f, +}; + +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; +} diff --git a/circuitpython/lib/libm/atanhf.c b/circuitpython/lib/libm/atanhf.c new file mode 100644 index 0000000..6f95f49 --- /dev/null +++ b/circuitpython/lib/libm/atanhf.c @@ -0,0 +1,34 @@ +/*****************************************************************************/ +/*****************************************************************************/ +// atanhf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +#include "libm.h" + +/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */ +float atanhf(float x) +{ + union {float f; uint32_t i;} u = {.f = x}; + unsigned s = u.i >> 31; + float_t y; + + /* |x| */ + u.i &= 0x7fffffff; + y = u.f; + + if (u.i < 0x3f800000 - (1<<23)) { + if (u.i < 0x3f800000 - (32<<23)) { + /* handle underflow */ + if (u.i < (1<<23)) + FORCE_EVAL((float)(y*y)); + } else { + /* |x| < 0.5, up to 1.7ulp error */ + y = 0.5f*log1pf(2*y + 2*y*y/(1-y)); + } + } else { + /* avoid overflow */ + y = 0.5f*log1pf(2*(y/(1-y))); + } + return s ? -y : y; +} diff --git a/circuitpython/lib/libm/ef_rem_pio2.c b/circuitpython/lib/libm/ef_rem_pio2.c new file mode 100644 index 0000000..386c6fd --- /dev/null +++ b/circuitpython/lib/libm/ef_rem_pio2.c @@ -0,0 +1,211 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* ef_rem_pio2.c -- float version of e_rem_pio2.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2f() + */ + +#include "fdlibm.h" + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +#ifdef __STDC__ +static const __uint8_t two_over_pi[] = { +#else +static __uint8_t two_over_pi[] = { +#endif +0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC, +0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62, +0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63, +0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A, +0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09, +0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29, +0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44, +0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41, +0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C, +0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8, +0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11, +0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF, +0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E, +0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5, +0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92, +0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08, +0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0, +0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3, +0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85, +0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80, +0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA, +0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B, +}; + +/* This array is like the one in e_rem_pio2.c, but the numbers are + single precision and the last 8 bits are forced to 0. */ +#ifdef __STDC__ +static const __int32_t npio2_hw[] = { +#else +static __int32_t npio2_hw[] = { +#endif +0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, +0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, +0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, +0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, +0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, +0x4242c700, 0x42490f00 +}; + +/* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const float +#else +static float +#endif +zero = 0.0000000000e+00f, /* 0x00000000 */ +half = 5.0000000000e-01f, /* 0x3f000000 */ +two8 = 2.5600000000e+02f, /* 0x43800000 */ +invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ +pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ +pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ +pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ +pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ +pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ +pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ + +#ifdef __STDC__ + __int32_t __ieee754_rem_pio2f(float x, float *y) +#else + __int32_t __ieee754_rem_pio2f(x,y) + float x,y[]; +#endif +{ + float z,w,t,r,fn; + float tx[3]; + __int32_t i,j,n,ix,hx; + int e0,nx; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z - pio2_1t; + y[1] = (z-y[0])-pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z-y[0])-pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z + pio2_1t; + y[1] = (z-y[0])+pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z-y[0])+pio2_2t; + } + return -1; + } + } +#if CIRCUITPY_FULL_BUILD + if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (__int32_t) (t*invpio2+half); + fn = (float)n; + r = t-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 40 bit */ + if(n<32&&(__int32_t)(ix&0xffffff00)!=npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + __uint32_t high; + j = ix>>23; + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>25) { /* 3rd iteration need, 74 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } +#else + // Suppress "defined but not used" diagnostics + (void) j; (void) fn; (void) r; (void) t; (void) w; (void) pio2_3t; + (void) pio2_3; (void) invpio2; (void)half; (void)npio2_hw; +#endif + /* + * all other (large) arguments + */ + if(!FLT_UWORD_IS_FINITE(ix)) { + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-7) */ + e0 = (int)((ix>>23)-134); /* e0 = ilogb(z)-7; */ + SET_FLOAT_WORD(z, ix - ((__int32_t)e0<<23)); + for(i=0;i<2;i++) { + tx[i] = (float)((__int32_t)(z)); + z = (z-tx[i])*two8; + } + tx[2] = z; + nx = 3; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + while(tx[nx-1]==zero) nx--; /* skip zero term */ +#pragma GCC diagnostic pop + n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi); + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + return n; +} diff --git a/circuitpython/lib/libm/ef_sqrt.c b/circuitpython/lib/libm/ef_sqrt.c new file mode 100644 index 0000000..2c1ae6f --- /dev/null +++ b/circuitpython/lib/libm/ef_sqrt.c @@ -0,0 +1,102 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* ef_sqrtf.c -- float version of e_sqrt.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float one = 1.0f, tiny=1.0e-30f; +#else +static float one = 1.0f, tiny=1.0e-30f; +#endif + +// sqrtf is exactly __ieee754_sqrtf when _IEEE_LIBM defined +float sqrtf(float x) +/* +#ifdef __STDC__ + float __ieee754_sqrtf(float x) +#else + float __ieee754_sqrtf(x) + float x; +#endif +*/ +{ + float z; + __uint32_t r,hx; + __int32_t ix,s,q,m,t,i; + + GET_FLOAT_WORD(ix,x); + hx = ix&0x7fffffff; + + /* take care of Inf and NaN */ + if(!FLT_UWORD_IS_FINITE(hx)) + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + /* take care of zero and -ves */ + if(FLT_UWORD_IS_ZERO(hx)) return x;/* sqrt(+-0) = +-0 */ + if(ix<0) return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + + /* normalize x */ + m = (ix>>23); + if(FLT_UWORD_IS_SUBNORMAL(hx)) { /* subnormal x */ + for(i=0;(ix&0x00800000L)==0;i++) ix<<=1; + m -= i-1; + } + m -= 127; /* unbias exponent */ + ix = (ix&0x007fffffL)|0x00800000L; + if(m&1) /* odd m, double x to make it even */ + ix += ix; + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix += ix; + q = s = 0; /* q = sqrt(x) */ + r = 0x01000000L; /* r = moving bit from right to left */ + + while(r!=0) { + t = s+r; + if(t<=ix) { + s = t+r; + ix -= t; + q += r; + } + ix += ix; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if(ix!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (z>one) + q += 2; + else + q += (q&1); + } + } + ix = (q>>1)+0x3f000000L; + ix += (m <<23); + SET_FLOAT_WORD(z,ix); + return z; +} diff --git a/circuitpython/lib/libm/erf_lgamma.c b/circuitpython/lib/libm/erf_lgamma.c new file mode 100644 index 0000000..6d675f1 --- /dev/null +++ b/circuitpython/lib/libm/erf_lgamma.c @@ -0,0 +1,256 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* erf_lgamma.c -- float version of er_lgamma.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +#include "fdlibm.h" +#pragma GCC diagnostic ignored "-Wfloat-equal" + +#define __ieee754_logf logf + +#ifdef __STDC__ +static const float +#else +static float +#endif +two23= 8.3886080000e+06f, /* 0x4b000000 */ +half= 5.0000000000e-01f, /* 0x3f000000 */ +one = 1.0000000000e+00f, /* 0x3f800000 */ +pi = 3.1415927410e+00f, /* 0x40490fdb */ +a0 = 7.7215664089e-02f, /* 0x3d9e233f */ +a1 = 3.2246702909e-01f, /* 0x3ea51a66 */ +a2 = 6.7352302372e-02f, /* 0x3d89f001 */ +a3 = 2.0580807701e-02f, /* 0x3ca89915 */ +a4 = 7.3855509982e-03f, /* 0x3bf2027e */ +a5 = 2.8905137442e-03f, /* 0x3b3d6ec6 */ +a6 = 1.1927076848e-03f, /* 0x3a9c54a1 */ +a7 = 5.1006977446e-04f, /* 0x3a05b634 */ +a8 = 2.2086278477e-04f, /* 0x39679767 */ +a9 = 1.0801156895e-04f, /* 0x38e28445 */ +a10 = 2.5214456400e-05f, /* 0x37d383a2 */ +a11 = 4.4864096708e-05f, /* 0x383c2c75 */ +tc = 1.4616321325e+00f, /* 0x3fbb16c3 */ +tf = -1.2148628384e-01f, /* 0xbdf8cdcd */ +/* tt = -(tail of tf) */ +tt = 6.6971006518e-09f, /* 0x31e61c52 */ +t0 = 4.8383611441e-01f, /* 0x3ef7b95e */ +t1 = -1.4758771658e-01f, /* 0xbe17213c */ +t2 = 6.4624942839e-02f, /* 0x3d845a15 */ +t3 = -3.2788541168e-02f, /* 0xbd064d47 */ +t4 = 1.7970675603e-02f, /* 0x3c93373d */ +t5 = -1.0314224288e-02f, /* 0xbc28fcfe */ +t6 = 6.1005386524e-03f, /* 0x3bc7e707 */ +t7 = -3.6845202558e-03f, /* 0xbb7177fe */ +t8 = 2.2596477065e-03f, /* 0x3b141699 */ +t9 = -1.4034647029e-03f, /* 0xbab7f476 */ +t10 = 8.8108185446e-04f, /* 0x3a66f867 */ +t11 = -5.3859531181e-04f, /* 0xba0d3085 */ +t12 = 3.1563205994e-04f, /* 0x39a57b6b */ +t13 = -3.1275415677e-04f, /* 0xb9a3f927 */ +t14 = 3.3552918467e-04f, /* 0x39afe9f7 */ +u0 = -7.7215664089e-02f, /* 0xbd9e233f */ +u1 = 6.3282704353e-01f, /* 0x3f2200f4 */ +u2 = 1.4549225569e+00f, /* 0x3fba3ae7 */ +u3 = 9.7771751881e-01f, /* 0x3f7a4bb2 */ +u4 = 2.2896373272e-01f, /* 0x3e6a7578 */ +u5 = 1.3381091878e-02f, /* 0x3c5b3c5e */ +v1 = 2.4559779167e+00f, /* 0x401d2ebe */ +v2 = 2.1284897327e+00f, /* 0x4008392d */ +v3 = 7.6928514242e-01f, /* 0x3f44efdf */ +v4 = 1.0422264785e-01f, /* 0x3dd572af */ +v5 = 3.2170924824e-03f, /* 0x3b52d5db */ +s0 = -7.7215664089e-02f, /* 0xbd9e233f */ +s1 = 2.1498242021e-01f, /* 0x3e5c245a */ +s2 = 3.2577878237e-01f, /* 0x3ea6cc7a */ +s3 = 1.4635047317e-01f, /* 0x3e15dce6 */ +s4 = 2.6642270386e-02f, /* 0x3cda40e4 */ +s5 = 1.8402845599e-03f, /* 0x3af135b4 */ +s6 = 3.1947532989e-05f, /* 0x3805ff67 */ +r1 = 1.3920053244e+00f, /* 0x3fb22d3b */ +r2 = 7.2193557024e-01f, /* 0x3f38d0c5 */ +r3 = 1.7193385959e-01f, /* 0x3e300f6e */ +r4 = 1.8645919859e-02f, /* 0x3c98bf54 */ +r5 = 7.7794247773e-04f, /* 0x3a4beed6 */ +r6 = 7.3266842264e-06f, /* 0x36f5d7bd */ +w0 = 4.1893854737e-01f, /* 0x3ed67f1d */ +w1 = 8.3333335817e-02f, /* 0x3daaaaab */ +w2 = -2.7777778450e-03f, /* 0xbb360b61 */ +w3 = 7.9365057172e-04f, /* 0x3a500cfd */ +w4 = -5.9518753551e-04f, /* 0xba1c065c */ +w5 = 8.3633989561e-04f, /* 0x3a5b3dd2 */ +w6 = -1.6309292987e-03f; /* 0xbad5c4e8 */ + +#ifdef __STDC__ +static const float zero= 0.0000000000e+00f; +#else +static float zero= 0.0000000000e+00f; +#endif + +#ifdef __STDC__ + static float sin_pif(float x) +#else + static float sin_pif(x) + float x; +#endif +{ + float y,z; + __int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + + if(ix<0x3e800000) return __kernel_sinf(pi*x,zero,0); + y = -x; /* x is assume negative */ + + /* + * argument reduction, make sure inexact flag not raised if input + * is an integer + */ + z = floorf(y); + if(z!=y) { /* inexact anyway */ + y *= (float)0.5; + y = (float)2.0*(y - floorf(y)); /* y = |x| mod 2.0 */ + n = (__int32_t) (y*(float)4.0); + } else { + if(ix>=0x4b800000) { + y = zero; n = 0; /* y must be even */ + } else { + if(ix<0x4b000000) z = y+two23; /* exact */ + GET_FLOAT_WORD(n,z); + n &= 1; + y = n; + n<<= 2; + } + } + switch (n) { + case 0: y = __kernel_sinf(pi*y,zero,0); break; + case 1: + case 2: y = __kernel_cosf(pi*((float)0.5-y),zero); break; + case 3: + case 4: y = __kernel_sinf(pi*(one-y),zero,0); break; + case 5: + case 6: y = -__kernel_cosf(pi*(y-(float)1.5),zero); break; + default: y = __kernel_sinf(pi*(y-(float)2.0),zero,0); break; + } + return -y; +} + + +#ifdef __STDC__ + float __ieee754_lgammaf_r(float x, int *signgamp) +#else + float __ieee754_lgammaf_r(x,signgamp) + float x; int *signgamp; +#endif +{ + float t,y,z,nadj = 0.0,p,p1,p2,p3,q,r,w; + __int32_t i,hx,ix; + + GET_FLOAT_WORD(hx,x); + + /* purge off +-inf, NaN, +-0, and negative arguments */ + *signgamp = 1; + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return x*x; + if(ix==0) return one/zero; + if(ix<0x1c800000) { /* |x|<2**-70, return -log(|x|) */ + if(hx<0) { + *signgamp = -1; + return -__ieee754_logf(-x); + } else return -__ieee754_logf(x); + } + if(hx<0) { + if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */ + return one/zero; + t = sin_pif(x); + if(t==zero) return one/zero; /* -integer */ + nadj = __ieee754_logf(pi/fabsf(t*x)); + if(t=0x3f3b4a20) {y = one-x; i= 0;} + else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;} + else {y = x; i=2;} + } else { + r = zero; + if(ix>=0x3fdda618) {y=(float)2.0-x;i=0;} /* [1.7316,2] */ + else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23,1.73] */ + else {y=x-one;i=2;} + } + switch(i) { + case 0: + z = y*y; + p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); + p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); + p = y*p1+p2; + r += (p-(float)0.5*y); break; + case 1: + z = y*y; + w = z*y; + p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ + p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); + p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); + p = z*p1-(tt-w*(p2+y*p3)); + r += (tf + p); break; + case 2: + p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); + p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); + r += (-(float)0.5*y + p1/p2); + } + } + else if(ix<0x41000000) { /* x < 8.0 */ + i = (__int32_t)x; + t = zero; + y = x-(float)i; + p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); + q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); + r = half*y+p/q; + z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch(i) { + case 7: z *= (y+(float)6.0); /* FALLTHRU */ + case 6: z *= (y+(float)5.0); /* FALLTHRU */ + case 5: z *= (y+(float)4.0); /* FALLTHRU */ + case 4: z *= (y+(float)3.0); /* FALLTHRU */ + case 3: z *= (y+(float)2.0); /* FALLTHRU */ + r += __ieee754_logf(z); break; + } + /* 8.0 <= x < 2**58 */ + } else if (ix < 0x5c800000) { + t = __ieee754_logf(x); + z = one/x; + y = z*z; + w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); + r = (x-half)*(t-one)+w; + } else + /* 2**58 <= x <= inf */ + r = x*(__ieee754_logf(x)-one); + if(hx<0) r = nadj - r; + return r; +} diff --git a/circuitpython/lib/libm/fdlibm.h b/circuitpython/lib/libm/fdlibm.h new file mode 100644 index 0000000..91698a6 --- /dev/null +++ b/circuitpython/lib/libm/fdlibm.h @@ -0,0 +1,227 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * This file is adapted from from newlib-nano-2, the newlib/libm/common/fdlib.h, + * available from https://github.com/32bitmicro/newlib-nano-2. The main change + * is removal of anything to do with double precision. + * + * Appropriate copyright headers are reproduced below. + */ + +/* @(#)fdlibm.h 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include + +/* Default to XOPEN_MODE. */ +#define _XOPEN_MODE + +/* Most routines need to check whether a float is finite, infinite, or not a + number, and many need to know whether the result of an operation will + overflow. These conditions depend on whether the largest exponent is + used for NaNs & infinities, or whether it's used for finite numbers. The + macros below wrap up that kind of information: + + FLT_UWORD_IS_FINITE(X) + True if a positive float with bitmask X is finite. + + FLT_UWORD_IS_NAN(X) + True if a positive float with bitmask X is not a number. + + FLT_UWORD_IS_INFINITE(X) + True if a positive float with bitmask X is +infinity. + + FLT_UWORD_MAX + The bitmask of FLT_MAX. + + FLT_UWORD_HALF_MAX + The bitmask of FLT_MAX/2. + + FLT_UWORD_EXP_MAX + The bitmask of the largest finite exponent (129 if the largest + exponent is used for finite numbers, 128 otherwise). + + FLT_UWORD_LOG_MAX + The bitmask of log(FLT_MAX), rounded down. This value is the largest + input that can be passed to exp() without producing overflow. + + FLT_UWORD_LOG_2MAX + The bitmask of log(2*FLT_MAX), rounded down. This value is the + largest input than can be passed to cosh() without producing + overflow. + + FLT_LARGEST_EXP + The largest biased exponent that can be used for finite numbers + (255 if the largest exponent is used for finite numbers, 254 + otherwise) */ + +#ifdef _FLT_LARGEST_EXPONENT_IS_NORMAL +#define FLT_UWORD_IS_FINITE(x) 1 +#define FLT_UWORD_IS_NAN(x) 0 +#define FLT_UWORD_IS_INFINITE(x) 0 +#define FLT_UWORD_MAX 0x7fffffff +#define FLT_UWORD_EXP_MAX 0x43010000 +#define FLT_UWORD_LOG_MAX 0x42b2d4fc +#define FLT_UWORD_LOG_2MAX 0x42b437e0 +#define HUGE ((float)0X1.FFFFFEP128) +#else +#define FLT_UWORD_IS_FINITE(x) ((x)<0x7f800000L) +#define FLT_UWORD_IS_NAN(x) ((x)>0x7f800000L) +#define FLT_UWORD_IS_INFINITE(x) ((x)==0x7f800000L) +#define FLT_UWORD_MAX 0x7f7fffffL +#define FLT_UWORD_EXP_MAX 0x43000000 +#define FLT_UWORD_LOG_MAX 0x42b17217 +#define FLT_UWORD_LOG_2MAX 0x42b2d4fc +#define HUGE ((float)3.40282346638528860e+38) +#endif +#define FLT_UWORD_HALF_MAX (FLT_UWORD_MAX-(1L<<23)) +#define FLT_LARGEST_EXP (FLT_UWORD_MAX>>23) + +/* Many routines check for zero and subnormal numbers. Such things depend + on whether the target supports denormals or not: + + FLT_UWORD_IS_ZERO(X) + True if a positive float with bitmask X is +0. Without denormals, + any float with a zero exponent is a +0 representation. With + denormals, the only +0 representation is a 0 bitmask. + + FLT_UWORD_IS_SUBNORMAL(X) + True if a non-zero positive float with bitmask X is subnormal. + (Routines should check for zeros first.) + + FLT_UWORD_MIN + The bitmask of the smallest float above +0. Call this number + REAL_FLT_MIN... + + FLT_UWORD_EXP_MIN + The bitmask of the float representation of REAL_FLT_MIN's exponent. + + FLT_UWORD_LOG_MIN + The bitmask of |log(REAL_FLT_MIN)|, rounding down. + + FLT_SMALLEST_EXP + REAL_FLT_MIN's exponent - EXP_BIAS (1 if denormals are not supported, + -22 if they are). +*/ + +#ifdef _FLT_NO_DENORMALS +#define FLT_UWORD_IS_ZERO(x) ((x)<0x00800000L) +#define FLT_UWORD_IS_SUBNORMAL(x) 0 +#define FLT_UWORD_MIN 0x00800000 +#define FLT_UWORD_EXP_MIN 0x42fc0000 +#define FLT_UWORD_LOG_MIN 0x42aeac50 +#define FLT_SMALLEST_EXP 1 +#else +#define FLT_UWORD_IS_ZERO(x) ((x)==0) +#define FLT_UWORD_IS_SUBNORMAL(x) ((x)<0x00800000L) +#define FLT_UWORD_MIN 0x00000001 +#define FLT_UWORD_EXP_MIN 0x43160000 +#define FLT_UWORD_LOG_MIN 0x42cff1b5 +#define FLT_SMALLEST_EXP -22 +#endif + +#ifdef __STDC__ +#undef __P +#define __P(p) p +#else +#define __P(p) () +#endif + +/* + * set X_TLOSS = pi*2**52, which is possibly defined in + * (one may replace the following line by "#include ") + */ + +#define X_TLOSS 1.41484755040568800000e+16 + +/* Functions that are not documented, and are not in . */ + +/* Undocumented float functions. */ +#ifdef _SCALB_INT +extern float scalbf __P((float, int)); +#else +extern float scalbf __P((float, float)); +#endif +extern float significandf __P((float)); + +/* ieee style elementary float functions */ +extern float __ieee754_sqrtf __P((float)); +extern float __ieee754_acosf __P((float)); +extern float __ieee754_acoshf __P((float)); +extern float __ieee754_logf __P((float)); +extern float __ieee754_atanhf __P((float)); +extern float __ieee754_asinf __P((float)); +extern float __ieee754_atan2f __P((float,float)); +extern float __ieee754_expf __P((float)); +extern float __ieee754_coshf __P((float)); +extern float __ieee754_fmodf __P((float,float)); +extern float __ieee754_powf __P((float,float)); +extern float __ieee754_lgammaf_r __P((float,int *)); +extern float __ieee754_gammaf_r __P((float,int *)); +extern float __ieee754_log10f __P((float)); +extern float __ieee754_sinhf __P((float)); +extern float __ieee754_hypotf __P((float,float)); +extern float __ieee754_j0f __P((float)); +extern float __ieee754_j1f __P((float)); +extern float __ieee754_y0f __P((float)); +extern float __ieee754_y1f __P((float)); +extern float __ieee754_jnf __P((int,float)); +extern float __ieee754_ynf __P((int,float)); +extern float __ieee754_remainderf __P((float,float)); +extern __int32_t __ieee754_rem_pio2f __P((float,float*)); +#ifdef _SCALB_INT +extern float __ieee754_scalbf __P((float,int)); +#else +extern float __ieee754_scalbf __P((float,float)); +#endif + +/* float versions of fdlibm kernel functions */ +extern float __kernel_sinf __P((float,float,int)); +extern float __kernel_cosf __P((float,float)); +extern float __kernel_tanf __P((float,float,int)); +extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const __uint8_t*)); + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + __uint32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + +/* Macros to avoid undefined behaviour that can arise if the amount + of a shift is exactly equal to the size of the shifted operand. */ + +#define SAFE_LEFT_SHIFT(op,amt) \ + (((amt) < 8 * sizeof(op)) ? ((op) << (amt)) : 0) + +#define SAFE_RIGHT_SHIFT(op,amt) \ + (((amt) < 8 * sizeof(op)) ? ((op) >> (amt)) : 0) diff --git a/circuitpython/lib/libm/fmodf.c b/circuitpython/lib/libm/fmodf.c new file mode 100644 index 0000000..69a9ad9 --- /dev/null +++ b/circuitpython/lib/libm/fmodf.c @@ -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; +} diff --git a/circuitpython/lib/libm/kf_cos.c b/circuitpython/lib/libm/kf_cos.c new file mode 100644 index 0000000..73b4859 --- /dev/null +++ b/circuitpython/lib/libm/kf_cos.c @@ -0,0 +1,68 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* kf_cos.c -- float version of k_cos.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +one = 1.0000000000e+00f, /* 0x3f800000 */ +C1 = 4.1666667908e-02f, /* 0x3d2aaaab */ +C2 = -1.3888889225e-03f, /* 0xbab60b61 */ +C3 = 2.4801587642e-05f, /* 0x37d00d01 */ +C4 = -2.7557314297e-07f, /* 0xb493f27c */ +C5 = 2.0875723372e-09f, /* 0x310f74f6 */ +C6 = -1.1359647598e-11f; /* 0xad47d74e */ + +#ifdef __STDC__ + float __kernel_cosf(float x, float y) +#else + float __kernel_cosf(x, y) + float x,y; +#endif +{ + float a,hz,z,r,qx; + __int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x32000000) { /* if x < 2**27 */ + if(((int)x)==0) return one; /* generate inexact */ + } + z = x*x; + r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6))))); + if(ix < 0x3e99999a) /* if |x| < 0.3 */ + return one - ((float)0.5*z - (z*r - x*y)); + else { + if(ix > 0x3f480000) { /* x > 0.78125 */ + qx = (float)0.28125; + } else { + SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */ + } + hz = (float)0.5*z-qx; + a = one-qx; + return a - (hz - (z*r-x*y)); + } +} diff --git a/circuitpython/lib/libm/kf_rem_pio2.c b/circuitpython/lib/libm/kf_rem_pio2.c new file mode 100644 index 0000000..cce9eb1 --- /dev/null +++ b/circuitpython/lib/libm/kf_rem_pio2.c @@ -0,0 +1,224 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* kf_rem_pio2.c -- float version of k_rem_pio2.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +/* In the float version, the input parameter x contains 8 bit + integers, not 24 bit integers. 113 bit precision is not supported. */ + +#ifdef __STDC__ +static const int init_jk[] = {4,7,9}; /* initial value for jk */ +#else +static int init_jk[] = {4,7,9}; +#endif + +#ifdef __STDC__ +static const float PIo2[] = { +#else +static float PIo2[] = { +#endif + 1.5703125000e+00f, /* 0x3fc90000 */ + 4.5776367188e-04f, /* 0x39f00000 */ + 2.5987625122e-05f, /* 0x37da0000 */ + 7.5437128544e-08f, /* 0x33a20000 */ + 6.0026650317e-11f, /* 0x2e840000 */ + 7.3896444519e-13f, /* 0x2b500000 */ + 5.3845816694e-15f, /* 0x27c20000 */ + 5.6378512969e-18f, /* 0x22d00000 */ + 8.3009228831e-20f, /* 0x1fc40000 */ + 3.2756352257e-22f, /* 0x1bc60000 */ + 6.3331015649e-25f, /* 0x17440000 */ +}; + +#ifdef __STDC__ +static const float +#else +static float +#endif +zero = 0.0f, +one = 1.0f, +two8 = 2.5600000000e+02f, /* 0x43800000 */ +twon8 = 3.9062500000e-03f; /* 0x3b800000 */ + +#ifdef __STDC__ + int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const __uint8_t *ipio2) +#else + int __kernel_rem_pio2f(x,y,e0,nx,prec,ipio2) + float x[], y[]; int e0,nx,prec; __uint8_t ipio2[]; +#endif +{ + __int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + float z,fw,f[20],fq[20],q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx-1; + jv = (e0-3)/8; if(jv<0) jv=0; + q0 = e0-8*(jv+1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv-jx; m = jx+jk; + for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (float) ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i=0;i<=jk;i++) { + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for(i=0,j=jz,z=q[jz];j>0;i++,j--) { + fw = (float)((__int32_t)(twon8* z)); + iq[i] = (__int32_t)(z-two8*fw); + z = q[j-1]+fw; + } + + /* compute n */ + z = scalbnf(z,(int)q0); /* actual value of z */ + z -= (float)8.0*floorf(z*(float)0.125); /* trim off integer >= 8 */ + n = (__int32_t) z; + z -= (float)n; + ih = 0; + if(q0>0) { /* need iq[jz-1] to determine n */ + i = (iq[jz-1]>>(8-q0)); n += i; + iq[jz-1] -= i<<(8-q0); + ih = iq[jz-1]>>(7-q0); + } + else if(q0==0) ih = iq[jz-1]>>8; + else if(z>=(float)0.5) ih=2; + + if(ih>0) { /* q > 0.5 */ + n += 1; carry = 0; + for(i=0;i0) { /* rare case: chance is 1 in 12 */ + switch(q0) { + case 1: + iq[jz-1] &= 0x7f; break; + case 2: + iq[jz-1] &= 0x3f; break; + } + } + if(ih==2) { + z = one - z; + if(carry!=0) z -= scalbnf(one,(int)q0); + } + } + + /* check if recomputation is needed */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + if(z==zero) { +#pragma GCC diagnostic pop + j = 0; + for (i=jz-1;i>=jk;i--) j |= iq[i]; + if(j==0) { /* need recomputation */ + for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ + + for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ + f[jx+i] = (float) ipio2[jv+i]; + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + if(z==(float)0.0) { +#pragma GCC diagnostic pop + jz -= 1; q0 -= 8; + while(iq[jz]==0) { jz--; q0-=8;} + } else { /* break z into 8-bit if necessary */ + z = scalbnf(z,-(int)q0); + if(z>=two8) { + fw = (float)((__int32_t)(twon8*z)); + iq[jz] = (__int32_t)(z-two8*fw); + jz += 1; q0 += 8; + iq[jz] = (__int32_t) fw; + } else iq[jz] = (__int32_t) z ; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = scalbnf(one,(int)q0); + for(i=jz;i>=0;i--) { + q[i] = fw*(float)iq[i]; fw*=twon8; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i=jz;i>=0;i--) { + for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; + fq[jz-i] = fw; + } + + /* compress fq[] into y[] */ + switch(prec) { + case 0: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + fw = fq[0]-fw; + for (i=1;i<=jz;i++) fw += fq[i]; + y[1] = (ih==0)? fw: -fw; + break; + case 3: /* painful */ + for (i=jz;i>0;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (i=jz;i>1;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; + if(ih==0) { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } else { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + } + } + return n&7; +} diff --git a/circuitpython/lib/libm/kf_sin.c b/circuitpython/lib/libm/kf_sin.c new file mode 100644 index 0000000..9f22906 --- /dev/null +++ b/circuitpython/lib/libm/kf_sin.c @@ -0,0 +1,58 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* kf_sin.c -- float version of k_sin.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +half = 5.0000000000e-01f,/* 0x3f000000 */ +S1 = -1.6666667163e-01f, /* 0xbe2aaaab */ +S2 = 8.3333337680e-03f, /* 0x3c088889 */ +S3 = -1.9841270114e-04f, /* 0xb9500d01 */ +S4 = 2.7557314297e-06f, /* 0x3638ef1b */ +S5 = -2.5050759689e-08f, /* 0xb2d72f34 */ +S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */ + +#ifdef __STDC__ + float __kernel_sinf(float x, float y, int iy) +#else + float __kernel_sinf(x, y, iy) + float x,y; int iy; /* iy=0 if y is zero */ +#endif +{ + float z,r,v; + __int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x32000000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = S2+z*(S3+z*(S4+z*(S5+z*S6))); + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); +} diff --git a/circuitpython/lib/libm/kf_tan.c b/circuitpython/lib/libm/kf_tan.c new file mode 100644 index 0000000..305645b --- /dev/null +++ b/circuitpython/lib/libm/kf_tan.c @@ -0,0 +1,105 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* kf_tan.c -- float version of k_tan.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "libm.h" +#ifdef __STDC__ +static const float +#else +static float +#endif +one = 1.0000000000e+00f, /* 0x3f800000 */ +pio4 = 7.8539812565e-01f, /* 0x3f490fda */ +pio4lo= 3.7748947079e-08f, /* 0x33222168 */ +T[] = { + 3.3333334327e-01f, /* 0x3eaaaaab */ + 1.3333334029e-01f, /* 0x3e088889 */ + 5.3968254477e-02f, /* 0x3d5d0dd1 */ + 2.1869488060e-02f, /* 0x3cb327a4 */ + 8.8632395491e-03f, /* 0x3c11371f */ + 3.5920790397e-03f, /* 0x3b6b6916 */ + 1.4562094584e-03f, /* 0x3abede48 */ + 5.8804126456e-04f, /* 0x3a1a26c8 */ + 2.4646313977e-04f, /* 0x398137b9 */ + 7.8179444245e-05f, /* 0x38a3f445 */ + 7.1407252108e-05f, /* 0x3895c07a */ + -1.8558637748e-05f, /* 0xb79bae5f */ + 2.5907305826e-05f, /* 0x37d95384 */ +}; + +#ifdef __STDC__ + float __kernel_tanf(float x, float y, int iy) +#else + float __kernel_tanf(x, y, iy) + float x,y; int iy; +#endif +{ + float z,r,v,w,s; + __int32_t ix,hx; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; /* high word of |x| */ + if(ix<0x31800000) /* x < 2**-28 */ + {if((int)x==0) { /* generate inexact */ + if((ix|(iy+1))==0) return one/fabsf(x); + else return (iy==1)? x: -one/x; + } + } + if(ix>=0x3f2ca140) { /* |x|>=0.6744 */ + if(hx<0) {x = -x; y = -y;} + z = pio4-x; + w = pio4lo-y; + x = z+w; y = 0.0; + } + z = x*x; + w = z*z; + /* Break x^5*(T[1]+x^2*T[2]+...) into + * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + */ + r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11])))); + v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12]))))); + s = z*x; + r = y + z*(s*(r+v)+y); + r += T[0]*s; + w = x+r; + if(ix>=0x3f2ca140) { + v = (float)iy; + return (float)(1-((hx>>30)&2))*(v-(float)2.0*(x-(w*w/(w+v)-r))); + } + if(iy==1) return w; + else { /* if allow error up to 2 ulp, + simply return -1.0/(x+r) here */ + /* compute -1.0/(x+r) accurately */ + float a,t; + __int32_t i; + z = w; + GET_FLOAT_WORD(i,z); + SET_FLOAT_WORD(z,i&0xfffff000); + v = r-(z - x); /* z+v = r+x */ + t = a = -(float)1.0/w; /* a = -1.0/w */ + GET_FLOAT_WORD(i,t); + SET_FLOAT_WORD(t,i&0xfffff000); + s = (float)1.0+t*z; + return t+a*(s+t*v); + } +} diff --git a/circuitpython/lib/libm/libm.h b/circuitpython/lib/libm/libm.h new file mode 100644 index 0000000..f782249 --- /dev/null +++ b/circuitpython/lib/libm/libm.h @@ -0,0 +1,54 @@ +/*****************************************************************************/ +/*****************************************************************************/ +// 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 +#include + +#define FLT_EVAL_METHOD 0 + +#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) diff --git a/circuitpython/lib/libm/log1pf.c b/circuitpython/lib/libm/log1pf.c new file mode 100644 index 0000000..306b1cd --- /dev/null +++ b/circuitpython/lib/libm/log1pf.c @@ -0,0 +1,85 @@ +/*****************************************************************************/ +/*****************************************************************************/ +// log1pf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +/* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "libm.h" + +#pragma GCC diagnostic ignored "-Wfloat-equal" + +static const float +ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ +/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ +Lg1 = 0xaaaaaa.0p-24f, /* 0.66666662693 */ +Lg2 = 0xccce13.0p-25f, /* 0.40000972152 */ +Lg3 = 0x91e9ee.0p-25f, /* 0.28498786688 */ +Lg4 = 0xf89e26.0p-26f; /* 0.24279078841 */ + +float log1pf(float x) +{ + union {float f; uint32_t i;} u = {x}; + float_t hfsq,f,c,s,z,R,w,t1,t2,dk; + uint32_t ix,iu; + int k; + + ix = u.i; + k = 1; + if (ix < 0x3ed413d0 || ix>>31) { /* 1+x < sqrt(2)+ */ + if (ix >= 0xbf800000) { /* x <= -1.0 */ + if (x == -1) + return x/0.0f; /* log1p(-1)=+inf */ + return (x-x)/0.0f; /* log1p(x<-1)=NaN */ + } + if (ix<<1 < 0x33800000<<1) { /* |x| < 2**-24 */ + /* underflow if subnormal */ + if ((ix&0x7f800000) == 0) + FORCE_EVAL(x*x); + return x; + } + if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ + k = 0; + c = 0; + f = x; + } + } else if (ix >= 0x7f800000) + return x; + if (k) { + u.f = 1 + x; + iu = u.i; + iu += 0x3f800000 - 0x3f3504f3; + k = (int)(iu>>23) - 0x7f; + /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ + if (k < 25) { + c = k >= 2 ? 1-(u.f-x) : x-(u.f-1); + c /= u.f; + } else + c = 0; + /* reduce u into [sqrt(2)/2, sqrt(2)] */ + iu = (iu&0x007fffff) + 0x3f3504f3; + u.i = iu; + f = u.f - 1; + } + s = f/(2.0f + f); + z = s*s; + w = z*z; + t1= w*(Lg2+w*Lg4); + t2= z*(Lg1+w*Lg3); + R = t2 + t1; + hfsq = 0.5f*f*f; + dk = k; + return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi; +} diff --git a/circuitpython/lib/libm/math.c b/circuitpython/lib/libm/math.c new file mode 100644 index 0000000..09f4fc2 --- /dev/null +++ b/circuitpython/lib/libm/math.c @@ -0,0 +1,829 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: 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 "libm.h" + +typedef float float_t; +typedef union { + float f; + struct { + uint32_t m : 23; + uint32_t e : 8; + uint32_t s : 1; + }; +} float_s_t; + +int __signbitf(float f) { + float_s_t u = {.f = f}; + return u.s; +} + +#ifndef NDEBUG +float copysignf(float x, float y) { + float_s_t fx={.f = x}; + float_s_t fy={.f = y}; + + // copy sign bit; + fx.s = fy.s; + + return fx.f; +} +#endif + +static const float _M_LN10 = 2.30258509299404f; // 0x40135d8e +float log10f(float x) { return logf(x) / (float)_M_LN10; } +#undef _M_LN2 +static const float _M_LN2 = 0.6931472; +float log2f(float x) { return logf(x) / (float)_M_LN2; } + +float tanhf(float x) { + int sign = 0; + if (x < 0) { + sign = 1; + x = -x; + } + x = expm1f(-2 * x); + x = x / (x + 2); + return sign ? x : -x; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// __fpclassifyf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +int __fpclassifyf(float x) +{ + union {float f; uint32_t i;} u = {x}; + int e = u.i>>23 & 0xff; + if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; + if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE; + return FP_NORMAL; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// scalbnf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +float scalbnf(float x, int n) +{ + union {float f; uint32_t i;} u; + float_t y = x; + + if (n > 127) { + y *= 0x1p127f; + n -= 127; + if (n > 127) { + y *= 0x1p127f; + n -= 127; + if (n > 127) + n = 127; + } + } else if (n < -126) { + y *= 0x1p-126f; + n += 126; + if (n < -126) { + y *= 0x1p-126f; + n += 126; + if (n < -126) + n = -126; + } + } + u.i = (uint32_t)(0x7f+n)<<23; + x = y * u.f; + return x; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// powf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +/* origin: FreeBSD /usr/src/lib/msun/src/e_powf.c */ +/* + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +static const float +bp[] = {1.0f, 1.5f,}, +dp_h[] = { 0.0f, 5.84960938e-01f,}, /* 0x3f15c000 */ +dp_l[] = { 0.0f, 1.56322085e-06f,}, /* 0x35d1cfdc */ +two24 = 16777216.0f, /* 0x4b800000 */ +huge = 1.0e30f, +tiny = 1.0e-30f, +/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 6.0000002384e-01f, /* 0x3f19999a */ +L2 = 4.2857143283e-01f, /* 0x3edb6db7 */ +L3 = 3.3333334327e-01f, /* 0x3eaaaaab */ +L4 = 2.7272811532e-01f, /* 0x3e8ba305 */ +L5 = 2.3066075146e-01f, /* 0x3e6c3255 */ +L6 = 2.0697501302e-01f, /* 0x3e53f142 */ +P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ +P2 = -2.7777778450e-03f, /* 0xbb360b61 */ +P3 = 6.6137559770e-05f, /* 0x388ab355 */ +P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ +P5 = 4.1381369442e-08f, /* 0x3331bb4c */ +lg2 = 6.9314718246e-01f, /* 0x3f317218 */ +lg2_h = 6.93145752e-01f, /* 0x3f317200 */ +lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */ +ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */ +cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */ +cp_h = 9.6191406250e-01f, /* 0x3f764000 =12b cp */ +cp_l = -1.1736857402e-04f, /* 0xb8f623c6 =tail of cp_h */ +ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */ +ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/ +ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/ + +float powf(float x, float y) +{ + float z,ax,z_h,z_l,p_h,p_l; + float y1,t1,t2,r,s,sn,t,u,v,w; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy,is; + + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; + + /* x**0 = 1, even if x is NaN */ + if (iy == 0) + return 1.0f; + /* 1**y = 1, even if y is NaN */ + if (hx == 0x3f800000) + return 1.0f; + /* NaN if either arg is NaN */ + if (ix > 0x7f800000 || iy > 0x7f800000) + return x + y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if (hx < 0) { + if (iy >= 0x4b800000) + yisint = 2; /* even integer y */ + else if (iy >= 0x3f800000) { + k = (iy>>23) - 0x7f; /* exponent */ + j = iy>>(23-k); + if ((j<<(23-k)) == iy) + yisint = 2 - (j & 1); + } + } + + /* special value of y */ + if (iy == 0x7f800000) { /* y is +-inf */ + if (ix == 0x3f800000) /* (-1)**+-inf is 1 */ + return 1.0f; + else if (ix > 0x3f800000) /* (|x|>1)**+-inf = inf,0 */ + return hy >= 0 ? y : 0.0f; + else if (ix != 0) /* (|x|<1)**+-inf = 0,inf if x!=0 */ + return hy >= 0 ? 0.0f: -y; + } + if (iy == 0x3f800000) /* y is +-1 */ + return hy >= 0 ? x : 1.0f/x; + if (hy == 0x40000000) /* y is 2 */ + return x*x; + if (hy == 0x3f000000) { /* y is 0.5 */ + if (hx >= 0) /* x >= +0 */ + return sqrtf(x); + } + + ax = fabsf(x); + /* special value of x */ + if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) { /* x is +-0,+-inf,+-1 */ + z = ax; + if (hy < 0) /* z = (1/|x|) */ + z = 1.0f/z; + if (hx < 0) { + if (((ix-0x3f800000)|yisint) == 0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if (yisint == 1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + + sn = 1.0f; /* sign of result */ + if (hx < 0) { + if (yisint == 0) /* (x<0)**(non-int) is NaN */ + return (x-x)/(x-x); + if (yisint == 1) /* (x<0)**(odd int) */ + sn = -1.0f; + } + + /* |y| is huge */ + if (iy > 0x4d000000) { /* if |y| > 2**27 */ + /* over/underflow if x is not close to one */ + if (ix < 0x3f7ffff8) + return hy < 0 ? sn*huge*huge : sn*tiny*tiny; + if (ix > 0x3f800007) + return hy > 0 ? sn*huge*huge : sn*tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = ax - 1; /* t has 20 trailing zeros */ + w = (t*t)*(0.5f - t*(0.333333333333f - t*0.25f)); + u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ + v = t*ivln2_l - w*ivln2; + t1 = u + v; + GET_FLOAT_WORD(is, t1); + SET_FLOAT_WORD(t1, is & 0xfffff000); + t2 = v - (t1-u); + } else { + float s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if (ix < 0x00800000) { + ax *= two24; + n -= 24; + GET_FLOAT_WORD(ix, ax); + } + n += ((ix)>>23) - 0x7f; + j = ix & 0x007fffff; + /* determine interval */ + ix = j | 0x3f800000; /* normalize ix */ + if (j <= 0x1cc471) /* |x|>1) & 0xfffff000) | 0x20000000; + SET_FLOAT_WORD(t_h, is + 0x00400000 + (k<<21)); + t_l = ax - (t_h - bp[k]); + s_l = v*((u - s_h*t_h) - s_h*t_l); + /* compute log(ax) */ + s2 = s*s; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+s); + s2 = s_h*s_h; + t_h = 3.0f + s2 + r; + GET_FLOAT_WORD(is, t_h); + SET_FLOAT_WORD(t_h, is & 0xfffff000); + t_l = r - ((t_h - 3.0f) - s2); + /* u+v = s*(1+...) */ + u = s_h*t_h; + v = s_l*t_h + t_l*s; + /* 2/(3log2)*(s+...) */ + p_h = u + v; + GET_FLOAT_WORD(is, p_h); + SET_FLOAT_WORD(p_h, is & 0xfffff000); + p_l = v - (p_h - u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h + p_l*cp+dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (float)n; + t1 = (((z_h + z_l) + dp_h[k]) + t); + GET_FLOAT_WORD(is, t1); + SET_FLOAT_WORD(t1, is & 0xfffff000); + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + } + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + GET_FLOAT_WORD(is, y); + SET_FLOAT_WORD(y1, is & 0xfffff000); + p_l = (y-y1)*t1 + y*t2; + p_h = y1*t1; + z = p_l + p_h; + GET_FLOAT_WORD(j, z); + if (j > 0x43000000) /* if z > 128 */ + return sn*huge*huge; /* overflow */ + else if (j == 0x43000000) { /* if z == 128 */ + if (p_l + ovt > z - p_h) + return sn*huge*huge; /* overflow */ + } else if ((j&0x7fffffff) > 0x43160000) /* z < -150 */ // FIXME: check should be (uint32_t)j > 0xc3160000 + return sn*tiny*tiny; /* underflow */ + else if (j == (int32_t) 0xc3160000) { /* z == -150 */ + if (p_l <= z-p_h) + return sn*tiny*tiny; /* underflow */ + } + /* + * compute 2**(p_h+p_l) + */ + i = j & 0x7fffffff; + k = (i>>23) - 0x7f; + n = 0; + if (i > 0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j + (0x00800000>>(k+1)); + k = ((n&0x7fffffff)>>23) - 0x7f; /* new k for n */ + SET_FLOAT_WORD(t, n & ~(0x007fffff>>k)); + n = ((n&0x007fffff)|0x00800000)>>(23-k); + if (j < 0) + n = -n; + p_h -= t; + } + t = p_l + p_h; + GET_FLOAT_WORD(is, t); + SET_FLOAT_WORD(t, is & 0xffff8000); + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2 + t*lg2_l; + z = u + v; + w = v - (z - u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-2.0f) - (w+z*w); + z = 1.0f - (r - z); + GET_FLOAT_WORD(j, z); + j += n<<23; + if ((j>>23) <= 0) /* subnormal output */ + z = scalbnf(z, n); + else + SET_FLOAT_WORD(z, j); + return sn*z; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// expf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +/* origin: FreeBSD /usr/src/lib/msun/src/e_expf.c */ +/* + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +static const float +half[2] = {0.5f,-0.5f}, +ln2hi = 6.9314575195e-1f, /* 0x3f317200 */ +ln2lo = 1.4286067653e-6f, /* 0x35bfbe8e */ +invln2 = 1.4426950216e+0f, /* 0x3fb8aa3b */ +/* + * Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]: + * |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74 + */ +expf_P1 = 1.6666625440e-1f, /* 0xaaaa8f.0p-26 */ +expf_P2 = -2.7667332906e-3f; /* -0xb55215.0p-32 */ + +float expf(float x) +{ + float_t hi, lo, c, xx, y; + int k, sign; + uint32_t hx; + + GET_FLOAT_WORD(hx, x); + sign = hx >> 31; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* special cases */ + if (hx >= 0x42aeac50) { /* if |x| >= -87.33655f or NaN */ + if (hx >= 0x42b17218 && !sign) { /* x >= 88.722839f */ + /* overflow */ + x *= 0x1p127f; + return x; + } + if (sign) { + /* underflow */ + FORCE_EVAL(-0x1p-149f/x); + if (hx >= 0x42cff1b5) /* x <= -103.972084f */ + return 0; + } + } + + /* argument reduction */ + if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ + if (hx > 0x3f851592) /* if |x| > 1.5 ln2 */ + k = (int)(invln2*x + half[sign]); + else + k = 1 - sign - sign; + hi = x - k*ln2hi; /* k*ln2hi is exact here */ + lo = k*ln2lo; + x = hi - lo; + } else if (hx > 0x39000000) { /* |x| > 2**-14 */ + k = 0; + hi = x; + lo = 0; + } else { + /* raise inexact */ + FORCE_EVAL(0x1p127f + x); + return 1 + x; + } + + /* x is now in primary range */ + xx = x*x; + c = x - xx*(expf_P1+xx*expf_P2); + y = 1 + (x*c/(2-c) - lo + hi); + if (k == 0) + return y; + return scalbnf(y, k); +} + +/*****************************************************************************/ +/*****************************************************************************/ +// expm1f from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1f.c */ +/* + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +static const float +o_threshold = 8.8721679688e+01f, /* 0x42b17180 */ +ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ +//invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */ +/* + * Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]: + * |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04 + * Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c): + */ +Q1 = -3.3333212137e-2f, /* -0x888868.0p-28 */ +Q2 = 1.5807170421e-3f; /* 0xcf3010.0p-33 */ + +float expm1f(float x) +{ + float_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk; + union {float f; uint32_t i;} u = {x}; + uint32_t hx = u.i & 0x7fffffff; + int k, sign = u.i >> 31; + + /* filter out huge and non-finite argument */ + if (hx >= 0x4195b844) { /* if |x|>=27*ln2 */ + if (hx > 0x7f800000) /* NaN */ + return x; + if (sign) + return -1; + if (x > o_threshold) { + x *= 0x1p127f; + return x; + } + } + + /* argument reduction */ + if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ + if (hx < 0x3F851592) { /* and |x| < 1.5 ln2 */ + if (!sign) { + hi = x - ln2_hi; + lo = ln2_lo; + k = 1; + } else { + hi = x + ln2_hi; + lo = -ln2_lo; + k = -1; + } + } else { + k = (int)(invln2*x + (sign ? -0.5f : 0.5f)); + t = k; + hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ + lo = t*ln2_lo; + } + x = hi-lo; + c = (hi-x)-lo; + } else if (hx < 0x33000000) { /* when |x|<2**-25, return x */ + if (hx < 0x00800000) + FORCE_EVAL(x*x); + return x; + } else + k = 0; + + /* x is now in primary range */ + hfx = 0.5f*x; + hxs = x*hfx; + r1 = 1.0f+hxs*(Q1+hxs*Q2); + t = 3.0f - r1*hfx; + e = hxs*((r1-t)/(6.0f - x*t)); + if (k == 0) /* c is 0 */ + return x - (x*e-hxs); + e = x*(e-c) - c; + e -= hxs; + /* exp(x) ~ 2^k (x_reduced - e + 1) */ + if (k == -1) + return 0.5f*(x-e) - 0.5f; + if (k == 1) { + if (x < -0.25f) + return -2.0f*(e-(x+0.5f)); + return 1.0f + 2.0f*(x-e); + } + u.i = (0x7f+k)<<23; /* 2^k */ + twopk = u.f; + if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */ + y = x - e + 1.0f; + if (k == 128) + y = y*2.0f*0x1p127f; + else + y = y*twopk; + return y - 1.0f; + } + u.i = (0x7f-k)<<23; /* 2^-k */ + if (k < 23) + y = (x-e+(1-u.f))*twopk; + else + y = (x-(e+u.f)+1)*twopk; + return y; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// __expo2f from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + + +/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */ +float __expo2f(float x) +{ + /* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */ + static const int k = 235; + static const float kln2 = 0x1.45c778p+7f; + float scale; + + /* note that k is odd and scale*scale overflows */ + SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23); + /* exp(x - k ln2) * 2**(k-1) */ + return expf(x - kln2) * scale * scale; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// logf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +/* origin: FreeBSD /usr/src/lib/msun/src/e_logf.c */ +/* + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +static const float +/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ +Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ +Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ +Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ +Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ + +float logf(float x) +{ + union {float f; uint32_t i;} u = {x}; + float_t hfsq,f,s,z,R,w,t1,t2,dk; + uint32_t ix; + int k; + + ix = u.i; + k = 0; + if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */ + if (ix<<1 == 0) + return -1/(x*x); /* log(+-0)=-inf */ + if (ix>>31) + return (x-x)/0.0f; /* log(-#) = NaN */ + /* subnormal number, scale up x */ + k -= 25; + x *= 0x1p25f; + u.f = x; + ix = u.i; + } else if (ix >= 0x7f800000) { + return x; + } else if (ix == 0x3f800000) + return 0; + + /* reduce x into [sqrt(2)/2, sqrt(2)] */ + ix += 0x3f800000 - 0x3f3504f3; + k += (int)(ix>>23) - 0x7f; + ix = (ix&0x007fffff) + 0x3f3504f3; + u.i = ix; + x = u.f; + + f = x - 1.0f; + s = f/(2.0f + f); + z = s*s; + w = z*z; + t1= w*(Lg2+w*Lg4); + t2= z*(Lg1+w*Lg3); + R = t2 + t1; + hfsq = 0.5f*f*f; + dk = k; + return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// coshf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +float coshf(float x) +{ + union {float f; uint32_t i;} u = {.f = x}; + uint32_t w; + float t; + + /* |x| */ + u.i &= 0x7fffffff; + x = u.f; + w = u.i; + + /* |x| < log(2) */ + if (w < 0x3f317217) { + if (w < 0x3f800000 - (12<<23)) { + FORCE_EVAL(x + 0x1p120f); + return 1; + } + t = expm1f(x); + return 1 + t*t/(2*(1+t)); + } + + /* |x| < log(FLT_MAX) */ + if (w < 0x42b17217) { + t = expf(x); + return 0.5f*(t + 1/t); + } + + /* |x| > log(FLT_MAX) or nan */ + t = __expo2f(x); + return t; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// sinhf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +float sinhf(float x) +{ + union {float f; uint32_t i;} u = {.f = x}; + uint32_t w; + float t, h, absx; + + h = 0.5; + if (u.i >> 31) + h = -h; + /* |x| */ + u.i &= 0x7fffffff; + absx = u.f; + w = u.i; + + /* |x| < log(FLT_MAX) */ + if (w < 0x42b17217) { + t = expm1f(absx); + if (w < 0x3f800000) { + if (w < 0x3f800000 - (12<<23)) + return x; + return h*(2*t - t*t/(t+1)); + } + return h*(t + t/(t+1)); + } + + /* |x| > logf(FLT_MAX) or nan */ + t = 2*h*__expo2f(absx); + return t; +} + +/*****************************************************************************/ +/*****************************************************************************/ +// ceilf, floorf and truncf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +float ceilf(float x) +{ + union {float f; uint32_t i;} u = {x}; + int e = (int)(u.i >> 23 & 0xff) - 0x7f; + uint32_t m; + + if (e >= 23) + return x; + if (e >= 0) { + m = 0x007fffff >> e; + if ((u.i & m) == 0) + return x; + FORCE_EVAL(x + 0x1p120f); + if (u.i >> 31 == 0) + u.i += m; + u.i &= ~m; + } else { + FORCE_EVAL(x + 0x1p120f); + if (u.i >> 31) + u.f = -0.0; + else if (u.i << 1) + u.f = 1.0; + } + return u.f; +} + +float floorf(float x) +{ + union {float f; uint32_t i;} u = {x}; + int e = (int)(u.i >> 23 & 0xff) - 0x7f; + uint32_t m; + + if (e >= 23) + return x; + if (e >= 0) { + m = 0x007fffff >> e; + if ((u.i & m) == 0) + return x; + FORCE_EVAL(x + 0x1p120f); + if (u.i >> 31) + u.i += m; + u.i &= ~m; + } else { + FORCE_EVAL(x + 0x1p120f); + if (u.i >> 31 == 0) + u.i = 0; + else if (u.i << 1) + u.f = -1.0; + } + return u.f; +} + +float truncf(float x) +{ + union {float f; uint32_t i;} u = {x}; + int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9; + uint32_t m; + + if (e >= 23 + 9) + return x; + if (e < 9) + e = 1; + m = -1U >> e; + if ((u.i & m) == 0) + return x; + FORCE_EVAL(x + 0x1p120f); + u.i &= ~m; + return u.f; +} diff --git a/circuitpython/lib/libm/nearbyintf.c b/circuitpython/lib/libm/nearbyintf.c new file mode 100644 index 0000000..5ac3178 --- /dev/null +++ b/circuitpython/lib/libm/nearbyintf.c @@ -0,0 +1,24 @@ +// adapted from the rintf() function from musl-1.1.16 + +#include "libm.h" + +float nearbyintf(float x) +{ + union {float f; uint32_t i;} u = {x}; + int e = u.i>>23 & 0xff; + int s = u.i>>31; + float_t y; + + if (e >= 0x7f+23) + return x; + if (s) + y = x - 0x1p23f + 0x1p23f; + else + y = x + 0x1p23f - 0x1p23f; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + if (y == 0) + return s ? -0.0f : 0.0f; +#pragma GCC diagnostic pop + return y; +} diff --git a/circuitpython/lib/libm/roundf.c b/circuitpython/lib/libm/roundf.c new file mode 100644 index 0000000..3da1f05 --- /dev/null +++ b/circuitpython/lib/libm/roundf.c @@ -0,0 +1,33 @@ +/*****************************************************************************/ +/*****************************************************************************/ +// roundf from musl-0.9.15 +/*****************************************************************************/ +/*****************************************************************************/ + +#include "libm.h" + +float roundf(float x) +{ + union {float f; uint32_t i;} u = {x}; + int e = u.i >> 23 & 0xff; + float_t y; + + if (e >= 0x7f+23) + return x; + if (u.i >> 31) + x = -x; + if (e < 0x7f-1) { + FORCE_EVAL(x + 0x1p23f); + return 0*u.f; + } + y = (float)(x + 0x1p23f) - 0x1p23f - x; + if (y > 0.5f) + y = y + x - 1; + else if (y <= -0.5f) + y = y + x + 1; + else + y = y + x; + if (u.i >> 31) + y = -y; + return y; +} diff --git a/circuitpython/lib/libm/sf_cos.c b/circuitpython/lib/libm/sf_cos.c new file mode 100644 index 0000000..0fe7c8c --- /dev/null +++ b/circuitpython/lib/libm/sf_cos.c @@ -0,0 +1,71 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* sf_cos.c -- float version of s_cos.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + float cosf(float x) +#else + float cosf(x) + float x; +#endif +{ + float y[2],z=0.0; + __int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return __kernel_cosf(x,z); + + /* cos(Inf or NaN) is NaN */ + else if (!FLT_UWORD_IS_FINITE(ix)) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return __kernel_cosf(y[0],y[1]); + case 1: return -__kernel_sinf(y[0],y[1],1); + case 2: return -__kernel_cosf(y[0],y[1]); + default: + return __kernel_sinf(y[0],y[1],1); + } + } +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double cos(double x) +#else + double cos(x) + double x; +#endif +{ + return (double) cosf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm/sf_erf.c b/circuitpython/lib/libm/sf_erf.c new file mode 100644 index 0000000..e1b0a78 --- /dev/null +++ b/circuitpython/lib/libm/sf_erf.c @@ -0,0 +1,257 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* sf_erf.c -- float version of s_erf.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#define __ieee754_expf expf + +#ifdef __v810__ +#define const +#endif + +#ifdef __STDC__ +static const float +#else +static float +#endif +tiny = 1e-30f, +half= 5.0000000000e-01f, /* 0x3F000000 */ +one = 1.0000000000e+00f, /* 0x3F800000 */ +two = 2.0000000000e+00f, /* 0x40000000 */ + /* c = (subfloat)0.84506291151 */ +erx = 8.4506291151e-01f, /* 0x3f58560b */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +efx = 1.2837916613e-01f, /* 0x3e0375d4 */ +efx8= 1.0270333290e+00f, /* 0x3f8375d4 */ +pp0 = 1.2837916613e-01f, /* 0x3e0375d4 */ +pp1 = -3.2504209876e-01f, /* 0xbea66beb */ +pp2 = -2.8481749818e-02f, /* 0xbce9528f */ +pp3 = -5.7702702470e-03f, /* 0xbbbd1489 */ +pp4 = -2.3763017452e-05f, /* 0xb7c756b1 */ +qq1 = 3.9791721106e-01f, /* 0x3ecbbbce */ +qq2 = 6.5022252500e-02f, /* 0x3d852a63 */ +qq3 = 5.0813062117e-03f, /* 0x3ba68116 */ +qq4 = 1.3249473704e-04f, /* 0x390aee49 */ +qq5 = -3.9602282413e-06f, /* 0xb684e21a */ +/* + * Coefficients for approximation to erf in [0.84375,1.25] + */ +pa0 = -2.3621185683e-03f, /* 0xbb1acdc6 */ +pa1 = 4.1485610604e-01f, /* 0x3ed46805 */ +pa2 = -3.7220788002e-01f, /* 0xbebe9208 */ +pa3 = 3.1834661961e-01f, /* 0x3ea2fe54 */ +pa4 = -1.1089469492e-01f, /* 0xbde31cc2 */ +pa5 = 3.5478305072e-02f, /* 0x3d1151b3 */ +pa6 = -2.1663755178e-03f, /* 0xbb0df9c0 */ +qa1 = 1.0642088205e-01f, /* 0x3dd9f331 */ +qa2 = 5.4039794207e-01f, /* 0x3f0a5785 */ +qa3 = 7.1828655899e-02f, /* 0x3d931ae7 */ +qa4 = 1.2617121637e-01f, /* 0x3e013307 */ +qa5 = 1.3637083583e-02f, /* 0x3c5f6e13 */ +qa6 = 1.1984500103e-02f, /* 0x3c445aa3 */ +/* + * Coefficients for approximation to erfc in [1.25,1/0.35] + */ +ra0 = -9.8649440333e-03f, /* 0xbc21a093 */ +ra1 = -6.9385856390e-01f, /* 0xbf31a0b7 */ +ra2 = -1.0558626175e+01f, /* 0xc128f022 */ +ra3 = -6.2375331879e+01f, /* 0xc2798057 */ +ra4 = -1.6239666748e+02f, /* 0xc322658c */ +ra5 = -1.8460508728e+02f, /* 0xc3389ae7 */ +ra6 = -8.1287437439e+01f, /* 0xc2a2932b */ +ra7 = -9.8143291473e+00f, /* 0xc11d077e */ +sa1 = 1.9651271820e+01f, /* 0x419d35ce */ +sa2 = 1.3765776062e+02f, /* 0x4309a863 */ +sa3 = 4.3456588745e+02f, /* 0x43d9486f */ +sa4 = 6.4538726807e+02f, /* 0x442158c9 */ +sa5 = 4.2900814819e+02f, /* 0x43d6810b */ +sa6 = 1.0863500214e+02f, /* 0x42d9451f */ +sa7 = 6.5702495575e+00f, /* 0x40d23f7c */ +sa8 = -6.0424413532e-02f, /* 0xbd777f97 */ +/* + * Coefficients for approximation to erfc in [1/.35,28] + */ +rb0 = -9.8649431020e-03f, /* 0xbc21a092 */ +rb1 = -7.9928326607e-01f, /* 0xbf4c9dd4 */ +rb2 = -1.7757955551e+01f, /* 0xc18e104b */ +rb3 = -1.6063638306e+02f, /* 0xc320a2ea */ +rb4 = -6.3756646729e+02f, /* 0xc41f6441 */ +rb5 = -1.0250950928e+03f, /* 0xc480230b */ +rb6 = -4.8351919556e+02f, /* 0xc3f1c275 */ +sb1 = 3.0338060379e+01f, /* 0x41f2b459 */ +sb2 = 3.2579251099e+02f, /* 0x43a2e571 */ +sb3 = 1.5367296143e+03f, /* 0x44c01759 */ +sb4 = 3.1998581543e+03f, /* 0x4547fdbb */ +sb5 = 2.5530502930e+03f, /* 0x451f90ce */ +sb6 = 4.7452853394e+02f, /* 0x43ed43a7 */ +sb7 = -2.2440952301e+01f; /* 0xc1b38712 */ + +#ifdef __STDC__ + float erff(float x) +#else + float erff(x) + float x; +#endif +{ + __int32_t hx,ix,i; + float R,S,P,Q,s,y,z,r; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(!FLT_UWORD_IS_FINITE(ix)) { /* erf(nan)=nan */ + i = ((__uint32_t)hx>>31)<<1; + return (float)(1-i)+one/x; /* erf(+-inf)=+-1 */ + } + + if(ix < 0x3f580000) { /* |x|<0.84375 */ + if(ix < 0x31800000) { /* |x|<2**-28 */ + if (ix < 0x04000000) + /*avoid underflow */ + return (float)0.125*((float)8.0*x+efx8*x); + return x + efx*x; + } + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + return x + x*y; + } + if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ + s = fabsf(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) return erx + P/Q; else return -erx - P/Q; + } + if (ix >= 0x40c00000) { /* inf>|x|>=6 */ + if(hx>=0) return one-tiny; else return tiny-one; + } + x = fabsf(x); + s = one/(x*x); + if(ix< 0x4036DB6E) { /* |x| < 1/0.35 */ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/0.35 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(z,ix&0xfffff000); + r = __ieee754_expf(-z*z-(float)0.5625)*__ieee754_expf((z-x)*(z+x)+R/S); + if(hx>=0) return one-r/x; else return r/x-one; +} + +#ifdef __STDC__ + float erfcf(float x) +#else + float erfcf(x) + float x; +#endif +{ + __int32_t hx,ix; + float R,S,P,Q,s,y,z,r; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(!FLT_UWORD_IS_FINITE(ix)) { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (float)(((__uint32_t)hx>>31)<<1)+one/x; + } + + if(ix < 0x3f580000) { /* |x|<0.84375 */ + if(ix < 0x23800000) /* |x|<2**-56 */ + return one-x; + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + if(hx < 0x3e800000) { /* x<1/4 */ + return one-(x+x*y); + } else { + r = x*y; + r += (x-half); + return half - r ; + } + } + if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ + s = fabsf(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) { + z = one-erx; return z - P/Q; + } else { + z = erx+P/Q; return one+z; + } + } + if (ix < 0x41e00000) { /* |x|<28 */ + x = fabsf(x); + s = one/(x*x); + if(ix< 0x4036DB6D) { /* |x| < 1/.35 ~ 2.857143*/ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/.35 ~ 2.857143 */ + if(hx<0&&ix>=0x40c00000) return two-tiny;/* x < -6 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(z,ix&0xfffff000); + r = __ieee754_expf(-z*z-(float)0.5625)* + __ieee754_expf((z-x)*(z+x)+R/S); + if(hx>0) return r/x; else return two-r/x; + } else { + if(hx>0) return tiny*tiny; else return two-tiny; + } +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double erf(double x) +#else + double erf(x) + double x; +#endif +{ + return (double) erff((float) x); +} + +#ifdef __STDC__ + double erfc(double x) +#else + double erfc(x) + double x; +#endif +{ + return (double) erfcf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm/sf_frexp.c b/circuitpython/lib/libm/sf_frexp.c new file mode 100644 index 0000000..097185c --- /dev/null +++ b/circuitpython/lib/libm/sf_frexp.c @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* sf_frexp.c -- float version of s_frexp.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +two25 = 3.3554432000e+07f; /* 0x4c000000 */ + +#ifdef __STDC__ + float frexpf(float x, int *eptr) +#else + float frexpf(x, eptr) + float x; int *eptr; +#endif +{ + __int32_t hx, ix; + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + *eptr = 0; + if(!FLT_UWORD_IS_FINITE(ix)||FLT_UWORD_IS_ZERO(ix)) return x; /* 0,inf,nan */ + if (FLT_UWORD_IS_SUBNORMAL(ix)) { /* subnormal */ + x *= two25; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + *eptr = -25; + } + *eptr += (ix>>23)-126; + hx = (hx&0x807fffff)|0x3f000000; + SET_FLOAT_WORD(x,hx); + return x; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double frexp(double x, int *eptr) +#else + double frexp(x, eptr) + double x; int *eptr; +#endif +{ + return (double) frexpf((float) x, eptr); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm/sf_ldexp.c b/circuitpython/lib/libm/sf_ldexp.c new file mode 100644 index 0000000..ebddc1f --- /dev/null +++ b/circuitpython/lib/libm/sf_ldexp.c @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* sf_ldexp.c -- float version of s_ldexp.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + float ldexpf(float value, int exp) +#else + float ldexpf(value, exp) + float value; int exp; +#endif +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + if(!isfinite(value)||value==(float)0.0) return value; +#pragma GCC diagnostic pop + value = scalbnf(value,exp); + //if(!finitef(value)||value==(float)0.0) errno = ERANGE; + return value; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double ldexp(double value, int exp) +#else + double ldexp(value, exp) + double value; int exp; +#endif +{ + return (double) ldexpf((float) value, exp); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm/sf_modf.c b/circuitpython/lib/libm/sf_modf.c new file mode 100644 index 0000000..8141aa8 --- /dev/null +++ b/circuitpython/lib/libm/sf_modf.c @@ -0,0 +1,82 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/common + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* sf_modf.c -- float version of s_modf.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float one = 1.0f; +#else +static float one = 1.0f; +#endif + +#ifdef __STDC__ + float modff(float x, float *iptr) +#else + float modff(x, iptr) + float x,*iptr; +#endif +{ + __int32_t i0,j0; + __uint32_t i; + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */ + if(j0<23) { /* integer part in x */ + if(j0<0) { /* |x|<1 */ + SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */ + return x; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) { /* x is integral */ + __uint32_t ix; + *iptr = x; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */ + return x; + } else { + SET_FLOAT_WORD(*iptr,i0&(~i)); + return x - *iptr; + } + } + } else { /* no fraction part */ + __uint32_t ix; + *iptr = x*one; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */ + return x; + } +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double modf(double x, double *iptr) +#else + double modf(x, iptr) + double x,*iptr; +#endif +{ + return (double) modff((float) x, (float *) iptr); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm/sf_sin.c b/circuitpython/lib/libm/sf_sin.c new file mode 100644 index 0000000..b9d4049 --- /dev/null +++ b/circuitpython/lib/libm/sf_sin.c @@ -0,0 +1,71 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* sf_sin.c -- float version of s_sin.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + float sinf(float x) +#else + float sinf(x) + float x; +#endif +{ + float y[2],z=0.0; + __int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (!FLT_UWORD_IS_FINITE(ix)) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return __kernel_sinf(y[0],y[1],1); + case 1: return __kernel_cosf(y[0],y[1]); + case 2: return -__kernel_sinf(y[0],y[1],1); + default: + return -__kernel_cosf(y[0],y[1]); + } + } +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double sin(double x) +#else + double sin(x) + double x; +#endif +{ + return (double) sinf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm/sf_tan.c b/circuitpython/lib/libm/sf_tan.c new file mode 100644 index 0000000..42d2df9 --- /dev/null +++ b/circuitpython/lib/libm/sf_tan.c @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* sf_tan.c -- float version of s_tan.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + float tanf(float x) +#else + float tanf(x) + float x; +#endif +{ + float y[2],z=0.0; + __int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1); + + /* tan(Inf or NaN) is NaN */ + else if (!FLT_UWORD_IS_FINITE(ix)) return x-x; /* NaN */ + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,y); + return __kernel_tanf(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even + -1 -- n odd */ + } +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double tan(double x) +#else + double tan(x) + double x; +#endif +{ + return (double) tanf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm/thumb_vfp_sqrtf.c b/circuitpython/lib/libm/thumb_vfp_sqrtf.c new file mode 100644 index 0000000..12ffebf --- /dev/null +++ b/circuitpython/lib/libm/thumb_vfp_sqrtf.c @@ -0,0 +1,11 @@ +// an implementation of sqrtf for Thumb using hardware VFP instructions + +#include + +float sqrtf(float x) { + asm volatile ( + "vsqrt.f32 %[r], %[x]\n" + : [r] "=t" (x) + : [x] "t" (x)); + return x; +} diff --git a/circuitpython/lib/libm/wf_lgamma.c b/circuitpython/lib/libm/wf_lgamma.c new file mode 100644 index 0000000..bcf3705 --- /dev/null +++ b/circuitpython/lib/libm/wf_lgamma.c @@ -0,0 +1,96 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* wf_lgamma.c -- float version of w_lgamma.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +#include "fdlibm.h" +#define _IEEE_LIBM 1 + +#ifdef __STDC__ + float lgammaf(float x) +#else + float lgammaf(x) + float x; +#endif +{ +#ifdef _IEEE_LIBM + int sign; + return __ieee754_lgammaf_r(x,&sign); +#else + float y; + struct exception exc; + y = __ieee754_lgammaf_r(x,&(_REENT_SIGNGAM(_REENT))); + if(_LIB_VERSION == _IEEE_) return y; + if(!finitef(y)&&finitef(x)) { +#ifndef HUGE_VAL +#define HUGE_VAL inf + double inf = 0.0; + + SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ +#endif + exc.name = "lgammaf"; + exc.err = 0; + exc.arg1 = exc.arg2 = (double)x; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if(floorf(x)==x&&x<=(float)0.0) { + /* lgammaf(-integer) */ + exc.type = SING; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + + } else { + /* lgammaf(finite) overflow */ + exc.type = OVERFLOW; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + } + if (exc.err != 0) + errno = exc.err; + return (float)exc.retval; + } else + return y; +#endif +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double lgamma(double x) +#else + double lgamma(x) + double x; +#endif +{ + return (double) lgammaf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm/wf_tgamma.c b/circuitpython/lib/libm/wf_tgamma.c new file mode 100644 index 0000000..3ff05f3 --- /dev/null +++ b/circuitpython/lib/libm/wf_tgamma.c @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * These math functions are taken from newlib-nano-2, the newlib/libm/math + * directory, available from https://github.com/32bitmicro/newlib-nano-2. + * + * Appropriate copyright headers are reproduced below. + */ + +/* w_gammaf.c -- float version of w_gamma.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 "math.h" +#include "fdlibm.h" +#define _IEEE_LIBM 1 + +#ifdef __STDC__ + float tgammaf(float x) +#else + float tgammaf(x) + float x; +#endif +{ + float y; + int local_signgam; + if (!isfinite(x)) { + /* special cases: tgammaf(nan)=nan, tgammaf(inf)=inf, tgammaf(-inf)=nan */ + return x + INFINITY; + } + y = expf(__ieee754_lgammaf_r(x,&local_signgam)); + if (local_signgam < 0) y = -y; +#ifdef _IEEE_LIBM + return y; +#else + if(_LIB_VERSION == _IEEE_) return y; + + if(!finitef(y)&&finitef(x)) { + if(floorf(x)==x&&x<=(float)0.0) + /* tgammaf pole */ + return (float)__kernel_standard((double)x,(double)x,141); + else + /* tgammaf overflow */ + return (float)__kernel_standard((double)x,(double)x,140); + } + return y; +#endif +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double tgamma(double x) +#else + double tgamma(x) + double x; +#endif +{ + return (double) tgammaf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/circuitpython/lib/libm_dbl/README b/circuitpython/lib/libm_dbl/README new file mode 100644 index 0000000..0ef01af --- /dev/null +++ b/circuitpython/lib/libm_dbl/README @@ -0,0 +1,36 @@ +This directory contains source code for the standard double-precision math +functions. + +The files lgamma.c, log10.c and tanh.c are too small to have a meaningful +copyright or license. + +The file copysign.c contains a double version of the float copysignf provided +in libm/math.c for use in DEBUG builds where the standard library copy is +not available. + +The rest of the files in this directory are copied from the musl library, +v1.1.16, and, unless otherwise stated in the individual file, have the +following copyright and MIT license: + +---------------------------------------------------------------------- +Copyright © 2005-2014 Rich Felker, et al. + +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. +---------------------------------------------------------------------- diff --git a/circuitpython/lib/libm_dbl/__cos.c b/circuitpython/lib/libm_dbl/__cos.c new file mode 100644 index 0000000..46cefb3 --- /dev/null +++ b/circuitpython/lib/libm_dbl/__cos.c @@ -0,0 +1,71 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* + * __cos( x, y ) + * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * + * Algorithm + * 1. Since cos(-x) = cos(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. + * 3. cos(x) is approximated by a polynomial of degree 14 on + * [0,pi/4] + * 4 14 + * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x + * where the remez error is + * + * | 2 4 6 8 10 12 14 | -58 + * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 + * | | + * + * 4 6 8 10 12 14 + * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then + * cos(x) ~ 1 - x*x/2 + r + * since cos(x+y) ~ cos(x) - sin(x)*y + * ~ cos(x) - x*y, + * a correction term is necessary in cos(x) and hence + * cos(x+y) = 1 - (x*x/2 - (r - x*y)) + * For better accuracy, rearrange to + * cos(x+y) ~ w + (tmp + (r-x*y)) + * where w = 1 - x*x/2 and tmp is a tiny correction term + * (1 - x*x/2 == w + tmp exactly in infinite precision). + * The exactness of w + tmp in infinite precision depends on w + * and tmp having the same precision as x. If they have extra + * precision due to compiler bugs, then the extra precision is + * only good provided it is retained in all terms of the final + * expression for cos(). Retention happens in all cases tested + * under FreeBSD, so don't pessimize things by forcibly clipping + * any extra precision in w. + */ + +#include "libm.h" + +static const double +C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ +C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ +C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ +C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ +C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ +C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ + +double __cos(double x, double y) +{ + double_t hz,z,r,w; + + z = x*x; + w = z*z; + r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6)); + hz = 0.5*z; + w = 1.0-hz; + return w + (((1.0-w)-hz) + (z*r-x*y)); +} diff --git a/circuitpython/lib/libm_dbl/__expo2.c b/circuitpython/lib/libm_dbl/__expo2.c new file mode 100644 index 0000000..740ac68 --- /dev/null +++ b/circuitpython/lib/libm_dbl/__expo2.c @@ -0,0 +1,16 @@ +#include "libm.h" + +/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */ +static const int k = 2043; +static const double kln2 = 0x1.62066151add8bp+10; + +/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */ +double __expo2(double x) +{ + double scale; + + /* note that k is odd and scale*scale overflows */ + INSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0); + /* exp(x - k ln2) * 2**(k-1) */ + return exp(x - kln2) * scale * scale; +} diff --git a/circuitpython/lib/libm_dbl/__fpclassify.c b/circuitpython/lib/libm_dbl/__fpclassify.c new file mode 100644 index 0000000..5c908ba --- /dev/null +++ b/circuitpython/lib/libm_dbl/__fpclassify.c @@ -0,0 +1,11 @@ +#include +#include + +int __fpclassifyd(double x) +{ + union {double f; uint64_t i;} u = {x}; + int e = u.i>>52 & 0x7ff; + if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; + if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE; + return FP_NORMAL; +} diff --git a/circuitpython/lib/libm_dbl/__rem_pio2.c b/circuitpython/lib/libm_dbl/__rem_pio2.c new file mode 100644 index 0000000..d403f81 --- /dev/null +++ b/circuitpython/lib/libm_dbl/__rem_pio2.c @@ -0,0 +1,177 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * Optimized by Bruce D. Evans. + */ +/* __rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __rem_pio2_large() for large x + */ + +#include "libm.h" + +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 +#define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD==2 +#define EPS LDBL_EPSILON +#endif + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 33 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 33 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ +static const double +toint = 1.5/EPS, +invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ +pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ +pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ +pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ +pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ +pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + +/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */ +int __rem_pio2(double x, double *y) +{ + union {double f; uint64_t i;} u = {x}; + double_t z,w,t,r,fn; + double tx[3],ty[2]; + uint32_t ix; + int sign, n, ex, ey, i; + + sign = u.i>>63; + ix = u.i>>32 & 0x7fffffff; + if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */ + if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */ + goto medium; /* cancellation -- use medium case */ + if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */ + if (!sign) { + z = x - pio2_1; /* one round good to 85 bits */ + y[0] = z - pio2_1t; + y[1] = (z-y[0]) - pio2_1t; + return 1; + } else { + z = x + pio2_1; + y[0] = z + pio2_1t; + y[1] = (z-y[0]) + pio2_1t; + return -1; + } + } else { + if (!sign) { + z = x - 2*pio2_1; + y[0] = z - 2*pio2_1t; + y[1] = (z-y[0]) - 2*pio2_1t; + return 2; + } else { + z = x + 2*pio2_1; + y[0] = z + 2*pio2_1t; + y[1] = (z-y[0]) + 2*pio2_1t; + return -2; + } + } + } + if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */ + if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */ + if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */ + goto medium; + if (!sign) { + z = x - 3*pio2_1; + y[0] = z - 3*pio2_1t; + y[1] = (z-y[0]) - 3*pio2_1t; + return 3; + } else { + z = x + 3*pio2_1; + y[0] = z + 3*pio2_1t; + y[1] = (z-y[0]) + 3*pio2_1t; + return -3; + } + } else { + if (ix == 0x401921fb) /* |x| ~= 4pi/2 */ + goto medium; + if (!sign) { + z = x - 4*pio2_1; + y[0] = z - 4*pio2_1t; + y[1] = (z-y[0]) - 4*pio2_1t; + return 4; + } else { + z = x + 4*pio2_1; + y[0] = z + 4*pio2_1t; + y[1] = (z-y[0]) + 4*pio2_1t; + return -4; + } + } + } + if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */ +medium: + /* rint(x/(pi/2)), Assume round-to-nearest. */ + fn = (double_t)x*invpio2 + toint - toint; + n = (int32_t)fn; + r = x - fn*pio2_1; + w = fn*pio2_1t; /* 1st round, good to 85 bits */ + y[0] = r - w; + u.f = y[0]; + ey = u.i>>52 & 0x7ff; + ex = ix>>20; + if (ex - ey > 16) { /* 2nd round, good to 118 bits */ + t = r; + w = fn*pio2_2; + r = t - w; + w = fn*pio2_2t - ((t-r)-w); + y[0] = r - w; + u.f = y[0]; + ey = u.i>>52 & 0x7ff; + if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */ + t = r; + w = fn*pio2_3; + r = t - w; + w = fn*pio2_3t - ((t-r)-w); + y[0] = r - w; + } + } + y[1] = (r - y[0]) - w; + return n; + } + /* + * all other (large) arguments + */ + if (ix >= 0x7ff00000) { /* x is inf or NaN */ + y[0] = y[1] = x - x; + return 0; + } + /* set z = scalbn(|x|,-ilogb(x)+23) */ + u.f = x; + u.i &= (uint64_t)-1>>12; + u.i |= (uint64_t)(0x3ff + 23)<<52; + z = u.f; + for (i=0; i < 2; i++) { + tx[i] = (double)(int32_t)z; + z = (z-tx[i])*0x1p24; + } + tx[i] = z; + /* skip zero terms, first term is non-zero */ + while (tx[i] == 0.0) + i--; + n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1); + if (sign) { + y[0] = -ty[0]; + y[1] = -ty[1]; + return -n; + } + y[0] = ty[0]; + y[1] = ty[1]; + return n; +} diff --git a/circuitpython/lib/libm_dbl/__rem_pio2_large.c b/circuitpython/lib/libm_dbl/__rem_pio2_large.c new file mode 100644 index 0000000..958f28c --- /dev/null +++ b/circuitpython/lib/libm_dbl/__rem_pio2_large.c @@ -0,0 +1,442 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* + * __rem_pio2_large(x,y,e0,nx,prec) + * double x[],y[]; int e0,nx,prec; + * + * __rem_pio2_large return the last three digits of N with + * y = x - N*pi/2 + * so that |y| < pi/2. + * + * The method is to compute the integer (mod 8) and fraction parts of + * (2/pi)*x without doing the full multiplication. In general we + * skip the part of the product that are known to be a huge integer ( + * more accurately, = 0 mod 8 ). Thus the number of operations are + * independent of the exponent of the input. + * + * (2/pi) is represented by an array of 24-bit integers in ipio2[]. + * + * Input parameters: + * x[] The input value (must be positive) is broken into nx + * pieces of 24-bit integers in double precision format. + * x[i] will be the i-th 24 bit of x. The scaled exponent + * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 + * match x's up to 24 bits. + * + * Example of breaking a double positive z into x[0]+x[1]+x[2]: + * e0 = ilogb(z)-23 + * z = scalbn(z,-e0) + * for i = 0,1,2 + * x[i] = floor(z) + * z = (z-x[i])*2**24 + * + * + * y[] ouput result in an array of double precision numbers. + * The dimension of y[] is: + * 24-bit precision 1 + * 53-bit precision 2 + * 64-bit precision 2 + * 113-bit precision 3 + * The actual value is the sum of them. Thus for 113-bit + * precison, one may have to do something like: + * + * long double t,w,r_head, r_tail; + * t = (long double)y[2] + (long double)y[1]; + * w = (long double)y[0]; + * r_head = t+w; + * r_tail = w - (r_head - t); + * + * e0 The exponent of x[0]. Must be <= 16360 or you need to + * expand the ipio2 table. + * + * nx dimension of x[] + * + * prec an integer indicating the precision: + * 0 24 bits (single) + * 1 53 bits (double) + * 2 64 bits (extended) + * 3 113 bits (quad) + * + * External function: + * double scalbn(), floor(); + * + * + * Here is the description of some local variables: + * + * jk jk+1 is the initial number of terms of ipio2[] needed + * in the computation. The minimum and recommended value + * for jk is 3,4,4,6 for single, double, extended, and quad. + * jk+1 must be 2 larger than you might expect so that our + * recomputation test works. (Up to 24 bits in the integer + * part (the 24 bits of it that we compute) and 23 bits in + * the fraction part may be lost to cancelation before we + * recompute.) + * + * jz local integer variable indicating the number of + * terms of ipio2[] used. + * + * jx nx - 1 + * + * jv index for pointing to the suitable ipio2[] for the + * computation. In general, we want + * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 + * is an integer. Thus + * e0-3-24*jv >= 0 or (e0-3)/24 >= jv + * Hence jv = max(0,(e0-3)/24). + * + * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. + * + * q[] double array with integral value, representing the + * 24-bits chunk of the product of x and 2/pi. + * + * q0 the corresponding exponent of q[0]. Note that the + * exponent for q[i] would be q0-24*i. + * + * PIo2[] double precision array, obtained by cutting pi/2 + * into 24 bits chunks. + * + * f[] ipio2[] in floating point + * + * iq[] integer array by breaking up q[] in 24-bits chunk. + * + * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] + * + * ih integer. If >0 it indicates q[] is >= 0.5, hence + * it also indicates the *sign* of the result. + * + */ +/* + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "libm.h" + +static const int init_jk[] = {3,4,4,6}; /* initial value for jk */ + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + * + * integer array, contains the (24*i)-th to (24*i+23)-th + * bit of 2/pi after binary point. The corresponding + * floating value is + * + * ipio2[i] * 2^(-24(i+1)). + * + * NB: This table must have at least (e0-3)/24 + jk terms. + * For quad precision (e0 <= 16360, jk = 6), this is 686. + */ +static const int32_t ipio2[] = { +0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, +0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, +0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, +0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, +0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, +0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, +0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, +0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, +0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, +0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, +0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, + +#if LDBL_MAX_EXP > 1024 +0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6, +0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2, +0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35, +0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30, +0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C, +0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4, +0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770, +0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7, +0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19, +0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522, +0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16, +0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6, +0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E, +0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48, +0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3, +0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF, +0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55, +0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612, +0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929, +0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC, +0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B, +0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C, +0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4, +0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB, +0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC, +0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C, +0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F, +0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5, +0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437, +0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B, +0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA, +0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD, +0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3, +0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3, +0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717, +0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F, +0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61, +0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB, +0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51, +0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0, +0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C, +0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6, +0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC, +0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED, +0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328, +0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D, +0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0, +0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B, +0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4, +0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3, +0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F, +0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD, +0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B, +0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4, +0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761, +0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31, +0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30, +0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262, +0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E, +0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1, +0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C, +0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4, +0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08, +0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196, +0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9, +0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4, +0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC, +0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C, +0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0, +0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C, +0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0, +0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC, +0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22, +0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893, +0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7, +0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5, +0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F, +0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4, +0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF, +0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B, +0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2, +0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138, +0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E, +0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569, +0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34, +0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9, +0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D, +0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F, +0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855, +0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569, +0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B, +0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE, +0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41, +0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49, +0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F, +0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110, +0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8, +0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365, +0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A, +0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270, +0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5, +0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616, +0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B, +0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0, +#endif +}; + +static const double PIo2[] = { + 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ + 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ + 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ + 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ + 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ + 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ + 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ + 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ +}; + +int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec) +{ + int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + double z,fw,f[20],fq[20],q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx-1; + jv = (e0-3)/24; if(jv<0) jv=0; + q0 = e0-24*(jv+1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv-jx; m = jx+jk; + for (i=0; i<=m; i++,j++) + f[i] = j<0 ? 0.0 : (double)ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i=0; i<=jk; i++) { + for (j=0,fw=0.0; j<=jx; j++) + fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for (i=0,j=jz,z=q[jz]; j>0; i++,j--) { + fw = (double)(int32_t)(0x1p-24*z); + iq[i] = (int32_t)(z - 0x1p24*fw); + z = q[j-1]+fw; + } + + /* compute n */ + z = scalbn(z,q0); /* actual value of z */ + z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */ + n = (int32_t)z; + z -= (double)n; + ih = 0; + if (q0 > 0) { /* need iq[jz-1] to determine n */ + i = iq[jz-1]>>(24-q0); n += i; + iq[jz-1] -= i<<(24-q0); + ih = iq[jz-1]>>(23-q0); + } + else if (q0 == 0) ih = iq[jz-1]>>23; + else if (z >= 0.5) ih = 2; + + if (ih > 0) { /* q > 0.5 */ + n += 1; carry = 0; + for (i=0; i 0) { /* rare case: chance is 1 in 12 */ + switch(q0) { + case 1: + iq[jz-1] &= 0x7fffff; break; + case 2: + iq[jz-1] &= 0x3fffff; break; + } + } + if (ih == 2) { + z = 1.0 - z; + if (carry != 0) + z -= scalbn(1.0,q0); + } + } + + /* check if recomputation is needed */ + if (z == 0.0) { + j = 0; + for (i=jz-1; i>=jk; i--) j |= iq[i]; + if (j == 0) { /* need recomputation */ + for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */ + + for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */ + f[jx+i] = (double)ipio2[jv+i]; + for (j=0,fw=0.0; j<=jx; j++) + fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if (z == 0.0) { + jz -= 1; + q0 -= 24; + while (iq[jz] == 0) { + jz--; + q0 -= 24; + } + } else { /* break z into 24-bit if necessary */ + z = scalbn(z,-q0); + if (z >= 0x1p24) { + fw = (double)(int32_t)(0x1p-24*z); + iq[jz] = (int32_t)(z - 0x1p24*fw); + jz += 1; + q0 += 24; + iq[jz] = (int32_t)fw; + } else + iq[jz] = (int32_t)z; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = scalbn(1.0,q0); + for (i=jz; i>=0; i--) { + q[i] = fw*(double)iq[i]; + fw *= 0x1p-24; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i=jz; i>=0; i--) { + for (fw=0.0,k=0; k<=jp && k<=jz-i; k++) + fw += PIo2[k]*q[i+k]; + fq[jz-i] = fw; + } + + /* compress fq[] into y[] */ + switch(prec) { + case 0: + fw = 0.0; + for (i=jz; i>=0; i--) + fw += fq[i]; + y[0] = ih==0 ? fw : -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i=jz; i>=0; i--) + fw += fq[i]; + // TODO: drop excess precision here once double_t is used + fw = (double)fw; + y[0] = ih==0 ? fw : -fw; + fw = fq[0]-fw; + for (i=1; i<=jz; i++) + fw += fq[i]; + y[1] = ih==0 ? fw : -fw; + break; + case 3: /* painful */ + for (i=jz; i>0; i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (i=jz; i>1; i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (fw=0.0,i=jz; i>=2; i--) + fw += fq[i]; + if (ih==0) { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } else { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + } + } + return n&7; +} diff --git a/circuitpython/lib/libm_dbl/__signbit.c b/circuitpython/lib/libm_dbl/__signbit.c new file mode 100644 index 0000000..f1f1ae8 --- /dev/null +++ b/circuitpython/lib/libm_dbl/__signbit.c @@ -0,0 +1,10 @@ +#include "libm.h" + +int __signbitd(double x) +{ + union { + double d; + uint64_t i; + } y = { x }; + return y.i>>63; +} diff --git a/circuitpython/lib/libm_dbl/__sin.c b/circuitpython/lib/libm_dbl/__sin.c new file mode 100644 index 0000000..4030949 --- /dev/null +++ b/circuitpython/lib/libm_dbl/__sin.c @@ -0,0 +1,64 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* __sin( x, y, iy) + * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). + * + * Algorithm + * 1. Since sin(-x) = -sin(x), we need only to consider positive x. + * 2. Callers must return sin(-0) = -0 without calling here since our + * odd polynomial is not evaluated in a way that preserves -0. + * Callers may do the optimization sin(x) ~ x for tiny x. + * 3. sin(x) is approximated by a polynomial of degree 13 on + * [0,pi/4] + * 3 13 + * sin(x) ~ x + S1*x + ... + S6*x + * where + * + * |sin(x) 2 4 6 8 10 12 | -58 + * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 + * | x | + * + * 4. sin(x+y) = sin(x) + sin'(x')*y + * ~ sin(x) + (1-x*x/2)*y + * For better accuracy, let + * 3 2 2 2 2 + * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) + * then 3 2 + * sin(x) = x + (S1*x + (x *(r-y/2)+y)) + */ + +#include "libm.h" + +static const double +S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ +S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ +S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ +S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ +S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ +S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ + +double __sin(double x, double y, int iy) +{ + double_t z,r,v,w; + + z = x*x; + w = z*z; + r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6); + v = z*x; + if (iy == 0) + return x + v*(S1 + z*r); + else + return x - ((z*(0.5*y - v*r) - y) - v*S1); +} diff --git a/circuitpython/lib/libm_dbl/__tan.c b/circuitpython/lib/libm_dbl/__tan.c new file mode 100644 index 0000000..8019844 --- /dev/null +++ b/circuitpython/lib/libm_dbl/__tan.c @@ -0,0 +1,110 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */ +/* + * ==================================================== + * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* __tan( x, y, k ) + * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned. + * + * Algorithm + * 1. Since tan(-x) = -tan(x), we need only to consider positive x. + * 2. Callers must return tan(-0) = -0 without calling here since our + * odd polynomial is not evaluated in a way that preserves -0. + * Callers may do the optimization tan(x) ~ x for tiny x. + * 3. tan(x) is approximated by a odd polynomial of degree 27 on + * [0,0.67434] + * 3 27 + * tan(x) ~ x + T1*x + ... + T13*x + * where + * + * |tan(x) 2 4 26 | -59.2 + * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 + * | x | + * + * Note: tan(x+y) = tan(x) + tan'(x)*y + * ~ tan(x) + (1+x*x)*y + * Therefore, for better accuracy in computing tan(x+y), let + * 3 2 2 2 2 + * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) + * then + * 3 2 + * tan(x+y) = x + (T1*x + (x *(r+y)+y)) + * + * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then + * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) + * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) + */ + +#include "libm.h" + +static const double T[] = { + 3.33333333333334091986e-01, /* 3FD55555, 55555563 */ + 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */ + 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */ + 2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */ + 8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */ + 3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */ + 1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */ + 5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */ + 2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */ + 7.81794442939557092300e-05, /* 3F147E88, A03792A6 */ + 7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */ + -1.85586374855275456654e-05, /* BEF375CB, DB605373 */ + 2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */ +}, +pio4 = 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */ +pio4lo = 3.06161699786838301793e-17; /* 3C81A626, 33145C07 */ + +double __tan(double x, double y, int odd) +{ + double_t z, r, v, w, s, a; + double w0, a0; + uint32_t hx; + int big, sign; + + GET_HIGH_WORD(hx,x); + big = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */ + if (big) { + sign = hx>>31; + if (sign) { + x = -x; + y = -y; + } + x = (pio4 - x) + (pio4lo - y); + y = 0.0; + } + z = x * x; + w = z * z; + /* + * Break x^5*(T[1]+x^2*T[2]+...) into + * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + */ + r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11])))); + v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12]))))); + s = z * x; + r = y + z*(s*(r + v) + y) + s*T[0]; + w = x + r; + if (big) { + s = 1 - 2*odd; + v = s - 2.0 * (x + (r - w*w/(w + s))); + return sign ? -v : v; + } + if (!odd) + return w; + /* -1.0/(x+r) has up to 2ulp error, so compute it accurately */ + w0 = w; + SET_LOW_WORD(w0, 0); + v = r - (w0 - x); /* w0+v = r+x */ + a0 = a = -1.0 / w; + SET_LOW_WORD(a0, 0); + return a0 + a*(1.0 + a0*w0 + a0*v); +} diff --git a/circuitpython/lib/libm_dbl/acos.c b/circuitpython/lib/libm_dbl/acos.c new file mode 100644 index 0000000..6104a32 --- /dev/null +++ b/circuitpython/lib/libm_dbl/acos.c @@ -0,0 +1,101 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_acos.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* acos(x) + * Method : + * acos(x) = pi/2 - asin(x) + * acos(-x) = pi/2 + asin(x) + * For |x|<=0.5 + * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) + * For x>0.5 + * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) + * = 2asin(sqrt((1-x)/2)) + * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) + * = 2f + (2c + 2s*z*R(z)) + * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term + * for f so that f+c ~ sqrt(z). + * For x<-0.5 + * acos(x) = pi - 2asin(sqrt((1-|x|)/2)) + * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + * Function needed: sqrt + */ + +#include "libm.h" + +static const double +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +static double R(double z) +{ + double_t p, q; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + return p/q; +} + +double acos(double x) +{ + double z,w,s,c,df; + uint32_t hx,ix; + + GET_HIGH_WORD(hx, x); + ix = hx & 0x7fffffff; + /* |x| >= 1 or nan */ + if (ix >= 0x3ff00000) { + uint32_t lx; + + GET_LOW_WORD(lx,x); + if (((ix-0x3ff00000) | lx) == 0) { + /* acos(1)=0, acos(-1)=pi */ + if (hx >> 31) + return 2*pio2_hi + 0x1p-120f; + return 0; + } + return 0/(x-x); + } + /* |x| < 0.5 */ + if (ix < 0x3fe00000) { + if (ix <= 0x3c600000) /* |x| < 2**-57 */ + return pio2_hi + 0x1p-120f; + return pio2_hi - (x - (pio2_lo-x*R(x*x))); + } + /* x < -0.5 */ + if (hx >> 31) { + z = (1.0+x)*0.5; + s = sqrt(z); + w = R(z)*s-pio2_lo; + return 2*(pio2_hi - (s+w)); + } + /* x > 0.5 */ + z = (1.0-x)*0.5; + s = sqrt(z); + df = s; + SET_LOW_WORD(df,0); + c = (z-df*df)/(s+df); + w = R(z)*s+c; + return 2*(df+w); +} diff --git a/circuitpython/lib/libm_dbl/acosh.c b/circuitpython/lib/libm_dbl/acosh.c new file mode 100644 index 0000000..badbf90 --- /dev/null +++ b/circuitpython/lib/libm_dbl/acosh.c @@ -0,0 +1,24 @@ +#include "libm.h" + +#if FLT_EVAL_METHOD==2 +#undef sqrt +#define sqrt sqrtl +#endif + +/* acosh(x) = log(x + sqrt(x*x-1)) */ +double acosh(double x) +{ + union {double f; uint64_t i;} u = {.f = x}; + unsigned e = u.i >> 52 & 0x7ff; + + /* x < 1 domain error is handled in the called functions */ + + if (e < 0x3ff + 1) + /* |x| < 2, up to 2ulp error in [1,1.125] */ + return log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1))); + if (e < 0x3ff + 26) + /* |x| < 0x1p26 */ + return log(2*x - 1/(x+sqrt(x*x-1))); + /* |x| >= 0x1p26 or nan */ + return log(x) + 0.693147180559945309417232121458176568; +} diff --git a/circuitpython/lib/libm_dbl/asin.c b/circuitpython/lib/libm_dbl/asin.c new file mode 100644 index 0000000..96b4cdf --- /dev/null +++ b/circuitpython/lib/libm_dbl/asin.c @@ -0,0 +1,107 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* asin(x) + * Method : + * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... + * we approximate asin(x) on [0,0.5] by + * asin(x) = x + x*x^2*R(x^2) + * where + * R(x^2) is a rational approximation of (asin(x)-x)/x^3 + * and its remez error is bounded by + * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75) + * + * For x in [0.5,1] + * asin(x) = pi/2-2*asin(sqrt((1-x)/2)) + * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2; + * then for x>0.98 + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) + * For x<=0.98, let pio4_hi = pio2_hi/2, then + * f = hi part of s; + * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) + * and + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) + * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + */ + +#include "libm.h" + +static const double +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +/* coefficients for R(x^2) */ +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +static double R(double z) +{ + double_t p, q; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + return p/q; +} + +double asin(double x) +{ + double z,r,s; + uint32_t hx,ix; + + GET_HIGH_WORD(hx, x); + ix = hx & 0x7fffffff; + /* |x| >= 1 or nan */ + if (ix >= 0x3ff00000) { + uint32_t lx; + GET_LOW_WORD(lx, x); + if (((ix-0x3ff00000) | lx) == 0) + /* asin(1) = +-pi/2 with inexact */ + return x*pio2_hi + 0x1p-120f; + return 0/(x-x); + } + /* |x| < 0.5 */ + if (ix < 0x3fe00000) { + /* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */ + if (ix < 0x3e500000 && ix >= 0x00100000) + return x; + return x + x*R(x*x); + } + /* 1 > |x| >= 0.5 */ + z = (1 - fabs(x))*0.5; + s = sqrt(z); + r = R(z); + if (ix >= 0x3fef3333) { /* if |x| > 0.975 */ + x = pio2_hi-(2*(s+s*r)-pio2_lo); + } else { + double f,c; + /* f+c = sqrt(z) */ + f = s; + SET_LOW_WORD(f,0); + c = (z-f*f)/(s+f); + x = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f)); + } + if (hx >> 31) + return -x; + return x; +} diff --git a/circuitpython/lib/libm_dbl/asinh.c b/circuitpython/lib/libm_dbl/asinh.c new file mode 100644 index 0000000..0829f22 --- /dev/null +++ b/circuitpython/lib/libm_dbl/asinh.c @@ -0,0 +1,28 @@ +#include "libm.h" + +/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */ +double asinh(double x) +{ + union {double f; uint64_t i;} u = {.f = x}; + unsigned e = u.i >> 52 & 0x7ff; + unsigned s = u.i >> 63; + + /* |x| */ + u.i &= (uint64_t)-1/2; + x = u.f; + + if (e >= 0x3ff + 26) { + /* |x| >= 0x1p26 or inf or nan */ + x = log(x) + 0.693147180559945309417232121458176568; + } else if (e >= 0x3ff + 1) { + /* |x| >= 2 */ + x = log(2*x + 1/(sqrt(x*x+1)+x)); + } else if (e >= 0x3ff - 26) { + /* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */ + x = log1p(x + x*x/(sqrt(x*x+1)+1)); + } else { + /* |x| < 0x1p-26, raise inexact if x != 0 */ + FORCE_EVAL(x + 0x1p120f); + } + return s ? -x : x; +} diff --git a/circuitpython/lib/libm_dbl/atan.c b/circuitpython/lib/libm_dbl/atan.c new file mode 100644 index 0000000..63b0ab2 --- /dev/null +++ b/circuitpython/lib/libm_dbl/atan.c @@ -0,0 +1,116 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/s_atan.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* atan(x) + * Method + * 1. Reduce x to positive by atan(x) = -atan(-x). + * 2. According to the integer k=4t+0.25 chopped, t=x, the argument + * is further reduced to one of the following intervals and the + * arctangent of t is evaluated by the corresponding formula: + * + * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) + * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) + * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) + * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) + * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + + +#include "libm.h" + +static const double atanhi[] = { + 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ + 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ + 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ + 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ +}; + +static const double atanlo[] = { + 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ + 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ + 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ + 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ +}; + +static const double aT[] = { + 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ + -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ + 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ + -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ + 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ + -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ + 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ + -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ + 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ + -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ + 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ +}; + +double atan(double x) +{ + double_t w,s1,s2,z; + uint32_t ix,sign; + int id; + + GET_HIGH_WORD(ix, x); + sign = ix >> 31; + ix &= 0x7fffffff; + if (ix >= 0x44100000) { /* if |x| >= 2^66 */ + if (isnan(x)) + return x; + z = atanhi[3] + 0x1p-120f; + return sign ? -z : z; + } + if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e400000) { /* |x| < 2^-27 */ + if (ix < 0x00100000) + /* raise underflow for subnormal x */ + FORCE_EVAL((float)x); + return x; + } + id = -1; + } else { + x = fabs(x); + if (ix < 0x3ff30000) { /* |x| < 1.1875 */ + if (ix < 0x3fe60000) { /* 7/16 <= |x| < 11/16 */ + id = 0; + x = (2.0*x-1.0)/(2.0+x); + } else { /* 11/16 <= |x| < 19/16 */ + id = 1; + x = (x-1.0)/(x+1.0); + } + } else { + if (ix < 0x40038000) { /* |x| < 2.4375 */ + id = 2; + x = (x-1.5)/(1.0+1.5*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; + x = -1.0/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]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); + s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); + if (id < 0) + return x - x*(s1+s2); + z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x); + return sign ? -z : z; +} diff --git a/circuitpython/lib/libm_dbl/atan2.c b/circuitpython/lib/libm_dbl/atan2.c new file mode 100644 index 0000000..91378b9 --- /dev/null +++ b/circuitpython/lib/libm_dbl/atan2.c @@ -0,0 +1,107 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ +/* atan2(y,x) + * Method : + * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). + * 2. Reduce x to positive by (if x and y are unexceptional): + * ARG (x+iy) = arctan(y/x) ... if x > 0, + * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, + * + * Special cases: + * + * ATAN2((anything), NaN ) is NaN; + * ATAN2(NAN , (anything) ) is NaN; + * ATAN2(+-0, +(anything but NaN)) is +-0 ; + * ATAN2(+-0, -(anything but NaN)) is +-pi ; + * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; + * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; + * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; + * ATAN2(+-INF,+INF ) is +-pi/4 ; + * ATAN2(+-INF,-INF ) is +-3pi/4; + * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "libm.h" + +static const double +pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ +pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ + +double atan2(double y, double x) +{ + double z; + uint32_t m,lx,ly,ix,iy; + + if (isnan(x) || isnan(y)) + return x+y; + EXTRACT_WORDS(ix, lx, x); + EXTRACT_WORDS(iy, ly, y); + if (((ix-0x3ff00000) | lx) == 0) /* x = 1.0 */ + return atan(y); + m = ((iy>>31)&1) | ((ix>>30)&2); /* 2*sign(x)+sign(y) */ + ix = ix & 0x7fffffff; + iy = iy & 0x7fffffff; + + /* when y = 0 */ + if ((iy|ly) == 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|lx) == 0) + return m&1 ? -pi/2 : pi/2; + /* when x is INF */ + if (ix == 0x7ff00000) { + if (iy == 0x7ff00000) { + 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.0; /* atan(+...,+INF) */ + case 1: return -0.0; /* atan(-...,+INF) */ + case 2: return pi; /* atan(+...,-INF) */ + case 3: return -pi; /* atan(-...,-INF) */ + } + } + } + /* |y/x| > 0x1p64 */ + if (ix+(64<<20) < iy || iy == 0x7ff00000) + return m&1 ? -pi/2 : pi/2; + + /* z = atan(|y/x|) without spurious underflow */ + if ((m&2) && iy+(64<<20) < ix) /* |y/x| < 0x1p-64, x<0 */ + z = 0; + else + z = atan(fabs(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(-,-) */ + } +} diff --git a/circuitpython/lib/libm_dbl/atanh.c b/circuitpython/lib/libm_dbl/atanh.c new file mode 100644 index 0000000..63a035d --- /dev/null +++ b/circuitpython/lib/libm_dbl/atanh.c @@ -0,0 +1,29 @@ +#include "libm.h" + +/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */ +double atanh(double x) +{ + union {double f; uint64_t i;} u = {.f = x}; + unsigned e = u.i >> 52 & 0x7ff; + unsigned s = u.i >> 63; + double_t y; + + /* |x| */ + u.i &= (uint64_t)-1/2; + y = u.f; + + if (e < 0x3ff - 1) { + if (e < 0x3ff - 32) { + /* handle underflow */ + if (e == 0) + FORCE_EVAL((float)y); + } else { + /* |x| < 0.5, up to 1.7ulp error */ + y = 0.5*log1p(2*y + 2*y*y/(1-y)); + } + } else { + /* avoid overflow */ + y = 0.5*log1p(2*(y/(1-y))); + } + return s ? -y : y; +} diff --git a/circuitpython/lib/libm_dbl/ceil.c b/circuitpython/lib/libm_dbl/ceil.c new file mode 100644 index 0000000..b13e6f2 --- /dev/null +++ b/circuitpython/lib/libm_dbl/ceil.c @@ -0,0 +1,31 @@ +#include "libm.h" + +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 +#define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD==2 +#define EPS LDBL_EPSILON +#endif +static const double_t toint = 1/EPS; + +double ceil(double x) +{ + union {double f; uint64_t i;} u = {x}; + int e = u.i >> 52 & 0x7ff; + double_t y; + + if (e >= 0x3ff+52 || x == 0) + return x; + /* y = int(x) - x, where int(x) is an integer neighbor of x */ + if (u.i >> 63) + y = x - toint + toint - x; + else + y = x + toint - toint - x; + /* special case because of non-nearest rounding modes */ + if (e <= 0x3ff-1) { + FORCE_EVAL(y); + return u.i >> 63 ? -0.0 : 1; + } + if (y < 0) + return x + y + 1; + return x + y; +} diff --git a/circuitpython/lib/libm_dbl/copysign.c b/circuitpython/lib/libm_dbl/copysign.c new file mode 100644 index 0000000..f42b09b --- /dev/null +++ b/circuitpython/lib/libm_dbl/copysign.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "libm.h" + +#ifndef NDEBUG +typedef union { + double d; + struct { + uint64_t m : 52; + uint64_t e : 11; + uint64_t s : 1; + }; +} double_s_t; + +double copysign(double x, double y) { + double_s_t dx={.d = x}; + double_s_t dy={.d = y}; + + // copy sign bit; + dx.s = dy.s; + + return dx.d; +} +#endif diff --git a/circuitpython/lib/libm_dbl/cos.c b/circuitpython/lib/libm_dbl/cos.c new file mode 100644 index 0000000..ee97f68 --- /dev/null +++ b/circuitpython/lib/libm_dbl/cos.c @@ -0,0 +1,77 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/s_cos.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* cos(x) + * Return cosine function of x. + * + * kernel function: + * __sin ... sine function on [-pi/4,pi/4] + * __cos ... cosine function on [-pi/4,pi/4] + * __rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "libm.h" + +double cos(double x) +{ + double y[2]; + uint32_t ix; + unsigned n; + + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; + + /* |x| ~< pi/4 */ + if (ix <= 0x3fe921fb) { + if (ix < 0x3e46a09e) { /* |x| < 2**-27 * sqrt(2) */ + /* raise inexact if x!=0 */ + FORCE_EVAL(x + 0x1p120f); + return 1.0; + } + return __cos(x, 0); + } + + /* cos(Inf or NaN) is NaN */ + if (ix >= 0x7ff00000) + return x-x; + + /* argument reduction */ + n = __rem_pio2(x, y); + switch (n&3) { + case 0: return __cos(y[0], y[1]); + case 1: return -__sin(y[0], y[1], 1); + case 2: return -__cos(y[0], y[1]); + default: + return __sin(y[0], y[1], 1); + } +} diff --git a/circuitpython/lib/libm_dbl/cosh.c b/circuitpython/lib/libm_dbl/cosh.c new file mode 100644 index 0000000..100f823 --- /dev/null +++ b/circuitpython/lib/libm_dbl/cosh.c @@ -0,0 +1,40 @@ +#include "libm.h" + +/* cosh(x) = (exp(x) + 1/exp(x))/2 + * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) + * = 1 + x*x/2 + o(x^4) + */ +double cosh(double x) +{ + union {double f; uint64_t i;} u = {.f = x}; + uint32_t w; + double t; + + /* |x| */ + u.i &= (uint64_t)-1/2; + x = u.f; + w = u.i >> 32; + + /* |x| < log(2) */ + if (w < 0x3fe62e42) { + if (w < 0x3ff00000 - (26<<20)) { + /* raise inexact if x!=0 */ + FORCE_EVAL(x + 0x1p120f); + return 1; + } + t = expm1(x); + return 1 + t*t/(2*(1+t)); + } + + /* |x| < log(DBL_MAX) */ + if (w < 0x40862e42) { + t = exp(x); + /* note: if x>log(0x1p26) then the 1/t is not needed */ + return 0.5*(t + 1/t); + } + + /* |x| > log(DBL_MAX) or nan */ + /* note: the result is stored to handle overflow */ + t = __expo2(x); + return t; +} diff --git a/circuitpython/lib/libm_dbl/erf.c b/circuitpython/lib/libm_dbl/erf.c new file mode 100644 index 0000000..2f30a29 --- /dev/null +++ b/circuitpython/lib/libm_dbl/erf.c @@ -0,0 +1,273 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/s_erf.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* double erf(double x) + * double erfc(double x) + * x + * 2 |\ + * erf(x) = --------- | exp(-t*t)dt + * sqrt(pi) \| + * 0 + * + * erfc(x) = 1-erf(x) + * Note that + * erf(-x) = -erf(x) + * erfc(-x) = 2 - erfc(x) + * + * Method: + * 1. For |x| in [0, 0.84375] + * erf(x) = x + x*R(x^2) + * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] + * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] + * where R = P/Q where P is an odd poly of degree 8 and + * Q is an odd poly of degree 10. + * -57.90 + * | R - (erf(x)-x)/x | <= 2 + * + * + * Remark. The formula is derived by noting + * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) + * and that + * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 + * is close to one. The interval is chosen because the fix + * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is + * near 0.6174), and by some experiment, 0.84375 is chosen to + * guarantee the error is less than one ulp for erf. + * + * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and + * c = 0.84506291151 rounded to single (24 bits) + * erf(x) = sign(x) * (c + P1(s)/Q1(s)) + * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 + * 1+(c+P1(s)/Q1(s)) if x < 0 + * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 + * Remark: here we use the taylor series expansion at x=1. + * erf(1+s) = erf(1) + s*Poly(s) + * = 0.845.. + P1(s)/Q1(s) + * That is, we use rational approximation to approximate + * erf(1+s) - (c = (single)0.84506291151) + * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] + * where + * P1(s) = degree 6 poly in s + * Q1(s) = degree 6 poly in s + * + * 3. For x in [1.25,1/0.35(~2.857143)], + * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) + * erf(x) = 1 - erfc(x) + * where + * R1(z) = degree 7 poly in z, (z=1/x^2) + * S1(z) = degree 8 poly in z + * + * 4. For x in [1/0.35,28] + * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 + * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 + * erf(x) = sign(x) *(1 - tiny) (raise inexact) + * erfc(x) = tiny*tiny (raise underflow) if x > 0 + * = 2 - tiny if x<0 + * + * 7. Special case: + * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, + * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, + * erfc/erf(NaN) is NaN + */ + +#include "libm.h" + +static const double +erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +efx8 = 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ +pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ +pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ +pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ +pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ +pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */ +qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ +qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ +qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ +qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ +qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */ +/* + * Coefficients for approximation to erf in [0.84375,1.25] + */ +pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ +pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ +pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ +pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ +pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ +pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ +pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */ +qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ +qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ +qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ +qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ +qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ +qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */ +/* + * Coefficients for approximation to erfc in [1.25,1/0.35] + */ +ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ +ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ +ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ +ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ +ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ +ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ +ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ +ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */ +sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ +sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ +sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ +sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ +sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ +sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ +sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ +sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */ +/* + * Coefficients for approximation to erfc in [1/.35,28] + */ +rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ +rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ +rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ +rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ +rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ +rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ +rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */ +sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ +sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ +sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ +sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ +sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ +sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ +sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ + +static double erfc1(double x) +{ + double_t s,P,Q; + + s = fabs(x) - 1; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + return 1 - erx - P/Q; +} + +static double erfc2(uint32_t ix, double x) +{ + double_t s,R,S; + double z; + + if (ix < 0x3ff40000) /* |x| < 1.25 */ + return erfc1(x); + + x = fabs(x); + s = 1/(x*x); + if (ix < 0x4006db6d) { /* |x| < 1/.35 ~ 2.85714 */ + R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S = 1.0+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| > 1/.35 */ + R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S = 1.0+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + z = x; + SET_LOW_WORD(z,0); + return exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S)/x; +} + +double erf(double x) +{ + double r,s,z,y; + uint32_t ix; + int sign; + + GET_HIGH_WORD(ix, x); + sign = ix>>31; + ix &= 0x7fffffff; + if (ix >= 0x7ff00000) { + /* erf(nan)=nan, erf(+-inf)=+-1 */ + return 1-2*sign + 1/x; + } + if (ix < 0x3feb0000) { /* |x| < 0.84375 */ + if (ix < 0x3e300000) { /* |x| < 2**-28 */ + /* avoid underflow */ + return 0.125*(8*x + efx8*x); + } + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + return x + x*y; + } + if (ix < 0x40180000) /* 0.84375 <= |x| < 6 */ + y = 1 - erfc2(ix,x); + else + y = 1 - 0x1p-1022; + return sign ? -y : y; +} + +double erfc(double x) +{ + double r,s,z,y; + uint32_t ix; + int sign; + + GET_HIGH_WORD(ix, x); + sign = ix>>31; + ix &= 0x7fffffff; + if (ix >= 0x7ff00000) { + /* erfc(nan)=nan, erfc(+-inf)=0,2 */ + return 2*sign + 1/x; + } + if (ix < 0x3feb0000) { /* |x| < 0.84375 */ + if (ix < 0x3c700000) /* |x| < 2**-56 */ + return 1.0 - x; + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + if (sign || ix < 0x3fd00000) { /* x < 1/4 */ + return 1.0 - (x+x*y); + } + return 0.5 - (x - 0.5 + x*y); + } + if (ix < 0x403c0000) { /* 0.84375 <= |x| < 28 */ + return sign ? 2 - erfc2(ix,x) : erfc2(ix,x); + } + return sign ? 2 - 0x1p-1022 : 0x1p-1022*0x1p-1022; +} diff --git a/circuitpython/lib/libm_dbl/exp.c b/circuitpython/lib/libm_dbl/exp.c new file mode 100644 index 0000000..9ea672f --- /dev/null +++ b/circuitpython/lib/libm_dbl/exp.c @@ -0,0 +1,134 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_exp.c */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* exp(x) + * Returns the exponential of x. + * + * Method + * 1. Argument reduction: + * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2. + * + * Here r will be represented as r = hi-lo for better + * accuracy. + * + * 2. Approximation of exp(r) by a special rational function on + * the interval [0,0.34658]: + * Write + * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... + * We use a special Remez algorithm on [0,0.34658] to generate + * a polynomial of degree 5 to approximate R. The maximum error + * of this polynomial approximation is bounded by 2**-59. In + * other words, + * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 + * (where z=r*r, and the values of P1 to P5 are listed below) + * and + * | 5 | -59 + * | 2.0+P1*z+...+P5*z - R(z) | <= 2 + * | | + * The computation of exp(r) thus becomes + * 2*r + * exp(r) = 1 + ---------- + * R(r) - r + * r*c(r) + * = 1 + r + ----------- (for better accuracy) + * 2 - c(r) + * where + * 2 4 10 + * c(r) = r - (P1*r + P2*r + ... + P5*r ). + * + * 3. Scale back to obtain exp(x): + * From step 1, we have + * exp(x) = 2^k * exp(r) + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF) is 0, and + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 709.782712893383973096 then exp(x) overflows + * if x < -745.133219101941108420 then exp(x) underflows + */ + +#include "libm.h" + +static const double +half[2] = {0.5,-0.5}, +ln2hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ +ln2lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ + +double exp(double x) +{ + double_t hi, lo, c, xx, y; + int k, sign; + uint32_t hx; + + GET_HIGH_WORD(hx, x); + sign = hx>>31; + hx &= 0x7fffffff; /* high word of |x| */ + + /* special cases */ + if (hx >= 0x4086232b) { /* if |x| >= 708.39... */ + if (isnan(x)) + return x; + if (x > 709.782712893383973096) { + /* overflow if x!=inf */ + x *= 0x1p1023; + return x; + } + if (x < -708.39641853226410622) { + /* underflow if x!=-inf */ + FORCE_EVAL((float)(-0x1p-149/x)); + if (x < -745.13321910194110842) + return 0; + } + } + + /* argument reduction */ + if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if (hx >= 0x3ff0a2b2) /* if |x| >= 1.5 ln2 */ + k = (int)(invln2*x + half[sign]); + else + k = 1 - sign - sign; + hi = x - k*ln2hi; /* k*ln2hi is exact here */ + lo = k*ln2lo; + x = hi - lo; + } else if (hx > 0x3e300000) { /* if |x| > 2**-28 */ + k = 0; + hi = x; + lo = 0; + } else { + /* inexact if x!=0 */ + FORCE_EVAL(0x1p1023 + x); + return 1 + x; + } + + /* x is now in primary range */ + xx = x*x; + c = x - xx*(P1+xx*(P2+xx*(P3+xx*(P4+xx*P5)))); + y = 1 + (x*c/(2-c) - lo + hi); + if (k == 0) + return y; + return scalbn(y, k); +} diff --git a/circuitpython/lib/libm_dbl/expm1.c b/circuitpython/lib/libm_dbl/expm1.c new file mode 100644 index 0000000..ac1e61e --- /dev/null +++ b/circuitpython/lib/libm_dbl/expm1.c @@ -0,0 +1,201 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* expm1(x) + * Returns exp(x)-1, the exponential of x minus 1. + * + * Method + * 1. Argument reduction: + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 + * + * Here a correction term c will be computed to compensate + * the error in r when rounded to a floating-point number. + * + * 2. Approximating expm1(r) by a special rational function on + * the interval [0,0.34658]: + * Since + * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ... + * we define R1(r*r) by + * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r) + * That is, + * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) + * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) + * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... + * We use a special Remez algorithm on [0,0.347] to generate + * a polynomial of degree 5 in r*r to approximate R1. The + * maximum error of this polynomial approximation is bounded + * by 2**-61. In other words, + * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 + * where Q1 = -1.6666666666666567384E-2, + * Q2 = 3.9682539681370365873E-4, + * Q3 = -9.9206344733435987357E-6, + * Q4 = 2.5051361420808517002E-7, + * Q5 = -6.2843505682382617102E-9; + * z = r*r, + * with error bounded by + * | 5 | -61 + * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 + * | | + * + * expm1(r) = exp(r)-1 is then computed by the following + * specific way which minimize the accumulation rounding error: + * 2 3 + * r r [ 3 - (R1 + R1*r/2) ] + * expm1(r) = r + --- + --- * [--------------------] + * 2 2 [ 6 - r*(3 - R1*r/2) ] + * + * To compensate the error in the argument reduction, we use + * expm1(r+c) = expm1(r) + c + expm1(r)*c + * ~ expm1(r) + c + r*c + * Thus c+r*c will be added in as the correction terms for + * expm1(r+c). Now rearrange the term to avoid optimization + * screw up: + * ( 2 2 ) + * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) + * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) + * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) + * ( ) + * + * = r - E + * 3. Scale back to obtain expm1(x): + * From step 1, we have + * expm1(x) = either 2^k*[expm1(r)+1] - 1 + * = or 2^k*[expm1(r) + (1-2^-k)] + * 4. Implementation notes: + * (A). To save one multiplication, we scale the coefficient Qi + * to Qi*2^i, and replace z by (x^2)/2. + * (B). To achieve maximum accuracy, we compute expm1(x) by + * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) + * (ii) if k=0, return r-E + * (iii) if k=-1, return 0.5*(r-E)-0.5 + * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) + * else return 1.0+2.0*(r-E); + * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) + * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else + * (vii) return 2^k(1-((E+2^-k)-r)) + * + * Special cases: + * expm1(INF) is INF, expm1(NaN) is NaN; + * expm1(-INF) is -1, and + * for finite argument, only expm1(0)=0 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then expm1(x) overflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "libm.h" + +static const double +o_threshold = 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +ln2_hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +/* Scaled Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */ +Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */ +Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ +Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ +Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ +Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ + +double expm1(double x) +{ + double_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk; + union {double f; uint64_t i;} u = {x}; + uint32_t hx = u.i>>32 & 0x7fffffff; + int k, sign = u.i>>63; + + /* filter out huge and non-finite argument */ + if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */ + if (isnan(x)) + return x; + if (sign) + return -1; + if (x > o_threshold) { + x *= 0x1p1023; + return x; + } + } + + /* argument reduction */ + if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + if (!sign) { + hi = x - ln2_hi; + lo = ln2_lo; + k = 1; + } else { + hi = x + ln2_hi; + lo = -ln2_lo; + k = -1; + } + } else { + k = invln2*x + (sign ? -0.5 : 0.5); + t = k; + hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ + lo = t*ln2_lo; + } + x = hi-lo; + c = (hi-x)-lo; + } else if (hx < 0x3c900000) { /* |x| < 2**-54, return x */ + if (hx < 0x00100000) + FORCE_EVAL((float)x); + return x; + } else + k = 0; + + /* x is now in primary range */ + hfx = 0.5*x; + hxs = x*hfx; + r1 = 1.0+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); + t = 3.0-r1*hfx; + e = hxs*((r1-t)/(6.0 - x*t)); + if (k == 0) /* c is 0 */ + return x - (x*e-hxs); + e = x*(e-c) - c; + e -= hxs; + /* exp(x) ~ 2^k (x_reduced - e + 1) */ + if (k == -1) + return 0.5*(x-e) - 0.5; + if (k == 1) { + if (x < -0.25) + return -2.0*(e-(x+0.5)); + return 1.0+2.0*(x-e); + } + u.i = (uint64_t)(0x3ff + k)<<52; /* 2^k */ + twopk = u.f; + if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */ + y = x - e + 1.0; + if (k == 1024) + y = y*2.0*0x1p1023; + else + y = y*twopk; + return y - 1.0; + } + u.i = (uint64_t)(0x3ff - k)<<52; /* 2^-k */ + if (k < 20) + y = (x-e+(1-u.f))*twopk; + else + y = (x-(e+u.f)+1)*twopk; + return y; +} diff --git a/circuitpython/lib/libm_dbl/floor.c b/circuitpython/lib/libm_dbl/floor.c new file mode 100644 index 0000000..14a31cd --- /dev/null +++ b/circuitpython/lib/libm_dbl/floor.c @@ -0,0 +1,31 @@ +#include "libm.h" + +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 +#define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD==2 +#define EPS LDBL_EPSILON +#endif +static const double_t toint = 1/EPS; + +double floor(double x) +{ + union {double f; uint64_t i;} u = {x}; + int e = u.i >> 52 & 0x7ff; + double_t y; + + if (e >= 0x3ff+52 || x == 0) + return x; + /* y = int(x) - x, where int(x) is an integer neighbor of x */ + if (u.i >> 63) + y = x - toint + toint - x; + else + y = x + toint - toint - x; + /* special case because of non-nearest rounding modes */ + if (e <= 0x3ff-1) { + FORCE_EVAL(y); + return u.i >> 63 ? -1 : 0; + } + if (y > 0) + return x + y - 1; + return x + y; +} diff --git a/circuitpython/lib/libm_dbl/fmod.c b/circuitpython/lib/libm_dbl/fmod.c new file mode 100644 index 0000000..6849722 --- /dev/null +++ b/circuitpython/lib/libm_dbl/fmod.c @@ -0,0 +1,68 @@ +#include +#include + +double fmod(double x, double y) +{ + union {double f; uint64_t i;} ux = {x}, uy = {y}; + int ex = ux.i>>52 & 0x7ff; + int ey = uy.i>>52 & 0x7ff; + int sx = ux.i>>63; + uint64_t i; + + /* in the followings uxi should be ux.i, but then gcc wrongly adds */ + /* float load/store to inner loops ruining performance and code size */ + uint64_t uxi = ux.i; + + if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff) + 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<<12; i>>63 == 0; ex--, i <<= 1); + uxi <<= -ex + 1; + } else { + uxi &= -1ULL >> 12; + uxi |= 1ULL << 52; + } + if (!ey) { + for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1); + uy.i <<= -ey + 1; + } else { + uy.i &= -1ULL >> 12; + uy.i |= 1ULL << 52; + } + + /* x mod y */ + for (; ex > ey; ex--) { + i = uxi - uy.i; + if (i >> 63 == 0) { + if (i == 0) + return 0*x; + uxi = i; + } + uxi <<= 1; + } + i = uxi - uy.i; + if (i >> 63 == 0) { + if (i == 0) + return 0*x; + uxi = i; + } + for (; uxi>>52 == 0; uxi <<= 1, ex--); + + /* scale result */ + if (ex > 0) { + uxi -= 1ULL << 52; + uxi |= (uint64_t)ex << 52; + } else { + uxi >>= -ex + 1; + } + uxi |= (uint64_t)sx << 63; + ux.i = uxi; + return ux.f; +} diff --git a/circuitpython/lib/libm_dbl/frexp.c b/circuitpython/lib/libm_dbl/frexp.c new file mode 100644 index 0000000..27b6266 --- /dev/null +++ b/circuitpython/lib/libm_dbl/frexp.c @@ -0,0 +1,23 @@ +#include +#include + +double frexp(double x, int *e) +{ + union { double d; uint64_t i; } y = { x }; + int ee = y.i>>52 & 0x7ff; + + if (!ee) { + if (x) { + x = frexp(x*0x1p64, e); + *e -= 64; + } else *e = 0; + return x; + } else if (ee == 0x7ff) { + return x; + } + + *e = ee - 0x3fe; + y.i &= 0x800fffffffffffffull; + y.i |= 0x3fe0000000000000ull; + return y.d; +} diff --git a/circuitpython/lib/libm_dbl/ldexp.c b/circuitpython/lib/libm_dbl/ldexp.c new file mode 100644 index 0000000..f4d1cd6 --- /dev/null +++ b/circuitpython/lib/libm_dbl/ldexp.c @@ -0,0 +1,6 @@ +#include + +double ldexp(double x, int n) +{ + return scalbn(x, n); +} diff --git a/circuitpython/lib/libm_dbl/lgamma.c b/circuitpython/lib/libm_dbl/lgamma.c new file mode 100644 index 0000000..ed193da --- /dev/null +++ b/circuitpython/lib/libm_dbl/lgamma.c @@ -0,0 +1,8 @@ +#include + +double __lgamma_r(double, int*); + +double lgamma(double x) { + int sign; + return __lgamma_r(x, &sign); +} diff --git a/circuitpython/lib/libm_dbl/libm.h b/circuitpython/lib/libm_dbl/libm.h new file mode 100644 index 0000000..dc0b431 --- /dev/null +++ b/circuitpython/lib/libm_dbl/libm.h @@ -0,0 +1,96 @@ +// Portions of this file are extracted from musl-1.1.16 src/internal/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 +#include + +#define FLT_EVAL_METHOD 0 + +#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 two 32 bit ints from a double. */ +#define EXTRACT_WORDS(hi,lo,d) \ +do { \ + union {double f; uint64_t i;} __u; \ + __u.f = (d); \ + (hi) = __u.i >> 32; \ + (lo) = (uint32_t)__u.i; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ +#define GET_HIGH_WORD(hi,d) \ +do { \ + union {double f; uint64_t i;} __u; \ + __u.f = (d); \ + (hi) = __u.i >> 32; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ +#define GET_LOW_WORD(lo,d) \ +do { \ + union {double f; uint64_t i;} __u; \ + __u.f = (d); \ + (lo) = (uint32_t)__u.i; \ +} while (0) + +/* Set a double from two 32 bit ints. */ +#define INSERT_WORDS(d,hi,lo) \ +do { \ + union {double f; uint64_t i;} __u; \ + __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \ + (d) = __u.f; \ +} while (0) + +/* Set the more significant 32 bits of a double from an int. */ +#define SET_HIGH_WORD(d,hi) \ +do { \ + union {double f; uint64_t i;} __u; \ + __u.f = (d); \ + __u.i &= 0xffffffff; \ + __u.i |= (uint64_t)(hi) << 32; \ + (d) = __u.f; \ +} while (0) + +/* Set the less significant 32 bits of a double from an int. */ +#define SET_LOW_WORD(d,lo) \ +do { \ + union {double f; uint64_t i;} __u; \ + __u.f = (d); \ + __u.i &= 0xffffffff00000000ull; \ + __u.i |= (uint32_t)(lo); \ + (d) = __u.f; \ +} while (0) + +#define DBL_EPSILON 2.22044604925031308085e-16 + +int __rem_pio2(double, double*); +int __rem_pio2_large(double*, double*, int, int, int); +double __sin(double, double, int); +double __cos(double, double); +double __tan(double, double, int); +double __expo2(double); diff --git a/circuitpython/lib/libm_dbl/log.c b/circuitpython/lib/libm_dbl/log.c new file mode 100644 index 0000000..e61e113 --- /dev/null +++ b/circuitpython/lib/libm_dbl/log.c @@ -0,0 +1,118 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_log.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* log(x) + * Return the logarithm of x + * + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Approximation of log(1+f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Remez algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s + * (the values of Lg1 to Lg7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lg1*s +...+Lg7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log(1+f) = f - s*(f - R) (if f is not too large) + * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) + * + * 3. Finally, log(x) = k*ln2 + log(1+f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(+INF) is +INF; log(0) is -INF with signal; + * log(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include +#include + +static const double +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +double log(double x) +{ + union {double f; uint64_t i;} u = {x}; + double_t hfsq,f,s,z,R,w,t1,t2,dk; + uint32_t hx; + int k; + + hx = u.i>>32; + k = 0; + if (hx < 0x00100000 || hx>>31) { + if (u.i<<1 == 0) + return -1/(x*x); /* log(+-0)=-inf */ + if (hx>>31) + return (x-x)/0.0; /* log(-#) = NaN */ + /* subnormal number, scale x up */ + k -= 54; + x *= 0x1p54; + u.f = x; + hx = u.i>>32; + } else if (hx >= 0x7ff00000) { + return x; + } else if (hx == 0x3ff00000 && u.i<<32 == 0) + return 0; + + /* reduce x into [sqrt(2)/2, sqrt(2)] */ + hx += 0x3ff00000 - 0x3fe6a09e; + k += (int)(hx>>20) - 0x3ff; + hx = (hx&0x000fffff) + 0x3fe6a09e; + u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); + x = u.f; + + f = x - 1.0; + hfsq = 0.5*f*f; + s = f/(2.0+f); + z = s*s; + w = z*z; + t1 = w*(Lg2+w*(Lg4+w*Lg6)); + t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + R = t2 + t1; + dk = k; + return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi; +} diff --git a/circuitpython/lib/libm_dbl/log10.c b/circuitpython/lib/libm_dbl/log10.c new file mode 100644 index 0000000..bddedd6 --- /dev/null +++ b/circuitpython/lib/libm_dbl/log10.c @@ -0,0 +1,7 @@ +#include + +static const double _M_LN10 = 2.302585092994046; + +double log10(double x) { + return log(x) / (double)_M_LN10; +} diff --git a/circuitpython/lib/libm_dbl/log1p.c b/circuitpython/lib/libm_dbl/log1p.c new file mode 100644 index 0000000..0097134 --- /dev/null +++ b/circuitpython/lib/libm_dbl/log1p.c @@ -0,0 +1,122 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/s_log1p.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* double log1p(double x) + * Return the natural logarithm of 1+x. + * + * Method : + * 1. Argument Reduction: find k and f such that + * 1+x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * Note. If k=0, then f=x is exact. However, if k!=0, then f + * may not be representable exactly. In that case, a correction + * term is need. Let u=1+x rounded. Let c = (1+x)-u, then + * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), + * and add back the correction term c/u. + * (Note: when x > 2**53, one can simply return log(x)) + * + * 2. Approximation of log(1+f): See log.c + * + * 3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c + * + * Special cases: + * log1p(x) is NaN with signal if x < -1 (including -INF) ; + * log1p(+INF) is +INF; log1p(-1) is -INF with signal; + * log1p(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + * + * Note: Assuming log() return accurate answer, the following + * algorithm can be used to compute log1p(x) to within a few ULP: + * + * u = 1+x; + * if(u==1.0) return x ; else + * return log(u)*(x/(u-1.0)); + * + * See HP-15C Advanced Functions Handbook, p.193. + */ + +#include "libm.h" + +static const double +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +double log1p(double x) +{ + union {double f; uint64_t i;} u = {x}; + double_t hfsq,f,c,s,z,R,w,t1,t2,dk; + uint32_t hx,hu; + int k; + + hx = u.i>>32; + k = 1; + if (hx < 0x3fda827a || hx>>31) { /* 1+x < sqrt(2)+ */ + if (hx >= 0xbff00000) { /* x <= -1.0 */ + if (x == -1) + return x/0.0; /* log1p(-1) = -inf */ + return (x-x)/0.0; /* log1p(x<-1) = NaN */ + } + if (hx<<1 < 0x3ca00000<<1) { /* |x| < 2**-53 */ + /* underflow if subnormal */ + if ((hx&0x7ff00000) == 0) + FORCE_EVAL((float)x); + return x; + } + if (hx <= 0xbfd2bec4) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ + k = 0; + c = 0; + f = x; + } + } else if (hx >= 0x7ff00000) + return x; + if (k) { + u.f = 1 + x; + hu = u.i>>32; + hu += 0x3ff00000 - 0x3fe6a09e; + k = (int)(hu>>20) - 0x3ff; + /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ + if (k < 54) { + c = k >= 2 ? 1-(u.f-x) : x-(u.f-1); + c /= u.f; + } else + c = 0; + /* reduce u into [sqrt(2)/2, sqrt(2)] */ + hu = (hu&0x000fffff) + 0x3fe6a09e; + u.i = (uint64_t)hu<<32 | (u.i&0xffffffff); + f = u.f - 1; + } + hfsq = 0.5*f*f; + s = f/(2.0+f); + z = s*s; + w = z*z; + t1 = w*(Lg2+w*(Lg4+w*Lg6)); + t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + R = t2 + t1; + dk = k; + return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi; +} diff --git a/circuitpython/lib/libm_dbl/modf.c b/circuitpython/lib/libm_dbl/modf.c new file mode 100644 index 0000000..1c8a1db --- /dev/null +++ b/circuitpython/lib/libm_dbl/modf.c @@ -0,0 +1,34 @@ +#include "libm.h" + +double modf(double x, double *iptr) +{ + union {double f; uint64_t i;} u = {x}; + uint64_t mask; + int e = (int)(u.i>>52 & 0x7ff) - 0x3ff; + + /* no fractional part */ + if (e >= 52) { + *iptr = x; + if (e == 0x400 && u.i<<12 != 0) /* nan */ + return x; + u.i &= 1ULL<<63; + return u.f; + } + + /* no integral part*/ + if (e < 0) { + u.i &= 1ULL<<63; + *iptr = u.f; + return x; + } + + mask = -1ULL>>12>>e; + if ((u.i & mask) == 0) { + *iptr = x; + u.i &= 1ULL<<63; + return u.f; + } + u.i &= ~mask; + *iptr = u.f; + return x - u.f; +} diff --git a/circuitpython/lib/libm_dbl/nearbyint.c b/circuitpython/lib/libm_dbl/nearbyint.c new file mode 100644 index 0000000..c3a0b88 --- /dev/null +++ b/circuitpython/lib/libm_dbl/nearbyint.c @@ -0,0 +1,19 @@ +#include + +/* nearbyint is the same as rint, but it must not raise the inexact exception */ + +double nearbyint(double x) +{ +#ifdef FE_INEXACT + #pragma STDC FENV_ACCESS ON + int e; + + e = fetestexcept(FE_INEXACT); +#endif + x = rint(x); +#ifdef FE_INEXACT + if (!e) + feclearexcept(FE_INEXACT); +#endif + return x; +} diff --git a/circuitpython/lib/libm_dbl/pow.c b/circuitpython/lib/libm_dbl/pow.c new file mode 100644 index 0000000..4aef8a5 --- /dev/null +++ b/circuitpython/lib/libm_dbl/pow.c @@ -0,0 +1,328 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_pow.c */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. 1 ** (anything) is 1 + * 3. (anything except 1) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. -1 ** +-INF is 1 + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF, raise divbyzero + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF, raise divbyzero + * 14. -0 ** (+odd integer) is -0 + * 15. -0 ** (-odd integer) is -INF, raise divbyzero + * 16. +INF ** (+anything except 0,NAN) is +INF + * 17. +INF ** (-anything except 0,NAN) is +0 + * 18. -INF ** (+odd integer) is -INF + * 19. -INF ** (anything) = -0 ** (-anything), (anything except odd integer) + * 20. (anything) ** 1 is (anything) + * 21. (anything) ** -1 is 1/(anything) + * 22. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 23. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "libm.h" + +static const double +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +huge = 1.0e300, +tiny = 1.0e-300, +/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +double pow(double x, double y) +{ + double z,ax,z_h,z_l,p_h,p_l; + double y1,t1,t2,r,s,t,u,v,w; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy; + uint32_t lx,ly; + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; + + /* x**0 = 1, even if x is NaN */ + if ((iy|ly) == 0) + return 1.0; + /* 1**y = 1, even if y is NaN */ + if (hx == 0x3ff00000 && lx == 0) + return 1.0; + /* NaN if either arg is NaN */ + if (ix > 0x7ff00000 || (ix == 0x7ff00000 && lx != 0) || + iy > 0x7ff00000 || (iy == 0x7ff00000 && ly != 0)) + return x + y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if (hx < 0) { + if (iy >= 0x43400000) + yisint = 2; /* even integer y */ + else if (iy >= 0x3ff00000) { + k = (iy>>20) - 0x3ff; /* exponent */ + if (k > 20) { + uint32_t j2 = ly>>(52-k); + if ((j2<<(52-k)) == ly) + yisint = 2 - (j2&1); + } else if (ly == 0) { + uint32_t j2 = iy>>(20-k); + if ((j2<<(20-k)) == (uint32_t)iy) + yisint = 2 - (j2&1); + } + } + } + + /* special value of y */ + if (ly == 0) { + if (iy == 0x7ff00000) { /* y is +-inf */ + if (((ix-0x3ff00000)|lx) == 0) /* (-1)**+-inf is 1 */ + return 1.0; + else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */ + return hy >= 0 ? y : 0.0; + else /* (|x|<1)**+-inf = 0,inf */ + return hy >= 0 ? 0.0 : -y; + } + if (iy == 0x3ff00000) { /* y is +-1 */ + if (hy >= 0) + return x; + y = 1/x; +#if FLT_EVAL_METHOD!=0 + { + union {double f; uint64_t i;} u = {y}; + uint64_t i = u.i & -1ULL/2; + if (i>>52 == 0 && (i&(i-1))) + FORCE_EVAL((float)y); + } +#endif + return y; + } + if (hy == 0x40000000) /* y is 2 */ + return x*x; + if (hy == 0x3fe00000) { /* y is 0.5 */ + if (hx >= 0) /* x >= +0 */ + return sqrt(x); + } + } + + ax = fabs(x); + /* special value of x */ + if (lx == 0) { + if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { /* x is +-0,+-inf,+-1 */ + z = ax; + if (hy < 0) /* z = (1/|x|) */ + z = 1.0/z; + if (hx < 0) { + if (((ix-0x3ff00000)|yisint) == 0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if (yisint == 1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + s = 1.0; /* sign of result */ + if (hx < 0) { + if (yisint == 0) /* (x<0)**(non-int) is NaN */ + return (x-x)/(x-x); + if (yisint == 1) /* (x<0)**(odd int) */ + s = -1.0; + } + + /* |y| is huge */ + if (iy > 0x41e00000) { /* if |y| > 2**31 */ + if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */ + if (ix <= 0x3fefffff) + return hy < 0 ? huge*huge : tiny*tiny; + if (ix >= 0x3ff00000) + return hy > 0 ? huge*huge : tiny*tiny; + } + /* over/underflow if x is not close to one */ + if (ix < 0x3fefffff) + return hy < 0 ? s*huge*huge : s*tiny*tiny; + if (ix > 0x3ff00000) + return hy > 0 ? s*huge*huge : s*tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = ax - 1.0; /* t has 20 trailing zeros */ + w = (t*t)*(0.5 - t*(0.3333333333333333333333-t*0.25)); + u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ + v = t*ivln2_l - w*ivln2; + t1 = u + v; + SET_LOW_WORD(t1, 0); + t2 = v - (t1-u); + } else { + double ss,s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if (ix < 0x00100000) { + ax *= two53; + n -= 53; + GET_HIGH_WORD(ix,ax); + } + n += ((ix)>>20) - 0x3ff; + j = ix & 0x000fffff; + /* determine interval */ + ix = j | 0x3ff00000; /* normalize ix */ + if (j <= 0x3988E) /* |x|>1)|0x20000000) + 0x00080000 + (k<<18)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = ss*ss; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+ss); + s2 = s_h*s_h; + t_h = 3.0 + s2 + r; + SET_LOW_WORD(t_h, 0); + t_l = r - ((t_h-3.0)-s2); + /* u+v = ss*(1+...) */ + u = s_h*t_h; + v = s_l*t_h + t_l*ss; + /* 2/(3log2)*(ss+...) */ + p_h = u + v; + SET_LOW_WORD(p_h, 0); + p_l = v - (p_h-u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h+p_l*cp + dp_l[k]; + /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = ((z_h + z_l) + dp_h[k]) + t; + SET_LOW_WORD(t1, 0); + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + } + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + SET_LOW_WORD(y1, 0); + p_l = (y-y1)*t1 + y*t2; + p_h = y1*t1; + z = p_l + p_h; + EXTRACT_WORDS(j, i, z); + if (j >= 0x40900000) { /* z >= 1024 */ + if (((j-0x40900000)|i) != 0) /* if z > 1024 */ + return s*huge*huge; /* overflow */ + if (p_l + ovt > z - p_h) + return s*huge*huge; /* overflow */ + } else if ((j&0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ // FIXME: instead of abs(j) use unsigned j + if (((j-0xc090cc00)|i) != 0) /* z < -1075 */ + return s*tiny*tiny; /* underflow */ + if (p_l <= z - p_h) + return s*tiny*tiny; /* underflow */ + } + /* + * compute 2**(p_h+p_l) + */ + i = j & 0x7fffffff; + k = (i>>20) - 0x3ff; + n = 0; + if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j + (0x00100000>>(k+1)); + k = ((n&0x7fffffff)>>20) - 0x3ff; /* new k for n */ + t = 0.0; + SET_HIGH_WORD(t, n & ~(0x000fffff>>k)); + n = ((n&0x000fffff)|0x00100000)>>(20-k); + if (j < 0) + n = -n; + p_h -= t; + } + t = p_l + p_h; + SET_LOW_WORD(t, 0); + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2 + t*lg2_l; + z = u + v; + w = v - (z-u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-2.0) - (w + z*w); + z = 1.0 - (r-z); + GET_HIGH_WORD(j, z); + j += n<<20; + if ((j>>20) <= 0) /* subnormal output */ + z = scalbn(z,n); + else + SET_HIGH_WORD(z, j); + return s*z; +} diff --git a/circuitpython/lib/libm_dbl/rint.c b/circuitpython/lib/libm_dbl/rint.c new file mode 100644 index 0000000..fbba390 --- /dev/null +++ b/circuitpython/lib/libm_dbl/rint.c @@ -0,0 +1,28 @@ +#include +#include +#include + +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 +#define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD==2 +#define EPS LDBL_EPSILON +#endif +static const double_t toint = 1/EPS; + +double rint(double x) +{ + union {double f; uint64_t i;} u = {x}; + int e = u.i>>52 & 0x7ff; + int s = u.i>>63; + double_t y; + + if (e >= 0x3ff+52) + return x; + if (s) + y = x - toint + toint; + else + y = x + toint - toint; + if (y == 0) + return s ? -0.0 : 0; + return y; +} diff --git a/circuitpython/lib/libm_dbl/round.c b/circuitpython/lib/libm_dbl/round.c new file mode 100644 index 0000000..130d58d --- /dev/null +++ b/circuitpython/lib/libm_dbl/round.c @@ -0,0 +1,35 @@ +#include "libm.h" + +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 +#define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD==2 +#define EPS LDBL_EPSILON +#endif +static const double_t toint = 1/EPS; + +double round(double x) +{ + union {double f; uint64_t i;} u = {x}; + int e = u.i >> 52 & 0x7ff; + double_t y; + + if (e >= 0x3ff+52) + return x; + if (u.i >> 63) + x = -x; + if (e < 0x3ff-1) { + /* raise inexact if x!=0 */ + FORCE_EVAL(x + toint); + return 0*u.f; + } + y = x + toint - toint - x; + if (y > 0.5) + y = y + x - 1; + else if (y <= -0.5) + y = y + x + 1; + else + y = y + x; + if (u.i >> 63) + y = -y; + return y; +} diff --git a/circuitpython/lib/libm_dbl/scalbn.c b/circuitpython/lib/libm_dbl/scalbn.c new file mode 100644 index 0000000..182f561 --- /dev/null +++ b/circuitpython/lib/libm_dbl/scalbn.c @@ -0,0 +1,33 @@ +#include +#include + +double scalbn(double x, int n) +{ + union {double f; uint64_t i;} u; + double_t y = x; + + if (n > 1023) { + y *= 0x1p1023; + n -= 1023; + if (n > 1023) { + y *= 0x1p1023; + n -= 1023; + if (n > 1023) + n = 1023; + } + } else if (n < -1022) { + /* make sure final n < -53 to avoid double + rounding in the subnormal range */ + y *= 0x1p-1022 * 0x1p53; + n += 1022 - 53; + if (n < -1022) { + y *= 0x1p-1022 * 0x1p53; + n += 1022 - 53; + if (n < -1022) + n = -1022; + } + } + u.i = (uint64_t)(0x3ff+n)<<52; + x = y * u.f; + return x; +} diff --git a/circuitpython/lib/libm_dbl/sin.c b/circuitpython/lib/libm_dbl/sin.c new file mode 100644 index 0000000..055e215 --- /dev/null +++ b/circuitpython/lib/libm_dbl/sin.c @@ -0,0 +1,78 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* sin(x) + * Return sine function of x. + * + * kernel function: + * __sin ... sine function on [-pi/4,pi/4] + * __cos ... cose function on [-pi/4,pi/4] + * __rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "libm.h" + +double sin(double x) +{ + double y[2]; + uint32_t ix; + unsigned n; + + /* High word of x. */ + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; + + /* |x| ~< pi/4 */ + if (ix <= 0x3fe921fb) { + if (ix < 0x3e500000) { /* |x| < 2**-26 */ + /* raise inexact if x != 0 and underflow if subnormal*/ + FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f); + return x; + } + return __sin(x, 0.0, 0); + } + + /* sin(Inf or NaN) is NaN */ + if (ix >= 0x7ff00000) + return x - x; + + /* argument reduction needed */ + n = __rem_pio2(x, y); + switch (n&3) { + case 0: return __sin(y[0], y[1], 1); + case 1: return __cos(y[0], y[1]); + case 2: return -__sin(y[0], y[1], 1); + default: + return -__cos(y[0], y[1]); + } +} diff --git a/circuitpython/lib/libm_dbl/sinh.c b/circuitpython/lib/libm_dbl/sinh.c new file mode 100644 index 0000000..00022c4 --- /dev/null +++ b/circuitpython/lib/libm_dbl/sinh.c @@ -0,0 +1,39 @@ +#include "libm.h" + +/* sinh(x) = (exp(x) - 1/exp(x))/2 + * = (exp(x)-1 + (exp(x)-1)/exp(x))/2 + * = x + x^3/6 + o(x^5) + */ +double sinh(double x) +{ + union {double f; uint64_t i;} u = {.f = x}; + uint32_t w; + double t, h, absx; + + h = 0.5; + if (u.i >> 63) + h = -h; + /* |x| */ + u.i &= (uint64_t)-1/2; + absx = u.f; + w = u.i >> 32; + + /* |x| < log(DBL_MAX) */ + if (w < 0x40862e42) { + t = expm1(absx); + if (w < 0x3ff00000) { + if (w < 0x3ff00000 - (26<<20)) + /* note: inexact and underflow are raised by expm1 */ + /* note: this branch avoids spurious underflow */ + return x; + return h*(2*t - t*t/(t+1)); + } + /* note: |x|>log(0x1p26)+eps could be just h*exp(x) */ + return h*(t + t/(t+1)); + } + + /* |x| > log(DBL_MAX) or nan */ + /* note: the result is stored to handle overflow */ + t = 2*h*__expo2(absx); + return t; +} diff --git a/circuitpython/lib/libm_dbl/sqrt.c b/circuitpython/lib/libm_dbl/sqrt.c new file mode 100644 index 0000000..b277567 --- /dev/null +++ b/circuitpython/lib/libm_dbl/sqrt.c @@ -0,0 +1,185 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrt.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* sqrt(x) + * Return correctly rounded sqrt. + * ------------------------------------------ + * | Use the hardware sqrt if you have one | + * ------------------------------------------ + * Method: + * Bit by bit method using integer arithmetic. (Slow, but portable) + * 1. Normalization + * Scale x to y in [1,4) with even powers of 2: + * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then + * sqrt(x) = 2^k * sqrt(y) + * 2. Bit by bit computation + * Let q = sqrt(y) truncated to i bit after binary point (q = 1), + * i 0 + * i+1 2 + * s = 2*q , and y = 2 * ( y - q ). (1) + * i i i i + * + * To compute q from q , one checks whether + * i+1 i + * + * -(i+1) 2 + * (q + 2 ) <= y. (2) + * i + * -(i+1) + * If (2) is false, then q = q ; otherwise q = q + 2 . + * i+1 i i+1 i + * + * With some algebric manipulation, it is not difficult to see + * that (2) is equivalent to + * -(i+1) + * s + 2 <= y (3) + * i i + * + * The advantage of (3) is that s and y can be computed by + * i i + * the following recurrence formula: + * if (3) is false + * + * s = s , y = y ; (4) + * i+1 i i+1 i + * + * otherwise, + * -i -(i+1) + * s = s + 2 , y = y - s - 2 (5) + * i+1 i i+1 i i + * + * One may easily use induction to prove (4) and (5). + * Note. Since the left hand side of (3) contain only i+2 bits, + * it does not necessary to do a full (53-bit) comparison + * in (3). + * 3. Final rounding + * After generating the 53 bits result, we compute one more bit. + * Together with the remainder, we can decide whether the + * result is exact, bigger than 1/2ulp, or less than 1/2ulp + * (it will never equal to 1/2ulp). + * The rounding mode can be detected by checking whether + * huge + tiny is equal to huge, and whether huge - tiny is + * equal to huge for some floating point number "huge" and "tiny". + * + * Special cases: + * sqrt(+-0) = +-0 ... exact + * sqrt(inf) = inf + * sqrt(-ve) = NaN ... with invalid signal + * sqrt(NaN) = NaN ... with invalid signal for signaling NaN + */ + +#include "libm.h" + +static const double tiny = 1.0e-300; + +double sqrt(double x) +{ + double z; + int32_t sign = (int)0x80000000; + int32_t ix0,s0,q,m,t,i; + uint32_t r,t1,s1,ix1,q1; + + EXTRACT_WORDS(ix0, ix1, x); + + /* take care of Inf and NaN */ + if ((ix0&0x7ff00000) == 0x7ff00000) { + return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if (ix0 <= 0) { + if (((ix0&~sign)|ix1) == 0) + return x; /* sqrt(+-0) = +-0 */ + if (ix0 < 0) + return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = ix0>>20; + if (m == 0) { /* subnormal x */ + while (ix0 == 0) { + m -= 21; + ix0 |= (ix1>>11); + ix1 <<= 21; + } + for (i=0; (ix0&0x00100000) == 0; i++) + ix0<<=1; + m -= i - 1; + ix0 |= ix1>>(32-i); + ix1 <<= i; + } + m -= 1023; /* unbias exponent */ + ix0 = (ix0&0x000fffff)|0x00100000; + if (m & 1) { /* odd m, double x to make it even */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + } + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ + r = 0x00200000; /* r = moving bit from right to left */ + + while (r != 0) { + t = s0 + r; + if (t <= ix0) { + s0 = t + r; + ix0 -= t; + q += r; + } + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + r >>= 1; + } + + r = sign; + while (r != 0) { + t1 = s1 + r; + t = s0; + if (t < ix0 || (t == ix0 && t1 <= ix1)) { + s1 = t1 + r; + if ((t1&sign) == sign && (s1&sign) == 0) + s0++; + ix0 -= t; + if (ix1 < t1) + ix0--; + ix1 -= t1; + q1 += r; + } + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + r >>= 1; + } + + /* use floating add to find out rounding direction */ + if ((ix0|ix1) != 0) { + z = 1.0 - tiny; /* raise inexact flag */ + if (z >= 1.0) { + z = 1.0 + tiny; + if (q1 == (uint32_t)0xffffffff) { + q1 = 0; + q++; + } else if (z > 1.0) { + if (q1 == (uint32_t)0xfffffffe) + q++; + q1 += 2; + } else + q1 += q1 & 1; + } + } + ix0 = (q>>1) + 0x3fe00000; + ix1 = q1>>1; + if (q&1) + ix1 |= sign; + ix0 += m << 20; + INSERT_WORDS(z, ix0, ix1); + return z; +} diff --git a/circuitpython/lib/libm_dbl/tan.c b/circuitpython/lib/libm_dbl/tan.c new file mode 100644 index 0000000..9c724a4 --- /dev/null +++ b/circuitpython/lib/libm_dbl/tan.c @@ -0,0 +1,70 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/s_tan.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* tan(x) + * Return tangent function of x. + * + * kernel function: + * __tan ... tangent function on [-pi/4,pi/4] + * __rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "libm.h" + +double tan(double x) +{ + double y[2]; + uint32_t ix; + unsigned n; + + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; + + /* |x| ~< pi/4 */ + if (ix <= 0x3fe921fb) { + if (ix < 0x3e400000) { /* |x| < 2**-27 */ + /* raise inexact if x!=0 and underflow if subnormal */ + FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f); + return x; + } + return __tan(x, 0.0, 0); + } + + /* tan(Inf or NaN) is NaN */ + if (ix >= 0x7ff00000) + return x - x; + + /* argument reduction */ + n = __rem_pio2(x, y); + return __tan(y[0], y[1], n&1); +} diff --git a/circuitpython/lib/libm_dbl/tanh.c b/circuitpython/lib/libm_dbl/tanh.c new file mode 100644 index 0000000..6bdb7c3 --- /dev/null +++ b/circuitpython/lib/libm_dbl/tanh.c @@ -0,0 +1,12 @@ +#include + +double tanh(double x) { + int sign = 0; + if (x < 0) { + sign = 1; + x = -x; + } + x = expm1(-2 * x); + x = x / (x + 2); + return sign ? x : -x; +} diff --git a/circuitpython/lib/libm_dbl/tgamma.c b/circuitpython/lib/libm_dbl/tgamma.c new file mode 100644 index 0000000..d1d0a04 --- /dev/null +++ b/circuitpython/lib/libm_dbl/tgamma.c @@ -0,0 +1,222 @@ +/* +"A Precision Approximation of the Gamma Function" - Cornelius Lanczos (1964) +"Lanczos Implementation of the Gamma Function" - Paul Godfrey (2001) +"An Analysis of the Lanczos Gamma Approximation" - Glendon Ralph Pugh (2004) + +approximation method: + + (x - 0.5) S(x) +Gamma(x) = (x + g - 0.5) * ---------------- + exp(x + g - 0.5) + +with + a1 a2 a3 aN +S(x) ~= [ a0 + ----- + ----- + ----- + ... + ----- ] + x + 1 x + 2 x + 3 x + N + +with a0, a1, a2, a3,.. aN constants which depend on g. + +for x < 0 the following reflection formula is used: + +Gamma(x)*Gamma(-x) = -pi/(x sin(pi x)) + +most ideas and constants are from boost and python +*/ +#include "libm.h" + +static const double pi = 3.141592653589793238462643383279502884; + +/* sin(pi x) with x > 0x1p-100, if sin(pi*x)==0 the sign is arbitrary */ +static double sinpi(double x) +{ + int n; + + /* argument reduction: x = |x| mod 2 */ + /* spurious inexact when x is odd int */ + x = x * 0.5; + x = 2 * (x - floor(x)); + + /* reduce x into [-.25,.25] */ + n = 4 * x; + n = (n+1)/2; + x -= n * 0.5; + + x *= pi; + switch (n) { + default: /* case 4 */ + case 0: + return __sin(x, 0, 0); + case 1: + return __cos(x, 0); + case 2: + return __sin(-x, 0, 0); + case 3: + return -__cos(x, 0); + } +} + +#define N 12 +//static const double g = 6.024680040776729583740234375; +static const double gmhalf = 5.524680040776729583740234375; +static const double Snum[N+1] = { + 23531376880.410759688572007674451636754734846804940, + 42919803642.649098768957899047001988850926355848959, + 35711959237.355668049440185451547166705960488635843, + 17921034426.037209699919755754458931112671403265390, + 6039542586.3520280050642916443072979210699388420708, + 1439720407.3117216736632230727949123939715485786772, + 248874557.86205415651146038641322942321632125127801, + 31426415.585400194380614231628318205362874684987640, + 2876370.6289353724412254090516208496135991145378768, + 186056.26539522349504029498971604569928220784236328, + 8071.6720023658162106380029022722506138218516325024, + 210.82427775157934587250973392071336271166969580291, + 2.5066282746310002701649081771338373386264310793408, +}; +static const double Sden[N+1] = { + 0, 39916800, 120543840, 150917976, 105258076, 45995730, 13339535, + 2637558, 357423, 32670, 1925, 66, 1, +}; +/* n! for small integer n */ +static const double fact[] = { + 1, 1, 2, 6, 24, 120, 720, 5040.0, 40320.0, 362880.0, 3628800.0, 39916800.0, + 479001600.0, 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0, + 355687428096000.0, 6402373705728000.0, 121645100408832000.0, + 2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0, +}; + +/* S(x) rational function for positive x */ +static double S(double x) +{ + double_t num = 0, den = 0; + int i; + + /* to avoid overflow handle large x differently */ + if (x < 8) + for (i = N; i >= 0; i--) { + num = num * x + Snum[i]; + den = den * x + Sden[i]; + } + else + for (i = 0; i <= N; i++) { + num = num / x + Snum[i]; + den = den / x + Sden[i]; + } + return num/den; +} + +double tgamma(double x) +{ + union {double f; uint64_t i;} u = {x}; + double absx, y; + double_t dy, z, r; + uint32_t ix = u.i>>32 & 0x7fffffff; + int sign = u.i>>63; + + /* special cases */ + if (ix >= 0x7ff00000) + /* tgamma(nan)=nan, tgamma(inf)=inf, tgamma(-inf)=nan with invalid */ + return x + INFINITY; + if (ix < (0x3ff-54)<<20) + /* |x| < 2^-54: tgamma(x) ~ 1/x, +-0 raises div-by-zero */ + return 1/x; + + /* integer arguments */ + /* raise inexact when non-integer */ + if (x == floor(x)) { + if (sign) + return 0/0.0; + if (x <= sizeof fact/sizeof *fact) + return fact[(int)x - 1]; + } + + /* x >= 172: tgamma(x)=inf with overflow */ + /* x =< -184: tgamma(x)=+-0 with underflow */ + if (ix >= 0x40670000) { /* |x| >= 184 */ + if (sign) { + FORCE_EVAL((float)(0x1p-126/x)); + if (floor(x) * 0.5 == floor(x * 0.5)) + return 0; + return -0.0; + } + x *= 0x1p1023; + return x; + } + + absx = sign ? -x : x; + + /* handle the error of x + g - 0.5 */ + y = absx + gmhalf; + if (absx > gmhalf) { + dy = y - absx; + dy -= gmhalf; + } else { + dy = y - gmhalf; + dy -= absx; + } + + z = absx - 0.5; + r = S(absx) * exp(-y); + if (x < 0) { + /* reflection formula for negative x */ + /* sinpi(absx) is not 0, integers are already handled */ + r = -pi / (sinpi(absx) * absx * r); + dy = -dy; + z = -z; + } + r += dy * (gmhalf+0.5) * r / y; + z = pow(y, 0.5*z); + y = r * z * z; + return y; +} + +#if 1 +double __lgamma_r(double x, int *sign) +{ + double r, absx; + + *sign = 1; + + /* special cases */ + if (!isfinite(x)) + /* lgamma(nan)=nan, lgamma(+-inf)=inf */ + return x*x; + + /* integer arguments */ + if (x == floor(x) && x <= 2) { + /* n <= 0: lgamma(n)=inf with divbyzero */ + /* n == 1,2: lgamma(n)=0 */ + if (x <= 0) + return 1/0.0; + return 0; + } + + absx = fabs(x); + + /* lgamma(x) ~ -log(|x|) for tiny |x| */ + if (absx < 0x1p-54) { + *sign = 1 - 2*!!signbit(x); + return -log(absx); + } + + /* use tgamma for smaller |x| */ + if (absx < 128) { + x = tgamma(x); + *sign = 1 - 2*!!signbit(x); + return log(fabs(x)); + } + + /* second term (log(S)-g) could be more precise here.. */ + /* or with stirling: (|x|-0.5)*(log(|x|)-1) + poly(1/|x|) */ + r = (absx-0.5)*(log(absx+gmhalf)-1) + (log(S(absx)) - (gmhalf+0.5)); + if (x < 0) { + /* reflection formula for negative x */ + x = sinpi(absx); + *sign = 2*!!signbit(x) - 1; + r = log(pi/(fabs(x)*absx)) - r; + } + return r; +} + +//weak_alias(__lgamma_r, lgamma_r); +#endif diff --git a/circuitpython/lib/libm_dbl/thumb_vfp_sqrt.c b/circuitpython/lib/libm_dbl/thumb_vfp_sqrt.c new file mode 100644 index 0000000..dd37a07 --- /dev/null +++ b/circuitpython/lib/libm_dbl/thumb_vfp_sqrt.c @@ -0,0 +1,10 @@ +// an implementation of sqrt for Thumb using hardware double-precision VFP instructions + +double sqrt(double x) { + double ret; + asm volatile ( + "vsqrt.f64 %P0, %P1\n" + : "=w" (ret) + : "w" (x)); + return ret; +} diff --git a/circuitpython/lib/libm_dbl/trunc.c b/circuitpython/lib/libm_dbl/trunc.c new file mode 100644 index 0000000..d13711b --- /dev/null +++ b/circuitpython/lib/libm_dbl/trunc.c @@ -0,0 +1,19 @@ +#include "libm.h" + +double trunc(double x) +{ + union {double f; uint64_t i;} u = {x}; + int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12; + uint64_t m; + + if (e >= 52 + 12) + return x; + if (e < 12) + e = 1; + m = -1ULL >> e; + if ((u.i & m) == 0) + return x; + FORCE_EVAL(x + 0x1p120f); + u.i &= ~m; + return u.f; +} diff --git a/circuitpython/lib/littlefs/README.md b/circuitpython/lib/littlefs/README.md new file mode 100644 index 0000000..ca21a05 --- /dev/null +++ b/circuitpython/lib/littlefs/README.md @@ -0,0 +1,19 @@ +littlefs library +================ + +The upstream source for the files in this directory is +https://github.com/littlefs-project/littlefs + +To generate the separate files with lfs1 and lfs2 prefixes run the following +commands in the top-level directory of the littlefs repository (replace the +version tags with the latest/desired ones, and set `$MPY_DIR`): + + git checkout v1.7.2 + python2 ./scripts/prefix.py lfs1 + cp lfs1*.[ch] $MPY_DIR/lib/littlefs + git reset --hard HEAD + + git checkout v2.3.0 + python2 ./scripts/prefix.py lfs2 + cp lfs2*.[ch] $MPY_DIR/lib/littlefs + git reset --hard HEAD diff --git a/circuitpython/lib/littlefs/lfs1.c b/circuitpython/lib/littlefs/lfs1.c new file mode 100644 index 0000000..6a3fd67 --- /dev/null +++ b/circuitpython/lib/littlefs/lfs1.c @@ -0,0 +1,2583 @@ +/* + * The little filesystem + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "lfs1.h" +#include "lfs1_util.h" + +#include + + +/// Caching block device operations /// +static int lfs1_cache_read(lfs1_t *lfs1, lfs1_cache_t *rcache, + const lfs1_cache_t *pcache, lfs1_block_t block, + lfs1_off_t off, void *buffer, lfs1_size_t size) { + uint8_t *data = buffer; + LFS1_ASSERT(block < lfs1->cfg->block_count); + + while (size > 0) { + if (pcache && block == pcache->block && off >= pcache->off && + off < pcache->off + lfs1->cfg->prog_size) { + // is already in pcache? + lfs1_size_t diff = lfs1_min(size, + lfs1->cfg->prog_size - (off-pcache->off)); + memcpy(data, &pcache->buffer[off-pcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + if (block == rcache->block && off >= rcache->off && + off < rcache->off + lfs1->cfg->read_size) { + // is already in rcache? + lfs1_size_t diff = lfs1_min(size, + lfs1->cfg->read_size - (off-rcache->off)); + memcpy(data, &rcache->buffer[off-rcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + if (off % lfs1->cfg->read_size == 0 && size >= lfs1->cfg->read_size) { + // bypass cache? + lfs1_size_t diff = size - (size % lfs1->cfg->read_size); + int err = lfs1->cfg->read(lfs1->cfg, block, off, data, diff); + if (err) { + return err; + } + + data += diff; + off += diff; + size -= diff; + continue; + } + + // load to cache, first condition can no longer fail + rcache->block = block; + rcache->off = off - (off % lfs1->cfg->read_size); + int err = lfs1->cfg->read(lfs1->cfg, rcache->block, + rcache->off, rcache->buffer, lfs1->cfg->read_size); + if (err) { + return err; + } + } + + return 0; +} + +static int lfs1_cache_cmp(lfs1_t *lfs1, lfs1_cache_t *rcache, + const lfs1_cache_t *pcache, lfs1_block_t block, + lfs1_off_t off, const void *buffer, lfs1_size_t size) { + const uint8_t *data = buffer; + + for (lfs1_off_t i = 0; i < size; i++) { + uint8_t c; + int err = lfs1_cache_read(lfs1, rcache, pcache, + block, off+i, &c, 1); + if (err) { + return err; + } + + if (c != data[i]) { + return false; + } + } + + return true; +} + +static int lfs1_cache_crc(lfs1_t *lfs1, lfs1_cache_t *rcache, + const lfs1_cache_t *pcache, lfs1_block_t block, + lfs1_off_t off, lfs1_size_t size, uint32_t *crc) { + for (lfs1_off_t i = 0; i < size; i++) { + uint8_t c; + int err = lfs1_cache_read(lfs1, rcache, pcache, + block, off+i, &c, 1); + if (err) { + return err; + } + + lfs1_crc(crc, &c, 1); + } + + return 0; +} + +static inline void lfs1_cache_drop(lfs1_t *lfs1, lfs1_cache_t *rcache) { + // do not zero, cheaper if cache is readonly or only going to be + // written with identical data (during relocates) + (void)lfs1; + rcache->block = 0xffffffff; +} + +static inline void lfs1_cache_zero(lfs1_t *lfs1, lfs1_cache_t *pcache) { + // zero to avoid information leak + memset(pcache->buffer, 0xff, lfs1->cfg->prog_size); + pcache->block = 0xffffffff; +} + +static int lfs1_cache_flush(lfs1_t *lfs1, + lfs1_cache_t *pcache, lfs1_cache_t *rcache) { + if (pcache->block != 0xffffffff) { + int err = lfs1->cfg->prog(lfs1->cfg, pcache->block, + pcache->off, pcache->buffer, lfs1->cfg->prog_size); + if (err) { + return err; + } + + if (rcache) { + int res = lfs1_cache_cmp(lfs1, rcache, NULL, pcache->block, + pcache->off, pcache->buffer, lfs1->cfg->prog_size); + if (res < 0) { + return res; + } + + if (!res) { + return LFS1_ERR_CORRUPT; + } + } + + lfs1_cache_zero(lfs1, pcache); + } + + return 0; +} + +static int lfs1_cache_prog(lfs1_t *lfs1, lfs1_cache_t *pcache, + lfs1_cache_t *rcache, lfs1_block_t block, + lfs1_off_t off, const void *buffer, lfs1_size_t size) { + const uint8_t *data = buffer; + LFS1_ASSERT(block < lfs1->cfg->block_count); + + while (size > 0) { + if (block == pcache->block && off >= pcache->off && + off < pcache->off + lfs1->cfg->prog_size) { + // is already in pcache? + lfs1_size_t diff = lfs1_min(size, + lfs1->cfg->prog_size - (off-pcache->off)); + memcpy(&pcache->buffer[off-pcache->off], data, diff); + + data += diff; + off += diff; + size -= diff; + + if (off % lfs1->cfg->prog_size == 0) { + // eagerly flush out pcache if we fill up + int err = lfs1_cache_flush(lfs1, pcache, rcache); + if (err) { + return err; + } + } + + continue; + } + + // pcache must have been flushed, either by programming and + // entire block or manually flushing the pcache + LFS1_ASSERT(pcache->block == 0xffffffff); + + if (off % lfs1->cfg->prog_size == 0 && + size >= lfs1->cfg->prog_size) { + // bypass pcache? + lfs1_size_t diff = size - (size % lfs1->cfg->prog_size); + int err = lfs1->cfg->prog(lfs1->cfg, block, off, data, diff); + if (err) { + return err; + } + + if (rcache) { + int res = lfs1_cache_cmp(lfs1, rcache, NULL, + block, off, data, diff); + if (res < 0) { + return res; + } + + if (!res) { + return LFS1_ERR_CORRUPT; + } + } + + data += diff; + off += diff; + size -= diff; + continue; + } + + // prepare pcache, first condition can no longer fail + pcache->block = block; + pcache->off = off - (off % lfs1->cfg->prog_size); + } + + return 0; +} + + +/// General lfs1 block device operations /// +static int lfs1_bd_read(lfs1_t *lfs1, lfs1_block_t block, + lfs1_off_t off, void *buffer, lfs1_size_t size) { + // if we ever do more than writes to alternating pairs, + // this may need to consider pcache + return lfs1_cache_read(lfs1, &lfs1->rcache, NULL, + block, off, buffer, size); +} + +static int lfs1_bd_prog(lfs1_t *lfs1, lfs1_block_t block, + lfs1_off_t off, const void *buffer, lfs1_size_t size) { + return lfs1_cache_prog(lfs1, &lfs1->pcache, NULL, + block, off, buffer, size); +} + +static int lfs1_bd_cmp(lfs1_t *lfs1, lfs1_block_t block, + lfs1_off_t off, const void *buffer, lfs1_size_t size) { + return lfs1_cache_cmp(lfs1, &lfs1->rcache, NULL, block, off, buffer, size); +} + +static int lfs1_bd_crc(lfs1_t *lfs1, lfs1_block_t block, + lfs1_off_t off, lfs1_size_t size, uint32_t *crc) { + return lfs1_cache_crc(lfs1, &lfs1->rcache, NULL, block, off, size, crc); +} + +static int lfs1_bd_erase(lfs1_t *lfs1, lfs1_block_t block) { + return lfs1->cfg->erase(lfs1->cfg, block); +} + +static int lfs1_bd_sync(lfs1_t *lfs1) { + lfs1_cache_drop(lfs1, &lfs1->rcache); + + int err = lfs1_cache_flush(lfs1, &lfs1->pcache, NULL); + if (err) { + return err; + } + + return lfs1->cfg->sync(lfs1->cfg); +} + + +/// Internal operations predeclared here /// +int lfs1_traverse(lfs1_t *lfs1, int (*cb)(void*, lfs1_block_t), void *data); +static int lfs1_pred(lfs1_t *lfs1, const lfs1_block_t dir[2], lfs1_dir_t *pdir); +static int lfs1_parent(lfs1_t *lfs1, const lfs1_block_t dir[2], + lfs1_dir_t *parent, lfs1_entry_t *entry); +static int lfs1_moved(lfs1_t *lfs1, const void *e); +static int lfs1_relocate(lfs1_t *lfs1, + const lfs1_block_t oldpair[2], const lfs1_block_t newpair[2]); +int lfs1_deorphan(lfs1_t *lfs1); + + +/// Block allocator /// +static int lfs1_alloc_lookahead(void *p, lfs1_block_t block) { + lfs1_t *lfs1 = p; + + lfs1_block_t off = ((block - lfs1->free.off) + + lfs1->cfg->block_count) % lfs1->cfg->block_count; + + if (off < lfs1->free.size) { + lfs1->free.buffer[off / 32] |= 1U << (off % 32); + } + + return 0; +} + +static int lfs1_alloc(lfs1_t *lfs1, lfs1_block_t *block) { + while (true) { + while (lfs1->free.i != lfs1->free.size) { + lfs1_block_t off = lfs1->free.i; + lfs1->free.i += 1; + lfs1->free.ack -= 1; + + if (!(lfs1->free.buffer[off / 32] & (1U << (off % 32)))) { + // found a free block + *block = (lfs1->free.off + off) % lfs1->cfg->block_count; + + // eagerly find next off so an alloc ack can + // discredit old lookahead blocks + while (lfs1->free.i != lfs1->free.size && + (lfs1->free.buffer[lfs1->free.i / 32] + & (1U << (lfs1->free.i % 32)))) { + lfs1->free.i += 1; + lfs1->free.ack -= 1; + } + + return 0; + } + } + + // check if we have looked at all blocks since last ack + if (lfs1->free.ack == 0) { + LFS1_WARN("No more free space %" PRIu32, + lfs1->free.i + lfs1->free.off); + return LFS1_ERR_NOSPC; + } + + lfs1->free.off = (lfs1->free.off + lfs1->free.size) + % lfs1->cfg->block_count; + lfs1->free.size = lfs1_min(lfs1->cfg->lookahead, lfs1->free.ack); + lfs1->free.i = 0; + + // find mask of free blocks from tree + memset(lfs1->free.buffer, 0, lfs1->cfg->lookahead/8); + int err = lfs1_traverse(lfs1, lfs1_alloc_lookahead, lfs1); + if (err) { + return err; + } + } +} + +static void lfs1_alloc_ack(lfs1_t *lfs1) { + lfs1->free.ack = lfs1->cfg->block_count; +} + + +/// Endian swapping functions /// +static void lfs1_dir_fromle32(struct lfs1_disk_dir *d) { + d->rev = lfs1_fromle32(d->rev); + d->size = lfs1_fromle32(d->size); + d->tail[0] = lfs1_fromle32(d->tail[0]); + d->tail[1] = lfs1_fromle32(d->tail[1]); +} + +static void lfs1_dir_tole32(struct lfs1_disk_dir *d) { + d->rev = lfs1_tole32(d->rev); + d->size = lfs1_tole32(d->size); + d->tail[0] = lfs1_tole32(d->tail[0]); + d->tail[1] = lfs1_tole32(d->tail[1]); +} + +static void lfs1_entry_fromle32(struct lfs1_disk_entry *d) { + d->u.dir[0] = lfs1_fromle32(d->u.dir[0]); + d->u.dir[1] = lfs1_fromle32(d->u.dir[1]); +} + +static void lfs1_entry_tole32(struct lfs1_disk_entry *d) { + d->u.dir[0] = lfs1_tole32(d->u.dir[0]); + d->u.dir[1] = lfs1_tole32(d->u.dir[1]); +} + +static void lfs1_superblock_fromle32(struct lfs1_disk_superblock *d) { + d->root[0] = lfs1_fromle32(d->root[0]); + d->root[1] = lfs1_fromle32(d->root[1]); + d->block_size = lfs1_fromle32(d->block_size); + d->block_count = lfs1_fromle32(d->block_count); + d->version = lfs1_fromle32(d->version); +} + +static void lfs1_superblock_tole32(struct lfs1_disk_superblock *d) { + d->root[0] = lfs1_tole32(d->root[0]); + d->root[1] = lfs1_tole32(d->root[1]); + d->block_size = lfs1_tole32(d->block_size); + d->block_count = lfs1_tole32(d->block_count); + d->version = lfs1_tole32(d->version); +} + + +/// Metadata pair and directory operations /// +static inline void lfs1_pairswap(lfs1_block_t pair[2]) { + lfs1_block_t t = pair[0]; + pair[0] = pair[1]; + pair[1] = t; +} + +static inline bool lfs1_pairisnull(const lfs1_block_t pair[2]) { + return pair[0] == 0xffffffff || pair[1] == 0xffffffff; +} + +static inline int lfs1_paircmp( + const lfs1_block_t paira[2], + const lfs1_block_t pairb[2]) { + return !(paira[0] == pairb[0] || paira[1] == pairb[1] || + paira[0] == pairb[1] || paira[1] == pairb[0]); +} + +static inline bool lfs1_pairsync( + const lfs1_block_t paira[2], + const lfs1_block_t pairb[2]) { + return (paira[0] == pairb[0] && paira[1] == pairb[1]) || + (paira[0] == pairb[1] && paira[1] == pairb[0]); +} + +static inline lfs1_size_t lfs1_entry_size(const lfs1_entry_t *entry) { + return 4 + entry->d.elen + entry->d.alen + entry->d.nlen; +} + +static int lfs1_dir_alloc(lfs1_t *lfs1, lfs1_dir_t *dir) { + // allocate pair of dir blocks + for (int i = 0; i < 2; i++) { + int err = lfs1_alloc(lfs1, &dir->pair[i]); + if (err) { + return err; + } + } + + // rather than clobbering one of the blocks we just pretend + // the revision may be valid + int err = lfs1_bd_read(lfs1, dir->pair[0], 0, &dir->d.rev, 4); + if (err && err != LFS1_ERR_CORRUPT) { + return err; + } + + if (err != LFS1_ERR_CORRUPT) { + dir->d.rev = lfs1_fromle32(dir->d.rev); + } + + // set defaults + dir->d.rev += 1; + dir->d.size = sizeof(dir->d)+4; + dir->d.tail[0] = 0xffffffff; + dir->d.tail[1] = 0xffffffff; + dir->off = sizeof(dir->d); + + // don't write out yet, let caller take care of that + return 0; +} + +static int lfs1_dir_fetch(lfs1_t *lfs1, + lfs1_dir_t *dir, const lfs1_block_t pair[2]) { + // copy out pair, otherwise may be aliasing dir + const lfs1_block_t tpair[2] = {pair[0], pair[1]}; + bool valid = false; + + // check both blocks for the most recent revision + for (int i = 0; i < 2; i++) { + struct lfs1_disk_dir test; + int err = lfs1_bd_read(lfs1, tpair[i], 0, &test, sizeof(test)); + lfs1_dir_fromle32(&test); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + continue; + } + return err; + } + + if (valid && lfs1_scmp(test.rev, dir->d.rev) < 0) { + continue; + } + + if ((0x7fffffff & test.size) < sizeof(test)+4 || + (0x7fffffff & test.size) > lfs1->cfg->block_size) { + continue; + } + + uint32_t crc = 0xffffffff; + lfs1_dir_tole32(&test); + lfs1_crc(&crc, &test, sizeof(test)); + lfs1_dir_fromle32(&test); + err = lfs1_bd_crc(lfs1, tpair[i], sizeof(test), + (0x7fffffff & test.size) - sizeof(test), &crc); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + continue; + } + return err; + } + + if (crc != 0) { + continue; + } + + valid = true; + + // setup dir in case it's valid + dir->pair[0] = tpair[(i+0) % 2]; + dir->pair[1] = tpair[(i+1) % 2]; + dir->off = sizeof(dir->d); + dir->d = test; + } + + if (!valid) { + LFS1_ERROR("Corrupted dir pair at %" PRIu32 " %" PRIu32 , + tpair[0], tpair[1]); + return LFS1_ERR_CORRUPT; + } + + return 0; +} + +struct lfs1_region { + lfs1_off_t oldoff; + lfs1_size_t oldlen; + const void *newdata; + lfs1_size_t newlen; +}; + +static int lfs1_dir_commit(lfs1_t *lfs1, lfs1_dir_t *dir, + const struct lfs1_region *regions, int count) { + // increment revision count + dir->d.rev += 1; + + // keep pairs in order such that pair[0] is most recent + lfs1_pairswap(dir->pair); + for (int i = 0; i < count; i++) { + dir->d.size += regions[i].newlen - regions[i].oldlen; + } + + const lfs1_block_t oldpair[2] = {dir->pair[0], dir->pair[1]}; + bool relocated = false; + + while (true) { + if (true) { + int err = lfs1_bd_erase(lfs1, dir->pair[0]); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + uint32_t crc = 0xffffffff; + lfs1_dir_tole32(&dir->d); + lfs1_crc(&crc, &dir->d, sizeof(dir->d)); + err = lfs1_bd_prog(lfs1, dir->pair[0], 0, &dir->d, sizeof(dir->d)); + lfs1_dir_fromle32(&dir->d); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + int i = 0; + lfs1_off_t oldoff = sizeof(dir->d); + lfs1_off_t newoff = sizeof(dir->d); + while (newoff < (0x7fffffff & dir->d.size)-4) { + if (i < count && regions[i].oldoff == oldoff) { + lfs1_crc(&crc, regions[i].newdata, regions[i].newlen); + err = lfs1_bd_prog(lfs1, dir->pair[0], + newoff, regions[i].newdata, regions[i].newlen); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + oldoff += regions[i].oldlen; + newoff += regions[i].newlen; + i += 1; + } else { + uint8_t data; + err = lfs1_bd_read(lfs1, oldpair[1], oldoff, &data, 1); + if (err) { + return err; + } + + lfs1_crc(&crc, &data, 1); + err = lfs1_bd_prog(lfs1, dir->pair[0], newoff, &data, 1); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + oldoff += 1; + newoff += 1; + } + } + + crc = lfs1_tole32(crc); + err = lfs1_bd_prog(lfs1, dir->pair[0], newoff, &crc, 4); + crc = lfs1_fromle32(crc); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + err = lfs1_bd_sync(lfs1); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // successful commit, check checksum to make sure + uint32_t ncrc = 0xffffffff; + err = lfs1_bd_crc(lfs1, dir->pair[0], 0, + (0x7fffffff & dir->d.size)-4, &ncrc); + if (err) { + return err; + } + + if (ncrc != crc) { + goto relocate; + } + } + + break; +relocate: + //commit was corrupted + LFS1_DEBUG("Bad block at %" PRIu32, dir->pair[0]); + + // drop caches and prepare to relocate block + relocated = true; + lfs1_cache_drop(lfs1, &lfs1->pcache); + + // can't relocate superblock, filesystem is now frozen + if (lfs1_paircmp(oldpair, (const lfs1_block_t[2]){0, 1}) == 0) { + LFS1_WARN("Superblock %" PRIu32 " has become unwritable", + oldpair[0]); + return LFS1_ERR_CORRUPT; + } + + // relocate half of pair + int err = lfs1_alloc(lfs1, &dir->pair[0]); + if (err) { + return err; + } + } + + if (relocated) { + // update references if we relocated + LFS1_DEBUG("Relocating %" PRIu32 " %" PRIu32 " to %" PRIu32 " %" PRIu32, + oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]); + int err = lfs1_relocate(lfs1, oldpair, dir->pair); + if (err) { + return err; + } + } + + // shift over any directories that are affected + for (lfs1_dir_t *d = lfs1->dirs; d; d = d->next) { + if (lfs1_paircmp(d->pair, dir->pair) == 0) { + d->pair[0] = dir->pair[0]; + d->pair[1] = dir->pair[1]; + } + } + + return 0; +} + +static int lfs1_dir_update(lfs1_t *lfs1, lfs1_dir_t *dir, + lfs1_entry_t *entry, const void *data) { + lfs1_entry_tole32(&entry->d); + int err = lfs1_dir_commit(lfs1, dir, (struct lfs1_region[]){ + {entry->off, sizeof(entry->d), &entry->d, sizeof(entry->d)}, + {entry->off+sizeof(entry->d), entry->d.nlen, data, entry->d.nlen} + }, data ? 2 : 1); + lfs1_entry_fromle32(&entry->d); + return err; +} + +static int lfs1_dir_append(lfs1_t *lfs1, lfs1_dir_t *dir, + lfs1_entry_t *entry, const void *data) { + // check if we fit, if top bit is set we do not and move on + while (true) { + if (dir->d.size + lfs1_entry_size(entry) <= lfs1->cfg->block_size) { + entry->off = dir->d.size - 4; + + lfs1_entry_tole32(&entry->d); + int err = lfs1_dir_commit(lfs1, dir, (struct lfs1_region[]){ + {entry->off, 0, &entry->d, sizeof(entry->d)}, + {entry->off, 0, data, entry->d.nlen} + }, 2); + lfs1_entry_fromle32(&entry->d); + return err; + } + + // we need to allocate a new dir block + if (!(0x80000000 & dir->d.size)) { + lfs1_dir_t olddir = *dir; + int err = lfs1_dir_alloc(lfs1, dir); + if (err) { + return err; + } + + dir->d.tail[0] = olddir.d.tail[0]; + dir->d.tail[1] = olddir.d.tail[1]; + entry->off = dir->d.size - 4; + lfs1_entry_tole32(&entry->d); + err = lfs1_dir_commit(lfs1, dir, (struct lfs1_region[]){ + {entry->off, 0, &entry->d, sizeof(entry->d)}, + {entry->off, 0, data, entry->d.nlen} + }, 2); + lfs1_entry_fromle32(&entry->d); + if (err) { + return err; + } + + olddir.d.size |= 0x80000000; + olddir.d.tail[0] = dir->pair[0]; + olddir.d.tail[1] = dir->pair[1]; + return lfs1_dir_commit(lfs1, &olddir, NULL, 0); + } + + int err = lfs1_dir_fetch(lfs1, dir, dir->d.tail); + if (err) { + return err; + } + } +} + +static int lfs1_dir_remove(lfs1_t *lfs1, lfs1_dir_t *dir, lfs1_entry_t *entry) { + // check if we should just drop the directory block + if ((dir->d.size & 0x7fffffff) == sizeof(dir->d)+4 + + lfs1_entry_size(entry)) { + lfs1_dir_t pdir; + int res = lfs1_pred(lfs1, dir->pair, &pdir); + if (res < 0) { + return res; + } + + if (pdir.d.size & 0x80000000) { + pdir.d.size &= dir->d.size | 0x7fffffff; + pdir.d.tail[0] = dir->d.tail[0]; + pdir.d.tail[1] = dir->d.tail[1]; + return lfs1_dir_commit(lfs1, &pdir, NULL, 0); + } + } + + // shift out the entry + int err = lfs1_dir_commit(lfs1, dir, (struct lfs1_region[]){ + {entry->off, lfs1_entry_size(entry), NULL, 0}, + }, 1); + if (err) { + return err; + } + + // shift over any files/directories that are affected + for (lfs1_file_t *f = lfs1->files; f; f = f->next) { + if (lfs1_paircmp(f->pair, dir->pair) == 0) { + if (f->poff == entry->off) { + f->pair[0] = 0xffffffff; + f->pair[1] = 0xffffffff; + } else if (f->poff > entry->off) { + f->poff -= lfs1_entry_size(entry); + } + } + } + + for (lfs1_dir_t *d = lfs1->dirs; d; d = d->next) { + if (lfs1_paircmp(d->pair, dir->pair) == 0) { + if (d->off > entry->off) { + d->off -= lfs1_entry_size(entry); + d->pos -= lfs1_entry_size(entry); + } + } + } + + return 0; +} + +static int lfs1_dir_next(lfs1_t *lfs1, lfs1_dir_t *dir, lfs1_entry_t *entry) { + while (dir->off + sizeof(entry->d) > (0x7fffffff & dir->d.size)-4) { + if (!(0x80000000 & dir->d.size)) { + entry->off = dir->off; + return LFS1_ERR_NOENT; + } + + int err = lfs1_dir_fetch(lfs1, dir, dir->d.tail); + if (err) { + return err; + } + + dir->off = sizeof(dir->d); + dir->pos += sizeof(dir->d) + 4; + } + + int err = lfs1_bd_read(lfs1, dir->pair[0], dir->off, + &entry->d, sizeof(entry->d)); + lfs1_entry_fromle32(&entry->d); + if (err) { + return err; + } + + entry->off = dir->off; + dir->off += lfs1_entry_size(entry); + dir->pos += lfs1_entry_size(entry); + return 0; +} + +static int lfs1_dir_find(lfs1_t *lfs1, lfs1_dir_t *dir, + lfs1_entry_t *entry, const char **path) { + const char *pathname = *path; + size_t pathlen; + entry->d.type = LFS1_TYPE_DIR; + entry->d.elen = sizeof(entry->d) - 4; + entry->d.alen = 0; + entry->d.nlen = 0; + entry->d.u.dir[0] = lfs1->root[0]; + entry->d.u.dir[1] = lfs1->root[1]; + + while (true) { +nextname: + // skip slashes + pathname += strspn(pathname, "/"); + pathlen = strcspn(pathname, "/"); + + // skip '.' and root '..' + if ((pathlen == 1 && memcmp(pathname, ".", 1) == 0) || + (pathlen == 2 && memcmp(pathname, "..", 2) == 0)) { + pathname += pathlen; + goto nextname; + } + + // skip if matched by '..' in name + const char *suffix = pathname + pathlen; + size_t sufflen; + int depth = 1; + while (true) { + suffix += strspn(suffix, "/"); + sufflen = strcspn(suffix, "/"); + if (sufflen == 0) { + break; + } + + if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) { + depth -= 1; + if (depth == 0) { + pathname = suffix + sufflen; + goto nextname; + } + } else { + depth += 1; + } + + suffix += sufflen; + } + + // found path + if (pathname[0] == '\0') { + return 0; + } + + // update what we've found + *path = pathname; + + // continue on if we hit a directory + if (entry->d.type != LFS1_TYPE_DIR) { + return LFS1_ERR_NOTDIR; + } + + int err = lfs1_dir_fetch(lfs1, dir, entry->d.u.dir); + if (err) { + return err; + } + + // find entry matching name + while (true) { + err = lfs1_dir_next(lfs1, dir, entry); + if (err) { + return err; + } + + if (((0x7f & entry->d.type) != LFS1_TYPE_REG && + (0x7f & entry->d.type) != LFS1_TYPE_DIR) || + entry->d.nlen != pathlen) { + continue; + } + + int res = lfs1_bd_cmp(lfs1, dir->pair[0], + entry->off + 4+entry->d.elen+entry->d.alen, + pathname, pathlen); + if (res < 0) { + return res; + } + + // found match + if (res) { + break; + } + } + + // check that entry has not been moved + if (!lfs1->moving && entry->d.type & 0x80) { + int moved = lfs1_moved(lfs1, &entry->d.u); + if (moved < 0 || moved) { + return (moved < 0) ? moved : LFS1_ERR_NOENT; + } + + entry->d.type &= ~0x80; + } + + // to next name + pathname += pathlen; + } +} + + +/// Top level directory operations /// +int lfs1_mkdir(lfs1_t *lfs1, const char *path) { + // deorphan if we haven't yet, needed at most once after poweron + if (!lfs1->deorphaned) { + int err = lfs1_deorphan(lfs1); + if (err) { + return err; + } + } + + // fetch parent directory + lfs1_dir_t cwd; + lfs1_entry_t entry; + int err = lfs1_dir_find(lfs1, &cwd, &entry, &path); + if (err != LFS1_ERR_NOENT || strchr(path, '/') != NULL) { + return err ? err : LFS1_ERR_EXIST; + } + + // build up new directory + lfs1_alloc_ack(lfs1); + + lfs1_dir_t dir; + err = lfs1_dir_alloc(lfs1, &dir); + if (err) { + return err; + } + dir.d.tail[0] = cwd.d.tail[0]; + dir.d.tail[1] = cwd.d.tail[1]; + + err = lfs1_dir_commit(lfs1, &dir, NULL, 0); + if (err) { + return err; + } + + entry.d.type = LFS1_TYPE_DIR; + entry.d.elen = sizeof(entry.d) - 4; + entry.d.alen = 0; + entry.d.nlen = strlen(path); + entry.d.u.dir[0] = dir.pair[0]; + entry.d.u.dir[1] = dir.pair[1]; + + cwd.d.tail[0] = dir.pair[0]; + cwd.d.tail[1] = dir.pair[1]; + + err = lfs1_dir_append(lfs1, &cwd, &entry, path); + if (err) { + return err; + } + + lfs1_alloc_ack(lfs1); + return 0; +} + +int lfs1_dir_open(lfs1_t *lfs1, lfs1_dir_t *dir, const char *path) { + dir->pair[0] = lfs1->root[0]; + dir->pair[1] = lfs1->root[1]; + + lfs1_entry_t entry; + int err = lfs1_dir_find(lfs1, dir, &entry, &path); + if (err) { + return err; + } else if (entry.d.type != LFS1_TYPE_DIR) { + return LFS1_ERR_NOTDIR; + } + + err = lfs1_dir_fetch(lfs1, dir, entry.d.u.dir); + if (err) { + return err; + } + + // setup head dir + // special offset for '.' and '..' + dir->head[0] = dir->pair[0]; + dir->head[1] = dir->pair[1]; + dir->pos = sizeof(dir->d) - 2; + dir->off = sizeof(dir->d); + + // add to list of directories + dir->next = lfs1->dirs; + lfs1->dirs = dir; + + return 0; +} + +int lfs1_dir_close(lfs1_t *lfs1, lfs1_dir_t *dir) { + // remove from list of directories + for (lfs1_dir_t **p = &lfs1->dirs; *p; p = &(*p)->next) { + if (*p == dir) { + *p = dir->next; + break; + } + } + + return 0; +} + +int lfs1_dir_read(lfs1_t *lfs1, lfs1_dir_t *dir, struct lfs1_info *info) { + memset(info, 0, sizeof(*info)); + + // special offset for '.' and '..' + if (dir->pos == sizeof(dir->d) - 2) { + info->type = LFS1_TYPE_DIR; + strcpy(info->name, "."); + dir->pos += 1; + return 1; + } else if (dir->pos == sizeof(dir->d) - 1) { + info->type = LFS1_TYPE_DIR; + strcpy(info->name, ".."); + dir->pos += 1; + return 1; + } + + lfs1_entry_t entry; + while (true) { + int err = lfs1_dir_next(lfs1, dir, &entry); + if (err) { + return (err == LFS1_ERR_NOENT) ? 0 : err; + } + + if ((0x7f & entry.d.type) != LFS1_TYPE_REG && + (0x7f & entry.d.type) != LFS1_TYPE_DIR) { + continue; + } + + // check that entry has not been moved + if (entry.d.type & 0x80) { + int moved = lfs1_moved(lfs1, &entry.d.u); + if (moved < 0) { + return moved; + } + + if (moved) { + continue; + } + + entry.d.type &= ~0x80; + } + + break; + } + + info->type = entry.d.type; + if (info->type == LFS1_TYPE_REG) { + info->size = entry.d.u.file.size; + } + + int err = lfs1_bd_read(lfs1, dir->pair[0], + entry.off + 4+entry.d.elen+entry.d.alen, + info->name, entry.d.nlen); + if (err) { + return err; + } + + return 1; +} + +int lfs1_dir_seek(lfs1_t *lfs1, lfs1_dir_t *dir, lfs1_off_t off) { + // simply walk from head dir + int err = lfs1_dir_rewind(lfs1, dir); + if (err) { + return err; + } + dir->pos = off; + + while (off > (0x7fffffff & dir->d.size)) { + off -= 0x7fffffff & dir->d.size; + if (!(0x80000000 & dir->d.size)) { + return LFS1_ERR_INVAL; + } + + err = lfs1_dir_fetch(lfs1, dir, dir->d.tail); + if (err) { + return err; + } + } + + dir->off = off; + return 0; +} + +lfs1_soff_t lfs1_dir_tell(lfs1_t *lfs1, lfs1_dir_t *dir) { + (void)lfs1; + return dir->pos; +} + +int lfs1_dir_rewind(lfs1_t *lfs1, lfs1_dir_t *dir) { + // reload the head dir + int err = lfs1_dir_fetch(lfs1, dir, dir->head); + if (err) { + return err; + } + + dir->pair[0] = dir->head[0]; + dir->pair[1] = dir->head[1]; + dir->pos = sizeof(dir->d) - 2; + dir->off = sizeof(dir->d); + return 0; +} + + +/// File index list operations /// +static int lfs1_ctz_index(lfs1_t *lfs1, lfs1_off_t *off) { + lfs1_off_t size = *off; + lfs1_off_t b = lfs1->cfg->block_size - 2*4; + lfs1_off_t i = size / b; + if (i == 0) { + return 0; + } + + i = (size - 4*(lfs1_popc(i-1)+2)) / b; + *off = size - b*i - 4*lfs1_popc(i); + return i; +} + +static int lfs1_ctz_find(lfs1_t *lfs1, + lfs1_cache_t *rcache, const lfs1_cache_t *pcache, + lfs1_block_t head, lfs1_size_t size, + lfs1_size_t pos, lfs1_block_t *block, lfs1_off_t *off) { + if (size == 0) { + *block = 0xffffffff; + *off = 0; + return 0; + } + + lfs1_off_t current = lfs1_ctz_index(lfs1, &(lfs1_off_t){size-1}); + lfs1_off_t target = lfs1_ctz_index(lfs1, &pos); + + while (current > target) { + lfs1_size_t skip = lfs1_min( + lfs1_npw2(current-target+1) - 1, + lfs1_ctz(current)); + + int err = lfs1_cache_read(lfs1, rcache, pcache, head, 4*skip, &head, 4); + head = lfs1_fromle32(head); + if (err) { + return err; + } + + LFS1_ASSERT(head >= 2 && head <= lfs1->cfg->block_count); + current -= 1 << skip; + } + + *block = head; + *off = pos; + return 0; +} + +static int lfs1_ctz_extend(lfs1_t *lfs1, + lfs1_cache_t *rcache, lfs1_cache_t *pcache, + lfs1_block_t head, lfs1_size_t size, + lfs1_block_t *block, lfs1_off_t *off) { + while (true) { + // go ahead and grab a block + lfs1_block_t nblock; + int err = lfs1_alloc(lfs1, &nblock); + if (err) { + return err; + } + LFS1_ASSERT(nblock >= 2 && nblock <= lfs1->cfg->block_count); + + if (true) { + err = lfs1_bd_erase(lfs1, nblock); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + if (size == 0) { + *block = nblock; + *off = 0; + return 0; + } + + size -= 1; + lfs1_off_t index = lfs1_ctz_index(lfs1, &size); + size += 1; + + // just copy out the last block if it is incomplete + if (size != lfs1->cfg->block_size) { + for (lfs1_off_t i = 0; i < size; i++) { + uint8_t data; + err = lfs1_cache_read(lfs1, rcache, NULL, + head, i, &data, 1); + if (err) { + return err; + } + + err = lfs1_cache_prog(lfs1, pcache, rcache, + nblock, i, &data, 1); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + *block = nblock; + *off = size; + return 0; + } + + // append block + index += 1; + lfs1_size_t skips = lfs1_ctz(index) + 1; + + for (lfs1_off_t i = 0; i < skips; i++) { + head = lfs1_tole32(head); + err = lfs1_cache_prog(lfs1, pcache, rcache, + nblock, 4*i, &head, 4); + head = lfs1_fromle32(head); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + if (i != skips-1) { + err = lfs1_cache_read(lfs1, rcache, NULL, + head, 4*i, &head, 4); + head = lfs1_fromle32(head); + if (err) { + return err; + } + } + + LFS1_ASSERT(head >= 2 && head <= lfs1->cfg->block_count); + } + + *block = nblock; + *off = 4*skips; + return 0; + } + +relocate: + LFS1_DEBUG("Bad block at %" PRIu32, nblock); + + // just clear cache and try a new block + lfs1_cache_drop(lfs1, &lfs1->pcache); + } +} + +static int lfs1_ctz_traverse(lfs1_t *lfs1, + lfs1_cache_t *rcache, const lfs1_cache_t *pcache, + lfs1_block_t head, lfs1_size_t size, + int (*cb)(void*, lfs1_block_t), void *data) { + if (size == 0) { + return 0; + } + + lfs1_off_t index = lfs1_ctz_index(lfs1, &(lfs1_off_t){size-1}); + + while (true) { + int err = cb(data, head); + if (err) { + return err; + } + + if (index == 0) { + return 0; + } + + lfs1_block_t heads[2]; + int count = 2 - (index & 1); + err = lfs1_cache_read(lfs1, rcache, pcache, head, 0, &heads, count*4); + heads[0] = lfs1_fromle32(heads[0]); + heads[1] = lfs1_fromle32(heads[1]); + if (err) { + return err; + } + + for (int i = 0; i < count-1; i++) { + err = cb(data, heads[i]); + if (err) { + return err; + } + } + + head = heads[count-1]; + index -= count; + } +} + + +/// Top level file operations /// +int lfs1_file_opencfg(lfs1_t *lfs1, lfs1_file_t *file, + const char *path, int flags, + const struct lfs1_file_config *cfg) { + // deorphan if we haven't yet, needed at most once after poweron + if ((flags & 3) != LFS1_O_RDONLY && !lfs1->deorphaned) { + int err = lfs1_deorphan(lfs1); + if (err) { + return err; + } + } + + // allocate entry for file if it doesn't exist + lfs1_dir_t cwd; + lfs1_entry_t entry; + int err = lfs1_dir_find(lfs1, &cwd, &entry, &path); + if (err && (err != LFS1_ERR_NOENT || strchr(path, '/') != NULL)) { + return err; + } + + if (err == LFS1_ERR_NOENT) { + if (!(flags & LFS1_O_CREAT)) { + return LFS1_ERR_NOENT; + } + + // create entry to remember name + entry.d.type = LFS1_TYPE_REG; + entry.d.elen = sizeof(entry.d) - 4; + entry.d.alen = 0; + entry.d.nlen = strlen(path); + entry.d.u.file.head = 0xffffffff; + entry.d.u.file.size = 0; + err = lfs1_dir_append(lfs1, &cwd, &entry, path); + if (err) { + return err; + } + } else if (entry.d.type == LFS1_TYPE_DIR) { + return LFS1_ERR_ISDIR; + } else if (flags & LFS1_O_EXCL) { + return LFS1_ERR_EXIST; + } + + // setup file struct + file->cfg = cfg; + file->pair[0] = cwd.pair[0]; + file->pair[1] = cwd.pair[1]; + file->poff = entry.off; + file->head = entry.d.u.file.head; + file->size = entry.d.u.file.size; + file->flags = flags; + file->pos = 0; + + if (flags & LFS1_O_TRUNC) { + if (file->size != 0) { + file->flags |= LFS1_F_DIRTY; + } + file->head = 0xffffffff; + file->size = 0; + } + + // allocate buffer if needed + file->cache.block = 0xffffffff; + if (file->cfg && file->cfg->buffer) { + file->cache.buffer = file->cfg->buffer; + } else if (lfs1->cfg->file_buffer) { + if (lfs1->files) { + // already in use + return LFS1_ERR_NOMEM; + } + file->cache.buffer = lfs1->cfg->file_buffer; + } else if ((file->flags & 3) == LFS1_O_RDONLY) { + file->cache.buffer = lfs1_malloc(lfs1->cfg->read_size); + if (!file->cache.buffer) { + return LFS1_ERR_NOMEM; + } + } else { + file->cache.buffer = lfs1_malloc(lfs1->cfg->prog_size); + if (!file->cache.buffer) { + return LFS1_ERR_NOMEM; + } + } + + // zero to avoid information leak + lfs1_cache_drop(lfs1, &file->cache); + if ((file->flags & 3) != LFS1_O_RDONLY) { + lfs1_cache_zero(lfs1, &file->cache); + } + + // add to list of files + file->next = lfs1->files; + lfs1->files = file; + + return 0; +} + +int lfs1_file_open(lfs1_t *lfs1, lfs1_file_t *file, + const char *path, int flags) { + return lfs1_file_opencfg(lfs1, file, path, flags, NULL); +} + +int lfs1_file_close(lfs1_t *lfs1, lfs1_file_t *file) { + int err = lfs1_file_sync(lfs1, file); + + // remove from list of files + for (lfs1_file_t **p = &lfs1->files; *p; p = &(*p)->next) { + if (*p == file) { + *p = file->next; + break; + } + } + + // clean up memory + if (!(file->cfg && file->cfg->buffer) && !lfs1->cfg->file_buffer) { + lfs1_free(file->cache.buffer); + } + + return err; +} + +static int lfs1_file_relocate(lfs1_t *lfs1, lfs1_file_t *file) { +relocate: + LFS1_DEBUG("Bad block at %" PRIu32, file->block); + + // just relocate what exists into new block + lfs1_block_t nblock; + int err = lfs1_alloc(lfs1, &nblock); + if (err) { + return err; + } + + err = lfs1_bd_erase(lfs1, nblock); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // either read from dirty cache or disk + for (lfs1_off_t i = 0; i < file->off; i++) { + uint8_t data; + err = lfs1_cache_read(lfs1, &lfs1->rcache, &file->cache, + file->block, i, &data, 1); + if (err) { + return err; + } + + err = lfs1_cache_prog(lfs1, &lfs1->pcache, &lfs1->rcache, + nblock, i, &data, 1); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + // copy over new state of file + memcpy(file->cache.buffer, lfs1->pcache.buffer, lfs1->cfg->prog_size); + file->cache.block = lfs1->pcache.block; + file->cache.off = lfs1->pcache.off; + lfs1_cache_zero(lfs1, &lfs1->pcache); + + file->block = nblock; + return 0; +} + +static int lfs1_file_flush(lfs1_t *lfs1, lfs1_file_t *file) { + if (file->flags & LFS1_F_READING) { + // just drop read cache + lfs1_cache_drop(lfs1, &file->cache); + file->flags &= ~LFS1_F_READING; + } + + if (file->flags & LFS1_F_WRITING) { + lfs1_off_t pos = file->pos; + + // copy over anything after current branch + lfs1_file_t orig = { + .head = file->head, + .size = file->size, + .flags = LFS1_O_RDONLY, + .pos = file->pos, + .cache = lfs1->rcache, + }; + lfs1_cache_drop(lfs1, &lfs1->rcache); + + while (file->pos < file->size) { + // copy over a byte at a time, leave it up to caching + // to make this efficient + uint8_t data; + lfs1_ssize_t res = lfs1_file_read(lfs1, &orig, &data, 1); + if (res < 0) { + return res; + } + + res = lfs1_file_write(lfs1, file, &data, 1); + if (res < 0) { + return res; + } + + // keep our reference to the rcache in sync + if (lfs1->rcache.block != 0xffffffff) { + lfs1_cache_drop(lfs1, &orig.cache); + lfs1_cache_drop(lfs1, &lfs1->rcache); + } + } + + // write out what we have + while (true) { + int err = lfs1_cache_flush(lfs1, &file->cache, &lfs1->rcache); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + break; +relocate: + err = lfs1_file_relocate(lfs1, file); + if (err) { + return err; + } + } + + // actual file updates + file->head = file->block; + file->size = file->pos; + file->flags &= ~LFS1_F_WRITING; + file->flags |= LFS1_F_DIRTY; + + file->pos = pos; + } + + return 0; +} + +int lfs1_file_sync(lfs1_t *lfs1, lfs1_file_t *file) { + int err = lfs1_file_flush(lfs1, file); + if (err) { + return err; + } + + if ((file->flags & LFS1_F_DIRTY) && + !(file->flags & LFS1_F_ERRED) && + !lfs1_pairisnull(file->pair)) { + // update dir entry + lfs1_dir_t cwd; + err = lfs1_dir_fetch(lfs1, &cwd, file->pair); + if (err) { + return err; + } + + lfs1_entry_t entry = {.off = file->poff}; + err = lfs1_bd_read(lfs1, cwd.pair[0], entry.off, + &entry.d, sizeof(entry.d)); + lfs1_entry_fromle32(&entry.d); + if (err) { + return err; + } + + LFS1_ASSERT(entry.d.type == LFS1_TYPE_REG); + entry.d.u.file.head = file->head; + entry.d.u.file.size = file->size; + + err = lfs1_dir_update(lfs1, &cwd, &entry, NULL); + if (err) { + return err; + } + + file->flags &= ~LFS1_F_DIRTY; + } + + return 0; +} + +lfs1_ssize_t lfs1_file_read(lfs1_t *lfs1, lfs1_file_t *file, + void *buffer, lfs1_size_t size) { + uint8_t *data = buffer; + lfs1_size_t nsize = size; + + if ((file->flags & 3) == LFS1_O_WRONLY) { + return LFS1_ERR_BADF; + } + + if (file->flags & LFS1_F_WRITING) { + // flush out any writes + int err = lfs1_file_flush(lfs1, file); + if (err) { + return err; + } + } + + if (file->pos >= file->size) { + // eof if past end + return 0; + } + + size = lfs1_min(size, file->size - file->pos); + nsize = size; + + while (nsize > 0) { + // check if we need a new block + if (!(file->flags & LFS1_F_READING) || + file->off == lfs1->cfg->block_size) { + int err = lfs1_ctz_find(lfs1, &file->cache, NULL, + file->head, file->size, + file->pos, &file->block, &file->off); + if (err) { + return err; + } + + file->flags |= LFS1_F_READING; + } + + // read as much as we can in current block + lfs1_size_t diff = lfs1_min(nsize, lfs1->cfg->block_size - file->off); + int err = lfs1_cache_read(lfs1, &file->cache, NULL, + file->block, file->off, data, diff); + if (err) { + return err; + } + + file->pos += diff; + file->off += diff; + data += diff; + nsize -= diff; + } + + return size; +} + +lfs1_ssize_t lfs1_file_write(lfs1_t *lfs1, lfs1_file_t *file, + const void *buffer, lfs1_size_t size) { + const uint8_t *data = buffer; + lfs1_size_t nsize = size; + + if ((file->flags & 3) == LFS1_O_RDONLY) { + return LFS1_ERR_BADF; + } + + if (file->flags & LFS1_F_READING) { + // drop any reads + int err = lfs1_file_flush(lfs1, file); + if (err) { + return err; + } + } + + if ((file->flags & LFS1_O_APPEND) && file->pos < file->size) { + file->pos = file->size; + } + + if (file->pos + size > LFS1_FILE_MAX) { + // larger than file limit? + return LFS1_ERR_FBIG; + } + + if (!(file->flags & LFS1_F_WRITING) && file->pos > file->size) { + // fill with zeros + lfs1_off_t pos = file->pos; + file->pos = file->size; + + while (file->pos < pos) { + lfs1_ssize_t res = lfs1_file_write(lfs1, file, &(uint8_t){0}, 1); + if (res < 0) { + return res; + } + } + } + + while (nsize > 0) { + // check if we need a new block + if (!(file->flags & LFS1_F_WRITING) || + file->off == lfs1->cfg->block_size) { + if (!(file->flags & LFS1_F_WRITING) && file->pos > 0) { + // find out which block we're extending from + int err = lfs1_ctz_find(lfs1, &file->cache, NULL, + file->head, file->size, + file->pos-1, &file->block, &file->off); + if (err) { + file->flags |= LFS1_F_ERRED; + return err; + } + + // mark cache as dirty since we may have read data into it + lfs1_cache_zero(lfs1, &file->cache); + } + + // extend file with new blocks + lfs1_alloc_ack(lfs1); + int err = lfs1_ctz_extend(lfs1, &lfs1->rcache, &file->cache, + file->block, file->pos, + &file->block, &file->off); + if (err) { + file->flags |= LFS1_F_ERRED; + return err; + } + + file->flags |= LFS1_F_WRITING; + } + + // program as much as we can in current block + lfs1_size_t diff = lfs1_min(nsize, lfs1->cfg->block_size - file->off); + while (true) { + int err = lfs1_cache_prog(lfs1, &file->cache, &lfs1->rcache, + file->block, file->off, data, diff); + if (err) { + if (err == LFS1_ERR_CORRUPT) { + goto relocate; + } + file->flags |= LFS1_F_ERRED; + return err; + } + + break; +relocate: + err = lfs1_file_relocate(lfs1, file); + if (err) { + file->flags |= LFS1_F_ERRED; + return err; + } + } + + file->pos += diff; + file->off += diff; + data += diff; + nsize -= diff; + + lfs1_alloc_ack(lfs1); + } + + file->flags &= ~LFS1_F_ERRED; + return size; +} + +lfs1_soff_t lfs1_file_seek(lfs1_t *lfs1, lfs1_file_t *file, + lfs1_soff_t off, int whence) { + // write out everything beforehand, may be noop if rdonly + int err = lfs1_file_flush(lfs1, file); + if (err) { + return err; + } + + // find new pos + lfs1_soff_t npos = file->pos; + if (whence == LFS1_SEEK_SET) { + npos = off; + } else if (whence == LFS1_SEEK_CUR) { + npos = file->pos + off; + } else if (whence == LFS1_SEEK_END) { + npos = file->size + off; + } + + if (npos < 0 || npos > LFS1_FILE_MAX) { + // file position out of range + return LFS1_ERR_INVAL; + } + + // update pos + file->pos = npos; + return npos; +} + +int lfs1_file_truncate(lfs1_t *lfs1, lfs1_file_t *file, lfs1_off_t size) { + if ((file->flags & 3) == LFS1_O_RDONLY) { + return LFS1_ERR_BADF; + } + + lfs1_off_t oldsize = lfs1_file_size(lfs1, file); + if (size < oldsize) { + // need to flush since directly changing metadata + int err = lfs1_file_flush(lfs1, file); + if (err) { + return err; + } + + // lookup new head in ctz skip list + err = lfs1_ctz_find(lfs1, &file->cache, NULL, + file->head, file->size, + size, &file->head, &(lfs1_off_t){0}); + if (err) { + return err; + } + + file->size = size; + file->flags |= LFS1_F_DIRTY; + } else if (size > oldsize) { + lfs1_off_t pos = file->pos; + + // flush+seek if not already at end + if (file->pos != oldsize) { + int err = lfs1_file_seek(lfs1, file, 0, LFS1_SEEK_END); + if (err < 0) { + return err; + } + } + + // fill with zeros + while (file->pos < size) { + lfs1_ssize_t res = lfs1_file_write(lfs1, file, &(uint8_t){0}, 1); + if (res < 0) { + return res; + } + } + + // restore pos + int err = lfs1_file_seek(lfs1, file, pos, LFS1_SEEK_SET); + if (err < 0) { + return err; + } + } + + return 0; +} + +lfs1_soff_t lfs1_file_tell(lfs1_t *lfs1, lfs1_file_t *file) { + (void)lfs1; + return file->pos; +} + +int lfs1_file_rewind(lfs1_t *lfs1, lfs1_file_t *file) { + lfs1_soff_t res = lfs1_file_seek(lfs1, file, 0, LFS1_SEEK_SET); + if (res < 0) { + return res; + } + + return 0; +} + +lfs1_soff_t lfs1_file_size(lfs1_t *lfs1, lfs1_file_t *file) { + (void)lfs1; + if (file->flags & LFS1_F_WRITING) { + return lfs1_max(file->pos, file->size); + } else { + return file->size; + } +} + + +/// General fs operations /// +int lfs1_stat(lfs1_t *lfs1, const char *path, struct lfs1_info *info) { + lfs1_dir_t cwd; + lfs1_entry_t entry; + int err = lfs1_dir_find(lfs1, &cwd, &entry, &path); + if (err) { + return err; + } + + memset(info, 0, sizeof(*info)); + info->type = entry.d.type; + if (info->type == LFS1_TYPE_REG) { + info->size = entry.d.u.file.size; + } + + if (lfs1_paircmp(entry.d.u.dir, lfs1->root) == 0) { + strcpy(info->name, "/"); + } else { + err = lfs1_bd_read(lfs1, cwd.pair[0], + entry.off + 4+entry.d.elen+entry.d.alen, + info->name, entry.d.nlen); + if (err) { + return err; + } + } + + return 0; +} + +int lfs1_remove(lfs1_t *lfs1, const char *path) { + // deorphan if we haven't yet, needed at most once after poweron + if (!lfs1->deorphaned) { + int err = lfs1_deorphan(lfs1); + if (err) { + return err; + } + } + + lfs1_dir_t cwd; + lfs1_entry_t entry; + int err = lfs1_dir_find(lfs1, &cwd, &entry, &path); + if (err) { + return err; + } + + lfs1_dir_t dir; + if (entry.d.type == LFS1_TYPE_DIR) { + // must be empty before removal, checking size + // without masking top bit checks for any case where + // dir is not empty + err = lfs1_dir_fetch(lfs1, &dir, entry.d.u.dir); + if (err) { + return err; + } else if (dir.d.size != sizeof(dir.d)+4) { + return LFS1_ERR_NOTEMPTY; + } + } + + // remove the entry + err = lfs1_dir_remove(lfs1, &cwd, &entry); + if (err) { + return err; + } + + // if we were a directory, find pred, replace tail + if (entry.d.type == LFS1_TYPE_DIR) { + int res = lfs1_pred(lfs1, dir.pair, &cwd); + if (res < 0) { + return res; + } + + LFS1_ASSERT(res); // must have pred + cwd.d.tail[0] = dir.d.tail[0]; + cwd.d.tail[1] = dir.d.tail[1]; + + err = lfs1_dir_commit(lfs1, &cwd, NULL, 0); + if (err) { + return err; + } + } + + return 0; +} + +int lfs1_rename(lfs1_t *lfs1, const char *oldpath, const char *newpath) { + // deorphan if we haven't yet, needed at most once after poweron + if (!lfs1->deorphaned) { + int err = lfs1_deorphan(lfs1); + if (err) { + return err; + } + } + + // find old entry + lfs1_dir_t oldcwd; + lfs1_entry_t oldentry; + int err = lfs1_dir_find(lfs1, &oldcwd, &oldentry, &(const char *){oldpath}); + if (err) { + return err; + } + + // mark as moving + oldentry.d.type |= 0x80; + err = lfs1_dir_update(lfs1, &oldcwd, &oldentry, NULL); + if (err) { + return err; + } + + // allocate new entry + lfs1_dir_t newcwd; + lfs1_entry_t preventry; + err = lfs1_dir_find(lfs1, &newcwd, &preventry, &newpath); + if (err && (err != LFS1_ERR_NOENT || strchr(newpath, '/') != NULL)) { + return err; + } + + // must have same type + bool prevexists = (err != LFS1_ERR_NOENT); + if (prevexists && preventry.d.type != (0x7f & oldentry.d.type)) { + return LFS1_ERR_ISDIR; + } + + lfs1_dir_t dir; + if (prevexists && preventry.d.type == LFS1_TYPE_DIR) { + // must be empty before removal, checking size + // without masking top bit checks for any case where + // dir is not empty + err = lfs1_dir_fetch(lfs1, &dir, preventry.d.u.dir); + if (err) { + return err; + } else if (dir.d.size != sizeof(dir.d)+4) { + return LFS1_ERR_NOTEMPTY; + } + } + + // move to new location + lfs1_entry_t newentry = preventry; + newentry.d = oldentry.d; + newentry.d.type &= ~0x80; + newentry.d.nlen = strlen(newpath); + + if (prevexists) { + err = lfs1_dir_update(lfs1, &newcwd, &newentry, newpath); + if (err) { + return err; + } + } else { + err = lfs1_dir_append(lfs1, &newcwd, &newentry, newpath); + if (err) { + return err; + } + } + + // fetch old pair again in case dir block changed + lfs1->moving = true; + err = lfs1_dir_find(lfs1, &oldcwd, &oldentry, &oldpath); + if (err) { + return err; + } + lfs1->moving = false; + + // remove old entry + err = lfs1_dir_remove(lfs1, &oldcwd, &oldentry); + if (err) { + return err; + } + + // if we were a directory, find pred, replace tail + if (prevexists && preventry.d.type == LFS1_TYPE_DIR) { + int res = lfs1_pred(lfs1, dir.pair, &newcwd); + if (res < 0) { + return res; + } + + LFS1_ASSERT(res); // must have pred + newcwd.d.tail[0] = dir.d.tail[0]; + newcwd.d.tail[1] = dir.d.tail[1]; + + err = lfs1_dir_commit(lfs1, &newcwd, NULL, 0); + if (err) { + return err; + } + } + + return 0; +} + + +/// Filesystem operations /// +static void lfs1_deinit(lfs1_t *lfs1) { + // free allocated memory + if (!lfs1->cfg->read_buffer) { + lfs1_free(lfs1->rcache.buffer); + } + + if (!lfs1->cfg->prog_buffer) { + lfs1_free(lfs1->pcache.buffer); + } + + if (!lfs1->cfg->lookahead_buffer) { + lfs1_free(lfs1->free.buffer); + } +} + +static int lfs1_init(lfs1_t *lfs1, const struct lfs1_config *cfg) { + lfs1->cfg = cfg; + + // setup read cache + if (lfs1->cfg->read_buffer) { + lfs1->rcache.buffer = lfs1->cfg->read_buffer; + } else { + lfs1->rcache.buffer = lfs1_malloc(lfs1->cfg->read_size); + if (!lfs1->rcache.buffer) { + goto cleanup; + } + } + + // setup program cache + if (lfs1->cfg->prog_buffer) { + lfs1->pcache.buffer = lfs1->cfg->prog_buffer; + } else { + lfs1->pcache.buffer = lfs1_malloc(lfs1->cfg->prog_size); + if (!lfs1->pcache.buffer) { + goto cleanup; + } + } + + // zero to avoid information leaks + lfs1_cache_zero(lfs1, &lfs1->pcache); + lfs1_cache_drop(lfs1, &lfs1->rcache); + + // setup lookahead, round down to nearest 32-bits + LFS1_ASSERT(lfs1->cfg->lookahead % 32 == 0); + LFS1_ASSERT(lfs1->cfg->lookahead > 0); + if (lfs1->cfg->lookahead_buffer) { + lfs1->free.buffer = lfs1->cfg->lookahead_buffer; + } else { + lfs1->free.buffer = lfs1_malloc(lfs1->cfg->lookahead/8); + if (!lfs1->free.buffer) { + goto cleanup; + } + } + + // check that program and read sizes are multiples of the block size + LFS1_ASSERT(lfs1->cfg->prog_size % lfs1->cfg->read_size == 0); + LFS1_ASSERT(lfs1->cfg->block_size % lfs1->cfg->prog_size == 0); + + // check that the block size is large enough to fit ctz pointers + LFS1_ASSERT(4*lfs1_npw2(0xffffffff / (lfs1->cfg->block_size-2*4)) + <= lfs1->cfg->block_size); + + // setup default state + lfs1->root[0] = 0xffffffff; + lfs1->root[1] = 0xffffffff; + lfs1->files = NULL; + lfs1->dirs = NULL; + lfs1->deorphaned = false; + lfs1->moving = false; + + return 0; + +cleanup: + lfs1_deinit(lfs1); + return LFS1_ERR_NOMEM; +} + +int lfs1_format(lfs1_t *lfs1, const struct lfs1_config *cfg) { + int err = 0; + if (true) { + err = lfs1_init(lfs1, cfg); + if (err) { + return err; + } + + // create free lookahead + memset(lfs1->free.buffer, 0, lfs1->cfg->lookahead/8); + lfs1->free.off = 0; + lfs1->free.size = lfs1_min(lfs1->cfg->lookahead, lfs1->cfg->block_count); + lfs1->free.i = 0; + lfs1_alloc_ack(lfs1); + + // create superblock dir + lfs1_dir_t superdir; + err = lfs1_dir_alloc(lfs1, &superdir); + if (err) { + goto cleanup; + } + + // write root directory + lfs1_dir_t root; + err = lfs1_dir_alloc(lfs1, &root); + if (err) { + goto cleanup; + } + + err = lfs1_dir_commit(lfs1, &root, NULL, 0); + if (err) { + goto cleanup; + } + + lfs1->root[0] = root.pair[0]; + lfs1->root[1] = root.pair[1]; + + // write superblocks + lfs1_superblock_t superblock = { + .off = sizeof(superdir.d), + .d.type = LFS1_TYPE_SUPERBLOCK, + .d.elen = sizeof(superblock.d) - sizeof(superblock.d.magic) - 4, + .d.nlen = sizeof(superblock.d.magic), + .d.version = LFS1_DISK_VERSION, + .d.magic = {"littlefs"}, + .d.block_size = lfs1->cfg->block_size, + .d.block_count = lfs1->cfg->block_count, + .d.root = {lfs1->root[0], lfs1->root[1]}, + }; + superdir.d.tail[0] = root.pair[0]; + superdir.d.tail[1] = root.pair[1]; + superdir.d.size = sizeof(superdir.d) + sizeof(superblock.d) + 4; + + // write both pairs to be safe + lfs1_superblock_tole32(&superblock.d); + bool valid = false; + for (int i = 0; i < 2; i++) { + err = lfs1_dir_commit(lfs1, &superdir, (struct lfs1_region[]){ + {sizeof(superdir.d), sizeof(superblock.d), + &superblock.d, sizeof(superblock.d)} + }, 1); + if (err && err != LFS1_ERR_CORRUPT) { + goto cleanup; + } + + valid = valid || !err; + } + + if (!valid) { + err = LFS1_ERR_CORRUPT; + goto cleanup; + } + + // sanity check that fetch works + err = lfs1_dir_fetch(lfs1, &superdir, (const lfs1_block_t[2]){0, 1}); + if (err) { + goto cleanup; + } + + lfs1_alloc_ack(lfs1); + } + +cleanup: + lfs1_deinit(lfs1); + return err; +} + +int lfs1_mount(lfs1_t *lfs1, const struct lfs1_config *cfg) { + int err = 0; + if (true) { + err = lfs1_init(lfs1, cfg); + if (err) { + return err; + } + + // setup free lookahead + lfs1->free.off = 0; + lfs1->free.size = 0; + lfs1->free.i = 0; + lfs1_alloc_ack(lfs1); + + // load superblock + lfs1_dir_t dir; + lfs1_superblock_t superblock; + err = lfs1_dir_fetch(lfs1, &dir, (const lfs1_block_t[2]){0, 1}); + if (err && err != LFS1_ERR_CORRUPT) { + goto cleanup; + } + + if (!err) { + err = lfs1_bd_read(lfs1, dir.pair[0], sizeof(dir.d), + &superblock.d, sizeof(superblock.d)); + lfs1_superblock_fromle32(&superblock.d); + if (err) { + goto cleanup; + } + + lfs1->root[0] = superblock.d.root[0]; + lfs1->root[1] = superblock.d.root[1]; + } + + if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) { + LFS1_ERROR("Invalid superblock at %d %d", 0, 1); + err = LFS1_ERR_CORRUPT; + goto cleanup; + } + + uint16_t major_version = (0xffff & (superblock.d.version >> 16)); + uint16_t minor_version = (0xffff & (superblock.d.version >> 0)); + if ((major_version != LFS1_DISK_VERSION_MAJOR || + minor_version > LFS1_DISK_VERSION_MINOR)) { + LFS1_ERROR("Invalid version %d.%d", major_version, minor_version); + err = LFS1_ERR_INVAL; + goto cleanup; + } + + return 0; + } + +cleanup: + + lfs1_deinit(lfs1); + return err; +} + +int lfs1_unmount(lfs1_t *lfs1) { + lfs1_deinit(lfs1); + return 0; +} + + +/// Littlefs specific operations /// +int lfs1_traverse(lfs1_t *lfs1, int (*cb)(void*, lfs1_block_t), void *data) { + if (lfs1_pairisnull(lfs1->root)) { + return 0; + } + + // iterate over metadata pairs + lfs1_dir_t dir; + lfs1_entry_t entry; + lfs1_block_t cwd[2] = {0, 1}; + + while (true) { + for (int i = 0; i < 2; i++) { + int err = cb(data, cwd[i]); + if (err) { + return err; + } + } + + int err = lfs1_dir_fetch(lfs1, &dir, cwd); + if (err) { + return err; + } + + // iterate over contents + while (dir.off + sizeof(entry.d) <= (0x7fffffff & dir.d.size)-4) { + err = lfs1_bd_read(lfs1, dir.pair[0], dir.off, + &entry.d, sizeof(entry.d)); + lfs1_entry_fromle32(&entry.d); + if (err) { + return err; + } + + dir.off += lfs1_entry_size(&entry); + if ((0x70 & entry.d.type) == (0x70 & LFS1_TYPE_REG)) { + err = lfs1_ctz_traverse(lfs1, &lfs1->rcache, NULL, + entry.d.u.file.head, entry.d.u.file.size, cb, data); + if (err) { + return err; + } + } + } + + cwd[0] = dir.d.tail[0]; + cwd[1] = dir.d.tail[1]; + + if (lfs1_pairisnull(cwd)) { + break; + } + } + + // iterate over any open files + for (lfs1_file_t *f = lfs1->files; f; f = f->next) { + if (f->flags & LFS1_F_DIRTY) { + int err = lfs1_ctz_traverse(lfs1, &lfs1->rcache, &f->cache, + f->head, f->size, cb, data); + if (err) { + return err; + } + } + + if (f->flags & LFS1_F_WRITING) { + int err = lfs1_ctz_traverse(lfs1, &lfs1->rcache, &f->cache, + f->block, f->pos, cb, data); + if (err) { + return err; + } + } + } + + return 0; +} + +static int lfs1_pred(lfs1_t *lfs1, const lfs1_block_t dir[2], lfs1_dir_t *pdir) { + if (lfs1_pairisnull(lfs1->root)) { + return 0; + } + + // iterate over all directory directory entries + int err = lfs1_dir_fetch(lfs1, pdir, (const lfs1_block_t[2]){0, 1}); + if (err) { + return err; + } + + while (!lfs1_pairisnull(pdir->d.tail)) { + if (lfs1_paircmp(pdir->d.tail, dir) == 0) { + return true; + } + + err = lfs1_dir_fetch(lfs1, pdir, pdir->d.tail); + if (err) { + return err; + } + } + + return false; +} + +static int lfs1_parent(lfs1_t *lfs1, const lfs1_block_t dir[2], + lfs1_dir_t *parent, lfs1_entry_t *entry) { + if (lfs1_pairisnull(lfs1->root)) { + return 0; + } + + parent->d.tail[0] = 0; + parent->d.tail[1] = 1; + + // iterate over all directory directory entries + while (!lfs1_pairisnull(parent->d.tail)) { + int err = lfs1_dir_fetch(lfs1, parent, parent->d.tail); + if (err) { + return err; + } + + while (true) { + err = lfs1_dir_next(lfs1, parent, entry); + if (err && err != LFS1_ERR_NOENT) { + return err; + } + + if (err == LFS1_ERR_NOENT) { + break; + } + + if (((0x70 & entry->d.type) == (0x70 & LFS1_TYPE_DIR)) && + lfs1_paircmp(entry->d.u.dir, dir) == 0) { + return true; + } + } + } + + return false; +} + +static int lfs1_moved(lfs1_t *lfs1, const void *e) { + if (lfs1_pairisnull(lfs1->root)) { + return 0; + } + + // skip superblock + lfs1_dir_t cwd; + int err = lfs1_dir_fetch(lfs1, &cwd, (const lfs1_block_t[2]){0, 1}); + if (err) { + return err; + } + + // iterate over all directory directory entries + lfs1_entry_t entry; + while (!lfs1_pairisnull(cwd.d.tail)) { + err = lfs1_dir_fetch(lfs1, &cwd, cwd.d.tail); + if (err) { + return err; + } + + while (true) { + err = lfs1_dir_next(lfs1, &cwd, &entry); + if (err && err != LFS1_ERR_NOENT) { + return err; + } + + if (err == LFS1_ERR_NOENT) { + break; + } + + if (!(0x80 & entry.d.type) && + memcmp(&entry.d.u, e, sizeof(entry.d.u)) == 0) { + return true; + } + } + } + + return false; +} + +static int lfs1_relocate(lfs1_t *lfs1, + const lfs1_block_t oldpair[2], const lfs1_block_t newpair[2]) { + // find parent + lfs1_dir_t parent; + lfs1_entry_t entry; + int res = lfs1_parent(lfs1, oldpair, &parent, &entry); + if (res < 0) { + return res; + } + + if (res) { + // update disk, this creates a desync + entry.d.u.dir[0] = newpair[0]; + entry.d.u.dir[1] = newpair[1]; + + int err = lfs1_dir_update(lfs1, &parent, &entry, NULL); + if (err) { + return err; + } + + // update internal root + if (lfs1_paircmp(oldpair, lfs1->root) == 0) { + LFS1_DEBUG("Relocating root %" PRIu32 " %" PRIu32, + newpair[0], newpair[1]); + lfs1->root[0] = newpair[0]; + lfs1->root[1] = newpair[1]; + } + + // clean up bad block, which should now be a desync + return lfs1_deorphan(lfs1); + } + + // find pred + res = lfs1_pred(lfs1, oldpair, &parent); + if (res < 0) { + return res; + } + + if (res) { + // just replace bad pair, no desync can occur + parent.d.tail[0] = newpair[0]; + parent.d.tail[1] = newpair[1]; + + return lfs1_dir_commit(lfs1, &parent, NULL, 0); + } + + // couldn't find dir, must be new + return 0; +} + +int lfs1_deorphan(lfs1_t *lfs1) { + lfs1->deorphaned = true; + + if (lfs1_pairisnull(lfs1->root)) { + return 0; + } + + lfs1_dir_t pdir = {.d.size = 0x80000000}; + lfs1_dir_t cwd = {.d.tail[0] = 0, .d.tail[1] = 1}; + + // iterate over all directory directory entries + for (lfs1_size_t i = 0; i < lfs1->cfg->block_count; i++) { + if (lfs1_pairisnull(cwd.d.tail)) { + return 0; + } + + int err = lfs1_dir_fetch(lfs1, &cwd, cwd.d.tail); + if (err) { + return err; + } + + // check head blocks for orphans + if (!(0x80000000 & pdir.d.size)) { + // check if we have a parent + lfs1_dir_t parent; + lfs1_entry_t entry; + int res = lfs1_parent(lfs1, pdir.d.tail, &parent, &entry); + if (res < 0) { + return res; + } + + if (!res) { + // we are an orphan + LFS1_DEBUG("Found orphan %" PRIu32 " %" PRIu32, + pdir.d.tail[0], pdir.d.tail[1]); + + pdir.d.tail[0] = cwd.d.tail[0]; + pdir.d.tail[1] = cwd.d.tail[1]; + + err = lfs1_dir_commit(lfs1, &pdir, NULL, 0); + if (err) { + return err; + } + + return 0; + } + + if (!lfs1_pairsync(entry.d.u.dir, pdir.d.tail)) { + // we have desynced + LFS1_DEBUG("Found desync %" PRIu32 " %" PRIu32, + entry.d.u.dir[0], entry.d.u.dir[1]); + + pdir.d.tail[0] = entry.d.u.dir[0]; + pdir.d.tail[1] = entry.d.u.dir[1]; + + err = lfs1_dir_commit(lfs1, &pdir, NULL, 0); + if (err) { + return err; + } + + return 0; + } + } + + // check entries for moves + lfs1_entry_t entry; + while (true) { + err = lfs1_dir_next(lfs1, &cwd, &entry); + if (err && err != LFS1_ERR_NOENT) { + return err; + } + + if (err == LFS1_ERR_NOENT) { + break; + } + + // found moved entry + if (entry.d.type & 0x80) { + int moved = lfs1_moved(lfs1, &entry.d.u); + if (moved < 0) { + return moved; + } + + if (moved) { + LFS1_DEBUG("Found move %" PRIu32 " %" PRIu32, + entry.d.u.dir[0], entry.d.u.dir[1]); + err = lfs1_dir_remove(lfs1, &cwd, &entry); + if (err) { + return err; + } + } else { + LFS1_DEBUG("Found partial move %" PRIu32 " %" PRIu32, + entry.d.u.dir[0], entry.d.u.dir[1]); + entry.d.type &= ~0x80; + err = lfs1_dir_update(lfs1, &cwd, &entry, NULL); + if (err) { + return err; + } + } + } + } + + memcpy(&pdir, &cwd, sizeof(pdir)); + } + + // If we reached here, we have more directory pairs than blocks in the + // filesystem... So something must be horribly wrong + return LFS1_ERR_CORRUPT; +} diff --git a/circuitpython/lib/littlefs/lfs1.h b/circuitpython/lib/littlefs/lfs1.h new file mode 100644 index 0000000..355c145 --- /dev/null +++ b/circuitpython/lib/littlefs/lfs1.h @@ -0,0 +1,501 @@ +/* + * The little filesystem + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef LFS1_H +#define LFS1_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/// Version info /// + +// Software library version +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS1_VERSION 0x00010007 +#define LFS1_VERSION_MAJOR (0xffff & (LFS1_VERSION >> 16)) +#define LFS1_VERSION_MINOR (0xffff & (LFS1_VERSION >> 0)) + +// Version of On-disk data structures +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS1_DISK_VERSION 0x00010001 +#define LFS1_DISK_VERSION_MAJOR (0xffff & (LFS1_DISK_VERSION >> 16)) +#define LFS1_DISK_VERSION_MINOR (0xffff & (LFS1_DISK_VERSION >> 0)) + + +/// Definitions /// + +// Type definitions +typedef uint32_t lfs1_size_t; +typedef uint32_t lfs1_off_t; + +typedef int32_t lfs1_ssize_t; +typedef int32_t lfs1_soff_t; + +typedef uint32_t lfs1_block_t; + +// Max name size in bytes +#ifndef LFS1_NAME_MAX +#define LFS1_NAME_MAX 255 +#endif + +// Max file size in bytes +#ifndef LFS1_FILE_MAX +#define LFS1_FILE_MAX 2147483647 +#endif + +// Possible error codes, these are negative to allow +// valid positive return values +enum lfs1_error { + LFS1_ERR_OK = 0, // No error + LFS1_ERR_IO = -5, // Error during device operation + LFS1_ERR_CORRUPT = -52, // Corrupted + LFS1_ERR_NOENT = -2, // No directory entry + LFS1_ERR_EXIST = -17, // Entry already exists + LFS1_ERR_NOTDIR = -20, // Entry is not a dir + LFS1_ERR_ISDIR = -21, // Entry is a dir + LFS1_ERR_NOTEMPTY = -39, // Dir is not empty + LFS1_ERR_BADF = -9, // Bad file number + LFS1_ERR_FBIG = -27, // File too large + LFS1_ERR_INVAL = -22, // Invalid parameter + LFS1_ERR_NOSPC = -28, // No space left on device + LFS1_ERR_NOMEM = -12, // No more memory available +}; + +// File types +enum lfs1_type { + LFS1_TYPE_REG = 0x11, + LFS1_TYPE_DIR = 0x22, + LFS1_TYPE_SUPERBLOCK = 0x2e, +}; + +// File open flags +enum lfs1_open_flags { + // open flags + LFS1_O_RDONLY = 1, // Open a file as read only + LFS1_O_WRONLY = 2, // Open a file as write only + LFS1_O_RDWR = 3, // Open a file as read and write + LFS1_O_CREAT = 0x0100, // Create a file if it does not exist + LFS1_O_EXCL = 0x0200, // Fail if a file already exists + LFS1_O_TRUNC = 0x0400, // Truncate the existing file to zero size + LFS1_O_APPEND = 0x0800, // Move to end of file on every write + + // internally used flags + LFS1_F_DIRTY = 0x10000, // File does not match storage + LFS1_F_WRITING = 0x20000, // File has been written since last flush + LFS1_F_READING = 0x40000, // File has been read since last flush + LFS1_F_ERRED = 0x80000, // An error occured during write +}; + +// File seek flags +enum lfs1_whence_flags { + LFS1_SEEK_SET = 0, // Seek relative to an absolute position + LFS1_SEEK_CUR = 1, // Seek relative to the current file position + LFS1_SEEK_END = 2, // Seek relative to the end of the file +}; + + +// Configuration provided during initialization of the littlefs +struct lfs1_config { + // Opaque user provided context that can be used to pass + // information to the block device operations + void *context; + + // Read a region in a block. Negative error codes are propogated + // to the user. + int (*read)(const struct lfs1_config *c, lfs1_block_t block, + lfs1_off_t off, void *buffer, lfs1_size_t size); + + // Program a region in a block. The block must have previously + // been erased. Negative error codes are propogated to the user. + // May return LFS1_ERR_CORRUPT if the block should be considered bad. + int (*prog)(const struct lfs1_config *c, lfs1_block_t block, + lfs1_off_t off, const void *buffer, lfs1_size_t size); + + // Erase a block. A block must be erased before being programmed. + // The state of an erased block is undefined. Negative error codes + // are propogated to the user. + // May return LFS1_ERR_CORRUPT if the block should be considered bad. + int (*erase)(const struct lfs1_config *c, lfs1_block_t block); + + // Sync the state of the underlying block device. Negative error codes + // are propogated to the user. + int (*sync)(const struct lfs1_config *c); + + // Minimum size of a block read. This determines the size of read buffers. + // This may be larger than the physical read size to improve performance + // by caching more of the block device. + lfs1_size_t read_size; + + // Minimum size of a block program. This determines the size of program + // buffers. This may be larger than the physical program size to improve + // performance by caching more of the block device. + // Must be a multiple of the read size. + lfs1_size_t prog_size; + + // Size of an erasable block. This does not impact ram consumption and + // may be larger than the physical erase size. However, this should be + // kept small as each file currently takes up an entire block. + // Must be a multiple of the program size. + lfs1_size_t block_size; + + // Number of erasable blocks on the device. + lfs1_size_t block_count; + + // Number of blocks to lookahead during block allocation. A larger + // lookahead reduces the number of passes required to allocate a block. + // The lookahead buffer requires only 1 bit per block so it can be quite + // large with little ram impact. Should be a multiple of 32. + lfs1_size_t lookahead; + + // Optional, statically allocated read buffer. Must be read sized. + void *read_buffer; + + // Optional, statically allocated program buffer. Must be program sized. + void *prog_buffer; + + // Optional, statically allocated lookahead buffer. Must be 1 bit per + // lookahead block. + void *lookahead_buffer; + + // Optional, statically allocated buffer for files. Must be program sized. + // If enabled, only one file may be opened at a time. + void *file_buffer; +}; + +// Optional configuration provided during lfs1_file_opencfg +struct lfs1_file_config { + // Optional, statically allocated buffer for files. Must be program sized. + // If NULL, malloc will be used by default. + void *buffer; +}; + +// File info structure +struct lfs1_info { + // Type of the file, either LFS1_TYPE_REG or LFS1_TYPE_DIR + uint8_t type; + + // Size of the file, only valid for REG files + lfs1_size_t size; + + // Name of the file stored as a null-terminated string + char name[LFS1_NAME_MAX+1]; +}; + + +/// littlefs data structures /// +typedef struct lfs1_entry { + lfs1_off_t off; + + struct lfs1_disk_entry { + uint8_t type; + uint8_t elen; + uint8_t alen; + uint8_t nlen; + union { + struct { + lfs1_block_t head; + lfs1_size_t size; + } file; + lfs1_block_t dir[2]; + } u; + } d; +} lfs1_entry_t; + +typedef struct lfs1_cache { + lfs1_block_t block; + lfs1_off_t off; + uint8_t *buffer; +} lfs1_cache_t; + +typedef struct lfs1_file { + struct lfs1_file *next; + lfs1_block_t pair[2]; + lfs1_off_t poff; + + lfs1_block_t head; + lfs1_size_t size; + + const struct lfs1_file_config *cfg; + uint32_t flags; + lfs1_off_t pos; + lfs1_block_t block; + lfs1_off_t off; + lfs1_cache_t cache; +} lfs1_file_t; + +typedef struct lfs1_dir { + struct lfs1_dir *next; + lfs1_block_t pair[2]; + lfs1_off_t off; + + lfs1_block_t head[2]; + lfs1_off_t pos; + + struct lfs1_disk_dir { + uint32_t rev; + lfs1_size_t size; + lfs1_block_t tail[2]; + } d; +} lfs1_dir_t; + +typedef struct lfs1_superblock { + lfs1_off_t off; + + struct lfs1_disk_superblock { + uint8_t type; + uint8_t elen; + uint8_t alen; + uint8_t nlen; + lfs1_block_t root[2]; + uint32_t block_size; + uint32_t block_count; + uint32_t version; + char magic[8]; + } d; +} lfs1_superblock_t; + +typedef struct lfs1_free { + lfs1_block_t off; + lfs1_block_t size; + lfs1_block_t i; + lfs1_block_t ack; + uint32_t *buffer; +} lfs1_free_t; + +// The littlefs type +typedef struct lfs1 { + const struct lfs1_config *cfg; + + lfs1_block_t root[2]; + lfs1_file_t *files; + lfs1_dir_t *dirs; + + lfs1_cache_t rcache; + lfs1_cache_t pcache; + + lfs1_free_t free; + bool deorphaned; + bool moving; +} lfs1_t; + + +/// Filesystem functions /// + +// Format a block device with the littlefs +// +// Requires a littlefs object and config struct. This clobbers the littlefs +// object, and does not leave the filesystem mounted. The config struct must +// be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs1_format(lfs1_t *lfs1, const struct lfs1_config *config); + +// Mounts a littlefs +// +// Requires a littlefs object and config struct. Multiple filesystems +// may be mounted simultaneously with multiple littlefs objects. Both +// lfs1 and config must be allocated while mounted. The config struct must +// be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs1_mount(lfs1_t *lfs1, const struct lfs1_config *config); + +// Unmounts a littlefs +// +// Does nothing besides releasing any allocated resources. +// Returns a negative error code on failure. +int lfs1_unmount(lfs1_t *lfs1); + +/// General operations /// + +// Removes a file or directory +// +// If removing a directory, the directory must be empty. +// Returns a negative error code on failure. +int lfs1_remove(lfs1_t *lfs1, const char *path); + +// Rename or move a file or directory +// +// If the destination exists, it must match the source in type. +// If the destination is a directory, the directory must be empty. +// +// Returns a negative error code on failure. +int lfs1_rename(lfs1_t *lfs1, const char *oldpath, const char *newpath); + +// Find info about a file or directory +// +// Fills out the info structure, based on the specified file or directory. +// Returns a negative error code on failure. +int lfs1_stat(lfs1_t *lfs1, const char *path, struct lfs1_info *info); + + +/// File operations /// + +// Open a file +// +// The mode that the file is opened in is determined by the flags, which +// are values from the enum lfs1_open_flags that are bitwise-ored together. +// +// Returns a negative error code on failure. +int lfs1_file_open(lfs1_t *lfs1, lfs1_file_t *file, + const char *path, int flags); + +// Open a file with extra configuration +// +// The mode that the file is opened in is determined by the flags, which +// are values from the enum lfs1_open_flags that are bitwise-ored together. +// +// The config struct provides additional config options per file as described +// above. The config struct must be allocated while the file is open, and the +// config struct must be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs1_file_opencfg(lfs1_t *lfs1, lfs1_file_t *file, + const char *path, int flags, + const struct lfs1_file_config *config); + +// Close a file +// +// Any pending writes are written out to storage as though +// sync had been called and releases any allocated resources. +// +// Returns a negative error code on failure. +int lfs1_file_close(lfs1_t *lfs1, lfs1_file_t *file); + +// Synchronize a file on storage +// +// Any pending writes are written out to storage. +// Returns a negative error code on failure. +int lfs1_file_sync(lfs1_t *lfs1, lfs1_file_t *file); + +// Read data from file +// +// Takes a buffer and size indicating where to store the read data. +// Returns the number of bytes read, or a negative error code on failure. +lfs1_ssize_t lfs1_file_read(lfs1_t *lfs1, lfs1_file_t *file, + void *buffer, lfs1_size_t size); + +// Write data to file +// +// Takes a buffer and size indicating the data to write. The file will not +// actually be updated on the storage until either sync or close is called. +// +// Returns the number of bytes written, or a negative error code on failure. +lfs1_ssize_t lfs1_file_write(lfs1_t *lfs1, lfs1_file_t *file, + const void *buffer, lfs1_size_t size); + +// Change the position of the file +// +// The change in position is determined by the offset and whence flag. +// Returns the old position of the file, or a negative error code on failure. +lfs1_soff_t lfs1_file_seek(lfs1_t *lfs1, lfs1_file_t *file, + lfs1_soff_t off, int whence); + +// Truncates the size of the file to the specified size +// +// Returns a negative error code on failure. +int lfs1_file_truncate(lfs1_t *lfs1, lfs1_file_t *file, lfs1_off_t size); + +// Return the position of the file +// +// Equivalent to lfs1_file_seek(lfs1, file, 0, LFS1_SEEK_CUR) +// Returns the position of the file, or a negative error code on failure. +lfs1_soff_t lfs1_file_tell(lfs1_t *lfs1, lfs1_file_t *file); + +// Change the position of the file to the beginning of the file +// +// Equivalent to lfs1_file_seek(lfs1, file, 0, LFS1_SEEK_CUR) +// Returns a negative error code on failure. +int lfs1_file_rewind(lfs1_t *lfs1, lfs1_file_t *file); + +// Return the size of the file +// +// Similar to lfs1_file_seek(lfs1, file, 0, LFS1_SEEK_END) +// Returns the size of the file, or a negative error code on failure. +lfs1_soff_t lfs1_file_size(lfs1_t *lfs1, lfs1_file_t *file); + + +/// Directory operations /// + +// Create a directory +// +// Returns a negative error code on failure. +int lfs1_mkdir(lfs1_t *lfs1, const char *path); + +// Open a directory +// +// Once open a directory can be used with read to iterate over files. +// Returns a negative error code on failure. +int lfs1_dir_open(lfs1_t *lfs1, lfs1_dir_t *dir, const char *path); + +// Close a directory +// +// Releases any allocated resources. +// Returns a negative error code on failure. +int lfs1_dir_close(lfs1_t *lfs1, lfs1_dir_t *dir); + +// Read an entry in the directory +// +// Fills out the info structure, based on the specified file or directory. +// Returns a negative error code on failure. +int lfs1_dir_read(lfs1_t *lfs1, lfs1_dir_t *dir, struct lfs1_info *info); + +// Change the position of the directory +// +// The new off must be a value previous returned from tell and specifies +// an absolute offset in the directory seek. +// +// Returns a negative error code on failure. +int lfs1_dir_seek(lfs1_t *lfs1, lfs1_dir_t *dir, lfs1_off_t off); + +// Return the position of the directory +// +// The returned offset is only meant to be consumed by seek and may not make +// sense, but does indicate the current position in the directory iteration. +// +// Returns the position of the directory, or a negative error code on failure. +lfs1_soff_t lfs1_dir_tell(lfs1_t *lfs1, lfs1_dir_t *dir); + +// Change the position of the directory to the beginning of the directory +// +// Returns a negative error code on failure. +int lfs1_dir_rewind(lfs1_t *lfs1, lfs1_dir_t *dir); + + +/// Miscellaneous littlefs specific operations /// + +// Traverse through all blocks in use by the filesystem +// +// The provided callback will be called with each block address that is +// currently in use by the filesystem. This can be used to determine which +// blocks are in use or how much of the storage is available. +// +// Returns a negative error code on failure. +int lfs1_traverse(lfs1_t *lfs1, int (*cb)(void*, lfs1_block_t), void *data); + +// Prunes any recoverable errors that may have occured in the filesystem +// +// Not needed to be called by user unless an operation is interrupted +// but the filesystem is still mounted. This is already called on first +// allocation. +// +// Returns a negative error code on failure. +int lfs1_deorphan(lfs1_t *lfs1); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/circuitpython/lib/littlefs/lfs1_util.c b/circuitpython/lib/littlefs/lfs1_util.c new file mode 100644 index 0000000..3832a5d --- /dev/null +++ b/circuitpython/lib/littlefs/lfs1_util.c @@ -0,0 +1,31 @@ +/* + * lfs1 util functions + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "lfs1_util.h" + +// Only compile if user does not provide custom config +#ifndef LFS1_CONFIG + + +// Software CRC implementation with small lookup table +void lfs1_crc(uint32_t *restrict crc, const void *buffer, size_t size) { + static const uint32_t rtable[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c, + }; + + const uint8_t *data = buffer; + + for (size_t i = 0; i < size; i++) { + *crc = (*crc >> 4) ^ rtable[(*crc ^ (data[i] >> 0)) & 0xf]; + *crc = (*crc >> 4) ^ rtable[(*crc ^ (data[i] >> 4)) & 0xf]; + } +} + + +#endif diff --git a/circuitpython/lib/littlefs/lfs1_util.h b/circuitpython/lib/littlefs/lfs1_util.h new file mode 100644 index 0000000..b33b6a7 --- /dev/null +++ b/circuitpython/lib/littlefs/lfs1_util.h @@ -0,0 +1,186 @@ +/* + * lfs1 utility functions + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef LFS1_UTIL_H +#define LFS1_UTIL_H + +// Users can override lfs1_util.h with their own configuration by defining +// LFS1_CONFIG as a header file to include (-DLFS1_CONFIG=lfs1_config.h). +// +// If LFS1_CONFIG is used, none of the default utils will be emitted and must be +// provided by the config file. To start I would suggest copying lfs1_util.h and +// modifying as needed. +#ifdef LFS1_CONFIG +#define LFS1_STRINGIZE(x) LFS1_STRINGIZE2(x) +#define LFS1_STRINGIZE2(x) #x +#include LFS1_STRINGIZE(LFS1_CONFIG) +#else + +// System includes +#include +#include +#include + +#ifndef LFS1_NO_MALLOC +#include +#endif +#ifndef LFS1_NO_ASSERT +#include +#endif +#if !defined(LFS1_NO_DEBUG) || !defined(LFS1_NO_WARN) || !defined(LFS1_NO_ERROR) +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// Macros, may be replaced by system specific wrappers. Arguments to these +// macros must not have side-effects as the macros can be removed for a smaller +// code footprint + +// Logging functions +#ifndef LFS1_NO_DEBUG +#define LFS1_DEBUG(fmt, ...) \ + printf("lfs1 debug:%d: " fmt "\n", __LINE__, __VA_ARGS__) +#else +#define LFS1_DEBUG(fmt, ...) +#endif + +#ifndef LFS1_NO_WARN +#define LFS1_WARN(fmt, ...) \ + printf("lfs1 warn:%d: " fmt "\n", __LINE__, __VA_ARGS__) +#else +#define LFS1_WARN(fmt, ...) +#endif + +#ifndef LFS1_NO_ERROR +#define LFS1_ERROR(fmt, ...) \ + printf("lfs1 error:%d: " fmt "\n", __LINE__, __VA_ARGS__) +#else +#define LFS1_ERROR(fmt, ...) +#endif + +// Runtime assertions +#ifndef LFS1_NO_ASSERT +#define LFS1_ASSERT(test) assert(test) +#else +#define LFS1_ASSERT(test) +#endif + + +// Builtin functions, these may be replaced by more efficient +// toolchain-specific implementations. LFS1_NO_INTRINSICS falls back to a more +// expensive basic C implementation for debugging purposes + +// Min/max functions for unsigned 32-bit numbers +static inline uint32_t lfs1_max(uint32_t a, uint32_t b) { + return (a > b) ? a : b; +} + +static inline uint32_t lfs1_min(uint32_t a, uint32_t b) { + return (a < b) ? a : b; +} + +// Find the next smallest power of 2 less than or equal to a +static inline uint32_t lfs1_npw2(uint32_t a) { +#if !defined(LFS1_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return 32 - __builtin_clz(a-1); +#else + uint32_t r = 0; + uint32_t s; + a -= 1; + s = (a > 0xffff) << 4; a >>= s; r |= s; + s = (a > 0xff ) << 3; a >>= s; r |= s; + s = (a > 0xf ) << 2; a >>= s; r |= s; + s = (a > 0x3 ) << 1; a >>= s; r |= s; + return (r | (a >> 1)) + 1; +#endif +} + +// Count the number of trailing binary zeros in a +// lfs1_ctz(0) may be undefined +static inline uint32_t lfs1_ctz(uint32_t a) { +#if !defined(LFS1_NO_INTRINSICS) && defined(__GNUC__) + return __builtin_ctz(a); +#else + return lfs1_npw2((a & -a) + 1) - 1; +#endif +} + +// Count the number of binary ones in a +static inline uint32_t lfs1_popc(uint32_t a) { +#if !defined(LFS1_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return __builtin_popcount(a); +#else + a = a - ((a >> 1) & 0x55555555); + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); + return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; +#endif +} + +// Find the sequence comparison of a and b, this is the distance +// between a and b ignoring overflow +static inline int lfs1_scmp(uint32_t a, uint32_t b) { + return (int)(unsigned)(a - b); +} + +// Convert from 32-bit little-endian to native order +static inline uint32_t lfs1_fromle32(uint32_t a) { +#if !defined(LFS1_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + return a; +#elif !defined(LFS1_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + return __builtin_bswap32(a); +#else + return (((uint8_t*)&a)[0] << 0) | + (((uint8_t*)&a)[1] << 8) | + (((uint8_t*)&a)[2] << 16) | + (((uint8_t*)&a)[3] << 24); +#endif +} + +// Convert to 32-bit little-endian from native order +static inline uint32_t lfs1_tole32(uint32_t a) { + return lfs1_fromle32(a); +} + +// Calculate CRC-32 with polynomial = 0x04c11db7 +void lfs1_crc(uint32_t *crc, const void *buffer, size_t size); + +// Allocate memory, only used if buffers are not provided to littlefs +static inline void *lfs1_malloc(size_t size) { +#ifndef LFS1_NO_MALLOC + return malloc(size); +#else + (void)size; + return NULL; +#endif +} + +// Deallocate memory, only used if buffers are not provided to littlefs +static inline void lfs1_free(void *p) { +#ifndef LFS1_NO_MALLOC + free(p); +#else + (void)p; +#endif +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +#endif diff --git a/circuitpython/lib/littlefs/lfs2.c b/circuitpython/lib/littlefs/lfs2.c new file mode 100644 index 0000000..39bd2f0 --- /dev/null +++ b/circuitpython/lib/littlefs/lfs2.c @@ -0,0 +1,5391 @@ +/* + * The little filesystem + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "lfs2.h" +#include "lfs2_util.h" + +#define LFS2_BLOCK_NULL ((lfs2_block_t)-1) +#define LFS2_BLOCK_INLINE ((lfs2_block_t)-2) + +/// Caching block device operations /// +static inline void lfs2_cache_drop(lfs2_t *lfs2, lfs2_cache_t *rcache) { + // do not zero, cheaper if cache is readonly or only going to be + // written with identical data (during relocates) + (void)lfs2; + rcache->block = LFS2_BLOCK_NULL; +} + +static inline void lfs2_cache_zero(lfs2_t *lfs2, lfs2_cache_t *pcache) { + // zero to avoid information leak + memset(pcache->buffer, 0xff, lfs2->cfg->cache_size); + pcache->block = LFS2_BLOCK_NULL; +} + +static int lfs2_bd_read(lfs2_t *lfs2, + const lfs2_cache_t *pcache, lfs2_cache_t *rcache, lfs2_size_t hint, + lfs2_block_t block, lfs2_off_t off, + void *buffer, lfs2_size_t size) { + uint8_t *data = buffer; + if (block >= lfs2->cfg->block_count || + off+size > lfs2->cfg->block_size) { + return LFS2_ERR_CORRUPT; + } + + while (size > 0) { + lfs2_size_t diff = size; + + if (pcache && block == pcache->block && + off < pcache->off + pcache->size) { + if (off >= pcache->off) { + // is already in pcache? + diff = lfs2_min(diff, pcache->size - (off-pcache->off)); + memcpy(data, &pcache->buffer[off-pcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + // pcache takes priority + diff = lfs2_min(diff, pcache->off-off); + } + + if (block == rcache->block && + off < rcache->off + rcache->size) { + if (off >= rcache->off) { + // is already in rcache? + diff = lfs2_min(diff, rcache->size - (off-rcache->off)); + memcpy(data, &rcache->buffer[off-rcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + // rcache takes priority + diff = lfs2_min(diff, rcache->off-off); + } + + if (size >= hint && off % lfs2->cfg->read_size == 0 && + size >= lfs2->cfg->read_size) { + // bypass cache? + diff = lfs2_aligndown(diff, lfs2->cfg->read_size); + int err = lfs2->cfg->read(lfs2->cfg, block, off, data, diff); + if (err) { + return err; + } + + data += diff; + off += diff; + size -= diff; + continue; + } + + // load to cache, first condition can no longer fail + LFS2_ASSERT(block < lfs2->cfg->block_count); + rcache->block = block; + rcache->off = lfs2_aligndown(off, lfs2->cfg->read_size); + rcache->size = lfs2_min( + lfs2_min( + lfs2_alignup(off+hint, lfs2->cfg->read_size), + lfs2->cfg->block_size) + - rcache->off, + lfs2->cfg->cache_size); + int err = lfs2->cfg->read(lfs2->cfg, rcache->block, + rcache->off, rcache->buffer, rcache->size); + LFS2_ASSERT(err <= 0); + if (err) { + return err; + } + } + + return 0; +} + +enum { + LFS2_CMP_EQ = 0, + LFS2_CMP_LT = 1, + LFS2_CMP_GT = 2, +}; + +static int lfs2_bd_cmp(lfs2_t *lfs2, + const lfs2_cache_t *pcache, lfs2_cache_t *rcache, lfs2_size_t hint, + lfs2_block_t block, lfs2_off_t off, + const void *buffer, lfs2_size_t size) { + const uint8_t *data = buffer; + lfs2_size_t diff = 0; + + for (lfs2_off_t i = 0; i < size; i += diff) { + uint8_t dat[8]; + + diff = lfs2_min(size-i, sizeof(dat)); + int res = lfs2_bd_read(lfs2, + pcache, rcache, hint-i, + block, off+i, &dat, diff); + if (res) { + return res; + } + + res = memcmp(dat, data + i, diff); + if (res) { + return res < 0 ? LFS2_CMP_LT : LFS2_CMP_GT; + } + } + + return LFS2_CMP_EQ; +} + +#ifndef LFS2_READONLY +static int lfs2_bd_flush(lfs2_t *lfs2, + lfs2_cache_t *pcache, lfs2_cache_t *rcache, bool validate) { + if (pcache->block != LFS2_BLOCK_NULL && pcache->block != LFS2_BLOCK_INLINE) { + LFS2_ASSERT(pcache->block < lfs2->cfg->block_count); + lfs2_size_t diff = lfs2_alignup(pcache->size, lfs2->cfg->prog_size); + int err = lfs2->cfg->prog(lfs2->cfg, pcache->block, + pcache->off, pcache->buffer, diff); + LFS2_ASSERT(err <= 0); + if (err) { + return err; + } + + if (validate) { + // check data on disk + lfs2_cache_drop(lfs2, rcache); + int res = lfs2_bd_cmp(lfs2, + NULL, rcache, diff, + pcache->block, pcache->off, pcache->buffer, diff); + if (res < 0) { + return res; + } + + if (res != LFS2_CMP_EQ) { + return LFS2_ERR_CORRUPT; + } + } + + lfs2_cache_zero(lfs2, pcache); + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_bd_sync(lfs2_t *lfs2, + lfs2_cache_t *pcache, lfs2_cache_t *rcache, bool validate) { + lfs2_cache_drop(lfs2, rcache); + + int err = lfs2_bd_flush(lfs2, pcache, rcache, validate); + if (err) { + return err; + } + + err = lfs2->cfg->sync(lfs2->cfg); + LFS2_ASSERT(err <= 0); + return err; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_bd_prog(lfs2_t *lfs2, + lfs2_cache_t *pcache, lfs2_cache_t *rcache, bool validate, + lfs2_block_t block, lfs2_off_t off, + const void *buffer, lfs2_size_t size) { + const uint8_t *data = buffer; + LFS2_ASSERT(block == LFS2_BLOCK_INLINE || block < lfs2->cfg->block_count); + LFS2_ASSERT(off + size <= lfs2->cfg->block_size); + + while (size > 0) { + if (block == pcache->block && + off >= pcache->off && + off < pcache->off + lfs2->cfg->cache_size) { + // already fits in pcache? + lfs2_size_t diff = lfs2_min(size, + lfs2->cfg->cache_size - (off-pcache->off)); + memcpy(&pcache->buffer[off-pcache->off], data, diff); + + data += diff; + off += diff; + size -= diff; + + pcache->size = lfs2_max(pcache->size, off - pcache->off); + if (pcache->size == lfs2->cfg->cache_size) { + // eagerly flush out pcache if we fill up + int err = lfs2_bd_flush(lfs2, pcache, rcache, validate); + if (err) { + return err; + } + } + + continue; + } + + // pcache must have been flushed, either by programming and + // entire block or manually flushing the pcache + LFS2_ASSERT(pcache->block == LFS2_BLOCK_NULL); + + // prepare pcache, first condition can no longer fail + pcache->block = block; + pcache->off = lfs2_aligndown(off, lfs2->cfg->prog_size); + pcache->size = 0; + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_bd_erase(lfs2_t *lfs2, lfs2_block_t block) { + LFS2_ASSERT(block < lfs2->cfg->block_count); + int err = lfs2->cfg->erase(lfs2->cfg, block); + LFS2_ASSERT(err <= 0); + return err; +} +#endif + + +/// Small type-level utilities /// +// operations on block pairs +static inline void lfs2_pair_swap(lfs2_block_t pair[2]) { + lfs2_block_t t = pair[0]; + pair[0] = pair[1]; + pair[1] = t; +} + +static inline bool lfs2_pair_isnull(const lfs2_block_t pair[2]) { + return pair[0] == LFS2_BLOCK_NULL || pair[1] == LFS2_BLOCK_NULL; +} + +static inline int lfs2_pair_cmp( + const lfs2_block_t paira[2], + const lfs2_block_t pairb[2]) { + return !(paira[0] == pairb[0] || paira[1] == pairb[1] || + paira[0] == pairb[1] || paira[1] == pairb[0]); +} + +static inline bool lfs2_pair_sync( + const lfs2_block_t paira[2], + const lfs2_block_t pairb[2]) { + return (paira[0] == pairb[0] && paira[1] == pairb[1]) || + (paira[0] == pairb[1] && paira[1] == pairb[0]); +} + +static inline void lfs2_pair_fromle32(lfs2_block_t pair[2]) { + pair[0] = lfs2_fromle32(pair[0]); + pair[1] = lfs2_fromle32(pair[1]); +} + +static inline void lfs2_pair_tole32(lfs2_block_t pair[2]) { + pair[0] = lfs2_tole32(pair[0]); + pair[1] = lfs2_tole32(pair[1]); +} + +// operations on 32-bit entry tags +typedef uint32_t lfs2_tag_t; +typedef int32_t lfs2_stag_t; + +#define LFS2_MKTAG(type, id, size) \ + (((lfs2_tag_t)(type) << 20) | ((lfs2_tag_t)(id) << 10) | (lfs2_tag_t)(size)) + +#define LFS2_MKTAG_IF(cond, type, id, size) \ + ((cond) ? LFS2_MKTAG(type, id, size) : LFS2_MKTAG(LFS2_FROM_NOOP, 0, 0)) + +#define LFS2_MKTAG_IF_ELSE(cond, type1, id1, size1, type2, id2, size2) \ + ((cond) ? LFS2_MKTAG(type1, id1, size1) : LFS2_MKTAG(type2, id2, size2)) + +static inline bool lfs2_tag_isvalid(lfs2_tag_t tag) { + return !(tag & 0x80000000); +} + +static inline bool lfs2_tag_isdelete(lfs2_tag_t tag) { + return ((int32_t)(tag << 22) >> 22) == -1; +} + +static inline uint16_t lfs2_tag_type1(lfs2_tag_t tag) { + return (tag & 0x70000000) >> 20; +} + +static inline uint16_t lfs2_tag_type3(lfs2_tag_t tag) { + return (tag & 0x7ff00000) >> 20; +} + +static inline uint8_t lfs2_tag_chunk(lfs2_tag_t tag) { + return (tag & 0x0ff00000) >> 20; +} + +static inline int8_t lfs2_tag_splice(lfs2_tag_t tag) { + return (int8_t)lfs2_tag_chunk(tag); +} + +static inline uint16_t lfs2_tag_id(lfs2_tag_t tag) { + return (tag & 0x000ffc00) >> 10; +} + +static inline lfs2_size_t lfs2_tag_size(lfs2_tag_t tag) { + return tag & 0x000003ff; +} + +static inline lfs2_size_t lfs2_tag_dsize(lfs2_tag_t tag) { + return sizeof(tag) + lfs2_tag_size(tag + lfs2_tag_isdelete(tag)); +} + +// operations on attributes in attribute lists +struct lfs2_mattr { + lfs2_tag_t tag; + const void *buffer; +}; + +struct lfs2_diskoff { + lfs2_block_t block; + lfs2_off_t off; +}; + +#define LFS2_MKATTRS(...) \ + (struct lfs2_mattr[]){__VA_ARGS__}, \ + sizeof((struct lfs2_mattr[]){__VA_ARGS__}) / sizeof(struct lfs2_mattr) + +// operations on global state +static inline void lfs2_gstate_xor(lfs2_gstate_t *a, const lfs2_gstate_t *b) { + for (int i = 0; i < 3; i++) { + ((uint32_t*)a)[i] ^= ((const uint32_t*)b)[i]; + } +} + +static inline bool lfs2_gstate_iszero(const lfs2_gstate_t *a) { + for (int i = 0; i < 3; i++) { + if (((uint32_t*)a)[i] != 0) { + return false; + } + } + return true; +} + +static inline bool lfs2_gstate_hasorphans(const lfs2_gstate_t *a) { + return lfs2_tag_size(a->tag); +} + +static inline uint8_t lfs2_gstate_getorphans(const lfs2_gstate_t *a) { + return lfs2_tag_size(a->tag); +} + +static inline bool lfs2_gstate_hasmove(const lfs2_gstate_t *a) { + return lfs2_tag_type1(a->tag); +} + +static inline bool lfs2_gstate_hasmovehere(const lfs2_gstate_t *a, + const lfs2_block_t *pair) { + return lfs2_tag_type1(a->tag) && lfs2_pair_cmp(a->pair, pair) == 0; +} + +static inline void lfs2_gstate_fromle32(lfs2_gstate_t *a) { + a->tag = lfs2_fromle32(a->tag); + a->pair[0] = lfs2_fromle32(a->pair[0]); + a->pair[1] = lfs2_fromle32(a->pair[1]); +} + +static inline void lfs2_gstate_tole32(lfs2_gstate_t *a) { + a->tag = lfs2_tole32(a->tag); + a->pair[0] = lfs2_tole32(a->pair[0]); + a->pair[1] = lfs2_tole32(a->pair[1]); +} + +// other endianness operations +static void lfs2_ctz_fromle32(struct lfs2_ctz *ctz) { + ctz->head = lfs2_fromle32(ctz->head); + ctz->size = lfs2_fromle32(ctz->size); +} + +#ifndef LFS2_READONLY +static void lfs2_ctz_tole32(struct lfs2_ctz *ctz) { + ctz->head = lfs2_tole32(ctz->head); + ctz->size = lfs2_tole32(ctz->size); +} +#endif + +static inline void lfs2_superblock_fromle32(lfs2_superblock_t *superblock) { + superblock->version = lfs2_fromle32(superblock->version); + superblock->block_size = lfs2_fromle32(superblock->block_size); + superblock->block_count = lfs2_fromle32(superblock->block_count); + superblock->name_max = lfs2_fromle32(superblock->name_max); + superblock->file_max = lfs2_fromle32(superblock->file_max); + superblock->attr_max = lfs2_fromle32(superblock->attr_max); +} + +static inline void lfs2_superblock_tole32(lfs2_superblock_t *superblock) { + superblock->version = lfs2_tole32(superblock->version); + superblock->block_size = lfs2_tole32(superblock->block_size); + superblock->block_count = lfs2_tole32(superblock->block_count); + superblock->name_max = lfs2_tole32(superblock->name_max); + superblock->file_max = lfs2_tole32(superblock->file_max); + superblock->attr_max = lfs2_tole32(superblock->attr_max); +} + +#ifndef LFS2_NO_ASSERT +static inline bool lfs2_mlist_isopen(struct lfs2_mlist *head, + struct lfs2_mlist *node) { + for (struct lfs2_mlist **p = &head; *p; p = &(*p)->next) { + if (*p == (struct lfs2_mlist*)node) { + return true; + } + } + + return false; +} +#endif + +static inline void lfs2_mlist_remove(lfs2_t *lfs2, struct lfs2_mlist *mlist) { + for (struct lfs2_mlist **p = &lfs2->mlist; *p; p = &(*p)->next) { + if (*p == mlist) { + *p = (*p)->next; + break; + } + } +} + +static inline void lfs2_mlist_append(lfs2_t *lfs2, struct lfs2_mlist *mlist) { + mlist->next = lfs2->mlist; + lfs2->mlist = mlist; +} + + +/// Internal operations predeclared here /// +#ifndef LFS2_READONLY +static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, + const struct lfs2_mattr *attrs, int attrcount); +static int lfs2_dir_compact(lfs2_t *lfs2, + lfs2_mdir_t *dir, const struct lfs2_mattr *attrs, int attrcount, + lfs2_mdir_t *source, uint16_t begin, uint16_t end); + +static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, + const void *buffer, lfs2_size_t size); +static int lfs2_file_rawsync(lfs2_t *lfs2, lfs2_file_t *file); +static int lfs2_file_outline(lfs2_t *lfs2, lfs2_file_t *file); +static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file); + +static void lfs2_fs_preporphans(lfs2_t *lfs2, int8_t orphans); +static void lfs2_fs_prepmove(lfs2_t *lfs2, + uint16_t id, const lfs2_block_t pair[2]); +static int lfs2_fs_pred(lfs2_t *lfs2, const lfs2_block_t dir[2], + lfs2_mdir_t *pdir); +static lfs2_stag_t lfs2_fs_parent(lfs2_t *lfs2, const lfs2_block_t dir[2], + lfs2_mdir_t *parent); +static int lfs2_fs_relocate(lfs2_t *lfs2, + const lfs2_block_t oldpair[2], lfs2_block_t newpair[2]); +static int lfs2_fs_forceconsistency(lfs2_t *lfs2); +#endif + +#ifdef LFS2_MIGRATE +static int lfs21_traverse(lfs2_t *lfs2, + int (*cb)(void*, lfs2_block_t), void *data); +#endif + +static int lfs2_dir_rawrewind(lfs2_t *lfs2, lfs2_dir_t *dir); + +static lfs2_ssize_t lfs2_file_rawread(lfs2_t *lfs2, lfs2_file_t *file, + void *buffer, lfs2_size_t size); +static int lfs2_file_rawclose(lfs2_t *lfs2, lfs2_file_t *file); +static lfs2_soff_t lfs2_file_rawsize(lfs2_t *lfs2, lfs2_file_t *file); + +static lfs2_ssize_t lfs2_fs_rawsize(lfs2_t *lfs2); +static int lfs2_fs_rawtraverse(lfs2_t *lfs2, + int (*cb)(void *data, lfs2_block_t block), void *data, + bool includeorphans); + +static int lfs2_deinit(lfs2_t *lfs2); +static int lfs2_rawunmount(lfs2_t *lfs2); + + +/// Block allocator /// +#ifndef LFS2_READONLY +static int lfs2_alloc_lookahead(void *p, lfs2_block_t block) { + lfs2_t *lfs2 = (lfs2_t*)p; + lfs2_block_t off = ((block - lfs2->free.off) + + lfs2->cfg->block_count) % lfs2->cfg->block_count; + + if (off < lfs2->free.size) { + lfs2->free.buffer[off / 32] |= 1U << (off % 32); + } + + return 0; +} +#endif + +// indicate allocated blocks have been committed into the filesystem, this +// is to prevent blocks from being garbage collected in the middle of a +// commit operation +static void lfs2_alloc_ack(lfs2_t *lfs2) { + lfs2->free.ack = lfs2->cfg->block_count; +} + +// drop the lookahead buffer, this is done during mounting and failed +// traversals in order to avoid invalid lookahead state +static void lfs2_alloc_drop(lfs2_t *lfs2) { + lfs2->free.size = 0; + lfs2->free.i = 0; + lfs2_alloc_ack(lfs2); +} + +#ifndef LFS2_READONLY +static int lfs2_alloc(lfs2_t *lfs2, lfs2_block_t *block) { + while (true) { + while (lfs2->free.i != lfs2->free.size) { + lfs2_block_t off = lfs2->free.i; + lfs2->free.i += 1; + lfs2->free.ack -= 1; + + if (!(lfs2->free.buffer[off / 32] & (1U << (off % 32)))) { + // found a free block + *block = (lfs2->free.off + off) % lfs2->cfg->block_count; + + // eagerly find next off so an alloc ack can + // discredit old lookahead blocks + while (lfs2->free.i != lfs2->free.size && + (lfs2->free.buffer[lfs2->free.i / 32] + & (1U << (lfs2->free.i % 32)))) { + lfs2->free.i += 1; + lfs2->free.ack -= 1; + } + + return 0; + } + } + + // check if we have looked at all blocks since last ack + if (lfs2->free.ack == 0) { + LFS2_ERROR("No more free space %"PRIu32, + lfs2->free.i + lfs2->free.off); + return LFS2_ERR_NOSPC; + } + + lfs2->free.off = (lfs2->free.off + lfs2->free.size) + % lfs2->cfg->block_count; + lfs2->free.size = lfs2_min(8*lfs2->cfg->lookahead_size, lfs2->free.ack); + lfs2->free.i = 0; + + // find mask of free blocks from tree + memset(lfs2->free.buffer, 0, lfs2->cfg->lookahead_size); + int err = lfs2_fs_rawtraverse(lfs2, lfs2_alloc_lookahead, lfs2, true); + if (err) { + lfs2_alloc_drop(lfs2); + return err; + } + } +} +#endif + +/// Metadata pair and directory operations /// +static lfs2_stag_t lfs2_dir_getslice(lfs2_t *lfs2, const lfs2_mdir_t *dir, + lfs2_tag_t gmask, lfs2_tag_t gtag, + lfs2_off_t goff, void *gbuffer, lfs2_size_t gsize) { + lfs2_off_t off = dir->off; + lfs2_tag_t ntag = dir->etag; + lfs2_stag_t gdiff = 0; + + if (lfs2_gstate_hasmovehere(&lfs2->gdisk, dir->pair) && + lfs2_tag_id(gmask) != 0 && + lfs2_tag_id(lfs2->gdisk.tag) <= lfs2_tag_id(gtag)) { + // synthetic moves + gdiff -= LFS2_MKTAG(0, 1, 0); + } + + // iterate over dir block backwards (for faster lookups) + while (off >= sizeof(lfs2_tag_t) + lfs2_tag_dsize(ntag)) { + off -= lfs2_tag_dsize(ntag); + lfs2_tag_t tag = ntag; + int err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, sizeof(ntag), + dir->pair[0], off, &ntag, sizeof(ntag)); + if (err) { + return err; + } + + ntag = (lfs2_frombe32(ntag) ^ tag) & 0x7fffffff; + + if (lfs2_tag_id(gmask) != 0 && + lfs2_tag_type1(tag) == LFS2_TYPE_SPLICE && + lfs2_tag_id(tag) <= lfs2_tag_id(gtag - gdiff)) { + if (tag == (LFS2_MKTAG(LFS2_TYPE_CREATE, 0, 0) | + (LFS2_MKTAG(0, 0x3ff, 0) & (gtag - gdiff)))) { + // found where we were created + return LFS2_ERR_NOENT; + } + + // move around splices + gdiff += LFS2_MKTAG(0, lfs2_tag_splice(tag), 0); + } + + if ((gmask & tag) == (gmask & (gtag - gdiff))) { + if (lfs2_tag_isdelete(tag)) { + return LFS2_ERR_NOENT; + } + + lfs2_size_t diff = lfs2_min(lfs2_tag_size(tag), gsize); + err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, diff, + dir->pair[0], off+sizeof(tag)+goff, gbuffer, diff); + if (err) { + return err; + } + + memset((uint8_t*)gbuffer + diff, 0, gsize - diff); + + return tag + gdiff; + } + } + + return LFS2_ERR_NOENT; +} + +static lfs2_stag_t lfs2_dir_get(lfs2_t *lfs2, const lfs2_mdir_t *dir, + lfs2_tag_t gmask, lfs2_tag_t gtag, void *buffer) { + return lfs2_dir_getslice(lfs2, dir, + gmask, gtag, + 0, buffer, lfs2_tag_size(gtag)); +} + +static int lfs2_dir_getread(lfs2_t *lfs2, const lfs2_mdir_t *dir, + const lfs2_cache_t *pcache, lfs2_cache_t *rcache, lfs2_size_t hint, + lfs2_tag_t gmask, lfs2_tag_t gtag, + lfs2_off_t off, void *buffer, lfs2_size_t size) { + uint8_t *data = buffer; + if (off+size > lfs2->cfg->block_size) { + return LFS2_ERR_CORRUPT; + } + + while (size > 0) { + lfs2_size_t diff = size; + + if (pcache && pcache->block == LFS2_BLOCK_INLINE && + off < pcache->off + pcache->size) { + if (off >= pcache->off) { + // is already in pcache? + diff = lfs2_min(diff, pcache->size - (off-pcache->off)); + memcpy(data, &pcache->buffer[off-pcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + // pcache takes priority + diff = lfs2_min(diff, pcache->off-off); + } + + if (rcache->block == LFS2_BLOCK_INLINE && + off < rcache->off + rcache->size) { + if (off >= rcache->off) { + // is already in rcache? + diff = lfs2_min(diff, rcache->size - (off-rcache->off)); + memcpy(data, &rcache->buffer[off-rcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + // rcache takes priority + diff = lfs2_min(diff, rcache->off-off); + } + + // load to cache, first condition can no longer fail + rcache->block = LFS2_BLOCK_INLINE; + rcache->off = lfs2_aligndown(off, lfs2->cfg->read_size); + rcache->size = lfs2_min(lfs2_alignup(off+hint, lfs2->cfg->read_size), + lfs2->cfg->cache_size); + int err = lfs2_dir_getslice(lfs2, dir, gmask, gtag, + rcache->off, rcache->buffer, rcache->size); + if (err < 0) { + return err; + } + } + + return 0; +} + +#ifndef LFS2_READONLY +static int lfs2_dir_traverse_filter(void *p, + lfs2_tag_t tag, const void *buffer) { + lfs2_tag_t *filtertag = p; + (void)buffer; + + // which mask depends on unique bit in tag structure + uint32_t mask = (tag & LFS2_MKTAG(0x100, 0, 0)) + ? LFS2_MKTAG(0x7ff, 0x3ff, 0) + : LFS2_MKTAG(0x700, 0x3ff, 0); + + // check for redundancy + if ((mask & tag) == (mask & *filtertag) || + lfs2_tag_isdelete(*filtertag) || + (LFS2_MKTAG(0x7ff, 0x3ff, 0) & tag) == ( + LFS2_MKTAG(LFS2_TYPE_DELETE, 0, 0) | + (LFS2_MKTAG(0, 0x3ff, 0) & *filtertag))) { + return true; + } + + // check if we need to adjust for created/deleted tags + if (lfs2_tag_type1(tag) == LFS2_TYPE_SPLICE && + lfs2_tag_id(tag) <= lfs2_tag_id(*filtertag)) { + *filtertag += LFS2_MKTAG(0, lfs2_tag_splice(tag), 0); + } + + return false; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_traverse(lfs2_t *lfs2, + const lfs2_mdir_t *dir, lfs2_off_t off, lfs2_tag_t ptag, + const struct lfs2_mattr *attrs, int attrcount, + lfs2_tag_t tmask, lfs2_tag_t ttag, + uint16_t begin, uint16_t end, int16_t diff, + int (*cb)(void *data, lfs2_tag_t tag, const void *buffer), void *data) { + // iterate over directory and attrs + while (true) { + lfs2_tag_t tag; + const void *buffer; + struct lfs2_diskoff disk; + if (off+lfs2_tag_dsize(ptag) < dir->off) { + off += lfs2_tag_dsize(ptag); + int err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, sizeof(tag), + dir->pair[0], off, &tag, sizeof(tag)); + if (err) { + return err; + } + + tag = (lfs2_frombe32(tag) ^ ptag) | 0x80000000; + disk.block = dir->pair[0]; + disk.off = off+sizeof(lfs2_tag_t); + buffer = &disk; + ptag = tag; + } else if (attrcount > 0) { + tag = attrs[0].tag; + buffer = attrs[0].buffer; + attrs += 1; + attrcount -= 1; + } else { + return 0; + } + + lfs2_tag_t mask = LFS2_MKTAG(0x7ff, 0, 0); + if ((mask & tmask & tag) != (mask & tmask & ttag)) { + continue; + } + + // do we need to filter? inlining the filtering logic here allows + // for some minor optimizations + if (lfs2_tag_id(tmask) != 0) { + // scan for duplicates and update tag based on creates/deletes + int filter = lfs2_dir_traverse(lfs2, + dir, off, ptag, attrs, attrcount, + 0, 0, 0, 0, 0, + lfs2_dir_traverse_filter, &tag); + if (filter < 0) { + return filter; + } + + if (filter) { + continue; + } + + // in filter range? + if (!(lfs2_tag_id(tag) >= begin && lfs2_tag_id(tag) < end)) { + continue; + } + } + + // handle special cases for mcu-side operations + if (lfs2_tag_type3(tag) == LFS2_FROM_NOOP) { + // do nothing + } else if (lfs2_tag_type3(tag) == LFS2_FROM_MOVE) { + uint16_t fromid = lfs2_tag_size(tag); + uint16_t toid = lfs2_tag_id(tag); + int err = lfs2_dir_traverse(lfs2, + buffer, 0, 0xffffffff, NULL, 0, + LFS2_MKTAG(0x600, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, 0, 0), + fromid, fromid+1, toid-fromid+diff, + cb, data); + if (err) { + return err; + } + } else if (lfs2_tag_type3(tag) == LFS2_FROM_USERATTRS) { + for (unsigned i = 0; i < lfs2_tag_size(tag); i++) { + const struct lfs2_attr *a = buffer; + int err = cb(data, LFS2_MKTAG(LFS2_TYPE_USERATTR + a[i].type, + lfs2_tag_id(tag) + diff, a[i].size), a[i].buffer); + if (err) { + return err; + } + } + } else { + int err = cb(data, tag + LFS2_MKTAG(0, diff, 0), buffer); + if (err) { + return err; + } + } + } +} +#endif + +static lfs2_stag_t lfs2_dir_fetchmatch(lfs2_t *lfs2, + lfs2_mdir_t *dir, const lfs2_block_t pair[2], + lfs2_tag_t fmask, lfs2_tag_t ftag, uint16_t *id, + int (*cb)(void *data, lfs2_tag_t tag, const void *buffer), void *data) { + // we can find tag very efficiently during a fetch, since we're already + // scanning the entire directory + lfs2_stag_t besttag = -1; + + // if either block address is invalid we return LFS2_ERR_CORRUPT here, + // otherwise later writes to the pair could fail + if (pair[0] >= lfs2->cfg->block_count || pair[1] >= lfs2->cfg->block_count) { + return LFS2_ERR_CORRUPT; + } + + // find the block with the most recent revision + uint32_t revs[2] = {0, 0}; + int r = 0; + for (int i = 0; i < 2; i++) { + int err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, sizeof(revs[i]), + pair[i], 0, &revs[i], sizeof(revs[i])); + revs[i] = lfs2_fromle32(revs[i]); + if (err && err != LFS2_ERR_CORRUPT) { + return err; + } + + if (err != LFS2_ERR_CORRUPT && + lfs2_scmp(revs[i], revs[(i+1)%2]) > 0) { + r = i; + } + } + + dir->pair[0] = pair[(r+0)%2]; + dir->pair[1] = pair[(r+1)%2]; + dir->rev = revs[(r+0)%2]; + dir->off = 0; // nonzero = found some commits + + // now scan tags to fetch the actual dir and find possible match + for (int i = 0; i < 2; i++) { + lfs2_off_t off = 0; + lfs2_tag_t ptag = 0xffffffff; + + uint16_t tempcount = 0; + lfs2_block_t temptail[2] = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}; + bool tempsplit = false; + lfs2_stag_t tempbesttag = besttag; + + dir->rev = lfs2_tole32(dir->rev); + uint32_t crc = lfs2_crc(0xffffffff, &dir->rev, sizeof(dir->rev)); + dir->rev = lfs2_fromle32(dir->rev); + + while (true) { + // extract next tag + lfs2_tag_t tag; + off += lfs2_tag_dsize(ptag); + int err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, lfs2->cfg->block_size, + dir->pair[0], off, &tag, sizeof(tag)); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + // can't continue? + dir->erased = false; + break; + } + return err; + } + + crc = lfs2_crc(crc, &tag, sizeof(tag)); + tag = lfs2_frombe32(tag) ^ ptag; + + // next commit not yet programmed or we're not in valid range + if (!lfs2_tag_isvalid(tag)) { + dir->erased = (lfs2_tag_type1(ptag) == LFS2_TYPE_CRC && + dir->off % lfs2->cfg->prog_size == 0); + break; + } else if (off + lfs2_tag_dsize(tag) > lfs2->cfg->block_size) { + dir->erased = false; + break; + } + + ptag = tag; + + if (lfs2_tag_type1(tag) == LFS2_TYPE_CRC) { + // check the crc attr + uint32_t dcrc; + err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, lfs2->cfg->block_size, + dir->pair[0], off+sizeof(tag), &dcrc, sizeof(dcrc)); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + dir->erased = false; + break; + } + return err; + } + dcrc = lfs2_fromle32(dcrc); + + if (crc != dcrc) { + dir->erased = false; + break; + } + + // reset the next bit if we need to + ptag ^= (lfs2_tag_t)(lfs2_tag_chunk(tag) & 1U) << 31; + + // toss our crc into the filesystem seed for + // pseudorandom numbers, note we use another crc here + // as a collection function because it is sufficiently + // random and convenient + lfs2->seed = lfs2_crc(lfs2->seed, &crc, sizeof(crc)); + + // update with what's found so far + besttag = tempbesttag; + dir->off = off + lfs2_tag_dsize(tag); + dir->etag = ptag; + dir->count = tempcount; + dir->tail[0] = temptail[0]; + dir->tail[1] = temptail[1]; + dir->split = tempsplit; + + // reset crc + crc = 0xffffffff; + continue; + } + + // crc the entry first, hopefully leaving it in the cache + for (lfs2_off_t j = sizeof(tag); j < lfs2_tag_dsize(tag); j++) { + uint8_t dat; + err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, lfs2->cfg->block_size, + dir->pair[0], off+j, &dat, 1); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + dir->erased = false; + break; + } + return err; + } + + crc = lfs2_crc(crc, &dat, 1); + } + + // directory modification tags? + if (lfs2_tag_type1(tag) == LFS2_TYPE_NAME) { + // increase count of files if necessary + if (lfs2_tag_id(tag) >= tempcount) { + tempcount = lfs2_tag_id(tag) + 1; + } + } else if (lfs2_tag_type1(tag) == LFS2_TYPE_SPLICE) { + tempcount += lfs2_tag_splice(tag); + + if (tag == (LFS2_MKTAG(LFS2_TYPE_DELETE, 0, 0) | + (LFS2_MKTAG(0, 0x3ff, 0) & tempbesttag))) { + tempbesttag |= 0x80000000; + } else if (tempbesttag != -1 && + lfs2_tag_id(tag) <= lfs2_tag_id(tempbesttag)) { + tempbesttag += LFS2_MKTAG(0, lfs2_tag_splice(tag), 0); + } + } else if (lfs2_tag_type1(tag) == LFS2_TYPE_TAIL) { + tempsplit = (lfs2_tag_chunk(tag) & 1); + + err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, lfs2->cfg->block_size, + dir->pair[0], off+sizeof(tag), &temptail, 8); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + dir->erased = false; + break; + } + } + lfs2_pair_fromle32(temptail); + } + + // found a match for our fetcher? + if ((fmask & tag) == (fmask & ftag)) { + int res = cb(data, tag, &(struct lfs2_diskoff){ + dir->pair[0], off+sizeof(tag)}); + if (res < 0) { + if (res == LFS2_ERR_CORRUPT) { + dir->erased = false; + break; + } + return res; + } + + if (res == LFS2_CMP_EQ) { + // found a match + tempbesttag = tag; + } else if ((LFS2_MKTAG(0x7ff, 0x3ff, 0) & tag) == + (LFS2_MKTAG(0x7ff, 0x3ff, 0) & tempbesttag)) { + // found an identical tag, but contents didn't match + // this must mean that our besttag has been overwritten + tempbesttag = -1; + } else if (res == LFS2_CMP_GT && + lfs2_tag_id(tag) <= lfs2_tag_id(tempbesttag)) { + // found a greater match, keep track to keep things sorted + tempbesttag = tag | 0x80000000; + } + } + } + + // consider what we have good enough + if (dir->off > 0) { + // synthetic move + if (lfs2_gstate_hasmovehere(&lfs2->gdisk, dir->pair)) { + if (lfs2_tag_id(lfs2->gdisk.tag) == lfs2_tag_id(besttag)) { + besttag |= 0x80000000; + } else if (besttag != -1 && + lfs2_tag_id(lfs2->gdisk.tag) < lfs2_tag_id(besttag)) { + besttag -= LFS2_MKTAG(0, 1, 0); + } + } + + // found tag? or found best id? + if (id) { + *id = lfs2_min(lfs2_tag_id(besttag), dir->count); + } + + if (lfs2_tag_isvalid(besttag)) { + return besttag; + } else if (lfs2_tag_id(besttag) < dir->count) { + return LFS2_ERR_NOENT; + } else { + return 0; + } + } + + // failed, try the other block? + lfs2_pair_swap(dir->pair); + dir->rev = revs[(r+1)%2]; + } + + LFS2_ERROR("Corrupted dir pair at {0x%"PRIx32", 0x%"PRIx32"}", + dir->pair[0], dir->pair[1]); + return LFS2_ERR_CORRUPT; +} + +static int lfs2_dir_fetch(lfs2_t *lfs2, + lfs2_mdir_t *dir, const lfs2_block_t pair[2]) { + // note, mask=-1, tag=-1 can never match a tag since this + // pattern has the invalid bit set + return (int)lfs2_dir_fetchmatch(lfs2, dir, pair, + (lfs2_tag_t)-1, (lfs2_tag_t)-1, NULL, NULL, NULL); +} + +static int lfs2_dir_getgstate(lfs2_t *lfs2, const lfs2_mdir_t *dir, + lfs2_gstate_t *gstate) { + lfs2_gstate_t temp; + lfs2_stag_t res = lfs2_dir_get(lfs2, dir, LFS2_MKTAG(0x7ff, 0, 0), + LFS2_MKTAG(LFS2_TYPE_MOVESTATE, 0, sizeof(temp)), &temp); + if (res < 0 && res != LFS2_ERR_NOENT) { + return res; + } + + if (res != LFS2_ERR_NOENT) { + // xor together to find resulting gstate + lfs2_gstate_fromle32(&temp); + lfs2_gstate_xor(gstate, &temp); + } + + return 0; +} + +static int lfs2_dir_getinfo(lfs2_t *lfs2, lfs2_mdir_t *dir, + uint16_t id, struct lfs2_info *info) { + if (id == 0x3ff) { + // special case for root + strcpy(info->name, "/"); + info->type = LFS2_TYPE_DIR; + return 0; + } + + lfs2_stag_t tag = lfs2_dir_get(lfs2, dir, LFS2_MKTAG(0x780, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_NAME, id, lfs2->name_max+1), info->name); + if (tag < 0) { + return (int)tag; + } + + info->type = lfs2_tag_type3(tag); + + struct lfs2_ctz ctz; + tag = lfs2_dir_get(lfs2, dir, LFS2_MKTAG(0x700, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, id, sizeof(ctz)), &ctz); + if (tag < 0) { + return (int)tag; + } + lfs2_ctz_fromle32(&ctz); + + if (lfs2_tag_type3(tag) == LFS2_TYPE_CTZSTRUCT) { + info->size = ctz.size; + } else if (lfs2_tag_type3(tag) == LFS2_TYPE_INLINESTRUCT) { + info->size = lfs2_tag_size(tag); + } + + return 0; +} + +struct lfs2_dir_find_match { + lfs2_t *lfs2; + const void *name; + lfs2_size_t size; +}; + +static int lfs2_dir_find_match(void *data, + lfs2_tag_t tag, const void *buffer) { + struct lfs2_dir_find_match *name = data; + lfs2_t *lfs2 = name->lfs2; + const struct lfs2_diskoff *disk = buffer; + + // compare with disk + lfs2_size_t diff = lfs2_min(name->size, lfs2_tag_size(tag)); + int res = lfs2_bd_cmp(lfs2, + NULL, &lfs2->rcache, diff, + disk->block, disk->off, name->name, diff); + if (res != LFS2_CMP_EQ) { + return res; + } + + // only equal if our size is still the same + if (name->size != lfs2_tag_size(tag)) { + return (name->size < lfs2_tag_size(tag)) ? LFS2_CMP_LT : LFS2_CMP_GT; + } + + // found a match! + return LFS2_CMP_EQ; +} + +static lfs2_stag_t lfs2_dir_find(lfs2_t *lfs2, lfs2_mdir_t *dir, + const char **path, uint16_t *id) { + // we reduce path to a single name if we can find it + const char *name = *path; + if (id) { + *id = 0x3ff; + } + + // default to root dir + lfs2_stag_t tag = LFS2_MKTAG(LFS2_TYPE_DIR, 0x3ff, 0); + dir->tail[0] = lfs2->root[0]; + dir->tail[1] = lfs2->root[1]; + + while (true) { +nextname: + // skip slashes + name += strspn(name, "/"); + lfs2_size_t namelen = strcspn(name, "/"); + + // skip '.' and root '..' + if ((namelen == 1 && memcmp(name, ".", 1) == 0) || + (namelen == 2 && memcmp(name, "..", 2) == 0)) { + name += namelen; + goto nextname; + } + + // skip if matched by '..' in name + const char *suffix = name + namelen; + lfs2_size_t sufflen; + int depth = 1; + while (true) { + suffix += strspn(suffix, "/"); + sufflen = strcspn(suffix, "/"); + if (sufflen == 0) { + break; + } + + if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) { + depth -= 1; + if (depth == 0) { + name = suffix + sufflen; + goto nextname; + } + } else { + depth += 1; + } + + suffix += sufflen; + } + + // found path + if (name[0] == '\0') { + return tag; + } + + // update what we've found so far + *path = name; + + // only continue if we hit a directory + if (lfs2_tag_type3(tag) != LFS2_TYPE_DIR) { + return LFS2_ERR_NOTDIR; + } + + // grab the entry data + if (lfs2_tag_id(tag) != 0x3ff) { + lfs2_stag_t res = lfs2_dir_get(lfs2, dir, LFS2_MKTAG(0x700, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, lfs2_tag_id(tag), 8), dir->tail); + if (res < 0) { + return res; + } + lfs2_pair_fromle32(dir->tail); + } + + // find entry matching name + while (true) { + tag = lfs2_dir_fetchmatch(lfs2, dir, dir->tail, + LFS2_MKTAG(0x780, 0, 0), + LFS2_MKTAG(LFS2_TYPE_NAME, 0, namelen), + // are we last name? + (strchr(name, '/') == NULL) ? id : NULL, + lfs2_dir_find_match, &(struct lfs2_dir_find_match){ + lfs2, name, namelen}); + if (tag < 0) { + return tag; + } + + if (tag) { + break; + } + + if (!dir->split) { + return LFS2_ERR_NOENT; + } + } + + // to next name + name += namelen; + } +} + +// commit logic +struct lfs2_commit { + lfs2_block_t block; + lfs2_off_t off; + lfs2_tag_t ptag; + uint32_t crc; + + lfs2_off_t begin; + lfs2_off_t end; +}; + +#ifndef LFS2_READONLY +static int lfs2_dir_commitprog(lfs2_t *lfs2, struct lfs2_commit *commit, + const void *buffer, lfs2_size_t size) { + int err = lfs2_bd_prog(lfs2, + &lfs2->pcache, &lfs2->rcache, false, + commit->block, commit->off , + (const uint8_t*)buffer, size); + if (err) { + return err; + } + + commit->crc = lfs2_crc(commit->crc, buffer, size); + commit->off += size; + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_commitattr(lfs2_t *lfs2, struct lfs2_commit *commit, + lfs2_tag_t tag, const void *buffer) { + // check if we fit + lfs2_size_t dsize = lfs2_tag_dsize(tag); + if (commit->off + dsize > commit->end) { + return LFS2_ERR_NOSPC; + } + + // write out tag + lfs2_tag_t ntag = lfs2_tobe32((tag & 0x7fffffff) ^ commit->ptag); + int err = lfs2_dir_commitprog(lfs2, commit, &ntag, sizeof(ntag)); + if (err) { + return err; + } + + if (!(tag & 0x80000000)) { + // from memory + err = lfs2_dir_commitprog(lfs2, commit, buffer, dsize-sizeof(tag)); + if (err) { + return err; + } + } else { + // from disk + const struct lfs2_diskoff *disk = buffer; + for (lfs2_off_t i = 0; i < dsize-sizeof(tag); i++) { + // rely on caching to make this efficient + uint8_t dat; + err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, dsize-sizeof(tag)-i, + disk->block, disk->off+i, &dat, 1); + if (err) { + return err; + } + + err = lfs2_dir_commitprog(lfs2, commit, &dat, 1); + if (err) { + return err; + } + } + } + + commit->ptag = tag & 0x7fffffff; + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_commitcrc(lfs2_t *lfs2, struct lfs2_commit *commit) { + // align to program units + const lfs2_off_t end = lfs2_alignup(commit->off + 2*sizeof(uint32_t), + lfs2->cfg->prog_size); + + lfs2_off_t off1 = 0; + uint32_t crc1 = 0; + + // create crc tags to fill up remainder of commit, note that + // padding is not crced, which lets fetches skip padding but + // makes committing a bit more complicated + while (commit->off < end) { + lfs2_off_t off = commit->off + sizeof(lfs2_tag_t); + lfs2_off_t noff = lfs2_min(end - off, 0x3fe) + off; + if (noff < end) { + noff = lfs2_min(noff, end - 2*sizeof(uint32_t)); + } + + // read erased state from next program unit + lfs2_tag_t tag = 0xffffffff; + int err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, sizeof(tag), + commit->block, noff, &tag, sizeof(tag)); + if (err && err != LFS2_ERR_CORRUPT) { + return err; + } + + // build crc tag + bool reset = ~lfs2_frombe32(tag) >> 31; + tag = LFS2_MKTAG(LFS2_TYPE_CRC + reset, 0x3ff, noff - off); + + // write out crc + uint32_t footer[2]; + footer[0] = lfs2_tobe32(tag ^ commit->ptag); + commit->crc = lfs2_crc(commit->crc, &footer[0], sizeof(footer[0])); + footer[1] = lfs2_tole32(commit->crc); + err = lfs2_bd_prog(lfs2, + &lfs2->pcache, &lfs2->rcache, false, + commit->block, commit->off, &footer, sizeof(footer)); + if (err) { + return err; + } + + // keep track of non-padding checksum to verify + if (off1 == 0) { + off1 = commit->off + sizeof(uint32_t); + crc1 = commit->crc; + } + + commit->off += sizeof(tag)+lfs2_tag_size(tag); + commit->ptag = tag ^ ((lfs2_tag_t)reset << 31); + commit->crc = 0xffffffff; // reset crc for next "commit" + } + + // flush buffers + int err = lfs2_bd_sync(lfs2, &lfs2->pcache, &lfs2->rcache, false); + if (err) { + return err; + } + + // successful commit, check checksums to make sure + lfs2_off_t off = commit->begin; + lfs2_off_t noff = off1; + while (off < end) { + uint32_t crc = 0xffffffff; + for (lfs2_off_t i = off; i < noff+sizeof(uint32_t); i++) { + // check against written crc, may catch blocks that + // become readonly and match our commit size exactly + if (i == off1 && crc != crc1) { + return LFS2_ERR_CORRUPT; + } + + // leave it up to caching to make this efficient + uint8_t dat; + err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, noff+sizeof(uint32_t)-i, + commit->block, i, &dat, 1); + if (err) { + return err; + } + + crc = lfs2_crc(crc, &dat, 1); + } + + // detected write error? + if (crc != 0) { + return LFS2_ERR_CORRUPT; + } + + // skip padding + off = lfs2_min(end - noff, 0x3fe) + noff; + if (off < end) { + off = lfs2_min(off, end - 2*sizeof(uint32_t)); + } + noff = off + sizeof(uint32_t); + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_alloc(lfs2_t *lfs2, lfs2_mdir_t *dir) { + // allocate pair of dir blocks (backwards, so we write block 1 first) + for (int i = 0; i < 2; i++) { + int err = lfs2_alloc(lfs2, &dir->pair[(i+1)%2]); + if (err) { + return err; + } + } + + // zero for reproducability in case initial block is unreadable + dir->rev = 0; + + // rather than clobbering one of the blocks we just pretend + // the revision may be valid + int err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, sizeof(dir->rev), + dir->pair[0], 0, &dir->rev, sizeof(dir->rev)); + dir->rev = lfs2_fromle32(dir->rev); + if (err && err != LFS2_ERR_CORRUPT) { + return err; + } + + // to make sure we don't immediately evict, align the new revision count + // to our block_cycles modulus, see lfs2_dir_compact for why our modulus + // is tweaked this way + if (lfs2->cfg->block_cycles > 0) { + dir->rev = lfs2_alignup(dir->rev, ((lfs2->cfg->block_cycles+1)|1)); + } + + // set defaults + dir->off = sizeof(dir->rev); + dir->etag = 0xffffffff; + dir->count = 0; + dir->tail[0] = LFS2_BLOCK_NULL; + dir->tail[1] = LFS2_BLOCK_NULL; + dir->erased = false; + dir->split = false; + + // don't write out yet, let caller take care of that + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_drop(lfs2_t *lfs2, lfs2_mdir_t *dir, lfs2_mdir_t *tail) { + // steal state + int err = lfs2_dir_getgstate(lfs2, tail, &lfs2->gdelta); + if (err) { + return err; + } + + // steal tail + lfs2_pair_tole32(tail->tail); + err = lfs2_dir_commit(lfs2, dir, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_TAIL + tail->split, 0x3ff, 8), tail->tail})); + lfs2_pair_fromle32(tail->tail); + if (err) { + return err; + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_split(lfs2_t *lfs2, + lfs2_mdir_t *dir, const struct lfs2_mattr *attrs, int attrcount, + lfs2_mdir_t *source, uint16_t split, uint16_t end) { + // create tail directory + lfs2_alloc_ack(lfs2); + lfs2_mdir_t tail; + int err = lfs2_dir_alloc(lfs2, &tail); + if (err) { + return err; + } + + tail.split = dir->split; + tail.tail[0] = dir->tail[0]; + tail.tail[1] = dir->tail[1]; + + err = lfs2_dir_compact(lfs2, &tail, attrs, attrcount, source, split, end); + if (err) { + return err; + } + + dir->tail[0] = tail.pair[0]; + dir->tail[1] = tail.pair[1]; + dir->split = true; + + // update root if needed + if (lfs2_pair_cmp(dir->pair, lfs2->root) == 0 && split == 0) { + lfs2->root[0] = tail.pair[0]; + lfs2->root[1] = tail.pair[1]; + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_commit_size(void *p, lfs2_tag_t tag, const void *buffer) { + lfs2_size_t *size = p; + (void)buffer; + + *size += lfs2_tag_dsize(tag); + return 0; +} +#endif + +#ifndef LFS2_READONLY +struct lfs2_dir_commit_commit { + lfs2_t *lfs2; + struct lfs2_commit *commit; +}; +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_commit_commit(void *p, lfs2_tag_t tag, const void *buffer) { + struct lfs2_dir_commit_commit *commit = p; + return lfs2_dir_commitattr(commit->lfs2, commit->commit, tag, buffer); +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_compact(lfs2_t *lfs2, + lfs2_mdir_t *dir, const struct lfs2_mattr *attrs, int attrcount, + lfs2_mdir_t *source, uint16_t begin, uint16_t end) { + // save some state in case block is bad + const lfs2_block_t oldpair[2] = {dir->pair[0], dir->pair[1]}; + bool relocated = false; + bool tired = false; + + // should we split? + while (end - begin > 1) { + // find size + lfs2_size_t size = 0; + int err = lfs2_dir_traverse(lfs2, + source, 0, 0xffffffff, attrs, attrcount, + LFS2_MKTAG(0x400, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_NAME, 0, 0), + begin, end, -begin, + lfs2_dir_commit_size, &size); + if (err) { + return err; + } + + // space is complicated, we need room for tail, crc, gstate, + // cleanup delete, and we cap at half a block to give room + // for metadata updates. + if (end - begin < 0xff && + size <= lfs2_min(lfs2->cfg->block_size - 36, + lfs2_alignup(lfs2->cfg->block_size/2, + lfs2->cfg->prog_size))) { + break; + } + + // can't fit, need to split, we should really be finding the + // largest size that fits with a small binary search, but right now + // it's not worth the code size + uint16_t split = (end - begin) / 2; + err = lfs2_dir_split(lfs2, dir, attrs, attrcount, + source, begin+split, end); + if (err) { + // if we fail to split, we may be able to overcompact, unless + // we're too big for even the full block, in which case our + // only option is to error + if (err == LFS2_ERR_NOSPC && size <= lfs2->cfg->block_size - 36) { + break; + } + return err; + } + + end = begin + split; + } + + // increment revision count + dir->rev += 1; + // If our revision count == n * block_cycles, we should force a relocation, + // this is how littlefs wear-levels at the metadata-pair level. Note that we + // actually use (block_cycles+1)|1, this is to avoid two corner cases: + // 1. block_cycles = 1, which would prevent relocations from terminating + // 2. block_cycles = 2n, which, due to aliasing, would only ever relocate + // one metadata block in the pair, effectively making this useless + if (lfs2->cfg->block_cycles > 0 && + (dir->rev % ((lfs2->cfg->block_cycles+1)|1) == 0)) { + if (lfs2_pair_cmp(dir->pair, (const lfs2_block_t[2]){0, 1}) == 0) { + // oh no! we're writing too much to the superblock, + // should we expand? + lfs2_ssize_t res = lfs2_fs_rawsize(lfs2); + if (res < 0) { + return res; + } + + // do we have extra space? littlefs can't reclaim this space + // by itself, so expand cautiously + if ((lfs2_size_t)res < lfs2->cfg->block_count/2) { + LFS2_DEBUG("Expanding superblock at rev %"PRIu32, dir->rev); + int err = lfs2_dir_split(lfs2, dir, attrs, attrcount, + source, begin, end); + if (err && err != LFS2_ERR_NOSPC) { + return err; + } + + // welp, we tried, if we ran out of space there's not much + // we can do, we'll error later if we've become frozen + if (!err) { + end = begin; + } + } +#ifdef LFS2_MIGRATE + } else if (lfs2->lfs21) { + // do not proactively relocate blocks during migrations, this + // can cause a number of failure states such: clobbering the + // v1 superblock if we relocate root, and invalidating directory + // pointers if we relocate the head of a directory. On top of + // this, relocations increase the overall complexity of + // lfs2_migration, which is already a delicate operation. +#endif + } else { + // we're writing too much, time to relocate + tired = true; + goto relocate; + } + } + + // begin loop to commit compaction to blocks until a compact sticks + while (true) { + { + // setup commit state + struct lfs2_commit commit = { + .block = dir->pair[1], + .off = 0, + .ptag = 0xffffffff, + .crc = 0xffffffff, + + .begin = 0, + .end = lfs2->cfg->block_size - 8, + }; + + // erase block to write to + int err = lfs2_bd_erase(lfs2, dir->pair[1]); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // write out header + dir->rev = lfs2_tole32(dir->rev); + err = lfs2_dir_commitprog(lfs2, &commit, + &dir->rev, sizeof(dir->rev)); + dir->rev = lfs2_fromle32(dir->rev); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // traverse the directory, this time writing out all unique tags + err = lfs2_dir_traverse(lfs2, + source, 0, 0xffffffff, attrs, attrcount, + LFS2_MKTAG(0x400, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_NAME, 0, 0), + begin, end, -begin, + lfs2_dir_commit_commit, &(struct lfs2_dir_commit_commit){ + lfs2, &commit}); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // commit tail, which may be new after last size check + if (!lfs2_pair_isnull(dir->tail)) { + lfs2_pair_tole32(dir->tail); + err = lfs2_dir_commitattr(lfs2, &commit, + LFS2_MKTAG(LFS2_TYPE_TAIL + dir->split, 0x3ff, 8), + dir->tail); + lfs2_pair_fromle32(dir->tail); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + // bring over gstate? + lfs2_gstate_t delta = {0}; + if (!relocated) { + lfs2_gstate_xor(&delta, &lfs2->gdisk); + lfs2_gstate_xor(&delta, &lfs2->gstate); + } + lfs2_gstate_xor(&delta, &lfs2->gdelta); + delta.tag &= ~LFS2_MKTAG(0, 0, 0x3ff); + + err = lfs2_dir_getgstate(lfs2, dir, &delta); + if (err) { + return err; + } + + if (!lfs2_gstate_iszero(&delta)) { + lfs2_gstate_tole32(&delta); + err = lfs2_dir_commitattr(lfs2, &commit, + LFS2_MKTAG(LFS2_TYPE_MOVESTATE, 0x3ff, + sizeof(delta)), &delta); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + // complete commit with crc + err = lfs2_dir_commitcrc(lfs2, &commit); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // successful compaction, swap dir pair to indicate most recent + LFS2_ASSERT(commit.off % lfs2->cfg->prog_size == 0); + lfs2_pair_swap(dir->pair); + dir->count = end - begin; + dir->off = commit.off; + dir->etag = commit.ptag; + // update gstate + lfs2->gdelta = (lfs2_gstate_t){0}; + if (!relocated) { + lfs2->gdisk = lfs2->gstate; + } + } + break; + +relocate: + // commit was corrupted, drop caches and prepare to relocate block + relocated = true; + lfs2_cache_drop(lfs2, &lfs2->pcache); + if (!tired) { + LFS2_DEBUG("Bad block at 0x%"PRIx32, dir->pair[1]); + } + + // can't relocate superblock, filesystem is now frozen + if (lfs2_pair_cmp(dir->pair, (const lfs2_block_t[2]){0, 1}) == 0) { + LFS2_WARN("Superblock 0x%"PRIx32" has become unwritable", + dir->pair[1]); + return LFS2_ERR_NOSPC; + } + + // relocate half of pair + int err = lfs2_alloc(lfs2, &dir->pair[1]); + if (err && (err != LFS2_ERR_NOSPC || !tired)) { + return err; + } + + tired = false; + continue; + } + + if (relocated) { + // update references if we relocated + LFS2_DEBUG("Relocating {0x%"PRIx32", 0x%"PRIx32"} " + "-> {0x%"PRIx32", 0x%"PRIx32"}", + oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]); + int err = lfs2_fs_relocate(lfs2, oldpair, dir->pair); + if (err) { + return err; + } + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, + const struct lfs2_mattr *attrs, int attrcount) { + // check for any inline files that aren't RAM backed and + // forcefully evict them, needed for filesystem consistency + for (lfs2_file_t *f = (lfs2_file_t*)lfs2->mlist; f; f = f->next) { + if (dir != &f->m && lfs2_pair_cmp(f->m.pair, dir->pair) == 0 && + f->type == LFS2_TYPE_REG && (f->flags & LFS2_F_INLINE) && + f->ctz.size > lfs2->cfg->cache_size) { + int err = lfs2_file_outline(lfs2, f); + if (err) { + return err; + } + + err = lfs2_file_flush(lfs2, f); + if (err) { + return err; + } + } + } + + // calculate changes to the directory + lfs2_mdir_t olddir = *dir; + bool hasdelete = false; + for (int i = 0; i < attrcount; i++) { + if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_CREATE) { + dir->count += 1; + } else if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE) { + LFS2_ASSERT(dir->count > 0); + dir->count -= 1; + hasdelete = true; + } else if (lfs2_tag_type1(attrs[i].tag) == LFS2_TYPE_TAIL) { + dir->tail[0] = ((lfs2_block_t*)attrs[i].buffer)[0]; + dir->tail[1] = ((lfs2_block_t*)attrs[i].buffer)[1]; + dir->split = (lfs2_tag_chunk(attrs[i].tag) & 1); + lfs2_pair_fromle32(dir->tail); + } + } + + // should we actually drop the directory block? + if (hasdelete && dir->count == 0) { + lfs2_mdir_t pdir; + int err = lfs2_fs_pred(lfs2, dir->pair, &pdir); + if (err && err != LFS2_ERR_NOENT) { + *dir = olddir; + return err; + } + + if (err != LFS2_ERR_NOENT && pdir.split) { + err = lfs2_dir_drop(lfs2, &pdir, dir); + if (err) { + *dir = olddir; + return err; + } + } + } + + if (dir->erased || dir->count >= 0xff) { + // try to commit + struct lfs2_commit commit = { + .block = dir->pair[0], + .off = dir->off, + .ptag = dir->etag, + .crc = 0xffffffff, + + .begin = dir->off, + .end = lfs2->cfg->block_size - 8, + }; + + // traverse attrs that need to be written out + lfs2_pair_tole32(dir->tail); + int err = lfs2_dir_traverse(lfs2, + dir, dir->off, dir->etag, attrs, attrcount, + 0, 0, 0, 0, 0, + lfs2_dir_commit_commit, &(struct lfs2_dir_commit_commit){ + lfs2, &commit}); + lfs2_pair_fromle32(dir->tail); + if (err) { + if (err == LFS2_ERR_NOSPC || err == LFS2_ERR_CORRUPT) { + goto compact; + } + *dir = olddir; + return err; + } + + // commit any global diffs if we have any + lfs2_gstate_t delta = {0}; + lfs2_gstate_xor(&delta, &lfs2->gstate); + lfs2_gstate_xor(&delta, &lfs2->gdisk); + lfs2_gstate_xor(&delta, &lfs2->gdelta); + delta.tag &= ~LFS2_MKTAG(0, 0, 0x3ff); + if (!lfs2_gstate_iszero(&delta)) { + err = lfs2_dir_getgstate(lfs2, dir, &delta); + if (err) { + *dir = olddir; + return err; + } + + lfs2_gstate_tole32(&delta); + err = lfs2_dir_commitattr(lfs2, &commit, + LFS2_MKTAG(LFS2_TYPE_MOVESTATE, 0x3ff, + sizeof(delta)), &delta); + if (err) { + if (err == LFS2_ERR_NOSPC || err == LFS2_ERR_CORRUPT) { + goto compact; + } + *dir = olddir; + return err; + } + } + + // finalize commit with the crc + err = lfs2_dir_commitcrc(lfs2, &commit); + if (err) { + if (err == LFS2_ERR_NOSPC || err == LFS2_ERR_CORRUPT) { + goto compact; + } + *dir = olddir; + return err; + } + + // successful commit, update dir + LFS2_ASSERT(commit.off % lfs2->cfg->prog_size == 0); + dir->off = commit.off; + dir->etag = commit.ptag; + // and update gstate + lfs2->gdisk = lfs2->gstate; + lfs2->gdelta = (lfs2_gstate_t){0}; + } else { +compact: + // fall back to compaction + lfs2_cache_drop(lfs2, &lfs2->pcache); + + int err = lfs2_dir_compact(lfs2, dir, attrs, attrcount, + dir, 0, dir->count); + if (err) { + *dir = olddir; + return err; + } + } + + // this complicated bit of logic is for fixing up any active + // metadata-pairs that we may have affected + // + // note we have to make two passes since the mdir passed to + // lfs2_dir_commit could also be in this list, and even then + // we need to copy the pair so they don't get clobbered if we refetch + // our mdir. + for (struct lfs2_mlist *d = lfs2->mlist; d; d = d->next) { + if (&d->m != dir && lfs2_pair_cmp(d->m.pair, olddir.pair) == 0) { + d->m = *dir; + for (int i = 0; i < attrcount; i++) { + if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE && + d->id == lfs2_tag_id(attrs[i].tag)) { + d->m.pair[0] = LFS2_BLOCK_NULL; + d->m.pair[1] = LFS2_BLOCK_NULL; + } else if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE && + d->id > lfs2_tag_id(attrs[i].tag)) { + d->id -= 1; + if (d->type == LFS2_TYPE_DIR) { + ((lfs2_dir_t*)d)->pos -= 1; + } + } else if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_CREATE && + d->id >= lfs2_tag_id(attrs[i].tag)) { + d->id += 1; + if (d->type == LFS2_TYPE_DIR) { + ((lfs2_dir_t*)d)->pos += 1; + } + } + } + } + } + + for (struct lfs2_mlist *d = lfs2->mlist; d; d = d->next) { + if (lfs2_pair_cmp(d->m.pair, olddir.pair) == 0) { + while (d->id >= d->m.count && d->m.split) { + // we split and id is on tail now + d->id -= d->m.count; + int err = lfs2_dir_fetch(lfs2, &d->m, d->m.tail); + if (err) { + return err; + } + } + } + } + + return 0; +} +#endif + + +/// Top level directory operations /// +#ifndef LFS2_READONLY +static int lfs2_rawmkdir(lfs2_t *lfs2, const char *path) { + // deorphan if we haven't yet, needed at most once after poweron + int err = lfs2_fs_forceconsistency(lfs2); + if (err) { + return err; + } + + struct lfs2_mlist cwd; + cwd.next = lfs2->mlist; + uint16_t id; + err = lfs2_dir_find(lfs2, &cwd.m, &path, &id); + if (!(err == LFS2_ERR_NOENT && id != 0x3ff)) { + return (err < 0) ? err : LFS2_ERR_EXIST; + } + + // check that name fits + lfs2_size_t nlen = strlen(path); + if (nlen > lfs2->name_max) { + return LFS2_ERR_NAMETOOLONG; + } + + // build up new directory + lfs2_alloc_ack(lfs2); + lfs2_mdir_t dir; + err = lfs2_dir_alloc(lfs2, &dir); + if (err) { + return err; + } + + // find end of list + lfs2_mdir_t pred = cwd.m; + while (pred.split) { + err = lfs2_dir_fetch(lfs2, &pred, pred.tail); + if (err) { + return err; + } + } + + // setup dir + lfs2_pair_tole32(pred.tail); + err = lfs2_dir_commit(lfs2, &dir, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_SOFTTAIL, 0x3ff, 8), pred.tail})); + lfs2_pair_fromle32(pred.tail); + if (err) { + return err; + } + + // current block end of list? + if (cwd.m.split) { + // update tails, this creates a desync + lfs2_fs_preporphans(lfs2, +1); + + // it's possible our predecessor has to be relocated, and if + // our parent is our predecessor's predecessor, this could have + // caused our parent to go out of date, fortunately we can hook + // ourselves into littlefs to catch this + cwd.type = 0; + cwd.id = 0; + lfs2->mlist = &cwd; + + lfs2_pair_tole32(dir.pair); + err = lfs2_dir_commit(lfs2, &pred, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_SOFTTAIL, 0x3ff, 8), dir.pair})); + lfs2_pair_fromle32(dir.pair); + if (err) { + lfs2->mlist = cwd.next; + return err; + } + + lfs2->mlist = cwd.next; + lfs2_fs_preporphans(lfs2, -1); + } + + // now insert into our parent block + lfs2_pair_tole32(dir.pair); + err = lfs2_dir_commit(lfs2, &cwd.m, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_CREATE, id, 0), NULL}, + {LFS2_MKTAG(LFS2_TYPE_DIR, id, nlen), path}, + {LFS2_MKTAG(LFS2_TYPE_DIRSTRUCT, id, 8), dir.pair}, + {LFS2_MKTAG_IF(!cwd.m.split, + LFS2_TYPE_SOFTTAIL, 0x3ff, 8), dir.pair})); + lfs2_pair_fromle32(dir.pair); + if (err) { + return err; + } + + return 0; +} +#endif + +static int lfs2_dir_rawopen(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { + lfs2_stag_t tag = lfs2_dir_find(lfs2, &dir->m, &path, NULL); + if (tag < 0) { + return tag; + } + + if (lfs2_tag_type3(tag) != LFS2_TYPE_DIR) { + return LFS2_ERR_NOTDIR; + } + + lfs2_block_t pair[2]; + if (lfs2_tag_id(tag) == 0x3ff) { + // handle root dir separately + pair[0] = lfs2->root[0]; + pair[1] = lfs2->root[1]; + } else { + // get dir pair from parent + lfs2_stag_t res = lfs2_dir_get(lfs2, &dir->m, LFS2_MKTAG(0x700, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, lfs2_tag_id(tag), 8), pair); + if (res < 0) { + return res; + } + lfs2_pair_fromle32(pair); + } + + // fetch first pair + int err = lfs2_dir_fetch(lfs2, &dir->m, pair); + if (err) { + return err; + } + + // setup entry + dir->head[0] = dir->m.pair[0]; + dir->head[1] = dir->m.pair[1]; + dir->id = 0; + dir->pos = 0; + + // add to list of mdirs + dir->type = LFS2_TYPE_DIR; + lfs2_mlist_append(lfs2, (struct lfs2_mlist *)dir); + + return 0; +} + +static int lfs2_dir_rawclose(lfs2_t *lfs2, lfs2_dir_t *dir) { + // remove from list of mdirs + lfs2_mlist_remove(lfs2, (struct lfs2_mlist *)dir); + + return 0; +} + +static int lfs2_dir_rawread(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { + memset(info, 0, sizeof(*info)); + + // special offset for '.' and '..' + if (dir->pos == 0) { + info->type = LFS2_TYPE_DIR; + strcpy(info->name, "."); + dir->pos += 1; + return true; + } else if (dir->pos == 1) { + info->type = LFS2_TYPE_DIR; + strcpy(info->name, ".."); + dir->pos += 1; + return true; + } + + while (true) { + if (dir->id == dir->m.count) { + if (!dir->m.split) { + return false; + } + + int err = lfs2_dir_fetch(lfs2, &dir->m, dir->m.tail); + if (err) { + return err; + } + + dir->id = 0; + } + + int err = lfs2_dir_getinfo(lfs2, &dir->m, dir->id, info); + if (err && err != LFS2_ERR_NOENT) { + return err; + } + + dir->id += 1; + if (err != LFS2_ERR_NOENT) { + break; + } + } + + dir->pos += 1; + return true; +} + +static int lfs2_dir_rawseek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off) { + // simply walk from head dir + int err = lfs2_dir_rawrewind(lfs2, dir); + if (err) { + return err; + } + + // first two for ./.. + dir->pos = lfs2_min(2, off); + off -= dir->pos; + + // skip superblock entry + dir->id = (off > 0 && lfs2_pair_cmp(dir->head, lfs2->root) == 0); + + while (off > 0) { + int diff = lfs2_min(dir->m.count - dir->id, off); + dir->id += diff; + dir->pos += diff; + off -= diff; + + if (dir->id == dir->m.count) { + if (!dir->m.split) { + return LFS2_ERR_INVAL; + } + + err = lfs2_dir_fetch(lfs2, &dir->m, dir->m.tail); + if (err) { + return err; + } + + dir->id = 0; + } + } + + return 0; +} + +static lfs2_soff_t lfs2_dir_rawtell(lfs2_t *lfs2, lfs2_dir_t *dir) { + (void)lfs2; + return dir->pos; +} + +static int lfs2_dir_rawrewind(lfs2_t *lfs2, lfs2_dir_t *dir) { + // reload the head dir + int err = lfs2_dir_fetch(lfs2, &dir->m, dir->head); + if (err) { + return err; + } + + dir->id = 0; + dir->pos = 0; + return 0; +} + + +/// File index list operations /// +static int lfs2_ctz_index(lfs2_t *lfs2, lfs2_off_t *off) { + lfs2_off_t size = *off; + lfs2_off_t b = lfs2->cfg->block_size - 2*4; + lfs2_off_t i = size / b; + if (i == 0) { + return 0; + } + + i = (size - 4*(lfs2_popc(i-1)+2)) / b; + *off = size - b*i - 4*lfs2_popc(i); + return i; +} + +static int lfs2_ctz_find(lfs2_t *lfs2, + const lfs2_cache_t *pcache, lfs2_cache_t *rcache, + lfs2_block_t head, lfs2_size_t size, + lfs2_size_t pos, lfs2_block_t *block, lfs2_off_t *off) { + if (size == 0) { + *block = LFS2_BLOCK_NULL; + *off = 0; + return 0; + } + + lfs2_off_t current = lfs2_ctz_index(lfs2, &(lfs2_off_t){size-1}); + lfs2_off_t target = lfs2_ctz_index(lfs2, &pos); + + while (current > target) { + lfs2_size_t skip = lfs2_min( + lfs2_npw2(current-target+1) - 1, + lfs2_ctz(current)); + + int err = lfs2_bd_read(lfs2, + pcache, rcache, sizeof(head), + head, 4*skip, &head, sizeof(head)); + head = lfs2_fromle32(head); + if (err) { + return err; + } + + current -= 1 << skip; + } + + *block = head; + *off = pos; + return 0; +} + +#ifndef LFS2_READONLY +static int lfs2_ctz_extend(lfs2_t *lfs2, + lfs2_cache_t *pcache, lfs2_cache_t *rcache, + lfs2_block_t head, lfs2_size_t size, + lfs2_block_t *block, lfs2_off_t *off) { + while (true) { + // go ahead and grab a block + lfs2_block_t nblock; + int err = lfs2_alloc(lfs2, &nblock); + if (err) { + return err; + } + + { + err = lfs2_bd_erase(lfs2, nblock); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + if (size == 0) { + *block = nblock; + *off = 0; + return 0; + } + + lfs2_size_t noff = size - 1; + lfs2_off_t index = lfs2_ctz_index(lfs2, &noff); + noff = noff + 1; + + // just copy out the last block if it is incomplete + if (noff != lfs2->cfg->block_size) { + for (lfs2_off_t i = 0; i < noff; i++) { + uint8_t data; + err = lfs2_bd_read(lfs2, + NULL, rcache, noff-i, + head, i, &data, 1); + if (err) { + return err; + } + + err = lfs2_bd_prog(lfs2, + pcache, rcache, true, + nblock, i, &data, 1); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + *block = nblock; + *off = noff; + return 0; + } + + // append block + index += 1; + lfs2_size_t skips = lfs2_ctz(index) + 1; + lfs2_block_t nhead = head; + for (lfs2_off_t i = 0; i < skips; i++) { + nhead = lfs2_tole32(nhead); + err = lfs2_bd_prog(lfs2, pcache, rcache, true, + nblock, 4*i, &nhead, 4); + nhead = lfs2_fromle32(nhead); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + if (i != skips-1) { + err = lfs2_bd_read(lfs2, + NULL, rcache, sizeof(nhead), + nhead, 4*i, &nhead, sizeof(nhead)); + nhead = lfs2_fromle32(nhead); + if (err) { + return err; + } + } + } + + *block = nblock; + *off = 4*skips; + return 0; + } + +relocate: + LFS2_DEBUG("Bad block at 0x%"PRIx32, nblock); + + // just clear cache and try a new block + lfs2_cache_drop(lfs2, pcache); + } +} +#endif + +static int lfs2_ctz_traverse(lfs2_t *lfs2, + const lfs2_cache_t *pcache, lfs2_cache_t *rcache, + lfs2_block_t head, lfs2_size_t size, + int (*cb)(void*, lfs2_block_t), void *data) { + if (size == 0) { + return 0; + } + + lfs2_off_t index = lfs2_ctz_index(lfs2, &(lfs2_off_t){size-1}); + + while (true) { + int err = cb(data, head); + if (err) { + return err; + } + + if (index == 0) { + return 0; + } + + lfs2_block_t heads[2]; + int count = 2 - (index & 1); + err = lfs2_bd_read(lfs2, + pcache, rcache, count*sizeof(head), + head, 0, &heads, count*sizeof(head)); + heads[0] = lfs2_fromle32(heads[0]); + heads[1] = lfs2_fromle32(heads[1]); + if (err) { + return err; + } + + for (int i = 0; i < count-1; i++) { + err = cb(data, heads[i]); + if (err) { + return err; + } + } + + head = heads[count-1]; + index -= count; + } +} + + +/// Top level file operations /// +static int lfs2_file_rawopencfg(lfs2_t *lfs2, lfs2_file_t *file, + const char *path, int flags, + const struct lfs2_file_config *cfg) { +#ifndef LFS2_READONLY + // deorphan if we haven't yet, needed at most once after poweron + if ((flags & LFS2_O_WRONLY) == LFS2_O_WRONLY) { + int err = lfs2_fs_forceconsistency(lfs2); + if (err) { + return err; + } + } +#else + LFS2_ASSERT((flags & LFS2_O_RDONLY) == LFS2_O_RDONLY); +#endif + + // setup simple file details + int err; + file->cfg = cfg; + file->flags = flags; + file->pos = 0; + file->off = 0; + file->cache.buffer = NULL; + + // allocate entry for file if it doesn't exist + lfs2_stag_t tag = lfs2_dir_find(lfs2, &file->m, &path, &file->id); + if (tag < 0 && !(tag == LFS2_ERR_NOENT && file->id != 0x3ff)) { + err = tag; + goto cleanup; + } + + // get id, add to list of mdirs to catch update changes + file->type = LFS2_TYPE_REG; + lfs2_mlist_append(lfs2, (struct lfs2_mlist *)file); + +#ifdef LFS2_READONLY + if (tag == LFS2_ERR_NOENT) { + err = LFS2_ERR_NOENT; + goto cleanup; +#else + if (tag == LFS2_ERR_NOENT) { + if (!(flags & LFS2_O_CREAT)) { + err = LFS2_ERR_NOENT; + goto cleanup; + } + + // check that name fits + lfs2_size_t nlen = strlen(path); + if (nlen > lfs2->name_max) { + err = LFS2_ERR_NAMETOOLONG; + goto cleanup; + } + + // get next slot and create entry to remember name + err = lfs2_dir_commit(lfs2, &file->m, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_CREATE, file->id, 0), NULL}, + {LFS2_MKTAG(LFS2_TYPE_REG, file->id, nlen), path}, + {LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, file->id, 0), NULL})); + if (err) { + err = LFS2_ERR_NAMETOOLONG; + goto cleanup; + } + + tag = LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, 0); + } else if (flags & LFS2_O_EXCL) { + err = LFS2_ERR_EXIST; + goto cleanup; +#endif + } else if (lfs2_tag_type3(tag) != LFS2_TYPE_REG) { + err = LFS2_ERR_ISDIR; + goto cleanup; +#ifndef LFS2_READONLY + } else if (flags & LFS2_O_TRUNC) { + // truncate if requested + tag = LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, file->id, 0); + file->flags |= LFS2_F_DIRTY; +#endif + } else { + // try to load what's on disk, if it's inlined we'll fix it later + tag = lfs2_dir_get(lfs2, &file->m, LFS2_MKTAG(0x700, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, file->id, 8), &file->ctz); + if (tag < 0) { + err = tag; + goto cleanup; + } + lfs2_ctz_fromle32(&file->ctz); + } + + // fetch attrs + for (unsigned i = 0; i < file->cfg->attr_count; i++) { + // if opened for read / read-write operations + if ((file->flags & LFS2_O_RDONLY) == LFS2_O_RDONLY) { + lfs2_stag_t res = lfs2_dir_get(lfs2, &file->m, + LFS2_MKTAG(0x7ff, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_USERATTR + file->cfg->attrs[i].type, + file->id, file->cfg->attrs[i].size), + file->cfg->attrs[i].buffer); + if (res < 0 && res != LFS2_ERR_NOENT) { + err = res; + goto cleanup; + } + } + +#ifndef LFS2_READONLY + // if opened for write / read-write operations + if ((file->flags & LFS2_O_WRONLY) == LFS2_O_WRONLY) { + if (file->cfg->attrs[i].size > lfs2->attr_max) { + err = LFS2_ERR_NOSPC; + goto cleanup; + } + + file->flags |= LFS2_F_DIRTY; + } +#endif + } + + // allocate buffer if needed + if (file->cfg->buffer) { + file->cache.buffer = file->cfg->buffer; + } else { + file->cache.buffer = lfs2_malloc(lfs2->cfg->cache_size); + if (!file->cache.buffer) { + err = LFS2_ERR_NOMEM; + goto cleanup; + } + } + + // zero to avoid information leak + lfs2_cache_zero(lfs2, &file->cache); + + if (lfs2_tag_type3(tag) == LFS2_TYPE_INLINESTRUCT) { + // load inline files + file->ctz.head = LFS2_BLOCK_INLINE; + file->ctz.size = lfs2_tag_size(tag); + file->flags |= LFS2_F_INLINE; + file->cache.block = file->ctz.head; + file->cache.off = 0; + file->cache.size = lfs2->cfg->cache_size; + + // don't always read (may be new/trunc file) + if (file->ctz.size > 0) { + lfs2_stag_t res = lfs2_dir_get(lfs2, &file->m, + LFS2_MKTAG(0x700, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, file->id, + lfs2_min(file->cache.size, 0x3fe)), + file->cache.buffer); + if (res < 0) { + err = res; + goto cleanup; + } + } + } + + return 0; + +cleanup: + // clean up lingering resources +#ifndef LFS2_READONLY + file->flags |= LFS2_F_ERRED; +#endif + lfs2_file_rawclose(lfs2, file); + return err; +} + +static int lfs2_file_rawopen(lfs2_t *lfs2, lfs2_file_t *file, + const char *path, int flags) { + static const struct lfs2_file_config defaults = {0}; + int err = lfs2_file_rawopencfg(lfs2, file, path, flags, &defaults); + return err; +} + +static int lfs2_file_rawclose(lfs2_t *lfs2, lfs2_file_t *file) { +#ifndef LFS2_READONLY + int err = lfs2_file_rawsync(lfs2, file); +#else + int err = 0; +#endif + + // remove from list of mdirs + lfs2_mlist_remove(lfs2, (struct lfs2_mlist*)file); + + // clean up memory + if (!file->cfg->buffer) { + lfs2_free(file->cache.buffer); + } + + return err; +} + + +#ifndef LFS2_READONLY +static int lfs2_file_relocate(lfs2_t *lfs2, lfs2_file_t *file) { + while (true) { + // just relocate what exists into new block + lfs2_block_t nblock; + int err = lfs2_alloc(lfs2, &nblock); + if (err) { + return err; + } + + err = lfs2_bd_erase(lfs2, nblock); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // either read from dirty cache or disk + for (lfs2_off_t i = 0; i < file->off; i++) { + uint8_t data; + if (file->flags & LFS2_F_INLINE) { + err = lfs2_dir_getread(lfs2, &file->m, + // note we evict inline files before they can be dirty + NULL, &file->cache, file->off-i, + LFS2_MKTAG(0xfff, 0x1ff, 0), + LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, file->id, 0), + i, &data, 1); + if (err) { + return err; + } + } else { + err = lfs2_bd_read(lfs2, + &file->cache, &lfs2->rcache, file->off-i, + file->block, i, &data, 1); + if (err) { + return err; + } + } + + err = lfs2_bd_prog(lfs2, + &lfs2->pcache, &lfs2->rcache, true, + nblock, i, &data, 1); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + // copy over new state of file + memcpy(file->cache.buffer, lfs2->pcache.buffer, lfs2->cfg->cache_size); + file->cache.block = lfs2->pcache.block; + file->cache.off = lfs2->pcache.off; + file->cache.size = lfs2->pcache.size; + lfs2_cache_zero(lfs2, &lfs2->pcache); + + file->block = nblock; + file->flags |= LFS2_F_WRITING; + return 0; + +relocate: + LFS2_DEBUG("Bad block at 0x%"PRIx32, nblock); + + // just clear cache and try a new block + lfs2_cache_drop(lfs2, &lfs2->pcache); + } +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_file_outline(lfs2_t *lfs2, lfs2_file_t *file) { + file->off = file->pos; + lfs2_alloc_ack(lfs2); + int err = lfs2_file_relocate(lfs2, file); + if (err) { + return err; + } + + file->flags &= ~LFS2_F_INLINE; + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { + if (file->flags & LFS2_F_READING) { + if (!(file->flags & LFS2_F_INLINE)) { + lfs2_cache_drop(lfs2, &file->cache); + } + file->flags &= ~LFS2_F_READING; + } + + if (file->flags & LFS2_F_WRITING) { + lfs2_off_t pos = file->pos; + + if (!(file->flags & LFS2_F_INLINE)) { + // copy over anything after current branch + lfs2_file_t orig = { + .ctz.head = file->ctz.head, + .ctz.size = file->ctz.size, + .flags = LFS2_O_RDONLY, + .pos = file->pos, + .cache = lfs2->rcache, + }; + lfs2_cache_drop(lfs2, &lfs2->rcache); + + while (file->pos < file->ctz.size) { + // copy over a byte at a time, leave it up to caching + // to make this efficient + uint8_t data; + lfs2_ssize_t res = lfs2_file_rawread(lfs2, &orig, &data, 1); + if (res < 0) { + return res; + } + + res = lfs2_file_rawwrite(lfs2, file, &data, 1); + if (res < 0) { + return res; + } + + // keep our reference to the rcache in sync + if (lfs2->rcache.block != LFS2_BLOCK_NULL) { + lfs2_cache_drop(lfs2, &orig.cache); + lfs2_cache_drop(lfs2, &lfs2->rcache); + } + } + + // write out what we have + while (true) { + int err = lfs2_bd_flush(lfs2, &file->cache, &lfs2->rcache, true); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + break; + +relocate: + LFS2_DEBUG("Bad block at 0x%"PRIx32, file->block); + err = lfs2_file_relocate(lfs2, file); + if (err) { + return err; + } + } + } else { + file->pos = lfs2_max(file->pos, file->ctz.size); + } + + // actual file updates + file->ctz.head = file->block; + file->ctz.size = file->pos; + file->flags &= ~LFS2_F_WRITING; + file->flags |= LFS2_F_DIRTY; + + file->pos = pos; + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_file_rawsync(lfs2_t *lfs2, lfs2_file_t *file) { + if (file->flags & LFS2_F_ERRED) { + // it's not safe to do anything if our file errored + return 0; + } + + int err = lfs2_file_flush(lfs2, file); + if (err) { + file->flags |= LFS2_F_ERRED; + return err; + } + + + if ((file->flags & LFS2_F_DIRTY) && + !lfs2_pair_isnull(file->m.pair)) { + // update dir entry + uint16_t type; + const void *buffer; + lfs2_size_t size; + struct lfs2_ctz ctz; + if (file->flags & LFS2_F_INLINE) { + // inline the whole file + type = LFS2_TYPE_INLINESTRUCT; + buffer = file->cache.buffer; + size = file->ctz.size; + } else { + // update the ctz reference + type = LFS2_TYPE_CTZSTRUCT; + // copy ctz so alloc will work during a relocate + ctz = file->ctz; + lfs2_ctz_tole32(&ctz); + buffer = &ctz; + size = sizeof(ctz); + } + + // commit file data and attributes + err = lfs2_dir_commit(lfs2, &file->m, LFS2_MKATTRS( + {LFS2_MKTAG(type, file->id, size), buffer}, + {LFS2_MKTAG(LFS2_FROM_USERATTRS, file->id, + file->cfg->attr_count), file->cfg->attrs})); + if (err) { + file->flags |= LFS2_F_ERRED; + return err; + } + + file->flags &= ~LFS2_F_DIRTY; + } + + return 0; +} +#endif + +static lfs2_ssize_t lfs2_file_rawread(lfs2_t *lfs2, lfs2_file_t *file, + void *buffer, lfs2_size_t size) { + LFS2_ASSERT((file->flags & LFS2_O_RDONLY) == LFS2_O_RDONLY); + + uint8_t *data = buffer; + lfs2_size_t nsize = size; + +#ifndef LFS2_READONLY + if (file->flags & LFS2_F_WRITING) { + // flush out any writes + int err = lfs2_file_flush(lfs2, file); + if (err) { + return err; + } + } +#endif + + if (file->pos >= file->ctz.size) { + // eof if past end + return 0; + } + + size = lfs2_min(size, file->ctz.size - file->pos); + nsize = size; + + while (nsize > 0) { + // check if we need a new block + if (!(file->flags & LFS2_F_READING) || + file->off == lfs2->cfg->block_size) { + if (!(file->flags & LFS2_F_INLINE)) { + int err = lfs2_ctz_find(lfs2, NULL, &file->cache, + file->ctz.head, file->ctz.size, + file->pos, &file->block, &file->off); + if (err) { + return err; + } + } else { + file->block = LFS2_BLOCK_INLINE; + file->off = file->pos; + } + + file->flags |= LFS2_F_READING; + } + + // read as much as we can in current block + lfs2_size_t diff = lfs2_min(nsize, lfs2->cfg->block_size - file->off); + if (file->flags & LFS2_F_INLINE) { + int err = lfs2_dir_getread(lfs2, &file->m, + NULL, &file->cache, lfs2->cfg->block_size, + LFS2_MKTAG(0xfff, 0x1ff, 0), + LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, file->id, 0), + file->off, data, diff); + if (err) { + return err; + } + } else { + int err = lfs2_bd_read(lfs2, + NULL, &file->cache, lfs2->cfg->block_size, + file->block, file->off, data, diff); + if (err) { + return err; + } + } + + file->pos += diff; + file->off += diff; + data += diff; + nsize -= diff; + } + + return size; +} + +#ifndef LFS2_READONLY +static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, + const void *buffer, lfs2_size_t size) { + LFS2_ASSERT((file->flags & LFS2_O_WRONLY) == LFS2_O_WRONLY); + + const uint8_t *data = buffer; + lfs2_size_t nsize = size; + + if (file->flags & LFS2_F_READING) { + // drop any reads + int err = lfs2_file_flush(lfs2, file); + if (err) { + return err; + } + } + + if ((file->flags & LFS2_O_APPEND) && file->pos < file->ctz.size) { + file->pos = file->ctz.size; + } + + if (file->pos + size > lfs2->file_max) { + // Larger than file limit? + return LFS2_ERR_FBIG; + } + + if (!(file->flags & LFS2_F_WRITING) && file->pos > file->ctz.size) { + // fill with zeros + lfs2_off_t pos = file->pos; + file->pos = file->ctz.size; + + while (file->pos < pos) { + lfs2_ssize_t res = lfs2_file_rawwrite(lfs2, file, &(uint8_t){0}, 1); + if (res < 0) { + return res; + } + } + } + + if ((file->flags & LFS2_F_INLINE) && + lfs2_max(file->pos+nsize, file->ctz.size) > + lfs2_min(0x3fe, lfs2_min( + lfs2->cfg->cache_size, lfs2->cfg->block_size/8))) { + // inline file doesn't fit anymore + int err = lfs2_file_outline(lfs2, file); + if (err) { + file->flags |= LFS2_F_ERRED; + return err; + } + } + + while (nsize > 0) { + // check if we need a new block + if (!(file->flags & LFS2_F_WRITING) || + file->off == lfs2->cfg->block_size) { + if (!(file->flags & LFS2_F_INLINE)) { + if (!(file->flags & LFS2_F_WRITING) && file->pos > 0) { + // find out which block we're extending from + int err = lfs2_ctz_find(lfs2, NULL, &file->cache, + file->ctz.head, file->ctz.size, + file->pos-1, &file->block, &file->off); + if (err) { + file->flags |= LFS2_F_ERRED; + return err; + } + + // mark cache as dirty since we may have read data into it + lfs2_cache_zero(lfs2, &file->cache); + } + + // extend file with new blocks + lfs2_alloc_ack(lfs2); + int err = lfs2_ctz_extend(lfs2, &file->cache, &lfs2->rcache, + file->block, file->pos, + &file->block, &file->off); + if (err) { + file->flags |= LFS2_F_ERRED; + return err; + } + } else { + file->block = LFS2_BLOCK_INLINE; + file->off = file->pos; + } + + file->flags |= LFS2_F_WRITING; + } + + // program as much as we can in current block + lfs2_size_t diff = lfs2_min(nsize, lfs2->cfg->block_size - file->off); + while (true) { + int err = lfs2_bd_prog(lfs2, &file->cache, &lfs2->rcache, true, + file->block, file->off, data, diff); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + goto relocate; + } + file->flags |= LFS2_F_ERRED; + return err; + } + + break; +relocate: + err = lfs2_file_relocate(lfs2, file); + if (err) { + file->flags |= LFS2_F_ERRED; + return err; + } + } + + file->pos += diff; + file->off += diff; + data += diff; + nsize -= diff; + + lfs2_alloc_ack(lfs2); + } + + file->flags &= ~LFS2_F_ERRED; + return size; +} +#endif + +static lfs2_soff_t lfs2_file_rawseek(lfs2_t *lfs2, lfs2_file_t *file, + lfs2_soff_t off, int whence) { +#ifndef LFS2_READONLY + // write out everything beforehand, may be noop if rdonly + int err = lfs2_file_flush(lfs2, file); + if (err) { + return err; + } +#endif + + // find new pos + lfs2_off_t npos = file->pos; + if (whence == LFS2_SEEK_SET) { + npos = off; + } else if (whence == LFS2_SEEK_CUR) { + npos = file->pos + off; + } else if (whence == LFS2_SEEK_END) { + npos = file->ctz.size + off; + } + + if (npos > lfs2->file_max) { + // file position out of range + return LFS2_ERR_INVAL; + } + + // update pos + file->pos = npos; + return npos; +} + +#ifndef LFS2_READONLY +static int lfs2_file_rawtruncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { + LFS2_ASSERT((file->flags & LFS2_O_WRONLY) == LFS2_O_WRONLY); + + if (size > LFS2_FILE_MAX) { + return LFS2_ERR_INVAL; + } + + lfs2_off_t pos = file->pos; + lfs2_off_t oldsize = lfs2_file_rawsize(lfs2, file); + if (size < oldsize) { + // need to flush since directly changing metadata + int err = lfs2_file_flush(lfs2, file); + if (err) { + return err; + } + + // lookup new head in ctz skip list + err = lfs2_ctz_find(lfs2, NULL, &file->cache, + file->ctz.head, file->ctz.size, + size, &file->block, &file->off); + if (err) { + return err; + } + + file->ctz.head = file->block; + file->ctz.size = size; + file->flags |= LFS2_F_DIRTY | LFS2_F_READING; + } else if (size > oldsize) { + // flush+seek if not already at end + if (file->pos != oldsize) { + lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, 0, LFS2_SEEK_END); + if (res < 0) { + return (int)res; + } + } + + // fill with zeros + while (file->pos < size) { + lfs2_ssize_t res = lfs2_file_rawwrite(lfs2, file, &(uint8_t){0}, 1); + if (res < 0) { + return (int)res; + } + } + } + + // restore pos + lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, pos, LFS2_SEEK_SET); + if (res < 0) { + return (int)res; + } + + return 0; +} +#endif + +static lfs2_soff_t lfs2_file_rawtell(lfs2_t *lfs2, lfs2_file_t *file) { + (void)lfs2; + return file->pos; +} + +static int lfs2_file_rawrewind(lfs2_t *lfs2, lfs2_file_t *file) { + lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, 0, LFS2_SEEK_SET); + if (res < 0) { + return (int)res; + } + + return 0; +} + +static lfs2_soff_t lfs2_file_rawsize(lfs2_t *lfs2, lfs2_file_t *file) { + (void)lfs2; + +#ifndef LFS2_READONLY + if (file->flags & LFS2_F_WRITING) { + return lfs2_max(file->pos, file->ctz.size); + } +#endif + + return file->ctz.size; +} + + +/// General fs operations /// +static int lfs2_rawstat(lfs2_t *lfs2, const char *path, struct lfs2_info *info) { + lfs2_mdir_t cwd; + lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); + if (tag < 0) { + return (int)tag; + } + + return lfs2_dir_getinfo(lfs2, &cwd, lfs2_tag_id(tag), info); +} + +#ifndef LFS2_READONLY +static int lfs2_rawremove(lfs2_t *lfs2, const char *path) { + // deorphan if we haven't yet, needed at most once after poweron + int err = lfs2_fs_forceconsistency(lfs2); + if (err) { + return err; + } + + lfs2_mdir_t cwd; + lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); + if (tag < 0 || lfs2_tag_id(tag) == 0x3ff) { + return (tag < 0) ? (int)tag : LFS2_ERR_INVAL; + } + + struct lfs2_mlist dir; + dir.next = lfs2->mlist; + if (lfs2_tag_type3(tag) == LFS2_TYPE_DIR) { + // must be empty before removal + lfs2_block_t pair[2]; + lfs2_stag_t res = lfs2_dir_get(lfs2, &cwd, LFS2_MKTAG(0x700, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, lfs2_tag_id(tag), 8), pair); + if (res < 0) { + return (int)res; + } + lfs2_pair_fromle32(pair); + + err = lfs2_dir_fetch(lfs2, &dir.m, pair); + if (err) { + return err; + } + + if (dir.m.count > 0 || dir.m.split) { + return LFS2_ERR_NOTEMPTY; + } + + // mark fs as orphaned + lfs2_fs_preporphans(lfs2, +1); + + // I know it's crazy but yes, dir can be changed by our parent's + // commit (if predecessor is child) + dir.type = 0; + dir.id = 0; + lfs2->mlist = &dir; + } + + // delete the entry + err = lfs2_dir_commit(lfs2, &cwd, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_DELETE, lfs2_tag_id(tag), 0), NULL})); + if (err) { + lfs2->mlist = dir.next; + return err; + } + + lfs2->mlist = dir.next; + if (lfs2_tag_type3(tag) == LFS2_TYPE_DIR) { + // fix orphan + lfs2_fs_preporphans(lfs2, -1); + + err = lfs2_fs_pred(lfs2, dir.m.pair, &cwd); + if (err) { + return err; + } + + err = lfs2_dir_drop(lfs2, &cwd, &dir.m); + if (err) { + return err; + } + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { + // deorphan if we haven't yet, needed at most once after poweron + int err = lfs2_fs_forceconsistency(lfs2); + if (err) { + return err; + } + + // find old entry + lfs2_mdir_t oldcwd; + lfs2_stag_t oldtag = lfs2_dir_find(lfs2, &oldcwd, &oldpath, NULL); + if (oldtag < 0 || lfs2_tag_id(oldtag) == 0x3ff) { + return (oldtag < 0) ? (int)oldtag : LFS2_ERR_INVAL; + } + + // find new entry + lfs2_mdir_t newcwd; + uint16_t newid; + lfs2_stag_t prevtag = lfs2_dir_find(lfs2, &newcwd, &newpath, &newid); + if ((prevtag < 0 || lfs2_tag_id(prevtag) == 0x3ff) && + !(prevtag == LFS2_ERR_NOENT && newid != 0x3ff)) { + return (prevtag < 0) ? (int)prevtag : LFS2_ERR_INVAL; + } + + // if we're in the same pair there's a few special cases... + bool samepair = (lfs2_pair_cmp(oldcwd.pair, newcwd.pair) == 0); + uint16_t newoldid = lfs2_tag_id(oldtag); + + struct lfs2_mlist prevdir; + prevdir.next = lfs2->mlist; + if (prevtag == LFS2_ERR_NOENT) { + // check that name fits + lfs2_size_t nlen = strlen(newpath); + if (nlen > lfs2->name_max) { + return LFS2_ERR_NAMETOOLONG; + } + + // there is a small chance we are being renamed in the same + // directory/ to an id less than our old id, the global update + // to handle this is a bit messy + if (samepair && newid <= newoldid) { + newoldid += 1; + } + } else if (lfs2_tag_type3(prevtag) != lfs2_tag_type3(oldtag)) { + return LFS2_ERR_ISDIR; + } else if (samepair && newid == newoldid) { + // we're renaming to ourselves?? + return 0; + } else if (lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) { + // must be empty before removal + lfs2_block_t prevpair[2]; + lfs2_stag_t res = lfs2_dir_get(lfs2, &newcwd, LFS2_MKTAG(0x700, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, newid, 8), prevpair); + if (res < 0) { + return (int)res; + } + lfs2_pair_fromle32(prevpair); + + // must be empty before removal + err = lfs2_dir_fetch(lfs2, &prevdir.m, prevpair); + if (err) { + return err; + } + + if (prevdir.m.count > 0 || prevdir.m.split) { + return LFS2_ERR_NOTEMPTY; + } + + // mark fs as orphaned + lfs2_fs_preporphans(lfs2, +1); + + // I know it's crazy but yes, dir can be changed by our parent's + // commit (if predecessor is child) + prevdir.type = 0; + prevdir.id = 0; + lfs2->mlist = &prevdir; + } + + if (!samepair) { + lfs2_fs_prepmove(lfs2, newoldid, oldcwd.pair); + } + + // move over all attributes + err = lfs2_dir_commit(lfs2, &newcwd, LFS2_MKATTRS( + {LFS2_MKTAG_IF(prevtag != LFS2_ERR_NOENT, + LFS2_TYPE_DELETE, newid, 0), NULL}, + {LFS2_MKTAG(LFS2_TYPE_CREATE, newid, 0), NULL}, + {LFS2_MKTAG(lfs2_tag_type3(oldtag), newid, strlen(newpath)), newpath}, + {LFS2_MKTAG(LFS2_FROM_MOVE, newid, lfs2_tag_id(oldtag)), &oldcwd}, + {LFS2_MKTAG_IF(samepair, + LFS2_TYPE_DELETE, newoldid, 0), NULL})); + if (err) { + lfs2->mlist = prevdir.next; + return err; + } + + // let commit clean up after move (if we're different! otherwise move + // logic already fixed it for us) + if (!samepair && lfs2_gstate_hasmove(&lfs2->gstate)) { + // prep gstate and delete move id + lfs2_fs_prepmove(lfs2, 0x3ff, NULL); + err = lfs2_dir_commit(lfs2, &oldcwd, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_DELETE, lfs2_tag_id(oldtag), 0), NULL})); + if (err) { + lfs2->mlist = prevdir.next; + return err; + } + } + + lfs2->mlist = prevdir.next; + if (prevtag != LFS2_ERR_NOENT && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) { + // fix orphan + lfs2_fs_preporphans(lfs2, -1); + + err = lfs2_fs_pred(lfs2, prevdir.m.pair, &newcwd); + if (err) { + return err; + } + + err = lfs2_dir_drop(lfs2, &newcwd, &prevdir.m); + if (err) { + return err; + } + } + + return 0; +} +#endif + +static lfs2_ssize_t lfs2_rawgetattr(lfs2_t *lfs2, const char *path, + uint8_t type, void *buffer, lfs2_size_t size) { + lfs2_mdir_t cwd; + lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); + if (tag < 0) { + return tag; + } + + uint16_t id = lfs2_tag_id(tag); + if (id == 0x3ff) { + // special case for root + id = 0; + int err = lfs2_dir_fetch(lfs2, &cwd, lfs2->root); + if (err) { + return err; + } + } + + tag = lfs2_dir_get(lfs2, &cwd, LFS2_MKTAG(0x7ff, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_USERATTR + type, + id, lfs2_min(size, lfs2->attr_max)), + buffer); + if (tag < 0) { + if (tag == LFS2_ERR_NOENT) { + return LFS2_ERR_NOATTR; + } + + return tag; + } + + return lfs2_tag_size(tag); +} + +#ifndef LFS2_READONLY +static int lfs2_commitattr(lfs2_t *lfs2, const char *path, + uint8_t type, const void *buffer, lfs2_size_t size) { + lfs2_mdir_t cwd; + lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); + if (tag < 0) { + return tag; + } + + uint16_t id = lfs2_tag_id(tag); + if (id == 0x3ff) { + // special case for root + id = 0; + int err = lfs2_dir_fetch(lfs2, &cwd, lfs2->root); + if (err) { + return err; + } + } + + return lfs2_dir_commit(lfs2, &cwd, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_USERATTR + type, id, size), buffer})); +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_rawsetattr(lfs2_t *lfs2, const char *path, + uint8_t type, const void *buffer, lfs2_size_t size) { + if (size > lfs2->attr_max) { + return LFS2_ERR_NOSPC; + } + + return lfs2_commitattr(lfs2, path, type, buffer, size); +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_rawremoveattr(lfs2_t *lfs2, const char *path, uint8_t type) { + return lfs2_commitattr(lfs2, path, type, NULL, 0x3ff); +} +#endif + + +/// Filesystem operations /// +static int lfs2_init(lfs2_t *lfs2, const struct lfs2_config *cfg) { + lfs2->cfg = cfg; + int err = 0; + + // validate that the lfs2-cfg sizes were initiated properly before + // performing any arithmetic logics with them + LFS2_ASSERT(lfs2->cfg->read_size != 0); + LFS2_ASSERT(lfs2->cfg->prog_size != 0); + LFS2_ASSERT(lfs2->cfg->cache_size != 0); + + // check that block size is a multiple of cache size is a multiple + // of prog and read sizes + LFS2_ASSERT(lfs2->cfg->cache_size % lfs2->cfg->read_size == 0); + LFS2_ASSERT(lfs2->cfg->cache_size % lfs2->cfg->prog_size == 0); + LFS2_ASSERT(lfs2->cfg->block_size % lfs2->cfg->cache_size == 0); + + // check that the block size is large enough to fit ctz pointers + LFS2_ASSERT(4*lfs2_npw2(0xffffffff / (lfs2->cfg->block_size-2*4)) + <= lfs2->cfg->block_size); + + // block_cycles = 0 is no longer supported. + // + // block_cycles is the number of erase cycles before littlefs evicts + // metadata logs as a part of wear leveling. Suggested values are in the + // range of 100-1000, or set block_cycles to -1 to disable block-level + // wear-leveling. + LFS2_ASSERT(lfs2->cfg->block_cycles != 0); + + + // setup read cache + if (lfs2->cfg->read_buffer) { + lfs2->rcache.buffer = lfs2->cfg->read_buffer; + } else { + lfs2->rcache.buffer = lfs2_malloc(lfs2->cfg->cache_size); + if (!lfs2->rcache.buffer) { + err = LFS2_ERR_NOMEM; + goto cleanup; + } + } + + // setup program cache + if (lfs2->cfg->prog_buffer) { + lfs2->pcache.buffer = lfs2->cfg->prog_buffer; + } else { + lfs2->pcache.buffer = lfs2_malloc(lfs2->cfg->cache_size); + if (!lfs2->pcache.buffer) { + err = LFS2_ERR_NOMEM; + goto cleanup; + } + } + + // zero to avoid information leaks + lfs2_cache_zero(lfs2, &lfs2->rcache); + lfs2_cache_zero(lfs2, &lfs2->pcache); + + // setup lookahead, must be multiple of 64-bits, 32-bit aligned + LFS2_ASSERT(lfs2->cfg->lookahead_size > 0); + LFS2_ASSERT(lfs2->cfg->lookahead_size % 8 == 0 && + (uintptr_t)lfs2->cfg->lookahead_buffer % 4 == 0); + if (lfs2->cfg->lookahead_buffer) { + lfs2->free.buffer = lfs2->cfg->lookahead_buffer; + } else { + lfs2->free.buffer = lfs2_malloc(lfs2->cfg->lookahead_size); + if (!lfs2->free.buffer) { + err = LFS2_ERR_NOMEM; + goto cleanup; + } + } + + // check that the size limits are sane + LFS2_ASSERT(lfs2->cfg->name_max <= LFS2_NAME_MAX); + lfs2->name_max = lfs2->cfg->name_max; + if (!lfs2->name_max) { + lfs2->name_max = LFS2_NAME_MAX; + } + + LFS2_ASSERT(lfs2->cfg->file_max <= LFS2_FILE_MAX); + lfs2->file_max = lfs2->cfg->file_max; + if (!lfs2->file_max) { + lfs2->file_max = LFS2_FILE_MAX; + } + + LFS2_ASSERT(lfs2->cfg->attr_max <= LFS2_ATTR_MAX); + lfs2->attr_max = lfs2->cfg->attr_max; + if (!lfs2->attr_max) { + lfs2->attr_max = LFS2_ATTR_MAX; + } + + // setup default state + lfs2->root[0] = LFS2_BLOCK_NULL; + lfs2->root[1] = LFS2_BLOCK_NULL; + lfs2->mlist = NULL; + lfs2->seed = 0; + lfs2->gdisk = (lfs2_gstate_t){0}; + lfs2->gstate = (lfs2_gstate_t){0}; + lfs2->gdelta = (lfs2_gstate_t){0}; +#ifdef LFS2_MIGRATE + lfs2->lfs21 = NULL; +#endif + + return 0; + +cleanup: + lfs2_deinit(lfs2); + return err; +} + +static int lfs2_deinit(lfs2_t *lfs2) { + // free allocated memory + if (!lfs2->cfg->read_buffer) { + lfs2_free(lfs2->rcache.buffer); + } + + if (!lfs2->cfg->prog_buffer) { + lfs2_free(lfs2->pcache.buffer); + } + + if (!lfs2->cfg->lookahead_buffer) { + lfs2_free(lfs2->free.buffer); + } + + return 0; +} + +#ifndef LFS2_READONLY +static int lfs2_rawformat(lfs2_t *lfs2, const struct lfs2_config *cfg) { + int err = 0; + { + err = lfs2_init(lfs2, cfg); + if (err) { + return err; + } + + // create free lookahead + memset(lfs2->free.buffer, 0, lfs2->cfg->lookahead_size); + lfs2->free.off = 0; + lfs2->free.size = lfs2_min(8*lfs2->cfg->lookahead_size, + lfs2->cfg->block_count); + lfs2->free.i = 0; + lfs2_alloc_ack(lfs2); + + // create root dir + lfs2_mdir_t root; + err = lfs2_dir_alloc(lfs2, &root); + if (err) { + goto cleanup; + } + + // write one superblock + lfs2_superblock_t superblock = { + .version = LFS2_DISK_VERSION, + .block_size = lfs2->cfg->block_size, + .block_count = lfs2->cfg->block_count, + .name_max = lfs2->name_max, + .file_max = lfs2->file_max, + .attr_max = lfs2->attr_max, + }; + + lfs2_superblock_tole32(&superblock); + err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_CREATE, 0, 0), NULL}, + {LFS2_MKTAG(LFS2_TYPE_SUPERBLOCK, 0, 8), "littlefs"}, + {LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock})); + if (err) { + goto cleanup; + } + + // sanity check that fetch works + err = lfs2_dir_fetch(lfs2, &root, (const lfs2_block_t[2]){0, 1}); + if (err) { + goto cleanup; + } + + // force compaction to prevent accidentally mounting any + // older version of littlefs that may live on disk + root.erased = false; + err = lfs2_dir_commit(lfs2, &root, NULL, 0); + if (err) { + goto cleanup; + } + } + +cleanup: + lfs2_deinit(lfs2); + return err; + +} +#endif + +static int lfs2_rawmount(lfs2_t *lfs2, const struct lfs2_config *cfg) { + int err = lfs2_init(lfs2, cfg); + if (err) { + return err; + } + + // scan directory blocks for superblock and any global updates + lfs2_mdir_t dir = {.tail = {0, 1}}; + lfs2_block_t cycle = 0; + while (!lfs2_pair_isnull(dir.tail)) { + if (cycle >= lfs2->cfg->block_count/2) { + // loop detected + err = LFS2_ERR_CORRUPT; + goto cleanup; + } + cycle += 1; + + // fetch next block in tail list + lfs2_stag_t tag = lfs2_dir_fetchmatch(lfs2, &dir, dir.tail, + LFS2_MKTAG(0x7ff, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_SUPERBLOCK, 0, 8), + NULL, + lfs2_dir_find_match, &(struct lfs2_dir_find_match){ + lfs2, "littlefs", 8}); + if (tag < 0) { + err = tag; + goto cleanup; + } + + // has superblock? + if (tag && !lfs2_tag_isdelete(tag)) { + // update root + lfs2->root[0] = dir.pair[0]; + lfs2->root[1] = dir.pair[1]; + + // grab superblock + lfs2_superblock_t superblock; + tag = lfs2_dir_get(lfs2, &dir, LFS2_MKTAG(0x7ff, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock); + if (tag < 0) { + err = tag; + goto cleanup; + } + lfs2_superblock_fromle32(&superblock); + + // check version + uint16_t major_version = (0xffff & (superblock.version >> 16)); + uint16_t minor_version = (0xffff & (superblock.version >> 0)); + if ((major_version != LFS2_DISK_VERSION_MAJOR || + minor_version > LFS2_DISK_VERSION_MINOR)) { + LFS2_ERROR("Invalid version v%"PRIu16".%"PRIu16, + major_version, minor_version); + err = LFS2_ERR_INVAL; + goto cleanup; + } + + // check superblock configuration + if (superblock.name_max) { + if (superblock.name_max > lfs2->name_max) { + LFS2_ERROR("Unsupported name_max (%"PRIu32" > %"PRIu32")", + superblock.name_max, lfs2->name_max); + err = LFS2_ERR_INVAL; + goto cleanup; + } + + lfs2->name_max = superblock.name_max; + } + + if (superblock.file_max) { + if (superblock.file_max > lfs2->file_max) { + LFS2_ERROR("Unsupported file_max (%"PRIu32" > %"PRIu32")", + superblock.file_max, lfs2->file_max); + err = LFS2_ERR_INVAL; + goto cleanup; + } + + lfs2->file_max = superblock.file_max; + } + + if (superblock.attr_max) { + if (superblock.attr_max > lfs2->attr_max) { + LFS2_ERROR("Unsupported attr_max (%"PRIu32" > %"PRIu32")", + superblock.attr_max, lfs2->attr_max); + err = LFS2_ERR_INVAL; + goto cleanup; + } + + lfs2->attr_max = superblock.attr_max; + } + } + + // has gstate? + err = lfs2_dir_getgstate(lfs2, &dir, &lfs2->gstate); + if (err) { + goto cleanup; + } + } + + // found superblock? + if (lfs2_pair_isnull(lfs2->root)) { + err = LFS2_ERR_INVAL; + goto cleanup; + } + + // update littlefs with gstate + if (!lfs2_gstate_iszero(&lfs2->gstate)) { + LFS2_DEBUG("Found pending gstate 0x%08"PRIx32"%08"PRIx32"%08"PRIx32, + lfs2->gstate.tag, + lfs2->gstate.pair[0], + lfs2->gstate.pair[1]); + } + lfs2->gstate.tag += !lfs2_tag_isvalid(lfs2->gstate.tag); + lfs2->gdisk = lfs2->gstate; + + // setup free lookahead, to distribute allocations uniformly across + // boots, we start the allocator at a random location + lfs2->free.off = lfs2->seed % lfs2->cfg->block_count; + lfs2_alloc_drop(lfs2); + + return 0; + +cleanup: + lfs2_rawunmount(lfs2); + return err; +} + +static int lfs2_rawunmount(lfs2_t *lfs2) { + return lfs2_deinit(lfs2); +} + + +/// Filesystem filesystem operations /// +int lfs2_fs_rawtraverse(lfs2_t *lfs2, + int (*cb)(void *data, lfs2_block_t block), void *data, + bool includeorphans) { + // iterate over metadata pairs + lfs2_mdir_t dir = {.tail = {0, 1}}; + +#ifdef LFS2_MIGRATE + // also consider v1 blocks during migration + if (lfs2->lfs21) { + int err = lfs21_traverse(lfs2, cb, data); + if (err) { + return err; + } + + dir.tail[0] = lfs2->root[0]; + dir.tail[1] = lfs2->root[1]; + } +#endif + + lfs2_block_t cycle = 0; + while (!lfs2_pair_isnull(dir.tail)) { + if (cycle >= lfs2->cfg->block_count/2) { + // loop detected + return LFS2_ERR_CORRUPT; + } + cycle += 1; + + for (int i = 0; i < 2; i++) { + int err = cb(data, dir.tail[i]); + if (err) { + return err; + } + } + + // iterate through ids in directory + int err = lfs2_dir_fetch(lfs2, &dir, dir.tail); + if (err) { + return err; + } + + for (uint16_t id = 0; id < dir.count; id++) { + struct lfs2_ctz ctz; + lfs2_stag_t tag = lfs2_dir_get(lfs2, &dir, LFS2_MKTAG(0x700, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_STRUCT, id, sizeof(ctz)), &ctz); + if (tag < 0) { + if (tag == LFS2_ERR_NOENT) { + continue; + } + return tag; + } + lfs2_ctz_fromle32(&ctz); + + if (lfs2_tag_type3(tag) == LFS2_TYPE_CTZSTRUCT) { + err = lfs2_ctz_traverse(lfs2, NULL, &lfs2->rcache, + ctz.head, ctz.size, cb, data); + if (err) { + return err; + } + } else if (includeorphans && + lfs2_tag_type3(tag) == LFS2_TYPE_DIRSTRUCT) { + for (int i = 0; i < 2; i++) { + err = cb(data, (&ctz.head)[i]); + if (err) { + return err; + } + } + } + } + } + +#ifndef LFS2_READONLY + // iterate over any open files + for (lfs2_file_t *f = (lfs2_file_t*)lfs2->mlist; f; f = f->next) { + if (f->type != LFS2_TYPE_REG) { + continue; + } + + if ((f->flags & LFS2_F_DIRTY) && !(f->flags & LFS2_F_INLINE)) { + int err = lfs2_ctz_traverse(lfs2, &f->cache, &lfs2->rcache, + f->ctz.head, f->ctz.size, cb, data); + if (err) { + return err; + } + } + + if ((f->flags & LFS2_F_WRITING) && !(f->flags & LFS2_F_INLINE)) { + int err = lfs2_ctz_traverse(lfs2, &f->cache, &lfs2->rcache, + f->block, f->pos, cb, data); + if (err) { + return err; + } + } + } +#endif + + return 0; +} + +#ifndef LFS2_READONLY +static int lfs2_fs_pred(lfs2_t *lfs2, + const lfs2_block_t pair[2], lfs2_mdir_t *pdir) { + // iterate over all directory directory entries + pdir->tail[0] = 0; + pdir->tail[1] = 1; + lfs2_block_t cycle = 0; + while (!lfs2_pair_isnull(pdir->tail)) { + if (cycle >= lfs2->cfg->block_count/2) { + // loop detected + return LFS2_ERR_CORRUPT; + } + cycle += 1; + + if (lfs2_pair_cmp(pdir->tail, pair) == 0) { + return 0; + } + + int err = lfs2_dir_fetch(lfs2, pdir, pdir->tail); + if (err) { + return err; + } + } + + return LFS2_ERR_NOENT; +} +#endif + +#ifndef LFS2_READONLY +struct lfs2_fs_parent_match { + lfs2_t *lfs2; + const lfs2_block_t pair[2]; +}; +#endif + +#ifndef LFS2_READONLY +static int lfs2_fs_parent_match(void *data, + lfs2_tag_t tag, const void *buffer) { + struct lfs2_fs_parent_match *find = data; + lfs2_t *lfs2 = find->lfs2; + const struct lfs2_diskoff *disk = buffer; + (void)tag; + + lfs2_block_t child[2]; + int err = lfs2_bd_read(lfs2, + &lfs2->pcache, &lfs2->rcache, lfs2->cfg->block_size, + disk->block, disk->off, &child, sizeof(child)); + if (err) { + return err; + } + + lfs2_pair_fromle32(child); + return (lfs2_pair_cmp(child, find->pair) == 0) ? LFS2_CMP_EQ : LFS2_CMP_LT; +} +#endif + +#ifndef LFS2_READONLY +static lfs2_stag_t lfs2_fs_parent(lfs2_t *lfs2, const lfs2_block_t pair[2], + lfs2_mdir_t *parent) { + // use fetchmatch with callback to find pairs + parent->tail[0] = 0; + parent->tail[1] = 1; + lfs2_block_t cycle = 0; + while (!lfs2_pair_isnull(parent->tail)) { + if (cycle >= lfs2->cfg->block_count/2) { + // loop detected + return LFS2_ERR_CORRUPT; + } + cycle += 1; + + lfs2_stag_t tag = lfs2_dir_fetchmatch(lfs2, parent, parent->tail, + LFS2_MKTAG(0x7ff, 0, 0x3ff), + LFS2_MKTAG(LFS2_TYPE_DIRSTRUCT, 0, 8), + NULL, + lfs2_fs_parent_match, &(struct lfs2_fs_parent_match){ + lfs2, {pair[0], pair[1]}}); + if (tag && tag != LFS2_ERR_NOENT) { + return tag; + } + } + + return LFS2_ERR_NOENT; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_fs_relocate(lfs2_t *lfs2, + const lfs2_block_t oldpair[2], lfs2_block_t newpair[2]) { + // update internal root + if (lfs2_pair_cmp(oldpair, lfs2->root) == 0) { + lfs2->root[0] = newpair[0]; + lfs2->root[1] = newpair[1]; + } + + // update internally tracked dirs + for (struct lfs2_mlist *d = lfs2->mlist; d; d = d->next) { + if (lfs2_pair_cmp(oldpair, d->m.pair) == 0) { + d->m.pair[0] = newpair[0]; + d->m.pair[1] = newpair[1]; + } + + if (d->type == LFS2_TYPE_DIR && + lfs2_pair_cmp(oldpair, ((lfs2_dir_t*)d)->head) == 0) { + ((lfs2_dir_t*)d)->head[0] = newpair[0]; + ((lfs2_dir_t*)d)->head[1] = newpair[1]; + } + } + + // find parent + lfs2_mdir_t parent; + lfs2_stag_t tag = lfs2_fs_parent(lfs2, oldpair, &parent); + if (tag < 0 && tag != LFS2_ERR_NOENT) { + return tag; + } + + if (tag != LFS2_ERR_NOENT) { + // update disk, this creates a desync + lfs2_fs_preporphans(lfs2, +1); + + // fix pending move in this pair? this looks like an optimization but + // is in fact _required_ since relocating may outdate the move. + uint16_t moveid = 0x3ff; + if (lfs2_gstate_hasmovehere(&lfs2->gstate, parent.pair)) { + moveid = lfs2_tag_id(lfs2->gstate.tag); + LFS2_DEBUG("Fixing move while relocating " + "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", + parent.pair[0], parent.pair[1], moveid); + lfs2_fs_prepmove(lfs2, 0x3ff, NULL); + if (moveid < lfs2_tag_id(tag)) { + tag -= LFS2_MKTAG(0, 1, 0); + } + } + + lfs2_pair_tole32(newpair); + int err = lfs2_dir_commit(lfs2, &parent, LFS2_MKATTRS( + {LFS2_MKTAG_IF(moveid != 0x3ff, + LFS2_TYPE_DELETE, moveid, 0), NULL}, + {tag, newpair})); + lfs2_pair_fromle32(newpair); + if (err) { + return err; + } + + // next step, clean up orphans + lfs2_fs_preporphans(lfs2, -1); + } + + // find pred + int err = lfs2_fs_pred(lfs2, oldpair, &parent); + if (err && err != LFS2_ERR_NOENT) { + return err; + } + + // if we can't find dir, it must be new + if (err != LFS2_ERR_NOENT) { + // fix pending move in this pair? this looks like an optimization but + // is in fact _required_ since relocating may outdate the move. + uint16_t moveid = 0x3ff; + if (lfs2_gstate_hasmovehere(&lfs2->gstate, parent.pair)) { + moveid = lfs2_tag_id(lfs2->gstate.tag); + LFS2_DEBUG("Fixing move while relocating " + "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", + parent.pair[0], parent.pair[1], moveid); + lfs2_fs_prepmove(lfs2, 0x3ff, NULL); + } + + // replace bad pair, either we clean up desync, or no desync occured + lfs2_pair_tole32(newpair); + err = lfs2_dir_commit(lfs2, &parent, LFS2_MKATTRS( + {LFS2_MKTAG_IF(moveid != 0x3ff, + LFS2_TYPE_DELETE, moveid, 0), NULL}, + {LFS2_MKTAG(LFS2_TYPE_TAIL + parent.split, 0x3ff, 8), newpair})); + lfs2_pair_fromle32(newpair); + if (err) { + return err; + } + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static void lfs2_fs_preporphans(lfs2_t *lfs2, int8_t orphans) { + LFS2_ASSERT(lfs2_tag_size(lfs2->gstate.tag) > 0 || orphans >= 0); + lfs2->gstate.tag += orphans; + lfs2->gstate.tag = ((lfs2->gstate.tag & ~LFS2_MKTAG(0x800, 0, 0)) | + ((uint32_t)lfs2_gstate_hasorphans(&lfs2->gstate) << 31)); +} +#endif + +#ifndef LFS2_READONLY +static void lfs2_fs_prepmove(lfs2_t *lfs2, + uint16_t id, const lfs2_block_t pair[2]) { + lfs2->gstate.tag = ((lfs2->gstate.tag & ~LFS2_MKTAG(0x7ff, 0x3ff, 0)) | + ((id != 0x3ff) ? LFS2_MKTAG(LFS2_TYPE_DELETE, id, 0) : 0)); + lfs2->gstate.pair[0] = (id != 0x3ff) ? pair[0] : 0; + lfs2->gstate.pair[1] = (id != 0x3ff) ? pair[1] : 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_fs_demove(lfs2_t *lfs2) { + if (!lfs2_gstate_hasmove(&lfs2->gdisk)) { + return 0; + } + + // Fix bad moves + LFS2_DEBUG("Fixing move {0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16, + lfs2->gdisk.pair[0], + lfs2->gdisk.pair[1], + lfs2_tag_id(lfs2->gdisk.tag)); + + // fetch and delete the moved entry + lfs2_mdir_t movedir; + int err = lfs2_dir_fetch(lfs2, &movedir, lfs2->gdisk.pair); + if (err) { + return err; + } + + // prep gstate and delete move id + uint16_t moveid = lfs2_tag_id(lfs2->gdisk.tag); + lfs2_fs_prepmove(lfs2, 0x3ff, NULL); + err = lfs2_dir_commit(lfs2, &movedir, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_DELETE, moveid, 0), NULL})); + if (err) { + return err; + } + + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_fs_deorphan(lfs2_t *lfs2) { + if (!lfs2_gstate_hasorphans(&lfs2->gstate)) { + return 0; + } + + // Fix any orphans + lfs2_mdir_t pdir = {.split = true, .tail = {0, 1}}; + lfs2_mdir_t dir; + + // iterate over all directory directory entries + while (!lfs2_pair_isnull(pdir.tail)) { + int err = lfs2_dir_fetch(lfs2, &dir, pdir.tail); + if (err) { + return err; + } + + // check head blocks for orphans + if (!pdir.split) { + // check if we have a parent + lfs2_mdir_t parent; + lfs2_stag_t tag = lfs2_fs_parent(lfs2, pdir.tail, &parent); + if (tag < 0 && tag != LFS2_ERR_NOENT) { + return tag; + } + + if (tag == LFS2_ERR_NOENT) { + // we are an orphan + LFS2_DEBUG("Fixing orphan {0x%"PRIx32", 0x%"PRIx32"}", + pdir.tail[0], pdir.tail[1]); + + err = lfs2_dir_drop(lfs2, &pdir, &dir); + if (err) { + return err; + } + + // refetch tail + continue; + } + + lfs2_block_t pair[2]; + lfs2_stag_t res = lfs2_dir_get(lfs2, &parent, + LFS2_MKTAG(0x7ff, 0x3ff, 0), tag, pair); + if (res < 0) { + return res; + } + lfs2_pair_fromle32(pair); + + if (!lfs2_pair_sync(pair, pdir.tail)) { + // we have desynced + LFS2_DEBUG("Fixing half-orphan {0x%"PRIx32", 0x%"PRIx32"} " + "-> {0x%"PRIx32", 0x%"PRIx32"}", + pdir.tail[0], pdir.tail[1], pair[0], pair[1]); + + lfs2_pair_tole32(pair); + err = lfs2_dir_commit(lfs2, &pdir, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_SOFTTAIL, 0x3ff, 8), pair})); + lfs2_pair_fromle32(pair); + if (err) { + return err; + } + + // refetch tail + continue; + } + } + + pdir = dir; + } + + // mark orphans as fixed + lfs2_fs_preporphans(lfs2, -lfs2_gstate_getorphans(&lfs2->gstate)); + return 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_fs_forceconsistency(lfs2_t *lfs2) { + int err = lfs2_fs_demove(lfs2); + if (err) { + return err; + } + + err = lfs2_fs_deorphan(lfs2); + if (err) { + return err; + } + + return 0; +} +#endif + +static int lfs2_fs_size_count(void *p, lfs2_block_t block) { + (void)block; + lfs2_size_t *size = p; + *size += 1; + return 0; +} + +static lfs2_ssize_t lfs2_fs_rawsize(lfs2_t *lfs2) { + lfs2_size_t size = 0; + int err = lfs2_fs_rawtraverse(lfs2, lfs2_fs_size_count, &size, false); + if (err) { + return err; + } + + return size; +} + +#ifdef LFS2_MIGRATE +////// Migration from littelfs v1 below this ////// + +/// Version info /// + +// Software library version +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS21_VERSION 0x00010007 +#define LFS21_VERSION_MAJOR (0xffff & (LFS21_VERSION >> 16)) +#define LFS21_VERSION_MINOR (0xffff & (LFS21_VERSION >> 0)) + +// Version of On-disk data structures +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS21_DISK_VERSION 0x00010001 +#define LFS21_DISK_VERSION_MAJOR (0xffff & (LFS21_DISK_VERSION >> 16)) +#define LFS21_DISK_VERSION_MINOR (0xffff & (LFS21_DISK_VERSION >> 0)) + + +/// v1 Definitions /// + +// File types +enum lfs21_type { + LFS21_TYPE_REG = 0x11, + LFS21_TYPE_DIR = 0x22, + LFS21_TYPE_SUPERBLOCK = 0x2e, +}; + +typedef struct lfs21 { + lfs2_block_t root[2]; +} lfs21_t; + +typedef struct lfs21_entry { + lfs2_off_t off; + + struct lfs21_disk_entry { + uint8_t type; + uint8_t elen; + uint8_t alen; + uint8_t nlen; + union { + struct { + lfs2_block_t head; + lfs2_size_t size; + } file; + lfs2_block_t dir[2]; + } u; + } d; +} lfs21_entry_t; + +typedef struct lfs21_dir { + struct lfs21_dir *next; + lfs2_block_t pair[2]; + lfs2_off_t off; + + lfs2_block_t head[2]; + lfs2_off_t pos; + + struct lfs21_disk_dir { + uint32_t rev; + lfs2_size_t size; + lfs2_block_t tail[2]; + } d; +} lfs21_dir_t; + +typedef struct lfs21_superblock { + lfs2_off_t off; + + struct lfs21_disk_superblock { + uint8_t type; + uint8_t elen; + uint8_t alen; + uint8_t nlen; + lfs2_block_t root[2]; + uint32_t block_size; + uint32_t block_count; + uint32_t version; + char magic[8]; + } d; +} lfs21_superblock_t; + + +/// Low-level wrappers v1->v2 /// +static void lfs21_crc(uint32_t *crc, const void *buffer, size_t size) { + *crc = lfs2_crc(*crc, buffer, size); +} + +static int lfs21_bd_read(lfs2_t *lfs2, lfs2_block_t block, + lfs2_off_t off, void *buffer, lfs2_size_t size) { + // if we ever do more than writes to alternating pairs, + // this may need to consider pcache + return lfs2_bd_read(lfs2, &lfs2->pcache, &lfs2->rcache, size, + block, off, buffer, size); +} + +static int lfs21_bd_crc(lfs2_t *lfs2, lfs2_block_t block, + lfs2_off_t off, lfs2_size_t size, uint32_t *crc) { + for (lfs2_off_t i = 0; i < size; i++) { + uint8_t c; + int err = lfs21_bd_read(lfs2, block, off+i, &c, 1); + if (err) { + return err; + } + + lfs21_crc(crc, &c, 1); + } + + return 0; +} + + +/// Endian swapping functions /// +static void lfs21_dir_fromle32(struct lfs21_disk_dir *d) { + d->rev = lfs2_fromle32(d->rev); + d->size = lfs2_fromle32(d->size); + d->tail[0] = lfs2_fromle32(d->tail[0]); + d->tail[1] = lfs2_fromle32(d->tail[1]); +} + +static void lfs21_dir_tole32(struct lfs21_disk_dir *d) { + d->rev = lfs2_tole32(d->rev); + d->size = lfs2_tole32(d->size); + d->tail[0] = lfs2_tole32(d->tail[0]); + d->tail[1] = lfs2_tole32(d->tail[1]); +} + +static void lfs21_entry_fromle32(struct lfs21_disk_entry *d) { + d->u.dir[0] = lfs2_fromle32(d->u.dir[0]); + d->u.dir[1] = lfs2_fromle32(d->u.dir[1]); +} + +static void lfs21_entry_tole32(struct lfs21_disk_entry *d) { + d->u.dir[0] = lfs2_tole32(d->u.dir[0]); + d->u.dir[1] = lfs2_tole32(d->u.dir[1]); +} + +static void lfs21_superblock_fromle32(struct lfs21_disk_superblock *d) { + d->root[0] = lfs2_fromle32(d->root[0]); + d->root[1] = lfs2_fromle32(d->root[1]); + d->block_size = lfs2_fromle32(d->block_size); + d->block_count = lfs2_fromle32(d->block_count); + d->version = lfs2_fromle32(d->version); +} + + +///// Metadata pair and directory operations /// +static inline lfs2_size_t lfs21_entry_size(const lfs21_entry_t *entry) { + return 4 + entry->d.elen + entry->d.alen + entry->d.nlen; +} + +static int lfs21_dir_fetch(lfs2_t *lfs2, + lfs21_dir_t *dir, const lfs2_block_t pair[2]) { + // copy out pair, otherwise may be aliasing dir + const lfs2_block_t tpair[2] = {pair[0], pair[1]}; + bool valid = false; + + // check both blocks for the most recent revision + for (int i = 0; i < 2; i++) { + struct lfs21_disk_dir test; + int err = lfs21_bd_read(lfs2, tpair[i], 0, &test, sizeof(test)); + lfs21_dir_fromle32(&test); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + continue; + } + return err; + } + + if (valid && lfs2_scmp(test.rev, dir->d.rev) < 0) { + continue; + } + + if ((0x7fffffff & test.size) < sizeof(test)+4 || + (0x7fffffff & test.size) > lfs2->cfg->block_size) { + continue; + } + + uint32_t crc = 0xffffffff; + lfs21_dir_tole32(&test); + lfs21_crc(&crc, &test, sizeof(test)); + lfs21_dir_fromle32(&test); + err = lfs21_bd_crc(lfs2, tpair[i], sizeof(test), + (0x7fffffff & test.size) - sizeof(test), &crc); + if (err) { + if (err == LFS2_ERR_CORRUPT) { + continue; + } + return err; + } + + if (crc != 0) { + continue; + } + + valid = true; + + // setup dir in case it's valid + dir->pair[0] = tpair[(i+0) % 2]; + dir->pair[1] = tpair[(i+1) % 2]; + dir->off = sizeof(dir->d); + dir->d = test; + } + + if (!valid) { + LFS2_ERROR("Corrupted dir pair at {0x%"PRIx32", 0x%"PRIx32"}", + tpair[0], tpair[1]); + return LFS2_ERR_CORRUPT; + } + + return 0; +} + +static int lfs21_dir_next(lfs2_t *lfs2, lfs21_dir_t *dir, lfs21_entry_t *entry) { + while (dir->off + sizeof(entry->d) > (0x7fffffff & dir->d.size)-4) { + if (!(0x80000000 & dir->d.size)) { + entry->off = dir->off; + return LFS2_ERR_NOENT; + } + + int err = lfs21_dir_fetch(lfs2, dir, dir->d.tail); + if (err) { + return err; + } + + dir->off = sizeof(dir->d); + dir->pos += sizeof(dir->d) + 4; + } + + int err = lfs21_bd_read(lfs2, dir->pair[0], dir->off, + &entry->d, sizeof(entry->d)); + lfs21_entry_fromle32(&entry->d); + if (err) { + return err; + } + + entry->off = dir->off; + dir->off += lfs21_entry_size(entry); + dir->pos += lfs21_entry_size(entry); + return 0; +} + +/// littlefs v1 specific operations /// +int lfs21_traverse(lfs2_t *lfs2, int (*cb)(void*, lfs2_block_t), void *data) { + if (lfs2_pair_isnull(lfs2->lfs21->root)) { + return 0; + } + + // iterate over metadata pairs + lfs21_dir_t dir; + lfs21_entry_t entry; + lfs2_block_t cwd[2] = {0, 1}; + + while (true) { + for (int i = 0; i < 2; i++) { + int err = cb(data, cwd[i]); + if (err) { + return err; + } + } + + int err = lfs21_dir_fetch(lfs2, &dir, cwd); + if (err) { + return err; + } + + // iterate over contents + while (dir.off + sizeof(entry.d) <= (0x7fffffff & dir.d.size)-4) { + err = lfs21_bd_read(lfs2, dir.pair[0], dir.off, + &entry.d, sizeof(entry.d)); + lfs21_entry_fromle32(&entry.d); + if (err) { + return err; + } + + dir.off += lfs21_entry_size(&entry); + if ((0x70 & entry.d.type) == (0x70 & LFS21_TYPE_REG)) { + err = lfs2_ctz_traverse(lfs2, NULL, &lfs2->rcache, + entry.d.u.file.head, entry.d.u.file.size, cb, data); + if (err) { + return err; + } + } + } + + // we also need to check if we contain a threaded v2 directory + lfs2_mdir_t dir2 = {.split=true, .tail={cwd[0], cwd[1]}}; + while (dir2.split) { + err = lfs2_dir_fetch(lfs2, &dir2, dir2.tail); + if (err) { + break; + } + + for (int i = 0; i < 2; i++) { + err = cb(data, dir2.pair[i]); + if (err) { + return err; + } + } + } + + cwd[0] = dir.d.tail[0]; + cwd[1] = dir.d.tail[1]; + + if (lfs2_pair_isnull(cwd)) { + break; + } + } + + return 0; +} + +static int lfs21_moved(lfs2_t *lfs2, const void *e) { + if (lfs2_pair_isnull(lfs2->lfs21->root)) { + return 0; + } + + // skip superblock + lfs21_dir_t cwd; + int err = lfs21_dir_fetch(lfs2, &cwd, (const lfs2_block_t[2]){0, 1}); + if (err) { + return err; + } + + // iterate over all directory directory entries + lfs21_entry_t entry; + while (!lfs2_pair_isnull(cwd.d.tail)) { + err = lfs21_dir_fetch(lfs2, &cwd, cwd.d.tail); + if (err) { + return err; + } + + while (true) { + err = lfs21_dir_next(lfs2, &cwd, &entry); + if (err && err != LFS2_ERR_NOENT) { + return err; + } + + if (err == LFS2_ERR_NOENT) { + break; + } + + if (!(0x80 & entry.d.type) && + memcmp(&entry.d.u, e, sizeof(entry.d.u)) == 0) { + return true; + } + } + } + + return false; +} + +/// Filesystem operations /// +static int lfs21_mount(lfs2_t *lfs2, struct lfs21 *lfs21, + const struct lfs2_config *cfg) { + int err = 0; + { + err = lfs2_init(lfs2, cfg); + if (err) { + return err; + } + + lfs2->lfs21 = lfs21; + lfs2->lfs21->root[0] = LFS2_BLOCK_NULL; + lfs2->lfs21->root[1] = LFS2_BLOCK_NULL; + + // setup free lookahead + lfs2->free.off = 0; + lfs2->free.size = 0; + lfs2->free.i = 0; + lfs2_alloc_ack(lfs2); + + // load superblock + lfs21_dir_t dir; + lfs21_superblock_t superblock; + err = lfs21_dir_fetch(lfs2, &dir, (const lfs2_block_t[2]){0, 1}); + if (err && err != LFS2_ERR_CORRUPT) { + goto cleanup; + } + + if (!err) { + err = lfs21_bd_read(lfs2, dir.pair[0], sizeof(dir.d), + &superblock.d, sizeof(superblock.d)); + lfs21_superblock_fromle32(&superblock.d); + if (err) { + goto cleanup; + } + + lfs2->lfs21->root[0] = superblock.d.root[0]; + lfs2->lfs21->root[1] = superblock.d.root[1]; + } + + if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) { + LFS2_ERROR("Invalid superblock at {0x%"PRIx32", 0x%"PRIx32"}", + 0, 1); + err = LFS2_ERR_CORRUPT; + goto cleanup; + } + + uint16_t major_version = (0xffff & (superblock.d.version >> 16)); + uint16_t minor_version = (0xffff & (superblock.d.version >> 0)); + if ((major_version != LFS21_DISK_VERSION_MAJOR || + minor_version > LFS21_DISK_VERSION_MINOR)) { + LFS2_ERROR("Invalid version v%d.%d", major_version, minor_version); + err = LFS2_ERR_INVAL; + goto cleanup; + } + + return 0; + } + +cleanup: + lfs2_deinit(lfs2); + return err; +} + +static int lfs21_unmount(lfs2_t *lfs2) { + return lfs2_deinit(lfs2); +} + +/// v1 migration /// +static int lfs2_rawmigrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { + struct lfs21 lfs21; + int err = lfs21_mount(lfs2, &lfs21, cfg); + if (err) { + return err; + } + + { + // iterate through each directory, copying over entries + // into new directory + lfs21_dir_t dir1; + lfs2_mdir_t dir2; + dir1.d.tail[0] = lfs2->lfs21->root[0]; + dir1.d.tail[1] = lfs2->lfs21->root[1]; + while (!lfs2_pair_isnull(dir1.d.tail)) { + // iterate old dir + err = lfs21_dir_fetch(lfs2, &dir1, dir1.d.tail); + if (err) { + goto cleanup; + } + + // create new dir and bind as temporary pretend root + err = lfs2_dir_alloc(lfs2, &dir2); + if (err) { + goto cleanup; + } + + dir2.rev = dir1.d.rev; + dir1.head[0] = dir1.pair[0]; + dir1.head[1] = dir1.pair[1]; + lfs2->root[0] = dir2.pair[0]; + lfs2->root[1] = dir2.pair[1]; + + err = lfs2_dir_commit(lfs2, &dir2, NULL, 0); + if (err) { + goto cleanup; + } + + while (true) { + lfs21_entry_t entry1; + err = lfs21_dir_next(lfs2, &dir1, &entry1); + if (err && err != LFS2_ERR_NOENT) { + goto cleanup; + } + + if (err == LFS2_ERR_NOENT) { + break; + } + + // check that entry has not been moved + if (entry1.d.type & 0x80) { + int moved = lfs21_moved(lfs2, &entry1.d.u); + if (moved < 0) { + err = moved; + goto cleanup; + } + + if (moved) { + continue; + } + + entry1.d.type &= ~0x80; + } + + // also fetch name + char name[LFS2_NAME_MAX+1]; + memset(name, 0, sizeof(name)); + err = lfs21_bd_read(lfs2, dir1.pair[0], + entry1.off + 4+entry1.d.elen+entry1.d.alen, + name, entry1.d.nlen); + if (err) { + goto cleanup; + } + + bool isdir = (entry1.d.type == LFS21_TYPE_DIR); + + // create entry in new dir + err = lfs2_dir_fetch(lfs2, &dir2, lfs2->root); + if (err) { + goto cleanup; + } + + uint16_t id; + err = lfs2_dir_find(lfs2, &dir2, &(const char*){name}, &id); + if (!(err == LFS2_ERR_NOENT && id != 0x3ff)) { + err = (err < 0) ? err : LFS2_ERR_EXIST; + goto cleanup; + } + + lfs21_entry_tole32(&entry1.d); + err = lfs2_dir_commit(lfs2, &dir2, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_CREATE, id, 0)}, + {LFS2_MKTAG_IF_ELSE(isdir, + LFS2_TYPE_DIR, id, entry1.d.nlen, + LFS2_TYPE_REG, id, entry1.d.nlen), + name}, + {LFS2_MKTAG_IF_ELSE(isdir, + LFS2_TYPE_DIRSTRUCT, id, sizeof(entry1.d.u), + LFS2_TYPE_CTZSTRUCT, id, sizeof(entry1.d.u)), + &entry1.d.u})); + lfs21_entry_fromle32(&entry1.d); + if (err) { + goto cleanup; + } + } + + if (!lfs2_pair_isnull(dir1.d.tail)) { + // find last block and update tail to thread into fs + err = lfs2_dir_fetch(lfs2, &dir2, lfs2->root); + if (err) { + goto cleanup; + } + + while (dir2.split) { + err = lfs2_dir_fetch(lfs2, &dir2, dir2.tail); + if (err) { + goto cleanup; + } + } + + lfs2_pair_tole32(dir2.pair); + err = lfs2_dir_commit(lfs2, &dir2, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_SOFTTAIL, 0x3ff, 8), dir1.d.tail})); + lfs2_pair_fromle32(dir2.pair); + if (err) { + goto cleanup; + } + } + + // Copy over first block to thread into fs. Unfortunately + // if this fails there is not much we can do. + LFS2_DEBUG("Migrating {0x%"PRIx32", 0x%"PRIx32"} " + "-> {0x%"PRIx32", 0x%"PRIx32"}", + lfs2->root[0], lfs2->root[1], dir1.head[0], dir1.head[1]); + + err = lfs2_bd_erase(lfs2, dir1.head[1]); + if (err) { + goto cleanup; + } + + err = lfs2_dir_fetch(lfs2, &dir2, lfs2->root); + if (err) { + goto cleanup; + } + + for (lfs2_off_t i = 0; i < dir2.off; i++) { + uint8_t dat; + err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, dir2.off, + dir2.pair[0], i, &dat, 1); + if (err) { + goto cleanup; + } + + err = lfs2_bd_prog(lfs2, + &lfs2->pcache, &lfs2->rcache, true, + dir1.head[1], i, &dat, 1); + if (err) { + goto cleanup; + } + } + + err = lfs2_bd_flush(lfs2, &lfs2->pcache, &lfs2->rcache, true); + if (err) { + goto cleanup; + } + } + + // Create new superblock. This marks a successful migration! + err = lfs21_dir_fetch(lfs2, &dir1, (const lfs2_block_t[2]){0, 1}); + if (err) { + goto cleanup; + } + + dir2.pair[0] = dir1.pair[0]; + dir2.pair[1] = dir1.pair[1]; + dir2.rev = dir1.d.rev; + dir2.off = sizeof(dir2.rev); + dir2.etag = 0xffffffff; + dir2.count = 0; + dir2.tail[0] = lfs2->lfs21->root[0]; + dir2.tail[1] = lfs2->lfs21->root[1]; + dir2.erased = false; + dir2.split = true; + + lfs2_superblock_t superblock = { + .version = LFS2_DISK_VERSION, + .block_size = lfs2->cfg->block_size, + .block_count = lfs2->cfg->block_count, + .name_max = lfs2->name_max, + .file_max = lfs2->file_max, + .attr_max = lfs2->attr_max, + }; + + lfs2_superblock_tole32(&superblock); + err = lfs2_dir_commit(lfs2, &dir2, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_CREATE, 0, 0)}, + {LFS2_MKTAG(LFS2_TYPE_SUPERBLOCK, 0, 8), "littlefs"}, + {LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock})); + if (err) { + goto cleanup; + } + + // sanity check that fetch works + err = lfs2_dir_fetch(lfs2, &dir2, (const lfs2_block_t[2]){0, 1}); + if (err) { + goto cleanup; + } + + // force compaction to prevent accidentally mounting v1 + dir2.erased = false; + err = lfs2_dir_commit(lfs2, &dir2, NULL, 0); + if (err) { + goto cleanup; + } + } + +cleanup: + lfs21_unmount(lfs2); + return err; +} + +#endif + + +/// Public API wrappers /// + +// Here we can add tracing/thread safety easily + +// Thread-safe wrappers if enabled +#ifdef LFS2_THREADSAFE +#define LFS2_LOCK(cfg) cfg->lock(cfg) +#define LFS2_UNLOCK(cfg) cfg->unlock(cfg) +#else +#define LFS2_LOCK(cfg) ((void)cfg, 0) +#define LFS2_UNLOCK(cfg) ((void)cfg) +#endif + +// Public API +#ifndef LFS2_READONLY +int lfs2_format(lfs2_t *lfs2, const struct lfs2_config *cfg) { + int err = LFS2_LOCK(cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_format(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs2, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); + + err = lfs2_rawformat(lfs2, cfg); + + LFS2_TRACE("lfs2_format -> %d", err); + LFS2_UNLOCK(cfg); + return err; +} +#endif + +int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *cfg) { + int err = LFS2_LOCK(cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_mount(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs2, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); + + err = lfs2_rawmount(lfs2, cfg); + + LFS2_TRACE("lfs2_mount -> %d", err); + LFS2_UNLOCK(cfg); + return err; +} + +int lfs2_unmount(lfs2_t *lfs2) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_unmount(%p)", (void*)lfs2); + + err = lfs2_rawunmount(lfs2); + + LFS2_TRACE("lfs2_unmount -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +#ifndef LFS2_READONLY +int lfs2_remove(lfs2_t *lfs2, const char *path) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_remove(%p, \"%s\")", (void*)lfs2, path); + + err = lfs2_rawremove(lfs2, path); + + LFS2_TRACE("lfs2_remove -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} +#endif + +#ifndef LFS2_READONLY +int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_rename(%p, \"%s\", \"%s\")", (void*)lfs2, oldpath, newpath); + + err = lfs2_rawrename(lfs2, oldpath, newpath); + + LFS2_TRACE("lfs2_rename -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} +#endif + +int lfs2_stat(lfs2_t *lfs2, const char *path, struct lfs2_info *info) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_stat(%p, \"%s\", %p)", (void*)lfs2, path, (void*)info); + + err = lfs2_rawstat(lfs2, path, info); + + LFS2_TRACE("lfs2_stat -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path, + uint8_t type, void *buffer, lfs2_size_t size) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_getattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", + (void*)lfs2, path, type, buffer, size); + + lfs2_ssize_t res = lfs2_rawgetattr(lfs2, path, type, buffer, size); + + LFS2_TRACE("lfs2_getattr -> %"PRId32, res); + LFS2_UNLOCK(lfs2->cfg); + return res; +} + +#ifndef LFS2_READONLY +int lfs2_setattr(lfs2_t *lfs2, const char *path, + uint8_t type, const void *buffer, lfs2_size_t size) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_setattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", + (void*)lfs2, path, type, buffer, size); + + err = lfs2_rawsetattr(lfs2, path, type, buffer, size); + + LFS2_TRACE("lfs2_setattr -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} +#endif + +#ifndef LFS2_READONLY +int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs2, path, type); + + err = lfs2_rawremoveattr(lfs2, path, type); + + LFS2_TRACE("lfs2_removeattr -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} +#endif + +int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_open(%p, %p, \"%s\", %x)", + (void*)lfs2, (void*)file, path, flags); + LFS2_ASSERT(!lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + err = lfs2_file_rawopen(lfs2, file, path, flags); + + LFS2_TRACE("lfs2_file_open -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +int lfs2_file_opencfg(lfs2_t *lfs2, lfs2_file_t *file, + const char *path, int flags, + const struct lfs2_file_config *cfg) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_opencfg(%p, %p, \"%s\", %x, %p {" + ".buffer=%p, .attrs=%p, .attr_count=%"PRIu32"})", + (void*)lfs2, (void*)file, path, flags, + (void*)cfg, cfg->buffer, (void*)cfg->attrs, cfg->attr_count); + LFS2_ASSERT(!lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + err = lfs2_file_rawopencfg(lfs2, file, path, flags, cfg); + + LFS2_TRACE("lfs2_file_opencfg -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +int lfs2_file_close(lfs2_t *lfs2, lfs2_file_t *file) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_close(%p, %p)", (void*)lfs2, (void*)file); + LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + err = lfs2_file_rawclose(lfs2, file); + + LFS2_TRACE("lfs2_file_close -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +#ifndef LFS2_READONLY +int lfs2_file_sync(lfs2_t *lfs2, lfs2_file_t *file) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_sync(%p, %p)", (void*)lfs2, (void*)file); + LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + err = lfs2_file_rawsync(lfs2, file); + + LFS2_TRACE("lfs2_file_sync -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} +#endif + +lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file, + void *buffer, lfs2_size_t size) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_read(%p, %p, %p, %"PRIu32")", + (void*)lfs2, (void*)file, buffer, size); + LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + lfs2_ssize_t res = lfs2_file_rawread(lfs2, file, buffer, size); + + LFS2_TRACE("lfs2_file_read -> %"PRId32, res); + LFS2_UNLOCK(lfs2->cfg); + return res; +} + +#ifndef LFS2_READONLY +lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, + const void *buffer, lfs2_size_t size) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_write(%p, %p, %p, %"PRIu32")", + (void*)lfs2, (void*)file, buffer, size); + LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + lfs2_ssize_t res = lfs2_file_rawwrite(lfs2, file, buffer, size); + + LFS2_TRACE("lfs2_file_write -> %"PRId32, res); + LFS2_UNLOCK(lfs2->cfg); + return res; +} +#endif + +lfs2_soff_t lfs2_file_seek(lfs2_t *lfs2, lfs2_file_t *file, + lfs2_soff_t off, int whence) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_seek(%p, %p, %"PRId32", %d)", + (void*)lfs2, (void*)file, off, whence); + LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, off, whence); + + LFS2_TRACE("lfs2_file_seek -> %"PRId32, res); + LFS2_UNLOCK(lfs2->cfg); + return res; +} + +#ifndef LFS2_READONLY +int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_truncate(%p, %p, %"PRIu32")", + (void*)lfs2, (void*)file, size); + LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + err = lfs2_file_rawtruncate(lfs2, file, size); + + LFS2_TRACE("lfs2_file_truncate -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} +#endif + +lfs2_soff_t lfs2_file_tell(lfs2_t *lfs2, lfs2_file_t *file) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_tell(%p, %p)", (void*)lfs2, (void*)file); + LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + lfs2_soff_t res = lfs2_file_rawtell(lfs2, file); + + LFS2_TRACE("lfs2_file_tell -> %"PRId32, res); + LFS2_UNLOCK(lfs2->cfg); + return res; +} + +int lfs2_file_rewind(lfs2_t *lfs2, lfs2_file_t *file) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_rewind(%p, %p)", (void*)lfs2, (void*)file); + + err = lfs2_file_rawrewind(lfs2, file); + + LFS2_TRACE("lfs2_file_rewind -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +lfs2_soff_t lfs2_file_size(lfs2_t *lfs2, lfs2_file_t *file) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_file_size(%p, %p)", (void*)lfs2, (void*)file); + LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); + + lfs2_soff_t res = lfs2_file_rawsize(lfs2, file); + + LFS2_TRACE("lfs2_file_size -> %"PRId32, res); + LFS2_UNLOCK(lfs2->cfg); + return res; +} + +#ifndef LFS2_READONLY +int lfs2_mkdir(lfs2_t *lfs2, const char *path) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_mkdir(%p, \"%s\")", (void*)lfs2, path); + + err = lfs2_rawmkdir(lfs2, path); + + LFS2_TRACE("lfs2_mkdir -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} +#endif + +int lfs2_dir_open(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_dir_open(%p, %p, \"%s\")", (void*)lfs2, (void*)dir, path); + LFS2_ASSERT(!lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)dir)); + + err = lfs2_dir_rawopen(lfs2, dir, path); + + LFS2_TRACE("lfs2_dir_open -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +int lfs2_dir_close(lfs2_t *lfs2, lfs2_dir_t *dir) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_dir_close(%p, %p)", (void*)lfs2, (void*)dir); + + err = lfs2_dir_rawclose(lfs2, dir); + + LFS2_TRACE("lfs2_dir_close -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +int lfs2_dir_read(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_dir_read(%p, %p, %p)", + (void*)lfs2, (void*)dir, (void*)info); + + err = lfs2_dir_rawread(lfs2, dir, info); + + LFS2_TRACE("lfs2_dir_read -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +int lfs2_dir_seek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_dir_seek(%p, %p, %"PRIu32")", + (void*)lfs2, (void*)dir, off); + + err = lfs2_dir_rawseek(lfs2, dir, off); + + LFS2_TRACE("lfs2_dir_seek -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +lfs2_soff_t lfs2_dir_tell(lfs2_t *lfs2, lfs2_dir_t *dir) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_dir_tell(%p, %p)", (void*)lfs2, (void*)dir); + + lfs2_soff_t res = lfs2_dir_rawtell(lfs2, dir); + + LFS2_TRACE("lfs2_dir_tell -> %"PRId32, res); + LFS2_UNLOCK(lfs2->cfg); + return res; +} + +int lfs2_dir_rewind(lfs2_t *lfs2, lfs2_dir_t *dir) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_dir_rewind(%p, %p)", (void*)lfs2, (void*)dir); + + err = lfs2_dir_rawrewind(lfs2, dir); + + LFS2_TRACE("lfs2_dir_rewind -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +lfs2_ssize_t lfs2_fs_size(lfs2_t *lfs2) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_fs_size(%p)", (void*)lfs2); + + lfs2_ssize_t res = lfs2_fs_rawsize(lfs2); + + LFS2_TRACE("lfs2_fs_size -> %"PRId32, res); + LFS2_UNLOCK(lfs2->cfg); + return res; +} + +int lfs2_fs_traverse(lfs2_t *lfs2, int (*cb)(void *, lfs2_block_t), void *data) { + int err = LFS2_LOCK(lfs2->cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_fs_traverse(%p, %p, %p)", + (void*)lfs2, (void*)(uintptr_t)cb, data); + + err = lfs2_fs_rawtraverse(lfs2, cb, data, true); + + LFS2_TRACE("lfs2_fs_traverse -> %d", err); + LFS2_UNLOCK(lfs2->cfg); + return err; +} + +#ifdef LFS2_MIGRATE +int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { + int err = LFS2_LOCK(cfg); + if (err) { + return err; + } + LFS2_TRACE("lfs2_migrate(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs2, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); + + err = lfs2_rawmigrate(lfs2, cfg); + + LFS2_TRACE("lfs2_migrate -> %d", err); + LFS2_UNLOCK(cfg); + return err; +} +#endif diff --git a/circuitpython/lib/littlefs/lfs2.h b/circuitpython/lib/littlefs/lfs2.h new file mode 100644 index 0000000..f3b66d7 --- /dev/null +++ b/circuitpython/lib/littlefs/lfs2.h @@ -0,0 +1,689 @@ +/* + * The little filesystem + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef LFS2_H +#define LFS2_H + +#include +#include +#include "lfs2_util.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/// Version info /// + +// Software library version +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS2_VERSION 0x00020003 +#define LFS2_VERSION_MAJOR (0xffff & (LFS2_VERSION >> 16)) +#define LFS2_VERSION_MINOR (0xffff & (LFS2_VERSION >> 0)) + +// Version of On-disk data structures +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS2_DISK_VERSION 0x00020000 +#define LFS2_DISK_VERSION_MAJOR (0xffff & (LFS2_DISK_VERSION >> 16)) +#define LFS2_DISK_VERSION_MINOR (0xffff & (LFS2_DISK_VERSION >> 0)) + + +/// Definitions /// + +// Type definitions +typedef uint32_t lfs2_size_t; +typedef uint32_t lfs2_off_t; + +typedef int32_t lfs2_ssize_t; +typedef int32_t lfs2_soff_t; + +typedef uint32_t lfs2_block_t; + +// Maximum name size in bytes, may be redefined to reduce the size of the +// info struct. Limited to <= 1022. Stored in superblock and must be +// respected by other littlefs drivers. +#ifndef LFS2_NAME_MAX +#define LFS2_NAME_MAX 255 +#endif + +// Maximum size of a file in bytes, may be redefined to limit to support other +// drivers. Limited on disk to <= 4294967296. However, above 2147483647 the +// functions lfs2_file_seek, lfs2_file_size, and lfs2_file_tell will return +// incorrect values due to using signed integers. Stored in superblock and +// must be respected by other littlefs drivers. +#ifndef LFS2_FILE_MAX +#define LFS2_FILE_MAX 2147483647 +#endif + +// Maximum size of custom attributes in bytes, may be redefined, but there is +// no real benefit to using a smaller LFS2_ATTR_MAX. Limited to <= 1022. +#ifndef LFS2_ATTR_MAX +#define LFS2_ATTR_MAX 1022 +#endif + +// Possible error codes, these are negative to allow +// valid positive return values +enum lfs2_error { + LFS2_ERR_OK = 0, // No error + LFS2_ERR_IO = -5, // Error during device operation + LFS2_ERR_CORRUPT = -84, // Corrupted + LFS2_ERR_NOENT = -2, // No directory entry + LFS2_ERR_EXIST = -17, // Entry already exists + LFS2_ERR_NOTDIR = -20, // Entry is not a dir + LFS2_ERR_ISDIR = -21, // Entry is a dir + LFS2_ERR_NOTEMPTY = -39, // Dir is not empty + LFS2_ERR_BADF = -9, // Bad file number + LFS2_ERR_FBIG = -27, // File too large + LFS2_ERR_INVAL = -22, // Invalid parameter + LFS2_ERR_NOSPC = -28, // No space left on device + LFS2_ERR_NOMEM = -12, // No more memory available + LFS2_ERR_NOATTR = -61, // No data/attr available + LFS2_ERR_NAMETOOLONG = -36, // File name too long +}; + +// File types +enum lfs2_type { + // file types + LFS2_TYPE_REG = 0x001, + LFS2_TYPE_DIR = 0x002, + + // internally used types + LFS2_TYPE_SPLICE = 0x400, + LFS2_TYPE_NAME = 0x000, + LFS2_TYPE_STRUCT = 0x200, + LFS2_TYPE_USERATTR = 0x300, + LFS2_TYPE_FROM = 0x100, + LFS2_TYPE_TAIL = 0x600, + LFS2_TYPE_GLOBALS = 0x700, + LFS2_TYPE_CRC = 0x500, + + // internally used type specializations + LFS2_TYPE_CREATE = 0x401, + LFS2_TYPE_DELETE = 0x4ff, + LFS2_TYPE_SUPERBLOCK = 0x0ff, + LFS2_TYPE_DIRSTRUCT = 0x200, + LFS2_TYPE_CTZSTRUCT = 0x202, + LFS2_TYPE_INLINESTRUCT = 0x201, + LFS2_TYPE_SOFTTAIL = 0x600, + LFS2_TYPE_HARDTAIL = 0x601, + LFS2_TYPE_MOVESTATE = 0x7ff, + + // internal chip sources + LFS2_FROM_NOOP = 0x000, + LFS2_FROM_MOVE = 0x101, + LFS2_FROM_USERATTRS = 0x102, +}; + +// File open flags +enum lfs2_open_flags { + // open flags + LFS2_O_RDONLY = 1, // Open a file as read only +#ifndef LFS2_READONLY + LFS2_O_WRONLY = 2, // Open a file as write only + LFS2_O_RDWR = 3, // Open a file as read and write + LFS2_O_CREAT = 0x0100, // Create a file if it does not exist + LFS2_O_EXCL = 0x0200, // Fail if a file already exists + LFS2_O_TRUNC = 0x0400, // Truncate the existing file to zero size + LFS2_O_APPEND = 0x0800, // Move to end of file on every write +#endif + + // internally used flags +#ifndef LFS2_READONLY + LFS2_F_DIRTY = 0x010000, // File does not match storage + LFS2_F_WRITING = 0x020000, // File has been written since last flush +#endif + LFS2_F_READING = 0x040000, // File has been read since last flush +#ifndef LFS2_READONLY + LFS2_F_ERRED = 0x080000, // An error occurred during write +#endif + LFS2_F_INLINE = 0x100000, // Currently inlined in directory entry +}; + +// File seek flags +enum lfs2_whence_flags { + LFS2_SEEK_SET = 0, // Seek relative to an absolute position + LFS2_SEEK_CUR = 1, // Seek relative to the current file position + LFS2_SEEK_END = 2, // Seek relative to the end of the file +}; + + +// Configuration provided during initialization of the littlefs +struct lfs2_config { + // Opaque user provided context that can be used to pass + // information to the block device operations + void *context; + + // Read a region in a block. Negative error codes are propogated + // to the user. + int (*read)(const struct lfs2_config *c, lfs2_block_t block, + lfs2_off_t off, void *buffer, lfs2_size_t size); + + // Program a region in a block. The block must have previously + // been erased. Negative error codes are propogated to the user. + // May return LFS2_ERR_CORRUPT if the block should be considered bad. + int (*prog)(const struct lfs2_config *c, lfs2_block_t block, + lfs2_off_t off, const void *buffer, lfs2_size_t size); + + // Erase a block. A block must be erased before being programmed. + // The state of an erased block is undefined. Negative error codes + // are propogated to the user. + // May return LFS2_ERR_CORRUPT if the block should be considered bad. + int (*erase)(const struct lfs2_config *c, lfs2_block_t block); + + // Sync the state of the underlying block device. Negative error codes + // are propogated to the user. + int (*sync)(const struct lfs2_config *c); + +#ifdef LFS2_THREADSAFE + // Lock the underlying block device. Negative error codes + // are propogated to the user. + int (*lock)(const struct lfs2_config *c); + + // Unlock the underlying block device. Negative error codes + // are propogated to the user. + int (*unlock)(const struct lfs2_config *c); +#endif + + // Minimum size of a block read. All read operations will be a + // multiple of this value. + lfs2_size_t read_size; + + // Minimum size of a block program. All program operations will be a + // multiple of this value. + lfs2_size_t prog_size; + + // Size of an erasable block. This does not impact ram consumption and + // may be larger than the physical erase size. However, non-inlined files + // take up at minimum one block. Must be a multiple of the read + // and program sizes. + lfs2_size_t block_size; + + // Number of erasable blocks on the device. + lfs2_size_t block_count; + + // Number of erase cycles before littlefs evicts metadata logs and moves + // the metadata to another block. Suggested values are in the + // range 100-1000, with large values having better performance at the cost + // of less consistent wear distribution. + // + // Set to -1 to disable block-level wear-leveling. + int32_t block_cycles; + + // Size of block caches. Each cache buffers a portion of a block in RAM. + // The littlefs needs a read cache, a program cache, and one additional + // cache per file. Larger caches can improve performance by storing more + // data and reducing the number of disk accesses. Must be a multiple of + // the read and program sizes, and a factor of the block size. + lfs2_size_t cache_size; + + // Size of the lookahead buffer in bytes. A larger lookahead buffer + // increases the number of blocks found during an allocation pass. The + // lookahead buffer is stored as a compact bitmap, so each byte of RAM + // can track 8 blocks. Must be a multiple of 8. + lfs2_size_t lookahead_size; + + // Optional statically allocated read buffer. Must be cache_size. + // By default lfs2_malloc is used to allocate this buffer. + void *read_buffer; + + // Optional statically allocated program buffer. Must be cache_size. + // By default lfs2_malloc is used to allocate this buffer. + void *prog_buffer; + + // Optional statically allocated lookahead buffer. Must be lookahead_size + // and aligned to a 32-bit boundary. By default lfs2_malloc is used to + // allocate this buffer. + void *lookahead_buffer; + + // Optional upper limit on length of file names in bytes. No downside for + // larger names except the size of the info struct which is controlled by + // the LFS2_NAME_MAX define. Defaults to LFS2_NAME_MAX when zero. Stored in + // superblock and must be respected by other littlefs drivers. + lfs2_size_t name_max; + + // Optional upper limit on files in bytes. No downside for larger files + // but must be <= LFS2_FILE_MAX. Defaults to LFS2_FILE_MAX when zero. Stored + // in superblock and must be respected by other littlefs drivers. + lfs2_size_t file_max; + + // Optional upper limit on custom attributes in bytes. No downside for + // larger attributes size but must be <= LFS2_ATTR_MAX. Defaults to + // LFS2_ATTR_MAX when zero. + lfs2_size_t attr_max; +}; + +// File info structure +struct lfs2_info { + // Type of the file, either LFS2_TYPE_REG or LFS2_TYPE_DIR + uint8_t type; + + // Size of the file, only valid for REG files. Limited to 32-bits. + lfs2_size_t size; + + // Name of the file stored as a null-terminated string. Limited to + // LFS2_NAME_MAX+1, which can be changed by redefining LFS2_NAME_MAX to + // reduce RAM. LFS2_NAME_MAX is stored in superblock and must be + // respected by other littlefs drivers. + char name[LFS2_NAME_MAX+1]; +}; + +// Custom attribute structure, used to describe custom attributes +// committed atomically during file writes. +struct lfs2_attr { + // 8-bit type of attribute, provided by user and used to + // identify the attribute + uint8_t type; + + // Pointer to buffer containing the attribute + void *buffer; + + // Size of attribute in bytes, limited to LFS2_ATTR_MAX + lfs2_size_t size; +}; + +// Optional configuration provided during lfs2_file_opencfg +struct lfs2_file_config { + // Optional statically allocated file buffer. Must be cache_size. + // By default lfs2_malloc is used to allocate this buffer. + void *buffer; + + // Optional list of custom attributes related to the file. If the file + // is opened with read access, these attributes will be read from disk + // during the open call. If the file is opened with write access, the + // attributes will be written to disk every file sync or close. This + // write occurs atomically with update to the file's contents. + // + // Custom attributes are uniquely identified by an 8-bit type and limited + // to LFS2_ATTR_MAX bytes. When read, if the stored attribute is smaller + // than the buffer, it will be padded with zeros. If the stored attribute + // is larger, then it will be silently truncated. If the attribute is not + // found, it will be created implicitly. + struct lfs2_attr *attrs; + + // Number of custom attributes in the list + lfs2_size_t attr_count; +}; + + +/// internal littlefs data structures /// +typedef struct lfs2_cache { + lfs2_block_t block; + lfs2_off_t off; + lfs2_size_t size; + uint8_t *buffer; +} lfs2_cache_t; + +typedef struct lfs2_mdir { + lfs2_block_t pair[2]; + uint32_t rev; + lfs2_off_t off; + uint32_t etag; + uint16_t count; + bool erased; + bool split; + lfs2_block_t tail[2]; +} lfs2_mdir_t; + +// littlefs directory type +typedef struct lfs2_dir { + struct lfs2_dir *next; + uint16_t id; + uint8_t type; + lfs2_mdir_t m; + + lfs2_off_t pos; + lfs2_block_t head[2]; +} lfs2_dir_t; + +// littlefs file type +typedef struct lfs2_file { + struct lfs2_file *next; + uint16_t id; + uint8_t type; + lfs2_mdir_t m; + + struct lfs2_ctz { + lfs2_block_t head; + lfs2_size_t size; + } ctz; + + uint32_t flags; + lfs2_off_t pos; + lfs2_block_t block; + lfs2_off_t off; + lfs2_cache_t cache; + + const struct lfs2_file_config *cfg; +} lfs2_file_t; + +typedef struct lfs2_superblock { + uint32_t version; + lfs2_size_t block_size; + lfs2_size_t block_count; + lfs2_size_t name_max; + lfs2_size_t file_max; + lfs2_size_t attr_max; +} lfs2_superblock_t; + +typedef struct lfs2_gstate { + uint32_t tag; + lfs2_block_t pair[2]; +} lfs2_gstate_t; + +// The littlefs filesystem type +typedef struct lfs2 { + lfs2_cache_t rcache; + lfs2_cache_t pcache; + + lfs2_block_t root[2]; + struct lfs2_mlist { + struct lfs2_mlist *next; + uint16_t id; + uint8_t type; + lfs2_mdir_t m; + } *mlist; + uint32_t seed; + + lfs2_gstate_t gstate; + lfs2_gstate_t gdisk; + lfs2_gstate_t gdelta; + + struct lfs2_free { + lfs2_block_t off; + lfs2_block_t size; + lfs2_block_t i; + lfs2_block_t ack; + uint32_t *buffer; + } free; + + const struct lfs2_config *cfg; + lfs2_size_t name_max; + lfs2_size_t file_max; + lfs2_size_t attr_max; + +#ifdef LFS2_MIGRATE + struct lfs21 *lfs21; +#endif +} lfs2_t; + + +/// Filesystem functions /// + +#ifndef LFS2_READONLY +// Format a block device with the littlefs +// +// Requires a littlefs object and config struct. This clobbers the littlefs +// object, and does not leave the filesystem mounted. The config struct must +// be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs2_format(lfs2_t *lfs2, const struct lfs2_config *config); +#endif + +// Mounts a littlefs +// +// Requires a littlefs object and config struct. Multiple filesystems +// may be mounted simultaneously with multiple littlefs objects. Both +// lfs2 and config must be allocated while mounted. The config struct must +// be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *config); + +// Unmounts a littlefs +// +// Does nothing besides releasing any allocated resources. +// Returns a negative error code on failure. +int lfs2_unmount(lfs2_t *lfs2); + +/// General operations /// + +#ifndef LFS2_READONLY +// Removes a file or directory +// +// If removing a directory, the directory must be empty. +// Returns a negative error code on failure. +int lfs2_remove(lfs2_t *lfs2, const char *path); +#endif + +#ifndef LFS2_READONLY +// Rename or move a file or directory +// +// If the destination exists, it must match the source in type. +// If the destination is a directory, the directory must be empty. +// +// Returns a negative error code on failure. +int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath); +#endif + +// Find info about a file or directory +// +// Fills out the info structure, based on the specified file or directory. +// Returns a negative error code on failure. +int lfs2_stat(lfs2_t *lfs2, const char *path, struct lfs2_info *info); + +// Get a custom attribute +// +// Custom attributes are uniquely identified by an 8-bit type and limited +// to LFS2_ATTR_MAX bytes. When read, if the stored attribute is smaller than +// the buffer, it will be padded with zeros. If the stored attribute is larger, +// then it will be silently truncated. If no attribute is found, the error +// LFS2_ERR_NOATTR is returned and the buffer is filled with zeros. +// +// Returns the size of the attribute, or a negative error code on failure. +// Note, the returned size is the size of the attribute on disk, irrespective +// of the size of the buffer. This can be used to dynamically allocate a buffer +// or check for existance. +lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path, + uint8_t type, void *buffer, lfs2_size_t size); + +#ifndef LFS2_READONLY +// Set custom attributes +// +// Custom attributes are uniquely identified by an 8-bit type and limited +// to LFS2_ATTR_MAX bytes. If an attribute is not found, it will be +// implicitly created. +// +// Returns a negative error code on failure. +int lfs2_setattr(lfs2_t *lfs2, const char *path, + uint8_t type, const void *buffer, lfs2_size_t size); +#endif + +#ifndef LFS2_READONLY +// Removes a custom attribute +// +// If an attribute is not found, nothing happens. +// +// Returns a negative error code on failure. +int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type); +#endif + + +/// File operations /// + +// Open a file +// +// The mode that the file is opened in is determined by the flags, which +// are values from the enum lfs2_open_flags that are bitwise-ored together. +// +// Returns a negative error code on failure. +int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file, + const char *path, int flags); + +// Open a file with extra configuration +// +// The mode that the file is opened in is determined by the flags, which +// are values from the enum lfs2_open_flags that are bitwise-ored together. +// +// The config struct provides additional config options per file as described +// above. The config struct must be allocated while the file is open, and the +// config struct must be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs2_file_opencfg(lfs2_t *lfs2, lfs2_file_t *file, + const char *path, int flags, + const struct lfs2_file_config *config); + +// Close a file +// +// Any pending writes are written out to storage as though +// sync had been called and releases any allocated resources. +// +// Returns a negative error code on failure. +int lfs2_file_close(lfs2_t *lfs2, lfs2_file_t *file); + +// Synchronize a file on storage +// +// Any pending writes are written out to storage. +// Returns a negative error code on failure. +int lfs2_file_sync(lfs2_t *lfs2, lfs2_file_t *file); + +// Read data from file +// +// Takes a buffer and size indicating where to store the read data. +// Returns the number of bytes read, or a negative error code on failure. +lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file, + void *buffer, lfs2_size_t size); + +#ifndef LFS2_READONLY +// Write data to file +// +// Takes a buffer and size indicating the data to write. The file will not +// actually be updated on the storage until either sync or close is called. +// +// Returns the number of bytes written, or a negative error code on failure. +lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, + const void *buffer, lfs2_size_t size); +#endif + +// Change the position of the file +// +// The change in position is determined by the offset and whence flag. +// Returns the new position of the file, or a negative error code on failure. +lfs2_soff_t lfs2_file_seek(lfs2_t *lfs2, lfs2_file_t *file, + lfs2_soff_t off, int whence); + +#ifndef LFS2_READONLY +// Truncates the size of the file to the specified size +// +// Returns a negative error code on failure. +int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size); +#endif + +// Return the position of the file +// +// Equivalent to lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_CUR) +// Returns the position of the file, or a negative error code on failure. +lfs2_soff_t lfs2_file_tell(lfs2_t *lfs2, lfs2_file_t *file); + +// Change the position of the file to the beginning of the file +// +// Equivalent to lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_SET) +// Returns a negative error code on failure. +int lfs2_file_rewind(lfs2_t *lfs2, lfs2_file_t *file); + +// Return the size of the file +// +// Similar to lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_END) +// Returns the size of the file, or a negative error code on failure. +lfs2_soff_t lfs2_file_size(lfs2_t *lfs2, lfs2_file_t *file); + + +/// Directory operations /// + +#ifndef LFS2_READONLY +// Create a directory +// +// Returns a negative error code on failure. +int lfs2_mkdir(lfs2_t *lfs2, const char *path); +#endif + +// Open a directory +// +// Once open a directory can be used with read to iterate over files. +// Returns a negative error code on failure. +int lfs2_dir_open(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path); + +// Close a directory +// +// Releases any allocated resources. +// Returns a negative error code on failure. +int lfs2_dir_close(lfs2_t *lfs2, lfs2_dir_t *dir); + +// Read an entry in the directory +// +// Fills out the info structure, based on the specified file or directory. +// Returns a positive value on success, 0 at the end of directory, +// or a negative error code on failure. +int lfs2_dir_read(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info); + +// Change the position of the directory +// +// The new off must be a value previous returned from tell and specifies +// an absolute offset in the directory seek. +// +// Returns a negative error code on failure. +int lfs2_dir_seek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off); + +// Return the position of the directory +// +// The returned offset is only meant to be consumed by seek and may not make +// sense, but does indicate the current position in the directory iteration. +// +// Returns the position of the directory, or a negative error code on failure. +lfs2_soff_t lfs2_dir_tell(lfs2_t *lfs2, lfs2_dir_t *dir); + +// Change the position of the directory to the beginning of the directory +// +// Returns a negative error code on failure. +int lfs2_dir_rewind(lfs2_t *lfs2, lfs2_dir_t *dir); + + +/// Filesystem-level filesystem operations + +// Finds the current size of the filesystem +// +// Note: Result is best effort. If files share COW structures, the returned +// size may be larger than the filesystem actually is. +// +// Returns the number of allocated blocks, or a negative error code on failure. +lfs2_ssize_t lfs2_fs_size(lfs2_t *lfs2); + +// Traverse through all blocks in use by the filesystem +// +// The provided callback will be called with each block address that is +// currently in use by the filesystem. This can be used to determine which +// blocks are in use or how much of the storage is available. +// +// Returns a negative error code on failure. +int lfs2_fs_traverse(lfs2_t *lfs2, int (*cb)(void*, lfs2_block_t), void *data); + +#ifndef LFS2_READONLY +#ifdef LFS2_MIGRATE +// Attempts to migrate a previous version of littlefs +// +// Behaves similarly to the lfs2_format function. Attempts to mount +// the previous version of littlefs and update the filesystem so it can be +// mounted with the current version of littlefs. +// +// Requires a littlefs object and config struct. This clobbers the littlefs +// object, and does not leave the filesystem mounted. The config struct must +// be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg); +#endif +#endif + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/circuitpython/lib/littlefs/lfs2_util.c b/circuitpython/lib/littlefs/lfs2_util.c new file mode 100644 index 0000000..083a99c --- /dev/null +++ b/circuitpython/lib/littlefs/lfs2_util.c @@ -0,0 +1,33 @@ +/* + * lfs2 util functions + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "lfs2_util.h" + +// Only compile if user does not provide custom config +#ifndef LFS2_CONFIG + + +// Software CRC implementation with small lookup table +uint32_t lfs2_crc(uint32_t crc, const void *buffer, size_t size) { + static const uint32_t rtable[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c, + }; + + const uint8_t *data = buffer; + + for (size_t i = 0; i < size; i++) { + crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 0)) & 0xf]; + crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 4)) & 0xf]; + } + + return crc; +} + + +#endif diff --git a/circuitpython/lib/littlefs/lfs2_util.h b/circuitpython/lib/littlefs/lfs2_util.h new file mode 100644 index 0000000..70bca71 --- /dev/null +++ b/circuitpython/lib/littlefs/lfs2_util.h @@ -0,0 +1,234 @@ +/* + * lfs2 utility functions + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef LFS2_UTIL_H +#define LFS2_UTIL_H + +// Users can override lfs2_util.h with their own configuration by defining +// LFS2_CONFIG as a header file to include (-DLFS2_CONFIG=lfs2_config.h). +// +// If LFS2_CONFIG is used, none of the default utils will be emitted and must be +// provided by the config file. To start, I would suggest copying lfs2_util.h +// and modifying as needed. +#ifdef LFS2_CONFIG +#define LFS2_STRINGIZE(x) LFS2_STRINGIZE2(x) +#define LFS2_STRINGIZE2(x) #x +#include LFS2_STRINGIZE(LFS2_CONFIG) +#else + +// System includes +#include +#include +#include +#include + +#ifndef LFS2_NO_MALLOC +#include +#endif +#ifndef LFS2_NO_ASSERT +#include +#endif +#if !defined(LFS2_NO_DEBUG) || \ + !defined(LFS2_NO_WARN) || \ + !defined(LFS2_NO_ERROR) || \ + defined(LFS2_YES_TRACE) +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// Macros, may be replaced by system specific wrappers. Arguments to these +// macros must not have side-effects as the macros can be removed for a smaller +// code footprint + +// Logging functions +#ifdef LFS2_YES_TRACE +#define LFS2_TRACE_(fmt, ...) \ + printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS2_TRACE(...) LFS2_TRACE_(__VA_ARGS__, "") +#else +#define LFS2_TRACE(...) +#endif + +#ifndef LFS2_NO_DEBUG +#define LFS2_DEBUG_(fmt, ...) \ + printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS2_DEBUG(...) LFS2_DEBUG_(__VA_ARGS__, "") +#else +#define LFS2_DEBUG(...) +#endif + +#ifndef LFS2_NO_WARN +#define LFS2_WARN_(fmt, ...) \ + printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS2_WARN(...) LFS2_WARN_(__VA_ARGS__, "") +#else +#define LFS2_WARN(...) +#endif + +#ifndef LFS2_NO_ERROR +#define LFS2_ERROR_(fmt, ...) \ + printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS2_ERROR(...) LFS2_ERROR_(__VA_ARGS__, "") +#else +#define LFS2_ERROR(...) +#endif + +// Runtime assertions +#ifndef LFS2_NO_ASSERT +#define LFS2_ASSERT(test) assert(test) +#else +#define LFS2_ASSERT(test) +#endif + + +// Builtin functions, these may be replaced by more efficient +// toolchain-specific implementations. LFS2_NO_INTRINSICS falls back to a more +// expensive basic C implementation for debugging purposes + +// Min/max functions for unsigned 32-bit numbers +static inline uint32_t lfs2_max(uint32_t a, uint32_t b) { + return (a > b) ? a : b; +} + +static inline uint32_t lfs2_min(uint32_t a, uint32_t b) { + return (a < b) ? a : b; +} + +// Align to nearest multiple of a size +static inline uint32_t lfs2_aligndown(uint32_t a, uint32_t alignment) { + return a - (a % alignment); +} + +static inline uint32_t lfs2_alignup(uint32_t a, uint32_t alignment) { + return lfs2_aligndown(a + alignment-1, alignment); +} + +// Find the smallest power of 2 greater than or equal to a +static inline uint32_t lfs2_npw2(uint32_t a) { +#if !defined(LFS2_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return 32 - __builtin_clz(a-1); +#else + uint32_t r = 0; + uint32_t s; + a -= 1; + s = (a > 0xffff) << 4; a >>= s; r |= s; + s = (a > 0xff ) << 3; a >>= s; r |= s; + s = (a > 0xf ) << 2; a >>= s; r |= s; + s = (a > 0x3 ) << 1; a >>= s; r |= s; + return (r | (a >> 1)) + 1; +#endif +} + +// Count the number of trailing binary zeros in a +// lfs2_ctz(0) may be undefined +static inline uint32_t lfs2_ctz(uint32_t a) { +#if !defined(LFS2_NO_INTRINSICS) && defined(__GNUC__) + return __builtin_ctz(a); +#else + return lfs2_npw2((a & -a) + 1) - 1; +#endif +} + +// Count the number of binary ones in a +static inline uint32_t lfs2_popc(uint32_t a) { +#if !defined(LFS2_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return __builtin_popcount(a); +#else + a = a - ((a >> 1) & 0x55555555); + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); + return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; +#endif +} + +// Find the sequence comparison of a and b, this is the distance +// between a and b ignoring overflow +static inline int lfs2_scmp(uint32_t a, uint32_t b) { + return (int)(unsigned)(a - b); +} + +// Convert between 32-bit little-endian and native order +static inline uint32_t lfs2_fromle32(uint32_t a) { +#if !defined(LFS2_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + return a; +#elif !defined(LFS2_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + return __builtin_bswap32(a); +#else + return (((uint8_t*)&a)[0] << 0) | + (((uint8_t*)&a)[1] << 8) | + (((uint8_t*)&a)[2] << 16) | + (((uint8_t*)&a)[3] << 24); +#endif +} + +static inline uint32_t lfs2_tole32(uint32_t a) { + return lfs2_fromle32(a); +} + +// Convert between 32-bit big-endian and native order +static inline uint32_t lfs2_frombe32(uint32_t a) { +#if !defined(LFS2_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + return __builtin_bswap32(a); +#elif !defined(LFS2_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + return a; +#else + return (((uint8_t*)&a)[0] << 24) | + (((uint8_t*)&a)[1] << 16) | + (((uint8_t*)&a)[2] << 8) | + (((uint8_t*)&a)[3] << 0); +#endif +} + +static inline uint32_t lfs2_tobe32(uint32_t a) { + return lfs2_frombe32(a); +} + +// Calculate CRC-32 with polynomial = 0x04c11db7 +uint32_t lfs2_crc(uint32_t crc, const void *buffer, size_t size); + +// Allocate memory, only used if buffers are not provided to littlefs +// Note, memory must be 64-bit aligned +static inline void *lfs2_malloc(size_t size) { +#ifndef LFS2_NO_MALLOC + return malloc(size); +#else + (void)size; + return NULL; +#endif +} + +// Deallocate memory, only used if buffers are not provided to littlefs +static inline void lfs2_free(void *p) { +#ifndef LFS2_NO_MALLOC + free(p); +#else + (void)p; +#endif +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +#endif diff --git a/circuitpython/lib/mp3/Doxyfile b/circuitpython/lib/mp3/Doxyfile new file mode 100644 index 0000000..7f16716 --- /dev/null +++ b/circuitpython/lib/mp3/Doxyfile @@ -0,0 +1,2481 @@ +# Doxyfile 1.8.14 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Adafruit mp3" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = docs + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /

© COPYRIGHT(c) 2019 STMicroelectronics

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. 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. +** 3. Neither the name of STMicroelectronics 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 HOLDER 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. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20004000; /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld new file mode 100644 index 0000000..8d31f6a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F072RBTx Device with +** 128KByte FLASH, 16KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20004000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/board.h new file mode 100644 index 0000000..0b1824b --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/board.h @@ -0,0 +1,85 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOC +#define LED_PIN GPIO_PIN_6 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +// UART +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF1_USART1 +#define UART_TX_PIN GPIO_PIN_9 +#define UART_RX_PIN GPIO_PIN_10 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32f0_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Select HSI48 Oscillator as PLL source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI48; + RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK and PCLK1 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); +} + +static inline void board_vbus_sense_init(void) +{ +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/board.mk new file mode 100644 index 0000000..7c72d8f --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072disco/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F072xB -DCFG_EXAMPLE_VIDEO_READONLY + +LD_FILE = $(BOARD_PATH)/STM32F072RBTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f072xb.s + +# For flash-jlink target +JLINK_DEVICE = stm32f072rb + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld new file mode 100644 index 0000000..581613a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld @@ -0,0 +1,177 @@ +/** + ****************************************************************************** + * @file LinkerScript.ld + * @author Auto-generated by STM32CubeIDE + * Abstract : Linker script for STM32072B-EVAL Board embedding STM32F072VBTx Device from stm32f0 series + * 128Kbytes FLASH + * 16Kbytes RAM + * + * Set heap size, stack size and stack location according + * to application requirements. + * + * Set memory bank area and size if external memory is used + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/board.h new file mode 100644 index 0000000..8869d5d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/board.h @@ -0,0 +1,102 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOD +#define LED_PIN GPIO_PIN_8 // LED1, GREEN +// #define LED_PIN GPIO_PIN_9 // LED2, ORANGE +// #define LED_PIN GPIO_PIN_10 // LED3, RED +// #define LED_PIN GPIO_PIN_11 // LED4, BLUE +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 // JOY_SEL +#define BUTTON_STATE_ACTIVE 1 + +// UART +#define UART_DEV USART2 +#define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE +#define UART_GPIO_PORT GPIOD +#define UART_GPIO_AF GPIO_AF0_USART2 +#define UART_TX_PIN GPIO_PIN_5 +#define UART_RX_PIN GPIO_PIN_6 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32f0_clock_init(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; + RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1; + + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = + RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB | RCC_PERIPHCLK_USART2; + PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); +} + +static inline void board_vbus_sense_init(void) +{ +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/board.mk new file mode 100644 index 0000000..b625c3e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/boards/stm32f072eval/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F072xB -DLSI_VALUE=40000 -DCFG_EXAMPLE_VIDEO_READONLY + +LD_FILE = $(BOARD_PATH)/STM32F072VBTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f072xb.s + +# For flash-jlink target +JLINK_DEVICE = stm32f072vb + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.c b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.c new file mode 100644 index 0000000..8de3147 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.c @@ -0,0 +1,182 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stm32f0xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_stm32f0_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + + // Enable UART Clock + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // LED + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + // Uart + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle.Instance = UART_DEV; + UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; + HAL_UART_Init(&UartHandle); + + // USB Pins + // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // USB Clock enable + __HAL_RCC_USB_CLK_ENABLE(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + (void) file; (void) line; + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.mk new file mode 100644 index 0000000..39831e1 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/family.mk @@ -0,0 +1,40 @@ +UF2_FAMILY_ID = 0x647824b6 +ST_FAMILY = f0 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m0 \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DCFG_EXAMPLE_MSC_READONLY \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F0 + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM0 diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f0/stm32f0xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/stm32f0xx_hal_conf.h new file mode 100644 index 0000000..cfa66b3 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f0/stm32f0xx_hal_conf.h @@ -0,0 +1,321 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_CONF_H +#define __STM32F0xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_CEC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +/*#define HAL_EXTI_MODULE_ENABLED */ +/*#define HAL_I2C_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ + +/* ######################### Oscillator Values adaptation ################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + * Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + * Timeout value + */ +#if !defined (HSI_STARTUP_TIMEOUT) + #define HSI_STARTUP_TIMEOUT 5000U /*!< Time out for HSI start up */ +#endif /* HSI_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator for ADC (HSI14) value. + */ +#if !defined (HSI14_VALUE) + #define HSI14_VALUE 14000000U /*!< Value of the Internal High Speed oscillator for ADC in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI14_VALUE */ + +/** + * @brief Internal High Speed oscillator for USB (HSI48) value. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE 48000000U /*!< Value of the Internal High Speed oscillator for USB in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE 32000U +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +/** + * @brief Time out for LSE start up value in ms. + */ +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)(1U<<__NVIC_PRIO_BITS) - 1U) /*!< tick interrupt priority (lowest by default) */ + /* Warning: Must be set to higher priority for HAL_Delay() */ + /* and HAL_GetTick() usage under interrupt context */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 0U +#define DATA_CACHE_ENABLE 0U +#define USE_SPI_CRC 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ + #define USE_FULL_ASSERT 1 + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f0xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f0xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f0xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f0xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f0xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f0xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f0xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f0xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32f0xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f0xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f0xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f0xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f0xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f0xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f0xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f0xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f0xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f0xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f0xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f0xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f0xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f0xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f0xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32f0xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f0xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f0xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f0xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld new file mode 100644 index 0000000..ca18049 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld @@ -0,0 +1,167 @@ +/* +***************************************************************************** +** +** File : STM32F103XB_FLASH.ld +** +** Abstract : Linker script for STM32F103xB Device with +** 128KByte FLASH, 20KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20004FFF; /* end of RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h new file mode 100644 index 0000000..57a607e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h @@ -0,0 +1,92 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOC +#define LED_PIN GPIO_PIN_13 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +// UART +//#define UART_DEV USART1 +//#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +//#define UART_GPIO_PORT GPIOA +//#define UART_GPIO_AF GPIO_AF1_USART1 +//#define UART_TX_PIN GPIO_PIN_9 +//#define UART_RX_PIN GPIO_PIN_10 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32f1_clock_init(void) +{ + RCC_ClkInitTypeDef clkinitstruct = {0}; + RCC_OscInitTypeDef oscinitstruct = {0}; + RCC_PeriphCLKInitTypeDef rccperiphclkinit = {0}; + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + oscinitstruct.HSEState = RCC_HSE_ON; + oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL9; + oscinitstruct.PLL.PLLState = RCC_PLL_ON; + oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + HAL_RCC_OscConfig(&oscinitstruct); + + /* USB clock selection */ + rccperiphclkinit.PeriphClockSelection = RCC_PERIPHCLK_USB; + rccperiphclkinit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; + clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); +} + +static inline void board_vbus_sense_init(void) +{ +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.mk new file mode 100644 index 0000000..db64b3a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F103xB -DHSE_VALUE=8000000U -DCFG_EXAMPLE_VIDEO_READONLY + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/STM32F103X8_FLASH.ld +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f103xb.s + +# For flash-jlink target +JLINK_DEVICE = stm32f103c8 + +# flash target ROM bootloader +flash: flash-dfu-util diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld new file mode 100644 index 0000000..da40d1e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld @@ -0,0 +1,167 @@ +/* +***************************************************************************** +** +** File : STM32F103XB_FLASH.ld +** +** Abstract : Linker script for STM32F103xB Device with +** 128KByte FLASH, 20KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20004FFF; /* end of RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 48K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/board.h new file mode 100644 index 0000000..bedce7f --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/board.h @@ -0,0 +1,92 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOA +#define LED_PIN GPIO_PIN_8 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +// UART +//#define UART_DEV USART1 +//#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +//#define UART_GPIO_PORT GPIOA +//#define UART_GPIO_AF GPIO_AF1_USART1 +//#define UART_TX_PIN GPIO_PIN_9 +//#define UART_RX_PIN GPIO_PIN_10 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32f1_clock_init(void) +{ + RCC_ClkInitTypeDef clkinitstruct = {0}; + RCC_OscInitTypeDef oscinitstruct = {0}; + RCC_PeriphCLKInitTypeDef rccperiphclkinit = {0}; + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + oscinitstruct.HSEState = RCC_HSE_ON; + oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL9; + oscinitstruct.PLL.PLLState = RCC_PLL_ON; + oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + HAL_RCC_OscConfig(&oscinitstruct); + + /* USB clock selection */ + rccperiphclkinit.PeriphClockSelection = RCC_PERIPHCLK_USB; + rccperiphclkinit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; + clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); +} + +static inline void board_vbus_sense_init(void) +{ +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/board.mk new file mode 100644 index 0000000..eeda870 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/boards/stm32f103_mini_2/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F103xB -DHSE_VALUE=8000000U + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/STM32F103XC_FLASH.ld +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f103xb.s + +# For flash-jlink target +JLINK_DEVICE = stm32f103rc + +# flash target ROM bootloader +flash: flash-jlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.c b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.c new file mode 100644 index 0000000..8fcf9eb --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.c @@ -0,0 +1,167 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stm32f1xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_HP_IRQHandler(void) +{ + tud_int_handler(0); +} + +void USB_LP_IRQHandler(void) +{ + tud_int_handler(0); +} + +void USBWakeUp_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +void board_init(void) +{ + board_stm32f1_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USBWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // LED + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = LED_STATE_ON ? GPIO_PULLDOWN : GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + // USB Pins + // Configure USB DM and DP pins. + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // USB Clock enable + __HAL_RCC_USB_CLK_ENABLE(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(char *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.mk new file mode 100644 index 0000000..3fb2e6e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/family.mk @@ -0,0 +1,45 @@ +ST_FAMILY = f1 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m3 \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F1 + +# mcu driver cause following warnings +#CFLAGS += -Wno-error=unused-parameter + +# All source paths should be relative to the top level. +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM3 + +# For flash-jlink target +JLINK_DEVICE = stm32f103c8 + +# flash target ROM bootloader +flash-dfu-util: $(BUILD)/$(PROJECT).bin + dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f1/stm32f1xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/stm32f1xx_hal_conf.h new file mode 100644 index 0000000..a4a3f30 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f1/stm32f1xx_hal_conf.h @@ -0,0 +1,379 @@ +/** + ****************************************************************************** + * @file USB_Device/HID_Standalone/Inc/stm32f1xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32f1xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F1xx_HAL_CONF_H +#define __STM32F1xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +#if defined(USE_STM3210C_EVAL) + #define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#else + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 8U /* 8 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f1xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f1xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f1xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f1xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f1xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "Legacy/stm32f1xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f1xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f1xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f1xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f1xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f1xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f1xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f1xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f1xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f1xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f1xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f1xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f1xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f1xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f1xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f1xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f1xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f1xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f1xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f1xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f1xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f1xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f1xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f1xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F1xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld new file mode 100644 index 0000000..29e387f --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F207IGHx Device with +** 1024KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/board.mk new file mode 100644 index 0000000..fa7d283 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/board.mk @@ -0,0 +1,48 @@ +ST_FAMILY = f2 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m3 \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DSTM32F207xx \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F2 + +# mcu driver cause following warnings +CFLAGS += -Wno-error=sign-compare + +# All source paths should be relative to the top level. +LD_FILE = hw/bsp/$(BOARD)/STM32F207ZGTx_FLASH.ld + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + +SRC_S += \ + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f207xx.s + +INC += \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM3 + +# For flash-jlink target +JLINK_DEVICE = stm32f207zg + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/stm32f207nucleo.c b/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/stm32f207nucleo.c new file mode 100644 index 0000000..619c90d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/stm32f207nucleo.c @@ -0,0 +1,213 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" + +#include "stm32f2xx_hal.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void OTG_FS_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + + +// enable all LED, Button, Uart, USB clock +static void all_rcc_clk_enable(void) +{ + __HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D- + __HAL_RCC_GPIOB_CLK_ENABLE(); // LED + __HAL_RCC_GPIOC_CLK_ENABLE(); // Button +} + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (HSE) + * SYSCLK(Hz) = 120000000 + * HCLK(Hz) = 120000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 4 + * APB2 Prescaler = 2 + * HSE Frequency(Hz) = 8000000 + * PLL_M = HSE_VALUE/1000000 + * PLL_N = 240 + * PLL_P = 2 + * PLL_Q = 5 + * VDD(V) = 3.3 + * Flash Latency(WS) = 3 + * @param None + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 240; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 5; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); +} + +void board_init(void) +{ + SystemClock_Config(); + + #if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + #endif + + + all_rcc_clk_enable(); + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + board_led_write(false); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + /* Configure DM DP Pins */ + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Configure VBUS Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Configure ID pin */ + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Enable USB FS Clocks */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/stm32f2xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/stm32f2xx_hal_conf.h new file mode 100644 index 0000000..2ab46b2 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f207nucleo/stm32f2xx_hal_conf.h @@ -0,0 +1,407 @@ +/** + ****************************************************************************** + * @file stm32f2xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F2xx_HAL_CONF_H +#define __STM32F2xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +/* #define HAL_DMA_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +/* #define HAL_UART_MODULE_ENABLED */ +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +/* #define HAL_HCD_MODULE_ENABLED */ + + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 5U /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 5U /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* LAN8742A PHY Address*/ +#define LAN8742A_PHY_ADDRESS 0x00U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ + + +#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f2xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f2xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f2xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f2xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f2xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f2xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f2xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f2xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f2xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f2xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f2xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f2xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f2xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f2xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f2xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f2xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f2xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f2xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f2xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f2xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f2xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f2xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f2xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f2xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f2xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f2xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f2xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f2xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f2xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f2xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f2xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f2xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f2xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f2xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F2xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld new file mode 100644 index 0000000..ca9046d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld @@ -0,0 +1,189 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F303VCTx Device with +** 256KByte FLASH, 40KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x2000a000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x800;; /* required amount of heap */ +_Min_Stack_Size = 0x800;; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 256K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 40K +CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 8K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/board.mk new file mode 100644 index 0000000..9dd27a8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/board.mk @@ -0,0 +1,49 @@ +ST_FAMILY = f3 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -nostdlib -nostartfiles \ + -DSTM32F303xC \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F3 + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter + +# All source paths should be relative to the top level. +LD_FILE = hw/bsp/$(BOARD)/STM32F303VCTx_FLASH.ld + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + +SRC_S += \ + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f303xc.s + +INC += \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# For flash-jlink target +JLINK_DEVICE = stm32f303vc + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/stm32f303disco.c b/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/stm32f303disco.c new file mode 100644 index 0000000..33552bc --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/stm32f303disco.c @@ -0,0 +1,215 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "stm32f3xx_hal.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ + +// USB defaults to using interrupts 19, 20 and 42, however, this BSP sets the +// SYSCFG_CFGR1.USB_IT_RMP bit remapping interrupts to 74, 75 and 76. + +// FIXME: Do all three need to be handled, or just the LP one? +// USB high-priority interrupt (Channel 74): Triggered only by a correct +// transfer event for isochronous and double-buffer bulk transfer to reach +// the highest possible transfer rate. +void USB_HP_IRQHandler(void) +{ + tud_int_handler(0); +} + +// USB low-priority interrupt (Channel 75): Triggered by all USB events +// (Correct transfer, USB reset, etc.). The firmware has to check the +// interrupt source before serving the interrupt. +void USB_LP_IRQHandler(void) +{ + tud_int_handler(0); +} + +// USB wakeup interrupt (Channel 76): Triggered by the wakeup event from the USB +// Suspend mode. +void USBWakeUp_RMP_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +#define LED_PORT GPIOE +#define LED_PIN GPIO_PIN_9 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (HSE) + * SYSCLK(Hz) = 72000000 + * HCLK(Hz) = 72000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 2 + * APB2 Prescaler = 1 + * HSE Frequency(Hz) = 8000000 + * HSE PREDIV = 1 + * PLLMUL = RCC_PLL_MUL9 (9) + * Flash Latency(WS) = 2 + * @param None + * @retval None + */ +static void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Configures the USB clock */ + HAL_RCCEx_GetPeriphCLKConfig(&RCC_PeriphClkInit); + RCC_PeriphClkInit.USBClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); + + /* Enable Power Clock */ + __HAL_RCC_PWR_CLK_ENABLE(); +} + +void board_init(void) +{ + SystemClock_Config(); + + #if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + #endif + + // Remap the USB interrupts + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_REMAPINTERRUPT_USB_ENABLE(); + + // LED + __HAL_RCC_GPIOE_CLK_ENABLE(); + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + // Button + __HAL_RCC_GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + /* Configure USB DM and DP pins */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF14_USB; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // Enable USB clock + __HAL_RCC_USB_CLK_ENABLE(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/stm32f3xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/stm32f3xx_hal_conf.h new file mode 100644 index 0000000..0abcbb0 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f303disco/stm32f3xx_hal_conf.h @@ -0,0 +1,357 @@ +/** + ****************************************************************************** + * @file stm32f3xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F3xx_HAL_CONF_H +#define __STM32F3xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_COMP_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_HRTIM_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_OPAMP_MODULE_ENABLED */ +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_PWR_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SDADC_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +/* #define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + * Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (8000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + * Timeout value + */ +#if !defined (HSI_STARTUP_TIMEOUT) + #define HSI_STARTUP_TIMEOUT (5000U) /*!< Time out for HSI start up */ +#endif /* HSI_STARTUP_TIMEOUT */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (40000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +/** + * @brief Time out for LSE start up value in ms. + */ +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + * - External clock generated through external PLL component on EVAL 303 (based on MCO or crystal) + * - External clock not generated on EVAL 373 + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (8000000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)(1U<<__NVIC_PRIO_BITS) - 1U) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 0U +#define DATA_CACHE_ENABLE 0U +#define USE_SPI_CRC 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SDADC_REGISTER_CALLBACKS 0U /* SDADC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* OPAMP register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/*#define USE_FULL_ASSERT 1U*/ + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f3xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f3xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f3xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f3xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f3xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f3xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f3xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f3xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f3xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32f3xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f3xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f3xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f3xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f3xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f3xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f3xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f3xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_HRTIM_MODULE_ENABLED + #include "stm32f3xx_hal_hrtim.h" +#endif /* HAL_HRTIM_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f3xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f3xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f3xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f3xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED + #include "stm32f3xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f3xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f3xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f3xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SDADC_MODULE_ENABLED + #include "stm32f3xx_hal_sdadc.h" +#endif /* HAL_SDADC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f3xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f3xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f3xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f3xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32f3xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f3xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f3xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f3xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F3xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld new file mode 100644 index 0000000..57ef61e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld @@ -0,0 +1,189 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F405RGTx Device with +** 1024KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/board.h new file mode 100644 index 0000000..19d0a1e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/board.h @@ -0,0 +1,104 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOC +#define LED_PIN GPIO_PIN_1 +#define LED_STATE_ON 1 + +// Button: Pin D5 +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_7 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_DEV USART3 +#define UART_GPIO_PORT GPIOB +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_10 +#define UART_RX_PIN GPIO_PIN_11 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_USART3_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/board.mk new file mode 100644 index 0000000..1de56fe --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/board.mk @@ -0,0 +1,12 @@ +CFLAGS += -DSTM32F405xx + +LD_FILE = $(BOARD_PATH)/STM32F405RGTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f405xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f405rg + +# flash target ROM bootloader +flash: $(BUILD)/$(PROJECT).bin + dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..b892df3 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/feather_stm32f405/stm32f4xx_hal_conf.h @@ -0,0 +1,491 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of STMicroelectronics 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 HOLDER 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED + +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_EXTI_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)12000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* Copied over manually- STM32Cube didn't generate these for some reason. */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848_PHY_ADDRESS Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FFU) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) + +#define PHY_READ_TO ((uint32_t)0x0000FFFFU) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld new file mode 100644 index 0000000..57ef61e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld @@ -0,0 +1,189 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F405RGTx Device with +** 1024KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/board.h new file mode 100644 index 0000000..685919c --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/board.h @@ -0,0 +1,102 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// Blue LED is chosen because the other LEDs are connected to ST-LINK lines. +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_4 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOB +#define BUTTON_PIN GPIO_PIN_3 +#define BUTTON_STATE_ACTIVE 1 + +// Enable PA2 as the debug log UART +// It is not routed to the ST/Link on the Discovery board. +//#define UART_DEV USART2 +//#define UART_GPIO_PORT GPIOA +//#define UART_GPIO_AF GPIO_AF7_USART2 +//#define UART_TX_PIN GPIO_PIN_2 +//#define UART_RX_PIN GPIO_PIN_3 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOB_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/board.mk new file mode 100644 index 0000000..02dcd12 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F405xx + +LD_FILE = $(BOARD_PATH)/STM32F405RGTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f405xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f405rg + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..b892df3 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/pyboardv11/stm32f4xx_hal_conf.h @@ -0,0 +1,491 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of STMicroelectronics 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 HOLDER 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED + +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_EXTI_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)12000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* Copied over manually- STM32Cube didn't generate these for some reason. */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848_PHY_ADDRESS Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FFU) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) + +#define PHY_READ_TO ((uint32_t)0x0000FFFFU) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld new file mode 100644 index 0000000..f51f1ab --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F401VCTx Device with +** 256KByte FLASH, 64KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20010000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200;; /* required amount of heap */ +_Min_Stack_Size = 0x400;; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/board.h new file mode 100644 index 0000000..0f82051 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/board.h @@ -0,0 +1,106 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOC +#define LED_PIN GPIO_PIN_13 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 0 + +// Enable PA2 as the debug log UART +//#define UART_DEV USART2 +//#define UART_GPIO_PORT GPIOA +//#define UART_GPIO_AF GPIO_AF7_USART2 +//#define UART_TX_PIN GPIO_PIN_2 +//#define UART_RX_PIN GPIO_PIN_3 + + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + //__HAL_RCC_USART2_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Blackpill doens't use VBUS sense (B device) explicitly disable it + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN; + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/board.mk new file mode 100644 index 0000000..de0f3d4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/board.mk @@ -0,0 +1,12 @@ +CFLAGS += -DSTM32F401xC + +LD_FILE = $(BOARD_PATH)/STM32F401VCTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f401xc.s + +# For flash-jlink target +JLINK_DEVICE = stm32f401cc + +# flash target ROM bootloader +flash: $(BUILD)/$(PROJECT).bin + dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..2ab9a1d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f401blackpill/stm32f4xx_hal_conf.h @@ -0,0 +1,493 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (25000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld new file mode 100644 index 0000000..c416027 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld @@ -0,0 +1,189 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F407VGTx Device with +** 1024KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x4000; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K + CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/board.h new file mode 100644 index 0000000..693e039 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/board.h @@ -0,0 +1,105 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOD +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +// Enable PA2 as the debug log UART +// It is not routed to the ST/Link on the Discovery board. +#define UART_DEV USART2 +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF7_USART2 +#define UART_TX_PIN GPIO_PIN_2 +#define UART_RX_PIN GPIO_PIN_3 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_USART2_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/board.mk new file mode 100644 index 0000000..212b924 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F407xx + +LD_FILE = $(BOARD_PATH)/STM32F407VGTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f407xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f407vg + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..7864f8d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f407disco/stm32f4xx_hal_conf.h @@ -0,0 +1,493 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld new file mode 100644 index 0000000..efea1e0 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F411CEUx Device with +** 512KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200;; /* required amount of heap */ +_Min_Stack_Size = 0x400;; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/board.h new file mode 100644 index 0000000..0f82051 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/board.h @@ -0,0 +1,106 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOC +#define LED_PIN GPIO_PIN_13 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 0 + +// Enable PA2 as the debug log UART +//#define UART_DEV USART2 +//#define UART_GPIO_PORT GPIOA +//#define UART_GPIO_AF GPIO_AF7_USART2 +//#define UART_TX_PIN GPIO_PIN_2 +//#define UART_RX_PIN GPIO_PIN_3 + + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + //__HAL_RCC_USART2_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Blackpill doens't use VBUS sense (B device) explicitly disable it + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN; + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/board.mk new file mode 100644 index 0000000..78be434 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/board.mk @@ -0,0 +1,12 @@ +CFLAGS += -DSTM32F411xE + +LD_FILE = $(BOARD_PATH)/STM32F411CEUx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f411xe.s + +# For flash-jlink target +JLINK_DEVICE = stm32f411ce + +# flash target ROM bootloader +flash: $(BUILD)/$(PROJECT).bin + dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..2ab9a1d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411blackpill/stm32f4xx_hal_conf.h @@ -0,0 +1,493 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (25000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld new file mode 100644 index 0000000..3a0ce52 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F411VETx Device with +** 512KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200;; /* required amount of heap */ +_Min_Stack_Size = 0x400;; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/board.h new file mode 100644 index 0000000..008a94a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/board.h @@ -0,0 +1,104 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// Orange LED +#define LED_PORT GPIOD +#define LED_PIN GPIO_PIN_13 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +// Enable PA2 as the debug log UART +#define UART_DEV USART2 +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF7_USART2 +#define UART_TX_PIN GPIO_PIN_2 +#define UART_RX_PIN GPIO_PIN_3 + + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_USART2_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/board.mk new file mode 100644 index 0000000..48272ac --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F411xE + +LD_FILE = $(BOARD_PATH)/STM32F411VETx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f411xe.s + +# For flash-jlink target +JLINK_DEVICE = stm32f411ve + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..7864f8d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f411disco/stm32f4xx_hal_conf.h @@ -0,0 +1,493 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld new file mode 100644 index 0000000..b00b5db --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F412ZGTx Device with +** 1024KByte FLASH, 256KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20040000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/board.h new file mode 100644 index 0000000..7f4a4fa --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/board.h @@ -0,0 +1,118 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOE +#define LED_PIN GPIO_PIN_2 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable PA2 as the debug log UART +#define UART_DEV USART2 +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF7_USART2 +#define UART_TX_PIN GPIO_PIN_2 +#define UART_RX_PIN GPIO_PIN_3 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the + * device is clocked below the maximum system frequency, to update the + * voltage scaling value regarding system frequency refer to product + * datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 200; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + RCC_OscInitStruct.PLL.PLLR = 2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLLSAI output as USB clock source */ + PeriphClkInitStruct.PLLI2S.PLLI2SM = 8; + PeriphClkInitStruct.PLLI2S.PLLI2SQ = 4; + PeriphClkInitStruct.PLLI2S.PLLI2SN = 192; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48; + PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLI2SQ; + PeriphClkInitStruct.PLLI2SSelection = RCC_PLLI2SCLKSOURCE_PLLSRC; + PeriphClkInitStruct.PLLI2S.PLLI2SR = 7; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + * clocks dividers */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_USART2_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/board.mk new file mode 100644 index 0000000..50973f7 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F412Zx + +LD_FILE = $(BOARD_PATH)/STM32F412ZGTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f412zx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f412zg + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..7864f8d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412disco/stm32f4xx_hal_conf.h @@ -0,0 +1,493 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld new file mode 100644 index 0000000..b00b5db --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F412ZGTx Device with +** 1024KByte FLASH, 256KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20040000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/board.h new file mode 100644 index 0000000..73c5f83 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/board.h @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV USART3 +#define UART_GPIO_PORT GPIOD +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_8 +#define UART_RX_PIN GPIO_PIN_9 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the + * device is clocked below the maximum system frequency, to update the + * voltage scaling value regarding system frequency refer to product + * datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 200; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + RCC_OscInitStruct.PLL.PLLR = 2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLLSAI output as USB clock source */ + PeriphClkInitStruct.PLLI2S.PLLI2SM = 8; + PeriphClkInitStruct.PLLI2S.PLLI2SQ = 4; + PeriphClkInitStruct.PLLI2S.PLLI2SN = 192; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48; + PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLI2SQ; + PeriphClkInitStruct.PLLI2SSelection = RCC_PLLI2SCLKSOURCE_PLLSRC; + PeriphClkInitStruct.PLLI2S.PLLI2SR = 7; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + * clocks dividers */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_USART3_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/board.mk new file mode 100644 index 0000000..50973f7 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F412Zx + +LD_FILE = $(BOARD_PATH)/STM32F412ZGTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f412zx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f412zg + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..7864f8d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f412nucleo/stm32f4xx_hal_conf.h @@ -0,0 +1,493 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld new file mode 100644 index 0000000..2dc277c --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld @@ -0,0 +1,206 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for NUCLEO-F439ZI Board embedding STM32F439ZITx Device from stm32f4 series +** 2048Kbytes FLASH +** 64Kbytes CCMRAM +** 192Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2021 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h new file mode 100644 index 0000000..e5a8224 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h @@ -0,0 +1,108 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV USART3 +#define UART_GPIO_PORT GPIOD +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_8 +#define UART_RX_PIN GPIO_PIN_9 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the + * device is clocked below the maximum system frequency, to update the + * voltage scaling value regarding system frequency refer to product + * datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + * clocks dividers */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_USART3_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk new file mode 100644 index 0000000..b7b36a8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F439xx + +LD_FILE = $(BOARD_PATH)/STM32F439ZITX_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f439xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f439zi + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..a2c11d7 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h @@ -0,0 +1,486 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* LAN8742A_PHY_ADDRESS Address*/ +#define LAN8742A_PHY_ADDRESS 0U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +#define PHY_ISFR ((uint16_t)0x001DU) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x000BU) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.c b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.c new file mode 100644 index 0000000..82d4957 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.c @@ -0,0 +1,201 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stm32f4xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void OTG_FS_IRQHandler(void) +{ + tud_int_handler(0); +} + +void OTG_HS_IRQHandler(void) +{ + tud_int_handler(1); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_clock_init(); + //SystemCoreClockUpdate(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + board_led_write(false); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + +#ifdef UART_DEV + // UART + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle = (UART_HandleTypeDef){ + .Instance = UART_DEV, + .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.OverSampling = UART_OVERSAMPLING_16 + }; + HAL_UART_Init(&UartHandle); +#endif + + /* Configure USB FS GPIOs */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + + /* Configure USB D+ D- Pins */ + GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Configure VBUS Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* ID Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + +#ifdef STM32F412Zx + /* Configure POWER_SWITCH IO pin */ + __HAL_RCC_GPIOG_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_8; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); +#endif + + // Enable USB OTG clock + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + +// __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); + + board_vbus_sense_init(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ +#ifdef UART_DEV + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +#else + (void) buf; (void) len; (void) UartHandle; + return 0; +#endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.mk new file mode 100644 index 0000000..9811d33 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f4/family.mk @@ -0,0 +1,43 @@ +UF2_FAMILY_ID = 0x57755a57 +ST_FAMILY = f4 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F4 + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=cast-align + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld new file mode 100644 index 0000000..8645ce5 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld @@ -0,0 +1,167 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F723xE Device with +** 512KByte FLASH, 256KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20040000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x460; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/board.h new file mode 100644 index 0000000..d0ef662 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/board.h @@ -0,0 +1,101 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_PIN_10 +#define LED_STATE_ON 1 + +// No physical button is populated +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV USART6 +#define UART_CLK_EN __HAL_RCC_USART6_CLK_ENABLE +#define UART_GPIO_AF GPIO_AF8_USART6 + +#define UART_TX_PORT GPIOG +#define UART_TX_PIN GPIO_PIN_9 + +#define UART_RX_PORT GPIOG +#define UART_RX_PIN GPIO_PIN_14 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 432; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 9; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Activate the OverDrive to reach the 216 MHz Frequency */ + HAL_PWREx_EnableOverDrive(); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/board.mk new file mode 100644 index 0000000..a18b323 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/board.mk @@ -0,0 +1,14 @@ +# Only OTG-HS has a connector on this board +PORT ?= 1 +SPEED ?= high + +CFLAGS += \ + -DSTM32F723xx \ + -DHSE_VALUE=25000000 \ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/STM32F723xE_FLASH.ld +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f723xx.s + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/stm32f7xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/stm32f7xx_hal_conf.h new file mode 100644 index 0000000..581f0e4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stlinkv3mini/stm32f7xx_hal_conf.h @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_CONF_H +#define __STM32F7xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_JPEG_MODULE_ENABLED */ +/* #define HAL_MDIOS_MODULE_ENABLED */ + + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)5) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)5) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ +/* LAN8742A PHY Address*/ +#define LAN8742A_PHY_ADDRESS 0x00 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x00000FFF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) + +#define PHY_READ_TO ((uint32_t)0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ + + +#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f7xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f7xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f7xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f7xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f7xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f7xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f7xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f7xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f7xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f7xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f7xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f7xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f7xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f7xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f7xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f7xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f7xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f7xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f7xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f7xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f7xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f7xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f7xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f7xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f7xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f7xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f7xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f7xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f7xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f7xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f7xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f7xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f7xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f7xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f7xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f7xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f7xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f7xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f7xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f7xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f7xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32f7xx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_MDIOS_MODULE_ENABLED + #include "stm32f7xx_hal_mdios.h" +#endif /* HAL_MDIOS_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld new file mode 100644 index 0000000..8645ce5 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld @@ -0,0 +1,167 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F723xE Device with +** 512KByte FLASH, 256KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20040000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x460; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/board.h new file mode 100644 index 0000000..93d83ef --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/board.h @@ -0,0 +1,105 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_1 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV USART6 +#define UART_CLK_EN __HAL_RCC_USART6_CLK_ENABLE +#define UART_GPIO_AF GPIO_AF8_USART6 + +#define UART_TX_PORT GPIOC +#define UART_TX_PIN GPIO_PIN_6 + +#define UART_RX_PORT GPIOC +#define UART_RX_PIN GPIO_PIN_7 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 432; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 9; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Activate the OverDrive to reach the 216 MHz Frequency */ + HAL_PWREx_EnableOverDrive(); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); +} + +//static inline void board_vbus_sense_init(void) +//{ +// +//} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/board.mk new file mode 100644 index 0000000..66d9ff8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/board.mk @@ -0,0 +1,15 @@ +PORT ?= 1 +SPEED ?= high + +CFLAGS += \ + -DSTM32F723xx \ + -DHSE_VALUE=25000000 \ + +LD_FILE = $(BOARD_PATH)/STM32F723xE_FLASH.ld +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f723xx.s + +# flash target using on-board stlink +flash: flash-stlink + +# For flash-jlink target +JLINK_DEVICE = stm32f723ie diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/stm32f7xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/stm32f7xx_hal_conf.h new file mode 100644 index 0000000..581f0e4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f723disco/stm32f7xx_hal_conf.h @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_CONF_H +#define __STM32F7xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_JPEG_MODULE_ENABLED */ +/* #define HAL_MDIOS_MODULE_ENABLED */ + + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)5) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)5) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ +/* LAN8742A PHY Address*/ +#define LAN8742A_PHY_ADDRESS 0x00 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x00000FFF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) + +#define PHY_READ_TO ((uint32_t)0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ + + +#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f7xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f7xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f7xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f7xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f7xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f7xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f7xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f7xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f7xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f7xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f7xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f7xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f7xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f7xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f7xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f7xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f7xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f7xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f7xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f7xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f7xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f7xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f7xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f7xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f7xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f7xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f7xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f7xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f7xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f7xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f7xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f7xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f7xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f7xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f7xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f7xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f7xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f7xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f7xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f7xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f7xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32f7xx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_MDIOS_MODULE_ENABLED + #include "stm32f7xx_hal_mdios.h" +#endif /* HAL_MDIOS_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld new file mode 100644 index 0000000..045ec76 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld @@ -0,0 +1,167 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F746ZGTx Device with +** 1024KByte FLASH, 320KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20050000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x460; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/board.h new file mode 100644 index 0000000..ee342b9 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/board.h @@ -0,0 +1,100 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOI +#define LED_PIN GPIO_PIN_1 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOI +#define BUTTON_PIN GPIO_PIN_11 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_AF GPIO_AF7_USART1 + +#define UART_TX_PORT GPIOA +#define UART_TX_PIN GPIO_PIN_9 + +#define UART_RX_PORT GPIOB +#define UART_RX_PIN GPIO_PIN_7 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 0 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 432; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 9; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Activate the OverDrive to reach the 216 MHz Frequency */ + HAL_PWREx_EnableOverDrive(); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/board.mk new file mode 100644 index 0000000..2ba59f6 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/board.mk @@ -0,0 +1,12 @@ +PORT ?= 1 +SPEED ?= high + +CFLAGS += \ + -DSTM32F746xx \ + -DHSE_VALUE=25000000 + +LD_FILE = $(BOARD_PATH)/STM32F746ZGTx_FLASH.ld +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f746xx.s + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/stm32f7xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/stm32f7xx_hal_conf.h new file mode 100644 index 0000000..03dec8f --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746disco/stm32f7xx_hal_conf.h @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_CONF_H +#define __STM32F7xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_JPEG_MODULE_ENABLED */ +/* #define HAL_MDIOS_MODULE_ENABLED */ + + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)5) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)5) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ +/* LAN8742A PHY Address*/ +#define LAN8742A_PHY_ADDRESS 0x00 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x00000FFF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) + +#define PHY_READ_TO ((uint32_t)0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ + + +#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f7xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f7xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f7xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f7xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f7xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f7xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f7xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f7xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f7xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f7xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f7xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f7xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f7xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f7xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f7xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f7xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f7xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f7xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f7xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f7xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f7xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f7xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f7xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f7xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f7xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f7xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f7xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f7xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f7xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f7xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f7xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f7xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f7xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f7xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f7xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f7xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f7xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f7xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f7xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f7xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f7xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32f7xx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_MDIOS_MODULE_ENABLED + #include "stm32f7xx_hal_mdios.h" +#endif /* HAL_MDIOS_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld new file mode 100644 index 0000000..b434a01 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld @@ -0,0 +1,167 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F746ZGTx Device with +** 1024KByte FLASH, 320KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20050000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x460; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/board.h new file mode 100644 index 0000000..92c109a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/board.h @@ -0,0 +1,98 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV USART3 +#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE +#define UART_GPIO_AF GPIO_AF7_USART3 + +#define UART_TX_PORT GPIOD +#define UART_TX_PIN GPIO_PIN_8 +#define UART_RX_PORT GPIOD +#define UART_RX_PIN GPIO_PIN_9 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 432; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 9; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + // TODO need to enable usb clock source + + /* Activate the OverDrive to reach the 216 MHz Frequency */ + HAL_PWREx_EnableOverDrive(); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/board.mk new file mode 100644 index 0000000..3dcf481 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/board.mk @@ -0,0 +1,12 @@ +PORT ?= 0 +SPEED ?= full + +CFLAGS += \ + -DSTM32F746xx \ + -DHSE_VALUE=8000000 + +LD_FILE = $(BOARD_PATH)/STM32F746ZGTx_FLASH.ld +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f746xx.s + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/stm32f7xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/stm32f7xx_hal_conf.h new file mode 100644 index 0000000..234191b --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f746nucleo/stm32f7xx_hal_conf.h @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_CONF_H +#define __STM32F7xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_JPEG_MODULE_ENABLED */ +/* #define HAL_MDIOS_MODULE_ENABLED */ + + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)5) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)5) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ +/* LAN8742A PHY Address*/ +#define LAN8742A_PHY_ADDRESS 0x00 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x00000FFF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) + +#define PHY_READ_TO ((uint32_t)0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ + + +#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f7xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f7xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f7xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f7xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f7xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f7xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f7xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f7xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f7xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f7xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f7xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f7xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f7xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f7xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f7xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f7xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f7xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f7xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f7xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f7xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f7xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f7xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f7xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f7xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f7xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f7xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f7xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f7xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f7xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f7xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f7xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f7xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f7xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f7xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f7xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f7xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f7xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f7xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f7xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f7xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f7xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32f7xx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_MDIOS_MODULE_ENABLED + #include "stm32f7xx_hal_mdios.h" +#endif /* HAL_MDIOS_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld new file mode 100644 index 0000000..0b6d5a4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F767ZITx Device with +** 2048KByte FLASH, 512KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20080000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/board.h new file mode 100644 index 0000000..1283f23 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/board.h @@ -0,0 +1,102 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV USART3 +#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE +#define UART_GPIO_AF GPIO_AF7_USART3 + +#define UART_TX_PORT GPIOD +#define UART_TX_PIN GPIO_PIN_8 + +#define UART_RX_PORT GPIOD +#define UART_RX_PIN GPIO_PIN_9 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 432; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 9; + RCC_OscInitStruct.PLL.PLLR = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Activate the OverDrive to reach the 216 MHz Frequency */ + HAL_PWREx_EnableOverDrive(); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); +} + + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/board.mk new file mode 100644 index 0000000..7710619 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/board.mk @@ -0,0 +1,15 @@ +PORT ?= 0 +SPEED ?= full + +CFLAGS += \ + -DSTM32F767xx \ + -DHSE_VALUE=8000000 \ + +LD_FILE = $(BOARD_PATH)/STM32F767ZITx_FLASH.ld +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f767xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f767zi + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/stm32f7xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/stm32f7xx_hal_conf.h new file mode 100644 index 0000000..234191b --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f767nucleo/stm32f7xx_hal_conf.h @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_CONF_H +#define __STM32F7xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_JPEG_MODULE_ENABLED */ +/* #define HAL_MDIOS_MODULE_ENABLED */ + + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)5) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)5) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ +/* LAN8742A PHY Address*/ +#define LAN8742A_PHY_ADDRESS 0x00 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x00000FFF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) + +#define PHY_READ_TO ((uint32_t)0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ + + +#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f7xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f7xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f7xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f7xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f7xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f7xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f7xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f7xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f7xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f7xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f7xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f7xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f7xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f7xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f7xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f7xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f7xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f7xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f7xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f7xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f7xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f7xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f7xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f7xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f7xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f7xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f7xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f7xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f7xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f7xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f7xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f7xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f7xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f7xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f7xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f7xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f7xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f7xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f7xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f7xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f7xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32f7xx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_MDIOS_MODULE_ENABLED + #include "stm32f7xx_hal_mdios.h" +#endif /* HAL_MDIOS_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld new file mode 100644 index 0000000..378ed80 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld @@ -0,0 +1,167 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F767ZITx Device with +** 2048KByte FLASH, 512KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20080000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/board.h new file mode 100644 index 0000000..5ec217f --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/board.h @@ -0,0 +1,101 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOJ +#define LED_PIN GPIO_PIN_12 +#define LED_STATE_ON 5 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_AF GPIO_AF7_USART1 + +#define UART_TX_PORT GPIOA +#define UART_TX_PIN GPIO_PIN_9 + +#define UART_RX_PORT GPIOA +#define UART_RX_PIN GPIO_PIN_10 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 432; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 9; + RCC_OscInitStruct.PLL.PLLR = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Activate the OverDrive to reach the 216 MHz Frequency */ + HAL_PWREx_EnableOverDrive(); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/board.mk new file mode 100644 index 0000000..45b4a78 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/board.mk @@ -0,0 +1,13 @@ +# Only OTG-HS has a connector on this board +PORT ?= 1 +SPEED ?= high + +CFLAGS += \ + -DSTM32F769xx \ + -DHSE_VALUE=25000000 \ + +LD_FILE = $(BOARD_PATH)/STM32F769ZITx_FLASH.ld +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f769xx.s + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/stm32f7xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/stm32f7xx_hal_conf.h new file mode 100644 index 0000000..581f0e4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/boards/stm32f769disco/stm32f7xx_hal_conf.h @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_CONF_H +#define __STM32F7xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_JPEG_MODULE_ENABLED */ +/* #define HAL_MDIOS_MODULE_ENABLED */ + + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)5) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)5) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ +/* LAN8742A PHY Address*/ +#define LAN8742A_PHY_ADDRESS 0x00 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x00000FFF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) + +#define PHY_READ_TO ((uint32_t)0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ + + +#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f7xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f7xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f7xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f7xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f7xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f7xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f7xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f7xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f7xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f7xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f7xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f7xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f7xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f7xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f7xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f7xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f7xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f7xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f7xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f7xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f7xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f7xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f7xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f7xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f7xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f7xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f7xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f7xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f7xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f7xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f7xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f7xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f7xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f7xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f7xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f7xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f7xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f7xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f7xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f7xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f7xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f7xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32f7xx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_MDIOS_MODULE_ENABLED + #include "stm32f7xx_hal_mdios.h" +#endif /* HAL_MDIOS_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.c b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.c new file mode 100644 index 0000000..14e3b2f --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.c @@ -0,0 +1,314 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 William D. Jones (thor0505@comcast.net), + * Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de), + * Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stm32f7xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void OTG_FS_IRQHandler(void) +{ + tud_int_handler(0); +} + +// Despite being call USB2_OTG +// OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port +void OTG_HS_IRQHandler(void) +{ + tud_int_handler(1); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); // ULPI NXT + __HAL_RCC_GPIOI_CLK_ENABLE(); // ULPI NXT + +#ifdef __HAL_RCC_GPIOJ_CLK_ENABLE + __HAL_RCC_GPIOJ_CLK_ENABLE(); +#endif + + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + // Uart TX + GPIO_InitStruct.Pin = UART_TX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_TX_PORT, &GPIO_InitStruct); + + // Uart RX + GPIO_InitStruct.Pin = UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_RX_PORT, &GPIO_InitStruct); + + UartHandle.Instance = UART_DEV; + UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; + HAL_UART_Init(&UartHandle); + +#if BOARD_DEVICE_RHPORT_NUM == 0 + // OTG_FS + + /* Configure DM DP Pins */ + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Configure OTG-FS ID pin */ + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Enable USB FS Clocks */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + +#if OTG_FS_VBUS_SENSE + /* Configure VBUS Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; +#else + // Disable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // B-peripheral session valid override enable + USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; +#endif // vbus sense + +#else + // OTG_HS + + #ifdef USB_HS_PHYC + // MCU with built-in HS PHY such as F723, F733, F730 + + /* Configure DM DP Pins */ + GPIO_InitStruct.Pin = (GPIO_PIN_14 | GPIO_PIN_15); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + // Enable HS VBUS sense (B device) via pin PB13 + USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBDEN; + + /* Configure OTG-HS ID pin */ + GPIO_InitStruct.Pin = GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /* Enable PHYC Clocks */ + __HAL_RCC_OTGPHYC_CLK_ENABLE(); + + #else + // MUC with external ULPI PHY + + /* ULPI CLK */ + GPIO_InitStruct.Pin = GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* ULPI D0 */ + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* ULPI D1 D2 D3 D4 D5 D6 D7 */ + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* ULPI STP */ + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /* NXT */ + GPIO_InitStruct.Pin = GPIO_PIN_4; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); + + /* ULPI DIR */ + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); + #endif // USB_HS_PHYC + + // Enable USB HS & ULPI Clocks + __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); + __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); + +#if OTG_HS_VBUS_SENSE + #error OTG HS VBUS Sense enabled is not implemented +#else + // No VBUS sense + USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // B-peripheral session valid override enable + USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; +#endif + + // Force device mode + USB_OTG_HS->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; + USB_OTG_HS->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + +#endif // BOARD_DEVICE_RHPORT_NUM + +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.mk new file mode 100644 index 0000000..8482e6d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32f7/family.mk @@ -0,0 +1,54 @@ +UF2_FAMILY_ID = 0x53b80f00 +ST_FAMILY = f7 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F7 \ + -DBOARD_DEVICE_RHPORT_NUM=$(PORT) + +ifeq ($(PORT), 1) + ifeq ($(SPEED), high) + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using OTG_HS in HighSpeed mode") + else + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED + $(info "Using OTG_HS in FullSpeed mode") + endif +else + $(info "Using OTG_FS") +endif + +# mcu driver cause following warnings +CFLAGS += -Wno-error=shadow -Wno-error=cast-align + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM7/r0p1 diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld new file mode 100644 index 0000000..935d97c --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld @@ -0,0 +1,190 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : Auto-generated by Ac6 System Workbench +** +** Abstract : Linker script for STM32G474RETx series +** 512Kbytes FLASH and 160Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed “as is,” without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2014 Ac6

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. 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. +** 3. Neither the name of Ac6 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 HOLDER 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. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +CCMSRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 32K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h new file mode 100644 index 0000000..eab0bd5 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h @@ -0,0 +1,134 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// G474RE Nucleo does not has usb connection. We need to manually connect +// - PA12 for D+, CN10.12 +// - PA11 for D-, CN10.14 + +// LED +#define LED_PORT GPIOA +#define LED_PIN GPIO_PIN_5 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV LPUART1 +#define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF12_LPUART1 +#define UART_TX_PIN GPIO_PIN_2 +#define UART_RX_PIN GPIO_PIN_3 + + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + // Configure the main internal regulator output voltage + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); + + // Initializes the CPU, AHB and APB busses clocks + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; + RCC_OscInitStruct.PLL.PLLN = 50; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + // Initializes the CPU, AHB and APB busses clocks + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; + +#if 0 // TODO need to check if USB clock is enabled + /* Enable HSI48 */ + memset(&RCC_OscInitStruct, 0, sizeof(RCC_OscInitStruct)); + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /*Enable CRS Clock*/ + RCC_CRSInitTypeDef RCC_CRSInitStruct= {0}; + __HAL_RCC_CRS_CLK_ENABLE(); + + /* Default Synchro Signal division factor (not divided) */ + RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; + + /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ + RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; + + /* HSI48 is synchronized with USB SOF at 1KHz rate */ + RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); + RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; + + /* Set the TRIM[5:0] to the default value */ + RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT; + + /* Start automatic synchronization */ + HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); +#endif +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk new file mode 100644 index 0000000..e41edd3 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk @@ -0,0 +1,10 @@ +CFLAGS += \ + -DSTM32G474xx \ + -DHSE_VALUE=24000000 + +LD_FILE = $(BOARD_PATH)/STM32G474RETx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32g474xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32g474re diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.c b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.c new file mode 100644 index 0000000..461dc61 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.c @@ -0,0 +1,186 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stm32g4xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_HP_IRQHandler(void) +{ + tud_int_handler(0); +} + +void USB_LP_IRQHandler(void) +{ + tud_int_handler(0); +} + +void USBWakeUp_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + board_led_write(false); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + +#ifdef UART_DEV + // UART + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle = (UART_HandleTypeDef){ + .Instance = UART_DEV, + .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.OverSampling = UART_OVERSAMPLING_16 + }; + HAL_UART_Init(&UartHandle); +#endif + + // USB Pins TODO double check USB clock and pin setup + // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + __HAL_RCC_USB_CLK_ENABLE(); + + board_vbus_sense_init(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ +#ifdef UART_DEV + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +#else + (void) buf; (void) len; (void) UartHandle; + return 0; +#endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.mk new file mode 100644 index 0000000..04222f3 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/family.mk @@ -0,0 +1,44 @@ +UF2_FAMILY_ID = 0x4c71240a +ST_FAMILY = g4 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32G4 + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=cast-align + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32g4/stm32g4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/stm32g4xx_hal_conf.h new file mode 100644 index 0000000..ad5f7db --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32g4/stm32g4xx_hal_conf.h @@ -0,0 +1,381 @@ +/** + ****************************************************************************** + * @file stm32g4xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32G4xx_HAL_CONF_H +#define STM32G4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED + + /*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CORDIC_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_FDCAN_MODULE_ENABLED */ +/*#define HAL_FMAC_MODULE_ENABLED */ +/*#define HAL_HRTIM_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_I2C_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Register Callbacks selection ############################## */ +/** + * @brief This is the list of modules where register callback can be used + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_EXTI_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (24000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE (48000000UL) /*!< Value of the Internal High Speed oscillator for USB FS/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) +/*!< Value of the Internal Low Speed oscillator in Hz +The real value may vary depending on the variations in voltage and temperature.*/ +#define LSI_VALUE (32000UL) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S and SAI peripherals + * This value is used by the I2S and SAI HAL modules to compute the I2S and SAI clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE (12288000UL) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32g4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32g4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32g4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32g4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32g4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32g4xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED +#include "stm32g4xx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32g4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32g4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32g4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32g4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED +#include "stm32g4xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32g4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_FMAC_MODULE_ENABLED +#include "stm32g4xx_hal_fmac.h" +#endif /* HAL_FMAC_MODULE_ENABLED */ + +#ifdef HAL_HRTIM_MODULE_ENABLED +#include "stm32g4xx_hal_hrtim.h" +#endif /* HAL_HRTIM_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32g4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32g4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32g4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32g4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32g4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED +#include "stm32g4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED +#include "stm32g4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32g4xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32g4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32g4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED +#include "stm32g4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32g4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32g4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32g4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32g4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32g4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32g4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED +#include "stm32g4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32g4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32g4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32g4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32g4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32G4xx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/board.h new file mode 100644 index 0000000..af2063c --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/board.h @@ -0,0 +1,143 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_PIN_4 +#define LED_STATE_ON 1 + +// Tamper push-button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 0 + +// Need to change jumper setting J7 and J8 from RS-232 to STLink +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOB +#define UART_GPIO_AF GPIO_AF4_USART1 +#define UART_TX_PIN GPIO_PIN_14 +#define UART_RX_PIN GPIO_PIN_15 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +// USB HS External PHY Pin: CLK, STP, DIR, NXT, D0-D7 +#define ULPI_PINS \ + {GPIOA, GPIO_PIN_3 }, {GPIOA, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_0 }, {GPIOB, GPIO_PIN_1 }, \ + {GPIOB, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_10}, {GPIOB, GPIO_PIN_11}, {GPIOB, GPIO_PIN_12}, \ + {GPIOB, GPIO_PIN_13}, {GPIOC, GPIO_PIN_0 }, {GPIOH, GPIO_PIN_4 }, {GPIOI, GPIO_PIN_11} + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32h7_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + /*!< Supply configuration update enable */ + HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {} + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + + /* PLL1 for System Clock */ + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 160; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLQ = 4; + + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* PLL3 for USB Clock */ + PeriphClkInitStruct.PLL3.PLL3M = 25; + PeriphClkInitStruct.PLL3.PLL3N = 336; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.PLL3.PLL3P = 2; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3Q = 7; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure bus clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ + RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + + /*activate CSI clock mondatory for I/O Compensation Cell*/ + __HAL_RCC_CSI_ENABLE() ; + + /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ + __HAL_RCC_SYSCFG_CLK_ENABLE() ; + + /* Enables the I/O Compensation Cell */ + HAL_EnableCompensationCell(); +} + +static inline void board_stm32h7_post_init(void) +{ + // For this board does nothing +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/board.mk new file mode 100644 index 0000000..b768a0e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/board.mk @@ -0,0 +1,14 @@ +CFLAGS += -DSTM32H743xx -DHSE_VALUE=25000000 + +# Default is Highspeed port +PORT ?= 1 +SPEED ?= high + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h743xx.s +LD_FILE = $(BOARD_PATH)/stm32h743xx_flash.ld + +# For flash-jlink target +JLINK_DEVICE = stm32h743xi + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/stm32h743xx_flash.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/stm32h743xx_flash.ld new file mode 100644 index 0000000..59b9ff4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743eval/stm32h743xx_flash.ld @@ -0,0 +1,173 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32H743XIHx Device with +** 2048KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K +RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K +RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K +ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >DTCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >DTCMRAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCMRAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/board.h new file mode 100644 index 0000000..06148c8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/board.h @@ -0,0 +1,122 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_0 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV USART3 +#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE +#define UART_GPIO_PORT GPIOD +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_8 +#define UART_RX_PIN GPIO_PIN_9 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32h7_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* The PWR block is always enabled on the H7 series- there is no clock + enable. For now, use the default VOS3 scale mode (lowest) and limit clock + frequencies to avoid potential current draw problems from bus + power when using the max clock speeds throughout the chip. */ + + /* Enable HSE Oscillator and activate PLL1 with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 7; + RCC_OscInitStruct.PLL.PLLR = 2; /* Unused */ + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_0; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \ + RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \ + RCC_CLOCKTYPE_D3PCLK1); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; + + /* Unlike on the STM32F4 family, it appears the maximum APB frequencies are + device-dependent- 120 MHz for this board according to Figure 2 of + the datasheet. Dividing by half will be safe for now. */ + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; + RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; + + /* 4 wait states required for 168MHz and VOS3. */ + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + + /* Like on F4, on H7, USB's actual peripheral clock and bus clock are + separate. However, the main system PLL (PLL1) doesn't have a direct + connection to the USB peripheral clock to generate 48 MHz, so we do this + dance. This will connect PLL1's Q output to the USB peripheral clock. */ + RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct; + + RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + RCC_PeriphCLKInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); +} + +static inline void board_stm32h7_post_init(void) +{ + // For this board does nothing +} + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/board.mk new file mode 100644 index 0000000..fc670fe --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/board.mk @@ -0,0 +1,13 @@ +CFLAGS += -DSTM32H743xx -DHSE_VALUE=8000000 + +# Default is FulSpeed port +PORT ?= 0 + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h743xx.s +LD_FILE = $(BOARD_PATH)/stm32h743xx_flash.ld + +# For flash-jlink target +JLINK_DEVICE = stm32h743zi + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/stm32h743xx_flash.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/stm32h743xx_flash.ld new file mode 100644 index 0000000..59b9ff4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h743nucleo/stm32h743xx_flash.ld @@ -0,0 +1,173 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32H743XIHx Device with +** 2048KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K +RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K +RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K +ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >DTCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >DTCMRAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCMRAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h745disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h745disco/board.h new file mode 100644 index 0000000..d33e0c8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h745disco/board.h @@ -0,0 +1,139 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOJ +#define LED_PIN GPIO_PIN_2 +#define LED_STATE_ON 1 + +// Blue push-button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART +#define UART_DEV USART3 +#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE +#define UART_GPIO_PORT GPIOB +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_10 +#define UART_RX_PIN GPIO_PIN_11 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32h7_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + /*!< Supply configuration update enable */ + /* For STM32H750XB, use "HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);" */ + HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY); + + /* The voltage scaling allows optimizing the power consumption when the + device is clocked below the maximum system frequency, to update the + voltage scaling value regarding system frequency refer to product + datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {} + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + + /* PLL1 for System Clock */ + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 160; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLQ = 4; + + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* PLL3 for USB Clock */ + PeriphClkInitStruct.PLL3.PLL3M = 25; + PeriphClkInitStruct.PLL3.PLL3N = 336; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.PLL3.PLL3P = 2; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3Q = 7; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure bus clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ + RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + + /*activate CSI clock mondatory for I/O Compensation Cell*/ + __HAL_RCC_CSI_ENABLE() ; + + /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ + __HAL_RCC_SYSCFG_CLK_ENABLE() ; + + /* Enables the I/O Compensation Cell */ + HAL_EnableCompensationCell(); +} + +static inline void board_stm32h7_post_init(void) +{ + // For this board does nothing +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h745disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h745disco/board.mk new file mode 100644 index 0000000..384065b --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/stm32h745disco/board.mk @@ -0,0 +1,17 @@ +# STM32H745I-DISCO uses OTG_FS +# FIXME: Reset enumerates, un/replug USB plug does not enumerate + +CFLAGS += -DSTM32H745xx -DCORE_CM7 -DHSE_VALUE=25000000 + +# Default is FulSpeed port +PORT ?= 0 + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h745xx.s +LD_FILE = $(ST_CMSIS)/Source/Templates/gcc/linker/stm32h745xx_flash_CM7.ld + +# For flash-jlink target +JLINK_DEVICE = stm32h745xi_m7 + +# flash target using on-board stlink +flash: flash-stlink + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/STM32H743IITX_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/STM32H743IITX_FLASH.ld new file mode 100644 index 0000000..73d2ded --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/STM32H743IITX_FLASH.ld @@ -0,0 +1,175 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7 series +** 2048Kbytes FLASH and 192Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2019 STMicroelectronics. +** All rights reserved. +** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +**************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x2000 ; /* required amount of heap */ +_Min_Stack_Size = 0x2000 ; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K + RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K + RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K + RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K + ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h new file mode 100644 index 0000000..09442c2 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h @@ -0,0 +1,229 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 + * Ha Thach (tinyusb.org) + * Benjamin Evans + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +/* ** BOARD SETUP ** + * + * NOTE: This board has bad signal integrity so you may experience some problems. + * This setup assumes you have an openh743i-c Core and breakout board. For the HS + * examples it also assumes you have a waveshare USB3300 breakout board plugged + * into the ULPI PMOD header on the openh743i-c. + * + * UART Debugging: + * Due to pin conflicts in the HS configuration, this BSP uses USART3 (PD8, PD9). + * As such, you won't be able to use the UART to USB converter on board and will + * require an external UART to USB converter. You could use the waveshare FT232 + * USB UART Board (micro) but any 3.3V UART to USB converter will be fine. + * + * Fullspeed: + * If VBUS sense is enabled, ensure the PA9-VBUS jumper is connected on the core + * board. Connect the PB6 jumper for the LED and the Wakeup - PA0 jumper for the + * button. Connect the USB cable to the USB connector on the core board. + * + * High Speed: + * Remove all jumpers from the openh743i-c (especially the USART1 jumpers as the + * pins conflict). Connect the PB6 jumper for the LED and the Wakeup - PA0 + * jumper for the button. + * + * The reset pin on the ULPI PMOD port is not connected to the MCU. You'll need + * to solder a wire from the RST pin on the USB3300 to a pin of your choosing on + * the openh743i-c board (this example assumes you've used PD14 as specified with + * the ULPI_RST_PORT and ULPI_RST_PIN defines below). + * + * Preferably power the board using the external 5VDC jack. Connect the USB cable + * to the USB connector on the ULPI board. Adjust delays in this file as required. + * + * If you're having trouble, ask a question on the tinyUSB Github Discussion boards. + * + * Have fun! + * +*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_6 +#define LED_STATE_ON 1 + +// Tamper push-button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +// Need to change jumper setting J7 and J8 from RS-232 to STLink +#define UART_DEV USART3 +#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE +#define UART_GPIO_PORT GPIOD +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_8 +#define UART_RX_PIN GPIO_PIN_9 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + + // USB HS External PHY Pin: CLK, STP, DIR, NXT, D0-D7 +#define ULPI_PINS \ + {GPIOA, GPIO_PIN_3 }, {GPIOA, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_0 }, {GPIOB, GPIO_PIN_1 }, \ + {GPIOB, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_10}, {GPIOB, GPIO_PIN_11}, {GPIOB, GPIO_PIN_12}, \ + {GPIOB, GPIO_PIN_13}, {GPIOC, GPIO_PIN_0 }, {GPIOC, GPIO_PIN_2 }, {GPIOC, GPIO_PIN_3 } + +// ULPI PHY reset pin used by walkaround +#define ULPI_RST_PORT GPIOD +#define ULPI_RST_PIN GPIO_PIN_14 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32h7_clock_init(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + // Supply configuration update enable + HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); + + // Configure the main internal regulator output voltage + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + + while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) + { + } + // Macro to configure the PLL clock source + __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE); + + // Initializes the RCC Oscillators according to the specified parameters in the RCC_OscInitTypeDef structure. + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 2; + RCC_OscInitStruct.PLL.PLLN = 240; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB | RCC_PERIPHCLK_USART3; + PeriphClkInitStruct.PLL3.PLL3M = 8; + PeriphClkInitStruct.PLL3.PLL3N = 336; + PeriphClkInitStruct.PLL3.PLL3P = 2; + PeriphClkInitStruct.PLL3.PLL3Q = 7; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_0; + PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_PLL3; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + // Initializes the CPU, AHB and APB buses clocks + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; + RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); + + __HAL_RCC_CSI_ENABLE(); + + // Enable SYSCFG clock mondatory for I/O Compensation Cell + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + // Enables the I/O Compensation Cell + HAL_EnableCompensationCell(); + + // Enable voltage detector + HAL_PWREx_EnableUSBVoltageDetector(); +} + +static inline void timer_board_delay(TIM_HandleTypeDef* tim_hdl, uint32_t ms) +{ + uint32_t startMs = __HAL_TIM_GET_COUNTER(tim_hdl); + while ((__HAL_TIM_GET_COUNTER(tim_hdl) - startMs) < ms) + { + asm("nop"); //do nothing + } +} + +static inline void board_stm32h7_post_init(void) +{ + // walkaround for reseting the ULPI PHY using Timer since systick is not + // available when RTOS is used. + + // Init timer + TIM_HandleTypeDef tim2Handle; + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + + __HAL_RCC_TIM2_CLK_ENABLE(); + + //Assuming timer clock is running at 260Mhz this should configure the timer counter to 1000Hz + tim2Handle.Instance = TIM2; + tim2Handle.Init.Prescaler = 60000U - 1U; + tim2Handle.Init.CounterMode = TIM_COUNTERMODE_UP; + tim2Handle.Init.Period = 0xFFFFFFFFU; + tim2Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; + tim2Handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + HAL_TIM_Base_Init(&tim2Handle); + + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + HAL_TIM_ConfigClockSource(&tim2Handle, &sClockSourceConfig); + + //Start the timer + HAL_TIM_Base_Start(&tim2Handle); + + // Reset PHY, change the delays as you see fit + timer_board_delay(&tim2Handle, 5U); + HAL_GPIO_WritePin(ULPI_RST_PORT, ULPI_RST_PIN, 1U); + timer_board_delay(&tim2Handle, 20U); + HAL_GPIO_WritePin(ULPI_RST_PORT, ULPI_RST_PIN, 0U); + timer_board_delay(&tim2Handle, 20U); + + //Disable the timer used for delays + HAL_TIM_Base_Stop(&tim2Handle); + __HAL_RCC_TIM2_CLK_DISABLE(); +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/board.mk new file mode 100644 index 0000000..4dfcc1c --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/boards/waveshare_openh743i/board.mk @@ -0,0 +1,19 @@ +CFLAGS += -DSTM32H743xx -DHSE_VALUE=8000000 + +# Default is HS port +PORT ?= 1 + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h743xx.s +LD_FILE = $(BOARD_PATH)/STM32H743IITX_FLASH.ld + +# Use Timer module for ULPI PHY reset +CFLAGS += -DHAL_TIM_MODULE_ENABLED +SRC_C += \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_tim.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_tim_ex.c + +# For flash-jlink target +JLINK_DEVICE = stm32h743ii + +# flash target using jlink +flash: flash-jlink \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.c b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.c new file mode 100644 index 0000000..84976b4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.c @@ -0,0 +1,268 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 + * William D. Jones (thor0505@comcast.net), + * Ha Thach (tinyusb.org) + * Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stm32h7xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ + +// Despite being call USB2_OTG +// OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port +void OTG_FS_IRQHandler(void) +{ + tud_int_handler(0); +} + +// Despite being call USB2_OTG +// OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port +void OTG_HS_IRQHandler(void) +{ + tud_int_handler(1); +} + + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_stm32h7_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); // USB ULPI NXT + __HAL_RCC_GPIOC_CLK_ENABLE(); // USB ULPI NXT + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); // USB ULPI NXT + __HAL_RCC_GPIOI_CLK_ENABLE(); // USB ULPI NXT + __HAL_RCC_GPIOJ_CLK_ENABLE(); + + // Enable UART Clock + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + // Uart + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle.Instance = UART_DEV; + UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; + HAL_UART_Init(&UartHandle); + +#if BOARD_DEVICE_RHPORT_NUM == 0 + // Despite being call USB2_OTG + // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port + // PA9 VUSB, PA10 ID, PA11 DM, PA12 DP + + // Configure DM DP Pins + GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // This for ID line debug + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // https://community.st.com/s/question/0D50X00009XkYZLSA3/stm32h7-nucleo-usb-fs-cdc + // TODO: Board init actually works fine without this line. + HAL_PWREx_EnableUSBVoltageDetector(); + __HAL_RCC_USB2_OTG_FS_CLK_ENABLE(); + +#if OTG_FS_VBUS_SENSE + // Configure VBUS Pin + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; +#else + // Disable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // B-peripheral session valid override enable + USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; +#endif // vbus sense + +#elif BOARD_DEVICE_RHPORT_NUM == 1 + // Despite being call USB2_OTG + // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port + + struct { + GPIO_TypeDef* port; + uint32_t pin; + } const ulpi_pins[] = + { + ULPI_PINS + }; + + for (uint8_t i=0; i < sizeof(ulpi_pins)/sizeof(ulpi_pins[0]); i++) + { + GPIO_InitStruct.Pin = ulpi_pins[i].pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(ulpi_pins[i].port, &GPIO_InitStruct); + } + + // Enable USB HS & ULPI Clocks + __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE(); + __HAL_RCC_USB1_OTG_HS_CLK_ENABLE(); + +#if OTG_HS_VBUS_SENSE + #error OTG HS VBUS Sense enabled is not implemented +#else + // No VBUS sense + USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // B-peripheral session valid override enable + USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; +#endif + + // Force device mode + USB_OTG_HS->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; + USB_OTG_HS->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + + HAL_PWREx_EnableUSBVoltageDetector(); + + // For waveshare openh743 ULPI PHY reset walkaround + board_stm32h7_post_init(); +#endif // rhport = 1 + +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return (BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) ? 1 : 0; +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +} + + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler(void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.mk new file mode 100644 index 0000000..096d04d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/family.mk @@ -0,0 +1,57 @@ +UF2_FAMILY_ID = 0x6db66082 +ST_FAMILY = h7 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32H7 \ + -DBOARD_DEVICE_RHPORT_NUM=$(PORT) + +ifeq ($(PORT), 1) + ifeq ($(SPEED), high) + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using OTG_HS in HighSpeed mode") + else + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED + $(info "Using OTG_HS in FullSpeed mode") + endif +else + $(info "Using OTG_FS") +endif + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align + +# All source paths should be relative to the top level. + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM7/r0p1 + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32h7/stm32h7xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/stm32h7xx_hal_conf.h new file mode 100644 index 0000000..a7cc6d8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32h7/stm32h7xx_hal_conf.h @@ -0,0 +1,483 @@ +/** + ****************************************************************************** + * @file stm32h7xx_hal_conf_template.h + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32h7xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of STMicroelectronics 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 HOLDER 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H7xx_HAL_CONF_H +#define __STM32H7xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_COMP_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_FDCAN_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_HASH_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_HRTIM_MODULE_ENABLED */ +/* #define HAL_HSEM_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_JPEG_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_MDIOS_MODULE_ENABLED */ +/* #define HAL_MDMA_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_OPAMP_MODULE_ENABLED */ +/* #define HAL_PCD_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_RAMECC_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SWPMI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +//#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ +#error HSE_VALUE is not defined +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal oscillator (CSI) default value. + * This value is the default CSI value after Reset. + */ +#if !defined (CSI_VALUE) + #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External clock in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0x0F) /*!< tick interrupt priority */ +#define USE_RTOS 0 +#define USE_SD_TRANSCEIVER 1U /*!< use uSD Transceiver */ +#define USE_SPI_CRC 1U /*!< use CRC in SPI */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################### Ethernet Configuration ######################### */ +#define ETH_TX_DESC_CNT 4 /* number of Ethernet Tx DMA descriptors */ +#define ETH_RX_DESC_CNT 4 /* number of Ethernet Rx DMA descriptors */ + +#define ETH_MAC_ADDR0 ((uint8_t)0x02) +#define ETH_MAC_ADDR1 ((uint8_t)0x00) +#define ETH_MAC_ADDR2 ((uint8_t)0x00) +#define ETH_MAC_ADDR3 ((uint8_t)0x00) +#define ETH_MAC_ADDR4 ((uint8_t)0x00) +#define ETH_MAC_ADDR5 ((uint8_t)0x00) + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32h7xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32h7xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32h7xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_MDMA_MODULE_ENABLED + #include "stm32h7xx_hal_mdma.h" +#endif /* HAL_MDMA_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32h7xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32h7xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32h7xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32h7xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32h7xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32h7xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32h7xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32h7xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32h7xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED + #include "stm32h7xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32h7xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32h7xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32h7xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32h7xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32h7xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32h7xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_HRTIM_MODULE_ENABLED + #include "stm32h7xx_hal_hrtim.h" +#endif /* HAL_HRTIM_MODULE_ENABLED */ + +#ifdef HAL_HSEM_MODULE_ENABLED + #include "stm32h7xx_hal_hsem.h" +#endif /* HAL_HSEM_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32h7xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32h7xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32h7xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32h7xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32h7xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32h7xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32h7xx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_MDIOS_MODULE_ENABLED + #include "stm32h7xx_hal_mdios.h" +#endif /* HAL_MDIOS_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32h7xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32h7xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED +#include "stm32h7xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32h7xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32h7xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32h7xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RAMECC_MODULE_ENABLED + #include "stm32h7xx_hal_ramecc.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32h7xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32h7xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32h7xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32h7xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32h7xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32h7xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32h7xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SWPMI_MODULE_ENABLED + #include "stm32h7xx_hal_swpmi.h" +#endif /* HAL_SWPMI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32h7xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32h7xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32h7xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32h7xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32h7xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32h7xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32h7xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32h7xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32h7xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t *file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H7xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld new file mode 100644 index 0000000..787418e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32L053C8Tx Device with +** 64KByte FLASH, 8KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20002000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x200; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/board.mk new file mode 100644 index 0000000..e19101d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/board.mk @@ -0,0 +1,54 @@ +ST_FAMILY = l0 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m0plus \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DSTM32L053xx \ + -DCFG_EXAMPLE_MSC_READONLY \ + -DCFG_EXAMPLE_VIDEO_READONLY \ + -DCFG_TUSB_MCU=OPT_MCU_STM32L0 + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter -Wno-error=maybe-uninitialized + +# All source paths should be relative to the top level. +LD_FILE = hw/bsp/$(BOARD)/STM32L053C8Tx_FLASH.ld + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + +SRC_S += \ + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l053xx.s + +INC += \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM0 + +# For flash-jlink target +JLINK_DEVICE = STM32L053R8 + +# Path to STM32 Cube Programmer CLI, should be added into system path +STM32Prog = STM32_Programmer_CLI + +# flash target using on-board stlink +flash: $(BUILD)/$(PROJECT).elf + $(STM32Prog) --connect port=swd --write $< --go diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/stm32l0538disco.c b/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/stm32l0538disco.c new file mode 100644 index 0000000..f0f1d02 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/stm32l0538disco.c @@ -0,0 +1,205 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "stm32l0xx_hal.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +#define LED_PORT GPIOA +#define LED_PIN GPIO_PIN_5 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow: + * HSI48 used as USB clock source + * - System Clock source = HSI + * - HSI Frequency(Hz) = 16000000 + * - SYSCLK(Hz) = 16000000 + * - HCLK(Hz) = 16000000 + * - AHB Prescaler = 1 + * - APB1 Prescaler = 1 + * - APB2 Prescaler = 1 + * - Flash Latency(WS) = 0 + * - Main regulator output voltage = Scale1 mode + * @param None + * @retval None + */ +static void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + static RCC_CRSInitTypeDef RCC_CRSInitStruct; + + /* Enable HSI Oscillator to be used as System clock source + Enable HSI48 Oscillator to be used as USB clock source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select HSI48 as USB clock source */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select HSI as system clock source and configure the HCLK, PCLK1 and PCLK2 + clock dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0); + + /*Configure the clock recovery system (CRS)**********************************/ + + /*Enable CRS Clock*/ + __HAL_RCC_CRS_CLK_ENABLE(); + + /* Default Synchro Signal division factor (not divided) */ + RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; + /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ + RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; + /* HSI48 is synchronized with USB SOF at 1KHz rate */ + RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); + RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; + /* Set the TRIM[5:0] to the default value*/ + RCC_CRSInitStruct.HSI48CalibrationValue = 0x20; + /* Start automatic synchronization */ + HAL_RCCEx_CRSConfig (&RCC_CRSInitStruct); +} + +void board_init(void) +{ + SystemClock_Config(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + //NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + __HAL_RCC_GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + board_led_write(false); + + // Button + //__HAL_RCC_GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + // USB + /* Configure DM DP Pins */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Enable USB FS Clock */ + __HAL_RCC_USB_CLK_ENABLE(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/stm32l0xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/stm32l0xx_hal_conf.h new file mode 100644 index 0000000..773b74e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l0538disco/stm32l0xx_hal_conf.h @@ -0,0 +1,331 @@ +/** + ****************************************************************************** + * @file stm32l0xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * + * Copyright (c) 2016 STMicroelectronics International N.V. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L0xx_HAL_CONF_H +#define __STM32L0xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +// #define HAL_ADC_MODULE_ENABLED +/* #define HAL_COMP_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_FIREWALL_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LCD_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +//#define HAL_RNG_MODULE_ENABLED +/* #define HAL_RTC_MODULE_ENABLED */ +//#define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +/* #define HAL_TSC_MODULE_ENABLED */ +/* #define HAL_UART_MODULE_ENABLED */ +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +//#define HAL_PCD_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ + + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE ((uint32_t)2097152U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator for USB (HSI48) value. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)37000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +/** + * @brief Time out for LSE start up value in ms. + */ +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define PREREAD_ENABLE 1U +#define BUFFER_CACHE_DISABLE 0U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32l0xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32l0xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32l0xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32l0xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32l0xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32l0xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32l0xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32l0xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32l0xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FIREWALL_MODULE_ENABLED + #include "stm32l0xx_hal_firewall.h" +#endif /* HAL_FIREWALL_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32l0xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32l0xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32l0xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32l0xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED + #include "stm32l0xx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32l0xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32l0xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32l0xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32l0xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32l0xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32l0xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32l0xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32l0xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32l0xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32l0xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32l0xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32l0xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32l0xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32l0xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t *file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L0xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld new file mode 100644 index 0000000..98f468a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld @@ -0,0 +1,183 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32L476VGTx Device with +** 1024KByte FLASH, 96KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20018000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x500; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(8); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(8); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(8); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(8); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >FLASH + + .ARM.extab : + { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >FLASH + .ARM : { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >FLASH + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >FLASH + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >FLASH + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/board.h new file mode 100644 index 0000000..42c657d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/board.h @@ -0,0 +1,139 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_2 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV USART2 +#define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE +#define UART_GPIO_PORT GPIOD +#define UART_GPIO_AF GPIO_AF7_USART2 +#define UART_TX_PIN GPIO_PIN_5 +#define UART_RX_PIN GPIO_PIN_6 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * + * If define USB_USE_LSE_MSI_CLOCK enabled: + * System Clock source = PLL (MSI) + * SYSCLK(Hz) = 80000000 + * HCLK(Hz) = 80000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 1 + * APB2 Prescaler = 2 + * MSI Frequency(Hz) = 4800000 + * LSE Frequency(Hz) = 32768 + * PLL_M = 6 + * PLL_N = 40 + * PLL_P = 7 + * PLL_Q = 4 + * PLL_R = 4 + * Flash Latency(WS) = 4 + * @param None + * @retval None + */ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + /* Enable the LSE Oscillator */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Enable the CSS interrupt in case LSE signal is corrupted or not present */ + HAL_RCCEx_DisableLSECSS(); + + /* Set tick interrupt priority, default HAL value is intentionally invalid + and that prevents PLL initialization in HAL_RCC_OscConfig() */ + HAL_InitTick((1UL << __NVIC_PRIO_BITS) - 1UL); + + /* Enable MSI Oscillator and activate PLL with MSI as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; + RCC_OscInitStruct.MSIState = RCC_MSI_ON; + RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; + RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; + RCC_OscInitStruct.PLL.PLLM = 6; + RCC_OscInitStruct.PLL.PLLN = 40; + RCC_OscInitStruct.PLL.PLLP = 7; + RCC_OscInitStruct.PLL.PLLQ = 4; + RCC_OscInitStruct.PLL.PLLR = 4; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Enable MSI Auto-calibration through LSE */ + HAL_RCCEx_EnableMSIPLLMode(); + + /* Select MSI output as USB clock source */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); +} + +static inline void board_vbus_sense_init(void) +{ + // L476Disco use general GPIO PC11 for VBUS sensing instead of dedicated PA9 as others + // Disable VBUS Sense and force device mode + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN | USB_OTG_GOTGCTL_BVALOVAL; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/board.mk new file mode 100644 index 0000000..e7b8557 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l476disco/board.mk @@ -0,0 +1,10 @@ +CFLAGS += \ + -DSTM32L476xx \ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/STM32L476VGTx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l476xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32l476vg diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld new file mode 100644 index 0000000..c1a490a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld @@ -0,0 +1,200 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32L4P5ZGTx Device from STM32L4PLUS series +** 1024Kbytes ROM +** 320Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2019 STMicroelectronics

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. 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. +** 3. Neither the name of STMicroelectronics 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 HOLDER 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. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + 0x0001FFFF; /* end of "SRAM1" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "ROM" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >ROM + + /* The program code and other data into "ROM" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >ROM + + /* Constant data into "ROM" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >ROM + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >ROM + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >ROM + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >ROM + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >ROM + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >ROM + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> ROM + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.h new file mode 100644 index 0000000..1df389a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.h @@ -0,0 +1,137 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV LPUART1 +#define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOG +#define UART_GPIO_AF GPIO_AF8_LPUART1 +#define UART_TX_PIN GPIO_PIN_7 +#define UART_RX_PIN GPIO_PIN_8 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (MSI) + * SYSCLK(Hz) = 120000000 + * HCLK(Hz) = 120000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 1 + * APB2 Prescaler = 1 + * MSI Frequency(Hz) = 48000000 + * PLL_M = 12 + * PLL_N = 60 + * PLL_P = 2 + * PLL_Q = 2 + * VDD(V) = 3.3 + * Main regulator output voltage = Scale1 mode + * Flash Latency(WS) = 5 + * The USB clock configuration from PLLSAI: + * PLLSAIP = 8 FIXME + * PLLSAIN = 384 FIXME + * PLLSAIQ = 7 FIXME + * @param None + * @retval None + */ + +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + /* Activate PLL with MSI , stabilizied via PLL by LSE */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI; + RCC_OscInitStruct.MSIState = RCC_MSI_ON; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; + RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; + RCC_OscInitStruct.PLL.PLLM = 12; + RCC_OscInitStruct.PLL.PLLN = 60; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Enable MSI Auto-calibration through LSE */ + HAL_RCCEx_EnableMSIPLLMode(); + + /* Select MSI output as USB clock source */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select MSI output as USB clock source */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; + PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + // Avoid overshoot and start with HCLK 60 MHz + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); + + /* AHB prescaler divider at 1 as second step */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.mk new file mode 100644 index 0000000..8252dd8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.mk @@ -0,0 +1,10 @@ +CFLAGS += \ + -DSTM32L4P5xx \ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/STM32L4P5ZGTX_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l4p5xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32l4p5zg diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld new file mode 100644 index 0000000..f93a160 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld @@ -0,0 +1,167 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32L4RxI Device with +** 2048KByte FLASH, 640KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x200a0000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x460; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.h new file mode 100644 index 0000000..1df389a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.h @@ -0,0 +1,137 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV LPUART1 +#define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOG +#define UART_GPIO_AF GPIO_AF8_LPUART1 +#define UART_TX_PIN GPIO_PIN_7 +#define UART_RX_PIN GPIO_PIN_8 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (MSI) + * SYSCLK(Hz) = 120000000 + * HCLK(Hz) = 120000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 1 + * APB2 Prescaler = 1 + * MSI Frequency(Hz) = 48000000 + * PLL_M = 12 + * PLL_N = 60 + * PLL_P = 2 + * PLL_Q = 2 + * VDD(V) = 3.3 + * Main regulator output voltage = Scale1 mode + * Flash Latency(WS) = 5 + * The USB clock configuration from PLLSAI: + * PLLSAIP = 8 FIXME + * PLLSAIN = 384 FIXME + * PLLSAIQ = 7 FIXME + * @param None + * @retval None + */ + +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + /* Activate PLL with MSI , stabilizied via PLL by LSE */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI; + RCC_OscInitStruct.MSIState = RCC_MSI_ON; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; + RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; + RCC_OscInitStruct.PLL.PLLM = 12; + RCC_OscInitStruct.PLL.PLLN = 60; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Enable MSI Auto-calibration through LSE */ + HAL_RCCEx_EnableMSIPLLMode(); + + /* Select MSI output as USB clock source */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select MSI output as USB clock source */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; + PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + // Avoid overshoot and start with HCLK 60 MHz + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); + + /* AHB prescaler divider at 1 as second step */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.mk new file mode 100644 index 0000000..3d7fa22 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.mk @@ -0,0 +1,14 @@ +CFLAGS += \ + -DHSE_VALUE=8000000 \ + -DSTM32L4R5xx \ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/STM32L4RXxI_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l4r5xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32l4r5zi + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.c b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.c new file mode 100644 index 0000000..c15be98 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.c @@ -0,0 +1,198 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 William D. Jones (thor0505@comcast.net), + * Ha Thach (tinyusb.org) + * Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stm32l4xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void OTG_FS_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + //NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + /* Enable USB power on Pwrctrl CR2 register */ + /* Enable Power Clock*/ + __HAL_RCC_PWR_CLK_ENABLE(); + +#if defined(PWR_CR5_R1MODE) + /* Enable voltage range 1 boost mode for frequency above 80 Mhz */ + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); +#endif + + /* Enable USB power on Pwrctrl CR2 register */ + HAL_PWREx_EnableVddUSB(); + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + // IOSV bit MUST be set to access GPIO port G[2:15] */ + __HAL_RCC_PWR_CLK_ENABLE(); + HAL_PWREx_EnableVddIO2(); + + // Uart + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle.Instance = UART_DEV; + UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; + UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + //UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1; + UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + + HAL_UART_Init(&UartHandle); + + /* Configure USB FS GPIOs */ + /* Configure DM DP Pins */ + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Configure VBUS Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Configure ID pin */ + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Enable USB FS Clocks */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + + board_vbus_sense_init(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.mk new file mode 100644 index 0000000..d6f55e5 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/family.mk @@ -0,0 +1,45 @@ +ST_FAMILY = l4 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32L4 + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align + +#src/portable/st/synopsys/dcd_synopsys.c +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c + +INC += \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/$(BOARD_PATH) + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32l4/stm32l4xx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/stm32l4xx_hal_conf.h new file mode 100644 index 0000000..312f86d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32l4/stm32l4xx_hal_conf.h @@ -0,0 +1,420 @@ +/** + ****************************************************************************** + * @file stm32l4xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32l4xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L4xx_HAL_CONF_H +#define __STM32L4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_COMP_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_FIREWALL_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +// #define HAL_NOR_MODULE_ENABLED +// #define HAL_SRAM_MODULE_ENABLED +/* #define HAL_HCD_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +//#define HAL_I2C_MODULE_ENABLED +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +//#define HAL_LCD_MODULE_ENABLED +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_OPAMP_MODULE_ENABLED */ +//#define HAL_PCD_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +//#define HAL_SAI_MODULE_ENABLED +//#define HAL_SD_MODULE_ENABLED +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_SWPMI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +/* #define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ + + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE 48000000U /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) + #define EXTERNAL_SAI1_CLOCK_VALUE 48000U /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/** + * @brief External clock source for SAI2 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI2_CLOCK_VALUE) + #define EXTERNAL_SAI2_CLOCK_VALUE 48000U /*!< Value of the SAI2 External clock source in Hz*/ +#endif /* EXTERNAL_SAI2_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32l4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32l4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32l4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32l4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32l4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32l4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32l4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "Legacy/stm32l4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32l4xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32l4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32l4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32l4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FIREWALL_MODULE_ENABLED + #include "stm32l4xx_hal_firewall.h" +#endif /* HAL_FIREWALL_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32l4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32l4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32l4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32l4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32l4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32l4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED + #include "stm32l4xx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32l4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32l4xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32l4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32l4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32l4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32l4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32l4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32l4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32l4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32l4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SWPMI_MODULE_ENABLED + #include "stm32l4xx_hal_swpmi.h" +#endif /* HAL_SWPMI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32l4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32l4xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32l4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32l4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32l4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32l4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32l4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32l4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32l4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t *file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h new file mode 100644 index 0000000..f42c7d6 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h @@ -0,0 +1,122 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022, Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_5 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_4 +#define BUTTON_STATE_ACTIVE 0 + +// UART Enable for STLink VCOM +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOB +#define UART_GPIO_AF GPIO_AF7_USART1 +#define UART_TX_PIN GPIO_PIN_6 +#define UART_RX_PIN GPIO_PIN_7 + + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + // Initializes the CPU, AHB and APB busses clocks + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; + RCC_OscInitStruct.PLL.PLLN = 24; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV3; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + // Initializes the CPU, AHB and APB busses clocks + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; + +#if 0 // TODO need to check if USB clock is enabled + /* Enable HSI48 */ + memset(&RCC_OscInitStruct, 0, sizeof(RCC_OscInitStruct)); + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /*Enable CRS Clock*/ + RCC_CRSInitTypeDef RCC_CRSInitStruct= {0}; + __HAL_RCC_CRS_CLK_ENABLE(); + + /* Default Synchro Signal division factor (not divided) */ + RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; + + /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ + RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; + + /* HSI48 is synchronized with USB SOF at 1KHz rate */ + RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); + RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; + + /* Set the TRIM[5:0] to the default value */ + RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT; + + /* Start automatic synchronization */ + HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); +#endif +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk new file mode 100644 index 0000000..d6adc6b --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk @@ -0,0 +1,9 @@ +CFLAGS += \ + -DSTM32WB55xx + +LD_FILE = $(BOARD_PATH)/stm32wb55xx_flash_cm4.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32wb55xx_cm4.s + +# For flash-jlink target +JLINK_DEVICE = STM32WB55RG diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld new file mode 100644 index 0000000..660f301 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld @@ -0,0 +1,171 @@ +/** +***************************************************************************** +** +** File : stm32wb55xx_flash_cm4.ld +** +** Abstract : System Workbench Minimal System calls file +** +** For more information about which c-functions +** need which of these lowlevel functions +** please consult the Newlib libc-manual +** +** Environment : System Workbench for MCU +** +** Distribution: The file is distributed “as is,†without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2019 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20030000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x400; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 +RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM1 AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM1 + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM1 + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } + MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED + MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED + MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED +} + + diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.c b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.c new file mode 100644 index 0000000..1ed3830 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.c @@ -0,0 +1,190 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stm32wbxx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_HP_IRQHandler(void) +{ + tud_int_handler(0); +} + +void USB_LP_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + +#if 0 + // MCO configuration for System clock value verification PA8 will have SYSCLK / 2 + GPIO_InitStruct.Pin = 8; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_2); +#endif + + board_led_write(false); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + +#ifdef UART_DEV + // UART + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle = (UART_HandleTypeDef){ + .Instance = UART_DEV, + .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.OverSampling = UART_OVERSAMPLING_16 + }; + HAL_UART_Init(&UartHandle); +#endif + + // USB Pins TODO double check USB clock and pin setup + // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + HAL_PWREx_EnableVddUSB(); + __HAL_RCC_USB_CLK_ENABLE(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ +#ifdef UART_DEV + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +#else + (void) buf; (void) len; (void) UartHandle; + return 0; +#endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.mk b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.mk new file mode 100644 index 0000000..f85c5ba --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/family.mk @@ -0,0 +1,44 @@ +UF2_FAMILY_ID = 0x70d16653 +ST_FAMILY = wb +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32WB + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=cast-align -Wno-unused-parameter + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# flash target using on-board stlink +flash: flash-stlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/stm32wb/stm32wbxx_hal_conf.h b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/stm32wbxx_hal_conf.h new file mode 100644 index 0000000..754c94e --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/stm32wb/stm32wbxx_hal_conf.h @@ -0,0 +1,349 @@ +/** + ****************************************************************************** + * @file stm32wbxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32WBxx_HAL_CONF_H +#define __STM32WBxx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_HSEM_MODULE_ENABLED */ +/*#define HAL_IPCC_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_PKA_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_IWDG_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0u +#define USE_HAL_COMP_REGISTER_CALLBACKS 0u +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u +#define USE_HAL_I2C_REGISTER_CALLBACKS 0u +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u +#define USE_HAL_PCD_REGISTER_CALLBACKS 0u +#define USE_HAL_PKA_REGISTER_CALLBACKS 0u +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0u +#define USE_HAL_RNG_REGISTER_CALLBACKS 0u +#define USE_HAL_RTC_REGISTER_CALLBACKS 0u +#define USE_HAL_SAI_REGISTER_CALLBACKS 0u +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u +#define USE_HAL_SPI_REGISTER_CALLBACKS 0u +#define USE_HAL_TIM_REGISTER_CALLBACKS 0u +#define USE_HAL_TSC_REGISTER_CALLBACKS 0u +#define USE_HAL_UART_REGISTER_CALLBACKS 0u +#define USE_HAL_USART_REGISTER_CALLBACKS 0u +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE 32000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI1) value. + */ +#if !defined (LSI1_VALUE) + #define LSI1_VALUE ((uint32_t)32000) /*!< LSI1 Typical Value in Hz*/ +#endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief Internal Low Speed oscillator (LSI2) value. + */ +#if !defined (LSI2_VALUE) + #define LSI2_VALUE ((uint32_t)32000) /*!< LSI2 Typical Value in Hz*/ +#endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +/** + * @brief Internal Multiple Speed oscillator (HSI48) default value. + * This value is the default HSI48 range value after Reset. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI48_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) + #define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000) /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define DATA_CACHE_ENABLE 1 + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32wbxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32wbxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32wbxx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32wbxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32wbxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32wbxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32wbxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32wbxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_HSEM_MODULE_ENABLED + #include "stm32wbxx_hal_hsem.h" +#endif /* HAL_HSEM_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32wbxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_IPCC_MODULE_ENABLED + #include "stm32wbxx_hal_ipcc.h" +#endif /* HAL_IPCC_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32wbxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32wbxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED + #include "stm32wbxx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32wbxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32wbxx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32wbxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32wbxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U + #include "stm32wbxx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32wbxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32wbxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32wbxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32wbxx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32wbxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32wbxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32wbxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32wbxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32wbxx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32wbxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32wbxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32wbxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32WBxx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.h b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.h new file mode 100644 index 0000000..5732056 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.h @@ -0,0 +1,52 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define BOARD_UART UART0 +#define BOARD_UART_PORT GPIOA + +#define BOARD_BTN_PORT GPIOF +#define BOARD_BTN 4 +#define BOARD_BTN_Msk (1u<<4) +#define BUTTON_STATE_ACTIVE 0 + +#define LED_PORT GPIOF +#define LED_PIN_RED 1 +#define LED_PIN_BLUE 2 +#define LED_PIN_GREEN 3 +#define LED_STATE_ON 1 + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.mk b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.mk new file mode 100644 index 0000000..d60365d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DTM4C123GH6PM + +LD_FILE = $(BOARD_PATH)/tm4c123.ld + +# For flash-jlink target +JLINK_DEVICE = TM4C123GH6PM + +# flash using openocd +OPENOCD_OPTION = -f board/ti_ek-tm4c123gxl.cfg + +flash: flash-openocd diff --git a/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/tm4c123.ld b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/tm4c123.ld new file mode 100644 index 0000000..e2720a9 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/boards/ek-tm4c123gxl/tm4c123.ld @@ -0,0 +1,65 @@ +ENTRY(Reset_Handler) + +_estack = 0x20008000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + + +MEMORY +{ + FLASH(rx) : ORIGIN = 0x00000000, LENGTH = 256K + SRAM(rwx) : ORIGIN = 0x20000000, LENGTH = 32K +} + +SECTIONS +{ + .text : + { + . = ALIGN(4) ; + *(.vectors) + *(.text) + *(.text.*) + *(.init) + *(.fini) + *(.rodata) + *(.rodata.*) + . = ALIGN(4) ; + __end_text = . ; + } >FLASH + + .data : AT(ADDR(.text) + SIZEOF(.text)) + { + . = ALIGN(4); + __start_data = . ; + __la_data = LOADADDR(.data); + *(.data) + *(.data.*) + . = ALIGN(4); + __end_data = . ; + + } >SRAM + + .bss : + { + . = ALIGN(4) ; + __start_bss = . ; + __bss_start__ = __start_bss; + *(.bss) + *(.bss.*) + *(.COMMON) + __end_bss = . ; + . = ALIGN(4); + }>SRAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >SRAM +} diff --git a/circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.c b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.c new file mode 100644 index 0000000..b0947d6 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.c @@ -0,0 +1,178 @@ +#include "TM4C123.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB0_Handler(void) +{ +#if CFG_TUH_ENABLED + tuh_int_handler(0); +#endif + +#if CFG_TUD_ENABLED + tud_int_handler(0); +#endif +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +static void board_uart_init (void) +{ + SYSCTL->RCGCUART |= (1 << 0); // Enable the clock to UART0 + SYSCTL->RCGCGPIO |= (1 << 0); // Enable the clock to GPIOA + + GPIOA->AFSEL |= (1 << 1) | (1 << 0); // Enable the alternate function on pin PA0 & PA1 + GPIOA->PCTL |= (1 << 0) | (1 << 4); // Configure the GPIOPCTL register to select UART0 in PA0 and PA1 + GPIOA->DEN |= (1 << 0) | (1 << 1); // Enable the digital functionality in PA0 and PA1 + + // BAUDRATE = 115200, with SystemCoreClock = 50 Mhz refer manual for calculation + // - BRDI = SystemCoreClock / (16* baud) + // - BRDF = int(fraction*64 + 0.5) + UART0->CTL &= ~(1 << 0); // Disable UART0 by clearing UARTEN bit in the UARTCTL register + UART0->IBRD = 27; // Write the integer portion of the BRD to the UARTIRD register + UART0->FBRD = 8; // Write the fractional portion of the BRD to the UARTFBRD registerer + + UART0->LCRH = (0x3 << 5); // 8-bit, no parity, 1 stop bit + UART0->CC = 0x0; // Configure the UART clock source as system clock + + UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Recieve Enable +} + +static void initialize_board_led (GPIOA_Type *port, uint8_t PinMsk, uint8_t dirmsk) +{ + /* Enable PortF Clock */ + SYSCTL->RCGCGPIO |= (1 << 5); + + /* Let the clock stabilize */ + while ( !((SYSCTL->PRGPIO) & (1 << 5)) ) {} + + /* Port Digital Enable */ + port->DEN |= PinMsk; + + /* Set direction */ + port->DIR = dirmsk; +} + +static void board_switch_init (void) +{ + GPIOF->DIR &= ~(1 << BOARD_BTN); + GPIOF->PUR |= (1 << BOARD_BTN); + GPIOF->DEN |= (1 << BOARD_BTN); +} + +static void WriteGPIOPin (GPIOA_Type *port, uint8_t PinMsk, bool state) +{ + if ( state ) + { + port->DATA |= PinMsk; + } + else + { + port->DATA &= ~(PinMsk); + } +} + +static uint32_t ReadGPIOPin (GPIOA_Type *port, uint8_t pinMsk) +{ + return (port->DATA & pinMsk); +} + +void board_init (void) +{ + SystemCoreClockUpdate(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + /* Reset USB */ + SYSCTL->SRCR2 |= (1u << 16); + + for ( volatile uint8_t i = 0; i < 20; i++ ) {} + + SYSCTL->SRCR2 &= ~(1u << 16); + + /* Open the USB clock gate */ + SYSCTL->RCGCUSB |= (1 << 0); + + /* Power-up USB PLL */ + SYSCTL->RCC2 &= ~(1u << 14); + + /* USB IO Initialization */ + SYSCTL->RCGCGPIO |= (1u << 3); + + /* Let the clock stabilize */ + while ( !(SYSCTL->PRGPIO & (1u << 3)) ) {} + + /* USB IOs to Analog Mode */ + GPIOD->AFSEL &= ~((1u << 4) | (1u << 5)); + GPIOD->DEN &= ~((1u << 4) | (1u << 5)); + GPIOD->AMSEL |= ((1u << 4) | (1u << 5)); + + uint8_t leds = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); + uint8_t dirmsk = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); + + /* Configure GPIO for board LED */ + initialize_board_led(LED_PORT, leds, dirmsk); + + /* Configure GPIO for board switch */ + board_switch_init(); + + /* Initialize board UART */ + board_uart_init(); + + TU_LOG1_INT(SystemCoreClock); +} + +void board_led_write (bool state) +{ + WriteGPIOPin(LED_PORT, (1 << LED_PIN_BLUE), state); +} + +uint32_t board_button_read (void) +{ + uint32_t gpio_value = ReadGPIOPin(BOARD_BTN_PORT, BOARD_BTN_Msk); + return BUTTON_STATE_ACTIVE ? gpio_value : !gpio_value; +} + +int board_uart_write (void const *buf, int len) +{ + uint8_t const * data = buf; + + for ( int i = 0; i < len; i++ ) + { + while ( (UART0->FR & (1 << 5)) != 0 ) {} // Poll until previous data was shofted out + UART0->DR = data[i]; // Write UART0 DATA REGISTER + } + + return len; +} + +int board_uart_read (uint8_t *buf, int len) +{ + (void) buf; + (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis (void) +{ + return system_ticks; +} +#endif + diff --git a/circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.mk b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.mk new file mode 100644 index 0000000..7510761 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/tm4c123/family.mk @@ -0,0 +1,36 @@ +DEPS_SUBMODULES += hw/mcu/ti + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -DCFG_TUSB_MCU=OPT_MCU_TM4C123 \ + -uvectors \ + -DTM4C123GH6PM + +# mcu driver cause following warnings +CFLAGS += -Wno-error=strict-prototypes -Wno-error=cast-qual + +MCU_DIR=hw/mcu/ti/tm4c123xx/ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/tm4c123.ld + +INC += \ + $(TOP)/$(MCU_DIR)/CMSIS/5.7.0/CMSIS/Include \ + $(TOP)/$(MCU_DIR)/Include/TM4C123 \ + $(TOP)/$(BOARD_PATH) + +SRC_C += \ + src/portable/mentor/musb/dcd_musb.c \ + src/portable/mentor/musb/hcd_musb.c \ + $(MCU_DIR)/Source/system_TM4C123.c \ + $(MCU_DIR)/Source/GCC/tm4c123_startup.c + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F diff --git a/circuitpython/lib/tinyusb/hw/bsp/xmc4000/boards/xmc4500_relax/board.h b/circuitpython/lib/tinyusb/hw/bsp/xmc4000/boards/xmc4500_relax/board.h new file mode 100644 index 0000000..3e2cb95 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/xmc4000/boards/xmc4500_relax/board.h @@ -0,0 +1,88 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PIN P1_1 +#define LED_STATE_ON 1 + +#define BUTTON_PIN P1_14 +#define BUTTON_STATE_ACTIVE 0 + +//#define UART_DEV USART6 +//#define UART_CLK_EN __HAL_RCC_USART6_CLK_ENABLE +//#define UART_GPIO_AF GPIO_AF8_USART6 +// +//#define UART_TX_PORT GPIOC +//#define UART_TX_PIN GPIO_PIN_6 +// +//#define UART_RX_PORT GPIOC +//#define UART_RX_PIN GPIO_PIN_7 + +static inline void board_clock_init(void) +{ + /* Clock configuration */ + /* fPLL = 120MHz */ + /* fSYS = 120MHz */ + /* fUSBPLL = 192MHz */ + /* fUSB = 48MHz */ + const XMC_SCU_CLOCK_CONFIG_t clock_config = + { + .syspll_config.p_div = 2, + .syspll_config.n_div = 80, + .syspll_config.k_div = 4, + .syspll_config.mode = XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL, + .syspll_config.clksrc = XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP, + .enable_oschp = true, + .calibration_mode = XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_FACTORY, + .fsys_clksrc = XMC_SCU_CLOCK_SYSCLKSRC_PLL, + .fsys_clkdiv = 1, + .fcpu_clkdiv = 1, + .fccu_clkdiv = 1, + .fperipheral_clkdiv = 1 + }; + + /* Setup settings for USB clock */ + XMC_SCU_CLOCK_Init(&clock_config); + + XMC_SCU_CLOCK_EnableUsbPll(); + XMC_SCU_CLOCK_StartUsbPll(2, 64); + XMC_SCU_CLOCK_SetUsbClockDivider(4); + XMC_SCU_CLOCK_SetUsbClockSource(XMC_SCU_CLOCK_USBCLKSRC_USBPLL); + XMC_SCU_CLOCK_EnableClock(XMC_SCU_CLOCK_USB); +} + + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk b/circuitpython/lib/tinyusb/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk new file mode 100644 index 0000000..a2c2c5a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk @@ -0,0 +1,9 @@ +MCU_VARIANT = XMC4500 +CFLAGS += \ + -DXMC4500_F100x1024 \ + +LD_FILE = $(MCU_DIR)/CMSIS/Infineon/COMPONENT_$(MCU_VARIANT)/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld + +JLINK_DEVICE = XMC4500-1024 + +flash: flash-jlink diff --git a/circuitpython/lib/tinyusb/hw/bsp/xmc4000/family.c b/circuitpython/lib/tinyusb/hw/bsp/xmc4000/family.c new file mode 100644 index 0000000..bf66847 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/bsp/xmc4000/family.c @@ -0,0 +1,130 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "xmc_gpio.h" +#include "xmc_scu.h" + +#include "bsp/board.h" +#include "board.h" + + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB0_0_IRQHandler(void) +{ + tud_int_handler(0); +} + +void board_init(void) +{ + board_clock_init(); + SystemCoreClockUpdate(); + + // LED + XMC_GPIO_CONFIG_t led_cfg; + led_cfg.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL; + led_cfg.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH; + led_cfg.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM; + XMC_GPIO_Init(LED_PIN, &led_cfg); + + // Button + XMC_GPIO_CONFIG_t button_cfg; + button_cfg.mode = XMC_GPIO_MODE_INPUT_TRISTATE; + XMC_GPIO_Init(BUTTON_PIN, &button_cfg); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB0_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + // USB Power Enable + XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USB0); + XMC_SCU_POWER_EnableUsb(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + uint32_t is_high = state ? LED_STATE_ON : (1-LED_STATE_ON); + + XMC_GPIO_SetOutputLevel(LED_PIN, is_high ? XMC_GPIO_OUTPUT_LEVEL_HIGH : XMC_GPIO_OUTPUT_LEVEL_LOW); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == XMC_GPIO_GetInput(BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ +#ifdef UART_DEV + for(int i=0;i flash + .tors : + { + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + . = ALIGN(4); + } > ram + .data : AT (ADDR (.text) + SIZEOF (.text)) + { + *(.data) + *(.data*) + *(.rodata) + *(.rodata*) + _edata = . ; + . = ALIGN(4); + } > ram + .bss SIZEOF(.data) + ADDR(.data) : + { + _bss_start = . ; + *(.bss) + *(.bss*) + *(COMMON) + _end = . ; + . = ALIGN(4); + } > ram + __data_load_start = LOADADDR(.data); + __data_load_end = __data_load_start + SIZEOF(.data); + .stab 0 (NOLOAD) : + { + *(.stab) + } + .stabstr 0 (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } +} diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/README.md b/circuitpython/lib/tinyusb/hw/mcu/dialog/README.md new file mode 100644 index 0000000..69676f0 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/README.md @@ -0,0 +1,9 @@ +# Dialog DA1469x MCU + +**Dialog Semiconductors** provides SDKs for DA146x MCU family. +Most of the files there can't be redistributed. +Registers definition file `DA1469xAB.h` and some **ARM** originated headers are have licenses that allow +for redistribution. +Whole SDK repository can be downloaded from Dialog Semiconductor web page `https://www.dialog.com` + + diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/arm_license.txt b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/arm_license.txt new file mode 100644 index 0000000..b324eb2 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/arm_license.txt @@ -0,0 +1,27 @@ +/* Copyright (c) 2009 - 2013 ARM LIMITED + + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/DA1469xAB.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/DA1469xAB.h new file mode 100644 index 0000000..fa2ca5d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/DA1469xAB.h @@ -0,0 +1,8657 @@ +/* + * Copyright (C) 2019 Dialog Semiconductor. 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 Dialog Semiconductor 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 COPYRIGHT HOLDERS AND 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. + * + * @file DA1469xAB.h + * @brief CMSIS HeaderFile + * @version 1.2 + * @date 22. April 2019 + * @note Generated by SVDConv V3.3.25 on Monday, 22.04.2019 11:06:30 + * from File 'DA1469xAB.xml', + */ + + + +/** @addtogroup PLA_BSP_REGISTERS + * @{ + */ + + +/** @addtogroup DA1469x + * @{ + */ + + +#ifndef DA1469X_H +#define DA1469X_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + +/* =========================================================================================================================== */ +/* ================ Interrupt Number Definition ================ */ +/* =========================================================================================================================== */ + +/** + * @brief Interrupt Number Definition + */ + +typedef enum { +/* ======================================= ARM Cortex-M33 Specific Interrupt Numbers ======================================= */ + Reset_IRQn = -15, /*!< -15 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< -14 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< -13 Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /*!< -12 Memory Management, MPU mismatch, including Access Violation + and No Match */ + BusFault_IRQn = -11, /*!< -11 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory + related Fault */ + UsageFault_IRQn = -10, /*!< -10 Usage Fault, i.e. Undef Instruction, Illegal State Transition */ + SecureFault_IRQn = -9, /*!< -9 Secure Fault Handler */ + SVCall_IRQn = -5, /*!< -5 System Service Call via SVC instruction */ + DebugMonitor_IRQn = -4, /*!< -4 Debug Monitor */ + PendSV_IRQn = -2, /*!< -2 Pendable request for system service */ + SysTick_IRQn = -1, /*!< -1 System Tick Timer */ +/* ========================================== DA1469x Specific Interrupt Numbers =========================================== */ + SNC_IRQn = 0, /*!< 0 Sensor Node Controller interrupt request. */ + DMA_IRQn = 1, /*!< 1 General Purpose DMA interrupt request. */ + CHARGER_STATE_IRQn = 2, /*!< 2 Charger State interrupt request. */ + CHARGER_ERROR_IRQn = 3, /*!< 3 Charger Error interrupt request. */ + CMAC2SYS_IRQn = 4, /*!< 4 CMAC and mailbox interrupt request. */ + UART_IRQn = 5, /*!< 5 UART interrupt request. */ + UART2_IRQn = 6, /*!< 6 UART2 interrupt request. */ + UART3_IRQn = 7, /*!< 7 UART3 interrupt request. */ + I2C_IRQn = 8, /*!< 8 I2C interrupt request. */ + I2C2_IRQn = 9, /*!< 9 I2C2 interrupt request. */ + SPI_IRQn = 10, /*!< 10 SPI interrupt request. */ + SPI2_IRQn = 11, /*!< 11 SPI2 interrupt request. */ + PCM_IRQn = 12, /*!< 12 PCM interrupt request. */ + SRC_IN_IRQn = 13, /*!< 13 SRC input interrupt request. */ + SRC_OUT_IRQn = 14, /*!< 14 SRC output interrupt request. */ + USB_IRQn = 15, /*!< 15 USB interrupt request. */ + TIMER_IRQn = 16, /*!< 16 TIMER interrupt request. */ + TIMER2_IRQn = 17, /*!< 17 TIMER2 interrupt request. */ + RTC_IRQn = 18, /*!< 18 RTC interrupt request. */ + KEY_WKUP_GPIO_IRQn = 19, /*!< 19 Debounced button press interrupt request. */ + PDC_IRQn = 20, /*!< 20 Wakeup IRQ from PDC to CM33 */ + VBUS_IRQn = 21, /*!< 21 VBUS presence interrupt request. */ + MRM_IRQn = 22, /*!< 22 Cache Miss Rate Monitor interrupt request. */ + MOTOR_CONTROLLER_IRQn = 23, /*!< 23 MOTOR and mailbox interrupt request. */ + TRNG_IRQn = 24, /*!< 24 True Random Number Generation interrupt request. */ + DCDC_IRQn = 25, /*!< 25 DCDC interrupt request. */ + XTAL32M_RDY_IRQn = 26, /*!< 26 XTAL32M trimmed and ready interrupt request. */ + GPADC_IRQn = 27, /*!< 27 General Purpose Analog-Digital Converter interrupt request. */ + SDADC_IRQn = 28, /*!< 28 Sigma Delta Analog-Digital Converter interrupt request. */ + CRYPTO_IRQn = 29, /*!< 29 Crypto interrupt request. */ + CAPTIMER_IRQn = 30, /*!< 30 GPIO triggered Timer Capture interrupt request. */ + RFDIAG_IRQn = 31, /*!< 31 Baseband or Radio Diagnostics interrupt request. */ + LCD_CONTROLLER_IRQn = 32, /*!< 32 Parallel LCD Controller interrupt request. */ + PLL_LOCK_IRQn = 33, /*!< 33 Pll lock interrupt request. */ + TIMER3_IRQn = 34, /*!< 34 TIMER3 interrupt request. */ + TIMER4_IRQn = 35, /*!< 35 TIMER4 interrupt request. */ + LRA_IRQn = 36, /*!< 36 LRA/ERM interrupt request. */ + RTC_EVENT_IRQn = 37, /*!< 37 RTC event interrupt request. */ + GPIO_P0_IRQn = 38, /*!< 38 GPIO port 0 toggle interrupt request. */ + GPIO_P1_IRQn = 39 /*!< 39 GPIO port 1 toggle interrupt request. */ +} IRQn_Type; + + + +/* =========================================================================================================================== */ +/* ================ Processor and Core Peripheral Section ================ */ +/* =========================================================================================================================== */ + +/* ========================== Configuration of the ARM Cortex-M33 Processor and Core Peripherals =========================== */ +#define __CM33_REV 0x0000U /*!< CM33 Core Revision */ +#define __NVIC_PRIO_BITS 4 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __VTOR_PRESENT 1 /*!< Set to 1 if CPU supports Vector Table Offset Register */ +#define __MPU_PRESENT 1 /*!< MPU present */ +#define __FPU_PRESENT 1 /*!< FPU present */ +#define __FPU_DP 0 /*!< Double Precision FPU */ +#define __DSP_PRESENT 1 /*!< DSP extension present */ +#define __SAU_REGION_PRESENT 0 /*!< SAU present */ + + +/** @} */ /* End of group Configuration_of_CMSIS */ + +#include "core_cm33.h" /*!< ARM Cortex-M33 processor and core peripherals */ +#include "system_DA1469x.h" /*!< DA1469x System */ + +#ifndef __IM /*!< Fallback for older CMSIS versions */ + #define __IM __I +#endif +#ifndef __OM /*!< Fallback for older CMSIS versions */ + #define __OM __O +#endif +#ifndef __IOM /*!< Fallback for older CMSIS versions */ + #define __IOM __IO +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ AES_HASH ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief AES_HASH registers (AES_HASH) + */ + +typedef struct { /*!< (@ 0x30040000) AES_HASH Structure */ + __IOM uint32_t CRYPTO_CTRL_REG; /*!< (@ 0x00000000) Crypto Control register */ + __IOM uint32_t CRYPTO_START_REG; /*!< (@ 0x00000004) Crypto Start calculation */ + __IOM uint32_t CRYPTO_FETCH_ADDR_REG; /*!< (@ 0x00000008) Crypto DMA fetch register */ + __IOM uint32_t CRYPTO_LEN_REG; /*!< (@ 0x0000000C) Crypto Length of the input block in bytes */ + __IOM uint32_t CRYPTO_DEST_ADDR_REG; /*!< (@ 0x00000010) Crypto DMA destination memory */ + __IOM uint32_t CRYPTO_STATUS_REG; /*!< (@ 0x00000014) Crypto Status register */ + __IOM uint32_t CRYPTO_CLRIRQ_REG; /*!< (@ 0x00000018) Crypto Clear interrupt request */ + __IOM uint32_t CRYPTO_MREG0_REG; /*!< (@ 0x0000001C) Crypto Mode depended register 0 */ + __IOM uint32_t CRYPTO_MREG1_REG; /*!< (@ 0x00000020) Crypto Mode depended register 1 */ + __IOM uint32_t CRYPTO_MREG2_REG; /*!< (@ 0x00000024) Crypto Mode depended register 2 */ + __IOM uint32_t CRYPTO_MREG3_REG; /*!< (@ 0x00000028) Crypto Mode depended register 3 */ + __IM uint32_t RESERVED[53]; + __IOM uint32_t CRYPTO_KEYS_START; /*!< (@ 0x00000100) Crypto First position of the AES keys storage + memory */ +} AES_HASH_Type; /*!< Size = 260 (0x104) */ + + + +/* =========================================================================================================================== */ +/* ================ ANAMISC_BIF ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief ANAMISC_BIF registers (ANAMISC_BIF) + */ + +typedef struct { /*!< (@ 0x50030B00) ANAMISC_BIF Structure */ + __IM uint32_t RESERVED[4]; + __IOM uint32_t CLK_REF_SEL_REG; /*!< (@ 0x00000010) Select clock for oscillator calibration */ + __IOM uint32_t CLK_REF_CNT_REG; /*!< (@ 0x00000014) Count value for oscillator calibration */ + __IOM uint32_t CLK_REF_VAL_REG; /*!< (@ 0x00000018) DIVN reference cycles, lower 16 bits */ +} ANAMISC_BIF_Type; /*!< Size = 28 (0x1c) */ + + + +/* =========================================================================================================================== */ +/* ================ APU ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief APU registers (APU) + */ + +typedef struct { /*!< (@ 0x50030600) APU Structure */ + __IOM uint32_t SRC1_CTRL_REG; /*!< (@ 0x00000000) SRC1 control register */ + __IOM uint32_t SRC1_IN_FS_REG; /*!< (@ 0x00000004) SRC1 Sample input rate */ + __IOM uint32_t SRC1_OUT_FS_REG; /*!< (@ 0x00000008) SRC1 Sample output rate */ + __IOM uint32_t SRC1_IN1_REG; /*!< (@ 0x0000000C) SRC1 data in 1 */ + __IOM uint32_t SRC1_IN2_REG; /*!< (@ 0x00000010) SRC1 data in 2 */ + __IOM uint32_t SRC1_OUT1_REG; /*!< (@ 0x00000014) SRC1 data out 1 */ + __IOM uint32_t SRC1_OUT2_REG; /*!< (@ 0x00000018) SRC1 data out 2 */ + __IOM uint32_t APU_MUX_REG; /*!< (@ 0x0000001C) APU mux register */ + __IOM uint32_t COEF10_SET1_REG; /*!< (@ 0x00000020) SRC coefficient 1,0 set 1 */ + __IOM uint32_t COEF32_SET1_REG; /*!< (@ 0x00000024) SRC coefficient 3,2 set 1 */ + __IOM uint32_t COEF54_SET1_REG; /*!< (@ 0x00000028) SRC coefficient 5,4 set 1 */ + __IOM uint32_t COEF76_SET1_REG; /*!< (@ 0x0000002C) SRC coefficient 7,6 set 1 */ + __IOM uint32_t COEF98_SET1_REG; /*!< (@ 0x00000030) SRC coefficient 9,8 set 1 */ + __IOM uint32_t COEF0A_SET1_REG; /*!< (@ 0x00000034) SRC coefficient 10 set 1 */ + __IM uint32_t RESERVED[50]; + __IOM uint32_t PCM1_CTRL_REG; /*!< (@ 0x00000100) PCM1 Control register */ + __IOM uint32_t PCM1_IN1_REG; /*!< (@ 0x00000104) PCM1 data in 1 */ + __IOM uint32_t PCM1_IN2_REG; /*!< (@ 0x00000108) PCM1 data in 2 */ + __IOM uint32_t PCM1_OUT1_REG; /*!< (@ 0x0000010C) PCM1 data out 1 */ + __IOM uint32_t PCM1_OUT2_REG; /*!< (@ 0x00000110) PCM1 data out 2 */ +} APU_Type; /*!< Size = 276 (0x114) */ + + + +/* =========================================================================================================================== */ +/* ================ CACHE ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief CACHE registers (CACHE) + */ + +typedef struct { /*!< (@ 0x100C0000) CACHE Structure */ + __IOM uint32_t CACHE_CTRL1_REG; /*!< (@ 0x00000000) Cache control register 1 */ + __IOM uint32_t CACHE_LNSIZECFG_REG; /*!< (@ 0x00000004) Cache line size configuration register */ + __IOM uint32_t CACHE_ASSOCCFG_REG; /*!< (@ 0x00000008) Cache associativity configuration register */ + __IM uint32_t RESERVED[5]; + __IOM uint32_t CACHE_CTRL2_REG; /*!< (@ 0x00000020) Cache control register 2 */ + __IM uint32_t RESERVED1; + __IOM uint32_t CACHE_MRM_HITS_REG; /*!< (@ 0x00000028) Cache MRM (Miss Rate Monitor) HITS register */ + __IOM uint32_t CACHE_MRM_MISSES_REG; /*!< (@ 0x0000002C) Cache MRM (Miss Rate Monitor) MISSES register */ + __IOM uint32_t CACHE_MRM_CTRL_REG; /*!< (@ 0x00000030) Cache MRM (Miss Rate Monitor) CONTROL register */ + __IOM uint32_t CACHE_MRM_TINT_REG; /*!< (@ 0x00000034) Cache MRM (Miss Rate Monitor) TIME INTERVAL register */ + __IOM uint32_t CACHE_MRM_MISSES_THRES_REG; /*!< (@ 0x00000038) Cache MRM (Miss Rate Monitor) THRESHOLD register */ + __IOM uint32_t CACHE_MRM_HITS_THRES_REG; /*!< (@ 0x0000003C) Cache MRM (Miss Rate Monitor) HITS THRESHOLD + register */ + __IOM uint32_t CACHE_FLASH_REG; /*!< (@ 0x00000040) Cache Flash program size and base address register */ + __IM uint32_t RESERVED2[3]; + __IOM uint32_t SWD_RESET_REG; /*!< (@ 0x00000050) SWD HW reset control register */ +} CACHE_Type; /*!< Size = 84 (0x54) */ + + + +/* =========================================================================================================================== */ +/* ================ CHARGER ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief CHARGER registers (CHARGER) + */ + +typedef struct { /*!< (@ 0x50040400) CHARGER Structure */ + __IOM uint32_t CHARGER_CTRL_REG; /*!< (@ 0x00000000) Charger main control register */ + __IOM uint32_t CHARGER_TEST_CTRL_REG; /*!< (@ 0x00000004) Charger test control register */ + __IOM uint32_t CHARGER_STATUS_REG; /*!< (@ 0x00000008) Charger main status register */ + __IOM uint32_t CHARGER_VOLTAGE_PARAM_REG; /*!< (@ 0x0000000C) Charger voltage settings register */ + __IOM uint32_t CHARGER_CURRENT_PARAM_REG; /*!< (@ 0x00000010) Charger current settings register */ + __IOM uint32_t CHARGER_TEMPSET_PARAM_REG; /*!< (@ 0x00000014) Charger battery temperature settings register */ + __IOM uint32_t CHARGER_PRE_CHARGE_TIMER_REG; /*!< (@ 0x00000018) Maximum pre-charge time limit register */ + __IOM uint32_t CHARGER_CC_CHARGE_TIMER_REG; /*!< (@ 0x0000001C) Maximum CC-charge time limit register */ + __IOM uint32_t CHARGER_CV_CHARGE_TIMER_REG; /*!< (@ 0x00000020) Maximum CV-charge time limit register */ + __IOM uint32_t CHARGER_TOTAL_CHARGE_TIMER_REG;/*!< (@ 0x00000024) Maximum total charge time limit register */ + __IOM uint32_t CHARGER_JEITA_V_CHARGE_REG; /*!< (@ 0x00000028) JEITA-compliant Charge voltage settings register */ + __IOM uint32_t CHARGER_JEITA_V_PRECHARGE_REG;/*!< (@ 0x0000002C) JEITA-compliant Pre-Charge voltage settings register */ + __IOM uint32_t CHARGER_JEITA_V_REPLENISH_REG;/*!< (@ 0x00000030) JEITA-compliant Replenish settings register */ + __IOM uint32_t CHARGER_JEITA_V_OVP_REG; /*!< (@ 0x00000034) JEITA-compliant OVP settings register */ + __IOM uint32_t CHARGER_JEITA_CURRENT_REG; /*!< (@ 0x00000038) JEITA-compliant current settings register */ + __IOM uint32_t CHARGER_VBAT_COMP_TIMER_REG; /*!< (@ 0x0000003C) Main Vbat comparator timer register */ + __IOM uint32_t CHARGER_VOVP_COMP_TIMER_REG; /*!< (@ 0x00000040) Vbat OVP comparator timer register */ + __IOM uint32_t CHARGER_TDIE_COMP_TIMER_REG; /*!< (@ 0x00000044) Die temperature comparator timer register */ + __IOM uint32_t CHARGER_TBAT_MON_TIMER_REG; /*!< (@ 0x00000048) Battery temperature monitor interval timer */ + __IOM uint32_t CHARGER_TBAT_COMP_TIMER_REG; /*!< (@ 0x0000004C) Battery temperature (main) comparator timer */ + __IOM uint32_t CHARGER_THOT_COMP_TIMER_REG; /*!< (@ 0x00000050) Battery temperature comparator timer for 'Hot' + zone */ + __IOM uint32_t CHARGER_PWR_UP_TIMER_REG; /*!< (@ 0x00000054) Charger power-up (settling) timer */ + __IOM uint32_t CHARGER_STATE_IRQ_MASK_REG; /*!< (@ 0x00000058) Mask register of Charger FSM IRQs */ + __IOM uint32_t CHARGER_ERROR_IRQ_MASK_REG; /*!< (@ 0x0000005C) Mask register of Charger Error IRQs */ + __IOM uint32_t CHARGER_STATE_IRQ_STATUS_REG; /*!< (@ 0x00000060) Status register of Charger FSM IRQs */ + __IOM uint32_t CHARGER_ERROR_IRQ_STATUS_REG; /*!< (@ 0x00000064) Status register of Charger Error IRQs */ + __IOM uint32_t CHARGER_STATE_IRQ_CLR_REG; /*!< (@ 0x00000068) Interrupt clear register of Charger FSM IRQs */ + __IOM uint32_t CHARGER_ERROR_IRQ_CLR_REG; /*!< (@ 0x0000006C) Interrupt clear register of Charger Error IRQs */ +} CHARGER_Type; /*!< Size = 112 (0x70) */ + + + +/* =========================================================================================================================== */ +/* ================ CHIP_VERSION ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief CHIP_VERSION registers (CHIP_VERSION) + */ + +typedef struct { /*!< (@ 0x50040200) CHIP_VERSION Structure */ + __IOM uint32_t CHIP_ID1_REG; /*!< (@ 0x00000000) Chip identification register 1. */ + __IOM uint32_t CHIP_ID2_REG; /*!< (@ 0x00000004) Chip identification register 2. */ + __IOM uint32_t CHIP_ID3_REG; /*!< (@ 0x00000008) Chip identification register 3. */ + __IOM uint32_t CHIP_ID4_REG; /*!< (@ 0x0000000C) Chip identification register 4. */ + __IOM uint32_t CHIP_SWC_REG; /*!< (@ 0x00000010) Software compatibility register. */ + __IOM uint32_t CHIP_REVISION_REG; /*!< (@ 0x00000014) Chip revision register. */ + __IM uint32_t RESERVED[56]; + __IOM uint32_t CHIP_TEST1_REG; /*!< (@ 0x000000F8) Chip test register 1. */ + __IOM uint32_t CHIP_TEST2_REG; /*!< (@ 0x000000FC) Chip test register 2. */ +} CHIP_VERSION_Type; /*!< Size = 256 (0x100) */ + + + +/* =========================================================================================================================== */ +/* ================ CRG_COM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief CRG_COM registers (CRG_COM) + */ + +typedef struct { /*!< (@ 0x50020900) CRG_COM Structure */ + __IM uint32_t RESERVED; + __IOM uint32_t CLK_COM_REG; /*!< (@ 0x00000004) Peripheral divider register */ + __IOM uint32_t SET_CLK_COM_REG; /*!< (@ 0x00000008) Peripheral divider register SET register. Reads + back 0x0000 */ + __IOM uint32_t RESET_CLK_COM_REG; /*!< (@ 0x0000000C) Peripheral divider register RESET register. Reads + back 0x0000 */ +} CRG_COM_Type; /*!< Size = 16 (0x10) */ + + + +/* =========================================================================================================================== */ +/* ================ CRG_PER ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief CRG_PER registers (CRG_PER) + */ + +typedef struct { /*!< (@ 0x50030C00) CRG_PER Structure */ + __IM uint32_t RESERVED; + __IOM uint32_t CLK_PER_REG; /*!< (@ 0x00000004) Peripheral divider register */ + __IOM uint32_t SET_CLK_PER_REG; /*!< (@ 0x00000008) Peripheral divider register SET register, reads + 0x0000 */ + __IOM uint32_t RESET_CLK_PER_REG; /*!< (@ 0x0000000C) Peripheral divider register RESET register, reads + 0x0000 */ + __IM uint32_t RESERVED1[12]; + __IOM uint32_t PCM_DIV_REG; /*!< (@ 0x00000040) PCM divider and enables */ + __IOM uint32_t PCM_FDIV_REG; /*!< (@ 0x00000044) PCM fractional division register */ + __IOM uint32_t PDM_DIV_REG; /*!< (@ 0x00000048) PDM divider and enables */ + __IOM uint32_t SRC_DIV_REG; /*!< (@ 0x0000004C) SRC divider and enables */ +} CRG_PER_Type; /*!< Size = 80 (0x50) */ + + + +/* =========================================================================================================================== */ +/* ================ CRG_SYS ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief CRG_SYS registers (CRG_SYS) + */ + +typedef struct { /*!< (@ 0x50040500) CRG_SYS Structure */ + __IOM uint32_t CLK_SYS_REG; /*!< (@ 0x00000000) Peripheral divider register */ + __IOM uint32_t BATCHECK_REG; /*!< (@ 0x00000004) BATCHECK_REG */ +} CRG_SYS_Type; /*!< Size = 8 (0x8) */ + + + +/* =========================================================================================================================== */ +/* ================ CRG_TOP ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief CRG_TOP registers (CRG_TOP) + */ + +typedef struct { /*!< (@ 0x50000000) CRG_TOP Structure */ + __IOM uint32_t CLK_AMBA_REG; /*!< (@ 0x00000000) HCLK, PCLK, divider and clock gates */ + __IM uint32_t RESERVED[3]; + __IOM uint32_t CLK_RADIO_REG; /*!< (@ 0x00000010) Radio PLL control register */ + __IOM uint32_t CLK_CTRL_REG; /*!< (@ 0x00000014) Clock control register */ + __IOM uint32_t CLK_TMR_REG; /*!< (@ 0x00000018) Clock control for the timers */ + __IOM uint32_t CLK_SWITCH2XTAL_REG; /*!< (@ 0x0000001C) Switches clock from RC32M to XTAL32M */ + __IOM uint32_t PMU_CTRL_REG; /*!< (@ 0x00000020) Power Management Unit control register */ + __IOM uint32_t SYS_CTRL_REG; /*!< (@ 0x00000024) System Control register */ + __IOM uint32_t SYS_STAT_REG; /*!< (@ 0x00000028) System status register */ + __IM uint32_t RESERVED1[4]; + __IOM uint32_t CLK_RC32K_REG; /*!< (@ 0x0000003C) 32 kHz RC oscillator register */ + __IOM uint32_t CLK_XTAL32K_REG; /*!< (@ 0x00000040) 32 kHz XTAL oscillator register */ + __IOM uint32_t CLK_RC32M_REG; /*!< (@ 0x00000044) Fast RC control register */ + __IOM uint32_t CLK_RCX_REG; /*!< (@ 0x00000048) RCX-oscillator control register */ + __IOM uint32_t CLK_RTCDIV_REG; /*!< (@ 0x0000004C) Divisor for RTC 100Hz clock */ + __IOM uint32_t BANDGAP_REG; /*!< (@ 0x00000050) bandgap trimming */ + __IOM uint32_t VBUS_IRQ_MASK_REG; /*!< (@ 0x00000054) IRQ masking */ + __IOM uint32_t VBUS_IRQ_CLEAR_REG; /*!< (@ 0x00000058) Clear pending IRQ register */ + __IM uint32_t RESERVED2; + __IOM uint32_t BOD_CTRL_REG; /*!< (@ 0x00000060) Brown Out Detection control register */ + __IOM uint32_t BOD_LVL_CTRL0_REG; /*!< (@ 0x00000064) BOD_LVL_CTRL0_REG */ + __IOM uint32_t BOD_LVL_CTRL1_REG; /*!< (@ 0x00000068) BOD_LVL_CTRL1_REG */ + __IOM uint32_t BOD_LVL_CTRL2_REG; /*!< (@ 0x0000006C) BOD_LVL_CTRL2_REG */ + __IOM uint32_t P0_PAD_LATCH_REG; /*!< (@ 0x00000070) Control the state retention of the GPIO ports */ + __IOM uint32_t P0_SET_PAD_LATCH_REG; /*!< (@ 0x00000074) Control the state retention of the GPIO ports */ + __IOM uint32_t P0_RESET_PAD_LATCH_REG; /*!< (@ 0x00000078) Control the state retention of the GPIO ports */ + __IOM uint32_t P1_PAD_LATCH_REG; /*!< (@ 0x0000007C) Control the state retention of the GPIO ports */ + __IOM uint32_t P1_SET_PAD_LATCH_REG; /*!< (@ 0x00000080) Control the state retention of the GPIO ports */ + __IOM uint32_t P1_RESET_PAD_LATCH_REG; /*!< (@ 0x00000084) Control the state retention of the GPIO ports */ + __IM uint32_t RESERVED3[2]; + __IOM uint32_t BOD_STATUS_REG; /*!< (@ 0x00000090) BOD_STATUS_REG */ + __IOM uint32_t POR_VBAT_CTRL_REG; /*!< (@ 0x00000094) Controls the POR on VBAT */ + __IOM uint32_t POR_PIN_REG; /*!< (@ 0x00000098) Selects a GPIO pin for POR generation */ + __IOM uint32_t POR_TIMER_REG; /*!< (@ 0x0000009C) Time for POR to happen */ + __IOM uint32_t LDO_VDDD_HIGH_CTRL_REG; /*!< (@ 0x000000A0) LDO control register */ + __IOM uint32_t BIAS_VREF_SEL_REG; /*!< (@ 0x000000A4) BIAS_VREF_SEL_REG */ + __IM uint32_t RESERVED4[5]; + __IOM uint32_t RESET_STAT_REG; /*!< (@ 0x000000BC) Reset status register */ + __IOM uint32_t RAM_PWR_CTRL_REG; /*!< (@ 0x000000C0) Control power state of System RAMS */ + __IM uint32_t RESERVED5[2]; + __IOM uint32_t SECURE_BOOT_REG; /*!< (@ 0x000000CC) Controls secure booting */ + __IM uint32_t RESERVED6; + __IOM uint32_t DISCHARGE_RAIL_REG; /*!< (@ 0x000000D4) Immediate rail resetting. There is no LDO/DCDC + gating */ + __IM uint32_t RESERVED7[5]; + __IOM uint32_t ANA_STATUS_REG; /*!< (@ 0x000000EC) Analog Signals Status Register */ + __IOM uint32_t POWER_CTRL_REG; /*!< (@ 0x000000F0) Power control register */ + __IOM uint32_t PMU_SLEEP_REG; /*!< (@ 0x000000F4) Configures the sleep/wakeup strategy */ + __IOM uint32_t PMU_TRIM_REG; /*!< (@ 0x000000F8) LDO trimming register */ +} CRG_TOP_Type; /*!< Size = 252 (0xfc) */ + + + +/* =========================================================================================================================== */ +/* ================ CRG_XTAL ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief CRG_XTAL registers (CRG_XTAL) + */ + +typedef struct { /*!< (@ 0x50010000) CRG_XTAL Structure */ + __IOM uint32_t CLK_FREQ_TRIM_REG; /*!< (@ 0x00000000) Xtal frequency trimming register. */ + __IM uint32_t RESERVED[3]; + __IOM uint32_t TRIM_CTRL_REG; /*!< (@ 0x00000010) Control trimming of the XTAL32M */ + __IM uint32_t RESERVED1; + __IOM uint32_t XTALRDY_CTRL_REG; /*!< (@ 0x00000018) Control register for XTALRDY IRQ */ + __IOM uint32_t XTALRDY_STAT_REG; /*!< (@ 0x0000001C) Difference between XTAL_OK and XTALRDY_IRQ in + LP clock cycles */ + __IM uint32_t RESERVED2[4]; + __IOM uint32_t XTAL32M_CTRL0_REG; /*!< (@ 0x00000030) Control register for XTAL32M */ + __IOM uint32_t XTAL32M_CTRL1_REG; /*!< (@ 0x00000034) Control register for XTAL32M */ + __IOM uint32_t XTAL32M_CTRL2_REG; /*!< (@ 0x00000038) Control register for XTAL32M */ + __IOM uint32_t XTAL32M_CTRL3_REG; /*!< (@ 0x0000003C) Control register for XTAL32M */ + __IOM uint32_t XTAL32M_CTRL4_REG; /*!< (@ 0x00000040) Control register for XTAL32M */ + __IM uint32_t RESERVED3[3]; + __IOM uint32_t XTAL32M_STAT0_REG; /*!< (@ 0x00000050) Status register for XTAL32M */ + __IOM uint32_t XTAL32M_STAT1_REG; /*!< (@ 0x00000054) Status register for XTAL32M */ + __IM uint32_t RESERVED4[2]; + __IOM uint32_t PLL_SYS_CTRL1_REG; /*!< (@ 0x00000060) System PLL control register 1. */ + __IOM uint32_t PLL_SYS_CTRL2_REG; /*!< (@ 0x00000064) System PLL control register 2. */ + __IOM uint32_t PLL_SYS_CTRL3_REG; /*!< (@ 0x00000068) System PLL control register 3. */ + __IM uint32_t RESERVED5; + __IOM uint32_t PLL_SYS_STATUS_REG; /*!< (@ 0x00000070) System PLL status register. */ +} CRG_XTAL_Type; /*!< Size = 116 (0x74) */ + + + +/* =========================================================================================================================== */ +/* ================ DCDC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DCDC registers (DCDC) + */ + +typedef struct { /*!< (@ 0x50000300) DCDC Structure */ + __IM uint32_t RESERVED; + __IOM uint32_t DCDC_CTRL1_REG; /*!< (@ 0x00000004) DCDC First Control Register */ + __IOM uint32_t DCDC_CTRL2_REG; /*!< (@ 0x00000008) DCDC Second Control Register */ + __IOM uint32_t DCDC_V14_REG; /*!< (@ 0x0000000C) DCDC V14 Control Register */ + __IOM uint32_t DCDC_VDD_REG; /*!< (@ 0x00000010) DCDC VDD Control Register */ + __IOM uint32_t DCDC_V18_REG; /*!< (@ 0x00000014) DCDC V18 Control Register */ + __IOM uint32_t DCDC_V18P_REG; /*!< (@ 0x00000018) DCDC V18P Control Register */ + __IM uint32_t RESERVED1; + __IOM uint32_t DCDC_STATUS1_REG; /*!< (@ 0x00000020) DCDC First Status Register */ + __IM uint32_t RESERVED2[3]; + __IOM uint32_t DCDC_IRQ_STATUS_REG; /*!< (@ 0x00000030) DCDC Interrupt Status Register */ + __IOM uint32_t DCDC_IRQ_CLEAR_REG; /*!< (@ 0x00000034) DCDC Interrupt Clear Register */ + __IOM uint32_t DCDC_IRQ_MASK_REG; /*!< (@ 0x00000038) DCDC Interrupt Mask Register */ +} DCDC_Type; /*!< Size = 60 (0x3c) */ + + + +/* =========================================================================================================================== */ +/* ================ DMA ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DMA registers (DMA) + */ + +typedef struct { /*!< (@ 0x50040800) DMA Structure */ + __IOM uint32_t DMA0_A_START_REG; /*!< (@ 0x00000000) Start address A of DMA channel 0 */ + __IOM uint32_t DMA0_B_START_REG; /*!< (@ 0x00000004) Start address B of DMA channel 0 */ + __IOM uint32_t DMA0_INT_REG; /*!< (@ 0x00000008) DMA receive interrupt register channel 0 */ + __IOM uint32_t DMA0_LEN_REG; /*!< (@ 0x0000000C) DMA receive length register channel 0 */ + __IOM uint32_t DMA0_CTRL_REG; /*!< (@ 0x00000010) Control register for the DMA channel 0 */ + __IOM uint32_t DMA0_IDX_REG; /*!< (@ 0x00000014) Index value of DMA channel 0 */ + __IM uint32_t RESERVED[2]; + __IOM uint32_t DMA1_A_START_REG; /*!< (@ 0x00000020) Start address A of DMA channel 1 */ + __IOM uint32_t DMA1_B_START_REG; /*!< (@ 0x00000024) Start address B of DMA channel 1 */ + __IOM uint32_t DMA1_INT_REG; /*!< (@ 0x00000028) DMA receive interrupt register channel 1 */ + __IOM uint32_t DMA1_LEN_REG; /*!< (@ 0x0000002C) DMA receive length register channel 1 */ + __IOM uint32_t DMA1_CTRL_REG; /*!< (@ 0x00000030) Control register for the DMA channel 1 */ + __IOM uint32_t DMA1_IDX_REG; /*!< (@ 0x00000034) Index value of DMA channel 1 */ + __IM uint32_t RESERVED1[2]; + __IOM uint32_t DMA2_A_START_REG; /*!< (@ 0x00000040) Start address A of DMA channel 2 */ + __IOM uint32_t DMA2_B_START_REG; /*!< (@ 0x00000044) Start address B of DMA channel 2 */ + __IOM uint32_t DMA2_INT_REG; /*!< (@ 0x00000048) DMA receive interrupt register channel 2 */ + __IOM uint32_t DMA2_LEN_REG; /*!< (@ 0x0000004C) DMA receive length register channel 2 */ + __IOM uint32_t DMA2_CTRL_REG; /*!< (@ 0x00000050) Control register for the DMA channel 2 */ + __IOM uint32_t DMA2_IDX_REG; /*!< (@ 0x00000054) Index value of DMA channel 2 */ + __IM uint32_t RESERVED2[2]; + __IOM uint32_t DMA3_A_START_REG; /*!< (@ 0x00000060) Start address A of DMA channel 3 */ + __IOM uint32_t DMA3_B_START_REG; /*!< (@ 0x00000064) Start address B of DMA channel 3 */ + __IOM uint32_t DMA3_INT_REG; /*!< (@ 0x00000068) DMA receive interrupt register channel 3 */ + __IOM uint32_t DMA3_LEN_REG; /*!< (@ 0x0000006C) DMA receive length register channel 3 */ + __IOM uint32_t DMA3_CTRL_REG; /*!< (@ 0x00000070) Control register for the DMA channel 3 */ + __IOM uint32_t DMA3_IDX_REG; /*!< (@ 0x00000074) Index value of DMA channel 3 */ + __IM uint32_t RESERVED3[2]; + __IOM uint32_t DMA4_A_START_REG; /*!< (@ 0x00000080) Start address A of DMA channel 4 */ + __IOM uint32_t DMA4_B_START_REG; /*!< (@ 0x00000084) Start address B of DMA channel 4 */ + __IOM uint32_t DMA4_INT_REG; /*!< (@ 0x00000088) DMA receive interrupt register channel 4 */ + __IOM uint32_t DMA4_LEN_REG; /*!< (@ 0x0000008C) DMA receive length register channel 4 */ + __IOM uint32_t DMA4_CTRL_REG; /*!< (@ 0x00000090) Control register for the DMA channel 4 */ + __IOM uint32_t DMA4_IDX_REG; /*!< (@ 0x00000094) Index value of DMA channel 4 */ + __IM uint32_t RESERVED4[2]; + __IOM uint32_t DMA5_A_START_REG; /*!< (@ 0x000000A0) Start address A of DMA channel 5 */ + __IOM uint32_t DMA5_B_START_REG; /*!< (@ 0x000000A4) Start address B of DMA channel 5 */ + __IOM uint32_t DMA5_INT_REG; /*!< (@ 0x000000A8) DMA receive interrupt register channel 5 */ + __IOM uint32_t DMA5_LEN_REG; /*!< (@ 0x000000AC) DMA receive length register channel 5 */ + __IOM uint32_t DMA5_CTRL_REG; /*!< (@ 0x000000B0) Control register for the DMA channel 5 */ + __IOM uint32_t DMA5_IDX_REG; /*!< (@ 0x000000B4) Index value of DMA channel 5 */ + __IM uint32_t RESERVED5[2]; + __IOM uint32_t DMA6_A_START_REG; /*!< (@ 0x000000C0) Start address A of DMA channel 6 */ + __IOM uint32_t DMA6_B_START_REG; /*!< (@ 0x000000C4) Start address B of DMA channel 6 */ + __IOM uint32_t DMA6_INT_REG; /*!< (@ 0x000000C8) DMA receive interrupt register channel 6 */ + __IOM uint32_t DMA6_LEN_REG; /*!< (@ 0x000000CC) DMA receive length register channel 6 */ + __IOM uint32_t DMA6_CTRL_REG; /*!< (@ 0x000000D0) Control register for the DMA channel 6 */ + __IOM uint32_t DMA6_IDX_REG; /*!< (@ 0x000000D4) Index value of DMA channel 6 */ + __IM uint32_t RESERVED6[2]; + __IOM uint32_t DMA7_A_START_REG; /*!< (@ 0x000000E0) Start address A of DMA channel 7 */ + __IOM uint32_t DMA7_B_START_REG; /*!< (@ 0x000000E4) Start address B of DMA channel 7 */ + __IOM uint32_t DMA7_INT_REG; /*!< (@ 0x000000E8) DMA receive interrupt register channel 7 */ + __IOM uint32_t DMA7_LEN_REG; /*!< (@ 0x000000EC) DMA receive length register channel 7 */ + __IOM uint32_t DMA7_CTRL_REG; /*!< (@ 0x000000F0) Control register for the DMA channel 7 */ + __IOM uint32_t DMA7_IDX_REG; /*!< (@ 0x000000F4) Index value of DMA channel 7 */ + __IM uint32_t RESERVED7[2]; + __IOM uint32_t DMA_REQ_MUX_REG; /*!< (@ 0x00000100) DMA channel assignments */ + __IOM uint32_t DMA_INT_STATUS_REG; /*!< (@ 0x00000104) DMA interrupt status register */ + __IOM uint32_t DMA_CLEAR_INT_REG; /*!< (@ 0x00000108) DMA clear interrupt register */ + __IOM uint32_t DMA_INT_MASK_REG; /*!< (@ 0x0000010C) DMA Interrupt mask register */ +} DMA_Type; /*!< Size = 272 (0x110) */ + + + +/* =========================================================================================================================== */ +/* ================ DW ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DW registers (DW) + */ + +typedef struct { /*!< (@ 0x30020000) DW Structure */ + __IOM uint32_t AHB_DMA_PL1_REG; /*!< (@ 0x00000000) AHB-DMA layer priority level for RFTP (AHB DMA + layer only) */ + __IOM uint32_t AHB_DMA_PL2_REG; /*!< (@ 0x00000004) AHB-DMA layer priority level for LCD (AHB DMA + layer only) */ + __IOM uint32_t AHB_DMA_PL3_REG; /*!< (@ 0x00000008) AHB-DMA layer Priority level for GEN-DMA (AHB + DMA layer only) */ + __IOM uint32_t AHB_DMA_PL4_REG; /*!< (@ 0x0000000C) AHB-DMA layer Priority level for CRYPTO-DMA (AHB + DMA layer only) */ + __IM uint32_t RESERVED[14]; + __IOM uint32_t AHB_DMA_DFLT_MASTER_REG; /*!< (@ 0x00000048) Default master ID number (AHB DMA layer only) */ + __IOM uint32_t AHB_DMA_WTEN_REG; /*!< (@ 0x0000004C) Weighted-Token Arbitration Scheme Enable (AHB + DMA layer only) */ + __IOM uint32_t AHB_DMA_TCL_REG; /*!< (@ 0x00000050) Master clock refresh period (AHB DMA layer only) */ + __IOM uint32_t AHB_DMA_CCLM1_REG; /*!< (@ 0x00000054) USB Master clock tokens (AHB DMA layer only) */ + __IOM uint32_t AHB_DMA_CCLM2_REG; /*!< (@ 0x00000058) GenDMA Master clock tokens (AHB DMA layer only) */ + __IOM uint32_t AHB_DMA_CCLM3_REG; /*!< (@ 0x0000005C) CRYPTO Master clock tokens (AHB DMA layer only) */ + __IOM uint32_t AHB_DMA_CCLM4_REG; /*!< (@ 0x00000060) CRYPTO Master clock tokens (AHB DMA layer only) */ + __IM uint32_t RESERVED1[11]; + __IOM uint32_t AHB_DMA_VERSION_REG; /*!< (@ 0x00000090) Version ID (AHB DMA layer only) */ +} DW_Type; /*!< Size = 148 (0x94) */ + + + +/* =========================================================================================================================== */ +/* ================ GPADC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief GPADC registers (GPADC) + */ + +typedef struct { /*!< (@ 0x50030900) GPADC Structure */ + __IOM uint32_t GP_ADC_CTRL_REG; /*!< (@ 0x00000000) General Purpose ADC Control Register */ + __IOM uint32_t GP_ADC_CTRL2_REG; /*!< (@ 0x00000004) General Purpose ADC Second Control Register */ + __IOM uint32_t GP_ADC_CTRL3_REG; /*!< (@ 0x00000008) General Purpose ADC Third Control Register */ + __IOM uint32_t GP_ADC_OFFP_REG; /*!< (@ 0x0000000C) General Purpose ADC Positive Offset Register */ + __IOM uint32_t GP_ADC_OFFN_REG; /*!< (@ 0x00000010) General Purpose ADC Negative Offset Register */ + __IOM uint32_t GP_ADC_CLEAR_INT_REG; /*!< (@ 0x00000014) General Purpose ADC Clear Interrupt Register */ + __IOM uint32_t GP_ADC_RESULT_REG; /*!< (@ 0x00000018) General Purpose ADC Result Register */ +} GPADC_Type; /*!< Size = 28 (0x1c) */ + + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief GPIO registers (GPIO) + */ + +typedef struct { /*!< (@ 0x50020A00) GPIO Structure */ + __IOM uint32_t P0_DATA_REG; /*!< (@ 0x00000000) P0 Data input / output Register */ + __IOM uint32_t P1_DATA_REG; /*!< (@ 0x00000004) P1 Data input / output Register */ + __IOM uint32_t P0_SET_DATA_REG; /*!< (@ 0x00000008) P0 Set port pins Register */ + __IOM uint32_t P1_SET_DATA_REG; /*!< (@ 0x0000000C) P1 Set port pins Register */ + __IOM uint32_t P0_RESET_DATA_REG; /*!< (@ 0x00000010) P0 Reset port pins Register */ + __IOM uint32_t P1_RESET_DATA_REG; /*!< (@ 0x00000014) P1 Reset port pins Register */ + __IOM uint32_t P0_00_MODE_REG; /*!< (@ 0x00000018) P0_00 Mode Register */ + __IOM uint32_t P0_01_MODE_REG; /*!< (@ 0x0000001C) P0_01 Mode Register */ + __IOM uint32_t P0_02_MODE_REG; /*!< (@ 0x00000020) P0_02 Mode Register */ + __IOM uint32_t P0_03_MODE_REG; /*!< (@ 0x00000024) P0_03 Mode Register */ + __IOM uint32_t P0_04_MODE_REG; /*!< (@ 0x00000028) P0_04 Mode Register */ + __IOM uint32_t P0_05_MODE_REG; /*!< (@ 0x0000002C) P0_05 Mode Register */ + __IOM uint32_t P0_06_MODE_REG; /*!< (@ 0x00000030) P0_06 Mode Register */ + __IOM uint32_t P0_07_MODE_REG; /*!< (@ 0x00000034) P0_07 Mode Register */ + __IOM uint32_t P0_08_MODE_REG; /*!< (@ 0x00000038) P0_08 Mode Register */ + __IOM uint32_t P0_09_MODE_REG; /*!< (@ 0x0000003C) P0_09 Mode Register */ + __IOM uint32_t P0_10_MODE_REG; /*!< (@ 0x00000040) P0_10 Mode Register */ + __IOM uint32_t P0_11_MODE_REG; /*!< (@ 0x00000044) P0_11 Mode Register */ + __IOM uint32_t P0_12_MODE_REG; /*!< (@ 0x00000048) P0_12 Mode Register */ + __IOM uint32_t P0_13_MODE_REG; /*!< (@ 0x0000004C) P0_13 Mode Register */ + __IOM uint32_t P0_14_MODE_REG; /*!< (@ 0x00000050) P0_14 Mode Register */ + __IOM uint32_t P0_15_MODE_REG; /*!< (@ 0x00000054) P0_15 Mode Register */ + __IOM uint32_t P0_16_MODE_REG; /*!< (@ 0x00000058) P0_16 Mode Register */ + __IOM uint32_t P0_17_MODE_REG; /*!< (@ 0x0000005C) P0_17 Mode Register */ + __IOM uint32_t P0_18_MODE_REG; /*!< (@ 0x00000060) P0_18 Mode Register */ + __IOM uint32_t P0_19_MODE_REG; /*!< (@ 0x00000064) P0_19 Mode Register */ + __IOM uint32_t P0_20_MODE_REG; /*!< (@ 0x00000068) P0_20 Mode Register */ + __IOM uint32_t P0_21_MODE_REG; /*!< (@ 0x0000006C) P0_21 Mode Register */ + __IOM uint32_t P0_22_MODE_REG; /*!< (@ 0x00000070) P0_22 Mode Register */ + __IOM uint32_t P0_23_MODE_REG; /*!< (@ 0x00000074) P0_23 Mode Register */ + __IOM uint32_t P0_24_MODE_REG; /*!< (@ 0x00000078) P0_24 Mode Register */ + __IOM uint32_t P0_25_MODE_REG; /*!< (@ 0x0000007C) P0_25 Mode Register */ + __IOM uint32_t P0_26_MODE_REG; /*!< (@ 0x00000080) P0_26 Mode Register */ + __IOM uint32_t P0_27_MODE_REG; /*!< (@ 0x00000084) P0_27 Mode Register */ + __IOM uint32_t P0_28_MODE_REG; /*!< (@ 0x00000088) P0_28 Mode Register */ + __IOM uint32_t P0_29_MODE_REG; /*!< (@ 0x0000008C) P0_29 Mode Register */ + __IOM uint32_t P0_30_MODE_REG; /*!< (@ 0x00000090) P0_30 Mode Register */ + __IOM uint32_t P0_31_MODE_REG; /*!< (@ 0x00000094) P0_31 Mode Register */ + __IOM uint32_t P1_00_MODE_REG; /*!< (@ 0x00000098) P1_00 Mode Register */ + __IOM uint32_t P1_01_MODE_REG; /*!< (@ 0x0000009C) P1_01 Mode Register */ + __IOM uint32_t P1_02_MODE_REG; /*!< (@ 0x000000A0) P1_02 Mode Register */ + __IOM uint32_t P1_03_MODE_REG; /*!< (@ 0x000000A4) P1_03 Mode Register */ + __IOM uint32_t P1_04_MODE_REG; /*!< (@ 0x000000A8) P1_04 Mode Register */ + __IOM uint32_t P1_05_MODE_REG; /*!< (@ 0x000000AC) P1_05 Mode Register */ + __IOM uint32_t P1_06_MODE_REG; /*!< (@ 0x000000B0) P1_06 Mode Register */ + __IOM uint32_t P1_07_MODE_REG; /*!< (@ 0x000000B4) P1_07 Mode Register */ + __IOM uint32_t P1_08_MODE_REG; /*!< (@ 0x000000B8) P1_08 Mode Register */ + __IOM uint32_t P1_09_MODE_REG; /*!< (@ 0x000000BC) P1_09 Mode Register */ + __IOM uint32_t P1_10_MODE_REG; /*!< (@ 0x000000C0) P1_10 Mode Register */ + __IOM uint32_t P1_11_MODE_REG; /*!< (@ 0x000000C4) P1_11 Mode Register */ + __IOM uint32_t P1_12_MODE_REG; /*!< (@ 0x000000C8) P1_12 Mode Register */ + __IOM uint32_t P1_13_MODE_REG; /*!< (@ 0x000000CC) P1_13 Mode Register */ + __IOM uint32_t P1_14_MODE_REG; /*!< (@ 0x000000D0) P1_14 Mode Register */ + __IOM uint32_t P1_15_MODE_REG; /*!< (@ 0x000000D4) P1_15 Mode Register */ + __IOM uint32_t P1_16_MODE_REG; /*!< (@ 0x000000D8) P1_16 Mode Register */ + __IOM uint32_t P1_17_MODE_REG; /*!< (@ 0x000000DC) P1_17 Mode Register */ + __IOM uint32_t P1_18_MODE_REG; /*!< (@ 0x000000E0) P1_18 Mode Register */ + __IOM uint32_t P1_19_MODE_REG; /*!< (@ 0x000000E4) P1_19 Mode Register */ + __IOM uint32_t P1_20_MODE_REG; /*!< (@ 0x000000E8) P1_20 Mode Register */ + __IOM uint32_t P1_21_MODE_REG; /*!< (@ 0x000000EC) P1_21 Mode Register */ + __IOM uint32_t P1_22_MODE_REG; /*!< (@ 0x000000F0) P1_22 Mode Register */ + __IOM uint32_t P0_PADPWR_CTRL_REG; /*!< (@ 0x000000F4) P0 Output Power Control Register */ + __IOM uint32_t P1_PADPWR_CTRL_REG; /*!< (@ 0x000000F8) P1 Output Power Control Register */ + __IOM uint32_t GPIO_CLK_SEL_REG; /*!< (@ 0x000000FC) Select which clock to map on ports P0/P1 */ + __IOM uint32_t PAD_WEAK_CTRL_REG; /*!< (@ 0x00000100) Weak Pads Control Register */ +} GPIO_Type; /*!< Size = 260 (0x104) */ + + + +/* =========================================================================================================================== */ +/* ================ GPREG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief GPREG registers (GPREG) + */ + +typedef struct { /*!< (@ 0x50040300) GPREG Structure */ + __IOM uint32_t SET_FREEZE_REG; /*!< (@ 0x00000000) Controls freezing of various timers/counters + (incl. DMA and USB). */ + __IOM uint32_t RESET_FREEZE_REG; /*!< (@ 0x00000004) Controls unfreezing of various timers/counters + (incl. DMA and USB). */ + __IOM uint32_t DEBUG_REG; /*!< (@ 0x00000008) Various debug information register. */ + __IOM uint32_t GP_STATUS_REG; /*!< (@ 0x0000000C) General purpose system status register. */ + __IOM uint32_t GP_CONTROL_REG; /*!< (@ 0x00000010) General purpose system control register. */ + __IM uint32_t RESERVED; + __IOM uint32_t USBPAD_REG; /*!< (@ 0x00000018) USB pads control register */ +} GPREG_Type; /*!< Size = 28 (0x1c) */ + + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief I2C registers (I2C) + */ + +typedef struct { /*!< (@ 0x50020600) I2C Structure */ + __IOM uint32_t I2C_CON_REG; /*!< (@ 0x00000000) I2C Control Register */ + __IOM uint32_t I2C_TAR_REG; /*!< (@ 0x00000004) I2C Target Address Register */ + __IOM uint32_t I2C_SAR_REG; /*!< (@ 0x00000008) I2C Slave Address Register */ + __IOM uint32_t I2C_HS_MADDR_REG; /*!< (@ 0x0000000C) I2C High Speed Master Mode Code Address Register */ + __IOM uint32_t I2C_DATA_CMD_REG; /*!< (@ 0x00000010) I2C Rx/Tx Data Buffer and Command Register */ + __IOM uint32_t I2C_SS_SCL_HCNT_REG; /*!< (@ 0x00000014) Standard Speed I2C Clock SCL High Count Register */ + __IOM uint32_t I2C_SS_SCL_LCNT_REG; /*!< (@ 0x00000018) Standard Speed I2C Clock SCL Low Count Register */ + __IOM uint32_t I2C_FS_SCL_HCNT_REG; /*!< (@ 0x0000001C) Fast Speed I2C Clock SCL High Count Register */ + __IOM uint32_t I2C_FS_SCL_LCNT_REG; /*!< (@ 0x00000020) Fast Speed I2C Clock SCL Low Count Register */ + __IOM uint32_t I2C_HS_SCL_HCNT_REG; /*!< (@ 0x00000024) High Speed I2C Clock SCL High Count Register */ + __IOM uint32_t I2C_HS_SCL_LCNT_REG; /*!< (@ 0x00000028) High Speed I2C Clock SCL Low Count Register */ + __IOM uint32_t I2C_INTR_STAT_REG; /*!< (@ 0x0000002C) I2C Interrupt Status Register */ + __IOM uint32_t I2C_INTR_MASK_REG; /*!< (@ 0x00000030) I2C Interrupt Mask Register */ + __IOM uint32_t I2C_RAW_INTR_STAT_REG; /*!< (@ 0x00000034) I2C Raw Interrupt Status Register */ + __IOM uint32_t I2C_RX_TL_REG; /*!< (@ 0x00000038) I2C Receive FIFO Threshold Register */ + __IOM uint32_t I2C_TX_TL_REG; /*!< (@ 0x0000003C) I2C Transmit FIFO Threshold Register */ + __IOM uint32_t I2C_CLR_INTR_REG; /*!< (@ 0x00000040) Clear Combined and Individual Interrupt Register */ + __IOM uint32_t I2C_CLR_RX_UNDER_REG; /*!< (@ 0x00000044) Clear RX_UNDER Interrupt Register */ + __IOM uint32_t I2C_CLR_RX_OVER_REG; /*!< (@ 0x00000048) Clear RX_OVER Interrupt Register */ + __IOM uint32_t I2C_CLR_TX_OVER_REG; /*!< (@ 0x0000004C) Clear TX_OVER Interrupt Register */ + __IOM uint32_t I2C_CLR_RD_REQ_REG; /*!< (@ 0x00000050) Clear RD_REQ Interrupt Register */ + __IOM uint32_t I2C_CLR_TX_ABRT_REG; /*!< (@ 0x00000054) Clear TX_ABRT Interrupt Register */ + __IOM uint32_t I2C_CLR_RX_DONE_REG; /*!< (@ 0x00000058) Clear RX_DONE Interrupt Register */ + __IOM uint32_t I2C_CLR_ACTIVITY_REG; /*!< (@ 0x0000005C) Clear ACTIVITY Interrupt Register */ + __IOM uint32_t I2C_CLR_STOP_DET_REG; /*!< (@ 0x00000060) Clear STOP_DET Interrupt Register */ + __IOM uint32_t I2C_CLR_START_DET_REG; /*!< (@ 0x00000064) Clear START_DET Interrupt Register */ + __IOM uint32_t I2C_CLR_GEN_CALL_REG; /*!< (@ 0x00000068) Clear GEN_CALL Interrupt Register */ + __IOM uint32_t I2C_ENABLE_REG; /*!< (@ 0x0000006C) I2C Enable Register */ + __IOM uint32_t I2C_STATUS_REG; /*!< (@ 0x00000070) I2C Status Register */ + __IOM uint32_t I2C_TXFLR_REG; /*!< (@ 0x00000074) I2C Transmit FIFO Level Register */ + __IOM uint32_t I2C_RXFLR_REG; /*!< (@ 0x00000078) I2C Receive FIFO Level Register */ + __IOM uint32_t I2C_SDA_HOLD_REG; /*!< (@ 0x0000007C) I2C SDA Hold Time Length Register */ + __IOM uint32_t I2C_TX_ABRT_SOURCE_REG; /*!< (@ 0x00000080) I2C Transmit Abort Source Register */ + __IM uint32_t RESERVED; + __IOM uint32_t I2C_DMA_CR_REG; /*!< (@ 0x00000088) DMA Control Register */ + __IOM uint32_t I2C_DMA_TDLR_REG; /*!< (@ 0x0000008C) DMA Transmit Data Level Register */ + __IOM uint32_t I2C_DMA_RDLR_REG; /*!< (@ 0x00000090) I2C Receive Data Level Register */ + __IOM uint32_t I2C_SDA_SETUP_REG; /*!< (@ 0x00000094) I2C SDA Setup Register */ + __IOM uint32_t I2C_ACK_GENERAL_CALL_REG; /*!< (@ 0x00000098) I2C ACK General Call Register */ + __IOM uint32_t I2C_ENABLE_STATUS_REG; /*!< (@ 0x0000009C) I2C Enable Status Register */ + __IOM uint32_t I2C_IC_FS_SPKLEN_REG; /*!< (@ 0x000000A0) I2C SS and FS spike suppression limit Size */ + __IOM uint32_t I2C_IC_HS_SPKLEN_REG; /*!< (@ 0x000000A4) I2C HS spike suppression limit Size */ +} I2C_Type; /*!< Size = 168 (0xa8) */ + + + +/* =========================================================================================================================== */ +/* ================ I2C2 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief I2C2 registers (I2C2) + */ + +typedef struct { /*!< (@ 0x50020700) I2C2 Structure */ + __IOM uint32_t I2C2_CON_REG; /*!< (@ 0x00000000) I2C Control Register */ + __IOM uint32_t I2C2_TAR_REG; /*!< (@ 0x00000004) I2C Target Address Register */ + __IOM uint32_t I2C2_SAR_REG; /*!< (@ 0x00000008) I2C Slave Address Register */ + __IOM uint32_t I2C2_HS_MADDR_REG; /*!< (@ 0x0000000C) I2C High Speed Master Mode Code Address Register */ + __IOM uint32_t I2C2_DATA_CMD_REG; /*!< (@ 0x00000010) I2C Rx/Tx Data Buffer and Command Register */ + __IOM uint32_t I2C2_SS_SCL_HCNT_REG; /*!< (@ 0x00000014) Standard Speed I2C Clock SCL High Count Register */ + __IOM uint32_t I2C2_SS_SCL_LCNT_REG; /*!< (@ 0x00000018) Standard Speed I2C Clock SCL Low Count Register */ + __IOM uint32_t I2C2_FS_SCL_HCNT_REG; /*!< (@ 0x0000001C) Fast Speed I2C Clock SCL High Count Register */ + __IOM uint32_t I2C2_FS_SCL_LCNT_REG; /*!< (@ 0x00000020) Fast Speed I2C Clock SCL Low Count Register */ + __IOM uint32_t I2C2_HS_SCL_HCNT_REG; /*!< (@ 0x00000024) High Speed I2C Clock SCL High Count Register */ + __IOM uint32_t I2C2_HS_SCL_LCNT_REG; /*!< (@ 0x00000028) High Speed I2C Clock SCL Low Count Register */ + __IOM uint32_t I2C2_INTR_STAT_REG; /*!< (@ 0x0000002C) I2C Interrupt Status Register */ + __IOM uint32_t I2C2_INTR_MASK_REG; /*!< (@ 0x00000030) I2C Interrupt Mask Register */ + __IOM uint32_t I2C2_RAW_INTR_STAT_REG; /*!< (@ 0x00000034) I2C Raw Interrupt Status Register */ + __IOM uint32_t I2C2_RX_TL_REG; /*!< (@ 0x00000038) I2C Receive FIFO Threshold Register */ + __IOM uint32_t I2C2_TX_TL_REG; /*!< (@ 0x0000003C) I2C Transmit FIFO Threshold Register */ + __IOM uint32_t I2C2_CLR_INTR_REG; /*!< (@ 0x00000040) Clear Combined and Individual Interrupt Register */ + __IOM uint32_t I2C2_CLR_RX_UNDER_REG; /*!< (@ 0x00000044) Clear RX_UNDER Interrupt Register */ + __IOM uint32_t I2C2_CLR_RX_OVER_REG; /*!< (@ 0x00000048) Clear RX_OVER Interrupt Register */ + __IOM uint32_t I2C2_CLR_TX_OVER_REG; /*!< (@ 0x0000004C) Clear TX_OVER Interrupt Register */ + __IOM uint32_t I2C2_CLR_RD_REQ_REG; /*!< (@ 0x00000050) Clear RD_REQ Interrupt Register */ + __IOM uint32_t I2C2_CLR_TX_ABRT_REG; /*!< (@ 0x00000054) Clear TX_ABRT Interrupt Register */ + __IOM uint32_t I2C2_CLR_RX_DONE_REG; /*!< (@ 0x00000058) Clear RX_DONE Interrupt Register */ + __IOM uint32_t I2C2_CLR_ACTIVITY_REG; /*!< (@ 0x0000005C) Clear ACTIVITY Interrupt Register */ + __IOM uint32_t I2C2_CLR_STOP_DET_REG; /*!< (@ 0x00000060) Clear STOP_DET Interrupt Register */ + __IOM uint32_t I2C2_CLR_START_DET_REG; /*!< (@ 0x00000064) Clear START_DET Interrupt Register */ + __IOM uint32_t I2C2_CLR_GEN_CALL_REG; /*!< (@ 0x00000068) Clear GEN_CALL Interrupt Register */ + __IOM uint32_t I2C2_ENABLE_REG; /*!< (@ 0x0000006C) I2C Enable Register */ + __IOM uint32_t I2C2_STATUS_REG; /*!< (@ 0x00000070) I2C Status Register */ + __IOM uint32_t I2C2_TXFLR_REG; /*!< (@ 0x00000074) I2C Transmit FIFO Level Register */ + __IOM uint32_t I2C2_RXFLR_REG; /*!< (@ 0x00000078) I2C Receive FIFO Level Register */ + __IOM uint32_t I2C2_SDA_HOLD_REG; /*!< (@ 0x0000007C) I2C SDA Hold Time Length Register */ + __IOM uint32_t I2C2_TX_ABRT_SOURCE_REG; /*!< (@ 0x00000080) I2C Transmit Abort Source Register */ + __IM uint32_t RESERVED; + __IOM uint32_t I2C2_DMA_CR_REG; /*!< (@ 0x00000088) DMA Control Register */ + __IOM uint32_t I2C2_DMA_TDLR_REG; /*!< (@ 0x0000008C) DMA Transmit Data Level Register */ + __IOM uint32_t I2C2_DMA_RDLR_REG; /*!< (@ 0x00000090) I2C Receive Data Level Register */ + __IOM uint32_t I2C2_SDA_SETUP_REG; /*!< (@ 0x00000094) I2C SDA Setup Register */ + __IOM uint32_t I2C2_ACK_GENERAL_CALL_REG; /*!< (@ 0x00000098) I2C ACK General Call Register */ + __IOM uint32_t I2C2_ENABLE_STATUS_REG; /*!< (@ 0x0000009C) I2C Enable Status Register */ + __IOM uint32_t I2C2_IC_FS_SPKLEN_REG; /*!< (@ 0x000000A0) I2C SS and FS spike suppression limit Size */ + __IOM uint32_t I2C2_IC_HS_SPKLEN_REG; /*!< (@ 0x000000A4) I2C HS spike suppression limit Size */ +} I2C2_Type; /*!< Size = 168 (0xa8) */ + + + +/* =========================================================================================================================== */ +/* ================ LCDC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief LCDC registers (LCDC) + */ + +typedef struct { /*!< (@ 0x30030000) LCDC Structure */ + __IOM uint32_t LCDC_MODE_REG; /*!< (@ 0x00000000) Display Mode */ + __IOM uint32_t LCDC_CLKCTRL_REG; /*!< (@ 0x00000004) Clock Divider */ + __IOM uint32_t LCDC_BGCOLOR_REG; /*!< (@ 0x00000008) Background Color */ + __IOM uint32_t LCDC_RESXY_REG; /*!< (@ 0x0000000C) Resolution X,Y */ + __IM uint32_t RESERVED; + __IOM uint32_t LCDC_FRONTPORCHXY_REG; /*!< (@ 0x00000014) Front Porch X and Y */ + __IOM uint32_t LCDC_BLANKINGXY_REG; /*!< (@ 0x00000018) Blanking X and Y */ + __IOM uint32_t LCDC_BACKPORCHXY_REG; /*!< (@ 0x0000001C) Back Porch X and Y */ + __IM uint32_t RESERVED1[2]; + __IOM uint32_t LCDC_DBIB_CFG_REG; /*!< (@ 0x00000028) MIPI Config Register */ + __IOM uint32_t LCDC_GPIO_REG; /*!< (@ 0x0000002C) General Purpose IO (2-bits) */ + __IOM uint32_t LCDC_LAYER0_MODE_REG; /*!< (@ 0x00000030) Layer0 Mode */ + __IOM uint32_t LCDC_LAYER0_STARTXY_REG; /*!< (@ 0x00000034) Layer0 Start XY */ + __IOM uint32_t LCDC_LAYER0_SIZEXY_REG; /*!< (@ 0x00000038) Layer0 Size XY */ + __IOM uint32_t LCDC_LAYER0_BASEADDR_REG; /*!< (@ 0x0000003C) Layer0 Base Addr */ + __IOM uint32_t LCDC_LAYER0_STRIDE_REG; /*!< (@ 0x00000040) Layer0 Stride */ + __IOM uint32_t LCDC_LAYER0_RESXY_REG; /*!< (@ 0x00000044) Layer0 Res XY */ + __IM uint32_t RESERVED2[18]; + __IOM uint32_t LCDC_JDI_RESXY_REG; /*!< (@ 0x00000090) Resolution XY for the JDI parallel I/F */ + __IOM uint32_t LCDC_JDI_FBX_BLANKING_REG; /*!< (@ 0x00000094) Horizontal front/back blanking (hck half periods) */ + __IOM uint32_t LCDC_JDI_FBY_BLANKING_REG; /*!< (@ 0x00000098) Vertical front/back blanking (vck half periods) */ + __IOM uint32_t LCDC_JDI_HCK_WIDTH_REG; /*!< (@ 0x0000009C) HCK high/low width */ + __IOM uint32_t LCDC_JDI_XRST_WIDTH_REG; /*!< (@ 0x000000A0) XRST width */ + __IOM uint32_t LCDC_JDI_VST_DELAY_REG; /*!< (@ 0x000000A4) XRST-to-VST delay */ + __IOM uint32_t LCDC_JDI_VST_WIDTH_REG; /*!< (@ 0x000000A8) VST width */ + __IOM uint32_t LCDC_JDI_VCK_DELAY_REG; /*!< (@ 0x000000AC) XRST-to-VCK delay */ + __IOM uint32_t LCDC_JDI_HST_DELAY_REG; /*!< (@ 0x000000B0) VCK-to-HST delay */ + __IOM uint32_t LCDC_JDI_HST_WIDTH_REG; /*!< (@ 0x000000B4) HST width */ + __IOM uint32_t LCDC_JDI_ENB_START_HLINE_REG; /*!< (@ 0x000000B8) ENB start horizontal line */ + __IOM uint32_t LCDC_JDI_ENB_END_HLINE_REG; /*!< (@ 0x000000BC) ENB end horizontal line */ + __IOM uint32_t LCDC_JDI_ENB_START_CLK_REG; /*!< (@ 0x000000C0) ENB start delay */ + __IOM uint32_t LCDC_JDI_ENB_WIDTH_CLK_REG; /*!< (@ 0x000000C4) ENB width */ + __IM uint32_t RESERVED3[8]; + __IOM uint32_t LCDC_DBIB_CMD_REG; /*!< (@ 0x000000E8) MIPI DBIB Command Register */ + __IM uint32_t RESERVED4[2]; + __IOM uint32_t LCDC_IDREG_REG; /*!< (@ 0x000000F4) Identification Register */ + __IOM uint32_t LCDC_INTERRUPT_REG; /*!< (@ 0x000000F8) Interrupt Register */ + __IOM uint32_t LCDC_STATUS_REG; /*!< (@ 0x000000FC) Status Register */ + __IM uint32_t RESERVED5[33]; + __IOM uint32_t LCDC_CRC_REG; /*!< (@ 0x00000184) CRC check */ + __IOM uint32_t LCDC_LAYER0_OFFSETX_REG; /*!< (@ 0x00000188) Layer0 OffsetX and DMA prefetch */ +} LCDC_Type; /*!< Size = 396 (0x18c) */ + + + +/* =========================================================================================================================== */ +/* ================ LRA ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief LRA registers (LRA) + */ + +typedef struct { /*!< (@ 0x50030A00) LRA Structure */ + __IOM uint32_t LRA_CTRL1_REG; /*!< (@ 0x00000000) General Purpose LRA Control Register */ + __IOM uint32_t LRA_CTRL2_REG; /*!< (@ 0x00000004) General Purpose LRA Control Register */ + __IOM uint32_t LRA_CTRL3_REG; /*!< (@ 0x00000008) General Purpose LRA Control Register */ + __IOM uint32_t LRA_FLT_SMP1_REG; /*!< (@ 0x0000000C) LRA Sample Register */ + __IOM uint32_t LRA_FLT_SMP2_REG; /*!< (@ 0x00000010) LRA Sample Register */ + __IOM uint32_t LRA_FLT_SMP3_REG; /*!< (@ 0x00000014) LRA Sample Register */ + __IOM uint32_t LRA_FLT_SMP4_REG; /*!< (@ 0x00000018) LRA Sample Register */ + __IOM uint32_t LRA_FLT_SMP5_REG; /*!< (@ 0x0000001C) LRA Sample Register */ + __IOM uint32_t LRA_FLT_SMP6_REG; /*!< (@ 0x00000020) LRA Sample Register */ + __IOM uint32_t LRA_FLT_SMP7_REG; /*!< (@ 0x00000024) LRA Sample Register */ + __IOM uint32_t LRA_FLT_SMP8_REG; /*!< (@ 0x00000028) LRA Sample Register */ + __IOM uint32_t LRA_FLT_COEF1_REG; /*!< (@ 0x0000002C) LRA Filter Coefficient Register */ + __IOM uint32_t LRA_FLT_COEF2_REG; /*!< (@ 0x00000030) LRA Filter Coefficient Register */ + __IOM uint32_t LRA_FLT_COEF3_REG; /*!< (@ 0x00000034) LRA Filter Coefficient Register */ + __IOM uint32_t LRA_BRD_LS_REG; /*!< (@ 0x00000038) LRA Bridge Register */ + __IOM uint32_t LRA_BRD_HS_REG; /*!< (@ 0x0000003C) LRA Bridge Register */ + __IOM uint32_t LRA_BRD_STAT_REG; /*!< (@ 0x00000040) LRA Bridge Staus Register */ + __IOM uint32_t LRA_ADC_CTRL1_REG; /*!< (@ 0x00000044) General Purpose ADC Control Register */ + __IM uint32_t RESERVED[2]; + __IOM uint32_t LRA_ADC_RESULT_REG; /*!< (@ 0x00000050) General Purpose ADC Result Register */ + __IOM uint32_t LRA_LDO_REG; /*!< (@ 0x00000054) LRA LDO Regsiter */ + __IOM uint32_t LRA_DFT_REG; /*!< (@ 0x00000058) LRA test Register */ +} LRA_Type; /*!< Size = 92 (0x5c) */ + + + +/* =========================================================================================================================== */ +/* ================ MEMCTRL ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief MEMCTRL registers (MEMCTRL) + */ + +typedef struct { /*!< (@ 0x50050000) MEMCTRL Structure */ + __IM uint32_t RESERVED; + __IOM uint32_t MEM_PRIO_REG; /*!< (@ 0x00000004) Priority Control Register */ + __IOM uint32_t MEM_STALL_REG; /*!< (@ 0x00000008) Maximum Stall cycles Control Register */ + __IOM uint32_t MEM_STATUS_REG; /*!< (@ 0x0000000C) Memory Arbiter Status Register */ + __IOM uint32_t MEM_STATUS2_REG; /*!< (@ 0x00000010) RAM cells Status Register */ + __IM uint32_t RESERVED1[3]; + __IOM uint32_t CMI_CODE_BASE_REG; /*!< (@ 0x00000020) CMAC code Base Address Register */ + __IOM uint32_t CMI_DATA_BASE_REG; /*!< (@ 0x00000024) CMAC data Base Address Register */ + __IOM uint32_t CMI_SHARED_BASE_REG; /*!< (@ 0x00000028) CMAC shared data Base Address Register */ + __IOM uint32_t CMI_END_REG; /*!< (@ 0x0000002C) CMAC end Address Register */ + __IOM uint32_t SNC_BASE_REG; /*!< (@ 0x00000030) Sensor Node Controller Base Address Register */ + __IM uint32_t RESERVED2[16]; + __IOM uint32_t BUSY_SET_REG; /*!< (@ 0x00000074) BSR Set Register */ + __IOM uint32_t BUSY_RESET_REG; /*!< (@ 0x00000078) BSR Reset Register */ + __IOM uint32_t BUSY_STAT_REG; /*!< (@ 0x0000007C) BSR Status Register */ +} MEMCTRL_Type; /*!< Size = 128 (0x80) */ + + + +/* =========================================================================================================================== */ +/* ================ OTPC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief OTPC registers (OTPC) + */ + +typedef struct { /*!< (@ 0x30070000) OTPC Structure */ + __IOM uint32_t OTPC_MODE_REG; /*!< (@ 0x00000000) Mode register */ + __IOM uint32_t OTPC_STAT_REG; /*!< (@ 0x00000004) Status register */ + __IOM uint32_t OTPC_PADDR_REG; /*!< (@ 0x00000008) The address of the word that will be programmed, + when the PROG mode is used. */ + __IOM uint32_t OTPC_PWORD_REG; /*!< (@ 0x0000000C) The 32-bit word that will be programmed, when + the PROG mode is used. */ + __IOM uint32_t OTPC_TIM1_REG; /*!< (@ 0x00000010) Various timing parameters of the OTP cell. */ + __IOM uint32_t OTPC_TIM2_REG; /*!< (@ 0x00000014) Various timing parameters of the OTP cell. */ +} OTPC_Type; /*!< Size = 24 (0x18) */ + + + +/* =========================================================================================================================== */ +/* ================ PDC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief PDC registers (PDC) + */ + +typedef struct { /*!< (@ 0x50000200) PDC Structure */ + __IOM uint32_t PDC_CTRL0_REG; /*!< (@ 0x00000000) PDC control register */ + __IOM uint32_t PDC_CTRL1_REG; /*!< (@ 0x00000004) PDC control register */ + __IOM uint32_t PDC_CTRL2_REG; /*!< (@ 0x00000008) PDC control register */ + __IOM uint32_t PDC_CTRL3_REG; /*!< (@ 0x0000000C) PDC control register */ + __IOM uint32_t PDC_CTRL4_REG; /*!< (@ 0x00000010) PDC control register */ + __IOM uint32_t PDC_CTRL5_REG; /*!< (@ 0x00000014) PDC control register */ + __IOM uint32_t PDC_CTRL6_REG; /*!< (@ 0x00000018) PDC control register */ + __IOM uint32_t PDC_CTRL7_REG; /*!< (@ 0x0000001C) PDC control register */ + __IOM uint32_t PDC_CTRL8_REG; /*!< (@ 0x00000020) PDC control register */ + __IOM uint32_t PDC_CTRL9_REG; /*!< (@ 0x00000024) PDC control register */ + __IOM uint32_t PDC_CTRL10_REG; /*!< (@ 0x00000028) PDC control register */ + __IOM uint32_t PDC_CTRL11_REG; /*!< (@ 0x0000002C) PDC control register */ + __IOM uint32_t PDC_CTRL12_REG; /*!< (@ 0x00000030) PDC control register */ + __IOM uint32_t PDC_CTRL13_REG; /*!< (@ 0x00000034) PDC control register */ + __IOM uint32_t PDC_CTRL14_REG; /*!< (@ 0x00000038) PDC control register */ + __IOM uint32_t PDC_CTRL15_REG; /*!< (@ 0x0000003C) PDC control register */ + __IM uint32_t RESERVED[16]; + __IOM uint32_t PDC_ACKNOWLEDGE_REG; /*!< (@ 0x00000080) Clear a pending PDC bit */ + __IOM uint32_t PDC_PENDING_REG; /*!< (@ 0x00000084) Shows any pending wakup event */ + __IOM uint32_t PDC_PENDING_SNC_REG; /*!< (@ 0x00000088) Shows any pending IRQ to SNC */ + __IOM uint32_t PDC_PENDING_CM33_REG; /*!< (@ 0x0000008C) Shows any pending IRQ to CM33 */ + __IOM uint32_t PDC_PENDING_CMAC_REG; /*!< (@ 0x00000090) Shows any pending IRQ to CM33 */ + __IOM uint32_t PDC_SET_PENDING_REG; /*!< (@ 0x00000094) Set a pending PDC bit */ +} PDC_Type; /*!< Size = 152 (0x98) */ + + + +/* =========================================================================================================================== */ +/* ================ PWMLED ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief PWMLED registers (PWMLED) + */ + +typedef struct { /*!< (@ 0x50030500) PWMLED Structure */ + __IOM uint32_t PWMLED_DUTY_CYCLE_LED1_REG; /*!< (@ 0x00000000) Defines duty cycle for PWM1 */ + __IOM uint32_t PWMLED_DUTY_CYCLE_LED2_REG; /*!< (@ 0x00000004) Defines duty cycle for PWM2 */ + __IOM uint32_t PWMLED_FREQUENCY_REG; /*!< (@ 0x00000008) Defines the PWM frequecny */ + __IOM uint32_t PWMLED_CTRL_REG; /*!< (@ 0x0000000C) PWM Control register */ +} PWMLED_Type; /*!< Size = 16 (0x10) */ + + + +/* =========================================================================================================================== */ +/* ================ QSPIC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief QSPIC registers (QSPIC) + */ + +typedef struct { /*!< (@ 0x38000000) QSPIC Structure */ + __IOM uint32_t QSPIC_CTRLBUS_REG; /*!< (@ 0x00000000) SPI Bus control register for the Manual mode */ + __IOM uint32_t QSPIC_CTRLMODE_REG; /*!< (@ 0x00000004) Mode Control register */ + __IOM uint32_t QSPIC_RECVDATA_REG; /*!< (@ 0x00000008) Received data for the Manual mode */ + __IOM uint32_t QSPIC_BURSTCMDA_REG; /*!< (@ 0x0000000C) The way of reading in Auto mode (command register + A) */ + __IOM uint32_t QSPIC_BURSTCMDB_REG; /*!< (@ 0x00000010) The way of reading in Auto mode (command register + B) */ + __IOM uint32_t QSPIC_STATUS_REG; /*!< (@ 0x00000014) The status register of the QSPI controller */ + __IOM uint32_t QSPIC_WRITEDATA_REG; /*!< (@ 0x00000018) Write data to SPI Bus for the Manual mode */ + __IOM uint32_t QSPIC_READDATA_REG; /*!< (@ 0x0000001C) Read data from SPI Bus for the Manual mode */ + __IOM uint32_t QSPIC_DUMMYDATA_REG; /*!< (@ 0x00000020) Send dummy clocks to SPI Bus for the Manual mode */ + __IOM uint32_t QSPIC_ERASECTRL_REG; /*!< (@ 0x00000024) QSPI Erase control register */ + __IOM uint32_t QSPIC_ERASECMDA_REG; /*!< (@ 0x00000028) The way of erasing in Auto mode (command register + A) */ + __IOM uint32_t QSPIC_ERASECMDB_REG; /*!< (@ 0x0000002C) The way of erasing in Auto mode (command register + B) */ + __IOM uint32_t QSPIC_BURSTBRK_REG; /*!< (@ 0x00000030) Read break sequence in Auto mode */ + __IOM uint32_t QSPIC_STATUSCMD_REG; /*!< (@ 0x00000034) The way of reading the status of external device + in Auto mode */ + __IOM uint32_t QSPIC_CHCKERASE_REG; /*!< (@ 0x00000038) Check erase progress in Auto mode */ + __IOM uint32_t QSPIC_GP_REG; /*!< (@ 0x0000003C) QSPI General Purpose control register */ + __IOM uint32_t QSPIC_UCODE_START; /*!< (@ 0x00000040) QSPIC uCode memory */ + __IM uint32_t RESERVED[15]; + __IOM uint32_t QSPIC_CTR_CTRL_REG; /*!< (@ 0x00000080) Control register for the decryption engine of + the QSPIC */ + __IOM uint32_t QSPIC_CTR_SADDR_REG; /*!< (@ 0x00000084) Start address of the encrypted content in the + QSPI flash */ + __IOM uint32_t QSPIC_CTR_EADDR_REG; /*!< (@ 0x00000088) End address of the encrypted content in the QSPI + flash */ + __IOM uint32_t QSPIC_CTR_NONCE_0_3_REG; /*!< (@ 0x0000008C) Nonce bytes 0 to 3 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_NONCE_4_7_REG; /*!< (@ 0x00000090) Nonce bytes 4 to 7 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_KEY_0_3_REG; /*!< (@ 0x00000094) Key bytes 0 to 3 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_KEY_4_7_REG; /*!< (@ 0x00000098) Key bytes 4 to 7 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_KEY_8_11_REG; /*!< (@ 0x0000009C) Key bytes 8 to 11 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_KEY_12_15_REG; /*!< (@ 0x000000A0) Key bytes 12 to 15 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_KEY_16_19_REG; /*!< (@ 0x000000A4) Key bytes 16 to 19 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_KEY_20_23_REG; /*!< (@ 0x000000A8) Key bytes 20 to 23 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_KEY_24_27_REG; /*!< (@ 0x000000AC) Key bytes 24 to 27 for the AES-CTR algorithm */ + __IOM uint32_t QSPIC_CTR_KEY_28_31_REG; /*!< (@ 0x000000B0) Key bytes 28 to 31 for the AES-CTR algorithm */ +} QSPIC_Type; /*!< Size = 180 (0xb4) */ + + + +/* =========================================================================================================================== */ +/* ================ QSPIC2 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief QSPIC2 registers (QSPIC2) + */ + +typedef struct { /*!< (@ 0x34000000) QSPIC2 Structure */ + __IOM uint32_t QSPIC2_CTRLBUS_REG; /*!< (@ 0x00000000) SPI Bus control register for the Manual mode */ + __IOM uint32_t QSPIC2_CTRLMODE_REG; /*!< (@ 0x00000004) Mode control register */ + __IOM uint32_t QSPIC2_RECVDATA_REG; /*!< (@ 0x00000008) Received data for the Manual mode */ + __IOM uint32_t QSPIC2_BURSTCMDA_REG; /*!< (@ 0x0000000C) The way of reading in Auto mode (command register + A) */ + __IOM uint32_t QSPIC2_BURSTCMDB_REG; /*!< (@ 0x00000010) The way of reading in Auto mode (command register + B) */ + __IOM uint32_t QSPIC2_STATUS_REG; /*!< (@ 0x00000014) The status register of the QSPI controller */ + __IOM uint32_t QSPIC2_WRITEDATA_REG; /*!< (@ 0x00000018) Write data to SPI Bus for the Manual mode */ + __IOM uint32_t QSPIC2_READDATA_REG; /*!< (@ 0x0000001C) Read data from SPI Bus for the Manual mode */ + __IOM uint32_t QSPIC2_DUMMYDATA_REG; /*!< (@ 0x00000020) Send dummy clocks to SPI Bus for the Manual mode */ + __IOM uint32_t QSPIC2_ERASECTRL_REG; /*!< (@ 0x00000024) Erase control register */ + __IOM uint32_t QSPIC2_ERASECMDA_REG; /*!< (@ 0x00000028) The way of erasing in Auto mode (command register + A) */ + __IOM uint32_t QSPIC2_ERASECMDB_REG; /*!< (@ 0x0000002C) The way of erasing in Auto mode (command register + B) */ + __IOM uint32_t QSPIC2_BURSTBRK_REG; /*!< (@ 0x00000030) Read break sequence in Auto mode */ + __IOM uint32_t QSPIC2_STATUSCMD_REG; /*!< (@ 0x00000034) The way of reading the status of external device + in Auto mode */ + __IOM uint32_t QSPIC2_CHCKERASE_REG; /*!< (@ 0x00000038) Check erase progress in Auto mode */ + __IOM uint32_t QSPIC2_GP_REG; /*!< (@ 0x0000003C) General purpose QSPIC2 register */ + __IOM uint32_t QSPIC2_AWRITECMD_REG; /*!< (@ 0x00000040) The way of writing in Auto mode when the external + device is a serial SRAM */ + __IOM uint32_t QSPIC2_MEMBLEN_REG; /*!< (@ 0x00000044) External memory burst length configuration */ +} QSPIC2_Type; /*!< Size = 72 (0x48) */ + + + +/* =========================================================================================================================== */ +/* ================ RFMON ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief RFMON registers (RFMON) + */ + +typedef struct { /*!< (@ 0x50040600) RFMON Structure */ + __IOM uint32_t RFMON_CTRL_REG; /*!< (@ 0x00000000) Control register */ + __IOM uint32_t RFMON_ADDR_REG; /*!< (@ 0x00000004) AHB master start address */ + __IOM uint32_t RFMON_LEN_REG; /*!< (@ 0x00000008) Data length register */ + __IOM uint32_t RFMON_STAT_REG; /*!< (@ 0x0000000C) Status register */ + __IOM uint32_t RFMON_CRV_ADDR_REG; /*!< (@ 0x00000010) AHB master current address */ + __IOM uint32_t RFMON_CRV_LEN_REG; /*!< (@ 0x00000014) The remaining data to be transferred */ +} RFMON_Type; /*!< Size = 24 (0x18) */ + + + +/* =========================================================================================================================== */ +/* ================ RTC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief RTC registers (RTC) + */ + +typedef struct { /*!< (@ 0x50000400) RTC Structure */ + __IOM uint32_t RTC_CONTROL_REG; /*!< (@ 0x00000000) RTC Control Register */ + __IOM uint32_t RTC_HOUR_MODE_REG; /*!< (@ 0x00000004) RTC Hour Mode Register */ + __IOM uint32_t RTC_TIME_REG; /*!< (@ 0x00000008) RTC Time Register */ + __IOM uint32_t RTC_CALENDAR_REG; /*!< (@ 0x0000000C) RTC Calendar Register */ + __IOM uint32_t RTC_TIME_ALARM_REG; /*!< (@ 0x00000010) RTC Time Alarm Register */ + __IOM uint32_t RTC_CALENDAR_ALARM_REG; /*!< (@ 0x00000014) RTC Calendar Alram Register */ + __IOM uint32_t RTC_ALARM_ENABLE_REG; /*!< (@ 0x00000018) RTC Alarm Enable Register */ + __IOM uint32_t RTC_EVENT_FLAGS_REG; /*!< (@ 0x0000001C) RTC Event Flags Register */ + __IOM uint32_t RTC_INTERRUPT_ENABLE_REG; /*!< (@ 0x00000020) RTC Interrupt Enable Register */ + __IOM uint32_t RTC_INTERRUPT_DISABLE_REG; /*!< (@ 0x00000024) RTC Interrupt Disable Register */ + __IOM uint32_t RTC_INTERRUPT_MASK_REG; /*!< (@ 0x00000028) RTC Interrupt Mask Register */ + __IOM uint32_t RTC_STATUS_REG; /*!< (@ 0x0000002C) RTC Status Register */ + __IOM uint32_t RTC_KEEP_RTC_REG; /*!< (@ 0x00000030) RTC Keep RTC Register */ + __IM uint32_t RESERVED[19]; + __IOM uint32_t RTC_EVENT_CTRL_REG; /*!< (@ 0x00000080) RTC Event Control Register */ + __IOM uint32_t RTC_MOTOR_EVENT_PERIOD_REG; /*!< (@ 0x00000084) RTC Motor Event Period Register */ + __IOM uint32_t RTC_PDC_EVENT_PERIOD_REG; /*!< (@ 0x00000088) RTC PDC Event Period Register */ + __IOM uint32_t RTC_PDC_EVENT_CLEAR_REG; /*!< (@ 0x0000008C) RTC PDC Event Clear Register */ + __IOM uint32_t RTC_MOTOR_EVENT_CNT_REG; /*!< (@ 0x00000090) RTC Motor Event Counter Register */ + __IOM uint32_t RTC_PDC_EVENT_CNT_REG; /*!< (@ 0x00000094) RTC PDC Event Counter Register */ +} RTC_Type; /*!< Size = 152 (0x98) */ + + + +/* =========================================================================================================================== */ +/* ================ SDADC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief SDADC registers (SDADC) + */ + +typedef struct { /*!< (@ 0x50020800) SDADC Structure */ + __IOM uint32_t SDADC_CTRL_REG; /*!< (@ 0x00000000) Sigma Delta ADC Control Register */ + __IM uint32_t RESERVED; + __IOM uint32_t SDADC_TEST_REG; /*!< (@ 0x00000008) Sigma Delta ADC Test Register */ + __IOM uint32_t SDADC_GAIN_CORR_REG; /*!< (@ 0x0000000C) Sigma Delta ADC Gain Correction Register */ + __IOM uint32_t SDADC_OFFS_CORR_REG; /*!< (@ 0x00000010) Sigma Delta ADC Offset Correction Register */ + __IOM uint32_t SDADC_CLEAR_INT_REG; /*!< (@ 0x00000014) Sigma Delta ADC Clear Interrupt Register */ + __IOM uint32_t SDADC_RESULT_REG; /*!< (@ 0x00000018) Sigma Delta ADC Result Register */ +} SDADC_Type; /*!< Size = 28 (0x1c) */ + + + +/* =========================================================================================================================== */ +/* ================ SMOTOR ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief SMOTOR registers (SMOTOR) + */ + +typedef struct { /*!< (@ 0x50030E00) SMOTOR Structure */ + __IOM uint32_t SMOTOR_CTRL_REG; /*!< (@ 0x00000000) Motor control register */ + __IOM uint32_t PG0_CTRL_REG; /*!< (@ 0x00000004) Pattern generator 0 control register */ + __IOM uint32_t PG1_CTRL_REG; /*!< (@ 0x00000008) Pattern generator 1 control register */ + __IOM uint32_t PG2_CTRL_REG; /*!< (@ 0x0000000C) Pattern generator 2 control register */ + __IOM uint32_t PG3_CTRL_REG; /*!< (@ 0x00000010) Pattern generator 3 control register */ + __IOM uint32_t PG4_CTRL_REG; /*!< (@ 0x00000014) Pattern generator 4 control register */ + __IOM uint32_t SMOTOR_TRIGGER_REG; /*!< (@ 0x00000018) Motor controller trigger register */ + __IM uint32_t RESERVED; + __IOM uint32_t SMOTOR_CMD_FIFO_REG; /*!< (@ 0x00000020) Motor control command FIFO register */ + __IOM uint32_t SMOTOR_CMD_READ_PTR_REG; /*!< (@ 0x00000024) Command read pointer register */ + __IOM uint32_t SMOTOR_CMD_WRITE_PTR_REG; /*!< (@ 0x00000028) Command write pointer register */ + __IOM uint32_t SMOTOR_STATUS_REG; /*!< (@ 0x0000002C) Motor controller status register */ + __IOM uint32_t SMOTOR_IRQ_CLEAR_REG; /*!< (@ 0x00000030) Motor control IRQ clear register */ + __IM uint32_t RESERVED1[3]; + __IOM uint32_t WAVETABLE_BASE; /*!< (@ 0x00000040) Base address of the wavetable */ + __IM uint32_t RESERVED2[15]; + __IOM uint32_t CMD_TABLE_BASE; /*!< (@ 0x00000080) Base address of the command table */ +} SMOTOR_Type; /*!< Size = 132 (0x84) */ + + + +/* =========================================================================================================================== */ +/* ================ SNC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief SNC registers (SNC) + */ + +typedef struct { /*!< (@ 0x50020C00) SNC Structure */ + __IOM uint32_t SNC_CTRL_REG; /*!< (@ 0x00000000) Sensor Node Control Register */ + __IOM uint32_t SNC_STATUS_REG; /*!< (@ 0x00000004) Sensor Node Status Register */ + __IOM uint32_t SNC_LP_TIMER_REG; /*!< (@ 0x00000008) Sensor Node Low-Power Timer Register */ + __IOM uint32_t SNC_PC_REG; /*!< (@ 0x0000000C) Sensor Node Program Counter */ + __IOM uint32_t SNC_R1_REG; /*!< (@ 0x00000010) Sensor Node core - Operand 1 Register */ + __IOM uint32_t SNC_R2_REG; /*!< (@ 0x00000014) Sensor Node core - Operand 2 Register */ + __IOM uint32_t SNC_TMP1_REG; /*!< (@ 0x00000018) Sensor Node core - Temporary Register 1 */ + __IOM uint32_t SNC_TMP2_REG; /*!< (@ 0x0000001C) Sensor Node core - Temporary Register 2 */ +} SNC_Type; /*!< Size = 32 (0x20) */ + + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief SPI registers (SPI) + */ + +typedef struct { /*!< (@ 0x50020300) SPI Structure */ + __IOM uint32_t SPI_CTRL_REG; /*!< (@ 0x00000000) SPI control register 0 */ + __IOM uint32_t SPI_RX_TX_REG; /*!< (@ 0x00000004) SPI RX/TX register0 */ + __IOM uint32_t SPI_CLEAR_INT_REG; /*!< (@ 0x00000008) SPI clear interrupt register */ +} SPI_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ SPI2 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief SPI2 registers (SPI2) + */ + +typedef struct { /*!< (@ 0x50020400) SPI2 Structure */ + __IOM uint32_t SPI2_CTRL_REG; /*!< (@ 0x00000000) SPI control register 0 */ + __IOM uint32_t SPI2_RX_TX_REG; /*!< (@ 0x00000004) SPI RX/TX register0 */ + __IOM uint32_t SPI2_CLEAR_INT_REG; /*!< (@ 0x00000008) SPI clear interrupt register */ +} SPI2_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ SYS_WDOG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief SYS_WDOG registers (SYS_WDOG) + */ + +typedef struct { /*!< (@ 0x50000700) SYS_WDOG Structure */ + __IOM uint32_t WATCHDOG_REG; /*!< (@ 0x00000000) Watchdog timer register. */ + __IOM uint32_t WATCHDOG_CTRL_REG; /*!< (@ 0x00000004) Watchdog control register. */ +} SYS_WDOG_Type; /*!< Size = 8 (0x8) */ + + + +/* =========================================================================================================================== */ +/* ================ TIMER ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief TIMER registers (TIMER) + */ + +typedef struct { /*!< (@ 0x50010200) TIMER Structure */ + __IOM uint32_t TIMER_CTRL_REG; /*!< (@ 0x00000000) Timer control register */ + __IOM uint32_t TIMER_TIMER_VAL_REG; /*!< (@ 0x00000004) Timer counter value */ + __IOM uint32_t TIMER_STATUS_REG; /*!< (@ 0x00000008) Timer status register */ + __IOM uint32_t TIMER_GPIO1_CONF_REG; /*!< (@ 0x0000000C) Timer gpio1 selection */ + __IOM uint32_t TIMER_GPIO2_CONF_REG; /*!< (@ 0x00000010) Timer gpio2 selection */ + __IOM uint32_t TIMER_RELOAD_REG; /*!< (@ 0x00000014) Timer reload value and Delay in shot mode */ + __IOM uint32_t TIMER_SHOTWIDTH_REG; /*!< (@ 0x00000018) Timer Shot duration in shot mode */ + __IOM uint32_t TIMER_PRESCALER_REG; /*!< (@ 0x0000001C) Timer prescaler value */ + __IOM uint32_t TIMER_CAPTURE_GPIO1_REG; /*!< (@ 0x00000020) Timer value for event on GPIO1 */ + __IOM uint32_t TIMER_CAPTURE_GPIO2_REG; /*!< (@ 0x00000024) Timer value for event on GPIO2 */ + __IOM uint32_t TIMER_PRESCALER_VAL_REG; /*!< (@ 0x00000028) Timer prescaler counter valuew */ + __IOM uint32_t TIMER_PWM_FREQ_REG; /*!< (@ 0x0000002C) Timer pwm frequency register */ + __IOM uint32_t TIMER_PWM_DC_REG; /*!< (@ 0x00000030) Timer pwm dc register */ + __IOM uint32_t TIMER_GPIO3_CONF_REG; /*!< (@ 0x00000034) Timer gpio3 selection */ + __IOM uint32_t TIMER_GPIO4_CONF_REG; /*!< (@ 0x00000038) Timer gpio4 selection */ + __IOM uint32_t TIMER_CAPTURE_GPIO3_REG; /*!< (@ 0x0000003C) Timer value for event on GPIO1 */ + __IOM uint32_t TIMER_CAPTURE_GPIO4_REG; /*!< (@ 0x00000040) Timer value for event on GPIO1 */ + __IOM uint32_t TIMER_CLEAR_GPIO_EVENT_REG; /*!< (@ 0x00000044) Timer clear gpio event register */ + __IOM uint32_t TIMER_CLEAR_IRQ_REG; /*!< (@ 0x00000048) Timer clear interrupt */ +} TIMER_Type; /*!< Size = 76 (0x4c) */ + + + +/* =========================================================================================================================== */ +/* ================ TIMER2 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief TIMER2 registers (TIMER2) + */ + +typedef struct { /*!< (@ 0x50010300) TIMER2 Structure */ + __IOM uint32_t TIMER2_CTRL_REG; /*!< (@ 0x00000000) Timer control register */ + __IOM uint32_t TIMER2_TIMER_VAL_REG; /*!< (@ 0x00000004) Timer counter value */ + __IOM uint32_t TIMER2_STATUS_REG; /*!< (@ 0x00000008) Timer status register */ + __IOM uint32_t TIMER2_GPIO1_CONF_REG; /*!< (@ 0x0000000C) Timer gpio1 selection */ + __IOM uint32_t TIMER2_GPIO2_CONF_REG; /*!< (@ 0x00000010) Timer gpio2 selection */ + __IOM uint32_t TIMER2_RELOAD_REG; /*!< (@ 0x00000014) Timer reload value and Delay in shot mode */ + __IOM uint32_t TIMER2_SHOTWIDTH_REG; /*!< (@ 0x00000018) Timer Shot duration in shot mode */ + __IOM uint32_t TIMER2_PRESCALER_REG; /*!< (@ 0x0000001C) Timer prescaler value */ + __IOM uint32_t TIMER2_CAPTURE_GPIO1_REG; /*!< (@ 0x00000020) Timer value for event on GPIO1 */ + __IOM uint32_t TIMER2_CAPTURE_GPIO2_REG; /*!< (@ 0x00000024) Timer value for event on GPIO2 */ + __IOM uint32_t TIMER2_PRESCALER_VAL_REG; /*!< (@ 0x00000028) Timer prescaler counter valuew */ + __IOM uint32_t TIMER2_PWM_FREQ_REG; /*!< (@ 0x0000002C) Timer pwm frequency register */ + __IOM uint32_t TIMER2_PWM_DC_REG; /*!< (@ 0x00000030) Timer pwm dc register */ + __IOM uint32_t TIMER2_CLEAR_IRQ_REG; /*!< (@ 0x00000034) Timer clear interrupt */ +} TIMER2_Type; /*!< Size = 56 (0x38) */ + + + +/* =========================================================================================================================== */ +/* ================ TIMER3 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief TIMER3 registers (TIMER3) + */ + +typedef struct { /*!< (@ 0x50040A00) TIMER3 Structure */ + __IOM uint32_t TIMER3_CTRL_REG; /*!< (@ 0x00000000) Timer control register */ + __IOM uint32_t TIMER3_TIMER_VAL_REG; /*!< (@ 0x00000004) Timer counter value */ + __IOM uint32_t TIMER3_STATUS_REG; /*!< (@ 0x00000008) Timer status register */ + __IOM uint32_t TIMER3_GPIO1_CONF_REG; /*!< (@ 0x0000000C) Timer gpio1 selection */ + __IOM uint32_t TIMER3_GPIO2_CONF_REG; /*!< (@ 0x00000010) Timer gpio2 selection */ + __IOM uint32_t TIMER3_RELOAD_REG; /*!< (@ 0x00000014) Timer reload value and Delay in shot mode */ + __IM uint32_t RESERVED; + __IOM uint32_t TIMER3_PRESCALER_REG; /*!< (@ 0x0000001C) Timer prescaler value */ + __IOM uint32_t TIMER3_CAPTURE_GPIO1_REG; /*!< (@ 0x00000020) Timer value for event on GPIO1 */ + __IOM uint32_t TIMER3_CAPTURE_GPIO2_REG; /*!< (@ 0x00000024) Timer value for event on GPIO2 */ + __IOM uint32_t TIMER3_PRESCALER_VAL_REG; /*!< (@ 0x00000028) Timer prescaler counter valuew */ + __IOM uint32_t TIMER3_PWM_FREQ_REG; /*!< (@ 0x0000002C) Timer pwm frequency register */ + __IOM uint32_t TIMER3_PWM_DC_REG; /*!< (@ 0x00000030) Timer pwm dc register */ + __IOM uint32_t TIMER3_CLEAR_IRQ_REG; /*!< (@ 0x00000034) Timer clear interrupt */ +} TIMER3_Type; /*!< Size = 56 (0x38) */ + + + +/* =========================================================================================================================== */ +/* ================ TIMER4 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief TIMER4 registers (TIMER4) + */ + +typedef struct { /*!< (@ 0x50040B00) TIMER4 Structure */ + __IOM uint32_t TIMER4_CTRL_REG; /*!< (@ 0x00000000) Timer control register */ + __IOM uint32_t TIMER4_TIMER_VAL_REG; /*!< (@ 0x00000004) Timer counter value */ + __IOM uint32_t TIMER4_STATUS_REG; /*!< (@ 0x00000008) Timer status register */ + __IOM uint32_t TIMER4_GPIO1_CONF_REG; /*!< (@ 0x0000000C) Timer gpio1 selection */ + __IOM uint32_t TIMER4_GPIO2_CONF_REG; /*!< (@ 0x00000010) Timer gpio2 selection */ + __IOM uint32_t TIMER4_RELOAD_REG; /*!< (@ 0x00000014) Timer reload value and Delay in shot mode */ + __IM uint32_t RESERVED; + __IOM uint32_t TIMER4_PRESCALER_REG; /*!< (@ 0x0000001C) Timer prescaler value */ + __IOM uint32_t TIMER4_CAPTURE_GPIO1_REG; /*!< (@ 0x00000020) Timer value for event on GPIO1 */ + __IOM uint32_t TIMER4_CAPTURE_GPIO2_REG; /*!< (@ 0x00000024) Timer value for event on GPIO2 */ + __IOM uint32_t TIMER4_PRESCALER_VAL_REG; /*!< (@ 0x00000028) Timer prescaler counter valuew */ + __IOM uint32_t TIMER4_PWM_FREQ_REG; /*!< (@ 0x0000002C) Timer pwm frequency register */ + __IOM uint32_t TIMER4_PWM_DC_REG; /*!< (@ 0x00000030) Timer pwm dc register */ + __IOM uint32_t TIMER4_CLEAR_IRQ_REG; /*!< (@ 0x00000034) Timer clear interrupt */ +} TIMER4_Type; /*!< Size = 56 (0x38) */ + + + +/* =========================================================================================================================== */ +/* ================ TRNG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief TRNG registers (TRNG) + */ + +typedef struct { /*!< (@ 0x50040C00) TRNG Structure */ + __IOM uint32_t TRNG_CTRL_REG; /*!< (@ 0x00000000) TRNG control register */ + __IOM uint32_t TRNG_FIFOLVL_REG; /*!< (@ 0x00000004) TRNG FIFO level register */ + __IOM uint32_t TRNG_VER_REG; /*!< (@ 0x00000008) TRNG Version register */ +} TRNG_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief UART registers (UART) + */ + +typedef struct { /*!< (@ 0x50020000) UART Structure */ + __IOM uint32_t UART_RBR_THR_DLL_REG; /*!< (@ 0x00000000) Receive Buffer Register */ + __IOM uint32_t UART_IER_DLH_REG; /*!< (@ 0x00000004) Interrupt Enable Register */ + __IOM uint32_t UART_IIR_FCR_REG; /*!< (@ 0x00000008) Interrupt Identification Register/FIFO Control + Register */ + __IOM uint32_t UART_LCR_REG; /*!< (@ 0x0000000C) Line Control Register */ + __IOM uint32_t UART_MCR_REG; /*!< (@ 0x00000010) Modem Control Register */ + __IOM uint32_t UART_LSR_REG; /*!< (@ 0x00000014) Line Status Register */ + __IM uint32_t RESERVED; + __IOM uint32_t UART_SCR_REG; /*!< (@ 0x0000001C) Scratchpad Register */ + __IM uint32_t RESERVED1[4]; + __IOM uint32_t UART_SRBR_STHR0_REG; /*!< (@ 0x00000030) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR1_REG; /*!< (@ 0x00000034) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR2_REG; /*!< (@ 0x00000038) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR3_REG; /*!< (@ 0x0000003C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR4_REG; /*!< (@ 0x00000040) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR5_REG; /*!< (@ 0x00000044) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR6_REG; /*!< (@ 0x00000048) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR7_REG; /*!< (@ 0x0000004C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR8_REG; /*!< (@ 0x00000050) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR9_REG; /*!< (@ 0x00000054) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR10_REG; /*!< (@ 0x00000058) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR11_REG; /*!< (@ 0x0000005C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR12_REG; /*!< (@ 0x00000060) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR13_REG; /*!< (@ 0x00000064) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR14_REG; /*!< (@ 0x00000068) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART_SRBR_STHR15_REG; /*!< (@ 0x0000006C) Shadow Receive/Transmit Buffer Register */ + __IM uint32_t RESERVED2[3]; + __IOM uint32_t UART_USR_REG; /*!< (@ 0x0000007C) UART Status register. */ + __IOM uint32_t UART_TFL_REG; /*!< (@ 0x00000080) Transmit FIFO Level */ + __IOM uint32_t UART_RFL_REG; /*!< (@ 0x00000084) Receive FIFO Level. */ + __IOM uint32_t UART_SRR_REG; /*!< (@ 0x00000088) Software Reset Register. */ + __IM uint32_t RESERVED3; + __IOM uint32_t UART_SBCR_REG; /*!< (@ 0x00000090) Shadow Break Control Register */ + __IOM uint32_t UART_SDMAM_REG; /*!< (@ 0x00000094) Shadow DMA Mode */ + __IOM uint32_t UART_SFE_REG; /*!< (@ 0x00000098) Shadow FIFO Enable */ + __IOM uint32_t UART_SRT_REG; /*!< (@ 0x0000009C) Shadow RCVR Trigger */ + __IOM uint32_t UART_STET_REG; /*!< (@ 0x000000A0) Shadow TX Empty Trigger */ + __IOM uint32_t UART_HTX_REG; /*!< (@ 0x000000A4) Halt TX */ + __IOM uint32_t UART_DMASA_REG; /*!< (@ 0x000000A8) DMA Software Acknowledge */ + __IM uint32_t RESERVED4[5]; + __IOM uint32_t UART_DLF_REG; /*!< (@ 0x000000C0) Divisor Latch Fraction Register */ + __IM uint32_t RESERVED5[13]; + __IOM uint32_t UART_UCV_REG; /*!< (@ 0x000000F8) Component Version */ + __IOM uint32_t UART_CTR_REG; /*!< (@ 0x000000FC) Component Type Register */ +} UART_Type; /*!< Size = 256 (0x100) */ + + + +/* =========================================================================================================================== */ +/* ================ UART2 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief UART2 registers (UART2) + */ + +typedef struct { /*!< (@ 0x50020100) UART2 Structure */ + __IOM uint32_t UART2_RBR_THR_DLL_REG; /*!< (@ 0x00000000) Receive Buffer Register */ + __IOM uint32_t UART2_IER_DLH_REG; /*!< (@ 0x00000004) Interrupt Enable Register */ + __IOM uint32_t UART2_IIR_FCR_REG; /*!< (@ 0x00000008) Interrupt Identification Register/FIFO Control + Register */ + __IOM uint32_t UART2_LCR_REG; /*!< (@ 0x0000000C) Line Control Register */ + __IOM uint32_t UART2_MCR_REG; /*!< (@ 0x00000010) Modem Control Register */ + __IOM uint32_t UART2_LSR_REG; /*!< (@ 0x00000014) Line Status Register */ + __IOM uint32_t UART2_MSR_REG; /*!< (@ 0x00000018) Modem Status Register */ + __IOM uint32_t UART2_SCR_REG; /*!< (@ 0x0000001C) Scratchpad Register */ + __IM uint32_t RESERVED[4]; + __IOM uint32_t UART2_SRBR_STHR0_REG; /*!< (@ 0x00000030) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR1_REG; /*!< (@ 0x00000034) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR2_REG; /*!< (@ 0x00000038) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR3_REG; /*!< (@ 0x0000003C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR4_REG; /*!< (@ 0x00000040) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR5_REG; /*!< (@ 0x00000044) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR6_REG; /*!< (@ 0x00000048) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR7_REG; /*!< (@ 0x0000004C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR8_REG; /*!< (@ 0x00000050) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR9_REG; /*!< (@ 0x00000054) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR10_REG; /*!< (@ 0x00000058) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR11_REG; /*!< (@ 0x0000005C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR12_REG; /*!< (@ 0x00000060) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR13_REG; /*!< (@ 0x00000064) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR14_REG; /*!< (@ 0x00000068) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART2_SRBR_STHR15_REG; /*!< (@ 0x0000006C) Shadow Receive/Transmit Buffer Register */ + __IM uint32_t RESERVED1[3]; + __IOM uint32_t UART2_USR_REG; /*!< (@ 0x0000007C) UART Status register. */ + __IOM uint32_t UART2_TFL_REG; /*!< (@ 0x00000080) Transmit FIFO Level */ + __IOM uint32_t UART2_RFL_REG; /*!< (@ 0x00000084) Receive FIFO Level. */ + __IOM uint32_t UART2_SRR_REG; /*!< (@ 0x00000088) Software Reset Register. */ + __IOM uint32_t UART2_SRTS_REG; /*!< (@ 0x0000008C) Shadow Request to Send */ + __IOM uint32_t UART2_SBCR_REG; /*!< (@ 0x00000090) Shadow Break Control Register */ + __IOM uint32_t UART2_SDMAM_REG; /*!< (@ 0x00000094) Shadow DMA Mode */ + __IOM uint32_t UART2_SFE_REG; /*!< (@ 0x00000098) Shadow FIFO Enable */ + __IOM uint32_t UART2_SRT_REG; /*!< (@ 0x0000009C) Shadow RCVR Trigger */ + __IOM uint32_t UART2_STET_REG; /*!< (@ 0x000000A0) Shadow TX Empty Trigger */ + __IOM uint32_t UART2_HTX_REG; /*!< (@ 0x000000A4) Halt TX */ + __IOM uint32_t UART2_DMASA_REG; /*!< (@ 0x000000A8) DMA Software Acknowledge */ + __IM uint32_t RESERVED2[5]; + __IOM uint32_t UART2_DLF_REG; /*!< (@ 0x000000C0) Divisor Latch Fraction Register */ + __IOM uint32_t UART2_RAR_REG; /*!< (@ 0x000000C4) Receive Address Register */ + __IOM uint32_t UART2_TAR_REG; /*!< (@ 0x000000C8) Transmit Address Register */ + __IOM uint32_t UART2_LCR_EXT; /*!< (@ 0x000000CC) Line Extended Control Register */ + __IM uint32_t RESERVED3[10]; + __IOM uint32_t UART2_UCV_REG; /*!< (@ 0x000000F8) Component Version */ + __IOM uint32_t UART2_CTR_REG; /*!< (@ 0x000000FC) Component Type Register */ +} UART2_Type; /*!< Size = 256 (0x100) */ + + + +/* =========================================================================================================================== */ +/* ================ UART3 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief UART3 registers (UART3) + */ + +typedef struct { /*!< (@ 0x50020200) UART3 Structure */ + __IOM uint32_t UART3_RBR_THR_DLL_REG; /*!< (@ 0x00000000) Receive Buffer Register */ + __IOM uint32_t UART3_IER_DLH_REG; /*!< (@ 0x00000004) Interrupt Enable Register */ + __IOM uint32_t UART3_IIR_FCR_REG; /*!< (@ 0x00000008) Interrupt Identification Register/FIFO Control + Register */ + __IOM uint32_t UART3_LCR_REG; /*!< (@ 0x0000000C) Line Control Register */ + __IOM uint32_t UART3_MCR_REG; /*!< (@ 0x00000010) Modem Control Register */ + __IOM uint32_t UART3_LSR_REG; /*!< (@ 0x00000014) Line Status Register */ + __IOM uint32_t UART3_MSR_REG; /*!< (@ 0x00000018) Modem Status Register */ + __IOM uint32_t UART3_CONFIG_REG; /*!< (@ 0x0000001C) ISO7816 Config Register */ + __IM uint32_t RESERVED[4]; + __IOM uint32_t UART3_SRBR_STHR0_REG; /*!< (@ 0x00000030) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR1_REG; /*!< (@ 0x00000034) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR2_REG; /*!< (@ 0x00000038) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR3_REG; /*!< (@ 0x0000003C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR4_REG; /*!< (@ 0x00000040) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR5_REG; /*!< (@ 0x00000044) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR6_REG; /*!< (@ 0x00000048) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR7_REG; /*!< (@ 0x0000004C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR8_REG; /*!< (@ 0x00000050) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR9_REG; /*!< (@ 0x00000054) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR10_REG; /*!< (@ 0x00000058) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR11_REG; /*!< (@ 0x0000005C) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR12_REG; /*!< (@ 0x00000060) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR13_REG; /*!< (@ 0x00000064) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR14_REG; /*!< (@ 0x00000068) Shadow Receive/Transmit Buffer Register */ + __IOM uint32_t UART3_SRBR_STHR15_REG; /*!< (@ 0x0000006C) Shadow Receive/Transmit Buffer Register */ + __IM uint32_t RESERVED1[3]; + __IOM uint32_t UART3_USR_REG; /*!< (@ 0x0000007C) UART Status register. */ + __IOM uint32_t UART3_TFL_REG; /*!< (@ 0x00000080) Transmit FIFO Level */ + __IOM uint32_t UART3_RFL_REG; /*!< (@ 0x00000084) Receive FIFO Level. */ + __IOM uint32_t UART3_SRR_REG; /*!< (@ 0x00000088) Software Reset Register. */ + __IOM uint32_t UART3_SRTS_REG; /*!< (@ 0x0000008C) Shadow Request to Send */ + __IOM uint32_t UART3_SBCR_REG; /*!< (@ 0x00000090) Shadow Break Control Register */ + __IOM uint32_t UART3_SDMAM_REG; /*!< (@ 0x00000094) Shadow DMA Mode */ + __IOM uint32_t UART3_SFE_REG; /*!< (@ 0x00000098) Shadow FIFO Enable */ + __IOM uint32_t UART3_SRT_REG; /*!< (@ 0x0000009C) Shadow RCVR Trigger */ + __IOM uint32_t UART3_STET_REG; /*!< (@ 0x000000A0) Shadow TX Empty Trigger */ + __IOM uint32_t UART3_HTX_REG; /*!< (@ 0x000000A4) Halt TX */ + __IOM uint32_t UART3_DMASA_REG; /*!< (@ 0x000000A8) DMA Software Acknowledge */ + __IM uint32_t RESERVED2[5]; + __IOM uint32_t UART3_DLF_REG; /*!< (@ 0x000000C0) Divisor Latch Fraction Register */ + __IOM uint32_t UART3_RAR_REG; /*!< (@ 0x000000C4) Receive Address Register */ + __IOM uint32_t UART3_TAR_REG; /*!< (@ 0x000000C8) Transmit Address Register */ + __IOM uint32_t UART3_LCR_EXT; /*!< (@ 0x000000CC) Line Extended Control Register */ + __IM uint32_t RESERVED3[4]; + __IOM uint32_t UART3_CTRL_REG; /*!< (@ 0x000000E0) ISO7816 Control Register */ + __IOM uint32_t UART3_TIMER_REG; /*!< (@ 0x000000E4) ISO7816 Timer Register */ + __IOM uint32_t UART3_ERR_CTRL_REG; /*!< (@ 0x000000E8) ISO7816 Error Signal Control Register */ + __IOM uint32_t UART3_IRQ_STATUS_REG; /*!< (@ 0x000000EC) ISO7816 Interrupt Status Register */ + __IM uint32_t RESERVED4[2]; + __IOM uint32_t UART3_UCV_REG; /*!< (@ 0x000000F8) Component Version */ + __IOM uint32_t UART3_CTR_REG; /*!< (@ 0x000000FC) Component Type Register */ +} UART3_Type; /*!< Size = 256 (0x100) */ + + + +/* =========================================================================================================================== */ +/* ================ USB ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief USB registers (USB) + */ + +typedef struct { /*!< (@ 0x50040000) USB Structure */ + __IOM uint32_t USB_MCTRL_REG; /*!< (@ 0x00000000) Main Control Register) */ + __IOM uint32_t USB_XCVDIAG_REG; /*!< (@ 0x00000004) Transceiver diagnostic Register (for test purpose + only) */ + __IOM uint32_t USB_TCR_REG; /*!< (@ 0x00000008) Transceiver configuration Register */ + __IOM uint32_t USB_UTR_REG; /*!< (@ 0x0000000C) USB test Register (for test purpose only) */ + __IOM uint32_t USB_FAR_REG; /*!< (@ 0x00000010) Function Address Register */ + __IOM uint32_t USB_NFSR_REG; /*!< (@ 0x00000014) Node Functional State Register */ + __IOM uint32_t USB_MAEV_REG; /*!< (@ 0x00000018) Main Event Register */ + __IOM uint32_t USB_MAMSK_REG; /*!< (@ 0x0000001C) Main Mask Register */ + __IOM uint32_t USB_ALTEV_REG; /*!< (@ 0x00000020) Alternate Event Register */ + __IOM uint32_t USB_ALTMSK_REG; /*!< (@ 0x00000024) Alternate Mask Register */ + __IOM uint32_t USB_TXEV_REG; /*!< (@ 0x00000028) Transmit Event Register */ + __IOM uint32_t USB_TXMSK_REG; /*!< (@ 0x0000002C) Transmit Mask Register */ + __IOM uint32_t USB_RXEV_REG; /*!< (@ 0x00000030) Receive Event Register */ + __IOM uint32_t USB_RXMSK_REG; /*!< (@ 0x00000034) Receive Mask Register */ + __IOM uint32_t USB_NAKEV_REG; /*!< (@ 0x00000038) NAK Event Register */ + __IOM uint32_t USB_NAKMSK_REG; /*!< (@ 0x0000003C) NAK Mask Register */ + __IOM uint32_t USB_FWEV_REG; /*!< (@ 0x00000040) FIFO Warning Event Register */ + __IOM uint32_t USB_FWMSK_REG; /*!< (@ 0x00000044) FIFO Warning Mask Register */ + __IOM uint32_t USB_FNH_REG; /*!< (@ 0x00000048) Frame Number High Byte Register */ + __IOM uint32_t USB_FNL_REG; /*!< (@ 0x0000004C) Frame Number Low Byte Register */ + __IM uint32_t RESERVED[11]; + __IOM uint32_t USB_UX20CDR_REG; /*!< (@ 0x0000007C) Transceiver 2.0 Configuration and Diagnostics + Register(for test purpose only) */ + __IOM uint32_t USB_EPC0_REG; /*!< (@ 0x00000080) Endpoint Control 0 Register */ + __IOM uint32_t USB_TXD0_REG; /*!< (@ 0x00000084) Transmit Data 0 Register */ + __IOM uint32_t USB_TXS0_REG; /*!< (@ 0x00000088) Transmit Status 0 Register */ + __IOM uint32_t USB_TXC0_REG; /*!< (@ 0x0000008C) Transmit command 0 Register */ + __IOM uint32_t USB_EP0_NAK_REG; /*!< (@ 0x00000090) EP0 INNAK and OUTNAK Register */ + __IOM uint32_t USB_RXD0_REG; /*!< (@ 0x00000094) Receive Data 0 Register */ + __IOM uint32_t USB_RXS0_REG; /*!< (@ 0x00000098) Receive Status 0 Register */ + __IOM uint32_t USB_RXC0_REG; /*!< (@ 0x0000009C) Receive Command 0 Register */ + __IOM uint32_t USB_EPC1_REG; /*!< (@ 0x000000A0) Endpoint Control Register 1 */ + __IOM uint32_t USB_TXD1_REG; /*!< (@ 0x000000A4) Transmit Data Register 1 */ + __IOM uint32_t USB_TXS1_REG; /*!< (@ 0x000000A8) Transmit Status Register 1 */ + __IOM uint32_t USB_TXC1_REG; /*!< (@ 0x000000AC) Transmit Command Register 1 */ + __IOM uint32_t USB_EPC2_REG; /*!< (@ 0x000000B0) Endpoint Control Register 2 */ + __IOM uint32_t USB_RXD1_REG; /*!< (@ 0x000000B4) Receive Data Register,1 */ + __IOM uint32_t USB_RXS1_REG; /*!< (@ 0x000000B8) Receive Status Register 1 */ + __IOM uint32_t USB_RXC1_REG; /*!< (@ 0x000000BC) Receive Command Register 1 */ + __IOM uint32_t USB_EPC3_REG; /*!< (@ 0x000000C0) Endpoint Control Register 3 */ + __IOM uint32_t USB_TXD2_REG; /*!< (@ 0x000000C4) Transmit Data Register 2 */ + __IOM uint32_t USB_TXS2_REG; /*!< (@ 0x000000C8) Transmit Status Register 2 */ + __IOM uint32_t USB_TXC2_REG; /*!< (@ 0x000000CC) Transmit Command Register 2 */ + __IOM uint32_t USB_EPC4_REG; /*!< (@ 0x000000D0) Endpoint Control Register 4 */ + __IOM uint32_t USB_RXD2_REG; /*!< (@ 0x000000D4) Receive Data Register 2 */ + __IOM uint32_t USB_RXS2_REG; /*!< (@ 0x000000D8) Receive Status Register 2 */ + __IOM uint32_t USB_RXC2_REG; /*!< (@ 0x000000DC) Receive Command Register 2 */ + __IOM uint32_t USB_EPC5_REG; /*!< (@ 0x000000E0) Endpoint Control Register 5 */ + __IOM uint32_t USB_TXD3_REG; /*!< (@ 0x000000E4) Transmit Data Register 3 */ + __IOM uint32_t USB_TXS3_REG; /*!< (@ 0x000000E8) Transmit Status Register 3 */ + __IOM uint32_t USB_TXC3_REG; /*!< (@ 0x000000EC) Transmit Command Register 3 */ + __IOM uint32_t USB_EPC6_REG; /*!< (@ 0x000000F0) Endpoint Control Register 6 */ + __IOM uint32_t USB_RXD3_REG; /*!< (@ 0x000000F4) Receive Data Register 3 */ + __IOM uint32_t USB_RXS3_REG; /*!< (@ 0x000000F8) Receive Status Register 3 */ + __IOM uint32_t USB_RXC3_REG; /*!< (@ 0x000000FC) Receive Command Register 3 */ + __IM uint32_t RESERVED1[40]; + __IOM uint32_t USB_DMA_CTRL_REG; /*!< (@ 0x000001A0) USB DMA control register */ + __IM uint32_t RESERVED2; + __IOM uint32_t USB_CHARGER_CTRL_REG; /*!< (@ 0x000001A8) USB Charger Control Register */ + __IOM uint32_t USB_CHARGER_STAT_REG; /*!< (@ 0x000001AC) USB Charger Status Register */ +} USB_Type; /*!< Size = 432 (0x1b0) */ + + + +/* =========================================================================================================================== */ +/* ================ WAKEUP ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief WAKEUP registers (WAKEUP) + */ + +typedef struct { /*!< (@ 0x50000100) WAKEUP Structure */ + __IOM uint32_t WKUP_CTRL_REG; /*!< (@ 0x00000000) Control register for the wakeup counter */ + __IM uint32_t RESERVED; + __IOM uint32_t WKUP_RESET_IRQ_REG; /*!< (@ 0x00000008) Reset wakeup interrupt */ + __IM uint32_t RESERVED1[2]; + __IOM uint32_t WKUP_SELECT_P0_REG; /*!< (@ 0x00000014) select which inputs from P0 port can trigger + wkup counter */ + __IOM uint32_t WKUP_SELECT_P1_REG; /*!< (@ 0x00000018) select which inputs from P1 port can trigger + wkup counter */ + __IM uint32_t RESERVED2[3]; + __IOM uint32_t WKUP_POL_P0_REG; /*!< (@ 0x00000028) select the sesitivity polarity for each P0 input */ + __IOM uint32_t WKUP_POL_P1_REG; /*!< (@ 0x0000002C) select the sesitivity polarity for each P1 input */ + __IM uint32_t RESERVED3[3]; + __IOM uint32_t WKUP_STATUS_P0_REG; /*!< (@ 0x0000003C) Event status register for P0 */ + __IOM uint32_t WKUP_STATUS_P1_REG; /*!< (@ 0x00000040) Event status register for P1 */ + __IM uint32_t RESERVED4; + __IOM uint32_t WKUP_CLEAR_P0_REG; /*!< (@ 0x00000048) Clear event register for P0 */ + __IOM uint32_t WKUP_CLEAR_P1_REG; /*!< (@ 0x0000004C) Clear event register for P1 */ + __IM uint32_t RESERVED5; + __IOM uint32_t WKUP_SEL_GPIO_P0_REG; /*!< (@ 0x00000054) select which inputs from P0 port can trigger + interrupt */ + __IOM uint32_t WKUP_SEL_GPIO_P1_REG; /*!< (@ 0x00000058) select which inputs from P1 port can trigger + interrupt */ +} WAKEUP_Type; /*!< Size = 92 (0x5c) */ + + +/** @} */ /* End of group Device_Peripheral_peripherals */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +#define AES_HASH_BASE 0x30040000UL +#define ANAMISC_BIF_BASE 0x50030B00UL +#define APU_BASE 0x50030600UL +#define CACHE_BASE 0x100C0000UL +#define CHARGER_BASE 0x50040400UL +#define CHIP_VERSION_BASE 0x50040200UL +#define CRG_COM_BASE 0x50020900UL +#define CRG_PER_BASE 0x50030C00UL +#define CRG_SYS_BASE 0x50040500UL +#define CRG_TOP_BASE 0x50000000UL +#define CRG_XTAL_BASE 0x50010000UL +#define DCDC_BASE 0x50000300UL +#define DMA_BASE 0x50040800UL +#define DW_BASE 0x30020000UL +#define GPADC_BASE 0x50030900UL +#define GPIO_BASE 0x50020A00UL +#define GPREG_BASE 0x50040300UL +#define I2C_BASE 0x50020600UL +#define I2C2_BASE 0x50020700UL +#define LCDC_BASE 0x30030000UL +#define LRA_BASE 0x50030A00UL +#define MEMCTRL_BASE 0x50050000UL +#define OTPC_BASE 0x30070000UL +#define PDC_BASE 0x50000200UL +#define PWMLED_BASE 0x50030500UL +#define QSPIC_BASE 0x38000000UL +#define QSPIC2_BASE 0x34000000UL +#define RFMON_BASE 0x50040600UL +#define RTC_BASE 0x50000400UL +#define SDADC_BASE 0x50020800UL +#define SMOTOR_BASE 0x50030E00UL +#define SNC_BASE 0x50020C00UL +#define SPI_BASE 0x50020300UL +#define SPI2_BASE 0x50020400UL +#define SYS_WDOG_BASE 0x50000700UL +#define TIMER_BASE 0x50010200UL +#define TIMER2_BASE 0x50010300UL +#define TIMER3_BASE 0x50040A00UL +#define TIMER4_BASE 0x50040B00UL +#define TRNG_BASE 0x50040C00UL +#define UART_BASE 0x50020000UL +#define UART2_BASE 0x50020100UL +#define UART3_BASE 0x50020200UL +#define USB_BASE 0x50040000UL +#define WAKEUP_BASE 0x50000100UL + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +#define AES_HASH ((AES_HASH_Type*) AES_HASH_BASE) +#define ANAMISC_BIF ((ANAMISC_BIF_Type*) ANAMISC_BIF_BASE) +#define APU ((APU_Type*) APU_BASE) +#define CACHE ((CACHE_Type*) CACHE_BASE) +#define CHARGER ((CHARGER_Type*) CHARGER_BASE) +#define CHIP_VERSION ((CHIP_VERSION_Type*) CHIP_VERSION_BASE) +#define CRG_COM ((CRG_COM_Type*) CRG_COM_BASE) +#define CRG_PER ((CRG_PER_Type*) CRG_PER_BASE) +#define CRG_SYS ((CRG_SYS_Type*) CRG_SYS_BASE) +#define CRG_TOP ((CRG_TOP_Type*) CRG_TOP_BASE) +#define CRG_XTAL ((CRG_XTAL_Type*) CRG_XTAL_BASE) +#define DCDC ((DCDC_Type*) DCDC_BASE) +#define DMA ((DMA_Type*) DMA_BASE) +#define DW ((DW_Type*) DW_BASE) +#define GPADC ((GPADC_Type*) GPADC_BASE) +#define GPIO ((GPIO_Type*) GPIO_BASE) +#define GPREG ((GPREG_Type*) GPREG_BASE) +#define I2C ((I2C_Type*) I2C_BASE) +#define I2C2 ((I2C2_Type*) I2C2_BASE) +#define LCDC ((LCDC_Type*) LCDC_BASE) +#define LRA ((LRA_Type*) LRA_BASE) +#define MEMCTRL ((MEMCTRL_Type*) MEMCTRL_BASE) +#define OTPC ((OTPC_Type*) OTPC_BASE) +#define PDC ((PDC_Type*) PDC_BASE) +#define PWMLED ((PWMLED_Type*) PWMLED_BASE) +#define QSPIC ((QSPIC_Type*) QSPIC_BASE) +#define QSPIC2 ((QSPIC2_Type*) QSPIC2_BASE) +#define RFMON ((RFMON_Type*) RFMON_BASE) +#define RTC ((RTC_Type*) RTC_BASE) +#define SDADC ((SDADC_Type*) SDADC_BASE) +#define SMOTOR ((SMOTOR_Type*) SMOTOR_BASE) +#define SNC ((SNC_Type*) SNC_BASE) +#define SPI ((SPI_Type*) SPI_BASE) +#define SPI2 ((SPI2_Type*) SPI2_BASE) +#define SYS_WDOG ((SYS_WDOG_Type*) SYS_WDOG_BASE) +#define TIMER ((TIMER_Type*) TIMER_BASE) +#define TIMER2 ((TIMER2_Type*) TIMER2_BASE) +#define TIMER3 ((TIMER3_Type*) TIMER3_BASE) +#define TIMER4 ((TIMER4_Type*) TIMER4_BASE) +#define TRNG ((TRNG_Type*) TRNG_BASE) +#define UART ((UART_Type*) UART_BASE) +#define UART2 ((UART2_Type*) UART2_BASE) +#define UART3 ((UART3_Type*) UART3_BASE) +#define USB ((USB_Type*) USB_BASE) +#define WAKEUP ((WAKEUP_Type*) WAKEUP_BASE) + + +/* =========================================================================================================================== */ +/* ================ Pos/Mask Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup PosMask_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ AES_HASH ================ */ +/* =========================================================================================================================== */ + +/* =================================================== CRYPTO_CLRIRQ_REG =================================================== */ +#define AES_HASH_CRYPTO_CLRIRQ_REG_CRYPTO_CLRIRQ_Pos (0UL) /*!< CRYPTO_CLRIRQ (Bit 0) */ +#define AES_HASH_CRYPTO_CLRIRQ_REG_CRYPTO_CLRIRQ_Msk (0x1UL) /*!< CRYPTO_CLRIRQ (Bitfield-Mask: 0x01) */ +/* ==================================================== CRYPTO_CTRL_REG ==================================================== */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEXP_Pos (17UL) /*!< CRYPTO_AES_KEXP (Bit 17) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEXP_Msk (0x20000UL) /*!< CRYPTO_AES_KEXP (Bitfield-Mask: 0x01) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Pos (16UL) /*!< CRYPTO_MORE_IN (Bit 16) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Msk (0x10000UL) /*!< CRYPTO_MORE_IN (Bitfield-Mask: 0x01) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_OUT_LEN_Pos (10UL) /*!< CRYPTO_HASH_OUT_LEN (Bit 10) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_OUT_LEN_Msk (0xfc00UL) /*!< CRYPTO_HASH_OUT_LEN (Bitfield-Mask: 0x3f) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Pos (9UL) /*!< CRYPTO_HASH_SEL (Bit 9) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Msk (0x200UL) /*!< CRYPTO_HASH_SEL (Bitfield-Mask: 0x01) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_IRQ_EN_Pos (8UL) /*!< CRYPTO_IRQ_EN (Bit 8) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_IRQ_EN_Msk (0x100UL) /*!< CRYPTO_IRQ_EN (Bitfield-Mask: 0x01) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ENCDEC_Pos (7UL) /*!< CRYPTO_ENCDEC (Bit 7) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ENCDEC_Msk (0x80UL) /*!< CRYPTO_ENCDEC (Bitfield-Mask: 0x01) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEY_SZ_Pos (5UL) /*!< CRYPTO_AES_KEY_SZ (Bit 5) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEY_SZ_Msk (0x60UL) /*!< CRYPTO_AES_KEY_SZ (Bitfield-Mask: 0x03) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_OUT_MD_Pos (4UL) /*!< CRYPTO_OUT_MD (Bit 4) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_OUT_MD_Msk (0x10UL) /*!< CRYPTO_OUT_MD (Bitfield-Mask: 0x01) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Pos (2UL) /*!< CRYPTO_ALG_MD (Bit 2) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk (0xcUL) /*!< CRYPTO_ALG_MD (Bitfield-Mask: 0x03) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Pos (0UL) /*!< CRYPTO_ALG (Bit 0) */ +#define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Msk (0x3UL) /*!< CRYPTO_ALG (Bitfield-Mask: 0x03) */ +/* ================================================= CRYPTO_DEST_ADDR_REG ================================================== */ +#define AES_HASH_CRYPTO_DEST_ADDR_REG_CRYPTO_DEST_ADDR_Pos (0UL) /*!< CRYPTO_DEST_ADDR (Bit 0) */ +#define AES_HASH_CRYPTO_DEST_ADDR_REG_CRYPTO_DEST_ADDR_Msk (0xffffffffUL) /*!< CRYPTO_DEST_ADDR (Bitfield-Mask: 0xffffffff) */ +/* ================================================= CRYPTO_FETCH_ADDR_REG ================================================= */ +#define AES_HASH_CRYPTO_FETCH_ADDR_REG_CRYPTO_FETCH_ADDR_Pos (0UL) /*!< CRYPTO_FETCH_ADDR (Bit 0) */ +#define AES_HASH_CRYPTO_FETCH_ADDR_REG_CRYPTO_FETCH_ADDR_Msk (0xffffffffUL) /*!< CRYPTO_FETCH_ADDR (Bitfield-Mask: 0xffffffff) */ +/* =================================================== CRYPTO_KEYS_START =================================================== */ +#define AES_HASH_CRYPTO_KEYS_START_CRYPTO_KEY_X_Pos (0UL) /*!< CRYPTO_KEY_X (Bit 0) */ +#define AES_HASH_CRYPTO_KEYS_START_CRYPTO_KEY_X_Msk (0xffffffffUL) /*!< CRYPTO_KEY_X (Bitfield-Mask: 0xffffffff) */ +/* ==================================================== CRYPTO_LEN_REG ===================================================== */ +#define AES_HASH_CRYPTO_LEN_REG_CRYPTO_LEN_Pos (0UL) /*!< CRYPTO_LEN (Bit 0) */ +#define AES_HASH_CRYPTO_LEN_REG_CRYPTO_LEN_Msk (0xffffffUL) /*!< CRYPTO_LEN (Bitfield-Mask: 0xffffff) */ +/* =================================================== CRYPTO_MREG0_REG ==================================================== */ +#define AES_HASH_CRYPTO_MREG0_REG_CRYPTO_MREG0_Pos (0UL) /*!< CRYPTO_MREG0 (Bit 0) */ +#define AES_HASH_CRYPTO_MREG0_REG_CRYPTO_MREG0_Msk (0xffffffffUL) /*!< CRYPTO_MREG0 (Bitfield-Mask: 0xffffffff) */ +/* =================================================== CRYPTO_MREG1_REG ==================================================== */ +#define AES_HASH_CRYPTO_MREG1_REG_CRYPTO_MREG1_Pos (0UL) /*!< CRYPTO_MREG1 (Bit 0) */ +#define AES_HASH_CRYPTO_MREG1_REG_CRYPTO_MREG1_Msk (0xffffffffUL) /*!< CRYPTO_MREG1 (Bitfield-Mask: 0xffffffff) */ +/* =================================================== CRYPTO_MREG2_REG ==================================================== */ +#define AES_HASH_CRYPTO_MREG2_REG_CRYPTO_MREG2_Pos (0UL) /*!< CRYPTO_MREG2 (Bit 0) */ +#define AES_HASH_CRYPTO_MREG2_REG_CRYPTO_MREG2_Msk (0xffffffffUL) /*!< CRYPTO_MREG2 (Bitfield-Mask: 0xffffffff) */ +/* =================================================== CRYPTO_MREG3_REG ==================================================== */ +#define AES_HASH_CRYPTO_MREG3_REG_CRYPTO_MREG3_Pos (0UL) /*!< CRYPTO_MREG3 (Bit 0) */ +#define AES_HASH_CRYPTO_MREG3_REG_CRYPTO_MREG3_Msk (0xffffffffUL) /*!< CRYPTO_MREG3 (Bitfield-Mask: 0xffffffff) */ +/* =================================================== CRYPTO_START_REG ==================================================== */ +#define AES_HASH_CRYPTO_START_REG_CRYPTO_START_Pos (0UL) /*!< CRYPTO_START (Bit 0) */ +#define AES_HASH_CRYPTO_START_REG_CRYPTO_START_Msk (0x1UL) /*!< CRYPTO_START (Bitfield-Mask: 0x01) */ +/* =================================================== CRYPTO_STATUS_REG =================================================== */ +#define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_IRQ_ST_Pos (2UL) /*!< CRYPTO_IRQ_ST (Bit 2) */ +#define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_IRQ_ST_Msk (0x4UL) /*!< CRYPTO_IRQ_ST (Bitfield-Mask: 0x01) */ +#define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_WAIT_FOR_IN_Pos (1UL) /*!< CRYPTO_WAIT_FOR_IN (Bit 1) */ +#define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_WAIT_FOR_IN_Msk (0x2UL) /*!< CRYPTO_WAIT_FOR_IN (Bitfield-Mask: 0x01) */ +#define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_INACTIVE_Pos (0UL) /*!< CRYPTO_INACTIVE (Bit 0) */ +#define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_INACTIVE_Msk (0x1UL) /*!< CRYPTO_INACTIVE (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ ANAMISC_BIF ================ */ +/* =========================================================================================================================== */ + +/* ==================================================== CLK_REF_CNT_REG ==================================================== */ +#define ANAMISC_BIF_CLK_REF_CNT_REG_REF_CNT_VAL_Pos (0UL) /*!< REF_CNT_VAL (Bit 0) */ +#define ANAMISC_BIF_CLK_REF_CNT_REG_REF_CNT_VAL_Msk (0xffffUL) /*!< REF_CNT_VAL (Bitfield-Mask: 0xffff) */ +/* ==================================================== CLK_REF_SEL_REG ==================================================== */ +#define ANAMISC_BIF_CLK_REF_SEL_REG_CAL_CLK_SEL_Pos (5UL) /*!< CAL_CLK_SEL (Bit 5) */ +#define ANAMISC_BIF_CLK_REF_SEL_REG_CAL_CLK_SEL_Msk (0xe0UL) /*!< CAL_CLK_SEL (Bitfield-Mask: 0x07) */ +#define ANAMISC_BIF_CLK_REF_SEL_REG_EXT_CNT_EN_SEL_Pos (4UL) /*!< EXT_CNT_EN_SEL (Bit 4) */ +#define ANAMISC_BIF_CLK_REF_SEL_REG_EXT_CNT_EN_SEL_Msk (0x10UL) /*!< EXT_CNT_EN_SEL (Bitfield-Mask: 0x01) */ +#define ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Pos (3UL) /*!< REF_CAL_START (Bit 3) */ +#define ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Msk (0x8UL) /*!< REF_CAL_START (Bitfield-Mask: 0x01) */ +#define ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Pos (0UL) /*!< REF_CLK_SEL (Bit 0) */ +#define ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Msk (0x7UL) /*!< REF_CLK_SEL (Bitfield-Mask: 0x07) */ +/* ==================================================== CLK_REF_VAL_REG ==================================================== */ +#define ANAMISC_BIF_CLK_REF_VAL_REG_XTAL_CNT_VAL_Pos (0UL) /*!< XTAL_CNT_VAL (Bit 0) */ +#define ANAMISC_BIF_CLK_REF_VAL_REG_XTAL_CNT_VAL_Msk (0xffffffffUL) /*!< XTAL_CNT_VAL (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ APU ================ */ +/* =========================================================================================================================== */ + +/* ====================================================== APU_MUX_REG ====================================================== */ +#define APU_APU_MUX_REG_PDM1_MUX_IN_Pos (6UL) /*!< PDM1_MUX_IN (Bit 6) */ +#define APU_APU_MUX_REG_PDM1_MUX_IN_Msk (0x40UL) /*!< PDM1_MUX_IN (Bitfield-Mask: 0x01) */ +#define APU_APU_MUX_REG_PCM1_MUX_IN_Pos (3UL) /*!< PCM1_MUX_IN (Bit 3) */ +#define APU_APU_MUX_REG_PCM1_MUX_IN_Msk (0x38UL) /*!< PCM1_MUX_IN (Bitfield-Mask: 0x07) */ +#define APU_APU_MUX_REG_SRC1_MUX_IN_Pos (0UL) /*!< SRC1_MUX_IN (Bit 0) */ +#define APU_APU_MUX_REG_SRC1_MUX_IN_Msk (0x7UL) /*!< SRC1_MUX_IN (Bitfield-Mask: 0x07) */ +/* ==================================================== COEF0A_SET1_REG ==================================================== */ +#define APU_COEF0A_SET1_REG_SRC_COEF10_Pos (0UL) /*!< SRC_COEF10 (Bit 0) */ +#define APU_COEF0A_SET1_REG_SRC_COEF10_Msk (0xffffUL) /*!< SRC_COEF10 (Bitfield-Mask: 0xffff) */ +/* ==================================================== COEF10_SET1_REG ==================================================== */ +#define APU_COEF10_SET1_REG_SRC_COEF1_Pos (16UL) /*!< SRC_COEF1 (Bit 16) */ +#define APU_COEF10_SET1_REG_SRC_COEF1_Msk (0xffff0000UL) /*!< SRC_COEF1 (Bitfield-Mask: 0xffff) */ +#define APU_COEF10_SET1_REG_SRC_COEF0_Pos (0UL) /*!< SRC_COEF0 (Bit 0) */ +#define APU_COEF10_SET1_REG_SRC_COEF0_Msk (0xffffUL) /*!< SRC_COEF0 (Bitfield-Mask: 0xffff) */ +/* ==================================================== COEF32_SET1_REG ==================================================== */ +#define APU_COEF32_SET1_REG_SRC_COEF3_Pos (16UL) /*!< SRC_COEF3 (Bit 16) */ +#define APU_COEF32_SET1_REG_SRC_COEF3_Msk (0xffff0000UL) /*!< SRC_COEF3 (Bitfield-Mask: 0xffff) */ +#define APU_COEF32_SET1_REG_SRC_COEF2_Pos (0UL) /*!< SRC_COEF2 (Bit 0) */ +#define APU_COEF32_SET1_REG_SRC_COEF2_Msk (0xffffUL) /*!< SRC_COEF2 (Bitfield-Mask: 0xffff) */ +/* ==================================================== COEF54_SET1_REG ==================================================== */ +#define APU_COEF54_SET1_REG_SRC_COEF5_Pos (16UL) /*!< SRC_COEF5 (Bit 16) */ +#define APU_COEF54_SET1_REG_SRC_COEF5_Msk (0xffff0000UL) /*!< SRC_COEF5 (Bitfield-Mask: 0xffff) */ +#define APU_COEF54_SET1_REG_SRC_COEF4_Pos (0UL) /*!< SRC_COEF4 (Bit 0) */ +#define APU_COEF54_SET1_REG_SRC_COEF4_Msk (0xffffUL) /*!< SRC_COEF4 (Bitfield-Mask: 0xffff) */ +/* ==================================================== COEF76_SET1_REG ==================================================== */ +#define APU_COEF76_SET1_REG_SRC_COEF7_Pos (16UL) /*!< SRC_COEF7 (Bit 16) */ +#define APU_COEF76_SET1_REG_SRC_COEF7_Msk (0xffff0000UL) /*!< SRC_COEF7 (Bitfield-Mask: 0xffff) */ +#define APU_COEF76_SET1_REG_SRC_COEF6_Pos (0UL) /*!< SRC_COEF6 (Bit 0) */ +#define APU_COEF76_SET1_REG_SRC_COEF6_Msk (0xffffUL) /*!< SRC_COEF6 (Bitfield-Mask: 0xffff) */ +/* ==================================================== COEF98_SET1_REG ==================================================== */ +#define APU_COEF98_SET1_REG_SRC_COEF9_Pos (16UL) /*!< SRC_COEF9 (Bit 16) */ +#define APU_COEF98_SET1_REG_SRC_COEF9_Msk (0xffff0000UL) /*!< SRC_COEF9 (Bitfield-Mask: 0xffff) */ +#define APU_COEF98_SET1_REG_SRC_COEF8_Pos (0UL) /*!< SRC_COEF8 (Bit 0) */ +#define APU_COEF98_SET1_REG_SRC_COEF8_Msk (0xffffUL) /*!< SRC_COEF8 (Bitfield-Mask: 0xffff) */ +/* ===================================================== PCM1_CTRL_REG ===================================================== */ +#define APU_PCM1_CTRL_REG_PCM_FSC_DIV_Pos (20UL) /*!< PCM_FSC_DIV (Bit 20) */ +#define APU_PCM1_CTRL_REG_PCM_FSC_DIV_Msk (0xfff00000UL) /*!< PCM_FSC_DIV (Bitfield-Mask: 0xfff) */ +#define APU_PCM1_CTRL_REG_PCM_FSC_EDGE_Pos (16UL) /*!< PCM_FSC_EDGE (Bit 16) */ +#define APU_PCM1_CTRL_REG_PCM_FSC_EDGE_Msk (0x10000UL) /*!< PCM_FSC_EDGE (Bitfield-Mask: 0x01) */ +#define APU_PCM1_CTRL_REG_PCM_CH_DEL_Pos (11UL) /*!< PCM_CH_DEL (Bit 11) */ +#define APU_PCM1_CTRL_REG_PCM_CH_DEL_Msk (0xf800UL) /*!< PCM_CH_DEL (Bitfield-Mask: 0x1f) */ +#define APU_PCM1_CTRL_REG_PCM_CLK_BIT_Pos (10UL) /*!< PCM_CLK_BIT (Bit 10) */ +#define APU_PCM1_CTRL_REG_PCM_CLK_BIT_Msk (0x400UL) /*!< PCM_CLK_BIT (Bitfield-Mask: 0x01) */ +#define APU_PCM1_CTRL_REG_PCM_FSCINV_Pos (9UL) /*!< PCM_FSCINV (Bit 9) */ +#define APU_PCM1_CTRL_REG_PCM_FSCINV_Msk (0x200UL) /*!< PCM_FSCINV (Bitfield-Mask: 0x01) */ +#define APU_PCM1_CTRL_REG_PCM_CLKINV_Pos (8UL) /*!< PCM_CLKINV (Bit 8) */ +#define APU_PCM1_CTRL_REG_PCM_CLKINV_Msk (0x100UL) /*!< PCM_CLKINV (Bitfield-Mask: 0x01) */ +#define APU_PCM1_CTRL_REG_PCM_PPOD_Pos (7UL) /*!< PCM_PPOD (Bit 7) */ +#define APU_PCM1_CTRL_REG_PCM_PPOD_Msk (0x80UL) /*!< PCM_PPOD (Bitfield-Mask: 0x01) */ +#define APU_PCM1_CTRL_REG_PCM_FSCDEL_Pos (6UL) /*!< PCM_FSCDEL (Bit 6) */ +#define APU_PCM1_CTRL_REG_PCM_FSCDEL_Msk (0x40UL) /*!< PCM_FSCDEL (Bitfield-Mask: 0x01) */ +#define APU_PCM1_CTRL_REG_PCM_FSCLEN_Pos (2UL) /*!< PCM_FSCLEN (Bit 2) */ +#define APU_PCM1_CTRL_REG_PCM_FSCLEN_Msk (0x3cUL) /*!< PCM_FSCLEN (Bitfield-Mask: 0x0f) */ +#define APU_PCM1_CTRL_REG_PCM_MASTER_Pos (1UL) /*!< PCM_MASTER (Bit 1) */ +#define APU_PCM1_CTRL_REG_PCM_MASTER_Msk (0x2UL) /*!< PCM_MASTER (Bitfield-Mask: 0x01) */ +#define APU_PCM1_CTRL_REG_PCM_EN_Pos (0UL) /*!< PCM_EN (Bit 0) */ +#define APU_PCM1_CTRL_REG_PCM_EN_Msk (0x1UL) /*!< PCM_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== PCM1_IN1_REG ====================================================== */ +#define APU_PCM1_IN1_REG_PCM_IN_Pos (0UL) /*!< PCM_IN (Bit 0) */ +#define APU_PCM1_IN1_REG_PCM_IN_Msk (0xffffffffUL) /*!< PCM_IN (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== PCM1_IN2_REG ====================================================== */ +#define APU_PCM1_IN2_REG_PCM_IN_Pos (0UL) /*!< PCM_IN (Bit 0) */ +#define APU_PCM1_IN2_REG_PCM_IN_Msk (0xffffffffUL) /*!< PCM_IN (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== PCM1_OUT1_REG ===================================================== */ +#define APU_PCM1_OUT1_REG_PCM_OUT_Pos (0UL) /*!< PCM_OUT (Bit 0) */ +#define APU_PCM1_OUT1_REG_PCM_OUT_Msk (0xffffffffUL) /*!< PCM_OUT (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== PCM1_OUT2_REG ===================================================== */ +#define APU_PCM1_OUT2_REG_PCM_OUT_Pos (0UL) /*!< PCM_OUT (Bit 0) */ +#define APU_PCM1_OUT2_REG_PCM_OUT_Msk (0xffffffffUL) /*!< PCM_OUT (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== SRC1_CTRL_REG ===================================================== */ +#define APU_SRC1_CTRL_REG_SRC_PDM_DO_DEL_Pos (30UL) /*!< SRC_PDM_DO_DEL (Bit 30) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_DO_DEL_Msk (0xc0000000UL) /*!< SRC_PDM_DO_DEL (Bitfield-Mask: 0x03) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_MODE_Pos (28UL) /*!< SRC_PDM_MODE (Bit 28) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_MODE_Msk (0x30000000UL) /*!< SRC_PDM_MODE (Bitfield-Mask: 0x03) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_DI_DEL_Pos (26UL) /*!< SRC_PDM_DI_DEL (Bit 26) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_DI_DEL_Msk (0xc000000UL) /*!< SRC_PDM_DI_DEL (Bitfield-Mask: 0x03) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_FLOWCLR_Pos (25UL) /*!< SRC_OUT_FLOWCLR (Bit 25) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_FLOWCLR_Msk (0x2000000UL) /*!< SRC_OUT_FLOWCLR (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_IN_FLOWCLR_Pos (24UL) /*!< SRC_IN_FLOWCLR (Bit 24) */ +#define APU_SRC1_CTRL_REG_SRC_IN_FLOWCLR_Msk (0x1000000UL) /*!< SRC_IN_FLOWCLR (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_UNFLOW_Pos (23UL) /*!< SRC_OUT_UNFLOW (Bit 23) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_UNFLOW_Msk (0x800000UL) /*!< SRC_OUT_UNFLOW (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_OVFLOW_Pos (22UL) /*!< SRC_OUT_OVFLOW (Bit 22) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_OVFLOW_Msk (0x400000UL) /*!< SRC_OUT_OVFLOW (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_IN_UNFLOW_Pos (21UL) /*!< SRC_IN_UNFLOW (Bit 21) */ +#define APU_SRC1_CTRL_REG_SRC_IN_UNFLOW_Msk (0x200000UL) /*!< SRC_IN_UNFLOW (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_IN_OVFLOW_Pos (20UL) /*!< SRC_IN_OVFLOW (Bit 20) */ +#define APU_SRC1_CTRL_REG_SRC_IN_OVFLOW_Msk (0x100000UL) /*!< SRC_IN_OVFLOW (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_RESYNC_Pos (19UL) /*!< SRC_RESYNC (Bit 19) */ +#define APU_SRC1_CTRL_REG_SRC_RESYNC_Msk (0x80000UL) /*!< SRC_RESYNC (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_OK_Pos (18UL) /*!< SRC_OUT_OK (Bit 18) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_OK_Msk (0x40000UL) /*!< SRC_OUT_OK (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_US_Pos (16UL) /*!< SRC_OUT_US (Bit 16) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_US_Msk (0x30000UL) /*!< SRC_OUT_US (Bitfield-Mask: 0x03) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_CAL_BYPASS_Pos (14UL) /*!< SRC_OUT_CAL_BYPASS (Bit 14) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_CAL_BYPASS_Msk (0x4000UL) /*!< SRC_OUT_CAL_BYPASS (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_AMODE_Pos (13UL) /*!< SRC_OUT_AMODE (Bit 13) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_AMODE_Msk (0x2000UL) /*!< SRC_OUT_AMODE (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_OUT_INV_Pos (12UL) /*!< SRC_PDM_OUT_INV (Bit 12) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_OUT_INV_Msk (0x1000UL) /*!< SRC_PDM_OUT_INV (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_FIFO_DIRECTION_Pos (11UL) /*!< SRC_FIFO_DIRECTION (Bit 11) */ +#define APU_SRC1_CTRL_REG_SRC_FIFO_DIRECTION_Msk (0x800UL) /*!< SRC_FIFO_DIRECTION (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_FIFO_ENABLE_Pos (10UL) /*!< SRC_FIFO_ENABLE (Bit 10) */ +#define APU_SRC1_CTRL_REG_SRC_FIFO_ENABLE_Msk (0x400UL) /*!< SRC_FIFO_ENABLE (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_DSD_MODE_Pos (9UL) /*!< SRC_OUT_DSD_MODE (Bit 9) */ +#define APU_SRC1_CTRL_REG_SRC_OUT_DSD_MODE_Msk (0x200UL) /*!< SRC_OUT_DSD_MODE (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_IN_DSD_MODE_Pos (8UL) /*!< SRC_IN_DSD_MODE (Bit 8) */ +#define APU_SRC1_CTRL_REG_SRC_IN_DSD_MODE_Msk (0x100UL) /*!< SRC_IN_DSD_MODE (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_DITHER_DISABLE_Pos (7UL) /*!< SRC_DITHER_DISABLE (Bit 7) */ +#define APU_SRC1_CTRL_REG_SRC_DITHER_DISABLE_Msk (0x80UL) /*!< SRC_DITHER_DISABLE (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_IN_OK_Pos (6UL) /*!< SRC_IN_OK (Bit 6) */ +#define APU_SRC1_CTRL_REG_SRC_IN_OK_Msk (0x40UL) /*!< SRC_IN_OK (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_IN_DS_Pos (4UL) /*!< SRC_IN_DS (Bit 4) */ +#define APU_SRC1_CTRL_REG_SRC_IN_DS_Msk (0x30UL) /*!< SRC_IN_DS (Bitfield-Mask: 0x03) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_IN_INV_Pos (3UL) /*!< SRC_PDM_IN_INV (Bit 3) */ +#define APU_SRC1_CTRL_REG_SRC_PDM_IN_INV_Msk (0x8UL) /*!< SRC_PDM_IN_INV (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_IN_CAL_BYPASS_Pos (2UL) /*!< SRC_IN_CAL_BYPASS (Bit 2) */ +#define APU_SRC1_CTRL_REG_SRC_IN_CAL_BYPASS_Msk (0x4UL) /*!< SRC_IN_CAL_BYPASS (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_IN_AMODE_Pos (1UL) /*!< SRC_IN_AMODE (Bit 1) */ +#define APU_SRC1_CTRL_REG_SRC_IN_AMODE_Msk (0x2UL) /*!< SRC_IN_AMODE (Bitfield-Mask: 0x01) */ +#define APU_SRC1_CTRL_REG_SRC_EN_Pos (0UL) /*!< SRC_EN (Bit 0) */ +#define APU_SRC1_CTRL_REG_SRC_EN_Msk (0x1UL) /*!< SRC_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== SRC1_IN1_REG ====================================================== */ +#define APU_SRC1_IN1_REG_SRC_IN_Pos (0UL) /*!< SRC_IN (Bit 0) */ +#define APU_SRC1_IN1_REG_SRC_IN_Msk (0xffffffffUL) /*!< SRC_IN (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== SRC1_IN2_REG ====================================================== */ +#define APU_SRC1_IN2_REG_SRC_IN_Pos (0UL) /*!< SRC_IN (Bit 0) */ +#define APU_SRC1_IN2_REG_SRC_IN_Msk (0xffffffffUL) /*!< SRC_IN (Bitfield-Mask: 0xffffffff) */ +/* ==================================================== SRC1_IN_FS_REG ===================================================== */ +#define APU_SRC1_IN_FS_REG_SRC_IN_FS_Pos (0UL) /*!< SRC_IN_FS (Bit 0) */ +#define APU_SRC1_IN_FS_REG_SRC_IN_FS_Msk (0xffffffUL) /*!< SRC_IN_FS (Bitfield-Mask: 0xffffff) */ +/* ===================================================== SRC1_OUT1_REG ===================================================== */ +#define APU_SRC1_OUT1_REG_SRC_OUT_Pos (0UL) /*!< SRC_OUT (Bit 0) */ +#define APU_SRC1_OUT1_REG_SRC_OUT_Msk (0xffffffffUL) /*!< SRC_OUT (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== SRC1_OUT2_REG ===================================================== */ +#define APU_SRC1_OUT2_REG_SRC_OUT_Pos (0UL) /*!< SRC_OUT (Bit 0) */ +#define APU_SRC1_OUT2_REG_SRC_OUT_Msk (0xffffffffUL) /*!< SRC_OUT (Bitfield-Mask: 0xffffffff) */ +/* ==================================================== SRC1_OUT_FS_REG ==================================================== */ +#define APU_SRC1_OUT_FS_REG_SRC_OUT_FS_Pos (0UL) /*!< SRC_OUT_FS (Bit 0) */ +#define APU_SRC1_OUT_FS_REG_SRC_OUT_FS_Msk (0xffffffUL) /*!< SRC_OUT_FS (Bitfield-Mask: 0xffffff) */ + + +/* =========================================================================================================================== */ +/* ================ CACHE ================ */ +/* =========================================================================================================================== */ + +/* ================================================== CACHE_ASSOCCFG_REG =================================================== */ +#define CACHE_CACHE_ASSOCCFG_REG_CACHE_ASSOC_Pos (0UL) /*!< CACHE_ASSOC (Bit 0) */ +#define CACHE_CACHE_ASSOCCFG_REG_CACHE_ASSOC_Msk (0x3UL) /*!< CACHE_ASSOC (Bitfield-Mask: 0x03) */ +/* ==================================================== CACHE_CTRL1_REG ==================================================== */ +#define CACHE_CACHE_CTRL1_REG_CACHE_RES1_Pos (1UL) /*!< CACHE_RES1 (Bit 1) */ +#define CACHE_CACHE_CTRL1_REG_CACHE_RES1_Msk (0x2UL) /*!< CACHE_RES1 (Bitfield-Mask: 0x01) */ +#define CACHE_CACHE_CTRL1_REG_CACHE_FLUSH_Pos (0UL) /*!< CACHE_FLUSH (Bit 0) */ +#define CACHE_CACHE_CTRL1_REG_CACHE_FLUSH_Msk (0x1UL) /*!< CACHE_FLUSH (Bitfield-Mask: 0x01) */ +/* ==================================================== CACHE_CTRL2_REG ==================================================== */ +#define CACHE_CACHE_CTRL2_REG_CACHE_CGEN_Pos (10UL) /*!< CACHE_CGEN (Bit 10) */ +#define CACHE_CACHE_CTRL2_REG_CACHE_CGEN_Msk (0x400UL) /*!< CACHE_CGEN (Bitfield-Mask: 0x01) */ +#define CACHE_CACHE_CTRL2_REG_CACHE_WEN_Pos (9UL) /*!< CACHE_WEN (Bit 9) */ +#define CACHE_CACHE_CTRL2_REG_CACHE_WEN_Msk (0x200UL) /*!< CACHE_WEN (Bitfield-Mask: 0x01) */ +#define CACHE_CACHE_CTRL2_REG_CACHE_LEN_Pos (0UL) /*!< CACHE_LEN (Bit 0) */ +#define CACHE_CACHE_CTRL2_REG_CACHE_LEN_Msk (0x1ffUL) /*!< CACHE_LEN (Bitfield-Mask: 0x1ff) */ +/* ==================================================== CACHE_FLASH_REG ==================================================== */ +#define CACHE_CACHE_FLASH_REG_FLASH_REGION_BASE_Pos (16UL) /*!< FLASH_REGION_BASE (Bit 16) */ +#define CACHE_CACHE_FLASH_REG_FLASH_REGION_BASE_Msk (0xffff0000UL) /*!< FLASH_REGION_BASE (Bitfield-Mask: 0xffff) */ +#define CACHE_CACHE_FLASH_REG_FLASH_REGION_OFFSET_Pos (4UL) /*!< FLASH_REGION_OFFSET (Bit 4) */ +#define CACHE_CACHE_FLASH_REG_FLASH_REGION_OFFSET_Msk (0xfff0UL) /*!< FLASH_REGION_OFFSET (Bitfield-Mask: 0xfff) */ +#define CACHE_CACHE_FLASH_REG_FLASH_REGION_SIZE_Pos (0UL) /*!< FLASH_REGION_SIZE (Bit 0) */ +#define CACHE_CACHE_FLASH_REG_FLASH_REGION_SIZE_Msk (0x7UL) /*!< FLASH_REGION_SIZE (Bitfield-Mask: 0x07) */ +/* ================================================== CACHE_LNSIZECFG_REG ================================================== */ +#define CACHE_CACHE_LNSIZECFG_REG_CACHE_LINE_Pos (0UL) /*!< CACHE_LINE (Bit 0) */ +#define CACHE_CACHE_LNSIZECFG_REG_CACHE_LINE_Msk (0x3UL) /*!< CACHE_LINE (Bitfield-Mask: 0x03) */ +/* ================================================== CACHE_MRM_CTRL_REG =================================================== */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_HITS_THRES_STATUS_Pos (4UL) /*!< MRM_IRQ_HITS_THRES_STATUS (Bit 4) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_HITS_THRES_STATUS_Msk (0x10UL) /*!< MRM_IRQ_HITS_THRES_STATUS (Bitfield-Mask: 0x01) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_MISSES_THRES_STATUS_Pos (3UL) /*!< MRM_IRQ_MISSES_THRES_STATUS (Bit 3) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_MISSES_THRES_STATUS_Msk (0x8UL) /*!< MRM_IRQ_MISSES_THRES_STATUS (Bitfield-Mask: 0x01) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_TINT_STATUS_Pos (2UL) /*!< MRM_IRQ_TINT_STATUS (Bit 2) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_TINT_STATUS_Msk (0x4UL) /*!< MRM_IRQ_TINT_STATUS (Bitfield-Mask: 0x01) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_MASK_Pos (1UL) /*!< MRM_IRQ_MASK (Bit 1) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_MASK_Msk (0x2UL) /*!< MRM_IRQ_MASK (Bitfield-Mask: 0x01) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_START_Pos (0UL) /*!< MRM_START (Bit 0) */ +#define CACHE_CACHE_MRM_CTRL_REG_MRM_START_Msk (0x1UL) /*!< MRM_START (Bitfield-Mask: 0x01) */ +/* ================================================== CACHE_MRM_HITS_REG =================================================== */ +#define CACHE_CACHE_MRM_HITS_REG_MRM_HITS_Pos (0UL) /*!< MRM_HITS (Bit 0) */ +#define CACHE_CACHE_MRM_HITS_REG_MRM_HITS_Msk (0xffffffffUL) /*!< MRM_HITS (Bitfield-Mask: 0xffffffff) */ +/* =============================================== CACHE_MRM_HITS_THRES_REG ================================================ */ +#define CACHE_CACHE_MRM_HITS_THRES_REG_MRM_HITS_THRES_Pos (0UL) /*!< MRM_HITS_THRES (Bit 0) */ +#define CACHE_CACHE_MRM_HITS_THRES_REG_MRM_HITS_THRES_Msk (0xffffffffUL) /*!< MRM_HITS_THRES (Bitfield-Mask: 0xffffffff) */ +/* ================================================= CACHE_MRM_MISSES_REG ================================================== */ +#define CACHE_CACHE_MRM_MISSES_REG_MRM_MISSES_Pos (0UL) /*!< MRM_MISSES (Bit 0) */ +#define CACHE_CACHE_MRM_MISSES_REG_MRM_MISSES_Msk (0xffffffffUL) /*!< MRM_MISSES (Bitfield-Mask: 0xffffffff) */ +/* ============================================== CACHE_MRM_MISSES_THRES_REG =============================================== */ +#define CACHE_CACHE_MRM_MISSES_THRES_REG_MRM_MISSES_THRES_Pos (0UL) /*!< MRM_MISSES_THRES (Bit 0) */ +#define CACHE_CACHE_MRM_MISSES_THRES_REG_MRM_MISSES_THRES_Msk (0xffffffffUL) /*!< MRM_MISSES_THRES (Bitfield-Mask: 0xffffffff) */ +/* ================================================== CACHE_MRM_TINT_REG =================================================== */ +#define CACHE_CACHE_MRM_TINT_REG_MRM_TINT_Pos (0UL) /*!< MRM_TINT (Bit 0) */ +#define CACHE_CACHE_MRM_TINT_REG_MRM_TINT_Msk (0x7ffffUL) /*!< MRM_TINT (Bitfield-Mask: 0x7ffff) */ +/* ===================================================== SWD_RESET_REG ===================================================== */ +#define CACHE_SWD_RESET_REG_SWD_HW_RESET_REQ_Pos (0UL) /*!< SWD_HW_RESET_REQ (Bit 0) */ +#define CACHE_SWD_RESET_REG_SWD_HW_RESET_REQ_Msk (0x1UL) /*!< SWD_HW_RESET_REQ (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ CHARGER ================ */ +/* =========================================================================================================================== */ + +/* ============================================== CHARGER_CC_CHARGE_TIMER_REG ============================================== */ +#define CHARGER_CHARGER_CC_CHARGE_TIMER_REG_CC_CHARGE_TIMER_Pos (16UL) /*!< CC_CHARGE_TIMER (Bit 16) */ +#define CHARGER_CHARGER_CC_CHARGE_TIMER_REG_CC_CHARGE_TIMER_Msk (0x7fff0000UL) /*!< CC_CHARGE_TIMER (Bitfield-Mask: 0x7fff) */ +#define CHARGER_CHARGER_CC_CHARGE_TIMER_REG_MAX_CC_CHARGE_TIME_Pos (0UL) /*!< MAX_CC_CHARGE_TIME (Bit 0) */ +#define CHARGER_CHARGER_CC_CHARGE_TIMER_REG_MAX_CC_CHARGE_TIME_Msk (0x7fffUL) /*!< MAX_CC_CHARGE_TIME (Bitfield-Mask: 0x7fff) */ +/* =================================================== CHARGER_CTRL_REG ==================================================== */ +#define CHARGER_CHARGER_CTRL_REG_EOC_INTERVAL_CHECK_TIMER_Pos (22UL) /*!< EOC_INTERVAL_CHECK_TIMER (Bit 22) */ +#define CHARGER_CHARGER_CTRL_REG_EOC_INTERVAL_CHECK_TIMER_Msk (0xfc00000UL) /*!< EOC_INTERVAL_CHECK_TIMER (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_CTRL_REG_EOC_INTERVAL_CHECK_THRES_Pos (16UL) /*!< EOC_INTERVAL_CHECK_THRES (Bit 16) */ +#define CHARGER_CHARGER_CTRL_REG_EOC_INTERVAL_CHECK_THRES_Msk (0x3f0000UL) /*!< EOC_INTERVAL_CHECK_THRES (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_CTRL_REG_REPLENISH_MODE_Pos (15UL) /*!< REPLENISH_MODE (Bit 15) */ +#define CHARGER_CHARGER_CTRL_REG_REPLENISH_MODE_Msk (0x8000UL) /*!< REPLENISH_MODE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_PRE_CHARGE_MODE_Pos (14UL) /*!< PRE_CHARGE_MODE (Bit 14) */ +#define CHARGER_CHARGER_CTRL_REG_PRE_CHARGE_MODE_Msk (0x4000UL) /*!< PRE_CHARGE_MODE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGE_LOOP_HOLD_Pos (13UL) /*!< CHARGE_LOOP_HOLD (Bit 13) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGE_LOOP_HOLD_Msk (0x2000UL) /*!< CHARGE_LOOP_HOLD (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_JEITA_SUPPORT_DISABLED_Pos (12UL) /*!< JEITA_SUPPORT_DISABLED (Bit 12) */ +#define CHARGER_CHARGER_CTRL_REG_JEITA_SUPPORT_DISABLED_Msk (0x1000UL) /*!< JEITA_SUPPORT_DISABLED (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_TBAT_MONITOR_MODE_Pos (10UL) /*!< TBAT_MONITOR_MODE (Bit 10) */ +#define CHARGER_CHARGER_CTRL_REG_TBAT_MONITOR_MODE_Msk (0xc00UL) /*!< TBAT_MONITOR_MODE (Bitfield-Mask: 0x03) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGE_TIMERS_HALT_ENABLE_Pos (9UL) /*!< CHARGE_TIMERS_HALT_ENABLE (Bit 9) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGE_TIMERS_HALT_ENABLE_Msk (0x200UL) /*!< CHARGE_TIMERS_HALT_ENABLE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_NTC_LOW_DISABLE_Pos (7UL) /*!< NTC_LOW_DISABLE (Bit 7) */ +#define CHARGER_CHARGER_CTRL_REG_NTC_LOW_DISABLE_Msk (0x80UL) /*!< NTC_LOW_DISABLE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_TBAT_PROT_ENABLE_Pos (6UL) /*!< TBAT_PROT_ENABLE (Bit 6) */ +#define CHARGER_CHARGER_CTRL_REG_TBAT_PROT_ENABLE_Msk (0x40UL) /*!< TBAT_PROT_ENABLE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_TDIE_ERROR_RESUME_Pos (5UL) /*!< TDIE_ERROR_RESUME (Bit 5) */ +#define CHARGER_CHARGER_CTRL_REG_TDIE_ERROR_RESUME_Msk (0x20UL) /*!< TDIE_ERROR_RESUME (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_TDIE_PROT_ENABLE_Pos (4UL) /*!< TDIE_PROT_ENABLE (Bit 4) */ +#define CHARGER_CHARGER_CTRL_REG_TDIE_PROT_ENABLE_Msk (0x10UL) /*!< TDIE_PROT_ENABLE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGER_RESUME_Pos (3UL) /*!< CHARGER_RESUME (Bit 3) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGER_RESUME_Msk (0x8UL) /*!< CHARGER_RESUME (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGER_BYPASS_Pos (2UL) /*!< CHARGER_BYPASS (Bit 2) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGER_BYPASS_Msk (0x4UL) /*!< CHARGER_BYPASS (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGE_START_Pos (1UL) /*!< CHARGE_START (Bit 1) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGE_START_Msk (0x2UL) /*!< CHARGE_START (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGER_ENABLE_Pos (0UL) /*!< CHARGER_ENABLE (Bit 0) */ +#define CHARGER_CHARGER_CTRL_REG_CHARGER_ENABLE_Msk (0x1UL) /*!< CHARGER_ENABLE (Bitfield-Mask: 0x01) */ +/* =============================================== CHARGER_CURRENT_PARAM_REG =============================================== */ +#define CHARGER_CHARGER_CURRENT_PARAM_REG_I_EOC_DOUBLE_RANGE_Pos (15UL) /*!< I_EOC_DOUBLE_RANGE (Bit 15) */ +#define CHARGER_CHARGER_CURRENT_PARAM_REG_I_EOC_DOUBLE_RANGE_Msk (0x8000UL) /*!< I_EOC_DOUBLE_RANGE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_CURRENT_PARAM_REG_I_END_OF_CHARGE_Pos (12UL) /*!< I_END_OF_CHARGE (Bit 12) */ +#define CHARGER_CHARGER_CURRENT_PARAM_REG_I_END_OF_CHARGE_Msk (0x7000UL) /*!< I_END_OF_CHARGE (Bitfield-Mask: 0x07) */ +#define CHARGER_CHARGER_CURRENT_PARAM_REG_I_PRECHARGE_Pos (6UL) /*!< I_PRECHARGE (Bit 6) */ +#define CHARGER_CHARGER_CURRENT_PARAM_REG_I_PRECHARGE_Msk (0xfc0UL) /*!< I_PRECHARGE (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_CURRENT_PARAM_REG_I_CHARGE_Pos (0UL) /*!< I_CHARGE (Bit 0) */ +#define CHARGER_CHARGER_CURRENT_PARAM_REG_I_CHARGE_Msk (0x3fUL) /*!< I_CHARGE (Bitfield-Mask: 0x3f) */ +/* ============================================== CHARGER_CV_CHARGE_TIMER_REG ============================================== */ +#define CHARGER_CHARGER_CV_CHARGE_TIMER_REG_CV_CHARGE_TIMER_Pos (16UL) /*!< CV_CHARGE_TIMER (Bit 16) */ +#define CHARGER_CHARGER_CV_CHARGE_TIMER_REG_CV_CHARGE_TIMER_Msk (0x7fff0000UL) /*!< CV_CHARGE_TIMER (Bitfield-Mask: 0x7fff) */ +#define CHARGER_CHARGER_CV_CHARGE_TIMER_REG_MAX_CV_CHARGE_TIME_Pos (0UL) /*!< MAX_CV_CHARGE_TIME (Bit 0) */ +#define CHARGER_CHARGER_CV_CHARGE_TIMER_REG_MAX_CV_CHARGE_TIME_Msk (0x7fffUL) /*!< MAX_CV_CHARGE_TIME (Bitfield-Mask: 0x7fff) */ +/* =============================================== CHARGER_ERROR_IRQ_CLR_REG =============================================== */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TBAT_ERROR_IRQ_CLR_Pos (6UL) /*!< TBAT_ERROR_IRQ_CLR (Bit 6) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TBAT_ERROR_IRQ_CLR_Msk (0x40UL) /*!< TBAT_ERROR_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TDIE_ERROR_IRQ_CLR_Pos (5UL) /*!< TDIE_ERROR_IRQ_CLR (Bit 5) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TDIE_ERROR_IRQ_CLR_Msk (0x20UL) /*!< TDIE_ERROR_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_VBAT_OVP_ERROR_IRQ_CLR_Pos (4UL) /*!< VBAT_OVP_ERROR_IRQ_CLR (Bit 4) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_VBAT_OVP_ERROR_IRQ_CLR_Msk (0x10UL) /*!< VBAT_OVP_ERROR_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TOTAL_CHARGE_TIMEOUT_IRQ_CLR_Pos (3UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ_CLR (Bit 3) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TOTAL_CHARGE_TIMEOUT_IRQ_CLR_Msk (0x8UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_CV_CHARGE_TIMEOUT_IRQ_CLR_Pos (2UL) /*!< CV_CHARGE_TIMEOUT_IRQ_CLR (Bit 2) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_CV_CHARGE_TIMEOUT_IRQ_CLR_Msk (0x4UL) /*!< CV_CHARGE_TIMEOUT_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_CC_CHARGE_TIMEOUT_IRQ_CLR_Pos (1UL) /*!< CC_CHARGE_TIMEOUT_IRQ_CLR (Bit 1) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_CC_CHARGE_TIMEOUT_IRQ_CLR_Msk (0x2UL) /*!< CC_CHARGE_TIMEOUT_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_PRECHARGE_TIMEOUT_IRQ_CLR_Pos (0UL) /*!< PRECHARGE_TIMEOUT_IRQ_CLR (Bit 0) */ +#define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_PRECHARGE_TIMEOUT_IRQ_CLR_Msk (0x1UL) /*!< PRECHARGE_TIMEOUT_IRQ_CLR (Bitfield-Mask: 0x01) */ +/* ============================================== CHARGER_ERROR_IRQ_MASK_REG =============================================== */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TBAT_ERROR_IRQ_EN_Pos (6UL) /*!< TBAT_ERROR_IRQ_EN (Bit 6) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TBAT_ERROR_IRQ_EN_Msk (0x40UL) /*!< TBAT_ERROR_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TDIE_ERROR_IRQ_EN_Pos (5UL) /*!< TDIE_ERROR_IRQ_EN (Bit 5) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TDIE_ERROR_IRQ_EN_Msk (0x20UL) /*!< TDIE_ERROR_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_VBAT_OVP_ERROR_IRQ_EN_Pos (4UL) /*!< VBAT_OVP_ERROR_IRQ_EN (Bit 4) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_VBAT_OVP_ERROR_IRQ_EN_Msk (0x10UL) /*!< VBAT_OVP_ERROR_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TOTAL_CHARGE_TIMEOUT_IRQ_EN_Pos (3UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ_EN (Bit 3) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TOTAL_CHARGE_TIMEOUT_IRQ_EN_Msk (0x8UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_CV_CHARGE_TIMEOUT_IRQ_EN_Pos (2UL) /*!< CV_CHARGE_TIMEOUT_IRQ_EN (Bit 2) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_CV_CHARGE_TIMEOUT_IRQ_EN_Msk (0x4UL) /*!< CV_CHARGE_TIMEOUT_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_CC_CHARGE_TIMEOUT_IRQ_EN_Pos (1UL) /*!< CC_CHARGE_TIMEOUT_IRQ_EN (Bit 1) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_CC_CHARGE_TIMEOUT_IRQ_EN_Msk (0x2UL) /*!< CC_CHARGE_TIMEOUT_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_PRECHARGE_TIMEOUT_IRQ_EN_Pos (0UL) /*!< PRECHARGE_TIMEOUT_IRQ_EN (Bit 0) */ +#define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_PRECHARGE_TIMEOUT_IRQ_EN_Msk (0x1UL) /*!< PRECHARGE_TIMEOUT_IRQ_EN (Bitfield-Mask: 0x01) */ +/* ============================================= CHARGER_ERROR_IRQ_STATUS_REG ============================================== */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TBAT_ERROR_IRQ_Pos (6UL) /*!< TBAT_ERROR_IRQ (Bit 6) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TBAT_ERROR_IRQ_Msk (0x40UL) /*!< TBAT_ERROR_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TDIE_ERROR_IRQ_Pos (5UL) /*!< TDIE_ERROR_IRQ (Bit 5) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TDIE_ERROR_IRQ_Msk (0x20UL) /*!< TDIE_ERROR_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_VBAT_OVP_ERROR_IRQ_Pos (4UL) /*!< VBAT_OVP_ERROR_IRQ (Bit 4) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_VBAT_OVP_ERROR_IRQ_Msk (0x10UL) /*!< VBAT_OVP_ERROR_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TOTAL_CHARGE_TIMEOUT_IRQ_Pos (3UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ (Bit 3) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TOTAL_CHARGE_TIMEOUT_IRQ_Msk (0x8UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_CV_CHARGE_TIMEOUT_IRQ_Pos (2UL) /*!< CV_CHARGE_TIMEOUT_IRQ (Bit 2) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_CV_CHARGE_TIMEOUT_IRQ_Msk (0x4UL) /*!< CV_CHARGE_TIMEOUT_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_CC_CHARGE_TIMEOUT_IRQ_Pos (1UL) /*!< CC_CHARGE_TIMEOUT_IRQ (Bit 1) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_CC_CHARGE_TIMEOUT_IRQ_Msk (0x2UL) /*!< CC_CHARGE_TIMEOUT_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_PRECHARGE_TIMEOUT_IRQ_Pos (0UL) /*!< PRECHARGE_TIMEOUT_IRQ (Bit 0) */ +#define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_PRECHARGE_TIMEOUT_IRQ_Msk (0x1UL) /*!< PRECHARGE_TIMEOUT_IRQ (Bitfield-Mask: 0x01) */ +/* =============================================== CHARGER_JEITA_CURRENT_REG =============================================== */ +#define CHARGER_CHARGER_JEITA_CURRENT_REG_I_PRECHARGE_TWARM_Pos (18UL) /*!< I_PRECHARGE_TWARM (Bit 18) */ +#define CHARGER_CHARGER_JEITA_CURRENT_REG_I_PRECHARGE_TWARM_Msk (0xfc0000UL) /*!< I_PRECHARGE_TWARM (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_JEITA_CURRENT_REG_I_PRECHARGE_TCOOL_Pos (12UL) /*!< I_PRECHARGE_TCOOL (Bit 12) */ +#define CHARGER_CHARGER_JEITA_CURRENT_REG_I_PRECHARGE_TCOOL_Msk (0x3f000UL) /*!< I_PRECHARGE_TCOOL (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_JEITA_CURRENT_REG_I_CHARGE_TWARM_Pos (6UL) /*!< I_CHARGE_TWARM (Bit 6) */ +#define CHARGER_CHARGER_JEITA_CURRENT_REG_I_CHARGE_TWARM_Msk (0xfc0UL) /*!< I_CHARGE_TWARM (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_JEITA_CURRENT_REG_I_CHARGE_TCOOL_Pos (0UL) /*!< I_CHARGE_TCOOL (Bit 0) */ +#define CHARGER_CHARGER_JEITA_CURRENT_REG_I_CHARGE_TCOOL_Msk (0x3fUL) /*!< I_CHARGE_TCOOL (Bitfield-Mask: 0x3f) */ +/* ============================================== CHARGER_JEITA_V_CHARGE_REG =============================================== */ +#define CHARGER_CHARGER_JEITA_V_CHARGE_REG_V_CHARGE_TWARM_Pos (6UL) /*!< V_CHARGE_TWARM (Bit 6) */ +#define CHARGER_CHARGER_JEITA_V_CHARGE_REG_V_CHARGE_TWARM_Msk (0xfc0UL) /*!< V_CHARGE_TWARM (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_JEITA_V_CHARGE_REG_V_CHARGE_TCOOL_Pos (0UL) /*!< V_CHARGE_TCOOL (Bit 0) */ +#define CHARGER_CHARGER_JEITA_V_CHARGE_REG_V_CHARGE_TCOOL_Msk (0x3fUL) /*!< V_CHARGE_TCOOL (Bitfield-Mask: 0x3f) */ +/* ================================================ CHARGER_JEITA_V_OVP_REG ================================================ */ +#define CHARGER_CHARGER_JEITA_V_OVP_REG_V_OVP_TWARM_Pos (6UL) /*!< V_OVP_TWARM (Bit 6) */ +#define CHARGER_CHARGER_JEITA_V_OVP_REG_V_OVP_TWARM_Msk (0xfc0UL) /*!< V_OVP_TWARM (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_JEITA_V_OVP_REG_V_OVP_TCOOL_Pos (0UL) /*!< V_OVP_TCOOL (Bit 0) */ +#define CHARGER_CHARGER_JEITA_V_OVP_REG_V_OVP_TCOOL_Msk (0x3fUL) /*!< V_OVP_TCOOL (Bitfield-Mask: 0x3f) */ +/* ============================================= CHARGER_JEITA_V_PRECHARGE_REG ============================================= */ +#define CHARGER_CHARGER_JEITA_V_PRECHARGE_REG_V_PRECHARGE_TWARM_Pos (6UL) /*!< V_PRECHARGE_TWARM (Bit 6) */ +#define CHARGER_CHARGER_JEITA_V_PRECHARGE_REG_V_PRECHARGE_TWARM_Msk (0xfc0UL) /*!< V_PRECHARGE_TWARM (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_JEITA_V_PRECHARGE_REG_V_PRECHARGE_TCOOL_Pos (0UL) /*!< V_PRECHARGE_TCOOL (Bit 0) */ +#define CHARGER_CHARGER_JEITA_V_PRECHARGE_REG_V_PRECHARGE_TCOOL_Msk (0x3fUL) /*!< V_PRECHARGE_TCOOL (Bitfield-Mask: 0x3f) */ +/* ============================================= CHARGER_JEITA_V_REPLENISH_REG ============================================= */ +#define CHARGER_CHARGER_JEITA_V_REPLENISH_REG_V_REPLENISH_TWARM_Pos (6UL) /*!< V_REPLENISH_TWARM (Bit 6) */ +#define CHARGER_CHARGER_JEITA_V_REPLENISH_REG_V_REPLENISH_TWARM_Msk (0xfc0UL) /*!< V_REPLENISH_TWARM (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_JEITA_V_REPLENISH_REG_V_REPLENISH_TCOOL_Pos (0UL) /*!< V_REPLENISH_TCOOL (Bit 0) */ +#define CHARGER_CHARGER_JEITA_V_REPLENISH_REG_V_REPLENISH_TCOOL_Msk (0x3fUL) /*!< V_REPLENISH_TCOOL (Bitfield-Mask: 0x3f) */ +/* ============================================= CHARGER_PRE_CHARGE_TIMER_REG ============================================== */ +#define CHARGER_CHARGER_PRE_CHARGE_TIMER_REG_PRE_CHARGE_TIMER_Pos (16UL) /*!< PRE_CHARGE_TIMER (Bit 16) */ +#define CHARGER_CHARGER_PRE_CHARGE_TIMER_REG_PRE_CHARGE_TIMER_Msk (0x7fff0000UL) /*!< PRE_CHARGE_TIMER (Bitfield-Mask: 0x7fff) */ +#define CHARGER_CHARGER_PRE_CHARGE_TIMER_REG_MAX_PRE_CHARGE_TIME_Pos (0UL) /*!< MAX_PRE_CHARGE_TIME (Bit 0) */ +#define CHARGER_CHARGER_PRE_CHARGE_TIMER_REG_MAX_PRE_CHARGE_TIME_Msk (0x7fffUL) /*!< MAX_PRE_CHARGE_TIME (Bitfield-Mask: 0x7fff) */ +/* =============================================== CHARGER_PWR_UP_TIMER_REG ================================================ */ +#define CHARGER_CHARGER_PWR_UP_TIMER_REG_CHARGER_PWR_UP_TIMER_Pos (16UL) /*!< CHARGER_PWR_UP_TIMER (Bit 16) */ +#define CHARGER_CHARGER_PWR_UP_TIMER_REG_CHARGER_PWR_UP_TIMER_Msk (0x3ff0000UL) /*!< CHARGER_PWR_UP_TIMER (Bitfield-Mask: 0x3ff) */ +#define CHARGER_CHARGER_PWR_UP_TIMER_REG_CHARGER_PWR_UP_SETTLING_Pos (0UL) /*!< CHARGER_PWR_UP_SETTLING (Bit 0) */ +#define CHARGER_CHARGER_PWR_UP_TIMER_REG_CHARGER_PWR_UP_SETTLING_Msk (0x3ffUL) /*!< CHARGER_PWR_UP_SETTLING (Bitfield-Mask: 0x3ff) */ +/* =============================================== CHARGER_STATE_IRQ_CLR_REG =============================================== */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_PRECHARGE_IRQ_CLR_Pos (11UL) /*!< CV_TO_PRECHARGE_IRQ_CLR (Bit 11) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_PRECHARGE_IRQ_CLR_Msk (0x800UL) /*!< CV_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_PRECHARGE_IRQ_CLR_Pos (10UL) /*!< CC_TO_PRECHARGE_IRQ_CLR (Bit 10) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_PRECHARGE_IRQ_CLR_Msk (0x400UL) /*!< CC_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_CC_IRQ_CLR_Pos (9UL) /*!< CV_TO_CC_IRQ_CLR (Bit 9) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_CC_IRQ_CLR_Msk (0x200UL) /*!< CV_TO_CC_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TBAT_STATUS_UPDATE_IRQ_CLR_Pos (8UL) /*!< TBAT_STATUS_UPDATE_IRQ_CLR (Bit 8) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TBAT_STATUS_UPDATE_IRQ_CLR_Msk (0x100UL) /*!< TBAT_STATUS_UPDATE_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TBAT_PROT_TO_PRECHARGE_IRQ_CLR_Pos (7UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ_CLR (Bit 7) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TBAT_PROT_TO_PRECHARGE_IRQ_CLR_Msk (0x80UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TDIE_PROT_TO_PRECHARGE_IRQ_CLR_Pos (6UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ_CLR (Bit 6) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TDIE_PROT_TO_PRECHARGE_IRQ_CLR_Msk (0x40UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_EOC_TO_PRECHARGE_IRQ_CLR_Pos (5UL) /*!< EOC_TO_PRECHARGE_IRQ_CLR (Bit 5) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_EOC_TO_PRECHARGE_IRQ_CLR_Msk (0x20UL) /*!< EOC_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_EOC_IRQ_CLR_Pos (4UL) /*!< CV_TO_EOC_IRQ_CLR (Bit 4) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_EOC_IRQ_CLR_Msk (0x10UL) /*!< CV_TO_EOC_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_EOC_IRQ_CLR_Pos (3UL) /*!< CC_TO_EOC_IRQ_CLR (Bit 3) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_EOC_IRQ_CLR_Msk (0x8UL) /*!< CC_TO_EOC_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_CV_IRQ_CLR_Pos (2UL) /*!< CC_TO_CV_IRQ_CLR (Bit 2) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_CV_IRQ_CLR_Msk (0x4UL) /*!< CC_TO_CV_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_PRECHARGE_TO_CC_IRQ_CLR_Pos (1UL) /*!< PRECHARGE_TO_CC_IRQ_CLR (Bit 1) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_PRECHARGE_TO_CC_IRQ_CLR_Msk (0x2UL) /*!< PRECHARGE_TO_CC_IRQ_CLR (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_DISABLED_TO_PRECHARGE_IRQ_CLR_Pos (0UL) /*!< DISABLED_TO_PRECHARGE_IRQ_CLR (Bit 0) */ +#define CHARGER_CHARGER_STATE_IRQ_CLR_REG_DISABLED_TO_PRECHARGE_IRQ_CLR_Msk (0x1UL) /*!< DISABLED_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ +/* ============================================== CHARGER_STATE_IRQ_MASK_REG =============================================== */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_PRECHARGE_IRQ_EN_Pos (11UL) /*!< CV_TO_PRECHARGE_IRQ_EN (Bit 11) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_PRECHARGE_IRQ_EN_Msk (0x800UL) /*!< CV_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_PRECHARGE_IRQ_EN_Pos (10UL) /*!< CC_TO_PRECHARGE_IRQ_EN (Bit 10) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_PRECHARGE_IRQ_EN_Msk (0x400UL) /*!< CC_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_CC_IRQ_EN_Pos (9UL) /*!< CV_TO_CC_IRQ_EN (Bit 9) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_CC_IRQ_EN_Msk (0x200UL) /*!< CV_TO_CC_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TBAT_STATUS_UPDATE_IRQ_EN_Pos (8UL) /*!< TBAT_STATUS_UPDATE_IRQ_EN (Bit 8) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TBAT_STATUS_UPDATE_IRQ_EN_Msk (0x100UL) /*!< TBAT_STATUS_UPDATE_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TBAT_PROT_TO_PRECHARGE_IRQ_EN_Pos (7UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ_EN (Bit 7) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TBAT_PROT_TO_PRECHARGE_IRQ_EN_Msk (0x80UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TDIE_PROT_TO_PRECHARGE_IRQ_EN_Pos (6UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ_EN (Bit 6) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TDIE_PROT_TO_PRECHARGE_IRQ_EN_Msk (0x40UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_EOC_TO_PRECHARGE_IRQ_EN_Pos (5UL) /*!< EOC_TO_PRECHARGE_IRQ_EN (Bit 5) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_EOC_TO_PRECHARGE_IRQ_EN_Msk (0x20UL) /*!< EOC_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_EOC_IRQ_EN_Pos (4UL) /*!< CV_TO_EOC_IRQ_EN (Bit 4) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_EOC_IRQ_EN_Msk (0x10UL) /*!< CV_TO_EOC_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_EOC_IRQ_EN_Pos (3UL) /*!< CC_TO_EOC_IRQ_EN (Bit 3) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_EOC_IRQ_EN_Msk (0x8UL) /*!< CC_TO_EOC_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_CV_IRQ_EN_Pos (2UL) /*!< CC_TO_CV_IRQ_EN (Bit 2) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_CV_IRQ_EN_Msk (0x4UL) /*!< CC_TO_CV_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_PRECHARGE_TO_CC_IRQ_EN_Pos (1UL) /*!< PRECHARGE_TO_CC_IRQ_EN (Bit 1) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_PRECHARGE_TO_CC_IRQ_EN_Msk (0x2UL) /*!< PRECHARGE_TO_CC_IRQ_EN (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_DISABLED_TO_PRECHARGE_IRQ_EN_Pos (0UL) /*!< DISABLED_TO_PRECHARGE_IRQ_EN (Bit 0) */ +#define CHARGER_CHARGER_STATE_IRQ_MASK_REG_DISABLED_TO_PRECHARGE_IRQ_EN_Msk (0x1UL) /*!< DISABLED_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ +/* ============================================= CHARGER_STATE_IRQ_STATUS_REG ============================================== */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_PRECHARGE_IRQ_Pos (11UL) /*!< CV_TO_PRECHARGE_IRQ (Bit 11) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_PRECHARGE_IRQ_Msk (0x800UL) /*!< CV_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_PRECHARGE_IRQ_Pos (10UL) /*!< CC_TO_PRECHARGE_IRQ (Bit 10) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_PRECHARGE_IRQ_Msk (0x400UL) /*!< CC_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_CC_IRQ_Pos (9UL) /*!< CV_TO_CC_IRQ (Bit 9) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_CC_IRQ_Msk (0x200UL) /*!< CV_TO_CC_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TBAT_STATUS_UPDATE_IRQ_Pos (8UL) /*!< TBAT_STATUS_UPDATE_IRQ (Bit 8) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TBAT_STATUS_UPDATE_IRQ_Msk (0x100UL) /*!< TBAT_STATUS_UPDATE_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TBAT_PROT_TO_PRECHARGE_IRQ_Pos (7UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ (Bit 7) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TBAT_PROT_TO_PRECHARGE_IRQ_Msk (0x80UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TDIE_PROT_TO_PRECHARGE_IRQ_Pos (6UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ (Bit 6) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TDIE_PROT_TO_PRECHARGE_IRQ_Msk (0x40UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_EOC_TO_PRECHARGE_IRQ_Pos (5UL) /*!< EOC_TO_PRECHARGE_IRQ (Bit 5) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_EOC_TO_PRECHARGE_IRQ_Msk (0x20UL) /*!< EOC_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_EOC_IRQ_Pos (4UL) /*!< CV_TO_EOC_IRQ (Bit 4) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_EOC_IRQ_Msk (0x10UL) /*!< CV_TO_EOC_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_EOC_IRQ_Pos (3UL) /*!< CC_TO_EOC_IRQ (Bit 3) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_EOC_IRQ_Msk (0x8UL) /*!< CC_TO_EOC_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_CV_IRQ_Pos (2UL) /*!< CC_TO_CV_IRQ (Bit 2) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_CV_IRQ_Msk (0x4UL) /*!< CC_TO_CV_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_PRECHARGE_TO_CC_IRQ_Pos (1UL) /*!< PRECHARGE_TO_CC_IRQ (Bit 1) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_PRECHARGE_TO_CC_IRQ_Msk (0x2UL) /*!< PRECHARGE_TO_CC_IRQ (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_DISABLED_TO_PRECHARGE_IRQ_Pos (0UL) /*!< DISABLED_TO_PRECHARGE_IRQ (Bit 0) */ +#define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_DISABLED_TO_PRECHARGE_IRQ_Msk (0x1UL) /*!< DISABLED_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ +/* ================================================== CHARGER_STATUS_REG =================================================== */ +#define CHARGER_CHARGER_STATUS_REG_OVP_EVENTS_DEBOUNCE_CNT_Pos (27UL) /*!< OVP_EVENTS_DEBOUNCE_CNT (Bit 27) */ +#define CHARGER_CHARGER_STATUS_REG_OVP_EVENTS_DEBOUNCE_CNT_Msk (0x38000000UL) /*!< OVP_EVENTS_DEBOUNCE_CNT (Bitfield-Mask: 0x07) */ +#define CHARGER_CHARGER_STATUS_REG_EOC_EVENTS_DEBOUNCE_CNT_Pos (24UL) /*!< EOC_EVENTS_DEBOUNCE_CNT (Bit 24) */ +#define CHARGER_CHARGER_STATUS_REG_EOC_EVENTS_DEBOUNCE_CNT_Msk (0x7000000UL) /*!< EOC_EVENTS_DEBOUNCE_CNT (Bitfield-Mask: 0x07) */ +#define CHARGER_CHARGER_STATUS_REG_TDIE_ERROR_DEBOUNCE_CNT_Pos (21UL) /*!< TDIE_ERROR_DEBOUNCE_CNT (Bit 21) */ +#define CHARGER_CHARGER_STATUS_REG_TDIE_ERROR_DEBOUNCE_CNT_Msk (0xe00000UL) /*!< TDIE_ERROR_DEBOUNCE_CNT (Bitfield-Mask: 0x07) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_JEITA_STATE_Pos (18UL) /*!< CHARGER_JEITA_STATE (Bit 18) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_JEITA_STATE_Msk (0x1c0000UL) /*!< CHARGER_JEITA_STATE (Bitfield-Mask: 0x07) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_STATE_Pos (14UL) /*!< CHARGER_STATE (Bit 14) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_STATE_Msk (0x3c000UL) /*!< CHARGER_STATE (Bitfield-Mask: 0x0f) */ +#define CHARGER_CHARGER_STATUS_REG_TBAT_STATUS_Pos (9UL) /*!< TBAT_STATUS (Bit 9) */ +#define CHARGER_CHARGER_STATUS_REG_TBAT_STATUS_Msk (0x3e00UL) /*!< TBAT_STATUS (Bitfield-Mask: 0x1f) */ +#define CHARGER_CHARGER_STATUS_REG_MAIN_TBAT_COMP_OUT_Pos (8UL) /*!< MAIN_TBAT_COMP_OUT (Bit 8) */ +#define CHARGER_CHARGER_STATUS_REG_MAIN_TBAT_COMP_OUT_Msk (0x100UL) /*!< MAIN_TBAT_COMP_OUT (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATUS_REG_TBAT_HOT_COMP_OUT_Pos (7UL) /*!< TBAT_HOT_COMP_OUT (Bit 7) */ +#define CHARGER_CHARGER_STATUS_REG_TBAT_HOT_COMP_OUT_Msk (0x80UL) /*!< TBAT_HOT_COMP_OUT (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATUS_REG_TDIE_COMP_OUT_Pos (6UL) /*!< TDIE_COMP_OUT (Bit 6) */ +#define CHARGER_CHARGER_STATUS_REG_TDIE_COMP_OUT_Msk (0x40UL) /*!< TDIE_COMP_OUT (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATUS_REG_VBAT_OVP_COMP_OUT_Pos (5UL) /*!< VBAT_OVP_COMP_OUT (Bit 5) */ +#define CHARGER_CHARGER_STATUS_REG_VBAT_OVP_COMP_OUT_Msk (0x20UL) /*!< VBAT_OVP_COMP_OUT (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATUS_REG_MAIN_VBAT_COMP_OUT_Pos (4UL) /*!< MAIN_VBAT_COMP_OUT (Bit 4) */ +#define CHARGER_CHARGER_STATUS_REG_MAIN_VBAT_COMP_OUT_Msk (0x10UL) /*!< MAIN_VBAT_COMP_OUT (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATUS_REG_END_OF_CHARGE_Pos (3UL) /*!< END_OF_CHARGE (Bit 3) */ +#define CHARGER_CHARGER_STATUS_REG_END_OF_CHARGE_Msk (0x8UL) /*!< END_OF_CHARGE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_CV_MODE_Pos (2UL) /*!< CHARGER_CV_MODE (Bit 2) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_CV_MODE_Msk (0x4UL) /*!< CHARGER_CV_MODE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_CC_MODE_Pos (1UL) /*!< CHARGER_CC_MODE (Bit 1) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_CC_MODE_Msk (0x2UL) /*!< CHARGER_CC_MODE (Bitfield-Mask: 0x01) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_IS_POWERED_UP_Pos (0UL) /*!< CHARGER_IS_POWERED_UP (Bit 0) */ +#define CHARGER_CHARGER_STATUS_REG_CHARGER_IS_POWERED_UP_Msk (0x1UL) /*!< CHARGER_IS_POWERED_UP (Bitfield-Mask: 0x01) */ +/* ============================================== CHARGER_TBAT_COMP_TIMER_REG ============================================== */ +#define CHARGER_CHARGER_TBAT_COMP_TIMER_REG_TBAT_COMP_TIMER_Pos (16UL) /*!< TBAT_COMP_TIMER (Bit 16) */ +#define CHARGER_CHARGER_TBAT_COMP_TIMER_REG_TBAT_COMP_TIMER_Msk (0x3ff0000UL) /*!< TBAT_COMP_TIMER (Bitfield-Mask: 0x3ff) */ +#define CHARGER_CHARGER_TBAT_COMP_TIMER_REG_TBAT_COMP_SETTLING_Pos (0UL) /*!< TBAT_COMP_SETTLING (Bit 0) */ +#define CHARGER_CHARGER_TBAT_COMP_TIMER_REG_TBAT_COMP_SETTLING_Msk (0x3ffUL) /*!< TBAT_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ +/* ============================================== CHARGER_TBAT_MON_TIMER_REG =============================================== */ +#define CHARGER_CHARGER_TBAT_MON_TIMER_REG_TBAT_MON_TIMER_Pos (16UL) /*!< TBAT_MON_TIMER (Bit 16) */ +#define CHARGER_CHARGER_TBAT_MON_TIMER_REG_TBAT_MON_TIMER_Msk (0x3ff0000UL) /*!< TBAT_MON_TIMER (Bitfield-Mask: 0x3ff) */ +#define CHARGER_CHARGER_TBAT_MON_TIMER_REG_TBAT_MON_INTERVAL_Pos (0UL) /*!< TBAT_MON_INTERVAL (Bit 0) */ +#define CHARGER_CHARGER_TBAT_MON_TIMER_REG_TBAT_MON_INTERVAL_Msk (0x3ffUL) /*!< TBAT_MON_INTERVAL (Bitfield-Mask: 0x3ff) */ +/* ============================================== CHARGER_TDIE_COMP_TIMER_REG ============================================== */ +#define CHARGER_CHARGER_TDIE_COMP_TIMER_REG_TDIE_COMP_TIMER_Pos (16UL) /*!< TDIE_COMP_TIMER (Bit 16) */ +#define CHARGER_CHARGER_TDIE_COMP_TIMER_REG_TDIE_COMP_TIMER_Msk (0x3ff0000UL) /*!< TDIE_COMP_TIMER (Bitfield-Mask: 0x3ff) */ +#define CHARGER_CHARGER_TDIE_COMP_TIMER_REG_TDIE_COMP_SETTLING_Pos (0UL) /*!< TDIE_COMP_SETTLING (Bit 0) */ +#define CHARGER_CHARGER_TDIE_COMP_TIMER_REG_TDIE_COMP_SETTLING_Msk (0x3ffUL) /*!< TDIE_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ +/* =============================================== CHARGER_TEMPSET_PARAM_REG =============================================== */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TDIE_MAX_Pos (24UL) /*!< TDIE_MAX (Bit 24) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TDIE_MAX_Msk (0x7000000UL) /*!< TDIE_MAX (Bitfield-Mask: 0x07) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_HOT_Pos (18UL) /*!< TBAT_HOT (Bit 18) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_HOT_Msk (0xfc0000UL) /*!< TBAT_HOT (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_WARM_Pos (12UL) /*!< TBAT_WARM (Bit 12) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_WARM_Msk (0x3f000UL) /*!< TBAT_WARM (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_COOL_Pos (6UL) /*!< TBAT_COOL (Bit 6) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_COOL_Msk (0xfc0UL) /*!< TBAT_COOL (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_COLD_Pos (0UL) /*!< TBAT_COLD (Bit 0) */ +#define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_COLD_Msk (0x3fUL) /*!< TBAT_COLD (Bitfield-Mask: 0x3f) */ +/* ================================================= CHARGER_TEST_CTRL_REG ================================================= */ +/* ============================================== CHARGER_THOT_COMP_TIMER_REG ============================================== */ +#define CHARGER_CHARGER_THOT_COMP_TIMER_REG_THOT_COMP_TIMER_Pos (16UL) /*!< THOT_COMP_TIMER (Bit 16) */ +#define CHARGER_CHARGER_THOT_COMP_TIMER_REG_THOT_COMP_TIMER_Msk (0x3ff0000UL) /*!< THOT_COMP_TIMER (Bitfield-Mask: 0x3ff) */ +#define CHARGER_CHARGER_THOT_COMP_TIMER_REG_THOT_COMP_SETTLING_Pos (0UL) /*!< THOT_COMP_SETTLING (Bit 0) */ +#define CHARGER_CHARGER_THOT_COMP_TIMER_REG_THOT_COMP_SETTLING_Msk (0x3ffUL) /*!< THOT_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ +/* ============================================ CHARGER_TOTAL_CHARGE_TIMER_REG ============================================= */ +#define CHARGER_CHARGER_TOTAL_CHARGE_TIMER_REG_TOTAL_CHARGE_TIMER_Pos (16UL) /*!< TOTAL_CHARGE_TIMER (Bit 16) */ +#define CHARGER_CHARGER_TOTAL_CHARGE_TIMER_REG_TOTAL_CHARGE_TIMER_Msk (0xffff0000UL) /*!< TOTAL_CHARGE_TIMER (Bitfield-Mask: 0xffff) */ +#define CHARGER_CHARGER_TOTAL_CHARGE_TIMER_REG_MAX_TOTAL_CHARGE_TIME_Pos (0UL) /*!< MAX_TOTAL_CHARGE_TIME (Bit 0) */ +#define CHARGER_CHARGER_TOTAL_CHARGE_TIMER_REG_MAX_TOTAL_CHARGE_TIME_Msk (0xffffUL) /*!< MAX_TOTAL_CHARGE_TIME (Bitfield-Mask: 0xffff) */ +/* ============================================== CHARGER_VBAT_COMP_TIMER_REG ============================================== */ +#define CHARGER_CHARGER_VBAT_COMP_TIMER_REG_VBAT_COMP_TIMER_Pos (16UL) /*!< VBAT_COMP_TIMER (Bit 16) */ +#define CHARGER_CHARGER_VBAT_COMP_TIMER_REG_VBAT_COMP_TIMER_Msk (0x3ff0000UL) /*!< VBAT_COMP_TIMER (Bitfield-Mask: 0x3ff) */ +#define CHARGER_CHARGER_VBAT_COMP_TIMER_REG_VBAT_COMP_SETTLING_Pos (0UL) /*!< VBAT_COMP_SETTLING (Bit 0) */ +#define CHARGER_CHARGER_VBAT_COMP_TIMER_REG_VBAT_COMP_SETTLING_Msk (0x3ffUL) /*!< VBAT_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ +/* =============================================== CHARGER_VOLTAGE_PARAM_REG =============================================== */ +#define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_OVP_Pos (18UL) /*!< V_OVP (Bit 18) */ +#define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_OVP_Msk (0xfc0000UL) /*!< V_OVP (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_REPLENISH_Pos (12UL) /*!< V_REPLENISH (Bit 12) */ +#define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_REPLENISH_Msk (0x3f000UL) /*!< V_REPLENISH (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_PRECHARGE_Pos (6UL) /*!< V_PRECHARGE (Bit 6) */ +#define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_PRECHARGE_Msk (0xfc0UL) /*!< V_PRECHARGE (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_CHARGE_Pos (0UL) /*!< V_CHARGE (Bit 0) */ +#define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_CHARGE_Msk (0x3fUL) /*!< V_CHARGE (Bitfield-Mask: 0x3f) */ +/* ============================================== CHARGER_VOVP_COMP_TIMER_REG ============================================== */ +#define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_OVP_INTERVAL_CHECK_TIMER_Pos (26UL) /*!< OVP_INTERVAL_CHECK_TIMER (Bit 26) */ +#define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_OVP_INTERVAL_CHECK_TIMER_Msk (0xfc000000UL) /*!< OVP_INTERVAL_CHECK_TIMER (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_VBAT_OVP_COMP_TIMER_Pos (16UL) /*!< VBAT_OVP_COMP_TIMER (Bit 16) */ +#define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_VBAT_OVP_COMP_TIMER_Msk (0x3ff0000UL) /*!< VBAT_OVP_COMP_TIMER (Bitfield-Mask: 0x3ff) */ +#define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_OVP_INTERVAL_CHECK_THRES_Pos (10UL) /*!< OVP_INTERVAL_CHECK_THRES (Bit 10) */ +#define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_OVP_INTERVAL_CHECK_THRES_Msk (0xfc00UL) /*!< OVP_INTERVAL_CHECK_THRES (Bitfield-Mask: 0x3f) */ +#define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_VBAT_OVP_COMP_SETTLING_Pos (0UL) /*!< VBAT_OVP_COMP_SETTLING (Bit 0) */ +#define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_VBAT_OVP_COMP_SETTLING_Msk (0x3ffUL) /*!< VBAT_OVP_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ + + +/* =========================================================================================================================== */ +/* ================ CHIP_VERSION ================ */ +/* =========================================================================================================================== */ + +/* ===================================================== CHIP_ID1_REG ====================================================== */ +#define CHIP_VERSION_CHIP_ID1_REG_CHIP_ID1_Pos (0UL) /*!< CHIP_ID1 (Bit 0) */ +#define CHIP_VERSION_CHIP_ID1_REG_CHIP_ID1_Msk (0xffUL) /*!< CHIP_ID1 (Bitfield-Mask: 0xff) */ +/* ===================================================== CHIP_ID2_REG ====================================================== */ +#define CHIP_VERSION_CHIP_ID2_REG_CHIP_ID2_Pos (0UL) /*!< CHIP_ID2 (Bit 0) */ +#define CHIP_VERSION_CHIP_ID2_REG_CHIP_ID2_Msk (0xffUL) /*!< CHIP_ID2 (Bitfield-Mask: 0xff) */ +/* ===================================================== CHIP_ID3_REG ====================================================== */ +#define CHIP_VERSION_CHIP_ID3_REG_CHIP_ID3_Pos (0UL) /*!< CHIP_ID3 (Bit 0) */ +#define CHIP_VERSION_CHIP_ID3_REG_CHIP_ID3_Msk (0xffUL) /*!< CHIP_ID3 (Bitfield-Mask: 0xff) */ +/* ===================================================== CHIP_ID4_REG ====================================================== */ +#define CHIP_VERSION_CHIP_ID4_REG_CHIP_ID4_Pos (0UL) /*!< CHIP_ID4 (Bit 0) */ +#define CHIP_VERSION_CHIP_ID4_REG_CHIP_ID4_Msk (0xffUL) /*!< CHIP_ID4 (Bitfield-Mask: 0xff) */ +/* =================================================== CHIP_REVISION_REG =================================================== */ +#define CHIP_VERSION_CHIP_REVISION_REG_CHIP_REVISION_Pos (0UL) /*!< CHIP_REVISION (Bit 0) */ +#define CHIP_VERSION_CHIP_REVISION_REG_CHIP_REVISION_Msk (0xffUL) /*!< CHIP_REVISION (Bitfield-Mask: 0xff) */ +/* ===================================================== CHIP_SWC_REG ====================================================== */ +#define CHIP_VERSION_CHIP_SWC_REG_CHIP_SWC_Pos (0UL) /*!< CHIP_SWC (Bit 0) */ +#define CHIP_VERSION_CHIP_SWC_REG_CHIP_SWC_Msk (0xfUL) /*!< CHIP_SWC (Bitfield-Mask: 0x0f) */ +/* ==================================================== CHIP_TEST1_REG ===================================================== */ +#define CHIP_VERSION_CHIP_TEST1_REG_CHIP_LAYOUT_REVISION_Pos (0UL) /*!< CHIP_LAYOUT_REVISION (Bit 0) */ +#define CHIP_VERSION_CHIP_TEST1_REG_CHIP_LAYOUT_REVISION_Msk (0xffUL) /*!< CHIP_LAYOUT_REVISION (Bitfield-Mask: 0xff) */ +/* ==================================================== CHIP_TEST2_REG ===================================================== */ +#define CHIP_VERSION_CHIP_TEST2_REG_CHIP_METAL_OPTION_Pos (0UL) /*!< CHIP_METAL_OPTION (Bit 0) */ +#define CHIP_VERSION_CHIP_TEST2_REG_CHIP_METAL_OPTION_Msk (0xfUL) /*!< CHIP_METAL_OPTION (Bitfield-Mask: 0x0f) */ + + +/* =========================================================================================================================== */ +/* ================ CRG_COM ================ */ +/* =========================================================================================================================== */ + +/* ====================================================== CLK_COM_REG ====================================================== */ +#define CRG_COM_CLK_COM_REG_LCD_EXT_CLK_SEL_Pos (16UL) /*!< LCD_EXT_CLK_SEL (Bit 16) */ +#define CRG_COM_CLK_COM_REG_LCD_EXT_CLK_SEL_Msk (0x30000UL) /*!< LCD_EXT_CLK_SEL (Bitfield-Mask: 0x03) */ +#define CRG_COM_CLK_COM_REG_SNC_DIV_Pos (14UL) /*!< SNC_DIV (Bit 14) */ +#define CRG_COM_CLK_COM_REG_SNC_DIV_Msk (0xc000UL) /*!< SNC_DIV (Bitfield-Mask: 0x03) */ +#define CRG_COM_CLK_COM_REG_I2C2_CLK_SEL_Pos (12UL) /*!< I2C2_CLK_SEL (Bit 12) */ +#define CRG_COM_CLK_COM_REG_I2C2_CLK_SEL_Msk (0x1000UL) /*!< I2C2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_I2C2_ENABLE_Pos (11UL) /*!< I2C2_ENABLE (Bit 11) */ +#define CRG_COM_CLK_COM_REG_I2C2_ENABLE_Msk (0x800UL) /*!< I2C2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_I2C_CLK_SEL_Pos (10UL) /*!< I2C_CLK_SEL (Bit 10) */ +#define CRG_COM_CLK_COM_REG_I2C_CLK_SEL_Msk (0x400UL) /*!< I2C_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_I2C_ENABLE_Pos (9UL) /*!< I2C_ENABLE (Bit 9) */ +#define CRG_COM_CLK_COM_REG_I2C_ENABLE_Msk (0x200UL) /*!< I2C_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_SPI2_CLK_SEL_Pos (8UL) /*!< SPI2_CLK_SEL (Bit 8) */ +#define CRG_COM_CLK_COM_REG_SPI2_CLK_SEL_Msk (0x100UL) /*!< SPI2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_SPI2_ENABLE_Pos (7UL) /*!< SPI2_ENABLE (Bit 7) */ +#define CRG_COM_CLK_COM_REG_SPI2_ENABLE_Msk (0x80UL) /*!< SPI2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_SPI_CLK_SEL_Pos (6UL) /*!< SPI_CLK_SEL (Bit 6) */ +#define CRG_COM_CLK_COM_REG_SPI_CLK_SEL_Msk (0x40UL) /*!< SPI_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_SPI_ENABLE_Pos (5UL) /*!< SPI_ENABLE (Bit 5) */ +#define CRG_COM_CLK_COM_REG_SPI_ENABLE_Msk (0x20UL) /*!< SPI_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_UART3_CLK_SEL_Pos (4UL) /*!< UART3_CLK_SEL (Bit 4) */ +#define CRG_COM_CLK_COM_REG_UART3_CLK_SEL_Msk (0x10UL) /*!< UART3_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_UART3_ENABLE_Pos (3UL) /*!< UART3_ENABLE (Bit 3) */ +#define CRG_COM_CLK_COM_REG_UART3_ENABLE_Msk (0x8UL) /*!< UART3_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_UART2_CLK_SEL_Pos (2UL) /*!< UART2_CLK_SEL (Bit 2) */ +#define CRG_COM_CLK_COM_REG_UART2_CLK_SEL_Msk (0x4UL) /*!< UART2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_UART2_ENABLE_Pos (1UL) /*!< UART2_ENABLE (Bit 1) */ +#define CRG_COM_CLK_COM_REG_UART2_ENABLE_Msk (0x2UL) /*!< UART2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_CLK_COM_REG_UART_ENABLE_Pos (0UL) /*!< UART_ENABLE (Bit 0) */ +#define CRG_COM_CLK_COM_REG_UART_ENABLE_Msk (0x1UL) /*!< UART_ENABLE (Bitfield-Mask: 0x01) */ +/* =================================================== RESET_CLK_COM_REG =================================================== */ +#define CRG_COM_RESET_CLK_COM_REG_LCD_EXT_CLK_SEL_Pos (16UL) /*!< LCD_EXT_CLK_SEL (Bit 16) */ +#define CRG_COM_RESET_CLK_COM_REG_LCD_EXT_CLK_SEL_Msk (0x30000UL) /*!< LCD_EXT_CLK_SEL (Bitfield-Mask: 0x03) */ +#define CRG_COM_RESET_CLK_COM_REG_SNC_DIV_Pos (14UL) /*!< SNC_DIV (Bit 14) */ +#define CRG_COM_RESET_CLK_COM_REG_SNC_DIV_Msk (0xc000UL) /*!< SNC_DIV (Bitfield-Mask: 0x03) */ +#define CRG_COM_RESET_CLK_COM_REG_I2C2_CLK_SEL_Pos (12UL) /*!< I2C2_CLK_SEL (Bit 12) */ +#define CRG_COM_RESET_CLK_COM_REG_I2C2_CLK_SEL_Msk (0x1000UL) /*!< I2C2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_I2C2_ENABLE_Pos (11UL) /*!< I2C2_ENABLE (Bit 11) */ +#define CRG_COM_RESET_CLK_COM_REG_I2C2_ENABLE_Msk (0x800UL) /*!< I2C2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_I2C_CLK_SEL_Pos (10UL) /*!< I2C_CLK_SEL (Bit 10) */ +#define CRG_COM_RESET_CLK_COM_REG_I2C_CLK_SEL_Msk (0x400UL) /*!< I2C_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_I2C_ENABLE_Pos (9UL) /*!< I2C_ENABLE (Bit 9) */ +#define CRG_COM_RESET_CLK_COM_REG_I2C_ENABLE_Msk (0x200UL) /*!< I2C_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_SPI2_CLK_SEL_Pos (8UL) /*!< SPI2_CLK_SEL (Bit 8) */ +#define CRG_COM_RESET_CLK_COM_REG_SPI2_CLK_SEL_Msk (0x100UL) /*!< SPI2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_SPI2_ENABLE_Pos (7UL) /*!< SPI2_ENABLE (Bit 7) */ +#define CRG_COM_RESET_CLK_COM_REG_SPI2_ENABLE_Msk (0x80UL) /*!< SPI2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_SPI_CLK_SEL_Pos (6UL) /*!< SPI_CLK_SEL (Bit 6) */ +#define CRG_COM_RESET_CLK_COM_REG_SPI_CLK_SEL_Msk (0x40UL) /*!< SPI_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_SPI_ENABLE_Pos (5UL) /*!< SPI_ENABLE (Bit 5) */ +#define CRG_COM_RESET_CLK_COM_REG_SPI_ENABLE_Msk (0x20UL) /*!< SPI_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_UART3_CLK_SEL_Pos (4UL) /*!< UART3_CLK_SEL (Bit 4) */ +#define CRG_COM_RESET_CLK_COM_REG_UART3_CLK_SEL_Msk (0x10UL) /*!< UART3_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_UART3_ENABLE_Pos (3UL) /*!< UART3_ENABLE (Bit 3) */ +#define CRG_COM_RESET_CLK_COM_REG_UART3_ENABLE_Msk (0x8UL) /*!< UART3_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_UART2_CLK_SEL_Pos (2UL) /*!< UART2_CLK_SEL (Bit 2) */ +#define CRG_COM_RESET_CLK_COM_REG_UART2_CLK_SEL_Msk (0x4UL) /*!< UART2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_UART2_ENABLE_Pos (1UL) /*!< UART2_ENABLE (Bit 1) */ +#define CRG_COM_RESET_CLK_COM_REG_UART2_ENABLE_Msk (0x2UL) /*!< UART2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_RESET_CLK_COM_REG_UART_ENABLE_Pos (0UL) /*!< UART_ENABLE (Bit 0) */ +#define CRG_COM_RESET_CLK_COM_REG_UART_ENABLE_Msk (0x1UL) /*!< UART_ENABLE (Bitfield-Mask: 0x01) */ +/* ==================================================== SET_CLK_COM_REG ==================================================== */ +#define CRG_COM_SET_CLK_COM_REG_LCD_EXT_CLK_SEL_Pos (16UL) /*!< LCD_EXT_CLK_SEL (Bit 16) */ +#define CRG_COM_SET_CLK_COM_REG_LCD_EXT_CLK_SEL_Msk (0x30000UL) /*!< LCD_EXT_CLK_SEL (Bitfield-Mask: 0x03) */ +#define CRG_COM_SET_CLK_COM_REG_SNC_DIV_Pos (14UL) /*!< SNC_DIV (Bit 14) */ +#define CRG_COM_SET_CLK_COM_REG_SNC_DIV_Msk (0xc000UL) /*!< SNC_DIV (Bitfield-Mask: 0x03) */ +#define CRG_COM_SET_CLK_COM_REG_I2C2_CLK_SEL_Pos (12UL) /*!< I2C2_CLK_SEL (Bit 12) */ +#define CRG_COM_SET_CLK_COM_REG_I2C2_CLK_SEL_Msk (0x1000UL) /*!< I2C2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_I2C2_ENABLE_Pos (11UL) /*!< I2C2_ENABLE (Bit 11) */ +#define CRG_COM_SET_CLK_COM_REG_I2C2_ENABLE_Msk (0x800UL) /*!< I2C2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_I2C_CLK_SEL_Pos (10UL) /*!< I2C_CLK_SEL (Bit 10) */ +#define CRG_COM_SET_CLK_COM_REG_I2C_CLK_SEL_Msk (0x400UL) /*!< I2C_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_I2C_ENABLE_Pos (9UL) /*!< I2C_ENABLE (Bit 9) */ +#define CRG_COM_SET_CLK_COM_REG_I2C_ENABLE_Msk (0x200UL) /*!< I2C_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_SPI2_CLK_SEL_Pos (8UL) /*!< SPI2_CLK_SEL (Bit 8) */ +#define CRG_COM_SET_CLK_COM_REG_SPI2_CLK_SEL_Msk (0x100UL) /*!< SPI2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_SPI2_ENABLE_Pos (7UL) /*!< SPI2_ENABLE (Bit 7) */ +#define CRG_COM_SET_CLK_COM_REG_SPI2_ENABLE_Msk (0x80UL) /*!< SPI2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_SPI_CLK_SEL_Pos (6UL) /*!< SPI_CLK_SEL (Bit 6) */ +#define CRG_COM_SET_CLK_COM_REG_SPI_CLK_SEL_Msk (0x40UL) /*!< SPI_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_SPI_ENABLE_Pos (5UL) /*!< SPI_ENABLE (Bit 5) */ +#define CRG_COM_SET_CLK_COM_REG_SPI_ENABLE_Msk (0x20UL) /*!< SPI_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_UART3_CLK_SEL_Pos (4UL) /*!< UART3_CLK_SEL (Bit 4) */ +#define CRG_COM_SET_CLK_COM_REG_UART3_CLK_SEL_Msk (0x10UL) /*!< UART3_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_UART3_ENABLE_Pos (3UL) /*!< UART3_ENABLE (Bit 3) */ +#define CRG_COM_SET_CLK_COM_REG_UART3_ENABLE_Msk (0x8UL) /*!< UART3_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_UART2_CLK_SEL_Pos (2UL) /*!< UART2_CLK_SEL (Bit 2) */ +#define CRG_COM_SET_CLK_COM_REG_UART2_CLK_SEL_Msk (0x4UL) /*!< UART2_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_UART2_ENABLE_Pos (1UL) /*!< UART2_ENABLE (Bit 1) */ +#define CRG_COM_SET_CLK_COM_REG_UART2_ENABLE_Msk (0x2UL) /*!< UART2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_COM_SET_CLK_COM_REG_UART_ENABLE_Pos (0UL) /*!< UART_ENABLE (Bit 0) */ +#define CRG_COM_SET_CLK_COM_REG_UART_ENABLE_Msk (0x1UL) /*!< UART_ENABLE (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ CRG_PER ================ */ +/* =========================================================================================================================== */ + +/* ====================================================== CLK_PER_REG ====================================================== */ +#define CRG_PER_CLK_PER_REG_MC_TRIG_DIV_Pos (8UL) /*!< MC_TRIG_DIV (Bit 8) */ +#define CRG_PER_CLK_PER_REG_MC_TRIG_DIV_Msk (0x1f00UL) /*!< MC_TRIG_DIV (Bitfield-Mask: 0x1f) */ +#define CRG_PER_CLK_PER_REG_MC_CLK_DIV_Pos (3UL) /*!< MC_CLK_DIV (Bit 3) */ +#define CRG_PER_CLK_PER_REG_MC_CLK_DIV_Msk (0xf8UL) /*!< MC_CLK_DIV (Bitfield-Mask: 0x1f) */ +#define CRG_PER_CLK_PER_REG_MC_CLK_EN_Pos (2UL) /*!< MC_CLK_EN (Bit 2) */ +#define CRG_PER_CLK_PER_REG_MC_CLK_EN_Msk (0x4UL) /*!< MC_CLK_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_CLK_PER_REG_LRA_CLK_EN_Pos (1UL) /*!< LRA_CLK_EN (Bit 1) */ +#define CRG_PER_CLK_PER_REG_LRA_CLK_EN_Msk (0x2UL) /*!< LRA_CLK_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_CLK_PER_REG_GPADC_CLK_SEL_Pos (0UL) /*!< GPADC_CLK_SEL (Bit 0) */ +#define CRG_PER_CLK_PER_REG_GPADC_CLK_SEL_Msk (0x1UL) /*!< GPADC_CLK_SEL (Bitfield-Mask: 0x01) */ +/* ====================================================== PCM_DIV_REG ====================================================== */ +#define CRG_PER_PCM_DIV_REG_PCM_SRC_SEL_Pos (13UL) /*!< PCM_SRC_SEL (Bit 13) */ +#define CRG_PER_PCM_DIV_REG_PCM_SRC_SEL_Msk (0x2000UL) /*!< PCM_SRC_SEL (Bitfield-Mask: 0x01) */ +#define CRG_PER_PCM_DIV_REG_CLK_PCM_EN_Pos (12UL) /*!< CLK_PCM_EN (Bit 12) */ +#define CRG_PER_PCM_DIV_REG_CLK_PCM_EN_Msk (0x1000UL) /*!< CLK_PCM_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_PCM_DIV_REG_PCM_DIV_Pos (0UL) /*!< PCM_DIV (Bit 0) */ +#define CRG_PER_PCM_DIV_REG_PCM_DIV_Msk (0xfffUL) /*!< PCM_DIV (Bitfield-Mask: 0xfff) */ +/* ===================================================== PCM_FDIV_REG ====================================================== */ +#define CRG_PER_PCM_FDIV_REG_PCM_FDIV_Pos (0UL) /*!< PCM_FDIV (Bit 0) */ +#define CRG_PER_PCM_FDIV_REG_PCM_FDIV_Msk (0xffffUL) /*!< PCM_FDIV (Bitfield-Mask: 0xffff) */ +/* ====================================================== PDM_DIV_REG ====================================================== */ +#define CRG_PER_PDM_DIV_REG_PDM_MASTER_MODE_Pos (9UL) /*!< PDM_MASTER_MODE (Bit 9) */ +#define CRG_PER_PDM_DIV_REG_PDM_MASTER_MODE_Msk (0x200UL) /*!< PDM_MASTER_MODE (Bitfield-Mask: 0x01) */ +#define CRG_PER_PDM_DIV_REG_CLK_PDM_EN_Pos (8UL) /*!< CLK_PDM_EN (Bit 8) */ +#define CRG_PER_PDM_DIV_REG_CLK_PDM_EN_Msk (0x100UL) /*!< CLK_PDM_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_PDM_DIV_REG_PDM_DIV_Pos (0UL) /*!< PDM_DIV (Bit 0) */ +#define CRG_PER_PDM_DIV_REG_PDM_DIV_Msk (0xffUL) /*!< PDM_DIV (Bitfield-Mask: 0xff) */ +/* =================================================== RESET_CLK_PER_REG =================================================== */ +#define CRG_PER_RESET_CLK_PER_REG_MC_TRIG_DIV_Pos (8UL) /*!< MC_TRIG_DIV (Bit 8) */ +#define CRG_PER_RESET_CLK_PER_REG_MC_TRIG_DIV_Msk (0x1f00UL) /*!< MC_TRIG_DIV (Bitfield-Mask: 0x1f) */ +#define CRG_PER_RESET_CLK_PER_REG_MC_CLK_DIV_Pos (3UL) /*!< MC_CLK_DIV (Bit 3) */ +#define CRG_PER_RESET_CLK_PER_REG_MC_CLK_DIV_Msk (0xf8UL) /*!< MC_CLK_DIV (Bitfield-Mask: 0x1f) */ +#define CRG_PER_RESET_CLK_PER_REG_MC_CLK_EN_Pos (2UL) /*!< MC_CLK_EN (Bit 2) */ +#define CRG_PER_RESET_CLK_PER_REG_MC_CLK_EN_Msk (0x4UL) /*!< MC_CLK_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_RESET_CLK_PER_REG_LRA_CLK_EN_Pos (1UL) /*!< LRA_CLK_EN (Bit 1) */ +#define CRG_PER_RESET_CLK_PER_REG_LRA_CLK_EN_Msk (0x2UL) /*!< LRA_CLK_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_RESET_CLK_PER_REG_GPADC_CLK_SEL_Pos (0UL) /*!< GPADC_CLK_SEL (Bit 0) */ +#define CRG_PER_RESET_CLK_PER_REG_GPADC_CLK_SEL_Msk (0x1UL) /*!< GPADC_CLK_SEL (Bitfield-Mask: 0x01) */ +/* ==================================================== SET_CLK_PER_REG ==================================================== */ +#define CRG_PER_SET_CLK_PER_REG_MC_TRIG_DIV_Pos (8UL) /*!< MC_TRIG_DIV (Bit 8) */ +#define CRG_PER_SET_CLK_PER_REG_MC_TRIG_DIV_Msk (0x1f00UL) /*!< MC_TRIG_DIV (Bitfield-Mask: 0x1f) */ +#define CRG_PER_SET_CLK_PER_REG_MC_CLK_DIV_Pos (3UL) /*!< MC_CLK_DIV (Bit 3) */ +#define CRG_PER_SET_CLK_PER_REG_MC_CLK_DIV_Msk (0xf8UL) /*!< MC_CLK_DIV (Bitfield-Mask: 0x1f) */ +#define CRG_PER_SET_CLK_PER_REG_MC_CLK_EN_Pos (2UL) /*!< MC_CLK_EN (Bit 2) */ +#define CRG_PER_SET_CLK_PER_REG_MC_CLK_EN_Msk (0x4UL) /*!< MC_CLK_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_SET_CLK_PER_REG_LRA_CLK_EN_Pos (1UL) /*!< LRA_CLK_EN (Bit 1) */ +#define CRG_PER_SET_CLK_PER_REG_LRA_CLK_EN_Msk (0x2UL) /*!< LRA_CLK_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_SET_CLK_PER_REG_GPADC_CLK_SEL_Pos (0UL) /*!< GPADC_CLK_SEL (Bit 0) */ +#define CRG_PER_SET_CLK_PER_REG_GPADC_CLK_SEL_Msk (0x1UL) /*!< GPADC_CLK_SEL (Bitfield-Mask: 0x01) */ +/* ====================================================== SRC_DIV_REG ====================================================== */ +#define CRG_PER_SRC_DIV_REG_CLK_SRC_EN_Pos (8UL) /*!< CLK_SRC_EN (Bit 8) */ +#define CRG_PER_SRC_DIV_REG_CLK_SRC_EN_Msk (0x100UL) /*!< CLK_SRC_EN (Bitfield-Mask: 0x01) */ +#define CRG_PER_SRC_DIV_REG_SRC_DIV_Pos (0UL) /*!< SRC_DIV (Bit 0) */ +#define CRG_PER_SRC_DIV_REG_SRC_DIV_Msk (0xffUL) /*!< SRC_DIV (Bitfield-Mask: 0xff) */ + + +/* =========================================================================================================================== */ +/* ================ CRG_SYS ================ */ +/* =========================================================================================================================== */ + +/* ===================================================== BATCHECK_REG ====================================================== */ +#define CRG_SYS_BATCHECK_REG_BATCHECK_LOAD_ENABLE_Pos (7UL) /*!< BATCHECK_LOAD_ENABLE (Bit 7) */ +#define CRG_SYS_BATCHECK_REG_BATCHECK_LOAD_ENABLE_Msk (0x80UL) /*!< BATCHECK_LOAD_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_SYS_BATCHECK_REG_BATCHECK_ILOAD_Pos (4UL) /*!< BATCHECK_ILOAD (Bit 4) */ +#define CRG_SYS_BATCHECK_REG_BATCHECK_ILOAD_Msk (0x70UL) /*!< BATCHECK_ILOAD (Bitfield-Mask: 0x07) */ +#define CRG_SYS_BATCHECK_REG_BATCHECK_TRIM_Pos (0UL) /*!< BATCHECK_TRIM (Bit 0) */ +#define CRG_SYS_BATCHECK_REG_BATCHECK_TRIM_Msk (0xfUL) /*!< BATCHECK_TRIM (Bitfield-Mask: 0x0f) */ +/* ====================================================== CLK_SYS_REG ====================================================== */ +#define CRG_SYS_CLK_SYS_REG_CLK_CHG_EN_Pos (5UL) /*!< CLK_CHG_EN (Bit 5) */ +#define CRG_SYS_CLK_SYS_REG_CLK_CHG_EN_Msk (0x20UL) /*!< CLK_CHG_EN (Bitfield-Mask: 0x01) */ +#define CRG_SYS_CLK_SYS_REG_LCD_RESET_REQ_Pos (4UL) /*!< LCD_RESET_REQ (Bit 4) */ +#define CRG_SYS_CLK_SYS_REG_LCD_RESET_REQ_Msk (0x10UL) /*!< LCD_RESET_REQ (Bitfield-Mask: 0x01) */ +#define CRG_SYS_CLK_SYS_REG_LCD_CLK_SEL_Pos (1UL) /*!< LCD_CLK_SEL (Bit 1) */ +#define CRG_SYS_CLK_SYS_REG_LCD_CLK_SEL_Msk (0x2UL) /*!< LCD_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_SYS_CLK_SYS_REG_LCD_ENABLE_Pos (0UL) /*!< LCD_ENABLE (Bit 0) */ +#define CRG_SYS_CLK_SYS_REG_LCD_ENABLE_Msk (0x1UL) /*!< LCD_ENABLE (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ CRG_TOP ================ */ +/* =========================================================================================================================== */ + +/* ==================================================== ANA_STATUS_REG ===================================================== */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VBUS_HIGH_Pos (14UL) /*!< COMP_VBUS_HIGH (Bit 14) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VBUS_HIGH_Msk (0x4000UL) /*!< COMP_VBUS_HIGH (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VBUS_LOW_Pos (13UL) /*!< COMP_VBUS_LOW (Bit 13) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VBUS_LOW_Msk (0x2000UL) /*!< COMP_VBUS_LOW (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VBAT_HIGH_Pos (12UL) /*!< COMP_VBAT_HIGH (Bit 12) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VBAT_HIGH_Msk (0x1000UL) /*!< COMP_VBAT_HIGH (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VBAT_LOW_Pos (11UL) /*!< COMP_VBAT_LOW (Bit 11) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VBAT_LOW_Msk (0x800UL) /*!< COMP_VBAT_LOW (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VDD_OK_Pos (10UL) /*!< COMP_VDD_OK (Bit 10) */ +#define CRG_TOP_ANA_STATUS_REG_COMP_VDD_OK_Msk (0x400UL) /*!< COMP_VDD_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Pos (9UL) /*!< VBUS_AVAILABLE (Bit 9) */ +#define CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Msk (0x200UL) /*!< VBUS_AVAILABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_BANDGAP_OK_Pos (8UL) /*!< BANDGAP_OK (Bit 8) */ +#define CRG_TOP_ANA_STATUS_REG_BANDGAP_OK_Msk (0x100UL) /*!< BANDGAP_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_3V0_VBAT_OK_Pos (7UL) /*!< LDO_3V0_VBAT_OK (Bit 7) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_3V0_VBAT_OK_Msk (0x80UL) /*!< LDO_3V0_VBAT_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_3V0_VBUS_OK_Pos (6UL) /*!< LDO_3V0_VBUS_OK (Bit 6) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_3V0_VBUS_OK_Msk (0x40UL) /*!< LDO_3V0_VBUS_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_1V8P_OK_Pos (5UL) /*!< LDO_1V8P_OK (Bit 5) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_1V8P_OK_Msk (0x20UL) /*!< LDO_1V8P_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_1V8_OK_Pos (4UL) /*!< LDO_1V8_OK (Bit 4) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_1V8_OK_Msk (0x10UL) /*!< LDO_1V8_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_RADIO_OK_Pos (3UL) /*!< LDO_RADIO_OK (Bit 3) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_RADIO_OK_Msk (0x8UL) /*!< LDO_RADIO_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_CORE_OK_Pos (2UL) /*!< LDO_CORE_OK (Bit 2) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_CORE_OK_Msk (0x4UL) /*!< LDO_CORE_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_VDD_HIGH_OK_Pos (1UL) /*!< LDO_VDD_HIGH_OK (Bit 1) */ +#define CRG_TOP_ANA_STATUS_REG_LDO_VDD_HIGH_OK_Msk (0x2UL) /*!< LDO_VDD_HIGH_OK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_ANA_STATUS_REG_BOD_VIN_NOK_Pos (0UL) /*!< BOD_VIN_NOK (Bit 0) */ +#define CRG_TOP_ANA_STATUS_REG_BOD_VIN_NOK_Msk (0x1UL) /*!< BOD_VIN_NOK (Bitfield-Mask: 0x01) */ +/* ====================================================== BANDGAP_REG ====================================================== */ +#define CRG_TOP_BANDGAP_REG_BANDGAP_ENABLE_CLAMP_Pos (12UL) /*!< BANDGAP_ENABLE_CLAMP (Bit 12) */ +#define CRG_TOP_BANDGAP_REG_BANDGAP_ENABLE_CLAMP_Msk (0x1000UL) /*!< BANDGAP_ENABLE_CLAMP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BANDGAP_REG_BGR_ITRIM_Pos (6UL) /*!< BGR_ITRIM (Bit 6) */ +#define CRG_TOP_BANDGAP_REG_BGR_ITRIM_Msk (0xfc0UL) /*!< BGR_ITRIM (Bitfield-Mask: 0x3f) */ +#define CRG_TOP_BANDGAP_REG_SYSRAM_LPMX_Pos (5UL) /*!< SYSRAM_LPMX (Bit 5) */ +#define CRG_TOP_BANDGAP_REG_SYSRAM_LPMX_Msk (0x20UL) /*!< SYSRAM_LPMX (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BANDGAP_REG_BGR_TRIM_Pos (0UL) /*!< BGR_TRIM (Bit 0) */ +#define CRG_TOP_BANDGAP_REG_BGR_TRIM_Msk (0x1fUL) /*!< BGR_TRIM (Bitfield-Mask: 0x1f) */ +/* =================================================== BIAS_VREF_SEL_REG =================================================== */ +#define CRG_TOP_BIAS_VREF_SEL_REG_BIAS_VREF_RF2_SEL_Pos (4UL) /*!< BIAS_VREF_RF2_SEL (Bit 4) */ +#define CRG_TOP_BIAS_VREF_SEL_REG_BIAS_VREF_RF2_SEL_Msk (0xf0UL) /*!< BIAS_VREF_RF2_SEL (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_BIAS_VREF_SEL_REG_BIAS_VREF_RF1_SEL_Pos (0UL) /*!< BIAS_VREF_RF1_SEL (Bit 0) */ +#define CRG_TOP_BIAS_VREF_SEL_REG_BIAS_VREF_RF1_SEL_Msk (0xfUL) /*!< BIAS_VREF_RF1_SEL (Bitfield-Mask: 0x0f) */ +/* ===================================================== BOD_CTRL_REG ====================================================== */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V14_RST_EN_Pos (16UL) /*!< BOD_V14_RST_EN (Bit 16) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V14_RST_EN_Msk (0x10000UL) /*!< BOD_V14_RST_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18F_RST_EN_Pos (15UL) /*!< BOD_V18F_RST_EN (Bit 15) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18F_RST_EN_Msk (0x8000UL) /*!< BOD_V18F_RST_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_VDD_RST_EN_Pos (14UL) /*!< BOD_VDD_RST_EN (Bit 14) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_VDD_RST_EN_Msk (0x4000UL) /*!< BOD_VDD_RST_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18P_RST_EN_Pos (13UL) /*!< BOD_V18P_RST_EN (Bit 13) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18P_RST_EN_Msk (0x2000UL) /*!< BOD_V18P_RST_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18_RST_EN_Pos (12UL) /*!< BOD_V18_RST_EN (Bit 12) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18_RST_EN_Msk (0x1000UL) /*!< BOD_V18_RST_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V30_RST_EN_Pos (11UL) /*!< BOD_V30_RST_EN (Bit 11) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V30_RST_EN_Msk (0x800UL) /*!< BOD_V30_RST_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_VBAT_RST_EN_Pos (10UL) /*!< BOD_VBAT_RST_EN (Bit 10) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_VBAT_RST_EN_Msk (0x400UL) /*!< BOD_VBAT_RST_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V14_EN_Pos (9UL) /*!< BOD_V14_EN (Bit 9) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V14_EN_Msk (0x200UL) /*!< BOD_V14_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18F_EN_Pos (8UL) /*!< BOD_V18F_EN (Bit 8) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18F_EN_Msk (0x100UL) /*!< BOD_V18F_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_VDD_EN_Pos (7UL) /*!< BOD_VDD_EN (Bit 7) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_VDD_EN_Msk (0x80UL) /*!< BOD_VDD_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18P_EN_Pos (6UL) /*!< BOD_V18P_EN (Bit 6) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18P_EN_Msk (0x40UL) /*!< BOD_V18P_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18_EN_Pos (5UL) /*!< BOD_V18_EN (Bit 5) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V18_EN_Msk (0x20UL) /*!< BOD_V18_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V30_EN_Pos (4UL) /*!< BOD_V30_EN (Bit 4) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_V30_EN_Msk (0x10UL) /*!< BOD_V30_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_VBAT_EN_Pos (3UL) /*!< BOD_VBAT_EN (Bit 3) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_VBAT_EN_Msk (0x8UL) /*!< BOD_VBAT_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_STATUS_CLEAR_Pos (2UL) /*!< BOD_STATUS_CLEAR (Bit 2) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_STATUS_CLEAR_Msk (0x4UL) /*!< BOD_STATUS_CLEAR (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_CLK_DIV_Pos (0UL) /*!< BOD_CLK_DIV (Bit 0) */ +#define CRG_TOP_BOD_CTRL_REG_BOD_CLK_DIV_Msk (0x3UL) /*!< BOD_CLK_DIV (Bitfield-Mask: 0x03) */ +/* =================================================== BOD_LVL_CTRL0_REG =================================================== */ +#define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_V18_Pos (18UL) /*!< BOD_LVL_V18 (Bit 18) */ +#define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_V18_Msk (0x7fc0000UL) /*!< BOD_LVL_V18 (Bitfield-Mask: 0x1ff) */ +#define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_V30_Pos (9UL) /*!< BOD_LVL_V30 (Bit 9) */ +#define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_V30_Msk (0x3fe00UL) /*!< BOD_LVL_V30 (Bitfield-Mask: 0x1ff) */ +#define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_VBAT_Pos (0UL) /*!< BOD_LVL_VBAT (Bit 0) */ +#define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_VBAT_Msk (0x1ffUL) /*!< BOD_LVL_VBAT (Bitfield-Mask: 0x1ff) */ +/* =================================================== BOD_LVL_CTRL1_REG =================================================== */ +#define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_VDD_RET_Pos (17UL) /*!< BOD_LVL_VDD_RET (Bit 17) */ +#define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_VDD_RET_Msk (0x1fe0000UL) /*!< BOD_LVL_VDD_RET (Bitfield-Mask: 0xff) */ +#define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_VDD_ON_Pos (9UL) /*!< BOD_LVL_VDD_ON (Bit 9) */ +#define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_VDD_ON_Msk (0x1fe00UL) /*!< BOD_LVL_VDD_ON (Bitfield-Mask: 0xff) */ +#define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_V18P_Pos (0UL) /*!< BOD_LVL_V18P (Bit 0) */ +#define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_V18P_Msk (0x1ffUL) /*!< BOD_LVL_V18P (Bitfield-Mask: 0x1ff) */ +/* =================================================== BOD_LVL_CTRL2_REG =================================================== */ +#define CRG_TOP_BOD_LVL_CTRL2_REG_BOD_LVL_V14_Pos (9UL) /*!< BOD_LVL_V14 (Bit 9) */ +#define CRG_TOP_BOD_LVL_CTRL2_REG_BOD_LVL_V14_Msk (0x3fe00UL) /*!< BOD_LVL_V14 (Bitfield-Mask: 0x1ff) */ +#define CRG_TOP_BOD_LVL_CTRL2_REG_BOD_LVL_V18F_Pos (0UL) /*!< BOD_LVL_V18F (Bit 0) */ +#define CRG_TOP_BOD_LVL_CTRL2_REG_BOD_LVL_V18F_Msk (0x1ffUL) /*!< BOD_LVL_V18F (Bitfield-Mask: 0x1ff) */ +/* ==================================================== BOD_STATUS_REG ===================================================== */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V14_Pos (6UL) /*!< BOD_V14 (Bit 6) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V14_Msk (0x40UL) /*!< BOD_V14 (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V18F_Pos (5UL) /*!< BOD_V18F (Bit 5) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V18F_Msk (0x20UL) /*!< BOD_V18F (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_VDD_Pos (4UL) /*!< BOD_VDD (Bit 4) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_VDD_Msk (0x10UL) /*!< BOD_VDD (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V18P_Pos (3UL) /*!< BOD_V18P (Bit 3) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V18P_Msk (0x8UL) /*!< BOD_V18P (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V18_Pos (2UL) /*!< BOD_V18 (Bit 2) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V18_Msk (0x4UL) /*!< BOD_V18 (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V30_Pos (1UL) /*!< BOD_V30 (Bit 1) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_V30_Msk (0x2UL) /*!< BOD_V30 (Bitfield-Mask: 0x01) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_VBAT_Pos (0UL) /*!< BOD_VBAT (Bit 0) */ +#define CRG_TOP_BOD_STATUS_REG_BOD_VBAT_Msk (0x1UL) /*!< BOD_VBAT (Bitfield-Mask: 0x01) */ +/* ===================================================== CLK_AMBA_REG ====================================================== */ +#define CRG_TOP_CLK_AMBA_REG_QSPI2_ENABLE_Pos (15UL) /*!< QSPI2_ENABLE (Bit 15) */ +#define CRG_TOP_CLK_AMBA_REG_QSPI2_ENABLE_Msk (0x8000UL) /*!< QSPI2_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_AMBA_REG_QSPI2_DIV_Pos (13UL) /*!< QSPI2_DIV (Bit 13) */ +#define CRG_TOP_CLK_AMBA_REG_QSPI2_DIV_Msk (0x6000UL) /*!< QSPI2_DIV (Bitfield-Mask: 0x03) */ +#define CRG_TOP_CLK_AMBA_REG_QSPI_ENABLE_Pos (12UL) /*!< QSPI_ENABLE (Bit 12) */ +#define CRG_TOP_CLK_AMBA_REG_QSPI_ENABLE_Msk (0x1000UL) /*!< QSPI_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_AMBA_REG_QSPI_DIV_Pos (10UL) /*!< QSPI_DIV (Bit 10) */ +#define CRG_TOP_CLK_AMBA_REG_QSPI_DIV_Msk (0xc00UL) /*!< QSPI_DIV (Bitfield-Mask: 0x03) */ +#define CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Pos (9UL) /*!< OTP_ENABLE (Bit 9) */ +#define CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk (0x200UL) /*!< OTP_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_AMBA_REG_TRNG_CLK_ENABLE_Pos (8UL) /*!< TRNG_CLK_ENABLE (Bit 8) */ +#define CRG_TOP_CLK_AMBA_REG_TRNG_CLK_ENABLE_Msk (0x100UL) /*!< TRNG_CLK_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Pos (6UL) /*!< AES_CLK_ENABLE (Bit 6) */ +#define CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Msk (0x40UL) /*!< AES_CLK_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Pos (4UL) /*!< PCLK_DIV (Bit 4) */ +#define CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk (0x30UL) /*!< PCLK_DIV (Bitfield-Mask: 0x03) */ +#define CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Pos (0UL) /*!< HCLK_DIV (Bit 0) */ +#define CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk (0x7UL) /*!< HCLK_DIV (Bitfield-Mask: 0x07) */ +/* ===================================================== CLK_CTRL_REG ====================================================== */ +#define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Pos (15UL) /*!< RUNNING_AT_PLL96M (Bit 15) */ +#define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk (0x8000UL) /*!< RUNNING_AT_PLL96M (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Pos (14UL) /*!< RUNNING_AT_XTAL32M (Bit 14) */ +#define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Msk (0x4000UL) /*!< RUNNING_AT_XTAL32M (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Pos (13UL) /*!< RUNNING_AT_RC32M (Bit 13) */ +#define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk (0x2000UL) /*!< RUNNING_AT_RC32M (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Pos (12UL) /*!< RUNNING_AT_LP_CLK (Bit 12) */ +#define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Msk (0x1000UL) /*!< RUNNING_AT_LP_CLK (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Pos (4UL) /*!< USB_CLK_SRC (Bit 4) */ +#define CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Msk (0x10UL) /*!< USB_CLK_SRC (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos (2UL) /*!< LP_CLK_SEL (Bit 2) */ +#define CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk (0xcUL) /*!< LP_CLK_SEL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos (0UL) /*!< SYS_CLK_SEL (Bit 0) */ +#define CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk (0x3UL) /*!< SYS_CLK_SEL (Bitfield-Mask: 0x03) */ +/* ===================================================== CLK_RADIO_REG ===================================================== */ +#define CRG_TOP_CLK_RADIO_REG_RFCU_ENABLE_Pos (5UL) /*!< RFCU_ENABLE (Bit 5) */ +#define CRG_TOP_CLK_RADIO_REG_RFCU_ENABLE_Msk (0x20UL) /*!< RFCU_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Pos (4UL) /*!< CMAC_SYNCH_RESET (Bit 4) */ +#define CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk (0x10UL) /*!< CMAC_SYNCH_RESET (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RADIO_REG_CMAC_CLK_SEL_Pos (3UL) /*!< CMAC_CLK_SEL (Bit 3) */ +#define CRG_TOP_CLK_RADIO_REG_CMAC_CLK_SEL_Msk (0x8UL) /*!< CMAC_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RADIO_REG_CMAC_CLK_ENABLE_Pos (2UL) /*!< CMAC_CLK_ENABLE (Bit 2) */ +#define CRG_TOP_CLK_RADIO_REG_CMAC_CLK_ENABLE_Msk (0x4UL) /*!< CMAC_CLK_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RADIO_REG_CMAC_DIV_Pos (0UL) /*!< CMAC_DIV (Bit 0) */ +#define CRG_TOP_CLK_RADIO_REG_CMAC_DIV_Msk (0x3UL) /*!< CMAC_DIV (Bitfield-Mask: 0x03) */ +/* ===================================================== CLK_RC32K_REG ===================================================== */ +#define CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Pos (1UL) /*!< RC32K_TRIM (Bit 1) */ +#define CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Msk (0x1eUL) /*!< RC32K_TRIM (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Pos (0UL) /*!< RC32K_ENABLE (Bit 0) */ +#define CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk (0x1UL) /*!< RC32K_ENABLE (Bitfield-Mask: 0x01) */ +/* ===================================================== CLK_RC32M_REG ===================================================== */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_RANGE_Pos (20UL) /*!< RC32M_INIT_RANGE (Bit 20) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_RANGE_Msk (0x300000UL) /*!< RC32M_INIT_RANGE (Bitfield-Mask: 0x03) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DEL_Pos (12UL) /*!< RC32M_INIT_DEL (Bit 12) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DEL_Msk (0xff000UL) /*!< RC32M_INIT_DEL (Bitfield-Mask: 0xff) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DTCF_Pos (9UL) /*!< RC32M_INIT_DTCF (Bit 9) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DTCF_Msk (0xe00UL) /*!< RC32M_INIT_DTCF (Bitfield-Mask: 0x07) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DTC_Pos (5UL) /*!< RC32M_INIT_DTC (Bit 5) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DTC_Msk (0x1e0UL) /*!< RC32M_INIT_DTC (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_BIAS_Pos (1UL) /*!< RC32M_BIAS (Bit 1) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_BIAS_Msk (0x1eUL) /*!< RC32M_BIAS (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Pos (0UL) /*!< RC32M_ENABLE (Bit 0) */ +#define CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk (0x1UL) /*!< RC32M_ENABLE (Bitfield-Mask: 0x01) */ +/* ====================================================== CLK_RCX_REG ====================================================== */ +#define CRG_TOP_CLK_RCX_REG_RCX_BIAS_Pos (8UL) /*!< RCX_BIAS (Bit 8) */ +#define CRG_TOP_CLK_RCX_REG_RCX_BIAS_Msk (0xf00UL) /*!< RCX_BIAS (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_CLK_RCX_REG_RCX_C0_Pos (7UL) /*!< RCX_C0 (Bit 7) */ +#define CRG_TOP_CLK_RCX_REG_RCX_C0_Msk (0x80UL) /*!< RCX_C0 (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RCX_REG_RCX_CADJUST_Pos (2UL) /*!< RCX_CADJUST (Bit 2) */ +#define CRG_TOP_CLK_RCX_REG_RCX_CADJUST_Msk (0x7cUL) /*!< RCX_CADJUST (Bitfield-Mask: 0x1f) */ +#define CRG_TOP_CLK_RCX_REG_RCX_RADJUST_Pos (1UL) /*!< RCX_RADJUST (Bit 1) */ +#define CRG_TOP_CLK_RCX_REG_RCX_RADJUST_Msk (0x2UL) /*!< RCX_RADJUST (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Pos (0UL) /*!< RCX_ENABLE (Bit 0) */ +#define CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Msk (0x1UL) /*!< RCX_ENABLE (Bitfield-Mask: 0x01) */ +/* ==================================================== CLK_RTCDIV_REG ===================================================== */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_RESET_REQ_Pos (21UL) /*!< RTC_RESET_REQ (Bit 21) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_RESET_REQ_Msk (0x200000UL) /*!< RTC_RESET_REQ (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ENABLE_Pos (20UL) /*!< RTC_DIV_ENABLE (Bit 20) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ENABLE_Msk (0x100000UL) /*!< RTC_DIV_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_DENOM_Pos (19UL) /*!< RTC_DIV_DENOM (Bit 19) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_DENOM_Msk (0x80000UL) /*!< RTC_DIV_DENOM (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_INT_Pos (10UL) /*!< RTC_DIV_INT (Bit 10) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_INT_Msk (0x7fc00UL) /*!< RTC_DIV_INT (Bitfield-Mask: 0x1ff) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_FRAC_Pos (0UL) /*!< RTC_DIV_FRAC (Bit 0) */ +#define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_FRAC_Msk (0x3ffUL) /*!< RTC_DIV_FRAC (Bitfield-Mask: 0x3ff) */ +/* ================================================== CLK_SWITCH2XTAL_REG ================================================== */ +#define CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Pos (0UL) /*!< SWITCH2XTAL (Bit 0) */ +#define CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk (0x1UL) /*!< SWITCH2XTAL (Bitfield-Mask: 0x01) */ +/* ====================================================== CLK_TMR_REG ====================================================== */ +#define CRG_TOP_CLK_TMR_REG_TMR2_PWM_AON_MODE_Pos (2UL) /*!< TMR2_PWM_AON_MODE (Bit 2) */ +#define CRG_TOP_CLK_TMR_REG_TMR2_PWM_AON_MODE_Msk (0x4UL) /*!< TMR2_PWM_AON_MODE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_TMR_REG_TMR_PWM_AON_MODE_Pos (1UL) /*!< TMR_PWM_AON_MODE (Bit 1) */ +#define CRG_TOP_CLK_TMR_REG_TMR_PWM_AON_MODE_Msk (0x2UL) /*!< TMR_PWM_AON_MODE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Pos (0UL) /*!< WAKEUPCT_ENABLE (Bit 0) */ +#define CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Msk (0x1UL) /*!< WAKEUPCT_ENABLE (Bitfield-Mask: 0x01) */ +/* ==================================================== CLK_XTAL32K_REG ==================================================== */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_DISABLE_OUTPUT_Pos (9UL) /*!< XTAL32K_DISABLE_OUTPUT (Bit 9) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_DISABLE_OUTPUT_Msk (0x200UL) /*!< XTAL32K_DISABLE_OUTPUT (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_DISABLE_AMPREG_Pos (7UL) /*!< XTAL32K_DISABLE_AMPREG (Bit 7) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_DISABLE_AMPREG_Msk (0x80UL) /*!< XTAL32K_DISABLE_AMPREG (Bitfield-Mask: 0x01) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_CUR_Pos (3UL) /*!< XTAL32K_CUR (Bit 3) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_CUR_Msk (0x78UL) /*!< XTAL32K_CUR (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_RBIAS_Pos (1UL) /*!< XTAL32K_RBIAS (Bit 1) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_RBIAS_Msk (0x6UL) /*!< XTAL32K_RBIAS (Bitfield-Mask: 0x03) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Pos (0UL) /*!< XTAL32K_ENABLE (Bit 0) */ +#define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Msk (0x1UL) /*!< XTAL32K_ENABLE (Bitfield-Mask: 0x01) */ +/* ================================================== DISCHARGE_RAIL_REG =================================================== */ +#define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V18P_Pos (2UL) /*!< RESET_V18P (Bit 2) */ +#define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V18P_Msk (0x4UL) /*!< RESET_V18P (Bitfield-Mask: 0x01) */ +#define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V18_Pos (1UL) /*!< RESET_V18 (Bit 1) */ +#define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V18_Msk (0x2UL) /*!< RESET_V18 (Bitfield-Mask: 0x01) */ +#define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V14_Pos (0UL) /*!< RESET_V14 (Bit 0) */ +#define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V14_Msk (0x1UL) /*!< RESET_V14 (Bitfield-Mask: 0x01) */ +/* ================================================ LDO_VDDD_HIGH_CTRL_REG ================================================= */ +#define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_LOW_ZOUT_DISABLE_Pos (3UL) /*!< LDO_VDDD_HIGH_LOW_ZOUT_DISABLE (Bit 3) */ +#define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_LOW_ZOUT_DISABLE_Msk (0x8UL) /*!< LDO_VDDD_HIGH_LOW_ZOUT_DISABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_STATIC_LOAD_ENABLE_Pos (2UL) /*!< LDO_VDDD_HIGH_STATIC_LOAD_ENABLE (Bit 2) */ +#define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_STATIC_LOAD_ENABLE_Msk (0x4UL) /*!< LDO_VDDD_HIGH_STATIC_LOAD_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_ENABLE_Pos (1UL) /*!< LDO_VDDD_HIGH_ENABLE (Bit 1) */ +#define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_ENABLE_Msk (0x2UL) /*!< LDO_VDDD_HIGH_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_VREF_HOLD_Pos (0UL) /*!< LDO_VDDD_HIGH_VREF_HOLD (Bit 0) */ +#define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_VREF_HOLD_Msk (0x1UL) /*!< LDO_VDDD_HIGH_VREF_HOLD (Bitfield-Mask: 0x01) */ +/* =================================================== P0_PAD_LATCH_REG ==================================================== */ +#define CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Pos (0UL) /*!< P0_LATCH_EN (Bit 0) */ +#define CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Msk (0xffffffffUL) /*!< P0_LATCH_EN (Bitfield-Mask: 0xffffffff) */ +/* ================================================ P0_RESET_PAD_LATCH_REG ================================================= */ +#define CRG_TOP_P0_RESET_PAD_LATCH_REG_P0_RESET_LATCH_EN_Pos (0UL) /*!< P0_RESET_LATCH_EN (Bit 0) */ +#define CRG_TOP_P0_RESET_PAD_LATCH_REG_P0_RESET_LATCH_EN_Msk (0xffffffffUL) /*!< P0_RESET_LATCH_EN (Bitfield-Mask: 0xffffffff) */ +/* ================================================= P0_SET_PAD_LATCH_REG ================================================== */ +#define CRG_TOP_P0_SET_PAD_LATCH_REG_P0_SET_LATCH_EN_Pos (0UL) /*!< P0_SET_LATCH_EN (Bit 0) */ +#define CRG_TOP_P0_SET_PAD_LATCH_REG_P0_SET_LATCH_EN_Msk (0xffffffffUL) /*!< P0_SET_LATCH_EN (Bitfield-Mask: 0xffffffff) */ +/* =================================================== P1_PAD_LATCH_REG ==================================================== */ +#define CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Pos (0UL) /*!< P1_LATCH_EN (Bit 0) */ +#define CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Msk (0x7fffffUL) /*!< P1_LATCH_EN (Bitfield-Mask: 0x7fffff) */ +/* ================================================ P1_RESET_PAD_LATCH_REG ================================================= */ +#define CRG_TOP_P1_RESET_PAD_LATCH_REG_P1_RESET_LATCH_EN_Pos (0UL) /*!< P1_RESET_LATCH_EN (Bit 0) */ +#define CRG_TOP_P1_RESET_PAD_LATCH_REG_P1_RESET_LATCH_EN_Msk (0x7fffffUL) /*!< P1_RESET_LATCH_EN (Bitfield-Mask: 0x7fffff) */ +/* ================================================= P1_SET_PAD_LATCH_REG ================================================== */ +#define CRG_TOP_P1_SET_PAD_LATCH_REG_P1_SET_LATCH_EN_Pos (0UL) /*!< P1_SET_LATCH_EN (Bit 0) */ +#define CRG_TOP_P1_SET_PAD_LATCH_REG_P1_SET_LATCH_EN_Msk (0x7fffffUL) /*!< P1_SET_LATCH_EN (Bitfield-Mask: 0x7fffff) */ +/* ===================================================== PMU_CTRL_REG ====================================================== */ +#define CRG_TOP_PMU_CTRL_REG_ENABLE_CLKLESS_Pos (8UL) /*!< ENABLE_CLKLESS (Bit 8) */ +#define CRG_TOP_PMU_CTRL_REG_ENABLE_CLKLESS_Msk (0x100UL) /*!< ENABLE_CLKLESS (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_CTRL_REG_RETAIN_CACHE_Pos (7UL) /*!< RETAIN_CACHE (Bit 7) */ +#define CRG_TOP_PMU_CTRL_REG_RETAIN_CACHE_Msk (0x80UL) /*!< RETAIN_CACHE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_CTRL_REG_SYS_SLEEP_Pos (6UL) /*!< SYS_SLEEP (Bit 6) */ +#define CRG_TOP_PMU_CTRL_REG_SYS_SLEEP_Msk (0x40UL) /*!< SYS_SLEEP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_CTRL_REG_RESET_ON_WAKEUP_Pos (5UL) /*!< RESET_ON_WAKEUP (Bit 5) */ +#define CRG_TOP_PMU_CTRL_REG_RESET_ON_WAKEUP_Msk (0x20UL) /*!< RESET_ON_WAKEUP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_CTRL_REG_MAP_BANDGAP_EN_Pos (4UL) /*!< MAP_BANDGAP_EN (Bit 4) */ +#define CRG_TOP_PMU_CTRL_REG_MAP_BANDGAP_EN_Msk (0x10UL) /*!< MAP_BANDGAP_EN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_CTRL_REG_COM_SLEEP_Pos (3UL) /*!< COM_SLEEP (Bit 3) */ +#define CRG_TOP_PMU_CTRL_REG_COM_SLEEP_Msk (0x8UL) /*!< COM_SLEEP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_CTRL_REG_TIM_SLEEP_Pos (2UL) /*!< TIM_SLEEP (Bit 2) */ +#define CRG_TOP_PMU_CTRL_REG_TIM_SLEEP_Msk (0x4UL) /*!< TIM_SLEEP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Pos (1UL) /*!< RADIO_SLEEP (Bit 1) */ +#define CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Msk (0x2UL) /*!< RADIO_SLEEP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_CTRL_REG_PERIPH_SLEEP_Pos (0UL) /*!< PERIPH_SLEEP (Bit 0) */ +#define CRG_TOP_PMU_CTRL_REG_PERIPH_SLEEP_Msk (0x1UL) /*!< PERIPH_SLEEP (Bitfield-Mask: 0x01) */ +/* ===================================================== PMU_SLEEP_REG ===================================================== */ +#define CRG_TOP_PMU_SLEEP_REG_CLAMP_VDD_WKUP_MAX_Pos (18UL) /*!< CLAMP_VDD_WKUP_MAX (Bit 18) */ +#define CRG_TOP_PMU_SLEEP_REG_CLAMP_VDD_WKUP_MAX_Msk (0x40000UL) /*!< CLAMP_VDD_WKUP_MAX (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_SLEEP_REG_ULTRA_FAST_WAKEUP_Pos (17UL) /*!< ULTRA_FAST_WAKEUP (Bit 17) */ +#define CRG_TOP_PMU_SLEEP_REG_ULTRA_FAST_WAKEUP_Msk (0x20000UL) /*!< ULTRA_FAST_WAKEUP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_SLEEP_REG_FAST_WAKEUP_Pos (16UL) /*!< FAST_WAKEUP (Bit 16) */ +#define CRG_TOP_PMU_SLEEP_REG_FAST_WAKEUP_Msk (0x10000UL) /*!< FAST_WAKEUP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_PMU_SLEEP_REG_BOD_SLEEP_INTERVAL_Pos (12UL) /*!< BOD_SLEEP_INTERVAL (Bit 12) */ +#define CRG_TOP_PMU_SLEEP_REG_BOD_SLEEP_INTERVAL_Msk (0xf000UL) /*!< BOD_SLEEP_INTERVAL (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_PMU_SLEEP_REG_BG_REFRESH_INTERVAL_Pos (0UL) /*!< BG_REFRESH_INTERVAL (Bit 0) */ +#define CRG_TOP_PMU_SLEEP_REG_BG_REFRESH_INTERVAL_Msk (0xfffUL) /*!< BG_REFRESH_INTERVAL (Bitfield-Mask: 0xfff) */ +/* ===================================================== PMU_TRIM_REG ====================================================== */ +#define CRG_TOP_PMU_TRIM_REG_LDO_1V8_TRIM_Pos (12UL) /*!< LDO_1V8_TRIM (Bit 12) */ +#define CRG_TOP_PMU_TRIM_REG_LDO_1V8_TRIM_Msk (0xf000UL) /*!< LDO_1V8_TRIM (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_PMU_TRIM_REG_LDO_1V8P_TRIM_Pos (8UL) /*!< LDO_1V8P_TRIM (Bit 8) */ +#define CRG_TOP_PMU_TRIM_REG_LDO_1V8P_TRIM_Msk (0xf00UL) /*!< LDO_1V8P_TRIM (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_PMU_TRIM_REG_LDO_SUPPLY_VBAT_TRIM_Pos (4UL) /*!< LDO_SUPPLY_VBAT_TRIM (Bit 4) */ +#define CRG_TOP_PMU_TRIM_REG_LDO_SUPPLY_VBAT_TRIM_Msk (0xf0UL) /*!< LDO_SUPPLY_VBAT_TRIM (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_PMU_TRIM_REG_LDO_SUPPLY_VBUS_TRIM_Pos (0UL) /*!< LDO_SUPPLY_VBUS_TRIM (Bit 0) */ +#define CRG_TOP_PMU_TRIM_REG_LDO_SUPPLY_VBUS_TRIM_Msk (0xfUL) /*!< LDO_SUPPLY_VBUS_TRIM (Bitfield-Mask: 0x0f) */ +/* ====================================================== POR_PIN_REG ====================================================== */ +#define CRG_TOP_POR_PIN_REG_POR_PIN_POLARITY_Pos (7UL) /*!< POR_PIN_POLARITY (Bit 7) */ +#define CRG_TOP_POR_PIN_REG_POR_PIN_POLARITY_Msk (0x80UL) /*!< POR_PIN_POLARITY (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POR_PIN_REG_POR_PIN_SELECT_Pos (0UL) /*!< POR_PIN_SELECT (Bit 0) */ +#define CRG_TOP_POR_PIN_REG_POR_PIN_SELECT_Msk (0x3fUL) /*!< POR_PIN_SELECT (Bitfield-Mask: 0x3f) */ +/* ===================================================== POR_TIMER_REG ===================================================== */ +#define CRG_TOP_POR_TIMER_REG_POR_TIME_Pos (0UL) /*!< POR_TIME (Bit 0) */ +#define CRG_TOP_POR_TIMER_REG_POR_TIME_Msk (0x7fUL) /*!< POR_TIME (Bitfield-Mask: 0x7f) */ +/* =================================================== POR_VBAT_CTRL_REG =================================================== */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_MASK_N_Pos (13UL) /*!< POR_VBAT_MASK_N (Bit 13) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_MASK_N_Msk (0x2000UL) /*!< POR_VBAT_MASK_N (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_ENABLE_Pos (12UL) /*!< POR_VBAT_ENABLE (Bit 12) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_ENABLE_Msk (0x1000UL) /*!< POR_VBAT_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_HYST_LOW_Pos (8UL) /*!< POR_VBAT_HYST_LOW (Bit 8) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_HYST_LOW_Msk (0xf00UL) /*!< POR_VBAT_HYST_LOW (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_THRES_HIGH_Pos (4UL) /*!< POR_VBAT_THRES_HIGH (Bit 4) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_THRES_HIGH_Msk (0xf0UL) /*!< POR_VBAT_THRES_HIGH (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_THRES_LOW_Pos (0UL) /*!< POR_VBAT_THRES_LOW (Bit 0) */ +#define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_THRES_LOW_Msk (0xfUL) /*!< POR_VBAT_THRES_LOW (Bitfield-Mask: 0x0f) */ +/* ==================================================== POWER_CTRL_REG ===================================================== */ +#define CRG_TOP_POWER_CTRL_REG_VDD_SLEEP_LEVEL_Pos (29UL) /*!< VDD_SLEEP_LEVEL (Bit 29) */ +#define CRG_TOP_POWER_CTRL_REG_VDD_SLEEP_LEVEL_Msk (0xe0000000UL) /*!< VDD_SLEEP_LEVEL (Bitfield-Mask: 0x07) */ +#define CRG_TOP_POWER_CTRL_REG_VDD_CLAMP_LEVEL_Pos (25UL) /*!< VDD_CLAMP_LEVEL (Bit 25) */ +#define CRG_TOP_POWER_CTRL_REG_VDD_CLAMP_LEVEL_Msk (0x1e000000UL) /*!< VDD_CLAMP_LEVEL (Bitfield-Mask: 0x0f) */ +#define CRG_TOP_POWER_CTRL_REG_CLAMP_3V0_VBAT_ENABLE_Pos (24UL) /*!< CLAMP_3V0_VBAT_ENABLE (Bit 24) */ +#define CRG_TOP_POWER_CTRL_REG_CLAMP_3V0_VBAT_ENABLE_Msk (0x1000000UL) /*!< CLAMP_3V0_VBAT_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_V18_LEVEL_Pos (23UL) /*!< V18_LEVEL (Bit 23) */ +#define CRG_TOP_POWER_CTRL_REG_V18_LEVEL_Msk (0x800000UL) /*!< V18_LEVEL (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_V14_LEVEL_Pos (20UL) /*!< V14_LEVEL (Bit 20) */ +#define CRG_TOP_POWER_CTRL_REG_V14_LEVEL_Msk (0x700000UL) /*!< V14_LEVEL (Bitfield-Mask: 0x07) */ +#define CRG_TOP_POWER_CTRL_REG_V30_LEVEL_Pos (18UL) /*!< V30_LEVEL (Bit 18) */ +#define CRG_TOP_POWER_CTRL_REG_V30_LEVEL_Msk (0xc0000UL) /*!< V30_LEVEL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_POWER_CTRL_REG_VDD_LEVEL_Pos (16UL) /*!< VDD_LEVEL (Bit 16) */ +#define CRG_TOP_POWER_CTRL_REG_VDD_LEVEL_Msk (0x30000UL) /*!< VDD_LEVEL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_3V0_REF_Pos (15UL) /*!< LDO_3V0_REF (Bit 15) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_3V0_REF_Msk (0x8000UL) /*!< LDO_3V0_REF (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_SLEEP_Pos (14UL) /*!< LDO_CORE_RET_ENABLE_SLEEP (Bit 14) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_SLEEP_Msk (0x4000UL) /*!< LDO_CORE_RET_ENABLE_SLEEP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_ACTIVE_Pos (13UL) /*!< LDO_CORE_RET_ENABLE_ACTIVE (Bit 13) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_ACTIVE_Msk (0x2000UL) /*!< LDO_CORE_RET_ENABLE_ACTIVE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_CORE_ENABLE_Pos (12UL) /*!< LDO_CORE_ENABLE (Bit 12) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_CORE_ENABLE_Msk (0x1000UL) /*!< LDO_CORE_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_SLEEP_Pos (11UL) /*!< LDO_3V0_RET_ENABLE_SLEEP (Bit 11) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_SLEEP_Msk (0x800UL) /*!< LDO_3V0_RET_ENABLE_SLEEP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_ACTIVE_Pos (10UL) /*!< LDO_3V0_RET_ENABLE_ACTIVE (Bit 10) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_ACTIVE_Msk (0x400UL) /*!< LDO_3V0_RET_ENABLE_ACTIVE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_3V0_MODE_Pos (8UL) /*!< LDO_3V0_MODE (Bit 8) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_3V0_MODE_Msk (0x300UL) /*!< LDO_3V0_MODE (Bitfield-Mask: 0x03) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Pos (7UL) /*!< LDO_RADIO_ENABLE (Bit 7) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Msk (0x80UL) /*!< LDO_RADIO_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_SLEEP_Pos (6UL) /*!< LDO_1V8_RET_ENABLE_SLEEP (Bit 6) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_SLEEP_Msk (0x40UL) /*!< LDO_1V8_RET_ENABLE_SLEEP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_ACTIVE_Pos (5UL) /*!< LDO_1V8_RET_ENABLE_ACTIVE (Bit 5) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_ACTIVE_Msk (0x20UL) /*!< LDO_1V8_RET_ENABLE_ACTIVE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8_ENABLE_Pos (4UL) /*!< LDO_1V8_ENABLE (Bit 4) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8_ENABLE_Msk (0x10UL) /*!< LDO_1V8_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_SW_1V8F_ENABLE_FORCE_Pos (3UL) /*!< SW_1V8F_ENABLE_FORCE (Bit 3) */ +#define CRG_TOP_POWER_CTRL_REG_SW_1V8F_ENABLE_FORCE_Msk (0x8UL) /*!< SW_1V8F_ENABLE_FORCE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_SLEEP_Pos (2UL) /*!< LDO_1V8P_RET_ENABLE_SLEEP (Bit 2) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_SLEEP_Msk (0x4UL) /*!< LDO_1V8P_RET_ENABLE_SLEEP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_ACTIVE_Pos (1UL) /*!< LDO_1V8P_RET_ENABLE_ACTIVE (Bit 1) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_ACTIVE_Msk (0x2UL) /*!< LDO_1V8P_RET_ENABLE_ACTIVE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_ENABLE_Pos (0UL) /*!< LDO_1V8P_ENABLE (Bit 0) */ +#define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_ENABLE_Msk (0x1UL) /*!< LDO_1V8P_ENABLE (Bitfield-Mask: 0x01) */ +/* =================================================== RAM_PWR_CTRL_REG ==================================================== */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM8_PWR_CTRL_Pos (14UL) /*!< RAM8_PWR_CTRL (Bit 14) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM8_PWR_CTRL_Msk (0xc000UL) /*!< RAM8_PWR_CTRL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM7_PWR_CTRL_Pos (12UL) /*!< RAM7_PWR_CTRL (Bit 12) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM7_PWR_CTRL_Msk (0x3000UL) /*!< RAM7_PWR_CTRL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM6_PWR_CTRL_Pos (10UL) /*!< RAM6_PWR_CTRL (Bit 10) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM6_PWR_CTRL_Msk (0xc00UL) /*!< RAM6_PWR_CTRL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM5_PWR_CTRL_Pos (8UL) /*!< RAM5_PWR_CTRL (Bit 8) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM5_PWR_CTRL_Msk (0x300UL) /*!< RAM5_PWR_CTRL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM4_PWR_CTRL_Pos (6UL) /*!< RAM4_PWR_CTRL (Bit 6) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM4_PWR_CTRL_Msk (0xc0UL) /*!< RAM4_PWR_CTRL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM3_PWR_CTRL_Pos (4UL) /*!< RAM3_PWR_CTRL (Bit 4) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM3_PWR_CTRL_Msk (0x30UL) /*!< RAM3_PWR_CTRL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM2_PWR_CTRL_Pos (2UL) /*!< RAM2_PWR_CTRL (Bit 2) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM2_PWR_CTRL_Msk (0xcUL) /*!< RAM2_PWR_CTRL (Bitfield-Mask: 0x03) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM1_PWR_CTRL_Pos (0UL) /*!< RAM1_PWR_CTRL (Bit 0) */ +#define CRG_TOP_RAM_PWR_CTRL_REG_RAM1_PWR_CTRL_Msk (0x3UL) /*!< RAM1_PWR_CTRL (Bitfield-Mask: 0x03) */ +/* ==================================================== RESET_STAT_REG ===================================================== */ +#define CRG_TOP_RESET_STAT_REG_CMAC_WDOGRESET_STAT_Pos (5UL) /*!< CMAC_WDOGRESET_STAT (Bit 5) */ +#define CRG_TOP_RESET_STAT_REG_CMAC_WDOGRESET_STAT_Msk (0x20UL) /*!< CMAC_WDOGRESET_STAT (Bitfield-Mask: 0x01) */ +#define CRG_TOP_RESET_STAT_REG_SWD_HWRESET_STAT_Pos (4UL) /*!< SWD_HWRESET_STAT (Bit 4) */ +#define CRG_TOP_RESET_STAT_REG_SWD_HWRESET_STAT_Msk (0x10UL) /*!< SWD_HWRESET_STAT (Bitfield-Mask: 0x01) */ +#define CRG_TOP_RESET_STAT_REG_WDOGRESET_STAT_Pos (3UL) /*!< WDOGRESET_STAT (Bit 3) */ +#define CRG_TOP_RESET_STAT_REG_WDOGRESET_STAT_Msk (0x8UL) /*!< WDOGRESET_STAT (Bitfield-Mask: 0x01) */ +#define CRG_TOP_RESET_STAT_REG_SWRESET_STAT_Pos (2UL) /*!< SWRESET_STAT (Bit 2) */ +#define CRG_TOP_RESET_STAT_REG_SWRESET_STAT_Msk (0x4UL) /*!< SWRESET_STAT (Bitfield-Mask: 0x01) */ +#define CRG_TOP_RESET_STAT_REG_HWRESET_STAT_Pos (1UL) /*!< HWRESET_STAT (Bit 1) */ +#define CRG_TOP_RESET_STAT_REG_HWRESET_STAT_Msk (0x2UL) /*!< HWRESET_STAT (Bitfield-Mask: 0x01) */ +#define CRG_TOP_RESET_STAT_REG_PORESET_STAT_Pos (0UL) /*!< PORESET_STAT (Bit 0) */ +#define CRG_TOP_RESET_STAT_REG_PORESET_STAT_Msk (0x1UL) /*!< PORESET_STAT (Bitfield-Mask: 0x01) */ +/* ==================================================== SECURE_BOOT_REG ==================================================== */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_READ_Pos (7UL) /*!< PROT_QSPI_KEY_READ (Bit 7) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_READ_Msk (0x80UL) /*!< PROT_QSPI_KEY_READ (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_WRITE_Pos (6UL) /*!< PROT_QSPI_KEY_WRITE (Bit 6) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_WRITE_Msk (0x40UL) /*!< PROT_QSPI_KEY_WRITE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_READ_Pos (5UL) /*!< PROT_AES_KEY_READ (Bit 5) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_READ_Msk (0x20UL) /*!< PROT_AES_KEY_READ (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_WRITE_Pos (4UL) /*!< PROT_AES_KEY_WRITE (Bit 4) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_WRITE_Msk (0x10UL) /*!< PROT_AES_KEY_WRITE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_SIG_KEY_WRITE_Pos (3UL) /*!< PROT_SIG_KEY_WRITE (Bit 3) */ +#define CRG_TOP_SECURE_BOOT_REG_PROT_SIG_KEY_WRITE_Msk (0x8UL) /*!< PROT_SIG_KEY_WRITE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SECURE_BOOT_REG_FORCE_CMAC_DEBUGGER_OFF_Pos (2UL) /*!< FORCE_CMAC_DEBUGGER_OFF (Bit 2) */ +#define CRG_TOP_SECURE_BOOT_REG_FORCE_CMAC_DEBUGGER_OFF_Msk (0x4UL) /*!< FORCE_CMAC_DEBUGGER_OFF (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SECURE_BOOT_REG_FORCE_DEBUGGER_OFF_Pos (1UL) /*!< FORCE_DEBUGGER_OFF (Bit 1) */ +#define CRG_TOP_SECURE_BOOT_REG_FORCE_DEBUGGER_OFF_Msk (0x2UL) /*!< FORCE_DEBUGGER_OFF (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SECURE_BOOT_REG_SECURE_BOOT_Pos (0UL) /*!< SECURE_BOOT (Bit 0) */ +#define CRG_TOP_SECURE_BOOT_REG_SECURE_BOOT_Msk (0x1UL) /*!< SECURE_BOOT (Bitfield-Mask: 0x01) */ +/* ===================================================== SYS_CTRL_REG ====================================================== */ +#define CRG_TOP_SYS_CTRL_REG_SW_RESET_Pos (15UL) /*!< SW_RESET (Bit 15) */ +#define CRG_TOP_SYS_CTRL_REG_SW_RESET_Msk (0x8000UL) /*!< SW_RESET (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_CTRL_REG_CACHERAM_MUX_Pos (10UL) /*!< CACHERAM_MUX (Bit 10) */ +#define CRG_TOP_SYS_CTRL_REG_CACHERAM_MUX_Msk (0x400UL) /*!< CACHERAM_MUX (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_CTRL_REG_TIMEOUT_DISABLE_Pos (9UL) /*!< TIMEOUT_DISABLE (Bit 9) */ +#define CRG_TOP_SYS_CTRL_REG_TIMEOUT_DISABLE_Msk (0x200UL) /*!< TIMEOUT_DISABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_CTRL_REG_DEBUGGER_ENABLE_Pos (7UL) /*!< DEBUGGER_ENABLE (Bit 7) */ +#define CRG_TOP_SYS_CTRL_REG_DEBUGGER_ENABLE_Msk (0x80UL) /*!< DEBUGGER_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_CTRL_REG_QSPI_INIT_Pos (4UL) /*!< QSPI_INIT (Bit 4) */ +#define CRG_TOP_SYS_CTRL_REG_QSPI_INIT_Msk (0x10UL) /*!< QSPI_INIT (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_CTRL_REG_REMAP_INTVECT_Pos (3UL) /*!< REMAP_INTVECT (Bit 3) */ +#define CRG_TOP_SYS_CTRL_REG_REMAP_INTVECT_Msk (0x8UL) /*!< REMAP_INTVECT (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_CTRL_REG_REMAP_ADR0_Pos (0UL) /*!< REMAP_ADR0 (Bit 0) */ +#define CRG_TOP_SYS_CTRL_REG_REMAP_ADR0_Msk (0x7UL) /*!< REMAP_ADR0 (Bitfield-Mask: 0x07) */ +/* ===================================================== SYS_STAT_REG ====================================================== */ +#define CRG_TOP_SYS_STAT_REG_POWER_IS_UP_Pos (13UL) /*!< POWER_IS_UP (Bit 13) */ +#define CRG_TOP_SYS_STAT_REG_POWER_IS_UP_Msk (0x2000UL) /*!< POWER_IS_UP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_DBG_IS_ACTIVE_Pos (12UL) /*!< DBG_IS_ACTIVE (Bit 12) */ +#define CRG_TOP_SYS_STAT_REG_DBG_IS_ACTIVE_Msk (0x1000UL) /*!< DBG_IS_ACTIVE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_COM_IS_UP_Pos (11UL) /*!< COM_IS_UP (Bit 11) */ +#define CRG_TOP_SYS_STAT_REG_COM_IS_UP_Msk (0x800UL) /*!< COM_IS_UP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_COM_IS_DOWN_Pos (10UL) /*!< COM_IS_DOWN (Bit 10) */ +#define CRG_TOP_SYS_STAT_REG_COM_IS_DOWN_Msk (0x400UL) /*!< COM_IS_DOWN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_TIM_IS_UP_Pos (9UL) /*!< TIM_IS_UP (Bit 9) */ +#define CRG_TOP_SYS_STAT_REG_TIM_IS_UP_Msk (0x200UL) /*!< TIM_IS_UP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_TIM_IS_DOWN_Pos (8UL) /*!< TIM_IS_DOWN (Bit 8) */ +#define CRG_TOP_SYS_STAT_REG_TIM_IS_DOWN_Msk (0x100UL) /*!< TIM_IS_DOWN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_MEM_IS_UP_Pos (7UL) /*!< MEM_IS_UP (Bit 7) */ +#define CRG_TOP_SYS_STAT_REG_MEM_IS_UP_Msk (0x80UL) /*!< MEM_IS_UP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_MEM_IS_DOWN_Pos (6UL) /*!< MEM_IS_DOWN (Bit 6) */ +#define CRG_TOP_SYS_STAT_REG_MEM_IS_DOWN_Msk (0x40UL) /*!< MEM_IS_DOWN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_SYS_IS_UP_Pos (5UL) /*!< SYS_IS_UP (Bit 5) */ +#define CRG_TOP_SYS_STAT_REG_SYS_IS_UP_Msk (0x20UL) /*!< SYS_IS_UP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_SYS_IS_DOWN_Pos (4UL) /*!< SYS_IS_DOWN (Bit 4) */ +#define CRG_TOP_SYS_STAT_REG_SYS_IS_DOWN_Msk (0x10UL) /*!< SYS_IS_DOWN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_PER_IS_UP_Pos (3UL) /*!< PER_IS_UP (Bit 3) */ +#define CRG_TOP_SYS_STAT_REG_PER_IS_UP_Msk (0x8UL) /*!< PER_IS_UP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_PER_IS_DOWN_Pos (2UL) /*!< PER_IS_DOWN (Bit 2) */ +#define CRG_TOP_SYS_STAT_REG_PER_IS_DOWN_Msk (0x4UL) /*!< PER_IS_DOWN (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_RAD_IS_UP_Pos (1UL) /*!< RAD_IS_UP (Bit 1) */ +#define CRG_TOP_SYS_STAT_REG_RAD_IS_UP_Msk (0x2UL) /*!< RAD_IS_UP (Bitfield-Mask: 0x01) */ +#define CRG_TOP_SYS_STAT_REG_RAD_IS_DOWN_Pos (0UL) /*!< RAD_IS_DOWN (Bit 0) */ +#define CRG_TOP_SYS_STAT_REG_RAD_IS_DOWN_Msk (0x1UL) /*!< RAD_IS_DOWN (Bitfield-Mask: 0x01) */ +/* ================================================== VBUS_IRQ_CLEAR_REG =================================================== */ +#define CRG_TOP_VBUS_IRQ_CLEAR_REG_VBUS_IRQ_CLEAR_Pos (0UL) /*!< VBUS_IRQ_CLEAR (Bit 0) */ +#define CRG_TOP_VBUS_IRQ_CLEAR_REG_VBUS_IRQ_CLEAR_Msk (0xffffUL) /*!< VBUS_IRQ_CLEAR (Bitfield-Mask: 0xffff) */ +/* =================================================== VBUS_IRQ_MASK_REG =================================================== */ +#define CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Pos (1UL) /*!< VBUS_IRQ_EN_RISE (Bit 1) */ +#define CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Msk (0x2UL) /*!< VBUS_IRQ_EN_RISE (Bitfield-Mask: 0x01) */ +#define CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Pos (0UL) /*!< VBUS_IRQ_EN_FALL (Bit 0) */ +#define CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Msk (0x1UL) /*!< VBUS_IRQ_EN_FALL (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ CRG_XTAL ================ */ +/* =========================================================================================================================== */ + +/* =================================================== CLK_FREQ_TRIM_REG =================================================== */ +#define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_START_Pos (20UL) /*!< XTAL32M_START (Bit 20) */ +#define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_START_Msk (0x3ff00000UL) /*!< XTAL32M_START (Bitfield-Mask: 0x3ff) */ +#define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_RAMP_Pos (10UL) /*!< XTAL32M_RAMP (Bit 10) */ +#define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_RAMP_Msk (0xffc00UL) /*!< XTAL32M_RAMP (Bitfield-Mask: 0x3ff) */ +#define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_TRIM_Pos (0UL) /*!< XTAL32M_TRIM (Bit 0) */ +#define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_TRIM_Msk (0x3ffUL) /*!< XTAL32M_TRIM (Bitfield-Mask: 0x3ff) */ +/* =================================================== PLL_SYS_CTRL1_REG =================================================== */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_SEL_MIN_CUR_INT_Pos (14UL) /*!< PLL_SEL_MIN_CUR_INT (Bit 14) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_SEL_MIN_CUR_INT_Msk (0x4000UL) /*!< PLL_SEL_MIN_CUR_INT (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_PRE_DIV_Pos (11UL) /*!< PLL_PRE_DIV (Bit 11) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_PRE_DIV_Msk (0x800UL) /*!< PLL_PRE_DIV (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_N_DIV_Pos (4UL) /*!< PLL_N_DIV (Bit 4) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_N_DIV_Msk (0x7f0UL) /*!< PLL_N_DIV (Bitfield-Mask: 0x7f) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_VREF_HOLD_Pos (3UL) /*!< LDO_PLL_VREF_HOLD (Bit 3) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_VREF_HOLD_Msk (0x8UL) /*!< LDO_PLL_VREF_HOLD (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_Pos (2UL) /*!< LDO_PLL_ENABLE (Bit 2) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_Msk (0x4UL) /*!< LDO_PLL_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Pos (1UL) /*!< PLL_EN (Bit 1) */ +#define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Msk (0x2UL) /*!< PLL_EN (Bitfield-Mask: 0x01) */ +/* =================================================== PLL_SYS_CTRL2_REG =================================================== */ +#define CRG_XTAL_PLL_SYS_CTRL2_REG_PLL_RECALIB_Pos (15UL) /*!< PLL_RECALIB (Bit 15) */ +#define CRG_XTAL_PLL_SYS_CTRL2_REG_PLL_RECALIB_Msk (0x8000UL) /*!< PLL_RECALIB (Bitfield-Mask: 0x01) */ +/* =================================================== PLL_SYS_CTRL3_REG =================================================== */ +#define CRG_XTAL_PLL_SYS_CTRL3_REG_PLL_TEST_VCTR_Pos (7UL) /*!< PLL_TEST_VCTR (Bit 7) */ +#define CRG_XTAL_PLL_SYS_CTRL3_REG_PLL_TEST_VCTR_Msk (0x80UL) /*!< PLL_TEST_VCTR (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_PLL_SYS_CTRL3_REG_PLL_MIN_CURRENT_Pos (1UL) /*!< PLL_MIN_CURRENT (Bit 1) */ +#define CRG_XTAL_PLL_SYS_CTRL3_REG_PLL_MIN_CURRENT_Msk (0x7eUL) /*!< PLL_MIN_CURRENT (Bitfield-Mask: 0x3f) */ +/* ================================================== PLL_SYS_STATUS_REG =================================================== */ +#define CRG_XTAL_PLL_SYS_STATUS_REG_LDO_PLL_OK_Pos (15UL) /*!< LDO_PLL_OK (Bit 15) */ +#define CRG_XTAL_PLL_SYS_STATUS_REG_LDO_PLL_OK_Msk (0x8000UL) /*!< LDO_PLL_OK (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_CALIBRATION_END_Pos (11UL) /*!< PLL_CALIBRATION_END (Bit 11) */ +#define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_CALIBRATION_END_Msk (0x800UL) /*!< PLL_CALIBRATION_END (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_BEST_MIN_CUR_Pos (5UL) /*!< PLL_BEST_MIN_CUR (Bit 5) */ +#define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_BEST_MIN_CUR_Msk (0x7e0UL) /*!< PLL_BEST_MIN_CUR (Bitfield-Mask: 0x3f) */ +#define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_Pos (0UL) /*!< PLL_LOCK_FINE (Bit 0) */ +#define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_Msk (0x1UL) /*!< PLL_LOCK_FINE (Bitfield-Mask: 0x01) */ +/* ===================================================== TRIM_CTRL_REG ===================================================== */ +#define CRG_XTAL_TRIM_CTRL_REG_XTAL_SETTLE_N_Pos (8UL) /*!< XTAL_SETTLE_N (Bit 8) */ +#define CRG_XTAL_TRIM_CTRL_REG_XTAL_SETTLE_N_Msk (0x3f00UL) /*!< XTAL_SETTLE_N (Bitfield-Mask: 0x3f) */ +#define CRG_XTAL_TRIM_CTRL_REG_XTAL_TRIM_SELECT_Pos (6UL) /*!< XTAL_TRIM_SELECT (Bit 6) */ +#define CRG_XTAL_TRIM_CTRL_REG_XTAL_TRIM_SELECT_Msk (0xc0UL) /*!< XTAL_TRIM_SELECT (Bitfield-Mask: 0x03) */ +#define CRG_XTAL_TRIM_CTRL_REG_XTAL_COUNT_N_Pos (0UL) /*!< XTAL_COUNT_N (Bit 0) */ +#define CRG_XTAL_TRIM_CTRL_REG_XTAL_COUNT_N_Msk (0x3fUL) /*!< XTAL_COUNT_N (Bitfield-Mask: 0x3f) */ +/* =================================================== XTAL32M_CTRL0_REG =================================================== */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_DXTAL_SYSPLL_ENABLE_Pos (30UL) /*!< XTAL32M_DXTAL_SYSPLL_ENABLE (Bit 30) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_DXTAL_SYSPLL_ENABLE_Msk (0x40000000UL) /*!< XTAL32M_DXTAL_SYSPLL_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_CORE_CUR_SET_Pos (15UL) /*!< XTAL32M_CORE_CUR_SET (Bit 15) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_CORE_CUR_SET_Msk (0x38000UL) /*!< XTAL32M_CORE_CUR_SET (Bitfield-Mask: 0x07) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_RCOSC_CALIBRATE_Pos (3UL) /*!< XTAL32M_RCOSC_CALIBRATE (Bit 3) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_RCOSC_CALIBRATE_Msk (0x8UL) /*!< XTAL32M_RCOSC_CALIBRATE (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_RCOSC_XTAL_DRIVE_Pos (1UL) /*!< XTAL32M_RCOSC_XTAL_DRIVE (Bit 1) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_RCOSC_XTAL_DRIVE_Msk (0x2UL) /*!< XTAL32M_RCOSC_XTAL_DRIVE (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_CXCOMP_ENABLE_Pos (0UL) /*!< XTAL32M_CXCOMP_ENABLE (Bit 0) */ +#define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_CXCOMP_ENABLE_Msk (0x1UL) /*!< XTAL32M_CXCOMP_ENABLE (Bitfield-Mask: 0x01) */ +/* =================================================== XTAL32M_CTRL1_REG =================================================== */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDISCHARGE_Pos (28UL) /*!< XTAL32M_STARTUP_TDISCHARGE (Bit 28) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDISCHARGE_Msk (0x70000000UL) /*!< XTAL32M_STARTUP_TDISCHARGE (Bitfield-Mask: 0x07) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TSETTLE_Pos (24UL) /*!< XTAL32M_STARTUP_TSETTLE (Bit 24) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TSETTLE_Msk (0x7000000UL) /*!< XTAL32M_STARTUP_TSETTLE (Bitfield-Mask: 0x07) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_XTAL_ENABLE_Pos (23UL) /*!< XTAL32M_XTAL_ENABLE (Bit 23) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_XTAL_ENABLE_Msk (0x800000UL) /*!< XTAL32M_XTAL_ENABLE (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDRIVE_LSB_Pos (13UL) /*!< XTAL32M_STARTUP_TDRIVE_LSB (Bit 13) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDRIVE_LSB_Msk (0x7fe000UL) /*!< XTAL32M_STARTUP_TDRIVE_LSB (Bitfield-Mask: 0x3ff) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_DRIVE_CYCLES_Pos (8UL) /*!< XTAL32M_DRIVE_CYCLES (Bit 8) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_DRIVE_CYCLES_Msk (0x1f00UL) /*!< XTAL32M_DRIVE_CYCLES (Bitfield-Mask: 0x1f) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDRIVE_Pos (5UL) /*!< XTAL32M_STARTUP_TDRIVE (Bit 5) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDRIVE_Msk (0xe0UL) /*!< XTAL32M_STARTUP_TDRIVE (Bitfield-Mask: 0x07) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_RCOSC_SYNC_DELAY_TRIM_Pos (0UL) /*!< XTAL32M_RCOSC_SYNC_DELAY_TRIM (Bit 0) */ +#define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_RCOSC_SYNC_DELAY_TRIM_Msk (0x1fUL) /*!< XTAL32M_RCOSC_SYNC_DELAY_TRIM (Bitfield-Mask: 0x1f) */ +/* =================================================== XTAL32M_CTRL2_REG =================================================== */ +#define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_RCOSC_TRIM_SNS_Pos (14UL) /*!< XTAL32M_RCOSC_TRIM_SNS (Bit 14) */ +#define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_RCOSC_TRIM_SNS_Msk (0x3fc000UL) /*!< XTAL32M_RCOSC_TRIM_SNS (Bitfield-Mask: 0xff) */ +#define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_CXCOMP_PHI_TRIM_Pos (12UL) /*!< XTAL32M_CXCOMP_PHI_TRIM (Bit 12) */ +#define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_CXCOMP_PHI_TRIM_Msk (0x3000UL) /*!< XTAL32M_CXCOMP_PHI_TRIM (Bitfield-Mask: 0x03) */ +#define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_CXCOMP_TRIM_CAP_Pos (3UL) /*!< XTAL32M_CXCOMP_TRIM_CAP (Bit 3) */ +#define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_CXCOMP_TRIM_CAP_Msk (0xff8UL) /*!< XTAL32M_CXCOMP_TRIM_CAP (Bitfield-Mask: 0x1ff) */ +/* =================================================== XTAL32M_CTRL3_REG =================================================== */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_STROBE_Pos (30UL) /*!< XTAL32M_RCOSC_TRIM_STROBE (Bit 30) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_STROBE_Msk (0x40000000UL) /*!< XTAL32M_RCOSC_TRIM_STROBE (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_FREQ_DET_START_Pos (22UL) /*!< XTAL32M_FREQ_DET_START (Bit 22) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_FREQ_DET_START_Msk (0x400000UL) /*!< XTAL32M_FREQ_DET_START (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_SW_CTRL_MODE_Pos (18UL) /*!< XTAL32M_SW_CTRL_MODE (Bit 18) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_SW_CTRL_MODE_Msk (0x40000UL) /*!< XTAL32M_SW_CTRL_MODE (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_BAND_SELECT_Pos (14UL) /*!< XTAL32M_RCOSC_BAND_SELECT (Bit 14) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_BAND_SELECT_Msk (0x3c000UL) /*!< XTAL32M_RCOSC_BAND_SELECT (Bitfield-Mask: 0x0f) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_Pos (4UL) /*!< XTAL32M_RCOSC_TRIM (Bit 4) */ +#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_Msk (0x3ff0UL) /*!< XTAL32M_RCOSC_TRIM (Bitfield-Mask: 0x3ff) */ +/* =================================================== XTAL32M_CTRL4_REG =================================================== */ +/* =================================================== XTAL32M_STAT0_REG =================================================== */ +#define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_BAND_SELECT_STAT_Pos (28UL) /*!< XTAL32M_RCOSC_BAND_SELECT_STAT (Bit 28) */ +#define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_BAND_SELECT_STAT_Msk (0xf0000000UL) /*!< XTAL32M_RCOSC_BAND_SELECT_STAT (Bitfield-Mask: 0x0f) */ +#define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_CALIBRATION_DONE_Pos (15UL) /*!< XTAL32M_RCOSC_CALIBRATION_DONE (Bit 15) */ +#define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_CALIBRATION_DONE_Msk (0x8000UL) /*!< XTAL32M_RCOSC_CALIBRATION_DONE (Bitfield-Mask: 0x01) */ +/* =================================================== XTAL32M_STAT1_REG =================================================== */ +#define CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_CAL_STATE_Pos (4UL) /*!< XTAL32M_CAL_STATE (Bit 4) */ +#define CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_CAL_STATE_Msk (0xf0UL) /*!< XTAL32M_CAL_STATE (Bitfield-Mask: 0x0f) */ +#define CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_STATE_Pos (0UL) /*!< XTAL32M_STATE (Bit 0) */ +#define CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_STATE_Msk (0xfUL) /*!< XTAL32M_STATE (Bitfield-Mask: 0x0f) */ +/* =================================================== XTALRDY_CTRL_REG ==================================================== */ +#define CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Pos (8UL) /*!< XTALRDY_CLK_SEL (Bit 8) */ +#define CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Msk (0x100UL) /*!< XTALRDY_CLK_SEL (Bitfield-Mask: 0x01) */ +#define CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Pos (0UL) /*!< XTALRDY_CNT (Bit 0) */ +#define CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk (0xffUL) /*!< XTALRDY_CNT (Bitfield-Mask: 0xff) */ +/* =================================================== XTALRDY_STAT_REG ==================================================== */ +#define CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_COUNT_Pos (8UL) /*!< XTALRDY_COUNT (Bit 8) */ +#define CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_COUNT_Msk (0xff00UL) /*!< XTALRDY_COUNT (Bitfield-Mask: 0xff) */ +#define CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_STAT_Pos (0UL) /*!< XTALRDY_STAT (Bit 0) */ +#define CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_STAT_Msk (0xffUL) /*!< XTALRDY_STAT (Bitfield-Mask: 0xff) */ + + +/* =========================================================================================================================== */ +/* ================ DCDC ================ */ +/* =========================================================================================================================== */ + +/* ==================================================== DCDC_CTRL1_REG ===================================================== */ +#define DCDC_DCDC_CTRL1_REG_DCDC_SH_ENABLE_Pos (31UL) /*!< DCDC_SH_ENABLE (Bit 31) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_SH_ENABLE_Msk (0x80000000UL) /*!< DCDC_SH_ENABLE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_STARTUP_DELAY_Pos (26UL) /*!< DCDC_STARTUP_DELAY (Bit 26) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_STARTUP_DELAY_Msk (0x7c000000UL) /*!< DCDC_STARTUP_DELAY (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_IDLE_MAX_FAST_DOWNRAMP_Pos (20UL) /*!< DCDC_IDLE_MAX_FAST_DOWNRAMP (Bit 20) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_IDLE_MAX_FAST_DOWNRAMP_Msk (0x3f00000UL) /*!< DCDC_IDLE_MAX_FAST_DOWNRAMP (Bitfield-Mask: 0x3f) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_SW_TIMEOUT_Pos (15UL) /*!< DCDC_SW_TIMEOUT (Bit 15) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_SW_TIMEOUT_Msk (0xf8000UL) /*!< DCDC_SW_TIMEOUT (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_FAST_STARTUP_Pos (14UL) /*!< DCDC_FAST_STARTUP (Bit 14) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_FAST_STARTUP_Msk (0x4000UL) /*!< DCDC_FAST_STARTUP (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_MAN_LV_MODE_Pos (13UL) /*!< DCDC_MAN_LV_MODE (Bit 13) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_MAN_LV_MODE_Msk (0x2000UL) /*!< DCDC_MAN_LV_MODE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_AUTO_LV_MODE_Pos (12UL) /*!< DCDC_AUTO_LV_MODE (Bit 12) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_AUTO_LV_MODE_Msk (0x1000UL) /*!< DCDC_AUTO_LV_MODE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_IDLE_CLK_DIV_Pos (10UL) /*!< DCDC_IDLE_CLK_DIV (Bit 10) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_IDLE_CLK_DIV_Msk (0xc00UL) /*!< DCDC_IDLE_CLK_DIV (Bitfield-Mask: 0x03) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_PRIORITY_Pos (2UL) /*!< DCDC_PRIORITY (Bit 2) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_PRIORITY_Msk (0x3fcUL) /*!< DCDC_PRIORITY (Bitfield-Mask: 0xff) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_FW_ENABLE_Pos (1UL) /*!< DCDC_FW_ENABLE (Bit 1) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_FW_ENABLE_Msk (0x2UL) /*!< DCDC_FW_ENABLE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Pos (0UL) /*!< DCDC_ENABLE (Bit 0) */ +#define DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk (0x1UL) /*!< DCDC_ENABLE (Bitfield-Mask: 0x01) */ +/* ==================================================== DCDC_CTRL2_REG ===================================================== */ +#define DCDC_DCDC_CTRL2_REG_DCDC_V_NOK_CNT_MAX_Pos (24UL) /*!< DCDC_V_NOK_CNT_MAX (Bit 24) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_V_NOK_CNT_MAX_Msk (0xf000000UL) /*!< DCDC_V_NOK_CNT_MAX (Bitfield-Mask: 0x0f) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_N_COMP_TRIM_MAN_Pos (22UL) /*!< DCDC_N_COMP_TRIM_MAN (Bit 22) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_N_COMP_TRIM_MAN_Msk (0x400000UL) /*!< DCDC_N_COMP_TRIM_MAN (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_N_COMP_TRIM_VAL_Pos (16UL) /*!< DCDC_N_COMP_TRIM_VAL (Bit 16) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_N_COMP_TRIM_VAL_Msk (0x3f0000UL) /*!< DCDC_N_COMP_TRIM_VAL (Bitfield-Mask: 0x3f) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_TIMEOUT_IRQ_TRIG_Pos (12UL) /*!< DCDC_TIMEOUT_IRQ_TRIG (Bit 12) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_TIMEOUT_IRQ_TRIG_Msk (0xf000UL) /*!< DCDC_TIMEOUT_IRQ_TRIG (Bitfield-Mask: 0x0f) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_TIMEOUT_IRQ_RES_Pos (8UL) /*!< DCDC_TIMEOUT_IRQ_RES (Bit 8) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_TIMEOUT_IRQ_RES_Msk (0xf00UL) /*!< DCDC_TIMEOUT_IRQ_RES (Bitfield-Mask: 0x0f) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_SLOPE_CONTROL_Pos (6UL) /*!< DCDC_SLOPE_CONTROL (Bit 6) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_SLOPE_CONTROL_Msk (0xc0UL) /*!< DCDC_SLOPE_CONTROL (Bitfield-Mask: 0x03) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_VBTSTRP_TRIM_Pos (4UL) /*!< DCDC_VBTSTRP_TRIM (Bit 4) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_VBTSTRP_TRIM_Msk (0x30UL) /*!< DCDC_VBTSTRP_TRIM (Bitfield-Mask: 0x03) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_LSSUP_TRIM_Pos (2UL) /*!< DCDC_LSSUP_TRIM (Bit 2) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_LSSUP_TRIM_Msk (0xcUL) /*!< DCDC_LSSUP_TRIM (Bitfield-Mask: 0x03) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_HSGND_TRIM_Pos (0UL) /*!< DCDC_HSGND_TRIM (Bit 0) */ +#define DCDC_DCDC_CTRL2_REG_DCDC_HSGND_TRIM_Msk (0x3UL) /*!< DCDC_HSGND_TRIM (Bitfield-Mask: 0x03) */ +/* ================================================== DCDC_IRQ_CLEAR_REG =================================================== */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_LOW_VBAT_IRQ_CLEAR_Pos (4UL) /*!< DCDC_LOW_VBAT_IRQ_CLEAR (Bit 4) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_LOW_VBAT_IRQ_CLEAR_Msk (0x10UL) /*!< DCDC_LOW_VBAT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V18P_TIMEOUT_IRQ_CLEAR_Pos (3UL) /*!< DCDC_V18P_TIMEOUT_IRQ_CLEAR (Bit 3) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V18P_TIMEOUT_IRQ_CLEAR_Msk (0x8UL) /*!< DCDC_V18P_TIMEOUT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_VDD_TIMEOUT_IRQ_CLEAR_Pos (2UL) /*!< DCDC_VDD_TIMEOUT_IRQ_CLEAR (Bit 2) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_VDD_TIMEOUT_IRQ_CLEAR_Msk (0x4UL) /*!< DCDC_VDD_TIMEOUT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V18_TIMEOUT_IRQ_CLEAR_Pos (1UL) /*!< DCDC_V18_TIMEOUT_IRQ_CLEAR (Bit 1) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V18_TIMEOUT_IRQ_CLEAR_Msk (0x2UL) /*!< DCDC_V18_TIMEOUT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V14_TIMEOUT_IRQ_CLEAR_Pos (0UL) /*!< DCDC_V14_TIMEOUT_IRQ_CLEAR (Bit 0) */ +#define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V14_TIMEOUT_IRQ_CLEAR_Msk (0x1UL) /*!< DCDC_V14_TIMEOUT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +/* =================================================== DCDC_IRQ_MASK_REG =================================================== */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_LOW_VBAT_IRQ_MASK_Pos (4UL) /*!< DCDC_LOW_VBAT_IRQ_MASK (Bit 4) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_LOW_VBAT_IRQ_MASK_Msk (0x10UL) /*!< DCDC_LOW_VBAT_IRQ_MASK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_V18P_TIMEOUT_IRQ_MASK_Pos (3UL) /*!< DCDC_V18P_TIMEOUT_IRQ_MASK (Bit 3) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_V18P_TIMEOUT_IRQ_MASK_Msk (0x8UL) /*!< DCDC_V18P_TIMEOUT_IRQ_MASK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_VDD_TIMEOUT_IRQ_MASK_Pos (2UL) /*!< DCDC_VDD_TIMEOUT_IRQ_MASK (Bit 2) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_VDD_TIMEOUT_IRQ_MASK_Msk (0x4UL) /*!< DCDC_VDD_TIMEOUT_IRQ_MASK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_V18_TIMEOUT_IRQ_MASK_Pos (1UL) /*!< DCDC_V18_TIMEOUT_IRQ_MASK (Bit 1) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_V18_TIMEOUT_IRQ_MASK_Msk (0x2UL) /*!< DCDC_V18_TIMEOUT_IRQ_MASK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_V14_TIMEOUT_IRQ_MASK_Pos (0UL) /*!< DCDC_V14_TIMEOUT_IRQ_MASK (Bit 0) */ +#define DCDC_DCDC_IRQ_MASK_REG_DCDC_V14_TIMEOUT_IRQ_MASK_Msk (0x1UL) /*!< DCDC_V14_TIMEOUT_IRQ_MASK (Bitfield-Mask: 0x01) */ +/* ================================================== DCDC_IRQ_STATUS_REG ================================================== */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_LOW_VBAT_IRQ_STATUS_Pos (4UL) /*!< DCDC_LOW_VBAT_IRQ_STATUS (Bit 4) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_LOW_VBAT_IRQ_STATUS_Msk (0x10UL) /*!< DCDC_LOW_VBAT_IRQ_STATUS (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V18P_TIMEOUT_IRQ_STATUS_Pos (3UL) /*!< DCDC_V18P_TIMEOUT_IRQ_STATUS (Bit 3) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V18P_TIMEOUT_IRQ_STATUS_Msk (0x8UL) /*!< DCDC_V18P_TIMEOUT_IRQ_STATUS (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_VDD_TIMEOUT_IRQ_STATUS_Pos (2UL) /*!< DCDC_VDD_TIMEOUT_IRQ_STATUS (Bit 2) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_VDD_TIMEOUT_IRQ_STATUS_Msk (0x4UL) /*!< DCDC_VDD_TIMEOUT_IRQ_STATUS (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V18_TIMEOUT_IRQ_STATUS_Pos (1UL) /*!< DCDC_V18_TIMEOUT_IRQ_STATUS (Bit 1) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V18_TIMEOUT_IRQ_STATUS_Msk (0x2UL) /*!< DCDC_V18_TIMEOUT_IRQ_STATUS (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V14_TIMEOUT_IRQ_STATUS_Pos (0UL) /*!< DCDC_V14_TIMEOUT_IRQ_STATUS (Bit 0) */ +#define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V14_TIMEOUT_IRQ_STATUS_Msk (0x1UL) /*!< DCDC_V14_TIMEOUT_IRQ_STATUS (Bitfield-Mask: 0x01) */ +/* =================================================== DCDC_STATUS1_REG ==================================================== */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18P_AVAILABLE_Pos (27UL) /*!< DCDC_V18P_AVAILABLE (Bit 27) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18P_AVAILABLE_Msk (0x8000000UL) /*!< DCDC_V18P_AVAILABLE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_VDD_AVAILABLE_Pos (26UL) /*!< DCDC_VDD_AVAILABLE (Bit 26) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_VDD_AVAILABLE_Msk (0x4000000UL) /*!< DCDC_VDD_AVAILABLE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18_AVAILABLE_Pos (25UL) /*!< DCDC_V18_AVAILABLE (Bit 25) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18_AVAILABLE_Msk (0x2000000UL) /*!< DCDC_V18_AVAILABLE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V14_AVAILABLE_Pos (24UL) /*!< DCDC_V14_AVAILABLE (Bit 24) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V14_AVAILABLE_Msk (0x1000000UL) /*!< DCDC_V14_AVAILABLE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18P_COMP_OK_Pos (23UL) /*!< DCDC_V18P_COMP_OK (Bit 23) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18P_COMP_OK_Msk (0x800000UL) /*!< DCDC_V18P_COMP_OK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_VDD_COMP_OK_Pos (22UL) /*!< DCDC_VDD_COMP_OK (Bit 22) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_VDD_COMP_OK_Msk (0x400000UL) /*!< DCDC_VDD_COMP_OK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18_COMP_OK_Pos (21UL) /*!< DCDC_V18_COMP_OK (Bit 21) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18_COMP_OK_Msk (0x200000UL) /*!< DCDC_V18_COMP_OK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V14_COMP_OK_Pos (20UL) /*!< DCDC_V14_COMP_OK (Bit 20) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V14_COMP_OK_Msk (0x100000UL) /*!< DCDC_V14_COMP_OK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18P_COMP_NOK_Pos (19UL) /*!< DCDC_V18P_COMP_NOK (Bit 19) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18P_COMP_NOK_Msk (0x80000UL) /*!< DCDC_V18P_COMP_NOK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_VDD_COMP_NOK_Pos (18UL) /*!< DCDC_VDD_COMP_NOK (Bit 18) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_VDD_COMP_NOK_Msk (0x40000UL) /*!< DCDC_VDD_COMP_NOK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18_COMP_NOK_Pos (17UL) /*!< DCDC_V18_COMP_NOK (Bit 17) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18_COMP_NOK_Msk (0x20000UL) /*!< DCDC_V18_COMP_NOK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V14_COMP_NOK_Pos (16UL) /*!< DCDC_V14_COMP_NOK (Bit 16) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V14_COMP_NOK_Msk (0x10000UL) /*!< DCDC_V14_COMP_NOK (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_P_Pos (11UL) /*!< DCDC_N_COMP_P (Bit 11) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_P_Msk (0x800UL) /*!< DCDC_N_COMP_P (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_N_Pos (10UL) /*!< DCDC_N_COMP_N (Bit 10) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_N_Msk (0x400UL) /*!< DCDC_N_COMP_N (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_P_COMP_Pos (9UL) /*!< DCDC_P_COMP (Bit 9) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_P_COMP_Msk (0x200UL) /*!< DCDC_P_COMP (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_Pos (8UL) /*!< DCDC_N_COMP (Bit 8) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_Msk (0x100UL) /*!< DCDC_N_COMP (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_LV_MODE_Pos (7UL) /*!< DCDC_LV_MODE (Bit 7) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_LV_MODE_Msk (0x80UL) /*!< DCDC_LV_MODE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18P_SW_STATE_Pos (6UL) /*!< DCDC_V18P_SW_STATE (Bit 6) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18P_SW_STATE_Msk (0x40UL) /*!< DCDC_V18P_SW_STATE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_VDD_SW_STATE_Pos (5UL) /*!< DCDC_VDD_SW_STATE (Bit 5) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_VDD_SW_STATE_Msk (0x20UL) /*!< DCDC_VDD_SW_STATE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18_SW_STATE_Pos (4UL) /*!< DCDC_V18_SW_STATE (Bit 4) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V18_SW_STATE_Msk (0x10UL) /*!< DCDC_V18_SW_STATE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V14_SW_STATE_Pos (3UL) /*!< DCDC_V14_SW_STATE (Bit 3) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_V14_SW_STATE_Msk (0x8UL) /*!< DCDC_V14_SW_STATE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_N_SW_STATE_Pos (2UL) /*!< DCDC_N_SW_STATE (Bit 2) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_N_SW_STATE_Msk (0x4UL) /*!< DCDC_N_SW_STATE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_P_SW_STATE_Pos (1UL) /*!< DCDC_P_SW_STATE (Bit 1) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_P_SW_STATE_Msk (0x2UL) /*!< DCDC_P_SW_STATE (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_STARTUP_COMPLETE_Pos (0UL) /*!< DCDC_STARTUP_COMPLETE (Bit 0) */ +#define DCDC_DCDC_STATUS1_REG_DCDC_STARTUP_COMPLETE_Msk (0x1UL) /*!< DCDC_STARTUP_COMPLETE (Bitfield-Mask: 0x01) */ +/* ===================================================== DCDC_V14_REG ====================================================== */ +#define DCDC_DCDC_V14_REG_DCDC_V14_FAST_RAMPING_Pos (31UL) /*!< DCDC_V14_FAST_RAMPING (Bit 31) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_FAST_RAMPING_Msk (0x80000000UL) /*!< DCDC_V14_FAST_RAMPING (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_TRIM_Pos (27UL) /*!< DCDC_V14_TRIM (Bit 27) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_TRIM_Msk (0x8000000UL) /*!< DCDC_V14_TRIM (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_HV_Pos (22UL) /*!< DCDC_V14_CUR_LIM_MAX_HV (Bit 22) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_HV_Msk (0x7c00000UL) /*!< DCDC_V14_CUR_LIM_MAX_HV (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_LV_Pos (17UL) /*!< DCDC_V14_CUR_LIM_MAX_LV (Bit 17) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_LV_Msk (0x3e0000UL) /*!< DCDC_V14_CUR_LIM_MAX_LV (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MIN_Pos (12UL) /*!< DCDC_V14_CUR_LIM_MIN (Bit 12) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MIN_Msk (0x1f000UL) /*!< DCDC_V14_CUR_LIM_MIN (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_IDLE_HYST_Pos (7UL) /*!< DCDC_V14_IDLE_HYST (Bit 7) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_IDLE_HYST_Msk (0xf80UL) /*!< DCDC_V14_IDLE_HYST (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_IDLE_MIN_Pos (2UL) /*!< DCDC_V14_IDLE_MIN (Bit 2) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_IDLE_MIN_Msk (0x7cUL) /*!< DCDC_V14_IDLE_MIN (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_HV_Pos (1UL) /*!< DCDC_V14_ENABLE_HV (Bit 1) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_HV_Msk (0x2UL) /*!< DCDC_V14_ENABLE_HV (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_LV_Pos (0UL) /*!< DCDC_V14_ENABLE_LV (Bit 0) */ +#define DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_LV_Msk (0x1UL) /*!< DCDC_V14_ENABLE_LV (Bitfield-Mask: 0x01) */ +/* ===================================================== DCDC_V18P_REG ===================================================== */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_FAST_RAMPING_Pos (31UL) /*!< DCDC_V18P_FAST_RAMPING (Bit 31) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_FAST_RAMPING_Msk (0x80000000UL) /*!< DCDC_V18P_FAST_RAMPING (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_TRIM_Pos (27UL) /*!< DCDC_V18P_TRIM (Bit 27) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_TRIM_Msk (0x78000000UL) /*!< DCDC_V18P_TRIM (Bitfield-Mask: 0x0f) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MAX_HV_Pos (22UL) /*!< DCDC_V18P_CUR_LIM_MAX_HV (Bit 22) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MAX_HV_Msk (0x7c00000UL) /*!< DCDC_V18P_CUR_LIM_MAX_HV (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MAX_LV_Pos (17UL) /*!< DCDC_V18P_CUR_LIM_MAX_LV (Bit 17) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MAX_LV_Msk (0x3e0000UL) /*!< DCDC_V18P_CUR_LIM_MAX_LV (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MIN_Pos (12UL) /*!< DCDC_V18P_CUR_LIM_MIN (Bit 12) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MIN_Msk (0x1f000UL) /*!< DCDC_V18P_CUR_LIM_MIN (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_IDLE_HYST_Pos (7UL) /*!< DCDC_V18P_IDLE_HYST (Bit 7) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_IDLE_HYST_Msk (0xf80UL) /*!< DCDC_V18P_IDLE_HYST (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_IDLE_MIN_Pos (2UL) /*!< DCDC_V18P_IDLE_MIN (Bit 2) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_IDLE_MIN_Msk (0x7cUL) /*!< DCDC_V18P_IDLE_MIN (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_ENABLE_HV_Pos (1UL) /*!< DCDC_V18P_ENABLE_HV (Bit 1) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_ENABLE_HV_Msk (0x2UL) /*!< DCDC_V18P_ENABLE_HV (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_ENABLE_LV_Pos (0UL) /*!< DCDC_V18P_ENABLE_LV (Bit 0) */ +#define DCDC_DCDC_V18P_REG_DCDC_V18P_ENABLE_LV_Msk (0x1UL) /*!< DCDC_V18P_ENABLE_LV (Bitfield-Mask: 0x01) */ +/* ===================================================== DCDC_V18_REG ====================================================== */ +#define DCDC_DCDC_V18_REG_DCDC_V18_FAST_RAMPING_Pos (31UL) /*!< DCDC_V18_FAST_RAMPING (Bit 31) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_FAST_RAMPING_Msk (0x80000000UL) /*!< DCDC_V18_FAST_RAMPING (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_TRIM_Pos (27UL) /*!< DCDC_V18_TRIM (Bit 27) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_TRIM_Msk (0x78000000UL) /*!< DCDC_V18_TRIM (Bitfield-Mask: 0x0f) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MAX_HV_Pos (22UL) /*!< DCDC_V18_CUR_LIM_MAX_HV (Bit 22) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MAX_HV_Msk (0x7c00000UL) /*!< DCDC_V18_CUR_LIM_MAX_HV (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MAX_LV_Pos (17UL) /*!< DCDC_V18_CUR_LIM_MAX_LV (Bit 17) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MAX_LV_Msk (0x3e0000UL) /*!< DCDC_V18_CUR_LIM_MAX_LV (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MIN_Pos (12UL) /*!< DCDC_V18_CUR_LIM_MIN (Bit 12) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MIN_Msk (0x1f000UL) /*!< DCDC_V18_CUR_LIM_MIN (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_IDLE_HYST_Pos (7UL) /*!< DCDC_V18_IDLE_HYST (Bit 7) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_IDLE_HYST_Msk (0xf80UL) /*!< DCDC_V18_IDLE_HYST (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_IDLE_MIN_Pos (2UL) /*!< DCDC_V18_IDLE_MIN (Bit 2) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_IDLE_MIN_Msk (0x7cUL) /*!< DCDC_V18_IDLE_MIN (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_ENABLE_HV_Pos (1UL) /*!< DCDC_V18_ENABLE_HV (Bit 1) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_ENABLE_HV_Msk (0x2UL) /*!< DCDC_V18_ENABLE_HV (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_ENABLE_LV_Pos (0UL) /*!< DCDC_V18_ENABLE_LV (Bit 0) */ +#define DCDC_DCDC_V18_REG_DCDC_V18_ENABLE_LV_Msk (0x1UL) /*!< DCDC_V18_ENABLE_LV (Bitfield-Mask: 0x01) */ +/* ===================================================== DCDC_VDD_REG ====================================================== */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_FAST_RAMPING_Pos (31UL) /*!< DCDC_VDD_FAST_RAMPING (Bit 31) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_FAST_RAMPING_Msk (0x80000000UL) /*!< DCDC_VDD_FAST_RAMPING (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_TRIM_Pos (27UL) /*!< DCDC_VDD_TRIM (Bit 27) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_TRIM_Msk (0x38000000UL) /*!< DCDC_VDD_TRIM (Bitfield-Mask: 0x07) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MAX_HV_Pos (22UL) /*!< DCDC_VDD_CUR_LIM_MAX_HV (Bit 22) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MAX_HV_Msk (0x7c00000UL) /*!< DCDC_VDD_CUR_LIM_MAX_HV (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MAX_LV_Pos (17UL) /*!< DCDC_VDD_CUR_LIM_MAX_LV (Bit 17) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MAX_LV_Msk (0x3e0000UL) /*!< DCDC_VDD_CUR_LIM_MAX_LV (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MIN_Pos (12UL) /*!< DCDC_VDD_CUR_LIM_MIN (Bit 12) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MIN_Msk (0x1f000UL) /*!< DCDC_VDD_CUR_LIM_MIN (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_IDLE_HYST_Pos (7UL) /*!< DCDC_VDD_IDLE_HYST (Bit 7) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_IDLE_HYST_Msk (0xf80UL) /*!< DCDC_VDD_IDLE_HYST (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_IDLE_MIN_Pos (2UL) /*!< DCDC_VDD_IDLE_MIN (Bit 2) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_IDLE_MIN_Msk (0x7cUL) /*!< DCDC_VDD_IDLE_MIN (Bitfield-Mask: 0x1f) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_HV_Pos (1UL) /*!< DCDC_VDD_ENABLE_HV (Bit 1) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_HV_Msk (0x2UL) /*!< DCDC_VDD_ENABLE_HV (Bitfield-Mask: 0x01) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_LV_Pos (0UL) /*!< DCDC_VDD_ENABLE_LV (Bit 0) */ +#define DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_LV_Msk (0x1UL) /*!< DCDC_VDD_ENABLE_LV (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ DMA ================ */ +/* =========================================================================================================================== */ + +/* =================================================== DMA0_A_START_REG ==================================================== */ +#define DMA_DMA0_A_START_REG_DMA0_A_START_Pos (0UL) /*!< DMA0_A_START (Bit 0) */ +#define DMA_DMA0_A_START_REG_DMA0_A_START_Msk (0xffffffffUL) /*!< DMA0_A_START (Bitfield-Mask: 0xffffffff) */ +/* =================================================== DMA0_B_START_REG ==================================================== */ +#define DMA_DMA0_B_START_REG_DMA0_B_START_Pos (0UL) /*!< DMA0_B_START (Bit 0) */ +#define DMA_DMA0_B_START_REG_DMA0_B_START_Msk (0xffffffffUL) /*!< DMA0_B_START (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== DMA0_CTRL_REG ===================================================== */ +#define DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ +#define DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ +#define DMA_DMA0_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ +#define DMA_DMA0_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ +#define DMA_DMA0_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ +#define DMA_DMA0_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ +#define DMA_DMA0_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ +#define DMA_DMA0_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ +#define DMA_DMA0_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ +#define DMA_DMA0_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ +#define DMA_DMA0_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ +#define DMA_DMA0_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ +#define DMA_DMA0_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ +#define DMA_DMA0_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ +#define DMA_DMA0_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ +#define DMA_DMA0_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA0_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ +#define DMA_DMA0_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA0_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ +#define DMA_DMA0_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ +#define DMA_DMA0_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ +#define DMA_DMA0_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ +#define DMA_DMA0_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ +#define DMA_DMA0_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== DMA0_IDX_REG ====================================================== */ +#define DMA_DMA0_IDX_REG_DMA0_IDX_Pos (0UL) /*!< DMA0_IDX (Bit 0) */ +#define DMA_DMA0_IDX_REG_DMA0_IDX_Msk (0xffffUL) /*!< DMA0_IDX (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA0_INT_REG ====================================================== */ +#define DMA_DMA0_INT_REG_DMA0_INT_Pos (0UL) /*!< DMA0_INT (Bit 0) */ +#define DMA_DMA0_INT_REG_DMA0_INT_Msk (0xffffUL) /*!< DMA0_INT (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA0_LEN_REG ====================================================== */ +#define DMA_DMA0_LEN_REG_DMA0_LEN_Pos (0UL) /*!< DMA0_LEN (Bit 0) */ +#define DMA_DMA0_LEN_REG_DMA0_LEN_Msk (0xffffUL) /*!< DMA0_LEN (Bitfield-Mask: 0xffff) */ +/* =================================================== DMA1_A_START_REG ==================================================== */ +#define DMA_DMA1_A_START_REG_DMA1_A_START_Pos (0UL) /*!< DMA1_A_START (Bit 0) */ +#define DMA_DMA1_A_START_REG_DMA1_A_START_Msk (0xffffffffUL) /*!< DMA1_A_START (Bitfield-Mask: 0xffffffff) */ +/* =================================================== DMA1_B_START_REG ==================================================== */ +#define DMA_DMA1_B_START_REG_DMA1_B_START_Pos (0UL) /*!< DMA1_B_START (Bit 0) */ +#define DMA_DMA1_B_START_REG_DMA1_B_START_Msk (0xffffffffUL) /*!< DMA1_B_START (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== DMA1_CTRL_REG ===================================================== */ +#define DMA_DMA1_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ +#define DMA_DMA1_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ +#define DMA_DMA1_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ +#define DMA_DMA1_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ +#define DMA_DMA1_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ +#define DMA_DMA1_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ +#define DMA_DMA1_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ +#define DMA_DMA1_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ +#define DMA_DMA1_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ +#define DMA_DMA1_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ +#define DMA_DMA1_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ +#define DMA_DMA1_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ +#define DMA_DMA1_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ +#define DMA_DMA1_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ +#define DMA_DMA1_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ +#define DMA_DMA1_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA1_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ +#define DMA_DMA1_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA1_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ +#define DMA_DMA1_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ +#define DMA_DMA1_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ +#define DMA_DMA1_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ +#define DMA_DMA1_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ +#define DMA_DMA1_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== DMA1_IDX_REG ====================================================== */ +#define DMA_DMA1_IDX_REG_DMA1_IDX_Pos (0UL) /*!< DMA1_IDX (Bit 0) */ +#define DMA_DMA1_IDX_REG_DMA1_IDX_Msk (0xffffUL) /*!< DMA1_IDX (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA1_INT_REG ====================================================== */ +#define DMA_DMA1_INT_REG_DMA1_INT_Pos (0UL) /*!< DMA1_INT (Bit 0) */ +#define DMA_DMA1_INT_REG_DMA1_INT_Msk (0xffffUL) /*!< DMA1_INT (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA1_LEN_REG ====================================================== */ +#define DMA_DMA1_LEN_REG_DMA1_LEN_Pos (0UL) /*!< DMA1_LEN (Bit 0) */ +#define DMA_DMA1_LEN_REG_DMA1_LEN_Msk (0xffffUL) /*!< DMA1_LEN (Bitfield-Mask: 0xffff) */ +/* =================================================== DMA2_A_START_REG ==================================================== */ +#define DMA_DMA2_A_START_REG_DMA2_A_START_Pos (0UL) /*!< DMA2_A_START (Bit 0) */ +#define DMA_DMA2_A_START_REG_DMA2_A_START_Msk (0xffffffffUL) /*!< DMA2_A_START (Bitfield-Mask: 0xffffffff) */ +/* =================================================== DMA2_B_START_REG ==================================================== */ +#define DMA_DMA2_B_START_REG_DMA2_B_START_Pos (0UL) /*!< DMA2_B_START (Bit 0) */ +#define DMA_DMA2_B_START_REG_DMA2_B_START_Msk (0xffffffffUL) /*!< DMA2_B_START (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== DMA2_CTRL_REG ===================================================== */ +#define DMA_DMA2_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ +#define DMA_DMA2_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ +#define DMA_DMA2_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ +#define DMA_DMA2_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ +#define DMA_DMA2_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ +#define DMA_DMA2_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ +#define DMA_DMA2_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ +#define DMA_DMA2_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ +#define DMA_DMA2_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ +#define DMA_DMA2_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ +#define DMA_DMA2_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ +#define DMA_DMA2_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ +#define DMA_DMA2_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ +#define DMA_DMA2_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ +#define DMA_DMA2_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ +#define DMA_DMA2_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA2_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ +#define DMA_DMA2_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA2_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ +#define DMA_DMA2_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ +#define DMA_DMA2_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ +#define DMA_DMA2_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ +#define DMA_DMA2_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ +#define DMA_DMA2_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== DMA2_IDX_REG ====================================================== */ +#define DMA_DMA2_IDX_REG_DMA2_IDX_Pos (0UL) /*!< DMA2_IDX (Bit 0) */ +#define DMA_DMA2_IDX_REG_DMA2_IDX_Msk (0xffffUL) /*!< DMA2_IDX (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA2_INT_REG ====================================================== */ +#define DMA_DMA2_INT_REG_DMA2_INT_Pos (0UL) /*!< DMA2_INT (Bit 0) */ +#define DMA_DMA2_INT_REG_DMA2_INT_Msk (0xffffUL) /*!< DMA2_INT (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA2_LEN_REG ====================================================== */ +#define DMA_DMA2_LEN_REG_DMA2_LEN_Pos (0UL) /*!< DMA2_LEN (Bit 0) */ +#define DMA_DMA2_LEN_REG_DMA2_LEN_Msk (0xffffUL) /*!< DMA2_LEN (Bitfield-Mask: 0xffff) */ +/* =================================================== DMA3_A_START_REG ==================================================== */ +#define DMA_DMA3_A_START_REG_DMA3_A_START_Pos (0UL) /*!< DMA3_A_START (Bit 0) */ +#define DMA_DMA3_A_START_REG_DMA3_A_START_Msk (0xffffffffUL) /*!< DMA3_A_START (Bitfield-Mask: 0xffffffff) */ +/* =================================================== DMA3_B_START_REG ==================================================== */ +#define DMA_DMA3_B_START_REG_DMA3_B_START_Pos (0UL) /*!< DMA3_B_START (Bit 0) */ +#define DMA_DMA3_B_START_REG_DMA3_B_START_Msk (0xffffffffUL) /*!< DMA3_B_START (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== DMA3_CTRL_REG ===================================================== */ +#define DMA_DMA3_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ +#define DMA_DMA3_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ +#define DMA_DMA3_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ +#define DMA_DMA3_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ +#define DMA_DMA3_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ +#define DMA_DMA3_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ +#define DMA_DMA3_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ +#define DMA_DMA3_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ +#define DMA_DMA3_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ +#define DMA_DMA3_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ +#define DMA_DMA3_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ +#define DMA_DMA3_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ +#define DMA_DMA3_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ +#define DMA_DMA3_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ +#define DMA_DMA3_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ +#define DMA_DMA3_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA3_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ +#define DMA_DMA3_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA3_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ +#define DMA_DMA3_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ +#define DMA_DMA3_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ +#define DMA_DMA3_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ +#define DMA_DMA3_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ +#define DMA_DMA3_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== DMA3_IDX_REG ====================================================== */ +#define DMA_DMA3_IDX_REG_DMA3_IDX_Pos (0UL) /*!< DMA3_IDX (Bit 0) */ +#define DMA_DMA3_IDX_REG_DMA3_IDX_Msk (0xffffUL) /*!< DMA3_IDX (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA3_INT_REG ====================================================== */ +#define DMA_DMA3_INT_REG_DMA3_INT_Pos (0UL) /*!< DMA3_INT (Bit 0) */ +#define DMA_DMA3_INT_REG_DMA3_INT_Msk (0xffffUL) /*!< DMA3_INT (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA3_LEN_REG ====================================================== */ +#define DMA_DMA3_LEN_REG_DMA3_LEN_Pos (0UL) /*!< DMA3_LEN (Bit 0) */ +#define DMA_DMA3_LEN_REG_DMA3_LEN_Msk (0xffffUL) /*!< DMA3_LEN (Bitfield-Mask: 0xffff) */ +/* =================================================== DMA4_A_START_REG ==================================================== */ +#define DMA_DMA4_A_START_REG_DMA4_A_START_Pos (0UL) /*!< DMA4_A_START (Bit 0) */ +#define DMA_DMA4_A_START_REG_DMA4_A_START_Msk (0xffffffffUL) /*!< DMA4_A_START (Bitfield-Mask: 0xffffffff) */ +/* =================================================== DMA4_B_START_REG ==================================================== */ +#define DMA_DMA4_B_START_REG_DMA4_B_START_Pos (0UL) /*!< DMA4_B_START (Bit 0) */ +#define DMA_DMA4_B_START_REG_DMA4_B_START_Msk (0xffffffffUL) /*!< DMA4_B_START (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== DMA4_CTRL_REG ===================================================== */ +#define DMA_DMA4_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ +#define DMA_DMA4_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ +#define DMA_DMA4_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ +#define DMA_DMA4_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ +#define DMA_DMA4_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ +#define DMA_DMA4_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ +#define DMA_DMA4_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ +#define DMA_DMA4_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ +#define DMA_DMA4_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ +#define DMA_DMA4_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ +#define DMA_DMA4_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ +#define DMA_DMA4_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ +#define DMA_DMA4_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ +#define DMA_DMA4_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ +#define DMA_DMA4_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ +#define DMA_DMA4_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA4_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ +#define DMA_DMA4_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA4_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ +#define DMA_DMA4_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ +#define DMA_DMA4_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ +#define DMA_DMA4_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ +#define DMA_DMA4_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ +#define DMA_DMA4_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== DMA4_IDX_REG ====================================================== */ +#define DMA_DMA4_IDX_REG_DMA4_IDX_Pos (0UL) /*!< DMA4_IDX (Bit 0) */ +#define DMA_DMA4_IDX_REG_DMA4_IDX_Msk (0xffffUL) /*!< DMA4_IDX (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA4_INT_REG ====================================================== */ +#define DMA_DMA4_INT_REG_DMA4_INT_Pos (0UL) /*!< DMA4_INT (Bit 0) */ +#define DMA_DMA4_INT_REG_DMA4_INT_Msk (0xffffUL) /*!< DMA4_INT (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA4_LEN_REG ====================================================== */ +#define DMA_DMA4_LEN_REG_DMA4_LEN_Pos (0UL) /*!< DMA4_LEN (Bit 0) */ +#define DMA_DMA4_LEN_REG_DMA4_LEN_Msk (0xffffUL) /*!< DMA4_LEN (Bitfield-Mask: 0xffff) */ +/* =================================================== DMA5_A_START_REG ==================================================== */ +#define DMA_DMA5_A_START_REG_DMA5_A_START_Pos (0UL) /*!< DMA5_A_START (Bit 0) */ +#define DMA_DMA5_A_START_REG_DMA5_A_START_Msk (0xffffffffUL) /*!< DMA5_A_START (Bitfield-Mask: 0xffffffff) */ +/* =================================================== DMA5_B_START_REG ==================================================== */ +#define DMA_DMA5_B_START_REG_DMA5_B_START_Pos (0UL) /*!< DMA5_B_START (Bit 0) */ +#define DMA_DMA5_B_START_REG_DMA5_B_START_Msk (0xffffffffUL) /*!< DMA5_B_START (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== DMA5_CTRL_REG ===================================================== */ +#define DMA_DMA5_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ +#define DMA_DMA5_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ +#define DMA_DMA5_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ +#define DMA_DMA5_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ +#define DMA_DMA5_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ +#define DMA_DMA5_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ +#define DMA_DMA5_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ +#define DMA_DMA5_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ +#define DMA_DMA5_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ +#define DMA_DMA5_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ +#define DMA_DMA5_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ +#define DMA_DMA5_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ +#define DMA_DMA5_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ +#define DMA_DMA5_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ +#define DMA_DMA5_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ +#define DMA_DMA5_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA5_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ +#define DMA_DMA5_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA5_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ +#define DMA_DMA5_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ +#define DMA_DMA5_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ +#define DMA_DMA5_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ +#define DMA_DMA5_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ +#define DMA_DMA5_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== DMA5_IDX_REG ====================================================== */ +#define DMA_DMA5_IDX_REG_DMA5_IDX_Pos (0UL) /*!< DMA5_IDX (Bit 0) */ +#define DMA_DMA5_IDX_REG_DMA5_IDX_Msk (0xffffUL) /*!< DMA5_IDX (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA5_INT_REG ====================================================== */ +#define DMA_DMA5_INT_REG_DMA5_INT_Pos (0UL) /*!< DMA5_INT (Bit 0) */ +#define DMA_DMA5_INT_REG_DMA5_INT_Msk (0xffffUL) /*!< DMA5_INT (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA5_LEN_REG ====================================================== */ +#define DMA_DMA5_LEN_REG_DMA5_LEN_Pos (0UL) /*!< DMA5_LEN (Bit 0) */ +#define DMA_DMA5_LEN_REG_DMA5_LEN_Msk (0xffffUL) /*!< DMA5_LEN (Bitfield-Mask: 0xffff) */ +/* =================================================== DMA6_A_START_REG ==================================================== */ +#define DMA_DMA6_A_START_REG_DMA6_A_START_Pos (0UL) /*!< DMA6_A_START (Bit 0) */ +#define DMA_DMA6_A_START_REG_DMA6_A_START_Msk (0xffffffffUL) /*!< DMA6_A_START (Bitfield-Mask: 0xffffffff) */ +/* =================================================== DMA6_B_START_REG ==================================================== */ +#define DMA_DMA6_B_START_REG_DMA6_B_START_Pos (0UL) /*!< DMA6_B_START (Bit 0) */ +#define DMA_DMA6_B_START_REG_DMA6_B_START_Msk (0xffffffffUL) /*!< DMA6_B_START (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== DMA6_CTRL_REG ===================================================== */ +#define DMA_DMA6_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ +#define DMA_DMA6_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ +#define DMA_DMA6_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ +#define DMA_DMA6_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ +#define DMA_DMA6_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ +#define DMA_DMA6_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ +#define DMA_DMA6_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ +#define DMA_DMA6_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ +#define DMA_DMA6_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ +#define DMA_DMA6_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ +#define DMA_DMA6_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ +#define DMA_DMA6_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ +#define DMA_DMA6_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ +#define DMA_DMA6_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ +#define DMA_DMA6_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ +#define DMA_DMA6_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA6_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ +#define DMA_DMA6_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA6_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ +#define DMA_DMA6_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ +#define DMA_DMA6_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ +#define DMA_DMA6_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ +#define DMA_DMA6_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ +#define DMA_DMA6_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== DMA6_IDX_REG ====================================================== */ +#define DMA_DMA6_IDX_REG_DMA6_IDX_Pos (0UL) /*!< DMA6_IDX (Bit 0) */ +#define DMA_DMA6_IDX_REG_DMA6_IDX_Msk (0xffffUL) /*!< DMA6_IDX (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA6_INT_REG ====================================================== */ +#define DMA_DMA6_INT_REG_DMA6_INT_Pos (0UL) /*!< DMA6_INT (Bit 0) */ +#define DMA_DMA6_INT_REG_DMA6_INT_Msk (0xffffUL) /*!< DMA6_INT (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA6_LEN_REG ====================================================== */ +#define DMA_DMA6_LEN_REG_DMA6_LEN_Pos (0UL) /*!< DMA6_LEN (Bit 0) */ +#define DMA_DMA6_LEN_REG_DMA6_LEN_Msk (0xffffUL) /*!< DMA6_LEN (Bitfield-Mask: 0xffff) */ +/* =================================================== DMA7_A_START_REG ==================================================== */ +#define DMA_DMA7_A_START_REG_DMA7_A_START_Pos (0UL) /*!< DMA7_A_START (Bit 0) */ +#define DMA_DMA7_A_START_REG_DMA7_A_START_Msk (0xffffffffUL) /*!< DMA7_A_START (Bitfield-Mask: 0xffffffff) */ +/* =================================================== DMA7_B_START_REG ==================================================== */ +#define DMA_DMA7_B_START_REG_DMA7_B_START_Pos (0UL) /*!< DMA7_B_START (Bit 0) */ +#define DMA_DMA7_B_START_REG_DMA7_B_START_Msk (0xffffffffUL) /*!< DMA7_B_START (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== DMA7_CTRL_REG ===================================================== */ +#define DMA_DMA7_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ +#define DMA_DMA7_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ +#define DMA_DMA7_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ +#define DMA_DMA7_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ +#define DMA_DMA7_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ +#define DMA_DMA7_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ +#define DMA_DMA7_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ +#define DMA_DMA7_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ +#define DMA_DMA7_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ +#define DMA_DMA7_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ +#define DMA_DMA7_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ +#define DMA_DMA7_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ +#define DMA_DMA7_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ +#define DMA_DMA7_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ +#define DMA_DMA7_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ +#define DMA_DMA7_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA7_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ +#define DMA_DMA7_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ +#define DMA_DMA7_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ +#define DMA_DMA7_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ +#define DMA_DMA7_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ +#define DMA_DMA7_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ +#define DMA_DMA7_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ +#define DMA_DMA7_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== DMA7_IDX_REG ====================================================== */ +#define DMA_DMA7_IDX_REG_DMA7_IDX_Pos (0UL) /*!< DMA7_IDX (Bit 0) */ +#define DMA_DMA7_IDX_REG_DMA7_IDX_Msk (0xffffUL) /*!< DMA7_IDX (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA7_INT_REG ====================================================== */ +#define DMA_DMA7_INT_REG_DMA7_INT_Pos (0UL) /*!< DMA7_INT (Bit 0) */ +#define DMA_DMA7_INT_REG_DMA7_INT_Msk (0xffffUL) /*!< DMA7_INT (Bitfield-Mask: 0xffff) */ +/* ===================================================== DMA7_LEN_REG ====================================================== */ +#define DMA_DMA7_LEN_REG_DMA7_LEN_Pos (0UL) /*!< DMA7_LEN (Bit 0) */ +#define DMA_DMA7_LEN_REG_DMA7_LEN_Msk (0xffffUL) /*!< DMA7_LEN (Bitfield-Mask: 0xffff) */ +/* =================================================== DMA_CLEAR_INT_REG =================================================== */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH7_Pos (7UL) /*!< DMA_RST_IRQ_CH7 (Bit 7) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH7_Msk (0x80UL) /*!< DMA_RST_IRQ_CH7 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH6_Pos (6UL) /*!< DMA_RST_IRQ_CH6 (Bit 6) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH6_Msk (0x40UL) /*!< DMA_RST_IRQ_CH6 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH5_Pos (5UL) /*!< DMA_RST_IRQ_CH5 (Bit 5) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH5_Msk (0x20UL) /*!< DMA_RST_IRQ_CH5 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH4_Pos (4UL) /*!< DMA_RST_IRQ_CH4 (Bit 4) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH4_Msk (0x10UL) /*!< DMA_RST_IRQ_CH4 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH3_Pos (3UL) /*!< DMA_RST_IRQ_CH3 (Bit 3) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH3_Msk (0x8UL) /*!< DMA_RST_IRQ_CH3 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH2_Pos (2UL) /*!< DMA_RST_IRQ_CH2 (Bit 2) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH2_Msk (0x4UL) /*!< DMA_RST_IRQ_CH2 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH1_Pos (1UL) /*!< DMA_RST_IRQ_CH1 (Bit 1) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH1_Msk (0x2UL) /*!< DMA_RST_IRQ_CH1 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH0_Pos (0UL) /*!< DMA_RST_IRQ_CH0 (Bit 0) */ +#define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH0_Msk (0x1UL) /*!< DMA_RST_IRQ_CH0 (Bitfield-Mask: 0x01) */ +/* =================================================== DMA_INT_MASK_REG ==================================================== */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE7_Pos (7UL) /*!< DMA_IRQ_ENABLE7 (Bit 7) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE7_Msk (0x80UL) /*!< DMA_IRQ_ENABLE7 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE6_Pos (6UL) /*!< DMA_IRQ_ENABLE6 (Bit 6) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE6_Msk (0x40UL) /*!< DMA_IRQ_ENABLE6 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE5_Pos (5UL) /*!< DMA_IRQ_ENABLE5 (Bit 5) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE5_Msk (0x20UL) /*!< DMA_IRQ_ENABLE5 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE4_Pos (4UL) /*!< DMA_IRQ_ENABLE4 (Bit 4) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE4_Msk (0x10UL) /*!< DMA_IRQ_ENABLE4 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE3_Pos (3UL) /*!< DMA_IRQ_ENABLE3 (Bit 3) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE3_Msk (0x8UL) /*!< DMA_IRQ_ENABLE3 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE2_Pos (2UL) /*!< DMA_IRQ_ENABLE2 (Bit 2) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE2_Msk (0x4UL) /*!< DMA_IRQ_ENABLE2 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE1_Pos (1UL) /*!< DMA_IRQ_ENABLE1 (Bit 1) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE1_Msk (0x2UL) /*!< DMA_IRQ_ENABLE1 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE0_Pos (0UL) /*!< DMA_IRQ_ENABLE0 (Bit 0) */ +#define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE0_Msk (0x1UL) /*!< DMA_IRQ_ENABLE0 (Bitfield-Mask: 0x01) */ +/* ================================================== DMA_INT_STATUS_REG =================================================== */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR7_Pos (15UL) /*!< DMA_BUS_ERR7 (Bit 15) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR7_Msk (0x8000UL) /*!< DMA_BUS_ERR7 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR6_Pos (14UL) /*!< DMA_BUS_ERR6 (Bit 14) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR6_Msk (0x4000UL) /*!< DMA_BUS_ERR6 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR5_Pos (13UL) /*!< DMA_BUS_ERR5 (Bit 13) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR5_Msk (0x2000UL) /*!< DMA_BUS_ERR5 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR4_Pos (12UL) /*!< DMA_BUS_ERR4 (Bit 12) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR4_Msk (0x1000UL) /*!< DMA_BUS_ERR4 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR3_Pos (11UL) /*!< DMA_BUS_ERR3 (Bit 11) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR3_Msk (0x800UL) /*!< DMA_BUS_ERR3 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR2_Pos (10UL) /*!< DMA_BUS_ERR2 (Bit 10) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR2_Msk (0x400UL) /*!< DMA_BUS_ERR2 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR1_Pos (9UL) /*!< DMA_BUS_ERR1 (Bit 9) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR1_Msk (0x200UL) /*!< DMA_BUS_ERR1 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR0_Pos (8UL) /*!< DMA_BUS_ERR0 (Bit 8) */ +#define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR0_Msk (0x100UL) /*!< DMA_BUS_ERR0 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH7_Pos (7UL) /*!< DMA_IRQ_CH7 (Bit 7) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH7_Msk (0x80UL) /*!< DMA_IRQ_CH7 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH6_Pos (6UL) /*!< DMA_IRQ_CH6 (Bit 6) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH6_Msk (0x40UL) /*!< DMA_IRQ_CH6 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH5_Pos (5UL) /*!< DMA_IRQ_CH5 (Bit 5) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH5_Msk (0x20UL) /*!< DMA_IRQ_CH5 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH4_Pos (4UL) /*!< DMA_IRQ_CH4 (Bit 4) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH4_Msk (0x10UL) /*!< DMA_IRQ_CH4 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH3_Pos (3UL) /*!< DMA_IRQ_CH3 (Bit 3) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH3_Msk (0x8UL) /*!< DMA_IRQ_CH3 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH2_Pos (2UL) /*!< DMA_IRQ_CH2 (Bit 2) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH2_Msk (0x4UL) /*!< DMA_IRQ_CH2 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH1_Pos (1UL) /*!< DMA_IRQ_CH1 (Bit 1) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH1_Msk (0x2UL) /*!< DMA_IRQ_CH1 (Bitfield-Mask: 0x01) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH0_Pos (0UL) /*!< DMA_IRQ_CH0 (Bit 0) */ +#define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH0_Msk (0x1UL) /*!< DMA_IRQ_CH0 (Bitfield-Mask: 0x01) */ +/* ==================================================== DMA_REQ_MUX_REG ==================================================== */ +#define DMA_DMA_REQ_MUX_REG_DMA67_SEL_Pos (12UL) /*!< DMA67_SEL (Bit 12) */ +#define DMA_DMA_REQ_MUX_REG_DMA67_SEL_Msk (0xf000UL) /*!< DMA67_SEL (Bitfield-Mask: 0x0f) */ +#define DMA_DMA_REQ_MUX_REG_DMA45_SEL_Pos (8UL) /*!< DMA45_SEL (Bit 8) */ +#define DMA_DMA_REQ_MUX_REG_DMA45_SEL_Msk (0xf00UL) /*!< DMA45_SEL (Bitfield-Mask: 0x0f) */ +#define DMA_DMA_REQ_MUX_REG_DMA23_SEL_Pos (4UL) /*!< DMA23_SEL (Bit 4) */ +#define DMA_DMA_REQ_MUX_REG_DMA23_SEL_Msk (0xf0UL) /*!< DMA23_SEL (Bitfield-Mask: 0x0f) */ +#define DMA_DMA_REQ_MUX_REG_DMA01_SEL_Pos (0UL) /*!< DMA01_SEL (Bit 0) */ +#define DMA_DMA_REQ_MUX_REG_DMA01_SEL_Msk (0xfUL) /*!< DMA01_SEL (Bitfield-Mask: 0x0f) */ + + +/* =========================================================================================================================== */ +/* ================ DW ================ */ +/* =========================================================================================================================== */ + +/* =================================================== AHB_DMA_CCLM1_REG =================================================== */ +#define DW_AHB_DMA_CCLM1_REG_AHB_DMA_CCLM_Pos (0UL) /*!< AHB_DMA_CCLM (Bit 0) */ +#define DW_AHB_DMA_CCLM1_REG_AHB_DMA_CCLM_Msk (0xffffUL) /*!< AHB_DMA_CCLM (Bitfield-Mask: 0xffff) */ +/* =================================================== AHB_DMA_CCLM2_REG =================================================== */ +#define DW_AHB_DMA_CCLM2_REG_AHB_DMA_CCLM_Pos (0UL) /*!< AHB_DMA_CCLM (Bit 0) */ +#define DW_AHB_DMA_CCLM2_REG_AHB_DMA_CCLM_Msk (0xffffUL) /*!< AHB_DMA_CCLM (Bitfield-Mask: 0xffff) */ +/* =================================================== AHB_DMA_CCLM3_REG =================================================== */ +#define DW_AHB_DMA_CCLM3_REG_AHB_DMA_CCLM_Pos (0UL) /*!< AHB_DMA_CCLM (Bit 0) */ +#define DW_AHB_DMA_CCLM3_REG_AHB_DMA_CCLM_Msk (0xffffUL) /*!< AHB_DMA_CCLM (Bitfield-Mask: 0xffff) */ +/* =================================================== AHB_DMA_CCLM4_REG =================================================== */ +#define DW_AHB_DMA_CCLM4_REG_AHB_DMA_CCLM_Pos (0UL) /*!< AHB_DMA_CCLM (Bit 0) */ +#define DW_AHB_DMA_CCLM4_REG_AHB_DMA_CCLM_Msk (0xffffUL) /*!< AHB_DMA_CCLM (Bitfield-Mask: 0xffff) */ +/* ================================================ AHB_DMA_DFLT_MASTER_REG ================================================ */ +#define DW_AHB_DMA_DFLT_MASTER_REG_AHB_DMA_DFLT_MASTER_Pos (0UL) /*!< AHB_DMA_DFLT_MASTER (Bit 0) */ +#define DW_AHB_DMA_DFLT_MASTER_REG_AHB_DMA_DFLT_MASTER_Msk (0xfUL) /*!< AHB_DMA_DFLT_MASTER (Bitfield-Mask: 0x0f) */ +/* ==================================================== AHB_DMA_PL1_REG ==================================================== */ +#define DW_AHB_DMA_PL1_REG_AHB_DMA_PL1_Pos (0UL) /*!< AHB_DMA_PL1 (Bit 0) */ +#define DW_AHB_DMA_PL1_REG_AHB_DMA_PL1_Msk (0xfUL) /*!< AHB_DMA_PL1 (Bitfield-Mask: 0x0f) */ +/* ==================================================== AHB_DMA_PL2_REG ==================================================== */ +#define DW_AHB_DMA_PL2_REG_AHB_DMA_PL2_Pos (0UL) /*!< AHB_DMA_PL2 (Bit 0) */ +#define DW_AHB_DMA_PL2_REG_AHB_DMA_PL2_Msk (0xfUL) /*!< AHB_DMA_PL2 (Bitfield-Mask: 0x0f) */ +/* ==================================================== AHB_DMA_PL3_REG ==================================================== */ +#define DW_AHB_DMA_PL3_REG_AHB_DMA_PL3_Pos (0UL) /*!< AHB_DMA_PL3 (Bit 0) */ +#define DW_AHB_DMA_PL3_REG_AHB_DMA_PL3_Msk (0xfUL) /*!< AHB_DMA_PL3 (Bitfield-Mask: 0x0f) */ +/* ==================================================== AHB_DMA_PL4_REG ==================================================== */ +#define DW_AHB_DMA_PL4_REG_AHB_DMA_PL4_Pos (0UL) /*!< AHB_DMA_PL4 (Bit 0) */ +#define DW_AHB_DMA_PL4_REG_AHB_DMA_PL4_Msk (0xfUL) /*!< AHB_DMA_PL4 (Bitfield-Mask: 0x0f) */ +/* ==================================================== AHB_DMA_TCL_REG ==================================================== */ +#define DW_AHB_DMA_TCL_REG_AHB_DMA_TCL_Pos (0UL) /*!< AHB_DMA_TCL (Bit 0) */ +#define DW_AHB_DMA_TCL_REG_AHB_DMA_TCL_Msk (0xffffUL) /*!< AHB_DMA_TCL (Bitfield-Mask: 0xffff) */ +/* ================================================== AHB_DMA_VERSION_REG ================================================== */ +#define DW_AHB_DMA_VERSION_REG_AHB_DMA_VERSION_Pos (0UL) /*!< AHB_DMA_VERSION (Bit 0) */ +#define DW_AHB_DMA_VERSION_REG_AHB_DMA_VERSION_Msk (0xffffffffUL) /*!< AHB_DMA_VERSION (Bitfield-Mask: 0xffffffff) */ +/* =================================================== AHB_DMA_WTEN_REG ==================================================== */ +#define DW_AHB_DMA_WTEN_REG_AHB_DMA_WTEN_Pos (0UL) /*!< AHB_DMA_WTEN (Bit 0) */ +#define DW_AHB_DMA_WTEN_REG_AHB_DMA_WTEN_Msk (0x1UL) /*!< AHB_DMA_WTEN (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ GPADC ================ */ +/* =========================================================================================================================== */ + +/* ================================================= GP_ADC_CLEAR_INT_REG ================================================== */ +#define GPADC_GP_ADC_CLEAR_INT_REG_GP_ADC_CLR_INT_Pos (0UL) /*!< GP_ADC_CLR_INT (Bit 0) */ +#define GPADC_GP_ADC_CLEAR_INT_REG_GP_ADC_CLR_INT_Msk (0xffffUL) /*!< GP_ADC_CLR_INT (Bitfield-Mask: 0xffff) */ +/* =================================================== GP_ADC_CTRL2_REG ==================================================== */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_STORE_DEL_Pos (12UL) /*!< GP_ADC_STORE_DEL (Bit 12) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_STORE_DEL_Msk (0xf000UL) /*!< GP_ADC_STORE_DEL (Bitfield-Mask: 0x0f) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_SMPL_TIME_Pos (8UL) /*!< GP_ADC_SMPL_TIME (Bit 8) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_SMPL_TIME_Msk (0xf00UL) /*!< GP_ADC_SMPL_TIME (Bitfield-Mask: 0x0f) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_CONV_NRS_Pos (5UL) /*!< GP_ADC_CONV_NRS (Bit 5) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_CONV_NRS_Msk (0xe0UL) /*!< GP_ADC_CONV_NRS (Bitfield-Mask: 0x07) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_DMA_EN_Pos (3UL) /*!< GP_ADC_DMA_EN (Bit 3) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_DMA_EN_Msk (0x8UL) /*!< GP_ADC_DMA_EN (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_I20U_Pos (2UL) /*!< GP_ADC_I20U (Bit 2) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_I20U_Msk (0x4UL) /*!< GP_ADC_I20U (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_IDYN_Pos (1UL) /*!< GP_ADC_IDYN (Bit 1) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_IDYN_Msk (0x2UL) /*!< GP_ADC_IDYN (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_ATTN3X_Pos (0UL) /*!< GP_ADC_ATTN3X (Bit 0) */ +#define GPADC_GP_ADC_CTRL2_REG_GP_ADC_ATTN3X_Msk (0x1UL) /*!< GP_ADC_ATTN3X (Bitfield-Mask: 0x01) */ +/* =================================================== GP_ADC_CTRL3_REG ==================================================== */ +#define GPADC_GP_ADC_CTRL3_REG_GP_ADC_INTERVAL_Pos (8UL) /*!< GP_ADC_INTERVAL (Bit 8) */ +#define GPADC_GP_ADC_CTRL3_REG_GP_ADC_INTERVAL_Msk (0xff00UL) /*!< GP_ADC_INTERVAL (Bitfield-Mask: 0xff) */ +#define GPADC_GP_ADC_CTRL3_REG_GP_ADC_EN_DEL_Pos (0UL) /*!< GP_ADC_EN_DEL (Bit 0) */ +#define GPADC_GP_ADC_CTRL3_REG_GP_ADC_EN_DEL_Msk (0xffUL) /*!< GP_ADC_EN_DEL (Bitfield-Mask: 0xff) */ +/* ==================================================== GP_ADC_CTRL_REG ==================================================== */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_DIFF_TEMP_EN_Pos (18UL) /*!< GP_ADC_DIFF_TEMP_EN (Bit 18) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_DIFF_TEMP_EN_Msk (0x40000UL) /*!< GP_ADC_DIFF_TEMP_EN (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_DIFF_TEMP_SEL_Pos (16UL) /*!< GP_ADC_DIFF_TEMP_SEL (Bit 16) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_DIFF_TEMP_SEL_Msk (0x30000UL) /*!< GP_ADC_DIFF_TEMP_SEL (Bitfield-Mask: 0x03) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_LDO_ZERO_Pos (15UL) /*!< GP_ADC_LDO_ZERO (Bit 15) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_LDO_ZERO_Msk (0x8000UL) /*!< GP_ADC_LDO_ZERO (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_CHOP_Pos (14UL) /*!< GP_ADC_CHOP (Bit 14) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_CHOP_Msk (0x4000UL) /*!< GP_ADC_CHOP (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_SIGN_Pos (13UL) /*!< GP_ADC_SIGN (Bit 13) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_SIGN_Msk (0x2000UL) /*!< GP_ADC_SIGN (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_SEL_Pos (8UL) /*!< GP_ADC_SEL (Bit 8) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_SEL_Msk (0x1f00UL) /*!< GP_ADC_SEL (Bitfield-Mask: 0x1f) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_MUTE_Pos (7UL) /*!< GP_ADC_MUTE (Bit 7) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_MUTE_Msk (0x80UL) /*!< GP_ADC_MUTE (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_SE_Pos (6UL) /*!< GP_ADC_SE (Bit 6) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_SE_Msk (0x40UL) /*!< GP_ADC_SE (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_MINT_Pos (5UL) /*!< GP_ADC_MINT (Bit 5) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_MINT_Msk (0x20UL) /*!< GP_ADC_MINT (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_INT_Pos (4UL) /*!< GP_ADC_INT (Bit 4) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_INT_Msk (0x10UL) /*!< GP_ADC_INT (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_CLK_SEL_Pos (3UL) /*!< GP_ADC_CLK_SEL (Bit 3) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_CLK_SEL_Msk (0x8UL) /*!< GP_ADC_CLK_SEL (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_CONT_Pos (2UL) /*!< GP_ADC_CONT (Bit 2) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_CONT_Msk (0x4UL) /*!< GP_ADC_CONT (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_START_Pos (1UL) /*!< GP_ADC_START (Bit 1) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_START_Msk (0x2UL) /*!< GP_ADC_START (Bitfield-Mask: 0x01) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_EN_Pos (0UL) /*!< GP_ADC_EN (Bit 0) */ +#define GPADC_GP_ADC_CTRL_REG_GP_ADC_EN_Msk (0x1UL) /*!< GP_ADC_EN (Bitfield-Mask: 0x01) */ +/* ==================================================== GP_ADC_OFFN_REG ==================================================== */ +#define GPADC_GP_ADC_OFFN_REG_GP_ADC_OFFN_Pos (0UL) /*!< GP_ADC_OFFN (Bit 0) */ +#define GPADC_GP_ADC_OFFN_REG_GP_ADC_OFFN_Msk (0x3ffUL) /*!< GP_ADC_OFFN (Bitfield-Mask: 0x3ff) */ +/* ==================================================== GP_ADC_OFFP_REG ==================================================== */ +#define GPADC_GP_ADC_OFFP_REG_GP_ADC_OFFP_Pos (0UL) /*!< GP_ADC_OFFP (Bit 0) */ +#define GPADC_GP_ADC_OFFP_REG_GP_ADC_OFFP_Msk (0x3ffUL) /*!< GP_ADC_OFFP (Bitfield-Mask: 0x3ff) */ +/* =================================================== GP_ADC_RESULT_REG =================================================== */ +#define GPADC_GP_ADC_RESULT_REG_GP_ADC_VAL_Pos (0UL) /*!< GP_ADC_VAL (Bit 0) */ +#define GPADC_GP_ADC_RESULT_REG_GP_ADC_VAL_Msk (0xffffUL) /*!< GP_ADC_VAL (Bitfield-Mask: 0xffff) */ + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + +/* =================================================== GPIO_CLK_SEL_REG ==================================================== */ +#define GPIO_GPIO_CLK_SEL_REG_DIVN_OUTPUT_EN_Pos (9UL) /*!< DIVN_OUTPUT_EN (Bit 9) */ +#define GPIO_GPIO_CLK_SEL_REG_DIVN_OUTPUT_EN_Msk (0x200UL) /*!< DIVN_OUTPUT_EN (Bitfield-Mask: 0x01) */ +#define GPIO_GPIO_CLK_SEL_REG_RC32M_OUTPUT_EN_Pos (8UL) /*!< RC32M_OUTPUT_EN (Bit 8) */ +#define GPIO_GPIO_CLK_SEL_REG_RC32M_OUTPUT_EN_Msk (0x100UL) /*!< RC32M_OUTPUT_EN (Bitfield-Mask: 0x01) */ +#define GPIO_GPIO_CLK_SEL_REG_XTAL32M_OUTPUT_EN_Pos (7UL) /*!< XTAL32M_OUTPUT_EN (Bit 7) */ +#define GPIO_GPIO_CLK_SEL_REG_XTAL32M_OUTPUT_EN_Msk (0x80UL) /*!< XTAL32M_OUTPUT_EN (Bitfield-Mask: 0x01) */ +#define GPIO_GPIO_CLK_SEL_REG_RCX_OUTPUT_EN_Pos (6UL) /*!< RCX_OUTPUT_EN (Bit 6) */ +#define GPIO_GPIO_CLK_SEL_REG_RCX_OUTPUT_EN_Msk (0x40UL) /*!< RCX_OUTPUT_EN (Bitfield-Mask: 0x01) */ +#define GPIO_GPIO_CLK_SEL_REG_RC32K_OUTPUT_EN_Pos (5UL) /*!< RC32K_OUTPUT_EN (Bit 5) */ +#define GPIO_GPIO_CLK_SEL_REG_RC32K_OUTPUT_EN_Msk (0x20UL) /*!< RC32K_OUTPUT_EN (Bitfield-Mask: 0x01) */ +#define GPIO_GPIO_CLK_SEL_REG_XTAL32K_OUTPUT_EN_Pos (4UL) /*!< XTAL32K_OUTPUT_EN (Bit 4) */ +#define GPIO_GPIO_CLK_SEL_REG_XTAL32K_OUTPUT_EN_Msk (0x10UL) /*!< XTAL32K_OUTPUT_EN (Bitfield-Mask: 0x01) */ +#define GPIO_GPIO_CLK_SEL_REG_FUNC_CLOCK_EN_Pos (3UL) /*!< FUNC_CLOCK_EN (Bit 3) */ +#define GPIO_GPIO_CLK_SEL_REG_FUNC_CLOCK_EN_Msk (0x8UL) /*!< FUNC_CLOCK_EN (Bitfield-Mask: 0x01) */ +#define GPIO_GPIO_CLK_SEL_REG_FUNC_CLOCK_SEL_Pos (0UL) /*!< FUNC_CLOCK_SEL (Bit 0) */ +#define GPIO_GPIO_CLK_SEL_REG_FUNC_CLOCK_SEL_Msk (0x7UL) /*!< FUNC_CLOCK_SEL (Bitfield-Mask: 0x07) */ +/* ==================================================== P0_00_MODE_REG ===================================================== */ +#define GPIO_P0_00_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_00_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_00_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_00_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_00_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_00_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_01_MODE_REG ===================================================== */ +#define GPIO_P0_01_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_01_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_01_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_01_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_01_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_01_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_02_MODE_REG ===================================================== */ +#define GPIO_P0_02_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_02_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_02_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_02_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_02_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_02_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_03_MODE_REG ===================================================== */ +#define GPIO_P0_03_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_03_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_03_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_03_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_03_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_03_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_04_MODE_REG ===================================================== */ +#define GPIO_P0_04_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_04_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_04_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_04_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_04_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_04_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_05_MODE_REG ===================================================== */ +#define GPIO_P0_05_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_05_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_05_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_05_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_05_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_05_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_06_MODE_REG ===================================================== */ +#define GPIO_P0_06_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_06_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_06_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_06_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_06_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_06_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_07_MODE_REG ===================================================== */ +#define GPIO_P0_07_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_07_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_07_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_07_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_07_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_07_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_08_MODE_REG ===================================================== */ +#define GPIO_P0_08_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_08_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_08_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_08_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_08_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_08_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_09_MODE_REG ===================================================== */ +#define GPIO_P0_09_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_09_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_09_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_09_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_09_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_09_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_10_MODE_REG ===================================================== */ +#define GPIO_P0_10_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_10_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_10_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_10_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_10_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_10_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_11_MODE_REG ===================================================== */ +#define GPIO_P0_11_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_11_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_11_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_11_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_11_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_11_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_12_MODE_REG ===================================================== */ +#define GPIO_P0_12_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_12_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_12_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_12_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_12_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_12_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_13_MODE_REG ===================================================== */ +#define GPIO_P0_13_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_13_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_13_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_13_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_13_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_13_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_14_MODE_REG ===================================================== */ +#define GPIO_P0_14_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_14_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_14_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_14_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_14_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_14_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_15_MODE_REG ===================================================== */ +#define GPIO_P0_15_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_15_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_15_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_15_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_15_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_15_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_16_MODE_REG ===================================================== */ +#define GPIO_P0_16_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_16_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_16_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_16_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_16_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_16_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_17_MODE_REG ===================================================== */ +#define GPIO_P0_17_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_17_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_17_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_17_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_17_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_17_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_18_MODE_REG ===================================================== */ +#define GPIO_P0_18_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_18_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_18_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_18_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_18_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_18_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_19_MODE_REG ===================================================== */ +#define GPIO_P0_19_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_19_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_19_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_19_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_19_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_19_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_20_MODE_REG ===================================================== */ +#define GPIO_P0_20_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_20_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_20_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_20_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_20_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_20_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_21_MODE_REG ===================================================== */ +#define GPIO_P0_21_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_21_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_21_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_21_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_21_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_21_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_22_MODE_REG ===================================================== */ +#define GPIO_P0_22_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_22_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_22_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_22_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_22_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_22_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_23_MODE_REG ===================================================== */ +#define GPIO_P0_23_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_23_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_23_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_23_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_23_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_23_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_24_MODE_REG ===================================================== */ +#define GPIO_P0_24_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_24_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_24_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_24_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_24_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_24_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_25_MODE_REG ===================================================== */ +#define GPIO_P0_25_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_25_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_25_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_25_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_25_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_25_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_26_MODE_REG ===================================================== */ +#define GPIO_P0_26_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_26_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_26_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_26_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_26_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_26_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_27_MODE_REG ===================================================== */ +#define GPIO_P0_27_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_27_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_27_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_27_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_27_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_27_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_28_MODE_REG ===================================================== */ +#define GPIO_P0_28_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_28_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_28_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_28_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_28_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_28_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_29_MODE_REG ===================================================== */ +#define GPIO_P0_29_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_29_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_29_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_29_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_29_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_29_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_30_MODE_REG ===================================================== */ +#define GPIO_P0_30_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_30_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_30_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_30_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_30_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_30_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P0_31_MODE_REG ===================================================== */ +#define GPIO_P0_31_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P0_31_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P0_31_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P0_31_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P0_31_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P0_31_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ====================================================== P0_DATA_REG ====================================================== */ +#define GPIO_P0_DATA_REG_P0_DATA_Pos (0UL) /*!< P0_DATA (Bit 0) */ +#define GPIO_P0_DATA_REG_P0_DATA_Msk (0xffffffffUL) /*!< P0_DATA (Bitfield-Mask: 0xffffffff) */ +/* ================================================== P0_PADPWR_CTRL_REG =================================================== */ +#define GPIO_P0_PADPWR_CTRL_REG_P0_OUT_CTRL_Pos (6UL) /*!< P0_OUT_CTRL (Bit 6) */ +#define GPIO_P0_PADPWR_CTRL_REG_P0_OUT_CTRL_Msk (0xffffffc0UL) /*!< P0_OUT_CTRL (Bitfield-Mask: 0x3ffffff) */ +/* =================================================== P0_RESET_DATA_REG =================================================== */ +#define GPIO_P0_RESET_DATA_REG_P0_RESET_Pos (0UL) /*!< P0_RESET (Bit 0) */ +#define GPIO_P0_RESET_DATA_REG_P0_RESET_Msk (0xffffffffUL) /*!< P0_RESET (Bitfield-Mask: 0xffffffff) */ +/* ==================================================== P0_SET_DATA_REG ==================================================== */ +#define GPIO_P0_SET_DATA_REG_P0_SET_Pos (0UL) /*!< P0_SET (Bit 0) */ +#define GPIO_P0_SET_DATA_REG_P0_SET_Msk (0xffffffffUL) /*!< P0_SET (Bitfield-Mask: 0xffffffff) */ +/* ==================================================== P1_00_MODE_REG ===================================================== */ +#define GPIO_P1_00_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_00_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_00_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_00_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_00_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_00_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_01_MODE_REG ===================================================== */ +#define GPIO_P1_01_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_01_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_01_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_01_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_01_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_01_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_02_MODE_REG ===================================================== */ +#define GPIO_P1_02_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_02_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_02_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_02_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_02_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_02_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_03_MODE_REG ===================================================== */ +#define GPIO_P1_03_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_03_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_03_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_03_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_03_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_03_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_04_MODE_REG ===================================================== */ +#define GPIO_P1_04_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_04_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_04_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_04_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_04_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_04_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_05_MODE_REG ===================================================== */ +#define GPIO_P1_05_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_05_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_05_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_05_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_05_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_05_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_06_MODE_REG ===================================================== */ +#define GPIO_P1_06_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_06_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_06_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_06_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_06_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_06_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_07_MODE_REG ===================================================== */ +#define GPIO_P1_07_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_07_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_07_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_07_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_07_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_07_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_08_MODE_REG ===================================================== */ +#define GPIO_P1_08_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_08_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_08_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_08_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_08_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_08_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_09_MODE_REG ===================================================== */ +#define GPIO_P1_09_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_09_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_09_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_09_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_09_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_09_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_10_MODE_REG ===================================================== */ +#define GPIO_P1_10_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_10_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_10_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_10_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_10_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_10_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_11_MODE_REG ===================================================== */ +#define GPIO_P1_11_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_11_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_11_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_11_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_11_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_11_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_12_MODE_REG ===================================================== */ +#define GPIO_P1_12_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_12_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_12_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_12_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_12_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_12_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_13_MODE_REG ===================================================== */ +#define GPIO_P1_13_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_13_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_13_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_13_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_13_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_13_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_14_MODE_REG ===================================================== */ +#define GPIO_P1_14_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_14_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_14_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_14_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_14_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_14_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_15_MODE_REG ===================================================== */ +#define GPIO_P1_15_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_15_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_15_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_15_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_15_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_15_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_16_MODE_REG ===================================================== */ +#define GPIO_P1_16_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_16_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_16_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_16_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_16_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_16_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_17_MODE_REG ===================================================== */ +#define GPIO_P1_17_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_17_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_17_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_17_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_17_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_17_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_18_MODE_REG ===================================================== */ +#define GPIO_P1_18_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_18_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_18_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_18_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_18_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_18_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_19_MODE_REG ===================================================== */ +#define GPIO_P1_19_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_19_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_19_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_19_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_19_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_19_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_20_MODE_REG ===================================================== */ +#define GPIO_P1_20_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_20_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_20_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_20_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_20_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_20_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_21_MODE_REG ===================================================== */ +#define GPIO_P1_21_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_21_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_21_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_21_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_21_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_21_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ==================================================== P1_22_MODE_REG ===================================================== */ +#define GPIO_P1_22_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ +#define GPIO_P1_22_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ +#define GPIO_P1_22_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ +#define GPIO_P1_22_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ +#define GPIO_P1_22_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ +#define GPIO_P1_22_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ +/* ====================================================== P1_DATA_REG ====================================================== */ +#define GPIO_P1_DATA_REG_P1_DATA_Pos (0UL) /*!< P1_DATA (Bit 0) */ +#define GPIO_P1_DATA_REG_P1_DATA_Msk (0x7fffffUL) /*!< P1_DATA (Bitfield-Mask: 0x7fffff) */ +/* ================================================== P1_PADPWR_CTRL_REG =================================================== */ +#define GPIO_P1_PADPWR_CTRL_REG_P1_OUT_CTRL_Pos (0UL) /*!< P1_OUT_CTRL (Bit 0) */ +#define GPIO_P1_PADPWR_CTRL_REG_P1_OUT_CTRL_Msk (0x7fffffUL) /*!< P1_OUT_CTRL (Bitfield-Mask: 0x7fffff) */ +/* =================================================== P1_RESET_DATA_REG =================================================== */ +#define GPIO_P1_RESET_DATA_REG_P1_RESET_Pos (0UL) /*!< P1_RESET (Bit 0) */ +#define GPIO_P1_RESET_DATA_REG_P1_RESET_Msk (0x7fffffUL) /*!< P1_RESET (Bitfield-Mask: 0x7fffff) */ +/* ==================================================== P1_SET_DATA_REG ==================================================== */ +#define GPIO_P1_SET_DATA_REG_P1_SET_Pos (0UL) /*!< P1_SET (Bit 0) */ +#define GPIO_P1_SET_DATA_REG_P1_SET_Msk (0x7fffffUL) /*!< P1_SET (Bitfield-Mask: 0x7fffff) */ +/* =================================================== PAD_WEAK_CTRL_REG =================================================== */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_09_LOWDRV_Pos (12UL) /*!< P1_09_LOWDRV (Bit 12) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_09_LOWDRV_Msk (0x1000UL) /*!< P1_09_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_06_LOWDRV_Pos (11UL) /*!< P1_06_LOWDRV (Bit 11) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_06_LOWDRV_Msk (0x800UL) /*!< P1_06_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_02_LOWDRV_Pos (10UL) /*!< P1_02_LOWDRV (Bit 10) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_02_LOWDRV_Msk (0x400UL) /*!< P1_02_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_01_LOWDRV_Pos (9UL) /*!< P1_01_LOWDRV (Bit 9) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_01_LOWDRV_Msk (0x200UL) /*!< P1_01_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_00_LOWDRV_Pos (8UL) /*!< P1_00_LOWDRV (Bit 8) */ +#define GPIO_PAD_WEAK_CTRL_REG_P1_00_LOWDRV_Msk (0x100UL) /*!< P1_00_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_27_LOWDRV_Pos (7UL) /*!< P0_27_LOWDRV (Bit 7) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_27_LOWDRV_Msk (0x80UL) /*!< P0_27_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_26_LOWDRV_Pos (6UL) /*!< P0_26_LOWDRV (Bit 6) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_26_LOWDRV_Msk (0x40UL) /*!< P0_26_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_25_LOWDRV_Pos (5UL) /*!< P0_25_LOWDRV (Bit 5) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_25_LOWDRV_Msk (0x20UL) /*!< P0_25_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_18_LOWDRV_Pos (4UL) /*!< P0_18_LOWDRV (Bit 4) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_18_LOWDRV_Msk (0x10UL) /*!< P0_18_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_17_LOWDRV_Pos (3UL) /*!< P0_17_LOWDRV (Bit 3) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_17_LOWDRV_Msk (0x8UL) /*!< P0_17_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_16_LOWDRV_Pos (2UL) /*!< P0_16_LOWDRV (Bit 2) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_16_LOWDRV_Msk (0x4UL) /*!< P0_16_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_07_LOWDRV_Pos (1UL) /*!< P0_07_LOWDRV (Bit 1) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_07_LOWDRV_Msk (0x2UL) /*!< P0_07_LOWDRV (Bitfield-Mask: 0x01) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_06_LOWDRV_Pos (0UL) /*!< P0_06_LOWDRV (Bit 0) */ +#define GPIO_PAD_WEAK_CTRL_REG_P0_06_LOWDRV_Msk (0x1UL) /*!< P0_06_LOWDRV (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ GPREG ================ */ +/* =========================================================================================================================== */ + +/* ======================================================= DEBUG_REG ======================================================= */ +#define GPREG_DEBUG_REG_CROSS_CPU_HALT_SENSITIVITY_Pos (8UL) /*!< CROSS_CPU_HALT_SENSITIVITY (Bit 8) */ +#define GPREG_DEBUG_REG_CROSS_CPU_HALT_SENSITIVITY_Msk (0x100UL) /*!< CROSS_CPU_HALT_SENSITIVITY (Bitfield-Mask: 0x01) */ +#define GPREG_DEBUG_REG_SYS_CPUWAIT_ON_JTAG_Pos (7UL) /*!< SYS_CPUWAIT_ON_JTAG (Bit 7) */ +#define GPREG_DEBUG_REG_SYS_CPUWAIT_ON_JTAG_Msk (0x80UL) /*!< SYS_CPUWAIT_ON_JTAG (Bitfield-Mask: 0x01) */ +#define GPREG_DEBUG_REG_SYS_CPUWAIT_Pos (6UL) /*!< SYS_CPUWAIT (Bit 6) */ +#define GPREG_DEBUG_REG_SYS_CPUWAIT_Msk (0x40UL) /*!< SYS_CPUWAIT (Bitfield-Mask: 0x01) */ +#define GPREG_DEBUG_REG_CMAC_CPU_IS_HALTED_Pos (5UL) /*!< CMAC_CPU_IS_HALTED (Bit 5) */ +#define GPREG_DEBUG_REG_CMAC_CPU_IS_HALTED_Msk (0x20UL) /*!< CMAC_CPU_IS_HALTED (Bitfield-Mask: 0x01) */ +#define GPREG_DEBUG_REG_SYS_CPU_IS_HALTED_Pos (4UL) /*!< SYS_CPU_IS_HALTED (Bit 4) */ +#define GPREG_DEBUG_REG_SYS_CPU_IS_HALTED_Msk (0x10UL) /*!< SYS_CPU_IS_HALTED (Bitfield-Mask: 0x01) */ +#define GPREG_DEBUG_REG_HALT_CMAC_SYS_CPU_EN_Pos (3UL) /*!< HALT_CMAC_SYS_CPU_EN (Bit 3) */ +#define GPREG_DEBUG_REG_HALT_CMAC_SYS_CPU_EN_Msk (0x8UL) /*!< HALT_CMAC_SYS_CPU_EN (Bitfield-Mask: 0x01) */ +#define GPREG_DEBUG_REG_HALT_SYS_CMAC_CPU_EN_Pos (2UL) /*!< HALT_SYS_CMAC_CPU_EN (Bit 2) */ +#define GPREG_DEBUG_REG_HALT_SYS_CMAC_CPU_EN_Msk (0x4UL) /*!< HALT_SYS_CMAC_CPU_EN (Bitfield-Mask: 0x01) */ +#define GPREG_DEBUG_REG_CMAC_CPU_FREEZE_EN_Pos (1UL) /*!< CMAC_CPU_FREEZE_EN (Bit 1) */ +#define GPREG_DEBUG_REG_CMAC_CPU_FREEZE_EN_Msk (0x2UL) /*!< CMAC_CPU_FREEZE_EN (Bitfield-Mask: 0x01) */ +#define GPREG_DEBUG_REG_SYS_CPU_FREEZE_EN_Pos (0UL) /*!< SYS_CPU_FREEZE_EN (Bit 0) */ +#define GPREG_DEBUG_REG_SYS_CPU_FREEZE_EN_Msk (0x1UL) /*!< SYS_CPU_FREEZE_EN (Bitfield-Mask: 0x01) */ +/* ==================================================== GP_CONTROL_REG ===================================================== */ +#define GPREG_GP_CONTROL_REG_CMAC_H2H_BRIDGE_BYPASS_Pos (1UL) /*!< CMAC_H2H_BRIDGE_BYPASS (Bit 1) */ +#define GPREG_GP_CONTROL_REG_CMAC_H2H_BRIDGE_BYPASS_Msk (0x2UL) /*!< CMAC_H2H_BRIDGE_BYPASS (Bitfield-Mask: 0x01) */ +/* ===================================================== GP_STATUS_REG ===================================================== */ +#define GPREG_GP_STATUS_REG_CAL_PHASE_Pos (0UL) /*!< CAL_PHASE (Bit 0) */ +#define GPREG_GP_STATUS_REG_CAL_PHASE_Msk (0x1UL) /*!< CAL_PHASE (Bitfield-Mask: 0x01) */ +/* =================================================== RESET_FREEZE_REG ==================================================== */ +#define GPREG_RESET_FREEZE_REG_FRZ_CMAC_WDOG_Pos (10UL) /*!< FRZ_CMAC_WDOG (Bit 10) */ +#define GPREG_RESET_FREEZE_REG_FRZ_CMAC_WDOG_Msk (0x400UL) /*!< FRZ_CMAC_WDOG (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SWTIM4_Pos (9UL) /*!< FRZ_SWTIM4 (Bit 9) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SWTIM4_Msk (0x200UL) /*!< FRZ_SWTIM4 (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SWTIM3_Pos (8UL) /*!< FRZ_SWTIM3 (Bit 8) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SWTIM3_Msk (0x100UL) /*!< FRZ_SWTIM3 (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_PWMLED_Pos (7UL) /*!< FRZ_PWMLED (Bit 7) */ +#define GPREG_RESET_FREEZE_REG_FRZ_PWMLED_Msk (0x80UL) /*!< FRZ_PWMLED (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SWTIM2_Pos (6UL) /*!< FRZ_SWTIM2 (Bit 6) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SWTIM2_Msk (0x40UL) /*!< FRZ_SWTIM2 (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_DMA_Pos (5UL) /*!< FRZ_DMA (Bit 5) */ +#define GPREG_RESET_FREEZE_REG_FRZ_DMA_Msk (0x20UL) /*!< FRZ_DMA (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_USB_Pos (4UL) /*!< FRZ_USB (Bit 4) */ +#define GPREG_RESET_FREEZE_REG_FRZ_USB_Msk (0x10UL) /*!< FRZ_USB (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SYS_WDOG_Pos (3UL) /*!< FRZ_SYS_WDOG (Bit 3) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SYS_WDOG_Msk (0x8UL) /*!< FRZ_SYS_WDOG (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_RESERVED_Pos (2UL) /*!< FRZ_RESERVED (Bit 2) */ +#define GPREG_RESET_FREEZE_REG_FRZ_RESERVED_Msk (0x4UL) /*!< FRZ_RESERVED (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SWTIM_Pos (1UL) /*!< FRZ_SWTIM (Bit 1) */ +#define GPREG_RESET_FREEZE_REG_FRZ_SWTIM_Msk (0x2UL) /*!< FRZ_SWTIM (Bitfield-Mask: 0x01) */ +#define GPREG_RESET_FREEZE_REG_FRZ_WKUPTIM_Pos (0UL) /*!< FRZ_WKUPTIM (Bit 0) */ +#define GPREG_RESET_FREEZE_REG_FRZ_WKUPTIM_Msk (0x1UL) /*!< FRZ_WKUPTIM (Bitfield-Mask: 0x01) */ +/* ==================================================== SET_FREEZE_REG ===================================================== */ +#define GPREG_SET_FREEZE_REG_FRZ_CMAC_WDOG_Pos (10UL) /*!< FRZ_CMAC_WDOG (Bit 10) */ +#define GPREG_SET_FREEZE_REG_FRZ_CMAC_WDOG_Msk (0x400UL) /*!< FRZ_CMAC_WDOG (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_SWTIM4_Pos (9UL) /*!< FRZ_SWTIM4 (Bit 9) */ +#define GPREG_SET_FREEZE_REG_FRZ_SWTIM4_Msk (0x200UL) /*!< FRZ_SWTIM4 (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_SWTIM3_Pos (8UL) /*!< FRZ_SWTIM3 (Bit 8) */ +#define GPREG_SET_FREEZE_REG_FRZ_SWTIM3_Msk (0x100UL) /*!< FRZ_SWTIM3 (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_PWMLED_Pos (7UL) /*!< FRZ_PWMLED (Bit 7) */ +#define GPREG_SET_FREEZE_REG_FRZ_PWMLED_Msk (0x80UL) /*!< FRZ_PWMLED (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_SWTIM2_Pos (6UL) /*!< FRZ_SWTIM2 (Bit 6) */ +#define GPREG_SET_FREEZE_REG_FRZ_SWTIM2_Msk (0x40UL) /*!< FRZ_SWTIM2 (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_DMA_Pos (5UL) /*!< FRZ_DMA (Bit 5) */ +#define GPREG_SET_FREEZE_REG_FRZ_DMA_Msk (0x20UL) /*!< FRZ_DMA (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_USB_Pos (4UL) /*!< FRZ_USB (Bit 4) */ +#define GPREG_SET_FREEZE_REG_FRZ_USB_Msk (0x10UL) /*!< FRZ_USB (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Pos (3UL) /*!< FRZ_SYS_WDOG (Bit 3) */ +#define GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk (0x8UL) /*!< FRZ_SYS_WDOG (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_RESERVED_Pos (2UL) /*!< FRZ_RESERVED (Bit 2) */ +#define GPREG_SET_FREEZE_REG_FRZ_RESERVED_Msk (0x4UL) /*!< FRZ_RESERVED (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_SWTIM_Pos (1UL) /*!< FRZ_SWTIM (Bit 1) */ +#define GPREG_SET_FREEZE_REG_FRZ_SWTIM_Msk (0x2UL) /*!< FRZ_SWTIM (Bitfield-Mask: 0x01) */ +#define GPREG_SET_FREEZE_REG_FRZ_WKUPTIM_Pos (0UL) /*!< FRZ_WKUPTIM (Bit 0) */ +#define GPREG_SET_FREEZE_REG_FRZ_WKUPTIM_Msk (0x1UL) /*!< FRZ_WKUPTIM (Bitfield-Mask: 0x01) */ +/* ====================================================== USBPAD_REG ======================================================= */ +#define GPREG_USBPAD_REG_USBPHY_FORCE_SW2_ON_Pos (2UL) /*!< USBPHY_FORCE_SW2_ON (Bit 2) */ +#define GPREG_USBPAD_REG_USBPHY_FORCE_SW2_ON_Msk (0x4UL) /*!< USBPHY_FORCE_SW2_ON (Bitfield-Mask: 0x01) */ +#define GPREG_USBPAD_REG_USBPHY_FORCE_SW1_OFF_Pos (1UL) /*!< USBPHY_FORCE_SW1_OFF (Bit 1) */ +#define GPREG_USBPAD_REG_USBPHY_FORCE_SW1_OFF_Msk (0x2UL) /*!< USBPHY_FORCE_SW1_OFF (Bitfield-Mask: 0x01) */ +#define GPREG_USBPAD_REG_USBPAD_EN_Pos (0UL) /*!< USBPAD_EN (Bit 0) */ +#define GPREG_USBPAD_REG_USBPAD_EN_Msk (0x1UL) /*!< USBPAD_EN (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ + +/* =============================================== I2C_ACK_GENERAL_CALL_REG ================================================ */ +#define I2C_I2C_ACK_GENERAL_CALL_REG_ACK_GEN_CALL_Pos (0UL) /*!< ACK_GEN_CALL (Bit 0) */ +#define I2C_I2C_ACK_GENERAL_CALL_REG_ACK_GEN_CALL_Msk (0x1UL) /*!< ACK_GEN_CALL (Bitfield-Mask: 0x01) */ +/* ================================================= I2C_CLR_ACTIVITY_REG ================================================== */ +#define I2C_I2C_CLR_ACTIVITY_REG_CLR_ACTIVITY_Pos (0UL) /*!< CLR_ACTIVITY (Bit 0) */ +#define I2C_I2C_CLR_ACTIVITY_REG_CLR_ACTIVITY_Msk (0x1UL) /*!< CLR_ACTIVITY (Bitfield-Mask: 0x01) */ +/* ================================================= I2C_CLR_GEN_CALL_REG ================================================== */ +#define I2C_I2C_CLR_GEN_CALL_REG_CLR_GEN_CALL_Pos (0UL) /*!< CLR_GEN_CALL (Bit 0) */ +#define I2C_I2C_CLR_GEN_CALL_REG_CLR_GEN_CALL_Msk (0x1UL) /*!< CLR_GEN_CALL (Bitfield-Mask: 0x01) */ +/* =================================================== I2C_CLR_INTR_REG ==================================================== */ +#define I2C_I2C_CLR_INTR_REG_CLR_INTR_Pos (0UL) /*!< CLR_INTR (Bit 0) */ +#define I2C_I2C_CLR_INTR_REG_CLR_INTR_Msk (0x1UL) /*!< CLR_INTR (Bitfield-Mask: 0x01) */ +/* ================================================== I2C_CLR_RD_REQ_REG =================================================== */ +#define I2C_I2C_CLR_RD_REQ_REG_CLR_RD_REQ_Pos (0UL) /*!< CLR_RD_REQ (Bit 0) */ +#define I2C_I2C_CLR_RD_REQ_REG_CLR_RD_REQ_Msk (0x1UL) /*!< CLR_RD_REQ (Bitfield-Mask: 0x01) */ +/* ================================================== I2C_CLR_RX_DONE_REG ================================================== */ +#define I2C_I2C_CLR_RX_DONE_REG_CLR_RX_DONE_Pos (0UL) /*!< CLR_RX_DONE (Bit 0) */ +#define I2C_I2C_CLR_RX_DONE_REG_CLR_RX_DONE_Msk (0x1UL) /*!< CLR_RX_DONE (Bitfield-Mask: 0x01) */ +/* ================================================== I2C_CLR_RX_OVER_REG ================================================== */ +#define I2C_I2C_CLR_RX_OVER_REG_CLR_RX_OVER_Pos (0UL) /*!< CLR_RX_OVER (Bit 0) */ +#define I2C_I2C_CLR_RX_OVER_REG_CLR_RX_OVER_Msk (0x1UL) /*!< CLR_RX_OVER (Bitfield-Mask: 0x01) */ +/* ================================================= I2C_CLR_RX_UNDER_REG ================================================== */ +#define I2C_I2C_CLR_RX_UNDER_REG_CLR_RX_UNDER_Pos (0UL) /*!< CLR_RX_UNDER (Bit 0) */ +#define I2C_I2C_CLR_RX_UNDER_REG_CLR_RX_UNDER_Msk (0x1UL) /*!< CLR_RX_UNDER (Bitfield-Mask: 0x01) */ +/* ================================================= I2C_CLR_START_DET_REG ================================================= */ +#define I2C_I2C_CLR_START_DET_REG_CLR_START_DET_Pos (0UL) /*!< CLR_START_DET (Bit 0) */ +#define I2C_I2C_CLR_START_DET_REG_CLR_START_DET_Msk (0x1UL) /*!< CLR_START_DET (Bitfield-Mask: 0x01) */ +/* ================================================= I2C_CLR_STOP_DET_REG ================================================== */ +#define I2C_I2C_CLR_STOP_DET_REG_CLR_STOP_DET_Pos (0UL) /*!< CLR_STOP_DET (Bit 0) */ +#define I2C_I2C_CLR_STOP_DET_REG_CLR_STOP_DET_Msk (0x1UL) /*!< CLR_STOP_DET (Bitfield-Mask: 0x01) */ +/* ================================================== I2C_CLR_TX_ABRT_REG ================================================== */ +#define I2C_I2C_CLR_TX_ABRT_REG_CLR_TX_ABRT_Pos (0UL) /*!< CLR_TX_ABRT (Bit 0) */ +#define I2C_I2C_CLR_TX_ABRT_REG_CLR_TX_ABRT_Msk (0x1UL) /*!< CLR_TX_ABRT (Bitfield-Mask: 0x01) */ +/* ================================================== I2C_CLR_TX_OVER_REG ================================================== */ +#define I2C_I2C_CLR_TX_OVER_REG_CLR_TX_OVER_Pos (0UL) /*!< CLR_TX_OVER (Bit 0) */ +#define I2C_I2C_CLR_TX_OVER_REG_CLR_TX_OVER_Msk (0x1UL) /*!< CLR_TX_OVER (Bitfield-Mask: 0x01) */ +/* ====================================================== I2C_CON_REG ====================================================== */ +#define I2C_I2C_CON_REG_I2C_STOP_DET_IF_MASTER_ACTIVE_Pos (10UL) /*!< I2C_STOP_DET_IF_MASTER_ACTIVE (Bit 10) */ +#define I2C_I2C_CON_REG_I2C_STOP_DET_IF_MASTER_ACTIVE_Msk (0x400UL) /*!< I2C_STOP_DET_IF_MASTER_ACTIVE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_CON_REG_I2C_RX_FIFO_FULL_HLD_CTRL_Pos (9UL) /*!< I2C_RX_FIFO_FULL_HLD_CTRL (Bit 9) */ +#define I2C_I2C_CON_REG_I2C_RX_FIFO_FULL_HLD_CTRL_Msk (0x200UL) /*!< I2C_RX_FIFO_FULL_HLD_CTRL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_CON_REG_I2C_TX_EMPTY_CTRL_Pos (8UL) /*!< I2C_TX_EMPTY_CTRL (Bit 8) */ +#define I2C_I2C_CON_REG_I2C_TX_EMPTY_CTRL_Msk (0x100UL) /*!< I2C_TX_EMPTY_CTRL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_CON_REG_I2C_STOP_DET_IFADDRESSED_Pos (7UL) /*!< I2C_STOP_DET_IFADDRESSED (Bit 7) */ +#define I2C_I2C_CON_REG_I2C_STOP_DET_IFADDRESSED_Msk (0x80UL) /*!< I2C_STOP_DET_IFADDRESSED (Bitfield-Mask: 0x01) */ +#define I2C_I2C_CON_REG_I2C_SLAVE_DISABLE_Pos (6UL) /*!< I2C_SLAVE_DISABLE (Bit 6) */ +#define I2C_I2C_CON_REG_I2C_SLAVE_DISABLE_Msk (0x40UL) /*!< I2C_SLAVE_DISABLE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_CON_REG_I2C_RESTART_EN_Pos (5UL) /*!< I2C_RESTART_EN (Bit 5) */ +#define I2C_I2C_CON_REG_I2C_RESTART_EN_Msk (0x20UL) /*!< I2C_RESTART_EN (Bitfield-Mask: 0x01) */ +#define I2C_I2C_CON_REG_I2C_10BITADDR_MASTER_Pos (4UL) /*!< I2C_10BITADDR_MASTER (Bit 4) */ +#define I2C_I2C_CON_REG_I2C_10BITADDR_MASTER_Msk (0x10UL) /*!< I2C_10BITADDR_MASTER (Bitfield-Mask: 0x01) */ +#define I2C_I2C_CON_REG_I2C_10BITADDR_SLAVE_Pos (3UL) /*!< I2C_10BITADDR_SLAVE (Bit 3) */ +#define I2C_I2C_CON_REG_I2C_10BITADDR_SLAVE_Msk (0x8UL) /*!< I2C_10BITADDR_SLAVE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_CON_REG_I2C_SPEED_Pos (1UL) /*!< I2C_SPEED (Bit 1) */ +#define I2C_I2C_CON_REG_I2C_SPEED_Msk (0x6UL) /*!< I2C_SPEED (Bitfield-Mask: 0x03) */ +#define I2C_I2C_CON_REG_I2C_MASTER_MODE_Pos (0UL) /*!< I2C_MASTER_MODE (Bit 0) */ +#define I2C_I2C_CON_REG_I2C_MASTER_MODE_Msk (0x1UL) /*!< I2C_MASTER_MODE (Bitfield-Mask: 0x01) */ +/* =================================================== I2C_DATA_CMD_REG ==================================================== */ +#define I2C_I2C_DATA_CMD_REG_I2C_RESTART_Pos (10UL) /*!< I2C_RESTART (Bit 10) */ +#define I2C_I2C_DATA_CMD_REG_I2C_RESTART_Msk (0x400UL) /*!< I2C_RESTART (Bitfield-Mask: 0x01) */ +#define I2C_I2C_DATA_CMD_REG_I2C_STOP_Pos (9UL) /*!< I2C_STOP (Bit 9) */ +#define I2C_I2C_DATA_CMD_REG_I2C_STOP_Msk (0x200UL) /*!< I2C_STOP (Bitfield-Mask: 0x01) */ +#define I2C_I2C_DATA_CMD_REG_I2C_CMD_Pos (8UL) /*!< I2C_CMD (Bit 8) */ +#define I2C_I2C_DATA_CMD_REG_I2C_CMD_Msk (0x100UL) /*!< I2C_CMD (Bitfield-Mask: 0x01) */ +#define I2C_I2C_DATA_CMD_REG_I2C_DAT_Pos (0UL) /*!< I2C_DAT (Bit 0) */ +#define I2C_I2C_DATA_CMD_REG_I2C_DAT_Msk (0xffUL) /*!< I2C_DAT (Bitfield-Mask: 0xff) */ +/* ==================================================== I2C_DMA_CR_REG ===================================================== */ +#define I2C_I2C_DMA_CR_REG_TDMAE_Pos (1UL) /*!< TDMAE (Bit 1) */ +#define I2C_I2C_DMA_CR_REG_TDMAE_Msk (0x2UL) /*!< TDMAE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_DMA_CR_REG_RDMAE_Pos (0UL) /*!< RDMAE (Bit 0) */ +#define I2C_I2C_DMA_CR_REG_RDMAE_Msk (0x1UL) /*!< RDMAE (Bitfield-Mask: 0x01) */ +/* =================================================== I2C_DMA_RDLR_REG ==================================================== */ +#define I2C_I2C_DMA_RDLR_REG_DMARDL_Pos (0UL) /*!< DMARDL (Bit 0) */ +#define I2C_I2C_DMA_RDLR_REG_DMARDL_Msk (0x1fUL) /*!< DMARDL (Bitfield-Mask: 0x1f) */ +/* =================================================== I2C_DMA_TDLR_REG ==================================================== */ +#define I2C_I2C_DMA_TDLR_REG_DMATDL_Pos (0UL) /*!< DMATDL (Bit 0) */ +#define I2C_I2C_DMA_TDLR_REG_DMATDL_Msk (0x1fUL) /*!< DMATDL (Bitfield-Mask: 0x1f) */ +/* ==================================================== I2C_ENABLE_REG ===================================================== */ +#define I2C_I2C_ENABLE_REG_I2C_TX_CMD_BLOCK_Pos (2UL) /*!< I2C_TX_CMD_BLOCK (Bit 2) */ +#define I2C_I2C_ENABLE_REG_I2C_TX_CMD_BLOCK_Msk (0x4UL) /*!< I2C_TX_CMD_BLOCK (Bitfield-Mask: 0x01) */ +#define I2C_I2C_ENABLE_REG_I2C_ABORT_Pos (1UL) /*!< I2C_ABORT (Bit 1) */ +#define I2C_I2C_ENABLE_REG_I2C_ABORT_Msk (0x2UL) /*!< I2C_ABORT (Bitfield-Mask: 0x01) */ +#define I2C_I2C_ENABLE_REG_I2C_EN_Pos (0UL) /*!< I2C_EN (Bit 0) */ +#define I2C_I2C_ENABLE_REG_I2C_EN_Msk (0x1UL) /*!< I2C_EN (Bitfield-Mask: 0x01) */ +/* ================================================= I2C_ENABLE_STATUS_REG ================================================= */ +#define I2C_I2C_ENABLE_STATUS_REG_SLV_RX_DATA_LOST_Pos (2UL) /*!< SLV_RX_DATA_LOST (Bit 2) */ +#define I2C_I2C_ENABLE_STATUS_REG_SLV_RX_DATA_LOST_Msk (0x4UL) /*!< SLV_RX_DATA_LOST (Bitfield-Mask: 0x01) */ +#define I2C_I2C_ENABLE_STATUS_REG_SLV_DISABLED_WHILE_BUSY_Pos (1UL) /*!< SLV_DISABLED_WHILE_BUSY (Bit 1) */ +#define I2C_I2C_ENABLE_STATUS_REG_SLV_DISABLED_WHILE_BUSY_Msk (0x2UL) /*!< SLV_DISABLED_WHILE_BUSY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_ENABLE_STATUS_REG_IC_EN_Pos (0UL) /*!< IC_EN (Bit 0) */ +#define I2C_I2C_ENABLE_STATUS_REG_IC_EN_Msk (0x1UL) /*!< IC_EN (Bitfield-Mask: 0x01) */ +/* ================================================== I2C_FS_SCL_HCNT_REG ================================================== */ +#define I2C_I2C_FS_SCL_HCNT_REG_IC_FS_SCL_HCNT_Pos (0UL) /*!< IC_FS_SCL_HCNT (Bit 0) */ +#define I2C_I2C_FS_SCL_HCNT_REG_IC_FS_SCL_HCNT_Msk (0xffffUL) /*!< IC_FS_SCL_HCNT (Bitfield-Mask: 0xffff) */ +/* ================================================== I2C_FS_SCL_LCNT_REG ================================================== */ +#define I2C_I2C_FS_SCL_LCNT_REG_IC_FS_SCL_LCNT_Pos (0UL) /*!< IC_FS_SCL_LCNT (Bit 0) */ +#define I2C_I2C_FS_SCL_LCNT_REG_IC_FS_SCL_LCNT_Msk (0xffffUL) /*!< IC_FS_SCL_LCNT (Bitfield-Mask: 0xffff) */ +/* =================================================== I2C_HS_MADDR_REG ==================================================== */ +#define I2C_I2C_HS_MADDR_REG_I2C_IC_HS_MAR_Pos (0UL) /*!< I2C_IC_HS_MAR (Bit 0) */ +#define I2C_I2C_HS_MADDR_REG_I2C_IC_HS_MAR_Msk (0x7UL) /*!< I2C_IC_HS_MAR (Bitfield-Mask: 0x07) */ +/* ================================================== I2C_HS_SCL_HCNT_REG ================================================== */ +#define I2C_I2C_HS_SCL_HCNT_REG_IC_HS_SCL_HCNT_Pos (0UL) /*!< IC_HS_SCL_HCNT (Bit 0) */ +#define I2C_I2C_HS_SCL_HCNT_REG_IC_HS_SCL_HCNT_Msk (0xffffUL) /*!< IC_HS_SCL_HCNT (Bitfield-Mask: 0xffff) */ +/* ================================================== I2C_HS_SCL_LCNT_REG ================================================== */ +#define I2C_I2C_HS_SCL_LCNT_REG_IC_HS_SCL_LCNT_Pos (0UL) /*!< IC_HS_SCL_LCNT (Bit 0) */ +#define I2C_I2C_HS_SCL_LCNT_REG_IC_HS_SCL_LCNT_Msk (0xffffUL) /*!< IC_HS_SCL_LCNT (Bitfield-Mask: 0xffff) */ +/* ================================================= I2C_IC_FS_SPKLEN_REG ================================================== */ +#define I2C_I2C_IC_FS_SPKLEN_REG_I2C_FS_SPKLEN_Pos (0UL) /*!< I2C_FS_SPKLEN (Bit 0) */ +#define I2C_I2C_IC_FS_SPKLEN_REG_I2C_FS_SPKLEN_Msk (0xffUL) /*!< I2C_FS_SPKLEN (Bitfield-Mask: 0xff) */ +/* ================================================= I2C_IC_HS_SPKLEN_REG ================================================== */ +#define I2C_I2C_IC_HS_SPKLEN_REG_I2C_HS_SPKLEN_Pos (0UL) /*!< I2C_HS_SPKLEN (Bit 0) */ +#define I2C_I2C_IC_HS_SPKLEN_REG_I2C_HS_SPKLEN_Msk (0xffUL) /*!< I2C_HS_SPKLEN (Bitfield-Mask: 0xff) */ +/* =================================================== I2C_INTR_MASK_REG =================================================== */ +#define I2C_I2C_INTR_MASK_REG_M_SCL_STUCK_AT_LOW_Pos (14UL) /*!< M_SCL_STUCK_AT_LOW (Bit 14) */ +#define I2C_I2C_INTR_MASK_REG_M_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< M_SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_MASTER_ON_HOLD_Pos (13UL) /*!< M_MASTER_ON_HOLD (Bit 13) */ +#define I2C_I2C_INTR_MASK_REG_M_MASTER_ON_HOLD_Msk (0x2000UL) /*!< M_MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_RESTART_DET_Pos (12UL) /*!< M_RESTART_DET (Bit 12) */ +#define I2C_I2C_INTR_MASK_REG_M_RESTART_DET_Msk (0x1000UL) /*!< M_RESTART_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_GEN_CALL_Pos (11UL) /*!< M_GEN_CALL (Bit 11) */ +#define I2C_I2C_INTR_MASK_REG_M_GEN_CALL_Msk (0x800UL) /*!< M_GEN_CALL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_START_DET_Pos (10UL) /*!< M_START_DET (Bit 10) */ +#define I2C_I2C_INTR_MASK_REG_M_START_DET_Msk (0x400UL) /*!< M_START_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_STOP_DET_Pos (9UL) /*!< M_STOP_DET (Bit 9) */ +#define I2C_I2C_INTR_MASK_REG_M_STOP_DET_Msk (0x200UL) /*!< M_STOP_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_ACTIVITY_Pos (8UL) /*!< M_ACTIVITY (Bit 8) */ +#define I2C_I2C_INTR_MASK_REG_M_ACTIVITY_Msk (0x100UL) /*!< M_ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_RX_DONE_Pos (7UL) /*!< M_RX_DONE (Bit 7) */ +#define I2C_I2C_INTR_MASK_REG_M_RX_DONE_Msk (0x80UL) /*!< M_RX_DONE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_TX_ABRT_Pos (6UL) /*!< M_TX_ABRT (Bit 6) */ +#define I2C_I2C_INTR_MASK_REG_M_TX_ABRT_Msk (0x40UL) /*!< M_TX_ABRT (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_RD_REQ_Pos (5UL) /*!< M_RD_REQ (Bit 5) */ +#define I2C_I2C_INTR_MASK_REG_M_RD_REQ_Msk (0x20UL) /*!< M_RD_REQ (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_TX_EMPTY_Pos (4UL) /*!< M_TX_EMPTY (Bit 4) */ +#define I2C_I2C_INTR_MASK_REG_M_TX_EMPTY_Msk (0x10UL) /*!< M_TX_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_TX_OVER_Pos (3UL) /*!< M_TX_OVER (Bit 3) */ +#define I2C_I2C_INTR_MASK_REG_M_TX_OVER_Msk (0x8UL) /*!< M_TX_OVER (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_RX_FULL_Pos (2UL) /*!< M_RX_FULL (Bit 2) */ +#define I2C_I2C_INTR_MASK_REG_M_RX_FULL_Msk (0x4UL) /*!< M_RX_FULL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_RX_OVER_Pos (1UL) /*!< M_RX_OVER (Bit 1) */ +#define I2C_I2C_INTR_MASK_REG_M_RX_OVER_Msk (0x2UL) /*!< M_RX_OVER (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_MASK_REG_M_RX_UNDER_Pos (0UL) /*!< M_RX_UNDER (Bit 0) */ +#define I2C_I2C_INTR_MASK_REG_M_RX_UNDER_Msk (0x1UL) /*!< M_RX_UNDER (Bitfield-Mask: 0x01) */ +/* =================================================== I2C_INTR_STAT_REG =================================================== */ +#define I2C_I2C_INTR_STAT_REG_R_SCL_STUCK_AT_LOW_Pos (14UL) /*!< R_SCL_STUCK_AT_LOW (Bit 14) */ +#define I2C_I2C_INTR_STAT_REG_R_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< R_SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_MASTER_ON_HOLD_Pos (13UL) /*!< R_MASTER_ON_HOLD (Bit 13) */ +#define I2C_I2C_INTR_STAT_REG_R_MASTER_ON_HOLD_Msk (0x2000UL) /*!< R_MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_RESTART_DET_Pos (12UL) /*!< R_RESTART_DET (Bit 12) */ +#define I2C_I2C_INTR_STAT_REG_R_RESTART_DET_Msk (0x1000UL) /*!< R_RESTART_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_GEN_CALL_Pos (11UL) /*!< R_GEN_CALL (Bit 11) */ +#define I2C_I2C_INTR_STAT_REG_R_GEN_CALL_Msk (0x800UL) /*!< R_GEN_CALL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_START_DET_Pos (10UL) /*!< R_START_DET (Bit 10) */ +#define I2C_I2C_INTR_STAT_REG_R_START_DET_Msk (0x400UL) /*!< R_START_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_STOP_DET_Pos (9UL) /*!< R_STOP_DET (Bit 9) */ +#define I2C_I2C_INTR_STAT_REG_R_STOP_DET_Msk (0x200UL) /*!< R_STOP_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_ACTIVITY_Pos (8UL) /*!< R_ACTIVITY (Bit 8) */ +#define I2C_I2C_INTR_STAT_REG_R_ACTIVITY_Msk (0x100UL) /*!< R_ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_RX_DONE_Pos (7UL) /*!< R_RX_DONE (Bit 7) */ +#define I2C_I2C_INTR_STAT_REG_R_RX_DONE_Msk (0x80UL) /*!< R_RX_DONE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_TX_ABRT_Pos (6UL) /*!< R_TX_ABRT (Bit 6) */ +#define I2C_I2C_INTR_STAT_REG_R_TX_ABRT_Msk (0x40UL) /*!< R_TX_ABRT (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_RD_REQ_Pos (5UL) /*!< R_RD_REQ (Bit 5) */ +#define I2C_I2C_INTR_STAT_REG_R_RD_REQ_Msk (0x20UL) /*!< R_RD_REQ (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_TX_EMPTY_Pos (4UL) /*!< R_TX_EMPTY (Bit 4) */ +#define I2C_I2C_INTR_STAT_REG_R_TX_EMPTY_Msk (0x10UL) /*!< R_TX_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_TX_OVER_Pos (3UL) /*!< R_TX_OVER (Bit 3) */ +#define I2C_I2C_INTR_STAT_REG_R_TX_OVER_Msk (0x8UL) /*!< R_TX_OVER (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_RX_FULL_Pos (2UL) /*!< R_RX_FULL (Bit 2) */ +#define I2C_I2C_INTR_STAT_REG_R_RX_FULL_Msk (0x4UL) /*!< R_RX_FULL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_RX_OVER_Pos (1UL) /*!< R_RX_OVER (Bit 1) */ +#define I2C_I2C_INTR_STAT_REG_R_RX_OVER_Msk (0x2UL) /*!< R_RX_OVER (Bitfield-Mask: 0x01) */ +#define I2C_I2C_INTR_STAT_REG_R_RX_UNDER_Pos (0UL) /*!< R_RX_UNDER (Bit 0) */ +#define I2C_I2C_INTR_STAT_REG_R_RX_UNDER_Msk (0x1UL) /*!< R_RX_UNDER (Bitfield-Mask: 0x01) */ +/* ================================================= I2C_RAW_INTR_STAT_REG ================================================= */ +#define I2C_I2C_RAW_INTR_STAT_REG_SCL_STUCK_AT_LOW_Pos (14UL) /*!< SCL_STUCK_AT_LOW (Bit 14) */ +#define I2C_I2C_RAW_INTR_STAT_REG_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_MASTER_ON_HOLD_Pos (13UL) /*!< MASTER_ON_HOLD (Bit 13) */ +#define I2C_I2C_RAW_INTR_STAT_REG_MASTER_ON_HOLD_Msk (0x2000UL) /*!< MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RESTART_DET_Pos (12UL) /*!< RESTART_DET (Bit 12) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RESTART_DET_Msk (0x1000UL) /*!< RESTART_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_GEN_CALL_Pos (11UL) /*!< GEN_CALL (Bit 11) */ +#define I2C_I2C_RAW_INTR_STAT_REG_GEN_CALL_Msk (0x800UL) /*!< GEN_CALL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_START_DET_Pos (10UL) /*!< START_DET (Bit 10) */ +#define I2C_I2C_RAW_INTR_STAT_REG_START_DET_Msk (0x400UL) /*!< START_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_STOP_DET_Pos (9UL) /*!< STOP_DET (Bit 9) */ +#define I2C_I2C_RAW_INTR_STAT_REG_STOP_DET_Msk (0x200UL) /*!< STOP_DET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_ACTIVITY_Pos (8UL) /*!< ACTIVITY (Bit 8) */ +#define I2C_I2C_RAW_INTR_STAT_REG_ACTIVITY_Msk (0x100UL) /*!< ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RX_DONE_Pos (7UL) /*!< RX_DONE (Bit 7) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RX_DONE_Msk (0x80UL) /*!< RX_DONE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_TX_ABRT_Pos (6UL) /*!< TX_ABRT (Bit 6) */ +#define I2C_I2C_RAW_INTR_STAT_REG_TX_ABRT_Msk (0x40UL) /*!< TX_ABRT (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RD_REQ_Pos (5UL) /*!< RD_REQ (Bit 5) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RD_REQ_Msk (0x20UL) /*!< RD_REQ (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_TX_EMPTY_Pos (4UL) /*!< TX_EMPTY (Bit 4) */ +#define I2C_I2C_RAW_INTR_STAT_REG_TX_EMPTY_Msk (0x10UL) /*!< TX_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_TX_OVER_Pos (3UL) /*!< TX_OVER (Bit 3) */ +#define I2C_I2C_RAW_INTR_STAT_REG_TX_OVER_Msk (0x8UL) /*!< TX_OVER (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RX_FULL_Pos (2UL) /*!< RX_FULL (Bit 2) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RX_FULL_Msk (0x4UL) /*!< RX_FULL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RX_OVER_Pos (1UL) /*!< RX_OVER (Bit 1) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RX_OVER_Msk (0x2UL) /*!< RX_OVER (Bitfield-Mask: 0x01) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RX_UNDER_Pos (0UL) /*!< RX_UNDER (Bit 0) */ +#define I2C_I2C_RAW_INTR_STAT_REG_RX_UNDER_Msk (0x1UL) /*!< RX_UNDER (Bitfield-Mask: 0x01) */ +/* ===================================================== I2C_RXFLR_REG ===================================================== */ +#define I2C_I2C_RXFLR_REG_RXFLR_Pos (0UL) /*!< RXFLR (Bit 0) */ +#define I2C_I2C_RXFLR_REG_RXFLR_Msk (0x3fUL) /*!< RXFLR (Bitfield-Mask: 0x3f) */ +/* ===================================================== I2C_RX_TL_REG ===================================================== */ +#define I2C_I2C_RX_TL_REG_RX_TL_Pos (0UL) /*!< RX_TL (Bit 0) */ +#define I2C_I2C_RX_TL_REG_RX_TL_Msk (0x1fUL) /*!< RX_TL (Bitfield-Mask: 0x1f) */ +/* ====================================================== I2C_SAR_REG ====================================================== */ +#define I2C_I2C_SAR_REG_IC_SAR_Pos (0UL) /*!< IC_SAR (Bit 0) */ +#define I2C_I2C_SAR_REG_IC_SAR_Msk (0x3ffUL) /*!< IC_SAR (Bitfield-Mask: 0x3ff) */ +/* =================================================== I2C_SDA_HOLD_REG ==================================================== */ +#define I2C_I2C_SDA_HOLD_REG_I2C_SDA_RX_HOLD_Pos (16UL) /*!< I2C_SDA_RX_HOLD (Bit 16) */ +#define I2C_I2C_SDA_HOLD_REG_I2C_SDA_RX_HOLD_Msk (0xff0000UL) /*!< I2C_SDA_RX_HOLD (Bitfield-Mask: 0xff) */ +#define I2C_I2C_SDA_HOLD_REG_I2C_SDA_TX_HOLD_Pos (0UL) /*!< I2C_SDA_TX_HOLD (Bit 0) */ +#define I2C_I2C_SDA_HOLD_REG_I2C_SDA_TX_HOLD_Msk (0xffffUL) /*!< I2C_SDA_TX_HOLD (Bitfield-Mask: 0xffff) */ +/* =================================================== I2C_SDA_SETUP_REG =================================================== */ +#define I2C_I2C_SDA_SETUP_REG_SDA_SETUP_Pos (0UL) /*!< SDA_SETUP (Bit 0) */ +#define I2C_I2C_SDA_SETUP_REG_SDA_SETUP_Msk (0xffUL) /*!< SDA_SETUP (Bitfield-Mask: 0xff) */ +/* ================================================== I2C_SS_SCL_HCNT_REG ================================================== */ +#define I2C_I2C_SS_SCL_HCNT_REG_IC_SS_SCL_HCNT_Pos (0UL) /*!< IC_SS_SCL_HCNT (Bit 0) */ +#define I2C_I2C_SS_SCL_HCNT_REG_IC_SS_SCL_HCNT_Msk (0xffffUL) /*!< IC_SS_SCL_HCNT (Bitfield-Mask: 0xffff) */ +/* ================================================== I2C_SS_SCL_LCNT_REG ================================================== */ +#define I2C_I2C_SS_SCL_LCNT_REG_IC_SS_SCL_LCNT_Pos (0UL) /*!< IC_SS_SCL_LCNT (Bit 0) */ +#define I2C_I2C_SS_SCL_LCNT_REG_IC_SS_SCL_LCNT_Msk (0xffffUL) /*!< IC_SS_SCL_LCNT (Bitfield-Mask: 0xffff) */ +/* ==================================================== I2C_STATUS_REG ===================================================== */ +#define I2C_I2C_STATUS_REG_LV_HOLD_RX_FIFO_FULL_Pos (10UL) /*!< LV_HOLD_RX_FIFO_FULL (Bit 10) */ +#define I2C_I2C_STATUS_REG_LV_HOLD_RX_FIFO_FULL_Msk (0x400UL) /*!< LV_HOLD_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_SLV_HOLD_TX_FIFO_EMPTY_Pos (9UL) /*!< SLV_HOLD_TX_FIFO_EMPTY (Bit 9) */ +#define I2C_I2C_STATUS_REG_SLV_HOLD_TX_FIFO_EMPTY_Msk (0x200UL) /*!< SLV_HOLD_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_MST_HOLD_RX_FIFO_FULL_Pos (8UL) /*!< MST_HOLD_RX_FIFO_FULL (Bit 8) */ +#define I2C_I2C_STATUS_REG_MST_HOLD_RX_FIFO_FULL_Msk (0x100UL) /*!< MST_HOLD_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_MST_HOLD_TX_FIFO_EMPTY_Pos (7UL) /*!< MST_HOLD_TX_FIFO_EMPTY (Bit 7) */ +#define I2C_I2C_STATUS_REG_MST_HOLD_TX_FIFO_EMPTY_Msk (0x80UL) /*!< MST_HOLD_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_SLV_ACTIVITY_Pos (6UL) /*!< SLV_ACTIVITY (Bit 6) */ +#define I2C_I2C_STATUS_REG_SLV_ACTIVITY_Msk (0x40UL) /*!< SLV_ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_MST_ACTIVITY_Pos (5UL) /*!< MST_ACTIVITY (Bit 5) */ +#define I2C_I2C_STATUS_REG_MST_ACTIVITY_Msk (0x20UL) /*!< MST_ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_RFF_Pos (4UL) /*!< RFF (Bit 4) */ +#define I2C_I2C_STATUS_REG_RFF_Msk (0x10UL) /*!< RFF (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_RFNE_Pos (3UL) /*!< RFNE (Bit 3) */ +#define I2C_I2C_STATUS_REG_RFNE_Msk (0x8UL) /*!< RFNE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_TFE_Pos (2UL) /*!< TFE (Bit 2) */ +#define I2C_I2C_STATUS_REG_TFE_Msk (0x4UL) /*!< TFE (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_TFNF_Pos (1UL) /*!< TFNF (Bit 1) */ +#define I2C_I2C_STATUS_REG_TFNF_Msk (0x2UL) /*!< TFNF (Bitfield-Mask: 0x01) */ +#define I2C_I2C_STATUS_REG_I2C_ACTIVITY_Pos (0UL) /*!< I2C_ACTIVITY (Bit 0) */ +#define I2C_I2C_STATUS_REG_I2C_ACTIVITY_Msk (0x1UL) /*!< I2C_ACTIVITY (Bitfield-Mask: 0x01) */ +/* ====================================================== I2C_TAR_REG ====================================================== */ +#define I2C_I2C_TAR_REG_SPECIAL_Pos (11UL) /*!< SPECIAL (Bit 11) */ +#define I2C_I2C_TAR_REG_SPECIAL_Msk (0x800UL) /*!< SPECIAL (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TAR_REG_GC_OR_START_Pos (10UL) /*!< GC_OR_START (Bit 10) */ +#define I2C_I2C_TAR_REG_GC_OR_START_Msk (0x400UL) /*!< GC_OR_START (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TAR_REG_IC_TAR_Pos (0UL) /*!< IC_TAR (Bit 0) */ +#define I2C_I2C_TAR_REG_IC_TAR_Msk (0x3ffUL) /*!< IC_TAR (Bitfield-Mask: 0x3ff) */ +/* ===================================================== I2C_TXFLR_REG ===================================================== */ +#define I2C_I2C_TXFLR_REG_TXFLR_Pos (0UL) /*!< TXFLR (Bit 0) */ +#define I2C_I2C_TXFLR_REG_TXFLR_Msk (0x3fUL) /*!< TXFLR (Bitfield-Mask: 0x3f) */ +/* ================================================ I2C_TX_ABRT_SOURCE_REG ================================================= */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Pos (16UL) /*!< ABRT_USER_ABRT (Bit 16) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Msk (0x10000UL) /*!< ABRT_USER_ABRT (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLVRD_INTX_Pos (15UL) /*!< ABRT_SLVRD_INTX (Bit 15) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLVRD_INTX_Msk (0x8000UL) /*!< ABRT_SLVRD_INTX (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLV_ARBLOST_Pos (14UL) /*!< ABRT_SLV_ARBLOST (Bit 14) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLV_ARBLOST_Msk (0x4000UL) /*!< ABRT_SLV_ARBLOST (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLVFLUSH_TXFIFO_Pos (13UL) /*!< ABRT_SLVFLUSH_TXFIFO (Bit 13) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLVFLUSH_TXFIFO_Msk (0x2000UL) /*!< ABRT_SLVFLUSH_TXFIFO (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ARB_LOST_Pos (12UL) /*!< ARB_LOST (Bit 12) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ARB_LOST_Msk (0x1000UL) /*!< ARB_LOST (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_MASTER_DIS_Pos (11UL) /*!< ABRT_MASTER_DIS (Bit 11) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_MASTER_DIS_Msk (0x800UL) /*!< ABRT_MASTER_DIS (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10B_RD_NORSTRT_Pos (10UL) /*!< ABRT_10B_RD_NORSTRT (Bit 10) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10B_RD_NORSTRT_Msk (0x400UL) /*!< ABRT_10B_RD_NORSTRT (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SBYTE_NORSTRT_Pos (9UL) /*!< ABRT_SBYTE_NORSTRT (Bit 9) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SBYTE_NORSTRT_Msk (0x200UL) /*!< ABRT_SBYTE_NORSTRT (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_HS_NORSTRT_Pos (8UL) /*!< ABRT_HS_NORSTRT (Bit 8) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_HS_NORSTRT_Msk (0x100UL) /*!< ABRT_HS_NORSTRT (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SBYTE_ACKDET_Pos (7UL) /*!< ABRT_SBYTE_ACKDET (Bit 7) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SBYTE_ACKDET_Msk (0x80UL) /*!< ABRT_SBYTE_ACKDET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_HS_ACKDET_Pos (6UL) /*!< ABRT_HS_ACKDET (Bit 6) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_HS_ACKDET_Msk (0x40UL) /*!< ABRT_HS_ACKDET (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_GCALL_READ_Pos (5UL) /*!< ABRT_GCALL_READ (Bit 5) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_GCALL_READ_Msk (0x20UL) /*!< ABRT_GCALL_READ (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_GCALL_NOACK_Pos (4UL) /*!< ABRT_GCALL_NOACK (Bit 4) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_GCALL_NOACK_Msk (0x10UL) /*!< ABRT_GCALL_NOACK (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_TXDATA_NOACK_Pos (3UL) /*!< ABRT_TXDATA_NOACK (Bit 3) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_TXDATA_NOACK_Msk (0x8UL) /*!< ABRT_TXDATA_NOACK (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10ADDR2_NOACK_Pos (2UL) /*!< ABRT_10ADDR2_NOACK (Bit 2) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10ADDR2_NOACK_Msk (0x4UL) /*!< ABRT_10ADDR2_NOACK (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10ADDR1_NOACK_Pos (1UL) /*!< ABRT_10ADDR1_NOACK (Bit 1) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10ADDR1_NOACK_Msk (0x2UL) /*!< ABRT_10ADDR1_NOACK (Bitfield-Mask: 0x01) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_7B_ADDR_NOACK_Pos (0UL) /*!< ABRT_7B_ADDR_NOACK (Bit 0) */ +#define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_7B_ADDR_NOACK_Msk (0x1UL) /*!< ABRT_7B_ADDR_NOACK (Bitfield-Mask: 0x01) */ +/* ===================================================== I2C_TX_TL_REG ===================================================== */ +#define I2C_I2C_TX_TL_REG_TX_TL_Pos (0UL) /*!< TX_TL (Bit 0) */ +#define I2C_I2C_TX_TL_REG_TX_TL_Msk (0x1fUL) /*!< TX_TL (Bitfield-Mask: 0x1f) */ + + +/* =========================================================================================================================== */ +/* ================ I2C2 ================ */ +/* =========================================================================================================================== */ + +/* =============================================== I2C2_ACK_GENERAL_CALL_REG =============================================== */ +#define I2C2_I2C2_ACK_GENERAL_CALL_REG_ACK_GEN_CALL_Pos (0UL) /*!< ACK_GEN_CALL (Bit 0) */ +#define I2C2_I2C2_ACK_GENERAL_CALL_REG_ACK_GEN_CALL_Msk (0x1UL) /*!< ACK_GEN_CALL (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_CLR_ACTIVITY_REG ================================================= */ +#define I2C2_I2C2_CLR_ACTIVITY_REG_CLR_ACTIVITY_Pos (0UL) /*!< CLR_ACTIVITY (Bit 0) */ +#define I2C2_I2C2_CLR_ACTIVITY_REG_CLR_ACTIVITY_Msk (0x1UL) /*!< CLR_ACTIVITY (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_CLR_GEN_CALL_REG ================================================= */ +#define I2C2_I2C2_CLR_GEN_CALL_REG_CLR_GEN_CALL_Pos (0UL) /*!< CLR_GEN_CALL (Bit 0) */ +#define I2C2_I2C2_CLR_GEN_CALL_REG_CLR_GEN_CALL_Msk (0x1UL) /*!< CLR_GEN_CALL (Bitfield-Mask: 0x01) */ +/* =================================================== I2C2_CLR_INTR_REG =================================================== */ +#define I2C2_I2C2_CLR_INTR_REG_CLR_INTR_Pos (0UL) /*!< CLR_INTR (Bit 0) */ +#define I2C2_I2C2_CLR_INTR_REG_CLR_INTR_Msk (0x1UL) /*!< CLR_INTR (Bitfield-Mask: 0x01) */ +/* ================================================== I2C2_CLR_RD_REQ_REG ================================================== */ +#define I2C2_I2C2_CLR_RD_REQ_REG_CLR_RD_REQ_Pos (0UL) /*!< CLR_RD_REQ (Bit 0) */ +#define I2C2_I2C2_CLR_RD_REQ_REG_CLR_RD_REQ_Msk (0x1UL) /*!< CLR_RD_REQ (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_CLR_RX_DONE_REG ================================================== */ +#define I2C2_I2C2_CLR_RX_DONE_REG_CLR_RX_DONE_Pos (0UL) /*!< CLR_RX_DONE (Bit 0) */ +#define I2C2_I2C2_CLR_RX_DONE_REG_CLR_RX_DONE_Msk (0x1UL) /*!< CLR_RX_DONE (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_CLR_RX_OVER_REG ================================================== */ +#define I2C2_I2C2_CLR_RX_OVER_REG_CLR_RX_OVER_Pos (0UL) /*!< CLR_RX_OVER (Bit 0) */ +#define I2C2_I2C2_CLR_RX_OVER_REG_CLR_RX_OVER_Msk (0x1UL) /*!< CLR_RX_OVER (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_CLR_RX_UNDER_REG ================================================= */ +#define I2C2_I2C2_CLR_RX_UNDER_REG_CLR_RX_UNDER_Pos (0UL) /*!< CLR_RX_UNDER (Bit 0) */ +#define I2C2_I2C2_CLR_RX_UNDER_REG_CLR_RX_UNDER_Msk (0x1UL) /*!< CLR_RX_UNDER (Bitfield-Mask: 0x01) */ +/* ================================================ I2C2_CLR_START_DET_REG ================================================= */ +#define I2C2_I2C2_CLR_START_DET_REG_CLR_START_DET_Pos (0UL) /*!< CLR_START_DET (Bit 0) */ +#define I2C2_I2C2_CLR_START_DET_REG_CLR_START_DET_Msk (0x1UL) /*!< CLR_START_DET (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_CLR_STOP_DET_REG ================================================= */ +#define I2C2_I2C2_CLR_STOP_DET_REG_CLR_STOP_DET_Pos (0UL) /*!< CLR_STOP_DET (Bit 0) */ +#define I2C2_I2C2_CLR_STOP_DET_REG_CLR_STOP_DET_Msk (0x1UL) /*!< CLR_STOP_DET (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_CLR_TX_ABRT_REG ================================================== */ +#define I2C2_I2C2_CLR_TX_ABRT_REG_CLR_TX_ABRT_Pos (0UL) /*!< CLR_TX_ABRT (Bit 0) */ +#define I2C2_I2C2_CLR_TX_ABRT_REG_CLR_TX_ABRT_Msk (0x1UL) /*!< CLR_TX_ABRT (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_CLR_TX_OVER_REG ================================================== */ +#define I2C2_I2C2_CLR_TX_OVER_REG_CLR_TX_OVER_Pos (0UL) /*!< CLR_TX_OVER (Bit 0) */ +#define I2C2_I2C2_CLR_TX_OVER_REG_CLR_TX_OVER_Msk (0x1UL) /*!< CLR_TX_OVER (Bitfield-Mask: 0x01) */ +/* ===================================================== I2C2_CON_REG ====================================================== */ +#define I2C2_I2C2_CON_REG_I2C_STOP_DET_IF_MASTER_ACTIVE_Pos (10UL) /*!< I2C_STOP_DET_IF_MASTER_ACTIVE (Bit 10) */ +#define I2C2_I2C2_CON_REG_I2C_STOP_DET_IF_MASTER_ACTIVE_Msk (0x400UL) /*!< I2C_STOP_DET_IF_MASTER_ACTIVE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_CON_REG_I2C_RX_FIFO_FULL_HLD_CTRL_Pos (9UL) /*!< I2C_RX_FIFO_FULL_HLD_CTRL (Bit 9) */ +#define I2C2_I2C2_CON_REG_I2C_RX_FIFO_FULL_HLD_CTRL_Msk (0x200UL) /*!< I2C_RX_FIFO_FULL_HLD_CTRL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_CON_REG_I2C_TX_EMPTY_CTRL_Pos (8UL) /*!< I2C_TX_EMPTY_CTRL (Bit 8) */ +#define I2C2_I2C2_CON_REG_I2C_TX_EMPTY_CTRL_Msk (0x100UL) /*!< I2C_TX_EMPTY_CTRL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_CON_REG_I2C_STOP_DET_IFADDRESSED_Pos (7UL) /*!< I2C_STOP_DET_IFADDRESSED (Bit 7) */ +#define I2C2_I2C2_CON_REG_I2C_STOP_DET_IFADDRESSED_Msk (0x80UL) /*!< I2C_STOP_DET_IFADDRESSED (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_CON_REG_I2C_SLAVE_DISABLE_Pos (6UL) /*!< I2C_SLAVE_DISABLE (Bit 6) */ +#define I2C2_I2C2_CON_REG_I2C_SLAVE_DISABLE_Msk (0x40UL) /*!< I2C_SLAVE_DISABLE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_CON_REG_I2C_RESTART_EN_Pos (5UL) /*!< I2C_RESTART_EN (Bit 5) */ +#define I2C2_I2C2_CON_REG_I2C_RESTART_EN_Msk (0x20UL) /*!< I2C_RESTART_EN (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_CON_REG_I2C_10BITADDR_MASTER_Pos (4UL) /*!< I2C_10BITADDR_MASTER (Bit 4) */ +#define I2C2_I2C2_CON_REG_I2C_10BITADDR_MASTER_Msk (0x10UL) /*!< I2C_10BITADDR_MASTER (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_CON_REG_I2C_10BITADDR_SLAVE_Pos (3UL) /*!< I2C_10BITADDR_SLAVE (Bit 3) */ +#define I2C2_I2C2_CON_REG_I2C_10BITADDR_SLAVE_Msk (0x8UL) /*!< I2C_10BITADDR_SLAVE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_CON_REG_I2C_SPEED_Pos (1UL) /*!< I2C_SPEED (Bit 1) */ +#define I2C2_I2C2_CON_REG_I2C_SPEED_Msk (0x6UL) /*!< I2C_SPEED (Bitfield-Mask: 0x03) */ +#define I2C2_I2C2_CON_REG_I2C_MASTER_MODE_Pos (0UL) /*!< I2C_MASTER_MODE (Bit 0) */ +#define I2C2_I2C2_CON_REG_I2C_MASTER_MODE_Msk (0x1UL) /*!< I2C_MASTER_MODE (Bitfield-Mask: 0x01) */ +/* =================================================== I2C2_DATA_CMD_REG =================================================== */ +#define I2C2_I2C2_DATA_CMD_REG_I2C_RESTART_Pos (10UL) /*!< I2C_RESTART (Bit 10) */ +#define I2C2_I2C2_DATA_CMD_REG_I2C_RESTART_Msk (0x400UL) /*!< I2C_RESTART (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_DATA_CMD_REG_I2C_STOP_Pos (9UL) /*!< I2C_STOP (Bit 9) */ +#define I2C2_I2C2_DATA_CMD_REG_I2C_STOP_Msk (0x200UL) /*!< I2C_STOP (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_DATA_CMD_REG_I2C_CMD_Pos (8UL) /*!< I2C_CMD (Bit 8) */ +#define I2C2_I2C2_DATA_CMD_REG_I2C_CMD_Msk (0x100UL) /*!< I2C_CMD (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_DATA_CMD_REG_I2C_DAT_Pos (0UL) /*!< I2C_DAT (Bit 0) */ +#define I2C2_I2C2_DATA_CMD_REG_I2C_DAT_Msk (0xffUL) /*!< I2C_DAT (Bitfield-Mask: 0xff) */ +/* ==================================================== I2C2_DMA_CR_REG ==================================================== */ +#define I2C2_I2C2_DMA_CR_REG_TDMAE_Pos (1UL) /*!< TDMAE (Bit 1) */ +#define I2C2_I2C2_DMA_CR_REG_TDMAE_Msk (0x2UL) /*!< TDMAE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_DMA_CR_REG_RDMAE_Pos (0UL) /*!< RDMAE (Bit 0) */ +#define I2C2_I2C2_DMA_CR_REG_RDMAE_Msk (0x1UL) /*!< RDMAE (Bitfield-Mask: 0x01) */ +/* =================================================== I2C2_DMA_RDLR_REG =================================================== */ +#define I2C2_I2C2_DMA_RDLR_REG_DMARDL_Pos (0UL) /*!< DMARDL (Bit 0) */ +#define I2C2_I2C2_DMA_RDLR_REG_DMARDL_Msk (0x1fUL) /*!< DMARDL (Bitfield-Mask: 0x1f) */ +/* =================================================== I2C2_DMA_TDLR_REG =================================================== */ +#define I2C2_I2C2_DMA_TDLR_REG_DMATDL_Pos (0UL) /*!< DMATDL (Bit 0) */ +#define I2C2_I2C2_DMA_TDLR_REG_DMATDL_Msk (0x1fUL) /*!< DMATDL (Bitfield-Mask: 0x1f) */ +/* ==================================================== I2C2_ENABLE_REG ==================================================== */ +#define I2C2_I2C2_ENABLE_REG_I2C_TX_CMD_BLOCK_Pos (2UL) /*!< I2C_TX_CMD_BLOCK (Bit 2) */ +#define I2C2_I2C2_ENABLE_REG_I2C_TX_CMD_BLOCK_Msk (0x4UL) /*!< I2C_TX_CMD_BLOCK (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_ENABLE_REG_I2C_ABORT_Pos (1UL) /*!< I2C_ABORT (Bit 1) */ +#define I2C2_I2C2_ENABLE_REG_I2C_ABORT_Msk (0x2UL) /*!< I2C_ABORT (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_ENABLE_REG_I2C_EN_Pos (0UL) /*!< I2C_EN (Bit 0) */ +#define I2C2_I2C2_ENABLE_REG_I2C_EN_Msk (0x1UL) /*!< I2C_EN (Bitfield-Mask: 0x01) */ +/* ================================================ I2C2_ENABLE_STATUS_REG ================================================= */ +#define I2C2_I2C2_ENABLE_STATUS_REG_SLV_RX_DATA_LOST_Pos (2UL) /*!< SLV_RX_DATA_LOST (Bit 2) */ +#define I2C2_I2C2_ENABLE_STATUS_REG_SLV_RX_DATA_LOST_Msk (0x4UL) /*!< SLV_RX_DATA_LOST (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_ENABLE_STATUS_REG_SLV_DISABLED_WHILE_BUSY_Pos (1UL) /*!< SLV_DISABLED_WHILE_BUSY (Bit 1) */ +#define I2C2_I2C2_ENABLE_STATUS_REG_SLV_DISABLED_WHILE_BUSY_Msk (0x2UL) /*!< SLV_DISABLED_WHILE_BUSY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_ENABLE_STATUS_REG_IC_EN_Pos (0UL) /*!< IC_EN (Bit 0) */ +#define I2C2_I2C2_ENABLE_STATUS_REG_IC_EN_Msk (0x1UL) /*!< IC_EN (Bitfield-Mask: 0x01) */ +/* ================================================= I2C2_FS_SCL_HCNT_REG ================================================== */ +#define I2C2_I2C2_FS_SCL_HCNT_REG_IC_FS_SCL_HCNT_Pos (0UL) /*!< IC_FS_SCL_HCNT (Bit 0) */ +#define I2C2_I2C2_FS_SCL_HCNT_REG_IC_FS_SCL_HCNT_Msk (0xffffUL) /*!< IC_FS_SCL_HCNT (Bitfield-Mask: 0xffff) */ +/* ================================================= I2C2_FS_SCL_LCNT_REG ================================================== */ +#define I2C2_I2C2_FS_SCL_LCNT_REG_IC_FS_SCL_LCNT_Pos (0UL) /*!< IC_FS_SCL_LCNT (Bit 0) */ +#define I2C2_I2C2_FS_SCL_LCNT_REG_IC_FS_SCL_LCNT_Msk (0xffffUL) /*!< IC_FS_SCL_LCNT (Bitfield-Mask: 0xffff) */ +/* =================================================== I2C2_HS_MADDR_REG =================================================== */ +#define I2C2_I2C2_HS_MADDR_REG_I2C_IC_HS_MAR_Pos (0UL) /*!< I2C_IC_HS_MAR (Bit 0) */ +#define I2C2_I2C2_HS_MADDR_REG_I2C_IC_HS_MAR_Msk (0x7UL) /*!< I2C_IC_HS_MAR (Bitfield-Mask: 0x07) */ +/* ================================================= I2C2_HS_SCL_HCNT_REG ================================================== */ +#define I2C2_I2C2_HS_SCL_HCNT_REG_IC_HS_SCL_HCNT_Pos (0UL) /*!< IC_HS_SCL_HCNT (Bit 0) */ +#define I2C2_I2C2_HS_SCL_HCNT_REG_IC_HS_SCL_HCNT_Msk (0xffffUL) /*!< IC_HS_SCL_HCNT (Bitfield-Mask: 0xffff) */ +/* ================================================= I2C2_HS_SCL_LCNT_REG ================================================== */ +#define I2C2_I2C2_HS_SCL_LCNT_REG_IC_HS_SCL_LCNT_Pos (0UL) /*!< IC_HS_SCL_LCNT (Bit 0) */ +#define I2C2_I2C2_HS_SCL_LCNT_REG_IC_HS_SCL_LCNT_Msk (0xffffUL) /*!< IC_HS_SCL_LCNT (Bitfield-Mask: 0xffff) */ +/* ================================================= I2C2_IC_FS_SPKLEN_REG ================================================= */ +#define I2C2_I2C2_IC_FS_SPKLEN_REG_I2C_FS_SPKLEN_Pos (0UL) /*!< I2C_FS_SPKLEN (Bit 0) */ +#define I2C2_I2C2_IC_FS_SPKLEN_REG_I2C_FS_SPKLEN_Msk (0xffUL) /*!< I2C_FS_SPKLEN (Bitfield-Mask: 0xff) */ +/* ================================================= I2C2_IC_HS_SPKLEN_REG ================================================= */ +#define I2C2_I2C2_IC_HS_SPKLEN_REG_I2C_HS_SPKLEN_Pos (0UL) /*!< I2C_HS_SPKLEN (Bit 0) */ +#define I2C2_I2C2_IC_HS_SPKLEN_REG_I2C_HS_SPKLEN_Msk (0xffUL) /*!< I2C_HS_SPKLEN (Bitfield-Mask: 0xff) */ +/* ================================================== I2C2_INTR_MASK_REG =================================================== */ +#define I2C2_I2C2_INTR_MASK_REG_M_SCL_STUCK_AT_LOW_Pos (14UL) /*!< M_SCL_STUCK_AT_LOW (Bit 14) */ +#define I2C2_I2C2_INTR_MASK_REG_M_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< M_SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_MASTER_ON_HOLD_Pos (13UL) /*!< M_MASTER_ON_HOLD (Bit 13) */ +#define I2C2_I2C2_INTR_MASK_REG_M_MASTER_ON_HOLD_Msk (0x2000UL) /*!< M_MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RESTART_DET_Pos (12UL) /*!< M_RESTART_DET (Bit 12) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RESTART_DET_Msk (0x1000UL) /*!< M_RESTART_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_GEN_CALL_Pos (11UL) /*!< M_GEN_CALL (Bit 11) */ +#define I2C2_I2C2_INTR_MASK_REG_M_GEN_CALL_Msk (0x800UL) /*!< M_GEN_CALL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_START_DET_Pos (10UL) /*!< M_START_DET (Bit 10) */ +#define I2C2_I2C2_INTR_MASK_REG_M_START_DET_Msk (0x400UL) /*!< M_START_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_STOP_DET_Pos (9UL) /*!< M_STOP_DET (Bit 9) */ +#define I2C2_I2C2_INTR_MASK_REG_M_STOP_DET_Msk (0x200UL) /*!< M_STOP_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_ACTIVITY_Pos (8UL) /*!< M_ACTIVITY (Bit 8) */ +#define I2C2_I2C2_INTR_MASK_REG_M_ACTIVITY_Msk (0x100UL) /*!< M_ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RX_DONE_Pos (7UL) /*!< M_RX_DONE (Bit 7) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RX_DONE_Msk (0x80UL) /*!< M_RX_DONE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_TX_ABRT_Pos (6UL) /*!< M_TX_ABRT (Bit 6) */ +#define I2C2_I2C2_INTR_MASK_REG_M_TX_ABRT_Msk (0x40UL) /*!< M_TX_ABRT (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RD_REQ_Pos (5UL) /*!< M_RD_REQ (Bit 5) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RD_REQ_Msk (0x20UL) /*!< M_RD_REQ (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_TX_EMPTY_Pos (4UL) /*!< M_TX_EMPTY (Bit 4) */ +#define I2C2_I2C2_INTR_MASK_REG_M_TX_EMPTY_Msk (0x10UL) /*!< M_TX_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_TX_OVER_Pos (3UL) /*!< M_TX_OVER (Bit 3) */ +#define I2C2_I2C2_INTR_MASK_REG_M_TX_OVER_Msk (0x8UL) /*!< M_TX_OVER (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RX_FULL_Pos (2UL) /*!< M_RX_FULL (Bit 2) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RX_FULL_Msk (0x4UL) /*!< M_RX_FULL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RX_OVER_Pos (1UL) /*!< M_RX_OVER (Bit 1) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RX_OVER_Msk (0x2UL) /*!< M_RX_OVER (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RX_UNDER_Pos (0UL) /*!< M_RX_UNDER (Bit 0) */ +#define I2C2_I2C2_INTR_MASK_REG_M_RX_UNDER_Msk (0x1UL) /*!< M_RX_UNDER (Bitfield-Mask: 0x01) */ +/* ================================================== I2C2_INTR_STAT_REG =================================================== */ +#define I2C2_I2C2_INTR_STAT_REG_R_SCL_STUCK_AT_LOW_Pos (14UL) /*!< R_SCL_STUCK_AT_LOW (Bit 14) */ +#define I2C2_I2C2_INTR_STAT_REG_R_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< R_SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_MASTER_ON_HOLD_Pos (13UL) /*!< R_MASTER_ON_HOLD (Bit 13) */ +#define I2C2_I2C2_INTR_STAT_REG_R_MASTER_ON_HOLD_Msk (0x2000UL) /*!< R_MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RESTART_DET_Pos (12UL) /*!< R_RESTART_DET (Bit 12) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RESTART_DET_Msk (0x1000UL) /*!< R_RESTART_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_GEN_CALL_Pos (11UL) /*!< R_GEN_CALL (Bit 11) */ +#define I2C2_I2C2_INTR_STAT_REG_R_GEN_CALL_Msk (0x800UL) /*!< R_GEN_CALL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_START_DET_Pos (10UL) /*!< R_START_DET (Bit 10) */ +#define I2C2_I2C2_INTR_STAT_REG_R_START_DET_Msk (0x400UL) /*!< R_START_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_STOP_DET_Pos (9UL) /*!< R_STOP_DET (Bit 9) */ +#define I2C2_I2C2_INTR_STAT_REG_R_STOP_DET_Msk (0x200UL) /*!< R_STOP_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_ACTIVITY_Pos (8UL) /*!< R_ACTIVITY (Bit 8) */ +#define I2C2_I2C2_INTR_STAT_REG_R_ACTIVITY_Msk (0x100UL) /*!< R_ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RX_DONE_Pos (7UL) /*!< R_RX_DONE (Bit 7) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RX_DONE_Msk (0x80UL) /*!< R_RX_DONE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_TX_ABRT_Pos (6UL) /*!< R_TX_ABRT (Bit 6) */ +#define I2C2_I2C2_INTR_STAT_REG_R_TX_ABRT_Msk (0x40UL) /*!< R_TX_ABRT (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RD_REQ_Pos (5UL) /*!< R_RD_REQ (Bit 5) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RD_REQ_Msk (0x20UL) /*!< R_RD_REQ (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_TX_EMPTY_Pos (4UL) /*!< R_TX_EMPTY (Bit 4) */ +#define I2C2_I2C2_INTR_STAT_REG_R_TX_EMPTY_Msk (0x10UL) /*!< R_TX_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_TX_OVER_Pos (3UL) /*!< R_TX_OVER (Bit 3) */ +#define I2C2_I2C2_INTR_STAT_REG_R_TX_OVER_Msk (0x8UL) /*!< R_TX_OVER (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RX_FULL_Pos (2UL) /*!< R_RX_FULL (Bit 2) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RX_FULL_Msk (0x4UL) /*!< R_RX_FULL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RX_OVER_Pos (1UL) /*!< R_RX_OVER (Bit 1) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RX_OVER_Msk (0x2UL) /*!< R_RX_OVER (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RX_UNDER_Pos (0UL) /*!< R_RX_UNDER (Bit 0) */ +#define I2C2_I2C2_INTR_STAT_REG_R_RX_UNDER_Msk (0x1UL) /*!< R_RX_UNDER (Bitfield-Mask: 0x01) */ +/* ================================================ I2C2_RAW_INTR_STAT_REG ================================================= */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_SCL_STUCK_AT_LOW_Pos (14UL) /*!< SCL_STUCK_AT_LOW (Bit 14) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_MASTER_ON_HOLD_Pos (13UL) /*!< MASTER_ON_HOLD (Bit 13) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_MASTER_ON_HOLD_Msk (0x2000UL) /*!< MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RESTART_DET_Pos (12UL) /*!< RESTART_DET (Bit 12) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RESTART_DET_Msk (0x1000UL) /*!< RESTART_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_GEN_CALL_Pos (11UL) /*!< GEN_CALL (Bit 11) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_GEN_CALL_Msk (0x800UL) /*!< GEN_CALL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_START_DET_Pos (10UL) /*!< START_DET (Bit 10) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_START_DET_Msk (0x400UL) /*!< START_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_STOP_DET_Pos (9UL) /*!< STOP_DET (Bit 9) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_STOP_DET_Msk (0x200UL) /*!< STOP_DET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_ACTIVITY_Pos (8UL) /*!< ACTIVITY (Bit 8) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_ACTIVITY_Msk (0x100UL) /*!< ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RX_DONE_Pos (7UL) /*!< RX_DONE (Bit 7) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RX_DONE_Msk (0x80UL) /*!< RX_DONE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_TX_ABRT_Pos (6UL) /*!< TX_ABRT (Bit 6) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_TX_ABRT_Msk (0x40UL) /*!< TX_ABRT (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RD_REQ_Pos (5UL) /*!< RD_REQ (Bit 5) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RD_REQ_Msk (0x20UL) /*!< RD_REQ (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_TX_EMPTY_Pos (4UL) /*!< TX_EMPTY (Bit 4) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_TX_EMPTY_Msk (0x10UL) /*!< TX_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_TX_OVER_Pos (3UL) /*!< TX_OVER (Bit 3) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_TX_OVER_Msk (0x8UL) /*!< TX_OVER (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RX_FULL_Pos (2UL) /*!< RX_FULL (Bit 2) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RX_FULL_Msk (0x4UL) /*!< RX_FULL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RX_OVER_Pos (1UL) /*!< RX_OVER (Bit 1) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RX_OVER_Msk (0x2UL) /*!< RX_OVER (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RX_UNDER_Pos (0UL) /*!< RX_UNDER (Bit 0) */ +#define I2C2_I2C2_RAW_INTR_STAT_REG_RX_UNDER_Msk (0x1UL) /*!< RX_UNDER (Bitfield-Mask: 0x01) */ +/* ==================================================== I2C2_RXFLR_REG ===================================================== */ +#define I2C2_I2C2_RXFLR_REG_RXFLR_Pos (0UL) /*!< RXFLR (Bit 0) */ +#define I2C2_I2C2_RXFLR_REG_RXFLR_Msk (0x3fUL) /*!< RXFLR (Bitfield-Mask: 0x3f) */ +/* ==================================================== I2C2_RX_TL_REG ===================================================== */ +#define I2C2_I2C2_RX_TL_REG_RX_TL_Pos (0UL) /*!< RX_TL (Bit 0) */ +#define I2C2_I2C2_RX_TL_REG_RX_TL_Msk (0x1fUL) /*!< RX_TL (Bitfield-Mask: 0x1f) */ +/* ===================================================== I2C2_SAR_REG ====================================================== */ +#define I2C2_I2C2_SAR_REG_IC_SAR_Pos (0UL) /*!< IC_SAR (Bit 0) */ +#define I2C2_I2C2_SAR_REG_IC_SAR_Msk (0x3ffUL) /*!< IC_SAR (Bitfield-Mask: 0x3ff) */ +/* =================================================== I2C2_SDA_HOLD_REG =================================================== */ +#define I2C2_I2C2_SDA_HOLD_REG_I2C_SDA_RX_HOLD_Pos (16UL) /*!< I2C_SDA_RX_HOLD (Bit 16) */ +#define I2C2_I2C2_SDA_HOLD_REG_I2C_SDA_RX_HOLD_Msk (0xff0000UL) /*!< I2C_SDA_RX_HOLD (Bitfield-Mask: 0xff) */ +#define I2C2_I2C2_SDA_HOLD_REG_I2C_SDA_TX_HOLD_Pos (0UL) /*!< I2C_SDA_TX_HOLD (Bit 0) */ +#define I2C2_I2C2_SDA_HOLD_REG_I2C_SDA_TX_HOLD_Msk (0xffffUL) /*!< I2C_SDA_TX_HOLD (Bitfield-Mask: 0xffff) */ +/* ================================================== I2C2_SDA_SETUP_REG =================================================== */ +#define I2C2_I2C2_SDA_SETUP_REG_SDA_SETUP_Pos (0UL) /*!< SDA_SETUP (Bit 0) */ +#define I2C2_I2C2_SDA_SETUP_REG_SDA_SETUP_Msk (0xffUL) /*!< SDA_SETUP (Bitfield-Mask: 0xff) */ +/* ================================================= I2C2_SS_SCL_HCNT_REG ================================================== */ +#define I2C2_I2C2_SS_SCL_HCNT_REG_IC_SS_SCL_HCNT_Pos (0UL) /*!< IC_SS_SCL_HCNT (Bit 0) */ +#define I2C2_I2C2_SS_SCL_HCNT_REG_IC_SS_SCL_HCNT_Msk (0xffffUL) /*!< IC_SS_SCL_HCNT (Bitfield-Mask: 0xffff) */ +/* ================================================= I2C2_SS_SCL_LCNT_REG ================================================== */ +#define I2C2_I2C2_SS_SCL_LCNT_REG_IC_SS_SCL_LCNT_Pos (0UL) /*!< IC_SS_SCL_LCNT (Bit 0) */ +#define I2C2_I2C2_SS_SCL_LCNT_REG_IC_SS_SCL_LCNT_Msk (0xffffUL) /*!< IC_SS_SCL_LCNT (Bitfield-Mask: 0xffff) */ +/* ==================================================== I2C2_STATUS_REG ==================================================== */ +#define I2C2_I2C2_STATUS_REG_LV_HOLD_RX_FIFO_FULL_Pos (10UL) /*!< LV_HOLD_RX_FIFO_FULL (Bit 10) */ +#define I2C2_I2C2_STATUS_REG_LV_HOLD_RX_FIFO_FULL_Msk (0x400UL) /*!< LV_HOLD_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_SLV_HOLD_TX_FIFO_EMPTY_Pos (9UL) /*!< SLV_HOLD_TX_FIFO_EMPTY (Bit 9) */ +#define I2C2_I2C2_STATUS_REG_SLV_HOLD_TX_FIFO_EMPTY_Msk (0x200UL) /*!< SLV_HOLD_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_MST_HOLD_RX_FIFO_FULL_Pos (8UL) /*!< MST_HOLD_RX_FIFO_FULL (Bit 8) */ +#define I2C2_I2C2_STATUS_REG_MST_HOLD_RX_FIFO_FULL_Msk (0x100UL) /*!< MST_HOLD_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_MST_HOLD_TX_FIFO_EMPTY_Pos (7UL) /*!< MST_HOLD_TX_FIFO_EMPTY (Bit 7) */ +#define I2C2_I2C2_STATUS_REG_MST_HOLD_TX_FIFO_EMPTY_Msk (0x80UL) /*!< MST_HOLD_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_SLV_ACTIVITY_Pos (6UL) /*!< SLV_ACTIVITY (Bit 6) */ +#define I2C2_I2C2_STATUS_REG_SLV_ACTIVITY_Msk (0x40UL) /*!< SLV_ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_MST_ACTIVITY_Pos (5UL) /*!< MST_ACTIVITY (Bit 5) */ +#define I2C2_I2C2_STATUS_REG_MST_ACTIVITY_Msk (0x20UL) /*!< MST_ACTIVITY (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_RFF_Pos (4UL) /*!< RFF (Bit 4) */ +#define I2C2_I2C2_STATUS_REG_RFF_Msk (0x10UL) /*!< RFF (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_RFNE_Pos (3UL) /*!< RFNE (Bit 3) */ +#define I2C2_I2C2_STATUS_REG_RFNE_Msk (0x8UL) /*!< RFNE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_TFE_Pos (2UL) /*!< TFE (Bit 2) */ +#define I2C2_I2C2_STATUS_REG_TFE_Msk (0x4UL) /*!< TFE (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_TFNF_Pos (1UL) /*!< TFNF (Bit 1) */ +#define I2C2_I2C2_STATUS_REG_TFNF_Msk (0x2UL) /*!< TFNF (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_STATUS_REG_I2C_ACTIVITY_Pos (0UL) /*!< I2C_ACTIVITY (Bit 0) */ +#define I2C2_I2C2_STATUS_REG_I2C_ACTIVITY_Msk (0x1UL) /*!< I2C_ACTIVITY (Bitfield-Mask: 0x01) */ +/* ===================================================== I2C2_TAR_REG ====================================================== */ +#define I2C2_I2C2_TAR_REG_SPECIAL_Pos (11UL) /*!< SPECIAL (Bit 11) */ +#define I2C2_I2C2_TAR_REG_SPECIAL_Msk (0x800UL) /*!< SPECIAL (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TAR_REG_GC_OR_START_Pos (10UL) /*!< GC_OR_START (Bit 10) */ +#define I2C2_I2C2_TAR_REG_GC_OR_START_Msk (0x400UL) /*!< GC_OR_START (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TAR_REG_IC_TAR_Pos (0UL) /*!< IC_TAR (Bit 0) */ +#define I2C2_I2C2_TAR_REG_IC_TAR_Msk (0x3ffUL) /*!< IC_TAR (Bitfield-Mask: 0x3ff) */ +/* ==================================================== I2C2_TXFLR_REG ===================================================== */ +#define I2C2_I2C2_TXFLR_REG_TXFLR_Pos (0UL) /*!< TXFLR (Bit 0) */ +#define I2C2_I2C2_TXFLR_REG_TXFLR_Msk (0x3fUL) /*!< TXFLR (Bitfield-Mask: 0x3f) */ +/* ================================================ I2C2_TX_ABRT_SOURCE_REG ================================================ */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Pos (16UL) /*!< ABRT_USER_ABRT (Bit 16) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Msk (0x10000UL) /*!< ABRT_USER_ABRT (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLVRD_INTX_Pos (15UL) /*!< ABRT_SLVRD_INTX (Bit 15) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLVRD_INTX_Msk (0x8000UL) /*!< ABRT_SLVRD_INTX (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLV_ARBLOST_Pos (14UL) /*!< ABRT_SLV_ARBLOST (Bit 14) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLV_ARBLOST_Msk (0x4000UL) /*!< ABRT_SLV_ARBLOST (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLVFLUSH_TXFIFO_Pos (13UL) /*!< ABRT_SLVFLUSH_TXFIFO (Bit 13) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLVFLUSH_TXFIFO_Msk (0x2000UL) /*!< ABRT_SLVFLUSH_TXFIFO (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ARB_LOST_Pos (12UL) /*!< ARB_LOST (Bit 12) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ARB_LOST_Msk (0x1000UL) /*!< ARB_LOST (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_MASTER_DIS_Pos (11UL) /*!< ABRT_MASTER_DIS (Bit 11) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_MASTER_DIS_Msk (0x800UL) /*!< ABRT_MASTER_DIS (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10B_RD_NORSTRT_Pos (10UL) /*!< ABRT_10B_RD_NORSTRT (Bit 10) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10B_RD_NORSTRT_Msk (0x400UL) /*!< ABRT_10B_RD_NORSTRT (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SBYTE_NORSTRT_Pos (9UL) /*!< ABRT_SBYTE_NORSTRT (Bit 9) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SBYTE_NORSTRT_Msk (0x200UL) /*!< ABRT_SBYTE_NORSTRT (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_HS_NORSTRT_Pos (8UL) /*!< ABRT_HS_NORSTRT (Bit 8) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_HS_NORSTRT_Msk (0x100UL) /*!< ABRT_HS_NORSTRT (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SBYTE_ACKDET_Pos (7UL) /*!< ABRT_SBYTE_ACKDET (Bit 7) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SBYTE_ACKDET_Msk (0x80UL) /*!< ABRT_SBYTE_ACKDET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_HS_ACKDET_Pos (6UL) /*!< ABRT_HS_ACKDET (Bit 6) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_HS_ACKDET_Msk (0x40UL) /*!< ABRT_HS_ACKDET (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_GCALL_READ_Pos (5UL) /*!< ABRT_GCALL_READ (Bit 5) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_GCALL_READ_Msk (0x20UL) /*!< ABRT_GCALL_READ (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_GCALL_NOACK_Pos (4UL) /*!< ABRT_GCALL_NOACK (Bit 4) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_GCALL_NOACK_Msk (0x10UL) /*!< ABRT_GCALL_NOACK (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_TXDATA_NOACK_Pos (3UL) /*!< ABRT_TXDATA_NOACK (Bit 3) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_TXDATA_NOACK_Msk (0x8UL) /*!< ABRT_TXDATA_NOACK (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10ADDR2_NOACK_Pos (2UL) /*!< ABRT_10ADDR2_NOACK (Bit 2) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10ADDR2_NOACK_Msk (0x4UL) /*!< ABRT_10ADDR2_NOACK (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10ADDR1_NOACK_Pos (1UL) /*!< ABRT_10ADDR1_NOACK (Bit 1) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10ADDR1_NOACK_Msk (0x2UL) /*!< ABRT_10ADDR1_NOACK (Bitfield-Mask: 0x01) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_7B_ADDR_NOACK_Pos (0UL) /*!< ABRT_7B_ADDR_NOACK (Bit 0) */ +#define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_7B_ADDR_NOACK_Msk (0x1UL) /*!< ABRT_7B_ADDR_NOACK (Bitfield-Mask: 0x01) */ +/* ==================================================== I2C2_TX_TL_REG ===================================================== */ +#define I2C2_I2C2_TX_TL_REG_TX_TL_Pos (0UL) /*!< TX_TL (Bit 0) */ +#define I2C2_I2C2_TX_TL_REG_TX_TL_Msk (0x1fUL) /*!< TX_TL (Bitfield-Mask: 0x1f) */ + + +/* =========================================================================================================================== */ +/* ================ LCDC ================ */ +/* =========================================================================================================================== */ + +/* ================================================= LCDC_BACKPORCHXY_REG ================================================== */ +#define LCDC_LCDC_BACKPORCHXY_REG_LCDC_BPORCH_X_Pos (16UL) /*!< LCDC_BPORCH_X (Bit 16) */ +#define LCDC_LCDC_BACKPORCHXY_REG_LCDC_BPORCH_X_Msk (0xffff0000UL) /*!< LCDC_BPORCH_X (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_BACKPORCHXY_REG_LCDC_BPORCH_Y_Pos (0UL) /*!< LCDC_BPORCH_Y (Bit 0) */ +#define LCDC_LCDC_BACKPORCHXY_REG_LCDC_BPORCH_Y_Msk (0xffffUL) /*!< LCDC_BPORCH_Y (Bitfield-Mask: 0xffff) */ +/* =================================================== LCDC_BGCOLOR_REG ==================================================== */ +#define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_RED_Pos (24UL) /*!< LCDC_BG_RED (Bit 24) */ +#define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_RED_Msk (0xff000000UL) /*!< LCDC_BG_RED (Bitfield-Mask: 0xff) */ +#define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_GREEN_Pos (16UL) /*!< LCDC_BG_GREEN (Bit 16) */ +#define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_GREEN_Msk (0xff0000UL) /*!< LCDC_BG_GREEN (Bitfield-Mask: 0xff) */ +#define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_BLUE_Pos (8UL) /*!< LCDC_BG_BLUE (Bit 8) */ +#define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_BLUE_Msk (0xff00UL) /*!< LCDC_BG_BLUE (Bitfield-Mask: 0xff) */ +#define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_ALPHA_Pos (0UL) /*!< LCDC_BG_ALPHA (Bit 0) */ +#define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_ALPHA_Msk (0xffUL) /*!< LCDC_BG_ALPHA (Bitfield-Mask: 0xff) */ +/* ================================================== LCDC_BLANKINGXY_REG ================================================== */ +#define LCDC_LCDC_BLANKINGXY_REG_LCDC_BLANKING_X_Pos (16UL) /*!< LCDC_BLANKING_X (Bit 16) */ +#define LCDC_LCDC_BLANKINGXY_REG_LCDC_BLANKING_X_Msk (0xffff0000UL) /*!< LCDC_BLANKING_X (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_BLANKINGXY_REG_LCDC_BLANKING_Y_Pos (0UL) /*!< LCDC_BLANKING_Y (Bit 0) */ +#define LCDC_LCDC_BLANKINGXY_REG_LCDC_BLANKING_Y_Msk (0xffffUL) /*!< LCDC_BLANKING_Y (Bitfield-Mask: 0xffff) */ +/* =================================================== LCDC_CLKCTRL_REG ==================================================== */ +#define LCDC_LCDC_CLKCTRL_REG_LCDC_SEC_CLK_DIV_Pos (27UL) /*!< LCDC_SEC_CLK_DIV (Bit 27) */ +#define LCDC_LCDC_CLKCTRL_REG_LCDC_SEC_CLK_DIV_Msk (0xf8000000UL) /*!< LCDC_SEC_CLK_DIV (Bitfield-Mask: 0x1f) */ +#define LCDC_LCDC_CLKCTRL_REG_LCDC_DMA_HOLD_Pos (8UL) /*!< LCDC_DMA_HOLD (Bit 8) */ +#define LCDC_LCDC_CLKCTRL_REG_LCDC_DMA_HOLD_Msk (0x3f00UL) /*!< LCDC_DMA_HOLD (Bitfield-Mask: 0x3f) */ +#define LCDC_LCDC_CLKCTRL_REG_LCDC_CLK_DIV_Pos (0UL) /*!< LCDC_CLK_DIV (Bit 0) */ +#define LCDC_LCDC_CLKCTRL_REG_LCDC_CLK_DIV_Msk (0x3fUL) /*!< LCDC_CLK_DIV (Bitfield-Mask: 0x3f) */ +/* ===================================================== LCDC_CRC_REG ====================================================== */ +#define LCDC_LCDC_CRC_REG_LCDC_CRC_Pos (0UL) /*!< LCDC_CRC (Bit 0) */ +#define LCDC_LCDC_CRC_REG_LCDC_CRC_Msk (0xffffffffUL) /*!< LCDC_CRC (Bitfield-Mask: 0xffffffff) */ +/* =================================================== LCDC_DBIB_CFG_REG =================================================== */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_TE_DIS_Pos (31UL) /*!< LCDC_DBIB_TE_DIS (Bit 31) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_TE_DIS_Msk (0x80000000UL) /*!< LCDC_DBIB_TE_DIS (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_CSX_FORCE_Pos (30UL) /*!< LCDC_DBIB_CSX_FORCE (Bit 30) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_CSX_FORCE_Msk (0x40000000UL) /*!< LCDC_DBIB_CSX_FORCE (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_CSX_FORCE_VAL_Pos (29UL) /*!< LCDC_DBIB_CSX_FORCE_VAL (Bit 29) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_CSX_FORCE_VAL_Msk (0x20000000UL) /*!< LCDC_DBIB_CSX_FORCE_VAL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_PAD_Pos (28UL) /*!< LCDC_DBIB_SPI_PAD (Bit 28) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_PAD_Msk (0x10000000UL) /*!< LCDC_DBIB_SPI_PAD (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_RESX_Pos (25UL) /*!< LCDC_DBIB_RESX (Bit 25) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_RESX_Msk (0x2000000UL) /*!< LCDC_DBIB_RESX (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_DMA_EN_Pos (24UL) /*!< LCDC_DBIB_DMA_EN (Bit 24) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_DMA_EN_Msk (0x1000000UL) /*!< LCDC_DBIB_DMA_EN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI3_EN_Pos (23UL) /*!< LCDC_DBIB_SPI3_EN (Bit 23) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI3_EN_Msk (0x800000UL) /*!< LCDC_DBIB_SPI3_EN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI4_EN_Pos (22UL) /*!< LCDC_DBIB_SPI4_EN (Bit 22) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI4_EN_Msk (0x400000UL) /*!< LCDC_DBIB_SPI4_EN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_CPHA_Pos (20UL) /*!< LCDC_DBIB_SPI_CPHA (Bit 20) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_CPHA_Msk (0x100000UL) /*!< LCDC_DBIB_SPI_CPHA (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_CPOL_Pos (19UL) /*!< LCDC_DBIB_SPI_CPOL (Bit 19) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_CPOL_Msk (0x80000UL) /*!< LCDC_DBIB_SPI_CPOL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_JDI_Pos (18UL) /*!< LCDC_DBIB_SPI_JDI (Bit 18) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_JDI_Msk (0x40000UL) /*!< LCDC_DBIB_SPI_JDI (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_HOLD_Pos (17UL) /*!< LCDC_DBIB_SPI_HOLD (Bit 17) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_HOLD_Msk (0x20000UL) /*!< LCDC_DBIB_SPI_HOLD (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_INV_ADDR_Pos (16UL) /*!< LCDC_DBIB_SPI_INV_ADDR (Bit 16) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_INV_ADDR_Msk (0x10000UL) /*!< LCDC_DBIB_SPI_INV_ADDR (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_INV_DATA_Pos (15UL) /*!< LCDC_DBIB_INV_DATA (Bit 15) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_INV_DATA_Msk (0x8000UL) /*!< LCDC_DBIB_INV_DATA (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_JDI_INV_PIX_Pos (14UL) /*!< LCDC_DBIB_JDI_INV_PIX (Bit 14) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_JDI_INV_PIX_Msk (0x4000UL) /*!< LCDC_DBIB_JDI_INV_PIX (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_JDI_SOFT_RST_Pos (13UL) /*!< LCDC_DBIB_JDI_SOFT_RST (Bit 13) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_JDI_SOFT_RST_Msk (0x2000UL) /*!< LCDC_DBIB_JDI_SOFT_RST (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_FMT_Pos (0UL) /*!< LCDC_DBIB_FMT (Bit 0) */ +#define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_FMT_Msk (0x1fUL) /*!< LCDC_DBIB_FMT (Bitfield-Mask: 0x1f) */ +/* =================================================== LCDC_DBIB_CMD_REG =================================================== */ +#define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_SEND_Pos (30UL) /*!< LCDC_DBIB_CMD_SEND (Bit 30) */ +#define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_SEND_Msk (0x40000000UL) /*!< LCDC_DBIB_CMD_SEND (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_STORE_Pos (27UL) /*!< LCDC_DBIB_CMD_STORE (Bit 27) */ +#define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_STORE_Msk (0x8000000UL) /*!< LCDC_DBIB_CMD_STORE (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_VAL_Pos (0UL) /*!< LCDC_DBIB_CMD_VAL (Bit 0) */ +#define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_VAL_Msk (0xffffUL) /*!< LCDC_DBIB_CMD_VAL (Bitfield-Mask: 0xffff) */ +/* ================================================= LCDC_FRONTPORCHXY_REG ================================================= */ +#define LCDC_LCDC_FRONTPORCHXY_REG_LCDC_FPORCH_X_Pos (16UL) /*!< LCDC_FPORCH_X (Bit 16) */ +#define LCDC_LCDC_FRONTPORCHXY_REG_LCDC_FPORCH_X_Msk (0xffff0000UL) /*!< LCDC_FPORCH_X (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_FRONTPORCHXY_REG_LCDC_FPORCH_Y_Pos (0UL) /*!< LCDC_FPORCH_Y (Bit 0) */ +#define LCDC_LCDC_FRONTPORCHXY_REG_LCDC_FPORCH_Y_Msk (0xffffUL) /*!< LCDC_FPORCH_Y (Bitfield-Mask: 0xffff) */ +/* ===================================================== LCDC_GPIO_REG ===================================================== */ +#define LCDC_LCDC_GPIO_REG_LCDC_TE_INV_Pos (1UL) /*!< LCDC_TE_INV (Bit 1) */ +#define LCDC_LCDC_GPIO_REG_LCDC_TE_INV_Msk (0x2UL) /*!< LCDC_TE_INV (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_GPIO_REG_LCDC_PARIF_SEL_Pos (0UL) /*!< LCDC_PARIF_SEL (Bit 0) */ +#define LCDC_LCDC_GPIO_REG_LCDC_PARIF_SEL_Msk (0x1UL) /*!< LCDC_PARIF_SEL (Bitfield-Mask: 0x01) */ +/* ==================================================== LCDC_IDREG_REG ===================================================== */ +#define LCDC_LCDC_IDREG_REG_LCDC_ID_Pos (0UL) /*!< LCDC_ID (Bit 0) */ +#define LCDC_LCDC_IDREG_REG_LCDC_ID_Msk (0xffffffffUL) /*!< LCDC_ID (Bitfield-Mask: 0xffffffff) */ +/* ================================================== LCDC_INTERRUPT_REG =================================================== */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_IRQ_TRIGGER_SEL_Pos (31UL) /*!< LCDC_IRQ_TRIGGER_SEL (Bit 31) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_IRQ_TRIGGER_SEL_Msk (0x80000000UL) /*!< LCDC_IRQ_TRIGGER_SEL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_FRAME_END_IRQ_EN_Pos (5UL) /*!< LCDC_FRAME_END_IRQ_EN (Bit 5) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_FRAME_END_IRQ_EN_Msk (0x20UL) /*!< LCDC_FRAME_END_IRQ_EN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_TE_IRQ_EN_Pos (3UL) /*!< LCDC_TE_IRQ_EN (Bit 3) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_TE_IRQ_EN_Msk (0x8UL) /*!< LCDC_TE_IRQ_EN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_HSYNC_IRQ_EN_Pos (1UL) /*!< LCDC_HSYNC_IRQ_EN (Bit 1) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_HSYNC_IRQ_EN_Msk (0x2UL) /*!< LCDC_HSYNC_IRQ_EN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_VSYNC_IRQ_EN_Pos (0UL) /*!< LCDC_VSYNC_IRQ_EN (Bit 0) */ +#define LCDC_LCDC_INTERRUPT_REG_LCDC_VSYNC_IRQ_EN_Msk (0x1UL) /*!< LCDC_VSYNC_IRQ_EN (Bitfield-Mask: 0x01) */ +/* ============================================== LCDC_JDI_ENB_END_HLINE_REG =============================================== */ +#define LCDC_LCDC_JDI_ENB_END_HLINE_REG_LCDC_JDI_ENB_END_HLINE_Pos (0UL) /*!< LCDC_JDI_ENB_END_HLINE (Bit 0) */ +#define LCDC_LCDC_JDI_ENB_END_HLINE_REG_LCDC_JDI_ENB_END_HLINE_Msk (0xffffffffUL) /*!< LCDC_JDI_ENB_END_HLINE (Bitfield-Mask: 0xffffffff) */ +/* ============================================== LCDC_JDI_ENB_START_CLK_REG =============================================== */ +#define LCDC_LCDC_JDI_ENB_START_CLK_REG_LCDC_JDI_ENB_START_CLK_Pos (0UL) /*!< LCDC_JDI_ENB_START_CLK (Bit 0) */ +#define LCDC_LCDC_JDI_ENB_START_CLK_REG_LCDC_JDI_ENB_START_CLK_Msk (0xffffffffUL) /*!< LCDC_JDI_ENB_START_CLK (Bitfield-Mask: 0xffffffff) */ +/* ============================================= LCDC_JDI_ENB_START_HLINE_REG ============================================== */ +#define LCDC_LCDC_JDI_ENB_START_HLINE_REG_LCDC_JDI_ENB_START_HLINE_Pos (0UL) /*!< LCDC_JDI_ENB_START_HLINE (Bit 0) */ +#define LCDC_LCDC_JDI_ENB_START_HLINE_REG_LCDC_JDI_ENB_START_HLINE_Msk (0xffffffffUL) /*!< LCDC_JDI_ENB_START_HLINE (Bitfield-Mask: 0xffffffff) */ +/* ============================================== LCDC_JDI_ENB_WIDTH_CLK_REG =============================================== */ +#define LCDC_LCDC_JDI_ENB_WIDTH_CLK_REG_LCDC_JDI_ENB_WIDTH_CLK_Pos (0UL) /*!< LCDC_JDI_ENB_WIDTH_CLK (Bit 0) */ +#define LCDC_LCDC_JDI_ENB_WIDTH_CLK_REG_LCDC_JDI_ENB_WIDTH_CLK_Msk (0xffffffffUL) /*!< LCDC_JDI_ENB_WIDTH_CLK (Bitfield-Mask: 0xffffffff) */ +/* =============================================== LCDC_JDI_FBX_BLANKING_REG =============================================== */ +#define LCDC_LCDC_JDI_FBX_BLANKING_REG_LCDC_JDI_FXBLANKING_Pos (16UL) /*!< LCDC_JDI_FXBLANKING (Bit 16) */ +#define LCDC_LCDC_JDI_FBX_BLANKING_REG_LCDC_JDI_FXBLANKING_Msk (0xffff0000UL) /*!< LCDC_JDI_FXBLANKING (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_JDI_FBX_BLANKING_REG_LCDC_JDI_BXBLANKING_Pos (0UL) /*!< LCDC_JDI_BXBLANKING (Bit 0) */ +#define LCDC_LCDC_JDI_FBX_BLANKING_REG_LCDC_JDI_BXBLANKING_Msk (0xffffUL) /*!< LCDC_JDI_BXBLANKING (Bitfield-Mask: 0xffff) */ +/* =============================================== LCDC_JDI_FBY_BLANKING_REG =============================================== */ +#define LCDC_LCDC_JDI_FBY_BLANKING_REG_LCDC_JDI_FYBLANKING_Pos (16UL) /*!< LCDC_JDI_FYBLANKING (Bit 16) */ +#define LCDC_LCDC_JDI_FBY_BLANKING_REG_LCDC_JDI_FYBLANKING_Msk (0xffff0000UL) /*!< LCDC_JDI_FYBLANKING (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_JDI_FBY_BLANKING_REG_LCDC_JDI_BYBLANKING_Pos (0UL) /*!< LCDC_JDI_BYBLANKING (Bit 0) */ +#define LCDC_LCDC_JDI_FBY_BLANKING_REG_LCDC_JDI_BYBLANKING_Msk (0xffffUL) /*!< LCDC_JDI_BYBLANKING (Bitfield-Mask: 0xffff) */ +/* ================================================ LCDC_JDI_HCK_WIDTH_REG ================================================= */ +#define LCDC_LCDC_JDI_HCK_WIDTH_REG_LCDC_JDI_HCK_WIDTH_Pos (0UL) /*!< LCDC_JDI_HCK_WIDTH (Bit 0) */ +#define LCDC_LCDC_JDI_HCK_WIDTH_REG_LCDC_JDI_HCK_WIDTH_Msk (0xffffffffUL) /*!< LCDC_JDI_HCK_WIDTH (Bitfield-Mask: 0xffffffff) */ +/* ================================================ LCDC_JDI_HST_DELAY_REG ================================================= */ +#define LCDC_LCDC_JDI_HST_DELAY_REG_LCDC_JDI_HST_DELAY_Pos (0UL) /*!< LCDC_JDI_HST_DELAY (Bit 0) */ +#define LCDC_LCDC_JDI_HST_DELAY_REG_LCDC_JDI_HST_DELAY_Msk (0xffffffffUL) /*!< LCDC_JDI_HST_DELAY (Bitfield-Mask: 0xffffffff) */ +/* ================================================ LCDC_JDI_HST_WIDTH_REG ================================================= */ +#define LCDC_LCDC_JDI_HST_WIDTH_REG_LCDC_JDI_HST_WIDTH_Pos (0UL) /*!< LCDC_JDI_HST_WIDTH (Bit 0) */ +#define LCDC_LCDC_JDI_HST_WIDTH_REG_LCDC_JDI_HST_WIDTH_Msk (0xffffffffUL) /*!< LCDC_JDI_HST_WIDTH (Bitfield-Mask: 0xffffffff) */ +/* ================================================== LCDC_JDI_RESXY_REG =================================================== */ +#define LCDC_LCDC_JDI_RESXY_REG_LCDC_JDI_RES_X_Pos (16UL) /*!< LCDC_JDI_RES_X (Bit 16) */ +#define LCDC_LCDC_JDI_RESXY_REG_LCDC_JDI_RES_X_Msk (0xffff0000UL) /*!< LCDC_JDI_RES_X (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_JDI_RESXY_REG_LCDC_JDI_RES_Y_Pos (0UL) /*!< LCDC_JDI_RES_Y (Bit 0) */ +#define LCDC_LCDC_JDI_RESXY_REG_LCDC_JDI_RES_Y_Msk (0xffffUL) /*!< LCDC_JDI_RES_Y (Bitfield-Mask: 0xffff) */ +/* ================================================ LCDC_JDI_VCK_DELAY_REG ================================================= */ +#define LCDC_LCDC_JDI_VCK_DELAY_REG_LCDC_JDI_VCK_DELAY_Pos (0UL) /*!< LCDC_JDI_VCK_DELAY (Bit 0) */ +#define LCDC_LCDC_JDI_VCK_DELAY_REG_LCDC_JDI_VCK_DELAY_Msk (0xffffffffUL) /*!< LCDC_JDI_VCK_DELAY (Bitfield-Mask: 0xffffffff) */ +/* ================================================ LCDC_JDI_VST_DELAY_REG ================================================= */ +#define LCDC_LCDC_JDI_VST_DELAY_REG_LCDC_JDI_VST_DELAY_Pos (0UL) /*!< LCDC_JDI_VST_DELAY (Bit 0) */ +#define LCDC_LCDC_JDI_VST_DELAY_REG_LCDC_JDI_VST_DELAY_Msk (0xffffffffUL) /*!< LCDC_JDI_VST_DELAY (Bitfield-Mask: 0xffffffff) */ +/* ================================================ LCDC_JDI_VST_WIDTH_REG ================================================= */ +#define LCDC_LCDC_JDI_VST_WIDTH_REG_LCDC_JDI_VST_WIDTH_Pos (0UL) /*!< LCDC_JDI_VST_WIDTH (Bit 0) */ +#define LCDC_LCDC_JDI_VST_WIDTH_REG_LCDC_JDI_VST_WIDTH_Msk (0xffffffffUL) /*!< LCDC_JDI_VST_WIDTH (Bitfield-Mask: 0xffffffff) */ +/* ================================================ LCDC_JDI_XRST_WIDTH_REG ================================================ */ +#define LCDC_LCDC_JDI_XRST_WIDTH_REG_LCDC_JDI_XRST_WIDTH_Pos (0UL) /*!< LCDC_JDI_XRST_WIDTH (Bit 0) */ +#define LCDC_LCDC_JDI_XRST_WIDTH_REG_LCDC_JDI_XRST_WIDTH_Msk (0xffffffffUL) /*!< LCDC_JDI_XRST_WIDTH (Bitfield-Mask: 0xffffffff) */ +/* =============================================== LCDC_LAYER0_BASEADDR_REG ================================================ */ +#define LCDC_LCDC_LAYER0_BASEADDR_REG_LCDC_L0_FB_ADDR_Pos (0UL) /*!< LCDC_L0_FB_ADDR (Bit 0) */ +#define LCDC_LCDC_LAYER0_BASEADDR_REG_LCDC_L0_FB_ADDR_Msk (0xffffffffUL) /*!< LCDC_L0_FB_ADDR (Bitfield-Mask: 0xffffffff) */ +/* ================================================= LCDC_LAYER0_MODE_REG ================================================== */ +#define LCDC_LCDC_LAYER0_MODE_REG_LCDC_L0_EN_Pos (31UL) /*!< LCDC_L0_EN (Bit 31) */ +#define LCDC_LCDC_LAYER0_MODE_REG_LCDC_L0_EN_Msk (0x80000000UL) /*!< LCDC_L0_EN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_LAYER0_MODE_REG_LCDC_L0_COLOUR_MODE_Pos (0UL) /*!< LCDC_L0_COLOUR_MODE (Bit 0) */ +#define LCDC_LCDC_LAYER0_MODE_REG_LCDC_L0_COLOUR_MODE_Msk (0x1fUL) /*!< LCDC_L0_COLOUR_MODE (Bitfield-Mask: 0x1f) */ +/* ================================================ LCDC_LAYER0_OFFSETX_REG ================================================ */ +#define LCDC_LCDC_LAYER0_OFFSETX_REG_LCDC_L0_DMA_PREFETCH_Pos (16UL) /*!< LCDC_L0_DMA_PREFETCH (Bit 16) */ +#define LCDC_LCDC_LAYER0_OFFSETX_REG_LCDC_L0_DMA_PREFETCH_Msk (0xffff0000UL) /*!< LCDC_L0_DMA_PREFETCH (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_LAYER0_OFFSETX_REG_LCDC_L0_OFFSETX_Pos (0UL) /*!< LCDC_L0_OFFSETX (Bit 0) */ +#define LCDC_LCDC_LAYER0_OFFSETX_REG_LCDC_L0_OFFSETX_Msk (0xffffUL) /*!< LCDC_L0_OFFSETX (Bitfield-Mask: 0xffff) */ +/* ================================================= LCDC_LAYER0_RESXY_REG ================================================= */ +#define LCDC_LCDC_LAYER0_RESXY_REG_LCDC_L0_RES_X_Pos (16UL) /*!< LCDC_L0_RES_X (Bit 16) */ +#define LCDC_LCDC_LAYER0_RESXY_REG_LCDC_L0_RES_X_Msk (0xffff0000UL) /*!< LCDC_L0_RES_X (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_LAYER0_RESXY_REG_LCDC_L0_RES_Y_Pos (0UL) /*!< LCDC_L0_RES_Y (Bit 0) */ +#define LCDC_LCDC_LAYER0_RESXY_REG_LCDC_L0_RES_Y_Msk (0xffffUL) /*!< LCDC_L0_RES_Y (Bitfield-Mask: 0xffff) */ +/* ================================================ LCDC_LAYER0_SIZEXY_REG ================================================= */ +#define LCDC_LCDC_LAYER0_SIZEXY_REG_LCDC_L0_SIZE_X_Pos (16UL) /*!< LCDC_L0_SIZE_X (Bit 16) */ +#define LCDC_LCDC_LAYER0_SIZEXY_REG_LCDC_L0_SIZE_X_Msk (0xffff0000UL) /*!< LCDC_L0_SIZE_X (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_LAYER0_SIZEXY_REG_LCDC_L0_SIZE_Y_Pos (0UL) /*!< LCDC_L0_SIZE_Y (Bit 0) */ +#define LCDC_LCDC_LAYER0_SIZEXY_REG_LCDC_L0_SIZE_Y_Msk (0xffffUL) /*!< LCDC_L0_SIZE_Y (Bitfield-Mask: 0xffff) */ +/* ================================================ LCDC_LAYER0_STARTXY_REG ================================================ */ +#define LCDC_LCDC_LAYER0_STARTXY_REG_LCDC_L0_START_X_Pos (16UL) /*!< LCDC_L0_START_X (Bit 16) */ +#define LCDC_LCDC_LAYER0_STARTXY_REG_LCDC_L0_START_X_Msk (0xffff0000UL) /*!< LCDC_L0_START_X (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_LAYER0_STARTXY_REG_LCDC_L0_START_Y_Pos (0UL) /*!< LCDC_L0_START_Y (Bit 0) */ +#define LCDC_LCDC_LAYER0_STARTXY_REG_LCDC_L0_START_Y_Msk (0xffffUL) /*!< LCDC_L0_START_Y (Bitfield-Mask: 0xffff) */ +/* ================================================ LCDC_LAYER0_STRIDE_REG ================================================= */ +#define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_FIFO_THR_Pos (19UL) /*!< LCDC_L0_FIFO_THR (Bit 19) */ +#define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_FIFO_THR_Msk (0x180000UL) /*!< LCDC_L0_FIFO_THR (Bitfield-Mask: 0x03) */ +#define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_BURST_LEN_Pos (16UL) /*!< LCDC_L0_BURST_LEN (Bit 16) */ +#define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_BURST_LEN_Msk (0x70000UL) /*!< LCDC_L0_BURST_LEN (Bitfield-Mask: 0x07) */ +#define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_STRIDE_Pos (0UL) /*!< LCDC_L0_STRIDE (Bit 0) */ +#define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_STRIDE_Msk (0xffffUL) /*!< LCDC_L0_STRIDE (Bitfield-Mask: 0xffff) */ +/* ===================================================== LCDC_MODE_REG ===================================================== */ +#define LCDC_LCDC_MODE_REG_LCDC_MODE_EN_Pos (31UL) /*!< LCDC_MODE_EN (Bit 31) */ +#define LCDC_LCDC_MODE_REG_LCDC_MODE_EN_Msk (0x80000000UL) /*!< LCDC_MODE_EN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_VSYNC_POL_Pos (28UL) /*!< LCDC_VSYNC_POL (Bit 28) */ +#define LCDC_LCDC_MODE_REG_LCDC_VSYNC_POL_Msk (0x10000000UL) /*!< LCDC_VSYNC_POL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_HSYNC_POL_Pos (27UL) /*!< LCDC_HSYNC_POL (Bit 27) */ +#define LCDC_LCDC_MODE_REG_LCDC_HSYNC_POL_Msk (0x8000000UL) /*!< LCDC_HSYNC_POL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_DE_POL_Pos (26UL) /*!< LCDC_DE_POL (Bit 26) */ +#define LCDC_LCDC_MODE_REG_LCDC_DE_POL_Msk (0x4000000UL) /*!< LCDC_DE_POL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_VSYNC_SCPL_Pos (23UL) /*!< LCDC_VSYNC_SCPL (Bit 23) */ +#define LCDC_LCDC_MODE_REG_LCDC_VSYNC_SCPL_Msk (0x800000UL) /*!< LCDC_VSYNC_SCPL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_PIXCLKOUT_POL_Pos (22UL) /*!< LCDC_PIXCLKOUT_POL (Bit 22) */ +#define LCDC_LCDC_MODE_REG_LCDC_PIXCLKOUT_POL_Msk (0x400000UL) /*!< LCDC_PIXCLKOUT_POL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_FORCE_BLANK_Pos (19UL) /*!< LCDC_FORCE_BLANK (Bit 19) */ +#define LCDC_LCDC_MODE_REG_LCDC_FORCE_BLANK_Msk (0x80000UL) /*!< LCDC_FORCE_BLANK (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_SFRAME_UPD_Pos (17UL) /*!< LCDC_SFRAME_UPD (Bit 17) */ +#define LCDC_LCDC_MODE_REG_LCDC_SFRAME_UPD_Msk (0x20000UL) /*!< LCDC_SFRAME_UPD (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_PIXCLKOUT_SEL_Pos (11UL) /*!< LCDC_PIXCLKOUT_SEL (Bit 11) */ +#define LCDC_LCDC_MODE_REG_LCDC_PIXCLKOUT_SEL_Msk (0x800UL) /*!< LCDC_PIXCLKOUT_SEL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_OUT_MODE_Pos (5UL) /*!< LCDC_OUT_MODE (Bit 5) */ +#define LCDC_LCDC_MODE_REG_LCDC_OUT_MODE_Msk (0x1e0UL) /*!< LCDC_OUT_MODE (Bitfield-Mask: 0x0f) */ +#define LCDC_LCDC_MODE_REG_LCDC_MIPI_OFF_Pos (4UL) /*!< LCDC_MIPI_OFF (Bit 4) */ +#define LCDC_LCDC_MODE_REG_LCDC_MIPI_OFF_Msk (0x10UL) /*!< LCDC_MIPI_OFF (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_FORM_OFF_Pos (3UL) /*!< LCDC_FORM_OFF (Bit 3) */ +#define LCDC_LCDC_MODE_REG_LCDC_FORM_OFF_Msk (0x8UL) /*!< LCDC_FORM_OFF (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_DSCAN_Pos (1UL) /*!< LCDC_DSCAN (Bit 1) */ +#define LCDC_LCDC_MODE_REG_LCDC_DSCAN_Msk (0x2UL) /*!< LCDC_DSCAN (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_MODE_REG_LCDC_TMODE_Pos (0UL) /*!< LCDC_TMODE (Bit 0) */ +#define LCDC_LCDC_MODE_REG_LCDC_TMODE_Msk (0x1UL) /*!< LCDC_TMODE (Bitfield-Mask: 0x01) */ +/* ==================================================== LCDC_RESXY_REG ===================================================== */ +#define LCDC_LCDC_RESXY_REG_LCDC_RES_X_Pos (16UL) /*!< LCDC_RES_X (Bit 16) */ +#define LCDC_LCDC_RESXY_REG_LCDC_RES_X_Msk (0xffff0000UL) /*!< LCDC_RES_X (Bitfield-Mask: 0xffff) */ +#define LCDC_LCDC_RESXY_REG_LCDC_RES_Y_Pos (0UL) /*!< LCDC_RES_Y (Bit 0) */ +#define LCDC_LCDC_RESXY_REG_LCDC_RES_Y_Msk (0xffffUL) /*!< LCDC_RES_Y (Bitfield-Mask: 0xffff) */ +/* ==================================================== LCDC_STATUS_REG ==================================================== */ +#define LCDC_LCDC_STATUS_REG_LCDC_JDI_TIM_SW_RST_Pos (15UL) /*!< LCDC_JDI_TIM_SW_RST (Bit 15) */ +#define LCDC_LCDC_STATUS_REG_LCDC_JDI_TIM_SW_RST_Msk (0x8000UL) /*!< LCDC_JDI_TIM_SW_RST (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_FRAME_START_Pos (14UL) /*!< LCDC_FRAME_START (Bit 14) */ +#define LCDC_LCDC_STATUS_REG_LCDC_FRAME_START_Msk (0x4000UL) /*!< LCDC_FRAME_START (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_FRAME_END_Pos (13UL) /*!< LCDC_FRAME_END (Bit 13) */ +#define LCDC_LCDC_STATUS_REG_LCDC_FRAME_END_Msk (0x2000UL) /*!< LCDC_FRAME_END (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_PENDING_Pos (12UL) /*!< LCDC_DBIB_CMD_PENDING (Bit 12) */ +#define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_PENDING_Msk (0x1000UL) /*!< LCDC_DBIB_CMD_PENDING (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_FIFO_FULL_Pos (11UL) /*!< LCDC_DBIB_CMD_FIFO_FULL (Bit 11) */ +#define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_FIFO_FULL_Msk (0x800UL) /*!< LCDC_DBIB_CMD_FIFO_FULL (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_FIFO_EMPTY_N_Pos (10UL) /*!< LCDC_DBIB_CMD_FIFO_EMPTY_N (Bit 10) */ +#define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_FIFO_EMPTY_N_Msk (0x400UL) /*!< LCDC_DBIB_CMD_FIFO_EMPTY_N (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_DBIB_TE_Pos (8UL) /*!< LCDC_DBIB_TE (Bit 8) */ +#define LCDC_LCDC_STATUS_REG_LCDC_DBIB_TE_Msk (0x100UL) /*!< LCDC_DBIB_TE (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STICKY_UNDERFLOW_Pos (7UL) /*!< LCDC_STICKY_UNDERFLOW (Bit 7) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STICKY_UNDERFLOW_Msk (0x80UL) /*!< LCDC_STICKY_UNDERFLOW (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_UNDERFLOW_Pos (6UL) /*!< LCDC_UNDERFLOW (Bit 6) */ +#define LCDC_LCDC_STATUS_REG_LCDC_UNDERFLOW_Msk (0x40UL) /*!< LCDC_UNDERFLOW (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_LAST_ROW_Pos (5UL) /*!< LCDC_LAST_ROW (Bit 5) */ +#define LCDC_LCDC_STATUS_REG_LCDC_LAST_ROW_Msk (0x20UL) /*!< LCDC_LAST_ROW (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STAT_CSYNC_Pos (4UL) /*!< LCDC_STAT_CSYNC (Bit 4) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STAT_CSYNC_Msk (0x10UL) /*!< LCDC_STAT_CSYNC (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STAT_VSYNC_Pos (3UL) /*!< LCDC_STAT_VSYNC (Bit 3) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STAT_VSYNC_Msk (0x8UL) /*!< LCDC_STAT_VSYNC (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STAT_HSYNC_Pos (2UL) /*!< LCDC_STAT_HSYNC (Bit 2) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STAT_HSYNC_Msk (0x4UL) /*!< LCDC_STAT_HSYNC (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_FRAMEGEN_BUSY_Pos (1UL) /*!< LCDC_FRAMEGEN_BUSY (Bit 1) */ +#define LCDC_LCDC_STATUS_REG_LCDC_FRAMEGEN_BUSY_Msk (0x2UL) /*!< LCDC_FRAMEGEN_BUSY (Bitfield-Mask: 0x01) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STAT_ACTIVE_Pos (0UL) /*!< LCDC_STAT_ACTIVE (Bit 0) */ +#define LCDC_LCDC_STATUS_REG_LCDC_STAT_ACTIVE_Msk (0x1UL) /*!< LCDC_STAT_ACTIVE (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ LRA ================ */ +/* =========================================================================================================================== */ + +/* =================================================== LRA_ADC_CTRL1_REG =================================================== */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_BUSY_Pos (31UL) /*!< LRA_ADC_BUSY (Bit 31) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_BUSY_Msk (0x80000000UL) /*!< LRA_ADC_BUSY (Bitfield-Mask: 0x01) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_OFFSET_Pos (9UL) /*!< LRA_ADC_OFFSET (Bit 9) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_OFFSET_Msk (0x1fe00UL) /*!< LRA_ADC_OFFSET (Bitfield-Mask: 0xff) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_TEST_PARAM_Pos (8UL) /*!< LRA_ADC_TEST_PARAM (Bit 8) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_TEST_PARAM_Msk (0x100UL) /*!< LRA_ADC_TEST_PARAM (Bitfield-Mask: 0x01) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_TEST_IN_SEL_Pos (7UL) /*!< LRA_ADC_TEST_IN_SEL (Bit 7) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_TEST_IN_SEL_Msk (0x80UL) /*!< LRA_ADC_TEST_IN_SEL (Bitfield-Mask: 0x01) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_FREQ_Pos (3UL) /*!< LRA_ADC_FREQ (Bit 3) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_FREQ_Msk (0x78UL) /*!< LRA_ADC_FREQ (Bitfield-Mask: 0x0f) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_SIGN_Pos (2UL) /*!< LRA_ADC_SIGN (Bit 2) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_SIGN_Msk (0x4UL) /*!< LRA_ADC_SIGN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_MUTE_Pos (1UL) /*!< LRA_ADC_MUTE (Bit 1) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_MUTE_Msk (0x2UL) /*!< LRA_ADC_MUTE (Bitfield-Mask: 0x01) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_START_Pos (0UL) /*!< LRA_ADC_START (Bit 0) */ +#define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_START_Msk (0x1UL) /*!< LRA_ADC_START (Bitfield-Mask: 0x01) */ +/* ================================================== LRA_ADC_RESULT_REG =================================================== */ +#define LRA_LRA_ADC_RESULT_REG_MAN_FLT_IN_Pos (16UL) /*!< MAN_FLT_IN (Bit 16) */ +#define LRA_LRA_ADC_RESULT_REG_MAN_FLT_IN_Msk (0xffff0000UL) /*!< MAN_FLT_IN (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_ADC_RESULT_REG_GP_ADC_VAL_Pos (0UL) /*!< GP_ADC_VAL (Bit 0) */ +#define LRA_LRA_ADC_RESULT_REG_GP_ADC_VAL_Msk (0xffffUL) /*!< GP_ADC_VAL (Bitfield-Mask: 0xffff) */ +/* ==================================================== LRA_BRD_HS_REG ===================================================== */ +#define LRA_LRA_BRD_HS_REG_TRIM_GAIN_Pos (11UL) /*!< TRIM_GAIN (Bit 11) */ +#define LRA_LRA_BRD_HS_REG_TRIM_GAIN_Msk (0x7800UL) /*!< TRIM_GAIN (Bitfield-Mask: 0x0f) */ +#define LRA_LRA_BRD_HS_REG_HSGND_TRIM_Pos (8UL) /*!< HSGND_TRIM (Bit 8) */ +#define LRA_LRA_BRD_HS_REG_HSGND_TRIM_Msk (0x700UL) /*!< HSGND_TRIM (Bitfield-Mask: 0x07) */ +#define LRA_LRA_BRD_HS_REG_SCP_HS_TRIM_Pos (4UL) /*!< SCP_HS_TRIM (Bit 4) */ +#define LRA_LRA_BRD_HS_REG_SCP_HS_TRIM_Msk (0xf0UL) /*!< SCP_HS_TRIM (Bitfield-Mask: 0x0f) */ +#define LRA_LRA_BRD_HS_REG_SCP_HS_EN_Pos (3UL) /*!< SCP_HS_EN (Bit 3) */ +#define LRA_LRA_BRD_HS_REG_SCP_HS_EN_Msk (0x8UL) /*!< SCP_HS_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_HS_REG_ERC_HS_TRIM_Pos (1UL) /*!< ERC_HS_TRIM (Bit 1) */ +#define LRA_LRA_BRD_HS_REG_ERC_HS_TRIM_Msk (0x6UL) /*!< ERC_HS_TRIM (Bitfield-Mask: 0x03) */ +#define LRA_LRA_BRD_HS_REG_ERC_HS_EN_Pos (0UL) /*!< ERC_HS_EN (Bit 0) */ +#define LRA_LRA_BRD_HS_REG_ERC_HS_EN_Msk (0x1UL) /*!< ERC_HS_EN (Bitfield-Mask: 0x01) */ +/* ==================================================== LRA_BRD_LS_REG ===================================================== */ +#define LRA_LRA_BRD_LS_REG_SCP_LS_TRIM_N_Pos (8UL) /*!< SCP_LS_TRIM_N (Bit 8) */ +#define LRA_LRA_BRD_LS_REG_SCP_LS_TRIM_N_Msk (0xf00UL) /*!< SCP_LS_TRIM_N (Bitfield-Mask: 0x0f) */ +#define LRA_LRA_BRD_LS_REG_SCP_LS_TRIM_P_Pos (4UL) /*!< SCP_LS_TRIM_P (Bit 4) */ +#define LRA_LRA_BRD_LS_REG_SCP_LS_TRIM_P_Msk (0xf0UL) /*!< SCP_LS_TRIM_P (Bitfield-Mask: 0x0f) */ +#define LRA_LRA_BRD_LS_REG_SCP_LS_EN_Pos (3UL) /*!< SCP_LS_EN (Bit 3) */ +#define LRA_LRA_BRD_LS_REG_SCP_LS_EN_Msk (0x8UL) /*!< SCP_LS_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_LS_REG_ERC_LS_TRIM_Pos (1UL) /*!< ERC_LS_TRIM (Bit 1) */ +#define LRA_LRA_BRD_LS_REG_ERC_LS_TRIM_Msk (0x6UL) /*!< ERC_LS_TRIM (Bitfield-Mask: 0x03) */ +#define LRA_LRA_BRD_LS_REG_ERC_LS_EN_Pos (0UL) /*!< ERC_LS_EN (Bit 0) */ +#define LRA_LRA_BRD_LS_REG_ERC_LS_EN_Msk (0x1UL) /*!< ERC_LS_EN (Bitfield-Mask: 0x01) */ +/* =================================================== LRA_BRD_STAT_REG ==================================================== */ +#define LRA_LRA_BRD_STAT_REG_SCP_HS_OUT_Pos (13UL) /*!< SCP_HS_OUT (Bit 13) */ +#define LRA_LRA_BRD_STAT_REG_SCP_HS_OUT_Msk (0x2000UL) /*!< SCP_HS_OUT (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_SCP_LS_COMP_OUT_N_Pos (12UL) /*!< SCP_LS_COMP_OUT_N (Bit 12) */ +#define LRA_LRA_BRD_STAT_REG_SCP_LS_COMP_OUT_N_Msk (0x1000UL) /*!< SCP_LS_COMP_OUT_N (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_SCP_LS_COMP_OUT_P_Pos (11UL) /*!< SCP_LS_COMP_OUT_P (Bit 11) */ +#define LRA_LRA_BRD_STAT_REG_SCP_LS_COMP_OUT_P_Msk (0x800UL) /*!< SCP_LS_COMP_OUT_P (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_SC_EVENT_LS_Pos (10UL) /*!< SC_EVENT_LS (Bit 10) */ +#define LRA_LRA_BRD_STAT_REG_SC_EVENT_LS_Msk (0x400UL) /*!< SC_EVENT_LS (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_SC_EVENT_HS_Pos (9UL) /*!< SC_EVENT_HS (Bit 9) */ +#define LRA_LRA_BRD_STAT_REG_SC_EVENT_HS_Msk (0x200UL) /*!< SC_EVENT_HS (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_LOOP_STAT_Pos (8UL) /*!< LOOP_STAT (Bit 8) */ +#define LRA_LRA_BRD_STAT_REG_LOOP_STAT_Msk (0x100UL) /*!< LOOP_STAT (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_LSN_ON_Pos (7UL) /*!< LSN_ON (Bit 7) */ +#define LRA_LRA_BRD_STAT_REG_LSN_ON_Msk (0x80UL) /*!< LSN_ON (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_LSP_ON_Pos (6UL) /*!< LSP_ON (Bit 6) */ +#define LRA_LRA_BRD_STAT_REG_LSP_ON_Msk (0x40UL) /*!< LSP_ON (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_HSN_ON_Pos (5UL) /*!< HSN_ON (Bit 5) */ +#define LRA_LRA_BRD_STAT_REG_HSN_ON_Msk (0x20UL) /*!< HSN_ON (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_HSP_ON_Pos (4UL) /*!< HSP_ON (Bit 4) */ +#define LRA_LRA_BRD_STAT_REG_HSP_ON_Msk (0x10UL) /*!< HSP_ON (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_LSN_STAT_Pos (3UL) /*!< LSN_STAT (Bit 3) */ +#define LRA_LRA_BRD_STAT_REG_LSN_STAT_Msk (0x8UL) /*!< LSN_STAT (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_LSP_STAT_Pos (2UL) /*!< LSP_STAT (Bit 2) */ +#define LRA_LRA_BRD_STAT_REG_LSP_STAT_Msk (0x4UL) /*!< LSP_STAT (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_HSN_STAT_Pos (1UL) /*!< HSN_STAT (Bit 1) */ +#define LRA_LRA_BRD_STAT_REG_HSN_STAT_Msk (0x2UL) /*!< HSN_STAT (Bitfield-Mask: 0x01) */ +#define LRA_LRA_BRD_STAT_REG_HSP_STAT_Pos (0UL) /*!< HSP_STAT (Bit 0) */ +#define LRA_LRA_BRD_STAT_REG_HSP_STAT_Msk (0x1UL) /*!< HSP_STAT (Bitfield-Mask: 0x01) */ +/* ===================================================== LRA_CTRL1_REG ===================================================== */ +#define LRA_LRA_CTRL1_REG_SMP_IDX_Pos (24UL) /*!< SMP_IDX (Bit 24) */ +#define LRA_LRA_CTRL1_REG_SMP_IDX_Msk (0xf000000UL) /*!< SMP_IDX (Bitfield-Mask: 0x0f) */ +#define LRA_LRA_CTRL1_REG_IRQ_SCP_EVENT_EN_Pos (18UL) /*!< IRQ_SCP_EVENT_EN (Bit 18) */ +#define LRA_LRA_CTRL1_REG_IRQ_SCP_EVENT_EN_Msk (0x40000UL) /*!< IRQ_SCP_EVENT_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL1_REG_IRQ_ADC_EN_Pos (17UL) /*!< IRQ_ADC_EN (Bit 17) */ +#define LRA_LRA_CTRL1_REG_IRQ_ADC_EN_Msk (0x20000UL) /*!< IRQ_ADC_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL1_REG_IRQ_CTRL_EN_Pos (16UL) /*!< IRQ_CTRL_EN (Bit 16) */ +#define LRA_LRA_CTRL1_REG_IRQ_CTRL_EN_Msk (0x10000UL) /*!< IRQ_CTRL_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL1_REG_IRQ_IDX_Pos (12UL) /*!< IRQ_IDX (Bit 12) */ +#define LRA_LRA_CTRL1_REG_IRQ_IDX_Msk (0xf000UL) /*!< IRQ_IDX (Bitfield-Mask: 0x0f) */ +#define LRA_LRA_CTRL1_REG_IRQ_DIV_Pos (8UL) /*!< IRQ_DIV (Bit 8) */ +#define LRA_LRA_CTRL1_REG_IRQ_DIV_Msk (0xf00UL) /*!< IRQ_DIV (Bitfield-Mask: 0x0f) */ +#define LRA_LRA_CTRL1_REG_SMP_SEL_Pos (6UL) /*!< SMP_SEL (Bit 6) */ +#define LRA_LRA_CTRL1_REG_SMP_SEL_Msk (0xc0UL) /*!< SMP_SEL (Bitfield-Mask: 0x03) */ +#define LRA_LRA_CTRL1_REG_PULLDOWN_EN_Pos (5UL) /*!< PULLDOWN_EN (Bit 5) */ +#define LRA_LRA_CTRL1_REG_PULLDOWN_EN_Msk (0x20UL) /*!< PULLDOWN_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL1_REG_LOOP_EN_Pos (4UL) /*!< LOOP_EN (Bit 4) */ +#define LRA_LRA_CTRL1_REG_LOOP_EN_Msk (0x10UL) /*!< LOOP_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL1_REG_LDO_EN_Pos (3UL) /*!< LDO_EN (Bit 3) */ +#define LRA_LRA_CTRL1_REG_LDO_EN_Msk (0x8UL) /*!< LDO_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL1_REG_ADC_EN_Pos (2UL) /*!< ADC_EN (Bit 2) */ +#define LRA_LRA_CTRL1_REG_ADC_EN_Msk (0x4UL) /*!< ADC_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL1_REG_HBRIDGE_EN_Pos (1UL) /*!< HBRIDGE_EN (Bit 1) */ +#define LRA_LRA_CTRL1_REG_HBRIDGE_EN_Msk (0x2UL) /*!< HBRIDGE_EN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL1_REG_LRA_EN_Pos (0UL) /*!< LRA_EN (Bit 0) */ +#define LRA_LRA_CTRL1_REG_LRA_EN_Msk (0x1UL) /*!< LRA_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== LRA_CTRL2_REG ===================================================== */ +#define LRA_LRA_CTRL2_REG_HALF_PERIOD_Pos (16UL) /*!< HALF_PERIOD (Bit 16) */ +#define LRA_LRA_CTRL2_REG_HALF_PERIOD_Msk (0xffff0000UL) /*!< HALF_PERIOD (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_CTRL2_REG_AUTO_MODE_Pos (5UL) /*!< AUTO_MODE (Bit 5) */ +#define LRA_LRA_CTRL2_REG_AUTO_MODE_Msk (0x20UL) /*!< AUTO_MODE (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL2_REG_SMP_MODE_Pos (4UL) /*!< SMP_MODE (Bit 4) */ +#define LRA_LRA_CTRL2_REG_SMP_MODE_Msk (0x10UL) /*!< SMP_MODE (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL2_REG_POLARITY_Pos (3UL) /*!< POLARITY (Bit 3) */ +#define LRA_LRA_CTRL2_REG_POLARITY_Msk (0x8UL) /*!< POLARITY (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL2_REG_FLT_IN_SEL_Pos (2UL) /*!< FLT_IN_SEL (Bit 2) */ +#define LRA_LRA_CTRL2_REG_FLT_IN_SEL_Msk (0x4UL) /*!< FLT_IN_SEL (Bitfield-Mask: 0x01) */ +#define LRA_LRA_CTRL2_REG_PWM_MODE_Pos (0UL) /*!< PWM_MODE (Bit 0) */ +#define LRA_LRA_CTRL2_REG_PWM_MODE_Msk (0x3UL) /*!< PWM_MODE (Bitfield-Mask: 0x03) */ +/* ===================================================== LRA_CTRL3_REG ===================================================== */ +#define LRA_LRA_CTRL3_REG_VREF_Pos (16UL) /*!< VREF (Bit 16) */ +#define LRA_LRA_CTRL3_REG_VREF_Msk (0xffff0000UL) /*!< VREF (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_CTRL3_REG_DREF_Pos (0UL) /*!< DREF (Bit 0) */ +#define LRA_LRA_CTRL3_REG_DREF_Msk (0xffffUL) /*!< DREF (Bitfield-Mask: 0xffff) */ +/* ====================================================== LRA_DFT_REG ====================================================== */ +#define LRA_LRA_DFT_REG_SPARE_Pos (29UL) /*!< SPARE (Bit 29) */ +#define LRA_LRA_DFT_REG_SPARE_Msk (0xe0000000UL) /*!< SPARE (Bitfield-Mask: 0x07) */ +#define LRA_LRA_DFT_REG_SWM_SEL_Pos (28UL) /*!< SWM_SEL (Bit 28) */ +#define LRA_LRA_DFT_REG_SWM_SEL_Msk (0x10000000UL) /*!< SWM_SEL (Bitfield-Mask: 0x01) */ +#define LRA_LRA_DFT_REG_SWM_MAN_Pos (27UL) /*!< SWM_MAN (Bit 27) */ +#define LRA_LRA_DFT_REG_SWM_MAN_Msk (0x8000000UL) /*!< SWM_MAN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_DFT_REG_PWM_SEL_Pos (26UL) /*!< PWM_SEL (Bit 26) */ +#define LRA_LRA_DFT_REG_PWM_SEL_Msk (0x4000000UL) /*!< PWM_SEL (Bitfield-Mask: 0x01) */ +#define LRA_LRA_DFT_REG_PWM_MAN_Pos (25UL) /*!< PWM_MAN (Bit 25) */ +#define LRA_LRA_DFT_REG_PWM_MAN_Msk (0x2000000UL) /*!< PWM_MAN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_DFT_REG_TIMER_TRIM_Pos (23UL) /*!< TIMER_TRIM (Bit 23) */ +#define LRA_LRA_DFT_REG_TIMER_TRIM_Msk (0x1800000UL) /*!< TIMER_TRIM (Bitfield-Mask: 0x03) */ +#define LRA_LRA_DFT_REG_TIMER_SCALE_TRIM_Pos (21UL) /*!< TIMER_SCALE_TRIM (Bit 21) */ +#define LRA_LRA_DFT_REG_TIMER_SCALE_TRIM_Msk (0x600000UL) /*!< TIMER_SCALE_TRIM (Bitfield-Mask: 0x03) */ +#define LRA_LRA_DFT_REG_DFT_SEL_Pos (20UL) /*!< DFT_SEL (Bit 20) */ +#define LRA_LRA_DFT_REG_DFT_SEL_Msk (0x100000UL) /*!< DFT_SEL (Bitfield-Mask: 0x01) */ +#define LRA_LRA_DFT_REG_DFT_FORCE_HSPN_Pos (19UL) /*!< DFT_FORCE_HSPN (Bit 19) */ +#define LRA_LRA_DFT_REG_DFT_FORCE_HSPN_Msk (0x80000UL) /*!< DFT_FORCE_HSPN (Bitfield-Mask: 0x01) */ +#define LRA_LRA_DFT_REG_DFT_EN_TIMER_Pos (18UL) /*!< DFT_EN_TIMER (Bit 18) */ +#define LRA_LRA_DFT_REG_DFT_EN_TIMER_Msk (0x40000UL) /*!< DFT_EN_TIMER (Bitfield-Mask: 0x01) */ +#define LRA_LRA_DFT_REG_DFT_STALL_Pos (16UL) /*!< DFT_STALL (Bit 16) */ +#define LRA_LRA_DFT_REG_DFT_STALL_Msk (0x30000UL) /*!< DFT_STALL (Bitfield-Mask: 0x03) */ +#define LRA_LRA_DFT_REG_DFT_CTRL_Pos (0UL) /*!< DFT_CTRL (Bit 0) */ +#define LRA_LRA_DFT_REG_DFT_CTRL_Msk (0xffffUL) /*!< DFT_CTRL (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_COEF1_REG =================================================== */ +#define LRA_LRA_FLT_COEF1_REG_FLT_COEF_01_Pos (16UL) /*!< FLT_COEF_01 (Bit 16) */ +#define LRA_LRA_FLT_COEF1_REG_FLT_COEF_01_Msk (0xffff0000UL) /*!< FLT_COEF_01 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_COEF1_REG_FLT_COEF_00_Pos (0UL) /*!< FLT_COEF_00 (Bit 0) */ +#define LRA_LRA_FLT_COEF1_REG_FLT_COEF_00_Msk (0xffffUL) /*!< FLT_COEF_00 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_COEF2_REG =================================================== */ +#define LRA_LRA_FLT_COEF2_REG_FLT_COEF_10_Pos (16UL) /*!< FLT_COEF_10 (Bit 16) */ +#define LRA_LRA_FLT_COEF2_REG_FLT_COEF_10_Msk (0xffff0000UL) /*!< FLT_COEF_10 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_COEF2_REG_FLT_COEF_02_Pos (0UL) /*!< FLT_COEF_02 (Bit 0) */ +#define LRA_LRA_FLT_COEF2_REG_FLT_COEF_02_Msk (0xffffUL) /*!< FLT_COEF_02 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_COEF3_REG =================================================== */ +#define LRA_LRA_FLT_COEF3_REG_FLT_COEF_12_Pos (16UL) /*!< FLT_COEF_12 (Bit 16) */ +#define LRA_LRA_FLT_COEF3_REG_FLT_COEF_12_Msk (0xffff0000UL) /*!< FLT_COEF_12 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_COEF3_REG_FLT_COEF_11_Pos (0UL) /*!< FLT_COEF_11 (Bit 0) */ +#define LRA_LRA_FLT_COEF3_REG_FLT_COEF_11_Msk (0xffffUL) /*!< FLT_COEF_11 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_SMP1_REG ==================================================== */ +#define LRA_LRA_FLT_SMP1_REG_LRA_SMP_2_Pos (16UL) /*!< LRA_SMP_2 (Bit 16) */ +#define LRA_LRA_FLT_SMP1_REG_LRA_SMP_2_Msk (0xffff0000UL) /*!< LRA_SMP_2 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_SMP1_REG_LRA_SMP_1_Pos (0UL) /*!< LRA_SMP_1 (Bit 0) */ +#define LRA_LRA_FLT_SMP1_REG_LRA_SMP_1_Msk (0xffffUL) /*!< LRA_SMP_1 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_SMP2_REG ==================================================== */ +#define LRA_LRA_FLT_SMP2_REG_LRA_SMP_4_Pos (16UL) /*!< LRA_SMP_4 (Bit 16) */ +#define LRA_LRA_FLT_SMP2_REG_LRA_SMP_4_Msk (0xffff0000UL) /*!< LRA_SMP_4 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_SMP2_REG_LRA_SMP_3_Pos (0UL) /*!< LRA_SMP_3 (Bit 0) */ +#define LRA_LRA_FLT_SMP2_REG_LRA_SMP_3_Msk (0xffffUL) /*!< LRA_SMP_3 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_SMP3_REG ==================================================== */ +#define LRA_LRA_FLT_SMP3_REG_LRA_SMP_6_Pos (16UL) /*!< LRA_SMP_6 (Bit 16) */ +#define LRA_LRA_FLT_SMP3_REG_LRA_SMP_6_Msk (0xffff0000UL) /*!< LRA_SMP_6 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_SMP3_REG_LRA_SMP_5_Pos (0UL) /*!< LRA_SMP_5 (Bit 0) */ +#define LRA_LRA_FLT_SMP3_REG_LRA_SMP_5_Msk (0xffffUL) /*!< LRA_SMP_5 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_SMP4_REG ==================================================== */ +#define LRA_LRA_FLT_SMP4_REG_LRA_SMP_8_Pos (16UL) /*!< LRA_SMP_8 (Bit 16) */ +#define LRA_LRA_FLT_SMP4_REG_LRA_SMP_8_Msk (0xffff0000UL) /*!< LRA_SMP_8 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_SMP4_REG_LRA_SMP_7_Pos (0UL) /*!< LRA_SMP_7 (Bit 0) */ +#define LRA_LRA_FLT_SMP4_REG_LRA_SMP_7_Msk (0xffffUL) /*!< LRA_SMP_7 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_SMP5_REG ==================================================== */ +#define LRA_LRA_FLT_SMP5_REG_LRA_SMP_10_Pos (16UL) /*!< LRA_SMP_10 (Bit 16) */ +#define LRA_LRA_FLT_SMP5_REG_LRA_SMP_10_Msk (0xffff0000UL) /*!< LRA_SMP_10 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_SMP5_REG_LRA_SMP_9_Pos (0UL) /*!< LRA_SMP_9 (Bit 0) */ +#define LRA_LRA_FLT_SMP5_REG_LRA_SMP_9_Msk (0xffffUL) /*!< LRA_SMP_9 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_SMP6_REG ==================================================== */ +#define LRA_LRA_FLT_SMP6_REG_LRA_SMP_12_Pos (16UL) /*!< LRA_SMP_12 (Bit 16) */ +#define LRA_LRA_FLT_SMP6_REG_LRA_SMP_12_Msk (0xffff0000UL) /*!< LRA_SMP_12 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_SMP6_REG_LRA_SMP_11_Pos (0UL) /*!< LRA_SMP_11 (Bit 0) */ +#define LRA_LRA_FLT_SMP6_REG_LRA_SMP_11_Msk (0xffffUL) /*!< LRA_SMP_11 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_SMP7_REG ==================================================== */ +#define LRA_LRA_FLT_SMP7_REG_LRA_SMP_14_Pos (16UL) /*!< LRA_SMP_14 (Bit 16) */ +#define LRA_LRA_FLT_SMP7_REG_LRA_SMP_14_Msk (0xffff0000UL) /*!< LRA_SMP_14 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_SMP7_REG_LRA_SMP_13_Pos (0UL) /*!< LRA_SMP_13 (Bit 0) */ +#define LRA_LRA_FLT_SMP7_REG_LRA_SMP_13_Msk (0xffffUL) /*!< LRA_SMP_13 (Bitfield-Mask: 0xffff) */ +/* =================================================== LRA_FLT_SMP8_REG ==================================================== */ +#define LRA_LRA_FLT_SMP8_REG_LRA_SMP_16_Pos (16UL) /*!< LRA_SMP_16 (Bit 16) */ +#define LRA_LRA_FLT_SMP8_REG_LRA_SMP_16_Msk (0xffff0000UL) /*!< LRA_SMP_16 (Bitfield-Mask: 0xffff) */ +#define LRA_LRA_FLT_SMP8_REG_LRA_SMP_15_Pos (0UL) /*!< LRA_SMP_15 (Bit 0) */ +#define LRA_LRA_FLT_SMP8_REG_LRA_SMP_15_Msk (0xffffUL) /*!< LRA_SMP_15 (Bitfield-Mask: 0xffff) */ +/* ====================================================== LRA_LDO_REG ====================================================== */ +#define LRA_LRA_LDO_REG_LDO_OK_Pos (31UL) /*!< LDO_OK (Bit 31) */ +#define LRA_LRA_LDO_REG_LDO_OK_Msk (0x80000000UL) /*!< LDO_OK (Bitfield-Mask: 0x01) */ +#define LRA_LRA_LDO_REG_LDO_TST_Pos (1UL) /*!< LDO_TST (Bit 1) */ +#define LRA_LRA_LDO_REG_LDO_TST_Msk (0x2UL) /*!< LDO_TST (Bitfield-Mask: 0x01) */ +#define LRA_LRA_LDO_REG_LDO_VREF_HOLD_Pos (0UL) /*!< LDO_VREF_HOLD (Bit 0) */ +#define LRA_LRA_LDO_REG_LDO_VREF_HOLD_Msk (0x1UL) /*!< LDO_VREF_HOLD (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ MEMCTRL ================ */ +/* =========================================================================================================================== */ + +/* ==================================================== BUSY_RESET_REG ===================================================== */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SPARE_Pos (30UL) /*!< BUSY_SPARE (Bit 30) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SPARE_Msk (0xc0000000UL) /*!< BUSY_SPARE (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_MOTOR_Pos (28UL) /*!< BUSY_MOTOR (Bit 28) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_MOTOR_Msk (0x30000000UL) /*!< BUSY_MOTOR (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_TIMER2_Pos (26UL) /*!< BUSY_TIMER2 (Bit 26) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_TIMER2_Msk (0xc000000UL) /*!< BUSY_TIMER2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_TIMER_Pos (24UL) /*!< BUSY_TIMER (Bit 24) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_TIMER_Msk (0x3000000UL) /*!< BUSY_TIMER (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_UART3_Pos (22UL) /*!< BUSY_UART3 (Bit 22) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_UART3_Msk (0xc00000UL) /*!< BUSY_UART3 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_GPADC_Pos (20UL) /*!< BUSY_GPADC (Bit 20) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_GPADC_Msk (0x300000UL) /*!< BUSY_GPADC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_PDM_Pos (18UL) /*!< BUSY_PDM (Bit 18) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_PDM_Msk (0xc0000UL) /*!< BUSY_PDM (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SRC_Pos (16UL) /*!< BUSY_SRC (Bit 16) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SRC_Msk (0x30000UL) /*!< BUSY_SRC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_PCM_Pos (14UL) /*!< BUSY_PCM (Bit 14) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_PCM_Msk (0xc000UL) /*!< BUSY_PCM (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SDADC_Pos (12UL) /*!< BUSY_SDADC (Bit 12) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SDADC_Msk (0x3000UL) /*!< BUSY_SDADC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_I2C2_Pos (10UL) /*!< BUSY_I2C2 (Bit 10) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_I2C2_Msk (0xc00UL) /*!< BUSY_I2C2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_I2C_Pos (8UL) /*!< BUSY_I2C (Bit 8) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_I2C_Msk (0x300UL) /*!< BUSY_I2C (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SPI2_Pos (6UL) /*!< BUSY_SPI2 (Bit 6) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SPI2_Msk (0xc0UL) /*!< BUSY_SPI2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SPI_Pos (4UL) /*!< BUSY_SPI (Bit 4) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_SPI_Msk (0x30UL) /*!< BUSY_SPI (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_UART2_Pos (2UL) /*!< BUSY_UART2 (Bit 2) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_UART2_Msk (0xcUL) /*!< BUSY_UART2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_UART_Pos (0UL) /*!< BUSY_UART (Bit 0) */ +#define MEMCTRL_BUSY_RESET_REG_BUSY_UART_Msk (0x3UL) /*!< BUSY_UART (Bitfield-Mask: 0x03) */ +/* ===================================================== BUSY_SET_REG ====================================================== */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SPARE_Pos (30UL) /*!< BUSY_SPARE (Bit 30) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SPARE_Msk (0xc0000000UL) /*!< BUSY_SPARE (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_MOTOR_Pos (28UL) /*!< BUSY_MOTOR (Bit 28) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_MOTOR_Msk (0x30000000UL) /*!< BUSY_MOTOR (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_TIMER2_Pos (26UL) /*!< BUSY_TIMER2 (Bit 26) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_TIMER2_Msk (0xc000000UL) /*!< BUSY_TIMER2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_TIMER_Pos (24UL) /*!< BUSY_TIMER (Bit 24) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_TIMER_Msk (0x3000000UL) /*!< BUSY_TIMER (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_UART3_Pos (22UL) /*!< BUSY_UART3 (Bit 22) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_UART3_Msk (0xc00000UL) /*!< BUSY_UART3 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_GPADC_Pos (20UL) /*!< BUSY_GPADC (Bit 20) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_GPADC_Msk (0x300000UL) /*!< BUSY_GPADC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_PDM_Pos (18UL) /*!< BUSY_PDM (Bit 18) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_PDM_Msk (0xc0000UL) /*!< BUSY_PDM (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SRC_Pos (16UL) /*!< BUSY_SRC (Bit 16) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SRC_Msk (0x30000UL) /*!< BUSY_SRC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_PCM_Pos (14UL) /*!< BUSY_PCM (Bit 14) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_PCM_Msk (0xc000UL) /*!< BUSY_PCM (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SDADC_Pos (12UL) /*!< BUSY_SDADC (Bit 12) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SDADC_Msk (0x3000UL) /*!< BUSY_SDADC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_I2C2_Pos (10UL) /*!< BUSY_I2C2 (Bit 10) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_I2C2_Msk (0xc00UL) /*!< BUSY_I2C2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_I2C_Pos (8UL) /*!< BUSY_I2C (Bit 8) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_I2C_Msk (0x300UL) /*!< BUSY_I2C (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SPI2_Pos (6UL) /*!< BUSY_SPI2 (Bit 6) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SPI2_Msk (0xc0UL) /*!< BUSY_SPI2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SPI_Pos (4UL) /*!< BUSY_SPI (Bit 4) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_SPI_Msk (0x30UL) /*!< BUSY_SPI (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_UART2_Pos (2UL) /*!< BUSY_UART2 (Bit 2) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_UART2_Msk (0xcUL) /*!< BUSY_UART2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_UART_Pos (0UL) /*!< BUSY_UART (Bit 0) */ +#define MEMCTRL_BUSY_SET_REG_BUSY_UART_Msk (0x3UL) /*!< BUSY_UART (Bitfield-Mask: 0x03) */ +/* ===================================================== BUSY_STAT_REG ===================================================== */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SPARE_Pos (30UL) /*!< BUSY_SPARE (Bit 30) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SPARE_Msk (0xc0000000UL) /*!< BUSY_SPARE (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_MOTOR_Pos (28UL) /*!< BUSY_MOTOR (Bit 28) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_MOTOR_Msk (0x30000000UL) /*!< BUSY_MOTOR (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_TIMER2_Pos (26UL) /*!< BUSY_TIMER2 (Bit 26) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_TIMER2_Msk (0xc000000UL) /*!< BUSY_TIMER2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_TIMER_Pos (24UL) /*!< BUSY_TIMER (Bit 24) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_TIMER_Msk (0x3000000UL) /*!< BUSY_TIMER (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_UART3_Pos (22UL) /*!< BUSY_UART3 (Bit 22) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_UART3_Msk (0xc00000UL) /*!< BUSY_UART3 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_GPADC_Pos (20UL) /*!< BUSY_GPADC (Bit 20) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_GPADC_Msk (0x300000UL) /*!< BUSY_GPADC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_PDM_Pos (18UL) /*!< BUSY_PDM (Bit 18) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_PDM_Msk (0xc0000UL) /*!< BUSY_PDM (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SRC_Pos (16UL) /*!< BUSY_SRC (Bit 16) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SRC_Msk (0x30000UL) /*!< BUSY_SRC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_PCM_Pos (14UL) /*!< BUSY_PCM (Bit 14) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_PCM_Msk (0xc000UL) /*!< BUSY_PCM (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SDADC_Pos (12UL) /*!< BUSY_SDADC (Bit 12) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SDADC_Msk (0x3000UL) /*!< BUSY_SDADC (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_I2C2_Pos (10UL) /*!< BUSY_I2C2 (Bit 10) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_I2C2_Msk (0xc00UL) /*!< BUSY_I2C2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_I2C_Pos (8UL) /*!< BUSY_I2C (Bit 8) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_I2C_Msk (0x300UL) /*!< BUSY_I2C (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SPI2_Pos (6UL) /*!< BUSY_SPI2 (Bit 6) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SPI2_Msk (0xc0UL) /*!< BUSY_SPI2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SPI_Pos (4UL) /*!< BUSY_SPI (Bit 4) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_SPI_Msk (0x30UL) /*!< BUSY_SPI (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_UART2_Pos (2UL) /*!< BUSY_UART2 (Bit 2) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_UART2_Msk (0xcUL) /*!< BUSY_UART2 (Bitfield-Mask: 0x03) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_UART_Pos (0UL) /*!< BUSY_UART (Bit 0) */ +#define MEMCTRL_BUSY_STAT_REG_BUSY_UART_Msk (0x3UL) /*!< BUSY_UART (Bitfield-Mask: 0x03) */ +/* =================================================== CMI_CODE_BASE_REG =================================================== */ +#define MEMCTRL_CMI_CODE_BASE_REG_CMI_CODE_BASE_ADDR_Pos (10UL) /*!< CMI_CODE_BASE_ADDR (Bit 10) */ +#define MEMCTRL_CMI_CODE_BASE_REG_CMI_CODE_BASE_ADDR_Msk (0x7fc00UL) /*!< CMI_CODE_BASE_ADDR (Bitfield-Mask: 0x1ff) */ +/* =================================================== CMI_DATA_BASE_REG =================================================== */ +#define MEMCTRL_CMI_DATA_BASE_REG_CMI_DATA_BASE_ADDR_Pos (2UL) /*!< CMI_DATA_BASE_ADDR (Bit 2) */ +#define MEMCTRL_CMI_DATA_BASE_REG_CMI_DATA_BASE_ADDR_Msk (0x7fffcUL) /*!< CMI_DATA_BASE_ADDR (Bitfield-Mask: 0x1ffff) */ +/* ====================================================== CMI_END_REG ====================================================== */ +#define MEMCTRL_CMI_END_REG_CMI_END_ADDR_Pos (10UL) /*!< CMI_END_ADDR (Bit 10) */ +#define MEMCTRL_CMI_END_REG_CMI_END_ADDR_Msk (0x7fc00UL) /*!< CMI_END_ADDR (Bitfield-Mask: 0x1ff) */ +/* ================================================== CMI_SHARED_BASE_REG ================================================== */ +#define MEMCTRL_CMI_SHARED_BASE_REG_CMI_SHARED_BASE_ADDR_Pos (10UL) /*!< CMI_SHARED_BASE_ADDR (Bit 10) */ +#define MEMCTRL_CMI_SHARED_BASE_REG_CMI_SHARED_BASE_ADDR_Msk (0x7fc00UL) /*!< CMI_SHARED_BASE_ADDR (Bitfield-Mask: 0x1ff) */ +/* ===================================================== MEM_PRIO_REG ====================================================== */ +#define MEMCTRL_MEM_PRIO_REG_AHB_PRIO_Pos (4UL) /*!< AHB_PRIO (Bit 4) */ +#define MEMCTRL_MEM_PRIO_REG_AHB_PRIO_Msk (0x30UL) /*!< AHB_PRIO (Bitfield-Mask: 0x03) */ +#define MEMCTRL_MEM_PRIO_REG_AHB2_PRIO_Pos (2UL) /*!< AHB2_PRIO (Bit 2) */ +#define MEMCTRL_MEM_PRIO_REG_AHB2_PRIO_Msk (0xcUL) /*!< AHB2_PRIO (Bitfield-Mask: 0x03) */ +#define MEMCTRL_MEM_PRIO_REG_SNC_PRIO_Pos (0UL) /*!< SNC_PRIO (Bit 0) */ +#define MEMCTRL_MEM_PRIO_REG_SNC_PRIO_Msk (0x3UL) /*!< SNC_PRIO (Bitfield-Mask: 0x03) */ +/* ===================================================== MEM_STALL_REG ===================================================== */ +#define MEMCTRL_MEM_STALL_REG_AHB_MAX_STALL_Pos (8UL) /*!< AHB_MAX_STALL (Bit 8) */ +#define MEMCTRL_MEM_STALL_REG_AHB_MAX_STALL_Msk (0xf00UL) /*!< AHB_MAX_STALL (Bitfield-Mask: 0x0f) */ +#define MEMCTRL_MEM_STALL_REG_AHB2_MAX_STALL_Pos (4UL) /*!< AHB2_MAX_STALL (Bit 4) */ +#define MEMCTRL_MEM_STALL_REG_AHB2_MAX_STALL_Msk (0xf0UL) /*!< AHB2_MAX_STALL (Bitfield-Mask: 0x0f) */ +#define MEMCTRL_MEM_STALL_REG_SNC_MAX_STALL_Pos (0UL) /*!< SNC_MAX_STALL (Bit 0) */ +#define MEMCTRL_MEM_STALL_REG_SNC_MAX_STALL_Msk (0xfUL) /*!< SNC_MAX_STALL (Bitfield-Mask: 0x0f) */ +/* ==================================================== MEM_STATUS2_REG ==================================================== */ +#define MEMCTRL_MEM_STATUS2_REG_RAM8_OFF_BUT_ACCESS_Pos (7UL) /*!< RAM8_OFF_BUT_ACCESS (Bit 7) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM8_OFF_BUT_ACCESS_Msk (0x80UL) /*!< RAM8_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM7_OFF_BUT_ACCESS_Pos (6UL) /*!< RAM7_OFF_BUT_ACCESS (Bit 6) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM7_OFF_BUT_ACCESS_Msk (0x40UL) /*!< RAM7_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM6_OFF_BUT_ACCESS_Pos (5UL) /*!< RAM6_OFF_BUT_ACCESS (Bit 5) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM6_OFF_BUT_ACCESS_Msk (0x20UL) /*!< RAM6_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM5_OFF_BUT_ACCESS_Pos (4UL) /*!< RAM5_OFF_BUT_ACCESS (Bit 4) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM5_OFF_BUT_ACCESS_Msk (0x10UL) /*!< RAM5_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM4_OFF_BUT_ACCESS_Pos (3UL) /*!< RAM4_OFF_BUT_ACCESS (Bit 3) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM4_OFF_BUT_ACCESS_Msk (0x8UL) /*!< RAM4_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM3_OFF_BUT_ACCESS_Pos (2UL) /*!< RAM3_OFF_BUT_ACCESS (Bit 2) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM3_OFF_BUT_ACCESS_Msk (0x4UL) /*!< RAM3_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM2_OFF_BUT_ACCESS_Pos (1UL) /*!< RAM2_OFF_BUT_ACCESS (Bit 1) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM2_OFF_BUT_ACCESS_Msk (0x2UL) /*!< RAM2_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM1_OFF_BUT_ACCESS_Pos (0UL) /*!< RAM1_OFF_BUT_ACCESS (Bit 0) */ +#define MEMCTRL_MEM_STATUS2_REG_RAM1_OFF_BUT_ACCESS_Msk (0x1UL) /*!< RAM1_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ +/* ==================================================== MEM_STATUS_REG ===================================================== */ +#define MEMCTRL_MEM_STATUS_REG_CMI_CLEAR_READY_Pos (13UL) /*!< CMI_CLEAR_READY (Bit 13) */ +#define MEMCTRL_MEM_STATUS_REG_CMI_CLEAR_READY_Msk (0x2000UL) /*!< CMI_CLEAR_READY (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS_REG_CMI_NOT_READY_Pos (12UL) /*!< CMI_NOT_READY (Bit 12) */ +#define MEMCTRL_MEM_STATUS_REG_CMI_NOT_READY_Msk (0x1000UL) /*!< CMI_NOT_READY (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS_REG_AHB2_WR_BUFF_CNT_Pos (8UL) /*!< AHB2_WR_BUFF_CNT (Bit 8) */ +#define MEMCTRL_MEM_STATUS_REG_AHB2_WR_BUFF_CNT_Msk (0xf00UL) /*!< AHB2_WR_BUFF_CNT (Bitfield-Mask: 0x0f) */ +#define MEMCTRL_MEM_STATUS_REG_AHB_WR_BUFF_CNT_Pos (4UL) /*!< AHB_WR_BUFF_CNT (Bit 4) */ +#define MEMCTRL_MEM_STATUS_REG_AHB_WR_BUFF_CNT_Msk (0xf0UL) /*!< AHB_WR_BUFF_CNT (Bitfield-Mask: 0x0f) */ +#define MEMCTRL_MEM_STATUS_REG_AHB2_CLR_WR_BUFF_Pos (3UL) /*!< AHB2_CLR_WR_BUFF (Bit 3) */ +#define MEMCTRL_MEM_STATUS_REG_AHB2_CLR_WR_BUFF_Msk (0x8UL) /*!< AHB2_CLR_WR_BUFF (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS_REG_AHB_CLR_WR_BUFF_Pos (2UL) /*!< AHB_CLR_WR_BUFF (Bit 2) */ +#define MEMCTRL_MEM_STATUS_REG_AHB_CLR_WR_BUFF_Msk (0x4UL) /*!< AHB_CLR_WR_BUFF (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS_REG_AHB2_WRITE_BUFF_Pos (1UL) /*!< AHB2_WRITE_BUFF (Bit 1) */ +#define MEMCTRL_MEM_STATUS_REG_AHB2_WRITE_BUFF_Msk (0x2UL) /*!< AHB2_WRITE_BUFF (Bitfield-Mask: 0x01) */ +#define MEMCTRL_MEM_STATUS_REG_AHB_WRITE_BUFF_Pos (0UL) /*!< AHB_WRITE_BUFF (Bit 0) */ +#define MEMCTRL_MEM_STATUS_REG_AHB_WRITE_BUFF_Msk (0x1UL) /*!< AHB_WRITE_BUFF (Bitfield-Mask: 0x01) */ +/* ===================================================== SNC_BASE_REG ====================================================== */ +#define MEMCTRL_SNC_BASE_REG_SNC_BASE_ADDRESS_Pos (2UL) /*!< SNC_BASE_ADDRESS (Bit 2) */ +#define MEMCTRL_SNC_BASE_REG_SNC_BASE_ADDRESS_Msk (0x7fffcUL) /*!< SNC_BASE_ADDRESS (Bitfield-Mask: 0x1ffff) */ + + +/* =========================================================================================================================== */ +/* ================ OTPC ================ */ +/* =========================================================================================================================== */ + +/* ===================================================== OTPC_MODE_REG ===================================================== */ +#define OTPC_OTPC_MODE_REG_OTPC_MODE_PRG_SEL_Pos (6UL) /*!< OTPC_MODE_PRG_SEL (Bit 6) */ +#define OTPC_OTPC_MODE_REG_OTPC_MODE_PRG_SEL_Msk (0xc0UL) /*!< OTPC_MODE_PRG_SEL (Bitfield-Mask: 0x03) */ +#define OTPC_OTPC_MODE_REG_OTPC_MODE_HT_MARG_EN_Pos (5UL) /*!< OTPC_MODE_HT_MARG_EN (Bit 5) */ +#define OTPC_OTPC_MODE_REG_OTPC_MODE_HT_MARG_EN_Msk (0x20UL) /*!< OTPC_MODE_HT_MARG_EN (Bitfield-Mask: 0x01) */ +#define OTPC_OTPC_MODE_REG_OTPC_MODE_USE_TST_ROW_Pos (4UL) /*!< OTPC_MODE_USE_TST_ROW (Bit 4) */ +#define OTPC_OTPC_MODE_REG_OTPC_MODE_USE_TST_ROW_Msk (0x10UL) /*!< OTPC_MODE_USE_TST_ROW (Bitfield-Mask: 0x01) */ +#define OTPC_OTPC_MODE_REG_OTPC_MODE_MODE_Pos (0UL) /*!< OTPC_MODE_MODE (Bit 0) */ +#define OTPC_OTPC_MODE_REG_OTPC_MODE_MODE_Msk (0x7UL) /*!< OTPC_MODE_MODE (Bitfield-Mask: 0x07) */ +/* ==================================================== OTPC_PADDR_REG ===================================================== */ +#define OTPC_OTPC_PADDR_REG_OTPC_PADDR_Pos (0UL) /*!< OTPC_PADDR (Bit 0) */ +#define OTPC_OTPC_PADDR_REG_OTPC_PADDR_Msk (0x3ffUL) /*!< OTPC_PADDR (Bitfield-Mask: 0x3ff) */ +/* ==================================================== OTPC_PWORD_REG ===================================================== */ +#define OTPC_OTPC_PWORD_REG_OTPC_PWORD_Pos (0UL) /*!< OTPC_PWORD (Bit 0) */ +#define OTPC_OTPC_PWORD_REG_OTPC_PWORD_Msk (0xffffffffUL) /*!< OTPC_PWORD (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== OTPC_STAT_REG ===================================================== */ +#define OTPC_OTPC_STAT_REG_OTPC_STAT_MRDY_Pos (2UL) /*!< OTPC_STAT_MRDY (Bit 2) */ +#define OTPC_OTPC_STAT_REG_OTPC_STAT_MRDY_Msk (0x4UL) /*!< OTPC_STAT_MRDY (Bitfield-Mask: 0x01) */ +#define OTPC_OTPC_STAT_REG_OTPC_STAT_PBUF_EMPTY_Pos (1UL) /*!< OTPC_STAT_PBUF_EMPTY (Bit 1) */ +#define OTPC_OTPC_STAT_REG_OTPC_STAT_PBUF_EMPTY_Msk (0x2UL) /*!< OTPC_STAT_PBUF_EMPTY (Bitfield-Mask: 0x01) */ +#define OTPC_OTPC_STAT_REG_OTPC_STAT_PRDY_Pos (0UL) /*!< OTPC_STAT_PRDY (Bit 0) */ +#define OTPC_OTPC_STAT_REG_OTPC_STAT_PRDY_Msk (0x1UL) /*!< OTPC_STAT_PRDY (Bitfield-Mask: 0x01) */ +/* ===================================================== OTPC_TIM1_REG ===================================================== */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_CSP_Pos (24UL) /*!< OTPC_TIM1_US_T_CSP (Bit 24) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_CSP_Msk (0x7f000000UL) /*!< OTPC_TIM1_US_T_CSP (Bitfield-Mask: 0x7f) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_CS_Pos (20UL) /*!< OTPC_TIM1_US_T_CS (Bit 20) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_CS_Msk (0xf00000UL) /*!< OTPC_TIM1_US_T_CS (Bitfield-Mask: 0x0f) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_PL_Pos (16UL) /*!< OTPC_TIM1_US_T_PL (Bit 16) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_PL_Msk (0xf0000UL) /*!< OTPC_TIM1_US_T_PL (Bitfield-Mask: 0x0f) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_RD_Pos (12UL) /*!< OTPC_TIM1_CC_T_RD (Bit 12) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_RD_Msk (0x7000UL) /*!< OTPC_TIM1_CC_T_RD (Bitfield-Mask: 0x07) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_20NS_Pos (8UL) /*!< OTPC_TIM1_CC_T_20NS (Bit 8) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_20NS_Msk (0x300UL) /*!< OTPC_TIM1_CC_T_20NS (Bitfield-Mask: 0x03) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos (0UL) /*!< OTPC_TIM1_CC_T_1US (Bit 0) */ +#define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Msk (0x7fUL) /*!< OTPC_TIM1_CC_T_1US (Bitfield-Mask: 0x7f) */ +/* ===================================================== OTPC_TIM2_REG ===================================================== */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_ADD_CC_EN_Pos (31UL) /*!< OTPC_TIM2_US_ADD_CC_EN (Bit 31) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_ADD_CC_EN_Msk (0x80000000UL) /*!< OTPC_TIM2_US_ADD_CC_EN (Bitfield-Mask: 0x01) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_SAS_Pos (29UL) /*!< OTPC_TIM2_US_T_SAS (Bit 29) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_SAS_Msk (0x60000000UL) /*!< OTPC_TIM2_US_T_SAS (Bitfield-Mask: 0x03) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPH_Pos (24UL) /*!< OTPC_TIM2_US_T_PPH (Bit 24) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPH_Msk (0x1f000000UL) /*!< OTPC_TIM2_US_T_PPH (Bitfield-Mask: 0x1f) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_VDS_Pos (21UL) /*!< OTPC_TIM2_US_T_VDS (Bit 21) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_VDS_Msk (0xe00000UL) /*!< OTPC_TIM2_US_T_VDS (Bitfield-Mask: 0x07) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPS_Pos (16UL) /*!< OTPC_TIM2_US_T_PPS (Bit 16) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPS_Msk (0x1f0000UL) /*!< OTPC_TIM2_US_T_PPS (Bitfield-Mask: 0x1f) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPR_Pos (8UL) /*!< OTPC_TIM2_US_T_PPR (Bit 8) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPR_Msk (0x7f00UL) /*!< OTPC_TIM2_US_T_PPR (Bitfield-Mask: 0x7f) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PWI_Pos (5UL) /*!< OTPC_TIM2_US_T_PWI (Bit 5) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PWI_Msk (0xe0UL) /*!< OTPC_TIM2_US_T_PWI (Bitfield-Mask: 0x07) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PW_Pos (0UL) /*!< OTPC_TIM2_US_T_PW (Bit 0) */ +#define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PW_Msk (0x1fUL) /*!< OTPC_TIM2_US_T_PW (Bitfield-Mask: 0x1f) */ + + +/* =========================================================================================================================== */ +/* ================ PDC ================ */ +/* =========================================================================================================================== */ + +/* ================================================== PDC_ACKNOWLEDGE_REG ================================================== */ +#define PDC_PDC_ACKNOWLEDGE_REG_PDC_ACKNOWLEDGE_Pos (0UL) /*!< PDC_ACKNOWLEDGE (Bit 0) */ +#define PDC_PDC_ACKNOWLEDGE_REG_PDC_ACKNOWLEDGE_Msk (0x1fUL) /*!< PDC_ACKNOWLEDGE (Bitfield-Mask: 0x1f) */ +/* ===================================================== PDC_CTRL0_REG ===================================================== */ +#define PDC_PDC_CTRL0_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL0_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL0_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL0_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL0_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL0_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL0_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL0_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL0_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL0_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL0_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL0_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL0_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL0_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ==================================================== PDC_CTRL10_REG ===================================================== */ +#define PDC_PDC_CTRL10_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL10_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL10_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL10_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL10_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL10_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL10_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL10_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL10_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL10_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL10_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL10_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL10_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL10_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ==================================================== PDC_CTRL11_REG ===================================================== */ +#define PDC_PDC_CTRL11_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL11_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL11_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL11_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL11_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL11_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL11_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL11_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL11_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL11_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL11_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL11_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL11_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL11_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ==================================================== PDC_CTRL12_REG ===================================================== */ +#define PDC_PDC_CTRL12_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL12_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL12_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL12_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL12_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL12_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL12_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL12_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL12_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL12_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL12_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL12_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL12_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL12_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ==================================================== PDC_CTRL13_REG ===================================================== */ +#define PDC_PDC_CTRL13_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL13_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL13_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL13_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL13_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL13_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL13_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL13_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL13_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL13_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL13_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL13_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL13_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL13_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ==================================================== PDC_CTRL14_REG ===================================================== */ +#define PDC_PDC_CTRL14_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL14_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL14_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL14_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL14_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL14_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL14_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL14_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL14_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL14_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL14_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL14_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL14_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL14_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ==================================================== PDC_CTRL15_REG ===================================================== */ +#define PDC_PDC_CTRL15_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL15_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL15_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL15_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL15_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL15_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL15_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL15_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL15_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL15_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL15_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL15_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL15_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL15_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL1_REG ===================================================== */ +#define PDC_PDC_CTRL1_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL1_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL1_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL1_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL1_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL1_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL1_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL1_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL1_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL1_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL1_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL1_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL1_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL1_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL2_REG ===================================================== */ +#define PDC_PDC_CTRL2_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL2_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL2_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL2_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL2_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL2_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL2_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL2_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL2_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL2_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL2_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL2_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL2_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL2_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL3_REG ===================================================== */ +#define PDC_PDC_CTRL3_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL3_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL3_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL3_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL3_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL3_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL3_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL3_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL3_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL3_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL3_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL3_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL3_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL3_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL4_REG ===================================================== */ +#define PDC_PDC_CTRL4_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL4_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL4_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL4_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL4_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL4_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL4_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL4_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL4_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL4_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL4_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL4_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL4_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL4_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL5_REG ===================================================== */ +#define PDC_PDC_CTRL5_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL5_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL5_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL5_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL5_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL5_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL5_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL5_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL5_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL5_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL5_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL5_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL5_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL5_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL6_REG ===================================================== */ +#define PDC_PDC_CTRL6_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL6_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL6_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL6_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL6_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL6_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL6_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL6_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL6_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL6_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL6_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL6_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL6_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL6_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL7_REG ===================================================== */ +#define PDC_PDC_CTRL7_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL7_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL7_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL7_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL7_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL7_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL7_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL7_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL7_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL7_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL7_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL7_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL7_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL7_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL8_REG ===================================================== */ +#define PDC_PDC_CTRL8_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL8_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL8_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL8_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL8_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL8_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL8_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL8_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL8_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL8_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL8_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL8_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL8_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL8_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ===================================================== PDC_CTRL9_REG ===================================================== */ +#define PDC_PDC_CTRL9_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ +#define PDC_PDC_CTRL9_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ +#define PDC_PDC_CTRL9_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ +#define PDC_PDC_CTRL9_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL9_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ +#define PDC_PDC_CTRL9_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL9_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ +#define PDC_PDC_CTRL9_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL9_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ +#define PDC_PDC_CTRL9_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ +#define PDC_PDC_CTRL9_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ +#define PDC_PDC_CTRL9_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ +#define PDC_PDC_CTRL9_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ +#define PDC_PDC_CTRL9_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ +/* ================================================= PDC_PENDING_CM33_REG ================================================== */ +#define PDC_PDC_PENDING_CM33_REG_PDC_PENDING_Pos (0UL) /*!< PDC_PENDING (Bit 0) */ +#define PDC_PDC_PENDING_CM33_REG_PDC_PENDING_Msk (0xffffUL) /*!< PDC_PENDING (Bitfield-Mask: 0xffff) */ +/* ================================================= PDC_PENDING_CMAC_REG ================================================== */ +#define PDC_PDC_PENDING_CMAC_REG_PDC_PENDING_Pos (0UL) /*!< PDC_PENDING (Bit 0) */ +#define PDC_PDC_PENDING_CMAC_REG_PDC_PENDING_Msk (0xffffUL) /*!< PDC_PENDING (Bitfield-Mask: 0xffff) */ +/* ==================================================== PDC_PENDING_REG ==================================================== */ +#define PDC_PDC_PENDING_REG_PDC_PENDING_Pos (0UL) /*!< PDC_PENDING (Bit 0) */ +#define PDC_PDC_PENDING_REG_PDC_PENDING_Msk (0xffffUL) /*!< PDC_PENDING (Bitfield-Mask: 0xffff) */ +/* ================================================== PDC_PENDING_SNC_REG ================================================== */ +#define PDC_PDC_PENDING_SNC_REG_PDC_PENDING_Pos (0UL) /*!< PDC_PENDING (Bit 0) */ +#define PDC_PDC_PENDING_SNC_REG_PDC_PENDING_Msk (0xffffUL) /*!< PDC_PENDING (Bitfield-Mask: 0xffff) */ +/* ================================================== PDC_SET_PENDING_REG ================================================== */ +#define PDC_PDC_SET_PENDING_REG_PDC_SET_PENDING_Pos (0UL) /*!< PDC_SET_PENDING (Bit 0) */ +#define PDC_PDC_SET_PENDING_REG_PDC_SET_PENDING_Msk (0x1fUL) /*!< PDC_SET_PENDING (Bitfield-Mask: 0x1f) */ + + +/* =========================================================================================================================== */ +/* ================ PWMLED ================ */ +/* =========================================================================================================================== */ + +/* ==================================================== PWMLED_CTRL_REG ==================================================== */ +#define PWMLED_PWMLED_CTRL_REG_LED2_LOAD_SEL_Pos (11UL) /*!< LED2_LOAD_SEL (Bit 11) */ +#define PWMLED_PWMLED_CTRL_REG_LED2_LOAD_SEL_Msk (0x3800UL) /*!< LED2_LOAD_SEL (Bitfield-Mask: 0x07) */ +#define PWMLED_PWMLED_CTRL_REG_LED1_LOAD_SEL_Pos (8UL) /*!< LED1_LOAD_SEL (Bit 8) */ +#define PWMLED_PWMLED_CTRL_REG_LED1_LOAD_SEL_Msk (0x700UL) /*!< LED1_LOAD_SEL (Bitfield-Mask: 0x07) */ +#define PWMLED_PWMLED_CTRL_REG_LED2_EN_Pos (7UL) /*!< LED2_EN (Bit 7) */ +#define PWMLED_PWMLED_CTRL_REG_LED2_EN_Msk (0x80UL) /*!< LED2_EN (Bitfield-Mask: 0x01) */ +#define PWMLED_PWMLED_CTRL_REG_LED1_EN_Pos (6UL) /*!< LED1_EN (Bit 6) */ +#define PWMLED_PWMLED_CTRL_REG_LED1_EN_Msk (0x40UL) /*!< LED1_EN (Bitfield-Mask: 0x01) */ +#define PWMLED_PWMLED_CTRL_REG_LED_TRIM_Pos (2UL) /*!< LED_TRIM (Bit 2) */ +#define PWMLED_PWMLED_CTRL_REG_LED_TRIM_Msk (0x3cUL) /*!< LED_TRIM (Bitfield-Mask: 0x0f) */ +#define PWMLED_PWMLED_CTRL_REG_SW_PAUSE_EN_Pos (1UL) /*!< SW_PAUSE_EN (Bit 1) */ +#define PWMLED_PWMLED_CTRL_REG_SW_PAUSE_EN_Msk (0x2UL) /*!< SW_PAUSE_EN (Bitfield-Mask: 0x01) */ +#define PWMLED_PWMLED_CTRL_REG_PWM_ENABLE_Pos (0UL) /*!< PWM_ENABLE (Bit 0) */ +#define PWMLED_PWMLED_CTRL_REG_PWM_ENABLE_Msk (0x1UL) /*!< PWM_ENABLE (Bitfield-Mask: 0x01) */ +/* ============================================== PWMLED_DUTY_CYCLE_LED1_REG =============================================== */ +#define PWMLED_PWMLED_DUTY_CYCLE_LED1_REG_LED1_PWM_START_CYCLE_Pos (8UL) /*!< LED1_PWM_START_CYCLE (Bit 8) */ +#define PWMLED_PWMLED_DUTY_CYCLE_LED1_REG_LED1_PWM_START_CYCLE_Msk (0xff00UL) /*!< LED1_PWM_START_CYCLE (Bitfield-Mask: 0xff) */ +#define PWMLED_PWMLED_DUTY_CYCLE_LED1_REG_LED1_PWM_END_CYCLE_Pos (0UL) /*!< LED1_PWM_END_CYCLE (Bit 0) */ +#define PWMLED_PWMLED_DUTY_CYCLE_LED1_REG_LED1_PWM_END_CYCLE_Msk (0xffUL) /*!< LED1_PWM_END_CYCLE (Bitfield-Mask: 0xff) */ +/* ============================================== PWMLED_DUTY_CYCLE_LED2_REG =============================================== */ +#define PWMLED_PWMLED_DUTY_CYCLE_LED2_REG_LED2_PWM_START_CYCLE_Pos (8UL) /*!< LED2_PWM_START_CYCLE (Bit 8) */ +#define PWMLED_PWMLED_DUTY_CYCLE_LED2_REG_LED2_PWM_START_CYCLE_Msk (0xff00UL) /*!< LED2_PWM_START_CYCLE (Bitfield-Mask: 0xff) */ +#define PWMLED_PWMLED_DUTY_CYCLE_LED2_REG_LED2_PWM_END_CYCLE_Pos (0UL) /*!< LED2_PWM_END_CYCLE (Bit 0) */ +#define PWMLED_PWMLED_DUTY_CYCLE_LED2_REG_LED2_PWM_END_CYCLE_Msk (0xffUL) /*!< LED2_PWM_END_CYCLE (Bitfield-Mask: 0xff) */ +/* ================================================= PWMLED_FREQUENCY_REG ================================================== */ +#define PWMLED_PWMLED_FREQUENCY_REG_LED_PWM_FREQUENCY_Pos (0UL) /*!< LED_PWM_FREQUENCY (Bit 0) */ +#define PWMLED_PWMLED_FREQUENCY_REG_LED_PWM_FREQUENCY_Msk (0xffUL) /*!< LED_PWM_FREQUENCY (Bitfield-Mask: 0xff) */ + + +/* =========================================================================================================================== */ +/* ================ QSPIC ================ */ +/* =========================================================================================================================== */ + +/* ================================================== QSPIC_BURSTBRK_REG =================================================== */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_SEC_HF_DS_Pos (20UL) /*!< QSPIC_SEC_HF_DS (Bit 20) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_SEC_HF_DS_Msk (0x100000UL) /*!< QSPIC_SEC_HF_DS (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_TX_MD_Pos (18UL) /*!< QSPIC_BRK_TX_MD (Bit 18) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_TX_MD_Msk (0xc0000UL) /*!< QSPIC_BRK_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_SZ_Pos (17UL) /*!< QSPIC_BRK_SZ (Bit 17) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_SZ_Msk (0x20000UL) /*!< QSPIC_BRK_SZ (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_EN_Pos (16UL) /*!< QSPIC_BRK_EN (Bit 16) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_EN_Msk (0x10000UL) /*!< QSPIC_BRK_EN (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_WRD_Pos (0UL) /*!< QSPIC_BRK_WRD (Bit 0) */ +#define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_WRD_Msk (0xffffUL) /*!< QSPIC_BRK_WRD (Bitfield-Mask: 0xffff) */ +/* ================================================== QSPIC_BURSTCMDA_REG ================================================== */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_DMY_TX_MD_Pos (30UL) /*!< QSPIC_DMY_TX_MD (Bit 30) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_DMY_TX_MD_Msk (0xc0000000UL) /*!< QSPIC_DMY_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_EXT_TX_MD_Pos (28UL) /*!< QSPIC_EXT_TX_MD (Bit 28) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_EXT_TX_MD_Msk (0x30000000UL) /*!< QSPIC_EXT_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_ADR_TX_MD_Pos (26UL) /*!< QSPIC_ADR_TX_MD (Bit 26) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_ADR_TX_MD_Msk (0xc000000UL) /*!< QSPIC_ADR_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_TX_MD_Pos (24UL) /*!< QSPIC_INST_TX_MD (Bit 24) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_TX_MD_Msk (0x3000000UL) /*!< QSPIC_INST_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_EXT_BYTE_Pos (16UL) /*!< QSPIC_EXT_BYTE (Bit 16) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_EXT_BYTE_Msk (0xff0000UL) /*!< QSPIC_EXT_BYTE (Bitfield-Mask: 0xff) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_WB_Pos (8UL) /*!< QSPIC_INST_WB (Bit 8) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_WB_Msk (0xff00UL) /*!< QSPIC_INST_WB (Bitfield-Mask: 0xff) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_Pos (0UL) /*!< QSPIC_INST (Bit 0) */ +#define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_Msk (0xffUL) /*!< QSPIC_INST (Bitfield-Mask: 0xff) */ +/* ================================================== QSPIC_BURSTCMDB_REG ================================================== */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DMY_FORCE_Pos (15UL) /*!< QSPIC_DMY_FORCE (Bit 15) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DMY_FORCE_Msk (0x8000UL) /*!< QSPIC_DMY_FORCE (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Pos (12UL) /*!< QSPIC_CS_HIGH_MIN (Bit 12) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Msk (0x7000UL) /*!< QSPIC_CS_HIGH_MIN (Bitfield-Mask: 0x07) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_SIZE_Pos (10UL) /*!< QSPIC_WRAP_SIZE (Bit 10) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_SIZE_Msk (0xc00UL) /*!< QSPIC_WRAP_SIZE (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_LEN_Pos (8UL) /*!< QSPIC_WRAP_LEN (Bit 8) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_LEN_Msk (0x300UL) /*!< QSPIC_WRAP_LEN (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_MD_Pos (7UL) /*!< QSPIC_WRAP_MD (Bit 7) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_MD_Msk (0x80UL) /*!< QSPIC_WRAP_MD (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_INST_MD_Pos (6UL) /*!< QSPIC_INST_MD (Bit 6) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_INST_MD_Msk (0x40UL) /*!< QSPIC_INST_MD (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DMY_NUM_Pos (4UL) /*!< QSPIC_DMY_NUM (Bit 4) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DMY_NUM_Msk (0x30UL) /*!< QSPIC_DMY_NUM (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_EXT_HF_DS_Pos (3UL) /*!< QSPIC_EXT_HF_DS (Bit 3) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_EXT_HF_DS_Msk (0x8UL) /*!< QSPIC_EXT_HF_DS (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_EXT_BYTE_EN_Pos (2UL) /*!< QSPIC_EXT_BYTE_EN (Bit 2) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_EXT_BYTE_EN_Msk (0x4UL) /*!< QSPIC_EXT_BYTE_EN (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DAT_RX_MD_Pos (0UL) /*!< QSPIC_DAT_RX_MD (Bit 0) */ +#define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DAT_RX_MD_Msk (0x3UL) /*!< QSPIC_DAT_RX_MD (Bitfield-Mask: 0x03) */ +/* ================================================== QSPIC_CHCKERASE_REG ================================================== */ +#define QSPIC_QSPIC_CHCKERASE_REG_QSPIC_CHCKERASE_Pos (0UL) /*!< QSPIC_CHCKERASE (Bit 0) */ +#define QSPIC_QSPIC_CHCKERASE_REG_QSPIC_CHCKERASE_Msk (0xffffffffUL) /*!< QSPIC_CHCKERASE (Bitfield-Mask: 0xffffffff) */ +/* =================================================== QSPIC_CTRLBUS_REG =================================================== */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_DIS_CS_Pos (4UL) /*!< QSPIC_DIS_CS (Bit 4) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_DIS_CS_Msk (0x10UL) /*!< QSPIC_DIS_CS (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_EN_CS_Pos (3UL) /*!< QSPIC_EN_CS (Bit 3) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_EN_CS_Msk (0x8UL) /*!< QSPIC_EN_CS (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_QUAD_Pos (2UL) /*!< QSPIC_SET_QUAD (Bit 2) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_QUAD_Msk (0x4UL) /*!< QSPIC_SET_QUAD (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_DUAL_Pos (1UL) /*!< QSPIC_SET_DUAL (Bit 1) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_DUAL_Msk (0x2UL) /*!< QSPIC_SET_DUAL (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_SINGLE_Pos (0UL) /*!< QSPIC_SET_SINGLE (Bit 0) */ +#define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_SINGLE_Msk (0x1UL) /*!< QSPIC_SET_SINGLE (Bitfield-Mask: 0x01) */ +/* ================================================== QSPIC_CTRLMODE_REG =================================================== */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_USE_32BA_Pos (13UL) /*!< QSPIC_USE_32BA (Bit 13) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_USE_32BA_Msk (0x2000UL) /*!< QSPIC_USE_32BA (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_BUF_LIM_EN_Pos (12UL) /*!< QSPIC_BUF_LIM_EN (Bit 12) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_BUF_LIM_EN_Msk (0x1000UL) /*!< QSPIC_BUF_LIM_EN (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_PCLK_MD_Pos (9UL) /*!< QSPIC_PCLK_MD (Bit 9) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_PCLK_MD_Msk (0xe00UL) /*!< QSPIC_PCLK_MD (Bitfield-Mask: 0x07) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RPIPE_EN_Pos (8UL) /*!< QSPIC_RPIPE_EN (Bit 8) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RPIPE_EN_Msk (0x100UL) /*!< QSPIC_RPIPE_EN (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RXD_NEG_Pos (7UL) /*!< QSPIC_RXD_NEG (Bit 7) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RXD_NEG_Msk (0x80UL) /*!< QSPIC_RXD_NEG (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_HRDY_MD_Pos (6UL) /*!< QSPIC_HRDY_MD (Bit 6) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_HRDY_MD_Msk (0x40UL) /*!< QSPIC_HRDY_MD (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO3_DAT_Pos (5UL) /*!< QSPIC_IO3_DAT (Bit 5) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO3_DAT_Msk (0x20UL) /*!< QSPIC_IO3_DAT (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO2_DAT_Pos (4UL) /*!< QSPIC_IO2_DAT (Bit 4) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO2_DAT_Msk (0x10UL) /*!< QSPIC_IO2_DAT (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO3_OEN_Pos (3UL) /*!< QSPIC_IO3_OEN (Bit 3) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO3_OEN_Msk (0x8UL) /*!< QSPIC_IO3_OEN (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO2_OEN_Pos (2UL) /*!< QSPIC_IO2_OEN (Bit 2) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO2_OEN_Msk (0x4UL) /*!< QSPIC_IO2_OEN (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_CLK_MD_Pos (1UL) /*!< QSPIC_CLK_MD (Bit 1) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_CLK_MD_Msk (0x2UL) /*!< QSPIC_CLK_MD (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_AUTO_MD_Pos (0UL) /*!< QSPIC_AUTO_MD (Bit 0) */ +#define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_AUTO_MD_Msk (0x1UL) /*!< QSPIC_AUTO_MD (Bitfield-Mask: 0x01) */ +/* ================================================== QSPIC_CTR_CTRL_REG =================================================== */ +#define QSPIC_QSPIC_CTR_CTRL_REG_QSPIC_CTR_EN_Pos (0UL) /*!< QSPIC_CTR_EN (Bit 0) */ +#define QSPIC_QSPIC_CTR_CTRL_REG_QSPIC_CTR_EN_Msk (0x1UL) /*!< QSPIC_CTR_EN (Bitfield-Mask: 0x01) */ +/* ================================================== QSPIC_CTR_EADDR_REG ================================================== */ +#define QSPIC_QSPIC_CTR_EADDR_REG_QSPIC_CTR_EADDR_Pos (10UL) /*!< QSPIC_CTR_EADDR (Bit 10) */ +#define QSPIC_QSPIC_CTR_EADDR_REG_QSPIC_CTR_EADDR_Msk (0xfffffc00UL) /*!< QSPIC_CTR_EADDR (Bitfield-Mask: 0x3fffff) */ +/* ================================================= QSPIC_CTR_KEY_0_3_REG ================================================= */ +#define QSPIC_QSPIC_CTR_KEY_0_3_REG_QSPIC_CTR_KEY_0_3_Pos (0UL) /*!< QSPIC_CTR_KEY_0_3 (Bit 0) */ +#define QSPIC_QSPIC_CTR_KEY_0_3_REG_QSPIC_CTR_KEY_0_3_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_0_3 (Bitfield-Mask: 0xffffffff) */ +/* ================================================ QSPIC_CTR_KEY_12_15_REG ================================================ */ +#define QSPIC_QSPIC_CTR_KEY_12_15_REG_QSPIC_CTR_KEY_12_15_Pos (0UL) /*!< QSPIC_CTR_KEY_12_15 (Bit 0) */ +#define QSPIC_QSPIC_CTR_KEY_12_15_REG_QSPIC_CTR_KEY_12_15_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_12_15 (Bitfield-Mask: 0xffffffff) */ +/* ================================================ QSPIC_CTR_KEY_16_19_REG ================================================ */ +#define QSPIC_QSPIC_CTR_KEY_16_19_REG_QSPIC_CTR_KEY_16_19_Pos (0UL) /*!< QSPIC_CTR_KEY_16_19 (Bit 0) */ +#define QSPIC_QSPIC_CTR_KEY_16_19_REG_QSPIC_CTR_KEY_16_19_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_16_19 (Bitfield-Mask: 0xffffffff) */ +/* ================================================ QSPIC_CTR_KEY_20_23_REG ================================================ */ +#define QSPIC_QSPIC_CTR_KEY_20_23_REG_QSPIC_CTR_KEY_20_23_Pos (0UL) /*!< QSPIC_CTR_KEY_20_23 (Bit 0) */ +#define QSPIC_QSPIC_CTR_KEY_20_23_REG_QSPIC_CTR_KEY_20_23_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_20_23 (Bitfield-Mask: 0xffffffff) */ +/* ================================================ QSPIC_CTR_KEY_24_27_REG ================================================ */ +#define QSPIC_QSPIC_CTR_KEY_24_27_REG_QSPIC_CTR_KEY_24_27_Pos (0UL) /*!< QSPIC_CTR_KEY_24_27 (Bit 0) */ +#define QSPIC_QSPIC_CTR_KEY_24_27_REG_QSPIC_CTR_KEY_24_27_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_24_27 (Bitfield-Mask: 0xffffffff) */ +/* ================================================ QSPIC_CTR_KEY_28_31_REG ================================================ */ +#define QSPIC_QSPIC_CTR_KEY_28_31_REG_QSPIC_CTR_KEY_28_31_Pos (0UL) /*!< QSPIC_CTR_KEY_28_31 (Bit 0) */ +#define QSPIC_QSPIC_CTR_KEY_28_31_REG_QSPIC_CTR_KEY_28_31_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_28_31 (Bitfield-Mask: 0xffffffff) */ +/* ================================================= QSPIC_CTR_KEY_4_7_REG ================================================= */ +#define QSPIC_QSPIC_CTR_KEY_4_7_REG_QSPIC_CTR_KEY_4_7_Pos (0UL) /*!< QSPIC_CTR_KEY_4_7 (Bit 0) */ +#define QSPIC_QSPIC_CTR_KEY_4_7_REG_QSPIC_CTR_KEY_4_7_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_4_7 (Bitfield-Mask: 0xffffffff) */ +/* ================================================ QSPIC_CTR_KEY_8_11_REG ================================================= */ +#define QSPIC_QSPIC_CTR_KEY_8_11_REG_QSPIC_CTR_KEY_8_11_Pos (0UL) /*!< QSPIC_CTR_KEY_8_11 (Bit 0) */ +#define QSPIC_QSPIC_CTR_KEY_8_11_REG_QSPIC_CTR_KEY_8_11_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_8_11 (Bitfield-Mask: 0xffffffff) */ +/* ================================================ QSPIC_CTR_NONCE_0_3_REG ================================================ */ +#define QSPIC_QSPIC_CTR_NONCE_0_3_REG_QSPIC_CTR_NONCE_0_3_Pos (0UL) /*!< QSPIC_CTR_NONCE_0_3 (Bit 0) */ +#define QSPIC_QSPIC_CTR_NONCE_0_3_REG_QSPIC_CTR_NONCE_0_3_Msk (0xffffffffUL) /*!< QSPIC_CTR_NONCE_0_3 (Bitfield-Mask: 0xffffffff) */ +/* ================================================ QSPIC_CTR_NONCE_4_7_REG ================================================ */ +#define QSPIC_QSPIC_CTR_NONCE_4_7_REG_QSPIC_CTR_NONCE_4_7_Pos (0UL) /*!< QSPIC_CTR_NONCE_4_7 (Bit 0) */ +#define QSPIC_QSPIC_CTR_NONCE_4_7_REG_QSPIC_CTR_NONCE_4_7_Msk (0xffffffffUL) /*!< QSPIC_CTR_NONCE_4_7 (Bitfield-Mask: 0xffffffff) */ +/* ================================================== QSPIC_CTR_SADDR_REG ================================================== */ +#define QSPIC_QSPIC_CTR_SADDR_REG_QSPIC_CTR_SADDR_Pos (10UL) /*!< QSPIC_CTR_SADDR (Bit 10) */ +#define QSPIC_QSPIC_CTR_SADDR_REG_QSPIC_CTR_SADDR_Msk (0xfffffc00UL) /*!< QSPIC_CTR_SADDR (Bitfield-Mask: 0x3fffff) */ +/* ================================================== QSPIC_DUMMYDATA_REG ================================================== */ +#define QSPIC_QSPIC_DUMMYDATA_REG_QSPIC_DUMMYDATA_Pos (0UL) /*!< QSPIC_DUMMYDATA (Bit 0) */ +#define QSPIC_QSPIC_DUMMYDATA_REG_QSPIC_DUMMYDATA_Msk (0xffffffffUL) /*!< QSPIC_DUMMYDATA (Bitfield-Mask: 0xffffffff) */ +/* ================================================== QSPIC_ERASECMDA_REG ================================================== */ +#define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_RES_INST_Pos (24UL) /*!< QSPIC_RES_INST (Bit 24) */ +#define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_RES_INST_Msk (0xff000000UL) /*!< QSPIC_RES_INST (Bitfield-Mask: 0xff) */ +#define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_SUS_INST_Pos (16UL) /*!< QSPIC_SUS_INST (Bit 16) */ +#define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_SUS_INST_Msk (0xff0000UL) /*!< QSPIC_SUS_INST (Bitfield-Mask: 0xff) */ +#define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_WEN_INST_Pos (8UL) /*!< QSPIC_WEN_INST (Bit 8) */ +#define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_WEN_INST_Msk (0xff00UL) /*!< QSPIC_WEN_INST (Bitfield-Mask: 0xff) */ +#define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_ERS_INST_Pos (0UL) /*!< QSPIC_ERS_INST (Bit 0) */ +#define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_ERS_INST_Msk (0xffUL) /*!< QSPIC_ERS_INST (Bitfield-Mask: 0xff) */ +/* ================================================== QSPIC_ERASECMDB_REG ================================================== */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_RESSUS_DLY_Pos (24UL) /*!< QSPIC_RESSUS_DLY (Bit 24) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_RESSUS_DLY_Msk (0x3f000000UL) /*!< QSPIC_RESSUS_DLY (Bitfield-Mask: 0x3f) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERSRES_HLD_Pos (16UL) /*!< QSPIC_ERSRES_HLD (Bit 16) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERSRES_HLD_Msk (0xf0000UL) /*!< QSPIC_ERSRES_HLD (Bitfield-Mask: 0x0f) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_CS_HI_Pos (10UL) /*!< QSPIC_ERS_CS_HI (Bit 10) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_CS_HI_Msk (0x7c00UL) /*!< QSPIC_ERS_CS_HI (Bitfield-Mask: 0x1f) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_EAD_TX_MD_Pos (8UL) /*!< QSPIC_EAD_TX_MD (Bit 8) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_EAD_TX_MD_Msk (0x300UL) /*!< QSPIC_EAD_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_RES_TX_MD_Pos (6UL) /*!< QSPIC_RES_TX_MD (Bit 6) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_RES_TX_MD_Msk (0xc0UL) /*!< QSPIC_RES_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_SUS_TX_MD_Pos (4UL) /*!< QSPIC_SUS_TX_MD (Bit 4) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_SUS_TX_MD_Msk (0x30UL) /*!< QSPIC_SUS_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_WEN_TX_MD_Pos (2UL) /*!< QSPIC_WEN_TX_MD (Bit 2) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_WEN_TX_MD_Msk (0xcUL) /*!< QSPIC_WEN_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_TX_MD_Pos (0UL) /*!< QSPIC_ERS_TX_MD (Bit 0) */ +#define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_TX_MD_Msk (0x3UL) /*!< QSPIC_ERS_TX_MD (Bitfield-Mask: 0x03) */ +/* ================================================== QSPIC_ERASECTRL_REG ================================================== */ +#define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERS_STATE_Pos (25UL) /*!< QSPIC_ERS_STATE (Bit 25) */ +#define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERS_STATE_Msk (0xe000000UL) /*!< QSPIC_ERS_STATE (Bitfield-Mask: 0x07) */ +#define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERASE_EN_Pos (24UL) /*!< QSPIC_ERASE_EN (Bit 24) */ +#define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERASE_EN_Msk (0x1000000UL) /*!< QSPIC_ERASE_EN (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERS_ADDR_Pos (4UL) /*!< QSPIC_ERS_ADDR (Bit 4) */ +#define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERS_ADDR_Msk (0xfffff0UL) /*!< QSPIC_ERS_ADDR (Bitfield-Mask: 0xfffff) */ +/* ===================================================== QSPIC_GP_REG ====================================================== */ +#define QSPIC_QSPIC_GP_REG_QSPIC_PADS_SLEW_Pos (3UL) /*!< QSPIC_PADS_SLEW (Bit 3) */ +#define QSPIC_QSPIC_GP_REG_QSPIC_PADS_SLEW_Msk (0x18UL) /*!< QSPIC_PADS_SLEW (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_GP_REG_QSPIC_PADS_DRV_Pos (1UL) /*!< QSPIC_PADS_DRV (Bit 1) */ +#define QSPIC_QSPIC_GP_REG_QSPIC_PADS_DRV_Msk (0x6UL) /*!< QSPIC_PADS_DRV (Bitfield-Mask: 0x03) */ +/* ================================================== QSPIC_READDATA_REG =================================================== */ +#define QSPIC_QSPIC_READDATA_REG_QSPIC_READDATA_Pos (0UL) /*!< QSPIC_READDATA (Bit 0) */ +#define QSPIC_QSPIC_READDATA_REG_QSPIC_READDATA_Msk (0xffffffffUL) /*!< QSPIC_READDATA (Bitfield-Mask: 0xffffffff) */ +/* ================================================== QSPIC_RECVDATA_REG =================================================== */ +#define QSPIC_QSPIC_RECVDATA_REG_QSPIC_RECVDATA_Pos (0UL) /*!< QSPIC_RECVDATA (Bit 0) */ +#define QSPIC_QSPIC_RECVDATA_REG_QSPIC_RECVDATA_Msk (0xffffffffUL) /*!< QSPIC_RECVDATA (Bitfield-Mask: 0xffffffff) */ +/* ================================================== QSPIC_STATUSCMD_REG ================================================== */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_STSDLY_SEL_Pos (22UL) /*!< QSPIC_STSDLY_SEL (Bit 22) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_STSDLY_SEL_Msk (0x400000UL) /*!< QSPIC_STSDLY_SEL (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RESSTS_DLY_Pos (16UL) /*!< QSPIC_RESSTS_DLY (Bit 16) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RESSTS_DLY_Msk (0x3f0000UL) /*!< QSPIC_RESSTS_DLY (Bitfield-Mask: 0x3f) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_BUSY_VAL_Pos (15UL) /*!< QSPIC_BUSY_VAL (Bit 15) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_BUSY_VAL_Msk (0x8000UL) /*!< QSPIC_BUSY_VAL (Bitfield-Mask: 0x01) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_BUSY_POS_Pos (12UL) /*!< QSPIC_BUSY_POS (Bit 12) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_BUSY_POS_Msk (0x7000UL) /*!< QSPIC_BUSY_POS (Bitfield-Mask: 0x07) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_RX_MD_Pos (10UL) /*!< QSPIC_RSTAT_RX_MD (Bit 10) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_RX_MD_Msk (0xc00UL) /*!< QSPIC_RSTAT_RX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_TX_MD_Pos (8UL) /*!< QSPIC_RSTAT_TX_MD (Bit 8) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_TX_MD_Msk (0x300UL) /*!< QSPIC_RSTAT_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_INST_Pos (0UL) /*!< QSPIC_RSTAT_INST (Bit 0) */ +#define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_INST_Msk (0xffUL) /*!< QSPIC_RSTAT_INST (Bitfield-Mask: 0xff) */ +/* =================================================== QSPIC_STATUS_REG ==================================================== */ +#define QSPIC_QSPIC_STATUS_REG_QSPIC_BUSY_Pos (0UL) /*!< QSPIC_BUSY (Bit 0) */ +#define QSPIC_QSPIC_STATUS_REG_QSPIC_BUSY_Msk (0x1UL) /*!< QSPIC_BUSY (Bitfield-Mask: 0x01) */ +/* =================================================== QSPIC_UCODE_START =================================================== */ +#define QSPIC_QSPIC_UCODE_START_QSPIC_UCODE_X_Pos (0UL) /*!< QSPIC_UCODE_X (Bit 0) */ +#define QSPIC_QSPIC_UCODE_START_QSPIC_UCODE_X_Msk (0xffffffffUL) /*!< QSPIC_UCODE_X (Bitfield-Mask: 0xffffffff) */ +/* ================================================== QSPIC_WRITEDATA_REG ================================================== */ +#define QSPIC_QSPIC_WRITEDATA_REG_QSPIC_WRITEDATA_Pos (0UL) /*!< QSPIC_WRITEDATA (Bit 0) */ +#define QSPIC_QSPIC_WRITEDATA_REG_QSPIC_WRITEDATA_Msk (0xffffffffUL) /*!< QSPIC_WRITEDATA (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ QSPIC2 ================ */ +/* =========================================================================================================================== */ + +/* ================================================= QSPIC2_AWRITECMD_REG ================================================== */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_CS_HIGH_MIN_Pos (14UL) /*!< QSPIC_WR_CS_HIGH_MIN (Bit 14) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_CS_HIGH_MIN_Msk (0x7c000UL) /*!< QSPIC_WR_CS_HIGH_MIN (Bitfield-Mask: 0x1f) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_DAT_TX_MD_Pos (12UL) /*!< QSPIC_WR_DAT_TX_MD (Bit 12) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_DAT_TX_MD_Msk (0x3000UL) /*!< QSPIC_WR_DAT_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_ADR_TX_MD_Pos (10UL) /*!< QSPIC_WR_ADR_TX_MD (Bit 10) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_ADR_TX_MD_Msk (0xc00UL) /*!< QSPIC_WR_ADR_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_INST_TX_MD_Pos (8UL) /*!< QSPIC_WR_INST_TX_MD (Bit 8) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_INST_TX_MD_Msk (0x300UL) /*!< QSPIC_WR_INST_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_INST_Pos (0UL) /*!< QSPIC_WR_INST (Bit 0) */ +#define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_INST_Msk (0xffUL) /*!< QSPIC_WR_INST (Bitfield-Mask: 0xff) */ +/* ================================================== QSPIC2_BURSTBRK_REG ================================================== */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_SEC_HF_DS_Pos (20UL) /*!< QSPIC_SEC_HF_DS (Bit 20) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_SEC_HF_DS_Msk (0x100000UL) /*!< QSPIC_SEC_HF_DS (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_TX_MD_Pos (18UL) /*!< QSPIC_BRK_TX_MD (Bit 18) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_TX_MD_Msk (0xc0000UL) /*!< QSPIC_BRK_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_SZ_Pos (17UL) /*!< QSPIC_BRK_SZ (Bit 17) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_SZ_Msk (0x20000UL) /*!< QSPIC_BRK_SZ (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_EN_Pos (16UL) /*!< QSPIC_BRK_EN (Bit 16) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_EN_Msk (0x10000UL) /*!< QSPIC_BRK_EN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_WRD_Pos (0UL) /*!< QSPIC_BRK_WRD (Bit 0) */ +#define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_WRD_Msk (0xffffUL) /*!< QSPIC_BRK_WRD (Bitfield-Mask: 0xffff) */ +/* ================================================= QSPIC2_BURSTCMDA_REG ================================================== */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_DMY_TX_MD_Pos (30UL) /*!< QSPIC_DMY_TX_MD (Bit 30) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_DMY_TX_MD_Msk (0xc0000000UL) /*!< QSPIC_DMY_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_EXT_TX_MD_Pos (28UL) /*!< QSPIC_EXT_TX_MD (Bit 28) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_EXT_TX_MD_Msk (0x30000000UL) /*!< QSPIC_EXT_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_ADR_TX_MD_Pos (26UL) /*!< QSPIC_ADR_TX_MD (Bit 26) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_ADR_TX_MD_Msk (0xc000000UL) /*!< QSPIC_ADR_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_TX_MD_Pos (24UL) /*!< QSPIC_INST_TX_MD (Bit 24) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_TX_MD_Msk (0x3000000UL) /*!< QSPIC_INST_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_EXT_BYTE_Pos (16UL) /*!< QSPIC_EXT_BYTE (Bit 16) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_EXT_BYTE_Msk (0xff0000UL) /*!< QSPIC_EXT_BYTE (Bitfield-Mask: 0xff) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_WB_Pos (8UL) /*!< QSPIC_INST_WB (Bit 8) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_WB_Msk (0xff00UL) /*!< QSPIC_INST_WB (Bitfield-Mask: 0xff) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_Pos (0UL) /*!< QSPIC_INST (Bit 0) */ +#define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_Msk (0xffUL) /*!< QSPIC_INST (Bitfield-Mask: 0xff) */ +/* ================================================= QSPIC2_BURSTCMDB_REG ================================================== */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DMY_FORCE_Pos (15UL) /*!< QSPIC_DMY_FORCE (Bit 15) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DMY_FORCE_Msk (0x8000UL) /*!< QSPIC_DMY_FORCE (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Pos (12UL) /*!< QSPIC_CS_HIGH_MIN (Bit 12) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Msk (0x7000UL) /*!< QSPIC_CS_HIGH_MIN (Bitfield-Mask: 0x07) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_SIZE_Pos (10UL) /*!< QSPIC_WRAP_SIZE (Bit 10) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_SIZE_Msk (0xc00UL) /*!< QSPIC_WRAP_SIZE (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_LEN_Pos (8UL) /*!< QSPIC_WRAP_LEN (Bit 8) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_LEN_Msk (0x300UL) /*!< QSPIC_WRAP_LEN (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_MD_Pos (7UL) /*!< QSPIC_WRAP_MD (Bit 7) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_MD_Msk (0x80UL) /*!< QSPIC_WRAP_MD (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_INST_MD_Pos (6UL) /*!< QSPIC_INST_MD (Bit 6) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_INST_MD_Msk (0x40UL) /*!< QSPIC_INST_MD (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DMY_NUM_Pos (4UL) /*!< QSPIC_DMY_NUM (Bit 4) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DMY_NUM_Msk (0x30UL) /*!< QSPIC_DMY_NUM (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_EXT_HF_DS_Pos (3UL) /*!< QSPIC_EXT_HF_DS (Bit 3) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_EXT_HF_DS_Msk (0x8UL) /*!< QSPIC_EXT_HF_DS (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_EXT_BYTE_EN_Pos (2UL) /*!< QSPIC_EXT_BYTE_EN (Bit 2) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_EXT_BYTE_EN_Msk (0x4UL) /*!< QSPIC_EXT_BYTE_EN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DAT_RX_MD_Pos (0UL) /*!< QSPIC_DAT_RX_MD (Bit 0) */ +#define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DAT_RX_MD_Msk (0x3UL) /*!< QSPIC_DAT_RX_MD (Bitfield-Mask: 0x03) */ +/* ================================================= QSPIC2_CHCKERASE_REG ================================================== */ +#define QSPIC2_QSPIC2_CHCKERASE_REG_QSPIC_CHCKERASE_Pos (0UL) /*!< QSPIC_CHCKERASE (Bit 0) */ +#define QSPIC2_QSPIC2_CHCKERASE_REG_QSPIC_CHCKERASE_Msk (0xffffffffUL) /*!< QSPIC_CHCKERASE (Bitfield-Mask: 0xffffffff) */ +/* ================================================== QSPIC2_CTRLBUS_REG =================================================== */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_DIS_CS_Pos (4UL) /*!< QSPIC_DIS_CS (Bit 4) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_DIS_CS_Msk (0x10UL) /*!< QSPIC_DIS_CS (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_EN_CS_Pos (3UL) /*!< QSPIC_EN_CS (Bit 3) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_EN_CS_Msk (0x8UL) /*!< QSPIC_EN_CS (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_QUAD_Pos (2UL) /*!< QSPIC_SET_QUAD (Bit 2) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_QUAD_Msk (0x4UL) /*!< QSPIC_SET_QUAD (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_DUAL_Pos (1UL) /*!< QSPIC_SET_DUAL (Bit 1) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_DUAL_Msk (0x2UL) /*!< QSPIC_SET_DUAL (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_SINGLE_Pos (0UL) /*!< QSPIC_SET_SINGLE (Bit 0) */ +#define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_SINGLE_Msk (0x1UL) /*!< QSPIC_SET_SINGLE (Bitfield-Mask: 0x01) */ +/* ================================================== QSPIC2_CTRLMODE_REG ================================================== */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CLK_FREE_EN_Pos (16UL) /*!< QSPIC_CLK_FREE_EN (Bit 16) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CLK_FREE_EN_Msk (0x10000UL) /*!< QSPIC_CLK_FREE_EN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CS_MD_Pos (15UL) /*!< QSPIC_CS_MD (Bit 15) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CS_MD_Msk (0x8000UL) /*!< QSPIC_CS_MD (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_SRAM_EN_Pos (14UL) /*!< QSPIC_SRAM_EN (Bit 14) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_SRAM_EN_Msk (0x4000UL) /*!< QSPIC_SRAM_EN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_USE_32BA_Pos (13UL) /*!< QSPIC_USE_32BA (Bit 13) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_USE_32BA_Msk (0x2000UL) /*!< QSPIC_USE_32BA (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_FORCENSEQ_EN_Pos (12UL) /*!< QSPIC_FORCENSEQ_EN (Bit 12) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_FORCENSEQ_EN_Msk (0x1000UL) /*!< QSPIC_FORCENSEQ_EN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_PCLK_MD_Pos (9UL) /*!< QSPIC_PCLK_MD (Bit 9) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_PCLK_MD_Msk (0xe00UL) /*!< QSPIC_PCLK_MD (Bitfield-Mask: 0x07) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_RPIPE_EN_Pos (8UL) /*!< QSPIC_RPIPE_EN (Bit 8) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_RPIPE_EN_Msk (0x100UL) /*!< QSPIC_RPIPE_EN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_RXD_NEG_Pos (7UL) /*!< QSPIC_RXD_NEG (Bit 7) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_RXD_NEG_Msk (0x80UL) /*!< QSPIC_RXD_NEG (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_HRDY_MD_Pos (6UL) /*!< QSPIC_HRDY_MD (Bit 6) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_HRDY_MD_Msk (0x40UL) /*!< QSPIC_HRDY_MD (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO3_DAT_Pos (5UL) /*!< QSPIC_IO3_DAT (Bit 5) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO3_DAT_Msk (0x20UL) /*!< QSPIC_IO3_DAT (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO2_DAT_Pos (4UL) /*!< QSPIC_IO2_DAT (Bit 4) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO2_DAT_Msk (0x10UL) /*!< QSPIC_IO2_DAT (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO3_OEN_Pos (3UL) /*!< QSPIC_IO3_OEN (Bit 3) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO3_OEN_Msk (0x8UL) /*!< QSPIC_IO3_OEN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO2_OEN_Pos (2UL) /*!< QSPIC_IO2_OEN (Bit 2) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO2_OEN_Msk (0x4UL) /*!< QSPIC_IO2_OEN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CLK_MD_Pos (1UL) /*!< QSPIC_CLK_MD (Bit 1) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CLK_MD_Msk (0x2UL) /*!< QSPIC_CLK_MD (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_AUTO_MD_Pos (0UL) /*!< QSPIC_AUTO_MD (Bit 0) */ +#define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_AUTO_MD_Msk (0x1UL) /*!< QSPIC_AUTO_MD (Bitfield-Mask: 0x01) */ +/* ================================================= QSPIC2_DUMMYDATA_REG ================================================== */ +#define QSPIC2_QSPIC2_DUMMYDATA_REG_QSPIC_DUMMYDATA_Pos (0UL) /*!< QSPIC_DUMMYDATA (Bit 0) */ +#define QSPIC2_QSPIC2_DUMMYDATA_REG_QSPIC_DUMMYDATA_Msk (0xffffffffUL) /*!< QSPIC_DUMMYDATA (Bitfield-Mask: 0xffffffff) */ +/* ================================================= QSPIC2_ERASECMDA_REG ================================================== */ +#define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_RES_INST_Pos (24UL) /*!< QSPIC_RES_INST (Bit 24) */ +#define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_RES_INST_Msk (0xff000000UL) /*!< QSPIC_RES_INST (Bitfield-Mask: 0xff) */ +#define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_SUS_INST_Pos (16UL) /*!< QSPIC_SUS_INST (Bit 16) */ +#define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_SUS_INST_Msk (0xff0000UL) /*!< QSPIC_SUS_INST (Bitfield-Mask: 0xff) */ +#define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_WEN_INST_Pos (8UL) /*!< QSPIC_WEN_INST (Bit 8) */ +#define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_WEN_INST_Msk (0xff00UL) /*!< QSPIC_WEN_INST (Bitfield-Mask: 0xff) */ +#define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_ERS_INST_Pos (0UL) /*!< QSPIC_ERS_INST (Bit 0) */ +#define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_ERS_INST_Msk (0xffUL) /*!< QSPIC_ERS_INST (Bitfield-Mask: 0xff) */ +/* ================================================= QSPIC2_ERASECMDB_REG ================================================== */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_RESSUS_DLY_Pos (24UL) /*!< QSPIC_RESSUS_DLY (Bit 24) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_RESSUS_DLY_Msk (0x3f000000UL) /*!< QSPIC_RESSUS_DLY (Bitfield-Mask: 0x3f) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERSRES_HLD_Pos (16UL) /*!< QSPIC_ERSRES_HLD (Bit 16) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERSRES_HLD_Msk (0xf0000UL) /*!< QSPIC_ERSRES_HLD (Bitfield-Mask: 0x0f) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERS_CS_HI_Pos (10UL) /*!< QSPIC_ERS_CS_HI (Bit 10) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERS_CS_HI_Msk (0x7c00UL) /*!< QSPIC_ERS_CS_HI (Bitfield-Mask: 0x1f) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_EAD_TX_MD_Pos (8UL) /*!< QSPIC_EAD_TX_MD (Bit 8) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_EAD_TX_MD_Msk (0x300UL) /*!< QSPIC_EAD_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_RES_TX_MD_Pos (6UL) /*!< QSPIC_RES_TX_MD (Bit 6) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_RES_TX_MD_Msk (0xc0UL) /*!< QSPIC_RES_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_SUS_TX_MD_Pos (4UL) /*!< QSPIC_SUS_TX_MD (Bit 4) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_SUS_TX_MD_Msk (0x30UL) /*!< QSPIC_SUS_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_WEN_TX_MD_Pos (2UL) /*!< QSPIC_WEN_TX_MD (Bit 2) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_WEN_TX_MD_Msk (0xcUL) /*!< QSPIC_WEN_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERS_TX_MD_Pos (0UL) /*!< QSPIC_ERS_TX_MD (Bit 0) */ +#define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERS_TX_MD_Msk (0x3UL) /*!< QSPIC_ERS_TX_MD (Bitfield-Mask: 0x03) */ +/* ================================================= QSPIC2_ERASECTRL_REG ================================================== */ +#define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERS_STATE_Pos (25UL) /*!< QSPIC_ERS_STATE (Bit 25) */ +#define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERS_STATE_Msk (0xe000000UL) /*!< QSPIC_ERS_STATE (Bitfield-Mask: 0x07) */ +#define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERASE_EN_Pos (24UL) /*!< QSPIC_ERASE_EN (Bit 24) */ +#define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERASE_EN_Msk (0x1000000UL) /*!< QSPIC_ERASE_EN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERS_ADDR_Pos (4UL) /*!< QSPIC_ERS_ADDR (Bit 4) */ +#define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERS_ADDR_Msk (0xfffff0UL) /*!< QSPIC_ERS_ADDR (Bitfield-Mask: 0xfffff) */ +/* ===================================================== QSPIC2_GP_REG ===================================================== */ +#define QSPIC2_QSPIC2_GP_REG_QSPIC_PADS_SLEW_Pos (3UL) /*!< QSPIC_PADS_SLEW (Bit 3) */ +#define QSPIC2_QSPIC2_GP_REG_QSPIC_PADS_SLEW_Msk (0x18UL) /*!< QSPIC_PADS_SLEW (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_GP_REG_QSPIC_PADS_DRV_Pos (1UL) /*!< QSPIC_PADS_DRV (Bit 1) */ +#define QSPIC2_QSPIC2_GP_REG_QSPIC_PADS_DRV_Msk (0x6UL) /*!< QSPIC_PADS_DRV (Bitfield-Mask: 0x03) */ +/* ================================================== QSPIC2_MEMBLEN_REG =================================================== */ +#define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_T_CEM_CC_Pos (4UL) /*!< QSPIC_T_CEM_CC (Bit 4) */ +#define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_T_CEM_CC_Msk (0x3ff0UL) /*!< QSPIC_T_CEM_CC (Bitfield-Mask: 0x3ff) */ +#define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_T_CEM_EN_Pos (3UL) /*!< QSPIC_T_CEM_EN (Bit 3) */ +#define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_T_CEM_EN_Msk (0x8UL) /*!< QSPIC_T_CEM_EN (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_MEMBLEN_Pos (0UL) /*!< QSPIC_MEMBLEN (Bit 0) */ +#define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_MEMBLEN_Msk (0x7UL) /*!< QSPIC_MEMBLEN (Bitfield-Mask: 0x07) */ +/* ================================================== QSPIC2_READDATA_REG ================================================== */ +#define QSPIC2_QSPIC2_READDATA_REG_QSPIC_READDATA_Pos (0UL) /*!< QSPIC_READDATA (Bit 0) */ +#define QSPIC2_QSPIC2_READDATA_REG_QSPIC_READDATA_Msk (0xffffffffUL) /*!< QSPIC_READDATA (Bitfield-Mask: 0xffffffff) */ +/* ================================================== QSPIC2_RECVDATA_REG ================================================== */ +#define QSPIC2_QSPIC2_RECVDATA_REG_QSPIC_RECVDATA_Pos (0UL) /*!< QSPIC_RECVDATA (Bit 0) */ +#define QSPIC2_QSPIC2_RECVDATA_REG_QSPIC_RECVDATA_Msk (0xffffffffUL) /*!< QSPIC_RECVDATA (Bitfield-Mask: 0xffffffff) */ +/* ================================================= QSPIC2_STATUSCMD_REG ================================================== */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_STSDLY_SEL_Pos (22UL) /*!< QSPIC_STSDLY_SEL (Bit 22) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_STSDLY_SEL_Msk (0x400000UL) /*!< QSPIC_STSDLY_SEL (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RESSTS_DLY_Pos (16UL) /*!< QSPIC_RESSTS_DLY (Bit 16) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RESSTS_DLY_Msk (0x3f0000UL) /*!< QSPIC_RESSTS_DLY (Bitfield-Mask: 0x3f) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_BUSY_VAL_Pos (15UL) /*!< QSPIC_BUSY_VAL (Bit 15) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_BUSY_VAL_Msk (0x8000UL) /*!< QSPIC_BUSY_VAL (Bitfield-Mask: 0x01) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_BUSY_POS_Pos (12UL) /*!< QSPIC_BUSY_POS (Bit 12) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_BUSY_POS_Msk (0x7000UL) /*!< QSPIC_BUSY_POS (Bitfield-Mask: 0x07) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_RX_MD_Pos (10UL) /*!< QSPIC_RSTAT_RX_MD (Bit 10) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_RX_MD_Msk (0xc00UL) /*!< QSPIC_RSTAT_RX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_TX_MD_Pos (8UL) /*!< QSPIC_RSTAT_TX_MD (Bit 8) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_TX_MD_Msk (0x300UL) /*!< QSPIC_RSTAT_TX_MD (Bitfield-Mask: 0x03) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_INST_Pos (0UL) /*!< QSPIC_RSTAT_INST (Bit 0) */ +#define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_INST_Msk (0xffUL) /*!< QSPIC_RSTAT_INST (Bitfield-Mask: 0xff) */ +/* =================================================== QSPIC2_STATUS_REG =================================================== */ +#define QSPIC2_QSPIC2_STATUS_REG_QSPIC_BUSY_Pos (0UL) /*!< QSPIC_BUSY (Bit 0) */ +#define QSPIC2_QSPIC2_STATUS_REG_QSPIC_BUSY_Msk (0x1UL) /*!< QSPIC_BUSY (Bitfield-Mask: 0x01) */ +/* ================================================= QSPIC2_WRITEDATA_REG ================================================== */ +#define QSPIC2_QSPIC2_WRITEDATA_REG_QSPIC_WRITEDATA_Pos (0UL) /*!< QSPIC_WRITEDATA (Bit 0) */ +#define QSPIC2_QSPIC2_WRITEDATA_REG_QSPIC_WRITEDATA_Msk (0xffffffffUL) /*!< QSPIC_WRITEDATA (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ RFMON ================ */ +/* =========================================================================================================================== */ + +/* ==================================================== RFMON_ADDR_REG ===================================================== */ +#define RFMON_RFMON_ADDR_REG_RFMON_ADDR_Pos (2UL) /*!< RFMON_ADDR (Bit 2) */ +#define RFMON_RFMON_ADDR_REG_RFMON_ADDR_Msk (0xfffffffcUL) /*!< RFMON_ADDR (Bitfield-Mask: 0x3fffffff) */ +/* ================================================== RFMON_CRV_ADDR_REG =================================================== */ +#define RFMON_RFMON_CRV_ADDR_REG_RFMON_CRV_ADDR_Pos (2UL) /*!< RFMON_CRV_ADDR (Bit 2) */ +#define RFMON_RFMON_CRV_ADDR_REG_RFMON_CRV_ADDR_Msk (0xfffffffcUL) /*!< RFMON_CRV_ADDR (Bitfield-Mask: 0x3fffffff) */ +/* =================================================== RFMON_CRV_LEN_REG =================================================== */ +#define RFMON_RFMON_CRV_LEN_REG_RFMON_CRV_LEN_Pos (0UL) /*!< RFMON_CRV_LEN (Bit 0) */ +#define RFMON_RFMON_CRV_LEN_REG_RFMON_CRV_LEN_Msk (0x1ffffUL) /*!< RFMON_CRV_LEN (Bitfield-Mask: 0x1ffff) */ +/* ==================================================== RFMON_CTRL_REG ===================================================== */ +#define RFMON_RFMON_CTRL_REG_RFMON_BREQ_FORCE_Pos (2UL) /*!< RFMON_BREQ_FORCE (Bit 2) */ +#define RFMON_RFMON_CTRL_REG_RFMON_BREQ_FORCE_Msk (0x4UL) /*!< RFMON_BREQ_FORCE (Bitfield-Mask: 0x01) */ +#define RFMON_RFMON_CTRL_REG_RFMON_CIRC_EN_Pos (1UL) /*!< RFMON_CIRC_EN (Bit 1) */ +#define RFMON_RFMON_CTRL_REG_RFMON_CIRC_EN_Msk (0x2UL) /*!< RFMON_CIRC_EN (Bitfield-Mask: 0x01) */ +#define RFMON_RFMON_CTRL_REG_RFMON_PACK_EN_Pos (0UL) /*!< RFMON_PACK_EN (Bit 0) */ +#define RFMON_RFMON_CTRL_REG_RFMON_PACK_EN_Msk (0x1UL) /*!< RFMON_PACK_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== RFMON_LEN_REG ===================================================== */ +#define RFMON_RFMON_LEN_REG_RFMON_LEN_Pos (0UL) /*!< RFMON_LEN (Bit 0) */ +#define RFMON_RFMON_LEN_REG_RFMON_LEN_Msk (0x1ffffUL) /*!< RFMON_LEN (Bitfield-Mask: 0x1ffff) */ +/* ==================================================== RFMON_STAT_REG ===================================================== */ +#define RFMON_RFMON_STAT_REG_RFMON_OFLOW_STK_Pos (1UL) /*!< RFMON_OFLOW_STK (Bit 1) */ +#define RFMON_RFMON_STAT_REG_RFMON_OFLOW_STK_Msk (0x2UL) /*!< RFMON_OFLOW_STK (Bitfield-Mask: 0x01) */ +#define RFMON_RFMON_STAT_REG_RFMON_ACTIVE_Pos (0UL) /*!< RFMON_ACTIVE (Bit 0) */ +#define RFMON_RFMON_STAT_REG_RFMON_ACTIVE_Msk (0x1UL) /*!< RFMON_ACTIVE (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ RTC ================ */ +/* =========================================================================================================================== */ + +/* ================================================= RTC_ALARM_ENABLE_REG ================================================== */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MNTH_EN_Pos (5UL) /*!< RTC_ALARM_MNTH_EN (Bit 5) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MNTH_EN_Msk (0x20UL) /*!< RTC_ALARM_MNTH_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_DATE_EN_Pos (4UL) /*!< RTC_ALARM_DATE_EN (Bit 4) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_DATE_EN_Msk (0x10UL) /*!< RTC_ALARM_DATE_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOUR_EN_Pos (3UL) /*!< RTC_ALARM_HOUR_EN (Bit 3) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOUR_EN_Msk (0x8UL) /*!< RTC_ALARM_HOUR_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MIN_EN_Pos (2UL) /*!< RTC_ALARM_MIN_EN (Bit 2) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MIN_EN_Msk (0x4UL) /*!< RTC_ALARM_MIN_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_SEC_EN_Pos (1UL) /*!< RTC_ALARM_SEC_EN (Bit 1) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_SEC_EN_Msk (0x2UL) /*!< RTC_ALARM_SEC_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOS_EN_Pos (0UL) /*!< RTC_ALARM_HOS_EN (Bit 0) */ +#define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOS_EN_Msk (0x1UL) /*!< RTC_ALARM_HOS_EN (Bitfield-Mask: 0x01) */ +/* ================================================ RTC_CALENDAR_ALARM_REG ================================================= */ +#define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_D_T_Pos (12UL) /*!< RTC_CAL_D_T (Bit 12) */ +#define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_D_T_Msk (0x3000UL) /*!< RTC_CAL_D_T (Bitfield-Mask: 0x03) */ +#define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_D_U_Pos (8UL) /*!< RTC_CAL_D_U (Bit 8) */ +#define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_D_U_Msk (0xf00UL) /*!< RTC_CAL_D_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_M_T_Pos (7UL) /*!< RTC_CAL_M_T (Bit 7) */ +#define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_M_T_Msk (0x80UL) /*!< RTC_CAL_M_T (Bitfield-Mask: 0x01) */ +#define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_M_U_Pos (3UL) /*!< RTC_CAL_M_U (Bit 3) */ +#define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_M_U_Msk (0x78UL) /*!< RTC_CAL_M_U (Bitfield-Mask: 0x0f) */ +/* =================================================== RTC_CALENDAR_REG ==================================================== */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_CH_Pos (31UL) /*!< RTC_CAL_CH (Bit 31) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_CH_Msk (0x80000000UL) /*!< RTC_CAL_CH (Bitfield-Mask: 0x01) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_C_T_Pos (28UL) /*!< RTC_CAL_C_T (Bit 28) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_C_T_Msk (0x30000000UL) /*!< RTC_CAL_C_T (Bitfield-Mask: 0x03) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_C_U_Pos (24UL) /*!< RTC_CAL_C_U (Bit 24) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_C_U_Msk (0xf000000UL) /*!< RTC_CAL_C_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_Y_T_Pos (20UL) /*!< RTC_CAL_Y_T (Bit 20) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_Y_T_Msk (0xf00000UL) /*!< RTC_CAL_Y_T (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_Y_U_Pos (16UL) /*!< RTC_CAL_Y_U (Bit 16) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_Y_U_Msk (0xf0000UL) /*!< RTC_CAL_Y_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_D_T_Pos (12UL) /*!< RTC_CAL_D_T (Bit 12) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_D_T_Msk (0x3000UL) /*!< RTC_CAL_D_T (Bitfield-Mask: 0x03) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_D_U_Pos (8UL) /*!< RTC_CAL_D_U (Bit 8) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_D_U_Msk (0xf00UL) /*!< RTC_CAL_D_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_M_T_Pos (7UL) /*!< RTC_CAL_M_T (Bit 7) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_M_T_Msk (0x80UL) /*!< RTC_CAL_M_T (Bitfield-Mask: 0x01) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_M_U_Pos (3UL) /*!< RTC_CAL_M_U (Bit 3) */ +#define RTC_RTC_CALENDAR_REG_RTC_CAL_M_U_Msk (0x78UL) /*!< RTC_CAL_M_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_CALENDAR_REG_RTC_DAY_Pos (0UL) /*!< RTC_DAY (Bit 0) */ +#define RTC_RTC_CALENDAR_REG_RTC_DAY_Msk (0x7UL) /*!< RTC_DAY (Bitfield-Mask: 0x07) */ +/* ==================================================== RTC_CONTROL_REG ==================================================== */ +#define RTC_RTC_CONTROL_REG_RTC_CAL_DISABLE_Pos (1UL) /*!< RTC_CAL_DISABLE (Bit 1) */ +#define RTC_RTC_CONTROL_REG_RTC_CAL_DISABLE_Msk (0x2UL) /*!< RTC_CAL_DISABLE (Bitfield-Mask: 0x01) */ +#define RTC_RTC_CONTROL_REG_RTC_TIME_DISABLE_Pos (0UL) /*!< RTC_TIME_DISABLE (Bit 0) */ +#define RTC_RTC_CONTROL_REG_RTC_TIME_DISABLE_Msk (0x1UL) /*!< RTC_TIME_DISABLE (Bitfield-Mask: 0x01) */ +/* ================================================== RTC_EVENT_CTRL_REG =================================================== */ +#define RTC_RTC_EVENT_CTRL_REG_RTC_PDC_EVENT_EN_Pos (1UL) /*!< RTC_PDC_EVENT_EN (Bit 1) */ +#define RTC_RTC_EVENT_CTRL_REG_RTC_PDC_EVENT_EN_Msk (0x2UL) /*!< RTC_PDC_EVENT_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_EVENT_CTRL_REG_RTC_MOTOR_EVENT_EN_Pos (0UL) /*!< RTC_MOTOR_EVENT_EN (Bit 0) */ +#define RTC_RTC_EVENT_CTRL_REG_RTC_MOTOR_EVENT_EN_Msk (0x1UL) /*!< RTC_MOTOR_EVENT_EN (Bitfield-Mask: 0x01) */ +/* ================================================== RTC_EVENT_FLAGS_REG ================================================== */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_ALRM_Pos (6UL) /*!< RTC_EVENT_ALRM (Bit 6) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_ALRM_Msk (0x40UL) /*!< RTC_EVENT_ALRM (Bitfield-Mask: 0x01) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_MNTH_Pos (5UL) /*!< RTC_EVENT_MNTH (Bit 5) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_MNTH_Msk (0x20UL) /*!< RTC_EVENT_MNTH (Bitfield-Mask: 0x01) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_DATE_Pos (4UL) /*!< RTC_EVENT_DATE (Bit 4) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_DATE_Msk (0x10UL) /*!< RTC_EVENT_DATE (Bitfield-Mask: 0x01) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_HOUR_Pos (3UL) /*!< RTC_EVENT_HOUR (Bit 3) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_HOUR_Msk (0x8UL) /*!< RTC_EVENT_HOUR (Bitfield-Mask: 0x01) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_MIN_Pos (2UL) /*!< RTC_EVENT_MIN (Bit 2) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_MIN_Msk (0x4UL) /*!< RTC_EVENT_MIN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_SEC_Pos (1UL) /*!< RTC_EVENT_SEC (Bit 1) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_SEC_Msk (0x2UL) /*!< RTC_EVENT_SEC (Bitfield-Mask: 0x01) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_HOS_Pos (0UL) /*!< RTC_EVENT_HOS (Bit 0) */ +#define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_HOS_Msk (0x1UL) /*!< RTC_EVENT_HOS (Bitfield-Mask: 0x01) */ +/* =================================================== RTC_HOUR_MODE_REG =================================================== */ +#define RTC_RTC_HOUR_MODE_REG_RTC_HMS_Pos (0UL) /*!< RTC_HMS (Bit 0) */ +#define RTC_RTC_HOUR_MODE_REG_RTC_HMS_Msk (0x1UL) /*!< RTC_HMS (Bitfield-Mask: 0x01) */ +/* =============================================== RTC_INTERRUPT_DISABLE_REG =============================================== */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_ALRM_INT_DIS_Pos (6UL) /*!< RTC_ALRM_INT_DIS (Bit 6) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_ALRM_INT_DIS_Msk (0x40UL) /*!< RTC_ALRM_INT_DIS (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_MNTH_INT_DIS_Pos (5UL) /*!< RTC_MNTH_INT_DIS (Bit 5) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_MNTH_INT_DIS_Msk (0x20UL) /*!< RTC_MNTH_INT_DIS (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_DATE_INT_DIS_Pos (4UL) /*!< RTC_DATE_INT_DIS (Bit 4) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_DATE_INT_DIS_Msk (0x10UL) /*!< RTC_DATE_INT_DIS (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_HOUR_INT_DIS_Pos (3UL) /*!< RTC_HOUR_INT_DIS (Bit 3) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_HOUR_INT_DIS_Msk (0x8UL) /*!< RTC_HOUR_INT_DIS (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_MIN_INT_DIS_Pos (2UL) /*!< RTC_MIN_INT_DIS (Bit 2) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_MIN_INT_DIS_Msk (0x4UL) /*!< RTC_MIN_INT_DIS (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_SEC_INT_DIS_Pos (1UL) /*!< RTC_SEC_INT_DIS (Bit 1) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_SEC_INT_DIS_Msk (0x2UL) /*!< RTC_SEC_INT_DIS (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_HOS_INT_DIS_Pos (0UL) /*!< RTC_HOS_INT_DIS (Bit 0) */ +#define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_HOS_INT_DIS_Msk (0x1UL) /*!< RTC_HOS_INT_DIS (Bitfield-Mask: 0x01) */ +/* =============================================== RTC_INTERRUPT_ENABLE_REG ================================================ */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_ALRM_INT_EN_Pos (6UL) /*!< RTC_ALRM_INT_EN (Bit 6) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_ALRM_INT_EN_Msk (0x40UL) /*!< RTC_ALRM_INT_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_MNTH_INT_EN_Pos (5UL) /*!< RTC_MNTH_INT_EN (Bit 5) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_MNTH_INT_EN_Msk (0x20UL) /*!< RTC_MNTH_INT_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_DATE_INT_EN_Pos (4UL) /*!< RTC_DATE_INT_EN (Bit 4) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_DATE_INT_EN_Msk (0x10UL) /*!< RTC_DATE_INT_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_HOUR_INT_EN_Pos (3UL) /*!< RTC_HOUR_INT_EN (Bit 3) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_HOUR_INT_EN_Msk (0x8UL) /*!< RTC_HOUR_INT_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_MIN_INT_EN_Pos (2UL) /*!< RTC_MIN_INT_EN (Bit 2) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_MIN_INT_EN_Msk (0x4UL) /*!< RTC_MIN_INT_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_SEC_INT_EN_Pos (1UL) /*!< RTC_SEC_INT_EN (Bit 1) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_SEC_INT_EN_Msk (0x2UL) /*!< RTC_SEC_INT_EN (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_HOS_INT_EN_Pos (0UL) /*!< RTC_HOS_INT_EN (Bit 0) */ +#define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_HOS_INT_EN_Msk (0x1UL) /*!< RTC_HOS_INT_EN (Bitfield-Mask: 0x01) */ +/* ================================================ RTC_INTERRUPT_MASK_REG ================================================= */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_ALRM_INT_MSK_Pos (6UL) /*!< RTC_ALRM_INT_MSK (Bit 6) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_ALRM_INT_MSK_Msk (0x40UL) /*!< RTC_ALRM_INT_MSK (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_MNTH_INT_MSK_Pos (5UL) /*!< RTC_MNTH_INT_MSK (Bit 5) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_MNTH_INT_MSK_Msk (0x20UL) /*!< RTC_MNTH_INT_MSK (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_DATE_INT_MSK_Pos (4UL) /*!< RTC_DATE_INT_MSK (Bit 4) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_DATE_INT_MSK_Msk (0x10UL) /*!< RTC_DATE_INT_MSK (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_HOUR_INT_MSK_Pos (3UL) /*!< RTC_HOUR_INT_MSK (Bit 3) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_HOUR_INT_MSK_Msk (0x8UL) /*!< RTC_HOUR_INT_MSK (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_MIN_INT_MSK_Pos (2UL) /*!< RTC_MIN_INT_MSK (Bit 2) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_MIN_INT_MSK_Msk (0x4UL) /*!< RTC_MIN_INT_MSK (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_SEC_INT_MSK_Pos (1UL) /*!< RTC_SEC_INT_MSK (Bit 1) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_SEC_INT_MSK_Msk (0x2UL) /*!< RTC_SEC_INT_MSK (Bitfield-Mask: 0x01) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_HOS_INT_MSK_Pos (0UL) /*!< RTC_HOS_INT_MSK (Bit 0) */ +#define RTC_RTC_INTERRUPT_MASK_REG_RTC_HOS_INT_MSK_Msk (0x1UL) /*!< RTC_HOS_INT_MSK (Bitfield-Mask: 0x01) */ +/* =================================================== RTC_KEEP_RTC_REG ==================================================== */ +#define RTC_RTC_KEEP_RTC_REG_RTC_KEEP_Pos (0UL) /*!< RTC_KEEP (Bit 0) */ +#define RTC_RTC_KEEP_RTC_REG_RTC_KEEP_Msk (0x1UL) /*!< RTC_KEEP (Bitfield-Mask: 0x01) */ +/* ================================================ RTC_MOTOR_EVENT_CNT_REG ================================================ */ +#define RTC_RTC_MOTOR_EVENT_CNT_REG_RTC_MOTOR_EVENT_CNT_Pos (0UL) /*!< RTC_MOTOR_EVENT_CNT (Bit 0) */ +#define RTC_RTC_MOTOR_EVENT_CNT_REG_RTC_MOTOR_EVENT_CNT_Msk (0xfffUL) /*!< RTC_MOTOR_EVENT_CNT (Bitfield-Mask: 0xfff) */ +/* ============================================== RTC_MOTOR_EVENT_PERIOD_REG =============================================== */ +#define RTC_RTC_MOTOR_EVENT_PERIOD_REG_RTC_MOTOR_EVENT_PERIOD_Pos (0UL) /*!< RTC_MOTOR_EVENT_PERIOD (Bit 0) */ +#define RTC_RTC_MOTOR_EVENT_PERIOD_REG_RTC_MOTOR_EVENT_PERIOD_Msk (0xfffUL) /*!< RTC_MOTOR_EVENT_PERIOD (Bitfield-Mask: 0xfff) */ +/* ================================================ RTC_PDC_EVENT_CLEAR_REG ================================================ */ +#define RTC_RTC_PDC_EVENT_CLEAR_REG_PDC_EVENT_CLEAR_Pos (0UL) /*!< PDC_EVENT_CLEAR (Bit 0) */ +#define RTC_RTC_PDC_EVENT_CLEAR_REG_PDC_EVENT_CLEAR_Msk (0x1UL) /*!< PDC_EVENT_CLEAR (Bitfield-Mask: 0x01) */ +/* ================================================= RTC_PDC_EVENT_CNT_REG ================================================= */ +#define RTC_RTC_PDC_EVENT_CNT_REG_RTC_PDC_EVENT_CNT_Pos (0UL) /*!< RTC_PDC_EVENT_CNT (Bit 0) */ +#define RTC_RTC_PDC_EVENT_CNT_REG_RTC_PDC_EVENT_CNT_Msk (0x1fffUL) /*!< RTC_PDC_EVENT_CNT (Bitfield-Mask: 0x1fff) */ +/* =============================================== RTC_PDC_EVENT_PERIOD_REG ================================================ */ +#define RTC_RTC_PDC_EVENT_PERIOD_REG_RTC_PDC_EVENT_PERIOD_Pos (0UL) /*!< RTC_PDC_EVENT_PERIOD (Bit 0) */ +#define RTC_RTC_PDC_EVENT_PERIOD_REG_RTC_PDC_EVENT_PERIOD_Msk (0x1fffUL) /*!< RTC_PDC_EVENT_PERIOD (Bitfield-Mask: 0x1fff) */ +/* ==================================================== RTC_STATUS_REG ===================================================== */ +#define RTC_RTC_STATUS_REG_RTC_VALID_CAL_ALM_Pos (3UL) /*!< RTC_VALID_CAL_ALM (Bit 3) */ +#define RTC_RTC_STATUS_REG_RTC_VALID_CAL_ALM_Msk (0x8UL) /*!< RTC_VALID_CAL_ALM (Bitfield-Mask: 0x01) */ +#define RTC_RTC_STATUS_REG_RTC_VALID_TIME_ALM_Pos (2UL) /*!< RTC_VALID_TIME_ALM (Bit 2) */ +#define RTC_RTC_STATUS_REG_RTC_VALID_TIME_ALM_Msk (0x4UL) /*!< RTC_VALID_TIME_ALM (Bitfield-Mask: 0x01) */ +#define RTC_RTC_STATUS_REG_RTC_VALID_CAL_Pos (1UL) /*!< RTC_VALID_CAL (Bit 1) */ +#define RTC_RTC_STATUS_REG_RTC_VALID_CAL_Msk (0x2UL) /*!< RTC_VALID_CAL (Bitfield-Mask: 0x01) */ +#define RTC_RTC_STATUS_REG_RTC_VALID_TIME_Pos (0UL) /*!< RTC_VALID_TIME (Bit 0) */ +#define RTC_RTC_STATUS_REG_RTC_VALID_TIME_Msk (0x1UL) /*!< RTC_VALID_TIME (Bitfield-Mask: 0x01) */ +/* ================================================== RTC_TIME_ALARM_REG =================================================== */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_PM_Pos (30UL) /*!< RTC_TIME_PM (Bit 30) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_PM_Msk (0x40000000UL) /*!< RTC_TIME_PM (Bitfield-Mask: 0x01) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_HR_T_Pos (28UL) /*!< RTC_TIME_HR_T (Bit 28) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_HR_T_Msk (0x30000000UL) /*!< RTC_TIME_HR_T (Bitfield-Mask: 0x03) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_HR_U_Pos (24UL) /*!< RTC_TIME_HR_U (Bit 24) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_HR_U_Msk (0xf000000UL) /*!< RTC_TIME_HR_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_M_T_Pos (20UL) /*!< RTC_TIME_M_T (Bit 20) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_M_T_Msk (0x700000UL) /*!< RTC_TIME_M_T (Bitfield-Mask: 0x07) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_M_U_Pos (16UL) /*!< RTC_TIME_M_U (Bit 16) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_M_U_Msk (0xf0000UL) /*!< RTC_TIME_M_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_S_T_Pos (12UL) /*!< RTC_TIME_S_T (Bit 12) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_S_T_Msk (0x7000UL) /*!< RTC_TIME_S_T (Bitfield-Mask: 0x07) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_S_U_Pos (8UL) /*!< RTC_TIME_S_U (Bit 8) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_S_U_Msk (0xf00UL) /*!< RTC_TIME_S_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_H_T_Pos (4UL) /*!< RTC_TIME_H_T (Bit 4) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_H_T_Msk (0xf0UL) /*!< RTC_TIME_H_T (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_H_U_Pos (0UL) /*!< RTC_TIME_H_U (Bit 0) */ +#define RTC_RTC_TIME_ALARM_REG_RTC_TIME_H_U_Msk (0xfUL) /*!< RTC_TIME_H_U (Bitfield-Mask: 0x0f) */ +/* ===================================================== RTC_TIME_REG ====================================================== */ +#define RTC_RTC_TIME_REG_RTC_TIME_CH_Pos (31UL) /*!< RTC_TIME_CH (Bit 31) */ +#define RTC_RTC_TIME_REG_RTC_TIME_CH_Msk (0x80000000UL) /*!< RTC_TIME_CH (Bitfield-Mask: 0x01) */ +#define RTC_RTC_TIME_REG_RTC_TIME_PM_Pos (30UL) /*!< RTC_TIME_PM (Bit 30) */ +#define RTC_RTC_TIME_REG_RTC_TIME_PM_Msk (0x40000000UL) /*!< RTC_TIME_PM (Bitfield-Mask: 0x01) */ +#define RTC_RTC_TIME_REG_RTC_TIME_HR_T_Pos (28UL) /*!< RTC_TIME_HR_T (Bit 28) */ +#define RTC_RTC_TIME_REG_RTC_TIME_HR_T_Msk (0x30000000UL) /*!< RTC_TIME_HR_T (Bitfield-Mask: 0x03) */ +#define RTC_RTC_TIME_REG_RTC_TIME_HR_U_Pos (24UL) /*!< RTC_TIME_HR_U (Bit 24) */ +#define RTC_RTC_TIME_REG_RTC_TIME_HR_U_Msk (0xf000000UL) /*!< RTC_TIME_HR_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_TIME_REG_RTC_TIME_M_T_Pos (20UL) /*!< RTC_TIME_M_T (Bit 20) */ +#define RTC_RTC_TIME_REG_RTC_TIME_M_T_Msk (0x700000UL) /*!< RTC_TIME_M_T (Bitfield-Mask: 0x07) */ +#define RTC_RTC_TIME_REG_RTC_TIME_M_U_Pos (16UL) /*!< RTC_TIME_M_U (Bit 16) */ +#define RTC_RTC_TIME_REG_RTC_TIME_M_U_Msk (0xf0000UL) /*!< RTC_TIME_M_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_TIME_REG_RTC_TIME_S_T_Pos (12UL) /*!< RTC_TIME_S_T (Bit 12) */ +#define RTC_RTC_TIME_REG_RTC_TIME_S_T_Msk (0x7000UL) /*!< RTC_TIME_S_T (Bitfield-Mask: 0x07) */ +#define RTC_RTC_TIME_REG_RTC_TIME_S_U_Pos (8UL) /*!< RTC_TIME_S_U (Bit 8) */ +#define RTC_RTC_TIME_REG_RTC_TIME_S_U_Msk (0xf00UL) /*!< RTC_TIME_S_U (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_TIME_REG_RTC_TIME_H_T_Pos (4UL) /*!< RTC_TIME_H_T (Bit 4) */ +#define RTC_RTC_TIME_REG_RTC_TIME_H_T_Msk (0xf0UL) /*!< RTC_TIME_H_T (Bitfield-Mask: 0x0f) */ +#define RTC_RTC_TIME_REG_RTC_TIME_H_U_Pos (0UL) /*!< RTC_TIME_H_U (Bit 0) */ +#define RTC_RTC_TIME_REG_RTC_TIME_H_U_Msk (0xfUL) /*!< RTC_TIME_H_U (Bitfield-Mask: 0x0f) */ + + +/* =========================================================================================================================== */ +/* ================ SDADC ================ */ +/* =========================================================================================================================== */ + +/* ================================================== SDADC_CLEAR_INT_REG ================================================== */ +#define SDADC_SDADC_CLEAR_INT_REG_SDADC_CLR_INT_Pos (0UL) /*!< SDADC_CLR_INT (Bit 0) */ +#define SDADC_SDADC_CLEAR_INT_REG_SDADC_CLR_INT_Msk (0xffffUL) /*!< SDADC_CLR_INT (Bitfield-Mask: 0xffff) */ +/* ==================================================== SDADC_CTRL_REG ===================================================== */ +#define SDADC_SDADC_CTRL_REG_SDADC_DMA_EN_Pos (17UL) /*!< SDADC_DMA_EN (Bit 17) */ +#define SDADC_SDADC_CTRL_REG_SDADC_DMA_EN_Msk (0x20000UL) /*!< SDADC_DMA_EN (Bitfield-Mask: 0x01) */ +#define SDADC_SDADC_CTRL_REG_SDADC_MINT_Pos (16UL) /*!< SDADC_MINT (Bit 16) */ +#define SDADC_SDADC_CTRL_REG_SDADC_MINT_Msk (0x10000UL) /*!< SDADC_MINT (Bitfield-Mask: 0x01) */ +#define SDADC_SDADC_CTRL_REG_SDADC_INT_Pos (15UL) /*!< SDADC_INT (Bit 15) */ +#define SDADC_SDADC_CTRL_REG_SDADC_INT_Msk (0x8000UL) /*!< SDADC_INT (Bitfield-Mask: 0x01) */ +#define SDADC_SDADC_CTRL_REG_SDADC_LDO_OK_Pos (14UL) /*!< SDADC_LDO_OK (Bit 14) */ +#define SDADC_SDADC_CTRL_REG_SDADC_LDO_OK_Msk (0x4000UL) /*!< SDADC_LDO_OK (Bitfield-Mask: 0x01) */ +#define SDADC_SDADC_CTRL_REG_SDADC_VREF_SEL_Pos (13UL) /*!< SDADC_VREF_SEL (Bit 13) */ +#define SDADC_SDADC_CTRL_REG_SDADC_VREF_SEL_Msk (0x2000UL) /*!< SDADC_VREF_SEL (Bitfield-Mask: 0x01) */ +#define SDADC_SDADC_CTRL_REG_SDADC_CONT_Pos (12UL) /*!< SDADC_CONT (Bit 12) */ +#define SDADC_SDADC_CTRL_REG_SDADC_CONT_Msk (0x1000UL) /*!< SDADC_CONT (Bitfield-Mask: 0x01) */ +#define SDADC_SDADC_CTRL_REG_SDADC_OSR_Pos (10UL) /*!< SDADC_OSR (Bit 10) */ +#define SDADC_SDADC_CTRL_REG_SDADC_OSR_Msk (0xc00UL) /*!< SDADC_OSR (Bitfield-Mask: 0x03) */ +#define SDADC_SDADC_CTRL_REG_SDADC_SE_Pos (9UL) /*!< SDADC_SE (Bit 9) */ +#define SDADC_SDADC_CTRL_REG_SDADC_SE_Msk (0x200UL) /*!< SDADC_SE (Bitfield-Mask: 0x01) */ +#define SDADC_SDADC_CTRL_REG_SDADC_INN_SEL_Pos (6UL) /*!< SDADC_INN_SEL (Bit 6) */ +#define SDADC_SDADC_CTRL_REG_SDADC_INN_SEL_Msk (0x1c0UL) /*!< SDADC_INN_SEL (Bitfield-Mask: 0x07) */ +#define SDADC_SDADC_CTRL_REG_SDADC_INP_SEL_Pos (2UL) /*!< SDADC_INP_SEL (Bit 2) */ +#define SDADC_SDADC_CTRL_REG_SDADC_INP_SEL_Msk (0x3cUL) /*!< SDADC_INP_SEL (Bitfield-Mask: 0x0f) */ +#define SDADC_SDADC_CTRL_REG_SDADC_START_Pos (1UL) /*!< SDADC_START (Bit 1) */ +#define SDADC_SDADC_CTRL_REG_SDADC_START_Msk (0x2UL) /*!< SDADC_START (Bitfield-Mask: 0x01) */ +#define SDADC_SDADC_CTRL_REG_SDADC_EN_Pos (0UL) /*!< SDADC_EN (Bit 0) */ +#define SDADC_SDADC_CTRL_REG_SDADC_EN_Msk (0x1UL) /*!< SDADC_EN (Bitfield-Mask: 0x01) */ +/* ================================================== SDADC_GAIN_CORR_REG ================================================== */ +#define SDADC_SDADC_GAIN_CORR_REG_SDADC_GAIN_CORR_Pos (0UL) /*!< SDADC_GAIN_CORR (Bit 0) */ +#define SDADC_SDADC_GAIN_CORR_REG_SDADC_GAIN_CORR_Msk (0x3ffUL) /*!< SDADC_GAIN_CORR (Bitfield-Mask: 0x3ff) */ +/* ================================================== SDADC_OFFS_CORR_REG ================================================== */ +#define SDADC_SDADC_OFFS_CORR_REG_SDADC_OFFS_CORR_Pos (0UL) /*!< SDADC_OFFS_CORR (Bit 0) */ +#define SDADC_SDADC_OFFS_CORR_REG_SDADC_OFFS_CORR_Msk (0x3ffUL) /*!< SDADC_OFFS_CORR (Bitfield-Mask: 0x3ff) */ +/* =================================================== SDADC_RESULT_REG ==================================================== */ +#define SDADC_SDADC_RESULT_REG_SDADC_VAL_Pos (0UL) /*!< SDADC_VAL (Bit 0) */ +#define SDADC_SDADC_RESULT_REG_SDADC_VAL_Msk (0xffffUL) /*!< SDADC_VAL (Bitfield-Mask: 0xffff) */ +/* ==================================================== SDADC_TEST_REG ===================================================== */ +#define SDADC_SDADC_TEST_REG_SDADC_CLK_FREQ_Pos (6UL) /*!< SDADC_CLK_FREQ (Bit 6) */ +#define SDADC_SDADC_TEST_REG_SDADC_CLK_FREQ_Msk (0xc0UL) /*!< SDADC_CLK_FREQ (Bitfield-Mask: 0x03) */ + + +/* =========================================================================================================================== */ +/* ================ SMOTOR ================ */ +/* =========================================================================================================================== */ + +/* ==================================================== CMD_TABLE_BASE ===================================================== */ +/* ===================================================== PG0_CTRL_REG ====================================================== */ +#define SMOTOR_PG0_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ +#define SMOTOR_PG0_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG0_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ +#define SMOTOR_PG0_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG0_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ +#define SMOTOR_PG0_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG0_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ +#define SMOTOR_PG0_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG0_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ +#define SMOTOR_PG0_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG0_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ +#define SMOTOR_PG0_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG0_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ +#define SMOTOR_PG0_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG0_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ +#define SMOTOR_PG0_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG0_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ +#define SMOTOR_PG0_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG0_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ +#define SMOTOR_PG0_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG0_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ +#define SMOTOR_PG0_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG0_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ +#define SMOTOR_PG0_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ +/* ===================================================== PG1_CTRL_REG ====================================================== */ +#define SMOTOR_PG1_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ +#define SMOTOR_PG1_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG1_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ +#define SMOTOR_PG1_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG1_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ +#define SMOTOR_PG1_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG1_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ +#define SMOTOR_PG1_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG1_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ +#define SMOTOR_PG1_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG1_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ +#define SMOTOR_PG1_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG1_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ +#define SMOTOR_PG1_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG1_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ +#define SMOTOR_PG1_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG1_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ +#define SMOTOR_PG1_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG1_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ +#define SMOTOR_PG1_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG1_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ +#define SMOTOR_PG1_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG1_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ +#define SMOTOR_PG1_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ +/* ===================================================== PG2_CTRL_REG ====================================================== */ +#define SMOTOR_PG2_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ +#define SMOTOR_PG2_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG2_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ +#define SMOTOR_PG2_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG2_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ +#define SMOTOR_PG2_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG2_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ +#define SMOTOR_PG2_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG2_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ +#define SMOTOR_PG2_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG2_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ +#define SMOTOR_PG2_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG2_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ +#define SMOTOR_PG2_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG2_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ +#define SMOTOR_PG2_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG2_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ +#define SMOTOR_PG2_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG2_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ +#define SMOTOR_PG2_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG2_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ +#define SMOTOR_PG2_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG2_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ +#define SMOTOR_PG2_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ +/* ===================================================== PG3_CTRL_REG ====================================================== */ +#define SMOTOR_PG3_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ +#define SMOTOR_PG3_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG3_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ +#define SMOTOR_PG3_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG3_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ +#define SMOTOR_PG3_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG3_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ +#define SMOTOR_PG3_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG3_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ +#define SMOTOR_PG3_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG3_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ +#define SMOTOR_PG3_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG3_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ +#define SMOTOR_PG3_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG3_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ +#define SMOTOR_PG3_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG3_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ +#define SMOTOR_PG3_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG3_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ +#define SMOTOR_PG3_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG3_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ +#define SMOTOR_PG3_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG3_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ +#define SMOTOR_PG3_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ +/* ===================================================== PG4_CTRL_REG ====================================================== */ +#define SMOTOR_PG4_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ +#define SMOTOR_PG4_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG4_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ +#define SMOTOR_PG4_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG4_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ +#define SMOTOR_PG4_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG4_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ +#define SMOTOR_PG4_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG4_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ +#define SMOTOR_PG4_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG4_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ +#define SMOTOR_PG4_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG4_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ +#define SMOTOR_PG4_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG4_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ +#define SMOTOR_PG4_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_PG4_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ +#define SMOTOR_PG4_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG4_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ +#define SMOTOR_PG4_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG4_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ +#define SMOTOR_PG4_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ +#define SMOTOR_PG4_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ +#define SMOTOR_PG4_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ +/* ================================================== SMOTOR_CMD_FIFO_REG ================================================== */ +#define SMOTOR_SMOTOR_CMD_FIFO_REG_SMOTOR_CMD_FIFO_Pos (0UL) /*!< SMOTOR_CMD_FIFO (Bit 0) */ +#define SMOTOR_SMOTOR_CMD_FIFO_REG_SMOTOR_CMD_FIFO_Msk (0xffffUL) /*!< SMOTOR_CMD_FIFO (Bitfield-Mask: 0xffff) */ +/* ================================================ SMOTOR_CMD_READ_PTR_REG ================================================ */ +#define SMOTOR_SMOTOR_CMD_READ_PTR_REG_SMOTOR_CMD_READ_PTR_Pos (0UL) /*!< SMOTOR_CMD_READ_PTR (Bit 0) */ +#define SMOTOR_SMOTOR_CMD_READ_PTR_REG_SMOTOR_CMD_READ_PTR_Msk (0x3fUL) /*!< SMOTOR_CMD_READ_PTR (Bitfield-Mask: 0x3f) */ +/* =============================================== SMOTOR_CMD_WRITE_PTR_REG ================================================ */ +#define SMOTOR_SMOTOR_CMD_WRITE_PTR_REG_SMOTOR_CMD_WRITE_PTR_Pos (0UL) /*!< SMOTOR_CMD_WRITE_PTR (Bit 0) */ +#define SMOTOR_SMOTOR_CMD_WRITE_PTR_REG_SMOTOR_CMD_WRITE_PTR_Msk (0x3fUL) /*!< SMOTOR_CMD_WRITE_PTR (Bitfield-Mask: 0x3f) */ +/* ==================================================== SMOTOR_CTRL_REG ==================================================== */ +#define SMOTOR_SMOTOR_CTRL_REG_TRIG_RTC_EVENT_EN_Pos (28UL) /*!< TRIG_RTC_EVENT_EN (Bit 28) */ +#define SMOTOR_SMOTOR_CTRL_REG_TRIG_RTC_EVENT_EN_Msk (0x10000000UL) /*!< TRIG_RTC_EVENT_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_CTRL_REG_MC_LP_CLK_TRIG_EN_Pos (27UL) /*!< MC_LP_CLK_TRIG_EN (Bit 27) */ +#define SMOTOR_SMOTOR_CTRL_REG_MC_LP_CLK_TRIG_EN_Msk (0x8000000UL) /*!< MC_LP_CLK_TRIG_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_THRESHOLD_IRQ_EN_Pos (26UL) /*!< SMOTOR_THRESHOLD_IRQ_EN (Bit 26) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_THRESHOLD_IRQ_EN_Msk (0x4000000UL) /*!< SMOTOR_THRESHOLD_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_THRESHOLD_Pos (21UL) /*!< SMOTOR_THRESHOLD (Bit 21) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_THRESHOLD_Msk (0x3e00000UL) /*!< SMOTOR_THRESHOLD (Bitfield-Mask: 0x1f) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_FIFO_UNR_IRQ_EN_Pos (20UL) /*!< SMOTOR_FIFO_UNR_IRQ_EN (Bit 20) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_FIFO_UNR_IRQ_EN_Msk (0x100000UL) /*!< SMOTOR_FIFO_UNR_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_FIFO_OVF_IRQ_EN_Pos (19UL) /*!< SMOTOR_FIFO_OVF_IRQ_EN (Bit 19) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_FIFO_OVF_IRQ_EN_Msk (0x80000UL) /*!< SMOTOR_FIFO_OVF_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_GENEND_IRQ_EN_Pos (18UL) /*!< SMOTOR_GENEND_IRQ_EN (Bit 18) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_GENEND_IRQ_EN_Msk (0x40000UL) /*!< SMOTOR_GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_GENSTART_IRQ_EN_Pos (17UL) /*!< SMOTOR_GENSTART_IRQ_EN (Bit 17) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_GENSTART_IRQ_EN_Msk (0x20000UL) /*!< SMOTOR_GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_MOI_Pos (7UL) /*!< SMOTOR_MOI (Bit 7) */ +#define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_MOI_Msk (0x1ff80UL) /*!< SMOTOR_MOI (Bitfield-Mask: 0x3ff) */ +#define SMOTOR_SMOTOR_CTRL_REG_CYCLIC_SIZE_Pos (1UL) /*!< CYCLIC_SIZE (Bit 1) */ +#define SMOTOR_SMOTOR_CTRL_REG_CYCLIC_SIZE_Msk (0x7eUL) /*!< CYCLIC_SIZE (Bitfield-Mask: 0x3f) */ +#define SMOTOR_SMOTOR_CTRL_REG_CYCLIC_MODE_Pos (0UL) /*!< CYCLIC_MODE (Bit 0) */ +#define SMOTOR_SMOTOR_CTRL_REG_CYCLIC_MODE_Msk (0x1UL) /*!< CYCLIC_MODE (Bitfield-Mask: 0x01) */ +/* ================================================= SMOTOR_IRQ_CLEAR_REG ================================================== */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_THRESHOLD_IRQ_CLEAR_Pos (4UL) /*!< THRESHOLD_IRQ_CLEAR (Bit 4) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_THRESHOLD_IRQ_CLEAR_Msk (0x10UL) /*!< THRESHOLD_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_FIFO_UNR_IRQ_CLEAR_Pos (3UL) /*!< FIFO_UNR_IRQ_CLEAR (Bit 3) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_FIFO_UNR_IRQ_CLEAR_Msk (0x8UL) /*!< FIFO_UNR_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_FIFO_OVF_IRQ_CLEAR_Pos (2UL) /*!< FIFO_OVF_IRQ_CLEAR (Bit 2) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_FIFO_OVF_IRQ_CLEAR_Msk (0x4UL) /*!< FIFO_OVF_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_GENEND_IRQ_CLEAR_Pos (1UL) /*!< GENEND_IRQ_CLEAR (Bit 1) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_GENEND_IRQ_CLEAR_Msk (0x2UL) /*!< GENEND_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_GENSTART_IRQ_CLEAR_Pos (0UL) /*!< GENSTART_IRQ_CLEAR (Bit 0) */ +#define SMOTOR_SMOTOR_IRQ_CLEAR_REG_GENSTART_IRQ_CLEAR_Msk (0x1UL) /*!< GENSTART_IRQ_CLEAR (Bitfield-Mask: 0x01) */ +/* =================================================== SMOTOR_STATUS_REG =================================================== */ +#define SMOTOR_SMOTOR_STATUS_REG_PG4_BUSY_Pos (9UL) /*!< PG4_BUSY (Bit 9) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG4_BUSY_Msk (0x200UL) /*!< PG4_BUSY (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG3_BUSY_Pos (8UL) /*!< PG3_BUSY (Bit 8) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG3_BUSY_Msk (0x100UL) /*!< PG3_BUSY (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG2_BUSY_Pos (7UL) /*!< PG2_BUSY (Bit 7) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG2_BUSY_Msk (0x80UL) /*!< PG2_BUSY (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG1_BUSY_Pos (6UL) /*!< PG1_BUSY (Bit 6) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG1_BUSY_Msk (0x40UL) /*!< PG1_BUSY (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG0_BUSY_Pos (5UL) /*!< PG0_BUSY (Bit 5) */ +#define SMOTOR_SMOTOR_STATUS_REG_PG0_BUSY_Msk (0x20UL) /*!< PG0_BUSY (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_THRESHOLD_IRQ_STATUS_Pos (4UL) /*!< THRESHOLD_IRQ_STATUS (Bit 4) */ +#define SMOTOR_SMOTOR_STATUS_REG_THRESHOLD_IRQ_STATUS_Msk (0x10UL) /*!< THRESHOLD_IRQ_STATUS (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_FIFO_UNR_IRQ_STATUS_Pos (3UL) /*!< FIFO_UNR_IRQ_STATUS (Bit 3) */ +#define SMOTOR_SMOTOR_STATUS_REG_FIFO_UNR_IRQ_STATUS_Msk (0x8UL) /*!< FIFO_UNR_IRQ_STATUS (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_FIFO_OVF_IRQ_STATUS_Pos (2UL) /*!< FIFO_OVF_IRQ_STATUS (Bit 2) */ +#define SMOTOR_SMOTOR_STATUS_REG_FIFO_OVF_IRQ_STATUS_Msk (0x4UL) /*!< FIFO_OVF_IRQ_STATUS (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_GENEND_IRQ_STATUS_Pos (1UL) /*!< GENEND_IRQ_STATUS (Bit 1) */ +#define SMOTOR_SMOTOR_STATUS_REG_GENEND_IRQ_STATUS_Msk (0x2UL) /*!< GENEND_IRQ_STATUS (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_STATUS_REG_GENSTART_IRQ_STATUS_Pos (0UL) /*!< GENSTART_IRQ_STATUS (Bit 0) */ +#define SMOTOR_SMOTOR_STATUS_REG_GENSTART_IRQ_STATUS_Msk (0x1UL) /*!< GENSTART_IRQ_STATUS (Bitfield-Mask: 0x01) */ +/* ================================================== SMOTOR_TRIGGER_REG =================================================== */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG4_START_Pos (5UL) /*!< PG4_START (Bit 5) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG4_START_Msk (0x20UL) /*!< PG4_START (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG3_START_Pos (4UL) /*!< PG3_START (Bit 4) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG3_START_Msk (0x10UL) /*!< PG3_START (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG2_START_Pos (3UL) /*!< PG2_START (Bit 3) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG2_START_Msk (0x8UL) /*!< PG2_START (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG1_START_Pos (2UL) /*!< PG1_START (Bit 2) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG1_START_Msk (0x4UL) /*!< PG1_START (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG0_START_Pos (1UL) /*!< PG0_START (Bit 1) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_PG0_START_Msk (0x2UL) /*!< PG0_START (Bitfield-Mask: 0x01) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_POP_CMD_Pos (0UL) /*!< POP_CMD (Bit 0) */ +#define SMOTOR_SMOTOR_TRIGGER_REG_POP_CMD_Msk (0x1UL) /*!< POP_CMD (Bitfield-Mask: 0x01) */ +/* ==================================================== WAVETABLE_BASE ===================================================== */ + + +/* =========================================================================================================================== */ +/* ================ SNC ================ */ +/* =========================================================================================================================== */ + +/* ===================================================== SNC_CTRL_REG ====================================================== */ +#define SNC_SNC_CTRL_REG_SNC_IRQ_ACK_Pos (8UL) /*!< SNC_IRQ_ACK (Bit 8) */ +#define SNC_SNC_CTRL_REG_SNC_IRQ_ACK_Msk (0x100UL) /*!< SNC_IRQ_ACK (Bitfield-Mask: 0x01) */ +#define SNC_SNC_CTRL_REG_SNC_IRQ_CONFIG_Pos (6UL) /*!< SNC_IRQ_CONFIG (Bit 6) */ +#define SNC_SNC_CTRL_REG_SNC_IRQ_CONFIG_Msk (0xc0UL) /*!< SNC_IRQ_CONFIG (Bitfield-Mask: 0x03) */ +#define SNC_SNC_CTRL_REG_SNC_IRQ_EN_Pos (5UL) /*!< SNC_IRQ_EN (Bit 5) */ +#define SNC_SNC_CTRL_REG_SNC_IRQ_EN_Msk (0x20UL) /*!< SNC_IRQ_EN (Bitfield-Mask: 0x01) */ +#define SNC_SNC_CTRL_REG_SNC_BRANCH_LOOP_INIT_Pos (4UL) /*!< SNC_BRANCH_LOOP_INIT (Bit 4) */ +#define SNC_SNC_CTRL_REG_SNC_BRANCH_LOOP_INIT_Msk (0x10UL) /*!< SNC_BRANCH_LOOP_INIT (Bitfield-Mask: 0x01) */ +#define SNC_SNC_CTRL_REG_SNC_RESET_Pos (3UL) /*!< SNC_RESET (Bit 3) */ +#define SNC_SNC_CTRL_REG_SNC_RESET_Msk (0x8UL) /*!< SNC_RESET (Bitfield-Mask: 0x01) */ +#define SNC_SNC_CTRL_REG_BUS_ERROR_DETECT_EN_Pos (2UL) /*!< BUS_ERROR_DETECT_EN (Bit 2) */ +#define SNC_SNC_CTRL_REG_BUS_ERROR_DETECT_EN_Msk (0x4UL) /*!< BUS_ERROR_DETECT_EN (Bitfield-Mask: 0x01) */ +#define SNC_SNC_CTRL_REG_SNC_SW_CTRL_Pos (1UL) /*!< SNC_SW_CTRL (Bit 1) */ +#define SNC_SNC_CTRL_REG_SNC_SW_CTRL_Msk (0x2UL) /*!< SNC_SW_CTRL (Bitfield-Mask: 0x01) */ +#define SNC_SNC_CTRL_REG_SNC_EN_Pos (0UL) /*!< SNC_EN (Bit 0) */ +#define SNC_SNC_CTRL_REG_SNC_EN_Msk (0x1UL) /*!< SNC_EN (Bitfield-Mask: 0x01) */ +/* =================================================== SNC_LP_TIMER_REG ==================================================== */ +#define SNC_SNC_LP_TIMER_REG_LP_TIMER_Pos (0UL) /*!< LP_TIMER (Bit 0) */ +#define SNC_SNC_LP_TIMER_REG_LP_TIMER_Msk (0xffUL) /*!< LP_TIMER (Bitfield-Mask: 0xff) */ +/* ====================================================== SNC_PC_REG ======================================================= */ +#define SNC_SNC_PC_REG_PC_REG_Pos (2UL) /*!< PC_REG (Bit 2) */ +#define SNC_SNC_PC_REG_PC_REG_Msk (0x7fffcUL) /*!< PC_REG (Bitfield-Mask: 0x1ffff) */ +/* ====================================================== SNC_R1_REG ======================================================= */ +#define SNC_SNC_R1_REG_R1_REG_Pos (0UL) /*!< R1_REG (Bit 0) */ +#define SNC_SNC_R1_REG_R1_REG_Msk (0xffffffffUL) /*!< R1_REG (Bitfield-Mask: 0xffffffff) */ +/* ====================================================== SNC_R2_REG ======================================================= */ +#define SNC_SNC_R2_REG_R2_REG_Pos (0UL) /*!< R2_REG (Bit 0) */ +#define SNC_SNC_R2_REG_R2_REG_Msk (0xffffffffUL) /*!< R2_REG (Bitfield-Mask: 0xffffffff) */ +/* ==================================================== SNC_STATUS_REG ===================================================== */ +#define SNC_SNC_STATUS_REG_SNC_PC_LOADED_Pos (6UL) /*!< SNC_PC_LOADED (Bit 6) */ +#define SNC_SNC_STATUS_REG_SNC_PC_LOADED_Msk (0x40UL) /*!< SNC_PC_LOADED (Bitfield-Mask: 0x01) */ +#define SNC_SNC_STATUS_REG_SNC_IS_STOPPED_Pos (5UL) /*!< SNC_IS_STOPPED (Bit 5) */ +#define SNC_SNC_STATUS_REG_SNC_IS_STOPPED_Msk (0x20UL) /*!< SNC_IS_STOPPED (Bitfield-Mask: 0x01) */ +#define SNC_SNC_STATUS_REG_HARD_FAULT_STATUS_Pos (4UL) /*!< HARD_FAULT_STATUS (Bit 4) */ +#define SNC_SNC_STATUS_REG_HARD_FAULT_STATUS_Msk (0x10UL) /*!< HARD_FAULT_STATUS (Bitfield-Mask: 0x01) */ +#define SNC_SNC_STATUS_REG_BUS_ERROR_STATUS_Pos (3UL) /*!< BUS_ERROR_STATUS (Bit 3) */ +#define SNC_SNC_STATUS_REG_BUS_ERROR_STATUS_Msk (0x8UL) /*!< BUS_ERROR_STATUS (Bitfield-Mask: 0x01) */ +#define SNC_SNC_STATUS_REG_SNC_DONE_STATUS_Pos (2UL) /*!< SNC_DONE_STATUS (Bit 2) */ +#define SNC_SNC_STATUS_REG_SNC_DONE_STATUS_Msk (0x4UL) /*!< SNC_DONE_STATUS (Bitfield-Mask: 0x01) */ +#define SNC_SNC_STATUS_REG_GR_FLAG_Pos (1UL) /*!< GR_FLAG (Bit 1) */ +#define SNC_SNC_STATUS_REG_GR_FLAG_Msk (0x2UL) /*!< GR_FLAG (Bitfield-Mask: 0x01) */ +#define SNC_SNC_STATUS_REG_EQ_FLAG_Pos (0UL) /*!< EQ_FLAG (Bit 0) */ +#define SNC_SNC_STATUS_REG_EQ_FLAG_Msk (0x1UL) /*!< EQ_FLAG (Bitfield-Mask: 0x01) */ +/* ===================================================== SNC_TMP1_REG ====================================================== */ +#define SNC_SNC_TMP1_REG_TMP1_REG_Pos (0UL) /*!< TMP1_REG (Bit 0) */ +#define SNC_SNC_TMP1_REG_TMP1_REG_Msk (0xffffffffUL) /*!< TMP1_REG (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== SNC_TMP2_REG ====================================================== */ +#define SNC_SNC_TMP2_REG_TMP2_REG_Pos (0UL) /*!< TMP2_REG (Bit 0) */ +#define SNC_SNC_TMP2_REG_TMP2_REG_Msk (0xffffffffUL) /*!< TMP2_REG (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + +/* =================================================== SPI_CLEAR_INT_REG =================================================== */ +#define SPI_SPI_CLEAR_INT_REG_SPI_CLEAR_INT_Pos (0UL) /*!< SPI_CLEAR_INT (Bit 0) */ +#define SPI_SPI_CLEAR_INT_REG_SPI_CLEAR_INT_Msk (0xffffffffUL) /*!< SPI_CLEAR_INT (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== SPI_CTRL_REG ====================================================== */ +#define SPI_SPI_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Pos (25UL) /*!< SPI_TX_FIFO_NOTFULL_MASK (Bit 25) */ +#define SPI_SPI_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Msk (0x2000000UL) /*!< SPI_TX_FIFO_NOTFULL_MASK (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_DMA_TXREQ_MODE_Pos (24UL) /*!< SPI_DMA_TXREQ_MODE (Bit 24) */ +#define SPI_SPI_CTRL_REG_SPI_DMA_TXREQ_MODE_Msk (0x1000000UL) /*!< SPI_DMA_TXREQ_MODE (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_TX_FIFO_EMPTY_Pos (23UL) /*!< SPI_TX_FIFO_EMPTY (Bit 23) */ +#define SPI_SPI_CTRL_REG_SPI_TX_FIFO_EMPTY_Msk (0x800000UL) /*!< SPI_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_RX_FIFO_FULL_Pos (22UL) /*!< SPI_RX_FIFO_FULL (Bit 22) */ +#define SPI_SPI_CTRL_REG_SPI_RX_FIFO_FULL_Msk (0x400000UL) /*!< SPI_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_RX_FIFO_EMPTY_Pos (21UL) /*!< SPI_RX_FIFO_EMPTY (Bit 21) */ +#define SPI_SPI_CTRL_REG_SPI_RX_FIFO_EMPTY_Msk (0x200000UL) /*!< SPI_RX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_9BIT_VAL_Pos (20UL) /*!< SPI_9BIT_VAL (Bit 20) */ +#define SPI_SPI_CTRL_REG_SPI_9BIT_VAL_Msk (0x100000UL) /*!< SPI_9BIT_VAL (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_BUSY_Pos (19UL) /*!< SPI_BUSY (Bit 19) */ +#define SPI_SPI_CTRL_REG_SPI_BUSY_Msk (0x80000UL) /*!< SPI_BUSY (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_PRIORITY_Pos (18UL) /*!< SPI_PRIORITY (Bit 18) */ +#define SPI_SPI_CTRL_REG_SPI_PRIORITY_Msk (0x40000UL) /*!< SPI_PRIORITY (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_FIFO_MODE_Pos (16UL) /*!< SPI_FIFO_MODE (Bit 16) */ +#define SPI_SPI_CTRL_REG_SPI_FIFO_MODE_Msk (0x30000UL) /*!< SPI_FIFO_MODE (Bitfield-Mask: 0x03) */ +#define SPI_SPI_CTRL_REG_SPI_EN_CTRL_Pos (15UL) /*!< SPI_EN_CTRL (Bit 15) */ +#define SPI_SPI_CTRL_REG_SPI_EN_CTRL_Msk (0x8000UL) /*!< SPI_EN_CTRL (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_MINT_Pos (14UL) /*!< SPI_MINT (Bit 14) */ +#define SPI_SPI_CTRL_REG_SPI_MINT_Msk (0x4000UL) /*!< SPI_MINT (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_INT_BIT_Pos (13UL) /*!< SPI_INT_BIT (Bit 13) */ +#define SPI_SPI_CTRL_REG_SPI_INT_BIT_Msk (0x2000UL) /*!< SPI_INT_BIT (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_DI_Pos (12UL) /*!< SPI_DI (Bit 12) */ +#define SPI_SPI_CTRL_REG_SPI_DI_Msk (0x1000UL) /*!< SPI_DI (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_TXH_Pos (11UL) /*!< SPI_TXH (Bit 11) */ +#define SPI_SPI_CTRL_REG_SPI_TXH_Msk (0x800UL) /*!< SPI_TXH (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_FORCE_DO_Pos (10UL) /*!< SPI_FORCE_DO (Bit 10) */ +#define SPI_SPI_CTRL_REG_SPI_FORCE_DO_Msk (0x400UL) /*!< SPI_FORCE_DO (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_WORD_Pos (8UL) /*!< SPI_WORD (Bit 8) */ +#define SPI_SPI_CTRL_REG_SPI_WORD_Msk (0x300UL) /*!< SPI_WORD (Bitfield-Mask: 0x03) */ +#define SPI_SPI_CTRL_REG_SPI_RST_Pos (7UL) /*!< SPI_RST (Bit 7) */ +#define SPI_SPI_CTRL_REG_SPI_RST_Msk (0x80UL) /*!< SPI_RST (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_SMN_Pos (6UL) /*!< SPI_SMN (Bit 6) */ +#define SPI_SPI_CTRL_REG_SPI_SMN_Msk (0x40UL) /*!< SPI_SMN (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_DO_Pos (5UL) /*!< SPI_DO (Bit 5) */ +#define SPI_SPI_CTRL_REG_SPI_DO_Msk (0x20UL) /*!< SPI_DO (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_CLK_Pos (3UL) /*!< SPI_CLK (Bit 3) */ +#define SPI_SPI_CTRL_REG_SPI_CLK_Msk (0x18UL) /*!< SPI_CLK (Bitfield-Mask: 0x03) */ +#define SPI_SPI_CTRL_REG_SPI_POL_Pos (2UL) /*!< SPI_POL (Bit 2) */ +#define SPI_SPI_CTRL_REG_SPI_POL_Msk (0x4UL) /*!< SPI_POL (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_PHA_Pos (1UL) /*!< SPI_PHA (Bit 1) */ +#define SPI_SPI_CTRL_REG_SPI_PHA_Msk (0x2UL) /*!< SPI_PHA (Bitfield-Mask: 0x01) */ +#define SPI_SPI_CTRL_REG_SPI_ON_Pos (0UL) /*!< SPI_ON (Bit 0) */ +#define SPI_SPI_CTRL_REG_SPI_ON_Msk (0x1UL) /*!< SPI_ON (Bitfield-Mask: 0x01) */ +/* ===================================================== SPI_RX_TX_REG ===================================================== */ +#define SPI_SPI_RX_TX_REG_SPI_DATA_Pos (0UL) /*!< SPI_DATA (Bit 0) */ +#define SPI_SPI_RX_TX_REG_SPI_DATA_Msk (0xffffffffUL) /*!< SPI_DATA (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ SPI2 ================ */ +/* =========================================================================================================================== */ + +/* ================================================== SPI2_CLEAR_INT_REG =================================================== */ +#define SPI2_SPI2_CLEAR_INT_REG_SPI_CLEAR_INT_Pos (0UL) /*!< SPI_CLEAR_INT (Bit 0) */ +#define SPI2_SPI2_CLEAR_INT_REG_SPI_CLEAR_INT_Msk (0xffffffffUL) /*!< SPI_CLEAR_INT (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== SPI2_CTRL_REG ===================================================== */ +#define SPI2_SPI2_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Pos (25UL) /*!< SPI_TX_FIFO_NOTFULL_MASK (Bit 25) */ +#define SPI2_SPI2_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Msk (0x2000000UL) /*!< SPI_TX_FIFO_NOTFULL_MASK (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_DMA_TXREQ_MODE_Pos (24UL) /*!< SPI_DMA_TXREQ_MODE (Bit 24) */ +#define SPI2_SPI2_CTRL_REG_SPI_DMA_TXREQ_MODE_Msk (0x1000000UL) /*!< SPI_DMA_TXREQ_MODE (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_TX_FIFO_EMPTY_Pos (23UL) /*!< SPI_TX_FIFO_EMPTY (Bit 23) */ +#define SPI2_SPI2_CTRL_REG_SPI_TX_FIFO_EMPTY_Msk (0x800000UL) /*!< SPI_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_RX_FIFO_FULL_Pos (22UL) /*!< SPI_RX_FIFO_FULL (Bit 22) */ +#define SPI2_SPI2_CTRL_REG_SPI_RX_FIFO_FULL_Msk (0x400000UL) /*!< SPI_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_RX_FIFO_EMPTY_Pos (21UL) /*!< SPI_RX_FIFO_EMPTY (Bit 21) */ +#define SPI2_SPI2_CTRL_REG_SPI_RX_FIFO_EMPTY_Msk (0x200000UL) /*!< SPI_RX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_9BIT_VAL_Pos (20UL) /*!< SPI_9BIT_VAL (Bit 20) */ +#define SPI2_SPI2_CTRL_REG_SPI_9BIT_VAL_Msk (0x100000UL) /*!< SPI_9BIT_VAL (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_BUSY_Pos (19UL) /*!< SPI_BUSY (Bit 19) */ +#define SPI2_SPI2_CTRL_REG_SPI_BUSY_Msk (0x80000UL) /*!< SPI_BUSY (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_PRIORITY_Pos (18UL) /*!< SPI_PRIORITY (Bit 18) */ +#define SPI2_SPI2_CTRL_REG_SPI_PRIORITY_Msk (0x40000UL) /*!< SPI_PRIORITY (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_FIFO_MODE_Pos (16UL) /*!< SPI_FIFO_MODE (Bit 16) */ +#define SPI2_SPI2_CTRL_REG_SPI_FIFO_MODE_Msk (0x30000UL) /*!< SPI_FIFO_MODE (Bitfield-Mask: 0x03) */ +#define SPI2_SPI2_CTRL_REG_SPI_EN_CTRL_Pos (15UL) /*!< SPI_EN_CTRL (Bit 15) */ +#define SPI2_SPI2_CTRL_REG_SPI_EN_CTRL_Msk (0x8000UL) /*!< SPI_EN_CTRL (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_MINT_Pos (14UL) /*!< SPI_MINT (Bit 14) */ +#define SPI2_SPI2_CTRL_REG_SPI_MINT_Msk (0x4000UL) /*!< SPI_MINT (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_INT_BIT_Pos (13UL) /*!< SPI_INT_BIT (Bit 13) */ +#define SPI2_SPI2_CTRL_REG_SPI_INT_BIT_Msk (0x2000UL) /*!< SPI_INT_BIT (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_DI_Pos (12UL) /*!< SPI_DI (Bit 12) */ +#define SPI2_SPI2_CTRL_REG_SPI_DI_Msk (0x1000UL) /*!< SPI_DI (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_TXH_Pos (11UL) /*!< SPI_TXH (Bit 11) */ +#define SPI2_SPI2_CTRL_REG_SPI_TXH_Msk (0x800UL) /*!< SPI_TXH (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_FORCE_DO_Pos (10UL) /*!< SPI_FORCE_DO (Bit 10) */ +#define SPI2_SPI2_CTRL_REG_SPI_FORCE_DO_Msk (0x400UL) /*!< SPI_FORCE_DO (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_WORD_Pos (8UL) /*!< SPI_WORD (Bit 8) */ +#define SPI2_SPI2_CTRL_REG_SPI_WORD_Msk (0x300UL) /*!< SPI_WORD (Bitfield-Mask: 0x03) */ +#define SPI2_SPI2_CTRL_REG_SPI_RST_Pos (7UL) /*!< SPI_RST (Bit 7) */ +#define SPI2_SPI2_CTRL_REG_SPI_RST_Msk (0x80UL) /*!< SPI_RST (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_SMN_Pos (6UL) /*!< SPI_SMN (Bit 6) */ +#define SPI2_SPI2_CTRL_REG_SPI_SMN_Msk (0x40UL) /*!< SPI_SMN (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_DO_Pos (5UL) /*!< SPI_DO (Bit 5) */ +#define SPI2_SPI2_CTRL_REG_SPI_DO_Msk (0x20UL) /*!< SPI_DO (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_CLK_Pos (3UL) /*!< SPI_CLK (Bit 3) */ +#define SPI2_SPI2_CTRL_REG_SPI_CLK_Msk (0x18UL) /*!< SPI_CLK (Bitfield-Mask: 0x03) */ +#define SPI2_SPI2_CTRL_REG_SPI_POL_Pos (2UL) /*!< SPI_POL (Bit 2) */ +#define SPI2_SPI2_CTRL_REG_SPI_POL_Msk (0x4UL) /*!< SPI_POL (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_PHA_Pos (1UL) /*!< SPI_PHA (Bit 1) */ +#define SPI2_SPI2_CTRL_REG_SPI_PHA_Msk (0x2UL) /*!< SPI_PHA (Bitfield-Mask: 0x01) */ +#define SPI2_SPI2_CTRL_REG_SPI_ON_Pos (0UL) /*!< SPI_ON (Bit 0) */ +#define SPI2_SPI2_CTRL_REG_SPI_ON_Msk (0x1UL) /*!< SPI_ON (Bitfield-Mask: 0x01) */ +/* ==================================================== SPI2_RX_TX_REG ===================================================== */ +#define SPI2_SPI2_RX_TX_REG_SPI_DATA_Pos (0UL) /*!< SPI_DATA (Bit 0) */ +#define SPI2_SPI2_RX_TX_REG_SPI_DATA_Msk (0xffffffffUL) /*!< SPI_DATA (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ SYS_WDOG ================ */ +/* =========================================================================================================================== */ + +/* =================================================== WATCHDOG_CTRL_REG =================================================== */ +#define SYS_WDOG_WATCHDOG_CTRL_REG_WRITE_BUSY_Pos (3UL) /*!< WRITE_BUSY (Bit 3) */ +#define SYS_WDOG_WATCHDOG_CTRL_REG_WRITE_BUSY_Msk (0x8UL) /*!< WRITE_BUSY (Bitfield-Mask: 0x01) */ +#define SYS_WDOG_WATCHDOG_CTRL_REG_WDOG_FREEZE_EN_Pos (2UL) /*!< WDOG_FREEZE_EN (Bit 2) */ +#define SYS_WDOG_WATCHDOG_CTRL_REG_WDOG_FREEZE_EN_Msk (0x4UL) /*!< WDOG_FREEZE_EN (Bitfield-Mask: 0x01) */ +#define SYS_WDOG_WATCHDOG_CTRL_REG_NMI_RST_Pos (0UL) /*!< NMI_RST (Bit 0) */ +#define SYS_WDOG_WATCHDOG_CTRL_REG_NMI_RST_Msk (0x1UL) /*!< NMI_RST (Bitfield-Mask: 0x01) */ +/* ===================================================== WATCHDOG_REG ====================================================== */ +#define SYS_WDOG_WATCHDOG_REG_WDOG_WEN_Pos (14UL) /*!< WDOG_WEN (Bit 14) */ +#define SYS_WDOG_WATCHDOG_REG_WDOG_WEN_Msk (0xffffc000UL) /*!< WDOG_WEN (Bitfield-Mask: 0x3ffff) */ +#define SYS_WDOG_WATCHDOG_REG_WDOG_VAL_NEG_Pos (13UL) /*!< WDOG_VAL_NEG (Bit 13) */ +#define SYS_WDOG_WATCHDOG_REG_WDOG_VAL_NEG_Msk (0x2000UL) /*!< WDOG_VAL_NEG (Bitfield-Mask: 0x01) */ +#define SYS_WDOG_WATCHDOG_REG_WDOG_VAL_Pos (0UL) /*!< WDOG_VAL (Bit 0) */ +#define SYS_WDOG_WATCHDOG_REG_WDOG_VAL_Msk (0x1fffUL) /*!< WDOG_VAL (Bitfield-Mask: 0x1fff) */ + + +/* =========================================================================================================================== */ +/* ================ TIMER ================ */ +/* =========================================================================================================================== */ + +/* ================================================ TIMER_CAPTURE_GPIO1_REG ================================================ */ +#define TIMER_TIMER_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Pos (0UL) /*!< TIM_CAPTURE_GPIO1 (Bit 0) */ +#define TIMER_TIMER_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO1 (Bitfield-Mask: 0xffffff) */ +/* ================================================ TIMER_CAPTURE_GPIO2_REG ================================================ */ +#define TIMER_TIMER_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Pos (0UL) /*!< TIM_CAPTURE_GPIO2 (Bit 0) */ +#define TIMER_TIMER_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO2 (Bitfield-Mask: 0xffffff) */ +/* ================================================ TIMER_CAPTURE_GPIO3_REG ================================================ */ +#define TIMER_TIMER_CAPTURE_GPIO3_REG_TIM_CAPTURE_GPIO3_Pos (0UL) /*!< TIM_CAPTURE_GPIO3 (Bit 0) */ +#define TIMER_TIMER_CAPTURE_GPIO3_REG_TIM_CAPTURE_GPIO3_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO3 (Bitfield-Mask: 0xffffff) */ +/* ================================================ TIMER_CAPTURE_GPIO4_REG ================================================ */ +#define TIMER_TIMER_CAPTURE_GPIO4_REG_TIM_CAPTURE_GPIO4_Pos (0UL) /*!< TIM_CAPTURE_GPIO4 (Bit 0) */ +#define TIMER_TIMER_CAPTURE_GPIO4_REG_TIM_CAPTURE_GPIO4_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO4 (Bitfield-Mask: 0xffffff) */ +/* ============================================== TIMER_CLEAR_GPIO_EVENT_REG =============================================== */ +#define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO4_EVENT_Pos (3UL) /*!< TIM_CLEAR_GPIO4_EVENT (Bit 3) */ +#define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO4_EVENT_Msk (0x8UL) /*!< TIM_CLEAR_GPIO4_EVENT (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO3_EVENT_Pos (2UL) /*!< TIM_CLEAR_GPIO3_EVENT (Bit 2) */ +#define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO3_EVENT_Msk (0x4UL) /*!< TIM_CLEAR_GPIO3_EVENT (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO2_EVENT_Pos (1UL) /*!< TIM_CLEAR_GPIO2_EVENT (Bit 1) */ +#define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO2_EVENT_Msk (0x2UL) /*!< TIM_CLEAR_GPIO2_EVENT (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO1_EVENT_Pos (0UL) /*!< TIM_CLEAR_GPIO1_EVENT (Bit 0) */ +#define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO1_EVENT_Msk (0x1UL) /*!< TIM_CLEAR_GPIO1_EVENT (Bitfield-Mask: 0x01) */ +/* ================================================== TIMER_CLEAR_IRQ_REG ================================================== */ +#define TIMER_TIMER_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Pos (0UL) /*!< TIM_CLEAR_IRQ (Bit 0) */ +#define TIMER_TIMER_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Msk (0x1UL) /*!< TIM_CLEAR_IRQ (Bitfield-Mask: 0x01) */ +/* ==================================================== TIMER_CTRL_REG ===================================================== */ +#define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO4_IRQ_EN_Pos (14UL) /*!< TIM_CAP_GPIO4_IRQ_EN (Bit 14) */ +#define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO4_IRQ_EN_Msk (0x4000UL) /*!< TIM_CAP_GPIO4_IRQ_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO3_IRQ_EN_Pos (13UL) /*!< TIM_CAP_GPIO3_IRQ_EN (Bit 13) */ +#define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO3_IRQ_EN_Msk (0x2000UL) /*!< TIM_CAP_GPIO3_IRQ_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO2_IRQ_EN_Pos (12UL) /*!< TIM_CAP_GPIO2_IRQ_EN (Bit 12) */ +#define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO2_IRQ_EN_Msk (0x1000UL) /*!< TIM_CAP_GPIO2_IRQ_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO1_IRQ_EN_Pos (11UL) /*!< TIM_CAP_GPIO1_IRQ_EN (Bit 11) */ +#define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO1_IRQ_EN_Msk (0x800UL) /*!< TIM_CAP_GPIO1_IRQ_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_IN4_EVENT_FALL_EN_Pos (10UL) /*!< TIM_IN4_EVENT_FALL_EN (Bit 10) */ +#define TIMER_TIMER_CTRL_REG_TIM_IN4_EVENT_FALL_EN_Msk (0x400UL) /*!< TIM_IN4_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_IN3_EVENT_FALL_EN_Pos (9UL) /*!< TIM_IN3_EVENT_FALL_EN (Bit 9) */ +#define TIMER_TIMER_CTRL_REG_TIM_IN3_EVENT_FALL_EN_Msk (0x200UL) /*!< TIM_IN3_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_CLK_EN_Pos (8UL) /*!< TIM_CLK_EN (Bit 8) */ +#define TIMER_TIMER_CTRL_REG_TIM_CLK_EN_Msk (0x100UL) /*!< TIM_CLK_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_SYS_CLK_EN_Pos (7UL) /*!< TIM_SYS_CLK_EN (Bit 7) */ +#define TIMER_TIMER_CTRL_REG_TIM_SYS_CLK_EN_Msk (0x80UL) /*!< TIM_SYS_CLK_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_FREE_RUN_MODE_EN_Pos (6UL) /*!< TIM_FREE_RUN_MODE_EN (Bit 6) */ +#define TIMER_TIMER_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk (0x40UL) /*!< TIM_FREE_RUN_MODE_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_IRQ_EN_Pos (5UL) /*!< TIM_IRQ_EN (Bit 5) */ +#define TIMER_TIMER_CTRL_REG_TIM_IRQ_EN_Msk (0x20UL) /*!< TIM_IRQ_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Pos (4UL) /*!< TIM_IN2_EVENT_FALL_EN (Bit 4) */ +#define TIMER_TIMER_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Msk (0x10UL) /*!< TIM_IN2_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Pos (3UL) /*!< TIM_IN1_EVENT_FALL_EN (Bit 3) */ +#define TIMER_TIMER_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Msk (0x8UL) /*!< TIM_IN1_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_COUNT_DOWN_EN_Pos (2UL) /*!< TIM_COUNT_DOWN_EN (Bit 2) */ +#define TIMER_TIMER_CTRL_REG_TIM_COUNT_DOWN_EN_Msk (0x4UL) /*!< TIM_COUNT_DOWN_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_ONESHOT_MODE_EN_Pos (1UL) /*!< TIM_ONESHOT_MODE_EN (Bit 1) */ +#define TIMER_TIMER_CTRL_REG_TIM_ONESHOT_MODE_EN_Msk (0x2UL) /*!< TIM_ONESHOT_MODE_EN (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_CTRL_REG_TIM_EN_Pos (0UL) /*!< TIM_EN (Bit 0) */ +#define TIMER_TIMER_CTRL_REG_TIM_EN_Msk (0x1UL) /*!< TIM_EN (Bitfield-Mask: 0x01) */ +/* ================================================= TIMER_GPIO1_CONF_REG ================================================== */ +#define TIMER_TIMER_GPIO1_CONF_REG_TIM_GPIO1_CONF_Pos (0UL) /*!< TIM_GPIO1_CONF (Bit 0) */ +#define TIMER_TIMER_GPIO1_CONF_REG_TIM_GPIO1_CONF_Msk (0x3fUL) /*!< TIM_GPIO1_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER_GPIO2_CONF_REG ================================================== */ +#define TIMER_TIMER_GPIO2_CONF_REG_TIM_GPIO2_CONF_Pos (0UL) /*!< TIM_GPIO2_CONF (Bit 0) */ +#define TIMER_TIMER_GPIO2_CONF_REG_TIM_GPIO2_CONF_Msk (0x3fUL) /*!< TIM_GPIO2_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER_GPIO3_CONF_REG ================================================== */ +#define TIMER_TIMER_GPIO3_CONF_REG_TIM_GPIO3_CONF_Pos (0UL) /*!< TIM_GPIO3_CONF (Bit 0) */ +#define TIMER_TIMER_GPIO3_CONF_REG_TIM_GPIO3_CONF_Msk (0x3fUL) /*!< TIM_GPIO3_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER_GPIO4_CONF_REG ================================================== */ +#define TIMER_TIMER_GPIO4_CONF_REG_TIM_GPIO4_CONF_Pos (0UL) /*!< TIM_GPIO4_CONF (Bit 0) */ +#define TIMER_TIMER_GPIO4_CONF_REG_TIM_GPIO4_CONF_Msk (0x3fUL) /*!< TIM_GPIO4_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================== TIMER_PRESCALER_REG ================================================== */ +#define TIMER_TIMER_PRESCALER_REG_TIM_PRESCALER_Pos (0UL) /*!< TIM_PRESCALER (Bit 0) */ +#define TIMER_TIMER_PRESCALER_REG_TIM_PRESCALER_Msk (0x1fUL) /*!< TIM_PRESCALER (Bitfield-Mask: 0x1f) */ +/* ================================================ TIMER_PRESCALER_VAL_REG ================================================ */ +#define TIMER_TIMER_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Pos (0UL) /*!< TIM_PRESCALER_VAL (Bit 0) */ +#define TIMER_TIMER_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Msk (0x1fUL) /*!< TIM_PRESCALER_VAL (Bitfield-Mask: 0x1f) */ +/* =================================================== TIMER_PWM_DC_REG ==================================================== */ +#define TIMER_TIMER_PWM_DC_REG_TIM_PWM_DC_Pos (0UL) /*!< TIM_PWM_DC (Bit 0) */ +#define TIMER_TIMER_PWM_DC_REG_TIM_PWM_DC_Msk (0xffffUL) /*!< TIM_PWM_DC (Bitfield-Mask: 0xffff) */ +/* ================================================== TIMER_PWM_FREQ_REG =================================================== */ +#define TIMER_TIMER_PWM_FREQ_REG_TIM_PWM_FREQ_Pos (0UL) /*!< TIM_PWM_FREQ (Bit 0) */ +#define TIMER_TIMER_PWM_FREQ_REG_TIM_PWM_FREQ_Msk (0xffffUL) /*!< TIM_PWM_FREQ (Bitfield-Mask: 0xffff) */ +/* =================================================== TIMER_RELOAD_REG ==================================================== */ +#define TIMER_TIMER_RELOAD_REG_TIM_RELOAD_Pos (0UL) /*!< TIM_RELOAD (Bit 0) */ +#define TIMER_TIMER_RELOAD_REG_TIM_RELOAD_Msk (0xffffffUL) /*!< TIM_RELOAD (Bitfield-Mask: 0xffffff) */ +/* ================================================== TIMER_SHOTWIDTH_REG ================================================== */ +#define TIMER_TIMER_SHOTWIDTH_REG_TIM_SHOTWIDTH_Pos (0UL) /*!< TIM_SHOTWIDTH (Bit 0) */ +#define TIMER_TIMER_SHOTWIDTH_REG_TIM_SHOTWIDTH_Msk (0xffffffUL) /*!< TIM_SHOTWIDTH (Bitfield-Mask: 0xffffff) */ +/* =================================================== TIMER_STATUS_REG ==================================================== */ +#define TIMER_TIMER_STATUS_REG_TIM_GPIO4_EVENT_PENDING_Pos (7UL) /*!< TIM_GPIO4_EVENT_PENDING (Bit 7) */ +#define TIMER_TIMER_STATUS_REG_TIM_GPIO4_EVENT_PENDING_Msk (0x80UL) /*!< TIM_GPIO4_EVENT_PENDING (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_STATUS_REG_TIM_GPIO3_EVENT_PENDING_Pos (6UL) /*!< TIM_GPIO3_EVENT_PENDING (Bit 6) */ +#define TIMER_TIMER_STATUS_REG_TIM_GPIO3_EVENT_PENDING_Msk (0x40UL) /*!< TIM_GPIO3_EVENT_PENDING (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_STATUS_REG_TIM_GPIO2_EVENT_PENDING_Pos (5UL) /*!< TIM_GPIO2_EVENT_PENDING (Bit 5) */ +#define TIMER_TIMER_STATUS_REG_TIM_GPIO2_EVENT_PENDING_Msk (0x20UL) /*!< TIM_GPIO2_EVENT_PENDING (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_STATUS_REG_TIM_GPIO1_EVENT_PENDING_Pos (4UL) /*!< TIM_GPIO1_EVENT_PENDING (Bit 4) */ +#define TIMER_TIMER_STATUS_REG_TIM_GPIO1_EVENT_PENDING_Msk (0x10UL) /*!< TIM_GPIO1_EVENT_PENDING (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_STATUS_REG_TIM_ONESHOT_PHASE_Pos (2UL) /*!< TIM_ONESHOT_PHASE (Bit 2) */ +#define TIMER_TIMER_STATUS_REG_TIM_ONESHOT_PHASE_Msk (0xcUL) /*!< TIM_ONESHOT_PHASE (Bitfield-Mask: 0x03) */ +#define TIMER_TIMER_STATUS_REG_TIM_IN2_STATE_Pos (1UL) /*!< TIM_IN2_STATE (Bit 1) */ +#define TIMER_TIMER_STATUS_REG_TIM_IN2_STATE_Msk (0x2UL) /*!< TIM_IN2_STATE (Bitfield-Mask: 0x01) */ +#define TIMER_TIMER_STATUS_REG_TIM_IN1_STATE_Pos (0UL) /*!< TIM_IN1_STATE (Bit 0) */ +#define TIMER_TIMER_STATUS_REG_TIM_IN1_STATE_Msk (0x1UL) /*!< TIM_IN1_STATE (Bitfield-Mask: 0x01) */ +/* ================================================== TIMER_TIMER_VAL_REG ================================================== */ +#define TIMER_TIMER_TIMER_VAL_REG_TIM_TIMER_VALUE_Pos (0UL) /*!< TIM_TIMER_VALUE (Bit 0) */ +#define TIMER_TIMER_TIMER_VAL_REG_TIM_TIMER_VALUE_Msk (0xffffffUL) /*!< TIM_TIMER_VALUE (Bitfield-Mask: 0xffffff) */ + + +/* =========================================================================================================================== */ +/* ================ TIMER2 ================ */ +/* =========================================================================================================================== */ + +/* =============================================== TIMER2_CAPTURE_GPIO1_REG ================================================ */ +#define TIMER2_TIMER2_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Pos (0UL) /*!< TIM_CAPTURE_GPIO1 (Bit 0) */ +#define TIMER2_TIMER2_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO1 (Bitfield-Mask: 0xffffff) */ +/* =============================================== TIMER2_CAPTURE_GPIO2_REG ================================================ */ +#define TIMER2_TIMER2_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Pos (0UL) /*!< TIM_CAPTURE_GPIO2 (Bit 0) */ +#define TIMER2_TIMER2_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO2 (Bitfield-Mask: 0xffffff) */ +/* ================================================= TIMER2_CLEAR_IRQ_REG ================================================== */ +#define TIMER2_TIMER2_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Pos (0UL) /*!< TIM_CLEAR_IRQ (Bit 0) */ +#define TIMER2_TIMER2_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Msk (0x1UL) /*!< TIM_CLEAR_IRQ (Bitfield-Mask: 0x01) */ +/* ==================================================== TIMER2_CTRL_REG ==================================================== */ +#define TIMER2_TIMER2_CTRL_REG_TIM_CLK_EN_Pos (8UL) /*!< TIM_CLK_EN (Bit 8) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_CLK_EN_Msk (0x100UL) /*!< TIM_CLK_EN (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_SYS_CLK_EN_Pos (7UL) /*!< TIM_SYS_CLK_EN (Bit 7) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_SYS_CLK_EN_Msk (0x80UL) /*!< TIM_SYS_CLK_EN (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_FREE_RUN_MODE_EN_Pos (6UL) /*!< TIM_FREE_RUN_MODE_EN (Bit 6) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk (0x40UL) /*!< TIM_FREE_RUN_MODE_EN (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_IRQ_EN_Pos (5UL) /*!< TIM_IRQ_EN (Bit 5) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_IRQ_EN_Msk (0x20UL) /*!< TIM_IRQ_EN (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Pos (4UL) /*!< TIM_IN2_EVENT_FALL_EN (Bit 4) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Msk (0x10UL) /*!< TIM_IN2_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Pos (3UL) /*!< TIM_IN1_EVENT_FALL_EN (Bit 3) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Msk (0x8UL) /*!< TIM_IN1_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_COUNT_DOWN_EN_Pos (2UL) /*!< TIM_COUNT_DOWN_EN (Bit 2) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_COUNT_DOWN_EN_Msk (0x4UL) /*!< TIM_COUNT_DOWN_EN (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_ONESHOT_MODE_EN_Pos (1UL) /*!< TIM_ONESHOT_MODE_EN (Bit 1) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_ONESHOT_MODE_EN_Msk (0x2UL) /*!< TIM_ONESHOT_MODE_EN (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_EN_Pos (0UL) /*!< TIM_EN (Bit 0) */ +#define TIMER2_TIMER2_CTRL_REG_TIM_EN_Msk (0x1UL) /*!< TIM_EN (Bitfield-Mask: 0x01) */ +/* ================================================= TIMER2_GPIO1_CONF_REG ================================================= */ +#define TIMER2_TIMER2_GPIO1_CONF_REG_TIM_GPIO1_CONF_Pos (0UL) /*!< TIM_GPIO1_CONF (Bit 0) */ +#define TIMER2_TIMER2_GPIO1_CONF_REG_TIM_GPIO1_CONF_Msk (0x3fUL) /*!< TIM_GPIO1_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER2_GPIO2_CONF_REG ================================================= */ +#define TIMER2_TIMER2_GPIO2_CONF_REG_TIM_GPIO2_CONF_Pos (0UL) /*!< TIM_GPIO2_CONF (Bit 0) */ +#define TIMER2_TIMER2_GPIO2_CONF_REG_TIM_GPIO2_CONF_Msk (0x3fUL) /*!< TIM_GPIO2_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER2_PRESCALER_REG ================================================== */ +#define TIMER2_TIMER2_PRESCALER_REG_TIM_PRESCALER_Pos (0UL) /*!< TIM_PRESCALER (Bit 0) */ +#define TIMER2_TIMER2_PRESCALER_REG_TIM_PRESCALER_Msk (0x1fUL) /*!< TIM_PRESCALER (Bitfield-Mask: 0x1f) */ +/* =============================================== TIMER2_PRESCALER_VAL_REG ================================================ */ +#define TIMER2_TIMER2_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Pos (0UL) /*!< TIM_PRESCALER_VAL (Bit 0) */ +#define TIMER2_TIMER2_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Msk (0x1fUL) /*!< TIM_PRESCALER_VAL (Bitfield-Mask: 0x1f) */ +/* =================================================== TIMER2_PWM_DC_REG =================================================== */ +#define TIMER2_TIMER2_PWM_DC_REG_TIM_PWM_DC_Pos (0UL) /*!< TIM_PWM_DC (Bit 0) */ +#define TIMER2_TIMER2_PWM_DC_REG_TIM_PWM_DC_Msk (0xffffUL) /*!< TIM_PWM_DC (Bitfield-Mask: 0xffff) */ +/* ================================================== TIMER2_PWM_FREQ_REG ================================================== */ +#define TIMER2_TIMER2_PWM_FREQ_REG_TIM_PWM_FREQ_Pos (0UL) /*!< TIM_PWM_FREQ (Bit 0) */ +#define TIMER2_TIMER2_PWM_FREQ_REG_TIM_PWM_FREQ_Msk (0xffffUL) /*!< TIM_PWM_FREQ (Bitfield-Mask: 0xffff) */ +/* =================================================== TIMER2_RELOAD_REG =================================================== */ +#define TIMER2_TIMER2_RELOAD_REG_TIM_RELOAD_Pos (0UL) /*!< TIM_RELOAD (Bit 0) */ +#define TIMER2_TIMER2_RELOAD_REG_TIM_RELOAD_Msk (0xffffffUL) /*!< TIM_RELOAD (Bitfield-Mask: 0xffffff) */ +/* ================================================= TIMER2_SHOTWIDTH_REG ================================================== */ +#define TIMER2_TIMER2_SHOTWIDTH_REG_TIM_SHOTWIDTH_Pos (0UL) /*!< TIM_SHOTWIDTH (Bit 0) */ +#define TIMER2_TIMER2_SHOTWIDTH_REG_TIM_SHOTWIDTH_Msk (0xffffffUL) /*!< TIM_SHOTWIDTH (Bitfield-Mask: 0xffffff) */ +/* =================================================== TIMER2_STATUS_REG =================================================== */ +#define TIMER2_TIMER2_STATUS_REG_TIM_ONESHOT_PHASE_Pos (2UL) /*!< TIM_ONESHOT_PHASE (Bit 2) */ +#define TIMER2_TIMER2_STATUS_REG_TIM_ONESHOT_PHASE_Msk (0xcUL) /*!< TIM_ONESHOT_PHASE (Bitfield-Mask: 0x03) */ +#define TIMER2_TIMER2_STATUS_REG_TIM_IN2_STATE_Pos (1UL) /*!< TIM_IN2_STATE (Bit 1) */ +#define TIMER2_TIMER2_STATUS_REG_TIM_IN2_STATE_Msk (0x2UL) /*!< TIM_IN2_STATE (Bitfield-Mask: 0x01) */ +#define TIMER2_TIMER2_STATUS_REG_TIM_IN1_STATE_Pos (0UL) /*!< TIM_IN1_STATE (Bit 0) */ +#define TIMER2_TIMER2_STATUS_REG_TIM_IN1_STATE_Msk (0x1UL) /*!< TIM_IN1_STATE (Bitfield-Mask: 0x01) */ +/* ================================================= TIMER2_TIMER_VAL_REG ================================================== */ +#define TIMER2_TIMER2_TIMER_VAL_REG_TIM_TIMER_VALUE_Pos (0UL) /*!< TIM_TIMER_VALUE (Bit 0) */ +#define TIMER2_TIMER2_TIMER_VAL_REG_TIM_TIMER_VALUE_Msk (0xffffffUL) /*!< TIM_TIMER_VALUE (Bitfield-Mask: 0xffffff) */ + + +/* =========================================================================================================================== */ +/* ================ TIMER3 ================ */ +/* =========================================================================================================================== */ + +/* =============================================== TIMER3_CAPTURE_GPIO1_REG ================================================ */ +#define TIMER3_TIMER3_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Pos (0UL) /*!< TIM_CAPTURE_GPIO1 (Bit 0) */ +#define TIMER3_TIMER3_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO1 (Bitfield-Mask: 0xffffff) */ +/* =============================================== TIMER3_CAPTURE_GPIO2_REG ================================================ */ +#define TIMER3_TIMER3_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Pos (0UL) /*!< TIM_CAPTURE_GPIO2 (Bit 0) */ +#define TIMER3_TIMER3_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO2 (Bitfield-Mask: 0xffffff) */ +/* ================================================= TIMER3_CLEAR_IRQ_REG ================================================== */ +#define TIMER3_TIMER3_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Pos (0UL) /*!< TIM_CLEAR_IRQ (Bit 0) */ +#define TIMER3_TIMER3_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Msk (0x1UL) /*!< TIM_CLEAR_IRQ (Bitfield-Mask: 0x01) */ +/* ==================================================== TIMER3_CTRL_REG ==================================================== */ +#define TIMER3_TIMER3_CTRL_REG_TIM_CLK_EN_Pos (8UL) /*!< TIM_CLK_EN (Bit 8) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_CLK_EN_Msk (0x100UL) /*!< TIM_CLK_EN (Bitfield-Mask: 0x01) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_SYS_CLK_EN_Pos (7UL) /*!< TIM_SYS_CLK_EN (Bit 7) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_SYS_CLK_EN_Msk (0x80UL) /*!< TIM_SYS_CLK_EN (Bitfield-Mask: 0x01) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_FREE_RUN_MODE_EN_Pos (6UL) /*!< TIM_FREE_RUN_MODE_EN (Bit 6) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk (0x40UL) /*!< TIM_FREE_RUN_MODE_EN (Bitfield-Mask: 0x01) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_IRQ_EN_Pos (5UL) /*!< TIM_IRQ_EN (Bit 5) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_IRQ_EN_Msk (0x20UL) /*!< TIM_IRQ_EN (Bitfield-Mask: 0x01) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Pos (4UL) /*!< TIM_IN2_EVENT_FALL_EN (Bit 4) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Msk (0x10UL) /*!< TIM_IN2_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Pos (3UL) /*!< TIM_IN1_EVENT_FALL_EN (Bit 3) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Msk (0x8UL) /*!< TIM_IN1_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_COUNT_DOWN_EN_Pos (2UL) /*!< TIM_COUNT_DOWN_EN (Bit 2) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_COUNT_DOWN_EN_Msk (0x4UL) /*!< TIM_COUNT_DOWN_EN (Bitfield-Mask: 0x01) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_EN_Pos (0UL) /*!< TIM_EN (Bit 0) */ +#define TIMER3_TIMER3_CTRL_REG_TIM_EN_Msk (0x1UL) /*!< TIM_EN (Bitfield-Mask: 0x01) */ +/* ================================================= TIMER3_GPIO1_CONF_REG ================================================= */ +#define TIMER3_TIMER3_GPIO1_CONF_REG_TIM_GPIO1_CONF_Pos (0UL) /*!< TIM_GPIO1_CONF (Bit 0) */ +#define TIMER3_TIMER3_GPIO1_CONF_REG_TIM_GPIO1_CONF_Msk (0x3fUL) /*!< TIM_GPIO1_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER3_GPIO2_CONF_REG ================================================= */ +#define TIMER3_TIMER3_GPIO2_CONF_REG_TIM_GPIO2_CONF_Pos (0UL) /*!< TIM_GPIO2_CONF (Bit 0) */ +#define TIMER3_TIMER3_GPIO2_CONF_REG_TIM_GPIO2_CONF_Msk (0x3fUL) /*!< TIM_GPIO2_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER3_PRESCALER_REG ================================================== */ +#define TIMER3_TIMER3_PRESCALER_REG_TIM_PRESCALER_Pos (0UL) /*!< TIM_PRESCALER (Bit 0) */ +#define TIMER3_TIMER3_PRESCALER_REG_TIM_PRESCALER_Msk (0x1fUL) /*!< TIM_PRESCALER (Bitfield-Mask: 0x1f) */ +/* =============================================== TIMER3_PRESCALER_VAL_REG ================================================ */ +#define TIMER3_TIMER3_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Pos (0UL) /*!< TIM_PRESCALER_VAL (Bit 0) */ +#define TIMER3_TIMER3_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Msk (0x1fUL) /*!< TIM_PRESCALER_VAL (Bitfield-Mask: 0x1f) */ +/* =================================================== TIMER3_PWM_DC_REG =================================================== */ +#define TIMER3_TIMER3_PWM_DC_REG_TIM_PWM_DC_Pos (0UL) /*!< TIM_PWM_DC (Bit 0) */ +#define TIMER3_TIMER3_PWM_DC_REG_TIM_PWM_DC_Msk (0xffffUL) /*!< TIM_PWM_DC (Bitfield-Mask: 0xffff) */ +/* ================================================== TIMER3_PWM_FREQ_REG ================================================== */ +#define TIMER3_TIMER3_PWM_FREQ_REG_TIM_PWM_FREQ_Pos (0UL) /*!< TIM_PWM_FREQ (Bit 0) */ +#define TIMER3_TIMER3_PWM_FREQ_REG_TIM_PWM_FREQ_Msk (0xffffUL) /*!< TIM_PWM_FREQ (Bitfield-Mask: 0xffff) */ +/* =================================================== TIMER3_RELOAD_REG =================================================== */ +#define TIMER3_TIMER3_RELOAD_REG_TIM_RELOAD_Pos (0UL) /*!< TIM_RELOAD (Bit 0) */ +#define TIMER3_TIMER3_RELOAD_REG_TIM_RELOAD_Msk (0xffffffUL) /*!< TIM_RELOAD (Bitfield-Mask: 0xffffff) */ +/* =================================================== TIMER3_STATUS_REG =================================================== */ +#define TIMER3_TIMER3_STATUS_REG_TIM_ONESHOT_PHASE_Pos (2UL) /*!< TIM_ONESHOT_PHASE (Bit 2) */ +#define TIMER3_TIMER3_STATUS_REG_TIM_ONESHOT_PHASE_Msk (0xcUL) /*!< TIM_ONESHOT_PHASE (Bitfield-Mask: 0x03) */ +#define TIMER3_TIMER3_STATUS_REG_TIM_IN2_STATE_Pos (1UL) /*!< TIM_IN2_STATE (Bit 1) */ +#define TIMER3_TIMER3_STATUS_REG_TIM_IN2_STATE_Msk (0x2UL) /*!< TIM_IN2_STATE (Bitfield-Mask: 0x01) */ +#define TIMER3_TIMER3_STATUS_REG_TIM_IN1_STATE_Pos (0UL) /*!< TIM_IN1_STATE (Bit 0) */ +#define TIMER3_TIMER3_STATUS_REG_TIM_IN1_STATE_Msk (0x1UL) /*!< TIM_IN1_STATE (Bitfield-Mask: 0x01) */ +/* ================================================= TIMER3_TIMER_VAL_REG ================================================== */ +#define TIMER3_TIMER3_TIMER_VAL_REG_TIM_TIMER_VALUE_Pos (0UL) /*!< TIM_TIMER_VALUE (Bit 0) */ +#define TIMER3_TIMER3_TIMER_VAL_REG_TIM_TIMER_VALUE_Msk (0xffffffUL) /*!< TIM_TIMER_VALUE (Bitfield-Mask: 0xffffff) */ + + +/* =========================================================================================================================== */ +/* ================ TIMER4 ================ */ +/* =========================================================================================================================== */ + +/* =============================================== TIMER4_CAPTURE_GPIO1_REG ================================================ */ +#define TIMER4_TIMER4_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Pos (0UL) /*!< TIM_CAPTURE_GPIO1 (Bit 0) */ +#define TIMER4_TIMER4_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO1 (Bitfield-Mask: 0xffffff) */ +/* =============================================== TIMER4_CAPTURE_GPIO2_REG ================================================ */ +#define TIMER4_TIMER4_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Pos (0UL) /*!< TIM_CAPTURE_GPIO2 (Bit 0) */ +#define TIMER4_TIMER4_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO2 (Bitfield-Mask: 0xffffff) */ +/* ================================================= TIMER4_CLEAR_IRQ_REG ================================================== */ +#define TIMER4_TIMER4_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Pos (0UL) /*!< TIM_CLEAR_IRQ (Bit 0) */ +#define TIMER4_TIMER4_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Msk (0x1UL) /*!< TIM_CLEAR_IRQ (Bitfield-Mask: 0x01) */ +/* ==================================================== TIMER4_CTRL_REG ==================================================== */ +#define TIMER4_TIMER4_CTRL_REG_TIM_CLK_EN_Pos (8UL) /*!< TIM_CLK_EN (Bit 8) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_CLK_EN_Msk (0x100UL) /*!< TIM_CLK_EN (Bitfield-Mask: 0x01) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_SYS_CLK_EN_Pos (7UL) /*!< TIM_SYS_CLK_EN (Bit 7) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_SYS_CLK_EN_Msk (0x80UL) /*!< TIM_SYS_CLK_EN (Bitfield-Mask: 0x01) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_FREE_RUN_MODE_EN_Pos (6UL) /*!< TIM_FREE_RUN_MODE_EN (Bit 6) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk (0x40UL) /*!< TIM_FREE_RUN_MODE_EN (Bitfield-Mask: 0x01) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_IRQ_EN_Pos (5UL) /*!< TIM_IRQ_EN (Bit 5) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_IRQ_EN_Msk (0x20UL) /*!< TIM_IRQ_EN (Bitfield-Mask: 0x01) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Pos (4UL) /*!< TIM_IN2_EVENT_FALL_EN (Bit 4) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Msk (0x10UL) /*!< TIM_IN2_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Pos (3UL) /*!< TIM_IN1_EVENT_FALL_EN (Bit 3) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Msk (0x8UL) /*!< TIM_IN1_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_COUNT_DOWN_EN_Pos (2UL) /*!< TIM_COUNT_DOWN_EN (Bit 2) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_COUNT_DOWN_EN_Msk (0x4UL) /*!< TIM_COUNT_DOWN_EN (Bitfield-Mask: 0x01) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_EN_Pos (0UL) /*!< TIM_EN (Bit 0) */ +#define TIMER4_TIMER4_CTRL_REG_TIM_EN_Msk (0x1UL) /*!< TIM_EN (Bitfield-Mask: 0x01) */ +/* ================================================= TIMER4_GPIO1_CONF_REG ================================================= */ +#define TIMER4_TIMER4_GPIO1_CONF_REG_TIM_GPIO1_CONF_Pos (0UL) /*!< TIM_GPIO1_CONF (Bit 0) */ +#define TIMER4_TIMER4_GPIO1_CONF_REG_TIM_GPIO1_CONF_Msk (0x3fUL) /*!< TIM_GPIO1_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER4_GPIO2_CONF_REG ================================================= */ +#define TIMER4_TIMER4_GPIO2_CONF_REG_TIM_GPIO2_CONF_Pos (0UL) /*!< TIM_GPIO2_CONF (Bit 0) */ +#define TIMER4_TIMER4_GPIO2_CONF_REG_TIM_GPIO2_CONF_Msk (0x3fUL) /*!< TIM_GPIO2_CONF (Bitfield-Mask: 0x3f) */ +/* ================================================= TIMER4_PRESCALER_REG ================================================== */ +#define TIMER4_TIMER4_PRESCALER_REG_TIM_PRESCALER_Pos (0UL) /*!< TIM_PRESCALER (Bit 0) */ +#define TIMER4_TIMER4_PRESCALER_REG_TIM_PRESCALER_Msk (0x1fUL) /*!< TIM_PRESCALER (Bitfield-Mask: 0x1f) */ +/* =============================================== TIMER4_PRESCALER_VAL_REG ================================================ */ +#define TIMER4_TIMER4_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Pos (0UL) /*!< TIM_PRESCALER_VAL (Bit 0) */ +#define TIMER4_TIMER4_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Msk (0x1fUL) /*!< TIM_PRESCALER_VAL (Bitfield-Mask: 0x1f) */ +/* =================================================== TIMER4_PWM_DC_REG =================================================== */ +#define TIMER4_TIMER4_PWM_DC_REG_TIM_PWM_DC_Pos (0UL) /*!< TIM_PWM_DC (Bit 0) */ +#define TIMER4_TIMER4_PWM_DC_REG_TIM_PWM_DC_Msk (0xffffUL) /*!< TIM_PWM_DC (Bitfield-Mask: 0xffff) */ +/* ================================================== TIMER4_PWM_FREQ_REG ================================================== */ +#define TIMER4_TIMER4_PWM_FREQ_REG_TIM_PWM_FREQ_Pos (0UL) /*!< TIM_PWM_FREQ (Bit 0) */ +#define TIMER4_TIMER4_PWM_FREQ_REG_TIM_PWM_FREQ_Msk (0xffffUL) /*!< TIM_PWM_FREQ (Bitfield-Mask: 0xffff) */ +/* =================================================== TIMER4_RELOAD_REG =================================================== */ +#define TIMER4_TIMER4_RELOAD_REG_TIM_RELOAD_Pos (0UL) /*!< TIM_RELOAD (Bit 0) */ +#define TIMER4_TIMER4_RELOAD_REG_TIM_RELOAD_Msk (0xffffffUL) /*!< TIM_RELOAD (Bitfield-Mask: 0xffffff) */ +/* =================================================== TIMER4_STATUS_REG =================================================== */ +#define TIMER4_TIMER4_STATUS_REG_TIM_ONESHOT_PHASE_Pos (2UL) /*!< TIM_ONESHOT_PHASE (Bit 2) */ +#define TIMER4_TIMER4_STATUS_REG_TIM_ONESHOT_PHASE_Msk (0xcUL) /*!< TIM_ONESHOT_PHASE (Bitfield-Mask: 0x03) */ +#define TIMER4_TIMER4_STATUS_REG_TIM_IN2_STATE_Pos (1UL) /*!< TIM_IN2_STATE (Bit 1) */ +#define TIMER4_TIMER4_STATUS_REG_TIM_IN2_STATE_Msk (0x2UL) /*!< TIM_IN2_STATE (Bitfield-Mask: 0x01) */ +#define TIMER4_TIMER4_STATUS_REG_TIM_IN1_STATE_Pos (0UL) /*!< TIM_IN1_STATE (Bit 0) */ +#define TIMER4_TIMER4_STATUS_REG_TIM_IN1_STATE_Msk (0x1UL) /*!< TIM_IN1_STATE (Bitfield-Mask: 0x01) */ +/* ================================================= TIMER4_TIMER_VAL_REG ================================================== */ +#define TIMER4_TIMER4_TIMER_VAL_REG_TIM_TIMER_VALUE_Pos (0UL) /*!< TIM_TIMER_VALUE (Bit 0) */ +#define TIMER4_TIMER4_TIMER_VAL_REG_TIM_TIMER_VALUE_Msk (0xffffffUL) /*!< TIM_TIMER_VALUE (Bitfield-Mask: 0xffffff) */ + + +/* =========================================================================================================================== */ +/* ================ TRNG ================ */ +/* =========================================================================================================================== */ + +/* ===================================================== TRNG_CTRL_REG ===================================================== */ +#define TRNG_TRNG_CTRL_REG_TRNG_ENABLE_Pos (0UL) /*!< TRNG_ENABLE (Bit 0) */ +#define TRNG_TRNG_CTRL_REG_TRNG_ENABLE_Msk (0x1UL) /*!< TRNG_ENABLE (Bitfield-Mask: 0x01) */ +/* =================================================== TRNG_FIFOLVL_REG ==================================================== */ +#define TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOFULL_Pos (5UL) /*!< TRNG_FIFOFULL (Bit 5) */ +#define TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOFULL_Msk (0x20UL) /*!< TRNG_FIFOFULL (Bitfield-Mask: 0x01) */ +#define TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOLVL_Pos (0UL) /*!< TRNG_FIFOLVL (Bit 0) */ +#define TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOLVL_Msk (0x1fUL) /*!< TRNG_FIFOLVL (Bitfield-Mask: 0x1f) */ +/* ===================================================== TRNG_VER_REG ====================================================== */ +#define TRNG_TRNG_VER_REG_TRNG_MAJ_Pos (24UL) /*!< TRNG_MAJ (Bit 24) */ +#define TRNG_TRNG_VER_REG_TRNG_MAJ_Msk (0xff000000UL) /*!< TRNG_MAJ (Bitfield-Mask: 0xff) */ +#define TRNG_TRNG_VER_REG_TRNG_MIN_Pos (16UL) /*!< TRNG_MIN (Bit 16) */ +#define TRNG_TRNG_VER_REG_TRNG_MIN_Msk (0xff0000UL) /*!< TRNG_MIN (Bitfield-Mask: 0xff) */ +#define TRNG_TRNG_VER_REG_TRNG_SVN_Pos (0UL) /*!< TRNG_SVN (Bit 0) */ +#define TRNG_TRNG_VER_REG_TRNG_SVN_Msk (0xffffUL) /*!< TRNG_SVN (Bitfield-Mask: 0xffff) */ + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + +/* ===================================================== UART_CTR_REG ====================================================== */ +#define UART_UART_CTR_REG_UART_CTR_Pos (0UL) /*!< UART_CTR (Bit 0) */ +#define UART_UART_CTR_REG_UART_CTR_Msk (0xffffffffUL) /*!< UART_CTR (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== UART_DLF_REG ====================================================== */ +#define UART_UART_DLF_REG_UART_DLF_Pos (0UL) /*!< UART_DLF (Bit 0) */ +#define UART_UART_DLF_REG_UART_DLF_Msk (0xfUL) /*!< UART_DLF (Bitfield-Mask: 0x0f) */ +/* ==================================================== UART_DMASA_REG ===================================================== */ +#define UART_UART_DMASA_REG_UART_DMASA_Pos (0UL) /*!< UART_DMASA (Bit 0) */ +#define UART_UART_DMASA_REG_UART_DMASA_Msk (0x1UL) /*!< UART_DMASA (Bitfield-Mask: 0x01) */ +/* ===================================================== UART_HTX_REG ====================================================== */ +#define UART_UART_HTX_REG_UART_HALT_TX_Pos (0UL) /*!< UART_HALT_TX (Bit 0) */ +#define UART_UART_HTX_REG_UART_HALT_TX_Msk (0x1UL) /*!< UART_HALT_TX (Bitfield-Mask: 0x01) */ +/* =================================================== UART_IER_DLH_REG ==================================================== */ +#define UART_UART_IER_DLH_REG_PTIME_DLH7_Pos (7UL) /*!< PTIME_DLH7 (Bit 7) */ +#define UART_UART_IER_DLH_REG_PTIME_DLH7_Msk (0x80UL) /*!< PTIME_DLH7 (Bitfield-Mask: 0x01) */ +#define UART_UART_IER_DLH_REG_DLH6_5_Pos (5UL) /*!< DLH6_5 (Bit 5) */ +#define UART_UART_IER_DLH_REG_DLH6_5_Msk (0x60UL) /*!< DLH6_5 (Bitfield-Mask: 0x03) */ +#define UART_UART_IER_DLH_REG_ELCOLR_DLH4_Pos (4UL) /*!< ELCOLR_DLH4 (Bit 4) */ +#define UART_UART_IER_DLH_REG_ELCOLR_DLH4_Msk (0x10UL) /*!< ELCOLR_DLH4 (Bitfield-Mask: 0x01) */ +#define UART_UART_IER_DLH_REG_EDSSI_DLH3_Pos (3UL) /*!< EDSSI_DLH3 (Bit 3) */ +#define UART_UART_IER_DLH_REG_EDSSI_DLH3_Msk (0x8UL) /*!< EDSSI_DLH3 (Bitfield-Mask: 0x01) */ +#define UART_UART_IER_DLH_REG_ELSI_DLH2_Pos (2UL) /*!< ELSI_DLH2 (Bit 2) */ +#define UART_UART_IER_DLH_REG_ELSI_DLH2_Msk (0x4UL) /*!< ELSI_DLH2 (Bitfield-Mask: 0x01) */ +#define UART_UART_IER_DLH_REG_ETBEI_DLH1_Pos (1UL) /*!< ETBEI_DLH1 (Bit 1) */ +#define UART_UART_IER_DLH_REG_ETBEI_DLH1_Msk (0x2UL) /*!< ETBEI_DLH1 (Bitfield-Mask: 0x01) */ +#define UART_UART_IER_DLH_REG_ERBFI_DLH0_Pos (0UL) /*!< ERBFI_DLH0 (Bit 0) */ +#define UART_UART_IER_DLH_REG_ERBFI_DLH0_Msk (0x1UL) /*!< ERBFI_DLH0 (Bitfield-Mask: 0x01) */ +/* =================================================== UART_IIR_FCR_REG ==================================================== */ +#define UART_UART_IIR_FCR_REG_IIR_FCR_Pos (0UL) /*!< IIR_FCR (Bit 0) */ +#define UART_UART_IIR_FCR_REG_IIR_FCR_Msk (0xffUL) /*!< IIR_FCR (Bitfield-Mask: 0xff) */ +/* ===================================================== UART_LCR_REG ====================================================== */ +#define UART_UART_LCR_REG_UART_DLAB_Pos (7UL) /*!< UART_DLAB (Bit 7) */ +#define UART_UART_LCR_REG_UART_DLAB_Msk (0x80UL) /*!< UART_DLAB (Bitfield-Mask: 0x01) */ +#define UART_UART_LCR_REG_UART_BC_Pos (6UL) /*!< UART_BC (Bit 6) */ +#define UART_UART_LCR_REG_UART_BC_Msk (0x40UL) /*!< UART_BC (Bitfield-Mask: 0x01) */ +#define UART_UART_LCR_REG_UART_EPS_Pos (4UL) /*!< UART_EPS (Bit 4) */ +#define UART_UART_LCR_REG_UART_EPS_Msk (0x10UL) /*!< UART_EPS (Bitfield-Mask: 0x01) */ +#define UART_UART_LCR_REG_UART_PEN_Pos (3UL) /*!< UART_PEN (Bit 3) */ +#define UART_UART_LCR_REG_UART_PEN_Msk (0x8UL) /*!< UART_PEN (Bitfield-Mask: 0x01) */ +#define UART_UART_LCR_REG_UART_STOP_Pos (2UL) /*!< UART_STOP (Bit 2) */ +#define UART_UART_LCR_REG_UART_STOP_Msk (0x4UL) /*!< UART_STOP (Bitfield-Mask: 0x01) */ +#define UART_UART_LCR_REG_UART_DLS_Pos (0UL) /*!< UART_DLS (Bit 0) */ +#define UART_UART_LCR_REG_UART_DLS_Msk (0x3UL) /*!< UART_DLS (Bitfield-Mask: 0x03) */ +/* ===================================================== UART_LSR_REG ====================================================== */ +#define UART_UART_LSR_REG_UART_RFE_Pos (7UL) /*!< UART_RFE (Bit 7) */ +#define UART_UART_LSR_REG_UART_RFE_Msk (0x80UL) /*!< UART_RFE (Bitfield-Mask: 0x01) */ +#define UART_UART_LSR_REG_UART_TEMT_Pos (6UL) /*!< UART_TEMT (Bit 6) */ +#define UART_UART_LSR_REG_UART_TEMT_Msk (0x40UL) /*!< UART_TEMT (Bitfield-Mask: 0x01) */ +#define UART_UART_LSR_REG_UART_THRE_Pos (5UL) /*!< UART_THRE (Bit 5) */ +#define UART_UART_LSR_REG_UART_THRE_Msk (0x20UL) /*!< UART_THRE (Bitfield-Mask: 0x01) */ +#define UART_UART_LSR_REG_UART_BI_Pos (4UL) /*!< UART_BI (Bit 4) */ +#define UART_UART_LSR_REG_UART_BI_Msk (0x10UL) /*!< UART_BI (Bitfield-Mask: 0x01) */ +#define UART_UART_LSR_REG_UART_FE_Pos (3UL) /*!< UART_FE (Bit 3) */ +#define UART_UART_LSR_REG_UART_FE_Msk (0x8UL) /*!< UART_FE (Bitfield-Mask: 0x01) */ +#define UART_UART_LSR_REG_UART_PE_Pos (2UL) /*!< UART_PE (Bit 2) */ +#define UART_UART_LSR_REG_UART_PE_Msk (0x4UL) /*!< UART_PE (Bitfield-Mask: 0x01) */ +#define UART_UART_LSR_REG_UART_OE_Pos (1UL) /*!< UART_OE (Bit 1) */ +#define UART_UART_LSR_REG_UART_OE_Msk (0x2UL) /*!< UART_OE (Bitfield-Mask: 0x01) */ +#define UART_UART_LSR_REG_UART_DR_Pos (0UL) /*!< UART_DR (Bit 0) */ +#define UART_UART_LSR_REG_UART_DR_Msk (0x1UL) /*!< UART_DR (Bitfield-Mask: 0x01) */ +/* ===================================================== UART_MCR_REG ====================================================== */ +#define UART_UART_MCR_REG_UART_LB_Pos (4UL) /*!< UART_LB (Bit 4) */ +#define UART_UART_MCR_REG_UART_LB_Msk (0x10UL) /*!< UART_LB (Bitfield-Mask: 0x01) */ +/* ================================================= UART_RBR_THR_DLL_REG ================================================== */ +#define UART_UART_RBR_THR_DLL_REG_RBR_THR_DLL_Pos (0UL) /*!< RBR_THR_DLL (Bit 0) */ +#define UART_UART_RBR_THR_DLL_REG_RBR_THR_DLL_Msk (0xffUL) /*!< RBR_THR_DLL (Bitfield-Mask: 0xff) */ +/* ===================================================== UART_RFL_REG ====================================================== */ +#define UART_UART_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Pos (0UL) /*!< UART_RECEIVE_FIFO_LEVEL (Bit 0) */ +#define UART_UART_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_RECEIVE_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ +/* ===================================================== UART_SBCR_REG ===================================================== */ +#define UART_UART_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Pos (0UL) /*!< UART_SHADOW_BREAK_CONTROL (Bit 0) */ +#define UART_UART_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Msk (0x1UL) /*!< UART_SHADOW_BREAK_CONTROL (Bitfield-Mask: 0x01) */ +/* ===================================================== UART_SCR_REG ====================================================== */ +#define UART_UART_SCR_REG_UART_SCRATCH_PAD_Pos (0UL) /*!< UART_SCRATCH_PAD (Bit 0) */ +#define UART_UART_SCR_REG_UART_SCRATCH_PAD_Msk (0xffUL) /*!< UART_SCRATCH_PAD (Bitfield-Mask: 0xff) */ +/* ==================================================== UART_SDMAM_REG ===================================================== */ +#define UART_UART_SDMAM_REG_UART_SHADOW_DMA_MODE_Pos (0UL) /*!< UART_SHADOW_DMA_MODE (Bit 0) */ +#define UART_UART_SDMAM_REG_UART_SHADOW_DMA_MODE_Msk (0x1UL) /*!< UART_SHADOW_DMA_MODE (Bitfield-Mask: 0x01) */ +/* ===================================================== UART_SFE_REG ====================================================== */ +#define UART_UART_SFE_REG_UART_SHADOW_FIFO_ENABLE_Pos (0UL) /*!< UART_SHADOW_FIFO_ENABLE (Bit 0) */ +#define UART_UART_SFE_REG_UART_SHADOW_FIFO_ENABLE_Msk (0x1UL) /*!< UART_SHADOW_FIFO_ENABLE (Bitfield-Mask: 0x01) */ +/* ================================================== UART_SRBR_STHR0_REG ================================================== */ +#define UART_UART_SRBR_STHR0_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR0_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART_SRBR_STHR10_REG ================================================== */ +#define UART_UART_SRBR_STHR10_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR10_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART_SRBR_STHR11_REG ================================================== */ +#define UART_UART_SRBR_STHR11_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR11_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART_SRBR_STHR12_REG ================================================== */ +#define UART_UART_SRBR_STHR12_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR12_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART_SRBR_STHR13_REG ================================================== */ +#define UART_UART_SRBR_STHR13_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR13_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART_SRBR_STHR14_REG ================================================== */ +#define UART_UART_SRBR_STHR14_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR14_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART_SRBR_STHR15_REG ================================================== */ +#define UART_UART_SRBR_STHR15_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR15_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR1_REG ================================================== */ +#define UART_UART_SRBR_STHR1_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR1_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR2_REG ================================================== */ +#define UART_UART_SRBR_STHR2_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR2_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR3_REG ================================================== */ +#define UART_UART_SRBR_STHR3_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR3_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR4_REG ================================================== */ +#define UART_UART_SRBR_STHR4_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR4_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR5_REG ================================================== */ +#define UART_UART_SRBR_STHR5_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR5_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR6_REG ================================================== */ +#define UART_UART_SRBR_STHR6_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR6_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR7_REG ================================================== */ +#define UART_UART_SRBR_STHR7_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR7_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR8_REG ================================================== */ +#define UART_UART_SRBR_STHR8_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR8_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================== UART_SRBR_STHR9_REG ================================================== */ +#define UART_UART_SRBR_STHR9_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART_UART_SRBR_STHR9_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ===================================================== UART_SRR_REG ====================================================== */ +#define UART_UART_SRR_REG_UART_XFR_Pos (2UL) /*!< UART_XFR (Bit 2) */ +#define UART_UART_SRR_REG_UART_XFR_Msk (0x4UL) /*!< UART_XFR (Bitfield-Mask: 0x01) */ +#define UART_UART_SRR_REG_UART_RFR_Pos (1UL) /*!< UART_RFR (Bit 1) */ +#define UART_UART_SRR_REG_UART_RFR_Msk (0x2UL) /*!< UART_RFR (Bitfield-Mask: 0x01) */ +#define UART_UART_SRR_REG_UART_UR_Pos (0UL) /*!< UART_UR (Bit 0) */ +#define UART_UART_SRR_REG_UART_UR_Msk (0x1UL) /*!< UART_UR (Bitfield-Mask: 0x01) */ +/* ===================================================== UART_SRT_REG ====================================================== */ +#define UART_UART_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Pos (0UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bit 0) */ +#define UART_UART_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bitfield-Mask: 0x03) */ +/* ===================================================== UART_STET_REG ===================================================== */ +#define UART_UART_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Pos (0UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bit 0) */ +#define UART_UART_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bitfield-Mask: 0x03) */ +/* ===================================================== UART_TFL_REG ====================================================== */ +#define UART_UART_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Pos (0UL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bit 0) */ +#define UART_UART_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ +/* ===================================================== UART_UCV_REG ====================================================== */ +#define UART_UART_UCV_REG_UART_UCV_Pos (0UL) /*!< UART_UCV (Bit 0) */ +#define UART_UART_UCV_REG_UART_UCV_Msk (0xffffffffUL) /*!< UART_UCV (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== UART_USR_REG ====================================================== */ +#define UART_UART_USR_REG_UART_RFF_Pos (4UL) /*!< UART_RFF (Bit 4) */ +#define UART_UART_USR_REG_UART_RFF_Msk (0x10UL) /*!< UART_RFF (Bitfield-Mask: 0x01) */ +#define UART_UART_USR_REG_UART_RFNE_Pos (3UL) /*!< UART_RFNE (Bit 3) */ +#define UART_UART_USR_REG_UART_RFNE_Msk (0x8UL) /*!< UART_RFNE (Bitfield-Mask: 0x01) */ +#define UART_UART_USR_REG_UART_TFE_Pos (2UL) /*!< UART_TFE (Bit 2) */ +#define UART_UART_USR_REG_UART_TFE_Msk (0x4UL) /*!< UART_TFE (Bitfield-Mask: 0x01) */ +#define UART_UART_USR_REG_UART_TFNF_Pos (1UL) /*!< UART_TFNF (Bit 1) */ +#define UART_UART_USR_REG_UART_TFNF_Msk (0x2UL) /*!< UART_TFNF (Bitfield-Mask: 0x01) */ +#define UART_UART_USR_REG_UART_BUSY_Pos (0UL) /*!< UART_BUSY (Bit 0) */ +#define UART_UART_USR_REG_UART_BUSY_Msk (0x1UL) /*!< UART_BUSY (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ UART2 ================ */ +/* =========================================================================================================================== */ + +/* ===================================================== UART2_CTR_REG ===================================================== */ +#define UART2_UART2_CTR_REG_UART_CTR_Pos (0UL) /*!< UART_CTR (Bit 0) */ +#define UART2_UART2_CTR_REG_UART_CTR_Msk (0xffffffffUL) /*!< UART_CTR (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== UART2_DLF_REG ===================================================== */ +#define UART2_UART2_DLF_REG_UART_DLF_Pos (0UL) /*!< UART_DLF (Bit 0) */ +#define UART2_UART2_DLF_REG_UART_DLF_Msk (0xfUL) /*!< UART_DLF (Bitfield-Mask: 0x0f) */ +/* ==================================================== UART2_DMASA_REG ==================================================== */ +#define UART2_UART2_DMASA_REG_UART_DMASA_Pos (0UL) /*!< UART_DMASA (Bit 0) */ +#define UART2_UART2_DMASA_REG_UART_DMASA_Msk (0x1UL) /*!< UART_DMASA (Bitfield-Mask: 0x01) */ +/* ===================================================== UART2_HTX_REG ===================================================== */ +#define UART2_UART2_HTX_REG_UART_HALT_TX_Pos (0UL) /*!< UART_HALT_TX (Bit 0) */ +#define UART2_UART2_HTX_REG_UART_HALT_TX_Msk (0x1UL) /*!< UART_HALT_TX (Bitfield-Mask: 0x01) */ +/* =================================================== UART2_IER_DLH_REG =================================================== */ +#define UART2_UART2_IER_DLH_REG_PTIME_DLH7_Pos (7UL) /*!< PTIME_DLH7 (Bit 7) */ +#define UART2_UART2_IER_DLH_REG_PTIME_DLH7_Msk (0x80UL) /*!< PTIME_DLH7 (Bitfield-Mask: 0x01) */ +#define UART2_UART2_IER_DLH_REG_DLH6_5_Pos (5UL) /*!< DLH6_5 (Bit 5) */ +#define UART2_UART2_IER_DLH_REG_DLH6_5_Msk (0x60UL) /*!< DLH6_5 (Bitfield-Mask: 0x03) */ +#define UART2_UART2_IER_DLH_REG_ELCOLR_DLH4_Pos (4UL) /*!< ELCOLR_DLH4 (Bit 4) */ +#define UART2_UART2_IER_DLH_REG_ELCOLR_DLH4_Msk (0x10UL) /*!< ELCOLR_DLH4 (Bitfield-Mask: 0x01) */ +#define UART2_UART2_IER_DLH_REG_EDSSI_DLH3_Pos (3UL) /*!< EDSSI_DLH3 (Bit 3) */ +#define UART2_UART2_IER_DLH_REG_EDSSI_DLH3_Msk (0x8UL) /*!< EDSSI_DLH3 (Bitfield-Mask: 0x01) */ +#define UART2_UART2_IER_DLH_REG_ELSI_DLH2_Pos (2UL) /*!< ELSI_DLH2 (Bit 2) */ +#define UART2_UART2_IER_DLH_REG_ELSI_DLH2_Msk (0x4UL) /*!< ELSI_DLH2 (Bitfield-Mask: 0x01) */ +#define UART2_UART2_IER_DLH_REG_ETBEI_DLH1_Pos (1UL) /*!< ETBEI_DLH1 (Bit 1) */ +#define UART2_UART2_IER_DLH_REG_ETBEI_DLH1_Msk (0x2UL) /*!< ETBEI_DLH1 (Bitfield-Mask: 0x01) */ +#define UART2_UART2_IER_DLH_REG_ERBFI_DLH0_Pos (0UL) /*!< ERBFI_DLH0 (Bit 0) */ +#define UART2_UART2_IER_DLH_REG_ERBFI_DLH0_Msk (0x1UL) /*!< ERBFI_DLH0 (Bitfield-Mask: 0x01) */ +/* =================================================== UART2_IIR_FCR_REG =================================================== */ +#define UART2_UART2_IIR_FCR_REG_IIR_FCR_Pos (0UL) /*!< IIR_FCR (Bit 0) */ +#define UART2_UART2_IIR_FCR_REG_IIR_FCR_Msk (0xffUL) /*!< IIR_FCR (Bitfield-Mask: 0xff) */ +/* ===================================================== UART2_LCR_EXT ===================================================== */ +#define UART2_UART2_LCR_EXT_UART_TRANSMIT_MODE_Pos (3UL) /*!< UART_TRANSMIT_MODE (Bit 3) */ +#define UART2_UART2_LCR_EXT_UART_TRANSMIT_MODE_Msk (0x8UL) /*!< UART_TRANSMIT_MODE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_EXT_UART_SEND_ADDR_Pos (2UL) /*!< UART_SEND_ADDR (Bit 2) */ +#define UART2_UART2_LCR_EXT_UART_SEND_ADDR_Msk (0x4UL) /*!< UART_SEND_ADDR (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_EXT_UART_ADDR_MATCH_Pos (1UL) /*!< UART_ADDR_MATCH (Bit 1) */ +#define UART2_UART2_LCR_EXT_UART_ADDR_MATCH_Msk (0x2UL) /*!< UART_ADDR_MATCH (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_EXT_UART_DLS_E_Pos (0UL) /*!< UART_DLS_E (Bit 0) */ +#define UART2_UART2_LCR_EXT_UART_DLS_E_Msk (0x1UL) /*!< UART_DLS_E (Bitfield-Mask: 0x01) */ +/* ===================================================== UART2_LCR_REG ===================================================== */ +#define UART2_UART2_LCR_REG_UART_DLAB_Pos (7UL) /*!< UART_DLAB (Bit 7) */ +#define UART2_UART2_LCR_REG_UART_DLAB_Msk (0x80UL) /*!< UART_DLAB (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_REG_UART_BC_Pos (6UL) /*!< UART_BC (Bit 6) */ +#define UART2_UART2_LCR_REG_UART_BC_Msk (0x40UL) /*!< UART_BC (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_REG_UART_SP_Pos (5UL) /*!< UART_SP (Bit 5) */ +#define UART2_UART2_LCR_REG_UART_SP_Msk (0x20UL) /*!< UART_SP (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_REG_UART_EPS_Pos (4UL) /*!< UART_EPS (Bit 4) */ +#define UART2_UART2_LCR_REG_UART_EPS_Msk (0x10UL) /*!< UART_EPS (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_REG_UART_PEN_Pos (3UL) /*!< UART_PEN (Bit 3) */ +#define UART2_UART2_LCR_REG_UART_PEN_Msk (0x8UL) /*!< UART_PEN (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_REG_UART_STOP_Pos (2UL) /*!< UART_STOP (Bit 2) */ +#define UART2_UART2_LCR_REG_UART_STOP_Msk (0x4UL) /*!< UART_STOP (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LCR_REG_UART_DLS_Pos (0UL) /*!< UART_DLS (Bit 0) */ +#define UART2_UART2_LCR_REG_UART_DLS_Msk (0x3UL) /*!< UART_DLS (Bitfield-Mask: 0x03) */ +/* ===================================================== UART2_LSR_REG ===================================================== */ +#define UART2_UART2_LSR_REG_UART_ADDR_RCVD_Pos (8UL) /*!< UART_ADDR_RCVD (Bit 8) */ +#define UART2_UART2_LSR_REG_UART_ADDR_RCVD_Msk (0x100UL) /*!< UART_ADDR_RCVD (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LSR_REG_UART_RFE_Pos (7UL) /*!< UART_RFE (Bit 7) */ +#define UART2_UART2_LSR_REG_UART_RFE_Msk (0x80UL) /*!< UART_RFE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LSR_REG_UART_TEMT_Pos (6UL) /*!< UART_TEMT (Bit 6) */ +#define UART2_UART2_LSR_REG_UART_TEMT_Msk (0x40UL) /*!< UART_TEMT (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LSR_REG_UART_THRE_Pos (5UL) /*!< UART_THRE (Bit 5) */ +#define UART2_UART2_LSR_REG_UART_THRE_Msk (0x20UL) /*!< UART_THRE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LSR_REG_UART_BI_Pos (4UL) /*!< UART_BI (Bit 4) */ +#define UART2_UART2_LSR_REG_UART_BI_Msk (0x10UL) /*!< UART_BI (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LSR_REG_UART_FE_Pos (3UL) /*!< UART_FE (Bit 3) */ +#define UART2_UART2_LSR_REG_UART_FE_Msk (0x8UL) /*!< UART_FE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LSR_REG_UART_PE_Pos (2UL) /*!< UART_PE (Bit 2) */ +#define UART2_UART2_LSR_REG_UART_PE_Msk (0x4UL) /*!< UART_PE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LSR_REG_UART_OE_Pos (1UL) /*!< UART_OE (Bit 1) */ +#define UART2_UART2_LSR_REG_UART_OE_Msk (0x2UL) /*!< UART_OE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_LSR_REG_UART_DR_Pos (0UL) /*!< UART_DR (Bit 0) */ +#define UART2_UART2_LSR_REG_UART_DR_Msk (0x1UL) /*!< UART_DR (Bitfield-Mask: 0x01) */ +/* ===================================================== UART2_MCR_REG ===================================================== */ +#define UART2_UART2_MCR_REG_UART_AFCE_Pos (5UL) /*!< UART_AFCE (Bit 5) */ +#define UART2_UART2_MCR_REG_UART_AFCE_Msk (0x20UL) /*!< UART_AFCE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_MCR_REG_UART_LB_Pos (4UL) /*!< UART_LB (Bit 4) */ +#define UART2_UART2_MCR_REG_UART_LB_Msk (0x10UL) /*!< UART_LB (Bitfield-Mask: 0x01) */ +#define UART2_UART2_MCR_REG_UART_RTS_Pos (1UL) /*!< UART_RTS (Bit 1) */ +#define UART2_UART2_MCR_REG_UART_RTS_Msk (0x2UL) /*!< UART_RTS (Bitfield-Mask: 0x01) */ +/* ===================================================== UART2_MSR_REG ===================================================== */ +#define UART2_UART2_MSR_REG_UART_CTS_Pos (4UL) /*!< UART_CTS (Bit 4) */ +#define UART2_UART2_MSR_REG_UART_CTS_Msk (0x10UL) /*!< UART_CTS (Bitfield-Mask: 0x01) */ +#define UART2_UART2_MSR_REG_UART_DCTS_Pos (0UL) /*!< UART_DCTS (Bit 0) */ +#define UART2_UART2_MSR_REG_UART_DCTS_Msk (0x1UL) /*!< UART_DCTS (Bitfield-Mask: 0x01) */ +/* ===================================================== UART2_RAR_REG ===================================================== */ +#define UART2_UART2_RAR_REG_UART_RAR_Pos (0UL) /*!< UART_RAR (Bit 0) */ +#define UART2_UART2_RAR_REG_UART_RAR_Msk (0xffUL) /*!< UART_RAR (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_RBR_THR_DLL_REG ================================================= */ +#define UART2_UART2_RBR_THR_DLL_REG_RBR_THR_9BIT_Pos (8UL) /*!< RBR_THR_9BIT (Bit 8) */ +#define UART2_UART2_RBR_THR_DLL_REG_RBR_THR_9BIT_Msk (0x100UL) /*!< RBR_THR_9BIT (Bitfield-Mask: 0x01) */ +#define UART2_UART2_RBR_THR_DLL_REG_RBR_THR_DLL_Pos (0UL) /*!< RBR_THR_DLL (Bit 0) */ +#define UART2_UART2_RBR_THR_DLL_REG_RBR_THR_DLL_Msk (0xffUL) /*!< RBR_THR_DLL (Bitfield-Mask: 0xff) */ +/* ===================================================== UART2_RFL_REG ===================================================== */ +#define UART2_UART2_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Pos (0UL) /*!< UART_RECEIVE_FIFO_LEVEL (Bit 0) */ +#define UART2_UART2_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_RECEIVE_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ +/* ==================================================== UART2_SBCR_REG ===================================================== */ +#define UART2_UART2_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Pos (0UL) /*!< UART_SHADOW_BREAK_CONTROL (Bit 0) */ +#define UART2_UART2_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Msk (0x1UL) /*!< UART_SHADOW_BREAK_CONTROL (Bitfield-Mask: 0x01) */ +/* ===================================================== UART2_SCR_REG ===================================================== */ +#define UART2_UART2_SCR_REG_UART_SCRATCH_PAD_Pos (0UL) /*!< UART_SCRATCH_PAD (Bit 0) */ +#define UART2_UART2_SCR_REG_UART_SCRATCH_PAD_Msk (0xffUL) /*!< UART_SCRATCH_PAD (Bitfield-Mask: 0xff) */ +/* ==================================================== UART2_SDMAM_REG ==================================================== */ +#define UART2_UART2_SDMAM_REG_UART_SHADOW_DMA_MODE_Pos (0UL) /*!< UART_SHADOW_DMA_MODE (Bit 0) */ +#define UART2_UART2_SDMAM_REG_UART_SHADOW_DMA_MODE_Msk (0x1UL) /*!< UART_SHADOW_DMA_MODE (Bitfield-Mask: 0x01) */ +/* ===================================================== UART2_SFE_REG ===================================================== */ +#define UART2_UART2_SFE_REG_UART_SHADOW_FIFO_ENABLE_Pos (0UL) /*!< UART_SHADOW_FIFO_ENABLE (Bit 0) */ +#define UART2_UART2_SFE_REG_UART_SHADOW_FIFO_ENABLE_Msk (0x1UL) /*!< UART_SHADOW_FIFO_ENABLE (Bitfield-Mask: 0x01) */ +/* ================================================= UART2_SRBR_STHR0_REG ================================================== */ +#define UART2_UART2_SRBR_STHR0_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR0_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR10_REG ================================================= */ +#define UART2_UART2_SRBR_STHR10_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR10_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR11_REG ================================================= */ +#define UART2_UART2_SRBR_STHR11_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR11_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR12_REG ================================================= */ +#define UART2_UART2_SRBR_STHR12_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR12_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR13_REG ================================================= */ +#define UART2_UART2_SRBR_STHR13_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR13_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR14_REG ================================================= */ +#define UART2_UART2_SRBR_STHR14_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR14_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR15_REG ================================================= */ +#define UART2_UART2_SRBR_STHR15_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR15_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR1_REG ================================================== */ +#define UART2_UART2_SRBR_STHR1_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR1_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR2_REG ================================================== */ +#define UART2_UART2_SRBR_STHR2_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR2_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR3_REG ================================================== */ +#define UART2_UART2_SRBR_STHR3_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR3_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR4_REG ================================================== */ +#define UART2_UART2_SRBR_STHR4_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR4_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR5_REG ================================================== */ +#define UART2_UART2_SRBR_STHR5_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR5_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR6_REG ================================================== */ +#define UART2_UART2_SRBR_STHR6_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR6_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR7_REG ================================================== */ +#define UART2_UART2_SRBR_STHR7_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR7_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR8_REG ================================================== */ +#define UART2_UART2_SRBR_STHR8_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR8_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART2_SRBR_STHR9_REG ================================================== */ +#define UART2_UART2_SRBR_STHR9_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART2_UART2_SRBR_STHR9_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ===================================================== UART2_SRR_REG ===================================================== */ +#define UART2_UART2_SRR_REG_UART_XFR_Pos (2UL) /*!< UART_XFR (Bit 2) */ +#define UART2_UART2_SRR_REG_UART_XFR_Msk (0x4UL) /*!< UART_XFR (Bitfield-Mask: 0x01) */ +#define UART2_UART2_SRR_REG_UART_RFR_Pos (1UL) /*!< UART_RFR (Bit 1) */ +#define UART2_UART2_SRR_REG_UART_RFR_Msk (0x2UL) /*!< UART_RFR (Bitfield-Mask: 0x01) */ +#define UART2_UART2_SRR_REG_UART_UR_Pos (0UL) /*!< UART_UR (Bit 0) */ +#define UART2_UART2_SRR_REG_UART_UR_Msk (0x1UL) /*!< UART_UR (Bitfield-Mask: 0x01) */ +/* ==================================================== UART2_SRTS_REG ===================================================== */ +#define UART2_UART2_SRTS_REG_UART_SHADOW_REQUEST_TO_SEND_Pos (0UL) /*!< UART_SHADOW_REQUEST_TO_SEND (Bit 0) */ +#define UART2_UART2_SRTS_REG_UART_SHADOW_REQUEST_TO_SEND_Msk (0x1UL) /*!< UART_SHADOW_REQUEST_TO_SEND (Bitfield-Mask: 0x01) */ +/* ===================================================== UART2_SRT_REG ===================================================== */ +#define UART2_UART2_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Pos (0UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bit 0) */ +#define UART2_UART2_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bitfield-Mask: 0x03) */ +/* ==================================================== UART2_STET_REG ===================================================== */ +#define UART2_UART2_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Pos (0UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bit 0) */ +#define UART2_UART2_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bitfield-Mask: 0x03) */ +/* ===================================================== UART2_TAR_REG ===================================================== */ +#define UART2_UART2_TAR_REG_UART_TAR_Pos (0UL) /*!< UART_TAR (Bit 0) */ +#define UART2_UART2_TAR_REG_UART_TAR_Msk (0xffUL) /*!< UART_TAR (Bitfield-Mask: 0xff) */ +/* ===================================================== UART2_TFL_REG ===================================================== */ +#define UART2_UART2_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Pos (0UL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bit 0) */ +#define UART2_UART2_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ +/* ===================================================== UART2_UCV_REG ===================================================== */ +#define UART2_UART2_UCV_REG_UART_UCV_Pos (0UL) /*!< UART_UCV (Bit 0) */ +#define UART2_UART2_UCV_REG_UART_UCV_Msk (0xffffffffUL) /*!< UART_UCV (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== UART2_USR_REG ===================================================== */ +#define UART2_UART2_USR_REG_UART_RFF_Pos (4UL) /*!< UART_RFF (Bit 4) */ +#define UART2_UART2_USR_REG_UART_RFF_Msk (0x10UL) /*!< UART_RFF (Bitfield-Mask: 0x01) */ +#define UART2_UART2_USR_REG_UART_RFNE_Pos (3UL) /*!< UART_RFNE (Bit 3) */ +#define UART2_UART2_USR_REG_UART_RFNE_Msk (0x8UL) /*!< UART_RFNE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_USR_REG_UART_TFE_Pos (2UL) /*!< UART_TFE (Bit 2) */ +#define UART2_UART2_USR_REG_UART_TFE_Msk (0x4UL) /*!< UART_TFE (Bitfield-Mask: 0x01) */ +#define UART2_UART2_USR_REG_UART_TFNF_Pos (1UL) /*!< UART_TFNF (Bit 1) */ +#define UART2_UART2_USR_REG_UART_TFNF_Msk (0x2UL) /*!< UART_TFNF (Bitfield-Mask: 0x01) */ +#define UART2_UART2_USR_REG_UART_BUSY_Pos (0UL) /*!< UART_BUSY (Bit 0) */ +#define UART2_UART2_USR_REG_UART_BUSY_Msk (0x1UL) /*!< UART_BUSY (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ UART3 ================ */ +/* =========================================================================================================================== */ + +/* =================================================== UART3_CONFIG_REG ==================================================== */ +#define UART3_UART3_CONFIG_REG_ISO7816_SCRATCH_PAD_Pos (3UL) /*!< ISO7816_SCRATCH_PAD (Bit 3) */ +#define UART3_UART3_CONFIG_REG_ISO7816_SCRATCH_PAD_Msk (0xf8UL) /*!< ISO7816_SCRATCH_PAD (Bitfield-Mask: 0x1f) */ +#define UART3_UART3_CONFIG_REG_ISO7816_ENABLE_Pos (2UL) /*!< ISO7816_ENABLE (Bit 2) */ +#define UART3_UART3_CONFIG_REG_ISO7816_ENABLE_Msk (0x4UL) /*!< ISO7816_ENABLE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CONFIG_REG_ISO7816_ERR_SIG_EN_Pos (1UL) /*!< ISO7816_ERR_SIG_EN (Bit 1) */ +#define UART3_UART3_CONFIG_REG_ISO7816_ERR_SIG_EN_Msk (0x2UL) /*!< ISO7816_ERR_SIG_EN (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CONFIG_REG_ISO7816_CONVENTION_Pos (0UL) /*!< ISO7816_CONVENTION (Bit 0) */ +#define UART3_UART3_CONFIG_REG_ISO7816_CONVENTION_Msk (0x1UL) /*!< ISO7816_CONVENTION (Bitfield-Mask: 0x01) */ +/* ==================================================== UART3_CTRL_REG ===================================================== */ +#define UART3_UART3_CTRL_REG_ISO7816_AUTO_GT_Pos (11UL) /*!< ISO7816_AUTO_GT (Bit 11) */ +#define UART3_UART3_CTRL_REG_ISO7816_AUTO_GT_Msk (0x800UL) /*!< ISO7816_AUTO_GT (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CTRL_REG_ISO7816_ERR_TX_VALUE_IRQMASK_Pos (10UL) /*!< ISO7816_ERR_TX_VALUE_IRQMASK (Bit 10) */ +#define UART3_UART3_CTRL_REG_ISO7816_ERR_TX_VALUE_IRQMASK_Msk (0x400UL) /*!< ISO7816_ERR_TX_VALUE_IRQMASK (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CTRL_REG_ISO7816_ERR_TX_TIME_IRQMASK_Pos (9UL) /*!< ISO7816_ERR_TX_TIME_IRQMASK (Bit 9) */ +#define UART3_UART3_CTRL_REG_ISO7816_ERR_TX_TIME_IRQMASK_Msk (0x200UL) /*!< ISO7816_ERR_TX_TIME_IRQMASK (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CTRL_REG_ISO7816_TIM_EXPIRED_IRQMASK_Pos (8UL) /*!< ISO7816_TIM_EXPIRED_IRQMASK (Bit 8) */ +#define UART3_UART3_CTRL_REG_ISO7816_TIM_EXPIRED_IRQMASK_Msk (0x100UL) /*!< ISO7816_TIM_EXPIRED_IRQMASK (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CTRL_REG_ISO7816_CLK_STATUS_Pos (7UL) /*!< ISO7816_CLK_STATUS (Bit 7) */ +#define UART3_UART3_CTRL_REG_ISO7816_CLK_STATUS_Msk (0x80UL) /*!< ISO7816_CLK_STATUS (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CTRL_REG_ISO7816_CLK_LEVEL_Pos (6UL) /*!< ISO7816_CLK_LEVEL (Bit 6) */ +#define UART3_UART3_CTRL_REG_ISO7816_CLK_LEVEL_Msk (0x40UL) /*!< ISO7816_CLK_LEVEL (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CTRL_REG_ISO7816_CLK_EN_Pos (5UL) /*!< ISO7816_CLK_EN (Bit 5) */ +#define UART3_UART3_CTRL_REG_ISO7816_CLK_EN_Msk (0x20UL) /*!< ISO7816_CLK_EN (Bitfield-Mask: 0x01) */ +#define UART3_UART3_CTRL_REG_ISO7816_CLK_DIV_Pos (0UL) /*!< ISO7816_CLK_DIV (Bit 0) */ +#define UART3_UART3_CTRL_REG_ISO7816_CLK_DIV_Msk (0x1fUL) /*!< ISO7816_CLK_DIV (Bitfield-Mask: 0x1f) */ +/* ===================================================== UART3_CTR_REG ===================================================== */ +#define UART3_UART3_CTR_REG_UART_CTR_Pos (0UL) /*!< UART_CTR (Bit 0) */ +#define UART3_UART3_CTR_REG_UART_CTR_Msk (0xffffffffUL) /*!< UART_CTR (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== UART3_DLF_REG ===================================================== */ +#define UART3_UART3_DLF_REG_UART_DLF_Pos (0UL) /*!< UART_DLF (Bit 0) */ +#define UART3_UART3_DLF_REG_UART_DLF_Msk (0xfUL) /*!< UART_DLF (Bitfield-Mask: 0x0f) */ +/* ==================================================== UART3_DMASA_REG ==================================================== */ +#define UART3_UART3_DMASA_REG_UART_DMASA_Pos (0UL) /*!< UART_DMASA (Bit 0) */ +#define UART3_UART3_DMASA_REG_UART_DMASA_Msk (0x1UL) /*!< UART_DMASA (Bitfield-Mask: 0x01) */ +/* ================================================== UART3_ERR_CTRL_REG =================================================== */ +#define UART3_UART3_ERR_CTRL_REG_ISO7816_ERR_PULSE_WIDTH_Pos (4UL) /*!< ISO7816_ERR_PULSE_WIDTH (Bit 4) */ +#define UART3_UART3_ERR_CTRL_REG_ISO7816_ERR_PULSE_WIDTH_Msk (0x1f0UL) /*!< ISO7816_ERR_PULSE_WIDTH (Bitfield-Mask: 0x1f) */ +#define UART3_UART3_ERR_CTRL_REG_ISO7816_ERR_PULSE_OFFSET_Pos (0UL) /*!< ISO7816_ERR_PULSE_OFFSET (Bit 0) */ +#define UART3_UART3_ERR_CTRL_REG_ISO7816_ERR_PULSE_OFFSET_Msk (0xfUL) /*!< ISO7816_ERR_PULSE_OFFSET (Bitfield-Mask: 0x0f) */ +/* ===================================================== UART3_HTX_REG ===================================================== */ +#define UART3_UART3_HTX_REG_UART_HALT_TX_Pos (0UL) /*!< UART_HALT_TX (Bit 0) */ +#define UART3_UART3_HTX_REG_UART_HALT_TX_Msk (0x1UL) /*!< UART_HALT_TX (Bitfield-Mask: 0x01) */ +/* =================================================== UART3_IER_DLH_REG =================================================== */ +#define UART3_UART3_IER_DLH_REG_PTIME_DLH7_Pos (7UL) /*!< PTIME_DLH7 (Bit 7) */ +#define UART3_UART3_IER_DLH_REG_PTIME_DLH7_Msk (0x80UL) /*!< PTIME_DLH7 (Bitfield-Mask: 0x01) */ +#define UART3_UART3_IER_DLH_REG_DLH6_5_Pos (5UL) /*!< DLH6_5 (Bit 5) */ +#define UART3_UART3_IER_DLH_REG_DLH6_5_Msk (0x60UL) /*!< DLH6_5 (Bitfield-Mask: 0x03) */ +#define UART3_UART3_IER_DLH_REG_ELCOLR_DLH4_Pos (4UL) /*!< ELCOLR_DLH4 (Bit 4) */ +#define UART3_UART3_IER_DLH_REG_ELCOLR_DLH4_Msk (0x10UL) /*!< ELCOLR_DLH4 (Bitfield-Mask: 0x01) */ +#define UART3_UART3_IER_DLH_REG_EDSSI_DLH3_Pos (3UL) /*!< EDSSI_DLH3 (Bit 3) */ +#define UART3_UART3_IER_DLH_REG_EDSSI_DLH3_Msk (0x8UL) /*!< EDSSI_DLH3 (Bitfield-Mask: 0x01) */ +#define UART3_UART3_IER_DLH_REG_ELSI_DLH2_Pos (2UL) /*!< ELSI_DLH2 (Bit 2) */ +#define UART3_UART3_IER_DLH_REG_ELSI_DLH2_Msk (0x4UL) /*!< ELSI_DLH2 (Bitfield-Mask: 0x01) */ +#define UART3_UART3_IER_DLH_REG_ETBEI_DLH1_Pos (1UL) /*!< ETBEI_DLH1 (Bit 1) */ +#define UART3_UART3_IER_DLH_REG_ETBEI_DLH1_Msk (0x2UL) /*!< ETBEI_DLH1 (Bitfield-Mask: 0x01) */ +#define UART3_UART3_IER_DLH_REG_ERBFI_DLH0_Pos (0UL) /*!< ERBFI_DLH0 (Bit 0) */ +#define UART3_UART3_IER_DLH_REG_ERBFI_DLH0_Msk (0x1UL) /*!< ERBFI_DLH0 (Bitfield-Mask: 0x01) */ +/* =================================================== UART3_IIR_FCR_REG =================================================== */ +#define UART3_UART3_IIR_FCR_REG_IIR_FCR_Pos (0UL) /*!< IIR_FCR (Bit 0) */ +#define UART3_UART3_IIR_FCR_REG_IIR_FCR_Msk (0xffUL) /*!< IIR_FCR (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_IRQ_STATUS_REG ================================================== */ +#define UART3_UART3_IRQ_STATUS_REG_ISO7816_ERR_TX_VALUE_IRQ_Pos (2UL) /*!< ISO7816_ERR_TX_VALUE_IRQ (Bit 2) */ +#define UART3_UART3_IRQ_STATUS_REG_ISO7816_ERR_TX_VALUE_IRQ_Msk (0x4UL) /*!< ISO7816_ERR_TX_VALUE_IRQ (Bitfield-Mask: 0x01) */ +#define UART3_UART3_IRQ_STATUS_REG_ISO7816_ERR_TX_TIME_IRQ_Pos (1UL) /*!< ISO7816_ERR_TX_TIME_IRQ (Bit 1) */ +#define UART3_UART3_IRQ_STATUS_REG_ISO7816_ERR_TX_TIME_IRQ_Msk (0x2UL) /*!< ISO7816_ERR_TX_TIME_IRQ (Bitfield-Mask: 0x01) */ +#define UART3_UART3_IRQ_STATUS_REG_ISO7816_TIM_EXPIRED_IRQ_Pos (0UL) /*!< ISO7816_TIM_EXPIRED_IRQ (Bit 0) */ +#define UART3_UART3_IRQ_STATUS_REG_ISO7816_TIM_EXPIRED_IRQ_Msk (0x1UL) /*!< ISO7816_TIM_EXPIRED_IRQ (Bitfield-Mask: 0x01) */ +/* ===================================================== UART3_LCR_EXT ===================================================== */ +#define UART3_UART3_LCR_EXT_UART_TRANSMIT_MODE_Pos (3UL) /*!< UART_TRANSMIT_MODE (Bit 3) */ +#define UART3_UART3_LCR_EXT_UART_TRANSMIT_MODE_Msk (0x8UL) /*!< UART_TRANSMIT_MODE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_EXT_UART_SEND_ADDR_Pos (2UL) /*!< UART_SEND_ADDR (Bit 2) */ +#define UART3_UART3_LCR_EXT_UART_SEND_ADDR_Msk (0x4UL) /*!< UART_SEND_ADDR (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_EXT_UART_ADDR_MATCH_Pos (1UL) /*!< UART_ADDR_MATCH (Bit 1) */ +#define UART3_UART3_LCR_EXT_UART_ADDR_MATCH_Msk (0x2UL) /*!< UART_ADDR_MATCH (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_EXT_UART_DLS_E_Pos (0UL) /*!< UART_DLS_E (Bit 0) */ +#define UART3_UART3_LCR_EXT_UART_DLS_E_Msk (0x1UL) /*!< UART_DLS_E (Bitfield-Mask: 0x01) */ +/* ===================================================== UART3_LCR_REG ===================================================== */ +#define UART3_UART3_LCR_REG_UART_DLAB_Pos (7UL) /*!< UART_DLAB (Bit 7) */ +#define UART3_UART3_LCR_REG_UART_DLAB_Msk (0x80UL) /*!< UART_DLAB (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_REG_UART_BC_Pos (6UL) /*!< UART_BC (Bit 6) */ +#define UART3_UART3_LCR_REG_UART_BC_Msk (0x40UL) /*!< UART_BC (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_REG_UART_SP_Pos (5UL) /*!< UART_SP (Bit 5) */ +#define UART3_UART3_LCR_REG_UART_SP_Msk (0x20UL) /*!< UART_SP (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_REG_UART_EPS_Pos (4UL) /*!< UART_EPS (Bit 4) */ +#define UART3_UART3_LCR_REG_UART_EPS_Msk (0x10UL) /*!< UART_EPS (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_REG_UART_PEN_Pos (3UL) /*!< UART_PEN (Bit 3) */ +#define UART3_UART3_LCR_REG_UART_PEN_Msk (0x8UL) /*!< UART_PEN (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_REG_UART_STOP_Pos (2UL) /*!< UART_STOP (Bit 2) */ +#define UART3_UART3_LCR_REG_UART_STOP_Msk (0x4UL) /*!< UART_STOP (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LCR_REG_UART_DLS_Pos (0UL) /*!< UART_DLS (Bit 0) */ +#define UART3_UART3_LCR_REG_UART_DLS_Msk (0x3UL) /*!< UART_DLS (Bitfield-Mask: 0x03) */ +/* ===================================================== UART3_LSR_REG ===================================================== */ +#define UART3_UART3_LSR_REG_UART_ADDR_RCVD_Pos (8UL) /*!< UART_ADDR_RCVD (Bit 8) */ +#define UART3_UART3_LSR_REG_UART_ADDR_RCVD_Msk (0x100UL) /*!< UART_ADDR_RCVD (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LSR_REG_UART_RFE_Pos (7UL) /*!< UART_RFE (Bit 7) */ +#define UART3_UART3_LSR_REG_UART_RFE_Msk (0x80UL) /*!< UART_RFE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LSR_REG_UART_TEMT_Pos (6UL) /*!< UART_TEMT (Bit 6) */ +#define UART3_UART3_LSR_REG_UART_TEMT_Msk (0x40UL) /*!< UART_TEMT (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LSR_REG_UART_THRE_Pos (5UL) /*!< UART_THRE (Bit 5) */ +#define UART3_UART3_LSR_REG_UART_THRE_Msk (0x20UL) /*!< UART_THRE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LSR_REG_UART_BI_Pos (4UL) /*!< UART_BI (Bit 4) */ +#define UART3_UART3_LSR_REG_UART_BI_Msk (0x10UL) /*!< UART_BI (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LSR_REG_UART_FE_Pos (3UL) /*!< UART_FE (Bit 3) */ +#define UART3_UART3_LSR_REG_UART_FE_Msk (0x8UL) /*!< UART_FE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LSR_REG_UART_PE_Pos (2UL) /*!< UART_PE (Bit 2) */ +#define UART3_UART3_LSR_REG_UART_PE_Msk (0x4UL) /*!< UART_PE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LSR_REG_UART_OE_Pos (1UL) /*!< UART_OE (Bit 1) */ +#define UART3_UART3_LSR_REG_UART_OE_Msk (0x2UL) /*!< UART_OE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_LSR_REG_UART_DR_Pos (0UL) /*!< UART_DR (Bit 0) */ +#define UART3_UART3_LSR_REG_UART_DR_Msk (0x1UL) /*!< UART_DR (Bitfield-Mask: 0x01) */ +/* ===================================================== UART3_MCR_REG ===================================================== */ +#define UART3_UART3_MCR_REG_UART_AFCE_Pos (5UL) /*!< UART_AFCE (Bit 5) */ +#define UART3_UART3_MCR_REG_UART_AFCE_Msk (0x20UL) /*!< UART_AFCE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_MCR_REG_UART_LB_Pos (4UL) /*!< UART_LB (Bit 4) */ +#define UART3_UART3_MCR_REG_UART_LB_Msk (0x10UL) /*!< UART_LB (Bitfield-Mask: 0x01) */ +#define UART3_UART3_MCR_REG_UART_RTS_Pos (1UL) /*!< UART_RTS (Bit 1) */ +#define UART3_UART3_MCR_REG_UART_RTS_Msk (0x2UL) /*!< UART_RTS (Bitfield-Mask: 0x01) */ +/* ===================================================== UART3_MSR_REG ===================================================== */ +#define UART3_UART3_MSR_REG_UART_CTS_Pos (4UL) /*!< UART_CTS (Bit 4) */ +#define UART3_UART3_MSR_REG_UART_CTS_Msk (0x10UL) /*!< UART_CTS (Bitfield-Mask: 0x01) */ +#define UART3_UART3_MSR_REG_UART_DCTS_Pos (0UL) /*!< UART_DCTS (Bit 0) */ +#define UART3_UART3_MSR_REG_UART_DCTS_Msk (0x1UL) /*!< UART_DCTS (Bitfield-Mask: 0x01) */ +/* ===================================================== UART3_RAR_REG ===================================================== */ +#define UART3_UART3_RAR_REG_UART_RAR_Pos (0UL) /*!< UART_RAR (Bit 0) */ +#define UART3_UART3_RAR_REG_UART_RAR_Msk (0xffUL) /*!< UART_RAR (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_RBR_THR_DLL_REG ================================================= */ +#define UART3_UART3_RBR_THR_DLL_REG_RBR_THR_9BIT_Pos (8UL) /*!< RBR_THR_9BIT (Bit 8) */ +#define UART3_UART3_RBR_THR_DLL_REG_RBR_THR_9BIT_Msk (0x100UL) /*!< RBR_THR_9BIT (Bitfield-Mask: 0x01) */ +#define UART3_UART3_RBR_THR_DLL_REG_RBR_THR_DLL_Pos (0UL) /*!< RBR_THR_DLL (Bit 0) */ +#define UART3_UART3_RBR_THR_DLL_REG_RBR_THR_DLL_Msk (0xffUL) /*!< RBR_THR_DLL (Bitfield-Mask: 0xff) */ +/* ===================================================== UART3_RFL_REG ===================================================== */ +#define UART3_UART3_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Pos (0UL) /*!< UART_RECEIVE_FIFO_LEVEL (Bit 0) */ +#define UART3_UART3_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_RECEIVE_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ +/* ==================================================== UART3_SBCR_REG ===================================================== */ +#define UART3_UART3_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Pos (0UL) /*!< UART_SHADOW_BREAK_CONTROL (Bit 0) */ +#define UART3_UART3_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Msk (0x1UL) /*!< UART_SHADOW_BREAK_CONTROL (Bitfield-Mask: 0x01) */ +/* ==================================================== UART3_SDMAM_REG ==================================================== */ +#define UART3_UART3_SDMAM_REG_UART_SHADOW_DMA_MODE_Pos (0UL) /*!< UART_SHADOW_DMA_MODE (Bit 0) */ +#define UART3_UART3_SDMAM_REG_UART_SHADOW_DMA_MODE_Msk (0x1UL) /*!< UART_SHADOW_DMA_MODE (Bitfield-Mask: 0x01) */ +/* ===================================================== UART3_SFE_REG ===================================================== */ +#define UART3_UART3_SFE_REG_UART_SHADOW_FIFO_ENABLE_Pos (0UL) /*!< UART_SHADOW_FIFO_ENABLE (Bit 0) */ +#define UART3_UART3_SFE_REG_UART_SHADOW_FIFO_ENABLE_Msk (0x1UL) /*!< UART_SHADOW_FIFO_ENABLE (Bitfield-Mask: 0x01) */ +/* ================================================= UART3_SRBR_STHR0_REG ================================================== */ +#define UART3_UART3_SRBR_STHR0_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR0_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR10_REG ================================================= */ +#define UART3_UART3_SRBR_STHR10_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR10_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR11_REG ================================================= */ +#define UART3_UART3_SRBR_STHR11_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR11_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR12_REG ================================================= */ +#define UART3_UART3_SRBR_STHR12_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR12_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR13_REG ================================================= */ +#define UART3_UART3_SRBR_STHR13_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR13_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR14_REG ================================================= */ +#define UART3_UART3_SRBR_STHR14_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR14_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR15_REG ================================================= */ +#define UART3_UART3_SRBR_STHR15_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR15_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR1_REG ================================================== */ +#define UART3_UART3_SRBR_STHR1_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR1_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR2_REG ================================================== */ +#define UART3_UART3_SRBR_STHR2_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR2_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR3_REG ================================================== */ +#define UART3_UART3_SRBR_STHR3_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR3_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR4_REG ================================================== */ +#define UART3_UART3_SRBR_STHR4_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR4_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR5_REG ================================================== */ +#define UART3_UART3_SRBR_STHR5_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR5_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR6_REG ================================================== */ +#define UART3_UART3_SRBR_STHR6_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR6_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR7_REG ================================================== */ +#define UART3_UART3_SRBR_STHR7_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR7_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR8_REG ================================================== */ +#define UART3_UART3_SRBR_STHR8_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR8_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ================================================= UART3_SRBR_STHR9_REG ================================================== */ +#define UART3_UART3_SRBR_STHR9_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ +#define UART3_UART3_SRBR_STHR9_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ +/* ===================================================== UART3_SRR_REG ===================================================== */ +#define UART3_UART3_SRR_REG_UART_XFR_Pos (2UL) /*!< UART_XFR (Bit 2) */ +#define UART3_UART3_SRR_REG_UART_XFR_Msk (0x4UL) /*!< UART_XFR (Bitfield-Mask: 0x01) */ +#define UART3_UART3_SRR_REG_UART_RFR_Pos (1UL) /*!< UART_RFR (Bit 1) */ +#define UART3_UART3_SRR_REG_UART_RFR_Msk (0x2UL) /*!< UART_RFR (Bitfield-Mask: 0x01) */ +#define UART3_UART3_SRR_REG_UART_UR_Pos (0UL) /*!< UART_UR (Bit 0) */ +#define UART3_UART3_SRR_REG_UART_UR_Msk (0x1UL) /*!< UART_UR (Bitfield-Mask: 0x01) */ +/* ==================================================== UART3_SRTS_REG ===================================================== */ +#define UART3_UART3_SRTS_REG_UART_SHADOW_REQUEST_TO_SEND_Pos (0UL) /*!< UART_SHADOW_REQUEST_TO_SEND (Bit 0) */ +#define UART3_UART3_SRTS_REG_UART_SHADOW_REQUEST_TO_SEND_Msk (0x1UL) /*!< UART_SHADOW_REQUEST_TO_SEND (Bitfield-Mask: 0x01) */ +/* ===================================================== UART3_SRT_REG ===================================================== */ +#define UART3_UART3_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Pos (0UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bit 0) */ +#define UART3_UART3_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bitfield-Mask: 0x03) */ +/* ==================================================== UART3_STET_REG ===================================================== */ +#define UART3_UART3_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Pos (0UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bit 0) */ +#define UART3_UART3_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bitfield-Mask: 0x03) */ +/* ===================================================== UART3_TAR_REG ===================================================== */ +#define UART3_UART3_TAR_REG_UART_TAR_Pos (0UL) /*!< UART_TAR (Bit 0) */ +#define UART3_UART3_TAR_REG_UART_TAR_Msk (0xffUL) /*!< UART_TAR (Bitfield-Mask: 0xff) */ +/* ===================================================== UART3_TFL_REG ===================================================== */ +#define UART3_UART3_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Pos (0UL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bit 0) */ +#define UART3_UART3_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ +/* ==================================================== UART3_TIMER_REG ==================================================== */ +#define UART3_UART3_TIMER_REG_ISO7816_TIM_MODE_Pos (17UL) /*!< ISO7816_TIM_MODE (Bit 17) */ +#define UART3_UART3_TIMER_REG_ISO7816_TIM_MODE_Msk (0x20000UL) /*!< ISO7816_TIM_MODE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_TIMER_REG_ISO7816_TIM_EN_Pos (16UL) /*!< ISO7816_TIM_EN (Bit 16) */ +#define UART3_UART3_TIMER_REG_ISO7816_TIM_EN_Msk (0x10000UL) /*!< ISO7816_TIM_EN (Bitfield-Mask: 0x01) */ +#define UART3_UART3_TIMER_REG_ISO7816_TIM_MAX_Pos (0UL) /*!< ISO7816_TIM_MAX (Bit 0) */ +#define UART3_UART3_TIMER_REG_ISO7816_TIM_MAX_Msk (0xffffUL) /*!< ISO7816_TIM_MAX (Bitfield-Mask: 0xffff) */ +/* ===================================================== UART3_UCV_REG ===================================================== */ +#define UART3_UART3_UCV_REG_UART_UCV_Pos (0UL) /*!< UART_UCV (Bit 0) */ +#define UART3_UART3_UCV_REG_UART_UCV_Msk (0xffffffffUL) /*!< UART_UCV (Bitfield-Mask: 0xffffffff) */ +/* ===================================================== UART3_USR_REG ===================================================== */ +#define UART3_UART3_USR_REG_UART_RFF_Pos (4UL) /*!< UART_RFF (Bit 4) */ +#define UART3_UART3_USR_REG_UART_RFF_Msk (0x10UL) /*!< UART_RFF (Bitfield-Mask: 0x01) */ +#define UART3_UART3_USR_REG_UART_RFNE_Pos (3UL) /*!< UART_RFNE (Bit 3) */ +#define UART3_UART3_USR_REG_UART_RFNE_Msk (0x8UL) /*!< UART_RFNE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_USR_REG_UART_TFE_Pos (2UL) /*!< UART_TFE (Bit 2) */ +#define UART3_UART3_USR_REG_UART_TFE_Msk (0x4UL) /*!< UART_TFE (Bitfield-Mask: 0x01) */ +#define UART3_UART3_USR_REG_UART_TFNF_Pos (1UL) /*!< UART_TFNF (Bit 1) */ +#define UART3_UART3_USR_REG_UART_TFNF_Msk (0x2UL) /*!< UART_TFNF (Bitfield-Mask: 0x01) */ +#define UART3_UART3_USR_REG_UART_BUSY_Pos (0UL) /*!< UART_BUSY (Bit 0) */ +#define UART3_UART3_USR_REG_UART_BUSY_Msk (0x1UL) /*!< UART_BUSY (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ USB ================ */ +/* =========================================================================================================================== */ + +/* ===================================================== USB_ALTEV_REG ===================================================== */ +#define USB_USB_ALTEV_REG_USB_RESUME_Pos (7UL) /*!< USB_RESUME (Bit 7) */ +#define USB_USB_ALTEV_REG_USB_RESUME_Msk (0x80UL) /*!< USB_RESUME (Bitfield-Mask: 0x01) */ +#define USB_USB_ALTEV_REG_USB_RESET_Pos (6UL) /*!< USB_RESET (Bit 6) */ +#define USB_USB_ALTEV_REG_USB_RESET_Msk (0x40UL) /*!< USB_RESET (Bitfield-Mask: 0x01) */ +#define USB_USB_ALTEV_REG_USB_SD5_Pos (5UL) /*!< USB_SD5 (Bit 5) */ +#define USB_USB_ALTEV_REG_USB_SD5_Msk (0x20UL) /*!< USB_SD5 (Bitfield-Mask: 0x01) */ +#define USB_USB_ALTEV_REG_USB_SD3_Pos (4UL) /*!< USB_SD3 (Bit 4) */ +#define USB_USB_ALTEV_REG_USB_SD3_Msk (0x10UL) /*!< USB_SD3 (Bitfield-Mask: 0x01) */ +#define USB_USB_ALTEV_REG_USB_EOP_Pos (3UL) /*!< USB_EOP (Bit 3) */ +#define USB_USB_ALTEV_REG_USB_EOP_Msk (0x8UL) /*!< USB_EOP (Bitfield-Mask: 0x01) */ +/* ==================================================== USB_ALTMSK_REG ===================================================== */ +#define USB_USB_ALTMSK_REG_USB_M_RESUME_Pos (7UL) /*!< USB_M_RESUME (Bit 7) */ +#define USB_USB_ALTMSK_REG_USB_M_RESUME_Msk (0x80UL) /*!< USB_M_RESUME (Bitfield-Mask: 0x01) */ +#define USB_USB_ALTMSK_REG_USB_M_RESET_Pos (6UL) /*!< USB_M_RESET (Bit 6) */ +#define USB_USB_ALTMSK_REG_USB_M_RESET_Msk (0x40UL) /*!< USB_M_RESET (Bitfield-Mask: 0x01) */ +#define USB_USB_ALTMSK_REG_USB_M_SD5_Pos (5UL) /*!< USB_M_SD5 (Bit 5) */ +#define USB_USB_ALTMSK_REG_USB_M_SD5_Msk (0x20UL) /*!< USB_M_SD5 (Bitfield-Mask: 0x01) */ +#define USB_USB_ALTMSK_REG_USB_M_SD3_Pos (4UL) /*!< USB_M_SD3 (Bit 4) */ +#define USB_USB_ALTMSK_REG_USB_M_SD3_Msk (0x10UL) /*!< USB_M_SD3 (Bitfield-Mask: 0x01) */ +#define USB_USB_ALTMSK_REG_USB_M_EOP_Pos (3UL) /*!< USB_M_EOP (Bit 3) */ +#define USB_USB_ALTMSK_REG_USB_M_EOP_Msk (0x8UL) /*!< USB_M_EOP (Bitfield-Mask: 0x01) */ +/* ================================================= USB_CHARGER_CTRL_REG ================================================== */ +#define USB_USB_CHARGER_CTRL_REG_IDM_SINK_ON_Pos (5UL) /*!< IDM_SINK_ON (Bit 5) */ +#define USB_USB_CHARGER_CTRL_REG_IDM_SINK_ON_Msk (0x20UL) /*!< IDM_SINK_ON (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_CTRL_REG_IDP_SINK_ON_Pos (4UL) /*!< IDP_SINK_ON (Bit 4) */ +#define USB_USB_CHARGER_CTRL_REG_IDP_SINK_ON_Msk (0x10UL) /*!< IDP_SINK_ON (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_CTRL_REG_VDM_SRC_ON_Pos (3UL) /*!< VDM_SRC_ON (Bit 3) */ +#define USB_USB_CHARGER_CTRL_REG_VDM_SRC_ON_Msk (0x8UL) /*!< VDM_SRC_ON (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_CTRL_REG_VDP_SRC_ON_Pos (2UL) /*!< VDP_SRC_ON (Bit 2) */ +#define USB_USB_CHARGER_CTRL_REG_VDP_SRC_ON_Msk (0x4UL) /*!< VDP_SRC_ON (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_CTRL_REG_IDP_SRC_ON_Pos (1UL) /*!< IDP_SRC_ON (Bit 1) */ +#define USB_USB_CHARGER_CTRL_REG_IDP_SRC_ON_Msk (0x2UL) /*!< IDP_SRC_ON (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_CTRL_REG_USB_CHARGE_ON_Pos (0UL) /*!< USB_CHARGE_ON (Bit 0) */ +#define USB_USB_CHARGER_CTRL_REG_USB_CHARGE_ON_Msk (0x1UL) /*!< USB_CHARGE_ON (Bitfield-Mask: 0x01) */ +/* ================================================= USB_CHARGER_STAT_REG ================================================== */ +#define USB_USB_CHARGER_STAT_REG_USB_DM_VAL2_Pos (5UL) /*!< USB_DM_VAL2 (Bit 5) */ +#define USB_USB_CHARGER_STAT_REG_USB_DM_VAL2_Msk (0x20UL) /*!< USB_DM_VAL2 (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_STAT_REG_USB_DP_VAL2_Pos (4UL) /*!< USB_DP_VAL2 (Bit 4) */ +#define USB_USB_CHARGER_STAT_REG_USB_DP_VAL2_Msk (0x10UL) /*!< USB_DP_VAL2 (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_STAT_REG_USB_DM_VAL_Pos (3UL) /*!< USB_DM_VAL (Bit 3) */ +#define USB_USB_CHARGER_STAT_REG_USB_DM_VAL_Msk (0x8UL) /*!< USB_DM_VAL (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_STAT_REG_USB_DP_VAL_Pos (2UL) /*!< USB_DP_VAL (Bit 2) */ +#define USB_USB_CHARGER_STAT_REG_USB_DP_VAL_Msk (0x4UL) /*!< USB_DP_VAL (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_STAT_REG_USB_CHG_DET_Pos (1UL) /*!< USB_CHG_DET (Bit 1) */ +#define USB_USB_CHARGER_STAT_REG_USB_CHG_DET_Msk (0x2UL) /*!< USB_CHG_DET (Bitfield-Mask: 0x01) */ +#define USB_USB_CHARGER_STAT_REG_USB_DCP_DET_Pos (0UL) /*!< USB_DCP_DET (Bit 0) */ +#define USB_USB_CHARGER_STAT_REG_USB_DCP_DET_Msk (0x1UL) /*!< USB_DCP_DET (Bitfield-Mask: 0x01) */ +/* =================================================== USB_DMA_CTRL_REG ==================================================== */ +#define USB_USB_DMA_CTRL_REG_USB_DMA_EN_Pos (6UL) /*!< USB_DMA_EN (Bit 6) */ +#define USB_USB_DMA_CTRL_REG_USB_DMA_EN_Msk (0x40UL) /*!< USB_DMA_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_DMA_CTRL_REG_USB_DMA_TX_Pos (3UL) /*!< USB_DMA_TX (Bit 3) */ +#define USB_USB_DMA_CTRL_REG_USB_DMA_TX_Msk (0x38UL) /*!< USB_DMA_TX (Bitfield-Mask: 0x07) */ +#define USB_USB_DMA_CTRL_REG_USB_DMA_RX_Pos (0UL) /*!< USB_DMA_RX (Bit 0) */ +#define USB_USB_DMA_CTRL_REG_USB_DMA_RX_Msk (0x7UL) /*!< USB_DMA_RX (Bitfield-Mask: 0x07) */ +/* ==================================================== USB_EP0_NAK_REG ==================================================== */ +#define USB_USB_EP0_NAK_REG_USB_EP0_OUTNAK_Pos (1UL) /*!< USB_EP0_OUTNAK (Bit 1) */ +#define USB_USB_EP0_NAK_REG_USB_EP0_OUTNAK_Msk (0x2UL) /*!< USB_EP0_OUTNAK (Bitfield-Mask: 0x01) */ +#define USB_USB_EP0_NAK_REG_USB_EP0_INNAK_Pos (0UL) /*!< USB_EP0_INNAK (Bit 0) */ +#define USB_USB_EP0_NAK_REG_USB_EP0_INNAK_Msk (0x1UL) /*!< USB_EP0_INNAK (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_EPC0_REG ====================================================== */ +#define USB_USB_EPC0_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ +#define USB_USB_EPC0_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC0_REG_USB_DEF_Pos (6UL) /*!< USB_DEF (Bit 6) */ +#define USB_USB_EPC0_REG_USB_DEF_Msk (0x40UL) /*!< USB_DEF (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC0_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ +#define USB_USB_EPC0_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_EPC1_REG ====================================================== */ +#define USB_USB_EPC1_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ +#define USB_USB_EPC1_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC1_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ +#define USB_USB_EPC1_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC1_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ +#define USB_USB_EPC1_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC1_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ +#define USB_USB_EPC1_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_EPC2_REG ====================================================== */ +#define USB_USB_EPC2_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ +#define USB_USB_EPC2_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC2_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ +#define USB_USB_EPC2_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC2_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ +#define USB_USB_EPC2_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC2_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ +#define USB_USB_EPC2_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_EPC3_REG ====================================================== */ +#define USB_USB_EPC3_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ +#define USB_USB_EPC3_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC3_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ +#define USB_USB_EPC3_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC3_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ +#define USB_USB_EPC3_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC3_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ +#define USB_USB_EPC3_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_EPC4_REG ====================================================== */ +#define USB_USB_EPC4_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ +#define USB_USB_EPC4_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC4_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ +#define USB_USB_EPC4_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC4_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ +#define USB_USB_EPC4_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC4_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ +#define USB_USB_EPC4_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_EPC5_REG ====================================================== */ +#define USB_USB_EPC5_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ +#define USB_USB_EPC5_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC5_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ +#define USB_USB_EPC5_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC5_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ +#define USB_USB_EPC5_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC5_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ +#define USB_USB_EPC5_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_EPC6_REG ====================================================== */ +#define USB_USB_EPC6_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ +#define USB_USB_EPC6_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC6_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ +#define USB_USB_EPC6_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC6_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ +#define USB_USB_EPC6_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_EPC6_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ +#define USB_USB_EPC6_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ +/* ====================================================== USB_FAR_REG ====================================================== */ +#define USB_USB_FAR_REG_USB_AD_EN_Pos (7UL) /*!< USB_AD_EN (Bit 7) */ +#define USB_USB_FAR_REG_USB_AD_EN_Msk (0x80UL) /*!< USB_AD_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_FAR_REG_USB_AD_Pos (0UL) /*!< USB_AD (Bit 0) */ +#define USB_USB_FAR_REG_USB_AD_Msk (0x7fUL) /*!< USB_AD (Bitfield-Mask: 0x7f) */ +/* ====================================================== USB_FNH_REG ====================================================== */ +#define USB_USB_FNH_REG_USB_MF_Pos (7UL) /*!< USB_MF (Bit 7) */ +#define USB_USB_FNH_REG_USB_MF_Msk (0x80UL) /*!< USB_MF (Bitfield-Mask: 0x01) */ +#define USB_USB_FNH_REG_USB_UL_Pos (6UL) /*!< USB_UL (Bit 6) */ +#define USB_USB_FNH_REG_USB_UL_Msk (0x40UL) /*!< USB_UL (Bitfield-Mask: 0x01) */ +#define USB_USB_FNH_REG_USB_RFC_Pos (5UL) /*!< USB_RFC (Bit 5) */ +#define USB_USB_FNH_REG_USB_RFC_Msk (0x20UL) /*!< USB_RFC (Bitfield-Mask: 0x01) */ +#define USB_USB_FNH_REG_USB_FN_10_8_Pos (0UL) /*!< USB_FN_10_8 (Bit 0) */ +#define USB_USB_FNH_REG_USB_FN_10_8_Msk (0x7UL) /*!< USB_FN_10_8 (Bitfield-Mask: 0x07) */ +/* ====================================================== USB_FNL_REG ====================================================== */ +#define USB_USB_FNL_REG_USB_FN_Pos (0UL) /*!< USB_FN (Bit 0) */ +#define USB_USB_FNL_REG_USB_FN_Msk (0xffUL) /*!< USB_FN (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_FWEV_REG ====================================================== */ +#define USB_USB_FWEV_REG_USB_RXWARN31_Pos (4UL) /*!< USB_RXWARN31 (Bit 4) */ +#define USB_USB_FWEV_REG_USB_RXWARN31_Msk (0x70UL) /*!< USB_RXWARN31 (Bitfield-Mask: 0x07) */ +#define USB_USB_FWEV_REG_USB_TXWARN31_Pos (0UL) /*!< USB_TXWARN31 (Bit 0) */ +#define USB_USB_FWEV_REG_USB_TXWARN31_Msk (0x7UL) /*!< USB_TXWARN31 (Bitfield-Mask: 0x07) */ +/* ===================================================== USB_FWMSK_REG ===================================================== */ +#define USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos (4UL) /*!< USB_M_RXWARN31 (Bit 4) */ +#define USB_USB_FWMSK_REG_USB_M_RXWARN31_Msk (0x70UL) /*!< USB_M_RXWARN31 (Bitfield-Mask: 0x07) */ +#define USB_USB_FWMSK_REG_USB_M_TXWARN31_Pos (0UL) /*!< USB_M_TXWARN31 (Bit 0) */ +#define USB_USB_FWMSK_REG_USB_M_TXWARN31_Msk (0x7UL) /*!< USB_M_TXWARN31 (Bitfield-Mask: 0x07) */ +/* ===================================================== USB_MAEV_REG ====================================================== */ +#define USB_USB_MAEV_REG_USB_CH_EV_Pos (11UL) /*!< USB_CH_EV (Bit 11) */ +#define USB_USB_MAEV_REG_USB_CH_EV_Msk (0x800UL) /*!< USB_CH_EV (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_EP0_NAK_Pos (10UL) /*!< USB_EP0_NAK (Bit 10) */ +#define USB_USB_MAEV_REG_USB_EP0_NAK_Msk (0x400UL) /*!< USB_EP0_NAK (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_EP0_RX_Pos (9UL) /*!< USB_EP0_RX (Bit 9) */ +#define USB_USB_MAEV_REG_USB_EP0_RX_Msk (0x200UL) /*!< USB_EP0_RX (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_EP0_TX_Pos (8UL) /*!< USB_EP0_TX (Bit 8) */ +#define USB_USB_MAEV_REG_USB_EP0_TX_Msk (0x100UL) /*!< USB_EP0_TX (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_INTR_Pos (7UL) /*!< USB_INTR (Bit 7) */ +#define USB_USB_MAEV_REG_USB_INTR_Msk (0x80UL) /*!< USB_INTR (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_RX_EV_Pos (6UL) /*!< USB_RX_EV (Bit 6) */ +#define USB_USB_MAEV_REG_USB_RX_EV_Msk (0x40UL) /*!< USB_RX_EV (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_ULD_Pos (5UL) /*!< USB_ULD (Bit 5) */ +#define USB_USB_MAEV_REG_USB_ULD_Msk (0x20UL) /*!< USB_ULD (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_NAK_Pos (4UL) /*!< USB_NAK (Bit 4) */ +#define USB_USB_MAEV_REG_USB_NAK_Msk (0x10UL) /*!< USB_NAK (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_FRAME_Pos (3UL) /*!< USB_FRAME (Bit 3) */ +#define USB_USB_MAEV_REG_USB_FRAME_Msk (0x8UL) /*!< USB_FRAME (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_TX_EV_Pos (2UL) /*!< USB_TX_EV (Bit 2) */ +#define USB_USB_MAEV_REG_USB_TX_EV_Msk (0x4UL) /*!< USB_TX_EV (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_ALT_Pos (1UL) /*!< USB_ALT (Bit 1) */ +#define USB_USB_MAEV_REG_USB_ALT_Msk (0x2UL) /*!< USB_ALT (Bitfield-Mask: 0x01) */ +#define USB_USB_MAEV_REG_USB_WARN_Pos (0UL) /*!< USB_WARN (Bit 0) */ +#define USB_USB_MAEV_REG_USB_WARN_Msk (0x1UL) /*!< USB_WARN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_MAMSK_REG ===================================================== */ +#define USB_USB_MAMSK_REG_USB_M_CH_EV_Pos (11UL) /*!< USB_M_CH_EV (Bit 11) */ +#define USB_USB_MAMSK_REG_USB_M_CH_EV_Msk (0x800UL) /*!< USB_M_CH_EV (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_EP0_NAK_Pos (10UL) /*!< USB_M_EP0_NAK (Bit 10) */ +#define USB_USB_MAMSK_REG_USB_M_EP0_NAK_Msk (0x400UL) /*!< USB_M_EP0_NAK (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_EP0_RX_Pos (9UL) /*!< USB_M_EP0_RX (Bit 9) */ +#define USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk (0x200UL) /*!< USB_M_EP0_RX (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_EP0_TX_Pos (8UL) /*!< USB_M_EP0_TX (Bit 8) */ +#define USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk (0x100UL) /*!< USB_M_EP0_TX (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_INTR_Pos (7UL) /*!< USB_M_INTR (Bit 7) */ +#define USB_USB_MAMSK_REG_USB_M_INTR_Msk (0x80UL) /*!< USB_M_INTR (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_RX_EV_Pos (6UL) /*!< USB_M_RX_EV (Bit 6) */ +#define USB_USB_MAMSK_REG_USB_M_RX_EV_Msk (0x40UL) /*!< USB_M_RX_EV (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_ULD_Pos (5UL) /*!< USB_M_ULD (Bit 5) */ +#define USB_USB_MAMSK_REG_USB_M_ULD_Msk (0x20UL) /*!< USB_M_ULD (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_NAK_Pos (4UL) /*!< USB_M_NAK (Bit 4) */ +#define USB_USB_MAMSK_REG_USB_M_NAK_Msk (0x10UL) /*!< USB_M_NAK (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_FRAME_Pos (3UL) /*!< USB_M_FRAME (Bit 3) */ +#define USB_USB_MAMSK_REG_USB_M_FRAME_Msk (0x8UL) /*!< USB_M_FRAME (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_TX_EV_Pos (2UL) /*!< USB_M_TX_EV (Bit 2) */ +#define USB_USB_MAMSK_REG_USB_M_TX_EV_Msk (0x4UL) /*!< USB_M_TX_EV (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_ALT_Pos (1UL) /*!< USB_M_ALT (Bit 1) */ +#define USB_USB_MAMSK_REG_USB_M_ALT_Msk (0x2UL) /*!< USB_M_ALT (Bitfield-Mask: 0x01) */ +#define USB_USB_MAMSK_REG_USB_M_WARN_Pos (0UL) /*!< USB_M_WARN (Bit 0) */ +#define USB_USB_MAMSK_REG_USB_M_WARN_Msk (0x1UL) /*!< USB_M_WARN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_MCTRL_REG ===================================================== */ +#define USB_USB_MCTRL_REG_LSMODE_Pos (4UL) /*!< LSMODE (Bit 4) */ +#define USB_USB_MCTRL_REG_LSMODE_Msk (0x10UL) /*!< LSMODE (Bitfield-Mask: 0x01) */ +#define USB_USB_MCTRL_REG_USB_NAT_Pos (3UL) /*!< USB_NAT (Bit 3) */ +#define USB_USB_MCTRL_REG_USB_NAT_Msk (0x8UL) /*!< USB_NAT (Bitfield-Mask: 0x01) */ +#define USB_USB_MCTRL_REG_USB_DBG_Pos (1UL) /*!< USB_DBG (Bit 1) */ +#define USB_USB_MCTRL_REG_USB_DBG_Msk (0x2UL) /*!< USB_DBG (Bitfield-Mask: 0x01) */ +#define USB_USB_MCTRL_REG_USBEN_Pos (0UL) /*!< USBEN (Bit 0) */ +#define USB_USB_MCTRL_REG_USBEN_Msk (0x1UL) /*!< USBEN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_NAKEV_REG ===================================================== */ +#define USB_USB_NAKEV_REG_USB_OUT31_Pos (4UL) /*!< USB_OUT31 (Bit 4) */ +#define USB_USB_NAKEV_REG_USB_OUT31_Msk (0x70UL) /*!< USB_OUT31 (Bitfield-Mask: 0x07) */ +#define USB_USB_NAKEV_REG_USB_IN31_Pos (0UL) /*!< USB_IN31 (Bit 0) */ +#define USB_USB_NAKEV_REG_USB_IN31_Msk (0x7UL) /*!< USB_IN31 (Bitfield-Mask: 0x07) */ +/* ==================================================== USB_NAKMSK_REG ===================================================== */ +#define USB_USB_NAKMSK_REG_USB_M_OUT31_Pos (4UL) /*!< USB_M_OUT31 (Bit 4) */ +#define USB_USB_NAKMSK_REG_USB_M_OUT31_Msk (0x70UL) /*!< USB_M_OUT31 (Bitfield-Mask: 0x07) */ +#define USB_USB_NAKMSK_REG_USB_M_IN31_Pos (0UL) /*!< USB_M_IN31 (Bit 0) */ +#define USB_USB_NAKMSK_REG_USB_M_IN31_Msk (0x7UL) /*!< USB_M_IN31 (Bitfield-Mask: 0x07) */ +/* ===================================================== USB_NFSR_REG ====================================================== */ +#define USB_USB_NFSR_REG_USB_NFS_Pos (0UL) /*!< USB_NFS (Bit 0) */ +#define USB_USB_NFSR_REG_USB_NFS_Msk (0x3UL) /*!< USB_NFS (Bitfield-Mask: 0x03) */ +/* ===================================================== USB_RXC0_REG ====================================================== */ +#define USB_USB_RXC0_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ +#define USB_USB_RXC0_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC0_REG_USB_IGN_SETUP_Pos (2UL) /*!< USB_IGN_SETUP (Bit 2) */ +#define USB_USB_RXC0_REG_USB_IGN_SETUP_Msk (0x4UL) /*!< USB_IGN_SETUP (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC0_REG_USB_IGN_OUT_Pos (1UL) /*!< USB_IGN_OUT (Bit 1) */ +#define USB_USB_RXC0_REG_USB_IGN_OUT_Msk (0x2UL) /*!< USB_IGN_OUT (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC0_REG_USB_RX_EN_Pos (0UL) /*!< USB_RX_EN (Bit 0) */ +#define USB_USB_RXC0_REG_USB_RX_EN_Msk (0x1UL) /*!< USB_RX_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_RXC1_REG ====================================================== */ +#define USB_USB_RXC1_REG_USB_RFWL_Pos (5UL) /*!< USB_RFWL (Bit 5) */ +#define USB_USB_RXC1_REG_USB_RFWL_Msk (0x60UL) /*!< USB_RFWL (Bitfield-Mask: 0x03) */ +#define USB_USB_RXC1_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ +#define USB_USB_RXC1_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC1_REG_USB_IGN_SETUP_Pos (2UL) /*!< USB_IGN_SETUP (Bit 2) */ +#define USB_USB_RXC1_REG_USB_IGN_SETUP_Msk (0x4UL) /*!< USB_IGN_SETUP (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC1_REG_USB_RX_EN_Pos (0UL) /*!< USB_RX_EN (Bit 0) */ +#define USB_USB_RXC1_REG_USB_RX_EN_Msk (0x1UL) /*!< USB_RX_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_RXC2_REG ====================================================== */ +#define USB_USB_RXC2_REG_USB_RFWL_Pos (5UL) /*!< USB_RFWL (Bit 5) */ +#define USB_USB_RXC2_REG_USB_RFWL_Msk (0x60UL) /*!< USB_RFWL (Bitfield-Mask: 0x03) */ +#define USB_USB_RXC2_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ +#define USB_USB_RXC2_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC2_REG_USB_IGN_SETUP_Pos (2UL) /*!< USB_IGN_SETUP (Bit 2) */ +#define USB_USB_RXC2_REG_USB_IGN_SETUP_Msk (0x4UL) /*!< USB_IGN_SETUP (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC2_REG_USB_RX_EN_Pos (0UL) /*!< USB_RX_EN (Bit 0) */ +#define USB_USB_RXC2_REG_USB_RX_EN_Msk (0x1UL) /*!< USB_RX_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_RXC3_REG ====================================================== */ +#define USB_USB_RXC3_REG_USB_RFWL_Pos (5UL) /*!< USB_RFWL (Bit 5) */ +#define USB_USB_RXC3_REG_USB_RFWL_Msk (0x60UL) /*!< USB_RFWL (Bitfield-Mask: 0x03) */ +#define USB_USB_RXC3_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ +#define USB_USB_RXC3_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC3_REG_USB_IGN_SETUP_Pos (2UL) /*!< USB_IGN_SETUP (Bit 2) */ +#define USB_USB_RXC3_REG_USB_IGN_SETUP_Msk (0x4UL) /*!< USB_IGN_SETUP (Bitfield-Mask: 0x01) */ +#define USB_USB_RXC3_REG_USB_RX_EN_Pos (0UL) /*!< USB_RX_EN (Bit 0) */ +#define USB_USB_RXC3_REG_USB_RX_EN_Msk (0x1UL) /*!< USB_RX_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_RXD0_REG ====================================================== */ +#define USB_USB_RXD0_REG_USB_RXFD_Pos (0UL) /*!< USB_RXFD (Bit 0) */ +#define USB_USB_RXD0_REG_USB_RXFD_Msk (0xffUL) /*!< USB_RXFD (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_RXD1_REG ====================================================== */ +#define USB_USB_RXD1_REG_USB_RXFD_Pos (0UL) /*!< USB_RXFD (Bit 0) */ +#define USB_USB_RXD1_REG_USB_RXFD_Msk (0xffUL) /*!< USB_RXFD (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_RXD2_REG ====================================================== */ +#define USB_USB_RXD2_REG_USB_RXFD_Pos (0UL) /*!< USB_RXFD (Bit 0) */ +#define USB_USB_RXD2_REG_USB_RXFD_Msk (0xffUL) /*!< USB_RXFD (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_RXD3_REG ====================================================== */ +#define USB_USB_RXD3_REG_USB_RXFD_Pos (0UL) /*!< USB_RXFD (Bit 0) */ +#define USB_USB_RXD3_REG_USB_RXFD_Msk (0xffUL) /*!< USB_RXFD (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_RXEV_REG ====================================================== */ +#define USB_USB_RXEV_REG_USB_RXOVRRN31_Pos (4UL) /*!< USB_RXOVRRN31 (Bit 4) */ +#define USB_USB_RXEV_REG_USB_RXOVRRN31_Msk (0x70UL) /*!< USB_RXOVRRN31 (Bitfield-Mask: 0x07) */ +#define USB_USB_RXEV_REG_USB_RXFIFO31_Pos (0UL) /*!< USB_RXFIFO31 (Bit 0) */ +#define USB_USB_RXEV_REG_USB_RXFIFO31_Msk (0x7UL) /*!< USB_RXFIFO31 (Bitfield-Mask: 0x07) */ +/* ===================================================== USB_RXMSK_REG ===================================================== */ +#define USB_USB_RXMSK_REG_USB_M_RXOVRRN31_Pos (4UL) /*!< USB_M_RXOVRRN31 (Bit 4) */ +#define USB_USB_RXMSK_REG_USB_M_RXOVRRN31_Msk (0x70UL) /*!< USB_M_RXOVRRN31 (Bitfield-Mask: 0x07) */ +#define USB_USB_RXMSK_REG_USB_M_RXFIFO31_Pos (0UL) /*!< USB_M_RXFIFO31 (Bit 0) */ +#define USB_USB_RXMSK_REG_USB_M_RXFIFO31_Msk (0x7UL) /*!< USB_M_RXFIFO31 (Bitfield-Mask: 0x07) */ +/* ===================================================== USB_RXS0_REG ====================================================== */ +#define USB_USB_RXS0_REG_USB_SETUP_Pos (6UL) /*!< USB_SETUP (Bit 6) */ +#define USB_USB_RXS0_REG_USB_SETUP_Msk (0x40UL) /*!< USB_SETUP (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS0_REG_USB_TOGGLE_RX0_Pos (5UL) /*!< USB_TOGGLE_RX0 (Bit 5) */ +#define USB_USB_RXS0_REG_USB_TOGGLE_RX0_Msk (0x20UL) /*!< USB_TOGGLE_RX0 (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS0_REG_USB_RX_LAST_Pos (4UL) /*!< USB_RX_LAST (Bit 4) */ +#define USB_USB_RXS0_REG_USB_RX_LAST_Msk (0x10UL) /*!< USB_RX_LAST (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS0_REG_USB_RCOUNT_Pos (0UL) /*!< USB_RCOUNT (Bit 0) */ +#define USB_USB_RXS0_REG_USB_RCOUNT_Msk (0xfUL) /*!< USB_RCOUNT (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_RXS1_REG ====================================================== */ +#define USB_USB_RXS1_REG_USB_RXCOUNT_Pos (8UL) /*!< USB_RXCOUNT (Bit 8) */ +#define USB_USB_RXS1_REG_USB_RXCOUNT_Msk (0x7f00UL) /*!< USB_RXCOUNT (Bitfield-Mask: 0x7f) */ +#define USB_USB_RXS1_REG_USB_RX_ERR_Pos (7UL) /*!< USB_RX_ERR (Bit 7) */ +#define USB_USB_RXS1_REG_USB_RX_ERR_Msk (0x80UL) /*!< USB_RX_ERR (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS1_REG_USB_SETUP_Pos (6UL) /*!< USB_SETUP (Bit 6) */ +#define USB_USB_RXS1_REG_USB_SETUP_Msk (0x40UL) /*!< USB_SETUP (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS1_REG_USB_TOGGLE_RX_Pos (5UL) /*!< USB_TOGGLE_RX (Bit 5) */ +#define USB_USB_RXS1_REG_USB_TOGGLE_RX_Msk (0x20UL) /*!< USB_TOGGLE_RX (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS1_REG_USB_RX_LAST_Pos (4UL) /*!< USB_RX_LAST (Bit 4) */ +#define USB_USB_RXS1_REG_USB_RX_LAST_Msk (0x10UL) /*!< USB_RX_LAST (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS1_REG_USB_RCOUNT_Pos (0UL) /*!< USB_RCOUNT (Bit 0) */ +#define USB_USB_RXS1_REG_USB_RCOUNT_Msk (0xfUL) /*!< USB_RCOUNT (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_RXS2_REG ====================================================== */ +#define USB_USB_RXS2_REG_USB_RXCOUNT_Pos (8UL) /*!< USB_RXCOUNT (Bit 8) */ +#define USB_USB_RXS2_REG_USB_RXCOUNT_Msk (0x7f00UL) /*!< USB_RXCOUNT (Bitfield-Mask: 0x7f) */ +#define USB_USB_RXS2_REG_USB_RX_ERR_Pos (7UL) /*!< USB_RX_ERR (Bit 7) */ +#define USB_USB_RXS2_REG_USB_RX_ERR_Msk (0x80UL) /*!< USB_RX_ERR (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS2_REG_USB_SETUP_Pos (6UL) /*!< USB_SETUP (Bit 6) */ +#define USB_USB_RXS2_REG_USB_SETUP_Msk (0x40UL) /*!< USB_SETUP (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS2_REG_USB_TOGGLE_RX_Pos (5UL) /*!< USB_TOGGLE_RX (Bit 5) */ +#define USB_USB_RXS2_REG_USB_TOGGLE_RX_Msk (0x20UL) /*!< USB_TOGGLE_RX (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS2_REG_USB_RX_LAST_Pos (4UL) /*!< USB_RX_LAST (Bit 4) */ +#define USB_USB_RXS2_REG_USB_RX_LAST_Msk (0x10UL) /*!< USB_RX_LAST (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS2_REG_USB_RCOUNT_Pos (0UL) /*!< USB_RCOUNT (Bit 0) */ +#define USB_USB_RXS2_REG_USB_RCOUNT_Msk (0xfUL) /*!< USB_RCOUNT (Bitfield-Mask: 0x0f) */ +/* ===================================================== USB_RXS3_REG ====================================================== */ +#define USB_USB_RXS3_REG_USB_RXCOUNT_Pos (8UL) /*!< USB_RXCOUNT (Bit 8) */ +#define USB_USB_RXS3_REG_USB_RXCOUNT_Msk (0x7f00UL) /*!< USB_RXCOUNT (Bitfield-Mask: 0x7f) */ +#define USB_USB_RXS3_REG_USB_RX_ERR_Pos (7UL) /*!< USB_RX_ERR (Bit 7) */ +#define USB_USB_RXS3_REG_USB_RX_ERR_Msk (0x80UL) /*!< USB_RX_ERR (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS3_REG_USB_SETUP_Pos (6UL) /*!< USB_SETUP (Bit 6) */ +#define USB_USB_RXS3_REG_USB_SETUP_Msk (0x40UL) /*!< USB_SETUP (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS3_REG_USB_TOGGLE_RX_Pos (5UL) /*!< USB_TOGGLE_RX (Bit 5) */ +#define USB_USB_RXS3_REG_USB_TOGGLE_RX_Msk (0x20UL) /*!< USB_TOGGLE_RX (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS3_REG_USB_RX_LAST_Pos (4UL) /*!< USB_RX_LAST (Bit 4) */ +#define USB_USB_RXS3_REG_USB_RX_LAST_Msk (0x10UL) /*!< USB_RX_LAST (Bitfield-Mask: 0x01) */ +#define USB_USB_RXS3_REG_USB_RCOUNT_Pos (0UL) /*!< USB_RCOUNT (Bit 0) */ +#define USB_USB_RXS3_REG_USB_RCOUNT_Msk (0xfUL) /*!< USB_RCOUNT (Bitfield-Mask: 0x0f) */ +/* ====================================================== USB_TCR_REG ====================================================== */ +#define USB_USB_TCR_REG_USB_VADJ_Pos (5UL) /*!< USB_VADJ (Bit 5) */ +#define USB_USB_TCR_REG_USB_VADJ_Msk (0xe0UL) /*!< USB_VADJ (Bitfield-Mask: 0x07) */ +#define USB_USB_TCR_REG_USB_CADJ_Pos (0UL) /*!< USB_CADJ (Bit 0) */ +#define USB_USB_TCR_REG_USB_CADJ_Msk (0x1fUL) /*!< USB_CADJ (Bitfield-Mask: 0x1f) */ +/* ===================================================== USB_TXC0_REG ====================================================== */ +#define USB_USB_TXC0_REG_USB_IGN_IN_Pos (4UL) /*!< USB_IGN_IN (Bit 4) */ +#define USB_USB_TXC0_REG_USB_IGN_IN_Msk (0x10UL) /*!< USB_IGN_IN (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC0_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ +#define USB_USB_TXC0_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC0_REG_USB_TOGGLE_TX0_Pos (2UL) /*!< USB_TOGGLE_TX0 (Bit 2) */ +#define USB_USB_TXC0_REG_USB_TOGGLE_TX0_Msk (0x4UL) /*!< USB_TOGGLE_TX0 (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC0_REG_USB_TX_EN_Pos (0UL) /*!< USB_TX_EN (Bit 0) */ +#define USB_USB_TXC0_REG_USB_TX_EN_Msk (0x1UL) /*!< USB_TX_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_TXC1_REG ====================================================== */ +#define USB_USB_TXC1_REG_USB_IGN_ISOMSK_Pos (7UL) /*!< USB_IGN_ISOMSK (Bit 7) */ +#define USB_USB_TXC1_REG_USB_IGN_ISOMSK_Msk (0x80UL) /*!< USB_IGN_ISOMSK (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC1_REG_USB_TFWL_Pos (5UL) /*!< USB_TFWL (Bit 5) */ +#define USB_USB_TXC1_REG_USB_TFWL_Msk (0x60UL) /*!< USB_TFWL (Bitfield-Mask: 0x03) */ +#define USB_USB_TXC1_REG_USB_RFF_Pos (4UL) /*!< USB_RFF (Bit 4) */ +#define USB_USB_TXC1_REG_USB_RFF_Msk (0x10UL) /*!< USB_RFF (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC1_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ +#define USB_USB_TXC1_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC1_REG_USB_TOGGLE_TX_Pos (2UL) /*!< USB_TOGGLE_TX (Bit 2) */ +#define USB_USB_TXC1_REG_USB_TOGGLE_TX_Msk (0x4UL) /*!< USB_TOGGLE_TX (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC1_REG_USB_LAST_Pos (1UL) /*!< USB_LAST (Bit 1) */ +#define USB_USB_TXC1_REG_USB_LAST_Msk (0x2UL) /*!< USB_LAST (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC1_REG_USB_TX_EN_Pos (0UL) /*!< USB_TX_EN (Bit 0) */ +#define USB_USB_TXC1_REG_USB_TX_EN_Msk (0x1UL) /*!< USB_TX_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_TXC2_REG ====================================================== */ +#define USB_USB_TXC2_REG_USB_IGN_ISOMSK_Pos (7UL) /*!< USB_IGN_ISOMSK (Bit 7) */ +#define USB_USB_TXC2_REG_USB_IGN_ISOMSK_Msk (0x80UL) /*!< USB_IGN_ISOMSK (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC2_REG_USB_TFWL_Pos (5UL) /*!< USB_TFWL (Bit 5) */ +#define USB_USB_TXC2_REG_USB_TFWL_Msk (0x60UL) /*!< USB_TFWL (Bitfield-Mask: 0x03) */ +#define USB_USB_TXC2_REG_USB_RFF_Pos (4UL) /*!< USB_RFF (Bit 4) */ +#define USB_USB_TXC2_REG_USB_RFF_Msk (0x10UL) /*!< USB_RFF (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC2_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ +#define USB_USB_TXC2_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC2_REG_USB_TOGGLE_TX_Pos (2UL) /*!< USB_TOGGLE_TX (Bit 2) */ +#define USB_USB_TXC2_REG_USB_TOGGLE_TX_Msk (0x4UL) /*!< USB_TOGGLE_TX (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC2_REG_USB_LAST_Pos (1UL) /*!< USB_LAST (Bit 1) */ +#define USB_USB_TXC2_REG_USB_LAST_Msk (0x2UL) /*!< USB_LAST (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC2_REG_USB_TX_EN_Pos (0UL) /*!< USB_TX_EN (Bit 0) */ +#define USB_USB_TXC2_REG_USB_TX_EN_Msk (0x1UL) /*!< USB_TX_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_TXC3_REG ====================================================== */ +#define USB_USB_TXC3_REG_USB_IGN_ISOMSK_Pos (7UL) /*!< USB_IGN_ISOMSK (Bit 7) */ +#define USB_USB_TXC3_REG_USB_IGN_ISOMSK_Msk (0x80UL) /*!< USB_IGN_ISOMSK (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC3_REG_USB_TFWL_Pos (5UL) /*!< USB_TFWL (Bit 5) */ +#define USB_USB_TXC3_REG_USB_TFWL_Msk (0x60UL) /*!< USB_TFWL (Bitfield-Mask: 0x03) */ +#define USB_USB_TXC3_REG_USB_RFF_Pos (4UL) /*!< USB_RFF (Bit 4) */ +#define USB_USB_TXC3_REG_USB_RFF_Msk (0x10UL) /*!< USB_RFF (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC3_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ +#define USB_USB_TXC3_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC3_REG_USB_TOGGLE_TX_Pos (2UL) /*!< USB_TOGGLE_TX (Bit 2) */ +#define USB_USB_TXC3_REG_USB_TOGGLE_TX_Msk (0x4UL) /*!< USB_TOGGLE_TX (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC3_REG_USB_LAST_Pos (1UL) /*!< USB_LAST (Bit 1) */ +#define USB_USB_TXC3_REG_USB_LAST_Msk (0x2UL) /*!< USB_LAST (Bitfield-Mask: 0x01) */ +#define USB_USB_TXC3_REG_USB_TX_EN_Pos (0UL) /*!< USB_TX_EN (Bit 0) */ +#define USB_USB_TXC3_REG_USB_TX_EN_Msk (0x1UL) /*!< USB_TX_EN (Bitfield-Mask: 0x01) */ +/* ===================================================== USB_TXD0_REG ====================================================== */ +#define USB_USB_TXD0_REG_USB_TXFD_Pos (0UL) /*!< USB_TXFD (Bit 0) */ +#define USB_USB_TXD0_REG_USB_TXFD_Msk (0xffUL) /*!< USB_TXFD (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_TXD1_REG ====================================================== */ +#define USB_USB_TXD1_REG_USB_TXFD_Pos (0UL) /*!< USB_TXFD (Bit 0) */ +#define USB_USB_TXD1_REG_USB_TXFD_Msk (0xffUL) /*!< USB_TXFD (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_TXD2_REG ====================================================== */ +#define USB_USB_TXD2_REG_USB_TXFD_Pos (0UL) /*!< USB_TXFD (Bit 0) */ +#define USB_USB_TXD2_REG_USB_TXFD_Msk (0xffUL) /*!< USB_TXFD (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_TXD3_REG ====================================================== */ +#define USB_USB_TXD3_REG_USB_TXFD_Pos (0UL) /*!< USB_TXFD (Bit 0) */ +#define USB_USB_TXD3_REG_USB_TXFD_Msk (0xffUL) /*!< USB_TXFD (Bitfield-Mask: 0xff) */ +/* ===================================================== USB_TXEV_REG ====================================================== */ +#define USB_USB_TXEV_REG_USB_TXUDRRN31_Pos (4UL) /*!< USB_TXUDRRN31 (Bit 4) */ +#define USB_USB_TXEV_REG_USB_TXUDRRN31_Msk (0x70UL) /*!< USB_TXUDRRN31 (Bitfield-Mask: 0x07) */ +#define USB_USB_TXEV_REG_USB_TXFIFO31_Pos (0UL) /*!< USB_TXFIFO31 (Bit 0) */ +#define USB_USB_TXEV_REG_USB_TXFIFO31_Msk (0x7UL) /*!< USB_TXFIFO31 (Bitfield-Mask: 0x07) */ +/* ===================================================== USB_TXMSK_REG ===================================================== */ +#define USB_USB_TXMSK_REG_USB_M_TXUDRRN31_Pos (4UL) /*!< USB_M_TXUDRRN31 (Bit 4) */ +#define USB_USB_TXMSK_REG_USB_M_TXUDRRN31_Msk (0x70UL) /*!< USB_M_TXUDRRN31 (Bitfield-Mask: 0x07) */ +#define USB_USB_TXMSK_REG_USB_M_TXFIFO31_Pos (0UL) /*!< USB_M_TXFIFO31 (Bit 0) */ +#define USB_USB_TXMSK_REG_USB_M_TXFIFO31_Msk (0x7UL) /*!< USB_M_TXFIFO31 (Bitfield-Mask: 0x07) */ +/* ===================================================== USB_TXS0_REG ====================================================== */ +#define USB_USB_TXS0_REG_USB_ACK_STAT_Pos (6UL) /*!< USB_ACK_STAT (Bit 6) */ +#define USB_USB_TXS0_REG_USB_ACK_STAT_Msk (0x40UL) /*!< USB_ACK_STAT (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS0_REG_USB_TX_DONE_Pos (5UL) /*!< USB_TX_DONE (Bit 5) */ +#define USB_USB_TXS0_REG_USB_TX_DONE_Msk (0x20UL) /*!< USB_TX_DONE (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS0_REG_USB_TCOUNT_Pos (0UL) /*!< USB_TCOUNT (Bit 0) */ +#define USB_USB_TXS0_REG_USB_TCOUNT_Msk (0x1fUL) /*!< USB_TCOUNT (Bitfield-Mask: 0x1f) */ +/* ===================================================== USB_TXS1_REG ====================================================== */ +#define USB_USB_TXS1_REG_USB_TX_URUN_Pos (7UL) /*!< USB_TX_URUN (Bit 7) */ +#define USB_USB_TXS1_REG_USB_TX_URUN_Msk (0x80UL) /*!< USB_TX_URUN (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS1_REG_USB_ACK_STAT_Pos (6UL) /*!< USB_ACK_STAT (Bit 6) */ +#define USB_USB_TXS1_REG_USB_ACK_STAT_Msk (0x40UL) /*!< USB_ACK_STAT (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS1_REG_USB_TX_DONE_Pos (5UL) /*!< USB_TX_DONE (Bit 5) */ +#define USB_USB_TXS1_REG_USB_TX_DONE_Msk (0x20UL) /*!< USB_TX_DONE (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS1_REG_USB_TCOUNT_Pos (0UL) /*!< USB_TCOUNT (Bit 0) */ +#define USB_USB_TXS1_REG_USB_TCOUNT_Msk (0x1fUL) /*!< USB_TCOUNT (Bitfield-Mask: 0x1f) */ +/* ===================================================== USB_TXS2_REG ====================================================== */ +#define USB_USB_TXS2_REG_USB_TX_URUN_Pos (7UL) /*!< USB_TX_URUN (Bit 7) */ +#define USB_USB_TXS2_REG_USB_TX_URUN_Msk (0x80UL) /*!< USB_TX_URUN (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS2_REG_USB_ACK_STAT_Pos (6UL) /*!< USB_ACK_STAT (Bit 6) */ +#define USB_USB_TXS2_REG_USB_ACK_STAT_Msk (0x40UL) /*!< USB_ACK_STAT (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS2_REG_USB_TX_DONE_Pos (5UL) /*!< USB_TX_DONE (Bit 5) */ +#define USB_USB_TXS2_REG_USB_TX_DONE_Msk (0x20UL) /*!< USB_TX_DONE (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS2_REG_USB_TCOUNT_Pos (0UL) /*!< USB_TCOUNT (Bit 0) */ +#define USB_USB_TXS2_REG_USB_TCOUNT_Msk (0x1fUL) /*!< USB_TCOUNT (Bitfield-Mask: 0x1f) */ +/* ===================================================== USB_TXS3_REG ====================================================== */ +#define USB_USB_TXS3_REG_USB_TX_URUN_Pos (7UL) /*!< USB_TX_URUN (Bit 7) */ +#define USB_USB_TXS3_REG_USB_TX_URUN_Msk (0x80UL) /*!< USB_TX_URUN (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS3_REG_USB_ACK_STAT_Pos (6UL) /*!< USB_ACK_STAT (Bit 6) */ +#define USB_USB_TXS3_REG_USB_ACK_STAT_Msk (0x40UL) /*!< USB_ACK_STAT (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS3_REG_USB_TX_DONE_Pos (5UL) /*!< USB_TX_DONE (Bit 5) */ +#define USB_USB_TXS3_REG_USB_TX_DONE_Msk (0x20UL) /*!< USB_TX_DONE (Bitfield-Mask: 0x01) */ +#define USB_USB_TXS3_REG_USB_TCOUNT_Pos (0UL) /*!< USB_TCOUNT (Bit 0) */ +#define USB_USB_TXS3_REG_USB_TCOUNT_Msk (0x1fUL) /*!< USB_TCOUNT (Bitfield-Mask: 0x1f) */ +/* ====================================================== USB_UTR_REG ====================================================== */ +#define USB_USB_UTR_REG_USB_DIAG_Pos (7UL) /*!< USB_DIAG (Bit 7) */ +#define USB_USB_UTR_REG_USB_DIAG_Msk (0x80UL) /*!< USB_DIAG (Bitfield-Mask: 0x01) */ +#define USB_USB_UTR_REG_USB_NCRC_Pos (6UL) /*!< USB_NCRC (Bit 6) */ +#define USB_USB_UTR_REG_USB_NCRC_Msk (0x40UL) /*!< USB_NCRC (Bitfield-Mask: 0x01) */ +#define USB_USB_UTR_REG_USB_SF_Pos (5UL) /*!< USB_SF (Bit 5) */ +#define USB_USB_UTR_REG_USB_SF_Msk (0x20UL) /*!< USB_SF (Bitfield-Mask: 0x01) */ +#define USB_USB_UTR_REG_USB_UTR_RES_Pos (0UL) /*!< USB_UTR_RES (Bit 0) */ +#define USB_USB_UTR_REG_USB_UTR_RES_Msk (0x1fUL) /*!< USB_UTR_RES (Bitfield-Mask: 0x1f) */ +/* ==================================================== USB_UX20CDR_REG ==================================================== */ +#define USB_USB_UX20CDR_REG_RPU_TEST7_Pos (7UL) /*!< RPU_TEST7 (Bit 7) */ +#define USB_USB_UX20CDR_REG_RPU_TEST7_Msk (0x80UL) /*!< RPU_TEST7 (Bitfield-Mask: 0x01) */ +#define USB_USB_UX20CDR_REG_RPU_TEST_SW2_Pos (6UL) /*!< RPU_TEST_SW2 (Bit 6) */ +#define USB_USB_UX20CDR_REG_RPU_TEST_SW2_Msk (0x40UL) /*!< RPU_TEST_SW2 (Bitfield-Mask: 0x01) */ +#define USB_USB_UX20CDR_REG_RPU_TEST_SW1_Pos (5UL) /*!< RPU_TEST_SW1 (Bit 5) */ +#define USB_USB_UX20CDR_REG_RPU_TEST_SW1_Msk (0x20UL) /*!< RPU_TEST_SW1 (Bitfield-Mask: 0x01) */ +#define USB_USB_UX20CDR_REG_RPU_TEST_EN_Pos (4UL) /*!< RPU_TEST_EN (Bit 4) */ +#define USB_USB_UX20CDR_REG_RPU_TEST_EN_Msk (0x10UL) /*!< RPU_TEST_EN (Bitfield-Mask: 0x01) */ +#define USB_USB_UX20CDR_REG_RPU_TEST_SW1DM_Pos (2UL) /*!< RPU_TEST_SW1DM (Bit 2) */ +#define USB_USB_UX20CDR_REG_RPU_TEST_SW1DM_Msk (0x4UL) /*!< RPU_TEST_SW1DM (Bitfield-Mask: 0x01) */ +#define USB_USB_UX20CDR_REG_RPU_RCDELAY_Pos (1UL) /*!< RPU_RCDELAY (Bit 1) */ +#define USB_USB_UX20CDR_REG_RPU_RCDELAY_Msk (0x2UL) /*!< RPU_RCDELAY (Bitfield-Mask: 0x01) */ +#define USB_USB_UX20CDR_REG_RPU_SSPROTEN_Pos (0UL) /*!< RPU_SSPROTEN (Bit 0) */ +#define USB_USB_UX20CDR_REG_RPU_SSPROTEN_Msk (0x1UL) /*!< RPU_SSPROTEN (Bitfield-Mask: 0x01) */ +/* ==================================================== USB_XCVDIAG_REG ==================================================== */ +#define USB_USB_XCVDIAG_REG_USB_VPIN_Pos (7UL) /*!< USB_VPIN (Bit 7) */ +#define USB_USB_XCVDIAG_REG_USB_VPIN_Msk (0x80UL) /*!< USB_VPIN (Bitfield-Mask: 0x01) */ +#define USB_USB_XCVDIAG_REG_USB_VMIN_Pos (6UL) /*!< USB_VMIN (Bit 6) */ +#define USB_USB_XCVDIAG_REG_USB_VMIN_Msk (0x40UL) /*!< USB_VMIN (Bitfield-Mask: 0x01) */ +#define USB_USB_XCVDIAG_REG_USB_RCV_Pos (5UL) /*!< USB_RCV (Bit 5) */ +#define USB_USB_XCVDIAG_REG_USB_RCV_Msk (0x20UL) /*!< USB_RCV (Bitfield-Mask: 0x01) */ +#define USB_USB_XCVDIAG_REG_USB_XCV_TXEN_Pos (3UL) /*!< USB_XCV_TXEN (Bit 3) */ +#define USB_USB_XCVDIAG_REG_USB_XCV_TXEN_Msk (0x8UL) /*!< USB_XCV_TXEN (Bitfield-Mask: 0x01) */ +#define USB_USB_XCVDIAG_REG_USB_XCV_TXn_Pos (2UL) /*!< USB_XCV_TXn (Bit 2) */ +#define USB_USB_XCVDIAG_REG_USB_XCV_TXn_Msk (0x4UL) /*!< USB_XCV_TXn (Bitfield-Mask: 0x01) */ +#define USB_USB_XCVDIAG_REG_USB_XCV_TXp_Pos (1UL) /*!< USB_XCV_TXp (Bit 1) */ +#define USB_USB_XCVDIAG_REG_USB_XCV_TXp_Msk (0x2UL) /*!< USB_XCV_TXp (Bitfield-Mask: 0x01) */ +#define USB_USB_XCVDIAG_REG_USB_XCV_TEST_Pos (0UL) /*!< USB_XCV_TEST (Bit 0) */ +#define USB_USB_XCVDIAG_REG_USB_XCV_TEST_Msk (0x1UL) /*!< USB_XCV_TEST (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ WAKEUP ================ */ +/* =========================================================================================================================== */ + +/* =================================================== WKUP_CLEAR_P0_REG =================================================== */ +#define WAKEUP_WKUP_CLEAR_P0_REG_WKUP_CLEAR_P0_Pos (0UL) /*!< WKUP_CLEAR_P0 (Bit 0) */ +#define WAKEUP_WKUP_CLEAR_P0_REG_WKUP_CLEAR_P0_Msk (0xffffffffUL) /*!< WKUP_CLEAR_P0 (Bitfield-Mask: 0xffffffff) */ +/* =================================================== WKUP_CLEAR_P1_REG =================================================== */ +#define WAKEUP_WKUP_CLEAR_P1_REG_WKUP_CLEAR_P1_Pos (0UL) /*!< WKUP_CLEAR_P1 (Bit 0) */ +#define WAKEUP_WKUP_CLEAR_P1_REG_WKUP_CLEAR_P1_Msk (0x7fffffUL) /*!< WKUP_CLEAR_P1 (Bitfield-Mask: 0x7fffff) */ +/* ===================================================== WKUP_CTRL_REG ===================================================== */ +#define WAKEUP_WKUP_CTRL_REG_WKUP_ENABLE_IRQ_Pos (7UL) /*!< WKUP_ENABLE_IRQ (Bit 7) */ +#define WAKEUP_WKUP_CTRL_REG_WKUP_ENABLE_IRQ_Msk (0x80UL) /*!< WKUP_ENABLE_IRQ (Bitfield-Mask: 0x01) */ +#define WAKEUP_WKUP_CTRL_REG_WKUP_SFT_KEYHIT_Pos (6UL) /*!< WKUP_SFT_KEYHIT (Bit 6) */ +#define WAKEUP_WKUP_CTRL_REG_WKUP_SFT_KEYHIT_Msk (0x40UL) /*!< WKUP_SFT_KEYHIT (Bitfield-Mask: 0x01) */ +#define WAKEUP_WKUP_CTRL_REG_WKUP_DEB_VALUE_Pos (0UL) /*!< WKUP_DEB_VALUE (Bit 0) */ +#define WAKEUP_WKUP_CTRL_REG_WKUP_DEB_VALUE_Msk (0x3fUL) /*!< WKUP_DEB_VALUE (Bitfield-Mask: 0x3f) */ +/* ==================================================== WKUP_POL_P0_REG ==================================================== */ +#define WAKEUP_WKUP_POL_P0_REG_WKUP_POL_P0_Pos (0UL) /*!< WKUP_POL_P0 (Bit 0) */ +#define WAKEUP_WKUP_POL_P0_REG_WKUP_POL_P0_Msk (0xffffffffUL) /*!< WKUP_POL_P0 (Bitfield-Mask: 0xffffffff) */ +/* ==================================================== WKUP_POL_P1_REG ==================================================== */ +#define WAKEUP_WKUP_POL_P1_REG_WKUP_POL_P1_Pos (0UL) /*!< WKUP_POL_P1 (Bit 0) */ +#define WAKEUP_WKUP_POL_P1_REG_WKUP_POL_P1_Msk (0x7fffffUL) /*!< WKUP_POL_P1 (Bitfield-Mask: 0x7fffff) */ +/* ================================================== WKUP_RESET_IRQ_REG =================================================== */ +#define WAKEUP_WKUP_RESET_IRQ_REG_WKUP_IRQ_RST_Pos (0UL) /*!< WKUP_IRQ_RST (Bit 0) */ +#define WAKEUP_WKUP_RESET_IRQ_REG_WKUP_IRQ_RST_Msk (0xffffUL) /*!< WKUP_IRQ_RST (Bitfield-Mask: 0xffff) */ +/* ================================================== WKUP_SELECT_P0_REG =================================================== */ +#define WAKEUP_WKUP_SELECT_P0_REG_WKUP_SELECT_P0_Pos (0UL) /*!< WKUP_SELECT_P0 (Bit 0) */ +#define WAKEUP_WKUP_SELECT_P0_REG_WKUP_SELECT_P0_Msk (0xffffffffUL) /*!< WKUP_SELECT_P0 (Bitfield-Mask: 0xffffffff) */ +/* ================================================== WKUP_SELECT_P1_REG =================================================== */ +#define WAKEUP_WKUP_SELECT_P1_REG_WKUP_SELECT_P1_Pos (0UL) /*!< WKUP_SELECT_P1 (Bit 0) */ +#define WAKEUP_WKUP_SELECT_P1_REG_WKUP_SELECT_P1_Msk (0x7fffffUL) /*!< WKUP_SELECT_P1 (Bitfield-Mask: 0x7fffff) */ +/* ================================================= WKUP_SEL_GPIO_P0_REG ================================================== */ +#define WAKEUP_WKUP_SEL_GPIO_P0_REG_WKUP_SEL_GPIO_P0_Pos (0UL) /*!< WKUP_SEL_GPIO_P0 (Bit 0) */ +#define WAKEUP_WKUP_SEL_GPIO_P0_REG_WKUP_SEL_GPIO_P0_Msk (0xffffffffUL) /*!< WKUP_SEL_GPIO_P0 (Bitfield-Mask: 0xffffffff) */ +/* ================================================= WKUP_SEL_GPIO_P1_REG ================================================== */ +#define WAKEUP_WKUP_SEL_GPIO_P1_REG_WKUP_SEL_GPIO_P1_Pos (0UL) /*!< WKUP_SEL_GPIO_P1 (Bit 0) */ +#define WAKEUP_WKUP_SEL_GPIO_P1_REG_WKUP_SEL_GPIO_P1_Msk (0x7fffffUL) /*!< WKUP_SEL_GPIO_P1 (Bitfield-Mask: 0x7fffff) */ +/* ================================================== WKUP_STATUS_P0_REG =================================================== */ +#define WAKEUP_WKUP_STATUS_P0_REG_WKUP_STAT_P0_Pos (0UL) /*!< WKUP_STAT_P0 (Bit 0) */ +#define WAKEUP_WKUP_STATUS_P0_REG_WKUP_STAT_P0_Msk (0xffffffffUL) /*!< WKUP_STAT_P0 (Bitfield-Mask: 0xffffffff) */ +/* ================================================== WKUP_STATUS_P1_REG =================================================== */ +#define WAKEUP_WKUP_STATUS_P1_REG_WKUP_STAT_P1_Pos (0UL) /*!< WKUP_STAT_P1 (Bit 0) */ +#define WAKEUP_WKUP_STATUS_P1_REG_WKUP_STAT_P1_Msk (0x7fffffUL) /*!< WKUP_STAT_P1 (Bitfield-Mask: 0x7fffff) */ + +/** @} */ /* End of group PosMask_peripherals */ + + +#ifdef __cplusplus +} +#endif + +#endif /* DA1469X_H */ + + +/** @} */ /* End of group DA1469x */ + +/** @} */ /* End of group PLA_BSP_REGISTERS */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_compiler.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_compiler.h new file mode 100644 index 0000000..fdb1a97 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_compiler.h @@ -0,0 +1,271 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_gcc.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_gcc.h new file mode 100644 index 0000000..47a4b59 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_gcc.h @@ -0,0 +1,2102 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.1.0 + * @date 20. December 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /* Copyright (c) 2019 Modified by Dialog Semiconductor */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] val Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] val Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_version.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_version.h new file mode 100644 index 0000000..660f612 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm0.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm0.h new file mode 100644 index 0000000..e2cf6b9 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm0.h @@ -0,0 +1,950 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /* Copyright (c) 2019 Modified by Dialog Semiconductor */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref __NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref __NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t vectors = 0x0U; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t vectors = 0x0U; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm33.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm33.h new file mode 100644 index 0000000..7249e13 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm33.h @@ -0,0 +1,2908 @@ +/**************************************************************************//** + * @file core_cm33.h + * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /* Copyright (c) 2019 Modified by Dialog Semiconductor */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM33_H_GENERIC +#define __CORE_CM33_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M33 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM33 definitions */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (33U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM33_H_DEPENDANT +#define __CORE_CM33_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM33_REV + #define __CM33_REV 0x0000U + #warning "__CM33_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M33 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref __NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with \ref __NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/mpu_armv8.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/mpu_armv8.h new file mode 100644 index 0000000..bc3b051 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/mpu_armv8.h @@ -0,0 +1,347 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU + * @version V5.1.0 + * @date 08. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2017-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /* Copyright (c) 2019 Modified by Dialog Semiconductor */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \param XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + ((BASE & MPU_RBAR_BASE_Msk) | \ + ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#if defined(MPU_RLAR_PXN_Pos) + +/** \brief Region Limit Address Register with PXN value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((PXN << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#endif + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_ARMCM0.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_ARMCM0.h new file mode 100644 index 0000000..7fe7e91 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_ARMCM0.h @@ -0,0 +1,55 @@ +/**************************************************************************//** + * @file system_ARMCM0.h + * @brief CMSIS Device System Header File for + * ARMCM0 Device + * @version V5.3.1 + * @date 09. July 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_ARMCM0_H +#define SYSTEM_ARMCM0_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + + +/** + \brief Setup the microcontroller system. + + Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + + +/** + \brief Update SystemCoreClock variable. + + Updates the SystemCoreClock with current core Clock retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_ARMCM0_H */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_DA1469x.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_DA1469x.h new file mode 100644 index 0000000..6c53ee9 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_DA1469x.h @@ -0,0 +1,72 @@ +/**************************************************************************//** + * @file system_DA1469x.h + * @brief CMSIS Device System Header File for DA1469x Device + * @version V5.3.1 + * @date 17. May 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* Copyright (c) 2017 Modified by Dialog Semiconductor */ + + +#ifndef SYSTEM_DA1469x_H +#define SYSTEM_DA1469x_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + + +/** + \brief Setup the microcontroller system. + + Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + + +/** + \brief Update SystemCoreClock variable. + Updates the SystemCoreClock with current core Clock retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +/** + * \brief Convert a CPU address to a physical address + * + * To calculate the physical address, the current remapping (SYS_CTRL_REG.REMAP_ADR0) + * is used. + * + * \param [in] addr address seen by CPU + * + * \return physical address (for DMA, AES/HASH etc.) -- can be same or different as addr + * + */ +extern uint32_t black_orca_phy_addr(uint32_t addr); + + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_DA1469x_H */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/da1469x.ld b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/da1469x.ld new file mode 100644 index 0000000..c91dea8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/da1469x.ld @@ -0,0 +1,228 @@ +/* Linker script for Dialog DA1469x devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .imghdr (NOLOAD): + { + . = . + _imghdr_size; + } > FLASH + + __text = .; + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + /* ISR vector shall have exactly 512 bytes */ + . = __isr_vector_start + 0x200; + __isr_vector_end = .; + + *(.text) + *(.text.*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + .intvect : + { + . = ALIGN(4); + __intvect_start__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .sleep_state (NOLOAD) : + { + . = ALIGN(4); + *(sleep_state) + } > RAM + + /* This section will be zeroed by RTT package init */ + .rtt (NOLOAD): + { + . = ALIGN(4); + *(.rtt) + . = ALIGN(4); + } > RAM + + __text_ram_addr = LOADADDR(.text_ram); + + .text_ram : + { + . = ALIGN(4); + __text_ram_start__ = .; + *(.text_ram*) + . = ALIGN(4); + __text_ram_end__ = .; + } > RAM AT > FLASH + + __etext = LOADADDR(.data); + + .data : + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + *(.preinit_array) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + *(SORT(.init_array.*)) + *(.init_array) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM AT > FLASH + + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .cmac (NOLOAD) : + { + . = ALIGN(0x400); + *(.libcmac.ram) + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + _ram_start = ORIGIN(RAM); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") + + /* Check that intvect is at the beginning of RAM */ + ASSERT(__intvect_start__ == ORIGIN(RAM), "intvect is not at beginning of RAM") +} + diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/hal/hal_gpio.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/hal/hal_gpio.h new file mode 100644 index 0000000..67fc3c1 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/hal/hal_gpio.h @@ -0,0 +1,184 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +/** + * @addtogroup HAL + * @{ + * @defgroup HALGpio HAL GPIO + * @{ + */ + +#ifndef H_HAL_GPIO_ +#define H_HAL_GPIO_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The "mode" of the gpio. The gpio is either an input, output, or it is + * "not connected" (the pin specified is not functioning as a gpio) + */ +enum hal_gpio_mode_e { + /** Not connected */ + HAL_GPIO_MODE_NC = -1, + /** Input */ + HAL_GPIO_MODE_IN = 0, + /** Output */ + HAL_GPIO_MODE_OUT = 1 +}; +typedef enum hal_gpio_mode_e hal_gpio_mode_t; + +/* + * The "pull" of the gpio. This is either an input or an output. + */ +enum hal_gpio_pull { + /** Pull-up/down not enabled */ + HAL_GPIO_PULL_NONE = 0, + /** Pull-up enabled */ + HAL_GPIO_PULL_UP = 1, + /** Pull-down enabled */ + HAL_GPIO_PULL_DOWN = 2 +}; +typedef enum hal_gpio_pull hal_gpio_pull_t; + +/* + * IRQ trigger type. + */ +enum hal_gpio_irq_trigger { + HAL_GPIO_TRIG_NONE = 0, + /** IRQ occurs on rising edge */ + HAL_GPIO_TRIG_RISING = 1, + /** IRQ occurs on falling edge */ + HAL_GPIO_TRIG_FALLING = 2, + /** IRQ occurs on either edge */ + HAL_GPIO_TRIG_BOTH = 3, + /** IRQ occurs when line is low */ + HAL_GPIO_TRIG_LOW = 4, + /** IRQ occurs when line is high */ + HAL_GPIO_TRIG_HIGH = 5 +}; +typedef enum hal_gpio_irq_trigger hal_gpio_irq_trig_t; + +/* Function proto for GPIO irq handler functions */ +typedef void (*hal_gpio_irq_handler_t)(void *arg); + +/** + * Initializes the specified pin as an input + * + * @param pin Pin number to set as input + * @param pull pull type + * + * @return int 0: no error; -1 otherwise. + */ +int hal_gpio_init_in(int pin, hal_gpio_pull_t pull); + +/** + * Initialize the specified pin as an output, setting the pin to the specified + * value. + * + * @param pin Pin number to set as output + * @param val Value to set pin + * + * @return int 0: no error; -1 otherwise. + */ +int hal_gpio_init_out(int pin, int val); + +/** + * Deinitialize the specified pin to revert the previous initialization + * + * @param pin Pin number to unset + * + * @return int 0: no error; -1 otherwise. + */ +int hal_gpio_deinit(int pin); + +/** + * Write a value (either high or low) to the specified pin. + * + * @param pin Pin to set + * @param val Value to set pin (0:low 1:high) + */ +void hal_gpio_write(int pin, int val); + +/** + * Reads the specified pin. + * + * @param pin Pin number to read + * + * @return int 0: low, 1: high + */ +int hal_gpio_read(int pin); + +/** + * Toggles the specified pin + * + * @param pin Pin number to toggle + * + * @return current gpio state int 0: low, 1: high + */ +int hal_gpio_toggle(int pin); + +/** + * Initialize a given pin to trigger a GPIO IRQ callback. + * + * @param pin The pin to trigger GPIO interrupt on + * @param handler The handler function to call + * @param arg The argument to provide to the IRQ handler + * @param trig The trigger mode (e.g. rising, falling) + * @param pull The mode of the pin (e.g. pullup, pulldown) + * + * @return 0 on success, non-zero error code on failure. + */ +int hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, + hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull); + +/** + * Release a pin from being configured to trigger IRQ on state change. + * + * @param pin The pin to release + */ +void hal_gpio_irq_release(int pin); + +/** + * Enable IRQs on the passed pin + * + * @param pin The pin to enable IRQs on + */ +void hal_gpio_irq_enable(int pin); + +/** + * Disable IRQs on the passed pin + * + * @param pin The pin to disable IRQs on + */ +void hal_gpio_irq_disable(int pin); + + +#ifdef __cplusplus +} +#endif + +#endif /* H_HAL_GPIO_ */ + +/** + * @} HALGpio + * @} HAL + */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h new file mode 100644 index 0000000..3c69774 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __MCU_DA1469X_CLOCK_H_ +#define __MCU_DA1469X_CLOCK_H_ + +#include +#include "mcu/da1469x_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialize XTAL32M + */ +void da1469x_clock_sys_xtal32m_init(void); + +/** + * Enable XTAL32M + */ +void da1469x_clock_sys_xtal32m_enable(void); + +/** + * Wait for XTAL32M to settle + */ +void da1469x_clock_sys_xtal32m_wait_to_settle(void); + +/** + * Switch sys_clk to XTAL32M + * + * Caller shall ensure that XTAL32M is already settled. + */ +void da1469x_clock_sys_xtal32m_switch(void); + +/** + * Switch sys_clk to XTAL32M + * + * Waits for XTAL32M to settle before switching. + */ +void da1469x_clock_sys_xtal32m_switch_safe(void); + +/** + * Disable RC32M + */ +void da1469x_clock_sys_rc32m_disable(void); + +/** + * Enable AMBA clock(s) + * + * @param mask + */ +static inline void +da1469x_clock_amba_enable(uint32_t mask) +{ + uint32_t primask; + + __HAL_DISABLE_INTERRUPTS(primask); + CRG_TOP->CLK_AMBA_REG |= mask; + __HAL_ENABLE_INTERRUPTS(primask); +} + +/** + * Disable AMBA clock(s) + * + * @param uint32_t mask + */ +static inline void +da1469x_clock_amba_disable(uint32_t mask) +{ + uint32_t primask; + + __HAL_DISABLE_INTERRUPTS(primask); + CRG_TOP->CLK_AMBA_REG &= ~mask; + __HAL_ENABLE_INTERRUPTS(primask); +} + +/** + * Enable PLL96 + */ +static inline void +da1469x_clock_sys_pll_enable(void) +{ + CRG_XTAL->PLL_SYS_CTRL1_REG |= CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Msk | + CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_Msk; +} + +/** + * Disable PLL96 + * + * If PLL was used as SYS_CLOCK switches to XTAL32M. + */ +void da1469x_clock_sys_pll_disable(void); + +/** + * Checks whether PLL96 is locked and can be use as system clock or USB clock + * + * @return 0 if PLL is off, non-0 it its running + */ +static inline int +da1469x_clock_is_pll_locked(void) +{ + return 0 != (CRG_XTAL->PLL_SYS_STATUS_REG & CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_Msk); +} + +/** + * Waits for PLL96 to lock. + */ +void da1469x_clock_pll_wait_to_lock(void); + +/** + * Switches system clock to PLL96 + * + * Caller shall ensure that PLL is already locked. + */ +void da1469x_clock_sys_pll_switch(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_DA1469X_CLOCK_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h new file mode 100644 index 0000000..28fa1aa --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __MCU_DA1469X_HAL_H_ +#define __MCU_DA1469X_HAL_H_ + +#include +#include "mcu/mcu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper functions to enable/disable interrupts. */ +#define __HAL_DISABLE_INTERRUPTS(x) \ + do { \ + x = __get_PRIMASK(); \ + __disable_irq(); \ + } while (0) + +#define __HAL_ENABLE_INTERRUPTS(x) \ + do { \ + if (!x) { \ + __enable_irq(); \ + } \ + } while (0) + +#define __HAL_ASSERT_CRITICAL() \ + do { \ + assert(__get_PRIMASK() & 1); \ + } while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_DA1469X_HAL_H_ */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/mcu.h b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/mcu.h new file mode 100644 index 0000000..1e67367 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/include/mcu/mcu.h @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __MCU_MCU_H_ +#define __MCU_MCU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "DA1469xAB.h" + +#define sec_text_ram_core __attribute__((section(".text_ram"))) __attribute__((noinline)) + +#define MCU_SYSVIEW_INTERRUPTS \ + "I#1=Reset,I#2=MNI,I#3=HardFault,I#4=MemoryMgmt,I#5=BusFault,I#6=UsageFault," \ + "I#7=SecureFault,I#11=SVCall,I#12=DebugMonitor,I#14=PendSV,I#15=SysTick," \ + "I#16=SENSOR_NODE,I#17=DMA,I#18=CHARGER_STATE,I#19=CHARGER_ERROR," \ + "I#20=CMAC2SYS,I#21=UART,I#22=UART2,I#23=UART3,I#24=I2C,I#25=I2C2,I#26=SPI," \ + "I#27=SPI2,I#28=PCM,I#29=SRC_IN,I#30=SRC_OUT,I#31=USB,I#32=TIMER," \ + "I#33=TIMER2,I#34=RTC,I#35=KEY_WKUP_GPIO,I#36=PDC,I#37=VBUS,I#38=MRM," \ + "I#39=MOTOR_CONTROLLER,I#40=TRNG,I#41=DCDC,I#42=XTAL32M_RDY,I#43=ADC," \ + "I#44=ADC2,I#45=CRYPTO,I#46=CAPTIMER1,I#47=RFDIAG,I#48=LCD_CONTROLLER," \ + "I#49=PLL_LOCK,I#50=TIMER3,I#51=TIMER4,I#52=LRA,I#53=RTC_EVENT," \ + "I#54=GPIO_P0,I#55=GPIO_P1" + +/** +* \brief GPIO function +* +*/ +typedef enum { + MCU_GPIO_FUNC_GPIO = 0, /**< GPIO */ + MCU_GPIO_FUNC_UART_RX = 1, /**< GPIO as UART RX */ + MCU_GPIO_FUNC_UART_TX = 2, /**< GPIO as UART TX */ + MCU_GPIO_FUNC_UART2_RX = 3, /**< GPIO as UART2 RX */ + MCU_GPIO_FUNC_UART2_TX = 4, /**< GPIO as UART2 TX */ + MCU_GPIO_FUNC_UART2_CTSN = 5, /**< GPIO as UART2 CTSN */ + MCU_GPIO_FUNC_UART2_RTSN = 6, /**< GPIO as UART2 RTSN */ + MCU_GPIO_FUNC_UART3_RX = 7, /**< GPIO as UART3 RX */ + MCU_GPIO_FUNC_UART3_TX = 8, /**< GPIO as UART3 TX */ + MCU_GPIO_FUNC_UART3_CTSN = 9, /**< GPIO as UART3 CTSN */ + MCU_GPIO_FUNC_UART3_RTSN = 10, /**< GPIO as UART3 RTSN */ + MCU_GPIO_FUNC_ISO_CLK = 11, /**< GPIO as ISO CLK */ + MCU_GPIO_FUNC_ISO_DATA = 12, /**< GPIO as ISO DATA */ + MCU_GPIO_FUNC_SPI_DI = 13, /**< GPIO as SPI DI */ + MCU_GPIO_FUNC_SPI_DO = 14, /**< GPIO as SPI DO */ + MCU_GPIO_FUNC_SPI_CLK = 15, /**< GPIO as SPI CLK */ + MCU_GPIO_FUNC_SPI_EN = 16, /**< GPIO as SPI EN */ + MCU_GPIO_FUNC_SPI2_DI = 17, /**< GPIO as SPI2 DI */ + MCU_GPIO_FUNC_SPI2_DO = 18, /**< GPIO as SPI2 DO */ + MCU_GPIO_FUNC_SPI2_CLK = 19, /**< GPIO as SPI2 CLK */ + MCU_GPIO_FUNC_SPI2_EN = 20, /**< GPIO as SPI2 EN */ + MCU_GPIO_FUNC_I2C_SCL = 21, /**< GPIO as I2C SCL */ + MCU_GPIO_FUNC_I2C_SDA = 22, /**< GPIO as I2C SDA */ + MCU_GPIO_FUNC_I2C2_SCL = 23, /**< GPIO as I2C2 SCL */ + MCU_GPIO_FUNC_I2C2_SDA = 24, /**< GPIO as I2C2 SDA */ + MCU_GPIO_FUNC_USB_SOF = 25, /**< GPIO as USB SOF */ + MCU_GPIO_FUNC_ADC = 26, /**< GPIO as ADC (dedicated pin) */ + MCU_GPIO_FUNC_USB = 27, /**< GPIO as USB */ + MCU_GPIO_FUNC_PCM_DI = 28, /**< GPIO as PCM DI */ + MCU_GPIO_FUNC_PCM_DO = 29, /**< GPIO as PCM DO */ + MCU_GPIO_FUNC_PCM_FSC = 30, /**< GPIO as PCM FSC */ + MCU_GPIO_FUNC_PCM_CLK = 31, /**< GPIO as PCM CLK */ + MCU_GPIO_FUNC_PDM_DATA = 32, /**< GPIO as PDM DATA */ + MCU_GPIO_FUNC_PDM_CLK = 33, /**< GPIO as PDM CLK */ + MCU_GPIO_FUNC_COEX_EXT_ACT = 34, /**< GPIO as COEX EXT ACT0 */ + MCU_GPIO_FUNC_COEX_SMART_ACT = 35, /**< GPIO as COEX SMART ACT */ + MCU_GPIO_FUNC_COEX_SMART_PRI = 36, /**< GPIO as COEX SMART PRI */ + MCU_GPIO_FUNC_PORT0_DCF = 37, /**< GPIO as PORT0 DCF */ + MCU_GPIO_FUNC_PORT1_DCF = 38, /**< GPIO as PORT1 DCF */ + MCU_GPIO_FUNC_PORT2_DCF = 39, /**< GPIO as PORT2 DCF */ + MCU_GPIO_FUNC_PORT3_DCF = 40, /**< GPIO as PORT3 DCF */ + MCU_GPIO_FUNC_PORT4_DCF = 41, /**< GPIO as PORT4 DCF */ + MCU_GPIO_FUNC_CLOCK = 42, /**< GPIO as CLOCK */ + MCU_GPIO_FUNC_PG = 43, /**< GPIO as PG */ + MCU_GPIO_FUNC_LCD = 44, /**< GPIO as LCD */ + MCU_GPIO_FUNC_LCD_SPI_DC = 45, /**< GPIO as LCD SPI DC */ + MCU_GPIO_FUNC_LCD_SPI_DO = 46, /**< GPIO as LCD SPI DO */ + MCU_GPIO_FUNC_LCD_SPI_CLK = 47, /**< GPIO as LCD SPI CLK */ + MCU_GPIO_FUNC_LCD_SPI_EN = 48, /**< GPIO as LCD SPI EN */ + MCU_GPIO_FUNC_TIM_PWM = 49, /**< GPIO as TIM PWM */ + MCU_GPIO_FUNC_TIM2_PWM = 50, /**< GPIO as TIM2 PWM */ + MCU_GPIO_FUNC_TIM_1SHOT = 51, /**< GPIO as TIM 1SHOT */ + MCU_GPIO_FUNC_TIM2_1SHOT = 52, /**< GPIO as TIM2 1SHOT */ + MCU_GPIO_FUNC_TIM3_PWM = 53, /**< GPIO as TIM3 PWM */ + MCU_GPIO_FUNC_TIM4_PWM = 54, /**< GPIO as TIM4 PWM */ + MCU_GPIO_FUNC_AGC_EXT = 55, /**< GPIO as AGC EXT */ + MCU_GPIO_FUNC_CMAC_DIAG0 = 56, /**< GPIO as CMAC DIAG0 */ + MCU_GPIO_FUNC_CMAC_DIAG1 = 57, /**< GPIO as CMAC DIAG1 */ + MCU_GPIO_FUNC_CMAC_DIAG2 = 58, /**< GPIO as CMAC DIAG2 */ + MCU_GPIO_FUNC_CMAC_DIAGX = 59, /**< GPIO as CMAC DIAGX */ + MCU_GPIO_FUNC_LAST, +} mcu_gpio_func; + +#define MCU_GPIO_MODE_INPUT 0x000 /**< GPIO as an input */ +#define MCU_GPIO_MODE_INPUT_PULLUP 0x100 /**< GPIO as an input with pull-up */ +#define MCU_GPIO_MODE_INPUT_PULLDOWN 0x200 /**< GPIO as an input with pull-down */ +#define MCU_GPIO_MODE_OUTPUT 0x300 /**< GPIO as an output */ +#define MCU_GPIO_MODE_OUTPUT_OPEN_DRAIN 0x700 /**< GPIO as an open-drain output */ + +#define MCU_GPIO_PORT0_PIN_COUNT 32 +#define MCU_GPIO_PORT0(pin) ((0 * 32) + (pin)) +#define MCU_GPIO_PORT1(pin) ((1 * 32) + (pin)) +#define MCU_DMA_CHAN_MAX 8 + +#define MCU_PIN_GPADC_SEL0 MCU_GPIO_PORT1(9) +#define MCU_PIN_GPADC_SEL1 MCU_GPIO_PORT0(25) +#define MCU_PIN_GPADC_SEL2 MCU_GPIO_PORT0(8) +#define MCU_PIN_GPADC_SEL3 MCU_GPIO_PORT0(9) +#define MCU_PIN_GPADC_SEL16 MCU_GPIO_PORT1(13) +#define MCU_PIN_GPADC_SEL17 MCU_GPIO_PORT1(12) +#define MCU_PIN_GPADC_SEL18 MCU_GPIO_PORT1(18) +#define MCU_PIN_GPADC_SEL19 MCU_GPIO_PORT1(19) +#define MCU_PIN_GPADC_DIFF0_P0 MCU_GPIO_PORT1(9) +#define MCU_PIN_GPADC_DIFF0_P1 MCU_GPIO_PORT0(25) +#define MCU_PIN_GPADC_DIFF1_P0 MCU_GPIO_PORT0(8) +#define MCU_PIN_GPADC_DIFF1_P1 MCU_GPIO_PORT0(9) + +#define MCU_PIN_SDADC0 MCU_GPIO_PORT1(9) +#define MCU_PIN_SDADC1 MCU_GPIO_PORT0(25) +#define MCU_PIN_SDADC2 MCU_GPIO_PORT0(8) +#define MCU_PIN_SDADC3 MCU_GPIO_PORT0(9) +#define MCU_PIN_SDADC4 MCU_GPIO_PORT1(14) +#define MCU_PIN_SDADC5 MCU_GPIO_PORT1(20) +#define MCU_PIN_SDADC6 MCU_GPIO_PORT1(21) +#define MCU_PIN_SDADC7 MCU_GPIO_PORT1(22) + +void mcu_gpio_set_pin_function(int pin, int mode, mcu_gpio_func func); +void mcu_gpio_enter_sleep(void); +void mcu_gpio_exit_sleep(void); + +#define MCU_MEM_QSPIF_M_END_REMAP_ADDRESS (0x800000) +#define MCU_MEM_QSPIF_M_START_ADDRESS (0x16000000) +#define MCU_MEM_QSPIF_M_END_ADDRESS (0x18000000) +#define MCU_MEM_SYSRAM_START_ADDRESS (0x20000000) +#define MCU_MEM_SYSRAM_END_ADDRESS (0x20080000) + +#define MCU_OTPM_BASE 0x30080000UL +#define MCU_OTPM_SIZE 4096 + +/* Largest group id seen on a DA14699 was 18 so far */ +#define MCU_TRIMV_GROUP_ID_MAX (18) + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_MCU_H_ */ + diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/da1469x_clock.c b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/da1469x_clock.c new file mode 100644 index 0000000..6b4f0e6 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/da1469x_clock.c @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include "syscfg/syscfg.h" +#include "mcu/da1469x_hal.h" +#include "mcu/da1469x_clock.h" + +static inline bool +da1469x_clock_is_xtal32m_settled(void) +{ + return ((*(uint32_t *)0x5001001c & 0xff00) == 0) && + ((*(uint32_t *)0x50010054 & 0x000f) != 0xb); +} + +void +da1469x_clock_sys_xtal32m_init(void) +{ + uint32_t reg; + int xtalrdy_cnt; + + /* Number of lp_clk cycles (~30.5us) */ + xtalrdy_cnt = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US) * 10 / 305; + + reg = CRG_XTAL->XTALRDY_CTRL_REG; + reg &= ~(CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Msk | + CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk); + reg |= xtalrdy_cnt; + CRG_XTAL->XTALRDY_CTRL_REG = reg; +} + +void +da1469x_clock_sys_xtal32m_enable(void) +{ + PDC->PDC_CTRL0_REG = (2 << PDC_PDC_CTRL0_REG_TRIG_SELECT_Pos) | + (15 << PDC_PDC_CTRL0_REG_TRIG_ID_Pos) | + (1 << PDC_PDC_CTRL0_REG_PDC_MASTER_Pos) | + (1 << PDC_PDC_CTRL0_REG_EN_XTAL_Pos); + + PDC->PDC_SET_PENDING_REG = 0; + PDC->PDC_ACKNOWLEDGE_REG = 0; +} + +void +da1469x_clock_sys_xtal32m_switch(void) +{ + if (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk) { + CRG_TOP->CLK_SWITCH2XTAL_REG = CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk; + } else { + CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk; + } + + while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Msk)); +} + +void +da1469x_clock_sys_xtal32m_wait_to_settle(void) +{ + uint32_t primask; + + __HAL_DISABLE_INTERRUPTS(primask); + + NVIC_ClearPendingIRQ(XTAL32M_RDY_IRQn); + + if (!da1469x_clock_is_xtal32m_settled()) { + NVIC_EnableIRQ(XTAL32M_RDY_IRQn); + while (!NVIC_GetPendingIRQ(XTAL32M_RDY_IRQn)) { + __WFI(); + } + NVIC_DisableIRQ(XTAL32M_RDY_IRQn); + } + + __HAL_ENABLE_INTERRUPTS(primask); +} + +void +da1469x_clock_sys_xtal32m_switch_safe(void) +{ + da1469x_clock_sys_xtal32m_wait_to_settle(); + + da1469x_clock_sys_xtal32m_switch(); +} + +void +da1469x_clock_sys_rc32m_disable(void) +{ + CRG_TOP->CLK_RC32M_REG &= ~CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk; +} + +void +da1469x_clock_lp_xtal32k_enable(void) +{ + CRG_TOP->CLK_XTAL32K_REG |= CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Msk; +} + +void +da1469x_clock_lp_xtal32k_switch(void) +{ + CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & + ~CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) | + (2 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); +} + +void +da1469x_clock_pll_disable(void) +{ + while (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk) { + CRG_TOP->CLK_SWITCH2XTAL_REG = CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk; + } + + CRG_XTAL->PLL_SYS_CTRL1_REG &= ~CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Msk; +} + +void +da1469x_clock_pll_wait_to_lock(void) +{ + uint32_t primask; + + __HAL_DISABLE_INTERRUPTS(primask); + + NVIC_ClearPendingIRQ(PLL_LOCK_IRQn); + + if (!da1469x_clock_is_pll_locked()) { + NVIC_EnableIRQ(PLL_LOCK_IRQn); + while (!NVIC_GetPendingIRQ(PLL_LOCK_IRQn)) { + __WFI(); + } + NVIC_DisableIRQ(PLL_LOCK_IRQn); + } + + __HAL_ENABLE_INTERRUPTS(primask); +} + +void +da1469x_clock_sys_pll_switch(void) +{ + /* CLK_SEL_Msk == 3 means PLL */ + CRG_TOP->CLK_CTRL_REG |= CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk; + + while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk)); +} diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_gpio.c b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_gpio.c new file mode 100644 index 0000000..e105cf2 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_gpio.c @@ -0,0 +1,478 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include "syscfg/syscfg.h" +#include "mcu/da1469x_hal.h" +#include +#include "hal/hal_gpio.h" + +/* GPIO interrupts */ +#define HAL_GPIO_MAX_IRQ MYNEWT_VAL(MCU_GPIO_MAX_IRQ) + +#define GPIO_REG(name) ((__IO uint32_t *)(GPIO_BASE + offsetof(GPIO_Type, name))) +#define WAKEUP_REG(name) ((__IO uint32_t *)(WAKEUP_BASE + offsetof(WAKEUP_Type, name))) +#define CRG_TOP_REG(name) ((__IO uint32_t *)(CRG_TOP_BASE + offsetof(CRG_TOP_Type, name))) + +#ifndef MCU_GPIO_PORT0_PIN_COUNT +#define MCU_GPIO_PORT0_PIN_COUNT 32 +#endif + +#if (MCU_GPIO_PORT0_PIN_COUNT) == 32 +#define GPIO_PORT(pin) (((unsigned)(pin)) >> 5U) +#define GPIO_PORT_PIN(pin) (((unsigned)(pin)) & 31U) +#else +#define GPIO_PORT(pin) (((unsigned)(pin)) < MCU_GPIO_PORT0_PIN_COUNT ? 0 : 1) +#define GPIO_PORT_PIN(pin) ((unsigned)(pin) < MCU_GPIO_PORT0_PIN_COUNT ? \ + (pin) : (pin) - MCU_GPIO_PORT0_PIN_COUNT) +#endif + +#define GPIO_PIN_BIT(pin) (1 << GPIO_PORT_PIN(pin)) + +#define GPIO_PIN_DATA_REG_ADDR(pin) (GPIO_REG(P0_DATA_REG) + GPIO_PORT(pin)) +#define GPIO_PIN_DATA_REG(pin) *GPIO_PIN_DATA_REG_ADDR(pin) +#define GPIO_PIN_SET_DATA_REG_ADDR(pin) (GPIO_REG(P0_SET_DATA_REG) + GPIO_PORT(pin)) +#define GPIO_PIN_SET_DATA_REG(pin) *GPIO_PIN_SET_DATA_REG_ADDR(pin) +#define GPIO_PIN_RESET_DATA_REG_ADDR(pin) (GPIO_REG(P0_RESET_DATA_REG) + GPIO_PORT(pin)) +#define GPIO_PIN_RESET_DATA_REG(pin) *GPIO_PIN_RESET_DATA_REG_ADDR(pin) +#define GPIO_PIN_MODE_REG_ADDR(pin) (GPIO_REG(P0_00_MODE_REG) + (pin)) +#define GPIO_PIN_MODE_REG(pin) *GPIO_PIN_MODE_REG_ADDR(pin) +#define GPIO_PIN_PADPWR_CTRL_REG_ADDR(pin) (GPIO_REG(P0_PADPWR_CTRL_REG) + GPIO_PORT(pin)) +#define GPIO_PIN_PADPWR_CTRL_REG(pin) *GPIO_PIN_PADPWR_CTRL_REG_ADDR(pin) +#define GPIO_PIN_UNLATCH_ADDR(pin) (CRG_TOP_REG(P0_SET_PAD_LATCH_REG) + GPIO_PORT(pin) * 3) +#define GPIO_PIN_LATCH_ADDR(pin) (CRG_TOP_REG(P0_RESET_PAD_LATCH_REG) + GPIO_PORT(pin) * 3) + +#define WKUP_CTRL_REG_ADDR (WAKEUP_REG(WKUP_CTRL_REG)) +#define WKUP_RESET_IRQ_REG_ADDR (WAKEUP_REG(WKUP_RESET_IRQ_REG)) +#define WKUP_SELECT_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_SELECT_P0_REG) + GPIO_PORT(pin)) +#define WKUP_SELECT_PX_REG(pin) *(WKUP_SELECT_PX_REG_ADDR(pin)) +#define WKUP_POL_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_POL_P0_REG) + GPIO_PORT(pin)) +#define WKUP_POL_PX_SET_FALLING(pin) do { *(WKUP_POL_PX_REG_ADDR(pin)) |= GPIO_PIN_BIT(pin); } while (0) +#define WKUP_POL_PX_SET_RISING(pin) do { *(WKUP_POL_PX_REG_ADDR(pin)) &= ~GPIO_PIN_BIT(pin); } while (0) +#define WKUP_STAT_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_STATUS_P0_REG) + GPIO_PORT(pin)) +#define WKUP_STAT(pin) ((*(WKUP_STAT_PX_REG_ADDR(pin)) >> GPIO_PORT_PIN(pin)) & 1) +#define WKUP_CLEAR_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_CLEAR_P0_REG) + GPIO_PORT(pin)) +#define WKUP_CLEAR_PX(pin) do { (*(WKUP_CLEAR_PX_REG_ADDR(pin)) = GPIO_PIN_BIT(pin)); } while (0) +#define WKUP_SEL_GPIO_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_SEL_GPIO_P0_REG) + GPIO_PORT(pin)) +#define WKUP_SEL_GPIO_PX_REG(pin) *(WKUP_SEL_GPIO_PX_REG_ADDR(pin)) + +/* Storage for GPIO callbacks. */ +struct hal_gpio_irq { + int pin; + hal_gpio_irq_handler_t func; + void *arg; +}; + +static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ]; + +#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 +static uint32_t g_mcu_gpio_latch_state[2]; +static uint8_t g_mcu_gpio_retained_num; +static struct da1469x_retreg g_mcu_gpio_retained[MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM)]; +#endif + +/* + * We assume that any latched pin has default configuration, i.e. was either + * not configured or was deinited. Any unlatched pin is considered to be used + * by someone. + * + * By default, all pins are assumed to have default configuration and are + * latched. This allows PD_COM to be disabled (if no other peripheral needs + * it) since we do not need GPIO mux to be active. + * + * Configuration of any pin shall be done as follows, with interrupts disabled: + * 1. call mcu_gpio_unlatch_prepare() to enable PD_COM if needed + * 2. configure pin + * 3. call mcu_gpio_unlatch() to actually unlatch pin + * + * Once pin is restored to default configuration it shall be latched again by + * calling mcu_gpio_latch(). + */ + +#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 +static void +mcu_gpio_retained_add_port(uint32_t latch_val, volatile uint32_t *base_reg) +{ + struct da1469x_retreg *retreg; + int pin; + + retreg = &g_mcu_gpio_retained[g_mcu_gpio_retained_num]; + + while (latch_val) { + assert(g_mcu_gpio_retained_num < MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM)); + + pin = __builtin_ctz(latch_val); + latch_val &= ~(1 << pin); + + da1469x_retreg_assign(retreg, &base_reg[pin]); + + g_mcu_gpio_retained_num++; + retreg++; + } +} +#endif + +static void +mcu_gpio_retained_refresh(void) +{ +#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 + g_mcu_gpio_retained_num = 0; + + mcu_gpio_retained_add_port(CRG_TOP->P0_PAD_LATCH_REG, &GPIO->P0_00_MODE_REG); + mcu_gpio_retained_add_port(CRG_TOP->P1_PAD_LATCH_REG, &GPIO->P1_00_MODE_REG); +#endif +} + +static inline void +mcu_gpio_unlatch_prepare(int pin) +{ + __HAL_ASSERT_CRITICAL(); + (void)pin; + + /* Acquire PD_COM if first pin will be unlatched */ +// if ((CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG) == 0) { +// da1469x_pd_acquire(MCU_PD_DOMAIN_COM); +// } +} + +static inline void +mcu_gpio_unlatch(int pin) +{ + __HAL_ASSERT_CRITICAL(); + + *GPIO_PIN_UNLATCH_ADDR(pin) = GPIO_PIN_BIT(pin); + mcu_gpio_retained_refresh(); +} + +static inline void +mcu_gpio_latch(int pin) +{ + (void)pin; +// uint32_t primask; +// uint32_t latch_pre; +// uint32_t latch_post; +// +// __HAL_DISABLE_INTERRUPTS(primask); +// +// latch_pre = CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG; +// +// *GPIO_PIN_LATCH_ADDR(pin) = GPIO_PIN_BIT(pin); +// mcu_gpio_retained_refresh(); +// +// latch_post = CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG; +// +// /* Release PD_COM if last pin was latched */ +// if (latch_pre && !latch_post) { +// da1469x_pd_release(MCU_PD_DOMAIN_COM); +// } +// +// __HAL_ENABLE_INTERRUPTS(primask); +} + +int +hal_gpio_init_in(int pin, hal_gpio_pull_t pull) +{ + volatile uint32_t *px_xx_mod_reg = GPIO_PIN_MODE_REG_ADDR(pin); + uint32_t regval; + uint32_t primask; + + switch (pull) { + case HAL_GPIO_PULL_UP: + regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT_PULLUP; + break; + case HAL_GPIO_PULL_DOWN: + regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT_PULLDOWN; + break; + case HAL_GPIO_PULL_NONE: + regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT; + break; + default: + return -1; + } + + __HAL_DISABLE_INTERRUPTS(primask); + + mcu_gpio_unlatch_prepare(pin); + + *px_xx_mod_reg = regval; + + mcu_gpio_unlatch(pin); + + __HAL_ENABLE_INTERRUPTS(primask); + + return 0; +} + +int +hal_gpio_init_out(int pin, int val) +{ + uint32_t primask; + + __HAL_DISABLE_INTERRUPTS(primask); + + mcu_gpio_unlatch_prepare(pin); + + GPIO_PIN_MODE_REG(pin) = MCU_GPIO_MODE_OUTPUT; + + if (val) { + GPIO_PIN_SET_DATA_REG(pin) = GPIO_PIN_BIT(pin); + } else { + GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin); + } + + mcu_gpio_unlatch(pin); + + __HAL_ENABLE_INTERRUPTS(primask); + + return 0; +} + +int +hal_gpio_deinit(int pin) +{ + /* Reset mode to default value and latch pin */ + GPIO_PIN_MODE_REG(pin) = 0x200; + GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin); + + mcu_gpio_latch(pin); + + return 0; +} + +void +hal_gpio_write(int pin, int val) +{ + if (val) { + GPIO_PIN_SET_DATA_REG(pin) = GPIO_PIN_BIT(pin); + } else { + GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin); + } +} + +int +hal_gpio_read(int pin) +{ + return (GPIO_PIN_DATA_REG(pin) >> GPIO_PORT_PIN(pin)) & 1; +} + +int +hal_gpio_toggle(int pin) +{ + int new_value = hal_gpio_read(pin) == 0; + + hal_gpio_write(pin, new_value); + + return new_value; +} + +static void +hal_gpio_irq_handler(void) +{ + struct hal_gpio_irq *irq; + uint32_t stat; + int i; + + *WKUP_RESET_IRQ_REG_ADDR = 1; + NVIC_ClearPendingIRQ(KEY_WKUP_GPIO_IRQn); + + for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { + irq = &hal_gpio_irqs[i]; + + /* Read latched status value from relevant GPIO port */ + stat = WKUP_STAT(irq->pin); + + if (irq->func && stat) { + irq->func(irq->arg); + } + + WKUP_CLEAR_PX(irq->pin); + } +} + +static void +hal_gpio_irq_setup(void) +{ + static uint8_t irq_setup; + int sr; + + if (!irq_setup) { + __HAL_DISABLE_INTERRUPTS(sr); + + irq_setup = 1; + + NVIC_ClearPendingIRQ(GPIO_P0_IRQn); + NVIC_ClearPendingIRQ(GPIO_P1_IRQn); + NVIC_SetVector(GPIO_P0_IRQn, (uint32_t)hal_gpio_irq_handler); + NVIC_SetVector(GPIO_P1_IRQn, (uint32_t)hal_gpio_irq_handler); + WAKEUP->WKUP_CTRL_REG = 0; + WAKEUP->WKUP_CLEAR_P0_REG = 0xFFFFFFFF; + WAKEUP->WKUP_CLEAR_P1_REG = 0x007FFFFF; + WAKEUP->WKUP_SELECT_P0_REG = 0; + WAKEUP->WKUP_SELECT_P1_REG = 0; + WAKEUP->WKUP_SEL_GPIO_P0_REG = 0; + WAKEUP->WKUP_SEL_GPIO_P1_REG = 0; + WAKEUP->WKUP_RESET_IRQ_REG = 0; + + CRG_TOP->CLK_TMR_REG |= CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Msk; + + __HAL_ENABLE_INTERRUPTS(sr); + NVIC_EnableIRQ(GPIO_P0_IRQn); + NVIC_EnableIRQ(GPIO_P1_IRQn); + } +} + +static int +hal_gpio_find_empty_slot(void) +{ + int i; + + for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { + if (hal_gpio_irqs[i].func == NULL) { + return i; + } + } + + return -1; +} + +int +hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, + hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull) +{ + int i; + + hal_gpio_irq_setup(); + + i = hal_gpio_find_empty_slot(); + /* If assert failed increase syscfg value MCU_GPIO_MAX_IRQ */ + assert(i >= 0); + if (i < 0) { + return -1; + } + + hal_gpio_init_in(pin, pull); + + switch (trig) { + case HAL_GPIO_TRIG_RISING: + WKUP_POL_PX_SET_RISING(pin); + break; + case HAL_GPIO_TRIG_FALLING: + WKUP_POL_PX_SET_FALLING(pin); + break; + case HAL_GPIO_TRIG_BOTH: + /* Not supported */ + default: + return -1; + } + + hal_gpio_irqs[i].pin = pin; + hal_gpio_irqs[i].func = handler; + hal_gpio_irqs[i].arg = arg; + + return 0; +} + +void +hal_gpio_irq_release(int pin) +{ + int i; + + hal_gpio_irq_disable(pin); + + for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { + if (hal_gpio_irqs[i].pin == pin && hal_gpio_irqs[i].func) { + hal_gpio_irqs[i].pin = -1; + hal_gpio_irqs[i].arg = NULL; + hal_gpio_irqs[i].func = NULL; + } + } +} + +void +hal_gpio_irq_enable(int pin) +{ + WKUP_SEL_GPIO_PX_REG(pin) |= GPIO_PIN_BIT(pin); +} + +void +hal_gpio_irq_disable(int pin) +{ + WKUP_SEL_GPIO_PX_REG(pin) &= ~GPIO_PIN_BIT(pin); + WKUP_CLEAR_PX(pin); +} + +void +mcu_gpio_set_pin_function(int pin, int mode, mcu_gpio_func func) +{ + uint32_t primask; + + __HAL_DISABLE_INTERRUPTS(primask); + + mcu_gpio_unlatch_prepare(pin); + + GPIO_PIN_MODE_REG(pin) = (func & GPIO_P0_00_MODE_REG_PID_Msk) | + (mode & (GPIO_P0_00_MODE_REG_PUPD_Msk | GPIO_P0_00_MODE_REG_PPOD_Msk)); + + mcu_gpio_unlatch(pin); + + __HAL_ENABLE_INTERRUPTS(primask); +} + +void +mcu_gpio_enter_sleep(void) +{ +#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 + if (g_mcu_gpio_retained_num == 0) { + return; + } + + g_mcu_gpio_latch_state[0] = CRG_TOP->P0_PAD_LATCH_REG; + g_mcu_gpio_latch_state[1] = CRG_TOP->P1_PAD_LATCH_REG; + + da1469x_retreg_update(g_mcu_gpio_retained, g_mcu_gpio_retained_num); + + CRG_TOP->P0_RESET_PAD_LATCH_REG = CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Msk; + CRG_TOP->P1_RESET_PAD_LATCH_REG = CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Msk; + + da1469x_pd_release(MCU_PD_DOMAIN_COM); +#endif +} + +void +mcu_gpio_exit_sleep(void) +{ +#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 + if (g_mcu_gpio_retained_num == 0) { + return; + } + + da1469x_pd_acquire(MCU_PD_DOMAIN_COM); + + da1469x_retreg_restore(g_mcu_gpio_retained, g_mcu_gpio_retained_num); + + /* Set pins states to their latched values */ + GPIO->P0_DATA_REG = GPIO->P0_DATA_REG; + GPIO->P1_DATA_REG = GPIO->P1_DATA_REG; + + CRG_TOP->P0_PAD_LATCH_REG = g_mcu_gpio_latch_state[0]; + CRG_TOP->P1_PAD_LATCH_REG = g_mcu_gpio_latch_state[1]; +#endif +} diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_system.c b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_system.c new file mode 100644 index 0000000..2841979 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_system.c @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include "syscfg/syscfg.h" +#include "mcu/da1469x_clock.h" +#include "mcu/da1469x_lpclk.h" +#include "mcu/da1469x_pd.h" +#include "mcu/da1469x_pdc.h" +#include "mcu/da1469x_prail.h" +#include "hal/hal_system.h" +#include "os/os_cputime.h" + +#if !MYNEWT_VAL(BOOT_LOADER) +static enum hal_reset_reason g_hal_reset_reason; +#endif + +void +hal_system_init(void) +{ +#if MYNEWT_VAL(MCU_DCDC_ENABLE) + da1469x_prail_dcdc_enable(); +#endif + + /* + * RESET_STAT_REG has to be cleared to allow HW set bits during next reset + * so we should read it now and keep result for application to check at any + * time. This does not happen for bootloader since reading reset reason in + * bootloader would prevent application from reading it. + */ + +#if !MYNEWT_VAL(BOOT_LOADER) + uint32_t reg; + + reg = CRG_TOP->RESET_STAT_REG; + CRG_TOP->RESET_STAT_REG = 0; + + if (reg & CRG_TOP_RESET_STAT_REG_PORESET_STAT_Msk) { + g_hal_reset_reason = HAL_RESET_POR; + } else if (reg & CRG_TOP_RESET_STAT_REG_WDOGRESET_STAT_Msk) { + g_hal_reset_reason = HAL_RESET_WATCHDOG; + } else if (reg & CRG_TOP_RESET_STAT_REG_SWRESET_STAT_Msk) { + g_hal_reset_reason = HAL_RESET_SOFT; + } else if (reg & CRG_TOP_RESET_STAT_REG_HWRESET_STAT_Msk) { + g_hal_reset_reason = HAL_RESET_PIN; + } else { + g_hal_reset_reason = 0; + } +#endif +} + +void +hal_system_reset(void) +{ + +#if MYNEWT_VAL(HAL_SYSTEM_RESET_CB) + hal_system_reset_cb(); +#endif + + while (1) { + HAL_DEBUG_BREAK(); + CRG_TOP->SYS_CTRL_REG = 0x20; + NVIC_SystemReset(); + } +} + +int +hal_debugger_connected(void) +{ + return CRG_TOP->SYS_STAT_REG & CRG_TOP_SYS_STAT_REG_DBG_IS_ACTIVE_Msk; +} + +void +hal_system_clock_start(void) +{ + /* Reset clock dividers to 0 */ + CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk | CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk); + + /* PD_TIM is already started in SystemInit */ + + da1469x_clock_sys_xtal32m_init(); + da1469x_clock_sys_xtal32m_enable(); +#if MYNEWT_VAL(MCU_PLL_ENABLE) + da1469x_clock_sys_pll_enable(); +#endif +#if MYNEWT_VAL_CHOICE(MCU_SYSCLK_SOURCE, PLL96) + da1469x_clock_pll_wait_to_lock(); + da1469x_clock_sys_pll_switch(); +#endif +#if MYNEWT_VAL_CHOICE(MCU_SYSCLK_SOURCE, XTAL32M) + /* Switch to XTAL32M and disable RC32M */ + da1469x_clock_sys_xtal32m_switch_safe(); +#endif + da1469x_clock_sys_rc32m_disable(); + +#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) + /* Switch to RCX and calibrate it */ + da1469x_clock_lp_rcx_enable(); + da1469x_clock_lp_rcx_switch(); + da1469x_clock_lp_rcx_calibrate(); + da1469x_lpclk_enabled(); +#else + /* + * We cannot switch lp_clk to XTAL32K here since it needs some time to + * settle, so we just disable RCX (we don't need it) and then we'll handle + * switch to XTAL32K from sysinit since we need os_cputime for this. + */ + da1469x_clock_lp_rcx_disable(); +#endif +} + +enum hal_reset_reason +hal_reset_cause(void) +{ +#if MYNEWT_VAL(BOOT_LOADER) + return 0; +#else + return g_hal_reset_reason; +#endif +} diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_system_start.c b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_system_start.c new file mode 100644 index 0000000..bd24650 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/hal_system_start.c @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include "mcu/mcu.h" +#include "mcu/da1469x_hal.h" +#include +#include +#if MCUBOOT_MYNEWT +#include "bootutil/bootutil.h" +#include "bootutil/image.h" +#include "bootutil/bootutil_log.h" +#include "mcu/da1469x_dma.h" +#include "mcu/da1469x_otp.h" +#endif + +#if MYNEWT_VAL(BOOT_CUSTOM_START) && MCUBOOT_MYNEWT +sec_text_ram_core +#endif +void __attribute__((naked)) +hal_system_start(void *img_start) +{ + uint32_t img_data_addr; + uint32_t *img_data; + + img_data_addr = MCU_MEM_QSPIF_M_START_ADDRESS + (uint32_t)img_start; + + assert(img_data_addr < MCU_MEM_QSPIF_M_END_ADDRESS); + + img_data = (uint32_t *)img_data_addr; + + asm volatile (".syntax unified \n" + /* 1st word is stack pointer */ + " msr msp, %0 \n" + /* 2nd word is a reset handler (image entry) */ + " bx %1 \n" + : /* no output */ + : "r" (img_data[0]), "r" (img_data[1])); +} + +void +hal_system_restart(void *img_start) +{ + uint32_t primask __attribute__((unused)); + int i; + + /* + * Disable interrupts, and leave them disabled. + * They get re-enabled when system starts coming back again. + */ + __HAL_DISABLE_INTERRUPTS(primask); + + for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) { + NVIC->ICER[i] = 0xffffffff; + } + + hal_system_start(img_start); +} + +#if MYNEWT_VAL(BOOT_CUSTOM_START) && MCUBOOT_MYNEWT +#define IMAGE_TLV_AES_NONCE 0x50 +#define IMAGE_TLV_SECRET_ID 0x60 + +sec_text_ram_core void +boot_custom_start(uintptr_t flash_base, struct boot_rsp *rsp) +{ + int rc; + struct image_tlv_iter it; + const struct flash_area *fap; + uint32_t off; + uint16_t len; + uint16_t type; + uint8_t buf[8]; + uint8_t key; + uint32_t nonce[2]; + bool has_aes_nonce; + bool has_secret_id; + DMA_Type *dma_regs = DMA; + uint32_t jump_offset = rsp->br_image_off + rsp->br_hdr->ih_hdr_size; + + BOOT_LOG_INF("Custom initialization"); + + /* skip to booting if we are running nonsecure mode */ + if (!(CRG_TOP->SECURE_BOOT_REG & 0x1)) { + hal_system_start((void *)(flash_base + jump_offset)); + } + + rc = flash_area_open(flash_area_id_from_image_slot(0), &fap); + assert(rc == 0); + + rc = bootutil_tlv_iter_begin(&it, rsp->br_hdr, fap, IMAGE_TLV_ANY, true); + assert(rc == 0); + + has_aes_nonce = has_secret_id = false; + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + assert(rc >= 0); + + if (rc > 0) { + break; + } + + if (type == IMAGE_TLV_AES_NONCE) { + assert(len == 8); + + rc = flash_area_read(fap, off, buf, len); + assert(rc == 0); + + nonce[0] = __builtin_bswap32(*(uint32_t *)buf); + nonce[1] = __builtin_bswap32(*(uint32_t *)(buf + 4)); + has_aes_nonce = true; + } else if (type == IMAGE_TLV_SECRET_ID) { + assert(len == 4); + + rc = flash_area_read(fap, off, buf, len); + assert(rc == 0); + + key = buf[0]; + has_secret_id = true; + } + } + + assert(has_aes_nonce && has_secret_id && key <= 7); + + /* enable OTP clock and set in read mode */ + da1469x_clock_amba_enable(CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk); + da1469x_otp_set_mode(OTPC_MODE_READ); + + /* disable decrypt on the fly and program start and end addresses */ + QSPIC->QSPIC_CTR_CTRL_REG = 0; + QSPIC->QSPIC_CTR_SADDR_REG = jump_offset; + QSPIC->QSPIC_CTR_EADDR_REG = QSPIC->QSPIC_CTR_SADDR_REG + + rsp->br_hdr->ih_img_size - 1; + + /* securely DMA hardware key from secret storage to QSPI decrypt engine */ + dma_regs->DMA_REQ_MUX_REG |= 0xf000; + dma_regs->DMA7_LEN_REG = 8; + dma_regs->DMA7_A_START_REG = MCU_OTPM_BASE + OTP_SEGMENT_QSPI_FW_KEYS + + (32 * key); + dma_regs->DMA7_B_START_REG = (uint32_t)&QSPIC->QSPIC_CTR_KEY_0_3_REG; + dma_regs->DMA7_CTRL_REG = DMA_DMA7_CTRL_REG_AINC_Msk | + DMA_DMA7_CTRL_REG_BINC_Msk | + (MCU_DMA_BUS_WIDTH_4B << DMA_DMA7_CTRL_REG_BW_Pos) | + DMA_DMA7_CTRL_REG_DMA_ON_Msk; + while (dma_regs->DMA7_IDX_REG != 8); + + /* program NONCE */ + QSPIC->QSPIC_CTR_NONCE_0_3_REG = nonce[0]; + QSPIC->QSPIC_CTR_NONCE_4_7_REG = nonce[1]; + + /* turn back on decrypt on the fly */ + QSPIC->QSPIC_CTR_CTRL_REG = 1; + + /* set OTP to standby and turn off clock */ + da1469x_otp_set_mode(OTPC_MODE_STBY); + da1469x_clock_amba_disable(CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk); + + hal_system_start((void *)(flash_base + jump_offset)); +} +#endif diff --git a/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/system_da1469x.c b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/system_da1469x.c new file mode 100644 index 0000000..538bac7 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/dialog/da1469x/src/system_da1469x.c @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "mcu/mcu.h" +#include + +extern uint8_t __StackLimit; + +uint32_t SystemCoreClock = 32000000; + +void +SystemInit(void) +{ + /* Enable FPU when using hard-float */ +#if (__FPU_USED == 1) + SCB->CPACR |= (3UL << 20) | (3UL << 22); + __DSB(); + __ISB(); +#endif + + /* Freez watchdog */ + GPREG->SET_FREEZE_REG |= GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk; + /* Initialize power domains (disable radio only) */ + CRG_TOP->PMU_CTRL_REG = CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Msk; + + CRG_TOP->P0_SET_PAD_LATCH_REG = CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Msk; + CRG_TOP->P1_SET_PAD_LATCH_REG = CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Msk; + + /* Reset clock dividers to 0 */ + CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk | CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk); + + /* PD_TIM is already started in SystemInit */ + + da1469x_clock_sys_xtal32m_init(); + da1469x_clock_sys_xtal32m_enable(); + da1469x_clock_sys_pll_enable(); + da1469x_clock_pll_wait_to_lock(); + /* Switch to XTAL32M and disable RC32M */ + da1469x_clock_sys_xtal32m_switch_safe(); + da1469x_clock_sys_rc32m_disable(); +} + +void _init(void) +{ +} diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble.h new file mode 100644 index 0000000..76a432b --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble.h @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_COMMON BLE SoftDevice Common + @{ + @defgroup ble_api Events, type definitions and API calls + @{ + + @brief Module independent events, type definitions and API calls for the BLE SoftDevice. + + */ + +#ifndef BLE_H__ +#define BLE_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_err.h" +#include "ble_gap.h" +#include "ble_l2cap.h" +#include "ble_gatt.h" +#include "ble_gattc.h" +#include "ble_gatts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief Common API SVC numbers. + */ +enum BLE_COMMON_SVCS +{ + SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ + SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ + SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific base UUID. */ + SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ + SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ + SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */ + SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */ + SD_BLE_OPT_SET, /**< Set a BLE option. */ + SD_BLE_OPT_GET, /**< Get a BLE option. */ + SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */ + SD_BLE_UUID_VS_REMOVE, /**< Remove a Vendor Specific base UUID. */ +}; + +/** + * @brief BLE Module Independent Event IDs. + */ +enum BLE_COMMON_EVTS +{ + BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE + 0, /**< User Memory request. @ref ble_evt_user_mem_request_t */ + BLE_EVT_USER_MEM_RELEASE = BLE_EVT_BASE + 1, /**< User Memory release. @ref ble_evt_user_mem_release_t */ +}; + +/**@brief BLE Connection Configuration IDs. + * + * IDs that uniquely identify a connection configuration. + */ +enum BLE_CONN_CFGS +{ + BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE + 0, /**< BLE GAP specific connection configuration. */ + BLE_CONN_CFG_GATTC = BLE_CONN_CFG_BASE + 1, /**< BLE GATTC specific connection configuration. */ + BLE_CONN_CFG_GATTS = BLE_CONN_CFG_BASE + 2, /**< BLE GATTS specific connection configuration. */ + BLE_CONN_CFG_GATT = BLE_CONN_CFG_BASE + 3, /**< BLE GATT specific connection configuration. */ + BLE_CONN_CFG_L2CAP = BLE_CONN_CFG_BASE + 4, /**< BLE L2CAP specific connection configuration. */ +}; + +/**@brief BLE Common Configuration IDs. + * + * IDs that uniquely identify a common configuration. + */ +enum BLE_COMMON_CFGS +{ + BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific base UUID configuration */ +}; + +/**@brief Common Option IDs. + * IDs that uniquely identify a common option. + */ +enum BLE_COMMON_OPTS +{ + BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE + 0, /**< PA and LNA options */ + BLE_COMMON_OPT_CONN_EVT_EXT = BLE_OPT_BASE + 1, /**< Extended connection events option */ + BLE_COMMON_OPT_EXTENDED_RC_CAL = BLE_OPT_BASE + 2, /**< Extended RC calibration option */ + BLE_COMMON_OPT_ADV_SCHED_CFG = BLE_OPT_BASE + 3, /**< Advertiser role scheduling configuration option */ +}; + +/** @} */ + +/** @addtogroup BLE_COMMON_DEFINES Defines + * @{ */ + +/** @brief Required pointer alignment for BLE Events. +*/ +#define BLE_EVT_PTR_ALIGNMENT 4 + +/** @brief Leaves the maximum of the two arguments. +*/ +#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a)) + +/** @brief Maximum possible length for BLE Events. + * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter. + * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead. +*/ +#define BLE_EVT_LEN_MAX(ATT_MTU) ( \ + offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU) - 1) / 4 * sizeof(ble_gattc_service_t) \ +) + +/** @defgroup ADV_SCHED_CFG Advertiser Role Scheduling Configuration + * @{ */ +#define ADV_SCHED_CFG_DEFAULT 0 /**< Default advertiser role scheduling configuration. */ +#define ADV_SCHED_CFG_IMPROVED 1 /**< Improved advertiser role scheduling configuration in which the housekeeping time is reduced. */ +/** @} */ + +/** @defgroup BLE_USER_MEM_TYPES User Memory Types + * @{ */ +#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */ +#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ +/** @} */ + +/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific base UUID counts + * @{ + */ +#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */ +#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */ +/** @} */ + +/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults. + * @{ + */ +#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */ + +/** @} */ + +/** @} */ + +/** @addtogroup BLE_COMMON_STRUCTURES Structures + * @{ */ + +/**@brief User Memory Block. */ +typedef struct +{ + uint8_t *p_mem; /**< Pointer to the start of the user memory block. */ + uint16_t len; /**< Length in bytes of the user memory block. */ +} ble_user_mem_block_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */ +typedef struct +{ + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ +} ble_evt_user_mem_request_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */ +typedef struct +{ + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ + ble_user_mem_block_t mem_block; /**< User memory block */ +} ble_evt_user_mem_release_t; + +/**@brief Event structure for events not associated with a specific function module. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ + union + { + ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ + ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ + } params; /**< Event parameter union. */ +} ble_common_evt_t; + +/**@brief BLE Event header. */ +typedef struct +{ + uint16_t evt_id; /**< Value from a BLE__EVT series. */ + uint16_t evt_len; /**< Length in octets including this header. */ +} ble_evt_hdr_t; + +/**@brief Common BLE Event type, wrapping the module specific event reports. */ +typedef struct +{ + ble_evt_hdr_t header; /**< Event header. */ + union + { + ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ + ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ + ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ + ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ + ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ + } evt; /**< Event union. */ +} ble_evt_t; + + +/** + * @brief Version Information. + */ +typedef struct +{ + uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */ + uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ + uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ +} ble_version_t; + +/** + * @brief Configuration parameters for the PA and LNA. + */ +typedef struct +{ + uint8_t enable :1; /**< Enable toggling for this amplifier */ + uint8_t active_high :1; /**< Set the pin to be active high */ + uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ +} ble_pa_lna_cfg_t; + +/** + * @brief PA & LNA GPIO toggle configuration + * + * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or + * a low noise amplifier. + * + * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided + * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences + * and must be avoided by the application. + */ +typedef struct +{ + ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ + ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ + + uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ + uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ + uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ +} ble_common_opt_pa_lna_t; + +/** + * @brief Configuration of extended BLE connection events. + * + * When enabled the SoftDevice will dynamically extend the connection event when possible. + * + * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length. + * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval, + * and if there are no conflicts with other BLE roles requesting radio time. + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */ +} ble_common_opt_conn_evt_ext_t; + +/** + * @brief Enable/disable extended RC calibration. + * + * If extended RC calibration is enabled and the internal RC oscillator (@ref NRF_CLOCK_LF_SRC_RC) is used as the SoftDevice + * LFCLK source, the SoftDevice as a peripheral will by default try to increase the receive window if two consecutive packets + * are not received. If it turns out that the packets were not received due to clock drift, the RC calibration is started. + * This calibration comes in addition to the periodic calibration that is configured by @ref sd_softdevice_enable(). When + * using only peripheral connections, the periodic calibration can therefore be configured with a much longer interval as the + * peripheral will be able to detect and adjust automatically to clock drift, and calibrate on demand. + * + * If extended RC calibration is disabled and the internal RC oscillator is used as the SoftDevice LFCLK source, the + * RC oscillator is calibrated periodically as configured by @ref sd_softdevice_enable(). + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable extended RC calibration, enabled by default. */ +} ble_common_opt_extended_rc_cal_t; + +/** + * @brief Configuration of BLE advertiser role scheduling. + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct +{ + uint8_t sched_cfg; /**< See @ref ADV_SCHED_CFG. */ +} ble_common_opt_adv_sched_cfg_t; + +/**@brief Option structure for common options. */ +typedef union +{ + ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ + ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */ + ble_common_opt_extended_rc_cal_t extended_rc_cal; /**< Parameters for enabling extended RC calibration. */ + ble_common_opt_adv_sched_cfg_t adv_sched_cfg; /**< Parameters for configuring advertiser role scheduling. */ +} ble_common_opt_t; + +/**@brief Common BLE Option type, wrapping the module specific options. */ +typedef union +{ + ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ + ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ +} ble_opt_t; + +/**@brief BLE connection configuration type, wrapping the module specific configurations, set with + * @ref sd_ble_cfg_set. + * + * @note Connection configurations don't have to be set. + * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections, + * the default connection configuration will be automatically added for the remaining connections. + * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in + * place of @ref ble_conn_cfg_t::conn_cfg_tag. + * + * @sa sd_ble_gap_adv_start() + * @sa sd_ble_gap_connect() + * + * @mscs + * @mmsc{@ref BLE_CONN_CFG} + * @endmscs + + */ +typedef struct +{ + uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the + @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() calls + to select this configuration when creating a connection. + Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */ + union { + ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */ + ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */ + ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */ + ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */ + ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */ + } params; /**< Connection configuration union. */ +} ble_conn_cfg_t; + +/** + * @brief Configuration of Vendor Specific base UUIDs, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured. + */ +typedef struct +{ + uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific base UUID bases to allocate memory for. + Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is + @ref BLE_UUID_VS_COUNT_MAX. */ +} ble_common_cfg_vs_uuid_t; + +/**@brief Common BLE Configuration type, wrapping the common configurations. */ +typedef union +{ + ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor Specific base UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */ +} ble_common_cfg_t; + +/**@brief BLE Configuration type, wrapping the module specific configurations. */ +typedef union +{ + ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */ + ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */ + ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */ + ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */ +} ble_cfg_t; + +/** @} */ + +/** @addtogroup BLE_COMMON_FUNCTIONS Functions + * @{ */ + +/**@brief Enable the BLE stack + * + * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the + * application RAM region (APP_RAM_BASE). On return, this will + * contain the minimum start address of the application RAM region + * required by the SoftDevice for this configuration. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located + * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between + * APP_RAM_BASE and the start of the call stack. + * + * @details This call initializes the BLE stack, no BLE related function other than @ref + * sd_ble_cfg_set can be called before this one. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NO_MEM One or more of the following is true: + * - The amount of memory assigned to the SoftDevice by *p_app_ram_base is not + * large enough to fit this configuration's memory requirement. Check *p_app_ram_base + * and set the start address of the application RAM region accordingly. + * - Dynamic part of the SoftDevice RAM region is larger then 64 kB which + * is currently not supported. + * @retval ::NRF_ERROR_RESOURCES The total number of L2CAP Channels configured using @ref sd_ble_cfg_set is too large. + */ +SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base)); + +/**@brief Add configurations for the BLE stack + * + * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref + * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS. + * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value. + * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE). + * See @ref sd_ble_enable for details about APP_RAM_BASE. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note If a configuration is set more than once, the last one set is the one that takes effect on + * @ref sd_ble_enable. + * + * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default + * configuration. + * + * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref + * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref + * sd_ble_enable). + * + * @note Error codes for the configurations are described in the configuration structs. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The configuration has been added successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not + * large enough to fit this configuration's memory requirement. + */ +SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base)); + +/**@brief Get an event from the pending events queue. + * + * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. + * This buffer must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT. + * The buffer should be interpreted as a @ref ble_evt_t struct. + * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. + * + * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that + * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. + * The application is free to choose whether to call this function from thread mode (main context) or directly from the + * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher + * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) + * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so + * could potentially leave events in the internal queue without the application being aware of this fact. + * + * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to + * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, + * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. + * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length + * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return: + * + * \code + * uint16_t len; + * errcode = sd_ble_evt_get(NULL, &len); + * \endcode + * + * @mscs + * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} + * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. + * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. + */ +SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); + + +/**@brief Add a Vendor Specific base UUID. + * + * @details This call enables the application to add a Vendor Specific base UUID to the BLE stack's table, for later + * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t + * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code + * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses + * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to + * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field + * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to + * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, + * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. + * + * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by + * the 16-bit uuid field in @ref ble_uuid_t. + * + * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in + * p_uuid_type along with an @ref NRF_SUCCESS error code. + * + * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific base UUID disregarding + * bytes 12 and 13. + * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. + * + * @retval ::NRF_SUCCESS Successfully added the Vendor Specific base UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. + * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. + */ +SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); + + +/**@brief Remove a Vendor Specific base UUID. + * + * @details This call removes a Vendor Specific base UUID that has been added with @ref sd_ble_uuid_vs_add. This function allows + * the application to reuse memory allocated for Vendor Specific base UUIDs. + * + * @note Currently this function can only be called with a p_uuid_type set to @ref BLE_UUID_TYPE_UNKNOWN or the last added UUID type. + * + * @param[in] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t::type corresponds to the UUID type that + * shall be removed. If the type is set to @ref BLE_UUID_TYPE_UNKNOWN, or the pointer is NULL, the last + * Vendor Specific base UUID will be removed. + * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponds to the UUID type that was + * removed. If function returns with a failure, it contains the last type that is in use by the ATT Server. + * + * @retval ::NRF_SUCCESS Successfully removed the Vendor Specific base UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_uuid_type is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM If p_uuid_type points to a non-valid UUID type. + * @retval ::NRF_ERROR_FORBIDDEN If the Vendor Specific base UUID is in use by the ATT Server. + */ + +SVCALL(SD_BLE_UUID_VS_REMOVE, uint32_t, sd_ble_uuid_vs_remove(uint8_t *p_uuid_type)); + + +/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. + * + * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared + * to the corresponding ones in each entry of the table of Vendor Specific base UUIDs populated with @ref sd_ble_uuid_vs_add + * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index + * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. + * + * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. + * + * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). + * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. + * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. + * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. + */ +SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); + + +/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). + * + * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. + * + * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. + * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). + * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. + * + * @retval ::NRF_SUCCESS Successfully encoded into the buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. + */ +SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); + + +/**@brief Get Version Information. + * + * @details This call allows the application to get the BLE stack version information. + * + * @param[out] p_version Pointer to a ble_version_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Version information stored successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). + */ +SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); + + +/**@brief Provide a user memory block. + * + * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending. + */ +SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); + +/**@brief Set a BLE option. + * + * @details This call allows the application to set the value of an option. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @endmscs + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. + * + * @retval ::NRF_SUCCESS Option set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + */ +SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); + + +/**@brief Get a BLE option. + * + * @details This call allows the application to retrieve the value of an option. + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Option retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. + * + */ +SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); + +/** @} */ +#ifdef __cplusplus +} +#endif +#endif /* BLE_H__ */ + +/** + @} + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_err.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_err.h new file mode 100644 index 0000000..1b4820d --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_err.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_COMMON + @{ + @addtogroup nrf_error + @{ + @ingroup BLE_COMMON + @} + + @defgroup ble_err General error codes + @{ + + @brief General error code definitions for the BLE API. + + @ingroup BLE_COMMON +*/ +#ifndef NRF_BLE_ERR_H__ +#define NRF_BLE_ERR_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* @defgroup BLE_ERRORS Error Codes + * @{ */ +#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ +#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ +#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ +#define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid advertising handle. */ +#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ +#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */ +/** @} */ + + +/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges + * @brief Assignment of subranges for module specific error codes. + * @note For specific error codes, see ble_.h or ble_error_.h. + * @{ */ +#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ +#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ +#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ +#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif + + +/** + @} + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gap.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gap.h new file mode 100644 index 0000000..c434fef --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gap.h @@ -0,0 +1,2696 @@ +/* + * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_GAP Generic Access Profile (GAP) + @{ + @brief Definitions and prototypes for the GAP interface. + */ + +#ifndef BLE_GAP_H__ +#define BLE_GAP_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GAP API SVC numbers. + */ +enum BLE_GAP_SVCS +{ + SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ + SD_BLE_GAP_ADDR_GET = BLE_GAP_SVC_BASE + 1, /**< Get own Bluetooth Address. */ + SD_BLE_GAP_WHITELIST_SET = BLE_GAP_SVC_BASE + 2, /**< Set active whitelist. */ + SD_BLE_GAP_DEVICE_IDENTITIES_SET = BLE_GAP_SVC_BASE + 3, /**< Set device identity list. */ + SD_BLE_GAP_PRIVACY_SET = BLE_GAP_SVC_BASE + 4, /**< Set Privacy settings*/ + SD_BLE_GAP_PRIVACY_GET = BLE_GAP_SVC_BASE + 5, /**< Get Privacy settings*/ + SD_BLE_GAP_ADV_SET_CONFIGURE = BLE_GAP_SVC_BASE + 6, /**< Configure an advertising set. */ + SD_BLE_GAP_ADV_START = BLE_GAP_SVC_BASE + 7, /**< Start Advertising. */ + SD_BLE_GAP_ADV_STOP = BLE_GAP_SVC_BASE + 8, /**< Stop Advertising. */ + SD_BLE_GAP_CONN_PARAM_UPDATE = BLE_GAP_SVC_BASE + 9, /**< Connection Parameter Update. */ + SD_BLE_GAP_DISCONNECT = BLE_GAP_SVC_BASE + 10, /**< Disconnect. */ + SD_BLE_GAP_TX_POWER_SET = BLE_GAP_SVC_BASE + 11, /**< Set TX Power. */ + SD_BLE_GAP_APPEARANCE_SET = BLE_GAP_SVC_BASE + 12, /**< Set Appearance. */ + SD_BLE_GAP_APPEARANCE_GET = BLE_GAP_SVC_BASE + 13, /**< Get Appearance. */ + SD_BLE_GAP_PPCP_SET = BLE_GAP_SVC_BASE + 14, /**< Set PPCP. */ + SD_BLE_GAP_PPCP_GET = BLE_GAP_SVC_BASE + 15, /**< Get PPCP. */ + SD_BLE_GAP_DEVICE_NAME_SET = BLE_GAP_SVC_BASE + 16, /**< Set Device Name. */ + SD_BLE_GAP_DEVICE_NAME_GET = BLE_GAP_SVC_BASE + 17, /**< Get Device Name. */ + SD_BLE_GAP_AUTHENTICATE = BLE_GAP_SVC_BASE + 18, /**< Initiate Pairing/Bonding. */ + SD_BLE_GAP_SEC_PARAMS_REPLY = BLE_GAP_SVC_BASE + 19, /**< Reply with Security Parameters. */ + SD_BLE_GAP_AUTH_KEY_REPLY = BLE_GAP_SVC_BASE + 20, /**< Reply with an authentication key. */ + SD_BLE_GAP_LESC_DHKEY_REPLY = BLE_GAP_SVC_BASE + 21, /**< Reply with an LE Secure Connections DHKey. */ + SD_BLE_GAP_KEYPRESS_NOTIFY = BLE_GAP_SVC_BASE + 22, /**< Notify of a keypress during an authentication procedure. */ + SD_BLE_GAP_LESC_OOB_DATA_GET = BLE_GAP_SVC_BASE + 23, /**< Get the local LE Secure Connections OOB data. */ + SD_BLE_GAP_LESC_OOB_DATA_SET = BLE_GAP_SVC_BASE + 24, /**< Set the remote LE Secure Connections OOB data. */ + SD_BLE_GAP_ENCRYPT = BLE_GAP_SVC_BASE + 25, /**< Initiate encryption procedure. */ + SD_BLE_GAP_SEC_INFO_REPLY = BLE_GAP_SVC_BASE + 26, /**< Reply with Security Information. */ + SD_BLE_GAP_CONN_SEC_GET = BLE_GAP_SVC_BASE + 27, /**< Obtain connection security level. */ + SD_BLE_GAP_RSSI_START = BLE_GAP_SVC_BASE + 28, /**< Start reporting of changes in RSSI. */ + SD_BLE_GAP_RSSI_STOP = BLE_GAP_SVC_BASE + 29, /**< Stop reporting of changes in RSSI. */ + SD_BLE_GAP_SCAN_START = BLE_GAP_SVC_BASE + 30, /**< Start Scanning. */ + SD_BLE_GAP_SCAN_STOP = BLE_GAP_SVC_BASE + 31, /**< Stop Scanning. */ + SD_BLE_GAP_CONNECT = BLE_GAP_SVC_BASE + 32, /**< Connect. */ + SD_BLE_GAP_CONNECT_CANCEL = BLE_GAP_SVC_BASE + 33, /**< Cancel ongoing connection procedure. */ + SD_BLE_GAP_RSSI_GET = BLE_GAP_SVC_BASE + 34, /**< Get the last RSSI sample. */ + SD_BLE_GAP_PHY_UPDATE = BLE_GAP_SVC_BASE + 35, /**< Initiate or respond to a PHY Update Procedure. */ + SD_BLE_GAP_DATA_LENGTH_UPDATE = BLE_GAP_SVC_BASE + 36, /**< Initiate or respond to a Data Length Update Procedure. */ + SD_BLE_GAP_QOS_CHANNEL_SURVEY_START = BLE_GAP_SVC_BASE + 37, /**< Start Quality of Service (QoS) channel survey module. */ + SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP = BLE_GAP_SVC_BASE + 38, /**< Stop Quality of Service (QoS) channel survey module. */ + SD_BLE_GAP_ADV_ADDR_GET = BLE_GAP_SVC_BASE + 39, /**< Get the Address used on air while Advertising. */ +}; + +/**@brief GAP Event IDs. + * IDs that uniquely identify an event coming from the stack to the application. + */ +enum BLE_GAP_EVTS +{ + BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connected to peer. \n See @ref ble_gap_evt_connected_t */ + BLE_GAP_EVT_DISCONNECTED = BLE_GAP_EVT_BASE + 1, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE = BLE_GAP_EVT_BASE + 2, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ + BLE_GAP_EVT_SEC_PARAMS_REQUEST = BLE_GAP_EVT_BASE + 3, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */ + BLE_GAP_EVT_SEC_INFO_REQUEST = BLE_GAP_EVT_BASE + 4, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */ + BLE_GAP_EVT_PASSKEY_DISPLAY = BLE_GAP_EVT_BASE + 5, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ + BLE_GAP_EVT_KEY_PRESSED = BLE_GAP_EVT_BASE + 6, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ + BLE_GAP_EVT_AUTH_KEY_REQUEST = BLE_GAP_EVT_BASE + 7, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */ + BLE_GAP_EVT_LESC_DHKEY_REQUEST = BLE_GAP_EVT_BASE + 8, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ + BLE_GAP_EVT_AUTH_STATUS = BLE_GAP_EVT_BASE + 9, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ + BLE_GAP_EVT_CONN_SEC_UPDATE = BLE_GAP_EVT_BASE + 10, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ + BLE_GAP_EVT_TIMEOUT = BLE_GAP_EVT_BASE + 11, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ + BLE_GAP_EVT_RSSI_CHANGED = BLE_GAP_EVT_BASE + 12, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ + BLE_GAP_EVT_ADV_REPORT = BLE_GAP_EVT_BASE + 13, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ + BLE_GAP_EVT_SEC_REQUEST = BLE_GAP_EVT_BASE + 14, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 15, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ + BLE_GAP_EVT_SCAN_REQ_REPORT = BLE_GAP_EVT_BASE + 16, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ + BLE_GAP_EVT_PHY_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 17, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n See @ref ble_gap_evt_phy_update_request_t. */ + BLE_GAP_EVT_PHY_UPDATE = BLE_GAP_EVT_BASE + 18, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 19, /**< Data Length Update Request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE = BLE_GAP_EVT_BASE + 20, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */ + BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT = BLE_GAP_EVT_BASE + 21, /**< Channel survey report. \n See @ref ble_gap_evt_qos_channel_survey_report_t. */ + BLE_GAP_EVT_ADV_SET_TERMINATED = BLE_GAP_EVT_BASE + 22, /**< Advertising set terminated. \n See @ref ble_gap_evt_adv_set_terminated_t. */ +}; + +/**@brief GAP Option IDs. + * IDs that uniquely identify a GAP option. + */ +enum BLE_GAP_OPTS +{ + BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ + BLE_GAP_OPT_LOCAL_CONN_LATENCY = BLE_GAP_OPT_BASE + 1, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ + BLE_GAP_OPT_PASSKEY = BLE_GAP_OPT_BASE + 2, /**< Set passkey. @ref ble_gap_opt_passkey_t */ + BLE_GAP_OPT_COMPAT_MODE_1 = BLE_GAP_OPT_BASE + 3, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */ + BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT = BLE_GAP_OPT_BASE + 4, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ + BLE_GAP_OPT_SLAVE_LATENCY_DISABLE = BLE_GAP_OPT_BASE + 5, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */ +}; + +/**@brief GAP Configuration IDs. + * + * IDs that uniquely identify a GAP configuration. + */ +enum BLE_GAP_CFGS +{ + BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */ + BLE_GAP_CFG_DEVICE_NAME = BLE_GAP_CFG_BASE + 1, /**< Device name configuration. */ +}; + +/**@brief GAP TX Power roles. + */ +enum BLE_GAP_TX_POWER_ROLES +{ + BLE_GAP_TX_POWER_ROLE_ADV = 1, /**< Advertiser role. */ + BLE_GAP_TX_POWER_ROLE_SCAN_INIT = 2, /**< Scanner and initiator role. */ + BLE_GAP_TX_POWER_ROLE_CONN = 3, /**< Connection role. */ +}; + +/** @} */ + +/**@addtogroup BLE_GAP_DEFINES Defines + * @{ */ + +/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP + * @{ */ +#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ +#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ +#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ +#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */ +/**@} */ + + +/**@defgroup BLE_GAP_ROLES GAP Roles + * @{ */ +#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ +#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ +#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ +/**@} */ + + +/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources + * @{ */ +#define BLE_GAP_TIMEOUT_SRC_SCAN 0x01 /**< Scanning timeout. */ +#define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */ +#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types + * @{ */ +#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/ +#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */ +#define BLE_GAP_ADDR_TYPE_ANONYMOUS 0x7F /**< An advertiser may advertise without its address. + This type of advertising is called anonymous. */ +/**@} */ + + +/**@brief The default interval in seconds at which a private address is refreshed. */ +#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */ +/**@brief The maximum interval in seconds at which a private address can be refreshed. */ +#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */ + + +/** @brief BLE address length. */ +#define BLE_GAP_ADDR_LEN (6) + +/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes + * @{ */ +#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ +#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ +#define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY 0x02 /**< Device will send and accept only private addresses for its own address, + and will not accept a peer using identity address as sender address when + the peer IRK is exchanged, non-zero and added to the identity list. */ +/**@} */ + +/** @brief Invalid power level. */ +#define BLE_GAP_POWER_LEVEL_INVALID 127 + +/** @brief Advertising set handle not set. */ +#define BLE_GAP_ADV_SET_HANDLE_NOT_SET (0xFF) + +/** @brief The default number of advertising sets. */ +#define BLE_GAP_ADV_SET_COUNT_DEFAULT (1) + +/** @brief The maximum number of advertising sets supported by this SoftDevice. */ +#define BLE_GAP_ADV_SET_COUNT_MAX (1) + +/**@defgroup BLE_GAP_ADV_SET_DATA_SIZES Advertising data sizes. + * @{ */ +#define BLE_GAP_ADV_SET_DATA_SIZE_MAX (31) /**< Maximum data length for an advertising set. + If more advertising data is required, use extended advertising instead. */ +#define BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED (255) /**< Maximum supported data length for an extended advertising set. */ + +#define BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED (238) /**< Maximum supported data length for an extended connectable advertising set. */ +/**@}. */ + +/** @brief Set ID not available in advertising report. */ +#define BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE 0xFF + +/**@defgroup BLE_GAP_EVT_ADV_SET_TERMINATED_REASON GAP Advertising Set Terminated reasons + * @{ */ +#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT 0x01 /**< Timeout value reached. */ +#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED 0x02 /**< @ref ble_gap_adv_params_t::max_adv_evts was reached. */ +/**@} */ + +/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format + * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm + * @{ */ +#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ +#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ +#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ +#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ +#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ +#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ +#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ +#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ +#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ +#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ +#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ +#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */ +#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */ +#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ +#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ +#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags + * @{ */ +#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min + * @{ */ +#define BLE_GAP_ADV_INTERVAL_MIN 0x000020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ +#define BLE_GAP_ADV_INTERVAL_MAX 0x004000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ + /**@} */ + + +/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min + * @{ */ +#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_INTERVAL_MAX 0xFFFF /**< Maximum Scan interval in 625 us units, i.e. 40,959.375 s. */ + /** @} */ + + +/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min + * @{ */ +#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_WINDOW_MAX 0xFFFF /**< Maximum Scan window in 625 us units, i.e. 40,959.375 s. */ + /** @} */ + + +/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min + * @{ */ +#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in 10 ms units, i.e 10 ms. */ +#define BLE_GAP_SCAN_TIMEOUT_UNLIMITED 0x0000 /**< Continue to scan forever. */ + /** @} */ + +/**@defgroup BLE_GAP_SCAN_BUFFER_SIZE GAP Minimum scanner buffer size + * + * Scan buffers are used for storing advertising data received from an advertiser. + * If ble_gap_scan_params_t::extended is set to 0, @ref BLE_GAP_SCAN_BUFFER_MIN is the minimum scan buffer length. + * else the minimum scan buffer size is @ref BLE_GAP_SCAN_BUFFER_EXTENDED_MIN. + * @{ */ +#define BLE_GAP_SCAN_BUFFER_MIN (31) /**< Minimum data length for an + advertising set. */ +#define BLE_GAP_SCAN_BUFFER_MAX (31) /**< Maximum data length for an + advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MIN (255) /**< Minimum data length for an + extended advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX (1650) /**< Maximum data length for an + extended advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED (255) /**< Maximum supported data length for + an extended advertising set. */ +/** @} */ + +/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types + * + * Advertising types defined in Bluetooth Core Specification v5.0, Vol 6, Part B, Section 4.4.2. + * + * The maximum advertising data length is defined by @ref BLE_GAP_ADV_SET_DATA_SIZE_MAX. + * The maximum supported data length for an extended advertiser is defined by + * @ref BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED + * Note that some of the advertising types do not support advertising data. Non-scannable types do not support + * scan response data. + * + * @{ */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED 0x01 /**< Connectable and scannable undirected + advertising events. */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE 0x02 /**< Connectable non-scannable directed advertising + events. Advertising interval is less that 3.75 ms. + Use this type for fast reconnections. + @note Advertising data is not supported. */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED 0x03 /**< Connectable non-scannable directed advertising + events. + @note Advertising data is not supported. */ +#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x04 /**< Non-connectable scannable undirected + advertising events. */ +#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x05 /**< Non-connectable non-scannable undirected + advertising events. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED 0x06 /**< Connectable non-scannable undirected advertising + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED 0x07 /**< Connectable non-scannable directed advertising + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x08 /**< Non-connectable scannable undirected advertising + events using extended advertising PDUs. + @note Only scan response data is supported. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_DIRECTED 0x09 /**< Non-connectable scannable directed advertising + events using extended advertising PDUs. + @note Only scan response data is supported. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x0A /**< Non-connectable non-scannable undirected advertising + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED 0x0B /**< Non-connectable non-scannable directed advertising + events using extended advertising PDUs. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies + * @{ */ +#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ +#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_DATA_STATUS GAP Advertising data status + * @{ */ +#define BLE_GAP_ADV_DATA_STATUS_COMPLETE 0x00 /**< All data in the advertising event have been received. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA 0x01 /**< More data to be received. + @note This value will only be used if + @ref ble_gap_scan_params_t::report_incomplete_evts and + @ref ble_gap_adv_report_type_t::extended_pdu are set to true. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED 0x02 /**< Incomplete data. Buffer size insufficient to receive more. + @note This value will only be used if + @ref ble_gap_adv_report_type_t::extended_pdu is set to true. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MISSED 0x03 /**< Failed to receive the remaining data. + @note This value will only be used if + @ref ble_gap_adv_report_type_t::extended_pdu is set to true. */ +/**@} */ + +/**@defgroup BLE_GAP_SCAN_FILTER_POLICIES GAP Scanner filter policies + * @{ */ +#define BLE_GAP_SCAN_FP_ACCEPT_ALL 0x00 /**< Accept all advertising packets except directed advertising packets + not addressed to this device. */ +#define BLE_GAP_SCAN_FP_WHITELIST 0x01 /**< Accept advertising packets from devices in the whitelist except directed + packets not addressed to this device. */ +#define BLE_GAP_SCAN_FP_ALL_NOT_RESOLVED_DIRECTED 0x02 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_ACCEPT_ALL. + In addition, accept directed advertising packets, where the advertiser's + address is a resolvable private address that cannot be resolved. */ +#define BLE_GAP_SCAN_FP_WHITELIST_NOT_RESOLVED_DIRECTED 0x03 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_WHITELIST. + In addition, accept directed advertising packets, where the advertiser's + address is a resolvable private address that cannot be resolved. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values in 10 ms units + * @{ */ +#define BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX (128) /**< Maximum high duty advertising time in 10 ms units. Corresponds to 1.28 s. */ +#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (18000) /**< Maximum advertising time in 10 ms units corresponding to TGAP(lim_adv_timeout) = 180 s in limited discoverable mode. */ +#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode. + For high duty cycle advertising, this corresponds to @ref BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX. */ +/**@} */ + + +/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes + * @{ */ +#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ +#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ +#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ +/**@} */ + + +/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities + * @{ */ +#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ +#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ +#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ +/**@} */ + + +/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types + * @{ */ +#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ +#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ +#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ +/**@} */ + + +/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types + * @{ */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ +/**@} */ + + +/**@defgroup BLE_GAP_SEC_STATUS GAP Security status + * @{ */ +#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ +#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ +#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */ +#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */ +#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ +#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ +#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ +#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ +#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ +#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ +#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ +#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ +#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ +#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ +#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ +#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ +#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ +/**@} */ + + +/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources + * @{ */ +#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ +#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ +/**@} */ + + +/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits + * @{ */ +#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ +#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ +/**@} */ + + +/**@defgroup BLE_GAP_DEVNAME GAP device name defines. + * @{ */ +#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */ +#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */ +#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */ +/**@} */ + + +/**@brief Disable RSSI events for connections */ +#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF + +/**@defgroup BLE_GAP_PHYS GAP PHYs + * @{ */ +#define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/ +#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */ +#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */ +#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */ +#define BLE_GAP_PHY_NOT_SET 0xFF /**< PHY is not configured. */ + +/**@brief Supported PHYs in connections, for scanning, and for advertising. */ +#define BLE_GAP_PHYS_SUPPORTED (BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_CODED) /**< All PHYs are supported. */ + +/**@} */ + +/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters + * + * See @ref ble_gap_conn_sec_mode_t. + * @{ */ +/**@brief Set sec_mode pointed to by ptr to have no access rights.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) +/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) +/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) +/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) +/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) +/**@} */ + + +/**@brief GAP Security Random Number Length. */ +#define BLE_GAP_SEC_RAND_LEN 8 + + +/**@brief GAP Security Key Length. */ +#define BLE_GAP_SEC_KEY_LEN 16 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ +#define BLE_GAP_LESC_P256_PK_LEN 64 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ +#define BLE_GAP_LESC_DHKEY_LEN 32 + + +/**@brief GAP Passkey Length. */ +#define BLE_GAP_PASSKEY_LEN 6 + + +/**@brief Maximum amount of addresses in the whitelist. */ +#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) + + +/**@brief Maximum amount of identities in the device identities list. */ +#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8) + + +/**@brief Default connection count for a configuration. */ +#define BLE_GAP_CONN_COUNT_DEFAULT (1) + + +/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines. + * @{ */ +#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */ +#define BLE_GAP_EVENT_LENGTH_CODED_PHY_MIN (6) /**< The shortest event length in 1.25 ms units supporting LE Coded PHY. */ +#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */ +/**@} */ + + +/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines. + * @{ */ +#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */ + +/**@} */ + +/**@brief Automatic data length parameter. */ +#define BLE_GAP_DATA_LENGTH_AUTO 0 + +/**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines. + * @{ */ +#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */ +#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */ +/**@} */ + +/**@defgroup GAP_SEC_MODES GAP Security Modes + * @{ */ +#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ +/**@} */ + +/**@brief The total number of channels in Bluetooth Low Energy. */ +#define BLE_GAP_CHANNEL_COUNT (40) + +/**@defgroup BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS Quality of Service (QoS) Channel survey interval defines + * @{ */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS (0) /**< Continuous channel survey. */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MIN_US (7500) /**< Minimum channel survey interval in microseconds (7.5 ms). */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MAX_US (4000000) /**< Maximum channel survey interval in microseconds (4 s). */ + /**@} */ + +/** @} */ + + +/**@addtogroup BLE_GAP_STRUCTURES Structures + * @{ */ + +/**@brief Advertising event properties. */ +typedef struct +{ + uint8_t type; /**< Advertising type. See @ref BLE_GAP_ADV_TYPES. */ + uint8_t anonymous : 1; /**< Omit advertiser's address from all PDUs. + @note Anonymous advertising is only available for + @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED and + @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED. */ + uint8_t include_tx_power : 1; /**< This feature is not supported on this SoftDevice. */ +} ble_gap_adv_properties_t; + + +/**@brief Advertising report type. */ +typedef struct +{ + uint16_t connectable : 1; /**< Connectable advertising event type. */ + uint16_t scannable : 1; /**< Scannable advertising event type. */ + uint16_t directed : 1; /**< Directed advertising event type. */ + uint16_t scan_response : 1; /**< Received a scan response. */ + uint16_t extended_pdu : 1; /**< Received an extended advertising set. */ + uint16_t status : 2; /**< Data status. See @ref BLE_GAP_ADV_DATA_STATUS. */ + uint16_t reserved : 9; /**< Reserved for future use. */ +} ble_gap_adv_report_type_t; + +/**@brief Advertising Auxiliary Pointer. */ +typedef struct +{ + uint16_t aux_offset; /**< Time offset from the beginning of advertising packet to the auxiliary packet in 100 us units. */ + uint8_t aux_phy; /**< Indicates the PHY on which the auxiliary advertising packet is sent. See @ref BLE_GAP_PHYS. */ +} ble_gap_aux_pointer_t; + +/**@brief Bluetooth Low Energy address. */ +typedef struct +{ + uint8_t addr_id_peer : 1; /**< Only valid for peer addresses. + This bit is set by the SoftDevice to indicate whether the address has been resolved from + a Resolvable Private Address (when the peer is using privacy). + If set to 1, @ref addr and @ref addr_type refer to the identity address of the resolved address. + + This bit is ignored when a variable of type @ref ble_gap_addr_t is used as input to API functions. */ + uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */ + uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. + @ref addr is not used if @ref addr_type is @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. */ +} ble_gap_addr_t; + + +/**@brief GAP connection parameters. + * + * @note When ble_conn_params_t is received in an event, both min_conn_interval and + * max_conn_interval will be equal to the connection interval set by the central. + * + * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: + * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval + * that corresponds to the following Bluetooth Spec requirement: + * The Supervision_Timeout in milliseconds shall be larger than + * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. + */ +typedef struct +{ + uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ +} ble_gap_conn_params_t; + + +/**@brief GAP connection security modes. + * + * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n + * Security Mode 1 Level 1: No security is needed (aka open link).\n + * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n + * Security Mode 1 Level 3: MITM protected encrypted link required.\n + * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n + * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n + * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n + */ +typedef struct +{ + uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ + uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ + +} ble_gap_conn_sec_mode_t; + + +/**@brief GAP connection security status.*/ +typedef struct +{ + ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ + uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ +} ble_gap_conn_sec_t; + +/**@brief Identity Resolving Key. */ +typedef struct +{ + uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ +} ble_gap_irk_t; + + +/**@brief Channel mask (40 bits). + * Every channel is represented with a bit positioned as per channel index defined in Bluetooth Core Specification v5.0, + * Vol 6, Part B, Section 1.4.1. The LSB contained in array element 0 represents channel index 0, and bit 39 represents + * channel index 39. If a bit is set to 1, the channel is not used. + */ +typedef uint8_t ble_gap_ch_mask_t[5]; + + +/**@brief GAP advertising parameters. */ +typedef struct +{ + ble_gap_adv_properties_t properties; /**< The properties of the advertising events. */ + ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer. + @note ble_gap_addr_t::addr_type cannot be + @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. + - When privacy is enabled and the local device uses + @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, + the device identity list is searched for a matching entry. If + the local IRK for that device identity is set, the local IRK + for that device will be used to generate the advertiser address + field in the advertising packet. + - If @ref ble_gap_adv_properties_t::type is directed, this must be + set to the targeted scanner or initiator. If the peer address is + in the device identity list, the peer IRK for that device will be + used to generate @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + target addresses used in the advertising event PDUs. */ + uint32_t interval; /**< Advertising interval in 625 us units. @sa BLE_GAP_ADV_INTERVALS. + @note If @ref ble_gap_adv_properties_t::type is set to + @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE + advertising, this parameter is ignored. */ + uint16_t duration; /**< Advertising duration in 10 ms units. When timeout is reached, + an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised. + @sa BLE_GAP_ADV_TIMEOUT_VALUES. + @note The SoftDevice will always complete at least one advertising + event even if the duration is set too low. */ + uint8_t max_adv_evts; /**< Maximum advertising events that shall be sent prior to disabling + advertising. Setting the value to 0 disables the limitation. When + the count of advertising events specified by this parameter + (if not 0) is reached, advertising will be automatically stopped + and an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised + @note If @ref ble_gap_adv_properties_t::type is set to + @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE, + this parameter is ignored. */ + ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels. + At least one of the primary channels, that is channel index 37-39, must be used. + Masking away secondary advertising channels is not supported. */ + uint8_t filter_policy; /**< Filter Policy. @sa BLE_GAP_ADV_FILTER_POLICIES. */ + uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising channel packets + are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS + will be used. + Valid values are @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_CODED. + @note The primary_phy shall indicate @ref BLE_GAP_PHY_1MBPS if + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising channel packets + are transmitted. + If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS will be used. + Valid values are + @ref BLE_GAP_PHY_1MBPS, @ref BLE_GAP_PHY_2MBPS, and @ref BLE_GAP_PHY_CODED. + If @ref ble_gap_adv_properties_t::type is an extended advertising type + and connectable, this is the PHY that will be used to establish a + connection and send AUX_ADV_IND packets on. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t set_id:4; /**< The advertising set identifier distinguishes this advertising set from other + advertising sets transmitted by this and other devices. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t scan_req_notification:1; /**< Enable scan request notifications for this advertising set. When a + scan request is received and the scanner address is allowed + by the filter policy, @ref BLE_GAP_EVT_SCAN_REQ_REPORT is raised. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is a non-scannable + advertising type. */ +} ble_gap_adv_params_t; + + +/**@brief GAP advertising data buffers. + * + * The application must provide the buffers for advertisement. The memory shall reside in application RAM, and + * shall never be modified while advertising. The data shall be kept alive until either: + * - @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised. + * - @ref BLE_GAP_EVT_CONNECTED is raised with @ref ble_gap_evt_connected_t::adv_handle set to the corresponding + * advertising handle. + * - Advertising is stopped. + * - Advertising data is changed. + * To update advertising data while advertising, provide new buffers to @ref sd_ble_gap_adv_set_configure. */ +typedef struct +{ + ble_data_t adv_data; /**< Advertising data. + @note + Advertising data can only be specified for a @ref ble_gap_adv_properties_t::type + that is allowed to contain advertising data. */ + ble_data_t scan_rsp_data; /**< Scan response data. + @note + Scan response data can only be specified for a @ref ble_gap_adv_properties_t::type + that is scannable. */ +} ble_gap_adv_data_t; + + +/**@brief GAP scanning parameters. */ +typedef struct +{ + uint8_t extended : 1; /**< If 1, the scanner will accept extended advertising packets. + If set to 0, the scanner will not receive advertising packets + on secondary advertising channels, and will not be able + to receive long advertising PDUs. */ + uint8_t report_incomplete_evts : 1; /**< If 1, events of type @ref ble_gap_evt_adv_report_t may have + @ref ble_gap_adv_report_type_t::status set to + @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. + This parameter is ignored when used with @ref sd_ble_gap_connect + @note This may be used to abort receiving more packets from an extended + advertising event, and is only available for extended + scanning, see @ref sd_ble_gap_scan_start. + @note This feature is not supported by this SoftDevice. */ + uint8_t active : 1; /**< If 1, perform active scanning by sending scan requests. + This parameter is ignored when used with @ref sd_ble_gap_connect. */ + uint8_t filter_policy : 2; /**< Scanning filter policy. @sa BLE_GAP_SCAN_FILTER_POLICIES. + @note Only @ref BLE_GAP_SCAN_FP_ACCEPT_ALL and + @ref BLE_GAP_SCAN_FP_WHITELIST are valid when used with + @ref sd_ble_gap_connect */ + uint8_t scan_phys; /**< Bitfield of PHYs to scan on. If set to @ref BLE_GAP_PHY_AUTO, + scan_phys will default to @ref BLE_GAP_PHY_1MBPS. + - If @ref ble_gap_scan_params_t::extended is set to 0, the only + supported PHY is @ref BLE_GAP_PHY_1MBPS. + - When used with @ref sd_ble_gap_scan_start, + the bitfield indicates the PHYs the scanner will use for scanning + on primary advertising channels. The scanner will accept + @ref BLE_GAP_PHYS_SUPPORTED as secondary advertising channel PHYs. + - When used with @ref sd_ble_gap_connect, the bitfield indicates + the PHYs the initiator will use for scanning on primary advertising + channels. The initiator will accept connections initiated on either + of the @ref BLE_GAP_PHYS_SUPPORTED PHYs. + If scan_phys contains @ref BLE_GAP_PHY_1MBPS and/or @ref BLE_GAP_PHY_2MBPS, + the primary scan PHY is @ref BLE_GAP_PHY_1MBPS. + If scan_phys also contains @ref BLE_GAP_PHY_CODED, the primary scan + PHY will also contain @ref BLE_GAP_PHY_CODED. If the only scan PHY is + @ref BLE_GAP_PHY_CODED, the primary scan PHY is + @ref BLE_GAP_PHY_CODED only. */ + uint16_t interval; /**< Scan interval in 625 us units. @sa BLE_GAP_SCAN_INTERVALS. */ + uint16_t window; /**< Scan window in 625 us units. @sa BLE_GAP_SCAN_WINDOW. + If scan_phys contains both @ref BLE_GAP_PHY_1MBPS and + @ref BLE_GAP_PHY_CODED interval shall be larger than or + equal to twice the scan window. */ + uint16_t timeout; /**< Scan timeout in 10 ms units. @sa BLE_GAP_SCAN_TIMEOUT. */ + ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels. + At least one of the primary channels, that is channel index 37-39, must be + set to 0. + Masking away secondary channels is not supported. */ +} ble_gap_scan_params_t; + + +/**@brief Privacy. + * + * The privacy feature provides a way for the device to avoid being tracked over a period of time. + * The privacy feature, when enabled, hides the local device identity and replaces it with a private address + * that is automatically refreshed at a specified interval. + * + * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). + * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key, + * and devices can establish connections without revealing their real identities. + * + * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY) + * are supported. + * + * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all + * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. + * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called. + */ +typedef struct +{ + uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ + uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ + uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ + ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. + When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. + By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ +} ble_gap_privacy_params_t; + + +/**@brief PHY preferences for TX and RX + * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each direction. + * @code + * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * @endcode + * + */ +typedef struct +{ + uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */ +} ble_gap_phys_t; + +/** @brief Keys that can be exchanged during a bonding procedure. */ +typedef struct +{ + uint8_t enc : 1; /**< Long Term Key and Master Identification. */ + uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ + uint8_t sign : 1; /**< Connection Signature Resolving Key. */ + uint8_t link : 1; /**< Derive the Link Key from the LTK. */ +} ble_gap_sec_kdist_t; + + +/**@brief GAP security parameters. */ +typedef struct +{ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ + uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ + uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ + uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ + uint8_t oob : 1; /**< The OOB data flag. + - In LE legacy pairing, this flag is set if a device has out of band authentication data. + The OOB method is used if both of the devices have out of band authentication data. + - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data. + The OOB method is used if at least one device has the peer device's OOB data available. */ + uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ + uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ + ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ + ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ +} ble_gap_sec_params_t; + + +/**@brief GAP Encryption Information. */ +typedef struct +{ + uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ + uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ + uint8_t auth : 1; /**< Authenticated Key. */ + uint8_t ltk_len : 6; /**< LTK length in octets. */ +} ble_gap_enc_info_t; + + +/**@brief GAP Master Identification. */ +typedef struct +{ + uint16_t ediv; /**< Encrypted Diversifier. */ + uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ +} ble_gap_master_id_t; + + +/**@brief GAP Signing Information. */ +typedef struct +{ + uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ +} ble_gap_sign_info_t; + + +/**@brief GAP LE Secure Connections P-256 Public Key. */ +typedef struct +{ + uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */ +} ble_gap_lesc_p256_pk_t; + + +/**@brief GAP LE Secure Connections DHKey. */ +typedef struct +{ + uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ +} ble_gap_lesc_dhkey_t; + + +/**@brief GAP LE Secure Connections OOB data. */ +typedef struct +{ + ble_gap_addr_t addr; /**< Bluetooth address of the device. */ + uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ + uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ +} ble_gap_lesc_oob_data_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ + uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ + uint8_t adv_handle; /**< Advertising handle in which advertising has ended. + This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */ + ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated + advertising set. The advertising buffers provided in + @ref sd_ble_gap_adv_set_configure are now released. + This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */ +} ble_gap_evt_connected_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */ +typedef struct +{ + uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ +} ble_gap_evt_disconnected_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */ +typedef struct +{ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */ +} ble_gap_evt_phy_update_request_t; + +/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */ +typedef struct +{ + uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/ + uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */ +} ble_gap_evt_phy_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */ +typedef struct +{ + ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ +} ble_gap_evt_sec_params_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ + ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ + uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ + uint8_t id_info : 1; /**< If 1, Identity Information required. */ + uint8_t sign_info : 1; /**< If 1, Signing Information required. */ +} ble_gap_evt_sec_info_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */ +typedef struct +{ + uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply + with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or + @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ +} ble_gap_evt_passkey_display_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ +typedef struct +{ + uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ +} ble_gap_evt_key_pressed_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ +typedef struct +{ + uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ +} ble_gap_evt_auth_key_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ +typedef struct +{ + ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory + inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ + uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */ +} ble_gap_evt_lesc_dhkey_request_t; + + +/**@brief Security levels supported. + * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. +*/ +typedef struct +{ + uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ + uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ + uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ + uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ +} ble_gap_sec_levels_t; + + +/**@brief Encryption Key. */ +typedef struct +{ + ble_gap_enc_info_t enc_info; /**< Encryption Information. */ + ble_gap_master_id_t master_id; /**< Master Identification. */ +} ble_gap_enc_key_t; + + +/**@brief Identity Key. */ +typedef struct +{ + ble_gap_irk_t id_info; /**< Identity Resolving Key. */ + ble_gap_addr_t id_addr_info; /**< Identity Address. */ +} ble_gap_id_key_t; + + +/**@brief Security Keys. */ +typedef struct +{ + ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ + ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ + ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined + in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ +} ble_gap_sec_keys_t; + + +/**@brief Security key set for both local and peer keys. */ +typedef struct +{ + ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */ + ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ +} ble_gap_sec_keyset_t; + + +/**@brief Data Length Update Procedure parameters. */ +typedef struct +{ + uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ + uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */ + uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ + uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */ +} ble_gap_data_length_params_t; + + +/**@brief Data Length Update Procedure local limitation. */ +typedef struct +{ + uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */ + uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */ + uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */ +} ble_gap_data_length_limitation_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */ +typedef struct +{ + uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ + uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ + uint8_t bonded : 1; /**< Procedure resulted in a bond. */ + uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */ + ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ + ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ + ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ + ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ +} ble_gap_evt_auth_status_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */ +typedef struct +{ + ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ +} ble_gap_evt_conn_sec_update_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ + union + { + ble_data_t adv_report_buffer; /**< If source is set to @ref BLE_GAP_TIMEOUT_SRC_SCAN, the released + scan buffer is contained in this field. */ + } params; /**< Event Parameters. */ +} ble_gap_evt_timeout_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */ +typedef struct +{ + int8_t rssi; /**< Received Signal Strength Indication in dBm. + @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ + uint8_t ch_index; /**< Data Channel Index on which the Signal Strength is measured (0-36). */ +} ble_gap_evt_rssi_changed_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_ADV_SET_TERMINATED */ +typedef struct +{ + uint8_t reason; /**< Reason for why the advertising set terminated. See + @ref BLE_GAP_EVT_ADV_SET_TERMINATED_REASON. */ + uint8_t adv_handle; /**< Advertising handle in which advertising has ended. */ + uint8_t num_completed_adv_events; /**< If @ref ble_gap_adv_params_t::max_adv_evts was not set to 0, + this field indicates the number of completed advertising events. */ + ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated + advertising set. The advertising buffers provided in + @ref sd_ble_gap_adv_set_configure are now released. */ +} ble_gap_evt_adv_set_terminated_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. + * + * @note If @ref ble_gap_adv_report_type_t::status is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, + * not all fields in the advertising report may be available. + * + * @note When ble_gap_adv_report_type_t::status is not set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, + * scanning will be paused. To continue scanning, call @ref sd_ble_gap_scan_start. + */ +typedef struct +{ + ble_gap_adv_report_type_t type; /**< Advertising report type. See @ref ble_gap_adv_report_type_t. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr is resolved: + @ref ble_gap_addr_t::addr_id_peer is set to 1 and the address is the + peer's identity address. */ + ble_gap_addr_t direct_addr; /**< Contains the target address of the advertising event if + @ref ble_gap_adv_report_type_t::directed is set to 1. If the + SoftDevice was able to resolve the address, + @ref ble_gap_addr_t::addr_id_peer is set to 1 and the direct_addr + contains the local identity address. If the target address of the + advertising event is @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, + and the SoftDevice was unable to resolve it, the application may try + to resolve this address to find out if the advertising event was + directed to us. */ + uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising packet was received. + See @ref BLE_GAP_PHYS. */ + uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising packet was received. + See @ref BLE_GAP_PHYS. This field is set to @ref BLE_GAP_PHY_NOT_SET if no packets + were received on a secondary advertising channel. */ + int8_t tx_power; /**< TX Power reported by the advertiser in the last packet header received. + This field is set to @ref BLE_GAP_POWER_LEVEL_INVALID if the + last received packet did not contain the Tx Power field. + @note TX Power is only included in extended advertising packets. */ + int8_t rssi; /**< Received Signal Strength Indication in dBm of the last packet received. + @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ + uint8_t ch_index; /**< Channel Index on which the last advertising packet is received (0-39). */ + uint8_t set_id; /**< Set ID of the received advertising data. Set ID is not present + if set to @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */ + uint16_t data_id:12; /**< The advertising data ID of the received advertising data. Data ID + is not present if @ref ble_gap_evt_adv_report_t::set_id is set to + @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */ + ble_data_t data; /**< Received advertising or scan response data. If + @ref ble_gap_adv_report_type_t::status is not set to + @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the data buffer provided + in @ref sd_ble_gap_scan_start is now released. */ + ble_gap_aux_pointer_t aux_pointer; /**< The offset and PHY of the next advertising packet in this extended advertising + event. @note This field is only set if @ref ble_gap_adv_report_type_t::status + is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. */ +} ble_gap_evt_adv_report_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ +typedef struct +{ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Man In The Middle protection requested. */ + uint8_t lesc : 1; /**< LE Secure Connections requested. */ + uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ +} ble_gap_evt_sec_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */ +typedef struct +{ + uint8_t adv_handle; /**< Advertising handle for the advertising set which received the Scan Request */ + int8_t rssi; /**< Received Signal Strength Indication in dBm. + @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ +} ble_gap_evt_scan_req_report_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */ +} ble_gap_evt_data_length_update_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */ +typedef struct +{ + ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */ +} ble_gap_evt_data_length_update_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT. */ +typedef struct +{ + int8_t channel_energy[BLE_GAP_CHANNEL_COUNT]; /**< The measured energy on the Bluetooth Low Energy + channels, in dBm, indexed by Channel Index. + If no measurement is available for the given channel, channel_energy is set to + @ref BLE_GAP_POWER_LEVEL_INVALID. */ +} ble_gap_evt_qos_channel_survey_report_t; + +/**@brief GAP event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + union /**< union alternative identified by evt_id in enclosing struct. */ + { + ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ + ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ + ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ + ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ + ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ + ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ + ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ + ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ + ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ + ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ + ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */ + ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ + ble_gap_evt_adv_set_terminated_t adv_set_terminated; /**< Advertising Set Terminated Event Parameters. */ + ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ + ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */ + ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */ + ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */ + ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */ + ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */ + ble_gap_evt_qos_channel_survey_report_t qos_channel_survey_report; /**< Quality of Service (QoS) Channel Survey Report Parameters. */ + } params; /**< Event Parameters. */ +} ble_gap_evt_t; + + +/** + * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX. + * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN. + */ +typedef struct +{ + uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration. + The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */ + uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units. + The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN. + The event length and the connection interval are the primary parameters + for setting the throughput of a connection. + See the SoftDevice Specification for details on throughput. */ +} ble_gap_conn_cfg_t; + + +/** + * @brief Configuration of maximum concurrent connections in the different connected roles, set with + * @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too + * large. The maximum supported sum of concurrent connections is + * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX. + * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count. + * @retval ::NRF_ERROR_RESOURCES The adv_set_count is too large. The maximum + * supported advertising handles is + * @ref BLE_GAP_ADV_SET_COUNT_MAX. + */ +typedef struct +{ + uint8_t adv_set_count; /**< Maximum number of advertising sets. Default value is @ref BLE_GAP_ADV_SET_COUNT_DEFAULT. */ + uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */ + uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */ + uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */ + uint8_t qos_channel_survey_role_available:1; /**< If set, the Quality of Service (QoS) channel survey module is available to the + application using @ref sd_ble_gap_qos_channel_survey_start. */ +} ble_gap_cfg_role_count_t; + + +/** + * @brief Device name and its properties, set with @ref sd_ble_cfg_set. + * + * @note If the device name is not configured, the default device name will be + * @ref BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be + * @ref BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name + * will have no write access. + * + * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK, + * the attribute table size must be increased to have room for the longer device name (see + * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t). + * + * @note If vloc is @ref BLE_GATTS_VLOC_STACK : + * - p_value must point to non-volatile memory (flash) or be NULL. + * - If p_value is NULL, the device name will initially be empty. + * + * @note If vloc is @ref BLE_GATTS_VLOC_USER : + * - p_value cannot be NULL. + * - If the device name is writable, p_value must point to volatile memory (RAM). + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Invalid device name location (vloc). + * - Invalid device name security mode. + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN). + * - The device name length is too long for the given Attribute Table. + * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported. + */ +typedef struct +{ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */ + uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/ + uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/ +} ble_gap_cfg_device_name_t; + + +/**@brief Configuration structure for GAP configurations. */ +typedef union +{ + ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */ + ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */ +} ble_gap_cfg_t; + + +/**@brief Channel Map option. + * + * @details Used with @ref sd_ble_opt_get to get the current channel map + * or @ref sd_ble_opt_set to set a new channel map. When setting the + * channel map, it applies to all current and future connections. When getting the + * current channel map, it applies to a single connection and the connection handle + * must be supplied. + * + * @note Setting the channel map may take some time, depending on connection parameters. + * The time taken may be different for each connection and the get operation will + * return the previous channel map until the new one has taken effect. + * + * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. + * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. + * + * @retval ::NRF_SUCCESS Get or set successful. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Less then two bits in @ref ch_map are set. + * - Bits for primary advertising channels (37-39) are set. + * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. + * + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ + uint8_t ch_map[5]; /**< Channel Map (37-bit). */ +} ble_gap_opt_ch_map_t; + + +/**@brief Local connection latency option. + * + * @details Local connection latency is a feature which enables the slave to improve + * current consumption by ignoring the slave latency set by the peer. The + * local connection latency can only be set to a multiple of the slave latency, + * and cannot be longer than half of the supervision timeout. + * + * @details Used with @ref sd_ble_opt_set to set the local connection latency. The + * @ref sd_ble_opt_get is not supported for this option, but the actual + * local connection latency (unless set to NULL) is set as a return parameter + * when setting the option. + * + * @note The latency set will be truncated down to the closest slave latency event + * multiple, or the nearest multiple before half of the supervision timeout. + * + * @note The local connection latency is disabled by default, and needs to be enabled for new + * connections and whenever the connection is updated. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t requested_latency; /**< Requested local connection latency. */ + uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */ +} ble_gap_opt_local_conn_latency_t; + +/**@brief Disable slave latency + * + * @details Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection + * (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. When disabled, the + * peripheral will ignore the slave_latency set by the central. + * + * @note Shall only be called on peripheral links. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/ +} ble_gap_opt_slave_latency_disable_t; + +/**@brief Passkey Option. + * + * @details Structure containing the passkey to be used during pairing. This can be used with @ref + * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication + * instead of generating a random one. + * + * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * + */ +typedef struct +{ + uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ +} ble_gap_opt_passkey_t; + + +/**@brief Compatibility mode 1 option. + * + * @details This can be used with @ref sd_ble_opt_set to enable and disable + * compatibility mode 1. Compatibility mode 1 is disabled by default. + * + * @note Compatibility mode 1 enables interoperability with devices that do not support a value of + * 0 for the WinOffset parameter in the Link Layer CONNECT_IND packet. This applies to a + * limited set of legacy peripheral devices from another vendor. Enabling this compatibility + * mode will only have an effect if the local device will act as a central device and + * initiate a connection to a peripheral device. In that case it may lead to the connection + * creation taking up to one connection interval longer to complete for all connections. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable compatibility mode 1.*/ +} ble_gap_opt_compat_mode_1_t; + + +/**@brief Authenticated payload timeout option. + * + * @details This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other + * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX. + * + * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated + * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted + * link. + * + * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance + * to reset the timer. In addition the stack will try to prioritize running of LE ping over other + * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects + * on other activities, it is recommended to use high timeout values. + * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */ +} ble_gap_opt_auth_payload_timeout_t; + +/**@brief Option structure for GAP options. */ +typedef union +{ + ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ + ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ + ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ + ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/ + ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ + ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */ +} ble_gap_opt_t; +/**@} */ + + +/**@addtogroup BLE_GAP_FUNCTIONS Functions + * @{ */ + +/**@brief Set the local Bluetooth identity address. + * + * The local Bluetooth identity address is the address that identifies this device to other peers. + * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @note The identity address cannot be changed while advertising, scanning or creating a connection. + * + * @note This address will be distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the ability to + * reconnect using the old address will be lost. + * + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being + * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged + * for the lifetime of each IC. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @endmscs + * + * @param[in] p_addr Pointer to address structure. + * + * @retval ::NRF_SUCCESS Address successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising, + * scanning or creating a connection. + */ +SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr)); + + +/**@brief Get local Bluetooth identity address. + * + * @note This will always return the identity address irrespective of the privacy settings, + * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval ::NRF_SUCCESS Address successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + */ +SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)); + + +/**@brief Get the Bluetooth device address used by the advertiser. + * + * @note This function will return the local Bluetooth address used in advertising PDUs. When + * using privacy, the SoftDevice will generate a new private address every + * @ref ble_gap_privacy_params_t::private_addr_cycle_s configured using + * @ref sd_ble_gap_privacy_set. Hence depending on when the application calls this API, the + * address returned may not be the latest address that is used in the advertising PDUs. + * + * @param[in] adv_handle The advertising handle to get the address from. + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval ::NRF_SUCCESS Address successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. + * @retval ::NRF_ERROR_INVALID_STATE The advertising set is currently not advertising. + */ +SVCALL(SD_BLE_GAP_ADV_ADDR_GET, uint32_t, sd_ble_gap_adv_addr_get(uint8_t adv_handle, ble_gap_addr_t *p_addr)); + + +/**@brief Set the active whitelist in the SoftDevice. + * + * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles. + * The whitelist cannot be set if a BLE role is using the whitelist. + * + * @note If an address is resolved using the information in the device identity list, then the whitelist + * filter policy applies to the peer identity address and not the resolvable address sent on air. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @endmscs + * + * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared. + * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + * + * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid. + * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when + * pp_wl_addrs is not NULL. + */ +SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len)); + + +/**@brief Set device identity list. + * + * @note Only one device identity list can be used at a time and the list is shared between the BLE roles. + * The device identity list cannot be set if a BLE role is using the list. + * + * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared. + * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index. + * To fill in the list with the currently set device IRK for all peers, set to NULL. + * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS The device identity list successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid. + * This code may be returned if the local IRK list also has an invalid entry. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can + * only return when pp_id_keys is not NULL. + */ +SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len)); + + +/**@brief Set privacy settings. + * + * @note Privacy settings cannot be changed while advertising, scanning or creating a connection. + * + * @param[in] p_privacy_params Privacy settings. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided. + * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising, scanning + * or creating a connection. + */ +SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)); + + +/**@brief Get privacy settings. + * + * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called. + * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return. + * + * @param[in,out] p_privacy_params Privacy settings. + * + * @retval ::NRF_SUCCESS Privacy settings read. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + */ +SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); + + +/**@brief Configure an advertising set. Set, clear or update advertising and scan response data. + * + * @note The format of the advertising data will be checked by this call to ensure interoperability. + * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and + * duplicating the local name in the advertising data and scan response data. + * + * @note In order to update advertising data while advertising, new advertising buffers must be provided. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in,out] p_adv_handle Provide a pointer to a handle containing @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure + * a new advertising set. On success, a new handle is then returned through the pointer. + * Provide a pointer to an existing advertising handle to configure an existing advertising set. + * @param[in] p_adv_data Advertising data. If set to NULL, no advertising data will be used. See @ref ble_gap_adv_data_t. + * @param[in] p_adv_params Advertising parameters. When this function is used to update advertising data while advertising, + * this parameter must be NULL. See @ref ble_gap_adv_params_t. + * + * @retval ::NRF_SUCCESS Advertising set successfully configured. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied: + * - Invalid advertising data configuration specified. See @ref ble_gap_adv_data_t. + * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t. + * - Use of whitelist requested but whitelist has not been set, + * see @ref sd_ble_gap_whitelist_set. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR ble_gap_adv_params_t::p_peer_addr is invalid. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - It is invalid to provide non-NULL advertising set parameters while advertising. + * - It is invalid to provide the same data buffers while advertising. To update + * advertising data, provide new advertising buffers. + * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. Use @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to + * configure a new advertising handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied. Check the advertising data format specification + * given in Bluetooth Specification Version 5.0, Volume 3, Part C, Chapter 11. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data length or advertising parameter configuration. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to configure a new advertising handle. Update an + * existing advertising handle instead. + * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. + */ +SVCALL(SD_BLE_GAP_ADV_SET_CONFIGURE, uint32_t, sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params)); + + +/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @note Only one advertiser may be active at any time. + * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} + * @event{@ref BLE_GAP_EVT_ADV_SET_TERMINATED, Advertising set has terminated.} + * @event{@ref BLE_GAP_EVT_SCAN_REQ_REPORT, A scan request was received.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] adv_handle Advertising handle to advertise on, received from @ref sd_ble_gap_adv_set_configure. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or + * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. For non-connectable + * advertising, this is ignored. + * + * @retval ::NRF_SUCCESS The BLE stack has started advertising. + * @retval ::NRF_ERROR_INVALID_STATE adv_handle is not configured or already advertising. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. Configure a new adveriting handle with @ref sd_ble_gap_adv_set_configure. + * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied: + * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t. + * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. + * @retval ::NRF_ERROR_RESOURCES Either: + * - adv_handle is configured with connectable advertising, but the event_length parameter + * associated with conn_cfg_tag is too small to be able to establish a connection on + * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length. + * - Not enough BLE role slots available. + Stop one or more currently active roles (Central, Peripheral, Broadcaster or Observer) and try again. + * - p_adv_params is configured with connectable advertising, but the event_length parameter + * associated with conn_cfg_tag is too small to be able to establish a connection on + * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length. + */ +SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag)); + + +/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] adv_handle The advertising handle that should stop advertising. + * + * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Invalid advertising handle. + * @retval ::NRF_ERROR_INVALID_STATE The advertising handle is not advertising. + */ +SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(uint8_t adv_handle)); + + + +/**@brief Update connection parameters. + * + * @details In the central role this will initiate a Link Layer connection parameter update procedure, + * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for + * the central to perform the procedure. In both cases, and regardless of success or failure, the application + * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. + * + * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CPU_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, + * the parameters in the PPCP characteristic of the GAP service will be used instead. + * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected + * + * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established. + * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); + + +/**@brief Disconnect (GAP Link Termination). + * + * @details This call initiates the disconnection procedure, and its completion will be communicated to the application + * with a @ref BLE_GAP_EVT_DISCONNECTED event. + * + * @events + * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CONN_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). + * + * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established. + */ +SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); + + +/**@brief Set the radio's transmit power. + * + * @param[in] role The role to set the transmit power for, see @ref BLE_GAP_TX_POWER_ROLES for + * possible roles. + * @param[in] handle The handle parameter is interpreted depending on role: + * - If role is @ref BLE_GAP_TX_POWER_ROLE_CONN, this value is the specific connection handle. + * - If role is @ref BLE_GAP_TX_POWER_ROLE_ADV, the advertising set identified with the advertising handle, + * will use the specified transmit power, and include it in the advertising packet headers if + * @ref ble_gap_adv_properties_t::include_tx_power set. + * - For all other roles handle is ignored. + * @param[in] tx_power Radio transmit power in dBm (see note for accepted values). + * + * @note Supported tx_power values: -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +2dBm, +3dBm, +4dBm, +5dBm, +6dBm, +7dBm and +8dBm. + * @note The initiator will have the same transmit power as the scanner. + * @note When a connection is created it will inherit the transmit power from the initiator or + * advertiser leading to the connection. + * + * @retval ::NRF_SUCCESS Successfully changed the transmit power. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(uint8_t role, uint16_t handle, int8_t tx_power)); + + +/**@brief Set GAP Appearance value. + * + * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); + + +/**@brief Get GAP Appearance value. + * + * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); + + +/**@brief Set GAP Peripheral Preferred Connection Parameters. + * + * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); + + +/**@brief Get GAP Peripheral Preferred Connection Parameters. + * + * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); + + +/**@brief Set GAP device name. + * + * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t), + * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned. + * + * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t. + * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. + * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). + * + * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); + + +/**@brief Get GAP device name. + * + * @note If the device name is longer than the size of the supplied buffer, + * p_len will return the complete device name length, + * and not the number of bytes actually returned in p_dev_name. + * The application may use this information to allocate a suitable buffer size. + * + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. + * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. + * + * @retval ::NRF_SUCCESS GAP device name retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); + + +/**@brief Initiate the GAP Authentication procedure. + * + * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), + * otherwise in the peripheral role, an SMP Security Request will be sent. + * + * @events + * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:} + * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} + * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} + * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} + * @event{@ref BLE_GAP_EVT_KEY_PRESSED} + * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} + * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} + * @event{@ref BLE_GAP_EVT_AUTH_STATUS} + * @event{@ref BLE_GAP_EVT_TIMEOUT} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. + * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. + * In the central role, this pointer may be NULL to reject a Security Request. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - No link has been established. + * - An encryption is already executing or queued. + * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. + */ +SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); + + +/**@brief Reply with GAP security parameters. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. + * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have + * already been provided during a previous call to @ref sd_ble_gap_authenticate. + * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure + * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application + * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. + * Note that the SoftDevice expects the application to provide memory for storing the + * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key + * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the + * @ref BLE_GAP_EVT_AUTH_STATUS event. + * + * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Security parameters has not been requested. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + */ +SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); + + +/**@brief Reply with an authentication key. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. + * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination) + * or NULL when confirming LE Secure Connections Numeric Comparison. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format. + * + * @retval ::NRF_SUCCESS Authentication key successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Authentication key has not been requested. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); + + +/**@brief Reply with an LE Secure connections DHKey. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey LE Secure Connections DHKey. + * + * @retval ::NRF_SUCCESS DHKey successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - The peer is not authenticated. + * - The application has not pulled a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); + + +/**@brief Notify the peer of a local keypress. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. + * + * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Authentication key not requested. + * - Passkey has not been entered. + * - Keypresses have not been enabled by both peers. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); + + +/**@brief Generate a set of OOB data to send to a peer out of band. + * + * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established, + * the one used during connection setup). The application may manually overwrite it with an updated value. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Can be @ref BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. + * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. + * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. + * + * @retval ::NRF_SUCCESS OOB data successfully generated. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own)); + +/**@brief Provide the OOB data sent/received out of band. + * + * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. + * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data. + * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. + * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. + * Must correspond to @ref ble_gap_sec_params_t::oob flag + * in @ref sd_ble_gap_authenticate in the central role or + * in @ref sd_ble_gap_sec_params_reply in the peripheral role. + * + * @retval ::NRF_SUCCESS OOB data accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Authentication key not requested + * - Not expecting LESC OOB data + * - Have not actually exchanged passkeys. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer)); + + +/**@brief Initiate GAP Encryption procedure. + * + * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. + * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry. + */ +SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); + + +/**@brief Reply with GAP security information. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. + * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. + * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. + * + * @retval ::NRF_SUCCESS Successfully accepted security information. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - No link has been established. + * - No @ref BLE_GAP_EVT_SEC_REQUEST pending. + * - LE long term key requested command not allowed. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info)); + + +/**@brief Get the current connection security. + * + * @param[in] conn_handle Connection handle. + * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Current connection security successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); + + +/**@brief Start reporting the received signal strength to the application. + * + * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. + * + * @events + * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is + * dependent on the settings of the threshold_dbm + * and skip_count input parameters.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. + * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. + * + * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is already ongoing. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); + + +/**@brief Stop reporting the received signal strength. + * + * @note An RSSI change detected before the call but not yet received by the application + * may be reported after @ref sd_ble_gap_rssi_stop has been called. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * + * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); + + +/**@brief Get the received signal strength for the last connection event. + * + * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND + * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. + * @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. + * @param[out] p_ch_index Pointer to the location where Channel Index for the RSSI measurement shall be stored. + * + * @retval ::NRF_SUCCESS Successfully read the RSSI. + * @retval ::NRF_ERROR_NOT_FOUND No sample is available. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing. + */ +SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi, uint8_t *p_ch_index)); + + +/**@brief Start or continue scanning (GAP Discovery procedure, Observer Procedure). + * + * @note A call to this function will require the application to keep the memory pointed by + * p_adv_report_buffer alive until the buffer is released. The buffer is released when the scanner is stopped + * or when this function is called with another buffer. + * + * @note The scanner will automatically stop in the following cases: + * - @ref sd_ble_gap_scan_stop is called. + * - @ref sd_ble_gap_connect is called. + * - A @ref BLE_GAP_EVT_TIMEOUT with source set to @ref BLE_GAP_TIMEOUT_SRC_SCAN is received. + * - When a @ref BLE_GAP_EVT_ADV_REPORT event is received and @ref ble_gap_adv_report_type_t::status is not set to + * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. In this case scanning is only paused to let the application + * access received data. The application must call this function to continue scanning, or call @ref sd_ble_gap_scan_stop + * to stop scanning. + * + * @note If a @ref BLE_GAP_EVT_ADV_REPORT event is received with @ref ble_gap_adv_report_type_t::status set to + * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the scanner will continue scanning, and the application will + * receive more reports from this advertising event. The following reports will include the old and new received data. + * + * @events + * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_scan_params Pointer to scan parameters structure. When this function is used to continue + * scanning, this parameter must be NULL. + * @param[in] p_adv_report_buffer Pointer to buffer used to store incoming advertising data. + * The memory pointed to should be kept alive until the scanning is stopped. + * See @ref BLE_GAP_SCAN_BUFFER_SIZE for minimum and maximum buffer size. + * If the scanner receives advertising data larger than can be stored in the buffer, + * a @ref BLE_GAP_EVT_ADV_REPORT will be raised with @ref ble_gap_adv_report_type_t::status + * set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED. + * + * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Scanning is already ongoing and p_scan_params was not NULL + * - Scanning is not running and p_scan_params was NULL. + * - The scanner has timed out when this function is called to continue scanning. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. See @ref ble_gap_scan_params_t. + * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported parameters supplied. See @ref ble_gap_scan_params_t. + * @retval ::NRF_ERROR_INVALID_LENGTH The provided buffer length is invalid. See @ref BLE_GAP_SCAN_BUFFER_MIN. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again + */ +SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params, ble_data_t const * p_adv_report_buffer)); + + +/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). + * + * @note The buffer provided in @ref sd_ble_gap_scan_start is released. + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. + * @retval ::NRF_ERROR_INVALID_STATE Not in the scanning state. + */ +SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); + + +/**@brief Create a connection (GAP Link Establishment). + * + * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. + * The scanning procedure will be stopped even if the function returns an error. + * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, A connection was established.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Failed to establish a connection.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @param[in] p_peer_addr Pointer to peer identity address. If @ref ble_gap_scan_params_t::filter_policy is set to use + * whitelist, then p_peer_addr is ignored. + * @param[in] p_scan_params Pointer to scan parameters structure. + * @param[in] p_conn_params Pointer to desired connection parameters. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or + * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. + * + * @retval ::NRF_SUCCESS Successfully initiated connection procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * - Invalid parameter(s) in p_scan_params or p_conn_params. + * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. + * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set. + * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found. + * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an + * existing locally initiated connect procedure, which must complete before initiating again. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. + * @retval ::NRF_ERROR_RESOURCES Either: + * - Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Observer) and try again. + * - The event_length parameter associated with conn_cfg_tag is too small to be able to + * establish a connection on the selected @ref ble_gap_scan_params_t::scan_phys. + * Use @ref sd_ble_cfg_set to increase the event length. + */ +SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)); + + +/**@brief Cancel a connection establishment. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure. + * @retval ::NRF_ERROR_INVALID_STATE No locally initiated connect procedure started or connection + * completed occurred. + */ +SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); + + +/**@brief Initiate or respond to a PHY Update Procedure + * + * @details This function is used to initiate or respond to a PHY Update Procedure. It will always + * generate a @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed. + * If this function is used to initiate a PHY Update procedure and the only option + * provided in @ref ble_gap_phys_t::tx_phys and @ref ble_gap_phys_t::rx_phys is the + * currently active PHYs in the respective directions, the SoftDevice will generate a + * @ref BLE_GAP_EVT_PHY_UPDATE with the current PHYs set and will not initiate the + * procedure in the Link Layer. + * + * If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys is @ref BLE_GAP_PHY_AUTO, + * then the stack will select PHYs based on the peer's PHY preferences and the local link + * configuration. The PHY Update procedure will for this case result in a PHY combination + * that respects the time constraints configured with @ref sd_ble_cfg_set and the current + * link layer data length. + * + * When acting as a central, the SoftDevice will select the fastest common PHY in each direction. + * + * If the peer does not support the PHY Update Procedure, then the resulting + * @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to + * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE. + * + * If the PHY procedure was rejected by the peer due to a procedure collision, the status + * will be @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or + * @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION. + * If the peer responds to the PHY Update procedure with invalid parameters, the status + * will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS. + * If the PHY procedure was rejected by the peer for a different reason, the status will + * contain the reason as specified by the peer. + * + * @events + * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE} + * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE} + * @endmscs + * + * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested. + * @param[in] p_gap_phys Pointer to PHY structure. + * + * @retval ::NRF_SUCCESS Successfully requested a PHY Update. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the combination of + * @ref ble_gap_phys_t::tx_phys, @ref ble_gap_phys_t::rx_phys, and @ref ble_gap_data_length_params_t. + * The connection event length is configured with @ref BLE_CONN_CFG_GAP using @ref sd_ble_cfg_set. + * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry. + * + */ +SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)); + + +/**@brief Initiate or respond to a Data Length Update Procedure. + * + * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of + * p_dl_params, the SoftDevice will choose the highest value supported in current + * configuration and connection parameters. + * @note If the link PHY is Coded, the SoftDevice will ensure that the MaxTxTime and/or MaxRxTime + * used in the Data Length Update procedure is at least 2704 us. Otherwise, MaxTxTime and + * MaxRxTime will be limited to maximum 2120 us. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update + * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let + * the SoftDevice automatically decide the value for that member. + * Set to NULL to use automatic values for all members. + * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not + * have enough resources or does not support the requested Data Length + * Update parameters. Ignored if NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. Inspect + * p_dl_limitation to see which parameter is not supported. + * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the requested parameters. + * Use @ref sd_ble_cfg_set with @ref BLE_CONN_CFG_GAP to increase the connection event length. + * Inspect p_dl_limitation to see where the limitation is. + * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the + * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond. + */ +SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation)); + +/**@brief Start the Quality of Service (QoS) channel survey module. + * + * @details The channel survey module provides measurements of the energy levels on + * the Bluetooth Low Energy channels. When the module is enabled, @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT + * events will periodically report the measured energy levels for each channel. + * + * @note The measurements are scheduled with lower priority than other Bluetooth Low Energy roles, + * Radio Timeslot API events and Flash API events. + * + * @note The channel survey module will attempt to do measurements so that the average interval + * between measurements will be interval_us. However due to the channel survey module + * having the lowest priority of all roles and modules, this may not be possible. In that + * case fewer than expected channel survey reports may be given. + * + * @note In order to use the channel survey module, @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available + * must be set. This is done using @ref sd_ble_cfg_set. + * + * @param[in] interval_us Requested average interval for the measurements and reports. See + * @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS for valid ranges. If set + * to @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS, the channel + * survey role will be scheduled at every available opportunity. + * + * @retval ::NRF_SUCCESS The module is successfully started. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter supplied. interval_us is out of the + * allowed range. + * @retval ::NRF_ERROR_INVALID_STATE Trying to start the module when already running. + * @retval ::NRF_ERROR_RESOURCES The channel survey module is not available to the application. + * Set @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available using + * @ref sd_ble_cfg_set. + */ +SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START, uint32_t, sd_ble_gap_qos_channel_survey_start(uint32_t interval_us)); + +/**@brief Stop the Quality of Service (QoS) channel survey module. + * + * @retval ::NRF_SUCCESS The module is successfully stopped. + * @retval ::NRF_ERROR_INVALID_STATE Trying to stop the module when it is not running. + */ +SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP, uint32_t, sd_ble_gap_qos_channel_survey_stop(void)); + + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GAP_H__ + +/** + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatt.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatt.h new file mode 100644 index 0000000..9cb577c --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatt.h @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common + @{ + @brief Common definitions and prototypes for the GATT interfaces. + */ + +#ifndef BLE_GATT_H__ +#define BLE_GATT_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATT_DEFINES Defines + * @{ */ + +/** @brief Default ATT MTU, in bytes. */ +#define BLE_GATT_ATT_MTU_DEFAULT 23 + +/**@brief Invalid Attribute Handle. */ +#define BLE_GATT_HANDLE_INVALID 0x0000 + +/**@brief First Attribute Handle. */ +#define BLE_GATT_HANDLE_START 0x0001 + +/**@brief Last Attribute Handle. */ +#define BLE_GATT_HANDLE_END 0xFFFF + +/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources + * @{ */ +#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ +/** @} */ + +/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations + * @{ */ +#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ +/** @} */ + +/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags + * @{ */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ +/** @} */ + +/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations + * @{ */ +#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ +#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ +/** @} */ + +/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes + * @{ */ +#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ +#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ +#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ +#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ +#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ +#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */ +#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ +#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ +#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ +#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ +#define BLE_GATT_STATUS_ATTERR_CPS_WRITE_REQ_REJECTED 0x01FC /**< ATT Common Profile and Service Error: Write request rejected. */ +#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ +#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ +#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ +/** @} */ + + +/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats + * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + * @{ */ +#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ +#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ +#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ +#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ +#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ +#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ +#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ +#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ +/** @} */ + +/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces + * @{ + */ +#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ +#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATT_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT. + */ +typedef struct +{ + uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive. + The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + @mscs + @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + @endmscs + */ +} ble_gatt_conn_cfg_t; + +/**@brief GATT Characteristic Properties. */ +typedef struct +{ + /* Standard properties */ + uint8_t broadcast :1; /**< Broadcasting of the value permitted. */ + uint8_t read :1; /**< Reading the value permitted. */ + uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */ + uint8_t write :1; /**< Writing the value with Write Request permitted. */ + uint8_t notify :1; /**< Notification of the value permitted. */ + uint8_t indicate :1; /**< Indications of the value permitted. */ + uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */ +} ble_gatt_char_props_t; + +/**@brief GATT Characteristic Extended Properties. */ +typedef struct +{ + /* Extended properties */ + uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */ + uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ +} ble_gatt_char_ext_props_t; + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATT_H__ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gattc.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gattc.h new file mode 100644 index 0000000..7fb3920 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gattc.h @@ -0,0 +1,715 @@ +/* + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client + @{ + @brief Definitions and prototypes for the GATT Client interface. + */ + +#ifndef BLE_GATTC_H__ +#define BLE_GATTC_H__ + +#include +#include "nrf.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" +#include "ble_gatt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GATTC API SVC numbers. */ +enum BLE_GATTC_SVCS +{ + SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ + SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ + SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ + SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ + SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ + SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ + SD_BLE_GATTC_READ, /**< Generic read. */ + SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ + SD_BLE_GATTC_WRITE, /**< Generic write. */ + SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ + SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */ +}; + +/** + * @brief GATT Client Event IDs. + */ +enum BLE_GATTC_EVTS +{ + BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */ + BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */ + BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */ + BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ + BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ + BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */ + BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ + BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ + BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */ + BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ + BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTC_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC + * @{ */ +#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ +/** @} */ + +/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats + * @{ */ +#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ +#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ +/** @} */ + +/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults + * @{ */ +#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTC_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct +{ + uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission. + The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */ +} ble_gattc_conn_cfg_t; + +/**@brief Operation Handle Range. */ +typedef struct +{ + uint16_t start_handle; /**< Start Handle. */ + uint16_t end_handle; /**< End Handle. */ +} ble_gattc_handle_range_t; + + +/**@brief GATT service. */ +typedef struct +{ + ble_uuid_t uuid; /**< Service UUID. */ + ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ +} ble_gattc_service_t; + + +/**@brief GATT include. */ +typedef struct +{ + uint16_t handle; /**< Include Handle. */ + ble_gattc_service_t included_srvc; /**< Handle of the included service. */ +} ble_gattc_include_t; + + +/**@brief GATT characteristic. */ +typedef struct +{ + ble_uuid_t uuid; /**< Characteristic UUID. */ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + uint8_t char_ext_props : 1; /**< Extended properties present. */ + uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ + uint16_t handle_value; /**< Handle of the Characteristic Value. */ +} ble_gattc_char_t; + + +/**@brief GATT descriptor. */ +typedef struct +{ + uint16_t handle; /**< Descriptor Handle. */ + ble_uuid_t uuid; /**< Descriptor UUID. */ +} ble_gattc_desc_t; + + +/**@brief Write Parameters. */ +typedef struct +{ + uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ + uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ + uint16_t handle; /**< Handle to the attribute to be written. */ + uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ + uint16_t len; /**< Length of data in bytes. */ + uint8_t const *p_value; /**< Pointer to the value data. */ +} ble_gattc_write_params_t; + +/**@brief Attribute Information for 16-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid_t uuid; /**< 16-bit Attribute UUID. */ +} ble_gattc_attr_info16_t; + +/**@brief Attribute Information for 128-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */ +} ble_gattc_attr_info128_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Service count. */ + ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_prim_srvc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Include count. */ + ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_rel_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Characteristic count. */ + ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Descriptor count. */ + ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_desc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Attribute count. */ + uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ + union { + ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + } info; /**< Attribute information union. */ +} ble_gattc_evt_attr_info_disc_rsp_t; + +/**@brief GATT read by UUID handle value pair. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */ +} ble_gattc_handle_value_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ +typedef struct +{ + uint16_t count; /**< Handle-Value Pair Count. */ + uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ + uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_val_by_uuid_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint16_t offset; /**< Offset of the attribute data. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ +typedef struct +{ + uint16_t len; /**< Concatenated Attribute values length. */ + uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_vals_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ + uint16_t offset; /**< Data offset. */ + uint16_t len; /**< Data length. */ + uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_write_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ +typedef struct +{ + uint16_t handle; /**< Handle to which the HVx operation applies. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_hvx_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */ +typedef struct +{ + uint16_t server_rx_mtu; /**< Server RX MTU size. */ +} ble_gattc_evt_exchange_mtu_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gattc_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */ +typedef struct +{ + uint8_t count; /**< Number of write without response transmissions completed. */ +} ble_gattc_evt_write_cmd_tx_complete_t; + +/**@brief GATTC event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ + union + { + ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ + ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ + ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ + ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ + ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ + ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ + ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ + ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ + ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ + ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */ + ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ + ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */ + } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ +} ble_gattc_evt_t; +/** @} */ + +/** @addtogroup BLE_GATTC_FUNCTIONS Functions + * @{ */ + +/**@brief Initiate or continue a GATT Primary Service Discovery procedure. + * + * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. + * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search. + * + * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with + * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. + * + * @events + * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] start_handle Handle to start searching from. + * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); + + +/**@brief Initiate or continue a GATT Relationship Discovery procedure. + * + * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, + * this must be called again with an updated handle range to continue the search. + * + * @events + * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Characteristic Discovery procedure. + * + * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with + * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. + * + * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. + * + * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_uuid Pointer to a Characteristic value UUID to read. + * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. + * + * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor + * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the + * complete value. + * + * @events + * @event{@ref BLE_GATTC_EVT_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute to be read. + * @param[in] offset Offset into the attribute value to be read. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); + + +/**@brief Initiate a GATT Read Multiple Characteristic Values procedure. + * + * @details This function initiates a GATT Read Multiple Characteristic Values procedure. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. + * @param[in] handle_count The number of handles in p_handles. + * + * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); + + +/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure. + * + * @details This function can perform all write procedures described in GATT. + * + * @note Only one write with response procedure can be ongoing per connection at a time. + * If the application tries to write with response while another write with response procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer. + * + * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size + * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete. + * + * @note The application can keep track of the available queue element count for writes without responses by following the procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.} + * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_write_params A pointer to a write parameters structure. + * + * @retval ::NRF_SUCCESS Successfully started the Write procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry. + * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued. + * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); + + +/**@brief Send a Handle Value Confirmation to the GATT Server. + * + * @mscs + * @mmsc{@ref BLE_GATTC_HVI_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute in the indication. + * + * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); + +/**@brief Discovers information about a range of attributes on a GATT server. + * + * @events + * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} + * @endevents + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range The range of handles to request information about. + * + * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range)); + +/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value, and + * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @events + * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] client_rx_mtu Client RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + used for this connection. + * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent request to the server. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu)); + +/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * + * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * @note If the buffer contains different event, behavior is undefined. + * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with + * the next Handle-Value pair in each iteration. If the function returns other than + * @ref NRF_SUCCESS, it will not be changed. + * - To start iteration, initialize the structure to zero. + * - To continue, pass the value from previous iteration. + * + * \code + * ble_gattc_handle_value_t iter; + * memset(&iter, 0, sizeof(ble_gattc_handle_value_t)); + * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS) + * { + * app_handle = iter.handle; + * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len); + * } + * \endcode + * + * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair. + * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list. + */ +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter); + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter) +{ + uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len; + uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value; + uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first; + + if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count) + { + p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0]; + p_iter->p_value = p_next + sizeof(uint16_t); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NOT_FOUND; + } +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif +#endif /* BLE_GATTC_H__ */ + +/** + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatts.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatts.h new file mode 100644 index 0000000..394d8d1 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatts.h @@ -0,0 +1,845 @@ +/* + * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server + @{ + @brief Definitions and prototypes for the GATTS interface. + */ + +#ifndef BLE_GATTS_H__ +#define BLE_GATTS_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" +#include "ble_gatt.h" +#include "ble_gap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief GATTS API SVC numbers. + */ +enum BLE_GATTS_SVCS +{ + SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ + SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ + SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ + SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ + SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ + SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ + SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ + SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ + SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ + SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ + SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ + SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ + SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */ + SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */ +}; + +/** + * @brief GATT Server Event IDs. + */ +enum BLE_GATTS_EVTS +{ + BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */ + BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */ + BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ + BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */ + BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */ + BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */ + BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */ + BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */ +}; + +/**@brief GATTS Configuration IDs. + * + * IDs that uniquely identify a GATTS configuration. + */ +enum BLE_GATTS_CFGS +{ + BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */ + BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTS_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS + * @{ */ +#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ +#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths + * @{ */ +#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ +#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ +/** @} */ + +/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types + * @{ */ +#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ +#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ +#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ +/** @} */ + + +/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types + * @{ */ +#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ +#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ +#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ +#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ +/** @} */ + + +/** @defgroup BLE_GATTS_OPS GATT Server Operations + * @{ */ +#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ +/** @} */ + +/** @defgroup BLE_GATTS_VLOCS GATT Value Locations + * @{ */ +#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ +#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ +#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack + will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */ +/** @} */ + +/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types + * @{ */ +#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ +#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ +#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ +/** @} */ + +/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags + * @{ */ +#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ +#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ +/** @} */ + +/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values + * @{ + */ +#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size + * @{ + */ +#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */ +#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */ +/** @} */ + +/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults + * @{ + */ +#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTS_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct +{ + uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission. + The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */ +} ble_gatts_conn_cfg_t; + +/**@brief Attribute metadata. */ +typedef struct +{ + ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vlen :1; /**< Variable length attribute. */ + uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ + uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */ +} ble_gatts_attr_md_t; + + +/**@brief GATT Attribute. */ +typedef struct +{ + ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */ + ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */ + uint16_t init_len; /**< Initial attribute value length in bytes. */ + uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ + uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ + uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer + that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. + The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/ +} ble_gatts_attr_t; + +/**@brief GATT Attribute Value. */ +typedef struct +{ + uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ + uint16_t offset; /**< Attribute value offset. */ + uint8_t *p_value; /**< Pointer to where value is stored or will be stored. + If value is stored in user memory, only the attribute length is updated when p_value == NULL. + Set to NULL when reading to obtain the complete length of the attribute value */ +} ble_gatts_value_t; + + +/**@brief GATT Characteristic Presentation Format. */ +typedef struct +{ + uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ + int8_t exponent; /**< Exponent for integer data types. */ + uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */ + uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ + uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ +} ble_gatts_char_pf_t; + + +/**@brief GATT Characteristic metadata. */ +typedef struct +{ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ + uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ + uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ + uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ + ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ + ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ +} ble_gatts_char_md_t; + + +/**@brief GATT Characteristic Definition Handles. */ +typedef struct +{ + uint16_t value_handle; /**< Handle to the characteristic value. */ + uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ +} ble_gatts_char_handles_t; + + +/**@brief GATT HVx parameters. */ +typedef struct +{ + uint16_t handle; /**< Characteristic Value Handle. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t offset; /**< Offset within the attribute value. */ + uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */ + uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */ +} ble_gatts_hvx_params_t; + +/**@brief GATT Authorization parameters. */ +typedef struct +{ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. + Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set, + as the data to be written needs to be stored and later provided by the application. */ + uint16_t offset; /**< Offset of the attribute value being updated. */ + uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ + uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */ +} ble_gatts_authorize_params_t; + +/**@brief GATT Read or Write Authorize Reply parameters. */ +typedef struct +{ + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ + ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ + } params; /**< Reply Parameters. */ +} ble_gatts_rw_authorize_reply_params_t; + +/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */ +typedef struct +{ + uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */ +} ble_gatts_cfg_service_changed_t; + +/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The specified Attribute Table size is too small. + * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. + * - The specified Attribute Table size is not a multiple of 4. + */ +typedef struct +{ + uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */ +} ble_gatts_cfg_attr_tab_size_t; + +/**@brief Config structure for GATTS configurations. */ +typedef union +{ + ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */ + ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */ +} ble_gatts_cfg_t; + + +/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ + uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the received data. */ + uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gatts_evt_write_t; + +/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint16_t offset; /**< Offset for the read operation. */ +} ble_gatts_evt_read_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ +typedef struct +{ + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ + ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ + } request; /**< Request Parameters. */ +} ble_gatts_evt_rw_authorize_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ +typedef struct +{ + uint8_t hint; /**< Hint (currently unused). */ +} ble_gatts_evt_sys_attr_missing_t; + + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ +} ble_gatts_evt_hvc_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */ +typedef struct +{ + uint16_t client_rx_mtu; /**< Client RX MTU size. */ +} ble_gatts_evt_exchange_mtu_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gatts_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */ +typedef struct +{ + uint8_t count; /**< Number of notification transmissions completed. */ +} ble_gatts_evt_hvn_tx_complete_t; + +/**@brief GATTS event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ + union + { + ble_gatts_evt_write_t write; /**< Write Event Parameters. */ + ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ + ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ + ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ + ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */ + ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ + ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_gatts_evt_t; + +/** @} */ + +/** @addtogroup BLE_GATTS_FUNCTIONS Functions + * @{ */ + +/**@brief Add a service declaration to the Attribute Table. + * + * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to + * add a secondary service declaration that is not referenced by another service later in the Attribute Table. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. + * @param[in] p_uuid Pointer to service UUID. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a service declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); + + +/**@brief Add an include declaration to the Attribute Table. + * + * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). + * + * @note The included service must already be present in the Attribute Table prior to this call. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] inc_srvc_handle Handle of the included service. + * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added an include declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. + * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + */ +SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); + + +/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table. + * + * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). + * + * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits, + * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values. + * + * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_char_md Characteristic metadata. + * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. + * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a characteristic. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); + + +/**@brief Add a descriptor to the Attribute Table. + * + * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_attr Pointer to the attribute structure. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a descriptor. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); + +/**@brief Set the value of a given attribute. + * + * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully set the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + */ +SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Get the value of a given attribute. + * + * @note If the attribute value is longer than the size of the supplied buffer, + * @ref ble_gatts_value_t::len will return the total attribute value length (excluding offset), + * and not the number of bytes actually returned in @ref ble_gatts_value_t::p_value. + * The application may use this information to allocate a suitable buffer size. + * + * @note When retrieving system attribute values with this function, the connection handle + * may refer to an already disconnected connection. Refer to the documentation of + * @ref sd_ble_gatts_sys_attr_get for further information. + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + */ +SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Notify or Indicate an attribute value. + * + * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation + * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that + * the application can atomically perform a value update and a server initiated transaction with a single API call. + * + * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. + * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, + * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES. + * The caller can check whether the value has been updated by looking at the contents of *(@ref ble_gatts_hvx_params_t::p_len). + * + * @note Only one indication procedure can be ongoing per connection at a time. + * If the application tries to indicate an attribute value while another indication procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer. + * + * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size + * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete. + * + * @note The application can keep track of the available queue element count for notifications by following the procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.} + * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_HVN_MSC} + * @mmsc{@ref BLE_GATTS_HVI_MSC} + * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data + * contains a non-NULL pointer the attribute value will be updated with the contents + * pointed by it before sending the notification or indication. If the attribute value + * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to + * contain the number of actual bytes written, else it will be set to 0. + * + * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. + * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + * @retval ::NRF_ERROR_RESOURCES Too many notifications queued. + * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); + +/**@brief Indicate the Service Changed attribute value. + * + * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute + * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will + * be issued. + * + * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. + * + * @events + * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_SC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] start_handle Start of affected attribute handle range. + * @param[in] end_handle End of affected attribute handle range. + * + * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref + * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. + * @retval ::NRF_ERROR_BUSY Procedure already in progress. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); + +/**@brief Respond to a Read/Write authorization request. + * + * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. + * + * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond + * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update + * is set to 0. + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, + * handle supplied does not match requested handle, + * or invalid data to be written provided by the application. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); + + +/**@brief Update persistent system attribute information. + * + * @details Supply information about persistent system attributes to the stack, + * previously obtained using @ref sd_ble_gatts_sys_attr_get. + * This call is only allowed for active connections, and is usually + * made immediately after a connection is established with an known bonded device, + * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. + * + * p_sysattrs may point directly to the application's stored copy of the system attributes + * obtained using @ref sd_ble_gatts_sys_attr_get. + * If the pointer is NULL, the system attribute info is initialized, assuming that + * the application does not have any previously saved system attribute data for this device. + * + * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. + * + * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. + * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or + * reset the SoftDevice to return to a known state. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. + * @param[in] len Size of data pointed by p_sys_attr_data, in octets. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully set the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); + + +/**@brief Retrieve persistent system attribute information from the stack. + * + * @details This call is used to retrieve information about values to be stored persistently by the application + * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, + * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set. + * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for + * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it. + * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes + * may be written to at any time by the peer during a connection's lifetime. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. + * + * @mscs + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle of the recently terminated connection. + * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described + * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. + * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. + * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); + + +/**@brief Retrieve the first valid user attribute handle. + * + * @param[out] p_handle Pointer to an integer where the handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully retrieved the handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); + +/**@brief Retrieve the attribute UUID and/or metadata. + * + * @param[in] handle Attribute handle + * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. + * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. + * + * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. + * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. + */ +SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md)); + +/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client. + * + * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and + * - The Server RX MTU value. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @mscs + * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] server_rx_mtu Server RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + * used for this connection. + * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent response to the client. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)); +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATTS_H__ + +/** + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_hci.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_hci.h new file mode 100644 index 0000000..f0dde9a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_hci.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_COMMON + @{ +*/ + + +#ifndef BLE_HCI_H__ +#define BLE_HCI_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes + * @{ */ + +#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ +/*0x03 Hardware Failure +0x04 Page Timeout +*/ +#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ +#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ +#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ +#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ +/*0x09 Connection Limit Exceeded +0x0A Synchronous Connection Limit To A Device Exceeded +0x0B ACL Connection Already Exists*/ +#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ +/*0x0D Connection Rejected due to Limited Resources +0x0E Connection Rejected Due To Security Reasons +0x0F Connection Rejected due to Unacceptable BD_ADDR +0x10 Connection Accept Timeout Exceeded +0x11 Unsupported Feature or Parameter Value*/ +#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ +#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ +#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ +/* +0x17 Repeated Attempts +0x18 Pairing Not Allowed +0x19 Unknown LMP PDU +*/ +#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ +/* +0x1B SCO Offset Rejected +0x1C SCO Interval Rejected +0x1D SCO Air Mode Rejected*/ +#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ +#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ +/*0x20 Unsupported LMP Parameter Value +0x21 Role Change Not Allowed +*/ +#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ +#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */ +#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ +/*0x25 Encryption Mode Not Acceptable +0x26 Link Key Can Not be Changed +0x27 Requested QoS Not Supported +*/ +#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ +#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ +#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ +/* +0x2B Reserved +0x2C QoS Unacceptable Parameter +0x2D QoS Rejected +0x2E Channel Classification Not Supported +0x2F Insufficient Security +*/ +#define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */ +/* +0x31 Reserved +0x32 Role Switch Pending +0x33 Reserved +0x34 Reserved Slot Violation +0x35 Role Switch Failed +0x36 Extended Inquiry Response Too Large +0x37 Secure Simple Pairing Not Supported By Host. +0x38 Host Busy - Pairing +0x39 Connection Rejected due to No Suitable Channel Found*/ +#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ +#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ +#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */ +#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ +#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif +#endif // BLE_HCI_H__ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_l2cap.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_l2cap.h new file mode 100644 index 0000000..edaf664 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_l2cap.h @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) + @{ + @brief Definitions and prototypes for the L2CAP interface. + */ + +#ifndef BLE_L2CAP_H__ +#define BLE_L2CAP_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology + * @{ + * @details + * + * L2CAP SDU + * - A data unit that the application can send/receive to/from a peer. + * + * L2CAP PDU + * - A data unit that is exchanged between local and remote L2CAP entities. + * It consists of L2CAP protocol control information and payload fields. + * The payload field can contain an L2CAP SDU or a part of an L2CAP SDU. + * + * L2CAP MTU + * - The maximum length of an L2CAP SDU. + * + * L2CAP MPS + * - The maximum length of an L2CAP PDU payload field. + * + * Credits + * - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer. + * @} */ + +/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations + * @{ */ + +/**@brief L2CAP API SVC numbers. */ +enum BLE_L2CAP_SVCS +{ + SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE + 0, /**< Set up an L2CAP channel. */ + SD_BLE_L2CAP_CH_RELEASE = BLE_L2CAP_SVC_BASE + 1, /**< Release an L2CAP channel. */ + SD_BLE_L2CAP_CH_RX = BLE_L2CAP_SVC_BASE + 2, /**< Receive an SDU on an L2CAP channel. */ + SD_BLE_L2CAP_CH_TX = BLE_L2CAP_SVC_BASE + 3, /**< Transmit an SDU on an L2CAP channel. */ + SD_BLE_L2CAP_CH_FLOW_CONTROL = BLE_L2CAP_SVC_BASE + 4, /**< Advanced SDU reception flow control. */ +}; + +/**@brief L2CAP Event IDs. */ +enum BLE_L2CAP_EVTS +{ + BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE + 0, /**< L2CAP Channel Setup Request event. + \n See @ref ble_l2cap_evt_ch_setup_request_t. */ + BLE_L2CAP_EVT_CH_SETUP_REFUSED = BLE_L2CAP_EVT_BASE + 1, /**< L2CAP Channel Setup Refused event. + \n See @ref ble_l2cap_evt_ch_setup_refused_t. */ + BLE_L2CAP_EVT_CH_SETUP = BLE_L2CAP_EVT_BASE + 2, /**< L2CAP Channel Setup Completed event. + \n See @ref ble_l2cap_evt_ch_setup_t. */ + BLE_L2CAP_EVT_CH_RELEASED = BLE_L2CAP_EVT_BASE + 3, /**< L2CAP Channel Released event. + \n No additional event structure applies. */ + BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED = BLE_L2CAP_EVT_BASE + 4, /**< L2CAP Channel SDU data buffer released event. + \n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */ + BLE_L2CAP_EVT_CH_CREDIT = BLE_L2CAP_EVT_BASE + 5, /**< L2CAP Channel Credit received. + \n See @ref ble_l2cap_evt_ch_credit_t. */ + BLE_L2CAP_EVT_CH_RX = BLE_L2CAP_EVT_BASE + 6, /**< L2CAP Channel SDU received. + \n See @ref ble_l2cap_evt_ch_rx_t. */ + BLE_L2CAP_EVT_CH_TX = BLE_L2CAP_EVT_BASE + 7, /**< L2CAP Channel SDU transmitted. + \n See @ref ble_l2cap_evt_ch_tx_t. */ +}; + +/** @} */ + +/**@addtogroup BLE_L2CAP_DEFINES Defines + * @{ */ + +/**@brief Maximum number of L2CAP channels per connection. */ +#define BLE_L2CAP_CH_COUNT_MAX (64) + +/**@brief Minimum L2CAP MTU, in bytes. */ +#define BLE_L2CAP_MTU_MIN (23) + +/**@brief Minimum L2CAP MPS, in bytes. */ +#define BLE_L2CAP_MPS_MIN (23) + +/**@brief Invalid CID. */ +#define BLE_L2CAP_CID_INVALID (0x0000) + +/**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */ +#define BLE_L2CAP_CREDITS_DEFAULT (1) + +/**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources + * @{ */ +#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */ +#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */ + /** @} */ + + /** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes + * @{ */ +#define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */ +#define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */ +#define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */ +#define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */ +#define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */ +#define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */ +#define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */ +#define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */ +/** @} */ + +/** @} */ + +/**@addtogroup BLE_L2CAP_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @note These parameters are set per connection, so all L2CAP channels created on this connection + * will have the same parameters. + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. + * - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. + * - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX. + * @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high. + */ +typedef struct +{ + uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall + be able to receive on L2CAP channels on connections with this + configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ + uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall + be able to transmit on L2CAP channels on connections with this + configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ + uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per + L2CAP channel. The minimum value is one. */ + uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission + per L2CAP channel. The minimum value is one. */ + uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection + with this configuration. The default value is zero, the maximum + value is @ref BLE_L2CAP_CH_COUNT_MAX. + @note if this parameter is set to zero, all other parameters in + @ref ble_l2cap_conn_cfg_t are ignored. */ +} ble_l2cap_conn_cfg_t; + +/**@brief L2CAP channel RX parameters. */ +typedef struct +{ + uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to + receive on this L2CAP channel. + - Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */ + uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be + able to receive on this L2CAP channel. + - Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN. + - Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */ + ble_data_t sdu_buf; /**< SDU data buffer for reception. + - If @ref ble_data_t::p_data is non-NULL, initial credits are + issued to the peer. + - If @ref ble_data_t::p_data is NULL, no initial credits are + issued to the peer. */ +} ble_l2cap_ch_rx_params_t; + +/**@brief L2CAP channel setup parameters. */ +typedef struct +{ + ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */ + uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting + setup of an L2CAP channel, ignored otherwise. */ + uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES. + Used when replying to a setup request of an L2CAP + channel, ignored otherwise. */ +} ble_l2cap_ch_setup_params_t; + +/**@brief L2CAP channel TX parameters. */ +typedef struct +{ + uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to + transmit on this L2CAP channel. */ + uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is + able to receive on this L2CAP channel. */ + uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able + to transmit on this L2CAP channel. This is effective tx_mps, + selected by the SoftDevice as + MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */ + uint16_t credits; /**< Initial credits given by the peer. */ +} ble_l2cap_ch_tx_params_t; + +/**@brief L2CAP Channel Setup Request event. */ +typedef struct +{ + ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ + uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */ +} ble_l2cap_evt_ch_setup_request_t; + +/**@brief L2CAP Channel Setup Refused event. */ +typedef struct +{ + uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */ + uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */ +} ble_l2cap_evt_ch_setup_refused_t; + +/**@brief L2CAP Channel Setup Completed event. */ +typedef struct +{ + ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ +} ble_l2cap_evt_ch_setup_t; + +/**@brief L2CAP Channel SDU Data Buffer Released event. */ +typedef struct +{ + ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice + returns SDU data buffers supplied by the application, which have + not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or + @ref BLE_L2CAP_EVT_CH_TX event. */ +} ble_l2cap_evt_ch_sdu_buf_released_t; + +/**@brief L2CAP Channel Credit received event. */ +typedef struct +{ + uint16_t credits; /**< Additional credits given by the peer. */ +} ble_l2cap_evt_ch_credit_t; + +/**@brief L2CAP Channel received SDU event. */ +typedef struct +{ + uint16_t sdu_len; /**< Total SDU length, in bytes. */ + ble_data_t sdu_buf; /**< SDU data buffer. + @note If there is not enough space in the buffer + (sdu_buf.len < sdu_len) then the rest of the SDU will be + silently discarded by the SoftDevice. */ +} ble_l2cap_evt_ch_rx_t; + +/**@brief L2CAP Channel transmitted SDU event. */ +typedef struct +{ + ble_data_t sdu_buf; /**< SDU data buffer. */ +} ble_l2cap_evt_ch_tx_t; + +/**@brief L2CAP event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which the event occured. */ + uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or + @ref BLE_L2CAP_CID_INVALID if not present. */ + union + { + ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */ + ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */ + ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */ + ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released;/**< L2CAP Channel SDU Data Buffer Released Event Parameters. */ + ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */ + ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */ + ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_l2cap_evt_t; + +/** @} */ + +/**@addtogroup BLE_L2CAP_FUNCTIONS Functions + * @{ */ + +/**@brief Set up an L2CAP channel. + * + * @details This function is used to: + * - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer. + * - Reply to a setup request of an L2CAP channel (if called in response to a + * @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection + * Response packet to a peer. + * + * @note A call to this function will require the application to keep the SDU data buffer alive + * until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or + * @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.} + * @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel: + * - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP + * channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST + * event when replying to a setup request of an L2CAP channel. + * - As output: local_cid for this channel. + * @param[in] p_params L2CAP channel parameters. + * + * @retval ::NRF_SUCCESS Successfully queued request or response for transmission. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels, + * see @ref ble_l2cap_conn_cfg_t::ch_count. + */ +SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params)); + +/**@brief Release an L2CAP channel. + * + * @details This sends a Disconnection Request packet to a peer. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * + * @retval ::NRF_SUCCESS Successfully queued request for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for the L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + */ +SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid)); + +/**@brief Receive an SDU on an L2CAP channel. + * + * @details This may issue additional credits to the peer using an LE Flow Control Credit packet. + * + * @note A call to this function will require the application to keep the memory pointed by + * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX + * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers + * for reception per L2CAP channel. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_RX_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * @param[in] p_sdu_buf Pointer to the SDU data buffer. + * + * @retval ::NRF_SUCCESS Buffer accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for an L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a + * @ref BLE_L2CAP_EVT_CH_RX event and retry. + */ +SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); + +/**@brief Transmit an SDU on an L2CAP channel. + * + * @note A call to this function will require the application to keep the memory pointed by + * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX + * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for + * transmission per L2CAP channel. + * + * @note The application can keep track of the available credits for transmission by following + * the procedure below: + * - Store initial credits given by the peer in a variable. + * (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) + * - Decrement the variable, which stores the currently available credits, by + * ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns + * @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) + * - Increment the variable, which stores the currently available credits, by additional + * credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_TX_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * @param[in] p_sdu_buf Pointer to the SDU data buffer. + * + * @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for the L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than + * @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in + * @ref BLE_L2CAP_EVT_CH_SETUP event. + * @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a + * @ref BLE_L2CAP_EVT_CH_TX event and retry. + */ +SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); + +/**@brief Advanced SDU reception flow control. + * + * @details Adjust the way the SoftDevice issues credits to the peer. + * This may issue additional credits to the peer using an LE Flow Control Credit packet. + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set + * the value that will be used for newly created channels. + * @param[in] credits Number of credits that the SoftDevice will make sure the peer has every + * time it starts using a new reception buffer. + * - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will + * use if this function is not called. + * - If set to zero, the SoftDevice will stop issuing credits for new reception + * buffers the application provides or has provided. SDU reception that is + * currently ongoing will be allowed to complete. + * @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be + * written by the SoftDevice with the number of credits that is or will be + * available to the peer. If the value written by the SoftDevice is 0 when + * credits parameter was set to 0, the peer will not be able to send more + * data until more credits are provided by calling this function again with + * credits > 0. This parameter is ignored when local_cid is set to + * @ref BLE_L2CAP_CID_INVALID. + * + * @note Application should take care when setting number of credits higher than default value. In + * this case the application must make sure that the SoftDevice always has reception buffers + * available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have + * such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic + * on the connection handle may be stalled until the SoftDevice again has an available + * reception buffer. This applies even if the application has used this call to set the + * credits back to default, or zero. + * + * @retval ::NRF_SUCCESS Flow control parameters accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for an L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + */ +SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_L2CAP_H__ + +/** + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_ranges.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_ranges.h new file mode 100644 index 0000000..0935bca --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_ranges.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_COMMON + @{ + @defgroup ble_ranges Module specific SVC, event and option number subranges + @{ + + @brief Definition of SVC, event and option number subranges for each API module. + + @note + SVCs, event and option numbers are split into subranges for each API module. + Each module receives its entire allocated range of SVC calls, whether implemented or not, + but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. + + Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, + rather than the last SVC function call actually defined and implemented. + + Specific SVC, event and option values are defined in each module's ble_.h file, + which defines names of each individual SVC code based on the range start value. +*/ + +#ifndef BLE_RANGES_H__ +#define BLE_RANGES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ +#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */ + +#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */ +#define BLE_GAP_SVC_LAST 0x9A /**< GAP BLE SVC last. */ + +#define BLE_GATTC_SVC_BASE 0x9B /**< GATTC BLE SVC base. */ +#define BLE_GATTC_SVC_LAST 0xA7 /**< GATTC BLE SVC last. */ + +#define BLE_GATTS_SVC_BASE 0xA8 /**< GATTS BLE SVC base. */ +#define BLE_GATTS_SVC_LAST 0xB7 /**< GATTS BLE SVC last. */ + +#define BLE_L2CAP_SVC_BASE 0xB8 /**< L2CAP BLE SVC base. */ +#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */ + + +#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ + +#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ +#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */ + +#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ +#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */ + +#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ +#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */ + +#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ +#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */ + +#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ +#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */ + + +#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ + +#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ +#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */ + +#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ +#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */ + +#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */ +#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */ + +#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */ +#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */ + +#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */ +#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */ + +#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */ +#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */ + + +#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */ + +#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */ +#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */ + +#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */ +#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */ + +#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */ +#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */ + +#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */ +#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */ + +#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */ +#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */ + +#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */ +#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */ + +#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */ +#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */ + + + + + +#ifdef __cplusplus +} +#endif +#endif /* BLE_RANGES_H__ */ + +/** + @} + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_types.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_types.h new file mode 100644 index 0000000..88c9318 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_types.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup BLE_COMMON + @{ + @defgroup ble_types Common types and macro definitions + @{ + + @brief Common types and macro definitions for the BLE SoftDevice. + */ + +#ifndef BLE_TYPES_H__ +#define BLE_TYPES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_TYPES_DEFINES Defines + * @{ */ + +/** @defgroup BLE_CONN_HANDLES BLE Connection Handles + * @{ */ +#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ +#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ +/** @} */ + + +/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs + * @{ */ +/* Generic UUIDs, applicable to all services */ +#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ +#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ +#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ +#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ +#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ +#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ +/* GATT specific UUIDs */ +#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ +#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ +/* GAP specific UUIDs */ +#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ +#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */ +/** @} */ + + +/** @defgroup BLE_UUID_TYPES Types of UUID + * @{ */ +#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ +#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ +#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ +/** @} */ + + +/** @defgroup BLE_APPEARANCES Bluetooth Appearance values + * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml + * @{ */ +#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ +#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ +#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ +#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ +#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ +#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ +#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ +#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ +#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ +#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ +#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ +#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ +#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ +#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ +#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ +#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ +#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ +#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ +#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ +#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ +#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ +#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */ +#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ +#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ +#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ +#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ +#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ +#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ +#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ +#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ +#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ +#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ +#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ +#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ +#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ +#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ +/** @} */ + +/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */ +#define BLE_UUID_BLE_ASSIGN(instance, value) do {\ + instance.type = BLE_UUID_TYPE_BLE; \ + instance.uuid = value;} while(0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ +#define BLE_UUID_COPY_PTR(dst, src) do {\ + (dst)->type = (src)->type; \ + (dst)->uuid = (src)->uuid;} while(0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ +#define BLE_UUID_COPY_INST(dst, src) do {\ + (dst).type = (src).type; \ + (dst).uuid = (src).uuid;} while(0) + +/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_EQ(p_uuid1, p_uuid2) \ + (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) + +/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \ + (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) + +/** @} */ + +/** @addtogroup BLE_TYPES_STRUCTURES Structures + * @{ */ + +/** @brief 128 bit UUID values. */ +typedef struct +{ + uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ +} ble_uuid128_t; + +/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ +typedef struct +{ + uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ + uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ +} ble_uuid_t; + +/**@brief Data structure. */ +typedef struct +{ + uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */ + uint16_t len; /**< Length of the data buffer, in bytes. */ +} ble_data_t; + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* BLE_TYPES_H__ */ + +/** + @} + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf52/nrf_mbr.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf52/nrf_mbr.h new file mode 100644 index 0000000..42e09fc --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf52/nrf_mbr.h @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 nrf_mbr_api Master Boot Record API + @{ + + @brief APIs for updating SoftDevice and BootLoader + +*/ + +#ifndef NRF_MBR_H__ +#define NRF_MBR_H__ + +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_MBR_DEFINES Defines + * @{ */ + +/**@brief MBR SVC Base number. */ +#define MBR_SVC_BASE (0x18) + +/**@brief Page size in words. */ +#define MBR_PAGE_SIZE_IN_WORDS (1024) + +/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash. +This is the offset where the first byte of the SoftDevice hex file is written. */ +#define MBR_SIZE (0x1000) + +/** @brief Location (in the flash memory) of the bootloader address. */ +#define MBR_BOOTLOADER_ADDR (0xFF8) + +/** @brief Location (in UICR) of the bootloader address. */ +#define MBR_UICR_BOOTLOADER_ADDR (&(NRF_UICR->NRFFW[0])) + +/** @brief Location (in the flash memory) of the address of the MBR parameter page. */ +#define MBR_PARAM_PAGE_ADDR (0xFFC) + +/** @brief Location (in UICR) of the address of the MBR parameter page. */ +#define MBR_UICR_PARAM_PAGE_ADDR (&(NRF_UICR->NRFFW[1])) + + +/** @} */ + +/** @addtogroup NRF_MBR_ENUMS Enumerations + * @{ */ + +/**@brief nRF Master Boot Record API SVC numbers. */ +enum NRF_MBR_SVCS +{ + SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ +}; + +/**@brief Possible values for ::sd_mbr_command_t.command */ +enum NRF_MBR_COMMANDS +{ + SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/ + SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ + SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/ + SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ + SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/ + SD_MBR_COMMAND_RESERVED, + SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/ +}; + +/** @} */ + +/** @addtogroup NRF_MBR_TYPES Types + * @{ */ + +/**@brief This command copies part of a new SoftDevice + * + * The destination area is erased before copying. + * If dst is in the middle of a flash page, that whole flash page will be erased. + * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. + * + * The user of this function is responsible for setting the BPROT registers. + * + * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. + * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + */ +typedef struct +{ + uint32_t *src; /**< Pointer to the source of data to be copied.*/ + uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ + uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/ +} sd_mbr_command_copy_sd_t; + + +/**@brief This command works like memcmp, but takes the length in words. + * + * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. + * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. + */ +typedef struct +{ + uint32_t *ptr1; /**< Pointer to block of memory. */ + uint32_t *ptr2; /**< Pointer to block of memory. */ + uint32_t len; /**< Number of 32 bit words to compare.*/ +} sd_mbr_command_compare_t; + + +/**@brief This command copies a new BootLoader. + * + * The MBR assumes that either @ref MBR_BOOTLOADER_ADDR or @ref MBR_UICR_BOOTLOADER_ADDR is set to + * the address where the bootloader will be copied. If both addresses are set, the MBR will prioritize + * @ref MBR_BOOTLOADER_ADDR. + * + * The bootloader destination is erased by this function. + * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. + * + * This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set, + * see @ref sd_mbr_command. + * + * This command will use the flash protect peripheral (BPROT or ACL) to protect the flash that is + * not intended to be written. + * + * On success, this function will not return. It will start the new bootloader from reset-vector as normal. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_FORBIDDEN if the bootloader address is not set. + * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. + * @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command. + */ +typedef struct +{ + uint32_t *bl_src; /**< Pointer to the source of the bootloader to be be copied.*/ + uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ +} sd_mbr_command_copy_bl_t; + +/**@brief Change the address the MBR starts after a reset + * + * Once this function has been called, this address is where the MBR will start to forward + * interrupts to after a reset. + * + * To restore default forwarding, this function should be called with @ref address set to 0. If a + * bootloader is present, interrupts will be forwarded to the bootloader. If not, interrupts will + * be forwarded to the SoftDevice. + * + * The location of a bootloader can be specified in @ref MBR_BOOTLOADER_ADDR or + * @ref MBR_UICR_BOOTLOADER_ADDR. If both addresses are set, the MBR will prioritize + * @ref MBR_BOOTLOADER_ADDR. + * + * This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set, + * see @ref sd_mbr_command. + * + * On success, this function will not return. It will reset the device. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. + * @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command. + */ +typedef struct +{ + uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ +} sd_mbr_command_vector_table_base_set_t; + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR + * + * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not + * change where the MBR starts after reset. + * + * @retval ::NRF_SUCCESS + */ +typedef struct +{ + uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ +} sd_mbr_command_irq_forward_address_set_t; + +/**@brief Input structure containing data used when calling ::sd_mbr_command + * + * Depending on what command value that is set, the corresponding params value type must also be + * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command + * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params. + */ +typedef struct +{ + uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */ + union + { + sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ + sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ + sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ + sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ + sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/ + } params; /**< Command parameters. */ +} sd_mbr_command_t; + +/** @} */ + +/** @addtogroup NRF_MBR_FUNCTIONS Functions + * @{ */ + +/**@brief Issue Master Boot Record commands + * + * Commands used when updating a SoftDevice and bootloader. + * + * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires + * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash + * page. The location of the flash page should be provided by the application in either + * @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR. If both addresses are set, the MBR + * will prioritize @ref MBR_PARAM_PAGE_ADDR. This page will be cleared by the MBR and is used to + * store the command before reset. When an address is specified, the page it refers to must not be + * used by the application. If no address is provided by the application, i.e. both + * @ref MBR_PARAM_PAGE_ADDR and @ref MBR_UICR_PARAM_PAGE_ADDR is 0xFFFFFFFF, MBR commands which use + * flash will be unavailable and return @ref NRF_ERROR_NO_MEM. + * + * @param[in] param Pointer to a struct describing the command. + * + * @note For a complete set of return values, see ::sd_mbr_command_copy_sd_t, + * ::sd_mbr_command_copy_bl_t, ::sd_mbr_command_compare_t, + * ::sd_mbr_command_vector_table_base_set_t, ::sd_mbr_command_irq_forward_address_set_t + * + * @retval ::NRF_ERROR_NO_MEM No MBR parameter page provided + * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given. +*/ +SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_MBR_H__ + +/** + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error.h new file mode 100644 index 0000000..6badee9 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 nrf_error SoftDevice Global Error Codes + @{ + + @brief Global Error definitions +*/ + +/* Header guard */ +#ifndef NRF_ERROR_H__ +#define NRF_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions + * @{ */ +#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base +#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base +#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base +#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base +/** @} */ + +#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command +#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing +#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled +#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error +#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation +#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found +#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported +#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter +#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state +#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length +#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags +#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data +#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size +#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out +#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer +#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation +#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address +#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy +#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. +#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_H__ + +/** + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_sdm.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_sdm.h new file mode 100644 index 0000000..530959b --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_sdm.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + + /** + @addtogroup nrf_sdm_api + @{ + @defgroup nrf_sdm_error SoftDevice Manager Error Codes + @{ + + @brief Error definitions for the SDM API +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SDM_H__ +#define NRF_ERROR_SDM_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source. +#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). +#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SDM_H__ + +/** + @} + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_soc.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_soc.h new file mode 100644 index 0000000..1e784b8 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_soc.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + */ + +/** + @addtogroup nrf_soc_api + @{ + @defgroup nrf_soc_error SoC Library Error Codes + @{ + + @brief Error definitions for the SoC library + +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SOC_H__ +#define NRF_ERROR_SOC_H__ + +#include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Mutex Errors */ +#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken + +/* NVIC errors */ +#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available +#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed +#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return + +/* Power errors */ +#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown +#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown +#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return + +/* Rand errors */ +#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values + +/* PPI errors */ +#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel +#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SOC_H__ +/** + @} + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_nvic.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_nvic.h new file mode 100644 index 0000000..1f79cc3 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_nvic.h @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 nrf_nvic_api SoftDevice NVIC API + * @{ + * + * @note In order to use this module, the following code has to be added to a .c file: + * \code + * nrf_nvic_state_t nrf_nvic_state = {0}; + * \endcode + * + * @note Definitions and declarations starting with __ (double underscore) in this header file are + * not intended for direct use by the application. + * + * @brief APIs for the accessing NVIC when using a SoftDevice. + * + */ + +#ifndef NRF_NVIC_H__ +#define NRF_NVIC_H__ + +#include +#include "nrf.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_NVIC_DEFINES Defines + * @{ */ + +/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions + * @{ */ + +#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */ + +#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ + +/**@brief Interrupt priority levels used by the SoftDevice. */ +#define __NRF_NVIC_SD_IRQ_PRIOS ((uint8_t)( \ + (1U << 0) /**< Priority level high .*/ \ + | (1U << 1) /**< Priority level medium. */ \ + | (1U << 4) /**< Priority level low. */ \ + )) + +/**@brief Interrupt priority levels available to the application. */ +#define __NRF_NVIC_APP_IRQ_PRIOS ((uint8_t)~__NRF_NVIC_SD_IRQ_PRIOS) + +/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */ +#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI5_IRQn) \ + )) + +/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */ +#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) + +/**@brief Interrupts available for to application, with IRQn in the range 0-31. */ +#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) + +/**@brief Interrupts available for to application, with IRQn in the range 32-63. */ +#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) + +/**@} */ + +/**@} */ + +/**@addtogroup NRF_NVIC_VARIABLES Variables + * @{ */ + +/**@brief Type representing the state struct for the SoftDevice NVIC module. */ +typedef struct +{ + uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ + uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ +} nrf_nvic_state_t; + +/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an + * application source file. */ +extern nrf_nvic_state_t nrf_nvic_state; + +/**@} */ + +/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions + * @{ */ + +/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. + * + * @retval The value of PRIMASK prior to disabling the interrupts. + */ +__STATIC_INLINE int __sd_nvic_irq_disable(void); + +/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. + */ +__STATIC_INLINE void __sd_nvic_irq_enable(void); + +/**@brief Checks if IRQn is available to application + * @param[in] IRQn IRQ to check + * + * @retval 1 (true) if the IRQ to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn); + +/**@brief Checks if priority is available to application + * @param[in] priority priority to check + * + * @retval 1 (true) if the priority to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority); + +/**@} */ + +/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions + * @{ */ + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * @pre Priority is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority); + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void); + +/**@brief Enter critical region. + * + * @post Application interrupts will be disabled. + * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each + * execution context + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); + +/**@} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE int __sd_nvic_irq_disable(void) +{ + int pm = __get_PRIMASK(); + __disable_irq(); + return pm; +} + +__STATIC_INLINE void __sd_nvic_irq_enable(void) +{ + __enable_irq(); +} + +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) +{ + if (IRQn < 32) + { + return ((1UL<= (1 << __NVIC_PRIO_BITS)) + || (((1 << priority) & __NRF_NVIC_APP_IRQ_PRIOS) == 0) + ) + { + return 0; + } + return 1; +} + + +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); + } + else + { + NVIC_EnableIRQ(IRQn); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F)); + } + else + { + NVIC_DisableIRQ(IRQn); + } + + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (!__sd_nvic_is_app_accessible_priority(priority)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + NVIC_SetPriority(IRQn, (uint32_t)priority); + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) +{ + int was_masked = __sd_nvic_irq_disable(); + if (!nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__cr_flag = 1; + nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); + NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; + nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); + NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; + *p_is_nested_critical_region = 0; + } + else + { + *p_is_nested_critical_region = 1; + } + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) + { + int was_masked = __sd_nvic_irq_disable(); + NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; + NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; + nrf_nvic_state.__cr_flag = 0; + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + } + + return NRF_SUCCESS; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_NVIC_H__ + +/**@} */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_sdm.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_sdm.h new file mode 100644 index 0000000..5dfbb28 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_sdm.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 nrf_sdm_api SoftDevice Manager API + @{ + + @brief APIs for SoftDevice management. + +*/ + +#ifndef NRF_SDM_H__ +#define NRF_SDM_H__ + +#include +#include "nrf.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "nrf_error_sdm.h" +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ +#ifdef NRFSOC_DOXYGEN +/// Declared in nrf_mbr.h +#define MBR_SIZE 0 +#warning test +#endif + +/** @brief The major version for the SoftDevice binary distributed with this header file. */ +#define SD_MAJOR_VERSION (6) + +/** @brief The minor version for the SoftDevice binary distributed with this header file. */ +#define SD_MINOR_VERSION (1) + +/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ +#define SD_BUGFIX_VERSION (1) + +/** @brief The SoftDevice variant of this firmware. */ +#define SD_VARIANT_ID 140 + +/** @brief The full version number for the SoftDevice binary this header file was distributed + * with, as a decimal number in the form Mmmmbbb, where: + * - M is major version (one or more digits) + * - mmm is minor version (three digits) + * - bbb is bugfix version (three digits). */ +#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION) + +/** @brief SoftDevice Manager SVC Base number. */ +#define SDM_SVC_BASE 0x10 + +/** @brief SoftDevice unique string size in bytes. */ +#define SD_UNIQUE_STR_SIZE 20 + +/** @brief Invalid info field. Returned when an info field does not exist. */ +#define SDM_INFO_FIELD_INVALID (0) + +/** @brief Defines the SoftDevice Information Structure location (address) as an offset from +the start of the SoftDevice (without MBR)*/ +#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) + +/** @brief Defines the absolute SoftDevice Information Structure location (address) when the + * SoftDevice is installed just above the MBR (the usual case). */ +#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) + +/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the + * SoftDevice base address. The size value is of type uint8_t. */ +#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET) + +/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address. + * The size value is of type uint32_t. */ +#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) + +/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value + * is of type uint16_t. */ +#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) + +/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID + * is of type uint32_t. */ +#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) + +/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in + * the same format as @ref SD_VERSION, stored as an uint32_t. */ +#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) + +/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address. + * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE. + */ +#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18) + +/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value + * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is + * installed just above the MBR (the usual case). */ +#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base + * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above + * the MBR (the usual case). */ +#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) + +/** @brief Defines the amount of flash that is used by the SoftDevice. + * Add @ref MBR_SIZE to find the first available flash address when the SoftDevice is installed + * just above the MBR (the usual case). + */ +#define SD_FLASH_SIZE 0x25000 + +/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the + * usual case). */ +#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address. + * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR + * (the usual case). */ +#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address. + * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR + * (the usual case). */ +#define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges + * @{ */ +#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ +#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ +/**@} */ + +/**@defgroup NRF_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */ +#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000, + in case of SoftDevice RAM access violation. In case of SoftDevice peripheral + register violation the info parameter will contain the sub-region number of + PREGION[0], on whose address range the disallowed write access caused the + memory access fault. */ +/**@} */ + +/** @} */ + +/** @addtogroup NRF_SDM_ENUMS Enumerations + * @{ */ + +/**@brief nRF SoftDevice Manager API SVC numbers. */ +enum NRF_SD_SVCS +{ + SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ + SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ + SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ + SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ + SVC_SDM_LAST /**< Placeholder for last SDM SVC */ +}; + +/** @} */ + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ + +/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy + * @{ */ + +#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ +#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */ +#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */ +#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */ +#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */ +#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */ +#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */ +#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */ +#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */ +#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */ +#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */ +#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */ + +/** @} */ + +/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources + * @{ */ + +#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ +#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ +#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ + +/** @} */ + +/** @} */ + +/** @addtogroup NRF_SDM_TYPES Types + * @{ */ + +/**@brief Type representing LFCLK oscillator source. */ +typedef struct +{ + uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ + uint8_t rc_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second + units (nRF52: 1-32). + @note To avoid excessive clock drift, 0.5 degrees Celsius is the + maximum temperature change allowed in one calibration timer + interval. The interval should be selected to ensure this. + + @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. */ + uint8_t rc_temp_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration + intervals) the RC oscillator shall be calibrated if the temperature + hasn't changed. + 0: Always calibrate even if the temperature hasn't changed. + 1: Only calibrate if the temperature has changed (legacy - nRF51 only). + 2-33: Check the temperature and only calibrate if it has changed, + however calibration will take place every rc_temp_ctiv + intervals in any case. + + @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. + + @note For nRF52, the application must ensure calibration at least once + every 8 seconds to ensure +/-500 ppm clock stability. The + recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is + rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at + least once every 8 seconds and for temperature changes of 0.5 + degrees Celsius every 4 seconds. See the Product Specification + for the nRF52 device being used for more information.*/ + uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing + windows, see @ref NRF_CLOCK_LF_ACCURACY.*/ +} nrf_clock_lf_cfg_t; + +/**@brief Fault Handler type. + * + * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. + * The protocol stack will be in an undefined state when this happens and the only way to recover will be to + * perform a reset, using e.g. CMSIS NVIC_SystemReset(). + * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset(). + * + * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. + * + * @note When id is set to @ref NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when + * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault. + */ +typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); + +/** @} */ + +/** @addtogroup NRF_SDM_FUNCTIONS Functions + * @{ */ + +/**@brief Enables the SoftDevice and by extension the protocol stack. + * + * @note Some care must be taken if a low frequency clock source is already running when calling this function: + * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new + * clock source will be started. + * + * @note This function has no effect when returning with an error. + * + * @post If return code is ::NRF_SUCCESS + * - SoC library and protocol stack APIs are made available. + * - A portion of RAM will be unavailable (see relevant SDS documentation). + * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). + * - Interrupts will not arrive from protected peripherals or interrupts. + * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. + * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). + * - Chosen low frequency clock source will be running. + * + * @param p_clock_lf_cfg Low frequency clock source and accuracy. + If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2 + In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock. + * @param fault_handler Callback to be invoked in case of fault, cannot be NULL. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. + * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level. + * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg. + */ +SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); + + +/**@brief Disables the SoftDevice and by extension the protocol stack. + * + * Idempotent function to disable the SoftDevice. + * + * @post SoC library and protocol stack APIs are made unavailable. + * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). + * @post All peripherals used by the SoftDevice will be reset to default values. + * @post All of RAM become available. + * @post All interrupts are forwarded to the application. + * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); + +/**@brief Check if the SoftDevice is enabled. + * + * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice + * + * This function is only intended to be called when a bootloader is enabled. + * + * @param[in] address The base address of the interrupt vector table for forwarded interrupts. + + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SDM_H__ + +/** + @} +*/ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_soc.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_soc.h new file mode 100644 index 0000000..beb4d3a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_soc.h @@ -0,0 +1,1079 @@ +/* + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 nrf_soc_api SoC Library API + * @{ + * + * @brief APIs for the SoC library. + * + */ + +#ifndef NRF_SOC_H__ +#define NRF_SOC_H__ + +#include +#include "nrf.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_SOC_DEFINES Defines + * @{ */ + +/**@brief The number of the lowest SVC number reserved for the SoC library. */ +#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ +#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ + +/**@brief Guaranteed time for application to process radio inactive notification. */ +#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) + +/**@brief The minimum allowed timeslot extension time. */ +#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) + +/**@brief The maximum processing time to handle a timeslot extension. */ +#define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (17) + +/**@brief The latest time before the end of a timeslot the timeslot can be extended. */ +#define NRF_RADIO_MIN_EXTENSION_MARGIN_US (79) + +#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ +#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ +#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ + +#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. + The default interrupt priority for this handler is set to 6 */ +#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. + The default interrupt priority for this handler is set to 6 */ +#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ +#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ + +#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ + +#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ + +#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ + +/**@brief Mask of PPI channels reserved by the SoftDevice when the SoftDevice is disabled. */ +#define NRF_SOC_SD_PPI_CHANNELS_SD_DISABLED_MSK ((uint32_t)(0)) + +/**@brief Mask of PPI channels reserved by the SoftDevice when the SoftDevice is enabled. */ +#define NRF_SOC_SD_PPI_CHANNELS_SD_ENABLED_MSK ((uint32_t)( \ + (1U << 17) \ + | (1U << 18) \ + | (1U << 19) \ + | (1U << 20) \ + | (1U << 21) \ + | (1U << 22) \ + | (1U << 23) \ + | (1U << 24) \ + | (1U << 25) \ + | (1U << 26) \ + | (1U << 27) \ + | (1U << 28) \ + | (1U << 29) \ + | (1U << 30) \ + | (1U << 31) \ + )) + +/**@brief Mask of PPI channels available to the application when the SoftDevice is disabled. */ +#define NRF_SOC_APP_PPI_CHANNELS_SD_DISABLED_MSK (~NRF_SOC_SD_PPI_CHANNELS_SD_DISABLED_MSK) + +/**@brief Mask of PPI channels available to the application when the SoftDevice is enabled. */ +#define NRF_SOC_APP_PPI_CHANNELS_SD_ENABLED_MSK (~NRF_SOC_SD_PPI_CHANNELS_SD_ENABLED_MSK) + +/**@brief Mask of PPI groups reserved by the SoftDevice when the SoftDevice is disabled. */ +#define NRF_SOC_SD_PPI_GROUPS_SD_DISABLED_MSK ((uint32_t)(0)) + +/**@brief Mask of PPI groups reserved by the SoftDevice when the SoftDevice is enabled. */ +#define NRF_SOC_SD_PPI_GROUPS_SD_ENABLED_MSK ((uint32_t)( \ + (1U << 4) \ + | (1U << 5) \ + )) + +/**@brief Mask of PPI groups available to the application when the SoftDevice is disabled. */ +#define NRF_SOC_APP_PPI_GROUPS_SD_DISABLED_MSK (~NRF_SOC_SD_PPI_GROUPS_SD_DISABLED_MSK) + +/**@brief Mask of PPI groups available to the application when the SoftDevice is enabled. */ +#define NRF_SOC_APP_PPI_GROUPS_SD_ENABLED_MSK (~NRF_SOC_SD_PPI_GROUPS_SD_ENABLED_MSK) + +/**@} */ + +/**@addtogroup NRF_SOC_ENUMS Enumerations + * @{ */ + +/**@brief The SVC numbers used by the SVC functions in the SoC library. */ +enum NRF_SOC_SVCS +{ + SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, + SD_PPI_CHANNEL_ENABLE_SET = SOC_SVC_BASE + 1, + SD_PPI_CHANNEL_ENABLE_CLR = SOC_SVC_BASE + 2, + SD_PPI_CHANNEL_ASSIGN = SOC_SVC_BASE + 3, + SD_PPI_GROUP_TASK_ENABLE = SOC_SVC_BASE + 4, + SD_PPI_GROUP_TASK_DISABLE = SOC_SVC_BASE + 5, + SD_PPI_GROUP_ASSIGN = SOC_SVC_BASE + 6, + SD_PPI_GROUP_GET = SOC_SVC_BASE + 7, + SD_FLASH_PAGE_ERASE = SOC_SVC_BASE + 8, + SD_FLASH_WRITE = SOC_SVC_BASE + 9, + SD_PROTECTED_REGISTER_WRITE = SOC_SVC_BASE + 11, + SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, + SD_MUTEX_ACQUIRE = SOC_SVC_BASE_NOT_AVAILABLE + 1, + SD_MUTEX_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 2, + SD_RAND_APPLICATION_POOL_CAPACITY_GET = SOC_SVC_BASE_NOT_AVAILABLE + 3, + SD_RAND_APPLICATION_BYTES_AVAILABLE_GET = SOC_SVC_BASE_NOT_AVAILABLE + 4, + SD_RAND_APPLICATION_VECTOR_GET = SOC_SVC_BASE_NOT_AVAILABLE + 5, + SD_POWER_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 6, + SD_POWER_SYSTEM_OFF = SOC_SVC_BASE_NOT_AVAILABLE + 7, + SD_POWER_RESET_REASON_GET = SOC_SVC_BASE_NOT_AVAILABLE + 8, + SD_POWER_RESET_REASON_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 9, + SD_POWER_POF_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 10, + SD_POWER_POF_THRESHOLD_SET = SOC_SVC_BASE_NOT_AVAILABLE + 11, + SD_POWER_POF_THRESHOLDVDDH_SET = SOC_SVC_BASE_NOT_AVAILABLE + 12, + SD_POWER_RAM_POWER_SET = SOC_SVC_BASE_NOT_AVAILABLE + 13, + SD_POWER_RAM_POWER_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 14, + SD_POWER_RAM_POWER_GET = SOC_SVC_BASE_NOT_AVAILABLE + 15, + SD_POWER_GPREGRET_SET = SOC_SVC_BASE_NOT_AVAILABLE + 16, + SD_POWER_GPREGRET_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 17, + SD_POWER_GPREGRET_GET = SOC_SVC_BASE_NOT_AVAILABLE + 18, + SD_POWER_DCDC_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 19, + SD_POWER_DCDC0_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 20, + SD_APP_EVT_WAIT = SOC_SVC_BASE_NOT_AVAILABLE + 21, + SD_CLOCK_HFCLK_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 22, + SD_CLOCK_HFCLK_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 23, + SD_CLOCK_HFCLK_IS_RUNNING = SOC_SVC_BASE_NOT_AVAILABLE + 24, + SD_RADIO_NOTIFICATION_CFG_SET = SOC_SVC_BASE_NOT_AVAILABLE + 25, + SD_ECB_BLOCK_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 26, + SD_ECB_BLOCKS_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 27, + SD_RADIO_SESSION_OPEN = SOC_SVC_BASE_NOT_AVAILABLE + 28, + SD_RADIO_SESSION_CLOSE = SOC_SVC_BASE_NOT_AVAILABLE + 29, + SD_RADIO_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 30, + SD_EVT_GET = SOC_SVC_BASE_NOT_AVAILABLE + 31, + SD_TEMP_GET = SOC_SVC_BASE_NOT_AVAILABLE + 32, + SD_POWER_USBPWRRDY_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 33, + SD_POWER_USBDETECTED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 34, + SD_POWER_USBREMOVED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 35, + SD_POWER_USBREGSTATUS_GET = SOC_SVC_BASE_NOT_AVAILABLE + 36, + SVC_SOC_LAST = SOC_SVC_BASE_NOT_AVAILABLE + 37 +}; + +/**@brief Possible values of a ::nrf_mutex_t. */ +enum NRF_MUTEX_VALUES +{ + NRF_MUTEX_FREE, + NRF_MUTEX_TAKEN +}; + +/**@brief Power modes. */ +enum NRF_POWER_MODES +{ + NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ + NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ +}; + + +/**@brief Power failure thresholds */ +enum NRF_POWER_THRESHOLDS +{ + NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */ +}; + +/**@brief Power failure thresholds for high voltage */ +enum NRF_POWER_THRESHOLDVDDHS +{ + NRF_POWER_THRESHOLDVDDH_V27, /**< 2.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V28, /**< 2.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V29, /**< 2.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V30, /**< 3.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V31, /**< 3.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V32, /**< 3.2 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V33, /**< 3.3 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V34, /**< 3.4 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V35, /**< 3.5 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V36, /**< 3.6 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V37, /**< 3.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V38, /**< 3.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V39, /**< 3.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V40, /**< 4.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V41, /**< 4.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V42 /**< 4.2 Volts power failure threshold. */ +}; + + +/**@brief DC/DC converter modes. */ +enum NRF_POWER_DCDC_MODES +{ + NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ + NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ +}; + +/**@brief Radio notification distances. */ +enum NRF_RADIO_NOTIFICATION_DISTANCES +{ + NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ + NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ +}; + + +/**@brief Radio notification types. */ +enum NRF_RADIO_NOTIFICATION_TYPES +{ + NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ +}; + +/**@brief The Radio signal callback types. */ +enum NRF_RADIO_CALLBACK_SIGNAL_TYPE +{ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ +}; + +/**@brief The actions requested by the signal callback. + * + * This code gives the SOC instructions about what action to take when the signal callback has + * returned. + */ +enum NRF_RADIO_SIGNAL_CALLBACK_ACTION +{ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current + timeslot. Maximum execution time for this action: + @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US. + This action must be started at least + @ref NRF_RADIO_MIN_EXTENSION_MARGIN_US before + the end of the timeslot. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ +}; + +/**@brief Radio timeslot high frequency clock source configuration. */ +enum NRF_RADIO_HFCLK_CFG +{ + NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the + external crystal for the whole duration of the timeslot. This should be the + preferred option for events that use the radio or require high timing accuracy. + @note The SoftDevice will automatically turn on and off the external crystal, + at the beginning and end of the timeslot, respectively. The crystal may also + intentionally be left running after the timeslot, in cases where it is needed + by the SoftDevice shortly after the end of the timeslot. */ + NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. + The RC oscillator may be the clock source in part or for the whole duration of the timeslot. + The RC oscillator's accuracy must therefore be taken into consideration. + @note If the application will use the radio peripheral in timeslots with this configuration, + it must make sure that the crystal is running and stable before starting the radio. */ +}; + +/**@brief Radio timeslot priorities. */ +enum NRF_RADIO_PRIORITY +{ + NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ + NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */ +}; + +/**@brief Radio timeslot request type. */ +enum NRF_RADIO_REQUEST_TYPE +{ + NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */ + NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ +}; + +/**@brief SoC Events. */ +enum NRF_SOC_EVTS +{ + NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ + NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ + NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ + NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ + NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ + NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ + NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */ + NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ + NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ + NRF_EVT_POWER_USB_POWER_READY, /**< Event indicating that a USB 3.3 V supply is ready. */ + NRF_EVT_POWER_USB_DETECTED, /**< Event indicating that voltage supply is detected on VBUS. */ + NRF_EVT_POWER_USB_REMOVED, /**< Event indicating that voltage supply is removed from VBUS. */ + NRF_EVT_NUMBER_OF_EVTS +}; + +/**@} */ + + +/**@addtogroup NRF_SOC_STRUCTURES Structures + * @{ */ + +/**@brief Represents a mutex for use with the nrf_mutex functions. + * @note Accessing the value directly is not safe, use the mutex functions! + */ +typedef volatile uint8_t nrf_mutex_t; + +/**@brief Parameters for a request for a timeslot as early as possible. */ +typedef struct +{ + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ + uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ +} nrf_radio_request_earliest_t; + +/**@brief Parameters for a normal radio timeslot request. */ +typedef struct +{ + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ + uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ +} nrf_radio_request_normal_t; + +/**@brief Radio timeslot request parameters. */ +typedef struct +{ + uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ + union + { + nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ + nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ + } params; /**< Parameter union. */ +} nrf_radio_request_t; + +/**@brief Return parameters of the radio timeslot signal callback. */ +typedef struct +{ + uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ + union + { + struct + { + nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ + } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ + struct + { + uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ + } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ + } params; /**< Parameter union. */ +} nrf_radio_signal_callback_return_param_t; + +/**@brief The radio timeslot signal callback type. + * + * @note In case of invalid return parameters, the radio timeslot will automatically end + * immediately after returning from the signal callback and the + * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. + * @note The returned struct pointer must remain valid after the signal callback + * function returns. For instance, this means that it must not point to a stack variable. + * + * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. + * + * @return Pointer to structure containing action requested by the application. + */ +typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); + +/**@brief AES ECB parameter typedefs */ +typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ +typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ +typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ + +/**@brief AES ECB data structure */ +typedef struct +{ + soc_ecb_key_t key; /**< Encryption key. */ + soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ + soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ +} nrf_ecb_hal_data_t; + +/**@brief AES ECB block. Used to provide multiple blocks in a single call + to @ref sd_ecb_blocks_encrypt.*/ +typedef struct +{ + soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */ + soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */ + soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */ +} nrf_ecb_hal_data_block_t; + +/**@} */ + +/**@addtogroup NRF_SOC_FUNCTIONS Functions + * @{ */ + +/**@brief Initialize a mutex. + * + * @param[in] p_mutex Pointer to the mutex to initialize. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); + +/**@brief Attempt to acquire a mutex. + * + * @param[in] p_mutex Pointer to the mutex to acquire. + * + * @retval ::NRF_SUCCESS The mutex was successfully acquired. + * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. + */ +SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); + +/**@brief Release a mutex. + * + * @param[in] p_mutex Pointer to the mutex to release. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); + +/**@brief Query the capacity of the application random pool. + * + * @param[out] p_pool_capacity The capacity of the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); + +/**@brief Get number of random bytes available to the application. + * + * @param[out] p_bytes_available The number of bytes currently available in the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); + +/**@brief Get random bytes from the application pool. + * + * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. + * @param[in] length Number of bytes to take from pool and place in p_buff. + * + * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. + * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. +*/ +SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); + +/**@brief Gets the reset reason register. + * + * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); + +/**@brief Clears the bits of the reset reason register. + * + * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); + +/**@brief Sets the power mode when in CPU sleep. + * + * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait + * + * @retval ::NRF_SUCCESS The power mode was set. + * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. + */ +SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); + +/**@brief Puts the chip in System OFF mode. + * + * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN + */ +SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); + +/**@brief Enables or disables the power-fail comparator. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); + +/**@brief Enables or disables the USB power ready event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_POWER_READY) when a USB 3.3 V supply is ready. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbpwrrdy_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBPWRRDY_ENABLE, uint32_t, sd_power_usbpwrrdy_enable(uint8_t usbpwrrdy_enable)); + +/**@brief Enables or disables the power USB-detected event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_DETECTED) when a voltage supply is detected on VBUS. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbdetected_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBDETECTED_ENABLE, uint32_t, sd_power_usbdetected_enable(uint8_t usbdetected_enable)); + +/**@brief Enables or disables the power USB-removed event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_REMOVED) when a voltage supply is removed from VBUS. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbremoved_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBREMOVED_ENABLE, uint32_t, sd_power_usbremoved_enable(uint8_t usbremoved_enable)); + +/**@brief Get USB supply status register content. + * + * @param[out] usbregstatus The content of USBREGSTATUS register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBREGSTATUS_GET, uint32_t, sd_power_usbregstatus_get(uint32_t * usbregstatus)); + +/**@brief Sets the power failure comparator threshold value. + * + * @note: Power failure comparator threshold setting. This setting applies both for normal voltage + * mode (supply connected to both VDD and VDDH) and high voltage mode (supply connected to + * VDDH only). + * + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. + * + * @retval ::NRF_SUCCESS The power failure threshold was set. + * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. + */ +SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); + +/**@brief Sets the power failure comparator threshold value for high voltage. + * + * @note: Power failure comparator threshold setting for high voltage mode (supply connected to + * VDDH only). This setting does not apply for normal voltage mode (supply connected to both + * VDD and VDDH). + * + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDVDDHS. + * + * @retval ::NRF_SUCCESS The power failure threshold was set. + * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. + */ +SVCALL(SD_POWER_POF_THRESHOLDVDDH_SET, uint32_t, sd_power_pof_thresholdvddh_set(uint8_t threshold)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERSET register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to. + * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to. + * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr)); + +/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from. + * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power)); + +/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be set in the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[out] p_gpregret Contents of the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); + +/**@brief Enable or disable the DC/DC regulator for the regulator stage 1 (REG1). + * + * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. + */ +SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); + +/**@brief Enable or disable the DC/DC regulator for the regulator stage 0 (REG0). + * + * For more details on the REG0 stage, please see product specification. + * + * @param[in] dcdc_mode The mode of the DCDC0, see @ref NRF_POWER_DCDC_MODES. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_PARAM The dcdc_mode is invalid. + */ +SVCALL(SD_POWER_DCDC0_MODE_SET, uint32_t, sd_power_dcdc0_mode_set(uint8_t dcdc_mode)); + +/**@brief Request the high frequency crystal oscillator. + * + * Will start the high frequency crystal oscillator, the startup time of the crystal varies + * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_release + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); + +/**@brief Releases the high frequency crystal oscillator. + * + * Will stop the high frequency crystal oscillator, this happens immediately. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_request + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); + +/**@brief Checks if the high frequency crystal oscillator is running. + * + * @see sd_clock_hfclk_request + * @see sd_clock_hfclk_release + * + * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); + +/**@brief Waits for an application event. + * + * An application event is either an application interrupt or a pended interrupt when the interrupt + * is disabled. + * + * When the application waits for an application event by calling this function, an interrupt that + * is enabled will be taken immediately on pending since this function will wait in thread mode, + * then the execution will return in the application's main thread. + * + * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M + * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets + * pended, this function will return to the application's main thread. + * + * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ + * in order to sleep using this function. This is only necessary for disabled interrupts, as + * the interrupt handler will clear the pending flag automatically for enabled interrupts. + * + * @note If an application interrupt has happened since the last time sd_app_evt_wait was + * called this function will return immediately and not go to sleep. This is to avoid race + * conditions that can occur when a flag is updated in the interrupt handler and processed + * in the main loop. + * + * @post An application interrupt has happened or a interrupt pending flag is set. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); + +/**@brief Get PPI channel enable register contents. + * + * @param[out] p_channel_enable The contents of the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); + +/**@brief Set PPI channel enable register. + * + * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); + +/**@brief Clear PPI channel enable register. + * + * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); + +/**@brief Assign endpoints to a PPI channel. + * + * @param[in] channel_num Number of the PPI channel to assign. + * @param[in] evt_endpoint Event endpoint of the PPI channel. + * @param[in] task_endpoint Task endpoint of the PPI channel. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); + +/**@brief Task to enable a channel group. + * + * @param[in] group_num Number of the channel group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); + +/**@brief Task to disable a channel group. + * + * @param[in] group_num Number of the PPI group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); + +/**@brief Assign PPI channels to a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[in] channel_msk Mask of the channels to assign to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); + +/**@brief Gets the PPI channels of a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[out] p_channel_msk Mask of the channels assigned to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); + +/**@brief Configures the Radio Notification signal. + * + * @note + * - The notification signal latency depends on the interrupt priority settings of SWI used + * for notification signal. + * - To ensure that the radio notification signal behaves in a consistent way, the radio + * notifications must be configured when there is no protocol stack or other SoftDevice + * activity in progress. It is recommended that the radio notification signal is + * configured directly after the SoftDevice has been enabled. + * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice + * will interrupt the application to do Radio Event preparation. + * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have + * to shorten the connection events to have time for the Radio Notification signals. + * + * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio + * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is + * recommended (but not required) to be used with + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. + * + * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES. + * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or + * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. + * + * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. + * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all + * running activities and retry. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); + +/**@brief Encrypts a block according to the specified parameters. + * + * 128-bit AES encryption. + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input + * parameters and one output parameter). + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); + +/**@brief Encrypts multiple data blocks provided as an array of data block structures. + * + * @details: Performs 128-bit AES encryption on multiple data blocks + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in] block_count Count of blocks in the p_data_blocks array. + * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of + * @ref nrf_ecb_hal_data_block_t structures. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks)); + +/**@brief Gets any pending events generated by the SoC API. + * + * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. + * + * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. + * + * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. + * @retval ::NRF_ERROR_NOT_FOUND No pending events. + */ +SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); + +/**@brief Get the temperature measured on the chip + * + * This function will block until the temperature measurement is done. + * It takes around 50 us from call to return. + * + * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius. + * + * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp + */ +SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); + +/**@brief Flash Write +* +* Commands to write a buffer to flash +* +* If the SoftDevice is enabled: +* This call initiates the flash access command, and its completion will be communicated to the +* application with exactly one of the following events: +* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. +* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. +* +* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the + * write has been completed +* +* @note +* - This call takes control over the radio and the CPU during flash erase and write to make sure that +* they will not interfere with the flash access. This means that all interrupts will be blocked +* for a predictable time (depending on the NVMC specification in the device's Product Specification +* and the command parameters). +* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS +* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. +* - This call will make the SoftDevice trigger a hardfault when the page is written, if it is +* protected. +* +* +* @param[in] p_dst Pointer to start of flash location to be written. +* @param[in] p_src Pointer to buffer with data to be written. +* @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one +* flash page. See the device's Product Specification for details. +* +* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. +* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. +* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. +* @retval ::NRF_ERROR_FORBIDDEN Tried to write to an address outside the application flash area. +* @retval ::NRF_SUCCESS The command was accepted. +*/ +SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size)); + + +/**@brief Flash Erase page +* +* Commands to erase a flash page +* If the SoftDevice is enabled: +* This call initiates the flash access command, and its completion will be communicated to the +* application with exactly one of the following events: +* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. +* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. +* +* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the +* erase has been completed +* +* @note +* - This call takes control over the radio and the CPU during flash erase and write to make sure that +* they will not interfere with the flash access. This means that all interrupts will be blocked +* for a predictable time (depending on the NVMC specification in the device's Product Specification +* and the command parameters). +* - This call will make the SoftDevice trigger a hardfault when the page is erased, if it is +* protected. +* +* +* @param[in] page_number Page number of the page to erase +* +* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. +* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. +* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. +* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a page outside the application flash area. +* @retval ::NRF_SUCCESS The command was accepted. +*/ +SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); + + + +/**@brief Opens a session for radio timeslot requests. + * + * @note Only one session can be open at a time. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot + * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed + * by the application. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 + * interrupt occurs. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO + * interrupt occurs. + * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This + * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). + * + * @param[in] p_radio_signal_callback The signal callback. + * + * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. + * @retval ::NRF_ERROR_BUSY If session cannot be opened. + * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); + +/**@brief Closes a session for radio timeslot requests. + * + * @note Any current radio timeslot will be finished before the session is closed. + * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. + * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED + * event is received. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened. + * @retval ::NRF_ERROR_BUSY If session is currently being closed. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); + +/**@brief Requests a radio timeslot. + * + * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST + * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST. + * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by + * p_request->distance_us and is given relative to the start of the previous timeslot. + * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. + * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this + * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. + * The application may then try to schedule the first radio timeslot again. + * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). + * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. + * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. + * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the + * specified radio timeslot start, but this does not affect the actual start time of the timeslot. + * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency + * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is + * guaranteed to be clocked from the external crystal. + * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral + * during the radio timeslot. + * + * @param[in] p_request Pointer to the request parameters. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. + * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request)); + +/**@brief Write register protected by the SoftDevice + * + * This function writes to a register that is write-protected by the SoftDevice. Please refer to your + * SoftDevice Specification for more details about which registers that are protected by SoftDevice. + * This function can write to the following protected peripheral: + * - ACL + * + * @note Protected registers may be read directly. + * @note Register that are write-once will return @ref NRF_SUCCESS on second set, even the value in + * the register has not changed. See the Product Specification for more details about register + * properties. + * + * @param[in] p_register Pointer to register to be written. + * @param[in] value Value to be written to the register. + * + * @retval ::NRF_ERROR_INVALID_ADDR This function can not write to the reguested register. + * @retval ::NRF_SUCCESS Value successfully written to register. + * + */ +SVCALL(SD_PROTECTED_REGISTER_WRITE, uint32_t, sd_protected_register_write(volatile uint32_t * p_register, uint32_t value)); + +/**@} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SOC_H__ + +/**@} */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_svc.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_svc.h new file mode 100644 index 0000000..292c692 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_svc.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SVC__ +#define NRF_SVC__ + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SVCALL_AS_NORMAL_FUNCTION +#define SVCALL(number, return_type, signature) return_type signature +#else + +#ifndef SVCALL +#if defined (__CC_ARM) +#define SVCALL(number, return_type, signature) return_type __svc(number) signature +#elif defined (__GNUC__) +#ifdef __cplusplus +#define GCC_CAST_CPP (uint16_t) +#else +#define GCC_CAST_CPP +#endif +#define SVCALL(number, return_type, signature) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + __attribute__((naked)) \ + __attribute__((unused)) \ + static return_type signature \ + { \ + __asm( \ + "svc %0\n" \ + "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ + ); \ + } \ + _Pragma("GCC diagnostic pop") + +#elif defined (__ICCARM__) +#define PRAGMA(x) _Pragma(#x) +#define SVCALL(number, return_type, signature) \ +PRAGMA(swi_number = (number)) \ + __swi return_type signature; +#else +#define SVCALL(number, return_type, signature) return_type signature +#endif +#endif // SVCALL + +#endif // SVCALL_AS_NORMAL_FUNCTION + +#ifdef __cplusplus +} +#endif +#endif // NRF_SVC__ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_config.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_config.h new file mode 100644 index 0000000..6a974ba --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_config.h @@ -0,0 +1,18 @@ +#ifndef NRFX_CONFIG_H__ +#define NRFX_CONFIG_H__ + +#define NRFX_POWER_ENABLED 1 +#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY 7 + +#define NRFX_CLOCK_ENABLED 0 + +#define NRFX_UARTE_ENABLED 1 +#define NRFX_UARTE0_ENABLED 1 + +#define NRFX_UARTE1_ENABLED 0 +#define NRFX_UARTE2_ENABLED 0 +#define NRFX_UARTE3_ENABLED 0 + +#define NRFX_PRS_ENABLED 0 + +#endif // NRFX_CONFIG_H__ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_glue.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_glue.h new file mode 100644 index 0000000..cdf49b4 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_glue.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 HOLDER 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 NRFX_GLUE_H__ +#define NRFX_GLUE_H__ + +// THIS IS A TEMPLATE FILE. +// It should be copied to a suitable location within the host environment into +// which nrfx is integrated, and the following macros should be provided with +// appropriate implementations. +// And this comment should be removed from the customized file. + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrfx_glue nrfx_glue.h + * @{ + * @ingroup nrfx + * + * @brief This file contains macros that should be implemented according to + * the needs of the host environment into which @em nrfx is integrated. + */ + +// Uncomment this line to use the standard MDK way of binding IRQ handlers +// at linking time. +#include + +//------------------------------------------------------------------------------ + +/** + * @brief Macro for placing a runtime assertion. + * + * @param expression Expression to evaluate. + */ +#define NRFX_ASSERT(expression) + +/** + * @brief Macro for placing a compile time assertion. + * + * @param expression Expression to evaluate. + */ +#define NRFX_STATIC_ASSERT(expression) + +//------------------------------------------------------------------------------ + +/** + * @brief Macro for setting the priority of a specific IRQ. + * + * @param irq_number IRQ number. + * @param priority Priority to set. + */ +#define NRFX_IRQ_PRIORITY_SET(irq_number, priority) _NRFX_IRQ_PRIORITY_SET(irq_number, priority) +static inline void _NRFX_IRQ_PRIORITY_SET(IRQn_Type irq_number, + uint8_t priority) +{ + NRFX_ASSERT(INTERRUPT_PRIORITY_IS_VALID(priority)); + NVIC_SetPriority(irq_number, priority); +} + +/** + * @brief Macro for enabling a specific IRQ. + * + * @param irq_number IRQ number. + */ +#define NRFX_IRQ_ENABLE(irq_number) _NRFX_IRQ_ENABLE(irq_number) +static inline void _NRFX_IRQ_ENABLE(IRQn_Type irq_number) +{ + NVIC_ClearPendingIRQ(irq_number); + NVIC_EnableIRQ(irq_number); +} + +/** + * @brief Macro for checking if a specific IRQ is enabled. + * + * @param irq_number IRQ number. + * + * @retval true If the IRQ is enabled. + * @retval false Otherwise. + */ +#define NRFX_IRQ_IS_ENABLED(irq_number) _NRFX_IRQ_IS_ENABLED(irq_number) +static inline bool _NRFX_IRQ_IS_ENABLED(IRQn_Type irq_number) +{ + return 0 != (NVIC->ISER[irq_number / 32] & (1UL << (irq_number % 32))); +} + +/** + * @brief Macro for disabling a specific IRQ. + * + * @param irq_number IRQ number. + */ +#define NRFX_IRQ_DISABLE(irq_number) _NRFX_IRQ_DISABLE(irq_number) +static inline void _NRFX_IRQ_DISABLE(IRQn_Type irq_number) +{ + NVIC_DisableIRQ(irq_number); +} + +/** + * @brief Macro for setting a specific IRQ as pending. + * + * @param irq_number IRQ number. + */ +#define NRFX_IRQ_PENDING_SET(irq_number) _NRFX_IRQ_PENDING_SET(irq_number) +static inline void _NRFX_IRQ_PENDING_SET(IRQn_Type irq_number) +{ + NVIC_SetPendingIRQ(irq_number); +} + +/** + * @brief Macro for clearing the pending status of a specific IRQ. + * + * @param irq_number IRQ number. + */ +#define NRFX_IRQ_PENDING_CLEAR(irq_number) _NRFX_IRQ_PENDING_CLEAR(irq_number) +static inline void _NRFX_IRQ_PENDING_CLEAR(IRQn_Type irq_number) +{ + NVIC_ClearPendingIRQ(irq_number); +} + +/** + * @brief Macro for checking the pending status of a specific IRQ. + * + * @retval true If the IRQ is pending. + * @retval false Otherwise. + */ +#define NRFX_IRQ_IS_PENDING(irq_number) _NRFX_IRQ_IS_PENDING(irq_number) +static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number) +{ + return (NVIC_GetPendingIRQ(irq_number) == 1); +} + +/** + * @brief Macro for entering into a critical section. + */ +#define NRFX_CRITICAL_SECTION_ENTER() + +/** + * @brief Macro for exiting from a critical section. + */ +#define NRFX_CRITICAL_SECTION_EXIT() + +//------------------------------------------------------------------------------ + +/** + * @brief When set to a non-zero value, this macro specifies that + * @ref nrfx_coredep_delay_us uses a precise DWT-based solution. + * A compilation error is generated if the DWT unit is not present + * in the SoC used. + */ +#define NRFX_DELAY_DWT_BASED 0 + +/** + * @brief Macro for delaying the code execution for at least the specified time. + * + * @param us_time Number of microseconds to wait. + */ +#include +#define NRFX_DELAY_US(us_time) nrfx_coredep_delay_us(us_time) + +//------------------------------------------------------------------------------ + +/** + * @brief When set to a non-zero value, this macro specifies that the + * @ref nrfx_error_codes and the @ref nrfx_err_t type itself are defined + * in a customized way and the default definitions from @c + * should not be used. + */ +#define NRFX_CUSTOM_ERROR_CODES 0 + +//------------------------------------------------------------------------------ + +/** + * @brief Bitmask defining PPI channels reserved to be used outside of nrfx. + */ +#define NRFX_PPI_CHANNELS_USED 0 + +/** + * @brief Bitmask defining PPI groups reserved to be used outside of nrfx. + */ +#define NRFX_PPI_GROUPS_USED 0 + +/** + * @brief Bitmask defining SWI instances reserved to be used outside of nrfx. + */ +#define NRFX_SWI_USED 0 + +/** + * @brief Bitmask defining TIMER instances reserved to be used outside of nrfx. + */ +#define NRFX_TIMERS_USED 0 + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRFX_GLUE_H__ diff --git a/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_log.h b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_log.h new file mode 100644 index 0000000..3bc1b42 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/nordic/nrfx_log.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 HOLDER 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 NRFX_LOG_H__ +#define NRFX_LOG_H__ + +// THIS IS A TEMPLATE FILE. +// It should be copied to a suitable location within the host environment into +// which nrfx is integrated, and the following macros should be provided with +// appropriate implementations. +// And this comment should be removed from the customized file. + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrfx_log nrfx_log.h + * @{ + * @ingroup nrfx + * + * @brief This file contains macros that should be implemented according to + * the needs of the host environment into which @em nrfx is integrated. + */ + +/** + * @brief Macro for logging a message with the severity level ERROR. + * + * @param format printf-style format string, optionally followed by arguments + * to be formatted and inserted in the resulting string. + */ +#define NRFX_LOG_ERROR(format, ...) + +/** + * @brief Macro for logging a message with the severity level WARNING. + * + * @param format printf-style format string, optionally followed by arguments + * to be formatted and inserted in the resulting string. + */ +#define NRFX_LOG_WARNING(format, ...) + +/** + * @brief Macro for logging a message with the severity level INFO. + * + * @param format printf-style format string, optionally followed by arguments + * to be formatted and inserted in the resulting string. + */ +#define NRFX_LOG_INFO(format, ...) + +/** + * @brief Macro for logging a message with the severity level DEBUG. + * + * @param format printf-style format string, optionally followed by arguments + * to be formatted and inserted in the resulting string. + */ +#define NRFX_LOG_DEBUG(format, ...) + + +/** + * @brief Macro for logging a memory dump with the severity level ERROR. + * + * @param[in] p_memory Pointer to the memory region to be dumped. + * @param[in] length Length of the memory region in bytes. + */ +#define NRFX_LOG_HEXDUMP_ERROR(p_memory, length) + +/** + * @brief Macro for logging a memory dump with the severity level WARNING. + * + * @param[in] p_memory Pointer to the memory region to be dumped. + * @param[in] length Length of the memory region in bytes. + */ +#define NRFX_LOG_HEXDUMP_WARNING(p_memory, length) + +/** + * @brief Macro for logging a memory dump with the severity level INFO. + * + * @param[in] p_memory Pointer to the memory region to be dumped. + * @param[in] length Length of the memory region in bytes. + */ +#define NRFX_LOG_HEXDUMP_INFO(p_memory, length) + +/** + * @brief Macro for logging a memory dump with the severity level DEBUG. + * + * @param[in] p_memory Pointer to the memory region to be dumped. + * @param[in] length Length of the memory region in bytes. + */ +#define NRFX_LOG_HEXDUMP_DEBUG(p_memory, length) + + +/** + * @brief Macro for getting the textual representation of a given error code. + * + * @param[in] error_code Error code. + * + * @return String containing the textual representation of the error code. + */ +#define NRFX_LOG_ERROR_STRING_GET(error_code) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRFX_LOG_H__ diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/Makefile b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/Makefile new file mode 100644 index 0000000..d91d17a --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/Makefile @@ -0,0 +1,51 @@ +############################################################################ +# tools/mkspk/Makefile +# +# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name NuttX 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. +# +############################################################################ + +all: mkspk +default: mkspk +.PHONY: clean + +# Add CFLAGS=-g on the make command line to build debug versions + +CFLAGS = -O2 -Wall -I. + +# mkspk - Convert nuttx.hex image to nuttx.spk image + +mkspk: + @gcc $(CFLAGS) -o mkspk mkspk.c clefia.c + +clean: + @rm -f *.o *.a *.dSYM *~ .*.swp + @rm -f mkspk mkspk.exe diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.c b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.c new file mode 100644 index 0000000..02a1755 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.c @@ -0,0 +1,517 @@ +/**************************************************************************** + * tools/cxd56/clefia.c + * + * Copyright (C) 2007, 2008 Sony Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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. + *****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "clefia.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define clefiamul4(_x) (clefiamul2(clefiamul2((_x)))) +#define clefiamul6(_x) (clefiamul2((_x)) ^ clefiamul4((_x))) +#define clefiamul8(_x) (clefiamul2(clefiamul4((_x)))) +#define clefiamula(_x) (clefiamul2((_x)) ^ clefiamul8((_x))) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* S0 (8-bit S-box based on four 4-bit S-boxes) */ + +static const unsigned char clefia_s0[256] = +{ + 0x57u, 0x49u, 0xd1u, 0xc6u, 0x2fu, 0x33u, 0x74u, 0xfbu, + 0x95u, 0x6du, 0x82u, 0xeau, 0x0eu, 0xb0u, 0xa8u, 0x1cu, + 0x28u, 0xd0u, 0x4bu, 0x92u, 0x5cu, 0xeeu, 0x85u, 0xb1u, + 0xc4u, 0x0au, 0x76u, 0x3du, 0x63u, 0xf9u, 0x17u, 0xafu, + 0xbfu, 0xa1u, 0x19u, 0x65u, 0xf7u, 0x7au, 0x32u, 0x20u, + 0x06u, 0xceu, 0xe4u, 0x83u, 0x9du, 0x5bu, 0x4cu, 0xd8u, + 0x42u, 0x5du, 0x2eu, 0xe8u, 0xd4u, 0x9bu, 0x0fu, 0x13u, + 0x3cu, 0x89u, 0x67u, 0xc0u, 0x71u, 0xaau, 0xb6u, 0xf5u, + 0xa4u, 0xbeu, 0xfdu, 0x8cu, 0x12u, 0x00u, 0x97u, 0xdau, + 0x78u, 0xe1u, 0xcfu, 0x6bu, 0x39u, 0x43u, 0x55u, 0x26u, + 0x30u, 0x98u, 0xccu, 0xddu, 0xebu, 0x54u, 0xb3u, 0x8fu, + 0x4eu, 0x16u, 0xfau, 0x22u, 0xa5u, 0x77u, 0x09u, 0x61u, + 0xd6u, 0x2au, 0x53u, 0x37u, 0x45u, 0xc1u, 0x6cu, 0xaeu, + 0xefu, 0x70u, 0x08u, 0x99u, 0x8bu, 0x1du, 0xf2u, 0xb4u, + 0xe9u, 0xc7u, 0x9fu, 0x4au, 0x31u, 0x25u, 0xfeu, 0x7cu, + 0xd3u, 0xa2u, 0xbdu, 0x56u, 0x14u, 0x88u, 0x60u, 0x0bu, + 0xcdu, 0xe2u, 0x34u, 0x50u, 0x9eu, 0xdcu, 0x11u, 0x05u, + 0x2bu, 0xb7u, 0xa9u, 0x48u, 0xffu, 0x66u, 0x8au, 0x73u, + 0x03u, 0x75u, 0x86u, 0xf1u, 0x6au, 0xa7u, 0x40u, 0xc2u, + 0xb9u, 0x2cu, 0xdbu, 0x1fu, 0x58u, 0x94u, 0x3eu, 0xedu, + 0xfcu, 0x1bu, 0xa0u, 0x04u, 0xb8u, 0x8du, 0xe6u, 0x59u, + 0x62u, 0x93u, 0x35u, 0x7eu, 0xcau, 0x21u, 0xdfu, 0x47u, + 0x15u, 0xf3u, 0xbau, 0x7fu, 0xa6u, 0x69u, 0xc8u, 0x4du, + 0x87u, 0x3bu, 0x9cu, 0x01u, 0xe0u, 0xdeu, 0x24u, 0x52u, + 0x7bu, 0x0cu, 0x68u, 0x1eu, 0x80u, 0xb2u, 0x5au, 0xe7u, + 0xadu, 0xd5u, 0x23u, 0xf4u, 0x46u, 0x3fu, 0x91u, 0xc9u, + 0x6eu, 0x84u, 0x72u, 0xbbu, 0x0du, 0x18u, 0xd9u, 0x96u, + 0xf0u, 0x5fu, 0x41u, 0xacu, 0x27u, 0xc5u, 0xe3u, 0x3au, + 0x81u, 0x6fu, 0x07u, 0xa3u, 0x79u, 0xf6u, 0x2du, 0x38u, + 0x1au, 0x44u, 0x5eu, 0xb5u, 0xd2u, 0xecu, 0xcbu, 0x90u, + 0x9au, 0x36u, 0xe5u, 0x29u, 0xc3u, 0x4fu, 0xabu, 0x64u, + 0x51u, 0xf8u, 0x10u, 0xd7u, 0xbcu, 0x02u, 0x7du, 0x8eu +}; + +/* S1 (8-bit S-box based on inverse function) */ + +static const unsigned char clefia_s1[256] = +{ + 0x6cu, 0xdau, 0xc3u, 0xe9u, 0x4eu, 0x9du, 0x0au, 0x3du, + 0xb8u, 0x36u, 0xb4u, 0x38u, 0x13u, 0x34u, 0x0cu, 0xd9u, + 0xbfu, 0x74u, 0x94u, 0x8fu, 0xb7u, 0x9cu, 0xe5u, 0xdcu, + 0x9eu, 0x07u, 0x49u, 0x4fu, 0x98u, 0x2cu, 0xb0u, 0x93u, + 0x12u, 0xebu, 0xcdu, 0xb3u, 0x92u, 0xe7u, 0x41u, 0x60u, + 0xe3u, 0x21u, 0x27u, 0x3bu, 0xe6u, 0x19u, 0xd2u, 0x0eu, + 0x91u, 0x11u, 0xc7u, 0x3fu, 0x2au, 0x8eu, 0xa1u, 0xbcu, + 0x2bu, 0xc8u, 0xc5u, 0x0fu, 0x5bu, 0xf3u, 0x87u, 0x8bu, + 0xfbu, 0xf5u, 0xdeu, 0x20u, 0xc6u, 0xa7u, 0x84u, 0xceu, + 0xd8u, 0x65u, 0x51u, 0xc9u, 0xa4u, 0xefu, 0x43u, 0x53u, + 0x25u, 0x5du, 0x9bu, 0x31u, 0xe8u, 0x3eu, 0x0du, 0xd7u, + 0x80u, 0xffu, 0x69u, 0x8au, 0xbau, 0x0bu, 0x73u, 0x5cu, + 0x6eu, 0x54u, 0x15u, 0x62u, 0xf6u, 0x35u, 0x30u, 0x52u, + 0xa3u, 0x16u, 0xd3u, 0x28u, 0x32u, 0xfau, 0xaau, 0x5eu, + 0xcfu, 0xeau, 0xedu, 0x78u, 0x33u, 0x58u, 0x09u, 0x7bu, + 0x63u, 0xc0u, 0xc1u, 0x46u, 0x1eu, 0xdfu, 0xa9u, 0x99u, + 0x55u, 0x04u, 0xc4u, 0x86u, 0x39u, 0x77u, 0x82u, 0xecu, + 0x40u, 0x18u, 0x90u, 0x97u, 0x59u, 0xddu, 0x83u, 0x1fu, + 0x9au, 0x37u, 0x06u, 0x24u, 0x64u, 0x7cu, 0xa5u, 0x56u, + 0x48u, 0x08u, 0x85u, 0xd0u, 0x61u, 0x26u, 0xcau, 0x6fu, + 0x7eu, 0x6au, 0xb6u, 0x71u, 0xa0u, 0x70u, 0x05u, 0xd1u, + 0x45u, 0x8cu, 0x23u, 0x1cu, 0xf0u, 0xeeu, 0x89u, 0xadu, + 0x7au, 0x4bu, 0xc2u, 0x2fu, 0xdbu, 0x5au, 0x4du, 0x76u, + 0x67u, 0x17u, 0x2du, 0xf4u, 0xcbu, 0xb1u, 0x4au, 0xa8u, + 0xb5u, 0x22u, 0x47u, 0x3au, 0xd5u, 0x10u, 0x4cu, 0x72u, + 0xccu, 0x00u, 0xf9u, 0xe0u, 0xfdu, 0xe2u, 0xfeu, 0xaeu, + 0xf8u, 0x5fu, 0xabu, 0xf1u, 0x1bu, 0x42u, 0x81u, 0xd6u, + 0xbeu, 0x44u, 0x29u, 0xa6u, 0x57u, 0xb9u, 0xafu, 0xf2u, + 0xd4u, 0x75u, 0x66u, 0xbbu, 0x68u, 0x9fu, 0x50u, 0x02u, + 0x01u, 0x3cu, 0x7fu, 0x8du, 0x1au, 0x88u, 0xbdu, 0xacu, + 0xf7u, 0xe4u, 0x79u, 0x96u, 0xa2u, 0xfcu, 0x6du, 0xb2u, + 0x6bu, 0x03u, 0xe1u, 0x2eu, 0x7du, 0x14u, 0x95u, 0x1du +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void bytecpy(unsigned char *dst, const unsigned char *src, int bytelen) +{ + while (bytelen-- > 0) + { + *dst++ = *src++; + } +} + +static unsigned char clefiamul2(unsigned char x) +{ + /* multiplication over GF(2^8) (p(x) = '11d') */ + + if (x & 0x80u) + { + x ^= 0x0eu; + } + + return ((x << 1) | (x >> 7)); +} + +static void clefiaf0xor(unsigned char *dst, const unsigned char *src, + const unsigned char *rk) +{ + unsigned char x[4]; + unsigned char y[4]; + unsigned char z[4]; + + /* F0 */ + + /* Key addition */ + + bytexor(x, src, rk, 4); + + /* Substitution layer */ + + z[0] = clefia_s0[x[0]]; + z[1] = clefia_s1[x[1]]; + z[2] = clefia_s0[x[2]]; + z[3] = clefia_s1[x[3]]; + + /* Diffusion layer (M0) */ + + y[0] = z[0] ^ clefiamul2(z[1]) ^ clefiamul4(z[2]) ^ clefiamul6(z[3]); + y[1] = clefiamul2(z[0]) ^ z[1] ^ clefiamul6(z[2]) ^ clefiamul4(z[3]); + y[2] = clefiamul4(z[0]) ^ clefiamul6(z[1]) ^ z[2] ^ clefiamul2(z[3]); + y[3] = clefiamul6(z[0]) ^ clefiamul4(z[1]) ^ clefiamul2(z[2]) ^ z[3]; + + /* Xoring after F0 */ + + bytecpy(dst + 0, src + 0, 4); + bytexor(dst + 4, src + 4, y, 4); +} + +static void clefiaf1xor(unsigned char *dst, const unsigned char *src, + const unsigned char *rk) +{ + unsigned char x[4]; + unsigned char y[4]; + unsigned char z[4]; + + /* F1 */ + + /* Key addition */ + + bytexor(x, src, rk, 4); + + /* Substitution layer */ + + z[0] = clefia_s1[x[0]]; + z[1] = clefia_s0[x[1]]; + z[2] = clefia_s1[x[2]]; + z[3] = clefia_s0[x[3]]; + + /* Diffusion layer (M1) */ + + y[0] = z[0] ^ clefiamul8(z[1]) ^ clefiamul2(z[2]) ^ clefiamula(z[3]); + y[1] = clefiamul8(z[0]) ^ z[1] ^ clefiamula(z[2]) ^ clefiamul2(z[3]); + y[2] = clefiamul2(z[0]) ^ clefiamula(z[1]) ^ z[2] ^ clefiamul8(z[3]); + y[3] = clefiamula(z[0]) ^ clefiamul2(z[1]) ^ clefiamul8(z[2]) ^ z[3]; + + /* Xoring after F1 */ + + bytecpy(dst + 0, src + 0, 4); + bytexor(dst + 4, src + 4, y, 4); +} + +static void clefiagfn4(unsigned char *y, const unsigned char *x, + const unsigned char *rk, int r) +{ + unsigned char fin[16]; + unsigned char fout[16]; + + bytecpy(fin, x, 16); + while (r-- > 0) + { + clefiaf0xor(fout + 0, fin + 0, rk + 0); + clefiaf1xor(fout + 8, fin + 8, rk + 4); + rk += 8; + if (r) + { + /* swapping for encryption */ + + bytecpy(fin + 0, fout + 4, 12); + bytecpy(fin + 12, fout + 0, 4); + } + } + + bytecpy(y, fout, 16); +} + +#if 0 /* Not used */ +static void clefiagfn8(unsigned char *y, const unsigned char *x, + const unsigned char *rk, int r) +{ + unsigned char fin[32]; + unsigned char fout[32]; + + bytecpy(fin, x, 32); + while (r-- > 0) + { + clefiaf0xor(fout + 0, fin + 0, rk + 0); + clefiaf1xor(fout + 8, fin + 8, rk + 4); + clefiaf0xor(fout + 16, fin + 16, rk + 8); + clefiaf1xor(fout + 24, fin + 24, rk + 12); + rk += 16; + if (r) + { + /* swapping for encryption */ + + bytecpy(fin + 0, fout + 4, 28); + bytecpy(fin + 28, fout + 0, 4); + } + } + + bytecpy(y, fout, 32); +} +#endif + +#if 0 /* Not used */ +static void clefiagfn4inv(unsigned char *y, const unsigned char *x, + const unsigned char *rk, int r) +{ + unsigned char fin[16]; + unsigned char fout[16]; + + rk += (r - 1) * 8; + bytecpy(fin, x, 16); + while (r-- > 0) + { + clefiaf0xor(fout + 0, fin + 0, rk + 0); + clefiaf1xor(fout + 8, fin + 8, rk + 4); + rk -= 8; + if (r) + { + /* swapping for decryption */ + + bytecpy(fin + 0, fout + 12, 4); + bytecpy(fin + 4, fout + 0, 12); + } + } + + bytecpy(y, fout, 16); +} +#endif + +static void clefiadoubleswap(unsigned char *lk) +{ + unsigned char t[16]; + + t[0] = (lk[0] << 7) | (lk[1] >> 1); + t[1] = (lk[1] << 7) | (lk[2] >> 1); + t[2] = (lk[2] << 7) | (lk[3] >> 1); + t[3] = (lk[3] << 7) | (lk[4] >> 1); + t[4] = (lk[4] << 7) | (lk[5] >> 1); + t[5] = (lk[5] << 7) | (lk[6] >> 1); + t[6] = (lk[6] << 7) | (lk[7] >> 1); + t[7] = (lk[7] << 7) | (lk[15] & 0x7fu); + + t[8] = (lk[8] >> 7) | (lk[0] & 0xfeu); + t[9] = (lk[9] >> 7) | (lk[8] << 1); + t[10] = (lk[10] >> 7) | (lk[9] << 1); + t[11] = (lk[11] >> 7) | (lk[10] << 1); + t[12] = (lk[12] >> 7) | (lk[11] << 1); + t[13] = (lk[13] >> 7) | (lk[12] << 1); + t[14] = (lk[14] >> 7) | (lk[13] << 1); + t[15] = (lk[15] >> 7) | (lk[14] << 1); + + bytecpy(lk, t, 16); +} + +static void clefiaconset(unsigned char *con, const unsigned char *iv, int lk) +{ + unsigned char t[2]; + unsigned char tmp; + + bytecpy(t, iv, 2); + while (lk-- > 0) + { + con[0] = t[0] ^ 0xb7u; /* P_16 = 0xb7e1 (natural logarithm) */ + con[1] = t[1] ^ 0xe1u; + con[2] = ~((t[0] << 1) | (t[1] >> 7)); + con[3] = ~((t[1] << 1) | (t[0] >> 7)); + con[4] = ~t[0] ^ 0x24u; /* Q_16 = 0x243f (circle ratio) */ + con[5] = ~t[1] ^ 0x3fu; + con[6] = t[1]; + con[7] = t[0]; + con += 8; + + /* updating T */ + + if (t[1] & 0x01u) + { + t[0] ^= 0xa8u; + t[1] ^= 0x30u; + } + + tmp = t[0] << 7; + t[0] = (t[0] >> 1) | (t[1] << 7); + t[1] = (t[1] >> 1) | tmp; + } +} + +static void left_shift_one(uint8_t * in, uint8_t * out) +{ + int i; + int overflow; + + overflow = 0; + for (i = 15; i >= 0; i--) + { + out[i] = in[i] << 1; + out[i] |= overflow; + overflow = (in[i] >> 7) & 1; + } +} + +static void gen_subkey(struct cipher *c) +{ + uint8_t L[16]; + + memset(L, 0, 16); + clefiaencrypt(L, L, c->rk, c->round); + + left_shift_one(L, c->k1); + if (L[0] & 0x80) + { + c->k1[15] = c->k1[15] ^ 0x87; + } + + left_shift_one(c->k1, c->k2); + if (c->k1[0] & 0x80) + { + c->k2[15] = c->k2[15] ^ 0x87; + } + + memset(L, 0, 16); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +struct cipher *cipher_init(uint8_t * key, uint8_t * iv) +{ + struct cipher *c; + + c = (struct cipher *)malloc(sizeof(*c)); + if (!c) + { + return NULL; + } + + c->round = clefiakeyset(c->rk, key); + + gen_subkey(c); + memset(c->vector, 0, 16); + + return c; +} + +void cipher_deinit(struct cipher *c) +{ + memset(c, 0, sizeof(*c)); + free(c); +} + +int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac) +{ + uint8_t m[16]; + uint8_t *p; + + if (size & 0xf) + { + return -1; + } + + p = (uint8_t *) data; + while (size) + { + bytexor(m, c->vector, p, 16); + clefiaencrypt(c->vector, m, c->rk, c->round); + size -= 16; + p += 16; + } + + bytexor(cmac, m, c->k1, 16); + clefiaencrypt(cmac, cmac, c->rk, c->round); + memset(m, 0, 16); + + return 0; +} + +void bytexor(unsigned char *dst, const unsigned char *a, + const unsigned char *b, int bytelen) +{ + while (bytelen-- > 0) + { + *dst++ = *a++ ^ *b++; + } +} + +int clefiakeyset(unsigned char *rk, const unsigned char *skey) +{ + const unsigned char iv[2] = + { + 0x42u, 0x8au /* cubic root of 2 */ + }; + + unsigned char lk[16]; + unsigned char con128[4 * 60]; + int i; + + /* generating CONi^(128) (0 <= i < 60, lk = 30) */ + + clefiaconset(con128, iv, 30); + + /* GFN_{4,12} (generating L from K) */ + + clefiagfn4(lk, skey, con128, 12); + + bytecpy(rk, skey, 8); /* initial whitening key (WK0, WK1) */ + rk += 8; + for (i = 0; i < 9; i++) + { + /* round key (RKi (0 <= i < 36)) */ + + bytexor(rk, lk, con128 + i * 16 + (4 * 24), 16); + if (i % 2) + { + bytexor(rk, rk, skey, 16); /* Xoring K */ + } + + clefiadoubleswap(lk); /* Updating L (DoubleSwap function) */ + rk += 16; + } + + bytecpy(rk, skey + 8, 8); /* final whitening key (WK2, WK3) */ + + return 18; +} + +void clefiaencrypt(unsigned char *ct, const unsigned char *pt, + const unsigned char *rk, const int r) +{ + unsigned char rin[16]; + unsigned char rout[16]; + + bytecpy(rin, pt, 16); + + bytexor(rin + 4, rin + 4, rk + 0, 4); /* initial key whitening */ + bytexor(rin + 12, rin + 12, rk + 4, 4); + rk += 8; + + clefiagfn4(rout, rin, rk, r); /* GFN_{4,r} */ + + bytecpy(ct, rout, 16); + bytexor(ct + 4, ct + 4, rk + r * 8 + 0, 4); /* final key whitening */ + bytexor(ct + 12, ct + 12, rk + r * 8 + 4, 4); +} diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.h b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.h new file mode 100644 index 0000000..a0e0258 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/clefia.h @@ -0,0 +1,65 @@ +/**************************************************************************** + * tools/cxd56/clefia.h + * + * Copyright (C) 2007, 2008 Sony Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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 _TOOLS_CXD56_CLEFIA_H_ +#define _TOOLS_CXD56_CLEFIA_H_ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct cipher + { + int mode; + int dir; + uint8_t rk[8 * 26 + 16]; + uint8_t vector[16]; + int round; + uint8_t k1[16]; + uint8_t k2[16]; + }; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct cipher *cipher_init(uint8_t * key, uint8_t * iv); +void cipher_deinit(struct cipher *c); +int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac); +void bytexor(unsigned char *dst, const unsigned char *a, + const unsigned char *b, int bytelen); +int clefiakeyset(unsigned char *rk, const unsigned char *skey); +void clefiaencrypt(unsigned char *ct, const unsigned char *pt, + const unsigned char *rk, const int r); + +#endif diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/elf32.h b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/elf32.h new file mode 100644 index 0000000..94a9c81 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/elf32.h @@ -0,0 +1,175 @@ +/**************************************************************************** + * include/elf32.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: System V Application Binary Interface, Edition 4.1, March 18, + * 1997, The Santa Cruz Operation, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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 __INCLUDE_ELF32_H +#define __INCLUDE_ELF32_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define EI_NIDENT 16 /* Size of e_ident[] */ + +#define ELF32_ST_BIND(i) ((i) >> 4) +#define ELF32_ST_TYPE(i) ((i) & 0xf) +#define ELF32_ST_INFO(b,t) (((b) << 4) | ((t) & 0xf)) + +/* Definitions for Elf32_Rel*::r_info */ + +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((i) & 0xff) +#define ELF32_R_INFO(s,t) (((s)<< 8) | ((t) & 0xff)) + +#define ELF_R_SYM(i) ELF32_R_SYM(i) + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +/* Figure 4.2: 32-Bit Data Types */ + +typedef uint32_t Elf32_Addr; /* Unsigned program address */ +typedef uint16_t Elf32_Half; /* Unsigned medium integer */ +typedef uint32_t Elf32_Off; /* Unsigned file offset */ +typedef int32_t Elf32_Sword; /* Signed large integer */ +typedef uint32_t Elf32_Word; /* Unsigned large integer */ + +/* Figure 4-3: ELF Header */ + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +/* Figure 4-8: Section Header */ + +typedef struct +{ + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +/* Figure 4-15: Symbol Table Entry */ + +typedef struct +{ + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +/* Figure 4-19: Relocation Entries */ + +typedef struct +{ + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct +{ + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +} Elf32_Rela; + +/* Figure 5-1: Program Header */ + +typedef struct +{ + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +/* Figure 5-9: Dynamic Structure */ + +typedef struct +{ + Elf32_Sword d_tag; + union + { + Elf32_Word d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +typedef Elf32_Addr Elf_Addr; +typedef Elf32_Ehdr Elf_Ehdr; +typedef Elf32_Rel Elf_Rel; +typedef Elf32_Rela Elf_Rela; +typedef Elf32_Sym Elf_Sym; +typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Word Elf_Word; + +#endif /* __INCLUDE_ELF32_H */ diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.c b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.c new file mode 100644 index 0000000..c447ad7 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.c @@ -0,0 +1,383 @@ +/**************************************************************************** + * tools/cxd56/mkspk.c + * + * Copyright (C) 2007, 2008 Sony Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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. + *****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mkspk.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct args +{ + int core; + char *elffile; + char *savename; + char *outputfile; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t vmk[16] = + "\x27\xc0\xaf\x1b\x5d\xcb\xc6\xc5\x58\x22\x1c\xdd\xaf\xf3\x20\x21"; + +static struct args g_options = +{ + 0 +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static struct args *parse_args(int argc, char **argv) +{ + int opt; + int show_help; + struct args *args = &g_options; + char *endp; + + show_help = 0; + + if (argc < 2) + { + show_help = 1; + } + + memset(args, 0, sizeof(*args)); + args->core = -1; + + while ((opt = getopt(argc, argv, "h:c:")) != -1) + { + switch (opt) + { + case 'c': + args->core = strtol(optarg, &endp, 0); + if (*endp) + { + fprintf(stderr, "Invalid core number \"%s\"\n", optarg); + show_help = 1; + } + break; + + case 'h': + default: + show_help = 1; + } + } + + argc -= optind; + argv += optind; + + args->elffile = argv[0]; + args->savename = argv[1]; + argc -= 2; + argv += 2; + + if (argc > 0) + { + args->outputfile = strdup(argv[0]); + } + else + { + show_help = 1; + } + + /* Sanity checks for options */ + + if (show_help == 1) + { + fprintf(stderr, + "mkspk [-c ] []\n"); + exit(EXIT_FAILURE); + } + + if (args->core < 0) + { + fprintf(stderr, "Core number is not set. Please use -c option.\n"); + exit(EXIT_FAILURE); + } + + if (strlen(args->savename) > 63) + { + fprintf(stderr, "savename too long.\n"); + exit(EXIT_FAILURE); + } + + return args; +} + +static struct elf_file *load_elf(const char *filename) +{ + size_t fsize; + int pos; + char *buf; + FILE *fp; + struct elf_file *ef; + Elf32_Shdr *sh; + uint16_t i; + int ret; + + fp = fopen(filename, "rb"); + if (!fp) + { + return NULL; + } + + ef = (struct elf_file *)malloc(sizeof(*ef)); + if (!ef) + { + return NULL; + } + + pos = fseek(fp, 0, SEEK_END); + fsize = (size_t) ftell(fp); + fseek(fp, pos, SEEK_SET); + + buf = (char *)malloc(fsize); + if (!buf) + { + return NULL; + } + + ret = fread(buf, fsize, 1, fp); + fclose(fp); + if (ret != 1) + { + return NULL; + } + + ef->data = buf; + + ef->ehdr = (Elf32_Ehdr *) buf; + + Elf32_Ehdr *h = (Elf32_Ehdr *) buf; + + if (!(h->e_ident[EI_MAG0] == 0x7f && + h->e_ident[EI_MAG1] == 'E' && + h->e_ident[EI_MAG2] == 'L' && h->e_ident[EI_MAG3] == 'F')) + { + free(ef); + free(buf); + return NULL; + } + + ef->phdr = (Elf32_Phdr *) (buf + ef->ehdr->e_phoff); + ef->shdr = (Elf32_Shdr *) (buf + ef->ehdr->e_shoff); + ef->shstring = buf + ef->shdr[ef->ehdr->e_shstrndx].sh_offset; + + for (i = 0, sh = ef->shdr; i < ef->ehdr->e_shnum; i++, sh++) + { + if (sh->sh_type == SHT_SYMTAB) + { + ef->symtab = (Elf32_Sym *) (buf + sh->sh_offset); + ef->nsyms = sh->sh_size / sh->sh_entsize; + continue; + } + + if (sh->sh_type == SHT_STRTAB) + { + if (!strcmp(".strtab", ef->shstring + sh->sh_name)) + { + ef->string = buf + sh->sh_offset; + } + } + } + + return ef; +} + +static void *create_image(struct elf_file *elf, int core, char *savename, + int *image_size) +{ + char *img; + struct spk_header *header; + struct spk_prog_info *pi; + Elf32_Phdr *ph; + Elf32_Sym *sym; + char *name; + int snlen; + int nphs, psize, imgsize; + int i; + int j; + uint32_t offset; + uint32_t sp; + + snlen = alignup(strlen(savename) + 1, 16); + + nphs = 0; + psize = 0; + for (i = 0, ph = elf->phdr; i < elf->ehdr->e_phnum; i++, ph++) + { + if (ph->p_type != PT_LOAD || ph->p_filesz == 0) + { + continue; + } + + nphs++; + psize += alignup(ph->p_filesz, 16); + } + + imgsize = sizeof(*header) + snlen + (nphs * 16) + psize; + + img = (char *)malloc(imgsize + 32); + if (!img) + { + return NULL; + } + + *image_size = imgsize; + sym = elf->symtab; + name = elf->string; + sp = 0; + + for (j = 0; j < elf->nsyms; j++, sym++) + { + if (!strcmp("__stack", name + sym->st_name)) + { + sp = sym->st_value; + } + } + + memset(img, 0, imgsize); + + header = (struct spk_header *)img; + header->magic[0] = 0xef; + header->magic[1] = 'M'; + header->magic[2] = 'O'; + header->magic[3] = 'D'; + header->cpu = core; + + header->entry = elf->ehdr->e_entry; + header->stack = sp; + header->core = core; + + header->binaries = nphs; + header->phoffs = sizeof(*header) + snlen; + header->mode = 0777; + + strncpy(img + sizeof(*header), savename, 63); + + ph = elf->phdr; + pi = (struct spk_prog_info *)(img + header->phoffs); + offset = ((char *)pi - img) + (nphs * sizeof(*pi)); + for (i = 0; i < elf->ehdr->e_phnum; i++, ph++) + { + if (ph->p_type != PT_LOAD || ph->p_filesz == 0) + continue; + pi->load_address = ph->p_paddr; + pi->offset = offset; + pi->size = alignup(ph->p_filesz, 16); /* need 16 bytes align for + * decryption */ + pi->memsize = ph->p_memsz; + + memcpy(img + pi->offset, elf->data + ph->p_offset, ph->p_filesz); + + offset += alignup(ph->p_filesz, 16); + pi++; + } + + return img; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, char **argv) +{ + struct args *args; + struct elf_file *elf; + struct cipher *c; + uint8_t *spkimage; + int size = 0; + FILE *fp; + char footer[16]; + + args = parse_args(argc, argv); + + elf = load_elf(args->elffile); + if (!elf) + { + fprintf(stderr, "Loading ELF %s failure.\n", args->elffile); + exit(EXIT_FAILURE); + } + + spkimage = create_image(elf, args->core, args->savename, &size); + free(elf); + + c = cipher_init(vmk, NULL); + cipher_calc_cmac(c, spkimage, size, (uint8_t *) spkimage + size); + cipher_deinit(c); + + size += 16; /* Extend CMAC size */ + + snprintf(footer, 16, "MKSPK_BN_HOOTER"); + footer[15] = '\0'; + + fp = fopen(args->outputfile, "wb"); + if (!fp) + { + fprintf(stderr, "Output file open error.\n"); + free(spkimage); + exit(EXIT_FAILURE); + } + + fwrite(spkimage, size, 1, fp); + fwrite(footer, 16, 1, fp); + + fclose(fp); + + printf("File %s is successfully created.\n", args->outputfile); + free(args->outputfile); + + memset(spkimage, 0, size); + free(spkimage); + + exit(EXIT_SUCCESS); +} diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.h b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.h new file mode 100644 index 0000000..5c1b979 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/mkspk/mkspk.h @@ -0,0 +1,93 @@ +/**************************************************************************** + * tools/cxd56/mkspk.h + * + * Copyright (C) 2007, 2008 Sony Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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. + *****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "clefia.h" +#include "elf32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define EI_MAG0 0 /* File identification */ +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 + +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 + +#define PT_LOAD 1 + +#define alignup(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) +#define swap(a, b) { (a) ^= (b); (b) ^= (a); (a) ^= (b); } + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct spk_header + { + uint8_t magic[4]; + uint8_t cpu; + uint8_t reserved[11]; + uint32_t entry; + uint32_t stack; + uint16_t core; + uint16_t binaries; + uint16_t phoffs; + uint16_t mode; + }; + +struct spk_prog_info + { + uint32_t load_address; + uint32_t offset; + uint32_t size; + uint32_t memsize; + }; + +struct elf_file + { + Elf32_Ehdr *ehdr; + Elf32_Phdr *phdr; + Elf32_Shdr *shdr; + Elf32_Sym *symtab; + int nsyms; + char *shstring; + char *string; + char *data; + }; diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc new file mode 100644 index 0000000..cfa917f Binary files /dev/null and b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc differ diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/flash_writer.py b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/flash_writer.py new file mode 100755 index 0000000..840f10c --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/flash_writer.py @@ -0,0 +1,580 @@ +#! /usr/bin/env python3 + +# Copyright (C) 2018 Sony Semiconductor Solutions Corp. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name NuttX 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. +# + +import time +import sys +import os +import struct +import glob +import fnmatch +import errno +import telnetlib +import argparse +import shutil +import subprocess +import re +import xmodem + +import_serial_module = True + +# When SDK release, plase set SDK_RELEASE as True. +SDK_RELEASE = False + +if SDK_RELEASE : + PRINT_RAW_COMMAND = False + REBOOT_AT_END = True +else : + PRINT_RAW_COMMAND = True + REBOOT_AT_END = True + +try: + import serial +except: + import_serial_module = False + +# supported environment various +# CXD56_PORT +# CXD56_TELNETSRV_PORT +# CXD56_TELNETSRV_IP + +PROTOCOL_SERIAL = 0 +PROTOCOL_TELNET = 1 + +MAX_DOT_COUNT = 70 + +# configure parameters and default value +class ConfigArgs: + PROTOCOL_TYPE = None + SERIAL_PORT = "COM1" + SERVER_PORT = 4569 + SERVER_IP = "localhost" + EOL = bytes([10]) + WAIT_RESET = True + AUTO_RESET = False + DTR_RESET = False + XMODEM_BAUD = 0 + NO_SET_BOOTABLE = False + PACKAGE_NAME = [] + FILE_NAME = [] + ERASE_NAME = [] + PKGSYS_NAME = [] + PKGAPP_NAME = [] + PKGUPD_NAME = [] + +ROM_MSG = [b"Welcome to nash"] +XMDM_MSG = "Waiting for XMODEM (CRC or 1K) transfer. Ctrl-X to cancel." + +class ConfigArgsLoader(): + def __init__(self): + self.parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) + self.parser.add_argument("package_name", help="the name of the package to install", nargs='*') + self.parser.add_argument("-f", "--file", dest="file_name", help="save file", action='append') + self.parser.add_argument("-e", "--erase", dest="erase_name", help="erase file", action='append') + + self.parser.add_argument("-S", "--sys", dest="pkgsys_name", help="the name of the system package to install", action='append') + self.parser.add_argument("-A", "--app", dest="pkgapp_name", help="the name of the application package to install", action='append') + self.parser.add_argument("-U", "--upd", dest="pkgupd_name", help="the name of the updater package to install", action='append') + + self.parser.add_argument("-a", "--auto-reset", dest="auto_reset", + action="store_true", default=None, + help="try to auto reset develop board if possible") + self.parser.add_argument("-d", "--dtr-reset", dest="dtr_reset", + action="store_true", default=None, + help="try to auto reset develop board if possible") + self.parser.add_argument("-n", "--no-set-bootable", dest="no_set_bootable", + action="store_true", default=None, + help="not to set bootable") + + group = self.parser.add_argument_group() + group.add_argument("-i", "--server-ip", dest="server_ip", + help="the ip address connected to the telnet server") + group.add_argument("-p", "--server-port", dest="server_port", type=int, + help="the port connected to the telnet server") + + group = self.parser.add_argument_group() + group.add_argument("-c", "--serial-port", dest="serial_port", help="the serial port") + group.add_argument("-b", "--xmodem-baudrate", dest="xmodem_baud", help="Use the faster baudrate in xmodem") + + mutually_group = self.parser.add_mutually_exclusive_group() + mutually_group.add_argument("-t", "--telnet-protocol", dest="telnet_protocol", + action="store_true", default=None, + help="use the telnet protocol for binary transmission") + mutually_group.add_argument("-s", "--serial-protocol", dest="serial_protocol", + action="store_true", default=None, + help="use the serial port for binary transmission, default options") + + mutually_group2 = self.parser.add_mutually_exclusive_group() + mutually_group2.add_argument("-F", "--force-wait-reset", dest="wait_reset", + action="store_true", default=None, + help="force wait for pressing RESET button") + mutually_group2.add_argument("-N", "--no-wait-reset", dest="wait_reset", + action="store_false", default=None, + help="if possible, skip to wait for pressing RESET button") + + def update_config(self): + args = self.parser.parse_args() + + ConfigArgs.PACKAGE_NAME = args.package_name + ConfigArgs.FILE_NAME = args.file_name + ConfigArgs.ERASE_NAME = args.erase_name + ConfigArgs.PKGSYS_NAME = args.pkgsys_name + ConfigArgs.PKGAPP_NAME = args.pkgapp_name + ConfigArgs.PKGUPD_NAME = args.pkgupd_name + + # Get serial port or telnet server ip etc + if args.serial_protocol == True: + ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL + elif args.telnet_protocol == True: + ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET + + if ConfigArgs.PROTOCOL_TYPE == None: + proto = os.environ.get("CXD56_PROTOCOL") + if proto is not None: + if 's' in proto: + ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL + elif 't' in proto: + ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET + + if ConfigArgs.PROTOCOL_TYPE == None: + ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL + + if ConfigArgs.PROTOCOL_TYPE == PROTOCOL_SERIAL: + if args.serial_port is not None: + ConfigArgs.SERIAL_PORT = args.serial_port + else: + # Get serial port from the environment + port = os.environ.get("CXD56_PORT") + if port is not None: + ConfigArgs.SERIAL_PORT = port + else: + print("CXD56_PORT is not set, Use " + ConfigArgs.SERIAL_PORT + ".") + else: + ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET + if args.server_port is not None: + ConfigArgs.SERVER_PORT = args.server_port + else: + port = os.environ.get("CXD56_TELNETSRV_PORT") + if port is not None: + ConfigArgs.SERVER_PORT = port + else: + print("CXD56_TELNETSRV_PORT is not set, Use " + str(ConfigArgs.SERVER_PORT) + ".") + if args.server_ip is not None: + ConfigArgs.SERVER_IP = args.server_ip + else: + ip = os.environ.get("CXD56_TELNETSRV_IP") + if ip is not None: + ConfigArgs.SERVER_IP = ip + else: + print("CXD56_TELNETSRV_IP is not set, Use " + ConfigArgs.SERVER_IP + ".") + + if args.xmodem_baud is not None: + ConfigArgs.XMODEM_BAUD = args.xmodem_baud + + if args.auto_reset is not None: + ConfigArgs.AUTO_RESET = args.auto_reset + + if args.dtr_reset is not None: + ConfigArgs.DTR_RESET = args.dtr_reset + + if args.no_set_bootable is not None: + ConfigArgs.NO_SET_BOOTABLE = args.no_set_bootable + + if args.wait_reset is not None: + ConfigArgs.WAIT_RESET = args.wait_reset + +class TelnetDev: + def __init__(self): + srv_ipaddr = ConfigArgs.SERVER_IP + srv_port = ConfigArgs.SERVER_PORT + self.recvbuf = b''; + try: + self.telnet = telnetlib.Telnet(host=srv_ipaddr, port=srv_port, timeout=10) + # There is a ack to be sent after connecting to the telnet server. + self.telnet.write(b"\xff") + except Exception as e: + print("Cannot connect to the server %s:%d" % (srv_ipaddr, srv_port)) + sys.exit(e.args[0]) + + def readline(self, size=None): + res = b'' + ch = b'' + while ch != ConfigArgs.EOL: + ch = self.getc_raw(1, timeout=0.1) + if ch == b'': + return res + res += ch + return res + + def getc_raw(self, size, timeout=1): + res = b'' + tm = time.monotonic() + while size > 0: + while self.recvbuf == b'': + self.recvbuf = self.telnet.read_eager() + if self.recvbuf == b'': + if (time.monotonic() - tm) > timeout: + return res + time.sleep(0.1) + res += self.recvbuf[0:1] + self.recvbuf = self.recvbuf[1:] + size -= 1 + return res + + def write(self, buffer): + self.telnet.write(buffer) + + def discard_inputs(self, timeout=1.0): + while True: + ch = self.getc_raw(1, timeout=timeout) + if ch == b'': + break + + def getc(self, size, timeout=1): + c = self.getc_raw(size, timeout) + return c + + def putc(self, buffer, timeout=1): + self.telnet.write(buffer) + self.show_progress(len(buffer)) + + def reboot(self): + # no-op + pass + + def set_file_size(self, filesize): + self.bytes_transfered = 0 + self.filesize = filesize + self.count = 0 + + def show_progress(self, sendsize): + if PRINT_RAW_COMMAND: + if self.count < MAX_DOT_COUNT: + self.bytes_transfered = self.bytes_transfered + sendsize + cur_count = int(self.bytes_transfered * MAX_DOT_COUNT / self.filesize) + if MAX_DOT_COUNT < cur_count: + cur_count = MAX_DOT_COUNT + for idx in range(cur_count - self.count): + print('#',end='') + sys.stdout.flush() + self.count = cur_count + if self.count == MAX_DOT_COUNT: + print("\n") + +class SerialDev: + def __init__(self): + if import_serial_module is False: + print("Cannot import serial module, maybe it's not install yet.") + print("\n", end="") + print("Please install python-setuptool by Cygwin installer.") + print("After that use easy_intall command to install serial module") + print(" $ cd tool/") + print(" $ python3 -m easy_install pyserial-2.7.tar.gz") + quit() + else: + port = ConfigArgs.SERIAL_PORT + try: + self.serial = serial.Serial(port, baudrate=115200, + parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, + bytesize=serial.EIGHTBITS, timeout=0.1) + except Exception as e: + print("Cannot open port : " + port) + sys.exit(e.args[0]) + + def readline(self, size=None): + return self.serial.readline(size) + + def write(self, buffer): + self.serial.write(buffer) + self.serial.flush() + + def discard_inputs(self, timeout=1.0): + time.sleep(timeout) + self.serial.flushInput() + + def getc(self, size, timeout=1): + self.serial.timeout = timeout + c = self.serial.read(size) + self.serial.timeout = 0.1 + return c + + def putc(self, buffer, timeout=1): + self.serial.timeout = timeout + self.serial.write(buffer) + self.serial.flush() + self.serial.timeout = 0.1 + self.show_progress(len(buffer)) + + # Note: windows platform dependent code + def putc_win(self, buffer, timeout=1): + self.serial.write(buffer) + self.show_progress(len(buffer)) + while True: + if self.serial.out_waiting == 0: + break + + def setBaudrate(self, baudrate): +# self.serial.setBaudrate(baudrate) + self.serial.baudrate = baudrate + + def reboot(self): + # Target Reset by DTR + self.serial.setDTR(False) + self.serial.setDTR(True) + self.serial.setDTR(False) + + def set_file_size(self, filesize): + self.bytes_transfered = 0 + self.filesize = filesize + self.count = 0 + + def show_progress(self, sendsize): + if PRINT_RAW_COMMAND: + if self.count < MAX_DOT_COUNT: + self.bytes_transfered = self.bytes_transfered + sendsize + cur_count = int(self.bytes_transfered * MAX_DOT_COUNT / self.filesize) + if MAX_DOT_COUNT < cur_count: + cur_count = MAX_DOT_COUNT + for idx in range(cur_count - self.count): + print('#',end='') + sys.stdout.flush() + self.count = cur_count + if self.count == MAX_DOT_COUNT: + print("\n") + +class FlashWriter: + def __init__(self, protocol_sel=PROTOCOL_SERIAL): + if protocol_sel == PROTOCOL_TELNET: + self.serial = TelnetDev() + else: + self.serial = SerialDev() + + def cancel_autoboot(self) : + boot_msg = '' + self.serial.reboot() # Target reboot before send 'r' + while boot_msg == '' : + rx = self.serial.readline().strip() + self.serial.write(b"r") # Send "r" key to avoid auto boot + for msg in ROM_MSG : + if msg in rx : + boot_msg = msg + break + while True : + rx = self.serial.readline().decode(errors="replace").strip() + if "updater" in rx : + # Workaround : Sometime first character is dropped. + # Send line feed as air shot before actual command. + self.serial.write(b"\n") # Send line feed + self.serial.discard_inputs()# Clear input buffer to sync + return boot_msg.decode(errors="ignore") + + def recv(self): + rx = self.serial.readline() + if PRINT_RAW_COMMAND : + serial_line = rx.decode(errors="replace") + if serial_line.strip() != "" and not serial_line.startswith(XMDM_MSG): + print(serial_line, end="") + return rx + + def wait(self, string): + while True: + rx = self.recv() + if string.encode() in rx: + time.sleep(0.1) + break + + def wait_for_prompt(self): + prompt_pat = re.compile(b"updater") + while True: + rx = self.recv() + if prompt_pat.search(rx): + time.sleep(0.1) + break + + def send(self, string): + self.serial.write(str(string).encode() + b"\n") + rx = self.serial.readline() + if PRINT_RAW_COMMAND : + print(rx.decode(errors="replace"), end="") + + def read_output(self, prompt_text) : + output = [] + while True : + rx = self.serial.readline() + if prompt_text.encode() in rx : + time.sleep(0.1) + break + if rx != "" : + output.append(rx.decode(errors="ignore").rstrip()) + return output + + def install_files(self, files, command) : + if ConfigArgs.XMODEM_BAUD: + command += " -b " + ConfigArgs.XMODEM_BAUD + if os.name == 'nt': + modem = xmodem.XMODEM(self.serial.getc, self.serial.putc_win, 'xmodem1k') + else: + modem = xmodem.XMODEM(self.serial.getc, self.serial.putc, 'xmodem1k') + for file in files: + with open(file, "rb") as bin : + self.send(command) + print("Install " + file) + self.wait(XMDM_MSG) + print("|0%" + + "-" * (int(MAX_DOT_COUNT / 2) - 6) + + "50%" + + "-" * (MAX_DOT_COUNT - int(MAX_DOT_COUNT / 2) - 5) + + "100%|") + if ConfigArgs.XMODEM_BAUD: + self.serial.setBaudrate(ConfigArgs.XMODEM_BAUD) + self.serial.discard_inputs() # Clear input buffer to sync + self.serial.set_file_size(os.path.getsize(file)) + modem.send(bin) + if ConfigArgs.XMODEM_BAUD: + self.serial.setBaudrate(115200) + self.wait_for_prompt() + + def save_files(self, files) : + if ConfigArgs.XMODEM_BAUD: + command = "save_file -b " + ConfigArgs.XMODEM_BAUD + " -x " + else: + command = "save_file -x " + if os.name == 'nt': + modem = xmodem.XMODEM(self.serial.getc, self.serial.putc_win, 'xmodem1k') + else: + modem = xmodem.XMODEM(self.serial.getc, self.serial.putc, 'xmodem1k') + for file in files: + with open(file, "rb") as bin : + self.send(command + os.path.basename(file)) + print("Save " + file) + self.wait(XMDM_MSG) + if ConfigArgs.XMODEM_BAUD: + self.serial.setBaudrate(ConfigArgs.XMODEM_BAUD) + self.serial.discard_inputs() # Clear input buffer to sync + self.serial.set_file_size(os.path.getsize(file)) + modem.send(bin) + if ConfigArgs.XMODEM_BAUD: + self.serial.setBaudrate(115200) + self.wait_for_prompt() + self.send("chmod d+rw " + os.path.basename(file)) + self.wait_for_prompt() + + def delete_files(self, files) : + for file in files : + self.delete_binary(file) + + def delete_binary(self, bin_name) : + self.send("rm " + bin_name) + self.wait_for_prompt() + +def main(): + try: + config_loader = ConfigArgsLoader() + config_loader.update_config() + except: + return errno.EINVAL + + # Wait to reset the board + writer = FlashWriter(ConfigArgs.PROTOCOL_TYPE) + + do_wait_reset = True + if ConfigArgs.AUTO_RESET: + if subprocess.call("cd " + sys.path[0] + "; ./reset_board.sh", shell=True) == 0: + print("auto reset board sucess!!") + do_wait_reset = False + bootrom_msg = writer.cancel_autoboot() + + if ConfigArgs.DTR_RESET: + do_wait_reset = False + bootrom_msg = writer.cancel_autoboot() + + if ConfigArgs.WAIT_RESET == False and do_wait_reset == True: + rx = writer.recv() + time.sleep(1) + for i in range(3): + writer.send("") + rx = writer.recv() + if "updater".encode() in rx: + # No need to wait for reset + do_wait_reset = False + break + time.sleep(1) + + if do_wait_reset: + # Wait to reset the board + print('Please press RESET button on target board') + sys.stdout.flush() + bootrom_msg = writer.cancel_autoboot() + + # Remove files + if ConfigArgs.ERASE_NAME : + print(">>> Remove exisiting files ...") + writer.delete_files(ConfigArgs.ERASE_NAME) + + # Install files + if ConfigArgs.PACKAGE_NAME or ConfigArgs.PKGSYS_NAME or ConfigArgs.PKGAPP_NAME or ConfigArgs.PKGUPD_NAME: + print(">>> Install files ...") + if ConfigArgs.PACKAGE_NAME : + writer.install_files(ConfigArgs.PACKAGE_NAME, "install") + if ConfigArgs.PKGSYS_NAME : + writer.install_files(ConfigArgs.PKGSYS_NAME, "install") + if ConfigArgs.PKGAPP_NAME : + writer.install_files(ConfigArgs.PKGAPP_NAME, "install") + if ConfigArgs.PKGUPD_NAME : + writer.install_files(ConfigArgs.PKGUPD_NAME, "install -k updater.key") + + # Save files + if ConfigArgs.FILE_NAME : + print(">>> Save files ...") + writer.save_files(ConfigArgs.FILE_NAME) + + # Set auto boot + if not ConfigArgs.NO_SET_BOOTABLE: + print(">>> Save Configuration to FlashROM ...") + writer.send("set bootable M0P") + writer.wait_for_prompt() + + # Sync all cached data to flash + writer.send("sync") + writer.wait_for_prompt() + + if REBOOT_AT_END : + print("Restarting the board ...") + writer.send("reboot") + + return 0 + +if __name__ == "__main__": + try: + sys.exit(main()) + except KeyboardInterrupt: + print("Canceled by keyboard interrupt.") + pass diff --git a/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/xmodem.py b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/xmodem.py new file mode 100644 index 0000000..c934300 --- /dev/null +++ b/circuitpython/lib/tinyusb/hw/mcu/sony/cxd56/tools/xmodem.py @@ -0,0 +1,590 @@ +''' +=============================== + XMODEM file transfer protocol +=============================== + +.. $Id$ + +This is a literal implementation of XMODEM.TXT_, XMODEM1K.TXT_ and +XMODMCRC.TXT_, support for YMODEM and ZMODEM is pending. YMODEM should +be fairly easy to implement as it is a hack on top of the XMODEM +protocol using sequence bytes ``0x00`` for sending file names (and some +meta data). + +.. _XMODEM.TXT: doc/XMODEM.TXT +.. _XMODEM1K.TXT: doc/XMODEM1K.TXT +.. _XMODMCRC.TXT: doc/XMODMCRC.TXT + +Data flow example including error recovery +========================================== + +Here is a sample of the data flow, sending a 3-block message. +It includes the two most common line hits - a garbaged block, +and an ``ACK`` reply getting garbaged. ``CRC`` or ``CSUM`` represents +the checksum bytes. + +XMODEM 128 byte blocks +---------------------- + +:: + + SENDER RECEIVER + + <-- NAK + SOH 01 FE Data[128] CSUM --> + <-- ACK + SOH 02 FD Data[128] CSUM --> + <-- ACK + SOH 03 FC Data[128] CSUM --> + <-- ACK + SOH 04 FB Data[128] CSUM --> + <-- ACK + SOH 05 FA Data[100] CPMEOF[28] CSUM --> + <-- ACK + EOT --> + <-- ACK + +XMODEM-1k blocks, CRC mode +-------------------------- + +:: + + SENDER RECEIVER + + <-- C + STX 01 FE Data[1024] CRC CRC --> + <-- ACK + STX 02 FD Data[1024] CRC CRC --> + <-- ACK + STX 03 FC Data[1000] CPMEOF[24] CRC CRC --> + <-- ACK + EOT --> + <-- ACK + +Mixed 1024 and 128 byte Blocks +------------------------------ + +:: + + SENDER RECEIVER + + <-- C + STX 01 FE Data[1024] CRC CRC --> + <-- ACK + STX 02 FD Data[1024] CRC CRC --> + <-- ACK + SOH 03 FC Data[128] CRC CRC --> + <-- ACK + SOH 04 FB Data[100] CPMEOF[28] CRC CRC --> + <-- ACK + EOT --> + <-- ACK + +YMODEM Batch Transmission Session (1 file) +------------------------------------------ + +:: + + SENDER RECEIVER + <-- C (command:rb) + SOH 00 FF foo.c NUL[123] CRC CRC --> + <-- ACK + <-- C + SOH 01 FE Data[128] CRC CRC --> + <-- ACK + SOH 02 FC Data[128] CRC CRC --> + <-- ACK + SOH 03 FB Data[100] CPMEOF[28] CRC CRC --> + <-- ACK + EOT --> + <-- NAK + EOT --> + <-- ACK + <-- C + SOH 00 FF NUL[128] CRC CRC --> + <-- ACK + + +''' + +__author__ = 'Wijnand Modderman ' +__copyright__ = ['Copyright (c) 2010 Wijnand Modderman', + 'Copyright (c) 1981 Chuck Forsberg'] +__license__ = 'MIT' +__version__ = '0.3.2' + +import logging +import time +import sys +from functools import partial +import collections + +# Loggerr +log = logging.getLogger('xmodem') + +# Protocol bytes +SOH = bytes([0x01]) +STX = bytes([0x02]) +EOT = bytes([0x04]) +ACK = bytes([0x06]) +DLE = bytes([0x10]) +NAK = bytes([0x15]) +CAN = bytes([0x18]) +CRC = bytes([0x43]) # C + + +class XMODEM(object): + ''' + XMODEM Protocol handler, expects an object to read from and an object to + write to. + + >>> def getc(size, timeout=1): + ... return data or None + ... + >>> def putc(data, timeout=1): + ... return size or None + ... + >>> modem = XMODEM(getc, putc) + + + :param getc: Function to retreive bytes from a stream + :type getc: callable + :param putc: Function to transmit bytes to a stream + :type putc: callable + :param mode: XMODEM protocol mode + :type mode: string + :param pad: Padding character to make the packets match the packet size + :type pad: char + + ''' + + # crctab calculated by Mark G. Mendel, Network Systems Corporation + crctable = [ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, + ] + + def __init__(self, getc, putc, mode='xmodem', pad=b'\x1a'): + self.getc = getc + self.putc = putc + self.mode = mode + self.pad = pad + + def abort(self, count=2, timeout=60): + ''' + Send an abort sequence using CAN bytes. + ''' + for counter in range(0, count): + self.putc(CAN, timeout) + + def send(self, stream, retry=32, timeout=360, quiet=0, callback=None): + ''' + Send a stream via the XMODEM protocol. + + >>> stream = file('/etc/issue', 'rb') + >>> print modem.send(stream) + True + + Returns ``True`` upon succesful transmission or ``False`` in case of + failure. + + :param stream: The stream object to send data from. + :type stream: stream (file, etc.) + :param retry: The maximum number of times to try to resend a failed + packet before failing. + :type retry: int + :param timeout: The number of seconds to wait for a response before + timing out. + :type timeout: int + :param quiet: If 0, it prints info to stderr. If 1, it does not print any info. + :type quiet: int + :param callback: Reference to a callback function that has the + following signature. This is useful for + getting status updates while a xmodem + transfer is underway. + Expected callback signature: + def callback(total_packets, success_count, error_count) + :type callback: callable + ''' + + # initialize protocol + try: + packet_size = dict( + xmodem = 128, + xmodem1k = 1024, + )[self.mode] + except AttributeError: + raise ValueError("An invalid mode was supplied") + + error_count = 0 + crc_mode = 0 + cancel = 0 + while True: + char = self.getc(1) + if char: + if char == NAK: + crc_mode = 0 + break + elif char == CRC: + crc_mode = 1 + break + elif char == CAN: + if not quiet: + print('received CAN', file=sys.stderr) + if cancel: + return False + else: + cancel = 1 + else: + log.error('send ERROR expected NAK/CRC, got %s' % \ + (ord(char),)) + + error_count += 1 + if error_count >= retry: + self.abort(timeout=timeout) + return False + + # send data + error_count = 0 + success_count = 0 + total_packets = 0 + sequence = 1 + while True: + data = stream.read(packet_size) + if not data: + log.info('sending EOT') + # end of stream + break + total_packets += 1 + data = data.ljust(packet_size, self.pad) + if crc_mode: + crc = self.calc_crc(data) + else: + crc = self.calc_checksum(data) + + # emit packet + while True: + if packet_size == 128: + self.putc(SOH) + else: # packet_size == 1024 + self.putc(STX) + self.putc(bytes([sequence])) + self.putc(bytes([0xff - sequence])) + self.putc(data) + if crc_mode: + self.putc(bytes([crc >> 8])) + self.putc(bytes([crc & 0xff])) + else: + self.putc(bytes([crc])) + + char = self.getc(1, timeout) + if char == ACK: + success_count += 1 + if isinstance(callback, collections.Callable): + callback(total_packets, success_count, error_count) + break + if char == NAK: + error_count += 1 + if isinstance(callback, collections.Callable): + callback(total_packets, success_count, error_count) + if error_count >= retry: + # excessive amounts of retransmissions requested, + # abort transfer + self.abort(timeout=timeout) + log.warning('excessive NAKs, transfer aborted') + return False + + # return to loop and resend + continue + else: + log.error('Not ACK, Not NAK') + error_count += 1 + if isinstance(callback, collections.Callable): + callback(total_packets, success_count, error_count) + if error_count >= retry: + # excessive amounts of retransmissions requested, + # abort transfer + self.abort(timeout=timeout) + log.warning('excessive protocol errors, transfer aborted') + return False + + # return to loop and resend + continue + + # protocol error + self.abort(timeout=timeout) + log.error('protocol error') + return False + + # keep track of sequence + sequence = (sequence + 1) % 0x100 + + while True: + # end of transmission + self.putc(EOT) + + #An ACK should be returned + char = self.getc(1, timeout) + if char == ACK: + break + else: + error_count += 1 + if error_count >= retry: + self.abort(timeout=timeout) + log.warning('EOT was not ACKd, transfer aborted') + return False + + return True + + def recv(self, stream, crc_mode=1, retry=16, timeout=60, delay=1, quiet=0): + ''' + Receive a stream via the XMODEM protocol. + + >>> stream = file('/etc/issue', 'wb') + >>> print modem.recv(stream) + 2342 + + Returns the number of bytes received on success or ``None`` in case of + failure. + ''' + + # initiate protocol + error_count = 0 + char = 0 + cancel = 0 + while True: + # first try CRC mode, if this fails, + # fall back to checksum mode + if error_count >= retry: + self.abort(timeout=timeout) + return None + elif crc_mode and error_count < (retry / 2): + if not self.putc(CRC): + time.sleep(delay) + error_count += 1 + else: + crc_mode = 0 + if not self.putc(NAK): + time.sleep(delay) + error_count += 1 + + char = self.getc(1, timeout) + if not char: + error_count += 1 + continue + elif char == SOH: + #crc_mode = 0 + break + elif char == STX: + break + elif char == CAN: + if cancel: + return None + else: + cancel = 1 + else: + error_count += 1 + + # read data + error_count = 0 + income_size = 0 + packet_size = 128 + sequence = 1 + cancel = 0 + while True: + while True: + if char == SOH: + packet_size = 128 + break + elif char == STX: + packet_size = 1024 + break + elif char == EOT: + # We received an EOT, so send an ACK and return the received + # data length + self.putc(ACK) + return income_size + elif char == CAN: + # cancel at two consecutive cancels + if cancel: + return None + else: + cancel = 1 + else: + if not quiet: + print('recv ERROR expected SOH/EOT, got', ord(char), file=sys.stderr) + error_count += 1 + if error_count >= retry: + self.abort() + return None + # read sequence + error_count = 0 + cancel = 0 + seq1 = ord(self.getc(1)) + seq2 = 0xff - ord(self.getc(1)) + if seq1 == sequence and seq2 == sequence: + # sequence is ok, read packet + # packet_size + checksum + data = self.getc(packet_size + 1 + crc_mode, timeout) + if crc_mode: + csum = (ord(data[-2]) << 8) + ord(data[-1]) + data = data[:-2] + log.debug('CRC (%04x <> %04x)' % \ + (csum, self.calc_crc(data))) + valid = csum == self.calc_crc(data) + else: + csum = data[-1] + data = data[:-1] + log.debug('checksum (checksum(%02x <> %02x)' % \ + (ord(csum), self.calc_checksum(data))) + valid = ord(csum) == self.calc_checksum(data) + + # valid data, append chunk + if valid: + income_size += len(data) + stream.write(data) + self.putc(ACK) + sequence = (sequence + 1) % 0x100 + char = self.getc(1, timeout) + continue + else: + # consume data + self.getc(packet_size + 1 + crc_mode) + self.debug('expecting sequence %d, got %d/%d' % \ + (sequence, seq1, seq2)) + + # something went wrong, request retransmission + self.putc(NAK) + + def calc_checksum(self, data, checksum=0): + ''' + Calculate the checksum for a given block of data, can also be used to + update a checksum. + + >>> csum = modem.calc_checksum('hello') + >>> csum = modem.calc_checksum('world', csum) + >>> hex(csum) + '0x3c' + + ''' + return (sum(map(ord, data)) + checksum) % 256 + + def calc_crc(self, data, crc=0): + ''' + Calculate the Cyclic Redundancy Check for a given block of data, can + also be used to update a CRC. + + >>> crc = modem.calc_crc('hello') + >>> crc = modem.calc_crc('world', crc) + >>> hex(crc) + '0xd5e3' + + ''' + for char in data: + crc = (crc << 8) ^ self.crctable[((crc >> 8) ^ int(char)) & 0xff] + return crc & 0xffff + + +XMODEM1k = partial(XMODEM, mode='xmodem1k') + + +def run(): + import optparse + import subprocess + + parser = optparse.OptionParser(usage='%prog [] filename filename') + parser.add_option('-m', '--mode', default='xmodem', + help='XMODEM mode (xmodem, xmodem1k)') + + options, args = parser.parse_args() + if len(args) != 3: + parser.error('invalid arguments') + return 1 + + elif args[0] not in ('send', 'recv'): + parser.error('invalid mode') + return 1 + + def _func(so, si): + import select + import subprocess + + print('si', si) + print('so', so) + + def getc(size, timeout=3): + w,t,f = select.select([so], [], [], timeout) + if w: + data = so.read(size) + else: + data = None + + print('getc(', repr(data), ')') + return data + + def putc(data, timeout=3): + w,t,f = select.select([], [si], [], timeout) + if t: + si.write(data) + si.flush() + size = len(data) + else: + size = None + + print('putc(', repr(data), repr(size), ')') + return size + + return getc, putc + + def _pipe(*command): + pipe = subprocess.Popen(command, + stdout=subprocess.PIPE, stdin=subprocess.PIPE) + return pipe.stdout, pipe.stdin + + if args[0] == 'recv': + import io + getc, putc = _func(*_pipe('sz', '--xmodem', args[2])) + stream = open(args[1], 'wb') + xmodem = XMODEM(getc, putc, mode=options.mode) + status = xmodem.recv(stream, retry=8) + stream.close() + + elif args[0] == 'send': + getc, putc = _func(*_pipe('rz', '--xmodem', args[2])) + stream = open(args[1], 'rb') + xmodem = XMODEM(getc, putc, mode=options.mode) + status = xmodem.send(stream, retry=8) + stream.close() + +if __name__ == '__main__': + sys.exit(run()) diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/License.txt b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/License.txt new file mode 100644 index 0000000..e1f5f89 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/License.txt @@ -0,0 +1,34 @@ +Important - Read carefully: + +SEGGER RTT - Real Time Transfer for embedded targets + +All rights reserved. + +SEGGER strongly recommends to not make any changes +to or modify the source code of this software in order to stay +compatible with the RTT protocol and J-Link. + +Redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following +condition is met: + +o Redistributions of source code must retain the above copyright + notice, this condition and the following disclaimer. + +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 SEGGER Microcontroller 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. + + +(c) 2014 - 2016 SEGGER Microcontroller GmbH +www.segger.com diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/README.txt b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/README.txt new file mode 100644 index 0000000..49ec655 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/README.txt @@ -0,0 +1,20 @@ +README.txt for the SEGGER RTT Implementation Pack. + +Included files: +=============== +Root Directory + - Examples + - Main_RTT_InputEchoApp.c - Sample application which echoes input on Channel 0. + - Main_RTT_MenuApp.c - Sample application to demonstrate RTT bi-directional functionality. + - Main_RTT_PrintfTest.c - Sample application to test RTT small printf implementation. + - Main_RTT_SpeedTestApp.c - Sample application for measuring RTT performance. embOS needed. + - RTT + - SEGGER_RTT.c - The RTT implementation. + - SEGGER_RTT.h - Header for RTT implementation. + - SEGGER_RTT_Conf.h - Pre-processor configuration for the RTT implementation. + - SEGGER_RTT_Printf.c - Simple implementation of printf to write formatted strings via RTT. + - Syscalls + - RTT_Syscalls_GCC.c - Low-level syscalls to retarget printf() to RTT with GCC / Newlib. + - RTT_Syscalls_IAR.c - Low-level syscalls to retarget printf() to RTT with IAR compiler. + - RTT_Syscalls_KEIL.c - Low-level syscalls to retarget printf() to RTT with KEIL/uVision compiler. + - RTT_Syscalls_SES.c - Low-level syscalls to retarget printf() to RTT with SEGGER Embedded Studio. diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.c b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.c new file mode 100644 index 0000000..3ad2b1a --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.c @@ -0,0 +1,2005 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 17697 $ + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef STRCPY + #define STRCPY(pDest, pSrc, NumBytes) strcpy((pDest), (pSrc)) +#endif + +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 +#endif + +#ifndef SEGGER_RTT_MEMCPY + #ifdef MEMCPY + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes)) + #else + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) + #endif +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +#if (defined __ICCARM__) || (defined __ICCRX__) + #define RTT_PRAGMA(P) _Pragma(#P) +#endif + +#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT + #if (defined __GNUC__) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #elif (defined __ICCARM__) || (defined __ICCRX__) + #define PRAGMA(A) _Pragma(#A) +#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #else + #error "Alignment not supported for this compiler." + #endif +#else + #define SEGGER_RTT_ALIGN(Var, Alignment) Var +#endif + +#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) + #if (defined __GNUC__) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var + #elif (defined __ICCARM__) || (defined __ICCRX__) +#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var + #else + #error "Section placement not supported for this compiler." + #endif +#else + #define SEGGER_RTT_PUT_SECTION(Var, Section) Var +#endif + + +#if SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) +#else + #define SEGGER_RTT_CB_ALIGN(Var) Var +#endif + +#if SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) +#else + #define SEGGER_RTT_BUFFER_ALIGN(Var) Var +#endif + + +#if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) +#else + #define SEGGER_RTT_PUT_CB_SECTION(Var) Var +#endif + +#if defined(SEGGER_RTT_BUFFER_SECTION) + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) +#else + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// RTT Control Block and allocate buffers for channel 0 +// +SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); + +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); + +static unsigned char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + STRCPY(&p->acID[7], "RTT", 9); + STRCPY(&p->acID[0], "SEGGER", 7); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytesWritten += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + while (NumBytesToWrite--) { + *pDst++ = *pBuffer++; + }; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; +#endif + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytesAtOnce = Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pDst = pRing->pBuffer; + NumBytesAtOnce = NumBytes - Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pRing->WrOff = NumBytes - Rem; +#else + NumBytesAtOnce = Rem; + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; +#endif + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + unsigned char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, (const char*)ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadUpBufferNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the application. +* Do not lock against interrupts and multiple access. +* Used to do the same operation that J-Link does, to transfer +* RTT data via other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of Up-buffer to be used. +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +*/ +unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_UP* pRing; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + const char* pSrc; +#endif + // + INIT(); + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + // + // Update read offset of buffer + // + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + const char* pSrc; +#endif + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_ReadUpBuffer +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the application. +* Used to do the same operation that J-Link does, to transfer +* RTT data via other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of Up-buffer to be used. +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +* This function locks against all other RTT operations. I.e. during +* the read operation, writing is also locked. +* If only one consumer reads from the up buffer, +* call sEGGER_RTT_ReadUpBufferNoLock() instead. +*/ +unsigned SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + // + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadUpBufferNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + // + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + pRing->WrOff; + Avail = NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff += Avail; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, NumBytes); + pRing->WrOff += NumBytes; +#endif + break; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + pRing->WrOff; + NumBytes -= Avail; + while (Avail--) { + *pDst++ = *pData++; + }; + pRing->WrOff = 0; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, Avail); + pData += Avail; + pRing->WrOff = 0; + NumBytes -= Avail; +#endif + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* MUST be > 0!!! +* This is done for performance reasons, so no initial check has do be done. +* +* Return value +* 1: Data has been copied +* 0: No space, data has not been copied +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +#if (RTT_USE_ASM == 0) +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + // + // Cases: + // 1) RdOff <= WrOff => Space until wrap-around is sufficient + // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) + // 3) RdOff < WrOff => No space in buf + // 4) RdOff > WrOff => Space is sufficient + // 5) RdOff > WrOff => No space in buf + // + // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough + // + pData = (const char *)pBuffer; + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { // Case 1), 2) or 3) + Avail = pRing->SizeOfBuffer - WrOff - 1u; // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) + if (Avail >= NumBytes) { // Case 1)? +CopyStraight: + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + Avail += RdOff; // Space incl. wrap-around + if (Avail >= NumBytes) { // Case 2? => If not, we have case 3) (does not fit) + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + memcpy(pRing->pBuffer + WrOff, pData, Rem); // Copy 1st chunk + NumBytes -= Rem; + // + // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used + // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element + // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks + // Therefore, check if 2nd memcpy is necessary at all + // + if (NumBytes) { + memcpy(pRing->pBuffer, pData + Rem, NumBytes); + } + pRing->WrOff = NumBytes; + return 1; + } + } else { // Potential case 4) + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { // Case 4)? => If not, we have case 5) (does not fit) + goto CopyStraight; + } + } + return 0; // No space in buffer +} +#endif + +/********************************************************************* +* +* SEGGER_RTT_WriteDownBufferNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block inside a buffer. +* SEGGER_RTT_WriteDownBufferNoLock does not lock the application. +* Used to do the same operation that J-Link does, to transfer +* RTT data from other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of "Down"-buffer to be used. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Down"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +*/ +unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + + pData = (const char *)pBuffer; + // + // Get "to-target" ring buffer. + // It is save to cast that to a "to-host" buffer. Up and Down buffer differ in volatility of offsets that might be modified by J-Link. + // + pRing = (SEGGER_RTT_BUFFER_UP*)&_SEGGER_RTT.aDown[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteDownBuffer +* +* Function description +* Stores a specified number of characters in SEGGER RTT control block in a buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Down"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +* This function locks against all other RTT operations. I.e. during +* the write operation, writing from the application is also locked. +* If only one consumer writes to the down buffer, +* call SEGGER_RTT_WriteDownBufferNoLock() instead. +*/ +unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteDownBufferNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkipNoLock +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* SEGGER_RTT_PutCharSkipNoLock does not lock the application and +* skips the byte, if it does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + +unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkip +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +*/ + +unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + + /********************************************************************* +* +* SEGGER_RTT_PutChar +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ + +unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Wait for free space if mode is set to blocking + // + if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + while (WrOff == pRing->RdOff) { + ; + } + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_HasDataUp +* +* Function description +* Check if there is data remaining to be sent in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + v = pRing->RdOff; + return pRing->WrOff - v; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsUpBuffer +* +* Function description +* Run-time configuration of specific up-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsDownBuffer +* +* Function description +* Run-time configuration of specific Down-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (unsigned char TerminalId) { + unsigned char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFu; + if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, (const char*)ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, (const char*)ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = STRLEN(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetAvailWriteSpace +* +* Function description +* Returns the number of bytes available in the ring buffer. +* +* Parameters +* BufferIndex Index of the up buffer. +* +* Return value +* Number of bytes that are free in the selected up buffer. +*/ +unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex){ + return _GetAvailWriteSpace(&_SEGGER_RTT.aUp[BufferIndex]); +} + + +/********************************************************************* +* +* SEGGER_RTT_GetBytesInBuffer() +* +* Function description +* Returns the number of bytes currently used in the up buffer. +* +* Parameters +* BufferIndex Index of the up buffer. +* +* Return value +* Number of bytes that are used in the buffer. +*/ +unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = _SEGGER_RTT.aUp[BufferIndex].RdOff; + WrOff = _SEGGER_RTT.aUp[BufferIndex].WrOff; + if (RdOff <= WrOff) { + r = WrOff - RdOff; + } else { + r = _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer - (WrOff - RdOff); + } + return r; +} + +/*************************** End of file ****************************/ diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.h b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.h new file mode 100644 index 0000000..3c04df5 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT.h @@ -0,0 +1,321 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +Revision: $Rev: 17697 $ +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + + + +/********************************************************************* +* +* Defines, defaults +* +********************************************************************** +*/ +#ifndef RTT_USE_ASM + #if (defined __SES_ARM) // SEGGER Embedded Studio + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __CROSSWORKS_ARM) // Rowley Crossworks + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __GNUC__) // GCC + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __clang__) // Clang compiler + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __IASMARM__) // IAR assembler + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ICCARM__) // IAR compiler + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #else + #define _CC_HAS_RTT_ASM_SUPPORT 0 + #endif + #if (defined __ARM_ARCH_7M__) // Cortex-M3/4 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARM_ARCH_7EM__) // Cortex-M7 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARM7M__) // IAR Cortex-M3/4 + #if (__CORE__ == __ARM7M__) + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #else + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #endif + #elif (defined __ARM7EM__) // IAR Cortex-M7 + #if (__CORE__ == __ARM7EM__) + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #else + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #endif + #else + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #endif + // + // If IDE and core support the ASM version, enable ASM version by default + // + #if (_CC_HAS_RTT_ASM_SUPPORT && _CORE_HAS_RTT_ASM_SUPPORT) + #define RTT_USE_ASM (1) + #else + #define RTT_USE_ASM (0) + #endif +#endif + +#ifndef SEGGER_RTT_ASM // defined when SEGGER_RTT.h is included from assembly file +#include +#include + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_ASM_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex); +unsigned SEGGER_RTT_GetBytesInBuffer (unsigned BufferIndex); +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +#if RTT_USE_ASM + #define SEGGER_RTT_WriteSkipNoLock SEGGER_RTT_ASM_WriteSkipNoLock +#endif + +/********************************************************************* +* +* RTT transfer functions to send RTT data via other channels. +* +********************************************************************** +*/ +unsigned SEGGER_RTT_ReadUpBuffer (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadUpBufferNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +unsigned SEGGER_RTT_WriteDownBuffer (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteDownBufferNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); + +#define SEGGER_RTT_HASDATA_UP(n) (_SEGGER_RTT.aUp[n].WrOff - _SEGGER_RTT.aUp[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (unsigned char TerminalId); +int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +#ifdef __cplusplus + } +#endif + +#endif // ifndef(SEGGER_RTT_ASM) + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors +#define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m" +#define RTT_CTRL_TEXT_RED "\x1B[2;31m" +#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m" +#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m" +#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m" +#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m" +#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m" +#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m" +#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m" + +#define RTT_CTRL_BG_BLACK "\x1B[24;40m" +#define RTT_CTRL_BG_RED "\x1B[24;41m" +#define RTT_CTRL_BG_GREEN "\x1B[24;42m" +#define RTT_CTRL_BG_YELLOW "\x1B[24;43m" +#define RTT_CTRL_BG_BLUE "\x1B[24;44m" +#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m" +#define RTT_CTRL_BG_CYAN "\x1B[24;46m" +#define RTT_CTRL_BG_WHITE "\x1B[24;47m" + +#define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m" +#define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m" +#define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m" +#define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m" +#define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m" +#define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m" +#define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m" + + +#endif + +/*************************** End of file ****************************/ diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S new file mode 100644 index 0000000..78cde4d --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S @@ -0,0 +1,235 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +-------------------------- END-OF-HEADER ----------------------------- + +File : SEGGER_RTT_ASM_ARMv7M.S +Purpose : Assembler implementation of RTT functions for ARMv7M + +Additional information: + This module is written to be assembler-independent and works with + GCC and clang (Embedded Studio) and IAR. +*/ + +#define SEGGER_RTT_ASM // Used to control processed input from header file +#include "SEGGER_RTT.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +#define _CCIAR 0 +#define _CCCLANG 1 + +#if (defined __SES_ARM) || (defined __GNUC__) || (defined __clang__) + #define _CC_TYPE _CCCLANG + #define _PUB_SYM .global + #define _EXT_SYM .extern + #define _END .end + #define _WEAK .weak + #define _THUMB_FUNC .thumb_func + #define _THUMB_CODE .code 16 + #define _WORD .word + #define _SECTION(Sect, Type, AlignExp) .section Sect ##, "ax" + #define _ALIGN(Exp) .align Exp + #define _PLACE_LITS .ltorg + #define _DATA_SECT_START + #define _C_STARTUP _start + #define _STACK_END __stack_end__ + #define _RAMFUNC + // + // .text => Link to flash + // .fast => Link to RAM + // OtherSect => Usually link to RAM + // Alignment is 2^x + // +#elif defined (__IASMARM__) + #define _CC_TYPE _CCIAR + #define _PUB_SYM PUBLIC + #define _EXT_SYM EXTERN + #define _END END + #define _WEAK _WEAK + #define _THUMB_FUNC + #define _THUMB_CODE THUMB + #define _WORD DCD + #define _SECTION(Sect, Type, AlignExp) SECTION Sect ## : ## Type ## :REORDER:NOROOT ## (AlignExp) + #define _ALIGN(Exp) alignrom Exp + #define _PLACE_LITS + #define _DATA_SECT_START DATA + #define _C_STARTUP __iar_program_start + #define _STACK_END sfe(CSTACK) + #define _RAMFUNC SECTION_TYPE SHT_PROGBITS, SHF_WRITE | SHF_EXECINSTR + // + // .text => Link to flash + // .textrw => Link to RAM + // OtherSect => Usually link to RAM + // NOROOT => Allows linker to throw away the function, if not referenced + // Alignment is 2^x + // +#endif + +#if (_CC_TYPE == _CCIAR) + NAME SEGGER_RTT_ASM_ARMv7M +#else + .syntax unified +#endif + +#if defined (RTT_USE_ASM) && (RTT_USE_ASM == 1) + #define SHT_PROGBITS 0x1 + +/********************************************************************* +* +* Public / external symbols +* +********************************************************************** +*/ + + _EXT_SYM __aeabi_memcpy + _EXT_SYM __aeabi_memcpy4 + _EXT_SYM _SEGGER_RTT + + _PUB_SYM SEGGER_RTT_ASM_WriteSkipNoLock + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* MUST be > 0!!! +* This is done for performance reasons, so no initial check has do be done. +* +* Return value +* 1: Data has been copied +* 0: No space, data has not been copied +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + _SECTION(.text, CODE, 2) + _ALIGN(2) + _THUMB_FUNC +SEGGER_RTT_ASM_WriteSkipNoLock: // unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pData, unsigned NumBytes) { + // + // Cases: + // 1) RdOff <= WrOff => Space until wrap-around is sufficient + // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) + // 3) RdOff < WrOff => No space in buf + // 4) RdOff > WrOff => Space is sufficient + // 5) RdOff > WrOff => No space in buf + // + // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough + // + // Register usage: + // R0 Temporary needed as RdOff, register later on + // R1 pData + // R2 + // R3 register. Hold free for subroutine calls + // R4 + // R5 pRing->pBuffer + // R6 pRing (Points to active struct SEGGER_RTT_BUFFER_DOWN) + // R7 WrOff + // + PUSH {R4-R7} + ADD R3,R0,R0, LSL #+1 + LDR.W R0,=_SEGGER_RTT // pRing = &_SEGGER_RTT.aUp[BufferIndex]; + ADD R0,R0,R3, LSL #+3 + ADD R6,R0,#+24 + LDR R0,[R6, #+16] // RdOff = pRing->RdOff; + LDR R7,[R6, #+12] // WrOff = pRing->WrOff; + LDR R5,[R6, #+4] // pRing->pBuffer + CMP R7,R0 + BCC.N _CheckCase4 // if (RdOff <= WrOff) { => Case 1), 2) or 3) + // + // Handling for case 1, later on identical to case 4 + // + LDR R3,[R6, #+8] // Avail = pRing->SizeOfBuffer - WrOff - 1u; => Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) + SUBS R4,R3,R7 // (Used in case we jump into case 2 afterwards) + SUBS R3,R4,#+1 // + CMP R3,R2 + BCC.N _CheckCase2 // if (Avail >= NumBytes) { => Case 1)? +_Case4: + ADDS R5,R7,R5 // pBuffer += WrOff + ADDS R0,R2,R7 // v = WrOff + NumBytes + // + // 2x unrolling for the copy loop that is used most of the time + // This is a special optimization for small SystemView packets and makes them even faster + // + _ALIGN(2) +_LoopCopyStraight: // memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + LDRB R3,[R1], #+1 + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BEQ _CSDone + LDRB R3,[R1], #+1 + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BNE _LoopCopyStraight +_CSDone: + STR R0,[R6, #+12] // pRing->WrOff = WrOff + NumBytes; + MOVS R0,#+1 + POP {R4-R7} + BX LR // Return 1 +_CheckCase2: + ADDS R0,R0,R3 // Avail += RdOff; => Space incl. wrap-around + CMP R0,R2 + BCC.N _Case3 // if (Avail >= NumBytes) { => Case 2? => If not, we have case 3) (does not fit) + // + // Handling for case 2 + // + ADDS R0,R7,R5 // v = pRing->pBuffer + WrOff => Do not change pRing->pBuffer here because 2nd chunk needs org. value + SUBS R2,R2,R4 // NumBytes -= Rem; (Rem = pRing->SizeOfBuffer - WrOff; => Space until end of buffer) +_LoopCopyBeforeWrapAround: // memcpy(pRing->pBuffer + WrOff, pData, Rem); => Copy 1st chunk + LDRB R3,[R1], #+1 + STRB R3,[R0], #+1 // *pDest++ = *pSrc++ + SUBS R4,R4,#+1 + BNE _LoopCopyBeforeWrapAround + // + // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used + // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element + // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks + // Therefore, check if 2nd memcpy is necessary at all + // + ADDS R4,R2,#+0 // Save (needed as counter in loop but must be written to after the loop). Also use this inst to update the flags to skip 2nd loop if possible + BEQ.N _No2ChunkNeeded // if (NumBytes) { +_LoopCopyAfterWrapAround: // memcpy(pRing->pBuffer, pData + Rem, NumBytes); + LDRB R3,[R1], #+1 // pData already points to the next src byte due to copy loop increment before this loop + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BNE _LoopCopyAfterWrapAround +_No2ChunkNeeded: + STR R4,[R6, #+12] // pRing->WrOff = NumBytes; => Must be written after copying data because J-Link may read control block asynchronously while writing into buffer + MOVS R0,#+1 + POP {R4-R7} + BX LR // Return 1 +_CheckCase4: + SUBS R0,R0,R7 + SUBS R0,R0,#+1 // Avail = RdOff - WrOff - 1u; + CMP R0,R2 + BCS.N _Case4 // if (Avail >= NumBytes) { => Case 4) == 1) ? => If not, we have case 5) == 3) (does not fit) +_Case3: + MOVS R0,#+0 + POP {R4-R7} + BX LR // Return 0 + _PLACE_LITS + +#endif // defined (RTT_USE_ASM) && (RTT_USE_ASM == 1) + _END + +/*************************** End of file ****************************/ diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_Conf.h b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_Conf.h new file mode 100644 index 0000000..5e79d7e --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_Conf.h @@ -0,0 +1,384 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 18601 $ + +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3) +#endif + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) +#endif + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) +#endif + +/********************************************************************* +* +* RTT memcpy configuration +* +* memcpy() is good for large amounts of data, +* but the overhead is big for small amounts, which are usually stored via RTT. +* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead. +* +* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions. +* This is may be required with memory access restrictions, +* such as on Cortex-A devices with MMU. +*/ +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop +#endif +// +// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets +// +//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__)) +// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes)) +//#endif + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC +// or define SEGGER_RTT_LOCK() to completely disable interrupts. +// +#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) +#endif + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if ((defined(__SES_ARM) || defined(__SES_RISCV) || defined(__CROSSWORKS_ARM) || defined(__GNUC__) || defined(__clang__)) && !defined (__CC_ARM) && !defined(WIN32)) + #if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "movs r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + } + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (LockState) \ + : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (LockState) \ + : "r0", "r1" \ + ); \ + } + #elif defined(__riscv) || defined(__riscv_xlen) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("csrr %0, mstatus \n\t" \ + "csrci mstatus, 8 \n\t" \ + "andi %0, %0, 8 \n\t" \ + : "=r" (LockState) \ + : \ + : \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("csrr a1, mstatus \n\t" \ + "or %0, %0, a1 \n\t" \ + "csrs mstatus, %0 \n\t" \ + : \ + : "r" (LockState) \ + : "a1" \ + ); \ + } + #else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) || \ + (defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || \ + (defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || \ + (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \ + (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RX +*/ +#ifdef __ICCRX__ + #define SEGGER_RTT_LOCK() { \ + unsigned long LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RL78 +*/ +#ifdef __ICCRL78__ + #define SEGGER_RTT_LOCK() { \ + __istate_t LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char PRIMASK __asm( "primask"); \ + LockState = PRIMASK; \ + PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for TI ARM +*/ +#ifdef __TI_ARM__ + #if defined (__TI_ARM_V6M0__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() _set_interrupt_priority(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for CCRX +*/ +#ifdef __RX + #define SEGGER_RTT_LOCK() { \ + unsigned long LockState; \ + LockState = get_psw() & 0x010000; \ + clrpsw_i(); + + #define SEGGER_RTT_UNLOCK() set_psw(get_psw() | LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for embOS Simulation on Windows +* (Can also be used for generic RTT locking with embOS) +*/ +#if defined(WIN32) || defined(SEGGER_RTT_LOCK_EMBOS) + +void OS_SIM_EnterCriticalSection(void); +void OS_SIM_LeaveCriticalSection(void); + +#define SEGGER_RTT_LOCK() { \ + OS_SIM_EnterCriticalSection(); + +#define SEGGER_RTT_UNLOCK() OS_SIM_LeaveCriticalSection(); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c new file mode 100644 index 0000000..4c996b4 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c @@ -0,0 +1,500 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_printf.c +Purpose : Replacement for printf to write formatted data via RTT +Revision: $Rev: 17697 $ +---------------------------------------------------------------------- +*/ +#include "SEGGER_RTT.h" +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) +#endif + +#include +#include + + +#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define FORMAT_FLAG_PAD_ZERO (1u << 1) +#define FORMAT_FLAG_PRINT_SIGN (1u << 2) +#define FORMAT_FLAG_ALTERNATE (1u << 3) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + unsigned BufferSize; + unsigned Cnt; + + int ReturnValue; + + unsigned RTTBufferIndex; +} SEGGER_RTT_PRINTF_DESC; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _StoreChar +*/ +static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { + unsigned Cnt; + + Cnt = p->Cnt; + if ((Cnt + 1u) <= p->BufferSize) { + *(p->pBuffer + Cnt) = c; + p->Cnt = Cnt + 1u; + p->ReturnValue++; + } + // + // Write part of string, when the buffer is full + // + if (p->Cnt == p->BufferSize) { + if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { + p->ReturnValue = -1; + } else { + p->Cnt = 0u; + } + } +} + +/********************************************************************* +* +* _PrintUnsigned +*/ +static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned Div; + unsigned Digit; + unsigned Number; + unsigned Width; + char c; + + Number = v; + Digit = 1u; + // + // Get actual field width + // + Width = 1u; + while (Number >= Base) { + Number = (Number / Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { + if (FieldWidth != 0u) { + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { + c = '0'; + } else { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, c); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Compute Digit. + // Loop until Digit has the value of the highest digit required. + // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + // + while (1) { + if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) + NumDigits--; + } else { + Div = v / Digit; + if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done + break; + } + } + Digit *= Base; + } + // + // Output digits + // + do { + Div = v / Digit; + v -= Div * Digit; + _StoreChar(pBufferDesc, _aV2C[Div]); + if (pBufferDesc->ReturnValue < 0) { + break; + } + Digit /= Base; + } while (Digit); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + } +} + +/********************************************************************* +* +* _PrintInt +*/ +static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + unsigned Width; + int Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int)Base) { + Number = (Number / (int)Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { + FieldWidth--; + } + + // + // Print leading spaces if necessary + // + if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + // + // Print sign if necessary + // + if (pBufferDesc->ReturnValue >= 0) { + if (v < 0) { + v = -v; + _StoreChar(pBufferDesc, '-'); + } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { + _StoreChar(pBufferDesc, '+'); + } else { + + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print leading zeros if necessary + // + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, '0'); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print number without sign + // + _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); + } + } + } +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_vprintf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string +* pParamList Pointer to the list of arguments for the format string +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { + char c; + SEGGER_RTT_PRINTF_DESC BufferDesc; + int v; + unsigned NumDigits; + unsigned FormatFlags; + unsigned FieldWidth; + char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; + + BufferDesc.pBuffer = acBuffer; + BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; + BufferDesc.Cnt = 0u; + BufferDesc.RTTBufferIndex = BufferIndex; + BufferDesc.ReturnValue = 0; + + do { + c = *sFormat; + sFormat++; + if (c == 0u) { + break; + } + if (c == '%') { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + do { + c = *sFormat; + switch (c) { + case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; + case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; + case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; + case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; + default: v = 0; break; + } + } while (v); + // + // filter out field with + // + FieldWidth = 0u; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *sFormat; + if (c == '.') { + sFormat++; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + NumDigits = NumDigits * 10u + ((unsigned)c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *sFormat; + do { + if ((c == 'l') || (c == 'h')) { + sFormat++; + c = *sFormat; + } else { + break; + } + } while (1); + // + // Handle specifiers + // + switch (c) { + case 'c': { + char c0; + v = va_arg(*pParamList, int); + c0 = (char)v; + _StoreChar(&BufferDesc, c0); + break; + } + case 'd': + v = va_arg(*pParamList, int); + _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'u': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); + break; + case 's': + { + const char * s = va_arg(*pParamList, const char *); + do { + c = *s; + s++; + if (c == '\0') { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } + break; + case 'p': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); + break; + case '%': + _StoreChar(&BufferDesc, '%'); + break; + default: + break; + } + sFormat++; + } else { + _StoreChar(&BufferDesc, c); + } + } while (BufferDesc.ReturnValue >= 0); + + if (BufferDesc.ReturnValue > 0) { + // + // Write remaining data, if any + // + if (BufferDesc.Cnt != 0u) { + SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); + } + BufferDesc.ReturnValue += (int)BufferDesc.Cnt; + } + return BufferDesc.ReturnValue; +} + +/********************************************************************* +* +* SEGGER_RTT_printf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string, followed by the arguments for conversion +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +* +* Notes +* (1) Conversion specifications have following syntax: +* %[flags][FieldWidth][.Precision]ConversionSpecifier +* (2) Supported flags: +* -: Left justify within the field width +* +: Always print sign extension for signed conversions +* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision +* Supported conversion specifiers: +* c: Print the argument as one char +* d: Print the argument as a signed integer +* u: Print the argument as an unsigned integer +* x: Print the argument as an hexadecimal integer +* s: Print the string pointed to by the argument +* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { + int r; + va_list ParamList; + + va_start(ParamList, sFormat); + r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); + va_end(ParamList); + return r; +} +/*************************** End of file ****************************/ diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_GCC.c b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_GCC.c new file mode 100644 index 0000000..da4a4b5 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_GCC.c @@ -0,0 +1,120 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Syscalls_GCC.c +Purpose : Low-level functions for using printf() via RTT in GCC. + To use RTT for printf output, include this file in your + application. +Revision: $Rev: 17697 $ +---------------------------------------------------------------------- +*/ +#if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM) + +#include // required for _write_r +#include "SEGGER_RTT.h" + + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// If necessary define the _reent struct +// to match the one passed by the used standard library. +// +struct _reent; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +int _write(int file, char *ptr, int len); +int _write_r(struct _reent *r, int file, const void *ptr, int len); + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _write() +* +* Function description +* Low-level write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +int _write(int file, char *ptr, int len) { + (void) file; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +/********************************************************************* +* +* _write_r() +* +* Function description +* Low-level reentrant write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +int _write_r(struct _reent *r, int file, const void *ptr, int len) { + (void) file; /* Not used, avoid warning */ + (void) r; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +#endif +/****** End Of File *************************************************/ diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c new file mode 100644 index 0000000..4c76752 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c @@ -0,0 +1,115 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Syscalls_IAR.c +Purpose : Low-level functions for using printf() via RTT in IAR. + To use RTT for printf output, include this file in your + application and set the Library Configuration to Normal. +Revision: $Rev: 17697 $ +---------------------------------------------------------------------- +*/ +#ifdef __IAR_SYSTEMS_ICC__ + +// +// Since IAR EWARM V8 and EWRX V4, yfuns.h is considered as deprecated and LowLevelIOInterface.h +// shall be used instead. To not break any compatibility with older compiler versions, we have a +// version check in here. +// +#if ((defined __ICCARM__) && (__VER__ >= 8000000)) || ((defined __ICCRX__) && (__VER__ >= 400)) + #include +#else + #include +#endif + +#include "SEGGER_RTT.h" +#pragma module_name = "?__write" + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +size_t __write(int handle, const unsigned char * buffer, size_t size); + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ +/********************************************************************* +* +* __write() +* +* Function description +* Low-level write function. +* Standard library subroutines will use this system routine +* for output to all files, including stdout. +* Write data via RTT. +*/ +size_t __write(int handle, const unsigned char * buffer, size_t size) { + (void) handle; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, (const char*)buffer, size); + return size; +} + +/********************************************************************* +* +* __write_buffered() +* +* Function description +* Low-level write function. +* Standard library subroutines will use this system routine +* for output to all files, including stdout. +* Write data via RTT. +*/ +size_t __write_buffered(int handle, const unsigned char * buffer, size_t size) { + (void) handle; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, (const char*)buffer, size); + return size; +} + +#endif +/****** End Of File *************************************************/ diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_KEIL.c b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_KEIL.c new file mode 100644 index 0000000..f7f5aed --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_KEIL.c @@ -0,0 +1,386 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : RTT_Syscalls_KEIL.c +Purpose : Retargeting module for KEIL MDK-CM3. + Low-level functions for using printf() via RTT +Revision: $Rev: 17697 $ +---------------------------------------------------------------------- +*/ +#ifdef __CC_ARM + +#include +#include +#include +#include +#include + +#include "SEGGER_RTT.h" +/********************************************************************* +* +* #pragmas +* +********************************************************************** +*/ +#pragma import(__use_no_semihosting) + +#ifdef _MICROLIB + #pragma import(__use_full_stdio) +#endif + +/********************************************************************* +* +* Defines non-configurable +* +********************************************************************** +*/ + +/* Standard IO device handles - arbitrary, but any real file system handles must be + less than 0x8000. */ +#define STDIN 0x8001 // Standard Input Stream +#define STDOUT 0x8002 // Standard Output Stream +#define STDERR 0x8003 // Standard Error Stream + +/********************************************************************* +* +* Public const +* +********************************************************************** +*/ +#if __ARMCC_VERSION < 5000000 +//const char __stdin_name[] = "STDIN"; +const char __stdout_name[] = "STDOUT"; +const char __stderr_name[] = "STDERR"; +#endif + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ + +/********************************************************************* +* +* _ttywrch +* +* Function description: +* Outputs a character to the console +* +* Parameters: +* c - character to output +* +*/ +void _ttywrch(int c) { + fputc(c, stdout); // stdout + fflush(stdout); +} + +/********************************************************************* +* +* _sys_open +* +* Function description: +* Opens the device/file in order to do read/write operations +* +* Parameters: +* sName - sName of the device/file to open +* OpenMode - This parameter is currently ignored +* +* Return value: +* != 0 - Handle to the object to open, otherwise +* == 0 -"device" is not handled by this module +* +*/ +FILEHANDLE _sys_open(const char * sName, int OpenMode) { + (void)OpenMode; + // Register standard Input Output devices. + if (strcmp(sName, __stdout_name) == 0) { + return (STDOUT); + } else if (strcmp(sName, __stderr_name) == 0) { + return (STDERR); + } else + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_close +* +* Function description: +* Closes the handle to the open device/file +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* +* Return value: +* 0 - device/file closed +* +*/ +int _sys_close(FILEHANDLE hFile) { + (void)hFile; + return 0; // Not implemented +} + +/********************************************************************* +* +* _sys_write +* +* Function description: +* Writes the data to an open handle. +* Currently this function only outputs data to the console +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* pBuffer - Pointer to the data that shall be written +* NumBytes - Number of bytes to write +* Mode - The Mode that shall be used +* +* Return value: +* Number of bytes *not* written to the file/device +* +*/ +int _sys_write(FILEHANDLE hFile, const unsigned char * pBuffer, unsigned NumBytes, int Mode) { + int r = 0; + + (void)Mode; + if (hFile == STDOUT) { + SEGGER_RTT_Write(0, (const char*)pBuffer, NumBytes); + return 0; + } + return r; +} + +/********************************************************************* +* +* _sys_read +* +* Function description: +* Reads data from an open handle. +* Currently this modules does nothing. +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* pBuffer - Pointer to buffer to store the read data +* NumBytes - Number of bytes to read +* Mode - The Mode that shall be used +* +* Return value: +* Number of bytes read from the file/device +* +*/ +int _sys_read(FILEHANDLE hFile, unsigned char * pBuffer, unsigned NumBytes, int Mode) { + (void)hFile; + (void)pBuffer; + (void)NumBytes; + (void)Mode; + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_istty +* +* Function description: +* This function shall return whether the opened file +* is a console device or not. +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* +* Return value: +* 1 - Device is a console +* 0 - Device is not a console +* +*/ +int _sys_istty(FILEHANDLE hFile) { + if (hFile > 0x8000) { + return (1); + } + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_seek +* +* Function description: +* Seeks via the file to a specific position +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* Pos - +* +* Return value: +* int - +* +*/ +int _sys_seek(FILEHANDLE hFile, long Pos) { + (void)hFile; + (void)Pos; + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_ensure +* +* Function description: +* +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* +* Return value: +* int - +* +*/ +int _sys_ensure(FILEHANDLE hFile) { + (void)hFile; + return (-1); // Not implemented +} + +/********************************************************************* +* +* _sys_flen +* +* Function description: +* Returns the length of the opened file handle +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* +* Return value: +* Length of the file +* +*/ +long _sys_flen(FILEHANDLE hFile) { + (void)hFile; + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_tmpnam +* +* Function description: +* This function converts the file number fileno for a temporary +* file to a unique filename, for example, tmp0001. +* +* Parameters: +* pBuffer - Pointer to a buffer to store the name +* FileNum - file number to convert +* MaxLen - Size of the buffer +* +* Return value: +* 1 - Error +* 0 - Success +* +*/ +int _sys_tmpnam(char * pBuffer, int FileNum, unsigned MaxLen) { + (void)pBuffer; + (void)FileNum; + (void)MaxLen; + return (1); // Not implemented +} + +/********************************************************************* +* +* _sys_command_string +* +* Function description: +* This function shall execute a system command. +* +* Parameters: +* cmd - Pointer to the command string +* len - Length of the string +* +* Return value: +* == NULL - Command was not successfully executed +* == sCmd - Command was passed successfully +* +*/ +char * _sys_command_string(char * cmd, int len) { + (void)len; + return cmd; // Not implemented +} + +/********************************************************************* +* +* _sys_exit +* +* Function description: +* This function is called when the application returns from main +* +* Parameters: +* ReturnCode - Return code from the main function +* +* +*/ +void _sys_exit(int ReturnCode) { + (void)ReturnCode; + while (1); // Not implemented +} + +#if __ARMCC_VERSION >= 5000000 +/********************************************************************* +* +* stdout_putchar +* +* Function description: +* Put a character to the stdout +* +* Parameters: +* ch - Character to output +* +* +*/ +int stdout_putchar(int ch) { + (void)ch; + return ch; // Not implemented +} +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_SES.c b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_SES.c new file mode 100644 index 0000000..5ce8457 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_SES.c @@ -0,0 +1,247 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Syscalls_SES.c +Purpose : Reimplementation of printf, puts and __getchar using RTT + in SEGGER Embedded Studio. + To use RTT for printf output, include this file in your + application. +Revision: $Rev: 18539 $ +---------------------------------------------------------------------- +*/ +#if (defined __SES_ARM) || (defined __SES_RISCV) || (defined __CROSSWORKS_ARM) + +#include "SEGGER_RTT.h" +#include +#include +#include "limits.h" +#include "__libc.h" +#include "__vfprintf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ +// +// Select string formatting implementation. +// +// RTT printf formatting +// - Configurable stack usage. (SEGGER_RTT_PRINTF_BUFFER_SIZE in SEGGER_RTT_Conf.h) +// - No maximum string length. +// - Limited conversion specifiers and flags. (See SEGGER_RTT_printf.c) +// Standard library printf formatting +// - Configurable formatting capabilities. +// - Full conversion specifier and flag support. +// - Maximum string length has to be known or (slightly) slower character-wise output. +// +// #define PRINTF_USE_SEGGER_RTT_FORMATTING 0 // Use standard library formatting +// #define PRINTF_USE_SEGGER_RTT_FORMATTING 1 // Use RTT formatting +// +#ifndef PRINTF_USE_SEGGER_RTT_FORMATTING + #define PRINTF_USE_SEGGER_RTT_FORMATTING 0 +#endif +// +// If using standard library formatting, +// select maximum output string buffer size or character-wise output. +// +// #define PRINTF_BUFFER_SIZE 0 // Use character-wise output +// #define PRINTF_BUFFER_SIZE 128 // Default maximum string length +// +#ifndef PRINTF_BUFFER_SIZE + #define PRINTF_BUFFER_SIZE 128 +#endif + +#if PRINTF_USE_SEGGER_RTT_FORMATTING // Use SEGGER RTT formatting implementation +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +/********************************************************************* +* +* Global functions, printf +* +********************************************************************** +*/ +/********************************************************************* +* +* printf() +* +* Function description +* print a formatted string using RTT and SEGGER RTT formatting. +*/ +int printf(const char *fmt,...) { + int n; + va_list args; + + va_start (args, fmt); + n = SEGGER_RTT_vprintf(0, fmt, &args); + va_end(args); + return n; +} + +#elif PRINTF_BUFFER_SIZE == 0 // Use standard library formatting with character-wise output + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ +static int _putchar(int x, __printf_tag_ptr ctx) { + (void)ctx; + SEGGER_RTT_Write(0, (char *)&x, 1); + return x; +} + +/********************************************************************* +* +* Global functions, printf +* +********************************************************************** +*/ +/********************************************************************* +* +* printf() +* +* Function description +* print a formatted string character-wise, using RTT and standard +* library formatting. +*/ +int printf(const char *fmt, ...) { + int n; + va_list args; + __printf_t iod; + + va_start(args, fmt); + iod.string = 0; + iod.maxchars = INT_MAX; + iod.output_fn = _putchar; + SEGGER_RTT_LOCK(); + n = __vfprintf(&iod, fmt, args); + SEGGER_RTT_UNLOCK(); + va_end(args); + return n; +} + +#else // Use standard library formatting with static buffer + +/********************************************************************* +* +* Global functions, printf +* +********************************************************************** +*/ +/********************************************************************* +* +* printf() +* +* Function description +* print a formatted string using RTT and standard library formatting. +*/ +int printf(const char *fmt,...) { + int n; + char aBuffer[PRINTF_BUFFER_SIZE]; + va_list args; + + va_start (args, fmt); + n = vsnprintf(aBuffer, sizeof(aBuffer), fmt, args); + if (n > (int)sizeof(aBuffer)) { + SEGGER_RTT_Write(0, aBuffer, sizeof(aBuffer)); + } else if (n > 0) { + SEGGER_RTT_Write(0, aBuffer, n); + } + va_end(args); + return n; +} +#endif + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ +/********************************************************************* +* +* puts() +* +* Function description +* print a string using RTT. +*/ +int puts(const char *s) { + return SEGGER_RTT_WriteString(0, s); +} + +/********************************************************************* +* +* __putchar() +* +* Function description +* Write one character via RTT. +*/ +int __putchar(int x, __printf_tag_ptr ctx) { + (void)ctx; + SEGGER_RTT_Write(0, (char *)&x, 1); + return x; +} + +/********************************************************************* +* +* __getchar() +* +* Function description +* Wait for and get a character via RTT. +*/ +int __getchar() { + return SEGGER_RTT_WaitKey(); +} + +#endif +/****** End Of File *************************************************/ diff --git a/circuitpython/lib/tinyusb/lib/fatfs/00readme.txt b/circuitpython/lib/tinyusb/lib/fatfs/00readme.txt new file mode 100644 index 0000000..f7330e9 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/fatfs/00readme.txt @@ -0,0 +1,138 @@ +FatFs Module Source Files R0.09b (C)ChaN, 2013 + + +FILES + + ffconf.h Configuration file for FatFs module. + ff.h Common include file for FatFs and application module. + ff.c FatFs module. + diskio.h Common include file for FatFs and disk I/O module. + diskio.c An example of glue function to attach existing disk I/O module to FatFs. + integer.h Integer type definitions for FatFs. + option Optional external functions. + + Low level disk I/O module is not included in this archive because the FatFs + module is only a generic file system layer and not depend on any specific + storage device. You have to provide a low level disk I/O module that written + to control your storage device. + + + +AGREEMENTS + + FatFs module is an open source software to implement FAT file system to + small embedded systems. This is a free software and is opened for education, + research and commercial developments under license policy of following trems. + + Copyright (C) 2012, ChaN, all right reserved. + + * The FatFs module is a free software and there is NO WARRANTY. + * No restriction on use. You can use, modify and redistribute it for + personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. + * Redistributions of source code must retain the above copyright notice. + + + +REVISION HISTORY + + Feb 26, 2006 R0.00 Prototype + + Apr 29, 2006 R0.01 First release. + + Jun 01, 2006 R0.02 Added FAT12. + Removed unbuffered mode. + Fixed a problem on small (<32M) patition. + + Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM. + + Sep 22, 2006 R0.03 Added f_rename. + Changed option _FS_MINIMUM to _FS_MINIMIZE. + + Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast. + Fixed f_mkdir creates incorrect directory on FAT32. + + Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs) + Changed some APIs for multiple drive system. + Added f_mkfs. (FatFs) + Added _USE_FAT32 option. (Tiny-FatFs) + + Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs) + Fixed an endian sensitive code in f_mkfs. (FatFs) + Added a capability of extending the file size to f_lseek. + Added minimization level 3. + Fixed a problem that can collapse a sector when recreate an + existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs) + + May 05, 2007 R0.04b Added _USE_NTFLAG option. + Added FSInfo support. + Fixed some problems corresponds to FAT32. (Tiny-FatFs) + Fixed DBCS name can result FR_INVALID_NAME. + Fixed short seek (0 < ofs <= csize) collapses the file object. + + Aug 25, 2007 R0.05 Changed arguments of f_read, f_write. + Changed arguments of f_mkfs. (FatFs) + Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) + Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) + + Feb 03, 2008 R0.05a Added f_truncate(). + Added f_utime(). + Fixed off by one error at FAT sub-type determination. + Fixed btr in f_read() can be mistruncated. + Fixed cached sector is not flushed when create and close without write. + + Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs) + Added string functions: fputc(), fputs(), fprintf() and fgets(). + Improved performance of f_lseek() on move to the same or following cluster. + + Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option. + Added long file name support. + Added multiple code page support. + Added re-entrancy for multitask operation. + Added auto cluster size selection to f_mkfs(). + Added rewind option to f_readdir(). + Changed result code of critical errors. + Renamed string functions to avoid name collision. + + Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg. + Added multiple sector size support. + + Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error. + Fixed wrong cache control in f_lseek(). + Added relative path feature. + Added f_chdir(). + Added f_chdrive(). + Added proper case conversion for extended characters. + + Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h. + Added a configuration option, _LFN_UNICODE. + Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. + Fixed name matching error on the 13 char boundary. + Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. + + May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN) + Added file lock feature. (_FS_SHARE) + Added fast seek feature. (_USE_FASTSEEK) + Changed some types on the API, XCHAR->TCHAR. + Changed fname member in the FILINFO structure on Unicode cfg. + String functions support UTF-8 encoding files on Unicode cfg. + + Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2) + Added sector erase feature. (_USE_ERASE) + Moved file lock semaphore table from fs object to the bss. + Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'. + Fixed f_mkfs() creates wrong FAT32 volume. + + Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). + f_lseek() reports required table size on creating CLMP. + Extended format syntax of f_printf function. + Ignores duplicated directory separators in given path names. + + Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature. + Added f_fdisk(). (_MULTI_PARTITION = 2) + + Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16. + Changed f_open() and f_opendir() reject null object pointer to avoid crash. + Changed option name _FS_SHARE to _FS_LOCK. + + Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL == 1) + diff --git a/circuitpython/lib/tinyusb/lib/fatfs/ccsbcs.c b/circuitpython/lib/tinyusb/lib/fatfs/ccsbcs.c new file mode 100644 index 0000000..07d6f09 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/fatfs/ccsbcs.c @@ -0,0 +1,543 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - Local code bidirectional converter (C)ChaN, 2012 */ +/* (SBCS code pages) */ +/*------------------------------------------------------------------------*/ +/* 437 U.S. (OEM) +/ 720 Arabic (OEM) +/ 1256 Arabic (Windows) +/ 737 Greek (OEM) +/ 1253 Greek (Windows) +/ 1250 Central Europe (Windows) +/ 775 Baltic (OEM) +/ 1257 Baltic (Windows) +/ 850 Multilingual Latin 1 (OEM) +/ 852 Latin 2 (OEM) +/ 1252 Latin 1 (Windows) +/ 855 Cyrillic (OEM) +/ 1251 Cyrillic (Windows) +/ 866 Russian (OEM) +/ 857 Turkish (OEM) +/ 1254 Turkish (Windows) +/ 858 Multilingual Latin 1 + Euro (OEM) +/ 862 Hebrew (OEM) +/ 1255 Hebrew (Windows) +/ 874 Thai (OEM, Windows) +/ 1258 Vietnam (OEM, Windows) +*/ + +#include "ff.h" + +#if CFG_TUH_MSC + +#if _CODE_PAGE == 437 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 720 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */ + 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, + 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, + 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, + 0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 737 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, + 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, + 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, + 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, + 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, + 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, + 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 775 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */ + 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, + 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, + 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, + 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, + 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D, + 0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, + 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, + 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019, + 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, + 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 850 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, + 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 852 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, + 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, + 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, + 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, + 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, + 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, + 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 855 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */ + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, + 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, + 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580, + 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116, + 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, + 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 857 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, + 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 858 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, + 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 862 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */ + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 866 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 874 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, + 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, + 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, + 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, + 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, + 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, + 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, + 0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, + 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, + 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, + 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, + 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +#elif _CODE_PAGE == 1250 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, + 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B, + 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 +}; + +#elif _CODE_PAGE == 1251 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */ + 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, + 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, + 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, + 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, + 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, + 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, + 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F +}; + +#elif _CODE_PAGE == 1252 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF +}; + +#elif _CODE_PAGE == 1253 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7, + 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000 +}; + +#elif _CODE_PAGE == 1254 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF +}; + +#elif _CODE_PAGE == 1255 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, + 0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, + 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, + 0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000 +}; + +#elif _CODE_PAGE == 1256 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, + 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F, + 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, + 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643, + 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF, + 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, + 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2 +} + +#elif _CODE_PAGE == 1257 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, + 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7, + 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, + 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, + 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, + 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, + 0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9 +}; + +#elif _CODE_PAGE == 1258 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF +}; + +#endif + + +#if !_TBLDEF || !_USE_LFN +#error This file is not needed in current configuration. Remove from the project. +#endif + + +WCHAR ff_convert ( /* Converted character, Returns zero on error */ + WCHAR chr, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ +) +{ + WCHAR c; + + + if (chr < 0x80) { /* ASCII */ + c = chr; + + } else { + if (dir) { /* OEMCP to Unicode */ + c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80]; + + } else { /* Unicode to OEMCP */ + for (c = 0; c < 0x80; c++) { + if (chr == Tbl[c]) break; + } + c = (c + 0x80) & 0xFF; + } + } + + return c; +} + + +WCHAR ff_wtoupper ( /* Upper converted character */ + WCHAR chr /* Input character */ +) +{ + static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; + static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; + int i; + + + for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; + + return tbl_lower[i] ? tbl_upper[i] : chr; +} + +#endif // CFG_TUH_MSC diff --git a/circuitpython/lib/tinyusb/lib/fatfs/diskio.c b/circuitpython/lib/tinyusb/lib/fatfs/diskio.c new file mode 100644 index 0000000..a6132f2 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/fatfs/diskio.c @@ -0,0 +1,193 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb.h" + +#if CFG_TUH_MSC +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "ffconf.h" +#include "diskio.h" +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +// TODO change it to portable init +static DSTATUS disk_state[CFG_TUH_DEVICE_MAX]; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// IMPLEMENTATION +//--------------------------------------------------------------------+ +static DRESULT wait_for_io_complete(uint8_t usb_addr) +{ + // TODO with RTOS, this should use semaphore instead of blocking + while ( !tuh_msc_ready(usb_addr) ) + { + // TODO should have timeout here + #if CFG_TUSB_OS != OPT_OS_NONE + osal_task_delay(10); + #endif + } + + return RES_OK; +} + +void diskio_init(void) +{ + memset(disk_state, STA_NOINIT, CFG_TUH_DEVICE_MAX); +} + +//pdrv Specifies the physical drive number. +DSTATUS disk_initialize ( BYTE pdrv ) +{ + disk_state[pdrv] &= (~STA_NOINIT); // clear NOINIT bit + return disk_state[pdrv]; +} + +void disk_deinitialize ( BYTE pdrv ) +{ + disk_state[pdrv] |= STA_NOINIT; // set NOINIT bit +} + +DSTATUS disk_status (BYTE pdrv) +{ + return disk_state[pdrv]; +} + +//pdrv +// Specifies the physical drive number --> == dev_addr-1 +//buff +// Pointer to the byte array to store the read data. The size of buffer must be in sector size * sector count. +//sector +// Specifies the start sector number in logical block address (LBA). +//count +// Specifies number of sectors to read. The value can be 1 to 128. Generally, a multiple sector transfer request +// must not be split into single sector transactions to the device, or you may not get good read performance. +DRESULT disk_read (BYTE pdrv, BYTE*buff, DWORD sector, BYTE count) +{ + uint8_t usb_addr = pdrv+1; + + if ( TUSB_ERROR_NONE != tuh_msc_read10(usb_addr, 0, buff, sector, count) ) return RES_ERROR; + + return wait_for_io_complete(usb_addr); +} + + +DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, BYTE count) +{ + uint8_t usb_addr = pdrv+1; + + if ( TUSB_ERROR_NONE != tuh_msc_write10(usb_addr, 0, buff, sector, count) ) return RES_ERROR; + + return wait_for_io_complete(usb_addr); +} + +/* [IN] Drive number */ +/* [IN] Control command code */ +/* [I/O] Parameter and data buffer */ +DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff) +{ + (void) buff; (void) pdrv; // compiler warnings + + if (cmd != CTRL_SYNC) return RES_ERROR; + return RES_OK; +} + +static inline uint8_t month2number(char* p_ch) +{ + char const * const month_str[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + + for(uint8_t i=0; i<12; i++) + { + if ( strncmp(p_ch, month_str[i], 3) == 0 ) return i+1; + } + + return 1; +} + +static inline uint8_t c2i(char ch) +{ + return ch - '0'; +} + +DWORD get_fattime (void) +{ + union { + struct { + DWORD second : 5; + DWORD minute : 6; + DWORD hour : 5; + DWORD day_in_month : 5; + DWORD month : 4; + DWORD year : 7; + }; + + DWORD value; + } timestamp; + + //------------- Date is compiled date-------------// + char compile_date[] = __DATE__; // eg. "Sep 26 2013" + char* p_ch; + + p_ch = strtok (compile_date, " "); + timestamp.month = month2number(p_ch); + + p_ch = strtok (NULL, " "); + timestamp.day_in_month = 10*c2i(p_ch[0])+ c2i(p_ch[1]); + + p_ch = strtok (NULL, " "); + timestamp.year = 1000*c2i(p_ch[0]) + 100*c2i(p_ch[1]) + 10*c2i(p_ch[2]) + c2i(p_ch[3]) - 1980; + + //------------- Time each time this function call --> sec ++ -------------// + static uint8_t sec = 0; + static uint8_t min = 0; + static uint8_t hour = 0; + + if (++sec >= 60) + { + sec = 0; + if (++min >= 60) + { + min = 0; + if (++hour >= 24) + { + hour = 0; // assume demo wont call this function more than 24*60*60 times + } + } + } + + timestamp.hour = hour; + timestamp.minute = min; + timestamp.second = sec; + + return timestamp.value; +} + +#endif // CFG_TUH_MSC diff --git a/circuitpython/lib/tinyusb/lib/fatfs/diskio.h b/circuitpython/lib/tinyusb/lib/fatfs/diskio.h new file mode 100644 index 0000000..f1f4bd3 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/fatfs/diskio.h @@ -0,0 +1,95 @@ +/*----------------------------------------------------------------------- +/ Low level disk interface modlue include file (C)ChaN, 2013 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO_DEFINED +#define _DISKIO_DEFINED + +#ifdef __cplusplus +extern "C" { +#endif + +#define _USE_WRITE 1 /* 1: Enable disk_write function */ +#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */ + +#include "integer.h" +#include + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/* Disk Status Bits (DSTATUS) */ +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl fucntion */ + +/* Generic command (used by FatFs) */ +#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */ +#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */ +#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */ +#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */ + +/* Generic command (not used by FatFs) */ +#define CTRL_POWER 5 /* Get/Set power status */ +#define CTRL_LOCK 6 /* Lock/Unlock media removal */ +#define CTRL_EJECT 7 /* Eject media */ +#define CTRL_FORMAT 8 /* Create physical format on the media */ + +/* MMC/SDC specific ioctl command */ +#define MMC_GET_TYPE 10 /* Get card type */ +#define MMC_GET_CSD 11 /* Get CSD */ +#define MMC_GET_CID 12 /* Get CID */ +#define MMC_GET_OCR 13 /* Get OCR */ +#define MMC_GET_SDSTAT 14 /* Get SD status */ + +/* ATA/CF specific ioctl command */ +#define ATA_GET_REV 20 /* Get F/W revision */ +#define ATA_GET_MODEL 21 /* Get model name */ +#define ATA_GET_SN 22 /* Get serial number */ + + +/* MMC card type flags (MMC_GET_TYPE) */ +#define CT_MMC 0x01 /* MMC ver 3 */ +#define CT_SD1 0x02 /* SD ver 1 */ +#define CT_SD2 0x04 /* SD ver 2 */ +#define CT_SDC (CT_SD1|CT_SD2) /* SD */ +#define CT_BLOCK 0x08 /* Block addressing */ + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + +void diskio_init(void); +void disk_deinitialize ( BYTE pdrv ); +DSTATUS disk_initialize (BYTE pdrv); +DSTATUS disk_status (BYTE pdrv); +DRESULT disk_read (BYTE pdrv, BYTE*buff, DWORD sector, BYTE count); +DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, BYTE count); +DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); + +static inline bool disk_is_ready(BYTE pdrv); +static inline bool disk_is_ready(BYTE pdrv) +{ + return (pdrv < CFG_TUH_DEVICE_MAX) && + ( (disk_status(pdrv) & (STA_NOINIT | STA_NODISK)) == 0 ); +} + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/lib/fatfs/ff.c b/circuitpython/lib/tinyusb/lib/fatfs/ff.c new file mode 100644 index 0000000..79414af --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/fatfs/ff.c @@ -0,0 +1,4330 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.09b (C)ChaN, 2013 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2013, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) partition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSInfo support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a configuration option. (_FS_TINY) +/ Added long file name feature. +/ Added multiple code page feature. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size feature. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended char. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. +/ Fixed name matching error on the 13 char boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. +/ +/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN = 3) +/ Added file lock feature. (_FS_SHARE) +/ Added fast seek feature. (_USE_FASTSEEK) +/ Changed some types on the API, XCHAR->TCHAR. +/ Changed fname member in the FILINFO structure on Unicode cfg. +/ String functions support UTF-8 encoding files on Unicode cfg. +/ Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2) +/ Added sector erase feature. (_USE_ERASE) +/ Moved file lock semaphore table from fs object to the bss. +/ Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'. +/ Fixed f_mkfs() creates wrong FAT32 volume. +/ Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). +/ f_lseek() reports required table size on creating CLMP. +/ Extended format syntax of f_printf function. +/ Ignores duplicated directory separators in given path name. +/ +/ Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature. +/ Added f_fdisk(). (_MULTI_PARTITION = 2) +/ Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16 volume. +/ Changed f_open() and f_opendir reject null object pointer to avoid crash. +/ Changed option name _FS_SHARE to _FS_LOCK. +/ Jan 24,'13 R0.09b Added f_setlabel() and f_getlabel(). (_USE_LABEL = 1) +/---------------------------------------------------------------------------*/ + +#include "ff.h" /* FatFs configurations and declarations */ +#include "diskio.h" /* Declarations of low level disk I/O functions */ + +#if CFG_TUH_MSC +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 82786 /* Revision ID */ +#error Wrong include file (ff.h). +#endif + + +/* Definitions on sector size */ +#if _MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096 +#error Wrong sector size. +#endif +#if _MAX_SS != 512 +#define SS(fs) ((fs)->ssize) /* Variable sector size */ +#else +#define SS(fs) 512U /* Fixed sector size */ +#endif + + +/* Reentrancy related */ +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area must not be used in re-entrant configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res +#endif + +#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); } + + +/* File access control feature */ +#if _FS_LOCK +#if _FS_READONLY +#error _FS_LOCK must be 0 on read-only cfg. +#endif +typedef struct { + FATFS *fs; /* File ID 1, volume (NULL:blank entry) */ + DWORD clu; /* File ID 2, directory */ + WORD idx; /* File ID 3, directory index */ + WORD ctr; /* File open counter, 0:none, 0x01..0xFF:read open count, 0x100:write mode */ +} FILESEM; +#endif + + + +/* DBCS code ranges and SBCS extend char conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#if _USE_LFN +#error Cannot use LFN feature without valid code page. +#endif +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + +/* Character code support macros */ +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) +#define IsDigit(c) (((c)>='0')&&((c)<='9')) + +#if _DF1S /* Code page is DBCS */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* Code page is SBCS */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + +/* Name status flags */ +#define NS 11 /* Index of name status byte in fn[] */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + +/* FAT sub-type boundaries */ +/* Note that the FAT spec by Microsoft says 4085 but Windows works with 4087! */ +#define MIN_FAT16 4086 /* Minimum number of clusters for FAT16 */ +#define MIN_FAT32 65526 /* Minimum number of clusters for FAT32 */ + + +/* FatFs refers the members in the FAT structures as byte array instead of +/ structure member because the structure is not binary compatible between +/ different platforms */ + +#define BS_jmpBoot 0 /* Jump instruction (3) */ +#define BS_OEMName 3 /* OEM name (8) */ +#define BPB_BytsPerSec 11 /* Sector size [byte] (2) */ +#define BPB_SecPerClus 13 /* Cluster size [sector] (1) */ +#define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (2) */ +#define BPB_NumFATs 16 /* Number of FAT copies (1) */ +#define BPB_RootEntCnt 17 /* Number of root dir entries for FAT12/16 (2) */ +#define BPB_TotSec16 19 /* Volume size [sector] (2) */ +#define BPB_Media 21 /* Media descriptor (1) */ +#define BPB_FATSz16 22 /* FAT size [sector] (2) */ +#define BPB_SecPerTrk 24 /* Track size [sector] (2) */ +#define BPB_NumHeads 26 /* Number of heads (2) */ +#define BPB_HiddSec 28 /* Number of special hidden sectors (4) */ +#define BPB_TotSec32 32 /* Volume size [sector] (4) */ +#define BS_DrvNum 36 /* Physical drive number (2) */ +#define BS_BootSig 38 /* Extended boot signature (1) */ +#define BS_VolID 39 /* Volume serial number (4) */ +#define BS_VolLab 43 /* Volume label (8) */ +#define BS_FilSysType 54 /* File system type (1) */ +#define BPB_FATSz32 36 /* FAT size [sector] (4) */ +#define BPB_ExtFlags 40 /* Extended flags (2) */ +#define BPB_FSVer 42 /* File system version (2) */ +#define BPB_RootClus 44 /* Root dir first cluster (4) */ +#define BPB_FSInfo 48 /* Offset of FSInfo sector (2) */ +#define BPB_BkBootSec 50 /* Offset of backup boot sector (2) */ +#define BS_DrvNum32 64 /* Physical drive number (2) */ +#define BS_BootSig32 66 /* Extended boot signature (1) */ +#define BS_VolID32 67 /* Volume serial number (4) */ +#define BS_VolLab32 71 /* Volume label (8) */ +#define BS_FilSysType32 82 /* File system type (1) */ +#define FSI_LeadSig 0 /* FSI: Leading signature (4) */ +#define FSI_StrucSig 484 /* FSI: Structure signature (4) */ +#define FSI_Free_Count 488 /* FSI: Number of free clusters (4) */ +#define FSI_Nxt_Free 492 /* FSI: Last allocated cluster (4) */ +#define MBR_Table 446 /* MBR: Partition table offset (2) */ +#define SZ_PTE 16 /* MBR: Size of a partition table entry */ +#define BS_55AA 510 /* Boot sector signature (2) */ + +#define DIR_Name 0 /* Short file name (11) */ +#define DIR_Attr 11 /* Attribute (1) */ +#define DIR_NTres 12 /* NT flag (1) */ +#define DIR_CrtTimeTenth 13 /* Created time sub-second (1) */ +#define DIR_CrtTime 14 /* Created time (2) */ +#define DIR_CrtDate 16 /* Created date (2) */ +#define DIR_LstAccDate 18 /* Last accessed date (2) */ +#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (2) */ +#define DIR_WrtTime 22 /* Modified time (2) */ +#define DIR_WrtDate 24 /* Modified date (2) */ +#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (2) */ +#define DIR_FileSize 28 /* File size (4) */ +#define LDIR_Ord 0 /* LFN entry order and LLE flag (1) */ +#define LDIR_Attr 11 /* LFN attribute (1) */ +#define LDIR_Type 12 /* LFN type (1) */ +#define LDIR_Chksum 13 /* Sum of corresponding SFN entry */ +#define LDIR_FstClusLO 26 /* Filled by zero (0) */ +#define SZ_DIR 32 /* Size of a directory entry */ +#define LLE 0x40 /* Last long entry flag in LDIR_Ord */ +#define DDE 0xE5 /* Deleted directory entry mark in DIR_Name[0] */ +#define NDDE 0x05 /* Replacement of the character collides with DDE */ + + +/*------------------------------------------------------------*/ +/* Module private work area */ +/*------------------------------------------------------------*/ +/* Note that uninitialized variables with static duration are +/ zeroed/nulled at start-up. If not, the compiler or start-up +/ routine is out of ANSI-C standard. +*/ + +#if _VOLUMES +static +FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */ +#else +#error Number of volumes must not be 0. +#endif + +static +WORD Fsid; /* File system mount ID */ + +#if _FS_RPATH +static +BYTE CurrVol; /* Current drive */ +#endif + +#if _FS_LOCK +static +FILESEM Files[_FS_LOCK]; /* File lock semaphores */ +#endif + +#if _USE_LFN == 0 /* No LFN feature */ +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) (dobj).fn = sfn +#define FREE_BUF() + +#elif _USE_LFN == 1 /* LFN feature with static working buffer */ +static WCHAR LfnBuf[_MAX_LFN+1]; +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; } +#define FREE_BUF() + +#elif _USE_LFN == 2 /* LFN feature with dynamic working buffer on the stack */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; } +#define FREE_BUF() + +#elif _USE_LFN == 3 /* LFN feature with dynamic working buffer on the heap */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn +#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \ + if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \ + (dobj).lfn = lfn; (dobj).fn = sfn; } +#define FREE_BUF() ff_memfree(lfn) + +#else +#error Wrong LFN configuration. +#endif + + +#ifdef _EXCVT +static +const BYTE ExCvt[] = _EXCVT; /* Upper conversion table for extended chars */ +#endif + + + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, UINT cnt) { + BYTE *d = (BYTE*)dst; + const BYTE *s = (const BYTE*)src; + +#if _WORD_ACCESS == 1 + while (cnt >= sizeof (int)) { + *(int*)d = *(int*)s; + d += sizeof (int); s += sizeof (int); + cnt -= sizeof (int); + } +#endif + while (cnt--) + *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, UINT cnt) { + BYTE *d = (BYTE*)dst; + + while (cnt--) + *d++ = (BYTE)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, UINT cnt) { + const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; + int r = 0; + + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT + +static +int lock_fs ( + FATFS *fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS *fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (fs && + res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* File lock control functions */ +/*-----------------------------------------------------------------------*/ +#if _FS_LOCK + +static +FRESULT chk_lock ( /* Check if the file can be accessed */ + DIR* dj, /* Directory object pointing the file to be checked */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i, be; + + /* Search file semaphore table */ + for (i = be = 0; i < _FS_LOCK; i++) { + if (Files[i].fs) { /* Existing entry */ + if (Files[i].fs == dj->fs && /* Check if the file matched with an open file */ + Files[i].clu == dj->sclust && + Files[i].idx == dj->index) break; + } else { /* Blank entry */ + be++; + } + } + if (i == _FS_LOCK) /* The file is not opened */ + return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new file? */ + + /* The file has been opened. Reject any open against writing file and all write mode open */ + return (acc || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK; +} + + +static +int enq_lock (void) /* Check if an entry is available for a new file */ +{ + UINT i; + + for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; + return (i == _FS_LOCK) ? 0 : 1; +} + + +static +UINT inc_lock ( /* Increment file open counter and returns its index (0:int error) */ + DIR* dj, /* Directory object pointing the file to register or increment */ + int acc /* Desired access mode (0:Read, !0:Write) */ +) +{ + UINT i; + + + for (i = 0; i < _FS_LOCK; i++) { /* Find the file */ + if (Files[i].fs == dj->fs && + Files[i].clu == dj->sclust && + Files[i].idx == dj->index) break; + } + + if (i == _FS_LOCK) { /* Not opened. Register it as new. */ + for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; + if (i == _FS_LOCK) return 0; /* No space to register (int err) */ + Files[i].fs = dj->fs; + Files[i].clu = dj->sclust; + Files[i].idx = dj->index; + Files[i].ctr = 0; + } + + if (acc && Files[i].ctr) return 0; /* Access violation (int err) */ + + Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */ + + return i + 1; +} + + +static +FRESULT dec_lock ( /* Decrement file open counter */ + UINT i /* Semaphore index */ +) +{ + WORD n; + FRESULT res; + + + if (--i < _FS_LOCK) { + n = Files[i].ctr; + if (n == 0x100) n = 0; + if (n) n--; + Files[i].ctr = n; + if (!n) Files[i].fs = 0; + res = FR_OK; + } else { + res = FR_INT_ERR; + } + return res; +} + + +static +void clear_lock ( /* Clear lock entries of the volume */ + FATFS *fs +) +{ + UINT i; + + for (i = 0; i < _FS_LOCK; i++) { + if (Files[i].fs == fs) Files[i].fs = 0; + } +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Move/Flush disk access window */ +/*-----------------------------------------------------------------------*/ + + +#if !_FS_READONLY +static +FRESULT sync_window ( + FATFS *fs /* File system object */ +) +{ + DWORD wsect; + UINT nf; + + + if (fs->wflag) { /* Write back the sector if it is dirty */ + wsect = fs->winsect; /* Current sector number */ + if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect >= fs->fatbase && wsect < (fs->fatbase + fs->fsize)) { /* In FAT area? */ + for (nf = fs->n_fats; nf >= 2; nf--) { /* Reflect the change to all FAT copies */ + wsect += fs->fsize; + disk_write(fs->drv, fs->win, wsect, 1); + } + } + } + return FR_OK; +} +#endif + + +static +FRESULT move_window ( + FATFS *fs, /* File system object */ + DWORD sector /* Sector number to make appearance in the fs->win[] */ +) +{ + if (sector != fs->winsect) { /* Changed current window */ +#if !_FS_READONLY + if (sync_window(fs) != FR_OK) + return FR_DISK_ERR; +#endif + if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) + return FR_DISK_ERR; + fs->winsect = sector; + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize file system and strage device */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync_fs ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS *fs /* File system object */ +) +{ + FRESULT res; + + + res = sync_window(fs); + if (res == FR_OK) { + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { + fs->winsect = 0; + /* Create FSInfo structure */ + mem_set(fs->win, 0, 512); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + /* Write it into the FSInfo sector */ + disk_write(fs->drv, fs->win, fs->fsi_sector, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + BYTE *p; + + + if (clst < 2 || clst >= fs->n_fatent) /* Check range */ + return 1; + + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc = fs->win[bc % SS(fs)]; bc++; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc |= fs->win[bc % SS(fs)] << 8; + return (clst & 1) ? (wc >> 4) : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break; + p = &fs->win[clst * 2 % SS(fs)]; + return LD_WORD(p); + + case FS_FAT32 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break; + p = &fs->win[clst * 4 % SS(fs)]; + return LD_DWORD(p) & 0x0FFFFFFF; + } + + return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS *fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + FRESULT res; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + p = &fs->win[clst * 2 % SS(fs)]; + ST_WORD(p, (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + p = &fs->win[clst * 4 % SS(fs)]; + val |= LD_DWORD(p) & 0xF0000000; + ST_DWORD(p, val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; +#if _USE_ERASE + DWORD scl = clst, ecl = clst, rt[2]; +#endif + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->n_fatent) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */ + fs->free_clust++; + fs->fsi_flag = 1; + } +#if _USE_ERASE + if (ecl + 1 == nxt) { /* Is next cluster contiguous? */ + ecl = nxt; + } else { /* End of contiguous clusters */ + rt[0] = clust2sect(fs, scl); /* Start sector */ + rt[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */ + disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, rt); /* Erase the block */ + scl = ecl = nxt; + } +#endif + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl; + FRESULT res; + + + if (clst == 0) { /* Create a new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (!scl || scl >= fs->n_fatent) scl = 1; + } + else { /* Stretch the current chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* It is an invalid cluster */ + if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */ + return cs; + if (ncl == scl) return 0; /* No free cluster */ + } + + res = put_fat(fs, ncl, 0x0FFFFFFF); /* Mark the new cluster "last link" */ + if (res == FR_OK && clst != 0) { + res = put_fat(fs, clst, ncl); /* Link it to the previous one if needed */ + } + if (res == FR_OK) { + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag = 1; + } + } else { + ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1; + } + + return ncl; /* Return new cluster number or error code */ +} +#endif /* !_FS_READONLY */ + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Convert offset into cluster with link map table */ +/*-----------------------------------------------------------------------*/ + +#if _USE_FASTSEEK +static +DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ + FIL* fp, /* Pointer to the file object */ + DWORD ofs /* File offset to be converted to cluster# */ +) +{ + DWORD cl, ncl, *tbl; + + + tbl = fp->cltbl + 1; /* Top of CLMT */ + cl = ofs / SS(fp->fs) / fp->fs->csize; /* Cluster order from top of the file */ + for (;;) { + ncl = *tbl++; /* Number of cluters in the fragment */ + if (!ncl) return 0; /* End of table? (error) */ + if (cl < ncl) break; /* In this fragment? */ + cl -= ncl; tbl++; /* Next fragment */ + } + return cl + *tbl; /* Return the cluster number */ +} +#endif /* _USE_FASTSEEK */ + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Set directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_sdi ( + DIR *dj, /* Pointer to directory object */ + WORD idx /* Index of directory table */ +) +{ + DWORD clst; + WORD ic; + + + dj->index = idx; + clst = dj->sclust; + if (clst == 1 || clst >= dj->fs->n_fatent) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dj->fs->dirbase; + + if (clst == 0) { /* Static table (root-dir in FAT12/16) */ + dj->clust = clst; + if (idx >= dj->fs->n_rootdir) /* Index is out of range */ + return FR_INT_ERR; + dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / SZ_DIR); /* Sector# */ + } + else { /* Dynamic table (sub-dirs or root-dir in FAT32) */ + ic = SS(dj->fs) / SZ_DIR * dj->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dj->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dj->fs->n_fatent) /* Reached to end of table or int error */ + return FR_INT_ERR; + idx -= ic; + } + dj->clust = clst; + dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / SZ_DIR); /* Sector# */ + } + + dj->dir = dj->fs->win + (idx % (SS(dj->fs) / SZ_DIR)) * SZ_DIR; /* Ptr to the entry in the sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory table index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */ + DIR *dj, /* Pointer to the directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +) +{ + DWORD clst; + WORD i; + + + stretch = stretch; /* To suppress warning on read-only cfg. */ + i = dj->index + 1; + if (!i || !dj->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dj->fs) / SZ_DIR))) { /* Sector changed? */ + dj->sect++; /* Next sector */ + + if (dj->clust == 0) { /* Static table */ + if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dj->fs) / SZ_DIR)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dj->fs, dj->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dj->fs->n_fatent) { /* When it reached end of dynamic table */ +#if !_FS_READONLY + BYTE c; + if (!stretch) return FR_NO_FILE; /* When do not stretch, report EOT */ + clst = create_chain(dj->fs, dj->clust); /* Stretch cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up stretched table */ + if (sync_window(dj->fs)) return FR_DISK_ERR; /* Flush active window */ + mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */ + dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */ + for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */ + dj->fs->wflag = 1; + if (sync_window(dj->fs)) return FR_DISK_ERR; + dj->fs->winsect++; + } + dj->fs->winsect -= c; /* Rewind window address */ +#else + return FR_NO_FILE; /* Report EOT */ +#endif + } + dj->clust = clst; /* Initialize data for new cluster */ + dj->sect = clust2sect(dj->fs, clst); + } + } + } + + dj->index = i; + dj->dir = dj->fs->win + (i % (SS(dj->fs) / SZ_DIR)) * SZ_DIR; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Reserve directory entry */ +/*-----------------------------------------------------------------------*/ + +#if !_FS_READONLY +static +FRESULT dir_alloc ( + DIR* dj, /* Pointer to the directory object */ + UINT nent /* Number of contiguous entries to allocate (1-21) */ +) +{ + FRESULT res; + UINT n; + + + res = dir_sdi(dj, 0); + if (res == FR_OK) { + n = 0; + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + if (dj->dir[0] == DDE || dj->dir[0] == 0) { /* Is it a blank entry? */ + if (++n == nent) break; /* A block of contiguous entry is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dj, 1); /* Next entry with table stretch enabled */ + } while (res == FR_OK); + } + return res; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Load/Store start cluster number */ +/*-----------------------------------------------------------------------*/ + +static +DWORD ld_clust ( + FATFS *fs, /* Pointer to the fs object */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + DWORD cl; + + cl = LD_WORD(dir+DIR_FstClusLO); + if (fs->fs_type == FS_FAT32) + cl |= (DWORD)LD_WORD(dir+DIR_FstClusHI) << 16; + + return cl; +} + + +#if !_FS_READONLY +static +void st_clust ( + BYTE *dir, /* Pointer to the directory entry */ + DWORD cl /* Value to be set */ +) +{ + ST_WORD(dir+DIR_FstClusLO, cl); + ST_WORD(dir+DIR_FstClusHI, cl >> 16); +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */ + + +static +int cmp_lfn ( /* 1:Matched, 0:Not matched */ + WCHAR *lfnbuf, /* Pointer to the LFN to be compared */ + BYTE *dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + UINT i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return 0; /* Not matched */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Repeat until all chars in the entry are checked */ + + if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return 0; + + return 1; /* The part of LFN matched */ +} + + + +static +int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ + WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + UINT i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & LLE) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return 1; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR *lfnbuf, /* Pointer to the LFN buffer */ + BYTE *dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + UINT i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding chars following last char */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +void gen_numname ( + BYTE *dst, /* Pointer to generated SFN */ + const BYTE *src, /* Pointer to source SFN to be modified */ + const WCHAR *lfn, /* Pointer to LFN */ + WORD seq /* Sequence number */ +) +{ + BYTE ns[8], c; + UINT i, j; + + + mem_cpy(dst, src, 11); + + if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */ + do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn); + } + + /* itoa (hexdecimal) */ + i = 7; + do { + c = (seq % 16) + '0'; + if (c > '9') c += 7; + ns[i--] = c; + seq /= 16; + } while (seq); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE *dir /* Ptr to directory entry */ +) +{ + BYTE sum = 0; + UINT n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR *dj /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_sdi(dj, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; +#endif + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dj->lfn) { + if (c & LLE) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= ~LLE; ord = c; /* LFN start order */ + dj->lfn_idx = dj->index; + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2 +static +FRESULT dir_read ( + DIR *dj, /* Pointer to the directory object */ + int vol /* Filtered by 0:file/dir or 1:volume label */ +) +{ + FRESULT res; + BYTE a, c, *dir; +#if _USE_LFN + BYTE ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dj->sect) { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ + a = dir[DIR_Attr] & AM_MASK; +#if _USE_LFN /* LFN configuration */ + if (c == DDE || (!_FS_RPATH && c == '.') || (a == AM_VOL) != vol) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & LLE) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= ~LLE; ord = c; + dj->lfn_idx = dj->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dj->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != DDE && (_FS_RPATH || c != '.') && a != AM_LFN && (a == AM_VOL) == vol) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dj->sect = 0; + + return res; +} +#endif /* _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2 */ + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR *dj /* Target directory with object name to be created */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD n, ne; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dj->fn; lfn = dj->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) /* Cannot create dot entry */ + return FR_INVALID_NAME; + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dj->lfn = 0; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dj); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dj->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, allocate entries for an SFN + LFNs. */ + for (n = 0; lfn[n]; n++) ; + ne = (n + 25) / 13; + } else { /* Otherwise allocate an entry for an SFN */ + ne = 1; + } + res = dir_alloc(dj, ne); /* Allocate entries */ + + if (res == FR_OK && --ne) { /* Set LFN entry if needed */ + res = dir_sdi(dj, (WORD)(dj->index - ne)); + if (res == FR_OK) { + sum = sum_sfn(dj->fn); /* Sum value of the SFN tied to the LFN */ + do { /* Store LFN entries in bottom first */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum); + dj->fs->wflag = 1; + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK && --ne); + } + } +#else /* Non LFN configuration */ + res = dir_alloc(dj, 1); /* Allocate an entry for SFN */ +#endif + + if (res == FR_OK) { /* Set SFN entry */ + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + mem_set(dj->dir, 0, SZ_DIR); /* Clean the entry */ + mem_cpy(dj->dir, dj->fn, 11); /* Put SFN */ +#if _USE_LFN + dj->dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */ +#endif + dj->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR *dj /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD i; + + i = dj->index; /* SFN index */ + res = dir_sdi(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + *dj->dir = DDE; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, dj->index); + if (res == FR_OK) { + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + *dj->dir = DDE; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR *dj, /* Pointer to the directory object */ + const TCHAR **path /* Pointer to pointer to the segment in the path string */ +) +{ +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + UINT i, ni, si, di; + const TCHAR *p; + + /* Create LFN in Unicode */ + for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */ + lfn = dj->lfn; + si = di = 0; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; + if (IsDBCS1(w)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */ + b = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) + return FR_INVALID_NAME; /* Reject invalid sequence */ + w = (w << 8) + b; /* Create a DBC */ + } + w = ff_convert(w, 1); /* Convert ANSI/OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode char */ + } + *path = &p[si]; /* Return pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dj->fn[i] = (i < di) ? '.' : ' '; + dj->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di-1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject nul string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dj->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN char */ + if (!w) break; /* Break on end of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII char */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = ExCvt[w - 0x80]; /* Convert extended char to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte char (always false on SBCS cfg) */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dj->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte char */ + if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal chars for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dj->fn[i++] = (BYTE)w; + } + + if (dj->fn[0] == DDE) dj->fn[0] = NDDE; /* If the first char collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dj->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + UINT ni, si, i; + const char *p; + + /* Create file name in directory form */ + for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */ + sfn = dj->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = (BYTE)p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Return pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = (BYTE)p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended char? */ + b |= 3; /* Eliminate NT flag */ +#ifdef _EXCVT + c = ExCvt[c - 0x80]; /* To upper extended chars (SBCS cfg) */ +#else +#if !_DF1S + return FR_INVALID_NAME; /* Reject extended chars (ASCII cfg) */ +#endif +#endif + } + if (IsDBCS1(c)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */ + d = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr("\"*+,:;<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Return pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject nul string */ + if (sfn[0] == DDE) sfn[0] = NDDE; /* When first char collides with DDE, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 +static +void get_fileinfo ( /* No return code */ + DIR *dj, /* Pointer to the directory object */ + FILINFO *fno /* Pointer to the file information to be filled */ +) +{ + UINT i; + BYTE nt, *dir; + TCHAR *p, c; + + + p = fno->fname; + if (dj->sect) { + dir = dj->dir; + nt = dir[DIR_NTres]; /* NT flag */ + for (i = 0; i < 8; i++) { /* Copy name body */ + c = dir[i]; + if (c == ' ') break; + if (c == NDDE) c = (TCHAR)DDE; + if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 7 && IsDBCS2(dir[i+1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + if (dir[8] != ' ') { /* Copy name extension */ + *p++ = '.'; + for (i = 8; i < 11; i++) { + c = dir[i]; + if (c == ' ') break; + if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 10 && IsDBCS2(dir[i+1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; /* Terminate SFN str by a \0 */ + +#if _USE_LFN + if (fno->lfname && fno->lfsize) { + TCHAR *tp = fno->lfname; + WCHAR w, *lfn; + + i = 0; + if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */ + lfn = dj->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN char */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM conversion */ + if (!w) { i = 0; break; } /* Could not convert, no LFN */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC (always false on SBCS cfg) */ + tp[i++] = (TCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overflow, no LFN */ + tp[i++] = (TCHAR)w; + } + } + tp[i] = 0; /* Terminate the LFN str by a \0 */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2*/ + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR *dj, /* Directory object to return last directory and found object */ + const TCHAR *path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, ns; + + +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dj->sclust = 0; /* Strip it and start from the root dir */ + } else { /* No heading separator */ + dj->sclust = dj->fs->cdir; /* Start from the current dir */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dj->sclust = 0; /* Start from the root dir */ +#endif + + if ((UINT)*path < ' ') { /* Nul path means the start directory itself */ + res = dir_sdi(dj, 0); + dj->dir = 0; + } else { /* Follow path */ + for (;;) { + res = create_name(dj, &path); /* Get a segment */ + if (res != FR_OK) break; + res = dir_find(dj); /* Find it */ + ns = *(dj->fn+NS); + if (res != FR_OK) { /* Failed to find the object */ + if (res != FR_NO_FILE) break; /* Abort if any hard error occurred */ + /* Object not found */ + if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exit */ + dj->sclust = 0; dj->dir = 0; /* It is the root dir */ + res = FR_OK; + if (!(ns & NS_LAST)) continue; + } else { /* Could not find the object */ + if (!(ns & NS_LAST)) res = FR_NO_PATH; + } + break; + } + if (ns & NS_LAST) break; /* Last segment match. Function completed. */ + dir = dj->dir; /* There is next segment. Follow the sub directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ + res = FR_NO_PATH; break; + } + dj->sclust = ld_clust(dj->fs, dir); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load a sector and check if it is an FAT Volume Boot Record */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:FAT-VBR, 1:Any BR but not FAT, 2:Not a BR, 3:Disk error */ + FATFS *fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) /* Load boot record */ + return 3; + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file system object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ + const TCHAR **path, /* Pointer to pointer to the path name (drive number) */ + FATFS **rfs, /* Pointer to pointer to the found file system object */ + BYTE wmode /* !=0: Check write protection for write access */ +) +{ + BYTE fmt, b, pi, *tbl; + UINT vol; + DSTATUS stat; + DWORD bsect, fasize, tsect, sysect, nclst, szbfat; + WORD nrsv; + const TCHAR *p = *path; + FATFS *fs; + + + /* Get logical drive number from the path name */ + vol = p[0] - '0'; /* Is there a drive number? */ + if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ + p += 2; *path = p; /* Return pointer to the path name */ + } else { /* No drive number, use default drive */ +#if _FS_RPATH + vol = CurrVol; /* Use current drive */ +#else + vol = 0; /* Use drive 0 */ +#endif + } + + /* Check if the file system object is valid or not */ + *rfs = 0; + if (vol >= _VOLUMES) /* Is the drive number valid? */ + return FR_INVALID_DRIVE; + fs = FatFs[vol]; /* Get corresponding file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock volume */ + + *rfs = fs; /* Return pointer to the corresponding file system object */ + if (fs->fs_type) { /* If the volume has been mounted */ + stat = disk_status(fs->drv); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ + if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; + return FR_OK; /* The file system object is valid */ + } + } + + /* The file system object is not valid. */ + /* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drv = LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drv); /* Initialize the physical drive */ + if (stat & STA_NOINIT) /* Check if the initialization succeeded */ + return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ + if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size (variable sector size cfg only) */ + if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK) + return FR_DISK_ERR; +#endif + /* Search FAT partition on the drive. Supports only generic partitions, FDISK and SFD. */ + fmt = check_fs(fs, bsect = 0); /* Load sector 0 and check if it is an FAT-VBR (in SFD) */ + if (LD2PT(vol) && !fmt) fmt = 1; /* Force non-SFD if the volume is forced partition */ + if (fmt == 1) { /* Not an FAT-VBR, the physical drive can be partitioned */ + /* Check the partition listed in the partition table */ + pi = LD2PT(vol); + if (pi) pi--; + tbl = &fs->win[MBR_Table + pi * SZ_PTE];/* Partition table */ + if (tbl[4]) { /* Is the partition existing? */ + bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ + fmt = check_fs(fs, bsect); /* Check the partition */ + } + } + if (fmt == 3) return FR_DISK_ERR; + if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + + /* An FAT volume is found. Following code initializes the file system object */ + + if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ + return FR_NO_FILESYSTEM; + + fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); + fs->fsize = fasize; + + fs->n_fats = b = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + if (b != 1 && b != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ + fasize *= b; /* Number of sectors for FAT area */ + + fs->csize = b = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */ + + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / SZ_DIR)) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be sector aligned) */ + + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + + nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (!nrsv) return FR_NO_FILESYSTEM; /* (BPB_RsvdSecCnt must not be 0) */ + + /* Determine the FAT sub type */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR); /* RSV+FAT+DIR */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = FS_FAT12; + if (nclst >= MIN_FAT16) fmt = FS_FAT16; + if (nclst >= MIN_FAT32) fmt = FS_FAT32; + + /* Boundaries and Limits */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->volbase = bsect; /* Volume start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + fs->database = bsect + sysect; /* Data start sector */ + if (fmt == FS_FAT32) { + if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + szbfat = fs->n_fatent * 4; /* (Required FAT size) */ + } else { + if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */ + fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); + } + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (BPB_FATSz must not be less than required) */ + return FR_NO_FILESYSTEM; + +#if !_FS_READONLY + /* Initialize cluster allocation information */ + fs->free_clust = 0xFFFFFFFF; + fs->last_clust = 0; + + /* Get fsinfo if available */ + if (fmt == FS_FAT32) { + fs->fsi_flag = 0; + fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo); + if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK && + LD_WORD(fs->win+BS_55AA) == 0xAA55 && + LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 && + LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) { + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); + } + } +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->id = ++Fsid; /* File system mount ID */ + fs->winsect = 0; /* Invalidate sector cache */ + fs->wflag = 0; +#if _FS_RPATH + fs->cdir = 0; /* Current directory (root dir) */ +#endif +#if _FS_LOCK /* Clear file lock semaphores */ + clear_lock(fs); +#endif + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/dir object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + void* obj /* Pointer to the object FIL/DIR to check validity */ +) +{ + FIL *fil = (FIL*)obj; /* Assuming offset of fs and id in the FIL/DIR is identical */ + + + if (!fil || !fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id) + return FR_INVALID_OBJECT; + + ENTER_FF(fil->fs); /* Lock file system */ + + if (disk_status(fil->fs->drv) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Logical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + BYTE vol, /* Logical drive number to be mounted/unmounted */ + FATFS *fs /* Pointer to new file system object (NULL for unmount)*/ +) +{ + FATFS *rfs; + + + if (vol >= _VOLUMES) /* Check if the drive number is valid */ + return FR_INVALID_DRIVE; + rfs = FatFs[vol]; /* Get current fs object */ + + if (rfs) { +#if _FS_LOCK + clear_lock(rfs); +#endif +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR; +#endif + rfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL *fp, /* Pointer to the blank file object */ + const TCHAR *path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + if (!fp) return FR_INVALID_OBJECT; + fp->fs = 0; /* Clear file object */ + +#if !_FS_READONLY + mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW; + res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ)); +#else + mode &= FA_READ; + res = chk_mounted(&path, &dj.fs, 0); +#endif + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + dir = dj.dir; +#if !_FS_READONLY /* R/W configuration */ + if (res == FR_OK) { + if (!dir) /* Current dir itself */ + res = FR_INVALID_NAME; +#if _FS_LOCK + else + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); +#endif + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD dw, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ +#if _FS_LOCK + res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; +#else + res = dir_register(&dj); +#endif + mode |= FA_CREATE_ALWAYS; /* File is created */ + dir = dj.dir; /* New entry */ + } + else { /* Any object is already existing */ + if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } else { + if (mode & FA_CREATE_NEW) /* Cannot create as new file */ + res = FR_EXIST; + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ + dw = get_fattime(); /* Created time */ + ST_DWORD(dir+DIR_CrtTime, dw); + dir[DIR_Attr] = 0; /* Reset attribute */ + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + cl = ld_clust(dj.fs, dir); /* Get start cluster */ + st_clust(dir, 0); /* cluster = 0 */ + dj.fs->wflag = 1; + if (cl) { /* Remove the cluster chain if exist */ + dw = dj.fs->winsect; + res = remove_chain(dj.fs, cl); + if (res == FR_OK) { + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + res = move_window(dj.fs, dw); + } + } + } + } + else { /* Open an existing file */ + if (res == FR_OK) { /* Follow succeeded */ + if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + res = FR_DENIED; + } + } + } + if (res == FR_OK) { + if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */ + mode |= FA__WRITTEN; + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dir; +#if _FS_LOCK + fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + if (!fp->lockid) res = FR_INT_ERR; +#endif + } + +#else /* R/O configuration */ + if (res == FR_OK) { /* Follow succeeded */ + dir = dj.dir; + if (!dir) { /* Current dir itself */ + res = FR_INVALID_NAME; + } else { + if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ + res = FR_NO_FILE; + } + } +#endif + FREE_BUF(); + + if (res == FR_OK) { + fp->flag = mode; /* File access mode */ + fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */ + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; /* File pointer */ + fp->dsect = 0; +#if _USE_FASTSEEK + fp->cltbl = 0; /* Normal seek mode */ +#endif + fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */ + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL *fp, /* Pointer to the file object */ + void *buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE csect, *rbuff = (BYTE*)buff; + + + *br = 0; /* Clear read byte counter */ + + res = validate(fp); /* Check validity */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Aborted file? */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data read */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->sclust; /* Follow from the origin */ + } else { /* Middle or end of the file */ +#if _USE_FASTSEEK + if (fp->cltbl) + clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ + else +#endif + clst = get_fat(fp->fs, fp->clust); /* Follow cluster chain on the FAT */ + } + if (clst < 2) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } + sect = clust2sect(fp->fs, fp->clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY + if (fp->dsect != sect) { /* Load data sector if not in cache */ +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) /* Fill sector cache */ + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL *fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = (const BYTE*)buff; + BYTE csect; + + + *bw = 0; /* Clear write byte counter */ + + res = validate(fp); /* Check validity */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Aborted file? */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data written */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->sclust; /* Follow from the origin */ + if (clst == 0) /* When no cluster is allocated, */ + fp->sclust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ +#if _USE_FASTSEEK + if (fp->cltbl) + clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ + else +#endif + clst = create_chain(fp->fs, fp->clust); /* Follow or stretch cluster chain on the FAT */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && sync_window(fp->fs)) /* Write-back sector cache */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write-back sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly cache filling at growing edge */ + if (sync_window(fp->fs)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector cache with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file change flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tm; + BYTE *dir; + + + res = validate(fp); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ +#if !_FS_TINY /* Write-back dirty buffer */ + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + st_clust(dir, fp->sclust); /* Update start cluster */ + tm = get_fattime(); /* Update updated time */ + ST_DWORD(dir+DIR_WrtTime, tm); + ST_WORD(dir+DIR_LstAccDate, 0); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync_fs(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + + +#if _FS_READONLY + res = validate(fp); + { +#if _FS_REENTRANT + FATFS *fs = fp->fs; +#endif + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + LEAVE_FF(fs, res); + } +#else + res = f_sync(fp); /* Flush cached data */ +#if _FS_LOCK + if (res == FR_OK) { /* Decrement open counter */ +#if _FS_REENTRANT + FATFS *fs = fp->fs;; + res = validate(fp); + if (res == FR_OK) { + res = dec_lock(fp->lockid); + unlock_fs(fs, FR_OK); + } +#else + res = dec_lock(fp->lockid); +#endif + } +#endif + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + return res; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Current Drive/Directory Handlings */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH >= 1 + +FRESULT f_chdrive ( + BYTE drv /* Drive number */ +) +{ + if (drv >= _VOLUMES) return FR_INVALID_DRIVE; + + CurrVol = drv; + + return FR_OK; +} + +BYTE f_get_current_drive(void) +{ + return CurrVol; +} + +FRESULT f_chdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the path */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + if (!dj.dir) { + dj.fs->cdir = dj.sclust; /* Start directory itself */ + } else { + if (dj.dir[DIR_Attr] & AM_DIR) /* Reached to the directory */ + dj.fs->cdir = ld_clust(dj.fs, dj.dir); + else + res = FR_NO_PATH; /* Reached but a file */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + + +#if _FS_RPATH >= 2 +FRESULT f_getcwd ( + TCHAR *buff, /* Pointer to the directory path */ + UINT len /* Size of path */ +) +{ + FRESULT res; + DIR dj; + UINT i, n; + DWORD ccl; + TCHAR *tp; + FILINFO fno; + DEF_NAMEBUF; + + + *buff = 0; + res = chk_mounted((const TCHAR**)&buff, &dj.fs, 0); /* Get current volume */ + if (res == FR_OK) { + INIT_BUF(dj); + i = len; /* Bottom of buffer (dir stack base) */ + dj.sclust = dj.fs->cdir; /* Start to follow upper dir from current dir */ + while ((ccl = dj.sclust) != 0) { /* Repeat while current dir is a sub-dir */ + res = dir_sdi(&dj, 1); /* Get parent dir */ + if (res != FR_OK) break; + res = dir_read(&dj, 0); + if (res != FR_OK) break; + dj.sclust = ld_clust(dj.fs, dj.dir); /* Goto parent dir */ + res = dir_sdi(&dj, 0); + if (res != FR_OK) break; + do { /* Find the entry links to the child dir */ + res = dir_read(&dj, 0); + if (res != FR_OK) break; + if (ccl == ld_clust(dj.fs, dj.dir)) break; /* Found the entry */ + res = dir_next(&dj, 0); + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */ + if (res != FR_OK) break; +#if _USE_LFN + fno.lfname = buff; + fno.lfsize = i; +#endif + get_fileinfo(&dj, &fno); /* Get the dir name and push it to the buffer */ + tp = fno.fname; + if (_USE_LFN && *buff) tp = buff; + for (n = 0; tp[n]; n++) ; + if (i < n + 3) { + res = FR_NOT_ENOUGH_CORE; break; + } + while (n) buff[--i] = tp[--n]; + buff[--i] = '/'; + } + tp = buff; + if (res == FR_OK) { + *tp++ = '0' + CurrVol; /* Put drive number */ + *tp++ = ':'; + if (i == len) { /* Root-dir */ + *tp++ = '/'; + } else { /* Sub-dir */ + do /* Add stacked path str */ + *tp++ = buff[i++]; + while (i < len); + } + } + *tp = 0; + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} +#endif /* _FS_RPATH >= 2 */ +#endif /* _FS_RPATH >= 1 */ + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL *fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + + + res = validate(fp); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + +#if _USE_FASTSEEK + if (fp->cltbl) { /* Fast seek */ + DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl; + + if (ofs == CREATE_LINKMAP) { /* Create CLMT */ + tbl = fp->cltbl; + tlen = *tbl++; ulen = 2; /* Given table size and required table size */ + cl = fp->sclust; /* Top of the chain */ + if (cl) { + do { + /* Get a fragment */ + tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */ + do { + pcl = cl; ncl++; + cl = get_fat(fp->fs, cl); + if (cl <= 1) ABORT(fp->fs, FR_INT_ERR); + if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + } while (cl == pcl + 1); + if (ulen <= tlen) { /* Store the length and top of the fragment */ + *tbl++ = ncl; *tbl++ = tcl; + } + } while (cl < fp->fs->n_fatent); /* Repeat until end of chain */ + } + *fp->cltbl = ulen; /* Number of items used */ + if (ulen <= tlen) + *tbl = 0; /* Terminate table */ + else + res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */ + + } else { /* Fast seek */ + if (ofs > fp->fsize) /* Clip offset at the file size */ + ofs = fp->fsize; + fp->fptr = ofs; /* Set file pointer */ + if (ofs) { + fp->clust = clmt_clust(fp, ofs - 1); + dsc = clust2sect(fp->fs, fp->clust); + if (!dsc) ABORT(fp->fs, FR_INT_ERR); + dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1); + if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { /* Refill sector cache if needed */ +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) /* Load current sector */ + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = dsc; + } + } + } + } else +#endif + + /* Normal Seek */ + { + DWORD clst, bcs, nsect, ifptr; + + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; + if (ofs) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->clust; + } else { /* When seek to back cluster, */ + clst = fp->sclust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->sclust = clst; + } +#endif + fp->clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR); + fp->clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += ofs / SS(fp->fs); + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { /* Fill sector cache if needed */ +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) /* Fill sector cache */ + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set file change flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + } + + LEAVE_FF(fp->fs, res); +} + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directory Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR *dj, /* Pointer to directory object to create */ + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + FATFS *fs; + DEF_NAMEBUF; + + + if (!dj) return FR_INVALID_OBJECT; + + res = chk_mounted(&path, &dj->fs, 0); + fs = dj->fs; + if (res == FR_OK) { + INIT_BUF(*dj); + res = follow_path(dj, path); /* Follow the path to the directory */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + if (dj->dir) { /* It is not the root dir */ + if (dj->dir[DIR_Attr] & AM_DIR) { /* The object is a directory */ + dj->sclust = ld_clust(fs, dj->dir); + } else { /* The object is not a directory */ + res = FR_NO_PATH; + } + } + if (res == FR_OK) { + dj->id = fs->id; + res = dir_sdi(dj, 0); /* Rewind dir */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + if (res != FR_OK) dj->fs = 0; /* Invalidate the dir object if function faild */ + } else { + dj->fs = 0; + } + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entry in Sequence */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR *dj, /* Pointer to the open directory object */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DEF_NAMEBUF; + + + res = validate(dj); /* Check validity of the object */ + if (res == FR_OK) { + if (!fno) { + res = dir_sdi(dj, 0); /* Rewind the directory object */ + } else { + INIT_BUF(*dj); + res = dir_read(dj, 0); /* Read an item */ + if (res == FR_NO_FILE) { /* Reached end of dir */ + dj->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dj, fno); /* Get the object information */ + res = dir_next(dj, 0); /* Increment index for next */ + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + } + FREE_BUF(); + } + } + + LEAVE_FF(dj->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const TCHAR *path, /* Pointer to the file path */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.dir) /* Found an object */ + get_fileinfo(&dj, fno); + else /* It is root dir */ + res = FR_INVALID_NAME; + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const TCHAR *path, /* Path name of the logical drive number */ + DWORD *nclst, /* Pointer to a variable to return number of free clusters */ + FATFS **fatfs /* Pointer to return pointer to corresponding file system object */ +) +{ + FRESULT res; + FATFS *fs; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get drive number */ + res = chk_mounted(&path, fatfs, 0); + fs = *fatfs; + if (res == FR_OK) { + /* If free_clust is valid, return it without full cluster scan */ + if (fs->free_clust <= fs->n_fatent - 2) { + *nclst = fs->free_clust; + } else { + /* Get number of free clusters */ + fat = fs->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(fs, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) n++; + } while (++clst < fs->n_fatent); + } else { + clst = fs->n_fatent; + sect = fs->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(fs, sect++); + if (res != FR_OK) break; + p = fs->win; + i = SS(fs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + fs->free_clust = n; + if (fat == FS_FAT32) fs->fsi_flag = 1; + *nclst = n; + } + } + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__ERROR) { /* Check abort flag */ + res = FR_INT_ERR; + } else { + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + res = FR_DENIED; + } + } + if (res == FR_OK) { + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->sclust); + fp->sclust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->n_fatent) { + res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } + } + if (res != FR_OK) fp->flag |= FA__ERROR; + } + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const TCHAR *path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + BYTE *dir; + DWORD dclst; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; /* Cannot remove dot entry */ +#if _FS_LOCK + if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */ +#endif + if (res == FR_OK) { /* The object is accessible */ + dir = dj.dir; + if (!dir) { + res = FR_INVALID_NAME; /* Cannot remove the start directory */ + } else { + if (dir[DIR_Attr] & AM_RDO) + res = FR_DENIED; /* Cannot remove R/O object */ + } + dclst = ld_clust(dj.fs, dir); + if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ + if (dclst < 2) { + res = FR_INT_ERR; + } else { + mem_cpy(&sdj, &dj, sizeof (DIR)); /* Check if the sub-dir is empty or not */ + sdj.sclust = dclst; + res = dir_sdi(&sdj, 2); /* Exclude dot entries */ + if (res == FR_OK) { + res = dir_read(&sdj, 0); /* Read an item */ + if (res == FR_OK /* Not empty dir */ +#if _FS_RPATH + || dclst == dj.fs->cdir /* Current dir */ +#endif + ) res = FR_DENIED; + if (res == FR_NO_FILE) res = FR_OK; /* Empty */ + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj); /* Remove the directory entry */ + if (res == FR_OK) { + if (dclst) /* Remove the cluster chain if exist */ + res = remove_chain(dj.fs, dclst); + if (res == FR_OK) res = sync_fs(dj.fs); + } + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir, n; + DWORD dsc, dcl, pcl, tm = get_fattime(); + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_NO_FILE) { /* Can create a new directory */ + dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */ + res = FR_OK; + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ + if (dcl == 1) res = FR_INT_ERR; + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) /* Flush FAT */ + res = sync_window(dj.fs); + if (res == FR_OK) { /* Initialize the new directory table */ + dsc = clust2sect(dj.fs, dcl); + dir = dj.fs->win; + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 11); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + ST_DWORD(dir+DIR_WrtTime, tm); + st_clust(dir, dcl); + mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */ + dir[33] = '.'; pcl = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) + pcl = 0; + st_clust(dir+SZ_DIR, pcl); + for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ + dj.fs->winsect = dsc++; + dj.fs->wflag = 1; + res = sync_window(dj.fs); + if (res != FR_OK) break; + mem_set(dir, 0, SS(dj.fs)); + } + } + if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */ + if (res != FR_OK) { + remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */ + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tm); /* Created time */ + st_clust(dir, dcl); /* Table start cluster */ + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const TCHAR *path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const TCHAR *path, /* Pointer to the file/directory name */ + const FILINFO *fno /* Pointer to the time stamp to be set */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const TCHAR *path_old, /* Pointer to the old name */ + const TCHAR *path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR djo, djn; + BYTE buf[21], *dir; + DWORD dw; + DEF_NAMEBUF; + + + res = chk_mounted(&path_old, &djo.fs, 1); + if (res == FR_OK) { + djn.fs = djo.fs; + INIT_BUF(djo); + res = follow_path(&djo, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; +#if _FS_LOCK + if (res == FR_OK) res = chk_lock(&djo, 2); +#endif + if (res == FR_OK) { /* Old object is found */ + if (!djo.dir) { /* Is root dir? */ + res = FR_NO_FILE; + } else { + mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */ + mem_cpy(&djn, &djo, sizeof (DIR)); /* Check new object */ + res = follow_path(&djn, path_new); + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ +/* Start critical section that any interruption can cause a cross-link */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + dir = djn.dir; /* Copy object information except for name */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + djo.fs->wflag = 1; + if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */ + dw = clust2sect(djo.fs, ld_clust(djo.fs, dir)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(djo.fs, dw); + dir = djo.fs->win+SZ_DIR; /* .. entry */ + if (res == FR_OK && dir[1] == '.') { + dw = (djo.fs->fs_type == FS_FAT32 && djn.sclust == djo.fs->dirbase) ? 0 : djn.sclust; + st_clust(dir, dw); + djo.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&djo); /* Remove old entry */ + if (res == FR_OK) + res = sync_fs(djo.fs); + } + } +/* End critical section */ + } + } + } + FREE_BUF(); + } + + LEAVE_FF(djo.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +#if _USE_LABEL +/*-----------------------------------------------------------------------*/ +/* Get volume label */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getlabel ( + const TCHAR* path, /* Path name of the logical drive number */ + TCHAR* label, /* Pointer to a buffer to return the volume label */ + DWORD* sn /* Pointer to a variable to return the volume serial number */ +) +{ + FRESULT res; + DIR dj; + UINT i, j; + + + /* Get logical drive */ + res = chk_mounted(&path, &dj.fs, 0); + + /* Get volume label */ + if (res == FR_OK && label) { + dj.sclust = 0; /* Open root dir */ + res = dir_sdi(&dj, 0); + if (res == FR_OK) { + res = dir_read(&dj, 1); /* Get an entry with AM_VOL */ + if (res == FR_OK) { /* A volume label is exist */ +#if _LFN_UNICODE + WCHAR w; + i = j = 0; + do { + w = (i < 11) ? dj.dir[i++] : ' '; + if (IsDBCS1(w) && i < 11 && IsDBCS2(dj.dir[i])) + w = (w << 8) | dj.dir[i++]; + label[j++] = ff_convert(w, 1); + } while (j < 11); +#else + mem_cpy(label, dj.dir, 11); +#endif + j = 11; + do { + label[j] = 0; + if (!j) break; + } while (label[--j] == ' '); + } + if (res == FR_NO_FILE) { /* No label, return nul string */ + label[0] = 0; + res = FR_OK; + } + } + } + + /* Get volume serial number */ + if (res == FR_OK && sn) { + res = move_window(dj.fs, dj.fs->volbase); + if (res == FR_OK) { + i = dj.fs->fs_type == FS_FAT32 ? BS_VolID32 : BS_VolID; + *sn = LD_DWORD(&dj.fs->win[i]); + } + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Set volume label */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_setlabel ( + const TCHAR* label /* Pointer to the volume label to set */ +) +{ + FRESULT res; + DIR dj; + BYTE vn[11]; + UINT i, j, sl; + WCHAR w; + DWORD tm; + + + /* Get logical drive */ + res = chk_mounted(&label, &dj.fs, 1); + if (res) LEAVE_FF(dj.fs, res); + + /* Create a volume label in directory form */ + vn[0] = 0; + for (sl = 0; label[sl]; sl++) ; /* Get name length */ + for ( ; sl && label[sl-1] == ' '; sl--) ; /* Remove trailing spaces */ + if (sl) { /* Create volume label in directory form */ + i = j = 0; + do { +#if _LFN_UNICODE + w = ff_convert(ff_wtoupper(label[i++]), 0); +#else + w = (BYTE)label[i++]; + if (IsDBCS1(w)) + w = (j < 10 && i < sl && IsDBCS2(label[i])) ? (w << 8) | (BYTE)label[i++] : 0; +#if _USE_LFN + w = ff_convert(ff_wtoupper(ff_convert(w, 1)), 0); +#else + if (IsLower(w)) w -= 0x20; /* To upper ASCII chars */ +#ifdef _EXCVT + if (w >= 0x80) w = ExCvt[w - 0x80]; /* To upper extended chars (SBCS cfg) */ +#else + if (!_DF1S && w >= 0x80) w = 0; /* Reject extended chars (ASCII cfg) */ +#endif +#endif +#endif + if (!w || chk_chr("\"*+,.:;<=>\?[]|\x7F", w) || j >= (UINT)((w >= 0x100) ? 10 : 11)) /* Reject invalid chars for volume label */ + LEAVE_FF(dj.fs, FR_INVALID_NAME); + if (w >= 0x100) vn[j++] = (BYTE)(w >> 8); + vn[j++] = (BYTE)w; + } while (i < sl); + while (j < 11) vn[j++] = ' '; + } + + /* Set volume label */ + dj.sclust = 0; /* Open root dir */ + res = dir_sdi(&dj, 0); + if (res == FR_OK) { + res = dir_read(&dj, 1); /* Get an entry with AM_VOL */ + if (res == FR_OK) { /* A volume label is found */ + if (vn[0]) { + mem_cpy(dj.dir, vn, 11); /* Change the volume label name */ + tm = get_fattime(); + ST_DWORD(dj.dir+DIR_WrtTime, tm); + } else { + dj.dir[0] = DDE; /* Remove the volume label */ + } + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } else { /* No volume label is found or error */ + if (res == FR_NO_FILE) { + res = FR_OK; + if (vn[0]) { /* Create volume label as new */ + res = dir_alloc(&dj, 1); /* Allocate an entry for volume label */ + if (res == FR_OK) { + mem_set(dj.dir, 0, SZ_DIR); /* Set volume label */ + mem_cpy(dj.dir, vn, 11); + dj.dir[DIR_Attr] = AM_VOL; + tm = get_fattime(); + ST_DWORD(dj.dir+DIR_WrtTime, tm); + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + } + } + + LEAVE_FF(dj.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_LABEL */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (available on only tiny cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL *fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btf, /* Number of bytes to forward */ + UINT *bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + BYTE csect; + + + *bf = 0; /* Clear transfer byte counter */ + + res = validate(fp); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check error flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btf > remain) btf = (UINT)remain; /* Truncate btf by remaining bytes */ + + for ( ; btf && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) { + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->sclust : get_fat(fp->fs, fp->clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } + } + sect = clust2sect(fp->fs, fp->clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btf) rcnt = btf; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Number of root dir entries for FAT12/16 */ +#define N_FATS 1 /* Number of FAT copies (1 or 2) */ + + +FRESULT f_mkfs ( + BYTE vol, /* Logical drive number */ + BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */ + UINT au /* Allocation unit size [bytes] */ +) +{ + static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0}; + static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512}; + BYTE fmt, md, sys, *tbl, pdrv, part; + DWORD n_clst, vs, n, wsect; + UINT i; + DWORD b_vol, b_fat, b_dir, b_data; /* LBA */ + DWORD n_vol, n_rsv, n_fat, n_dir; /* Size */ + FATFS *fs; + DSTATUS stat; + + + /* Check mounted drive and clear work area */ + if (vol >= _VOLUMES) return FR_INVALID_DRIVE; + if (sfd > 1) return FR_INVALID_PARAMETER; + if (au & (au - 1)) return FR_INVALID_PARAMETER; + fs = FatFs[vol]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + pdrv = LD2PD(vol); /* Physical drive */ + part = LD2PT(vol); /* Partition (0:auto detect, 1-4:get from partition table)*/ + + /* Get disk statics */ + stat = disk_initialize(pdrv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size */ + if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_DISK_ERR; +#endif + if (_MULTI_PARTITION && part) { + /* Get partition information from partition table in the MBR */ + if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR; + if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; + tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE]; + if (!tbl[4]) return FR_MKFS_ABORTED; /* No partition? */ + b_vol = LD_DWORD(tbl+8); /* Volume start sector */ + n_vol = LD_DWORD(tbl+12); /* Volume size */ + } else { + /* Create a partition in this function */ + if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) + return FR_DISK_ERR; + b_vol = (sfd) ? 0 : 63; /* Volume start sector */ + n_vol -= b_vol; /* Volume size */ + } + + if (!au) { /* AU auto selection */ + vs = n_vol / (2000 / (SS(fs) / 512)); + for (i = 0; vs < vst[i]; i++) ; + au = cst[i]; + } + au /= SS(fs); /* Number of sectors per cluster */ + if (au == 0) au = 1; + if (au > 128) au = 128; + + /* Pre-compute number of clusters and FAT sub-type */ + n_clst = n_vol / au; + fmt = FS_FAT12; + if (n_clst >= MIN_FAT16) fmt = FS_FAT16; + if (n_clst >= MIN_FAT32) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + if (fmt == FS_FAT32) { + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 32; + n_dir = 0; + } else { + n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4; + n_fat = (n_fat + SS(fs) - 1) / SS(fs); + n_rsv = 1; + n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs); + } + b_fat = b_vol + n_rsv; /* FAT area start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */ + b_data = b_dir + n_dir; /* Data area start sector */ + if (n_vol < b_data + au - b_vol) return FR_MKFS_ABORTED; /* Too small volume */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1; + n = (b_data + n - 1) & ~(n - 1); /* Next nearest erase block from current data start */ + n = (n - b_data) / N_FATS; + if (fmt == FS_FAT32) { /* FAT32: Move FAT offset */ + n_rsv += n; + b_fat += n; + } else { /* FAT12/16: Expand FAT size */ + n_fat += n; + } + + /* Determine number of clusters and final check of validity of the FAT sub-type */ + n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au; + if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16) + || (fmt == FS_FAT32 && n_clst < MIN_FAT32)) + return FR_MKFS_ABORTED; + + switch (fmt) { /* Determine system ID for partition table */ + case FS_FAT12: sys = 0x01; break; + case FS_FAT16: sys = (n_vol < 0x10000) ? 0x04 : 0x06; break; + default: sys = 0x0C; + } + + if (_MULTI_PARTITION && part) { + /* Update system ID in the partition table */ + tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE]; + tbl[4] = sys; + if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR; + md = 0xF8; + } else { + if (sfd) { /* No partition table (SFD) */ + md = 0xF0; + } else { /* Create partition table (FDISK) */ + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; /* Create partition table for single partition in the drive */ + tbl[1] = 1; /* Partition start head */ + tbl[2] = 1; /* Partition start sector */ + tbl[3] = 0; /* Partition start cylinder */ + tbl[4] = sys; /* System type */ + tbl[5] = 254; /* Partition end head */ + n = (b_vol + n_vol) / 63 / 255; + tbl[6] = (BYTE)((n >> 2) | 63); /* Partition end sector */ + tbl[7] = (BYTE)n; /* End cylinder */ + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ + ST_WORD(fs->win+BS_55AA, 0xAA55); /* MBR signature */ + if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) /* Write it to the MBR sector */ + return FR_DISK_ERR; + md = 0xF8; + } + } + + /* Create BPB in the VBR */ + tbl = fs->win; /* Clear sector */ + mem_set(tbl, 0, SS(fs)); + mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */ + i = SS(fs); /* Sector size */ + ST_WORD(tbl+BPB_BytsPerSec, i); + tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of rootdir entries */ + ST_WORD(tbl+BPB_RootEntCnt, i); + if (n_vol < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_vol); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_vol); + } + tbl[BPB_Media] = md; /* Media descriptor */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */ + n = get_fattime(); /* Use current time as VSN */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+BS_VolID32, n); /* VSN */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (VBR+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID, n); /* VSN */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ + if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK) /* Write it to the VBR sector */ + return FR_DISK_ERR; + if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR+6) */ + disk_write(pdrv, tbl, b_vol + 6, 1); + + /* Initialize FAT area */ + wsect = b_fat; + for (i = 0; i < N_FATS; i++) { /* Initialize each FAT copy */ + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + n = md; /* Media descriptor byte */ + if (fmt != FS_FAT32) { + n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + n |= 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0xFFFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */ + } + if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */ + for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector writes */ + if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK) + return FR_DISK_ERR; + } + } + + /* Initialize root directory */ + i = (fmt == FS_FAT32) ? au : n_dir; + do { + if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK) + return FR_DISK_ERR; + } while (--i); + +#if _USE_ERASE /* Erase data area if needed */ + { + DWORD eb[2]; + + eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1; + disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb); + } +#endif + + /* Create FSInfo if needed */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); /* Number of free clusters */ + ST_DWORD(tbl+FSI_Nxt_Free, 2); /* Last allocated cluster# */ + ST_WORD(tbl+BS_55AA, 0xAA55); + disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR+1) */ + disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR+7) */ + } + + return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + + +#if _MULTI_PARTITION +/*-----------------------------------------------------------------------*/ +/* Divide Physical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_fdisk ( + BYTE pdrv, /* Physical drive number */ + const DWORD szt[], /* Pointer to the size table for each partitions */ + void* work /* Pointer to the working buffer */ +) +{ + UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl; + BYTE s_hd, e_hd, *p, *buf = (BYTE*)work; + DSTATUS stat; + DWORD sz_disk, sz_part, s_part; + + + stat = disk_initialize(pdrv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; + if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR; + + /* Determine CHS in the table regardless of the drive geometry */ + for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ; + if (n == 256) n--; + e_hd = n - 1; + sz_cyl = 63 * n; + tot_cyl = sz_disk / sz_cyl; + + /* Create partition table */ + mem_set(buf, 0, _MAX_SS); + p = buf + MBR_Table; b_cyl = 0; + for (i = 0; i < 4; i++, p += SZ_PTE) { + p_cyl = (szt[i] <= 100) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl; + if (!p_cyl) continue; + s_part = (DWORD)sz_cyl * b_cyl; + sz_part = (DWORD)sz_cyl * p_cyl; + if (i == 0) { /* Exclude first track of cylinder 0 */ + s_hd = 1; + s_part += 63; sz_part -= 63; + } else { + s_hd = 0; + } + e_cyl = b_cyl + p_cyl - 1; + if (e_cyl >= tot_cyl) return FR_INVALID_PARAMETER; + + /* Set partition table */ + p[1] = s_hd; /* Start head */ + p[2] = (BYTE)((b_cyl >> 2) + 1); /* Start sector */ + p[3] = (BYTE)b_cyl; /* Start cylinder */ + p[4] = 0x06; /* System type (temporary setting) */ + p[5] = e_hd; /* End head */ + p[6] = (BYTE)((e_cyl >> 2) + 63); /* End sector */ + p[7] = (BYTE)e_cyl; /* End cylinder */ + ST_DWORD(p + 8, s_part); /* Start sector in LBA */ + ST_DWORD(p + 12, sz_part); /* Partition size */ + + /* Next partition */ + b_cyl += p_cyl; + } + ST_WORD(p, 0xAA55); + + /* Write it to the MBR */ + return (disk_write(pdrv, buf, 0, 1) || disk_ioctl(pdrv, CTRL_SYNC, 0)) ? FR_DISK_ERR : FR_OK; +} + + +#endif /* _MULTI_PARTITION */ +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ + +TCHAR* f_gets ( + TCHAR* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer (characters) */ + FIL* fp /* Pointer to the file object */ +) +{ + int n = 0; + TCHAR c, *p = buff; + BYTE s[2]; + UINT rc; + + + while (n < len - 1) { /* Read bytes until buffer gets filled */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; /* Break on EOF or error */ + c = s[0]; +#if _LFN_UNICODE /* Read a character in UTF-8 encoding */ + if (c >= 0x80) { + if (c < 0xC0) continue; /* Skip stray trailer */ + if (c < 0xE0) { /* Two-byte sequence */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = ((c & 0x1F) << 6) | (s[0] & 0x3F); + if (c < 0x80) c = '?'; + } else { + if (c < 0xF0) { /* Three-byte sequence */ + f_read(fp, s, 2, &rc); + if (rc != 2) break; + c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F); + if (c < 0x800) c = '?'; + } else { /* Reject four-byte sequence */ + c = '?'; + } + } + } +#endif +#if _USE_STRFUNC >= 2 + if (c == '\r') continue; /* Strip '\r' */ +#endif + *p++ = c; + n++; + if (c == '\n') break; /* Break on EOL */ + } + *p = 0; + return n ? buff : 0; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ + +int f_putc ( + TCHAR c, /* A character to be output */ + FIL* fp /* Pointer to the file object */ +) +{ + UINT bw, btw; + BYTE s[3]; + + +#if _USE_STRFUNC >= 2 + if (c == '\n') f_putc ('\r', fp); /* LF -> CRLF conversion */ +#endif + +#if _LFN_UNICODE /* Write the character in UTF-8 encoding */ + if (c < 0x80) { /* 7-bit */ + s[0] = (BYTE)c; + btw = 1; + } else { + if (c < 0x800) { /* 11-bit */ + s[0] = (BYTE)(0xC0 | (c >> 6)); + s[1] = (BYTE)(0x80 | (c & 0x3F)); + btw = 2; + } else { /* 16-bit */ + s[0] = (BYTE)(0xE0 | (c >> 12)); + s[1] = (BYTE)(0x80 | ((c >> 6) & 0x3F)); + s[2] = (BYTE)(0x80 | (c & 0x3F)); + btw = 3; + } + } +#else /* Write the character without conversion */ + s[0] = (BYTE)c; + btw = 1; +#endif + f_write(fp, s, btw, &bw); /* Write the char to the file */ + return (bw == btw) ? 1 : EOF; /* Return the result */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ + +int f_puts ( + const TCHAR* str, /* Pointer to the string to be output */ + FIL* fp /* Pointer to the file object */ +) +{ + int n; + + + for (n = 0; *str; str++, n++) { + if (f_putc(*str, fp) == EOF) return EOF; + } + return n; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ + +int f_printf ( + FIL* fp, /* Pointer to the file object */ + const TCHAR* str, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + BYTE f, r; + UINT i, j, w; + ULONG v; + TCHAR c, d, s[16], *p; + int res, chc, cc; + + + va_start(arp, str); + + for (cc = res = 0; cc != EOF; res += cc) { + c = *str++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape character */ + cc = f_putc(c, fp); + if (cc != EOF) cc = 1; + continue; + } + w = f = 0; + c = *str++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *str++; + } else { + if (c == '-') { /* Flag: left justified */ + f = 2; c = *str++; + } + } + while (IsDigit(c)) { /* Precision */ + w = w * 10 + c - '0'; + c = *str++; + } + if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ + f |= 4; c = *str++; + } + if (!c) break; + d = c; + if (IsLower(d)) d -= 0x20; + switch (d) { /* Type is... */ + case 'S' : /* String */ + p = va_arg(arp, TCHAR*); + for (j = 0; p[j]; j++) ; + chc = 0; + if (!(f & 2)) { + while (j++ < w) chc += (cc = f_putc(' ', fp)); + } + chc += (cc = f_puts(p, fp)); + while (j++ < w) chc += (cc = f_putc(' ', fp)); + if (cc != EOF) cc = chc; + continue; + case 'C' : /* Character */ + cc = f_putc((TCHAR)va_arg(arp, int), fp); continue; + case 'B' : /* Binary */ + r = 2; break; + case 'O' : /* Octal */ + r = 8; break; + case 'D' : /* Signed decimal */ + case 'U' : /* Unsigned decimal */ + r = 10; break; + case 'X' : /* Hexdecimal */ + r = 16; break; + default: /* Unknown type (pass-through) */ + cc = f_putc(c, fp); continue; + } + + /* Get an argument and put it in numeral */ + v = (f & 4) ? (ULONG)va_arg(arp, long) : ((d == 'D') ? (ULONG)(long)va_arg(arp, int) : (ULONG)va_arg(arp, unsigned int)); + if (d == 'D' && (v & 0x80000000)) { + v = 0 - v; + f |= 8; + } + i = 0; + do { + d = (TCHAR)(v % r); v /= r; + if (d > 9) d += (c == 'x') ? 0x27 : 0x07; + s[i++] = d + '0'; + } while (v && i < sizeof s / sizeof s[0]); + if (f & 8) s[i++] = '-'; + j = i; d = (f & 1) ? '0' : ' '; + chc = 0; + while (!(f & 2) && j++ < w) chc += (cc = f_putc(d, fp)); + do chc += (cc = f_putc(s[--i], fp)); while(i); + while (j++ < w) chc += (cc = f_putc(' ', fp)); + if (cc != EOF) cc = chc; + } + + va_end(arp); + return (cc == EOF) ? cc : res; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ + +#endif // CFG_TUH_MSC diff --git a/circuitpython/lib/tinyusb/lib/fatfs/ff.h b/circuitpython/lib/tinyusb/lib/fatfs/ff.h new file mode 100644 index 0000000..5c2a611 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/fatfs/ff.h @@ -0,0 +1,342 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.09b (C)ChaN, 2013 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2013, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 82786 /* Revision ID */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ +#include "tusb_config.h" + +#if _FATFS != _FFCONF +#error Wrong configuration file (ffconf.h). +#endif + + + +/* Definitions of volume management */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ +typedef struct { + BYTE pd; /* Physical drive number */ + BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ +} PARTITION; +extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ +#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */ +#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ + +#else /* Single partition configuration */ +#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */ +#define LD2PT(vol) 0 /* Always mounts the 1st partition or in SFD */ + +#endif + + + +/* Type of path name strings on FatFs API */ + +#if _LFN_UNICODE /* Unicode string */ +#if !_USE_LFN +#error _LFN_UNICODE must be 0 in non-LFN cfg. +#endif +#ifndef _INC_TCHAR +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#endif + +#else /* ANSI/OEM string */ +#ifndef _INC_TCHAR +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif + +#endif + + + +/* File system object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /* FAT sub-type (0:Not mounted) */ + BYTE drv; /* Physical drive number */ + BYTE csize; /* Sectors per cluster (1,2,4...128) */ + BYTE n_fats; /* Number of FAT copies (1,2) */ + BYTE wflag; /* win[] dirty flag (1:must be written back) */ + BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ +#if _MAX_SS != 512 + WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* Last allocated cluster */ + DWORD free_clust; /* Number of free clusters */ + DWORD fsi_sector; /* fsinfo sector (FAT32) */ +#endif +#if _FS_RPATH + DWORD cdir; /* Current directory start cluster (0:root) */ +#endif + DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */ + DWORD fsize; /* Sectors per FAT */ + DWORD volbase; /* Volume start sector */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ + DWORD database; /* Data start sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */ +} FATFS; + + + +/* File object structure (FIL) */ + +typedef struct { + FATFS* fs; /* Pointer to the related file system object (**do not change order**) */ + WORD id; /* Owner file system mount ID (**do not change order**) */ + BYTE flag; /* File status flags */ + BYTE pad1; + DWORD fptr; /* File read/write pointer (0ed on file open) */ + DWORD fsize; /* File size */ + DWORD sclust; /* File data start cluster (0:no data cluster, always 0 when fsize is 0) */ + DWORD clust; /* Current cluster of fpter */ + DWORD dsect; /* Current data sector of fpter */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector containing the directory entry */ + BYTE* dir_ptr; /* Pointer to the directory entry in the window */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */ +#endif +#if _FS_LOCK + UINT lockid; /* File lock ID (index of file semaphore table Files[]) */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /* File data read/write buffer */ +#endif +} FIL; + + + +/* Directory object structure (DIR) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */ + WORD id; /* Owner file system mount ID (**do not change order**) */ + WORD index; /* Current read/write index number */ + DWORD sclust; /* Table start cluster (0:Root dir) */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the current SFN entry in the win[] */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _USE_LFN + WCHAR* lfn; /* Pointer to the LFN working buffer */ + WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File status structure (FILINFO) */ + +typedef struct { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + TCHAR fname[13]; /* Short file name (8.3 format) */ +#if _USE_LFN + TCHAR* lfname; /* Pointer to the LFN buffer */ + UINT lfsize; /* Size of LFN buffer in TCHAR */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* (0) Succeeded */ + FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ + FR_INT_ERR, /* (2) Assertion failed */ + FR_NOT_READY, /* (3) The physical drive cannot work */ + FR_NO_FILE, /* (4) Could not find the file */ + FR_NO_PATH, /* (5) Could not find the path */ + FR_INVALID_NAME, /* (6) The path name format is invalid */ + FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Access denied due to prohibited access */ + FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /* (12) The volume has no work area */ + FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ + FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ + FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ + FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */ + FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_mount (BYTE vol, FATFS* fs); /* Mount/Unmount a logical drive */ +FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ +FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */ +FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */ +FRESULT f_close (FIL* fp); /* Close an open file object */ +FRESULT f_opendir (DIR* dj, const TCHAR* path); /* Open an existing directory */ +FRESULT f_readdir (DIR* dj, FILINFO* fno); /* Read a directory item */ +FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ +FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */ +FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ +FRESULT f_truncate (FIL* fp); /* Truncate file */ +FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */ +FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ +FRESULT f_mkdir (const TCHAR* path); /* Create a new directory */ +FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */ +FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */ +FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ +FRESULT f_chdrive (BYTE drv); /* Change current drive */ +BYTE f_get_current_drive(void); +FRESULT f_chdir (const TCHAR* path); /* Change current directory */ +FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ +FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* sn); /* Get volume label */ +FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ +FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ +FRESULT f_mkfs (BYTE vol, BYTE sfd, UINT au); /* Create a file system on the drive */ +FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */ +int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ +int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ +int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ +TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ + +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) +#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) +#define f_tell(fp) ((fp)->fptr) +#define f_size(fp) ((fp)->fsize) + +#ifndef EOF +#define EOF (-1) +#endif + + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !_FS_READONLY +DWORD get_fattime (void); +#endif + +/* Unicode support functions */ +#if _USE_LFN /* Unicode - OEM code conversion */ +WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */ +WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */ +#if _USE_LFN == 3 /* Memory functions */ +void* ff_memalloc (UINT msize); /* Allocate memory block */ +void ff_memfree (void* mblock); /* Free memory block */ +#endif +#endif + +/* Sync functions */ +#if _FS_REENTRANT +int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */ +int ff_req_grant (_SYNC_t sobj); /* Lock sync object */ +void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */ +int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 +#define FA__ERROR 0x80 + +#if !_FS_READONLY +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* Fast seek feature */ +#define CREATE_LINKMAP 0xFFFFFFFF + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _FATFS */ diff --git a/circuitpython/lib/tinyusb/lib/fatfs/ffconf.h b/circuitpython/lib/tinyusb/lib/fatfs/ffconf.h new file mode 100644 index 0000000..782057e --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/fatfs/ffconf.h @@ -0,0 +1,193 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.09b (C)ChaN, 2013 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONF +#define _FFCONF 82786 /* Revision ID */ + +#include "tusb_config.h" + +/*---------------------------------------------------------------------------/ +/ Functions and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 0 /* 0 to 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to 1. +/ 3: f_lseek is removed in addition to 2. */ + + +#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ +/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ + + +#define _USE_LABEL 1 /* 0:Disable or 1:Enable */ +/* To enable volume label functions, set _USE_LAVEL to 1 */ + + +#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 437 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 1 /* 0 to 3 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN, +/ Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. When enable to use heap, memory control functions +/ ff_memalloc() and ff_memfree() must be added to the project. */ + + +#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. */ + + +#define _FS_RPATH 2 /* 0 to 2 */ +/* The _FS_RPATH option configures relative path feature. +/ +/ 0: Disable relative path feature and remove related functions. +/ 1: Enable relative path. f_chdrive() and f_chdir() are available. +/ 2: f_getcwd() is available in addition to 1. +/ +/ Note that output of the f_readdir fnction is affected by this option. */ + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _VOLUMES CFG_TUH_DEVICE_MAX +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for on-board flash memory, floppy disk and optical disk. +/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size +/ and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Enable multiple partition */ +/* When set to 0, each volume is bound to the same physical drive number and +/ it can mount only first primaly partition. When it is set to 1, each volume +/ is tied to the partitions listed in VolToPart[]. */ + + +#define _USE_ERASE 0 /* 0:Disable or 1:Enable */ +/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command +/ should be added to the disk_ioctl functio. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 0 /* 0 or 1 */ +/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS +/ option defines which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned word +/ access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. +*/ + + +/* A header file that defines sync object types on the O/S, such as +/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */ + +#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ + +/* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */ +/* To enable file lock control feature, set _FS_LOCK to 1 or greater. + The value defines how many files can be opened simultaneously. */ + + +#endif /* _FFCONFIG */ diff --git a/circuitpython/lib/tinyusb/lib/fatfs/integer.h b/circuitpython/lib/tinyusb/lib/fatfs/integer.h new file mode 100644 index 0000000..f34f56d --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/fatfs/integer.h @@ -0,0 +1,36 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER +#define _INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include + +#else /* Embedded platform */ + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/lib/networking/dhserver.c b/circuitpython/lib/tinyusb/lib/networking/dhserver.c new file mode 100644 index 0000000..5907392 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/networking/dhserver.c @@ -0,0 +1,348 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * 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 "dhserver.h" + +/* DHCP message type */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +/* DHCP options */ +enum DHCP_OPTIONS +{ + DHCP_PAD = 0, + DHCP_SUBNETMASK = 1, + DHCP_ROUTER = 3, + DHCP_DNSSERVER = 6, + DHCP_HOSTNAME = 12, + DHCP_DNSDOMAIN = 15, + DHCP_MTU = 26, + DHCP_BROADCAST = 28, + DHCP_PERFORMROUTERDISC = 31, + DHCP_STATICROUTE = 33, + DHCP_NISDOMAIN = 40, + DHCP_NISSERVER = 41, + DHCP_NTPSERVER = 42, + DHCP_VENDOR = 43, + DHCP_IPADDRESS = 50, + DHCP_LEASETIME = 51, + DHCP_OPTIONSOVERLOADED = 52, + DHCP_MESSAGETYPE = 53, + DHCP_SERVERID = 54, + DHCP_PARAMETERREQUESTLIST = 55, + DHCP_MESSAGE = 56, + DHCP_MAXMESSAGESIZE = 57, + DHCP_RENEWALTIME = 58, + DHCP_REBINDTIME = 59, + DHCP_CLASSID = 60, + DHCP_CLIENTID = 61, + DHCP_USERCLASS = 77, /* RFC 3004 */ + DHCP_FQDN = 81, + DHCP_DNSSEARCH = 119, /* RFC 3397 */ + DHCP_CSR = 121, /* RFC 3442 */ + DHCP_MSCSR = 249, /* MS code for RFC 3442 */ + DHCP_END = 255 +}; + +typedef struct +{ + uint8_t dp_op; /* packet opcode type */ + uint8_t dp_htype; /* hardware addr type */ + uint8_t dp_hlen; /* hardware addr length */ + uint8_t dp_hops; /* gateway hops */ + uint32_t dp_xid; /* transaction ID */ + uint16_t dp_secs; /* seconds since boot began */ + uint16_t dp_flags; + uint8_t dp_ciaddr[4]; /* client IP address */ + uint8_t dp_yiaddr[4]; /* 'your' IP address */ + uint8_t dp_siaddr[4]; /* server IP address */ + uint8_t dp_giaddr[4]; /* gateway IP address */ + uint8_t dp_chaddr[16]; /* client hardware address */ + uint8_t dp_legacy[192]; + uint8_t dp_magic[4]; + uint8_t dp_options[275]; /* options area */ +} DHCP_TYPE; + +DHCP_TYPE dhcp_data; +static struct udp_pcb *pcb = NULL; +static const dhcp_config_t *config = NULL; + +char magic_cookie[] = {0x63,0x82,0x53,0x63}; + +static ip4_addr_t get_ip(const uint8_t *pnt) +{ + ip4_addr_t result; + memcpy(&result, pnt, sizeof(result)); + return result; +} + +static void set_ip(uint8_t *pnt, ip4_addr_t value) +{ + memcpy(pnt, &value.addr, sizeof(value.addr)); +} + +static dhcp_entry_t *entry_by_ip(ip4_addr_t ip) +{ + int i; + for (i = 0; i < config->num_entry; i++) + if (config->entries[i].addr.addr == ip.addr) + return &config->entries[i]; + return NULL; +} + +static dhcp_entry_t *entry_by_mac(uint8_t *mac) +{ + int i; + for (i = 0; i < config->num_entry; i++) + if (memcmp(config->entries[i].mac, mac, 6) == 0) + return &config->entries[i]; + return NULL; +} + +static __inline bool is_vacant(dhcp_entry_t *entry) +{ + return memcmp("\0\0\0\0\0", entry->mac, 6) == 0; +} + +static dhcp_entry_t *vacant_address(void) +{ + int i; + for (i = 0; i < config->num_entry; i++) + if (is_vacant(config->entries + i)) + return config->entries + i; + return NULL; +} + +static __inline void free_entry(dhcp_entry_t *entry) +{ + memset(entry->mac, 0, 6); +} + +uint8_t *find_dhcp_option(uint8_t *attrs, int size, uint8_t attr) +{ + int i = 0; + while ((i + 1) < size) + { + int next = i + attrs[i + 1] + 2; + if (next > size) return NULL; + if (attrs[i] == attr) + return attrs + i; + i = next; + } + return NULL; +} + +int fill_options(void *dest, + uint8_t msg_type, + const char *domain, + ip4_addr_t dns, + int lease_time, + ip4_addr_t serverid, + ip4_addr_t router, + ip4_addr_t subnet) +{ + uint8_t *ptr = (uint8_t *)dest; + /* ACK message type */ + *ptr++ = 53; + *ptr++ = 1; + *ptr++ = msg_type; + + /* dhcp server identifier */ + *ptr++ = DHCP_SERVERID; + *ptr++ = 4; + set_ip(ptr, serverid); + ptr += 4; + + /* lease time */ + *ptr++ = DHCP_LEASETIME; + *ptr++ = 4; + *ptr++ = (lease_time >> 24) & 0xFF; + *ptr++ = (lease_time >> 16) & 0xFF; + *ptr++ = (lease_time >> 8) & 0xFF; + *ptr++ = (lease_time >> 0) & 0xFF; + + /* subnet mask */ + *ptr++ = DHCP_SUBNETMASK; + *ptr++ = 4; + set_ip(ptr, subnet); + ptr += 4; + + /* router */ + if (router.addr != 0) + { + *ptr++ = DHCP_ROUTER; + *ptr++ = 4; + set_ip(ptr, router); + ptr += 4; + } + + /* domain name */ + if (domain != NULL) + { + int len = strlen(domain); + *ptr++ = DHCP_DNSDOMAIN; + *ptr++ = len; + memcpy(ptr, domain, len); + ptr += len; + } + + /* domain name server (DNS) */ + if (dns.addr != 0) + { + *ptr++ = DHCP_DNSSERVER; + *ptr++ = 4; + set_ip(ptr, dns); + ptr += 4; + } + + /* end */ + *ptr++ = DHCP_END; + return ptr - (uint8_t *)dest; +} + +static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + uint8_t *ptr; + dhcp_entry_t *entry; + struct pbuf *pp; + struct netif *netif = netif_get_by_index(p->if_idx); + + (void)arg; + (void)addr; + + unsigned n = p->len; + if (n > sizeof(dhcp_data)) n = sizeof(dhcp_data); + memcpy(&dhcp_data, p->payload, n); + switch (dhcp_data.dp_options[2]) + { + case DHCP_DISCOVER: + entry = entry_by_mac(dhcp_data.dp_chaddr); + if (entry == NULL) entry = vacant_address(); + if (entry == NULL) break; + + dhcp_data.dp_op = 2; /* reply */ + dhcp_data.dp_secs = 0; + dhcp_data.dp_flags = 0; + set_ip(dhcp_data.dp_yiaddr, entry->addr); + memcpy(dhcp_data.dp_magic, magic_cookie, 4); + + memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); + + fill_options(dhcp_data.dp_options, + DHCP_OFFER, + config->domain, + config->dns, + entry->lease, + *netif_ip4_addr(netif), + config->router, + *netif_ip4_netmask(netif)); + + pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); + if (pp == NULL) break; + memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + pbuf_free(pp); + break; + + case DHCP_REQUEST: + /* 1. find requested ipaddr in option list */ + ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_IPADDRESS); + if (ptr == NULL) break; + if (ptr[1] != 4) break; + ptr += 2; + + /* 2. does hw-address registered? */ + entry = entry_by_mac(dhcp_data.dp_chaddr); + if (entry != NULL) free_entry(entry); + + /* 3. find requested ipaddr */ + entry = entry_by_ip(get_ip(ptr)); + if (entry == NULL) break; + if (!is_vacant(entry)) break; + + /* 4. fill struct fields */ + memcpy(dhcp_data.dp_yiaddr, ptr, 4); + dhcp_data.dp_op = 2; /* reply */ + dhcp_data.dp_secs = 0; + dhcp_data.dp_flags = 0; + memcpy(dhcp_data.dp_magic, magic_cookie, 4); + + /* 5. fill options */ + memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); + + fill_options(dhcp_data.dp_options, + DHCP_ACK, + config->domain, + config->dns, + entry->lease, + *netif_ip4_addr(netif), + config->router, + *netif_ip4_netmask(netif)); + + /* 6. send ACK */ + pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); + if (pp == NULL) break; + memcpy(entry->mac, dhcp_data.dp_chaddr, 6); + memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + pbuf_free(pp); + break; + + default: + break; + } + pbuf_free(p); +} + +err_t dhserv_init(const dhcp_config_t *c) +{ + err_t err; + udp_init(); + dhserv_free(); + pcb = udp_new(); + if (pcb == NULL) + return ERR_MEM; + err = udp_bind(pcb, IP_ADDR_ANY, c->port); + if (err != ERR_OK) + { + dhserv_free(); + return err; + } + udp_recv(pcb, udp_recv_proc, NULL); + config = c; + return ERR_OK; +} + +void dhserv_free(void) +{ + if (pcb == NULL) return; + udp_remove(pcb); + pcb = NULL; +} diff --git a/circuitpython/lib/tinyusb/lib/networking/dhserver.h b/circuitpython/lib/tinyusb/lib/networking/dhserver.h new file mode 100644 index 0000000..2a0b158 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/networking/dhserver.h @@ -0,0 +1,62 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * 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. + */ + +/* + * version: 1.0 demo (7.02.2015) + * brief: tiny dhcp ipv4 server using lwip (pcb) + * ref: https://lists.gnu.org/archive/html/lwip-users/2012-12/msg00016.html + */ + +#ifndef DHSERVER_H +#define DHSERVER_H + +#include +#include +#include +#include +#include "lwip/err.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +typedef struct dhcp_entry +{ + uint8_t mac[6]; + ip4_addr_t addr; + uint32_t lease; +} dhcp_entry_t; + +typedef struct dhcp_config +{ + ip4_addr_t router; + uint16_t port; + ip4_addr_t dns; + const char *domain; + int num_entry; + dhcp_entry_t *entries; +} dhcp_config_t; + +err_t dhserv_init(const dhcp_config_t *config); +void dhserv_free(void); + +#endif /* DHSERVER_H */ diff --git a/circuitpython/lib/tinyusb/lib/networking/dnserver.c b/circuitpython/lib/tinyusb/lib/networking/dnserver.c new file mode 100644 index 0000000..e4e7c34 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/networking/dnserver.c @@ -0,0 +1,200 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * 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. + */ + +/* + * version: 1.0 demo (7.02.2015) + * brief: tiny dns ipv4 server using lwip (pcb) + */ + +#include "dnserver.h" + +#define DNS_MAX_HOST_NAME_LEN 128 + +static struct udp_pcb *pcb = NULL; +dns_query_proc_t query_proc = NULL; + +#pragma pack(push, 1) +typedef struct +{ +#if BYTE_ORDER == LITTLE_ENDIAN + uint8_t rd: 1, /* Recursion Desired */ + tc: 1, /* Truncation Flag */ + aa: 1, /* Authoritative Answer Flag */ + opcode: 4, /* Operation code */ + qr: 1; /* Query/Response Flag */ + uint8_t rcode: 4, /* Response Code */ + z: 3, /* Zero */ + ra: 1; /* Recursion Available */ +#else + uint8_t qr: 1, /* Query/Response Flag */ + opcode: 4, /* Operation code */ + aa: 1, /* Authoritative Answer Flag */ + tc: 1, /* Truncation Flag */ + rd: 1; /* Recursion Desired */ + uint8_t ra: 1, /* Recursion Available */ + z: 3, /* Zero */ + rcode: 4; /* Response Code */ +#endif +} dns_header_flags_t; + +typedef struct +{ + uint16_t id; + dns_header_flags_t flags; + uint16_t n_record[4]; +} dns_header_t; + +typedef struct dns_answer +{ + uint16_t name; + uint16_t type; + uint16_t Class; + uint32_t ttl; + uint16_t len; + uint32_t addr; +} dns_answer_t; +#pragma pack(pop) + +typedef struct dns_query +{ + char name[DNS_MAX_HOST_NAME_LEN]; + uint16_t type; + uint16_t Class; +} dns_query_t; + +static uint16_t get_uint16(const uint8_t *pnt) +{ + uint16_t result; + memcpy(&result, pnt, sizeof(result)); + return result; +} + +static int parse_next_query(void *data, int size, dns_query_t *query) +{ + int len; + int lables; + uint8_t *ptr; + + len = 0; + lables = 0; + ptr = (uint8_t *)data; + + while (true) + { + uint8_t lable_len; + if (size <= 0) return -1; + lable_len = *ptr++; + size--; + if (lable_len == 0) break; + if (lables > 0) + { + if (len == DNS_MAX_HOST_NAME_LEN) return -2; + query->name[len++] = '.'; + } + if (lable_len > size) return -1; + if (len + lable_len >= DNS_MAX_HOST_NAME_LEN) return -2; + memcpy(&query->name[len], ptr, lable_len); + len += lable_len; + ptr += lable_len; + size -= lable_len; + lables++; + } + + if (size < 4) return -1; + query->name[len] = 0; + query->type = get_uint16(ptr); + ptr += 2; + query->Class = get_uint16(ptr); + ptr += 2; + return ptr - (uint8_t *)data; +} + +static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + int len; + dns_header_t *header; + static dns_query_t query; + struct pbuf *out; + ip4_addr_t host_addr; + dns_answer_t *answer; + + (void)arg; + + if (p->len <= sizeof(dns_header_t)) goto error; + header = (dns_header_t *)p->payload; + if (header->flags.qr != 0) goto error; + if (ntohs(header->n_record[0]) != 1) goto error; + + len = parse_next_query(header + 1, p->len - sizeof(dns_header_t), &query); + if (len < 0) goto error; + if (!query_proc(query.name, &host_addr)) goto error; + + len += sizeof(dns_header_t); + out = pbuf_alloc(PBUF_TRANSPORT, len + 16, PBUF_POOL); + if (out == NULL) goto error; + + memcpy(out->payload, p->payload, len); + header = (dns_header_t *)out->payload; + header->flags.qr = 1; + header->n_record[1] = htons(1); + answer = (struct dns_answer *)((uint8_t *)out->payload + len); + answer->name = htons(0xC00C); + answer->type = htons(1); + answer->Class = htons(1); + answer->ttl = htonl(32); + answer->len = htons(4); + answer->addr = host_addr.addr; + + udp_sendto(upcb, out, addr, port); + pbuf_free(out); + +error: + pbuf_free(p); +} + +err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t qp) +{ + err_t err; + udp_init(); + dnserv_free(); + pcb = udp_new(); + if (pcb == NULL) + return ERR_MEM; + err = udp_bind(pcb, bind, port); + if (err != ERR_OK) + { + dnserv_free(); + return err; + } + udp_recv(pcb, udp_recv_proc, NULL); + query_proc = qp; + return ERR_OK; +} + +void dnserv_free() +{ + if (pcb == NULL) return; + udp_remove(pcb); + pcb = NULL; +} diff --git a/circuitpython/lib/tinyusb/lib/networking/dnserver.h b/circuitpython/lib/tinyusb/lib/networking/dnserver.h new file mode 100644 index 0000000..a062e3a --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/networking/dnserver.h @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * 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. + */ + +/* + * version: 1.0 demo (7.02.2015) + * brief: tiny dns ipv4 server using lwip (pcb) + */ + +#ifndef DNSERVER +#define DNSERVER + +#include +#include +#include +#include +#include "lwip/def.h" +#include "lwip/err.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +typedef bool (*dns_query_proc_t)(const char *name, ip4_addr_t *addr); + +err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t query_proc); +void dnserv_free(void); + +#endif diff --git a/circuitpython/lib/tinyusb/lib/networking/ndis.h b/circuitpython/lib/tinyusb/lib/networking/ndis.h new file mode 100644 index 0000000..1c73757 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/networking/ndis.h @@ -0,0 +1,266 @@ +/* This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ndis.h *************************************************************** + * + * \brief + * This file contains the possible external configuration of the USB. + * + * \addtogroup usbstick + * + * + ******************************************************************************/ + +/** + \ingroup usbstick + \defgroup RNDIS RNDIS Support + @{ + */ + +/* + * ndis.h + * + * Modified by Colin O'Flynn + * ntddndis.h modified by Benedikt Spranger + * + * Thanks to the cygwin development team, + * espacially to Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _LINUX_NDIS_H +#define _LINUX_NDIS_H + + +#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 +#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A +#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B + +/* from drivers/net/sk98lin/h/skgepnmi.h */ +#define OID_PNP_CAPABILITIES 0xFD010100 +#define OID_PNP_SET_POWER 0xFD010101 +#define OID_PNP_QUERY_POWER 0xFD010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 + +enum NDIS_DEVICE_POWER_STATE { + NdisDeviceStateUnspecified = 0, + NdisDeviceStateD0, + NdisDeviceStateD1, + NdisDeviceStateD2, + NdisDeviceStateD3, + NdisDeviceStateMaximum +}; + +struct NDIS_PM_WAKE_UP_CAPABILITIES { + enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; + enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; + enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; +}; + +/* NDIS_PNP_CAPABILITIES.Flags constants */ +#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 +#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 +#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 + +/* +struct NDIS_PNP_CAPABILITIES { + __le32 Flags; + struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; +}; + +struct NDIS_PM_PACKET_PATTERN { + __le32 Priority; + __le32 Reserved; + __le32 MaskSize; + __le32 PatternOffset; + __le32 PatternSize; + __le32 PatternFlags; +}; +*/ + +/* Required Object IDs (OIDs) */ +#define OID_GEN_SUPPORTED_LIST 0x00010101 +#define OID_GEN_HARDWARE_STATUS 0x00010102 +#define OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_MEDIA_IN_USE 0x00010104 +#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define OID_GEN_LINK_SPEED 0x00010107 +#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B +#define OID_GEN_VENDOR_ID 0x0001010C +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +#define OID_GEN_DRIVER_VERSION 0x00010110 +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define OID_GEN_MAC_OPTIONS 0x00010113 +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 +#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 +#define OID_GEN_SUPPORTED_GUIDS 0x00010117 +#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 +#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 +#define OID_GEN_MACHINE_NAME 0x0001021A +#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B +#define OID_GEN_VLAN_ID 0x0001021C + +/* Optional OIDs */ +#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 +#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 + +/* Required statistics OIDs */ +#define OID_GEN_XMIT_OK 0x00020101 +#define OID_GEN_RCV_OK 0x00020102 +#define OID_GEN_XMIT_ERROR 0x00020103 +#define OID_GEN_RCV_ERROR 0x00020104 +#define OID_GEN_RCV_NO_BUFFER 0x00020105 + +/* Optional statistics OIDs */ +#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 +#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 +#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 +#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 +#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B +#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C +#define OID_GEN_RCV_CRC_ERROR 0x0002020D +#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E +#define OID_GEN_GET_TIME_CAPS 0x0002020F +#define OID_GEN_GET_NETCARD_TIME 0x00020210 +#define OID_GEN_NETCARD_LOAD 0x00020211 +#define OID_GEN_DEVICE_PROFILE 0x00020212 +#define OID_GEN_INIT_TIME_MS 0x00020213 +#define OID_GEN_RESET_COUNTS 0x00020214 +#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 +#define OID_GEN_FRIENDLY_NAME 0x00020216 +#define OID_GEN_MINIPORT_INFO 0x00020217 +#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 + +/* IEEE 802.3 (Ethernet) OIDs */ +#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 + +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +#define OID_802_3_MULTICAST_LIST 0x01010103 +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define OID_802_3_MAC_OPTIONS 0x01010105 +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 +#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 + +/* Wireless LAN OIDs */ +/* Mandatory */ +#define OID_802_11_BSSID 0x0D010101 /* Q S */ +#define OID_802_11_SSID 0x0D010102 /* Q S */ +#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 /* Q S */ +#define OID_802_11_RSSI 0x0D010206 /* Q I */ +#define OID_802_11_BSSID_LIST 0x0D010217 /* Q */ +#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A /* S */ +#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 /* Q S */ +#define OID_802_11_SUPPORTED_RATES 0x0D01020E /* Q */ +#define OID_802_11_CONFIGURATION 0x0D010211 /* Q S */ +#define OID_802_11_ADD_WEP 0x0D010113 /* S */ +#define OID_802_11_WEP_STATUS 0x0D01011B /* Q S */ +#define OID_802_11_REMOVE_WEP 0x0D010114 /* S */ +#define OID_802_11_DISASSOCIATE 0x0D010115 /* S */ +#define OID_802_11_AUTHENTICATION_MODE 0x0D010118 /* Q S */ +#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C /* S */ + + + +/* OID_GEN_MINIPORT_INFO constants */ +#define NDIS_MINIPORT_BUS_MASTER 0x00000001 +#define NDIS_MINIPORT_WDM_DRIVER 0x00000002 +#define NDIS_MINIPORT_SG_LIST 0x00000004 +#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 +#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010 +#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 +#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 +#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 +#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 +#define NDIS_MINIPORT_IS_NDIS_5 0x00000200 +#define NDIS_MINIPORT_IS_CO 0x00000400 +#define NDIS_MINIPORT_DESERIALIZE 0x00000800 +#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 +#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 +#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000 +#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000 +#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 +#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 +#define NDIS_MINIPORT_HIDDEN 0x00040000 +#define NDIS_MINIPORT_SWENUM 0x00080000 +#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 +#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 +#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 +#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 +#define NDIS_MINIPORT_64BITS_DMA 0x01000000 + +#define NDIS_MEDIUM_802_3 0x00000000 +#define NDIS_MEDIUM_802_5 0x00000001 +#define NDIS_MEDIUM_FDDI 0x00000002 +#define NDIS_MEDIUM_WAN 0x00000003 +#define NDIS_MEDIUM_LOCAL_TALK 0x00000004 +#define NDIS_MEDIUM_DIX 0x00000005 +#define NDIS_MEDIUM_ARCENT_RAW 0x00000006 +#define NDIS_MEDIUM_ARCENT_878_2 0x00000007 +#define NDIS_MEDIUM_ATM 0x00000008 +#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009 +#define NDIS_MEDIUM_IRDA 0x0000000A +#define NDIS_MEDIUM_BPC 0x0000000B +#define NDIS_MEDIUM_CO_WAN 0x0000000C +#define NDIS_MEDIUM_1394 0x0000000D + +#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 +#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 +#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 +#define NDIS_PACKET_TYPE_SMT 0x00000040 +#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 +#define NDIS_PACKET_TYPE_GROUP 0x00000100 +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 +#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 + +#define NDIS_MEDIA_STATE_CONNECTED 0x00000000 +#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001 + +#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 +#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 +#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 +#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 +#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 +#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 +#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 +#define NDIS_MAC_OPTION_RESERVED 0x80000000 + +#endif /* _LINUX_NDIS_H */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/lib/networking/rndis_protocol.h b/circuitpython/lib/tinyusb/lib/networking/rndis_protocol.h new file mode 100644 index 0000000..b45860e --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/networking/rndis_protocol.h @@ -0,0 +1,307 @@ +/** + * \file rndis_protocol.h + * RNDIS Defines + * + * \author + * Colin O'Flynn + * + * \addtogroup usbstick + */ + +/* Copyright (c) 2008 Colin O'Flynn + + 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 copyright holders nor the names of + 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 _RNDIS_H +#define _RNDIS_H + +/** + \addtogroup RNDIS + @{ + */ + +#include + +#define RNDIS_MAJOR_VERSION 1 +#define RNDIS_MINOR_VERSION 0 + +#define RNDIS_STATUS_SUCCESS 0X00000000 +#define RNDIS_STATUS_FAILURE 0XC0000001 +#define RNDIS_STATUS_INVALID_DATA 0XC0010015 +#define RNDIS_STATUS_NOT_SUPPORTED 0XC00000BB +#define RNDIS_STATUS_MEDIA_CONNECT 0X4001000B +#define RNDIS_STATUS_MEDIA_DISCONNECT 0X4001000C + + +/* Message set for Connectionless (802.3) Devices */ +#define REMOTE_NDIS_PACKET_MSG 0x00000001 +#define REMOTE_NDIS_INITIALIZE_MSG 0X00000002 +#define REMOTE_NDIS_HALT_MSG 0X00000003 +#define REMOTE_NDIS_QUERY_MSG 0X00000004 +#define REMOTE_NDIS_SET_MSG 0X00000005 +#define REMOTE_NDIS_RESET_MSG 0X00000006 +#define REMOTE_NDIS_INDICATE_STATUS_MSG 0X00000007 +#define REMOTE_NDIS_KEEPALIVE_MSG 0X00000008 +#define REMOTE_NDIS_INITIALIZE_CMPLT 0X80000002 +#define REMOTE_NDIS_QUERY_CMPLT 0X80000004 +#define REMOTE_NDIS_SET_CMPLT 0X80000005 +#define REMOTE_NDIS_RESET_CMPLT 0X80000006 +#define REMOTE_NDIS_KEEPALIVE_CMPLT 0X80000008 + +typedef uint32_t rndis_MessageType_t; +typedef uint32_t rndis_MessageLength_t; +typedef uint32_t rndis_RequestId_t; +typedef uint32_t rndis_MajorVersion_t; +typedef uint32_t rndis_MinorVersion_t; +typedef uint32_t rndis_MaxTransferSize_t; +typedef uint32_t rndis_Status_t; + + +/* Device Flags */ +#define RNDIS_DF_CONNECTIONLESS 0x00000001 +#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 +typedef uint32_t rndis_DeviceFlags_t; + +/* Mediums */ +#define RNDIS_MEDIUM_802_3 0x00000000 +typedef uint32_t rndis_Medium_t; + + +typedef uint32_t rndis_MaxPacketsPerTransfer_t; +typedef uint32_t rndis_PacketAlignmentFactor_t; +typedef uint32_t rndis_AfListOffset_t; +typedef uint32_t rndis_AfListSize_t; + +/*** Remote NDIS Generic Message type ***/ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + } rndis_generic_msg_t; + + +/*** Remote NDIS Initialize Message ***/ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_MajorVersion_t MajorVersion; + rndis_MinorVersion_t MinorVersion; + rndis_MaxTransferSize_t MaxTransferSize; + } rndis_initialize_msg_t; + +/* Response: */ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Status_t Status; + rndis_MajorVersion_t MajorVersion; + rndis_MinorVersion_t MinorVersion; + rndis_DeviceFlags_t DeviceFlags; + rndis_Medium_t Medium; + rndis_MaxPacketsPerTransfer_t MaxPacketsPerTransfer; + rndis_MaxTransferSize_t MaxTransferSize; + rndis_PacketAlignmentFactor_t PacketAlignmentFactor; + rndis_AfListOffset_t AfListOffset; + rndis_AfListSize_t AfListSize; + } rndis_initialize_cmplt_t; + + +/*** Remote NDIS Halt Message ***/ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + } rndis_halt_msg_t; + +typedef uint32_t rndis_Oid_t; +typedef uint32_t rndis_InformationBufferLength_t; +typedef uint32_t rndis_InformationBufferOffset_t; +typedef uint32_t rndis_DeviceVcHandle_t; + +/*** Remote NDIS Query Message ***/ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Oid_t Oid; + rndis_InformationBufferLength_t InformationBufferLength; + rndis_InformationBufferOffset_t InformationBufferOffset; + rndis_DeviceVcHandle_t DeviceVcHandle; + } rndis_query_msg_t; + +/* Response: */ + +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Status_t Status; + rndis_InformationBufferLength_t InformationBufferLength; + rndis_InformationBufferOffset_t InformationBufferOffset; + } rndis_query_cmplt_t; + +/*** Remote NDIS Set Message ***/ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Oid_t Oid; + rndis_InformationBufferLength_t InformationBufferLength; + rndis_InformationBufferOffset_t InformationBufferOffset; + rndis_DeviceVcHandle_t DeviceVcHandle; + } rndis_set_msg_t; + +/* Response */ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Status_t Status; + }rndis_set_cmplt_t; + +/* Information buffer layout for OID_GEN_RNDIS_CONFIG_PARAMETER */ +typedef uint32_t rndis_ParameterNameOffset_t; +typedef uint32_t rndis_ParameterNameLength_t; +typedef uint32_t rndis_ParameterType_t; +typedef uint32_t rndis_ParameterValueOffset_t; +typedef uint32_t rndis_ParameterValueLength_t; + +#define PARAMETER_TYPE_STRING 2 +#define PARAMETER_TYPE_NUMERICAL 0 + +typedef struct{ + rndis_ParameterNameOffset_t ParameterNameOffset; + rndis_ParameterNameLength_t ParameterNameLength; + rndis_ParameterType_t ParameterType; + rndis_ParameterValueOffset_t ParameterValueOffset; + rndis_ParameterValueLength_t ParameterValueLength; + }rndis_config_parameter_t; + +typedef uint32_t rndis_Reserved_t; + +/*** Remote NDIS Soft Reset Message ***/ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_Reserved_t Reserved; + } rndis_reset_msg_t; + +typedef uint32_t rndis_AddressingReset_t; + +/* Response: */ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_Status_t Status; + rndis_AddressingReset_t AddressingReset; + } rndis_reset_cmplt_t; + +/*** Remote NDIS Indicate Status Message ***/ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_Status_t Status; + rndis_Status_t StatusBufferLength; + rndis_Status_t StatusBufferOffset; + } rndis_indicate_status_t; + +typedef uint32_t rndis_DiagStatus_t; +typedef uint32_t rndis_ErrorOffset_t; + +typedef struct { + rndis_DiagStatus_t DiagStatus; + rndis_ErrorOffset_t ErrorOffset; + }rndis_diagnostic_info_t; + +/*** Remote NDIS Keepalive Message */ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + }rndis_keepalive_msg_t; + +/* Response: */ +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Status_t Status; + }rndis_keepalive_cmplt_t; + +/*** Remote NDIS Data Packet ***/ + +typedef uint32_t rndis_DataOffset_t; +typedef uint32_t rndis_DataLength_t; +typedef uint32_t rndis_OOBDataOffset_t; +typedef uint32_t rndis_OOBDataLength_t; +typedef uint32_t rndis_NumOOBDataElements_t; +typedef uint32_t rndis_PerPacketInfoOffset_t; +typedef uint32_t rndis_PerPacketInfoLength_t; + +typedef struct{ + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_DataOffset_t DataOffset; + rndis_DataLength_t DataLength; + rndis_OOBDataOffset_t OOBDataOffset; + rndis_OOBDataLength_t OOBDataLength; + rndis_NumOOBDataElements_t NumOOBDataElements; + rndis_PerPacketInfoOffset_t PerPacketInfoOffset; + rndis_PerPacketInfoLength_t PerPacketInfoLength; + rndis_DeviceVcHandle_t DeviceVcHandle; + rndis_Reserved_t Reserved; + }rndis_data_packet_t; + +typedef uint32_t rndis_ClassInformationOffset_t; +typedef uint32_t rndis_Size_t; +typedef uint32_t rndis_Type_t; + +typedef struct{ + rndis_Size_t Size; + rndis_Type_t Type; + rndis_ClassInformationOffset_t ClassInformationType; + }rndis_OOB_packet_t; + +#include "ndis.h" + +typedef enum rnids_state_e { + rndis_uninitialized, + rndis_initialized, + rndis_data_initialized + } rndis_state_t; + +typedef struct { + uint32_t txok; + uint32_t rxok; + uint32_t txbad; + uint32_t rxbad; +} usb_eth_stat_t; + +#endif /* _RNDIS_H */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/lib/networking/rndis_reports.c b/circuitpython/lib/tinyusb/lib/networking/rndis_reports.c new file mode 100644 index 0000000..ee611c8 --- /dev/null +++ b/circuitpython/lib/tinyusb/lib/networking/rndis_reports.c @@ -0,0 +1,303 @@ +/* + The original version of this code was lrndis/usbd_rndis_core.c from https://github.com/fetisov/lrndis + It has since been overhauled to suit this application +*/ + +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * 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 +#include +#include "class/net/net_device.h" +#include "rndis_protocol.h" +#include "netif/ethernet.h" + +#define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */ +#define RNDIS_VENDOR "TinyUSB" /* NIC vendor name */ + +static const uint8_t *const station_hwaddr = tud_network_mac_address; +static const uint8_t *const permanent_hwaddr = tud_network_mac_address; + +static usb_eth_stat_t usb_eth_stat = { 0, 0, 0, 0 }; +static uint32_t oid_packet_filter = 0x0000000; +static rndis_state_t rndis_state; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t ndis_report[8] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + +static const uint32_t OIDSupportedList[] = +{ + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_CURRENT_PACKET_FILTER, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_PROTOCOL_OPTIONS, + OID_GEN_MAC_OPTIONS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAXIMUM_LIST_SIZE, + OID_802_3_MAC_OPTIONS +}; + +#define OID_LIST_LENGTH TU_ARRAY_SIZE(OIDSupportedList) +#define ENC_BUF_SIZE (OID_LIST_LENGTH * 4 + 32) + +static void *encapsulated_buffer; + +static void rndis_report(void) +{ + netd_report(ndis_report, sizeof(ndis_report)); +} + +static void rndis_query_cmplt32(int status, uint32_t data) +{ + rndis_query_cmplt_t *c; + c = (rndis_query_cmplt_t *)encapsulated_buffer; + c->MessageType = REMOTE_NDIS_QUERY_CMPLT; + c->MessageLength = sizeof(rndis_query_cmplt_t) + 4; + c->InformationBufferLength = 4; + c->InformationBufferOffset = 16; + c->Status = status; + memcpy(c + 1, &data, sizeof(data)); + rndis_report(); +} + +static void rndis_query_cmplt(int status, const void *data, int size) +{ + rndis_query_cmplt_t *c; + c = (rndis_query_cmplt_t *)encapsulated_buffer; + c->MessageType = REMOTE_NDIS_QUERY_CMPLT; + c->MessageLength = sizeof(rndis_query_cmplt_t) + size; + c->InformationBufferLength = size; + c->InformationBufferOffset = 16; + c->Status = status; + memcpy(c + 1, data, size); + rndis_report(); +} + +#define MAC_OPT NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \ + NDIS_MAC_OPTION_RECEIVE_SERIALIZED | \ + NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \ + NDIS_MAC_OPTION_NO_LOOPBACK + +static const char *rndis_vendor = RNDIS_VENDOR; + +static void rndis_query(void) +{ + switch (((rndis_query_msg_t *)encapsulated_buffer)->Oid) + { + case OID_GEN_SUPPORTED_LIST: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, OIDSupportedList, 4 * OID_LIST_LENGTH); return; + case OID_GEN_VENDOR_DRIVER_VERSION: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0x00001000); return; + case OID_802_3_CURRENT_ADDRESS: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, station_hwaddr, 6); return; + case OID_802_3_PERMANENT_ADDRESS: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, permanent_hwaddr, 6); return; + case OID_GEN_MEDIA_SUPPORTED: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return; + case OID_GEN_MEDIA_IN_USE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return; + case OID_GEN_PHYSICAL_MEDIUM: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return; + case OID_GEN_HARDWARE_STATUS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; + case OID_GEN_LINK_SPEED: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, RNDIS_LINK_SPEED / 100); return; + case OID_GEN_VENDOR_ID: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0x00FFFFFF); return; + case OID_GEN_VENDOR_DESCRIPTION: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, rndis_vendor, strlen(rndis_vendor) + 1); return; + case OID_GEN_CURRENT_PACKET_FILTER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, oid_packet_filter); return; + case OID_GEN_MAXIMUM_FRAME_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU - SIZEOF_ETH_HDR); return; + case OID_GEN_MAXIMUM_TOTAL_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return; + case OID_GEN_TRANSMIT_BLOCK_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return; + case OID_GEN_RECEIVE_BLOCK_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return; + case OID_GEN_MEDIA_CONNECT_STATUS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIA_STATE_CONNECTED); return; + case OID_GEN_RNDIS_CONFIG_PARAMETER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; + case OID_802_3_MAXIMUM_LIST_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 1); return; + case OID_802_3_MULTICAST_LIST: rndis_query_cmplt32(RNDIS_STATUS_NOT_SUPPORTED, 0); return; + case OID_802_3_MAC_OPTIONS: rndis_query_cmplt32(RNDIS_STATUS_NOT_SUPPORTED, 0); return; + case OID_GEN_MAC_OPTIONS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, /*MAC_OPT*/ 0); return; + case OID_802_3_RCV_ERROR_ALIGNMENT: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; + case OID_802_3_XMIT_ONE_COLLISION: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; + case OID_802_3_XMIT_MORE_COLLISIONS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; + case OID_GEN_XMIT_OK: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.txok); return; + case OID_GEN_RCV_OK: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.rxok); return; + case OID_GEN_RCV_ERROR: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.rxbad); return; + case OID_GEN_XMIT_ERROR: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.txbad); return; + case OID_GEN_RCV_NO_BUFFER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; + default: rndis_query_cmplt(RNDIS_STATUS_FAILURE, NULL, 0); return; + } +} + +#define INFBUF ((uint8_t *)&(m->RequestId) + m->InformationBufferOffset) + +static void rndis_handle_config_parm(const char *data, int keyoffset, int valoffset, int keylen, int vallen) +{ + (void)data; + (void)keyoffset; + (void)valoffset; + (void)keylen; + (void)vallen; +} + +static void rndis_packetFilter(uint32_t newfilter) +{ + (void)newfilter; +} + +static void rndis_handle_set_msg(void) +{ + rndis_set_cmplt_t *c; + rndis_set_msg_t *m; + rndis_Oid_t oid; + + c = (rndis_set_cmplt_t *)encapsulated_buffer; + m = (rndis_set_msg_t *)encapsulated_buffer; + + oid = m->Oid; + c->MessageType = REMOTE_NDIS_SET_CMPLT; + c->MessageLength = sizeof(rndis_set_cmplt_t); + c->Status = RNDIS_STATUS_SUCCESS; + + switch (oid) + { + /* Parameters set up in 'Advanced' tab */ + case OID_GEN_RNDIS_CONFIG_PARAMETER: + { + rndis_config_parameter_t *p; + char *ptr = (char *)m; + ptr += sizeof(rndis_generic_msg_t); + ptr += m->InformationBufferOffset; + p = (rndis_config_parameter_t *) ((void*) ptr); + rndis_handle_config_parm(ptr, p->ParameterNameOffset, p->ParameterValueOffset, p->ParameterNameLength, p->ParameterValueLength); + } + break; + + /* Mandatory general OIDs */ + case OID_GEN_CURRENT_PACKET_FILTER: + memcpy(&oid_packet_filter, INFBUF, 4); + if (oid_packet_filter) + { + rndis_packetFilter(oid_packet_filter); + rndis_state = rndis_data_initialized; + } + else + { + rndis_state = rndis_initialized; + } + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + break; + + case OID_GEN_PROTOCOL_OPTIONS: + break; + + /* Mandatory 802_3 OIDs */ + case OID_802_3_MULTICAST_LIST: + break; + + /* Power Managment: fails for now */ + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + case OID_PNP_ENABLE_WAKE_UP: + default: + c->Status = RNDIS_STATUS_FAILURE; + break; + } + + /* c->MessageID is same as before */ + rndis_report(); + return; +} + +void rndis_class_set_handler(uint8_t *data, int size) +{ + encapsulated_buffer = data; + (void)size; + + switch (((rndis_generic_msg_t *)encapsulated_buffer)->MessageType) + { + case REMOTE_NDIS_INITIALIZE_MSG: + { + rndis_initialize_cmplt_t *m; + m = ((rndis_initialize_cmplt_t *)encapsulated_buffer); + /* m->MessageID is same as before */ + m->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT; + m->MessageLength = sizeof(rndis_initialize_cmplt_t); + m->MajorVersion = RNDIS_MAJOR_VERSION; + m->MinorVersion = RNDIS_MINOR_VERSION; + m->Status = RNDIS_STATUS_SUCCESS; + m->DeviceFlags = RNDIS_DF_CONNECTIONLESS; + m->Medium = RNDIS_MEDIUM_802_3; + m->MaxPacketsPerTransfer = 1; + m->MaxTransferSize = CFG_TUD_NET_MTU + sizeof(rndis_data_packet_t); + m->PacketAlignmentFactor = 0; + m->AfListOffset = 0; + m->AfListSize = 0; + rndis_state = rndis_initialized; + rndis_report(); + } + break; + + case REMOTE_NDIS_QUERY_MSG: + rndis_query(); + break; + + case REMOTE_NDIS_SET_MSG: + rndis_handle_set_msg(); + break; + + case REMOTE_NDIS_RESET_MSG: + { + rndis_reset_cmplt_t * m; + m = ((rndis_reset_cmplt_t *)encapsulated_buffer); + rndis_state = rndis_uninitialized; + m->MessageType = REMOTE_NDIS_RESET_CMPLT; + m->MessageLength = sizeof(rndis_reset_cmplt_t); + m->Status = RNDIS_STATUS_SUCCESS; + m->AddressingReset = 1; /* Make it look like we did something */ + /* m->AddressingReset = 0; - Windows halts if set to 1 for some reason */ + rndis_report(); + } + break; + + case REMOTE_NDIS_KEEPALIVE_MSG: + { + rndis_keepalive_cmplt_t * m; + m = (rndis_keepalive_cmplt_t *)encapsulated_buffer; + m->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT; + m->MessageLength = sizeof(rndis_keepalive_cmplt_t); + m->Status = RNDIS_STATUS_SUCCESS; + } + /* We have data to send back */ + rndis_report(); + break; + + default: + break; + } +} diff --git a/circuitpython/lib/tinyusb/pkg.yml b/circuitpython/lib/tinyusb/pkg.yml new file mode 100644 index 0000000..3314450 --- /dev/null +++ b/circuitpython/lib/tinyusb/pkg.yml @@ -0,0 +1,14 @@ +pkg.name: tinyusb +pkg.description: A silly USB stack for embedded +pkg.author: "Ha Thach " +pkg.homepage: "https://github.com/hathach/tinyusb" +pkg.keywords: + - usb + +pkg.type: sdk + +pkg.deps: + - "@apache-mynewt-core/kernel/os" + +pkg.include_dirs: + - src diff --git a/circuitpython/lib/tinyusb/repository.yml b/circuitpython/lib/tinyusb/repository.yml new file mode 100644 index 0000000..aaec10e --- /dev/null +++ b/circuitpython/lib/tinyusb/repository.yml @@ -0,0 +1,17 @@ +repo.name: tinyusb +repo.versions: + "0.0.0": "master" + "0.5.0": "0.5.0" + "0.6.0": "0.6.0" + "0.7.0": "0.7.0" + "0.8.0": "0.8.0" + "0.9.0": "0.9.0" + "0.10.0": "0.10.0" + "0.10.1": "0.10.1" + "0.11.0": "0.11.0" + "0.12.0": "0.12.0" + "0.13.0": "0.13.0" + + "0-dev": "0.0.0" # master + "0-latest": "0.13.0" # latest stable release + diff --git a/circuitpython/lib/tinyusb/src/class/audio/audio.h b/circuitpython/lib/tinyusb/src/class/audio/audio.h new file mode 100644 index 0000000..6f9c1a6 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/audio/audio.h @@ -0,0 +1,933 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2020 Reinhard Panhuber + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup group_class + * \defgroup ClassDriver_Audio Audio + * Currently only MIDI subclass is supported + * @{ */ + +#ifndef _TUSB_AUDIO_H__ +#define _TUSB_AUDIO_H__ + +#include "common/tusb_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// Audio Device Class Codes + +/// A.2 - Audio Function Subclass Codes +typedef enum +{ + AUDIO_FUNCTION_SUBCLASS_UNDEFINED = 0x00, +} audio_function_subclass_type_t; + +/// A.3 - Audio Function Protocol Codes +typedef enum +{ + AUDIO_FUNC_PROTOCOL_CODE_UNDEF = 0x00, + AUDIO_FUNC_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0 +} audio_function_protocol_code_t; + +/// A.5 - Audio Interface Subclass Codes +typedef enum +{ + AUDIO_SUBCLASS_UNDEFINED = 0x00, + AUDIO_SUBCLASS_CONTROL , ///< Audio Control + AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming + AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming +} audio_subclass_type_t; + +/// A.6 - Audio Interface Protocol Codes +typedef enum +{ + AUDIO_INT_PROTOCOL_CODE_UNDEF = 0x00, + AUDIO_INT_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0 +} audio_interface_protocol_code_t; + +/// A.7 - Audio Function Category Codes +typedef enum +{ + AUDIO_FUNC_UNDEF = 0x00, + AUDIO_FUNC_DESKTOP_SPEAKER = 0x01, + AUDIO_FUNC_HOME_THEATER = 0x02, + AUDIO_FUNC_MICROPHONE = 0x03, + AUDIO_FUNC_HEADSET = 0x04, + AUDIO_FUNC_TELEPHONE = 0x05, + AUDIO_FUNC_CONVERTER = 0x06, + AUDIO_FUNC_SOUND_RECODER = 0x07, + AUDIO_FUNC_IO_BOX = 0x08, + AUDIO_FUNC_MUSICAL_INSTRUMENT = 0x09, + AUDIO_FUNC_PRO_AUDIO = 0x0A, + AUDIO_FUNC_AUDIO_VIDEO = 0x0B, + AUDIO_FUNC_CONTROL_PANEL = 0x0C, + AUDIO_FUNC_OTHER = 0xFF, +} audio_function_code_t; + +/// A.9 - Audio Class-Specific AC Interface Descriptor Subtypes UAC2 +typedef enum +{ + AUDIO_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00, + AUDIO_CS_AC_INTERFACE_HEADER = 0x01, + AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02, + AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL = 0x03, + AUDIO_CS_AC_INTERFACE_MIXER_UNIT = 0x04, + AUDIO_CS_AC_INTERFACE_SELECTOR_UNIT = 0x05, + AUDIO_CS_AC_INTERFACE_FEATURE_UNIT = 0x06, + AUDIO_CS_AC_INTERFACE_EFFECT_UNIT = 0x07, + AUDIO_CS_AC_INTERFACE_PROCESSING_UNIT = 0x08, + AUDIO_CS_AC_INTERFACE_EXTENSION_UNIT = 0x09, + AUDIO_CS_AC_INTERFACE_CLOCK_SOURCE = 0x0A, + AUDIO_CS_AC_INTERFACE_CLOCK_SELECTOR = 0x0B, + AUDIO_CS_AC_INTERFACE_CLOCK_MULTIPLIER = 0x0C, + AUDIO_CS_AC_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D, +} audio_cs_ac_interface_subtype_t; + +/// A.10 - Audio Class-Specific AS Interface Descriptor Subtypes UAC2 +typedef enum +{ + AUDIO_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00, + AUDIO_CS_AS_INTERFACE_AS_GENERAL = 0x01, + AUDIO_CS_AS_INTERFACE_FORMAT_TYPE = 0x02, + AUDIO_CS_AS_INTERFACE_ENCODER = 0x03, + AUDIO_CS_AS_INTERFACE_DECODER = 0x04, +} audio_cs_as_interface_subtype_t; + +/// A.11 - Effect Unit Effect Types +typedef enum +{ + AUDIO_EFFECT_TYPE_UNDEF = 0x00, + AUDIO_EFFECT_TYPE_PARAM_EQ_SECTION = 0x01, + AUDIO_EFFECT_TYPE_REVERBERATION = 0x02, + AUDIO_EFFECT_TYPE_MOD_DELAY = 0x03, + AUDIO_EFFECT_TYPE_DYN_RANGE_COMP = 0x04, +} audio_effect_unit_effect_type_t; + +/// A.12 - Processing Unit Process Types +typedef enum +{ + AUDIO_PROCESS_TYPE_UNDEF = 0x00, + AUDIO_PROCESS_TYPE_UP_DOWN_MIX = 0x01, + AUDIO_PROCESS_TYPE_DOLBY_PROLOGIC = 0x02, + AUDIO_PROCESS_TYPE_STEREO_EXTENDER = 0x03, +} audio_processing_unit_process_type_t; + +/// A.13 - Audio Class-Specific EP Descriptor Subtypes UAC2 +typedef enum +{ + AUDIO_CS_EP_SUBTYPE_UNDEF = 0x00, + AUDIO_CS_EP_SUBTYPE_GENERAL = 0x01, +} audio_cs_ep_subtype_t; + +/// A.14 - Audio Class-Specific Request Codes +typedef enum +{ + AUDIO_CS_REQ_UNDEF = 0x00, + AUDIO_CS_REQ_CUR = 0x01, + AUDIO_CS_REQ_RANGE = 0x02, + AUDIO_CS_REQ_MEM = 0x03, +} audio_cs_req_t; + +/// A.17 - Control Selector Codes + +/// A.17.1 - Clock Source Control Selectors +typedef enum +{ + AUDIO_CS_CTRL_UNDEF = 0x00, + AUDIO_CS_CTRL_SAM_FREQ = 0x01, + AUDIO_CS_CTRL_CLK_VALID = 0x02, +} audio_clock_src_control_selector_t; + +/// A.17.2 - Clock Selector Control Selectors +typedef enum +{ + AUDIO_CX_CTRL_UNDEF = 0x00, + AUDIO_CX_CTRL_CONTROL = 0x01, +} audio_clock_sel_control_selector_t; + +/// A.17.3 - Clock Multiplier Control Selectors +typedef enum +{ + AUDIO_CM_CTRL_UNDEF = 0x00, + AUDIO_CM_CTRL_NUMERATOR_CONTROL = 0x01, + AUDIO_CM_CTRL_DENOMINATOR_CONTROL = 0x02, +} audio_clock_mul_control_selector_t; + +/// A.17.4 - Terminal Control Selectors +typedef enum +{ + AUDIO_TE_CTRL_UNDEF = 0x00, + AUDIO_TE_CTRL_COPY_PROTECT = 0x01, + AUDIO_TE_CTRL_CONNECTOR = 0x02, + AUDIO_TE_CTRL_OVERLOAD = 0x03, + AUDIO_TE_CTRL_CLUSTER = 0x04, + AUDIO_TE_CTRL_UNDERFLOW = 0x05, + AUDIO_TE_CTRL_OVERFLOW = 0x06, + AUDIO_TE_CTRL_LATENCY = 0x07, +} audio_terminal_control_selector_t; + +/// A.17.5 - Mixer Control Selectors +typedef enum +{ + AUDIO_MU_CTRL_UNDEF = 0x00, + AUDIO_MU_CTRL_MIXER = 0x01, + AUDIO_MU_CTRL_CLUSTER = 0x02, + AUDIO_MU_CTRL_UNDERFLOW = 0x03, + AUDIO_MU_CTRL_OVERFLOW = 0x04, + AUDIO_MU_CTRL_LATENCY = 0x05, +} audio_mixer_control_selector_t; + +/// A.17.6 - Selector Control Selectors +typedef enum +{ + AUDIO_SU_CTRL_UNDEF = 0x00, + AUDIO_SU_CTRL_SELECTOR = 0x01, + AUDIO_SU_CTRL_LATENCY = 0x02, +} audio_sel_control_selector_t; + +/// A.17.7 - Feature Unit Control Selectors +typedef enum +{ + AUDIO_FU_CTRL_UNDEF = 0x00, + AUDIO_FU_CTRL_MUTE = 0x01, + AUDIO_FU_CTRL_VOLUME = 0x02, + AUDIO_FU_CTRL_BASS = 0x03, + AUDIO_FU_CTRL_MID = 0x04, + AUDIO_FU_CTRL_TREBLE = 0x05, + AUDIO_FU_CTRL_GRAPHIC_EQUALIZER = 0x06, + AUDIO_FU_CTRL_AGC = 0x07, + AUDIO_FU_CTRL_DELAY = 0x08, + AUDIO_FU_CTRL_BASS_BOOST = 0x09, + AUDIO_FU_CTRL_LOUDNESS = 0x0A, + AUDIO_FU_CTRL_INPUT_GAIN = 0x0B, + AUDIO_FU_CTRL_GAIN_PAD = 0x0C, + AUDIO_FU_CTRL_INVERTER = 0x0D, + AUDIO_FU_CTRL_UNDERFLOW = 0x0E, + AUDIO_FU_CTRL_OVERVLOW = 0x0F, + AUDIO_FU_CTRL_LATENCY = 0x10, +} audio_feature_unit_control_selector_t; + +/// A.17.8 Effect Unit Control Selectors + +/// A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors +typedef enum +{ + AUDIO_PE_CTRL_UNDEF = 0x00, + AUDIO_PE_CTRL_ENABLE = 0x01, + AUDIO_PE_CTRL_CENTERFREQ = 0x02, + AUDIO_PE_CTRL_QFACTOR = 0x03, + AUDIO_PE_CTRL_GAIN = 0x04, + AUDIO_PE_CTRL_UNDERFLOW = 0x05, + AUDIO_PE_CTRL_OVERFLOW = 0x06, + AUDIO_PE_CTRL_LATENCY = 0x07, +} audio_parametric_equalizer_control_selector_t; + +/// A.17.8.2 Reverberation Effect Unit Control Selectors +typedef enum +{ + AUDIO_RV_CTRL_UNDEF = 0x00, + AUDIO_RV_CTRL_ENABLE = 0x01, + AUDIO_RV_CTRL_TYPE = 0x02, + AUDIO_RV_CTRL_LEVEL = 0x03, + AUDIO_RV_CTRL_TIME = 0x04, + AUDIO_RV_CTRL_FEEDBACK = 0x05, + AUDIO_RV_CTRL_PREDELAY = 0x06, + AUDIO_RV_CTRL_DENSITY = 0x07, + AUDIO_RV_CTRL_HIFREQ_ROLLOFF = 0x08, + AUDIO_RV_CTRL_UNDERFLOW = 0x09, + AUDIO_RV_CTRL_OVERFLOW = 0x0A, + AUDIO_RV_CTRL_LATENCY = 0x0B, +} audio_reverberation_effect_control_selector_t; + +/// A.17.8.3 Modulation Delay Effect Unit Control Selectors +typedef enum +{ + AUDIO_MD_CTRL_UNDEF = 0x00, + AUDIO_MD_CTRL_ENABLE = 0x01, + AUDIO_MD_CTRL_BALANCE = 0x02, + AUDIO_MD_CTRL_RATE = 0x03, + AUDIO_MD_CTRL_DEPTH = 0x04, + AUDIO_MD_CTRL_TIME = 0x05, + AUDIO_MD_CTRL_FEEDBACK = 0x06, + AUDIO_MD_CTRL_UNDERFLOW = 0x07, + AUDIO_MD_CTRL_OVERFLOW = 0x08, + AUDIO_MD_CTRL_LATENCY = 0x09, +} audio_modulation_delay_control_selector_t; + +/// A.17.8.4 Dynamic Range Compressor Effect Unit Control Selectors +typedef enum +{ + AUDIO_DR_CTRL_UNDEF = 0x00, + AUDIO_DR_CTRL_ENABLE = 0x01, + AUDIO_DR_CTRL_COMPRESSION_RATE = 0x02, + AUDIO_DR_CTRL_MAXAMPL = 0x03, + AUDIO_DR_CTRL_THRESHOLD = 0x04, + AUDIO_DR_CTRL_ATTACK_TIME = 0x05, + AUDIO_DR_CTRL_RELEASE_TIME = 0x06, + AUDIO_DR_CTRL_UNDERFLOW = 0x07, + AUDIO_DR_CTRL_OVERFLOW = 0x08, + AUDIO_DR_CTRL_LATENCY = 0x09, +} audio_dynamic_range_compression_control_selector_t; + +/// A.17.9 Processing Unit Control Selectors + +/// A.17.9.1 Up/Down-mix Processing Unit Control Selectors +typedef enum +{ + AUDIO_UD_CTRL_UNDEF = 0x00, + AUDIO_UD_CTRL_ENABLE = 0x01, + AUDIO_UD_CTRL_MODE_SELECT = 0x02, + AUDIO_UD_CTRL_CLUSTER = 0x03, + AUDIO_UD_CTRL_UNDERFLOW = 0x04, + AUDIO_UD_CTRL_OVERFLOW = 0x05, + AUDIO_UD_CTRL_LATENCY = 0x06, +} audio_up_down_mix_control_selector_t; + +/// A.17.9.2 Dolby Prologic â„¢ Processing Unit Control Selectors +typedef enum +{ + AUDIO_DP_CTRL_UNDEF = 0x00, + AUDIO_DP_CTRL_ENABLE = 0x01, + AUDIO_DP_CTRL_MODE_SELECT = 0x02, + AUDIO_DP_CTRL_CLUSTER = 0x03, + AUDIO_DP_CTRL_UNDERFLOW = 0x04, + AUDIO_DP_CTRL_OVERFLOW = 0x05, + AUDIO_DP_CTRL_LATENCY = 0x06, +} audio_dolby_prologic_control_selector_t; + +/// A.17.9.3 Stereo Extender Processing Unit Control Selectors +typedef enum +{ + AUDIO_ST_EXT_CTRL_UNDEF = 0x00, + AUDIO_ST_EXT_CTRL_ENABLE = 0x01, + AUDIO_ST_EXT_CTRL_WIDTH = 0x02, + AUDIO_ST_EXT_CTRL_UNDERFLOW = 0x03, + AUDIO_ST_EXT_CTRL_OVERFLOW = 0x04, + AUDIO_ST_EXT_CTRL_LATENCY = 0x05, +} audio_stereo_extender_control_selector_t; + +/// A.17.10 Extension Unit Control Selectors +typedef enum +{ + AUDIO_XU_CTRL_UNDEF = 0x00, + AUDIO_XU_CTRL_ENABLE = 0x01, + AUDIO_XU_CTRL_CLUSTER = 0x02, + AUDIO_XU_CTRL_UNDERFLOW = 0x03, + AUDIO_XU_CTRL_OVERFLOW = 0x04, + AUDIO_XU_CTRL_LATENCY = 0x05, +} audio_extension_unit_control_selector_t; + +/// A.17.11 AudioStreaming Interface Control Selectors +typedef enum +{ + AUDIO_AS_CTRL_UNDEF = 0x00, + AUDIO_AS_CTRL_ACT_ALT_SETTING = 0x01, + AUDIO_AS_CTRL_VAL_ALT_SETTINGS = 0x02, + AUDIO_AS_CTRL_AUDIO_DATA_FORMAT = 0x03, +} audio_audiostreaming_interface_control_selector_t; + +/// A.17.12 Encoder Control Selectors +typedef enum +{ + AUDIO_EN_CTRL_UNDEF = 0x00, + AUDIO_EN_CTRL_BIT_RATE = 0x01, + AUDIO_EN_CTRL_QUALITY = 0x02, + AUDIO_EN_CTRL_VBR = 0x03, + AUDIO_EN_CTRL_TYPE = 0x04, + AUDIO_EN_CTRL_UNDERFLOW = 0x05, + AUDIO_EN_CTRL_OVERFLOW = 0x06, + AUDIO_EN_CTRL_ENCODER_ERROR = 0x07, + AUDIO_EN_CTRL_PARAM1 = 0x08, + AUDIO_EN_CTRL_PARAM2 = 0x09, + AUDIO_EN_CTRL_PARAM3 = 0x0A, + AUDIO_EN_CTRL_PARAM4 = 0x0B, + AUDIO_EN_CTRL_PARAM5 = 0x0C, + AUDIO_EN_CTRL_PARAM6 = 0x0D, + AUDIO_EN_CTRL_PARAM7 = 0x0E, + AUDIO_EN_CTRL_PARAM8 = 0x0F, +} audio_encoder_control_selector_t; + +/// A.17.13 Decoder Control Selectors + +/// A.17.13.1 MPEG Decoder Control Selectors +typedef enum +{ + AUDIO_MPD_CTRL_UNDEF = 0x00, + AUDIO_MPD_CTRL_DUAL_CHANNEL = 0x01, + AUDIO_MPD_CTRL_SECOND_STEREO = 0x02, + AUDIO_MPD_CTRL_MULTILINGUAL = 0x03, + AUDIO_MPD_CTRL_DYN_RANGE = 0x04, + AUDIO_MPD_CTRL_SCALING = 0x05, + AUDIO_MPD_CTRL_HILO_SCALING = 0x06, + AUDIO_MPD_CTRL_UNDERFLOW = 0x07, + AUDIO_MPD_CTRL_OVERFLOW = 0x08, + AUDIO_MPD_CTRL_DECODER_ERROR = 0x09, +} audio_MPEG_decoder_control_selector_t; + +/// A.17.13.2 AC-3 Decoder Control Selectors +typedef enum +{ + AUDIO_AD_CTRL_UNDEF = 0x00, + AUDIO_AD_CTRL_MODE = 0x01, + AUDIO_AD_CTRL_DYN_RANGE = 0x02, + AUDIO_AD_CTRL_SCALING = 0x03, + AUDIO_AD_CTRL_HILO_SCALING = 0x04, + AUDIO_AD_CTRL_UNDERFLOW = 0x05, + AUDIO_AD_CTRL_OVERFLOW = 0x06, + AUDIO_AD_CTRL_DECODER_ERROR = 0x07, +} audio_AC3_decoder_control_selector_t; + +/// A.17.13.3 WMA Decoder Control Selectors +typedef enum +{ + AUDIO_WD_CTRL_UNDEF = 0x00, + AUDIO_WD_CTRL_UNDERFLOW = 0x01, + AUDIO_WD_CTRL_OVERFLOW = 0x02, + AUDIO_WD_CTRL_DECODER_ERROR = 0x03, +} audio_WMA_decoder_control_selector_t; + +/// A.17.13.4 DTS Decoder Control Selectors +typedef enum +{ + AUDIO_DD_CTRL_UNDEF = 0x00, + AUDIO_DD_CTRL_UNDERFLOW = 0x01, + AUDIO_DD_CTRL_OVERFLOW = 0x02, + AUDIO_DD_CTRL_DECODER_ERROR = 0x03, +} audio_DTS_decoder_control_selector_t; + +/// A.17.14 Endpoint Control Selectors +typedef enum +{ + AUDIO_EP_CTRL_UNDEF = 0x00, + AUDIO_EP_CTRL_PITCH = 0x01, + AUDIO_EP_CTRL_DATA_OVERRUN = 0x02, + AUDIO_EP_CTRL_DATA_UNDERRUN = 0x03, +} audio_EP_control_selector_t; + +/// Terminal Types + +/// 2.1 - Audio Class-Terminal Types UAC2 +typedef enum +{ + AUDIO_TERM_TYPE_USB_UNDEFINED = 0x0100, + AUDIO_TERM_TYPE_USB_STREAMING = 0x0101, + AUDIO_TERM_TYPE_USB_VENDOR_SPEC = 0x01FF, +} audio_terminal_type_t; + +/// 2.2 - Audio Class-Input Terminal Types UAC2 +typedef enum +{ + AUDIO_TERM_TYPE_IN_UNDEFINED = 0x0200, + AUDIO_TERM_TYPE_IN_GENERIC_MIC = 0x0201, + AUDIO_TERM_TYPE_IN_DESKTOP_MIC = 0x0202, + AUDIO_TERM_TYPE_IN_PERSONAL_MIC = 0x0203, + AUDIO_TERM_TYPE_IN_OMNI_MIC = 0x0204, + AUDIO_TERM_TYPE_IN_ARRAY_MIC = 0x0205, + AUDIO_TERM_TYPE_IN_PROC_ARRAY_MIC = 0x0206, +} audio_terminal_input_type_t; + +/// 2.3 - Audio Class-Output Terminal Types UAC2 +typedef enum +{ + AUDIO_TERM_TYPE_OUT_UNDEFINED = 0x0300, + AUDIO_TERM_TYPE_OUT_GENERIC_SPEAKER = 0x0301, + AUDIO_TERM_TYPE_OUT_HEADPHONES = 0x0302, + AUDIO_TERM_TYPE_OUT_HEAD_MNT_DISP_AUIDO = 0x0303, + AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER = 0x0304, + AUDIO_TERM_TYPE_OUT_ROOM_SPEAKER = 0x0305, + AUDIO_TERM_TYPE_OUT_COMMUNICATION_SPEAKER = 0x0306, + AUDIO_TERM_TYPE_OUT_LOW_FRQ_EFFECTS_SPEAKER = 0x0307, +} audio_terminal_output_type_t; + +/// Rest is yet to be implemented + +/// Additional Audio Device Class Codes - Source: Audio Data Formats + +/// A.1 - Audio Class-Format Type Codes UAC2 +typedef enum +{ + AUDIO_FORMAT_TYPE_UNDEFINED = 0x00, + AUDIO_FORMAT_TYPE_I = 0x01, + AUDIO_FORMAT_TYPE_II = 0x02, + AUDIO_FORMAT_TYPE_III = 0x03, + AUDIO_FORMAT_TYPE_IV = 0x04, + AUDIO_EXT_FORMAT_TYPE_I = 0x81, + AUDIO_EXT_FORMAT_TYPE_II = 0x82, + AUDIO_EXT_FORMAT_TYPE_III = 0x83, +} audio_format_type_t; + +// A.2.1 - Audio Class-Audio Data Format Type I UAC2 +typedef enum +{ + AUDIO_DATA_FORMAT_TYPE_I_PCM = (uint32_t) (1 << 0), + AUDIO_DATA_FORMAT_TYPE_I_PCM8 = (uint32_t) (1 << 1), + AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), + AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), + AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, +} audio_data_format_type_I_t; + +/// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification + +/// Audio Class-Control Values UAC2 +typedef enum +{ + AUDIO_CTRL_NONE = 0x00, ///< No Host access + AUDIO_CTRL_R = 0x01, ///< Host read access only + AUDIO_CTRL_RW = 0x03, ///< Host read write access +} audio_control_t; + +/// Audio Class-Specific AC Interface Descriptor Controls UAC2 +typedef enum +{ + AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS = 0, +} audio_cs_ac_interface_control_pos_t; + +/// Audio Class-Specific AS Interface Descriptor Controls UAC2 +typedef enum +{ + AUDIO_CS_AS_INTERFACE_CTRL_ACTIVE_ALT_SET_POS = 0, + AUDIO_CS_AS_INTERFACE_CTRL_VALID_ALT_SET_POS = 2, +} audio_cs_as_interface_control_pos_t; + +/// Audio Class-Specific AS Isochronous Data EP Attributes UAC2 +typedef enum +{ + AUDIO_CS_AS_ISO_DATA_EP_ATT_MAX_PACKETS_ONLY = 0x80, + AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK = 0x00, +} audio_cs_as_iso_data_ep_attribute_t; + +/// Audio Class-Specific AS Isochronous Data EP Controls UAC2 +typedef enum +{ + AUDIO_CS_AS_ISO_DATA_EP_CTRL_PITCH_POS = 0, + AUDIO_CS_AS_ISO_DATA_EP_CTRL_DATA_OVERRUN_POS = 2, + AUDIO_CS_AS_ISO_DATA_EP_CTRL_DATA_UNDERRUN_POS = 4, +} audio_cs_as_iso_data_ep_control_pos_t; + +/// Audio Class-Specific AS Isochronous Data EP Lock Delay Units UAC2 +typedef enum +{ + AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED = 0x00, + AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC = 0x01, + AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02, +} audio_cs_as_iso_data_ep_lock_delay_unit_t; + +/// Audio Class-Clock Source Attributes UAC2 +typedef enum +{ + AUDIO_CLOCK_SOURCE_ATT_EXT_CLK = 0x00, + AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK = 0x01, + AUDIO_CLOCK_SOURCE_ATT_INT_VAR_CLK = 0x02, + AUDIO_CLOCK_SOURCE_ATT_INT_PRO_CLK = 0x03, + AUDIO_CLOCK_SOURCE_ATT_CLK_SYC_SOF = 0x04, +} audio_clock_source_attribute_t; + +/// Audio Class-Clock Source Controls UAC2 +typedef enum +{ + AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS = 0, + AUDIO_CLOCK_SOURCE_CTRL_CLK_VAL_POS = 2, +} audio_clock_source_control_pos_t; + +/// Audio Class-Clock Selector Controls UAC2 +typedef enum +{ + AUDIO_CLOCK_SELECTOR_CTRL_POS = 0, +} audio_clock_selector_control_pos_t; + +/// Audio Class-Clock Multiplier Controls UAC2 +typedef enum +{ + AUDIO_CLOCK_MULTIPLIER_CTRL_NUMERATOR_POS = 0, + AUDIO_CLOCK_MULTIPLIER_CTRL_DENOMINATOR_POS = 2, +} audio_clock_multiplier_control_pos_t; + +/// Audio Class-Input Terminal Controls UAC2 +typedef enum +{ + AUDIO_IN_TERM_CTRL_CPY_PROT_POS = 0, + AUDIO_IN_TERM_CTRL_CONNECTOR_POS = 2, + AUDIO_IN_TERM_CTRL_OVERLOAD_POS = 4, + AUDIO_IN_TERM_CTRL_CLUSTER_POS = 6, + AUDIO_IN_TERM_CTRL_UNDERFLOW_POS = 8, + AUDIO_IN_TERM_CTRL_OVERFLOW_POS = 10, +} audio_terminal_input_control_pos_t; + +/// Audio Class-Output Terminal Controls UAC2 +typedef enum +{ + AUDIO_OUT_TERM_CTRL_CPY_PROT_POS = 0, + AUDIO_OUT_TERM_CTRL_CONNECTOR_POS = 2, + AUDIO_OUT_TERM_CTRL_OVERLOAD_POS = 4, + AUDIO_OUT_TERM_CTRL_UNDERFLOW_POS = 6, + AUDIO_OUT_TERM_CTRL_OVERFLOW_POS = 8, +} audio_terminal_output_control_pos_t; + +/// Audio Class-Feature Unit Controls UAC2 +typedef enum +{ + AUDIO_FEATURE_UNIT_CTRL_MUTE_POS = 0, + AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS = 2, + AUDIO_FEATURE_UNIT_CTRL_BASS_POS = 4, + AUDIO_FEATURE_UNIT_CTRL_MID_POS = 6, + AUDIO_FEATURE_UNIT_CTRL_TREBLE_POS = 8, + AUDIO_FEATURE_UNIT_CTRL_GRAPHIC_EQU_POS = 10, + AUDIO_FEATURE_UNIT_CTRL_AGC_POS = 12, + AUDIO_FEATURE_UNIT_CTRL_DELAY_POS = 14, + AUDIO_FEATURE_UNIT_CTRL_BASS_BOOST_POS = 16, + AUDIO_FEATURE_UNIT_CTRL_LOUDNESS_POS = 18, + AUDIO_FEATURE_UNIT_CTRL_INPUT_GAIN_POS = 20, + AUDIO_FEATURE_UNIT_CTRL_INPUT_GAIN_PAD_POS = 22, + AUDIO_FEATURE_UNIT_CTRL_PHASE_INV_POS = 24, + AUDIO_FEATURE_UNIT_CTRL_UNDERFLOW_POS = 26, + AUDIO_FEATURE_UNIT_CTRL_OVERFLOW_POS = 28, +} audio_feature_unit_control_pos_t; + +/// Audio Class-Audio Channel Configuration UAC2 +typedef enum +{ + AUDIO_CHANNEL_CONFIG_NON_PREDEFINED = 0x00000000, + AUDIO_CHANNEL_CONFIG_FRONT_LEFT = 0x00000001, + AUDIO_CHANNEL_CONFIG_FRONT_RIGHT = 0x00000002, + AUDIO_CHANNEL_CONFIG_FRONT_CENTER = 0x00000004, + AUDIO_CHANNEL_CONFIG_LOW_FRQ_EFFECTS = 0x00000008, + AUDIO_CHANNEL_CONFIG_BACK_LEFT = 0x00000010, + AUDIO_CHANNEL_CONFIG_BACK_RIGHT = 0x00000020, + AUDIO_CHANNEL_CONFIG_FRONT_LEFT_OF_CENTER = 0x00000040, + AUDIO_CHANNEL_CONFIG_FRONT_RIGHT_OF_CENTER = 0x00000080, + AUDIO_CHANNEL_CONFIG_BACK_CENTER = 0x00000100, + AUDIO_CHANNEL_CONFIG_SIDE_LEFT = 0x00000200, + AUDIO_CHANNEL_CONFIG_SIDE_RIGHT = 0x00000400, + AUDIO_CHANNEL_CONFIG_TOP_CENTER = 0x00000800, + AUDIO_CHANNEL_CONFIG_TOP_FRONT_LEFT = 0x00001000, + AUDIO_CHANNEL_CONFIG_TOP_FRONT_CENTER = 0x00002000, + AUDIO_CHANNEL_CONFIG_TOP_FRONT_RIGHT = 0x00004000, + AUDIO_CHANNEL_CONFIG_TOP_BACK_LEFT = 0x00008000, + AUDIO_CHANNEL_CONFIG_TOP_BACK_CENTER = 0x00010000, + AUDIO_CHANNEL_CONFIG_TOP_BACK_RIGHT = 0x00020000, + AUDIO_CHANNEL_CONFIG_TOP_FRONT_LEFT_OF_CENTER = 0x00040000, + AUDIO_CHANNEL_CONFIG_TOP_FRONT_RIGHT_OF_CENTER = 0x00080000, + AUDIO_CHANNEL_CONFIG_LEFT_LOW_FRQ_EFFECTS = 0x00100000, + AUDIO_CHANNEL_CONFIG_RIGHT_LOW_FRQ_EFFECTS = 0x00200000, + AUDIO_CHANNEL_CONFIG_TOP_SIDE_LEFT = 0x00400000, + AUDIO_CHANNEL_CONFIG_TOP_SIDE_RIGHT = 0x00800000, + AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, + AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, + AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, + AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, +} audio_channel_config_t; + +/// AUDIO Channel Cluster Descriptor (4.1) +typedef struct TU_ATTR_PACKED { + uint8_t bNrChannels; ///< Number of channels currently connected. + audio_channel_config_t bmChannelConfig; ///< Bitmap according to 'audio_channel_config_t' with a 1 set if channel is connected and 0 else. In case channels are non-predefined ignore them here (see UAC2 specification 4.1 Audio Channel Cluster Descriptor. + uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first inserted channel with a non-predefined spatial location. +} audio_desc_channel_cluster_t; + +/// AUDIO Class-Specific AC Interface Header Descriptor (4.7.2) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes: 9. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_HEADER. + uint16_t bcdADC ; ///< Audio Device Class Specification Release Number in Binary-Coded Decimal. Value: U16_TO_U8S_LE(0x0200). + uint8_t bCategory ; ///< Constant, indicating the primary use of this audio function, as intended by the manufacturer. See: audio_function_t. + uint16_t wTotalLength ; ///< Total number of bytes returned for the class-specific AudioControl interface descriptor. Includes the combined length of this descriptor header and all Clock Source, Unit and Terminal descriptors. + uint8_t bmControls ; ///< See: audio_cs_ac_interface_control_pos_t. +} audio_desc_cs_ac_interface_t; + +/// AUDIO Clock Source Descriptor (4.7.2.1) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes: 8. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_SOURCE. + uint8_t bClockID ; ///< Constant uniquely identifying the Clock Source Entity within the audio function. This value is used in all requests to address this Entity. + uint8_t bmAttributes ; ///< See: audio_clock_source_attribute_t. + uint8_t bmControls ; ///< See: audio_clock_source_control_pos_t. + uint8_t bAssocTerminal ; ///< Terminal ID of the Terminal that is associated with this Clock Source. + uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Source Entity. +} audio_desc_clock_source_t; + +/// AUDIO Clock Selector Descriptor (4.7.2.2) for ONE pin +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor, in bytes: 7+p. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_SELECTOR. + uint8_t bClockID ; ///< Constant uniquely identifying the Clock Selector Entity within the audio function. This value is used in all requests to address this Entity. + uint8_t bNrInPins ; ///< Number of Input Pins of this Unit: p = 1 thus bNrInPins = 1. + uint8_t baCSourceID ; ///< ID of the Clock Entity to which the first Clock Input Pin of this Clock Selector Entity is connected.. + uint8_t bmControls ; ///< See: audio_clock_selector_control_pos_t. + uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Selector Entity. +} audio_desc_clock_selector_t; + +/// AUDIO Clock Selector Descriptor (4.7.2.2) for multiple pins +#define audio_desc_clock_selector_n_t(source_num) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength ; \ + uint8_t bDescriptorType ; \ + uint8_t bDescriptorSubType ; \ + uint8_t bClockID ; \ + uint8_t bNrInPins ; \ + struct TU_ATTR_PACKED { \ + uint8_t baSourceID ; \ + } sourceID[source_num] ; \ + uint8_t bmControls ; \ + uint8_t iClockSource ; \ +} + +/// AUDIO Clock Multiplier Descriptor (4.7.2.3) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor, in bytes: 7. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_MULTIPLIER. + uint8_t bClockID ; ///< Constant uniquely identifying the Clock Multiplier Entity within the audio function. This value is used in all requests to address this Entity. + uint8_t bCSourceID ; ///< ID of the Clock Entity to which the last Clock Input Pin of this Clock Selector Entity is connected. + uint8_t bmControls ; ///< See: audio_clock_multiplier_control_pos_t. + uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Multiplier Entity. +} audio_desc_clock_multiplier_t; + +/// AUDIO Input Terminal Descriptor(4.7.2.4) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor, in bytes: 17. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL. + uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. See: audio_terminal_type_t for USB streaming and audio_terminal_input_type_t for other input types. + uint8_t bAssocTerminal ; ///< ID of the Output Terminal to which this Input Terminal is associated. + uint8_t bCSourceID ; ///< ID of the Clock Entity to which this Input Terminal is connected. + uint8_t bNrChannels ; ///< Number of logical output channels in the Terminal’s output audio channel cluster. + uint32_t bmChannelConfig ; ///< Describes the spatial location of the logical channels. See:audio_channel_config_t. + uint16_t bmControls ; ///< See: audio_terminal_input_control_pos_t. + uint8_t iTerminal ; ///< Index of a string descriptor, describing the Input Terminal. +} audio_desc_input_terminal_t; + +/// AUDIO Output Terminal Descriptor(4.7.2.5) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor, in bytes: 12. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL. + uint8_t bTerminalID ; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this Terminal. + uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. See: audio_terminal_type_t for USB streaming and audio_terminal_output_type_t for other output types. + uint8_t bAssocTerminal ; ///< Constant, identifying the Input Terminal to which this Output Terminal is associated. + uint8_t bSourceID ; ///< ID of the Unit or Terminal to which this Terminal is connected. + uint8_t bCSourceID ; ///< ID of the Clock Entity to which this Output Terminal is connected. + uint16_t bmControls ; ///< See: audio_terminal_output_type_t. + uint8_t iTerminal ; ///< Index of a string descriptor, describing the Output Terminal. +} audio_desc_output_terminal_t; + +/// AUDIO Feature Unit Descriptor(4.7.2.8) for ONE channel +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor, in bytes: 14. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_FEATURE_UNIT. + uint8_t bUnitID ; ///< Constant uniquely identifying the Unit within the audio function. This value is used in all requests to address this Unit. + uint8_t bSourceID ; ///< ID of the Unit or Terminal to which this Feature Unit is connected. + struct TU_ATTR_PACKED { + uint32_t bmaControls ; ///< See: audio_feature_unit_control_pos_t. Controls0 is master channel 0 (always present) and Controls1 is logical channel 1. + } controls[2] ; + uint8_t iTerminal ; ///< Index of a string descriptor, describing this Feature Unit. +} audio_desc_feature_unit_t; + +/// AUDIO Feature Unit Descriptor(4.7.2.8) for multiple channels +#define audio_desc_feature_unit_n_t(ch_num)\ + struct TU_ATTR_PACKED { \ + uint8_t bLength ; /* 6+(ch_num+1)*4 */\ + uint8_t bDescriptorType ; \ + uint8_t bDescriptorSubType ; \ + uint8_t bUnitID ; \ + uint8_t bSourceID ; \ + struct TU_ATTR_PACKED { \ + uint32_t bmaControls ; \ + } controls[ch_num+1] ; \ + uint8_t iTerminal ; \ +} + +/// AUDIO Class-Specific AS Interface Descriptor(4.9.2) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor, in bytes: 16. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AS_INTERFACE_AS_GENERAL. + uint8_t bTerminalLink ; ///< The Terminal ID of the Terminal to which this interface is connected. + uint8_t bmControls ; ///< See: audio_cs_as_interface_control_pos_t. + uint8_t bFormatType ; ///< Constant identifying the Format Type the AudioStreaming interface is using. See: audio_format_type_t. + uint32_t bmFormats ; ///< The Audio Data Format(s) that can be used to communicate with this interface.See: audio_data_format_type_I_t. + uint8_t bNrChannels ; ///< Number of physical channels in the AS Interface audio channel cluster. + uint32_t bmChannelConfig ; ///< Describes the spatial location of the physical channels. See: audio_channel_config_t. + uint8_t iChannelNames ; ///< Index of a string descriptor, describing the name of the first physical channel. +} audio_desc_cs_as_interface_t; + +/// AUDIO Type I Format Type Descriptor(2.3.1.6 - Audio Formats) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor, in bytes: 6. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AS_INTERFACE_FORMAT_TYPE. + uint8_t bFormatType ; ///< Constant identifying the Format Type the AudioStreaming interface is using. Value: AUDIO_FORMAT_TYPE_I. + uint8_t bSubslotSize ; ///< The number of bytes occupied by one audio subslot. Can be 1, 2, 3 or 4. + uint8_t bBitResolution ; ///< The number of effectively used bits from the available bits in an audio subslot. +} audio_desc_type_I_format_t; + +/// AUDIO Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor, in bytes: 8. + uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_ENDPOINT. + uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_EP_SUBTYPE_GENERAL. + uint8_t bmAttributes ; ///< See: audio_cs_as_iso_data_ep_attribute_t. + uint8_t bmControls ; ///< See: audio_cs_as_iso_data_ep_control_pos_t. + uint8_t bLockDelayUnits ; ///< Indicates the units used for the wLockDelay field. See: audio_cs_as_iso_data_ep_lock_delay_unit_t. + uint16_t wLockDelay ; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. Units used depend on the value of the bLockDelayUnits field. +} audio_desc_cs_as_iso_data_ep_t; + +// 5.2.2 Control Request Layout +typedef struct TU_ATTR_PACKED +{ + union + { + struct TU_ATTR_PACKED + { + uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. + uint8_t type : 2; ///< Request type tusb_request_type_t. + uint8_t direction : 1; ///< Direction type. tusb_dir_t + } bmRequestType_bit; + + uint8_t bmRequestType; + }; + + uint8_t bRequest; ///< Request type audio_cs_req_t + uint8_t bChannelNumber; + uint8_t bControlSelector; + union + { + uint8_t bInterface; + uint8_t bEndpoint; + }; + uint8_t bEntityID; + uint16_t wLength; +} audio_control_request_t; + +//// 5.2.3 Control Request Parameter Block Layout + +// 5.2.3.1 1-byte Control CUR Parameter Block +typedef struct TU_ATTR_PACKED +{ + int8_t bCur ; ///< The setting for the CUR attribute of the addressed Control +} audio_control_cur_1_t; + +// 5.2.3.2 2-byte Control CUR Parameter Block +typedef struct TU_ATTR_PACKED +{ + int16_t bCur ; ///< The setting for the CUR attribute of the addressed Control +} audio_control_cur_2_t; + +// 5.2.3.3 4-byte Control CUR Parameter Block +typedef struct TU_ATTR_PACKED +{ + int32_t bCur ; ///< The setting for the CUR attribute of the addressed Control +} audio_control_cur_4_t; + +// Use the following ONLY for RECEIVED data - compiler does not know how many subranges are defined! Use the one below for predefined lengths - or if you know what you are doing do what you like +// 5.2.3.1 1-byte Control RANGE Parameter Block +typedef struct TU_ATTR_PACKED { + uint16_t wNumSubRanges; + struct TU_ATTR_PACKED { + int8_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ + int8_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ + uint8_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ + } subrange[] ; +} audio_control_range_1_t; + +// 5.2.3.2 2-byte Control RANGE Parameter Block +typedef struct TU_ATTR_PACKED { + uint16_t wNumSubRanges; + struct TU_ATTR_PACKED { + int16_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ + int16_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ + uint16_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ + } subrange[] ; +} audio_control_range_2_t; + +// 5.2.3.3 4-byte Control RANGE Parameter Block +typedef struct TU_ATTR_PACKED { + uint16_t wNumSubRanges; + struct TU_ATTR_PACKED { + int32_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ + int32_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ + uint32_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ + } subrange[] ; +} audio_control_range_4_t; + +// 5.2.3.1 1-byte Control RANGE Parameter Block +#define audio_control_range_1_n_t(numSubRanges) \ + struct TU_ATTR_PACKED { \ + uint16_t wNumSubRanges; \ + struct TU_ATTR_PACKED { \ + int8_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\ + int8_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\ + uint8_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\ + } subrange[numSubRanges] ; \ +} + +/// 5.2.3.2 2-byte Control RANGE Parameter Block +#define audio_control_range_2_n_t(numSubRanges) \ + struct TU_ATTR_PACKED { \ + uint16_t wNumSubRanges; \ + struct TU_ATTR_PACKED { \ + int16_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\ + int16_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\ + uint16_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\ + } subrange[numSubRanges]; \ +} + +// 5.2.3.3 4-byte Control RANGE Parameter Block +#define audio_control_range_4_n_t(numSubRanges) \ + struct TU_ATTR_PACKED { \ + uint16_t wNumSubRanges; \ + struct TU_ATTR_PACKED { \ + int32_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\ + int32_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\ + uint32_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\ + } subrange[numSubRanges]; \ +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/class/audio/audio_device.c b/circuitpython/lib/tinyusb/src/class/audio/audio_device.c new file mode 100644 index 0000000..06979b0 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/audio/audio_device.c @@ -0,0 +1,2294 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Reinhard Panhuber, Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* + * This driver supports at most one out EP, one in EP, one control EP, and one feedback EP and one alternative interface other than zero. Hence, only one input terminal and one output terminal are support, if you need more adjust the driver! + * It supports multiple TX and RX channels. + * + * In case you need more alternate interfaces, you need to define additional defines for this specific alternate interface. Just define them and set them in the set_interface function. + * + * There are three data flow structures currently implemented, where at least one SW-FIFO is used to decouple the asynchronous processes MCU vs. host + * + * 1. Input data -> SW-FIFO -> MCU USB + * + * The most easiest version, available in case the target MCU can handle the software FIFO (SW-FIFO) and if it is implemented in the device driver (if yes then dcd_edpt_xfer_fifo() is available) + * + * 2. Input data -> SW-FIFO -> Linear buffer -> MCU USB + * + * In case the target MCU can not handle a SW-FIFO, a linear buffer is used. This uses the default function dcd_edpt_xfer(). In this case more memory is required. + * + * 3. (Input data 1 | Input data 2 | ... | Input data N) -> (SW-FIFO 1 | SW-FIFO 2 | ... | SW-FIFO N) -> Linear buffer -> MCU USB + * + * This case is used if you have more channels which need to be combined into one stream. Every channel has its own SW-FIFO. All data is encoded into an Linear buffer. + * + * The same holds in the RX case. + * + * */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_AUDIO) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "audio_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// Use ring buffer if it's available, some MCUs need extra RAM requirements +#ifndef TUD_AUDIO_PREFER_RING_BUFFER +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#define TUD_AUDIO_PREFER_RING_BUFFER 0 +#else +#define TUD_AUDIO_PREFER_RING_BUFFER 1 +#endif +#endif + +// Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer +// is available or driver is would need to be changed dramatically + +// Only STM32 synopsys and dcd_transdimension use non-linear buffer for now +// Synopsys detection copied from dcd_synopsys.c (refactor later on) +#if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ + defined (STM32F107xB) || defined (STM32F107xC) +#define STM32F1_SYNOPSYS +#endif + +#if defined (STM32L475xx) || defined (STM32L476xx) || \ + defined (STM32L485xx) || defined (STM32L486xx) || defined (STM32L496xx) || \ + defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ + defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) +#define STM32L4_SYNOPSYS +#endif + +#if (CFG_TUSB_MCU == OPT_MCU_STM32F1 && defined(STM32F1_SYNOPSYS)) || \ + CFG_TUSB_MCU == OPT_MCU_STM32F2 || \ + CFG_TUSB_MCU == OPT_MCU_STM32F4 || \ + CFG_TUSB_MCU == OPT_MCU_STM32F7 || \ + CFG_TUSB_MCU == OPT_MCU_STM32H7 || \ + (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) || \ + CFG_TUSB_MCU == OPT_MCU_RX63X || \ + CFG_TUSB_MCU == OPT_MCU_RX65X || \ + CFG_TUSB_MCU == OPT_MCU_RX72N || \ + CFG_TUSB_MCU == OPT_MCU_GD32VF103 || \ + CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ + CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ + CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ + CFG_TUSB_MCU == OPT_MCU_MSP432E4 +#if TUD_AUDIO_PREFER_RING_BUFFER +#define USE_LINEAR_BUFFER 0 +#else +#define USE_LINEAR_BUFFER 1 +#endif +#else +#define USE_LINEAR_BUFFER 1 +#endif + +// Declaration of buffers + +// Check for maximum supported numbers +#if CFG_TUD_AUDIO > 3 +#error Maximum number of audio functions restricted to three! +#endif + +// EP IN software buffers and mutexes +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING +#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t ep_in_ff_mutex_wr_1; // No need for read mutex as only USB driver reads from FIFO +#endif +#endif // CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t ep_in_ff_mutex_wr_2; // No need for read mutex as only USB driver reads from FIFO +#endif +#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t ep_in_ff_mutex_wr_3; // No need for read mutex as only USB driver reads from FIFO +#endif +#endif // CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0 +#endif // CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + +// Linear buffer TX in case: +// - target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR +// - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into +#if CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_ENCODING) +#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX]; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX]; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX]; +#endif +#endif // CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) + +// EP OUT software buffers and mutexes +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING +#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t ep_out_ff_mutex_rd_1; // No need for write mutex as only USB driver writes into FIFO +#endif +#endif // CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t ep_out_ff_mutex_rd_2; // No need for write mutex as only USB driver writes into FIFO +#endif +#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t ep_out_ff_mutex_rd_3; // No need for write mutex as only USB driver writes into FIFO +#endif +#endif // CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0 +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING + +// Linear buffer RX in case: +// - target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR +// - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) +#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX]; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX]; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX]; +#endif +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) + +// Control buffers +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ]; +#if CFG_TUD_AUDIO > 1 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ]; +#endif +#if CFG_TUD_AUDIO > 2 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ]; +#endif + +// Active alternate setting of interfaces +uint8_t alt_setting_1[CFG_TUD_AUDIO_FUNC_1_N_AS_INT]; +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_N_AS_INT > 0 +uint8_t alt_setting_2[CFG_TUD_AUDIO_FUNC_2_N_AS_INT]; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_N_AS_INT > 0 +uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT]; +#endif + +// Software encoding/decoding support FIFOs +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING +#if CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ]; +tu_fifo_t tx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t tx_supp_ff_mutex_wr_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO +#endif +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ]; +tu_fifo_t tx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t tx_supp_ff_mutex_wr_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO +#endif +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ]; +tu_fifo_t tx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t tx_supp_ff_mutex_wr_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO +#endif +#endif +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING +#if CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ]; +tu_fifo_t rx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t rx_supp_ff_mutex_rd_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO +#endif +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ]; +tu_fifo_t rx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t rx_supp_ff_mutex_rd_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO +#endif +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ > 0 +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ]; +tu_fifo_t rx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; +#if CFG_FIFO_MUTEX +osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO +#endif +#endif +#endif + +typedef struct +{ + uint8_t rhport; + uint8_t const * p_desc; // Pointer pointing to Standard AC Interface Descriptor(4.7.1) - Audio Control descriptor defining audio function + +#if CFG_TUD_AUDIO_ENABLE_EP_IN + uint8_t ep_in; // TX audio data EP. + uint16_t ep_in_sz; // Current size of TX EP + uint8_t ep_in_as_intf_num; // Corresponding Standard AS Interface Descriptor (4.9.1) belonging to output terminal to which this EP belongs - 0 is invalid (this fits to UAC2 specification since AS interfaces can not have interface number equal to zero) +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT + uint8_t ep_out; // Incoming (into uC) audio data EP. + uint16_t ep_out_sz; // Current size of RX EP + uint8_t ep_out_as_intf_num; // Corresponding Standard AS Interface Descriptor (4.9.1) belonging to input terminal to which this EP belongs - 0 is invalid (this fits to UAC2 specification since AS interfaces can not have interface number equal to zero) + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + uint8_t ep_fb; // Feedback EP. +#endif + +#endif + +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN + uint8_t ep_int_ctr; // Audio control interrupt EP. +#endif + + /*------------- From this point, data is not cleared by bus reset -------------*/ + + uint16_t desc_length; // Length of audio function descriptor + + // Buffer for control requests + uint8_t * ctrl_buf; + uint8_t ctrl_buf_sz; + + // Current active alternate settings + uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP! + + // EP Transfer buffers and FIFOs +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +#if !CFG_TUD_AUDIO_ENABLE_DECODING + tu_fifo_t ep_out_ff; +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). +#endif +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + tu_fifo_t ep_in_ff; +#endif + + // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN + CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; +#endif + + // Decoding parameters - parameters are set when alternate AS interface is set by host + // Coding is currently only supported for EP. Software coding corresponding to AS interfaces without EPs are not supported currently. +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING + audio_format_type_t format_type_rx; + uint8_t n_channels_rx; + +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + audio_data_format_type_I_t format_type_I_rx; + uint8_t n_bytes_per_sampe_rx; + uint8_t n_channels_per_ff_rx; + uint8_t n_ff_used_rx; +#endif +#endif + + // Encoding parameters - parameters are set when alternate AS interface is set by host +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING + audio_format_type_t format_type_tx; + uint8_t n_channels_tx; + +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + audio_data_format_type_I_t format_type_I_tx; + uint8_t n_bytes_per_sampe_tx; + uint8_t n_channels_per_ff_tx; + uint8_t n_ff_used_tx; +#endif +#endif + + // Support FIFOs for software encoding and decoding +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING + tu_fifo_t * rx_supp_ff; + uint8_t n_rx_supp_ff; + uint16_t rx_supp_ff_sz_max; +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING + tu_fifo_t * tx_supp_ff; + uint8_t n_tx_supp_ff; + uint16_t tx_supp_ff_sz_max; +#endif + + // Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR the support FIFOs are used +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) + uint8_t * lin_buf_out; +#define USE_LINEAR_BUFFER_RX 1 +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_ENCODING) + uint8_t * lin_buf_in; +#define USE_LINEAR_BUFFER_TX 1 +#endif + +} audiod_function_t; + +#ifndef USE_LINEAR_BUFFER_TX +#define USE_LINEAR_BUFFER_TX 0 +#endif + +#ifndef USE_LINEAR_BUFFER_RX +#define USE_LINEAR_BUFFER_RX 0 +#endif + +#define ITF_MEM_RESET_SIZE offsetof(audiod_function_t, ctrl_buf) + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION audiod_function_t _audiod_fct[CFG_TUD_AUDIO]; + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received); +#endif + +#if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT +static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN +static bool audiod_tx_done_cb(uint8_t rhport, audiod_function_t* audio); +#endif + +#if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_EP_IN +static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audio); +#endif + +static bool audiod_get_interface(uint8_t rhport, tusb_control_request_t const * p_request); +static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * p_request); + +static bool audiod_get_AS_interface_index_global(uint8_t itf, uint8_t *func_id, uint8_t *idxItf, uint8_t const **pp_desc_int); +static bool audiod_get_AS_interface_index(uint8_t itf, audiod_function_t * audio, uint8_t *idxItf, uint8_t const **pp_desc_int); +static bool audiod_verify_entity_exists(uint8_t itf, uint8_t entityID, uint8_t *func_id); +static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id); +static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id); +static uint8_t audiod_get_audio_fct_idx(audiod_function_t * audio); + +#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING +static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * p_desc, uint8_t const * p_desc_end, uint8_t const as_itf); + +static inline uint8_t tu_desc_subtype(void const* desc) +{ + return ((uint8_t const*) desc)[2]; +} +#endif + +bool tud_audio_n_mounted(uint8_t func_id) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO); + audiod_function_t* audio = &_audiod_fct[func_id]; + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT + if (audio->ep_out == 0) return false; +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN + if (audio->ep_in == 0) return false; +#endif + +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN + if (audio->ep_int_ctr == 0) return false; +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + if (audio->ep_fb == 0) return false; +#endif + + return true; +} + +//--------------------------------------------------------------------+ +// READ API +//--------------------------------------------------------------------+ + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING + +uint16_t tud_audio_n_available(uint8_t func_id) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + return tu_fifo_count(&_audiod_fct[func_id].ep_out_ff); +} + +uint16_t tud_audio_n_read(uint8_t func_id, void* buffer, uint16_t bufsize) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + return tu_fifo_read_n(&_audiod_fct[func_id].ep_out_ff, buffer, bufsize); +} + +bool tud_audio_n_clear_ep_out_ff(uint8_t func_id) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + return tu_fifo_clear(&_audiod_fct[func_id].ep_out_ff); +} + +tu_fifo_t* tud_audio_n_get_ep_out_ff(uint8_t func_id) +{ + if(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL) return &_audiod_fct[func_id].ep_out_ff; + return NULL; +} + +#endif + +#if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT +// Delete all content in the support RX FIFOs +bool tud_audio_n_clear_rx_support_ff(uint8_t func_id, uint8_t ff_idx) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_rx_supp_ff); + return tu_fifo_clear(&_audiod_fct[func_id].rx_supp_ff[ff_idx]); +} + +uint16_t tud_audio_n_available_support_ff(uint8_t func_id, uint8_t ff_idx) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_rx_supp_ff); + return tu_fifo_count(&_audiod_fct[func_id].rx_supp_ff[ff_idx]); +} + +uint16_t tud_audio_n_read_support_ff(uint8_t func_id, uint8_t ff_idx, void* buffer, uint16_t bufsize) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_rx_supp_ff); + return tu_fifo_read_n(&_audiod_fct[func_id].rx_supp_ff[ff_idx], buffer, bufsize); +} + +tu_fifo_t* tud_audio_n_get_rx_support_ff(uint8_t func_id, uint8_t ff_idx) +{ + if(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_rx_supp_ff) return &_audiod_fct[func_id].rx_supp_ff[ff_idx]; + return NULL; +} +#endif + +// This function is called once an audio packet is received by the USB and is responsible for putting data from USB memory into EP_OUT_FIFO (or support FIFOs + decoding of received stream into audio channels). +// If you prefer your own (more efficient) implementation suiting your purpose set CFG_TUD_AUDIO_ENABLE_DECODING = 0. + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT + +static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received) +{ + uint8_t idxItf; + uint8_t const *dummy2; + uint8_t idx_audio_fct = 0; + + if (tud_audio_rx_done_pre_read_cb || tud_audio_rx_done_post_read_cb) + { + idx_audio_fct = audiod_get_audio_fct_idx(audio); + TU_VERIFY(audiod_get_AS_interface_index(audio->ep_out_as_intf_num, audio, &idxItf, &dummy2)); + } + + // Call a weak callback here - a possibility for user to get informed an audio packet was received and data gets now loaded into EP FIFO (or decoded into support RX software FIFO) + if (tud_audio_rx_done_pre_read_cb) TU_VERIFY(tud_audio_rx_done_pre_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + +#if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT + + switch (audio->format_type_rx) + { + case AUDIO_FORMAT_TYPE_UNDEFINED: + // INDIVIDUAL DECODING PROCEDURE REQUIRED HERE! + TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT encoding not implemented!\r\n"); + TU_BREAKPOINT(); + break; + + case AUDIO_FORMAT_TYPE_I: + + switch (audio->format_type_I_tx) + { + case AUDIO_DATA_FORMAT_TYPE_I_PCM: + TU_VERIFY(audiod_decode_type_I_pcm(rhport, audio, n_bytes_received)); + break; + + default: + // DESIRED CFG_TUD_AUDIO_FORMAT_TYPE_I_RX NOT IMPLEMENTED! + TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT_TYPE_I_RX encoding not implemented!\r\n"); + TU_BREAKPOINT(); + break; + } + break; + + default: + // Desired CFG_TUD_AUDIO_FORMAT_TYPE_RX not implemented! + TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT_TYPE_RX not implemented!\r\n"); + TU_BREAKPOINT(); + break; + } + + // Prepare for next transmission + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); + +#else + +#if USE_LINEAR_BUFFER_RX + // Data currently is in linear buffer, copy into EP OUT FIFO + TU_VERIFY(tu_fifo_write_n(&audio->ep_out_ff, audio->lin_buf_out, n_bytes_received)); + + // Schedule for next receive + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); +#else + // Data is already placed in EP FIFO, schedule for next receive + TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz), false); +#endif + +#endif + + // Call a weak callback here - a possibility for user to get informed decoding was completed + if (tud_audio_rx_done_post_read_cb) TU_VERIFY(tud_audio_rx_done_post_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + + return true; +} + +#endif //CFG_TUD_AUDIO_ENABLE_EP_OUT + +// The following functions are used in case CFG_TUD_AUDIO_ENABLE_DECODING != 0 +#if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT + +// Decoding according to 2.3.1.5 Audio Streams + +// Helper function +static inline uint8_t * audiod_interleaved_copy_bytes_fast_decode(uint16_t const nBytesToCopy, void * dst, uint8_t * dst_end, uint8_t * src, uint8_t const n_ff_used) +{ + + // This function is an optimized version of + // while((uint8_t *)dst < dst_end) + // { + // memcpy(dst, src, nBytesToCopy); + // dst = (uint8_t *)dst + nBytesToCopy; + // src += nBytesToCopy * n_ff_used; + // } + + // Optimize for fast half word copies + typedef struct{ + uint16_t val; + } __attribute((__packed__)) unaligned_uint16_t; + + // Optimize for fast word copies + typedef struct{ + uint32_t val; + } __attribute((__packed__)) unaligned_uint32_t; + + switch (nBytesToCopy) + { + case 1: + while((uint8_t *)dst < dst_end) + { + *(uint8_t *)dst++ = *src; + src += n_ff_used; + } + break; + + case 2: + while((uint8_t *)dst < dst_end) + { + *(unaligned_uint16_t*)dst = *(unaligned_uint16_t*)src; + dst += 2; + src += 2 * n_ff_used; + } + break; + + case 3: + while((uint8_t *)dst < dst_end) + { + // memcpy(dst, src, 3); + // dst = (uint8_t *)dst + 3; + // src += 3 * n_ff_used; + + // TODO: Is there a faster way to copy 3 bytes? + *(uint8_t *)dst++ = *src++; + *(uint8_t *)dst++ = *src++; + *(uint8_t *)dst++ = *src++; + + src += 3 * (n_ff_used - 1); + } + break; + + case 4: + while((uint8_t *)dst < dst_end) + { + *(unaligned_uint32_t*)dst = *(unaligned_uint32_t*)src; + dst += 4; + src += 4 * n_ff_used; + } + break; + } + + return src; +} + +static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received) +{ + (void) rhport; + + // Determine amount of samples + uint8_t const n_ff_used = audio->n_ff_used_rx; + uint16_t const nBytesPerFFToRead = n_bytes_received / n_ff_used; + uint8_t cnt_ff; + + // Decode + uint8_t * src; + uint8_t * dst_end; + + tu_fifo_buffer_info_t info; + + for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) + { + tu_fifo_get_write_info(&audio->rx_supp_ff[cnt_ff], &info); + + if (info.len_lin != 0) + { + info.len_lin = tu_min16(nBytesPerFFToRead, info.len_lin); + src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; + dst_end = info.ptr_lin + info.len_lin; + src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_lin, dst_end, src, n_ff_used); + + // Handle wrapped part of FIFO + info.len_wrap = tu_min16(nBytesPerFFToRead - info.len_lin, info.len_wrap); + if (info.len_wrap != 0) + { + dst_end = info.ptr_wrap + info.len_wrap; + audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_wrap, dst_end, src, n_ff_used); + } + tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); + } + } + + // Number of bytes should be a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX but checking makes no sense - no way to correct it + // TU_VERIFY(cnt != n_bytes); + + return true; +} +#endif //CFG_TUD_AUDIO_ENABLE_DECODING + +//--------------------------------------------------------------------+ +// WRITE API +//--------------------------------------------------------------------+ + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + +/** + * \brief Write data to EP in buffer + * + * Write data to buffer. If it is full, new data can be inserted once a transmit was scheduled. See audiod_tx_done_cb(). + * If TX FIFOs are used, this function is not available in order to not let the user mess up the encoding process. + * + * \param[in] func_id: Index of audio function interface + * \param[in] data: Pointer to data array to be copied from + * \param[in] len: # of array elements to copy + * \return Number of bytes actually written + */ +uint16_t tud_audio_n_write(uint8_t func_id, const void * data, uint16_t len) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + return tu_fifo_write_n(&_audiod_fct[func_id].ep_in_ff, data, len); +} + +bool tud_audio_n_clear_ep_in_ff(uint8_t func_id) // Delete all content in the EP IN FIFO +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + return tu_fifo_clear(&_audiod_fct[func_id].ep_in_ff); +} + +tu_fifo_t* tud_audio_n_get_ep_in_ff(uint8_t func_id) +{ + if(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL) return &_audiod_fct[func_id].ep_in_ff; + return NULL; +} + +#endif + +#if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_EP_IN + +uint16_t tud_audio_n_flush_tx_support_ff(uint8_t func_id) // Force all content in the support TX FIFOs to be written into linear buffer and schedule a transmit +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + audiod_function_t* audio = &_audiod_fct[func_id]; + + uint16_t n_bytes_copied = tu_fifo_count(&audio->tx_supp_ff[0]); + + TU_VERIFY(audiod_tx_done_cb(audio->rhport, audio)); + + n_bytes_copied -= tu_fifo_count(&audio->tx_supp_ff[0]); + n_bytes_copied = n_bytes_copied*audio->tx_supp_ff[0].item_size; + + return n_bytes_copied; +} + +bool tud_audio_n_clear_tx_support_ff(uint8_t func_id, uint8_t ff_idx) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_tx_supp_ff); + return tu_fifo_clear(&_audiod_fct[func_id].tx_supp_ff[ff_idx]); +} + +uint16_t tud_audio_n_write_support_ff(uint8_t func_id, uint8_t ff_idx, const void * data, uint16_t len) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_tx_supp_ff); + return tu_fifo_write_n(&_audiod_fct[func_id].tx_supp_ff[ff_idx], data, len); +} + +tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx) +{ + if(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_tx_supp_ff) return &_audiod_fct[func_id].tx_supp_ff[ff_idx]; + return NULL; +} + +#endif + + +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN + +// If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_ctr_done_cb() is called in inform user +uint16_t tud_audio_int_ctr_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + + // We write directly into the EP's buffer - abort if previous transfer not complete + TU_VERIFY(!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int_ctr)); + + // Check length + TU_VERIFY(len <= CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE); + + memcpy(_audiod_fct[func_id].ep_int_ctr_buf, buffer, len); + + // Schedule transmit + TU_VERIFY(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int_ctr, _audiod_fct[func_id].ep_int_ctr_buf, len)); + + return true; +} + +#endif + + +// This function is called once a transmit of an audio packet was successfully completed. Here, we encode samples and place it in IN EP's buffer for next transmission. +// If you prefer your own (more efficient) implementation suiting your purpose set CFG_TUD_AUDIO_ENABLE_ENCODING = 0 and use tud_audio_n_write. + +// n_bytes_copied - Informs caller how many bytes were loaded. In case n_bytes_copied = 0, a ZLP is scheduled to inform host no data is available for current frame. +#if CFG_TUD_AUDIO_ENABLE_EP_IN +static bool audiod_tx_done_cb(uint8_t rhport, audiod_function_t * audio) +{ + uint8_t idxItf; + uint8_t const *dummy2; + + uint8_t idx_audio_fct = audiod_get_audio_fct_idx(audio); + TU_VERIFY(audiod_get_AS_interface_index(audio->ep_in_as_intf_num, audio, &idxItf, &dummy2)); + + // Only send something if current alternate interface is not 0 as in this case nothing is to be sent due to UAC2 specifications + if (audio->alt_setting[idxItf] == 0) return false; + + // Call a weak callback here - a possibility for user to get informed former TX was completed and data gets now loaded into EP in buffer (in case FIFOs are used) or + // if no FIFOs are used the user may use this call back to load its data into the EP IN buffer by use of tud_audio_n_write_ep_in_buffer(). + if (tud_audio_tx_done_pre_load_cb) TU_VERIFY(tud_audio_tx_done_pre_load_cb(rhport, idx_audio_fct, audio->ep_in, audio->alt_setting[idxItf])); + + // Send everything in ISO EP FIFO + uint16_t n_bytes_tx; + + // If support FIFOs are used, encode and schedule transmit +#if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_EP_IN + switch (audio->format_type_tx) + { + case AUDIO_FORMAT_TYPE_UNDEFINED: + // INDIVIDUAL ENCODING PROCEDURE REQUIRED HERE! + TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT encoding not implemented!\r\n"); + TU_BREAKPOINT(); + n_bytes_tx = 0; + break; + + case AUDIO_FORMAT_TYPE_I: + + switch (audio->format_type_I_tx) + { + case AUDIO_DATA_FORMAT_TYPE_I_PCM: + + n_bytes_tx = audiod_encode_type_I_pcm(rhport, audio); + break; + + default: + // YOUR ENCODING IS REQUIRED HERE! + TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT_TYPE_I_TX encoding not implemented!\r\n"); + TU_BREAKPOINT(); + n_bytes_tx = 0; + break; + } + break; + + default: + // Desired CFG_TUD_AUDIO_FORMAT_TYPE_TX not implemented! + TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT_TYPE_TX not implemented!\r\n"); + TU_BREAKPOINT(); + n_bytes_tx = 0; + break; + } + + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, n_bytes_tx)); + +#else + // No support FIFOs, if no linear buffer required schedule transmit, else put data into linear buffer and schedule + + n_bytes_tx = tu_min16(tu_fifo_count(&audio->ep_in_ff), audio->ep_in_sz); // Limit up to max packet size, more can not be done for ISO + +#if USE_LINEAR_BUFFER_TX + tu_fifo_read_n(&audio->ep_in_ff, audio->lin_buf_in, n_bytes_tx); + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, n_bytes_tx)); +#else + // Send everything in ISO EP FIFO + TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_in, &audio->ep_in_ff, n_bytes_tx)); +#endif + +#endif + + // Call a weak callback here - a possibility for user to get informed former TX was completed and how many bytes were loaded for the next frame + if (tud_audio_tx_done_post_load_cb) TU_VERIFY(tud_audio_tx_done_post_load_cb(rhport, n_bytes_tx, idx_audio_fct, audio->ep_in, audio->alt_setting[idxItf])); + + return true; +} + +#endif //CFG_TUD_AUDIO_ENABLE_EP_IN + +#if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_EP_IN +// Take samples from the support buffer and encode them into the IN EP software FIFO +// Returns number of bytes written into linear buffer + +/* 2.3.1.7.1 PCM Format +The PCM (Pulse Coded Modulation) format is the most commonly used audio format to represent audio +data streams. The audio data is not compressed and uses a signed two’s-complement fixed point format. It +is left-justified (the sign bit is the Msb) and data is padded with trailing zeros to fill the remaining unused +bits of the subslot. The binary point is located to the right of the sign bit so that all values lie within the +range [-1, +1) + */ + +/* + * This function encodes channels saved within the support FIFOs into one stream by interleaving the PCM samples + * in the support FIFOs according to 2.3.1.5 Audio Streams. It does not control justification (left or right) and + * does not change the number of bytes per sample. + * */ + +// Helper function +static inline uint8_t * audiod_interleaved_copy_bytes_fast_encode(uint16_t const nBytesToCopy, uint8_t * src, uint8_t * src_end, uint8_t * dst, uint8_t const n_ff_used) +{ + // Optimize for fast half word copies + typedef struct{ + uint16_t val; + } __attribute((__packed__)) unaligned_uint16_t; + + // Optimize for fast word copies + typedef struct{ + uint32_t val; + } __attribute((__packed__)) unaligned_uint32_t; + + switch (nBytesToCopy) + { + case 1: + while(src < src_end) + { + *dst = *src++; + dst += n_ff_used; + } + break; + + case 2: + while(src < src_end) + { + *(unaligned_uint16_t*)dst = *(unaligned_uint16_t*)src; + src += 2; + dst += 2 * n_ff_used; + } + break; + + case 3: + while(src < src_end) + { + // memcpy(dst, src, 3); + // src = (uint8_t *)src + 3; + // dst += 3 * n_ff_used; + + // TODO: Is there a faster way to copy 3 bytes? + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + + dst += 3 * (n_ff_used - 1); + } + break; + + case 4: + while(src < src_end) + { + *(unaligned_uint32_t*)dst = *(unaligned_uint32_t*)src; + src += 4; + dst += 4 * n_ff_used; + } + break; + } + + return dst; +} + +static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audio) +{ + // This function relies on the fact that the length of the support FIFOs was configured to be a multiple of the active sample size in bytes s.t. no sample is split within a wrap + // This is ensured within set_interface, where the FIFOs are reconfigured according to this size + + // We encode directly into IN EP's linear buffer - abort if previous transfer not complete + TU_VERIFY(!usbd_edpt_busy(rhport, audio->ep_in)); + + // Determine amount of samples + uint8_t const n_ff_used = audio->n_ff_used_tx; + uint16_t const nBytesToCopy = audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx; + uint16_t const capPerFF = audio->ep_in_sz / n_ff_used; // Sample capacity per FIFO in bytes + uint16_t nBytesPerFFToSend = tu_fifo_count(&audio->tx_supp_ff[0]); + uint8_t cnt_ff; + + for (cnt_ff = 1; cnt_ff < n_ff_used; cnt_ff++) + { + uint16_t const count = tu_fifo_count(&audio->tx_supp_ff[cnt_ff]); + if (count < nBytesPerFFToSend) + { + nBytesPerFFToSend = count; + } + } + + // Check if there is enough + if (nBytesPerFFToSend == 0) return 0; + + // Limit to maximum sample number - THIS IS A POSSIBLE ERROR SOURCE IF TOO MANY SAMPLE WOULD NEED TO BE SENT BUT CAN NOT! + nBytesPerFFToSend = tu_min16(nBytesPerFFToSend, capPerFF); + + // Round to full number of samples (flooring) + nBytesPerFFToSend = (nBytesPerFFToSend / nBytesToCopy) * nBytesToCopy; + + // Encode + uint8_t * dst; + uint8_t * src_end; + + tu_fifo_buffer_info_t info; + + for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) + { + dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx]; + + tu_fifo_get_read_info(&audio->tx_supp_ff[cnt_ff], &info); + + if (info.len_lin != 0) + { + info.len_lin = tu_min16(nBytesPerFFToSend, info.len_lin); // Limit up to desired length + src_end = (uint8_t *)info.ptr_lin + info.len_lin; + dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_lin, src_end, dst, n_ff_used); + + // Limit up to desired length + info.len_wrap = tu_min16(nBytesPerFFToSend - info.len_lin, info.len_wrap); + + // Handle wrapped part of FIFO + if (info.len_wrap != 0) + { + src_end = (uint8_t *)info.ptr_wrap + info.len_wrap; + audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_wrap, src_end, dst, n_ff_used); + } + + tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); + } + } + + return nBytesPerFFToSend * n_ff_used; +} +#endif //CFG_TUD_AUDIO_ENABLE_ENCODING + +// This function is called once a transmit of a feedback packet was successfully completed. Here, we get the next feedback value to be sent + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio) +{ + return usbd_edpt_xfer(rhport, audio->ep_fb, (uint8_t *) &audio->fb_val, 4); +} +#endif + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void audiod_init(void) +{ + tu_memclr(_audiod_fct, sizeof(_audiod_fct)); + + for(uint8_t i=0; ictrl_buf = ctrl_buf_1; + audio->ctrl_buf_sz = CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ; + break; +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ > 0 + case 1: + audio->ctrl_buf = ctrl_buf_2; + audio->ctrl_buf_sz = CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ; + break; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ > 0 + case 2: + audio->ctrl_buf = ctrl_buf_3; + audio->ctrl_buf_sz = CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ; + break; +#endif + } + + // Initialize active alternate interface buffers + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_N_AS_INT > 0 + case 0: + audio->alt_setting = alt_setting_1; + break; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_N_AS_INT > 0 + case 1: + audio->alt_setting = alt_setting_2; + break; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_N_AS_INT > 0 + case 2: + audio->alt_setting = alt_setting_3; + break; +#endif + } + + // Initialize IN EP FIFO if required +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 + case 0: + tu_fifo_config(&audio->ep_in_ff, audio_ep_in_sw_buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&audio->ep_in_ff, osal_mutex_create(&ep_in_ff_mutex_wr_1), NULL); +#endif + break; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 + case 1: + tu_fifo_config(&audio->ep_in_ff, audio_ep_in_sw_buf_2, CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&audio->ep_in_ff, osal_mutex_create(&ep_in_ff_mutex_wr_2), NULL); +#endif + break; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0 + case 2: + tu_fifo_config(&audio->ep_in_ff, audio_ep_in_sw_buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&audio->ep_in_ff, osal_mutex_create(&ep_in_ff_mutex_wr_3), NULL); +#endif + break; +#endif + } +#endif // CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + + // Initialize linear buffers +#if USE_LINEAR_BUFFER_TX + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0 + case 0: + audio->lin_buf_in = lin_buf_in_1; + break; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0 + case 1: + audio->lin_buf_in = lin_buf_in_2; + break; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0 + case 2: + audio->lin_buf_in = lin_buf_in_3; + break; +#endif + } +#endif // USE_LINEAR_BUFFER_TX + + // Initialize OUT EP FIFO if required +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING + + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 + case 0: + tu_fifo_config(&audio->ep_out_ff, audio_ep_out_sw_buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&audio->ep_out_ff, NULL, osal_mutex_create(&ep_out_ff_mutex_rd_1)); +#endif + break; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 + case 1: + tu_fifo_config(&audio->ep_out_ff, audio_ep_out_sw_buf_2, CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&audio->ep_out_ff, NULL, osal_mutex_create(&ep_out_ff_mutex_rd_2)); +#endif + break; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0 + case 2: + tu_fifo_config(&audio->ep_out_ff, audio_ep_out_sw_buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&audio->ep_out_ff, NULL, osal_mutex_create(&ep_out_ff_mutex_rd_3)); +#endif + break; +#endif + } +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING + + // Initialize linear buffers +#if USE_LINEAR_BUFFER_RX + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0 + case 0: + audio->lin_buf_out = lin_buf_out_1; + break; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0 + case 1: + audio->lin_buf_out = lin_buf_out_2; + break; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0 + case 2: + audio->lin_buf_out = lin_buf_out_3; + break; +#endif + } +#endif // USE_LINEAR_BUFFER_TX + + // Initialize TX support FIFOs if required +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING + + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0 + case 0: + audio->tx_supp_ff = tx_supp_ff_1; + audio->n_tx_supp_ff = CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO; + audio->tx_supp_ff_sz_max = CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ; + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO; cnt++) + { + tu_fifo_config(&tx_supp_ff_1[cnt], tx_supp_ff_buf_1[cnt], CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&tx_supp_ff_1[cnt], osal_mutex_create(&tx_supp_ff_mutex_wr_1[cnt]), NULL); +#endif + } + + break; +#endif // CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0 + +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0 + case 1: + audio->tx_supp_ff = tx_supp_ff_2; + audio->n_tx_supp_ff = CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO; + audio->tx_supp_ff_sz_max = CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ; + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO; cnt++) + { + tu_fifo_config(&tx_supp_ff_2[cnt], tx_supp_ff_buf_2[cnt], CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&tx_supp_ff_2[cnt], osal_mutex_create(&tx_supp_ff_mutex_wr_2[cnt]), NULL); +#endif + } + + break; +#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0 + +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ > 0 + case 2: + audio->tx_supp_ff = tx_supp_ff_3; + audio->n_tx_supp_ff = CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO; + audio->tx_supp_ff_sz_max = CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ; + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO; cnt++) + { + tu_fifo_config(&tx_supp_ff_3[cnt], tx_supp_ff_buf_3[cnt], CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&tx_supp_ff_3[cnt], osal_mutex_create(&tx_supp_ff_mutex_wr_3[cnt]), NULL); +#endif + } + + break; +#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0 + } +#endif // CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING + + // Set encoding parameters for Type_I formats +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0 + case 0: + audio->n_channels_per_ff_tx = CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX; + break; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0 + case 1: + audio->n_channels_per_ff_tx = CFG_TUD_AUDIO_FUNC_2_CHANNEL_PER_FIFO_TX; + break; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ > 0 + case 2: + audio->n_channels_per_ff_tx = CFG_TUD_AUDIO_FUNC_3_CHANNEL_PER_FIFO_TX; + break; +#endif + } +#endif // CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + + // Initialize RX support FIFOs if required +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING + + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ > 0 + case 0: + audio->rx_supp_ff = rx_supp_ff_1; + audio->n_rx_supp_ff = CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO; + audio->rx_supp_ff_sz_max = CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ; + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO; cnt++) + { + tu_fifo_config(&rx_supp_ff_1[cnt], rx_supp_ff_buf_1[cnt], CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&rx_supp_ff_1[cnt], osal_mutex_create(&rx_supp_ff_mutex_rd_1[cnt]), NULL); +#endif + } + + break; +#endif // CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ > 0 + +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0 + case 1: + audio->rx_supp_ff = rx_supp_ff_2; + audio->n_rx_supp_ff = CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO; + audio->rx_supp_ff_sz_max = CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ; + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO; cnt++) + { + tu_fifo_config(&rx_supp_ff_2[cnt], rx_supp_ff_buf_2[cnt], CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&rx_supp_ff_2[cnt], osal_mutex_create(&rx_supp_ff_mutex_rd_2[cnt]), NULL); +#endif + } + + break; +#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0 + +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ > 0 + case 2: + audio->rx_supp_ff = rx_supp_ff_3; + audio->n_rx_supp_ff = CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO; + audio->rx_supp_ff_sz_max = CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ; + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO; cnt++) + { + tu_fifo_config(&rx_supp_ff_3[cnt], rx_supp_ff_buf_3[cnt], CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ, 1, true); +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&rx_supp_ff_3[cnt], osal_mutex_create(&rx_supp_ff_mutex_rd_3[cnt]), NULL); +#endif + } + + break; +#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0 + } +#endif // CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING + + // Set encoding parameters for Type_I formats +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + switch (i) + { +#if CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ > 0 + case 0: + audio->n_channels_per_ff_rx = CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_RX; + break; +#endif +#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0 + case 1: + audio->n_channels_per_ff_rx = CFG_TUD_AUDIO_FUNC_2_CHANNEL_PER_FIFO_RX; + break; +#endif +#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ > 0 + case 2: + audio->n_channels_per_ff_rx = CFG_TUD_AUDIO_FUNC_3_CHANNEL_PER_FIFO_RX; + break; +#endif + } +#endif // CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + } +} + +void audiod_reset(uint8_t rhport) +{ + (void) rhport; + + for(uint8_t i=0; iep_in_ff); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING + tu_fifo_clear(&audio->ep_out_ff); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING + for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) + { + tu_fifo_clear(&audio->tx_supp_ff[cnt]); + } +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING + for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) + { + tu_fifo_clear(&audio->rx_supp_ff[cnt]); + } +#endif + } +} + +uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + (void) max_len; + + TU_VERIFY ( TUSB_CLASS_AUDIO == itf_desc->bInterfaceClass && + AUDIO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass); + + // Verify version is correct - this check can be omitted + TU_VERIFY(itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2); + + // Verify interrupt control EP is enabled if demanded by descriptor - this should be best some static check however - this check can be omitted + if (itf_desc->bNumEndpoints == 1) // 0 or 1 EPs are allowed + { + TU_VERIFY(CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0); + } + + // Alternate setting MUST be zero - this check can be omitted + TU_VERIFY(itf_desc->bAlternateSetting == 0); + + // Find available audio driver interface + uint8_t i; + for (i = 0; i < CFG_TUD_AUDIO; i++) + { + if (!_audiod_fct[i].p_desc) + { + _audiod_fct[i].p_desc = (uint8_t const *)itf_desc; // Save pointer to AC descriptor which is by specification always the first one + _audiod_fct[i].rhport = rhport; + + // Setup descriptor lengths + switch (i) + { + case 0: + _audiod_fct[i].desc_length = CFG_TUD_AUDIO_FUNC_1_DESC_LEN; + break; +#if CFG_TUD_AUDIO > 1 + case 1: + _audiod_fct[i].desc_length = CFG_TUD_AUDIO_FUNC_2_DESC_LEN; + break; +#endif +#if CFG_TUD_AUDIO > 2 + case 2: + _audiod_fct[i].desc_length = CFG_TUD_AUDIO_FUNC_3_DESC_LEN; + break; +#endif + } + + break; + } + } + + // Verify we found a free one + TU_ASSERT( i < CFG_TUD_AUDIO ); + + // This is all we need so far - the EPs are setup by a later set_interface request (as per UAC2 specification) + uint16_t drv_len = _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; // - TUD_AUDIO_DESC_IAD_LEN since tinyUSB already handles the IAD descriptor + + return drv_len; +} + +static bool audiod_get_interface(uint8_t rhport, tusb_control_request_t const * p_request) +{ + uint8_t const itf = tu_u16_low(p_request->wIndex); + + // Find index of audio streaming interface + uint8_t func_id, idxItf; + uint8_t const *dummy; + + TU_VERIFY(audiod_get_AS_interface_index_global(itf, &func_id, &idxItf, &dummy)); + TU_VERIFY(tud_control_xfer(rhport, p_request, &_audiod_fct[func_id].alt_setting[idxItf], 1)); + + TU_LOG2(" Get itf: %u - current alt: %u\r\n", itf, _audiod_fct[func_id].alt_setting[idxItf]); + + return true; +} + +static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Here we need to do the following: + + // 1. Find the audio driver assigned to the given interface to be set + // Since one audio driver interface has to be able to cover an unknown number of interfaces (AC, AS + its alternate settings), the best memory efficient way to solve this is to always search through the descriptors. + // The audio driver is mapped to an audio function by a reference pointer to the corresponding AC interface of this audio function which serves as a starting point for searching + + // 2. Close EPs which are currently open + // To do so it is not necessary to know the current active alternate interface since we already save the current EP addresses - we simply close them + + // 3. Open new EP + + uint8_t const itf = tu_u16_low(p_request->wIndex); + uint8_t const alt = tu_u16_low(p_request->wValue); + + TU_LOG2(" Set itf: %u - alt: %u\r\n", itf, alt); + + // Find index of audio streaming interface and index of interface + uint8_t func_id, idxItf; + uint8_t const *p_desc; + TU_VERIFY(audiod_get_AS_interface_index_global(itf, &func_id, &idxItf, &p_desc)); + + audiod_function_t* audio = &_audiod_fct[func_id]; + + // Look if there is an EP to be closed - for this driver, there are only 3 possible EPs which may be closed (only AS related EPs can be closed, AC EP (if present) is always open) +#if CFG_TUD_AUDIO_ENABLE_EP_IN + if (audio->ep_in_as_intf_num == itf) + { + audio->ep_in_as_intf_num = 0; + usbd_edpt_close(rhport, audio->ep_in); + + // Clear FIFOs, since data is no longer valid +#if !CFG_TUD_AUDIO_ENABLE_ENCODING + tu_fifo_clear(&audio->ep_in_ff); +#else + for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) + { + tu_fifo_clear(&audio->tx_supp_ff[cnt]); + } +#endif + + // Invoke callback - can be used to stop data sampling + if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); + + audio->ep_in = 0; // Necessary? + + } +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT + if (audio->ep_out_as_intf_num == itf) + { + audio->ep_out_as_intf_num = 0; + usbd_edpt_close(rhport, audio->ep_out); + + // Clear FIFOs, since data is no longer valid +#if !CFG_TUD_AUDIO_ENABLE_DECODING + tu_fifo_clear(&audio->ep_out_ff); +#else + for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) + { + tu_fifo_clear(&audio->rx_supp_ff[cnt]); + } +#endif + + // Invoke callback - can be used to stop data sampling + if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); + + audio->ep_out = 0; // Necessary? + + // Close corresponding feedback EP +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + usbd_edpt_close(rhport, audio->ep_fb); + audio->ep_fb = 0; // Necessary? +#endif + } +#endif + + // Save current alternative interface setting + audio->alt_setting[idxItf] = alt; + + // Open new EP if necessary - EPs are only to be closed or opened for AS interfaces - Look for AS interface with correct alternate interface + // Get pointer at end + uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN; + + // p_desc starts at required interface with alternate setting zero + while (p_desc < p_desc_end) + { + // Find correct interface + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == alt) + { +#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING + uint8_t const * p_desc_parse_for_params = p_desc; +#endif + // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary + uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints; + while (foundEPs < nEps && p_desc < p_desc_end) + { + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) + { + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; + TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); + + uint8_t const ep_addr = desc_ep->bEndpointAddress; + + //TODO: We need to set EP non busy since this is not taken care of right now in ep_close() - THIS IS A WORKAROUND! + usbd_edpt_clear_stall(rhport, ep_addr); + +#if CFG_TUD_AUDIO_ENABLE_EP_IN + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 0x00) // Check if usage is data EP + { + // Save address + audio->ep_in = ep_addr; + audio->ep_in_as_intf_num = itf; + audio->ep_in_sz = tu_edpt_packet_size(desc_ep); + + // If software encoding is enabled, parse for the corresponding parameters - doing this here means only AS interfaces with EPs get scanned for parameters +#if CFG_TUD_AUDIO_ENABLE_ENCODING + audiod_parse_for_AS_params(audio, p_desc_parse_for_params, p_desc_end, itf); + + // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + const uint16_t active_fifo_depth = (audio->tx_supp_ff_sz_max / audio->n_bytes_per_sampe_tx) * audio->n_bytes_per_sampe_tx; + for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) + { + tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); + } + audio->n_ff_used_tx = audio->n_channels_tx / audio->n_channels_per_ff_tx; + TU_ASSERT( audio->n_ff_used_tx <= audio->n_tx_supp_ff ); +#endif + +#endif + // Invoke callback - can be used to trigger data sampling if not already running + if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + + // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded + // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there + TU_VERIFY(audiod_tx_done_cb(rhport, &_audiod_fct[func_id])); + } +#endif // CFG_TUD_AUDIO_ENABLE_EP_IN + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) // Checking usage not necessary + { + // Save address + audio->ep_out = ep_addr; + audio->ep_out_as_intf_num = itf; + audio->ep_out_sz = tu_edpt_packet_size(desc_ep); + +#if CFG_TUD_AUDIO_ENABLE_DECODING + audiod_parse_for_AS_params(audio, p_desc_parse_for_params, p_desc_end, itf); + + // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sampe_rx) * audio->n_bytes_per_sampe_rx; + for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) + { + tu_fifo_config(&audio->rx_supp_ff[cnt], audio->rx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); + } + audio->n_ff_used_rx = audio->n_channels_rx / audio->n_channels_per_ff_rx; + TU_ASSERT( audio->n_ff_used_rx <= audio->n_rx_supp_ff ); +#endif +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + // In case of asynchronous EP, call Cb after ep_fb is set + if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) + { + if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + } +#else + // Invoke callback + if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +#endif + // Prepare for incoming data +#if USE_LINEAR_BUFFER_RX + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); +#else + TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz), false); +#endif + } + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback + { + audio->ep_fb = ep_addr; + + // Invoke callback after ep_out is set + if (audio->ep_out != 0) + { + if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + } + } +#endif +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT + + foundEPs += 1; + } + p_desc = tu_desc_next(p_desc); + } + + TU_VERIFY(foundEPs == nEps); + + // We are done - abort loop + break; + } + + // Moving forward + p_desc = tu_desc_next(p_desc); + } + + tud_control_status(rhport, p_request); + + return true; +} + +// Invoked when class request DATA stage is finished. +// return false to stall control EP (e.g Host send non-sense DATA) +static bool audiod_control_complete(uint8_t rhport, tusb_control_request_t const * p_request) +{ + // Handle audio class specific set requests + if(p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS && p_request->bmRequestType_bit.direction == TUSB_DIR_OUT) + { + uint8_t func_id; + + switch (p_request->bmRequestType_bit.recipient) + { + case TUSB_REQ_RCPT_INTERFACE: + { + uint8_t itf = TU_U16_LOW(p_request->wIndex); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + if (entityID != 0) + { + if (tud_audio_set_req_entity_cb) + { + // Check if entity is present and get corresponding driver index + TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); + + // Invoke callback + return tud_audio_set_req_entity_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); + } + else + { + TU_LOG2(" No entity set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it + } + } + else + { + if (tud_audio_set_req_itf_cb) + { + // Find index of audio driver structure and verify interface really exists + TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + + // Invoke callback + return tud_audio_set_req_itf_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); + } + else + { + TU_LOG2(" No interface set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it + } + } + } + break; + + case TUSB_REQ_RCPT_ENDPOINT: + { + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + if (tud_audio_set_req_ep_cb) + { + // Check if entity is present and get corresponding driver index + TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); + + // Invoke callback + return tud_audio_set_req_ep_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); + } + else + { + TU_LOG2(" No EP set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it + } + } + break; + // Unknown/Unsupported recipient + default: TU_BREAKPOINT(); return false; + } + } + return true; +} + +// Handle class control request +// return false to stall control endpoint (e.g unsupported request) +static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Handle standard requests - standard set requests usually have no data stage so we also handle set requests here + if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) + { + switch (p_request->bRequest) + { + case TUSB_REQ_GET_INTERFACE: + return audiod_get_interface(rhport, p_request); + + case TUSB_REQ_SET_INTERFACE: + return audiod_set_interface(rhport, p_request); + + // Unknown/Unsupported request + default: TU_BREAKPOINT(); return false; + } + } + + // Handle class requests + if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) + { + uint8_t itf = TU_U16_LOW(p_request->wIndex); + uint8_t func_id; + + // Conduct checks which depend on the recipient + switch (p_request->bmRequestType_bit.recipient) + { + case TUSB_REQ_RCPT_INTERFACE: + { + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // Verify if entity is present + if (entityID != 0) + { + // Find index of audio driver structure and verify entity really exists + TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); + + // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests + if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) + { + if (tud_audio_get_req_entity_cb) + { + return tud_audio_get_req_entity_cb(rhport, p_request); + } + else + { + TU_LOG2(" No entity get request callback available!\r\n"); + return false; // Stall + } + } + } + else + { + // Find index of audio driver structure and verify interface really exists + TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + + // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests + if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) + { + if (tud_audio_get_req_itf_cb) + { + return tud_audio_get_req_itf_cb(rhport, p_request); + } + else + { + TU_LOG2(" No interface get request callback available!\r\n"); + return false; // Stall + } + } + } + } + break; + + case TUSB_REQ_RCPT_ENDPOINT: + { + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + // Find index of audio driver structure and verify EP really exists + TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); + + // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests + if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) + { + if (tud_audio_get_req_ep_cb) + { + return tud_audio_get_req_ep_cb(rhport, p_request); + } + else + { + TU_LOG2(" No EP get request callback available!\r\n"); + return false; // Stall + } + } + } + break; + + // Unknown/Unsupported recipient + default: TU_LOG2(" Unsupported recipient: %d\r\n", p_request->bmRequestType_bit.recipient); TU_BREAKPOINT(); return false; + } + + // If we end here, the received request is a set request - we schedule a receive for the data stage and return true here. We handle the rest later in audiod_control_complete() once the data stage was finished + TU_VERIFY(tud_control_xfer(rhport, p_request, _audiod_fct[func_id].ctrl_buf, _audiod_fct[func_id].ctrl_buf_sz)); + return true; + } + + // There went something wrong - unsupported control request type + TU_BREAKPOINT(); + return false; +} + +bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + if ( stage == CONTROL_STAGE_SETUP ) + { + return audiod_control_request(rhport, request); + } + else if ( stage == CONTROL_STAGE_DATA ) + { + return audiod_control_complete(rhport, request); + } + + return true; +} + +bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) result; + (void) xferred_bytes; + + // Search for interface belonging to given end point address and proceed as required + uint8_t func_id; + for (func_id = 0; func_id < CFG_TUD_AUDIO; func_id++) + { + +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN + + // Data transmission of control interrupt finished + if (_audiod_fct[func_id].ep_int_ctr == ep_addr) + { + // According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49) + // In case there is nothing to send we have to return a NAK - this is taken care of by PHY ??? + // In case of an erroneous transmission a retransmission is conducted - this is taken care of by PHY ??? + + // I assume here, that things above are handled by PHY + // All transmission is done - what remains to do is to inform job was completed + + if (tud_audio_int_ctr_done_cb) TU_VERIFY(tud_audio_int_ctr_done_cb(rhport, (uint16_t) xferred_bytes)); + } + +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN + + // Data transmission of audio packet finished + if (_audiod_fct[func_id].ep_in == ep_addr && _audiod_fct[func_id].alt_setting != 0) + { + // USB 2.0, section 5.6.4, third paragraph, states "An isochronous endpoint must specify its required bus access period. However, an isochronous endpoint must be prepared to handle poll rates faster than the one specified." + // That paragraph goes on to say "An isochronous IN endpoint must return a zero-length packet whenever data is requested at a faster interval than the specified interval and data is not available." + // This can only be solved reliably if we load a ZLP after every IN transmission since we can not say if the host requests samples earlier than we declared! Once all samples are collected we overwrite the loaded ZLP. + + // Check if there is data to load into EPs buffer - if not load it with ZLP + // Be aware - we as a device are not able to know if the host polls for data with a faster rate as we stated this in the descriptors. Therefore we always have to put something into the EPs buffer. However, once we did that, there is no way of aborting this or replacing what we put into the buffer before! + // This is the only place where we can fill something into the EPs buffer! + + // Load new data + TU_VERIFY(audiod_tx_done_cb(rhport, &_audiod_fct[func_id])); + + // Transmission of ZLP is done by audiod_tx_done_cb() + return true; + } +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT + + // New audio packet received + if (_audiod_fct[func_id].ep_out == ep_addr) + { + TU_VERIFY(audiod_rx_done_cb(rhport, &_audiod_fct[func_id], (uint16_t) xferred_bytes)); + return true; + } + + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + // Transmission of feedback EP finished + if (_audiod_fct[func_id].ep_fb == ep_addr) + { + if (tud_audio_fb_done_cb) TU_VERIFY(tud_audio_fb_done_cb(rhport)); + + // Schedule a transmit with the new value if EP is not busy + if (!usbd_edpt_busy(rhport, _audiod_fct[func_id].ep_fb)) + { + // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent + return audiod_fb_send(rhport, &_audiod_fct[func_id]); + } + } +#endif +#endif + } + + return false; +} + +bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len) +{ + // Handles only sending of data not receiving + if (p_request->bmRequestType_bit.direction == TUSB_DIR_OUT) return false; + + // Get corresponding driver index + uint8_t func_id; + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + // Conduct checks which depend on the recipient + switch (p_request->bmRequestType_bit.recipient) + { + case TUSB_REQ_RCPT_INTERFACE: + { + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // Verify if entity is present + if (entityID != 0) + { + // Find index of audio driver structure and verify entity really exists + TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); + } + else + { + // Find index of audio driver structure and verify interface really exists + TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + } + } + break; + + case TUSB_REQ_RCPT_ENDPOINT: + { + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + // Find index of audio driver structure and verify EP really exists + TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); + } + break; + + // Unknown/Unsupported recipient + default: TU_LOG2(" Unsupported recipient: %d\r\n", p_request->bmRequestType_bit.recipient); TU_BREAKPOINT(); return false; + } + + // Crop length + if (len > _audiod_fct[func_id].ctrl_buf_sz) len = _audiod_fct[func_id].ctrl_buf_sz; + + // Copy into buffer + memcpy((void *)_audiod_fct[func_id].ctrl_buf, data, (size_t)len); + + // Schedule transmit + return tud_control_xfer(rhport, p_request, (void*)_audiod_fct[func_id].ctrl_buf, len); +} + +// This helper function finds for a given audio function and AS interface number the index of the attached driver structure, the index of the interface in the audio function +// (e.g. the std. AS interface with interface number 15 is the first AS interface for the given audio function and thus gets index zero), and +// finally a pointer to the std. AS interface, where the pointer always points to the first alternate setting i.e. alternate interface zero. +static bool audiod_get_AS_interface_index(uint8_t itf, audiod_function_t * audio, uint8_t *idxItf, uint8_t const **pp_desc_int) +{ + if (audio->p_desc) + { + // Get pointer at end + uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN; + + // Advance past AC descriptors + uint8_t const *p_desc = tu_desc_next(audio->p_desc); + p_desc += ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength; + + uint8_t tmp = 0; + while (p_desc < p_desc_end) + { + // We assume the number of alternate settings is increasing thus we return the index of alternate setting zero! + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0) + { + if (((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf) + { + *idxItf = tmp; + *pp_desc_int = p_desc; + return true; + } + // Increase index, bytes read, and pointer + tmp++; + } + p_desc = tu_desc_next(p_desc); + } + } + return false; +} + +// This helper function finds for a given AS interface number the index of the attached driver structure, the index of the interface in the audio function +// (e.g. the std. AS interface with interface number 15 is the first AS interface for the given audio function and thus gets index zero), and +// finally a pointer to the std. AS interface, where the pointer always points to the first alternate setting i.e. alternate interface zero. +static bool audiod_get_AS_interface_index_global(uint8_t itf, uint8_t *func_id, uint8_t *idxItf, uint8_t const **pp_desc_int) +{ + // Loop over audio driver interfaces + uint8_t i; + for (i = 0; i < CFG_TUD_AUDIO; i++) + { + if (audiod_get_AS_interface_index(itf, &_audiod_fct[i], idxItf, pp_desc_int)) + { + *func_id = i; + return true; + } + } + + return false; +} + +// Verify an entity with the given ID exists and returns also the corresponding driver index +static bool audiod_verify_entity_exists(uint8_t itf, uint8_t entityID, uint8_t *func_id) +{ + uint8_t i; + for (i = 0; i < CFG_TUD_AUDIO; i++) + { + // Look for the correct driver by checking if the unique standard AC interface number fits + if (_audiod_fct[i].p_desc && ((tusb_desc_interface_t const *)_audiod_fct[i].p_desc)->bInterfaceNumber == itf) + { + // Get pointers after class specific AC descriptors and end of AC descriptors - entities are defined in between + uint8_t const *p_desc = tu_desc_next(_audiod_fct[i].p_desc); // Points to CS AC descriptor + uint8_t const *p_desc_end = ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength + p_desc; + p_desc = tu_desc_next(p_desc); // Get past CS AC descriptor + + while (p_desc < p_desc_end) + { + if (p_desc[3] == entityID) // Entity IDs are always at offset 3 + { + *func_id = i; + return true; + } + p_desc = tu_desc_next(p_desc); + } + } + } + return false; +} + +static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id) +{ + uint8_t i; + for (i = 0; i < CFG_TUD_AUDIO; i++) + { + if (_audiod_fct[i].p_desc) + { + // Get pointer at beginning and end + uint8_t const *p_desc = _audiod_fct[i].p_desc; + uint8_t const *p_desc_end = _audiod_fct[i].p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; + + while (p_desc < p_desc_end) + { + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const *)_audiod_fct[i].p_desc)->bInterfaceNumber == itf) + { + *func_id = i; + return true; + } + p_desc = tu_desc_next(p_desc); + } + } + } + return false; +} + +static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id) +{ + uint8_t i; + for (i = 0; i < CFG_TUD_AUDIO; i++) + { + if (_audiod_fct[i].p_desc) + { + // Get pointer at end + uint8_t const *p_desc_end = _audiod_fct[i].p_desc + _audiod_fct[i].desc_length; + + // Advance past AC descriptors - EP we look for are streaming EPs + uint8_t const *p_desc = tu_desc_next(_audiod_fct[i].p_desc); + p_desc += ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength; + + while (p_desc < p_desc_end) + { + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT && ((tusb_desc_endpoint_t const * )p_desc)->bEndpointAddress == ep) + { + *func_id = i; + return true; + } + p_desc = tu_desc_next(p_desc); + } + } + } + return false; +} + +#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING +// p_desc points to the AS interface of alternate setting zero +// itf is the interface number of the corresponding interface - we check if the interface belongs to EP in or EP out to see if it is a TX or RX parameter +// Currently, only AS interfaces with an EP (in or out) are supposed to be parsed for! +static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * p_desc, uint8_t const * p_desc_end, uint8_t const as_itf) +{ + p_desc = tu_desc_next(p_desc); // Exclude standard AS interface descriptor of current alternate interface descriptor + + while (p_desc < p_desc_end) + { + // Abort if follow up descriptor is a new standard interface descriptor - indicates the last AS descriptor was already finished + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) break; + + // Look for a Class-Specific AS Interface Descriptor(4.9.2) to verify format type and format and also to get number of physical channels + if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO_CS_AS_INTERFACE_AS_GENERAL) + { +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_in_as_intf_num && as_itf != audio->ep_out_as_intf_num) break; // Abort loop, this interface has no EP, this driver does not support this currently +#endif +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_in_as_intf_num) break; +#endif +#if !CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_out_as_intf_num) break; +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN + if (as_itf == audio->ep_in_as_intf_num) + { + audio->n_channels_tx = ((audio_desc_cs_as_interface_t const * )p_desc)->bNrChannels; + audio->format_type_tx = (audio_format_type_t)(((audio_desc_cs_as_interface_t const * )p_desc)->bFormatType); + +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + audio->format_type_I_tx = (audio_data_format_type_I_t)(((audio_desc_cs_as_interface_t const * )p_desc)->bmFormats); +#endif + } +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf == audio->ep_out_as_intf_num) + { + audio->n_channels_rx = ((audio_desc_cs_as_interface_t const * )p_desc)->bNrChannels; + audio->format_type_rx = ((audio_desc_cs_as_interface_t const * )p_desc)->bFormatType; +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + audio->format_type_I_rx = ((audio_desc_cs_as_interface_t const * )p_desc)->bmFormats; +#endif + } +#endif + } + + // Look for a Type I Format Type Descriptor(2.3.1.6 - Audio Formats) +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING || CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO_CS_AS_INTERFACE_FORMAT_TYPE && ((audio_desc_type_I_format_t const * )p_desc)->bFormatType == AUDIO_FORMAT_TYPE_I) + { +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_in_as_intf_num && as_itf != audio->ep_out_as_intf_num) break; // Abort loop, this interface has no EP, this driver does not support this currently +#endif +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_in_as_intf_num) break; +#endif +#if !CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_out_as_intf_num) break; +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN + if (as_itf == audio->ep_in_as_intf_num) + { + audio->n_bytes_per_sampe_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; + } +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf == audio->ep_out_as_intf_num) + { + audio->n_bytes_per_sampe_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; + } +#endif + } +#endif + + // Other format types are not supported yet + + p_desc = tu_desc_next(p_desc); + } +} +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + +bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + + // Format the feedback value +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION + if ( TUSB_SPEED_FULL == tud_speed_get() ) + { + uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; + + // For FS format is 10.14 + *(fb++) = (feedback >> 2) & 0xFF; + *(fb++) = (feedback >> 10) & 0xFF; + *(fb++) = (feedback >> 18) & 0xFF; + // 4th byte is needed to work correctly with MS Windows + *fb = 0; + }else +#else + { + // Send value as-is, caller will choose the appropriate format + _audiod_fct[func_id].fb_val = feedback; + } +#endif + + // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value + if (!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_fb)) + { + return audiod_fb_send(_audiod_fct[func_id].rhport, &_audiod_fct[func_id]); + } + + return true; +} +#endif + +// No security checks here - internal function only which should always succeed +uint8_t audiod_get_audio_fct_idx(audiod_function_t * audio) +{ + for (uint8_t cnt=0; cnt < CFG_TUD_AUDIO; cnt++) + { + if (&_audiod_fct[cnt] == audio) return cnt; + } + return 0; +} + +#endif //CFG_TUD_ENABLED && CFG_TUD_AUDIO diff --git a/circuitpython/lib/tinyusb/src/class/audio/audio_device.h b/circuitpython/lib/tinyusb/src/class/audio/audio_device.h new file mode 100644 index 0000000..f406cf2 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/audio/audio_device.h @@ -0,0 +1,637 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Ha Thach (tinyusb.org) + * Copyright (c) 2020 Reinhard Panhuber + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_AUDIO_DEVICE_H_ +#define _TUSB_AUDIO_DEVICE_H_ + +#include "audio.h" + +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ + +// All sizes are in bytes! + +#ifndef CFG_TUD_AUDIO_FUNC_1_DESC_LEN +#error You must tell the driver the length of the audio function descriptor including IAD descriptor +#endif +#if CFG_TUD_AUDIO > 1 +#ifndef CFG_TUD_AUDIO_FUNC_2_DESC_LEN +#error You must tell the driver the length of the audio function descriptor including IAD descriptor +#endif +#endif +#if CFG_TUD_AUDIO > 2 +#ifndef CFG_TUD_AUDIO_FUNC_3_DESC_LEN +#error You must tell the driver the length of the audio function descriptor including IAD descriptor +#endif +#endif + +// Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces +#ifndef CFG_TUD_AUDIO_FUNC_1_N_AS_INT +#error You must tell the driver the number of Standard AS Interface Descriptors you have defined in the audio function descriptor! +#endif +#if CFG_TUD_AUDIO > 1 +#ifndef CFG_TUD_AUDIO_FUNC_2_N_AS_INT +#error You must tell the driver the number of Standard AS Interface Descriptors you have defined in the audio function descriptor! +#endif +#endif +#if CFG_TUD_AUDIO > 2 +#ifndef CFG_TUD_AUDIO_FUNC_3_N_AS_INT +#error You must tell the driver the number of Standard AS Interface Descriptors you have defined in the audio function descriptor! +#endif +#endif + +// Size of control buffer used to receive and send control messages via EP0 - has to be big enough to hold your biggest request structure e.g. range requests with multiple intervals defined or cluster descriptors +#ifndef CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ +#error You must define an audio class control request buffer size! +#endif + +#if CFG_TUD_AUDIO > 1 +#ifndef CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ +#error You must define an audio class control request buffer size! +#endif +#endif + +#if CFG_TUD_AUDIO > 2 +#ifndef CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ +#error You must define an audio class control request buffer size! +#endif +#endif + +// End point sizes IN BYTES - Limits: Full Speed <= 1023, High Speed <= 1024 +#ifndef CFG_TUD_AUDIO_ENABLE_EP_IN +#define CFG_TUD_AUDIO_ENABLE_EP_IN 0 // TX +#endif + +#ifndef CFG_TUD_AUDIO_ENABLE_EP_OUT +#define CFG_TUD_AUDIO_ENABLE_EP_OUT 0 // RX +#endif + +// Maximum EP sizes for all alternate AS interface settings - used for checks and buffer allocation +#if CFG_TUD_AUDIO_ENABLE_EP_IN +#ifndef CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX +#error You must tell the driver the biggest EP IN size! +#endif +#if CFG_TUD_AUDIO > 1 +#ifndef CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX +#error You must tell the driver the biggest EP IN size! +#endif +#endif +#if CFG_TUD_AUDIO > 2 +#ifndef CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX +#error You must tell the driver the biggest EP IN size! +#endif +#endif +#endif // CFG_TUD_AUDIO_ENABLE_EP_IN + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +#ifndef CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX +#error You must tell the driver the biggest EP OUT size! +#endif +#if CFG_TUD_AUDIO > 1 +#ifndef CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX +#error You must tell the driver the biggest EP OUT size! +#endif +#endif +#if CFG_TUD_AUDIO > 2 +#ifndef CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX +#error You must tell the driver the biggest EP OUT size! +#endif +#endif +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT + +// Software EP FIFO buffer sizes - must be >= max EP SIZEs! +#ifndef CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ +#define CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ +#define CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ 0 +#endif + +#ifndef CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ +#define CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ +#define CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ 0 +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN +#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX +#error EP software buffer size MUST BE at least as big as maximum EP size +#endif + +#if CFG_TUD_AUDIO > 1 +#if CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX +#error EP software buffer size MUST BE at least as big as maximum EP size +#endif +#endif + +#if CFG_TUD_AUDIO > 2 +#if CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX +#error EP software buffer size MUST BE at least as big as maximum EP size +#endif +#endif +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX +#error EP software buffer size MUST BE at least as big as maximum EP size +#endif + +#if CFG_TUD_AUDIO > 1 +#if CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX +#error EP software buffer size MUST BE at least as big as maximum EP size +#endif +#endif + +#if CFG_TUD_AUDIO > 2 +#if CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX +#error EP software buffer size MUST BE at least as big as maximum EP size +#endif +#endif +#endif + +// Enable/disable feedback EP (required for asynchronous RX applications) +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback - 0 or 1 +#endif + +// Enable/disable conversion from 16.16 to 10.14 format on full-speed devices. See tud_audio_n_fb_set(). +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 +#endif + +// Audio interrupt control EP size - disabled if 0 +#ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) +#endif + +#ifndef CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE +#define CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE 6 // Buffer size of audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74) +#endif + +// Use software encoding/decoding + +// The software coding feature of the driver is not mandatory. It is useful if, for instance, you have two I2S streams which need to be interleaved +// into a single PCM stream as SAMPLE_1 | SAMPLE_2 | SAMPLE_3 | SAMPLE_4. +// +// Currently, only PCM type I encoding/decoding is supported! +// +// If the coding feature is to be used, support FIFOs need to be configured. Their sizes and numbers are defined below. + +// Encoding/decoding is done in software and thus time consuming. If you can encode/decode your stream more efficiently do not use the +// support FIFOs but write/read directly into/from the EP_X_SW_BUFFER_FIFOs using +// - tud_audio_n_write() or +// - tud_audio_n_read(). +// To write/read to/from the support FIFOs use +// - tud_audio_n_write_support_ff() or +// - tud_audio_n_read_support_ff(). +// +// The encoding/decoding format type done is defined below. +// +// The encoding/decoding starts when the private callback functions +// - audio_tx_done_cb() +// - audio_rx_done_cb() +// are invoked. If support FIFOs are used, the corresponding encoding/decoding functions are called from there. +// Once encoding/decoding is done the result is put directly into the EP_X_SW_BUFFER_FIFOs. You can use the public callback functions +// - tud_audio_tx_done_pre_load_cb() or tud_audio_tx_done_post_load_cb() +// - tud_audio_rx_done_pre_read_cb() or tud_audio_rx_done_post_read_cb() +// if you want to get informed what happened. +// +// If you don't use the support FIFOs you may use the public callback functions +// - tud_audio_tx_done_pre_load_cb() or tud_audio_tx_done_post_load_cb() +// - tud_audio_rx_done_pre_read_cb() or tud_audio_rx_done_post_read_cb() +// to write/read from/into the EP_X_SW_BUFFER_FIFOs at the right time. +// +// If you need a different encoding which is not support so far implement it in the +// - audio_tx_done_cb() +// - audio_rx_done_cb() +// functions. + +// Enable encoding/decodings - for these to work, support FIFOs need to be setup in appropriate numbers and size +// The actual coding parameters of active AS alternate interface is parsed from the descriptors + +// The item size of the FIFO is always fixed to one i.e. bytes! Furthermore, the actively used FIFO depth is reconfigured such that the depth is a multiple of the current sample size in order to avoid samples to get split up in case of a wrap in the FIFO ring buffer (depth = (max_depth / sampe_sz) * sampe_sz)! +// This is important to remind in case you use DMAs! If the sample sizes changes, the DMA MUST BE RECONFIGURED just like the FIFOs for a different depth!!! + +// For PCM encoding/decoding + +#ifndef CFG_TUD_AUDIO_ENABLE_ENCODING +#define CFG_TUD_AUDIO_ENABLE_ENCODING 0 +#endif + +#ifndef CFG_TUD_AUDIO_ENABLE_DECODING +#define CFG_TUD_AUDIO_ENABLE_DECODING 0 +#endif + +// This enabling allows to save the current coding parameters e.g. # of bytes per sample etc. - TYPE_I includes common PCM encoding +#ifndef CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING +#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 0 +#endif + +#ifndef CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING +#define CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING 0 +#endif + +// Type I Coding parameters not given within UAC2 descriptors +// It would be possible to allow for a more flexible setting and not fix this parameter as done below. However, this is most often not needed and kept for later if really necessary. The more flexible setting could be implemented within set_interface(), however, how the values are saved per alternate setting is to be determined! +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING +#ifndef CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX +#error You must tell the driver the number of channels per FIFO for the interleaved encoding! E.g. for an I2S interface having two channels, CHANNEL_PER_FIFO = 2 as the I2S stream having two channels is usually saved within one FIFO +#endif +#if CFG_TUD_AUDIO > 1 +#ifndef CFG_TUD_AUDIO_FUNC_2_CHANNEL_PER_FIFO_TX +#error You must tell the driver the number of channels per FIFO for the interleaved encoding! E.g. for an I2S interface having two channels, CHANNEL_PER_FIFO = 2 as the I2S stream having two channels is usually saved within one FIFO +#endif +#endif +#if CFG_TUD_AUDIO > 2 +#ifndef CFG_TUD_AUDIO_FUNC_3_CHANNEL_PER_FIFO_TX +#error You must tell the driver the number of channels per FIFO for the interleaved encoding! E.g. for an I2S interface having two channels, CHANNEL_PER_FIFO = 2 as the I2S stream having two channels is usually saved within one FIFO +#endif +#endif +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING +#ifndef CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_RX +#error You must tell the driver the number of channels per FIFO for the interleaved encoding! E.g. for an I2S interface having two channels, CHANNEL_PER_FIFO = 2 as the I2S stream having two channels is usually saved within one FIFO +#endif +#if CFG_TUD_AUDIO > 1 +#ifndef CFG_TUD_AUDIO_FUNC_2_CHANNEL_PER_FIFO_RX +#error You must tell the driver the number of channels per FIFO for the interleaved encoding! E.g. for an I2S interface having two channels, CHANNEL_PER_FIFO = 2 as the I2S stream having two channels is usually saved within one FIFO +#endif +#endif +#if CFG_TUD_AUDIO > 2 +#ifndef CFG_TUD_AUDIO_FUNC_3_CHANNEL_PER_FIFO_RX +#error You must tell the driver the number of channels per FIFO for the interleaved encoding! E.g. for an I2S interface having two channels, CHANNEL_PER_FIFO = 2 as the I2S stream having two channels is usually saved within one FIFO +#endif +#endif +#endif + +// Remaining types not support so far + +// Number of support FIFOs to set up - multiple channels can be handled by one FIFO - very common is two channels per FIFO stemming from one I2S interface +#ifndef CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO +#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO +#define CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO +#define CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO 0 +#endif + +#ifndef CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO +#define CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO +#define CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO +#define CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO 0 +#endif + +// Size of support FIFOs IN BYTES - if size > 0 there are as many FIFOs set up as CFG_TUD_AUDIO_FUNC_X_N_TX_SUPP_SW_FIFO and CFG_TUD_AUDIO_FUNC_X_N_RX_SUPP_SW_FIFO +#ifndef CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ +#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ 0 // FIFO size - minimum size: ceil(f_s/1000) * max(# of TX channels) / (# of TX support FIFOs) * max(# of bytes per sample) +#endif +#ifndef CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ +#define CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ +#define CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ 0 +#endif + +#ifndef CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ +#define CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ 0 // FIFO size - minimum size: ceil(f_s/1000) * max(# of RX channels) / (# of RX support FIFOs) * max(# of bytes per sample) +#endif +#ifndef CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ +#define CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ 0 +#endif +#ifndef CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ +#define CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ 0 +#endif + +//static_assert(sizeof(tud_audio_desc_lengths) != CFG_TUD_AUDIO, "Supply audio function descriptor pack length!"); + +// Supported types of this driver: +// AUDIO_DATA_FORMAT_TYPE_I_PCM - Required definitions: CFG_TUD_AUDIO_N_CHANNELS and CFG_TUD_AUDIO_BYTES_PER_CHANNEL + +#ifdef __cplusplus +extern "C" { +#endif + +/** \addtogroup AUDIO_Serial Serial + * @{ + * \defgroup AUDIO_Serial_Device Device + * @{ */ + +//--------------------------------------------------------------------+ +// Application API (Multiple Interfaces) +// CFG_TUD_AUDIO > 1 +//--------------------------------------------------------------------+ +bool tud_audio_n_mounted (uint8_t func_id); + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING +uint16_t tud_audio_n_available (uint8_t func_id); +uint16_t tud_audio_n_read (uint8_t func_id, void* buffer, uint16_t bufsize); +bool tud_audio_n_clear_ep_out_ff (uint8_t func_id); // Delete all content in the EP OUT FIFO +tu_fifo_t* tud_audio_n_get_ep_out_ff (uint8_t func_id); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING +bool tud_audio_n_clear_rx_support_ff (uint8_t func_id, uint8_t ff_idx); // Delete all content in the support RX FIFOs +uint16_t tud_audio_n_available_support_ff (uint8_t func_id, uint8_t ff_idx); +uint16_t tud_audio_n_read_support_ff (uint8_t func_id, uint8_t ff_idx, void* buffer, uint16_t bufsize); +tu_fifo_t* tud_audio_n_get_rx_support_ff (uint8_t func_id, uint8_t ff_idx); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING +uint16_t tud_audio_n_write (uint8_t func_id, const void * data, uint16_t len); +bool tud_audio_n_clear_ep_in_ff (uint8_t func_id); // Delete all content in the EP IN FIFO +tu_fifo_t* tud_audio_n_get_ep_in_ff (uint8_t func_id); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING +uint16_t tud_audio_n_flush_tx_support_ff (uint8_t func_id); // Force all content in the support TX FIFOs to be written into EP SW FIFO +bool tud_audio_n_clear_tx_support_ff (uint8_t func_id, uint8_t ff_idx); +uint16_t tud_audio_n_write_support_ff (uint8_t func_id, uint8_t ff_idx, const void * data, uint16_t len); +tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_idx); +#endif + +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +uint16_t tud_audio_int_ctr_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len); +#endif + +//--------------------------------------------------------------------+ +// Application API (Interface0) +//--------------------------------------------------------------------+ + +static inline bool tud_audio_mounted (void); + +// RX API + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING +static inline uint16_t tud_audio_available (void); +static inline bool tud_audio_clear_ep_out_ff (void); // Delete all content in the EP OUT FIFO +static inline uint16_t tud_audio_read (void* buffer, uint16_t bufsize); +static inline tu_fifo_t* tud_audio_get_ep_out_ff (void); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING +static inline bool tud_audio_clear_rx_support_ff (uint8_t ff_idx); +static inline uint16_t tud_audio_available_support_ff (uint8_t ff_idx); +static inline uint16_t tud_audio_read_support_ff (uint8_t ff_idx, void* buffer, uint16_t bufsize); +static inline tu_fifo_t* tud_audio_get_rx_support_ff (uint8_t ff_idx); +#endif + +// TX API + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING +static inline uint16_t tud_audio_write (const void * data, uint16_t len); +static inline bool tud_audio_clear_ep_in_ff (void); +static inline tu_fifo_t* tud_audio_get_ep_in_ff (void); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING +static inline uint16_t tud_audio_flush_tx_support_ff (void); +static inline uint16_t tud_audio_clear_tx_support_ff (uint8_t ff_idx); +static inline uint16_t tud_audio_write_support_ff (uint8_t ff_idx, const void * data, uint16_t len); +static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx); +#endif + +// INT CTR API + +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +static inline uint16_t tud_audio_int_ctr_write (uint8_t const* buffer, uint16_t len); +#endif + +// Buffer control EP data and schedule a transmit +// This function is intended to be used if you do not have a persistent buffer or memory location available (e.g. non-local variables) and need to answer onto a +// get request. This function buffers your answer request frame into the control buffer of the corresponding audio driver and schedules a transmit for sending it. +// Since transmission is triggered via interrupts, a persistent memory location is required onto which the buffer pointer in pointing. If you already have such +// available you may directly use 'tud_control_xfer(...)'. In this case data does not need to be copied into an additional buffer and you save some time. +// If the request's wLength is zero, a status packet is sent instead. +bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len); + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +#if CFG_TUD_AUDIO_ENABLE_EP_IN +TU_ATTR_WEAK bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting); +TU_ATTR_WEAK bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +TU_ATTR_WEAK bool tud_audio_rx_done_pre_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting); +TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting); +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); + +// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. +// +// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, +// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb +// expects 16.16 format and handles the conversion to 10.14 on FS. +// +// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the +// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. +bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); +static inline bool tud_audio_fb_set(uint32_t feedback); +#endif + +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); +#endif + +// Invoked when audio set interface request received +TU_ATTR_WEAK bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request); + +// Invoked when audio set interface request received which closes an EP +TU_ATTR_WEAK bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request); + +// Invoked when audio class specific set request received for an EP +TU_ATTR_WEAK bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); + +// Invoked when audio class specific set request received for an interface +TU_ATTR_WEAK bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); + +// Invoked when audio class specific set request received for an entity +TU_ATTR_WEAK bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); + +// Invoked when audio class specific get request received for an EP +TU_ATTR_WEAK bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request); + +// Invoked when audio class specific get request received for an interface +TU_ATTR_WEAK bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request); + +// Invoked when audio class specific get request received for an entity +TU_ATTR_WEAK bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request); + +//--------------------------------------------------------------------+ +// Inline Functions +//--------------------------------------------------------------------+ + +static inline bool tud_audio_mounted(void) +{ + return tud_audio_n_mounted(0); +} + +// RX API + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING + +static inline uint16_t tud_audio_available(void) +{ + return tud_audio_n_available(0); +} + +static inline uint16_t tud_audio_read(void* buffer, uint16_t bufsize) +{ + return tud_audio_n_read(0, buffer, bufsize); +} + +static inline bool tud_audio_clear_ep_out_ff(void) +{ + return tud_audio_n_clear_ep_out_ff(0); +} + +static inline tu_fifo_t* tud_audio_get_ep_out_ff(void) +{ + return tud_audio_n_get_ep_out_ff(0); +} + +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING + +static inline bool tud_audio_clear_rx_support_ff(uint8_t ff_idx) +{ + return tud_audio_n_clear_rx_support_ff(0, ff_idx); +} + +static inline uint16_t tud_audio_available_support_ff(uint8_t ff_idx) +{ + return tud_audio_n_available_support_ff(0, ff_idx); +} + +static inline uint16_t tud_audio_read_support_ff(uint8_t ff_idx, void* buffer, uint16_t bufsize) +{ + return tud_audio_n_read_support_ff(0, ff_idx, buffer, bufsize); +} + +static inline tu_fifo_t* tud_audio_get_rx_support_ff(uint8_t ff_idx) +{ + return tud_audio_n_get_rx_support_ff(0, ff_idx); +} + +#endif + +// TX API + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + +static inline uint16_t tud_audio_write(const void * data, uint16_t len) +{ + return tud_audio_n_write(0, data, len); +} + +static inline bool tud_audio_clear_ep_in_ff(void) +{ + return tud_audio_n_clear_ep_in_ff(0); +} + +static inline tu_fifo_t* tud_audio_get_ep_in_ff(void) +{ + return tud_audio_n_get_ep_in_ff(0); +} + +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING + +static inline uint16_t tud_audio_flush_tx_support_ff(void) +{ + return tud_audio_n_flush_tx_support_ff(0); +} + +static inline uint16_t tud_audio_clear_tx_support_ff(uint8_t ff_idx) +{ + return tud_audio_n_clear_tx_support_ff(0, ff_idx); +} + +static inline uint16_t tud_audio_write_support_ff(uint8_t ff_idx, const void * data, uint16_t len) +{ + return tud_audio_n_write_support_ff(0, ff_idx, data, len); +} + +static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx) +{ + return tud_audio_n_get_tx_support_ff(0, ff_idx); +} + +#endif + +#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t len) +{ + return tud_audio_int_ctr_n_write(0, buffer, len); +} +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +static inline bool tud_audio_fb_set(uint32_t feedback) +{ + return tud_audio_n_fb_set(0, feedback); +} +#endif + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void audiod_init (void); +void audiod_reset (uint8_t rhport); +uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool audiod_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_AUDIO_DEVICE_H_ */ + +/** @} */ +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/class/bth/bth_device.c b/circuitpython/lib/tinyusb/src/class/bth/bth_device.c new file mode 100755 index 0000000..f40bfbd --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/bth/bth_device.c @@ -0,0 +1,258 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_BTH) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "bth_device.h" +#include + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef struct +{ + uint8_t itf_num; + uint8_t ep_ev; + uint8_t ep_acl_in; + uint8_t ep_acl_out; + uint8_t ep_voice[2]; // Not used yet + uint8_t ep_voice_size[2][CFG_TUD_BTH_ISO_ALT_COUNT]; + + // Endpoint Transfer buffer + CFG_TUSB_MEM_ALIGN bt_hci_cmd_t hci_cmd; + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_BTH_DATA_EPSIZE]; + +} btd_interface_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION btd_interface_t _btd_itf; + +static bool bt_tx_data(uint8_t ep, void *data, uint16_t len) +{ + // skip if previous transfer not complete + TU_VERIFY(!usbd_edpt_busy(TUD_OPT_RHPORT, ep)); + + TU_ASSERT(usbd_edpt_xfer(TUD_OPT_RHPORT, ep, data, len)); + + return true; +} + +//--------------------------------------------------------------------+ +// READ API +//--------------------------------------------------------------------+ + + +//--------------------------------------------------------------------+ +// WRITE API +//--------------------------------------------------------------------+ + +bool tud_bt_event_send(void *event, uint16_t event_len) +{ + return bt_tx_data(_btd_itf.ep_ev, event, event_len); +} + +bool tud_bt_acl_data_send(void *event, uint16_t event_len) +{ + return bt_tx_data(_btd_itf.ep_acl_in, event, event_len); +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void btd_init(void) +{ + tu_memclr(&_btd_itf, sizeof(_btd_itf)); +} + +void btd_reset(uint8_t rhport) +{ + (void)rhport; +} + +uint16_t btd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +{ + tusb_desc_endpoint_t const *desc_ep; + uint16_t drv_len = 0; + // Size of single alternative of ISO interface + const uint16_t iso_alt_itf_size = sizeof(tusb_desc_interface_t) + 2 * sizeof(tusb_desc_endpoint_t); + // Size of hci interface + const uint16_t hci_itf_size = sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t); + // Ensure this is BT Primary Controller + TU_VERIFY(TUSB_CLASS_WIRELESS_CONTROLLER == itf_desc->bInterfaceClass && + TUD_BT_APP_SUBCLASS == itf_desc->bInterfaceSubClass && + TUD_BT_PROTOCOL_PRIMARY_CONTROLLER == itf_desc->bInterfaceProtocol, 0); + + TU_ASSERT(itf_desc->bNumEndpoints == 3 && max_len >= hci_itf_size); + + _btd_itf.itf_num = itf_desc->bInterfaceNumber; + + desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); + + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); + _btd_itf.ep_ev = desc_ep->bEndpointAddress; + + // Open endpoint pair + TU_ASSERT(usbd_open_edpt_pair(rhport, tu_desc_next(desc_ep), 2, TUSB_XFER_BULK, &_btd_itf.ep_acl_out, + &_btd_itf.ep_acl_in), 0); + + itf_desc = (tusb_desc_interface_t const *)tu_desc_next(tu_desc_next(tu_desc_next(desc_ep))); + + // Prepare for incoming data from host + TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_itf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE), 0); + + drv_len = hci_itf_size; + + // Ensure this is still BT Primary Controller + TU_ASSERT(TUSB_CLASS_WIRELESS_CONTROLLER == itf_desc->bInterfaceClass && + TUD_BT_APP_SUBCLASS == itf_desc->bInterfaceSubClass && + TUD_BT_PROTOCOL_PRIMARY_CONTROLLER == itf_desc->bInterfaceProtocol, 0); + TU_ASSERT(itf_desc->bNumEndpoints == 2 && max_len >= iso_alt_itf_size + drv_len); + + uint8_t dir; + + desc_ep = (tusb_desc_endpoint_t const *)tu_desc_next(itf_desc); + TU_ASSERT(itf_desc->bAlternateSetting < CFG_TUD_BTH_ISO_ALT_COUNT, 0); + TU_ASSERT(desc_ep->bDescriptorType == TUSB_DESC_ENDPOINT, 0); + dir = tu_edpt_dir(desc_ep->bEndpointAddress); + _btd_itf.ep_voice[dir] = desc_ep->bEndpointAddress; + // Store endpoint size for alternative + _btd_itf.ep_voice_size[dir][itf_desc->bAlternateSetting] = (uint8_t) tu_edpt_packet_size(desc_ep); + + desc_ep = (tusb_desc_endpoint_t const *)tu_desc_next(desc_ep); + TU_ASSERT(desc_ep->bDescriptorType == TUSB_DESC_ENDPOINT, 0); + dir = tu_edpt_dir(desc_ep->bEndpointAddress); + _btd_itf.ep_voice[dir] = desc_ep->bEndpointAddress; + // Store endpoint size for alternative + _btd_itf.ep_voice_size[dir][itf_desc->bAlternateSetting] = (uint8_t) tu_edpt_packet_size(desc_ep); + drv_len += iso_alt_itf_size; + + for (int i = 1; i < CFG_TUD_BTH_ISO_ALT_COUNT && drv_len + iso_alt_itf_size <= max_len; ++i) { + // Make sure rest of alternatives matches + itf_desc = (tusb_desc_interface_t const *)tu_desc_next(desc_ep); + if (itf_desc->bDescriptorType != TUSB_DESC_INTERFACE || + TUSB_CLASS_WIRELESS_CONTROLLER != itf_desc->bInterfaceClass || + TUD_BT_APP_SUBCLASS != itf_desc->bInterfaceSubClass || + TUD_BT_PROTOCOL_PRIMARY_CONTROLLER != itf_desc->bInterfaceProtocol) + { + // Not an Iso interface instance + break; + } + TU_ASSERT(itf_desc->bAlternateSetting < CFG_TUD_BTH_ISO_ALT_COUNT, 0); + + desc_ep = (tusb_desc_endpoint_t const *)tu_desc_next(itf_desc); + dir = tu_edpt_dir(desc_ep->bEndpointAddress); + // Verify that alternative endpoint are same as first ones + TU_ASSERT(desc_ep->bDescriptorType == TUSB_DESC_ENDPOINT && + _btd_itf.ep_voice[dir] == desc_ep->bEndpointAddress, 0); + _btd_itf.ep_voice_size[dir][itf_desc->bAlternateSetting] = (uint8_t) tu_edpt_packet_size(desc_ep); + + desc_ep = (tusb_desc_endpoint_t const *)tu_desc_next(desc_ep); + dir = tu_edpt_dir(desc_ep->bEndpointAddress); + // Verify that alternative endpoint are same as first ones + TU_ASSERT(desc_ep->bDescriptorType == TUSB_DESC_ENDPOINT && + _btd_itf.ep_voice[dir] == desc_ep->bEndpointAddress, 0); + _btd_itf.ep_voice_size[dir][itf_desc->bAlternateSetting] = (uint8_t) tu_edpt_packet_size(desc_ep); + drv_len += iso_alt_itf_size; + } + + return drv_len; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool btd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +{ + (void)rhport; + + if ( stage == CONTROL_STAGE_SETUP ) + { + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS && + request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE) + { + // HCI command packet addressing for single function Primary Controllers + TU_VERIFY(request->bRequest == 0 && request->wValue == 0 && request->wIndex == 0); + } + else if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE) + { + if (request->bRequest == TUSB_REQ_SET_INTERFACE && _btd_itf.itf_num + 1 == request->wIndex) + { + // TODO: Set interface it would involve changing size of endpoint size + } + else + { + // HCI command packet for Primary Controller function in a composite device + TU_VERIFY(request->bRequest == 0 && request->wValue == 0 && request->wIndex == _btd_itf.itf_num); + } + } + else return false; + + return tud_control_xfer(rhport, request, &_btd_itf.hci_cmd, sizeof(_btd_itf.hci_cmd)); + } + else if ( stage == CONTROL_STAGE_DATA ) + { + // Handle class request only + TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); + + if (tud_bt_hci_cmd_cb) tud_bt_hci_cmd_cb(&_btd_itf.hci_cmd, tu_min16(request->wLength, sizeof(_btd_itf.hci_cmd))); + } + + return true; +} + +bool btd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void)result; + + // received new data from host + if (ep_addr == _btd_itf.ep_acl_out) + { + if (tud_bt_acl_data_received_cb) tud_bt_acl_data_received_cb(_btd_itf.epout_buf, xferred_bytes); + + // prepare for next data + TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_itf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE)); + } + else if (ep_addr == _btd_itf.ep_ev) + { + if (tud_bt_event_sent_cb) tud_bt_event_sent_cb((uint16_t)xferred_bytes); + } + else if (ep_addr == _btd_itf.ep_acl_in) + { + if (tud_bt_acl_data_sent_cb) tud_bt_acl_data_sent_cb((uint16_t)xferred_bytes); + } + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/bth/bth_device.h b/circuitpython/lib/tinyusb/src/class/bth/bth_device.h new file mode 100755 index 0000000..1b90d09 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/bth/bth_device.h @@ -0,0 +1,109 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_BTH_DEVICE_H_ +#define _TUSB_BTH_DEVICE_H_ + +#include +#include + +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ +#ifndef CFG_TUD_BTH_EVENT_EPSIZE +#define CFG_TUD_BTH_EVENT_EPSIZE 16 +#endif +#ifndef CFG_TUD_BTH_DATA_EPSIZE +#define CFG_TUD_BTH_DATA_EPSIZE 64 +#endif + +typedef struct TU_ATTR_PACKED +{ + uint16_t op_code; + uint8_t param_length; + uint8_t param[255]; +} bt_hci_cmd_t; + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when HCI command was received over USB from Bluetooth host. +// Detailed format is described in Bluetooth core specification Vol 2, +// Part E, 5.4.1. +// Length of the command is from 3 bytes (2 bytes for OpCode, +// 1 byte for parameter total length) to 258. +TU_ATTR_WEAK void tud_bt_hci_cmd_cb(void *hci_cmd, size_t cmd_len); + +// Invoked when ACL data was received over USB from Bluetooth host. +// Detailed format is described in Bluetooth core specification Vol 2, +// Part E, 5.4.2. +// Length is from 4 bytes, (12 bits for Handle, 4 bits for flags +// and 16 bits for data total length) to endpoint size. +TU_ATTR_WEAK void tud_bt_acl_data_received_cb(void *acl_data, uint16_t data_len); + +// Called when event sent with tud_bt_event_send() was delivered to BT stack. +// Controller can release/reuse buffer with Event packet at this point. +TU_ATTR_WEAK void tud_bt_event_sent_cb(uint16_t sent_bytes); + +// Called when ACL data that was sent with tud_bt_acl_data_send() +// was delivered to BT stack. +// Controller can release/reuse buffer with ACL packet at this point. +TU_ATTR_WEAK void tud_bt_acl_data_sent_cb(uint16_t sent_bytes); + +// Bluetooth controller calls this function when it wants to send even packet +// as described in Bluetooth core specification Vol 2, Part E, 5.4.4. +// Event has at least 2 bytes, first is Event code second contains parameter +// total length. Controller can release/reuse event memory after +// tud_bt_event_sent_cb() is called. +bool tud_bt_event_send(void *event, uint16_t event_len); + +// Bluetooth controller calls this to send ACL data packet +// as described in Bluetooth core specification Vol 2, Part E, 5.4.2 +// Minimum length is 4 bytes, (12 bits for Handle, 4 bits for flags +// and 16 bits for data total length). Upper limit is not limited +// to endpoint size since buffer is allocate by controller +// and must not be reused till tud_bt_acl_data_sent_cb() is called. +bool tud_bt_acl_data_send(void *acl_data, uint16_t data_len); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void btd_init (void); +void btd_reset (uint8_t rhport); +uint16_t btd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool btd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *request); +bool btd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_BTH_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/cdc/cdc.h b/circuitpython/lib/tinyusb/src/class/cdc/cdc.h new file mode 100644 index 0000000..e345139 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/cdc/cdc.h @@ -0,0 +1,409 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup group_class + * \defgroup ClassDriver_CDC Communication Device Class (CDC) + * Currently only Abstract Control Model subclass is supported + * @{ */ + +#ifndef _TUSB_CDC_H__ +#define _TUSB_CDC_H__ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/** \defgroup ClassDriver_CDC_Common Common Definitions + * @{ */ + +// TODO remove +/// CDC Pipe ID, used to indicate which pipe the API is addressing to (Notification, Out, In) +typedef enum +{ + CDC_PIPE_NOTIFICATION , ///< Notification pipe + CDC_PIPE_DATA_IN , ///< Data in pipe + CDC_PIPE_DATA_OUT , ///< Data out pipe + CDC_PIPE_ERROR , ///< Invalid Pipe ID +}cdc_pipeid_t; + +//--------------------------------------------------------------------+ +// CDC Communication Interface Class +//--------------------------------------------------------------------+ + +/// Communication Interface Subclass Codes +typedef enum +{ + CDC_COMM_SUBCLASS_DIRECT_LINE_CONTROL_MODEL = 0x01 , ///< Direct Line Control Model [USBPSTN1.2] + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL = 0x02 , ///< Abstract Control Model [USBPSTN1.2] + CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL = 0x03 , ///< Telephone Control Model [USBPSTN1.2] + CDC_COMM_SUBCLASS_MULTICHANNEL_CONTROL_MODEL = 0x04 , ///< Multi-Channel Control Model [USBISDN1.2] + CDC_COMM_SUBCLASS_CAPI_CONTROL_MODEL = 0x05 , ///< CAPI Control Model [USBISDN1.2] + CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL = 0x06 , ///< Ethernet Networking Control Model [USBECM1.2] + CDC_COMM_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL = 0x07 , ///< ATM Networking Control Model [USBATM1.2] + CDC_COMM_SUBCLASS_WIRELESS_HANDSET_CONTROL_MODEL = 0x08 , ///< Wireless Handset Control Model [USBWMC1.1] + CDC_COMM_SUBCLASS_DEVICE_MANAGEMENT = 0x09 , ///< Device Management [USBWMC1.1] + CDC_COMM_SUBCLASS_MOBILE_DIRECT_LINE_MODEL = 0x0A , ///< Mobile Direct Line Model [USBWMC1.1] + CDC_COMM_SUBCLASS_OBEX = 0x0B , ///< OBEX [USBWMC1.1] + CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL = 0x0C , ///< Ethernet Emulation Model [USBEEM1.0] + CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL = 0x0D ///< Network Control Model [USBNCM1.0] +} cdc_comm_sublcass_type_t; + +/// Communication Interface Protocol Codes +typedef enum +{ + CDC_COMM_PROTOCOL_NONE = 0x00 , ///< No specific protocol + CDC_COMM_PROTOCOL_ATCOMMAND = 0x01 , ///< AT Commands: V.250 etc + CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101 = 0x02 , ///< AT Commands defined by PCCA-101 + CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101_AND_ANNEXO = 0x03 , ///< AT Commands defined by PCCA-101 & Annex O + CDC_COMM_PROTOCOL_ATCOMMAND_GSM_707 = 0x04 , ///< AT Commands defined by GSM 07.07 + CDC_COMM_PROTOCOL_ATCOMMAND_3GPP_27007 = 0x05 , ///< AT Commands defined by 3GPP 27.007 + CDC_COMM_PROTOCOL_ATCOMMAND_CDMA = 0x06 , ///< AT Commands defined by TIA for CDMA + CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL = 0x07 ///< Ethernet Emulation Model +} cdc_comm_protocol_type_t; + +//------------- SubType Descriptor in COMM Functional Descriptor -------------// +/// Communication Interface SubType Descriptor +typedef enum +{ + CDC_FUNC_DESC_HEADER = 0x00 , ///< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface. + CDC_FUNC_DESC_CALL_MANAGEMENT = 0x01 , ///< Call Management Functional Descriptor. + CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT = 0x02 , ///< Abstract Control Management Functional Descriptor. + CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT = 0x03 , ///< Direct Line Management Functional Descriptor. + CDC_FUNC_DESC_TELEPHONE_RINGER = 0x04 , ///< Telephone Ringer Functional Descriptor. + CDC_FUNC_DESC_TELEPHONE_CALL_AND_LINE_STATE_REPORTING_CAPACITY = 0x05 , ///< Telephone Call and Line State Reporting Capabilities Functional Descriptor. + CDC_FUNC_DESC_UNION = 0x06 , ///< Union Functional Descriptor + CDC_FUNC_DESC_COUNTRY_SELECTION = 0x07 , ///< Country Selection Functional Descriptor + CDC_FUNC_DESC_TELEPHONE_OPERATIONAL_MODES = 0x08 , ///< Telephone Operational ModesFunctional Descriptor + CDC_FUNC_DESC_USB_TERMINAL = 0x09 , ///< USB Terminal Functional Descriptor + CDC_FUNC_DESC_NETWORK_CHANNEL_TERMINAL = 0x0A , ///< Network Channel Terminal Descriptor + CDC_FUNC_DESC_PROTOCOL_UNIT = 0x0B , ///< Protocol Unit Functional Descriptor + CDC_FUNC_DESC_EXTENSION_UNIT = 0x0C , ///< Extension Unit Functional Descriptor + CDC_FUNC_DESC_MULTICHANEL_MANAGEMENT = 0x0D , ///< Multi-Channel Management Functional Descriptor + CDC_FUNC_DESC_CAPI_CONTROL_MANAGEMENT = 0x0E , ///< CAPI Control Management Functional Descriptor + CDC_FUNC_DESC_ETHERNET_NETWORKING = 0x0F , ///< Ethernet Networking Functional Descriptor + CDC_FUNC_DESC_ATM_NETWORKING = 0x10 , ///< ATM Networking Functional Descriptor + CDC_FUNC_DESC_WIRELESS_HANDSET_CONTROL_MODEL = 0x11 , ///< Wireless Handset Control Model Functional Descriptor + CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL = 0x12 , ///< Mobile Direct Line Model Functional Descriptor + CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL_DETAIL = 0x13 , ///< MDLM Detail Functional Descriptor + CDC_FUNC_DESC_DEVICE_MANAGEMENT_MODEL = 0x14 , ///< Device Management Model Functional Descriptor + CDC_FUNC_DESC_OBEX = 0x15 , ///< OBEX Functional Descriptor + CDC_FUNC_DESC_COMMAND_SET = 0x16 , ///< Command Set Functional Descriptor + CDC_FUNC_DESC_COMMAND_SET_DETAIL = 0x17 , ///< Command Set Detail Functional Descriptor + CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL = 0x18 , ///< Telephone Control Model Functional Descriptor + CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER = 0x19 , ///< OBEX Service Identifier Functional Descriptor + CDC_FUNC_DESC_NCM = 0x1A , ///< NCM Functional Descriptor +}cdc_func_desc_type_t; + +//--------------------------------------------------------------------+ +// CDC Data Interface Class +//--------------------------------------------------------------------+ + +// SUBCLASS code of Data Interface is not used and should/must be zero + +// Data Interface Protocol Codes +typedef enum{ + CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, ///< Physical interface protocol for ISDN BRI + CDC_DATA_PROTOCOL_HDLC = 0x31, ///< HDLC + CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, ///< Transparent + CDC_DATA_PROTOCOL_Q921_MANAGEMENT = 0x50, ///< Management protocol for Q.921 data link protocol + CDC_DATA_PROTOCOL_Q921_DATA_LINK = 0x51, ///< Data link protocol for Q.931 + CDC_DATA_PROTOCOL_Q921_TEI_MULTIPLEXOR = 0x52, ///< TEI-multiplexor for Q.921 data link protocol + CDC_DATA_PROTOCOL_V42BIS_DATA_COMPRESSION = 0x90, ///< Data compression procedures + CDC_DATA_PROTOCOL_EURO_ISDN = 0x91, ///< Euro-ISDN protocol control + CDC_DATA_PROTOCOL_V24_RATE_ADAPTION_TO_ISDN = 0x92, ///< V.24 rate adaptation to ISDN + CDC_DATA_PROTOCOL_CAPI_COMMAND = 0x93, ///< CAPI Commands + CDC_DATA_PROTOCOL_HOST_BASED_DRIVER = 0xFD, ///< Host based driver. Note: This protocol code should only be used in messages between host and device to identify the host driver portion of a protocol stack. + CDC_DATA_PROTOCOL_IN_PROTOCOL_UNIT_FUNCTIONAL_DESCRIPTOR = 0xFE ///< The protocol(s) are described using a ProtocolUnit Functional Descriptors on Communications Class Interface +}cdc_data_protocol_type_t; + +//--------------------------------------------------------------------+ +// Management Element Request (Control Endpoint) +//--------------------------------------------------------------------+ + +/// Communication Interface Management Element Request Codes +typedef enum +{ + CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface + CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface. + CDC_REQUEST_SET_COMM_FEATURE = 0x02, + CDC_REQUEST_GET_COMM_FEATURE = 0x03, + CDC_REQUEST_CLEAR_COMM_FEATURE = 0x04, + + CDC_REQUEST_SET_AUX_LINE_STATE = 0x10, + CDC_REQUEST_SET_HOOK_STATE = 0x11, + CDC_REQUEST_PULSE_SETUP = 0x12, + CDC_REQUEST_SEND_PULSE = 0x13, + CDC_REQUEST_SET_PULSE_TIME = 0x14, + CDC_REQUEST_RING_AUX_JACK = 0x15, + + CDC_REQUEST_SET_LINE_CODING = 0x20, + CDC_REQUEST_GET_LINE_CODING = 0x21, + CDC_REQUEST_SET_CONTROL_LINE_STATE = 0x22, + CDC_REQUEST_SEND_BREAK = 0x23, + + CDC_REQUEST_SET_RINGER_PARMS = 0x30, + CDC_REQUEST_GET_RINGER_PARMS = 0x31, + CDC_REQUEST_SET_OPERATION_PARMS = 0x32, + CDC_REQUEST_GET_OPERATION_PARMS = 0x33, + CDC_REQUEST_SET_LINE_PARMS = 0x34, + CDC_REQUEST_GET_LINE_PARMS = 0x35, + CDC_REQUEST_DIAL_DIGITS = 0x36, + CDC_REQUEST_SET_UNIT_PARAMETER = 0x37, + CDC_REQUEST_GET_UNIT_PARAMETER = 0x38, + CDC_REQUEST_CLEAR_UNIT_PARAMETER = 0x39, + CDC_REQUEST_GET_PROFILE = 0x3A, + + CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS = 0x40, + CDC_REQUEST_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41, + CDC_REQUEST_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42, + CDC_REQUEST_SET_ETHERNET_PACKET_FILTER = 0x43, + CDC_REQUEST_GET_ETHERNET_STATISTIC = 0x44, + + CDC_REQUEST_SET_ATM_DATA_FORMAT = 0x50, + CDC_REQUEST_GET_ATM_DEVICE_STATISTICS = 0x51, + CDC_REQUEST_SET_ATM_DEFAULT_VC = 0x52, + CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53, + + CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60, +}cdc_management_request_t; + +//--------------------------------------------------------------------+ +// Management Elemenent Notification (Notification Endpoint) +//--------------------------------------------------------------------+ + +/// 6.3 Notification Codes +typedef enum +{ + CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status. + CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request. + CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, + CDC_NOTIF_RING_DETECT = 0x09, + CDC_NOTIF_SERIAL_STATE = 0x20, + CDC_NOTIF_CALL_STATE_CHANGE = 0x28, + CDC_NOTIF_LINE_STATE_CHANGE = 0x29, + CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred + CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40, +}cdc_notification_request_t; + +//--------------------------------------------------------------------+ +// Class Specific Functional Descriptor (Communication Interface) +//--------------------------------------------------------------------+ + +// Start of all packed definitions for compiler without per-type packed +TU_ATTR_PACKED_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN + +/// Header Functional Descriptor (Communication Interface) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUNC_DESC_ + uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal +}cdc_desc_func_header_t; + +/// Union Functional Descriptor (Communication Interface) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + uint8_t bControlInterface ; ///< Interface number of Communication Interface + uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface +}cdc_desc_func_union_t; + +#define cdc_desc_func_union_n_t(no_slave)\ + struct TU_ATTR_PACKED { \ + uint8_t bLength ;\ + uint8_t bDescriptorType ;\ + uint8_t bDescriptorSubType ;\ + uint8_t bControlInterface ;\ + uint8_t bSubordinateInterface[no_slave] ;\ +} + +/// Country Selection Functional Descriptor (Communication Interface) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes. + uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country. +}cdc_desc_func_country_selection_t; + +#define cdc_desc_func_country_selection_n_t(no_country) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength ;\ + uint8_t bDescriptorType ;\ + uint8_t bDescriptorSubType ;\ + uint8_t iCountryCodeRelDate ;\ + uint16_t wCountryCode[no_country] ;\ +} + +//--------------------------------------------------------------------+ +// PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS +//--------------------------------------------------------------------+ + +/// \brief Call Management Functional Descriptor +/// \details This functional descriptor describes the processing of calls for the Communications Class interface. +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + + struct { + uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface. + uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself. + uint8_t TU_RESERVED : 6; + } bmCapabilities; + + uint8_t bDataInterface; +}cdc_desc_func_call_management_t; + +typedef struct TU_ATTR_PACKED +{ + uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. + uint8_t support_line_request : 1; ///< Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State. + uint8_t support_send_break : 1; ///< Device supports the request Send_Break + uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection. + uint8_t TU_RESERVED : 4; +}cdc_acm_capability_t; + +TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler"); + +/// Abstract Control Management Functional Descriptor +/// This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + cdc_acm_capability_t bmCapabilities ; +}cdc_desc_func_acm_t; + +/// \brief Direct Line Management Functional Descriptor +/// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + struct { + uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit. + uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State. + uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time. + uint8_t TU_RESERVED : 5; + } bmCapabilities; +}cdc_desc_func_direct_line_management_t; + +/// \brief Telephone Ringer Functional Descriptor +/// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface, +/// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + uint8_t bRingerVolSteps ; + uint8_t bNumRingerPatterns ; +}cdc_desc_func_telephone_ringer_t; + +/// \brief Telephone Operational Modes Functional Descriptor +/// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by +/// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + struct { + uint8_t simple_mode : 1; + uint8_t standalone_mode : 1; + uint8_t computer_centric_mode : 1; + uint8_t TU_RESERVED : 5; + } bmCapabilities; +}cdc_desc_func_telephone_operational_modes_t; + +/// \brief Telephone Call and Line State Reporting Capabilities Descriptor +/// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a +/// telephone device to report optional call and line states. +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + struct { + uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone + uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states. + uint32_t caller_id : 1; ///< 0 : Does not report caller ID. 1 : Reports caller ID information. + uint32_t incoming_distinctive : 1; ///< 0 : Reports only incoming ringing. 1 : Reports incoming distinctive ringing patterns. + uint32_t dual_tone_multi_freq : 1; ///< 0 : Cannot report dual tone multi-frequency (DTMF) digits input remotely over the telephone line. 1 : Can report DTMF digits input remotely over the telephone line. + uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification + uint32_t TU_RESERVED : 26; + } bmCapabilities; +}cdc_desc_func_telephone_call_state_reporting_capabilities_t; + +// TODO remove +static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc) +{ + return p_desc[2]; +} + +//--------------------------------------------------------------------+ +// Requests +//--------------------------------------------------------------------+ +typedef struct TU_ATTR_PACKED +{ + uint32_t bit_rate; + uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits + uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space + uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16 +} cdc_line_coding_t; + +TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct"); + +typedef struct TU_ATTR_PACKED +{ + uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. + uint16_t half_duplex_carrier_control : 1; + uint16_t : 14; +} cdc_line_control_state_t; + +TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct"); + +TU_ATTR_PACKED_END // End of all packed definitions +TU_ATTR_BIT_FIELD_ORDER_END + +#ifdef __cplusplus + } +#endif + +#endif + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/class/cdc/cdc_device.c b/circuitpython/lib/tinyusb/src/class/cdc/cdc_device.c new file mode 100644 index 0000000..2b9b84e --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/cdc/cdc_device.c @@ -0,0 +1,486 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_CDC) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "cdc_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +enum +{ + BULK_PACKET_SIZE = (TUD_OPT_HIGH_SPEED ? 512 : 64) +}; + +typedef struct +{ + uint8_t itf_num; + uint8_t ep_notif; + uint8_t ep_in; + uint8_t ep_out; + + // Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) + uint8_t line_state; + + /*------------- From this point, data is not cleared by bus reset -------------*/ + char wanted_char; + cdc_line_coding_t line_coding; + + // FIFO + tu_fifo_t rx_ff; + tu_fifo_t tx_ff; + + uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; + +#if CFG_FIFO_MUTEX + osal_mutex_def_t rx_ff_mutex; + osal_mutex_def_t tx_ff_mutex; +#endif + + // Endpoint Transfer buffer + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE]; + +}cdcd_interface_t; + +#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char) + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; + +static bool _prep_out_transaction (cdcd_interface_t* p_cdc) +{ + uint8_t const rhport = TUD_OPT_RHPORT; + uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + TU_VERIFY(available >= sizeof(p_cdc->epout_buf)); + + // claim endpoint + TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_out)); + + // fifo can be changed before endpoint is claimed + available = tu_fifo_remaining(&p_cdc->rx_ff); + + if ( available >= sizeof(p_cdc->epout_buf) ) + { + return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf)); + }else + { + // Release endpoint since we don't make any transfer + usbd_edpt_release(rhport, p_cdc->ep_out); + + return false; + } +} + +//--------------------------------------------------------------------+ +// APPLICATION API +//--------------------------------------------------------------------+ +bool tud_cdc_n_connected(uint8_t itf) +{ + // DTR (bit 0) active is considered as connected + return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); +} + +uint8_t tud_cdc_n_get_line_state (uint8_t itf) +{ + return _cdcd_itf[itf].line_state; +} + +void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding) +{ + (*coding) = _cdcd_itf[itf].line_coding; +} + +void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted) +{ + _cdcd_itf[itf].wanted_char = wanted; +} + + +//--------------------------------------------------------------------+ +// READ API +//--------------------------------------------------------------------+ +uint32_t tud_cdc_n_available(uint8_t itf) +{ + return tu_fifo_count(&_cdcd_itf[itf].rx_ff); +} + +uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) +{ + cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; + uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, bufsize); + _prep_out_transaction(p_cdc); + return num_read; +} + +bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) +{ + return tu_fifo_peek(&_cdcd_itf[itf].rx_ff, chr); +} + +void tud_cdc_n_read_flush (uint8_t itf) +{ + cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; + tu_fifo_clear(&p_cdc->rx_ff); + _prep_out_transaction(p_cdc); +} + +//--------------------------------------------------------------------+ +// WRITE API +//--------------------------------------------------------------------+ +uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) +{ + cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; + uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, bufsize); + + // flush if queue more than packet size + if ( tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE ) + { + tud_cdc_n_write_flush(itf); + } + + return ret; +} + +uint32_t tud_cdc_n_write_flush (uint8_t itf) +{ + cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; + + // Skip if usb is not ready yet + TU_VERIFY( tud_ready(), 0 ); + + // No data to send + if ( !tu_fifo_count(&p_cdc->tx_ff) ) return 0; + + uint8_t const rhport = TUD_OPT_RHPORT; + + // Claim the endpoint + TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); + + // Pull data from FIFO + uint16_t const count = tu_fifo_read_n(&p_cdc->tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf)); + + if ( count ) + { + TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); + return count; + }else + { + // Release endpoint since we don't make any transfer + // Note: data is dropped if terminal is not connected + usbd_edpt_release(rhport, p_cdc->ep_in); + return 0; + } +} + +uint32_t tud_cdc_n_write_available (uint8_t itf) +{ + return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff); +} + +bool tud_cdc_n_write_clear (uint8_t itf) +{ + return tu_fifo_clear(&_cdcd_itf[itf].tx_ff); +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void cdcd_init(void) +{ + tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); + + for(uint8_t i=0; iwanted_char = (char) -1; + + // default line coding is : stop bit = 1, parity = none, data bits = 8 + p_cdc->line_coding.bit_rate = 115200; + p_cdc->line_coding.stop_bits = 0; + p_cdc->line_coding.parity = 0; + p_cdc->line_coding.data_bits = 8; + + // Config RX fifo + tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, TU_ARRAY_SIZE(p_cdc->rx_ff_buf), 1, false); + + // Config TX fifo as overwritable at initialization and will be changed to non-overwritable + // if terminal supports DTR bit. Without DTR we do not know if data is actually polled by terminal. + // In this way, the most current data is prioritized. + tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true); + +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex)); + tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL); +#endif + } +} + +void cdcd_reset(uint8_t rhport) +{ + (void) rhport; + + for(uint8_t i=0; irx_ff); + tu_fifo_clear(&p_cdc->tx_ff); + tu_fifo_set_overwritable(&p_cdc->tx_ff, true); + } +} + +uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + // Only support ACM subclass + TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); + + // Find available interface + cdcd_interface_t * p_cdc = NULL; + for(uint8_t cdc_id=0; cdc_iditf_num = itf_desc->bInterfaceNumber; + + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const * p_desc = tu_desc_next( itf_desc ); + + // Communication Functional Descriptors + while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) + { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) + { + // notification endpoint + tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + + TU_ASSERT( usbd_edpt_open(rhport, desc_ep), 0 ); + p_cdc->ep_notif = desc_ep->bEndpointAddress; + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + //------------- Data Interface (if any) -------------// + if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && + (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) + { + // next to endpoint descriptor + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + + // Open endpoint pair + TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0 ); + + drv_len += 2*sizeof(tusb_desc_endpoint_t); + } + + // Prepare for incoming data + _prep_out_transaction(p_cdc); + + return drv_len; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + // Handle class request only + TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); + + uint8_t itf = 0; + cdcd_interface_t* p_cdc = _cdcd_itf; + + // Identify which interface to use + for ( ; ; itf++, p_cdc++) + { + if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false; + + if ( p_cdc->itf_num == request->wIndex ) break; + } + + switch ( request->bRequest ) + { + case CDC_REQUEST_SET_LINE_CODING: + if (stage == CONTROL_STAGE_SETUP) + { + TU_LOG2(" Set Line Coding\r\n"); + tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); + } + else if ( stage == CONTROL_STAGE_ACK) + { + if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); + } + break; + + case CDC_REQUEST_GET_LINE_CODING: + if (stage == CONTROL_STAGE_SETUP) + { + TU_LOG2(" Get Line Coding\r\n"); + tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); + } + break; + + case CDC_REQUEST_SET_CONTROL_LINE_STATE: + if (stage == CONTROL_STAGE_SETUP) + { + tud_control_status(rhport, request); + } + else if (stage == CONTROL_STAGE_ACK) + { + // CDC PSTN v1.2 section 6.3.12 + // Bit 0: Indicates if DTE is present or not. + // This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready) + // Bit 1: Carrier control for half-duplex modems. + // This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send) + bool const dtr = tu_bit_test(request->wValue, 0); + bool const rts = tu_bit_test(request->wValue, 1); + + p_cdc->line_state = (uint8_t) request->wValue; + + // Disable fifo overwriting if DTR bit is set + tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr); + + TU_LOG2(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); + + // Invoke callback + if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts); + } + break; + case CDC_REQUEST_SEND_BREAK: + if (stage == CONTROL_STAGE_SETUP) + { + tud_control_status(rhport, request); + } + else if (stage == CONTROL_STAGE_ACK) + { + TU_LOG2(" Send Break\r\n"); + if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue); + } + break; + + default: return false; // stall unsupported request + } + + return true; +} + +bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) result; + + uint8_t itf; + cdcd_interface_t* p_cdc; + + // Identify which interface to use + for (itf = 0; itf < CFG_TUD_CDC; itf++) + { + p_cdc = &_cdcd_itf[itf]; + if ( ( ep_addr == p_cdc->ep_out ) || ( ep_addr == p_cdc->ep_in ) ) break; + } + TU_ASSERT(itf < CFG_TUD_CDC); + + // Received new data + if ( ep_addr == p_cdc->ep_out ) + { + tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, xferred_bytes); + + // Check for wanted char and invoke callback if needed + if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) ) + { + for ( uint32_t i = 0; i < xferred_bytes; i++ ) + { + if ( (p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff) ) + { + tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); + } + } + } + + // invoke receive callback (if there is still data) + if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf); + + // prepare for OUT transaction + _prep_out_transaction(p_cdc); + } + + // Data sent to host, we continue to fetch from tx fifo to send. + // Note: This will cause incorrect baudrate set in line coding. + // Though maybe the baudrate is not really important !!! + if ( ep_addr == p_cdc->ep_in ) + { + // invoke transmit callback to possibly refill tx fifo + if ( tud_cdc_tx_complete_cb ) tud_cdc_tx_complete_cb(itf); + + if ( 0 == tud_cdc_n_write_flush(itf) ) + { + // If there is no data left, a ZLP should be sent if + // xferred_bytes is multiple of EP Packet size and not zero + if ( !tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) + { + if ( usbd_edpt_claim(rhport, p_cdc->ep_in) ) + { + usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0); + } + } + } + } + + // nothing to do with notif endpoint for now + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/cdc/cdc_device.h b/circuitpython/lib/tinyusb/src/class/cdc/cdc_device.h new file mode 100644 index 0000000..fbc7162 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/cdc/cdc_device.h @@ -0,0 +1,260 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_CDC_DEVICE_H_ +#define _TUSB_CDC_DEVICE_H_ + +#include "common/tusb_common.h" +#include "cdc.h" + +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ +#if !defined(CFG_TUD_CDC_EP_BUFSIZE) && defined(CFG_TUD_CDC_EPSIZE) + #warning CFG_TUD_CDC_EPSIZE is renamed to CFG_TUD_CDC_EP_BUFSIZE, please update to use the new name + #define CFG_TUD_CDC_EP_BUFSIZE CFG_TUD_CDC_EPSIZE +#endif + +#ifndef CFG_TUD_CDC_EP_BUFSIZE + #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/** \addtogroup CDC_Serial Serial + * @{ + * \defgroup CDC_Serial_Device Device + * @{ */ + +//--------------------------------------------------------------------+ +// Application API (Multiple Ports) +// CFG_TUD_CDC > 1 +//--------------------------------------------------------------------+ + +// Check if terminal is connected to this port +bool tud_cdc_n_connected (uint8_t itf); + +// Get current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) +uint8_t tud_cdc_n_get_line_state (uint8_t itf); + +// Get current line encoding: bit rate, stop bits parity etc .. +void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding); + +// Set special character that will trigger tud_cdc_rx_wanted_cb() callback on receiving +void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted); + +// Get the number of bytes available for reading +uint32_t tud_cdc_n_available (uint8_t itf); + +// Read received bytes +uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize); + +// Read a byte, return -1 if there is none +static inline +int32_t tud_cdc_n_read_char (uint8_t itf); + +// Clear the received FIFO +void tud_cdc_n_read_flush (uint8_t itf); + +// Get a byte from FIFO at the specified position without removing it +bool tud_cdc_n_peek (uint8_t itf, uint8_t* ui8); + +// Write bytes to TX FIFO, data may remain in the FIFO for a while +uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); + +// Write a byte +static inline +uint32_t tud_cdc_n_write_char (uint8_t itf, char ch); + +// Write a null-terminated string +static inline +uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str); + +// Force sending data if possible, return number of forced bytes +uint32_t tud_cdc_n_write_flush (uint8_t itf); + +// Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation. +uint32_t tud_cdc_n_write_available (uint8_t itf); + +// Clear the transmit FIFO +bool tud_cdc_n_write_clear (uint8_t itf); + +//--------------------------------------------------------------------+ +// Application API (Single Port) +//--------------------------------------------------------------------+ +static inline bool tud_cdc_connected (void); +static inline uint8_t tud_cdc_get_line_state (void); +static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding); +static inline void tud_cdc_set_wanted_char (char wanted); + +static inline uint32_t tud_cdc_available (void); +static inline int32_t tud_cdc_read_char (void); +static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize); +static inline void tud_cdc_read_flush (void); +static inline bool tud_cdc_peek (uint8_t* ui8); + +static inline uint32_t tud_cdc_write_char (char ch); +static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize); +static inline uint32_t tud_cdc_write_str (char const* str); +static inline uint32_t tud_cdc_write_flush (void); +static inline uint32_t tud_cdc_write_available (void); +static inline bool tud_cdc_write_clear (void); + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received new data +TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); + +// Invoked when received `wanted_char` +TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); + +// Invoked when space becomes available in TX buffer +TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf); + +// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE +TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); + +// Invoked when line coding is change via SET_LINE_CODING +TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); + +// Invoked when received send break +TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); + +//--------------------------------------------------------------------+ +// Inline Functions +//--------------------------------------------------------------------+ +static inline int32_t tud_cdc_n_read_char (uint8_t itf) +{ + uint8_t ch; + return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; +} + +static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) +{ + return tud_cdc_n_write(itf, &ch, 1); +} + +static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str) +{ + return tud_cdc_n_write(itf, str, strlen(str)); +} + +static inline bool tud_cdc_connected (void) +{ + return tud_cdc_n_connected(0); +} + +static inline uint8_t tud_cdc_get_line_state (void) +{ + return tud_cdc_n_get_line_state(0); +} + +static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding) +{ + tud_cdc_n_get_line_coding(0, coding); +} + +static inline void tud_cdc_set_wanted_char (char wanted) +{ + tud_cdc_n_set_wanted_char(0, wanted); +} + +static inline uint32_t tud_cdc_available (void) +{ + return tud_cdc_n_available(0); +} + +static inline int32_t tud_cdc_read_char (void) +{ + return tud_cdc_n_read_char(0); +} + +static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize) +{ + return tud_cdc_n_read(0, buffer, bufsize); +} + +static inline void tud_cdc_read_flush (void) +{ + tud_cdc_n_read_flush(0); +} + +static inline bool tud_cdc_peek (uint8_t* ui8) +{ + return tud_cdc_n_peek(0, ui8); +} + +static inline uint32_t tud_cdc_write_char (char ch) +{ + return tud_cdc_n_write_char(0, ch); +} + +static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize) +{ + return tud_cdc_n_write(0, buffer, bufsize); +} + +static inline uint32_t tud_cdc_write_str (char const* str) +{ + return tud_cdc_n_write_str(0, str); +} + +static inline uint32_t tud_cdc_write_flush (void) +{ + return tud_cdc_n_write_flush(0); +} + +static inline uint32_t tud_cdc_write_available(void) +{ + return tud_cdc_n_write_available(0); +} + +static inline bool tud_cdc_write_clear(void) +{ + return tud_cdc_n_write_clear(0); +} + +/** @} */ +/** @} */ + +//--------------------------------------------------------------------+ +// INTERNAL USBD-CLASS DRIVER API +//--------------------------------------------------------------------+ +void cdcd_init (void); +void cdcd_reset (uint8_t rhport); +uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool cdcd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CDC_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/cdc/cdc_host.c b/circuitpython/lib/tinyusb/src/class/cdc/cdc_host.c new file mode 100644 index 0000000..c18234d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/cdc/cdc_host.c @@ -0,0 +1,249 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUH_ENABLED && CFG_TUH_CDC) + +#include "host/usbh.h" +#include "host/usbh_classdriver.h" + +#include "cdc_host.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef struct { + uint8_t itf_num; + uint8_t itf_protocol; + + uint8_t ep_notif; + uint8_t ep_in; + uint8_t ep_out; + + cdc_acm_capability_t acm_capability; + +} cdch_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static cdch_data_t cdch_data[CFG_TUH_DEVICE_MAX]; + +static inline cdch_data_t* get_itf(uint8_t dev_addr) +{ + return &cdch_data[dev_addr-1]; +} + +bool tuh_cdc_mounted(uint8_t dev_addr) +{ + cdch_data_t* cdc = get_itf(dev_addr); + return cdc->ep_in && cdc->ep_out; +} + +bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid) +{ + if ( !tuh_cdc_mounted(dev_addr) ) return false; + + cdch_data_t const * p_cdc = get_itf(dev_addr); + + switch (pipeid) + { + case CDC_PIPE_NOTIFICATION: + return usbh_edpt_busy(dev_addr, p_cdc->ep_notif ); + + case CDC_PIPE_DATA_IN: + return usbh_edpt_busy(dev_addr, p_cdc->ep_in ); + + case CDC_PIPE_DATA_OUT: + return usbh_edpt_busy(dev_addr, p_cdc->ep_out ); + + default: + return false; + } +} + +//--------------------------------------------------------------------+ +// APPLICATION API (parameter validation needed) +//--------------------------------------------------------------------+ +bool tuh_cdc_serial_is_mounted(uint8_t dev_addr) +{ + // TODO consider all AT Command as serial candidate + return tuh_cdc_mounted(dev_addr) && + (cdch_data[dev_addr-1].itf_protocol <= CDC_COMM_PROTOCOL_ATCOMMAND_CDMA); +} + +bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify) +{ + (void) is_notify; + TU_VERIFY( tuh_cdc_mounted(dev_addr) ); + TU_VERIFY( p_data != NULL && length, TUSB_ERROR_INVALID_PARA); + + uint8_t const ep_out = cdch_data[dev_addr-1].ep_out; + if ( usbh_edpt_busy(dev_addr, ep_out) ) return false; + + return usbh_edpt_xfer(dev_addr, ep_out, (void*)(uintptr_t) p_data, length); +} + +bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify) +{ + (void) is_notify; + TU_VERIFY( tuh_cdc_mounted(dev_addr) ); + TU_VERIFY( p_buffer != NULL && length, TUSB_ERROR_INVALID_PARA); + + uint8_t const ep_in = cdch_data[dev_addr-1].ep_in; + if ( usbh_edpt_busy(dev_addr, ep_in) ) return false; + + return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, length); +} + +bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_complete_cb_t complete_cb) +{ + cdch_data_t const * p_cdc = get_itf(dev_addr); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, + .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), + .wIndex = p_cdc->itf_num, + .wLength = 0 + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, complete_cb) ); + return true; +} + +//--------------------------------------------------------------------+ +// USBH-CLASS DRIVER API +//--------------------------------------------------------------------+ +void cdch_init(void) +{ + tu_memclr(cdch_data, sizeof(cdch_data)); +} + +bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +{ + (void) max_len; + + // Only support ACM subclass + // Protocol 0xFF can be RNDIS device for windows XP + TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass && + 0xFF != itf_desc->bInterfaceProtocol); + + cdch_data_t * p_cdc = get_itf(dev_addr); + + p_cdc->itf_num = itf_desc->bInterfaceNumber; + p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; + + //------------- Communication Interface -------------// + uint16_t drv_len = tu_desc_len(itf_desc); + uint8_t const * p_desc = tu_desc_next(itf_desc); + + // Communication Functional Descriptors + while( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) + { + if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) + { + // save ACM bmCapabilities + p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; + } + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) + { + // notification endpoint + tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + + TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); + p_cdc->ep_notif = desc_ep->bEndpointAddress; + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + //------------- Data Interface (if any) -------------// + if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && + (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) + { + // next to endpoint descriptor + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + + // data endpoints expected to be in pairs + for(uint32_t i=0; i<2; i++) + { + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); + + TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep)); + + if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) + { + p_cdc->ep_in = desc_ep->bEndpointAddress; + }else + { + p_cdc->ep_out = desc_ep->bEndpointAddress; + } + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next( p_desc ); + } + } + + return true; +} + +bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num) +{ + (void) dev_addr; (void) itf_num; + return true; +} + +bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) +{ + (void) ep_addr; + tuh_cdc_xfer_isr( dev_addr, event, 0, xferred_bytes ); + return true; +} + +void cdch_close(uint8_t dev_addr) +{ + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); + + cdch_data_t * p_cdc = get_itf(dev_addr); + tu_memclr(p_cdc, sizeof(cdch_data_t)); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/cdc/cdc_host.h b/circuitpython/lib/tinyusb/src/class/cdc/cdc_host.h new file mode 100644 index 0000000..0d43513 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/cdc/cdc_host.h @@ -0,0 +1,134 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_CDC_HOST_H_ +#define _TUSB_CDC_HOST_H_ + +#include "cdc.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// CDC APPLICATION PUBLIC API +//--------------------------------------------------------------------+ +/** \ingroup ClassDriver_CDC Communication Device Class (CDC) + * \addtogroup CDC_Serial Serial + * @{ + * \defgroup CDC_Serial_Host Host + * @{ */ + +bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_complete_cb_t complete_cb); + +static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_control_complete_cb_t complete_cb) +{ + return tuh_cdc_set_control_line_state(dev_addr, true, true, complete_cb); +} + +static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_control_complete_cb_t complete_cb) +{ + return tuh_cdc_set_control_line_state(dev_addr, false, false, complete_cb); +} + +/** \brief Check if device support CDC Serial interface or not + * \param[in] dev_addr device address + * \retval true if device supports + * \retval false if device does not support or is not mounted + */ +bool tuh_cdc_serial_is_mounted(uint8_t dev_addr); + +/** \brief Check if the interface is currently busy or not + * \param[in] dev_addr device address + * \param[in] pipeid value from \ref cdc_pipeid_t to indicate target pipe. + * \retval true if the interface is busy, meaning the stack is still transferring/waiting data from/to device + * \retval false if the interface is not busy, meaning the stack successfully transferred data from/to device + * \note This function is used to check if previous transfer is complete (success or error), so that the next transfer + * can be scheduled. User needs to make sure the corresponding interface is mounted + * (by \ref tuh_cdc_serial_is_mounted) before calling this function. + */ +bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid); + +/** \brief Perform USB OUT transfer to device + * \param[in] dev_addr device address + * \param[in] p_data Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION) + * \param[in] length Number of bytes to be transferred via USB bus + * \retval TUSB_ERROR_NONE on success + * \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device + * \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request) + * \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct + * \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the + * interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION. + */ +bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify); + +/** \brief Perform USB IN transfer to get data from device + * \param[in] dev_addr device address + * \param[in] p_buffer Buffer containing received data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION) + * \param[in] length Number of bytes to be transferred via USB bus + * \retval TUSB_ERROR_NONE on success + * \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device + * \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request) + * \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct + * \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the + * interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION. + */ +bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify); + +//--------------------------------------------------------------------+ +// CDC APPLICATION CALLBACKS +//--------------------------------------------------------------------+ + +/** \brief Callback function that is invoked when an transferring event occurred + * \param[in] dev_addr Address of device + * \param[in] event an value from \ref xfer_result_t + * \param[in] pipe_id value from \ref cdc_pipeid_t indicate the pipe + * \param[in] xferred_bytes Number of bytes transferred via USB bus + * \note event can be one of following + * - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully. + * - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error. + * - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device. + * \note + */ +void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes); + +/// @} // group CDC_Serial_Host +/// @} + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void cdch_init (void); +bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); +bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); +bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void cdch_close (uint8_t dev_addr); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CDC_HOST_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis.h b/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis.h new file mode 100644 index 0000000..e0f129f --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis.h @@ -0,0 +1,301 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup ClassDriver_CDC Communication Device Class (CDC) + * \defgroup CDC_RNDIS Remote Network Driver Interface Specification (RNDIS) + * @{ + * \defgroup CDC_RNDIS_Common Common Definitions + * @{ */ + +#ifndef _TUSB_CDC_RNDIS_H_ +#define _TUSB_CDC_RNDIS_H_ + +#include "cdc.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __CC_ARM +#pragma diag_suppress 66 // Suppress Keil warnings #66-D: enumeration value is out of "int" range +#endif + +/// RNDIS Message Types +typedef enum +{ + RNDIS_MSG_PACKET = 0x00000001UL, ///< The host and device use this to send network data to one another. + + RNDIS_MSG_INITIALIZE = 0x00000002UL, ///< Sent by the host to initialize the device. + RNDIS_MSG_INITIALIZE_CMPLT = 0x80000002UL, ///< Device response to an initialize message. + + RNDIS_MSG_HALT = 0x00000003UL, ///< Sent by the host to halt the device. This does not have a response. It is optional for the device to send this message to the host. + + RNDIS_MSG_QUERY = 0x00000004UL, ///< Sent by the host to send a query OID. + RNDIS_MSG_QUERY_CMPLT = 0x80000004UL, ///< Device response to a query OID. + + RNDIS_MSG_SET = 0x00000005UL, ///< Sent by the host to send a set OID. + RNDIS_MSG_SET_CMPLT = 0x80000005UL, ///< Device response to a set OID. + + RNDIS_MSG_RESET = 0x00000006UL, ///< Sent by the host to perform a soft reset on the device. + RNDIS_MSG_RESET_CMPLT = 0x80000006UL, ///< Device response to reset message. + + RNDIS_MSG_INDICATE_STATUS = 0x00000007UL, ///< Sent by the device to indicate its status or an error when an unrecognized message is received. + + RNDIS_MSG_KEEP_ALIVE = 0x00000008UL, ///< During idle periods, sent every few seconds by the host to check that the device is still responsive. It is optional for the device to send this message to check if the host is active. + RNDIS_MSG_KEEP_ALIVE_CMPLT = 0x80000008UL ///< The device response to a keepalivemessage. The host can respond with this message to a keepalive message from the device when the device implements the optional KeepAliveTimer. +}rndis_msg_type_t; + +/// RNDIS Message Status Values +typedef enum +{ + RNDIS_STATUS_SUCCESS = 0x00000000UL, ///< Success + RNDIS_STATUS_FAILURE = 0xC0000001UL, ///< Unspecified error + RNDIS_STATUS_INVALID_DATA = 0xC0010015UL, ///< Invalid data error + RNDIS_STATUS_NOT_SUPPORTED = 0xC00000BBUL, ///< Unsupported request error + RNDIS_STATUS_MEDIA_CONNECT = 0x4001000BUL, ///< Device is connected to a network medium. + RNDIS_STATUS_MEDIA_DISCONNECT = 0x4001000CUL ///< Device is disconnected from the medium. +}rndis_msg_status_t; + +#ifdef __CC_ARM +#pragma diag_default 66 // return Keil 66 to normal severity +#endif + +//--------------------------------------------------------------------+ +// MESSAGE STRUCTURE +//--------------------------------------------------------------------+ + +//------------- Initialize -------------// +/// \brief Initialize Message +/// \details This message MUST be sent by the host to initialize the device. +typedef struct { + uint32_t type ; ///< Message type, must be \ref RNDIS_MSG_INITIALIZE + uint32_t length ; ///< Message length in bytes, must be 0x18 + uint32_t request_id ; ///< A 32-bit integer value, generated by the host, used to match the host's sent request to the response from the device. + uint32_t major_version ; ///< The major version of the RNDIS Protocol implemented by the host. + uint32_t minor_version ; ///< The minor version of the RNDIS Protocol implemented by the host + uint32_t max_xfer_size ; ///< The maximum size, in bytes, of any single bus data transfer that the host expects to receive from the device. +}rndis_msg_initialize_t; + +/// \brief Initialize Complete Message +/// \details This message MUST be sent by the device in response to an initialize message. +typedef struct { + uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_INITIALIZE_CMPLT + uint32_t length ; ///< Message length in bytes, must be 0x30 + uint32_t request_id ; ///< A 32-bit integer value from \a request_id field of the \ref rndis_msg_initialize_t to which this message is a response. + uint32_t status ; ///< The initialization status of the device, has value from \ref rndis_msg_status_t + uint32_t major_version ; ///< the highest-numbered RNDIS Protocol version supported by the device. + uint32_t minor_version ; ///< the highest-numbered RNDIS Protocol version supported by the device. + uint32_t device_flags ; ///< MUST be set to 0x000000010. Other values are reserved for future use. + uint32_t medium ; ///< is 0x00 for RNDIS_MEDIUM_802_3 + uint32_t max_packet_per_xfer ; ///< The maximum number of concatenated \ref RNDIS_MSG_PACKET messages that the device can handle in a single bus transfer to it. This value MUST be at least 1. + uint32_t max_xfer_size ; ///< The maximum size, in bytes, of any single bus data transfer that the device expects to receive from the host. + uint32_t packet_alignment_factor ; ///< The byte alignment the device expects for each RNDIS message that is part of a multimessage transfer to it. The value is specified as an exponent of 2; for example, the host uses 2{PacketAlignmentFactor} as the alignment value. + uint32_t reserved[2] ; +} rndis_msg_initialize_cmplt_t; + +//------------- Query -------------// +/// \brief Query Message +/// \details This message MUST be sent by the host to query an OID. +typedef struct { + uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_QUERY + uint32_t length ; ///< Message length in bytes, including the header and the \a oid_buffer + uint32_t request_id ; ///< A 32-bit integer value, generated by the host, used to match the host's sent request to the response from the device. + uint32_t oid ; ///< The integer value of the host operating system-defined identifier, for the parameter of the device being queried for. + uint32_t buffer_length ; ///< The length, in bytes, of the input data required for the OID query. This MUST be set to 0 when there is no input data associated with the OID. + uint32_t buffer_offset ; ///< The offset, in bytes, from the beginning of \a request_id field where the input data for the query is located in the message. This value MUST be set to 0 when there is no input data associated with the OID. + uint32_t reserved ; + uint8_t oid_buffer[] ; ///< Flexible array contains the input data supplied by the host, required for the OID query request processing by the device, as per the host NDIS specification. +} rndis_msg_query_t, rndis_msg_set_t; + +TU_VERIFY_STATIC(sizeof(rndis_msg_query_t) == 28, "Make sure flexible array member does not affect layout"); + +/// \brief Query Complete Message +/// \details This message MUST be sent by the device in response to a query OID message. +typedef struct { + uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_QUERY_CMPLT + uint32_t length ; ///< Message length in bytes, including the header and the \a oid_buffer + uint32_t request_id ; ///< A 32-bit integer value from \a request_id field of the \ref rndis_msg_query_t to which this message is a response. + uint32_t status ; ///< The status of processing for the query request, has value from \ref rndis_msg_status_t. + uint32_t buffer_length ; ///< The length, in bytes, of the data in the response to the query. This MUST be set to 0 when there is no OIDInputBuffer. + uint32_t buffer_offset ; ///< The offset, in bytes, from the beginning of \a request_id field where the response data for the query is located in the message. This MUST be set to 0 when there is no \ref oid_buffer. + uint8_t oid_buffer[] ; ///< Flexible array member contains the response data to the OID query request as specified by the host. +} rndis_msg_query_cmplt_t; + +TU_VERIFY_STATIC(sizeof(rndis_msg_query_cmplt_t) == 24, "Make sure flexible array member does not affect layout"); + +//------------- Reset -------------// +/// \brief Reset Message +/// \details This message MUST be sent by the host to perform a soft reset on the device. +typedef struct { + uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_RESET + uint32_t length ; ///< Message length in bytes, MUST be 0x06 + uint32_t reserved ; +} rndis_msg_reset_t; + +/// \brief Reset Complete Message +/// \details This message MUST be sent by the device in response to a reset message. +typedef struct { + uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_RESET_CMPLT + uint32_t length ; ///< Message length in bytes, MUST be 0x10 + uint32_t status ; ///< The status of processing for the \ref rndis_msg_reset_t, has value from \ref rndis_msg_status_t. + uint32_t addressing_reset ; ///< This field indicates whether the addressing information, which is the multicast address list or packet filter, has been lost during the reset operation. This MUST be set to 0x00000001 if the device requires that the host to resend addressing information or MUST be set to zero otherwise. +} rndis_msg_reset_cmplt_t; + +//typedef struct { +// uint32_t type; +// uint32_t length; +// uint32_t status; +// uint32_t buffer_length; +// uint32_t buffer_offset; +// uint32_t diagnostic_status; // optional +// uint32_t diagnostic_error_offset; // optional +// uint32_t status_buffer[0]; // optional +//} rndis_msg_indicate_status_t; + +/// \brief Keep Alive Message +/// \details This message MUST be sent by the host to check that device is still responsive. It is optional for the device to send this message to check if the host is active +typedef struct { + uint32_t type ; ///< Message Type + uint32_t length ; ///< Message length in bytes, MUST be 0x10 + uint32_t request_id ; +} rndis_msg_keep_alive_t, rndis_msg_halt_t; + +/// \brief Set Complete Message +/// \brief This message MUST be sent in response to a the request message +typedef struct { + uint32_t type ; ///< Message Type + uint32_t length ; ///< Message length in bytes, MUST be 0x10 + uint32_t request_id ; ///< must be the same as requesting message + uint32_t status ; ///< The status of processing for the request message request by the device to which this message is the response. +} rndis_msg_set_cmplt_t, rndis_msg_keep_alive_cmplt_t; + +/// \brief Packet Data Message +/// \brief This message MUST be used by the host and the device to send network data to one another. +typedef struct { + uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_PACKET + uint32_t length ; ///< Message length in bytes, The total length of this RNDIS message including the header, payload, and padding. + uint32_t data_offset ; ///< Specifies the offset, in bytes, from the start of this \a data_offset field of this message to the start of the data. This MUST be an integer multiple of 4. + uint32_t data_length ; ///< Specifies the number of bytes in the payload of this message. + uint32_t out_of_band_data_offet ; ///< Specifies the offset, in bytes, of the first out-of-band data record from the start of the DataOffset field in this message. MUST be an integer multiple of 4 when out-of-band data is present or set to 0 otherwise. When there are multiple out-ofband data records, each subsequent record MUST immediately follow the previous out-of-band data record. + uint32_t out_of_band_data_length ; ///< Specifies, in bytes, the total length of the out-of-band data. + uint32_t num_out_of_band_data_elements ; ///< Specifies the number of out-of-band records in this message. + uint32_t per_packet_info_offset ; ///< Specifies the offset, in bytes, of the start of per-packet-info data record from the start of the \a data_offset field in this message. MUST be an integer multiple of 4 when per-packet-info data record is present or MUST be set to 0 otherwise. When there are multiple per-packet-info data records, each subsequent record MUST immediately follow the previous record. + uint32_t per_packet_info_length ; ///< Specifies, in bytes, the total length of per-packetinformation contained in this message. + uint32_t reserved[2] ; + uint32_t payload[0] ; ///< Network data contained in this message. + + // uint8_t padding[0] + // Additional bytes of zeros added at the end of the message to comply with + // the internal and external padding requirements. Internal padding SHOULD be as per the + // specification of the out-of-band data record and per-packet-info data record. The external + //padding size SHOULD be determined based on the PacketAlignmentFactor field specification + //in REMOTE_NDIS_INITIALIZE_CMPLT message by the device, when multiple + //REMOTE_NDIS_PACKET_MSG messages are bundled together in a single bus-native message. + //In this case, all but the very last REMOTE_NDIS_PACKET_MSG MUST respect the + //PacketAlignmentFactor field. + + // rndis_msg_packet_t [0] : (optional) more packet if multiple packet per bus transaction is supported +} rndis_msg_packet_t; + + +typedef struct { + uint32_t size ; ///< Length, in bytes, of this header and appended data and padding. This value MUST be an integer multiple of 4. + uint32_t type ; ///< MUST be as per host operating system specification. + uint32_t offset ; ///< The byte offset from the beginning of this record to the beginning of data. + uint32_t data[0] ; ///< Flexible array contains data +} rndis_msg_out_of_band_data_t, rndis_msg_per_packet_info_t; + +//--------------------------------------------------------------------+ +// NDIS Object ID +//--------------------------------------------------------------------+ + +/// NDIS Object ID +typedef enum +{ + //------------- General Required OIDs -------------// + RNDIS_OID_GEN_SUPPORTED_LIST = 0x00010101, ///< List of supported OIDs + RNDIS_OID_GEN_HARDWARE_STATUS = 0x00010102, ///< Hardware status + RNDIS_OID_GEN_MEDIA_SUPPORTED = 0x00010103, ///< Media types supported (encoded) + RNDIS_OID_GEN_MEDIA_IN_USE = 0x00010104, ///< Media types in use (encoded) + RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD = 0x00010105, ///< + RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE = 0x00010106, ///< Maximum frame size in bytes + RNDIS_OID_GEN_LINK_SPEED = 0x00010107, ///< Link speed in units of 100 bps + RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE = 0x00010108, ///< Transmit buffer space + RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE = 0x00010109, ///< Receive buffer space + RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE = 0x0001010A, ///< Minimum amount of storage, in bytes, that a single packet occupies in the transmit buffer space of the NIC + RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE = 0x0001010B, ///< Amount of storage, in bytes, that a single packet occupies in the receive buffer space of the NIC + RNDIS_OID_GEN_VENDOR_ID = 0x0001010C, ///< Vendor NIC code + RNDIS_OID_GEN_VENDOR_DESCRIPTION = 0x0001010D, ///< Vendor network card description + RNDIS_OID_GEN_CURRENT_PACKET_FILTER = 0x0001010E, ///< Current packet filter (encoded) + RNDIS_OID_GEN_CURRENT_LOOKAHEAD = 0x0001010F, ///< Current lookahead size in bytes + RNDIS_OID_GEN_DRIVER_VERSION = 0x00010110, ///< NDIS version number used by the driver + RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE = 0x00010111, ///< Maximum total packet length in bytes + RNDIS_OID_GEN_PROTOCOL_OPTIONS = 0x00010112, ///< Optional protocol flags (encoded) + RNDIS_OID_GEN_MAC_OPTIONS = 0x00010113, ///< Optional NIC flags (encoded) + RNDIS_OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114, ///< Whether the NIC is connected to the network + RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS = 0x00010115, ///< The maximum number of send packets the driver can accept per call to its MiniportSendPacketsfunction + + //------------- General Optional OIDs -------------// + RNDIS_OID_GEN_VENDOR_DRIVER_VERSION = 0x00010116, ///< Vendor-assigned version number of the driver + RNDIS_OID_GEN_SUPPORTED_GUIDS = 0x00010117, ///< The custom GUIDs (Globally Unique Identifier) supported by the miniport driver + RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES = 0x00010118, ///< List of network-layer addresses associated with the binding between a transport and the driver + RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET = 0x00010119, ///< Size of packets' additional headers + RNDIS_OID_GEN_MEDIA_CAPABILITIES = 0x00010201, ///< + RNDIS_OID_GEN_PHYSICAL_MEDIUM = 0x00010202, ///< Physical media supported by the miniport driver (encoded) + + //------------- 802.3 Objects (Ethernet) -------------// + RNDIS_OID_802_3_PERMANENT_ADDRESS = 0x01010101, ///< Permanent station address + RNDIS_OID_802_3_CURRENT_ADDRESS = 0x01010102, ///< Current station address + RNDIS_OID_802_3_MULTICAST_LIST = 0x01010103, ///< Current multicast address list + RNDIS_OID_802_3_MAXIMUM_LIST_SIZE = 0x01010104, ///< Maximum size of multicast address list +} rndis_oid_type_t; + +/// RNDIS Packet Filter Bits \ref RNDIS_OID_GEN_CURRENT_PACKET_FILTER. +typedef enum +{ + RNDIS_PACKET_TYPE_DIRECTED = 0x00000001, ///< Directed packets. Directed packets contain a destination address equal to the station address of the NIC. + RNDIS_PACKET_TYPE_MULTICAST = 0x00000002, ///< Multicast address packets sent to addresses in the multicast address list. + RNDIS_PACKET_TYPE_ALL_MULTICAST = 0x00000004, ///< All multicast address packets, not just the ones enumerated in the multicast address list. + RNDIS_PACKET_TYPE_BROADCAST = 0x00000008, ///< Broadcast packets. + RNDIS_PACKET_TYPE_SOURCE_ROUTING = 0x00000010, ///< All source routing packets. If the protocol driver sets this bit, the NDIS library attempts to act as a source routing bridge. + RNDIS_PACKET_TYPE_PROMISCUOUS = 0x00000020, ///< Specifies all packets regardless of whether VLAN filtering is enabled or not and whether the VLAN identifier matches or not. + RNDIS_PACKET_TYPE_SMT = 0x00000040, ///< SMT packets that an FDDI NIC receives. + RNDIS_PACKET_TYPE_ALL_LOCAL = 0x00000080, ///< All packets sent by installed protocols and all packets indicated by the NIC that is identified by a given NdisBindingHandle. + RNDIS_PACKET_TYPE_GROUP = 0x00001000, ///< Packets sent to the current group address. + RNDIS_PACKET_TYPE_ALL_FUNCTIONAL = 0x00002000, ///< All functional address packets, not just the ones in the current functional address. + RNDIS_PACKET_TYPE_FUNCTIONAL = 0x00004000, ///< Functional address packets sent to addresses included in the current functional address. + RNDIS_PACKET_TYPE_MAC_FRAME = 0x00008000, ///< NIC driver frames that a Token Ring NIC receives. + RNDIS_PACKET_TYPE_NO_LOCAL = 0x00010000, +} rndis_packet_filter_type_t; + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CDC_RNDIS_H_ */ + +/** @} */ +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis_host.c b/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis_host.c new file mode 100644 index 0000000..8f28f51 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis_host.c @@ -0,0 +1,289 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUH_ENABLED && CFG_TUH_CDC && CFG_TUH_CDC_RNDIS) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "common/tusb_common.h" +#include "cdc_host.h" +#include "cdc_rndis_host.h" + +#if 0 // TODO remove subtask related macros later +// Sub Task +#define OSAL_SUBTASK_BEGIN +#define OSAL_SUBTASK_END return TUSB_ERROR_NONE; + +#define STASK_RETURN(_error) return _error; +#define STASK_INVOKE(_subtask, _status) (_status) = _subtask +#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED) +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +#define RNDIS_MSG_PAYLOAD_MAX (1024*4) + +CFG_TUSB_MEM_SECTION static uint8_t msg_notification[CFG_TUH_DEVICE_MAX][8]; +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t msg_payload[RNDIS_MSG_PAYLOAD_MAX]; + +static rndish_data_t rndish_data[CFG_TUH_DEVICE_MAX]; + +// TODO Microsoft requires message length for any get command must be at least 4096 bytes + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static tusb_error_t rndis_body_subtask(void); +static tusb_error_t send_message_get_response_subtask( uint8_t dev_addr, cdch_data_t *p_cdc, + uint8_t * p_mess, uint32_t mess_length, + uint8_t *p_response ); + +//--------------------------------------------------------------------+ +// APPLICATION API +//--------------------------------------------------------------------+ +tusb_error_t tusbh_cdc_rndis_get_mac_addr(uint8_t dev_addr, uint8_t mac_address[6]) +{ + TU_ASSERT( tusbh_cdc_rndis_is_mounted(dev_addr), TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED); + TU_VERIFY( mac_address, TUSB_ERROR_INVALID_PARA); + + memcpy(mac_address, rndish_data[dev_addr-1].mac_address, 6); + + return TUSB_ERROR_NONE; +} + +//--------------------------------------------------------------------+ +// IMPLEMENTATION +//--------------------------------------------------------------------+ + +// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper +// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with +// forever loop cannot have any return at all. +OSAL_TASK_FUNCTION(cdch_rndis_task) (void* param;) +{ + OSAL_TASK_BEGIN + rndis_body_subtask(); + OSAL_TASK_END +} + +static tusb_error_t rndis_body_subtask(void) +{ + static uint8_t relative_addr; + + OSAL_SUBTASK_BEGIN + + for (relative_addr = 0; relative_addr < CFG_TUH_DEVICE_MAX; relative_addr++) + { + + } + + osal_task_delay(100); + + OSAL_SUBTASK_END +} + +//--------------------------------------------------------------------+ +// RNDIS-CDC Driver API +//--------------------------------------------------------------------+ +void rndish_init(void) +{ + tu_memclr(rndish_data, sizeof(rndish_data_t)*CFG_TUH_DEVICE_MAX); + + //------------- Task creation -------------// + + //------------- semaphore creation for notificaiton pipe -------------// + for(uint8_t i=0; itype == RNDIS_MSG_INITIALIZE_CMPLT && p_init_cmpt->status == RNDIS_STATUS_SUCCESS && + p_init_cmpt->max_packet_per_xfer == 1 && p_init_cmpt->max_xfer_size <= RNDIS_MSG_PAYLOAD_MAX); + rndish_data[dev_addr-1].max_xfer_size = p_init_cmpt->max_xfer_size; + + //------------- Message Query 802.3 Permanent Address -------------// + memcpy(msg_payload, &msg_query_permanent_addr, sizeof(rndis_msg_query_t)); + tu_memclr(msg_payload + sizeof(rndis_msg_query_t), 6); // 6 bytes for MAC address + + STASK_INVOKE( + send_message_get_response_subtask( dev_addr, p_cdc, + msg_payload, sizeof(rndis_msg_query_t) + 6, + msg_payload), + error + ); + if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); + + rndis_msg_query_cmplt_t * const p_query_cmpt = (rndis_msg_query_cmplt_t *) msg_payload; + STASK_ASSERT(p_query_cmpt->type == RNDIS_MSG_QUERY_CMPLT && p_query_cmpt->status == RNDIS_STATUS_SUCCESS); + memcpy(rndish_data[dev_addr-1].mac_address, msg_payload + 8 + p_query_cmpt->buffer_offset, 6); + + //------------- Set OID_GEN_CURRENT_PACKET_FILTER to (DIRECTED | MULTICAST | BROADCAST) -------------// + memcpy(msg_payload, &msg_set_packet_filter, sizeof(rndis_msg_set_t)); + tu_memclr(msg_payload + sizeof(rndis_msg_set_t), 4); // 4 bytes for filter flags + ((rndis_msg_set_t*) msg_payload)->oid_buffer[0] = (RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_MULTICAST | RNDIS_PACKET_TYPE_BROADCAST); + + STASK_INVOKE( + send_message_get_response_subtask( dev_addr, p_cdc, + msg_payload, sizeof(rndis_msg_set_t) + 4, + msg_payload), + error + ); + if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); + + rndis_msg_set_cmplt_t * const p_set_cmpt = (rndis_msg_set_cmplt_t *) msg_payload; + STASK_ASSERT(p_set_cmpt->type == RNDIS_MSG_SET_CMPLT && p_set_cmpt->status == RNDIS_STATUS_SUCCESS); + + tusbh_cdc_rndis_mounted_cb(dev_addr); + + OSAL_SUBTASK_END +} + +void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes) +{ + if ( pipehandle_is_equal(pipe_hdl, p_cdc->pipe_notification) ) + { + osal_semaphore_post( rndish_data[pipe_hdl.dev_addr-1].sem_notification_hdl ); + } +} + +//--------------------------------------------------------------------+ +// INTERNAL & HELPER +//--------------------------------------------------------------------+ +static tusb_error_t send_message_get_response_subtask( uint8_t dev_addr, cdch_data_t *p_cdc, + uint8_t * p_mess, uint32_t mess_length, + uint8_t *p_response) +{ + tusb_error_t error; + + OSAL_SUBTASK_BEGIN + + //------------- Send RNDIS Control Message -------------// + STASK_INVOKE( + usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE), + CDC_REQUEST_SEND_ENCAPSULATED_COMMAND, 0, p_cdc->interface_number, + mess_length, p_mess), + error + ); + if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); + + //------------- waiting for Response Available notification -------------// + (void) usbh_edpt_xfer(p_cdc->pipe_notification, msg_notification[dev_addr-1], 8); + osal_semaphore_wait(rndish_data[dev_addr-1].sem_notification_hdl, OSAL_TIMEOUT_NORMAL, &error); + if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); + STASK_ASSERT(msg_notification[dev_addr-1][0] == 1); + + //------------- Get RNDIS Message Initialize Complete -------------// + STASK_INVOKE( + usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE), + CDC_REQUEST_GET_ENCAPSULATED_RESPONSE, 0, p_cdc->interface_number, + RNDIS_MSG_PAYLOAD_MAX, p_response), + error + ); + if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); + + OSAL_SUBTASK_END +} + +//static tusb_error_t send_process_msg_initialize_subtask(uint8_t dev_addr, cdch_data_t *p_cdc) +//{ +// tusb_error_t error; +// +// OSAL_SUBTASK_BEGIN +// +// *((rndis_msg_initialize_t*) msg_payload) = (rndis_msg_initialize_t) +// { +// .type = RNDIS_MSG_INITIALIZE, +// .length = sizeof(rndis_msg_initialize_t), +// .request_id = 1, // TODO should use some magic number +// .major_version = 1, +// .minor_version = 0, +// .max_xfer_size = 0x4000 // TODO mimic windows +// }; +// +// +// +// OSAL_SUBTASK_END +//} +#endif diff --git a/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis_host.h b/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis_host.h new file mode 100644 index 0000000..170cb3b --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/cdc/cdc_rndis_host.h @@ -0,0 +1,63 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup CDC_RNDIS + * \defgroup CDC_RNSID_Host Host + * @{ */ + +#ifndef _TUSB_CDC_RNDIS_HOST_H_ +#define _TUSB_CDC_RNDIS_HOST_H_ + +#include "common/tusb_common.h" +#include "host/usbh.h" +#include "cdc_rndis.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// INTERNAL RNDIS-CDC Driver API +//--------------------------------------------------------------------+ +typedef struct { + OSAL_SEM_DEF(semaphore_notification); + osal_semaphore_handle_t sem_notification_hdl; // used to wait on notification pipe + uint32_t max_xfer_size; // got from device's msg initialize complete + uint8_t mac_address[6]; +}rndish_data_t; + +void rndish_init(void); +tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc); +void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes); +void rndish_close(uint8_t dev_addr); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CDC_RNDIS_HOST_H_ */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/class/dfu/dfu.h b/circuitpython/lib/tinyusb/src/class/dfu/dfu.h new file mode 100644 index 0000000..114c827 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/dfu/dfu.h @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 XMOS LIMITED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_DFU_H_ +#define _TUSB_DFU_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Common Definitions +//--------------------------------------------------------------------+ + +// DFU Protocol +typedef enum +{ + DFU_PROTOCOL_RT = 0x01, + DFU_PROTOCOL_DFU = 0x02, +} dfu_protocol_type_t; + +// DFU Descriptor Type +typedef enum +{ + DFU_DESC_FUNCTIONAL = 0x21, +} dfu_descriptor_type_t; + +// DFU Requests +typedef enum { + DFU_REQUEST_DETACH = 0, + DFU_REQUEST_DNLOAD = 1, + DFU_REQUEST_UPLOAD = 2, + DFU_REQUEST_GETSTATUS = 3, + DFU_REQUEST_CLRSTATUS = 4, + DFU_REQUEST_GETSTATE = 5, + DFU_REQUEST_ABORT = 6, +} dfu_requests_t; + +// DFU States +typedef enum { + APP_IDLE = 0, + APP_DETACH = 1, + DFU_IDLE = 2, + DFU_DNLOAD_SYNC = 3, + DFU_DNBUSY = 4, + DFU_DNLOAD_IDLE = 5, + DFU_MANIFEST_SYNC = 6, + DFU_MANIFEST = 7, + DFU_MANIFEST_WAIT_RESET = 8, + DFU_UPLOAD_IDLE = 9, + DFU_ERROR = 10, +} dfu_state_t; + +// DFU Status +typedef enum { + DFU_STATUS_OK = 0x00, + DFU_STATUS_ERR_TARGET = 0x01, + DFU_STATUS_ERR_FILE = 0x02, + DFU_STATUS_ERR_WRITE = 0x03, + DFU_STATUS_ERR_ERASE = 0x04, + DFU_STATUS_ERR_CHECK_ERASED = 0x05, + DFU_STATUS_ERR_PROG = 0x06, + DFU_STATUS_ERR_VERIFY = 0x07, + DFU_STATUS_ERR_ADDRESS = 0x08, + DFU_STATUS_ERR_NOTDONE = 0x09, + DFU_STATUS_ERR_FIRMWARE = 0x0A, + DFU_STATUS_ERR_VENDOR = 0x0B, + DFU_STATUS_ERR_USBR = 0x0C, + DFU_STATUS_ERR_POR = 0x0D, + DFU_STATUS_ERR_UNKNOWN = 0x0E, + DFU_STATUS_ERR_STALLEDPKT = 0x0F, +} dfu_status_t; + +#define DFU_ATTR_CAN_DOWNLOAD (1u << 0) +#define DFU_ATTR_CAN_UPLOAD (1u << 1) +#define DFU_ATTR_MANIFESTATION_TOLERANT (1u << 2) +#define DFU_ATTR_WILL_DETACH (1u << 3) + +// DFU Status Request Payload +typedef struct TU_ATTR_PACKED +{ + uint8_t bStatus; + uint8_t bwPollTimeout[3]; + uint8_t bState; + uint8_t iString; +} dfu_status_response_t; + +TU_VERIFY_STATIC( sizeof(dfu_status_response_t) == 6, "size is not correct"); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_DFU_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/dfu/dfu_device.c b/circuitpython/lib/tinyusb/src/class/dfu/dfu_device.c new file mode 100644 index 0000000..8d859d2 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/dfu/dfu_device.c @@ -0,0 +1,458 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 XMOS LIMITED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_DFU) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "dfu_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +typedef struct +{ + uint8_t attrs; + uint8_t alt; + + dfu_state_t state; + dfu_status_t status; + + bool flashing_in_progress; + uint16_t block; + uint16_t length; + + CFG_TUSB_MEM_ALIGN uint8_t transfer_buf[CFG_TUD_DFU_XFER_BUFSIZE]; +} dfu_state_ctx_t; + +// Only a single dfu state is allowed +CFG_TUSB_MEM_SECTION static dfu_state_ctx_t _dfu_ctx; + +static void reset_state(void) +{ + _dfu_ctx.state = DFU_IDLE; + _dfu_ctx.status = DFU_STATUS_OK; + _dfu_ctx.flashing_in_progress = false; +} + +static bool reply_getstatus(uint8_t rhport, tusb_control_request_t const * request, dfu_state_t state, dfu_status_t status, uint32_t timeout); +static bool process_download_get_status(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +static bool process_manifest_get_status(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); + +//--------------------------------------------------------------------+ +// Debug +//--------------------------------------------------------------------+ +#if CFG_TUSB_DEBUG >= 2 + +static tu_lookup_entry_t const _dfu_request_lookup[] = +{ + { .key = DFU_REQUEST_DETACH , .data = "DETACH" }, + { .key = DFU_REQUEST_DNLOAD , .data = "DNLOAD" }, + { .key = DFU_REQUEST_UPLOAD , .data = "UPLOAD" }, + { .key = DFU_REQUEST_GETSTATUS , .data = "GETSTATUS" }, + { .key = DFU_REQUEST_CLRSTATUS , .data = "CLRSTATUS" }, + { .key = DFU_REQUEST_GETSTATE , .data = "GETSTATE" }, + { .key = DFU_REQUEST_ABORT , .data = "ABORT" }, +}; + +static tu_lookup_table_t const _dfu_request_table = +{ + .count = TU_ARRAY_SIZE(_dfu_request_lookup), + .items = _dfu_request_lookup +}; + +static tu_lookup_entry_t const _dfu_state_lookup[] = +{ + { .key = APP_IDLE , .data = "APP_IDLE" }, + { .key = APP_DETACH , .data = "APP_DETACH" }, + { .key = DFU_IDLE , .data = "IDLE" }, + { .key = DFU_DNLOAD_SYNC , .data = "DNLOAD_SYNC" }, + { .key = DFU_DNBUSY , .data = "DNBUSY" }, + { .key = DFU_DNLOAD_IDLE , .data = "DNLOAD_IDLE" }, + { .key = DFU_MANIFEST_SYNC , .data = "MANIFEST_SYNC" }, + { .key = DFU_MANIFEST , .data = "MANIFEST" }, + { .key = DFU_MANIFEST_WAIT_RESET , .data = "MANIFEST_WAIT_RESET" }, + { .key = DFU_UPLOAD_IDLE , .data = "UPLOAD_IDLE" }, + { .key = DFU_ERROR , .data = "ERROR" }, +}; + +static tu_lookup_table_t const _dfu_state_table = +{ + .count = TU_ARRAY_SIZE(_dfu_state_lookup), + .items = _dfu_state_lookup +}; + +static tu_lookup_entry_t const _dfu_status_lookup[] = +{ + { .key = DFU_STATUS_OK , .data = "OK" }, + { .key = DFU_STATUS_ERR_TARGET , .data = "errTARGET" }, + { .key = DFU_STATUS_ERR_FILE , .data = "errFILE" }, + { .key = DFU_STATUS_ERR_WRITE , .data = "errWRITE" }, + { .key = DFU_STATUS_ERR_ERASE , .data = "errERASE" }, + { .key = DFU_STATUS_ERR_CHECK_ERASED , .data = "errCHECK_ERASED" }, + { .key = DFU_STATUS_ERR_PROG , .data = "errPROG" }, + { .key = DFU_STATUS_ERR_VERIFY , .data = "errVERIFY" }, + { .key = DFU_STATUS_ERR_ADDRESS , .data = "errADDRESS" }, + { .key = DFU_STATUS_ERR_NOTDONE , .data = "errNOTDONE" }, + { .key = DFU_STATUS_ERR_FIRMWARE , .data = "errFIRMWARE" }, + { .key = DFU_STATUS_ERR_VENDOR , .data = "errVENDOR" }, + { .key = DFU_STATUS_ERR_USBR , .data = "errUSBR" }, + { .key = DFU_STATUS_ERR_POR , .data = "errPOR" }, + { .key = DFU_STATUS_ERR_UNKNOWN , .data = "errUNKNOWN" }, + { .key = DFU_STATUS_ERR_STALLEDPKT , .data = "errSTALLEDPKT" }, +}; + +static tu_lookup_table_t const _dfu_status_table = +{ + .count = TU_ARRAY_SIZE(_dfu_status_lookup), + .items = _dfu_status_lookup +}; + +#endif + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void dfu_moded_reset(uint8_t rhport) +{ + (void) rhport; + + _dfu_ctx.attrs = 0; + _dfu_ctx.alt = 0; + + reset_state(); +} + +void dfu_moded_init(void) +{ + dfu_moded_reset(0); +} + +uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + (void) rhport; + + //------------- Interface (with Alt) descriptor -------------// + uint8_t const itf_num = itf_desc->bInterfaceNumber; + uint8_t alt_count = 0; + + uint16_t drv_len = 0; + while(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS && itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU) + { + TU_ASSERT(max_len > drv_len, 0); + + // Alternate must have the same interface number + TU_ASSERT(itf_desc->bInterfaceNumber == itf_num, 0); + + // Alt should increase by one every time + TU_ASSERT(itf_desc->bAlternateSetting == alt_count, 0); + alt_count++; + + drv_len += tu_desc_len(itf_desc); + itf_desc = (tusb_desc_interface_t const *) tu_desc_next(itf_desc); + } + + //------------- DFU Functional descriptor -------------// + tusb_desc_dfu_functional_t const *func_desc = (tusb_desc_dfu_functional_t const *) itf_desc; + TU_ASSERT(tu_desc_type(func_desc) == TUSB_DESC_FUNCTIONAL, 0); + drv_len += sizeof(tusb_desc_dfu_functional_t); + + _dfu_ctx.attrs = func_desc->bAttributes; + + // CFG_TUD_DFU_XFER_BUFSIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR + uint16_t const transfer_size = tu_le16toh( tu_unaligned_read16((uint8_t const*) func_desc + offsetof(tusb_desc_dfu_functional_t, wTransferSize)) ); + TU_ASSERT(transfer_size <= CFG_TUD_DFU_XFER_BUFSIZE, drv_len); + + return drv_len; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); + + TU_LOG2(" DFU State : %s, Status: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state), tu_lookup_find(&_dfu_status_table, _dfu_ctx.status)); + + if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) + { + // Standard request include GET/SET_INTERFACE + switch ( request->bRequest ) + { + case TUSB_REQ_SET_INTERFACE: + if ( stage == CONTROL_STAGE_SETUP ) + { + // Switch Alt interface and reset state machine + _dfu_ctx.alt = (uint8_t) request->wValue; + reset_state(); + return tud_control_status(rhport, request); + } + break; + + case TUSB_REQ_GET_INTERFACE: + if(stage == CONTROL_STAGE_SETUP) + { + return tud_control_xfer(rhport, request, &_dfu_ctx.alt, 1); + } + break; + + // unsupported request + default: return false; + } + } + else if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS ) + { + TU_LOG2(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest)); + + // Class request + switch ( request->bRequest ) + { + case DFU_REQUEST_DETACH: + if ( stage == CONTROL_STAGE_SETUP ) + { + tud_control_status(rhport, request); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + if ( tud_dfu_detach_cb ) tud_dfu_detach_cb(); + } + break; + + case DFU_REQUEST_CLRSTATUS: + if ( stage == CONTROL_STAGE_SETUP ) + { + reset_state(); + tud_control_status(rhport, request); + } + break; + + case DFU_REQUEST_GETSTATE: + if ( stage == CONTROL_STAGE_SETUP ) + { + tud_control_xfer(rhport, request, &_dfu_ctx.state, 1); + } + break; + + case DFU_REQUEST_ABORT: + if ( stage == CONTROL_STAGE_SETUP ) + { + reset_state(); + tud_control_status(rhport, request); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + if ( tud_dfu_abort_cb ) tud_dfu_abort_cb(_dfu_ctx.alt); + } + break; + + case DFU_REQUEST_UPLOAD: + if ( stage == CONTROL_STAGE_SETUP ) + { + TU_VERIFY(_dfu_ctx.attrs & DFU_ATTR_CAN_UPLOAD); + TU_VERIFY(tud_dfu_upload_cb); + TU_VERIFY(request->wLength <= CFG_TUD_DFU_XFER_BUFSIZE); + + uint16_t const xfer_len = tud_dfu_upload_cb(_dfu_ctx.alt, request->wValue, _dfu_ctx.transfer_buf, request->wLength); + + return tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, xfer_len); + } + break; + + case DFU_REQUEST_DNLOAD: + if ( stage == CONTROL_STAGE_SETUP ) + { + TU_VERIFY(_dfu_ctx.attrs & DFU_ATTR_CAN_DOWNLOAD); + TU_VERIFY(_dfu_ctx.state == DFU_IDLE || _dfu_ctx.state == DFU_DNLOAD_IDLE); + TU_VERIFY(request->wLength <= CFG_TUD_DFU_XFER_BUFSIZE); + + // set to true for both download and manifest + _dfu_ctx.flashing_in_progress = true; + + // save block and length for flashing + _dfu_ctx.block = request->wValue; + _dfu_ctx.length = request->wLength; + + if ( request->wLength ) + { + // Download with payload -> transition to DOWNLOAD SYNC + _dfu_ctx.state = DFU_DNLOAD_SYNC; + return tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, request->wLength); + } + else + { + // Download is complete -> transition to MANIFEST SYNC + _dfu_ctx.state = DFU_MANIFEST_SYNC; + return tud_control_status(rhport, request); + } + } + break; + + case DFU_REQUEST_GETSTATUS: + switch ( _dfu_ctx.state ) + { + case DFU_DNLOAD_SYNC: + return process_download_get_status(rhport, stage, request); + break; + + case DFU_MANIFEST_SYNC: + return process_manifest_get_status(rhport, stage, request); + break; + + default: + if ( stage == CONTROL_STAGE_SETUP ) return reply_getstatus(rhport, request, _dfu_ctx.state, _dfu_ctx.status, 0); + break; + } + break; + + default: return false; // stall unsupported request + } + }else + { + return false; // unsupported request + } + + return true; +} + +void tud_dfu_finish_flashing(uint8_t status) +{ + _dfu_ctx.flashing_in_progress = false; + + if ( status == DFU_STATUS_OK ) + { + if (_dfu_ctx.state == DFU_DNBUSY) + { + _dfu_ctx.state = DFU_DNLOAD_SYNC; + } + else if (_dfu_ctx.state == DFU_MANIFEST) + { + _dfu_ctx.state = (_dfu_ctx.attrs & DFU_ATTR_MANIFESTATION_TOLERANT) + ? DFU_MANIFEST_SYNC : DFU_MANIFEST_WAIT_RESET; + } + } + else + { + // failed while flashing, move to dfuError + _dfu_ctx.state = DFU_ERROR; + _dfu_ctx.status = (dfu_status_t)status; + } +} + +static bool process_download_get_status(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + if ( stage == CONTROL_STAGE_SETUP ) + { + // only transition to next state on CONTROL_STAGE_ACK + dfu_state_t next_state; + uint32_t timeout; + + if ( _dfu_ctx.flashing_in_progress ) + { + next_state = DFU_DNBUSY; + timeout = tud_dfu_get_timeout_cb(_dfu_ctx.alt, (uint8_t) next_state); + } + else + { + next_state = DFU_DNLOAD_IDLE; + timeout = 0; + } + + return reply_getstatus(rhport, request, next_state, _dfu_ctx.status, timeout); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + if ( _dfu_ctx.flashing_in_progress ) + { + _dfu_ctx.state = DFU_DNBUSY; + tud_dfu_download_cb(_dfu_ctx.alt, _dfu_ctx.block, _dfu_ctx.transfer_buf, _dfu_ctx.length); + }else + { + _dfu_ctx.state = DFU_DNLOAD_IDLE; + } + } + + return true; +} + +static bool process_manifest_get_status(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + if ( stage == CONTROL_STAGE_SETUP ) + { + // only transition to next state on CONTROL_STAGE_ACK + dfu_state_t next_state; + uint32_t timeout; + + if ( _dfu_ctx.flashing_in_progress ) + { + next_state = DFU_MANIFEST; + timeout = tud_dfu_get_timeout_cb(_dfu_ctx.alt, next_state); + } + else + { + next_state = DFU_IDLE; + timeout = 0; + } + + return reply_getstatus(rhport, request, next_state, _dfu_ctx.status, timeout); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + if ( _dfu_ctx.flashing_in_progress ) + { + _dfu_ctx.state = DFU_MANIFEST; + tud_dfu_manifest_cb(_dfu_ctx.alt); + } + else + { + _dfu_ctx.state = DFU_IDLE; + } + } + + return true; +} + +static bool reply_getstatus(uint8_t rhport, tusb_control_request_t const * request, dfu_state_t state, dfu_status_t status, uint32_t timeout) +{ + dfu_status_response_t resp; + resp.bStatus = (uint8_t) status; + resp.bwPollTimeout[0] = TU_U32_BYTE0(timeout); + resp.bwPollTimeout[1] = TU_U32_BYTE1(timeout); + resp.bwPollTimeout[2] = TU_U32_BYTE2(timeout); + resp.bState = (uint8_t) state; + resp.iString = 0; + + return tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_response_t)); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/dfu/dfu_device.h b/circuitpython/lib/tinyusb/src/class/dfu/dfu_device.h new file mode 100644 index 0000000..fecf859 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/dfu/dfu_device.h @@ -0,0 +1,98 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 XMOS LIMITED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_DFU_DEVICE_H_ +#define _TUSB_DFU_DEVICE_H_ + +#include "dfu.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Class Driver Default Configure & Validation +//--------------------------------------------------------------------+ + +#if !defined(CFG_TUD_DFU_XFER_BUFSIZE) + #error "CFG_TUD_DFU_XFER_BUFSIZE must be defined, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR" +#endif + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + +// Must be called when the application is done with flashing started by +// tud_dfu_download_cb() and tud_dfu_manifest_cb(). +// status is DFU_STATUS_OK if successful, any other error status will cause state to enter dfuError +void tud_dfu_finish_flashing(uint8_t status); + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. + +// Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) +// Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. +// During this period, USB host won't try to communicate with us. +uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state); + +// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests +// This callback could be returned before flashing op is complete (async). +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_download_cb (uint8_t alt, uint16_t block_num, uint8_t const *data, uint16_t length); + +// Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest) +// Application can do checksum, or actual flashing if buffered entire image previously. +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_manifest_cb(uint8_t alt); + +// Invoked when received DFU_UPLOAD request +// Application must populate data with up to length bytes and +// Return the number of written bytes +TU_ATTR_WEAK uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); + +// Invoked when a DFU_DETACH request is received +TU_ATTR_WEAK void tud_dfu_detach_cb(void); + +// Invoked when the Host has terminated a download or upload transfer +TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void dfu_moded_init(void); +void dfu_moded_reset(uint8_t rhport); +uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_DFU_MODE_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/dfu/dfu_rt_device.c b/circuitpython/lib/tinyusb/src/class/dfu/dfu_rt_device.c new file mode 100644 index 0000000..b9cd609 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/dfu/dfu_rt_device.c @@ -0,0 +1,128 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Sylvain Munaut + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_DFU_RUNTIME) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "dfu_rt_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void dfu_rtd_init(void) +{ +} + +void dfu_rtd_reset(uint8_t rhport) +{ + (void) rhport; +} + +uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + (void) rhport; + (void) max_len; + + // Ensure this is DFU Runtime + TU_VERIFY((itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS) && + (itf_desc->bInterfaceProtocol == DFU_PROTOCOL_RT), 0); + + uint8_t const * p_desc = tu_desc_next( itf_desc ); + uint16_t drv_len = sizeof(tusb_desc_interface_t); + + if ( TUSB_DESC_FUNCTIONAL == tu_desc_type(p_desc) ) + { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + return drv_len; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + // nothing to do with DATA or ACK stage + if ( stage != CONTROL_STAGE_SETUP ) return true; + + TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); + + // dfu-util will try to claim the interface with SET_INTERFACE request before sending DFU request + if ( TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && + TUSB_REQ_SET_INTERFACE == request->bRequest ) + { + tud_control_status(rhport, request); + return true; + } + + // Handle class request only from here + TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); + + switch (request->bRequest) + { + case DFU_REQUEST_DETACH: + { + TU_LOG2(" DFU RT Request: DETACH\r\n"); + tud_control_status(rhport, request); + tud_dfu_runtime_reboot_to_dfu_cb(); + } + break; + + case DFU_REQUEST_GETSTATUS: + { + TU_LOG2(" DFU RT Request: GETSTATUS\r\n"); + dfu_status_response_t resp; + // Status = OK, Poll timeout is ignored during RT, State = APP_IDLE, IString = 0 + memset(&resp, 0x00, sizeof(dfu_status_response_t)); + tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_response_t)); + } + break; + + default: + { + TU_LOG2(" DFU RT Unexpected Request: %d\r\n", request->bRequest); + return false; // stall unsupported request + } + } + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/dfu/dfu_rt_device.h b/circuitpython/lib/tinyusb/src/class/dfu/dfu_rt_device.h new file mode 100644 index 0000000..babaa82 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/dfu/dfu_rt_device.h @@ -0,0 +1,54 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Sylvain Munaut + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_DFU_RT_DEVICE_H_ +#define _TUSB_DFU_RT_DEVICE_H_ + +#include "dfu.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ +// Invoked when a DFU_DETACH request is received and bitWillDetach is set +void tud_dfu_runtime_reboot_to_dfu_cb(void); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void dfu_rtd_init(void); +void dfu_rtd_reset(uint8_t rhport); +uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_DFU_RT_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/hid/hid.h b/circuitpython/lib/tinyusb/src/class/hid/hid.h new file mode 100644 index 0000000..940454b --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/hid/hid.h @@ -0,0 +1,1122 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup group_class + * \defgroup ClassDriver_HID Human Interface Device (HID) + * @{ */ + +#ifndef _TUSB_HID_H_ +#define _TUSB_HID_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Common Definitions +//--------------------------------------------------------------------+ +/** \defgroup ClassDriver_HID_Common Common Definitions + * @{ */ + + /// USB HID Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength; /**< Numeric expression that is the total size of the HID descriptor */ + uint8_t bDescriptorType; /**< Constant name specifying type of HID descriptor. */ + + uint16_t bcdHID; /**< Numeric expression identifying the HID Class Specification release */ + uint8_t bCountryCode; /**< Numeric expression identifying country code of the localized hardware. */ + uint8_t bNumDescriptors; /**< Numeric expression specifying the number of class descriptors */ + + uint8_t bReportType; /**< Type of HID class report. */ + uint16_t wReportLength; /**< the total size of the Report descriptor. */ +} tusb_hid_descriptor_hid_t; + +/// HID Subclass +typedef enum +{ + HID_SUBCLASS_NONE = 0, ///< No Subclass + HID_SUBCLASS_BOOT = 1 ///< Boot Interface Subclass +}hid_subclass_enum_t; + +/// HID Interface Protocol +typedef enum +{ + HID_ITF_PROTOCOL_NONE = 0, ///< None + HID_ITF_PROTOCOL_KEYBOARD = 1, ///< Keyboard + HID_ITF_PROTOCOL_MOUSE = 2 ///< Mouse +}hid_interface_protocol_enum_t; + +/// HID Descriptor Type +typedef enum +{ + HID_DESC_TYPE_HID = 0x21, ///< HID Descriptor + HID_DESC_TYPE_REPORT = 0x22, ///< Report Descriptor + HID_DESC_TYPE_PHYSICAL = 0x23 ///< Physical Descriptor +}hid_descriptor_enum_t; + +/// HID Request Report Type +typedef enum +{ + HID_REPORT_TYPE_INVALID = 0, + HID_REPORT_TYPE_INPUT, ///< Input + HID_REPORT_TYPE_OUTPUT, ///< Output + HID_REPORT_TYPE_FEATURE ///< Feature +}hid_report_type_t; + +/// HID Class Specific Control Request +typedef enum +{ + HID_REQ_CONTROL_GET_REPORT = 0x01, ///< Get Report + HID_REQ_CONTROL_GET_IDLE = 0x02, ///< Get Idle + HID_REQ_CONTROL_GET_PROTOCOL = 0x03, ///< Get Protocol + HID_REQ_CONTROL_SET_REPORT = 0x09, ///< Set Report + HID_REQ_CONTROL_SET_IDLE = 0x0a, ///< Set Idle + HID_REQ_CONTROL_SET_PROTOCOL = 0x0b ///< Set Protocol +}hid_request_enum_t; + +/// HID Local Code +typedef enum +{ + HID_LOCAL_NotSupported = 0 , ///< NotSupported + HID_LOCAL_Arabic , ///< Arabic + HID_LOCAL_Belgian , ///< Belgian + HID_LOCAL_Canadian_Bilingual , ///< Canadian_Bilingual + HID_LOCAL_Canadian_French , ///< Canadian_French + HID_LOCAL_Czech_Republic , ///< Czech_Republic + HID_LOCAL_Danish , ///< Danish + HID_LOCAL_Finnish , ///< Finnish + HID_LOCAL_French , ///< French + HID_LOCAL_German , ///< German + HID_LOCAL_Greek , ///< Greek + HID_LOCAL_Hebrew , ///< Hebrew + HID_LOCAL_Hungary , ///< Hungary + HID_LOCAL_International , ///< International + HID_LOCAL_Italian , ///< Italian + HID_LOCAL_Japan_Katakana , ///< Japan_Katakana + HID_LOCAL_Korean , ///< Korean + HID_LOCAL_Latin_American , ///< Latin_American + HID_LOCAL_Netherlands_Dutch , ///< Netherlands/Dutch + HID_LOCAL_Norwegian , ///< Norwegian + HID_LOCAL_Persian_Farsi , ///< Persian (Farsi) + HID_LOCAL_Poland , ///< Poland + HID_LOCAL_Portuguese , ///< Portuguese + HID_LOCAL_Russia , ///< Russia + HID_LOCAL_Slovakia , ///< Slovakia + HID_LOCAL_Spanish , ///< Spanish + HID_LOCAL_Swedish , ///< Swedish + HID_LOCAL_Swiss_French , ///< Swiss/French + HID_LOCAL_Swiss_German , ///< Swiss/German + HID_LOCAL_Switzerland , ///< Switzerland + HID_LOCAL_Taiwan , ///< Taiwan + HID_LOCAL_Turkish_Q , ///< Turkish-Q + HID_LOCAL_UK , ///< UK + HID_LOCAL_US , ///< US + HID_LOCAL_Yugoslavia , ///< Yugoslavia + HID_LOCAL_Turkish_F ///< Turkish-F +} hid_local_enum_t; + +// HID protocol value used by GetProtocol / SetProtocol +typedef enum +{ + HID_PROTOCOL_BOOT = 0, + HID_PROTOCOL_REPORT = 1 +} hid_protocol_mode_enum_t; + +/** @} */ + +//--------------------------------------------------------------------+ +// GAMEPAD +//--------------------------------------------------------------------+ +/** \addtogroup ClassDriver_HID_Gamepad Gamepad + * @{ */ + +/* From https://www.kernel.org/doc/html/latest/input/gamepad.html + ____________________________ __ + / [__ZL__] [__ZR__] \ | + / [__ TL __] [__ TR __] \ | Front Triggers + __/________________________________\__ __| + / _ \ | + / /\ __ (N) \ | + / || __ |MO| __ _ _ \ | Main Pad + | <===DP===> |SE| |ST| (W) -|- (E) | | + \ || ___ ___ _ / | + /\ \/ / \ / \ (S) /\ __| + / \________ | LS | ____ | RS | ________/ \ | +| / \ \___/ / \ \___/ / \ | | Control Sticks +| / \_____/ \_____/ \ | __| +| / \ | + \_____/ \_____/ + + |________|______| |______|___________| + D-Pad Left Right Action Pad + Stick Stick + + |_____________| + Menu Pad + + Most gamepads have the following features: + - Action-Pad 4 buttons in diamonds-shape (on the right side) NORTH, SOUTH, WEST and EAST. + - D-Pad (Direction-pad) 4 buttons (on the left side) that point up, down, left and right. + - Menu-Pad Different constellations, but most-times 2 buttons: SELECT - START. + - Analog-Sticks provide freely moveable sticks to control directions, Analog-sticks may also + provide a digital button if you press them. + - Triggers are located on the upper-side of the pad in vertical direction. The upper buttons + are normally named Left- and Right-Triggers, the lower buttons Z-Left and Z-Right. + - Rumble Many devices provide force-feedback features. But are mostly just simple rumble motors. + */ + +/// HID Gamepad Protocol Report. +typedef struct TU_ATTR_PACKED +{ + int8_t x; ///< Delta x movement of left analog-stick + int8_t y; ///< Delta y movement of left analog-stick + int8_t z; ///< Delta z movement of right analog-joystick + int8_t rz; ///< Delta Rz movement of right analog-joystick + int8_t rx; ///< Delta Rx movement of analog left trigger + int8_t ry; ///< Delta Ry movement of analog right trigger + uint8_t hat; ///< Buttons mask for currently pressed buttons in the DPad/hat + uint32_t buttons; ///< Buttons mask for currently pressed buttons +}hid_gamepad_report_t; + +/// Standard Gamepad Buttons Bitmap +typedef enum +{ + GAMEPAD_BUTTON_0 = TU_BIT(0), + GAMEPAD_BUTTON_1 = TU_BIT(1), + GAMEPAD_BUTTON_2 = TU_BIT(2), + GAMEPAD_BUTTON_3 = TU_BIT(3), + GAMEPAD_BUTTON_4 = TU_BIT(4), + GAMEPAD_BUTTON_5 = TU_BIT(5), + GAMEPAD_BUTTON_6 = TU_BIT(6), + GAMEPAD_BUTTON_7 = TU_BIT(7), + GAMEPAD_BUTTON_8 = TU_BIT(8), + GAMEPAD_BUTTON_9 = TU_BIT(9), + GAMEPAD_BUTTON_10 = TU_BIT(10), + GAMEPAD_BUTTON_11 = TU_BIT(11), + GAMEPAD_BUTTON_12 = TU_BIT(12), + GAMEPAD_BUTTON_13 = TU_BIT(13), + GAMEPAD_BUTTON_14 = TU_BIT(14), + GAMEPAD_BUTTON_15 = TU_BIT(15), + GAMEPAD_BUTTON_16 = TU_BIT(16), + GAMEPAD_BUTTON_17 = TU_BIT(17), + GAMEPAD_BUTTON_18 = TU_BIT(18), + GAMEPAD_BUTTON_19 = TU_BIT(19), + GAMEPAD_BUTTON_20 = TU_BIT(20), + GAMEPAD_BUTTON_21 = TU_BIT(21), + GAMEPAD_BUTTON_22 = TU_BIT(22), + GAMEPAD_BUTTON_23 = TU_BIT(23), + GAMEPAD_BUTTON_24 = TU_BIT(24), + GAMEPAD_BUTTON_25 = TU_BIT(25), + GAMEPAD_BUTTON_26 = TU_BIT(26), + GAMEPAD_BUTTON_27 = TU_BIT(27), + GAMEPAD_BUTTON_28 = TU_BIT(28), + GAMEPAD_BUTTON_29 = TU_BIT(29), + GAMEPAD_BUTTON_30 = TU_BIT(30), + GAMEPAD_BUTTON_31 = TU_BIT(31), +}hid_gamepad_button_bm_t; + +/// Standard Gamepad Buttons Naming from Linux input event codes +/// https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h +#define GAMEPAD_BUTTON_A GAMEPAD_BUTTON_0 +#define GAMEPAD_BUTTON_SOUTH GAMEPAD_BUTTON_0 + +#define GAMEPAD_BUTTON_B GAMEPAD_BUTTON_1 +#define GAMEPAD_BUTTON_EAST GAMEPAD_BUTTON_1 + +#define GAMEPAD_BUTTON_C GAMEPAD_BUTTON_2 + +#define GAMEPAD_BUTTON_X GAMEPAD_BUTTON_3 +#define GAMEPAD_BUTTON_NORTH GAMEPAD_BUTTON_3 + +#define GAMEPAD_BUTTON_Y GAMEPAD_BUTTON_4 +#define GAMEPAD_BUTTON_WEST GAMEPAD_BUTTON_4 + +#define GAMEPAD_BUTTON_Z GAMEPAD_BUTTON_5 +#define GAMEPAD_BUTTON_TL GAMEPAD_BUTTON_6 +#define GAMEPAD_BUTTON_TR GAMEPAD_BUTTON_7 +#define GAMEPAD_BUTTON_TL2 GAMEPAD_BUTTON_8 +#define GAMEPAD_BUTTON_TR2 GAMEPAD_BUTTON_9 +#define GAMEPAD_BUTTON_SELECT GAMEPAD_BUTTON_10 +#define GAMEPAD_BUTTON_START GAMEPAD_BUTTON_11 +#define GAMEPAD_BUTTON_MODE GAMEPAD_BUTTON_12 +#define GAMEPAD_BUTTON_THUMBL GAMEPAD_BUTTON_13 +#define GAMEPAD_BUTTON_THUMBR GAMEPAD_BUTTON_14 + +/// Standard Gamepad HAT/DPAD Buttons (from Linux input event codes) +typedef enum +{ + GAMEPAD_HAT_CENTERED = 0, ///< DPAD_CENTERED + GAMEPAD_HAT_UP = 1, ///< DPAD_UP + GAMEPAD_HAT_UP_RIGHT = 2, ///< DPAD_UP_RIGHT + GAMEPAD_HAT_RIGHT = 3, ///< DPAD_RIGHT + GAMEPAD_HAT_DOWN_RIGHT = 4, ///< DPAD_DOWN_RIGHT + GAMEPAD_HAT_DOWN = 5, ///< DPAD_DOWN + GAMEPAD_HAT_DOWN_LEFT = 6, ///< DPAD_DOWN_LEFT + GAMEPAD_HAT_LEFT = 7, ///< DPAD_LEFT + GAMEPAD_HAT_UP_LEFT = 8, ///< DPAD_UP_LEFT +}hid_gamepad_hat_t; + +/// @} + +//--------------------------------------------------------------------+ +// MOUSE +//--------------------------------------------------------------------+ +/** \addtogroup ClassDriver_HID_Mouse Mouse + * @{ */ + +/// Standard HID Boot Protocol Mouse Report. +typedef struct TU_ATTR_PACKED +{ + uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */ + int8_t x; /**< Current delta x movement of the mouse. */ + int8_t y; /**< Current delta y movement on the mouse. */ + int8_t wheel; /**< Current delta wheel movement on the mouse. */ + int8_t pan; // using AC Pan +} hid_mouse_report_t; + +/// Standard Mouse Buttons Bitmap +typedef enum +{ + MOUSE_BUTTON_LEFT = TU_BIT(0), ///< Left button + MOUSE_BUTTON_RIGHT = TU_BIT(1), ///< Right button + MOUSE_BUTTON_MIDDLE = TU_BIT(2), ///< Middle button + MOUSE_BUTTON_BACKWARD = TU_BIT(3), ///< Backward button, + MOUSE_BUTTON_FORWARD = TU_BIT(4), ///< Forward button, +}hid_mouse_button_bm_t; + +/// @} + +//--------------------------------------------------------------------+ +// Keyboard +//--------------------------------------------------------------------+ +/** \addtogroup ClassDriver_HID_Keyboard Keyboard + * @{ */ + +/// Standard HID Boot Protocol Keyboard Report. +typedef struct TU_ATTR_PACKED +{ + uint8_t modifier; /**< Keyboard modifier (KEYBOARD_MODIFIER_* masks). */ + uint8_t reserved; /**< Reserved for OEM use, always set to 0. */ + uint8_t keycode[6]; /**< Key codes of the currently pressed keys. */ +} hid_keyboard_report_t; + +/// Keyboard modifier codes bitmap +typedef enum +{ + KEYBOARD_MODIFIER_LEFTCTRL = TU_BIT(0), ///< Left Control + KEYBOARD_MODIFIER_LEFTSHIFT = TU_BIT(1), ///< Left Shift + KEYBOARD_MODIFIER_LEFTALT = TU_BIT(2), ///< Left Alt + KEYBOARD_MODIFIER_LEFTGUI = TU_BIT(3), ///< Left Window + KEYBOARD_MODIFIER_RIGHTCTRL = TU_BIT(4), ///< Right Control + KEYBOARD_MODIFIER_RIGHTSHIFT = TU_BIT(5), ///< Right Shift + KEYBOARD_MODIFIER_RIGHTALT = TU_BIT(6), ///< Right Alt + KEYBOARD_MODIFIER_RIGHTGUI = TU_BIT(7) ///< Right Window +}hid_keyboard_modifier_bm_t; + +typedef enum +{ + KEYBOARD_LED_NUMLOCK = TU_BIT(0), ///< Num Lock LED + KEYBOARD_LED_CAPSLOCK = TU_BIT(1), ///< Caps Lock LED + KEYBOARD_LED_SCROLLLOCK = TU_BIT(2), ///< Scroll Lock LED + KEYBOARD_LED_COMPOSE = TU_BIT(3), ///< Composition Mode + KEYBOARD_LED_KANA = TU_BIT(4) ///< Kana mode +}hid_keyboard_led_bm_t; + +/// @} + +//--------------------------------------------------------------------+ +// HID KEYCODE +//--------------------------------------------------------------------+ +#define HID_KEY_NONE 0x00 +#define HID_KEY_A 0x04 +#define HID_KEY_B 0x05 +#define HID_KEY_C 0x06 +#define HID_KEY_D 0x07 +#define HID_KEY_E 0x08 +#define HID_KEY_F 0x09 +#define HID_KEY_G 0x0A +#define HID_KEY_H 0x0B +#define HID_KEY_I 0x0C +#define HID_KEY_J 0x0D +#define HID_KEY_K 0x0E +#define HID_KEY_L 0x0F +#define HID_KEY_M 0x10 +#define HID_KEY_N 0x11 +#define HID_KEY_O 0x12 +#define HID_KEY_P 0x13 +#define HID_KEY_Q 0x14 +#define HID_KEY_R 0x15 +#define HID_KEY_S 0x16 +#define HID_KEY_T 0x17 +#define HID_KEY_U 0x18 +#define HID_KEY_V 0x19 +#define HID_KEY_W 0x1A +#define HID_KEY_X 0x1B +#define HID_KEY_Y 0x1C +#define HID_KEY_Z 0x1D +#define HID_KEY_1 0x1E +#define HID_KEY_2 0x1F +#define HID_KEY_3 0x20 +#define HID_KEY_4 0x21 +#define HID_KEY_5 0x22 +#define HID_KEY_6 0x23 +#define HID_KEY_7 0x24 +#define HID_KEY_8 0x25 +#define HID_KEY_9 0x26 +#define HID_KEY_0 0x27 +#define HID_KEY_ENTER 0x28 +#define HID_KEY_ESCAPE 0x29 +#define HID_KEY_BACKSPACE 0x2A +#define HID_KEY_TAB 0x2B +#define HID_KEY_SPACE 0x2C +#define HID_KEY_MINUS 0x2D +#define HID_KEY_EQUAL 0x2E +#define HID_KEY_BRACKET_LEFT 0x2F +#define HID_KEY_BRACKET_RIGHT 0x30 +#define HID_KEY_BACKSLASH 0x31 +#define HID_KEY_EUROPE_1 0x32 +#define HID_KEY_SEMICOLON 0x33 +#define HID_KEY_APOSTROPHE 0x34 +#define HID_KEY_GRAVE 0x35 +#define HID_KEY_COMMA 0x36 +#define HID_KEY_PERIOD 0x37 +#define HID_KEY_SLASH 0x38 +#define HID_KEY_CAPS_LOCK 0x39 +#define HID_KEY_F1 0x3A +#define HID_KEY_F2 0x3B +#define HID_KEY_F3 0x3C +#define HID_KEY_F4 0x3D +#define HID_KEY_F5 0x3E +#define HID_KEY_F6 0x3F +#define HID_KEY_F7 0x40 +#define HID_KEY_F8 0x41 +#define HID_KEY_F9 0x42 +#define HID_KEY_F10 0x43 +#define HID_KEY_F11 0x44 +#define HID_KEY_F12 0x45 +#define HID_KEY_PRINT_SCREEN 0x46 +#define HID_KEY_SCROLL_LOCK 0x47 +#define HID_KEY_PAUSE 0x48 +#define HID_KEY_INSERT 0x49 +#define HID_KEY_HOME 0x4A +#define HID_KEY_PAGE_UP 0x4B +#define HID_KEY_DELETE 0x4C +#define HID_KEY_END 0x4D +#define HID_KEY_PAGE_DOWN 0x4E +#define HID_KEY_ARROW_RIGHT 0x4F +#define HID_KEY_ARROW_LEFT 0x50 +#define HID_KEY_ARROW_DOWN 0x51 +#define HID_KEY_ARROW_UP 0x52 +#define HID_KEY_NUM_LOCK 0x53 +#define HID_KEY_KEYPAD_DIVIDE 0x54 +#define HID_KEY_KEYPAD_MULTIPLY 0x55 +#define HID_KEY_KEYPAD_SUBTRACT 0x56 +#define HID_KEY_KEYPAD_ADD 0x57 +#define HID_KEY_KEYPAD_ENTER 0x58 +#define HID_KEY_KEYPAD_1 0x59 +#define HID_KEY_KEYPAD_2 0x5A +#define HID_KEY_KEYPAD_3 0x5B +#define HID_KEY_KEYPAD_4 0x5C +#define HID_KEY_KEYPAD_5 0x5D +#define HID_KEY_KEYPAD_6 0x5E +#define HID_KEY_KEYPAD_7 0x5F +#define HID_KEY_KEYPAD_8 0x60 +#define HID_KEY_KEYPAD_9 0x61 +#define HID_KEY_KEYPAD_0 0x62 +#define HID_KEY_KEYPAD_DECIMAL 0x63 +#define HID_KEY_EUROPE_2 0x64 +#define HID_KEY_APPLICATION 0x65 +#define HID_KEY_POWER 0x66 +#define HID_KEY_KEYPAD_EQUAL 0x67 +#define HID_KEY_F13 0x68 +#define HID_KEY_F14 0x69 +#define HID_KEY_F15 0x6A +#define HID_KEY_F16 0x6B +#define HID_KEY_F17 0x6C +#define HID_KEY_F18 0x6D +#define HID_KEY_F19 0x6E +#define HID_KEY_F20 0x6F +#define HID_KEY_F21 0x70 +#define HID_KEY_F22 0x71 +#define HID_KEY_F23 0x72 +#define HID_KEY_F24 0x73 +#define HID_KEY_EXECUTE 0x74 +#define HID_KEY_HELP 0x75 +#define HID_KEY_MENU 0x76 +#define HID_KEY_SELECT 0x77 +#define HID_KEY_STOP 0x78 +#define HID_KEY_AGAIN 0x79 +#define HID_KEY_UNDO 0x7A +#define HID_KEY_CUT 0x7B +#define HID_KEY_COPY 0x7C +#define HID_KEY_PASTE 0x7D +#define HID_KEY_FIND 0x7E +#define HID_KEY_MUTE 0x7F +#define HID_KEY_VOLUME_UP 0x80 +#define HID_KEY_VOLUME_DOWN 0x81 +#define HID_KEY_LOCKING_CAPS_LOCK 0x82 +#define HID_KEY_LOCKING_NUM_LOCK 0x83 +#define HID_KEY_LOCKING_SCROLL_LOCK 0x84 +#define HID_KEY_KEYPAD_COMMA 0x85 +#define HID_KEY_KEYPAD_EQUAL_SIGN 0x86 +#define HID_KEY_KANJI1 0x87 +#define HID_KEY_KANJI2 0x88 +#define HID_KEY_KANJI3 0x89 +#define HID_KEY_KANJI4 0x8A +#define HID_KEY_KANJI5 0x8B +#define HID_KEY_KANJI6 0x8C +#define HID_KEY_KANJI7 0x8D +#define HID_KEY_KANJI8 0x8E +#define HID_KEY_KANJI9 0x8F +#define HID_KEY_LANG1 0x90 +#define HID_KEY_LANG2 0x91 +#define HID_KEY_LANG3 0x92 +#define HID_KEY_LANG4 0x93 +#define HID_KEY_LANG5 0x94 +#define HID_KEY_LANG6 0x95 +#define HID_KEY_LANG7 0x96 +#define HID_KEY_LANG8 0x97 +#define HID_KEY_LANG9 0x98 +#define HID_KEY_ALTERNATE_ERASE 0x99 +#define HID_KEY_SYSREQ_ATTENTION 0x9A +#define HID_KEY_CANCEL 0x9B +#define HID_KEY_CLEAR 0x9C +#define HID_KEY_PRIOR 0x9D +#define HID_KEY_RETURN 0x9E +#define HID_KEY_SEPARATOR 0x9F +#define HID_KEY_OUT 0xA0 +#define HID_KEY_OPER 0xA1 +#define HID_KEY_CLEAR_AGAIN 0xA2 +#define HID_KEY_CRSEL_PROPS 0xA3 +#define HID_KEY_EXSEL 0xA4 +// RESERVED 0xA5-DF +#define HID_KEY_CONTROL_LEFT 0xE0 +#define HID_KEY_SHIFT_LEFT 0xE1 +#define HID_KEY_ALT_LEFT 0xE2 +#define HID_KEY_GUI_LEFT 0xE3 +#define HID_KEY_CONTROL_RIGHT 0xE4 +#define HID_KEY_SHIFT_RIGHT 0xE5 +#define HID_KEY_ALT_RIGHT 0xE6 +#define HID_KEY_GUI_RIGHT 0xE7 + + +//--------------------------------------------------------------------+ +// REPORT DESCRIPTOR +//--------------------------------------------------------------------+ + +//------------- ITEM & TAG -------------// +#define HID_REPORT_DATA_0(data) +#define HID_REPORT_DATA_1(data) , data +#define HID_REPORT_DATA_2(data) , U16_TO_U8S_LE(data) +#define HID_REPORT_DATA_3(data) , U32_TO_U8S_LE(data) + +#define HID_REPORT_ITEM(data, tag, type, size) \ + (((tag) << 4) | ((type) << 2) | (size)) HID_REPORT_DATA_##size(data) + +// Report Item Types +enum { + RI_TYPE_MAIN = 0, + RI_TYPE_GLOBAL = 1, + RI_TYPE_LOCAL = 2 +}; + +//------------- Main Items - HID 1.11 section 6.2.2.4 -------------// + +// Report Item Main group +enum { + RI_MAIN_INPUT = 8, + RI_MAIN_OUTPUT = 9, + RI_MAIN_COLLECTION = 10, + RI_MAIN_FEATURE = 11, + RI_MAIN_COLLECTION_END = 12 +}; + +#define HID_INPUT(x) HID_REPORT_ITEM(x, RI_MAIN_INPUT , RI_TYPE_MAIN, 1) +#define HID_OUTPUT(x) HID_REPORT_ITEM(x, RI_MAIN_OUTPUT , RI_TYPE_MAIN, 1) +#define HID_COLLECTION(x) HID_REPORT_ITEM(x, RI_MAIN_COLLECTION , RI_TYPE_MAIN, 1) +#define HID_FEATURE(x) HID_REPORT_ITEM(x, RI_MAIN_FEATURE , RI_TYPE_MAIN, 1) +#define HID_COLLECTION_END HID_REPORT_ITEM(x, RI_MAIN_COLLECTION_END, RI_TYPE_MAIN, 0) + +//------------- Input, Output, Feature - HID 1.11 section 6.2.2.5 -------------// +#define HID_DATA (0<<0) +#define HID_CONSTANT (1<<0) + +#define HID_ARRAY (0<<1) +#define HID_VARIABLE (1<<1) + +#define HID_ABSOLUTE (0<<2) +#define HID_RELATIVE (1<<2) + +#define HID_WRAP_NO (0<<3) +#define HID_WRAP (1<<3) + +#define HID_LINEAR (0<<4) +#define HID_NONLINEAR (1<<4) + +#define HID_PREFERRED_STATE (0<<5) +#define HID_PREFERRED_NO (1<<5) + +#define HID_NO_NULL_POSITION (0<<6) +#define HID_NULL_STATE (1<<6) + +#define HID_NON_VOLATILE (0<<7) +#define HID_VOLATILE (1<<7) + +#define HID_BITFIELD (0<<8) +#define HID_BUFFERED_BYTES (1<<8) + +//------------- Collection Item - HID 1.11 section 6.2.2.6 -------------// +enum { + HID_COLLECTION_PHYSICAL = 0, + HID_COLLECTION_APPLICATION, + HID_COLLECTION_LOGICAL, + HID_COLLECTION_REPORT, + HID_COLLECTION_NAMED_ARRAY, + HID_COLLECTION_USAGE_SWITCH, + HID_COLLECTION_USAGE_MODIFIER +}; + +//------------- Global Items - HID 1.11 section 6.2.2.7 -------------// + +// Report Item Global group +enum { + RI_GLOBAL_USAGE_PAGE = 0, + RI_GLOBAL_LOGICAL_MIN = 1, + RI_GLOBAL_LOGICAL_MAX = 2, + RI_GLOBAL_PHYSICAL_MIN = 3, + RI_GLOBAL_PHYSICAL_MAX = 4, + RI_GLOBAL_UNIT_EXPONENT = 5, + RI_GLOBAL_UNIT = 6, + RI_GLOBAL_REPORT_SIZE = 7, + RI_GLOBAL_REPORT_ID = 8, + RI_GLOBAL_REPORT_COUNT = 9, + RI_GLOBAL_PUSH = 10, + RI_GLOBAL_POP = 11 +}; + +#define HID_USAGE_PAGE(x) HID_REPORT_ITEM(x, RI_GLOBAL_USAGE_PAGE, RI_TYPE_GLOBAL, 1) +#define HID_USAGE_PAGE_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_USAGE_PAGE, RI_TYPE_GLOBAL, n) + +#define HID_LOGICAL_MIN(x) HID_REPORT_ITEM(x, RI_GLOBAL_LOGICAL_MIN, RI_TYPE_GLOBAL, 1) +#define HID_LOGICAL_MIN_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_LOGICAL_MIN, RI_TYPE_GLOBAL, n) + +#define HID_LOGICAL_MAX(x) HID_REPORT_ITEM(x, RI_GLOBAL_LOGICAL_MAX, RI_TYPE_GLOBAL, 1) +#define HID_LOGICAL_MAX_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_LOGICAL_MAX, RI_TYPE_GLOBAL, n) + +#define HID_PHYSICAL_MIN(x) HID_REPORT_ITEM(x, RI_GLOBAL_PHYSICAL_MIN, RI_TYPE_GLOBAL, 1) +#define HID_PHYSICAL_MIN_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_PHYSICAL_MIN, RI_TYPE_GLOBAL, n) + +#define HID_PHYSICAL_MAX(x) HID_REPORT_ITEM(x, RI_GLOBAL_PHYSICAL_MAX, RI_TYPE_GLOBAL, 1) +#define HID_PHYSICAL_MAX_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_PHYSICAL_MAX, RI_TYPE_GLOBAL, n) + +#define HID_UNIT_EXPONENT(x) HID_REPORT_ITEM(x, RI_GLOBAL_UNIT_EXPONENT, RI_TYPE_GLOBAL, 1) +#define HID_UNIT_EXPONENT_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_UNIT_EXPONENT, RI_TYPE_GLOBAL, n) + +#define HID_UNIT(x) HID_REPORT_ITEM(x, RI_GLOBAL_UNIT, RI_TYPE_GLOBAL, 1) +#define HID_UNIT_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_UNIT, RI_TYPE_GLOBAL, n) + +#define HID_REPORT_SIZE(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_SIZE, RI_TYPE_GLOBAL, 1) +#define HID_REPORT_SIZE_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_SIZE, RI_TYPE_GLOBAL, n) + +#define HID_REPORT_ID(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_ID, RI_TYPE_GLOBAL, 1), +#define HID_REPORT_ID_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_ID, RI_TYPE_GLOBAL, n), + +#define HID_REPORT_COUNT(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_COUNT, RI_TYPE_GLOBAL, 1) +#define HID_REPORT_COUNT_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_COUNT, RI_TYPE_GLOBAL, n) + +#define HID_PUSH HID_REPORT_ITEM(x, RI_GLOBAL_PUSH, RI_TYPE_GLOBAL, 0) +#define HID_POP HID_REPORT_ITEM(x, RI_GLOBAL_POP, RI_TYPE_GLOBAL, 0) + +//------------- LOCAL ITEMS 6.2.2.8 -------------// + +enum { + RI_LOCAL_USAGE = 0, + RI_LOCAL_USAGE_MIN = 1, + RI_LOCAL_USAGE_MAX = 2, + RI_LOCAL_DESIGNATOR_INDEX = 3, + RI_LOCAL_DESIGNATOR_MIN = 4, + RI_LOCAL_DESIGNATOR_MAX = 5, + // 6 is reserved + RI_LOCAL_STRING_INDEX = 7, + RI_LOCAL_STRING_MIN = 8, + RI_LOCAL_STRING_MAX = 9, + RI_LOCAL_DELIMITER = 10, +}; + +#define HID_USAGE(x) HID_REPORT_ITEM(x, RI_LOCAL_USAGE, RI_TYPE_LOCAL, 1) +#define HID_USAGE_N(x, n) HID_REPORT_ITEM(x, RI_LOCAL_USAGE, RI_TYPE_LOCAL, n) + +#define HID_USAGE_MIN(x) HID_REPORT_ITEM(x, RI_LOCAL_USAGE_MIN, RI_TYPE_LOCAL, 1) +#define HID_USAGE_MIN_N(x, n) HID_REPORT_ITEM(x, RI_LOCAL_USAGE_MIN, RI_TYPE_LOCAL, n) + +#define HID_USAGE_MAX(x) HID_REPORT_ITEM(x, RI_LOCAL_USAGE_MAX, RI_TYPE_LOCAL, 1) +#define HID_USAGE_MAX_N(x, n) HID_REPORT_ITEM(x, RI_LOCAL_USAGE_MAX, RI_TYPE_LOCAL, n) + +//--------------------------------------------------------------------+ +// Usage Table +//--------------------------------------------------------------------+ + +/// HID Usage Table - Table 1: Usage Page Summary +enum { + HID_USAGE_PAGE_DESKTOP = 0x01, + HID_USAGE_PAGE_SIMULATE = 0x02, + HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, + HID_USAGE_PAGE_SPORT = 0x04, + HID_USAGE_PAGE_GAME = 0x05, + HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, + HID_USAGE_PAGE_KEYBOARD = 0x07, + HID_USAGE_PAGE_LED = 0x08, + HID_USAGE_PAGE_BUTTON = 0x09, + HID_USAGE_PAGE_ORDINAL = 0x0a, + HID_USAGE_PAGE_TELEPHONY = 0x0b, + HID_USAGE_PAGE_CONSUMER = 0x0c, + HID_USAGE_PAGE_DIGITIZER = 0x0d, + HID_USAGE_PAGE_PID = 0x0f, + HID_USAGE_PAGE_UNICODE = 0x10, + HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, + HID_USAGE_PAGE_MEDICAL = 0x40, + HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 + HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 + HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, + HID_USAGE_PAGE_SCALE = 0x8d, + HID_USAGE_PAGE_MSR = 0x8e, + HID_USAGE_PAGE_CAMERA = 0x90, + HID_USAGE_PAGE_ARCADE = 0x91, + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF +}; + +/// HID Usage Table - Table 6: Generic Desktop Page +enum { + HID_USAGE_DESKTOP_POINTER = 0x01, + HID_USAGE_DESKTOP_MOUSE = 0x02, + HID_USAGE_DESKTOP_JOYSTICK = 0x04, + HID_USAGE_DESKTOP_GAMEPAD = 0x05, + HID_USAGE_DESKTOP_KEYBOARD = 0x06, + HID_USAGE_DESKTOP_KEYPAD = 0x07, + HID_USAGE_DESKTOP_MULTI_AXIS_CONTROLLER = 0x08, + HID_USAGE_DESKTOP_TABLET_PC_SYSTEM = 0x09, + HID_USAGE_DESKTOP_X = 0x30, + HID_USAGE_DESKTOP_Y = 0x31, + HID_USAGE_DESKTOP_Z = 0x32, + HID_USAGE_DESKTOP_RX = 0x33, + HID_USAGE_DESKTOP_RY = 0x34, + HID_USAGE_DESKTOP_RZ = 0x35, + HID_USAGE_DESKTOP_SLIDER = 0x36, + HID_USAGE_DESKTOP_DIAL = 0x37, + HID_USAGE_DESKTOP_WHEEL = 0x38, + HID_USAGE_DESKTOP_HAT_SWITCH = 0x39, + HID_USAGE_DESKTOP_COUNTED_BUFFER = 0x3a, + HID_USAGE_DESKTOP_BYTE_COUNT = 0x3b, + HID_USAGE_DESKTOP_MOTION_WAKEUP = 0x3c, + HID_USAGE_DESKTOP_START = 0x3d, + HID_USAGE_DESKTOP_SELECT = 0x3e, + HID_USAGE_DESKTOP_VX = 0x40, + HID_USAGE_DESKTOP_VY = 0x41, + HID_USAGE_DESKTOP_VZ = 0x42, + HID_USAGE_DESKTOP_VBRX = 0x43, + HID_USAGE_DESKTOP_VBRY = 0x44, + HID_USAGE_DESKTOP_VBRZ = 0x45, + HID_USAGE_DESKTOP_VNO = 0x46, + HID_USAGE_DESKTOP_FEATURE_NOTIFICATION = 0x47, + HID_USAGE_DESKTOP_RESOLUTION_MULTIPLIER = 0x48, + HID_USAGE_DESKTOP_SYSTEM_CONTROL = 0x80, + HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN = 0x81, + HID_USAGE_DESKTOP_SYSTEM_SLEEP = 0x82, + HID_USAGE_DESKTOP_SYSTEM_WAKE_UP = 0x83, + HID_USAGE_DESKTOP_SYSTEM_CONTEXT_MENU = 0x84, + HID_USAGE_DESKTOP_SYSTEM_MAIN_MENU = 0x85, + HID_USAGE_DESKTOP_SYSTEM_APP_MENU = 0x86, + HID_USAGE_DESKTOP_SYSTEM_MENU_HELP = 0x87, + HID_USAGE_DESKTOP_SYSTEM_MENU_EXIT = 0x88, + HID_USAGE_DESKTOP_SYSTEM_MENU_SELECT = 0x89, + HID_USAGE_DESKTOP_SYSTEM_MENU_RIGHT = 0x8A, + HID_USAGE_DESKTOP_SYSTEM_MENU_LEFT = 0x8B, + HID_USAGE_DESKTOP_SYSTEM_MENU_UP = 0x8C, + HID_USAGE_DESKTOP_SYSTEM_MENU_DOWN = 0x8D, + HID_USAGE_DESKTOP_SYSTEM_COLD_RESTART = 0x8E, + HID_USAGE_DESKTOP_SYSTEM_WARM_RESTART = 0x8F, + HID_USAGE_DESKTOP_DPAD_UP = 0x90, + HID_USAGE_DESKTOP_DPAD_DOWN = 0x91, + HID_USAGE_DESKTOP_DPAD_RIGHT = 0x92, + HID_USAGE_DESKTOP_DPAD_LEFT = 0x93, + HID_USAGE_DESKTOP_SYSTEM_DOCK = 0xA0, + HID_USAGE_DESKTOP_SYSTEM_UNDOCK = 0xA1, + HID_USAGE_DESKTOP_SYSTEM_SETUP = 0xA2, + HID_USAGE_DESKTOP_SYSTEM_BREAK = 0xA3, + HID_USAGE_DESKTOP_SYSTEM_DEBUGGER_BREAK = 0xA4, + HID_USAGE_DESKTOP_APPLICATION_BREAK = 0xA5, + HID_USAGE_DESKTOP_APPLICATION_DEBUGGER_BREAK = 0xA6, + HID_USAGE_DESKTOP_SYSTEM_SPEAKER_MUTE = 0xA7, + HID_USAGE_DESKTOP_SYSTEM_HIBERNATE = 0xA8, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INVERT = 0xB0, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INTERNAL = 0xB1, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_EXTERNAL = 0xB2, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_BOTH = 0xB3, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_DUAL = 0xB4, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_SWAP_PRIMARY_SECONDARY = 0xB6, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7 +}; + + +/// HID Usage Table: Consumer Page (0x0C) +/// Only contains controls that supported by Windows (whole list is too long) +enum +{ + // Generic Control + HID_USAGE_CONSUMER_CONTROL = 0x0001, + + // Power Control + HID_USAGE_CONSUMER_POWER = 0x0030, + HID_USAGE_CONSUMER_RESET = 0x0031, + HID_USAGE_CONSUMER_SLEEP = 0x0032, + + // Screen Brightness + HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT = 0x006F, + HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT = 0x0070, + + // These HID usages operate only on mobile systems (battery powered) and + // require Windows 8 (build 8302 or greater). + HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS = 0x000C, + HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS = 0x00C6, + HID_USAGE_CONSUMER_WIRELESS_RADIO_LED = 0x00C7, + HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH = 0x00C8, + + // Media Control + HID_USAGE_CONSUMER_PLAY_PAUSE = 0x00CD, + HID_USAGE_CONSUMER_SCAN_NEXT = 0x00B5, + HID_USAGE_CONSUMER_SCAN_PREVIOUS = 0x00B6, + HID_USAGE_CONSUMER_STOP = 0x00B7, + HID_USAGE_CONSUMER_VOLUME = 0x00E0, + HID_USAGE_CONSUMER_MUTE = 0x00E2, + HID_USAGE_CONSUMER_BASS = 0x00E3, + HID_USAGE_CONSUMER_TREBLE = 0x00E4, + HID_USAGE_CONSUMER_BASS_BOOST = 0x00E5, + HID_USAGE_CONSUMER_VOLUME_INCREMENT = 0x00E9, + HID_USAGE_CONSUMER_VOLUME_DECREMENT = 0x00EA, + HID_USAGE_CONSUMER_BASS_INCREMENT = 0x0152, + HID_USAGE_CONSUMER_BASS_DECREMENT = 0x0153, + HID_USAGE_CONSUMER_TREBLE_INCREMENT = 0x0154, + HID_USAGE_CONSUMER_TREBLE_DECREMENT = 0x0155, + + // Application Launcher + HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x0183, + HID_USAGE_CONSUMER_AL_EMAIL_READER = 0x018A, + HID_USAGE_CONSUMER_AL_CALCULATOR = 0x0192, + HID_USAGE_CONSUMER_AL_LOCAL_BROWSER = 0x0194, + + // Browser/Explorer Specific + HID_USAGE_CONSUMER_AC_SEARCH = 0x0221, + HID_USAGE_CONSUMER_AC_HOME = 0x0223, + HID_USAGE_CONSUMER_AC_BACK = 0x0224, + HID_USAGE_CONSUMER_AC_FORWARD = 0x0225, + HID_USAGE_CONSUMER_AC_STOP = 0x0226, + HID_USAGE_CONSUMER_AC_REFRESH = 0x0227, + HID_USAGE_CONSUMER_AC_BOOKMARKS = 0x022A, + + // Mouse Horizontal scroll + HID_USAGE_CONSUMER_AC_PAN = 0x0238, +}; + +/*-------------------------------------------------------------------- + * ASCII to KEYCODE Conversion + * Expand to array of [128][2] (shift, keycode) + * + * Usage: example to convert input chr into keyboard report (modifier + keycode) + * + * uint8_t const conv_table[128][2] = { HID_ASCII_TO_KEYCODE }; + * + * uint8_t keycode[6] = { 0 }; + * uint8_t modifier = 0; + * + * if ( conv_table[chr][0] ) modifier = KEYBOARD_MODIFIER_LEFTSHIFT; + * keycode[0] = conv_table[chr][1]; + * tud_hid_keyboard_report(report_id, modifier, keycode); + * + *--------------------------------------------------------------------*/ +#define HID_ASCII_TO_KEYCODE \ + {0, 0 }, /* 0x00 Null */ \ + {0, 0 }, /* 0x01 */ \ + {0, 0 }, /* 0x02 */ \ + {0, 0 }, /* 0x03 */ \ + {0, 0 }, /* 0x04 */ \ + {0, 0 }, /* 0x05 */ \ + {0, 0 }, /* 0x06 */ \ + {0, 0 }, /* 0x07 */ \ + {0, HID_KEY_BACKSPACE }, /* 0x08 Backspace */ \ + {0, HID_KEY_TAB }, /* 0x09 Tab */ \ + {0, HID_KEY_ENTER }, /* 0x0A Line Feed */ \ + {0, 0 }, /* 0x0B */ \ + {0, 0 }, /* 0x0C */ \ + {0, HID_KEY_ENTER }, /* 0x0D CR */ \ + {0, 0 }, /* 0x0E */ \ + {0, 0 }, /* 0x0F */ \ + {0, 0 }, /* 0x10 */ \ + {0, 0 }, /* 0x11 */ \ + {0, 0 }, /* 0x12 */ \ + {0, 0 }, /* 0x13 */ \ + {0, 0 }, /* 0x14 */ \ + {0, 0 }, /* 0x15 */ \ + {0, 0 }, /* 0x16 */ \ + {0, 0 }, /* 0x17 */ \ + {0, 0 }, /* 0x18 */ \ + {0, 0 }, /* 0x19 */ \ + {0, 0 }, /* 0x1A */ \ + {0, HID_KEY_ESCAPE }, /* 0x1B Escape */ \ + {0, 0 }, /* 0x1C */ \ + {0, 0 }, /* 0x1D */ \ + {0, 0 }, /* 0x1E */ \ + {0, 0 }, /* 0x1F */ \ + \ + {0, HID_KEY_SPACE }, /* 0x20 */ \ + {1, HID_KEY_1 }, /* 0x21 ! */ \ + {1, HID_KEY_APOSTROPHE }, /* 0x22 " */ \ + {1, HID_KEY_3 }, /* 0x23 # */ \ + {1, HID_KEY_4 }, /* 0x24 $ */ \ + {1, HID_KEY_5 }, /* 0x25 % */ \ + {1, HID_KEY_7 }, /* 0x26 & */ \ + {0, HID_KEY_APOSTROPHE }, /* 0x27 ' */ \ + {1, HID_KEY_9 }, /* 0x28 ( */ \ + {1, HID_KEY_0 }, /* 0x29 ) */ \ + {1, HID_KEY_8 }, /* 0x2A * */ \ + {1, HID_KEY_EQUAL }, /* 0x2B + */ \ + {0, HID_KEY_COMMA }, /* 0x2C , */ \ + {0, HID_KEY_MINUS }, /* 0x2D - */ \ + {0, HID_KEY_PERIOD }, /* 0x2E . */ \ + {0, HID_KEY_SLASH }, /* 0x2F / */ \ + {0, HID_KEY_0 }, /* 0x30 0 */ \ + {0, HID_KEY_1 }, /* 0x31 1 */ \ + {0, HID_KEY_2 }, /* 0x32 2 */ \ + {0, HID_KEY_3 }, /* 0x33 3 */ \ + {0, HID_KEY_4 }, /* 0x34 4 */ \ + {0, HID_KEY_5 }, /* 0x35 5 */ \ + {0, HID_KEY_6 }, /* 0x36 6 */ \ + {0, HID_KEY_7 }, /* 0x37 7 */ \ + {0, HID_KEY_8 }, /* 0x38 8 */ \ + {0, HID_KEY_9 }, /* 0x39 9 */ \ + {1, HID_KEY_SEMICOLON }, /* 0x3A : */ \ + {0, HID_KEY_SEMICOLON }, /* 0x3B ; */ \ + {1, HID_KEY_COMMA }, /* 0x3C < */ \ + {0, HID_KEY_EQUAL }, /* 0x3D = */ \ + {1, HID_KEY_PERIOD }, /* 0x3E > */ \ + {1, HID_KEY_SLASH }, /* 0x3F ? */ \ + \ + {1, HID_KEY_2 }, /* 0x40 @ */ \ + {1, HID_KEY_A }, /* 0x41 A */ \ + {1, HID_KEY_B }, /* 0x42 B */ \ + {1, HID_KEY_C }, /* 0x43 C */ \ + {1, HID_KEY_D }, /* 0x44 D */ \ + {1, HID_KEY_E }, /* 0x45 E */ \ + {1, HID_KEY_F }, /* 0x46 F */ \ + {1, HID_KEY_G }, /* 0x47 G */ \ + {1, HID_KEY_H }, /* 0x48 H */ \ + {1, HID_KEY_I }, /* 0x49 I */ \ + {1, HID_KEY_J }, /* 0x4A J */ \ + {1, HID_KEY_K }, /* 0x4B K */ \ + {1, HID_KEY_L }, /* 0x4C L */ \ + {1, HID_KEY_M }, /* 0x4D M */ \ + {1, HID_KEY_N }, /* 0x4E N */ \ + {1, HID_KEY_O }, /* 0x4F O */ \ + {1, HID_KEY_P }, /* 0x50 P */ \ + {1, HID_KEY_Q }, /* 0x51 Q */ \ + {1, HID_KEY_R }, /* 0x52 R */ \ + {1, HID_KEY_S }, /* 0x53 S */ \ + {1, HID_KEY_T }, /* 0x55 T */ \ + {1, HID_KEY_U }, /* 0x55 U */ \ + {1, HID_KEY_V }, /* 0x56 V */ \ + {1, HID_KEY_W }, /* 0x57 W */ \ + {1, HID_KEY_X }, /* 0x58 X */ \ + {1, HID_KEY_Y }, /* 0x59 Y */ \ + {1, HID_KEY_Z }, /* 0x5A Z */ \ + {0, HID_KEY_BRACKET_LEFT }, /* 0x5B [ */ \ + {0, HID_KEY_BACKSLASH }, /* 0x5C '\' */ \ + {0, HID_KEY_BRACKET_RIGHT }, /* 0x5D ] */ \ + {1, HID_KEY_6 }, /* 0x5E ^ */ \ + {1, HID_KEY_MINUS }, /* 0x5F _ */ \ + \ + {0, HID_KEY_GRAVE }, /* 0x60 ` */ \ + {0, HID_KEY_A }, /* 0x61 a */ \ + {0, HID_KEY_B }, /* 0x62 b */ \ + {0, HID_KEY_C }, /* 0x63 c */ \ + {0, HID_KEY_D }, /* 0x66 d */ \ + {0, HID_KEY_E }, /* 0x65 e */ \ + {0, HID_KEY_F }, /* 0x66 f */ \ + {0, HID_KEY_G }, /* 0x67 g */ \ + {0, HID_KEY_H }, /* 0x68 h */ \ + {0, HID_KEY_I }, /* 0x69 i */ \ + {0, HID_KEY_J }, /* 0x6A j */ \ + {0, HID_KEY_K }, /* 0x6B k */ \ + {0, HID_KEY_L }, /* 0x6C l */ \ + {0, HID_KEY_M }, /* 0x6D m */ \ + {0, HID_KEY_N }, /* 0x6E n */ \ + {0, HID_KEY_O }, /* 0x6F o */ \ + {0, HID_KEY_P }, /* 0x70 p */ \ + {0, HID_KEY_Q }, /* 0x71 q */ \ + {0, HID_KEY_R }, /* 0x72 r */ \ + {0, HID_KEY_S }, /* 0x73 s */ \ + {0, HID_KEY_T }, /* 0x75 t */ \ + {0, HID_KEY_U }, /* 0x75 u */ \ + {0, HID_KEY_V }, /* 0x76 v */ \ + {0, HID_KEY_W }, /* 0x77 w */ \ + {0, HID_KEY_X }, /* 0x78 x */ \ + {0, HID_KEY_Y }, /* 0x79 y */ \ + {0, HID_KEY_Z }, /* 0x7A z */ \ + {1, HID_KEY_BRACKET_LEFT }, /* 0x7B { */ \ + {1, HID_KEY_BACKSLASH }, /* 0x7C | */ \ + {1, HID_KEY_BRACKET_RIGHT }, /* 0x7D } */ \ + {1, HID_KEY_GRAVE }, /* 0x7E ~ */ \ + {0, HID_KEY_DELETE } /* 0x7F Delete */ \ + +/*-------------------------------------------------------------------- + * KEYCODE to Ascii Conversion + * Expand to array of [128][2] (ascii without shift, ascii with shift) + * + * Usage: example to convert ascii from keycode (key) and shift modifier (shift). + * Here we assume key < 128 ( printable ) + * + * uint8_t const conv_table[128][2] = { HID_KEYCODE_TO_ASCII }; + * char ch = shift ? conv_table[chr][1] : conv_table[chr][0]; + * + *--------------------------------------------------------------------*/ +#define HID_KEYCODE_TO_ASCII \ + {0 , 0 }, /* 0x00 */ \ + {0 , 0 }, /* 0x01 */ \ + {0 , 0 }, /* 0x02 */ \ + {0 , 0 }, /* 0x03 */ \ + {'a' , 'A' }, /* 0x04 */ \ + {'b' , 'B' }, /* 0x05 */ \ + {'c' , 'C' }, /* 0x06 */ \ + {'d' , 'D' }, /* 0x07 */ \ + {'e' , 'E' }, /* 0x08 */ \ + {'f' , 'F' }, /* 0x09 */ \ + {'g' , 'G' }, /* 0x0a */ \ + {'h' , 'H' }, /* 0x0b */ \ + {'i' , 'I' }, /* 0x0c */ \ + {'j' , 'J' }, /* 0x0d */ \ + {'k' , 'K' }, /* 0x0e */ \ + {'l' , 'L' }, /* 0x0f */ \ + {'m' , 'M' }, /* 0x10 */ \ + {'n' , 'N' }, /* 0x11 */ \ + {'o' , 'O' }, /* 0x12 */ \ + {'p' , 'P' }, /* 0x13 */ \ + {'q' , 'Q' }, /* 0x14 */ \ + {'r' , 'R' }, /* 0x15 */ \ + {'s' , 'S' }, /* 0x16 */ \ + {'t' , 'T' }, /* 0x17 */ \ + {'u' , 'U' }, /* 0x18 */ \ + {'v' , 'V' }, /* 0x19 */ \ + {'w' , 'W' }, /* 0x1a */ \ + {'x' , 'X' }, /* 0x1b */ \ + {'y' , 'Y' }, /* 0x1c */ \ + {'z' , 'Z' }, /* 0x1d */ \ + {'1' , '!' }, /* 0x1e */ \ + {'2' , '@' }, /* 0x1f */ \ + {'3' , '#' }, /* 0x20 */ \ + {'4' , '$' }, /* 0x21 */ \ + {'5' , '%' }, /* 0x22 */ \ + {'6' , '^' }, /* 0x23 */ \ + {'7' , '&' }, /* 0x24 */ \ + {'8' , '*' }, /* 0x25 */ \ + {'9' , '(' }, /* 0x26 */ \ + {'0' , ')' }, /* 0x27 */ \ + {'\r' , '\r' }, /* 0x28 */ \ + {'\x1b', '\x1b' }, /* 0x29 */ \ + {'\b' , '\b' }, /* 0x2a */ \ + {'\t' , '\t' }, /* 0x2b */ \ + {' ' , ' ' }, /* 0x2c */ \ + {'-' , '_' }, /* 0x2d */ \ + {'=' , '+' }, /* 0x2e */ \ + {'[' , '{' }, /* 0x2f */ \ + {']' , '}' }, /* 0x30 */ \ + {'\\' , '|' }, /* 0x31 */ \ + {'#' , '~' }, /* 0x32 */ \ + {';' , ':' }, /* 0x33 */ \ + {'\'' , '\"' }, /* 0x34 */ \ + {'`' , '~' }, /* 0x35 */ \ + {',' , '<' }, /* 0x36 */ \ + {'.' , '>' }, /* 0x37 */ \ + {'/' , '?' }, /* 0x38 */ \ + \ + {0 , 0 }, /* 0x39 */ \ + {0 , 0 }, /* 0x3a */ \ + {0 , 0 }, /* 0x3b */ \ + {0 , 0 }, /* 0x3c */ \ + {0 , 0 }, /* 0x3d */ \ + {0 , 0 }, /* 0x3e */ \ + {0 , 0 }, /* 0x3f */ \ + {0 , 0 }, /* 0x40 */ \ + {0 , 0 }, /* 0x41 */ \ + {0 , 0 }, /* 0x42 */ \ + {0 , 0 }, /* 0x43 */ \ + {0 , 0 }, /* 0x44 */ \ + {0 , 0 }, /* 0x45 */ \ + {0 , 0 }, /* 0x46 */ \ + {0 , 0 }, /* 0x47 */ \ + {0 , 0 }, /* 0x48 */ \ + {0 , 0 }, /* 0x49 */ \ + {0 , 0 }, /* 0x4a */ \ + {0 , 0 }, /* 0x4b */ \ + {0 , 0 }, /* 0x4c */ \ + {0 , 0 }, /* 0x4d */ \ + {0 , 0 }, /* 0x4e */ \ + {0 , 0 }, /* 0x4f */ \ + {0 , 0 }, /* 0x50 */ \ + {0 , 0 }, /* 0x51 */ \ + {0 , 0 }, /* 0x52 */ \ + {0 , 0 }, /* 0x53 */ \ + \ + {'/' , '/' }, /* 0x54 */ \ + {'*' , '*' }, /* 0x55 */ \ + {'-' , '-' }, /* 0x56 */ \ + {'+' , '+' }, /* 0x57 */ \ + {'\r' , '\r' }, /* 0x58 */ \ + {'1' , 0 }, /* 0x59 */ \ + {'2' , 0 }, /* 0x5a */ \ + {'3' , 0 }, /* 0x5b */ \ + {'4' , 0 }, /* 0x5c */ \ + {'5' , '5' }, /* 0x5d */ \ + {'6' , 0 }, /* 0x5e */ \ + {'7' , 0 }, /* 0x5f */ \ + {'8' , 0 }, /* 0x60 */ \ + {'9' , 0 }, /* 0x61 */ \ + {'0' , 0 }, /* 0x62 */ \ + {'.' , 0 }, /* 0x63 */ \ + {0 , 0 }, /* 0x64 */ \ + {0 , 0 }, /* 0x65 */ \ + {0 , 0 }, /* 0x66 */ \ + {'=' , '=' }, /* 0x67 */ \ + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_HID_H__ */ + +/// @} diff --git a/circuitpython/lib/tinyusb/src/class/hid/hid_device.c b/circuitpython/lib/tinyusb/src/class/hid/hid_device.c new file mode 100644 index 0000000..562ca7f --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/hid/hid_device.c @@ -0,0 +1,417 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_HID) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "hid_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef struct +{ + uint8_t itf_num; + uint8_t ep_in; + uint8_t ep_out; // optional Out endpoint + uint8_t itf_protocol; // Boot mouse or keyboard + + uint8_t protocol_mode; // Boot (0) or Report protocol (1) + uint8_t idle_rate; // up to application to handle idle rate + uint16_t report_desc_len; + + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; + + // TODO save hid descriptor since host can specifically request this after enumeration + // Note: HID descriptor may be not available from application after enumeration + tusb_hid_descriptor_hid_t const * hid_descriptor; +} hidd_interface_t; + +CFG_TUSB_MEM_SECTION static hidd_interface_t _hidd_itf[CFG_TUD_HID]; + +/*------------- Helpers -------------*/ +static inline uint8_t get_index_by_itfnum(uint8_t itf_num) +{ + for (uint8_t i=0; i < CFG_TUD_HID; i++ ) + { + if ( itf_num == _hidd_itf[i].itf_num ) return i; + } + + return 0xFF; +} + +//--------------------------------------------------------------------+ +// APPLICATION API +//--------------------------------------------------------------------+ +bool tud_hid_n_ready(uint8_t instance) +{ + uint8_t const ep_in = _hidd_itf[instance].ep_in; + return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(TUD_OPT_RHPORT, ep_in); +} + +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len) +{ + uint8_t const rhport = 0; + hidd_interface_t * p_hid = &_hidd_itf[instance]; + + // claim endpoint + TU_VERIFY( usbd_edpt_claim(rhport, p_hid->ep_in) ); + + // prepare data + if (report_id) + { + len = tu_min8(len, CFG_TUD_HID_EP_BUFSIZE-1); + + p_hid->epin_buf[0] = report_id; + memcpy(p_hid->epin_buf+1, report, len); + len++; + }else + { + // If report id = 0, skip ID field + len = tu_min8(len, CFG_TUD_HID_EP_BUFSIZE); + memcpy(p_hid->epin_buf, report, len); + } + + return usbd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->epin_buf, len); +} + +uint8_t tud_hid_n_interface_protocol(uint8_t instance) +{ + return _hidd_itf[instance].itf_protocol; +} + +uint8_t tud_hid_n_get_protocol(uint8_t instance) +{ + return _hidd_itf[instance].protocol_mode; +} + +bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) +{ + hid_keyboard_report_t report; + + report.modifier = modifier; + report.reserved = 0; + + if ( keycode ) + { + memcpy(report.keycode, keycode, 6); + }else + { + tu_memclr(report.keycode, 6); + } + + return tud_hid_n_report(instance, report_id, &report, sizeof(report)); +} + +bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, + uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) +{ + hid_mouse_report_t report = + { + .buttons = buttons, + .x = x, + .y = y, + .wheel = vertical, + .pan = horizontal + }; + + return tud_hid_n_report(instance, report_id, &report, sizeof(report)); +} + +bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, + int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) +{ + hid_gamepad_report_t report = + { + .x = x, + .y = y, + .z = z, + .rz = rz, + .rx = rx, + .ry = ry, + .hat = hat, + .buttons = buttons, + }; + + return tud_hid_n_report(instance, report_id, &report, sizeof(report)); +} + +//--------------------------------------------------------------------+ +// USBD-CLASS API +//--------------------------------------------------------------------+ +void hidd_init(void) +{ + hidd_reset(TUD_OPT_RHPORT); +} + +void hidd_reset(uint8_t rhport) +{ + (void) rhport; + tu_memclr(_hidd_itf, sizeof(_hidd_itf)); +} + +uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) +{ + TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); + + // len = interface + hid + n*endpoints + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + TU_ASSERT(max_len >= drv_len, 0); + + // Find available interface + hidd_interface_t * p_hid = NULL; + uint8_t hid_id; + for(hid_id=0; hid_idhid_descriptor = (tusb_hid_descriptor_hid_t const *) p_desc; + + //------------- Endpoint Descriptor -------------// + p_desc = tu_desc_next(p_desc); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in), 0); + + if ( desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT ) p_hid->itf_protocol = desc_itf->bInterfaceProtocol; + + p_hid->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode + p_hid->itf_num = desc_itf->bInterfaceNumber; + + // Use offsetof to avoid pointer to the odd/misaligned address + p_hid->report_desc_len = tu_unaligned_read16((uint8_t const*) p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); + + // Prepare for output endpoint + if (p_hid->ep_out) + { + if ( !usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf)) ) + { + TU_LOG_FAILED(); + TU_BREAKPOINT(); + } + } + + return drv_len; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); + + uint8_t const hid_itf = get_index_by_itfnum((uint8_t) request->wIndex); + TU_VERIFY(hid_itf < CFG_TUD_HID); + + hidd_interface_t* p_hid = &_hidd_itf[hid_itf]; + + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) + { + //------------- STD Request -------------// + if ( stage == CONTROL_STAGE_SETUP ) + { + uint8_t const desc_type = tu_u16_high(request->wValue); + //uint8_t const desc_index = tu_u16_low (request->wValue); + + if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) + { + TU_VERIFY(p_hid->hid_descriptor); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)(uintptr_t) p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); + } + else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) + { + uint8_t const * desc_report = tud_hid_descriptor_report_cb(hid_itf); + tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_report, p_hid->report_desc_len); + } + else + { + return false; // stall unsupported request + } + } + } + else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) + { + //------------- Class Specific Request -------------// + switch( request->bRequest ) + { + case HID_REQ_CONTROL_GET_REPORT: + if ( stage == CONTROL_STAGE_SETUP ) + { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t* report_buf = p_hid->epin_buf; + uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + + uint16_t xferlen = 0; + + // If host request a specific Report ID, add ID to as 1 byte of response + if ( (report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1) ) + { + *report_buf++ = report_id; + req_len--; + + xferlen++; + } + + xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); + TU_ASSERT( xferlen > 0 ); + + tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen); + } + break; + + case HID_REQ_CONTROL_SET_REPORT: + if ( stage == CONTROL_STAGE_SETUP ) + { + TU_VERIFY(request->wLength <= sizeof(p_hid->epout_buf)); + tud_control_xfer(rhport, request, p_hid->epout_buf, request->wLength); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t const* report_buf = p_hid->epout_buf; + uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + + // If host request a specific Report ID, extract report ID in buffer before invoking callback + if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0]) ) + { + report_buf++; + report_len--; + } + + tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); + } + break; + + case HID_REQ_CONTROL_SET_IDLE: + if ( stage == CONTROL_STAGE_SETUP ) + { + p_hid->idle_rate = tu_u16_high(request->wValue); + if ( tud_hid_set_idle_cb ) + { + // stall request if callback return false + TU_VERIFY( tud_hid_set_idle_cb( hid_itf, p_hid->idle_rate) ); + } + + tud_control_status(rhport, request); + } + break; + + case HID_REQ_CONTROL_GET_IDLE: + if ( stage == CONTROL_STAGE_SETUP ) + { + // TODO idle rate of report + tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); + } + break; + + case HID_REQ_CONTROL_GET_PROTOCOL: + if ( stage == CONTROL_STAGE_SETUP ) + { + tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); + } + break; + + case HID_REQ_CONTROL_SET_PROTOCOL: + if ( stage == CONTROL_STAGE_SETUP ) + { + tud_control_status(rhport, request); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + p_hid->protocol_mode = (uint8_t) request->wValue; + if (tud_hid_set_protocol_cb) + { + tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); + } + } + break; + + default: return false; // stall unsupported request + } + }else + { + return false; // stall unsupported request + } + + return true; +} + +bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) result; + + uint8_t instance = 0; + hidd_interface_t * p_hid = _hidd_itf; + + // Identify which interface to use + for (instance = 0; instance < CFG_TUD_HID; instance++) + { + p_hid = &_hidd_itf[instance]; + if ( (ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in) ) break; + } + TU_ASSERT(instance < CFG_TUD_HID); + + // Sent report successfully + if (ep_addr == p_hid->ep_in) + { + if (tud_hid_report_complete_cb) + { + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint8_t) xferred_bytes); + } + } + // Received report + else if (ep_addr == p_hid->ep_out) + { + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, xferred_bytes); + TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); + } + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/hid/hid_device.h b/circuitpython/lib/tinyusb/src/class/hid/hid_device.h new file mode 100644 index 0000000..078b673 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/hid/hid_device.h @@ -0,0 +1,393 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_HID_DEVICE_H_ +#define _TUSB_HID_DEVICE_H_ + +#include "hid.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Class Driver Default Configure & Validation +//--------------------------------------------------------------------+ + +#if !defined(CFG_TUD_HID_EP_BUFSIZE) & defined(CFG_TUD_HID_BUFSIZE) + // TODO warn user to use new name later on + // #warning CFG_TUD_HID_BUFSIZE is renamed to CFG_TUD_HID_EP_BUFSIZE, please update to use the new name + #define CFG_TUD_HID_EP_BUFSIZE CFG_TUD_HID_BUFSIZE +#endif + +#ifndef CFG_TUD_HID_EP_BUFSIZE + #define CFG_TUD_HID_EP_BUFSIZE 64 +#endif + +//--------------------------------------------------------------------+ +// Application API (Multiple Instances) +// CFG_TUD_HID > 1 +//--------------------------------------------------------------------+ + +// Check if the interface is ready to use +bool tud_hid_n_ready(uint8_t instance); + +// Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values +uint8_t tud_hid_n_interface_protocol(uint8_t instance); + +// Get current active protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) +uint8_t tud_hid_n_get_protocol(uint8_t instance); + +// Send report to host +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len); + +// KEYBOARD: convenient helper to send keyboard report if application +// use template layout report as defined by hid_keyboard_report_t +bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); + +// MOUSE: convenient helper to send mouse report if application +// use template layout report as defined by hid_mouse_report_t +bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); + +// Gamepad: convenient helper to send gamepad report if application +// use template layout report TUD_HID_REPORT_DESC_GAMEPAD +bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); + +//--------------------------------------------------------------------+ +// Application API (Single Port) +//--------------------------------------------------------------------+ +static inline bool tud_hid_ready(void); +static inline uint8_t tud_hid_interface_protocol(void); +static inline uint8_t tud_hid_get_protocol(void); +static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len); +static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); +static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); +static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); + +//--------------------------------------------------------------------+ +// Callbacks (Weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received GET HID REPORT DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance); + +// Invoked when received GET_REPORT control request +// Application must fill buffer report's content and return its length. +// Return zero will cause the stack to STALL request +uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen); + +// Invoked when received SET_REPORT control request or +// received data on OUT endpoint ( Report ID = 0, Type = 0 ) +void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize); + +// Invoked when received SET_PROTOCOL request +// protocol is either HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) +TU_ATTR_WEAK void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol); + +// Invoked when received SET_IDLE request. return false will stall the request +// - Idle Rate = 0 : only send report if there is changes, i.e skip duplication +// - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms). +TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); + +// Invoked when sent REPORT successfully to host +// Application can use this to send the next report +// Note: For composite reports, report[0] is report ID +TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len); + + +//--------------------------------------------------------------------+ +// Inline Functions +//--------------------------------------------------------------------+ +static inline bool tud_hid_ready(void) +{ + return tud_hid_n_ready(0); +} + +static inline uint8_t tud_hid_interface_protocol(void) +{ + return tud_hid_n_interface_protocol(0); +} + +static inline uint8_t tud_hid_get_protocol(void) +{ + return tud_hid_n_get_protocol(0); +} + +static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len) +{ + return tud_hid_n_report(0, report_id, report, len); +} + +static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) +{ + return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); +} + +static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) +{ + return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + +static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) +{ + return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons); +} + +/* --------------------------------------------------------------------+ + * HID Report Descriptor Template + * + * Convenient for declaring popular HID device (keyboard, mouse, consumer, + * gamepad etc...). Templates take "HID_REPORT_ID(n)" as input, leave + * empty if multiple reports is not used + * + * - Only 1 report: no parameter + * uint8_t const report_desc[] = { TUD_HID_REPORT_DESC_KEYBOARD() }; + * + * - Multiple Reports: "HID_REPORT_ID(ID)" must be passed to template + * uint8_t const report_desc[] = + * { + * TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1) ) , + * TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2) ) + * }; + *--------------------------------------------------------------------*/ + +// Keyboard Report Descriptor Template +#define TUD_HID_REPORT_DESC_KEYBOARD(...) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + /* 8 bits Modifier Keys (Shfit, Control, Alt) */ \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\ + HID_USAGE_MIN ( 224 ) ,\ + HID_USAGE_MAX ( 231 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX ( 1 ) ,\ + HID_REPORT_COUNT ( 8 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* 8 bit reserved */ \ + HID_REPORT_COUNT ( 1 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_CONSTANT ) ,\ + /* Output 5-bit LED Indicator Kana | Compose | ScrollLock | CapsLock | NumLock */ \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ) ,\ + HID_USAGE_MIN ( 1 ) ,\ + HID_USAGE_MAX ( 5 ) ,\ + HID_REPORT_COUNT ( 5 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* led padding */ \ + HID_REPORT_COUNT ( 1 ) ,\ + HID_REPORT_SIZE ( 3 ) ,\ + HID_OUTPUT ( HID_CONSTANT ) ,\ + /* 6-byte Keycodes */ \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\ + HID_USAGE_MIN ( 0 ) ,\ + HID_USAGE_MAX_N ( 255, 2 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX_N( 255, 2 ) ,\ + HID_REPORT_COUNT ( 6 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\ + HID_COLLECTION_END \ + +// Mouse Report Descriptor Template +#define TUD_HID_REPORT_DESC_MOUSE(...) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\ + HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ + HID_USAGE_MIN ( 1 ) ,\ + HID_USAGE_MAX ( 5 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX ( 1 ) ,\ + /* Left, Right, Middle, Backward, Forward buttons */ \ + HID_REPORT_COUNT( 5 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* 3 bit padding */ \ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 3 ) ,\ + HID_INPUT ( HID_CONSTANT ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + /* X, Y position [-127, 127] */ \ + HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ + HID_LOGICAL_MIN ( 0x81 ) ,\ + HID_LOGICAL_MAX ( 0x7f ) ,\ + HID_REPORT_COUNT( 2 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\ + /* Verital wheel scroll [-127, 127] */ \ + HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\ + HID_LOGICAL_MIN ( 0x81 ) ,\ + HID_LOGICAL_MAX ( 0x7f ) ,\ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \ + /* Horizontal wheel scroll [-127, 127] */ \ + HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \ + HID_LOGICAL_MIN ( 0x81 ), \ + HID_LOGICAL_MAX ( 0x7f ), \ + HID_REPORT_COUNT( 1 ), \ + HID_REPORT_SIZE ( 8 ), \ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \ + HID_COLLECTION_END , \ + HID_COLLECTION_END \ + +// Consumer Control Report Descriptor Template +#define TUD_HID_REPORT_DESC_CONSUMER(...) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\ + HID_USAGE ( HID_USAGE_CONSUMER_CONTROL ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + HID_LOGICAL_MIN ( 0x00 ) ,\ + HID_LOGICAL_MAX_N( 0x03FF, 2 ) ,\ + HID_USAGE_MIN ( 0x00 ) ,\ + HID_USAGE_MAX_N ( 0x03FF, 2 ) ,\ + HID_REPORT_COUNT ( 1 ) ,\ + HID_REPORT_SIZE ( 16 ) ,\ + HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\ + HID_COLLECTION_END \ + +/* System Control Report Descriptor Template + * 0x00 - do nothing + * 0x01 - Power Off + * 0x02 - Standby + * 0x03 - Wake Host + */ +#define TUD_HID_REPORT_DESC_SYSTEM_CONTROL(...) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_CONTROL ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + /* 2 bit system power control */ \ + HID_LOGICAL_MIN ( 1 ) ,\ + HID_LOGICAL_MAX ( 3 ) ,\ + HID_REPORT_COUNT ( 1 ) ,\ + HID_REPORT_SIZE ( 2 ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_SLEEP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_WAKE_UP ) ,\ + HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\ + /* 6 bit padding */ \ + HID_REPORT_COUNT ( 1 ) ,\ + HID_REPORT_SIZE ( 6 ) ,\ + HID_INPUT ( HID_CONSTANT ) ,\ + HID_COLLECTION_END \ + +// Gamepad Report Descriptor Template +// with 32 buttons, 2 joysticks and 1 hat/dpad with following layout +// | X | Y | Z | Rz | Rx | Ry (1 byte each) | hat/DPAD (1 byte) | Button Map (4 bytes) | +#define TUD_HID_REPORT_DESC_GAMEPAD(...) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + /* 8 bit X, Y, Z, Rz, Rx, Ry (min -127, max 127 ) */ \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\ + HID_LOGICAL_MIN ( 0x81 ) ,\ + HID_LOGICAL_MAX ( 0x7f ) ,\ + HID_REPORT_COUNT ( 6 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* 8 bit DPad/Hat Button Map */ \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\ + HID_LOGICAL_MIN ( 1 ) ,\ + HID_LOGICAL_MAX ( 8 ) ,\ + HID_PHYSICAL_MIN ( 0 ) ,\ + HID_PHYSICAL_MAX_N ( 315, 2 ) ,\ + HID_REPORT_COUNT ( 1 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* 32 bit Button Map */ \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ + HID_USAGE_MIN ( 1 ) ,\ + HID_USAGE_MAX ( 32 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX ( 1 ) ,\ + HID_REPORT_COUNT ( 32 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + HID_COLLECTION_END \ + +// HID Generic Input & Output +// - 1st parameter is report size (mandatory) +// - 2nd parameter is report id HID_REPORT_ID(n) (optional) +#define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \ + HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\ + HID_USAGE ( 0x01 ),\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ + /* Report ID if any */\ + __VA_ARGS__ \ + /* Input */ \ + HID_USAGE ( 0x02 ),\ + HID_LOGICAL_MIN ( 0x00 ),\ + HID_LOGICAL_MAX_N ( 0xff, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT( report_size ),\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + /* Output */ \ + HID_USAGE ( 0x03 ),\ + HID_LOGICAL_MIN ( 0x00 ),\ + HID_LOGICAL_MAX_N ( 0xff, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT( report_size ),\ + HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END \ + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void hidd_init (void); +void hidd_reset (uint8_t rhport); +uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_HID_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/hid/hid_host.c b/circuitpython/lib/tinyusb/src/class/hid/hid_host.c new file mode 100644 index 0000000..9190642 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/hid/hid_host.c @@ -0,0 +1,643 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUH_ENABLED && CFG_TUH_HID) + +#include "host/usbh.h" +#include "host/usbh_classdriver.h" + +#include "hid_host.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +typedef struct +{ + uint8_t itf_num; + uint8_t ep_in; + uint8_t ep_out; + + uint8_t itf_protocol; // None, Keyboard, Mouse + uint8_t protocol_mode; // Boot (0) or Report protocol (1) + + uint8_t report_desc_type; + uint16_t report_desc_len; + + uint16_t epin_size; + uint16_t epout_size; + + uint8_t epin_buf[CFG_TUH_HID_EPIN_BUFSIZE]; + uint8_t epout_buf[CFG_TUH_HID_EPOUT_BUFSIZE]; +} hidh_interface_t; + +typedef struct +{ + uint8_t inst_count; + hidh_interface_t instances[CFG_TUH_HID]; +} hidh_device_t; + +static hidh_device_t _hidh_dev[CFG_TUH_DEVICE_MAX]; + +//------------- Internal prototypes -------------// + +// Get HID device & interface +TU_ATTR_ALWAYS_INLINE static inline hidh_device_t* get_dev(uint8_t dev_addr); +TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_addr, uint8_t instance); +static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf); +static uint8_t get_instance_id_by_epaddr(uint8_t dev_addr, uint8_t ep_addr); + +//--------------------------------------------------------------------+ +// Interface API +//--------------------------------------------------------------------+ + +uint8_t tuh_hid_instance_count(uint8_t dev_addr) +{ + return get_dev(dev_addr)->inst_count; +} + +bool tuh_hid_mounted(uint8_t dev_addr, uint8_t instance) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + return (hid_itf->ep_in != 0) || (hid_itf->ep_out != 0); +} + +uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + return hid_itf->itf_protocol; +} + +//--------------------------------------------------------------------+ +// Control Endpoint API +//--------------------------------------------------------------------+ + +uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + return hid_itf->protocol_mode; +} + +static bool set_protocol_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) request->wValue; + + if (tuh_hid_set_protocol_complete_cb) + { + tuh_hid_set_protocol_complete_cb(dev_addr, instance, hid_itf->protocol_mode); + } + + return true; +} + +bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + TU_VERIFY(hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE); + + TU_LOG2("HID Set Protocol = %d\r\n", protocol); + + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = protocol, + .wIndex = hid_itf->itf_num, + .wLength = 0 + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, set_protocol_complete) ); + return true; +} + +static bool set_report_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + TU_LOG2("HID Set Report complete\r\n"); + + if (tuh_hid_set_report_complete_cb) + { + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? request->wLength : 0); + } + + return true; +} + +bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + TU_LOG2("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); + + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_REPORT, + .wValue = tu_u16(report_type, report_id), + .wIndex = hid_itf->itf_num, + .wLength = len + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &request, report, set_report_complete) ); + return true; +} + +//--------------------------------------------------------------------+ +// Interrupt Endpoint API +//--------------------------------------------------------------------+ + +bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + // claim endpoint + TU_VERIFY( usbh_edpt_claim(dev_addr, hid_itf->ep_in) ); + + return usbh_edpt_xfer(dev_addr, hid_itf->ep_in, hid_itf->epin_buf, hid_itf->epin_size); +} + +//bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance) +//{ +// TU_VERIFY(tuh_n_hid_n_mounted(dev_addr, instance)); +// +// hidh_interface_t* hid_itf = get_instance(dev_addr, instance); +// return !usbh_edpt_busy(dev_addr, hid_itf->ep_in); +//} + +//void tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t const* report, uint16_t len); + +//--------------------------------------------------------------------+ +// USBH API +//--------------------------------------------------------------------+ +void hidh_init(void) +{ + tu_memclr(_hidh_dev, sizeof(_hidh_dev)); +} + +bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) result; + + uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const instance = get_instance_id_by_epaddr(dev_addr, ep_addr); + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + if ( dir == TUSB_DIR_IN ) + { + TU_LOG2(" Get Report callback (%u, %u)\r\n", dev_addr, instance); + TU_LOG3_MEM(hid_itf->epin_buf, xferred_bytes, 2); + tuh_hid_report_received_cb(dev_addr, instance, hid_itf->epin_buf, xferred_bytes); + }else + { + if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(dev_addr, instance, hid_itf->epout_buf, xferred_bytes); + } + + return true; +} + +void hidh_close(uint8_t dev_addr) +{ + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); + + hidh_device_t* hid_dev = get_dev(dev_addr); + + if (tuh_hid_umount_cb) + { + for (uint8_t inst = 0; inst < hid_dev->inst_count; inst++ ) tuh_hid_umount_cb(dev_addr, inst); + } + + tu_memclr(hid_dev, sizeof(hidh_device_t)); +} + +//--------------------------------------------------------------------+ +// Enumeration +//--------------------------------------------------------------------+ + +static bool config_set_protocol (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool config_get_report_desc (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool config_get_report_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); + +static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); + +bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) +{ + (void) max_len; + + TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); + + TU_LOG2("HID opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr); + + // len = interface + hid + n*endpoints + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + TU_ASSERT(max_len >= drv_len); + + uint8_t const *p_desc = (uint8_t const *) desc_itf; + + //------------- HID descriptor -------------// + p_desc = tu_desc_next(p_desc); + tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; + TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType); + + // not enough interface, try to increase CFG_TUH_HID + // TODO multiple devices + hidh_device_t* hid_dev = get_dev(dev_addr); + TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID, 0); + + hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count); + + //------------- Endpoint Descriptors -------------// + p_desc = tu_desc_next(p_desc); + tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + + for(int i = 0; i < desc_itf->bNumEndpoints; i++) + { + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); + TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); + + if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) + { + hid_itf->ep_in = desc_ep->bEndpointAddress; + hid_itf->epin_size = tu_edpt_packet_size(desc_ep); + } + else + { + hid_itf->ep_out = desc_ep->bEndpointAddress; + hid_itf->epout_size = tu_edpt_packet_size(desc_ep); + } + + p_desc = tu_desc_next(p_desc); + desc_ep = (tusb_desc_endpoint_t const *) p_desc; + } + + hid_dev->inst_count++; + + hid_itf->itf_num = desc_itf->bInterfaceNumber; + + // Assume bNumDescriptors = 1 + hid_itf->report_desc_type = desc_hid->bReportType; + hid_itf->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); + + // Per HID Specs: default is Report protocol, though we will force Boot protocol when set_config + hid_itf->protocol_mode = HID_PROTOCOL_BOOT; + if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) hid_itf->itf_protocol = desc_itf->bInterfaceProtocol; + + return true; +} + +bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) +{ + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + // Idle rate = 0 mean only report when there is changes + uint16_t const idle_rate = 0; + + // SET IDLE request, device can stall if not support this request + TU_LOG2("HID Set Idle \r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_IDLE, + .wValue = idle_rate, + .wIndex = itf_num, + .wLength = 0 + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? config_set_protocol : config_get_report_desc) ); + + return true; +} + +// Force device to work in BOOT protocol +static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + // Stall is a valid response for SET_IDLE, therefore we could ignore its result + (void) result; + + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + TU_LOG2("HID Set Protocol to Boot Mode\r\n"); + hid_itf->protocol_mode = HID_PROTOCOL_BOOT; + tusb_control_request_t const new_request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = HID_PROTOCOL_BOOT, + .wIndex = hid_itf->itf_num, + .wLength = 0 + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, NULL, config_get_report_desc) ); + return true; +} + +static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + // We can be here after SET_IDLE or SET_PROTOCOL (boot device) + // Trigger assert if result is not successful with set protocol + if ( request->bRequest != HID_REQ_CONTROL_SET_IDLE ) + { + TU_ASSERT(result == XFER_RESULT_SUCCESS); + } + + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + // Get Report Descriptor if possible + // using usbh enumeration buffer since report descriptor can be very long + if( hid_itf->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE ) + { + TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", hid_itf->report_desc_len); + + // Driver is mounted without report descriptor + config_driver_mount_complete(dev_addr, instance, NULL, 0); + }else + { + TU_LOG2("HID Get Report Descriptor\r\n"); + tusb_control_request_t const new_request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_u16(hid_itf->report_desc_type, 0), + .wIndex = itf_num, + .wLength = hid_itf->report_desc_len + }; + + TU_ASSERT(tuh_control_xfer(dev_addr, &new_request, usbh_get_enum_buf(), config_get_report_desc_complete)); + } + + return true; +} + +static bool config_get_report_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + + uint8_t const* desc_report = usbh_get_enum_buf(); + uint16_t const desc_len = request->wLength; + + config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); + + return true; +} + +static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + // enumeration is complete + tuh_hid_mount_cb(dev_addr, instance, desc_report, desc_len); + + // notify usbh that driver enumeration is complete + usbh_driver_set_config_complete(dev_addr, hid_itf->itf_num); +} + +//--------------------------------------------------------------------+ +// Report Descriptor Parser +//--------------------------------------------------------------------+ + +uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) +{ + // Report Item 6.2.2.2 USB HID 1.11 + union TU_ATTR_PACKED + { + uint8_t byte; + struct TU_ATTR_PACKED + { + uint8_t size : 2; + uint8_t type : 2; + uint8_t tag : 4; + }; + } header; + + tu_memclr(report_info_arr, arr_count*sizeof(tuh_hid_report_info_t)); + + uint8_t report_num = 0; + tuh_hid_report_info_t* info = report_info_arr; + + // current parsed report count & size from descriptor +// uint8_t ri_report_count = 0; +// uint8_t ri_report_size = 0; + + uint8_t ri_collection_depth = 0; + + while(desc_len && report_num < arr_count) + { + header.byte = *desc_report++; + desc_len--; + + uint8_t const tag = header.tag; + uint8_t const type = header.type; + uint8_t const size = header.size; + + uint8_t const data8 = desc_report[0]; + + TU_LOG(3, "tag = %d, type = %d, size = %d, data = ", tag, type, size); + for(uint32_t i=0; iusage_page, desc_report, size); + break; + + case RI_GLOBAL_LOGICAL_MIN : break; + case RI_GLOBAL_LOGICAL_MAX : break; + case RI_GLOBAL_PHYSICAL_MIN : break; + case RI_GLOBAL_PHYSICAL_MAX : break; + + case RI_GLOBAL_REPORT_ID: + info->report_id = data8; + break; + + case RI_GLOBAL_REPORT_SIZE: +// ri_report_size = data8; + break; + + case RI_GLOBAL_REPORT_COUNT: +// ri_report_count = data8; + break; + + case RI_GLOBAL_UNIT_EXPONENT : break; + case RI_GLOBAL_UNIT : break; + case RI_GLOBAL_PUSH : break; + case RI_GLOBAL_POP : break; + + default: break; + } + break; + + case RI_TYPE_LOCAL: + switch(tag) + { + case RI_LOCAL_USAGE: + // only take in account the "usage" before starting REPORT ID + if ( ri_collection_depth == 0 ) info->usage = data8; + break; + + case RI_LOCAL_USAGE_MIN : break; + case RI_LOCAL_USAGE_MAX : break; + case RI_LOCAL_DESIGNATOR_INDEX : break; + case RI_LOCAL_DESIGNATOR_MIN : break; + case RI_LOCAL_DESIGNATOR_MAX : break; + case RI_LOCAL_STRING_INDEX : break; + case RI_LOCAL_STRING_MIN : break; + case RI_LOCAL_STRING_MAX : break; + case RI_LOCAL_DELIMITER : break; + default: break; + } + break; + + // error + default: break; + } + + desc_report += size; + desc_len -= size; + } + + for ( uint8_t i = 0; i < report_num; i++ ) + { + info = report_info_arr+i; + TU_LOG2("%u: id = %u, usage_page = %u, usage = %u\r\n", i, info->report_id, info->usage_page, info->usage); + } + + return report_num; +} + +//--------------------------------------------------------------------+ +// Helper +//--------------------------------------------------------------------+ + +// Get Device by address +TU_ATTR_ALWAYS_INLINE static inline hidh_device_t* get_dev(uint8_t dev_addr) +{ + return &_hidh_dev[dev_addr-1]; +} + +// Get Interface by instance number +TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_addr, uint8_t instance) +{ + return &_hidh_dev[dev_addr-1].instances[instance]; +} + +// Get instance ID by interface number +static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf) +{ + for ( uint8_t inst = 0; inst < CFG_TUH_HID; inst++ ) + { + hidh_interface_t *hid = get_instance(dev_addr, inst); + + if ( (hid->itf_num == itf) && (hid->ep_in || hid->ep_out) ) return inst; + } + + return 0xff; +} + +// Get instance ID by endpoint address +static uint8_t get_instance_id_by_epaddr(uint8_t dev_addr, uint8_t ep_addr) +{ + for ( uint8_t inst = 0; inst < CFG_TUH_HID; inst++ ) + { + hidh_interface_t *hid = get_instance(dev_addr, inst); + + if ( (ep_addr == hid->ep_in) || ( ep_addr == hid->ep_out) ) return inst; + } + + return 0xff; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/hid/hid_host.h b/circuitpython/lib/tinyusb/src/class/hid/hid_host.h new file mode 100644 index 0000000..fe09b03 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/hid/hid_host.h @@ -0,0 +1,152 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_HID_HOST_H_ +#define _TUSB_HID_HOST_H_ + +#include "hid.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ + +// TODO Highspeed interrupt can be up to 512 bytes +#ifndef CFG_TUH_HID_EPIN_BUFSIZE +#define CFG_TUH_HID_EPIN_BUFSIZE 64 +#endif + +#ifndef CFG_TUH_HID_EPOUT_BUFSIZE +#define CFG_TUH_HID_EPOUT_BUFSIZE 64 +#endif + + +typedef struct +{ + uint8_t report_id; + uint8_t usage; + uint16_t usage_page; + + // TODO still use the endpoint size for now +// uint8_t in_len; // length of IN report +// uint8_t out_len; // length of OUT report +} tuh_hid_report_info_t; + +//--------------------------------------------------------------------+ +// Interface API +//--------------------------------------------------------------------+ + +// Get the number of HID instances +uint8_t tuh_hid_instance_count(uint8_t dev_addr); + +// Check if HID instance is mounted +bool tuh_hid_mounted(uint8_t dev_addr, uint8_t instance); + +// Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values +uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance); + +// Parse report descriptor into array of report_info struct and return number of reports. +// For complicated report, application should write its own parser. +uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) TU_ATTR_UNUSED; + +//--------------------------------------------------------------------+ +// Control Endpoint API +//--------------------------------------------------------------------+ + +// Get current protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) +// Note: Device will be initialized in Boot protocol for simplicity. +// Application can use set_protocol() to switch back to Report protocol. +uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance); + +// Set protocol to HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) +// This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE) +bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol); + +// Set Report using control endpoint +// report_type is either Intput, Output or Feature, (value from hid_report_type_t) +bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); + +//--------------------------------------------------------------------+ +// Interrupt Endpoint API +//--------------------------------------------------------------------+ + +// Check if the interface is ready to use +//bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance); + +// Try to receive next report on Interrupt Endpoint. Immediately return +// - true If succeeded, tuh_hid_report_received_cb() callback will be invoked when report is available +// - false if failed to queue the transfer e.g endpoint is busy +bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance); + +// Send report using interrupt endpoint +// If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is sent. +//void tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t const* report, uint16_t len); + +//--------------------------------------------------------------------+ +// Callbacks (Weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when device with hid interface is mounted +// Report descriptor is also available for use. tuh_hid_parse_report_descriptor() +// can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report_desc, uint16_t desc_len); + +// Invoked when device with hid interface is un-mounted +TU_ATTR_WEAK void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance); + +// Invoked when received report from device via interrupt endpoint +// Note: if there is report ID (composite), it is 1st byte of report +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); + +// Invoked when sent report to device successfully via interrupt endpoint +TU_ATTR_WEAK void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); + +// Invoked when Sent Report to device via either control endpoint +// len = 0 indicate there is error in the transfer e.g stalled response +TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, uint16_t len); + +// Invoked when Set Protocol request is complete +TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t protocol); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void hidh_init (void); +bool hidh_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); +bool hidh_set_config (uint8_t dev_addr, uint8_t itf_num); +bool hidh_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void hidh_close (uint8_t dev_addr); + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_HID_HOST_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/midi/midi.h b/circuitpython/lib/tinyusb/src/class/midi/midi.h new file mode 100644 index 0000000..74dc417 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/midi/midi.h @@ -0,0 +1,212 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup group_class + * \defgroup ClassDriver_CDC Communication Device Class (CDC) + * Currently only Abstract Control Model subclass is supported + * @{ */ + +#ifndef _TUSB_MIDI_H__ +#define _TUSB_MIDI_H__ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Class Specific Descriptor +//--------------------------------------------------------------------+ + +typedef enum +{ + MIDI_CS_INTERFACE_HEADER = 0x01, + MIDI_CS_INTERFACE_IN_JACK = 0x02, + MIDI_CS_INTERFACE_OUT_JACK = 0x03, + MIDI_CS_INTERFACE_ELEMENT = 0x04, +} midi_cs_interface_subtype_t; + +typedef enum +{ + MIDI_CS_ENDPOINT_GENERAL = 0x01 +} midi_cs_endpoint_subtype_t; + +typedef enum +{ + MIDI_JACK_EMBEDDED = 0x01, + MIDI_JACK_EXTERNAL = 0x02 +} midi_jack_type_t; + +typedef enum +{ + MIDI_CIN_MISC = 0, + MIDI_CIN_CABLE_EVENT = 1, + MIDI_CIN_SYSCOM_2BYTE = 2, // 2 byte system common message e.g MTC, SongSelect + MIDI_CIN_SYSCOM_3BYTE = 3, // 3 byte system common message e.g SPP + MIDI_CIN_SYSEX_START = 4, // SysEx starts or continue + MIDI_CIN_SYSEX_END_1BYTE = 5, // SysEx ends with 1 data, or 1 byte system common message + MIDI_CIN_SYSEX_END_2BYTE = 6, // SysEx ends with 2 data + MIDI_CIN_SYSEX_END_3BYTE = 7, // SysEx ends with 3 data + MIDI_CIN_NOTE_ON = 8, + MIDI_CIN_NOTE_OFF = 9, + MIDI_CIN_POLY_KEYPRESS = 10, + MIDI_CIN_CONTROL_CHANGE = 11, + MIDI_CIN_PROGRAM_CHANGE = 12, + MIDI_CIN_CHANNEL_PRESSURE = 13, + MIDI_CIN_PITCH_BEND_CHANGE = 14, + MIDI_CIN_1BYTE_DATA = 15 +} midi_code_index_number_t; + +// MIDI 1.0 status byte +enum +{ + //------------- System Exclusive -------------// + MIDI_STATUS_SYSEX_START = 0xF0, + MIDI_STATUS_SYSEX_END = 0xF7, + + //------------- System Common -------------// + MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME = 0xF1, + MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER = 0xF2, + MIDI_STATUS_SYSCOM_SONG_SELECT = 0xF3, + // F4, F5 is undefined + MIDI_STATUS_SYSCOM_TUNE_REQUEST = 0xF6, + + //------------- System RealTime -------------// + MIDI_STATUS_SYSREAL_TIMING_CLOCK = 0xF8, + // 0xF9 is undefined + MIDI_STATUS_SYSREAL_START = 0xFA, + MIDI_STATUS_SYSREAL_CONTINUE = 0xFB, + MIDI_STATUS_SYSREAL_STOP = 0xFC, + // 0xFD is undefined + MIDI_STATUS_SYSREAL_ACTIVE_SENSING = 0xFE, + MIDI_STATUS_SYSREAL_SYSTEM_RESET = 0xFF, +}; + +/// MIDI Interface Header Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType + uint16_t bcdMSC ; ///< MidiStreaming SubClass release number in Binary-Coded Decimal + uint16_t wTotalLength ; +} midi_desc_header_t; + +/// MIDI In Jack Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType + uint8_t bJackType ; ///< Embedded or External + uint8_t bJackID ; ///< Unique ID for MIDI IN Jack + uint8_t iJack ; ///< string descriptor +} midi_desc_in_jack_t; + + +/// MIDI Out Jack Descriptor with single pin +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType + uint8_t bJackType ; ///< Embedded or External + uint8_t bJackID ; ///< Unique ID for MIDI IN Jack + uint8_t bNrInputPins; + + uint8_t baSourceID; + uint8_t baSourcePin; + + uint8_t iJack ; ///< string descriptor +} midi_desc_out_jack_t ; + +/// MIDI Out Jack Descriptor with multiple pins +#define midi_desc_out_jack_n_t(input_num) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength ; \ + uint8_t bDescriptorType ; \ + uint8_t bDescriptorSubType ; \ + uint8_t bJackType ; \ + uint8_t bJackID ; \ + uint8_t bNrInputPins ; \ + struct TU_ATTR_PACKED { \ + uint8_t baSourceID; \ + uint8_t baSourcePin; \ + } pins[input_num]; \ + uint8_t iJack ; \ + } + +/// MIDI Element Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific + uint8_t bDescriptorSubType ; ///< Descriptor SubType + uint8_t bElementID; + + uint8_t bNrInputPins; + uint8_t baSourceID; + uint8_t baSourcePin; + + uint8_t bNrOutputPins; + uint8_t bInTerminalLink; + uint8_t bOutTerminalLink; + uint8_t bElCapsSize; + + uint16_t bmElementCaps; + uint8_t iElement; +} midi_desc_element_t; + +/// MIDI Element Descriptor with multiple pins +#define midi_desc_element_n_t(input_num) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bElementID; \ + uint8_t bNrInputPins; \ + struct TU_ATTR_PACKED { \ + uint8_t baSourceID; \ + uint8_t baSourcePin; \ + } pins[input_num]; \ + uint8_t bNrOutputPins; \ + uint8_t bInTerminalLink; \ + uint8_t bOutTerminalLink; \ + uint8_t bElCapsSize; \ + uint16_t bmElementCaps; \ + uint8_t iElement; \ + } + +/** @} */ + +#ifdef __cplusplus + } +#endif + +#endif + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/class/midi/midi_device.c b/circuitpython/lib/tinyusb/src/class/midi/midi_device.c new file mode 100644 index 0000000..2ce1376 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/midi/midi_device.c @@ -0,0 +1,545 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_MIDI) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "midi_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +typedef struct +{ + uint8_t buffer[4]; + uint8_t index; + uint8_t total; +}midid_stream_t; + +typedef struct +{ + uint8_t itf_num; + uint8_t ep_in; + uint8_t ep_out; + + // For Stream read()/write() API + // Messages are always 4 bytes long, queue them for reading and writing so the + // callers can use the Stream interface with single-byte read/write calls. + midid_stream_t stream_write; + midid_stream_t stream_read; + + /*------------- From this point, data is not cleared by bus reset -------------*/ + // FIFO + tu_fifo_t rx_ff; + tu_fifo_t tx_ff; + uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUD_MIDI_TX_BUFSIZE]; + + #if CFG_FIFO_MUTEX + osal_mutex_def_t rx_ff_mutex; + osal_mutex_def_t tx_ff_mutex; + #endif + + // Endpoint Transfer buffer + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_MIDI_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_MIDI_EP_BUFSIZE]; + +} midid_interface_t; + +#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, rx_ff) + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI]; + +bool tud_midi_n_mounted (uint8_t itf) +{ + midid_interface_t* midi = &_midid_itf[itf]; + return midi->ep_in && midi->ep_out; +} + +static void _prep_out_transaction (midid_interface_t* p_midi) +{ + uint8_t const rhport = TUD_OPT_RHPORT; + uint16_t available = tu_fifo_remaining(&p_midi->rx_ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + TU_VERIFY(available >= sizeof(p_midi->epout_buf), ); + + // claim endpoint + TU_VERIFY(usbd_edpt_claim(rhport, p_midi->ep_out), ); + + // fifo can be changed before endpoint is claimed + available = tu_fifo_remaining(&p_midi->rx_ff); + + if ( available >= sizeof(p_midi->epout_buf) ) { + usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, sizeof(p_midi->epout_buf)); + }else + { + // Release endpoint since we don't make any transfer + usbd_edpt_release(rhport, p_midi->ep_out); + } +} + +//--------------------------------------------------------------------+ +// READ API +//--------------------------------------------------------------------+ +uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) +{ + (void) cable_num; + + midid_interface_t* midi = &_midid_itf[itf]; + midid_stream_t const* stream = &midi->stream_read; + + // when using with packet API stream total & index are both zero + return tu_fifo_count(&midi->rx_ff) + (stream->total - stream->index); +} + +uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize) +{ + (void) cable_num; + TU_VERIFY(bufsize, 0); + + uint8_t* buf8 = (uint8_t*) buffer; + + midid_interface_t* midi = &_midid_itf[itf]; + midid_stream_t* stream = &midi->stream_read; + + uint32_t total_read = 0; + while( bufsize ) + { + // Get new packet from fifo, then set packet expected bytes + if ( stream->total == 0 ) + { + // return if there is no more data from fifo + if ( !tud_midi_n_packet_read(itf, stream->buffer) ) return total_read; + + uint8_t const code_index = stream->buffer[0] & 0x0f; + + // MIDI 1.0 Table 4-1: Code Index Number Classifications + switch(code_index) + { + case MIDI_CIN_MISC: + case MIDI_CIN_CABLE_EVENT: + // These are reserved and unused, possibly issue somewhere, skip this packet + return 0; + break; + + case MIDI_CIN_SYSEX_END_1BYTE: + case MIDI_CIN_1BYTE_DATA: + stream->total = 1; + break; + + case MIDI_CIN_SYSCOM_2BYTE : + case MIDI_CIN_SYSEX_END_2BYTE : + case MIDI_CIN_PROGRAM_CHANGE : + case MIDI_CIN_CHANNEL_PRESSURE : + stream->total = 2; + break; + + default: + stream->total = 3; + break; + } + } + + // Copy data up to bufsize + uint32_t const count = tu_min32(stream->total - stream->index, bufsize); + + // Skip the header (1st byte) in the buffer + memcpy(buf8, stream->buffer + 1 + stream->index, count); + + total_read += count; + stream->index += count; + buf8 += count; + bufsize -= count; + + // complete current event packet, reset stream + if ( stream->total == stream->index ) + { + stream->index = 0; + stream->total = 0; + } + } + + return total_read; +} + +bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]) +{ + midid_interface_t* midi = &_midid_itf[itf]; + TU_VERIFY(midi->ep_out); + + uint32_t const num_read = tu_fifo_read_n(&midi->rx_ff, packet, 4); + _prep_out_transaction(midi); + return (num_read == 4); +} + +//--------------------------------------------------------------------+ +// WRITE API +//--------------------------------------------------------------------+ + +static uint32_t write_flush(midid_interface_t* midi) +{ + // No data to send + if ( !tu_fifo_count(&midi->tx_ff) ) return 0; + + uint8_t const rhport = TUD_OPT_RHPORT; + + // skip if previous transfer not complete + TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 ); + + uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EP_BUFSIZE); + + if (count) + { + TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, midi->epin_buf, count), 0 ); + return count; + }else + { + // Release endpoint since we don't make any transfer + usbd_edpt_release(rhport, midi->ep_in); + return 0; + } +} + +uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) +{ + midid_interface_t* midi = &_midid_itf[itf]; + TU_VERIFY(midi->ep_in, 0); + + midid_stream_t* stream = &midi->stream_write; + + uint32_t i = 0; + while ( (i < bufsize) && (tu_fifo_remaining(&midi->tx_ff) >= 4) ) + { + uint8_t const data = buffer[i]; + i++; + + if ( stream->index == 0 ) + { + //------------- New event packet -------------// + + uint8_t const msg = data >> 4; + + stream->index = 2; + stream->buffer[1] = data; + + // Check to see if we're still in a SysEx transmit. + if ( stream->buffer[0] == MIDI_CIN_SYSEX_START ) + { + if ( data == MIDI_STATUS_SYSEX_END ) + { + stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; + stream->total = 2; + } + else + { + stream->total = 4; + } + } + else if ( (msg >= 0x8 && msg <= 0xB) || msg == 0xE ) + { + // Channel Voice Messages + stream->buffer[0] = (cable_num << 4) | msg; + stream->total = 4; + } + else if ( msg == 0xC || msg == 0xD) + { + // Channel Voice Messages, two-byte variants (Program Change and Channel Pressure) + stream->buffer[0] = (cable_num << 4) | msg; + stream->total = 3; + } + else if ( msg == 0xf ) + { + // System message + if ( data == MIDI_STATUS_SYSEX_START ) + { + stream->buffer[0] = MIDI_CIN_SYSEX_START; + stream->total = 4; + } + else if ( data == MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME || data == MIDI_STATUS_SYSCOM_SONG_SELECT ) + { + stream->buffer[0] = MIDI_CIN_SYSCOM_2BYTE; + stream->total = 3; + } + else if ( data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER ) + { + stream->buffer[0] = MIDI_CIN_SYSCOM_3BYTE; + stream->total = 4; + } + else + { + stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; + stream->total = 2; + } + } + else + { + // Pack individual bytes if we don't support packing them into words. + stream->buffer[0] = cable_num << 4 | 0xf; + stream->buffer[2] = 0; + stream->buffer[3] = 0; + stream->index = 2; + stream->total = 2; + } + } + else + { + //------------- On-going (buffering) packet -------------// + + TU_ASSERT(stream->index < 4, i); + stream->buffer[stream->index] = data; + stream->index++; + + // See if this byte ends a SysEx. + if ( stream->buffer[0] == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END ) + { + stream->buffer[0] = MIDI_CIN_SYSEX_START + (stream->index - 1); + stream->total = stream->index; + } + } + + // Send out packet + if ( stream->index == stream->total ) + { + // zeroes unused bytes + for(uint8_t idx = stream->total; idx < 4; idx++) stream->buffer[idx] = 0; + + uint16_t const count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4); + + // complete current event packet, reset stream + stream->index = stream->total = 0; + + // FIFO overflown, since we already check fifo remaining. It is probably race condition + TU_ASSERT(count == 4, i); + } + } + + write_flush(midi); + + return i; +} + +bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]) +{ + midid_interface_t* midi = &_midid_itf[itf]; + TU_VERIFY(midi->ep_in); + + if (tu_fifo_remaining(&midi->tx_ff) < 4) return false; + + tu_fifo_write_n(&midi->tx_ff, packet, 4); + write_flush(midi); + + return true; +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void midid_init(void) +{ + tu_memclr(_midid_itf, sizeof(_midid_itf)); + + for(uint8_t i=0; irx_ff, midi->rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, 1, false); // true, true + tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS. + + #if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&midi->rx_ff, NULL, osal_mutex_create(&midi->rx_ff_mutex)); + tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex), NULL); + #endif + } +} + +void midid_reset(uint8_t rhport) +{ + (void) rhport; + + for(uint8_t i=0; irx_ff); + tu_fifo_clear(&midi->tx_ff); + } +} + +uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) +{ + // 1st Interface is Audio Control v1 + TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && + AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol, 0); + + uint16_t drv_len = tu_desc_len(desc_itf); + uint8_t const * p_desc = tu_desc_next(desc_itf); + + // Skip Class Specific descriptors + while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) + { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // 2nd Interface is MIDI Streaming + TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); + tusb_desc_interface_t const * desc_midi = (tusb_desc_interface_t const *) p_desc; + + TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass && + AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass && + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_midi->bInterfaceProtocol, 0); + + // Find available interface + midid_interface_t * p_midi = NULL; + for(uint8_t i=0; iitf_num = desc_midi->bInterfaceNumber; + (void) p_midi->itf_num; + + // next descriptor + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + + // Find and open endpoint descriptors + uint8_t found_endpoints = 0; + while ( (found_endpoints < desc_midi->bNumEndpoints) && (drv_len <= max_len) ) + { + if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) + { + TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0); + uint8_t ep_addr = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) + { + p_midi->ep_in = ep_addr; + } else { + p_midi->ep_out = ep_addr; + } + + // Class Specific MIDI Stream endpoint descriptor + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + + found_endpoints += 1; + } + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // Prepare for incoming data + _prep_out_transaction(p_midi); + + return drv_len; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + (void) rhport; + (void) stage; + (void) request; + + // driver doesn't support any request yet + return false; +} + +bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) result; + (void) rhport; + + uint8_t itf; + midid_interface_t* p_midi; + + // Identify which interface to use + for (itf = 0; itf < CFG_TUD_MIDI; itf++) + { + p_midi = &_midid_itf[itf]; + if ( ( ep_addr == p_midi->ep_out ) || ( ep_addr == p_midi->ep_in ) ) break; + } + TU_ASSERT(itf < CFG_TUD_MIDI); + + // receive new data + if ( ep_addr == p_midi->ep_out ) + { + tu_fifo_write_n(&p_midi->rx_ff, p_midi->epout_buf, xferred_bytes); + + // invoke receive callback if available + if (tud_midi_rx_cb) tud_midi_rx_cb(itf); + + // prepare for next + // TODO for now ep_out is not used by public API therefore there is no race condition, + // and does not need to claim like ep_in + _prep_out_transaction(p_midi); + } + else if ( ep_addr == p_midi->ep_in ) + { + if (0 == write_flush(p_midi)) + { + // If there is no data left, a ZLP should be sent if + // xferred_bytes is multiple of EP size and not zero + if ( !tu_fifo_count(&p_midi->tx_ff) && xferred_bytes && (0 == (xferred_bytes % CFG_TUD_MIDI_EP_BUFSIZE)) ) + { + if ( usbd_edpt_claim(rhport, p_midi->ep_in) ) + { + usbd_edpt_xfer(rhport, p_midi->ep_in, NULL, 0); + } + } + } + } + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/midi/midi_device.h b/circuitpython/lib/tinyusb/src/class/midi/midi_device.h new file mode 100644 index 0000000..211edc8 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/midi/midi_device.h @@ -0,0 +1,173 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MIDI_DEVICE_H_ +#define _TUSB_MIDI_DEVICE_H_ + +#include "class/audio/audio.h" +#include "midi.h" + +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ + +#if !defined(CFG_TUD_MIDI_EP_BUFSIZE) && defined(CFG_TUD_MIDI_EPSIZE) + #warning CFG_TUD_MIDI_EPSIZE is renamed to CFG_TUD_MIDI_EP_BUFSIZE, please update to use the new name + #define CFG_TUD_MIDI_EP_BUFSIZE CFG_TUD_MIDI_EPSIZE +#endif + +#ifndef CFG_TUD_MIDI_EP_BUFSIZE + #define CFG_TUD_MIDI_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/** \addtogroup MIDI_Serial Serial + * @{ + * \defgroup MIDI_Serial_Device Device + * @{ */ + +//--------------------------------------------------------------------+ +// Application API (Multiple Interfaces) +// CFG_TUD_MIDI > 1 +//--------------------------------------------------------------------+ + +// Check if midi interface is mounted +bool tud_midi_n_mounted (uint8_t itf); + +// Get the number of bytes available for reading +uint32_t tud_midi_n_available (uint8_t itf, uint8_t cable_num); + +// Read byte stream (legacy) +uint32_t tud_midi_n_stream_read (uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize); + +// Write byte Stream (legacy) +uint32_t tud_midi_n_stream_write (uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize); + +// Read event packet (4 bytes) +bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]); + +// Write event packet (4 bytes) +bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]); + +//--------------------------------------------------------------------+ +// Application API (Single Interface) +//--------------------------------------------------------------------+ +static inline bool tud_midi_mounted (void); +static inline uint32_t tud_midi_available (void); + +static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize); +static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize); + +static inline bool tud_midi_packet_read (uint8_t packet[4]); +static inline bool tud_midi_packet_write (uint8_t const packet[4]); + +//------------- Deprecated API name -------------// +// TODO remove after 0.10.0 release + +TU_ATTR_DEPRECATED("tud_midi_read() is renamed to tud_midi_stream_read()") +static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize) +{ + return tud_midi_stream_read(buffer, bufsize); +} + +TU_ATTR_DEPRECATED("tud_midi_write() is renamed to tud_midi_stream_write()") +static inline uint32_t tud_midi_write(uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) +{ + return tud_midi_stream_write(cable_num, buffer, bufsize); +} + + +TU_ATTR_DEPRECATED("tud_midi_send() is renamed to tud_midi_packet_write()") +static inline bool tud_midi_send(uint8_t packet[4]) +{ + return tud_midi_packet_write(packet); +} + +TU_ATTR_DEPRECATED("tud_midi_receive() is renamed to tud_midi_packet_read()") +static inline bool tud_midi_receive(uint8_t packet[4]) +{ + return tud_midi_packet_read(packet); +} + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf); + +//--------------------------------------------------------------------+ +// Inline Functions +//--------------------------------------------------------------------+ + +static inline bool tud_midi_mounted (void) +{ + return tud_midi_n_mounted(0); +} + +static inline uint32_t tud_midi_available (void) +{ + return tud_midi_n_available(0, 0); +} + +static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize) +{ + return tud_midi_n_stream_read(0, 0, buffer, bufsize); +} + +static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) +{ + return tud_midi_n_stream_write(0, cable_num, buffer, bufsize); +} + +static inline bool tud_midi_packet_read (uint8_t packet[4]) +{ + return tud_midi_n_packet_read(0, packet); +} + +static inline bool tud_midi_packet_write (uint8_t const packet[4]) +{ + return tud_midi_n_packet_write(0, packet); +} + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void midid_init (void); +void midid_reset (uint8_t rhport); +uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool midid_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_MIDI_DEVICE_H_ */ + +/** @} */ +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/class/msc/msc.h b/circuitpython/lib/tinyusb/src/class/msc/msc.h new file mode 100644 index 0000000..84b6e4d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/msc/msc.h @@ -0,0 +1,382 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MSC_H_ +#define _TUSB_MSC_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Mass Storage Class Constant +//--------------------------------------------------------------------+ +/// MassStorage Subclass +typedef enum +{ + MSC_SUBCLASS_RBC = 1 , ///< Reduced Block Commands (RBC) T10 Project 1240-D + MSC_SUBCLASS_SFF_MMC , ///< SFF-8020i, MMC-2 (ATAPI). Typically used by a CD/DVD device + MSC_SUBCLASS_QIC , ///< QIC-157. Typically used by a tape device + MSC_SUBCLASS_UFI , ///< UFI. Typically used by Floppy Disk Drive (FDD) device + MSC_SUBCLASS_SFF , ///< SFF-8070i. Can be used by Floppy Disk Drive (FDD) device + MSC_SUBCLASS_SCSI ///< SCSI transparent command set +}msc_subclass_type_t; + +enum { + MSC_CBW_SIGNATURE = 0x43425355, ///< Constant value of 43425355h (little endian) + MSC_CSW_SIGNATURE = 0x53425355 ///< Constant value of 53425355h (little endian) +}; + +/// \brief MassStorage Protocol. +/// \details CBI only approved to use with full-speed floopy disk & should not used with highspeed or device other than floopy +typedef enum +{ + MSC_PROTOCOL_CBI = 0 , ///< Control/Bulk/Interrupt protocol (with command completion interrupt) + MSC_PROTOCOL_CBI_NO_INTERRUPT = 1 , ///< Control/Bulk/Interrupt protocol (without command completion interrupt) + MSC_PROTOCOL_BOT = 0x50 ///< Bulk-Only Transport +}msc_protocol_type_t; + +/// MassStorage Class-Specific Control Request +typedef enum +{ + MSC_REQ_GET_MAX_LUN = 254, ///< The Get Max LUN device request is used to determine the number of logical units supported by the device. Logical Unit Numbers on the device shall be numbered contiguously starting from LUN 0 to a maximum LUN of 15 + MSC_REQ_RESET = 255 ///< This request is used to reset the mass storage device and its associated interface. This class-specific request shall ready the device for the next CBW from the host. +}msc_request_type_t; + +/// \brief Command Block Status Values +/// \details Indicates the success or failure of the command. The device shall set this byte to zero if the command completed +/// successfully. A non-zero value shall indicate a failure during command execution according to the following +typedef enum +{ + MSC_CSW_STATUS_PASSED = 0 , ///< MSC_CSW_STATUS_PASSED + MSC_CSW_STATUS_FAILED , ///< MSC_CSW_STATUS_FAILED + MSC_CSW_STATUS_PHASE_ERROR ///< MSC_CSW_STATUS_PHASE_ERROR +}msc_csw_status_t; + +/// Command Block Wrapper +typedef struct TU_ATTR_PACKED +{ + uint32_t signature; ///< Signature that helps identify this data packet as a CBW. The signature field shall contain the value 43425355h (little endian), indicating a CBW. + uint32_t tag; ///< Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTagfield of the associated CSW. The dCSWTagpositively associates a CSW with the corresponding CBW. + uint32_t total_bytes; ///< The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during the execution of this command. If this field is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore the value of the Direction bit in bmCBWFlags. + uint8_t dir; ///< Bit 7 of this field define transfer direction \n - 0 : Data-Out from host to the device. \n - 1 : Data-In from the device to the host. + uint8_t lun; ///< The device Logical Unit Number (LUN) to which the command block is being sent. For devices that support multiple LUNs, the host shall place into this field the LUN to which this command block is addressed. Otherwise, the host shall set this field to zero. + uint8_t cmd_len; ///< The valid length of the CBWCBin bytes. This defines the valid length of the command block. The only legal values are 1 through 16 + uint8_t command[16]; ///< The command block to be executed by the device. The device shall interpret the first cmd_len bytes in this field as a command block +}msc_cbw_t; + +TU_VERIFY_STATIC(sizeof(msc_cbw_t) == 31, "size is not correct"); + +/// Command Status Wrapper +typedef struct TU_ATTR_PACKED +{ + uint32_t signature ; ///< Signature that helps identify this data packet as a CSW. The signature field shall contain the value 53425355h (little endian), indicating CSW. + uint32_t tag ; ///< The device shall set this field to the value received in the dCBWTag of the associated CBW. + uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device + uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t +}msc_csw_t; + +TU_VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct"); + +//--------------------------------------------------------------------+ +// SCSI Constant +//--------------------------------------------------------------------+ + +/// SCSI Command Operation Code +typedef enum +{ + SCSI_CMD_TEST_UNIT_READY = 0x00, ///< The SCSI Test Unit Ready command is used to determine if a device is ready to transfer data (read/write), i.e. if a disk has spun up, if a tape is loaded and ready etc. The device does not perform a self-test operation. + SCSI_CMD_INQUIRY = 0x12, ///< The SCSI Inquiry command is used to obtain basic information from a target device. + SCSI_CMD_MODE_SELECT_6 = 0x15, ///< provides a means for the application client to specify medium, logical unit, or peripheral device parameters to the device server. Device servers that implement the MODE SELECT(6) command shall also implement the MODE SENSE(6) command. Application clients should issue MODE SENSE(6) prior to each MODE SELECT(6) to determine supported mode pages, page lengths, and other parameters. + SCSI_CMD_MODE_SENSE_6 = 0x1A, ///< provides a means for a device server to report parameters to an application client. It is a complementary command to the MODE SELECT(6) command. Device servers that implement the MODE SENSE(6) command shall also implement the MODE SELECT(6) command. + SCSI_CMD_START_STOP_UNIT = 0x1B, + SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E, + SCSI_CMD_READ_CAPACITY_10 = 0x25, ///< The SCSI Read Capacity command is used to obtain data capacity information from a target device. + SCSI_CMD_REQUEST_SENSE = 0x03, ///< The SCSI Request Sense command is part of the SCSI computer protocol standard. This command is used to obtain sense data -- status/error information -- from a target device. + SCSI_CMD_READ_FORMAT_CAPACITY = 0x23, ///< The command allows the Host to request a list of the possible format capacities for an installed writable media. This command also has the capability to report the writable capacity for a media when it is installed + SCSI_CMD_READ_10 = 0x28, ///< The READ (10) command requests that the device server read the specified logical block(s) and transfer them to the data-in buffer. + SCSI_CMD_WRITE_10 = 0x2A, ///< The WRITE (10) command requests thatthe device server transfer the specified logical block(s) from the data-out buffer and write them. +}scsi_cmd_type_t; + +/// SCSI Sense Key +typedef enum +{ + SCSI_SENSE_NONE = 0x00, ///< no specific Sense Key. This would be the case for a successful command + SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< ndicates the last command completed successfully with some recovery action performed by the disc drive. + SCSI_SENSE_NOT_READY = 0x02, ///< Indicates the logical unit addressed cannot be accessed. + SCSI_SENSE_MEDIUM_ERROR = 0x03, ///< Indicates the command terminated with a non-recovered error condition. + SCSI_SENSE_HARDWARE_ERROR = 0x04, ///< Indicates the disc drive detected a nonrecoverable hardware failure while performing the command or during a self test. + SCSI_SENSE_ILLEGAL_REQUEST = 0x05, ///< Indicates an illegal parameter in the command descriptor block or in the additional parameters + SCSI_SENSE_UNIT_ATTENTION = 0x06, ///< Indicates the disc drive may have been reset. + SCSI_SENSE_DATA_PROTECT = 0x07, ///< Indicates that a command that reads or writes the medium was attempted on a block that is protected from this operation. The read or write operation is not performed. + SCSI_SENSE_FIRMWARE_ERROR = 0x08, ///< Vendor specific sense key. + SCSI_SENSE_ABORTED_COMMAND = 0x0b, ///< Indicates the disc drive aborted the command. + SCSI_SENSE_EQUAL = 0x0c, ///< Indicates a SEARCH DATA command has satisfied an equal comparison. + SCSI_SENSE_VOLUME_OVERFLOW = 0x0d, ///< Indicates a buffered peripheral device has reached the end of medium partition and data remains in the buffer that has not been written to the medium. + SCSI_SENSE_MISCOMPARE = 0x0e ///< ndicates that the source data did not match the data read from the medium. +}scsi_sense_key_type_t; + +//--------------------------------------------------------------------+ +// SCSI Primary Command (SPC-4) +//--------------------------------------------------------------------+ + +/// SCSI Test Unit Ready Command +typedef struct TU_ATTR_PACKED +{ + uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_TEST_UNIT_READY + uint8_t lun ; ///< Logical Unit + uint8_t reserved[3] ; + uint8_t control ; +} scsi_test_unit_ready_t; + +TU_VERIFY_STATIC(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct"); + +/// SCSI Inquiry Command +typedef struct TU_ATTR_PACKED +{ + uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_INQUIRY + uint8_t reserved1 ; + uint8_t page_code ; + uint8_t reserved2 ; + uint8_t alloc_length ; ///< specifies the maximum number of bytes that USB host has allocated in the Data-In Buffer. An allocation length of zero specifies that no data shall be transferred. + uint8_t control ; +} scsi_inquiry_t, scsi_request_sense_t; + +TU_VERIFY_STATIC(sizeof(scsi_inquiry_t) == 6, "size is not correct"); + +/// SCSI Inquiry Response Data +typedef struct TU_ATTR_PACKED +{ + uint8_t peripheral_device_type : 5; + uint8_t peripheral_qualifier : 3; + + uint8_t : 7; + uint8_t is_removable : 1; + + uint8_t version; + + uint8_t response_data_format : 4; + uint8_t hierarchical_support : 1; + uint8_t normal_aca : 1; + uint8_t : 2; + + uint8_t additional_length; + + uint8_t protect : 1; + uint8_t : 2; + uint8_t third_party_copy : 1; + uint8_t target_port_group_support : 2; + uint8_t access_control_coordinator : 1; + uint8_t scc_support : 1; + + uint8_t addr16 : 1; + uint8_t : 3; + uint8_t multi_port : 1; + uint8_t : 1; // vendor specific + uint8_t enclosure_service : 1; + uint8_t : 1; + + uint8_t : 1; // vendor specific + uint8_t cmd_que : 1; + uint8_t : 2; + uint8_t sync : 1; + uint8_t wbus16 : 1; + uint8_t : 2; + + uint8_t vendor_id[8] ; ///< 8 bytes of ASCII data identifying the vendor of the product. + uint8_t product_id[16]; ///< 16 bytes of ASCII data defined by the vendor. + uint8_t product_rev[4]; ///< 4 bytes of ASCII data defined by the vendor. +} scsi_inquiry_resp_t; + +TU_VERIFY_STATIC(sizeof(scsi_inquiry_resp_t) == 36, "size is not correct"); + + +typedef struct TU_ATTR_PACKED +{ + uint8_t response_code : 7; ///< 70h - current errors, Fixed Format 71h - deferred errors, Fixed Format + uint8_t valid : 1; + + uint8_t reserved; + + uint8_t sense_key : 4; + uint8_t : 1; + uint8_t ili : 1; ///< Incorrect length indicator + uint8_t end_of_medium : 1; + uint8_t filemark : 1; + + uint32_t information; + uint8_t add_sense_len; + uint32_t command_specific_info; + uint8_t add_sense_code; + uint8_t add_sense_qualifier; + uint8_t field_replaceable_unit_code; + + uint8_t sense_key_specific[3]; ///< sense key specific valid bit is bit 7 of key[0], aka MSB in Big Endian layout + +} scsi_sense_fixed_resp_t; + +TU_VERIFY_STATIC(sizeof(scsi_sense_fixed_resp_t) == 18, "size is not correct"); + +typedef struct TU_ATTR_PACKED +{ + uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_MODE_SENSE_6 + + uint8_t : 3; + uint8_t disable_block_descriptor : 1; + uint8_t : 4; + + uint8_t page_code : 6; + uint8_t page_control : 2; + + uint8_t subpage_code; + uint8_t alloc_length; + uint8_t control; +} scsi_mode_sense6_t; + +TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct"); + +// This is only a Mode parameter header(6). +typedef struct TU_ATTR_PACKED +{ + uint8_t data_len; + uint8_t medium_type; + + uint8_t reserved : 7; + bool write_protected : 1; + + uint8_t block_descriptor_len; +} scsi_mode_sense6_resp_t; + +TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_resp_t) == 4, "size is not correct"); + +typedef struct TU_ATTR_PACKED +{ + uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL + uint8_t reserved[3]; + uint8_t prohibit_removal; + uint8_t control; +} scsi_prevent_allow_medium_removal_t; + +TU_VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct"); + +typedef struct TU_ATTR_PACKED +{ + uint8_t cmd_code; + + uint8_t immded : 1; + uint8_t : 7; + + uint8_t TU_RESERVED; + + uint8_t power_condition_mod : 4; + uint8_t : 4; + + uint8_t start : 1; + uint8_t load_eject : 1; + uint8_t no_flush : 1; + uint8_t : 1; + uint8_t power_condition : 4; + + uint8_t control; +} scsi_start_stop_unit_t; + +TU_VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct"); + +//--------------------------------------------------------------------+ +// SCSI MMC +//--------------------------------------------------------------------+ +/// SCSI Read Format Capacity: Write Capacity +typedef struct TU_ATTR_PACKED +{ + uint8_t cmd_code; + uint8_t reserved[6]; + uint16_t alloc_length; + uint8_t control; +} scsi_read_format_capacity_t; + +TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_t) == 10, "size is not correct"); + +typedef struct TU_ATTR_PACKED{ + uint8_t reserved[3]; + uint8_t list_length; /// must be 8*n, length in bytes of formattable capacity descriptor followed it. + + uint32_t block_num; /// Number of Logical Blocks + uint8_t descriptor_type; // 00: reserved, 01 unformatted media , 10 Formatted media, 11 No media present + + uint8_t reserved2; + uint16_t block_size_u16; + +} scsi_read_format_capacity_data_t; + +TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_data_t) == 12, "size is not correct"); + +//--------------------------------------------------------------------+ +// SCSI Block Command (SBC-3) +// NOTE: All data in SCSI command are in Big Endian +//--------------------------------------------------------------------+ + +/// SCSI Read Capacity 10 Command: Read Capacity +typedef struct TU_ATTR_PACKED +{ + uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_READ_CAPACITY_10 + uint8_t reserved1 ; + uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command + uint16_t reserved2 ; + uint8_t partial_medium_indicator ; + uint8_t control ; +} scsi_read_capacity10_t; + +TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_t) == 10, "size is not correct"); + +/// SCSI Read Capacity 10 Response Data +typedef struct { + uint32_t last_lba ; ///< The last Logical Block Address of the device + uint32_t block_size ; ///< Block size in bytes +} scsi_read_capacity10_resp_t; + +TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_resp_t) == 8, "size is not correct"); + +/// SCSI Read 10 Command +typedef struct TU_ATTR_PACKED +{ + uint8_t cmd_code ; ///< SCSI OpCode + uint8_t reserved ; // has LUN according to wiki + uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command + uint8_t reserved2 ; + uint16_t block_count ; ///< Number of Blocks used by this command + uint8_t control ; +} scsi_read10_t, scsi_write10_t; + +TU_VERIFY_STATIC(sizeof(scsi_read10_t) == 10, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct"); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_MSC_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/msc/msc_device.c b/circuitpython/lib/tinyusb/src/class/msc/msc_device.c new file mode 100644 index 0000000..3facb76 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/msc/msc_device.c @@ -0,0 +1,951 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_MSC) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" +#include "device/dcd.h" // for faking dcd_event_xfer_complete + +#include "msc_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// Can be selectively disabled to reduce logging when troubleshooting other driver +#define MSC_DEBUG 2 + +enum +{ + MSC_STAGE_CMD = 0, + MSC_STAGE_DATA, + MSC_STAGE_STATUS, + MSC_STAGE_STATUS_SENT, + MSC_STAGE_NEED_RESET, +}; + +typedef struct +{ + // TODO optimize alignment + CFG_TUSB_MEM_ALIGN msc_cbw_t cbw; + CFG_TUSB_MEM_ALIGN msc_csw_t csw; + + uint8_t itf_num; + uint8_t ep_in; + uint8_t ep_out; + + // Bulk Only Transfer (BOT) Protocol + uint8_t stage; + uint32_t total_len; // byte to be transferred, can be smaller than total_bytes in cbw + uint32_t xferred_len; // numbered of bytes transferred so far in the Data Stage + + // Sense Response Data + uint8_t sense_key; + uint8_t add_sense_code; + uint8_t add_sense_qualifier; +}mscd_interface_t; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static mscd_interface_t _mscd_itf; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE]; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_t* buffer, uint32_t bufsize); +static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc); + +static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc); +static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint32_t xferred_bytes); + +TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir) +{ + return tu_bit_test(dir, 7); +} + +static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc) +{ + // Data residue is always = host expect - actual transferred + p_msc->csw.data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len; + + p_msc->stage = MSC_STAGE_STATUS_SENT; + return usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)); +} + +static inline bool prepare_cbw(uint8_t rhport, mscd_interface_t* p_msc) +{ + p_msc->stage = MSC_STAGE_CMD; + return usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)); +} + +static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status) +{ + msc_cbw_t const * p_cbw = &p_msc->cbw; + msc_csw_t * p_csw = &p_msc->csw; + + p_csw->status = status; + p_csw->data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len; + p_msc->stage = MSC_STAGE_STATUS; + + // failed but sense key is not set: default to Illegal Request + if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + + // If there is data stage and not yet complete, stall it + if ( p_cbw->total_bytes && p_csw->data_residue ) + { + if ( is_data_in(p_cbw->dir) ) + { + usbd_edpt_stall(rhport, p_msc->ep_in); + } + else + { + usbd_edpt_stall(rhport, p_msc->ep_out); + } + } +} + +static inline uint32_t rdwr10_get_lba(uint8_t const command[]) +{ + // use offsetof to avoid pointer to the odd/unaligned address + uint32_t const lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba)); + + // lba is in Big Endian + return tu_ntohl(lba); +} + +static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw) +{ + uint16_t const block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count)); + return tu_ntohs(block_count); +} + +static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) +{ + // first extract block count in the command + uint16_t const block_count = rdwr10_get_blockcount(cbw); + + // invalid block count + if (block_count == 0) return 0; + + return (uint16_t) (cbw->total_bytes / block_count); +} + +uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) +{ + uint8_t status = MSC_CSW_STATUS_PASSED; + uint16_t const block_count = rdwr10_get_blockcount(cbw); + + if ( cbw->total_bytes == 0 ) + { + if ( block_count ) + { + TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n"); + status = MSC_CSW_STATUS_PHASE_ERROR; + }else + { + // no data transfer, only exist in complaint test suite + } + }else + { + if ( SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir) ) + { + TU_LOG(MSC_DEBUG, " SCSI case 10 (Ho <> Di)\r\n"); + status = MSC_CSW_STATUS_PHASE_ERROR; + } + else if ( SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir) ) + { + TU_LOG(MSC_DEBUG, " SCSI case 8 (Hi <> Do)\r\n"); + status = MSC_CSW_STATUS_PHASE_ERROR; + } + else if ( 0 == block_count ) + { + TU_LOG(MSC_DEBUG, " SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n"); + status = MSC_CSW_STATUS_FAILED; + } + else if ( cbw->total_bytes / block_count == 0 ) + { + TU_LOG(MSC_DEBUG, " Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n"); + status = MSC_CSW_STATUS_PHASE_ERROR; + } + } + + return status; +} + +//--------------------------------------------------------------------+ +// Debug +//--------------------------------------------------------------------+ +#if CFG_TUSB_DEBUG >= 2 + +TU_ATTR_UNUSED static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = +{ + { .key = SCSI_CMD_TEST_UNIT_READY , .data = "Test Unit Ready" }, + { .key = SCSI_CMD_INQUIRY , .data = "Inquiry" }, + { .key = SCSI_CMD_MODE_SELECT_6 , .data = "Mode_Select 6" }, + { .key = SCSI_CMD_MODE_SENSE_6 , .data = "Mode_Sense 6" }, + { .key = SCSI_CMD_START_STOP_UNIT , .data = "Start Stop Unit" }, + { .key = SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL , .data = "Prevent/Allow Medium Removal" }, + { .key = SCSI_CMD_READ_CAPACITY_10 , .data = "Read Capacity10" }, + { .key = SCSI_CMD_REQUEST_SENSE , .data = "Request Sense" }, + { .key = SCSI_CMD_READ_FORMAT_CAPACITY , .data = "Read Format Capacity" }, + { .key = SCSI_CMD_READ_10 , .data = "Read10" }, + { .key = SCSI_CMD_WRITE_10 , .data = "Write10" } +}; + +TU_ATTR_UNUSED static tu_lookup_table_t const _msc_scsi_cmd_table = +{ + .count = TU_ARRAY_SIZE(_msc_scsi_cmd_lookup), + .items = _msc_scsi_cmd_lookup +}; + +#endif + +//--------------------------------------------------------------------+ +// APPLICATION API +//--------------------------------------------------------------------+ +bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier) +{ + (void) lun; + + _mscd_itf.sense_key = sense_key; + _mscd_itf.add_sense_code = add_sense_code; + _mscd_itf.add_sense_qualifier = add_sense_qualifier; + + return true; +} + +static inline void set_sense_medium_not_present(uint8_t lun) +{ + // default sense is NOT READY, MEDIUM NOT PRESENT + tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00); +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void mscd_init(void) +{ + tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); +} + +void mscd_reset(uint8_t rhport) +{ + (void) rhport; + tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); +} + +uint16_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + // only support SCSI's BOT protocol + TU_VERIFY(TUSB_CLASS_MSC == itf_desc->bInterfaceClass && + MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass && + MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol, 0); + + // msc driver length is fixed + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); + + // Max length must be at least 1 interface + 2 endpoints + TU_ASSERT(max_len >= drv_len, 0); + + mscd_interface_t * p_msc = &_mscd_itf; + p_msc->itf_num = itf_desc->bInterfaceNumber; + + // Open endpoint pair + TU_ASSERT( usbd_open_edpt_pair(rhport, tu_desc_next(itf_desc), 2, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in), 0 ); + + // Prepare for Command Block Wrapper + TU_ASSERT( prepare_cbw(rhport, p_msc), drv_len); + + return drv_len; +} + +static void proc_bot_reset(mscd_interface_t* p_msc) +{ + p_msc->stage = MSC_STAGE_CMD; + p_msc->total_len = 0; + p_msc->xferred_len = 0; + + p_msc->sense_key = 0; + p_msc->add_sense_code = 0; + p_msc->add_sense_qualifier = 0; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + // nothing to do with DATA & ACK stage + if (stage != CONTROL_STAGE_SETUP) return true; + + mscd_interface_t* p_msc = &_mscd_itf; + + // Clear Endpoint Feature (stall) for recovery + if ( TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && + TUSB_REQ_RCPT_ENDPOINT == request->bmRequestType_bit.recipient && + TUSB_REQ_CLEAR_FEATURE == request->bRequest && + TUSB_REQ_FEATURE_EDPT_HALT == request->wValue ) + { + uint8_t const ep_addr = tu_u16_low(request->wIndex); + + if ( p_msc->stage == MSC_STAGE_NEED_RESET ) + { + // reset recovery is required to recover from this stage + // Clear Stall request cannot resolve this -> continue to stall endpoint + usbd_edpt_stall(rhport, ep_addr); + } + else + { + if ( ep_addr == p_msc->ep_in ) + { + if ( p_msc->stage == MSC_STAGE_STATUS ) + { + // resume sending SCSI status if we are in this stage previously before stalled + TU_ASSERT( send_csw(rhport, p_msc) ); + } + } + else if ( ep_addr == p_msc->ep_out ) + { + if ( p_msc->stage == MSC_STAGE_CMD ) + { + // part of reset recovery (probably due to invalid CBW) -> prepare for new command + // Note: skip if already queued previously + if ( usbd_edpt_ready(rhport, p_msc->ep_out) ) + { + TU_ASSERT( prepare_cbw(rhport, p_msc) ); + } + } + } + } + + return true; + } + + // From this point only handle class request only + TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); + + switch ( request->bRequest ) + { + case MSC_REQ_RESET: + TU_LOG(MSC_DEBUG, " MSC BOT Reset\r\n"); + TU_VERIFY(request->wValue == 0 && request->wLength == 0); + + // driver state reset + proc_bot_reset(p_msc); + + tud_control_status(rhport, request); + break; + + case MSC_REQ_GET_MAX_LUN: + { + TU_LOG(MSC_DEBUG, " MSC Get Max Lun\r\n"); + TU_VERIFY(request->wValue == 0 && request->wLength == 1); + + uint8_t maxlun = 1; + if (tud_msc_get_maxlun_cb) maxlun = tud_msc_get_maxlun_cb(); + TU_VERIFY(maxlun); + + // MAX LUN is minus 1 by specs + maxlun--; + + tud_control_xfer(rhport, request, &maxlun, 1); + } + break; + + default: return false; // stall unsupported request + } + + return true; +} + +bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) +{ + (void) event; + + mscd_interface_t* p_msc = &_mscd_itf; + msc_cbw_t const * p_cbw = &p_msc->cbw; + msc_csw_t * p_csw = &p_msc->csw; + + switch (p_msc->stage) + { + case MSC_STAGE_CMD: + //------------- new CBW received -------------// + // Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it + if(ep_addr != p_msc->ep_out) return true; + + if ( !(xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE) ) + { + TU_LOG(MSC_DEBUG, " SCSI CBW is not valid\r\n"); + + // BOT 6.6.1 If CBW is not valid stall both endpoints until reset recovery + p_msc->stage = MSC_STAGE_NEED_RESET; + + // invalid CBW stall both endpoints + usbd_edpt_stall(rhport, p_msc->ep_in); + usbd_edpt_stall(rhport, p_msc->ep_out); + + return false; + } + + TU_LOG(MSC_DEBUG, " SCSI Command [Lun%u]: %s\r\n", p_cbw->lun, tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0])); + //TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2); + + p_csw->signature = MSC_CSW_SIGNATURE; + p_csw->tag = p_cbw->tag; + p_csw->data_residue = 0; + p_csw->status = MSC_CSW_STATUS_PASSED; + + /*------------- Parse command and prepare DATA -------------*/ + p_msc->stage = MSC_STAGE_DATA; + p_msc->total_len = p_cbw->total_bytes; + p_msc->xferred_len = 0; + + // Read10 or Write10 + if ( (SCSI_CMD_READ_10 == p_cbw->command[0]) || (SCSI_CMD_WRITE_10 == p_cbw->command[0]) ) + { + uint8_t const status = rdwr10_validate_cmd(p_cbw); + + if ( status != MSC_CSW_STATUS_PASSED) + { + fail_scsi_op(rhport, p_msc, status); + }else if ( p_cbw->total_bytes ) + { + if (SCSI_CMD_READ_10 == p_cbw->command[0]) + { + proc_read10_cmd(rhport, p_msc); + }else + { + proc_write10_cmd(rhport, p_msc); + } + }else + { + // no data transfer, only exist in complaint test suite + p_msc->stage = MSC_STAGE_STATUS; + } + } + else + { + // For other SCSI commands + // 1. OUT : queue transfer (invoke app callback after done) + // 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length + if ( (p_cbw->total_bytes > 0 ) && !is_data_in(p_cbw->dir) ) + { + if (p_cbw->total_bytes > sizeof(_mscd_buf)) + { + TU_LOG(MSC_DEBUG, " SCSI reject non READ10/WRITE10 with large data\r\n"); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + }else + { + // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first + // but it is OK to just receive data then responded with failed status + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) ); + } + }else + { + // First process if it is a built-in commands + int32_t resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, _mscd_buf, sizeof(_mscd_buf)); + + // Invoke user callback if not built-in + if ( (resplen < 0) && (p_msc->sense_key == 0) ) + { + resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); + } + + if ( resplen < 0 ) + { + // unsupported command + TU_LOG(MSC_DEBUG, " SCSI unsupported or failed command\r\n"); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + } + else if (resplen == 0) + { + if (p_cbw->total_bytes) + { + // 6.7 The 13 Cases: case 4 (Hi > Dn) + // TU_LOG(MSC_DEBUG, " SCSI case 4 (Hi > Dn): %lu\r\n", p_cbw->total_bytes); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + }else + { + // case 1 Hn = Dn: all good + p_msc->stage = MSC_STAGE_STATUS; + } + } + else + { + if ( p_cbw->total_bytes == 0 ) + { + // 6.7 The 13 Cases: case 2 (Hn < Di) + // TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di): %lu\r\n", p_cbw->total_bytes); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + }else + { + // cannot return more than host expect + p_msc->total_len = tu_min32((uint32_t) resplen, p_cbw->total_bytes); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) ); + } + } + } + } + break; + + case MSC_STAGE_DATA: + TU_LOG(MSC_DEBUG, " SCSI Data [Lun%u]\r\n", p_cbw->lun); + //TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2); + + if (SCSI_CMD_READ_10 == p_cbw->command[0]) + { + p_msc->xferred_len += xferred_bytes; + + if ( p_msc->xferred_len >= p_msc->total_len ) + { + // Data Stage is complete + p_msc->stage = MSC_STAGE_STATUS; + }else + { + proc_read10_cmd(rhport, p_msc); + } + } + else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) + { + proc_write10_new_data(rhport, p_msc, xferred_bytes); + } + else + { + p_msc->xferred_len += xferred_bytes; + + // OUT transfer, invoke callback if needed + if ( !is_data_in(p_cbw->dir) ) + { + int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); + + if ( cb_result < 0 ) + { + // unsupported command + TU_LOG(MSC_DEBUG, " SCSI unsupported command\r\n"); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + }else + { + // TODO haven't implement this scenario any further yet + } + } + + if ( p_msc->xferred_len >= p_msc->total_len ) + { + // Data Stage is complete + p_msc->stage = MSC_STAGE_STATUS; + } + else + { + // This scenario with command that take more than one transfer is already rejected at Command stage + TU_BREAKPOINT(); + } + } + break; + + case MSC_STAGE_STATUS: + // processed immediately after this switch, supposedly to be empty + break; + + case MSC_STAGE_STATUS_SENT: + // Wait for the Status phase to complete + if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) ) + { + TU_LOG(MSC_DEBUG, " SCSI Status [Lun%u] = %u\r\n", p_cbw->lun, p_csw->status); + // TU_LOG_MEM(MSC_DEBUG, p_csw, xferred_bytes, 2); + + // Invoke complete callback if defined + // Note: There is racing issue with samd51 + qspi flash testing with arduino + // if complete_cb() is invoked after queuing the status. + switch(p_cbw->command[0]) + { + case SCSI_CMD_READ_10: + if ( tud_msc_read10_complete_cb ) tud_msc_read10_complete_cb(p_cbw->lun); + break; + + case SCSI_CMD_WRITE_10: + if ( tud_msc_write10_complete_cb ) tud_msc_write10_complete_cb(p_cbw->lun); + break; + + default: + if ( tud_msc_scsi_complete_cb ) tud_msc_scsi_complete_cb(p_cbw->lun, p_cbw->command); + break; + } + + TU_ASSERT( prepare_cbw(rhport, p_msc) ); + }else + { + // Any xfer ended here is consider unknown error, ignore it + TU_LOG1(" Warning expect SCSI Status but received unknown data\r\n"); + } + break; + + default : break; + } + + if ( p_msc->stage == MSC_STAGE_STATUS ) + { + // skip status if epin is currently stalled, will do it when received Clear Stall request + if ( !usbd_edpt_stalled(rhport, p_msc->ep_in) ) + { + if ( (p_cbw->total_bytes > p_msc->xferred_len) && is_data_in(p_cbw->dir) ) + { + // 6.7 The 13 Cases: case 5 (Hi > Di): STALL before status + // TU_LOG(MSC_DEBUG, " SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_cbw->total_bytes, p_msc->xferred_len); + usbd_edpt_stall(rhport, p_msc->ep_in); + }else + { + TU_ASSERT( send_csw(rhport, p_msc) ); + } + } + + #if TU_CHECK_MCU(OPT_MCU_CXD56) + // WORKAROUND: cxd56 has its own nuttx usb stack which does not forward Set/ClearFeature(Endpoint) to DCD. + // There is no way for us to know when EP is un-stall, therefore we will unconditionally un-stall here and + // hope everything will work + if ( usbd_edpt_stalled(rhport, p_msc->ep_in) ) + { + usbd_edpt_clear_stall(rhport, p_msc->ep_in); + send_csw(rhport, p_msc); + } + #endif + } + + return true; +} + +/*------------------------------------------------------------------*/ +/* SCSI Command Process + *------------------------------------------------------------------*/ + +// return response's length (copied to buffer). Negative if it is not an built-in command or indicate Failed status (CSW) +// In case of a failed status, sense key must be set for reason of failure +static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_t* buffer, uint32_t bufsize) +{ + (void) bufsize; // TODO refractor later + int32_t resplen; + + mscd_interface_t* p_msc = &_mscd_itf; + + switch ( scsi_cmd[0] ) + { + case SCSI_CMD_TEST_UNIT_READY: + resplen = 0; + if ( !tud_msc_test_unit_ready_cb(lun) ) + { + // Failed status response + resplen = - 1; + + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); + } + break; + + case SCSI_CMD_START_STOP_UNIT: + resplen = 0; + + if (tud_msc_start_stop_cb) + { + scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd; + if ( !tud_msc_start_stop_cb(lun, start_stop->power_condition, start_stop->start, start_stop->load_eject) ) + { + // Failed status response + resplen = - 1; + + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); + } + } + break; + + case SCSI_CMD_READ_CAPACITY_10: + { + uint32_t block_count; + uint32_t block_size; + uint16_t block_size_u16; + + tud_msc_capacity_cb(lun, &block_count, &block_size_u16); + block_size = (uint32_t) block_size_u16; + + // Invalid block size/count from callback, possibly unit is not ready + // stall this request, set sense key to NOT READY + if (block_count == 0 || block_size == 0) + { + resplen = -1; + + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); + }else + { + scsi_read_capacity10_resp_t read_capa10; + + read_capa10.last_lba = tu_htonl(block_count-1); + read_capa10.block_size = tu_htonl(block_size); + + resplen = sizeof(read_capa10); + memcpy(buffer, &read_capa10, resplen); + } + } + break; + + case SCSI_CMD_READ_FORMAT_CAPACITY: + { + scsi_read_format_capacity_data_t read_fmt_capa = + { + .list_length = 8, + .block_num = 0, + .descriptor_type = 2, // formatted media + .block_size_u16 = 0 + }; + + uint32_t block_count; + uint16_t block_size; + + tud_msc_capacity_cb(lun, &block_count, &block_size); + + // Invalid block size/count from callback, possibly unit is not ready + // stall this request, set sense key to NOT READY + if (block_count == 0 || block_size == 0) + { + resplen = -1; + + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); + }else + { + read_fmt_capa.block_num = tu_htonl(block_count); + read_fmt_capa.block_size_u16 = tu_htons(block_size); + + resplen = sizeof(read_fmt_capa); + memcpy(buffer, &read_fmt_capa, resplen); + } + } + break; + + case SCSI_CMD_INQUIRY: + { + scsi_inquiry_resp_t inquiry_rsp = + { + .is_removable = 1, + .version = 2, + .response_data_format = 2, + .additional_length = sizeof(scsi_inquiry_resp_t) - 5, + }; + + // vendor_id, product_id, product_rev is space padded string + memset(inquiry_rsp.vendor_id , ' ', sizeof(inquiry_rsp.vendor_id)); + memset(inquiry_rsp.product_id , ' ', sizeof(inquiry_rsp.product_id)); + memset(inquiry_rsp.product_rev, ' ', sizeof(inquiry_rsp.product_rev)); + + tud_msc_inquiry_cb(lun, inquiry_rsp.vendor_id, inquiry_rsp.product_id, inquiry_rsp.product_rev); + + resplen = sizeof(inquiry_rsp); + memcpy(buffer, &inquiry_rsp, resplen); + } + break; + + case SCSI_CMD_MODE_SENSE_6: + { + scsi_mode_sense6_resp_t mode_resp = + { + .data_len = 3, + .medium_type = 0, + .write_protected = false, + .reserved = 0, + .block_descriptor_len = 0 // no block descriptor are included + }; + + bool writable = true; + if ( tud_msc_is_writable_cb ) + { + writable = tud_msc_is_writable_cb(lun); + } + + mode_resp.write_protected = !writable; + + resplen = sizeof(mode_resp); + memcpy(buffer, &mode_resp, resplen); + } + break; + + case SCSI_CMD_REQUEST_SENSE: + { + scsi_sense_fixed_resp_t sense_rsp = + { + .response_code = 0x70, // current, fixed format + .valid = 1 + }; + + sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8; + sense_rsp.sense_key = p_msc->sense_key; + sense_rsp.add_sense_code = p_msc->add_sense_code; + sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier; + + resplen = sizeof(sense_rsp); + memcpy(buffer, &sense_rsp, resplen); + + // request sense callback could overwrite the sense data + if (tud_msc_request_sense_cb) + { + resplen = tud_msc_request_sense_cb(lun, buffer, bufsize); + } + + // Clear sense data after copy + tud_msc_set_sense(lun, 0, 0, 0); + } + break; + + default: resplen = -1; break; + } + + return resplen; +} + +static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) +{ + msc_cbw_t const * p_cbw = &p_msc->cbw; + + // block size already verified not zero + uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); + + // Adjust lba with transferred bytes + uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); + + // remaining bytes capped at class buffer + int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len); + + // Application can consume smaller bytes + uint32_t const offset = p_msc->xferred_len % block_sz; + nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_buf, (uint32_t) nbytes); + + if ( nbytes < 0 ) + { + // negative means error -> endpoint is stalled & status in CSW set to failed + TU_LOG(MSC_DEBUG, " tud_msc_read10_cb() return -1\r\n"); + + // set sense + set_sense_medium_not_present(p_cbw->lun); + + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + } + else if ( nbytes == 0 ) + { + // zero means not ready -> simulate an transfer complete so that this driver callback will fired again + dcd_event_xfer_complete(rhport, p_msc->ep_in, 0, XFER_RESULT_SUCCESS, false); + } + else + { + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, nbytes), ); + } +} + +static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc) +{ + msc_cbw_t const * p_cbw = &p_msc->cbw; + bool writable = true; + + if ( tud_msc_is_writable_cb ) + { + writable = tud_msc_is_writable_cb(p_cbw->lun); + } + + if ( !writable ) + { + // Not writable, complete this SCSI op with error + // Sense = Write protected + tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + return; + } + + // remaining bytes capped at class buffer + int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len); + + // Write10 callback will be called later when usb transfer complete + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, nbytes), ); +} + +// process new data arrived from WRITE10 +static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint32_t xferred_bytes) +{ + msc_cbw_t const * p_cbw = &p_msc->cbw; + + // block size already verified not zero + uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); + + // Adjust lba with transferred bytes + uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); + + // Invoke callback to consume new data + uint32_t const offset = p_msc->xferred_len % block_sz; + int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_buf, xferred_bytes); + + if ( nbytes < 0 ) + { + // negative means error -> failed this scsi op + TU_LOG(MSC_DEBUG, " tud_msc_write10_cb() return -1\r\n"); + + // update actual byte before failed + p_msc->xferred_len += xferred_bytes; + + // Set sense + set_sense_medium_not_present(p_cbw->lun); + + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + }else + { + // Application consume less than what we got (including zero) + if ( (uint32_t) nbytes < xferred_bytes ) + { + if ( nbytes > 0 ) + { + p_msc->xferred_len += nbytes; + memmove(_mscd_buf, _mscd_buf+nbytes, xferred_bytes-nbytes); + } + + // simulate an transfer complete with adjusted parameters --> callback will be invoked with adjusted parameter + dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false); + } + else + { + // Application consume all bytes in our buffer + p_msc->xferred_len += xferred_bytes; + + if ( p_msc->xferred_len >= p_msc->total_len ) + { + // Data Stage is complete + p_msc->stage = MSC_STAGE_STATUS; + }else + { + // prepare to receive more data from host + proc_write10_cmd(rhport, p_msc); + } + } + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/msc/msc_device.h b/circuitpython/lib/tinyusb/src/class/msc/msc_device.h new file mode 100644 index 0000000..5839b16 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/msc/msc_device.h @@ -0,0 +1,162 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MSC_DEVICE_H_ +#define _TUSB_MSC_DEVICE_H_ + +#include "common/tusb_common.h" +#include "msc.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ + +#if !defined(CFG_TUD_MSC_EP_BUFSIZE) & defined(CFG_TUD_MSC_BUFSIZE) + // TODO warn user to use new name later on + // #warning CFG_TUD_MSC_BUFSIZE is renamed to CFG_TUD_MSC_EP_BUFSIZE, please update to use the new name + #define CFG_TUD_MSC_EP_BUFSIZE CFG_TUD_MSC_BUFSIZE +#endif + +#ifndef CFG_TUD_MSC_EP_BUFSIZE + #error CFG_TUD_MSC_EP_BUFSIZE must be defined, value of a block size should work well, the more the better +#endif + +TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE < UINT16_MAX, "Size is not correct"); + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + +// Set SCSI sense response +bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier); + +//--------------------------------------------------------------------+ +// Application Callbacks (WEAK is optional) +//--------------------------------------------------------------------+ + +// Invoked when received SCSI READ10 command +// - Address = lba * BLOCK_SIZE + offset +// - offset is only needed if CFG_TUD_MSC_EP_BUFSIZE is smaller than BLOCK_SIZE. +// +// - Application fill the buffer (up to bufsize) with address contents and return number of read byte. If +// - read < bufsize : These bytes are transferred first and callback invoked again for remaining data. +// +// - read == 0 : Indicate application is not ready yet e.g disk I/O busy. +// Callback invoked again with the same parameters later on. +// +// - read < 0 : Indicate application error e.g invalid address. This request will be STALLed +// and return failed status in command status wrapper phase. +int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize); + +// Invoked when received SCSI WRITE10 command +// - Address = lba * BLOCK_SIZE + offset +// - offset is only needed if CFG_TUD_MSC_EP_BUFSIZE is smaller than BLOCK_SIZE. +// +// - Application write data from buffer to address contents (up to bufsize) and return number of written byte. If +// - write < bufsize : callback invoked again with remaining data later on. +// +// - write == 0 : Indicate application is not ready yet e.g disk I/O busy. +// Callback invoked again with the same parameters later on. +// +// - write < 0 : Indicate application error e.g invalid address. This request will be STALLed +// and return failed status in command status wrapper phase. +// +// TODO change buffer to const uint8_t* +int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize); + +// Invoked when received SCSI_CMD_INQUIRY +// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively +void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]); + +// Invoked when received Test Unit Ready command. +// return true allowing host to read/write this LUN e.g SD card inserted +bool tud_msc_test_unit_ready_cb(uint8_t lun); + +// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size +// Application update block count and block size +void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size); + +/** + * Invoked when received an SCSI command not in built-in list below. + * - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE + * - READ10 and WRITE10 has their own callbacks + * + * \param[in] lun Logical unit number + * \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly + * \param[out] buffer Buffer for SCSI Data Stage. + * - For INPUT: application must fill this with response. + * - For OUTPUT it holds the Data from host + * \param[in] bufsize Buffer's length. + * + * \return Actual bytes processed, can be zero for no-data command. + * \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding + * endpoint and return failed status in command status wrapper phase. + */ +int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize); + +/*------------- Optional callbacks -------------*/ + +// Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation +TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void); + +// Invoked when received Start Stop Unit command +// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage +// - Start = 1 : active mode, if load_eject = 1 : load disk storage +TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject); + +// Invoked when received REQUEST_SENSE +TU_ATTR_WEAK int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize); + +// Invoked when Read10 command is complete +TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun); + +// Invoke when Write10 command is complete, can be used to flush flash caching +TU_ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun); + +// Invoked when command in tud_msc_scsi_cb is complete +TU_ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]); + +// Invoked to check if device is writable as part of SCSI WRITE10 +TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void mscd_init (void); +void mscd_reset (uint8_t rhport); +uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request); +bool mscd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_MSC_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/msc/msc_host.c b/circuitpython/lib/tinyusb/src/class/msc/msc_host.c new file mode 100644 index 0000000..e4239e3 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/msc/msc_host.c @@ -0,0 +1,491 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && CFG_TUH_MSC + +#include "host/usbh.h" +#include "host/usbh_classdriver.h" + +#include "msc_host.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +enum +{ + MSC_STAGE_IDLE = 0, + MSC_STAGE_CMD, + MSC_STAGE_DATA, + MSC_STAGE_STATUS, +}; + +typedef struct +{ + uint8_t itf_num; + uint8_t ep_in; + uint8_t ep_out; + + uint8_t max_lun; + + volatile bool configured; // Receive SET_CONFIGURE + volatile bool mounted; // Enumeration is complete + + struct { + uint32_t block_size; + uint32_t block_count; + } capacity[CFG_TUH_MSC_MAXLUN]; + + //------------- SCSI -------------// + uint8_t stage; + void* buffer; + tuh_msc_complete_cb_t complete_cb; + + msc_cbw_t cbw; + msc_csw_t csw; +}msch_interface_t; + +CFG_TUSB_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX]; + +// buffer used to read scsi information when mounted +// largest response data currently is inquiry TODO Inquiry is not part of enum anymore +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) +static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)]; + +TU_ATTR_ALWAYS_INLINE +static inline msch_interface_t* get_itf(uint8_t dev_addr) +{ + return &_msch_itf[dev_addr-1]; +} + +//--------------------------------------------------------------------+ +// PUBLIC API +//--------------------------------------------------------------------+ +uint8_t tuh_msc_get_maxlun(uint8_t dev_addr) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + return p_msc->max_lun; +} + +uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + return p_msc->capacity[lun].block_count; +} + +uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + return p_msc->capacity[lun].block_size; +} + +bool tuh_msc_mounted(uint8_t dev_addr) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + return p_msc->mounted; +} + +bool tuh_msc_ready(uint8_t dev_addr) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + return p_msc->mounted && !usbh_edpt_busy(dev_addr, p_msc->ep_in); +} + +//--------------------------------------------------------------------+ +// PUBLIC API: SCSI COMMAND +//--------------------------------------------------------------------+ +static inline void cbw_init(msc_cbw_t *cbw, uint8_t lun) +{ + tu_memclr(cbw, sizeof(msc_cbw_t)); + cbw->signature = MSC_CBW_SIGNATURE; + cbw->tag = 0x54555342; // TUSB + cbw->lun = lun; +} + +bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + TU_VERIFY(p_msc->configured); + + // TODO claim endpoint + + p_msc->cbw = *cbw; + p_msc->stage = MSC_STAGE_CMD; + p_msc->buffer = data; + p_msc->complete_cb = complete_cb; + + TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t))); + + return true; +} + +bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + TU_VERIFY(p_msc->configured); + + msc_cbw_t cbw; + cbw_init(&cbw, lun); + + cbw.total_bytes = sizeof(scsi_read_capacity10_resp_t); + cbw.dir = TUSB_DIR_IN_MASK; + cbw.cmd_len = sizeof(scsi_read_capacity10_t); + cbw.command[0] = SCSI_CMD_READ_CAPACITY_10; + + return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb); +} + +bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + TU_VERIFY(p_msc->mounted); + + msc_cbw_t cbw; + cbw_init(&cbw, lun); + + cbw.total_bytes = sizeof(scsi_inquiry_resp_t); + cbw.dir = TUSB_DIR_IN_MASK; + cbw.cmd_len = sizeof(scsi_inquiry_t); + + scsi_inquiry_t const cmd_inquiry = + { + .cmd_code = SCSI_CMD_INQUIRY, + .alloc_length = sizeof(scsi_inquiry_resp_t) + }; + memcpy(cbw.command, &cmd_inquiry, cbw.cmd_len); + + return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb); +} + +bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + TU_VERIFY(p_msc->configured); + + msc_cbw_t cbw; + cbw_init(&cbw, lun); + + cbw.total_bytes = 0; + cbw.dir = TUSB_DIR_OUT; + cbw.cmd_len = sizeof(scsi_test_unit_ready_t); + cbw.command[0] = SCSI_CMD_TEST_UNIT_READY; + cbw.command[1] = lun; // according to wiki TODO need verification + + return tuh_msc_scsi_command(dev_addr, &cbw, NULL, complete_cb); +} + +bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_msc_complete_cb_t complete_cb) +{ + msc_cbw_t cbw; + cbw_init(&cbw, lun); + + cbw.total_bytes = 18; // TODO sense response + cbw.dir = TUSB_DIR_IN_MASK; + cbw.cmd_len = sizeof(scsi_request_sense_t); + + scsi_request_sense_t const cmd_request_sense = + { + .cmd_code = SCSI_CMD_REQUEST_SENSE, + .alloc_length = 18 + }; + + memcpy(cbw.command, &cmd_request_sense, cbw.cmd_len); + + return tuh_msc_scsi_command(dev_addr, &cbw, resposne, complete_cb); +} + +bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + TU_VERIFY(p_msc->mounted); + + msc_cbw_t cbw; + cbw_init(&cbw, lun); + + cbw.total_bytes = block_count*p_msc->capacity[lun].block_size; + cbw.dir = TUSB_DIR_IN_MASK; + cbw.cmd_len = sizeof(scsi_read10_t); + + scsi_read10_t const cmd_read10 = + { + .cmd_code = SCSI_CMD_READ_10, + .lba = tu_htonl(lba), + .block_count = tu_htons(block_count) + }; + + memcpy(cbw.command, &cmd_read10, cbw.cmd_len); + + return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb); +} + +bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + TU_VERIFY(p_msc->mounted); + + msc_cbw_t cbw; + cbw_init(&cbw, lun); + + cbw.total_bytes = block_count*p_msc->capacity[lun].block_size; + cbw.dir = TUSB_DIR_OUT; + cbw.cmd_len = sizeof(scsi_write10_t); + + scsi_write10_t const cmd_write10 = + { + .cmd_code = SCSI_CMD_WRITE_10, + .lba = tu_htonl(lba), + .block_count = tu_htons(block_count) + }; + + memcpy(cbw.command, &cmd_write10, cbw.cmd_len); + + return tuh_msc_scsi_command(dev_addr, &cbw, (void*)(uintptr_t) buffer, complete_cb); +} + +#if 0 +// MSC interface Reset (not used now) +bool tuh_msc_reset(uint8_t dev_addr) +{ + tusb_control_request_t const new_request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = MSC_REQ_RESET, + .wValue = 0, + .wIndex = p_msc->itf_num, + .wLength = 0 + }; + TU_ASSERT( usbh_control_xfer( dev_addr, &new_request, NULL ) ); +} +#endif + +//--------------------------------------------------------------------+ +// CLASS-USBH API +//--------------------------------------------------------------------+ +void msch_init(void) +{ + tu_memclr(_msch_itf, sizeof(_msch_itf)); +} + +void msch_close(uint8_t dev_addr) +{ + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); + + msch_interface_t* p_msc = get_itf(dev_addr); + + // invoke Application Callback + if (p_msc->mounted && tuh_msc_umount_cb) tuh_msc_umount_cb(dev_addr); + + tu_memclr(p_msc, sizeof(msch_interface_t)); +} + +bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + msc_cbw_t const * cbw = &p_msc->cbw; + msc_csw_t * csw = &p_msc->csw; + + switch (p_msc->stage) + { + case MSC_STAGE_CMD: + // Must be Command Block + TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t)); + + if ( cbw->total_bytes && p_msc->buffer ) + { + // Data stage if any + p_msc->stage = MSC_STAGE_DATA; + + uint8_t const ep_data = (cbw->dir & TUSB_DIR_IN_MASK) ? p_msc->ep_in : p_msc->ep_out; + TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, cbw->total_bytes)); + }else + { + // Status stage + p_msc->stage = MSC_STAGE_STATUS; + TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t))); + } + break; + + case MSC_STAGE_DATA: + // Status stage + p_msc->stage = MSC_STAGE_STATUS; + TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t))); + break; + + case MSC_STAGE_STATUS: + // SCSI op is complete + p_msc->stage = MSC_STAGE_IDLE; + + if (p_msc->complete_cb) p_msc->complete_cb(dev_addr, cbw, csw); + break; + + // unknown state + default: break; + } + + return true; +} + +//--------------------------------------------------------------------+ +// MSC Enumeration +//--------------------------------------------------------------------+ + +static bool config_get_maxlun_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); +static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); +static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); + +bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) +{ + TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && + MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); + + // msc driver length is fixed + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + TU_ASSERT(drv_len <= max_len); + + msch_interface_t* p_msc = get_itf(dev_addr); + tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(desc_itf); + + for(uint32_t i=0; i<2; i++) + { + TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); + TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc)); + + if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ) + { + p_msc->ep_in = ep_desc->bEndpointAddress; + }else + { + p_msc->ep_out = ep_desc->bEndpointAddress; + } + + ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(ep_desc); + } + + p_msc->itf_num = desc_itf->bInterfaceNumber; + + return true; +} + +bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) +{ + msch_interface_t* p_msc = get_itf(dev_addr); + TU_ASSERT(p_msc->itf_num == itf_num); + + p_msc->configured = true; + + //------------- Get Max Lun -------------// + TU_LOG2("MSC Get Max Lun\r\n"); + tusb_control_request_t request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = MSC_REQ_GET_MAX_LUN, + .wValue = 0, + .wIndex = itf_num, + .wLength = 1 + }; + TU_ASSERT(tuh_control_xfer(dev_addr, &request, &p_msc->max_lun, config_get_maxlun_complete)); + + return true; +} + +static bool config_get_maxlun_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) request; + + msch_interface_t* p_msc = get_itf(dev_addr); + + // STALL means zero + p_msc->max_lun = (XFER_RESULT_SUCCESS == result) ? _msch_buffer[0] : 0; + p_msc->max_lun++; // MAX LUN is minus 1 by specs + + // TODO multiple LUN support + TU_LOG2("SCSI Test Unit Ready\r\n"); + uint8_t const lun = 0; + tuh_msc_test_unit_ready(dev_addr, lun, config_test_unit_ready_complete); + + return true; +} + +static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw) +{ + if (csw->status == 0) + { + // Unit is ready, read its capacity + TU_LOG2("SCSI Read Capacity\r\n"); + tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), config_read_capacity_complete); + }else + { + // Note: During enumeration, some device fails Test Unit Ready and require a few retries + // with Request Sense to start working !! + // TODO limit number of retries + TU_LOG2("SCSI Request Sense\r\n"); + TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, _msch_buffer, config_request_sense_complete)); + } + + return true; +} + +static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw) +{ + TU_ASSERT(csw->status == 0); + TU_ASSERT(tuh_msc_test_unit_ready(dev_addr, cbw->lun, config_test_unit_ready_complete)); + return true; +} + +static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw) +{ + TU_ASSERT(csw->status == 0); + + msch_interface_t* p_msc = get_itf(dev_addr); + + // Capacity response field: Block size and Last LBA are both Big-Endian + scsi_read_capacity10_resp_t* resp = (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer); + p_msc->capacity[cbw->lun].block_count = tu_ntohl(resp->last_lba) + 1; + p_msc->capacity[cbw->lun].block_size = tu_ntohl(resp->block_size); + + // Mark enumeration is complete + p_msc->mounted = true; + if (tuh_msc_mount_cb) tuh_msc_mount_cb(dev_addr); + + // notify usbh that driver enumeration is complete + usbh_driver_set_config_complete(dev_addr, p_msc->itf_num); + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/msc/msc_host.h b/circuitpython/lib/tinyusb/src/class/msc/msc_host.h new file mode 100644 index 0000000..7718ad4 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/msc/msc_host.h @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MSC_HOST_H_ +#define _TUSB_MSC_HOST_H_ + +#include "msc.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ + +#ifndef CFG_TUH_MSC_MAXLUN +#define CFG_TUH_MSC_MAXLUN 4 +#endif + +typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + +// Check if device supports MassStorage interface. +// This function true after tuh_msc_mounted_cb() and false after tuh_msc_unmounted_cb() +bool tuh_msc_mounted(uint8_t dev_addr); + +// Check if the interface is currently ready or busy transferring data +bool tuh_msc_ready(uint8_t dev_addr); + +// Get Max Lun +uint8_t tuh_msc_get_maxlun(uint8_t dev_addr); + +// Get number of block +uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun); + +// Get block size in bytes +uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun); + +// Perform a full SCSI command (cbw, data, csw) in non-blocking manner. +// Complete callback is invoked when SCSI op is complete. +// return true if success, false if there is already pending operation. +bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb); + +// Perform SCSI Inquiry command +// Complete callback is invoked when SCSI op is complete. +bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb); + +// Perform SCSI Test Unit Ready command +// Complete callback is invoked when SCSI op is complete. +bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb); + +// Perform SCSI Request Sense 10 command +// Complete callback is invoked when SCSI op is complete. +bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_msc_complete_cb_t complete_cb); + +// Perform SCSI Read 10 command. Read n blocks starting from LBA to buffer +// Complete callback is invoked when SCSI op is complete. +bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb); + +// Perform SCSI Write 10 command. Write n blocks starting from LBA to device +// Complete callback is invoked when SCSI op is complete. +bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb); + +// Perform SCSI Read Capacity 10 command +// Complete callback is invoked when SCSI op is complete. +// Note: during enumeration, host stack already carried out this request. Application can retrieve capacity by +// simply call tuh_msc_get_block_count() and tuh_msc_get_block_size() +bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb); + +//------------- Application Callback -------------// + +// Invoked when a device with MassStorage interface is mounted +TU_ATTR_WEAK void tuh_msc_mount_cb(uint8_t dev_addr); + +// Invoked when a device with MassStorage interface is unmounted +TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ + +void msch_init (void); +bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); +bool msch_set_config (uint8_t dev_addr, uint8_t itf_num); +void msch_close (uint8_t dev_addr); +bool msch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_MSC_HOST_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/net/ecm_rndis_device.c b/circuitpython/lib/tinyusb/src/class/net/ecm_rndis_device.c new file mode 100644 index 0000000..f6b3180 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/net/ecm_rndis_device.c @@ -0,0 +1,445 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Peter Lawrence + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if ( CFG_TUD_ENABLED && CFG_TUD_ECM_RNDIS ) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "net_device.h" +#include "rndis_protocol.h" + +void rndis_class_set_handler(uint8_t *data, int size); /* found in ./misc/networking/rndis_reports.c */ + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef struct +{ + uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface + uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active + + uint8_t ep_notif; + uint8_t ep_in; + uint8_t ep_out; + + bool ecm_mode; + + // Endpoint descriptor use to open/close when receving SetInterface + // TODO since configuration descriptor may not be long-lived memory, we should + // keep a copy of endpoint attribute instead + uint8_t const * ecm_desc_epdata; + +} netd_interface_t; + +#define CFG_TUD_NET_PACKET_PREFIX_LEN sizeof(rndis_data_packet_t) +#define CFG_TUD_NET_PACKET_SUFFIX_LEN 0 + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t received[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t transmitted[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN]; + +struct ecm_notify_struct +{ + tusb_control_request_t header; + uint32_t downlink, uplink; +}; + +static const struct ecm_notify_struct ecm_notify_nc = +{ + .header = { + .bmRequestType = 0xA1, + .bRequest = 0 /* NETWORK_CONNECTION aka NetworkConnection */, + .wValue = 1 /* Connected */, + .wLength = 0, + }, +}; + +static const struct ecm_notify_struct ecm_notify_csc = +{ + .header = { + .bmRequestType = 0xA1, + .bRequest = 0x2A /* CONNECTION_SPEED_CHANGE aka ConnectionSpeedChange */, + .wLength = 8, + }, + .downlink = 9728000, + .uplink = 9728000, +}; + +// TODO remove CFG_TUSB_MEM_SECTION, control internal buffer is already in this special section +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static union +{ + uint8_t rndis_buf[120]; + struct ecm_notify_struct ecm_buf; +} notify; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +// TODO remove CFG_TUSB_MEM_SECTION +CFG_TUSB_MEM_SECTION static netd_interface_t _netd_itf; + +static bool can_xmit; + +void tud_network_recv_renew(void) +{ + usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_out, received, sizeof(received)); +} + +static void do_in_xfer(uint8_t *buf, uint16_t len) +{ + can_xmit = false; + usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_in, buf, len); +} + +void netd_report(uint8_t *buf, uint16_t len) +{ + // skip if previous report not yet acknowledged by host + if ( usbd_edpt_busy(TUD_OPT_RHPORT, _netd_itf.ep_notif) ) return; + usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_notif, buf, len); +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void netd_init(void) +{ + tu_memclr(&_netd_itf, sizeof(_netd_itf)); +} + +void netd_reset(uint8_t rhport) +{ + (void) rhport; + + netd_init(); +} + +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + bool const is_rndis = (TUD_RNDIS_ITF_CLASS == itf_desc->bInterfaceClass && + TUD_RNDIS_ITF_SUBCLASS == itf_desc->bInterfaceSubClass && + TUD_RNDIS_ITF_PROTOCOL == itf_desc->bInterfaceProtocol); + + bool const is_ecm = (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL == itf_desc->bInterfaceSubClass && + 0x00 == itf_desc->bInterfaceProtocol); + + TU_VERIFY(is_rndis || is_ecm, 0); + + // confirm interface hasn't already been allocated + TU_ASSERT(0 == _netd_itf.ep_notif, 0); + + // sanity check the descriptor + _netd_itf.ecm_mode = is_ecm; + + //------------- Management Interface -------------// + _netd_itf.itf_num = itf_desc->bInterfaceNumber; + + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const * p_desc = tu_desc_next( itf_desc ); + + // Communication Functional Descriptors + while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) + { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // notification endpoint (if any) + if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) + { + TU_ASSERT( usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0 ); + + _netd_itf.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + //------------- Data Interface -------------// + // - RNDIS Data followed immediately by a pair of endpoints + // - CDC-ECM data interface has 2 alternate settings + // - 0 : zero endpoints for inactive (default) + // - 1 : IN & OUT endpoints for active networking + TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); + + do + { + tusb_desc_interface_t const * data_itf_desc = (tusb_desc_interface_t const *) p_desc; + TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + }while( _netd_itf.ecm_mode && (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len) ); + + // Pair of endpoints + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); + + if ( _netd_itf.ecm_mode ) + { + // ECM by default is in-active, save the endpoint attribute + // to open later when received setInterface + _netd_itf.ecm_desc_epdata = p_desc; + }else + { + // Open endpoint pair for RNDIS + TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, &_netd_itf.ep_in), 0 ); + + tud_network_init_cb(); + + // we are ready to transmit a packet + can_xmit = true; + + // prepare for incoming packets + tud_network_recv_renew(); + } + + drv_len += 2*sizeof(tusb_desc_endpoint_t); + + return drv_len; +} + +static void ecm_report(bool nc) +{ + notify.ecm_buf = (nc) ? ecm_notify_nc : ecm_notify_csc; + notify.ecm_buf.header.wIndex = _netd_itf.itf_num; + netd_report((uint8_t *)¬ify.ecm_buf, (nc) ? sizeof(notify.ecm_buf.header) : sizeof(notify.ecm_buf)); +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + if ( stage == CONTROL_STAGE_SETUP ) + { + switch ( request->bmRequestType_bit.type ) + { + case TUSB_REQ_TYPE_STANDARD: + switch ( request->bRequest ) + { + case TUSB_REQ_GET_INTERFACE: + { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + TU_VERIFY(_netd_itf.itf_num+1 == req_itfnum); + + tud_control_xfer(rhport, request, &_netd_itf.itf_data_alt, 1); + } + break; + + case TUSB_REQ_SET_INTERFACE: + { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + uint8_t const req_alt = (uint8_t) request->wValue; + + // Only valid for Data Interface with Alternate is either 0 or 1 + TU_VERIFY(_netd_itf.itf_num+1 == req_itfnum && req_alt < 2); + + // ACM-ECM only: qequest to enable/disable network activities + TU_VERIFY(_netd_itf.ecm_mode); + + _netd_itf.itf_data_alt = req_alt; + + if ( _netd_itf.itf_data_alt ) + { + // TODO since we don't actually close endpoint + // hack here to not re-open it + if ( _netd_itf.ep_in == 0 && _netd_itf.ep_out == 0 ) + { + TU_ASSERT(_netd_itf.ecm_desc_epdata); + TU_ASSERT( usbd_open_edpt_pair(rhport, _netd_itf.ecm_desc_epdata, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, &_netd_itf.ep_in) ); + + // TODO should be merge with RNDIS's after endpoint opened + // Also should have opposite callback for application to disable network !! + tud_network_init_cb(); + can_xmit = true; // we are ready to transmit a packet + tud_network_recv_renew(); // prepare for incoming packets + } + }else + { + // TODO close the endpoint pair + // For now pretend that we did, this should have no harm since host won't try to + // communicate with the endpoints again + // _netd_itf.ep_in = _netd_itf.ep_out = 0 + } + + tud_control_status(rhport, request); + } + break; + + // unsupported request + default: return false; + } + break; + + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY (_netd_itf.itf_num == request->wIndex); + + if (_netd_itf.ecm_mode) + { + /* the only required CDC-ECM Management Element Request is SetEthernetPacketFilter */ + if (0x43 /* SET_ETHERNET_PACKET_FILTER */ == request->bRequest) + { + tud_control_xfer(rhport, request, NULL, 0); + ecm_report(true); + } + } + else + { + if (request->bmRequestType_bit.direction == TUSB_DIR_IN) + { + rndis_generic_msg_t *rndis_msg = (rndis_generic_msg_t *) ((void*) notify.rndis_buf); + uint32_t msglen = tu_le32toh(rndis_msg->MessageLength); + TU_ASSERT(msglen <= sizeof(notify.rndis_buf)); + tud_control_xfer(rhport, request, notify.rndis_buf, msglen); + } + else + { + tud_control_xfer(rhport, request, notify.rndis_buf, sizeof(notify.rndis_buf)); + } + } + break; + + // unsupported request + default: return false; + } + } + else if ( stage == CONTROL_STAGE_DATA ) + { + // Handle RNDIS class control OUT only + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS && + request->bmRequestType_bit.direction == TUSB_DIR_OUT && + _netd_itf.itf_num == request->wIndex) + { + if ( !_netd_itf.ecm_mode ) + { + rndis_class_set_handler(notify.rndis_buf, request->wLength); + } + } + } + + return true; +} + +static void handle_incoming_packet(uint32_t len) +{ + uint8_t *pnt = received; + uint32_t size = 0; + + if (_netd_itf.ecm_mode) + { + size = len; + } + else + { + rndis_data_packet_t *r = (rndis_data_packet_t *) ((void*) pnt); + if (len >= sizeof(rndis_data_packet_t)) + if ( (r->MessageType == REMOTE_NDIS_PACKET_MSG) && (r->MessageLength <= len)) + if ( (r->DataOffset + offsetof(rndis_data_packet_t, DataOffset) + r->DataLength) <= len) + { + pnt = &received[r->DataOffset + offsetof(rndis_data_packet_t, DataOffset)]; + size = r->DataLength; + } + } + + if (!tud_network_recv_cb(pnt, size)) + { + /* if a buffer was never handled by user code, we must renew on the user's behalf */ + tud_network_recv_renew(); + } +} + +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) rhport; + (void) result; + + /* new packet received */ + if ( ep_addr == _netd_itf.ep_out ) + { + handle_incoming_packet(xferred_bytes); + } + + /* data transmission finished */ + if ( ep_addr == _netd_itf.ep_in ) + { + /* TinyUSB requires the class driver to implement ZLP (since ZLP usage is class-specific) */ + + if ( xferred_bytes && (0 == (xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE)) ) + { + do_in_xfer(NULL, 0); /* a ZLP is needed */ + } + else + { + /* we're finally finished */ + can_xmit = true; + } + } + + if ( _netd_itf.ecm_mode && (ep_addr == _netd_itf.ep_notif) ) + { + if (sizeof(notify.ecm_buf.header) == xferred_bytes) ecm_report(false); + } + + return true; +} + +bool tud_network_can_xmit(uint16_t size) +{ + (void)size; + + return can_xmit; +} + +void tud_network_xmit(void *ref, uint16_t arg) +{ + uint8_t *data; + uint16_t len; + + if (!can_xmit) + return; + + len = (_netd_itf.ecm_mode) ? 0 : CFG_TUD_NET_PACKET_PREFIX_LEN; + data = transmitted + len; + + len += tud_network_xmit_cb(data, ref, arg); + + if (!_netd_itf.ecm_mode) + { + rndis_data_packet_t *hdr = (rndis_data_packet_t *) ((void*) transmitted); + memset(hdr, 0, sizeof(rndis_data_packet_t)); + hdr->MessageType = REMOTE_NDIS_PACKET_MSG; + hdr->MessageLength = len; + hdr->DataOffset = sizeof(rndis_data_packet_t) - offsetof(rndis_data_packet_t, DataOffset); + hdr->DataLength = len - sizeof(rndis_data_packet_t); + } + + do_in_xfer(transmitted, len); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/net/ncm.h b/circuitpython/lib/tinyusb/src/class/net/ncm.h new file mode 100644 index 0000000..96ba11f --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/net/ncm.h @@ -0,0 +1,69 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef _TUSB_NCM_H_ +#define _TUSB_NCM_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +// Table 4.3 Data Class Interface Protocol Codes +typedef enum +{ + NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 +} ncm_data_interface_protocol_code_t; + + +// Table 6.2 Class-Specific Request Codes for Network Control Model subclass +typedef enum +{ + NCM_SET_ETHERNET_MULTICAST_FILTERS = 0x40, + NCM_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41, + NCM_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42, + NCM_SET_ETHERNET_PACKET_FILTER = 0x43, + NCM_GET_ETHERNET_STATISTIC = 0x44, + NCM_GET_NTB_PARAMETERS = 0x80, + NCM_GET_NET_ADDRESS = 0x81, + NCM_SET_NET_ADDRESS = 0x82, + NCM_GET_NTB_FORMAT = 0x83, + NCM_SET_NTB_FORMAT = 0x84, + NCM_GET_NTB_INPUT_SIZE = 0x85, + NCM_SET_NTB_INPUT_SIZE = 0x86, + NCM_GET_MAX_DATAGRAM_SIZE = 0x87, + NCM_SET_MAX_DATAGRAM_SIZE = 0x88, + NCM_GET_CRC_MODE = 0x89, + NCM_SET_CRC_MODE = 0x8A, +} ncm_request_code_t; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/net/ncm_device.c b/circuitpython/lib/tinyusb/src/class/net/ncm_device.c new file mode 100644 index 0000000..1987337 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/net/ncm_device.c @@ -0,0 +1,510 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" +#include "net_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +#define NTH16_SIGNATURE 0x484D434E +#define NDP16_SIGNATURE_NCM0 0x304D434E +#define NDP16_SIGNATURE_NCM1 0x314D434E + +typedef struct TU_ATTR_PACKED +{ + uint16_t wLength; + uint16_t bmNtbFormatsSupported; + uint32_t dwNtbInMaxSize; + uint16_t wNdbInDivisor; + uint16_t wNdbInPayloadRemainder; + uint16_t wNdbInAlignment; + uint16_t wReserved; + uint32_t dwNtbOutMaxSize; + uint16_t wNdbOutDivisor; + uint16_t wNdbOutPayloadRemainder; + uint16_t wNdbOutAlignment; + uint16_t wNtbOutMaxDatagrams; +} ntb_parameters_t; + +typedef struct TU_ATTR_PACKED +{ + uint32_t dwSignature; + uint16_t wHeaderLength; + uint16_t wSequence; + uint16_t wBlockLength; + uint16_t wNdpIndex; +} nth16_t; + +typedef struct TU_ATTR_PACKED +{ + uint16_t wDatagramIndex; + uint16_t wDatagramLength; +} ndp16_datagram_t; + +typedef struct TU_ATTR_PACKED +{ + uint32_t dwSignature; + uint16_t wLength; + uint16_t wNextNdpIndex; + ndp16_datagram_t datagram[]; +} ndp16_t; + +typedef union TU_ATTR_PACKED { + struct { + nth16_t nth; + ndp16_t ndp; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; +} transmit_ntb_t; + +struct ecm_notify_struct +{ + tusb_control_request_t header; + uint32_t downlink, uplink; +}; + +typedef struct +{ + uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface + uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active + + uint8_t ep_notif; + uint8_t ep_in; + uint8_t ep_out; + + const ndp16_t *ndp; + uint8_t num_datagrams, current_datagram_index; + + enum { + REPORT_SPEED, + REPORT_CONNECTED, + REPORT_DONE + } report_state; + bool report_pending; + + uint8_t current_ntb; // Index in transmit_ntb[] that is currently being filled with datagrams + uint8_t datagram_count; // Number of datagrams in transmit_ntb[current_ntb] + uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram + uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE + uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + + uint16_t nth_sequence; // Sequence number counter for transmitted NTBs + + bool transferring; + +} ncm_interface_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static const ntb_parameters_t ntb_parameters = { + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01, + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, + .wNdbInDivisor = 4, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 4, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 0 +}; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static transmit_ntb_t transmit_ntb[2]; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; + +static ncm_interface_t ncm_interface; + +/* + * Set up the NTB state in ncm_interface to be ready to add datagrams. + */ +static void ncm_prepare_for_tx(void) { + ncm_interface.datagram_count = 0; + // datagrams start after all the headers + ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) + + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); +} + +/* + * If not already transmitting, start sending the current NTB to the host and swap buffers + * to start filling the other one with datagrams. + */ +static void ncm_start_tx(void) { + if (ncm_interface.transferring) { + return; + } + + transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + size_t ntb_length = ncm_interface.next_datagram_offset; + + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(nth16_t); + ntb->nth.wSequence = ncm_interface.nth_sequence++; + ntb->nth.wBlockLength = ntb_length; + ntb->nth.wNdpIndex = sizeof(nth16_t); + + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ndp16_t) + (ncm_interface.datagram_count + 1) * sizeof(ndp16_datagram_t); + ntb->ndp.wNextNdpIndex = 0; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = 0; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; + + // Kick off an endpoint transfer + usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_in, ntb->data, ntb_length); + ncm_interface.transferring = true; + + // Swap to the other NTB and clear it out + ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; + ncm_prepare_for_tx(); +} + +static struct ecm_notify_struct ncm_notify_connected = +{ + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_NETWORK_CONNECTION, + .wValue = 1 /* Connected */, + .wLength = 0, + }, +}; + +static struct ecm_notify_struct ncm_notify_speed_change = +{ + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, + .wLength = 8, + }, + .downlink = 10000000, + .uplink = 10000000, +}; + +void tud_network_recv_renew(void) +{ + if (!ncm_interface.num_datagrams) + { + usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); + return; + } + + const ndp16_t *ndp = ncm_interface.ndp; + const int i = ncm_interface.current_datagram_index; + ncm_interface.current_datagram_index++; + ncm_interface.num_datagrams--; + + tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ + +void netd_init(void) +{ + tu_memclr(&ncm_interface, sizeof(ncm_interface)); + ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; + ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; + ncm_prepare_for_tx(); +} + +void netd_reset(uint8_t rhport) +{ + (void) rhport; + + netd_init(); +} + +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + // confirm interface hasn't already been allocated + TU_ASSERT(0 == ncm_interface.ep_notif, 0); + + //------------- Management Interface -------------// + ncm_interface.itf_num = itf_desc->bInterfaceNumber; + + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const * p_desc = tu_desc_next( itf_desc ); + + // Communication Functional Descriptors + while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) + { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // notification endpoint (if any) + if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) + { + TU_ASSERT( usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0 ); + + ncm_interface.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + //------------- Data Interface -------------// + // - CDC-NCM data interface has 2 alternate settings + // - 0 : zero endpoints for inactive (default) + // - 1 : IN & OUT endpoints for transfer of NTBs + TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); + + do + { + tusb_desc_interface_t const * data_itf_desc = (tusb_desc_interface_t const *) p_desc; + TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } while((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len)); + + // Pair of endpoints + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); + + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in) ); + + drv_len += 2*sizeof(tusb_desc_endpoint_t); + + return drv_len; +} + +static void ncm_report(void) +{ + if (ncm_interface.report_state == REPORT_SPEED) { + ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); + ncm_interface.report_state = REPORT_CONNECTED; + ncm_interface.report_pending = true; + } else if (ncm_interface.report_state == REPORT_CONNECTED) { + ncm_notify_connected.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); + ncm_interface.report_state = REPORT_DONE; + ncm_interface.report_pending = true; + } +} + +TU_ATTR_WEAK void tud_network_link_state_cb(bool state) +{ + (void)state; +} + +// Handle class control request +// return false to stall control endpoint (e.g unsupported request) +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + if ( stage != CONTROL_STAGE_SETUP ) return true; + + switch ( request->bmRequestType_bit.type ) + { + case TUSB_REQ_TYPE_STANDARD: + switch ( request->bRequest ) + { + case TUSB_REQ_GET_INTERFACE: + { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); + + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + } + break; + + case TUSB_REQ_SET_INTERFACE: + { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + uint8_t const req_alt = (uint8_t) request->wValue; + + // Only valid for Data Interface with Alternate is either 0 or 1 + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); + + if (req_alt != ncm_interface.itf_data_alt) { + ncm_interface.itf_data_alt = req_alt; + + if (ncm_interface.itf_data_alt) { + if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { + tud_network_recv_renew(); // prepare for incoming datagrams + } + if (!ncm_interface.report_pending) { + ncm_report(); + } + } + + tud_network_link_state_cb(ncm_interface.itf_data_alt); + } + + tud_control_status(rhport, request); + } + break; + + // unsupported request + default: return false; + } + break; + + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY (ncm_interface.itf_num == request->wIndex); + + if (NCM_GET_NTB_PARAMETERS == request->bRequest) + { + tud_control_xfer(rhport, request, (void*)&ntb_parameters, sizeof(ntb_parameters)); + } + + break; + + // unsupported request + default: return false; + } + + return true; +} + +static void handle_incoming_datagram(uint32_t len) +{ + uint32_t size = len; + + if (len == 0) { + return; + } + + TU_ASSERT(size >= sizeof(nth16_t), ); + + const nth16_t *hdr = (const nth16_t *)receive_ntb; + TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE, ); + TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len, ); + + const ndp16_t *ndp = (const ndp16_t *)(receive_ntb + hdr->wNdpIndex); + TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1, ); + TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len, ); + + int num_datagrams = (ndp->wLength - 12) / 4; + ncm_interface.current_datagram_index = 0; + ncm_interface.num_datagrams = 0; + ncm_interface.ndp = ndp; + for (int i = 0; i < num_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) + { + ncm_interface.num_datagrams++; + } + + tud_network_recv_renew(); +} + +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) rhport; + (void) result; + + /* new datagram receive_ntb */ + if (ep_addr == ncm_interface.ep_out ) + { + handle_incoming_datagram(xferred_bytes); + } + + /* data transmission finished */ + if (ep_addr == ncm_interface.ep_in ) + { + if (ncm_interface.transferring) { + ncm_interface.transferring = false; + } + + // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now + if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { + ncm_start_tx(); + } + } + + if (ep_addr == ncm_interface.ep_notif ) + { + ncm_interface.report_pending = false; + ncm_report(); + } + + return true; +} + +// poll network driver for its ability to accept another packet to transmit +bool tud_network_can_xmit(uint16_t size) +{ + TU_VERIFY(ncm_interface.itf_data_alt == 1); + + if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { + TU_LOG2("NTB full [by count]\r\n"); + return false; + } + + size_t next_datagram_offset = ncm_interface.next_datagram_offset; + if (next_datagram_offset + size > ncm_interface.ntb_in_size) { + TU_LOG2("ntb full [by size]\r\n"); + return false; + } + + return true; +} + +void tud_network_xmit(void *ref, uint16_t arg) +{ + transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + size_t next_datagram_offset = ncm_interface.next_datagram_offset; + + uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); + + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; + + ncm_interface.datagram_count++; + next_datagram_offset += size; + + // round up so the next datagram is aligned correctly + next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); + next_datagram_offset -= (next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); + + ncm_interface.next_datagram_offset = next_datagram_offset; + + ncm_start_tx(); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/net/net_device.h b/circuitpython/lib/tinyusb/src/class/net/net_device.h new file mode 100644 index 0000000..6e29446 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/net/net_device.h @@ -0,0 +1,118 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Peter Lawrence + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_NET_DEVICE_H_ +#define _TUSB_NET_DEVICE_H_ + +#include "class/cdc/cdc.h" + +#if CFG_TUD_ECM_RNDIS && CFG_TUD_NCM +#error "Cannot enable both ECM_RNDIS and NCM network drivers" +#endif + +#include "ncm.h" + +/* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ +#define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +/* Maximum Transmission Unit (in bytes) of the network, including Ethernet header */ +#ifndef CFG_TUD_NET_MTU +#define CFG_TUD_NET_MTU 1514 +#endif + +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE +#define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE +#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB +#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 +#endif + +#ifndef CFG_TUD_NCM_ALIGNMENT +#define CFG_TUD_NCM_ALIGNMENT 4 +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + +// indicate to network driver that client has finished with the packet provided to network_recv_cb() +void tud_network_recv_renew(void); + +// poll network driver for its ability to accept another packet to transmit +bool tud_network_can_xmit(uint16_t size); + +// if network_can_xmit() returns true, network_xmit() can be called once +void tud_network_xmit(void *ref, uint16_t arg); + +//--------------------------------------------------------------------+ +// Application Callbacks (WEAK is optional) +//--------------------------------------------------------------------+ + +// client must provide this: return false if the packet buffer was not accepted +bool tud_network_recv_cb(const uint8_t *src, uint16_t size); + +// client must provide this: copy from network stack packet pointer to dst +uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); + +//------------- ECM/RNDIS -------------// + +// client must provide this: initialize any network state back to the beginning +void tud_network_init_cb(void); + +// client must provide this: 48-bit MAC address +// TODO removed later since it is not part of tinyusb stack +extern const uint8_t tud_network_mac_address[6]; + +//------------- NCM -------------// + +// callback to client providing optional indication of internal state of network driver +void tud_network_link_state_cb(bool state); + +//--------------------------------------------------------------------+ +// INTERNAL USBD-CLASS DRIVER API +//--------------------------------------------------------------------+ +void netd_init (void); +void netd_reset (uint8_t rhport); +uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool netd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void netd_report (uint8_t *buf, uint16_t len); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_NET_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc.h b/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc.h new file mode 100644 index 0000000..7d7005c --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc.h @@ -0,0 +1,316 @@ + +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 N Conrad + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_USBTMC_H__ +#define _TUSB_USBTMC_H__ + +#include "common/tusb_common.h" + + +/* Implements USBTMC Revision 1.0, April 14, 2003 + + String descriptors must have a "LANGID=0x409"/US English string. + Characters must be 0x20 (' ') to 0x7E ('~') ASCII, + But MUST not contain: "/:?\* + Also must not have leading or trailing space (' ') + Device descriptor must state USB version 0x0200 or greater + + If USB488DeviceCapabilites.D2 = 1 (SR1), then there must be a INT endpoint. +*/ + +#define USBTMC_VERSION 0x0100 +#define USBTMC_488_VERSION 0x0100 + +typedef enum { + USBTMC_MSGID_DEV_DEP_MSG_OUT = 1u, + USBTMC_MSGID_DEV_DEP_MSG_IN = 2u, + USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT = 126u, + USBTMC_MSGID_VENDOR_SPECIFIC_IN = 127u, + USBTMC_MSGID_USB488_TRIGGER = 128u, +} usbtmc_msgid_enum; + +/// \brief Message header (For BULK OUT and BULK IN); 4 bytes +typedef struct TU_ATTR_PACKED +{ + uint8_t MsgID ; ///< Message type ID (usbtmc_msgid_enum) + uint8_t bTag ; ///< Transfer ID 1<=bTag<=255 + uint8_t bTagInverse ; ///< Complement of the tag + uint8_t _reserved ; ///< Must be 0x00 +} usbtmc_msg_header_t; + +typedef struct TU_ATTR_PACKED +{ + usbtmc_msg_header_t header; + uint8_t data[8]; +} usbtmc_msg_generic_t; + +/* Uses on the bulk-out endpoint: */ +// Next 8 bytes are message-specific +typedef struct TU_ATTR_PACKED { + usbtmc_msg_header_t header ; ///< Header + uint32_t TransferSize ; ///< Transfer size; LSB first + struct TU_ATTR_PACKED + { + unsigned int EOM : 1 ; ///< EOM set on last byte + } bmTransferAttributes; + uint8_t _reserved[3]; +} usbtmc_msg_request_dev_dep_out; + +TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_out) == 12u, "struct wrong length"); + +// Next 8 bytes are message-specific +typedef struct TU_ATTR_PACKED +{ + usbtmc_msg_header_t header ; ///< Header + uint32_t TransferSize ; ///< Transfer size; LSB first + struct TU_ATTR_PACKED + { + unsigned int TermCharEnabled : 1 ; ///< "The Bulk-IN transfer must terminate on the specified TermChar."; CAPABILITIES must list TermChar + } bmTransferAttributes; + uint8_t TermChar; + uint8_t _reserved[2]; +} usbtmc_msg_request_dev_dep_in; + +TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_in) == 12u, "struct wrong length"); + +/* Bulk-in headers */ + +typedef struct TU_ATTR_PACKED +{ + usbtmc_msg_header_t header; + uint32_t TransferSize; + struct TU_ATTR_PACKED + { + uint8_t EOM: 1; ///< Last byte of transfer is the end of the message + uint8_t UsingTermChar: 1; ///< Support TermChar && Request.TermCharEnabled && last char in transfer is TermChar + } bmTransferAttributes; + uint8_t _reserved[3]; +} usbtmc_msg_dev_dep_msg_in_header_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_msg_dev_dep_msg_in_header_t) == 12u, "struct wrong length"); + +/* Unsupported vendor things.... Are these ever used?*/ + +typedef struct TU_ATTR_PACKED +{ + usbtmc_msg_header_t header ; ///< Header + uint32_t TransferSize ; ///< Transfer size; LSB first + uint8_t _reserved[4]; +} usbtmc_msg_request_vendor_specific_out; + + +TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_out) == 12u, "struct wrong length"); + +typedef struct TU_ATTR_PACKED +{ + usbtmc_msg_header_t header ; ///< Header + uint32_t TransferSize ; ///< Transfer size; LSB first + uint8_t _reserved[4]; +} usbtmc_msg_request_vendor_specific_in; + +TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_in) == 12u, "struct wrong length"); + +// Control request type should use tusb_control_request_t + +/* +typedef struct TU_ATTR_PACKED { + struct { + unsigned int Recipient : 5 ; ///< EOM set on last byte + unsigned int Type : 2 ; ///< EOM set on last byte + unsigned int DirectionToHost : 1 ; ///< 0 is OUT, 1 is IN + } bmRequestType; + uint8_t bRequest ; ///< If bmRequestType.Type = Class, see usmtmc_request_type_enum + uint16_t wValue ; + uint16_t wIndex ; + uint16_t wLength ; // Number of bytes in data stage +} usbtmc_class_specific_control_req; + +*/ +// bulk-in protocol errors +enum { + USBTMC_BULK_IN_ERR_INCOMPLETE_HEADER = 1u, + USBTMC_BULK_IN_ERR_UNSUPPORTED = 2u, + USBTMC_BULK_IN_ERR_BAD_PARAMETER = 3u, + USBTMC_BULK_IN_ERR_DATA_TOO_SHORT = 4u, + USBTMC_BULK_IN_ERR_DATA_TOO_LONG = 5u, +}; +// bult-in halt errors +enum { + USBTMC_BULK_IN_ERR = 1u, ///< receives a USBTMC command message that expects a response while a + /// Bulk-IN transfer is in progress +}; + +typedef enum { + USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT = 1u, + USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS = 2u, + USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN = 3u, + USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS = 4u, + USBTMC_bREQUEST_INITIATE_CLEAR = 5u, + USBTMC_bREQUEST_CHECK_CLEAR_STATUS = 6u, + USBTMC_bREQUEST_GET_CAPABILITIES = 7u, + + USBTMC_bREQUEST_INDICATOR_PULSE = 64u, // Optional + + /****** USBTMC 488 *************/ + USB488_bREQUEST_READ_STATUS_BYTE = 128u, + USB488_bREQUEST_REN_CONTROL = 160u, + USB488_bREQUEST_GO_TO_LOCAL = 161u, + USB488_bREQUEST_LOCAL_LOCKOUT = 162u, + +} usmtmc_request_type_enum; + +typedef enum { + USBTMC_STATUS_SUCCESS = 0x01, + USBTMC_STATUS_PENDING = 0x02, + USBTMC_STATUS_FAILED = 0x80, + USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS = 0x81, + USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS = 0x82, + USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83 +} usbtmc_status_enum; + +/************************************************************ + * Control Responses + */ + +typedef struct TU_ATTR_PACKED { + uint8_t USBTMC_status; ///< usbtmc_status_enum + uint8_t _reserved; + uint16_t bcdUSBTMC; ///< USBTMC_VERSION + + struct TU_ATTR_PACKED + { + unsigned int listenOnly :1; + unsigned int talkOnly :1; + unsigned int supportsIndicatorPulse :1; + } bmIntfcCapabilities; + struct TU_ATTR_PACKED + { + unsigned int canEndBulkInOnTermChar :1; + } bmDevCapabilities; + uint8_t _reserved2[6]; + uint8_t _reserved3[12]; +} usbtmc_response_capabilities_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_t) == 0x18, "struct wrong length"); + +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; + struct TU_ATTR_PACKED + { + unsigned int BulkInFifoBytes :1; + } bmClear; +} usbtmc_get_clear_status_rsp_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); + +// Used for both abort bulk IN and bulk OUT +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; + uint8_t bTag; +} usbtmc_initiate_abort_rsp_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); + +// Used for both check_abort_bulk_in_status and check_abort_bulk_out_status +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; + struct TU_ATTR_PACKED + { + unsigned int BulkInFifoBytes : 1; ///< Has queued data or a short packet that is queued + } bmAbortBulkIn; + uint8_t _reserved[2]; ///< Must be zero + uint32_t NBYTES_RXD_TXD; +} usbtmc_check_abort_bulk_rsp_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_check_abort_bulk_rsp_t) == 8u, "struct wrong length"); + +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; ///< usbtmc_status_enum + uint8_t _reserved; + uint16_t bcdUSBTMC; ///< USBTMC_VERSION + + struct TU_ATTR_PACKED + { + unsigned int listenOnly :1; + unsigned int talkOnly :1; + unsigned int supportsIndicatorPulse :1; + } bmIntfcCapabilities; + + struct TU_ATTR_PACKED + { + unsigned int canEndBulkInOnTermChar :1; + } bmDevCapabilities; + + uint8_t _reserved2[6]; + uint16_t bcdUSB488; + + struct TU_ATTR_PACKED + { + unsigned int is488_2 :1; + unsigned int supportsREN_GTL_LLO :1; + unsigned int supportsTrigger :1; + } bmIntfcCapabilities488; + + struct TU_ATTR_PACKED + { + unsigned int SCPI :1; + unsigned int SR1 :1; + unsigned int RL1 :1; + unsigned int DT1 :1; + } bmDevCapabilities488; + uint8_t _reserved3[8]; +} usbtmc_response_capabilities_488_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_488_t) == 0x18, "struct wrong length"); + +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; + uint8_t bTag; + uint8_t statusByte; +} usbtmc_read_stb_rsp_488_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length"); + +typedef struct TU_ATTR_PACKED +{ + struct TU_ATTR_PACKED + { + unsigned int bTag : 7; + unsigned int one : 1; + } bNotify1; + uint8_t StatusByte; +} usbtmc_read_stb_interrupt_488_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_interrupt_488_t) == 2u, "struct wrong length"); + +#endif + diff --git a/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc_device.c b/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc_device.c new file mode 100644 index 0000000..b02b075 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc_device.c @@ -0,0 +1,858 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Nathan Conrad + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* + * This library is not fully reentrant, though it is reentrant from the view + * of either the application layer or the USB stack. Due to its locking, + * it is not safe to call its functions from interrupts. + * + * The one exception is that its functions may not be called from the application + * until the USB stack is initialized. This should not be a problem since the + * device shouldn't be sending messages until it receives a request from the + * host. + */ + + +/* + * In the case of single-CPU "no OS", this task is never preempted other than by + * interrupts, and the USBTMC code isn't called by interrupts, so all is OK. For "no OS", + * the mutex structure's main effect is to disable the USB interrupts. + * With an OS, this class driver uses the OSAL to perform locking. The code uses a single lock + * and does not call outside of this class with a lock held, so deadlocks won't happen. + */ + +//Limitations: +// "vendor-specific" commands are not handled. +// Dealing with "termchar" must be handled by the application layer, +// though additional error checking is does in this module. +// talkOnly and listenOnly are NOT supported. They're not permitted +// in USB488, anyway. + +/* Supported: + * + * Notification pulse + * Trigger + * Read status byte (both by interrupt endpoint and control message) + * + */ + + +// TODO: +// USBTMC 3.2.2 error conditions not strictly followed +// No local lock-out, REN, or GTL. +// Clear message available status byte at the correct time? (488 4.3.1.3) + + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_USBTMC) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "usbtmc_device.h" + +#ifdef xDEBUG +#include "uart_util.h" +static char logMsg[150]; +#endif + +/* + * The state machine does not allow simultaneous reading and writing. This is + * consistent with USBTMC. + */ + +typedef enum +{ + STATE_CLOSED, // Endpoints have not yet been opened since USB reset + STATE_NAK, // Bulk-out endpoint is in NAK state. + STATE_IDLE, // Bulk-out endpoint is waiting for CMD. + STATE_RCV, // Bulk-out is receiving DEV_DEP message + STATE_TX_REQUESTED, + STATE_TX_INITIATED, + STATE_TX_SHORTED, + STATE_CLEARING, + STATE_ABORTING_BULK_IN, + STATE_ABORTING_BULK_IN_SHORTED, // aborting, and short packet has been queued for transmission + STATE_ABORTING_BULK_IN_ABORTED, // aborting, and short packet has been transmitted + STATE_ABORTING_BULK_OUT, + STATE_NUM_STATES +} usbtmcd_state_enum; + +#if (CFG_TUD_USBTMC_ENABLE_488) + typedef usbtmc_response_capabilities_488_t usbtmc_capabilities_specific_t; +#else + typedef usbtmc_response_capabilities_t usbtmc_capabilities_specific_t; +#endif + + +typedef struct +{ + volatile usbtmcd_state_enum state; + + uint8_t itf_id; + uint8_t rhport; + uint8_t ep_bulk_in; + uint8_t ep_bulk_out; + uint8_t ep_int_in; + // IN buffer is only used for first packet, not the remainder + // in order to deal with prepending header + CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_MAX_PACKET_SIZE]; + // OUT buffer receives one packet at a time + CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_MAX_PACKET_SIZE]; + uint32_t transfer_size_remaining; // also used for requested length for bulk IN. + uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes) + + uint8_t lastBulkOutTag; // used for aborts (mostly) + uint8_t lastBulkInTag; // used for aborts (mostly) + + uint8_t const * devInBuffer; // pointer to application-layer used for transmissions + + usbtmc_capabilities_specific_t const * capabilities; +} usbtmc_interface_state_t; + +CFG_TUSB_MEM_SECTION static usbtmc_interface_state_t usbtmc_state = +{ + .itf_id = 0xFF, +}; + +// We need all headers to fit in a single packet in this implementation. +TU_VERIFY_STATIC(USBTMCD_MAX_PACKET_SIZE >= 32u,"USBTMC dev EP packet size too small"); +TU_VERIFY_STATIC( + (sizeof(usbtmc_state.ep_bulk_in_buf) % USBTMCD_MAX_PACKET_SIZE) == 0, + "packet buffer must be a multiple of the packet size"); + +static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len); +static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen); + +static uint8_t termChar; +static uint8_t termCharRequested = false; + + +osal_mutex_def_t usbtmcLockBuffer; +static osal_mutex_t usbtmcLock; + +// Our own private lock, mostly for the state variable. +#define criticalEnter() do {osal_mutex_lock(usbtmcLock,OSAL_TIMEOUT_WAIT_FOREVER); } while (0) +#define criticalLeave() do {osal_mutex_unlock(usbtmcLock); } while (0) + +bool atomicChangeState(usbtmcd_state_enum expectedState, usbtmcd_state_enum newState) +{ + bool ret = true; + criticalEnter(); + usbtmcd_state_enum oldState = usbtmc_state.state; + if (oldState == expectedState) + { + usbtmc_state.state = newState; + } + else + { + ret = false; + } + criticalLeave(); + return ret; +} + +// called from app +// We keep a reference to the buffer, so it MUST not change until the app is +// notified that the transfer is complete. +// length of data is specified in the hdr. + +// We can't just send the whole thing at once because we need to concatanate the +// header with the data. +bool tud_usbtmc_transmit_dev_msg_data( + const void * data, size_t len, + bool endOfMessage, + bool usingTermChar) +{ + const unsigned int txBufLen = sizeof(usbtmc_state.ep_bulk_in_buf); + +#ifndef NDEBUG + TU_ASSERT(len > 0u); + TU_ASSERT(len <= usbtmc_state.transfer_size_remaining); + TU_ASSERT(usbtmc_state.transfer_size_sent == 0u); + if(usingTermChar) + { + TU_ASSERT(usbtmc_state.capabilities->bmDevCapabilities.canEndBulkInOnTermChar); + TU_ASSERT(termCharRequested); + TU_ASSERT(((uint8_t const*)data)[len-1u] == termChar); + } +#endif + + TU_VERIFY(usbtmc_state.state == STATE_TX_REQUESTED); + usbtmc_msg_dev_dep_msg_in_header_t *hdr = (usbtmc_msg_dev_dep_msg_in_header_t*)usbtmc_state.ep_bulk_in_buf; + tu_varclr(hdr); + hdr->header.MsgID = USBTMC_MSGID_DEV_DEP_MSG_IN; + hdr->header.bTag = usbtmc_state.lastBulkInTag; + hdr->header.bTagInverse = (uint8_t)~(usbtmc_state.lastBulkInTag); + hdr->TransferSize = len; + hdr->bmTransferAttributes.EOM = endOfMessage; + hdr->bmTransferAttributes.UsingTermChar = usingTermChar; + + // Copy in the header + const size_t headerLen = sizeof(*hdr); + const size_t dataLen = ((headerLen + hdr->TransferSize) <= txBufLen) ? + len : (txBufLen - headerLen); + const size_t packetLen = headerLen + dataLen; + + memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + headerLen, data, dataLen); + usbtmc_state.transfer_size_remaining = len - dataLen; + usbtmc_state.transfer_size_sent = dataLen; + usbtmc_state.devInBuffer = (uint8_t const*) data + (dataLen); + + bool stateChanged = + atomicChangeState(STATE_TX_REQUESTED, (packetLen >= txBufLen) ? STATE_TX_INITIATED : STATE_TX_SHORTED); + TU_VERIFY(stateChanged); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen)); + return true; +} + +void usbtmcd_init_cb(void) +{ + usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); +#ifndef NDEBUG +# if CFG_TUD_USBTMC_ENABLE_488 + if (usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) { + TU_ASSERT(&tud_usbtmc_msg_trigger_cb != NULL,); + } + // Per USB488 spec: table 8 + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); +# endif + if (usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) { + TU_ASSERT(&tud_usbtmc_indicator_pulse_cb != NULL,); + } +#endif + + usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); +} + +uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + (void)rhport; + + uint16_t drv_len; + uint8_t const * p_desc; + uint8_t found_endpoints = 0; + + TU_VERIFY(itf_desc->bInterfaceClass == TUD_USBTMC_APP_CLASS , 0); + TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_USBTMC_APP_SUBCLASS, 0); + +#ifndef NDEBUG + // Only 2 or 3 endpoints are allowed for USBTMC. + TU_ASSERT((itf_desc->bNumEndpoints == 2) || (itf_desc->bNumEndpoints ==3), 0); +#endif + + TU_ASSERT(usbtmc_state.state == STATE_CLOSED, 0); + + // Interface + drv_len = 0u; + p_desc = (uint8_t const *) itf_desc; + + usbtmc_state.itf_id = itf_desc->bInterfaceNumber; + usbtmc_state.rhport = rhport; + + while (found_endpoints < itf_desc->bNumEndpoints && drv_len <= max_len) + { + if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE]) + { + tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *)p_desc; + switch(ep_desc->bmAttributes.xfer) { + case TUSB_XFER_BULK: + TU_ASSERT(tu_edpt_packet_size(ep_desc) == USBTMCD_MAX_PACKET_SIZE, 0); + if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) + { + usbtmc_state.ep_bulk_in = ep_desc->bEndpointAddress; + } else { + usbtmc_state.ep_bulk_out = ep_desc->bEndpointAddress; + } + + break; + case TUSB_XFER_INTERRUPT: +#ifndef NDEBUG + TU_ASSERT(tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN, 0); + TU_ASSERT(usbtmc_state.ep_int_in == 0, 0); +#endif + usbtmc_state.ep_int_in = ep_desc->bEndpointAddress; + break; + default: + TU_ASSERT(false, 0); + } + TU_ASSERT( usbd_edpt_open(rhport, ep_desc), 0); + found_endpoints++; + } + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // bulk endpoints are required, but interrupt IN is optional +#ifndef NDEBUG + TU_ASSERT(usbtmc_state.ep_bulk_in != 0, 0); + TU_ASSERT(usbtmc_state.ep_bulk_out != 0, 0); + if (itf_desc->bNumEndpoints == 2) + { + TU_ASSERT(usbtmc_state.ep_int_in == 0, 0); + } + else if (itf_desc->bNumEndpoints == 3) + { + TU_ASSERT(usbtmc_state.ep_int_in != 0, 0); + } +#if (CFG_TUD_USBTMC_ENABLE_488) + if(usbtmc_state.capabilities->bmIntfcCapabilities488.is488_2 || + usbtmc_state.capabilities->bmDevCapabilities488.SR1) + { + TU_ASSERT(usbtmc_state.ep_int_in != 0, 0); + } +#endif +#endif + atomicChangeState(STATE_CLOSED, STATE_NAK); + tud_usbtmc_open_cb(itf_desc->iInterface); + + return drv_len; +} +// Tell USBTMC class to set its bulk-in EP to ACK so that it can +// receive USBTMC commands. +// Returns false if it was already in an ACK state or is busy +// processing a command (such as a clear). Returns true if it was +// in the NAK state and successfully transitioned to the ACK wait +// state. +bool tud_usbtmc_start_bus_read() +{ + usbtmcd_state_enum oldState = usbtmc_state.state; + switch(oldState) + { + // These may transition to IDLE + case STATE_NAK: + case STATE_ABORTING_BULK_IN_ABORTED: + TU_VERIFY(atomicChangeState(oldState, STATE_IDLE)); + break; + // When receiving, let it remain receiving + case STATE_RCV: + break; + default: + TU_VERIFY(false); + } + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + return true; +} + +void usbtmcd_reset_cb(uint8_t rhport) +{ + (void)rhport; + usbtmc_capabilities_specific_t const * capabilities = tud_usbtmc_get_capabilities_cb(); + + criticalEnter(); + tu_varclr(&usbtmc_state); + usbtmc_state.capabilities = capabilities; + usbtmc_state.itf_id = 0xFFu; + criticalLeave(); +} + +static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) +{ + (void)rhport; + // return true upon failure, as we can assume error is being handled elsewhere. + TU_VERIFY(atomicChangeState(STATE_IDLE, STATE_RCV), true); + usbtmc_state.transfer_size_sent = 0u; + + // must be a header, should have been confirmed before calling here. + usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; + usbtmc_state.transfer_size_remaining = msg->TransferSize; + TU_VERIFY(tud_usbtmc_msgBulkOut_start_cb(msg)); + + TU_VERIFY(handle_devMsgOut(rhport, (uint8_t*)data + sizeof(*msg), len - sizeof(*msg), len)); + usbtmc_state.lastBulkOutTag = msg->header.bTag; + return true; +} + +static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen) +{ + (void)rhport; + // return true upon failure, as we can assume error is being handled elsewhere. + TU_VERIFY(usbtmc_state.state == STATE_RCV,true); + + bool shortPacket = (packetLen < USBTMCD_MAX_PACKET_SIZE); + + // Packet is to be considered complete when we get enough data or at a short packet. + bool atEnd = false; + if(len >= usbtmc_state.transfer_size_remaining || shortPacket) + { + atEnd = true; + TU_VERIFY(atomicChangeState(STATE_RCV, STATE_NAK)); + } + + len = tu_min32(len, usbtmc_state.transfer_size_remaining); + + usbtmc_state.transfer_size_remaining -= len; + usbtmc_state.transfer_size_sent += len; + + // App may (should?) call the wait_for_bus() command at this point + if(!tud_usbtmc_msg_data_cb(data, len, atEnd)) + { + // TODO: Go to an error state upon failure other than just stalling the EP? + return false; + } + + + return true; +} + +static bool handle_devMsgIn(void *data, size_t len) +{ + TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); + usbtmc_msg_request_dev_dep_in *msg = (usbtmc_msg_request_dev_dep_in*)data; + bool stateChanged = atomicChangeState(STATE_IDLE, STATE_TX_REQUESTED); + TU_VERIFY(stateChanged); + usbtmc_state.lastBulkInTag = msg->header.bTag; + usbtmc_state.transfer_size_remaining = msg->TransferSize; + usbtmc_state.transfer_size_sent = 0u; + + termCharRequested = msg->bmTransferAttributes.TermCharEnabled; + termChar = msg->TermChar; + + if(termCharRequested) + TU_VERIFY(usbtmc_state.capabilities->bmDevCapabilities.canEndBulkInOnTermChar); + + TU_VERIFY(tud_usbtmc_msgBulkIn_request_cb(msg)); + return true; +} + +bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + TU_VERIFY(result == XFER_RESULT_SUCCESS); + //uart_tx_str_sync("TMC XFER CB\r\n"); + if(usbtmc_state.state == STATE_CLEARING) { + return true; /* I think we can ignore everything here */ + } + + if(ep_addr == usbtmc_state.ep_bulk_out) + { + usbtmc_msg_generic_t *msg = NULL; + + switch(usbtmc_state.state) + { + case STATE_IDLE: + TU_VERIFY(xferred_bytes >= sizeof(usbtmc_msg_generic_t)); + msg = (usbtmc_msg_generic_t*)(usbtmc_state.ep_bulk_out_buf); + uint8_t invInvTag = (uint8_t)~(msg->header.bTagInverse); + TU_VERIFY(msg->header.bTag == invInvTag); + TU_VERIFY(msg->header.bTag != 0x00); + + switch(msg->header.MsgID) { + case USBTMC_MSGID_DEV_DEP_MSG_OUT: + if(!handle_devMsgOutStart(rhport, msg, xferred_bytes)) + { + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + TU_VERIFY(false); + } + break; + + case USBTMC_MSGID_DEV_DEP_MSG_IN: + TU_VERIFY(handle_devMsgIn(msg, xferred_bytes)); + break; + +#if (CFG_TUD_USBTMC_ENABLE_488) + case USBTMC_MSGID_USB488_TRIGGER: + // Spec says we halt the EP if we didn't declare we support it. + TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger); + TU_VERIFY(tud_usbtmc_msg_trigger_cb(msg)); + + break; +#endif + case USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT: + case USBTMC_MSGID_VENDOR_SPECIFIC_IN: + default: + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + TU_VERIFY(false); + return false; + } + return true; + + case STATE_RCV: + if(!handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes, xferred_bytes)) + { + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + TU_VERIFY(false); + } + return true; + + case STATE_ABORTING_BULK_OUT: + TU_VERIFY(false); + return false; // Should be stalled by now, shouldn't have received a packet. + + case STATE_TX_REQUESTED: + case STATE_TX_INITIATED: + case STATE_ABORTING_BULK_IN: + case STATE_ABORTING_BULK_IN_SHORTED: + case STATE_ABORTING_BULK_IN_ABORTED: + default: + TU_VERIFY(false); + } + } + else if(ep_addr == usbtmc_state.ep_bulk_in) + { + switch(usbtmc_state.state) { + case STATE_TX_SHORTED: + TU_VERIFY(atomicChangeState(STATE_TX_SHORTED, STATE_NAK)); + TU_VERIFY(tud_usbtmc_msgBulkIn_complete_cb()); + break; + + case STATE_TX_INITIATED: + if(usbtmc_state.transfer_size_remaining >=sizeof(usbtmc_state.ep_bulk_in_buf)) + { + // FIXME! This removes const below! + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, + (void*)(uintptr_t) usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf))); + usbtmc_state.devInBuffer += sizeof(usbtmc_state.ep_bulk_in_buf); + usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.ep_bulk_in_buf); + usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.ep_bulk_in_buf); + } + else // last packet + { + size_t packetLen = usbtmc_state.transfer_size_remaining; + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); + usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.transfer_size_remaining); + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.devInBuffer = NULL; + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen) ); + if(((packetLen % USBTMCD_MAX_PACKET_SIZE) != 0) || (packetLen == 0 )) + { + usbtmc_state.state = STATE_TX_SHORTED; + } + } + return true; + + case STATE_ABORTING_BULK_IN: + // need to send short packet (ZLP?) + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)0u)); + usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; + return true; + + case STATE_ABORTING_BULK_IN_SHORTED: + /* Done. :)*/ + usbtmc_state.state = STATE_ABORTING_BULK_IN_ABORTED; + return true; + + default: + TU_ASSERT(false); + return false; + } + } + else if (ep_addr == usbtmc_state.ep_int_in) { + // Good? + return true; + } + return false; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + // nothing to do with DATA and ACK stage + if ( stage != CONTROL_STAGE_SETUP ) return true; + + uint8_t tmcStatusCode = USBTMC_STATUS_FAILED; +#if (CFG_TUD_USBTMC_ENABLE_488) + uint8_t bTag; +#endif + + if((request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) && + (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_ENDPOINT) && + (request->bRequest == TUSB_REQ_CLEAR_FEATURE) && + (request->wValue == TUSB_REQ_FEATURE_EDPT_HALT)) + { + uint32_t ep_addr = (request->wIndex); + + if(ep_addr == usbtmc_state.ep_bulk_out) + { + criticalEnter(); + usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us + criticalLeave(); + tud_usbtmc_bulkOut_clearFeature_cb(); + } + else if (ep_addr == usbtmc_state.ep_bulk_in) + { + tud_usbtmc_bulkIn_clearFeature_cb(); + } + else + { + return false; + } + return true; + } + + // Otherwise, we only handle class requests. + if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) + { + return false; + } + + // Verification that we own the interface is unneeded since it's been routed to us specifically. + + switch(request->bRequest) + { + // USBTMC required requests + case USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT: + { + usbtmc_initiate_abort_rsp_t rsp = { + .bTag = usbtmc_state.lastBulkOutTag, + }; + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,interface + TU_VERIFY(request->wLength == sizeof(rsp)); + TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); + + // wValue is the requested bTag to abort + if(usbtmc_state.state != STATE_RCV) + { + rsp.USBTMC_status = USBTMC_STATUS_FAILED; + } + else if(usbtmc_state.lastBulkOutTag == (request->wValue & 0x7Fu)) + { + rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; + } + else + { + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + // Check if we've queued a short packet + criticalEnter(); + usbtmc_state.state = STATE_ABORTING_BULK_OUT; + criticalLeave(); + TU_VERIFY(tud_usbtmc_initiate_abort_bulk_out_cb(&(rsp.USBTMC_status))); + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); + return true; + } + + case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: + { + usbtmc_check_abort_bulk_rsp_t rsp = { + .USBTMC_status = USBTMC_STATUS_SUCCESS, + .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent + }; + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP + TU_VERIFY(request->wLength == sizeof(rsp)); + TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); + TU_VERIFY(tud_usbtmc_check_abort_bulk_out_cb(&rsp)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); + return true; + } + + case USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN: + { + usbtmc_initiate_abort_rsp_t rsp = { + .bTag = usbtmc_state.lastBulkInTag, + }; + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,interface + TU_VERIFY(request->wLength == sizeof(rsp)); + TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_in); + // wValue is the requested bTag to abort + if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED) && + usbtmc_state.lastBulkInTag == (request->wValue & 0x7Fu)) + { + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + usbtmc_state.transfer_size_remaining = 0u; + // Check if we've queued a short packet + criticalEnter(); + usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) == 0) ? + STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; + criticalLeave(); + if(usbtmc_state.transfer_size_sent == 0) + { + // Send short packet, nothing is in the buffer yet + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)0u)); + usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; + } + TU_VERIFY(tud_usbtmc_initiate_abort_bulk_in_cb(&(rsp.USBTMC_status))); + } + else if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED)) + { // FIXME: Unsure how to check if the OUT endpoint fifo is non-empty.... + rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; + } + else + { + rsp.USBTMC_status = USBTMC_STATUS_FAILED; + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); + return true; + } + + case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: + { + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP + TU_VERIFY(request->wLength == 8u); + + usbtmc_check_abort_bulk_rsp_t rsp = + { + .USBTMC_status = USBTMC_STATUS_FAILED, + .bmAbortBulkIn = + { + .BulkInFifoBytes = (usbtmc_state.state != STATE_ABORTING_BULK_IN_ABORTED) + }, + .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent, + }; + TU_VERIFY(tud_usbtmc_check_abort_bulk_in_cb(&rsp)); + criticalEnter(); + switch(usbtmc_state.state) + { + case STATE_ABORTING_BULK_IN_ABORTED: + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + usbtmc_state.state = STATE_IDLE; + break; + case STATE_ABORTING_BULK_IN: + case STATE_ABORTING_BULK_OUT: + rsp.USBTMC_status = USBTMC_STATUS_PENDING; + break; + default: + break; + } + criticalLeave(); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); + + return true; + } + + case USBTMC_bREQUEST_INITIATE_CLEAR: + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); + // After receiving an INITIATE_CLEAR request, the device must Halt the Bulk-OUT endpoint, queue the + // control endpoint response shown in Table 31, and clear all input buffers and output buffers. + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + usbtmc_state.transfer_size_remaining = 0; + criticalEnter(); + usbtmc_state.state = STATE_CLEARING; + criticalLeave(); + TU_VERIFY(tud_usbtmc_initiate_clear_cb(&tmcStatusCode)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); + return true; + } + + case USBTMC_bREQUEST_CHECK_CLEAR_STATUS: + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; + TU_VERIFY(request->wLength == sizeof(clearStatusRsp)); + + if(usbd_edpt_busy(rhport, usbtmc_state.ep_bulk_in)) + { + // Stuff stuck in TX buffer? + clearStatusRsp.bmClear.BulkInFifoBytes = 1; + clearStatusRsp.USBTMC_status = USBTMC_STATUS_PENDING; + } + else + { + // Let app check if it's clear + TU_VERIFY(tud_usbtmc_check_clear_cb(&clearStatusRsp)); + } + if(clearStatusRsp.USBTMC_status == USBTMC_STATUS_SUCCESS) + { + criticalEnter(); + usbtmc_state.state = STATE_IDLE; + criticalLeave(); + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&clearStatusRsp,sizeof(clearStatusRsp))); + return true; + } + + case USBTMC_bREQUEST_GET_CAPABILITIES: + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(*(usbtmc_state.capabilities))); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)(uintptr_t) usbtmc_state.capabilities, sizeof(*usbtmc_state.capabilities))); + return true; + } + // USBTMC Optional Requests + + case USBTMC_bREQUEST_INDICATOR_PULSE: // Optional + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); + TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse); + TU_VERIFY(tud_usbtmc_indicator_pulse_cb(request, &tmcStatusCode)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); + return true; + } +#if (CFG_TUD_USBTMC_ENABLE_488) + + // USB488 required requests + case USB488_bREQUEST_READ_STATUS_BYTE: + { + usbtmc_read_stb_rsp_488_t rsp; + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(rsp)); // in,class,interface + + bTag = request->wValue & 0x7F; + TU_VERIFY(request->bmRequestType == 0xA1); + TU_VERIFY((request->wValue & (~0x7F)) == 0u); // Other bits are required to be zero + TU_VERIFY(bTag >= 0x02 && bTag <= 127); + TU_VERIFY(request->wIndex == usbtmc_state.itf_id); + TU_VERIFY(request->wLength == 0x0003); + rsp.bTag = (uint8_t)bTag; + if(usbtmc_state.ep_int_in != 0) + { + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + rsp.statusByte = 0x00; // Use interrupt endpoint, instead. + + usbtmc_read_stb_interrupt_488_t intMsg = + { + .bNotify1 = { + .one = 1, + .bTag = bTag & 0x7Fu, + }, + .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)) + }; + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); + } + else + { + rsp.statusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)); + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp, sizeof(rsp))); + return true; + } + // USB488 optional requests + case USB488_bREQUEST_REN_CONTROL: + case USB488_bREQUEST_GO_TO_LOCAL: + case USB488_bREQUEST_LOCAL_LOCKOUT: + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(false); + return false; + } +#endif + + default: + TU_VERIFY(false); + return false; + } + TU_VERIFY(false); +} + +#endif /* CFG_TUD_TSMC */ diff --git a/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc_device.h b/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc_device.h new file mode 100644 index 0000000..0549a15 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/usbtmc/usbtmc_device.h @@ -0,0 +1,116 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 N Conrad + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef CLASS_USBTMC_USBTMC_DEVICE_H_ +#define CLASS_USBTMC_USBTMC_DEVICE_H_ + +#include "usbtmc.h" + +// Enable 488 mode by default +#if !defined(CFG_TUD_USBTMC_ENABLE_488) +#define CFG_TUD_USBTMC_ENABLE_488 (1) +#endif + +// USB spec says that full-speed must be 8,16,32, or 64. +// However, this driver implementation requires it to be >=32 +#define USBTMCD_MAX_PACKET_SIZE (64u) + +/*********************************************** + * Functions to be implemeted by the class implementation + */ + +// In order to proceed, app must call call tud_usbtmc_start_bus_read(rhport) during or soon after: +// * tud_usbtmc_open_cb +// * tud_usbtmc_msg_data_cb +// * tud_usbtmc_msgBulkIn_complete_cb +// * tud_usbtmc_msg_trigger_cb +// * (successful) tud_usbtmc_check_abort_bulk_out_cb +// * (successful) tud_usbtmc_check_abort_bulk_in_cb +// * (successful) tud_usmtmc_bulkOut_clearFeature_cb + +#if (CFG_TUD_USBTMC_ENABLE_488) +usbtmc_response_capabilities_488_t const * tud_usbtmc_get_capabilities_cb(void); +#else +usbtmc_response_capabilities_t const * tud_usbtmc_get_capabilities_cb(void); +#endif + +void tud_usbtmc_open_cb(uint8_t interface_id); + +bool tud_usbtmc_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader); +// transfer_complete does not imply that a message is complete. +bool tud_usbtmc_msg_data_cb( void *data, size_t len, bool transfer_complete); +void tud_usbtmc_bulkOut_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer + +bool tud_usbtmc_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request); +bool tud_usbtmc_msgBulkIn_complete_cb(void); +void tud_usbtmc_bulkIn_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer + +bool tud_usbtmc_initiate_abort_bulk_in_cb(uint8_t *tmcResult); +bool tud_usbtmc_initiate_abort_bulk_out_cb(uint8_t *tmcResult); +bool tud_usbtmc_initiate_clear_cb(uint8_t *tmcResult); + +bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp); +bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp); +bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); + +// Indicator pulse should be 0.5 to 1.0 seconds long +TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); + +#if (CFG_TUD_USBTMC_ENABLE_488) +uint8_t tud_usbtmc_get_stb_cb(uint8_t *tmcResult); +TU_ATTR_WEAK bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg); +//TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(); +#endif + +/******************************************* + * Called from app + * + * We keep a reference to the buffer, so it MUST not change until the app is + * notified that the transfer is complete. + ******************************************/ + +bool tud_usbtmc_transmit_dev_msg_data( + const void * data, size_t len, + bool endOfMessage, bool usingTermChar); + +bool tud_usbtmc_start_bus_read(void); + + +/* "callbacks" from USB device core */ + +uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +void usbtmcd_reset_cb(uint8_t rhport); +bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +void usbtmcd_init_cb(void); + +/************************************************************ + * USBTMC Descriptor Templates + *************************************************************/ + + +#endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/vendor/vendor_device.c b/circuitpython/lib/tinyusb/src/class/vendor/vendor_device.c new file mode 100644 index 0000000..6e3ceb1 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/vendor/vendor_device.c @@ -0,0 +1,268 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_VENDOR) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "vendor_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef struct +{ + uint8_t itf_num; + uint8_t ep_in; + uint8_t ep_out; + + /*------------- From this point, data is not cleared by bus reset -------------*/ + tu_fifo_t rx_ff; + tu_fifo_t tx_ff; + + uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + +#if CFG_FIFO_MUTEX + osal_mutex_def_t rx_ff_mutex; + osal_mutex_def_t tx_ff_mutex; +#endif + + // Endpoint Transfer buffer + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE]; +} vendord_interface_t; + +CFG_TUSB_MEM_SECTION static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; + +#define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, rx_ff) + + +bool tud_vendor_n_mounted (uint8_t itf) +{ + return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; +} + +uint32_t tud_vendor_n_available (uint8_t itf) +{ + return tu_fifo_count(&_vendord_itf[itf].rx_ff); +} + +bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) +{ + return tu_fifo_peek(&_vendord_itf[itf].rx_ff, u8); +} + +//--------------------------------------------------------------------+ +// Read API +//--------------------------------------------------------------------+ +static void _prep_out_transaction (vendord_interface_t* p_itf) +{ + // skip if previous transfer not complete + if ( usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_out) ) return; + + // Prepare for incoming data but only allow what we can store in the ring buffer. + uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff); + if ( max_read >= CFG_TUD_VENDOR_EPSIZE ) + { + usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); + } +} + +uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) +{ + vendord_interface_t* p_itf = &_vendord_itf[itf]; + uint32_t num_read = tu_fifo_read_n(&p_itf->rx_ff, buffer, bufsize); + _prep_out_transaction(p_itf); + return num_read; +} + +void tud_vendor_n_read_flush (uint8_t itf) +{ + vendord_interface_t* p_itf = &_vendord_itf[itf]; + tu_fifo_clear(&p_itf->rx_ff); + _prep_out_transaction(p_itf); +} + +//--------------------------------------------------------------------+ +// Write API +//--------------------------------------------------------------------+ +static uint16_t maybe_transmit(vendord_interface_t* p_itf) +{ + // skip if previous transfer not complete + TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_in) ); + + uint16_t count = tu_fifo_read_n(&p_itf->tx_ff, p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE); + if (count > 0) + { + TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_in, p_itf->epin_buf, count) ); + } + return count; +} + +uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) +{ + vendord_interface_t* p_itf = &_vendord_itf[itf]; + uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, bufsize); + if (tu_fifo_count(&p_itf->tx_ff) >= CFG_TUD_VENDOR_EPSIZE) { + maybe_transmit(p_itf); + } + return ret; +} + +uint32_t tud_vendor_n_flush (uint8_t itf) +{ + vendord_interface_t* p_itf = &_vendord_itf[itf]; + uint32_t ret = maybe_transmit(p_itf); + + return ret; +} + +uint32_t tud_vendor_n_write_available (uint8_t itf) +{ + return tu_fifo_remaining(&_vendord_itf[itf].tx_ff); +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void vendord_init(void) +{ + tu_memclr(_vendord_itf, sizeof(_vendord_itf)); + + for(uint8_t i=0; irx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false); + tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false); + +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex)); + tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL); +#endif + } +} + +void vendord_reset(uint8_t rhport) +{ + (void) rhport; + + for(uint8_t i=0; irx_ff); + tu_fifo_clear(&p_itf->tx_ff); + } +} + +uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) +{ + TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0); + + uint8_t const * p_desc = tu_desc_next(desc_itf); + uint8_t const * desc_end = p_desc + max_len; + + // Find available interface + vendord_interface_t* p_vendor = NULL; + for(uint8_t i=0; iitf_num = desc_itf->bInterfaceNumber; + if (desc_itf->bNumEndpoints) + { + // skip non-endpoint descriptors + while ( (TUSB_DESC_ENDPOINT != tu_desc_type(p_desc)) && (p_desc < desc_end) ) + { + p_desc = tu_desc_next(p_desc); + } + + // Open endpoint pair with usbd helper + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_BULK, &p_vendor->ep_out, &p_vendor->ep_in), 0); + + p_desc += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + + // Prepare for incoming data + if ( p_vendor->ep_out ) + { + TU_ASSERT(usbd_edpt_xfer(rhport, p_vendor->ep_out, p_vendor->epout_buf, sizeof(p_vendor->epout_buf)), 0); + } + + if ( p_vendor->ep_in ) maybe_transmit(p_vendor); + } + + return (uintptr_t) p_desc - (uintptr_t) desc_itf; +} + +bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) rhport; + (void) result; + + uint8_t itf = 0; + vendord_interface_t* p_itf = _vendord_itf; + + for ( ; ; itf++, p_itf++) + { + if (itf >= TU_ARRAY_SIZE(_vendord_itf)) return false; + + if ( ( ep_addr == p_itf->ep_out ) || ( ep_addr == p_itf->ep_in ) ) break; + } + + if ( ep_addr == p_itf->ep_out ) + { + // Receive new data + tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, xferred_bytes); + + // Invoked callback if any + if (tud_vendor_rx_cb) tud_vendor_rx_cb(itf); + + _prep_out_transaction(p_itf); + } + else if ( ep_addr == p_itf->ep_in ) + { + if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, xferred_bytes); + // Send complete, try to send more if possible + maybe_transmit(p_itf); + } + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/vendor/vendor_device.h b/circuitpython/lib/tinyusb/src/class/vendor/vendor_device.h new file mode 100644 index 0000000..4a873e5 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/vendor/vendor_device.h @@ -0,0 +1,145 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_VENDOR_DEVICE_H_ +#define _TUSB_VENDOR_DEVICE_H_ + +#include "common/tusb_common.h" + +#ifndef CFG_TUD_VENDOR_EPSIZE +#define CFG_TUD_VENDOR_EPSIZE 64 +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application API (Multiple Interfaces) +//--------------------------------------------------------------------+ +bool tud_vendor_n_mounted (uint8_t itf); + +uint32_t tud_vendor_n_available (uint8_t itf); +uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize); +bool tud_vendor_n_peek (uint8_t itf, uint8_t* ui8); +void tud_vendor_n_read_flush (uint8_t itf); + +uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); +uint32_t tud_vendor_n_write_available (uint8_t itf); + +static inline +uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); +uint32_t tud_vendor_n_flush (uint8_t itf); + +//--------------------------------------------------------------------+ +// Application API (Single Port) +//--------------------------------------------------------------------+ +static inline bool tud_vendor_mounted (void); +static inline uint32_t tud_vendor_available (void); +static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize); +static inline bool tud_vendor_peek (uint8_t* ui8); +static inline void tud_vendor_read_flush (void); +static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); +static inline uint32_t tud_vendor_write_str (char const* str); +static inline uint32_t tud_vendor_write_available (void); +static inline uint32_t tud_vendor_flush (void); + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received new data +TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf); +// Invoked when last rx transfer finished +TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); + +//--------------------------------------------------------------------+ +// Inline Functions +//--------------------------------------------------------------------+ + +static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str) +{ + return tud_vendor_n_write(itf, str, strlen(str)); +} + +static inline bool tud_vendor_mounted (void) +{ + return tud_vendor_n_mounted(0); +} + +static inline uint32_t tud_vendor_available (void) +{ + return tud_vendor_n_available(0); +} + +static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize) +{ + return tud_vendor_n_read(0, buffer, bufsize); +} + +static inline bool tud_vendor_peek (uint8_t* ui8) +{ + return tud_vendor_n_peek(0, ui8); +} + +static inline void tud_vendor_read_flush(void) +{ + tud_vendor_n_read_flush(0); +} + +static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize) +{ + return tud_vendor_n_write(0, buffer, bufsize); +} + +static inline uint32_t tud_vendor_write_str (char const* str) +{ + return tud_vendor_n_write_str(0, str); +} + +static inline uint32_t tud_vendor_write_available (void) +{ + return tud_vendor_n_write_available(0); +} + +static inline uint32_t tud_vendor_flush (void) +{ + return tud_vendor_n_flush(0); +} + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void vendord_init(void); +void vendord_reset(uint8_t rhport); +uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_VENDOR_DEVICE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/vendor/vendor_host.c b/circuitpython/lib/tinyusb/src/class/vendor/vendor_host.c new file mode 100644 index 0000000..dbea122 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/vendor/vendor_host.c @@ -0,0 +1,146 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUH_ENABLED && CFG_TUH_VENDOR) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "host/usbh.h" +#include "vendor_host.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +custom_interface_info_t custom_interface[CFG_TUH_DEVICE_MAX]; + +static tusb_error_t cush_validate_paras(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length) +{ + if ( !tusbh_custom_is_mounted(dev_addr, vendor_id, product_id) ) + { + return TUSB_ERROR_DEVICE_NOT_READY; + } + + TU_ASSERT( p_buffer != NULL && length != 0, TUSB_ERROR_INVALID_PARA); + + return TUSB_ERROR_NONE; +} +//--------------------------------------------------------------------+ +// APPLICATION API (need to check parameters) +//--------------------------------------------------------------------+ +tusb_error_t tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length) +{ + TU_ASSERT_ERR( cush_validate_paras(dev_addr, vendor_id, product_id, p_buffer, length) ); + + if ( !hcd_pipe_is_idle(custom_interface[dev_addr-1].pipe_in) ) + { + return TUSB_ERROR_INTERFACE_IS_BUSY; + } + + (void) usbh_edpt_xfer( custom_interface[dev_addr-1].pipe_in, p_buffer, length); + + return TUSB_ERROR_NONE; +} + +tusb_error_t tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length) +{ + TU_ASSERT_ERR( cush_validate_paras(dev_addr, vendor_id, product_id, p_data, length) ); + + if ( !hcd_pipe_is_idle(custom_interface[dev_addr-1].pipe_out) ) + { + return TUSB_ERROR_INTERFACE_IS_BUSY; + } + + (void) usbh_edpt_xfer( custom_interface[dev_addr-1].pipe_out, p_data, length); + + return TUSB_ERROR_NONE; +} + +//--------------------------------------------------------------------+ +// USBH-CLASS API +//--------------------------------------------------------------------+ +void cush_init(void) +{ + tu_memclr(&custom_interface, sizeof(custom_interface_info_t) * CFG_TUH_DEVICE_MAX); +} + +tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) +{ + // FIXME quick hack to test lpc1k custom class with 2 bulk endpoints + uint8_t const *p_desc = (uint8_t const *) p_interface_desc; + p_desc = tu_desc_next(p_desc); + + //------------- Bulk Endpoints Descriptor -------------// + for(uint32_t i=0; i<2; i++) + { + tusb_desc_endpoint_t const *p_endpoint = (tusb_desc_endpoint_t const *) p_desc; + TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType, TUSB_ERROR_INVALID_PARA); + + pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ? + &custom_interface[dev_addr-1].pipe_in : &custom_interface[dev_addr-1].pipe_out; + *p_pipe_hdl = usbh_edpt_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC); + TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED ); + + p_desc = tu_desc_next(p_desc); + } + + (*p_length) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); + return TUSB_ERROR_NONE; +} + +void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event) +{ + +} + +void cush_close(uint8_t dev_addr) +{ + tusb_error_t err1, err2; + custom_interface_info_t * p_interface = &custom_interface[dev_addr-1]; + + // TODO re-consider to check pipe valid before calling pipe_close + if( pipehandle_is_valid( p_interface->pipe_in ) ) + { + err1 = hcd_pipe_close( p_interface->pipe_in ); + } + + if ( pipehandle_is_valid( p_interface->pipe_out ) ) + { + err2 = hcd_pipe_close( p_interface->pipe_out ); + } + + tu_memclr(p_interface, sizeof(custom_interface_info_t)); + + TU_ASSERT(err1 == TUSB_ERROR_NONE && err2 == TUSB_ERROR_NONE, (void) 0 ); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/vendor/vendor_host.h b/circuitpython/lib/tinyusb/src/class/vendor/vendor_host.h new file mode 100644 index 0000000..07fa56c --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/vendor/vendor_host.h @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_VENDOR_HOST_H_ +#define _TUSB_VENDOR_HOST_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct { + pipe_handle_t pipe_in; + pipe_handle_t pipe_out; +}custom_interface_info_t; + +//--------------------------------------------------------------------+ +// USBH-CLASS DRIVER API +//--------------------------------------------------------------------+ +static inline bool tusbh_custom_is_mounted(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id) +{ + (void) vendor_id; // TODO check this later + (void) product_id; +// return (tusbh_device_get_mounted_class_flag(dev_addr) & TU_BIT(TUSB_CLASS_MAPPED_INDEX_END-1) ) != 0; + return false; +} + +tusb_error_t tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length); +tusb_error_t tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void cush_init(void); +tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length); +void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event); +void cush_close(uint8_t dev_addr); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_VENDOR_HOST_H_ */ diff --git a/circuitpython/lib/tinyusb/src/class/video/video.h b/circuitpython/lib/tinyusb/src/class/video/video.h new file mode 100644 index 0000000..8447465 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/video/video.h @@ -0,0 +1,480 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_VIDEO_H_ +#define TUSB_VIDEO_H_ + +#include "common/tusb_common.h" + +// Table 3-19 Color Matching Descriptor +typedef enum { + VIDEO_COLOR_PRIMARIES_UNDEFINED = 0x00, + VIDEO_COLOR_PRIMARIES_BT709, // sRGB (default) + VIDEO_COLOR_PRIMARIES_BT470_2M, + VIDEO_COLOR_PRIMARIES_BT470_2BG, + VIDEO_COLOR_PRIMARIES_SMPTE170M, + VIDEO_COLOR_PRIMARIES_SMPTE240M, +} video_color_primaries_t; + +// Table 3-19 Color Matching Descriptor +typedef enum { + VIDEO_COLOR_XFER_CH_UNDEFINED = 0x00, + VIDEO_COLOR_XFER_CH_BT709, // default + VIDEO_COLOR_XFER_CH_BT470_2M, + VIDEO_COLOR_XFER_CH_BT470_2BG, + VIDEO_COLOR_XFER_CH_SMPTE170M, + VIDEO_COLOR_XFER_CH_SMPTE240M, + VIDEO_COLOR_XFER_CH_LINEAR, + VIDEO_COLOR_XFER_CH_SRGB, +} video_color_transfer_characteristics_t; + +// Table 3-19 Color Matching Descriptor +typedef enum { + VIDEO_COLOR_COEF_UNDEFINED = 0x00, + VIDEO_COLOR_COEF_BT709, + VIDEO_COLOR_COEF_FCC, + VIDEO_COLOR_COEF_BT470_2BG, + VIDEO_COLOR_COEF_SMPTE170M, // BT.601 default + VIDEO_COLOR_COEF_SMPTE240M, +} video_color_matrix_coefficients_t; + +/* 4.2.1.2 Request Error Code Control */ +typedef enum { + VIDEO_ERROR_NONE = 0, /* The request succeeded. */ + VIDEO_ERROR_NOT_READY, + VIDEO_ERROR_WRONG_STATE, + VIDEO_ERROR_POWER, + VIDEO_ERROR_OUT_OF_RANGE, + VIDEO_ERROR_INVALID_UNIT, + VIDEO_ERROR_INVALID_CONTROL, + VIDEO_ERROR_INVALID_REQUEST, + VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE, + VIDEO_ERROR_UNKNOWN = 0xFF, +} video_error_code_t; + +/* A.2 Interface Subclass */ +typedef enum { + VIDEO_SUBCLASS_UNDEFINED = 0x00, + VIDEO_SUBCLASS_CONTROL, + VIDEO_SUBCLASS_STREAMING, + VIDEO_SUBCLASS_INTERFACE_COLLECTION, +} video_subclass_type_t; + +/* A.3 Interface Protocol */ +typedef enum { + VIDEO_ITF_PROTOCOL_UNDEFINED = 0x00, + VIDEO_ITF_PROTOCOL_15, +} video_interface_protocol_code_t; + +/* A.5 Class-Specific VideoControl Interface Descriptor Subtypes */ +typedef enum { + VIDEO_CS_ITF_VC_UNDEFINED = 0x00, + VIDEO_CS_ITF_VC_HEADER, + VIDEO_CS_ITF_VC_INPUT_TERMINAL, + VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + VIDEO_CS_ITF_VC_SELECTOR_UNIT, + VIDEO_CS_ITF_VC_PROCESSING_UNIT, + VIDEO_CS_ITF_VC_EXTENSION_UNIT, + VIDEO_CS_ITF_VC_ENCODING_UNIT, + VIDEO_CS_ITF_VC_MAX, +} video_cs_vc_interface_subtype_t; + +/* A.6 Class-Specific VideoStreaming Interface Descriptor Subtypes */ +typedef enum { + VIDEO_CS_ITF_VS_UNDEFINED = 0x00, + VIDEO_CS_ITF_VS_INPUT_HEADER = 0x01, + VIDEO_CS_ITF_VS_OUTPUT_HEADER = 0x02, + VIDEO_CS_ITF_VS_STILL_IMAGE_FRAME = 0x03, + VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED = 0x04, + VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED = 0x05, + VIDEO_CS_ITF_VS_FORMAT_MJPEG = 0x06, + VIDEO_CS_ITF_VS_FRAME_MJPEG = 0x07, + VIDEO_CS_ITF_VS_FORMAT_MPEG2TS = 0x0A, + VIDEO_CS_ITF_VS_FORMAT_DV = 0x0C, + VIDEO_CS_ITF_VS_COLORFORMAT = 0x0D, + VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED = 0x10, + VIDEO_CS_ITF_VS_FRAME_FRAME_BASED = 0x11, + VIDEO_CS_ITF_VS_FORMAT_STREAM_BASED = 0x12, + VIDEO_CS_ITF_VS_FORMAT_H264 = 0x13, + VIDEO_CS_ITF_VS_FRAME_H264 = 0x14, + VIDEO_CS_ITF_VS_FORMAT_H264_SIMULCAST = 0x15, + VIDEO_CS_ITF_VS_FORMAT_VP8 = 0x16, + VIDEO_CS_ITF_VS_FRAME_VP8 = 0x17, + VIDEO_CS_ITF_VS_FORMAT_VP8_SIMULCAST = 0x18, +} video_cs_vs_interface_subtype_t; + +/* A.7. Class-Specific Endpoint Descriptor Subtypes */ +typedef enum { + VIDEO_CS_EP_UNDEFINED = 0x00, + VIDEO_CS_EP_GENERAL, + VIDEO_CS_EP_ENDPOINT, + VIDEO_CS_EP_INTERRUPT +} video_cs_ep_subtype_t; + +/* A.8 Class-Specific Request Codes */ +typedef enum { + VIDEO_REQUEST_UNDEFINED = 0x00, + VIDEO_REQUEST_SET_CUR = 0x01, + VIDEO_REQUEST_SET_CUR_ALL = 0x11, + VIDEO_REQUEST_GET_CUR = 0x81, + VIDEO_REQUEST_GET_MIN = 0x82, + VIDEO_REQUEST_GET_MAX = 0x83, + VIDEO_REQUEST_GET_RES = 0x84, + VIDEO_REQUEST_GET_LEN = 0x85, + VIDEO_REQUEST_GET_INFO = 0x86, + VIDEO_REQUEST_GET_DEF = 0x87, + VIDEO_REQUEST_GET_CUR_ALL = 0x91, + VIDEO_REQUEST_GET_MIN_ALL = 0x92, + VIDEO_REQUEST_GET_MAX_ALL = 0x93, + VIDEO_REQUEST_GET_RES_ALL = 0x94, + VIDEO_REQUEST_GET_DEF_ALL = 0x97 +} video_control_request_t; + +/* A.9.1 VideoControl Interface Control Selectors */ +typedef enum { + VIDEO_VC_CTL_UNDEFINED = 0x00, + VIDEO_VC_CTL_VIDEO_POWER_MODE, + VIDEO_VC_CTL_REQUEST_ERROR_CODE, +} video_interface_control_selector_t; + +/* A.9.8 VideoStreaming Interface Control Selectors */ +typedef enum { + VIDEO_VS_CTL_UNDEFINED = 0x00, + VIDEO_VS_CTL_PROBE, + VIDEO_VS_CTL_COMMIT, + VIDEO_VS_CTL_STILL_PROBE, + VIDEO_VS_CTL_STILL_COMMIT, + VIDEO_VS_CTL_STILL_IMAGE_TRIGGER, + VIDEO_VS_CTL_STREAM_ERROR_CODE, + VIDEO_VS_CTL_GENERATE_KEY_FRAME, + VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT, + VIDEO_VS_CTL_SYNCH_DELAY_CONTROL, +} video_interface_streaming_selector_t; + +/* B. Terminal Types */ +typedef enum { + // Terminal + VIDEO_TT_VENDOR_SPECIFIC = 0x0100, + VIDEO_TT_STREAMING = 0x0101, + + // Input + VIDEO_ITT_VENDOR_SPECIFIC = 0x0200, + VIDEO_ITT_CAMERA = 0x0201, + VIDEO_ITT_MEDIA_TRANSPORT_INPUT = 0x0202, + + // Output + VIDEO_OTT_VENDOR_SPECIFIC = 0x0300, + VIDEO_OTT_DISPLAY = 0x0301, + VIDEO_OTT_MEDIA_TRANSPORT_OUTPUT = 0x0302, + + // External + VIDEO_ETT_VENDOR_SPEIFIC = 0x0400, + VIDEO_ETT_COMPOSITE_CONNECTOR = 0x0401, + VIDEO_ETT_SVIDEO_CONNECTOR = 0x0402, + VIDEO_ETT_COMPONENT_CONNECTOR = 0x0403, +} video_terminal_type_t; + +//--------------------------------------------------------------------+ +// Descriptors +//--------------------------------------------------------------------+ + +/* 2.3.4.2 */ +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint16_t bcdUVC; + uint16_t wTotalLength; + uint32_t dwClockFrequency; + uint8_t bInCollection; + uint8_t baInterfaceNr[]; +} tusb_desc_cs_video_ctl_itf_hdr_t; + +/* 2.4.3.3 */ +typedef struct TU_ATTR_PACKED { + uint8_t bHeaderLength; + union { + uint8_t bmHeaderInfo; + struct { + uint8_t FrameID: 1; + uint8_t EndOfFrame: 1; + uint8_t PresentationTime: 1; + uint8_t SourceClockReference: 1; + uint8_t PayloadSpecific: 1; + uint8_t StillImage: 1; + uint8_t Error: 1; + uint8_t EndOfHeader: 1; + }; + }; +} tusb_video_payload_header_t; + +/* 3.9.2.1 */ +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bNumFormats; + uint16_t wTotalLength; + uint8_t bEndpointAddress; + uint8_t bmInfo; + uint8_t bTerminalLink; + uint8_t bStillCaptureMethod; + uint8_t bTriggerSupport; + uint8_t bTriggerUsage; + uint8_t bControlSize; + uint8_t bmaControls[]; +} tusb_desc_cs_video_stm_itf_in_hdr_t; + +/* 3.9.2.2 */ +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bNumFormats; + uint16_t wTotalLength; + uint8_t bEndpointAddress; + uint8_t bTerminalLink; + uint8_t bControlSize; + uint8_t bmaControls[]; +} tusb_desc_cs_video_stm_itf_out_hdr_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bNumFormats; + uint16_t wTotalLength; + uint8_t bEndpointAddress; + union { + struct { + uint8_t bmInfo; + uint8_t bTerminalLink; + uint8_t bStillCaptureMethod; + uint8_t bTriggerSupport; + uint8_t bTriggerUsage; + uint8_t bControlSize; + uint8_t bmaControls[]; + } input; + struct { + uint8_t bEndpointAddress; + uint8_t bTerminalLink; + uint8_t bControlSize; + uint8_t bmaControls[]; + } output; + }; +} tusb_desc_cs_video_stm_itf_hdr_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint8_t bNumFrameDescriptors; + uint8_t guidFormat[16]; + uint8_t bBitsPerPixel; + uint8_t bDefaultFrameIndex; + uint8_t bAspectRatioX; + uint8_t bAspectRatioY; + uint8_t bmInterlaceFlags; + uint8_t bCopyProtect; +} tusb_desc_cs_video_fmt_uncompressed_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + uint8_t bmCapabilities; + uint16_t wWidth; + uint16_t wHeight; + uint32_t dwMinBitRate; + uint32_t dwMaxBitRate; + uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ + uint32_t dwDefaultFrameInterval; + uint8_t bFrameIntervalType; + uint32_t dwFrameInterval[]; +} tusb_desc_cs_video_frm_uncompressed_t; + +//--------------------------------------------------------------------+ +// Requests +//--------------------------------------------------------------------+ + +/* 4.3.1.1 */ +typedef struct TU_ATTR_PACKED { + union { + uint8_t bmHint; + struct TU_ATTR_PACKED { + uint16_t dwFrameInterval: 1; + uint16_t wKeyFrameRatel : 1; + uint16_t wPFrameRate : 1; + uint16_t wCompQuality : 1; + uint16_t wCompWindowSize: 1; + uint16_t : 0; + } Hint; + }; + uint8_t bFormatIndex; + uint8_t bFrameIndex; + uint32_t dwFrameInterval; + uint16_t wKeyFrameRate; + uint16_t wPFrameRate; + uint16_t wCompQuality; + uint16_t wCompWindowSize; + uint16_t wDelay; + uint32_t dwMaxVideoFrameSize; + uint32_t dwMaxPayloadTransferSize; + uint32_t dwClockFrequency; + union { + uint8_t bmFramingInfo; + struct TU_ATTR_PACKED { + uint8_t FrameID : 1; + uint8_t EndOfFrame: 1; + uint8_t EndOfSlice: 1; + uint8_t : 0; + } FramingInfo; + }; + uint8_t bPreferedVersion; + uint8_t bMinVersion; + uint8_t bMaxVersion; + uint8_t bUsage; + uint8_t bBitDepthLuma; + uint8_t bmSettings; + uint8_t bMaxNumberOfRefFramesPlus1; + uint16_t bmRateControlModes; + uint64_t bmLayoutPerStream; +} video_probe_and_commit_control_t; + +TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not correct"); + +#define TUD_VIDEO_DESC_IAD_LEN 8 +#define TUD_VIDEO_DESC_STD_VC_LEN 9 +#define TUD_VIDEO_DESC_CS_VC_LEN 12 +#define TUD_VIDEO_DESC_INPUT_TERM_LEN 8 +#define TUD_VIDEO_DESC_OUTPUT_TERM_LEN 9 +#define TUD_VIDEO_DESC_CAMERA_TERM_LEN 18 +#define TUD_VIDEO_DESC_STD_VS_LEN 9 +#define TUD_VIDEO_DESC_CS_VS_IN_LEN 13 +#define TUD_VIDEO_DESC_CS_VS_OUT_LEN 9 +#define TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN 27 +#define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN 38 +#define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC_LEN 26 +#define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN 6 + +/* 2.2 compression formats */ +#define TUD_VIDEO_GUID_YUY2 0x59,0x55,0x59,0x32,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 +#define TUD_VIDEO_GUID_NV12 0x4E,0x56,0x31,0x32,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 +#define TUD_VIDEO_GUID_M420 0x4D,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 +#define TUD_VIDEO_GUID_I420 0x49,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 + +#define TUD_VIDEO_DESC_IAD(_firstitfs, _nitfs, _stridx) \ + TUD_VIDEO_DESC_IAD_LEN, TUSB_DESC_INTERFACE_ASSOCIATION, \ + _firstitfs, _nitfs, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_INTERFACE_COLLECTION, \ + VIDEO_ITF_PROTOCOL_UNDEFINED, _stridx + +#define TUD_VIDEO_DESC_STD_VC(_itfnum, _nEPs, _stridx) \ + TUD_VIDEO_DESC_STD_VC_LEN, TUSB_DESC_INTERFACE, _itfnum, /* fixed to zero */ 0x00, \ + _nEPs, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_CONTROL, VIDEO_ITF_PROTOCOL_15, _stridx + +/* 3.7.2 */ +#define TUD_VIDEO_DESC_CS_VC(_bcdUVC, _totallen, _clkfreq, ...) \ + TUD_VIDEO_DESC_CS_VC_LEN + (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_HEADER, \ + U16_TO_U8S_LE(_bcdUVC), U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VC_LEN + (TU_ARGS_NUM(__VA_ARGS__))), \ + U32_TO_U8S_LE(_clkfreq), TU_ARGS_NUM(__VA_ARGS__), __VA_ARGS__ + +/* 3.7.2.1 */ +#define TUD_VIDEO_DESC_INPUT_TERM(_tid, _tt, _at, _stridx) \ + TUD_VIDEO_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_INPUT_TERMINAL, \ + _tid, U16_TO_U8S_LE(_tt), _at, _stridx + +/* 3.7.2.2 */ +#define TUD_VIDEO_DESC_OUTPUT_TERM(_tid, _tt, _at, _srcid, _stridx) \ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, \ + _tid, U16_TO_U8S_LE(_tt), _at, _srcid, _stridx + +/* 3.7.2.3 */ +#define TUD_VIDEO_DESC_CAMERA_TERM(_tid, _at, _stridx, _focal_min, _focal_max, _focal, _ctls) \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_INPUT_TERMINAL, \ + _tid, U16_TO_U8S_LE(VIDEO_ITT_CAMERA), _at, _stridx, \ + U16_TO_U8S_LE(_focal_min), U16_TO_U8S_LE(_focal_max), U16_TO_U8S_LE(_focal), 3, \ + TU_U32_BYTE0(_ctls), TU_U32_BYTE1(_ctls), TU_U32_BYTE2(_ctls) + +/* 3.9.1 */ +#define TUD_VIDEO_DESC_STD_VS(_itfnum, _alt, _epn, _stridx) \ + TUD_VIDEO_DESC_STD_VS_LEN, TUSB_DESC_INTERFACE, _itfnum, _alt, \ + _epn, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_STREAMING, VIDEO_ITF_PROTOCOL_15, _stridx + +/* 3.9.2.1 */ +#define TUD_VIDEO_DESC_CS_VS_INPUT(_numfmt, _totallen, _ep, _inf, _termlnk, _sticaptmeth, _trgspt, _trgusg, ...) \ + TUD_VIDEO_DESC_CS_VS_IN_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, \ + VIDEO_CS_ITF_VS_INPUT_HEADER, _numfmt, \ + U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VS_IN_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__))), \ + _ep, _inf, _termlnk, _sticaptmeth, _trgspt, _trgusg, (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ + +/* 3.9.2.2 */ +#define TUD_VIDEO_DESC_CS_VS_OUTPUT(_numfmt, _totallen, _ep, _inf, _termlnk, ...) \ + TUD_VIDEO_DESC_CS_VS_OUT_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, \ + VIDEO_CS_ITF_VS_OUTPUT_HEADER, _numfmt, \ + U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VS_OUT_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__))), \ + _ep, _inf, _termlnk, (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ + +/* Uncompressed 3.1.1 */ +#define TUD_VIDEO_GUID(_g0,_g1,_g2,_g3,_g4,_g5,_g6,_g7,_g8,_g9,_g10,_g11,_g12,_g13,_g14,_g15) _g0,_g1,_g2,_g3,_g4,_g5,_g6,_g7,_g8,_g9,_g10,_g11,_g12,_g13,_g14,_g15 + +#define TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfrmdesc, \ + _guid, _bitsperpix, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, \ + _fmtidx, _numfrmdesc, TUD_VIDEO_GUID(_guid), \ + _bitsperpix, _frmidx, _asrx, _asry, _interlace, _cp + +/* Uncompressed 3.1.2 Table 3-3 */ +#define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, _minfrminterval, _maxfrminterval, _frmintervalstep) \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, \ + _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ + U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), 0, \ + U32_TO_U8S_LE(_minfrminterval), U32_TO_U8S_LE(_maxfrminterval), U32_TO_U8S_LE(_frmintervalstep) + +/* Uncompressed 3.1.2 Table 3-4 */ +#define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, \ + _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ + U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ + +/* 3.9.2.6 */ +#define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(_color, _trns, _mat) \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_COLORFORMAT, \ + _color, _trns, _mat + +/* 3.10.1.1 */ +#define TUD_VIDEO_DESC_EP_ISO(_ep, _epsize, _ep_interval) \ + 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS,\ + U16_TO_U8S_LE(_epsize), _ep_interval + +/* 3.10.1.2 */ +#define TUD_VIDEO_DESC_EP_BULK(_ep, _epsize, _ep_interval) \ + 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), _ep_interval + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/video/video_device.c b/circuitpython/lib/tinyusb/src/class/video/video_device.c new file mode 100644 index 0000000..91718f2 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/video/video_device.c @@ -0,0 +1,1149 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" + +#include "video_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef struct { + tusb_desc_interface_t std; + tusb_desc_cs_video_ctl_itf_hdr_t ctl; +} tusb_desc_vc_itf_t; + +typedef struct { + tusb_desc_interface_t std; + tusb_desc_cs_video_stm_itf_hdr_t stm; +} tusb_desc_vs_itf_t; + +typedef union { + tusb_desc_cs_video_ctl_itf_hdr_t ctl; + tusb_desc_cs_video_stm_itf_hdr_t stm; +} tusb_desc_video_itf_hdr_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bEntityId; +} tusb_desc_cs_video_entity_itf_t; + +/* video streaming interface */ +typedef struct TU_ATTR_PACKED { + uint8_t index_vc; /* index of bound video control interface */ + uint8_t index_vs; /* index from the video control interface */ + struct { + uint16_t beg; /* Offset of the begging of video streaming interface descriptor */ + uint16_t end; /* Offset of the end of video streaming interface descriptor */ + uint16_t cur; /* Offset of the current settings */ + uint16_t ep[2]; /* Offset of endpoint descriptors. 0: streaming, 1: still capture */ + } desc; + uint8_t *buffer; /* frame buffer. assume linear buffer. no support for stride access */ + uint32_t bufsize; /* frame buffer size */ + uint32_t offset; /* offset for the next payload transfer */ + uint32_t max_payload_transfer_size; + uint8_t error_code;/* error code */ + /*------------- From this point, data is not cleared by bus reset -------------*/ + CFG_TUSB_MEM_ALIGN uint8_t ep_buf[CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE]; /* EP transfer buffer for streaming */ +} videod_streaming_interface_t; + +/* video control interface */ +typedef struct TU_ATTR_PACKED { + void const *beg; /* The head of the first video control interface descriptor */ + uint16_t len; /* Byte length of the descriptors */ + uint16_t cur; /* offset for current video control interface */ + uint8_t stm[CFG_TUD_VIDEO_STREAMING]; /* Indices of streaming interface */ + uint8_t error_code; /* error code */ + uint8_t power_mode; + + /*------------- From this point, data is not cleared by bus reset -------------*/ + // CFG_TUSB_MEM_ALIGN uint8_t ctl_buf[64]; /* EP transfer buffer for interrupt transfer */ + +} videod_interface_t; + +#define ITF_STM_MEM_RESET_SIZE offsetof(videod_streaming_interface_t, ep_buf) + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION static videod_interface_t _videod_itf[CFG_TUD_VIDEO]; +CFG_TUSB_MEM_SECTION static videod_streaming_interface_t _videod_streaming_itf[CFG_TUD_VIDEO_STREAMING]; + +static uint8_t const _cap_get = 0x1u; /* support for GET */ +static uint8_t const _cap_get_set = 0x3u; /* support for GET and SET */ + +/** Get interface number from the interface descriptor + * + * @param[in] desc interface descriptor + * + * @return bInterfaceNumber */ +static inline uint8_t _desc_itfnum(void const *desc) +{ + return ((uint8_t const*)desc)[2]; +} + +/** Get endpoint address from the endpoint descriptor + * + * @param[in] desc endpoint descriptor + * + * @return bEndpointAddress */ +static inline uint8_t _desc_ep_addr(void const *desc) +{ + return ((uint8_t const*)desc)[2]; +} + +/** Get instance of streaming interface + * + * @param[in] ctl_idx instance number of video control + * @param[in] stm_idx index number of streaming interface + * + * @return instance */ +static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) +{ + videod_interface_t *ctl = &_videod_itf[ctl_idx]; + if (!ctl->beg) return NULL; + videod_streaming_interface_t *stm = &_videod_streaming_itf[ctl->stm[stm_idx]]; + if (!stm->desc.beg) return NULL; + return stm; +} + +static tusb_desc_vc_itf_t const* _get_desc_vc(videod_interface_t const *self) +{ + return (tusb_desc_vc_itf_t const *)(self->beg + self->cur); +} + +static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const *self) +{ + if (!self->desc.cur) return NULL; + void const *desc = _videod_itf[self->index_vc].beg; + return (tusb_desc_vs_itf_t const*)(desc + self->desc.cur); +} + +/** Find the first descriptor of a given type + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] desc_type The target descriptor type. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc(void const *beg, void const *end, uint_fast8_t desc_type) +{ + void const *cur = beg; + while ((cur < end) && (desc_type != tu_desc_type(cur))) { + cur = tu_desc_next(cur); + } + return cur; +} + +/** Find the first descriptor specified by the arguments + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] desc_type The target descriptor type + * @param[in] element_0 The target element following the desc_type + * @param[in] element_1 The target element following the element_0 + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_3(void const *beg, void const *end, + uint_fast8_t desc_type, + uint_fast8_t element_0, + uint_fast8_t element_1) +{ + for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) { + uint8_t const *p = (uint8_t const *)cur; + if ((p[2] == element_0) && (p[3] == element_1)) { + return cur; + } + cur = tu_desc_next(cur); + } + return end; +} + +/** Return the next interface descriptor which has another interface number. + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _next_desc_itf(void const *beg, void const *end) +{ + void const *cur = beg; + uint_fast8_t itfnum = ((tusb_desc_interface_t const*)cur)->bInterfaceNumber; + while ((cur < end) && + (itfnum == ((tusb_desc_interface_t const*)cur)->bInterfaceNumber)) { + cur = _find_desc(tu_desc_next(cur), end, TUSB_DESC_INTERFACE); + } + return cur; +} + +/** Find the first interface descriptor with the specified interface number and alternate setting number. + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] itfnum The target interface number. + * @param[in] altnum The target alternate setting number. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static inline void const* _find_desc_itf(void const *beg, void const *end, uint_fast8_t itfnum, uint_fast8_t altnum) +{ + return _find_desc_3(beg, end, TUSB_DESC_INTERFACE, itfnum, altnum); +} + +/** Find the first endpoint descriptor belonging to the current interface descriptor. + * + * The search range is from `beg` to `end` or the next interface descriptor. + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * + * @return The pointer for endpoint descriptor. + * @retval end did not found endpoint descriptor */ +static void const* _find_desc_ep(void const *beg, void const *end) +{ + for (void const *cur = beg; cur < end; cur = tu_desc_next(cur)) { + uint_fast8_t desc_type = tu_desc_type(cur); + if (TUSB_DESC_ENDPOINT == desc_type) return cur; + if (TUSB_DESC_INTERFACE == desc_type) break; + } + return end; +} + +/** Find the first entity descriptor with the entity ID + * specified by the argument belonging to the current video control descriptor. + * + * @param[in] desc The video control interface descriptor. + * @param[in] entityid The target entity id. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_entity(void const *desc, uint_fast8_t entityid) +{ + tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const*)desc; + void const *beg = vc; + void const *end = beg + vc->std.bLength + vc->ctl.wTotalLength; + for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + tusb_desc_cs_video_entity_itf_t const *itf = (tusb_desc_cs_video_entity_itf_t const *)cur; + if ((VIDEO_CS_ITF_VC_INPUT_TERMINAL <= itf->bDescriptorSubtype + && itf->bDescriptorSubtype < VIDEO_CS_ITF_VC_MAX) + && itf->bEntityId == entityid) { + return itf; + } + cur = tu_desc_next(cur); + } + return end; +} + +/** Return the end of the video streaming descriptor. */ +static inline void const* _end_of_streaming_descriptor(void const *desc) +{ + tusb_desc_vs_itf_t const *vs = (tusb_desc_vs_itf_t const *)desc; + return desc + vs->std.bLength + vs->stm.wTotalLength; +} + +/** Find the first format descriptor with the specified format number. */ +static inline tusb_desc_cs_video_fmt_uncompressed_t const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum) +{ + return (tusb_desc_cs_video_fmt_uncompressed_t const*) + _find_desc_3(beg, end, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, fmtnum); +} + +/** Find the first frame descriptor with the specified format number. */ +static inline tusb_desc_cs_video_frm_uncompressed_t const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum) +{ + return (tusb_desc_cs_video_frm_uncompressed_t const*) + _find_desc_3(beg, end, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, frmnum); +} + +/** Set uniquely determined values to variables that have not been set + * + * @param[in,out] param Target */ +static bool _update_streaming_parameters(videod_streaming_interface_t const *stm, + video_probe_and_commit_control_t *param) +{ + tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); + uint_fast8_t fmtnum = param->bFormatIndex; + TU_ASSERT(fmtnum <= vs->stm.bNumFormats); + if (!fmtnum) { + if (1 < vs->stm.bNumFormats) return true; /* Need to negotiate all variables. */ + fmtnum = 1; + param->bFormatIndex = 1; + } + + /* Set the parameters determined by the format */ + param->wKeyFrameRate = 1; + param->wPFrameRate = 0; + param->wCompQuality = 1; /* 1 to 10000 */ + param->wCompWindowSize = 1; /* GOP size? */ + param->wDelay = 0; /* milliseconds */ + param->dwClockFrequency = 27000000; /* same as MPEG-2 system time clock */ + param->bmFramingInfo = 0x3; /* enables FrameID and EndOfFrame */ + param->bPreferedVersion = 1; + param->bMinVersion = 1; + param->bMaxVersion = 1; + param->bUsage = 0; + param->bBitDepthLuma = 8; + + void const *end = _end_of_streaming_descriptor(vs); + tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + TU_ASSERT(fmt != end); + uint_fast8_t frmnum = param->bFrameIndex; + TU_ASSERT(frmnum <= fmt->bNumFrameDescriptors); + if (!frmnum) { + if (1 < fmt->bNumFrameDescriptors) return true; + frmnum = 1; + param->bFrameIndex = 1; + } + tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + TU_ASSERT(frm != end); + + /* Set the parameters determined by the frame */ + uint_fast32_t frame_size = param->dwMaxVideoFrameSize; + if (!frame_size) { + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8; + param->dwMaxVideoFrameSize = frame_size; + } + + uint_fast32_t interval = param->dwFrameInterval; + if (!interval) { + if ((1 < frm->bFrameIntervalType) || + ((0 == frm->bFrameIntervalType) && (frm->dwFrameInterval[1] != frm->dwFrameInterval[0]))) { + return true; + } + interval = frm->dwFrameInterval[0]; + param->dwFrameInterval = interval; + } + uint_fast32_t interval_ms = interval / 10000; + TU_ASSERT(interval_ms); + uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; + param->dwMaxPayloadTransferSize = payload_size; + return true; +} + +/** Set the minimum, maximum, default values or resolutions to variables which need to negotiate with the host + * + * @param[in] request GET_MAX, GET_MIN, GET_RES or GET_DEF + * @param[in,out] param Target + */ +static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *stm, uint_fast8_t request, + video_probe_and_commit_control_t *param) +{ + uint_fast8_t const fmtnum = param->bFormatIndex; + if (!fmtnum) { + switch (request) { + case VIDEO_REQUEST_GET_MAX: + param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; + break; + case VIDEO_REQUEST_GET_MIN: + case VIDEO_REQUEST_GET_DEF: + param->bFormatIndex = 1; + break; + default: return false; + } + /* Set the parameters determined by the format */ + param->wKeyFrameRate = 1; + param->wPFrameRate = 0; + param->wCompQuality = 1; /* 1 to 10000 */ + param->wCompWindowSize = 1; /* GOP size? */ + param->wDelay = 0; /* milliseconds */ + param->dwClockFrequency = 27000000; /* same as MPEG-2 system time clock */ + param->bmFramingInfo = 0x3; /* enables FrameID and EndOfFrame */ + param->bPreferedVersion = 1; + param->bMinVersion = 1; + param->bMaxVersion = 1; + param->bUsage = 0; + param->bBitDepthLuma = 8; + return true; + } + + uint_fast8_t frmnum = param->bFrameIndex; + if (!frmnum) { + tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); + void const *end = _end_of_streaming_descriptor(vs); + tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + switch (request) { + case VIDEO_REQUEST_GET_MAX: + frmnum = fmt->bNumFrameDescriptors; + break; + case VIDEO_REQUEST_GET_MIN: + frmnum = 1; + break; + case VIDEO_REQUEST_GET_DEF: + frmnum = fmt->bDefaultFrameIndex; + break; + default: return false; + } + param->bFrameIndex = frmnum; + /* Set the parameters determined by the frame */ + tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + param->dwMaxVideoFrameSize = frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8; + return true; + } + + if (!param->dwFrameInterval) { + tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); + void const *end = _end_of_streaming_descriptor(vs); + tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + + uint_fast32_t interval, interval_ms; + switch (request) { + case VIDEO_REQUEST_GET_MAX: + { + uint_fast32_t min_interval, max_interval; + uint_fast8_t num_intervals = frm->bFrameIntervalType; + max_interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; + min_interval = frm->dwFrameInterval[0]; + interval = max_interval; + interval_ms = min_interval / 10000; + } + break; + case VIDEO_REQUEST_GET_MIN: + { + uint_fast32_t min_interval, max_interval; + uint_fast8_t num_intervals = frm->bFrameIntervalType; + max_interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; + min_interval = frm->dwFrameInterval[0]; + interval = min_interval; + interval_ms = max_interval / 10000; + } + break; + case VIDEO_REQUEST_GET_DEF: + interval = frm->dwDefaultFrameInterval; + interval_ms = interval / 10000; + break; + case VIDEO_REQUEST_GET_RES: + { + uint_fast8_t num_intervals = frm->bFrameIntervalType; + if (num_intervals) { + interval = 0; + } else { + interval = frm->dwFrameInterval[2]; + interval_ms = interval / 10000; + } + } + break; + default: return false; + } + param->dwFrameInterval = interval; + if (!interval) { + param->dwMaxPayloadTransferSize = 0; + } else { + uint_fast32_t frame_size = param->dwMaxVideoFrameSize; + if (!interval_ms) { + param->dwMaxPayloadTransferSize = frame_size + 2; + } else { + param->dwMaxPayloadTransferSize = (frame_size + interval_ms - 1) / interval_ms + 2; + } + } + return true; + } + return true; +} + +/** Close current video control interface. + * + * @param[in,out] self Video control interface context. + * @param[in] altnum The target alternate setting number. */ +static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self) +{ + tusb_desc_vc_itf_t const *vc = _get_desc_vc(self); + /* The next descriptor after the class-specific VC interface header descriptor. */ + void const *cur = (void const*)vc + vc->std.bLength + vc->ctl.bLength; + /* The end of the video control interface descriptor. */ + void const *end = (void const*)vc + vc->std.bLength + vc->ctl.wTotalLength; + if (vc->std.bNumEndpoints) { + /* Find the notification endpoint descriptor. */ + cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT); + TU_ASSERT(cur < end); + tusb_desc_endpoint_t const *notif = (tusb_desc_endpoint_t const *)cur; + usbd_edpt_close(rhport, notif->bEndpointAddress); + } + self->cur = 0; + return true; +} + +/** Set the alternate setting to own video control interface. + * + * @param[in,out] self Video control interface context. + * @param[in] altnum The target alternate setting number. */ +static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t altnum) +{ + TU_LOG2(" open VC %d\n", altnum); + void const *beg = self->beg; + void const *end = beg + self->len; + /* The first descriptor is a video control interface descriptor. */ + void const *cur = _find_desc_itf(beg, end, _desc_itfnum(beg), altnum); + TU_LOG2(" cur %d\n", cur - beg); + TU_VERIFY(cur < end); + + tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)cur; + TU_LOG2(" bInCollection %d\n", vc->ctl.bInCollection); + /* Support for up to 2 streaming interfaces only. */ + TU_ASSERT(vc->ctl.bInCollection <= CFG_TUD_VIDEO_STREAMING); + + /* Update to point the end of the video control interface descriptor. */ + end = cur + vc->std.bLength + vc->ctl.wTotalLength; + /* Advance to the next descriptor after the class-specific VC interface header descriptor. */ + cur += vc->std.bLength + vc->ctl.bLength; + TU_LOG2(" bNumEndpoints %d\n", vc->std.bNumEndpoints); + /* Open the notification endpoint if it exist. */ + if (vc->std.bNumEndpoints) { + /* Support for 1 endpoint only. */ + TU_VERIFY(1 == vc->std.bNumEndpoints); + /* Find the notification endpoint descriptor. */ + cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT); + TU_VERIFY(cur < end); + tusb_desc_endpoint_t const *notif = (tusb_desc_endpoint_t const *)cur; + /* Open the notification endpoint */ + TU_ASSERT(usbd_edpt_open(rhport, notif)); + } + self->cur = (void const*)vc - beg; + return true; +} + +/** Set the alternate setting to own video streaming interface. + * + * @param[in,out] stm Streaming interface context. + * @param[in] altnum The target alternate setting number. */ +static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint_fast8_t altnum) +{ + uint_fast8_t i; + TU_LOG2(" reopen VS %d\n", altnum); + void const *desc = _videod_itf[stm->index_vc].beg; + + /* Close endpoints of previous settings. */ + for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) { + uint_fast16_t ofs_ep = stm->desc.ep[i]; + if (!ofs_ep) break; + uint_fast8_t ep_adr = _desc_ep_addr(desc + ofs_ep); + usbd_edpt_close(rhport, ep_adr); + stm->desc.ep[i] = 0; + TU_LOG2(" close EP%02x\n", ep_adr); + } + /* clear transfer management information */ + stm->buffer = NULL; + stm->bufsize = 0; + stm->offset = 0; + + /* Find a alternate interface */ + void const *beg = desc + stm->desc.beg; + void const *end = desc + stm->desc.end; + void const *cur = _find_desc_itf(beg, end, _desc_itfnum(beg), altnum); + TU_VERIFY(cur < end); + uint_fast8_t numeps = ((tusb_desc_interface_t const *)cur)->bNumEndpoints; + TU_ASSERT(numeps <= TU_ARRAY_SIZE(stm->desc.ep)); + stm->desc.cur = cur - desc; /* Save the offset of the new settings */ + if (!altnum) { + /* initialize streaming settings */ + stm->max_payload_transfer_size = 0; + video_probe_and_commit_control_t *param = + (video_probe_and_commit_control_t *)&stm->ep_buf; + tu_memclr(param, sizeof(*param)); + return _update_streaming_parameters(stm, param); + } + /* Open endpoints of the new settings. */ + for (i = 0, cur = tu_desc_next(cur); i < numeps; ++i, cur = tu_desc_next(cur)) { + cur = _find_desc_ep(cur, end); + TU_ASSERT(cur < end); + tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)cur; + if (!stm->max_payload_transfer_size) { + video_probe_and_commit_control_t const *param = (video_probe_and_commit_control_t const*)&stm->ep_buf; + uint_fast32_t max_size = param->dwMaxPayloadTransferSize; + if ((TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer) && + (tu_edpt_packet_size(ep) < max_size)) + { + /* FS must be less than or equal to max packet size */ + return false; + } + /* Set the negotiated value */ + stm->max_payload_transfer_size = max_size; + } + TU_ASSERT(usbd_edpt_open(rhport, ep)); + stm->desc.ep[i] = cur - desc; + TU_LOG2(" open EP%02x\n", _desc_ep_addr(cur)); + } + /* initialize payload header */ + tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*)stm->ep_buf; + hdr->bHeaderLength = sizeof(*hdr); + hdr->bmHeaderInfo = 0; + + return true; +} + +/** Prepare the next packet payload. */ +static uint_fast16_t _prepare_in_payload(videod_streaming_interface_t *stm) +{ + uint_fast16_t remaining = stm->bufsize - stm->offset; + uint_fast16_t hdr_len = stm->ep_buf[0]; + uint_fast16_t pkt_len = stm->max_payload_transfer_size; + if (hdr_len + remaining < pkt_len) { + pkt_len = hdr_len + remaining; + } + uint_fast16_t data_len = pkt_len - hdr_len; + memcpy(&stm->ep_buf[hdr_len], stm->buffer + stm->offset, data_len); + stm->offset += data_len; + remaining -= data_len; + if (!remaining) { + tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*)stm->ep_buf; + hdr->EndOfFrame = 1; + } + return hdr_len + data_len; +} + +/** Handle a standard request to the video control interface. */ +static int handle_video_ctl_std_req(uint8_t rhport, uint8_t stage, + tusb_control_request_t const *request, + uint_fast8_t ctl_idx) +{ + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); + tusb_desc_vc_itf_t const *vc = _get_desc_vc(&_videod_itf[ctl_idx]); + TU_VERIFY(vc, VIDEO_ERROR_UNKNOWN); + + uint8_t alt_num = vc->std.bAlternateSetting; + + TU_VERIFY(tud_control_xfer(rhport, request, &alt_num, sizeof(alt_num)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case TUSB_REQ_SET_INTERFACE: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(0 == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(_close_vc_itf(rhport, &_videod_itf[ctl_idx]), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(_open_vc_itf(rhport, &_videod_itf[ctl_idx], request->wValue), VIDEO_ERROR_UNKNOWN); + tud_control_status(rhport, request); + } + return VIDEO_ERROR_NONE; + + default: /* Unknown/Unsupported request */ + TU_BREAKPOINT(); + return VIDEO_ERROR_INVALID_REQUEST; + } +} + +static int handle_video_ctl_cs_req(uint8_t rhport, uint8_t stage, + tusb_control_request_t const *request, + uint_fast8_t ctl_idx) +{ + videod_interface_t *self = &_videod_itf[ctl_idx]; + + /* 4.2.1 Interface Control Request */ + switch (TU_U16_HIGH(request->wValue)) { + case VIDEO_VC_CTL_VIDEO_POWER_MODE: + switch (request->bRequest) { + case VIDEO_REQUEST_SET_CUR: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &self->power_mode, sizeof(self->power_mode)), VIDEO_ERROR_UNKNOWN); + } else if (stage == CONTROL_STAGE_ACK) { + if (tud_video_power_mode_cb) return tud_video_power_mode_cb(ctl_idx, self->power_mode); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_CUR: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &self->power_mode, sizeof(self->power_mode)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_INFO: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + default: break; + } + break; + + case VIDEO_VC_CTL_REQUEST_ERROR_CODE: + switch (request->bRequest) { + case VIDEO_REQUEST_GET_CUR: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(tud_control_xfer(rhport, request, &self->error_code, sizeof(uint8_t)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_INFO: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get, sizeof(_cap_get)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + default: break; + } + break; + + default: break; + } + + /* Unknown/Unsupported request */ + TU_BREAKPOINT(); + return VIDEO_ERROR_INVALID_REQUEST; +} + +static int handle_video_ctl_req(uint8_t rhport, uint8_t stage, + tusb_control_request_t const *request, + uint_fast8_t ctl_idx) +{ + uint_fast8_t entity_id; + switch (request->bmRequestType_bit.type) { + case TUSB_REQ_TYPE_STANDARD: + return handle_video_ctl_std_req(rhport, stage, request, ctl_idx); + + case TUSB_REQ_TYPE_CLASS: + entity_id = TU_U16_HIGH(request->wIndex); + if (!entity_id) { + return handle_video_ctl_cs_req(rhport, stage, request, ctl_idx); + } else { + TU_VERIFY(_find_desc_entity(_get_desc_vc(&_videod_itf[ctl_idx]), entity_id), VIDEO_ERROR_INVALID_REQUEST); + return VIDEO_ERROR_NONE; + } + + default: + return VIDEO_ERROR_INVALID_REQUEST; + } +} + +static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage, + tusb_control_request_t const *request, + uint_fast8_t stm_idx) +{ + videod_streaming_interface_t *self = &_videod_streaming_itf[stm_idx]; + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); + tusb_desc_vs_itf_t const *vs = _get_desc_vs(self); + TU_VERIFY(vs, VIDEO_ERROR_UNKNOWN); + uint8_t alt_num = vs->std.bAlternateSetting; + + TU_VERIFY(tud_control_xfer(rhport, request, &alt_num, sizeof(alt_num)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case TUSB_REQ_SET_INTERFACE: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(_open_vs_itf(rhport, self, request->wValue), VIDEO_ERROR_UNKNOWN); + tud_control_status(rhport, request); + } + return VIDEO_ERROR_NONE; + + default: /* Unknown/Unsupported request */ + TU_BREAKPOINT(); + return VIDEO_ERROR_INVALID_REQUEST; + } +} + +static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, + tusb_control_request_t const *request, + uint_fast8_t stm_idx) +{ + (void)rhport; + videod_streaming_interface_t *self = &_videod_streaming_itf[stm_idx]; + + /* 4.2.1 Interface Control Request */ + switch (TU_U16_HIGH(request->wValue)) { + case VIDEO_VS_CTL_STREAM_ERROR_CODE: + switch (request->bRequest) { + case VIDEO_REQUEST_GET_CUR: + if (stage == CONTROL_STAGE_SETUP) + { + /* TODO */ + TU_VERIFY(tud_control_xfer(rhport, request, &self->error_code, sizeof(uint8_t)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_INFO: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get, sizeof(_cap_get)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + default: break; + } + break; + + case VIDEO_VS_CTL_PROBE: + switch (request->bRequest) { + case VIDEO_REQUEST_SET_CUR: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(sizeof(video_probe_and_commit_control_t) == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), + VIDEO_ERROR_UNKNOWN); + } else if (stage == CONTROL_STAGE_ACK) { + TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), + VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_CUR: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_MIN: + case VIDEO_REQUEST_GET_MAX: + case VIDEO_REQUEST_GET_RES: + case VIDEO_REQUEST_GET_DEF: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); + video_probe_and_commit_control_t tmp; + tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; + TU_VERIFY(_negotiate_streaming_parameters(self, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); + TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_LEN: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); + uint16_t len = sizeof(video_probe_and_commit_control_t); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_INFO: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + default: break; + } + break; + + case VIDEO_VS_CTL_COMMIT: + switch (request->bRequest) { + case VIDEO_REQUEST_SET_CUR: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(sizeof(video_probe_and_commit_control_t) == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + } else if (stage == CONTROL_STAGE_ACK) { + TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); + if (tud_video_commit_cb) { + return tud_video_commit_cb(self->index_vc, self->index_vs, (video_probe_and_commit_control_t*)self->ep_buf); + } + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_CUR: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_LEN: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); + uint16_t len = sizeof(video_probe_and_commit_control_t); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + case VIDEO_REQUEST_GET_INFO: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + + default: break; + } + break; + + case VIDEO_VS_CTL_STILL_PROBE: + case VIDEO_VS_CTL_STILL_COMMIT: + case VIDEO_VS_CTL_STILL_IMAGE_TRIGGER: + case VIDEO_VS_CTL_GENERATE_KEY_FRAME: + case VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT: + case VIDEO_VS_CTL_SYNCH_DELAY_CONTROL: + /* TODO */ + break; + + default: break; + } + + /* Unknown/Unsupported request */ + TU_BREAKPOINT(); + return VIDEO_ERROR_INVALID_REQUEST; +} + +static int handle_video_stm_req(uint8_t rhport, uint8_t stage, + tusb_control_request_t const *request, + uint_fast8_t stm_idx) +{ + switch (request->bmRequestType_bit.type) { + case TUSB_REQ_TYPE_STANDARD: + return handle_video_stm_std_req(rhport, stage, request, stm_idx); + + case TUSB_REQ_TYPE_CLASS: + if (TU_U16_HIGH(request->wIndex)) return VIDEO_ERROR_INVALID_REQUEST; + return handle_video_stm_cs_req(rhport, stage, request, stm_idx); + + default: return VIDEO_ERROR_INVALID_REQUEST; + } + return VIDEO_ERROR_UNKNOWN; +} + +//--------------------------------------------------------------------+ +// APPLICATION API +//--------------------------------------------------------------------+ + +bool tud_video_n_connected(uint_fast8_t ctl_idx) +{ + TU_ASSERT(ctl_idx < CFG_TUD_VIDEO); + videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, 0); + if (stm) return true; + return false; +} + +bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) +{ + TU_ASSERT(ctl_idx < CFG_TUD_VIDEO); + TU_ASSERT(stm_idx < CFG_TUD_VIDEO_STREAMING); + videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx); + if (!stm || !stm->desc.ep[0]) return false; + return true; +} + +bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *buffer, size_t bufsize) +{ + TU_ASSERT(ctl_idx < CFG_TUD_VIDEO); + TU_ASSERT(stm_idx < CFG_TUD_VIDEO_STREAMING); + if (!buffer || !bufsize) return false; + videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx); + if (!stm || !stm->desc.ep[0] || stm->buffer) return false; + + /* Find EP address */ + void const *desc = _videod_itf[stm->index_vc].beg; + uint_fast8_t ep_addr = 0; + for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { + uint_fast16_t ofs_ep = stm->desc.ep[i]; + if (!ofs_ep) continue; + ep_addr = _desc_ep_addr(desc + ofs_ep); + break; + } + if (!ep_addr) return false; + + TU_VERIFY( usbd_edpt_claim(0, ep_addr)); + /* update the packet header */ + tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*)stm->ep_buf; + hdr->FrameID ^= 1; + hdr->EndOfFrame = 0; + /* update the packet data */ + stm->buffer = (uint8_t*)buffer; + stm->bufsize = bufsize; + uint_fast16_t pkt_len = _prepare_in_payload(stm); + TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm->ep_buf, pkt_len), 0); + return true; +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void videod_init(void) +{ + for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { + videod_interface_t* ctl = &_videod_itf[i]; + tu_memclr(ctl, sizeof(*ctl)); + } + for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { + videod_streaming_interface_t *stm = &_videod_streaming_itf[i]; + tu_memclr(stm, ITF_STM_MEM_RESET_SIZE); + } +} + +void videod_reset(uint8_t rhport) +{ + (void) rhport; + for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { + videod_interface_t* ctl = &_videod_itf[i]; + tu_memclr(ctl, sizeof(*ctl)); + } + for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { + videod_streaming_interface_t *stm = &_videod_streaming_itf[i]; + tu_memclr(stm, ITF_STM_MEM_RESET_SIZE); + } +} + +uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + TU_VERIFY((TUSB_CLASS_VIDEO == itf_desc->bInterfaceClass) && + (VIDEO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass) && + (VIDEO_ITF_PROTOCOL_15 == itf_desc->bInterfaceProtocol), 0); + + /* Find available interface */ + videod_interface_t *self = NULL; + uint_fast8_t ctl_idx; + for (ctl_idx = 0; ctl_idx < CFG_TUD_VIDEO; ++ctl_idx) { + if (_videod_itf[ctl_idx].beg) continue; + self = &_videod_itf[ctl_idx]; + break; + } + TU_ASSERT(ctl_idx < CFG_TUD_VIDEO, 0); + + void const *end = (void const*)itf_desc + max_len; + self->beg = itf_desc; + self->len = max_len; + /*------------- Video Control Interface -------------*/ + TU_VERIFY(_open_vc_itf(rhport, self, 0), 0); + tusb_desc_vc_itf_t const *vc = _get_desc_vc(self); + uint_fast8_t bInCollection = vc->ctl.bInCollection; + /* Find the end of the video interface descriptor */ + void const *cur = _next_desc_itf(itf_desc, end); + for (uint_fast8_t stm_idx = 0; stm_idx < bInCollection; ++stm_idx) { + videod_streaming_interface_t *stm = NULL; + /* find free streaming interface handle */ + for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { + if (_videod_streaming_itf[i].desc.beg) continue; + stm = &_videod_streaming_itf[i]; + self->stm[stm_idx] = i; + break; + } + TU_ASSERT(stm, 0); + stm->index_vc = ctl_idx; + stm->index_vs = stm_idx; + stm->desc.beg = (uintptr_t)cur - (uintptr_t)itf_desc; + cur = _next_desc_itf(cur, end); + stm->desc.end = (uintptr_t)cur - (uintptr_t)itf_desc; + } + self->len = (uintptr_t)cur - (uintptr_t)itf_desc; + return (uintptr_t)cur - (uintptr_t)itf_desc; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + int err; + TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); + uint_fast8_t itfnum = tu_u16_low(request->wIndex); + + /* Identify which control interface to use */ + uint_fast8_t itf; + for (itf = 0; itf < CFG_TUD_VIDEO; ++itf) { + void const *desc = _videod_itf[itf].beg; + if (!desc) continue; + if (itfnum == _desc_itfnum(desc)) break; + } + + if (itf < CFG_TUD_VIDEO) { + err = handle_video_ctl_req(rhport, stage, request, itf); + _videod_itf[itf].error_code = (uint8_t)err; + if (err) return false; + return true; + } + + /* Identify which streaming interface to use */ + for (itf = 0; itf < CFG_TUD_VIDEO_STREAMING; ++itf) { + videod_streaming_interface_t *stm = &_videod_streaming_itf[itf]; + if (!stm->desc.beg) continue; + void const *desc = _videod_itf[stm->index_vc].beg; + if (itfnum == _desc_itfnum(desc + stm->desc.beg)) break; + } + + if (itf < CFG_TUD_VIDEO_STREAMING) { + err = handle_video_stm_req(rhport, stage, request, itf); + _videod_streaming_itf[itf].error_code = (uint8_t)err; + if (err) return false; + return true; + } + return false; +} + +bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void)result; (void)xferred_bytes; + + /* find streaming handle */ + uint_fast8_t itf; + videod_interface_t *ctl; + videod_streaming_interface_t *stm; + for (itf = 0; itf < CFG_TUD_VIDEO_STREAMING; ++itf) { + stm = &_videod_streaming_itf[itf]; + uint_fast16_t const ep_ofs = stm->desc.ep[0]; + if (!ep_ofs) continue; + ctl = &_videod_itf[stm->index_vc]; + void const *desc = ctl->beg; + if (ep_addr == _desc_ep_addr(desc + ep_ofs)) break; + } + + TU_ASSERT(itf < CFG_TUD_VIDEO_STREAMING); + if (stm->offset < stm->bufsize) { + /* Claim the endpoint */ + TU_VERIFY( usbd_edpt_claim(rhport, ep_addr), 0); + uint_fast16_t pkt_len = _prepare_in_payload(stm); + TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm->ep_buf, pkt_len), 0); + } else { + stm->buffer = NULL; + stm->bufsize = 0; + stm->offset = 0; + if (tud_video_frame_xfer_complete_cb) { + tud_video_frame_xfer_complete_cb(stm->index_vc, stm->index_vs); + } + } + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/class/video/video_device.h b/circuitpython/lib/tinyusb/src/class/video/video_device.h new file mode 100644 index 0000000..ee2fcb9 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/class/video/video_device.h @@ -0,0 +1,97 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2021 Koji KITAYAMA + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_VIDEO_DEVICE_H_ +#define TUSB_VIDEO_DEVICE_H_ + +#include "common/tusb_common.h" +#include "video.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application API (Multiple Ports) +// CFG_TUD_VIDEO > 1 +//--------------------------------------------------------------------+ + +/** Return true if streaming + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index */ +bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); + +/** Transfer a frame + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index + * @param[in] buffer Frame buffer. The caller must not use this buffer until the operation is completed. + * @param[in] bufsize Byte size of the frame buffer */ +bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *buffer, size_t bufsize); + +/*------------- Optional callbacks -------------*/ +/** Invoked when compeletion of a frame transfer + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index */ +TU_ATTR_WEAK void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +/** Invoked when SET_POWER_MODE request received + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index + * @return video_error_code_t */ +TU_ATTR_WEAK int tud_video_power_mode_cb(uint_fast8_t ctl_idx, uint8_t power_mod); + +/** Invoked when VS_COMMIT_CONTROL(SET_CUR) request received + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index + * @param[in] parameters Video streaming parameters + * @return video_error_code_t */ +TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, + video_probe_and_commit_control_t const *parameters); + +//--------------------------------------------------------------------+ +// INTERNAL USBD-CLASS DRIVER API +//--------------------------------------------------------------------+ +void videod_init (void); +void videod_reset (uint8_t rhport); +uint16_t videod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool videod_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/common/tusb_common.h b/circuitpython/lib/tinyusb/src/common/tusb_common.h new file mode 100644 index 0000000..2686580 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_common.h @@ -0,0 +1,407 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_COMMON_H_ +#define _TUSB_COMMON_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Macros Helper +//--------------------------------------------------------------------+ +#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) +#define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) ) +#define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) ) + +#define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low))) +#define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff)) +#define TU_U16_LOW(_u16) ((uint8_t) ((_u16) & 0x00ff)) +#define U16_TO_U8S_BE(_u16) TU_U16_HIGH(_u16), TU_U16_LOW(_u16) +#define U16_TO_U8S_LE(_u16) TU_U16_LOW(_u16), TU_U16_HIGH(_u16) + +#define TU_U32_BYTE3(_u32) ((uint8_t) ((((uint32_t) _u32) >> 24) & 0x000000ff)) // MSB +#define TU_U32_BYTE2(_u32) ((uint8_t) ((((uint32_t) _u32) >> 16) & 0x000000ff)) +#define TU_U32_BYTE1(_u32) ((uint8_t) ((((uint32_t) _u32) >> 8) & 0x000000ff)) +#define TU_U32_BYTE0(_u32) ((uint8_t) (((uint32_t) _u32) & 0x000000ff)) // LSB + +#define U32_TO_U8S_BE(_u32) TU_U32_BYTE3(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE0(_u32) +#define U32_TO_U8S_LE(_u32) TU_U32_BYTE0(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE3(_u32) + +#define TU_BIT(n) (1UL << (n)) +#define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) ) + +//--------------------------------------------------------------------+ +// Includes +//--------------------------------------------------------------------+ + +// Standard Headers +#include +#include +#include +#include +#include + +// Tinyusb Common Headers +#include "tusb_option.h" +#include "tusb_compiler.h" +#include "tusb_verify.h" +#include "tusb_types.h" + +#include "tusb_error.h" // TODO remove +#include "tusb_timeout.h" // TODO remove + +//--------------------------------------------------------------------+ +// Internal Helper used by Host and Device Stack +//--------------------------------------------------------------------+ + +// Check if endpoint descriptor is valid per USB specs +bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed); + +// Bind all endpoint of a interface descriptor to class driver +void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* p_desc, uint16_t desc_len, uint8_t driver_id); + +// Calculate total length of n interfaces (depending on IAD) +uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); + +//--------------------------------------------------------------------+ +// Internal Inline Functions +//--------------------------------------------------------------------+ + +//------------- Mem -------------// +#define tu_memclr(buffer, size) memset((buffer), 0, (size)) +#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var))) + +//------------- Bytes -------------// +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) +{ + return ( ((uint32_t) b3) << 24) | ( ((uint32_t) b2) << 16) | ( ((uint32_t) b1) << 8) | b0; +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) +{ + return (uint16_t) ((((uint16_t) high) << 8) | low); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte3(uint32_t ui32) { return TU_U32_BYTE3(ui32); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t ui32) { return TU_U32_BYTE2(ui32); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t ui32) { return TU_U32_BYTE1(ui32); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t ui32) { return TU_U32_BYTE0(ui32); } + +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_high16(uint32_t ui32) { return (uint16_t) (ui32 >> 16); } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_low16 (uint32_t ui32) { return (uint16_t) (ui32 & 0x0000ffffu); } + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t ui16) { return TU_U16_HIGH(ui16); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t ui16) { return TU_U16_LOW(ui16); } + +//------------- Bits -------------// +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_set (uint32_t value, uint8_t pos) { return value | TU_BIT(pos); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_clear(uint32_t value, uint8_t pos) { return value & (~TU_BIT(pos)); } +TU_ATTR_ALWAYS_INLINE static inline bool tu_bit_test (uint32_t value, uint8_t pos) { return (value & TU_BIT(pos)) ? true : false; } + +//------------- Min -------------// +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_min8 (uint8_t x, uint8_t y ) { return (x < y) ? x : y; } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_min16 (uint16_t x, uint16_t y) { return (x < y) ? x : y; } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_min32 (uint32_t x, uint32_t y) { return (x < y) ? x : y; } + +//------------- Max -------------// +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_max8 (uint8_t x, uint8_t y ) { return (x > y) ? x : y; } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_max16 (uint16_t x, uint16_t y) { return (x > y) ? x : y; } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_max32 (uint32_t x, uint32_t y) { return (x > y) ? x : y; } + +//------------- Align -------------// +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment) +{ + return value & ((uint32_t) ~(alignment-1)); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align16 (uint32_t value) { return (value & 0xFFFFFFF0UL); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { return (value & 0xFFFFFFE0UL); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); } + +//------------- Mathematics -------------// +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; } + +/// inclusive range checking TODO remove +TU_ATTR_ALWAYS_INLINE static inline bool tu_within(uint32_t lower, uint32_t value, uint32_t upper) +{ + return (lower <= value) && (value <= upper); +} + +// log2 of a value is its MSB's position +// TODO use clz TODO remove +static inline uint8_t tu_log2(uint32_t value) +{ + uint8_t result = 0; + while (value >>= 1) { result++; } + return result; +} + +//------------- Unaligned Access -------------// +#if TUP_ARCH_STRICT_ALIGN + +// Rely on compiler to generate correct code for unaligned access +typedef struct { uint16_t val; } TU_ATTR_PACKED tu_unaligned_uint16_t; +typedef struct { uint32_t val; } TU_ATTR_PACKED tu_unaligned_uint32_t; + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void* mem) +{ + tu_unaligned_uint32_t const* ua32 = (tu_unaligned_uint32_t const*) mem; + return ua32->val; +} + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void* mem, uint32_t value) +{ + tu_unaligned_uint32_t* ua32 = (tu_unaligned_uint32_t*) mem; + ua32->val = value; +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void* mem) +{ + tu_unaligned_uint16_t const* ua16 = (tu_unaligned_uint16_t const*) mem; + return ua16->val; +} + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_t value) +{ + tu_unaligned_uint16_t* ua16 = (tu_unaligned_uint16_t*) mem; + ua16->val = value; +} + +#elif TUP_MCU_STRICT_ALIGN + +// MCU such as LPC_IP3511 Highspeed cannot access unaligned memory on USB_RAM although it is ARM M4. +// We have to manually pick up bytes since tu_unaligned_uint32_t will still generate unaligned code +// NOTE: volatile cast to memory to prevent compiler to optimize and generate unaligned code +// TODO Big Endian may need minor changes +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void* mem) +{ + volatile uint8_t const* buf8 = (uint8_t const*) mem; + return tu_u32(buf8[3], buf8[2], buf8[1], buf8[0]); +} + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void* mem, uint32_t value) +{ + volatile uint8_t* buf8 = (uint8_t*) mem; + buf8[0] = tu_u32_byte0(value); + buf8[1] = tu_u32_byte1(value); + buf8[2] = tu_u32_byte2(value); + buf8[3] = tu_u32_byte3(value); +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void* mem) +{ + volatile uint8_t const* buf8 = (uint8_t const*) mem; + return tu_u16(buf8[1], buf8[0]); +} + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_t value) +{ + volatile uint8_t* buf8 = (uint8_t*) mem; + buf8[0] = tu_u16_low(value); + buf8[1] = tu_u16_high(value); +} + + +#else + +// MCU that could access unaligned memory natively +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32 (const void* mem) { return *((uint32_t const *) mem); } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16 (const void* mem) { return *((uint16_t const *) mem); } + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32 (void* mem, uint32_t value ) { *((uint32_t*) mem) = value; } +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16 (void* mem, uint16_t value ) { *((uint16_t*) mem) = value; } + +#endif + +// To be removed +//------------- Binary constant -------------// +#if defined(__GNUC__) && !defined(__CC_ARM) + +#define TU_BIN8(x) ((uint8_t) (0b##x)) +#define TU_BIN16(b1, b2) ((uint16_t) (0b##b1##b2)) +#define TU_BIN32(b1, b2, b3, b4) ((uint32_t) (0b##b1##b2##b3##b4)) + +#else + +// internal macro of B8, B16, B32 +#define _B8__(x) (((x&0x0000000FUL)?1:0) \ + +((x&0x000000F0UL)?2:0) \ + +((x&0x00000F00UL)?4:0) \ + +((x&0x0000F000UL)?8:0) \ + +((x&0x000F0000UL)?16:0) \ + +((x&0x00F00000UL)?32:0) \ + +((x&0x0F000000UL)?64:0) \ + +((x&0xF0000000UL)?128:0)) + +#define TU_BIN8(d) ((uint8_t) _B8__(0x##d##UL)) +#define TU_BIN16(dmsb,dlsb) (((uint16_t)TU_BIN8(dmsb)<<8) + TU_BIN8(dlsb)) +#define TU_BIN32(dmsb,db2,db3,dlsb) \ + (((uint32_t)TU_BIN8(dmsb)<<24) \ + + ((uint32_t)TU_BIN8(db2)<<16) \ + + ((uint32_t)TU_BIN8(db3)<<8) \ + + TU_BIN8(dlsb)) +#endif + +//--------------------------------------------------------------------+ +// Debug Function +//--------------------------------------------------------------------+ + +// CFG_TUSB_DEBUG for debugging +// 0 : no debug +// 1 : print error +// 2 : print warning +// 3 : print info +#if CFG_TUSB_DEBUG + +void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); + +#ifdef CFG_TUSB_DEBUG_PRINTF + extern int CFG_TUSB_DEBUG_PRINTF(const char *format, ...); + #define tu_printf CFG_TUSB_DEBUG_PRINTF +#else + #define tu_printf printf +#endif + +static inline +void tu_print_var(uint8_t const* buf, uint32_t bufsize) +{ + for(uint32_t i=0; i= 2 + #define TU_LOG2 TU_LOG1 + #define TU_LOG2_MEM TU_LOG1_MEM + #define TU_LOG2_VAR TU_LOG1_VAR + #define TU_LOG2_INT TU_LOG1_INT + #define TU_LOG2_HEX TU_LOG1_HEX +#endif + +// Log Level 3: Info +#if CFG_TUSB_DEBUG >= 3 + #define TU_LOG3 TU_LOG1 + #define TU_LOG3_MEM TU_LOG1_MEM + #define TU_LOG3_VAR TU_LOG1_VAR + #define TU_LOG3_INT TU_LOG1_INT + #define TU_LOG3_HEX TU_LOG1_HEX +#endif + +typedef struct +{ + uint32_t key; + const char* data; +} tu_lookup_entry_t; + +typedef struct +{ + uint16_t count; + tu_lookup_entry_t const* items; +} tu_lookup_table_t; + +static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) +{ + static char not_found[11]; + + for(uint16_t i=0; icount; i++) + { + if (p_table->items[i].key == key) return p_table->items[i].data; + } + + // not found return the key value in hex + snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key); + + return not_found; +} + +#endif // CFG_TUSB_DEBUG + +#ifndef TU_LOG +#define TU_LOG(n, ...) +#define TU_LOG_MEM(n, ...) +#define TU_LOG_VAR(n, ...) +#define TU_LOG_INT(n, ...) +#define TU_LOG_HEX(n, ...) +#define TU_LOG_LOCATION() +#define TU_LOG_FAILED() +#endif + +// TODO replace all TU_LOGn with TU_LOG(n) + +#define TU_LOG0(...) +#define TU_LOG0_MEM(...) +#define TU_LOG0_VAR(...) +#define TU_LOG0_INT(...) +#define TU_LOG0_HEX(...) + + +#ifndef TU_LOG1 + #define TU_LOG1(...) + #define TU_LOG1_MEM(...) + #define TU_LOG1_VAR(...) + #define TU_LOG1_INT(...) + #define TU_LOG1_HEX(...) +#endif + +#ifndef TU_LOG2 + #define TU_LOG2(...) + #define TU_LOG2_MEM(...) + #define TU_LOG2_VAR(...) + #define TU_LOG2_INT(...) + #define TU_LOG2_HEX(...) +#endif + +#ifndef TU_LOG3 + #define TU_LOG3(...) + #define TU_LOG3_MEM(...) + #define TU_LOG3_VAR(...) + #define TU_LOG3_INT(...) + #define TU_LOG3_HEX(...) +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_COMMON_H_ */ diff --git a/circuitpython/lib/tinyusb/src/common/tusb_compiler.h b/circuitpython/lib/tinyusb/src/common/tusb_compiler.h new file mode 100644 index 0000000..ae00f4e --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_compiler.h @@ -0,0 +1,264 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup Group_Common + * \defgroup Group_Compiler Compiler + * \brief Group_Compiler brief + * @{ */ + +#ifndef _TUSB_COMPILER_H_ +#define _TUSB_COMPILER_H_ + +#define TU_TOKEN(x) x +#define TU_STRING(x) #x ///< stringify without expand +#define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify + +#define TU_STRCAT(a, b) a##b ///< concat without expand +#define TU_STRCAT3(a, b, c) a##b##c ///< concat without expand + +#define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat +#define TU_XSTRCAT3(a, b, c) TU_STRCAT3(a, b, c) ///< expand then concat 3 tokens + +#define TU_INCLUDE_PATH(_dir,_file) TU_XSTRING( TU_TOKEN(_dir)TU_TOKEN(_file) ) + +#if defined __COUNTER__ && __COUNTER__ != __COUNTER__ + #define _TU_COUNTER_ __COUNTER__ +#else + #define _TU_COUNTER_ __LINE__ +#endif + +// Compile-time Assert +#if defined (__cplusplus) && __cplusplus >= 201103L + #define TU_VERIFY_STATIC static_assert +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define TU_VERIFY_STATIC _Static_assert +#elif defined(__CCRX__) + #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(Line, __LINE__)[(const_expr) ? 1 : 0]; +#else + #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) } +#endif + +// for declaration of reserved field, make use of _TU_COUNTER_ +#define TU_RESERVED TU_XSTRCAT(reserved, _TU_COUNTER_) + +#define TU_LITTLE_ENDIAN (0x12u) +#define TU_BIG_ENDIAN (0x21u) + +/*------------------------------------------------------------------*/ +/* Count number of arguments of __VA_ARGS__ + * - reference https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments + * - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th) + * - _RSEQ_N() is reverse sequential to N to add padding to have + * Nth position is the same as the number of arguments + * - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma) + *------------------------------------------------------------------*/ +#if !defined(__CCRX__) +#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__,_RSEQ_N()) +#else +#define TU_ARGS_NUM(...) _TU_NARG(_0, __VA_ARGS__,_RSEQ_N()) +#endif + +#define _TU_NARG(...) _GET_NTH_ARG(__VA_ARGS__) +#define _GET_NTH_ARG( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63,N,...) N +#define _RSEQ_N() \ + 62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9,8,7,6,5,4,3,2,1,0 + +// Apply an macro X to each of the arguments with an separated of choice +#define TU_ARGS_APPLY(_X, _s, ...) TU_XSTRCAT(_TU_ARGS_APPLY_, TU_ARGS_NUM(__VA_ARGS__))(_X, _s, __VA_ARGS__) + +#define _TU_ARGS_APPLY_1(_X, _s, _a1) _X(_a1) +#define _TU_ARGS_APPLY_2(_X, _s, _a1, _a2) _X(_a1) _s _X(_a2) +#define _TU_ARGS_APPLY_3(_X, _s, _a1, _a2, _a3) _X(_a1) _s _TU_ARGS_APPLY_2(_X, _s, _a2, _a3) +#define _TU_ARGS_APPLY_4(_X, _s, _a1, _a2, _a3, _a4) _X(_a1) _s _TU_ARGS_APPLY_3(_X, _s, _a2, _a3, _a4) +#define _TU_ARGS_APPLY_5(_X, _s, _a1, _a2, _a3, _a4, _a5) _X(_a1) _s _TU_ARGS_APPLY_4(_X, _s, _a2, _a3, _a4, _a5) +#define _TU_ARGS_APPLY_6(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1) _s _TU_ARGS_APPLY_5(_X, _s, _a2, _a3, _a4, _a5, _a6) +#define _TU_ARGS_APPLY_7(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1) _s _TU_ARGS_APPLY_6(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7) +#define _TU_ARGS_APPLY_8(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1) _s _TU_ARGS_APPLY_7(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7, _a8) + +//--------------------------------------------------------------------+ +// Compiler porting with Attribute and Endian +//--------------------------------------------------------------------+ + +// TODO refactor since __attribute__ is supported across many compiler +#if defined(__GNUC__) + #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) + #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name))) + #define TU_ATTR_PACKED __attribute__ ((packed)) + #define TU_ATTR_WEAK __attribute__ ((weak)) + #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline)) + #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used + #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused + #define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used + + #define TU_ATTR_PACKED_BEGIN + #define TU_ATTR_PACKED_END + #define TU_ATTR_BIT_FIELD_ORDER_BEGIN + #define TU_ATTR_BIT_FIELD_ORDER_END + + // Endian conversion use well-known host to network (big endian) naming + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define TU_BYTE_ORDER TU_LITTLE_ENDIAN + #else + #define TU_BYTE_ORDER TU_BIG_ENDIAN + #endif + + #define TU_BSWAP16(u16) (__builtin_bswap16(u16)) + #define TU_BSWAP32(u32) (__builtin_bswap32(u32)) + + #ifndef __ARMCC_VERSION + // List of obsolete callback function that is renamed and should not be defined. + // Put it here since only gcc support this pragma + #pragma GCC poison tud_vendor_control_request_cb + #endif + +#elif defined(__TI_COMPILER_VERSION__) + #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) + #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name))) + #define TU_ATTR_PACKED __attribute__ ((packed)) + #define TU_ATTR_WEAK __attribute__ ((weak)) + #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline)) + #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used + #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused + #define TU_ATTR_USED __attribute__ ((used)) + + #define TU_ATTR_PACKED_BEGIN + #define TU_ATTR_PACKED_END + #define TU_ATTR_BIT_FIELD_ORDER_BEGIN + #define TU_ATTR_BIT_FIELD_ORDER_END + + // __BYTE_ORDER is defined in the TI ARM compiler, but not MSP430 (which is little endian) + #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) || defined(__MSP430__) + #define TU_BYTE_ORDER TU_LITTLE_ENDIAN + #else + #define TU_BYTE_ORDER TU_BIG_ENDIAN + #endif + + #define TU_BSWAP16(u16) (__builtin_bswap16(u16)) + #define TU_BSWAP32(u32) (__builtin_bswap32(u32)) + +#elif defined(__ICCARM__) + #include + #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) + #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name))) + #define TU_ATTR_PACKED __attribute__ ((packed)) + #define TU_ATTR_WEAK __attribute__ ((weak)) + #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline)) + #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used + #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused + #define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used + + #define TU_ATTR_PACKED_BEGIN + #define TU_ATTR_PACKED_END + #define TU_ATTR_BIT_FIELD_ORDER_BEGIN + #define TU_ATTR_BIT_FIELD_ORDER_END + + // Endian conversion use well-known host to network (big endian) naming + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define TU_BYTE_ORDER TU_LITTLE_ENDIAN + #else + #define TU_BYTE_ORDER TU_BIG_ENDIAN + #endif + + #define TU_BSWAP16(u16) (__iar_builtin_REV16(u16)) + #define TU_BSWAP32(u32) (__iar_builtin_REV(u32)) + +#elif defined(__CCRX__) + #define TU_ATTR_ALIGNED(Bytes) + #define TU_ATTR_SECTION(sec_name) + #define TU_ATTR_PACKED + #define TU_ATTR_WEAK + #define TU_ATTR_ALWAYS_INLINE + #define TU_ATTR_DEPRECATED(mess) + #define TU_ATTR_UNUSED + #define TU_ATTR_USED + + #define TU_ATTR_PACKED_BEGIN _Pragma("pack") + #define TU_ATTR_PACKED_END _Pragma("packoption") + #define TU_ATTR_BIT_FIELD_ORDER_BEGIN _Pragma("bit_order right") + #define TU_ATTR_BIT_FIELD_ORDER_END _Pragma("bit_order") + + // Endian conversion use well-known host to network (big endian) naming + #if defined(__LIT) + #define TU_BYTE_ORDER TU_LITTLE_ENDIAN + #else + #define TU_BYTE_ORDER TU_BIG_ENDIAN + #endif + + #define TU_BSWAP16(u16) ((unsigned short)_builtin_revw((unsigned long)u16)) + #define TU_BSWAP32(u32) (_builtin_revl(u32)) + +#else + #error "Compiler attribute porting is required" +#endif + +#if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN) + + #define tu_htons(u16) (TU_BSWAP16(u16)) + #define tu_ntohs(u16) (TU_BSWAP16(u16)) + + #define tu_htonl(u32) (TU_BSWAP32(u32)) + #define tu_ntohl(u32) (TU_BSWAP32(u32)) + + #define tu_htole16(u16) (u16) + #define tu_le16toh(u16) (u16) + + #define tu_htole32(u32) (u32) + #define tu_le32toh(u32) (u32) + +#elif (TU_BYTE_ORDER == TU_BIG_ENDIAN) + + #define tu_htons(u16) (u16) + #define tu_ntohs(u16) (u16) + + #define tu_htonl(u32) (u32) + #define tu_ntohl(u32) (u32) + + #define tu_htole16(u16) (TU_BSWAP16(u16)) + #define tu_le16toh(u16) (TU_BSWAP16(u16)) + + #define tu_htole32(u32) (TU_BSWAP32(u32)) + #define tu_le32toh(u32) (TU_BSWAP32(u32)) + +#else + #error Byte order is undefined +#endif + +#endif /* _TUSB_COMPILER_H_ */ + +/// @} diff --git a/circuitpython/lib/tinyusb/src/common/tusb_error.h b/circuitpython/lib/tinyusb/src/common/tusb_error.h new file mode 100644 index 0000000..42541ac --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_error.h @@ -0,0 +1,77 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup Group_Common + * \defgroup Group_Error Error Codes + * @{ */ + +#ifndef _TUSB_ERRORS_H_ +#define _TUSB_ERRORS_H_ + +#include "tusb_option.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define ERROR_ENUM(x) x, +#define ERROR_STRING(x) #x, + +#define ERROR_TABLE(ENTRY) \ + ENTRY(TUSB_ERROR_NONE )\ + ENTRY(TUSB_ERROR_INVALID_PARA )\ + ENTRY(TUSB_ERROR_DEVICE_NOT_READY )\ + ENTRY(TUSB_ERROR_INTERFACE_IS_BUSY )\ + ENTRY(TUSB_ERROR_HCD_OPEN_PIPE_FAILED )\ + ENTRY(TUSB_ERROR_OSAL_TIMEOUT )\ + ENTRY(TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED )\ + ENTRY(TUSB_ERROR_MSCH_DEVICE_NOT_MOUNTED )\ + ENTRY(TUSB_ERROR_NOT_SUPPORTED )\ + ENTRY(TUSB_ERROR_NOT_ENOUGH_MEMORY )\ + ENTRY(TUSB_ERROR_FAILED )\ + +/// \brief Error Code returned +/// TODO obsolete and to be remove +typedef enum +{ + ERROR_TABLE(ERROR_ENUM) + TUSB_ERROR_COUNT +}tusb_error_t; + +#if CFG_TUSB_DEBUG +/// Enum to String for debugging purposes. Only available if \ref CFG_TUSB_DEBUG > 0 +extern char const* const tusb_strerr[TUSB_ERROR_COUNT]; +extern char const* const tusb_speed_str[]; + +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_ERRORS_H_ */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/common/tusb_fifo.c b/circuitpython/lib/tinyusb/src/common/tusb_fifo.c new file mode 100644 index 0000000..183c9c6 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_fifo.c @@ -0,0 +1,1007 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2020 Reinhard Panhuber - rework to unmasked pointers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "osal/osal.h" +#include "tusb_fifo.h" + +// Supress IAR warning +// Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement +#if defined(__ICCARM__) +#pragma diag_suppress = Pa082 +#endif + +// implement mutex lock and unlock +#if CFG_FIFO_MUTEX + +static inline void _ff_lock(tu_fifo_mutex_t mutex) +{ + if (mutex) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); +} + +static inline void _ff_unlock(tu_fifo_mutex_t mutex) +{ + if (mutex) osal_mutex_unlock(mutex); +} + +#else + +#define _ff_lock(_mutex) +#define _ff_unlock(_mutex) + +#endif + +/** \enum tu_fifo_copy_mode_t + * \brief Write modes intended to allow special read and write functions to be able to + * copy data to and from USB hardware FIFOs as needed for e.g. STM32s and others + */ +typedef enum +{ + TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode + TU_FIFO_COPY_CST_FULL_WORDS, ///< Copy from/to a constant source/destination address - required for e.g. STM32 to write into USB hardware FIFO +} tu_fifo_copy_mode_t; + +bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) +{ + if (depth > 0x8000) return false; // Maximum depth is 2^15 items + + _ff_lock(f->mutex_wr); + _ff_lock(f->mutex_rd); + + f->buffer = (uint8_t*) buffer; + f->depth = depth; + f->item_size = item_size; + f->overwritable = overwritable; + + // Limit index space to 2*depth - this allows for a fast "modulo" calculation + // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable + // only if overflow happens once (important for unsupervised DMA applications) + f->max_pointer_idx = 2*depth - 1; + f->non_used_index_space = UINT16_MAX - f->max_pointer_idx; + + f->rd_idx = f->wr_idx = 0; + + _ff_unlock(f->mutex_wr); + _ff_unlock(f->mutex_rd); + + return true; +} + +// Static functions are intended to work on local variables +static inline uint16_t _ff_mod(uint16_t idx, uint16_t depth) +{ + while ( idx >= depth) idx -= depth; + return idx; +} + +// Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address +// Code adapted from dcd_synopsis.c +// TODO generalize with configurable 1 byte or 4 byte each read +static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t len) +{ + volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; + + // Reading full available 32 bit words from const app address + uint16_t full_words = len >> 2; + while(full_words--) + { + tu_unaligned_write32(ff_buf, *rx_fifo); + ff_buf += 4; + } + + // Read the remaining 1-3 bytes from const app address + uint8_t const bytes_rem = len & 0x03; + if ( bytes_rem ) + { + uint32_t tmp32 = *rx_fifo; + memcpy(ff_buf, &tmp32, bytes_rem); + } +} + +// Intended to be used to write to hardware USB FIFO in e.g. STM32 +// where all data is written to a constant address in full word copies +static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t len) +{ + volatile uint32_t * tx_fifo = (volatile uint32_t *) app_buf; + + // Pushing full available 32 bit words to const app address + uint16_t full_words = len >> 2; + while(full_words--) + { + *tx_fifo = tu_unaligned_read32(ff_buf); + ff_buf += 4; + } + + // Write the remaining 1-3 bytes into const app address + uint8_t const bytes_rem = len & 0x03; + if ( bytes_rem ) + { + uint32_t tmp32 = 0; + memcpy(&tmp32, ff_buf, bytes_rem); + + *tx_fifo = tmp32; + } +} + +// send one item to FIFO WITHOUT updating write pointer +static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) +{ + memcpy(f->buffer + (rel * f->item_size), app_buf, f->item_size); +} + +// send n items to FIFO WITHOUT updating write pointer +static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t rel, tu_fifo_copy_mode_t copy_mode) +{ + uint16_t const nLin = f->depth - rel; + uint16_t const nWrap = n - nLin; + + uint16_t nLin_bytes = nLin * f->item_size; + uint16_t nWrap_bytes = nWrap * f->item_size; + + // current buffer of fifo + uint8_t* ff_buf = f->buffer + (rel * f->item_size); + + switch (copy_mode) + { + case TU_FIFO_COPY_INC: + if(n <= nLin) + { + // Linear only + memcpy(ff_buf, app_buf, n*f->item_size); + } + else + { + // Wrap around + + // Write data to linear part of buffer + memcpy(ff_buf, app_buf, nLin_bytes); + + // Write data wrapped around + memcpy(f->buffer, ((uint8_t const*) app_buf) + nLin_bytes, nWrap_bytes); + } + break; + + case TU_FIFO_COPY_CST_FULL_WORDS: + // Intended for hardware buffers from which it can be read word by word only + if(n <= nLin) + { + // Linear only + _ff_push_const_addr(ff_buf, app_buf, n*f->item_size); + } + else + { + // Wrap around case + + // Write full words to linear part of buffer + uint16_t nLin_4n_bytes = nLin_bytes & 0xFFFC; + _ff_push_const_addr(ff_buf, app_buf, nLin_4n_bytes); + ff_buf += nLin_4n_bytes; + + // There could be odd 1-3 bytes before the wrap-around boundary + volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; + uint8_t rem = nLin_bytes & 0x03; + if (rem > 0) + { + uint8_t remrem = tu_min16(nWrap_bytes, 4-rem); + nWrap_bytes -= remrem; + + uint32_t tmp32 = *rx_fifo; + uint8_t * src_u8 = ((uint8_t *) &tmp32); + + // Write 1-3 bytes before wrapped boundary + while(rem--) *ff_buf++ = *src_u8++; + + // Read more bytes to beginning to complete a word + ff_buf = f->buffer; + while(remrem--) *ff_buf++ = *src_u8++; + } + else + { + ff_buf = f->buffer; // wrap around to beginning + } + + // Write data wrapped part + if (nWrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, nWrap_bytes); + } + break; + } +} + +// get one item from FIFO WITHOUT updating read pointer +static inline void _ff_pull(tu_fifo_t* f, void * app_buf, uint16_t rel) +{ + memcpy(app_buf, f->buffer + (rel * f->item_size), f->item_size); +} + +// get n items from FIFO WITHOUT updating read pointer +static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu_fifo_copy_mode_t copy_mode) +{ + uint16_t const nLin = f->depth - rel; + uint16_t const nWrap = n - nLin; // only used if wrapped + + uint16_t nLin_bytes = nLin * f->item_size; + uint16_t nWrap_bytes = nWrap * f->item_size; + + // current buffer of fifo + uint8_t* ff_buf = f->buffer + (rel * f->item_size); + + switch (copy_mode) + { + case TU_FIFO_COPY_INC: + if ( n <= nLin ) + { + // Linear only + memcpy(app_buf, ff_buf, n*f->item_size); + } + else + { + // Wrap around + + // Read data from linear part of buffer + memcpy(app_buf, ff_buf, nLin_bytes); + + // Read data wrapped part + memcpy((uint8_t*) app_buf + nLin_bytes, f->buffer, nWrap_bytes); + } + break; + + case TU_FIFO_COPY_CST_FULL_WORDS: + if ( n <= nLin ) + { + // Linear only + _ff_pull_const_addr(app_buf, ff_buf, n*f->item_size); + } + else + { + // Wrap around case + + // Read full words from linear part of buffer + uint16_t nLin_4n_bytes = nLin_bytes & 0xFFFC; + _ff_pull_const_addr(app_buf, ff_buf, nLin_4n_bytes); + ff_buf += nLin_4n_bytes; + + // There could be odd 1-3 bytes before the wrap-around boundary + volatile uint32_t * tx_fifo = (volatile uint32_t *) app_buf; + uint8_t rem = nLin_bytes & 0x03; + if (rem > 0) + { + uint8_t remrem = tu_min16(nWrap_bytes, 4-rem); + nWrap_bytes -= remrem; + + uint32_t tmp32=0; + uint8_t * dst_u8 = (uint8_t *)&tmp32; + + // Read 1-3 bytes before wrapped boundary + while(rem--) *dst_u8++ = *ff_buf++; + + // Read more bytes from beginning to complete a word + ff_buf = f->buffer; + while(remrem--) *dst_u8++ = *ff_buf++; + + *tx_fifo = tmp32; + } + else + { + ff_buf = f->buffer; // wrap around to beginning + } + + // Read data wrapped part + if (nWrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, nWrap_bytes); + } + break; + + default: break; + } +} + +// Advance an absolute pointer +static uint16_t advance_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) +{ + // We limit the index space of p such that a correct wrap around happens + // Check for a wrap around or if we are in unused index space - This has to be checked first!! + // We are exploiting the wrap around to the correct index + if ((p > (uint16_t)(p + offset)) || ((uint16_t)(p + offset) > f->max_pointer_idx)) + { + p = (p + offset) + f->non_used_index_space; + } + else + { + p += offset; + } + return p; +} + +// Backward an absolute pointer +static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) +{ + // We limit the index space of p such that a correct wrap around happens + // Check for a wrap around or if we are in unused index space - This has to be checked first!! + // We are exploiting the wrap around to the correct index + if ((p < (uint16_t)(p - offset)) || ((uint16_t)(p - offset) > f->max_pointer_idx)) + { + p = (p - offset) - f->non_used_index_space; + } + else + { + p -= offset; + } + return p; +} + +// get relative from absolute pointer +static uint16_t get_relative_pointer(tu_fifo_t* f, uint16_t p) +{ + return _ff_mod(p, f->depth); +} + +// Works on local copies of w and r - return only the difference and as such can be used to determine an overflow +static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) +{ + uint16_t cnt = wAbs-rAbs; + + // In case we have non-power of two depth we need a further modification + if (rAbs > wAbs) cnt -= f->non_used_index_space; + + return cnt; +} + +// Works on local copies of w and r +static inline bool _tu_fifo_empty(uint16_t wAbs, uint16_t rAbs) +{ + return wAbs == rAbs; +} + +// Works on local copies of w and r +static inline bool _tu_fifo_full(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) +{ + return (_tu_fifo_count(f, wAbs, rAbs) == f->depth); +} + +// Works on local copies of w and r +// BE AWARE - THIS FUNCTION MIGHT NOT GIVE A CORRECT ANSWERE IN CASE WRITE POINTER "OVERFLOWS" +// Only one overflow is allowed for this function to work e.g. if depth = 100, you must not +// write more than 2*depth-1 items in one rush without updating write pointer. Otherwise +// write pointer wraps and you pointer states are messed up. This can only happen if you +// use DMAs, write functions do not allow such an error. +static inline bool _tu_fifo_overflowed(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) +{ + return (_tu_fifo_count(f, wAbs, rAbs) > f->depth); +} + +// Works on local copies of w +// For more details see _tu_fifo_overflow()! +static inline void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wAbs) +{ + f->rd_idx = backward_pointer(f, wAbs, f->depth); +} + +// Works on local copies of w and r +// Must be protected by mutexes since in case of an overflow read pointer gets modified +static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wAbs, uint16_t rAbs) +{ + uint16_t cnt = _tu_fifo_count(f, wAbs, rAbs); + + // Check overflow and correct if required + if (cnt > f->depth) + { + _tu_fifo_correct_read_pointer(f, wAbs); + cnt = f->depth; + } + + // Skip beginning of buffer + if (cnt == 0) return false; + + uint16_t rRel = get_relative_pointer(f, rAbs); + + // Peek data + _ff_pull(f, p_buffer, rRel); + + return true; +} + +// Works on local copies of w and r +// Must be protected by mutexes since in case of an overflow read pointer gets modified +static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wAbs, uint16_t rAbs, tu_fifo_copy_mode_t copy_mode) +{ + uint16_t cnt = _tu_fifo_count(f, wAbs, rAbs); + + // Check overflow and correct if required + if (cnt > f->depth) + { + _tu_fifo_correct_read_pointer(f, wAbs); + rAbs = f->rd_idx; + cnt = f->depth; + } + + // Skip beginning of buffer + if (cnt == 0) return 0; + + // Check if we can read something at and after offset - if too less is available we read what remains + if (cnt < n) n = cnt; + + uint16_t rRel = get_relative_pointer(f, rAbs); + + // Peek data + _ff_pull_n(f, p_buffer, n, rRel, copy_mode); + + return n; +} + +// Works on local copies of w and r +static inline uint16_t _tu_fifo_remaining(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) +{ + return f->depth - _tu_fifo_count(f, wAbs, rAbs); +} + +static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu_fifo_copy_mode_t copy_mode) +{ + if ( n == 0 ) return 0; + + _ff_lock(f->mutex_wr); + + uint16_t w = f->wr_idx, r = f->rd_idx; + uint8_t const* buf8 = (uint8_t const*) data; + + if (!f->overwritable) + { + // Not overwritable limit up to full + n = tu_min16(n, _tu_fifo_remaining(f, w, r)); + } + else if (n >= f->depth) + { + // Only copy last part + buf8 = buf8 + (n - f->depth) * f->item_size; + n = f->depth; + + // We start writing at the read pointer's position since we fill the complete + // buffer and we do not want to modify the read pointer within a write function! + // This would end up in a race condition with read functions! + w = r; + } + + uint16_t wRel = get_relative_pointer(f, w); + + // Write data + _ff_push_n(f, buf8, n, wRel, copy_mode); + + // Advance pointer + f->wr_idx = advance_pointer(f, w, n); + + _ff_unlock(f->mutex_wr); + + return n; +} + +static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo_copy_mode_t copy_mode) +{ + _ff_lock(f->mutex_rd); + + // Peek the data + // f->rd_idx might get modified in case of an overflow so we can not use a local variable + n = _tu_fifo_peek_n(f, buffer, n, f->wr_idx, f->rd_idx, copy_mode); + + // Advance read pointer + f->rd_idx = advance_pointer(f, f->rd_idx, n); + + _ff_unlock(f->mutex_rd); + return n; +} + +/******************************************************************************/ +/*! + @brief Get number of items in FIFO. + + As this function only reads the read and write pointers once, this function is + reentrant and thus thread and ISR save without any mutexes. In case an + overflow occurred, this function return f.depth at maximum. Overflows are + checked and corrected for in the read functions! + + @param[in] f + Pointer to the FIFO buffer to manipulate + + @returns Number of items in FIFO + */ +/******************************************************************************/ +uint16_t tu_fifo_count(tu_fifo_t* f) +{ + return tu_min16(_tu_fifo_count(f, f->wr_idx, f->rd_idx), f->depth); +} + +/******************************************************************************/ +/*! + @brief Check if FIFO is empty. + + As this function only reads the read and write pointers once, this function is + reentrant and thus thread and ISR save without any mutexes. + + @param[in] f + Pointer to the FIFO buffer to manipulate + + @returns Number of items in FIFO + */ +/******************************************************************************/ +bool tu_fifo_empty(tu_fifo_t* f) +{ + return _tu_fifo_empty(f->wr_idx, f->rd_idx); +} + +/******************************************************************************/ +/*! + @brief Check if FIFO is full. + + As this function only reads the read and write pointers once, this function is + reentrant and thus thread and ISR save without any mutexes. + + @param[in] f + Pointer to the FIFO buffer to manipulate + + @returns Number of items in FIFO + */ +/******************************************************************************/ +bool tu_fifo_full(tu_fifo_t* f) +{ + return _tu_fifo_full(f, f->wr_idx, f->rd_idx); +} + +/******************************************************************************/ +/*! + @brief Get remaining space in FIFO. + + As this function only reads the read and write pointers once, this function is + reentrant and thus thread and ISR save without any mutexes. + + @param[in] f + Pointer to the FIFO buffer to manipulate + + @returns Number of items in FIFO + */ +/******************************************************************************/ +uint16_t tu_fifo_remaining(tu_fifo_t* f) +{ + return _tu_fifo_remaining(f, f->wr_idx, f->rd_idx); +} + +/******************************************************************************/ +/*! + @brief Check if overflow happened. + + BE AWARE - THIS FUNCTION MIGHT NOT GIVE A CORRECT ANSWERE IN CASE WRITE POINTER "OVERFLOWS" + Only one overflow is allowed for this function to work e.g. if depth = 100, you must not + write more than 2*depth-1 items in one rush without updating write pointer. Otherwise + write pointer wraps and your pointer states are messed up. This can only happen if you + use DMAs, write functions do not allow such an error. Avoid such nasty things! + + All reading functions (read, peek) check for overflows and correct read pointer on their own such + that latest items are read. + If required (e.g. for DMA use) you can also correct the read pointer by + tu_fifo_correct_read_pointer(). + + @param[in] f + Pointer to the FIFO buffer to manipulate + + @returns True if overflow happened + */ +/******************************************************************************/ +bool tu_fifo_overflowed(tu_fifo_t* f) +{ + return _tu_fifo_overflowed(f, f->wr_idx, f->rd_idx); +} + +// Only use in case tu_fifo_overflow() returned true! +void tu_fifo_correct_read_pointer(tu_fifo_t* f) +{ + _ff_lock(f->mutex_rd); + _tu_fifo_correct_read_pointer(f, f->wr_idx); + _ff_unlock(f->mutex_rd); +} + +/******************************************************************************/ +/*! + @brief Read one element out of the buffer. + + This function will return the element located at the array index of the + read pointer, and then increment the read pointer index. + This function checks for an overflow and corrects read pointer if required. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] buffer + Pointer to the place holder for data read from the buffer + + @returns TRUE if the queue is not empty + */ +/******************************************************************************/ +bool tu_fifo_read(tu_fifo_t* f, void * buffer) +{ + _ff_lock(f->mutex_rd); + + // Peek the data + // f->rd_idx might get modified in case of an overflow so we can not use a local variable + bool ret = _tu_fifo_peek(f, buffer, f->wr_idx, f->rd_idx); + + // Advance pointer + f->rd_idx = advance_pointer(f, f->rd_idx, ret); + + _ff_unlock(f->mutex_rd); + return ret; +} + +/******************************************************************************/ +/*! + @brief This function will read n elements from the array index specified by + the read pointer and increment the read index. + This function checks for an overflow and corrects read pointer if required. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] buffer + The pointer to data location + @param[in] n + Number of element that buffer can afford + + @returns number of items read from the FIFO + */ +/******************************************************************************/ +uint16_t tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n) +{ + return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_INC); +} + +uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint16_t n) +{ + return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_CST_FULL_WORDS); +} + +/******************************************************************************/ +/*! + @brief Read one item without removing it from the FIFO. + This function checks for an overflow and corrects read pointer if required. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] offset + Position to read from in the FIFO buffer with respect to read pointer + @param[in] p_buffer + Pointer to the place holder for data read from the buffer + + @returns TRUE if the queue is not empty + */ +/******************************************************************************/ +bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) +{ + _ff_lock(f->mutex_rd); + bool ret = _tu_fifo_peek(f, p_buffer, f->wr_idx, f->rd_idx); + _ff_unlock(f->mutex_rd); + return ret; +} + +/******************************************************************************/ +/*! + @brief Read n items without removing it from the FIFO + This function checks for an overflow and corrects read pointer if required. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] p_buffer + Pointer to the place holder for data read from the buffer + @param[in] n + Number of items to peek + + @returns Number of bytes written to p_buffer + */ +/******************************************************************************/ +uint16_t tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n) +{ + _ff_lock(f->mutex_rd); + uint16_t ret = _tu_fifo_peek_n(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_COPY_INC); + _ff_unlock(f->mutex_rd); + return ret; +} + +/******************************************************************************/ +/*! + @brief Write one element into the buffer. + + This function will write one element into the array index specified by + the write pointer and increment the write index. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] data + The byte to add to the FIFO + + @returns TRUE if the data was written to the FIFO (overwrittable + FIFO will always return TRUE) + */ +/******************************************************************************/ +bool tu_fifo_write(tu_fifo_t* f, const void * data) +{ + _ff_lock(f->mutex_wr); + + bool ret; + uint16_t const w = f->wr_idx; + + if ( _tu_fifo_full(f, w, f->rd_idx) && !f->overwritable ) + { + ret = false; + }else + { + uint16_t wRel = get_relative_pointer(f, w); + + // Write data + _ff_push(f, data, wRel); + + // Advance pointer + f->wr_idx = advance_pointer(f, w, 1); + + ret = true; + } + + _ff_unlock(f->mutex_wr); + + return ret; +} + +/******************************************************************************/ +/*! + @brief This function will write n elements into the array index specified by + the write pointer and increment the write index. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] data + The pointer to data to add to the FIFO + @param[in] count + Number of element + @return Number of written elements + */ +/******************************************************************************/ +uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n) +{ + return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_INC); +} + +/******************************************************************************/ +/*! + @brief This function will write n elements into the array index specified by + the write pointer and increment the write index. The source address will + not be incremented which is useful for reading from registers. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] data + The pointer to data to add to the FIFO + @param[in] count + Number of element + @return Number of written elements + */ +/******************************************************************************/ +uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t* f, const void * data, uint16_t n) +{ + return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_CST_FULL_WORDS); +} + +/******************************************************************************/ +/*! + @brief Clear the fifo read and write pointers + + @param[in] f + Pointer to the FIFO buffer to manipulate + */ +/******************************************************************************/ +bool tu_fifo_clear(tu_fifo_t *f) +{ + _ff_lock(f->mutex_wr); + _ff_lock(f->mutex_rd); + + f->rd_idx = f->wr_idx = 0; + f->max_pointer_idx = 2*f->depth-1; + f->non_used_index_space = UINT16_MAX - f->max_pointer_idx; + + _ff_unlock(f->mutex_wr); + _ff_unlock(f->mutex_rd); + return true; +} + +/******************************************************************************/ +/*! + @brief Change the fifo mode to overwritable or not overwritable + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] overwritable + Overwritable mode the fifo is set to + */ +/******************************************************************************/ +bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) +{ + _ff_lock(f->mutex_wr); + _ff_lock(f->mutex_rd); + + f->overwritable = overwritable; + + _ff_unlock(f->mutex_wr); + _ff_unlock(f->mutex_rd); + + return true; +} + +/******************************************************************************/ +/*! + @brief Advance write pointer - intended to be used in combination with DMA. + It is possible to fill the FIFO by use of a DMA in circular mode. Within + DMA ISRs you may update the write pointer to be able to read from the FIFO. + As long as the DMA is the only process writing into the FIFO this is safe + to use. + + USE WITH CARE - WE DO NOT CONDUCT SAFTY CHECKS HERE! + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] n + Number of items the write pointer moves forward + */ +/******************************************************************************/ +void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n) +{ + f->wr_idx = advance_pointer(f, f->wr_idx, n); +} + +/******************************************************************************/ +/*! + @brief Advance read pointer - intended to be used in combination with DMA. + It is possible to read from the FIFO by use of a DMA in linear mode. Within + DMA ISRs you may update the read pointer to be able to again write into the + FIFO. As long as the DMA is the only process reading from the FIFO this is + safe to use. + + USE WITH CARE - WE DO NOT CONDUCT SAFTY CHECKS HERE! + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] n + Number of items the read pointer moves forward + */ +/******************************************************************************/ +void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) +{ + f->rd_idx = advance_pointer(f, f->rd_idx, n); +} + +/******************************************************************************/ +/*! + @brief Get read info + + Returns the length and pointer from which bytes can be read in a linear manner. + This is of major interest for DMA transmissions. If returned length is zero the + corresponding pointer is invalid. + The read pointer does NOT get advanced, use tu_fifo_advance_read_pointer() to + do so! + @param[in] f + Pointer to FIFO + @param[out] *info + Pointer to struct which holds the desired infos + */ +/******************************************************************************/ +void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) +{ + // Operate on temporary values in case they change in between + uint16_t w = f->wr_idx, r = f->rd_idx; + + uint16_t cnt = _tu_fifo_count(f, w, r); + + // Check overflow and correct if required - may happen in case a DMA wrote too fast + if (cnt > f->depth) + { + _ff_lock(f->mutex_rd); + _tu_fifo_correct_read_pointer(f, w); + _ff_unlock(f->mutex_rd); + r = f->rd_idx; + cnt = f->depth; + } + + // Check if fifo is empty + if (cnt == 0) + { + info->len_lin = 0; + info->len_wrap = 0; + info->ptr_lin = NULL; + info->ptr_wrap = NULL; + return; + } + + // Get relative pointers + w = get_relative_pointer(f, w); + r = get_relative_pointer(f, r); + + // Copy pointer to buffer to start reading from + info->ptr_lin = &f->buffer[r]; + + // Check if there is a wrap around necessary + if (w > r) { + // Non wrapping case + info->len_lin = cnt; + info->len_wrap = 0; + info->ptr_wrap = NULL; + } + else + { + info->len_lin = f->depth - r; // Also the case if FIFO was full + info->len_wrap = cnt - info->len_lin; + info->ptr_wrap = f->buffer; + } +} + +/******************************************************************************/ +/*! + @brief Get linear write info + + Returns the length and pointer to which bytes can be written into FIFO in a linear manner. + This is of major interest for DMA transmissions not using circular mode. If a returned length is zero the + corresponding pointer is invalid. The returned lengths summed up are the currently free space in the FIFO. + The write pointer does NOT get advanced, use tu_fifo_advance_write_pointer() to do so! + TAKE CARE TO NOT OVERFLOW THE BUFFER MORE THAN TWO TIMES THE FIFO DEPTH - IT CAN NOT RECOVERE OTHERWISE! + @param[in] f + Pointer to FIFO + @param[out] *info + Pointer to struct which holds the desired infos + */ +/******************************************************************************/ +void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) +{ + uint16_t w = f->wr_idx, r = f->rd_idx; + uint16_t free = _tu_fifo_remaining(f, w, r); + + if (free == 0) + { + info->len_lin = 0; + info->len_wrap = 0; + info->ptr_lin = NULL; + info->ptr_wrap = NULL; + return; + } + + // Get relative pointers + w = get_relative_pointer(f, w); + r = get_relative_pointer(f, r); + + // Copy pointer to buffer to start writing to + info->ptr_lin = &f->buffer[w]; + + if (w < r) + { + // Non wrapping case + info->len_lin = r-w; + info->len_wrap = 0; + info->ptr_wrap = NULL; + } + else + { + info->len_lin = f->depth - w; + info->len_wrap = free - info->len_lin; // Remaining length - n already was limited to free or FIFO depth + info->ptr_wrap = f->buffer; // Always start of buffer + } +} diff --git a/circuitpython/lib/tinyusb/src/common/tusb_fifo.h b/circuitpython/lib/tinyusb/src/common/tusb_fifo.h new file mode 100644 index 0000000..18db289 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_fifo.h @@ -0,0 +1,151 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2020 Reinhard Panhuber - rework to unmasked pointers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_FIFO_H_ +#define _TUSB_FIFO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// Due to the use of unmasked pointers, this FIFO does not suffer from loosing +// one item slice. Furthermore, write and read operations are completely +// decoupled as write and read functions do not modify a common state. Henceforth, +// writing or reading from the FIFO within an ISR is safe as long as no other +// process (thread or ISR) interferes. +// Also, this FIFO is ready to be used in combination with a DMA as the write and +// read pointers can be updated from within a DMA ISR. Overflows are detectable +// within a certain number (see tu_fifo_overflow()). + +#include "common/tusb_common.h" + +// mutex is only needed for RTOS +// for OS None, we don't get preempted +#define CFG_FIFO_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) + +#if CFG_FIFO_MUTEX +#include "osal/osal.h" +#define tu_fifo_mutex_t osal_mutex_t +#endif + +typedef struct +{ + uint8_t* buffer ; ///< buffer pointer + uint16_t depth ; ///< max items + uint16_t item_size ; ///< size of each item + bool overwritable ; + + uint16_t non_used_index_space ; ///< required for non-power-of-two buffer length + uint16_t max_pointer_idx ; ///< maximum absolute pointer index + + volatile uint16_t wr_idx ; ///< write pointer + volatile uint16_t rd_idx ; ///< read pointer + +#if CFG_FIFO_MUTEX + tu_fifo_mutex_t mutex_wr; + tu_fifo_mutex_t mutex_rd; +#endif + +} tu_fifo_t; + +typedef struct +{ + uint16_t len_lin ; ///< linear length in item size + uint16_t len_wrap ; ///< wrapped length in item size + void * ptr_lin ; ///< linear part start pointer + void * ptr_wrap ; ///< wrapped part start pointer +} tu_fifo_buffer_info_t; + +#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ +{ \ + .buffer = _buffer, \ + .depth = _depth, \ + .item_size = sizeof(_type), \ + .overwritable = _overwritable, \ + .non_used_index_space = UINT16_MAX - (2*(_depth)-1), \ + .max_pointer_idx = 2*(_depth)-1, \ +} + +#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \ + uint8_t _name##_buf[_depth*sizeof(_type)]; \ + tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable) + + +bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable); +bool tu_fifo_clear(tu_fifo_t *f); +bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable); + +#if CFG_FIFO_MUTEX +TU_ATTR_ALWAYS_INLINE static inline +void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t write_mutex_hdl, tu_fifo_mutex_t read_mutex_hdl) +{ + f->mutex_wr = write_mutex_hdl; + f->mutex_rd = read_mutex_hdl; +} +#endif + +bool tu_fifo_write (tu_fifo_t* f, void const * p_data); +uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t n); +uint16_t tu_fifo_write_n_const_addr_full_words (tu_fifo_t* f, const void * data, uint16_t n); + +bool tu_fifo_read (tu_fifo_t* f, void * p_buffer); +uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t n); +uint16_t tu_fifo_read_n_const_addr_full_words (tu_fifo_t* f, void * buffer, uint16_t n); + +bool tu_fifo_peek (tu_fifo_t* f, void * p_buffer); +uint16_t tu_fifo_peek_n (tu_fifo_t* f, void * p_buffer, uint16_t n); + +uint16_t tu_fifo_count (tu_fifo_t* f); +uint16_t tu_fifo_remaining (tu_fifo_t* f); +bool tu_fifo_empty (tu_fifo_t* f); +bool tu_fifo_full (tu_fifo_t* f); +bool tu_fifo_overflowed (tu_fifo_t* f); +void tu_fifo_correct_read_pointer (tu_fifo_t* f); + +TU_ATTR_ALWAYS_INLINE static inline +uint16_t tu_fifo_depth(tu_fifo_t* f) +{ + return f->depth; +} + +// Pointer modifications intended to be used in combinations with DMAs. +// USE WITH CARE - NO SAFTY CHECKS CONDUCTED HERE! NOT MUTEX PROTECTED! +void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n); +void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n); + +// If you want to read/write from/to the FIFO by use of a DMA, you may need to conduct two copies +// to handle a possible wrapping part. These functions deliver a pointer to start +// reading/writing from/to and a valid linear length along which no wrap occurs. +void tu_fifo_get_read_info (tu_fifo_t *f, tu_fifo_buffer_info_t *info); +void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info); + + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_FIFO_H_ */ diff --git a/circuitpython/lib/tinyusb/src/common/tusb_mcu.h b/circuitpython/lib/tinyusb/src/common/tusb_mcu.h new file mode 100644 index 0000000..8eb4ad4 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_mcu.h @@ -0,0 +1,285 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_MCU_H_ +#define TUSB_MCU_H_ + +//--------------------------------------------------------------------+ +// Port Specific +// TUP stand for TinyUSB Port (can be renamed) +//--------------------------------------------------------------------+ + +//------------- Unaligned Memory Access -------------// + +// ARMv7+ (M3-M7, M23-M33) can access unaligned memory +#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) + #define TUP_ARCH_STRICT_ALIGN 0 +#else + #define TUP_ARCH_STRICT_ALIGN 1 +#endif + +/* USB Controller Attributes for Device, Host or MCU (both) + * - ENDPOINT_MAX: max (logical) number of endpoint + * - ENDPOINT_EXCLUSIVE_NUMBER: endpoint number with different direction IN and OUT aren't allowed, + * e.g EP1 OUT & EP1 IN cannot exist together + * - RHPORT_HIGHSPEED: mask to indicate which port support highspeed mode (without external PHY) + * bit0 for port0 and so on. + */ + +//------------- NXP -------------// +#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) + #define TUP_DCD_ENDPOINT_MAX 5 + +#elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_USBIP_OHCI + +#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) + // TODO USB0 has 6, USB1 has 4 + #define TUP_USBIP_CHIPIDEA_HS + #define TUP_USBIP_EHCI + + #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS + + +#elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) + #define TUP_DCD_ENDPOINT_MAX 5 + +#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) + // TODO USB0 has 5, USB1 has 6 + #define TUP_DCD_ENDPOINT_MAX 6 + +#elif TU_CHECK_MCU(OPT_MCU_LPC55XX) + // TODO USB0 has 5, USB1 has 6 + #define TUP_DCD_ENDPOINT_MAX 6 + +#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) + #define TUP_USBIP_CHIPIDEA_HS + #define TUP_USBIP_EHCI + + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS + + +#elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) + #define TUP_DCD_ENDPOINT_MAX 16 + +#elif TU_CHECK_MCU(OPT_MCU_MM32F327X) + #define TUP_DCD_ENDPOINT_MAX 16 + +//------------- Nordic -------------// +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) + // 8 CBI + 1 ISO + #define TUP_DCD_ENDPOINT_MAX 9 + +//------------- Microchip -------------// +#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \ + TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22) + #define TUP_DCD_ENDPOINT_MAX 8 + +#elif TU_CHECK_MCU(OPT_MCU_SAMG) + #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + +#elif TU_CHECK_MCU(OPT_MCU_SAMX7X) + #define TUP_DCD_ENDPOINT_MAX 10 + #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + +#elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + +//------------- ST -------------// +#elif TU_CHECK_MCU(OPT_MCU_STM32F0) + #define TUP_DCD_ENDPOINT_MAX 8 + +#elif TU_CHECK_MCU(OPT_MCU_STM32F1) + #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ + defined (STM32F107xB) || defined (STM32F107xC) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + #define TUP_DCD_ENDPOINT_MAX 4 + #else + #define TUP_DCD_ENDPOINT_MAX 8 + #endif + +#elif TU_CHECK_MCU(OPT_MCU_STM32F2) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + // FS has 4 ep, HS has 5 ep + #define TUP_DCD_ENDPOINT_MAX 6 + +#elif TU_CHECK_MCU(OPT_MCU_STM32F3) + #define TUP_DCD_ENDPOINT_MAX 8 + +#elif TU_CHECK_MCU(OPT_MCU_STM32F4) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 + #define TUP_DCD_ENDPOINT_MAX 6 + +#elif TU_CHECK_MCU(OPT_MCU_STM32F7) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + // FS has 6, HS has 9 + #define TUP_DCD_ENDPOINT_MAX 9 + + // MCU with on-chip HS Phy + #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) + #define TUP_RHPORT_HIGHSPEED 0x02 // Port 0: FS, Port 1: HS + #endif + +#elif TU_CHECK_MCU(OPT_MCU_STM32H7) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + #define TUP_DCD_ENDPOINT_MAX 9 + +#elif TU_CHECK_MCU(OPT_MCU_STM32G4) + #define TUP_DCD_ENDPOINT_MAX 8 + +#elif TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1) + #define TUP_DCD_ENDPOINT_MAX 8 + +#elif TU_CHECK_MCU(OPT_MCU_STM32L4) + #if defined (STM32L475xx) || defined (STM32L476xx) || \ + defined (STM32L485xx) || defined (STM32L486xx) || defined (STM32L496xx) || \ + defined (STM32L4A6xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \ + defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ + defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + #define TUP_DCD_ENDPOINT_MAX 6 + #else + #define TUP_DCD_ENDPOINT_MAX 8 + #endif + +#elif TU_CHECK_MCU(OPT_MCU_STM32WB) +#define TUP_DCD_ENDPOINT_MAX 8 + +//------------- Sony -------------// +#elif TU_CHECK_MCU(OPT_MCU_CXD56) + #define TUP_DCD_ENDPOINT_MAX 7 + #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + +//------------- TI -------------// +#elif TU_CHECK_MCU(OPT_MCU_MSP430x5xx) + #define TUP_DCD_ENDPOINT_MAX 8 + +#elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #define TUP_DCD_ENDPOINT_MAX 8 + +//------------- ValentyUSB -------------// +#elif TU_CHECK_MCU(OPT_MCU_VALENTYUSB_EPTRI) + #define TUP_DCD_ENDPOINT_MAX 16 + +//------------- Nuvoton -------------// +#elif TU_CHECK_MCU(OPT_MCU_NUC121, OPT_MCU_NUC126) + #define TUP_DCD_ENDPOINT_MAX 8 + +#elif TU_CHECK_MCU(OPT_MCU_NUC120) + #define TUP_DCD_ENDPOINT_MAX 6 + +#elif TU_CHECK_MCU(OPT_MCU_NUC505) + #define TUP_DCD_ENDPOINT_MAX 12 + #define TUP_RHPORT_HIGHSPEED 0x01 + +//------------- Espressif -------------// +#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 6 + +//------------- Dialog -------------// +#elif TU_CHECK_MCU(OPT_MCU_DA1469X) + #define TUP_DCD_ENDPOINT_MAX 4 + +//------------- Raspberry Pi -------------// +#elif TU_CHECK_MCU(OPT_MCU_RP2040) + #define TUP_DCD_ENDPOINT_MAX 16 + +//------------- Silabs -------------// +#elif TU_CHECK_MCU(OPT_MCU_EFM32GG) + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 7 + +//------------- Renesas -------------// +#elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) + #define TUP_DCD_ENDPOINT_MAX 10 + +//------------- GigaDevice -------------// +#elif TU_CHECK_MCU(OPT_MCU_GD32VF103) + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 4 + +//------------- Broadcom -------------// +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x01 + +//------------- Broadcom -------------// +#elif TU_CHECK_MCU(OPT_MCU_XMC4000) + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 8 + +//------------- BridgeTek -------------// +#elif TU_CHECK_MCU(OPT_MCU_FT90X) + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x01 + +#elif TU_CHECK_MCU(OPT_MCU_FT93X) + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_RHPORT_HIGHSPEED 0x01 + +//------------ Allwinner -------------// +#elif TU_CHECK_MCU(OPT_MCU_F1C100S) + #define TUP_DCD_ENDPOINT_MAX 4 + +#endif + +//--------------------------------------------------------------------+ +// Default Values +//--------------------------------------------------------------------+ + +#ifndef TUP_DCD_ENDPOINT_MAX + #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" + #define TUP_DCD_ENDPOINT_MAX 8 +#endif + +// Default to fullspeed if not defined +#ifndef TUP_RHPORT_HIGHSPEED + #define TUP_RHPORT_HIGHSPEED 0x00 +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/common/tusb_timeout.h b/circuitpython/lib/tinyusb/src/common/tusb_timeout.h new file mode 100644 index 0000000..ce53955 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_timeout.h @@ -0,0 +1,80 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup Group_Common Common Files + * \defgroup Group_TimeoutTimer timeout timer + * @{ */ + +#ifndef _TUSB_TIMEOUT_H_ +#define _TUSB_TIMEOUT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t start; + uint32_t interval; +}tu_timeout_t; + +#if 0 + +extern uint32_t tusb_hal_millis(void); + +static inline void tu_timeout_set(tu_timeout_t* tt, uint32_t msec) +{ + tt->interval = msec; + tt->start = tusb_hal_millis(); +} + +static inline bool tu_timeout_expired(tu_timeout_t* tt) +{ + return ( tusb_hal_millis() - tt->start ) >= tt->interval; +} + +// For used with periodic event to prevent drift +static inline void tu_timeout_reset(tu_timeout_t* tt) +{ + tt->start += tt->interval; +} + +static inline void tu_timeout_restart(tu_timeout_t* tt) +{ + tt->start = tusb_hal_millis(); +} + +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_TIMEOUT_H_ */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/common/tusb_types.h b/circuitpython/lib/tinyusb/src/common/tusb_types.h new file mode 100644 index 0000000..5b26f5a --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_types.h @@ -0,0 +1,546 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup group_usb_definitions + * \defgroup USBDef_Type USB Types + * @{ */ + +#ifndef _TUSB_TYPES_H_ +#define _TUSB_TYPES_H_ + +#include +#include +#include "tusb_compiler.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/*------------------------------------------------------------------*/ +/* CONSTANTS + *------------------------------------------------------------------*/ + +/// defined base on EHCI specs value for Endpoint Speed +typedef enum +{ + TUSB_SPEED_FULL = 0, + TUSB_SPEED_LOW = 1, + TUSB_SPEED_HIGH = 2, + TUSB_SPEED_INVALID = 0xff, +}tusb_speed_t; + +/// defined base on USB Specs Endpoint's bmAttributes +typedef enum +{ + TUSB_XFER_CONTROL = 0 , + TUSB_XFER_ISOCHRONOUS , + TUSB_XFER_BULK , + TUSB_XFER_INTERRUPT +}tusb_xfer_type_t; + +typedef enum +{ + TUSB_DIR_OUT = 0, + TUSB_DIR_IN = 1, + + TUSB_DIR_IN_MASK = 0x80 +}tusb_dir_t; + +/// Isochronous End Point Attributes +typedef enum +{ + TUSB_ISO_EP_ATT_NO_SYNC = 0x00, + TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, + TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, + TUSB_ISO_EP_ATT_SYNCHRONOUS = 0x0C, + TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point + TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point + TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback +}tusb_iso_ep_attribute_t; + +/// USB Descriptor Types +typedef enum +{ + TUSB_DESC_DEVICE = 0x01, + TUSB_DESC_CONFIGURATION = 0x02, + TUSB_DESC_STRING = 0x03, + TUSB_DESC_INTERFACE = 0x04, + TUSB_DESC_ENDPOINT = 0x05, + TUSB_DESC_DEVICE_QUALIFIER = 0x06, + TUSB_DESC_OTHER_SPEED_CONFIG = 0x07, + TUSB_DESC_INTERFACE_POWER = 0x08, + TUSB_DESC_OTG = 0x09, + TUSB_DESC_DEBUG = 0x0A, + TUSB_DESC_INTERFACE_ASSOCIATION = 0x0B, + + TUSB_DESC_BOS = 0x0F, + TUSB_DESC_DEVICE_CAPABILITY = 0x10, + + TUSB_DESC_FUNCTIONAL = 0x21, + + // Class Specific Descriptor + TUSB_DESC_CS_DEVICE = 0x21, + TUSB_DESC_CS_CONFIGURATION = 0x22, + TUSB_DESC_CS_STRING = 0x23, + TUSB_DESC_CS_INTERFACE = 0x24, + TUSB_DESC_CS_ENDPOINT = 0x25, + + TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30, + TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31 +}tusb_desc_type_t; + +typedef enum +{ + TUSB_REQ_GET_STATUS = 0 , + TUSB_REQ_CLEAR_FEATURE = 1 , + TUSB_REQ_RESERVED = 2 , + TUSB_REQ_SET_FEATURE = 3 , + TUSB_REQ_RESERVED2 = 4 , + TUSB_REQ_SET_ADDRESS = 5 , + TUSB_REQ_GET_DESCRIPTOR = 6 , + TUSB_REQ_SET_DESCRIPTOR = 7 , + TUSB_REQ_GET_CONFIGURATION = 8 , + TUSB_REQ_SET_CONFIGURATION = 9 , + TUSB_REQ_GET_INTERFACE = 10 , + TUSB_REQ_SET_INTERFACE = 11 , + TUSB_REQ_SYNCH_FRAME = 12 +}tusb_request_code_t; + +typedef enum +{ + TUSB_REQ_FEATURE_EDPT_HALT = 0, + TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1, + TUSB_REQ_FEATURE_TEST_MODE = 2 +}tusb_request_feature_selector_t; + +typedef enum +{ + TUSB_REQ_TYPE_STANDARD = 0, + TUSB_REQ_TYPE_CLASS, + TUSB_REQ_TYPE_VENDOR, + TUSB_REQ_TYPE_INVALID +} tusb_request_type_t; + +typedef enum +{ + TUSB_REQ_RCPT_DEVICE =0, + TUSB_REQ_RCPT_INTERFACE, + TUSB_REQ_RCPT_ENDPOINT, + TUSB_REQ_RCPT_OTHER +} tusb_request_recipient_t; + +// https://www.usb.org/defined-class-codes +typedef enum +{ + TUSB_CLASS_UNSPECIFIED = 0 , + TUSB_CLASS_AUDIO = 1 , + TUSB_CLASS_CDC = 2 , + TUSB_CLASS_HID = 3 , + TUSB_CLASS_RESERVED_4 = 4 , + TUSB_CLASS_PHYSICAL = 5 , + TUSB_CLASS_IMAGE = 6 , + TUSB_CLASS_PRINTER = 7 , + TUSB_CLASS_MSC = 8 , + TUSB_CLASS_HUB = 9 , + TUSB_CLASS_CDC_DATA = 10 , + TUSB_CLASS_SMART_CARD = 11 , + TUSB_CLASS_RESERVED_12 = 12 , + TUSB_CLASS_CONTENT_SECURITY = 13 , + TUSB_CLASS_VIDEO = 14 , + TUSB_CLASS_PERSONAL_HEALTHCARE = 15 , + TUSB_CLASS_AUDIO_VIDEO = 16 , + + TUSB_CLASS_DIAGNOSTIC = 0xDC , + TUSB_CLASS_WIRELESS_CONTROLLER = 0xE0 , + TUSB_CLASS_MISC = 0xEF , + TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE , + TUSB_CLASS_VENDOR_SPECIFIC = 0xFF +}tusb_class_code_t; + +typedef enum +{ + MISC_SUBCLASS_COMMON = 2 +}misc_subclass_type_t; + +typedef enum +{ + MISC_PROTOCOL_IAD = 1 +}misc_protocol_type_t; + +typedef enum +{ + APP_SUBCLASS_USBTMC = 0x03, + APP_SUBCLASS_DFU_RUNTIME = 0x01 +} app_subclass_type_t; + +typedef enum +{ + DEVICE_CAPABILITY_WIRELESS_USB = 0x01, + DEVICE_CAPABILITY_USB20_EXTENSION = 0x02, + DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03, + DEVICE_CAPABILITY_CONTAINER_id = 0x04, + DEVICE_CAPABILITY_PLATFORM = 0x05, + DEVICE_CAPABILITY_POWER_DELIVERY = 0x06, + DEVICE_CAPABILITY_BATTERY_INFO = 0x07, + DEVICE_CAPABILITY_PD_CONSUMER_PORT = 0x08, + DEVICE_CAPABILITY_PD_PROVIDER_PORT = 0x09, + DEVICE_CAPABILITY_SUPERSPEED_PLUS = 0x0A, + DEVICE_CAPABILITY_PRECESION_TIME_MEASUREMENT = 0x0B, + DEVICE_CAPABILITY_WIRELESS_USB_EXT = 0x0C, + DEVICE_CAPABILITY_BILLBOARD = 0x0D, + DEVICE_CAPABILITY_AUTHENTICATION = 0x0E, + DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F, + DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10 +}device_capability_type_t; + +enum { + TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = TU_BIT(5), + TUSB_DESC_CONFIG_ATT_SELF_POWERED = TU_BIT(6), +}; + +#define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) + +/// Device State TODO remove +typedef enum +{ + TUSB_DEVICE_STATE_UNPLUG = 0 , + TUSB_DEVICE_STATE_CONFIGURED , + TUSB_DEVICE_STATE_SUSPENDED , +}tusb_device_state_t; + +typedef enum +{ + XFER_RESULT_SUCCESS, + XFER_RESULT_FAILED, + XFER_RESULT_STALLED, +}xfer_result_t; + +enum // TODO remove +{ + DESC_OFFSET_LEN = 0, + DESC_OFFSET_TYPE = 1 +}; + +enum +{ + INTERFACE_INVALID_NUMBER = 0xff +}; + + +typedef enum +{ + MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00, + MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01, + MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02, + MS_OS_20_FEATURE_COMPATBLE_ID = 0x03, + MS_OS_20_FEATURE_REG_PROPERTY = 0x04, + MS_OS_20_FEATURE_MIN_RESUME_TIME = 0x05, + MS_OS_20_FEATURE_MODEL_ID = 0x06, + MS_OS_20_FEATURE_CCGP_DEVICE = 0x07, + MS_OS_20_FEATURE_VENDOR_REVISION = 0x08 +} microsoft_os_20_type_t; + +enum +{ + CONTROL_STAGE_SETUP, + CONTROL_STAGE_DATA, + CONTROL_STAGE_ACK +}; + +//--------------------------------------------------------------------+ +// USB Descriptors +//--------------------------------------------------------------------+ + +// Start of all packed definitions for compiler without per-type packed +TU_ATTR_PACKED_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN + +/// USB Device Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes. + uint8_t bDescriptorType ; ///< DEVICE Descriptor Type. + uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant. + + uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). \li If this field is reset to zero, each interface within a configuration specifies its own class information and the various interfaces operate independently. \li If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate independently. This value identifies the class definition used for the aggregate interfaces. \li If this field is set to FFH, the device class is vendor-specific. + uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass field. \li If the bDeviceClass field is reset to zero, this field must also be reset to zero. \li If the bDeviceClass field is not set to FFH, all values are reserved for assignment by the USB-IF. + uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass and the bDeviceSubClass fields. If a device supports class-specific protocols on a device basis as opposed to an interface basis, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use class-specific protocols on a device basis. However, it may use classspecific protocols on an interface basis. \li If this field is set to FFH, the device uses a vendor-specific protocol on a device basis. + uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64. + + uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF). + uint16_t idProduct ; ///< Product ID (assigned by the manufacturer). + uint16_t bcdDevice ; ///< Device release number in binary-coded decimal. + uint8_t iManufacturer ; ///< Index of string descriptor describing manufacturer. + uint8_t iProduct ; ///< Index of string descriptor describing product. + uint8_t iSerialNumber ; ///< Index of string descriptor describing the device's serial number. + + uint8_t bNumConfigurations ; ///< Number of possible configurations. +} tusb_desc_device_t; + +TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct"); + +// USB Binary Device Object Store (BOS) Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes + uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type + uint16_t wTotalLength ; ///< Total length of data returned for this descriptor + uint8_t bNumDeviceCaps ; ///< Number of device capability descriptors in the BOS +} tusb_desc_bos_t; + +TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct"); + +/// USB Configuration Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes + uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type + uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration. + + uint8_t bNumInterfaces ; ///< Number of interfaces supported by this configuration + uint8_t bConfigurationValue ; ///< Value to use as an argument to the SetConfiguration() request to select this configuration. + uint8_t iConfiguration ; ///< Index of string descriptor describing this configuration + uint8_t bmAttributes ; ///< Configuration characteristics \n D7: Reserved (set to one)\n D6: Self-powered \n D5: Remote Wakeup \n D4...0: Reserved (reset to zero) \n D7 is reserved and must be set to one for historical reasons. \n A device configuration that uses power from the bus and a local source reports a non-zero value in bMaxPower to indicate the amount of bus power required and sets D6. The actual power source at runtime may be determined using the GetStatus(DEVICE) request (see USB 2.0 spec Section 9.4.5). \n If a device configuration supports remote wakeup, D5 is set to one. + uint8_t bMaxPower ; ///< Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA). +} tusb_desc_configuration_t; + +TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9, "size is not correct"); + +/// USB Interface Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes + uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type + + uint8_t bInterfaceNumber ; ///< Number of this interface. Zero-based value identifying the index in the array of concurrent interfaces supported by this configuration. + uint8_t bAlternateSetting ; ///< Value used to select this alternate setting for the interface identified in the prior field + uint8_t bNumEndpoints ; ///< Number of endpoints used by this interface (excluding endpoint zero). If this value is zero, this interface only uses the Default Control Pipe. + uint8_t bInterfaceClass ; ///< Class code (assigned by the USB-IF). \li A value of zero is reserved for future standardization. \li If this field is set to FFH, the interface class is vendor-specific. \li All other values are reserved for assignment by the USB-IF. + uint8_t bInterfaceSubClass ; ///< Subclass code (assigned by the USB-IF). \n These codes are qualified by the value of the bInterfaceClass field. \li If the bInterfaceClass field is reset to zero, this field must also be reset to zero. \li If the bInterfaceClass field is not set to FFH, all values are reserved for assignment by the USB-IF. + uint8_t bInterfaceProtocol ; ///< Protocol code (assigned by the USB). \n These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. If an interface supports class-specific requests, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use a class-specific protocol on this interface. \li If this field is set to FFH, the device uses a vendor-specific protocol for this interface. + uint8_t iInterface ; ///< Index of string descriptor describing this interface +} tusb_desc_interface_t; + +TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct"); + +/// USB Endpoint Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; // Size of this descriptor in bytes + uint8_t bDescriptorType ; // ENDPOINT Descriptor Type + + uint8_t bEndpointAddress ; // The address of the endpoint + + struct TU_ATTR_PACKED { + uint8_t xfer : 2; // Control, ISO, Bulk, Interrupt + uint8_t sync : 2; // None, Asynchronous, Adaptive, Synchronous + uint8_t usage : 2; // Data, Feedback, Implicit feedback + uint8_t : 2; + } bmAttributes; + + uint16_t wMaxPacketSize ; // Bit 10..0 : max packet size, bit 12..11 additional transaction per highspeed micro-frame + uint8_t bInterval ; // Polling interval, in frames or microframes depending on the operating speed +} tusb_desc_endpoint_t; + +TU_VERIFY_STATIC( sizeof(tusb_desc_endpoint_t) == 7, "size is not correct"); + +/// USB Other Speed Configuration Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of descriptor + uint8_t bDescriptorType ; ///< Other_speed_Configuration Type + uint16_t wTotalLength ; ///< Total length of data returned + + uint8_t bNumInterfaces ; ///< Number of interfaces supported by this speed configuration + uint8_t bConfigurationValue ; ///< Value to use to select configuration + uint8_t iConfiguration ; ///< Index of string descriptor + uint8_t bmAttributes ; ///< Same as Configuration descriptor + uint8_t bMaxPower ; ///< Same as Configuration descriptor +} tusb_desc_other_speed_t; + +/// USB Device Qualifier Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of descriptor + uint8_t bDescriptorType ; ///< Device Qualifier Type + uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00) + + uint8_t bDeviceClass ; ///< Class Code + uint8_t bDeviceSubClass ; ///< SubClass Code + uint8_t bDeviceProtocol ; ///< Protocol Code + + uint8_t bMaxPacketSize0 ; ///< Maximum packet size for other speed + uint8_t bNumConfigurations ; ///< Number of Other-speed Configurations + uint8_t bReserved ; ///< Reserved for future use, must be zero +} tusb_desc_device_qualifier_t; + +TU_VERIFY_STATIC( sizeof(tusb_desc_device_qualifier_t) == 10, "size is not correct"); + +/// USB Interface Association Descriptor (IAD ECN) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of descriptor + uint8_t bDescriptorType ; ///< Other_speed_Configuration Type + + uint8_t bFirstInterface ; ///< Index of the first associated interface. + uint8_t bInterfaceCount ; ///< Total number of associated interfaces. + + uint8_t bFunctionClass ; ///< Interface class ID. + uint8_t bFunctionSubClass ; ///< Interface subclass ID. + uint8_t bFunctionProtocol ; ///< Interface protocol ID. + + uint8_t iFunction ; ///< Index of the string descriptor describing the interface association. +} tusb_desc_interface_assoc_t; + +// USB String Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength ; ///< Size of this descriptor in bytes + uint8_t bDescriptorType ; ///< Descriptor Type + uint16_t unicode_string[]; +} tusb_desc_string_t; + +// USB Binary Device Object Store (BOS) +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength; + uint8_t bDescriptorType ; + uint8_t bDevCapabilityType; + uint8_t bReserved; + uint8_t PlatformCapabilityUUID[16]; + uint8_t CapabilityData[]; +} tusb_desc_bos_platform_t; + +// USB WebuSB URL Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bScheme; + char url[]; +} tusb_desc_webusb_url_t; + +// DFU Functional Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength; + uint8_t bDescriptorType; + + union { + struct TU_ATTR_PACKED { + uint8_t bitCanDnload : 1; + uint8_t bitCanUpload : 1; + uint8_t bitManifestationTolerant : 1; + uint8_t bitWillDetach : 1; + uint8_t reserved : 4; + } bmAttributes; + + uint8_t bAttributes; + }; + + uint16_t wDetachTimeOut; + uint16_t wTransferSize; + uint16_t bcdDFUVersion; +} tusb_desc_dfu_functional_t; + +/*------------------------------------------------------------------*/ +/* Types + *------------------------------------------------------------------*/ +typedef struct TU_ATTR_PACKED{ + union { + struct TU_ATTR_PACKED { + uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. + uint8_t type : 2; ///< Request type tusb_request_type_t. + uint8_t direction : 1; ///< Direction type. tusb_dir_t + } bmRequestType_bit; + + uint8_t bmRequestType; + }; + + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} tusb_control_request_t; + +TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct"); + + +TU_ATTR_PACKED_END // End of all packed definitions +TU_ATTR_BIT_FIELD_ORDER_END + +//--------------------------------------------------------------------+ +// Endpoint helper +//--------------------------------------------------------------------+ + +// Get direction from Endpoint address +static inline tusb_dir_t tu_edpt_dir(uint8_t addr) +{ + return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; +} + +// Get Endpoint number from address +static inline uint8_t tu_edpt_number(uint8_t addr) +{ + return (uint8_t)(addr & (~TUSB_DIR_IN_MASK)); +} + +static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) +{ + return (uint8_t)(num | (dir ? TUSB_DIR_IN_MASK : 0)); +} + +static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) +{ + return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); +} + +//--------------------------------------------------------------------+ +// Descriptor helper +//--------------------------------------------------------------------+ +static inline uint8_t const * tu_desc_next(void const* desc) +{ + uint8_t const* desc8 = (uint8_t const*) desc; + return desc8 + desc8[DESC_OFFSET_LEN]; +} + +static inline uint8_t tu_desc_type(void const* desc) +{ + return ((uint8_t const*) desc)[DESC_OFFSET_TYPE]; +} + +static inline uint8_t tu_desc_len(void const* desc) +{ + return ((uint8_t const*) desc)[DESC_OFFSET_LEN]; +} + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_TYPES_H_ */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/common/tusb_verify.h b/circuitpython/lib/tinyusb/src/common/tusb_verify.h new file mode 100644 index 0000000..8fef11d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/common/tusb_verify.h @@ -0,0 +1,181 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ +#ifndef TUSB_VERIFY_H_ +#define TUSB_VERIFY_H_ + +#include +#include +#include "tusb_option.h" +#include "tusb_compiler.h" + +/*------------------------------------------------------------------*/ +/* This file use an advanced macro technique to mimic the default parameter + * as C++ for the sake of code simplicity. Beware of a headache macro + * manipulation that you are told to stay away. + * + * This contains macros for both VERIFY and ASSERT: + * + * VERIFY: Used when there is an error condition which is not the + * fault of the MCU. For example, bounds checking on data + * sent to the micro over USB should use this function. + * Another example is checking for buffer overflows, where + * returning from the active function causes a NAK. + * + * ASSERT: Used for error conditions that are caused by MCU firmware + * bugs. This is used to discover bugs in the code more + * quickly. One example would be adding assertions in library + * function calls to confirm a function's (untainted) + * parameters are valid. + * + * The difference in behavior is that ASSERT triggers a breakpoint while + * verify does not. + * + * #define TU_VERIFY(cond) if(cond) return false; + * #define TU_VERIFY(cond,ret) if(cond) return ret; + * + * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;} + * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;} + * + * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} + * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} + * + *------------------------------------------------------------------*/ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TU_VERIFY Helper +//--------------------------------------------------------------------+ + +#if CFG_TUSB_DEBUG + #include + #define _MESS_ERR(_err) tu_printf("%s %d: failed, error = %s\r\n", __func__, __LINE__, tusb_strerr[_err]) + #define _MESS_FAILED() tu_printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) +#else + #define _MESS_ERR(_err) do {} while (0) + #define _MESS_FAILED() do {} while (0) +#endif + +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) + #define TU_BREAKPOINT() do \ + { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */ \ + } while(0) + +#elif defined(__riscv) + #define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0) + +#else + #define TU_BREAKPOINT() do {} while (0) +#endif + +/*------------------------------------------------------------------*/ +/* Macro Generator + *------------------------------------------------------------------*/ + +// Helper to implement optional parameter for TU_VERIFY Macro family +#define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 +#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4 + +/*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/ +#define TU_VERIFY_DEFINE(_cond, _handler, _ret) do \ +{ \ + if ( !(_cond) ) { _handler; return _ret; } \ +} while(0) + +/*------------------------------------------------------------------*/ +/* TU_VERIFY + * - TU_VERIFY_1ARGS : return false if failed + * - TU_VERIFY_2ARGS : return provided value if failed + *------------------------------------------------------------------*/ +#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false) +#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret) + +#define TU_VERIFY(...) GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__) + + +/*------------------------------------------------------------------*/ +/* TU_VERIFY WITH HANDLER + * - TU_VERIFY_HDLR_2ARGS : execute handler, return false if failed + * - TU_VERIFY_HDLR_3ARGS : execute handler, return provided error if failed + *------------------------------------------------------------------*/ +#define TU_VERIFY_HDLR_2ARGS(_cond, _handler) TU_VERIFY_DEFINE(_cond, _handler, false) +#define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret) TU_VERIFY_DEFINE(_cond, _handler, _ret) + +#define TU_VERIFY_HDLR(...) GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__) + +/*------------------------------------------------------------------*/ +/* ASSERT + * basically TU_VERIFY with TU_BREAKPOINT() as handler + * - 1 arg : return false if failed + * - 2 arg : return error if failed + *------------------------------------------------------------------*/ +#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), false) +#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret) + +#ifndef TU_ASSERT +#define TU_ASSERT(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__) +#endif + +// TODO remove TU_ASSERT_ERR() later + +/*------------- Generator for TU_VERIFY_ERR and TU_VERIFY_ERR_HDLR -------------*/ +#define TU_VERIFY_ERR_DEF2(_error, _handler) do \ +{ \ + uint32_t _err = (uint32_t)(_error); \ + if ( 0 != _err ) { _MESS_ERR(_err); _handler; return _err; } \ +} while(0) + +#define TU_VERIFY_ERR_DEF3(_error, _handler, _ret) do \ +{ \ + uint32_t _err = (uint32_t)(_error); \ + if ( 0 != _err ) { _MESS_ERR(_err); _handler; return _ret; } \ +} while(0) + +/*------------------------------------------------------------------*/ +/* ASSERT Error + * basically TU_VERIFY Error with TU_BREAKPOINT() as handler + *------------------------------------------------------------------*/ +#define ASSERT_ERR_1ARGS(_error) TU_VERIFY_ERR_DEF2(_error, TU_BREAKPOINT()) +#define ASSERT_ERR_2ARGS(_error, _ret) TU_VERIFY_ERR_DEF3(_error, TU_BREAKPOINT(), _ret) + +#ifndef TU_ASSERT_ERR +#define TU_ASSERT_ERR(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_ERR_2ARGS, ASSERT_ERR_1ARGS,UNUSED)(__VA_ARGS__) +#endif + +/*------------------------------------------------------------------*/ +/* ASSERT HDLR + *------------------------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif /* TUSB_VERIFY_H_ */ diff --git a/circuitpython/lib/tinyusb/src/device/dcd.h b/circuitpython/lib/tinyusb/src/device/dcd.h new file mode 100644 index 0000000..8efbc90 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/device/dcd.h @@ -0,0 +1,192 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_DCD_H_ +#define _TUSB_DCD_H_ + +#include "common/tusb_common.h" +#include "osal/osal.h" +#include "common/tusb_fifo.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Configuration +//--------------------------------------------------------------------+ + +#ifndef CFG_TUD_ENDPPOINT_MAX + #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +typedef enum +{ + DCD_EVENT_INVALID = 0, + DCD_EVENT_BUS_RESET, + DCD_EVENT_UNPLUGGED, + DCD_EVENT_SOF, + DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support + DCD_EVENT_RESUME, + + DCD_EVENT_SETUP_RECEIVED, + DCD_EVENT_XFER_COMPLETE, + + // Not an DCD event, just a convenient way to defer ISR function + USBD_EVENT_FUNC_CALL, + + DCD_EVENT_COUNT +} dcd_eventid_t; + +typedef struct TU_ATTR_ALIGNED(4) +{ + uint8_t rhport; + uint8_t event_id; + + union + { + // BUS RESET + struct { + tusb_speed_t speed; + } bus_reset; + + // SETUP_RECEIVED + tusb_control_request_t setup_received; + + // XFER_COMPLETE + struct { + uint8_t ep_addr; + uint8_t result; + uint32_t len; + }xfer_complete; + + // FUNC_CALL + struct { + void (*func) (void*); + void* param; + }func_call; + }; +} dcd_event_t; + +//TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +// Initialize controller to device mode +void dcd_init (uint8_t rhport); + +// Interrupt Handler +#if __GNUC__ && !defined(__ARMCC_VERSION) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif +void dcd_int_handler(uint8_t rhport); +#if __GNUC__ && !defined(__ARMCC_VERSION) +#pragma GCC diagnostic pop +#endif + +// Enable device interrupt +void dcd_int_enable (uint8_t rhport); + +// Disable device interrupt +void dcd_int_disable(uint8_t rhport); + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr); + +// Wake up host +void dcd_remote_wakeup(uint8_t rhport); + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) TU_ATTR_WEAK; + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK; + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); + +// Close all non-control endpoints, cancel all pending transfers if any. +// Invoked when switching from a non-zero Configuration by SET_CONFIGURE therefore +// required for multiple configuration support. +void dcd_edpt_close_all (uint8_t rhport); + +// Close an endpoint. +// Since it is weak, caller must TU_ASSERT this function's existence before calling it. +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); + +// Submit an transfer using fifo, When complete dcd_event_xfer_complete() is invoked to notify the stack +// This API is optional, may be useful for register-based for transferring data. +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) TU_ATTR_WEAK; + +// Stall endpoint, any queuing transfer should be removed from endpoint +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); + +// clear stall, data toggle is also reset to DATA0 +// This API never calls with control endpoints, since it is auto cleared when receiving setup packet +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); + +//--------------------------------------------------------------------+ +// Event API (implemented by stack) +//--------------------------------------------------------------------+ + +// Called by DCD to notify device stack +extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); + +// helper to send bus signal event +extern void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr); + +// helper to send bus reset event +extern void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr); + +// helper to send setup received +extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr); + +// helper to send transfer complete event +extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_DCD_H_ */ diff --git a/circuitpython/lib/tinyusb/src/device/usbd.c b/circuitpython/lib/tinyusb/src/device/usbd.c new file mode 100644 index 0000000..7926689 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/device/usbd.c @@ -0,0 +1,1430 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED + +#include "tusb.h" +#include "device/usbd.h" +#include "device/usbd_pvt.h" +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// USBD Configuration +//--------------------------------------------------------------------+ + +// Debug level of USBD +#define USBD_DBG 2 + +#ifndef CFG_TUD_TASK_QUEUE_SZ + #define CFG_TUD_TASK_QUEUE_SZ 16 +#endif + +//--------------------------------------------------------------------+ +// Device Data +//--------------------------------------------------------------------+ + +// Invalid driver ID in itf2drv[] ep2drv[][] mapping +enum { DRVID_INVALID = 0xFFu }; + +typedef struct +{ + struct TU_ATTR_PACKED + { + volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; + volatile uint8_t suspended : 1; + + uint8_t remote_wakeup_en : 1; // enable/disable by host + uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute + uint8_t self_powered : 1; // configuration descriptor's attribute + }; + + volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) + uint8_t speed; + + uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) + uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) + + struct TU_ATTR_PACKED + { + volatile bool busy : 1; + volatile bool stalled : 1; + volatile bool claimed : 1; + + // TODO merge ep2drv here, 4-bit should be sufficient + }ep_status[CFG_TUD_ENDPPOINT_MAX][2]; + +}usbd_device_t; + +static usbd_device_t _usbd_dev; + +//--------------------------------------------------------------------+ +// Class Driver +//--------------------------------------------------------------------+ +#if CFG_TUSB_DEBUG >= 2 + #define DRIVER_NAME(_name) .name = _name, +#else + #define DRIVER_NAME(_name) +#endif + +// Built-in class drivers +static usbd_class_driver_t const _usbd_driver[] = +{ + #if CFG_TUD_CDC + { + DRIVER_NAME("CDC") + .init = cdcd_init, + .reset = cdcd_reset, + .open = cdcd_open, + .control_xfer_cb = cdcd_control_xfer_cb, + .xfer_cb = cdcd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_MSC + { + DRIVER_NAME("MSC") + .init = mscd_init, + .reset = mscd_reset, + .open = mscd_open, + .control_xfer_cb = mscd_control_xfer_cb, + .xfer_cb = mscd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_HID + { + DRIVER_NAME("HID") + .init = hidd_init, + .reset = hidd_reset, + .open = hidd_open, + .control_xfer_cb = hidd_control_xfer_cb, + .xfer_cb = hidd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_AUDIO + { + DRIVER_NAME("AUDIO") + .init = audiod_init, + .reset = audiod_reset, + .open = audiod_open, + .control_xfer_cb = audiod_control_xfer_cb, + .xfer_cb = audiod_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_VIDEO + { + DRIVER_NAME("VIDEO") + .init = videod_init, + .reset = videod_reset, + .open = videod_open, + .control_xfer_cb = videod_control_xfer_cb, + .xfer_cb = videod_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_MIDI + { + DRIVER_NAME("MIDI") + .init = midid_init, + .open = midid_open, + .reset = midid_reset, + .control_xfer_cb = midid_control_xfer_cb, + .xfer_cb = midid_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_VENDOR + { + DRIVER_NAME("VENDOR") + .init = vendord_init, + .reset = vendord_reset, + .open = vendord_open, + .control_xfer_cb = tud_vendor_control_xfer_cb, + .xfer_cb = vendord_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_USBTMC + { + DRIVER_NAME("TMC") + .init = usbtmcd_init_cb, + .reset = usbtmcd_reset_cb, + .open = usbtmcd_open_cb, + .control_xfer_cb = usbtmcd_control_xfer_cb, + .xfer_cb = usbtmcd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_DFU_RUNTIME + { + DRIVER_NAME("DFU-RUNTIME") + .init = dfu_rtd_init, + .reset = dfu_rtd_reset, + .open = dfu_rtd_open, + .control_xfer_cb = dfu_rtd_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL + }, + #endif + + #if CFG_TUD_DFU + { + DRIVER_NAME("DFU") + .init = dfu_moded_init, + .reset = dfu_moded_reset, + .open = dfu_moded_open, + .control_xfer_cb = dfu_moded_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL + }, + #endif + + #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM + { + DRIVER_NAME("NET") + .init = netd_init, + .reset = netd_reset, + .open = netd_open, + .control_xfer_cb = netd_control_xfer_cb, + .xfer_cb = netd_xfer_cb, + .sof = NULL, + }, + #endif + + #if CFG_TUD_BTH + { + DRIVER_NAME("BTH") + .init = btd_init, + .reset = btd_reset, + .open = btd_open, + .control_xfer_cb = btd_control_xfer_cb, + .xfer_cb = btd_xfer_cb, + .sof = NULL + }, + #endif +}; + +enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; + +// Additional class drivers implemented by application +static usbd_class_driver_t const * _app_driver = NULL; +static uint8_t _app_driver_count = 0; + +// virtually joins built-in and application drivers together. +// Application is positioned first to allow overwriting built-in ones. +static inline usbd_class_driver_t const * get_driver(uint8_t drvid) +{ + // Application drivers + if ( usbd_app_driver_get_cb ) + { + if ( drvid < _app_driver_count ) return &_app_driver[drvid]; + drvid -= _app_driver_count; + } + + // Built-in drivers + if (drvid < BUILTIN_DRIVER_COUNT) return &_usbd_driver[drvid]; + + return NULL; +} + +#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) + +//--------------------------------------------------------------------+ +// DCD Event +//--------------------------------------------------------------------+ + +enum { RHPORT_INVALID = 0xFFu }; +static uint8_t _usbd_rhport = RHPORT_INVALID; + +// Event queue +// OPT_MODE_DEVICE is used by OS NONE for mutex (disable usb isr) +OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); +static osal_queue_t _usbd_q; + +// Mutex for claiming endpoint, only needed when using with preempted RTOS +#if CFG_TUSB_OS != OPT_OS_NONE +static osal_mutex_def_t _ubsd_mutexdef; +static osal_mutex_t _usbd_mutex; +#endif + + +//--------------------------------------------------------------------+ +// Prototypes +//--------------------------------------------------------------------+ +static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); +static bool process_set_config(uint8_t rhport, uint8_t cfg_num); +static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); + +// from usbd_control.c +void usbd_control_reset(void); +void usbd_control_set_request(tusb_control_request_t const *request); +void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ); +bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + + +//--------------------------------------------------------------------+ +// Debug +//--------------------------------------------------------------------+ +#if CFG_TUSB_DEBUG >= 2 +static char const* const _usbd_event_str[DCD_EVENT_COUNT] = +{ + "Invalid" , + "Bus Reset" , + "Unplugged" , + "SOF" , + "Suspend" , + "Resume" , + "Setup Received" , + "Xfer Complete" , + "Func Call" +}; + +static char const* const _tusb_std_request_str[] = +{ + "Get Status" , + "Clear Feature" , + "Reserved" , + "Set Feature" , + "Reserved" , + "Set Address" , + "Get Descriptor" , + "Set Descriptor" , + "Get Configuration" , + "Set Configuration" , + "Get Interface" , + "Set Interface" , + "Synch Frame" +}; + +// for usbd_control to print the name of control complete driver +void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) +{ + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) + { + usbd_class_driver_t const * driver = get_driver(i); + if ( driver->control_xfer_cb == callback ) + { + TU_LOG2(" %s control complete\r\n", driver->name); + return; + } + } +} + +#endif + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ +tusb_speed_t tud_speed_get(void) +{ + return (tusb_speed_t) _usbd_dev.speed; +} + +bool tud_connected(void) +{ + return _usbd_dev.connected; +} + +bool tud_mounted(void) +{ + return _usbd_dev.cfg_num ? true : false; +} + +bool tud_suspended(void) +{ + return _usbd_dev.suspended; +} + +bool tud_remote_wakeup(void) +{ + // only wake up host if this feature is supported and enabled and we are suspended + TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en ); + dcd_remote_wakeup(_usbd_rhport); + return true; +} + +bool tud_disconnect(void) +{ + TU_VERIFY(dcd_disconnect); + dcd_disconnect(_usbd_rhport); + return true; +} + +bool tud_connect(void) +{ + TU_VERIFY(dcd_connect); + dcd_connect(_usbd_rhport); + return true; +} + +//--------------------------------------------------------------------+ +// USBD Task +//--------------------------------------------------------------------+ +bool tud_inited(void) +{ + return _usbd_rhport != RHPORT_INVALID; +} + +bool tud_init (uint8_t rhport) +{ + // skip if already initialized + if ( tud_inited() ) return true; + + TU_LOG2("USBD init\r\n"); + TU_LOG2_INT(sizeof(usbd_device_t)); + + tu_varclr(&_usbd_dev); + +#if CFG_TUSB_OS != OPT_OS_NONE + // Init device mutex + _usbd_mutex = osal_mutex_create(&_ubsd_mutexdef); + TU_ASSERT(_usbd_mutex); +#endif + + // Init device queue & task + _usbd_q = osal_queue_create(&_usbd_qdef); + TU_ASSERT(_usbd_q); + + // Get application driver if available + if ( usbd_app_driver_get_cb ) + { + _app_driver = usbd_app_driver_get_cb(&_app_driver_count); + } + + // Init class drivers + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) + { + usbd_class_driver_t const * driver = get_driver(i); + TU_LOG2("%s init\r\n", driver->name); + driver->init(); + } + + // Init device controller driver + dcd_init(rhport); + dcd_int_enable(rhport); + + _usbd_rhport = rhport; + + return true; +} + +static void configuration_reset(uint8_t rhport) +{ + for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) + { + get_driver(i)->reset(rhport); + } + + tu_varclr(&_usbd_dev); + memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping + memset(_usbd_dev.ep2drv , DRVID_INVALID, sizeof(_usbd_dev.ep2drv )); // invalid mapping +} + +static void usbd_reset(uint8_t rhport) +{ + configuration_reset(rhport); + usbd_control_reset(); +} + +bool tud_task_event_ready(void) +{ + // Skip if stack is not initialized + if ( !tusb_inited() ) return false; + + return !osal_queue_empty(_usbd_q); +} + +/* USB Device Driver task + * This top level thread manages all device controller event and delegates events to class-specific drivers. + * This should be called periodically within the mainloop or rtos thread. + * + @code + int main(void) + { + application_init(); + tusb_init(); + + while(1) // the mainloop + { + application_code(); + tud_task(); // tinyusb device task + } + } + @endcode + */ +void tud_task (void) +{ + // Skip if stack is not initialized + if ( !tusb_inited() ) return; + + // Loop until there is no more events in the queue + while (1) + { + dcd_event_t event; + + if ( !osal_queue_receive(_usbd_q, &event) ) return; + +#if CFG_TUSB_DEBUG >= 2 + if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG2("\r\n"); // extra line for setup + TU_LOG2("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); +#endif + + switch ( event.event_id ) + { + case DCD_EVENT_BUS_RESET: + TU_LOG2(": %s Speed\r\n", tusb_speed_str[event.bus_reset.speed]); + usbd_reset(event.rhport); + _usbd_dev.speed = event.bus_reset.speed; + break; + + case DCD_EVENT_UNPLUGGED: + TU_LOG2("\r\n"); + usbd_reset(event.rhport); + + // invoke callback + if (tud_umount_cb) tud_umount_cb(); + break; + + case DCD_EVENT_SETUP_RECEIVED: + TU_LOG2_VAR(&event.setup_received); + TU_LOG2("\r\n"); + + // Mark as connected after receiving 1st setup packet. + // But it is easier to set it every time instead of wasting time to check then set + _usbd_dev.connected = 1; + + // mark both in & out control as free + _usbd_dev.ep_status[0][TUSB_DIR_OUT].busy = false; + _usbd_dev.ep_status[0][TUSB_DIR_OUT].claimed = 0; + _usbd_dev.ep_status[0][TUSB_DIR_IN ].busy = false; + _usbd_dev.ep_status[0][TUSB_DIR_IN ].claimed = 0; + + // Process control request + if ( !process_control_request(event.rhport, &event.setup_received) ) + { + TU_LOG2(" Stall EP0\r\n"); + // Failed -> stall both control endpoint IN and OUT + dcd_edpt_stall(event.rhport, 0); + dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK); + } + break; + + case DCD_EVENT_XFER_COMPLETE: + { + // Invoke the class callback associated with the endpoint address + uint8_t const ep_addr = event.xfer_complete.ep_addr; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); + + TU_LOG2("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len); + + _usbd_dev.ep_status[epnum][ep_dir].busy = false; + _usbd_dev.ep_status[epnum][ep_dir].claimed = 0; + + if ( 0 == epnum ) + { + usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t)event.xfer_complete.result, event.xfer_complete.len); + } + else + { + usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] ); + TU_ASSERT(driver, ); + + TU_LOG2(" %s xfer callback\r\n", driver->name); + driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t)event.xfer_complete.result, event.xfer_complete.len); + } + } + break; + + case DCD_EVENT_SUSPEND: + // NOTE: When plugging/unplugging device, the D+/D- state are unstable and + // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ), which result in a series of event + // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected + if ( _usbd_dev.connected ) + { + TU_LOG2(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en); + if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en); + }else + { + TU_LOG2(" Skipped\r\n"); + } + break; + + case DCD_EVENT_RESUME: + if ( _usbd_dev.connected ) + { + TU_LOG2("\r\n"); + if (tud_resume_cb) tud_resume_cb(); + }else + { + TU_LOG2(" Skipped\r\n"); + } + break; + + case DCD_EVENT_SOF: + TU_LOG2("\r\n"); + for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) + { + usbd_class_driver_t const * driver = get_driver(i); + if ( driver->sof ) driver->sof(event.rhport); + } + break; + + case USBD_EVENT_FUNC_CALL: + TU_LOG2("\r\n"); + if ( event.func_call.func ) event.func_call.func(event.func_call.param); + break; + + default: + TU_BREAKPOINT(); + break; + } + } +} + +//--------------------------------------------------------------------+ +// Control Request Parser & Handling +//--------------------------------------------------------------------+ + +// Helper to invoke class driver control request handler +static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request) +{ + usbd_control_set_complete_callback(driver->control_xfer_cb); + TU_LOG2(" %s control request\r\n", driver->name); + return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request); +} + +// This handles the actual request and its response. +// return false will cause its caller to stall control endpoint +static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request) +{ + usbd_control_set_complete_callback(NULL); + + TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID); + + // Vendor request + if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) + { + TU_VERIFY(tud_vendor_control_xfer_cb); + + usbd_control_set_complete_callback(tud_vendor_control_xfer_cb); + return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request); + } + +#if CFG_TUSB_DEBUG >= 2 + if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) + { + TU_LOG2(" %s", _tusb_std_request_str[p_request->bRequest]); + if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG2("\r\n"); + } +#endif + + switch ( p_request->bmRequestType_bit.recipient ) + { + //------------- Device Requests e.g in enumeration -------------// + case TUSB_REQ_RCPT_DEVICE: + if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) + { + uint8_t const itf = tu_u16_low(p_request->wIndex); + TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); + + usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]); + TU_VERIFY(driver); + + // forward to class driver: "non-STD request to Interface" + return invoke_class_control(rhport, driver, p_request); + } + + if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) + { + // Non standard request is not supported + TU_BREAKPOINT(); + return false; + } + + switch ( p_request->bRequest ) + { + case TUSB_REQ_SET_ADDRESS: + // Depending on mcu, status phase could be sent either before or after changing device address, + // or even require stack to not response with status at all + // Therefore DCD must take full responsibility to response and include zlp status packet if needed. + usbd_control_set_request(p_request); // set request since DCD has no access to tud_control_status() API + dcd_set_address(rhport, (uint8_t) p_request->wValue); + // skip tud_control_status() + _usbd_dev.addressed = 1; + break; + + case TUSB_REQ_GET_CONFIGURATION: + { + uint8_t cfg_num = _usbd_dev.cfg_num; + tud_control_xfer(rhport, p_request, &cfg_num, 1); + } + break; + + case TUSB_REQ_SET_CONFIGURATION: + { + uint8_t const cfg_num = (uint8_t) p_request->wValue; + + // Only process if new configure is different + if (_usbd_dev.cfg_num != cfg_num) + { + if ( _usbd_dev.cfg_num ) + { + // already configured: need to clear all endpoints and driver first + TU_LOG(USBD_DBG, " Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num); + + // close all non-control endpoints, cancel all pending transfers if any + dcd_edpt_close_all(rhport); + + // close all drivers and current configured state except bus speed + uint8_t const speed = _usbd_dev.speed; + configuration_reset(rhport); + + _usbd_dev.speed = speed; // restore speed + } + + // switch to new configuration if not zero + if ( cfg_num ) TU_ASSERT( process_set_config(rhport, cfg_num) ); + } + + _usbd_dev.cfg_num = cfg_num; + tud_control_status(rhport, p_request); + } + break; + + case TUSB_REQ_GET_DESCRIPTOR: + TU_VERIFY( process_get_descriptor(rhport, p_request) ); + break; + + case TUSB_REQ_SET_FEATURE: + // Only support remote wakeup for device feature + TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue); + + TU_LOG(USBD_DBG, " Enable Remote Wakeup\r\n"); + + // Host may enable remote wake up before suspending especially HID device + _usbd_dev.remote_wakeup_en = true; + tud_control_status(rhport, p_request); + break; + + case TUSB_REQ_CLEAR_FEATURE: + // Only support remote wakeup for device feature + TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue); + + TU_LOG(USBD_DBG, " Disable Remote Wakeup\r\n"); + + // Host may disable remote wake up after resuming + _usbd_dev.remote_wakeup_en = false; + tud_control_status(rhport, p_request); + break; + + case TUSB_REQ_GET_STATUS: + { + // Device status bit mask + // - Bit 0: Self Powered + // - Bit 1: Remote Wakeup enabled + uint16_t status = (_usbd_dev.self_powered ? 1 : 0) | (_usbd_dev.remote_wakeup_en ? 2 : 0); + tud_control_xfer(rhport, p_request, &status, 2); + } + break; + + // Unknown/Unsupported request + default: TU_BREAKPOINT(); return false; + } + break; + + //------------- Class/Interface Specific Request -------------// + case TUSB_REQ_RCPT_INTERFACE: + { + uint8_t const itf = tu_u16_low(p_request->wIndex); + TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); + + usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]); + TU_VERIFY(driver); + + // all requests to Interface (STD or Class) is forwarded to class driver. + // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE + if ( !invoke_class_control(rhport, driver, p_request) ) + { + // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class + // driver doesn't use alternate settings or implement this + TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type); + + switch(p_request->bRequest) + { + case TUSB_REQ_GET_INTERFACE: + case TUSB_REQ_SET_INTERFACE: + // Clear complete callback if driver set since it can also stall the request. + usbd_control_set_complete_callback(NULL); + + if (TUSB_REQ_GET_INTERFACE == p_request->bRequest) + { + uint8_t alternate = 0; + tud_control_xfer(rhport, p_request, &alternate, 1); + }else + { + tud_control_status(rhport, p_request); + } + break; + + default: return false; + } + } + } + break; + + //------------- Endpoint Request -------------// + case TUSB_REQ_RCPT_ENDPOINT: + { + uint8_t const ep_addr = tu_u16_low(p_request->wIndex); + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); + + TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) ); + + usbd_class_driver_t const * driver = get_driver(_usbd_dev.ep2drv[ep_num][ep_dir]); + + if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) + { + // Forward class request to its driver + TU_VERIFY(driver); + return invoke_class_control(rhport, driver, p_request); + } + else + { + // Handle STD request to endpoint + switch ( p_request->bRequest ) + { + case TUSB_REQ_GET_STATUS: + { + uint16_t status = usbd_edpt_stalled(rhport, ep_addr) ? 0x0001 : 0x0000; + tud_control_xfer(rhport, p_request, &status, 2); + } + break; + + case TUSB_REQ_CLEAR_FEATURE: + case TUSB_REQ_SET_FEATURE: + { + if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) + { + if ( TUSB_REQ_CLEAR_FEATURE == p_request->bRequest ) + { + usbd_edpt_clear_stall(rhport, ep_addr); + }else + { + usbd_edpt_stall(rhport, ep_addr); + } + } + + if (driver) + { + // Some classes such as USBTMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request + // We will also forward std request targeted endpoint to class drivers as well + + // STD request must always be ACKed regardless of driver returned value + // Also clear complete callback if driver set since it can also stall the request. + (void) invoke_class_control(rhport, driver, p_request); + usbd_control_set_complete_callback(NULL); + + // skip ZLP status if driver already did that + if ( !_usbd_dev.ep_status[0][TUSB_DIR_IN].busy ) tud_control_status(rhport, p_request); + } + } + break; + + // Unknown/Unsupported request + default: TU_BREAKPOINT(); return false; + } + } + } + break; + + // Unknown recipient + default: TU_BREAKPOINT(); return false; + } + + return true; +} + +// Process Set Configure Request +// This function parse configuration descriptor & open drivers accordingly +static bool process_set_config(uint8_t rhport, uint8_t cfg_num) +{ + // index is cfg_num-1 + tusb_desc_configuration_t const * desc_cfg = (tusb_desc_configuration_t const *) tud_descriptor_configuration_cb(cfg_num-1); + TU_ASSERT(desc_cfg != NULL && desc_cfg->bDescriptorType == TUSB_DESC_CONFIGURATION); + + // Parse configuration descriptor + _usbd_dev.remote_wakeup_support = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP) ? 1 : 0; + _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED ) ? 1 : 0; + + // Parse interface descriptor + uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t); + uint8_t const * desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); + + while( p_desc < desc_end ) + { + uint8_t assoc_itf_count = 1; + + // Class will always starts with Interface Association (if any) and then Interface descriptor + if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) + { + tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; + assoc_itf_count = desc_iad->bInterfaceCount; + + p_desc = tu_desc_next(p_desc); // next to Interface + + // IAD's first interface number and class should match with opened interface + //TU_ASSERT(desc_iad->bFirstInterface == desc_itf->bInterfaceNumber && + // desc_iad->bFunctionClass == desc_itf->bInterfaceClass); + } + + TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); + tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc; + + // Find driver for this interface + uint16_t const remaining_len = desc_end-p_desc; + uint8_t drv_id; + for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) + { + usbd_class_driver_t const *driver = get_driver(drv_id); + uint16_t const drv_len = driver->open(rhport, desc_itf, remaining_len); + + if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) ) + { + // Open successfully + TU_LOG2(" %s opened\r\n", driver->name); + + // Some drivers use 2 or more interfaces but may not have IAD e.g MIDI (always) or + // BTH (even CDC) with class in device descriptor (single interface) + if ( assoc_itf_count == 1) + { + #if CFG_TUD_CDC + if ( driver->open == cdcd_open ) assoc_itf_count = 2; + #endif + + #if CFG_TUD_MIDI + if ( driver->open == midid_open ) assoc_itf_count = 2; + #endif + + #if CFG_TUD_BTH && CFG_TUD_BTH_ISO_ALT_COUNT + if ( driver->open == btd_open ) assoc_itf_count = 2; + #endif + } + + // bind (associated) interfaces to found driver + for(uint8_t i=0; ibInterfaceNumber+i; + + // Interface number must not be used already + TU_ASSERT(DRVID_INVALID == _usbd_dev.itf2drv[itf_num]); + _usbd_dev.itf2drv[itf_num] = drv_id; + } + + // bind all endpoints to found driver + tu_edpt_bind_driver(_usbd_dev.ep2drv, desc_itf, drv_len, drv_id); + + // next Interface + p_desc += drv_len; + + break; // exit driver find loop + } + } + + // Failed if there is no supported drivers + TU_ASSERT(drv_id < TOTAL_DRIVER_COUNT); + } + + // invoke callback + if (tud_mount_cb) tud_mount_cb(); + + return true; +} + +// return descriptor's buffer and update desc_len +static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request) +{ + tusb_desc_type_t const desc_type = (tusb_desc_type_t) tu_u16_high(p_request->wValue); + uint8_t const desc_index = tu_u16_low( p_request->wValue ); + + switch(desc_type) + { + case TUSB_DESC_DEVICE: + { + TU_LOG2(" Device\r\n"); + + void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb(); + + // Only response with exactly 1 Packet if: not addressed and host requested more data than device descriptor has. + // This only happens with the very first get device descriptor and EP0 size = 8 or 16. + if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed && + ((tusb_control_request_t const*) p_request)->wLength > sizeof(tusb_desc_device_t)) + { + // Hack here: we modify the request length to prevent usbd_control response with zlp + // since we are responding with 1 packet & less data than wLength. + tusb_control_request_t mod_request = *p_request; + mod_request.wLength = CFG_TUD_ENDPOINT0_SIZE; + + return tud_control_xfer(rhport, &mod_request, desc_device, CFG_TUD_ENDPOINT0_SIZE); + }else + { + return tud_control_xfer(rhport, p_request, desc_device, sizeof(tusb_desc_device_t)); + } + } + // break; // unreachable + + case TUSB_DESC_BOS: + { + TU_LOG2(" BOS\r\n"); + + // requested by host if USB > 2.0 ( i.e 2.1 or 3.x ) + if (!tud_descriptor_bos_cb) return false; + + uintptr_t desc_bos = (uintptr_t) tud_descriptor_bos_cb(); + TU_ASSERT(desc_bos); + + // Use offsetof to avoid pointer to the odd/misaligned address + uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_bos + offsetof(tusb_desc_bos_t, wTotalLength))) ); + + return tud_control_xfer(rhport, p_request, (void*) desc_bos, total_len); + } + // break; // unreachable + + case TUSB_DESC_CONFIGURATION: + case TUSB_DESC_OTHER_SPEED_CONFIG: + { + uintptr_t desc_config; + + if ( desc_type == TUSB_DESC_CONFIGURATION ) + { + TU_LOG2(" Configuration[%u]\r\n", desc_index); + desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index); + }else + { + // Host only request this after getting Device Qualifier descriptor + TU_LOG2(" Other Speed Configuration\r\n"); + TU_VERIFY( tud_descriptor_other_speed_configuration_cb ); + desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index); + } + + TU_ASSERT(desc_config); + + // Use offsetof to avoid pointer to the odd/misaligned address + uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))) ); + + return tud_control_xfer(rhport, p_request, (void*) desc_config, total_len); + } + // break; // unreachable + + case TUSB_DESC_STRING: + { + TU_LOG2(" String[%u]\r\n", desc_index); + + // String Descriptor always uses the desc set from user + uint8_t const* desc_str = (uint8_t const*) tud_descriptor_string_cb(desc_index, tu_le16toh(p_request->wIndex)); + TU_VERIFY(desc_str); + + // first byte of descriptor is its size + return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_str, tu_desc_len(desc_str)); + } + // break; // unreachable + + case TUSB_DESC_DEVICE_QUALIFIER: + { + TU_LOG2(" Device Qualifier\r\n"); + + TU_VERIFY( tud_descriptor_device_qualifier_cb ); + + uint8_t const* desc_qualifier = tud_descriptor_device_qualifier_cb(); + TU_VERIFY(desc_qualifier); + + // first byte of descriptor is its size + return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_qualifier, tu_desc_len(desc_qualifier)); + } + // break; // unreachable + + default: return false; + } +} + +//--------------------------------------------------------------------+ +// DCD Event Handler +//--------------------------------------------------------------------+ +void dcd_event_handler(dcd_event_t const * event, bool in_isr) +{ + switch (event->event_id) + { + case DCD_EVENT_UNPLUGGED: + _usbd_dev.connected = 0; + _usbd_dev.addressed = 0; + _usbd_dev.cfg_num = 0; + _usbd_dev.suspended = 0; + osal_queue_send(_usbd_q, event, in_isr); + break; + + case DCD_EVENT_SUSPEND: + // NOTE: When plugging/unplugging device, the D+/D- state are unstable and + // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ). + // In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish + // suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected + if ( _usbd_dev.connected ) + { + _usbd_dev.suspended = 1; + osal_queue_send(_usbd_q, event, in_isr); + } + break; + + case DCD_EVENT_RESUME: + // skip event if not connected (especially required for SAMD) + if ( _usbd_dev.connected ) + { + _usbd_dev.suspended = 0; + osal_queue_send(_usbd_q, event, in_isr); + } + break; + + case DCD_EVENT_SOF: + // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup + // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational + if ( _usbd_dev.suspended ) + { + _usbd_dev.suspended = 0; + dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME }; + osal_queue_send(_usbd_q, &event_resume, in_isr); + } + break; + + default: + osal_queue_send(_usbd_q, event, in_isr); + break; + } +} + +void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = eid }; + dcd_event_handler(&event, in_isr); +} + +void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET }; + event.bus_reset.speed = speed; + dcd_event_handler(&event, in_isr); +} + +void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; + memcpy(&event.setup_received, setup, 8); + + dcd_event_handler(&event, in_isr); +} + +void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; + + event.xfer_complete.ep_addr = ep_addr; + event.xfer_complete.len = xferred_bytes; + event.xfer_complete.result = result; + + dcd_event_handler(&event, in_isr); +} + +//--------------------------------------------------------------------+ +// USBD API For Class Driver +//--------------------------------------------------------------------+ + +void usbd_int_set(bool enabled) +{ + if (enabled) + { + dcd_int_enable(_usbd_rhport); + }else + { + dcd_int_disable(_usbd_rhport); + } +} + +// Parse consecutive endpoint descriptors (IN & OUT) +bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in) +{ + for(int i=0; ibDescriptorType && xfer_type == desc_ep->bmAttributes.xfer); + TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); + + if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) + { + (*ep_in) = desc_ep->bEndpointAddress; + }else + { + (*ep_out) = desc_ep->bEndpointAddress; + } + + p_desc = tu_desc_next(p_desc); + } + + return true; +} + +// Helper to defer an isr function +void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) +{ + dcd_event_t event = + { + .rhport = 0, + .event_id = USBD_EVENT_FUNC_CALL, + }; + + event.func_call.func = func; + event.func_call.param = param; + + dcd_event_handler(&event, in_isr); +} + +//--------------------------------------------------------------------+ +// USBD Endpoint API +//--------------------------------------------------------------------+ + +bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) +{ + TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX); + TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed)); + + return dcd_edpt_open(rhport, desc_ep); +} + +bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + // TODO add this check later, also make sure we don't starve an out endpoint while suspending + // TU_VERIFY(tud_ready()); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + +#if CFG_TUSB_OS != OPT_OS_NONE + // pre-check to help reducing mutex lock + TU_VERIFY((_usbd_dev.ep_status[epnum][dir].busy == 0) && (_usbd_dev.ep_status[epnum][dir].claimed == 0)); + osal_mutex_lock(_usbd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); +#endif + + // can only claim the endpoint if it is not busy and not claimed yet. + bool const ret = (_usbd_dev.ep_status[epnum][dir].busy == 0) && (_usbd_dev.ep_status[epnum][dir].claimed == 0); + if (ret) + { + _usbd_dev.ep_status[epnum][dir].claimed = 1; + } + +#if CFG_TUSB_OS != OPT_OS_NONE + osal_mutex_unlock(_usbd_mutex); +#endif + + return ret; +} + +bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + +#if CFG_TUSB_OS != OPT_OS_NONE + osal_mutex_lock(_usbd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); +#endif + + // can only release the endpoint if it is claimed and not busy + bool const ret = (_usbd_dev.ep_status[epnum][dir].busy == 0) && (_usbd_dev.ep_status[epnum][dir].claimed == 1); + if (ret) + { + _usbd_dev.ep_status[epnum][dir].claimed = 0; + } + +#if CFG_TUSB_OS != OPT_OS_NONE + osal_mutex_unlock(_usbd_mutex); +#endif + + return ret; +} + +bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // TODO skip ready() check for now since enumeration also use this API + // TU_VERIFY(tud_ready()); + + TU_LOG2(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes); + + // Attempt to transfer on a busy endpoint, sound like an race condition ! + TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); + + // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() + // could return and USBD task can preempt and clear the busy + _usbd_dev.ep_status[epnum][dir].busy = true; + + if ( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) ) + { + return true; + }else + { + // DCD error, mark endpoint as ready to allow next transfer + _usbd_dev.ep_status[epnum][dir].busy = false; + _usbd_dev.ep_status[epnum][dir].claimed = 0; + TU_LOG2("FAILED\r\n"); + TU_BREAKPOINT(); + return false; + } +} + +// The number of bytes has to be given explicitly to allow more flexible control of how many +// bytes should be written and second to keep the return value free to give back a boolean +// success message. If total_bytes is too big, the FIFO will copy only what is available +// into the USB buffer! +bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + TU_LOG2(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes); + + // Attempt to transfer on a busy endpoint, sound like an race condition ! + TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); + + // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return + // and usbd task can preempt and clear the busy + _usbd_dev.ep_status[epnum][dir].busy = true; + + if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes)) + { + TU_LOG2("OK\r\n"); + return true; + }else + { + // DCD error, mark endpoint as ready to allow next transfer + _usbd_dev.ep_status[epnum][dir].busy = false; + _usbd_dev.ep_status[epnum][dir].claimed = 0; + TU_LOG2("failed\r\n"); + TU_BREAKPOINT(); + return false; + } +} + +bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + return _usbd_dev.ep_status[epnum][dir].busy; +} + +void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // only stalled if currently cleared + if ( !_usbd_dev.ep_status[epnum][dir].stalled ) + { + TU_LOG(USBD_DBG, " Stall EP %02X\r\n", ep_addr); + dcd_edpt_stall(rhport, ep_addr); + _usbd_dev.ep_status[epnum][dir].stalled = true; + _usbd_dev.ep_status[epnum][dir].busy = true; + } +} + +void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // only clear if currently stalled + if ( _usbd_dev.ep_status[epnum][dir].stalled ) + { + TU_LOG(USBD_DBG, " Clear Stall EP %02X\r\n", ep_addr); + dcd_edpt_clear_stall(rhport, ep_addr); + _usbd_dev.ep_status[epnum][dir].stalled = false; + _usbd_dev.ep_status[epnum][dir].busy = false; + } +} + +bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + return _usbd_dev.ep_status[epnum][dir].stalled; +} + +/** + * usbd_edpt_close will disable an endpoint. + * + * In progress transfers on this EP may be delivered after this call. + * + */ +void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + TU_ASSERT(dcd_edpt_close, /**/); + TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_edpt_close(rhport, ep_addr); + _usbd_dev.ep_status[epnum][dir].stalled = false; + _usbd_dev.ep_status[epnum][dir].busy = false; + _usbd_dev.ep_status[epnum][dir].claimed = false; + + return; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/device/usbd.h b/circuitpython/lib/tinyusb/src/device/usbd.h new file mode 100644 index 0000000..b2bf8ba --- /dev/null +++ b/circuitpython/lib/tinyusb/src/device/usbd.h @@ -0,0 +1,853 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_USBD_H_ +#define _TUSB_USBD_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + +// Init device stack +bool tud_init (uint8_t rhport); + +// Check if device stack is already initialized +bool tud_inited(void); + +// Task function should be called in main/rtos loop +void tud_task (void); + +// Check if there is pending events need proccessing by tud_task() +bool tud_task_event_ready(void); + +// Interrupt handler, name alias to DCD +extern void dcd_int_handler(uint8_t rhport); +#define tud_int_handler dcd_int_handler + +// Get current bus speed +tusb_speed_t tud_speed_get(void); + +// Check if device is connected (may not mounted/configured yet) +// True if just got out of Bus Reset and received the very first data from host +bool tud_connected(void); + +// Check if device is connected and configured +bool tud_mounted(void); + +// Check if device is suspended +bool tud_suspended(void); + +// Check if device is ready to transfer +TU_ATTR_ALWAYS_INLINE static inline +bool tud_ready(void) +{ + return tud_mounted() && !tud_suspended(); +} + +// Remote wake up host, only if suspended and enabled by host +bool tud_remote_wakeup(void); + +// Enable pull-up resistor on D+ D- +// Return false on unsupported MCUs +bool tud_disconnect(void); + +// Disable pull-up resistor on D+ D- +// Return false on unsupported MCUs +bool tud_connect(void); + +// Carry out Data and Status stage of control transfer +// - If len = 0, it is equivalent to sending status only +// - If len > wLength : it will be truncated +bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len); + +// Send STATUS (zero length) packet +bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request); + +//--------------------------------------------------------------------+ +// Application Callbacks (WEAK is optional) +//--------------------------------------------------------------------+ + +// Invoked when received GET DEVICE DESCRIPTOR request +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void); + +// Invoked when received GET CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index); + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid); + +// Invoked when received GET BOS DESCRIPTOR request +// Application return pointer to descriptor +TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void); + +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void); + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index); + +// Invoked when device is mounted (configured) +TU_ATTR_WEAK void tud_mount_cb(void); + +// Invoked when device is unmounted +TU_ATTR_WEAK void tud_umount_cb(void); + +// Invoked when usb bus is suspended +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); + +// Invoked when usb bus is resumed +TU_ATTR_WEAK void tud_resume_cb(void); + +// Invoked when received control request with VENDOR TYPE +TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); + +//--------------------------------------------------------------------+ +// Binary Device Object Store (BOS) Descriptor Templates +//--------------------------------------------------------------------+ + +#define TUD_BOS_DESC_LEN 5 + +// total length, number of device caps +#define TUD_BOS_DESCRIPTOR(_total_len, _caps_num) \ + 5, TUSB_DESC_BOS, U16_TO_U8S_LE(_total_len), _caps_num + +// Device Capability Platform 128-bit UUID + Data +#define TUD_BOS_PLATFORM_DESCRIPTOR(...) \ + 4+TU_ARGS_NUM(__VA_ARGS__), TUSB_DESC_DEVICE_CAPABILITY, DEVICE_CAPABILITY_PLATFORM, 0x00, __VA_ARGS__ + +//------------- WebUSB BOS Platform -------------// + +// Descriptor Length +#define TUD_BOS_WEBUSB_DESC_LEN 24 + +// Vendor Code, iLandingPage +#define TUD_BOS_WEBUSB_DESCRIPTOR(_vendor_code, _ipage) \ + TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_WEBUSB_UUID, U16_TO_U8S_LE(0x0100), _vendor_code, _ipage) + +#define TUD_BOS_WEBUSB_UUID \ + 0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, \ + 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65 + +//------------- Microsoft OS 2.0 Platform -------------// +#define TUD_BOS_MICROSOFT_OS_DESC_LEN 28 + +// Total Length of descriptor set, vendor code +#define TUD_BOS_MS_OS_20_DESCRIPTOR(_desc_set_len, _vendor_code) \ + TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_MS_OS_20_UUID, U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(_desc_set_len), _vendor_code, 0) + +#define TUD_BOS_MS_OS_20_UUID \ + 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, \ + 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F + +//--------------------------------------------------------------------+ +// Configuration Descriptor Templates +//--------------------------------------------------------------------+ + +#define TUD_CONFIG_DESC_LEN (9) + +// Config number, interface count, string index, total length, attribute, power in mA +#define TUD_CONFIG_DESCRIPTOR(config_num, _itfcount, _stridx, _total_len, _attribute, _power_ma) \ + 9, TUSB_DESC_CONFIGURATION, U16_TO_U8S_LE(_total_len), _itfcount, config_num, _stridx, TU_BIT(7) | _attribute, (_power_ma)/2 + +//--------------------------------------------------------------------+ +// CDC Descriptor Templates +//--------------------------------------------------------------------+ + +// Length of template descriptor: 66 bytes +#define TUD_CDC_DESC_LEN (8+9+5+5+4+5+7+9+7+7) + +// CDC Descriptor Template +// Interface number, string index, EP notification address and size, EP data address (out, in) and size. +#define TUD_CDC_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \ + /* Interface Associate */\ + 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_NONE, 0,\ + /* CDC Control Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_NONE, _stridx,\ + /* CDC Header */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\ + /* CDC Call */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\ + /* CDC ACM: support line request */\ + 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\ + /* CDC Union */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ + /* Endpoint Notification */\ + 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 16,\ + /* CDC Data Interface */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 + +//--------------------------------------------------------------------+ +// MSC Descriptor Templates +//--------------------------------------------------------------------+ + +// Length of template descriptor: 23 bytes +#define TUD_MSC_DESC_LEN (9 + 7 + 7) + +// Interface number, string index, EP Out & EP In address, EP size +#define TUD_MSC_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ + /* Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_MSC, MSC_SUBCLASS_SCSI, MSC_PROTOCOL_BOT, _stridx,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 + + +//--------------------------------------------------------------------+ +// HID Descriptor Templates +//--------------------------------------------------------------------+ + +// Length of template descriptor: 25 bytes +#define TUD_HID_DESC_LEN (9 + 9 + 7) + +// HID Input only descriptor +// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval +#define TUD_HID_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epsize, _ep_interval) \ + /* Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_HID, (uint8_t)((_boot_protocol) ? (uint8_t)HID_SUBCLASS_BOOT : 0), _boot_protocol, _stridx,\ + /* HID descriptor */\ + 9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval + +// Length of template descriptor: 32 bytes +#define TUD_HID_INOUT_DESC_LEN (9 + 9 + 7 + 7) + +// HID Input & Output descriptor +// Interface number, string index, protocol, report descriptor len, EP OUT & IN address, size & polling interval +#define TUD_HID_INOUT_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epout, _epin, _epsize, _ep_interval) \ + /* Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_HID, (uint8_t)((_boot_protocol) ? (uint8_t)HID_SUBCLASS_BOOT : 0), _boot_protocol, _stridx,\ + /* HID descriptor */\ + 9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval, \ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval + +//--------------------------------------------------------------------+ +// MIDI Descriptor Templates +// Note: MIDI v1.0 is based on Audio v1.0 +//--------------------------------------------------------------------+ + +#define TUD_MIDI_DESC_HEAD_LEN (9 + 9 + 9 + 7) +#define TUD_MIDI_DESC_HEAD(_itfnum, _stridx, _numcables) \ + /* Audio Control (AC) Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, _stridx,\ + /* AC Header */\ + 9, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(0x0009), 1, (uint8_t)((_itfnum) + 1),\ + /* MIDI Streaming (MS) Interface */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 0, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, 0,\ + /* MS Header */\ + 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(7 + (_numcables) * TUD_MIDI_DESC_JACK_LEN) + +#define TUD_MIDI_JACKID_IN_EMB(_cablenum) \ + (uint8_t)(((_cablenum) - 1) * 4 + 1) + +#define TUD_MIDI_JACKID_IN_EXT(_cablenum) \ + (uint8_t)(((_cablenum) - 1) * 4 + 2) + +#define TUD_MIDI_JACKID_OUT_EMB(_cablenum) \ + (uint8_t)(((_cablenum) - 1) * 4 + 3) + +#define TUD_MIDI_JACKID_OUT_EXT(_cablenum) \ + (uint8_t)(((_cablenum) - 1) * 4 + 4) + +#define TUD_MIDI_DESC_JACK_LEN (6 + 6 + 9 + 9) +#define TUD_MIDI_DESC_JACK(_cablenum) \ + /* MS In Jack (Embedded) */\ + 6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EMBEDDED, TUD_MIDI_JACKID_IN_EMB(_cablenum), 0,\ + /* MS In Jack (External) */\ + 6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EXTERNAL, TUD_MIDI_JACKID_IN_EXT(_cablenum), 0,\ + /* MS Out Jack (Embedded), connected to In Jack External */\ + 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EMBEDDED, TUD_MIDI_JACKID_OUT_EMB(_cablenum), 1, TUD_MIDI_JACKID_IN_EXT(_cablenum), 1, 0,\ + /* MS Out Jack (External), connected to In Jack Embedded */\ + 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, TUD_MIDI_JACKID_OUT_EXT(_cablenum), 1, TUD_MIDI_JACKID_IN_EMB(_cablenum), 1, 0 + +#define TUD_MIDI_DESC_EP_LEN(_numcables) (9 + 4 + (_numcables)) +#define TUD_MIDI_DESC_EP(_epout, _epsize, _numcables) \ + /* Endpoint: Note Audio v1.0's endpoint has 9 bytes instead of 7 */\ + 9, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, 0, 0, \ + /* MS Endpoint (connected to embedded jack) */\ + (uint8_t)(4 + (_numcables)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, _numcables + +// Length of template descriptor (88 bytes) +#define TUD_MIDI_DESC_LEN (TUD_MIDI_DESC_HEAD_LEN + TUD_MIDI_DESC_JACK_LEN + TUD_MIDI_DESC_EP_LEN(1) * 2) + +// MIDI simple descriptor +// - 1 Embedded Jack In connected to 1 External Jack Out +// - 1 Embedded Jack out connected to 1 External Jack In +#define TUD_MIDI_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ + TUD_MIDI_DESC_HEAD(_itfnum, _stridx, 1),\ + TUD_MIDI_DESC_JACK(1),\ + TUD_MIDI_DESC_EP(_epout, _epsize, 1),\ + TUD_MIDI_JACKID_IN_EMB(1),\ + TUD_MIDI_DESC_EP(_epin, _epsize, 1),\ + TUD_MIDI_JACKID_OUT_EMB(1) + +//--------------------------------------------------------------------+ +// Audio v2.0 Descriptor Templates +//--------------------------------------------------------------------+ + +/* Standard Interface Association Descriptor (IAD) */ +#define TUD_AUDIO_DESC_IAD_LEN 8 +#define TUD_AUDIO_DESC_IAD(_firstitfs, _nitfs, _stridx) \ + TUD_AUDIO_DESC_IAD_LEN, TUSB_DESC_INTERFACE_ASSOCIATION, _firstitfs, _nitfs, TUSB_CLASS_AUDIO, AUDIO_FUNCTION_SUBCLASS_UNDEFINED, AUDIO_FUNC_PROTOCOL_CODE_V2, _stridx + +/* Standard AC Interface Descriptor(4.7.1) */ +#define TUD_AUDIO_DESC_STD_AC_LEN 9 +#define TUD_AUDIO_DESC_STD_AC(_itfnum, _nEPs, _stridx) /* _nEPs is 0 or 1 */\ + TUD_AUDIO_DESC_STD_AC_LEN, TUSB_DESC_INTERFACE, _itfnum, /* fixed to zero */ 0x00, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_INT_PROTOCOL_CODE_V2, _stridx + +/* Class-Specific AC Interface Header Descriptor(4.7.2) */ +#define TUD_AUDIO_DESC_CS_AC_LEN 9 +#define TUD_AUDIO_DESC_CS_AC(_bcdADC, _category, _totallen, _ctrl) /* _bcdADC : Audio Device Class Specification Release Number in Binary-Coded Decimal, _category : see audio_function_t, _totallen : Total number of bytes returned for the class-specific AudioControl interface i.e. Clock Source, Unit and Terminal descriptors - Do not include TUD_AUDIO_DESC_CS_AC_LEN, we already do this here*/ \ + TUD_AUDIO_DESC_CS_AC_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_HEADER, U16_TO_U8S_LE(_bcdADC), _category, U16_TO_U8S_LE(_totallen + TUD_AUDIO_DESC_CS_AC_LEN), _ctrl + +/* Clock Source Descriptor(4.7.2.1) */ +#define TUD_AUDIO_DESC_CLK_SRC_LEN 8 +#define TUD_AUDIO_DESC_CLK_SRC(_clkid, _attr, _ctrl, _assocTerm, _stridx) \ + TUD_AUDIO_DESC_CLK_SRC_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_CLOCK_SOURCE, _clkid, _attr, _ctrl, _assocTerm, _stridx + +/* Input Terminal Descriptor(4.7.2.4) */ +#define TUD_AUDIO_DESC_INPUT_TERM_LEN 17 +#define TUD_AUDIO_DESC_INPUT_TERM(_termid, _termtype, _assocTerm, _clkid, _nchannelslogical, _channelcfg, _idxchannelnames, _ctrl, _stridx) \ + TUD_AUDIO_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _clkid, _nchannelslogical, U32_TO_U8S_LE(_channelcfg), _idxchannelnames, U16_TO_U8S_LE(_ctrl), _stridx + +/* Output Terminal Descriptor(4.7.2.5) */ +#define TUD_AUDIO_DESC_OUTPUT_TERM_LEN 12 +#define TUD_AUDIO_DESC_OUTPUT_TERM(_termid, _termtype, _assocTerm, _srcid, _clkid, _ctrl, _stridx) \ + TUD_AUDIO_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _srcid, _clkid, U16_TO_U8S_LE(_ctrl), _stridx + +/* Feature Unit Descriptor(4.7.2.8) */ +// 1 - Channel +#define TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN 6+(1+1)*4 +#define TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(_unitid, _srcid, _ctrlch0master, _ctrlch1, _stridx) \ + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, U32_TO_U8S_LE(_ctrlch0master), U32_TO_U8S_LE(_ctrlch1), _stridx + +// 2 - Channels +#define TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN (6+(2+1)*4) +#define TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(_unitid, _srcid, _ctrlch0master, _ctrlch1, _ctrlch2, _stridx) \ + TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, U32_TO_U8S_LE(_ctrlch0master), U32_TO_U8S_LE(_ctrlch1), U32_TO_U8S_LE(_ctrlch2), _stridx +// 4 - Channels +#define TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN (6+(4+1)*4) +#define TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL(_unitid, _srcid, _ctrlch0master, _ctrlch1, _ctrlch2, _ctrlch3, _ctrlch4, _stridx) \ + TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, U32_TO_U8S_LE(_ctrlch0master), U32_TO_U8S_LE(_ctrlch1), U32_TO_U8S_LE(_ctrlch2), U32_TO_U8S_LE(_ctrlch3), U32_TO_U8S_LE(_ctrlch4), _stridx + +// For more channels, add definitions here + +/* Standard AS Interface Descriptor(4.9.1) */ +#define TUD_AUDIO_DESC_STD_AS_INT_LEN 9 +#define TUD_AUDIO_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ + TUD_AUDIO_DESC_STD_AS_INT_LEN, TUSB_DESC_INTERFACE, _itfnum, _altset, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_STREAMING, AUDIO_INT_PROTOCOL_CODE_V2, _stridx + +/* Class-Specific AS Interface Descriptor(4.9.2) */ +#define TUD_AUDIO_DESC_CS_AS_INT_LEN 16 +#define TUD_AUDIO_DESC_CS_AS_INT(_termid, _ctrl, _formattype, _formats, _nchannelsphysical, _channelcfg, _stridx) \ + TUD_AUDIO_DESC_CS_AS_INT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AS_INTERFACE_AS_GENERAL, _termid, _ctrl, _formattype, U32_TO_U8S_LE(_formats), _nchannelsphysical, U32_TO_U8S_LE(_channelcfg), _stridx + +/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ +#define TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN 6 +#define TUD_AUDIO_DESC_TYPE_I_FORMAT(_subslotsize, _bitresolution) /* _subslotsize is number of bytes per sample (i.e. subslot) and can be 1,2,3, or 4 */\ + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AS_INTERFACE_FORMAT_TYPE, AUDIO_FORMAT_TYPE_I, _subslotsize, _bitresolution + +/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ +#define TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN 7 +#define TUD_AUDIO_DESC_STD_AS_ISO_EP(_ep, _attr, _maxEPsize, _interval) \ + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN, TUSB_DESC_ENDPOINT, _ep, _attr, U16_TO_U8S_LE(_maxEPsize), _interval + +/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ +#define TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN 8 +#define TUD_AUDIO_DESC_CS_AS_ISO_EP(_attr, _ctrl, _lockdelayunit, _lockdelay) \ + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN, TUSB_DESC_CS_ENDPOINT, AUDIO_CS_EP_SUBTYPE_GENERAL, _attr, _ctrl, _lockdelayunit, U16_TO_U8S_LE(_lockdelay) + +/* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */ +#define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN 7 +#define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(_ep, _interval) \ + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_NO_SYNC | TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _interval + +// AUDIO simple descriptor (UAC2) for 1 microphone input +// - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source + +#define TUD_AUDIO_MIC_ONE_CH_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ + + TUD_AUDIO_DESC_STD_AC_LEN\ + + TUD_AUDIO_DESC_CS_AC_LEN\ + + TUD_AUDIO_DESC_CLK_SRC_LEN\ + + TUD_AUDIO_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN\ + + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) + +#define TUD_AUDIO_MIC_ONE_CH_DESC_N_AS_INT 1 // Number of AS interfaces + +#define TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ + /* Standard Interface Association Descriptor (IAD) */\ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + /* Standard AC Interface Descriptor(4.7.1) */\ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ + TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + /* Clock Source Descriptor(4.7.2.1) */\ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO_CTRL_R << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + /* Input Terminal Descriptor(4.7.2.4) */\ + TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ + /* Output Terminal Descriptor(4.7.2.5) */\ + TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + /* Feature Unit Descriptor(4.7.2.8) */\ + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.9.1) */\ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.9.1) */\ + /* Interface 1, Alternate 1 - alternate interface for data streaming */\ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ + /* Class-Specific AS Interface Descriptor(4.9.2) */\ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + +// AUDIO simple descriptor (UAC2) for 4 microphone input +// - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source + +#define TUD_AUDIO_MIC_FOUR_CH_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ + + TUD_AUDIO_DESC_STD_AC_LEN\ + + TUD_AUDIO_DESC_CS_AC_LEN\ + + TUD_AUDIO_DESC_CLK_SRC_LEN\ + + TUD_AUDIO_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN\ + + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) + +#define TUD_AUDIO_MIC_FOUR_CH_DESC_N_AS_INT 1 // Number of AS interfaces + +#define TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ + /* Standard Interface Association Descriptor (IAD) */\ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + /* Standard AC Interface Descriptor(4.7.1) */\ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ + TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + /* Clock Source Descriptor(4.7.2.1) */\ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO_CTRL_R << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + /* Input Terminal Descriptor(4.7.2.4) */\ + TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x04, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ + /* Output Terminal Descriptor(4.7.2.5) */\ + TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + /* Feature Unit Descriptor(4.7.2.8) */\ + TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch3*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch4*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.9.1) */\ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.9.1) */\ + /* Interface 1, Alternate 1 - alternate interface for data streaming */\ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ + /* Class-Specific AS Interface Descriptor(4.9.2) */\ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x04, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + +// AUDIO simple descriptor (UAC2) for mono speaker +// - 1 Input Terminal, 2 Feature Unit (Mute and Volume Control), 3 Output Terminal, 4 Clock Source + +#define TUD_AUDIO_SPEAKER_MONO_FB_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ + + TUD_AUDIO_DESC_STD_AC_LEN\ + + TUD_AUDIO_DESC_CS_AC_LEN\ + + TUD_AUDIO_DESC_CLK_SRC_LEN\ + + TUD_AUDIO_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN\ + + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN) + +#define TUD_AUDIO_SPEAKER_MONO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epsize, _epfb) \ + /* Standard Interface Association Descriptor (IAD) */\ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + /* Standard AC Interface Descriptor(4.7.1) */\ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ + TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + /* Clock Source Descriptor(4.7.2.1) */\ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO_CTRL_R << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + /* Input Terminal Descriptor(4.7.2.4) */\ + TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ + /* Output Terminal Descriptor(4.7.2.5) */\ + TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + /* Feature Unit Descriptor(4.7.2.8) */\ + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ 0 * (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ 0 * (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.9.1) */\ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.9.1) */\ + /* Interface 1, Alternate 1 - alternate interface for data streaming */\ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ + /* Class-Specific AS Interface Descriptor(4.9.2) */\ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ + /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_interval*/ 1)\ + +// Calculate wMaxPacketSize of Endpoints +#define TUD_AUDIO_EP_SIZE(_maxFrequency, _nBytesPerSample, _nChannels) \ + ((((_maxFrequency + (TUD_OPT_HIGH_SPEED ? 7999 : 999)) / (TUD_OPT_HIGH_SPEED ? 8000 : 1000)) + 1) * _nBytesPerSample * _nChannels) + + +//--------------------------------------------------------------------+ +// USBTMC/USB488 Descriptor Templates +//--------------------------------------------------------------------+ + +#define TUD_USBTMC_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC) +#define TUD_USBTMC_APP_SUBCLASS 0x03u + +#define TUD_USBTMC_PROTOCOL_STD 0x00u +#define TUD_USBTMC_PROTOCOL_USB488 0x01u + +// Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID, +// bulk-in endpoint ID +#define TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \ + /* Interface */ \ + 0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, TUD_USBTMC_APP_CLASS, TUD_USBTMC_APP_SUBCLASS, _itfProtocol, _stridx + +#define TUD_USBTMC_IF_DESCRIPTOR_LEN 9u + +#define TUD_USBTMC_BULK_DESCRIPTORS(_epout, _epin, _bulk_epsize) \ + /* Endpoint Out */ \ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \ + /* Endpoint In */ \ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u + +#define TUD_USBTMC_BULK_DESCRIPTORS_LEN (7u+7u) + +/* optional interrupt endpoint */ \ +// _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number? +#define TUD_USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \ + 7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16 + +#define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u) + +//--------------------------------------------------------------------+ +// Vendor Descriptor Templates +//--------------------------------------------------------------------+ + +#define TUD_VENDOR_DESC_LEN (9+7+7) + +// Interface number, string index, EP Out & IN address, EP size +#define TUD_VENDOR_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ + /* Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_VENDOR_SPECIFIC, 0x00, 0x00, _stridx,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 + +//--------------------------------------------------------------------+ +// DFU Runtime Descriptor Templates +//--------------------------------------------------------------------+ + +#define TUD_DFU_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC) +#define TUD_DFU_APP_SUBCLASS (APP_SUBCLASS_DFU_RUNTIME) + +// Length of template descriptr: 18 bytes +#define TUD_DFU_RT_DESC_LEN (9 + 9) + +// DFU runtime descriptor +// Interface number, string index, attributes, detach timeout, transfer size +#define TUD_DFU_RT_DESCRIPTOR(_itfnum, _stridx, _attr, _timeout, _xfer_size) \ + /* Interface */ \ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_RT, _stridx, \ + /* Function */ \ + 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) + +//--------------------------------------------------------------------+ +// DFU Descriptor Templates +//--------------------------------------------------------------------+ + +// Length of template descriptor: 9 bytes + number of alternatives * 9 +#define TUD_DFU_DESC_LEN(_alt_count) (9 + (_alt_count) * 9) + +// Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size +// Note: Alternate count must be numberic or macro, string index is increased by one for each Alt interface +#define TUD_DFU_DESCRIPTOR(_itfnum, _alt_count, _stridx, _attr, _timeout, _xfer_size) \ + TU_XSTRCAT(_TUD_DFU_ALT_,_alt_count)(_itfnum, 0, _stridx), \ + /* Function */ \ + 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) + +#define _TUD_DFU_ALT(_itfnum, _alt, _stridx) \ + /* Interface */ \ + 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx + +#define _TUD_DFU_ALT_1(_itfnum, _alt_count, _stridx) \ + _TUD_DFU_ALT(_itfnum, _alt_count, _stridx) + +#define _TUD_DFU_ALT_2(_itfnum, _alt_count, _stridx) \ + _TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ + _TUD_DFU_ALT_1(_itfnum, _alt_count+1, _stridx+1) + +#define _TUD_DFU_ALT_3(_itfnum, _alt_count, _stridx) \ + _TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ + _TUD_DFU_ALT_2(_itfnum, _alt_count+1, _stridx+1) + +#define _TUD_DFU_ALT_4(_itfnum, _alt_count, _stridx) \ + _TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ + _TUD_DFU_ALT_3(_itfnum, _alt_count+1, _stridx+1) + +#define _TUD_DFU_ALT_5(_itfnum, _alt_count, _stridx) \ + _TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ + _TUD_DFU_ALT_4(_itfnum, _alt_count+1, _stridx+1) + +#define _TUD_DFU_ALT_6(_itfnum, _alt_count, _stridx) \ + _TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ + _TUD_DFU_ALT_5(_itfnum, _alt_count+1, _stridx+1) + +#define _TUD_DFU_ALT_7(_itfnum, _alt_count, _stridx) \ + _TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ + _TUD_DFU_ALT_6(_itfnum, _alt_count+1, _stridx+1) + +#define _TUD_DFU_ALT_8(_itfnum, _alt_count, _stridx) \ + _TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ + _TUD_DFU_ALT_7(_itfnum, _alt_count+1, _stridx+1) + +//--------------------------------------------------------------------+ +// CDC-ECM Descriptor Templates +//--------------------------------------------------------------------+ + +// Length of template descriptor: 71 bytes +#define TUD_CDC_ECM_DESC_LEN (8+9+5+5+13+7+9+9+7+7) + +// CDC-ECM Descriptor Template +// Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. +#define TUD_CDC_ECM_DESCRIPTOR(_itfnum, _desc_stridx, _mac_stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize, _maxsegmentsize) \ + /* Interface Association */\ + 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL, 0, 0,\ + /* CDC Control Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL, 0, _desc_stridx,\ + /* CDC-ECM Header */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\ + /* CDC-ECM Union */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ + /* CDC-ECM Functional Descriptor */\ + 13, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ETHERNET_NETWORKING, _mac_stridx, 0, 0, 0, 0, U16_TO_U8S_LE(_maxsegmentsize), U16_TO_U8S_LE(0), 0,\ + /* Endpoint Notification */\ + 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\ + /* CDC Data Interface (default inactive) */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 0, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ + /* CDC Data Interface (alternative active) */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 1, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 + +//--------------------------------------------------------------------+ +// RNDIS Descriptor Templates +//--------------------------------------------------------------------+ + +#if 0 +/* Windows XP */ +#define TUD_RNDIS_ITF_CLASS TUSB_CLASS_CDC +#define TUD_RNDIS_ITF_SUBCLASS CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL +#define TUD_RNDIS_ITF_PROTOCOL 0xFF /* CDC_COMM_PROTOCOL_MICROSOFT_RNDIS */ +#else +/* Windows 7+ */ +#define TUD_RNDIS_ITF_CLASS TUSB_CLASS_WIRELESS_CONTROLLER +#define TUD_RNDIS_ITF_SUBCLASS 0x01 +#define TUD_RNDIS_ITF_PROTOCOL 0x03 +#endif + +// Length of template descriptor: 66 bytes +#define TUD_RNDIS_DESC_LEN (8+9+5+5+4+5+7+9+7+7) + +// RNDIS Descriptor Template +// Interface number, string index, EP notification address and size, EP data address (out, in) and size. +#define TUD_RNDIS_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \ + /* Interface Association */\ + 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUD_RNDIS_ITF_CLASS, TUD_RNDIS_ITF_SUBCLASS, TUD_RNDIS_ITF_PROTOCOL, 0,\ + /* CDC Control Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUD_RNDIS_ITF_CLASS, TUD_RNDIS_ITF_SUBCLASS, TUD_RNDIS_ITF_PROTOCOL, _stridx,\ + /* CDC-ACM Header */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0110),\ + /* CDC Call Management */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\ + /* ACM */\ + 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 0,\ + /* CDC Union */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ + /* Endpoint Notification */\ + 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\ + /* CDC Data Interface */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 + +//--------------------------------------------------------------------+ +// Bluetooth Radio Descriptor Templates +//--------------------------------------------------------------------+ + +#define TUD_BT_APP_CLASS (TUSB_CLASS_WIRELESS_CONTROLLER) +#define TUD_BT_APP_SUBCLASS 0x01 +#define TUD_BT_PROTOCOL_PRIMARY_CONTROLLER 0x01 +#define TUD_BT_PROTOCOL_AMP_CONTROLLER 0x02 + +#ifndef CFG_TUD_BTH_ISO_ALT_COUNT +#define CFG_TUD_BTH_ISO_ALT_COUNT 0 +#endif + +// Length of template descriptor: 38 bytes + number of ISO alternatives * 23 +#define TUD_BTH_DESC_LEN (8 + 9 + 7 + 7 + 7 + (CFG_TUD_BTH_ISO_ALT_COUNT) * (9 + 7 + 7)) + +/* Primary Interface */ +#define TUD_BTH_PRI_ITF(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_interval, _ep_in, _ep_out, _ep_size) \ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 3, TUD_BT_APP_CLASS, TUD_BT_APP_SUBCLASS, TUD_BT_PROTOCOL_PRIMARY_CONTROLLER, _stridx, \ + /* Endpoint In for events */ \ + 7, TUSB_DESC_ENDPOINT, _ep_evt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_evt_size), _ep_evt_interval, \ + /* Endpoint In for ACL data */ \ + 7, TUSB_DESC_ENDPOINT, _ep_in, TUSB_XFER_BULK, U16_TO_U8S_LE(_ep_size), 1, \ + /* Endpoint Out for ACL data */ \ + 7, TUSB_DESC_ENDPOINT, _ep_out, TUSB_XFER_BULK, U16_TO_U8S_LE(_ep_size), 1 + +#define TUD_BTH_ISO_ITF(_itfnum, _alt, _ep_in, _ep_out, _n) ,\ + /* Interface with 2 endpoints */ \ + 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 2, TUD_BT_APP_CLASS, TUD_BT_APP_SUBCLASS, TUD_BT_PROTOCOL_PRIMARY_CONTROLLER, 0, \ + /* Isochronous endpoints */ \ + 7, TUSB_DESC_ENDPOINT, _ep_in, TUSB_XFER_ISOCHRONOUS, U16_TO_U8S_LE(_n), 1, \ + 7, TUSB_DESC_ENDPOINT, _ep_out, TUSB_XFER_ISOCHRONOUS, U16_TO_U8S_LE(_n), 1 + +#define _FIRST(a, ...) a +#define _REST(a, ...) __VA_ARGS__ + +#define TUD_BTH_ISO_ITF_0(_itfnum, ...) +#define TUD_BTH_ISO_ITF_1(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 1, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) +#define TUD_BTH_ISO_ITF_2(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 2, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ + TUD_BTH_ISO_ITF_1(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) +#define TUD_BTH_ISO_ITF_3(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 3, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ + TUD_BTH_ISO_ITF_2(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) +#define TUD_BTH_ISO_ITF_4(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 4, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ + TUD_BTH_ISO_ITF_3(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) +#define TUD_BTH_ISO_ITF_5(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 5, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ + TUD_BTH_ISO_ITF_4(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) +#define TUD_BTH_ISO_ITF_6(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 6, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ + TUD_BTH_ISO_ITF_5(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) + +#define TUD_BTH_ISO_ITFS(_itfnum, _ep_in, _ep_out, ...) \ + TU_XSTRCAT(TUD_BTH_ISO_ITF_, CFG_TUD_BTH_ISO_ALT_COUNT)(_itfnum, _ep_in, _ep_out, __VA_ARGS__) + +// BT Primary controller descriptor +// Interface number, string index, attributes, event endpoint, event endpoint size, interval, data in, data out, data endpoint size, iso endpoint sizes +// TODO BTH should also use IAD like CDC for composite device +#define TUD_BTH_DESCRIPTOR(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_interval, _ep_in, _ep_out, _ep_size,...) \ + /* Interface Associate */\ + 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUD_BT_APP_CLASS, TUD_BT_APP_SUBCLASS, TUD_BT_PROTOCOL_PRIMARY_CONTROLLER, 0,\ + TUD_BTH_PRI_ITF(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_interval, _ep_in, _ep_out, _ep_size) \ + TUD_BTH_ISO_ITFS(_itfnum + 1, _ep_in + 1, _ep_out + 1, __VA_ARGS__) + +//--------------------------------------------------------------------+ +// CDC-NCM Descriptor Templates +//--------------------------------------------------------------------+ + +// Length of template descriptor +#define TUD_CDC_NCM_DESC_LEN (8+9+5+5+13+6+7+9+9+7+7) + +// CDC-ECM Descriptor Template +// Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. +#define TUD_CDC_NCM_DESCRIPTOR(_itfnum, _desc_stridx, _mac_stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize, _maxsegmentsize) \ + /* Interface Association */\ + 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL, 0, 0,\ + /* CDC Control Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL, 0, _desc_stridx,\ + /* CDC-NCM Header */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0110),\ + /* CDC-NCM Union */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ + /* CDC-NCM Functional Descriptor */\ + 13, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ETHERNET_NETWORKING, _mac_stridx, 0, 0, 0, 0, U16_TO_U8S_LE(_maxsegmentsize), U16_TO_U8S_LE(0), 0, \ + /* CDC-NCM Functional Descriptor */\ + 6, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_NCM, U16_TO_U8S_LE(0x0100), 0, \ + /* Endpoint Notification */\ + 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 50,\ + /* CDC Data Interface (default inactive) */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 0, TUSB_CLASS_CDC_DATA, 0, NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK, 0,\ + /* CDC Data Interface (alternative active) */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 1, 2, TUSB_CLASS_CDC_DATA, 0, NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK, 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_USBD_H_ */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/device/usbd_control.c b/circuitpython/lib/tinyusb/src/device/usbd_control.c new file mode 100644 index 0000000..4f41080 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/device/usbd_control.c @@ -0,0 +1,233 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED + +#include "tusb.h" +#include "device/usbd_pvt.h" +#include "dcd.h" + +#if CFG_TUSB_DEBUG >= 2 +extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); +#endif + +enum +{ + EDPT_CTRL_OUT = 0x00, + EDPT_CTRL_IN = 0x80 +}; + +typedef struct +{ + tusb_control_request_t request; + + uint8_t* buffer; + uint16_t data_len; + uint16_t total_xferred; + + usbd_control_xfer_cb_t complete_cb; +} usbd_control_xfer_t; + +static usbd_control_xfer_t _ctrl_xfer; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN +static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + +// Queue ZLP status transaction +static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const * request) +{ + // Opposite to endpoint in Data Phase + uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; + return usbd_edpt_xfer(rhport, ep_addr, NULL, 0); +} + +// Status phase +bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) +{ + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = NULL; + _ctrl_xfer.total_xferred = 0; + _ctrl_xfer.data_len = 0; + + return _status_stage_xact(rhport, request); +} + +// Queue a transaction in Data Stage +// Each transaction has up to Endpoint0's max packet size. +// This function can also transfer an zero-length packet +static bool _data_stage_xact(uint8_t rhport) +{ + uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_SIZE); + + uint8_t ep_addr = EDPT_CTRL_OUT; + + if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN ) + { + ep_addr = EDPT_CTRL_IN; + if ( xact_len ) memcpy(_usbd_ctrl_buf, _ctrl_xfer.buffer, xact_len); + } + + return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _usbd_ctrl_buf : NULL, xact_len); +} + +// Transmit data to/from the control endpoint. +// If the request's wLength is zero, a status packet is sent instead. +bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) +{ + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = (uint8_t*) buffer; + _ctrl_xfer.total_xferred = 0U; + _ctrl_xfer.data_len = tu_min16(len, request->wLength); + + if (request->wLength > 0U) + { + if(_ctrl_xfer.data_len > 0U) + { + TU_ASSERT(buffer); + } + +// TU_LOG2(" Control total data length is %u bytes\r\n", _ctrl_xfer.data_len); + + // Data stage + TU_ASSERT( _data_stage_xact(rhport) ); + } + else + { + // Status stage + TU_ASSERT( _status_stage_xact(rhport, request) ); + } + + return true; +} + +//--------------------------------------------------------------------+ +// USBD API +//--------------------------------------------------------------------+ + +void usbd_control_reset(void); +void usbd_control_set_request(tusb_control_request_t const *request); +void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ); +bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + +void usbd_control_reset(void) +{ + tu_varclr(&_ctrl_xfer); +} + +// Set complete callback +void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ) +{ + _ctrl_xfer.complete_cb = fp; +} + +// for dcd_set_address where DCD is responsible for status response +void usbd_control_set_request(tusb_control_request_t const *request) +{ + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = NULL; + _ctrl_xfer.total_xferred = 0; + _ctrl_xfer.data_len = 0; +} + +// callback when a transaction complete on +// - DATA stage of control endpoint or +// - Status stage +bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) result; + + // Endpoint Address is opposite to direction bit, this is Status Stage complete event + if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction ) + { + TU_ASSERT(0 == xferred_bytes); + + // invoke optional dcd hook if available + if (dcd_edpt0_status_complete) dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request); + + if (_ctrl_xfer.complete_cb) + { + // TODO refactor with usbd_driver_print_control_complete_name + _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request); + } + + return true; + } + + if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT ) + { + TU_VERIFY(_ctrl_xfer.buffer); + memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes); + TU_LOG_MEM(2, _usbd_ctrl_buf, xferred_bytes, 2); + } + + _ctrl_xfer.total_xferred += xferred_bytes; + _ctrl_xfer.buffer += xferred_bytes; + + // Data Stage is complete when all request's length are transferred or + // a short packet is sent including zero-length packet. + if ( (_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) || (xferred_bytes < CFG_TUD_ENDPOINT0_SIZE) ) + { + // DATA stage is complete + bool is_ok = true; + + // invoke complete callback if set + // callback can still stall control in status phase e.g out data does not make sense + if ( _ctrl_xfer.complete_cb ) + { + #if CFG_TUSB_DEBUG >= 2 + usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb); + #endif + + is_ok = _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_DATA, &_ctrl_xfer.request); + } + + if ( is_ok ) + { + // Send status + TU_ASSERT( _status_stage_xact(rhport, &_ctrl_xfer.request) ); + }else + { + // Stall both IN and OUT control endpoint + dcd_edpt_stall(rhport, EDPT_CTRL_OUT); + dcd_edpt_stall(rhport, EDPT_CTRL_IN); + } + } + else + { + // More data to transfer + TU_ASSERT( _data_stage_xact(rhport) ); + } + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/device/usbd_pvt.h b/circuitpython/lib/tinyusb/src/device/usbd_pvt.h new file mode 100644 index 0000000..dae95ce --- /dev/null +++ b/circuitpython/lib/tinyusb/src/device/usbd_pvt.h @@ -0,0 +1,117 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ +#ifndef USBD_PVT_H_ +#define USBD_PVT_H_ + +#include "osal/osal.h" +#include "common/tusb_fifo.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Class Driver API +//--------------------------------------------------------------------+ + +typedef struct +{ + #if CFG_TUSB_DEBUG >= 2 + char const* name; + #endif + + void (* init ) (void); + void (* reset ) (uint8_t rhport); + uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); + bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); + bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + void (* sof ) (uint8_t rhport); /* optional */ +} usbd_class_driver_t; + +// Invoked when initializing device stack to get additional class drivers. +// Can optionally implemented by application to extend/overwrite class driver support. +// Note: The drivers array must be accessible at all time when stack is active +usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; + +typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); + +void usbd_int_set(bool enabled); + +//--------------------------------------------------------------------+ +// USBD Endpoint API +//--------------------------------------------------------------------+ + +// Open an endpoint +bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); + +// Close an endpoint +void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr); + +// Submit a usb transfer +bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); + +// Submit a usb ISO transfer by use of a FIFO (ring buffer) - all bytes in FIFO get transmitted +bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes); + +// Claim an endpoint before submitting a transfer. +// If caller does not make any transfer, it must release endpoint for others. +bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr); + +// Release an endpoint without submitting a transfer +bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr); + +// Check if endpoint is busy transferring +bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr); + +// Stall endpoint +void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr); + +// Clear stalled endpoint +void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr); + +// Check if endpoint is stalled +bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr); + +// Check if endpoint is ready (not busy and not stalled) +TU_ATTR_ALWAYS_INLINE static inline +bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) +{ + return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr); +} + +/*------------------------------------------------------------------*/ +/* Helper + *------------------------------------------------------------------*/ + +bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); +void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr ); + + +#ifdef __cplusplus + } +#endif + +#endif /* USBD_PVT_H_ */ diff --git a/circuitpython/lib/tinyusb/src/host/hcd.h b/circuitpython/lib/tinyusb/src/host/hcd.h new file mode 100644 index 0000000..9819f5f --- /dev/null +++ b/circuitpython/lib/tinyusb/src/host/hcd.h @@ -0,0 +1,178 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_HCD_H_ +#define _TUSB_HCD_H_ + +#include "common/tusb_common.h" +#include "osal/osal.h" +#include "common/tusb_fifo.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Configuration +//--------------------------------------------------------------------+ + +#ifndef CFG_TUH_ENDPOINT_MAX + #define CFG_TUH_ENDPOINT_MAX (CFG_TUH_HUB + CFG_TUH_HID*2 + CFG_TUH_MSC*2 + CFG_TUH_CDC*3) +// #ifdef TUP_HCD_ENDPOINT_MAX +// #define CFG_TUH_ENDPPOINT_MAX TUP_HCD_ENDPOINT_MAX +// #else +// #define +// #endif +#endif + + //--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef enum +{ + HCD_EVENT_DEVICE_ATTACH, + HCD_EVENT_DEVICE_REMOVE, + HCD_EVENT_XFER_COMPLETE, + + // Not an HCD event, just a convenient way to defer ISR function + USBH_EVENT_FUNC_CALL, + + HCD_EVENT_COUNT +} hcd_eventid_t; + +typedef struct +{ + uint8_t rhport; + uint8_t event_id; + uint8_t dev_addr; + + union + { + // Attach, Remove + struct { + uint8_t hub_addr; + uint8_t hub_port; + uint8_t speed; + } connection; + + // XFER_COMPLETE + struct { + uint8_t ep_addr; + uint8_t result; + uint32_t len; + } xfer_complete; + + // FUNC_CALL + struct { + void (*func) (void*); + void* param; + }func_call; + }; + +} hcd_event_t; + +typedef struct { + uint8_t rhport; + uint8_t hub_addr; + uint8_t hub_port; + uint8_t speed; +} hcd_devtree_info_t; + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +// Initialize controller to host mode +bool hcd_init(uint8_t rhport); + +// Interrupt Handler +void hcd_int_handler(uint8_t rhport); + +// Enable USB interrupt +void hcd_int_enable (uint8_t rhport); + +// Disable USB interrupt +void hcd_int_disable(uint8_t rhport); + +// Get frame number (1ms) +uint32_t hcd_frame_number(uint8_t rhport); + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +// Get the current connect status of roothub port +bool hcd_port_connect_status(uint8_t rhport); + +// Reset USB bus on the port +void hcd_port_reset(uint8_t rhport); + +// TODO implement later +void hcd_port_reset_end(uint8_t rhport); + +// Get port link speed +tusb_speed_t hcd_port_speed_get(uint8_t rhport); + +// HCD closes all opened endpoints belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr); + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]); +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc); +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen); +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr); + +//--------------------------------------------------------------------+ +// USBH implemented API +//--------------------------------------------------------------------+ + +// Get device tree information of a device +// USB device tree can be complicated and manged by USBH, this help HCD to retrieve +// needed topology info to carry out its work +extern void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info); + +//------------- Event API -------------// + +// Called by HCD to notify stack +extern void hcd_event_handler(hcd_event_t const* event, bool in_isr); + +// Helper to send device attach event +extern void hcd_event_device_attach(uint8_t rhport, bool in_isr); + +// Helper to send device removal event +extern void hcd_event_device_remove(uint8_t rhport, bool in_isr); + +// Helper to send USB transfer event +extern void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_HCD_H_ */ diff --git a/circuitpython/lib/tinyusb/src/host/hub.c b/circuitpython/lib/tinyusb/src/host/hub.c new file mode 100644 index 0000000..1fec8b8 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/host/hub.c @@ -0,0 +1,388 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUH_ENABLED && CFG_TUH_HUB) + +#include "usbh.h" +#include "usbh_classdriver.h" +#include "hub.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef struct +{ + uint8_t itf_num; + uint8_t ep_in; + uint8_t port_count; + uint8_t status_change; // data from status change interrupt endpoint + + hub_port_status_response_t port_status; +} hub_interface_t; + +CFG_TUSB_MEM_SECTION static hub_interface_t hub_data[CFG_TUH_HUB]; +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _hub_buffer[sizeof(descriptor_hub_desc_t)]; + +TU_ATTR_ALWAYS_INLINE +static inline hub_interface_t* get_itf(uint8_t dev_addr) +{ + return &hub_data[dev_addr-1-CFG_TUH_DEVICE_MAX]; +} + +#if CFG_TUSB_DEBUG >= 2 +static char const* const _hub_feature_str[] = +{ + [HUB_FEATURE_PORT_CONNECTION ] = "PORT_CONNECTION", + [HUB_FEATURE_PORT_ENABLE ] = "PORT_ENABLE", + [HUB_FEATURE_PORT_SUSPEND ] = "PORT_SUSPEND", + [HUB_FEATURE_PORT_OVER_CURRENT ] = "PORT_OVER_CURRENT", + [HUB_FEATURE_PORT_RESET ] = "PORT_RESET", + [HUB_FEATURE_PORT_POWER ] = "PORT_POWER", + [HUB_FEATURE_PORT_LOW_SPEED ] = "PORT_LOW_SPEED", + [HUB_FEATURE_PORT_CONNECTION_CHANGE ] = "PORT_CONNECTION_CHANGE", + [HUB_FEATURE_PORT_ENABLE_CHANGE ] = "PORT_ENABLE_CHANGE", + [HUB_FEATURE_PORT_SUSPEND_CHANGE ] = "PORT_SUSPEND_CHANGE", + [HUB_FEATURE_PORT_OVER_CURRENT_CHANGE ] = "PORT_OVER_CURRENT_CHANGE", + [HUB_FEATURE_PORT_RESET_CHANGE ] = "PORT_RESET_CHANGE", + [HUB_FEATURE_PORT_TEST ] = "PORT_TEST", + [HUB_FEATURE_PORT_INDICATOR ] = "PORT_INDICATOR", +}; +#endif + +//--------------------------------------------------------------------+ +// HUB +//--------------------------------------------------------------------+ +bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb) +{ + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HUB_REQUEST_CLEAR_FEATURE, + .wValue = feature, + .wIndex = hub_port, + .wLength = 0 + }; + + TU_LOG2("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); + TU_ASSERT( tuh_control_xfer(hub_addr, &request, NULL, complete_cb) ); + return true; +} + +bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb) +{ + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HUB_REQUEST_SET_FEATURE, + .wValue = feature, + .wIndex = hub_port, + .wLength = 0 + }; + + TU_LOG2("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); + TU_ASSERT( tuh_control_xfer(hub_addr, &request, NULL, complete_cb) ); + return true; +} + +bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_complete_cb_t complete_cb) +{ + return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb); +} + +bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_complete_cb_t complete_cb) +{ + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HUB_REQUEST_GET_STATUS, + .wValue = 0, + .wIndex = hub_port, + .wLength = 4 + }; + + TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); + TU_ASSERT( tuh_control_xfer( hub_addr, &request, resp, complete_cb) ); + return true; +} + +//--------------------------------------------------------------------+ +// CLASS-USBH API (don't require to verify parameters) +//--------------------------------------------------------------------+ +void hub_init(void) +{ + tu_memclr(hub_data, sizeof(hub_data)); +} + +bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +{ + TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && + 0 == itf_desc->bInterfaceSubClass); + + // hub driver does not support multiple TT yet + TU_VERIFY(itf_desc->bInterfaceProtocol <= 1); + + // msc driver length is fixed + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); + TU_ASSERT(drv_len <= max_len); + + //------------- Interrupt Status endpoint -------------// + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); + + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && + TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); + + TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep)); + + hub_interface_t* p_hub = get_itf(dev_addr); + + p_hub->itf_num = itf_desc->bInterfaceNumber; + p_hub->ep_in = desc_ep->bEndpointAddress; + + return true; +} + +void hub_close(uint8_t dev_addr) +{ + TU_VERIFY(dev_addr > CFG_TUH_DEVICE_MAX, ); + hub_interface_t* p_hub = get_itf(dev_addr); + + if (p_hub->ep_in) tu_memclr(p_hub, sizeof( hub_interface_t)); +} + +bool hub_status_pipe_queue(uint8_t dev_addr) +{ + hub_interface_t* hub_itf = get_itf(dev_addr); + return usbh_edpt_xfer(dev_addr, hub_itf->ep_in, &hub_itf->status_change, 1); +} + + +//--------------------------------------------------------------------+ +// Set Configure +//--------------------------------------------------------------------+ + +static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); + +bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) +{ + hub_interface_t* p_hub = get_itf(dev_addr); + TU_ASSERT(itf_num == p_hub->itf_num); + + // Get Hub Descriptor + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HUB_REQUEST_GET_DESCRIPTOR, + .wValue = 0, + .wIndex = 0, + .wLength = sizeof(descriptor_hub_desc_t) + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &request, _hub_buffer, config_set_port_power) ); + + return true; +} + +static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + hub_interface_t* p_hub = get_itf(dev_addr); + + // only use number of ports in hub descriptor + descriptor_hub_desc_t const* desc_hub = (descriptor_hub_desc_t const*) _hub_buffer; + p_hub->port_count = desc_hub->bNbrPorts; + + // May need to GET_STATUS + + // Set Port Power to be able to detect connection, starting with port 1 + uint8_t const hub_port = 1; + return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete); +} + +static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + TU_ASSERT(XFER_RESULT_SUCCESS == result); + hub_interface_t* p_hub = get_itf(dev_addr); + + if (request->wIndex == p_hub->port_count) + { + // All ports are power -> queue notification status endpoint and + // complete the SET CONFIGURATION + TU_ASSERT( usbh_edpt_xfer(dev_addr, p_hub->ep_in, &p_hub->status_change, 1) ); + + usbh_driver_set_config_complete(dev_addr, p_hub->itf_num); + }else + { + // power next port + uint8_t const hub_port = (uint8_t) (request->wIndex + 1); + return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete); + } + + return true; +} + +//--------------------------------------------------------------------+ +// Connection Changes +//--------------------------------------------------------------------+ + +static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool connection_clear_conn_change_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool connection_port_reset_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); + +// callback as response of interrupt endpoint polling +bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports + (void) ep_addr; + TU_ASSERT(result == XFER_RESULT_SUCCESS); + + hub_interface_t* p_hub = get_itf(dev_addr); + + TU_LOG2(" Port Status Change = 0x%02X\r\n", p_hub->status_change); + + // Hub ignore bit0 in status change + for (uint8_t port=1; port <= p_hub->port_count; port++) + { + if ( tu_bit_test(p_hub->status_change, port) ) + { + hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete); + break; + } + } + + // NOTE: next status transfer is queued by usbh.c after handling this request + + return true; +} + +static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + TU_ASSERT(result == XFER_RESULT_SUCCESS); + + hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const port_num = (uint8_t) request->wIndex; + + // Connection change + if (p_hub->port_status.change.connection) + { + // Port is powered and enabled + //TU_VERIFY(port_status.status_current.port_power && port_status.status_current.port_enable, ); + + // Acknowledge Port Connection Change + hub_port_clear_feature(dev_addr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete); + }else + { + // Other changes are: Enable, Suspend, Over Current, Reset, L1 state + // TODO clear change + + // prepare for next hub status + // TODO continue with status_change, or maybe we can do it again with status + hub_status_pipe_queue(dev_addr); + } + + return true; +} + +static bool connection_clear_conn_change_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + TU_ASSERT(result == XFER_RESULT_SUCCESS); + + hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const port_num = (uint8_t) request->wIndex; + + if ( p_hub->port_status.status.connection ) + { + // Reset port if attach event + hub_port_reset(dev_addr, port_num, connection_port_reset_complete); + }else + { + // submit detach event + hcd_event_t event = + { + .rhport = usbh_get_rhport(dev_addr), + .event_id = HCD_EVENT_DEVICE_REMOVE, + .connection = + { + .hub_addr = dev_addr, + .hub_port = port_num + } + }; + + hcd_event_handler(&event, false); + } + + return true; +} + +static bool connection_port_reset_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + TU_ASSERT(result == XFER_RESULT_SUCCESS); + + // hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const port_num = (uint8_t) request->wIndex; + + // submit attach event + hcd_event_t event = + { + .rhport = usbh_get_rhport(dev_addr), + .event_id = HCD_EVENT_DEVICE_ATTACH, + .connection = + { + .hub_addr = dev_addr, + .hub_port = port_num + } + }; + + hcd_event_handler(&event, false); + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/host/hub.h b/circuitpython/lib/tinyusb/src/host/hub.h new file mode 100644 index 0000000..c4d5441 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/host/hub.h @@ -0,0 +1,196 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup group_class + * \defgroup ClassDriver_Hub Hub (Host only) + * \details Like most PC's OS, Hub support is completely hidden from Application. In fact, application cannot determine whether + * a device is mounted directly via roothub or via a hub's port. All Hub-related procedures are performed and managed + * by tinyusb stack. Unless you are trying to develop the stack itself, there are nothing else can be used by Application. + * \note Due to my laziness, only 1-level of Hub is supported. In other way, the stack cannot mount a hub via another hub. + * @{ + */ + +#ifndef _TUSB_HUB_H_ +#define _TUSB_HUB_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//D1...D0: Logical Power Switching Mode +//00: Ganged power switching (all ports’power at +//once) +//01: Individual port power switching +//1X: Reserved. Used only on 1.0 compliant hubs +//that implement no power switching +//D2: Identifies a Compound Device +//0: Hub is not part of a compound device. +//1: Hub is part of a compound device. +//D4...D3: Over-current Protection Mode +//00: Global Over-current Protection. The hub +//reports over-current as a summation of all +//ports’current draw, without a breakdown of +//individual port over-current status. +//01: Individual Port Over-current Protection. The +//hub reports over-current on a per-port basis. +//Each port has an over-current status. +//1X: No Over-current Protection. This option is +//allowed only for bus-powered hubs that do not +//implement over-current protection. +// +//D6...D5: TT Think TIme +//00: TT requires at most 8 FS bit times of inter +//transaction gap on a full-/low-speed +//downstream bus. +//01: TT requires at most 16 FS bit times. +//10: TT requires at most 24 FS bit times. +//11: TT requires at most 32 FS bit times. +//D7: Port Indicators Supported +//0: Port Indicators are not supported on its +//downstream facing ports and the +//PORT_INDICATOR request has no effect. +//1: Port Indicators are supported on its +//downstream facing ports and the +//PORT_INDICATOR request controls the +//indicators. See Section 11.5.3. +//D15...D8: Reserved + +typedef struct TU_ATTR_PACKED{ + uint8_t bLength ; ///< Size of descriptor + uint8_t bDescriptorType ; ///< Other_speed_Configuration Type + uint8_t bNbrPorts; + uint16_t wHubCharacteristics; + uint8_t bPwrOn2PwrGood; + uint8_t bHubContrCurrent; + uint8_t DeviceRemovable; // bitmap each bit for a port (from bit1) + uint8_t PortPwrCtrlMask; // just for compatibility, should be 0xff +} descriptor_hub_desc_t; + +TU_VERIFY_STATIC( sizeof(descriptor_hub_desc_t) == 9, "size is not correct"); + +enum { + HUB_REQUEST_GET_STATUS = 0 , + HUB_REQUEST_CLEAR_FEATURE = 1 , + + HUB_REQUEST_SET_FEATURE = 3 , + + HUB_REQUEST_GET_DESCRIPTOR = 6 , + HUB_REQUEST_SET_DESCRIPTOR = 7 , + HUB_REQUEST_CLEAR_TT_BUFFER = 8 , + HUB_REQUEST_RESET_TT = 9 , + HUB_REQUEST_GET_TT_STATE = 10 , + HUB_REQUEST_STOP_TT = 11 +}; + +enum { + HUB_FEATURE_HUB_LOCAL_POWER_CHANGE = 0, + HUB_FEATURE_HUB_OVER_CURRENT_CHANGE +}; + +enum{ + HUB_FEATURE_PORT_CONNECTION = 0, + HUB_FEATURE_PORT_ENABLE = 1, + HUB_FEATURE_PORT_SUSPEND = 2, + HUB_FEATURE_PORT_OVER_CURRENT = 3, + HUB_FEATURE_PORT_RESET = 4, + + HUB_FEATURE_PORT_POWER = 8, + HUB_FEATURE_PORT_LOW_SPEED = 9, + + HUB_FEATURE_PORT_CONNECTION_CHANGE = 16, + HUB_FEATURE_PORT_ENABLE_CHANGE = 17, + HUB_FEATURE_PORT_SUSPEND_CHANGE = 18, + HUB_FEATURE_PORT_OVER_CURRENT_CHANGE = 19, + HUB_FEATURE_PORT_RESET_CHANGE = 20, + HUB_FEATURE_PORT_TEST = 21, + HUB_FEATURE_PORT_INDICATOR = 22 +}; + +// data in response of HUB_REQUEST_GET_STATUS, wIndex = 0 (hub) +typedef struct { + union{ + struct TU_ATTR_PACKED { + uint16_t local_power_source : 1; + uint16_t over_current : 1; + uint16_t : 14; + }; + + uint16_t value; + } status, change; +} hub_status_response_t; + +TU_VERIFY_STATIC( sizeof(hub_status_response_t) == 4, "size is not correct"); + +// data in response of HUB_REQUEST_GET_STATUS, wIndex = Port num +typedef struct { + union { + struct TU_ATTR_PACKED { + uint16_t connection : 1; + uint16_t port_enable : 1; + uint16_t suspend : 1; + uint16_t over_current : 1; + uint16_t reset : 1; + + uint16_t : 3; + uint16_t port_power : 1; + uint16_t low_speed : 1; + uint16_t high_speed : 1; + uint16_t port_test_mode : 1; + uint16_t port_indicator_control : 1; + uint16_t TU_RESERVED : 3; + }; + + uint16_t value; + } status, change; +} hub_port_status_response_t; + +TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct"); + +bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb); +bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb); + +bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_complete_cb_t complete_cb); +bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_complete_cb_t complete_cb); +bool hub_status_pipe_queue(uint8_t dev_addr); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void hub_init (void); +bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); +bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); +bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void hub_close (uint8_t dev_addr); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_HUB_H_ */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/src/host/usbh.c b/circuitpython/lib/tinyusb/src/host/usbh.c new file mode 100644 index 0000000..192979c --- /dev/null +++ b/circuitpython/lib/tinyusb/src/host/usbh.c @@ -0,0 +1,1257 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED + +#include "tusb.h" +#include "host/usbh.h" +#include "host/usbh_classdriver.h" +#include "hub.h" + +//--------------------------------------------------------------------+ +// USBH Configuration +//--------------------------------------------------------------------+ + +#ifndef CFG_TUH_TASK_QUEUE_SZ +#define CFG_TUH_TASK_QUEUE_SZ 16 +#endif + +#ifndef CFG_TUH_INTERFACE_MAX +#define CFG_TUH_INTERFACE_MAX 8 +#endif + +// Debug level of USBD +#define USBH_DBG_LVL 2 + +//--------------------------------------------------------------------+ +// USBH-HCD common data structure +//--------------------------------------------------------------------+ + +// device0 struct must be strictly a subset of normal device struct +typedef struct +{ + // port + uint8_t rhport; + uint8_t hub_addr; + uint8_t hub_port; + uint8_t speed; + + struct TU_ATTR_PACKED + { + volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; + volatile uint8_t configured : 1; + volatile uint8_t suspended : 1; + }; +} usbh_dev0_t; + +typedef struct { + // port, must be same layout as usbh_dev0_t + uint8_t rhport; + uint8_t hub_addr; + uint8_t hub_port; + uint8_t speed; + + struct TU_ATTR_PACKED + { + volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; + volatile uint8_t configured : 1; + volatile uint8_t suspended : 1; + }; + + //------------- device descriptor -------------// + uint8_t ep0_size; + + uint16_t vid; + uint16_t pid; + + uint8_t i_manufacturer; + uint8_t i_product; + uint8_t i_serial; + + //------------- configuration descriptor -------------// + // uint8_t interface_count; // bNumInterfaces alias + + //------------- device -------------// + volatile uint8_t state; // device state, value from enum tusbh_device_state_t + + uint8_t itf2drv[CFG_TUH_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) + uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) + + struct TU_ATTR_PACKED + { + volatile bool busy : 1; + volatile bool stalled : 1; + volatile bool claimed : 1; + + // TODO merge ep2drv here, 4-bit should be sufficient + }ep_status[CFG_TUH_ENDPOINT_MAX][2]; + + // Mutex for claiming endpoint, only needed when using with preempted RTOS +#if CFG_TUSB_OS != OPT_OS_NONE + osal_mutex_def_t mutexdef; + osal_mutex_t mutex; +#endif + +} usbh_device_t; + + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// Invalid driver ID in itf2drv[] ep2drv[][] mapping +enum { DRVID_INVALID = 0xFFu }; +enum { ADDR_INVALID = 0xFFu }; + +#if CFG_TUSB_DEBUG >= 2 + #define DRIVER_NAME(_name) .name = _name, +#else + #define DRIVER_NAME(_name) +#endif + +static usbh_class_driver_t const usbh_class_drivers[] = +{ + #if CFG_TUH_CDC + { + DRIVER_NAME("CDC") + .init = cdch_init, + .open = cdch_open, + .set_config = cdch_set_config, + .xfer_cb = cdch_xfer_cb, + .close = cdch_close + }, + #endif + + #if CFG_TUH_MSC + { + DRIVER_NAME("MSC") + .init = msch_init, + .open = msch_open, + .set_config = msch_set_config, + .xfer_cb = msch_xfer_cb, + .close = msch_close + }, + #endif + + #if CFG_TUH_HID + { + DRIVER_NAME("HID") + .init = hidh_init, + .open = hidh_open, + .set_config = hidh_set_config, + .xfer_cb = hidh_xfer_cb, + .close = hidh_close + }, + #endif + + #if CFG_TUH_HUB + { + DRIVER_NAME("HUB") + .init = hub_init, + .open = hub_open, + .set_config = hub_set_config, + .xfer_cb = hub_xfer_cb, + .close = hub_close + }, + #endif + + #if CFG_TUH_VENDOR + { + DRIVER_NAME("VENDOR") + .init = cush_init, + .open = cush_open_subtask, + .xfer_cb = cush_isr, + .close = cush_close + } + #endif +}; + +enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; + +enum { RESET_DELAY = 500 }; // 200 USB specs say only 50ms but many devices require much longer + +enum { CONFIG_NUM = 1 }; // default to use configuration 1 + + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +static bool _usbh_initialized = false; + +// Device with address = 0 for enumeration +static usbh_dev0_t _dev0; + +// all devices excluding zero-address +// hub address start from CFG_TUH_DEVICE_MAX+1 +CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB]; + +// Event queue +// role device/host is used by OS NONE for mutex (disable usb isr) +OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); +static osal_queue_t _usbh_q; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; + +//------------- Helper Function -------------// + +TU_ATTR_ALWAYS_INLINE +static inline usbh_device_t* get_device(uint8_t dev_addr) +{ + TU_ASSERT(dev_addr, NULL); + return &_usbh_devices[dev_addr-1]; +} + +static bool enum_new_device(hcd_event_t* event); +static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port); +static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); + +// from usbh_control.c +extern bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + +//--------------------------------------------------------------------+ +// PUBLIC API (Parameter Verification is required) +//--------------------------------------------------------------------+ +bool tuh_mounted(uint8_t dev_addr) +{ + return get_device(dev_addr)->configured; +} + +bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) +{ + *vid = *pid = 0; + + TU_VERIFY(tuh_mounted(dev_addr)); + usbh_device_t const* dev = get_device(dev_addr); + + *vid = dev->vid; + *pid = dev->pid; + + return true; +} + +tusb_speed_t tuh_speed_get (uint8_t dev_addr) +{ + return (tusb_speed_t) (dev_addr ? get_device(dev_addr)->speed : _dev0.speed); +} + +#if CFG_TUSB_OS == OPT_OS_NONE +void osal_task_delay(uint32_t msec) +{ + (void) msec; + + const uint32_t start = hcd_frame_number(TUH_OPT_RHPORT); + while ( ( hcd_frame_number(TUH_OPT_RHPORT) - start ) < msec ) {} +} +#endif + +//--------------------------------------------------------------------+ +// Descriptors +//--------------------------------------------------------------------+ + +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16( TU_U16(type, index) ), + .wIndex = 0, + .wLength = tu_htole16(len) + }; + + TU_ASSERT( tuh_control_xfer(daddr, &request, buffer, complete_cb) ); + + return true; +} + +bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb); +} + +bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb); +} + +bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, + void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16( TU_U16(TUSB_DESC_STRING, index) ), + .wIndex = tu_htole16(language_id), + .wLength = tu_htole16(len) + }; + + TU_ASSERT( tuh_control_xfer(daddr, &request, buffer, complete_cb) ); + return true; +} + +// Get manufacturer string descriptor +bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + TU_VERIFY(tuh_mounted(daddr)); + usbh_device_t const* dev = get_device(daddr); + if (dev->i_manufacturer == 0) { + return false; + } + return tuh_descriptor_string_get(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb); +} + +// Get product string descriptor +bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + TU_VERIFY(tuh_mounted(daddr)); + usbh_device_t const* dev = get_device(daddr); + if (dev->i_product == 0) { + return false; + } + return tuh_descriptor_string_get(daddr, language_id, dev->i_product, buffer, len, complete_cb); +} + +// Get serial string descriptor +bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + TU_VERIFY(tuh_mounted(daddr)); + usbh_device_t const* dev = get_device(daddr); + if (dev->i_serial == 0) { + return false; + } + return tuh_descriptor_string_get(daddr, language_id, dev->i_serial, buffer, len, complete_cb); +} + +bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb) +{ + TU_LOG2("Set Configuration = %d\r\n", config_num); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = tu_htole16(config_num), + .wIndex = 0, + .wLength = 0 + }; + + TU_ASSERT( tuh_control_xfer(daddr, &request, NULL, complete_cb) ); + return true; +} + +//--------------------------------------------------------------------+ +// CLASS-USBD API (don't require to verify parameters) +//--------------------------------------------------------------------+ + +bool tuh_inited(void) +{ + return _usbh_initialized; +} + +bool tuh_init(uint8_t rhport) +{ + // skip if already initialized + if (_usbh_initialized) return _usbh_initialized; + + TU_LOG2("USBH init\r\n"); + TU_LOG2_INT(sizeof(usbh_device_t)); + + tu_memclr(_usbh_devices, sizeof(_usbh_devices)); + tu_memclr(&_dev0, sizeof(_dev0)); + + //------------- Enumeration & Reporter Task init -------------// + _usbh_q = osal_queue_create( &_usbh_qdef ); + TU_ASSERT(_usbh_q != NULL); + + //------------- Semaphore, Mutex for Control Pipe -------------// + for(uint8_t i=0; imutex = osal_mutex_create(&dev->mutexdef); + TU_ASSERT(dev->mutex); +#endif + + memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping + memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping + } + + // Class drivers init + for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + { + TU_LOG2("%s init\r\n", usbh_class_drivers[drv_id].name); + usbh_class_drivers[drv_id].init(); + } + + TU_ASSERT(hcd_init(rhport)); + hcd_int_enable(rhport); + + _usbh_initialized = true; + return true; +} + +/* USB Host Driver task + * This top level thread manages all host controller event and delegates events to class-specific drivers. + * This should be called periodically within the mainloop or rtos thread. + * + @code + int main(void) + { + application_init(); + tusb_init(); + + while(1) // the mainloop + { + application_code(); + tuh_task(); // tinyusb host task + } + } + @endcode + */ +void tuh_task(void) +{ + // Skip if stack is not initialized + if ( !tusb_inited() ) return; + + // Loop until there is no more events in the queue + while (1) + { + hcd_event_t event; + if ( !osal_queue_receive(_usbh_q, &event) ) return; + + switch (event.event_id) + { + case HCD_EVENT_DEVICE_ATTACH: + // TODO due to the shared _usbh_ctrl_buf, we must complete enumerating + // one device before enumerating another one. + TU_LOG2("USBH DEVICE ATTACH\r\n"); + enum_new_device(&event); + break; + + case HCD_EVENT_DEVICE_REMOVE: + TU_LOG2("USBH DEVICE REMOVED\r\n"); + process_device_unplugged(event.rhport, event.connection.hub_addr, event.connection.hub_port); + + #if CFG_TUH_HUB + // TODO remove + if ( event.connection.hub_addr != 0) + { + // done with hub, waiting for next data on status pipe + (void) hub_status_pipe_queue( event.connection.hub_addr ); + } + #endif + break; + + case HCD_EVENT_XFER_COMPLETE: + { + uint8_t const ep_addr = event.xfer_complete.ep_addr; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); + + TU_LOG2("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len); + + if (event.dev_addr == 0) + { + // device 0 only has control endpoint + TU_ASSERT(epnum == 0, ); + usbh_control_xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + } + else + { + usbh_device_t* dev = get_device(event.dev_addr); + dev->ep_status[epnum][ep_dir].busy = false; + dev->ep_status[epnum][ep_dir].claimed = 0; + + if ( 0 == epnum ) + { + usbh_control_xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + }else + { + uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; + TU_ASSERT(drv_id < USBH_CLASS_DRIVER_COUNT, ); + + TU_LOG2("%s xfer callback\r\n", usbh_class_drivers[drv_id].name); + usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + } + } + } + break; + + case USBH_EVENT_FUNC_CALL: + if ( event.func_call.func ) event.func_call.func(event.func_call.param); + break; + + default: break; + } + } +} + +//--------------------------------------------------------------------+ +// USBH API For Class Driver +//--------------------------------------------------------------------+ + +uint8_t usbh_get_rhport(uint8_t dev_addr) +{ + return (dev_addr == 0) ? _dev0.rhport : get_device(dev_addr)->rhport; +} + +uint8_t* usbh_get_enum_buf(void) +{ + return _usbh_ctrl_buf; +} + +void usbh_int_set(bool enabled) +{ + // TODO all host controller + if (enabled) + { + hcd_int_enable(TUH_OPT_RHPORT); + }else + { + hcd_int_disable(TUH_OPT_RHPORT); + } +} + +//--------------------------------------------------------------------+ +// HCD Event Handler +//--------------------------------------------------------------------+ + +void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) +{ + if (dev_addr) + { + usbh_device_t const* dev = get_device(dev_addr); + + devtree_info->rhport = dev->rhport; + devtree_info->hub_addr = dev->hub_addr; + devtree_info->hub_port = dev->hub_port; + devtree_info->speed = dev->speed; + }else + { + devtree_info->rhport = _dev0.rhport; + devtree_info->hub_addr = _dev0.hub_addr; + devtree_info->hub_port = _dev0.hub_port; + devtree_info->speed = _dev0.speed; + } +} + +void hcd_event_handler(hcd_event_t const* event, bool in_isr) +{ + switch (event->event_id) + { + default: + osal_queue_send(_usbh_q, event, in_isr); + break; + } +} + +void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) +{ + hcd_event_t event = + { + .rhport = 0, // TODO correct rhport + .event_id = HCD_EVENT_XFER_COMPLETE, + .dev_addr = dev_addr, + .xfer_complete = + { + .ep_addr = ep_addr, + .result = result, + .len = xferred_bytes + } + }; + + hcd_event_handler(&event, in_isr); +} + +void hcd_event_device_attach(uint8_t rhport, bool in_isr) +{ + hcd_event_t event = + { + .rhport = rhport, + .event_id = HCD_EVENT_DEVICE_ATTACH + }; + + event.connection.hub_addr = 0; + event.connection.hub_port = 0; + + hcd_event_handler(&event, in_isr); +} + +void hcd_event_device_remove(uint8_t hostid, bool in_isr) +{ + hcd_event_t event = + { + .rhport = hostid, + .event_id = HCD_EVENT_DEVICE_REMOVE + }; + + event.connection.hub_addr = 0; + event.connection.hub_port = 0; + + hcd_event_handler(&event, in_isr); +} + + +// a device unplugged on hostid, hub_addr, hub_port +// return true if found and unmounted device, false if cannot find +void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) +{ + //------------- find the all devices (star-network) under port that is unplugged -------------// + // TODO mark as disconnected in ISR, also handle dev0 + for ( uint8_t dev_id = 0; dev_id < TU_ARRAY_SIZE(_usbh_devices); dev_id++ ) + { + usbh_device_t* dev = &_usbh_devices[dev_id]; + uint8_t const dev_addr = dev_id+1; + + // TODO Hub multiple level + if (dev->rhport == rhport && + (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub + (hub_port == 0 || dev->hub_port == hub_port) && + dev->state != TUSB_DEVICE_STATE_UNPLUG) + { + // Invoke callback before close driver + if (tuh_umount_cb) tuh_umount_cb(dev_addr); + + // Close class driver + for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + { + TU_LOG2("%s close\r\n", usbh_class_drivers[drv_id].name); + usbh_class_drivers[drv_id].close(dev_addr); + } + + hcd_device_close(rhport, dev_addr); + + // release all endpoints associated with the device + memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping + memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping + tu_memclr(dev->ep_status, sizeof(dev->ep_status)); + + dev->state = TUSB_DEVICE_STATE_UNPLUG; + dev->configured = false; + } + } +} + +//--------------------------------------------------------------------+ +// INTERNAL HELPER +//--------------------------------------------------------------------+ +static uint8_t get_new_address(bool is_hub) +{ + uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; + uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); + + for (uint8_t i=0; i < count; i++) + { + uint8_t const addr = start + i; + if (get_device(addr)->state == TUSB_DEVICE_STATE_UNPLUG) return addr; + } + return ADDR_INVALID; +} + +void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) +{ + usbh_device_t* dev = get_device(dev_addr); + + for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) + { + // continue with next valid interface + // TODO skip IAD binding interface such as CDCs + uint8_t const drv_id = dev->itf2drv[itf_num]; + if (drv_id != DRVID_INVALID) + { + usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + TU_LOG2("%s set config: itf = %u\r\n", driver->name, itf_num); + driver->set_config(dev_addr, itf_num); + break; + } + } + + // all interface are configured + if (itf_num == CFG_TUH_INTERFACE_MAX) + { + // Invoke callback if available + if (tuh_mount_cb) tuh_mount_cb(dev_addr); + } +} + +//--------------------------------------------------------------------+ +// Enumeration Process +// is a lengthy process with a series of control transfer to configure +// newly attached device. Each step is handled by a function in this +// section +// TODO due to the shared _usbh_ctrl_buf, we must complete enumerating +// one device before enumerating another one. +//--------------------------------------------------------------------+ + +static bool enum_request_addr0_device_desc(void); +static bool enum_request_set_addr(void); + +static bool enum_get_addr0_device_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_set_address_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_get_device_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_get_9byte_config_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_get_config_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_set_config_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); + +#if CFG_TUH_HUB +static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) dev_addr; (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + enum_request_addr0_device_desc(); + return true; +} + +static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) dev_addr; (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + enum_request_set_addr(); + + // done with hub, waiting for next data on status pipe + (void) hub_status_pipe_queue( _dev0.hub_addr ); + + return true; +} + +static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) dev_addr; (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + hub_port_status_response_t port_status; + memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); + + // Acknowledge Port Reset Change if Reset Successful + if (port_status.change.reset) + { + TU_ASSERT( hub_port_clear_feature(_dev0.hub_addr, _dev0.hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset1_complete) ); + } + + return true; +} + +static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) dev_addr; (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + hub_port_status_response_t port_status; + memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); + + if ( !port_status.status.connection ) + { + // device unplugged while delaying, nothing else to do, queue hub status + return hub_status_pipe_queue(dev_addr); + } + + _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : + (port_status.status.low_speed ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; + + // Acknowledge Port Reset Change + if (port_status.change.reset) + { + hub_port_clear_feature(_dev0.hub_addr, _dev0.hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset0_complete); + } + + return true; +} +#endif + +static bool enum_new_device(hcd_event_t* event) +{ + _dev0.rhport = event->rhport; // TODO refractor integrate to device_pool + _dev0.hub_addr = event->connection.hub_addr; + _dev0.hub_port = event->connection.hub_port; + + //------------- connected/disconnected directly with roothub -------------// + if (_dev0.hub_addr == 0) + { + // wait until device is stable TODO non blocking + osal_task_delay(RESET_DELAY); + + // device unplugged while delaying + if ( !hcd_port_connect_status(_dev0.rhport) ) return true; + + _dev0.speed = hcd_port_speed_get(_dev0.rhport ); + TU_LOG2("%s Speed\r\n", tusb_speed_str[_dev0.speed]); + + enum_request_addr0_device_desc(); + } +#if CFG_TUH_HUB + //------------- connected/disconnected via hub -------------// + else + { + // wait until device is stable + osal_task_delay(RESET_DELAY); + TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete) ); + } +#endif // CFG_TUH_HUB + + return true; +} + +static bool enum_request_addr0_device_desc(void) +{ + // TODO probably doesn't need to open/close each enumeration + uint8_t const addr0 = 0; + TU_ASSERT( usbh_edpt_control_open(addr0, 8) ); + + // Get first 8 bytes of device descriptor for Control Endpoint size + TU_LOG2("Get 8 byte of Device Descriptor\r\n"); + + TU_ASSERT(tuh_descriptor_device_get(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete)); + return true; +} + +// After Get Device Descriptor of Address 0 +static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) request; + TU_ASSERT(0 == dev_addr); + + if (XFER_RESULT_SUCCESS != result) + { +#if CFG_TUH_HUB + // TODO remove, waiting for next data on status pipe + if (_dev0.hub_addr != 0) hub_status_pipe_queue(_dev0.hub_addr); +#endif + + return false; + } + + tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + TU_ASSERT( tu_desc_type(desc_device) == TUSB_DESC_DEVICE ); + + // Reset device again before Set Address + TU_LOG2("Port reset \r\n"); + + if (_dev0.hub_addr == 0) + { + // connected directly to roothub + hcd_port_reset( _dev0.rhport ); // reset port after 8 byte descriptor + osal_task_delay(RESET_DELAY); + + enum_request_set_addr(); + } +#if CFG_TUH_HUB + else + { + // after RESET_DELAY the hub_port_reset() already complete + TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, NULL) ); + osal_task_delay(RESET_DELAY); + + tuh_task(); // FIXME temporarily to clean up port_reset control transfer + + TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status1_complete) ); + } +#endif + + return true; +} + +static bool enum_request_set_addr(void) +{ + uint8_t const addr0 = 0; + tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + + // Get new address + uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); + TU_ASSERT(new_addr != ADDR_INVALID); + + TU_LOG2("Set Address = %d\r\n", new_addr); + + usbh_device_t* new_dev = get_device(new_addr); + + new_dev->rhport = _dev0.rhport; + new_dev->hub_addr = _dev0.hub_addr; + new_dev->hub_port = _dev0.hub_port; + new_dev->speed = _dev0.speed; + new_dev->connected = 1; + new_dev->ep0_size = desc_device->bMaxPacketSize0; + + tusb_control_request_t const new_request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = tu_htole16(new_addr), + .wIndex = 0, + .wLength = 0 + }; + + TU_ASSERT( tuh_control_xfer(addr0, &new_request, NULL, enum_set_address_complete) ); + + return true; +} + +// After SET_ADDRESS is complete +static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + TU_ASSERT(0 == dev_addr); + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + uint8_t const new_addr = (uint8_t const) request->wValue; + + usbh_device_t* new_dev = get_device(new_addr); + new_dev->addressed = 1; + + // TODO close device 0, may not be needed + hcd_device_close(_dev0.rhport, 0); + + // open control pipe for new address + TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size) ); + + // Get full device descriptor + TU_LOG2("Get Device Descriptor\r\n"); + + TU_ASSERT(tuh_descriptor_device_get(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete)); + return true; +} + +static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + usbh_device_t* dev = get_device(dev_addr); + + dev->vid = desc_device->idVendor; + dev->pid = desc_device->idProduct; + dev->i_manufacturer = desc_device->iManufacturer; + dev->i_product = desc_device->iProduct; + dev->i_serial = desc_device->iSerialNumber; + +// if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); + + // Get 9-byte for total length + uint8_t const config_idx = CONFIG_NUM - 1; + TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); + TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); + return true; +} + +static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + // TODO not enough buffer to hold configuration descriptor + uint8_t const * desc_config = _usbh_ctrl_buf; + + // Use offsetof to avoid pointer to the odd/misaligned address + uint16_t const total_len = tu_le16toh( tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) ); + + TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE); + + // Get full configuration descriptor + uint8_t const config_idx = CONFIG_NUM - 1; + TU_LOG2("Get Configuration[0] Descriptor\r\n"); + TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); + return true; +} + +static bool enum_get_config_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + // Parse configuration & set up drivers + // Driver open aren't allowed to make any usb transfer yet + TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf) ); + + TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, enum_set_config_complete) ); + return true; +} + +static bool enum_set_config_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + TU_LOG2("Device configured\r\n"); + usbh_device_t* dev = get_device(dev_addr); + dev->configured = 1; + dev->state = TUSB_DEVICE_STATE_CONFIGURED; + + // Start the Set Configuration process for interfaces (itf = DRVID_INVALID) + // Since driver can perform control transfer within its set_config, this is done asynchronously. + // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() + // TODO use separated API instead of using DRVID_INVALID + usbh_driver_set_config_complete(dev_addr, DRVID_INVALID); + + return true; +} + +static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) +{ + usbh_device_t* dev = get_device(dev_addr); + + uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); + uint8_t const* p_desc = tu_desc_next(desc_cfg); + + // parse each interfaces + while( p_desc < desc_end ) + { + uint8_t assoc_itf_count = 1; + + // Class will always starts with Interface Association (if any) and then Interface descriptor + if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) + { + tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; + assoc_itf_count = desc_iad->bInterfaceCount; + + p_desc = tu_desc_next(p_desc); // next to Interface + + // IAD's first interface number and class should match with opened interface + //TU_ASSERT(desc_iad->bFirstInterface == desc_itf->bInterfaceNumber && + // desc_iad->bFunctionClass == desc_itf->bInterfaceClass); + } + + TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); + tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; + +#if CFG_TUH_MIDI + // MIDI has 2 interfaces (Audio Control v1 + MIDIStreaming) but does not have IAD + // manually increase the associated count + if (1 == assoc_itf_count && + TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && + AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) + { + assoc_itf_count = 2; + } +#endif + + uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); + TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); + + if (desc_itf->bInterfaceClass == TUSB_CLASS_HUB && dev->hub_addr != 0) + { + // TODO Attach hub to Hub is not currently supported + // skip this interface + TU_LOG(USBH_DBG_LVL, "Only 1 level of HUB is supported\r\n"); + } + else + { + // Find driver for this interface + uint8_t drv_id; + for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + { + usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + + if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) + { + // open successfully + TU_LOG2(" %s opened\r\n", driver->name); + + // bind (associated) interfaces to found driver + for(uint8_t i=0; ibInterfaceNumber+i; + + // Interface number must not be used already + TU_ASSERT( DRVID_INVALID == dev->itf2drv[itf_num] ); + dev->itf2drv[itf_num] = drv_id; + } + + // bind all endpoints to found driver + tu_edpt_bind_driver(dev->ep2drv, desc_itf, drv_len, drv_id); + + break; // exit driver find loop + } + } + + if( drv_id >= USBH_CLASS_DRIVER_COUNT ) + { + TU_LOG(USBH_DBG_LVL, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", + desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); + } + } + + // next Interface or IAD descriptor + p_desc += drv_len; + } + + return true; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + usbh_device_t* dev = get_device(dev_addr); + +#if CFG_TUSB_OS != OPT_OS_NONE + // pre-check to help reducing mutex lock + TU_VERIFY((dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 0)); + osal_mutex_lock(dev->mutex, OSAL_TIMEOUT_WAIT_FOREVER); +#endif + + // can only claim the endpoint if it is not busy and not claimed yet. + bool const ret = (dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 0); + if (ret) + { + dev->ep_status[epnum][dir].claimed = 1; + } + +#if CFG_TUSB_OS != OPT_OS_NONE + osal_mutex_unlock(dev->mutex); +#endif + + return ret; +} + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + usbh_device_t* dev = get_device(dev_addr); + +#if CFG_TUSB_OS != OPT_OS_NONE + osal_mutex_lock(dev->mutex, OSAL_TIMEOUT_WAIT_FOREVER); +#endif + + // can only release the endpoint if it is claimed and not busy + bool const ret = (dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 1); + if (ret) + { + dev->ep_status[epnum][dir].claimed = 0; + } + +#if CFG_TUSB_OS != OPT_OS_NONE + osal_mutex_unlock(dev->mutex); +#endif + + return ret; +} + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + usbh_device_t* dev = get_device(dev_addr); + + TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); + + // Attempt to transfer on a busy endpoint, sound like an race condition ! + TU_ASSERT(dev->ep_status[epnum][dir].busy == 0); + + // Set busy first since the actual transfer can be complete before hcd_edpt_xfer() + // could return and USBH task can preempt and clear the busy + dev->ep_status[epnum][dir].busy = true; + + if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) + { + TU_LOG2("OK\r\n"); + return true; + }else + { + // HCD error, mark endpoint as ready to allow next transfer + dev->ep_status[epnum][dir].busy = false; + dev->ep_status[epnum][dir].claimed = 0; + TU_LOG2("failed\r\n"); + TU_BREAKPOINT(); + return false; + } +} + +static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) +{ + TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr); + + tusb_desc_endpoint_t ep0_desc = + { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = 0, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = max_packet_size, + .bInterval = 0 + }; + + return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); +} + +bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) +{ + usbh_device_t* dev = get_device(dev_addr); + TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) dev->speed)); + + return hcd_edpt_open(rhport, dev_addr, desc_ep); +} + +bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + usbh_device_t* dev = get_device(dev_addr); + + return dev->ep_status[epnum][dir].busy; +} + + + +#endif diff --git a/circuitpython/lib/tinyusb/src/host/usbh.h b/circuitpython/lib/tinyusb/src/host/usbh.h new file mode 100644 index 0000000..9465d1d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/host/usbh.h @@ -0,0 +1,130 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_USBH_H_ +#define _TUSB_USBH_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "common/tusb_common.h" +#include "hcd.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +typedef bool (*tuh_control_complete_cb_t)(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result); + +//--------------------------------------------------------------------+ +// APPLICATION API +//--------------------------------------------------------------------+ + +// Init host stack +bool tuh_init(uint8_t rhport); + +// Check if host stack is already initialized +bool tuh_inited(void); + +// Task function should be called in main/rtos loop +void tuh_task(void); + +// Interrupt handler, name alias to HCD +extern void hcd_int_handler(uint8_t rhport); +#define tuh_int_handler hcd_int_handler + +bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid); + +tusb_speed_t tuh_speed_get(uint8_t daddr); + +// Check if device is connected and configured +bool tuh_mounted(uint8_t daddr); + +// Check if device is suspended +TU_ATTR_ALWAYS_INLINE +static inline bool tuh_suspended(uint8_t daddr) +{ + // TODO implement suspend & resume on host + (void) daddr; + return false; +} + +// Check if device is ready to communicate with +TU_ATTR_ALWAYS_INLINE +static inline bool tuh_ready(uint8_t daddr) +{ + return tuh_mounted(daddr) && !tuh_suspended(daddr); +} + +// Carry out control transfer +bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); + +// Set Configuration +// config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 +bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb); + +//------------- descriptors -------------// + +// Get an descriptor +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, + void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get device descriptor +bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get configuration descriptor +bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get string descriptor +bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, + void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get manufacturer string descriptor +bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get product string descriptor +bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get serial string descriptor +bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +//--------------------------------------------------------------------+ +// APPLICATION CALLBACK +//--------------------------------------------------------------------+ +//TU_ATTR_WEAK uint8_t tuh_attach_cb (tusb_desc_device_t const *desc_device); + +// Invoked when device is mounted (configured) +TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); + +/// Invoked when device is unmounted (bus reset/unplugged) +TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/host/usbh_classdriver.h b/circuitpython/lib/tinyusb/src/host/usbh_classdriver.h new file mode 100644 index 0000000..2f9957c --- /dev/null +++ b/circuitpython/lib/tinyusb/src/host/usbh_classdriver.h @@ -0,0 +1,85 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_USBH_CLASSDRIVER_H_ +#define _TUSB_USBH_CLASSDRIVER_H_ + +#include "osal/osal.h" +#include "common/tusb_fifo.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Class Driver API +//--------------------------------------------------------------------+ + +typedef struct { + #if CFG_TUSB_DEBUG >= 2 + char const* name; + #endif + + void (* const init )(void); + bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); + bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); + bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + void (* const close )(uint8_t dev_addr); +} usbh_class_driver_t; + +// Call by class driver to tell USBH that it has complete the enumeration +void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num); + +uint8_t usbh_get_rhport(uint8_t dev_addr); + +uint8_t* usbh_get_enum_buf(void); + +void usbh_int_set(bool enabled); + +//--------------------------------------------------------------------+ +// USBH Endpoint API +//--------------------------------------------------------------------+ + +// Open an endpoint +bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep); + +// Submit a usb transfer +bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); + +// Claim an endpoint before submitting a transfer. +// If caller does not make any transfer, it must release endpoint for others. +bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr); + +bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr); + +// Check if endpoint transferring is complete +bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/host/usbh_control.c b/circuitpython/lib/tinyusb/src/host/usbh_control.c new file mode 100644 index 0000000..d034eec --- /dev/null +++ b/circuitpython/lib/tinyusb/src/host/usbh_control.c @@ -0,0 +1,138 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED + +#include "tusb.h" +#include "usbh_classdriver.h" + +enum +{ + STAGE_SETUP, + STAGE_DATA, + STAGE_ACK +}; + +typedef struct +{ + tusb_control_request_t request TU_ATTR_ALIGNED(4); + + uint8_t stage; + uint8_t* buffer; + tuh_control_complete_cb_t complete_cb; +} usbh_control_xfer_t; + +static usbh_control_xfer_t _ctrl_xfer; + +//CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN +//static uint8_t _tuh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) +{ + // TODO need to claim the endpoint first + const uint8_t rhport = usbh_get_rhport(dev_addr); + + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = buffer; + _ctrl_xfer.stage = STAGE_SETUP; + _ctrl_xfer.complete_cb = complete_cb; + + TU_LOG2("Control Setup (addr = %u): ", dev_addr); + TU_LOG2_VAR(request); + TU_LOG2("\r\n"); + + // Send setup packet + TU_ASSERT( hcd_setup_send(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.request) ); + + return true; +} + +static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) +{ + TU_LOG2("\r\n"); + if (_ctrl_xfer.complete_cb) _ctrl_xfer.complete_cb(dev_addr, &_ctrl_xfer.request, result); +} + +bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) ep_addr; + (void) xferred_bytes; + + const uint8_t rhport = usbh_get_rhport(dev_addr); + + tusb_control_request_t const * request = &_ctrl_xfer.request; + + if (XFER_RESULT_SUCCESS != result) + { + TU_LOG2("Control failed: result = %d\r\n", result); + + // terminate transfer if any stage failed + _xfer_complete(dev_addr, result); + }else + { + switch(_ctrl_xfer.stage) + { + case STAGE_SETUP: + _ctrl_xfer.stage = STAGE_DATA; + if (request->wLength) + { + // DATA stage: initial data toggle is always 1 + hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength); + return true; + } + __attribute__((fallthrough)); + + case STAGE_DATA: + _ctrl_xfer.stage = STAGE_ACK; + + if (request->wLength) + { + TU_LOG2("Control data (addr = %u):\r\n", dev_addr); + TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2); + } + + // ACK stage: toggle is always 1 + hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0); + break; + + case STAGE_ACK: + _xfer_complete(dev_addr, result); + break; + + default: return false; + } + } + + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/osal/osal.h b/circuitpython/lib/tinyusb/src/osal/osal.h new file mode 100644 index 0000000..7111bbd --- /dev/null +++ b/circuitpython/lib/tinyusb/src/osal/osal.h @@ -0,0 +1,89 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OSAL_H_ +#define _TUSB_OSAL_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "common/tusb_common.h" + +// Return immediately +#define OSAL_TIMEOUT_NOTIMEOUT (0) +// Default timeout +#define OSAL_TIMEOUT_NORMAL (10) +// Wait forever +#define OSAL_TIMEOUT_WAIT_FOREVER (UINT32_MAX) + +#define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER + +typedef void (*osal_task_func_t)( void * ); + +#if CFG_TUSB_OS == OPT_OS_NONE + #include "osal_none.h" +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + #include "osal_freertos.h" +#elif CFG_TUSB_OS == OPT_OS_MYNEWT + #include "osal_mynewt.h" +#elif CFG_TUSB_OS == OPT_OS_PICO + #include "osal_pico.h" +#elif CFG_TUSB_OS == OPT_OS_RTTHREAD + #include "osal_rtthread.h" +#elif CFG_TUSB_OS == OPT_OS_RTX4 + #include "osal_rtx4.h" +#elif CFG_TUSB_OS == OPT_OS_CUSTOM + #include "tusb_os_custom.h" // implemented by application +#else + #error OS is not supported yet +#endif + +//--------------------------------------------------------------------+ +// OSAL Porting API +// Should be implemented as static inline function in osal_port.h header +/* + static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); + static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); + static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); + static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed + + static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); + static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); + static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl); + + static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef); + static inline bool osal_queue_receive(osal_queue_t qhdl, void* data); + static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); + static inline bool osal_queue_empty(osal_queue_t qhdl); +*/ +//--------------------------------------------------------------------+ + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OSAL_H_ */ diff --git a/circuitpython/lib/tinyusb/src/osal/osal_freertos.h b/circuitpython/lib/tinyusb/src/osal/osal_freertos.h new file mode 100644 index 0000000..69a026d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/osal/osal_freertos.h @@ -0,0 +1,174 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OSAL_FREERTOS_H_ +#define _TUSB_OSAL_FREERTOS_H_ + +// FreeRTOS Headers +#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,FreeRTOS.h) +#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,semphr.h) +#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,queue.h) +#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,task.h) + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +static inline void osal_task_delay(uint32_t msec) +{ + vTaskDelay( pdMS_TO_TICKS(msec) ); +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef StaticSemaphore_t osal_semaphore_def_t; +typedef SemaphoreHandle_t osal_semaphore_t; + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + return xSemaphoreCreateBinaryStatic(semdef); +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +{ + if ( !in_isr ) + { + return xSemaphoreGive(sem_hdl) != 0; + } + else + { + BaseType_t xHigherPriorityTaskWoken; + BaseType_t res = xSemaphoreGiveFromISR(sem_hdl, &xHigherPriorityTaskWoken); + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + // not needed after https://github.com/espressif/esp-idf/commit/c5fd79547ac9b7bae06fa660e9f814d18d3390b7 + if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR(); +#else + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +#endif + + return res != 0; + } +} + +static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + return xSemaphoreTake(sem_hdl, ticks); +} + +static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) +{ + xQueueReset(sem_hdl); +} + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef StaticSemaphore_t osal_mutex_def_t; +typedef SemaphoreHandle_t osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +{ + return xSemaphoreCreateMutexStatic(mdef); +} + +static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +{ + return osal_semaphore_wait(mutex_hdl, msec); +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +{ + return xSemaphoreGive(mutex_hdl); +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ + static _type _name##_##buf[_depth];\ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; + + StaticQueue_t sq; +}osal_queue_def_t; + +typedef QueueHandle_t osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +{ + return xQueueReceive(qhdl, data, portMAX_DELAY); +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +{ + if ( !in_isr ) + { + return xQueueSendToBack(qhdl, data, OSAL_TIMEOUT_WAIT_FOREVER) != 0; + } + else + { + BaseType_t xHigherPriorityTaskWoken; + BaseType_t res = xQueueSendToBackFromISR(qhdl, data, &xHigherPriorityTaskWoken); + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + // not needed after https://github.com/espressif/esp-idf/commit/c5fd79547ac9b7bae06fa660e9f814d18d3390b7 + if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR(); +#else + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +#endif + + return res != 0; + } +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + return uxQueueMessagesWaiting(qhdl) == 0; +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/osal/osal_mynewt.h b/circuitpython/lib/tinyusb/src/osal/osal_mynewt.h new file mode 100644 index 0000000..78a257c --- /dev/null +++ b/circuitpython/lib/tinyusb/src/osal/osal_mynewt.h @@ -0,0 +1,174 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef OSAL_MYNEWT_H_ +#define OSAL_MYNEWT_H_ + +#include "os/os.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +static inline void osal_task_delay(uint32_t msec) +{ + os_time_delay( os_time_ms_to_ticks32(msec) ); +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef struct os_sem osal_semaphore_def_t; +typedef struct os_sem* osal_semaphore_t; + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +{ + (void) in_isr; + return os_sem_release(sem_hdl) == OS_OK; +} + +static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); + return os_sem_pend(sem_hdl, ticks) == OS_OK; +} + +static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) +{ + // TODO implement later +} + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef struct os_mutex osal_mutex_def_t; +typedef struct os_mutex* osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +{ + return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL; +} + +static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); + return os_mutex_pend(mutex_hdl, ticks) == OS_OK; +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +{ + return os_mutex_release(mutex_hdl) == OS_OK; +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ + static _type _name##_##buf[_depth];\ + static struct os_event _name##_##evbuf[_depth];\ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\ + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; + void* evbuf; + + struct os_mempool mpool; + struct os_mempool epool; + + struct os_eventq evq; +}osal_queue_def_t; + +typedef osal_queue_def_t* osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usbd queue") ) return NULL; + if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usbd evqueue") ) return NULL; + + os_eventq_init(&qdef->evq); + return (osal_queue_t) qdef; +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +{ + struct os_event* ev; + ev = os_eventq_get(&qhdl->evq); + + memcpy(data, ev->ev_arg, qhdl->item_sz); // copy message + os_memblock_put(&qhdl->mpool, ev->ev_arg); // put back mem block + os_memblock_put(&qhdl->epool, ev); // put back ev block + + return true; +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +{ + (void) in_isr; + + // get a block from mem pool for data + void* ptr = os_memblock_get(&qhdl->mpool); + if (!ptr) return false; + memcpy(ptr, data, qhdl->item_sz); + + // get a block from event pool to put into queue + struct os_event* ev = (struct os_event*) os_memblock_get(&qhdl->epool); + if (!ev) + { + os_memblock_put(&qhdl->mpool, ptr); + return false; + } + tu_memclr(ev, sizeof(struct os_event)); + ev->ev_arg = ptr; + + os_eventq_put(&qhdl->evq, ev); + + return true; +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + return STAILQ_EMPTY(&qhdl->evq.evq_list); +} + + +#ifdef __cplusplus + } +#endif + +#endif /* OSAL_MYNEWT_H_ */ diff --git a/circuitpython/lib/tinyusb/src/osal/osal_none.h b/circuitpython/lib/tinyusb/src/osal/osal_none.h new file mode 100644 index 0000000..e1dd95c --- /dev/null +++ b/circuitpython/lib/tinyusb/src/osal/osal_none.h @@ -0,0 +1,179 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OSAL_NONE_H_ +#define _TUSB_OSAL_NONE_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ + + +//--------------------------------------------------------------------+ +// Binary Semaphore API +//--------------------------------------------------------------------+ +typedef struct +{ + volatile uint16_t count; +}osal_semaphore_def_t; + +typedef osal_semaphore_def_t* osal_semaphore_t; + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + semdef->count = 0; + return semdef; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +{ + (void) in_isr; + sem_hdl->count++; + return true; +} + +// TODO blocking for now +static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) +{ + (void) msec; + + while (sem_hdl->count == 0) { } + sem_hdl->count--; + + return true; +} + +static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) +{ + sem_hdl->count = 0; +} + +//--------------------------------------------------------------------+ +// MUTEX API +// Within tinyusb, mutex is never used in ISR context +//--------------------------------------------------------------------+ +typedef osal_semaphore_def_t osal_mutex_def_t; +typedef osal_semaphore_t osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +{ + mdef->count = 1; + return mdef; +} + +static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +{ + return osal_semaphore_wait(mutex_hdl, msec); +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +{ + return osal_semaphore_post(mutex_hdl, false); +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#include "common/tusb_fifo.h" + +typedef struct +{ + void (*interrupt_set)(bool); + tu_fifo_t ff; +}osal_queue_def_t; + +typedef osal_queue_def_t* osal_queue_t; + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ + uint8_t _name##_buf[_depth*sizeof(_type)]; \ + osal_queue_def_t _name = { \ + .interrupt_set = _int_set, \ + .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ + } + +// lock queue by disable USB interrupt +static inline void _osal_q_lock(osal_queue_t qhdl) +{ + // disable dcd/hcd interrupt + qhdl->interrupt_set(false); +} + +// unlock queue +static inline void _osal_q_unlock(osal_queue_t qhdl) +{ + // enable dcd/hcd interrupt + qhdl->interrupt_set(true); +} + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + tu_fifo_clear(&qdef->ff); + return (osal_queue_t) qdef; +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +{ + _osal_q_lock(qhdl); + bool success = tu_fifo_read(&qhdl->ff, data); + _osal_q_unlock(qhdl); + + return success; +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +{ + if (!in_isr) { + _osal_q_lock(qhdl); + } + + bool success = tu_fifo_write(&qhdl->ff, data); + + if (!in_isr) { + _osal_q_unlock(qhdl); + } + + TU_ASSERT(success); + + return success; +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + // Skip queue lock/unlock since this function is primarily called + // with interrupt disabled before going into low power mode + return tu_fifo_empty(&qhdl->ff); +} + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OSAL_NONE_H_ */ diff --git a/circuitpython/lib/tinyusb/src/osal/osal_pico.h b/circuitpython/lib/tinyusb/src/osal/osal_pico.h new file mode 100644 index 0000000..70432d2 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/osal/osal_pico.h @@ -0,0 +1,187 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OSAL_PICO_H_ +#define _TUSB_OSAL_PICO_H_ + +#include "pico/time.h" +#include "pico/sem.h" +#include "pico/mutex.h" +#include "pico/critical_section.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +static inline void osal_task_delay(uint32_t msec) +{ + sleep_ms(msec); +} + +//--------------------------------------------------------------------+ +// Binary Semaphore API +//--------------------------------------------------------------------+ +typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t; + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + sem_init(semdef, 0, 255); + return semdef; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +{ + (void) in_isr; + sem_release(sem_hdl); + return true; +} + +static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) +{ + return sem_acquire_timeout_ms(sem_hdl, msec); +} + +static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) +{ + sem_reset(sem_hdl, 0); +} + +//--------------------------------------------------------------------+ +// MUTEX API +// Within tinyusb, mutex is never used in ISR context +//--------------------------------------------------------------------+ +typedef struct mutex osal_mutex_def_t, *osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +{ + mutex_init(mdef); + return mdef; +} + +static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +{ + return mutex_enter_timeout_ms(mutex_hdl, msec); +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +{ + mutex_exit(mutex_hdl); + return true; +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#include "common/tusb_fifo.h" + +#if CFG_TUH_ENABLED +extern void hcd_int_disable(uint8_t rhport); +extern void hcd_int_enable(uint8_t rhport); +#endif + +typedef struct +{ + tu_fifo_t ff; + struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section +} osal_queue_def_t; + +typedef osal_queue_def_t* osal_queue_t; + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ + uint8_t _name##_buf[_depth*sizeof(_type)]; \ + osal_queue_def_t _name = { \ + .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ + } + +// lock queue by disable USB interrupt +static inline void _osal_q_lock(osal_queue_t qhdl) +{ + critical_section_enter_blocking(&qhdl->critsec); +} + +// unlock queue +static inline void _osal_q_unlock(osal_queue_t qhdl) +{ + critical_section_exit(&qhdl->critsec); +} + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + critical_section_init(&qdef->critsec); + tu_fifo_clear(&qdef->ff); + return (osal_queue_t) qdef; +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +{ + // TODO: revisit... docs say that mutexes are never used from IRQ context, + // however osal_queue_recieve may be. therefore my assumption is that + // the fifo mutex is not populated for queues used from an IRQ context + //assert(!qhdl->ff.mutex); + + _osal_q_lock(qhdl); + bool success = tu_fifo_read(&qhdl->ff, data); + _osal_q_unlock(qhdl); + + return success; +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +{ + // TODO: revisit... docs say that mutexes are never used from IRQ context, + // however osal_queue_recieve may be. therefore my assumption is that + // the fifo mutex is not populated for queues used from an IRQ context + //assert(!qhdl->ff.mutex); + (void) in_isr; + + _osal_q_lock(qhdl); + bool success = tu_fifo_write(&qhdl->ff, data); + _osal_q_unlock(qhdl); + + TU_ASSERT(success); + + return success; +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + // TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single + // volatile read. + + // Skip queue lock/unlock since this function is primarily called + // with interrupt disabled before going into low power mode + return tu_fifo_empty(&qhdl->ff); +} + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OSAL_PICO_H_ */ diff --git a/circuitpython/lib/tinyusb/src/osal/osal_rtthread.h b/circuitpython/lib/tinyusb/src/osal/osal_rtthread.h new file mode 100644 index 0000000..0845175 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/osal/osal_rtthread.h @@ -0,0 +1,130 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 tfx2001 (2479727366@qq.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OSAL_RTTHREAD_H_ +#define _TUSB_OSAL_RTTHREAD_H_ + +// RT-Thread Headers +#include "rtthread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +static inline void osal_task_delay(uint32_t msec) { + rt_thread_mdelay(msec); +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef struct rt_semaphore osal_semaphore_def_t; +typedef rt_sem_t osal_semaphore_t; + +static inline osal_semaphore_t +osal_semaphore_create(osal_semaphore_def_t *semdef) { + rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_FIFO); + return semdef; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + (void) in_isr; + return rt_sem_release(sem_hdl) == RT_EOK; +} + +static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { + return rt_sem_take(sem_hdl, rt_tick_from_millisecond(msec)) == RT_EOK; +} + +static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { + // TODO: implement +} + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef struct rt_mutex osal_mutex_def_t; +typedef rt_mutex_t osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { + rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_FIFO); + return mdef; +} + +static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { + return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond(msec)) == RT_EOK; +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { + return rt_mutex_release(mutex_hdl) == RT_EOK; +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ + static _type _name##_##buf[_depth]; \ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; + +typedef struct { + uint16_t depth; + uint16_t item_sz; + void *buf; + + struct rt_messagequeue sq; +} osal_queue_def_t; + +typedef rt_mq_t osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { + rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, + qdef->item_sz * qdef->depth, RT_IPC_FLAG_FIFO); + return &(qdef->sq); +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void *data) { + return rt_mq_recv(qhdl, data, qhdl->msg_size, RT_WAITING_FOREVER) == RT_EOK; +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { + (void) in_isr; + return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) { + return (qhdl->entry) == 0; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_OSAL_RTTHREAD_H_ */ diff --git a/circuitpython/lib/tinyusb/src/osal/osal_rtx4.h b/circuitpython/lib/tinyusb/src/osal/osal_rtx4.h new file mode 100644 index 0000000..1856a5d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/osal/osal_rtx4.h @@ -0,0 +1,170 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Tian Yunhao (t123yh) + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OSAL_RTX4_H_ +#define _TUSB_OSAL_RTX4_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +static inline void osal_task_delay(uint32_t msec) +{ + uint16_t hi = msec >> 16; + uint16_t lo = msec; + while (hi--) { + os_dly_wait(0xFFFE); + } + os_dly_wait(lo); +} + +static inline uint16_t msec2wait(uint32_t msec) { + if (msec == OSAL_TIMEOUT_WAIT_FOREVER) + return 0xFFFF; + else if (msec >= 0xFFFE) + return 0xFFFE; + else + return msec; +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef OS_SEM osal_semaphore_def_t; +typedef OS_ID osal_semaphore_t; + +static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) { + os_sem_init(semdef, 0); + return semdef; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + if ( !in_isr ) { + os_sem_send(sem_hdl); + } else { + isr_sem_send(sem_hdl); + } + return true; +} + +static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { + return os_sem_wait(sem_hdl, msec2wait(msec)) != OS_R_TMO; +} + +static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { + // TODO: implement +} + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef OS_MUT osal_mutex_def_t; +typedef OS_ID osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +{ + os_mut_init(mdef); + return mdef; +} + +static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +{ + return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO; +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +{ + return os_mut_release(mutex_hdl) == OS_R_OK; +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ + os_mbx_declare(_name##__mbox, _depth); \ + _declare_box(_name##__pool, sizeof(_type), _depth); \ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .pool = _name##__pool, .mbox = _name##__mbox }; + + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + U32* pool; + U32* mbox; +}osal_queue_def_t; + +typedef osal_queue_def_t* osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4); + _init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz); + return qdef; +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +{ + void* buf; + os_mbx_wait(qhdl->mbox, &buf, 0xFFFF); + memcpy(data, buf, qhdl->item_sz); + _free_box(qhdl->pool, buf); + return true; +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +{ + void* buf = _alloc_box(qhdl->pool); + memcpy(buf, data, qhdl->item_sz); + if ( !in_isr ) + { + os_mbx_send(qhdl->mbox, buf, 0xFFFF); + } + else + { + isr_mbx_send(qhdl->mbox, buf); + } + return true; +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + return os_mbx_check(qhdl->mbox) == qhdl->depth; +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/circuitpython/lib/tinyusb/src/portable/bridgetek/ft9xx/dcd_ft9xx.c new file mode 100644 index 0000000..791f6cf --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -0,0 +1,1110 @@ +/* + * The MIT License (MIT) + * + * Copyright 2021 Bridgetek Pte Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* + * Contains code adapted from Bridgetek Pte Ltd via license terms stated + * in https://brtchip.com/BRTSourceCodeLicenseAgreement + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) + +#include +#include +#include + +#include "board.h" +#include "bsp/board.h" + +#define USBD_USE_STREAMS + +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +// Board code will determine the state of VBUS from USB host. +extern int8_t board_ft90x_vbus(void); + +// Static array to store an incoming SETUP request for processing by tinyusb. +static uint8_t _ft90x_setup_packet[8]; + +struct ft90x_xfer_state +{ + volatile uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid. + volatile int16_t total_size; // Total transfer size in bytes for this transfer. + volatile int16_t remain_size; // Total remaining in transfer. + volatile uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to. + + uint8_t type; // Endpoint type. Of type USBD_ENDPOINT_TYPE from endpoint descriptor. + uint8_t dir; // Endpoint direction. TUSB_DIR_OUT or TUSB_DIR_IN. For control endpoint this is the current direction. + uint16_t buff_size; // Actual size of buffer RAM used by endpoint. + uint16_t size; // Max packet size for endpoint from endpoint descriptor. +}; +// Endpoint description array for each endpoint. +static struct ft90x_xfer_state ep_xfer[USBD_MAX_ENDPOINT_COUNT]; +// USB speed. +static tusb_speed_t _speed; + +// Interrupt handlers. +void _ft90x_usbd_ISR(void); // Interrupt handler for USB device. +void ft90x_usbd_pm_ISR(void); // Interrupt handler for USB device for power management (called by board). + +// Internal functions forward declarations. +static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); +static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); +static void _ft90x_reset_edpts(void); +static inline void _ft90x_phy_enable(bool en); +static void _ft90x_usb_speed(void); +static void _dcd_ft90x_attach(void); +static void _dcd_ft90x_detach(void) __attribute__((unused)); +static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length); +static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length); + +// Internal functions. + +// Manage an OUT transfer from the host. +// This can be up-to the maximum packet size of the endpoint. +// Continuation of a transfer beyond the maximum packet size is performed +// by the interrupt handler. +static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) +{ + //Note: this is called from only the interrupt handler when an OUT transfer is called. + uint16_t ep_size = ep_xfer[ep_number].size; + (void)ep_size; + if (xfer_bytes > ep_size) + { + xfer_bytes = ep_size; + } + + // Wait until the endpoint has finished - it should be complete! + //while (!(USBD_EP_SR_REG(ep_number) & MASK_USBD_EPxSR_OPRDY)) + //; + + // Send the first packet of max packet size + xfer_bytes = _ft90x_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes); + if (ep_number == USBD_EP_0) + { + // Set flags to indicate data ready. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_OPRDY); + } + else + { + USBD_EP_SR_REG(ep_number) = (MASK_USBD_EPxSR_OPRDY); + } + + return xfer_bytes; +} + +// Manage an IN transfer to the host. +// This can be up-to the maximum packet size of the endpoint. +// Continuation of a transfer beyond the maximum packet size is performed +// by the interrupt handler. +static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) +{ + //Note: this may be called from the interrupt handler or from normal code. + uint8_t end = 0; + uint16_t ep_size = ep_xfer[ep_number].size; + (void)ep_size; + + if ((xfer_bytes == 0) || (xfer_bytes < ep_size)) + { + end = 1; + } + else + { + xfer_bytes = ep_size; + } + + if (ep_number == USBD_EP_0) + { + // An IN direction SETUP can be interrupted by an OUT packet. + // This will result in a STALL generated by the silicon. + while (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_STALL) + { + // Clear the STALL and finish the transaction. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_STALL); + } + } + else + { + uint8_t sr_reg; + // If there is data to transmit then wait until the IN buffer + // for the endpoint is empty. + do + { + sr_reg = USBD_EP_SR_REG(ep_number); + } while (sr_reg & MASK_USBD_EPxSR_INPRDY); + + } + + xfer_bytes = _ft90x_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes); + + if (ep_number == USBD_EP_0) + { + if (end) + { + // Set flags to indicate data ready and transfer complete. + USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_INPRDY | MASK_USBD_EP0SR_DATAEND; + } + else + { + // Set flags to indicate data ready. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_INPRDY); + } + } + else + { + // Set flags to indicate data ready. + USBD_EP_SR_REG(ep_number) = (MASK_USBD_EPxSR_INPRDY); + } + + return xfer_bytes; +} + +// Reset all non-control endpoints to a default state. +// Control endpoint is always enabled and ready. All others disabled. +static void _ft90x_reset_edpts(void) +{ + // Disable all endpoints and remove configuration values. + for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) + { + // Clear settings. + tu_memclr(&ep_xfer[i], sizeof(struct ft90x_xfer_state)); + // Disable hardware. + USBD_EP_CR_REG(i) = 0; + } + + // Enable interrupts from USB device control. + USBD_REG(cmie) = MASK_USBD_CMIE_ALL; +} + +// Enable or disable the USB PHY. +static inline void _ft90x_phy_enable(bool en) +{ + if (en) + SYS->PMCFG_L |= MASK_SYS_PMCFG_DEV_PHY_EN; + else + SYS->PMCFG_L &= ~MASK_SYS_PMCFG_DEV_PHY_EN; +} + +// Safely connect to the USB. +static void _dcd_ft90x_attach(void) +{ + uint8_t reg; + + CRITICAL_SECTION_BEGIN + // Disable device responses. + USBD_REG(faddr) = 0; + + // Reset USB Device. + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RESET_ALL; + // Disable device connect/disconnect/host reset detection. + SYS->PMCFG_H = MASK_SYS_PMCFG_DEV_DIS_DEV; + SYS->PMCFG_H = MASK_SYS_PMCFG_DEV_CONN_DEV; + SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN); + + // Enable Chip USB device clock/PM configuration. + sys_enable(sys_device_usb_device); + CRITICAL_SECTION_END; + + // Wait a short time to get started. + delayms(1); + + CRITICAL_SECTION_BEGIN + // Turn off the device enable bit. +#if BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_HIGH_SPEED + USBD_REG(fctrl) = 0; +#else // BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_FULL_SPEED + //Set the full speed only bit if required. + USBD_REG(fctrl) = MASK_USBD_FCTRL_MODE_FS_ONLY; +#endif // BOARD_DEVICE_RHPORT_SPEED + + // Clear first reset and suspend interrupts. + do + { + reg = USBD_REG(cmif); + USBD_REG(cmif) = reg; + } while (reg); + // Clear any endpoint interrupts. + reg = USBD_REG(epif); + USBD_REG(epif) = reg; + + // Disable all interrupts from USB device control before attaching interrupt. + USBD_REG(cmie) = 0; + CRITICAL_SECTION_END; + + // Enable device connect/disconnect/host reset detection. + // Set device detect and remote wakeup enable interrupt enables. + SYS->PMCFG_L = SYS->PMCFG_L | MASK_SYS_PMCFG_DEV_DETECT_EN; + +#if defined(__FT930__) + // Setup VBUS detect + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_USB_VBUS_EN; +#endif +} + +// Gracefully disconnect from the USB. +static void _dcd_ft90x_detach(void) +{ + // Disable device connect/disconnect/host reset detection. + SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN); + +#if defined(__FT930__) + // Disable VBUS detection. + SYS->MSC0CFG = SYS->MSC0CFG & (~MASK_SYS_MSC0CFG_USB_VBUS_EN); +#endif + CRITICAL_SECTION_BEGIN + // Disable interrupts from USB. + USBD_REG(epie) = 0; + USBD_REG(cmie) = 0; + // Turn off the device enable bit. + USBD_REG(fctrl) = 0; + CRITICAL_SECTION_END; + + delayms(1); + + // Disable USB PHY + dcd_disconnect(BOARD_DEVICE_RHPORT_NUM); + delayms(1); + + // Disable Chip USB device clock/PM configuration. + sys_disable(sys_device_usb_device); + + // Reset USB Device... Needed for Back voltage D+ to be <400mV + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RESET_ALL; + + delayms(1); + // Set device detect and remote wakeup enable interrupt enables. + SYS->PMCFG_L = SYS->PMCFG_L | MASK_SYS_PMCFG_DEV_DETECT_EN; + +#if defined(__FT930__) + // Setup VBUS detect + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_USB_VBUS_EN; +#endif +} + +// Determine the speed of the USB to which we are connected. +// Set the speed of the PHY accordingly. +// High speed can be disabled through CFG_TUSB_RHPORT0_MODE settings. +static void _ft90x_usb_speed(void) +{ + uint8_t fctrl_val; + + // If USB device function is already enabled then disable it. + if (USBD_REG(fctrl) & MASK_USBD_FCTRL_USB_DEV_EN) { + USBD_REG(fctrl) = (USBD_REG(fctrl) & (~MASK_USBD_FCTRL_USB_DEV_EN)); + delayus(200); + } + +#if BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_HIGH_SPEED + + /* Detect high or full speed */ + fctrl_val = MASK_USBD_FCTRL_USB_DEV_EN; +#if defined(__FT900__) + if (!sys_check_ft900_revB())//if 90x series is rev C + { + fctrl_val |= MASK_USBD_FCTRL_IMP_PERF; + } +#endif + USBD_REG(fctrl) = fctrl_val; + +#if defined(__FT930__) + delayus(200); + + _speed = (SYS->MSC0CFG & MASK_SYS_MSC0CFG_HIGH_SPED_MODE) ? + TUSB_SPEED_HIGH : TUSB_SPEED_FULL; +#else /* __FT930__ */ + /* Detection by SOF */ + while (!(USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ)); + USBD_REG(cmif) = MASK_USBD_CMIF_SOFIRQ; + delayus(125 + 5); + _speed = (USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ) ? + TUSB_SPEED_HIGH : TUSB_SPEED_FULL; + dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); + +#endif /* !__FT930__ */ + +#else // BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_FULL_SPEED + + /* User force set to full speed */ + _speed = TUSB_SPEED_FULL; + fctrl_val = + MASK_USBD_FCTRL_USB_DEV_EN | MASK_USBD_FCTRL_MODE_FS_ONLY; +#if defined(__FT900__) + if (!sys_check_ft900_revB())//if 90x series is rev C + { + fctrl_val |= MASK_USBD_FCTRL_IMP_PERF; + } +#endif + USBD_REG(fctrl) = fctrl_val; + dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); + return; + +#endif // BOARD_DEVICE_RHPORT_SPEED +} + +// Send a buffer to the USB IN FIFO. +// When the macro USBD_USE_STREAMS is defined this will stream a buffer of data +// to the FIFO using the most efficient MCU streamout combination. +// If streaming is disabled then it will send each byte of the buffer in turn +// to the FIFO. The is no reason to not stream. +// The total number of bytes sent to the FIFO is returned. +static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length) +{ + uint16_t bytes_read = 0; + uint16_t buff_size = length; + +#ifdef USBD_USE_STREAMS + volatile uint8_t *data_reg; + + data_reg = (volatile uint8_t *)&(USBD->ep[ep_number].epxfifo); + if (buff_size) + { + if (((uint32_t)buffer) % 4 == 0) + { + uint16_t aligned = buff_size & (~3); + uint16_t left = buff_size & 3; + + if (aligned) + { + __asm__ volatile("streamout.l %0,%1,%2" + : + : "r"(data_reg), "r"(buffer), "r"(aligned)); + buffer += aligned; + } + if (left) + { + __asm__ volatile("streamout.b %0,%1,%2" + : + : "r"(data_reg), "r"(buffer), "r"(left)); + } + } + else + { + __asm__ volatile("streamout.b %0,%1,%2" + : + : "r"(data_reg), "r"(buffer), "r"(buff_size)); + } + bytes_read = buff_size; + } +#else // USBD_USE_STREAMS + + bytes_read = buff_size; + while (buff_size--) + { + USBD_EP_FIFO_REG(ep_number) = *buffer++; + }; + +#endif // USBD_USE_STREAMS + + return bytes_read; +} + +// Receive a buffer from the USB OUT FIFO. +// When the macro USBD_USE_STREAMS is defined this will stream from the FIFO +// to a buffer of data using the most efficient MCU streamin combination. +// If streaming is disabled then it will receive each byte from the FIFO in turn +// to the buffer. The is no reason to not stream. +// The total number of bytes received from the FIFO is returned. +static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length) +{ +#ifdef USBD_USE_STREAMS + volatile uint8_t *data_reg; +#endif // USBD_USE_STREAMS + uint16_t bytes_read = 0; + uint16_t buff_size = length; + + if (length > 0) + { + if (ep_number == USBD_EP_0) + { + buff_size = USBD_EP_CNT_REG(USBD_EP_0); + } + else + { + if (USBD_EP_SR_REG(ep_number) & (MASK_USBD_EPxSR_OPRDY)) + { + buff_size = USBD_EP_CNT_REG(ep_number); + } + } + } + + // Only read as many bytes as we have space for. + if (buff_size > length) + buff_size = length; + +#ifdef USBD_USE_STREAMS + data_reg = (volatile uint8_t *)&(USBD->ep[ep_number].epxfifo); + if (buff_size) + { + if ((uint32_t)buffer % 4 == 0) + { + uint16_t aligned = buff_size & (~3); + uint16_t left = buff_size & 3; + + if (aligned) + { + __asm__ volatile("streamin.l %0,%1,%2" + : + : "r"(buffer), "r"(data_reg), "r"(aligned)); + buffer += aligned; + } + if (left) + { + __asm__ volatile("streamin.b %0,%1,%2" + : + : "r"(buffer), "r"(data_reg), "r"(left)); + } + } + else + { + __asm__ volatile("streamin.b %0,%1,%2" + : + : "r"(buffer), "r"(data_reg), "r"(buff_size)); + } + bytes_read = buff_size; + } +#else // USBD_USE_STREAMS + + bytes_read = buff_size; + while (buff_size--) + { + *buffer++ = USBD_EP_FIFO_REG(ep_number); + } + +#endif // USBD_USE_STREAMS + + return bytes_read; +} + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ + +// Initialize controller to device mode +void dcd_init(uint8_t rhport) +{ + TU_LOG2("FT90x initialisation\r\n"); + + _dcd_ft90x_attach(); + + interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft90x_usbd_ISR); + + dcd_connect(rhport); +} + +// Enable device interrupt +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + TU_LOG3("FT90x int enable\r\n"); + + // Peripheral devices interrupt enable. + interrupt_enable_globally(); +} + +// Disable device interrupt +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + TU_LOG3("FT90x int disable\r\n"); + + // Peripheral devices interrupt disable. + interrupt_disable_globally(); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + (void)dev_addr; + + // Respond with status. There is no checking that the address is in range. + dcd_edpt_xfer(rhport, tu_edpt_addr(USBD_EP_0, TUSB_DIR_IN), NULL, 0); + + // Set the update bit for the address register. + dev_addr |= 0x80; + + // Modify the address register within a critical section. + CRITICAL_SECTION_BEGIN + { + USBD_REG(faddr) = dev_addr; + } + CRITICAL_SECTION_END; +} + +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +#if 0 // never called +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) + { + if (request->bRequest == TUSB_REQ_SET_ADDRESS) + { + } + else if (request->bRequest == TUSB_REQ_SET_CONFIGURATION) + { + } + } +} +#endif // 0 + +// Wake up host +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RMWAKEUP; + + // Atleast 2 ms of delay needed for RESUME Data K state. + delayms(2); + + SYS->MSC0CFG &= ~MASK_SYS_MSC0CFG_DEV_RMWAKEUP; + + // Enable USB PHY and determine current bus speed. + dcd_connect(rhport); +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + TU_LOG2("FT90x connect\r\n"); + + CRITICAL_SECTION_BEGIN + // Is device connected? + if (board_ft90x_vbus()) + { + // Clear/disable address register. + USBD_REG(faddr) = 0; + _ft90x_phy_enable(true); + + // Determine bus speed and signal speed to tusb. + _ft90x_usb_speed(); + } + + // Setup the control endpoint only. +#if CFG_TUD_ENDPOINT0_SIZE == 64 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_64 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 32 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_32 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 16 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_16 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 8 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_8 << BIT_USBD_EP0_MAX_SIZE); +#else +#error "CFG_TUD_ENDPOINT0_SIZE must be defined with a value of 8, 16, 32 or 64." +#endif + CRITICAL_SECTION_END; + + // Configure the control endpoint. + ep_xfer[USBD_EP_0].size = CFG_TUD_ENDPOINT0_SIZE; + ep_xfer[USBD_EP_0].type = TUSB_XFER_CONTROL; + + // Enable interrupts on EP0. + USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE); + + // Restore default endpoint state. + _ft90x_reset_edpts(); +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + TU_LOG2("FT90x disconnect\r\n"); + + // Disable the USB PHY. + _ft90x_phy_enable(false); +} + + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) +{ + (void)rhport; + uint8_t const ep_number = tu_edpt_number(ep_desc->bEndpointAddress); + uint8_t const ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); + uint8_t const ep_type = ep_desc->bmAttributes.xfer; + uint16_t const ep_size = tu_edpt_packet_size(ep_desc); // Mask size per packet, bits 10..0. + uint16_t ep_buff_size; + uint8_t ep_reg_size = USBD_EP_MAX_SIZE_8; + uint8_t ep_reg_data = 0; + int16_t total_ram; + + TU_LOG2("FT90x endpoint open %d %c\r\n", ep_number, ep_dir?'I':'O'); + + // Check that the requested endpoint number is allowable. + if (ep_number >= USBD_MAX_ENDPOINT_COUNT) + { + TU_LOG1("FT90x endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT); + return false; + } + + // Calculate the physical size of the endpoint as a power of 2. This may be more than + // the requested size. + while (ep_size > (8 * (1 << ep_reg_size))) + { + ep_reg_size++; + } + if (ep_reg_size > USBD_EP_MAX_SIZE_1024) + { + TU_LOG1("FT90x endpoint size not valid: requested %d max 1024\r\n", ep_size); + return false; + } + // Calculate actual amount of buffer RAM used by this endpoint. This may be more than the + // requested size. + ep_buff_size = 8 << ep_reg_size; + + if (ep_number > 0) + { + // Set EP cmd parameters... + ep_reg_data |= (ep_reg_size << BIT_USBD_EP_MAX_SIZE); + + if (ep_xfer[ep_number].type != USBD_EP_TYPE_DISABLED) + { + // This could be because an endpoint has been assigned with the same number. + // On FT90x, IN and OUT endpoints may not have the same number. e.g. There + // cannot been an 0x81 and 0x01 endpoint. + TU_LOG1("FT90x endpoint %d already assigned\r\n", ep_number); + return false; + } + + // Check that there is enough buffer RAM to allocate to this new endpoint. + // Available buffer RAM depends on the device revision. + // The IN and OUT buffer RAM should be the same size. + if (ep_dir == USBD_DIR_IN) + total_ram = USBD_RAMTOTAL_IN; + else + total_ram = USBD_RAMTOTAL_OUT; + // Work out how much has been allocated to existing endpoints. + // The total RAM allocated shoudl alsyes be a positive number as this + // algorithm should not let it go below zero. + for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) + { + if (ep_xfer[i].type != USBD_EP_TYPE_DISABLED) + { + if (ep_xfer[i].dir == ep_dir) + { + total_ram -= ep_xfer[i].buff_size; + } + } + } + // The control endpoint is taken into account as well. + total_ram -= ep_xfer[0].buff_size; + // Make sure we have enough space. The corner case is having zero bytes + // free which means that total_ram must be signed as zero bytes free is + // allowable. + if (total_ram < ep_buff_size) + { + TU_LOG1("FT90x insufficient buffer RAM for endpoint %d\r\n", ep_number); + return false; + } + + // Set the type of this endpoint in the control register. + if (ep_type == USBD_EP_BULK) + ep_reg_data |= (USBD_EP_DIS_BULK << BIT_USBD_EP_CONTROL_DIS); + else if (ep_type == USBD_EP_INT) + ep_reg_data |= (USBD_EP_DIS_INT << BIT_USBD_EP_CONTROL_DIS); + else if (ep_type == USBD_EP_ISOC) + ep_reg_data |= (USBD_EP_DIS_ISO << BIT_USBD_EP_CONTROL_DIS); + // Set the direction of this endpoint in the control register. + if (ep_dir == USBD_DIR_IN) + ep_reg_data |= MASK_USBD_EPxCR_DIR; + // Do not perform double buffering. + //if ( != USBD_DB_OFF) + //ep_reg_data |= MASK_USBD_EPxCR_DB; + // Set the control endpoint for this endpoint. + USBD_EP_CR_REG(ep_number) = ep_reg_data; + TU_LOG2("FT90x endpoint setting %x\r\n", ep_reg_data); + } + else + { + // Set the control register for endpoint zero. + USBD_EP_CR_REG(USBD_EP_0) = (ep_reg_size << BIT_USBD_EP0_MAX_SIZE); + } + + // Store the endpoint characteristics for later reference. + ep_xfer[ep_number].dir = ep_dir; + ep_xfer[ep_number].type = ep_type; + ep_xfer[ep_number].size = ep_size; + ep_xfer[ep_number].buff_size = ep_buff_size; + + CRITICAL_SECTION_BEGIN + // Clear register transaction continuation and signalling state. + ep_xfer[ep_number].valid = 0; + ep_xfer[ep_number].buff_ptr = NULL; + ep_xfer[ep_number].total_size = 0; + ep_xfer[ep_number].remain_size = 0; + CRITICAL_SECTION_END + + return true; +} + +// Close all endpoints. +void dcd_edpt_close_all(uint8_t rhport) +{ + (void)rhport; + // Reset the endpoint configurations. + _ft90x_reset_edpts(); +} + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + uint8_t ep_number = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + uint16_t xfer_bytes; + bool status = false; + + // We will attempt to transfer the buffer. If it is less than or equal to the endpoint + // maximum packet size then the whole buffer will be transferred. If it is larger then + // the interrupt handler will transfer the remainder. + // ep_xfer is used to tell the interrupt handler what to do. + // ep_xfer can be used at interrupt level to continue transfers. + CRITICAL_SECTION_BEGIN + // Transfer currently in progress. + if (ep_xfer[ep_number].valid == 0) + { + status = true; + + ep_xfer[ep_number].total_size = total_bytes; + ep_xfer[ep_number].remain_size = total_bytes; + ep_xfer[ep_number].buff_ptr = buffer; + ep_xfer[ep_number].valid = 1; + + if (ep_number == USBD_EP_0) + { + ep_xfer[USBD_EP_0].dir = dir; + } + else + { + // Enable the interrupt for this endpoint allowing the interrupt handler to report + // continue the transfer and signal completion. + USBD_REG(epie) = USBD_REG(epie) | (1 << ep_number); + } + + if (dir == TUSB_DIR_IN) + { + // For IN transfers send the first packet as a starter. Interrupt handler to complete + // this if it is larger than one packet. + xfer_bytes = _ft90x_edpt_xfer_in(ep_number, buffer, total_bytes); + + ep_xfer[ep_number].buff_ptr += xfer_bytes; + ep_xfer[ep_number].remain_size -= xfer_bytes; + } + } + CRITICAL_SECTION_END + + return status; +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) +{ + (void)rhport; + (void)ep_addr; + (void)ff; + (void)total_bytes; + bool status = false; + return status; +} + +// Stall endpoint (non-control endpoint) +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t ep_number = tu_edpt_number(ep_addr); + (void)rhport; + + CRITICAL_SECTION_BEGIN + if (ep_number == USBD_EP_0) + { + USBD_EP_CR_REG(USBD_EP_0) = USBD_EP_CR_REG(USBD_EP_0) | + MASK_USBD_EP0CR_SDSTL; + } + else + { + USBD_EP_CR_REG(ep_number) = USBD_EP_CR_REG(ep_number) | + MASK_USBD_EPxCR_SDSTL; + USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE | + MASK_USBD_EPxSR_FIFO_FLUSH; + } + CRITICAL_SECTION_END +} + +// Clear stall (non-control endpoint), data toggle is also reset to DATA0 +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t ep_number = tu_edpt_number(ep_addr); + (void)rhport; + + if (ep_number > USBD_EP_0) + { + CRITICAL_SECTION_BEGIN + USBD_EP_CR_REG(ep_number) = USBD_EP_CR_REG(ep_number) & + (~MASK_USBD_EPxCR_SDSTL); + USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE; + + // Allow transfers to restart. + ep_xfer[ep_number].valid = 0; + ep_xfer[ep_number].remain_size = 0; + CRITICAL_SECTION_END + } +} + +// Interrupt handling. + +void _ft90x_usbd_ISR(void) +{ + tud_int_handler(BOARD_DEVICE_RHPORT_NUM); // Resolves to dcd_int_handler(). +} + +void dcd_int_handler(uint8_t rhport) +{ + (void)rhport; + + // Read the Common Interrupt Flag Register. + uint8_t cmif = USBD_REG(cmif); + // Read the Endpoint Interrupt Flag Register. +#if defined(__FT930__) + // This is 16 bits on FT93x. + uint16_t epif = USBD_REG(epif); +#else + // This is 8 bits on FT90x. + uint8_t epif = USBD_REG(epif); +#endif + + if (cmif & MASK_USBD_CMIF_ALL) + { + // Clear all CMIF bits. + USBD_REG(cmif) = MASK_USBD_CMIF_ALL; + if (cmif & MASK_USBD_CMIF_PHYIRQ) //Handle PHY interrupt + { + } + if (cmif & MASK_USBD_CMIF_PIDIRQ) //Handle PIDIRQ interrupt + { + } + if (cmif & MASK_USBD_CMIF_CRC16IRQ) //Handle CRC16IRQ interrupt + { + } + if (cmif & MASK_USBD_CMIF_CRC5IRQ) //Handle CRC5 interrupt + { + } + if (cmif & MASK_USBD_CMIF_RSTIRQ) //Handle Reset interrupt + { + // Reset endpoints to default state. + _ft90x_reset_edpts(); + dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); + } + if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt + { + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_SUSPEND, true); + } + if (cmif & MASK_USBD_CMIF_RESIRQ) //Handle Resume interrupt + { + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); + } + if (cmif & MASK_USBD_CMIF_SOFIRQ) //Handle SOF interrupt + { + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_SOF, true); + } + } + // Handle endpoint interrupts. + if (epif) + { + uint16_t xfer_bytes; + + // Check for EP0 interrupts pending. + if (epif & MASK_USBD_EPIF_EP0IRQ) + { + // Clear interrupt register. + USBD_REG(epif) = MASK_USBD_EPIF_EP0IRQ; + + // Test for an incoming SETUP request on the control endpoint. + if (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_SETUP) + { + // If protocol STALL, End the STALL signalling. + if (USBD_EP_CR_REG(USBD_EP_0) & MASK_USBD_EP0CR_SDSTL) + { + // STALL end. + USBD_EP_CR_REG(USBD_EP_0) = USBD_EP_CR_REG(USBD_EP_0) & + (~MASK_USBD_EP0CR_SDSTL); + // Clear STALL send. + USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL; + } + + // Host has sent a SETUP packet. Recieve this into the setup packet store. + _ft90x_dusb_out(USBD_EP_0, (uint8_t *)_ft90x_setup_packet, sizeof(USB_device_request)); + + // Send the packet to tinyusb. + dcd_event_setup_received(BOARD_DEVICE_RHPORT_NUM, _ft90x_setup_packet, true); + + // Clear the interrupt that signals a SETUP packet is received. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP); + + // Allow new transfers on the control endpoint. + ep_xfer[USBD_EP_0].valid = 0; + return; + } + else + { + // Check for a complete or partially complete transfers on EP0. + if (ep_xfer[USBD_EP_0].valid) + { + xfer_bytes = (uint16_t)ep_xfer[USBD_EP_0].total_size; + + // Transfer incoming data from an OUT packet to the buffer supplied. + if (ep_xfer[USBD_EP_0].dir == TUSB_DIR_OUT) + { + xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, (uint8_t *)ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes); + } + // Now signal completion of data packet. + dcd_event_xfer_complete(BOARD_DEVICE_RHPORT_NUM, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); + + // Allow new transfers on the control endpoint. + ep_xfer[USBD_EP_0].valid = 0; + } + } + } + else // !(epif & MASK_USBD_EPIF_EP0IRQ) + { + // Mask out currently disabled endpoints. + epif &= USBD_REG(epie); + + // Handle complete and partially complete transfers for each endpoint. + for (uint8_t ep_number = 1; ep_number < USBD_MAX_ENDPOINT_COUNT; ep_number++) + { + if ((epif & MASK_USBD_EPIF_IRQ(ep_number)) == 0) + { + // No pending interrupt for this endpoint. + continue; + } + + if (ep_xfer[ep_number].valid) + { + xfer_bytes = 0; + uint8_t ep_dirmask = (ep_xfer[ep_number].dir ? TUSB_DIR_IN_MASK : 0); + + // Clear interrupt register for this endpoint. + USBD_REG(epif) = MASK_USBD_EPIF_IRQ(ep_number); + + // Start or continue an OUT transfer. + if (ep_xfer[ep_number].dir == TUSB_DIR_OUT) + { + xfer_bytes = _ft90x_edpt_xfer_out(ep_number, + (uint8_t *)ep_xfer[ep_number].buff_ptr, + (uint16_t)ep_xfer[ep_number].remain_size); + + ep_xfer[ep_number].buff_ptr += xfer_bytes; + ep_xfer[ep_number].remain_size -= xfer_bytes; + } + // continue an IN transfer + else // if (ep_xfer[ep_number].dir == TUSB_DIR_IN) + { + if (ep_xfer[ep_number].remain_size > 0) + { + xfer_bytes = _ft90x_edpt_xfer_in(ep_number, + (uint8_t *)ep_xfer[ep_number].buff_ptr, + (uint16_t)ep_xfer[ep_number].remain_size); + + ep_xfer[ep_number].buff_ptr += xfer_bytes; + ep_xfer[ep_number].remain_size -= xfer_bytes; + } + } + + // When the transfer is complete... + if (ep_xfer[ep_number].remain_size == 0) + { + // Signal tinyUSB. + dcd_event_xfer_complete(BOARD_DEVICE_RHPORT_NUM, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); + + // Allow new transfers on this endpoint. + ep_xfer[ep_number].valid = 0; + + // Disable the interrupt for this endpoint now it is complete. + USBD_REG(epie) = USBD_REG(epie) & (~(1 << ep_number)); + } + } + } + } + } +} + +// Power management interrupt handler. +// This handles USB device related power management interrupts only. +void ft90x_usbd_pm_ISR(void) +{ + uint16_t pmcfg = SYS->PMCFG_H; + + // Main interrupt handler is responible for + if (pmcfg & MASK_SYS_PMCFG_DEV_CONN_DEV) + { + // Signal connection interrupt + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); + } + + if (pmcfg & MASK_SYS_PMCFG_DEV_DIS_DEV) + { + // Signal disconnection interrupt + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_UNPLUGGED, true); + } + + if (pmcfg & MASK_SYS_PMCFG_HOST_RST_DEV) + { + // Signal Host Reset interrupt + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_BUS_RESET, true); + } + + if (pmcfg & MASK_SYS_PMCFG_HOST_RESUME_DEV) + { + // Signal Host Resume interrupt + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + if (!(SYS->MSC0CFG & MASK_SYS_MSC0CFG_DEV_RMWAKEUP)) + { + // If we are driving K-state on Device USB port; + // We must maintain the 1ms requirement before resuming the phy + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); + } + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/broadcom/synopsys/dcd_synopsys.c b/circuitpython/lib/tinyusb/src/portable/broadcom/synopsys/dcd_synopsys.c new file mode 100644 index 0000000..c4881ee --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/broadcom/synopsys/dcd_synopsys.c @@ -0,0 +1,1267 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2020 Jan Duempelmann + * Copyright (c) 2020 Reinhard Panhuber + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_BCM2711 ) \ + + +#include "synopsys_common.h" + +#include "broadcom/interrupts.h" + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#define USE_SOF 0 + +// EP_MAX : Max number of bi-directional endpoints including EP0 +// EP_FIFO_SIZE : Size of dedicated USB SRAM +#if CFG_TUSB_MCU == OPT_MCU_BCM2711 +// #include "bcm2711.h" +#define EP_MAX_FS 8 +#define EP_FIFO_SIZE_FS 4096 +#define EP_MAX_HS 8 +#define EP_FIFO_SIZE_HS 4096 +#else +#error "Unsupported MCUs" +#endif + +#define EP_MAX 8 +#define EP_FIFO_SIZE 4096 + +// Info on values here: https://github.com/torvalds/linux/blob/79160a603bdb51916226caf4a6616cc4e1c58a58/Documentation/devicetree/bindings/usb/dwc2.yaml + +// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm283x.dtsi +// usb: usb@7e980000 { +// compatible = "brcm,bcm2835-usb"; +// reg = <0x7e980000 0x10000>; +// interrupts = <1 9>; +// #address-cells = <1>; +// #size-cells = <0>; +// clocks = <&clk_usb>; +// clock-names = "otg"; +// phys = <&usbphy>; +// phy-names = "usb2-phy"; +// }; + +// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi +// SPDX-License-Identifier: GPL-2.0 +// &usb { +// dr_mode = "otg"; +// g-rx-fifo-size = <256>; +// g-np-tx-fifo-size = <32>; + +// * According to dwc2 the sum of all device EP +// * fifo sizes shouldn't exceed 3776 bytes. + +// g-tx-fifo-size = <256 256 512 512 512 768 768>; +// }; + +// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm2711-rpi.dtsi +// &usb { +// /* Enable the FIQ support */ +// reg = <0x7e980000 0x10000>, +// <0x7e00b200 0x200>; +// interrupts = , +// ; +// status = "disabled"; +// }; + +// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm2711.dtsi +// &usb { +// interrupts = ; +// }; + +// From: https://github.com/torvalds/linux/blob/1d597682d3e669ec7021aa33d088ed3d136a5149/drivers/usb/dwc2/params.c +// static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg) +// { +// struct dwc2_core_params *p = &hsotg->params; + +// p->host_rx_fifo_size = 774; +// p->max_transfer_size = 65535; +// p->max_packet_count = 511; +// p->ahbcfg = 0x10; +// } + +#include "device/dcd.h" + +TU_VERIFY_STATIC(sizeof(USB_OTG_GlobalTypeDef) == 0x140, "size is incorrect"); + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +#define RHPORT_REGS_BASE USB_OTG_GLOBAL_BASE + +#define GLOBAL_BASE(_port) ((USB_OTG_GlobalTypeDef*) RHPORT_REGS_BASE) +#define DEVICE_BASE(_port) (USB_OTG_DeviceTypeDef *) (USB_OTG_DEVICE_BASE) +#define OUT_EP_BASE(_port) (USB_OTG_OUTEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_OUT_ENDPOINT_BASE) +#define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_IN_ENDPOINT_BASE) +#define FIFO_BASE(_port, _x) ((volatile uint32_t *) (RHPORT_REGS_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) + +enum +{ + DCD_HIGH_SPEED = 0, // Highspeed mode + DCD_FULL_SPEED_USE_HS = 1, // Full speed in Highspeed port (probably with internal PHY) + DCD_FULL_SPEED = 3, // Full speed with internal PHY +}; + +static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; + +typedef struct { + uint8_t * buffer; + tu_fifo_t * ff; + uint16_t total_len; + uint16_t max_size; + uint8_t interval; +} xfer_ctl_t; + +typedef volatile uint32_t * usb_fifo_t; + +xfer_ctl_t xfer_status[EP_MAX][2]; +#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] + +// EP0 transfers are limited to 1 packet - larger sizes has to be split +static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type + +// TX FIFO RAM allocation so far in words - RX FIFO size is readily available from usb_otg->GRXFSIZ +static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) +static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) + +// Calculate the RX FIFO size according to recommendations from reference manual +static inline uint16_t calc_rx_ff_size(uint16_t ep_size) +{ + return 15 + 2*(ep_size/4) + 2*EP_MAX; +} + +static void update_grxfsiz(uint8_t rhport) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + + // Determine largest EP size for RX FIFO + uint16_t max_epsize = 0; + for (uint8_t epnum = 0; epnum < EP_MAX; epnum++) + { + max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size); + } + + // Update size of RX FIFO + usb_otg->GRXFSIZ = calc_rx_ff_size(max_epsize); +} + +// Setup the control endpoint 0. +static void bus_reset(uint8_t rhport) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + tu_memclr(xfer_status, sizeof(xfer_status)); + _out_ep_closed = false; + + // clear device address + dev->DCFG &= ~USB_OTG_DCFG_DAD_Msk; + + // 1. NAK for all OUT endpoints + for(uint8_t n = 0; n < EP_MAX; n++) { + out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK; + } + + // 2. Un-mask interrupt bits + dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos); + dev->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM; + dev->DIEPMSK = USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM; + + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start. + // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located + // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard + // configuration done below. + // + // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed. + // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a + // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually + // opened when the host sends an additional command: setInterface. At this point in time + // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size + // an additional memory + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO 0 | + // --------------- (320 or 1024) - 16 + // | IN FIFO 1 | + // --------------- (320 or 1024) - 16 - x + // | . . . . | + // --------------- (320 or 1024) - 16 - x - y - ... - z + // | IN FIFO MAX | + // --------------- + // | FREE | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): + // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN + // + // - All EP OUT shared a unique OUT FIFO which uses + // - 13 for setup packets + control words (up to 3 setup packets). + // - 1 for global NAK (not required/used here). + // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" + // - 2 for each used OUT endpoint + // + // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum + // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x EP_MAX = 47 + 2 x EP_MAX + // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x EP_MAX = 271 + 2 x EP_MAX + // + // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge + // of the overall picture yet. We will use the worst scenario: largest possible + EP_MAX + // + // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO + // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to + // overwrite this. + + #if TUD_OPT_HIGH_SPEED + usb_otg->GRXFSIZ = calc_rx_ff_size(512); + #else + usb_otg->GRXFSIZ = calc_rx_ff_size(64); + #endif + + _allocated_fifo_words_tx = 16; + + // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) + usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); + + // Fixed control EP0 size to 64 bytes + in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos); + xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64; + + out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); + + usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; +} + +// Set turn-around timeout according to link speed +extern uint32_t SystemCoreClock; +static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) +{ + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; + + if ( speed == TUSB_SPEED_HIGH ) + { + // Use fixed 0x09 for Highspeed + usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); + } + else + { + // Turnaround timeout depends on the MCU clock + uint32_t turnaround; + + if ( SystemCoreClock >= 32000000U ) + turnaround = 0x6U; + else if ( SystemCoreClock >= 27500000U ) + turnaround = 0x7U; + else if ( SystemCoreClock >= 24000000U ) + turnaround = 0x8U; + else if ( SystemCoreClock >= 21800000U ) + turnaround = 0x9U; + else if ( SystemCoreClock >= 20000000U ) + turnaround = 0xAU; + else if ( SystemCoreClock >= 18500000U ) + turnaround = 0xBU; + else if ( SystemCoreClock >= 17200000U ) + turnaround = 0xCU; + else if ( SystemCoreClock >= 16000000U ) + turnaround = 0xDU; + else if ( SystemCoreClock >= 15000000U ) + turnaround = 0xEU; + else + turnaround = 0xFU; + + // Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz + usb_otg->GUSBCFG |= (turnaround << USB_OTG_GUSBCFG_TRDT_Pos); + } +} + +static tusb_speed_t get_speed(uint8_t rhport) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; + return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; +} + +static void set_speed(uint8_t rhport, tusb_speed_t speed) +{ + uint32_t bitvalue; + + if ( rhport == 1 ) + { + bitvalue = ((TUSB_SPEED_HIGH == speed) ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS); + } + else + { + bitvalue = DCD_FULL_SPEED; + } + + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + + // Clear and set speed bits + dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); + dev->DCFG |= (bitvalue << USB_OTG_DCFG_DSPD_Pos); +} + +#if 0 +// From CM4IO xtal to usb hub, may not be correct +#define HSE_VALUE 24000000 + +static bool USB_HS_PHYCInit(void) +{ + USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE; + + // Enable LDO + usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; + + // Wait until LDO ready + while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {} + + uint32_t phyc_pll = 0; + + // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS + switch ( HSE_VALUE ) + { + case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break; + case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break; + case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break; + case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break; + case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break; + case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header + default: + TU_ASSERT(0); + } + usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll; + + // Control the tuning interface of the High Speed PHY + // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver + usb_hs_phyc->USB_HS_PHYC_TUNE |= 0x00000F13U; + + // Enable PLL internal PHY + usb_hs_phyc->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; + + // Original ST code has 2 ms delay for PLL stabilization. + // Primitive test shows that more than 10 USB un/replug cycle showed no error with enumeration + + return true; +} +#endif + +static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) +{ + (void) rhport; + + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + // EP0 is limited to one packet each xfer + // We use multiple transaction of xfer->max_size length to get a whole transfer done + if(epnum == 0) { + xfer_ctl_t * const xfer = XFER_CTL_BASE(epnum, dir); + total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); + ep0_pending[dir] -= total_bytes; + } + + // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. + if(dir == TUSB_DIR_IN) { + // A full IN transfer (multiple packets, possibly) triggers XFRC. + in_ep[epnum].DIEPTSIZ = (num_packets << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | + ((total_bytes << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) & USB_OTG_DIEPTSIZ_XFRSIZ_Msk); + + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK; + // For ISO endpoint set correct odd/even bit for next frame. + if ((in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP) == USB_OTG_DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) + { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos)); + in_ep[epnum].DIEPCTL |= (odd_frame_now ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DIEPCTL_SODDFRM_Msk); + } + // Enable fifo empty interrupt only if there are something to put in the fifo. + if(total_bytes != 0) { + dev->DIEPEMPMSK |= (1 << epnum); + } + } else { + // A full OUT transfer (multiple packets, possibly) triggers XFRC. + out_ep[epnum].DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT_Msk | USB_OTG_DOEPTSIZ_XFRSIZ); + out_ep[epnum].DOEPTSIZ |= (num_packets << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | + ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk); + + out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; + if ((out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP) == USB_OTG_DOEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) + { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos)); + out_ep[epnum].DOEPCTL |= (odd_frame_now ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DOEPCTL_SODDFRM_Msk); + } + } +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ + +TU_ATTR_UNUSED +static void reset_core(USB_OTG_GlobalTypeDef * usb_otg) { + while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0) {} + + TU_LOG(2, " resetting\r\n"); + usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; + TU_LOG(2, " waiting\r\n"); + while ((usb_otg->GRSTCTL & (USB_OTG_GRSTCTL_AHBIDL | USB_OTG_GRSTCTL_CSRST)) != USB_OTG_GRSTCTL_AHBIDL) {} + TU_LOG(2, " reset done\r\n"); +} + +void dcd_init (uint8_t rhport) +{ + printf("test done\r\n"); + // Programming model begins in the last section of the chapter on the USB + // peripheral in each Reference Manual. + TU_LOG(2, " dcd_init\r\n"); + + TU_LOG2("Test 123\r\n"); + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + +#if 1 + // No VBUS sense + usb_otg->GCCFG &= ~(1UL << 21); // USB_OTG_GCCFG_VBDEN + + // B-peripheral session valid override enable + usb_otg->GOTGCTL |= (1UL << 6); // USB_OTG_GOTGCTL_BVALOEN + usb_otg->GOTGCTL |= (1UL << 7); // USB_OTG_GOTGCTL_BVALOVAL + + // Force device mode + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; + usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + + // deactivate internal PHY + usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; + + // Init The UTMI Interface + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); + + // Select default internal VBUS Indicator and Drive for ULPI + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); + + // Select UTMI Interface + usb_otg->GUSBCFG &= ~(1UL << 4); // USB_OTG_GUSBCFG_ULPI_UTMI_SEL + usb_otg->GCCFG |= (1UL << 32); // USB_OTG_GCCFG_PHYHSEN + + // Enables control of a High Speed USB PHY + //USB_HS_PHYCInit(); + + // Reset core after selecting PHY + // Wait AHB IDLE, reset then wait until it is cleared +// while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U) {} +// usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; +// while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST) {} + + reset_core(usb_otg); + + // Restart PHY clock + *((volatile uint32_t *)(RHPORT_REGS_BASE + USB_OTG_PCGCCTL_BASE)) = 0; + +#else + + // ReadBackReg(&Core->Usb); + // Core->Usb.UlpiDriveExternalVbus = 0; + // Core->Usb.TsDlinePulseEnable = 0; + // WriteThroughReg(&Core->Usb); + + // This sequence is modeled after: https://github.com/Chadderz121/csud/blob/e13b9355d043a9cdd384b335060f1bc0416df61e/source/hcd/dwc/designware20.c#L689 + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIEVBUSD); + reset_core(usb_otg); + + // Core->Usb.ModeSelect = UTMI; + // LOG_DEBUG("HCD: Interface: UTMI+.\n"); + // Core->Usb.PhyInterface = false; + + // HcdReset(); + TU_LOG2("init phy\r\n"); + usb_otg->GUSBCFG |= (1 << 4); // bit four sets UTMI+ mode + usb_otg->GUSBCFG &= ~(1 << 3); // bit three disables phy interface + reset_core(usb_otg); + + // LOG_DEBUG("HCD: ULPI FSLS configuration: disabled.\n"); + // Core->Usb.UlpiFsls = false; + // Core->Usb.ulpi_clk_sus_m = false; + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_ULPICSM); + + // LOG_DEBUG("HCD: DMA configuration: enabled.\n"); + // Core->Ahb.DmaEnable = true; + // Core->Ahb.DmaRemainderMode = Incremental; + usb_otg->GAHBCFG &= ~(1 << 23); // Remainder mode + usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN; + + // LOG_DEBUG("HCD: HNP/SRP configuration: HNP, SRP.\n"); + // Core->Usb.HnpCapable = true; + // Core->Usb.SrpCapable = true; + usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_SRPCAP | USB_OTG_GUSBCFG_HNPCAP; + +#endif + + // Clear all interrupts + usb_otg->GINTSTS |= usb_otg->GINTSTS; + + // Required as part of core initialization. + // TODO: How should mode mismatch be handled? It will cause + // the core to stop working/require reset. + usb_otg->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; + + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + + // If USB host misbehaves during status portion of control xfer + // (non zero-length packet), send STALL back and discard. + dev->DCFG |= USB_OTG_DCFG_NZLSOHSK; + + set_speed(rhport, TUSB_SPEED_HIGH); + + // TODO internal phy (full speed) + usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; + + usb_otg->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | + USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | + USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); + + // Enable global interrupt + usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; + + dcd_connect(rhport); +} + +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; + BP_EnableIRQ(USB_IRQn); +} + +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + BP_DisableIRQ(USB_IRQn); +} + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + dev->DCFG = (dev->DCFG & ~USB_OTG_DCFG_DAD_Msk) | (dev_addr << USB_OTG_DCFG_DAD_Pos); + + // Response with status after changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +static void remote_wakeup_delay(void) +{ + // try to delay for 1 ms + uint32_t count = SystemCoreClock / 1000; + while ( count-- ) + { + // __NOP(); + } +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + + // set remote wakeup + dev->DCTL |= USB_OTG_DCTL_RWUSIG; + + // enable SOF to detect bus resume + usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; + usb_otg->GINTMSK |= USB_OTG_GINTMSK_SOFM; + + // Per specs: remote wakeup signal bit must be clear within 1-15ms + remote_wakeup_delay(); + + dev->DCTL &= ~USB_OTG_DCTL_RWUSIG; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + dev->DCTL &= ~USB_OTG_DCTL_SDIS; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + dev->DCTL |= USB_OTG_DCTL_SDIS; +} + + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + TU_ASSERT(epnum < EP_MAX); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); + xfer->interval = desc_edpt->bInterval; + + uint16_t const fifo_size = (xfer->max_size + 3) / 4; // Round up to next full word + + if(dir == TUSB_DIR_OUT) + { + // Calculate required size of RX FIFO + uint16_t const sz = calc_rx_ff_size(4*fifo_size); + + // If size_rx needs to be extended check if possible and if so enlarge it + if (usb_otg->GRXFSIZ < sz) + { + TU_ASSERT(sz + _allocated_fifo_words_tx <= EP_FIFO_SIZE/4); + + // Enlarge RX FIFO + usb_otg->GRXFSIZ = sz; + } + + out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) | + (desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos) | + (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << USB_OTG_DOEPCTL_MPSIZ_Pos); + + dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum)); + } + else + { + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO 0 | + // --------------- (320 or 1024) - 16 + // | IN FIFO 1 | + // --------------- (320 or 1024) - 16 - x + // | . . . . | + // --------------- (320 or 1024) - 16 - x - y - ... - z + // | IN FIFO MAX | + // --------------- + // | FREE | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // In FIFO is allocated by following rules: + // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". + + // Check if free space is available + TU_ASSERT(_allocated_fifo_words_tx + fifo_size + usb_otg->GRXFSIZ <= EP_FIFO_SIZE/4); + + _allocated_fifo_words_tx += fifo_size; + + TU_LOG(2, " Allocated %u bytes at offset %u", fifo_size*4, EP_FIFO_SIZE-_allocated_fifo_words_tx*4); + + // DIEPTXF starts at FIFO #1. + // Both TXFD and TXSA are in unit of 32-bit words. + usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); + + in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) | + (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) | + (desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) | + (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << USB_OTG_DIEPCTL_MPSIZ_Pos); + + dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum)); + } + + return true; +} + +// Close all non-control endpoints, cancel all pending transfers if any. +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + +// USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + // Disable non-control interrupt + dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos); + + for(uint8_t n = 1; n < EP_MAX; n++) + { + // disable OUT endpoint + out_ep[n].DOEPCTL = 0; + xfer_status[n][TUSB_DIR_OUT].max_size = 0; + + // disable IN endpoint + in_ep[n].DIEPCTL = 0; + xfer_status[n][TUSB_DIR_IN].max_size = 0; + } + + // reset allocated fifo IN + _allocated_fifo_words_tx = 16; +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + xfer->ff = NULL; + xfer->total_len = total_bytes; + + // EP0 can only handle one packet + if(epnum == 0) { + ep0_pending[dir] = total_bytes; + // Schedule the first transaction for EP0 transfer + edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]); + return true; + } + + uint16_t num_packets = (total_bytes / xfer->max_size); + uint16_t const short_packet_size = total_bytes % xfer->max_size; + + // Zero-size packet is special case. + if(short_packet_size > 0 || (total_bytes == 0)) { + num_packets++; + } + + // Schedule packets to be sent within interrupt + edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); + + return true; +} + +// The number of bytes has to be given explicitly to allow more flexible control of how many +// bytes should be written and second to keep the return value free to give back a boolean +// success message. If total_bytes is too big, the FIFO will copy only what is available +// into the USB buffer! +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 + TU_ASSERT(ff->item_size == 1); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = NULL; + xfer->ff = ff; + xfer->total_len = total_bytes; + + uint16_t num_packets = (total_bytes / xfer->max_size); + uint16_t const short_packet_size = total_bytes % xfer->max_size; + + // Zero-size packet is special case. + if(short_packet_size > 0 || (total_bytes == 0)) num_packets++; + + // Schedule packets to be sent within interrupt + edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); + + return true; +} + +static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if(dir == TUSB_DIR_IN) { + // Only disable currently enabled non-control endpoint + if ( (epnum == 0) || !(in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPENA) ){ + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK | (stall ? USB_OTG_DIEPCTL_STALL : 0); + } else { + // Stop transmitting packets and NAK IN xfers. + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK; + while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_INEPNE) == 0); + + // Disable the endpoint. + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPDIS | (stall ? USB_OTG_DIEPCTL_STALL : 0); + while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_EPDISD_Msk) == 0); + in_ep[epnum].DIEPINT = USB_OTG_DIEPINT_EPDISD; + } + + // Flush the FIFO, and wait until we have confirmed it cleared. + usb_otg->GRSTCTL |= (epnum << USB_OTG_GRSTCTL_TXFNUM_Pos); + usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_TXFFLSH; + while((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH_Msk) != 0); + } else { + // Only disable currently enabled non-control endpoint + if ( (epnum == 0) || !(out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPENA) ){ + out_ep[epnum].DOEPCTL |= stall ? USB_OTG_DOEPCTL_STALL : 0; + } else { + // Asserting GONAK is required to STALL an OUT endpoint. + // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt + // anyway, and it can't be cleared by user code. If this while loop never + // finishes, we have bigger problems than just the stack. + dev->DCTL |= USB_OTG_DCTL_SGONAK; + while((usb_otg->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF_Msk) == 0); + + // Ditto here- disable the endpoint. + out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPDIS | (stall ? USB_OTG_DOEPCTL_STALL : 0); + while((out_ep[epnum].DOEPINT & USB_OTG_DOEPINT_EPDISD_Msk) == 0); + out_ep[epnum].DOEPINT = USB_OTG_DOEPINT_EPDISD; + + // Allow other OUT endpoints to keep receiving. + dev->DCTL |= USB_OTG_DCTL_CGONAK; + } + } +} + +/** + * Close an endpoint. + */ +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +{ + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_edpt_disable(rhport, ep_addr, false); + + // Update max_size + xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation + + if (dir == TUSB_DIR_IN) + { + uint16_t const fifo_size = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXFD_Msk) >> USB_OTG_DIEPTXF_INEPTXFD_Pos; + uint16_t const fifo_start = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXSA_Msk) >> USB_OTG_DIEPTXF_INEPTXSA_Pos; + // For now only the last opened endpoint can be closed without fuss. + TU_ASSERT(fifo_start == EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,); + _allocated_fifo_words_tx -= fifo_size; + } + else + { + _out_ep_closed = true; // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty + } +} + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + dcd_edpt_disable(rhport, ep_addr, true); +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // Clear stall and reset data toggle + if(dir == TUSB_DIR_IN) { + in_ep[epnum].DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + } else { + out_ep[epnum].DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; + out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + } +} + +/*------------------------------------------------------------------*/ + +// Read a single data packet from receive FIFO +static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len) +{ + (void) rhport; + + usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); + + // Reading full available 32 bit words from fifo + uint16_t full_words = len >> 2; + for(uint16_t i = 0; i < full_words; i++) { + uint32_t tmp = *rx_fifo; + dst[0] = tmp & 0x000000FF; + dst[1] = (tmp & 0x0000FF00) >> 8; + dst[2] = (tmp & 0x00FF0000) >> 16; + dst[3] = (tmp & 0xFF000000) >> 24; + dst += 4; + } + + // Read the remaining 1-3 bytes from fifo + uint8_t bytes_rem = len & 0x03; + if(bytes_rem != 0) { + uint32_t tmp = *rx_fifo; + dst[0] = tmp & 0x000000FF; + if(bytes_rem > 1) { + dst[1] = (tmp & 0x0000FF00) >> 8; + } + if(bytes_rem > 2) { + dst[2] = (tmp & 0x00FF0000) >> 16; + } + } +} + +// Write a single data packet to EPIN FIFO +static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, uint16_t len) +{ + (void) rhport; + + usb_fifo_t tx_fifo = FIFO_BASE(rhport, fifo_num); + + // Pushing full available 32 bit words to fifo + uint16_t full_words = len >> 2; + for(uint16_t i = 0; i < full_words; i++){ + *tx_fifo = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0]; + src += 4; + } + + // Write the remaining 1-3 bytes into fifo + uint8_t bytes_rem = len & 0x03; + if(bytes_rem){ + uint32_t tmp_word = 0; + tmp_word |= src[0]; + if(bytes_rem > 1){ + tmp_word |= src[1] << 8; + } + if(bytes_rem > 2){ + tmp_word |= src[2] << 16; + } + *tx_fifo = tmp_word; + } +} + +static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) { + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); + + // Pop control word off FIFO + uint32_t ctl_word = usb_otg->GRXSTSP; + uint8_t pktsts = (ctl_word & USB_OTG_GRXSTSP_PKTSTS_Msk) >> USB_OTG_GRXSTSP_PKTSTS_Pos; + uint8_t epnum = (ctl_word & USB_OTG_GRXSTSP_EPNUM_Msk) >> USB_OTG_GRXSTSP_EPNUM_Pos; + uint16_t bcnt = (ctl_word & USB_OTG_GRXSTSP_BCNT_Msk) >> USB_OTG_GRXSTSP_BCNT_Pos; + + switch(pktsts) { + case 0x01: // Global OUT NAK (Interrupt) + break; + + case 0x02: // Out packet recvd + { + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + + // Read packet off RxFIFO + if (xfer->ff) + { + // Ring buffer + tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *)(uintptr_t) rx_fifo, bcnt); + } + else + { + // Linear buffer + read_fifo_packet(rhport, xfer->buffer, bcnt); + + // Increment pointer to xfer data + xfer->buffer += bcnt; + } + + // Truncate transfer length in case of short packet + if(bcnt < xfer->max_size) { + xfer->total_len -= (out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos; + if(epnum == 0) { + xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; + ep0_pending[TUSB_DIR_OUT] = 0; + } + } + } + break; + + case 0x03: // Out packet done (Interrupt) + break; + + case 0x04: // Setup packet done (Interrupt) + out_ep[epnum].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); + break; + + case 0x06: // Setup packet recvd + // We can receive up to three setup packets in succession, but + // only the last one is valid. + _setup_packet[0] = (* rx_fifo); + _setup_packet[1] = (* rx_fifo); + break; + + default: // Invalid + TU_BREAKPOINT(); + break; + } +} + +static void handle_epout_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTypeDef * out_ep) { + // DAINT for a given EP clears when DOEPINTx is cleared. + // OEPINT will be cleared when DAINT's out bits are cleared. + for(uint8_t n = 0; n < EP_MAX; n++) { + xfer_ctl_t * xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); + + if(dev->DAINT & (1 << (USB_OTG_DAINT_OEPINT_Pos + n))) { + // SETUP packet Setup Phase done. + if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_STUP) { + out_ep[n].DOEPINT = USB_OTG_DOEPINT_STUP; + dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true); + } + + // OUT XFER complete + if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_XFRC) { + out_ep[n].DOEPINT = USB_OTG_DOEPINT_XFRC; + + // EP0 can only handle one packet + if((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + } + } +} + +static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointTypeDef * in_ep) { + // DAINT for a given EP clears when DIEPINTx is cleared. + // IEPINT will be cleared when DAINT's out bits are cleared. + for ( uint8_t n = 0; n < EP_MAX; n++ ) + { + xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_IN); + + if ( dev->DAINT & (1 << (USB_OTG_DAINT_IEPINT_Pos + n)) ) + { + // IN XFER complete (entire xfer). + if ( in_ep[n].DIEPINT & USB_OTG_DIEPINT_XFRC ) + { + in_ep[n].DIEPINT = USB_OTG_DIEPINT_XFRC; + + // EP0 can only handle one packet + if((n == 0) && ep0_pending[TUSB_DIR_IN]) { + // Schedule another packet to be transmitted. + edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); + } else { + dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + + // XFER FIFO empty + if ( (in_ep[n].DIEPINT & USB_OTG_DIEPINT_TXFE) && (dev->DIEPEMPMSK & (1 << n)) ) + { + // DIEPINT's TXFE bit is read-only, software cannot clear it. + // It will only be cleared by hardware when written bytes is more than + // - 64 bytes or + // - Half of TX FIFO size (configured by DIEPTXF) + + uint16_t remaining_packets = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_PKTCNT_Msk) >> USB_OTG_DIEPTSIZ_PKTCNT_Pos; + + // Process every single packet (only whole packets can be written to fifo) + for(uint16_t i = 0; i < remaining_packets; i++) + { + uint16_t const remaining_bytes = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos; + + // Packet can not be larger than ep max size + uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size); + + // It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current + // EP has to be checked if the buffer can take another WHOLE packet + if(packet_size > ((in_ep[n].DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV_Msk) << 2)) break; + + // Push packet to Tx-FIFO + if (xfer->ff) + { + usb_fifo_t tx_fifo = FIFO_BASE(rhport, n); + tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *)(uintptr_t) tx_fifo, packet_size); + } + else + { + write_fifo_packet(rhport, n, xfer->buffer, packet_size); + + // Increment pointer to xfer data + xfer->buffer += packet_size; + } + } + + // Turn off TXFE if all bytes are written. + if (((in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos) == 0) + { + dev->DIEPEMPMSK &= ~(1 << n); + } + } + } + } +} + +void dcd_int_handler(uint8_t rhport) +{ + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + uint32_t const int_status = usb_otg->GINTSTS & usb_otg->GINTMSK; + + if(int_status & USB_OTG_GINTSTS_USBRST) + { + // USBRST is start of reset. + usb_otg->GINTSTS = USB_OTG_GINTSTS_USBRST; + bus_reset(rhport); + } + + if(int_status & USB_OTG_GINTSTS_ENUMDNE) + { + // ENUMDNE is the end of reset where speed of the link is detected + + usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; + + tusb_speed_t const speed = get_speed(rhport); + + set_turnaround(usb_otg, speed); + dcd_event_bus_reset(rhport, speed, true); + } + + if(int_status & USB_OTG_GINTSTS_USBSUSP) + { + usb_otg->GINTSTS = USB_OTG_GINTSTS_USBSUSP; + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + if(int_status & USB_OTG_GINTSTS_WKUINT) + { + usb_otg->GINTSTS = USB_OTG_GINTSTS_WKUINT; + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + + // TODO check USB_OTG_GINTSTS_DISCINT for disconnect detection + // if(int_status & USB_OTG_GINTSTS_DISCINT) + + if(int_status & USB_OTG_GINTSTS_OTGINT) + { + // OTG INT bit is read-only + uint32_t const otg_int = usb_otg->GOTGINT; + + if (otg_int & USB_OTG_GOTGINT_SEDET) + { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + + usb_otg->GOTGINT = otg_int; + } + + if(int_status & USB_OTG_GINTSTS_SOF) + { + usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; + + // Disable SOF interrupt since currently only used for remote wakeup detection + usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_SOFM; + + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + + // RxFIFO non-empty interrupt handling. + if(int_status & USB_OTG_GINTSTS_RXFLVL) + { + // RXFLVL bit is read-only + + // Mask out RXFLVL while reading data from FIFO + usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; + + // Loop until all available packets were handled + do + { + handle_rxflvl_ints(rhport, out_ep); + } while(usb_otg->GINTSTS & USB_OTG_GINTSTS_RXFLVL); + + // Manage RX FIFO size + if (_out_ep_closed) + { + update_grxfsiz(rhport); + + // Disable flag + _out_ep_closed = false; + } + + usb_otg->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; + } + + // OUT endpoint interrupt handling. + if(int_status & USB_OTG_GINTSTS_OEPINT) + { + // OEPINT is read-only + handle_epout_ints(rhport, dev, out_ep); + } + + // IN endpoint interrupt handling. + if(int_status & USB_OTG_GINTSTS_IEPINT) + { + // IEPINT bit read-only + handle_epin_ints(rhport, dev, in_ep); + } + + // // Check for Incomplete isochronous IN transfer + // if(int_status & USB_OTG_GINTSTS_IISOIXFR) { + // printf(" IISOIXFR!\r\n"); + //// TU_LOG2(" IISOIXFR!\r\n"); + // } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/broadcom/synopsys/synopsys_common.h b/circuitpython/lib/tinyusb/src/portable/broadcom/synopsys/synopsys_common.h new file mode 100644 index 0000000..81ce3b4 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/broadcom/synopsys/synopsys_common.h @@ -0,0 +1,1476 @@ +/** + ****************************************************************************** + * @file synopsys_common.h + * @author MCD Application Team + * @brief CMSIS Cortex-M3 Device USB OTG peripheral Header File. + * This file contains the USB OTG peripheral register's definitions, bits + * definitions and memory mapping for STM32F1xx devices. + * + * This file contains: + * - Data structures and the address mapping for the USB OTG peripheral + * - The Peripheral's registers declarations and bits definition + * - Macros to access the peripheral's registers hardware + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#include "stdint.h" + +#pragma once + +#ifdef __cplusplus + #define __I volatile +#else + #define __I volatile const +#endif +#define __O volatile +#define __IO volatile +#define __IM volatile const +#define __OM volatile +#define __IOM volatile + +/** + * @brief __USB_OTG_Core_register + */ + +typedef struct +{ + __IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register Address offset: 000h */ + __IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register Address offset: 004h */ + __IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register Address offset: 008h */ + __IO uint32_t GUSBCFG; /*!< Core USB Configuration Register Address offset: 00Ch */ + __IO uint32_t GRSTCTL; /*!< Core Reset Register Address offset: 010h */ + __IO uint32_t GINTSTS; /*!< Core Interrupt Register Address offset: 014h */ + __IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register Address offset: 018h */ + __IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register Address offset: 01Ch */ + __IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register Address offset: 020h */ + __IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register Address offset: 024h */ + __IO uint32_t DIEPTXF0_HNPTXFSIZ; /*!< EP0 / Non Periodic Tx FIFO Size Register Address offset: 028h */ + __IO uint32_t HNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg Address offset: 02Ch */ + uint32_t Reserved30[2]; /*!< Reserved 030h*/ + __IO uint32_t GCCFG; /*!< General Purpose IO Register Address offset: 038h */ + __IO uint32_t CID; /*!< User ID Register 03Ch */ + __IO uint32_t GSNPSID; /* USB_OTG core ID 040h*/ + __IO uint32_t GHWCFG1; /* User HW config1 044h*/ + __IO uint32_t GHWCFG2; /* User HW config2 048h*/ + __IO uint32_t GHWCFG3; /*!< User HW config3 04Ch */ + uint32_t Reserved6; /*!< Reserved 050h */ + __IO uint32_t GLPMCFG; /*!< LPM Register 054h */ + __IO uint32_t GPWRDN; /*!< Power Down Register 058h */ + __IO uint32_t GDFIFOCFG; /*!< DFIFO Software Config Register 05Ch */ + __IO uint32_t GADPCTL; /*!< ADP Timer, Control and Status Register 60Ch */ + uint32_t Reserved43[39]; /*!< Reserved 058h-0FFh */ + __IO uint32_t HPTXFSIZ; /*!< Host Periodic Tx FIFO Size Reg Address offset: 100h */ + __IO uint32_t DIEPTXF[0x0F]; /*!< dev Periodic Transmit FIFO Address offset: 0x104 */ +} USB_OTG_GlobalTypeDef; + + + +/** + * @brief __device_Registers + */ + +typedef struct +{ + __IO uint32_t DCFG; /*!< dev Configuration Register Address offset: 800h*/ + __IO uint32_t DCTL; /*!< dev Control Register Address offset: 804h*/ + __IO uint32_t DSTS; /*!< dev Status Register (RO) Address offset: 808h*/ + uint32_t Reserved0C; /*!< Reserved 80Ch*/ + __IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask Address offset: 810h*/ + __IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask Address offset: 814h*/ + __IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg Address offset: 818h*/ + __IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask Address offset: 81Ch*/ + uint32_t Reserved20; /*!< Reserved 820h*/ + uint32_t Reserved9; /*!< Reserved 824h*/ + __IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register Address offset: 828h*/ + __IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register Address offset: 82Ch*/ + __IO uint32_t DTHRCTL; /*!< dev thr Address offset: 830h*/ + __IO uint32_t DIEPEMPMSK; /*!< dev empty msk Address offset: 834h*/ + __IO uint32_t DEACHINT; /*!< dedicated EP interrupt Address offset: 838h*/ + __IO uint32_t DEACHMSK; /*!< dedicated EP msk Address offset: 83Ch*/ + uint32_t Reserved40; /*!< dedicated EP mask Address offset: 840h*/ + __IO uint32_t DINEP1MSK; /*!< dedicated EP mask Address offset: 844h*/ + uint32_t Reserved44[15]; /*!< Reserved 844-87Ch*/ + __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk Address offset: 884h*/ +} USB_OTG_DeviceTypeDef; + +/** + * @brief __IN_Endpoint-Specific_Register + */ + +typedef struct +{ + __IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/ + uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h*/ + __IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/ + uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch*/ + __IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/ + __IO uint32_t DIEPDMA; /*!< IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/ + __IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/ + uint32_t Reserved18; /*!< Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/ +} USB_OTG_INEndpointTypeDef; + +/** + * @brief __OUT_Endpoint-Specific_Registers + */ + +typedef struct +{ + __IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ + uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h*/ + __IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ + uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch*/ + __IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ + __IO uint32_t DOEPDMA; /*!< dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ + uint32_t Reserved18[2]; /*!< Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ +} USB_OTG_OUTEndpointTypeDef; + +/** + * @brief __Host_Mode_Register_Structures + */ + +typedef struct +{ + __IO uint32_t HCFG; /*!< Host Configuration Register 400h*/ + __IO uint32_t HFIR; /*!< Host Frame Interval Register 404h*/ + __IO uint32_t HFNUM; /*!< Host Frame Nbr/Frame Remaining 408h*/ + uint32_t Reserved40C; /*!< Reserved 40Ch*/ + __IO uint32_t HPTXSTS; /*!< Host Periodic Tx FIFO/ Queue Status 410h*/ + __IO uint32_t HAINT; /*!< Host All Channels Interrupt Register 414h*/ + __IO uint32_t HAINTMSK; /*!< Host All Channels Interrupt Mask 418h*/ +} USB_OTG_HostTypeDef; + +/** + * @brief __Host_Channel_Specific_Registers + */ + +typedef struct +{ + __IO uint32_t HCCHAR; + __IO uint32_t HCSPLT; + __IO uint32_t HCINT; + __IO uint32_t HCINTMSK; + __IO uint32_t HCTSIZ; + __IO uint32_t HCDMA; + uint32_t Reserved[2]; +} USB_OTG_HostChannelTypeDef; + +/*!< USB registers base address */ +#define USB_OTG_FS_PERIPH_BASE 0x50000000UL + +// #define USB_OTG_GLOBAL_BASE 0x00000000UL +// #define USB_OTG_DEVICE_BASE 0x00000800UL +#define USB_OTG_IN_ENDPOINT_BASE 0x00000900UL +#define USB_OTG_OUT_ENDPOINT_BASE 0x00000B00UL +#define USB_OTG_EP_REG_SIZE 0x00000020UL +// #define USB_OTG_HOST_BASE 0x00000400UL +#define USB_OTG_HOST_PORT_BASE 0x00000440UL +#define USB_OTG_HOST_CHANNEL_BASE 0x00000500UL +#define USB_OTG_HOST_CHANNEL_SIZE 0x00000020UL +#define USB_OTG_PCGCCTL_BASE 0x00000E00UL +#define USB_OTG_FIFO_BASE 0x00001000UL +#define USB_OTG_FIFO_SIZE 0x00001000UL + +/******************************************************************************/ +/* */ +/* USB_OTG */ +/* */ +/******************************************************************************/ +/******************** Bit definition for USB_OTG_GOTGCTL register ***********/ +#define USB_OTG_GOTGCTL_SRQSCS_Pos (0U) +#define USB_OTG_GOTGCTL_SRQSCS_Msk (0x1UL << USB_OTG_GOTGCTL_SRQSCS_Pos) /*!< 0x00000001 */ +#define USB_OTG_GOTGCTL_SRQSCS USB_OTG_GOTGCTL_SRQSCS_Msk /*!< Session request success */ +#define USB_OTG_GOTGCTL_SRQ_Pos (1U) +#define USB_OTG_GOTGCTL_SRQ_Msk (0x1UL << USB_OTG_GOTGCTL_SRQ_Pos) /*!< 0x00000002 */ +#define USB_OTG_GOTGCTL_SRQ USB_OTG_GOTGCTL_SRQ_Msk /*!< Session request */ +#define USB_OTG_GOTGCTL_HNGSCS_Pos (8U) +#define USB_OTG_GOTGCTL_HNGSCS_Msk (0x1UL << USB_OTG_GOTGCTL_HNGSCS_Pos) /*!< 0x00000100 */ +#define USB_OTG_GOTGCTL_HNGSCS USB_OTG_GOTGCTL_HNGSCS_Msk /*!< Host set HNP enable */ +#define USB_OTG_GOTGCTL_HNPRQ_Pos (9U) +#define USB_OTG_GOTGCTL_HNPRQ_Msk (0x1UL << USB_OTG_GOTGCTL_HNPRQ_Pos) /*!< 0x00000200 */ +#define USB_OTG_GOTGCTL_HNPRQ USB_OTG_GOTGCTL_HNPRQ_Msk /*!< HNP request */ +#define USB_OTG_GOTGCTL_HSHNPEN_Pos (10U) +#define USB_OTG_GOTGCTL_HSHNPEN_Msk (0x1UL << USB_OTG_GOTGCTL_HSHNPEN_Pos) /*!< 0x00000400 */ +#define USB_OTG_GOTGCTL_HSHNPEN USB_OTG_GOTGCTL_HSHNPEN_Msk /*!< Host set HNP enable */ +#define USB_OTG_GOTGCTL_DHNPEN_Pos (11U) +#define USB_OTG_GOTGCTL_DHNPEN_Msk (0x1UL << USB_OTG_GOTGCTL_DHNPEN_Pos) /*!< 0x00000800 */ +#define USB_OTG_GOTGCTL_DHNPEN USB_OTG_GOTGCTL_DHNPEN_Msk /*!< Device HNP enabled */ +#define USB_OTG_GOTGCTL_CIDSTS_Pos (16U) +#define USB_OTG_GOTGCTL_CIDSTS_Msk (0x1UL << USB_OTG_GOTGCTL_CIDSTS_Pos) /*!< 0x00010000 */ +#define USB_OTG_GOTGCTL_CIDSTS USB_OTG_GOTGCTL_CIDSTS_Msk /*!< Connector ID status */ +#define USB_OTG_GOTGCTL_DBCT_Pos (17U) +#define USB_OTG_GOTGCTL_DBCT_Msk (0x1UL << USB_OTG_GOTGCTL_DBCT_Pos) /*!< 0x00020000 */ +#define USB_OTG_GOTGCTL_DBCT USB_OTG_GOTGCTL_DBCT_Msk /*!< Long/short debounce time */ +#define USB_OTG_GOTGCTL_ASVLD_Pos (18U) +#define USB_OTG_GOTGCTL_ASVLD_Msk (0x1UL << USB_OTG_GOTGCTL_ASVLD_Pos) /*!< 0x00040000 */ +#define USB_OTG_GOTGCTL_ASVLD USB_OTG_GOTGCTL_ASVLD_Msk /*!< A-session valid */ +#define USB_OTG_GOTGCTL_BSVLD_Pos (19U) +#define USB_OTG_GOTGCTL_BSVLD_Msk (0x1UL << USB_OTG_GOTGCTL_BSVLD_Pos) /*!< 0x00080000 */ +#define USB_OTG_GOTGCTL_BSVLD USB_OTG_GOTGCTL_BSVLD_Msk /*!< B-session valid */ + +/******************** Bit definition for USB_OTG_HCFG register ********************/ + +#define USB_OTG_HCFG_FSLSPCS_Pos (0U) +#define USB_OTG_HCFG_FSLSPCS_Msk (0x3UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000003 */ +#define USB_OTG_HCFG_FSLSPCS USB_OTG_HCFG_FSLSPCS_Msk /*!< FS/LS PHY clock select */ +#define USB_OTG_HCFG_FSLSPCS_0 (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */ +#define USB_OTG_HCFG_FSLSPCS_1 (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */ +#define USB_OTG_HCFG_FSLSS_Pos (2U) +#define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */ +#define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */ + +/******************** Bit definition for USB_OTG_DCFG register ********************/ + +#define USB_OTG_DCFG_DSPD_Pos (0U) +#define USB_OTG_DCFG_DSPD_Msk (0x3UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000003 */ +#define USB_OTG_DCFG_DSPD USB_OTG_DCFG_DSPD_Msk /*!< Device speed */ +#define USB_OTG_DCFG_DSPD_0 (0x1UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000001 */ +#define USB_OTG_DCFG_DSPD_1 (0x2UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000002 */ +#define USB_OTG_DCFG_NZLSOHSK_Pos (2U) +#define USB_OTG_DCFG_NZLSOHSK_Msk (0x1UL << USB_OTG_DCFG_NZLSOHSK_Pos) /*!< 0x00000004 */ +#define USB_OTG_DCFG_NZLSOHSK USB_OTG_DCFG_NZLSOHSK_Msk /*!< Nonzero-length status OUT handshake */ + +#define USB_OTG_DCFG_DAD_Pos (4U) +#define USB_OTG_DCFG_DAD_Msk (0x7FUL << USB_OTG_DCFG_DAD_Pos) /*!< 0x000007F0 */ +#define USB_OTG_DCFG_DAD USB_OTG_DCFG_DAD_Msk /*!< Device address */ +#define USB_OTG_DCFG_DAD_0 (0x01UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000010 */ +#define USB_OTG_DCFG_DAD_1 (0x02UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000020 */ +#define USB_OTG_DCFG_DAD_2 (0x04UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000040 */ +#define USB_OTG_DCFG_DAD_3 (0x08UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000080 */ +#define USB_OTG_DCFG_DAD_4 (0x10UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000100 */ +#define USB_OTG_DCFG_DAD_5 (0x20UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000200 */ +#define USB_OTG_DCFG_DAD_6 (0x40UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000400 */ + +#define USB_OTG_DCFG_PFIVL_Pos (11U) +#define USB_OTG_DCFG_PFIVL_Msk (0x3UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001800 */ +#define USB_OTG_DCFG_PFIVL USB_OTG_DCFG_PFIVL_Msk /*!< Periodic (micro)frame interval */ +#define USB_OTG_DCFG_PFIVL_0 (0x1UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00000800 */ +#define USB_OTG_DCFG_PFIVL_1 (0x2UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001000 */ + +#define USB_OTG_DCFG_PERSCHIVL_Pos (24U) +#define USB_OTG_DCFG_PERSCHIVL_Msk (0x3UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x03000000 */ +#define USB_OTG_DCFG_PERSCHIVL USB_OTG_DCFG_PERSCHIVL_Msk /*!< Periodic scheduling interval */ +#define USB_OTG_DCFG_PERSCHIVL_0 (0x1UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x01000000 */ +#define USB_OTG_DCFG_PERSCHIVL_1 (0x2UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x02000000 */ + +/******************** Bit definition for USB_OTG_PCGCR register ********************/ +#define USB_OTG_PCGCR_STPPCLK_Pos (0U) +#define USB_OTG_PCGCR_STPPCLK_Msk (0x1UL << USB_OTG_PCGCR_STPPCLK_Pos) /*!< 0x00000001 */ +#define USB_OTG_PCGCR_STPPCLK USB_OTG_PCGCR_STPPCLK_Msk /*!< Stop PHY clock */ +#define USB_OTG_PCGCR_GATEHCLK_Pos (1U) +#define USB_OTG_PCGCR_GATEHCLK_Msk (0x1UL << USB_OTG_PCGCR_GATEHCLK_Pos) /*!< 0x00000002 */ +#define USB_OTG_PCGCR_GATEHCLK USB_OTG_PCGCR_GATEHCLK_Msk /*!< Gate HCLK */ +#define USB_OTG_PCGCR_PHYSUSP_Pos (4U) +#define USB_OTG_PCGCR_PHYSUSP_Msk (0x1UL << USB_OTG_PCGCR_PHYSUSP_Pos) /*!< 0x00000010 */ +#define USB_OTG_PCGCR_PHYSUSP USB_OTG_PCGCR_PHYSUSP_Msk /*!< PHY suspended */ + +/******************** Bit definition for USB_OTG_GOTGINT register ********************/ +#define USB_OTG_GOTGINT_SEDET_Pos (2U) +#define USB_OTG_GOTGINT_SEDET_Msk (0x1UL << USB_OTG_GOTGINT_SEDET_Pos) /*!< 0x00000004 */ +#define USB_OTG_GOTGINT_SEDET USB_OTG_GOTGINT_SEDET_Msk /*!< Session end detected */ +#define USB_OTG_GOTGINT_SRSSCHG_Pos (8U) +#define USB_OTG_GOTGINT_SRSSCHG_Msk (0x1UL << USB_OTG_GOTGINT_SRSSCHG_Pos) /*!< 0x00000100 */ +#define USB_OTG_GOTGINT_SRSSCHG USB_OTG_GOTGINT_SRSSCHG_Msk /*!< Session request success status change */ +#define USB_OTG_GOTGINT_HNSSCHG_Pos (9U) +#define USB_OTG_GOTGINT_HNSSCHG_Msk (0x1UL << USB_OTG_GOTGINT_HNSSCHG_Pos) /*!< 0x00000200 */ +#define USB_OTG_GOTGINT_HNSSCHG USB_OTG_GOTGINT_HNSSCHG_Msk /*!< Host negotiation success status change */ +#define USB_OTG_GOTGINT_HNGDET_Pos (17U) +#define USB_OTG_GOTGINT_HNGDET_Msk (0x1UL << USB_OTG_GOTGINT_HNGDET_Pos) /*!< 0x00020000 */ +#define USB_OTG_GOTGINT_HNGDET USB_OTG_GOTGINT_HNGDET_Msk /*!< Host negotiation detected */ +#define USB_OTG_GOTGINT_ADTOCHG_Pos (18U) +#define USB_OTG_GOTGINT_ADTOCHG_Msk (0x1UL << USB_OTG_GOTGINT_ADTOCHG_Pos) /*!< 0x00040000 */ +#define USB_OTG_GOTGINT_ADTOCHG USB_OTG_GOTGINT_ADTOCHG_Msk /*!< A-device timeout change */ +#define USB_OTG_GOTGINT_DBCDNE_Pos (19U) +#define USB_OTG_GOTGINT_DBCDNE_Msk (0x1UL << USB_OTG_GOTGINT_DBCDNE_Pos) /*!< 0x00080000 */ +#define USB_OTG_GOTGINT_DBCDNE USB_OTG_GOTGINT_DBCDNE_Msk /*!< Debounce done */ + +/******************** Bit definition for USB_OTG_DCTL register ********************/ +#define USB_OTG_DCTL_RWUSIG_Pos (0U) +#define USB_OTG_DCTL_RWUSIG_Msk (0x1UL << USB_OTG_DCTL_RWUSIG_Pos) /*!< 0x00000001 */ +#define USB_OTG_DCTL_RWUSIG USB_OTG_DCTL_RWUSIG_Msk /*!< Remote wakeup signaling */ +#define USB_OTG_DCTL_SDIS_Pos (1U) +#define USB_OTG_DCTL_SDIS_Msk (0x1UL << USB_OTG_DCTL_SDIS_Pos) /*!< 0x00000002 */ +#define USB_OTG_DCTL_SDIS USB_OTG_DCTL_SDIS_Msk /*!< Soft disconnect */ +#define USB_OTG_DCTL_GINSTS_Pos (2U) +#define USB_OTG_DCTL_GINSTS_Msk (0x1UL << USB_OTG_DCTL_GINSTS_Pos) /*!< 0x00000004 */ +#define USB_OTG_DCTL_GINSTS USB_OTG_DCTL_GINSTS_Msk /*!< Global IN NAK status */ +#define USB_OTG_DCTL_GONSTS_Pos (3U) +#define USB_OTG_DCTL_GONSTS_Msk (0x1UL << USB_OTG_DCTL_GONSTS_Pos) /*!< 0x00000008 */ +#define USB_OTG_DCTL_GONSTS USB_OTG_DCTL_GONSTS_Msk /*!< Global OUT NAK status */ + +#define USB_OTG_DCTL_TCTL_Pos (4U) +#define USB_OTG_DCTL_TCTL_Msk (0x7UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000070 */ +#define USB_OTG_DCTL_TCTL USB_OTG_DCTL_TCTL_Msk /*!< Test control */ +#define USB_OTG_DCTL_TCTL_0 (0x1UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000010 */ +#define USB_OTG_DCTL_TCTL_1 (0x2UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000020 */ +#define USB_OTG_DCTL_TCTL_2 (0x4UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000040 */ +#define USB_OTG_DCTL_SGINAK_Pos (7U) +#define USB_OTG_DCTL_SGINAK_Msk (0x1UL << USB_OTG_DCTL_SGINAK_Pos) /*!< 0x00000080 */ +#define USB_OTG_DCTL_SGINAK USB_OTG_DCTL_SGINAK_Msk /*!< Set global IN NAK */ +#define USB_OTG_DCTL_CGINAK_Pos (8U) +#define USB_OTG_DCTL_CGINAK_Msk (0x1UL << USB_OTG_DCTL_CGINAK_Pos) /*!< 0x00000100 */ +#define USB_OTG_DCTL_CGINAK USB_OTG_DCTL_CGINAK_Msk /*!< Clear global IN NAK */ +#define USB_OTG_DCTL_SGONAK_Pos (9U) +#define USB_OTG_DCTL_SGONAK_Msk (0x1UL << USB_OTG_DCTL_SGONAK_Pos) /*!< 0x00000200 */ +#define USB_OTG_DCTL_SGONAK USB_OTG_DCTL_SGONAK_Msk /*!< Set global OUT NAK */ +#define USB_OTG_DCTL_CGONAK_Pos (10U) +#define USB_OTG_DCTL_CGONAK_Msk (0x1UL << USB_OTG_DCTL_CGONAK_Pos) /*!< 0x00000400 */ +#define USB_OTG_DCTL_CGONAK USB_OTG_DCTL_CGONAK_Msk /*!< Clear global OUT NAK */ +#define USB_OTG_DCTL_POPRGDNE_Pos (11U) +#define USB_OTG_DCTL_POPRGDNE_Msk (0x1UL << USB_OTG_DCTL_POPRGDNE_Pos) /*!< 0x00000800 */ +#define USB_OTG_DCTL_POPRGDNE USB_OTG_DCTL_POPRGDNE_Msk /*!< Power-on programming done */ + +/******************** Bit definition for USB_OTG_HFIR register ********************/ +#define USB_OTG_HFIR_FRIVL_Pos (0U) +#define USB_OTG_HFIR_FRIVL_Msk (0xFFFFUL << USB_OTG_HFIR_FRIVL_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HFIR_FRIVL USB_OTG_HFIR_FRIVL_Msk /*!< Frame interval */ + +/******************** Bit definition for USB_OTG_HFNUM register ********************/ +#define USB_OTG_HFNUM_FRNUM_Pos (0U) +#define USB_OTG_HFNUM_FRNUM_Msk (0xFFFFUL << USB_OTG_HFNUM_FRNUM_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HFNUM_FRNUM USB_OTG_HFNUM_FRNUM_Msk /*!< Frame number */ +#define USB_OTG_HFNUM_FTREM_Pos (16U) +#define USB_OTG_HFNUM_FTREM_Msk (0xFFFFUL << USB_OTG_HFNUM_FTREM_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_HFNUM_FTREM USB_OTG_HFNUM_FTREM_Msk /*!< Frame time remaining */ + +/******************** Bit definition for USB_OTG_DSTS register ********************/ +#define USB_OTG_DSTS_SUSPSTS_Pos (0U) +#define USB_OTG_DSTS_SUSPSTS_Msk (0x1UL << USB_OTG_DSTS_SUSPSTS_Pos) /*!< 0x00000001 */ +#define USB_OTG_DSTS_SUSPSTS USB_OTG_DSTS_SUSPSTS_Msk /*!< Suspend status */ + +#define USB_OTG_DSTS_ENUMSPD_Pos (1U) +#define USB_OTG_DSTS_ENUMSPD_Msk (0x3UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000006 */ +#define USB_OTG_DSTS_ENUMSPD USB_OTG_DSTS_ENUMSPD_Msk /*!< Enumerated speed */ +#define USB_OTG_DSTS_ENUMSPD_0 (0x1UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000002 */ +#define USB_OTG_DSTS_ENUMSPD_1 (0x2UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000004 */ +#define USB_OTG_DSTS_EERR_Pos (3U) +#define USB_OTG_DSTS_EERR_Msk (0x1UL << USB_OTG_DSTS_EERR_Pos) /*!< 0x00000008 */ +#define USB_OTG_DSTS_EERR USB_OTG_DSTS_EERR_Msk /*!< Erratic error */ +#define USB_OTG_DSTS_FNSOF_Pos (8U) +#define USB_OTG_DSTS_FNSOF_Msk (0x3FFFUL << USB_OTG_DSTS_FNSOF_Pos) /*!< 0x003FFF00 */ +#define USB_OTG_DSTS_FNSOF USB_OTG_DSTS_FNSOF_Msk /*!< Frame number of the received SOF */ + +/******************** Bit definition for USB_OTG_GAHBCFG register ********************/ +#define USB_OTG_GAHBCFG_GINT_Pos (0U) +#define USB_OTG_GAHBCFG_GINT_Msk (0x1UL << USB_OTG_GAHBCFG_GINT_Pos) /*!< 0x00000001 */ +#define USB_OTG_GAHBCFG_GINT USB_OTG_GAHBCFG_GINT_Msk /*!< Global interrupt mask */ +#define USB_OTG_GAHBCFG_HBSTLEN_Pos (1U) +#define USB_OTG_GAHBCFG_HBSTLEN_Msk (0xFUL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< 0x0000001E */ +#define USB_OTG_GAHBCFG_HBSTLEN USB_OTG_GAHBCFG_HBSTLEN_Msk /*!< Burst length/type */ +#define USB_OTG_GAHBCFG_HBSTLEN_0 (0x0UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< Single */ +#define USB_OTG_GAHBCFG_HBSTLEN_1 (0x1UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR */ +#define USB_OTG_GAHBCFG_HBSTLEN_2 (0x3UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR4 */ +#define USB_OTG_GAHBCFG_HBSTLEN_3 (0x5UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR8 */ +#define USB_OTG_GAHBCFG_HBSTLEN_4 (0x7UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR16 */ +#define USB_OTG_GAHBCFG_DMAEN_Pos (5U) +#define USB_OTG_GAHBCFG_DMAEN_Msk (0x1UL << USB_OTG_GAHBCFG_DMAEN_Pos) /*!< 0x00000020 */ +#define USB_OTG_GAHBCFG_DMAEN USB_OTG_GAHBCFG_DMAEN_Msk /*!< DMA enable */ +#define USB_OTG_GAHBCFG_TXFELVL_Pos (7U) +#define USB_OTG_GAHBCFG_TXFELVL_Msk (0x1UL << USB_OTG_GAHBCFG_TXFELVL_Pos) /*!< 0x00000080 */ +#define USB_OTG_GAHBCFG_TXFELVL USB_OTG_GAHBCFG_TXFELVL_Msk /*!< TxFIFO empty level */ +#define USB_OTG_GAHBCFG_PTXFELVL_Pos (8U) +#define USB_OTG_GAHBCFG_PTXFELVL_Msk (0x1UL << USB_OTG_GAHBCFG_PTXFELVL_Pos) /*!< 0x00000100 */ +#define USB_OTG_GAHBCFG_PTXFELVL USB_OTG_GAHBCFG_PTXFELVL_Msk /*!< Periodic TxFIFO empty level */ + +/******************** Bit definition for USB_OTG_GUSBCFG register ********************/ + +#define USB_OTG_GUSBCFG_TOCAL_Pos (0U) +#define USB_OTG_GUSBCFG_TOCAL_Msk (0x7UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000007 */ +#define USB_OTG_GUSBCFG_TOCAL USB_OTG_GUSBCFG_TOCAL_Msk /*!< FS timeout calibration */ +#define USB_OTG_GUSBCFG_TOCAL_0 (0x1UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000001 */ +#define USB_OTG_GUSBCFG_TOCAL_1 (0x2UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000002 */ +#define USB_OTG_GUSBCFG_TOCAL_2 (0x4UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000004 */ +#define USB_OTG_GUSBCFG_PHYSEL_Pos (6U) +#define USB_OTG_GUSBCFG_PHYSEL_Msk (0x1UL << USB_OTG_GUSBCFG_PHYSEL_Pos) /*!< 0x00000040 */ +#define USB_OTG_GUSBCFG_PHYSEL USB_OTG_GUSBCFG_PHYSEL_Msk /*!< USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */ +#define USB_OTG_GUSBCFG_SRPCAP_Pos (8U) +#define USB_OTG_GUSBCFG_SRPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_SRPCAP_Pos) /*!< 0x00000100 */ +#define USB_OTG_GUSBCFG_SRPCAP USB_OTG_GUSBCFG_SRPCAP_Msk /*!< SRP-capable */ +#define USB_OTG_GUSBCFG_HNPCAP_Pos (9U) +#define USB_OTG_GUSBCFG_HNPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_HNPCAP_Pos) /*!< 0x00000200 */ +#define USB_OTG_GUSBCFG_HNPCAP USB_OTG_GUSBCFG_HNPCAP_Msk /*!< HNP-capable */ +#define USB_OTG_GUSBCFG_TRDT_Pos (10U) +#define USB_OTG_GUSBCFG_TRDT_Msk (0xFUL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00003C00 */ +#define USB_OTG_GUSBCFG_TRDT USB_OTG_GUSBCFG_TRDT_Msk /*!< USB turnaround time */ +#define USB_OTG_GUSBCFG_TRDT_0 (0x1UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000400 */ +#define USB_OTG_GUSBCFG_TRDT_1 (0x2UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000800 */ +#define USB_OTG_GUSBCFG_TRDT_2 (0x4UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00001000 */ +#define USB_OTG_GUSBCFG_TRDT_3 (0x8UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00002000 */ +#define USB_OTG_GUSBCFG_PHYLPCS_Pos (15U) +#define USB_OTG_GUSBCFG_PHYLPCS_Msk (0x1UL << USB_OTG_GUSBCFG_PHYLPCS_Pos) /*!< 0x00008000 */ +#define USB_OTG_GUSBCFG_PHYLPCS USB_OTG_GUSBCFG_PHYLPCS_Msk /*!< PHY Low-power clock select */ +#define USB_OTG_GUSBCFG_ULPIFSLS_Pos (17U) +#define USB_OTG_GUSBCFG_ULPIFSLS_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIFSLS_Pos) /*!< 0x00020000 */ +#define USB_OTG_GUSBCFG_ULPIFSLS USB_OTG_GUSBCFG_ULPIFSLS_Msk /*!< ULPI FS/LS select */ +#define USB_OTG_GUSBCFG_ULPIAR_Pos (18U) +#define USB_OTG_GUSBCFG_ULPIAR_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIAR_Pos) /*!< 0x00040000 */ +#define USB_OTG_GUSBCFG_ULPIAR USB_OTG_GUSBCFG_ULPIAR_Msk /*!< ULPI Auto-resume */ +#define USB_OTG_GUSBCFG_ULPICSM_Pos (19U) +#define USB_OTG_GUSBCFG_ULPICSM_Msk (0x1UL << USB_OTG_GUSBCFG_ULPICSM_Pos) /*!< 0x00080000 */ +#define USB_OTG_GUSBCFG_ULPICSM USB_OTG_GUSBCFG_ULPICSM_Msk /*!< ULPI Clock SuspendM */ +#define USB_OTG_GUSBCFG_ULPIEVBUSD_Pos (20U) +#define USB_OTG_GUSBCFG_ULPIEVBUSD_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSD_Pos) /*!< 0x00100000 */ +#define USB_OTG_GUSBCFG_ULPIEVBUSD USB_OTG_GUSBCFG_ULPIEVBUSD_Msk /*!< ULPI External VBUS Drive */ +#define USB_OTG_GUSBCFG_ULPIEVBUSI_Pos (21U) +#define USB_OTG_GUSBCFG_ULPIEVBUSI_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSI_Pos) /*!< 0x00200000 */ +#define USB_OTG_GUSBCFG_ULPIEVBUSI USB_OTG_GUSBCFG_ULPIEVBUSI_Msk /*!< ULPI external VBUS indicator */ +#define USB_OTG_GUSBCFG_TSDPS_Pos (22U) +#define USB_OTG_GUSBCFG_TSDPS_Msk (0x1UL << USB_OTG_GUSBCFG_TSDPS_Pos) /*!< 0x00400000 */ +#define USB_OTG_GUSBCFG_TSDPS USB_OTG_GUSBCFG_TSDPS_Msk /*!< TermSel DLine pulsing selection */ +#define USB_OTG_GUSBCFG_PCCI_Pos (23U) +#define USB_OTG_GUSBCFG_PCCI_Msk (0x1UL << USB_OTG_GUSBCFG_PCCI_Pos) /*!< 0x00800000 */ +#define USB_OTG_GUSBCFG_PCCI USB_OTG_GUSBCFG_PCCI_Msk /*!< Indicator complement */ +#define USB_OTG_GUSBCFG_PTCI_Pos (24U) +#define USB_OTG_GUSBCFG_PTCI_Msk (0x1UL << USB_OTG_GUSBCFG_PTCI_Pos) /*!< 0x01000000 */ +#define USB_OTG_GUSBCFG_PTCI USB_OTG_GUSBCFG_PTCI_Msk /*!< Indicator pass through */ +#define USB_OTG_GUSBCFG_ULPIIPD_Pos (25U) +#define USB_OTG_GUSBCFG_ULPIIPD_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIIPD_Pos) /*!< 0x02000000 */ +#define USB_OTG_GUSBCFG_ULPIIPD USB_OTG_GUSBCFG_ULPIIPD_Msk /*!< ULPI interface protect disable */ +#define USB_OTG_GUSBCFG_FHMOD_Pos (29U) +#define USB_OTG_GUSBCFG_FHMOD_Msk (0x1UL << USB_OTG_GUSBCFG_FHMOD_Pos) /*!< 0x20000000 */ +#define USB_OTG_GUSBCFG_FHMOD USB_OTG_GUSBCFG_FHMOD_Msk /*!< Forced host mode */ +#define USB_OTG_GUSBCFG_FDMOD_Pos (30U) +#define USB_OTG_GUSBCFG_FDMOD_Msk (0x1UL << USB_OTG_GUSBCFG_FDMOD_Pos) /*!< 0x40000000 */ +#define USB_OTG_GUSBCFG_FDMOD USB_OTG_GUSBCFG_FDMOD_Msk /*!< Forced peripheral mode */ +#define USB_OTG_GUSBCFG_CTXPKT_Pos (31U) +#define USB_OTG_GUSBCFG_CTXPKT_Msk (0x1UL << USB_OTG_GUSBCFG_CTXPKT_Pos) /*!< 0x80000000 */ +#define USB_OTG_GUSBCFG_CTXPKT USB_OTG_GUSBCFG_CTXPKT_Msk /*!< Corrupt Tx packet */ + +/******************** Bit definition for USB_OTG_GRSTCTL register ********************/ +#define USB_OTG_GRSTCTL_CSRST_Pos (0U) +#define USB_OTG_GRSTCTL_CSRST_Msk (0x1UL << USB_OTG_GRSTCTL_CSRST_Pos) /*!< 0x00000001 */ +#define USB_OTG_GRSTCTL_CSRST USB_OTG_GRSTCTL_CSRST_Msk /*!< Core soft reset */ +#define USB_OTG_GRSTCTL_HSRST_Pos (1U) +#define USB_OTG_GRSTCTL_HSRST_Msk (0x1UL << USB_OTG_GRSTCTL_HSRST_Pos) /*!< 0x00000002 */ +#define USB_OTG_GRSTCTL_HSRST USB_OTG_GRSTCTL_HSRST_Msk /*!< HCLK soft reset */ +#define USB_OTG_GRSTCTL_FCRST_Pos (2U) +#define USB_OTG_GRSTCTL_FCRST_Msk (0x1UL << USB_OTG_GRSTCTL_FCRST_Pos) /*!< 0x00000004 */ +#define USB_OTG_GRSTCTL_FCRST USB_OTG_GRSTCTL_FCRST_Msk /*!< Host frame counter reset */ +#define USB_OTG_GRSTCTL_RXFFLSH_Pos (4U) +#define USB_OTG_GRSTCTL_RXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_RXFFLSH_Pos) /*!< 0x00000010 */ +#define USB_OTG_GRSTCTL_RXFFLSH USB_OTG_GRSTCTL_RXFFLSH_Msk /*!< RxFIFO flush */ +#define USB_OTG_GRSTCTL_TXFFLSH_Pos (5U) +#define USB_OTG_GRSTCTL_TXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_TXFFLSH_Pos) /*!< 0x00000020 */ +#define USB_OTG_GRSTCTL_TXFFLSH USB_OTG_GRSTCTL_TXFFLSH_Msk /*!< TxFIFO flush */ + + +#define USB_OTG_GRSTCTL_TXFNUM_Pos (6U) +#define USB_OTG_GRSTCTL_TXFNUM_Msk (0x1FUL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x000007C0 */ +#define USB_OTG_GRSTCTL_TXFNUM USB_OTG_GRSTCTL_TXFNUM_Msk /*!< TxFIFO number */ +#define USB_OTG_GRSTCTL_TXFNUM_0 (0x01UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000040 */ +#define USB_OTG_GRSTCTL_TXFNUM_1 (0x02UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000080 */ +#define USB_OTG_GRSTCTL_TXFNUM_2 (0x04UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000100 */ +#define USB_OTG_GRSTCTL_TXFNUM_3 (0x08UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000200 */ +#define USB_OTG_GRSTCTL_TXFNUM_4 (0x10UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000400 */ +#define USB_OTG_GRSTCTL_DMAREQ_Pos (30U) +#define USB_OTG_GRSTCTL_DMAREQ_Msk (0x1UL << USB_OTG_GRSTCTL_DMAREQ_Pos) /*!< 0x40000000 */ +#define USB_OTG_GRSTCTL_DMAREQ USB_OTG_GRSTCTL_DMAREQ_Msk /*!< DMA request signal */ +#define USB_OTG_GRSTCTL_AHBIDL_Pos (31U) +#define USB_OTG_GRSTCTL_AHBIDL_Msk (0x1UL << USB_OTG_GRSTCTL_AHBIDL_Pos) /*!< 0x80000000 */ +#define USB_OTG_GRSTCTL_AHBIDL USB_OTG_GRSTCTL_AHBIDL_Msk /*!< AHB master idle */ + +/******************** Bit definition for USB_OTG_DIEPMSK register ********************/ +#define USB_OTG_DIEPMSK_XFRCM_Pos (0U) +#define USB_OTG_DIEPMSK_XFRCM_Msk (0x1UL << USB_OTG_DIEPMSK_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_DIEPMSK_XFRCM USB_OTG_DIEPMSK_XFRCM_Msk /*!< Transfer completed interrupt mask */ +#define USB_OTG_DIEPMSK_EPDM_Pos (1U) +#define USB_OTG_DIEPMSK_EPDM_Msk (0x1UL << USB_OTG_DIEPMSK_EPDM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DIEPMSK_EPDM USB_OTG_DIEPMSK_EPDM_Msk /*!< Endpoint disabled interrupt mask */ +#define USB_OTG_DIEPMSK_TOM_Pos (3U) +#define USB_OTG_DIEPMSK_TOM_Msk (0x1UL << USB_OTG_DIEPMSK_TOM_Pos) /*!< 0x00000008 */ +#define USB_OTG_DIEPMSK_TOM USB_OTG_DIEPMSK_TOM_Msk /*!< Timeout condition mask (nonisochronous endpoints) */ +#define USB_OTG_DIEPMSK_ITTXFEMSK_Pos (4U) +#define USB_OTG_DIEPMSK_ITTXFEMSK_Msk (0x1UL << USB_OTG_DIEPMSK_ITTXFEMSK_Pos) /*!< 0x00000010 */ +#define USB_OTG_DIEPMSK_ITTXFEMSK USB_OTG_DIEPMSK_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ +#define USB_OTG_DIEPMSK_INEPNMM_Pos (5U) +#define USB_OTG_DIEPMSK_INEPNMM_Msk (0x1UL << USB_OTG_DIEPMSK_INEPNMM_Pos) /*!< 0x00000020 */ +#define USB_OTG_DIEPMSK_INEPNMM USB_OTG_DIEPMSK_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ +#define USB_OTG_DIEPMSK_INEPNEM_Pos (6U) +#define USB_OTG_DIEPMSK_INEPNEM_Msk (0x1UL << USB_OTG_DIEPMSK_INEPNEM_Pos) /*!< 0x00000040 */ +#define USB_OTG_DIEPMSK_INEPNEM USB_OTG_DIEPMSK_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ +#define USB_OTG_DIEPMSK_TXFURM_Pos (8U) +#define USB_OTG_DIEPMSK_TXFURM_Msk (0x1UL << USB_OTG_DIEPMSK_TXFURM_Pos) /*!< 0x00000100 */ +#define USB_OTG_DIEPMSK_TXFURM USB_OTG_DIEPMSK_TXFURM_Msk /*!< FIFO underrun mask */ +#define USB_OTG_DIEPMSK_BIM_Pos (9U) +#define USB_OTG_DIEPMSK_BIM_Msk (0x1UL << USB_OTG_DIEPMSK_BIM_Pos) /*!< 0x00000200 */ +#define USB_OTG_DIEPMSK_BIM USB_OTG_DIEPMSK_BIM_Msk /*!< BNA interrupt mask */ + +/******************** Bit definition for USB_OTG_HPTXSTS register ********************/ +#define USB_OTG_HPTXSTS_PTXFSAVL_Pos (0U) +#define USB_OTG_HPTXSTS_PTXFSAVL_Msk (0xFFFFUL << USB_OTG_HPTXSTS_PTXFSAVL_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HPTXSTS_PTXFSAVL USB_OTG_HPTXSTS_PTXFSAVL_Msk /*!< Periodic transmit data FIFO space available */ +#define USB_OTG_HPTXSTS_PTXQSAV_Pos (16U) +#define USB_OTG_HPTXSTS_PTXQSAV_Msk (0xFFUL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00FF0000 */ +#define USB_OTG_HPTXSTS_PTXQSAV USB_OTG_HPTXSTS_PTXQSAV_Msk /*!< Periodic transmit request queue space available */ +#define USB_OTG_HPTXSTS_PTXQSAV_0 (0x01UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00010000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_1 (0x02UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00020000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_2 (0x04UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00040000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_3 (0x08UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00080000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_4 (0x10UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00100000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_5 (0x20UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00200000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_6 (0x40UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00400000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_7 (0x80UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00800000 */ + +#define USB_OTG_HPTXSTS_PTXQTOP_Pos (24U) +#define USB_OTG_HPTXSTS_PTXQTOP_Msk (0xFFUL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0xFF000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP USB_OTG_HPTXSTS_PTXQTOP_Msk /*!< Top of the periodic transmit request queue */ +#define USB_OTG_HPTXSTS_PTXQTOP_0 (0x01UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x01000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_1 (0x02UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x02000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_2 (0x04UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x04000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_3 (0x08UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x08000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_4 (0x10UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x10000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_5 (0x20UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x20000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_6 (0x40UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x40000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_7 (0x80UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x80000000 */ + +/******************** Bit definition for USB_OTG_HAINT register ********************/ +#define USB_OTG_HAINT_HAINT_Pos (0U) +#define USB_OTG_HAINT_HAINT_Msk (0xFFFFUL << USB_OTG_HAINT_HAINT_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HAINT_HAINT USB_OTG_HAINT_HAINT_Msk /*!< Channel interrupts */ + +/******************** Bit definition for USB_OTG_DOEPMSK register ********************/ +#define USB_OTG_DOEPMSK_XFRCM_Pos (0U) +#define USB_OTG_DOEPMSK_XFRCM_Msk (0x1UL << USB_OTG_DOEPMSK_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_DOEPMSK_XFRCM USB_OTG_DOEPMSK_XFRCM_Msk /*!< Transfer completed interrupt mask */ +#define USB_OTG_DOEPMSK_EPDM_Pos (1U) +#define USB_OTG_DOEPMSK_EPDM_Msk (0x1UL << USB_OTG_DOEPMSK_EPDM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DOEPMSK_EPDM USB_OTG_DOEPMSK_EPDM_Msk /*!< Endpoint disabled interrupt mask */ +#define USB_OTG_DOEPMSK_AHBERRM_Pos (2U) +#define USB_OTG_DOEPMSK_AHBERRM_Msk (0x1UL << USB_OTG_DOEPMSK_AHBERRM_Pos) /*!< 0x00000004 */ +#define USB_OTG_DOEPMSK_AHBERRM USB_OTG_DOEPMSK_AHBERRM_Msk /*!< OUT transaction AHB Error interrupt mask */ +#define USB_OTG_DOEPMSK_STUPM_Pos (3U) +#define USB_OTG_DOEPMSK_STUPM_Msk (0x1UL << USB_OTG_DOEPMSK_STUPM_Pos) /*!< 0x00000008 */ +#define USB_OTG_DOEPMSK_STUPM USB_OTG_DOEPMSK_STUPM_Msk /*!< SETUP phase done mask */ +#define USB_OTG_DOEPMSK_OTEPDM_Pos (4U) +#define USB_OTG_DOEPMSK_OTEPDM_Msk (0x1UL << USB_OTG_DOEPMSK_OTEPDM_Pos) /*!< 0x00000010 */ +#define USB_OTG_DOEPMSK_OTEPDM USB_OTG_DOEPMSK_OTEPDM_Msk /*!< OUT token received when endpoint disabled mask */ +#define USB_OTG_DOEPMSK_OTEPSPRM_Pos (5U) +#define USB_OTG_DOEPMSK_OTEPSPRM_Msk (0x1UL << USB_OTG_DOEPMSK_OTEPSPRM_Pos) /*!< 0x00000020 */ +#define USB_OTG_DOEPMSK_OTEPSPRM USB_OTG_DOEPMSK_OTEPSPRM_Msk /*!< Status Phase Received mask */ +#define USB_OTG_DOEPMSK_B2BSTUP_Pos (6U) +#define USB_OTG_DOEPMSK_B2BSTUP_Msk (0x1UL << USB_OTG_DOEPMSK_B2BSTUP_Pos) /*!< 0x00000040 */ +#define USB_OTG_DOEPMSK_B2BSTUP USB_OTG_DOEPMSK_B2BSTUP_Msk /*!< Back-to-back SETUP packets received mask */ +#define USB_OTG_DOEPMSK_OPEM_Pos (8U) +#define USB_OTG_DOEPMSK_OPEM_Msk (0x1UL << USB_OTG_DOEPMSK_OPEM_Pos) /*!< 0x00000100 */ +#define USB_OTG_DOEPMSK_OPEM USB_OTG_DOEPMSK_OPEM_Msk /*!< OUT packet error mask */ +#define USB_OTG_DOEPMSK_BOIM_Pos (9U) +#define USB_OTG_DOEPMSK_BOIM_Msk (0x1UL << USB_OTG_DOEPMSK_BOIM_Pos) /*!< 0x00000200 */ +#define USB_OTG_DOEPMSK_BOIM USB_OTG_DOEPMSK_BOIM_Msk /*!< BNA interrupt mask */ +#define USB_OTG_DOEPMSK_BERRM_Pos (12U) +#define USB_OTG_DOEPMSK_BERRM_Msk (0x1UL << USB_OTG_DOEPMSK_BERRM_Pos) /*!< 0x00001000 */ +#define USB_OTG_DOEPMSK_BERRM USB_OTG_DOEPMSK_BERRM_Msk /*!< Babble error interrupt mask */ +#define USB_OTG_DOEPMSK_NAKM_Pos (13U) +#define USB_OTG_DOEPMSK_NAKM_Msk (0x1UL << USB_OTG_DOEPMSK_NAKM_Pos) /*!< 0x00002000 */ +#define USB_OTG_DOEPMSK_NAKM USB_OTG_DOEPMSK_NAKM_Msk /*!< OUT Packet NAK interrupt mask */ +#define USB_OTG_DOEPMSK_NYETM_Pos (14U) +#define USB_OTG_DOEPMSK_NYETM_Msk (0x1UL << USB_OTG_DOEPMSK_NYETM_Pos) /*!< 0x00004000 */ +#define USB_OTG_DOEPMSK_NYETM USB_OTG_DOEPMSK_NYETM_Msk /*!< NYET interrupt mask */ +/******************** Bit definition for USB_OTG_GINTSTS register ********************/ +#define USB_OTG_GINTSTS_CMOD_Pos (0U) +#define USB_OTG_GINTSTS_CMOD_Msk (0x1UL << USB_OTG_GINTSTS_CMOD_Pos) /*!< 0x00000001 */ +#define USB_OTG_GINTSTS_CMOD USB_OTG_GINTSTS_CMOD_Msk /*!< Current mode of operation */ +#define USB_OTG_GINTSTS_MMIS_Pos (1U) +#define USB_OTG_GINTSTS_MMIS_Msk (0x1UL << USB_OTG_GINTSTS_MMIS_Pos) /*!< 0x00000002 */ +#define USB_OTG_GINTSTS_MMIS USB_OTG_GINTSTS_MMIS_Msk /*!< Mode mismatch interrupt */ +#define USB_OTG_GINTSTS_OTGINT_Pos (2U) +#define USB_OTG_GINTSTS_OTGINT_Msk (0x1UL << USB_OTG_GINTSTS_OTGINT_Pos) /*!< 0x00000004 */ +#define USB_OTG_GINTSTS_OTGINT USB_OTG_GINTSTS_OTGINT_Msk /*!< OTG interrupt */ +#define USB_OTG_GINTSTS_SOF_Pos (3U) +#define USB_OTG_GINTSTS_SOF_Msk (0x1UL << USB_OTG_GINTSTS_SOF_Pos) /*!< 0x00000008 */ +#define USB_OTG_GINTSTS_SOF USB_OTG_GINTSTS_SOF_Msk /*!< Start of frame */ +#define USB_OTG_GINTSTS_RXFLVL_Pos (4U) +#define USB_OTG_GINTSTS_RXFLVL_Msk (0x1UL << USB_OTG_GINTSTS_RXFLVL_Pos) /*!< 0x00000010 */ +#define USB_OTG_GINTSTS_RXFLVL USB_OTG_GINTSTS_RXFLVL_Msk /*!< RxFIFO nonempty */ +#define USB_OTG_GINTSTS_NPTXFE_Pos (5U) +#define USB_OTG_GINTSTS_NPTXFE_Msk (0x1UL << USB_OTG_GINTSTS_NPTXFE_Pos) /*!< 0x00000020 */ +#define USB_OTG_GINTSTS_NPTXFE USB_OTG_GINTSTS_NPTXFE_Msk /*!< Nonperiodic TxFIFO empty */ +#define USB_OTG_GINTSTS_GINAKEFF_Pos (6U) +#define USB_OTG_GINTSTS_GINAKEFF_Msk (0x1UL << USB_OTG_GINTSTS_GINAKEFF_Pos) /*!< 0x00000040 */ +#define USB_OTG_GINTSTS_GINAKEFF USB_OTG_GINTSTS_GINAKEFF_Msk /*!< Global IN nonperiodic NAK effective */ +#define USB_OTG_GINTSTS_BOUTNAKEFF_Pos (7U) +#define USB_OTG_GINTSTS_BOUTNAKEFF_Msk (0x1UL << USB_OTG_GINTSTS_BOUTNAKEFF_Pos) /*!< 0x00000080 */ +#define USB_OTG_GINTSTS_BOUTNAKEFF USB_OTG_GINTSTS_BOUTNAKEFF_Msk /*!< Global OUT NAK effective */ +#define USB_OTG_GINTSTS_ESUSP_Pos (10U) +#define USB_OTG_GINTSTS_ESUSP_Msk (0x1UL << USB_OTG_GINTSTS_ESUSP_Pos) /*!< 0x00000400 */ +#define USB_OTG_GINTSTS_ESUSP USB_OTG_GINTSTS_ESUSP_Msk /*!< Early suspend */ +#define USB_OTG_GINTSTS_USBSUSP_Pos (11U) +#define USB_OTG_GINTSTS_USBSUSP_Msk (0x1UL << USB_OTG_GINTSTS_USBSUSP_Pos) /*!< 0x00000800 */ +#define USB_OTG_GINTSTS_USBSUSP USB_OTG_GINTSTS_USBSUSP_Msk /*!< USB suspend */ +#define USB_OTG_GINTSTS_USBRST_Pos (12U) +#define USB_OTG_GINTSTS_USBRST_Msk (0x1UL << USB_OTG_GINTSTS_USBRST_Pos) /*!< 0x00001000 */ +#define USB_OTG_GINTSTS_USBRST USB_OTG_GINTSTS_USBRST_Msk /*!< USB reset */ +#define USB_OTG_GINTSTS_ENUMDNE_Pos (13U) +#define USB_OTG_GINTSTS_ENUMDNE_Msk (0x1UL << USB_OTG_GINTSTS_ENUMDNE_Pos) /*!< 0x00002000 */ +#define USB_OTG_GINTSTS_ENUMDNE USB_OTG_GINTSTS_ENUMDNE_Msk /*!< Enumeration done */ +#define USB_OTG_GINTSTS_ISOODRP_Pos (14U) +#define USB_OTG_GINTSTS_ISOODRP_Msk (0x1UL << USB_OTG_GINTSTS_ISOODRP_Pos) /*!< 0x00004000 */ +#define USB_OTG_GINTSTS_ISOODRP USB_OTG_GINTSTS_ISOODRP_Msk /*!< Isochronous OUT packet dropped interrupt */ +#define USB_OTG_GINTSTS_EOPF_Pos (15U) +#define USB_OTG_GINTSTS_EOPF_Msk (0x1UL << USB_OTG_GINTSTS_EOPF_Pos) /*!< 0x00008000 */ +#define USB_OTG_GINTSTS_EOPF USB_OTG_GINTSTS_EOPF_Msk /*!< End of periodic frame interrupt */ +#define USB_OTG_GINTSTS_IEPINT_Pos (18U) +#define USB_OTG_GINTSTS_IEPINT_Msk (0x1UL << USB_OTG_GINTSTS_IEPINT_Pos) /*!< 0x00040000 */ +#define USB_OTG_GINTSTS_IEPINT USB_OTG_GINTSTS_IEPINT_Msk /*!< IN endpoint interrupt */ +#define USB_OTG_GINTSTS_OEPINT_Pos (19U) +#define USB_OTG_GINTSTS_OEPINT_Msk (0x1UL << USB_OTG_GINTSTS_OEPINT_Pos) /*!< 0x00080000 */ +#define USB_OTG_GINTSTS_OEPINT USB_OTG_GINTSTS_OEPINT_Msk /*!< OUT endpoint interrupt */ +#define USB_OTG_GINTSTS_IISOIXFR_Pos (20U) +#define USB_OTG_GINTSTS_IISOIXFR_Msk (0x1UL << USB_OTG_GINTSTS_IISOIXFR_Pos) /*!< 0x00100000 */ +#define USB_OTG_GINTSTS_IISOIXFR USB_OTG_GINTSTS_IISOIXFR_Msk /*!< Incomplete isochronous IN transfer */ +#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos (21U) +#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk (0x1UL << USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos) /*!< 0x00200000 */ +#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk /*!< Incomplete periodic transfer */ +#define USB_OTG_GINTSTS_DATAFSUSP_Pos (22U) +#define USB_OTG_GINTSTS_DATAFSUSP_Msk (0x1UL << USB_OTG_GINTSTS_DATAFSUSP_Pos) /*!< 0x00400000 */ +#define USB_OTG_GINTSTS_DATAFSUSP USB_OTG_GINTSTS_DATAFSUSP_Msk /*!< Data fetch suspended */ +#define USB_OTG_GINTSTS_HPRTINT_Pos (24U) +#define USB_OTG_GINTSTS_HPRTINT_Msk (0x1UL << USB_OTG_GINTSTS_HPRTINT_Pos) /*!< 0x01000000 */ +#define USB_OTG_GINTSTS_HPRTINT USB_OTG_GINTSTS_HPRTINT_Msk /*!< Host port interrupt */ +#define USB_OTG_GINTSTS_HCINT_Pos (25U) +#define USB_OTG_GINTSTS_HCINT_Msk (0x1UL << USB_OTG_GINTSTS_HCINT_Pos) /*!< 0x02000000 */ +#define USB_OTG_GINTSTS_HCINT USB_OTG_GINTSTS_HCINT_Msk /*!< Host channels interrupt */ +#define USB_OTG_GINTSTS_PTXFE_Pos (26U) +#define USB_OTG_GINTSTS_PTXFE_Msk (0x1UL << USB_OTG_GINTSTS_PTXFE_Pos) /*!< 0x04000000 */ +#define USB_OTG_GINTSTS_PTXFE USB_OTG_GINTSTS_PTXFE_Msk /*!< Periodic TxFIFO empty */ +#define USB_OTG_GINTSTS_CIDSCHG_Pos (28U) +#define USB_OTG_GINTSTS_CIDSCHG_Msk (0x1UL << USB_OTG_GINTSTS_CIDSCHG_Pos) /*!< 0x10000000 */ +#define USB_OTG_GINTSTS_CIDSCHG USB_OTG_GINTSTS_CIDSCHG_Msk /*!< Connector ID status change */ +#define USB_OTG_GINTSTS_DISCINT_Pos (29U) +#define USB_OTG_GINTSTS_DISCINT_Msk (0x1UL << USB_OTG_GINTSTS_DISCINT_Pos) /*!< 0x20000000 */ +#define USB_OTG_GINTSTS_DISCINT USB_OTG_GINTSTS_DISCINT_Msk /*!< Disconnect detected interrupt */ +#define USB_OTG_GINTSTS_SRQINT_Pos (30U) +#define USB_OTG_GINTSTS_SRQINT_Msk (0x1UL << USB_OTG_GINTSTS_SRQINT_Pos) /*!< 0x40000000 */ +#define USB_OTG_GINTSTS_SRQINT USB_OTG_GINTSTS_SRQINT_Msk /*!< Session request/new session detected interrupt */ +#define USB_OTG_GINTSTS_WKUINT_Pos (31U) +#define USB_OTG_GINTSTS_WKUINT_Msk (0x1UL << USB_OTG_GINTSTS_WKUINT_Pos) /*!< 0x80000000 */ +#define USB_OTG_GINTSTS_WKUINT USB_OTG_GINTSTS_WKUINT_Msk /*!< Resume/remote wakeup detected interrupt */ + +/******************** Bit definition for USB_OTG_GINTMSK register ********************/ +#define USB_OTG_GINTMSK_MMISM_Pos (1U) +#define USB_OTG_GINTMSK_MMISM_Msk (0x1UL << USB_OTG_GINTMSK_MMISM_Pos) /*!< 0x00000002 */ +#define USB_OTG_GINTMSK_MMISM USB_OTG_GINTMSK_MMISM_Msk /*!< Mode mismatch interrupt mask */ +#define USB_OTG_GINTMSK_OTGINT_Pos (2U) +#define USB_OTG_GINTMSK_OTGINT_Msk (0x1UL << USB_OTG_GINTMSK_OTGINT_Pos) /*!< 0x00000004 */ +#define USB_OTG_GINTMSK_OTGINT USB_OTG_GINTMSK_OTGINT_Msk /*!< OTG interrupt mask */ +#define USB_OTG_GINTMSK_SOFM_Pos (3U) +#define USB_OTG_GINTMSK_SOFM_Msk (0x1UL << USB_OTG_GINTMSK_SOFM_Pos) /*!< 0x00000008 */ +#define USB_OTG_GINTMSK_SOFM USB_OTG_GINTMSK_SOFM_Msk /*!< Start of frame mask */ +#define USB_OTG_GINTMSK_RXFLVLM_Pos (4U) +#define USB_OTG_GINTMSK_RXFLVLM_Msk (0x1UL << USB_OTG_GINTMSK_RXFLVLM_Pos) /*!< 0x00000010 */ +#define USB_OTG_GINTMSK_RXFLVLM USB_OTG_GINTMSK_RXFLVLM_Msk /*!< Receive FIFO nonempty mask */ +#define USB_OTG_GINTMSK_NPTXFEM_Pos (5U) +#define USB_OTG_GINTMSK_NPTXFEM_Msk (0x1UL << USB_OTG_GINTMSK_NPTXFEM_Pos) /*!< 0x00000020 */ +#define USB_OTG_GINTMSK_NPTXFEM USB_OTG_GINTMSK_NPTXFEM_Msk /*!< Nonperiodic TxFIFO empty mask */ +#define USB_OTG_GINTMSK_GINAKEFFM_Pos (6U) +#define USB_OTG_GINTMSK_GINAKEFFM_Msk (0x1UL << USB_OTG_GINTMSK_GINAKEFFM_Pos) /*!< 0x00000040 */ +#define USB_OTG_GINTMSK_GINAKEFFM USB_OTG_GINTMSK_GINAKEFFM_Msk /*!< Global nonperiodic IN NAK effective mask */ +#define USB_OTG_GINTMSK_GONAKEFFM_Pos (7U) +#define USB_OTG_GINTMSK_GONAKEFFM_Msk (0x1UL << USB_OTG_GINTMSK_GONAKEFFM_Pos) /*!< 0x00000080 */ +#define USB_OTG_GINTMSK_GONAKEFFM USB_OTG_GINTMSK_GONAKEFFM_Msk /*!< Global OUT NAK effective mask */ +#define USB_OTG_GINTMSK_ESUSPM_Pos (10U) +#define USB_OTG_GINTMSK_ESUSPM_Msk (0x1UL << USB_OTG_GINTMSK_ESUSPM_Pos) /*!< 0x00000400 */ +#define USB_OTG_GINTMSK_ESUSPM USB_OTG_GINTMSK_ESUSPM_Msk /*!< Early suspend mask */ +#define USB_OTG_GINTMSK_USBSUSPM_Pos (11U) +#define USB_OTG_GINTMSK_USBSUSPM_Msk (0x1UL << USB_OTG_GINTMSK_USBSUSPM_Pos) /*!< 0x00000800 */ +#define USB_OTG_GINTMSK_USBSUSPM USB_OTG_GINTMSK_USBSUSPM_Msk /*!< USB suspend mask */ +#define USB_OTG_GINTMSK_USBRST_Pos (12U) +#define USB_OTG_GINTMSK_USBRST_Msk (0x1UL << USB_OTG_GINTMSK_USBRST_Pos) /*!< 0x00001000 */ +#define USB_OTG_GINTMSK_USBRST USB_OTG_GINTMSK_USBRST_Msk /*!< USB reset mask */ +#define USB_OTG_GINTMSK_ENUMDNEM_Pos (13U) +#define USB_OTG_GINTMSK_ENUMDNEM_Msk (0x1UL << USB_OTG_GINTMSK_ENUMDNEM_Pos) /*!< 0x00002000 */ +#define USB_OTG_GINTMSK_ENUMDNEM USB_OTG_GINTMSK_ENUMDNEM_Msk /*!< Enumeration done mask */ +#define USB_OTG_GINTMSK_ISOODRPM_Pos (14U) +#define USB_OTG_GINTMSK_ISOODRPM_Msk (0x1UL << USB_OTG_GINTMSK_ISOODRPM_Pos) /*!< 0x00004000 */ +#define USB_OTG_GINTMSK_ISOODRPM USB_OTG_GINTMSK_ISOODRPM_Msk /*!< Isochronous OUT packet dropped interrupt mask */ +#define USB_OTG_GINTMSK_EOPFM_Pos (15U) +#define USB_OTG_GINTMSK_EOPFM_Msk (0x1UL << USB_OTG_GINTMSK_EOPFM_Pos) /*!< 0x00008000 */ +#define USB_OTG_GINTMSK_EOPFM USB_OTG_GINTMSK_EOPFM_Msk /*!< End of periodic frame interrupt mask */ +#define USB_OTG_GINTMSK_EPMISM_Pos (17U) +#define USB_OTG_GINTMSK_EPMISM_Msk (0x1UL << USB_OTG_GINTMSK_EPMISM_Pos) /*!< 0x00020000 */ +#define USB_OTG_GINTMSK_EPMISM USB_OTG_GINTMSK_EPMISM_Msk /*!< Endpoint mismatch interrupt mask */ +#define USB_OTG_GINTMSK_IEPINT_Pos (18U) +#define USB_OTG_GINTMSK_IEPINT_Msk (0x1UL << USB_OTG_GINTMSK_IEPINT_Pos) /*!< 0x00040000 */ +#define USB_OTG_GINTMSK_IEPINT USB_OTG_GINTMSK_IEPINT_Msk /*!< IN endpoints interrupt mask */ +#define USB_OTG_GINTMSK_OEPINT_Pos (19U) +#define USB_OTG_GINTMSK_OEPINT_Msk (0x1UL << USB_OTG_GINTMSK_OEPINT_Pos) /*!< 0x00080000 */ +#define USB_OTG_GINTMSK_OEPINT USB_OTG_GINTMSK_OEPINT_Msk /*!< OUT endpoints interrupt mask */ +#define USB_OTG_GINTMSK_IISOIXFRM_Pos (20U) +#define USB_OTG_GINTMSK_IISOIXFRM_Msk (0x1UL << USB_OTG_GINTMSK_IISOIXFRM_Pos) /*!< 0x00100000 */ +#define USB_OTG_GINTMSK_IISOIXFRM USB_OTG_GINTMSK_IISOIXFRM_Msk /*!< Incomplete isochronous IN transfer mask */ +#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos (21U) +#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk (0x1UL << USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos) /*!< 0x00200000 */ +#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk /*!< Incomplete periodic transfer mask */ +#define USB_OTG_GINTMSK_FSUSPM_Pos (22U) +#define USB_OTG_GINTMSK_FSUSPM_Msk (0x1UL << USB_OTG_GINTMSK_FSUSPM_Pos) /*!< 0x00400000 */ +#define USB_OTG_GINTMSK_FSUSPM USB_OTG_GINTMSK_FSUSPM_Msk /*!< Data fetch suspended mask */ +#define USB_OTG_GINTMSK_PRTIM_Pos (24U) +#define USB_OTG_GINTMSK_PRTIM_Msk (0x1UL << USB_OTG_GINTMSK_PRTIM_Pos) /*!< 0x01000000 */ +#define USB_OTG_GINTMSK_PRTIM USB_OTG_GINTMSK_PRTIM_Msk /*!< Host port interrupt mask */ +#define USB_OTG_GINTMSK_HCIM_Pos (25U) +#define USB_OTG_GINTMSK_HCIM_Msk (0x1UL << USB_OTG_GINTMSK_HCIM_Pos) /*!< 0x02000000 */ +#define USB_OTG_GINTMSK_HCIM USB_OTG_GINTMSK_HCIM_Msk /*!< Host channels interrupt mask */ +#define USB_OTG_GINTMSK_PTXFEM_Pos (26U) +#define USB_OTG_GINTMSK_PTXFEM_Msk (0x1UL << USB_OTG_GINTMSK_PTXFEM_Pos) /*!< 0x04000000 */ +#define USB_OTG_GINTMSK_PTXFEM USB_OTG_GINTMSK_PTXFEM_Msk /*!< Periodic TxFIFO empty mask */ +#define USB_OTG_GINTMSK_CIDSCHGM_Pos (28U) +#define USB_OTG_GINTMSK_CIDSCHGM_Msk (0x1UL << USB_OTG_GINTMSK_CIDSCHGM_Pos) /*!< 0x10000000 */ +#define USB_OTG_GINTMSK_CIDSCHGM USB_OTG_GINTMSK_CIDSCHGM_Msk /*!< Connector ID status change mask */ +#define USB_OTG_GINTMSK_DISCINT_Pos (29U) +#define USB_OTG_GINTMSK_DISCINT_Msk (0x1UL << USB_OTG_GINTMSK_DISCINT_Pos) /*!< 0x20000000 */ +#define USB_OTG_GINTMSK_DISCINT USB_OTG_GINTMSK_DISCINT_Msk /*!< Disconnect detected interrupt mask */ +#define USB_OTG_GINTMSK_SRQIM_Pos (30U) +#define USB_OTG_GINTMSK_SRQIM_Msk (0x1UL << USB_OTG_GINTMSK_SRQIM_Pos) /*!< 0x40000000 */ +#define USB_OTG_GINTMSK_SRQIM USB_OTG_GINTMSK_SRQIM_Msk /*!< Session request/new session detected interrupt mask */ +#define USB_OTG_GINTMSK_WUIM_Pos (31U) +#define USB_OTG_GINTMSK_WUIM_Msk (0x1UL << USB_OTG_GINTMSK_WUIM_Pos) /*!< 0x80000000 */ +#define USB_OTG_GINTMSK_WUIM USB_OTG_GINTMSK_WUIM_Msk /*!< Resume/remote wakeup detected interrupt mask */ + +/******************** Bit definition for USB_OTG_DAINT register ********************/ +#define USB_OTG_DAINT_IEPINT_Pos (0U) +#define USB_OTG_DAINT_IEPINT_Msk (0xFFFFUL << USB_OTG_DAINT_IEPINT_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DAINT_IEPINT USB_OTG_DAINT_IEPINT_Msk /*!< IN endpoint interrupt bits */ +#define USB_OTG_DAINT_OEPINT_Pos (16U) +#define USB_OTG_DAINT_OEPINT_Msk (0xFFFFUL << USB_OTG_DAINT_OEPINT_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_DAINT_OEPINT USB_OTG_DAINT_OEPINT_Msk /*!< OUT endpoint interrupt bits */ + +/******************** Bit definition for USB_OTG_HAINTMSK register ********************/ +#define USB_OTG_HAINTMSK_HAINTM_Pos (0U) +#define USB_OTG_HAINTMSK_HAINTM_Msk (0xFFFFUL << USB_OTG_HAINTMSK_HAINTM_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HAINTMSK_HAINTM USB_OTG_HAINTMSK_HAINTM_Msk /*!< Channel interrupt mask */ + +/******************** Bit definition for USB_OTG_GRXSTSP register ********************/ +#define USB_OTG_GRXSTSP_EPNUM_Pos (0U) +#define USB_OTG_GRXSTSP_EPNUM_Msk (0xFUL << USB_OTG_GRXSTSP_EPNUM_Pos) /*!< 0x0000000F */ +#define USB_OTG_GRXSTSP_EPNUM USB_OTG_GRXSTSP_EPNUM_Msk /*!< IN EP interrupt mask bits */ +#define USB_OTG_GRXSTSP_BCNT_Pos (4U) +#define USB_OTG_GRXSTSP_BCNT_Msk (0x7FFUL << USB_OTG_GRXSTSP_BCNT_Pos) /*!< 0x00007FF0 */ +#define USB_OTG_GRXSTSP_BCNT USB_OTG_GRXSTSP_BCNT_Msk /*!< OUT EP interrupt mask bits */ +#define USB_OTG_GRXSTSP_DPID_Pos (15U) +#define USB_OTG_GRXSTSP_DPID_Msk (0x3UL << USB_OTG_GRXSTSP_DPID_Pos) /*!< 0x00018000 */ +#define USB_OTG_GRXSTSP_DPID USB_OTG_GRXSTSP_DPID_Msk /*!< OUT EP interrupt mask bits */ +#define USB_OTG_GRXSTSP_PKTSTS_Pos (17U) +#define USB_OTG_GRXSTSP_PKTSTS_Msk (0xFUL << USB_OTG_GRXSTSP_PKTSTS_Pos) /*!< 0x001E0000 */ +#define USB_OTG_GRXSTSP_PKTSTS USB_OTG_GRXSTSP_PKTSTS_Msk /*!< OUT EP interrupt mask bits */ + +/******************** Bit definition for USB_OTG_DAINTMSK register ********************/ +#define USB_OTG_DAINTMSK_IEPM_Pos (0U) +#define USB_OTG_DAINTMSK_IEPM_Msk (0xFFFFUL << USB_OTG_DAINTMSK_IEPM_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DAINTMSK_IEPM USB_OTG_DAINTMSK_IEPM_Msk /*!< IN EP interrupt mask bits */ +#define USB_OTG_DAINTMSK_OEPM_Pos (16U) +#define USB_OTG_DAINTMSK_OEPM_Msk (0xFFFFUL << USB_OTG_DAINTMSK_OEPM_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_DAINTMSK_OEPM USB_OTG_DAINTMSK_OEPM_Msk /*!< OUT EP interrupt mask bits */ + +/******************** Bit definition for USB_OTG_GRXFSIZ register ********************/ +#define USB_OTG_GRXFSIZ_RXFD_Pos (0U) +#define USB_OTG_GRXFSIZ_RXFD_Msk (0xFFFFUL << USB_OTG_GRXFSIZ_RXFD_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_GRXFSIZ_RXFD USB_OTG_GRXFSIZ_RXFD_Msk /*!< RxFIFO depth */ + +/******************** Bit definition for USB_OTG_DVBUSDIS register ********************/ +#define USB_OTG_DVBUSDIS_VBUSDT_Pos (0U) +#define USB_OTG_DVBUSDIS_VBUSDT_Msk (0xFFFFUL << USB_OTG_DVBUSDIS_VBUSDT_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DVBUSDIS_VBUSDT USB_OTG_DVBUSDIS_VBUSDT_Msk /*!< Device VBUS discharge time */ + +/******************** Bit definition for OTG register ********************/ +#define USB_OTG_NPTXFSA_Pos (0U) +#define USB_OTG_NPTXFSA_Msk (0xFFFFUL << USB_OTG_NPTXFSA_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_NPTXFSA USB_OTG_NPTXFSA_Msk /*!< Nonperiodic transmit RAM start address */ +#define USB_OTG_NPTXFD_Pos (16U) +#define USB_OTG_NPTXFD_Msk (0xFFFFUL << USB_OTG_NPTXFD_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_NPTXFD USB_OTG_NPTXFD_Msk /*!< Nonperiodic TxFIFO depth */ +#define USB_OTG_TX0FSA_Pos (0U) +#define USB_OTG_TX0FSA_Msk (0xFFFFUL << USB_OTG_TX0FSA_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_TX0FSA USB_OTG_TX0FSA_Msk /*!< Endpoint 0 transmit RAM start address */ +#define USB_OTG_TX0FD_Pos (16U) +#define USB_OTG_TX0FD_Msk (0xFFFFUL << USB_OTG_TX0FD_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_TX0FD USB_OTG_TX0FD_Msk /*!< Endpoint 0 TxFIFO depth */ + +/******************** Bit definition for USB_OTG_DVBUSPULSE register ********************/ +#define USB_OTG_DVBUSPULSE_DVBUSP_Pos (0U) +#define USB_OTG_DVBUSPULSE_DVBUSP_Msk (0xFFFUL << USB_OTG_DVBUSPULSE_DVBUSP_Pos) /*!< 0x00000FFF */ +#define USB_OTG_DVBUSPULSE_DVBUSP USB_OTG_DVBUSPULSE_DVBUSP_Msk /*!< Device VBUS pulsing time */ + +/******************** Bit definition for USB_OTG_GNPTXSTS register ********************/ +#define USB_OTG_GNPTXSTS_NPTXFSAV_Pos (0U) +#define USB_OTG_GNPTXSTS_NPTXFSAV_Msk (0xFFFFUL << USB_OTG_GNPTXSTS_NPTXFSAV_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_GNPTXSTS_NPTXFSAV USB_OTG_GNPTXSTS_NPTXFSAV_Msk /*!< Nonperiodic TxFIFO space available */ + +#define USB_OTG_GNPTXSTS_NPTQXSAV_Pos (16U) +#define USB_OTG_GNPTXSTS_NPTQXSAV_Msk (0xFFUL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00FF0000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV USB_OTG_GNPTXSTS_NPTQXSAV_Msk /*!< Nonperiodic transmit request queue space available */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_0 (0x01UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00010000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_1 (0x02UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00020000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_2 (0x04UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00040000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_3 (0x08UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00080000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_4 (0x10UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00100000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_5 (0x20UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00200000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_6 (0x40UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00400000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_7 (0x80UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00800000 */ + +#define USB_OTG_GNPTXSTS_NPTXQTOP_Pos (24U) +#define USB_OTG_GNPTXSTS_NPTXQTOP_Msk (0x7FUL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x7F000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP USB_OTG_GNPTXSTS_NPTXQTOP_Msk /*!< Top of the nonperiodic transmit request queue */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_0 (0x01UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x01000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_1 (0x02UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x02000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_2 (0x04UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x04000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_3 (0x08UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x08000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_4 (0x10UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x10000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_5 (0x20UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x20000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_6 (0x40UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for USB_OTG_DTHRCTL register ********************/ +#define USB_OTG_DTHRCTL_NONISOTHREN_Pos (0U) +#define USB_OTG_DTHRCTL_NONISOTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_NONISOTHREN_Pos) /*!< 0x00000001 */ +#define USB_OTG_DTHRCTL_NONISOTHREN USB_OTG_DTHRCTL_NONISOTHREN_Msk /*!< Nonisochronous IN endpoints threshold enable */ +#define USB_OTG_DTHRCTL_ISOTHREN_Pos (1U) +#define USB_OTG_DTHRCTL_ISOTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_ISOTHREN_Pos) /*!< 0x00000002 */ +#define USB_OTG_DTHRCTL_ISOTHREN USB_OTG_DTHRCTL_ISOTHREN_Msk /*!< ISO IN endpoint threshold enable */ + +#define USB_OTG_DTHRCTL_TXTHRLEN_Pos (2U) +#define USB_OTG_DTHRCTL_TXTHRLEN_Msk (0x1FFUL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x000007FC */ +#define USB_OTG_DTHRCTL_TXTHRLEN USB_OTG_DTHRCTL_TXTHRLEN_Msk /*!< Transmit threshold length */ +#define USB_OTG_DTHRCTL_TXTHRLEN_0 (0x001UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000004 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_1 (0x002UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000008 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_2 (0x004UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000010 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_3 (0x008UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000020 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_4 (0x010UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000040 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_5 (0x020UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000080 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_6 (0x040UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000100 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_7 (0x080UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000200 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_8 (0x100UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000400 */ +#define USB_OTG_DTHRCTL_RXTHREN_Pos (16U) +#define USB_OTG_DTHRCTL_RXTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_RXTHREN_Pos) /*!< 0x00010000 */ +#define USB_OTG_DTHRCTL_RXTHREN USB_OTG_DTHRCTL_RXTHREN_Msk /*!< Receive threshold enable */ + +#define USB_OTG_DTHRCTL_RXTHRLEN_Pos (17U) +#define USB_OTG_DTHRCTL_RXTHRLEN_Msk (0x1FFUL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x03FE0000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN USB_OTG_DTHRCTL_RXTHRLEN_Msk /*!< Receive threshold length */ +#define USB_OTG_DTHRCTL_RXTHRLEN_0 (0x001UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00020000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_1 (0x002UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00040000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_2 (0x004UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00080000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_3 (0x008UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00100000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_4 (0x010UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00200000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_5 (0x020UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00400000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_6 (0x040UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00800000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_7 (0x080UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x01000000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_8 (0x100UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x02000000 */ +#define USB_OTG_DTHRCTL_ARPEN_Pos (27U) +#define USB_OTG_DTHRCTL_ARPEN_Msk (0x1UL << USB_OTG_DTHRCTL_ARPEN_Pos) /*!< 0x08000000 */ +#define USB_OTG_DTHRCTL_ARPEN USB_OTG_DTHRCTL_ARPEN_Msk /*!< Arbiter parking enable */ + +/******************** Bit definition for USB_OTG_DIEPEMPMSK register ********************/ +#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos (0U) +#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk (0xFFFFUL << USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DIEPEMPMSK_INEPTXFEM USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk /*!< IN EP Tx FIFO empty interrupt mask bits */ + +/******************** Bit definition for USB_OTG_DEACHINT register ********************/ +#define USB_OTG_DEACHINT_IEP1INT_Pos (1U) +#define USB_OTG_DEACHINT_IEP1INT_Msk (0x1UL << USB_OTG_DEACHINT_IEP1INT_Pos) /*!< 0x00000002 */ +#define USB_OTG_DEACHINT_IEP1INT USB_OTG_DEACHINT_IEP1INT_Msk /*!< IN endpoint 1interrupt bit */ +#define USB_OTG_DEACHINT_OEP1INT_Pos (17U) +#define USB_OTG_DEACHINT_OEP1INT_Msk (0x1UL << USB_OTG_DEACHINT_OEP1INT_Pos) /*!< 0x00020000 */ +#define USB_OTG_DEACHINT_OEP1INT USB_OTG_DEACHINT_OEP1INT_Msk /*!< OUT endpoint 1 interrupt bit */ + +/******************** Bit definition for USB_OTG_GCCFG register ********************/ +#define USB_OTG_GCCFG_PWRDWN_Pos (16U) +#define USB_OTG_GCCFG_PWRDWN_Msk (0x1UL << USB_OTG_GCCFG_PWRDWN_Pos) /*!< 0x00010000 */ +#define USB_OTG_GCCFG_PWRDWN USB_OTG_GCCFG_PWRDWN_Msk /*!< Power down */ +#define USB_OTG_GCCFG_VBUSASEN_Pos (18U) +#define USB_OTG_GCCFG_VBUSASEN_Msk (0x1UL << USB_OTG_GCCFG_VBUSASEN_Pos) /*!< 0x00040000 */ +#define USB_OTG_GCCFG_VBUSASEN USB_OTG_GCCFG_VBUSASEN_Msk /*!< Enable the VBUS sensing device */ +#define USB_OTG_GCCFG_VBUSBSEN_Pos (19U) +#define USB_OTG_GCCFG_VBUSBSEN_Msk (0x1UL << USB_OTG_GCCFG_VBUSBSEN_Pos) /*!< 0x00080000 */ +#define USB_OTG_GCCFG_VBUSBSEN USB_OTG_GCCFG_VBUSBSEN_Msk /*!< Enable the VBUS sensing device */ +#define USB_OTG_GCCFG_SOFOUTEN_Pos (20U) +#define USB_OTG_GCCFG_SOFOUTEN_Msk (0x1UL << USB_OTG_GCCFG_SOFOUTEN_Pos) /*!< 0x00100000 */ +#define USB_OTG_GCCFG_SOFOUTEN USB_OTG_GCCFG_SOFOUTEN_Msk /*!< SOF output enable */ + +/******************** Bit definition for USB_OTG_DEACHINTMSK register ********************/ +#define USB_OTG_DEACHINTMSK_IEP1INTM_Pos (1U) +#define USB_OTG_DEACHINTMSK_IEP1INTM_Msk (0x1UL << USB_OTG_DEACHINTMSK_IEP1INTM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DEACHINTMSK_IEP1INTM USB_OTG_DEACHINTMSK_IEP1INTM_Msk /*!< IN Endpoint 1 interrupt mask bit */ +#define USB_OTG_DEACHINTMSK_OEP1INTM_Pos (17U) +#define USB_OTG_DEACHINTMSK_OEP1INTM_Msk (0x1UL << USB_OTG_DEACHINTMSK_OEP1INTM_Pos) /*!< 0x00020000 */ +#define USB_OTG_DEACHINTMSK_OEP1INTM USB_OTG_DEACHINTMSK_OEP1INTM_Msk /*!< OUT Endpoint 1 interrupt mask bit */ + +/******************** Bit definition for USB_OTG_CID register ********************/ +#define USB_OTG_CID_PRODUCT_ID_Pos (0U) +#define USB_OTG_CID_PRODUCT_ID_Msk (0xFFFFFFFFUL << USB_OTG_CID_PRODUCT_ID_Pos) /*!< 0xFFFFFFFF */ +#define USB_OTG_CID_PRODUCT_ID USB_OTG_CID_PRODUCT_ID_Msk /*!< Product ID field */ + +/******************** Bit definition for USB_OTG_DIEPEACHMSK1 register ********************/ +#define USB_OTG_DIEPEACHMSK1_XFRCM_Pos (0U) +#define USB_OTG_DIEPEACHMSK1_XFRCM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_DIEPEACHMSK1_XFRCM USB_OTG_DIEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */ +#define USB_OTG_DIEPEACHMSK1_EPDM_Pos (1U) +#define USB_OTG_DIEPEACHMSK1_EPDM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DIEPEACHMSK1_EPDM USB_OTG_DIEPEACHMSK1_EPDM_Msk /*!< Endpoint disabled interrupt mask */ +#define USB_OTG_DIEPEACHMSK1_TOM_Pos (3U) +#define USB_OTG_DIEPEACHMSK1_TOM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */ +#define USB_OTG_DIEPEACHMSK1_TOM USB_OTG_DIEPEACHMSK1_TOM_Msk /*!< Timeout condition mask (nonisochronous endpoints) */ +#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos (4U) +#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */ +#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ +#define USB_OTG_DIEPEACHMSK1_INEPNMM_Pos (5U) +#define USB_OTG_DIEPEACHMSK1_INEPNMM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */ +#define USB_OTG_DIEPEACHMSK1_INEPNMM USB_OTG_DIEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ +#define USB_OTG_DIEPEACHMSK1_INEPNEM_Pos (6U) +#define USB_OTG_DIEPEACHMSK1_INEPNEM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */ +#define USB_OTG_DIEPEACHMSK1_INEPNEM USB_OTG_DIEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ +#define USB_OTG_DIEPEACHMSK1_TXFURM_Pos (8U) +#define USB_OTG_DIEPEACHMSK1_TXFURM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */ +#define USB_OTG_DIEPEACHMSK1_TXFURM USB_OTG_DIEPEACHMSK1_TXFURM_Msk /*!< FIFO underrun mask */ +#define USB_OTG_DIEPEACHMSK1_BIM_Pos (9U) +#define USB_OTG_DIEPEACHMSK1_BIM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */ +#define USB_OTG_DIEPEACHMSK1_BIM USB_OTG_DIEPEACHMSK1_BIM_Msk /*!< BNA interrupt mask */ +#define USB_OTG_DIEPEACHMSK1_NAKM_Pos (13U) +#define USB_OTG_DIEPEACHMSK1_NAKM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */ +#define USB_OTG_DIEPEACHMSK1_NAKM USB_OTG_DIEPEACHMSK1_NAKM_Msk /*!< NAK interrupt mask */ + +/******************** Bit definition for USB_OTG_HPRT register ********************/ +#define USB_OTG_HPRT_PCSTS_Pos (0U) +#define USB_OTG_HPRT_PCSTS_Msk (0x1UL << USB_OTG_HPRT_PCSTS_Pos) /*!< 0x00000001 */ +#define USB_OTG_HPRT_PCSTS USB_OTG_HPRT_PCSTS_Msk /*!< Port connect status */ +#define USB_OTG_HPRT_PCDET_Pos (1U) +#define USB_OTG_HPRT_PCDET_Msk (0x1UL << USB_OTG_HPRT_PCDET_Pos) /*!< 0x00000002 */ +#define USB_OTG_HPRT_PCDET USB_OTG_HPRT_PCDET_Msk /*!< Port connect detected */ +#define USB_OTG_HPRT_PENA_Pos (2U) +#define USB_OTG_HPRT_PENA_Msk (0x1UL << USB_OTG_HPRT_PENA_Pos) /*!< 0x00000004 */ +#define USB_OTG_HPRT_PENA USB_OTG_HPRT_PENA_Msk /*!< Port enable */ +#define USB_OTG_HPRT_PENCHNG_Pos (3U) +#define USB_OTG_HPRT_PENCHNG_Msk (0x1UL << USB_OTG_HPRT_PENCHNG_Pos) /*!< 0x00000008 */ +#define USB_OTG_HPRT_PENCHNG USB_OTG_HPRT_PENCHNG_Msk /*!< Port enable/disable change */ +#define USB_OTG_HPRT_POCA_Pos (4U) +#define USB_OTG_HPRT_POCA_Msk (0x1UL << USB_OTG_HPRT_POCA_Pos) /*!< 0x00000010 */ +#define USB_OTG_HPRT_POCA USB_OTG_HPRT_POCA_Msk /*!< Port overcurrent active */ +#define USB_OTG_HPRT_POCCHNG_Pos (5U) +#define USB_OTG_HPRT_POCCHNG_Msk (0x1UL << USB_OTG_HPRT_POCCHNG_Pos) /*!< 0x00000020 */ +#define USB_OTG_HPRT_POCCHNG USB_OTG_HPRT_POCCHNG_Msk /*!< Port overcurrent change */ +#define USB_OTG_HPRT_PRES_Pos (6U) +#define USB_OTG_HPRT_PRES_Msk (0x1UL << USB_OTG_HPRT_PRES_Pos) /*!< 0x00000040 */ +#define USB_OTG_HPRT_PRES USB_OTG_HPRT_PRES_Msk /*!< Port resume */ +#define USB_OTG_HPRT_PSUSP_Pos (7U) +#define USB_OTG_HPRT_PSUSP_Msk (0x1UL << USB_OTG_HPRT_PSUSP_Pos) /*!< 0x00000080 */ +#define USB_OTG_HPRT_PSUSP USB_OTG_HPRT_PSUSP_Msk /*!< Port suspend */ +#define USB_OTG_HPRT_PRST_Pos (8U) +#define USB_OTG_HPRT_PRST_Msk (0x1UL << USB_OTG_HPRT_PRST_Pos) /*!< 0x00000100 */ +#define USB_OTG_HPRT_PRST USB_OTG_HPRT_PRST_Msk /*!< Port reset */ + +#define USB_OTG_HPRT_PLSTS_Pos (10U) +#define USB_OTG_HPRT_PLSTS_Msk (0x3UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000C00 */ +#define USB_OTG_HPRT_PLSTS USB_OTG_HPRT_PLSTS_Msk /*!< Port line status */ +#define USB_OTG_HPRT_PLSTS_0 (0x1UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000400 */ +#define USB_OTG_HPRT_PLSTS_1 (0x2UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000800 */ +#define USB_OTG_HPRT_PPWR_Pos (12U) +#define USB_OTG_HPRT_PPWR_Msk (0x1UL << USB_OTG_HPRT_PPWR_Pos) /*!< 0x00001000 */ +#define USB_OTG_HPRT_PPWR USB_OTG_HPRT_PPWR_Msk /*!< Port power */ + +#define USB_OTG_HPRT_PTCTL_Pos (13U) +#define USB_OTG_HPRT_PTCTL_Msk (0xFUL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x0001E000 */ +#define USB_OTG_HPRT_PTCTL USB_OTG_HPRT_PTCTL_Msk /*!< Port test control */ +#define USB_OTG_HPRT_PTCTL_0 (0x1UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00002000 */ +#define USB_OTG_HPRT_PTCTL_1 (0x2UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00004000 */ +#define USB_OTG_HPRT_PTCTL_2 (0x4UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00008000 */ +#define USB_OTG_HPRT_PTCTL_3 (0x8UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00010000 */ + +#define USB_OTG_HPRT_PSPD_Pos (17U) +#define USB_OTG_HPRT_PSPD_Msk (0x3UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00060000 */ +#define USB_OTG_HPRT_PSPD USB_OTG_HPRT_PSPD_Msk /*!< Port speed */ +#define USB_OTG_HPRT_PSPD_0 (0x1UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00020000 */ +#define USB_OTG_HPRT_PSPD_1 (0x2UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00040000 */ + +/******************** Bit definition for USB_OTG_DOEPEACHMSK1 register ********************/ +#define USB_OTG_DOEPEACHMSK1_XFRCM_Pos (0U) +#define USB_OTG_DOEPEACHMSK1_XFRCM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_DOEPEACHMSK1_XFRCM USB_OTG_DOEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_EPDM_Pos (1U) +#define USB_OTG_DOEPEACHMSK1_EPDM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DOEPEACHMSK1_EPDM USB_OTG_DOEPEACHMSK1_EPDM_Msk /*!< Endpoint disabled interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_TOM_Pos (3U) +#define USB_OTG_DOEPEACHMSK1_TOM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */ +#define USB_OTG_DOEPEACHMSK1_TOM USB_OTG_DOEPEACHMSK1_TOM_Msk /*!< Timeout condition mask */ +#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos (4U) +#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */ +#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ +#define USB_OTG_DOEPEACHMSK1_INEPNMM_Pos (5U) +#define USB_OTG_DOEPEACHMSK1_INEPNMM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */ +#define USB_OTG_DOEPEACHMSK1_INEPNMM USB_OTG_DOEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ +#define USB_OTG_DOEPEACHMSK1_INEPNEM_Pos (6U) +#define USB_OTG_DOEPEACHMSK1_INEPNEM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */ +#define USB_OTG_DOEPEACHMSK1_INEPNEM USB_OTG_DOEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ +#define USB_OTG_DOEPEACHMSK1_TXFURM_Pos (8U) +#define USB_OTG_DOEPEACHMSK1_TXFURM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */ +#define USB_OTG_DOEPEACHMSK1_TXFURM USB_OTG_DOEPEACHMSK1_TXFURM_Msk /*!< OUT packet error mask */ +#define USB_OTG_DOEPEACHMSK1_BIM_Pos (9U) +#define USB_OTG_DOEPEACHMSK1_BIM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */ +#define USB_OTG_DOEPEACHMSK1_BIM USB_OTG_DOEPEACHMSK1_BIM_Msk /*!< BNA interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_BERRM_Pos (12U) +#define USB_OTG_DOEPEACHMSK1_BERRM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_BERRM_Pos) /*!< 0x00001000 */ +#define USB_OTG_DOEPEACHMSK1_BERRM USB_OTG_DOEPEACHMSK1_BERRM_Msk /*!< Bubble error interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_NAKM_Pos (13U) +#define USB_OTG_DOEPEACHMSK1_NAKM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */ +#define USB_OTG_DOEPEACHMSK1_NAKM USB_OTG_DOEPEACHMSK1_NAKM_Msk /*!< NAK interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_NYETM_Pos (14U) +#define USB_OTG_DOEPEACHMSK1_NYETM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_NYETM_Pos) /*!< 0x00004000 */ +#define USB_OTG_DOEPEACHMSK1_NYETM USB_OTG_DOEPEACHMSK1_NYETM_Msk /*!< NYET interrupt mask */ + +/******************** Bit definition for USB_OTG_HPTXFSIZ register ********************/ +#define USB_OTG_HPTXFSIZ_PTXSA_Pos (0U) +#define USB_OTG_HPTXFSIZ_PTXSA_Msk (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXSA_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HPTXFSIZ_PTXSA USB_OTG_HPTXFSIZ_PTXSA_Msk /*!< Host periodic TxFIFO start address */ +#define USB_OTG_HPTXFSIZ_PTXFD_Pos (16U) +#define USB_OTG_HPTXFSIZ_PTXFD_Msk (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXFD_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_HPTXFSIZ_PTXFD USB_OTG_HPTXFSIZ_PTXFD_Msk /*!< Host periodic TxFIFO depth */ + +/******************** Bit definition for USB_OTG_DIEPCTL register ********************/ +#define USB_OTG_DIEPCTL_MPSIZ_Pos (0U) +#define USB_OTG_DIEPCTL_MPSIZ_Msk (0x7FFUL << USB_OTG_DIEPCTL_MPSIZ_Pos) /*!< 0x000007FF */ +#define USB_OTG_DIEPCTL_MPSIZ USB_OTG_DIEPCTL_MPSIZ_Msk /*!< Maximum packet size */ +#define USB_OTG_DIEPCTL_USBAEP_Pos (15U) +#define USB_OTG_DIEPCTL_USBAEP_Msk (0x1UL << USB_OTG_DIEPCTL_USBAEP_Pos) /*!< 0x00008000 */ +#define USB_OTG_DIEPCTL_USBAEP USB_OTG_DIEPCTL_USBAEP_Msk /*!< USB active endpoint */ +#define USB_OTG_DIEPCTL_EONUM_DPID_Pos (16U) +#define USB_OTG_DIEPCTL_EONUM_DPID_Msk (0x1UL << USB_OTG_DIEPCTL_EONUM_DPID_Pos) /*!< 0x00010000 */ +#define USB_OTG_DIEPCTL_EONUM_DPID USB_OTG_DIEPCTL_EONUM_DPID_Msk /*!< Even/odd frame */ +#define USB_OTG_DIEPCTL_NAKSTS_Pos (17U) +#define USB_OTG_DIEPCTL_NAKSTS_Msk (0x1UL << USB_OTG_DIEPCTL_NAKSTS_Pos) /*!< 0x00020000 */ +#define USB_OTG_DIEPCTL_NAKSTS USB_OTG_DIEPCTL_NAKSTS_Msk /*!< NAK status */ + +#define USB_OTG_DIEPCTL_EPTYP_Pos (18U) +#define USB_OTG_DIEPCTL_EPTYP_Msk (0x3UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x000C0000 */ +#define USB_OTG_DIEPCTL_EPTYP USB_OTG_DIEPCTL_EPTYP_Msk /*!< Endpoint type */ +#define USB_OTG_DIEPCTL_EPTYP_0 (0x1UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00040000 */ +#define USB_OTG_DIEPCTL_EPTYP_1 (0x2UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00080000 */ +#define USB_OTG_DIEPCTL_STALL_Pos (21U) +#define USB_OTG_DIEPCTL_STALL_Msk (0x1UL << USB_OTG_DIEPCTL_STALL_Pos) /*!< 0x00200000 */ +#define USB_OTG_DIEPCTL_STALL USB_OTG_DIEPCTL_STALL_Msk /*!< STALL handshake */ + +#define USB_OTG_DIEPCTL_TXFNUM_Pos (22U) +#define USB_OTG_DIEPCTL_TXFNUM_Msk (0xFUL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x03C00000 */ +#define USB_OTG_DIEPCTL_TXFNUM USB_OTG_DIEPCTL_TXFNUM_Msk /*!< TxFIFO number */ +#define USB_OTG_DIEPCTL_TXFNUM_0 (0x1UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00400000 */ +#define USB_OTG_DIEPCTL_TXFNUM_1 (0x2UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00800000 */ +#define USB_OTG_DIEPCTL_TXFNUM_2 (0x4UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x01000000 */ +#define USB_OTG_DIEPCTL_TXFNUM_3 (0x8UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x02000000 */ +#define USB_OTG_DIEPCTL_CNAK_Pos (26U) +#define USB_OTG_DIEPCTL_CNAK_Msk (0x1UL << USB_OTG_DIEPCTL_CNAK_Pos) /*!< 0x04000000 */ +#define USB_OTG_DIEPCTL_CNAK USB_OTG_DIEPCTL_CNAK_Msk /*!< Clear NAK */ +#define USB_OTG_DIEPCTL_SNAK_Pos (27U) +#define USB_OTG_DIEPCTL_SNAK_Msk (0x1UL << USB_OTG_DIEPCTL_SNAK_Pos) /*!< 0x08000000 */ +#define USB_OTG_DIEPCTL_SNAK USB_OTG_DIEPCTL_SNAK_Msk /*!< Set NAK */ +#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos (28U) +#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos) /*!< 0x10000000 */ +#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk /*!< Set DATA0 PID */ +#define USB_OTG_DIEPCTL_SODDFRM_Pos (29U) +#define USB_OTG_DIEPCTL_SODDFRM_Msk (0x1UL << USB_OTG_DIEPCTL_SODDFRM_Pos) /*!< 0x20000000 */ +#define USB_OTG_DIEPCTL_SODDFRM USB_OTG_DIEPCTL_SODDFRM_Msk /*!< Set odd frame */ +#define USB_OTG_DIEPCTL_EPDIS_Pos (30U) +#define USB_OTG_DIEPCTL_EPDIS_Msk (0x1UL << USB_OTG_DIEPCTL_EPDIS_Pos) /*!< 0x40000000 */ +#define USB_OTG_DIEPCTL_EPDIS USB_OTG_DIEPCTL_EPDIS_Msk /*!< Endpoint disable */ +#define USB_OTG_DIEPCTL_EPENA_Pos (31U) +#define USB_OTG_DIEPCTL_EPENA_Msk (0x1UL << USB_OTG_DIEPCTL_EPENA_Pos) /*!< 0x80000000 */ +#define USB_OTG_DIEPCTL_EPENA USB_OTG_DIEPCTL_EPENA_Msk /*!< Endpoint enable */ + +/******************** Bit definition for USB_OTG_HCCHAR register ********************/ +#define USB_OTG_HCCHAR_MPSIZ_Pos (0U) +#define USB_OTG_HCCHAR_MPSIZ_Msk (0x7FFUL << USB_OTG_HCCHAR_MPSIZ_Pos) /*!< 0x000007FF */ +#define USB_OTG_HCCHAR_MPSIZ USB_OTG_HCCHAR_MPSIZ_Msk /*!< Maximum packet size */ + +#define USB_OTG_HCCHAR_EPNUM_Pos (11U) +#define USB_OTG_HCCHAR_EPNUM_Msk (0xFUL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00007800 */ +#define USB_OTG_HCCHAR_EPNUM USB_OTG_HCCHAR_EPNUM_Msk /*!< Endpoint number */ +#define USB_OTG_HCCHAR_EPNUM_0 (0x1UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00000800 */ +#define USB_OTG_HCCHAR_EPNUM_1 (0x2UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00001000 */ +#define USB_OTG_HCCHAR_EPNUM_2 (0x4UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00002000 */ +#define USB_OTG_HCCHAR_EPNUM_3 (0x8UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00004000 */ +#define USB_OTG_HCCHAR_EPDIR_Pos (15U) +#define USB_OTG_HCCHAR_EPDIR_Msk (0x1UL << USB_OTG_HCCHAR_EPDIR_Pos) /*!< 0x00008000 */ +#define USB_OTG_HCCHAR_EPDIR USB_OTG_HCCHAR_EPDIR_Msk /*!< Endpoint direction */ +#define USB_OTG_HCCHAR_LSDEV_Pos (17U) +#define USB_OTG_HCCHAR_LSDEV_Msk (0x1UL << USB_OTG_HCCHAR_LSDEV_Pos) /*!< 0x00020000 */ +#define USB_OTG_HCCHAR_LSDEV USB_OTG_HCCHAR_LSDEV_Msk /*!< Low-speed device */ + +#define USB_OTG_HCCHAR_EPTYP_Pos (18U) +#define USB_OTG_HCCHAR_EPTYP_Msk (0x3UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x000C0000 */ +#define USB_OTG_HCCHAR_EPTYP USB_OTG_HCCHAR_EPTYP_Msk /*!< Endpoint type */ +#define USB_OTG_HCCHAR_EPTYP_0 (0x1UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00040000 */ +#define USB_OTG_HCCHAR_EPTYP_1 (0x2UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00080000 */ + +#define USB_OTG_HCCHAR_MC_Pos (20U) +#define USB_OTG_HCCHAR_MC_Msk (0x3UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00300000 */ +#define USB_OTG_HCCHAR_MC USB_OTG_HCCHAR_MC_Msk /*!< Multi Count (MC) / Error Count (EC) */ +#define USB_OTG_HCCHAR_MC_0 (0x1UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00100000 */ +#define USB_OTG_HCCHAR_MC_1 (0x2UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00200000 */ + +#define USB_OTG_HCCHAR_DAD_Pos (22U) +#define USB_OTG_HCCHAR_DAD_Msk (0x7FUL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x1FC00000 */ +#define USB_OTG_HCCHAR_DAD USB_OTG_HCCHAR_DAD_Msk /*!< Device address */ +#define USB_OTG_HCCHAR_DAD_0 (0x01UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00400000 */ +#define USB_OTG_HCCHAR_DAD_1 (0x02UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00800000 */ +#define USB_OTG_HCCHAR_DAD_2 (0x04UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x01000000 */ +#define USB_OTG_HCCHAR_DAD_3 (0x08UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x02000000 */ +#define USB_OTG_HCCHAR_DAD_4 (0x10UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x04000000 */ +#define USB_OTG_HCCHAR_DAD_5 (0x20UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x08000000 */ +#define USB_OTG_HCCHAR_DAD_6 (0x40UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x10000000 */ +#define USB_OTG_HCCHAR_ODDFRM_Pos (29U) +#define USB_OTG_HCCHAR_ODDFRM_Msk (0x1UL << USB_OTG_HCCHAR_ODDFRM_Pos) /*!< 0x20000000 */ +#define USB_OTG_HCCHAR_ODDFRM USB_OTG_HCCHAR_ODDFRM_Msk /*!< Odd frame */ +#define USB_OTG_HCCHAR_CHDIS_Pos (30U) +#define USB_OTG_HCCHAR_CHDIS_Msk (0x1UL << USB_OTG_HCCHAR_CHDIS_Pos) /*!< 0x40000000 */ +#define USB_OTG_HCCHAR_CHDIS USB_OTG_HCCHAR_CHDIS_Msk /*!< Channel disable */ +#define USB_OTG_HCCHAR_CHENA_Pos (31U) +#define USB_OTG_HCCHAR_CHENA_Msk (0x1UL << USB_OTG_HCCHAR_CHENA_Pos) /*!< 0x80000000 */ +#define USB_OTG_HCCHAR_CHENA USB_OTG_HCCHAR_CHENA_Msk /*!< Channel enable */ + +/******************** Bit definition for USB_OTG_HCSPLT register ********************/ + +#define USB_OTG_HCSPLT_PRTADDR_Pos (0U) +#define USB_OTG_HCSPLT_PRTADDR_Msk (0x7FUL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x0000007F */ +#define USB_OTG_HCSPLT_PRTADDR USB_OTG_HCSPLT_PRTADDR_Msk /*!< Port address */ +#define USB_OTG_HCSPLT_PRTADDR_0 (0x01UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000001 */ +#define USB_OTG_HCSPLT_PRTADDR_1 (0x02UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000002 */ +#define USB_OTG_HCSPLT_PRTADDR_2 (0x04UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000004 */ +#define USB_OTG_HCSPLT_PRTADDR_3 (0x08UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000008 */ +#define USB_OTG_HCSPLT_PRTADDR_4 (0x10UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000010 */ +#define USB_OTG_HCSPLT_PRTADDR_5 (0x20UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000020 */ +#define USB_OTG_HCSPLT_PRTADDR_6 (0x40UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000040 */ + +#define USB_OTG_HCSPLT_HUBADDR_Pos (7U) +#define USB_OTG_HCSPLT_HUBADDR_Msk (0x7FUL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00003F80 */ +#define USB_OTG_HCSPLT_HUBADDR USB_OTG_HCSPLT_HUBADDR_Msk /*!< Hub address */ +#define USB_OTG_HCSPLT_HUBADDR_0 (0x01UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000080 */ +#define USB_OTG_HCSPLT_HUBADDR_1 (0x02UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000100 */ +#define USB_OTG_HCSPLT_HUBADDR_2 (0x04UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000200 */ +#define USB_OTG_HCSPLT_HUBADDR_3 (0x08UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000400 */ +#define USB_OTG_HCSPLT_HUBADDR_4 (0x10UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000800 */ +#define USB_OTG_HCSPLT_HUBADDR_5 (0x20UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00001000 */ +#define USB_OTG_HCSPLT_HUBADDR_6 (0x40UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00002000 */ + +#define USB_OTG_HCSPLT_XACTPOS_Pos (14U) +#define USB_OTG_HCSPLT_XACTPOS_Msk (0x3UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x0000C000 */ +#define USB_OTG_HCSPLT_XACTPOS USB_OTG_HCSPLT_XACTPOS_Msk /*!< XACTPOS */ +#define USB_OTG_HCSPLT_XACTPOS_0 (0x1UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00004000 */ +#define USB_OTG_HCSPLT_XACTPOS_1 (0x2UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00008000 */ +#define USB_OTG_HCSPLT_COMPLSPLT_Pos (16U) +#define USB_OTG_HCSPLT_COMPLSPLT_Msk (0x1UL << USB_OTG_HCSPLT_COMPLSPLT_Pos) /*!< 0x00010000 */ +#define USB_OTG_HCSPLT_COMPLSPLT USB_OTG_HCSPLT_COMPLSPLT_Msk /*!< Do complete split */ +#define USB_OTG_HCSPLT_SPLITEN_Pos (31U) +#define USB_OTG_HCSPLT_SPLITEN_Msk (0x1UL << USB_OTG_HCSPLT_SPLITEN_Pos) /*!< 0x80000000 */ +#define USB_OTG_HCSPLT_SPLITEN USB_OTG_HCSPLT_SPLITEN_Msk /*!< Split enable */ + +/******************** Bit definition for USB_OTG_HCINT register ********************/ +#define USB_OTG_HCINT_XFRC_Pos (0U) +#define USB_OTG_HCINT_XFRC_Msk (0x1UL << USB_OTG_HCINT_XFRC_Pos) /*!< 0x00000001 */ +#define USB_OTG_HCINT_XFRC USB_OTG_HCINT_XFRC_Msk /*!< Transfer completed */ +#define USB_OTG_HCINT_CHH_Pos (1U) +#define USB_OTG_HCINT_CHH_Msk (0x1UL << USB_OTG_HCINT_CHH_Pos) /*!< 0x00000002 */ +#define USB_OTG_HCINT_CHH USB_OTG_HCINT_CHH_Msk /*!< Channel halted */ +#define USB_OTG_HCINT_AHBERR_Pos (2U) +#define USB_OTG_HCINT_AHBERR_Msk (0x1UL << USB_OTG_HCINT_AHBERR_Pos) /*!< 0x00000004 */ +#define USB_OTG_HCINT_AHBERR USB_OTG_HCINT_AHBERR_Msk /*!< AHB error */ +#define USB_OTG_HCINT_STALL_Pos (3U) +#define USB_OTG_HCINT_STALL_Msk (0x1UL << USB_OTG_HCINT_STALL_Pos) /*!< 0x00000008 */ +#define USB_OTG_HCINT_STALL USB_OTG_HCINT_STALL_Msk /*!< STALL response received interrupt */ +#define USB_OTG_HCINT_NAK_Pos (4U) +#define USB_OTG_HCINT_NAK_Msk (0x1UL << USB_OTG_HCINT_NAK_Pos) /*!< 0x00000010 */ +#define USB_OTG_HCINT_NAK USB_OTG_HCINT_NAK_Msk /*!< NAK response received interrupt */ +#define USB_OTG_HCINT_ACK_Pos (5U) +#define USB_OTG_HCINT_ACK_Msk (0x1UL << USB_OTG_HCINT_ACK_Pos) /*!< 0x00000020 */ +#define USB_OTG_HCINT_ACK USB_OTG_HCINT_ACK_Msk /*!< ACK response received/transmitted interrupt */ +#define USB_OTG_HCINT_NYET_Pos (6U) +#define USB_OTG_HCINT_NYET_Msk (0x1UL << USB_OTG_HCINT_NYET_Pos) /*!< 0x00000040 */ +#define USB_OTG_HCINT_NYET USB_OTG_HCINT_NYET_Msk /*!< Response received interrupt */ +#define USB_OTG_HCINT_TXERR_Pos (7U) +#define USB_OTG_HCINT_TXERR_Msk (0x1UL << USB_OTG_HCINT_TXERR_Pos) /*!< 0x00000080 */ +#define USB_OTG_HCINT_TXERR USB_OTG_HCINT_TXERR_Msk /*!< Transaction error */ +#define USB_OTG_HCINT_BBERR_Pos (8U) +#define USB_OTG_HCINT_BBERR_Msk (0x1UL << USB_OTG_HCINT_BBERR_Pos) /*!< 0x00000100 */ +#define USB_OTG_HCINT_BBERR USB_OTG_HCINT_BBERR_Msk /*!< Babble error */ +#define USB_OTG_HCINT_FRMOR_Pos (9U) +#define USB_OTG_HCINT_FRMOR_Msk (0x1UL << USB_OTG_HCINT_FRMOR_Pos) /*!< 0x00000200 */ +#define USB_OTG_HCINT_FRMOR USB_OTG_HCINT_FRMOR_Msk /*!< Frame overrun */ +#define USB_OTG_HCINT_DTERR_Pos (10U) +#define USB_OTG_HCINT_DTERR_Msk (0x1UL << USB_OTG_HCINT_DTERR_Pos) /*!< 0x00000400 */ +#define USB_OTG_HCINT_DTERR USB_OTG_HCINT_DTERR_Msk /*!< Data toggle error */ + +/******************** Bit definition for USB_OTG_DIEPINT register ********************/ +#define USB_OTG_DIEPINT_XFRC_Pos (0U) +#define USB_OTG_DIEPINT_XFRC_Msk (0x1UL << USB_OTG_DIEPINT_XFRC_Pos) /*!< 0x00000001 */ +#define USB_OTG_DIEPINT_XFRC USB_OTG_DIEPINT_XFRC_Msk /*!< Transfer completed interrupt */ +#define USB_OTG_DIEPINT_EPDISD_Pos (1U) +#define USB_OTG_DIEPINT_EPDISD_Msk (0x1UL << USB_OTG_DIEPINT_EPDISD_Pos) /*!< 0x00000002 */ +#define USB_OTG_DIEPINT_EPDISD USB_OTG_DIEPINT_EPDISD_Msk /*!< Endpoint disabled interrupt */ +#define USB_OTG_DIEPINT_AHBERR_Pos (2U) +#define USB_OTG_DIEPINT_AHBERR_Msk (0x1UL << USB_OTG_DIEPINT_AHBERR_Pos) /*!< 0x00000004 */ +#define USB_OTG_DIEPINT_AHBERR USB_OTG_DIEPINT_AHBERR_Msk /*!< AHB Error (AHBErr) during an IN transaction */ +#define USB_OTG_DIEPINT_TOC_Pos (3U) +#define USB_OTG_DIEPINT_TOC_Msk (0x1UL << USB_OTG_DIEPINT_TOC_Pos) /*!< 0x00000008 */ +#define USB_OTG_DIEPINT_TOC USB_OTG_DIEPINT_TOC_Msk /*!< Timeout condition */ +#define USB_OTG_DIEPINT_ITTXFE_Pos (4U) +#define USB_OTG_DIEPINT_ITTXFE_Msk (0x1UL << USB_OTG_DIEPINT_ITTXFE_Pos) /*!< 0x00000010 */ +#define USB_OTG_DIEPINT_ITTXFE USB_OTG_DIEPINT_ITTXFE_Msk /*!< IN token received when TxFIFO is empty */ +#define USB_OTG_DIEPINT_INEPNM_Pos (5U) +#define USB_OTG_DIEPINT_INEPNM_Msk (0x1UL << USB_OTG_DIEPINT_INEPNM_Pos) /*!< 0x00000004 */ +#define USB_OTG_DIEPINT_INEPNM USB_OTG_DIEPINT_INEPNM_Msk /*!< IN token received with EP mismatch */ +#define USB_OTG_DIEPINT_INEPNE_Pos (6U) +#define USB_OTG_DIEPINT_INEPNE_Msk (0x1UL << USB_OTG_DIEPINT_INEPNE_Pos) /*!< 0x00000040 */ +#define USB_OTG_DIEPINT_INEPNE USB_OTG_DIEPINT_INEPNE_Msk /*!< IN endpoint NAK effective */ +#define USB_OTG_DIEPINT_TXFE_Pos (7U) +#define USB_OTG_DIEPINT_TXFE_Msk (0x1UL << USB_OTG_DIEPINT_TXFE_Pos) /*!< 0x00000080 */ +#define USB_OTG_DIEPINT_TXFE USB_OTG_DIEPINT_TXFE_Msk /*!< Transmit FIFO empty */ +#define USB_OTG_DIEPINT_TXFIFOUDRN_Pos (8U) +#define USB_OTG_DIEPINT_TXFIFOUDRN_Msk (0x1UL << USB_OTG_DIEPINT_TXFIFOUDRN_Pos) /*!< 0x00000100 */ +#define USB_OTG_DIEPINT_TXFIFOUDRN USB_OTG_DIEPINT_TXFIFOUDRN_Msk /*!< Transmit Fifo Underrun */ +#define USB_OTG_DIEPINT_BNA_Pos (9U) +#define USB_OTG_DIEPINT_BNA_Msk (0x1UL << USB_OTG_DIEPINT_BNA_Pos) /*!< 0x00000200 */ +#define USB_OTG_DIEPINT_BNA USB_OTG_DIEPINT_BNA_Msk /*!< Buffer not available interrupt */ +#define USB_OTG_DIEPINT_PKTDRPSTS_Pos (11U) +#define USB_OTG_DIEPINT_PKTDRPSTS_Msk (0x1UL << USB_OTG_DIEPINT_PKTDRPSTS_Pos) /*!< 0x00000800 */ +#define USB_OTG_DIEPINT_PKTDRPSTS USB_OTG_DIEPINT_PKTDRPSTS_Msk /*!< Packet dropped status */ +#define USB_OTG_DIEPINT_BERR_Pos (12U) +#define USB_OTG_DIEPINT_BERR_Msk (0x1UL << USB_OTG_DIEPINT_BERR_Pos) /*!< 0x00001000 */ +#define USB_OTG_DIEPINT_BERR USB_OTG_DIEPINT_BERR_Msk /*!< Babble error interrupt */ +#define USB_OTG_DIEPINT_NAK_Pos (13U) +#define USB_OTG_DIEPINT_NAK_Msk (0x1UL << USB_OTG_DIEPINT_NAK_Pos) /*!< 0x00002000 */ +#define USB_OTG_DIEPINT_NAK USB_OTG_DIEPINT_NAK_Msk /*!< NAK interrupt */ + +/******************** Bit definition for USB_OTG_HCINTMSK register ********************/ +#define USB_OTG_HCINTMSK_XFRCM_Pos (0U) +#define USB_OTG_HCINTMSK_XFRCM_Msk (0x1UL << USB_OTG_HCINTMSK_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_HCINTMSK_XFRCM USB_OTG_HCINTMSK_XFRCM_Msk /*!< Transfer completed mask */ +#define USB_OTG_HCINTMSK_CHHM_Pos (1U) +#define USB_OTG_HCINTMSK_CHHM_Msk (0x1UL << USB_OTG_HCINTMSK_CHHM_Pos) /*!< 0x00000002 */ +#define USB_OTG_HCINTMSK_CHHM USB_OTG_HCINTMSK_CHHM_Msk /*!< Channel halted mask */ +#define USB_OTG_HCINTMSK_AHBERR_Pos (2U) +#define USB_OTG_HCINTMSK_AHBERR_Msk (0x1UL << USB_OTG_HCINTMSK_AHBERR_Pos) /*!< 0x00000004 */ +#define USB_OTG_HCINTMSK_AHBERR USB_OTG_HCINTMSK_AHBERR_Msk /*!< AHB error */ +#define USB_OTG_HCINTMSK_STALLM_Pos (3U) +#define USB_OTG_HCINTMSK_STALLM_Msk (0x1UL << USB_OTG_HCINTMSK_STALLM_Pos) /*!< 0x00000008 */ +#define USB_OTG_HCINTMSK_STALLM USB_OTG_HCINTMSK_STALLM_Msk /*!< STALL response received interrupt mask */ +#define USB_OTG_HCINTMSK_NAKM_Pos (4U) +#define USB_OTG_HCINTMSK_NAKM_Msk (0x1UL << USB_OTG_HCINTMSK_NAKM_Pos) /*!< 0x00000010 */ +#define USB_OTG_HCINTMSK_NAKM USB_OTG_HCINTMSK_NAKM_Msk /*!< NAK response received interrupt mask */ +#define USB_OTG_HCINTMSK_ACKM_Pos (5U) +#define USB_OTG_HCINTMSK_ACKM_Msk (0x1UL << USB_OTG_HCINTMSK_ACKM_Pos) /*!< 0x00000020 */ +#define USB_OTG_HCINTMSK_ACKM USB_OTG_HCINTMSK_ACKM_Msk /*!< ACK response received/transmitted interrupt mask */ +#define USB_OTG_HCINTMSK_NYET_Pos (6U) +#define USB_OTG_HCINTMSK_NYET_Msk (0x1UL << USB_OTG_HCINTMSK_NYET_Pos) /*!< 0x00000040 */ +#define USB_OTG_HCINTMSK_NYET USB_OTG_HCINTMSK_NYET_Msk /*!< response received interrupt mask */ +#define USB_OTG_HCINTMSK_TXERRM_Pos (7U) +#define USB_OTG_HCINTMSK_TXERRM_Msk (0x1UL << USB_OTG_HCINTMSK_TXERRM_Pos) /*!< 0x00000080 */ +#define USB_OTG_HCINTMSK_TXERRM USB_OTG_HCINTMSK_TXERRM_Msk /*!< Transaction error mask */ +#define USB_OTG_HCINTMSK_BBERRM_Pos (8U) +#define USB_OTG_HCINTMSK_BBERRM_Msk (0x1UL << USB_OTG_HCINTMSK_BBERRM_Pos) /*!< 0x00000100 */ +#define USB_OTG_HCINTMSK_BBERRM USB_OTG_HCINTMSK_BBERRM_Msk /*!< Babble error mask */ +#define USB_OTG_HCINTMSK_FRMORM_Pos (9U) +#define USB_OTG_HCINTMSK_FRMORM_Msk (0x1UL << USB_OTG_HCINTMSK_FRMORM_Pos) /*!< 0x00000200 */ +#define USB_OTG_HCINTMSK_FRMORM USB_OTG_HCINTMSK_FRMORM_Msk /*!< Frame overrun mask */ +#define USB_OTG_HCINTMSK_DTERRM_Pos (10U) +#define USB_OTG_HCINTMSK_DTERRM_Msk (0x1UL << USB_OTG_HCINTMSK_DTERRM_Pos) /*!< 0x00000400 */ +#define USB_OTG_HCINTMSK_DTERRM USB_OTG_HCINTMSK_DTERRM_Msk /*!< Data toggle error mask */ + +/******************** Bit definition for USB_OTG_DIEPTSIZ register ********************/ + +#define USB_OTG_DIEPTSIZ_XFRSIZ_Pos (0U) +#define USB_OTG_DIEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */ +#define USB_OTG_DIEPTSIZ_XFRSIZ USB_OTG_DIEPTSIZ_XFRSIZ_Msk /*!< Transfer size */ +#define USB_OTG_DIEPTSIZ_PKTCNT_Pos (19U) +#define USB_OTG_DIEPTSIZ_PKTCNT_Msk (0x3FFUL << USB_OTG_DIEPTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */ +#define USB_OTG_DIEPTSIZ_PKTCNT USB_OTG_DIEPTSIZ_PKTCNT_Msk /*!< Packet count */ +#define USB_OTG_DIEPTSIZ_MULCNT_Pos (29U) +#define USB_OTG_DIEPTSIZ_MULCNT_Msk (0x3UL << USB_OTG_DIEPTSIZ_MULCNT_Pos) /*!< 0x60000000 */ +#define USB_OTG_DIEPTSIZ_MULCNT USB_OTG_DIEPTSIZ_MULCNT_Msk /*!< Packet count */ +/******************** Bit definition for USB_OTG_HCTSIZ register ********************/ +#define USB_OTG_HCTSIZ_XFRSIZ_Pos (0U) +#define USB_OTG_HCTSIZ_XFRSIZ_Msk (0x7FFFFUL << USB_OTG_HCTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */ +#define USB_OTG_HCTSIZ_XFRSIZ USB_OTG_HCTSIZ_XFRSIZ_Msk /*!< Transfer size */ +#define USB_OTG_HCTSIZ_PKTCNT_Pos (19U) +#define USB_OTG_HCTSIZ_PKTCNT_Msk (0x3FFUL << USB_OTG_HCTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */ +#define USB_OTG_HCTSIZ_PKTCNT USB_OTG_HCTSIZ_PKTCNT_Msk /*!< Packet count */ +#define USB_OTG_HCTSIZ_DOPING_Pos (31U) +#define USB_OTG_HCTSIZ_DOPING_Msk (0x1UL << USB_OTG_HCTSIZ_DOPING_Pos) /*!< 0x80000000 */ +#define USB_OTG_HCTSIZ_DOPING USB_OTG_HCTSIZ_DOPING_Msk /*!< Do PING */ +#define USB_OTG_HCTSIZ_DPID_Pos (29U) +#define USB_OTG_HCTSIZ_DPID_Msk (0x3UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x60000000 */ +#define USB_OTG_HCTSIZ_DPID USB_OTG_HCTSIZ_DPID_Msk /*!< Data PID */ +#define USB_OTG_HCTSIZ_DPID_0 (0x1UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x20000000 */ +#define USB_OTG_HCTSIZ_DPID_1 (0x2UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for USB_OTG_DIEPDMA register ********************/ +#define USB_OTG_DIEPDMA_DMAADDR_Pos (0U) +#define USB_OTG_DIEPDMA_DMAADDR_Msk (0xFFFFFFFFUL << USB_OTG_DIEPDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */ +#define USB_OTG_DIEPDMA_DMAADDR USB_OTG_DIEPDMA_DMAADDR_Msk /*!< DMA address */ + +/******************** Bit definition for USB_OTG_HCDMA register ********************/ +#define USB_OTG_HCDMA_DMAADDR_Pos (0U) +#define USB_OTG_HCDMA_DMAADDR_Msk (0xFFFFFFFFUL << USB_OTG_HCDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */ +#define USB_OTG_HCDMA_DMAADDR USB_OTG_HCDMA_DMAADDR_Msk /*!< DMA address */ + +/******************** Bit definition for USB_OTG_DTXFSTS register ********************/ +#define USB_OTG_DTXFSTS_INEPTFSAV_Pos (0U) +#define USB_OTG_DTXFSTS_INEPTFSAV_Msk (0xFFFFUL << USB_OTG_DTXFSTS_INEPTFSAV_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DTXFSTS_INEPTFSAV USB_OTG_DTXFSTS_INEPTFSAV_Msk /*!< IN endpoint TxFIFO space available */ + +/******************** Bit definition for USB_OTG_DIEPTXF register ********************/ +#define USB_OTG_DIEPTXF_INEPTXSA_Pos (0U) +#define USB_OTG_DIEPTXF_INEPTXSA_Msk (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXSA_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DIEPTXF_INEPTXSA USB_OTG_DIEPTXF_INEPTXSA_Msk /*!< IN endpoint FIFOx transmit RAM start address */ +#define USB_OTG_DIEPTXF_INEPTXFD_Pos (16U) +#define USB_OTG_DIEPTXF_INEPTXFD_Msk (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXFD_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_DIEPTXF_INEPTXFD USB_OTG_DIEPTXF_INEPTXFD_Msk /*!< IN endpoint TxFIFO depth */ + +/******************** Bit definition for USB_OTG_DOEPCTL register ********************/ + +#define USB_OTG_DOEPCTL_MPSIZ_Pos (0U) +#define USB_OTG_DOEPCTL_MPSIZ_Msk (0x7FFUL << USB_OTG_DOEPCTL_MPSIZ_Pos) /*!< 0x000007FF */ +#define USB_OTG_DOEPCTL_MPSIZ USB_OTG_DOEPCTL_MPSIZ_Msk /*!< Maximum packet size */ /*!ENDPTCTRL[i] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); + } + + //------------- Clear All Registers -------------// + dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK; + dcd_reg->ENDPTNAKEN = 0; + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE; + + while (dcd_reg->ENDPTPRIME) {} + dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; + while (dcd_reg->ENDPTFLUSH) {} + + // read reset bit in portsc + + //------------- Queue Head & Queue TD -------------// + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// + _dcd_data.qhd[0][0].zero_length_termination = _dcd_data.qhd[0][1].zero_length_termination = 1; + _dcd_data.qhd[0][0].max_packet_size = _dcd_data.qhd[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; + _dcd_data.qhd[0][0].qtd_overlay.next = _dcd_data.qhd[0][1].qtd_overlay.next = QTD_NEXT_INVALID; + + _dcd_data.qhd[0][0].int_on_setup = 1; // OUT only +} + +void dcd_init(uint8_t rhport) +{ + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + + // Reset controller + dcd_reg->USBCMD |= USBCMD_RESET; + while( dcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, must be set immediately after reset + dcd_reg->USBMODE = USBMODE_CM_DEVICE; + dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION; + +#if !TUD_OPT_HIGH_SPEED + dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; +#endif + + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_SUSPEND; + + dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 + dcd_reg->USBCMD |= USBCMD_RUN_STOP; // Connect +} + +void dcd_int_enable(uint8_t rhport) +{ + CI_DCD_INT_ENABLE(rhport); +} + +void dcd_int_disable(uint8_t rhport) +{ + CI_DCD_INT_DISABLE(rhport); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + // Response with status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + dcd_reg->PORTSC1 |= PORTSC1_FORCE_PORT_RESUME; +} + +void dcd_connect(uint8_t rhport) +{ + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + dcd_reg->USBCMD |= USBCMD_RUN_STOP; +} + +void dcd_disconnect(uint8_t rhport) +{ + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; +} + +//--------------------------------------------------------------------+ +// HELPER +//--------------------------------------------------------------------+ + +static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) +{ + // Force the CPU to flush the buffer. We increase the size by 31 because the call aligns the + // address to 32-byte boundaries. Buffer must be word aligned + CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) data_ptr, 4), total_bytes + 31); + + tu_memclr(p_qtd, sizeof(dcd_qtd_t)); + + p_qtd->next = QTD_NEXT_INVALID; + p_qtd->active = 1; + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + p_qtd->int_on_complete = true; + + if (data_ptr != NULL) + { + p_qtd->buffer[0] = (uint32_t) data_ptr; + + uint32_t const bufend = p_qtd->buffer[0] + total_bytes; + for(uint8_t i=1; i<5; i++) + { + uint32_t const next_page = tu_align4k( p_qtd->buffer[i-1] ) + 4096; + if ( bufend <= next_page ) break; + + p_qtd->buffer[i] = next_page; + + // TODO page[1] FRAME_N for ISO transfer + } + } +} + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); + + // flush to abort any primed buffer + dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // data toggle also need to be reset + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); + dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + + // Must not exceed max endpoint number + TU_ASSERT( epnum < _ci_controller[rhport].ep_count ); + + //------------- Prepare Queue Head -------------// + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + tu_memclr(p_qhd, sizeof(dcd_qhd_t)); + + p_qhd->zero_length_termination = 1; + p_qhd->max_packet_size = tu_edpt_packet_size(p_endpoint_desc); + if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) + { + p_qhd->iso_mult = 1; + } + + p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; + + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + // Enable EP Control + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + + uint32_t const epctrl = (p_endpoint_desc->bmAttributes.xfer << ENDPTCTRL_TYPE_POS) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET; + + if ( dir == TUSB_DIR_OUT ) + { + dcd_reg->ENDPTCTRL[epnum] = (dcd_reg->ENDPTCTRL[epnum] & 0xFFFF0000u) | epctrl; + }else + { + dcd_reg->ENDPTCTRL[epnum] = (dcd_reg->ENDPTCTRL[epnum] & 0x0000FFFFu) | (epctrl << 16); + } + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + + // Disable all non-control endpoints + for( uint8_t epnum=1; epnum < _ci_controller[rhport].ep_count; epnum++) + { + _dcd_data.qhd[epnum][TUSB_DIR_OUT].qtd_overlay.halted = 1; + _dcd_data.qhd[epnum][TUSB_DIR_IN ].qtd_overlay.halted = 1; + + dcd_reg->ENDPTFLUSH = TU_BIT(epnum) | TU_BIT(epnum+16); + dcd_reg->ENDPTCTRL[epnum] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); + } +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + + _dcd_data.qhd[epnum][dir].qtd_overlay.halted = 1; + + // Flush EP + uint32_t const flush_mask = TU_BIT(epnum + (dir ? 16 : 0)); + dcd_reg->ENDPTFLUSH = flush_mask; + while(dcd_reg->ENDPTFLUSH & flush_mask); + + // Clear EP enable + dcd_reg->ENDPTCTRL[epnum] &=~(ENDPTCTRL_ENABLE << (dir ? 16 : 0)); +} + +static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) +{ + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir]; + + p_qhd->qtd_overlay.halted = false; // clear any previous error + p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd + + // flush cache + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + if ( epnum == 0 ) + { + // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism + // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out + while(dcd_reg->ENDPTSETUPSTAT & TU_BIT(0)) {} + } + + // start transfer + dcd_reg->ENDPTPRIME = TU_BIT(epnum + (dir ? 16 : 0)); +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir]; + + // Prepare qtd + qtd_init(p_qtd, buffer, total_bytes); + + // Start qhd transfer + p_qhd->ff = NULL; + qhd_start_xfer(rhport, epnum, dir); + + return true; +} + +// fifo has to be aligned to 4k boundary +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[epnum][dir]; + + tu_fifo_buffer_info_t fifo_info; + + if (dir) + { + tu_fifo_get_read_info(ff, &fifo_info); + } else + { + tu_fifo_get_write_info(ff, &fifo_info); + } + + if ( fifo_info.len_lin >= total_bytes ) + { + // Linear length is enough for this transfer + qtd_init(p_qtd, fifo_info.ptr_lin, total_bytes); + } + else + { + // linear part is not enough + + // prepare TD up to linear length + qtd_init(p_qtd, fifo_info.ptr_lin, fifo_info.len_lin); + + if ( !tu_offset4k((uint32_t) fifo_info.ptr_wrap) && !tu_offset4k(tu_fifo_depth(ff)) ) + { + // If buffer is aligned to 4K & buffer size is multiple of 4K + // We can make use of buffer page array to also combine the linear + wrapped length + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + + for(uint8_t i = 1, page = 0; i < 5; i++) + { + // pick up buffer array where linear ends + if (p_qtd->buffer[i] == 0) + { + p_qtd->buffer[i] = (uint32_t) fifo_info.ptr_wrap + 4096 * page; + page++; + } + } + + CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_wrap, 4), total_bytes - fifo_info.len_wrap + 31); + } + else + { + // TODO we may need to carry the wrapped length after the linear part complete + // for now only transfer up to linear part + } + } + + // Start qhd transfer + p_qhd->ff = ff; + qhd_start_xfer(rhport, epnum, dir); + + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ + +static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir) +{ + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[epnum][dir]; + + uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : + ( p_qtd->xact_err || p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; + + if ( result != XFER_RESULT_SUCCESS ) + { + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + // flush to abort error buffer + dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); + } + + uint16_t const xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes; + + if (p_qhd->ff) + { + if (dir == TUSB_DIR_IN) + { + tu_fifo_advance_read_pointer(p_qhd->ff, xferred_bytes); + } else + { + tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes); + } + } + + // only number of bytes in the IOC qtd + dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), xferred_bytes, result, true); +} + +void dcd_int_handler(uint8_t rhport) +{ + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + + uint32_t const int_enable = dcd_reg->USBINTR; + uint32_t const int_status = dcd_reg->USBSTS & int_enable; + dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt + + // disabled interrupt sources + if (int_status == 0) return; + + // Set if the port controller enters the full or high-speed operational state. + // either from Bus Reset or Suspended state + if (int_status & INTR_PORT_CHANGE) + { + // TU_LOG2("PortChange %08lx\r\n", dcd_reg->PORTSC1); + + // Reset interrupt is not enabled, we manually check if Port Change is due + // to connection / disconnection + if ( dcd_reg->USBSTS & INTR_RESET ) + { + dcd_reg->USBSTS = INTR_RESET; + + if (dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) + { + uint32_t const speed = (dcd_reg->PORTSC1 & PORTSC1_PORT_SPEED) >> PORTSC1_PORT_SPEED_POS; + bus_reset(rhport); + dcd_event_bus_reset(rhport, (tusb_speed_t) speed, true); + }else + { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + } + else + { + // Triggered by resuming from suspended state + if ( !(dcd_reg->PORTSC1 & PORTSC1_SUSPEND) ) + { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + } + } + + if (int_status & INTR_SUSPEND) + { + // TU_LOG2("Suspend %08lx\r\n", dcd_reg->PORTSC1); + + if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) + { + // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. + // Skip suspend event if we are not addressed + if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + } + } + + if (int_status & INTR_USB) + { + // Make sure we read the latest version of _dcd_data. + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE; + dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge + + if (dcd_reg->ENDPTSETUPSTAT) + { + //------------- Set up Received -------------// + // 23.10.10.2 Operational model for setup transfers + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + + dcd_event_setup_received(rhport, (uint8_t*)(uintptr_t) &_dcd_data.qhd[0][0].setup_request, true); + } + + // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set + // nothing to do, we will submit xfer as error to usbd + // if (int_status & INTR_ERROR) { } + + if ( edpt_complete ) + { + for(uint8_t epnum = 0; epnum < TUP_DCD_ENDPOINT_MAX; epnum++) + { + if ( tu_bit_test(edpt_complete, epnum) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_OUT); + if ( tu_bit_test(edpt_complete, epnum+16) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN); + } + } + } + + if (int_status & INTR_SOF) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/circuitpython/lib/tinyusb/src/portable/chipidea/ci_hs/hcd_ci_hs.c new file mode 100644 index 0000000..221721b --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -0,0 +1,94 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +// Chipidea Highspeed USB IP implement EHCI for host functionality + +#if CFG_TUH_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "common/tusb_common.h" +#include "host/hcd.h" +#include "portable/ehci/ehci_api.h" +#include "ci_hs_type.h" + +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #include "ci_hs_imxrt.h" +#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) + #include "ci_hs_lpc18_43.h" +#else + #error "Unsupported MCUs" +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +#define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base) + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +bool hcd_init(uint8_t rhport) +{ + ci_hs_regs_t* hcd_reg = CI_HS_REG(rhport); + + // Reset controller + hcd_reg->USBCMD |= USBCMD_RESET; + while( hcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, must be set immediately after reset +#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX + // LPC18XX/43XX need to set VBUS Power Select to HIGH + // RHPORT1 is fullspeed only (need external PHY for Highspeed) + hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT; + if (rhport == 1) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; +#else + hcd_reg->USBMODE = USBMODE_CM_HOST; +#endif + + // FIXME force full speed, still have issue with Highspeed enumeration + hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; + + return ehci_init(rhport, (uint32_t) &hcd_reg->CAPLENGTH, (uint32_t) &hcd_reg->USBCMD); +} + +void hcd_int_enable(uint8_t rhport) +{ + CI_HCD_INT_ENABLE(rhport); +} + +void hcd_int_disable(uint8_t rhport) +{ + CI_HCD_INT_DISABLE(rhport); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/dialog/da146xx/dcd_da146xx.c b/circuitpython/lib/tinyusb/src/portable/dialog/da146xx/dcd_da146xx.c new file mode 100644 index 0000000..919249a --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/dialog/da146xx/dcd_da146xx.c @@ -0,0 +1,1212 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_DA1469X + +#include "mcu/mcu.h" + +#include "device/dcd.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#define USE_SOF 0 + +// Size of RX or TX FIFO. +#define FIFO_SIZE 64 + +#ifndef TU_DA1469X_FIFO_READ_THRESHOLD +// RX FIFO is 64 bytes. When endpoint size is greater then 64, FIFO warning interrupt +// is enabled to allow read incoming data during frame reception. +// It is possible to stay in interrupt reading whole packet at once, but it may be +// more efficient for MCU to read as much data as possible and when FIFO is hardly +// filled exit interrupt handler waiting for next FIFO warning level interrupt +// or packet end. +// When running at 96MHz code that reads FIFO based on number of bytes stored in +// USB_RXSx_REG.USB_RXCOUNT takes enough time to fill FIFO with two additional bytes. +// Settings this threshold above this allows to leave interrupt handler and wait +// for more bytes to before next ISR. This allows reduce overall ISR time to 1/3 +// of time that would be needed if ISR read as fast as possible. +#define TU_DA1469X_FIFO_READ_THRESHOLD 4 +#endif + +#define EP_MAX 4 + +// Node functional states +#define NFSR_NODE_RESET 0 +#define NFSR_NODE_RESUME 1 +#define NFSR_NODE_OPERATIONAL 2 +#define NFSR_NODE_SUSPEND 3 +// Those two following states are added to allow going out of sleep mode +// using frame interrupt. On remove wakeup RESUME state must be kept for +// at least 1ms. It is accomplished by using FRAME interrupt that goes +// through those two fake states before entering OPERATIONAL state. +#define NFSR_NODE_WAKING (0x10 | (NFSR_NODE_RESUME)) +#define NFSR_NODE_WAKING2 (0x20 | (NFSR_NODE_RESUME)) + +static TU_ATTR_ALIGNED(4) uint8_t _setup_packet[8]; + +typedef struct +{ + union + { + __IOM uint32_t epc_in; + __IOM uint32_t USB_EPC0_REG; /*!< (@ 0x00000080) Endpoint Control 0 Register */ + __IOM uint32_t USB_EPC1_REG; /*!< (@ 0x000000A0) Endpoint Control Register 1 */ + __IOM uint32_t USB_EPC3_REG; /*!< (@ 0x000000C0) Endpoint Control Register 3 */ + __IOM uint32_t USB_EPC5_REG; /*!< (@ 0x000000E0) Endpoint Control Register 5 */ + }; + union + { + __IOM uint32_t txd; + __IOM uint32_t USB_TXD0_REG; /*!< (@ 0x00000084) Transmit Data 0 Register */ + __IOM uint32_t USB_TXD1_REG; /*!< (@ 0x000000A4) Transmit Data Register 1 */ + __IOM uint32_t USB_TXD2_REG; /*!< (@ 0x000000C4) Transmit Data Register 2 */ + __IOM uint32_t USB_TXD3_REG; /*!< (@ 0x000000E4) Transmit Data Register 3 */ + }; + union + { + __IOM uint32_t txs; + __IOM uint32_t USB_TXS0_REG; /*!< (@ 0x00000088) Transmit Status 0 Register */ + __IOM uint32_t USB_TXS1_REG; /*!< (@ 0x000000A8) Transmit Status Register 1 */ + __IOM uint32_t USB_TXS2_REG; /*!< (@ 0x000000C8) Transmit Status Register 2 */ + __IOM uint32_t USB_TXS3_REG; /*!< (@ 0x000000E8) Transmit Status Register 3 */ + }; + union + { + __IOM uint32_t txc; + __IOM uint32_t USB_TXC0_REG; /*!< (@ 0x0000008C) Transmit command 0 Register */ + __IOM uint32_t USB_TXC1_REG; /*!< (@ 0x000000AC) Transmit Command Register 1 */ + __IOM uint32_t USB_TXC2_REG; /*!< (@ 0x000000CC) Transmit Command Register 2 */ + __IOM uint32_t USB_TXC3_REG; /*!< (@ 0x000000EC) Transmit Command Register 3 */ + }; + union + { + __IOM uint32_t epc_out; + __IOM uint32_t USB_EP0_NAK_REG; /*!< (@ 0x00000090) EP0 INNAK and OUTNAK Register */ + __IOM uint32_t USB_EPC2_REG; /*!< (@ 0x000000B0) Endpoint Control Register 2 */ + __IOM uint32_t USB_EPC4_REG; /*!< (@ 0x000000D0) Endpoint Control Register 4 */ + __IOM uint32_t USB_EPC6_REG; /*!< (@ 0x000000F0) Endpoint Control Register 6 */ + }; + union + { + __IOM uint32_t rxd; + __IOM uint32_t USB_RXD0_REG; /*!< (@ 0x00000094) Receive Data 0 Register */ + __IOM uint32_t USB_RXD1_REG; /*!< (@ 0x000000B4) Receive Data Register,1 */ + __IOM uint32_t USB_RXD2_REG; /*!< (@ 0x000000D4) Receive Data Register 2 */ + __IOM uint32_t USB_RXD3_REG; /*!< (@ 0x000000F4) Receive Data Register 3 */ + }; + union + { + __IOM uint32_t rxs; + __IOM uint32_t USB_RXS0_REG; /*!< (@ 0x00000098) Receive Status 0 Register */ + __IOM uint32_t USB_RXS1_REG; /*!< (@ 0x000000B8) Receive Status Register 1 */ + __IOM uint32_t USB_RXS2_REG; /*!< (@ 0x000000D8) Receive Status Register 2 */ + __IOM uint32_t USB_RXS3_REG; /*!< (@ 0x000000F8) Receive Status Register 3 */ + }; + union + { + __IOM uint32_t rxc; + __IOM uint32_t USB_RXC0_REG; /*!< (@ 0x0000009C) Receive Command 0 Register */ + __IOM uint32_t USB_RXC1_REG; /*!< (@ 0x000000BC) Receive Command Register 1 */ + __IOM uint32_t USB_RXC2_REG; /*!< (@ 0x000000DC) Receive Command Register 2 */ + __IOM uint32_t USB_RXC3_REG; /*!< (@ 0x000000FC) Receive Command Register 3 */ + }; +} volatile EPx_REGS; + +#define EP_REGS(first_ep_reg) (EPx_REGS*)(&USB->first_ep_reg) + +// DMA channel pair to use, channel 6 will be used for RX channel 7 for TX direction. +#ifndef TU_DA146XX_DMA_RX_CHANNEL +#define TU_DA146XX_DMA_RX_CHANNEL 6 +#endif +#define DA146XX_DMA_USB_MUX (0x6 << (TU_DA146XX_DMA_RX_CHANNEL * 2)) +#define DA146XX_DMA_USB_MUX_MASK (0xF << (TU_DA146XX_DMA_RX_CHANNEL * 2)) + +typedef struct +{ + __IOM uint32_t DMAx_A_START_REG; + __IOM uint32_t DMAx_B_START_REG; + __IOM uint32_t DMAx_INT_REG; + __IOM uint32_t DMAx_LEN_REG; + __IOM uint32_t DMAx_CTRL_REG; + __IOM uint32_t DMAx_IDX_REG; + __IM uint32_t RESERVED[2]; // Extend structure size for array like usage, registers for each channel are 0x20 bytes apart. +} da146xx_dma_channel_t; + +#define DMA_CHANNEL_REGS(n) ((da146xx_dma_channel_t *)(DMA) + n) +#define RX_DMA_REGS DMA_CHANNEL_REGS(TU_DA146XX_DMA_RX_CHANNEL) +#define TX_DMA_REGS DMA_CHANNEL_REGS((TU_DA146XX_DMA_RX_CHANNEL) + 1) + +#define RX_DMA_START ((1 << DMA_DMA0_CTRL_REG_DMA_ON_Pos) |\ + (0 << DMA_DMA0_CTRL_REG_BW_Pos) | \ + (1 << DMA_DMA0_CTRL_REG_DREQ_MODE_Pos) | \ + (1 << DMA_DMA0_CTRL_REG_BINC_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_AINC_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_CIRCULAR_Pos) | \ + (2 << DMA_DMA0_CTRL_REG_DMA_PRIO_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_DMA_IDLE_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_DMA_INIT_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_REQ_SENSE_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_BURST_MODE_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Pos)) + +#define TX_DMA_START ((1 << DMA_DMA0_CTRL_REG_DMA_ON_Pos) |\ + (0 << DMA_DMA0_CTRL_REG_BW_Pos) | \ + (1 << DMA_DMA0_CTRL_REG_DREQ_MODE_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_BINC_Pos) | \ + (1 << DMA_DMA0_CTRL_REG_AINC_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_CIRCULAR_Pos) | \ + (2 << DMA_DMA0_CTRL_REG_DMA_PRIO_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_DMA_IDLE_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_DMA_INIT_Pos) | \ + (1 << DMA_DMA0_CTRL_REG_REQ_SENSE_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_BURST_MODE_Pos) | \ + (0 << DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Pos)) + +// Dialog register fields and bit mask are very long. Filed masks repeat register names. +// Those convenience macros are a way to reduce complexity of register modification lines. +#define GET_BIT(val, field) (val & field ## _Msk) >> field ## _Pos +#define REG_GET_BIT(reg, field) (USB->reg & USB_ ## reg ## _ ## field ## _Msk) +#define REG_SET_BIT(reg, field) USB->reg |= USB_ ## reg ## _ ## field ## _Msk +#define REG_CLR_BIT(reg, field) USB->reg &= ~USB_ ## reg ## _ ## field ## _Msk +#define REG_SET_VAL(reg, field, val) USB->reg = (USB->reg & ~USB_ ## reg ## _ ## field ## _Msk) | (val << USB_ ## reg ## _ ## field ## _Pos) + +static EPx_REGS * const ep_regs[EP_MAX] = { + EP_REGS(USB_EPC0_REG), + EP_REGS(USB_EPC1_REG), + EP_REGS(USB_EPC3_REG), + EP_REGS(USB_EPC5_REG), +}; + +typedef struct { + uint8_t * buffer; + // Total length of current transfer + uint16_t total_len; + // Bytes transferred so far + uint16_t transferred; + uint16_t max_packet_size; + // Packet size sent or received so far. It is used to modify transferred field + // after ACK is received or when filling ISO endpoint with size larger then + // FIFO size. + uint16_t last_packet_size; + uint8_t ep_addr; + // DATA0/1 toggle bit 1 DATA1 is expected or transmitted + uint8_t data1 : 1; + // Endpoint is stalled + uint8_t stall : 1; + // ISO endpoint + uint8_t iso : 1; +} xfer_ctl_t; + +static struct +{ + bool vbus_present; + bool init_called; + uint8_t nfsr; + xfer_ctl_t xfer_status[EP_MAX][2]; + // Endpoints that use DMA, one for each direction + uint8_t dma_ep[2]; +} _dcd = +{ + .vbus_present = false, + .init_called = false, +}; + +// Converts xfer pointer to epnum (0,1,2,3) regardless of xfer direction +#define XFER_EPNUM(xfer) ((xfer - &_dcd.xfer_status[0][0]) >> 1) +// Converts xfer pinter to EPx_REGS pointer (returns same pointer for IN and OUT with same endpoint number) +#define XFER_REGS(xfer) ep_regs[XFER_EPNUM(xfer)] +// Converts epnum (0,1,2,3) to EPx_REGS pointer +#define EPNUM_REGS(epnum) ep_regs[epnum] + +// Two endpoint 0 descriptor definition for unified dcd_edpt_open() +static const tusb_desc_endpoint_t ep0OUT_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x00, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 +}; + +static const tusb_desc_endpoint_t ep0IN_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x80, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 +}; + +#define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir] + +static void set_nfsr(uint8_t val) +{ + _dcd.nfsr = val; + // Write only lower 2 bits to register, higher bits are used + // to count down till OPERATIONAL state can be entered when + // remote wakeup activated. + USB->USB_NFSR_REG = val & 3; +} + +static void fill_tx_fifo(xfer_ctl_t * xfer) +{ + int left_to_send; + uint8_t const *src; + uint8_t const epnum = tu_edpt_number(xfer->ep_addr); + EPx_REGS *regs = EPNUM_REGS(epnum); + + src = &xfer->buffer[xfer->transferred]; + left_to_send = xfer->total_len - xfer->transferred; + if (left_to_send > xfer->max_packet_size - xfer->last_packet_size) + { + left_to_send = xfer->max_packet_size - xfer->last_packet_size; + } + + // Loop checks TCOUNT all the time since this value is saturated to 31 + // and can't be read just once before. + while ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) > 0 && left_to_send > 0) + { + regs->txd = *src++; + xfer->last_packet_size++; + left_to_send--; + } + if (epnum != 0) + { + if (left_to_send > 0) + { + // Max packet size is set to value greater then FIFO. Enable fifo level warning + // to handle larger packets. + regs->txc |= (3 << USB_USB_TXC1_REG_USB_TFWL_Pos); + USB->USB_FWMSK_REG |= 1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_TXWARN31_Pos); + } + else + { + regs->txc &= ~USB_USB_TXC1_REG_USB_TFWL_Msk; + USB->USB_FWMSK_REG &= ~(1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_TXWARN31_Pos)); + // Whole packet already in fifo, no need to refill it later. Mark last. + regs->txc |= USB_USB_TXC1_REG_USB_LAST_Msk; + } + } +} + +static bool try_allocate_dma(uint8_t epnum, uint8_t dir) +{ + // TODO: Disable interrupts while checking + if (_dcd.dma_ep[dir] == 0) + { + _dcd.dma_ep[dir] = epnum; + if (dir == TUSB_DIR_OUT) + USB->USB_DMA_CTRL_REG = (USB->USB_DMA_CTRL_REG & ~USB_USB_DMA_CTRL_REG_USB_DMA_RX_Msk) | + ((epnum - 1) << USB_USB_DMA_CTRL_REG_USB_DMA_RX_Pos); + else + USB->USB_DMA_CTRL_REG = (USB->USB_DMA_CTRL_REG & ~USB_USB_DMA_CTRL_REG_USB_DMA_TX_Msk) | + ((epnum - 1) << USB_USB_DMA_CTRL_REG_USB_DMA_TX_Pos); + USB->USB_DMA_CTRL_REG |= USB_USB_DMA_CTRL_REG_USB_DMA_EN_Msk; + } + return _dcd.dma_ep[dir] == epnum; +} + +static void start_rx_dma(volatile void *src, void *dst, uint16_t size) +{ + // Setup SRC and DST registers + RX_DMA_REGS->DMAx_A_START_REG = (uint32_t)src; + RX_DMA_REGS->DMAx_B_START_REG = (uint32_t)dst; + // Don't need DMA interrupt, read end is determined by RX_LAST or RX_ERR events. + RX_DMA_REGS->DMAx_INT_REG = size - 1; + RX_DMA_REGS->DMAx_LEN_REG = size - 1; + RX_DMA_REGS->DMAx_CTRL_REG = RX_DMA_START; +} + +static void start_rx_packet(xfer_ctl_t *xfer) +{ + uint8_t const epnum = tu_edpt_number(xfer->ep_addr); + uint16_t remaining = xfer->total_len - xfer->transferred; + uint16_t size = tu_min16(remaining, xfer->max_packet_size); + EPx_REGS *regs = XFER_REGS(xfer); + + xfer->last_packet_size = 0; + if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE) + { + if (try_allocate_dma(epnum, TUSB_DIR_OUT)) + { + start_rx_dma(®s->rxd, xfer->buffer + xfer->transferred, size); + } + else + { + // Other endpoint is using DMA in that direction, fall back to interrupts. + // For endpoint size greater than FIFO size enable FIFO level warning interrupt + // when FIFO has less than 17 bytes free. + regs->rxc |= USB_USB_RXC1_REG_USB_RFWL_Msk; + USB->USB_FWMSK_REG |= 1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos); + } + } + else if (epnum != 0) + { + // If max_packet_size would fit in FIFO no need for FIFO level warning interrupt. + regs->rxc &= ~USB_USB_RXC1_REG_USB_RFWL_Msk; + USB->USB_FWMSK_REG &= ~(1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos)); + } + regs->rxc |= USB_USB_RXC1_REG_USB_RX_EN_Msk; +} + +static void start_tx_dma(void *src, volatile void *dst, uint16_t size) +{ + // Setup SRC and DST registers + TX_DMA_REGS->DMAx_A_START_REG = (uint32_t)src; + TX_DMA_REGS->DMAx_B_START_REG = (uint32_t)dst; + // Interrupt not needed + TX_DMA_REGS->DMAx_INT_REG = size; + TX_DMA_REGS->DMAx_LEN_REG = size - 1; + TX_DMA_REGS->DMAx_CTRL_REG = TX_DMA_START; +} + +static void start_tx_packet(xfer_ctl_t *xfer) +{ + uint8_t const epnum = tu_edpt_number(xfer->ep_addr); + uint16_t remaining = xfer->total_len - xfer->transferred; + uint16_t size = tu_min16(remaining, xfer->max_packet_size); + EPx_REGS *regs = EPNUM_REGS(epnum); + + xfer->last_packet_size = 0; + + regs->txc = USB_USB_TXC1_REG_USB_FLUSH_Msk; + regs->txc = USB_USB_TXC1_REG_USB_IGN_ISOMSK_Msk; + if (xfer->data1) regs->txc |= USB_USB_TXC1_REG_USB_TOGGLE_TX_Msk; + + if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE && try_allocate_dma(epnum, TUSB_DIR_IN)) + { + // Whole packet will be put in FIFO by DMA. Set LAST bit before start. + start_tx_dma(xfer->buffer + xfer->transferred, ®s->txd, size); + regs->txc |= USB_USB_TXC1_REG_USB_LAST_Msk; + } + else + { + fill_tx_fifo(xfer); + } + regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk; +} + +static uint16_t read_rx_fifo(xfer_ctl_t *xfer, uint16_t bytes_in_fifo) +{ + EPx_REGS *regs = XFER_REGS(xfer); + uint16_t remaining = xfer->total_len - xfer->transferred - xfer->last_packet_size; + uint16_t receive_this_time = bytes_in_fifo; + + if (remaining < bytes_in_fifo) receive_this_time = remaining; + + uint8_t *buf = xfer->buffer + xfer->transferred + xfer->last_packet_size; + + for (int i = 0; i < receive_this_time; ++i) buf[i] = regs->rxd; + + xfer->last_packet_size += receive_this_time; + + return bytes_in_fifo - receive_this_time; +} + +static void handle_ep0_rx(void) +{ + int fifo_bytes; + uint32_t rxs0 = USB->USB_RXS0_REG; + + xfer_ctl_t *xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT); + + fifo_bytes = GET_BIT(rxs0, USB_USB_RXS0_REG_USB_RCOUNT); + if (rxs0 & USB_USB_RXS0_REG_USB_SETUP_Msk) + { + xfer_ctl_t *xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN); + // Setup packet is in + for (int i = 0; i < fifo_bytes; ++i) _setup_packet[i] = USB->USB_RXD0_REG; + + xfer->stall = 0; + xfer->data1 = 1; + xfer_in->stall = 0; + xfer_in->data1 = 1; + REG_SET_BIT(USB_TXC0_REG, USB_TOGGLE_TX0); + REG_CLR_BIT(USB_EPC0_REG, USB_STALL); + dcd_event_setup_received(0, _setup_packet,true); + } + else + { + if (GET_BIT(rxs0, USB_USB_RXS0_REG_USB_TOGGLE_RX0) != xfer->data1) + { + // Toggle bit does not match discard packet + REG_SET_BIT(USB_RXC0_REG, USB_FLUSH); + xfer->last_packet_size = 0; + } + else + { + read_rx_fifo(xfer, fifo_bytes); + if (rxs0 & USB_USB_RXS0_REG_USB_RX_LAST_Msk) + { + xfer->transferred += xfer->last_packet_size; + xfer->data1 ^= 1; + + if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size) + { + dcd_event_xfer_complete(0, 0, xfer->transferred, XFER_RESULT_SUCCESS, true); + } + else + { + // Re-enable reception + REG_SET_BIT(USB_RXC0_REG, USB_RX_EN); + } + xfer->last_packet_size = 0; + } + } + } +} + +static void handle_ep0_tx(void) +{ + uint32_t txs0; + xfer_ctl_t *xfer = XFER_CTL_BASE(0, TUSB_DIR_IN); + EPx_REGS *regs = XFER_REGS(xfer); + + txs0 = regs->USB_TXS0_REG; + + if (GET_BIT(txs0, USB_USB_TXS0_REG_USB_TX_DONE)) + { + // ACK received + if (GET_BIT(txs0, USB_USB_TXS0_REG_USB_ACK_STAT)) + { + xfer->transferred += xfer->last_packet_size; + xfer->last_packet_size = 0; + xfer->data1 ^= 1; + REG_SET_VAL(USB_TXC0_REG, USB_TOGGLE_TX0, xfer->data1); + if (xfer->transferred == xfer->total_len) + { + dcd_event_xfer_complete(0, 0 | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + return; + } + } + else + { + // Start from the beginning + xfer->last_packet_size = 0; + } + fill_tx_fifo(xfer); + } +} + +static void handle_epx_rx_ev(uint8_t ep) +{ + uint32_t rxs; + int fifo_bytes; + xfer_ctl_t *xfer = XFER_CTL_BASE(ep, TUSB_DIR_OUT); + + EPx_REGS *regs = EPNUM_REGS(ep); + + do + { + rxs = regs->rxs; + + if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_ERR)) + { + regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; + xfer->last_packet_size = 0; + if (_dcd.dma_ep[TUSB_DIR_OUT] == ep) + { + // Stop DMA + RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk; + // Restart DMA since packet was dropped, all parameters should still work. + RX_DMA_REGS->DMAx_CTRL_REG |= DMA_DMA0_CTRL_REG_DMA_ON_Msk; + } + break; + } + else + { + if (_dcd.dma_ep[TUSB_DIR_OUT] == ep) + { + // Disable DMA and update last_packet_size with what DMA reported. + RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk; + xfer->last_packet_size = RX_DMA_REGS->DMAx_IDX_REG; + // When DMA did not finished (packet was smaller then MPS), DMAx_IDX_REG holds exact number of bytes transmitted. + // When DMA finished value in DMAx_IDX_REG is one less then actual number of transmitted bytes. + if (xfer->last_packet_size == RX_DMA_REGS->DMAx_LEN_REG) xfer->last_packet_size++; + // Release DMA to use by other endpoints. + _dcd.dma_ep[TUSB_DIR_OUT] = 0; + } + fifo_bytes = GET_BIT(rxs, USB_USB_RXS1_REG_USB_RXCOUNT); + // FIFO maybe empty if DMA read it before or it's final iteration and function already read all that was to read. + if (fifo_bytes > 0) + { + fifo_bytes = read_rx_fifo(xfer, fifo_bytes); + } + if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_LAST)) + { + if (!xfer->iso && GET_BIT(rxs, USB_USB_RXS1_REG_USB_TOGGLE_RX) != xfer->data1) + { + // Toggle bit does not match discard packet + regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; + } + else + { + xfer->data1 ^= 1; + xfer->transferred += xfer->last_packet_size; + if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size || xfer->iso) + { + if (fifo_bytes) + { + // There are extra bytes in the FIFO just flush them + regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; + fifo_bytes = 0; + } + + dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, XFER_RESULT_SUCCESS, true); + } + else + { + // Re-enable reception + start_rx_packet(xfer); + } + } + xfer->last_packet_size = 0; + } + } + } while (fifo_bytes > TU_DA1469X_FIFO_READ_THRESHOLD); +} + +static void handle_rx_ev(void) +{ + if (USB->USB_RXEV_REG & 1) + handle_epx_rx_ev(1); + if (USB->USB_RXEV_REG & 2) + handle_epx_rx_ev(2); + if (USB->USB_RXEV_REG & 4) + handle_epx_rx_ev(3); +} + +static void handle_epx_tx_ev(xfer_ctl_t *xfer) +{ + uint8_t const epnum = tu_edpt_number(xfer->ep_addr); + uint32_t txs; + EPx_REGS *regs = EPNUM_REGS(epnum); + + txs = regs->txs; + + if (GET_BIT(txs, USB_USB_TXS1_REG_USB_TX_DONE)) + { + if (_dcd.dma_ep[TUSB_DIR_IN] == epnum) + { + // Disable DMA and update last_packet_size with what DMA reported. + TX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA1_CTRL_REG_DMA_ON_Msk; + xfer->last_packet_size = TX_DMA_REGS->DMAx_IDX_REG + 1; + // Release DMA to used by other endpoints. + _dcd.dma_ep[TUSB_DIR_IN] = 0; + } + if (GET_BIT(txs, USB_USB_TXS1_REG_USB_ACK_STAT)) + { + // ACK received, update transfer state and DATA0/1 bit + xfer->transferred += xfer->last_packet_size; + xfer->last_packet_size = 0; + xfer->data1 ^= 1; + + if (xfer->transferred == xfer->total_len) + { + dcd_event_xfer_complete(0, xfer->ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); + return; + } + } + else if (regs->epc_in & USB_USB_EPC1_REG_USB_STALL_Msk) + { + // TX_DONE also indicates that STALL packet was just sent, there is + // no point to put anything into transmit FIFO. It could result in + // empty packet being scheduled. + return; + } + } + if (txs & USB_USB_TXS1_REG_USB_TX_URUN_Msk) + { + TU_LOG1("EP %d FIFO underrun\n", epnum); + } + // Start next or repeated packet. + start_tx_packet(xfer); +} + +static void handle_tx_ev(void) +{ + if (USB->USB_TXEV_REG & 1) + handle_epx_tx_ev(XFER_CTL_BASE(1, TUSB_DIR_IN)); + if (USB->USB_TXEV_REG & 2) + handle_epx_tx_ev(XFER_CTL_BASE(2, TUSB_DIR_IN)); + if (USB->USB_TXEV_REG & 4) + handle_epx_tx_ev(XFER_CTL_BASE(3, TUSB_DIR_IN)); +} + +static uint32_t check_reset_end(uint32_t alt_ev) +{ + if (_dcd.nfsr == NFSR_NODE_RESET) + { + if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET)) + { + // Could be still in reset, but since USB_M_RESET is disabled it can + // be also old reset state that was not cleared yet. + // If (after reading USB_ALTEV_REG register again) bit is cleared + // reset state just ended. + // Keep non-reset bits combined from two previous ALTEV read and + // one from the next line. + alt_ev = (alt_ev & ~USB_USB_ALTEV_REG_USB_RESET_Msk) | USB->USB_ALTEV_REG; + } + if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET) == 0) + { + USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | + USB_USB_ALTEV_REG_USB_SD3_Msk; + set_nfsr(NFSR_NODE_OPERATIONAL); + dcd_edpt_open(0, &ep0OUT_desc); + dcd_edpt_open(0, &ep0IN_desc); + } + } + return alt_ev; +} + +static void handle_bus_reset(void) +{ + uint32_t alt_ev; + + USB->USB_NFSR_REG = 0; + USB->USB_FAR_REG = 0x80; + USB->USB_ALTMSK_REG = 0; + USB->USB_NFSR_REG = NFSR_NODE_RESET; + USB->USB_TXMSK_REG = 0; + USB->USB_RXMSK_REG = 0; + set_nfsr(NFSR_NODE_RESET); + + dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); + USB->USB_DMA_CTRL_REG = 0; + + USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk | + USB_USB_MAMSK_REG_USB_M_FRAME_Msk | + USB_USB_MAMSK_REG_USB_M_WARN_Msk | + USB_USB_MAMSK_REG_USB_M_ALT_Msk; + USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESUME_Msk; + alt_ev = USB->USB_ALTEV_REG; + check_reset_end(alt_ev); +} + +static void handle_alt_ev(void) +{ + uint32_t alt_ev = USB->USB_ALTEV_REG; + + alt_ev = check_reset_end(alt_ev); + if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET) && _dcd.nfsr != NFSR_NODE_RESET) + { + handle_bus_reset(); + } + else if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESUME)) + { + if (USB->USB_NFSR_REG == NFSR_NODE_SUSPEND) + { + set_nfsr(NFSR_NODE_OPERATIONAL); + USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | + USB_USB_ALTMSK_REG_USB_M_SD3_Msk; + // Re-enable reception of endpoint with pending transfer + for (int epnum = 1; epnum <= 3; ++epnum) + { + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + if (xfer->total_len > xfer->transferred) + { + start_rx_packet(xfer); + } + } + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + } + else if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_SD3)) + { + set_nfsr(NFSR_NODE_SUSPEND); + USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | + USB_USB_ALTMSK_REG_USB_M_RESUME_Msk; + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } +} + +static void handle_epx_tx_warn_ev(uint8_t ep) +{ + fill_tx_fifo(XFER_CTL_BASE(ep, TUSB_DIR_IN)); +} + +static void handle_fifo_warning(void) +{ + uint32_t fifo_warning = USB->USB_FWEV_REG; + + if (fifo_warning & 0x01) + handle_epx_tx_warn_ev(1); + if (fifo_warning & 0x02) + handle_epx_tx_warn_ev(2); + if (fifo_warning & 0x04) + handle_epx_tx_warn_ev(3); + if (fifo_warning & 0x10) + handle_epx_rx_ev(1); + if (fifo_warning & 0x20) + handle_epx_rx_ev(2); + if (fifo_warning & 0x40) + handle_epx_rx_ev(3); +} + +static void handle_ep0_nak(void) +{ + uint32_t ep0_nak = USB->USB_EP0_NAK_REG; + + if (REG_GET_BIT(USB_EPC0_REG, USB_STALL)) + { + if (GET_BIT(ep0_nak, USB_USB_EP0_NAK_REG_USB_EP0_INNAK)) + { + // EP0 is stalled and NAK was sent, it means that RX is enabled + // Disable RX for now. + REG_CLR_BIT(USB_RXC0_REG, USB_RX_EN); + REG_SET_BIT(USB_TXC0_REG, USB_TX_EN); + } + if (GET_BIT(ep0_nak, USB_USB_EP0_NAK_REG_USB_EP0_OUTNAK)) + { + REG_SET_BIT(USB_RXC0_REG, USB_RX_EN); + } + } + else + { + REG_CLR_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); + } +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + _dcd.init_called = true; + if (_dcd.vbus_present) + { + dcd_connect(rhport); + } +} + +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + + NVIC_EnableIRQ(USB_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + + NVIC_DisableIRQ(USB_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + + // Set default address for one ZLP + USB->USB_EPC0_REG = USB_USB_EPC0_REG_USB_DEF_Msk; + USB->USB_FAR_REG = (dev_addr & USB_USB_FAR_REG_USB_AD_Msk) | USB_USB_FAR_REG_USB_AD_EN_Msk; + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + if (_dcd.nfsr == NFSR_NODE_SUSPEND) + { + // Enter fake state that will use FRAME interrupt to wait before going operational. + set_nfsr(NFSR_NODE_WAKING); + USB->USB_MAMSK_REG |= USB_USB_MAMSK_REG_USB_M_FRAME_Msk; + } +} + +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + + if (GET_BIT(USB->USB_MCTRL_REG, USB_USB_MCTRL_REG_USB_NAT) == 0) + { + USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk; + USB->USB_NFSR_REG = 0; + USB->USB_FAR_REG = 0x80; + USB->USB_TXMSK_REG = 0; + USB->USB_RXMSK_REG = 0; + + USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk | + USB_USB_MAMSK_REG_USB_M_ALT_Msk | + USB_USB_MAMSK_REG_USB_M_WARN_Msk; + USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | + USB_USB_ALTEV_REG_USB_SD3_Msk; + + USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk | USB_USB_MCTRL_REG_USB_NAT_Msk; + + // Select chosen DMA to be triggered by USB. + DMA->DMA_REQ_MUX_REG = (DMA->DMA_REQ_MUX_REG & ~DA146XX_DMA_USB_MUX_MASK) | DA146XX_DMA_USB_MUX; + } +} + +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + + REG_CLR_BIT(USB_MCTRL_REG, USB_NAT); +} + +TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) +{ + return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0; +} + +void tusb_vbus_changed(bool present) +{ + if (present && !_dcd.vbus_present) + { + _dcd.vbus_present = true; + // If power event happened before USB started, delay dcd_connect + // until dcd_init is called. + if (_dcd.init_called) + { + dcd_connect(0); + } + } + else if (!present && _dcd.vbus_present) + { + _dcd.vbus_present = false; + USB->USB_MCTRL_REG = 0; + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, is_in_isr()); + } +} + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void)rhport; + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + EPx_REGS *regs = EPNUM_REGS(epnum); + uint8_t iso_mask = 0; + + TU_ASSERT(epnum < EP_MAX); + + xfer->max_packet_size = tu_edpt_packet_size(desc_edpt); + xfer->ep_addr = desc_edpt->bEndpointAddress; + xfer->data1 = 0; + xfer->iso = 0; + + if (epnum != 0 && desc_edpt->bmAttributes.xfer == 1) + { + iso_mask = USB_USB_EPC1_REG_USB_ISO_Msk; + xfer->iso = 1; + } + + if (epnum == 0) + { + USB->USB_MAMSK_REG |= USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk | + USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk; + } + else + { + if (dir == TUSB_DIR_OUT) + { + regs->epc_out = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask; + USB->USB_RXMSK_REG |= 0x11 << (epnum - 1); + REG_SET_BIT(USB_MAMSK_REG, USB_M_RX_EV); + } + else + { + regs->epc_in = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask; + USB->USB_TXMSK_REG |= 0x11 << (epnum - 1); + REG_SET_BIT(USB_MAMSK_REG, USB_M_TX_EV); + } + } + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + + for (int epnum = 1; epnum < EP_MAX; ++epnum) + { + dcd_edpt_close(0, epnum | TUSB_DIR_OUT); + dcd_edpt_close(0, epnum | TUSB_DIR_IN); + } +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + EPx_REGS *regs = EPNUM_REGS(epnum); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + + (void)rhport; + + TU_ASSERT(epnum < EP_MAX,); + + if (epnum == 0) + { + USB->USB_MAMSK_REG &= ~(USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk | + USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk); + } + else + { + if (dir == TUSB_DIR_OUT) + { + regs->rxc = USB_USB_RXC1_REG_USB_FLUSH_Msk; + regs->epc_out = 0; + USB->USB_RXMSK_REG &= ~(0x11 << (epnum - 1)); + // Release DMA if needed + if (_dcd.dma_ep[TUSB_DIR_OUT] == epnum) + { + RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk; + _dcd.dma_ep[TUSB_DIR_OUT] = 0; + } + } + else + { + regs->txc = USB_USB_TXC1_REG_USB_FLUSH_Msk; + regs->epc_in = 0; + USB->USB_TXMSK_REG &= ~(0x11 << (epnum - 1)); + // Release DMA if needed + if (_dcd.dma_ep[TUSB_DIR_IN] == epnum) + { + TX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA1_CTRL_REG_DMA_ON_Msk; + _dcd.dma_ep[TUSB_DIR_IN] = 0; + } + } + } + tu_memclr(xfer, sizeof(*xfer)); +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + + (void)rhport; + + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->last_packet_size = 0; + xfer->transferred = 0; + + if (dir == TUSB_DIR_OUT) + { + start_rx_packet(xfer); + } + else // IN + { + start_tx_packet(xfer); + } + + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + (void)rhport; + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + EPx_REGS *regs = EPNUM_REGS(epnum); + xfer->stall = 1; + + if (epnum == 0) + { + // EP0 has just one registers to control stall for IN and OUT + REG_SET_BIT(USB_EPC0_REG, USB_STALL); + if (dir == TUSB_DIR_OUT) + { + regs->USB_RXC0_REG = USB_USB_RXC0_REG_USB_RX_EN_Msk; + } + else + { + if (regs->USB_RXC0_REG & USB_USB_RXC0_REG_USB_RX_EN_Msk) + { + // If RX is also enabled TX will not be stalled since RX has + // higher priority. Enable NAK interrupt to handle stall. + REG_SET_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); + } + else + { + regs->USB_TXC0_REG |= USB_USB_TXC0_REG_USB_TX_EN_Msk; + } + } + } + else + { + if (dir == TUSB_DIR_OUT) + { + regs->epc_out |= USB_USB_EPC1_REG_USB_STALL_Msk; + regs->rxc |= USB_USB_RXC1_REG_USB_RX_EN_Msk; + } + else + { + regs->epc_in |= USB_USB_EPC1_REG_USB_STALL_Msk; + regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk | USB_USB_TXC1_REG_USB_LAST_Msk; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + (void)rhport; + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + EPx_REGS *regs = EPNUM_REGS(epnum); + + // Clear stall is called in response to Clear Feature ENDPOINT_HALT, reset toggle + xfer->data1 = 0; + xfer->stall = 0; + + if (dir == TUSB_DIR_OUT) + { + regs->epc_out &= ~USB_USB_EPC1_REG_USB_STALL_Msk; + } + else + { + regs->epc_in &= ~USB_USB_EPC1_REG_USB_STALL_Msk; + } + if (epnum == 0) + { + REG_CLR_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); + } +} + +/*------------------------------------------------------------------*/ +/* Interrupt Handler + *------------------------------------------------------------------*/ + +void dcd_int_handler(uint8_t rhport) +{ + uint32_t int_status = USB->USB_MAEV_REG & USB->USB_MAMSK_REG; + + (void)rhport; + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_WARN)) + { + handle_fifo_warning(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_CH_EV)) + { + // TODO: for now just clear interrupt + (void)USB->USB_CHARGER_STAT_REG; + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_NAK)) + { + handle_ep0_nak(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_RX)) + { + handle_ep0_rx(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_TX)) + { + handle_ep0_tx(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_RX_EV)) + { + handle_rx_ev(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_NAK)) + { + (void)USB->USB_NAKEV_REG; + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_FRAME)) + { + if (_dcd.nfsr == NFSR_NODE_RESET) + { + // During reset FRAME interrupt is enabled to periodically + // check when reset state ends. + // FRAME interrupt is generated every 1ms without host sending + // actual SOF. + check_reset_end(USB_USB_ALTEV_REG_USB_RESET_Msk); + } + else if (_dcd.nfsr == NFSR_NODE_WAKING) + { + // No need to call set_nfsr, just set state + _dcd.nfsr = NFSR_NODE_WAKING2; + } + else if (_dcd.nfsr == NFSR_NODE_WAKING2) + { + // No need to call set_nfsr, just set state + _dcd.nfsr = NFSR_NODE_RESUME; + } + else if (_dcd.nfsr == NFSR_NODE_RESUME) + { + set_nfsr(NFSR_NODE_OPERATIONAL); + } + else + { +#if USE_SOF + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); +#else + // FRAME interrupt was used to re-enable reset detection or remote + // wakeup no need to keep it enabled when USE_SOF is off. + USB->USB_MAMSK_REG &= ~USB_USB_MAMSK_REG_USB_M_FRAME_Msk; +#endif + } + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_TX_EV)) + { + handle_tx_ev(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_ALT)) + { + handle_alt_ev(); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/ehci/ehci.c b/circuitpython/lib/tinyusb/src/portable/ehci/ehci.c new file mode 100644 index 0000000..8d420f2 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/ehci/ehci.c @@ -0,0 +1,900 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && defined(TUP_USBIP_EHCI) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "osal/osal.h" + +#include "host/hcd.h" +#include "ehci_api.h" +#include "ehci.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// Debug level of EHCI +#define EHCI_DBG 2 + +// Framelist size as small as possible to save SRAM +#ifdef TUP_USBIP_CHIPIDEA_HS + // NXP Transdimension: 8 elements + #define FRAMELIST_SIZE_BIT_VALUE 7u + #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) | \ + ((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB)) +#else + // STD EHCI: 256 elements + #define FRAMELIST_SIZE_BIT_VALUE 2u + #define FRAMELIST_SIZE_USBCMD_VALUE ((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) +#endif + +#define FRAMELIST_SIZE (1024 >> FRAMELIST_SIZE_BIT_VALUE) + +#define QHD_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX) +#define QTD_MAX QHD_MAX + +typedef struct +{ + ehci_link_t period_framelist[FRAMELIST_SIZE]; + + // TODO only implement 1 ms & 2 ms & 4 ms, 8 ms (framelist) + // [0] : 1ms, [1] : 2ms, [2] : 4ms, [3] : 8 ms + // TODO better implementation without dummy head to save SRAM + ehci_qhd_t period_head_arr[4]; + + // Note control qhd of dev0 is used as head of async list + struct { + ehci_qhd_t qhd; + ehci_qtd_t qtd; + }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; + + ehci_qhd_t qhd_pool[QHD_MAX]; + ehci_qtd_t qtd_pool[QTD_MAX] TU_ATTR_ALIGNED(32); + + ehci_registers_t* regs; + + volatile uint32_t uframe_number; +}ehci_data_t; + +// Periodic frame list must be 4K alignment +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4096) static ehci_data_t ehci_data; + +//--------------------------------------------------------------------+ +// PROTOTYPE +//--------------------------------------------------------------------+ +static inline ehci_link_t* get_period_head(uint8_t rhport, uint32_t interval_ms) +{ + (void) rhport; + return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ]; +} + +static inline ehci_qhd_t* qhd_control(uint8_t dev_addr) +{ + return &ehci_data.control[dev_addr].qhd; +} + +static inline ehci_qhd_t* qhd_async_head(uint8_t rhport) +{ + (void) rhport; + // control qhd of dev0 is used as async head + return qhd_control(0); +} + +static inline ehci_qtd_t* qtd_control(uint8_t dev_addr) +{ + return &ehci_data.control[dev_addr].qtd; +} + + +static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd); +static inline ehci_qhd_t* qhd_find_free (void); +static inline ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr); + +// determine if a queue head has bus-related error +static inline bool qhd_has_xact_error (ehci_qhd_t * p_qhd) +{ + return (p_qhd->qtd_overlay.buffer_err || p_qhd->qtd_overlay.babble_err || p_qhd->qtd_overlay.xact_err); + //p_qhd->qtd_overlay.non_hs_period_missed_uframe || p_qhd->qtd_overlay.pingstate_err TODO split transaction error +} + +static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc); + +static inline ehci_qtd_t* qtd_find_free (void); +static inline ehci_qtd_t* qtd_next (ehci_qtd_t const * p_qtd); +static inline void qtd_insert_to_qhd (ehci_qhd_t *p_qhd, ehci_qtd_t *p_qtd_new); +static inline void qtd_remove_1st_from_qhd (ehci_qhd_t *p_qhd); +static void qtd_init (ehci_qtd_t* p_qtd, void const* buffer, uint16_t total_bytes); + +static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type); +static inline ehci_link_t* list_next (ehci_link_t *p_link_pointer); + +//--------------------------------------------------------------------+ +// HCD API +//--------------------------------------------------------------------+ + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void) rhport; + return (ehci_data.uframe_number + ehci_data.regs->frame_index) >> 3; +} + +void hcd_port_reset(uint8_t rhport) +{ + (void) rhport; + + ehci_registers_t* regs = ehci_data.regs; + +// regs->portsc_bm.port_enabled = 0; // disable port before reset +// regs->portsc_bm.port_reset = 1; + + uint32_t portsc = regs->portsc; + + portsc &= ~(EHCI_PORTSC_MASK_PORT_EANBLED); + portsc |= EHCI_PORTSC_MASK_PORT_RESET; + + regs->portsc = portsc; +} + +#if 0 +void hcd_port_reset_end(uint8_t rhport) +{ + (void) rhport; + + ehci_registers_t* regs = ehci_data.regs; + regs->portsc_bm.port_reset = 0; +} +#endif + +bool hcd_port_connect_status(uint8_t rhport) +{ + (void) rhport; + return ehci_data.regs->portsc_bm.current_connect_status; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + (void) rhport; + return (tusb_speed_t) ehci_data.regs->portsc_bm.nxp_port_speed; // NXP specific port speed +} + +static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) +{ + for(ehci_link_t* prev = list_head; + !prev->terminate && (tu_align32(prev->address) != (uint32_t) list_head); + prev = list_next(prev) ) + { + // TODO check type for ISO iTD and siTD + // TODO Suppress cast-align warning + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + ehci_qhd_t* qhd = (ehci_qhd_t*) list_next(prev); + #pragma GCC diagnostic pop + if ( qhd->dev_addr == dev_addr ) + { + // TODO deactive all TD, wait for QHD to inactive before removal + prev->address = qhd->next.address; + + // EHCI 4.8.2 link the removed qhd to async head (which always reachable by Host Controller) + qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1); + + if ( qhd->int_smask ) + { + // period list queue element is guarantee to be free in the next frame (1 ms) + qhd->used = 0; + }else + { + // async list use async advance handshake + // mark as removing, will completely re-usable when async advance isr occurs + qhd->removing = 1; + } + } + } +} + +// Close all opened endpoint belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + // skip dev0 + if (dev_addr == 0) return; + + // Remove from async list + list_remove_qhd_by_addr( (ehci_link_t*) qhd_async_head(rhport), dev_addr ); + + // Remove from all interval period list + for(uint8_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++) + { + list_remove_qhd_by_addr( (ehci_link_t*) &ehci_data.period_head_arr[i], dev_addr); + } + + // Async doorbell (EHCI 4.8.2 for operational details) + ehci_data.regs->command_bm.async_adv_doorbell = 1; +} + +bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg) +{ + (void) capability_reg; // not used yet + + tu_memclr(&ehci_data, sizeof(ehci_data_t)); + + ehci_data.regs = (ehci_registers_t* ) operatial_reg; + + ehci_registers_t* regs = ehci_data.regs; + + //------------- CTRLDSSEGMENT Register (skip) -------------// + //------------- USB INT Register -------------// + regs->inten = 0; // 1. disable all the interrupt + regs->status = EHCI_INT_MASK_ALL; // 2. clear all status + + regs->inten = EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | EHCI_INT_MASK_ASYNC_ADVANCE | + EHCI_INT_MASK_NXP_PERIODIC | EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_FRAMELIST_ROLLOVER; + + //------------- Asynchronous List -------------// + ehci_qhd_t * const async_head = qhd_async_head(rhport); + tu_memclr(async_head, sizeof(ehci_qhd_t)); + + async_head->next.address = (uint32_t) async_head; // circular list, next is itself + async_head->next.type = EHCI_QTYPE_QHD; + async_head->head_list_flag = 1; + async_head->qtd_overlay.halted = 1; // inactive most of time + async_head->qtd_overlay.next.terminate = 1; // TODO removed if verified + + regs->async_list_addr = (uint32_t) async_head; + + //------------- Periodic List -------------// + // Build the polling interval tree with 1 ms, 2 ms, 4 ms and 8 ms (framesize) only + for ( uint32_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++ ) + { + ehci_data.period_head_arr[i].int_smask = 1; // queue head in period list must have smask non-zero + ehci_data.period_head_arr[i].qtd_overlay.halted = 1; // dummy node, always inactive + } + + ehci_link_t * const framelist = ehci_data.period_framelist; + ehci_link_t * const period_1ms = get_period_head(rhport, 1u); + + // all links --> period_head_arr[0] (1ms) + // 0, 2, 4, 6 etc --> period_head_arr[1] (2ms) + // 1, 5 --> period_head_arr[2] (4ms) + // 3 --> period_head_arr[3] (8ms) + + // TODO EHCI_FRAMELIST_SIZE with other size than 8 + for(uint32_t i=0; iterminate = 1; + + regs->periodic_list_base = (uint32_t) framelist; + + //------------- TT Control (NXP only) -------------// + regs->nxp_tt_control = 0; + + //------------- USB CMD Register -------------// + regs->command |= TU_BIT(EHCI_USBCMD_POS_RUN_STOP) | TU_BIT(EHCI_USBCMD_POS_ASYNC_ENABLE) | + TU_BIT(EHCI_USBCMD_POS_PERIOD_ENABLE) | // TODO enable period list only there is int/iso endpoint + FRAMELIST_SIZE_USBCMD_VALUE; + + //------------- ConfigFlag Register (skip) -------------// + regs->portsc_bm.port_power = 1; // enable port power + + return true; +} + +#if 0 +static void ehci_stop(uint8_t rhport) +{ + (void) rhport; + + ehci_registers_t* regs = ehci_data.regs; + + regs->command_bm.run_stop = 0; + + // USB Spec: controller has to stop within 16 uframe = 2 frames + while( regs->status_bm.hc_halted == 0 ) {} +} +#endif + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + // TODO not support ISO yet + TU_ASSERT (ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); + + //------------- Prepare Queue Head -------------// + ehci_qhd_t * p_qhd; + + if ( ep_desc->bEndpointAddress == 0 ) + { + p_qhd = qhd_control(dev_addr); + }else + { + p_qhd = qhd_find_free(); + } + TU_ASSERT(p_qhd); + + qhd_init(p_qhd, dev_addr, ep_desc); + + // control of dev0 is always present as async head + if ( dev_addr == 0 ) return true; + + // Insert to list + ehci_link_t * list_head = NULL; + + switch (ep_desc->bmAttributes.xfer) + { + case TUSB_XFER_CONTROL: + case TUSB_XFER_BULK: + list_head = (ehci_link_t*) qhd_async_head(rhport); + break; + + case TUSB_XFER_INTERRUPT: + list_head = get_period_head(rhport, p_qhd->interval_ms); + break; + + case TUSB_XFER_ISOCHRONOUS: + // TODO iso is not supported + break; + + default: break; + } + + TU_ASSERT(list_head); + + // TODO might need to disable async/period list + list_insert(list_head, (ehci_link_t*) p_qhd, EHCI_QTYPE_QHD); + + return true; +} + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void) rhport; + + ehci_qhd_t* qhd = &ehci_data.control[dev_addr].qhd; + ehci_qtd_t* td = &ehci_data.control[dev_addr].qtd; + + qtd_init(td, setup_packet, 8); + td->pid = EHCI_PID_SETUP; + td->int_on_complete = 1; + td->next.terminate = 1; + + // sw region + qhd->p_qtd_list_head = td; + qhd->p_qtd_list_tail = td; + + // attach TD + qhd->qtd_overlay.next.address = (uint32_t) td; + + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if ( epnum == 0 ) + { + ehci_qhd_t* qhd = qhd_control(dev_addr); + ehci_qtd_t* qtd = qtd_control(dev_addr); + + qtd_init(qtd, buffer, buflen); + + // first first data toggle is always 1 (data & setup stage) + qtd->data_toggle = 1; + qtd->pid = dir ? EHCI_PID_IN : EHCI_PID_OUT; + qtd->int_on_complete = 1; + qtd->next.terminate = 1; + + // sw region + qhd->p_qtd_list_head = qtd; + qhd->p_qtd_list_tail = qtd; + + // attach TD + qhd->qtd_overlay.next.address = (uint32_t) qtd; + }else + { + ehci_qhd_t *p_qhd = qhd_get_from_addr(dev_addr, ep_addr); + ehci_qtd_t *p_qtd = qtd_find_free(); + TU_ASSERT(p_qtd); + + qtd_init(p_qtd, buffer, buflen); + p_qtd->pid = p_qhd->pid; + + // Insert TD to QH + qtd_insert_to_qhd(p_qhd, p_qtd); + + p_qhd->p_qtd_list_tail->int_on_complete = 1; + + // attach head QTD to QHD start transferring + p_qhd->qtd_overlay.next.address = (uint32_t) p_qhd->p_qtd_list_head; + } + + return true; +} + +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + ehci_qhd_t *p_qhd = qhd_get_from_addr(dev_addr, ep_addr); + p_qhd->qtd_overlay.halted = 0; + // TODO reset data toggle ? + return true; +} + +//--------------------------------------------------------------------+ +// EHCI Interrupt Handler +//--------------------------------------------------------------------+ + +// async_advance is handshake between usb stack & ehci controller. +// This isr mean it is safe to modify previously removed queue head from async list. +// In tinyusb, queue head is only removed when device is unplugged. +static void async_advance_isr(uint8_t rhport) +{ + (void) rhport; + + ehci_qhd_t* qhd_pool = ehci_data.qhd_pool; + for(uint32_t i = 0; i < QHD_MAX; i++) + { + if ( qhd_pool[i].removing ) + { + qhd_pool[i].removing = 0; + qhd_pool[i].used = 0; + } + } +} + +static void port_connect_status_change_isr(uint8_t rhport) +{ + // NOTE There is an sequence plug->unplug->…..-> plug if device is powering with pre-plugged device + if (ehci_data.regs->portsc_bm.current_connect_status) + { + hcd_port_reset(rhport); + hcd_event_device_attach(rhport, true); + }else // device unplugged + { + hcd_event_device_remove(rhport, true); + } +} + +static void qhd_xfer_complete_isr(ehci_qhd_t * p_qhd) +{ + // free all TDs from the head td to the first active TD + while(p_qhd->p_qtd_list_head != NULL && !p_qhd->p_qtd_list_head->active) + { + ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile) p_qhd->p_qtd_list_head; + bool const is_ioc = (qtd->int_on_complete != 0); + uint8_t const ep_addr = tu_edpt_addr(p_qhd->ep_number, qtd->pid == EHCI_PID_IN ? 1 : 0); + + p_qhd->total_xferred_bytes += qtd->expected_bytes - qtd->total_bytes; + + // TD need to be freed and removed from qhd, before invoking callback + qtd->used = 0; // free QTD + qtd_remove_1st_from_qhd(p_qhd); + + if (is_ioc) + { + hcd_event_xfer_complete(p_qhd->dev_addr, ep_addr, p_qhd->total_xferred_bytes, XFER_RESULT_SUCCESS, true); + p_qhd->total_xferred_bytes = 0; + } + } +} + +static void async_list_xfer_complete_isr(ehci_qhd_t * const async_head) +{ + ehci_qhd_t *p_qhd = async_head; + do + { + if ( !p_qhd->qtd_overlay.halted ) // halted or error is processed in error isr + { + qhd_xfer_complete_isr(p_qhd); + } + p_qhd = qhd_next(p_qhd); + }while(p_qhd != async_head); // async list traversal, stop if loop around +} + +static void period_list_xfer_complete_isr(uint8_t hostid, uint32_t interval_ms) +{ + uint16_t max_loop = 0; + uint32_t const period_1ms_addr = (uint32_t) get_period_head(hostid, 1u); + ehci_link_t next_item = * get_period_head(hostid, interval_ms); + + // TODO abstract max loop guard for period + while( !next_item.terminate && + !(interval_ms > 1 && period_1ms_addr == tu_align32(next_item.address)) && + max_loop < (QHD_MAX + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUH_DEVICE_MAX) + { + switch ( next_item.type ) + { + case EHCI_QTYPE_QHD: + { + ehci_qhd_t *p_qhd_int = (ehci_qhd_t *) tu_align32(next_item.address); + if ( !p_qhd_int->qtd_overlay.halted ) + { + qhd_xfer_complete_isr(p_qhd_int); + } + } + break; + + case EHCI_QTYPE_ITD: // TODO support hs/fs ISO + case EHCI_QTYPE_SITD: + case EHCI_QTYPE_FSTN: + + default: break; + } + + next_item = *list_next(&next_item); + max_loop++; + } +} + +static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd) +{ + if ( (p_qhd->dev_addr != 0 && p_qhd->qtd_overlay.halted) || // addr0 cannot be protocol STALL + qhd_has_xact_error(p_qhd) ) + { + // current qhd has error in transaction + xfer_result_t error_event; + + // no error bits are set, endpoint is halted due to STALL + error_event = qhd_has_xact_error(p_qhd) ? XFER_RESULT_FAILED : XFER_RESULT_STALLED; + + p_qhd->total_xferred_bytes += p_qhd->p_qtd_list_head->expected_bytes - p_qhd->p_qtd_list_head->total_bytes; + +// if ( XFER_RESULT_FAILED == error_event ) TU_BREAKPOINT(); // TODO skip unplugged device + + p_qhd->p_qtd_list_head->used = 0; // free QTD + qtd_remove_1st_from_qhd(p_qhd); + + if ( 0 == p_qhd->ep_number ) + { + // control cannot be halted --> clear all qtd list + p_qhd->p_qtd_list_head = NULL; + p_qhd->p_qtd_list_tail = NULL; + + p_qhd->qtd_overlay.next.terminate = 1; + p_qhd->qtd_overlay.alternate.terminate = 1; + p_qhd->qtd_overlay.halted = 0; + + ehci_qtd_t *p_setup = qtd_control(p_qhd->dev_addr); + p_setup->used = 0; + } + + // call USBH callback + hcd_event_xfer_complete(p_qhd->dev_addr, tu_edpt_addr(p_qhd->ep_number, p_qhd->pid == EHCI_PID_IN ? 1 : 0), p_qhd->total_xferred_bytes, error_event, true); + + p_qhd->total_xferred_bytes = 0; + } +} + +static void xfer_error_isr(uint8_t hostid) +{ + //------------- async list -------------// + ehci_qhd_t * const async_head = qhd_async_head(hostid); + ehci_qhd_t *p_qhd = async_head; + do + { + qhd_xfer_error_isr( p_qhd ); + p_qhd = qhd_next(p_qhd); + }while(p_qhd != async_head); // async list traversal, stop if loop around + + //------------- TODO refractor period list -------------// + uint32_t const period_1ms_addr = (uint32_t) get_period_head(hostid, 1u); + for (uint32_t interval_ms=1; interval_ms <= FRAMELIST_SIZE; interval_ms *= 2) + { + ehci_link_t next_item = * get_period_head(hostid, interval_ms); + + // TODO abstract max loop guard for period + while( !next_item.terminate && + !(interval_ms > 1 && period_1ms_addr == tu_align32(next_item.address)) ) + { + switch ( next_item.type ) + { + case EHCI_QTYPE_QHD: + { + ehci_qhd_t *p_qhd_int = (ehci_qhd_t *) tu_align32(next_item.address); + qhd_xfer_error_isr(p_qhd_int); + } + break; + + // TODO support hs/fs ISO + case EHCI_QTYPE_ITD: + case EHCI_QTYPE_SITD: + case EHCI_QTYPE_FSTN: + default: break; + } + + next_item = *list_next(&next_item); + } + } +} + +//------------- Host Controller Driver's Interrupt Handler -------------// +void hcd_int_handler(uint8_t rhport) +{ + ehci_registers_t* regs = ehci_data.regs; + + uint32_t int_status = regs->status; + int_status &= regs->inten; + + regs->status = int_status; // Acknowledge handled interrupt + + if (int_status == 0) return; + + if (int_status & EHCI_INT_MASK_FRAMELIST_ROLLOVER) + { + ehci_data.uframe_number += (FRAMELIST_SIZE << 3); + } + + if (int_status & EHCI_INT_MASK_PORT_CHANGE) + { + uint32_t port_status = regs->portsc & EHCI_PORTSC_MASK_ALL; + + TU_LOG_HEX(EHCI_DBG, regs->portsc); + + if (regs->portsc_bm.connect_status_change) + { + port_connect_status_change_isr(rhport); + } + + regs->portsc |= port_status; // Acknowledge change bits in portsc + } + + if (int_status & EHCI_INT_MASK_ERROR) + { + xfer_error_isr(rhport); + } + + //------------- some QTD/SITD/ITD with IOC set is completed -------------// + if (int_status & EHCI_INT_MASK_NXP_ASYNC) + { + async_list_xfer_complete_isr( qhd_async_head(rhport) ); + } + + if (int_status & EHCI_INT_MASK_NXP_PERIODIC) + { + for (uint32_t i=1; i <= FRAMELIST_SIZE; i *= 2) + { + period_list_xfer_complete_isr( rhport, i ); + } + } + + //------------- There is some removed async previously -------------// + if (int_status & EHCI_INT_MASK_ASYNC_ADVANCE) // need to place after EHCI_INT_MASK_NXP_ASYNC + { + async_advance_isr(rhport); + } +} + +//--------------------------------------------------------------------+ +// HELPER +//--------------------------------------------------------------------+ + + +//------------- queue head helper -------------// +static inline ehci_qhd_t* qhd_find_free (void) +{ + for (uint32_t i=0; inext.address); +} + +static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) +{ + ehci_qhd_t* qhd_pool = ehci_data.qhd_pool; + + for(uint32_t i=0; inext.address); +} + +static inline void qtd_remove_1st_from_qhd(ehci_qhd_t *p_qhd) +{ + if (p_qhd->p_qtd_list_head == p_qhd->p_qtd_list_tail) // last TD --> make it NULL + { + p_qhd->p_qtd_list_head = p_qhd->p_qtd_list_tail = NULL; + }else + { + p_qhd->p_qtd_list_head = qtd_next( p_qhd->p_qtd_list_head ); + } +} + +static inline void qtd_insert_to_qhd(ehci_qhd_t *p_qhd, ehci_qtd_t *p_qtd_new) +{ + if (p_qhd->p_qtd_list_head == NULL) // empty list + { + p_qhd->p_qtd_list_head = p_qhd->p_qtd_list_tail = p_qtd_new; + }else + { + p_qhd->p_qtd_list_tail->next.address = (uint32_t) p_qtd_new; + p_qhd->p_qtd_list_tail = p_qtd_new; + } +} + +static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + // address 0 is used as async head, which always on the list --> cannot be cleared (ehci halted otherwise) + if (dev_addr != 0) + { + tu_memclr(p_qhd, sizeof(ehci_qhd_t)); + } + + hcd_devtree_info_t devtree_info; + hcd_devtree_get_info(dev_addr, &devtree_info); + + uint8_t const xfer_type = ep_desc->bmAttributes.xfer; + uint8_t const interval = ep_desc->bInterval; + + p_qhd->dev_addr = dev_addr; + p_qhd->fl_inactive_next_xact = 0; + p_qhd->ep_number = tu_edpt_number(ep_desc->bEndpointAddress); + p_qhd->ep_speed = devtree_info.speed; + p_qhd->data_toggle_control= (xfer_type == TUSB_XFER_CONTROL) ? 1 : 0; + p_qhd->head_list_flag = (dev_addr == 0) ? 1 : 0; // addr0's endpoint is the static asyn list head + p_qhd->max_packet_size = tu_edpt_packet_size(ep_desc); + p_qhd->fl_ctrl_ep_flag = ((xfer_type == TUSB_XFER_CONTROL) && (p_qhd->ep_speed != TUSB_SPEED_HIGH)) ? 1 : 0; + p_qhd->nak_reload = 0; + + // Bulk/Control -> smask = cmask = 0 + // TODO Isochronous + if (TUSB_XFER_INTERRUPT == xfer_type) + { + if (TUSB_SPEED_HIGH == p_qhd->ep_speed) + { + TU_ASSERT( interval <= 16, ); + if ( interval < 4) // sub milisecond interval + { + p_qhd->interval_ms = 0; + p_qhd->int_smask = (interval == 1) ? TU_BIN8(11111111) : + (interval == 2) ? TU_BIN8(10101010) : TU_BIN8(01000100); + }else + { + p_qhd->interval_ms = (uint8_t) tu_min16( 1 << (interval-4), 255 ); + p_qhd->int_smask = TU_BIT(interval % 8); + } + }else + { + TU_ASSERT( 0 != interval, ); + // Full/Low: 4.12.2.1 (EHCI) case 1 schedule start split at 1 us & complete split at 2,3,4 uframes + p_qhd->int_smask = 0x01; + p_qhd->fl_int_cmask = TU_BIN8(11100); + p_qhd->interval_ms = interval; + } + }else + { + p_qhd->int_smask = p_qhd->fl_int_cmask = 0; + } + + p_qhd->fl_hub_addr = devtree_info.hub_addr; + p_qhd->fl_hub_port = devtree_info.hub_port; + p_qhd->mult = 1; // TODO not use high bandwidth/park mode yet + + //------------- HCD Management Data -------------// + p_qhd->used = 1; + p_qhd->removing = 0; + p_qhd->p_qtd_list_head = NULL; + p_qhd->p_qtd_list_tail = NULL; + p_qhd->pid = tu_edpt_dir(ep_desc->bEndpointAddress) ? EHCI_PID_IN : EHCI_PID_OUT; // PID for TD under this endpoint + + //------------- active, but no TD list -------------// + p_qhd->qtd_overlay.halted = 0; + p_qhd->qtd_overlay.next.terminate = 1; + p_qhd->qtd_overlay.alternate.terminate = 1; + if (TUSB_XFER_BULK == xfer_type && p_qhd->ep_speed == TUSB_SPEED_HIGH && p_qhd->pid == EHCI_PID_OUT) + { + p_qhd->qtd_overlay.ping_err = 1; // do PING for Highspeed Bulk OUT, EHCI section 4.11 + } +} + +static void qtd_init(ehci_qtd_t* p_qtd, void const* buffer, uint16_t total_bytes) +{ + tu_memclr(p_qtd, sizeof(ehci_qtd_t)); + + p_qtd->used = 1; + + p_qtd->next.terminate = 1; // init to null + p_qtd->alternate.terminate = 1; // not used, always set to terminated + p_qtd->active = 1; + p_qtd->err_count = 3; // TODO 3 consecutive errors tolerance + p_qtd->data_toggle = 0; + p_qtd->total_bytes = total_bytes; + p_qtd->expected_bytes = total_bytes; + + p_qtd->buffer[0] = (uint32_t) buffer; + for(uint8_t i=1; i<5; i++) + { + p_qtd->buffer[i] |= tu_align4k( p_qtd->buffer[i-1] ) + 4096; + } +} + +//------------- List Managing Helper -------------// +static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type) +{ + new->address = current->address; + current->address = ((uint32_t) new) | (new_type << 1); +} + +static inline ehci_link_t* list_next(ehci_link_t *p_link_pointer) +{ + return (ehci_link_t*) tu_align32(p_link_pointer->address); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/ehci/ehci.h b/circuitpython/lib/tinyusb/src/portable/ehci/ehci.h new file mode 100644 index 0000000..ff9ae12 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/ehci/ehci.h @@ -0,0 +1,420 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_EHCI_H_ +#define _TUSB_EHCI_H_ + + +/* Abbreviation + * HC: Host Controller + * HCD: Host Controller Driver + * QHD: Queue Head for non-ISO transfer + * QTD: Queue Transfer Descriptor for non-ISO transfer + * ITD: Iso Transfer Descriptor for highspeed + * SITD: Split ISO Transfer Descriptor for full-speed + * SMASK: Start Split mask for Slipt Transaction + * CMASK: Complete Split mask for Slipt Transaction +*/ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// EHCI CONFIGURATION & CONSTANTS +//--------------------------------------------------------------------+ + +// TODO merge OHCI with EHCI +enum { + EHCI_MAX_ITD = 4, + EHCI_MAX_SITD = 16 +}; + +//--------------------------------------------------------------------+ +// EHCI Data Structure +//--------------------------------------------------------------------+ +enum +{ + EHCI_QTYPE_ITD = 0 , + EHCI_QTYPE_QHD , + EHCI_QTYPE_SITD , + EHCI_QTYPE_FSTN +}; + +/// EHCI PID +enum +{ + EHCI_PID_OUT = 0 , + EHCI_PID_IN , + EHCI_PID_SETUP +}; + +/// Link pointer +typedef union { + uint32_t address; + struct { + uint32_t terminate : 1; + uint32_t type : 2; + }; +}ehci_link_t; + +/// Queue Element Transfer Descriptor +/// Qtd is used to declare overlay in ehci_qhd_t -> cannot be declared with TU_ATTR_ALIGNED(32) +typedef struct +{ + // Word 0: Next QTD Pointer + ehci_link_t next; + + // Word 1: Alternate Next QTD Pointer (not used) + union{ + ehci_link_t alternate; + struct { + uint32_t : 5; + uint32_t used : 1; + uint32_t : 10; + uint32_t expected_bytes : 16; + }; + }; + + // Word 2: qTQ Token + volatile uint32_t ping_err : 1 ; ///< For Highspeed: 0 Out, 1 Ping. Full/Slow used as error indicator + volatile uint32_t non_hs_split_state : 1 ; ///< Used by HC to track the state of split transaction + volatile uint32_t non_hs_missed_uframe : 1 ; ///< HC misses a complete split transaction + volatile uint32_t xact_err : 1 ; ///< Error (Timeout, CRC, Bad PID ... ) + volatile uint32_t babble_err : 1 ; ///< Babble detected, also set Halted bit to 1 + volatile uint32_t buffer_err : 1 ; ///< Data overrun/underrun error + volatile uint32_t halted : 1 ; ///< Serious error or STALL received + volatile uint32_t active : 1 ; ///< Start transfer, clear by HC when complete + + uint32_t pid : 2 ; ///< 0: OUT, 1: IN, 2 Setup + volatile uint32_t err_count : 2 ; ///< Error Counter of consecutive errors + volatile uint32_t current_page : 3 ; ///< Index into the qTD buffer pointer list + uint32_t int_on_complete : 1 ; ///< Interrupt on complete + volatile uint32_t total_bytes : 15 ; ///< Transfer bytes, decreased during transaction + volatile uint32_t data_toggle : 1 ; ///< Data Toogle bit + + + /// Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page + uint32_t buffer[5]; +} ehci_qtd_t; + +TU_VERIFY_STATIC( sizeof(ehci_qtd_t) == 32, "size is not correct" ); + +/// Queue Head +typedef struct TU_ATTR_ALIGNED(32) +{ + // Word 0: Next QHD + ehci_link_t next; + + // Word 1: Endpoint Characteristics + uint32_t dev_addr : 7 ; ///< device address + uint32_t fl_inactive_next_xact : 1 ; ///< Only valid for Periodic with Full/Slow speed + uint32_t ep_number : 4 ; ///< EP number + uint32_t ep_speed : 2 ; ///< 0: Full, 1: Low, 2: High + uint32_t data_toggle_control : 1 ; ///< 0: use DT in qHD, 1: use DT in qTD + uint32_t head_list_flag : 1 ; ///< Head of the queue + uint32_t max_packet_size : 11 ; ///< Max packet size + uint32_t fl_ctrl_ep_flag : 1 ; ///< 1 if is Full/Low speed control endpoint + uint32_t nak_reload : 4 ; ///< Used by HC + + // Word 2: Endpoint Capabilities + uint32_t int_smask : 8 ; ///< Interrupt Schedule Mask + uint32_t fl_int_cmask : 8 ; ///< Split Completion Mask for Full/Slow speed + uint32_t fl_hub_addr : 7 ; ///< Hub Address for Full/Slow speed + uint32_t fl_hub_port : 7 ; ///< Hub Port for Full/Slow speed + uint32_t mult : 2 ; ///< Transaction per micro frame + + // Word 3: Current qTD Pointer + volatile uint32_t qtd_addr; + + // Word 4-11: Transfer Overlay + volatile ehci_qtd_t qtd_overlay; + + //--------------------------------------------------------------------+ + /// Due to the fact QHD is 32 bytes aligned but occupies only 48 bytes + /// thus there are 16 bytes padding free that we can make use of. + //--------------------------------------------------------------------+ + uint8_t used; + uint8_t removing; // removed from asyn list, waiting for async advance + uint8_t pid; + uint8_t interval_ms; // polling interval in frames (or milisecond) + + uint16_t total_xferred_bytes; // number of bytes xferred until a qtd with ioc bit set + uint8_t reserved2[2]; + + ehci_qtd_t * volatile p_qtd_list_head; // head of the scheduled TD list + ehci_qtd_t * volatile p_qtd_list_tail; // tail of the scheduled TD list +} ehci_qhd_t; + +TU_VERIFY_STATIC( sizeof(ehci_qhd_t) == 64, "size is not correct" ); + +/// Highspeed Isochronous Transfer Descriptor (section 3.3) +typedef struct TU_ATTR_ALIGNED(32) { + // Word 0: Next Link Pointer + ehci_link_t next; + + // Word 1-8: iTD Transaction Status and Control List + struct { + // iTD Control + volatile uint32_t offset : 12 ; ///< This field is a value that is an offset, expressed in bytes, from the beginning of a buffer. + volatile uint32_t page_select : 3 ; ///< These bits are set by software to indicate which of the buffer page pointers the offset field in this slot should be concatenated to produce the starting memory address for this transaction. The valid range of values for this field is 0 to 6 + uint32_t int_on_complete : 1 ; ///< If this bit is set to a one, it specifies that when this transaction completes, the Host Controller should issue an interrupt at the next interrupt threshold + volatile uint32_t length : 12 ; ///< For an OUT, this field is the number of data bytes the host controller will send during the transaction. The host controller is not required to update this field to reflect the actual number of bytes transferred during the transfer + ///< For an IN, the initial value of the field is the number of bytes the host expects the endpoint to deliver. During the status update, the host controller writes back the number of bytes successfully received. The value in this register is the actual byte count + // iTD Status + volatile uint32_t error : 1 ; ///< Set to a one by the Host Controller during status update in the case where the host did not receive a valid response from the device (Timeout, CRC, Bad PID, etc.). This bit may only be set for isochronous IN transactions. + volatile uint32_t babble_err : 1 ; ///< Set to a 1 by the Host Controller during status update when a babble is detected during the transaction + volatile uint32_t buffer_err : 1 ; ///< Set to a 1 by the Host Controller during status update to indicate that the Host Controller is unable to keep up with the reception of incoming data (overrun) or is unable to supply data fast enough during transmission (underrun). + volatile uint32_t active : 1 ; ///< Set to 1 by software to enable the execution of an isochronous transaction by the Host Controller + } xact[8]; + + // Word 9-15 Buffer Page Pointer List (Plus) + uint32_t BufferPointer[7]; + +// // FIXME: Store meta data into buffer pointer reserved for saving memory +// /*---------- HCD Area ----------*/ +// uint32_t used; +// uint32_t IhdIdx; +// uint32_t reserved[6]; +} ehci_itd_t; + +TU_VERIFY_STATIC( sizeof(ehci_itd_t) == 64, "size is not correct" ); + +/// Split (Full-Speed) Isochronous Transfer Descriptor +typedef struct TU_ATTR_ALIGNED(32) +{ + // Word 0: Next Link Pointer + ehci_link_t next; + + // Word 1: siTD Endpoint Characteristics + uint32_t dev_addr : 7; ///< This field selects the specific device serving as the data source or sink. + uint32_t : 1; ///< reserved + uint32_t ep_number : 4; ///< This 4-bit field selects the particular endpoint number on the device serving as the data source or sink. + uint32_t : 4; ///< This field is reserved and should be set to zero. + uint32_t hub_addr : 7; ///< This field holds the device address of the transaction translators’ hub. + uint32_t : 1; ///< reserved + uint32_t port_number : 7; ///< This field is the port number of the recipient transaction translator. + uint32_t direction : 1; ///< 0 = OUT; 1 = IN. This field encodes whether the full-speed transaction should be an IN or OUT. + + // Word 2: Micro-frame Schedule Control + uint8_t int_smask ; ///< This field (along with the Activeand SplitX-statefields in the Statusbyte) are used to determine during which micro-frames the host controller should execute complete-split transactions + uint8_t fl_int_cmask; ///< This field (along with the Activeand SplitX-statefields in the Statusbyte) are used to determine during which micro-frames the host controller should execute start-split transactions. + uint16_t reserved ; ///< reserved + + // Word 3: siTD Transfer Status and Control + // Status [7:0] TODO indentical to qTD Token'status --> refractor later + volatile uint32_t : 1 ; // reserved + volatile uint32_t split_state : 1 ; + volatile uint32_t missed_uframe : 1 ; + volatile uint32_t xact_err : 1 ; + volatile uint32_t babble_err : 1 ; + volatile uint32_t buffer_err : 1 ; + volatile uint32_t error : 1 ; + volatile uint32_t active : 1 ; + // Micro-frame Schedule Control + volatile uint32_t cmask_progress : 8 ; ///< This field is used by the host controller to record which split-completes have been executed. See Section 4.12.3.3.2 for behavioral requirements. + volatile uint32_t total_bytes : 10 ; ///< This field is initialized by software to the total number of bytes expected in this transfer. Maximum value is 1023 + volatile uint32_t : 4 ; ///< reserved + volatile uint32_t page_select : 1 ; ///< Used to indicate which data page pointer should be concatenated with the CurrentOffsetfield to construct a data buffer pointer + uint32_t int_on_complete : 1 ; ///< Do not interrupt when transaction is complete. 1 = Do interrupt when transaction is complete + uint32_t : 0 ; // padding to the end of current storage unit + + /// Word 4-5: Buffer Pointer List + uint32_t buffer[2]; // buffer[1] TP: Transaction Position - T-Count: Transaction Count + +// union{ +// uint32_t BufferPointer1; +// struct { +// volatile uint32_t TCount : 3; +// volatile uint32_t TPosition : 2; +// }; +// }; + + /*---------- Word 6 ----------*/ + ehci_link_t back; + + /// SITD is 32-byte aligned but occupies only 28 --> 4 bytes for storing extra data + uint8_t used; + uint8_t ihd_idx; + uint8_t reserved2[2]; +} ehci_sitd_t; + +TU_VERIFY_STATIC( sizeof(ehci_sitd_t) == 32, "size is not correct" ); + +//--------------------------------------------------------------------+ +// EHCI Operational Register +//--------------------------------------------------------------------+ +enum ehci_interrupt_mask_{ + EHCI_INT_MASK_USB = TU_BIT(0), + EHCI_INT_MASK_ERROR = TU_BIT(1), + EHCI_INT_MASK_PORT_CHANGE = TU_BIT(2), + + EHCI_INT_MASK_FRAMELIST_ROLLOVER = TU_BIT(3), + EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR = TU_BIT(4), + EHCI_INT_MASK_ASYNC_ADVANCE = TU_BIT(5), + EHCI_INT_MASK_NXP_SOF = TU_BIT(7), + + EHCI_INT_MASK_NXP_ASYNC = TU_BIT(18), + EHCI_INT_MASK_NXP_PERIODIC = TU_BIT(19), + + EHCI_INT_MASK_ALL = + EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | + EHCI_INT_MASK_FRAMELIST_ROLLOVER | EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR | + EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF | + EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC +}; + +enum ehci_usbcmd_pos_ { + EHCI_USBCMD_POS_RUN_STOP = 0, + EHCI_USBCMD_POS_FRAMELIST_SIZE = 2, + EHCI_USBCMD_POS_PERIOD_ENABLE = 4, + EHCI_USBCMD_POS_ASYNC_ENABLE = 5, + EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB = 15, + EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16 +}; + +enum ehci_portsc_change_mask_{ + EHCI_PORTSC_MASK_CURRENT_CONNECT_STATUS = TU_BIT(0), + EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE = TU_BIT(1), + EHCI_PORTSC_MASK_PORT_EANBLED = TU_BIT(2), + EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE = TU_BIT(3), + EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE = TU_BIT(5), + EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8), + + EHCI_PORTSC_MASK_ALL = + EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE | + EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE | + EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE +}; + +typedef volatile struct +{ + union { + uint32_t command; + + struct { + uint32_t run_stop : 1 ; ///< 1=Run. 0=Stop + uint32_t reset : 1 ; ///< SW write 1 to reset HC, clear by HC when complete + uint32_t framelist_size : 2 ; ///< Frame List size 0: 1024, 1: 512, 2: 256 + uint32_t periodic_enable : 1 ; ///< This bit controls whether the host controller skips processing the Periodic Schedule. Values mean: 0b Do not process the Periodic Schedule 1b Use the PERIODICLISTBASE register to access the Periodic Schedule. + uint32_t async_enable : 1 ; ///< This bit controls whether the host controller skips processing the Asynchronous Schedule. Values mean: 0b Do not process the Asynchronous Schedule 1b Use the ASYNCLISTADDR register to access the Asynchronous Schedule. + uint32_t async_adv_doorbell : 1 ; ///< Tell HC to interrupt next time it advances async list. Clear by HC + uint32_t light_reset : 1 ; ///< Reset HC without affecting ports state + uint32_t async_park_count : 2 ; ///< not used by tinyusb + uint32_t : 1 ; + uint32_t async_park_enable : 1 ; ///< Enable park mode, not used by tinyusb + uint32_t : 3 ; + uint32_t nxp_framelist_size_msb : 1 ; ///< NXP customized : Bit 2 of the Frame List Size bits \n 011b: 128 elements \n 100b: 64 elements \n 101b: 32 elements \n 110b: 16 elements \n 111b: 8 elements + uint32_t int_threshold : 8 ; ///< Default 08h. Interrupt rate in unit of micro frame + }command_bm; + }; + + union { + uint32_t status; + + struct { + uint32_t usb : 1 ; ///< qTD with IOC is retired + uint32_t usb_error : 1 ; ///< qTD retired due to error + uint32_t port_change_detect : 1 ; ///< Set when PortOwner or ForcePortResume change from 0 -> 1 + uint32_t framelist_rollover : 1 ; ///< R/WC The Host Controller sets this bit to a one when the Frame List Index(see Section 2.3.4) rolls over from its maximum value to zero. The exact value at which the rollover occurs depends on the frame list size. For example, if the frame list size (as programmed in the Frame List Sizefield of the USBCMD register) is 1024, the Frame Index Registerrolls over every time FRINDEX[13] toggles. Similarly, if the size is 512, the Host Controller sets this bit to a one every time FRINDEX[12] toggles. + uint32_t pci_host_system_error : 1 ; ///< R/WC (not used by NXP) The Host Controller sets this bit to 1 when a serious error occurs during a host system access involving the Host Controller module. In a PCI system, conditions that set this bit to 1 include PCI Parity error, PCI Master Abort, and PCI Target Abort. When this error occurs, the Host Controller clears the Run/Stop bit in the Command register to prevent further execution of the scheduled TDs. + uint32_t async_adv : 1 ; ///< Async Advance interrupt + uint32_t : 1 ; + uint32_t nxp_int_sof : 1 ; ///< NXP customized: this bit will be set every 125us and can be used by host controller driver as a time base. + uint32_t : 4 ; + uint32_t hc_halted : 1 ; ///< Opposite value to run_stop bit. + uint32_t reclamation : 1 ; ///< Used to detect empty async shecudle + uint32_t periodic_status : 1 ; ///< Periodic schedule status + uint32_t async_status : 1 ; ///< Async schedule status + uint32_t : 2 ; + uint32_t nxp_int_async : 1 ; ///< NXP customized: This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set andthe TD was from the asynchronous schedule. This bit is also set by the Host when a short packet is detected andthe packet is on the asynchronous schedule. + uint32_t nxp_int_period : 1 ; ///< NXP customized: This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set andthe TD was from the periodic schedule. + uint32_t : 12 ; + }status_bm; + }; + + union{ + uint32_t inten; + + struct { + uint32_t usb : 1 ; + uint32_t usb_error : 1 ; + uint32_t port_change_detect : 1 ; + uint32_t framelist_rollover : 1 ; + uint32_t pci_host_system_error : 1 ; + uint32_t async_adv : 1 ; + uint32_t : 1 ; + uint32_t nxp_int_sof : 1 ; + uint32_t : 10 ; + uint32_t nxp_int_async : 1 ; + uint32_t nxp_int_period : 1 ; + uint32_t : 12 ; + }inten_bm; + }; + + uint32_t frame_index ; ///< Micro frame counter + uint32_t ctrl_ds_seg ; ///< Control Data Structure Segment + uint32_t periodic_list_base ; ///< Beginning address of perodic frame list + uint32_t async_list_addr ; ///< Address of next async QHD to be executed + uint32_t nxp_tt_control ; ///< nxp embedded transaction translator (reserved by EHCI specs) + uint32_t reserved[8] ; + uint32_t config_flag ; ///< not used by NXP + + union { + uint32_t portsc ; ///< port status and control + struct { + uint32_t current_connect_status : 1; ///< 0: No device, 1: Device is present on port + uint32_t connect_status_change : 1; ///< Change in Current Connect Status + uint32_t port_enabled : 1; ///< Ports can only be enabled by HC as a part of the reset and enable. SW can write 0 to disable + uint32_t port_enable_change : 1; ///< Port Enabled has changed + uint32_t over_current_active : 1; ///< Port has an over-current condition + uint32_t over_current_change : 1; ///< Change to Over-current Active + uint32_t force_port_resume : 1; ///< Resume detected/driven on port. This functionality defined for manipulating this bit depends on the value of the Suspend bit. + uint32_t suspend : 1; ///< Port in suspend state + uint32_t port_reset : 1; ///< 1=Port is in Reset. 0=Port is not in Reset + uint32_t nxp_highspeed_status : 1; ///< NXP customized: 0=connected to the port is not in High-speed mode, 1=connected to the port is in High-speed mode + uint32_t line_status : 2; ///< D+/D- state: 00: SE0, 10: J-state, 01: K-state + uint32_t port_power : 1; ///< 0= power off, 1= power on + uint32_t port_owner : 1; ///< not used by NXP + uint32_t port_indicator_control : 2; ///< 00b: off, 01b: Amber, 10b: green, 11b: undefined + uint32_t port_test_control : 4; ///< Port test mode, not used by tinyusb + uint32_t wake_on_connect_enable : 1; ///< Enables device connects as wake-up events + uint32_t wake_on_disconnect_enable : 1; ///< Enables device disconnects as wake-up events + uint32_t wake_on_over_current_enable : 1; ///< Enables over-current conditions as wake-up events + uint32_t nxp_phy_clock_disable : 1; ///< NXP customized: the PHY can be put into Low Power Suspend – Clock Disable when the downstream device has been put into suspend mode or when no downstream device is connected. Low power suspend is completely under the control of software. 0: enable PHY clock, 1: disable PHY clock + uint32_t nxp_port_force_fullspeed : 1; ///< NXP customized: Writing this bit to a 1 will force the port to only connect at Full Speed. It disables the chirp sequence that allowsthe port to identify itself as High Speed. This is useful for testing FS configurations with a HS host, hub or device. + uint32_t TU_RESERVED : 1; + uint32_t nxp_port_speed : 2; ///< NXP customized: This register field indicates the speed atwhich the port is operating. For HS mode operation in the host controllerand HS/FS operation in the device controller the port routing steers data to the Protocol engine. For FS and LS mode operation in the host controller, the port routing steers data to the Protocol Engine w/ Embedded Transaction Translator. 0x0: Fullspeed, 0x1: Lowspeed, 0x2: Highspeed + uint32_t TU_RESERVED : 4; + }portsc_bm; + }; +}ehci_registers_t; + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_EHCI_H_ */ diff --git a/circuitpython/lib/tinyusb/src/portable/ehci/ehci_api.h b/circuitpython/lib/tinyusb/src/portable/ehci/ehci_api.h new file mode 100644 index 0000000..12e0a73 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/ehci/ehci_api.h @@ -0,0 +1,45 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_EHCI_API_H_ +#define _TUSB_EHCI_API_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// API Implemented by EHCI +//--------------------------------------------------------------------+ + +// Initialize EHCI driver +bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c b/circuitpython/lib/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c new file mode 100644 index 0000000..bd8805d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -0,0 +1,853 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Additions Copyright (c) 2020, Espressif Systems (Shanghai) Co. Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED) + +// Espressif +#include "freertos/xtensa_api.h" +#include "esp_intr_alloc.h" +#include "esp_log.h" +#include "soc/dport_reg.h" +#include "soc/gpio_sig_map.h" +#include "soc/usb_periph.h" +#include "soc/periph_defs.h" // for interrupt source + +#include "device/dcd.h" + +// Max number of bi-directional endpoints including EP0 +// Note: ESP32S2 specs say there are only up to 5 IN active endpoints include EP0 +// We should probably prohibit enabling Endpoint IN > 4 (not done yet) +#define EP_MAX USB_OUT_EP_NUM + +// FIFO size in bytes +#define EP_FIFO_SIZE 1024 + +// Max number of IN EP FIFOs +#define EP_FIFO_NUM 5 + +typedef struct { + uint8_t *buffer; + // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API + uint16_t total_len; + uint16_t queued_len; + uint16_t max_size; + bool short_packet; +} xfer_ctl_t; + +static const char *TAG = "TUSB:DCD"; +static intr_handle_t usb_ih; + + +static uint32_t _setup_packet[2]; + +#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] +static xfer_ctl_t xfer_status[EP_MAX][2]; + +// Keep count of how many FIFOs are in use +static uint8_t _allocated_fifos = 1; //FIFO0 is always in use + +// Will either return an unused FIFO number, or 0 if all are used. +static uint8_t get_free_fifo(void) +{ + if (_allocated_fifos < EP_FIFO_NUM) return _allocated_fifos++; + return 0; +} + +// Setup the control endpoint 0. +static void bus_reset(void) +{ + for (int ep_num = 0; ep_num < USB_OUT_EP_NUM; ep_num++) { + USB0.out_ep_reg[ep_num].doepctl |= USB_DO_SNAK0_M; // DOEPCTL0_SNAK + } + + // clear device address + USB0.dcfg &= ~USB_DEVADDR_M; + + USB0.daintmsk = USB_OUTEPMSK0_M | USB_INEPMSK0_M; + USB0.doepmsk = USB_SETUPMSK_M | USB_XFERCOMPLMSK; + USB0.diepmsk = USB_TIMEOUTMSK_M | USB_DI_XFERCOMPLMSK_M /*| USB_INTKNTXFEMPMSK_M*/; + + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO MAX | + // --------------- + // | ... | + // --------------- y + x + 16 + GRXFSIZ + // | IN FIFO 2 | + // --------------- x + 16 + GRXFSIZ + // | IN FIFO 1 | + // --------------- 16 + GRXFSIZ + // | IN FIFO 0 | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): + // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN + // + // - All EP OUT shared a unique OUT FIFO which uses + // * 10 locations in hardware for setup packets + setup control words (up to 3 setup packets). + // * 2 locations for OUT endpoint control words. + // * 16 for largest packet size of 64 bytes. ( TODO Highspeed is 512 bytes) + // * 1 location for global NAK (not required/used here). + // * It is recommended to allocate 2 times the largest packet size, therefore + // Recommended value = 10 + 1 + 2 x (16+2) = 47 --> Let's make it 52 + USB0.grstctl |= 0x10 << USB_TXFNUM_S; // fifo 0x10, + USB0.grstctl |= USB_TXFFLSH_M; // Flush fifo + USB0.grxfsiz = 52; + + // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) + USB0.gnptxfsiz = (16 << USB_NPTXFDEP_S) | (USB0.grxfsiz & 0x0000ffffUL); + + // Ready to receive SETUP packet + USB0.out_ep_reg[0].doeptsiz |= USB_SUPCNT0_M; + + USB0.gintmsk |= USB_IEPINTMSK_M | USB_OEPINTMSK_M; +} + +static void enum_done_processing(void) +{ + ESP_EARLY_LOGV(TAG, "dcd_int_handler - Speed enumeration done! Sending DCD_EVENT_BUS_RESET then"); + // On current silicon on the Full Speed core, speed is fixed to Full Speed. + // However, keep for debugging and in case Low Speed is ever supported. + uint32_t enum_spd = (USB0.dsts >> USB_ENUMSPD_S) & (USB_ENUMSPD_V); + + // Maximum packet size for EP 0 is set for both directions by writing DIEPCTL + if (enum_spd == 0x03) { // Full-Speed (PHY on 48 MHz) + USB0.in_ep_reg[0].diepctl &= ~USB_D_MPS0_V; // 64 bytes + USB0.in_ep_reg[0].diepctl &= ~USB_D_STALL0_M; // clear Stall + xfer_status[0][TUSB_DIR_OUT].max_size = 64; + xfer_status[0][TUSB_DIR_IN].max_size = 64; + } else { + USB0.in_ep_reg[0].diepctl |= USB_D_MPS0_V; // 8 bytes + USB0.in_ep_reg[0].diepctl &= ~USB_D_STALL0_M; // clear Stall + xfer_status[0][TUSB_DIR_OUT].max_size = 8; + xfer_status[0][TUSB_DIR_IN].max_size = 8; + } +} + + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + ESP_LOGV(TAG, "DCD init - Start"); + + // A. Disconnect + ESP_LOGV(TAG, "DCD init - Soft DISCONNECT and Setting up"); + USB0.dctl |= USB_SFTDISCON_M; // Soft disconnect + + // B. Programming DCFG + /* If USB host misbehaves during status portion of control xfer + (non zero-length packet), send STALL back and discard. Full speed. */ + USB0.dcfg |= USB_NZSTSOUTHSHK_M | // NonZero .... STALL + (3 << 0); // dev speed: fullspeed 1.1 on 48 mhz // TODO no value in usb_reg.h (IDF-1476) + + USB0.gahbcfg |= USB_NPTXFEMPLVL_M | USB_GLBLLNTRMSK_M; // Global interruptions ON + USB0.gusbcfg |= USB_FORCEDEVMODE_M; // force devmode + USB0.gotgctl &= ~(USB_BVALIDOVVAL_M | USB_BVALIDOVEN_M | USB_VBVALIDOVVAL_M); //no overrides + + // C. Setting SNAKs, then connect + for (int n = 0; n < USB_OUT_EP_NUM; n++) { + USB0.out_ep_reg[n].doepctl |= USB_DO_SNAK0_M; // DOEPCTL0_SNAK + } + + // D. Interruption masking + USB0.gintmsk = 0; //mask all + USB0.gotgint = ~0U; //clear OTG ints + USB0.gintsts = ~0U; //clear pending ints + USB0.gintmsk = USB_OTGINTMSK_M | + USB_MODEMISMSK_M | + USB_RXFLVIMSK_M | + USB_ERLYSUSPMSK_M | + USB_USBSUSPMSK_M | + USB_USBRSTMSK_M | + USB_ENUMDONEMSK_M | + USB_RESETDETMSK_M | + USB_DISCONNINTMSK_M; // host most only + + dcd_connect(rhport); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + ESP_LOGV(TAG, "DCD init - Set address : %u", dev_addr); + USB0.dcfg |= ((dev_addr & USB_DEVADDR_V) << USB_DEVADDR_S); + // Response with status after changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + + // set remote wakeup + USB0.dctl |= USB_RMTWKUPSIG_M; + + // enable SOF to detect bus resume + USB0.gintsts = USB_SOF_M; + USB0.gintmsk |= USB_SOFMSK_M; + + // Per specs: remote wakeup signal bit must be clear within 1-15ms + vTaskDelay(pdMS_TO_TICKS(1)); + + USB0.dctl &= ~USB_RMTWKUPSIG_M; +} + +// connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + USB0.dctl &= ~USB_SFTDISCON_M; +} + +// disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB0.dctl |= USB_SFTDISCON_M; +} + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) +{ + ESP_LOGV(TAG, "DCD endpoint opened"); + (void)rhport; + + usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); + usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + TU_ASSERT(epnum < EP_MAX); + + xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); + + if (dir == TUSB_DIR_OUT) { + out_ep[epnum].doepctl |= USB_USBACTEP1_M | + desc_edpt->bmAttributes.xfer << USB_EPTYPE1_S | + (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_DO_SETD0PID1_M : 0) | + xfer->max_size << USB_MPS1_S; + USB0.daintmsk |= (1 << (16 + epnum)); + } else { + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO MAX | + // --------------- + // | ... | + // --------------- y + x + 16 + GRXFSIZ + // | IN FIFO 2 | + // --------------- x + 16 + GRXFSIZ + // | IN FIFO 1 | + // --------------- 16 + GRXFSIZ + // | IN FIFO 0 | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // Since OUT FIFO = GRXFSIZ, FIFO 0 = 16, for simplicity, we equally allocated for the rest of endpoints + // - Size : (FIFO_SIZE/4 - GRXFSIZ - 16) / (EP_MAX-1) + // - Offset: GRXFSIZ + 16 + Size*(epnum-1) + // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". + + uint8_t fifo_num = get_free_fifo(); + TU_ASSERT(fifo_num != 0); + + in_ep[epnum].diepctl &= ~(USB_D_TXFNUM1_M | USB_D_EPTYPE1_M | USB_DI_SETD0PID1 | USB_D_MPS1_M); + in_ep[epnum].diepctl |= USB_D_USBACTEP1_M | + fifo_num << USB_D_TXFNUM1_S | + desc_edpt->bmAttributes.xfer << USB_D_EPTYPE1_S | + (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? (1 << USB_DI_SETD0PID1_S) : 0) | + xfer->max_size << 0; + + USB0.daintmsk |= (1 << (0 + epnum)); + + // Both TXFD and TXSA are in unit of 32-bit words. + // IN FIFO 0 was configured during enumeration, hence the "+ 16". + uint16_t const allocated_size = (USB0.grxfsiz & 0x0000ffff) + 16; + uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_FIFO_NUM-1); + uint32_t const fifo_offset = allocated_size + fifo_size*(fifo_num-1); + + // DIEPTXF starts at FIFO #1. + USB0.dieptxf[epnum - 1] = (fifo_size << USB_NPTXFDEP_S) | fifo_offset; + } + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + (void) rhport; + + usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); + usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); + + // Disable non-control interrupt + USB0.daintmsk = USB_OUTEPMSK0_M | USB_INEPMSK0_M; + + for(uint8_t n = 1; n < EP_MAX; n++) + { + // disable OUT endpoint + out_ep[n].doepctl = 0; + xfer_status[n][TUSB_DIR_OUT].max_size = 0; + + // disable IN endpoint + in_ep[n].diepctl = 0; + xfer_status[n][TUSB_DIR_IN].max_size = 0; + } + + _allocated_fifos = 1; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->short_packet = false; + + uint16_t num_packets = (total_bytes / xfer->max_size); + uint8_t short_packet_size = total_bytes % xfer->max_size; + + // Zero-size packet is special case. + if (short_packet_size > 0 || (total_bytes == 0)) { + num_packets++; + } + + ESP_LOGV(TAG, "Transfer <-> EP%i, %s, pkgs: %i, bytes: %i", + epnum, ((dir == TUSB_DIR_IN) ? "USB0.HOST (in)" : "HOST->DEV (out)"), + num_packets, total_bytes); + + // IN and OUT endpoint xfers are interrupt-driven, we just schedule them + // here. + if (dir == TUSB_DIR_IN) { + // A full IN transfer (multiple packets, possibly) triggers XFRC. + USB0.in_ep_reg[epnum].dieptsiz = (num_packets << USB_D_PKTCNT0_S) | total_bytes; + USB0.in_ep_reg[epnum].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M; // Enable | CNAK + + // Enable fifo empty interrupt only if there are something to put in the fifo. + if(total_bytes != 0) { + USB0.dtknqr4_fifoemptymsk |= (1 << epnum); + } + } else { + // Each complete packet for OUT xfers triggers XFRC. + USB0.out_ep_reg[epnum].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S); + USB0.out_ep_reg[epnum].doepctl |= USB_EPENA0_M | USB_CNAK0_M; + } + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void)rhport; +} +#endif + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + + usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); + usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (dir == TUSB_DIR_IN) { + // Only disable currently enabled non-control endpoint + if ((epnum == 0) || !(in_ep[epnum].diepctl & USB_D_EPENA1_M)) { + in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M); + } else { + // Stop transmitting packets and NAK IN xfers. + in_ep[epnum].diepctl |= USB_DI_SNAK1_M; + while ((in_ep[epnum].diepint & USB_DI_SNAK1_M) == 0) ; + + // Disable the endpoint. Note that both SNAK and STALL are set here. + in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M | USB_D_EPDIS1_M); + while ((in_ep[epnum].diepint & USB_D_EPDISBLD0_M) == 0) ; + in_ep[epnum].diepint = USB_D_EPDISBLD0_M; + } + + // Flush the FIFO, and wait until we have confirmed it cleared. + uint8_t const fifo_num = ((in_ep[epnum].diepctl >> USB_D_TXFNUM1_S) & USB_D_TXFNUM1_V); + USB0.grstctl |= (fifo_num << USB_TXFNUM_S); + USB0.grstctl |= USB_TXFFLSH_M; + while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ; + } else { + // Only disable currently enabled non-control endpoint + if ((epnum == 0) || !(out_ep[epnum].doepctl & USB_EPENA0_M)) { + out_ep[epnum].doepctl |= USB_STALL0_M; + } else { + // Asserting GONAK is required to STALL an OUT endpoint. + // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt + // anyway, and it can't be cleared by user code. If this while loop never + // finishes, we have bigger problems than just the stack. + USB0.dctl |= USB_SGOUTNAK_M; + while ((USB0.gintsts & USB_GOUTNAKEFF_M) == 0) ; + + // Ditto here- disable the endpoint. Note that only STALL and not SNAK + // is set here. + out_ep[epnum].doepctl |= (USB_STALL0_M | USB_EPDIS0_M); + while ((out_ep[epnum].doepint & USB_EPDISBLD0_M) == 0) ; + out_ep[epnum].doepint = USB_EPDISBLD0_M; + + // Allow other OUT endpoints to keep receiving. + USB0.dctl |= USB_CGOUTNAK_M; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + + usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); + usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (dir == TUSB_DIR_IN) { + in_ep[epnum].diepctl &= ~USB_D_STALL1_M; + + uint8_t eptype = (in_ep[epnum].diepctl & USB_D_EPTYPE1_M) >> USB_D_EPTYPE1_S; + // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt + // and bulk endpoints. + if (eptype == 2 || eptype == 3) { + in_ep[epnum].diepctl |= USB_DI_SETD0PID1_M; + } + } else { + out_ep[epnum].doepctl &= ~USB_STALL1_M; + + uint8_t eptype = (out_ep[epnum].doepctl & USB_EPTYPE1_M) >> USB_EPTYPE1_S; + // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt + // and bulk endpoints. + if (eptype == 2 || eptype == 3) { + out_ep[epnum].doepctl |= USB_DO_SETD0PID1_M; + } + } +} + +/*------------------------------------------------------------------*/ + +static void receive_packet(xfer_ctl_t *xfer, /* usb_out_endpoint_t * out_ep, */ uint16_t xfer_size) +{ + ESP_EARLY_LOGV(TAG, "USB - receive_packet"); + volatile uint32_t *rx_fifo = USB0.fifo[0]; + + // See above TODO + // uint16_t remaining = (out_ep->DOEPTSIZ & UsbDOEPTSIZ_XFRSIZ_Msk) >> UsbDOEPTSIZ_XFRSIZ_Pos; + // xfer->queued_len = xfer->total_len - remaining; + + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t to_recv_size; + + if (remaining <= xfer->max_size) { + // Avoid buffer overflow. + to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; + } else { + // Room for full packet, choose recv_size based on what the microcontroller + // claims. + to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; + } + + // Common buffer read +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + // Ring buffer + tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) rx_fifo, to_recv_size); + } + else +#endif + { + uint8_t to_recv_rem = to_recv_size % 4; + uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem; + + // Do not assume xfer buffer is aligned. + uint8_t *base = (xfer->buffer + xfer->queued_len); + + // This for loop always runs at least once- skip if less than 4 bytes + // to collect. + if (to_recv_size >= 4) { + for (uint16_t i = 0; i < to_recv_size_aligned; i += 4) { + uint32_t tmp = (*rx_fifo); + base[i] = tmp & 0x000000FF; + base[i + 1] = (tmp & 0x0000FF00) >> 8; + base[i + 2] = (tmp & 0x00FF0000) >> 16; + base[i + 3] = (tmp & 0xFF000000) >> 24; + } + } + + // Do not read invalid bytes from RX FIFO. + if (to_recv_rem != 0) { + uint32_t tmp = (*rx_fifo); + uint8_t *last_32b_bound = base + to_recv_size_aligned; + + last_32b_bound[0] = tmp & 0x000000FF; + if (to_recv_rem > 1) { + last_32b_bound[1] = (tmp & 0x0000FF00) >> 8; + } + if (to_recv_rem > 2) { + last_32b_bound[2] = (tmp & 0x00FF0000) >> 16; + } + } + } + + xfer->queued_len += xfer_size; + + // Per USB spec, a short OUT packet (including length 0) is always + // indicative of the end of a transfer (at least for ctl, bulk, int). + xfer->short_packet = (xfer_size < xfer->max_size); +} + +static void transmit_packet(xfer_ctl_t *xfer, volatile usb_in_endpoint_t *in_ep, uint8_t fifo_num) +{ + ESP_EARLY_LOGV(TAG, "USB - transmit_packet"); + volatile uint32_t *tx_fifo = USB0.fifo[fifo_num]; + + uint16_t remaining = (in_ep->dieptsiz & 0x7FFFFU) >> USB_D_XFERSIZE0_S; + xfer->queued_len = xfer->total_len - remaining; + + uint16_t to_xfer_size = (remaining > xfer->max_size) ? xfer->max_size : remaining; + +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) tx_fifo, to_xfer_size); + } + else +#endif + { + uint8_t to_xfer_rem = to_xfer_size % 4; + uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem; + + // Buffer might not be aligned to 32b, so we need to force alignment + // by copying to a temp var. + uint8_t *base = (xfer->buffer + xfer->queued_len); + + // This for loop always runs at least once- skip if less than 4 bytes + // to send off. + if (to_xfer_size >= 4) { + for (uint16_t i = 0; i < to_xfer_size_aligned; i += 4) { + uint32_t tmp = base[i] | (base[i + 1] << 8) | + (base[i + 2] << 16) | (base[i + 3] << 24); + (*tx_fifo) = tmp; + } + } + + // Do not read beyond end of buffer if not divisible by 4. + if (to_xfer_rem != 0) { + uint32_t tmp = 0; + uint8_t *last_32b_bound = base + to_xfer_size_aligned; + + tmp |= last_32b_bound[0]; + if (to_xfer_rem > 1) { + tmp |= (last_32b_bound[1] << 8); + } + if (to_xfer_rem > 2) { + tmp |= (last_32b_bound[2] << 16); + } + + (*tx_fifo) = tmp; + } + } +} + +static void read_rx_fifo(void) +{ + // Pop control word off FIFO (completed xfers will have 2 control words, + // we only pop one ctl word each interrupt). + uint32_t const ctl_word = USB0.grxstsp; + uint8_t const pktsts = (ctl_word & USB_PKTSTS_M) >> USB_PKTSTS_S; + uint8_t const epnum = (ctl_word & USB_CHNUM_M ) >> USB_CHNUM_S; + uint16_t const bcnt = (ctl_word & USB_BCNT_M ) >> USB_BCNT_S; + + switch (pktsts) { + case 0x01: // Global OUT NAK (Interrupt) + ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Global OUT NAK"); + break; + + case 0x02: { // Out packet recvd + ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Out packet"); + xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + receive_packet(xfer, bcnt); + } + break; + + case 0x03: // Out packet done (Interrupt) + ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Out packet done"); + break; + + case 0x04: // Step 2: Setup transaction completed (Interrupt) + // After this event, OEPINT interrupt will occur with SETUP bit set + ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX : Setup packet done"); + USB0.out_ep_reg[epnum].doeptsiz |= USB_SUPCNT0_M; + break; + + case 0x06: { // Step1: Setup data packet received + volatile uint32_t *rx_fifo = USB0.fifo[0]; + + // We can receive up to three setup packets in succession, but + // only the last one is valid. Therefore we just overwrite it + _setup_packet[0] = (*rx_fifo); + _setup_packet[1] = (*rx_fifo); + + ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX : Setup packet : 0x%08x 0x%08x", _setup_packet[0], _setup_packet[1]); + } + break; + + default: // Invalid, do something here, like breakpoint? + TU_BREAKPOINT(); + break; + } +} + +static void handle_epout_ints(void) +{ + // GINTSTS will be cleared with DAINT == 0 + // DAINT for a given EP clears when DOEPINTx is cleared. + // DOEPINT will be cleared when DAINT's out bits are cleared. + for (int n = 0; n < USB_OUT_EP_NUM; n++) { + xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); + + if (USB0.daint & (1 << (16 + n))) { + // SETUP packet Setup Phase done. + if ((USB0.out_ep_reg[n].doepint & USB_SETUP0_M)) { + USB0.out_ep_reg[n].doepint = USB_STUPPKTRCVD0_M | USB_SETUP0_M; // clear + dcd_event_setup_received(0, (uint8_t *)&_setup_packet[0], true); + } + + // OUT XFER complete (single packet).q + if (USB0.out_ep_reg[n].doepint & USB_XFERCOMPL0_M) { + + ESP_EARLY_LOGV(TAG, "TUSB IRQ - EP OUT - XFER complete (single packet)"); + USB0.out_ep_reg[n].doepint = USB_XFERCOMPL0_M; + + // Transfer complete if short packet or total len is transferred + if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { + xfer->short_packet = false; + dcd_event_xfer_complete(0, n, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + // Schedule another packet to be received. + USB0.out_ep_reg[n].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S); + USB0.out_ep_reg[n].doepctl |= USB_EPENA0_M | USB_CNAK0_M; + } + } + } + } +} + +static void handle_epin_ints(void) +{ + // GINTSTS will be cleared with DAINT == 0 + // DAINT for a given EP clears when DIEPINTx is cleared. + // IEPINT will be cleared when DAINT's out bits are cleared. + for (uint32_t n = 0; n < USB_IN_EP_NUM; n++) { + xfer_ctl_t *xfer = &xfer_status[n][TUSB_DIR_IN]; + + if (USB0.daint & (1 << (0 + n))) { + ESP_EARLY_LOGV(TAG, "TUSB IRQ - EP IN %u", n); + // IN XFER complete (entire xfer). + if (USB0.in_ep_reg[n].diepint & USB_D_XFERCOMPL0_M) { + ESP_EARLY_LOGV(TAG, "TUSB IRQ - IN XFER complete!"); + USB0.in_ep_reg[n].diepint = USB_D_XFERCOMPL0_M; + dcd_event_xfer_complete(0, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + + // XFER FIFO empty + if (USB0.in_ep_reg[n].diepint & USB_D_TXFEMP0_M) { + ESP_EARLY_LOGV(TAG, "TUSB IRQ - IN XFER FIFO empty!"); + USB0.in_ep_reg[n].diepint = USB_D_TXFEMP0_M; + transmit_packet(xfer, &USB0.in_ep_reg[n], n); + + // Turn off TXFE if all bytes are written. + if (xfer->queued_len == xfer->total_len) + { + USB0.dtknqr4_fifoemptymsk &= ~(1 << n); + } + } + + // XFER Timeout + if (USB0.in_ep_reg[n].diepint & USB_D_TIMEOUT0_M) { + // Clear interrupt or enpoint will hang. + USB0.in_ep_reg[n].diepint = USB_D_TIMEOUT0_M; + // Maybe retry? + } + } + } +} + + +static void _dcd_int_handler(void* arg) +{ + (void) arg; + uint8_t const rhport = 0; + + const uint32_t int_msk = USB0.gintmsk; + const uint32_t int_status = USB0.gintsts & int_msk; + + if (int_status & USB_USBRST_M) { + // start of reset + ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset"); + USB0.gintsts = USB_USBRST_M; + // FIFOs will be reassigned when the endpoints are reopen + _allocated_fifos = 1; + bus_reset(); + } + + if (int_status & USB_RESETDET_M) { + ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset while suspend"); + USB0.gintsts = USB_RESETDET_M; + bus_reset(); + } + + if (int_status & USB_ENUMDONE_M) { + // ENUMDNE detects speed of the link. For full-speed, we + // always expect the same value. This interrupt is considered + // the end of reset. + USB0.gintsts = USB_ENUMDONE_M; + enum_done_processing(); + dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); + } + + if(int_status & USB_USBSUSP_M) + { + USB0.gintsts = USB_USBSUSP_M; + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + if(int_status & USB_WKUPINT_M) + { + USB0.gintsts = USB_WKUPINT_M; + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + + if (int_status & USB_OTGINT_M) + { + // OTG INT bit is read-only + ESP_EARLY_LOGV(TAG, "dcd_int_handler - disconnected"); + + uint32_t const otg_int = USB0.gotgint; + + if (otg_int & USB_SESENDDET_M) + { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + + USB0.gotgint = otg_int; + } + + if (int_status & USB_SOF_M) { + USB0.gintsts = USB_SOF_M; + + // Disable SOF interrupt since currently only used for remote wakeup detection + USB0.gintmsk &= ~USB_SOFMSK_M; + + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + + + if (int_status & USB_RXFLVI_M) { + // RXFLVL bit is read-only + ESP_EARLY_LOGV(TAG, "dcd_int_handler - rx!"); + + // Mask out RXFLVL while reading data from FIFO + USB0.gintmsk &= ~USB_RXFLVIMSK_M; + read_rx_fifo(); + USB0.gintmsk |= USB_RXFLVIMSK_M; + } + + // OUT endpoint interrupt handling. + if (int_status & USB_OEPINT_M) { + // OEPINT is read-only + ESP_EARLY_LOGV(TAG, "dcd_int_handler - OUT endpoint!"); + handle_epout_ints(); + } + + // IN endpoint interrupt handling. + if (int_status & USB_IEPINT_M) { + // IEPINT bit read-only + ESP_EARLY_LOGV(TAG, "dcd_int_handler - IN endpoint!"); + handle_epin_ints(); + } + + // Without handling + USB0.gintsts |= USB_CURMOD_INT_M | + USB_MODEMIS_M | + USB_OTGINT_M | + USB_NPTXFEMP_M | + USB_GINNAKEFF_M | + USB_GOUTNAKEFF | + USB_ERLYSUSP_M | + USB_USBSUSP_M | + USB_ISOOUTDROP_M | + USB_EOPF_M | + USB_EPMIS_M | + USB_INCOMPISOIN_M | + USB_INCOMPIP_M | + USB_FETSUSP_M | + USB_PTXFEMP_M; +} + +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; + esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, (intr_handler_t) _dcd_int_handler, NULL, &usb_ih); +} + +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + esp_intr_free(usb_ih); +} + +#endif // #if OPT_MCU_ESP32S2 || OPT_MCU_ESP32S3 + diff --git a/circuitpython/lib/tinyusb/src/portable/mentor/musb/dcd_musb.c b/circuitpython/lib/tinyusb/src/portable/mentor/musb/dcd_musb.c new file mode 100644 index 0000000..d365855 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/mentor/musb/dcd_musb.c @@ -0,0 +1,900 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && \ + TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + +#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) +/* GCC warns that an address may be unaligned, even though + * the target CPU has the capability for unaligned memory access. */ +_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); +#endif + +#include "device/dcd.h" + +#if TU_CHECK_MCU(OPT_MCU_MSP432E4) + #include "musb_msp432e.h" + +#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #include "musb_tm4c.h" + + // HACK generalize later + #include "musb_type.h" + #define FIFO0_WORD FIFO0 + #define FIFO1_WORD FIFO1 + +#else + #error "Unsupported MCUs" +#endif + +/*------------------------------------------------------------------ + * MACRO TYPEDEF CONSTANT ENUM DECLARATION + *------------------------------------------------------------------*/ +#define REQUEST_TYPE_INVALID (0xFFu) + +typedef struct { + uint_fast16_t beg; /* offset of including first element */ + uint_fast16_t end; /* offset of excluding the last element */ +} free_block_t; + +typedef struct TU_ATTR_PACKED { + uint16_t TXMAXP; + uint8_t TXCSRL; + uint8_t TXCSRH; + uint16_t RXMAXP; + uint8_t RXCSRL; + uint8_t RXCSRH; + uint16_t RXCOUNT; + uint16_t RESERVED[3]; +} hw_endpoint_t; + +typedef union { + uint8_t u8; + uint16_t u16; + uint32_t u32; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ +} pipe_state_t; + +typedef struct +{ + tusb_control_request_t setup_packet; + uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ + int8_t status_out; + pipe_state_t pipe0; + pipe_state_t pipe[2][7]; /* pipe[direction][endpoint number - 1] */ + uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ +} dcd_data_t; + +/*------------------------------------------------------------------ + * INTERNAL OBJECT & FUNCTION DECLARATION + *------------------------------------------------------------------*/ +static dcd_data_t _dcd; + + +static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) +{ + free_block_t *cur = beg; + for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; + return cur; +} + +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) +{ + free_block_t *p = find_containing_block(blks, blks + num, addr); + TU_ASSERT(p != blks + num, -2); + if (p->beg == addr) { + /* Shrink block */ + p->beg = addr + size; + if (p->beg != p->end) return 0; + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } else { + /* Split into 2 blocks */ + free_block_t tmp = { + .beg = addr + size, + .end = p->end + }; + p->end = addr; + if (p->beg == p->end) { + if (tmp.beg != tmp.end) { + *p = tmp; + return 0; + } + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } + if (tmp.beg == tmp.end) return 0; + blks[num] = tmp; + return 1; + } +} + +static inline unsigned free_block_size(free_block_t const *blk) +{ + return blk->end - blk->beg; +} + +#if 0 +static inline void print_block_list(free_block_t const *blk, unsigned num) +{ + TU_LOG1("*************\n"); + for (unsigned i = 0; i < num; ++i) { + TU_LOG1(" Blk%u %u %u\n", i, blk->beg, blk->end); + ++blk; + } +} +#else +#define print_block_list(a,b) +#endif + +static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) +{ + free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; + unsigned num_blocks = 1; + + /* Initialize free memory block list */ + free_blocks[0].beg = 64 / 8; + free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ + for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + uint_fast16_t addr; + int num; + USB0->EPIDX = i; + addr = USB0->TXFIFOADD; + if (addr) { + unsigned sz = USB0->TXFIFOSZ; + unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + addr = USB0->RXFIFOADD; + if (addr) { + unsigned sz = USB0->RXFIFOSZ; + unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + } + print_block_list(free_blocks, num_blocks); + + /* Find the best fit memory block */ + uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; + free_block_t const *min = NULL; + uint_fast16_t min_sz = 0xFFFFu; + free_block_t const *end = &free_blocks[num_blocks]; + for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { + uint_fast16_t sz = free_block_size(cur); + if (sz < size_in_8byte_unit) continue; + if (size_in_8byte_unit == sz) return cur->beg; + if (sz < min_sz) min = cur; + } + TU_ASSERT(min, 0); + return min->beg; +} + +static inline volatile hw_endpoint_t* edpt_regs(unsigned epnum_minus1) +{ + volatile hw_endpoint_t *regs = (volatile hw_endpoint_t*)((uintptr_t)&USB0->TXMAXP1); + return regs + epnum_minus1; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + reg->u32 = *(uint32_t const *)addr; + addr += 4; + len -= 4; + } + if (len >= 2) { + reg->u16 = *(uint16_t const *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(uint8_t const *)addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + *(uint32_t *)addr = reg->u32; + addr += 4; + len -= 4; + } + if (len >= 2) { + *(uint16_t *)addr = reg->u16; + addr += 2; + len -= 2; + } + if (len) { + *(uint8_t *)addr = reg->u8; + } +} + +static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) +{ + static const struct { + void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); + void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); + void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); + } ops[] = { + /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, + /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, + }; + tu_fifo_buffer_info_t info; + ops[dir].tu_fifo_get_info(f, &info); + unsigned total_len = len; + len = TU_MIN(total_len, info.len_lin); + ops[dir].pipe_read_write(info.ptr_lin, fifo, len); + unsigned rem = total_len - len; + if (rem) { + len = TU_MIN(rem, info.len_wrap); + ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); + rem -= len; + } + ops[dir].tu_fifo_advance(f, total_len - rem); +} + +static void process_setup_packet(uint8_t rhport) +{ + uint32_t *p = (void*)&_dcd.setup_packet; + p[0] = USB0->FIFO0_WORD; + p[1] = USB0->FIFO0_WORD; + + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); + + const unsigned len = _dcd.setup_packet.wLength; + _dcd.remaining_ctrl = len; + const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); + /* Clear RX FIFO and reverse the transaction direction */ + if (len && dir_in) USB0->CSRL0 = USB_CSRL0_RXRDYC; +} + +static bool handle_xfer_in(uint_fast8_t ep_addr) +{ + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + const unsigned rem = pipe->remaining; + + if (!rem) { + pipe->buf = NULL; + return true; + } + + volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + const unsigned mps = regs->TXMAXP; + const unsigned len = TU_MIN(mps, rem); + void *buf = pipe->buf; + // TU_LOG1(" %p mps %d len %d rem %d\n", buf, mps, len, rem); + if (len) { + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_IN); + } else { + pipe_write_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + regs->TXCSRL = USB_TXCSRL1_TXRDY; + // TU_LOG1(" TXCSRL%d = %x %d\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); + return false; +} + +static bool handle_xfer_out(uint_fast8_t ep_addr) +{ + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + // TU_LOG1(" RXCSRL%d = %x\n", epnum_minus1 + 1, regs->RXCSRL); + + TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); + + const unsigned mps = regs->RXMAXP; + const unsigned rem = pipe->remaining; + const unsigned vld = regs->RXCOUNT; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_OUT); + } else { + pipe_read_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + regs->RXCSRL = 0; /* Clear RXRDY bit */ + return false; +} + +static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned dir_in = tu_edpt_dir(ep_addr); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; + pipe->buf = buffer; + pipe->length = total_bytes; + pipe->remaining = total_bytes; + + if (dir_in) { + handle_xfer_in(ep_addr); + } else { + volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = 0; + } + return true; +} + +static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ + + const unsigned req = _dcd.setup_packet.bmRequestType; + TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); + + if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { + /* STATUS OUT stage. + * MUSB controller automatically handles STATUS OUT packets without + * software helps. We do not have to do anything. And STATUS stage + * may have already finished and received the next setup packet + * without calling this function, so we have no choice but to + * invoke the callback function of status packet here. */ + // TU_LOG1(" STATUS OUT USB0->CSRL0 = %x\n", USB0->CSRL0); + _dcd.status_out = 0; + if (req == REQUEST_TYPE_INVALID) { + dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); + } else { + /* The next setup packet has already been received, it aborts + * invoking callback function to avoid confusing TUSB stack. */ + TU_LOG1("Drop CONTROL_STAGE_ACK\n"); + } + return true; + } + const unsigned dir_in = tu_edpt_dir(ep_addr); + if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ + TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); + const unsigned rem = _dcd.remaining_ctrl; + const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); + if (dir_in) { + pipe_write_packet(buffer, &USB0->FIFO0_WORD, len); + + _dcd.pipe0.buf = buffer + len; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = 0; + + _dcd.remaining_ctrl = rem - len; + if ((len < 64) || (rem == len)) { + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ + _dcd.status_out = 1; + /* Flush TX FIFO and reverse the transaction direction. */ + USB0->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; + } else { + USB0->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ + } + // TU_LOG1(" IN USB0->CSRL0 = %x\n", USB0->CSRL0); + } else { + // TU_LOG1(" OUT USB0->CSRL0 = %x\n", USB0->CSRL0); + _dcd.pipe0.buf = buffer; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = len; + USB0->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ + } + } else if (dir_in) { + // TU_LOG1(" STATUS IN USB0->CSRL0 = %x\n", USB0->CSRL0); + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO and reverse the transaction direction */ + USB0->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + } + return true; +} + +static void process_ep0(uint8_t rhport) +{ + uint_fast8_t csrl = USB0->CSRL0; + + // TU_LOG1(" EP0 USB0->CSRL0 = %x\n", csrl); + + if (csrl & USB_CSRL0_STALLED) { + /* Returned STALL packet to HOST. */ + USB0->CSRL0 = 0; /* Clear STALL */ + return; + } + + unsigned req = _dcd.setup_packet.bmRequestType; + if (csrl & USB_CSRL0_SETEND) { + TU_LOG1(" ABORT by the next packets\n"); + USB0->CSRL0 = USB_CSRL0_SETENDC; + if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { + /* DATA stage was aborted by receiving STATUS or SETUP packet. */ + _dcd.pipe0.buf = NULL; + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + req & TUSB_DIR_IN_MASK, + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + req = REQUEST_TYPE_INVALID; + if (!(csrl & USB_CSRL0_RXRDY)) return; /* Received SETUP packet */ + } + + if (csrl & USB_CSRL0_RXRDY) { + /* Received SETUP or DATA OUT packet */ + if (req == REQUEST_TYPE_INVALID) { + /* SETUP */ + TU_ASSERT(sizeof(tusb_control_request_t) == USB0->COUNT0,); + process_setup_packet(rhport); + return; + } + if (_dcd.pipe0.buf) { + /* DATA OUT */ + const unsigned vld = USB0->COUNT0; + const unsigned rem = _dcd.pipe0.remaining; + const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); + pipe_read_packet(_dcd.pipe0.buf, &USB0->FIFO0_WORD, len); + + _dcd.pipe0.remaining = rem - len; + _dcd.remaining_ctrl -= len; + + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_OUT), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + return; + } + + /* When CSRL0 is zero, it means that completion of sending a any length packet + * or receiving a zero length packet. */ + if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { + /* STATUS IN */ + if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { + /* The address must be changed on completion of the control transfer. */ + USB0->FADDR = (uint8_t)_dcd.setup_packet.wValue; + } + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + return; + } + if (_dcd.pipe0.buf) { + /* DATA IN */ + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) +{ + bool completed; + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned epn_minus1 = tu_edpt_number(ep_addr) - 1; + + volatile hw_endpoint_t *regs = edpt_regs(epn_minus1); + if (dir_in) { + // TU_LOG1(" TXCSRL%d = %x\n", epn_minus1 + 1, regs->TXCSRL); + if (regs->TXCSRL & USB_TXCSRL1_STALLED) { + regs->TXCSRL &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); + return; + } + completed = handle_xfer_in(ep_addr); + } else { + // TU_LOG1(" RXCSRL%d = %x\n", epn_minus1 + 1, regs->RXCSRL); + if (regs->RXCSRL & USB_RXCSRL1_STALLED) { + regs->RXCSRL &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); + return; + } + completed = handle_xfer_out(ep_addr); + } + + if (completed) { + pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; + dcd_event_xfer_complete(rhport, ep_addr, + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), + * a control transfer state is SETUP or STATUS stage. */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.status_out = 0; + /* When pipe0.buf has not NULL, DATA stage works in progress. */ + _dcd.pipe0.buf = NULL; + + USB0->TXIE = 1; /* Enable only EP0 */ + USB0->RXIE = 0; + + /* Clear FIFO settings */ + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + USB0->EPIDX = i; + USB0->TXFIFOSZ = 0; + USB0->TXFIFOADD = 0; + USB0->RXFIFOSZ = 0; + USB0->RXFIFOADD = 0; + } + dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); +} + +/*------------------------------------------------------------------ + * Device API + *------------------------------------------------------------------*/ + +void dcd_init(uint8_t rhport) +{ + (void)rhport; + USB0->IE |= USB_IE_SUSPND; + NVIC_ClearPendingIRQ(USB0_IRQn); + + dcd_connect(rhport); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + NVIC_EnableIRQ(USB0_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + NVIC_DisableIRQ(USB0_IRQn); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + (void)dev_addr; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO to return ACK. */ + USB0->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; +} + +// Wake up host +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + USB0->POWER |= USB_POWER_RESUME; + + unsigned cnt = SystemCoreClock / 1000; + while (cnt--) __NOP(); + + USB0->POWER &= ~USB_POWER_RESUME; +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + USB0->POWER |= USB_POWER_SOFTCONN; +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + USB0->POWER &= ~USB_POWER_SOFTCONN; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + const unsigned mps = tu_edpt_packet_size(ep_desc); + + TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + volatile hw_endpoint_t *regs = edpt_regs(epn - 1); + if (dir_in) { + regs->TXMAXP = mps; + regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + USB0->TXIE |= TU_BIT(epn); + } else { + regs->RXMAXP = mps; + regs->RXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + USB0->RXIE |= TU_BIT(epn); + } + + /* Setup FIFO */ + int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); + if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; + unsigned addr = find_free_memory(size_in_log2_minus3); + TU_ASSERT(addr); + + USB0->EPIDX = epn; + if (dir_in) { + USB0->TXFIFOADD = addr; + USB0->TXFIFOSZ = size_in_log2_minus3; + } else { + USB0->RXFIFOADD = addr; + USB0->RXFIFOSZ = size_in_log2_minus3; + } + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + (void) rhport; + volatile hw_endpoint_t *regs = (volatile hw_endpoint_t *)(uintptr_t)&USB0->TXMAXP1; + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + USB0->TXIE = 1; /* Enable only EP0 */ + USB0->RXIE = 0; + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + regs->TXMAXP = 0; + regs->TXCSRH = 0; + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + + regs->RXMAXP = 0; + regs->RXCSRH = 0; + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + + USB0->EPIDX = i; + USB0->TXFIFOSZ = 0; + USB0->TXFIFOADD = 0; + USB0->RXFIFOSZ = 0; + USB0->RXFIFOADD = 0; + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + unsigned const dir_in = tu_edpt_dir(ep_addr); + + hw_endpoint_t volatile *regs = edpt_regs(epn - 1); + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + if (dir_in) { + USB0->TXIE &= ~TU_BIT(epn); + regs->TXMAXP = 0; + regs->TXCSRH = 0; + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + + USB0->EPIDX = epn; + USB0->TXFIFOSZ = 0; + USB0->TXFIFOADD = 0; + } else { + USB0->RXIE &= ~TU_BIT(epn); + regs->RXMAXP = 0; + regs->RXCSRH = 0; + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + + USB0->EPIDX = epn; + USB0->RXFIFOSZ = 0; + USB0->RXFIFOADD = 0; + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + unsigned const epnum = tu_edpt_number(ep_addr); + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + if (epnum) { + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); + } else + ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return ret; +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + unsigned const epnum = tu_edpt_number(ep_addr); + TU_ASSERT(epnum); + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return ret; +} + +// Stall endpoint +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + if (0 == epn) { + if (!ep_addr) { /* Ignore EP80 */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.pipe0.buf = NULL; + USB0->CSRL0 = USB_CSRL0_STALL; + } + } else { + volatile hw_endpoint_t *regs = edpt_regs(epn - 1); + if (tu_edpt_dir(ep_addr)) { /* IN */ + regs->TXCSRL = USB_TXCSRL1_STALL; + } else { /* OUT */ + TU_ASSERT(!(regs->RXCSRL & USB_RXCSRL1_RXRDY),); + regs->RXCSRL = USB_RXCSRL1_STALL; + } + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + hw_endpoint_t volatile *regs = edpt_regs(epn - 1); + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + if (tu_edpt_dir(ep_addr)) { /* IN */ + regs->TXCSRL = USB_TXCSRL1_CLRDT; + } else { /* OUT */ + regs->RXCSRL = USB_RXCSRL1_CLRDT; + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +/*------------------------------------------------------------------- + * ISR + *-------------------------------------------------------------------*/ +void dcd_int_handler(uint8_t rhport) +{ + uint_fast8_t is, txis, rxis; + + is = USB0->IS; /* read and clear interrupt status */ + txis = USB0->TXIS; /* read and clear interrupt status */ + rxis = USB0->RXIS; /* read and clear interrupt status */ + // TU_LOG1("D%2x T%2x R%2x\n", is, txis, rxis); + + is &= USB0->IE; /* Clear disabled interrupts */ + if (is & USB_IS_DISCON) { + } + if (is & USB_IS_SOF) { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + if (is & USB_IS_RESET) { + process_bus_reset(rhport); + } + if (is & USB_IS_RESUME) { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + if (is & USB_IS_SUSPEND) { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + txis &= USB0->TXIE; /* Clear disabled interrupts */ + if (txis & USB_TXIE_EP0) { + process_ep0(rhport); + txis &= ~TU_BIT(0); + } + while (txis) { + unsigned const num = __builtin_ctz(txis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); + txis &= ~TU_BIT(num); + } + rxis &= USB0->RXIE; /* Clear disabled interrupts */ + while (rxis) { + unsigned const num = __builtin_ctz(rxis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); + rxis &= ~TU_BIT(num); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/mentor/musb/hcd_musb.c b/circuitpython/lib/tinyusb/src/portable/mentor/musb/hcd_musb.c new file mode 100644 index 0000000..3bfd65b --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/mentor/musb/hcd_musb.c @@ -0,0 +1,876 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && \ + TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + +#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) +/* GCC warns that an address may be unaligned, even though + * the target CPU has the capability for unaligned memory access. */ +_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); +#endif + +#include "host/hcd.h" + +#if TU_CHECK_MCU(OPT_MCU_MSP432E4) + #include "musb_msp432e.h" + +#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #include "musb_tm4c.h" + + // HACK generalize later + #include "musb_type.h" + #define FIFO0_WORD FIFO0 + +#else + #error "Unsupported MCUs" +#endif + +#ifndef HCD_ATTR_ENDPOINT_MAX +# define HCD_ATTR_ENDPOINT_MAX 8 +#endif + +/*------------------------------------------------------------------ + * MACRO TYPEDEF CONSTANT ENUM DECLARATION + *------------------------------------------------------------------*/ +#define REQUEST_TYPE_INVALID (0xFFu) + +typedef struct { + uint_fast16_t beg; /* offset of including first element */ + uint_fast16_t end; /* offset of excluding the last element */ +} free_block_t; + +typedef struct TU_ATTR_PACKED { + uint8_t TXFUNCADDR; + uint8_t RESERVED0; + uint8_t TXHUBADDR; + uint8_t TXHUBPORT; + uint8_t RXFUNCADDR; + uint8_t RESERVED1; + uint8_t RXHUBADDR; + uint8_t RXHUBPORT; +} hw_addr_t; + +typedef struct TU_ATTR_PACKED { + uint16_t TXMAXP; + uint8_t TXCSRL; + uint8_t TXCSRH; + uint16_t RXMAXP; + uint8_t RXCSRL; + uint8_t RXCSRH; + uint16_t RXCOUNT; + uint8_t TXTYPE; + uint8_t TXINTERVAL; + uint8_t RXTYPE; + uint8_t RXINTERVAL; + uint16_t RESERVED; +} hw_endpoint_t; + +typedef union { + uint8_t u8; + uint16_t u16; + uint32_t u32; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ +} pipe_state_t; + +typedef struct TU_ATTR_PACKED +{ + uint8_t dev; + uint8_t ep; +} pipe_addr_t; + +typedef struct +{ + bool need_reset; /* The device has not been reset after connection. */ + uint8_t bmRequestType; + uint8_t ctl_mps[7]; /* EP0 max packet size for each device */ + pipe_state_t pipe0; + pipe_state_t pipe[7][2]; /* pipe[pipe number - 1][direction 0:RX 1:TX] */ + pipe_addr_t addr[7][2]; /* addr[pipe number - 1][direction 0:RX 1:TX] */ +} hcd_data_t; + +/*------------------------------------------------------------------ + * INTERNAL OBJECT & FUNCTION DECLARATION + *------------------------------------------------------------------*/ +static hcd_data_t _hcd; + +static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) +{ + free_block_t *cur = beg; + for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; + return cur; +} + +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) +{ + free_block_t *p = find_containing_block(blks, blks + num, addr); + TU_ASSERT(p != blks + num, -2); + if (p->beg == addr) { + /* Shrink block */ + p->beg = addr + size; + if (p->beg != p->end) return 0; + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } else { + /* Split into 2 blocks */ + free_block_t tmp = { + .beg = addr + size, + .end = p->end + }; + p->end = addr; + if (p->beg == p->end) { + if (tmp.beg != tmp.end) { + *p = tmp; + return 0; + } + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } + if (tmp.beg == tmp.end) return 0; + blks[num] = tmp; + return 1; + } +} + +static inline unsigned free_block_size(free_block_t const *blk) +{ + return blk->end - blk->beg; +} + +static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) +{ + free_block_t free_blocks[2 * (HCD_ATTR_ENDPOINT_MAX - 1)]; + unsigned num_blocks = 1; + + /* Initialize free memory block list */ + free_blocks[0].beg = 64 / 8; + free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ + for (int i = 1; i < HCD_ATTR_ENDPOINT_MAX; ++i) { + uint_fast16_t addr; + int num; + USB0->EPIDX = i; + addr = USB0->TXFIFOADD; + if (addr) { + unsigned sz = USB0->TXFIFOSZ; + unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + } + addr = USB0->RXFIFOADD; + if (addr) { + unsigned sz = USB0->RXFIFOSZ; + unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + } + } + + /* Find the best fit memory block */ + uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; + free_block_t const *min = NULL; + uint_fast16_t min_sz = 0xFFFFu; + free_block_t const *end = &free_blocks[num_blocks]; + for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { + uint_fast16_t sz = free_block_size(cur); + if (sz < size_in_8byte_unit) continue; + if (size_in_8byte_unit == sz) return cur->beg; + if (sz < min_sz) min = cur; + } + TU_ASSERT(min, 0); + return min->beg; +} + +static inline volatile hw_endpoint_t* edpt_regs(unsigned epnum_minus1) +{ + volatile hw_endpoint_t *regs = (volatile hw_endpoint_t*)((uintptr_t)&USB0->TXMAXP1); + return regs + epnum_minus1; +} + +static unsigned find_pipe(uint_fast8_t dev_addr, uint_fast8_t ep_addr) +{ + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + pipe_addr_t const *p = &_hcd.addr[0][dir_tx]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i, p += 2) { + if ((dev_addr == p->dev) && (ep_addr == p->ep)) + return i + 1; + } + return 0; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + reg->u32 = *(uint32_t const *)addr; + addr += 4; + len -= 4; + } + if (len >= 2) { + reg->u16 = *(uint16_t const *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(uint8_t const *)addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + *(uint32_t *)addr = reg->u32; + addr += 4; + len -= 4; + } + if (len >= 2) { + *(uint16_t *)addr = reg->u16; + addr += 2; + len -= 2; + } + if (len) { + *(uint8_t *)addr = reg->u8; + } +} + +static bool edpt0_xfer_out(void) +{ + pipe_state_t *pipe = &_hcd.pipe0; + unsigned const rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const mps = _hcd.ctl_mps[dev_addr]; + unsigned const len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, &USB0->FIFO0_WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + USB0->CSRL0 = USB_CSRL0_TXRDY; + return false; +} + +static bool edpt0_xfer_in(void) +{ + pipe_state_t *pipe = &_hcd.pipe0; + unsigned const rem = pipe->remaining; + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const mps = _hcd.ctl_mps[dev_addr]; + unsigned const vld = USB0->COUNT0; + unsigned const len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + pipe_read_packet(buf, &USB0->FIFO0_WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return true; + } + USB0->CSRL0 = USB_CSRL0_REQPKT; + return false; +} + +static bool edpt0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + + unsigned const req = _hcd.bmRequestType; + TU_ASSERT(req != REQUEST_TYPE_INVALID); + TU_ASSERT(dev_addr < sizeof(_hcd.ctl_mps)); + + USB0->TXFUNCADDR0 = dev_addr; + const unsigned dir_in = tu_edpt_dir(ep_addr); + if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ + TU_ASSERT(buffer); + _hcd.pipe0.buf = buffer; + _hcd.pipe0.length = buflen; + _hcd.pipe0.remaining = buflen; + if (dir_in) + USB0->CSRL0 = USB_CSRL0_REQPKT; + else + edpt0_xfer_out(); + } else { /* STATUS stage */ + _hcd.pipe0.buf = NULL; + _hcd.pipe0.length = 0; + _hcd.pipe0.remaining = 0; + USB0->CSRL0 = USB_CSRL0_STATUS | (dir_in ? USB_CSRL0_REQPKT: USB_CSRL0_TXRDY); + } + return true; +} + +static bool pipe_xfer_out(uint_fast8_t pipenum) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][1]; + unsigned const rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + unsigned const mps = regs->TXMAXP; + unsigned const len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, &USB0->FIFO0_WORD + pipenum, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + regs->TXCSRL = USB_TXCSRL1_TXRDY; + return false; +} + +static bool pipe_xfer_in(uint_fast8_t pipenum) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][0]; + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + + TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); + + const unsigned mps = regs->RXMAXP; + const unsigned rem = pipe->remaining; + const unsigned vld = regs->RXCOUNT; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + pipe_read_packet(buf, &USB0->FIFO0_WORD + pipenum, len); + pipe->buf = buf + len; + pipe->remaining = rem - len; + } + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + regs->RXCSRL = USB_RXCSRL1_REQPKT; + return false; +} + +static bool edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + unsigned const pipenum = find_pipe(dev_addr, ep_addr); + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][dir_tx]; + pipe->buf = buffer; + pipe->length = buflen; + pipe->remaining = buflen; + if (dir_tx) { + pipe_xfer_out(pipenum); + } else { + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + regs->RXCSRL = USB_RXCSRL1_REQPKT; + } + return true; +} + +static void process_ep0(uint8_t rhport) +{ + (void)rhport; + + uint_fast8_t csrl = USB0->CSRL0; + // TU_LOG1(" EP0 CSRL = %x\n", csrl); + + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const req = _hcd.bmRequestType; + if (csrl & (USB_CSRL0_ERROR | USB_CSRL0_NAKTO | USB_CSRL0_STALLED)) { + /* No response / NAK timed out / Stall received */ + if (csrl & (USB_CSRL0_RXRDY | USB_CSRL0_TXRDY)) + USB0->CSRH0 = USB_CSRH0_FLUSH; + USB0->CSRL0 = 0; + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + uint8_t result = (csrl & USB_CSRL0_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + if (REQUEST_TYPE_INVALID == req) { /* SETUP */ + uint8_t const ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } else if (csrl & USB_CSRL0_STATUS) { /* STATUS */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_OUT): tu_edpt_addr(0, TUSB_DIR_IN); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } else { /* DATA */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_IN): tu_edpt_addr(0, TUSB_DIR_OUT); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } + return; + } + if (csrl & USB_CSRL0_STATUS) { + /* STATUS IN */ + TU_ASSERT(USB_CSRL0_RXRDY == (csrl & USB_CSRL0_RXRDY),); + TU_ASSERT(0 == USB0->COUNT0,); + USB0->CSRH0 = USB_CSRH0_FLUSH; + USB0->CSRL0 = 0; + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), + 0, XFER_RESULT_SUCCESS, true); + return; + } + if (csrl & USB_CSRL0_RXRDY) { + /* DATA IN */ + TU_ASSERT(REQUEST_TYPE_INVALID != req,); + TU_ASSERT(_hcd.pipe0.buf,); + if (edpt0_xfer_in()) { + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), + _hcd.pipe0.length - _hcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + return; + } + + /* When CSRL0 is zero, it means that completion of sending a any length packet. */ + if (!_hcd.pipe0.buf) { + /* STATUS OUT */ + TU_ASSERT(REQUEST_TYPE_INVALID != req,); + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + /* EP address is the reverse direction of DATA stage */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_OUT): tu_edpt_addr(0, TUSB_DIR_IN); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true); + return; + } + if (REQUEST_TYPE_INVALID == req) { + /* SETUP */ + _hcd.bmRequestType = *(uint8_t*)_hcd.pipe0.buf; + _hcd.pipe0.buf = NULL; + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_OUT), + 8, XFER_RESULT_SUCCESS, true); + return; + } + + /* DATA OUT */ + if (edpt0_xfer_out()) { + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_OUT), + _hcd.pipe0.length - _hcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_pipe_tx(uint8_t rhport, uint_fast8_t pipenum) +{ + (void)rhport; + bool completed; + uint8_t result; + + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + unsigned const csrl = regs->TXCSRL; + // TU_LOG1(" TXCSRL%d = %x\n", pipenum, csrl); + if (csrl & (USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) { + if (csrl & USB_TXCSRL1_TXRDY) + regs->TXCSRL = (csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR); + completed = true; + result = (csrl & USB_TXCSRL1_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + } else { + completed = pipe_xfer_out(pipenum); + result = XFER_RESULT_SUCCESS; + } + if (completed) { + pipe_addr_t *addr = &_hcd.addr[pipenum - 1][1]; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][1]; + hcd_event_xfer_complete(addr->dev, addr->ep, + pipe->length - pipe->remaining, + result, true); + } +} + +static void process_pipe_rx(uint8_t rhport, uint_fast8_t pipenum) +{ + (void)rhport; + bool completed; + uint8_t result; + + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + unsigned const csrl = regs->RXCSRL; + // TU_LOG1(" RXCSRL%d = %x\n", pipenum, csrl); + if (csrl & (USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) { + if (csrl & USB_RXCSRL1_RXRDY) + regs->RXCSRL = (csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR); + completed = true; + result = (csrl & USB_RXCSRL1_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + } else { + completed = pipe_xfer_in(pipenum); + result = XFER_RESULT_SUCCESS; + } + if (completed) { + pipe_addr_t *addr = &_hcd.addr[pipenum - 1][0]; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][0]; + hcd_event_xfer_complete(addr->dev, addr->ep, + pipe->length - pipe->remaining, + result, true); + } +} + +/*------------------------------------------------------------------ + * Host API + *------------------------------------------------------------------*/ + +bool hcd_init(uint8_t rhport) +{ + (void)rhport; + + NVIC_ClearPendingIRQ(USB0_IRQn); + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + USB0->DEVCTL |= USB_DEVCTL_SESSION; + USB0->IE = USB_IE_DISCON | USB_IE_CONN | USB_IE_BABBLE | USB_IE_RESUME; + return true; +} + +void hcd_int_enable(uint8_t rhport) +{ + (void)rhport; + NVIC_EnableIRQ(USB0_IRQn); +} + +void hcd_int_disable(uint8_t rhport) +{ + (void)rhport; + NVIC_DisableIRQ(USB0_IRQn); +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void)rhport; + /* The device must be reset at least once after connection + * in order to start the frame counter. */ + if (_hcd.need_reset) hcd_port_reset(rhport); + return USB0->FRAME; +} + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +bool hcd_port_connect_status(uint8_t rhport) +{ + (void)rhport; + unsigned devctl = USB0->DEVCTL; + if (!(devctl & USB_DEVCTL_HOST)) return false; + if (devctl & (USB_DEVCTL_LSDEV | USB_DEVCTL_FSDEV)) return true; + return false; +} + +void hcd_port_reset(uint8_t rhport) +{ + (void)rhport; + USB0->POWER |= USB_POWER_HSENAB | USB_POWER_RESET; + unsigned cnt = SystemCoreClock / 1000 * 20; + while (cnt--) __NOP(); + USB0->POWER &= ~USB_POWER_RESET; + _hcd.need_reset = false; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + (void)rhport; + unsigned devctl = USB0->DEVCTL; + if (devctl & USB_DEVCTL_LSDEV) return TUSB_SPEED_LOW; + if (!(devctl & USB_DEVCTL_FSDEV)) return TUSB_SPEED_INVALID; + if (USB0->POWER & USB_POWER_HSMODE) return TUSB_SPEED_HIGH; + return TUSB_SPEED_FULL; +} + +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + if (sizeof(_hcd.ctl_mps) <= dev_addr) return; + + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + _hcd.ctl_mps[dev_addr] = 0; + if (!dev_addr) return; + + pipe_addr_t *p = &_hcd.addr[0][0]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i) { + for (unsigned j = 0; j < 2; ++j, ++p) { + if (dev_addr != p->dev) continue; + hw_addr_t volatile *fadr = (hw_addr_t volatile*)&USB0->TXFUNCADDR0 + i + 1; + hw_endpoint_t volatile *regs = edpt_regs(i); + USB0->EPIDX = i + 1; + if (j) { + USB0->TXIE &= ~TU_BIT(i + 1); + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + regs->TXMAXP = 0; + regs->TXTYPE = 0; + regs->TXINTERVAL = 0; + fadr->TXFUNCADDR = 0; + fadr->TXHUBADDR = 0; + fadr->TXHUBPORT = 0; + USB0->TXFIFOADD = 0; + USB0->TXFIFOSZ = 0; + } else { + USB0->RXIE &= ~TU_BIT(i + 1); + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + regs->RXMAXP = 0; + regs->RXTYPE = 0; + regs->RXINTERVAL = 0; + fadr->RXFUNCADDR = 0; + fadr->RXHUBADDR = 0; + fadr->RXHUBPORT = 0; + USB0->RXFIFOADD = 0; + USB0->RXFIFOSZ = 0; + } + p->dev = 0; + p->ep = 0; + pipe_state_t *pipe = &_hcd.pipe[i][j]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + } + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void)rhport; + pipe_write_packet((void*)(uintptr_t)setup_packet, &USB0->FIFO0_WORD, 8); + _hcd.pipe0.buf = (void*)(uintptr_t)setup_packet; + _hcd.pipe0.length = 8; + _hcd.pipe0.remaining = 0; + + hcd_devtree_info_t devtree; + hcd_devtree_get_info(dev_addr, &devtree); + switch (devtree.speed) { + default: return false; + case TUSB_SPEED_LOW: USB0->TYPE0 = USB_TYPE0_SPEED_LOW; break; + case TUSB_SPEED_FULL: USB0->TYPE0 = USB_TYPE0_SPEED_FULL; break; + case TUSB_SPEED_HIGH: USB0->TYPE0 = USB_TYPE0_SPEED_HIGH; break; + } + USB0->TXHUBADDR0 = devtree.hub_addr; + USB0->TXHUBPORT0 = devtree.hub_port; + USB0->TXFUNCADDR0 = dev_addr; + USB0->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_SETUP; + return true; +} + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void)rhport; + if (sizeof(_hcd.ctl_mps) <= dev_addr) return false; + unsigned const ep_addr = ep_desc->bEndpointAddress; + unsigned const epn = tu_edpt_number(ep_addr); + if (0 == epn) { + _hcd.ctl_mps[dev_addr] = ep_desc->wMaxPacketSize; + return true; + } + + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + /* Find a free pipe */ + unsigned pipenum = 0; + pipe_addr_t *p = &_hcd.addr[0][dir_tx]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i, p += 2) { + if (0 == p->ep) { + p->dev = dev_addr; + p->ep = ep_addr; + pipenum = i + 1; + break; + } + } + if (!pipenum) return false; + + unsigned const xfer = ep_desc->bmAttributes.xfer; + unsigned const mps = tu_edpt_packet_size(ep_desc); + + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][dir_tx]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + uint8_t pipe_type = 0; + hcd_devtree_info_t devtree; + hcd_devtree_get_info(dev_addr, &devtree); + switch (devtree.speed) { + default: return false; + case TUSB_SPEED_LOW: pipe_type |= USB_TXTYPE1_SPEED_LOW; break; + case TUSB_SPEED_FULL: pipe_type |= USB_TXTYPE1_SPEED_FULL; break; + case TUSB_SPEED_HIGH: pipe_type |= USB_TXTYPE1_SPEED_HIGH; break; + } + switch (xfer) { + default: return false; + case TUSB_XFER_BULK: pipe_type |= USB_TXTYPE1_PROTO_BULK; break; + case TUSB_XFER_INTERRUPT: pipe_type |= USB_TXTYPE1_PROTO_INT; break; + case TUSB_XFER_ISOCHRONOUS: pipe_type |= USB_TXTYPE1_PROTO_ISOC; break; + } + + hw_addr_t volatile *fadr = (hw_addr_t volatile*)&USB0->TXFUNCADDR0 + pipenum; + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + if (dir_tx) { + fadr->TXFUNCADDR = dev_addr; + fadr->TXHUBADDR = devtree.hub_addr; + fadr->TXHUBPORT = devtree.hub_port; + regs->TXMAXP = mps; + regs->TXTYPE = pipe_type | epn; + regs->TXINTERVAL = ep_desc->bInterval; + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + USB0->TXIE |= TU_BIT(pipenum); + } else { + fadr->RXFUNCADDR = dev_addr; + fadr->RXHUBADDR = devtree.hub_addr; + fadr->RXHUBPORT = devtree.hub_port; + regs->RXMAXP = mps; + regs->RXTYPE = pipe_type | epn; + regs->RXINTERVAL = ep_desc->bInterval; + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + USB0->RXIE |= TU_BIT(pipenum); + } + + /* Setup FIFO */ + int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); + if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; + unsigned addr = find_free_memory(size_in_log2_minus3); + TU_ASSERT(addr); + + USB0->EPIDX = pipenum; + if (dir_tx) { + USB0->TXFIFOADD = addr; + USB0->TXFIFOSZ = size_in_log2_minus3; + } else { + USB0->RXFIFOADD = addr; + USB0->RXFIFOSZ = size_in_log2_minus3; + } + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + bool ret = false; + if (0 == tu_edpt_number(ep_addr)) { + ret = edpt0_xfer(rhport, dev_addr, ep_addr, buffer, buflen); + } else { + ret = edpt_xfer(rhport, dev_addr, ep_addr, buffer, buflen); + } + return ret; +} + +// clear stall, data toggle is also reset to DATA0 +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + unsigned const pipenum = find_pipe(dev_addr, ep_addr); + if (!pipenum) return false; + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + if (dir_tx) + regs->TXCSRL = USB_TXCSRL1_CLRDT; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + return true; +} + +/*------------------------------------------------------------------- + * ISR + *-------------------------------------------------------------------*/ +void hcd_int_handler(uint8_t rhport) +{ + uint_fast8_t is, txis, rxis; + + is = USB0->IS; /* read and clear interrupt status */ + txis = USB0->TXIS; /* read and clear interrupt status */ + rxis = USB0->RXIS; /* read and clear interrupt status */ + // TU_LOG1("D%2x T%2x R%2x\n", is, txis, rxis); + + is &= USB0->IE; /* Clear disabled interrupts */ + if (is & USB_IS_RESUME) { + } + if (is & USB_IS_CONN) { + _hcd.need_reset = true; + hcd_event_device_attach(rhport, true); + } + if (is & USB_IS_DISCON) { + hcd_event_device_remove(rhport, true); + } + if (is & USB_IS_BABBLE) { + } + txis &= USB0->TXIE; /* Clear disabled interrupts */ + if (txis & USB_TXIE_EP0) { + process_ep0(rhport); + txis &= ~TU_BIT(0); + } + while (txis) { + unsigned const num = __builtin_ctz(txis); + process_pipe_tx(rhport, num); + txis &= ~TU_BIT(num); + } + rxis &= USB0->RXIE; /* Clear disabled interrupts */ + while (rxis) { + unsigned const num = __builtin_ctz(rxis); + process_pipe_rx(rhport, num); + rxis &= ~TU_BIT(num); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_msp432e.h b/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_msp432e.h new file mode 100644 index 0000000..fce21de --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_msp432e.h @@ -0,0 +1,40 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MUSB_MSP432E_H_ +#define _TUSB_MUSB_MSP432E_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "msp.h" + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_tm4c.h b/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_tm4c.h new file mode 100644 index 0000000..65a1751 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_tm4c.h @@ -0,0 +1,45 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MUSB_TM4C_H_ +#define _TUSB_MUSB_TM4C_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#if CFG_TUSB_MCU == OPT_MCU_TM4C123 + #include "TM4C123.h" +//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 +#else + #error "Unsupported MCUs" +#endif + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_type.h b/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_type.h new file mode 100644 index 0000000..8f83305 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/mentor/musb/musb_type.h @@ -0,0 +1,2624 @@ +/****************************************************************************** +* +* Copyright (C) 2018 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 _TUSB_MUSB_TYPE_H_ +#define _TUSB_MUSB_TYPE_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FADDR register. +// +//***************************************************************************** +#define USB_FADDR_M 0x0000007F // Function Address +#define USB_FADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_POWER register. +// +//***************************************************************************** +#define USB_POWER_ISOUP 0x00000080 // Isochronous Update +#define USB_POWER_SOFTCONN 0x00000040 // Soft Connect/Disconnect +#define USB_POWER_HSENAB 0x00000020 // High Speed Enable +#define USB_POWER_HSMODE 0x00000010 // High Speed Enable +#define USB_POWER_RESET 0x00000008 // RESET Signaling +#define USB_POWER_RESUME 0x00000004 // RESUME Signaling +#define USB_POWER_SUSPEND 0x00000002 // SUSPEND Mode +#define USB_POWER_PWRDNPHY 0x00000001 // Power Down PHY + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXIS register. +// +//***************************************************************************** +#define USB_TXIS_EP7 0x00000080 // TX Endpoint 7 Interrupt +#define USB_TXIS_EP6 0x00000040 // TX Endpoint 6 Interrupt +#define USB_TXIS_EP5 0x00000020 // TX Endpoint 5 Interrupt +#define USB_TXIS_EP4 0x00000010 // TX Endpoint 4 Interrupt +#define USB_TXIS_EP3 0x00000008 // TX Endpoint 3 Interrupt +#define USB_TXIS_EP2 0x00000004 // TX Endpoint 2 Interrupt +#define USB_TXIS_EP1 0x00000002 // TX Endpoint 1 Interrupt +#define USB_TXIS_EP0 0x00000001 // TX and RX Endpoint 0 Interrupt + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXIS register. +// +//***************************************************************************** +#define USB_RXIS_EP7 0x00000080 // RX Endpoint 7 Interrupt +#define USB_RXIS_EP6 0x00000040 // RX Endpoint 6 Interrupt +#define USB_RXIS_EP5 0x00000020 // RX Endpoint 5 Interrupt +#define USB_RXIS_EP4 0x00000010 // RX Endpoint 4 Interrupt +#define USB_RXIS_EP3 0x00000008 // RX Endpoint 3 Interrupt +#define USB_RXIS_EP2 0x00000004 // RX Endpoint 2 Interrupt +#define USB_RXIS_EP1 0x00000002 // RX Endpoint 1 Interrupt + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXIE register. +// +//***************************************************************************** +#define USB_TXIE_EP7 0x00000080 // TX Endpoint 7 Interrupt Enable +#define USB_TXIE_EP6 0x00000040 // TX Endpoint 6 Interrupt Enable +#define USB_TXIE_EP5 0x00000020 // TX Endpoint 5 Interrupt Enable +#define USB_TXIE_EP4 0x00000010 // TX Endpoint 4 Interrupt Enable +#define USB_TXIE_EP3 0x00000008 // TX Endpoint 3 Interrupt Enable +#define USB_TXIE_EP2 0x00000004 // TX Endpoint 2 Interrupt Enable +#define USB_TXIE_EP1 0x00000002 // TX Endpoint 1 Interrupt Enable +#define USB_TXIE_EP0 0x00000001 // TX and RX Endpoint 0 Interrupt + // Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXIE register. +// +//***************************************************************************** +#define USB_RXIE_EP7 0x00000080 // RX Endpoint 7 Interrupt Enable +#define USB_RXIE_EP6 0x00000040 // RX Endpoint 6 Interrupt Enable +#define USB_RXIE_EP5 0x00000020 // RX Endpoint 5 Interrupt Enable +#define USB_RXIE_EP4 0x00000010 // RX Endpoint 4 Interrupt Enable +#define USB_RXIE_EP3 0x00000008 // RX Endpoint 3 Interrupt Enable +#define USB_RXIE_EP2 0x00000004 // RX Endpoint 2 Interrupt Enable +#define USB_RXIE_EP1 0x00000002 // RX Endpoint 1 Interrupt Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_IS register. +// +//***************************************************************************** +#define USB_IS_VBUSERR 0x00000080 // VBUS Error (OTG only) +#define USB_IS_SESREQ 0x00000040 // SESSION REQUEST (OTG only) +#define USB_IS_DISCON 0x00000020 // Session Disconnect (OTG only) +#define USB_IS_CONN 0x00000010 // Session Connect +#define USB_IS_SOF 0x00000008 // Start of Frame +#define USB_IS_BABBLE 0x00000004 // Babble Detected +#define USB_IS_RESET 0x00000004 // RESET Signaling Detected +#define USB_IS_RESUME 0x00000002 // RESUME Signaling Detected +#define USB_IS_SUSPEND 0x00000001 // SUSPEND Signaling Detected + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_IE register. +// +//***************************************************************************** +#define USB_IE_VBUSERR 0x00000080 // Enable VBUS Error Interrupt (OTG + // only) +#define USB_IE_SESREQ 0x00000040 // Enable Session Request (OTG + // only) +#define USB_IE_DISCON 0x00000020 // Enable Disconnect Interrupt +#define USB_IE_CONN 0x00000010 // Enable Connect Interrupt +#define USB_IE_SOF 0x00000008 // Enable Start-of-Frame Interrupt +#define USB_IE_BABBLE 0x00000004 // Enable Babble Interrupt +#define USB_IE_RESET 0x00000004 // Enable RESET Interrupt +#define USB_IE_RESUME 0x00000002 // Enable RESUME Interrupt +#define USB_IE_SUSPND 0x00000001 // Enable SUSPEND Interrupt + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FRAME register. +// +//***************************************************************************** +#define USB_FRAME_M 0x000007FF // Frame Number +#define USB_FRAME_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_EPIDX register. +// +//***************************************************************************** +#define USB_EPIDX_EPIDX_M 0x0000000F // Endpoint Index +#define USB_EPIDX_EPIDX_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TEST register. +// +//***************************************************************************** +#define USB_TEST_FORCEH 0x00000080 // Force Host Mode +#define USB_TEST_FIFOACC 0x00000040 // FIFO Access +#define USB_TEST_FORCEFS 0x00000020 // Force Full-Speed Mode +#define USB_TEST_FORCEHS 0x00000010 // Force High-Speed Mode +#define USB_TEST_TESTPKT 0x00000008 // Test Packet Mode Enable +#define USB_TEST_TESTK 0x00000004 // Test_K Mode Enable +#define USB_TEST_TESTJ 0x00000002 // Test_J Mode Enable +#define USB_TEST_TESTSE0NAK 0x00000001 // Test_SE0_NAK Test Mode Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FIFO0 register. +// +//***************************************************************************** +#define USB_FIFO0_EPDATA_M 0xFFFFFFFF // Endpoint Data +#define USB_FIFO0_EPDATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FIFO1 register. +// +//***************************************************************************** +#define USB_FIFO1_EPDATA_M 0xFFFFFFFF // Endpoint Data +#define USB_FIFO1_EPDATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FIFO2 register. +// +//***************************************************************************** +#define USB_FIFO2_EPDATA_M 0xFFFFFFFF // Endpoint Data +#define USB_FIFO2_EPDATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FIFO3 register. +// +//***************************************************************************** +#define USB_FIFO3_EPDATA_M 0xFFFFFFFF // Endpoint Data +#define USB_FIFO3_EPDATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FIFO4 register. +// +//***************************************************************************** +#define USB_FIFO4_EPDATA_M 0xFFFFFFFF // Endpoint Data +#define USB_FIFO4_EPDATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FIFO5 register. +// +//***************************************************************************** +#define USB_FIFO5_EPDATA_M 0xFFFFFFFF // Endpoint Data +#define USB_FIFO5_EPDATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FIFO6 register. +// +//***************************************************************************** +#define USB_FIFO6_EPDATA_M 0xFFFFFFFF // Endpoint Data +#define USB_FIFO6_EPDATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FIFO7 register. +// +//***************************************************************************** +#define USB_FIFO7_EPDATA_M 0xFFFFFFFF // Endpoint Data +#define USB_FIFO7_EPDATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DEVCTL register. +// +//***************************************************************************** +#define USB_DEVCTL_DEV 0x00000080 // Device Mode (OTG only) +#define USB_DEVCTL_FSDEV 0x00000040 // Full-Speed Device Detected +#define USB_DEVCTL_LSDEV 0x00000020 // Low-Speed Device Detected +#define USB_DEVCTL_VBUS_M 0x00000018 // VBUS Level (OTG only) +#define USB_DEVCTL_VBUS_NONE 0x00000000 // Below SessionEnd +#define USB_DEVCTL_VBUS_SEND 0x00000008 // Above SessionEnd, below AValid +#define USB_DEVCTL_VBUS_AVALID 0x00000010 // Above AValid, below VBUSValid +#define USB_DEVCTL_VBUS_VALID 0x00000018 // Above VBUSValid +#define USB_DEVCTL_HOST 0x00000004 // Host Mode +#define USB_DEVCTL_HOSTREQ 0x00000002 // Host Request (OTG only) +#define USB_DEVCTL_SESSION 0x00000001 // Session Start/End (OTG only) + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_CCONF register. +// +//***************************************************************************** +#define USB_CCONF_TXEDMA 0x00000002 // TX Early DMA Enable +#define USB_CCONF_RXEDMA 0x00000001 // TX Early DMA Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFIFOSZ register. +// +//***************************************************************************** +#define USB_TXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support +#define USB_TXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size +#define USB_TXFIFOSZ_SIZE_8 0x00000000 // 8 +#define USB_TXFIFOSZ_SIZE_16 0x00000001 // 16 +#define USB_TXFIFOSZ_SIZE_32 0x00000002 // 32 +#define USB_TXFIFOSZ_SIZE_64 0x00000003 // 64 +#define USB_TXFIFOSZ_SIZE_128 0x00000004 // 128 +#define USB_TXFIFOSZ_SIZE_256 0x00000005 // 256 +#define USB_TXFIFOSZ_SIZE_512 0x00000006 // 512 +#define USB_TXFIFOSZ_SIZE_1024 0x00000007 // 1024 +#define USB_TXFIFOSZ_SIZE_2048 0x00000008 // 2048 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFIFOSZ register. +// +//***************************************************************************** +#define USB_RXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support +#define USB_RXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size +#define USB_RXFIFOSZ_SIZE_8 0x00000000 // 8 +#define USB_RXFIFOSZ_SIZE_16 0x00000001 // 16 +#define USB_RXFIFOSZ_SIZE_32 0x00000002 // 32 +#define USB_RXFIFOSZ_SIZE_64 0x00000003 // 64 +#define USB_RXFIFOSZ_SIZE_128 0x00000004 // 128 +#define USB_RXFIFOSZ_SIZE_256 0x00000005 // 256 +#define USB_RXFIFOSZ_SIZE_512 0x00000006 // 512 +#define USB_RXFIFOSZ_SIZE_1024 0x00000007 // 1024 +#define USB_RXFIFOSZ_SIZE_2048 0x00000008 // 2048 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFIFOADD +// register. +// +//***************************************************************************** +#define USB_TXFIFOADD_ADDR_M 0x000001FF // Transmit/Receive Start Address +#define USB_TXFIFOADD_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFIFOADD +// register. +// +//***************************************************************************** +#define USB_RXFIFOADD_ADDR_M 0x000001FF // Transmit/Receive Start Address +#define USB_RXFIFOADD_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_ULPIVBUSCTL +// register. +// +//***************************************************************************** +#define USB_ULPIVBUSCTL_USEEXTVBUSIND \ + 0x00000002 // Use External VBUS Indicator +#define USB_ULPIVBUSCTL_USEEXTVBUS \ + 0x00000001 // Use External VBUS + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_ULPIREGDATA +// register. +// +//***************************************************************************** +#define USB_ULPIREGDATA_REGDATA_M \ + 0x000000FF // Register Data +#define USB_ULPIREGDATA_REGDATA_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_ULPIREGADDR +// register. +// +//***************************************************************************** +#define USB_ULPIREGADDR_ADDR_M 0x000000FF // Register Address +#define USB_ULPIREGADDR_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_ULPIREGCTL +// register. +// +//***************************************************************************** +#define USB_ULPIREGCTL_RDWR 0x00000004 // Read/Write Control +#define USB_ULPIREGCTL_REGCMPLT 0x00000002 // Register Access Complete +#define USB_ULPIREGCTL_REGACC 0x00000001 // Initiate Register Access + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_EPINFO register. +// +//***************************************************************************** +#define USB_EPINFO_RXEP_M 0x000000F0 // RX Endpoints +#define USB_EPINFO_TXEP_M 0x0000000F // TX Endpoints +#define USB_EPINFO_RXEP_S 4 +#define USB_EPINFO_TXEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RAMINFO register. +// +//***************************************************************************** +#define USB_RAMINFO_DMACHAN_M 0x000000F0 // DMA Channels +#define USB_RAMINFO_RAMBITS_M 0x0000000F // RAM Address Bus Width +#define USB_RAMINFO_DMACHAN_S 4 +#define USB_RAMINFO_RAMBITS_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_CONTIM register. +// +//***************************************************************************** +#define USB_CONTIM_WTCON_M 0x000000F0 // Connect Wait +#define USB_CONTIM_WTID_M 0x0000000F // Wait ID +#define USB_CONTIM_WTCON_S 4 +#define USB_CONTIM_WTID_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_VPLEN register. +// +//***************************************************************************** +#define USB_VPLEN_VPLEN_M 0x000000FF // VBUS Pulse Length +#define USB_VPLEN_VPLEN_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_HSEOF register. +// +//***************************************************************************** +#define USB_HSEOF_HSEOFG_M 0x000000FF // HIgh-Speed End-of-Frame Gap +#define USB_HSEOF_HSEOFG_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_FSEOF register. +// +//***************************************************************************** +#define USB_FSEOF_FSEOFG_M 0x000000FF // Full-Speed End-of-Frame Gap +#define USB_FSEOF_FSEOFG_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_LSEOF register. +// +//***************************************************************************** +#define USB_LSEOF_LSEOFG_M 0x000000FF // Low-Speed End-of-Frame Gap +#define USB_LSEOF_LSEOFG_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFUNCADDR0 +// register. +// +//***************************************************************************** +#define USB_TXFUNCADDR0_ADDR_M 0x0000007F // Device Address +#define USB_TXFUNCADDR0_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBADDR0 +// register. +// +//***************************************************************************** +#define USB_TXHUBADDR0_ADDR_M 0x0000007F // Hub Address +#define USB_TXHUBADDR0_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBPORT0 +// register. +// +//***************************************************************************** +#define USB_TXHUBPORT0_PORT_M 0x0000007F // Hub Port +#define USB_TXHUBPORT0_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFUNCADDR1 +// register. +// +//***************************************************************************** +#define USB_TXFUNCADDR1_ADDR_M 0x0000007F // Device Address +#define USB_TXFUNCADDR1_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBADDR1 +// register. +// +//***************************************************************************** +#define USB_TXHUBADDR1_ADDR_M 0x0000007F // Hub Address +#define USB_TXHUBADDR1_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBPORT1 +// register. +// +//***************************************************************************** +#define USB_TXHUBPORT1_PORT_M 0x0000007F // Hub Port +#define USB_TXHUBPORT1_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFUNCADDR1 +// register. +// +//***************************************************************************** +#define USB_RXFUNCADDR1_ADDR_M 0x0000007F // Device Address +#define USB_RXFUNCADDR1_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBADDR1 +// register. +// +//***************************************************************************** +#define USB_RXHUBADDR1_ADDR_M 0x0000007F // Hub Address +#define USB_RXHUBADDR1_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBPORT1 +// register. +// +//***************************************************************************** +#define USB_RXHUBPORT1_PORT_M 0x0000007F // Hub Port +#define USB_RXHUBPORT1_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFUNCADDR2 +// register. +// +//***************************************************************************** +#define USB_TXFUNCADDR2_ADDR_M 0x0000007F // Device Address +#define USB_TXFUNCADDR2_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBADDR2 +// register. +// +//***************************************************************************** +#define USB_TXHUBADDR2_ADDR_M 0x0000007F // Hub Address +#define USB_TXHUBADDR2_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBPORT2 +// register. +// +//***************************************************************************** +#define USB_TXHUBPORT2_PORT_M 0x0000007F // Hub Port +#define USB_TXHUBPORT2_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFUNCADDR2 +// register. +// +//***************************************************************************** +#define USB_RXFUNCADDR2_ADDR_M 0x0000007F // Device Address +#define USB_RXFUNCADDR2_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBADDR2 +// register. +// +//***************************************************************************** +#define USB_RXHUBADDR2_ADDR_M 0x0000007F // Hub Address +#define USB_RXHUBADDR2_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBPORT2 +// register. +// +//***************************************************************************** +#define USB_RXHUBPORT2_PORT_M 0x0000007F // Hub Port +#define USB_RXHUBPORT2_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFUNCADDR3 +// register. +// +//***************************************************************************** +#define USB_TXFUNCADDR3_ADDR_M 0x0000007F // Device Address +#define USB_TXFUNCADDR3_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBADDR3 +// register. +// +//***************************************************************************** +#define USB_TXHUBADDR3_ADDR_M 0x0000007F // Hub Address +#define USB_TXHUBADDR3_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBPORT3 +// register. +// +//***************************************************************************** +#define USB_TXHUBPORT3_PORT_M 0x0000007F // Hub Port +#define USB_TXHUBPORT3_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFUNCADDR3 +// register. +// +//***************************************************************************** +#define USB_RXFUNCADDR3_ADDR_M 0x0000007F // Device Address +#define USB_RXFUNCADDR3_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBADDR3 +// register. +// +//***************************************************************************** +#define USB_RXHUBADDR3_ADDR_M 0x0000007F // Hub Address +#define USB_RXHUBADDR3_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBPORT3 +// register. +// +//***************************************************************************** +#define USB_RXHUBPORT3_PORT_M 0x0000007F // Hub Port +#define USB_RXHUBPORT3_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFUNCADDR4 +// register. +// +//***************************************************************************** +#define USB_TXFUNCADDR4_ADDR_M 0x0000007F // Device Address +#define USB_TXFUNCADDR4_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBADDR4 +// register. +// +//***************************************************************************** +#define USB_TXHUBADDR4_ADDR_M 0x0000007F // Hub Address +#define USB_TXHUBADDR4_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBPORT4 +// register. +// +//***************************************************************************** +#define USB_TXHUBPORT4_PORT_M 0x0000007F // Hub Port +#define USB_TXHUBPORT4_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFUNCADDR4 +// register. +// +//***************************************************************************** +#define USB_RXFUNCADDR4_ADDR_M 0x0000007F // Device Address +#define USB_RXFUNCADDR4_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBADDR4 +// register. +// +//***************************************************************************** +#define USB_RXHUBADDR4_ADDR_M 0x0000007F // Hub Address +#define USB_RXHUBADDR4_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBPORT4 +// register. +// +//***************************************************************************** +#define USB_RXHUBPORT4_PORT_M 0x0000007F // Hub Port +#define USB_RXHUBPORT4_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFUNCADDR5 +// register. +// +//***************************************************************************** +#define USB_TXFUNCADDR5_ADDR_M 0x0000007F // Device Address +#define USB_TXFUNCADDR5_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBADDR5 +// register. +// +//***************************************************************************** +#define USB_TXHUBADDR5_ADDR_M 0x0000007F // Hub Address +#define USB_TXHUBADDR5_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBPORT5 +// register. +// +//***************************************************************************** +#define USB_TXHUBPORT5_PORT_M 0x0000007F // Hub Port +#define USB_TXHUBPORT5_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFUNCADDR5 +// register. +// +//***************************************************************************** +#define USB_RXFUNCADDR5_ADDR_M 0x0000007F // Device Address +#define USB_RXFUNCADDR5_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBADDR5 +// register. +// +//***************************************************************************** +#define USB_RXHUBADDR5_ADDR_M 0x0000007F // Hub Address +#define USB_RXHUBADDR5_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBPORT5 +// register. +// +//***************************************************************************** +#define USB_RXHUBPORT5_PORT_M 0x0000007F // Hub Port +#define USB_RXHUBPORT5_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFUNCADDR6 +// register. +// +//***************************************************************************** +#define USB_TXFUNCADDR6_ADDR_M 0x0000007F // Device Address +#define USB_TXFUNCADDR6_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBADDR6 +// register. +// +//***************************************************************************** +#define USB_TXHUBADDR6_ADDR_M 0x0000007F // Hub Address +#define USB_TXHUBADDR6_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBPORT6 +// register. +// +//***************************************************************************** +#define USB_TXHUBPORT6_PORT_M 0x0000007F // Hub Port +#define USB_TXHUBPORT6_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFUNCADDR6 +// register. +// +//***************************************************************************** +#define USB_RXFUNCADDR6_ADDR_M 0x0000007F // Device Address +#define USB_RXFUNCADDR6_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBADDR6 +// register. +// +//***************************************************************************** +#define USB_RXHUBADDR6_ADDR_M 0x0000007F // Hub Address +#define USB_RXHUBADDR6_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBPORT6 +// register. +// +//***************************************************************************** +#define USB_RXHUBPORT6_PORT_M 0x0000007F // Hub Port +#define USB_RXHUBPORT6_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXFUNCADDR7 +// register. +// +//***************************************************************************** +#define USB_TXFUNCADDR7_ADDR_M 0x0000007F // Device Address +#define USB_TXFUNCADDR7_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBADDR7 +// register. +// +//***************************************************************************** +#define USB_TXHUBADDR7_ADDR_M 0x0000007F // Hub Address +#define USB_TXHUBADDR7_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXHUBPORT7 +// register. +// +//***************************************************************************** +#define USB_TXHUBPORT7_PORT_M 0x0000007F // Hub Port +#define USB_TXHUBPORT7_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXFUNCADDR7 +// register. +// +//***************************************************************************** +#define USB_RXFUNCADDR7_ADDR_M 0x0000007F // Device Address +#define USB_RXFUNCADDR7_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBADDR7 +// register. +// +//***************************************************************************** +#define USB_RXHUBADDR7_ADDR_M 0x0000007F // Hub Address +#define USB_RXHUBADDR7_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXHUBPORT7 +// register. +// +//***************************************************************************** +#define USB_RXHUBPORT7_PORT_M 0x0000007F // Hub Port +#define USB_RXHUBPORT7_PORT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_CSRL0 register. +// +//***************************************************************************** +#define USB_CSRL0_NAKTO 0x00000080 // NAK Timeout +#define USB_CSRL0_SETENDC 0x00000080 // Setup End Clear +#define USB_CSRL0_STATUS 0x00000040 // STATUS Packet +#define USB_CSRL0_RXRDYC 0x00000040 // RXRDY Clear +#define USB_CSRL0_REQPKT 0x00000020 // Request Packet +#define USB_CSRL0_STALL 0x00000020 // Send Stall +#define USB_CSRL0_SETEND 0x00000010 // Setup End +#define USB_CSRL0_ERROR 0x00000010 // Error +#define USB_CSRL0_DATAEND 0x00000008 // Data End +#define USB_CSRL0_SETUP 0x00000008 // Setup Packet +#define USB_CSRL0_STALLED 0x00000004 // Endpoint Stalled +#define USB_CSRL0_TXRDY 0x00000002 // Transmit Packet Ready +#define USB_CSRL0_RXRDY 0x00000001 // Receive Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_CSRH0 register. +// +//***************************************************************************** +#define USB_CSRH0_DISPING 0x00000008 // PING Disable +#define USB_CSRH0_DTWE 0x00000004 // Data Toggle Write Enable +#define USB_CSRH0_DT 0x00000002 // Data Toggle +#define USB_CSRH0_FLUSH 0x00000001 // Flush FIFO + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_COUNT0 register. +// +//***************************************************************************** +#define USB_COUNT0_COUNT_M 0x0000007F // FIFO Count +#define USB_COUNT0_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TYPE0 register. +// +//***************************************************************************** +#define USB_TYPE0_SPEED_M 0x000000C0 // Operating Speed +#define USB_TYPE0_SPEED_HIGH 0x00000040 // High +#define USB_TYPE0_SPEED_FULL 0x00000080 // Full +#define USB_TYPE0_SPEED_LOW 0x000000C0 // Low + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_NAKLMT register. +// +//***************************************************************************** +#define USB_NAKLMT_NAKLMT_M 0x0000001F // EP0 NAK Limit +#define USB_NAKLMT_NAKLMT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXMAXP1 register. +// +//***************************************************************************** +#define USB_TXMAXP1_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP1_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRL1 register. +// +//***************************************************************************** +#define USB_TXCSRL1_NAKTO 0x00000080 // NAK Timeout +#define USB_TXCSRL1_CLRDT 0x00000040 // Clear Data Toggle +#define USB_TXCSRL1_STALLED 0x00000020 // Endpoint Stalled +#define USB_TXCSRL1_STALL 0x00000010 // Send STALL +#define USB_TXCSRL1_SETUP 0x00000010 // Setup Packet +#define USB_TXCSRL1_FLUSH 0x00000008 // Flush FIFO +#define USB_TXCSRL1_ERROR 0x00000004 // Error +#define USB_TXCSRL1_UNDRN 0x00000004 // Underrun +#define USB_TXCSRL1_FIFONE 0x00000002 // FIFO Not Empty +#define USB_TXCSRL1_TXRDY 0x00000001 // Transmit Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRH1 register. +// +//***************************************************************************** +#define USB_TXCSRH1_AUTOSET 0x00000080 // Auto Set +#define USB_TXCSRH1_ISO 0x00000040 // Isochronous Transfers +#define USB_TXCSRH1_MODE 0x00000020 // Mode +#define USB_TXCSRH1_DMAEN 0x00000010 // DMA Request Enable +#define USB_TXCSRH1_FDT 0x00000008 // Force Data Toggle +#define USB_TXCSRH1_DMAMOD 0x00000004 // DMA Request Mode +#define USB_TXCSRH1_DTWE 0x00000002 // Data Toggle Write Enable +#define USB_TXCSRH1_DT 0x00000001 // Data Toggle + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXMAXP1 register. +// +//***************************************************************************** +#define USB_RXMAXP1_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP1_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRL1 register. +// +//***************************************************************************** +#define USB_RXCSRL1_CLRDT 0x00000080 // Clear Data Toggle +#define USB_RXCSRL1_STALLED 0x00000040 // Endpoint Stalled +#define USB_RXCSRL1_STALL 0x00000020 // Send STALL +#define USB_RXCSRL1_REQPKT 0x00000020 // Request Packet +#define USB_RXCSRL1_FLUSH 0x00000010 // Flush FIFO +#define USB_RXCSRL1_DATAERR 0x00000008 // Data Error +#define USB_RXCSRL1_NAKTO 0x00000008 // NAK Timeout +#define USB_RXCSRL1_OVER 0x00000004 // Overrun +#define USB_RXCSRL1_ERROR 0x00000004 // Error +#define USB_RXCSRL1_FULL 0x00000002 // FIFO Full +#define USB_RXCSRL1_RXRDY 0x00000001 // Receive Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRH1 register. +// +//***************************************************************************** +#define USB_RXCSRH1_AUTOCL 0x00000080 // Auto Clear +#define USB_RXCSRH1_AUTORQ 0x00000040 // Auto Request +#define USB_RXCSRH1_ISO 0x00000040 // Isochronous Transfers +#define USB_RXCSRH1_DMAEN 0x00000020 // DMA Request Enable +#define USB_RXCSRH1_DISNYET 0x00000010 // Disable NYET +#define USB_RXCSRH1_PIDERR 0x00000010 // PID Error +#define USB_RXCSRH1_DMAMOD 0x00000008 // DMA Request Mode +#define USB_RXCSRH1_DTWE 0x00000004 // Data Toggle Write Enable +#define USB_RXCSRH1_DT 0x00000002 // Data Toggle +#define USB_RXCSRH1_INCOMPRX 0x00000001 // Incomplete RX Transmission + // Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCOUNT1 register. +// +//***************************************************************************** +#define USB_RXCOUNT1_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT1_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXTYPE1 register. +// +//***************************************************************************** +#define USB_TXTYPE1_SPEED_M 0x000000C0 // Operating Speed +#define USB_TXTYPE1_SPEED_DFLT 0x00000000 // Default +#define USB_TXTYPE1_SPEED_HIGH 0x00000040 // High +#define USB_TXTYPE1_SPEED_FULL 0x00000080 // Full +#define USB_TXTYPE1_SPEED_LOW 0x000000C0 // Low +#define USB_TXTYPE1_PROTO_M 0x00000030 // Protocol +#define USB_TXTYPE1_PROTO_CTRL 0x00000000 // Control +#define USB_TXTYPE1_PROTO_ISOC 0x00000010 // Isochronous +#define USB_TXTYPE1_PROTO_BULK 0x00000020 // Bulk +#define USB_TXTYPE1_PROTO_INT 0x00000030 // Interrupt +#define USB_TXTYPE1_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE1_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXINTERVAL1 +// register. +// +//***************************************************************************** +#define USB_TXINTERVAL1_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_TXINTERVAL1_TXPOLL_M \ + 0x000000FF // TX Polling +#define USB_TXINTERVAL1_TXPOLL_S \ + 0 +#define USB_TXINTERVAL1_NAKLMT_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXTYPE1 register. +// +//***************************************************************************** +#define USB_RXTYPE1_SPEED_M 0x000000C0 // Operating Speed +#define USB_RXTYPE1_SPEED_DFLT 0x00000000 // Default +#define USB_RXTYPE1_SPEED_HIGH 0x00000040 // High +#define USB_RXTYPE1_SPEED_FULL 0x00000080 // Full +#define USB_RXTYPE1_SPEED_LOW 0x000000C0 // Low +#define USB_RXTYPE1_PROTO_M 0x00000030 // Protocol +#define USB_RXTYPE1_PROTO_CTRL 0x00000000 // Control +#define USB_RXTYPE1_PROTO_ISOC 0x00000010 // Isochronous +#define USB_RXTYPE1_PROTO_BULK 0x00000020 // Bulk +#define USB_RXTYPE1_PROTO_INT 0x00000030 // Interrupt +#define USB_RXTYPE1_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE1_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXINTERVAL1 +// register. +// +//***************************************************************************** +#define USB_RXINTERVAL1_TXPOLL_M \ + 0x000000FF // RX Polling +#define USB_RXINTERVAL1_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_RXINTERVAL1_TXPOLL_S \ + 0 +#define USB_RXINTERVAL1_NAKLMT_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXMAXP2 register. +// +//***************************************************************************** +#define USB_TXMAXP2_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP2_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRL2 register. +// +//***************************************************************************** +#define USB_TXCSRL2_NAKTO 0x00000080 // NAK Timeout +#define USB_TXCSRL2_CLRDT 0x00000040 // Clear Data Toggle +#define USB_TXCSRL2_STALLED 0x00000020 // Endpoint Stalled +#define USB_TXCSRL2_SETUP 0x00000010 // Setup Packet +#define USB_TXCSRL2_STALL 0x00000010 // Send STALL +#define USB_TXCSRL2_FLUSH 0x00000008 // Flush FIFO +#define USB_TXCSRL2_ERROR 0x00000004 // Error +#define USB_TXCSRL2_UNDRN 0x00000004 // Underrun +#define USB_TXCSRL2_FIFONE 0x00000002 // FIFO Not Empty +#define USB_TXCSRL2_TXRDY 0x00000001 // Transmit Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRH2 register. +// +//***************************************************************************** +#define USB_TXCSRH2_AUTOSET 0x00000080 // Auto Set +#define USB_TXCSRH2_ISO 0x00000040 // Isochronous Transfers +#define USB_TXCSRH2_MODE 0x00000020 // Mode +#define USB_TXCSRH2_DMAEN 0x00000010 // DMA Request Enable +#define USB_TXCSRH2_FDT 0x00000008 // Force Data Toggle +#define USB_TXCSRH2_DMAMOD 0x00000004 // DMA Request Mode +#define USB_TXCSRH2_DTWE 0x00000002 // Data Toggle Write Enable +#define USB_TXCSRH2_DT 0x00000001 // Data Toggle + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXMAXP2 register. +// +//***************************************************************************** +#define USB_RXMAXP2_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP2_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRL2 register. +// +//***************************************************************************** +#define USB_RXCSRL2_CLRDT 0x00000080 // Clear Data Toggle +#define USB_RXCSRL2_STALLED 0x00000040 // Endpoint Stalled +#define USB_RXCSRL2_REQPKT 0x00000020 // Request Packet +#define USB_RXCSRL2_STALL 0x00000020 // Send STALL +#define USB_RXCSRL2_FLUSH 0x00000010 // Flush FIFO +#define USB_RXCSRL2_DATAERR 0x00000008 // Data Error +#define USB_RXCSRL2_NAKTO 0x00000008 // NAK Timeout +#define USB_RXCSRL2_ERROR 0x00000004 // Error +#define USB_RXCSRL2_OVER 0x00000004 // Overrun +#define USB_RXCSRL2_FULL 0x00000002 // FIFO Full +#define USB_RXCSRL2_RXRDY 0x00000001 // Receive Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRH2 register. +// +//***************************************************************************** +#define USB_RXCSRH2_AUTOCL 0x00000080 // Auto Clear +#define USB_RXCSRH2_AUTORQ 0x00000040 // Auto Request +#define USB_RXCSRH2_ISO 0x00000040 // Isochronous Transfers +#define USB_RXCSRH2_DMAEN 0x00000020 // DMA Request Enable +#define USB_RXCSRH2_DISNYET 0x00000010 // Disable NYET +#define USB_RXCSRH2_PIDERR 0x00000010 // PID Error +#define USB_RXCSRH2_DMAMOD 0x00000008 // DMA Request Mode +#define USB_RXCSRH2_DTWE 0x00000004 // Data Toggle Write Enable +#define USB_RXCSRH2_DT 0x00000002 // Data Toggle +#define USB_RXCSRH2_INCOMPRX 0x00000001 // Incomplete RX Transmission + // Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCOUNT2 register. +// +//***************************************************************************** +#define USB_RXCOUNT2_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT2_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXTYPE2 register. +// +//***************************************************************************** +#define USB_TXTYPE2_SPEED_M 0x000000C0 // Operating Speed +#define USB_TXTYPE2_SPEED_DFLT 0x00000000 // Default +#define USB_TXTYPE2_SPEED_HIGH 0x00000040 // High +#define USB_TXTYPE2_SPEED_FULL 0x00000080 // Full +#define USB_TXTYPE2_SPEED_LOW 0x000000C0 // Low +#define USB_TXTYPE2_PROTO_M 0x00000030 // Protocol +#define USB_TXTYPE2_PROTO_CTRL 0x00000000 // Control +#define USB_TXTYPE2_PROTO_ISOC 0x00000010 // Isochronous +#define USB_TXTYPE2_PROTO_BULK 0x00000020 // Bulk +#define USB_TXTYPE2_PROTO_INT 0x00000030 // Interrupt +#define USB_TXTYPE2_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE2_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXINTERVAL2 +// register. +// +//***************************************************************************** +#define USB_TXINTERVAL2_TXPOLL_M \ + 0x000000FF // TX Polling +#define USB_TXINTERVAL2_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_TXINTERVAL2_NAKLMT_S \ + 0 +#define USB_TXINTERVAL2_TXPOLL_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXTYPE2 register. +// +//***************************************************************************** +#define USB_RXTYPE2_SPEED_M 0x000000C0 // Operating Speed +#define USB_RXTYPE2_SPEED_DFLT 0x00000000 // Default +#define USB_RXTYPE2_SPEED_HIGH 0x00000040 // High +#define USB_RXTYPE2_SPEED_FULL 0x00000080 // Full +#define USB_RXTYPE2_SPEED_LOW 0x000000C0 // Low +#define USB_RXTYPE2_PROTO_M 0x00000030 // Protocol +#define USB_RXTYPE2_PROTO_CTRL 0x00000000 // Control +#define USB_RXTYPE2_PROTO_ISOC 0x00000010 // Isochronous +#define USB_RXTYPE2_PROTO_BULK 0x00000020 // Bulk +#define USB_RXTYPE2_PROTO_INT 0x00000030 // Interrupt +#define USB_RXTYPE2_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE2_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXINTERVAL2 +// register. +// +//***************************************************************************** +#define USB_RXINTERVAL2_TXPOLL_M \ + 0x000000FF // RX Polling +#define USB_RXINTERVAL2_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_RXINTERVAL2_TXPOLL_S \ + 0 +#define USB_RXINTERVAL2_NAKLMT_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXMAXP3 register. +// +//***************************************************************************** +#define USB_TXMAXP3_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP3_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRL3 register. +// +//***************************************************************************** +#define USB_TXCSRL3_NAKTO 0x00000080 // NAK Timeout +#define USB_TXCSRL3_CLRDT 0x00000040 // Clear Data Toggle +#define USB_TXCSRL3_STALLED 0x00000020 // Endpoint Stalled +#define USB_TXCSRL3_SETUP 0x00000010 // Setup Packet +#define USB_TXCSRL3_STALL 0x00000010 // Send STALL +#define USB_TXCSRL3_FLUSH 0x00000008 // Flush FIFO +#define USB_TXCSRL3_ERROR 0x00000004 // Error +#define USB_TXCSRL3_UNDRN 0x00000004 // Underrun +#define USB_TXCSRL3_FIFONE 0x00000002 // FIFO Not Empty +#define USB_TXCSRL3_TXRDY 0x00000001 // Transmit Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRH3 register. +// +//***************************************************************************** +#define USB_TXCSRH3_AUTOSET 0x00000080 // Auto Set +#define USB_TXCSRH3_ISO 0x00000040 // Isochronous Transfers +#define USB_TXCSRH3_MODE 0x00000020 // Mode +#define USB_TXCSRH3_DMAEN 0x00000010 // DMA Request Enable +#define USB_TXCSRH3_FDT 0x00000008 // Force Data Toggle +#define USB_TXCSRH3_DMAMOD 0x00000004 // DMA Request Mode +#define USB_TXCSRH3_DTWE 0x00000002 // Data Toggle Write Enable +#define USB_TXCSRH3_DT 0x00000001 // Data Toggle + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXMAXP3 register. +// +//***************************************************************************** +#define USB_RXMAXP3_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP3_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRL3 register. +// +//***************************************************************************** +#define USB_RXCSRL3_CLRDT 0x00000080 // Clear Data Toggle +#define USB_RXCSRL3_STALLED 0x00000040 // Endpoint Stalled +#define USB_RXCSRL3_STALL 0x00000020 // Send STALL +#define USB_RXCSRL3_REQPKT 0x00000020 // Request Packet +#define USB_RXCSRL3_FLUSH 0x00000010 // Flush FIFO +#define USB_RXCSRL3_DATAERR 0x00000008 // Data Error +#define USB_RXCSRL3_NAKTO 0x00000008 // NAK Timeout +#define USB_RXCSRL3_ERROR 0x00000004 // Error +#define USB_RXCSRL3_OVER 0x00000004 // Overrun +#define USB_RXCSRL3_FULL 0x00000002 // FIFO Full +#define USB_RXCSRL3_RXRDY 0x00000001 // Receive Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRH3 register. +// +//***************************************************************************** +#define USB_RXCSRH3_AUTOCL 0x00000080 // Auto Clear +#define USB_RXCSRH3_AUTORQ 0x00000040 // Auto Request +#define USB_RXCSRH3_ISO 0x00000040 // Isochronous Transfers +#define USB_RXCSRH3_DMAEN 0x00000020 // DMA Request Enable +#define USB_RXCSRH3_DISNYET 0x00000010 // Disable NYET +#define USB_RXCSRH3_PIDERR 0x00000010 // PID Error +#define USB_RXCSRH3_DMAMOD 0x00000008 // DMA Request Mode +#define USB_RXCSRH3_DTWE 0x00000004 // Data Toggle Write Enable +#define USB_RXCSRH3_DT 0x00000002 // Data Toggle +#define USB_RXCSRH3_INCOMPRX 0x00000001 // Incomplete RX Transmission + // Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCOUNT3 register. +// +//***************************************************************************** +#define USB_RXCOUNT3_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT3_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXTYPE3 register. +// +//***************************************************************************** +#define USB_TXTYPE3_SPEED_M 0x000000C0 // Operating Speed +#define USB_TXTYPE3_SPEED_DFLT 0x00000000 // Default +#define USB_TXTYPE3_SPEED_HIGH 0x00000040 // High +#define USB_TXTYPE3_SPEED_FULL 0x00000080 // Full +#define USB_TXTYPE3_SPEED_LOW 0x000000C0 // Low +#define USB_TXTYPE3_PROTO_M 0x00000030 // Protocol +#define USB_TXTYPE3_PROTO_CTRL 0x00000000 // Control +#define USB_TXTYPE3_PROTO_ISOC 0x00000010 // Isochronous +#define USB_TXTYPE3_PROTO_BULK 0x00000020 // Bulk +#define USB_TXTYPE3_PROTO_INT 0x00000030 // Interrupt +#define USB_TXTYPE3_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE3_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXINTERVAL3 +// register. +// +//***************************************************************************** +#define USB_TXINTERVAL3_TXPOLL_M \ + 0x000000FF // TX Polling +#define USB_TXINTERVAL3_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_TXINTERVAL3_TXPOLL_S \ + 0 +#define USB_TXINTERVAL3_NAKLMT_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXTYPE3 register. +// +//***************************************************************************** +#define USB_RXTYPE3_SPEED_M 0x000000C0 // Operating Speed +#define USB_RXTYPE3_SPEED_DFLT 0x00000000 // Default +#define USB_RXTYPE3_SPEED_HIGH 0x00000040 // High +#define USB_RXTYPE3_SPEED_FULL 0x00000080 // Full +#define USB_RXTYPE3_SPEED_LOW 0x000000C0 // Low +#define USB_RXTYPE3_PROTO_M 0x00000030 // Protocol +#define USB_RXTYPE3_PROTO_CTRL 0x00000000 // Control +#define USB_RXTYPE3_PROTO_ISOC 0x00000010 // Isochronous +#define USB_RXTYPE3_PROTO_BULK 0x00000020 // Bulk +#define USB_RXTYPE3_PROTO_INT 0x00000030 // Interrupt +#define USB_RXTYPE3_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE3_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXINTERVAL3 +// register. +// +//***************************************************************************** +#define USB_RXINTERVAL3_TXPOLL_M \ + 0x000000FF // RX Polling +#define USB_RXINTERVAL3_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_RXINTERVAL3_TXPOLL_S \ + 0 +#define USB_RXINTERVAL3_NAKLMT_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXMAXP4 register. +// +//***************************************************************************** +#define USB_TXMAXP4_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP4_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRL4 register. +// +//***************************************************************************** +#define USB_TXCSRL4_NAKTO 0x00000080 // NAK Timeout +#define USB_TXCSRL4_CLRDT 0x00000040 // Clear Data Toggle +#define USB_TXCSRL4_STALLED 0x00000020 // Endpoint Stalled +#define USB_TXCSRL4_SETUP 0x00000010 // Setup Packet +#define USB_TXCSRL4_STALL 0x00000010 // Send STALL +#define USB_TXCSRL4_FLUSH 0x00000008 // Flush FIFO +#define USB_TXCSRL4_ERROR 0x00000004 // Error +#define USB_TXCSRL4_UNDRN 0x00000004 // Underrun +#define USB_TXCSRL4_FIFONE 0x00000002 // FIFO Not Empty +#define USB_TXCSRL4_TXRDY 0x00000001 // Transmit Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRH4 register. +// +//***************************************************************************** +#define USB_TXCSRH4_AUTOSET 0x00000080 // Auto Set +#define USB_TXCSRH4_ISO 0x00000040 // Isochronous Transfers +#define USB_TXCSRH4_MODE 0x00000020 // Mode +#define USB_TXCSRH4_DMAEN 0x00000010 // DMA Request Enable +#define USB_TXCSRH4_FDT 0x00000008 // Force Data Toggle +#define USB_TXCSRH4_DMAMOD 0x00000004 // DMA Request Mode +#define USB_TXCSRH4_DTWE 0x00000002 // Data Toggle Write Enable +#define USB_TXCSRH4_DT 0x00000001 // Data Toggle + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXMAXP4 register. +// +//***************************************************************************** +#define USB_RXMAXP4_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP4_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRL4 register. +// +//***************************************************************************** +#define USB_RXCSRL4_CLRDT 0x00000080 // Clear Data Toggle +#define USB_RXCSRL4_STALLED 0x00000040 // Endpoint Stalled +#define USB_RXCSRL4_STALL 0x00000020 // Send STALL +#define USB_RXCSRL4_REQPKT 0x00000020 // Request Packet +#define USB_RXCSRL4_FLUSH 0x00000010 // Flush FIFO +#define USB_RXCSRL4_NAKTO 0x00000008 // NAK Timeout +#define USB_RXCSRL4_DATAERR 0x00000008 // Data Error +#define USB_RXCSRL4_OVER 0x00000004 // Overrun +#define USB_RXCSRL4_ERROR 0x00000004 // Error +#define USB_RXCSRL4_FULL 0x00000002 // FIFO Full +#define USB_RXCSRL4_RXRDY 0x00000001 // Receive Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRH4 register. +// +//***************************************************************************** +#define USB_RXCSRH4_AUTOCL 0x00000080 // Auto Clear +#define USB_RXCSRH4_AUTORQ 0x00000040 // Auto Request +#define USB_RXCSRH4_ISO 0x00000040 // Isochronous Transfers +#define USB_RXCSRH4_DMAEN 0x00000020 // DMA Request Enable +#define USB_RXCSRH4_DISNYET 0x00000010 // Disable NYET +#define USB_RXCSRH4_PIDERR 0x00000010 // PID Error +#define USB_RXCSRH4_DMAMOD 0x00000008 // DMA Request Mode +#define USB_RXCSRH4_DTWE 0x00000004 // Data Toggle Write Enable +#define USB_RXCSRH4_DT 0x00000002 // Data Toggle +#define USB_RXCSRH4_INCOMPRX 0x00000001 // Incomplete RX Transmission + // Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCOUNT4 register. +// +//***************************************************************************** +#define USB_RXCOUNT4_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT4_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXTYPE4 register. +// +//***************************************************************************** +#define USB_TXTYPE4_SPEED_M 0x000000C0 // Operating Speed +#define USB_TXTYPE4_SPEED_DFLT 0x00000000 // Default +#define USB_TXTYPE4_SPEED_HIGH 0x00000040 // High +#define USB_TXTYPE4_SPEED_FULL 0x00000080 // Full +#define USB_TXTYPE4_SPEED_LOW 0x000000C0 // Low +#define USB_TXTYPE4_PROTO_M 0x00000030 // Protocol +#define USB_TXTYPE4_PROTO_CTRL 0x00000000 // Control +#define USB_TXTYPE4_PROTO_ISOC 0x00000010 // Isochronous +#define USB_TXTYPE4_PROTO_BULK 0x00000020 // Bulk +#define USB_TXTYPE4_PROTO_INT 0x00000030 // Interrupt +#define USB_TXTYPE4_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE4_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXINTERVAL4 +// register. +// +//***************************************************************************** +#define USB_TXINTERVAL4_TXPOLL_M \ + 0x000000FF // TX Polling +#define USB_TXINTERVAL4_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_TXINTERVAL4_NAKLMT_S \ + 0 +#define USB_TXINTERVAL4_TXPOLL_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXTYPE4 register. +// +//***************************************************************************** +#define USB_RXTYPE4_SPEED_M 0x000000C0 // Operating Speed +#define USB_RXTYPE4_SPEED_DFLT 0x00000000 // Default +#define USB_RXTYPE4_SPEED_HIGH 0x00000040 // High +#define USB_RXTYPE4_SPEED_FULL 0x00000080 // Full +#define USB_RXTYPE4_SPEED_LOW 0x000000C0 // Low +#define USB_RXTYPE4_PROTO_M 0x00000030 // Protocol +#define USB_RXTYPE4_PROTO_CTRL 0x00000000 // Control +#define USB_RXTYPE4_PROTO_ISOC 0x00000010 // Isochronous +#define USB_RXTYPE4_PROTO_BULK 0x00000020 // Bulk +#define USB_RXTYPE4_PROTO_INT 0x00000030 // Interrupt +#define USB_RXTYPE4_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE4_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXINTERVAL4 +// register. +// +//***************************************************************************** +#define USB_RXINTERVAL4_TXPOLL_M \ + 0x000000FF // RX Polling +#define USB_RXINTERVAL4_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_RXINTERVAL4_NAKLMT_S \ + 0 +#define USB_RXINTERVAL4_TXPOLL_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXMAXP5 register. +// +//***************************************************************************** +#define USB_TXMAXP5_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP5_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRL5 register. +// +//***************************************************************************** +#define USB_TXCSRL5_NAKTO 0x00000080 // NAK Timeout +#define USB_TXCSRL5_CLRDT 0x00000040 // Clear Data Toggle +#define USB_TXCSRL5_STALLED 0x00000020 // Endpoint Stalled +#define USB_TXCSRL5_SETUP 0x00000010 // Setup Packet +#define USB_TXCSRL5_STALL 0x00000010 // Send STALL +#define USB_TXCSRL5_FLUSH 0x00000008 // Flush FIFO +#define USB_TXCSRL5_ERROR 0x00000004 // Error +#define USB_TXCSRL5_UNDRN 0x00000004 // Underrun +#define USB_TXCSRL5_FIFONE 0x00000002 // FIFO Not Empty +#define USB_TXCSRL5_TXRDY 0x00000001 // Transmit Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRH5 register. +// +//***************************************************************************** +#define USB_TXCSRH5_AUTOSET 0x00000080 // Auto Set +#define USB_TXCSRH5_ISO 0x00000040 // Isochronous Transfers +#define USB_TXCSRH5_MODE 0x00000020 // Mode +#define USB_TXCSRH5_DMAEN 0x00000010 // DMA Request Enable +#define USB_TXCSRH5_FDT 0x00000008 // Force Data Toggle +#define USB_TXCSRH5_DMAMOD 0x00000004 // DMA Request Mode +#define USB_TXCSRH5_DTWE 0x00000002 // Data Toggle Write Enable +#define USB_TXCSRH5_DT 0x00000001 // Data Toggle + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXMAXP5 register. +// +//***************************************************************************** +#define USB_RXMAXP5_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP5_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRL5 register. +// +//***************************************************************************** +#define USB_RXCSRL5_CLRDT 0x00000080 // Clear Data Toggle +#define USB_RXCSRL5_STALLED 0x00000040 // Endpoint Stalled +#define USB_RXCSRL5_STALL 0x00000020 // Send STALL +#define USB_RXCSRL5_REQPKT 0x00000020 // Request Packet +#define USB_RXCSRL5_FLUSH 0x00000010 // Flush FIFO +#define USB_RXCSRL5_NAKTO 0x00000008 // NAK Timeout +#define USB_RXCSRL5_DATAERR 0x00000008 // Data Error +#define USB_RXCSRL5_ERROR 0x00000004 // Error +#define USB_RXCSRL5_OVER 0x00000004 // Overrun +#define USB_RXCSRL5_FULL 0x00000002 // FIFO Full +#define USB_RXCSRL5_RXRDY 0x00000001 // Receive Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRH5 register. +// +//***************************************************************************** +#define USB_RXCSRH5_AUTOCL 0x00000080 // Auto Clear +#define USB_RXCSRH5_AUTORQ 0x00000040 // Auto Request +#define USB_RXCSRH5_ISO 0x00000040 // Isochronous Transfers +#define USB_RXCSRH5_DMAEN 0x00000020 // DMA Request Enable +#define USB_RXCSRH5_DISNYET 0x00000010 // Disable NYET +#define USB_RXCSRH5_PIDERR 0x00000010 // PID Error +#define USB_RXCSRH5_DMAMOD 0x00000008 // DMA Request Mode +#define USB_RXCSRH5_DTWE 0x00000004 // Data Toggle Write Enable +#define USB_RXCSRH5_DT 0x00000002 // Data Toggle +#define USB_RXCSRH5_INCOMPRX 0x00000001 // Incomplete RX Transmission + // Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCOUNT5 register. +// +//***************************************************************************** +#define USB_RXCOUNT5_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT5_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXTYPE5 register. +// +//***************************************************************************** +#define USB_TXTYPE5_SPEED_M 0x000000C0 // Operating Speed +#define USB_TXTYPE5_SPEED_DFLT 0x00000000 // Default +#define USB_TXTYPE5_SPEED_HIGH 0x00000040 // High +#define USB_TXTYPE5_SPEED_FULL 0x00000080 // Full +#define USB_TXTYPE5_SPEED_LOW 0x000000C0 // Low +#define USB_TXTYPE5_PROTO_M 0x00000030 // Protocol +#define USB_TXTYPE5_PROTO_CTRL 0x00000000 // Control +#define USB_TXTYPE5_PROTO_ISOC 0x00000010 // Isochronous +#define USB_TXTYPE5_PROTO_BULK 0x00000020 // Bulk +#define USB_TXTYPE5_PROTO_INT 0x00000030 // Interrupt +#define USB_TXTYPE5_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE5_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXINTERVAL5 +// register. +// +//***************************************************************************** +#define USB_TXINTERVAL5_TXPOLL_M \ + 0x000000FF // TX Polling +#define USB_TXINTERVAL5_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_TXINTERVAL5_NAKLMT_S \ + 0 +#define USB_TXINTERVAL5_TXPOLL_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXTYPE5 register. +// +//***************************************************************************** +#define USB_RXTYPE5_SPEED_M 0x000000C0 // Operating Speed +#define USB_RXTYPE5_SPEED_DFLT 0x00000000 // Default +#define USB_RXTYPE5_SPEED_HIGH 0x00000040 // High +#define USB_RXTYPE5_SPEED_FULL 0x00000080 // Full +#define USB_RXTYPE5_SPEED_LOW 0x000000C0 // Low +#define USB_RXTYPE5_PROTO_M 0x00000030 // Protocol +#define USB_RXTYPE5_PROTO_CTRL 0x00000000 // Control +#define USB_RXTYPE5_PROTO_ISOC 0x00000010 // Isochronous +#define USB_RXTYPE5_PROTO_BULK 0x00000020 // Bulk +#define USB_RXTYPE5_PROTO_INT 0x00000030 // Interrupt +#define USB_RXTYPE5_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE5_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXINTERVAL5 +// register. +// +//***************************************************************************** +#define USB_RXINTERVAL5_TXPOLL_M \ + 0x000000FF // RX Polling +#define USB_RXINTERVAL5_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_RXINTERVAL5_TXPOLL_S \ + 0 +#define USB_RXINTERVAL5_NAKLMT_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXMAXP6 register. +// +//***************************************************************************** +#define USB_TXMAXP6_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP6_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRL6 register. +// +//***************************************************************************** +#define USB_TXCSRL6_NAKTO 0x00000080 // NAK Timeout +#define USB_TXCSRL6_CLRDT 0x00000040 // Clear Data Toggle +#define USB_TXCSRL6_STALLED 0x00000020 // Endpoint Stalled +#define USB_TXCSRL6_STALL 0x00000010 // Send STALL +#define USB_TXCSRL6_SETUP 0x00000010 // Setup Packet +#define USB_TXCSRL6_FLUSH 0x00000008 // Flush FIFO +#define USB_TXCSRL6_ERROR 0x00000004 // Error +#define USB_TXCSRL6_UNDRN 0x00000004 // Underrun +#define USB_TXCSRL6_FIFONE 0x00000002 // FIFO Not Empty +#define USB_TXCSRL6_TXRDY 0x00000001 // Transmit Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRH6 register. +// +//***************************************************************************** +#define USB_TXCSRH6_AUTOSET 0x00000080 // Auto Set +#define USB_TXCSRH6_ISO 0x00000040 // Isochronous Transfers +#define USB_TXCSRH6_MODE 0x00000020 // Mode +#define USB_TXCSRH6_DMAEN 0x00000010 // DMA Request Enable +#define USB_TXCSRH6_FDT 0x00000008 // Force Data Toggle +#define USB_TXCSRH6_DMAMOD 0x00000004 // DMA Request Mode +#define USB_TXCSRH6_DTWE 0x00000002 // Data Toggle Write Enable +#define USB_TXCSRH6_DT 0x00000001 // Data Toggle + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXMAXP6 register. +// +//***************************************************************************** +#define USB_RXMAXP6_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP6_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRL6 register. +// +//***************************************************************************** +#define USB_RXCSRL6_CLRDT 0x00000080 // Clear Data Toggle +#define USB_RXCSRL6_STALLED 0x00000040 // Endpoint Stalled +#define USB_RXCSRL6_REQPKT 0x00000020 // Request Packet +#define USB_RXCSRL6_STALL 0x00000020 // Send STALL +#define USB_RXCSRL6_FLUSH 0x00000010 // Flush FIFO +#define USB_RXCSRL6_NAKTO 0x00000008 // NAK Timeout +#define USB_RXCSRL6_DATAERR 0x00000008 // Data Error +#define USB_RXCSRL6_ERROR 0x00000004 // Error +#define USB_RXCSRL6_OVER 0x00000004 // Overrun +#define USB_RXCSRL6_FULL 0x00000002 // FIFO Full +#define USB_RXCSRL6_RXRDY 0x00000001 // Receive Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRH6 register. +// +//***************************************************************************** +#define USB_RXCSRH6_AUTOCL 0x00000080 // Auto Clear +#define USB_RXCSRH6_AUTORQ 0x00000040 // Auto Request +#define USB_RXCSRH6_ISO 0x00000040 // Isochronous Transfers +#define USB_RXCSRH6_DMAEN 0x00000020 // DMA Request Enable +#define USB_RXCSRH6_DISNYET 0x00000010 // Disable NYET +#define USB_RXCSRH6_PIDERR 0x00000010 // PID Error +#define USB_RXCSRH6_DMAMOD 0x00000008 // DMA Request Mode +#define USB_RXCSRH6_DTWE 0x00000004 // Data Toggle Write Enable +#define USB_RXCSRH6_DT 0x00000002 // Data Toggle +#define USB_RXCSRH6_INCOMPRX 0x00000001 // Incomplete RX Transmission + // Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCOUNT6 register. +// +//***************************************************************************** +#define USB_RXCOUNT6_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT6_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXTYPE6 register. +// +//***************************************************************************** +#define USB_TXTYPE6_SPEED_M 0x000000C0 // Operating Speed +#define USB_TXTYPE6_SPEED_DFLT 0x00000000 // Default +#define USB_TXTYPE6_SPEED_HIGH 0x00000040 // High +#define USB_TXTYPE6_SPEED_FULL 0x00000080 // Full +#define USB_TXTYPE6_SPEED_LOW 0x000000C0 // Low +#define USB_TXTYPE6_PROTO_M 0x00000030 // Protocol +#define USB_TXTYPE6_PROTO_CTRL 0x00000000 // Control +#define USB_TXTYPE6_PROTO_ISOC 0x00000010 // Isochronous +#define USB_TXTYPE6_PROTO_BULK 0x00000020 // Bulk +#define USB_TXTYPE6_PROTO_INT 0x00000030 // Interrupt +#define USB_TXTYPE6_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE6_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXINTERVAL6 +// register. +// +//***************************************************************************** +#define USB_TXINTERVAL6_TXPOLL_M \ + 0x000000FF // TX Polling +#define USB_TXINTERVAL6_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_TXINTERVAL6_TXPOLL_S \ + 0 +#define USB_TXINTERVAL6_NAKLMT_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXTYPE6 register. +// +//***************************************************************************** +#define USB_RXTYPE6_SPEED_M 0x000000C0 // Operating Speed +#define USB_RXTYPE6_SPEED_DFLT 0x00000000 // Default +#define USB_RXTYPE6_SPEED_HIGH 0x00000040 // High +#define USB_RXTYPE6_SPEED_FULL 0x00000080 // Full +#define USB_RXTYPE6_SPEED_LOW 0x000000C0 // Low +#define USB_RXTYPE6_PROTO_M 0x00000030 // Protocol +#define USB_RXTYPE6_PROTO_CTRL 0x00000000 // Control +#define USB_RXTYPE6_PROTO_ISOC 0x00000010 // Isochronous +#define USB_RXTYPE6_PROTO_BULK 0x00000020 // Bulk +#define USB_RXTYPE6_PROTO_INT 0x00000030 // Interrupt +#define USB_RXTYPE6_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE6_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXINTERVAL6 +// register. +// +//***************************************************************************** +#define USB_RXINTERVAL6_TXPOLL_M \ + 0x000000FF // RX Polling +#define USB_RXINTERVAL6_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_RXINTERVAL6_NAKLMT_S \ + 0 +#define USB_RXINTERVAL6_TXPOLL_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXMAXP7 register. +// +//***************************************************************************** +#define USB_TXMAXP7_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP7_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRL7 register. +// +//***************************************************************************** +#define USB_TXCSRL7_NAKTO 0x00000080 // NAK Timeout +#define USB_TXCSRL7_CLRDT 0x00000040 // Clear Data Toggle +#define USB_TXCSRL7_STALLED 0x00000020 // Endpoint Stalled +#define USB_TXCSRL7_STALL 0x00000010 // Send STALL +#define USB_TXCSRL7_SETUP 0x00000010 // Setup Packet +#define USB_TXCSRL7_FLUSH 0x00000008 // Flush FIFO +#define USB_TXCSRL7_ERROR 0x00000004 // Error +#define USB_TXCSRL7_UNDRN 0x00000004 // Underrun +#define USB_TXCSRL7_FIFONE 0x00000002 // FIFO Not Empty +#define USB_TXCSRL7_TXRDY 0x00000001 // Transmit Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXCSRH7 register. +// +//***************************************************************************** +#define USB_TXCSRH7_AUTOSET 0x00000080 // Auto Set +#define USB_TXCSRH7_ISO 0x00000040 // Isochronous Transfers +#define USB_TXCSRH7_MODE 0x00000020 // Mode +#define USB_TXCSRH7_DMAEN 0x00000010 // DMA Request Enable +#define USB_TXCSRH7_FDT 0x00000008 // Force Data Toggle +#define USB_TXCSRH7_DMAMOD 0x00000004 // DMA Request Mode +#define USB_TXCSRH7_DTWE 0x00000002 // Data Toggle Write Enable +#define USB_TXCSRH7_DT 0x00000001 // Data Toggle + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXMAXP7 register. +// +//***************************************************************************** +#define USB_RXMAXP7_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP7_MAXLOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRL7 register. +// +//***************************************************************************** +#define USB_RXCSRL7_CLRDT 0x00000080 // Clear Data Toggle +#define USB_RXCSRL7_STALLED 0x00000040 // Endpoint Stalled +#define USB_RXCSRL7_REQPKT 0x00000020 // Request Packet +#define USB_RXCSRL7_STALL 0x00000020 // Send STALL +#define USB_RXCSRL7_FLUSH 0x00000010 // Flush FIFO +#define USB_RXCSRL7_DATAERR 0x00000008 // Data Error +#define USB_RXCSRL7_NAKTO 0x00000008 // NAK Timeout +#define USB_RXCSRL7_ERROR 0x00000004 // Error +#define USB_RXCSRL7_OVER 0x00000004 // Overrun +#define USB_RXCSRL7_FULL 0x00000002 // FIFO Full +#define USB_RXCSRL7_RXRDY 0x00000001 // Receive Packet Ready + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCSRH7 register. +// +//***************************************************************************** +#define USB_RXCSRH7_AUTOCL 0x00000080 // Auto Clear +#define USB_RXCSRH7_ISO 0x00000040 // Isochronous Transfers +#define USB_RXCSRH7_AUTORQ 0x00000040 // Auto Request +#define USB_RXCSRH7_DMAEN 0x00000020 // DMA Request Enable +#define USB_RXCSRH7_PIDERR 0x00000010 // PID Error +#define USB_RXCSRH7_DISNYET 0x00000010 // Disable NYET +#define USB_RXCSRH7_DMAMOD 0x00000008 // DMA Request Mode +#define USB_RXCSRH7_DTWE 0x00000004 // Data Toggle Write Enable +#define USB_RXCSRH7_DT 0x00000002 // Data Toggle +#define USB_RXCSRH7_INCOMPRX 0x00000001 // Incomplete RX Transmission + // Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXCOUNT7 register. +// +//***************************************************************************** +#define USB_RXCOUNT7_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT7_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXTYPE7 register. +// +//***************************************************************************** +#define USB_TXTYPE7_SPEED_M 0x000000C0 // Operating Speed +#define USB_TXTYPE7_SPEED_DFLT 0x00000000 // Default +#define USB_TXTYPE7_SPEED_HIGH 0x00000040 // High +#define USB_TXTYPE7_SPEED_FULL 0x00000080 // Full +#define USB_TXTYPE7_SPEED_LOW 0x000000C0 // Low +#define USB_TXTYPE7_PROTO_M 0x00000030 // Protocol +#define USB_TXTYPE7_PROTO_CTRL 0x00000000 // Control +#define USB_TXTYPE7_PROTO_ISOC 0x00000010 // Isochronous +#define USB_TXTYPE7_PROTO_BULK 0x00000020 // Bulk +#define USB_TXTYPE7_PROTO_INT 0x00000030 // Interrupt +#define USB_TXTYPE7_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE7_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXINTERVAL7 +// register. +// +//***************************************************************************** +#define USB_TXINTERVAL7_TXPOLL_M \ + 0x000000FF // TX Polling +#define USB_TXINTERVAL7_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_TXINTERVAL7_NAKLMT_S \ + 0 +#define USB_TXINTERVAL7_TXPOLL_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXTYPE7 register. +// +//***************************************************************************** +#define USB_RXTYPE7_SPEED_M 0x000000C0 // Operating Speed +#define USB_RXTYPE7_SPEED_DFLT 0x00000000 // Default +#define USB_RXTYPE7_SPEED_HIGH 0x00000040 // High +#define USB_RXTYPE7_SPEED_FULL 0x00000080 // Full +#define USB_RXTYPE7_SPEED_LOW 0x000000C0 // Low +#define USB_RXTYPE7_PROTO_M 0x00000030 // Protocol +#define USB_RXTYPE7_PROTO_CTRL 0x00000000 // Control +#define USB_RXTYPE7_PROTO_ISOC 0x00000010 // Isochronous +#define USB_RXTYPE7_PROTO_BULK 0x00000020 // Bulk +#define USB_RXTYPE7_PROTO_INT 0x00000030 // Interrupt +#define USB_RXTYPE7_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE7_TEP_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXINTERVAL7 +// register. +// +//***************************************************************************** +#define USB_RXINTERVAL7_TXPOLL_M \ + 0x000000FF // RX Polling +#define USB_RXINTERVAL7_NAKLMT_M \ + 0x000000FF // NAK Limit +#define USB_RXINTERVAL7_NAKLMT_S \ + 0 +#define USB_RXINTERVAL7_TXPOLL_S \ + 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAINTR register. +// +//***************************************************************************** +#define USB_DMAINTR_CH7 0x00000080 // Channel 7 DMA Interrupt +#define USB_DMAINTR_CH6 0x00000040 // Channel 6 DMA Interrupt +#define USB_DMAINTR_CH5 0x00000020 // Channel 5 DMA Interrupt +#define USB_DMAINTR_CH4 0x00000010 // Channel 4 DMA Interrupt +#define USB_DMAINTR_CH3 0x00000008 // Channel 3 DMA Interrupt +#define USB_DMAINTR_CH2 0x00000004 // Channel 2 DMA Interrupt +#define USB_DMAINTR_CH1 0x00000002 // Channel 1 DMA Interrupt +#define USB_DMAINTR_CH0 0x00000001 // Channel 0 DMA Interrupt + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACTL0 register. +// +//***************************************************************************** +#define USB_DMACTL0_BRSTM_M 0x00000600 // Burst Mode +#define USB_DMACTL0_BRSTM_ANY 0x00000000 // Bursts of unspecified length +#define USB_DMACTL0_BRSTM_INC4 0x00000200 // INCR4 or unspecified length +#define USB_DMACTL0_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL0_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL0_ERR 0x00000100 // Bus Error Bit +#define USB_DMACTL0_EP_M 0x000000F0 // Endpoint number +#define USB_DMACTL0_IE 0x00000008 // DMA Interrupt Enable +#define USB_DMACTL0_MODE 0x00000004 // DMA Transfer Mode +#define USB_DMACTL0_DIR 0x00000002 // DMA Direction +#define USB_DMACTL0_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL0_EP_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAADDR0 register. +// +//***************************************************************************** +#define USB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR0_ADDR_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACOUNT0 +// register. +// +//***************************************************************************** +#define USB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT0_COUNT_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACTL1 register. +// +//***************************************************************************** +#define USB_DMACTL1_BRSTM_M 0x00000600 // Burst Mode +#define USB_DMACTL1_BRSTM_ANY 0x00000000 // Bursts of unspecified length +#define USB_DMACTL1_BRSTM_INC4 0x00000200 // INCR4 or unspecified length +#define USB_DMACTL1_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL1_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL1_ERR 0x00000100 // Bus Error Bit +#define USB_DMACTL1_EP_M 0x000000F0 // Endpoint number +#define USB_DMACTL1_IE 0x00000008 // DMA Interrupt Enable +#define USB_DMACTL1_MODE 0x00000004 // DMA Transfer Mode +#define USB_DMACTL1_DIR 0x00000002 // DMA Direction +#define USB_DMACTL1_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL1_EP_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAADDR1 register. +// +//***************************************************************************** +#define USB_DMAADDR1_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR1_ADDR_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACOUNT1 +// register. +// +//***************************************************************************** +#define USB_DMACOUNT1_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT1_COUNT_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACTL2 register. +// +//***************************************************************************** +#define USB_DMACTL2_BRSTM_M 0x00000600 // Burst Mode +#define USB_DMACTL2_BRSTM_ANY 0x00000000 // Bursts of unspecified length +#define USB_DMACTL2_BRSTM_INC4 0x00000200 // INCR4 or unspecified length +#define USB_DMACTL2_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL2_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL2_ERR 0x00000100 // Bus Error Bit +#define USB_DMACTL2_EP_M 0x000000F0 // Endpoint number +#define USB_DMACTL2_IE 0x00000008 // DMA Interrupt Enable +#define USB_DMACTL2_MODE 0x00000004 // DMA Transfer Mode +#define USB_DMACTL2_DIR 0x00000002 // DMA Direction +#define USB_DMACTL2_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL2_EP_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAADDR2 register. +// +//***************************************************************************** +#define USB_DMAADDR2_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR2_ADDR_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACOUNT2 +// register. +// +//***************************************************************************** +#define USB_DMACOUNT2_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT2_COUNT_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACTL3 register. +// +//***************************************************************************** +#define USB_DMACTL3_BRSTM_M 0x00000600 // Burst Mode +#define USB_DMACTL3_BRSTM_ANY 0x00000000 // Bursts of unspecified length +#define USB_DMACTL3_BRSTM_INC4 0x00000200 // INCR4 or unspecified length +#define USB_DMACTL3_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL3_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL3_ERR 0x00000100 // Bus Error Bit +#define USB_DMACTL3_EP_M 0x000000F0 // Endpoint number +#define USB_DMACTL3_IE 0x00000008 // DMA Interrupt Enable +#define USB_DMACTL3_MODE 0x00000004 // DMA Transfer Mode +#define USB_DMACTL3_DIR 0x00000002 // DMA Direction +#define USB_DMACTL3_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL3_EP_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAADDR3 register. +// +//***************************************************************************** +#define USB_DMAADDR3_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR3_ADDR_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACOUNT3 +// register. +// +//***************************************************************************** +#define USB_DMACOUNT3_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT3_COUNT_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACTL4 register. +// +//***************************************************************************** +#define USB_DMACTL4_BRSTM_M 0x00000600 // Burst Mode +#define USB_DMACTL4_BRSTM_ANY 0x00000000 // Bursts of unspecified length +#define USB_DMACTL4_BRSTM_INC4 0x00000200 // INCR4 or unspecified length +#define USB_DMACTL4_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL4_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL4_ERR 0x00000100 // Bus Error Bit +#define USB_DMACTL4_EP_M 0x000000F0 // Endpoint number +#define USB_DMACTL4_IE 0x00000008 // DMA Interrupt Enable +#define USB_DMACTL4_MODE 0x00000004 // DMA Transfer Mode +#define USB_DMACTL4_DIR 0x00000002 // DMA Direction +#define USB_DMACTL4_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL4_EP_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAADDR4 register. +// +//***************************************************************************** +#define USB_DMAADDR4_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR4_ADDR_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACOUNT4 +// register. +// +//***************************************************************************** +#define USB_DMACOUNT4_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT4_COUNT_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACTL5 register. +// +//***************************************************************************** +#define USB_DMACTL5_BRSTM_M 0x00000600 // Burst Mode +#define USB_DMACTL5_BRSTM_ANY 0x00000000 // Bursts of unspecified length +#define USB_DMACTL5_BRSTM_INC4 0x00000200 // INCR4 or unspecified length +#define USB_DMACTL5_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL5_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL5_ERR 0x00000100 // Bus Error Bit +#define USB_DMACTL5_EP_M 0x000000F0 // Endpoint number +#define USB_DMACTL5_IE 0x00000008 // DMA Interrupt Enable +#define USB_DMACTL5_MODE 0x00000004 // DMA Transfer Mode +#define USB_DMACTL5_DIR 0x00000002 // DMA Direction +#define USB_DMACTL5_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL5_EP_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAADDR5 register. +// +//***************************************************************************** +#define USB_DMAADDR5_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR5_ADDR_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACOUNT5 +// register. +// +//***************************************************************************** +#define USB_DMACOUNT5_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT5_COUNT_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACTL6 register. +// +//***************************************************************************** +#define USB_DMACTL6_BRSTM_M 0x00000600 // Burst Mode +#define USB_DMACTL6_BRSTM_ANY 0x00000000 // Bursts of unspecified length +#define USB_DMACTL6_BRSTM_INC4 0x00000200 // INCR4 or unspecified length +#define USB_DMACTL6_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL6_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL6_ERR 0x00000100 // Bus Error Bit +#define USB_DMACTL6_EP_M 0x000000F0 // Endpoint number +#define USB_DMACTL6_IE 0x00000008 // DMA Interrupt Enable +#define USB_DMACTL6_MODE 0x00000004 // DMA Transfer Mode +#define USB_DMACTL6_DIR 0x00000002 // DMA Direction +#define USB_DMACTL6_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL6_EP_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAADDR6 register. +// +//***************************************************************************** +#define USB_DMAADDR6_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR6_ADDR_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACOUNT6 +// register. +// +//***************************************************************************** +#define USB_DMACOUNT6_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT6_COUNT_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACTL7 register. +// +//***************************************************************************** +#define USB_DMACTL7_BRSTM_M 0x00000600 // Burst Mode +#define USB_DMACTL7_BRSTM_ANY 0x00000000 // Bursts of unspecified length +#define USB_DMACTL7_BRSTM_INC4 0x00000200 // INCR4 or unspecified length +#define USB_DMACTL7_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL7_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL7_ERR 0x00000100 // Bus Error Bit +#define USB_DMACTL7_EP_M 0x000000F0 // Endpoint number +#define USB_DMACTL7_IE 0x00000008 // DMA Interrupt Enable +#define USB_DMACTL7_MODE 0x00000004 // DMA Transfer Mode +#define USB_DMACTL7_DIR 0x00000002 // DMA Direction +#define USB_DMACTL7_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL7_EP_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMAADDR7 register. +// +//***************************************************************************** +#define USB_DMAADDR7_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR7_ADDR_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DMACOUNT7 +// register. +// +//***************************************************************************** +#define USB_DMACOUNT7_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT7_COUNT_S 2 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RQPKTCOUNT1 +// register. +// +//***************************************************************************** +#define USB_RQPKTCOUNT1_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT1_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RQPKTCOUNT2 +// register. +// +//***************************************************************************** +#define USB_RQPKTCOUNT2_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT2_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RQPKTCOUNT3 +// register. +// +//***************************************************************************** +#define USB_RQPKTCOUNT3_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT3_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RQPKTCOUNT4 +// register. +// +//***************************************************************************** +#define USB_RQPKTCOUNT4_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT4_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RQPKTCOUNT5 +// register. +// +//***************************************************************************** +#define USB_RQPKTCOUNT5_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT5_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RQPKTCOUNT6 +// register. +// +//***************************************************************************** +#define USB_RQPKTCOUNT6_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT6_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RQPKTCOUNT7 +// register. +// +//***************************************************************************** +#define USB_RQPKTCOUNT7_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT7_COUNT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_RXDPKTBUFDIS +// register. +// +//***************************************************************************** +#define USB_RXDPKTBUFDIS_EP7 0x00000080 // EP7 RX Double-Packet Buffer + // Disable +#define USB_RXDPKTBUFDIS_EP6 0x00000040 // EP6 RX Double-Packet Buffer + // Disable +#define USB_RXDPKTBUFDIS_EP5 0x00000020 // EP5 RX Double-Packet Buffer + // Disable +#define USB_RXDPKTBUFDIS_EP4 0x00000010 // EP4 RX Double-Packet Buffer + // Disable +#define USB_RXDPKTBUFDIS_EP3 0x00000008 // EP3 RX Double-Packet Buffer + // Disable +#define USB_RXDPKTBUFDIS_EP2 0x00000004 // EP2 RX Double-Packet Buffer + // Disable +#define USB_RXDPKTBUFDIS_EP1 0x00000002 // EP1 RX Double-Packet Buffer + // Disable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_TXDPKTBUFDIS +// register. +// +//***************************************************************************** +#define USB_TXDPKTBUFDIS_EP7 0x00000080 // EP7 TX Double-Packet Buffer + // Disable +#define USB_TXDPKTBUFDIS_EP6 0x00000040 // EP6 TX Double-Packet Buffer + // Disable +#define USB_TXDPKTBUFDIS_EP5 0x00000020 // EP5 TX Double-Packet Buffer + // Disable +#define USB_TXDPKTBUFDIS_EP4 0x00000010 // EP4 TX Double-Packet Buffer + // Disable +#define USB_TXDPKTBUFDIS_EP3 0x00000008 // EP3 TX Double-Packet Buffer + // Disable +#define USB_TXDPKTBUFDIS_EP2 0x00000004 // EP2 TX Double-Packet Buffer + // Disable +#define USB_TXDPKTBUFDIS_EP1 0x00000002 // EP1 TX Double-Packet Buffer + // Disable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_CTO register. +// +//***************************************************************************** +#define USB_CTO_CCTV_M 0x0000FFFF // Configurable Chirp Timeout Value +#define USB_CTO_CCTV_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_HHSRTN register. +// +//***************************************************************************** +#define USB_HHSRTN_HHSRTN_M 0x0000FFFF // HIgh Speed to UTM Operating + // Delay +#define USB_HHSRTN_HHSRTN_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_HSBT register. +// +//***************************************************************************** +#define USB_HSBT_HSBT_M 0x0000000F // High Speed Timeout Adder +#define USB_HSBT_HSBT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_LPMATTR register. +// +//***************************************************************************** +#define USB_LPMATTR_ENDPT_M 0x0000F000 // Endpoint +#define USB_LPMATTR_RMTWAK 0x00000100 // Remote Wake +#define USB_LPMATTR_HIRD_M 0x000000F0 // Host Initiated Resume Duration +#define USB_LPMATTR_LS_M 0x0000000F // Link State +#define USB_LPMATTR_LS_L1 0x00000001 // Sleep State (L1) +#define USB_LPMATTR_ENDPT_S 12 +#define USB_LPMATTR_HIRD_S 4 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_LPMCNTRL register. +// +//***************************************************************************** +#define USB_LPMCNTRL_NAK 0x00000010 // LPM NAK +#define USB_LPMCNTRL_EN_M 0x0000000C // LPM Enable +#define USB_LPMCNTRL_EN_NONE 0x00000000 // LPM and Extended transactions + // are not supported. In this case, + // the USB does not respond to LPM + // transactions and LPM + // transactions cause a timeout +#define USB_LPMCNTRL_EN_EXT 0x00000004 // LPM is not supported but + // extended transactions are + // supported. In this case, the USB + // does respond to an LPM + // transaction with a STALL +#define USB_LPMCNTRL_EN_LPMEXT 0x0000000C // The USB supports LPM extended + // transactions. In this case, the + // USB responds with a NYET or an + // ACK as determined by the value + // of TXLPM and other conditions +#define USB_LPMCNTRL_RES 0x00000002 // LPM Resume +#define USB_LPMCNTRL_TXLPM 0x00000001 // Transmit LPM Transaction Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_LPMIM register. +// +//***************************************************************************** +#define USB_LPMIM_ERR 0x00000020 // LPM Error Interrupt Mask +#define USB_LPMIM_RES 0x00000010 // LPM Resume Interrupt Mask +#define USB_LPMIM_NC 0x00000008 // LPM NC Interrupt Mask +#define USB_LPMIM_ACK 0x00000004 // LPM ACK Interrupt Mask +#define USB_LPMIM_NY 0x00000002 // LPM NY Interrupt Mask +#define USB_LPMIM_STALL 0x00000001 // LPM STALL Interrupt Mask + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_LPMRIS register. +// +//***************************************************************************** +#define USB_LPMRIS_ERR 0x00000020 // LPM Interrupt Status +#define USB_LPMRIS_RES 0x00000010 // LPM Resume Interrupt Status +#define USB_LPMRIS_NC 0x00000008 // LPM NC Interrupt Status +#define USB_LPMRIS_ACK 0x00000004 // LPM ACK Interrupt Status +#define USB_LPMRIS_NY 0x00000002 // LPM NY Interrupt Status +#define USB_LPMRIS_LPMST 0x00000001 // LPM STALL Interrupt Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_LPMFADDR register. +// +//***************************************************************************** +#define USB_LPMFADDR_ADDR_M 0x0000007F // LPM Function Address +#define USB_LPMFADDR_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_EPC register. +// +//***************************************************************************** +#define USB_EPC_PFLTACT_M 0x00000300 // Power Fault Action +#define USB_EPC_PFLTACT_UNCHG 0x00000000 // Unchanged +#define USB_EPC_PFLTACT_TRIS 0x00000100 // Tristate +#define USB_EPC_PFLTACT_LOW 0x00000200 // Low +#define USB_EPC_PFLTACT_HIGH 0x00000300 // High +#define USB_EPC_PFLTAEN 0x00000040 // Power Fault Action Enable +#define USB_EPC_PFLTSEN_HIGH 0x00000020 // Power Fault Sense +#define USB_EPC_PFLTEN 0x00000010 // Power Fault Input Enable +#define USB_EPC_EPENDE 0x00000004 // EPEN Drive Enable +#define USB_EPC_EPEN_M 0x00000003 // External Power Supply Enable + // Configuration +#define USB_EPC_EPEN_LOW 0x00000000 // Power Enable Active Low +#define USB_EPC_EPEN_HIGH 0x00000001 // Power Enable Active High +#define USB_EPC_EPEN_VBLOW 0x00000002 // Power Enable High if VBUS Low + // (OTG only) +#define USB_EPC_EPEN_VBHIGH 0x00000003 // Power Enable High if VBUS High + // (OTG only) + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_EPCRIS register. +// +//***************************************************************************** +#define USB_EPCRIS_PF 0x00000001 // USB Power Fault Interrupt Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_EPCIM register. +// +//***************************************************************************** +#define USB_EPCIM_PF 0x00000001 // USB Power Fault Interrupt Mask + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_EPCISC register. +// +//***************************************************************************** +#define USB_EPCISC_PF 0x00000001 // USB Power Fault Interrupt Status + // and Clear + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DRRIS register. +// +//***************************************************************************** +#define USB_DRRIS_RESUME 0x00000001 // RESUME Interrupt Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DRIM register. +// +//***************************************************************************** +#define USB_DRIM_RESUME 0x00000001 // RESUME Interrupt Mask + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_DRISC register. +// +//***************************************************************************** +#define USB_DRISC_RESUME 0x00000001 // RESUME Interrupt Status and + // Clear + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_GPCS register. +// +//***************************************************************************** +#define USB_GPCS_DEVMOD_M 0x00000007 // Device Mode +#define USB_GPCS_DEVMOD_OTG 0x00000000 // Use USB0VBUS and USB0ID pin +#define USB_GPCS_DEVMOD_HOST 0x00000002 // Force USB0VBUS and USB0ID low +#define USB_GPCS_DEVMOD_DEV 0x00000003 // Force USB0VBUS and USB0ID high +#define USB_GPCS_DEVMOD_HOSTVBUS \ + 0x00000004 // Use USB0VBUS and force USB0ID + // low +#define USB_GPCS_DEVMOD_DEVVBUS 0x00000005 // Use USB0VBUS and force USB0ID + // high + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_VDC register. +// +//***************************************************************************** +#define USB_VDC_VBDEN 0x00000001 // VBUS Droop Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_VDCRIS register. +// +//***************************************************************************** +#define USB_VDCRIS_VD 0x00000001 // VBUS Droop Raw Interrupt Status + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_VDCIM register. +// +//***************************************************************************** +#define USB_VDCIM_VD 0x00000001 // VBUS Droop Interrupt Mask + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_VDCISC register. +// +//***************************************************************************** +#define USB_VDCISC_VD 0x00000001 // VBUS Droop Interrupt Status and + // Clear + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_PP register. +// +//***************************************************************************** +#define USB_PP_ECNT_M 0x0000FF00 // Endpoint Count +#define USB_PP_USB_M 0x000000C0 // USB Capability +#define USB_PP_USB_DEVICE 0x00000040 // DEVICE +#define USB_PP_USB_HOSTDEVICE 0x00000080 // HOST +#define USB_PP_USB_OTG 0x000000C0 // OTG +#define USB_PP_ULPI 0x00000020 // ULPI Present +#define USB_PP_PHY 0x00000010 // PHY Present +#define USB_PP_TYPE_M 0x0000000F // Controller Type +#define USB_PP_TYPE_0 0x00000000 // The first-generation USB + // controller +#define USB_PP_TYPE_1 0x00000001 // The second-generation USB + // controller revision +#define USB_PP_ECNT_S 8 + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_PC register. +// +//***************************************************************************** +#define USB_PC_ULPIEN 0x00010000 // ULPI Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_O_CC register. +// +//***************************************************************************** +#define USB_CC_CLKEN 0x00000200 // USB Clock Enable +#define USB_CC_CSD 0x00000100 // Clock Source/Direction +#define USB_CC_CLKDIV_M 0x0000000F // PLL Clock Divisor +#define USB_CC_CLKDIV_S 0 + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/microchip/pic32mz/dcd_pic32mz.c b/circuitpython/lib/tinyusb/src/portable/microchip/pic32mz/dcd_pic32mz.c new file mode 100644 index 0000000..7d48f75 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -0,0 +1,741 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_PIC32MZ + +#include +#include + +#include +#include "usbhs_registers.h" + +#define USB_REGS ((usbhs_registers_t *) (_USB_BASE_ADDRESS)) + +// Maximum number of endpoints, could be trimmed down in tusb_config to reduce RAM usage. +#ifndef EP_MAX +#define EP_MAX 8 +#endif + + +typedef enum { + EP0_STAGE_NONE, + EP0_STAGE_SETUP_IN_DATA, + EP0_STAGE_SETUP_OUT_NO_DATA, + EP0_STAGE_SETUP_OUT_DATA, + EP0_STAGE_DATA_IN, + EP0_STAGE_DATA_IN_LAST_PACKET_FILLED, + EP0_STAGE_DATA_IN_SENT, + EP0_STAGE_DATA_OUT, + EP0_STAGE_DATA_OUT_COMPLETE, + EP0_STAGE_STATUS_IN, + EP0_STAGE_ADDRESS_CHANGE, +} ep0_stage_t; + +typedef struct { + uint8_t * buffer; + // Total length of current transfer + uint16_t total_len; + // Bytes transferred so far + uint16_t transferred; + uint16_t max_packet_size; + uint16_t fifo_size; + // Packet size sent or received so far. It is used to modify transferred field + // after ACK is received or when filling ISO endpoint with size larger then + // FIFO size. + uint16_t last_packet_size; + uint8_t ep_addr; +} xfer_ctl_t; + +static struct +{ + // Current FIFO RAM address used for FIFO allocation + uint16_t fifo_addr_top; + // EP0 transfer stage + ep0_stage_t ep0_stage; + // Device address + uint8_t dev_addr; + xfer_ctl_t xfer_status[EP_MAX][2]; +} _dcd; + +// Two endpoint 0 descriptor definition for unified dcd_edpt_open() +static tusb_desc_endpoint_t const ep0OUT_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x00, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 +}; + +static tusb_desc_endpoint_t const ep0IN_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x80, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 +}; + +#define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir] + +static void ep0_set_stage(ep0_stage_t stage) +{ + _dcd.ep0_stage = stage; +} + +static ep0_stage_t ep0_get_stage(void) +{ + return _dcd.ep0_stage; +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + // Disable endpoint interrupts for now + USB_REGS->INTRRXEbits.w = 0; + USB_REGS->INTRTXEbits.w = 0; + // Enable Reset/Suspend/Resume interrupts only + USB_REGS->INTRUSBEbits.w = 7; + + dcd_connect(rhport); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + + USBCRCONbits.USBIE = 1; +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + + USBCRCONbits.USBIE = 0; +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + + ep0_set_stage(EP0_STAGE_ADDRESS_CHANGE); + // Store address it will be used later after status stage is done + _dcd.dev_addr = dev_addr; + // Confirm packet now, address will be set when status stage is detected + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + USB_REGS->POWERbits.RESUME = 1; +#if CFG_TUSB_OS != OPT_OS_NONE + osal_task_delay(10); +#else + // TODO: Wait in non blocking mode + unsigned cnt = 2000; + while (cnt--) __asm__("nop"); +#endif + USB_REGS->POWERbits.RESUME = 0; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + + USB_REGS->POWERbits.HSEN = TUD_OPT_HIGH_SPEED ? 1 : 0; + USB_REGS->POWERbits.SOFTCONN = 1; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + + USB_REGS->POWERbits.SOFTCONN = 1; +} + +TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) +{ + return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) != 0; +} + +static void epn_rx_configure(uint8_t endpoint, uint16_t endpointSize, + uint16_t fifoAddress, uint8_t fifoSize, + uint32_t transferType) +{ + uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; + + // Select endpoint register set (same register address is used for all endpoints. + USB_REGS->INDEXbits.ENDPOINT = endpoint; + + // Configure the Endpoint size + USB_REGS->INDEXED_EPCSR.RXMAXPbits.RXMAXP = endpointSize; + + // Set up the fifo address. + USB_REGS->RXFIFOADDbits.RXFIFOAD = fifoAddress; + + // Resets the endpoint data toggle to 0 + USB_REGS->INDEXED_EPCSR.RXCSRL_DEVICEbits.CLRDT = 1; + + // Set up the FIFO size + USB_REGS->RXFIFOSZbits.RXFIFOSZ = fifoSize; + + USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.ISO = transferType == 1 ? 1 : 0; + // Disable NYET Handshakes for interrupt endpoints + USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.DISNYET = transferType == 3 ? 1 : 0; + + // Restore the index register. + USB_REGS->INDEXbits.ENDPOINT = old_index; + + // Enable the endpoint interrupt. + USB_REGS->INTRRXEbits.w |= (1 << endpoint); +} + +static void epn_tx_configure(uint8_t endpoint, uint16_t endpointSize, + uint16_t fifoAddress, uint8_t fifoSize, + uint32_t transferType) +{ + uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; + + // Select endpoint register set (same register address is used for all endpoints. + USB_REGS->INDEXbits.ENDPOINT = endpoint; + + // Configure the Endpoint size + USB_REGS->INDEXED_EPCSR.TXMAXPbits.TXMAXP = endpointSize; + + // Set up the fifo address + USB_REGS->TXFIFOADDbits.TXFIFOAD = fifoAddress; + + // Resets the endpoint data toggle to 0 + USB_REGS->INDEXED_EPCSR.TXCSRL_DEVICEbits.CLRDT = 1; + + // Set up the FIFO size + USB_REGS->TXFIFOSZbits.TXFIFOSZ = fifoSize; + + USB_REGS->INDEXED_EPCSR.TXCSRH_DEVICEbits.ISO = 1 == transferType ? 1 : 0; + + // Restore the index register + USB_REGS->INDEXbits.ENDPOINT = old_index; + + // Enable the interrupt + USB_REGS->INTRTXEbits.w |= (1 << endpoint); +} + +static void tx_fifo_write(uint8_t endpoint, uint8_t const * buffer, size_t count) +{ + size_t i; + volatile uint8_t * fifo_reg; + + fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[endpoint]); + + for (i = 0; i < count; i++) + { + *fifo_reg = buffer[i]; + } +} + +static int rx_fifo_read(uint8_t epnum, uint8_t * buffer) +{ + uint32_t i; + uint32_t count; + volatile uint8_t * fifo_reg; + + fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[epnum]); + + count = USB_REGS->EPCSR[epnum].RXCOUNTbits.RXCNT; + + for (i = 0; i < count; i++) + { + buffer[i] = fifo_reg[i & 3]; + } + + return count; +} + +static void xfer_complete(xfer_ctl_t * xfer, uint8_t result, bool in_isr) +{ + dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, result, in_isr); +} + +static void ep0_fill_tx(xfer_ctl_t * xfer_in) +{ + uint16_t left = xfer_in->total_len - xfer_in->transferred; + + if (left) + { + xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left); + tx_fifo_write(0, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size); + xfer_in->transferred += xfer_in->last_packet_size; + left = xfer_in->total_len - xfer_in->transferred; + } + + if (xfer_in->last_packet_size < xfer_in->max_packet_size || left == 0) + { + switch (ep0_get_stage()) + { + case EP0_STAGE_SETUP_IN_DATA: + case EP0_STAGE_DATA_IN: + case EP0_STAGE_DATA_IN_SENT: + ep0_set_stage(EP0_STAGE_DATA_IN_LAST_PACKET_FILLED); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1; + break; + case EP0_STAGE_SETUP_OUT_NO_DATA: + ep0_set_stage(EP0_STAGE_STATUS_IN); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); + break; + case EP0_STAGE_DATA_OUT_COMPLETE: + ep0_set_stage(EP0_STAGE_STATUS_IN); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); + break; + default: + break; + } + } + else + { + switch (ep0_get_stage()) + { + case EP0_STAGE_SETUP_IN_DATA: + ep0_set_stage(EP0_STAGE_DATA_IN); + // fall through + case EP0_STAGE_DATA_IN: + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1; + break; + default: + break; + } + } +} + +static void epn_fill_tx(xfer_ctl_t * xfer_in, uint8_t epnum) +{ + uint16_t left = xfer_in->total_len - xfer_in->transferred; + if (left) + { + xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left); + tx_fifo_write(epnum, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size); + } + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.TXPKTRDY = 1; +} + +static bool ep0_xfer(xfer_ctl_t * xfer, int dir) +{ + if (dir == TUSB_DIR_OUT) + { + if (xfer->total_len) + { + switch (_dcd.ep0_stage) + { + case EP0_STAGE_DATA_OUT_COMPLETE: + case EP0_STAGE_SETUP_OUT_DATA: + ep0_set_stage(EP0_STAGE_DATA_OUT); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; + break; + default: + TU_ASSERT(0); + } + } + else + { + switch (_dcd.ep0_stage) + { + case EP0_STAGE_DATA_IN_SENT: + ep0_set_stage(EP0_STAGE_NONE); + // fall through + case EP0_STAGE_NONE: + xfer_complete(xfer, XFER_RESULT_SUCCESS, true); + break; + default: + break; + } + } + } + else // IN + { + ep0_fill_tx(xfer); + } + + return true; +} + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + + TU_ASSERT(epnum < EP_MAX); + + xfer->max_packet_size = tu_edpt_packet_size(desc_edpt); + xfer->fifo_size = xfer->max_packet_size; + xfer->ep_addr = desc_edpt->bEndpointAddress; + + if (epnum != 0) + { + if (dir == TUSB_DIR_OUT) + { + epn_rx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer); + _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3; + } + else + { + epn_tx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer); + _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3; + } + } + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + + // Reserve EP0 FIFO address + _dcd.fifo_addr_top = 64 >> 3; + for (int i = 1; i < EP_MAX; ++i) + { + tu_memclr(&_dcd.xfer_status[i], sizeof(_dcd.xfer_status[i])); + } +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + (void) ep_addr; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + (void) rhport; + + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->last_packet_size = 0; + xfer->transferred = 0; + + if (epnum == 0) + { + return ep0_xfer(xfer, dir); + } + if (dir == TUSB_DIR_OUT) + { + USB_REGS->INTRRXEbits.w |= (1u << epnum); + } + else // IN + { + epn_fill_tx(xfer, epnum); + } + + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + (void) rhport; + + if (epnum == 0) + { + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 1; + } + else + { + if (dir == TUSB_DIR_OUT) + { + USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.SENDSTALL = 1; + } + else + { + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.SENDSTALL = 1; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + (void) rhport; + + if (epnum == 0) + { + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 0; + } + else + { + if (dir == TUSB_DIR_OUT) + { + USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_RX_SENT_STALL | USBHS_EP_DEVICE_RX_SEND_STALL); + USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.CLRDT = 1; + } + else + { + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_TX_SENT_STALL | USBHS_EP_DEVICE_TX_SEND_STALL); + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.CLRDT = 1; + } + } +} + +/*------------------------------------------------------------------*/ +/* Interrupt Handler + *------------------------------------------------------------------*/ + +static void ep0_handle_rx(void) +{ + int transferred; + xfer_ctl_t * xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT); + + TU_ASSERT(xfer->buffer,); + + transferred = rx_fifo_read(0, xfer->buffer + xfer->transferred); + xfer->transferred += transferred; + if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) + { + ep0_set_stage(EP0_STAGE_DATA_OUT_COMPLETE); + xfer_complete(xfer, XFER_RESULT_SUCCESS, true); + } + else + { + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; + } +} + +static void epn_handle_rx_int(uint8_t epnum) +{ + uint8_t ep_status; + int transferred; + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + + ep_status = USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w; + if (ep_status & USBHS_EP_DEVICE_RX_SENT_STALL) + { + USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_RX_SENT_STALL; + } + + if (ep_status & USBHS_EP0_HOST_RXPKTRDY) + { + TU_ASSERT(xfer->buffer != NULL,); + + transferred = rx_fifo_read(epnum, xfer->buffer + xfer->transferred); + USB_REGS->EPCSR[epnum].RXCSRL_HOSTbits.RXPKTRDY = 0; + xfer->transferred += transferred; + if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) + { + xfer_complete(xfer, XFER_RESULT_SUCCESS, true); + } + } +} + +static void epn_handle_tx_int(uint8_t epnum) +{ + uint8_t ep_status = USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w; + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); + + if (ep_status & USBHS_EP_DEVICE_TX_SENT_STALL) + { + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_TX_SENT_STALL; + } + else + { + xfer->transferred += xfer->last_packet_size; + if (xfer->last_packet_size < xfer->max_packet_size || xfer->transferred == xfer->total_len) + { + xfer->last_packet_size = 0; + xfer_complete(xfer, XFER_RESULT_SUCCESS, true); + } + else + { + epn_fill_tx(xfer, epnum); + } + } +} + +static void ep0_handle_int(void) +{ + __USBHS_CSR0L_DEVICE_t ep0_status; + union { + tusb_control_request_t request; + uint32_t setup_buffer[2]; + } setup_packet; + xfer_ctl_t * xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN); + uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; + + // Select EP0 registers + USB_REGS->INDEXbits.ENDPOINT = 0; + + ep0_status = USB_REGS->EPCSR[0].CSR0L_DEVICEbits; + + if (ep0_status.SENTSTALL) + { + // Stall was sent. Reset the endpoint 0 state. + // Clear the sent stall bit. + ep0_set_stage(EP0_STAGE_NONE); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENTSTALL = 0; + } + + if (ep0_status.SETUPEND) + { + // This means the current control transfer end prematurely. We don't + // need to end any transfers. The device layer will manage the + // premature transfer end. We clear the SetupEnd bit and reset the + // driver control transfer state machine to waiting for next setup + // packet from host. + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVSSETEND = 1; + ep0_set_stage(EP0_STAGE_NONE); + } + + if (ep0_status.RXPKTRDY) + { + switch (ep0_get_stage()) + { + default: + // Data arrived at unexpected state, this must be setup stage packet after all. + // Fall through + case EP0_STAGE_NONE: + // This means we were expecting a SETUP packet and we got one. + setup_packet.setup_buffer[0] = USB_REGS->FIFO[0]; + setup_packet.setup_buffer[1] = USB_REGS->FIFO[0]; + if (setup_packet.request.bmRequestType_bit.direction == TUSB_DIR_OUT) + { + // SVCRPR is not set yet, it will be set later when out xfer is started + // Till then NAKs will hold incommint data + ep0_set_stage(setup_packet.request.wLength == 0 ? EP0_STAGE_SETUP_OUT_NO_DATA : EP0_STAGE_SETUP_OUT_DATA); + } + else + { + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; + ep0_set_stage(EP0_STAGE_SETUP_IN_DATA); + } + dcd_event_setup_received(0, &setup_packet.request.bmRequestType, true); + break; + case EP0_STAGE_DATA_OUT: + ep0_handle_rx(); + break; + } + } + else + { + switch (ep0_get_stage()) + { + case EP0_STAGE_STATUS_IN: + // Status was just sent, this concludes request, notify client + ep0_set_stage(EP0_STAGE_NONE); + xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true); + break; + case EP0_STAGE_DATA_IN: + // Packet sent, fill more data + ep0_fill_tx(xfer_in); + break; + case EP0_STAGE_DATA_IN_LAST_PACKET_FILLED: + ep0_set_stage(EP0_STAGE_DATA_IN_SENT); + xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true); + break; + case EP0_STAGE_ADDRESS_CHANGE: + // Status stage after set address request finished, address can be changed + USB_REGS->FADDRbits.FUNC = _dcd.dev_addr; + ep0_set_stage(EP0_STAGE_NONE); + break; + default: + break; + } + } + // Restore register index + USB_REGS->INDEXbits.ENDPOINT = old_index; +} + +void dcd_int_handler(uint8_t rhport) +{ + int i; + uint8_t mask; + __USBCSR2bits_t csr2_bits; + uint16_t rxints = USB_REGS->INTRRX; + uint16_t txints = USB_REGS->INTRTX; + csr2_bits = USBCSR2bits; + (void) rhport; + + IFS4CLR = _IFS4_USBIF_MASK; + + if (csr2_bits.SOFIF && csr2_bits.SOFIE) + { + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } + if (csr2_bits.RESETIF) + { + dcd_edpt_open(0, &ep0OUT_desc); + dcd_edpt_open(0, &ep0IN_desc); + dcd_event_bus_reset(0, USB_REGS->POWERbits.HSMODE ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + } + if (csr2_bits.SUSPIF) + { + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + if (csr2_bits.RESUMEIF) + { + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + // INTRTX has bit for EP0 + if (txints & 1) + { + txints ^= 1; + ep0_handle_int(); + } + for (mask = 0x02, i = 1; rxints != 0 && mask != 0; mask <<= 1, ++i) + { + if (rxints & mask) + { + rxints ^= mask; + epn_handle_rx_int(i); + } + } + for (mask = 0x02, i = 1; txints != 0 && mask != 0; mask <<= 1, ++i) + { + if (txints & mask) + { + txints ^= mask; + epn_handle_tx_int(i); + } + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/microchip/pic32mz/usbhs_registers.h b/circuitpython/lib/tinyusb/src/portable/microchip/pic32mz/usbhs_registers.h new file mode 100644 index 0000000..757e3f0 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/microchip/pic32mz/usbhs_registers.h @@ -0,0 +1,931 @@ +/******************************************************************************* +* Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries. +* +* Subject to your compliance with these terms, you may use Microchip software +* and any derivatives exclusively with Microchip products. It is your +* responsibility to comply with third party license terms applicable to your +* use of third party software (including open source software) that may +* accompany Microchip software. +* +* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED +* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A +* PARTICULAR PURPOSE. +* +* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS +* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE +* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN +* ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, +* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. +*******************************************************************************/ +/******************************************************************************* + USBHS Peripheral Library Register Defintions + + File Name: + usbhs_registers.h + + Summary: + USBHS PLIB Register Defintions + + Description: + This file contains the constants and defintions which are required by the + the USBHS library. +*******************************************************************************/ + +#ifndef __USBHS_REGISTERS_H__ +#define __USBHS_REGISTERS_H__ + +#include +#include + +/***************************************** + * Module Register Offsets. + *****************************************/ + +#define USBHS_REG_FADDR 0x000 +#define USBHS_REG_POWER 0x001 +#define USBHS_REG_INTRTX 0x002 +#define USBHS_REG_INTRRX 0x004 +#define USBHS_REG_INTRTXE 0x006 +#define USBHS_REG_INTRRXE 0x008 +#define USBHS_REG_INTRUSB 0x00A +#define USBHS_REG_INTRUSBE 0x00B +#define USBHS_REG_FRAME 0x00C +#define USBHS_REG_INDEX 0x00E +#define USBHS_REG_TESTMODE 0x00F + +/******************************************************* + * Endpoint Control Status Registers (CSR). These values + * should be added to either the 0x10 to access the + * register through Indexed CSR. To access the actual + * CSR, see ahead in this header file. + ******************************************************/ + +#define USBHS_REG_EP_TXMAXP 0x000 +#define USBHS_REG_EP_CSR0L 0x002 +#define USBHS_REG_EP_CSR0H 0x003 +#define USBHS_REG_EP_TXCSRL 0x002 +#define USBHS_REG_EP_TXCSRH 0x003 +#define USBHS_REG_EP_RXMAXP 0x004 +#define USBHS_REG_EP_RXCSRL 0x006 +#define USBHS_REG_EP_RXCSRH 0x007 +#define USBHS_REG_EP_COUNT0 0x008 +#define USBHS_REG_EP_RXCOUNT 0x008 +#define USBHS_REG_EP_TYPE0 0x01A +#define USBHS_REG_EP_TXTYPE 0x01A +#define USBHS_REG_EP_NAKLIMIT0 0x01B +#define USBHS_REG_EP_TXINTERVAL 0x01B +#define USBHS_REG_EP_RXTYPE 0x01C +#define USBHS_REG_EP_RXINTERVAL 0x01D +#define USBHS_REG_EP_CONFIGDATA 0x01F +#define USBHS_REG_EP_FIFOSIZE 0x01F + +#define USBHS_HOST_EP0_SETUPKT_SET 0x8 +#define USBHS_HOST_EP0_TXPKTRDY_SET 0x2 +#define USBHS_SOFT_RST_NRST_SET 0x1 +#define USBHS_SOFT_RST_NRSTX_SET 0x2 +#define USBHS_EP0_DEVICE_SERVICED_RXPKTRDY 0x40 +#define USBHS_EP0_DEVICE_DATAEND 0x08 +#define USBHS_EP0_DEVICE_TXPKTRDY 0x02 +#define USBHS_EP0_HOST_STATUS_STAGE_START 0x40 +#define USBHS_EP0_HOST_REQPKT 0x20 +#define USBHS_EP0_HOST_TXPKTRDY 0x02 +#define USBHS_EP0_HOST_RXPKTRDY 0x01 +#define USBHS_EP_DEVICE_TX_SENT_STALL 0x20 +#define USBHS_EP_DEVICE_TX_SEND_STALL 0x10 +#define USBHS_EP_DEVICE_RX_SENT_STALL 0x40 +#define USBHS_EP_DEVICE_RX_SEND_STALL 0x20 + +/* FADDR - Device Function Address */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned FUNC:7; + unsigned :1; + }; + + uint8_t w; + +} __USBHS_FADDR_t; + +/* POWER - Control Resume and Suspend signalling */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned SUSPEN:1; + unsigned SUSPMODE:1; + unsigned RESUME:1; + unsigned RESET:1; + unsigned HSMODE:1; + unsigned HSEN:1; + unsigned SOFTCONN:1; + unsigned ISOUPD:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_POWER_t; + +/* INTRTXE - Transmit endpoint interrupt enable */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned EP0IE:1; + unsigned EP1TXIE:1; + unsigned EP2TXIE:1; + unsigned EP3TXIE:1; + unsigned EP4TXIE:1; + unsigned EP5TXIE:1; + unsigned EP6TXIE:1; + unsigned EP7TXIE:1; + unsigned :8; + }; + struct + { + uint16_t w; + }; + +} __USBHS_INTRTXE_t; + +/* INTRRXE - Receive endpoint interrupt enable */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned :1; + unsigned EP1RXIE:1; + unsigned EP2RXIE:1; + unsigned EP3RXIE:1; + unsigned EP4RXIE:1; + unsigned EP5RXIE:1; + unsigned EP6RXIE:1; + unsigned EP7RXIE:1; + unsigned :8; + }; + struct + { + uint16_t w; + }; + +} __USBHS_INTRRXE_t; + +/* INTRUSBE - General USB Interrupt enable */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned SUSPIE:1; + unsigned RESUMEIE:1; + unsigned RESETIE:1; + unsigned SOFIE:1; + unsigned CONNIE:1; + unsigned DISCONIE:1; + unsigned SESSRQIE:1; + unsigned VBUSERRIE:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_INTRUSBE_t; + +/* FRAME - Frame number */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RFRMNUM:11; + unsigned :5; + }; + struct + { + uint16_t w; + }; + +} __USBHS_FRAME_t; + +/* INDEX - Endpoint index */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned ENDPOINT:4; + unsigned :4; + }; + struct + { + uint8_t w; + }; + +} __USBHS_INDEX_t; + +/* TESTMODE - Test mode register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned NAK:1; + unsigned TESTJ:1; + unsigned TESTK:1; + unsigned PACKET:1; + unsigned FORCEHS:1; + unsigned FORCEFS:1; + unsigned FIFOACC:1; + unsigned FORCEHST:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TESTMODE_t; + +/* COUNT0 - Indicates the amount of data received in endpoint 0 */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXCNT:7; + unsigned :1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_COUNT0_t; + +/* TYPE0 - Operating speed of target device */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned :6; + unsigned SPEED:2; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TYPE0_t; + +/* DEVCTL - Module control register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned SESSION:1; + unsigned HOSTREQ:1; + unsigned HOSTMODE:1; + unsigned VBUS:2; + unsigned LSDEV:1; + unsigned FSDEV:1; + unsigned BDEV:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_DEVCTL_t; + +/* CSR0L Device - Endpoint Device Mode Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXPKTRDY:1; + unsigned TXPKTRDY:1; + unsigned SENTSTALL:1; + unsigned DATAEND:1; + unsigned SETUPEND:1; + unsigned SENDSTALL:1; + unsigned SVCRPR:1; + unsigned SVSSETEND:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_CSR0L_DEVICE_t; + +/* CSR0L Host - Endpoint Host Mode Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXPKTRDY:1; + unsigned TXPKTRDY:1; + unsigned RXSTALL:1; + unsigned SETUPPKT:1; + unsigned ERROR:1; + unsigned REQPKT:1; + unsigned STATPKT:1; + unsigned NAKTMOUT:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_CSR0L_HOST_t; + +/* TXCSRL Device - Endpoint Transmit Control Status Register Low */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXPKTRDY:1; + unsigned FIFOONE:1; + unsigned UNDERRUN:1; + unsigned FLUSH:1; + unsigned SENDSTALL:1; + unsigned SENTSTALL:1; + unsigned CLRDT:1; + unsigned INCOMPTX:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXCSRL_DEVICE_t; + +/* TXCSRL Host - Endpoint Transmit Control Status Register Low */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXPKTRDY:1; + unsigned FIFONE:1; + unsigned ERROR:1; + unsigned FLUSH:1; + unsigned SETUPPKT:1; + unsigned RXSTALL:1; + unsigned CLRDT:1; + unsigned INCOMPTX:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXCSRL_HOST_t; + +/* TXCSRH Device - Endpoint Transmit Control Status Register High */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned :2; + unsigned DMAREQMD:1; + unsigned FRCDATTG:1; + unsigned DMAREQENL:1; + unsigned MODE:1; + unsigned ISO:1; + unsigned AUTOSET:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXCSRH_DEVICE_t; + +/* TXCSRH Host - Endpoint Transmit Control Status Register High */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned DATATGGL:1; + unsigned DTWREN:1; + unsigned DMAREQMD:1; + unsigned FRCDATTG:1; + unsigned DMAREQEN:1; + unsigned MODE:1; + unsigned :1; + unsigned AUOTSET:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXCSRH_HOST_t; + +/* CSR0H Device - Endpoint 0 Control Status Register High */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned FLSHFIFO:1; + unsigned :7; + }; + struct + { + uint8_t w; + }; + +} __USBHS_CSR0H_DEVICE_t; + +/* CSR0H Host - Endpoint 0 Control Status Register High */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned FLSHFIFO:1; + unsigned DATATGGL:1; + unsigned DTWREN:1; + unsigned DISPING:1; + unsigned :4; + }; + struct + { + uint8_t w; + }; + +} __USBHS_CSR0H_HOST_t; + +/* RXMAXP - Receive Endpoint Max packet size. */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXMAXP:11; + unsigned MULT:5; + }; + struct + { + uint16_t w; + }; + +} __USBHS_RXMAXP_t; + +/* RXCSRL Device - Receive endpoint Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXPKTRDY:1; + unsigned FIFOFULL:1; + unsigned OVERRUN:1; + unsigned DATAERR:1; + unsigned FLUSH:1; + unsigned SENDSTALL:1; + unsigned SENTSTALL:1; + unsigned CLRDT:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXCSRL_DEVICE_t; + +/* RXCSRL Host - Receive endpoint Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXPKTRDY:1; + unsigned FIFOFULL:1; + unsigned ERROR:1; + unsigned DERRNAKT:1; + unsigned FLUSH:1; + unsigned REQPKT:1; + unsigned RXSTALL:1; + unsigned CLRDT:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXCSRL_HOST_t; + +/* RXCSRH Device - Receive endpoint Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned INCOMPRX:1; + unsigned :2; + unsigned DMAREQMODE:1; + unsigned DISNYET:1; + unsigned DMAREQEN:1; + unsigned ISO:1; + unsigned AUTOCLR:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXCSRH_DEVICE_t; + +/* RXCSRH Host - Receive endpoint Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned INCOMPRX:1; + unsigned DATATGGL:1; + unsigned DATATWEN:1; + unsigned DMAREQMD:1; + unsigned PIDERR:1; + unsigned DMAREQEN:1; + unsigned AUTORQ:1; + unsigned AUOTCLR:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXCSRH_HOST_t; + +/* RXCOUNT - Amount of data pending in RX FIFO */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXCNT:14; + unsigned :2; + }; + struct + { + uint16_t w; + }; + +} __USBHS_RXCOUNT_t; + +/* TXTYPE - Specifies the target transmit endpoint */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TEP:4; + unsigned PROTOCOL:2; + unsigned SPEED:2; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXTYPE_t; + +/* RXTYPE - Specifies the target receive endpoint */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TEP:4; + unsigned PROTOCOL:2; + unsigned SPEED:2; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXTYPE_t; + +/* TXINTERVAL - Defines the polling interval */ +typedef struct +{ + uint8_t TXINTERV; + +} __USBHS_TXINTERVAL_t; + +/* RXINTERVAL - Defines the polling interval */ +typedef struct +{ + uint8_t RXINTERV; + +} __USBHS_RXINTERVAL_t; + +/* TXMAXP - Maximum amount of data that can be transferred through a TX endpoint + * */ + +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXMAXP:11; + unsigned MULT:5; + }; + uint16_t w; + +} __USBHS_TXMAXP_t; + +/* TXFIFOSZ - Size of the transmit endpoint FIFO */ +typedef struct __attribute__((packed)) +{ + unsigned TXFIFOSZ:4; + unsigned TXDPB:1; + unsigned :3; + +} __USBHS_TXFIFOSZ_t; + +/* RXFIFOSZ - Size of the receive endpoint FIFO */ +typedef struct __attribute__((packed)) +{ + unsigned RXFIFOSZ:4; + unsigned RXDPB:1; + unsigned :3; + +} __USBHS_RXFIFOSZ_t; + +/* TXFIFOADD - Start address of the transmit endpoint FIFO */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXFIFOAD:13; + unsigned :3; + }; + uint16_t w; + +} __USBHS_TXFIFOADD_t; + +/* RXFIFOADD - Start address of the receive endpoint FIFO */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXFIFOAD:13; + unsigned :3; + }; + uint16_t w; + +} __USBHS_RXFIFOADD_t; + +/* SOFTRST - Asserts NRSTO and NRSTOX */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned NRST:1; + unsigned NRSTX:1; + unsigned :6; + }; + uint8_t w; + +} __USBHS_SOFTRST_t; + +/* TXFUNCADDR - Target address of transmit endpoint */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXFADDR:7; + unsigned :1; + }; + uint8_t w; + +} __USBHS_TXFUNCADDR_t; + +/* RXFUNCADDR - Target address of receive endpoint */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXFADDR:7; + unsigned :1; + }; + uint8_t w; + +} __USBHS_RXFUNCADDR_t; + +/* TXHUBADDR - Address of the hub to which the target transmit device endpoint + * is connected */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXHUBADDR:7; + unsigned MULTTRAN:1; + }; + uint8_t w; + +} __USBHS_TXHUBADDR_t; + +/* RXHUBADDR - Address of the hub to which the target receive device endpoint is + * connected */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXHUBADDR:7; + unsigned MULTTRAN:1; + }; + uint8_t w; + +} __USBHS_RXHUBADDR_t; + +/* TXHUBPORT - Address of the hub to which the target transmit device endpoint + * is connected. */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXHUBPRT:7; + unsigned :1; + }; + + uint8_t w; + +} __USBHS_TXHUBPORT_t; + +/* RXHUBPORT - Address of the hub to which the target receive device endpoint + * is connected. */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXHUBPRT:7; + unsigned :1; + }; + + uint8_t w; + +} __USBHS_RXHUBPORT_t; + +/* DMACONTROL - Configures a DMA channel */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned DMAEN:1; + unsigned DMADIR:1; + unsigned DMAMODE:1; + unsigned DMAIE:1; + unsigned DMAEP:4; + unsigned DMAERR:1; + unsigned DMABRSTM:2; + unsigned:21; + }; + + uint32_t w; + +} __USBHS_DMACNTL_t; + +/* Endpoint Control and Status Register Set */ +typedef struct __attribute__((packed)) +{ + volatile __USBHS_TXMAXP_t TXMAXPbits; + union + { + struct + { + union + { + volatile __USBHS_CSR0L_DEVICE_t CSR0L_DEVICEbits; + volatile __USBHS_CSR0L_HOST_t CSR0L_HOSTbits; + }; + union + { + volatile __USBHS_CSR0H_DEVICE_t CSR0H_DEVICEbits; + volatile __USBHS_CSR0H_HOST_t CSR0H_HOSTbits; + }; + }; + + struct + { + union + { + volatile __USBHS_TXCSRL_DEVICE_t TXCSRL_DEVICEbits; + volatile __USBHS_TXCSRL_HOST_t TXCSRL_HOSTbits; + }; + + union + { + volatile __USBHS_TXCSRH_DEVICE_t TXCSRH_DEVICEbits; + volatile __USBHS_TXCSRH_HOST_t TXCSRH_HOSTbits; + }; + }; + }; + + volatile __USBHS_RXMAXP_t RXMAXPbits; + + union + { + volatile __USBHS_RXCSRL_DEVICE_t RXCSRL_DEVICEbits; + volatile __USBHS_RXCSRL_HOST_t RXCSRL_HOSTbits; + }; + + union + { + volatile __USBHS_RXCSRH_DEVICE_t RXCSRH_DEVICEbits; + volatile __USBHS_RXCSRH_HOST_t RXCSRH_HOSTbits; + }; + + union + { + volatile __USBHS_COUNT0_t COUNT0bits; + volatile __USBHS_RXCOUNT_t RXCOUNTbits; + }; + + union + { + volatile __USBHS_TYPE0_t TYPE0bits; + volatile __USBHS_TXTYPE_t TXTYPEbits; + }; + + union + { + volatile uint8_t NAKLIMIT0; + volatile __USBHS_TXINTERVAL_t TXINTERVALbits; + }; + + volatile __USBHS_RXTYPE_t RXTYPEbits; + volatile __USBHS_RXINTERVAL_t RXINTERVALbits; + unsigned :8; + union + { + volatile uint8_t CONFIGDATA; + volatile uint8_t FIFOSIZE; + }; + +} __USBHS_EPCSR_t; + +/* Set of registers that configure the multi-point option */ +typedef struct __attribute__((packed)) +{ + volatile __USBHS_TXFUNCADDR_t TXFUNCADDRbits; + unsigned :8; + volatile __USBHS_TXHUBADDR_t TXHUBADDRbits; + volatile __USBHS_TXHUBPORT_t TXHUBPORTbits; + volatile __USBHS_RXFUNCADDR_t RXFUNCADDRbits; + unsigned :8; + volatile __USBHS_RXHUBADDR_t RXHUBADDRbits; + volatile __USBHS_RXHUBPORT_t RXHUBPORTbits; + +} __USBHS_TARGET_ADDR_t; + +/* Set of registers that configure the DMA channel */ +typedef struct __attribute__((packed)) +{ + volatile __USBHS_DMACNTL_t DMACNTLbits; + volatile uint32_t DMAADDR; + volatile uint32_t DMACOUNT; + volatile uint32_t pad; +} __USBHS_DMA_CHANNEL_t; + +/* USBHS module register set */ +typedef struct __attribute__((aligned(4),packed)) +{ + volatile __USBHS_FADDR_t FADDRbits; + volatile __USBHS_POWER_t POWERbits; + volatile uint16_t INTRTX; + volatile uint16_t INTRRX; + volatile __USBHS_INTRTXE_t INTRTXEbits; + volatile __USBHS_INTRRXE_t INTRRXEbits; + volatile uint8_t INTRUSB; + volatile __USBHS_INTRUSBE_t INTRUSBEbits; + volatile __USBHS_FRAME_t FRAMEbits; + volatile __USBHS_INDEX_t INDEXbits; + volatile __USBHS_TESTMODE_t TESTMODEbits; + volatile __USBHS_EPCSR_t INDEXED_EPCSR; + volatile uint32_t FIFO[16]; + volatile __USBHS_DEVCTL_t DEVCTLbits; + volatile uint8_t MISC; + volatile __USBHS_TXFIFOSZ_t TXFIFOSZbits; + volatile __USBHS_RXFIFOSZ_t RXFIFOSZbits; + + volatile __USBHS_TXFIFOADD_t TXFIFOADDbits; + volatile __USBHS_RXFIFOADD_t RXFIFOADDbits; + + volatile uint32_t VCONTROL; + volatile uint16_t HWVERS; + volatile uint8_t padding1[10]; + volatile uint8_t EPINFO; + volatile uint8_t RAMINFO; + volatile uint8_t LINKINFO; + volatile uint8_t VPLEN; + volatile uint8_t HS_EOF1; + volatile uint8_t FS_EOF1; + volatile uint8_t LS_EOF1; + + volatile __USBHS_SOFTRST_t SOFTRSTbits; + + volatile __USBHS_TARGET_ADDR_t TADDR[16]; + volatile __USBHS_EPCSR_t EPCSR[16]; + volatile uint32_t DMA_INTR; + volatile __USBHS_DMA_CHANNEL_t DMA_CHANNEL[8]; + volatile uint32_t RQPKTXOUNT[16]; + +} usbhs_registers_t; + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/microchip/samd/dcd_samd.c b/circuitpython/lib/tinyusb/src/portable/microchip/samd/dcd_samd.c new file mode 100644 index 0000000..c4ee6f2 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/microchip/samd/dcd_samd.c @@ -0,0 +1,419 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_SAMD11 || CFG_TUSB_MCU == OPT_MCU_SAMD21 || \ + CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X || \ + CFG_TUSB_MCU == OPT_MCU_SAML22 || CFG_TUSB_MCU == OPT_MCU_SAML21) + +#include "sam.h" +#include "device/dcd.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +static TU_ATTR_ALIGNED(4) UsbDeviceDescBank sram_registers[8][2]; + +// Setup packet is only 8 bytes in length. However under certain scenario, +// USB DMA controller may decide to overwrite/overflow the buffer with +// 2 extra bytes of CRC. From datasheet's "Management of SETUP Transactions" section +// If the number of received data bytes is the maximum data payload specified by +// PCKSIZE.SIZE minus one, only the first CRC data is written to the data buffer. +// If the number of received data is equal or less than the data payload specified +// by PCKSIZE.SIZE minus two, both CRC data bytes are written to the data buffer. +// Therefore we will need to increase it to 10 bytes here. +static TU_ATTR_ALIGNED(4) uint8_t _setup_packet[8+2]; + +// ready for receiving SETUP packet +static inline void prepare_setup(void) +{ + // Only make sure the EP0 OUT buffer is ready + sram_registers[0][0].ADDR.reg = (uint32_t) _setup_packet; + sram_registers[0][0].PCKSIZE.bit.MULTI_PACKET_SIZE = sizeof(tusb_control_request_t); + sram_registers[0][0].PCKSIZE.bit.BYTE_COUNT = 0; +} + +// Setup the control endpoint 0. +static void bus_reset(void) +{ + // Max size of packets is 64 bytes. + UsbDeviceDescBank* bank_out = &sram_registers[0][TUSB_DIR_OUT]; + bank_out->PCKSIZE.bit.SIZE = 0x3; + UsbDeviceDescBank* bank_in = &sram_registers[0][TUSB_DIR_IN]; + bank_in->PCKSIZE.bit.SIZE = 0x3; + + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[0]; + ep->EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(0x1) | USB_DEVICE_EPCFG_EPTYPE1(0x1); + ep->EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1 | USB_DEVICE_EPINTENSET_RXSTP; + + // Prepare for setup packet + prepare_setup(); +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init (uint8_t rhport) +{ + (void) rhport; + + // Reset to get in a clean state. + USB->DEVICE.CTRLA.bit.SWRST = true; + while (USB->DEVICE.SYNCBUSY.bit.SWRST == 0) {} + while (USB->DEVICE.SYNCBUSY.bit.SWRST == 1) {} + + USB->DEVICE.PADCAL.bit.TRANSP = (*((uint32_t*) USB_FUSES_TRANSP_ADDR) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; + USB->DEVICE.PADCAL.bit.TRANSN = (*((uint32_t*) USB_FUSES_TRANSN_ADDR) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; + USB->DEVICE.PADCAL.bit.TRIM = (*((uint32_t*) USB_FUSES_TRIM_ADDR) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos; + + USB->DEVICE.QOSCTRL.bit.CQOS = 3; // High Quality + USB->DEVICE.QOSCTRL.bit.DQOS = 3; // High Quality + + // Configure registers + USB->DEVICE.DESCADD.reg = (uint32_t) &sram_registers; + USB->DEVICE.CTRLB.reg = USB_DEVICE_CTRLB_SPDCONF_FS; + USB->DEVICE.CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_ENABLE | USB_CTRLA_RUNSTDBY; + while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1) {} + + USB->DEVICE.INTFLAG.reg |= USB->DEVICE.INTFLAG.reg; // clear pending + USB->DEVICE.INTENSET.reg = /* USB_DEVICE_INTENSET_SOF | */ USB_DEVICE_INTENSET_EORST; +} + +#if CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB_0_IRQn); + NVIC_EnableIRQ(USB_1_IRQn); + NVIC_EnableIRQ(USB_2_IRQn); + NVIC_EnableIRQ(USB_3_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_3_IRQn); + NVIC_DisableIRQ(USB_2_IRQn); + NVIC_DisableIRQ(USB_1_IRQn); + NVIC_DisableIRQ(USB_0_IRQn); +} + +#elif CFG_TUSB_MCU == OPT_MCU_SAMD11 || CFG_TUSB_MCU == OPT_MCU_SAMD21 || \ + CFG_TUSB_MCU == OPT_MCU_SAML22 || CFG_TUSB_MCU == OPT_MCU_SAML21 + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_IRQn); +} + +#else + +#error "No implementation available for dcd_int_enable / dcd_int_disable" + +#endif + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) dev_addr; + + // Response with zlp status + dcd_edpt_xfer(rhport, 0x80, NULL, 0); + + // DCD can only set address after status for this request is complete + // do it at dcd_edpt0_status_complete() + + // Enable SUSPEND interrupt since the bus signal D+/D- are stable now. + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTENCLR_SUSPEND; // clear pending + USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_SUSPEND; +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + USB->DEVICE.CTRLB.bit.UPRSM = 1; +} + +// disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_DETACH; +} + +// connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; +} + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS ) + { + uint8_t const dev_addr = (uint8_t) request->wValue; + USB->DEVICE.DADD.reg = USB_DEVICE_DADD_DADD(dev_addr) | USB_DEVICE_DADD_ADDEN; + } + + // Just finished status stage, prepare for next setup packet + // Note: we may already prepare setup when queueing the control status. + // but it has no harm to do it again here + prepare_setup(); +} + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; + uint32_t size_value = 0; + while (size_value < 7) { + if (1 << (size_value + 3) == tu_edpt_packet_size(desc_edpt)) { + break; + } + size_value++; + } + + // unsupported endpoint size + if ( size_value == 7 && tu_edpt_packet_size(desc_edpt) != 1023 ) return false; + + bank->PCKSIZE.bit.SIZE = size_value; + + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if ( dir == TUSB_DIR_OUT ) + { + ep->EPCFG.bit.EPTYPE0 = desc_edpt->bmAttributes.xfer + 1; + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0 | USB_DEVICE_EPSTATUSCLR_DTGLOUT; // clear stall & dtoggle + ep->EPINTENSET.bit.TRCPT0 = true; + }else + { + ep->EPCFG.bit.EPTYPE1 = desc_edpt->bmAttributes.xfer + 1; + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1 | USB_DEVICE_EPSTATUSCLR_DTGLIN; // clear stall & dtoggle + ep->EPINTENSET.bit.TRCPT1 = true; + } + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + bank->ADDR.reg = (uint32_t) buffer; + + // A SETUP token can occur immediately after an ZLP Status. + // So make sure we have a valid buffer for setup packet. + // Status = ZLP EP0 with direction opposite to one in the dir bit of current setup + if ( (epnum == 0) && (buffer == NULL) && (total_bytes == 0) && (dir != tu_edpt_dir(_setup_packet[0])) ) { + prepare_setup(); + } + + if ( dir == TUSB_DIR_OUT ) + { + bank->PCKSIZE.bit.MULTI_PACKET_SIZE = total_bytes; + bank->PCKSIZE.bit.BYTE_COUNT = 0; + ep->EPSTATUSCLR.reg |= USB_DEVICE_EPSTATUSCLR_BK0RDY; + ep->EPINTFLAG.reg |= USB_DEVICE_EPINTFLAG_TRFAIL0; + } else + { + bank->PCKSIZE.bit.MULTI_PACKET_SIZE = 0; + bank->PCKSIZE.bit.BYTE_COUNT = total_bytes; + ep->EPSTATUSSET.reg |= USB_DEVICE_EPSTATUSSET_BK1RDY; + ep->EPINTFLAG.reg |= USB_DEVICE_EPINTFLAG_TRFAIL1; + } + + return true; +} + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; + } else { + ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; + } +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1 | USB_DEVICE_EPSTATUSCLR_DTGLIN; + } else { + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0 | USB_DEVICE_EPSTATUSCLR_DTGLOUT; + } +} + +//--------------------------------------------------------------------+ +// Interrupt Handler +//--------------------------------------------------------------------+ +void maybe_transfer_complete(void) { + uint32_t epints = USB->DEVICE.EPINTSMRY.reg; + + for (uint8_t epnum = 0; epnum < USB_EPT_NUM; epnum++) { + if ((epints & (1 << epnum)) == 0) { + continue; + } + + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + uint32_t epintflag = ep->EPINTFLAG.reg; + + // Handle IN completions + if ((epintflag & USB_DEVICE_EPINTFLAG_TRCPT1) != 0) { + UsbDeviceDescBank* bank = &sram_registers[epnum][TUSB_DIR_IN]; + uint16_t const total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT; + + dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, total_transfer_size, XFER_RESULT_SUCCESS, true); + + ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; + } + + // Handle OUT completions + if ((epintflag & USB_DEVICE_EPINTFLAG_TRCPT0) != 0) { + UsbDeviceDescBank* bank = &sram_registers[epnum][TUSB_DIR_OUT]; + uint16_t const total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT; + + dcd_event_xfer_complete(0, epnum, total_transfer_size, XFER_RESULT_SUCCESS, true); + + ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; + } + } +} + + +void dcd_int_handler (uint8_t rhport) +{ + (void) rhport; + + uint32_t int_status = USB->DEVICE.INTFLAG.reg & USB->DEVICE.INTENSET.reg; + + // Start of Frame + if ( int_status & USB_DEVICE_INTFLAG_SOF ) + { + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } + + // SAMD doesn't distinguish between Suspend and Disconnect state. + // Both condition will cause SUSPEND interrupt triggered. + // To prevent being triggered when D+/D- are not stable, SUSPEND interrupt is only + // enabled when we received SET_ADDRESS request and cleared on Bus Reset + if ( int_status & USB_DEVICE_INTFLAG_SUSPEND ) + { + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SUSPEND; + + // Enable wakeup interrupt + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_WAKEUP; // clear pending + USB->DEVICE.INTENSET.reg = USB_DEVICE_INTFLAG_WAKEUP; + + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + + // Wakeup interrupt is only enabled when we got suspended. + // Wakeup interrupt will disable itself + if ( int_status & USB_DEVICE_INTFLAG_WAKEUP ) + { + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_WAKEUP; + + // disable wakeup interrupt itself + USB->DEVICE.INTENCLR.reg = USB_DEVICE_INTFLAG_WAKEUP; + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + + // Enable of Reset + if ( int_status & USB_DEVICE_INTFLAG_EORST ) + { + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; + + // Disable both suspend and wakeup interrupt + USB->DEVICE.INTENCLR.reg = USB_DEVICE_INTFLAG_WAKEUP | USB_DEVICE_INTFLAG_SUSPEND; + + bus_reset(); + dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); + } + + // Handle SETUP packet + if (USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP) + { + // This copies the data elsewhere so we can reuse the buffer. + dcd_event_setup_received(0, _setup_packet, true); + + // Although Setup packet only set RXSTP bit, + // TRCPT0 bit could already be set by previous ZLP OUT Status (not handled until now). + // Since control status complete event is optional, we can just clear TRCPT0 and skip the status event + USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP | USB_DEVICE_EPINTFLAG_TRCPT0; + } + + // Handle complete transfer + maybe_transfer_complete(); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/microchip/samg/dcd_samg.c b/circuitpython/lib/tinyusb/src/portable/microchip/samg/dcd_samg.c new file mode 100644 index 0000000..2e98541 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/microchip/samg/dcd_samg.c @@ -0,0 +1,492 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUSB_MCU == OPT_MCU_SAMG + +#include "sam.h" +#include "device/dcd.h" + +// TODO should support (SAM3S || SAM4S || SAM4E || SAMG55) + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +#define EP_COUNT 6 + +// Transfer descriptor +typedef struct +{ + uint8_t* buffer; + // tu_fifo_t* ff; // TODO support dcd_edpt_xfer_fifo API + uint16_t total_len; + volatile uint16_t actual_len; + uint16_t epsize; +} xfer_desc_t; + +// Endpoint 0-5, each can only be either OUT or In +xfer_desc_t _dcd_xfer[EP_COUNT]; + +void xfer_epsize_set(xfer_desc_t* xfer, uint16_t epsize) +{ + xfer->epsize = epsize; +} + +void xfer_begin(xfer_desc_t* xfer, uint8_t * buffer, uint16_t total_bytes) +{ + xfer->buffer = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->total_len = total_bytes; + xfer->actual_len = 0; +} + +void xfer_end(xfer_desc_t* xfer) +{ + xfer->buffer = NULL; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->total_len = 0; + xfer->actual_len = 0; +} + +uint16_t xfer_packet_len(xfer_desc_t* xfer) +{ + // also cover zero-length packet + return tu_min16(xfer->total_len - xfer->actual_len, xfer->epsize); +} + +void xfer_packet_done(xfer_desc_t* xfer) +{ + uint16_t const xact_len = xfer_packet_len(xfer); + + xfer->buffer += xact_len; + xfer->actual_len += xact_len; +} + +//------------- Transaction helpers -------------// + +// Write data to EP FIFO, return number of written bytes +static void xact_ep_write(uint8_t epnum, uint8_t* buffer, uint16_t xact_len) +{ + for(uint16_t i=0; iUDP_FDR[epnum] = (uint32_t) buffer[i]; + } +} + +// Read data from EP FIFO +static void xact_ep_read(uint8_t epnum, uint8_t* buffer, uint16_t xact_len) +{ + for(uint16_t i=0; iUDP_FDR[epnum]; + } +} + + +//! Bitmap for all status bits in CSR that are not affected by a value 1. +#define CSR_NO_EFFECT_1_ALL (UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 | UDP_CSR_STALLSENT | UDP_CSR_RXSETUP | UDP_CSR_TXCOMP) + +// Per Specs: CSR need synchronization each write +static inline void csr_write(uint8_t epnum, uint32_t value) +{ + uint32_t const csr = value; + UDP->UDP_CSR[epnum] = csr; + + volatile uint32_t nop_count; + for (nop_count = 0; nop_count < 20; nop_count ++) __NOP(); +} + +// Per Specs: CSR need synchronization each write +static inline void csr_set(uint8_t epnum, uint32_t mask) +{ + csr_write(epnum, UDP->UDP_CSR[epnum] | CSR_NO_EFFECT_1_ALL | mask); +} + +// Per Specs: CSR need synchronization each write +static inline void csr_clear(uint8_t epnum, uint32_t mask) +{ + csr_write(epnum, (UDP->UDP_CSR[epnum] | CSR_NO_EFFECT_1_ALL) & ~mask); +} + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ + +// Set up endpoint 0, clear all other endpoints +static void bus_reset(void) +{ + tu_memclr(_dcd_xfer, sizeof(_dcd_xfer)); + + xfer_epsize_set(&_dcd_xfer[0], CFG_TUD_ENDPOINT0_SIZE); + + // Enable EP0 control + csr_write(0, UDP_CSR_EPEDS_Msk); + + // Enable interrupt : EP0, Suspend, Resume, Wakeup + UDP->UDP_IER = UDP_IER_EP0INT_Msk | UDP_IER_RXSUSP_Msk | UDP_IER_RXRSM_Msk | UDP_IER_WAKEUP_Msk; + + // Enable transceiver + UDP->UDP_TXVC &= ~UDP_TXVC_TXVDIS_Msk; +} + +// Initialize controller to device mode +void dcd_init (uint8_t rhport) +{ + tu_memclr(_dcd_xfer, sizeof(_dcd_xfer)); + dcd_connect(rhport); +} + +// Enable device interrupt +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(UDP_IRQn); +} + +// Disable device interrupt +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(UDP_IRQn); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + (void) dev_addr; + + // Response with zlp status + dcd_edpt_xfer(rhport, 0x80, NULL, 0); + + // DCD can only set address after status for this request is complete. + // do it at dcd_edpt0_status_complete() +} + +// Wake up host +void dcd_remote_wakeup (uint8_t rhport) +{ + (void) rhport; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + + // Enable pull-up, disable transceiver + UDP->UDP_TXVC = UDP_TXVC_PUON | UDP_TXVC_TXVDIS_Msk; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + + // disable both pullup and transceiver + UDP->UDP_TXVC = UDP_TXVC_TXVDIS_Msk; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) + { + if (request->bRequest == TUSB_REQ_SET_ADDRESS) + { + uint8_t const dev_addr = (uint8_t) request->wValue; + + // Enable addressed state + UDP->UDP_GLB_STAT |= UDP_GLB_STAT_FADDEN_Msk; + + // Set new address & Function enable bit + UDP->UDP_FADDR = UDP_FADDR_FEN_Msk | UDP_FADDR_FADD(dev_addr); + } + else if (request->bRequest == TUSB_REQ_SET_CONFIGURATION) + { + // Configured State + UDP->UDP_GLB_STAT |= UDP_GLB_STAT_CONFG_Msk; + } + } +} + +// Configure endpoint's registers according to descriptor +// SAMG doesn't support a same endpoint number with IN and OUT +// e.g EP1 OUT & EP1 IN cannot exist together +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(ep_desc->bEndpointAddress); + + // TODO Isochronous is not supported yet + TU_VERIFY(ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); + TU_VERIFY(epnum < EP_COUNT); + + // Must not already enabled + TU_ASSERT((UDP->UDP_CSR[epnum] & UDP_CSR_EPEDS_Msk) == 0); + + xfer_epsize_set(&_dcd_xfer[epnum], tu_edpt_packet_size(ep_desc)); + + // Configure type and enable EP + csr_write(epnum, UDP_CSR_EPEDS_Msk | UDP_CSR_EPTYPE(ep_desc->bmAttributes.xfer + 4*dir)); + + // Enable EP Interrupt for IN + if (dir == TUSB_DIR_IN) UDP->UDP_IER |= (1 << epnum); + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_desc_t* xfer = &_dcd_xfer[epnum]; + xfer_begin(xfer, buffer, total_bytes); + + if (dir == TUSB_DIR_OUT) + { + // Enable interrupt when starting OUT transfer + if (epnum != 0) UDP->UDP_IER |= (1 << epnum); + } + else + { + xact_ep_write(epnum, xfer->buffer, xfer_packet_len(xfer)); + + // TX ready for transfer + csr_set(epnum, UDP_CSR_TXPKTRDY_Msk); + } + + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + return true; +} +#endif + +// Stall endpoint +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + // For EP0 USBD will stall both EP0 Out and In with 0x00 and 0x80 + // only handle one by skipping 0x80 + if ( ep_addr == tu_edpt_addr(0, TUSB_DIR_IN_MASK) ) return; + + uint8_t const epnum = tu_edpt_number(ep_addr); + + // Set force stall bit + csr_set(epnum, UDP_CSR_FORCESTALL_Msk); +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + + // clear stall + csr_clear(epnum, UDP_CSR_FORCESTALL_Msk); + + // must also reset EP to clear data toggle + UDP->UDP_RST_EP |= (1 << epnum); + UDP->UDP_RST_EP &= ~(1 << epnum); +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void dcd_int_handler(uint8_t rhport) +{ + uint32_t const intr_mask = UDP->UDP_IMR; + uint32_t const intr_status = UDP->UDP_ISR & intr_mask; + + // clear interrupt + UDP->UDP_ICR = intr_status; + + // Bus reset + if (intr_status & UDP_ISR_ENDBUSRES_Msk) + { + bus_reset(); + dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); + } + + // SOF +// if (intr_status & UDP_ISR_SOFINT_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + + // Suspend + if (intr_status & UDP_ISR_RXSUSP_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + + // Resume + if (intr_status & UDP_ISR_RXRSM_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + + // Wakeup + if (intr_status & UDP_ISR_WAKEUP_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + + //------------- Endpoints -------------// + + if ( intr_status & TU_BIT(0) ) + { + // setup packet + if ( UDP->UDP_CSR[0] & UDP_CSR_RXSETUP ) + { + // get setup from FIFO + uint8_t setup[8]; + for(uint8_t i=0; iUDP_FDR[0]; + } + + // notify usbd + dcd_event_setup_received(rhport, setup, true); + + // Set EP direction bit according to DATA stage + // MUST only be set before RXSETUP is clear per specs + if ( tu_edpt_dir(setup[0]) ) + { + csr_set(0, UDP_CSR_DIR_Msk); + } + else + { + csr_clear(0, UDP_CSR_DIR_Msk); + } + + // Clear Setup, stall and other on-going transfer bits + csr_clear(0, UDP_CSR_RXSETUP_Msk | UDP_CSR_TXPKTRDY_Msk | UDP_CSR_TXCOMP_Msk | UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 | UDP_CSR_STALLSENT_Msk | UDP_CSR_FORCESTALL_Msk); + } + } + + for(uint8_t epnum = 0; epnum < EP_COUNT; epnum++) + { + if ( intr_status & TU_BIT(epnum) ) + { + xfer_desc_t* xfer = &_dcd_xfer[epnum]; + + //------------- Endpoint IN -------------// + if (UDP->UDP_CSR[epnum] & UDP_CSR_TXCOMP_Msk) + { + xfer_packet_done(xfer); + + uint16_t const xact_len = xfer_packet_len(xfer); + + if (xact_len) + { + // write to EP fifo +#if 0 // TODO support dcd_edpt_xfer_fifo + if (xfer->ff) + { + tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) &UDP->UDP_FDR[epnum], xact_len); + } + else +#endif + { + xact_ep_write(epnum, xfer->buffer, xact_len); + } + + // TX ready for transfer + csr_set(epnum, UDP_CSR_TXPKTRDY_Msk); + }else + { + // xfer is complete + dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); + + // Required since control OUT can happen right after before stack handle this event + xfer_end(xfer); + } + + // Clear TX Complete bit + csr_clear(epnum, UDP_CSR_TXCOMP_Msk); + } + + //------------- Endpoint OUT -------------// + // Ping-Pong is a MUST for Bulk/Iso + // NOTE: When both Bank0 and Bank1 are both set, there is no way to know which one comes first + uint32_t const banks_complete = UDP->UDP_CSR[epnum] & (UDP_CSR_RX_DATA_BK0_Msk | UDP_CSR_RX_DATA_BK1_Msk); + if (banks_complete) + { + uint16_t const xact_len = (uint16_t) ((UDP->UDP_CSR[epnum] & UDP_CSR_RXBYTECNT_Msk) >> UDP_CSR_RXBYTECNT_Pos); + + // Read from EP fifo +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) &UDP->UDP_FDR[epnum], xact_len); + } + else +#endif + { + xact_ep_read(epnum, xfer->buffer, xact_len); + } + + xfer_packet_done(xfer); + + if ( 0 == xfer_packet_len(xfer) ) + { + // Disable OUT EP interrupt when transfer is complete + if (epnum != 0) UDP->UDP_IDR |= (1 << epnum); + + dcd_event_xfer_complete(rhport, epnum, xfer->actual_len, XFER_RESULT_SUCCESS, true); + xfer_end(xfer); + } + + // Clear DATA Bank0/1 bit + csr_clear(epnum, banks_complete); + } + + // Stall sent to host + if (UDP->UDP_CSR[epnum] & UDP_CSR_STALLSENT_Msk) + { + csr_clear(epnum, UDP_CSR_STALLSENT_Msk); + } + } + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/microchip/samx7x/common_usb_regs.h b/circuitpython/lib/tinyusb/src/portable/microchip/samx7x/common_usb_regs.h new file mode 100644 index 0000000..d232f0b --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/microchip/samx7x/common_usb_regs.h @@ -0,0 +1,2108 @@ + /* +* The MIT License (MIT) +* +* Copyright (c) 2019 Microchip Technology Inc. +* Copyright (c) 2018, hathach (tinyusb.org) +* Copyright (c) 2021, HiFiPhile +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* This file is part of the TinyUSB stack. +*/ + +#ifndef _COMMON_USB_REGS_H_ +#define _COMMON_USB_REGS_H_ + +#if CFG_TUSB_MCU == OPT_MCU_SAMX7X + +/* -------- DEVDMANXTDSC : (USBHS Offset: 0x00) (R/W 32) Device DMA Channel Next Descriptor Address Register -------- */ + +#define DEVDMANXTDSC_OFFSET (0x00) /**< (DEVDMANXTDSC) Device DMA Channel Next Descriptor Address Register Offset */ + +#define DEVDMANXTDSC_NXT_DSC_ADD_Pos 0 /**< (DEVDMANXTDSC) Next Descriptor Address Position */ +#define DEVDMANXTDSC_NXT_DSC_ADD (_U_(0xFFFFFFFF) << DEVDMANXTDSC_NXT_DSC_ADD_Pos) /**< (DEVDMANXTDSC) Next Descriptor Address Mask */ +#define DEVDMANXTDSC_Msk _U_(0xFFFFFFFF) /**< (DEVDMANXTDSC) Register Mask */ + + +/* -------- DEVDMAADDRESS : (USBHS Offset: 0x04) (R/W 32) Device DMA Channel Address Register -------- */ + +#define DEVDMAADDRESS_OFFSET (0x04) /**< (DEVDMAADDRESS) Device DMA Channel Address Register Offset */ + +#define DEVDMAADDRESS_BUFF_ADD_Pos 0 /**< (DEVDMAADDRESS) Buffer Address Position */ +#define DEVDMAADDRESS_BUFF_ADD (_U_(0xFFFFFFFF) << DEVDMAADDRESS_BUFF_ADD_Pos) /**< (DEVDMAADDRESS) Buffer Address Mask */ +#define DEVDMAADDRESS_Msk _U_(0xFFFFFFFF) /**< (DEVDMAADDRESS) Register Mask */ + + +/* -------- DEVDMACONTROL : (USBHS Offset: 0x08) (R/W 32) Device DMA Channel Control Register -------- */ + +#define DEVDMACONTROL_OFFSET (0x08) /**< (DEVDMACONTROL) Device DMA Channel Control Register Offset */ + +#define DEVDMACONTROL_CHANN_ENB_Pos 0 /**< (DEVDMACONTROL) Channel Enable Command Position */ +#define DEVDMACONTROL_CHANN_ENB (_U_(0x1) << DEVDMACONTROL_CHANN_ENB_Pos) /**< (DEVDMACONTROL) Channel Enable Command Mask */ +#define DEVDMACONTROL_LDNXT_DSC_Pos 1 /**< (DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Position */ +#define DEVDMACONTROL_LDNXT_DSC (_U_(0x1) << DEVDMACONTROL_LDNXT_DSC_Pos) /**< (DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Mask */ +#define DEVDMACONTROL_END_TR_EN_Pos 2 /**< (DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only) Position */ +#define DEVDMACONTROL_END_TR_EN (_U_(0x1) << DEVDMACONTROL_END_TR_EN_Pos) /**< (DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only) Mask */ +#define DEVDMACONTROL_END_B_EN_Pos 3 /**< (DEVDMACONTROL) End of Buffer Enable Control Position */ +#define DEVDMACONTROL_END_B_EN (_U_(0x1) << DEVDMACONTROL_END_B_EN_Pos) /**< (DEVDMACONTROL) End of Buffer Enable Control Mask */ +#define DEVDMACONTROL_END_TR_IT_Pos 4 /**< (DEVDMACONTROL) End of Transfer Interrupt Enable Position */ +#define DEVDMACONTROL_END_TR_IT (_U_(0x1) << DEVDMACONTROL_END_TR_IT_Pos) /**< (DEVDMACONTROL) End of Transfer Interrupt Enable Mask */ +#define DEVDMACONTROL_END_BUFFIT_Pos 5 /**< (DEVDMACONTROL) End of Buffer Interrupt Enable Position */ +#define DEVDMACONTROL_END_BUFFIT (_U_(0x1) << DEVDMACONTROL_END_BUFFIT_Pos) /**< (DEVDMACONTROL) End of Buffer Interrupt Enable Mask */ +#define DEVDMACONTROL_DESC_LD_IT_Pos 6 /**< (DEVDMACONTROL) Descriptor Loaded Interrupt Enable Position */ +#define DEVDMACONTROL_DESC_LD_IT (_U_(0x1) << DEVDMACONTROL_DESC_LD_IT_Pos) /**< (DEVDMACONTROL) Descriptor Loaded Interrupt Enable Mask */ +#define DEVDMACONTROL_BURST_LCK_Pos 7 /**< (DEVDMACONTROL) Burst Lock Enable Position */ +#define DEVDMACONTROL_BURST_LCK (_U_(0x1) << DEVDMACONTROL_BURST_LCK_Pos) /**< (DEVDMACONTROL) Burst Lock Enable Mask */ +#define DEVDMACONTROL_BUFF_LENGTH_Pos 16 /**< (DEVDMACONTROL) Buffer Byte Length (Write-only) Position */ +#define DEVDMACONTROL_BUFF_LENGTH (_U_(0xFFFF) << DEVDMACONTROL_BUFF_LENGTH_Pos) /**< (DEVDMACONTROL) Buffer Byte Length (Write-only) Mask */ +#define DEVDMACONTROL_Msk _U_(0xFFFF00FF) /**< (DEVDMACONTROL) Register Mask */ + + +/* -------- DEVDMASTATUS : (USBHS Offset: 0x0c) (R/W 32) Device DMA Channel Status Register -------- */ + +#define DEVDMASTATUS_OFFSET (0x0C) /**< (DEVDMASTATUS) Device DMA Channel Status Register Offset */ + +#define DEVDMASTATUS_CHANN_ENB_Pos 0 /**< (DEVDMASTATUS) Channel Enable Status Position */ +#define DEVDMASTATUS_CHANN_ENB (_U_(0x1) << DEVDMASTATUS_CHANN_ENB_Pos) /**< (DEVDMASTATUS) Channel Enable Status Mask */ +#define DEVDMASTATUS_CHANN_ACT_Pos 1 /**< (DEVDMASTATUS) Channel Active Status Position */ +#define DEVDMASTATUS_CHANN_ACT (_U_(0x1) << DEVDMASTATUS_CHANN_ACT_Pos) /**< (DEVDMASTATUS) Channel Active Status Mask */ +#define DEVDMASTATUS_END_TR_ST_Pos 4 /**< (DEVDMASTATUS) End of Channel Transfer Status Position */ +#define DEVDMASTATUS_END_TR_ST (_U_(0x1) << DEVDMASTATUS_END_TR_ST_Pos) /**< (DEVDMASTATUS) End of Channel Transfer Status Mask */ +#define DEVDMASTATUS_END_BF_ST_Pos 5 /**< (DEVDMASTATUS) End of Channel Buffer Status Position */ +#define DEVDMASTATUS_END_BF_ST (_U_(0x1) << DEVDMASTATUS_END_BF_ST_Pos) /**< (DEVDMASTATUS) End of Channel Buffer Status Mask */ +#define DEVDMASTATUS_DESC_LDST_Pos 6 /**< (DEVDMASTATUS) Descriptor Loaded Status Position */ +#define DEVDMASTATUS_DESC_LDST (_U_(0x1) << DEVDMASTATUS_DESC_LDST_Pos) /**< (DEVDMASTATUS) Descriptor Loaded Status Mask */ +#define DEVDMASTATUS_BUFF_COUNT_Pos 16 /**< (DEVDMASTATUS) Buffer Byte Count Position */ +#define DEVDMASTATUS_BUFF_COUNT (_U_(0xFFFF) << DEVDMASTATUS_BUFF_COUNT_Pos) /**< (DEVDMASTATUS) Buffer Byte Count Mask */ +#define DEVDMASTATUS_Msk _U_(0xFFFF0073) /**< (DEVDMASTATUS) Register Mask */ + + +/* -------- HSTDMANXTDSC : (USBHS Offset: 0x00) (R/W 32) Host DMA Channel Next Descriptor Address Register -------- */ + +#define HSTDMANXTDSC_OFFSET (0x00) /**< (HSTDMANXTDSC) Host DMA Channel Next Descriptor Address Register Offset */ + +#define HSTDMANXTDSC_NXT_DSC_ADD_Pos 0 /**< (HSTDMANXTDSC) Next Descriptor Address Position */ +#define HSTDMANXTDSC_NXT_DSC_ADD (_U_(0xFFFFFFFF) << HSTDMANXTDSC_NXT_DSC_ADD_Pos) /**< (HSTDMANXTDSC) Next Descriptor Address Mask */ +#define HSTDMANXTDSC_Msk _U_(0xFFFFFFFF) /**< (HSTDMANXTDSC) Register Mask */ + + +/* -------- HSTDMAADDRESS : (USBHS Offset: 0x04) (R/W 32) Host DMA Channel Address Register -------- */ + +#define HSTDMAADDRESS_OFFSET (0x04) /**< (HSTDMAADDRESS) Host DMA Channel Address Register Offset */ + +#define HSTDMAADDRESS_BUFF_ADD_Pos 0 /**< (HSTDMAADDRESS) Buffer Address Position */ +#define HSTDMAADDRESS_BUFF_ADD (_U_(0xFFFFFFFF) << HSTDMAADDRESS_BUFF_ADD_Pos) /**< (HSTDMAADDRESS) Buffer Address Mask */ +#define HSTDMAADDRESS_Msk _U_(0xFFFFFFFF) /**< (HSTDMAADDRESS) Register Mask */ + + +/* -------- HSTDMACONTROL : (USBHS Offset: 0x08) (R/W 32) Host DMA Channel Control Register -------- */ + +#define HSTDMACONTROL_OFFSET (0x08) /**< (HSTDMACONTROL) Host DMA Channel Control Register Offset */ + +#define HSTDMACONTROL_CHANN_ENB_Pos 0 /**< (HSTDMACONTROL) Channel Enable Command Position */ +#define HSTDMACONTROL_CHANN_ENB (_U_(0x1) << HSTDMACONTROL_CHANN_ENB_Pos) /**< (HSTDMACONTROL) Channel Enable Command Mask */ +#define HSTDMACONTROL_LDNXT_DSC_Pos 1 /**< (HSTDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Position */ +#define HSTDMACONTROL_LDNXT_DSC (_U_(0x1) << HSTDMACONTROL_LDNXT_DSC_Pos) /**< (HSTDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Mask */ +#define HSTDMACONTROL_END_TR_EN_Pos 2 /**< (HSTDMACONTROL) End of Transfer Enable Control (OUT transfers only) Position */ +#define HSTDMACONTROL_END_TR_EN (_U_(0x1) << HSTDMACONTROL_END_TR_EN_Pos) /**< (HSTDMACONTROL) End of Transfer Enable Control (OUT transfers only) Mask */ +#define HSTDMACONTROL_END_B_EN_Pos 3 /**< (HSTDMACONTROL) End of Buffer Enable Control Position */ +#define HSTDMACONTROL_END_B_EN (_U_(0x1) << HSTDMACONTROL_END_B_EN_Pos) /**< (HSTDMACONTROL) End of Buffer Enable Control Mask */ +#define HSTDMACONTROL_END_TR_IT_Pos 4 /**< (HSTDMACONTROL) End of Transfer Interrupt Enable Position */ +#define HSTDMACONTROL_END_TR_IT (_U_(0x1) << HSTDMACONTROL_END_TR_IT_Pos) /**< (HSTDMACONTROL) End of Transfer Interrupt Enable Mask */ +#define HSTDMACONTROL_END_BUFFIT_Pos 5 /**< (HSTDMACONTROL) End of Buffer Interrupt Enable Position */ +#define HSTDMACONTROL_END_BUFFIT (_U_(0x1) << HSTDMACONTROL_END_BUFFIT_Pos) /**< (HSTDMACONTROL) End of Buffer Interrupt Enable Mask */ +#define HSTDMACONTROL_DESC_LD_IT_Pos 6 /**< (HSTDMACONTROL) Descriptor Loaded Interrupt Enable Position */ +#define HSTDMACONTROL_DESC_LD_IT (_U_(0x1) << HSTDMACONTROL_DESC_LD_IT_Pos) /**< (HSTDMACONTROL) Descriptor Loaded Interrupt Enable Mask */ +#define HSTDMACONTROL_BURST_LCK_Pos 7 /**< (HSTDMACONTROL) Burst Lock Enable Position */ +#define HSTDMACONTROL_BURST_LCK (_U_(0x1) << HSTDMACONTROL_BURST_LCK_Pos) /**< (HSTDMACONTROL) Burst Lock Enable Mask */ +#define HSTDMACONTROL_BUFF_LENGTH_Pos 16 /**< (HSTDMACONTROL) Buffer Byte Length (Write-only) Position */ +#define HSTDMACONTROL_BUFF_LENGTH (_U_(0xFFFF) << HSTDMACONTROL_BUFF_LENGTH_Pos) /**< (HSTDMACONTROL) Buffer Byte Length (Write-only) Mask */ +#define HSTDMACONTROL_Msk _U_(0xFFFF00FF) /**< (HSTDMACONTROL) Register Mask */ + + +/* -------- HSTDMASTATUS : (USBHS Offset: 0x0c) (R/W 32) Host DMA Channel Status Register -------- */ + +#define HSTDMASTATUS_OFFSET (0x0C) /**< (HSTDMASTATUS) Host DMA Channel Status Register Offset */ + +#define HSTDMASTATUS_CHANN_ENB_Pos 0 /**< (HSTDMASTATUS) Channel Enable Status Position */ +#define HSTDMASTATUS_CHANN_ENB (_U_(0x1) << HSTDMASTATUS_CHANN_ENB_Pos) /**< (HSTDMASTATUS) Channel Enable Status Mask */ +#define HSTDMASTATUS_CHANN_ACT_Pos 1 /**< (HSTDMASTATUS) Channel Active Status Position */ +#define HSTDMASTATUS_CHANN_ACT (_U_(0x1) << HSTDMASTATUS_CHANN_ACT_Pos) /**< (HSTDMASTATUS) Channel Active Status Mask */ +#define HSTDMASTATUS_END_TR_ST_Pos 4 /**< (HSTDMASTATUS) End of Channel Transfer Status Position */ +#define HSTDMASTATUS_END_TR_ST (_U_(0x1) << HSTDMASTATUS_END_TR_ST_Pos) /**< (HSTDMASTATUS) End of Channel Transfer Status Mask */ +#define HSTDMASTATUS_END_BF_ST_Pos 5 /**< (HSTDMASTATUS) End of Channel Buffer Status Position */ +#define HSTDMASTATUS_END_BF_ST (_U_(0x1) << HSTDMASTATUS_END_BF_ST_Pos) /**< (HSTDMASTATUS) End of Channel Buffer Status Mask */ +#define HSTDMASTATUS_DESC_LDST_Pos 6 /**< (HSTDMASTATUS) Descriptor Loaded Status Position */ +#define HSTDMASTATUS_DESC_LDST (_U_(0x1) << HSTDMASTATUS_DESC_LDST_Pos) /**< (HSTDMASTATUS) Descriptor Loaded Status Mask */ +#define HSTDMASTATUS_BUFF_COUNT_Pos 16 /**< (HSTDMASTATUS) Buffer Byte Count Position */ +#define HSTDMASTATUS_BUFF_COUNT (_U_(0xFFFF) << HSTDMASTATUS_BUFF_COUNT_Pos) /**< (HSTDMASTATUS) Buffer Byte Count Mask */ +#define HSTDMASTATUS_Msk _U_(0xFFFF0073) /**< (HSTDMASTATUS) Register Mask */ + + +/* -------- DEVCTRL : (USBHS Offset: 0x00) (R/W 32) Device General Control Register -------- */ + +#define DEVCTRL_OFFSET (0x00) /**< (DEVCTRL) Device General Control Register Offset */ + +#define DEVCTRL_UADD_Pos 0 /**< (DEVCTRL) USB Address Position */ +#define DEVCTRL_UADD (_U_(0x7F) << DEVCTRL_UADD_Pos) /**< (DEVCTRL) USB Address Mask */ +#define DEVCTRL_ADDEN_Pos 7 /**< (DEVCTRL) Address Enable Position */ +#define DEVCTRL_ADDEN (_U_(0x1) << DEVCTRL_ADDEN_Pos) /**< (DEVCTRL) Address Enable Mask */ +#define DEVCTRL_DETACH_Pos 8 /**< (DEVCTRL) Detach Position */ +#define DEVCTRL_DETACH (_U_(0x1) << DEVCTRL_DETACH_Pos) /**< (DEVCTRL) Detach Mask */ +#define DEVCTRL_RMWKUP_Pos 9 /**< (DEVCTRL) Remote Wake-Up Position */ +#define DEVCTRL_RMWKUP (_U_(0x1) << DEVCTRL_RMWKUP_Pos) /**< (DEVCTRL) Remote Wake-Up Mask */ +#define DEVCTRL_SPDCONF_Pos 10 /**< (DEVCTRL) Mode Configuration Position */ +#define DEVCTRL_SPDCONF (_U_(0x3) << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) Mode Configuration Mask */ +#define DEVCTRL_SPDCONF_NORMAL_Val _U_(0x0) /**< (DEVCTRL) The peripheral starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the host is high-speed-capable. */ +#define DEVCTRL_SPDCONF_LOW_POWER_Val _U_(0x1) /**< (DEVCTRL) For a better consumption, if high speed is not needed. */ +#define DEVCTRL_SPDCONF_HIGH_SPEED_Val _U_(0x2) /**< (DEVCTRL) Forced high speed. */ +#define DEVCTRL_SPDCONF_FORCED_FS_Val _U_(0x3) /**< (DEVCTRL) The peripheral remains in Full-speed mode whatever the host speed capability. */ +#define DEVCTRL_SPDCONF_NORMAL (DEVCTRL_SPDCONF_NORMAL_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) The peripheral starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the host is high-speed-capable. Position */ +#define DEVCTRL_SPDCONF_LOW_POWER (DEVCTRL_SPDCONF_LOW_POWER_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) For a better consumption, if high speed is not needed. Position */ +#define DEVCTRL_SPDCONF_HIGH_SPEED (DEVCTRL_SPDCONF_HIGH_SPEED_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) Forced high speed. Position */ +#define DEVCTRL_SPDCONF_FORCED_FS (DEVCTRL_SPDCONF_FORCED_FS_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) The peripheral remains in Full-speed mode whatever the host speed capability. Position */ +#define DEVCTRL_LS_Pos 12 /**< (DEVCTRL) Low-Speed Mode Force Position */ +#define DEVCTRL_LS (_U_(0x1) << DEVCTRL_LS_Pos) /**< (DEVCTRL) Low-Speed Mode Force Mask */ +#define DEVCTRL_TSTJ_Pos 13 /**< (DEVCTRL) Test mode J Position */ +#define DEVCTRL_TSTJ (_U_(0x1) << DEVCTRL_TSTJ_Pos) /**< (DEVCTRL) Test mode J Mask */ +#define DEVCTRL_TSTK_Pos 14 /**< (DEVCTRL) Test mode K Position */ +#define DEVCTRL_TSTK (_U_(0x1) << DEVCTRL_TSTK_Pos) /**< (DEVCTRL) Test mode K Mask */ +#define DEVCTRL_TSTPCKT_Pos 15 /**< (DEVCTRL) Test packet mode Position */ +#define DEVCTRL_TSTPCKT (_U_(0x1) << DEVCTRL_TSTPCKT_Pos) /**< (DEVCTRL) Test packet mode Mask */ +#define DEVCTRL_OPMODE2_Pos 16 /**< (DEVCTRL) Specific Operational mode Position */ +#define DEVCTRL_OPMODE2 (_U_(0x1) << DEVCTRL_OPMODE2_Pos) /**< (DEVCTRL) Specific Operational mode Mask */ +#define DEVCTRL_Msk _U_(0x1FFFF) /**< (DEVCTRL) Register Mask */ + +#define DEVCTRL_OPMODE_Pos 16 /**< (DEVCTRL Position) Specific Operational mode */ +#define DEVCTRL_OPMODE (_U_(0x1) << DEVCTRL_OPMODE_Pos) /**< (DEVCTRL Mask) OPMODE */ + +/* -------- DEVISR : (USBHS Offset: 0x04) (R/ 32) Device Global Interrupt Status Register -------- */ + +#define DEVISR_OFFSET (0x04) /**< (DEVISR) Device Global Interrupt Status Register Offset */ + +#define DEVISR_SUSP_Pos 0 /**< (DEVISR) Suspend Interrupt Position */ +#define DEVISR_SUSP (_U_(0x1) << DEVISR_SUSP_Pos) /**< (DEVISR) Suspend Interrupt Mask */ +#define DEVISR_MSOF_Pos 1 /**< (DEVISR) Micro Start of Frame Interrupt Position */ +#define DEVISR_MSOF (_U_(0x1) << DEVISR_MSOF_Pos) /**< (DEVISR) Micro Start of Frame Interrupt Mask */ +#define DEVISR_SOF_Pos 2 /**< (DEVISR) Start of Frame Interrupt Position */ +#define DEVISR_SOF (_U_(0x1) << DEVISR_SOF_Pos) /**< (DEVISR) Start of Frame Interrupt Mask */ +#define DEVISR_EORST_Pos 3 /**< (DEVISR) End of Reset Interrupt Position */ +#define DEVISR_EORST (_U_(0x1) << DEVISR_EORST_Pos) /**< (DEVISR) End of Reset Interrupt Mask */ +#define DEVISR_WAKEUP_Pos 4 /**< (DEVISR) Wake-Up Interrupt Position */ +#define DEVISR_WAKEUP (_U_(0x1) << DEVISR_WAKEUP_Pos) /**< (DEVISR) Wake-Up Interrupt Mask */ +#define DEVISR_EORSM_Pos 5 /**< (DEVISR) End of Resume Interrupt Position */ +#define DEVISR_EORSM (_U_(0x1) << DEVISR_EORSM_Pos) /**< (DEVISR) End of Resume Interrupt Mask */ +#define DEVISR_UPRSM_Pos 6 /**< (DEVISR) Upstream Resume Interrupt Position */ +#define DEVISR_UPRSM (_U_(0x1) << DEVISR_UPRSM_Pos) /**< (DEVISR) Upstream Resume Interrupt Mask */ +#define DEVISR_PEP_0_Pos 12 /**< (DEVISR) Endpoint 0 Interrupt Position */ +#define DEVISR_PEP_0 (_U_(0x1) << DEVISR_PEP_0_Pos) /**< (DEVISR) Endpoint 0 Interrupt Mask */ +#define DEVISR_PEP_1_Pos 13 /**< (DEVISR) Endpoint 1 Interrupt Position */ +#define DEVISR_PEP_1 (_U_(0x1) << DEVISR_PEP_1_Pos) /**< (DEVISR) Endpoint 1 Interrupt Mask */ +#define DEVISR_PEP_2_Pos 14 /**< (DEVISR) Endpoint 2 Interrupt Position */ +#define DEVISR_PEP_2 (_U_(0x1) << DEVISR_PEP_2_Pos) /**< (DEVISR) Endpoint 2 Interrupt Mask */ +#define DEVISR_PEP_3_Pos 15 /**< (DEVISR) Endpoint 3 Interrupt Position */ +#define DEVISR_PEP_3 (_U_(0x1) << DEVISR_PEP_3_Pos) /**< (DEVISR) Endpoint 3 Interrupt Mask */ +#define DEVISR_PEP_4_Pos 16 /**< (DEVISR) Endpoint 4 Interrupt Position */ +#define DEVISR_PEP_4 (_U_(0x1) << DEVISR_PEP_4_Pos) /**< (DEVISR) Endpoint 4 Interrupt Mask */ +#define DEVISR_PEP_5_Pos 17 /**< (DEVISR) Endpoint 5 Interrupt Position */ +#define DEVISR_PEP_5 (_U_(0x1) << DEVISR_PEP_5_Pos) /**< (DEVISR) Endpoint 5 Interrupt Mask */ +#define DEVISR_PEP_6_Pos 18 /**< (DEVISR) Endpoint 6 Interrupt Position */ +#define DEVISR_PEP_6 (_U_(0x1) << DEVISR_PEP_6_Pos) /**< (DEVISR) Endpoint 6 Interrupt Mask */ +#define DEVISR_PEP_7_Pos 19 /**< (DEVISR) Endpoint 7 Interrupt Position */ +#define DEVISR_PEP_7 (_U_(0x1) << DEVISR_PEP_7_Pos) /**< (DEVISR) Endpoint 7 Interrupt Mask */ +#define DEVISR_PEP_8_Pos 20 /**< (DEVISR) Endpoint 8 Interrupt Position */ +#define DEVISR_PEP_8 (_U_(0x1) << DEVISR_PEP_8_Pos) /**< (DEVISR) Endpoint 8 Interrupt Mask */ +#define DEVISR_PEP_9_Pos 21 /**< (DEVISR) Endpoint 9 Interrupt Position */ +#define DEVISR_PEP_9 (_U_(0x1) << DEVISR_PEP_9_Pos) /**< (DEVISR) Endpoint 9 Interrupt Mask */ +#define DEVISR_DMA_1_Pos 25 /**< (DEVISR) DMA Channel 1 Interrupt Position */ +#define DEVISR_DMA_1 (_U_(0x1) << DEVISR_DMA_1_Pos) /**< (DEVISR) DMA Channel 1 Interrupt Mask */ +#define DEVISR_DMA_2_Pos 26 /**< (DEVISR) DMA Channel 2 Interrupt Position */ +#define DEVISR_DMA_2 (_U_(0x1) << DEVISR_DMA_2_Pos) /**< (DEVISR) DMA Channel 2 Interrupt Mask */ +#define DEVISR_DMA_3_Pos 27 /**< (DEVISR) DMA Channel 3 Interrupt Position */ +#define DEVISR_DMA_3 (_U_(0x1) << DEVISR_DMA_3_Pos) /**< (DEVISR) DMA Channel 3 Interrupt Mask */ +#define DEVISR_DMA_4_Pos 28 /**< (DEVISR) DMA Channel 4 Interrupt Position */ +#define DEVISR_DMA_4 (_U_(0x1) << DEVISR_DMA_4_Pos) /**< (DEVISR) DMA Channel 4 Interrupt Mask */ +#define DEVISR_DMA_5_Pos 29 /**< (DEVISR) DMA Channel 5 Interrupt Position */ +#define DEVISR_DMA_5 (_U_(0x1) << DEVISR_DMA_5_Pos) /**< (DEVISR) DMA Channel 5 Interrupt Mask */ +#define DEVISR_DMA_6_Pos 30 /**< (DEVISR) DMA Channel 6 Interrupt Position */ +#define DEVISR_DMA_6 (_U_(0x1) << DEVISR_DMA_6_Pos) /**< (DEVISR) DMA Channel 6 Interrupt Mask */ +#define DEVISR_DMA_7_Pos 31 /**< (DEVISR) DMA Channel 7 Interrupt Position */ +#define DEVISR_DMA_7 (_U_(0x1) << DEVISR_DMA_7_Pos) /**< (DEVISR) DMA Channel 7 Interrupt Mask */ +#define DEVISR_Msk _U_(0xFE3FF07F) /**< (DEVISR) Register Mask */ + +#define DEVISR_PEP__Pos 12 /**< (DEVISR Position) Endpoint x Interrupt */ +#define DEVISR_PEP_ (_U_(0x3FF) << DEVISR_PEP__Pos) /**< (DEVISR Mask) PEP_ */ +#define DEVISR_DMA__Pos 25 /**< (DEVISR Position) DMA Channel 7 Interrupt */ +#define DEVISR_DMA_ (_U_(0x7F) << DEVISR_DMA__Pos) /**< (DEVISR Mask) DMA_ */ + +/* -------- DEVICR : (USBHS Offset: 0x08) (/W 32) Device Global Interrupt Clear Register -------- */ + +#define DEVICR_OFFSET (0x08) /**< (DEVICR) Device Global Interrupt Clear Register Offset */ + +#define DEVICR_SUSPC_Pos 0 /**< (DEVICR) Suspend Interrupt Clear Position */ +#define DEVICR_SUSPC (_U_(0x1) << DEVICR_SUSPC_Pos) /**< (DEVICR) Suspend Interrupt Clear Mask */ +#define DEVICR_MSOFC_Pos 1 /**< (DEVICR) Micro Start of Frame Interrupt Clear Position */ +#define DEVICR_MSOFC (_U_(0x1) << DEVICR_MSOFC_Pos) /**< (DEVICR) Micro Start of Frame Interrupt Clear Mask */ +#define DEVICR_SOFC_Pos 2 /**< (DEVICR) Start of Frame Interrupt Clear Position */ +#define DEVICR_SOFC (_U_(0x1) << DEVICR_SOFC_Pos) /**< (DEVICR) Start of Frame Interrupt Clear Mask */ +#define DEVICR_EORSTC_Pos 3 /**< (DEVICR) End of Reset Interrupt Clear Position */ +#define DEVICR_EORSTC (_U_(0x1) << DEVICR_EORSTC_Pos) /**< (DEVICR) End of Reset Interrupt Clear Mask */ +#define DEVICR_WAKEUPC_Pos 4 /**< (DEVICR) Wake-Up Interrupt Clear Position */ +#define DEVICR_WAKEUPC (_U_(0x1) << DEVICR_WAKEUPC_Pos) /**< (DEVICR) Wake-Up Interrupt Clear Mask */ +#define DEVICR_EORSMC_Pos 5 /**< (DEVICR) End of Resume Interrupt Clear Position */ +#define DEVICR_EORSMC (_U_(0x1) << DEVICR_EORSMC_Pos) /**< (DEVICR) End of Resume Interrupt Clear Mask */ +#define DEVICR_UPRSMC_Pos 6 /**< (DEVICR) Upstream Resume Interrupt Clear Position */ +#define DEVICR_UPRSMC (_U_(0x1) << DEVICR_UPRSMC_Pos) /**< (DEVICR) Upstream Resume Interrupt Clear Mask */ +#define DEVICR_Msk _U_(0x7F) /**< (DEVICR) Register Mask */ + + +/* -------- DEVIFR : (USBHS Offset: 0x0c) (/W 32) Device Global Interrupt Set Register -------- */ + +#define DEVIFR_OFFSET (0x0C) /**< (DEVIFR) Device Global Interrupt Set Register Offset */ + +#define DEVIFR_SUSPS_Pos 0 /**< (DEVIFR) Suspend Interrupt Set Position */ +#define DEVIFR_SUSPS (_U_(0x1) << DEVIFR_SUSPS_Pos) /**< (DEVIFR) Suspend Interrupt Set Mask */ +#define DEVIFR_MSOFS_Pos 1 /**< (DEVIFR) Micro Start of Frame Interrupt Set Position */ +#define DEVIFR_MSOFS (_U_(0x1) << DEVIFR_MSOFS_Pos) /**< (DEVIFR) Micro Start of Frame Interrupt Set Mask */ +#define DEVIFR_SOFS_Pos 2 /**< (DEVIFR) Start of Frame Interrupt Set Position */ +#define DEVIFR_SOFS (_U_(0x1) << DEVIFR_SOFS_Pos) /**< (DEVIFR) Start of Frame Interrupt Set Mask */ +#define DEVIFR_EORSTS_Pos 3 /**< (DEVIFR) End of Reset Interrupt Set Position */ +#define DEVIFR_EORSTS (_U_(0x1) << DEVIFR_EORSTS_Pos) /**< (DEVIFR) End of Reset Interrupt Set Mask */ +#define DEVIFR_WAKEUPS_Pos 4 /**< (DEVIFR) Wake-Up Interrupt Set Position */ +#define DEVIFR_WAKEUPS (_U_(0x1) << DEVIFR_WAKEUPS_Pos) /**< (DEVIFR) Wake-Up Interrupt Set Mask */ +#define DEVIFR_EORSMS_Pos 5 /**< (DEVIFR) End of Resume Interrupt Set Position */ +#define DEVIFR_EORSMS (_U_(0x1) << DEVIFR_EORSMS_Pos) /**< (DEVIFR) End of Resume Interrupt Set Mask */ +#define DEVIFR_UPRSMS_Pos 6 /**< (DEVIFR) Upstream Resume Interrupt Set Position */ +#define DEVIFR_UPRSMS (_U_(0x1) << DEVIFR_UPRSMS_Pos) /**< (DEVIFR) Upstream Resume Interrupt Set Mask */ +#define DEVIFR_DMA_1_Pos 25 /**< (DEVIFR) DMA Channel 1 Interrupt Set Position */ +#define DEVIFR_DMA_1 (_U_(0x1) << DEVIFR_DMA_1_Pos) /**< (DEVIFR) DMA Channel 1 Interrupt Set Mask */ +#define DEVIFR_DMA_2_Pos 26 /**< (DEVIFR) DMA Channel 2 Interrupt Set Position */ +#define DEVIFR_DMA_2 (_U_(0x1) << DEVIFR_DMA_2_Pos) /**< (DEVIFR) DMA Channel 2 Interrupt Set Mask */ +#define DEVIFR_DMA_3_Pos 27 /**< (DEVIFR) DMA Channel 3 Interrupt Set Position */ +#define DEVIFR_DMA_3 (_U_(0x1) << DEVIFR_DMA_3_Pos) /**< (DEVIFR) DMA Channel 3 Interrupt Set Mask */ +#define DEVIFR_DMA_4_Pos 28 /**< (DEVIFR) DMA Channel 4 Interrupt Set Position */ +#define DEVIFR_DMA_4 (_U_(0x1) << DEVIFR_DMA_4_Pos) /**< (DEVIFR) DMA Channel 4 Interrupt Set Mask */ +#define DEVIFR_DMA_5_Pos 29 /**< (DEVIFR) DMA Channel 5 Interrupt Set Position */ +#define DEVIFR_DMA_5 (_U_(0x1) << DEVIFR_DMA_5_Pos) /**< (DEVIFR) DMA Channel 5 Interrupt Set Mask */ +#define DEVIFR_DMA_6_Pos 30 /**< (DEVIFR) DMA Channel 6 Interrupt Set Position */ +#define DEVIFR_DMA_6 (_U_(0x1) << DEVIFR_DMA_6_Pos) /**< (DEVIFR) DMA Channel 6 Interrupt Set Mask */ +#define DEVIFR_DMA_7_Pos 31 /**< (DEVIFR) DMA Channel 7 Interrupt Set Position */ +#define DEVIFR_DMA_7 (_U_(0x1) << DEVIFR_DMA_7_Pos) /**< (DEVIFR) DMA Channel 7 Interrupt Set Mask */ +#define DEVIFR_Msk _U_(0xFE00007F) /**< (DEVIFR) Register Mask */ + +#define DEVIFR_DMA__Pos 25 /**< (DEVIFR Position) DMA Channel 7 Interrupt Set */ +#define DEVIFR_DMA_ (_U_(0x7F) << DEVIFR_DMA__Pos) /**< (DEVIFR Mask) DMA_ */ + +/* -------- DEVIMR : (USBHS Offset: 0x10) (R/ 32) Device Global Interrupt Mask Register -------- */ + +#define DEVIMR_OFFSET (0x10) /**< (DEVIMR) Device Global Interrupt Mask Register Offset */ + +#define DEVIMR_SUSPE_Pos 0 /**< (DEVIMR) Suspend Interrupt Mask Position */ +#define DEVIMR_SUSPE (_U_(0x1) << DEVIMR_SUSPE_Pos) /**< (DEVIMR) Suspend Interrupt Mask Mask */ +#define DEVIMR_MSOFE_Pos 1 /**< (DEVIMR) Micro Start of Frame Interrupt Mask Position */ +#define DEVIMR_MSOFE (_U_(0x1) << DEVIMR_MSOFE_Pos) /**< (DEVIMR) Micro Start of Frame Interrupt Mask Mask */ +#define DEVIMR_SOFE_Pos 2 /**< (DEVIMR) Start of Frame Interrupt Mask Position */ +#define DEVIMR_SOFE (_U_(0x1) << DEVIMR_SOFE_Pos) /**< (DEVIMR) Start of Frame Interrupt Mask Mask */ +#define DEVIMR_EORSTE_Pos 3 /**< (DEVIMR) End of Reset Interrupt Mask Position */ +#define DEVIMR_EORSTE (_U_(0x1) << DEVIMR_EORSTE_Pos) /**< (DEVIMR) End of Reset Interrupt Mask Mask */ +#define DEVIMR_WAKEUPE_Pos 4 /**< (DEVIMR) Wake-Up Interrupt Mask Position */ +#define DEVIMR_WAKEUPE (_U_(0x1) << DEVIMR_WAKEUPE_Pos) /**< (DEVIMR) Wake-Up Interrupt Mask Mask */ +#define DEVIMR_EORSME_Pos 5 /**< (DEVIMR) End of Resume Interrupt Mask Position */ +#define DEVIMR_EORSME (_U_(0x1) << DEVIMR_EORSME_Pos) /**< (DEVIMR) End of Resume Interrupt Mask Mask */ +#define DEVIMR_UPRSME_Pos 6 /**< (DEVIMR) Upstream Resume Interrupt Mask Position */ +#define DEVIMR_UPRSME (_U_(0x1) << DEVIMR_UPRSME_Pos) /**< (DEVIMR) Upstream Resume Interrupt Mask Mask */ +#define DEVIMR_PEP_0_Pos 12 /**< (DEVIMR) Endpoint 0 Interrupt Mask Position */ +#define DEVIMR_PEP_0 (_U_(0x1) << DEVIMR_PEP_0_Pos) /**< (DEVIMR) Endpoint 0 Interrupt Mask Mask */ +#define DEVIMR_PEP_1_Pos 13 /**< (DEVIMR) Endpoint 1 Interrupt Mask Position */ +#define DEVIMR_PEP_1 (_U_(0x1) << DEVIMR_PEP_1_Pos) /**< (DEVIMR) Endpoint 1 Interrupt Mask Mask */ +#define DEVIMR_PEP_2_Pos 14 /**< (DEVIMR) Endpoint 2 Interrupt Mask Position */ +#define DEVIMR_PEP_2 (_U_(0x1) << DEVIMR_PEP_2_Pos) /**< (DEVIMR) Endpoint 2 Interrupt Mask Mask */ +#define DEVIMR_PEP_3_Pos 15 /**< (DEVIMR) Endpoint 3 Interrupt Mask Position */ +#define DEVIMR_PEP_3 (_U_(0x1) << DEVIMR_PEP_3_Pos) /**< (DEVIMR) Endpoint 3 Interrupt Mask Mask */ +#define DEVIMR_PEP_4_Pos 16 /**< (DEVIMR) Endpoint 4 Interrupt Mask Position */ +#define DEVIMR_PEP_4 (_U_(0x1) << DEVIMR_PEP_4_Pos) /**< (DEVIMR) Endpoint 4 Interrupt Mask Mask */ +#define DEVIMR_PEP_5_Pos 17 /**< (DEVIMR) Endpoint 5 Interrupt Mask Position */ +#define DEVIMR_PEP_5 (_U_(0x1) << DEVIMR_PEP_5_Pos) /**< (DEVIMR) Endpoint 5 Interrupt Mask Mask */ +#define DEVIMR_PEP_6_Pos 18 /**< (DEVIMR) Endpoint 6 Interrupt Mask Position */ +#define DEVIMR_PEP_6 (_U_(0x1) << DEVIMR_PEP_6_Pos) /**< (DEVIMR) Endpoint 6 Interrupt Mask Mask */ +#define DEVIMR_PEP_7_Pos 19 /**< (DEVIMR) Endpoint 7 Interrupt Mask Position */ +#define DEVIMR_PEP_7 (_U_(0x1) << DEVIMR_PEP_7_Pos) /**< (DEVIMR) Endpoint 7 Interrupt Mask Mask */ +#define DEVIMR_PEP_8_Pos 20 /**< (DEVIMR) Endpoint 8 Interrupt Mask Position */ +#define DEVIMR_PEP_8 (_U_(0x1) << DEVIMR_PEP_8_Pos) /**< (DEVIMR) Endpoint 8 Interrupt Mask Mask */ +#define DEVIMR_PEP_9_Pos 21 /**< (DEVIMR) Endpoint 9 Interrupt Mask Position */ +#define DEVIMR_PEP_9 (_U_(0x1) << DEVIMR_PEP_9_Pos) /**< (DEVIMR) Endpoint 9 Interrupt Mask Mask */ +#define DEVIMR_DMA_1_Pos 25 /**< (DEVIMR) DMA Channel 1 Interrupt Mask Position */ +#define DEVIMR_DMA_1 (_U_(0x1) << DEVIMR_DMA_1_Pos) /**< (DEVIMR) DMA Channel 1 Interrupt Mask Mask */ +#define DEVIMR_DMA_2_Pos 26 /**< (DEVIMR) DMA Channel 2 Interrupt Mask Position */ +#define DEVIMR_DMA_2 (_U_(0x1) << DEVIMR_DMA_2_Pos) /**< (DEVIMR) DMA Channel 2 Interrupt Mask Mask */ +#define DEVIMR_DMA_3_Pos 27 /**< (DEVIMR) DMA Channel 3 Interrupt Mask Position */ +#define DEVIMR_DMA_3 (_U_(0x1) << DEVIMR_DMA_3_Pos) /**< (DEVIMR) DMA Channel 3 Interrupt Mask Mask */ +#define DEVIMR_DMA_4_Pos 28 /**< (DEVIMR) DMA Channel 4 Interrupt Mask Position */ +#define DEVIMR_DMA_4 (_U_(0x1) << DEVIMR_DMA_4_Pos) /**< (DEVIMR) DMA Channel 4 Interrupt Mask Mask */ +#define DEVIMR_DMA_5_Pos 29 /**< (DEVIMR) DMA Channel 5 Interrupt Mask Position */ +#define DEVIMR_DMA_5 (_U_(0x1) << DEVIMR_DMA_5_Pos) /**< (DEVIMR) DMA Channel 5 Interrupt Mask Mask */ +#define DEVIMR_DMA_6_Pos 30 /**< (DEVIMR) DMA Channel 6 Interrupt Mask Position */ +#define DEVIMR_DMA_6 (_U_(0x1) << DEVIMR_DMA_6_Pos) /**< (DEVIMR) DMA Channel 6 Interrupt Mask Mask */ +#define DEVIMR_DMA_7_Pos 31 /**< (DEVIMR) DMA Channel 7 Interrupt Mask Position */ +#define DEVIMR_DMA_7 (_U_(0x1) << DEVIMR_DMA_7_Pos) /**< (DEVIMR) DMA Channel 7 Interrupt Mask Mask */ +#define DEVIMR_Msk _U_(0xFE3FF07F) /**< (DEVIMR) Register Mask */ + +#define DEVIMR_PEP__Pos 12 /**< (DEVIMR Position) Endpoint x Interrupt Mask */ +#define DEVIMR_PEP_ (_U_(0x3FF) << DEVIMR_PEP__Pos) /**< (DEVIMR Mask) PEP_ */ +#define DEVIMR_DMA__Pos 25 /**< (DEVIMR Position) DMA Channel 7 Interrupt Mask */ +#define DEVIMR_DMA_ (_U_(0x7F) << DEVIMR_DMA__Pos) /**< (DEVIMR Mask) DMA_ */ + +/* -------- DEVIDR : (USBHS Offset: 0x14) (/W 32) Device Global Interrupt Disable Register -------- */ + +#define DEVIDR_OFFSET (0x14) /**< (DEVIDR) Device Global Interrupt Disable Register Offset */ + +#define DEVIDR_SUSPEC_Pos 0 /**< (DEVIDR) Suspend Interrupt Disable Position */ +#define DEVIDR_SUSPEC (_U_(0x1) << DEVIDR_SUSPEC_Pos) /**< (DEVIDR) Suspend Interrupt Disable Mask */ +#define DEVIDR_MSOFEC_Pos 1 /**< (DEVIDR) Micro Start of Frame Interrupt Disable Position */ +#define DEVIDR_MSOFEC (_U_(0x1) << DEVIDR_MSOFEC_Pos) /**< (DEVIDR) Micro Start of Frame Interrupt Disable Mask */ +#define DEVIDR_SOFEC_Pos 2 /**< (DEVIDR) Start of Frame Interrupt Disable Position */ +#define DEVIDR_SOFEC (_U_(0x1) << DEVIDR_SOFEC_Pos) /**< (DEVIDR) Start of Frame Interrupt Disable Mask */ +#define DEVIDR_EORSTEC_Pos 3 /**< (DEVIDR) End of Reset Interrupt Disable Position */ +#define DEVIDR_EORSTEC (_U_(0x1) << DEVIDR_EORSTEC_Pos) /**< (DEVIDR) End of Reset Interrupt Disable Mask */ +#define DEVIDR_WAKEUPEC_Pos 4 /**< (DEVIDR) Wake-Up Interrupt Disable Position */ +#define DEVIDR_WAKEUPEC (_U_(0x1) << DEVIDR_WAKEUPEC_Pos) /**< (DEVIDR) Wake-Up Interrupt Disable Mask */ +#define DEVIDR_EORSMEC_Pos 5 /**< (DEVIDR) End of Resume Interrupt Disable Position */ +#define DEVIDR_EORSMEC (_U_(0x1) << DEVIDR_EORSMEC_Pos) /**< (DEVIDR) End of Resume Interrupt Disable Mask */ +#define DEVIDR_UPRSMEC_Pos 6 /**< (DEVIDR) Upstream Resume Interrupt Disable Position */ +#define DEVIDR_UPRSMEC (_U_(0x1) << DEVIDR_UPRSMEC_Pos) /**< (DEVIDR) Upstream Resume Interrupt Disable Mask */ +#define DEVIDR_PEP_0_Pos 12 /**< (DEVIDR) Endpoint 0 Interrupt Disable Position */ +#define DEVIDR_PEP_0 (_U_(0x1) << DEVIDR_PEP_0_Pos) /**< (DEVIDR) Endpoint 0 Interrupt Disable Mask */ +#define DEVIDR_PEP_1_Pos 13 /**< (DEVIDR) Endpoint 1 Interrupt Disable Position */ +#define DEVIDR_PEP_1 (_U_(0x1) << DEVIDR_PEP_1_Pos) /**< (DEVIDR) Endpoint 1 Interrupt Disable Mask */ +#define DEVIDR_PEP_2_Pos 14 /**< (DEVIDR) Endpoint 2 Interrupt Disable Position */ +#define DEVIDR_PEP_2 (_U_(0x1) << DEVIDR_PEP_2_Pos) /**< (DEVIDR) Endpoint 2 Interrupt Disable Mask */ +#define DEVIDR_PEP_3_Pos 15 /**< (DEVIDR) Endpoint 3 Interrupt Disable Position */ +#define DEVIDR_PEP_3 (_U_(0x1) << DEVIDR_PEP_3_Pos) /**< (DEVIDR) Endpoint 3 Interrupt Disable Mask */ +#define DEVIDR_PEP_4_Pos 16 /**< (DEVIDR) Endpoint 4 Interrupt Disable Position */ +#define DEVIDR_PEP_4 (_U_(0x1) << DEVIDR_PEP_4_Pos) /**< (DEVIDR) Endpoint 4 Interrupt Disable Mask */ +#define DEVIDR_PEP_5_Pos 17 /**< (DEVIDR) Endpoint 5 Interrupt Disable Position */ +#define DEVIDR_PEP_5 (_U_(0x1) << DEVIDR_PEP_5_Pos) /**< (DEVIDR) Endpoint 5 Interrupt Disable Mask */ +#define DEVIDR_PEP_6_Pos 18 /**< (DEVIDR) Endpoint 6 Interrupt Disable Position */ +#define DEVIDR_PEP_6 (_U_(0x1) << DEVIDR_PEP_6_Pos) /**< (DEVIDR) Endpoint 6 Interrupt Disable Mask */ +#define DEVIDR_PEP_7_Pos 19 /**< (DEVIDR) Endpoint 7 Interrupt Disable Position */ +#define DEVIDR_PEP_7 (_U_(0x1) << DEVIDR_PEP_7_Pos) /**< (DEVIDR) Endpoint 7 Interrupt Disable Mask */ +#define DEVIDR_PEP_8_Pos 20 /**< (DEVIDR) Endpoint 8 Interrupt Disable Position */ +#define DEVIDR_PEP_8 (_U_(0x1) << DEVIDR_PEP_8_Pos) /**< (DEVIDR) Endpoint 8 Interrupt Disable Mask */ +#define DEVIDR_PEP_9_Pos 21 /**< (DEVIDR) Endpoint 9 Interrupt Disable Position */ +#define DEVIDR_PEP_9 (_U_(0x1) << DEVIDR_PEP_9_Pos) /**< (DEVIDR) Endpoint 9 Interrupt Disable Mask */ +#define DEVIDR_DMA_1_Pos 25 /**< (DEVIDR) DMA Channel 1 Interrupt Disable Position */ +#define DEVIDR_DMA_1 (_U_(0x1) << DEVIDR_DMA_1_Pos) /**< (DEVIDR) DMA Channel 1 Interrupt Disable Mask */ +#define DEVIDR_DMA_2_Pos 26 /**< (DEVIDR) DMA Channel 2 Interrupt Disable Position */ +#define DEVIDR_DMA_2 (_U_(0x1) << DEVIDR_DMA_2_Pos) /**< (DEVIDR) DMA Channel 2 Interrupt Disable Mask */ +#define DEVIDR_DMA_3_Pos 27 /**< (DEVIDR) DMA Channel 3 Interrupt Disable Position */ +#define DEVIDR_DMA_3 (_U_(0x1) << DEVIDR_DMA_3_Pos) /**< (DEVIDR) DMA Channel 3 Interrupt Disable Mask */ +#define DEVIDR_DMA_4_Pos 28 /**< (DEVIDR) DMA Channel 4 Interrupt Disable Position */ +#define DEVIDR_DMA_4 (_U_(0x1) << DEVIDR_DMA_4_Pos) /**< (DEVIDR) DMA Channel 4 Interrupt Disable Mask */ +#define DEVIDR_DMA_5_Pos 29 /**< (DEVIDR) DMA Channel 5 Interrupt Disable Position */ +#define DEVIDR_DMA_5 (_U_(0x1) << DEVIDR_DMA_5_Pos) /**< (DEVIDR) DMA Channel 5 Interrupt Disable Mask */ +#define DEVIDR_DMA_6_Pos 30 /**< (DEVIDR) DMA Channel 6 Interrupt Disable Position */ +#define DEVIDR_DMA_6 (_U_(0x1) << DEVIDR_DMA_6_Pos) /**< (DEVIDR) DMA Channel 6 Interrupt Disable Mask */ +#define DEVIDR_DMA_7_Pos 31 /**< (DEVIDR) DMA Channel 7 Interrupt Disable Position */ +#define DEVIDR_DMA_7 (_U_(0x1) << DEVIDR_DMA_7_Pos) /**< (DEVIDR) DMA Channel 7 Interrupt Disable Mask */ +#define DEVIDR_Msk _U_(0xFE3FF07F) /**< (DEVIDR) Register Mask */ + +#define DEVIDR_PEP__Pos 12 /**< (DEVIDR Position) Endpoint x Interrupt Disable */ +#define DEVIDR_PEP_ (_U_(0x3FF) << DEVIDR_PEP__Pos) /**< (DEVIDR Mask) PEP_ */ +#define DEVIDR_DMA__Pos 25 /**< (DEVIDR Position) DMA Channel 7 Interrupt Disable */ +#define DEVIDR_DMA_ (_U_(0x7F) << DEVIDR_DMA__Pos) /**< (DEVIDR Mask) DMA_ */ + +/* -------- DEVIER : (USBHS Offset: 0x18) (/W 32) Device Global Interrupt Enable Register -------- */ + +#define DEVIER_OFFSET (0x18) /**< (DEVIER) Device Global Interrupt Enable Register Offset */ + +#define DEVIER_SUSPES_Pos 0 /**< (DEVIER) Suspend Interrupt Enable Position */ +#define DEVIER_SUSPES (_U_(0x1) << DEVIER_SUSPES_Pos) /**< (DEVIER) Suspend Interrupt Enable Mask */ +#define DEVIER_MSOFES_Pos 1 /**< (DEVIER) Micro Start of Frame Interrupt Enable Position */ +#define DEVIER_MSOFES (_U_(0x1) << DEVIER_MSOFES_Pos) /**< (DEVIER) Micro Start of Frame Interrupt Enable Mask */ +#define DEVIER_SOFES_Pos 2 /**< (DEVIER) Start of Frame Interrupt Enable Position */ +#define DEVIER_SOFES (_U_(0x1) << DEVIER_SOFES_Pos) /**< (DEVIER) Start of Frame Interrupt Enable Mask */ +#define DEVIER_EORSTES_Pos 3 /**< (DEVIER) End of Reset Interrupt Enable Position */ +#define DEVIER_EORSTES (_U_(0x1) << DEVIER_EORSTES_Pos) /**< (DEVIER) End of Reset Interrupt Enable Mask */ +#define DEVIER_WAKEUPES_Pos 4 /**< (DEVIER) Wake-Up Interrupt Enable Position */ +#define DEVIER_WAKEUPES (_U_(0x1) << DEVIER_WAKEUPES_Pos) /**< (DEVIER) Wake-Up Interrupt Enable Mask */ +#define DEVIER_EORSMES_Pos 5 /**< (DEVIER) End of Resume Interrupt Enable Position */ +#define DEVIER_EORSMES (_U_(0x1) << DEVIER_EORSMES_Pos) /**< (DEVIER) End of Resume Interrupt Enable Mask */ +#define DEVIER_UPRSMES_Pos 6 /**< (DEVIER) Upstream Resume Interrupt Enable Position */ +#define DEVIER_UPRSMES (_U_(0x1) << DEVIER_UPRSMES_Pos) /**< (DEVIER) Upstream Resume Interrupt Enable Mask */ +#define DEVIER_PEP_0_Pos 12 /**< (DEVIER) Endpoint 0 Interrupt Enable Position */ +#define DEVIER_PEP_0 (_U_(0x1) << DEVIER_PEP_0_Pos) /**< (DEVIER) Endpoint 0 Interrupt Enable Mask */ +#define DEVIER_PEP_1_Pos 13 /**< (DEVIER) Endpoint 1 Interrupt Enable Position */ +#define DEVIER_PEP_1 (_U_(0x1) << DEVIER_PEP_1_Pos) /**< (DEVIER) Endpoint 1 Interrupt Enable Mask */ +#define DEVIER_PEP_2_Pos 14 /**< (DEVIER) Endpoint 2 Interrupt Enable Position */ +#define DEVIER_PEP_2 (_U_(0x1) << DEVIER_PEP_2_Pos) /**< (DEVIER) Endpoint 2 Interrupt Enable Mask */ +#define DEVIER_PEP_3_Pos 15 /**< (DEVIER) Endpoint 3 Interrupt Enable Position */ +#define DEVIER_PEP_3 (_U_(0x1) << DEVIER_PEP_3_Pos) /**< (DEVIER) Endpoint 3 Interrupt Enable Mask */ +#define DEVIER_PEP_4_Pos 16 /**< (DEVIER) Endpoint 4 Interrupt Enable Position */ +#define DEVIER_PEP_4 (_U_(0x1) << DEVIER_PEP_4_Pos) /**< (DEVIER) Endpoint 4 Interrupt Enable Mask */ +#define DEVIER_PEP_5_Pos 17 /**< (DEVIER) Endpoint 5 Interrupt Enable Position */ +#define DEVIER_PEP_5 (_U_(0x1) << DEVIER_PEP_5_Pos) /**< (DEVIER) Endpoint 5 Interrupt Enable Mask */ +#define DEVIER_PEP_6_Pos 18 /**< (DEVIER) Endpoint 6 Interrupt Enable Position */ +#define DEVIER_PEP_6 (_U_(0x1) << DEVIER_PEP_6_Pos) /**< (DEVIER) Endpoint 6 Interrupt Enable Mask */ +#define DEVIER_PEP_7_Pos 19 /**< (DEVIER) Endpoint 7 Interrupt Enable Position */ +#define DEVIER_PEP_7 (_U_(0x1) << DEVIER_PEP_7_Pos) /**< (DEVIER) Endpoint 7 Interrupt Enable Mask */ +#define DEVIER_PEP_8_Pos 20 /**< (DEVIER) Endpoint 8 Interrupt Enable Position */ +#define DEVIER_PEP_8 (_U_(0x1) << DEVIER_PEP_8_Pos) /**< (DEVIER) Endpoint 8 Interrupt Enable Mask */ +#define DEVIER_PEP_9_Pos 21 /**< (DEVIER) Endpoint 9 Interrupt Enable Position */ +#define DEVIER_PEP_9 (_U_(0x1) << DEVIER_PEP_9_Pos) /**< (DEVIER) Endpoint 9 Interrupt Enable Mask */ +#define DEVIER_DMA_1_Pos 25 /**< (DEVIER) DMA Channel 1 Interrupt Enable Position */ +#define DEVIER_DMA_1 (_U_(0x1) << DEVIER_DMA_1_Pos) /**< (DEVIER) DMA Channel 1 Interrupt Enable Mask */ +#define DEVIER_DMA_2_Pos 26 /**< (DEVIER) DMA Channel 2 Interrupt Enable Position */ +#define DEVIER_DMA_2 (_U_(0x1) << DEVIER_DMA_2_Pos) /**< (DEVIER) DMA Channel 2 Interrupt Enable Mask */ +#define DEVIER_DMA_3_Pos 27 /**< (DEVIER) DMA Channel 3 Interrupt Enable Position */ +#define DEVIER_DMA_3 (_U_(0x1) << DEVIER_DMA_3_Pos) /**< (DEVIER) DMA Channel 3 Interrupt Enable Mask */ +#define DEVIER_DMA_4_Pos 28 /**< (DEVIER) DMA Channel 4 Interrupt Enable Position */ +#define DEVIER_DMA_4 (_U_(0x1) << DEVIER_DMA_4_Pos) /**< (DEVIER) DMA Channel 4 Interrupt Enable Mask */ +#define DEVIER_DMA_5_Pos 29 /**< (DEVIER) DMA Channel 5 Interrupt Enable Position */ +#define DEVIER_DMA_5 (_U_(0x1) << DEVIER_DMA_5_Pos) /**< (DEVIER) DMA Channel 5 Interrupt Enable Mask */ +#define DEVIER_DMA_6_Pos 30 /**< (DEVIER) DMA Channel 6 Interrupt Enable Position */ +#define DEVIER_DMA_6 (_U_(0x1) << DEVIER_DMA_6_Pos) /**< (DEVIER) DMA Channel 6 Interrupt Enable Mask */ +#define DEVIER_DMA_7_Pos 31 /**< (DEVIER) DMA Channel 7 Interrupt Enable Position */ +#define DEVIER_DMA_7 (_U_(0x1) << DEVIER_DMA_7_Pos) /**< (DEVIER) DMA Channel 7 Interrupt Enable Mask */ +#define DEVIER_Msk _U_(0xFE3FF07F) /**< (DEVIER) Register Mask */ + +#define DEVIER_PEP__Pos 12 /**< (DEVIER Position) Endpoint x Interrupt Enable */ +#define DEVIER_PEP_ (_U_(0x3FF) << DEVIER_PEP__Pos) /**< (DEVIER Mask) PEP_ */ +#define DEVIER_DMA__Pos 25 /**< (DEVIER Position) DMA Channel 7 Interrupt Enable */ +#define DEVIER_DMA_ (_U_(0x7F) << DEVIER_DMA__Pos) /**< (DEVIER Mask) DMA_ */ + +/* -------- DEVEPT : (USBHS Offset: 0x1c) (R/W 32) Device Endpoint Register -------- */ + +#define DEVEPT_OFFSET (0x1C) /**< (DEVEPT) Device Endpoint Register Offset */ + +#define DEVEPT_EPEN0_Pos 0 /**< (DEVEPT) Endpoint 0 Enable Position */ +#define DEVEPT_EPEN0 (_U_(0x1) << DEVEPT_EPEN0_Pos) /**< (DEVEPT) Endpoint 0 Enable Mask */ +#define DEVEPT_EPEN1_Pos 1 /**< (DEVEPT) Endpoint 1 Enable Position */ +#define DEVEPT_EPEN1 (_U_(0x1) << DEVEPT_EPEN1_Pos) /**< (DEVEPT) Endpoint 1 Enable Mask */ +#define DEVEPT_EPEN2_Pos 2 /**< (DEVEPT) Endpoint 2 Enable Position */ +#define DEVEPT_EPEN2 (_U_(0x1) << DEVEPT_EPEN2_Pos) /**< (DEVEPT) Endpoint 2 Enable Mask */ +#define DEVEPT_EPEN3_Pos 3 /**< (DEVEPT) Endpoint 3 Enable Position */ +#define DEVEPT_EPEN3 (_U_(0x1) << DEVEPT_EPEN3_Pos) /**< (DEVEPT) Endpoint 3 Enable Mask */ +#define DEVEPT_EPEN4_Pos 4 /**< (DEVEPT) Endpoint 4 Enable Position */ +#define DEVEPT_EPEN4 (_U_(0x1) << DEVEPT_EPEN4_Pos) /**< (DEVEPT) Endpoint 4 Enable Mask */ +#define DEVEPT_EPEN5_Pos 5 /**< (DEVEPT) Endpoint 5 Enable Position */ +#define DEVEPT_EPEN5 (_U_(0x1) << DEVEPT_EPEN5_Pos) /**< (DEVEPT) Endpoint 5 Enable Mask */ +#define DEVEPT_EPEN6_Pos 6 /**< (DEVEPT) Endpoint 6 Enable Position */ +#define DEVEPT_EPEN6 (_U_(0x1) << DEVEPT_EPEN6_Pos) /**< (DEVEPT) Endpoint 6 Enable Mask */ +#define DEVEPT_EPEN7_Pos 7 /**< (DEVEPT) Endpoint 7 Enable Position */ +#define DEVEPT_EPEN7 (_U_(0x1) << DEVEPT_EPEN7_Pos) /**< (DEVEPT) Endpoint 7 Enable Mask */ +#define DEVEPT_EPEN8_Pos 8 /**< (DEVEPT) Endpoint 8 Enable Position */ +#define DEVEPT_EPEN8 (_U_(0x1) << DEVEPT_EPEN8_Pos) /**< (DEVEPT) Endpoint 8 Enable Mask */ +#define DEVEPT_EPEN9_Pos 9 /**< (DEVEPT) Endpoint 9 Enable Position */ +#define DEVEPT_EPEN9 (_U_(0x1) << DEVEPT_EPEN9_Pos) /**< (DEVEPT) Endpoint 9 Enable Mask */ +#define DEVEPT_EPRST0_Pos 16 /**< (DEVEPT) Endpoint 0 Reset Position */ +#define DEVEPT_EPRST0 (_U_(0x1) << DEVEPT_EPRST0_Pos) /**< (DEVEPT) Endpoint 0 Reset Mask */ +#define DEVEPT_EPRST1_Pos 17 /**< (DEVEPT) Endpoint 1 Reset Position */ +#define DEVEPT_EPRST1 (_U_(0x1) << DEVEPT_EPRST1_Pos) /**< (DEVEPT) Endpoint 1 Reset Mask */ +#define DEVEPT_EPRST2_Pos 18 /**< (DEVEPT) Endpoint 2 Reset Position */ +#define DEVEPT_EPRST2 (_U_(0x1) << DEVEPT_EPRST2_Pos) /**< (DEVEPT) Endpoint 2 Reset Mask */ +#define DEVEPT_EPRST3_Pos 19 /**< (DEVEPT) Endpoint 3 Reset Position */ +#define DEVEPT_EPRST3 (_U_(0x1) << DEVEPT_EPRST3_Pos) /**< (DEVEPT) Endpoint 3 Reset Mask */ +#define DEVEPT_EPRST4_Pos 20 /**< (DEVEPT) Endpoint 4 Reset Position */ +#define DEVEPT_EPRST4 (_U_(0x1) << DEVEPT_EPRST4_Pos) /**< (DEVEPT) Endpoint 4 Reset Mask */ +#define DEVEPT_EPRST5_Pos 21 /**< (DEVEPT) Endpoint 5 Reset Position */ +#define DEVEPT_EPRST5 (_U_(0x1) << DEVEPT_EPRST5_Pos) /**< (DEVEPT) Endpoint 5 Reset Mask */ +#define DEVEPT_EPRST6_Pos 22 /**< (DEVEPT) Endpoint 6 Reset Position */ +#define DEVEPT_EPRST6 (_U_(0x1) << DEVEPT_EPRST6_Pos) /**< (DEVEPT) Endpoint 6 Reset Mask */ +#define DEVEPT_EPRST7_Pos 23 /**< (DEVEPT) Endpoint 7 Reset Position */ +#define DEVEPT_EPRST7 (_U_(0x1) << DEVEPT_EPRST7_Pos) /**< (DEVEPT) Endpoint 7 Reset Mask */ +#define DEVEPT_EPRST8_Pos 24 /**< (DEVEPT) Endpoint 8 Reset Position */ +#define DEVEPT_EPRST8 (_U_(0x1) << DEVEPT_EPRST8_Pos) /**< (DEVEPT) Endpoint 8 Reset Mask */ +#define DEVEPT_EPRST9_Pos 25 /**< (DEVEPT) Endpoint 9 Reset Position */ +#define DEVEPT_EPRST9 (_U_(0x1) << DEVEPT_EPRST9_Pos) /**< (DEVEPT) Endpoint 9 Reset Mask */ +#define DEVEPT_Msk _U_(0x3FF03FF) /**< (DEVEPT) Register Mask */ + +#define DEVEPT_EPEN_Pos 0 /**< (DEVEPT Position) Endpoint x Enable */ +#define DEVEPT_EPEN (_U_(0x3FF) << DEVEPT_EPEN_Pos) /**< (DEVEPT Mask) EPEN */ +#define DEVEPT_EPRST_Pos 16 /**< (DEVEPT Position) Endpoint 9 Reset */ +#define DEVEPT_EPRST (_U_(0x3FF) << DEVEPT_EPRST_Pos) /**< (DEVEPT Mask) EPRST */ + +/* -------- DEVFNUM : (USBHS Offset: 0x20) (R/ 32) Device Frame Number Register -------- */ + +#define DEVFNUM_OFFSET (0x20) /**< (DEVFNUM) Device Frame Number Register Offset */ + +#define DEVFNUM_MFNUM_Pos 0 /**< (DEVFNUM) Micro Frame Number Position */ +#define DEVFNUM_MFNUM (_U_(0x7) << DEVFNUM_MFNUM_Pos) /**< (DEVFNUM) Micro Frame Number Mask */ +#define DEVFNUM_FNUM_Pos 3 /**< (DEVFNUM) Frame Number Position */ +#define DEVFNUM_FNUM (_U_(0x7FF) << DEVFNUM_FNUM_Pos) /**< (DEVFNUM) Frame Number Mask */ +#define DEVFNUM_FNCERR_Pos 15 /**< (DEVFNUM) Frame Number CRC Error Position */ +#define DEVFNUM_FNCERR (_U_(0x1) << DEVFNUM_FNCERR_Pos) /**< (DEVFNUM) Frame Number CRC Error Mask */ +#define DEVFNUM_Msk _U_(0xBFFF) /**< (DEVFNUM) Register Mask */ + + +/* -------- DEVEPTCFG : (USBHS Offset: 0x100) (R/W 32) Device Endpoint Configuration Register -------- */ + +#define DEVEPTCFG_OFFSET (0x100) /**< (DEVEPTCFG) Device Endpoint Configuration Register Offset */ + +#define DEVEPTCFG_ALLOC_Pos 1 /**< (DEVEPTCFG) Endpoint Memory Allocate Position */ +#define DEVEPTCFG_ALLOC (_U_(0x1) << DEVEPTCFG_ALLOC_Pos) /**< (DEVEPTCFG) Endpoint Memory Allocate Mask */ +#define DEVEPTCFG_EPBK_Pos 2 /**< (DEVEPTCFG) Endpoint Banks Position */ +#define DEVEPTCFG_EPBK (_U_(0x3) << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Endpoint Banks Mask */ +#define DEVEPTCFG_EPBK_1_BANK_Val _U_(0x0) /**< (DEVEPTCFG) Single-bank endpoint */ +#define DEVEPTCFG_EPBK_2_BANK_Val _U_(0x1) /**< (DEVEPTCFG) Double-bank endpoint */ +#define DEVEPTCFG_EPBK_3_BANK_Val _U_(0x2) /**< (DEVEPTCFG) Triple-bank endpoint */ +#define DEVEPTCFG_EPBK_1_BANK (DEVEPTCFG_EPBK_1_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Single-bank endpoint Position */ +#define DEVEPTCFG_EPBK_2_BANK (DEVEPTCFG_EPBK_2_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Double-bank endpoint Position */ +#define DEVEPTCFG_EPBK_3_BANK (DEVEPTCFG_EPBK_3_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Triple-bank endpoint Position */ +#define DEVEPTCFG_EPSIZE_Pos 4 /**< (DEVEPTCFG) Endpoint Size Position */ +#define DEVEPTCFG_EPSIZE (_U_(0x7) << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) Endpoint Size Mask */ +#define DEVEPTCFG_EPSIZE_8_BYTE_Val _U_(0x0) /**< (DEVEPTCFG) 8 bytes */ +#define DEVEPTCFG_EPSIZE_16_BYTE_Val _U_(0x1) /**< (DEVEPTCFG) 16 bytes */ +#define DEVEPTCFG_EPSIZE_32_BYTE_Val _U_(0x2) /**< (DEVEPTCFG) 32 bytes */ +#define DEVEPTCFG_EPSIZE_64_BYTE_Val _U_(0x3) /**< (DEVEPTCFG) 64 bytes */ +#define DEVEPTCFG_EPSIZE_128_BYTE_Val _U_(0x4) /**< (DEVEPTCFG) 128 bytes */ +#define DEVEPTCFG_EPSIZE_256_BYTE_Val _U_(0x5) /**< (DEVEPTCFG) 256 bytes */ +#define DEVEPTCFG_EPSIZE_512_BYTE_Val _U_(0x6) /**< (DEVEPTCFG) 512 bytes */ +#define DEVEPTCFG_EPSIZE_1024_BYTE_Val _U_(0x7) /**< (DEVEPTCFG) 1024 bytes */ +#define DEVEPTCFG_EPSIZE_8_BYTE (DEVEPTCFG_EPSIZE_8_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 8 bytes Position */ +#define DEVEPTCFG_EPSIZE_16_BYTE (DEVEPTCFG_EPSIZE_16_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 16 bytes Position */ +#define DEVEPTCFG_EPSIZE_32_BYTE (DEVEPTCFG_EPSIZE_32_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 32 bytes Position */ +#define DEVEPTCFG_EPSIZE_64_BYTE (DEVEPTCFG_EPSIZE_64_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 64 bytes Position */ +#define DEVEPTCFG_EPSIZE_128_BYTE (DEVEPTCFG_EPSIZE_128_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 128 bytes Position */ +#define DEVEPTCFG_EPSIZE_256_BYTE (DEVEPTCFG_EPSIZE_256_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 256 bytes Position */ +#define DEVEPTCFG_EPSIZE_512_BYTE (DEVEPTCFG_EPSIZE_512_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 512 bytes Position */ +#define DEVEPTCFG_EPSIZE_1024_BYTE (DEVEPTCFG_EPSIZE_1024_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 1024 bytes Position */ +#define DEVEPTCFG_EPDIR_Pos 8 /**< (DEVEPTCFG) Endpoint Direction Position */ +#define DEVEPTCFG_EPDIR (_U_(0x1) << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) Endpoint Direction Mask */ +#define DEVEPTCFG_EPDIR_OUT_Val _U_(0x0) /**< (DEVEPTCFG) The endpoint direction is OUT. */ +#define DEVEPTCFG_EPDIR_IN_Val _U_(0x1) /**< (DEVEPTCFG) The endpoint direction is IN (nor for control endpoints). */ +#define DEVEPTCFG_EPDIR_OUT (DEVEPTCFG_EPDIR_OUT_Val << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) The endpoint direction is OUT. Position */ +#define DEVEPTCFG_EPDIR_IN (DEVEPTCFG_EPDIR_IN_Val << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) The endpoint direction is IN (nor for control endpoints). Position */ +#define DEVEPTCFG_AUTOSW_Pos 9 /**< (DEVEPTCFG) Automatic Switch Position */ +#define DEVEPTCFG_AUTOSW (_U_(0x1) << DEVEPTCFG_AUTOSW_Pos) /**< (DEVEPTCFG) Automatic Switch Mask */ +#define DEVEPTCFG_EPTYPE_Pos 11 /**< (DEVEPTCFG) Endpoint Type Position */ +#define DEVEPTCFG_EPTYPE (_U_(0x3) << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Endpoint Type Mask */ +#define DEVEPTCFG_EPTYPE_CTRL_Val _U_(0x0) /**< (DEVEPTCFG) Control */ +#define DEVEPTCFG_EPTYPE_ISO_Val _U_(0x1) /**< (DEVEPTCFG) Isochronous */ +#define DEVEPTCFG_EPTYPE_BLK_Val _U_(0x2) /**< (DEVEPTCFG) Bulk */ +#define DEVEPTCFG_EPTYPE_INTRPT_Val _U_(0x3) /**< (DEVEPTCFG) Interrupt */ +#define DEVEPTCFG_EPTYPE_CTRL (DEVEPTCFG_EPTYPE_CTRL_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Control Position */ +#define DEVEPTCFG_EPTYPE_ISO (DEVEPTCFG_EPTYPE_ISO_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Isochronous Position */ +#define DEVEPTCFG_EPTYPE_BLK (DEVEPTCFG_EPTYPE_BLK_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Bulk Position */ +#define DEVEPTCFG_EPTYPE_INTRPT (DEVEPTCFG_EPTYPE_INTRPT_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Interrupt Position */ +#define DEVEPTCFG_NBTRANS_Pos 13 /**< (DEVEPTCFG) Number of transactions per microframe for isochronous endpoint Position */ +#define DEVEPTCFG_NBTRANS (_U_(0x3) << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Number of transactions per microframe for isochronous endpoint Mask */ +#define DEVEPTCFG_NBTRANS_0_TRANS_Val _U_(0x0) /**< (DEVEPTCFG) Reserved to endpoint that does not have the high-bandwidth isochronous capability. */ +#define DEVEPTCFG_NBTRANS_1_TRANS_Val _U_(0x1) /**< (DEVEPTCFG) Default value: one transaction per microframe. */ +#define DEVEPTCFG_NBTRANS_2_TRANS_Val _U_(0x2) /**< (DEVEPTCFG) Two transactions per microframe. This endpoint should be configured as double-bank. */ +#define DEVEPTCFG_NBTRANS_3_TRANS_Val _U_(0x3) /**< (DEVEPTCFG) Three transactions per microframe. This endpoint should be configured as triple-bank. */ +#define DEVEPTCFG_NBTRANS_0_TRANS (DEVEPTCFG_NBTRANS_0_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Reserved to endpoint that does not have the high-bandwidth isochronous capability. Position */ +#define DEVEPTCFG_NBTRANS_1_TRANS (DEVEPTCFG_NBTRANS_1_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Default value: one transaction per microframe. Position */ +#define DEVEPTCFG_NBTRANS_2_TRANS (DEVEPTCFG_NBTRANS_2_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Two transactions per microframe. This endpoint should be configured as double-bank. Position */ +#define DEVEPTCFG_NBTRANS_3_TRANS (DEVEPTCFG_NBTRANS_3_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Three transactions per microframe. This endpoint should be configured as triple-bank. Position */ +#define DEVEPTCFG_Msk _U_(0x7B7E) /**< (DEVEPTCFG) Register Mask */ + + +/* -------- DEVEPTISR : (USBHS Offset: 0x130) (R/ 32) Device Endpoint Interrupt Status Register -------- */ + +#define DEVEPTISR_OFFSET (0x130) /**< (DEVEPTISR) Device Endpoint Interrupt Status Register Offset */ + +#define DEVEPTISR_TXINI_Pos 0 /**< (DEVEPTISR) Transmitted IN Data Interrupt Position */ +#define DEVEPTISR_TXINI (_U_(0x1) << DEVEPTISR_TXINI_Pos) /**< (DEVEPTISR) Transmitted IN Data Interrupt Mask */ +#define DEVEPTISR_RXOUTI_Pos 1 /**< (DEVEPTISR) Received OUT Data Interrupt Position */ +#define DEVEPTISR_RXOUTI (_U_(0x1) << DEVEPTISR_RXOUTI_Pos) /**< (DEVEPTISR) Received OUT Data Interrupt Mask */ +#define DEVEPTISR_OVERFI_Pos 5 /**< (DEVEPTISR) Overflow Interrupt Position */ +#define DEVEPTISR_OVERFI (_U_(0x1) << DEVEPTISR_OVERFI_Pos) /**< (DEVEPTISR) Overflow Interrupt Mask */ +#define DEVEPTISR_SHORTPACKET_Pos 7 /**< (DEVEPTISR) Short Packet Interrupt Position */ +#define DEVEPTISR_SHORTPACKET (_U_(0x1) << DEVEPTISR_SHORTPACKET_Pos) /**< (DEVEPTISR) Short Packet Interrupt Mask */ +#define DEVEPTISR_DTSEQ_Pos 8 /**< (DEVEPTISR) Data Toggle Sequence Position */ +#define DEVEPTISR_DTSEQ (_U_(0x3) << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data Toggle Sequence Mask */ +#define DEVEPTISR_DTSEQ_DATA0_Val _U_(0x0) /**< (DEVEPTISR) Data0 toggle sequence */ +#define DEVEPTISR_DTSEQ_DATA1_Val _U_(0x1) /**< (DEVEPTISR) Data1 toggle sequence */ +#define DEVEPTISR_DTSEQ_DATA2_Val _U_(0x2) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint */ +#define DEVEPTISR_DTSEQ_MDATA_Val _U_(0x3) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint */ +#define DEVEPTISR_DTSEQ_DATA0 (DEVEPTISR_DTSEQ_DATA0_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data0 toggle sequence Position */ +#define DEVEPTISR_DTSEQ_DATA1 (DEVEPTISR_DTSEQ_DATA1_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data1 toggle sequence Position */ +#define DEVEPTISR_DTSEQ_DATA2 (DEVEPTISR_DTSEQ_DATA2_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint Position */ +#define DEVEPTISR_DTSEQ_MDATA (DEVEPTISR_DTSEQ_MDATA_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint Position */ +#define DEVEPTISR_NBUSYBK_Pos 12 /**< (DEVEPTISR) Number of Busy Banks Position */ +#define DEVEPTISR_NBUSYBK (_U_(0x3) << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) Number of Busy Banks Mask */ +#define DEVEPTISR_NBUSYBK_0_BUSY_Val _U_(0x0) /**< (DEVEPTISR) 0 busy bank (all banks free) */ +#define DEVEPTISR_NBUSYBK_1_BUSY_Val _U_(0x1) /**< (DEVEPTISR) 1 busy bank */ +#define DEVEPTISR_NBUSYBK_2_BUSY_Val _U_(0x2) /**< (DEVEPTISR) 2 busy banks */ +#define DEVEPTISR_NBUSYBK_3_BUSY_Val _U_(0x3) /**< (DEVEPTISR) 3 busy banks */ +#define DEVEPTISR_NBUSYBK_0_BUSY (DEVEPTISR_NBUSYBK_0_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 0 busy bank (all banks free) Position */ +#define DEVEPTISR_NBUSYBK_1_BUSY (DEVEPTISR_NBUSYBK_1_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 1 busy bank Position */ +#define DEVEPTISR_NBUSYBK_2_BUSY (DEVEPTISR_NBUSYBK_2_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 2 busy banks Position */ +#define DEVEPTISR_NBUSYBK_3_BUSY (DEVEPTISR_NBUSYBK_3_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 3 busy banks Position */ +#define DEVEPTISR_CURRBK_Pos 14 /**< (DEVEPTISR) Current Bank Position */ +#define DEVEPTISR_CURRBK (_U_(0x3) << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current Bank Mask */ +#define DEVEPTISR_CURRBK_BANK0_Val _U_(0x0) /**< (DEVEPTISR) Current bank is bank0 */ +#define DEVEPTISR_CURRBK_BANK1_Val _U_(0x1) /**< (DEVEPTISR) Current bank is bank1 */ +#define DEVEPTISR_CURRBK_BANK2_Val _U_(0x2) /**< (DEVEPTISR) Current bank is bank2 */ +#define DEVEPTISR_CURRBK_BANK0 (DEVEPTISR_CURRBK_BANK0_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank0 Position */ +#define DEVEPTISR_CURRBK_BANK1 (DEVEPTISR_CURRBK_BANK1_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank1 Position */ +#define DEVEPTISR_CURRBK_BANK2 (DEVEPTISR_CURRBK_BANK2_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank2 Position */ +#define DEVEPTISR_RWALL_Pos 16 /**< (DEVEPTISR) Read/Write Allowed Position */ +#define DEVEPTISR_RWALL (_U_(0x1) << DEVEPTISR_RWALL_Pos) /**< (DEVEPTISR) Read/Write Allowed Mask */ +#define DEVEPTISR_CFGOK_Pos 18 /**< (DEVEPTISR) Configuration OK Status Position */ +#define DEVEPTISR_CFGOK (_U_(0x1) << DEVEPTISR_CFGOK_Pos) /**< (DEVEPTISR) Configuration OK Status Mask */ +#define DEVEPTISR_BYCT_Pos 20 /**< (DEVEPTISR) Byte Count Position */ +#define DEVEPTISR_BYCT (_U_(0x7FF) << DEVEPTISR_BYCT_Pos) /**< (DEVEPTISR) Byte Count Mask */ +#define DEVEPTISR_Msk _U_(0x7FF5F3A3) /**< (DEVEPTISR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTISR_CTRL_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ +#define DEVEPTISR_CTRL_RXSTPI (_U_(0x1) << DEVEPTISR_CTRL_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ +#define DEVEPTISR_CTRL_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ +#define DEVEPTISR_CTRL_NAKOUTI (_U_(0x1) << DEVEPTISR_CTRL_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ +#define DEVEPTISR_CTRL_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ +#define DEVEPTISR_CTRL_NAKINI (_U_(0x1) << DEVEPTISR_CTRL_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ +#define DEVEPTISR_CTRL_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ +#define DEVEPTISR_CTRL_STALLEDI (_U_(0x1) << DEVEPTISR_CTRL_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ +#define DEVEPTISR_CTRL_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ +#define DEVEPTISR_CTRL_CTRLDIR (_U_(0x1) << DEVEPTISR_CTRL_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ +#define DEVEPTISR_CTRL_Msk _U_(0x2005C) /**< (DEVEPTISR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTISR_ISO_UNDERFI_Pos 2 /**< (DEVEPTISR) Underflow Interrupt Position */ +#define DEVEPTISR_ISO_UNDERFI (_U_(0x1) << DEVEPTISR_ISO_UNDERFI_Pos) /**< (DEVEPTISR) Underflow Interrupt Mask */ +#define DEVEPTISR_ISO_HBISOINERRI_Pos 3 /**< (DEVEPTISR) High Bandwidth Isochronous IN Underflow Error Interrupt Position */ +#define DEVEPTISR_ISO_HBISOINERRI (_U_(0x1) << DEVEPTISR_ISO_HBISOINERRI_Pos) /**< (DEVEPTISR) High Bandwidth Isochronous IN Underflow Error Interrupt Mask */ +#define DEVEPTISR_ISO_HBISOFLUSHI_Pos 4 /**< (DEVEPTISR) High Bandwidth Isochronous IN Flush Interrupt Position */ +#define DEVEPTISR_ISO_HBISOFLUSHI (_U_(0x1) << DEVEPTISR_ISO_HBISOFLUSHI_Pos) /**< (DEVEPTISR) High Bandwidth Isochronous IN Flush Interrupt Mask */ +#define DEVEPTISR_ISO_CRCERRI_Pos 6 /**< (DEVEPTISR) CRC Error Interrupt Position */ +#define DEVEPTISR_ISO_CRCERRI (_U_(0x1) << DEVEPTISR_ISO_CRCERRI_Pos) /**< (DEVEPTISR) CRC Error Interrupt Mask */ +#define DEVEPTISR_ISO_ERRORTRANS_Pos 10 /**< (DEVEPTISR) High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt Position */ +#define DEVEPTISR_ISO_ERRORTRANS (_U_(0x1) << DEVEPTISR_ISO_ERRORTRANS_Pos) /**< (DEVEPTISR) High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt Mask */ +#define DEVEPTISR_ISO_Msk _U_(0x45C) /**< (DEVEPTISR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTISR_BLK_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ +#define DEVEPTISR_BLK_RXSTPI (_U_(0x1) << DEVEPTISR_BLK_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ +#define DEVEPTISR_BLK_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ +#define DEVEPTISR_BLK_NAKOUTI (_U_(0x1) << DEVEPTISR_BLK_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ +#define DEVEPTISR_BLK_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ +#define DEVEPTISR_BLK_NAKINI (_U_(0x1) << DEVEPTISR_BLK_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ +#define DEVEPTISR_BLK_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ +#define DEVEPTISR_BLK_STALLEDI (_U_(0x1) << DEVEPTISR_BLK_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ +#define DEVEPTISR_BLK_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ +#define DEVEPTISR_BLK_CTRLDIR (_U_(0x1) << DEVEPTISR_BLK_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ +#define DEVEPTISR_BLK_Msk _U_(0x2005C) /**< (DEVEPTISR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTISR_INTRPT_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ +#define DEVEPTISR_INTRPT_RXSTPI (_U_(0x1) << DEVEPTISR_INTRPT_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ +#define DEVEPTISR_INTRPT_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ +#define DEVEPTISR_INTRPT_NAKOUTI (_U_(0x1) << DEVEPTISR_INTRPT_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ +#define DEVEPTISR_INTRPT_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ +#define DEVEPTISR_INTRPT_NAKINI (_U_(0x1) << DEVEPTISR_INTRPT_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ +#define DEVEPTISR_INTRPT_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ +#define DEVEPTISR_INTRPT_STALLEDI (_U_(0x1) << DEVEPTISR_INTRPT_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ +#define DEVEPTISR_INTRPT_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ +#define DEVEPTISR_INTRPT_CTRLDIR (_U_(0x1) << DEVEPTISR_INTRPT_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ +#define DEVEPTISR_INTRPT_Msk _U_(0x2005C) /**< (DEVEPTISR_INTRPT) Register Mask */ + + +/* -------- DEVEPTICR : (USBHS Offset: 0x160) (/W 32) Device Endpoint Interrupt Clear Register -------- */ + +#define DEVEPTICR_OFFSET (0x160) /**< (DEVEPTICR) Device Endpoint Interrupt Clear Register Offset */ + +#define DEVEPTICR_TXINIC_Pos 0 /**< (DEVEPTICR) Transmitted IN Data Interrupt Clear Position */ +#define DEVEPTICR_TXINIC (_U_(0x1) << DEVEPTICR_TXINIC_Pos) /**< (DEVEPTICR) Transmitted IN Data Interrupt Clear Mask */ +#define DEVEPTICR_RXOUTIC_Pos 1 /**< (DEVEPTICR) Received OUT Data Interrupt Clear Position */ +#define DEVEPTICR_RXOUTIC (_U_(0x1) << DEVEPTICR_RXOUTIC_Pos) /**< (DEVEPTICR) Received OUT Data Interrupt Clear Mask */ +#define DEVEPTICR_OVERFIC_Pos 5 /**< (DEVEPTICR) Overflow Interrupt Clear Position */ +#define DEVEPTICR_OVERFIC (_U_(0x1) << DEVEPTICR_OVERFIC_Pos) /**< (DEVEPTICR) Overflow Interrupt Clear Mask */ +#define DEVEPTICR_SHORTPACKETC_Pos 7 /**< (DEVEPTICR) Short Packet Interrupt Clear Position */ +#define DEVEPTICR_SHORTPACKETC (_U_(0x1) << DEVEPTICR_SHORTPACKETC_Pos) /**< (DEVEPTICR) Short Packet Interrupt Clear Mask */ +#define DEVEPTICR_Msk _U_(0xA3) /**< (DEVEPTICR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTICR_CTRL_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ +#define DEVEPTICR_CTRL_RXSTPIC (_U_(0x1) << DEVEPTICR_CTRL_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTICR_CTRL_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTICR_CTRL_NAKOUTIC (_U_(0x1) << DEVEPTICR_CTRL_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTICR_CTRL_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ +#define DEVEPTICR_CTRL_NAKINIC (_U_(0x1) << DEVEPTICR_CTRL_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTICR_CTRL_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ +#define DEVEPTICR_CTRL_STALLEDIC (_U_(0x1) << DEVEPTICR_CTRL_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ +#define DEVEPTICR_CTRL_Msk _U_(0x5C) /**< (DEVEPTICR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTICR_ISO_UNDERFIC_Pos 2 /**< (DEVEPTICR) Underflow Interrupt Clear Position */ +#define DEVEPTICR_ISO_UNDERFIC (_U_(0x1) << DEVEPTICR_ISO_UNDERFIC_Pos) /**< (DEVEPTICR) Underflow Interrupt Clear Mask */ +#define DEVEPTICR_ISO_HBISOINERRIC_Pos 3 /**< (DEVEPTICR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Position */ +#define DEVEPTICR_ISO_HBISOINERRIC (_U_(0x1) << DEVEPTICR_ISO_HBISOINERRIC_Pos) /**< (DEVEPTICR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Mask */ +#define DEVEPTICR_ISO_HBISOFLUSHIC_Pos 4 /**< (DEVEPTICR) High Bandwidth Isochronous IN Flush Interrupt Clear Position */ +#define DEVEPTICR_ISO_HBISOFLUSHIC (_U_(0x1) << DEVEPTICR_ISO_HBISOFLUSHIC_Pos) /**< (DEVEPTICR) High Bandwidth Isochronous IN Flush Interrupt Clear Mask */ +#define DEVEPTICR_ISO_CRCERRIC_Pos 6 /**< (DEVEPTICR) CRC Error Interrupt Clear Position */ +#define DEVEPTICR_ISO_CRCERRIC (_U_(0x1) << DEVEPTICR_ISO_CRCERRIC_Pos) /**< (DEVEPTICR) CRC Error Interrupt Clear Mask */ +#define DEVEPTICR_ISO_Msk _U_(0x5C) /**< (DEVEPTICR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTICR_BLK_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ +#define DEVEPTICR_BLK_RXSTPIC (_U_(0x1) << DEVEPTICR_BLK_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTICR_BLK_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTICR_BLK_NAKOUTIC (_U_(0x1) << DEVEPTICR_BLK_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTICR_BLK_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ +#define DEVEPTICR_BLK_NAKINIC (_U_(0x1) << DEVEPTICR_BLK_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTICR_BLK_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ +#define DEVEPTICR_BLK_STALLEDIC (_U_(0x1) << DEVEPTICR_BLK_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ +#define DEVEPTICR_BLK_Msk _U_(0x5C) /**< (DEVEPTICR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTICR_INTRPT_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ +#define DEVEPTICR_INTRPT_RXSTPIC (_U_(0x1) << DEVEPTICR_INTRPT_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTICR_INTRPT_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTICR_INTRPT_NAKOUTIC (_U_(0x1) << DEVEPTICR_INTRPT_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTICR_INTRPT_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ +#define DEVEPTICR_INTRPT_NAKINIC (_U_(0x1) << DEVEPTICR_INTRPT_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTICR_INTRPT_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ +#define DEVEPTICR_INTRPT_STALLEDIC (_U_(0x1) << DEVEPTICR_INTRPT_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ +#define DEVEPTICR_INTRPT_Msk _U_(0x5C) /**< (DEVEPTICR_INTRPT) Register Mask */ + + +/* -------- DEVEPTIFR : (USBHS Offset: 0x190) (/W 32) Device Endpoint Interrupt Set Register -------- */ + +#define DEVEPTIFR_OFFSET (0x190) /**< (DEVEPTIFR) Device Endpoint Interrupt Set Register Offset */ + +#define DEVEPTIFR_TXINIS_Pos 0 /**< (DEVEPTIFR) Transmitted IN Data Interrupt Set Position */ +#define DEVEPTIFR_TXINIS (_U_(0x1) << DEVEPTIFR_TXINIS_Pos) /**< (DEVEPTIFR) Transmitted IN Data Interrupt Set Mask */ +#define DEVEPTIFR_RXOUTIS_Pos 1 /**< (DEVEPTIFR) Received OUT Data Interrupt Set Position */ +#define DEVEPTIFR_RXOUTIS (_U_(0x1) << DEVEPTIFR_RXOUTIS_Pos) /**< (DEVEPTIFR) Received OUT Data Interrupt Set Mask */ +#define DEVEPTIFR_OVERFIS_Pos 5 /**< (DEVEPTIFR) Overflow Interrupt Set Position */ +#define DEVEPTIFR_OVERFIS (_U_(0x1) << DEVEPTIFR_OVERFIS_Pos) /**< (DEVEPTIFR) Overflow Interrupt Set Mask */ +#define DEVEPTIFR_SHORTPACKETS_Pos 7 /**< (DEVEPTIFR) Short Packet Interrupt Set Position */ +#define DEVEPTIFR_SHORTPACKETS (_U_(0x1) << DEVEPTIFR_SHORTPACKETS_Pos) /**< (DEVEPTIFR) Short Packet Interrupt Set Mask */ +#define DEVEPTIFR_NBUSYBKS_Pos 12 /**< (DEVEPTIFR) Number of Busy Banks Interrupt Set Position */ +#define DEVEPTIFR_NBUSYBKS (_U_(0x1) << DEVEPTIFR_NBUSYBKS_Pos) /**< (DEVEPTIFR) Number of Busy Banks Interrupt Set Mask */ +#define DEVEPTIFR_Msk _U_(0x10A3) /**< (DEVEPTIFR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTIFR_CTRL_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ +#define DEVEPTIFR_CTRL_RXSTPIS (_U_(0x1) << DEVEPTIFR_CTRL_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ +#define DEVEPTIFR_CTRL_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ +#define DEVEPTIFR_CTRL_NAKOUTIS (_U_(0x1) << DEVEPTIFR_CTRL_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ +#define DEVEPTIFR_CTRL_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ +#define DEVEPTIFR_CTRL_NAKINIS (_U_(0x1) << DEVEPTIFR_CTRL_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ +#define DEVEPTIFR_CTRL_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ +#define DEVEPTIFR_CTRL_STALLEDIS (_U_(0x1) << DEVEPTIFR_CTRL_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ +#define DEVEPTIFR_CTRL_Msk _U_(0x5C) /**< (DEVEPTIFR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTIFR_ISO_UNDERFIS_Pos 2 /**< (DEVEPTIFR) Underflow Interrupt Set Position */ +#define DEVEPTIFR_ISO_UNDERFIS (_U_(0x1) << DEVEPTIFR_ISO_UNDERFIS_Pos) /**< (DEVEPTIFR) Underflow Interrupt Set Mask */ +#define DEVEPTIFR_ISO_HBISOINERRIS_Pos 3 /**< (DEVEPTIFR) High Bandwidth Isochronous IN Underflow Error Interrupt Set Position */ +#define DEVEPTIFR_ISO_HBISOINERRIS (_U_(0x1) << DEVEPTIFR_ISO_HBISOINERRIS_Pos) /**< (DEVEPTIFR) High Bandwidth Isochronous IN Underflow Error Interrupt Set Mask */ +#define DEVEPTIFR_ISO_HBISOFLUSHIS_Pos 4 /**< (DEVEPTIFR) High Bandwidth Isochronous IN Flush Interrupt Set Position */ +#define DEVEPTIFR_ISO_HBISOFLUSHIS (_U_(0x1) << DEVEPTIFR_ISO_HBISOFLUSHIS_Pos) /**< (DEVEPTIFR) High Bandwidth Isochronous IN Flush Interrupt Set Mask */ +#define DEVEPTIFR_ISO_CRCERRIS_Pos 6 /**< (DEVEPTIFR) CRC Error Interrupt Set Position */ +#define DEVEPTIFR_ISO_CRCERRIS (_U_(0x1) << DEVEPTIFR_ISO_CRCERRIS_Pos) /**< (DEVEPTIFR) CRC Error Interrupt Set Mask */ +#define DEVEPTIFR_ISO_Msk _U_(0x5C) /**< (DEVEPTIFR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTIFR_BLK_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ +#define DEVEPTIFR_BLK_RXSTPIS (_U_(0x1) << DEVEPTIFR_BLK_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ +#define DEVEPTIFR_BLK_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ +#define DEVEPTIFR_BLK_NAKOUTIS (_U_(0x1) << DEVEPTIFR_BLK_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ +#define DEVEPTIFR_BLK_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ +#define DEVEPTIFR_BLK_NAKINIS (_U_(0x1) << DEVEPTIFR_BLK_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ +#define DEVEPTIFR_BLK_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ +#define DEVEPTIFR_BLK_STALLEDIS (_U_(0x1) << DEVEPTIFR_BLK_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ +#define DEVEPTIFR_BLK_Msk _U_(0x5C) /**< (DEVEPTIFR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTIFR_INTRPT_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ +#define DEVEPTIFR_INTRPT_RXSTPIS (_U_(0x1) << DEVEPTIFR_INTRPT_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ +#define DEVEPTIFR_INTRPT_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ +#define DEVEPTIFR_INTRPT_NAKOUTIS (_U_(0x1) << DEVEPTIFR_INTRPT_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ +#define DEVEPTIFR_INTRPT_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ +#define DEVEPTIFR_INTRPT_NAKINIS (_U_(0x1) << DEVEPTIFR_INTRPT_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ +#define DEVEPTIFR_INTRPT_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ +#define DEVEPTIFR_INTRPT_STALLEDIS (_U_(0x1) << DEVEPTIFR_INTRPT_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ +#define DEVEPTIFR_INTRPT_Msk _U_(0x5C) /**< (DEVEPTIFR_INTRPT) Register Mask */ + + +/* -------- DEVEPTIMR : (USBHS Offset: 0x1c0) (R/ 32) Device Endpoint Interrupt Mask Register -------- */ + +#define DEVEPTIMR_OFFSET (0x1C0) /**< (DEVEPTIMR) Device Endpoint Interrupt Mask Register Offset */ + +#define DEVEPTIMR_TXINE_Pos 0 /**< (DEVEPTIMR) Transmitted IN Data Interrupt Position */ +#define DEVEPTIMR_TXINE (_U_(0x1) << DEVEPTIMR_TXINE_Pos) /**< (DEVEPTIMR) Transmitted IN Data Interrupt Mask */ +#define DEVEPTIMR_RXOUTE_Pos 1 /**< (DEVEPTIMR) Received OUT Data Interrupt Position */ +#define DEVEPTIMR_RXOUTE (_U_(0x1) << DEVEPTIMR_RXOUTE_Pos) /**< (DEVEPTIMR) Received OUT Data Interrupt Mask */ +#define DEVEPTIMR_OVERFE_Pos 5 /**< (DEVEPTIMR) Overflow Interrupt Position */ +#define DEVEPTIMR_OVERFE (_U_(0x1) << DEVEPTIMR_OVERFE_Pos) /**< (DEVEPTIMR) Overflow Interrupt Mask */ +#define DEVEPTIMR_SHORTPACKETE_Pos 7 /**< (DEVEPTIMR) Short Packet Interrupt Position */ +#define DEVEPTIMR_SHORTPACKETE (_U_(0x1) << DEVEPTIMR_SHORTPACKETE_Pos) /**< (DEVEPTIMR) Short Packet Interrupt Mask */ +#define DEVEPTIMR_NBUSYBKE_Pos 12 /**< (DEVEPTIMR) Number of Busy Banks Interrupt Position */ +#define DEVEPTIMR_NBUSYBKE (_U_(0x1) << DEVEPTIMR_NBUSYBKE_Pos) /**< (DEVEPTIMR) Number of Busy Banks Interrupt Mask */ +#define DEVEPTIMR_KILLBK_Pos 13 /**< (DEVEPTIMR) Kill IN Bank Position */ +#define DEVEPTIMR_KILLBK (_U_(0x1) << DEVEPTIMR_KILLBK_Pos) /**< (DEVEPTIMR) Kill IN Bank Mask */ +#define DEVEPTIMR_FIFOCON_Pos 14 /**< (DEVEPTIMR) FIFO Control Position */ +#define DEVEPTIMR_FIFOCON (_U_(0x1) << DEVEPTIMR_FIFOCON_Pos) /**< (DEVEPTIMR) FIFO Control Mask */ +#define DEVEPTIMR_EPDISHDMA_Pos 16 /**< (DEVEPTIMR) Endpoint Interrupts Disable HDMA Request Position */ +#define DEVEPTIMR_EPDISHDMA (_U_(0x1) << DEVEPTIMR_EPDISHDMA_Pos) /**< (DEVEPTIMR) Endpoint Interrupts Disable HDMA Request Mask */ +#define DEVEPTIMR_RSTDT_Pos 18 /**< (DEVEPTIMR) Reset Data Toggle Position */ +#define DEVEPTIMR_RSTDT (_U_(0x1) << DEVEPTIMR_RSTDT_Pos) /**< (DEVEPTIMR) Reset Data Toggle Mask */ +#define DEVEPTIMR_Msk _U_(0x570A3) /**< (DEVEPTIMR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTIMR_CTRL_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ +#define DEVEPTIMR_CTRL_RXSTPE (_U_(0x1) << DEVEPTIMR_CTRL_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ +#define DEVEPTIMR_CTRL_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ +#define DEVEPTIMR_CTRL_NAKOUTE (_U_(0x1) << DEVEPTIMR_CTRL_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ +#define DEVEPTIMR_CTRL_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ +#define DEVEPTIMR_CTRL_NAKINE (_U_(0x1) << DEVEPTIMR_CTRL_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ +#define DEVEPTIMR_CTRL_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ +#define DEVEPTIMR_CTRL_STALLEDE (_U_(0x1) << DEVEPTIMR_CTRL_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ +#define DEVEPTIMR_CTRL_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ +#define DEVEPTIMR_CTRL_NYETDIS (_U_(0x1) << DEVEPTIMR_CTRL_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ +#define DEVEPTIMR_CTRL_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ +#define DEVEPTIMR_CTRL_STALLRQ (_U_(0x1) << DEVEPTIMR_CTRL_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ +#define DEVEPTIMR_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIMR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTIMR_ISO_UNDERFE_Pos 2 /**< (DEVEPTIMR) Underflow Interrupt Position */ +#define DEVEPTIMR_ISO_UNDERFE (_U_(0x1) << DEVEPTIMR_ISO_UNDERFE_Pos) /**< (DEVEPTIMR) Underflow Interrupt Mask */ +#define DEVEPTIMR_ISO_HBISOINERRE_Pos 3 /**< (DEVEPTIMR) High Bandwidth Isochronous IN Underflow Error Interrupt Position */ +#define DEVEPTIMR_ISO_HBISOINERRE (_U_(0x1) << DEVEPTIMR_ISO_HBISOINERRE_Pos) /**< (DEVEPTIMR) High Bandwidth Isochronous IN Underflow Error Interrupt Mask */ +#define DEVEPTIMR_ISO_HBISOFLUSHE_Pos 4 /**< (DEVEPTIMR) High Bandwidth Isochronous IN Flush Interrupt Position */ +#define DEVEPTIMR_ISO_HBISOFLUSHE (_U_(0x1) << DEVEPTIMR_ISO_HBISOFLUSHE_Pos) /**< (DEVEPTIMR) High Bandwidth Isochronous IN Flush Interrupt Mask */ +#define DEVEPTIMR_ISO_CRCERRE_Pos 6 /**< (DEVEPTIMR) CRC Error Interrupt Position */ +#define DEVEPTIMR_ISO_CRCERRE (_U_(0x1) << DEVEPTIMR_ISO_CRCERRE_Pos) /**< (DEVEPTIMR) CRC Error Interrupt Mask */ +#define DEVEPTIMR_ISO_MDATAE_Pos 8 /**< (DEVEPTIMR) MData Interrupt Position */ +#define DEVEPTIMR_ISO_MDATAE (_U_(0x1) << DEVEPTIMR_ISO_MDATAE_Pos) /**< (DEVEPTIMR) MData Interrupt Mask */ +#define DEVEPTIMR_ISO_DATAXE_Pos 9 /**< (DEVEPTIMR) DataX Interrupt Position */ +#define DEVEPTIMR_ISO_DATAXE (_U_(0x1) << DEVEPTIMR_ISO_DATAXE_Pos) /**< (DEVEPTIMR) DataX Interrupt Mask */ +#define DEVEPTIMR_ISO_ERRORTRANSE_Pos 10 /**< (DEVEPTIMR) Transaction Error Interrupt Position */ +#define DEVEPTIMR_ISO_ERRORTRANSE (_U_(0x1) << DEVEPTIMR_ISO_ERRORTRANSE_Pos) /**< (DEVEPTIMR) Transaction Error Interrupt Mask */ +#define DEVEPTIMR_ISO_Msk _U_(0x75C) /**< (DEVEPTIMR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTIMR_BLK_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ +#define DEVEPTIMR_BLK_RXSTPE (_U_(0x1) << DEVEPTIMR_BLK_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ +#define DEVEPTIMR_BLK_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ +#define DEVEPTIMR_BLK_NAKOUTE (_U_(0x1) << DEVEPTIMR_BLK_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ +#define DEVEPTIMR_BLK_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ +#define DEVEPTIMR_BLK_NAKINE (_U_(0x1) << DEVEPTIMR_BLK_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ +#define DEVEPTIMR_BLK_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ +#define DEVEPTIMR_BLK_STALLEDE (_U_(0x1) << DEVEPTIMR_BLK_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ +#define DEVEPTIMR_BLK_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ +#define DEVEPTIMR_BLK_NYETDIS (_U_(0x1) << DEVEPTIMR_BLK_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ +#define DEVEPTIMR_BLK_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ +#define DEVEPTIMR_BLK_STALLRQ (_U_(0x1) << DEVEPTIMR_BLK_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ +#define DEVEPTIMR_BLK_Msk _U_(0xA005C) /**< (DEVEPTIMR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTIMR_INTRPT_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ +#define DEVEPTIMR_INTRPT_RXSTPE (_U_(0x1) << DEVEPTIMR_INTRPT_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ +#define DEVEPTIMR_INTRPT_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ +#define DEVEPTIMR_INTRPT_NAKOUTE (_U_(0x1) << DEVEPTIMR_INTRPT_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ +#define DEVEPTIMR_INTRPT_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ +#define DEVEPTIMR_INTRPT_NAKINE (_U_(0x1) << DEVEPTIMR_INTRPT_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ +#define DEVEPTIMR_INTRPT_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ +#define DEVEPTIMR_INTRPT_STALLEDE (_U_(0x1) << DEVEPTIMR_INTRPT_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ +#define DEVEPTIMR_INTRPT_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ +#define DEVEPTIMR_INTRPT_NYETDIS (_U_(0x1) << DEVEPTIMR_INTRPT_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ +#define DEVEPTIMR_INTRPT_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ +#define DEVEPTIMR_INTRPT_STALLRQ (_U_(0x1) << DEVEPTIMR_INTRPT_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ +#define DEVEPTIMR_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIMR_INTRPT) Register Mask */ + + +/* -------- DEVEPTIER : (USBHS Offset: 0x1f0) (/W 32) Device Endpoint Interrupt Enable Register -------- */ + +#define DEVEPTIER_OFFSET (0x1F0) /**< (DEVEPTIER) Device Endpoint Interrupt Enable Register Offset */ + +#define DEVEPTIER_TXINES_Pos 0 /**< (DEVEPTIER) Transmitted IN Data Interrupt Enable Position */ +#define DEVEPTIER_TXINES (_U_(0x1) << DEVEPTIER_TXINES_Pos) /**< (DEVEPTIER) Transmitted IN Data Interrupt Enable Mask */ +#define DEVEPTIER_RXOUTES_Pos 1 /**< (DEVEPTIER) Received OUT Data Interrupt Enable Position */ +#define DEVEPTIER_RXOUTES (_U_(0x1) << DEVEPTIER_RXOUTES_Pos) /**< (DEVEPTIER) Received OUT Data Interrupt Enable Mask */ +#define DEVEPTIER_OVERFES_Pos 5 /**< (DEVEPTIER) Overflow Interrupt Enable Position */ +#define DEVEPTIER_OVERFES (_U_(0x1) << DEVEPTIER_OVERFES_Pos) /**< (DEVEPTIER) Overflow Interrupt Enable Mask */ +#define DEVEPTIER_SHORTPACKETES_Pos 7 /**< (DEVEPTIER) Short Packet Interrupt Enable Position */ +#define DEVEPTIER_SHORTPACKETES (_U_(0x1) << DEVEPTIER_SHORTPACKETES_Pos) /**< (DEVEPTIER) Short Packet Interrupt Enable Mask */ +#define DEVEPTIER_NBUSYBKES_Pos 12 /**< (DEVEPTIER) Number of Busy Banks Interrupt Enable Position */ +#define DEVEPTIER_NBUSYBKES (_U_(0x1) << DEVEPTIER_NBUSYBKES_Pos) /**< (DEVEPTIER) Number of Busy Banks Interrupt Enable Mask */ +#define DEVEPTIER_KILLBKS_Pos 13 /**< (DEVEPTIER) Kill IN Bank Position */ +#define DEVEPTIER_KILLBKS (_U_(0x1) << DEVEPTIER_KILLBKS_Pos) /**< (DEVEPTIER) Kill IN Bank Mask */ +#define DEVEPTIER_FIFOCONS_Pos 14 /**< (DEVEPTIER) FIFO Control Position */ +#define DEVEPTIER_FIFOCONS (_U_(0x1) << DEVEPTIER_FIFOCONS_Pos) /**< (DEVEPTIER) FIFO Control Mask */ +#define DEVEPTIER_EPDISHDMAS_Pos 16 /**< (DEVEPTIER) Endpoint Interrupts Disable HDMA Request Enable Position */ +#define DEVEPTIER_EPDISHDMAS (_U_(0x1) << DEVEPTIER_EPDISHDMAS_Pos) /**< (DEVEPTIER) Endpoint Interrupts Disable HDMA Request Enable Mask */ +#define DEVEPTIER_RSTDTS_Pos 18 /**< (DEVEPTIER) Reset Data Toggle Enable Position */ +#define DEVEPTIER_RSTDTS (_U_(0x1) << DEVEPTIER_RSTDTS_Pos) /**< (DEVEPTIER) Reset Data Toggle Enable Mask */ +#define DEVEPTIER_Msk _U_(0x570A3) /**< (DEVEPTIER) Register Mask */ + +/* CTRL mode */ +#define DEVEPTIER_CTRL_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ +#define DEVEPTIER_CTRL_RXSTPES (_U_(0x1) << DEVEPTIER_CTRL_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ +#define DEVEPTIER_CTRL_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ +#define DEVEPTIER_CTRL_NAKOUTES (_U_(0x1) << DEVEPTIER_CTRL_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ +#define DEVEPTIER_CTRL_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ +#define DEVEPTIER_CTRL_NAKINES (_U_(0x1) << DEVEPTIER_CTRL_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ +#define DEVEPTIER_CTRL_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ +#define DEVEPTIER_CTRL_STALLEDES (_U_(0x1) << DEVEPTIER_CTRL_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ +#define DEVEPTIER_CTRL_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ +#define DEVEPTIER_CTRL_NYETDISS (_U_(0x1) << DEVEPTIER_CTRL_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ +#define DEVEPTIER_CTRL_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ +#define DEVEPTIER_CTRL_STALLRQS (_U_(0x1) << DEVEPTIER_CTRL_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ +#define DEVEPTIER_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIER_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTIER_ISO_UNDERFES_Pos 2 /**< (DEVEPTIER) Underflow Interrupt Enable Position */ +#define DEVEPTIER_ISO_UNDERFES (_U_(0x1) << DEVEPTIER_ISO_UNDERFES_Pos) /**< (DEVEPTIER) Underflow Interrupt Enable Mask */ +#define DEVEPTIER_ISO_HBISOINERRES_Pos 3 /**< (DEVEPTIER) High Bandwidth Isochronous IN Underflow Error Interrupt Enable Position */ +#define DEVEPTIER_ISO_HBISOINERRES (_U_(0x1) << DEVEPTIER_ISO_HBISOINERRES_Pos) /**< (DEVEPTIER) High Bandwidth Isochronous IN Underflow Error Interrupt Enable Mask */ +#define DEVEPTIER_ISO_HBISOFLUSHES_Pos 4 /**< (DEVEPTIER) High Bandwidth Isochronous IN Flush Interrupt Enable Position */ +#define DEVEPTIER_ISO_HBISOFLUSHES (_U_(0x1) << DEVEPTIER_ISO_HBISOFLUSHES_Pos) /**< (DEVEPTIER) High Bandwidth Isochronous IN Flush Interrupt Enable Mask */ +#define DEVEPTIER_ISO_CRCERRES_Pos 6 /**< (DEVEPTIER) CRC Error Interrupt Enable Position */ +#define DEVEPTIER_ISO_CRCERRES (_U_(0x1) << DEVEPTIER_ISO_CRCERRES_Pos) /**< (DEVEPTIER) CRC Error Interrupt Enable Mask */ +#define DEVEPTIER_ISO_MDATAES_Pos 8 /**< (DEVEPTIER) MData Interrupt Enable Position */ +#define DEVEPTIER_ISO_MDATAES (_U_(0x1) << DEVEPTIER_ISO_MDATAES_Pos) /**< (DEVEPTIER) MData Interrupt Enable Mask */ +#define DEVEPTIER_ISO_DATAXES_Pos 9 /**< (DEVEPTIER) DataX Interrupt Enable Position */ +#define DEVEPTIER_ISO_DATAXES (_U_(0x1) << DEVEPTIER_ISO_DATAXES_Pos) /**< (DEVEPTIER) DataX Interrupt Enable Mask */ +#define DEVEPTIER_ISO_ERRORTRANSES_Pos 10 /**< (DEVEPTIER) Transaction Error Interrupt Enable Position */ +#define DEVEPTIER_ISO_ERRORTRANSES (_U_(0x1) << DEVEPTIER_ISO_ERRORTRANSES_Pos) /**< (DEVEPTIER) Transaction Error Interrupt Enable Mask */ +#define DEVEPTIER_ISO_Msk _U_(0x75C) /**< (DEVEPTIER_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTIER_BLK_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ +#define DEVEPTIER_BLK_RXSTPES (_U_(0x1) << DEVEPTIER_BLK_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ +#define DEVEPTIER_BLK_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ +#define DEVEPTIER_BLK_NAKOUTES (_U_(0x1) << DEVEPTIER_BLK_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ +#define DEVEPTIER_BLK_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ +#define DEVEPTIER_BLK_NAKINES (_U_(0x1) << DEVEPTIER_BLK_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ +#define DEVEPTIER_BLK_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ +#define DEVEPTIER_BLK_STALLEDES (_U_(0x1) << DEVEPTIER_BLK_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ +#define DEVEPTIER_BLK_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ +#define DEVEPTIER_BLK_NYETDISS (_U_(0x1) << DEVEPTIER_BLK_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ +#define DEVEPTIER_BLK_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ +#define DEVEPTIER_BLK_STALLRQS (_U_(0x1) << DEVEPTIER_BLK_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ +#define DEVEPTIER_BLK_Msk _U_(0xA005C) /**< (DEVEPTIER_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTIER_INTRPT_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ +#define DEVEPTIER_INTRPT_RXSTPES (_U_(0x1) << DEVEPTIER_INTRPT_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ +#define DEVEPTIER_INTRPT_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ +#define DEVEPTIER_INTRPT_NAKOUTES (_U_(0x1) << DEVEPTIER_INTRPT_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ +#define DEVEPTIER_INTRPT_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ +#define DEVEPTIER_INTRPT_NAKINES (_U_(0x1) << DEVEPTIER_INTRPT_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ +#define DEVEPTIER_INTRPT_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ +#define DEVEPTIER_INTRPT_STALLEDES (_U_(0x1) << DEVEPTIER_INTRPT_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ +#define DEVEPTIER_INTRPT_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ +#define DEVEPTIER_INTRPT_NYETDISS (_U_(0x1) << DEVEPTIER_INTRPT_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ +#define DEVEPTIER_INTRPT_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ +#define DEVEPTIER_INTRPT_STALLRQS (_U_(0x1) << DEVEPTIER_INTRPT_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ +#define DEVEPTIER_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIER_INTRPT) Register Mask */ + + +/* -------- DEVEPTIDR : (USBHS Offset: 0x220) (/W 32) Device Endpoint Interrupt Disable Register -------- */ + +#define DEVEPTIDR_OFFSET (0x220) /**< (DEVEPTIDR) Device Endpoint Interrupt Disable Register Offset */ + +#define DEVEPTIDR_TXINEC_Pos 0 /**< (DEVEPTIDR) Transmitted IN Interrupt Clear Position */ +#define DEVEPTIDR_TXINEC (_U_(0x1) << DEVEPTIDR_TXINEC_Pos) /**< (DEVEPTIDR) Transmitted IN Interrupt Clear Mask */ +#define DEVEPTIDR_RXOUTEC_Pos 1 /**< (DEVEPTIDR) Received OUT Data Interrupt Clear Position */ +#define DEVEPTIDR_RXOUTEC (_U_(0x1) << DEVEPTIDR_RXOUTEC_Pos) /**< (DEVEPTIDR) Received OUT Data Interrupt Clear Mask */ +#define DEVEPTIDR_OVERFEC_Pos 5 /**< (DEVEPTIDR) Overflow Interrupt Clear Position */ +#define DEVEPTIDR_OVERFEC (_U_(0x1) << DEVEPTIDR_OVERFEC_Pos) /**< (DEVEPTIDR) Overflow Interrupt Clear Mask */ +#define DEVEPTIDR_SHORTPACKETEC_Pos 7 /**< (DEVEPTIDR) Shortpacket Interrupt Clear Position */ +#define DEVEPTIDR_SHORTPACKETEC (_U_(0x1) << DEVEPTIDR_SHORTPACKETEC_Pos) /**< (DEVEPTIDR) Shortpacket Interrupt Clear Mask */ +#define DEVEPTIDR_NBUSYBKEC_Pos 12 /**< (DEVEPTIDR) Number of Busy Banks Interrupt Clear Position */ +#define DEVEPTIDR_NBUSYBKEC (_U_(0x1) << DEVEPTIDR_NBUSYBKEC_Pos) /**< (DEVEPTIDR) Number of Busy Banks Interrupt Clear Mask */ +#define DEVEPTIDR_FIFOCONC_Pos 14 /**< (DEVEPTIDR) FIFO Control Clear Position */ +#define DEVEPTIDR_FIFOCONC (_U_(0x1) << DEVEPTIDR_FIFOCONC_Pos) /**< (DEVEPTIDR) FIFO Control Clear Mask */ +#define DEVEPTIDR_EPDISHDMAC_Pos 16 /**< (DEVEPTIDR) Endpoint Interrupts Disable HDMA Request Clear Position */ +#define DEVEPTIDR_EPDISHDMAC (_U_(0x1) << DEVEPTIDR_EPDISHDMAC_Pos) /**< (DEVEPTIDR) Endpoint Interrupts Disable HDMA Request Clear Mask */ +#define DEVEPTIDR_Msk _U_(0x150A3) /**< (DEVEPTIDR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTIDR_CTRL_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ +#define DEVEPTIDR_CTRL_RXSTPEC (_U_(0x1) << DEVEPTIDR_CTRL_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTIDR_CTRL_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTIDR_CTRL_NAKOUTEC (_U_(0x1) << DEVEPTIDR_CTRL_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTIDR_CTRL_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ +#define DEVEPTIDR_CTRL_NAKINEC (_U_(0x1) << DEVEPTIDR_CTRL_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTIDR_CTRL_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ +#define DEVEPTIDR_CTRL_STALLEDEC (_U_(0x1) << DEVEPTIDR_CTRL_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ +#define DEVEPTIDR_CTRL_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ +#define DEVEPTIDR_CTRL_NYETDISC (_U_(0x1) << DEVEPTIDR_CTRL_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ +#define DEVEPTIDR_CTRL_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ +#define DEVEPTIDR_CTRL_STALLRQC (_U_(0x1) << DEVEPTIDR_CTRL_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ +#define DEVEPTIDR_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIDR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTIDR_ISO_UNDERFEC_Pos 2 /**< (DEVEPTIDR) Underflow Interrupt Clear Position */ +#define DEVEPTIDR_ISO_UNDERFEC (_U_(0x1) << DEVEPTIDR_ISO_UNDERFEC_Pos) /**< (DEVEPTIDR) Underflow Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_HBISOINERREC_Pos 3 /**< (DEVEPTIDR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Position */ +#define DEVEPTIDR_ISO_HBISOINERREC (_U_(0x1) << DEVEPTIDR_ISO_HBISOINERREC_Pos) /**< (DEVEPTIDR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_HBISOFLUSHEC_Pos 4 /**< (DEVEPTIDR) High Bandwidth Isochronous IN Flush Interrupt Clear Position */ +#define DEVEPTIDR_ISO_HBISOFLUSHEC (_U_(0x1) << DEVEPTIDR_ISO_HBISOFLUSHEC_Pos) /**< (DEVEPTIDR) High Bandwidth Isochronous IN Flush Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_MDATAEC_Pos 8 /**< (DEVEPTIDR) MData Interrupt Clear Position */ +#define DEVEPTIDR_ISO_MDATAEC (_U_(0x1) << DEVEPTIDR_ISO_MDATAEC_Pos) /**< (DEVEPTIDR) MData Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_DATAXEC_Pos 9 /**< (DEVEPTIDR) DataX Interrupt Clear Position */ +#define DEVEPTIDR_ISO_DATAXEC (_U_(0x1) << DEVEPTIDR_ISO_DATAXEC_Pos) /**< (DEVEPTIDR) DataX Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_ERRORTRANSEC_Pos 10 /**< (DEVEPTIDR) Transaction Error Interrupt Clear Position */ +#define DEVEPTIDR_ISO_ERRORTRANSEC (_U_(0x1) << DEVEPTIDR_ISO_ERRORTRANSEC_Pos) /**< (DEVEPTIDR) Transaction Error Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_Msk _U_(0x71C) /**< (DEVEPTIDR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTIDR_BLK_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ +#define DEVEPTIDR_BLK_RXSTPEC (_U_(0x1) << DEVEPTIDR_BLK_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTIDR_BLK_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTIDR_BLK_NAKOUTEC (_U_(0x1) << DEVEPTIDR_BLK_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTIDR_BLK_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ +#define DEVEPTIDR_BLK_NAKINEC (_U_(0x1) << DEVEPTIDR_BLK_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTIDR_BLK_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ +#define DEVEPTIDR_BLK_STALLEDEC (_U_(0x1) << DEVEPTIDR_BLK_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ +#define DEVEPTIDR_BLK_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ +#define DEVEPTIDR_BLK_NYETDISC (_U_(0x1) << DEVEPTIDR_BLK_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ +#define DEVEPTIDR_BLK_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ +#define DEVEPTIDR_BLK_STALLRQC (_U_(0x1) << DEVEPTIDR_BLK_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ +#define DEVEPTIDR_BLK_Msk _U_(0xA005C) /**< (DEVEPTIDR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTIDR_INTRPT_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ +#define DEVEPTIDR_INTRPT_RXSTPEC (_U_(0x1) << DEVEPTIDR_INTRPT_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTIDR_INTRPT_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTIDR_INTRPT_NAKOUTEC (_U_(0x1) << DEVEPTIDR_INTRPT_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTIDR_INTRPT_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ +#define DEVEPTIDR_INTRPT_NAKINEC (_U_(0x1) << DEVEPTIDR_INTRPT_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTIDR_INTRPT_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ +#define DEVEPTIDR_INTRPT_STALLEDEC (_U_(0x1) << DEVEPTIDR_INTRPT_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ +#define DEVEPTIDR_INTRPT_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ +#define DEVEPTIDR_INTRPT_NYETDISC (_U_(0x1) << DEVEPTIDR_INTRPT_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ +#define DEVEPTIDR_INTRPT_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ +#define DEVEPTIDR_INTRPT_STALLRQC (_U_(0x1) << DEVEPTIDR_INTRPT_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ +#define DEVEPTIDR_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIDR_INTRPT) Register Mask */ + + +/* -------- HSTCTRL : (USBHS Offset: 0x400) (R/W 32) Host General Control Register -------- */ + +#define HSTCTRL_OFFSET (0x400) /**< (HSTCTRL) Host General Control Register Offset */ + +#define HSTCTRL_SOFE_Pos 8 /**< (HSTCTRL) Start of Frame Generation Enable Position */ +#define HSTCTRL_SOFE (_U_(0x1) << HSTCTRL_SOFE_Pos) /**< (HSTCTRL) Start of Frame Generation Enable Mask */ +#define HSTCTRL_RESET_Pos 9 /**< (HSTCTRL) Send USB Reset Position */ +#define HSTCTRL_RESET (_U_(0x1) << HSTCTRL_RESET_Pos) /**< (HSTCTRL) Send USB Reset Mask */ +#define HSTCTRL_RESUME_Pos 10 /**< (HSTCTRL) Send USB Resume Position */ +#define HSTCTRL_RESUME (_U_(0x1) << HSTCTRL_RESUME_Pos) /**< (HSTCTRL) Send USB Resume Mask */ +#define HSTCTRL_SPDCONF_Pos 12 /**< (HSTCTRL) Mode Configuration Position */ +#define HSTCTRL_SPDCONF (_U_(0x3) << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) Mode Configuration Mask */ +#define HSTCTRL_SPDCONF_NORMAL_Val _U_(0x0) /**< (HSTCTRL) The host starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the downstream peripheral is high-speed capable. */ +#define HSTCTRL_SPDCONF_LOW_POWER_Val _U_(0x1) /**< (HSTCTRL) For a better consumption, if high speed is not needed. */ +#define HSTCTRL_SPDCONF_HIGH_SPEED_Val _U_(0x2) /**< (HSTCTRL) Forced high speed. */ +#define HSTCTRL_SPDCONF_FORCED_FS_Val _U_(0x3) /**< (HSTCTRL) The host remains in Full-speed mode whatever the peripheral speed capability. */ +#define HSTCTRL_SPDCONF_NORMAL (HSTCTRL_SPDCONF_NORMAL_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) The host starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the downstream peripheral is high-speed capable. Position */ +#define HSTCTRL_SPDCONF_LOW_POWER (HSTCTRL_SPDCONF_LOW_POWER_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) For a better consumption, if high speed is not needed. Position */ +#define HSTCTRL_SPDCONF_HIGH_SPEED (HSTCTRL_SPDCONF_HIGH_SPEED_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) Forced high speed. Position */ +#define HSTCTRL_SPDCONF_FORCED_FS (HSTCTRL_SPDCONF_FORCED_FS_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) The host remains in Full-speed mode whatever the peripheral speed capability. Position */ +#define HSTCTRL_Msk _U_(0x3700) /**< (HSTCTRL) Register Mask */ + + +/* -------- HSTISR : (USBHS Offset: 0x404) (R/ 32) Host Global Interrupt Status Register -------- */ + +#define HSTISR_OFFSET (0x404) /**< (HSTISR) Host Global Interrupt Status Register Offset */ + +#define HSTISR_DCONNI_Pos 0 /**< (HSTISR) Device Connection Interrupt Position */ +#define HSTISR_DCONNI (_U_(0x1) << HSTISR_DCONNI_Pos) /**< (HSTISR) Device Connection Interrupt Mask */ +#define HSTISR_DDISCI_Pos 1 /**< (HSTISR) Device Disconnection Interrupt Position */ +#define HSTISR_DDISCI (_U_(0x1) << HSTISR_DDISCI_Pos) /**< (HSTISR) Device Disconnection Interrupt Mask */ +#define HSTISR_RSTI_Pos 2 /**< (HSTISR) USB Reset Sent Interrupt Position */ +#define HSTISR_RSTI (_U_(0x1) << HSTISR_RSTI_Pos) /**< (HSTISR) USB Reset Sent Interrupt Mask */ +#define HSTISR_RSMEDI_Pos 3 /**< (HSTISR) Downstream Resume Sent Interrupt Position */ +#define HSTISR_RSMEDI (_U_(0x1) << HSTISR_RSMEDI_Pos) /**< (HSTISR) Downstream Resume Sent Interrupt Mask */ +#define HSTISR_RXRSMI_Pos 4 /**< (HSTISR) Upstream Resume Received Interrupt Position */ +#define HSTISR_RXRSMI (_U_(0x1) << HSTISR_RXRSMI_Pos) /**< (HSTISR) Upstream Resume Received Interrupt Mask */ +#define HSTISR_HSOFI_Pos 5 /**< (HSTISR) Host Start of Frame Interrupt Position */ +#define HSTISR_HSOFI (_U_(0x1) << HSTISR_HSOFI_Pos) /**< (HSTISR) Host Start of Frame Interrupt Mask */ +#define HSTISR_HWUPI_Pos 6 /**< (HSTISR) Host Wake-Up Interrupt Position */ +#define HSTISR_HWUPI (_U_(0x1) << HSTISR_HWUPI_Pos) /**< (HSTISR) Host Wake-Up Interrupt Mask */ +#define HSTISR_PEP_0_Pos 8 /**< (HSTISR) Pipe 0 Interrupt Position */ +#define HSTISR_PEP_0 (_U_(0x1) << HSTISR_PEP_0_Pos) /**< (HSTISR) Pipe 0 Interrupt Mask */ +#define HSTISR_PEP_1_Pos 9 /**< (HSTISR) Pipe 1 Interrupt Position */ +#define HSTISR_PEP_1 (_U_(0x1) << HSTISR_PEP_1_Pos) /**< (HSTISR) Pipe 1 Interrupt Mask */ +#define HSTISR_PEP_2_Pos 10 /**< (HSTISR) Pipe 2 Interrupt Position */ +#define HSTISR_PEP_2 (_U_(0x1) << HSTISR_PEP_2_Pos) /**< (HSTISR) Pipe 2 Interrupt Mask */ +#define HSTISR_PEP_3_Pos 11 /**< (HSTISR) Pipe 3 Interrupt Position */ +#define HSTISR_PEP_3 (_U_(0x1) << HSTISR_PEP_3_Pos) /**< (HSTISR) Pipe 3 Interrupt Mask */ +#define HSTISR_PEP_4_Pos 12 /**< (HSTISR) Pipe 4 Interrupt Position */ +#define HSTISR_PEP_4 (_U_(0x1) << HSTISR_PEP_4_Pos) /**< (HSTISR) Pipe 4 Interrupt Mask */ +#define HSTISR_PEP_5_Pos 13 /**< (HSTISR) Pipe 5 Interrupt Position */ +#define HSTISR_PEP_5 (_U_(0x1) << HSTISR_PEP_5_Pos) /**< (HSTISR) Pipe 5 Interrupt Mask */ +#define HSTISR_PEP_6_Pos 14 /**< (HSTISR) Pipe 6 Interrupt Position */ +#define HSTISR_PEP_6 (_U_(0x1) << HSTISR_PEP_6_Pos) /**< (HSTISR) Pipe 6 Interrupt Mask */ +#define HSTISR_PEP_7_Pos 15 /**< (HSTISR) Pipe 7 Interrupt Position */ +#define HSTISR_PEP_7 (_U_(0x1) << HSTISR_PEP_7_Pos) /**< (HSTISR) Pipe 7 Interrupt Mask */ +#define HSTISR_PEP_8_Pos 16 /**< (HSTISR) Pipe 8 Interrupt Position */ +#define HSTISR_PEP_8 (_U_(0x1) << HSTISR_PEP_8_Pos) /**< (HSTISR) Pipe 8 Interrupt Mask */ +#define HSTISR_PEP_9_Pos 17 /**< (HSTISR) Pipe 9 Interrupt Position */ +#define HSTISR_PEP_9 (_U_(0x1) << HSTISR_PEP_9_Pos) /**< (HSTISR) Pipe 9 Interrupt Mask */ +#define HSTISR_DMA_0_Pos 25 /**< (HSTISR) DMA Channel 0 Interrupt Position */ +#define HSTISR_DMA_0 (_U_(0x1) << HSTISR_DMA_0_Pos) /**< (HSTISR) DMA Channel 0 Interrupt Mask */ +#define HSTISR_DMA_1_Pos 26 /**< (HSTISR) DMA Channel 1 Interrupt Position */ +#define HSTISR_DMA_1 (_U_(0x1) << HSTISR_DMA_1_Pos) /**< (HSTISR) DMA Channel 1 Interrupt Mask */ +#define HSTISR_DMA_2_Pos 27 /**< (HSTISR) DMA Channel 2 Interrupt Position */ +#define HSTISR_DMA_2 (_U_(0x1) << HSTISR_DMA_2_Pos) /**< (HSTISR) DMA Channel 2 Interrupt Mask */ +#define HSTISR_DMA_3_Pos 28 /**< (HSTISR) DMA Channel 3 Interrupt Position */ +#define HSTISR_DMA_3 (_U_(0x1) << HSTISR_DMA_3_Pos) /**< (HSTISR) DMA Channel 3 Interrupt Mask */ +#define HSTISR_DMA_4_Pos 29 /**< (HSTISR) DMA Channel 4 Interrupt Position */ +#define HSTISR_DMA_4 (_U_(0x1) << HSTISR_DMA_4_Pos) /**< (HSTISR) DMA Channel 4 Interrupt Mask */ +#define HSTISR_DMA_5_Pos 30 /**< (HSTISR) DMA Channel 5 Interrupt Position */ +#define HSTISR_DMA_5 (_U_(0x1) << HSTISR_DMA_5_Pos) /**< (HSTISR) DMA Channel 5 Interrupt Mask */ +#define HSTISR_DMA_6_Pos 31 /**< (HSTISR) DMA Channel 6 Interrupt Position */ +#define HSTISR_DMA_6 (_U_(0x1) << HSTISR_DMA_6_Pos) /**< (HSTISR) DMA Channel 6 Interrupt Mask */ +#define HSTISR_Msk _U_(0xFE03FF7F) /**< (HSTISR) Register Mask */ + +#define HSTISR_PEP__Pos 8 /**< (HSTISR Position) Pipe x Interrupt */ +#define HSTISR_PEP_ (_U_(0x3FF) << HSTISR_PEP__Pos) /**< (HSTISR Mask) PEP_ */ +#define HSTISR_DMA__Pos 25 /**< (HSTISR Position) DMA Channel 6 Interrupt */ +#define HSTISR_DMA_ (_U_(0x7F) << HSTISR_DMA__Pos) /**< (HSTISR Mask) DMA_ */ + +/* -------- HSTICR : (USBHS Offset: 0x408) (/W 32) Host Global Interrupt Clear Register -------- */ + +#define HSTICR_OFFSET (0x408) /**< (HSTICR) Host Global Interrupt Clear Register Offset */ + +#define HSTICR_DCONNIC_Pos 0 /**< (HSTICR) Device Connection Interrupt Clear Position */ +#define HSTICR_DCONNIC (_U_(0x1) << HSTICR_DCONNIC_Pos) /**< (HSTICR) Device Connection Interrupt Clear Mask */ +#define HSTICR_DDISCIC_Pos 1 /**< (HSTICR) Device Disconnection Interrupt Clear Position */ +#define HSTICR_DDISCIC (_U_(0x1) << HSTICR_DDISCIC_Pos) /**< (HSTICR) Device Disconnection Interrupt Clear Mask */ +#define HSTICR_RSTIC_Pos 2 /**< (HSTICR) USB Reset Sent Interrupt Clear Position */ +#define HSTICR_RSTIC (_U_(0x1) << HSTICR_RSTIC_Pos) /**< (HSTICR) USB Reset Sent Interrupt Clear Mask */ +#define HSTICR_RSMEDIC_Pos 3 /**< (HSTICR) Downstream Resume Sent Interrupt Clear Position */ +#define HSTICR_RSMEDIC (_U_(0x1) << HSTICR_RSMEDIC_Pos) /**< (HSTICR) Downstream Resume Sent Interrupt Clear Mask */ +#define HSTICR_RXRSMIC_Pos 4 /**< (HSTICR) Upstream Resume Received Interrupt Clear Position */ +#define HSTICR_RXRSMIC (_U_(0x1) << HSTICR_RXRSMIC_Pos) /**< (HSTICR) Upstream Resume Received Interrupt Clear Mask */ +#define HSTICR_HSOFIC_Pos 5 /**< (HSTICR) Host Start of Frame Interrupt Clear Position */ +#define HSTICR_HSOFIC (_U_(0x1) << HSTICR_HSOFIC_Pos) /**< (HSTICR) Host Start of Frame Interrupt Clear Mask */ +#define HSTICR_HWUPIC_Pos 6 /**< (HSTICR) Host Wake-Up Interrupt Clear Position */ +#define HSTICR_HWUPIC (_U_(0x1) << HSTICR_HWUPIC_Pos) /**< (HSTICR) Host Wake-Up Interrupt Clear Mask */ +#define HSTICR_Msk _U_(0x7F) /**< (HSTICR) Register Mask */ + + +/* -------- HSTIFR : (USBHS Offset: 0x40c) (/W 32) Host Global Interrupt Set Register -------- */ + +#define HSTIFR_OFFSET (0x40C) /**< (HSTIFR) Host Global Interrupt Set Register Offset */ + +#define HSTIFR_DCONNIS_Pos 0 /**< (HSTIFR) Device Connection Interrupt Set Position */ +#define HSTIFR_DCONNIS (_U_(0x1) << HSTIFR_DCONNIS_Pos) /**< (HSTIFR) Device Connection Interrupt Set Mask */ +#define HSTIFR_DDISCIS_Pos 1 /**< (HSTIFR) Device Disconnection Interrupt Set Position */ +#define HSTIFR_DDISCIS (_U_(0x1) << HSTIFR_DDISCIS_Pos) /**< (HSTIFR) Device Disconnection Interrupt Set Mask */ +#define HSTIFR_RSTIS_Pos 2 /**< (HSTIFR) USB Reset Sent Interrupt Set Position */ +#define HSTIFR_RSTIS (_U_(0x1) << HSTIFR_RSTIS_Pos) /**< (HSTIFR) USB Reset Sent Interrupt Set Mask */ +#define HSTIFR_RSMEDIS_Pos 3 /**< (HSTIFR) Downstream Resume Sent Interrupt Set Position */ +#define HSTIFR_RSMEDIS (_U_(0x1) << HSTIFR_RSMEDIS_Pos) /**< (HSTIFR) Downstream Resume Sent Interrupt Set Mask */ +#define HSTIFR_RXRSMIS_Pos 4 /**< (HSTIFR) Upstream Resume Received Interrupt Set Position */ +#define HSTIFR_RXRSMIS (_U_(0x1) << HSTIFR_RXRSMIS_Pos) /**< (HSTIFR) Upstream Resume Received Interrupt Set Mask */ +#define HSTIFR_HSOFIS_Pos 5 /**< (HSTIFR) Host Start of Frame Interrupt Set Position */ +#define HSTIFR_HSOFIS (_U_(0x1) << HSTIFR_HSOFIS_Pos) /**< (HSTIFR) Host Start of Frame Interrupt Set Mask */ +#define HSTIFR_HWUPIS_Pos 6 /**< (HSTIFR) Host Wake-Up Interrupt Set Position */ +#define HSTIFR_HWUPIS (_U_(0x1) << HSTIFR_HWUPIS_Pos) /**< (HSTIFR) Host Wake-Up Interrupt Set Mask */ +#define HSTIFR_DMA_0_Pos 25 /**< (HSTIFR) DMA Channel 0 Interrupt Set Position */ +#define HSTIFR_DMA_0 (_U_(0x1) << HSTIFR_DMA_0_Pos) /**< (HSTIFR) DMA Channel 0 Interrupt Set Mask */ +#define HSTIFR_DMA_1_Pos 26 /**< (HSTIFR) DMA Channel 1 Interrupt Set Position */ +#define HSTIFR_DMA_1 (_U_(0x1) << HSTIFR_DMA_1_Pos) /**< (HSTIFR) DMA Channel 1 Interrupt Set Mask */ +#define HSTIFR_DMA_2_Pos 27 /**< (HSTIFR) DMA Channel 2 Interrupt Set Position */ +#define HSTIFR_DMA_2 (_U_(0x1) << HSTIFR_DMA_2_Pos) /**< (HSTIFR) DMA Channel 2 Interrupt Set Mask */ +#define HSTIFR_DMA_3_Pos 28 /**< (HSTIFR) DMA Channel 3 Interrupt Set Position */ +#define HSTIFR_DMA_3 (_U_(0x1) << HSTIFR_DMA_3_Pos) /**< (HSTIFR) DMA Channel 3 Interrupt Set Mask */ +#define HSTIFR_DMA_4_Pos 29 /**< (HSTIFR) DMA Channel 4 Interrupt Set Position */ +#define HSTIFR_DMA_4 (_U_(0x1) << HSTIFR_DMA_4_Pos) /**< (HSTIFR) DMA Channel 4 Interrupt Set Mask */ +#define HSTIFR_DMA_5_Pos 30 /**< (HSTIFR) DMA Channel 5 Interrupt Set Position */ +#define HSTIFR_DMA_5 (_U_(0x1) << HSTIFR_DMA_5_Pos) /**< (HSTIFR) DMA Channel 5 Interrupt Set Mask */ +#define HSTIFR_DMA_6_Pos 31 /**< (HSTIFR) DMA Channel 6 Interrupt Set Position */ +#define HSTIFR_DMA_6 (_U_(0x1) << HSTIFR_DMA_6_Pos) /**< (HSTIFR) DMA Channel 6 Interrupt Set Mask */ +#define HSTIFR_Msk _U_(0xFE00007F) /**< (HSTIFR) Register Mask */ + +#define HSTIFR_DMA__Pos 25 /**< (HSTIFR Position) DMA Channel 6 Interrupt Set */ +#define HSTIFR_DMA_ (_U_(0x7F) << HSTIFR_DMA__Pos) /**< (HSTIFR Mask) DMA_ */ + +/* -------- HSTIMR : (USBHS Offset: 0x410) (R/ 32) Host Global Interrupt Mask Register -------- */ + +#define HSTIMR_OFFSET (0x410) /**< (HSTIMR) Host Global Interrupt Mask Register Offset */ + +#define HSTIMR_DCONNIE_Pos 0 /**< (HSTIMR) Device Connection Interrupt Enable Position */ +#define HSTIMR_DCONNIE (_U_(0x1) << HSTIMR_DCONNIE_Pos) /**< (HSTIMR) Device Connection Interrupt Enable Mask */ +#define HSTIMR_DDISCIE_Pos 1 /**< (HSTIMR) Device Disconnection Interrupt Enable Position */ +#define HSTIMR_DDISCIE (_U_(0x1) << HSTIMR_DDISCIE_Pos) /**< (HSTIMR) Device Disconnection Interrupt Enable Mask */ +#define HSTIMR_RSTIE_Pos 2 /**< (HSTIMR) USB Reset Sent Interrupt Enable Position */ +#define HSTIMR_RSTIE (_U_(0x1) << HSTIMR_RSTIE_Pos) /**< (HSTIMR) USB Reset Sent Interrupt Enable Mask */ +#define HSTIMR_RSMEDIE_Pos 3 /**< (HSTIMR) Downstream Resume Sent Interrupt Enable Position */ +#define HSTIMR_RSMEDIE (_U_(0x1) << HSTIMR_RSMEDIE_Pos) /**< (HSTIMR) Downstream Resume Sent Interrupt Enable Mask */ +#define HSTIMR_RXRSMIE_Pos 4 /**< (HSTIMR) Upstream Resume Received Interrupt Enable Position */ +#define HSTIMR_RXRSMIE (_U_(0x1) << HSTIMR_RXRSMIE_Pos) /**< (HSTIMR) Upstream Resume Received Interrupt Enable Mask */ +#define HSTIMR_HSOFIE_Pos 5 /**< (HSTIMR) Host Start of Frame Interrupt Enable Position */ +#define HSTIMR_HSOFIE (_U_(0x1) << HSTIMR_HSOFIE_Pos) /**< (HSTIMR) Host Start of Frame Interrupt Enable Mask */ +#define HSTIMR_HWUPIE_Pos 6 /**< (HSTIMR) Host Wake-Up Interrupt Enable Position */ +#define HSTIMR_HWUPIE (_U_(0x1) << HSTIMR_HWUPIE_Pos) /**< (HSTIMR) Host Wake-Up Interrupt Enable Mask */ +#define HSTIMR_PEP_0_Pos 8 /**< (HSTIMR) Pipe 0 Interrupt Enable Position */ +#define HSTIMR_PEP_0 (_U_(0x1) << HSTIMR_PEP_0_Pos) /**< (HSTIMR) Pipe 0 Interrupt Enable Mask */ +#define HSTIMR_PEP_1_Pos 9 /**< (HSTIMR) Pipe 1 Interrupt Enable Position */ +#define HSTIMR_PEP_1 (_U_(0x1) << HSTIMR_PEP_1_Pos) /**< (HSTIMR) Pipe 1 Interrupt Enable Mask */ +#define HSTIMR_PEP_2_Pos 10 /**< (HSTIMR) Pipe 2 Interrupt Enable Position */ +#define HSTIMR_PEP_2 (_U_(0x1) << HSTIMR_PEP_2_Pos) /**< (HSTIMR) Pipe 2 Interrupt Enable Mask */ +#define HSTIMR_PEP_3_Pos 11 /**< (HSTIMR) Pipe 3 Interrupt Enable Position */ +#define HSTIMR_PEP_3 (_U_(0x1) << HSTIMR_PEP_3_Pos) /**< (HSTIMR) Pipe 3 Interrupt Enable Mask */ +#define HSTIMR_PEP_4_Pos 12 /**< (HSTIMR) Pipe 4 Interrupt Enable Position */ +#define HSTIMR_PEP_4 (_U_(0x1) << HSTIMR_PEP_4_Pos) /**< (HSTIMR) Pipe 4 Interrupt Enable Mask */ +#define HSTIMR_PEP_5_Pos 13 /**< (HSTIMR) Pipe 5 Interrupt Enable Position */ +#define HSTIMR_PEP_5 (_U_(0x1) << HSTIMR_PEP_5_Pos) /**< (HSTIMR) Pipe 5 Interrupt Enable Mask */ +#define HSTIMR_PEP_6_Pos 14 /**< (HSTIMR) Pipe 6 Interrupt Enable Position */ +#define HSTIMR_PEP_6 (_U_(0x1) << HSTIMR_PEP_6_Pos) /**< (HSTIMR) Pipe 6 Interrupt Enable Mask */ +#define HSTIMR_PEP_7_Pos 15 /**< (HSTIMR) Pipe 7 Interrupt Enable Position */ +#define HSTIMR_PEP_7 (_U_(0x1) << HSTIMR_PEP_7_Pos) /**< (HSTIMR) Pipe 7 Interrupt Enable Mask */ +#define HSTIMR_PEP_8_Pos 16 /**< (HSTIMR) Pipe 8 Interrupt Enable Position */ +#define HSTIMR_PEP_8 (_U_(0x1) << HSTIMR_PEP_8_Pos) /**< (HSTIMR) Pipe 8 Interrupt Enable Mask */ +#define HSTIMR_PEP_9_Pos 17 /**< (HSTIMR) Pipe 9 Interrupt Enable Position */ +#define HSTIMR_PEP_9 (_U_(0x1) << HSTIMR_PEP_9_Pos) /**< (HSTIMR) Pipe 9 Interrupt Enable Mask */ +#define HSTIMR_DMA_0_Pos 25 /**< (HSTIMR) DMA Channel 0 Interrupt Enable Position */ +#define HSTIMR_DMA_0 (_U_(0x1) << HSTIMR_DMA_0_Pos) /**< (HSTIMR) DMA Channel 0 Interrupt Enable Mask */ +#define HSTIMR_DMA_1_Pos 26 /**< (HSTIMR) DMA Channel 1 Interrupt Enable Position */ +#define HSTIMR_DMA_1 (_U_(0x1) << HSTIMR_DMA_1_Pos) /**< (HSTIMR) DMA Channel 1 Interrupt Enable Mask */ +#define HSTIMR_DMA_2_Pos 27 /**< (HSTIMR) DMA Channel 2 Interrupt Enable Position */ +#define HSTIMR_DMA_2 (_U_(0x1) << HSTIMR_DMA_2_Pos) /**< (HSTIMR) DMA Channel 2 Interrupt Enable Mask */ +#define HSTIMR_DMA_3_Pos 28 /**< (HSTIMR) DMA Channel 3 Interrupt Enable Position */ +#define HSTIMR_DMA_3 (_U_(0x1) << HSTIMR_DMA_3_Pos) /**< (HSTIMR) DMA Channel 3 Interrupt Enable Mask */ +#define HSTIMR_DMA_4_Pos 29 /**< (HSTIMR) DMA Channel 4 Interrupt Enable Position */ +#define HSTIMR_DMA_4 (_U_(0x1) << HSTIMR_DMA_4_Pos) /**< (HSTIMR) DMA Channel 4 Interrupt Enable Mask */ +#define HSTIMR_DMA_5_Pos 30 /**< (HSTIMR) DMA Channel 5 Interrupt Enable Position */ +#define HSTIMR_DMA_5 (_U_(0x1) << HSTIMR_DMA_5_Pos) /**< (HSTIMR) DMA Channel 5 Interrupt Enable Mask */ +#define HSTIMR_DMA_6_Pos 31 /**< (HSTIMR) DMA Channel 6 Interrupt Enable Position */ +#define HSTIMR_DMA_6 (_U_(0x1) << HSTIMR_DMA_6_Pos) /**< (HSTIMR) DMA Channel 6 Interrupt Enable Mask */ +#define HSTIMR_Msk _U_(0xFE03FF7F) /**< (HSTIMR) Register Mask */ + +#define HSTIMR_PEP__Pos 8 /**< (HSTIMR Position) Pipe x Interrupt Enable */ +#define HSTIMR_PEP_ (_U_(0x3FF) << HSTIMR_PEP__Pos) /**< (HSTIMR Mask) PEP_ */ +#define HSTIMR_DMA__Pos 25 /**< (HSTIMR Position) DMA Channel 6 Interrupt Enable */ +#define HSTIMR_DMA_ (_U_(0x7F) << HSTIMR_DMA__Pos) /**< (HSTIMR Mask) DMA_ */ + +/* -------- HSTIDR : (USBHS Offset: 0x414) (/W 32) Host Global Interrupt Disable Register -------- */ + +#define HSTIDR_OFFSET (0x414) /**< (HSTIDR) Host Global Interrupt Disable Register Offset */ + +#define HSTIDR_DCONNIEC_Pos 0 /**< (HSTIDR) Device Connection Interrupt Disable Position */ +#define HSTIDR_DCONNIEC (_U_(0x1) << HSTIDR_DCONNIEC_Pos) /**< (HSTIDR) Device Connection Interrupt Disable Mask */ +#define HSTIDR_DDISCIEC_Pos 1 /**< (HSTIDR) Device Disconnection Interrupt Disable Position */ +#define HSTIDR_DDISCIEC (_U_(0x1) << HSTIDR_DDISCIEC_Pos) /**< (HSTIDR) Device Disconnection Interrupt Disable Mask */ +#define HSTIDR_RSTIEC_Pos 2 /**< (HSTIDR) USB Reset Sent Interrupt Disable Position */ +#define HSTIDR_RSTIEC (_U_(0x1) << HSTIDR_RSTIEC_Pos) /**< (HSTIDR) USB Reset Sent Interrupt Disable Mask */ +#define HSTIDR_RSMEDIEC_Pos 3 /**< (HSTIDR) Downstream Resume Sent Interrupt Disable Position */ +#define HSTIDR_RSMEDIEC (_U_(0x1) << HSTIDR_RSMEDIEC_Pos) /**< (HSTIDR) Downstream Resume Sent Interrupt Disable Mask */ +#define HSTIDR_RXRSMIEC_Pos 4 /**< (HSTIDR) Upstream Resume Received Interrupt Disable Position */ +#define HSTIDR_RXRSMIEC (_U_(0x1) << HSTIDR_RXRSMIEC_Pos) /**< (HSTIDR) Upstream Resume Received Interrupt Disable Mask */ +#define HSTIDR_HSOFIEC_Pos 5 /**< (HSTIDR) Host Start of Frame Interrupt Disable Position */ +#define HSTIDR_HSOFIEC (_U_(0x1) << HSTIDR_HSOFIEC_Pos) /**< (HSTIDR) Host Start of Frame Interrupt Disable Mask */ +#define HSTIDR_HWUPIEC_Pos 6 /**< (HSTIDR) Host Wake-Up Interrupt Disable Position */ +#define HSTIDR_HWUPIEC (_U_(0x1) << HSTIDR_HWUPIEC_Pos) /**< (HSTIDR) Host Wake-Up Interrupt Disable Mask */ +#define HSTIDR_PEP_0_Pos 8 /**< (HSTIDR) Pipe 0 Interrupt Disable Position */ +#define HSTIDR_PEP_0 (_U_(0x1) << HSTIDR_PEP_0_Pos) /**< (HSTIDR) Pipe 0 Interrupt Disable Mask */ +#define HSTIDR_PEP_1_Pos 9 /**< (HSTIDR) Pipe 1 Interrupt Disable Position */ +#define HSTIDR_PEP_1 (_U_(0x1) << HSTIDR_PEP_1_Pos) /**< (HSTIDR) Pipe 1 Interrupt Disable Mask */ +#define HSTIDR_PEP_2_Pos 10 /**< (HSTIDR) Pipe 2 Interrupt Disable Position */ +#define HSTIDR_PEP_2 (_U_(0x1) << HSTIDR_PEP_2_Pos) /**< (HSTIDR) Pipe 2 Interrupt Disable Mask */ +#define HSTIDR_PEP_3_Pos 11 /**< (HSTIDR) Pipe 3 Interrupt Disable Position */ +#define HSTIDR_PEP_3 (_U_(0x1) << HSTIDR_PEP_3_Pos) /**< (HSTIDR) Pipe 3 Interrupt Disable Mask */ +#define HSTIDR_PEP_4_Pos 12 /**< (HSTIDR) Pipe 4 Interrupt Disable Position */ +#define HSTIDR_PEP_4 (_U_(0x1) << HSTIDR_PEP_4_Pos) /**< (HSTIDR) Pipe 4 Interrupt Disable Mask */ +#define HSTIDR_PEP_5_Pos 13 /**< (HSTIDR) Pipe 5 Interrupt Disable Position */ +#define HSTIDR_PEP_5 (_U_(0x1) << HSTIDR_PEP_5_Pos) /**< (HSTIDR) Pipe 5 Interrupt Disable Mask */ +#define HSTIDR_PEP_6_Pos 14 /**< (HSTIDR) Pipe 6 Interrupt Disable Position */ +#define HSTIDR_PEP_6 (_U_(0x1) << HSTIDR_PEP_6_Pos) /**< (HSTIDR) Pipe 6 Interrupt Disable Mask */ +#define HSTIDR_PEP_7_Pos 15 /**< (HSTIDR) Pipe 7 Interrupt Disable Position */ +#define HSTIDR_PEP_7 (_U_(0x1) << HSTIDR_PEP_7_Pos) /**< (HSTIDR) Pipe 7 Interrupt Disable Mask */ +#define HSTIDR_PEP_8_Pos 16 /**< (HSTIDR) Pipe 8 Interrupt Disable Position */ +#define HSTIDR_PEP_8 (_U_(0x1) << HSTIDR_PEP_8_Pos) /**< (HSTIDR) Pipe 8 Interrupt Disable Mask */ +#define HSTIDR_PEP_9_Pos 17 /**< (HSTIDR) Pipe 9 Interrupt Disable Position */ +#define HSTIDR_PEP_9 (_U_(0x1) << HSTIDR_PEP_9_Pos) /**< (HSTIDR) Pipe 9 Interrupt Disable Mask */ +#define HSTIDR_DMA_0_Pos 25 /**< (HSTIDR) DMA Channel 0 Interrupt Disable Position */ +#define HSTIDR_DMA_0 (_U_(0x1) << HSTIDR_DMA_0_Pos) /**< (HSTIDR) DMA Channel 0 Interrupt Disable Mask */ +#define HSTIDR_DMA_1_Pos 26 /**< (HSTIDR) DMA Channel 1 Interrupt Disable Position */ +#define HSTIDR_DMA_1 (_U_(0x1) << HSTIDR_DMA_1_Pos) /**< (HSTIDR) DMA Channel 1 Interrupt Disable Mask */ +#define HSTIDR_DMA_2_Pos 27 /**< (HSTIDR) DMA Channel 2 Interrupt Disable Position */ +#define HSTIDR_DMA_2 (_U_(0x1) << HSTIDR_DMA_2_Pos) /**< (HSTIDR) DMA Channel 2 Interrupt Disable Mask */ +#define HSTIDR_DMA_3_Pos 28 /**< (HSTIDR) DMA Channel 3 Interrupt Disable Position */ +#define HSTIDR_DMA_3 (_U_(0x1) << HSTIDR_DMA_3_Pos) /**< (HSTIDR) DMA Channel 3 Interrupt Disable Mask */ +#define HSTIDR_DMA_4_Pos 29 /**< (HSTIDR) DMA Channel 4 Interrupt Disable Position */ +#define HSTIDR_DMA_4 (_U_(0x1) << HSTIDR_DMA_4_Pos) /**< (HSTIDR) DMA Channel 4 Interrupt Disable Mask */ +#define HSTIDR_DMA_5_Pos 30 /**< (HSTIDR) DMA Channel 5 Interrupt Disable Position */ +#define HSTIDR_DMA_5 (_U_(0x1) << HSTIDR_DMA_5_Pos) /**< (HSTIDR) DMA Channel 5 Interrupt Disable Mask */ +#define HSTIDR_DMA_6_Pos 31 /**< (HSTIDR) DMA Channel 6 Interrupt Disable Position */ +#define HSTIDR_DMA_6 (_U_(0x1) << HSTIDR_DMA_6_Pos) /**< (HSTIDR) DMA Channel 6 Interrupt Disable Mask */ +#define HSTIDR_Msk _U_(0xFE03FF7F) /**< (HSTIDR) Register Mask */ + +#define HSTIDR_PEP__Pos 8 /**< (HSTIDR Position) Pipe x Interrupt Disable */ +#define HSTIDR_PEP_ (_U_(0x3FF) << HSTIDR_PEP__Pos) /**< (HSTIDR Mask) PEP_ */ +#define HSTIDR_DMA__Pos 25 /**< (HSTIDR Position) DMA Channel 6 Interrupt Disable */ +#define HSTIDR_DMA_ (_U_(0x7F) << HSTIDR_DMA__Pos) /**< (HSTIDR Mask) DMA_ */ + +/* -------- HSTIER : (USBHS Offset: 0x418) (/W 32) Host Global Interrupt Enable Register -------- */ + +#define HSTIER_OFFSET (0x418) /**< (HSTIER) Host Global Interrupt Enable Register Offset */ + +#define HSTIER_DCONNIES_Pos 0 /**< (HSTIER) Device Connection Interrupt Enable Position */ +#define HSTIER_DCONNIES (_U_(0x1) << HSTIER_DCONNIES_Pos) /**< (HSTIER) Device Connection Interrupt Enable Mask */ +#define HSTIER_DDISCIES_Pos 1 /**< (HSTIER) Device Disconnection Interrupt Enable Position */ +#define HSTIER_DDISCIES (_U_(0x1) << HSTIER_DDISCIES_Pos) /**< (HSTIER) Device Disconnection Interrupt Enable Mask */ +#define HSTIER_RSTIES_Pos 2 /**< (HSTIER) USB Reset Sent Interrupt Enable Position */ +#define HSTIER_RSTIES (_U_(0x1) << HSTIER_RSTIES_Pos) /**< (HSTIER) USB Reset Sent Interrupt Enable Mask */ +#define HSTIER_RSMEDIES_Pos 3 /**< (HSTIER) Downstream Resume Sent Interrupt Enable Position */ +#define HSTIER_RSMEDIES (_U_(0x1) << HSTIER_RSMEDIES_Pos) /**< (HSTIER) Downstream Resume Sent Interrupt Enable Mask */ +#define HSTIER_RXRSMIES_Pos 4 /**< (HSTIER) Upstream Resume Received Interrupt Enable Position */ +#define HSTIER_RXRSMIES (_U_(0x1) << HSTIER_RXRSMIES_Pos) /**< (HSTIER) Upstream Resume Received Interrupt Enable Mask */ +#define HSTIER_HSOFIES_Pos 5 /**< (HSTIER) Host Start of Frame Interrupt Enable Position */ +#define HSTIER_HSOFIES (_U_(0x1) << HSTIER_HSOFIES_Pos) /**< (HSTIER) Host Start of Frame Interrupt Enable Mask */ +#define HSTIER_HWUPIES_Pos 6 /**< (HSTIER) Host Wake-Up Interrupt Enable Position */ +#define HSTIER_HWUPIES (_U_(0x1) << HSTIER_HWUPIES_Pos) /**< (HSTIER) Host Wake-Up Interrupt Enable Mask */ +#define HSTIER_PEP_0_Pos 8 /**< (HSTIER) Pipe 0 Interrupt Enable Position */ +#define HSTIER_PEP_0 (_U_(0x1) << HSTIER_PEP_0_Pos) /**< (HSTIER) Pipe 0 Interrupt Enable Mask */ +#define HSTIER_PEP_1_Pos 9 /**< (HSTIER) Pipe 1 Interrupt Enable Position */ +#define HSTIER_PEP_1 (_U_(0x1) << HSTIER_PEP_1_Pos) /**< (HSTIER) Pipe 1 Interrupt Enable Mask */ +#define HSTIER_PEP_2_Pos 10 /**< (HSTIER) Pipe 2 Interrupt Enable Position */ +#define HSTIER_PEP_2 (_U_(0x1) << HSTIER_PEP_2_Pos) /**< (HSTIER) Pipe 2 Interrupt Enable Mask */ +#define HSTIER_PEP_3_Pos 11 /**< (HSTIER) Pipe 3 Interrupt Enable Position */ +#define HSTIER_PEP_3 (_U_(0x1) << HSTIER_PEP_3_Pos) /**< (HSTIER) Pipe 3 Interrupt Enable Mask */ +#define HSTIER_PEP_4_Pos 12 /**< (HSTIER) Pipe 4 Interrupt Enable Position */ +#define HSTIER_PEP_4 (_U_(0x1) << HSTIER_PEP_4_Pos) /**< (HSTIER) Pipe 4 Interrupt Enable Mask */ +#define HSTIER_PEP_5_Pos 13 /**< (HSTIER) Pipe 5 Interrupt Enable Position */ +#define HSTIER_PEP_5 (_U_(0x1) << HSTIER_PEP_5_Pos) /**< (HSTIER) Pipe 5 Interrupt Enable Mask */ +#define HSTIER_PEP_6_Pos 14 /**< (HSTIER) Pipe 6 Interrupt Enable Position */ +#define HSTIER_PEP_6 (_U_(0x1) << HSTIER_PEP_6_Pos) /**< (HSTIER) Pipe 6 Interrupt Enable Mask */ +#define HSTIER_PEP_7_Pos 15 /**< (HSTIER) Pipe 7 Interrupt Enable Position */ +#define HSTIER_PEP_7 (_U_(0x1) << HSTIER_PEP_7_Pos) /**< (HSTIER) Pipe 7 Interrupt Enable Mask */ +#define HSTIER_PEP_8_Pos 16 /**< (HSTIER) Pipe 8 Interrupt Enable Position */ +#define HSTIER_PEP_8 (_U_(0x1) << HSTIER_PEP_8_Pos) /**< (HSTIER) Pipe 8 Interrupt Enable Mask */ +#define HSTIER_PEP_9_Pos 17 /**< (HSTIER) Pipe 9 Interrupt Enable Position */ +#define HSTIER_PEP_9 (_U_(0x1) << HSTIER_PEP_9_Pos) /**< (HSTIER) Pipe 9 Interrupt Enable Mask */ +#define HSTIER_DMA_0_Pos 25 /**< (HSTIER) DMA Channel 0 Interrupt Enable Position */ +#define HSTIER_DMA_0 (_U_(0x1) << HSTIER_DMA_0_Pos) /**< (HSTIER) DMA Channel 0 Interrupt Enable Mask */ +#define HSTIER_DMA_1_Pos 26 /**< (HSTIER) DMA Channel 1 Interrupt Enable Position */ +#define HSTIER_DMA_1 (_U_(0x1) << HSTIER_DMA_1_Pos) /**< (HSTIER) DMA Channel 1 Interrupt Enable Mask */ +#define HSTIER_DMA_2_Pos 27 /**< (HSTIER) DMA Channel 2 Interrupt Enable Position */ +#define HSTIER_DMA_2 (_U_(0x1) << HSTIER_DMA_2_Pos) /**< (HSTIER) DMA Channel 2 Interrupt Enable Mask */ +#define HSTIER_DMA_3_Pos 28 /**< (HSTIER) DMA Channel 3 Interrupt Enable Position */ +#define HSTIER_DMA_3 (_U_(0x1) << HSTIER_DMA_3_Pos) /**< (HSTIER) DMA Channel 3 Interrupt Enable Mask */ +#define HSTIER_DMA_4_Pos 29 /**< (HSTIER) DMA Channel 4 Interrupt Enable Position */ +#define HSTIER_DMA_4 (_U_(0x1) << HSTIER_DMA_4_Pos) /**< (HSTIER) DMA Channel 4 Interrupt Enable Mask */ +#define HSTIER_DMA_5_Pos 30 /**< (HSTIER) DMA Channel 5 Interrupt Enable Position */ +#define HSTIER_DMA_5 (_U_(0x1) << HSTIER_DMA_5_Pos) /**< (HSTIER) DMA Channel 5 Interrupt Enable Mask */ +#define HSTIER_DMA_6_Pos 31 /**< (HSTIER) DMA Channel 6 Interrupt Enable Position */ +#define HSTIER_DMA_6 (_U_(0x1) << HSTIER_DMA_6_Pos) /**< (HSTIER) DMA Channel 6 Interrupt Enable Mask */ +#define HSTIER_Msk _U_(0xFE03FF7F) /**< (HSTIER) Register Mask */ + +#define HSTIER_PEP__Pos 8 /**< (HSTIER Position) Pipe x Interrupt Enable */ +#define HSTIER_PEP_ (_U_(0x3FF) << HSTIER_PEP__Pos) /**< (HSTIER Mask) PEP_ */ +#define HSTIER_DMA__Pos 25 /**< (HSTIER Position) DMA Channel 6 Interrupt Enable */ +#define HSTIER_DMA_ (_U_(0x7F) << HSTIER_DMA__Pos) /**< (HSTIER Mask) DMA_ */ + +/* -------- HSTPIP : (USBHS Offset: 0x41c) (R/W 32) Host Pipe Register -------- */ + +#define HSTPIP_OFFSET (0x41C) /**< (HSTPIP) Host Pipe Register Offset */ + +#define HSTPIP_PEN0_Pos 0 /**< (HSTPIP) Pipe 0 Enable Position */ +#define HSTPIP_PEN0 (_U_(0x1) << HSTPIP_PEN0_Pos) /**< (HSTPIP) Pipe 0 Enable Mask */ +#define HSTPIP_PEN1_Pos 1 /**< (HSTPIP) Pipe 1 Enable Position */ +#define HSTPIP_PEN1 (_U_(0x1) << HSTPIP_PEN1_Pos) /**< (HSTPIP) Pipe 1 Enable Mask */ +#define HSTPIP_PEN2_Pos 2 /**< (HSTPIP) Pipe 2 Enable Position */ +#define HSTPIP_PEN2 (_U_(0x1) << HSTPIP_PEN2_Pos) /**< (HSTPIP) Pipe 2 Enable Mask */ +#define HSTPIP_PEN3_Pos 3 /**< (HSTPIP) Pipe 3 Enable Position */ +#define HSTPIP_PEN3 (_U_(0x1) << HSTPIP_PEN3_Pos) /**< (HSTPIP) Pipe 3 Enable Mask */ +#define HSTPIP_PEN4_Pos 4 /**< (HSTPIP) Pipe 4 Enable Position */ +#define HSTPIP_PEN4 (_U_(0x1) << HSTPIP_PEN4_Pos) /**< (HSTPIP) Pipe 4 Enable Mask */ +#define HSTPIP_PEN5_Pos 5 /**< (HSTPIP) Pipe 5 Enable Position */ +#define HSTPIP_PEN5 (_U_(0x1) << HSTPIP_PEN5_Pos) /**< (HSTPIP) Pipe 5 Enable Mask */ +#define HSTPIP_PEN6_Pos 6 /**< (HSTPIP) Pipe 6 Enable Position */ +#define HSTPIP_PEN6 (_U_(0x1) << HSTPIP_PEN6_Pos) /**< (HSTPIP) Pipe 6 Enable Mask */ +#define HSTPIP_PEN7_Pos 7 /**< (HSTPIP) Pipe 7 Enable Position */ +#define HSTPIP_PEN7 (_U_(0x1) << HSTPIP_PEN7_Pos) /**< (HSTPIP) Pipe 7 Enable Mask */ +#define HSTPIP_PEN8_Pos 8 /**< (HSTPIP) Pipe 8 Enable Position */ +#define HSTPIP_PEN8 (_U_(0x1) << HSTPIP_PEN8_Pos) /**< (HSTPIP) Pipe 8 Enable Mask */ +#define HSTPIP_PRST0_Pos 16 /**< (HSTPIP) Pipe 0 Reset Position */ +#define HSTPIP_PRST0 (_U_(0x1) << HSTPIP_PRST0_Pos) /**< (HSTPIP) Pipe 0 Reset Mask */ +#define HSTPIP_PRST1_Pos 17 /**< (HSTPIP) Pipe 1 Reset Position */ +#define HSTPIP_PRST1 (_U_(0x1) << HSTPIP_PRST1_Pos) /**< (HSTPIP) Pipe 1 Reset Mask */ +#define HSTPIP_PRST2_Pos 18 /**< (HSTPIP) Pipe 2 Reset Position */ +#define HSTPIP_PRST2 (_U_(0x1) << HSTPIP_PRST2_Pos) /**< (HSTPIP) Pipe 2 Reset Mask */ +#define HSTPIP_PRST3_Pos 19 /**< (HSTPIP) Pipe 3 Reset Position */ +#define HSTPIP_PRST3 (_U_(0x1) << HSTPIP_PRST3_Pos) /**< (HSTPIP) Pipe 3 Reset Mask */ +#define HSTPIP_PRST4_Pos 20 /**< (HSTPIP) Pipe 4 Reset Position */ +#define HSTPIP_PRST4 (_U_(0x1) << HSTPIP_PRST4_Pos) /**< (HSTPIP) Pipe 4 Reset Mask */ +#define HSTPIP_PRST5_Pos 21 /**< (HSTPIP) Pipe 5 Reset Position */ +#define HSTPIP_PRST5 (_U_(0x1) << HSTPIP_PRST5_Pos) /**< (HSTPIP) Pipe 5 Reset Mask */ +#define HSTPIP_PRST6_Pos 22 /**< (HSTPIP) Pipe 6 Reset Position */ +#define HSTPIP_PRST6 (_U_(0x1) << HSTPIP_PRST6_Pos) /**< (HSTPIP) Pipe 6 Reset Mask */ +#define HSTPIP_PRST7_Pos 23 /**< (HSTPIP) Pipe 7 Reset Position */ +#define HSTPIP_PRST7 (_U_(0x1) << HSTPIP_PRST7_Pos) /**< (HSTPIP) Pipe 7 Reset Mask */ +#define HSTPIP_PRST8_Pos 24 /**< (HSTPIP) Pipe 8 Reset Position */ +#define HSTPIP_PRST8 (_U_(0x1) << HSTPIP_PRST8_Pos) /**< (HSTPIP) Pipe 8 Reset Mask */ +#define HSTPIP_Msk _U_(0x1FF01FF) /**< (HSTPIP) Register Mask */ + +#define HSTPIP_PEN_Pos 0 /**< (HSTPIP Position) Pipe x Enable */ +#define HSTPIP_PEN (_U_(0x1FF) << HSTPIP_PEN_Pos) /**< (HSTPIP Mask) PEN */ +#define HSTPIP_PRST_Pos 16 /**< (HSTPIP Position) Pipe 8 Reset */ +#define HSTPIP_PRST (_U_(0x1FF) << HSTPIP_PRST_Pos) /**< (HSTPIP Mask) PRST */ + +/* -------- HSTFNUM : (USBHS Offset: 0x420) (R/W 32) Host Frame Number Register -------- */ + +#define HSTFNUM_OFFSET (0x420) /**< (HSTFNUM) Host Frame Number Register Offset */ + +#define HSTFNUM_MFNUM_Pos 0 /**< (HSTFNUM) Micro Frame Number Position */ +#define HSTFNUM_MFNUM (_U_(0x7) << HSTFNUM_MFNUM_Pos) /**< (HSTFNUM) Micro Frame Number Mask */ +#define HSTFNUM_FNUM_Pos 3 /**< (HSTFNUM) Frame Number Position */ +#define HSTFNUM_FNUM (_U_(0x7FF) << HSTFNUM_FNUM_Pos) /**< (HSTFNUM) Frame Number Mask */ +#define HSTFNUM_FLENHIGH_Pos 16 /**< (HSTFNUM) Frame Length Position */ +#define HSTFNUM_FLENHIGH (_U_(0xFF) << HSTFNUM_FLENHIGH_Pos) /**< (HSTFNUM) Frame Length Mask */ +#define HSTFNUM_Msk _U_(0xFF3FFF) /**< (HSTFNUM) Register Mask */ + + +/* -------- HSTADDR1 : (USBHS Offset: 0x424) (R/W 32) Host Address 1 Register -------- */ + +#define HSTADDR1_OFFSET (0x424) /**< (HSTADDR1) Host Address 1 Register Offset */ + +#define HSTADDR1_HSTADDRP0_Pos 0 /**< (HSTADDR1) USB Host Address Position */ +#define HSTADDR1_HSTADDRP0 (_U_(0x7F) << HSTADDR1_HSTADDRP0_Pos) /**< (HSTADDR1) USB Host Address Mask */ +#define HSTADDR1_HSTADDRP1_Pos 8 /**< (HSTADDR1) USB Host Address Position */ +#define HSTADDR1_HSTADDRP1 (_U_(0x7F) << HSTADDR1_HSTADDRP1_Pos) /**< (HSTADDR1) USB Host Address Mask */ +#define HSTADDR1_HSTADDRP2_Pos 16 /**< (HSTADDR1) USB Host Address Position */ +#define HSTADDR1_HSTADDRP2 (_U_(0x7F) << HSTADDR1_HSTADDRP2_Pos) /**< (HSTADDR1) USB Host Address Mask */ +#define HSTADDR1_HSTADDRP3_Pos 24 /**< (HSTADDR1) USB Host Address Position */ +#define HSTADDR1_HSTADDRP3 (_U_(0x7F) << HSTADDR1_HSTADDRP3_Pos) /**< (HSTADDR1) USB Host Address Mask */ +#define HSTADDR1_Msk _U_(0x7F7F7F7F) /**< (HSTADDR1) Register Mask */ + + +/* -------- HSTADDR2 : (USBHS Offset: 0x428) (R/W 32) Host Address 2 Register -------- */ + +#define HSTADDR2_OFFSET (0x428) /**< (HSTADDR2) Host Address 2 Register Offset */ + +#define HSTADDR2_HSTADDRP4_Pos 0 /**< (HSTADDR2) USB Host Address Position */ +#define HSTADDR2_HSTADDRP4 (_U_(0x7F) << HSTADDR2_HSTADDRP4_Pos) /**< (HSTADDR2) USB Host Address Mask */ +#define HSTADDR2_HSTADDRP5_Pos 8 /**< (HSTADDR2) USB Host Address Position */ +#define HSTADDR2_HSTADDRP5 (_U_(0x7F) << HSTADDR2_HSTADDRP5_Pos) /**< (HSTADDR2) USB Host Address Mask */ +#define HSTADDR2_HSTADDRP6_Pos 16 /**< (HSTADDR2) USB Host Address Position */ +#define HSTADDR2_HSTADDRP6 (_U_(0x7F) << HSTADDR2_HSTADDRP6_Pos) /**< (HSTADDR2) USB Host Address Mask */ +#define HSTADDR2_HSTADDRP7_Pos 24 /**< (HSTADDR2) USB Host Address Position */ +#define HSTADDR2_HSTADDRP7 (_U_(0x7F) << HSTADDR2_HSTADDRP7_Pos) /**< (HSTADDR2) USB Host Address Mask */ +#define HSTADDR2_Msk _U_(0x7F7F7F7F) /**< (HSTADDR2) Register Mask */ + + +/* -------- HSTADDR3 : (USBHS Offset: 0x42c) (R/W 32) Host Address 3 Register -------- */ + +#define HSTADDR3_OFFSET (0x42C) /**< (HSTADDR3) Host Address 3 Register Offset */ + +#define HSTADDR3_HSTADDRP8_Pos 0 /**< (HSTADDR3) USB Host Address Position */ +#define HSTADDR3_HSTADDRP8 (_U_(0x7F) << HSTADDR3_HSTADDRP8_Pos) /**< (HSTADDR3) USB Host Address Mask */ +#define HSTADDR3_HSTADDRP9_Pos 8 /**< (HSTADDR3) USB Host Address Position */ +#define HSTADDR3_HSTADDRP9 (_U_(0x7F) << HSTADDR3_HSTADDRP9_Pos) /**< (HSTADDR3) USB Host Address Mask */ +#define HSTADDR3_Msk _U_(0x7F7F) /**< (HSTADDR3) Register Mask */ + + +/* -------- HSTPIPCFG : (USBHS Offset: 0x500) (R/W 32) Host Pipe Configuration Register -------- */ + +#define HSTPIPCFG_OFFSET (0x500) /**< (HSTPIPCFG) Host Pipe Configuration Register Offset */ + +#define HSTPIPCFG_ALLOC_Pos 1 /**< (HSTPIPCFG) Pipe Memory Allocate Position */ +#define HSTPIPCFG_ALLOC (_U_(0x1) << HSTPIPCFG_ALLOC_Pos) /**< (HSTPIPCFG) Pipe Memory Allocate Mask */ +#define HSTPIPCFG_PBK_Pos 2 /**< (HSTPIPCFG) Pipe Banks Position */ +#define HSTPIPCFG_PBK (_U_(0x3) << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Pipe Banks Mask */ +#define HSTPIPCFG_PBK_1_BANK_Val _U_(0x0) /**< (HSTPIPCFG) Single-bank pipe */ +#define HSTPIPCFG_PBK_2_BANK_Val _U_(0x1) /**< (HSTPIPCFG) Double-bank pipe */ +#define HSTPIPCFG_PBK_3_BANK_Val _U_(0x2) /**< (HSTPIPCFG) Triple-bank pipe */ +#define HSTPIPCFG_PBK_1_BANK (HSTPIPCFG_PBK_1_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Single-bank pipe Position */ +#define HSTPIPCFG_PBK_2_BANK (HSTPIPCFG_PBK_2_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Double-bank pipe Position */ +#define HSTPIPCFG_PBK_3_BANK (HSTPIPCFG_PBK_3_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Triple-bank pipe Position */ +#define HSTPIPCFG_PSIZE_Pos 4 /**< (HSTPIPCFG) Pipe Size Position */ +#define HSTPIPCFG_PSIZE (_U_(0x7) << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) Pipe Size Mask */ +#define HSTPIPCFG_PSIZE_8_BYTE_Val _U_(0x0) /**< (HSTPIPCFG) 8 bytes */ +#define HSTPIPCFG_PSIZE_16_BYTE_Val _U_(0x1) /**< (HSTPIPCFG) 16 bytes */ +#define HSTPIPCFG_PSIZE_32_BYTE_Val _U_(0x2) /**< (HSTPIPCFG) 32 bytes */ +#define HSTPIPCFG_PSIZE_64_BYTE_Val _U_(0x3) /**< (HSTPIPCFG) 64 bytes */ +#define HSTPIPCFG_PSIZE_128_BYTE_Val _U_(0x4) /**< (HSTPIPCFG) 128 bytes */ +#define HSTPIPCFG_PSIZE_256_BYTE_Val _U_(0x5) /**< (HSTPIPCFG) 256 bytes */ +#define HSTPIPCFG_PSIZE_512_BYTE_Val _U_(0x6) /**< (HSTPIPCFG) 512 bytes */ +#define HSTPIPCFG_PSIZE_1024_BYTE_Val _U_(0x7) /**< (HSTPIPCFG) 1024 bytes */ +#define HSTPIPCFG_PSIZE_8_BYTE (HSTPIPCFG_PSIZE_8_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 8 bytes Position */ +#define HSTPIPCFG_PSIZE_16_BYTE (HSTPIPCFG_PSIZE_16_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 16 bytes Position */ +#define HSTPIPCFG_PSIZE_32_BYTE (HSTPIPCFG_PSIZE_32_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 32 bytes Position */ +#define HSTPIPCFG_PSIZE_64_BYTE (HSTPIPCFG_PSIZE_64_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 64 bytes Position */ +#define HSTPIPCFG_PSIZE_128_BYTE (HSTPIPCFG_PSIZE_128_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 128 bytes Position */ +#define HSTPIPCFG_PSIZE_256_BYTE (HSTPIPCFG_PSIZE_256_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 256 bytes Position */ +#define HSTPIPCFG_PSIZE_512_BYTE (HSTPIPCFG_PSIZE_512_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 512 bytes Position */ +#define HSTPIPCFG_PSIZE_1024_BYTE (HSTPIPCFG_PSIZE_1024_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 1024 bytes Position */ +#define HSTPIPCFG_PTOKEN_Pos 8 /**< (HSTPIPCFG) Pipe Token Position */ +#define HSTPIPCFG_PTOKEN (_U_(0x3) << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) Pipe Token Mask */ +#define HSTPIPCFG_PTOKEN_SETUP_Val _U_(0x0) /**< (HSTPIPCFG) SETUP */ +#define HSTPIPCFG_PTOKEN_IN_Val _U_(0x1) /**< (HSTPIPCFG) IN */ +#define HSTPIPCFG_PTOKEN_OUT_Val _U_(0x2) /**< (HSTPIPCFG) OUT */ +#define HSTPIPCFG_PTOKEN_SETUP (HSTPIPCFG_PTOKEN_SETUP_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) SETUP Position */ +#define HSTPIPCFG_PTOKEN_IN (HSTPIPCFG_PTOKEN_IN_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) IN Position */ +#define HSTPIPCFG_PTOKEN_OUT (HSTPIPCFG_PTOKEN_OUT_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) OUT Position */ +#define HSTPIPCFG_AUTOSW_Pos 10 /**< (HSTPIPCFG) Automatic Switch Position */ +#define HSTPIPCFG_AUTOSW (_U_(0x1) << HSTPIPCFG_AUTOSW_Pos) /**< (HSTPIPCFG) Automatic Switch Mask */ +#define HSTPIPCFG_PTYPE_Pos 12 /**< (HSTPIPCFG) Pipe Type Position */ +#define HSTPIPCFG_PTYPE (_U_(0x3) << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Pipe Type Mask */ +#define HSTPIPCFG_PTYPE_CTRL_Val _U_(0x0) /**< (HSTPIPCFG) Control */ +#define HSTPIPCFG_PTYPE_ISO_Val _U_(0x1) /**< (HSTPIPCFG) Isochronous */ +#define HSTPIPCFG_PTYPE_BLK_Val _U_(0x2) /**< (HSTPIPCFG) Bulk */ +#define HSTPIPCFG_PTYPE_INTRPT_Val _U_(0x3) /**< (HSTPIPCFG) Interrupt */ +#define HSTPIPCFG_PTYPE_CTRL (HSTPIPCFG_PTYPE_CTRL_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Control Position */ +#define HSTPIPCFG_PTYPE_ISO (HSTPIPCFG_PTYPE_ISO_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Isochronous Position */ +#define HSTPIPCFG_PTYPE_BLK (HSTPIPCFG_PTYPE_BLK_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Bulk Position */ +#define HSTPIPCFG_PTYPE_INTRPT (HSTPIPCFG_PTYPE_INTRPT_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Interrupt Position */ +#define HSTPIPCFG_PEPNUM_Pos 16 /**< (HSTPIPCFG) Pipe Endpoint Number Position */ +#define HSTPIPCFG_PEPNUM (_U_(0xF) << HSTPIPCFG_PEPNUM_Pos) /**< (HSTPIPCFG) Pipe Endpoint Number Mask */ +#define HSTPIPCFG_INTFRQ_Pos 24 /**< (HSTPIPCFG) Pipe Interrupt Request Frequency Position */ +#define HSTPIPCFG_INTFRQ (_U_(0xFF) << HSTPIPCFG_INTFRQ_Pos) /**< (HSTPIPCFG) Pipe Interrupt Request Frequency Mask */ +#define HSTPIPCFG_Msk _U_(0xFF0F377E) /**< (HSTPIPCFG) Register Mask */ + +/* CTRL_BULK mode */ +#define HSTPIPCFG_CTRL_BULK_PINGEN_Pos 20 /**< (HSTPIPCFG) Ping Enable Position */ +#define HSTPIPCFG_CTRL_BULK_PINGEN (_U_(0x1) << HSTPIPCFG_CTRL_BULK_PINGEN_Pos) /**< (HSTPIPCFG) Ping Enable Mask */ +#define HSTPIPCFG_CTRL_BULK_BINTERVAL_Pos 24 /**< (HSTPIPCFG) bInterval Parameter for the Bulk-Out/Ping Transaction Position */ +#define HSTPIPCFG_CTRL_BULK_BINTERVAL (_U_(0xFF) << HSTPIPCFG_CTRL_BULK_BINTERVAL_Pos) /**< (HSTPIPCFG) bInterval Parameter for the Bulk-Out/Ping Transaction Mask */ +#define HSTPIPCFG_CTRL_BULK_Msk _U_(0xFF100000) /**< (HSTPIPCFG_CTRL_BULK) Register Mask */ + + +/* -------- HSTPIPISR : (USBHS Offset: 0x530) (R/ 32) Host Pipe Status Register -------- */ + +#define HSTPIPISR_OFFSET (0x530) /**< (HSTPIPISR) Host Pipe Status Register Offset */ + +#define HSTPIPISR_RXINI_Pos 0 /**< (HSTPIPISR) Received IN Data Interrupt Position */ +#define HSTPIPISR_RXINI (_U_(0x1) << HSTPIPISR_RXINI_Pos) /**< (HSTPIPISR) Received IN Data Interrupt Mask */ +#define HSTPIPISR_TXOUTI_Pos 1 /**< (HSTPIPISR) Transmitted OUT Data Interrupt Position */ +#define HSTPIPISR_TXOUTI (_U_(0x1) << HSTPIPISR_TXOUTI_Pos) /**< (HSTPIPISR) Transmitted OUT Data Interrupt Mask */ +#define HSTPIPISR_PERRI_Pos 3 /**< (HSTPIPISR) Pipe Error Interrupt Position */ +#define HSTPIPISR_PERRI (_U_(0x1) << HSTPIPISR_PERRI_Pos) /**< (HSTPIPISR) Pipe Error Interrupt Mask */ +#define HSTPIPISR_NAKEDI_Pos 4 /**< (HSTPIPISR) NAKed Interrupt Position */ +#define HSTPIPISR_NAKEDI (_U_(0x1) << HSTPIPISR_NAKEDI_Pos) /**< (HSTPIPISR) NAKed Interrupt Mask */ +#define HSTPIPISR_OVERFI_Pos 5 /**< (HSTPIPISR) Overflow Interrupt Position */ +#define HSTPIPISR_OVERFI (_U_(0x1) << HSTPIPISR_OVERFI_Pos) /**< (HSTPIPISR) Overflow Interrupt Mask */ +#define HSTPIPISR_SHORTPACKETI_Pos 7 /**< (HSTPIPISR) Short Packet Interrupt Position */ +#define HSTPIPISR_SHORTPACKETI (_U_(0x1) << HSTPIPISR_SHORTPACKETI_Pos) /**< (HSTPIPISR) Short Packet Interrupt Mask */ +#define HSTPIPISR_DTSEQ_Pos 8 /**< (HSTPIPISR) Data Toggle Sequence Position */ +#define HSTPIPISR_DTSEQ (_U_(0x3) << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data Toggle Sequence Mask */ +#define HSTPIPISR_DTSEQ_DATA0_Val _U_(0x0) /**< (HSTPIPISR) Data0 toggle sequence */ +#define HSTPIPISR_DTSEQ_DATA1_Val _U_(0x1) /**< (HSTPIPISR) Data1 toggle sequence */ +#define HSTPIPISR_DTSEQ_DATA0 (HSTPIPISR_DTSEQ_DATA0_Val << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data0 toggle sequence Position */ +#define HSTPIPISR_DTSEQ_DATA1 (HSTPIPISR_DTSEQ_DATA1_Val << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data1 toggle sequence Position */ +#define HSTPIPISR_NBUSYBK_Pos 12 /**< (HSTPIPISR) Number of Busy Banks Position */ +#define HSTPIPISR_NBUSYBK (_U_(0x3) << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) Number of Busy Banks Mask */ +#define HSTPIPISR_NBUSYBK_0_BUSY_Val _U_(0x0) /**< (HSTPIPISR) 0 busy bank (all banks free) */ +#define HSTPIPISR_NBUSYBK_1_BUSY_Val _U_(0x1) /**< (HSTPIPISR) 1 busy bank */ +#define HSTPIPISR_NBUSYBK_2_BUSY_Val _U_(0x2) /**< (HSTPIPISR) 2 busy banks */ +#define HSTPIPISR_NBUSYBK_3_BUSY_Val _U_(0x3) /**< (HSTPIPISR) 3 busy banks */ +#define HSTPIPISR_NBUSYBK_0_BUSY (HSTPIPISR_NBUSYBK_0_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 0 busy bank (all banks free) Position */ +#define HSTPIPISR_NBUSYBK_1_BUSY (HSTPIPISR_NBUSYBK_1_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 1 busy bank Position */ +#define HSTPIPISR_NBUSYBK_2_BUSY (HSTPIPISR_NBUSYBK_2_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 2 busy banks Position */ +#define HSTPIPISR_NBUSYBK_3_BUSY (HSTPIPISR_NBUSYBK_3_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 3 busy banks Position */ +#define HSTPIPISR_CURRBK_Pos 14 /**< (HSTPIPISR) Current Bank Position */ +#define HSTPIPISR_CURRBK (_U_(0x3) << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current Bank Mask */ +#define HSTPIPISR_CURRBK_BANK0_Val _U_(0x0) /**< (HSTPIPISR) Current bank is bank0 */ +#define HSTPIPISR_CURRBK_BANK1_Val _U_(0x1) /**< (HSTPIPISR) Current bank is bank1 */ +#define HSTPIPISR_CURRBK_BANK2_Val _U_(0x2) /**< (HSTPIPISR) Current bank is bank2 */ +#define HSTPIPISR_CURRBK_BANK0 (HSTPIPISR_CURRBK_BANK0_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank0 Position */ +#define HSTPIPISR_CURRBK_BANK1 (HSTPIPISR_CURRBK_BANK1_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank1 Position */ +#define HSTPIPISR_CURRBK_BANK2 (HSTPIPISR_CURRBK_BANK2_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank2 Position */ +#define HSTPIPISR_RWALL_Pos 16 /**< (HSTPIPISR) Read/Write Allowed Position */ +#define HSTPIPISR_RWALL (_U_(0x1) << HSTPIPISR_RWALL_Pos) /**< (HSTPIPISR) Read/Write Allowed Mask */ +#define HSTPIPISR_CFGOK_Pos 18 /**< (HSTPIPISR) Configuration OK Status Position */ +#define HSTPIPISR_CFGOK (_U_(0x1) << HSTPIPISR_CFGOK_Pos) /**< (HSTPIPISR) Configuration OK Status Mask */ +#define HSTPIPISR_PBYCT_Pos 20 /**< (HSTPIPISR) Pipe Byte Count Position */ +#define HSTPIPISR_PBYCT (_U_(0x7FF) << HSTPIPISR_PBYCT_Pos) /**< (HSTPIPISR) Pipe Byte Count Mask */ +#define HSTPIPISR_Msk _U_(0x7FF5F3BB) /**< (HSTPIPISR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPISR_CTRL_TXSTPI_Pos 2 /**< (HSTPIPISR) Transmitted SETUP Interrupt Position */ +#define HSTPIPISR_CTRL_TXSTPI (_U_(0x1) << HSTPIPISR_CTRL_TXSTPI_Pos) /**< (HSTPIPISR) Transmitted SETUP Interrupt Mask */ +#define HSTPIPISR_CTRL_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ +#define HSTPIPISR_CTRL_RXSTALLDI (_U_(0x1) << HSTPIPISR_CTRL_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ +#define HSTPIPISR_CTRL_Msk _U_(0x44) /**< (HSTPIPISR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPISR_ISO_UNDERFI_Pos 2 /**< (HSTPIPISR) Underflow Interrupt Position */ +#define HSTPIPISR_ISO_UNDERFI (_U_(0x1) << HSTPIPISR_ISO_UNDERFI_Pos) /**< (HSTPIPISR) Underflow Interrupt Mask */ +#define HSTPIPISR_ISO_CRCERRI_Pos 6 /**< (HSTPIPISR) CRC Error Interrupt Position */ +#define HSTPIPISR_ISO_CRCERRI (_U_(0x1) << HSTPIPISR_ISO_CRCERRI_Pos) /**< (HSTPIPISR) CRC Error Interrupt Mask */ +#define HSTPIPISR_ISO_Msk _U_(0x44) /**< (HSTPIPISR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPISR_BLK_TXSTPI_Pos 2 /**< (HSTPIPISR) Transmitted SETUP Interrupt Position */ +#define HSTPIPISR_BLK_TXSTPI (_U_(0x1) << HSTPIPISR_BLK_TXSTPI_Pos) /**< (HSTPIPISR) Transmitted SETUP Interrupt Mask */ +#define HSTPIPISR_BLK_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ +#define HSTPIPISR_BLK_RXSTALLDI (_U_(0x1) << HSTPIPISR_BLK_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ +#define HSTPIPISR_BLK_Msk _U_(0x44) /**< (HSTPIPISR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPISR_INTRPT_UNDERFI_Pos 2 /**< (HSTPIPISR) Underflow Interrupt Position */ +#define HSTPIPISR_INTRPT_UNDERFI (_U_(0x1) << HSTPIPISR_INTRPT_UNDERFI_Pos) /**< (HSTPIPISR) Underflow Interrupt Mask */ +#define HSTPIPISR_INTRPT_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ +#define HSTPIPISR_INTRPT_RXSTALLDI (_U_(0x1) << HSTPIPISR_INTRPT_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ +#define HSTPIPISR_INTRPT_Msk _U_(0x44) /**< (HSTPIPISR_INTRPT) Register Mask */ + + +/* -------- HSTPIPICR : (USBHS Offset: 0x560) (/W 32) Host Pipe Clear Register -------- */ + +#define HSTPIPICR_OFFSET (0x560) /**< (HSTPIPICR) Host Pipe Clear Register Offset */ + +#define HSTPIPICR_RXINIC_Pos 0 /**< (HSTPIPICR) Received IN Data Interrupt Clear Position */ +#define HSTPIPICR_RXINIC (_U_(0x1) << HSTPIPICR_RXINIC_Pos) /**< (HSTPIPICR) Received IN Data Interrupt Clear Mask */ +#define HSTPIPICR_TXOUTIC_Pos 1 /**< (HSTPIPICR) Transmitted OUT Data Interrupt Clear Position */ +#define HSTPIPICR_TXOUTIC (_U_(0x1) << HSTPIPICR_TXOUTIC_Pos) /**< (HSTPIPICR) Transmitted OUT Data Interrupt Clear Mask */ +#define HSTPIPICR_NAKEDIC_Pos 4 /**< (HSTPIPICR) NAKed Interrupt Clear Position */ +#define HSTPIPICR_NAKEDIC (_U_(0x1) << HSTPIPICR_NAKEDIC_Pos) /**< (HSTPIPICR) NAKed Interrupt Clear Mask */ +#define HSTPIPICR_OVERFIC_Pos 5 /**< (HSTPIPICR) Overflow Interrupt Clear Position */ +#define HSTPIPICR_OVERFIC (_U_(0x1) << HSTPIPICR_OVERFIC_Pos) /**< (HSTPIPICR) Overflow Interrupt Clear Mask */ +#define HSTPIPICR_SHORTPACKETIC_Pos 7 /**< (HSTPIPICR) Short Packet Interrupt Clear Position */ +#define HSTPIPICR_SHORTPACKETIC (_U_(0x1) << HSTPIPICR_SHORTPACKETIC_Pos) /**< (HSTPIPICR) Short Packet Interrupt Clear Mask */ +#define HSTPIPICR_Msk _U_(0xB3) /**< (HSTPIPICR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPICR_CTRL_TXSTPIC_Pos 2 /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Position */ +#define HSTPIPICR_CTRL_TXSTPIC (_U_(0x1) << HSTPIPICR_CTRL_TXSTPIC_Pos) /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Mask */ +#define HSTPIPICR_CTRL_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ +#define HSTPIPICR_CTRL_RXSTALLDIC (_U_(0x1) << HSTPIPICR_CTRL_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ +#define HSTPIPICR_CTRL_Msk _U_(0x44) /**< (HSTPIPICR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPICR_ISO_UNDERFIC_Pos 2 /**< (HSTPIPICR) Underflow Interrupt Clear Position */ +#define HSTPIPICR_ISO_UNDERFIC (_U_(0x1) << HSTPIPICR_ISO_UNDERFIC_Pos) /**< (HSTPIPICR) Underflow Interrupt Clear Mask */ +#define HSTPIPICR_ISO_CRCERRIC_Pos 6 /**< (HSTPIPICR) CRC Error Interrupt Clear Position */ +#define HSTPIPICR_ISO_CRCERRIC (_U_(0x1) << HSTPIPICR_ISO_CRCERRIC_Pos) /**< (HSTPIPICR) CRC Error Interrupt Clear Mask */ +#define HSTPIPICR_ISO_Msk _U_(0x44) /**< (HSTPIPICR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPICR_BLK_TXSTPIC_Pos 2 /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Position */ +#define HSTPIPICR_BLK_TXSTPIC (_U_(0x1) << HSTPIPICR_BLK_TXSTPIC_Pos) /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Mask */ +#define HSTPIPICR_BLK_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ +#define HSTPIPICR_BLK_RXSTALLDIC (_U_(0x1) << HSTPIPICR_BLK_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ +#define HSTPIPICR_BLK_Msk _U_(0x44) /**< (HSTPIPICR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPICR_INTRPT_UNDERFIC_Pos 2 /**< (HSTPIPICR) Underflow Interrupt Clear Position */ +#define HSTPIPICR_INTRPT_UNDERFIC (_U_(0x1) << HSTPIPICR_INTRPT_UNDERFIC_Pos) /**< (HSTPIPICR) Underflow Interrupt Clear Mask */ +#define HSTPIPICR_INTRPT_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ +#define HSTPIPICR_INTRPT_RXSTALLDIC (_U_(0x1) << HSTPIPICR_INTRPT_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ +#define HSTPIPICR_INTRPT_Msk _U_(0x44) /**< (HSTPIPICR_INTRPT) Register Mask */ + + +/* -------- HSTPIPIFR : (USBHS Offset: 0x590) (/W 32) Host Pipe Set Register -------- */ + +#define HSTPIPIFR_OFFSET (0x590) /**< (HSTPIPIFR) Host Pipe Set Register Offset */ + +#define HSTPIPIFR_RXINIS_Pos 0 /**< (HSTPIPIFR) Received IN Data Interrupt Set Position */ +#define HSTPIPIFR_RXINIS (_U_(0x1) << HSTPIPIFR_RXINIS_Pos) /**< (HSTPIPIFR) Received IN Data Interrupt Set Mask */ +#define HSTPIPIFR_TXOUTIS_Pos 1 /**< (HSTPIPIFR) Transmitted OUT Data Interrupt Set Position */ +#define HSTPIPIFR_TXOUTIS (_U_(0x1) << HSTPIPIFR_TXOUTIS_Pos) /**< (HSTPIPIFR) Transmitted OUT Data Interrupt Set Mask */ +#define HSTPIPIFR_PERRIS_Pos 3 /**< (HSTPIPIFR) Pipe Error Interrupt Set Position */ +#define HSTPIPIFR_PERRIS (_U_(0x1) << HSTPIPIFR_PERRIS_Pos) /**< (HSTPIPIFR) Pipe Error Interrupt Set Mask */ +#define HSTPIPIFR_NAKEDIS_Pos 4 /**< (HSTPIPIFR) NAKed Interrupt Set Position */ +#define HSTPIPIFR_NAKEDIS (_U_(0x1) << HSTPIPIFR_NAKEDIS_Pos) /**< (HSTPIPIFR) NAKed Interrupt Set Mask */ +#define HSTPIPIFR_OVERFIS_Pos 5 /**< (HSTPIPIFR) Overflow Interrupt Set Position */ +#define HSTPIPIFR_OVERFIS (_U_(0x1) << HSTPIPIFR_OVERFIS_Pos) /**< (HSTPIPIFR) Overflow Interrupt Set Mask */ +#define HSTPIPIFR_SHORTPACKETIS_Pos 7 /**< (HSTPIPIFR) Short Packet Interrupt Set Position */ +#define HSTPIPIFR_SHORTPACKETIS (_U_(0x1) << HSTPIPIFR_SHORTPACKETIS_Pos) /**< (HSTPIPIFR) Short Packet Interrupt Set Mask */ +#define HSTPIPIFR_NBUSYBKS_Pos 12 /**< (HSTPIPIFR) Number of Busy Banks Set Position */ +#define HSTPIPIFR_NBUSYBKS (_U_(0x1) << HSTPIPIFR_NBUSYBKS_Pos) /**< (HSTPIPIFR) Number of Busy Banks Set Mask */ +#define HSTPIPIFR_Msk _U_(0x10BB) /**< (HSTPIPIFR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPIFR_CTRL_TXSTPIS_Pos 2 /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Position */ +#define HSTPIPIFR_CTRL_TXSTPIS (_U_(0x1) << HSTPIPIFR_CTRL_TXSTPIS_Pos) /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Mask */ +#define HSTPIPIFR_CTRL_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ +#define HSTPIPIFR_CTRL_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_CTRL_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ +#define HSTPIPIFR_CTRL_Msk _U_(0x44) /**< (HSTPIPIFR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPIFR_ISO_UNDERFIS_Pos 2 /**< (HSTPIPIFR) Underflow Interrupt Set Position */ +#define HSTPIPIFR_ISO_UNDERFIS (_U_(0x1) << HSTPIPIFR_ISO_UNDERFIS_Pos) /**< (HSTPIPIFR) Underflow Interrupt Set Mask */ +#define HSTPIPIFR_ISO_CRCERRIS_Pos 6 /**< (HSTPIPIFR) CRC Error Interrupt Set Position */ +#define HSTPIPIFR_ISO_CRCERRIS (_U_(0x1) << HSTPIPIFR_ISO_CRCERRIS_Pos) /**< (HSTPIPIFR) CRC Error Interrupt Set Mask */ +#define HSTPIPIFR_ISO_Msk _U_(0x44) /**< (HSTPIPIFR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPIFR_BLK_TXSTPIS_Pos 2 /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Position */ +#define HSTPIPIFR_BLK_TXSTPIS (_U_(0x1) << HSTPIPIFR_BLK_TXSTPIS_Pos) /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Mask */ +#define HSTPIPIFR_BLK_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ +#define HSTPIPIFR_BLK_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_BLK_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ +#define HSTPIPIFR_BLK_Msk _U_(0x44) /**< (HSTPIPIFR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPIFR_INTRPT_UNDERFIS_Pos 2 /**< (HSTPIPIFR) Underflow Interrupt Set Position */ +#define HSTPIPIFR_INTRPT_UNDERFIS (_U_(0x1) << HSTPIPIFR_INTRPT_UNDERFIS_Pos) /**< (HSTPIPIFR) Underflow Interrupt Set Mask */ +#define HSTPIPIFR_INTRPT_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ +#define HSTPIPIFR_INTRPT_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_INTRPT_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ +#define HSTPIPIFR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIFR_INTRPT) Register Mask */ + + +/* -------- HSTPIPIMR : (USBHS Offset: 0x5c0) (R/ 32) Host Pipe Mask Register -------- */ + +#define HSTPIPIMR_OFFSET (0x5C0) /**< (HSTPIPIMR) Host Pipe Mask Register Offset */ + +#define HSTPIPIMR_RXINE_Pos 0 /**< (HSTPIPIMR) Received IN Data Interrupt Enable Position */ +#define HSTPIPIMR_RXINE (_U_(0x1) << HSTPIPIMR_RXINE_Pos) /**< (HSTPIPIMR) Received IN Data Interrupt Enable Mask */ +#define HSTPIPIMR_TXOUTE_Pos 1 /**< (HSTPIPIMR) Transmitted OUT Data Interrupt Enable Position */ +#define HSTPIPIMR_TXOUTE (_U_(0x1) << HSTPIPIMR_TXOUTE_Pos) /**< (HSTPIPIMR) Transmitted OUT Data Interrupt Enable Mask */ +#define HSTPIPIMR_PERRE_Pos 3 /**< (HSTPIPIMR) Pipe Error Interrupt Enable Position */ +#define HSTPIPIMR_PERRE (_U_(0x1) << HSTPIPIMR_PERRE_Pos) /**< (HSTPIPIMR) Pipe Error Interrupt Enable Mask */ +#define HSTPIPIMR_NAKEDE_Pos 4 /**< (HSTPIPIMR) NAKed Interrupt Enable Position */ +#define HSTPIPIMR_NAKEDE (_U_(0x1) << HSTPIPIMR_NAKEDE_Pos) /**< (HSTPIPIMR) NAKed Interrupt Enable Mask */ +#define HSTPIPIMR_OVERFIE_Pos 5 /**< (HSTPIPIMR) Overflow Interrupt Enable Position */ +#define HSTPIPIMR_OVERFIE (_U_(0x1) << HSTPIPIMR_OVERFIE_Pos) /**< (HSTPIPIMR) Overflow Interrupt Enable Mask */ +#define HSTPIPIMR_SHORTPACKETIE_Pos 7 /**< (HSTPIPIMR) Short Packet Interrupt Enable Position */ +#define HSTPIPIMR_SHORTPACKETIE (_U_(0x1) << HSTPIPIMR_SHORTPACKETIE_Pos) /**< (HSTPIPIMR) Short Packet Interrupt Enable Mask */ +#define HSTPIPIMR_NBUSYBKE_Pos 12 /**< (HSTPIPIMR) Number of Busy Banks Interrupt Enable Position */ +#define HSTPIPIMR_NBUSYBKE (_U_(0x1) << HSTPIPIMR_NBUSYBKE_Pos) /**< (HSTPIPIMR) Number of Busy Banks Interrupt Enable Mask */ +#define HSTPIPIMR_FIFOCON_Pos 14 /**< (HSTPIPIMR) FIFO Control Position */ +#define HSTPIPIMR_FIFOCON (_U_(0x1) << HSTPIPIMR_FIFOCON_Pos) /**< (HSTPIPIMR) FIFO Control Mask */ +#define HSTPIPIMR_PDISHDMA_Pos 16 /**< (HSTPIPIMR) Pipe Interrupts Disable HDMA Request Enable Position */ +#define HSTPIPIMR_PDISHDMA (_U_(0x1) << HSTPIPIMR_PDISHDMA_Pos) /**< (HSTPIPIMR) Pipe Interrupts Disable HDMA Request Enable Mask */ +#define HSTPIPIMR_PFREEZE_Pos 17 /**< (HSTPIPIMR) Pipe Freeze Position */ +#define HSTPIPIMR_PFREEZE (_U_(0x1) << HSTPIPIMR_PFREEZE_Pos) /**< (HSTPIPIMR) Pipe Freeze Mask */ +#define HSTPIPIMR_RSTDT_Pos 18 /**< (HSTPIPIMR) Reset Data Toggle Position */ +#define HSTPIPIMR_RSTDT (_U_(0x1) << HSTPIPIMR_RSTDT_Pos) /**< (HSTPIPIMR) Reset Data Toggle Mask */ +#define HSTPIPIMR_Msk _U_(0x750BB) /**< (HSTPIPIMR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPIMR_CTRL_TXSTPE_Pos 2 /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Position */ +#define HSTPIPIMR_CTRL_TXSTPE (_U_(0x1) << HSTPIPIMR_CTRL_TXSTPE_Pos) /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Mask */ +#define HSTPIPIMR_CTRL_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ +#define HSTPIPIMR_CTRL_RXSTALLDE (_U_(0x1) << HSTPIPIMR_CTRL_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIMR_CTRL_Msk _U_(0x44) /**< (HSTPIPIMR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPIMR_ISO_UNDERFIE_Pos 2 /**< (HSTPIPIMR) Underflow Interrupt Enable Position */ +#define HSTPIPIMR_ISO_UNDERFIE (_U_(0x1) << HSTPIPIMR_ISO_UNDERFIE_Pos) /**< (HSTPIPIMR) Underflow Interrupt Enable Mask */ +#define HSTPIPIMR_ISO_CRCERRE_Pos 6 /**< (HSTPIPIMR) CRC Error Interrupt Enable Position */ +#define HSTPIPIMR_ISO_CRCERRE (_U_(0x1) << HSTPIPIMR_ISO_CRCERRE_Pos) /**< (HSTPIPIMR) CRC Error Interrupt Enable Mask */ +#define HSTPIPIMR_ISO_Msk _U_(0x44) /**< (HSTPIPIMR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPIMR_BLK_TXSTPE_Pos 2 /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Position */ +#define HSTPIPIMR_BLK_TXSTPE (_U_(0x1) << HSTPIPIMR_BLK_TXSTPE_Pos) /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Mask */ +#define HSTPIPIMR_BLK_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ +#define HSTPIPIMR_BLK_RXSTALLDE (_U_(0x1) << HSTPIPIMR_BLK_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIMR_BLK_Msk _U_(0x44) /**< (HSTPIPIMR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPIMR_INTRPT_UNDERFIE_Pos 2 /**< (HSTPIPIMR) Underflow Interrupt Enable Position */ +#define HSTPIPIMR_INTRPT_UNDERFIE (_U_(0x1) << HSTPIPIMR_INTRPT_UNDERFIE_Pos) /**< (HSTPIPIMR) Underflow Interrupt Enable Mask */ +#define HSTPIPIMR_INTRPT_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ +#define HSTPIPIMR_INTRPT_RXSTALLDE (_U_(0x1) << HSTPIPIMR_INTRPT_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIMR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIMR_INTRPT) Register Mask */ + + +/* -------- HSTPIPIER : (USBHS Offset: 0x5f0) (/W 32) Host Pipe Enable Register -------- */ + +#define HSTPIPIER_OFFSET (0x5F0) /**< (HSTPIPIER) Host Pipe Enable Register Offset */ + +#define HSTPIPIER_RXINES_Pos 0 /**< (HSTPIPIER) Received IN Data Interrupt Enable Position */ +#define HSTPIPIER_RXINES (_U_(0x1) << HSTPIPIER_RXINES_Pos) /**< (HSTPIPIER) Received IN Data Interrupt Enable Mask */ +#define HSTPIPIER_TXOUTES_Pos 1 /**< (HSTPIPIER) Transmitted OUT Data Interrupt Enable Position */ +#define HSTPIPIER_TXOUTES (_U_(0x1) << HSTPIPIER_TXOUTES_Pos) /**< (HSTPIPIER) Transmitted OUT Data Interrupt Enable Mask */ +#define HSTPIPIER_PERRES_Pos 3 /**< (HSTPIPIER) Pipe Error Interrupt Enable Position */ +#define HSTPIPIER_PERRES (_U_(0x1) << HSTPIPIER_PERRES_Pos) /**< (HSTPIPIER) Pipe Error Interrupt Enable Mask */ +#define HSTPIPIER_NAKEDES_Pos 4 /**< (HSTPIPIER) NAKed Interrupt Enable Position */ +#define HSTPIPIER_NAKEDES (_U_(0x1) << HSTPIPIER_NAKEDES_Pos) /**< (HSTPIPIER) NAKed Interrupt Enable Mask */ +#define HSTPIPIER_OVERFIES_Pos 5 /**< (HSTPIPIER) Overflow Interrupt Enable Position */ +#define HSTPIPIER_OVERFIES (_U_(0x1) << HSTPIPIER_OVERFIES_Pos) /**< (HSTPIPIER) Overflow Interrupt Enable Mask */ +#define HSTPIPIER_SHORTPACKETIES_Pos 7 /**< (HSTPIPIER) Short Packet Interrupt Enable Position */ +#define HSTPIPIER_SHORTPACKETIES (_U_(0x1) << HSTPIPIER_SHORTPACKETIES_Pos) /**< (HSTPIPIER) Short Packet Interrupt Enable Mask */ +#define HSTPIPIER_NBUSYBKES_Pos 12 /**< (HSTPIPIER) Number of Busy Banks Enable Position */ +#define HSTPIPIER_NBUSYBKES (_U_(0x1) << HSTPIPIER_NBUSYBKES_Pos) /**< (HSTPIPIER) Number of Busy Banks Enable Mask */ +#define HSTPIPIER_PDISHDMAS_Pos 16 /**< (HSTPIPIER) Pipe Interrupts Disable HDMA Request Enable Position */ +#define HSTPIPIER_PDISHDMAS (_U_(0x1) << HSTPIPIER_PDISHDMAS_Pos) /**< (HSTPIPIER) Pipe Interrupts Disable HDMA Request Enable Mask */ +#define HSTPIPIER_PFREEZES_Pos 17 /**< (HSTPIPIER) Pipe Freeze Enable Position */ +#define HSTPIPIER_PFREEZES (_U_(0x1) << HSTPIPIER_PFREEZES_Pos) /**< (HSTPIPIER) Pipe Freeze Enable Mask */ +#define HSTPIPIER_RSTDTS_Pos 18 /**< (HSTPIPIER) Reset Data Toggle Enable Position */ +#define HSTPIPIER_RSTDTS (_U_(0x1) << HSTPIPIER_RSTDTS_Pos) /**< (HSTPIPIER) Reset Data Toggle Enable Mask */ +#define HSTPIPIER_Msk _U_(0x710BB) /**< (HSTPIPIER) Register Mask */ + +/* CTRL mode */ +#define HSTPIPIER_CTRL_TXSTPES_Pos 2 /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Position */ +#define HSTPIPIER_CTRL_TXSTPES (_U_(0x1) << HSTPIPIER_CTRL_TXSTPES_Pos) /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Mask */ +#define HSTPIPIER_CTRL_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ +#define HSTPIPIER_CTRL_RXSTALLDES (_U_(0x1) << HSTPIPIER_CTRL_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIER_CTRL_Msk _U_(0x44) /**< (HSTPIPIER_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPIER_ISO_UNDERFIES_Pos 2 /**< (HSTPIPIER) Underflow Interrupt Enable Position */ +#define HSTPIPIER_ISO_UNDERFIES (_U_(0x1) << HSTPIPIER_ISO_UNDERFIES_Pos) /**< (HSTPIPIER) Underflow Interrupt Enable Mask */ +#define HSTPIPIER_ISO_CRCERRES_Pos 6 /**< (HSTPIPIER) CRC Error Interrupt Enable Position */ +#define HSTPIPIER_ISO_CRCERRES (_U_(0x1) << HSTPIPIER_ISO_CRCERRES_Pos) /**< (HSTPIPIER) CRC Error Interrupt Enable Mask */ +#define HSTPIPIER_ISO_Msk _U_(0x44) /**< (HSTPIPIER_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPIER_BLK_TXSTPES_Pos 2 /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Position */ +#define HSTPIPIER_BLK_TXSTPES (_U_(0x1) << HSTPIPIER_BLK_TXSTPES_Pos) /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Mask */ +#define HSTPIPIER_BLK_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ +#define HSTPIPIER_BLK_RXSTALLDES (_U_(0x1) << HSTPIPIER_BLK_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIER_BLK_Msk _U_(0x44) /**< (HSTPIPIER_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPIER_INTRPT_UNDERFIES_Pos 2 /**< (HSTPIPIER) Underflow Interrupt Enable Position */ +#define HSTPIPIER_INTRPT_UNDERFIES (_U_(0x1) << HSTPIPIER_INTRPT_UNDERFIES_Pos) /**< (HSTPIPIER) Underflow Interrupt Enable Mask */ +#define HSTPIPIER_INTRPT_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ +#define HSTPIPIER_INTRPT_RXSTALLDES (_U_(0x1) << HSTPIPIER_INTRPT_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIER_INTRPT_Msk _U_(0x44) /**< (HSTPIPIER_INTRPT) Register Mask */ + + +/* -------- HSTPIPIDR : (USBHS Offset: 0x620) (/W 32) Host Pipe Disable Register -------- */ + +#define HSTPIPIDR_OFFSET (0x620) /**< (HSTPIPIDR) Host Pipe Disable Register Offset */ + +#define HSTPIPIDR_RXINEC_Pos 0 /**< (HSTPIPIDR) Received IN Data Interrupt Disable Position */ +#define HSTPIPIDR_RXINEC (_U_(0x1) << HSTPIPIDR_RXINEC_Pos) /**< (HSTPIPIDR) Received IN Data Interrupt Disable Mask */ +#define HSTPIPIDR_TXOUTEC_Pos 1 /**< (HSTPIPIDR) Transmitted OUT Data Interrupt Disable Position */ +#define HSTPIPIDR_TXOUTEC (_U_(0x1) << HSTPIPIDR_TXOUTEC_Pos) /**< (HSTPIPIDR) Transmitted OUT Data Interrupt Disable Mask */ +#define HSTPIPIDR_PERREC_Pos 3 /**< (HSTPIPIDR) Pipe Error Interrupt Disable Position */ +#define HSTPIPIDR_PERREC (_U_(0x1) << HSTPIPIDR_PERREC_Pos) /**< (HSTPIPIDR) Pipe Error Interrupt Disable Mask */ +#define HSTPIPIDR_NAKEDEC_Pos 4 /**< (HSTPIPIDR) NAKed Interrupt Disable Position */ +#define HSTPIPIDR_NAKEDEC (_U_(0x1) << HSTPIPIDR_NAKEDEC_Pos) /**< (HSTPIPIDR) NAKed Interrupt Disable Mask */ +#define HSTPIPIDR_OVERFIEC_Pos 5 /**< (HSTPIPIDR) Overflow Interrupt Disable Position */ +#define HSTPIPIDR_OVERFIEC (_U_(0x1) << HSTPIPIDR_OVERFIEC_Pos) /**< (HSTPIPIDR) Overflow Interrupt Disable Mask */ +#define HSTPIPIDR_SHORTPACKETIEC_Pos 7 /**< (HSTPIPIDR) Short Packet Interrupt Disable Position */ +#define HSTPIPIDR_SHORTPACKETIEC (_U_(0x1) << HSTPIPIDR_SHORTPACKETIEC_Pos) /**< (HSTPIPIDR) Short Packet Interrupt Disable Mask */ +#define HSTPIPIDR_NBUSYBKEC_Pos 12 /**< (HSTPIPIDR) Number of Busy Banks Disable Position */ +#define HSTPIPIDR_NBUSYBKEC (_U_(0x1) << HSTPIPIDR_NBUSYBKEC_Pos) /**< (HSTPIPIDR) Number of Busy Banks Disable Mask */ +#define HSTPIPIDR_FIFOCONC_Pos 14 /**< (HSTPIPIDR) FIFO Control Disable Position */ +#define HSTPIPIDR_FIFOCONC (_U_(0x1) << HSTPIPIDR_FIFOCONC_Pos) /**< (HSTPIPIDR) FIFO Control Disable Mask */ +#define HSTPIPIDR_PDISHDMAC_Pos 16 /**< (HSTPIPIDR) Pipe Interrupts Disable HDMA Request Disable Position */ +#define HSTPIPIDR_PDISHDMAC (_U_(0x1) << HSTPIPIDR_PDISHDMAC_Pos) /**< (HSTPIPIDR) Pipe Interrupts Disable HDMA Request Disable Mask */ +#define HSTPIPIDR_PFREEZEC_Pos 17 /**< (HSTPIPIDR) Pipe Freeze Disable Position */ +#define HSTPIPIDR_PFREEZEC (_U_(0x1) << HSTPIPIDR_PFREEZEC_Pos) /**< (HSTPIPIDR) Pipe Freeze Disable Mask */ +#define HSTPIPIDR_Msk _U_(0x350BB) /**< (HSTPIPIDR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPIDR_CTRL_TXSTPEC_Pos 2 /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Position */ +#define HSTPIPIDR_CTRL_TXSTPEC (_U_(0x1) << HSTPIPIDR_CTRL_TXSTPEC_Pos) /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Mask */ +#define HSTPIPIDR_CTRL_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ +#define HSTPIPIDR_CTRL_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_CTRL_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ +#define HSTPIPIDR_CTRL_Msk _U_(0x44) /**< (HSTPIPIDR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPIDR_ISO_UNDERFIEC_Pos 2 /**< (HSTPIPIDR) Underflow Interrupt Disable Position */ +#define HSTPIPIDR_ISO_UNDERFIEC (_U_(0x1) << HSTPIPIDR_ISO_UNDERFIEC_Pos) /**< (HSTPIPIDR) Underflow Interrupt Disable Mask */ +#define HSTPIPIDR_ISO_CRCERREC_Pos 6 /**< (HSTPIPIDR) CRC Error Interrupt Disable Position */ +#define HSTPIPIDR_ISO_CRCERREC (_U_(0x1) << HSTPIPIDR_ISO_CRCERREC_Pos) /**< (HSTPIPIDR) CRC Error Interrupt Disable Mask */ +#define HSTPIPIDR_ISO_Msk _U_(0x44) /**< (HSTPIPIDR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPIDR_BLK_TXSTPEC_Pos 2 /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Position */ +#define HSTPIPIDR_BLK_TXSTPEC (_U_(0x1) << HSTPIPIDR_BLK_TXSTPEC_Pos) /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Mask */ +#define HSTPIPIDR_BLK_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ +#define HSTPIPIDR_BLK_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_BLK_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ +#define HSTPIPIDR_BLK_Msk _U_(0x44) /**< (HSTPIPIDR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPIDR_INTRPT_UNDERFIEC_Pos 2 /**< (HSTPIPIDR) Underflow Interrupt Disable Position */ +#define HSTPIPIDR_INTRPT_UNDERFIEC (_U_(0x1) << HSTPIPIDR_INTRPT_UNDERFIEC_Pos) /**< (HSTPIPIDR) Underflow Interrupt Disable Mask */ +#define HSTPIPIDR_INTRPT_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ +#define HSTPIPIDR_INTRPT_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_INTRPT_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ +#define HSTPIPIDR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIDR_INTRPT) Register Mask */ + + +/* -------- HSTPIPINRQ : (USBHS Offset: 0x650) (R/W 32) Host Pipe IN Request Register -------- */ + +#define HSTPIPINRQ_OFFSET (0x650) /**< (HSTPIPINRQ) Host Pipe IN Request Register Offset */ + +#define HSTPIPINRQ_INRQ_Pos 0 /**< (HSTPIPINRQ) IN Request Number before Freeze Position */ +#define HSTPIPINRQ_INRQ (_U_(0xFF) << HSTPIPINRQ_INRQ_Pos) /**< (HSTPIPINRQ) IN Request Number before Freeze Mask */ +#define HSTPIPINRQ_INMODE_Pos 8 /**< (HSTPIPINRQ) IN Request Mode Position */ +#define HSTPIPINRQ_INMODE (_U_(0x1) << HSTPIPINRQ_INMODE_Pos) /**< (HSTPIPINRQ) IN Request Mode Mask */ +#define HSTPIPINRQ_Msk _U_(0x1FF) /**< (HSTPIPINRQ) Register Mask */ + + +/* -------- HSTPIPERR : (USBHS Offset: 0x680) (R/W 32) Host Pipe Error Register -------- */ + +#define HSTPIPERR_OFFSET (0x680) /**< (HSTPIPERR) Host Pipe Error Register Offset */ + +#define HSTPIPERR_DATATGL_Pos 0 /**< (HSTPIPERR) Data Toggle Error Position */ +#define HSTPIPERR_DATATGL (_U_(0x1) << HSTPIPERR_DATATGL_Pos) /**< (HSTPIPERR) Data Toggle Error Mask */ +#define HSTPIPERR_DATAPID_Pos 1 /**< (HSTPIPERR) Data PID Error Position */ +#define HSTPIPERR_DATAPID (_U_(0x1) << HSTPIPERR_DATAPID_Pos) /**< (HSTPIPERR) Data PID Error Mask */ +#define HSTPIPERR_PID_Pos 2 /**< (HSTPIPERR) Data PID Error Position */ +#define HSTPIPERR_PID (_U_(0x1) << HSTPIPERR_PID_Pos) /**< (HSTPIPERR) Data PID Error Mask */ +#define HSTPIPERR_TIMEOUT_Pos 3 /**< (HSTPIPERR) Time-Out Error Position */ +#define HSTPIPERR_TIMEOUT (_U_(0x1) << HSTPIPERR_TIMEOUT_Pos) /**< (HSTPIPERR) Time-Out Error Mask */ +#define HSTPIPERR_CRC16_Pos 4 /**< (HSTPIPERR) CRC16 Error Position */ +#define HSTPIPERR_CRC16 (_U_(0x1) << HSTPIPERR_CRC16_Pos) /**< (HSTPIPERR) CRC16 Error Mask */ +#define HSTPIPERR_COUNTER_Pos 5 /**< (HSTPIPERR) Error Counter Position */ +#define HSTPIPERR_COUNTER (_U_(0x3) << HSTPIPERR_COUNTER_Pos) /**< (HSTPIPERR) Error Counter Mask */ +#define HSTPIPERR_Msk _U_(0x7F) /**< (HSTPIPERR) Register Mask */ + +#define HSTPIPERR_CRC_Pos 4 /**< (HSTPIPERR Position) CRCx6 Error */ +#define HSTPIPERR_CRC (_U_(0x1) << HSTPIPERR_CRC_Pos) /**< (HSTPIPERR Mask) CRC */ + +/* -------- CTRL : (USBHS Offset: 0x800) (R/W 32) General Control Register -------- */ + +#define CTRL_OFFSET (0x800) /**< (CTRL) General Control Register Offset */ + +#define CTRL_RDERRE_Pos 4 /**< (CTRL) Remote Device Connection Error Interrupt Enable Position */ +#define CTRL_RDERRE (_U_(0x1) << CTRL_RDERRE_Pos) /**< (CTRL) Remote Device Connection Error Interrupt Enable Mask */ +#define CTRL_VBUSHWC_Pos 8 /**< (CTRL) VBUS Hardware Control Position */ +#define CTRL_VBUSHWC (_U_(0x1) << CTRL_VBUSHWC_Pos) /**< (CTRL) VBUS Hardware Control Mask */ +#define CTRL_FRZCLK_Pos 14 /**< (CTRL) Freeze USB Clock Position */ +#define CTRL_FRZCLK (_U_(0x1) << CTRL_FRZCLK_Pos) /**< (CTRL) Freeze USB Clock Mask */ +#define CTRL_USBE_Pos 15 /**< (CTRL) USBHS Enable Position */ +#define CTRL_USBE (_U_(0x1) << CTRL_USBE_Pos) /**< (CTRL) USBHS Enable Mask */ +#define CTRL_UID_Pos 24 /**< (CTRL) UID Pin Enable Position */ +#define CTRL_UID (_U_(0x1) << CTRL_UID_Pos) /**< (CTRL) UID Pin Enable Mask */ +#define CTRL_UIMOD_Pos 25 /**< (CTRL) USBHS Mode Position */ +#define CTRL_UIMOD (_U_(0x1) << CTRL_UIMOD_Pos) /**< (CTRL) USBHS Mode Mask */ +#define CTRL_UIMOD_HOST_Val _U_(0x0) /**< (CTRL) The module is in USB Host mode. */ +#define CTRL_UIMOD_DEVICE_Val _U_(0x1) /**< (CTRL) The module is in USB Device mode. */ +#define CTRL_UIMOD_HOST (CTRL_UIMOD_HOST_Val << CTRL_UIMOD_Pos) /**< (CTRL) The module is in USB Host mode. Position */ +#define CTRL_UIMOD_DEVICE (CTRL_UIMOD_DEVICE_Val << CTRL_UIMOD_Pos) /**< (CTRL) The module is in USB Device mode. Position */ +#define CTRL_Msk _U_(0x300C110) /**< (CTRL) Register Mask */ + + +/* -------- SR : (USBHS Offset: 0x804) (R/ 32) General Status Register -------- */ + +#define SR_OFFSET (0x804) /**< (SR) General Status Register Offset */ + +#define SR_RDERRI_Pos 4 /**< (SR) Remote Device Connection Error Interrupt (Host mode only) Position */ +#define SR_RDERRI (_U_(0x1) << SR_RDERRI_Pos) /**< (SR) Remote Device Connection Error Interrupt (Host mode only) Mask */ +#define SR_SPEED_Pos 12 /**< (SR) Speed Status (Device mode only) Position */ +#define SR_SPEED (_U_(0x3) << SR_SPEED_Pos) /**< (SR) Speed Status (Device mode only) Mask */ +#define SR_SPEED_FULL_SPEED_Val _U_(0x0) /**< (SR) Full-Speed mode */ +#define SR_SPEED_HIGH_SPEED_Val _U_(0x1) /**< (SR) High-Speed mode */ +#define SR_SPEED_LOW_SPEED_Val _U_(0x2) /**< (SR) Low-Speed mode */ +#define SR_SPEED_FULL_SPEED (SR_SPEED_FULL_SPEED_Val << SR_SPEED_Pos) /**< (SR) Full-Speed mode Position */ +#define SR_SPEED_HIGH_SPEED (SR_SPEED_HIGH_SPEED_Val << SR_SPEED_Pos) /**< (SR) High-Speed mode Position */ +#define SR_SPEED_LOW_SPEED (SR_SPEED_LOW_SPEED_Val << SR_SPEED_Pos) /**< (SR) Low-Speed mode Position */ +#define SR_CLKUSABLE_Pos 14 /**< (SR) UTMI Clock Usable Position */ +#define SR_CLKUSABLE (_U_(0x1) << SR_CLKUSABLE_Pos) /**< (SR) UTMI Clock Usable Mask */ +#define SR_Msk _U_(0x7010) /**< (SR) Register Mask */ + + +/* -------- SCR : (USBHS Offset: 0x808) (/W 32) General Status Clear Register -------- */ + +#define SCR_OFFSET (0x808) /**< (SCR) General Status Clear Register Offset */ + +#define SCR_RDERRIC_Pos 4 /**< (SCR) Remote Device Connection Error Interrupt Clear Position */ +#define SCR_RDERRIC (_U_(0x1) << SCR_RDERRIC_Pos) /**< (SCR) Remote Device Connection Error Interrupt Clear Mask */ +#define SCR_Msk _U_(0x10) /**< (SCR) Register Mask */ + + +/* -------- SFR : (USBHS Offset: 0x80c) (/W 32) General Status Set Register -------- */ + +#define SFR_OFFSET (0x80C) /**< (SFR) General Status Set Register Offset */ + +#define SFR_RDERRIS_Pos 4 /**< (SFR) Remote Device Connection Error Interrupt Set Position */ +#define SFR_RDERRIS (_U_(0x1) << SFR_RDERRIS_Pos) /**< (SFR) Remote Device Connection Error Interrupt Set Mask */ +#define SFR_VBUSRQS_Pos 9 /**< (SFR) VBUS Request Set Position */ +#define SFR_VBUSRQS (_U_(0x1) << SFR_VBUSRQS_Pos) /**< (SFR) VBUS Request Set Mask */ +#define SFR_Msk _U_(0x210) /**< (SFR) Register Mask */ + + +/** \brief DEVDMA hardware registers */ +typedef struct +{ + __IO uint32_t DEVDMANXTDSC; /**< (DEVDMA Offset: 0x00) Device DMA Channel Next Descriptor Address Register */ + __IO uint32_t DEVDMAADDRESS; /**< (DEVDMA Offset: 0x04) Device DMA Channel Address Register */ + __IO uint32_t DEVDMACONTROL; /**< (DEVDMA Offset: 0x08) Device DMA Channel Control Register */ + __IO uint32_t DEVDMASTATUS; /**< (DEVDMA Offset: 0x0C) Device DMA Channel Status Register */ +} devdma_t; + +/** \brief HSTDMA hardware registers */ +typedef struct +{ + __IO uint32_t HSTDMANXTDSC; /**< (HSTDMA Offset: 0x00) Host DMA Channel Next Descriptor Address Register */ + __IO uint32_t HSTDMAADDRESS; /**< (HSTDMA Offset: 0x04) Host DMA Channel Address Register */ + __IO uint32_t HSTDMACONTROL; /**< (HSTDMA Offset: 0x08) Host DMA Channel Control Register */ + __IO uint32_t HSTDMASTATUS; /**< (HSTDMA Offset: 0x0C) Host DMA Channel Status Register */ +} hstdma_t; + +/** \brief USBHS hardware registers */ +typedef struct +{ + __IO uint32_t DEVCTRL; /**< (USBHS Offset: 0x00) Device General Control Register */ + __I uint32_t DEVISR; /**< (USBHS Offset: 0x04) Device Global Interrupt Status Register */ + __O uint32_t DEVICR; /**< (USBHS Offset: 0x08) Device Global Interrupt Clear Register */ + __O uint32_t DEVIFR; /**< (USBHS Offset: 0x0C) Device Global Interrupt Set Register */ + __I uint32_t DEVIMR; /**< (USBHS Offset: 0x10) Device Global Interrupt Mask Register */ + __O uint32_t DEVIDR; /**< (USBHS Offset: 0x14) Device Global Interrupt Disable Register */ + __O uint32_t DEVIER; /**< (USBHS Offset: 0x18) Device Global Interrupt Enable Register */ + __IO uint32_t DEVEPT; /**< (USBHS Offset: 0x1C) Device Endpoint Register */ + __I uint32_t DEVFNUM; /**< (USBHS Offset: 0x20) Device Frame Number Register */ + __I uint8_t Reserved1[220]; + __IO uint32_t DEVEPTCFG[10]; /**< (USBHS Offset: 0x100) Device Endpoint Configuration Register */ + __I uint8_t Reserved2[8]; + __I uint32_t DEVEPTISR[10]; /**< (USBHS Offset: 0x130) Device Endpoint Interrupt Status Register */ + __I uint8_t Reserved3[8]; + __O uint32_t DEVEPTICR[10]; /**< (USBHS Offset: 0x160) Device Endpoint Interrupt Clear Register */ + __I uint8_t Reserved4[8]; + __O uint32_t DEVEPTIFR[10]; /**< (USBHS Offset: 0x190) Device Endpoint Interrupt Set Register */ + __I uint8_t Reserved5[8]; + __I uint32_t DEVEPTIMR[10]; /**< (USBHS Offset: 0x1C0) Device Endpoint Interrupt Mask Register */ + __I uint8_t Reserved6[8]; + __O uint32_t DEVEPTIER[10]; /**< (USBHS Offset: 0x1F0) Device Endpoint Interrupt Enable Register */ + __I uint8_t Reserved7[8]; + __O uint32_t DEVEPTIDR[10]; /**< (USBHS Offset: 0x220) Device Endpoint Interrupt Disable Register */ + __I uint8_t Reserved8[200]; + devdma_t DEVDMA[7]; /**< Offset: 0x310 Device DMA Channel Next Descriptor Address Register */ + __I uint8_t Reserved9[128]; + __IO uint32_t HSTCTRL; /**< (USBHS Offset: 0x400) Host General Control Register */ + __I uint32_t HSTISR; /**< (USBHS Offset: 0x404) Host Global Interrupt Status Register */ + __O uint32_t HSTICR; /**< (USBHS Offset: 0x408) Host Global Interrupt Clear Register */ + __O uint32_t HSTIFR; /**< (USBHS Offset: 0x40C) Host Global Interrupt Set Register */ + __I uint32_t HSTIMR; /**< (USBHS Offset: 0x410) Host Global Interrupt Mask Register */ + __O uint32_t HSTIDR; /**< (USBHS Offset: 0x414) Host Global Interrupt Disable Register */ + __O uint32_t HSTIER; /**< (USBHS Offset: 0x418) Host Global Interrupt Enable Register */ + __IO uint32_t HSTPIP; /**< (USBHS Offset: 0x41C) Host Pipe Register */ + __IO uint32_t HSTFNUM; /**< (USBHS Offset: 0x420) Host Frame Number Register */ + __IO uint32_t HSTADDR1; /**< (USBHS Offset: 0x424) Host Address 1 Register */ + __IO uint32_t HSTADDR2; /**< (USBHS Offset: 0x428) Host Address 2 Register */ + __IO uint32_t HSTADDR3; /**< (USBHS Offset: 0x42C) Host Address 3 Register */ + __I uint8_t Reserved10[208]; + __IO uint32_t HSTPIPCFG[10]; /**< (USBHS Offset: 0x500) Host Pipe Configuration Register */ + __I uint8_t Reserved11[8]; + __I uint32_t HSTPIPISR[10]; /**< (USBHS Offset: 0x530) Host Pipe Status Register */ + __I uint8_t Reserved12[8]; + __O uint32_t HSTPIPICR[10]; /**< (USBHS Offset: 0x560) Host Pipe Clear Register */ + __I uint8_t Reserved13[8]; + __O uint32_t HSTPIPIFR[10]; /**< (USBHS Offset: 0x590) Host Pipe Set Register */ + __I uint8_t Reserved14[8]; + __I uint32_t HSTPIPIMR[10]; /**< (USBHS Offset: 0x5C0) Host Pipe Mask Register */ + __I uint8_t Reserved15[8]; + __O uint32_t HSTPIPIER[10]; /**< (USBHS Offset: 0x5F0) Host Pipe Enable Register */ + __I uint8_t Reserved16[8]; + __O uint32_t HSTPIPIDR[10]; /**< (USBHS Offset: 0x620) Host Pipe Disable Register */ + __I uint8_t Reserved17[8]; + __IO uint32_t HSTPIPINRQ[10]; /**< (USBHS Offset: 0x650) Host Pipe IN Request Register */ + __I uint8_t Reserved18[8]; + __IO uint32_t HSTPIPERR[10]; /**< (USBHS Offset: 0x680) Host Pipe Error Register */ + __I uint8_t Reserved19[104]; + hstdma_t HSTDMA[7]; /**< Offset: 0x710 Host DMA Channel Next Descriptor Address Register */ + __I uint8_t Reserved20[128]; + __IO uint32_t CTRL; /**< (USBHS Offset: 0x800) General Control Register */ + __I uint32_t SR; /**< (USBHS Offset: 0x804) General Status Register */ + __O uint32_t SCR; /**< (USBHS Offset: 0x808) General Status Clear Register */ + __O uint32_t SFR; /**< (USBHS Offset: 0x80C) General Status Set Register */ +} dcd_registers_t; + +#define USB_REG ((dcd_registers_t *)0x40038000U) /**< \brief (USBHS) Base Address */ + +#define EP_MAX 10 + +#define FIFO_RAM_ADDR 0xA0100000u + +// Errata: The DMA feature is not available for Pipe/Endpoint 7 +#define EP_DMA_SUPPORT(epnum) (epnum >= 1 && epnum <= 6) + +#else // TODO : SAM3U + + +#endif + +#endif /* _COMMON_USB_REGS_H_ */ diff --git a/circuitpython/lib/tinyusb/src/portable/microchip/samx7x/dcd_samx7x.c b/circuitpython/lib/tinyusb/src/portable/microchip/samx7x/dcd_samx7x.c new file mode 100644 index 0000000..a82f29a --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/microchip/samx7x/dcd_samx7x.c @@ -0,0 +1,768 @@ +/* +* The MIT License (MIT) +* +* Copyright (c) 2018, hathach (tinyusb.org) +* Copyright (c) 2021, HiFiPhile +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* This file is part of the TinyUSB stack. +*/ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMX7X + +#include "device/dcd.h" +#include "sam.h" +#include "common_usb_regs.h" +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#ifndef USE_SOF +# define USE_SOF 0 +#endif + +// Dual bank can imporve performance, but need 2 times bigger packet buffer +// As SAM7x has only 4KB packet buffer, use with caution ! +// Enable in FS mode as packets are smaller +#ifndef USE_DUAL_BANK +# if TUD_OPT_HIGH_SPEED +# define USE_DUAL_BANK 0 +# else +# define USE_DUAL_BANK 1 +# endif +#endif + +#define EP_GET_FIFO_PTR(ep, scale) (((TU_XSTRCAT(TU_STRCAT(uint, scale),_t) (*)[0x8000 / ((scale) / 8)])FIFO_RAM_ADDR)[(ep)]) + +// DMA Channel Transfer Descriptor +typedef struct { + volatile uint32_t next_desc; + volatile uint32_t buff_addr; + volatile uint32_t chnl_ctrl; + uint32_t padding; +} dma_desc_t; + +// Transfer control context +typedef struct { + uint8_t * buffer; + uint16_t total_len; + uint16_t queued_len; + uint16_t max_packet_size; + uint8_t interval; + tu_fifo_t * fifo; +} xfer_ctl_t; + +static tusb_speed_t get_speed(void); +static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix); + +// DMA descriptors shouldn't be placed in ITCM ! +CFG_TUSB_MEM_SECTION static dma_desc_t dma_desc[6]; + +static xfer_ctl_t xfer_status[EP_MAX]; + +static const tusb_desc_endpoint_t ep0_desc = +{ + .bEndpointAddress = 0x00, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, +}; + +TU_ATTR_ALWAYS_INLINE static inline void CleanInValidateCache(uint32_t *addr, int32_t size) +{ + if (SCB->CCR & SCB_CCR_DC_Msk) + { + SCB_CleanInvalidateDCache_by_Addr(addr, size); + } + else + { + __DSB(); + __ISB(); + } +} +//------------------------------------------------------------------ +// Device API +//------------------------------------------------------------------ + +// Initialize controller to device mode +void dcd_init (uint8_t rhport) +{ + dcd_connect(rhport); +} + +// Enable device interrupt +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ((IRQn_Type) ID_USBHS); +} + +// Disable device interrupt +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ((IRQn_Type) ID_USBHS); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) dev_addr; + // DCD can only set address after status for this request is complete + // do it at dcd_edpt0_status_complete() + + // Response with zlp status + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +// Wake up host +void dcd_remote_wakeup (uint8_t rhport) +{ + (void) rhport; + USB_REG->DEVCTRL |= DEVCTRL_RMWKUP; +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + dcd_int_disable(rhport); + // Enable the USB controller in device mode + USB_REG->CTRL = CTRL_UIMOD | CTRL_USBE; + while (!(USB_REG->SR & SR_CLKUSABLE)); +#if TUD_OPT_HIGH_SPEED + USB_REG->DEVCTRL &= ~DEVCTRL_SPDCONF; +#else + USB_REG->DEVCTRL |= DEVCTRL_SPDCONF_LOW_POWER; +#endif + // Enable the End Of Reset, Suspend & Wakeup interrupts + USB_REG->DEVIER = (DEVIER_EORSTES | DEVIER_SUSPES | DEVIER_WAKEUPES); +#if USE_SOF + USB_REG->DEVIER = DEVIER_SOFES; +#endif + // Clear the End Of Reset, SOF & Wakeup interrupts + USB_REG->DEVICR = (DEVICR_EORSTC | DEVICR_SOFC | DEVICR_WAKEUPC); + // Manually set the Suspend Interrupt + USB_REG->DEVIFR |= DEVIFR_SUSPS; + // Ack the Wakeup Interrupt + USB_REG->DEVICR = DEVICR_WAKEUPC; + // Attach the device + USB_REG->DEVCTRL &= ~DEVCTRL_DETACH; + // Freeze USB clock + USB_REG->CTRL |= CTRL_FRZCLK; +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + dcd_int_disable(rhport); + // Disable all endpoints + USB_REG->DEVEPT &= ~(0x3FF << DEVEPT_EPEN0_Pos); + // Unfreeze USB clock + USB_REG->CTRL &= ~CTRL_FRZCLK; + while (!(USB_REG->SR & SR_CLKUSABLE)); + // Clear all the pending interrupts + USB_REG->DEVICR = DEVICR_Msk; + // Disable all interrupts + USB_REG->DEVIDR = DEVIDR_Msk; + // Detach the device + USB_REG->DEVCTRL |= DEVCTRL_DETACH; + // Disable the device address + USB_REG->DEVCTRL &=~(DEVCTRL_ADDEN | DEVCTRL_UADD); +} + +static tusb_speed_t get_speed(void) +{ + switch (USB_REG->SR & SR_SPEED) { + case SR_SPEED_FULL_SPEED: + default: + return TUSB_SPEED_FULL; + case SR_SPEED_HIGH_SPEED: + return TUSB_SPEED_HIGH; + case SR_SPEED_LOW_SPEED: + return TUSB_SPEED_LOW; + } +} + +static void dcd_ep_handler(uint8_t ep_ix) +{ + uint32_t int_status = USB_REG->DEVEPTISR[ep_ix]; + int_status &= USB_REG->DEVEPTIMR[ep_ix]; + + uint16_t count = (USB_REG->DEVEPTISR[ep_ix] & + DEVEPTISR_BYCT) >> DEVEPTISR_BYCT_Pos; + xfer_ctl_t *xfer = &xfer_status[ep_ix]; + + if (ep_ix == 0U) + { + static uint8_t ctrl_dir; + + if (int_status & DEVEPTISR_CTRL_RXSTPI) + { + ctrl_dir = (USB_REG->DEVEPTISR[0] & DEVEPTISR_CTRL_CTRLDIR) >> DEVEPTISR_CTRL_CTRLDIR_Pos; + // Setup packet should always be 8 bytes. If not, ignore it, and try again. + if (count == 8) + { + uint8_t *ptr = EP_GET_FIFO_PTR(0,8); + dcd_event_setup_received(0, ptr, true); + } + // Ack and disable SETUP interrupt + USB_REG->DEVEPTICR[0] = DEVEPTICR_CTRL_RXSTPIC; + USB_REG->DEVEPTIDR[0] = DEVEPTIDR_CTRL_RXSTPEC; + } + if (int_status & DEVEPTISR_RXOUTI) + { + uint8_t *ptr = EP_GET_FIFO_PTR(0,8); + + if (count && xfer->total_len) + { + uint16_t remain = xfer->total_len - xfer->queued_len; + if (count > remain) + { + count = remain; + } + if (xfer->buffer) + { + memcpy(xfer->buffer + xfer->queued_len, ptr, count); + } else + { + tu_fifo_write_n(xfer->fifo, ptr, count); + } + xfer->queued_len = (uint16_t)(xfer->queued_len + count); + } + // Acknowledge the interrupt + USB_REG->DEVEPTICR[0] = DEVEPTICR_RXOUTIC; + if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) + { + // RX COMPLETE + dcd_event_xfer_complete(0, 0, xfer->queued_len, XFER_RESULT_SUCCESS, true); + // Disable the interrupt + USB_REG->DEVEPTIDR[0] = DEVEPTIDR_RXOUTEC; + // Re-enable SETUP interrupt + if (ctrl_dir == 1) + { + USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; + } + } + } + if (int_status & DEVEPTISR_TXINI) + { + // Disable the interrupt + USB_REG->DEVEPTIDR[0] = DEVEPTIDR_TXINEC; + if ((xfer->total_len != xfer->queued_len)) + { + // TX not complete + dcd_transmit_packet(xfer, 0); + } else + { + // TX complete + dcd_event_xfer_complete(0, 0x80 + 0, xfer->total_len, XFER_RESULT_SUCCESS, true); + // Re-enable SETUP interrupt + if (ctrl_dir == 0) + { + USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; + } + } + } + } else + { + if (int_status & DEVEPTISR_RXOUTI) + { + if (count && xfer->total_len) + { + uint16_t remain = xfer->total_len - xfer->queued_len; + if (count > remain) + { + count = remain; + } + uint8_t *ptr = EP_GET_FIFO_PTR(ep_ix,8); + if (xfer->buffer) + { + memcpy(xfer->buffer + xfer->queued_len, ptr, count); + } else { + tu_fifo_write_n(xfer->fifo, ptr, count); + } + xfer->queued_len = (uint16_t)(xfer->queued_len + count); + } + // Clear the FIFO control flag to receive more data. + USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_FIFOCONC; + // Acknowledge the interrupt + USB_REG->DEVEPTICR[ep_ix] = DEVEPTICR_RXOUTIC; + if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) + { + // RX COMPLETE + dcd_event_xfer_complete(0, ep_ix, xfer->queued_len, XFER_RESULT_SUCCESS, true); + // Disable the interrupt + USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_RXOUTEC; + // Though the host could still send, we don't know. + } + } + if (int_status & DEVEPTISR_TXINI) + { + // Acknowledge the interrupt + USB_REG->DEVEPTICR[ep_ix] = DEVEPTICR_TXINIC; + if ((xfer->total_len != xfer->queued_len)) + { + // TX not complete + dcd_transmit_packet(xfer, ep_ix); + } else + { + // TX complete + dcd_event_xfer_complete(0, 0x80 + ep_ix, xfer->total_len, XFER_RESULT_SUCCESS, true); + // Disable the interrupt + USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_TXINEC; + } + } + } +} + +static void dcd_dma_handler(uint8_t ep_ix) +{ + uint32_t status = USB_REG->DEVDMA[ep_ix - 1].DEVDMASTATUS; + if (status & DEVDMASTATUS_CHANN_ENB) + { + return; // Ignore EOT_STA interrupt + } + // Disable DMA interrupt + USB_REG->DEVIDR = DEVIDR_DMA_1 << (ep_ix - 1); + + xfer_ctl_t *xfer = &xfer_status[ep_ix]; + uint16_t count = xfer->total_len - ((status & DEVDMASTATUS_BUFF_COUNT) >> DEVDMASTATUS_BUFF_COUNT_Pos); + if(USB_REG->DEVEPTCFG[ep_ix] & DEVEPTCFG_EPDIR) + { + dcd_event_xfer_complete(0, 0x80 + ep_ix, count, XFER_RESULT_SUCCESS, true); + } else + { + dcd_event_xfer_complete(0, ep_ix, count, XFER_RESULT_SUCCESS, true); + } +} + +void dcd_int_handler(uint8_t rhport) +{ + (void) rhport; + uint32_t int_status = USB_REG->DEVISR; + int_status &= USB_REG->DEVIMR; + // End of reset interrupt + if (int_status & DEVISR_EORST) + { + // Unfreeze USB clock + USB_REG->CTRL &= ~CTRL_FRZCLK; + while(!(USB_REG->SR & SR_CLKUSABLE)); + // Reset all endpoints + for (int ep_ix = 1; ep_ix < EP_MAX; ep_ix++) + { + USB_REG->DEVEPT |= 1 << (DEVEPT_EPRST0_Pos + ep_ix); + USB_REG->DEVEPT &=~(1 << (DEVEPT_EPRST0_Pos + ep_ix)); + } + dcd_edpt_open (0, &ep0_desc); + USB_REG->DEVICR = DEVICR_EORSTC; + USB_REG->DEVICR = DEVICR_WAKEUPC; + USB_REG->DEVICR = DEVICR_SUSPC; + USB_REG->DEVIER = DEVIER_SUSPES; + + dcd_event_bus_reset(rhport, get_speed(), true); + } + // End of Wakeup interrupt + if (int_status & DEVISR_WAKEUP) + { + USB_REG->CTRL &= ~CTRL_FRZCLK; + while (!(USB_REG->SR & SR_CLKUSABLE)); + USB_REG->DEVICR = DEVICR_WAKEUPC; + USB_REG->DEVIDR = DEVIDR_WAKEUPEC; + USB_REG->DEVIER = DEVIER_SUSPES; + + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + // Suspend interrupt + if (int_status & DEVISR_SUSP) + { + // Unfreeze USB clock + USB_REG->CTRL &= ~CTRL_FRZCLK; + while (!(USB_REG->SR & SR_CLKUSABLE)); + USB_REG->DEVICR = DEVICR_SUSPC; + USB_REG->DEVIDR = DEVIDR_SUSPEC; + USB_REG->DEVIER = DEVIER_WAKEUPES; + USB_REG->CTRL |= CTRL_FRZCLK; + + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } +#if USE_SOF + if(int_status & DEVISR_SOF) + { + USB_REG->DEVICR = DEVICR_SOFC; + + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } +#endif + // Endpoints interrupt + for (int ep_ix = 0; ep_ix < EP_MAX; ep_ix++) + { + if (int_status & (DEVISR_PEP_0 << ep_ix)) + { + dcd_ep_handler(ep_ix); + } + } + // Endpoints DMA interrupt + for (int ep_ix = 0; ep_ix < EP_MAX; ep_ix++) + { + if (EP_DMA_SUPPORT(ep_ix)) + { + if (int_status & (DEVISR_DMA_1 << (ep_ix - 1))) + { + dcd_dma_handler(ep_ix); + } + } + } +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS ) + { + uint8_t const dev_addr = (uint8_t) request->wValue; + + USB_REG->DEVCTRL |= dev_addr | DEVCTRL_ADDEN; + } +} + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(ep_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(ep_desc->bEndpointAddress); + uint16_t const epMaxPktSize = tu_edpt_packet_size(ep_desc); + tusb_xfer_type_t const eptype = (tusb_xfer_type_t)ep_desc->bmAttributes.xfer; + uint8_t fifoSize = 0; // FIFO size + uint16_t defaultEndpointSize = 8; // Default size of Endpoint + // Find upper 2 power number of epMaxPktSize + if (epMaxPktSize) + { + while (defaultEndpointSize < epMaxPktSize) + { + fifoSize++; + defaultEndpointSize <<= 1; + } + } + xfer_status[epnum].max_packet_size = epMaxPktSize; + + USB_REG->DEVEPT |= 1 << (DEVEPT_EPRST0_Pos + epnum); + USB_REG->DEVEPT &=~(1 << (DEVEPT_EPRST0_Pos + epnum)); + + if (epnum == 0) + { + // Enable the control endpoint - Endpoint 0 + USB_REG->DEVEPT |= DEVEPT_EPEN0; + // Configure the Endpoint 0 configuration register + USB_REG->DEVEPTCFG[0] = + ( + (fifoSize << DEVEPTCFG_EPSIZE_Pos) | + (TUSB_XFER_CONTROL << DEVEPTCFG_EPTYPE_Pos) | + (DEVEPTCFG_EPBK_1_BANK << DEVEPTCFG_EPBK_Pos) | + DEVEPTCFG_ALLOC + ); + USB_REG->DEVEPTIER[0] = DEVEPTIER_RSTDTS; + USB_REG->DEVEPTIDR[0] = DEVEPTIDR_CTRL_STALLRQC; + if (DEVEPTISR_CFGOK == (USB_REG->DEVEPTISR[0] & DEVEPTISR_CFGOK)) + { + // Endpoint configuration is successful + USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; + // Enable Endpoint 0 Interrupts + USB_REG->DEVIER = DEVIER_PEP_0; + return true; + } else + { + // Endpoint configuration is not successful + return false; + } + } else + { + // Enable the endpoint + USB_REG->DEVEPT |= ((0x01 << epnum) << DEVEPT_EPEN0_Pos); + // Set up the maxpacket size, fifo start address fifosize + // and enable the interrupt. CLear the data toggle. + // AUTOSW is needed for DMA ack ! + USB_REG->DEVEPTCFG[epnum] = + ( + (fifoSize << DEVEPTCFG_EPSIZE_Pos) | + (eptype << DEVEPTCFG_EPTYPE_Pos) | + (DEVEPTCFG_EPBK_1_BANK << DEVEPTCFG_EPBK_Pos) | + DEVEPTCFG_AUTOSW | + ((dir & 0x01) << DEVEPTCFG_EPDIR_Pos) + ); + if (eptype == TUSB_XFER_ISOCHRONOUS) + { + USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_NBTRANS_1_TRANS; + } +#if USE_DUAL_BANK + if (eptype == TUSB_XFER_ISOCHRONOUS || eptype == TUSB_XFER_BULK) + { + USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_EPBK_2_BANK; + } +#endif + USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_ALLOC; + USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RSTDTS; + USB_REG->DEVEPTIDR[epnum] = DEVEPTIDR_CTRL_STALLRQC; + if (DEVEPTISR_CFGOK == (USB_REG->DEVEPTISR[epnum] & DEVEPTISR_CFGOK)) + { + USB_REG->DEVIER = ((0x01 << epnum) << DEVIER_PEP_0_Pos); + return true; + } else + { + // Endpoint configuration is not successful + return false; + } + } +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); + + // Disable endpoint interrupt + USB_REG->DEVIDR = 1 << (DEVIDR_PEP_0_Pos + epnum); + // Disable EP + USB_REG->DEVEPT &=~(1 << (DEVEPT_EPEN0_Pos + epnum)); +} + +static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix) +{ + uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); + if (len) + { + if (len > xfer->max_packet_size) + { + len = xfer->max_packet_size; + } + uint8_t *ptr = EP_GET_FIFO_PTR(ep_ix,8); + if(xfer->buffer) + { + memcpy(ptr, xfer->buffer + xfer->queued_len, len); + } + else + { + tu_fifo_read_n(xfer->fifo, ptr, len); + } + __DSB(); + __ISB(); + xfer->queued_len = (uint16_t)(xfer->queued_len + len); + } + if (ep_ix == 0U) + { + // Control endpoint: clear the interrupt flag to send the data + USB_REG->DEVEPTICR[0] = DEVEPTICR_TXINIC; + } else + { + // Other endpoint types: clear the FIFO control flag to send the data + USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_FIFOCONC; + } + USB_REG->DEVEPTIER[ep_ix] = DEVEPTIER_TXINES; +} + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = &xfer_status[epnum]; + + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->fifo = NULL; + + if (EP_DMA_SUPPORT(epnum) && total_bytes != 0) + { + // Force the CPU to flush the buffer. We increase the size by 32 because the call aligns the + // address to 32-byte boundaries. + CleanInValidateCache((uint32_t*) tu_align((uint32_t) buffer, 4), total_bytes + 31); + uint32_t udd_dma_ctrl = total_bytes << DEVDMACONTROL_BUFF_LENGTH_Pos; + if (dir == TUSB_DIR_OUT) + { + udd_dma_ctrl |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; + } else { + udd_dma_ctrl |= DEVDMACONTROL_END_B_EN; + } + USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)buffer; + udd_dma_ctrl |= DEVDMACONTROL_END_BUFFIT | DEVDMACONTROL_CHANN_ENB; + // Disable IRQs to have a short sequence + // between read of EOT_STA and DMA enable + uint32_t irq_state = __get_PRIMASK(); + __disable_irq(); + if (!(USB_REG->DEVDMA[epnum - 1].DEVDMASTATUS & DEVDMASTATUS_END_TR_ST)) + { + USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl; + USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1); + __set_PRIMASK(irq_state); + return true; + } + __set_PRIMASK(irq_state); + + // Here a ZLP has been recieved + // and the DMA transfer must be not started. + // It is the end of transfer + return false; + } else + { + if (dir == TUSB_DIR_OUT) + { + USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES; + } else + { + dcd_transmit_packet(xfer,epnum); + } + } + return true; +} + +// The number of bytes has to be given explicitly to allow more flexible control of how many +// bytes should be written and second to keep the return value free to give back a boolean +// success message. If total_bytes is too big, the FIFO will copy only what is available +// into the USB buffer! +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = &xfer_status[epnum]; + if(epnum == 0x80) + xfer = &xfer_status[EP_MAX]; + + xfer->buffer = NULL; + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->fifo = ff; + + if (EP_DMA_SUPPORT(epnum) && total_bytes != 0) + { + tu_fifo_buffer_info_t info; + uint32_t udd_dma_ctrl_lin = DEVDMACONTROL_CHANN_ENB; + uint32_t udd_dma_ctrl_wrap = DEVDMACONTROL_CHANN_ENB | DEVDMACONTROL_END_BUFFIT; + if (dir == TUSB_DIR_OUT) + { + tu_fifo_get_write_info(ff, &info); + udd_dma_ctrl_lin |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; + udd_dma_ctrl_wrap |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; + } else { + tu_fifo_get_read_info(ff, &info); + if(info.len_wrap == 0) + { + udd_dma_ctrl_lin |= DEVDMACONTROL_END_B_EN; + } + udd_dma_ctrl_wrap |= DEVDMACONTROL_END_B_EN; + } + + // Clean invalidate cache of linear part + CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.ptr_lin, 4), info.len_lin + 31); + + USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)info.ptr_lin; + if (info.len_wrap) + { + // Clean invalidate cache of wrapped part + CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.ptr_wrap, 4), info.len_wrap + 31); + + dma_desc[epnum - 1].next_desc = 0; + dma_desc[epnum - 1].buff_addr = (uint32_t)info.ptr_wrap; + dma_desc[epnum - 1].chnl_ctrl = + udd_dma_ctrl_wrap | (info.len_wrap << DEVDMACONTROL_BUFF_LENGTH_Pos); + // Clean cache of wrapped DMA descriptor + CleanInValidateCache((uint32_t*)&dma_desc[epnum - 1], sizeof(dma_desc_t)); + + udd_dma_ctrl_lin |= DEVDMASTATUS_DESC_LDST; + USB_REG->DEVDMA[epnum - 1].DEVDMANXTDSC = (uint32_t)&dma_desc[epnum - 1]; + } else { + udd_dma_ctrl_lin |= DEVDMACONTROL_END_BUFFIT; + } + udd_dma_ctrl_lin |= (info.len_lin << DEVDMACONTROL_BUFF_LENGTH_Pos); + // Disable IRQs to have a short sequence + // between read of EOT_STA and DMA enable + uint32_t irq_state = __get_PRIMASK(); + __disable_irq(); + if (!(USB_REG->DEVDMA[epnum - 1].DEVDMASTATUS & DEVDMASTATUS_END_TR_ST)) + { + USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl_lin; + USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1); + __set_PRIMASK(irq_state); + return true; + } + __set_PRIMASK(irq_state); + + // Here a ZLP has been recieved + // and the DMA transfer must be not started. + // It is the end of transfer + return false; + } else + { + if (dir == TUSB_DIR_OUT) + { + USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES; + } else + { + dcd_transmit_packet(xfer,epnum); + } + } + return true; +} + +// Stall endpoint +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); + USB_REG->DEVEPTIER[epnum] = DEVEPTIER_CTRL_STALLRQS; + // Re-enable SETUP interrupt + if (epnum == 0) + { + USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; + } +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); + USB_REG->DEVEPTIDR[epnum] = DEVEPTIDR_CTRL_STALLRQC; + USB_REG->DEVEPTIER[epnum] = HSTPIPIER_RSTDTS; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/circuitpython/lib/tinyusb/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c new file mode 100644 index 0000000..1edcd84 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -0,0 +1,477 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 SE TEAM + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MM32F327X ) + +#include "reg_usb_otg_fs.h" +#include "mm32_device.h" +#include "hal_conf.h" +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +enum { + TOK_PID_OUT = 0x1u, + TOK_PID_IN = 0x9u, + TOK_PID_SETUP = 0xDu, +}; + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t head; + struct { + union { + struct { + uint16_t : 2; + uint16_t tok_pid : 4; + uint16_t data : 1; + uint16_t own : 1; + uint16_t : 8; + }; + struct { + uint16_t : 2; + uint16_t bdt_stall: 1; + uint16_t dts : 1; + uint16_t ninc : 1; + uint16_t keep : 1; + uint16_t : 10; + }; + }; + uint16_t bc : 10; + uint16_t : 6; + }; + }; + uint8_t *addr; +}buffer_descriptor_t; + +TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t state; + struct { + uint32_t max_packet_size :11; + uint32_t : 5; + uint32_t odd : 1; + uint32_t :15; + }; + }; + uint16_t length; + uint16_t remaining; +}endpoint_state_t; + +TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); + +typedef struct +{ + union { + /* [#EP][OUT,IN][EVEN,ODD] */ + buffer_descriptor_t bdt[16][2][2]; + uint16_t bda[512]; + }; + TU_ATTR_ALIGNED(4) union { + endpoint_state_t endpoint[16][2]; + endpoint_state_t endpoint_unified[16 * 2]; + }; + uint8_t setup_packet[8]; + uint8_t addr; +}dcd_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +// BDT(Buffer Descriptor Table) must be 256-byte aligned +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd; + +TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" ); + +static void prepare_next_setup_packet(uint8_t rhport) +{ + const unsigned out_odd = _dcd.endpoint[0][0].odd; + const unsigned in_odd = _dcd.endpoint[0][1].odd; + if (_dcd.bdt[0][0][out_odd].own) { + TU_LOG1("DCD fail to prepare the next SETUP %d %d\r\n", out_odd, in_odd); + return; + } + _dcd.bdt[0][0][out_odd].data = 0; + _dcd.bdt[0][0][out_odd ^ 1].data = 1; + _dcd.bdt[0][1][in_odd].data = 1; + _dcd.bdt[0][1][in_odd ^ 1].data = 0; + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), + _dcd.setup_packet, sizeof(_dcd.setup_packet)); +} + +static void process_stall(uint8_t rhport) +{ + if (USB_OTG_FS->EP_CTL[0] & USB_ENDPT_EPSTALL_MASK) { + /* clear stall condition of the control pipe */ + prepare_next_setup_packet(rhport); + USB_OTG_FS->EP_CTL[0] &= ~USB_ENDPT_EPSTALL_MASK; + } +} + +static void process_tokdne(uint8_t rhport) +{ + const unsigned s = USB_OTG_FS->STAT; + USB_OTG_FS->INT_STAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ + buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; + endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; + unsigned odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; + + /* fetch pid before discarded by the next steps */ + const unsigned pid = bd->tok_pid; + /* reset values for a next transfer */ + bd->bdt_stall = 0; + bd->dts = 1; + bd->ninc = 0; + bd->keep = 0; + /* update the odd variable to prepare for the next transfer */ + ep->odd = odd ^ 1; + if (pid == TOK_PID_SETUP) { + dcd_event_setup_received(rhport, bd->addr, true); + USB_OTG_FS->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + return; + } + if (s >> 4) { + TU_LOG1("TKDNE %x\r\n", s); + } + + const unsigned bc = bd->bc; + const unsigned remaining = ep->remaining - bc; + if (remaining && bc == ep->max_packet_size) { + /* continue the transferring consecutive data */ + ep->remaining = remaining; + const int next_remaining = remaining - ep->max_packet_size; + if (next_remaining > 0) { + /* prepare to the after next transfer */ + bd->addr += ep->max_packet_size * 2; + bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; + __DSB(); + bd->own = 1; /* the own bit must set after addr */ + } + return; + } + const unsigned length = ep->length; + dcd_event_xfer_complete(rhport, + ((s & USB_STAT_TX_MASK) << 4) | (s >> USB_STAT_ENDP_SHIFT), + length - remaining, XFER_RESULT_SUCCESS, true); + if (0 == (s & USB_STAT_ENDP_MASK) && 0 == length) { + /* After completion a ZLP of control transfer, + * it prepares for the next steup transfer. */ + if (_dcd.addr) { + /* When the transfer was the SetAddress, + * the device address should be updated here. */ + USB_OTG_FS->ADDR = _dcd.addr; + _dcd.addr = 0; + } + prepare_next_setup_packet(rhport); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + USB_OTG_FS->CTL |= USB_CTL_ODDRST_MASK; + USB_OTG_FS->ADDR = 0; + USB_OTG_FS->INT_ENB = (USB_OTG_FS->INT_ENB & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; + + USB_OTG_FS->EP_CTL[0] = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; + for (unsigned i = 1; i < 16; ++i) { + USB_OTG_FS->EP_CTL[i] = 0; + } + buffer_descriptor_t *bd = _dcd.bdt[0][0]; + for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { + bd->head = 0; + } + const endpoint_state_t ep0 = { + .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, + .odd = 0, + .length = 0, + .remaining = 0, + }; + _dcd.endpoint[0][0] = ep0; + _dcd.endpoint[0][1] = ep0; + tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0])); + _dcd.addr = 0; + prepare_next_setup_packet(rhport); + USB_OTG_FS->CTL &= ~USB_CTL_ODDRST_MASK; + dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); +} + +static void process_bus_inactive(uint8_t rhport) +{ + (void) rhport; + const unsigned inten = USB_OTG_FS->INT_ENB; + USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK; + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); +} + +static void process_bus_active(uint8_t rhport) +{ + (void) rhport; + const unsigned inten = USB_OTG_FS->INT_ENB; + USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); +} + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + tu_memclr(&_dcd, sizeof(_dcd)); + USB_OTG_FS->BDT_PAGE_01 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); + USB_OTG_FS->BDT_PAGE_02 = (uint8_t)((uintptr_t)_dcd.bdt >> 16); + USB_OTG_FS->BDT_PAGE_03 = (uint8_t)((uintptr_t)_dcd.bdt >> 24); + + dcd_connect(rhport); + NVIC_ClearPendingIRQ(USB_FS_IRQn); +} +#define USB_DEVICE_INTERRUPT_PRIORITY (3U) +void dcd_int_enable(uint8_t rhport) +{ + uint8_t irqNumber; + irqNumber = USB_FS_IRQn; + (void) rhport; + USB_OTG_FS->INT_ENB = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | + USB_INTEN_SLEEPEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; + NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY); + NVIC_EnableIRQ(USB_FS_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_FS_IRQn); + USB_OTG_FS->INT_ENB = 0; +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + _dcd.addr = dev_addr & 0x7F; + /* Response with status first before changing device address */ + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} +extern u32 SystemCoreClock; +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + unsigned cnt = SystemCoreClock / 100; + USB_OTG_FS->CTL |= USB_CTL_RESUME_MASK; + while (cnt--) __NOP(); + USB_OTG_FS->CTL &= ~USB_CTL_RESUME_MASK; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + USB_OTG_FS->CTL |= USB_CTL_USBENSOFEN_MASK; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB_OTG_FS->CTL = 0; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = ep_addr & 0xFu; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + const unsigned xfer = ep_desc->bmAttributes.xfer; + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + const unsigned odd = ep->odd; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0]; + + /* No support for control transfer */ + TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL)); + + ep->max_packet_size = tu_edpt_packet_size(ep_desc); + unsigned val = USB_ENDPT_EPCTLDIS_MASK; + val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK: 0; + val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; + USB_OTG_FS->EP_CTL[epn] |= val; + + if (xfer != TUSB_XFER_ISOCHRONOUS) { + bd[odd].dts = 1; + bd[odd].data = 0; + bd[odd ^ 1].dts = 1; + bd[odd ^ 1].data = 1; + } + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + const unsigned epn = ep_addr & 0xFu; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0]; + const unsigned msk = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; + USB_OTG_FS->EP_CTL[epn] &= ~msk; + ep->max_packet_size = 0; + ep->length = 0; + ep->remaining = 0; + bd->head = 0; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) +{ + (void) rhport; + NVIC_DisableIRQ(USB_FS_IRQn); + const unsigned epn = ep_addr & 0xFu; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; + + if (bd->own) { + TU_LOG1("DCD XFER fail %x %d %lx %lx\r\n", ep_addr, total_bytes, ep->state, bd->head); + return false; /* The last transfer has not completed */ + } + ep->length = total_bytes; + ep->remaining = total_bytes; + + const unsigned mps = ep->max_packet_size; + if (total_bytes > mps) { + buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; + /* When total_bytes is greater than the max packet size, + * it prepares to the next transfer to avoid NAK in advance. */ + next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; + next->addr = buffer + mps; + next->own = 1; + } + bd->bc = total_bytes >= mps ? mps: total_bytes; + bd->addr = buffer; + __DSB(); + bd->own = 1; /* the own bit must set after addr */ + NVIC_EnableIRQ(USB_FS_IRQn); + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + const unsigned epn = ep_addr & 0xFu; + if (0 == epn) { + USB_OTG_FS->EP_CTL[epn] |= USB_ENDPT_EPSTALL_MASK; + } else { + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + bd[0].bdt_stall = 1; + bd[1].bdt_stall = 1; + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + const unsigned epn = ep_addr & 0xFu; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + const unsigned odd = _dcd.endpoint[epn][dir].odd; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + + bd[odd ^ 1].own = 0; + bd[odd ^ 1].data = 1; + bd[odd ^ 1].bdt_stall = 0; + bd[odd].own = 0; + bd[odd].data = 0; + bd[odd].bdt_stall = 0; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void dcd_int_handler(uint8_t rhport) +{ + (void) rhport; + + uint32_t is = USB_OTG_FS->INT_STAT; + uint32_t msk = USB_OTG_FS->INT_ENB; + USB_OTG_FS->INT_STAT = is & ~msk; + is &= msk; + if (is & USB_ISTAT_ERROR_MASK) { + /* TODO: */ + uint32_t es = USB_OTG_FS->ERR_STAT; + USB_OTG_FS->ERR_STAT = es; + USB_OTG_FS->INT_STAT = is; /* discard any pending events */ + return; + } + + if (is & USB_ISTAT_USBRST_MASK) { + USB_OTG_FS->INT_STAT = is; /* discard any pending events */ + process_bus_reset(rhport); + return; + } + if (is & USB_ISTAT_SLEEP_MASK) { + USB_OTG_FS->INT_STAT = USB_ISTAT_SLEEP_MASK; + process_bus_inactive(rhport); + return; + } + if (is & USB_ISTAT_RESUME_MASK) { + USB_OTG_FS->INT_STAT = USB_ISTAT_RESUME_MASK; + process_bus_active(rhport); + return; + } + if (is & USB_ISTAT_SOFTOK_MASK) { + USB_OTG_FS->INT_STAT = USB_ISTAT_SOFTOK_MASK; + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + return; + } + if (is & USB_ISTAT_STALL_MASK) { + USB_OTG_FS->INT_STAT = USB_ISTAT_STALL_MASK; + process_stall(rhport); + return; + } + if (is & USB_ISTAT_TOKDNE_MASK) { + process_tokdne(rhport); + return; + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c b/circuitpython/lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c new file mode 100644 index 0000000..bc145ea --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -0,0 +1,1136 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_NRF5X + +#include "nrf.h" +#include "nrf_clock.h" +#include "nrf_power.h" +#include "nrfx_usbd_errata.h" +#include "device/dcd.h" + +// TODO remove later +#include "device/usbd.h" +#include "device/usbd_pvt.h" // to use defer function helper + +#if CFG_TUSB_OS == OPT_OS_MYNEWT +#include "mcu/mcu.h" +#endif + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +enum +{ + // Max allowed by USB specs + MAX_PACKET_SIZE = 64, + + // Mask of all END event (IN & OUT) for all endpoints. ENDEPIN0-7, ENDEPOUT0-7, ENDISOIN, ENDISOOUT + EDPT_END_ALL_MASK = (0xff << USBD_INTEN_ENDEPIN0_Pos) | (0xff << USBD_INTEN_ENDEPOUT0_Pos) | + USBD_INTENCLR_ENDISOIN_Msk | USBD_INTEN_ENDISOOUT_Msk +}; + +enum +{ + EP_ISO_NUM = 8, // Endpoint number is fixed (8) for ISOOUT and ISOIN + EP_CBI_COUNT = 8 // Control Bulk Interrupt endpoints count +}; + +// Transfer Descriptor +typedef struct +{ + uint8_t* buffer; + uint16_t total_len; + volatile uint16_t actual_len; + uint16_t mps; // max packet size + + // nRF will auto accept OUT packet after DMA is done + // indicate packet is already ACK + volatile bool data_received; + + // Set to true when data was transferred from RAM to ISO IN output buffer. + // New data can be put in ISO IN output buffer after SOF. + bool iso_in_transfer_ready; + +} xfer_td_t; + +static osal_mutex_def_t dcd_mutex_def; +static osal_mutex_t dcd_mutex; + +// Data for managing dcd +static struct +{ + // All 8 endpoints including control IN & OUT (offset 1) + // +1 for ISO endpoints + xfer_td_t xfer[EP_CBI_COUNT + 1][2]; + + // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA + volatile bool dma_running; +}_dcd; + +/*------------------------------------------------------------------*/ +/* Control / Bulk / Interrupt (CBI) Transfer + *------------------------------------------------------------------*/ + +// NVIC_GetEnableIRQ is only available in CMSIS v5 +#ifndef NVIC_GetEnableIRQ +static inline uint32_t NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif + +// check if we are in ISR +TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) +{ + return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) ? true : false; +} + +// helper to start DMA +static void start_dma(volatile uint32_t* reg_startep) +{ + _dcd.dma_running = true; + + (*reg_startep) = 1; + __ISB(); __DSB(); + + // TASKS_EP0STATUS, TASKS_EP0RCVOUT seem to need EasyDMA to be available + // However these don't trigger any DMA transfer and got ENDED event subsequently + // Therefore dma_pending is corrected right away + if ( (reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT) ) + { + _dcd.dma_running = false; + } +} + +// only 1 EasyDMA can be active at any time +// TODO use Cortex M4 LDREX and STREX command (atomic) to have better mutex access to EasyDMA +// since current implementation does not 100% guarded against race condition +static void edpt_dma_start(volatile uint32_t* reg_startep) +{ + // Called in critical section i.e within USB ISR, or USB/Global interrupt disabled + if ( is_in_isr() || __get_PRIMASK() || !NVIC_GetEnableIRQ(USBD_IRQn) ) + { + if (_dcd.dma_running) + { + //use usbd task to defer later + usbd_defer_func((osal_task_func_t) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); + }else + { + start_dma(reg_startep); + } + }else + { + // Called in non-critical thread-mode, should be 99% of the time. + // Should be safe to blocking wait until previous DMA transfer complete + uint8_t const rhport = 0; + bool started = false; + osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); + while(!started) + { + // LDREX/STREX may be needed in form of std atomic (required C11) or + // use osal mutex to guard against multiple core MCUs such as nRF53 + dcd_int_disable(rhport); + + if ( !_dcd.dma_running ) + { + start_dma(reg_startep); + started = true; + } + + dcd_int_enable(rhport); + + // osal_yield(); + } + osal_mutex_unlock(dcd_mutex); + } +} + +// DMA is complete +static void edpt_dma_end(void) +{ + TU_ASSERT(_dcd.dma_running, ); + _dcd.dma_running = false; +} + +// helper getting td +static inline xfer_td_t* get_td(uint8_t epnum, uint8_t dir) +{ + return &_dcd.xfer[epnum][dir]; +} + +// Start DMA to move data from Endpoint -> RAM +static void xact_out_dma(uint8_t epnum) +{ + xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); + uint32_t xact_len; + + if (epnum == EP_ISO_NUM) + { + xact_len = NRF_USBD->SIZE.ISOOUT; + // If ZERO bit is set, ignore ISOOUT length + if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) + { + xact_len = 0; + } + else + { + // Trigger DMA move data from Endpoint -> SRAM + NRF_USBD->ISOOUT.PTR = (uint32_t) xfer->buffer; + NRF_USBD->ISOOUT.MAXCNT = xact_len; + + edpt_dma_start(&NRF_USBD->TASKS_STARTISOOUT); + } + } + else + { + // limit xact len to remaining length + xact_len = tu_min16((uint16_t) NRF_USBD->SIZE.EPOUT[epnum], xfer->total_len - xfer->actual_len); + + // Trigger DMA move data from Endpoint -> SRAM + NRF_USBD->EPOUT[epnum].PTR = (uint32_t) xfer->buffer; + NRF_USBD->EPOUT[epnum].MAXCNT = xact_len; + + edpt_dma_start(&NRF_USBD->TASKS_STARTEPOUT[epnum]); + } +} + +// Prepare for a CBI transaction IN, call at the start +// it start DMA to transfer data from RAM -> Endpoint +static void xact_in_dma(uint8_t epnum) +{ + xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN); + + // Each transaction is up to Max Packet Size + uint16_t const xact_len = tu_min16(xfer->total_len - xfer->actual_len, xfer->mps); + + NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; + NRF_USBD->EPIN[epnum].MAXCNT = xact_len; + + edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]); +} + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ +void dcd_init (uint8_t rhport) +{ + TU_LOG1("dcd init\r\n"); + dcd_mutex = osal_mutex_create(&dcd_mutex_def); + (void) rhport; +} + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USBD_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USBD_IRQn); +} + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + (void) dev_addr; + // Set Address is automatically update by hw controller, nothing to do + + // Enable usbevent for suspend and resume detection + // Since the bus signal D+/D- are stable now. + + // Clear current pending first + NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE; + NRF_USBD->EVENTS_USBEVENT = 0; + + NRF_USBD->INTENSET = USBD_INTEN_USBEVENT_Msk; +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + // Bring controller out of low power mode + // will start wakeup when USBWUALLOWED is set + NRF_USBD->LOWPOWER = 0; +} + +// disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + NRF_USBD->USBPULLUP = 0; + + // Disable Pull-up does not trigger Power USB Removed, in fact it have no + // impact on the USB Power status at all -> need to submit unplugged event to the stack. + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, false); +} + +// connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + NRF_USBD->USBPULLUP = 1; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + uint8_t const ep_addr = desc_edpt->bEndpointAddress; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + _dcd.xfer[epnum][dir].mps = tu_edpt_packet_size(desc_edpt); + + if (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) + { + if (dir == TUSB_DIR_OUT) + { + NRF_USBD->INTENSET = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + epnum); + NRF_USBD->EPOUTEN |= TU_BIT(epnum); + + // Write any value to SIZE register will allow nRF to ACK/accept data + NRF_USBD->SIZE.EPOUT[epnum] = 0; + }else + { + NRF_USBD->INTENSET = TU_BIT(USBD_INTEN_ENDEPIN0_Pos + epnum); + NRF_USBD->EPINEN |= TU_BIT(epnum); + } + } + else + { + TU_ASSERT(epnum == EP_ISO_NUM); + if (dir == TUSB_DIR_OUT) + { + // SPLIT ISO buffer when ISO IN endpoint is already opened. + if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps) NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; + + // Clear old events + NRF_USBD->EVENTS_ENDISOOUT = 0; + + // Clear SOF event in case interrupt was not enabled yet. + if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0) NRF_USBD->EVENTS_SOF = 0; + + // Enable SOF and ISOOUT interrupts, and ISOOUT endpoint. + NRF_USBD->INTENSET = USBD_INTENSET_ENDISOOUT_Msk | USBD_INTENSET_SOF_Msk; + NRF_USBD->EPOUTEN |= USBD_EPOUTEN_ISOOUT_Msk; + } + else + { + NRF_USBD->EVENTS_ENDISOIN = 0; + + // SPLIT ISO buffer when ISO OUT endpoint is already opened. + if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps) NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; + + // Clear SOF event in case interrupt was not enabled yet. + if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0) NRF_USBD->EVENTS_SOF = 0; + + // Enable SOF and ISOIN interrupts, and ISOIN endpoint. + NRF_USBD->INTENSET = USBD_INTENSET_ENDISOIN_Msk | USBD_INTENSET_SOF_Msk; + NRF_USBD->EPINEN |= USBD_EPINEN_ISOIN_Msk; + } + } + + // clear stall and reset DataToggle + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr; + NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep_addr; + + __ISB(); __DSB(); + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + // disable interrupt to prevent race condition + dcd_int_disable(rhport); + + // disable all non-control (bulk + interrupt) endpoints + for ( uint8_t ep = 1; ep < EP_CBI_COUNT; ep++ ) + { + NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + ep) | TU_BIT(USBD_INTEN_ENDEPIN0_Pos + ep); + + NRF_USBD->TASKS_STARTEPIN[ep] = 0; + NRF_USBD->TASKS_STARTEPOUT[ep] = 0; + + tu_memclr(_dcd.xfer[ep], 2*sizeof(xfer_td_t)); + } + + // disable both ISO + NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk | USBD_INTENCLR_ENDISOOUT_Msk | USBD_INTENCLR_ENDISOIN_Msk; + NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir; + + NRF_USBD->TASKS_STARTISOIN = 0; + NRF_USBD->TASKS_STARTISOOUT = 0; + + tu_memclr(_dcd.xfer[EP_ISO_NUM], 2*sizeof(xfer_td_t)); + + // de-activate all non-control + NRF_USBD->EPOUTEN = 1UL; + NRF_USBD->EPINEN = 1UL; + + dcd_int_enable(rhport); +} + +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (epnum != EP_ISO_NUM) + { + // CBI + if (dir == TUSB_DIR_OUT) + { + NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + epnum); + NRF_USBD->EPOUTEN &= ~TU_BIT(epnum); + } + else + { + NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPIN0_Pos + epnum); + NRF_USBD->EPINEN &= ~TU_BIT(epnum); + } + } + else + { + _dcd.xfer[EP_ISO_NUM][dir].mps = 0; + // ISO + if (dir == TUSB_DIR_OUT) + { + NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOOUT_Msk; + NRF_USBD->EPOUTEN &= ~USBD_EPOUTEN_ISOOUT_Msk; + NRF_USBD->EVENTS_ENDISOOUT = 0; + } + else + { + NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOIN_Msk; + NRF_USBD->EPINEN &= ~USBD_EPINEN_ISOIN_Msk; + } + // One of the ISO endpoints closed, no need to split buffers any more. + NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir; + // When both ISO endpoint are close there is no need for SOF any more. + if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps + _dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps == 0) NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; + } + __ISB(); __DSB(); +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_td_t* xfer = get_td(epnum, dir); + + if (!is_in_isr()) { + osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); + dcd_int_disable(rhport); + } + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->actual_len = 0; + if (!is_in_isr()) { + dcd_int_enable(rhport); + osal_mutex_unlock(dcd_mutex); + } + + // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage + bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); + + if ( control_status ) + { + // Status Phase also requires EasyDMA has to be available as well !!!! + edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); + + // The nRF doesn't interrupt on status transmit so we queue up a success response. + dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); + } + else if ( dir == TUSB_DIR_OUT ) + { + if ( epnum == 0 ) + { + // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA + edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); + }else + { + if ( xfer->data_received && xfer->total_len > xfer->actual_len) + { + // Data is already received previously + // start DMA to copy to SRAM + xfer->data_received = false; + xact_out_dma(epnum); + } + else + { + // nRF auto accept next Bulk/Interrupt OUT packet + // nothing to do + } + } + } + else + { + // Start DMA to copy data from RAM -> Endpoint + xact_in_dma(epnum); + } + + return true; +} + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_td_t* xfer = get_td(epnum, dir); + + if ( epnum == 0 ) + { + NRF_USBD->TASKS_EP0STALL = 1; + }else if (epnum != EP_ISO_NUM) + { + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep_addr; + + // Note: nRF can auto ACK packet OUT before get stalled. + // There maybe data in endpoint fifo already, we need to pull it out + if ( (dir == TUSB_DIR_OUT) && xfer->data_received ) + { + xfer->data_received = false; + xact_out_dma(epnum); + } + } + + __ISB(); __DSB(); +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if ( epnum != 0 && epnum != EP_ISO_NUM ) + { + // reset data toggle to DATA0 + // First write this register with VALUE=Nop to select the endpoint, then either read it to get the status from + // VALUE, or write it again with VALUE=Data0 or Data1 + NRF_USBD->DTOGGLE = ep_addr; + NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep_addr; + + // clear stall + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr; + + // Write any value to SIZE register will allow nRF to ACK/accept data + if (dir == TUSB_DIR_OUT) NRF_USBD->SIZE.EPOUT[epnum] = 0; + + __ISB(); __DSB(); + } +} + +/*------------------------------------------------------------------*/ +/* Interrupt Handler + *------------------------------------------------------------------*/ +void bus_reset(void) +{ + // 6.35.6 USB controller automatically disabled all endpoints (except control) + NRF_USBD->EPOUTEN = 1UL; + NRF_USBD->EPINEN = 1UL; + + for(int i=0; i<8; i++) + { + NRF_USBD->TASKS_STARTEPIN[i] = 0; + NRF_USBD->TASKS_STARTEPOUT[i] = 0; + } + + NRF_USBD->TASKS_STARTISOIN = 0; + NRF_USBD->TASKS_STARTISOOUT = 0; + + // Clear USB Event Interrupt + NRF_USBD->EVENTS_USBEVENT = 0; + NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE; + + // Reset interrupt + NRF_USBD->INTENCLR = NRF_USBD->INTEN; + NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_USBEVENT_Msk | USBD_INTEN_EPDATA_Msk | + USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | USBD_INTEN_ENDEPOUT0_Msk; + + tu_varclr(&_dcd); + _dcd.xfer[0][TUSB_DIR_IN].mps = MAX_PACKET_SIZE; + _dcd.xfer[0][TUSB_DIR_OUT].mps = MAX_PACKET_SIZE; +} + +void dcd_int_handler(uint8_t rhport) +{ + (void) rhport; + + uint32_t const inten = NRF_USBD->INTEN; + uint32_t int_status = 0; + + volatile uint32_t* regevt = &NRF_USBD->EVENTS_USBRESET; + + for(uint8_t i=0; iactual_len = NRF_USBD->ISOIN.AMOUNT; + // Data transferred from RAM to endpoint output buffer. + // Next transfer can be scheduled after SOF. + xfer->iso_in_transfer_ready = true; + } + + if ( int_status & USBD_INTEN_SOF_Msk ) + { + bool iso_enabled = false; + + // ISOOUT: Transfer data gathered in previous frame from buffer to RAM + if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) + { + iso_enabled = true; + xact_out_dma(EP_ISO_NUM); + } + + // ISOIN: Notify client that data was transferred + if (NRF_USBD->EPINEN & USBD_EPINEN_ISOIN_Msk) + { + iso_enabled = true; + + xfer_td_t* xfer = get_td(EP_ISO_NUM, TUSB_DIR_IN); + if ( xfer->iso_in_transfer_ready ) + { + xfer->iso_in_transfer_ready = false; + dcd_event_xfer_complete(0, EP_ISO_NUM | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); + } + } + + if ( !iso_enabled ) + { + // ISO endpoint is not used, SOF is only enabled one-time for remote wakeup + // so we disable it now + NRF_USBD->INTENCLR = USBD_INTENSET_SOF_Msk; + } + + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } + + if ( int_status & USBD_INTEN_USBEVENT_Msk ) + { + TU_LOG(2, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); + + enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk }; + uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & EVT_CAUSE_MASK; + NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt + + if ( evt_cause & USBD_EVENTCAUSE_SUSPEND_Msk ) + { + // Put controller into low power mode + // Leave HFXO disable to application, since it may be used by other peripherals + NRF_USBD->LOWPOWER = 1; + + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + + if ( evt_cause & USBD_EVENTCAUSE_USBWUALLOWED_Msk ) + { + // USB is out of low power mode, and wakeup is allowed + // Initiate RESUME signal + NRF_USBD->DPDMVALUE = USBD_DPDMVALUE_STATE_Resume; + NRF_USBD->TASKS_DPDMDRIVE = 1; + + // There is no Resume interrupt for remote wakeup, enable SOF for to report bus ready state + // Clear SOF event in case interrupt was not enabled yet. + if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0) NRF_USBD->EVENTS_SOF = 0; + NRF_USBD->INTENSET = USBD_INTENSET_SOF_Msk; + } + + if ( evt_cause & USBD_EVENTCAUSE_RESUME_Msk ) + { + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + } + + // Setup tokens are specific to the Control endpoint. + if ( int_status & USBD_INTEN_EP0SETUP_Msk ) + { + uint8_t const setup[8] = + { + NRF_USBD->BMREQUESTTYPE , NRF_USBD->BREQUEST, NRF_USBD->WVALUEL , NRF_USBD->WVALUEH, + NRF_USBD->WINDEXL , NRF_USBD->WINDEXH , NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH + }; + + // nrf5x hw auto handle set address, there is no need to inform usb stack + tusb_control_request_t const * request = (tusb_control_request_t const *) setup; + + if ( !(TUSB_REQ_RCPT_DEVICE == request->bmRequestType_bit.recipient && + TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && + TUSB_REQ_SET_ADDRESS == request->bRequest) ) + { + dcd_event_setup_received(0, setup, true); + } + } + + if ( int_status & EDPT_END_ALL_MASK ) + { + // DMA complete move data from SRAM <-> Endpoint + // Must before endpoint transfer handling + edpt_dma_end(); + } + + //--------------------------------------------------------------------+ + /* Control/Bulk/Interrupt (CBI) Transfer + * + * Data flow is: + * (bus) (dma) + * Host <-------> Endpoint <-------> RAM + * + * For CBI OUT: + * - Host -> Endpoint + * EPDATA (or EP0DATADONE) interrupted, check EPDATASTATUS.EPOUT[i] + * to start DMA. For Bulk/Interrupt, this step can occur automatically (without sw), + * which means data may or may not be ready (out_received flag). + * - Endpoint -> RAM + * ENDEPOUT[i] interrupted, transaction complete, sw prepare next transaction + * + * For CBI IN: + * - RAM -> Endpoint + * ENDEPIN[i] interrupted indicate DMA is complete. HW will start + * to move data to host + * - Endpoint -> Host + * EPDATA (or EP0DATADONE) interrupted, check EPDATASTATUS.EPIN[i]. + * Transaction is complete, sw prepare next transaction + * + * Note: in both Control In and Out of Data stage from Host <-> Endpoint + * EP0DATADONE will be set as interrupt source + */ + //--------------------------------------------------------------------+ + + /* CBI OUT: Endpoint -> SRAM (aka transaction complete) + * Note: Since nRF controller auto ACK next packet without SW awareness + * We must handle this stage before Host -> Endpoint just in case 2 event happens at once + * + * ISO OUT: Transaction must fit in single packet, it can be shorter then total + * len if Host decides to sent fewer bytes, it this case transaction is also + * complete and next transfer is not initiated here like for CBI. + */ + for(uint8_t epnum=0; epnumEPOUT[epnum].AMOUNT; + + xfer->buffer += xact_len; + xfer->actual_len += xact_len; + + // Transfer complete if transaction len < Max Packet Size or total len is transferred + if ( (epnum != EP_ISO_NUM) && (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len) ) + { + if ( epnum == 0 ) + { + // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA + edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); + }else + { + // nRF auto accept next Bulk/Interrupt OUT packet + // nothing to do + } + }else + { + xfer->total_len = xfer->actual_len; + + // CBI OUT complete + dcd_event_xfer_complete(0, epnum, xfer->actual_len, XFER_RESULT_SUCCESS, true); + } + } + + // Ended event for CBI IN : nothing to do + } + + // Endpoint <-> Host ( In & OUT ) + if ( int_status & (USBD_INTEN_EPDATA_Msk | USBD_INTEN_EP0DATADONE_Msk) ) + { + uint32_t data_status = NRF_USBD->EPDATASTATUS; + NRF_USBD->EPDATASTATUS = data_status; + __ISB(); __DSB(); + + // EP0DATADONE is set with either Control Out on IN Data + // Since EPDATASTATUS cannot be used to determine whether it is control OUT or IN. + // We will use BMREQUESTTYPE in setup packet to determine the direction + bool const is_control_in = (int_status & USBD_INTEN_EP0DATADONE_Msk) && (NRF_USBD->BMREQUESTTYPE & TUSB_DIR_IN_MASK); + bool const is_control_out = (int_status & USBD_INTEN_EP0DATADONE_Msk) && !(NRF_USBD->BMREQUESTTYPE & TUSB_DIR_IN_MASK); + + // CBI In: Endpoint -> Host (transaction complete) + for(uint8_t epnum=0; epnumEPIN[epnum].AMOUNT; + + xfer->buffer += xact_len; + xfer->actual_len += xact_len; + + if ( xfer->actual_len < xfer->total_len ) + { + // Start DMA to copy next data packet + xact_in_dma(epnum); + } else + { + // CBI IN complete + dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); + } + } + } + + // CBI OUT: Host -> Endpoint + for(uint8_t epnum=0; epnumactual_len < xfer->total_len) + { + xact_out_dma(epnum); + }else + { + // Data overflow !!! Nah, nRF will auto accept next Bulk/Interrupt OUT packet + // Mark this endpoint with data received + xfer->data_received = true; + } + } + } + } +} + +//--------------------------------------------------------------------+ +// HFCLK helper +//--------------------------------------------------------------------+ +#ifdef SOFTDEVICE_PRESENT + +// For enable/disable hfclk with SoftDevice +#include "nrf_mbr.h" +#include "nrf_sdm.h" +#include "nrf_soc.h" + +#ifndef SD_MAGIC_NUMBER + #define SD_MAGIC_NUMBER 0x51B1E5DB +#endif + +static inline bool is_sd_existed(void) +{ + return *((uint32_t*)(SOFTDEVICE_INFO_STRUCT_ADDRESS+4)) == SD_MAGIC_NUMBER; +} + +// check if SD is existed and enabled +static inline bool is_sd_enabled(void) +{ + if ( !is_sd_existed() ) return false; + + uint8_t sd_en = false; + (void) sd_softdevice_is_enabled(&sd_en); + return sd_en; +} +#endif + +static bool hfclk_running(void) +{ +#ifdef SOFTDEVICE_PRESENT + if ( is_sd_enabled() ) + { + uint32_t is_running = 0; + (void) sd_clock_hfclk_is_running(&is_running); + return (is_running ? true : false); + } +#endif + + return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY); +} + +static void hfclk_enable(void) +{ +#if CFG_TUSB_OS == OPT_OS_MYNEWT + usb_clock_request(); + return; +#else + + // already running, nothing to do + if ( hfclk_running() ) return; + +#ifdef SOFTDEVICE_PRESENT + if ( is_sd_enabled() ) + { + (void)sd_clock_hfclk_request(); + return; + } +#endif + + nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); +#endif +} + +static void hfclk_disable(void) +{ +#if CFG_TUSB_OS == OPT_OS_MYNEWT + usb_clock_release(); + return; +#else + +#ifdef SOFTDEVICE_PRESENT + if ( is_sd_enabled() ) + { + (void)sd_clock_hfclk_release(); + return; + } +#endif + + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); +#endif +} + +// Power & Clock Peripheral on nRF5x to manage USB +// +// USB Bus power is managed by Power module, there are 3 VBUS power events: +// Detected, Ready, Removed. Upon these power events, This function will +// enable ( or disable ) usb & hfclk peripheral, set the usb pin pull up +// accordingly to the controller Startup/Standby Sequence in USBD 51.4 specs. +// +// Therefore this function must be called to handle USB power event by +// - nrfx_power_usbevt_init() : if Softdevice is not used or enabled +// - SoftDevice SOC event : if SD is used and enabled +void tusb_hal_nrf_power_event (uint32_t event) +{ + // Value is chosen to be as same as NRFX_POWER_USB_EVT_* in nrfx_power.h + enum { + USB_EVT_DETECTED = 0, + USB_EVT_REMOVED = 1, + USB_EVT_READY = 2 + }; + +#if CFG_TUSB_DEBUG >= 2 + const char* const power_evt_str[] = { "Detected", "Removed", "Ready" }; + TU_LOG(2, "Power USB event: %s\r\n", power_evt_str[event]); +#endif + + switch ( event ) + { + case USB_EVT_DETECTED: + if ( !NRF_USBD->ENABLE ) + { + // Prepare for receiving READY event: disable interrupt since we will blocking wait + NRF_USBD->INTENCLR = USBD_INTEN_USBEVENT_Msk; + NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; + __ISB(); __DSB(); // for sync + +#ifdef NRF52_SERIES // NRF53 does not need this errata + // ERRATA 171, 187, 166 + if ( nrfx_usbd_errata_187() ) + { + // CRITICAL_REGION_ENTER(); + if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) + { + *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t *) (0x4006ED14)) = 0x00000003; + *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; + } + else + { + *((volatile uint32_t *) (0x4006ED14)) = 0x00000003; + } + // CRITICAL_REGION_EXIT(); + } + + if ( nrfx_usbd_errata_171() ) + { + // CRITICAL_REGION_ENTER(); + if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) + { + *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t *) (0x4006EC14)) = 0x000000C0; + *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; + } + else + { + *((volatile uint32_t *) (0x4006EC14)) = 0x000000C0; + } + // CRITICAL_REGION_EXIT(); + } +#endif + + // Enable the peripheral (will cause Ready event) + NRF_USBD->ENABLE = 1; + __ISB(); __DSB(); // for sync + + // Enable HFCLK + hfclk_enable(); + } + break; + + case USB_EVT_READY: + // Skip if pull-up is enabled and HCLK is already running. + // Application probably call this more than necessary. + if ( NRF_USBD->USBPULLUP && hfclk_running() ) break; + + // Waiting for USBD peripheral enabled + while ( !(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE) ) { } + + NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; + __ISB(); __DSB(); // for sync + +#ifdef NRF52_SERIES + if ( nrfx_usbd_errata_171() ) + { + // CRITICAL_REGION_ENTER(); + if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) + { + *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t *) (0x4006EC14)) = 0x00000000; + *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; + } + else + { + *((volatile uint32_t *) (0x4006EC14)) = 0x00000000; + } + + // CRITICAL_REGION_EXIT(); + } + + if ( nrfx_usbd_errata_187() ) + { + // CRITICAL_REGION_ENTER(); + if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) + { + *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t *) (0x4006ED14)) = 0x00000000; + *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; + } + else + { + *((volatile uint32_t *) (0x4006ED14)) = 0x00000000; + } + // CRITICAL_REGION_EXIT(); + } + + if ( nrfx_usbd_errata_166() ) + { + *((volatile uint32_t *) (NRF_USBD_BASE + 0x800)) = 0x7E3; + *((volatile uint32_t *) (NRF_USBD_BASE + 0x804)) = 0x40; + + __ISB(); __DSB(); + } +#endif + + // ISO buffer Lower half for IN, upper half for OUT + NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; + + // Enable bus-reset interrupt + NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk; + + // Enable interrupt, priorities should be set by application + NVIC_ClearPendingIRQ(USBD_IRQn); + // Don't enable USBD interrupt yet, if dcd_init() did not finish yet + // Interrupt will be enabled by tud_init(), when USB stack is ready + // to handle interrupts. + if (tud_inited()) + { + NVIC_EnableIRQ(USBD_IRQn); + } + + // Wait for HFCLK + while ( !hfclk_running() ) { } + + // Enable pull up + NRF_USBD->USBPULLUP = 1; + __ISB(); __DSB(); // for sync + break; + + case USB_EVT_REMOVED: + if ( NRF_USBD->ENABLE ) + { + // Abort all transfers + + // Disable pull up + NRF_USBD->USBPULLUP = 0; + __ISB(); __DSB(); // for sync + + // Disable Interrupt + NVIC_DisableIRQ(USBD_IRQn); + + // disable all interrupt + NRF_USBD->INTENCLR = NRF_USBD->INTEN; + + NRF_USBD->ENABLE = 0; + __ISB(); __DSB(); // for sync + + hfclk_disable(); + + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, is_in_isr()); + } + break; + + default: break; + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc120/dcd_nuc120.c b/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc120/dcd_nuc120.c new file mode 100644 index 0000000..6947666 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc120/dcd_nuc120.c @@ -0,0 +1,500 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2020 Peter Lawrence + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* + Theory of operation: + + The NUC100/NUC120 USBD peripheral has six "EP"s, but each is simplex, + so two collectively (peripheral nomenclature of "EP0" and "EP1") are needed to + implement USB EP0. PERIPH_EP0 and PERIPH_EP1 are used by this driver for + EP0_IN and EP0_OUT respectively. This leaves up to four for user usage. +*/ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC120) + +#include "device/dcd.h" +#include "NUC100Series.h" + +/* allocation of USBD RAM for Setup, EP0_IN, and and EP_OUT */ +#define PERIPH_SETUP_BUF_BASE 0 +#define PERIPH_SETUP_BUF_LEN 8 +#define PERIPH_EP0_BUF_BASE (PERIPH_SETUP_BUF_BASE + PERIPH_SETUP_BUF_LEN) +#define PERIPH_EP0_BUF_LEN CFG_TUD_ENDPOINT0_SIZE +#define PERIPH_EP1_BUF_BASE (PERIPH_EP0_BUF_BASE + PERIPH_EP0_BUF_LEN) +#define PERIPH_EP1_BUF_LEN CFG_TUD_ENDPOINT0_SIZE +#define PERIPH_EP2_BUF_BASE (PERIPH_EP1_BUF_BASE + PERIPH_EP1_BUF_LEN) + +/* rather important info unfortunately not provided by device include files: how much there is */ +#define USBD_BUF_SIZE 512 + +enum ep_enum +{ + PERIPH_EP0 = 0, + PERIPH_EP1 = 1, + PERIPH_EP2 = 2, + PERIPH_EP3 = 3, + PERIPH_EP4 = 4, + PERIPH_EP5 = 5, + PERIPH_MAX_EP, +}; + +/* set by dcd_set_address() */ +static volatile uint8_t assigned_address; + +/* reset by dcd_init(), this is used by dcd_edpt_open() to assign USBD peripheral buffer addresses */ +static uint32_t bufseg_addr; + +/* used by dcd_edpt_xfer() and the ISR to reset the data sync (DATA0/DATA1) in an EP0_IN transfer */ +static bool active_ep0_xfer; + +/* RAM table needed to track ongoing transfers performed by dcd_edpt_xfer(), dcd_in_xfer(), and the ISR */ +static struct xfer_ctl_t +{ + uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */ + // tu_fifo_t * ff; /* pointer to FIFO required for dcd_edpt_xfer_fifo() */ // TODO support dcd_edpt_xfer_fifo API + union { + uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */ + uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */ + }; + uint16_t max_packet_size; /* needed since device driver only finds out this at runtime */ + uint16_t total_bytes; /* quantity needed to pass as argument to dcd_event_xfer_complete() (for IN endpoints) */ +} xfer_table[PERIPH_MAX_EP]; + +/* + local helper functions +*/ + +static void usb_attach(void) +{ + USBD->DRVSE0 &= ~USBD_DRVSE0_DRVSE0_Msk; +} + +static void usb_detach(void) +{ + USBD->DRVSE0 |= USBD_DRVSE0_DRVSE0_Msk; +} + +static inline void usb_memcpy(uint8_t *dest, uint8_t *src, uint16_t size) +{ + while(size--) *dest++ = *src++; +} + +static void usb_control_send_zlp(void) +{ + USBD->EP[PERIPH_EP0].CFG |= USBD_CFG_DSQ_SYNC_Msk; + USBD->EP[PERIPH_EP0].MXPLD = 0; +} + +/* reconstruct ep_addr from particular USB Configuration Register */ +static uint8_t decode_ep_addr(USBD_EP_T *ep) +{ + uint8_t ep_addr = ep->CFG & USBD_CFG_EP_NUM_Msk; + if ( USBD_CFG_EPMODE_IN == (ep->CFG & USBD_CFG_STATE_Msk) ) + ep_addr |= TUSB_DIR_IN_MASK; + return ep_addr; +} + +/* map 8-bit ep_addr into peripheral endpoint index (PERIPH_EP0...) */ +static USBD_EP_T *ep_entry(uint8_t ep_addr, bool add) +{ + USBD_EP_T *ep; + enum ep_enum ep_index; + + for (ep_index = PERIPH_EP0, ep = USBD->EP; ep_index < PERIPH_MAX_EP; ep_index++, ep++) + { + if (add) + { + /* take first peripheral endpoint that is unused */ + if (0 == (ep->CFG & USBD_CFG_STATE_Msk)) return ep; + } + else + { + /* find a peripheral endpoint that matches ep_addr */ + uint8_t candidate_ep_addr = decode_ep_addr(ep); + if (candidate_ep_addr == ep_addr) return ep; + } + } + + return NULL; +} + +/* perform an IN endpoint transfer; this is called by dcd_edpt_xfer() and the ISR */ +static void dcd_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) +{ + uint16_t bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size); + +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_read_n(xfer->ff, (void *) (USBD_BUF_BASE + ep->BUFSEG), bytes_now); + } + else +#endif + { + // USB SRAM seems to only support byte access and memcpy could possibly do it by words + usb_memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now); + } + + ep->MXPLD = bytes_now; +} + +/* called by dcd_init() as well as by the ISR during a USB bus reset */ +static void bus_reset(void) +{ + USBD->STBUFSEG = PERIPH_SETUP_BUF_BASE; + + for (enum ep_enum ep_index = PERIPH_EP0; ep_index < PERIPH_MAX_EP; ep_index++) + { + USBD->EP[ep_index].CFG = 0; + USBD->EP[ep_index].CFGP = 0; + } + + /* allocate the default EP0 endpoints */ + + USBD->EP[PERIPH_EP0].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_IN; + USBD->EP[PERIPH_EP0].BUFSEG = PERIPH_EP0_BUF_BASE; + xfer_table[PERIPH_EP0].max_packet_size = PERIPH_EP0_BUF_LEN; + + USBD->EP[PERIPH_EP1].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_OUT; + USBD->EP[PERIPH_EP1].BUFSEG = PERIPH_EP1_BUF_BASE; + xfer_table[PERIPH_EP1].max_packet_size = PERIPH_EP1_BUF_LEN; + + /* USB RAM beyond what we've allocated above is available to the user */ + bufseg_addr = PERIPH_EP2_BUF_BASE; + + /* Reset USB device address */ + USBD->FADDR = 0; + + /* reset EP0_IN flag */ + active_ep0_xfer = false; +} + +/* centralized location for USBD interrupt enable bit mask */ +static const uint32_t enabled_irqs = USBD_INTSTS_FLDET_STS_Msk | USBD_INTSTS_BUS_STS_Msk | USBD_INTSTS_SETUP_Msk | USBD_INTSTS_USB_STS_Msk; + +/* + NUC100/NUC120 TinyUSB API driver implementation +*/ + +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + USBD->ATTR = 0x7D0; + + usb_detach(); + + bus_reset(); + + usb_attach(); + + USBD->INTSTS = enabled_irqs; + USBD->INTEN = enabled_irqs; +} + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USBD_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USBD_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + usb_control_send_zlp(); /* SET_ADDRESS is the one exception where TinyUSB doesn't use dcd_edpt_xfer() to generate a ZLP */ + assigned_address = dev_addr; +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + USBD->ATTR = USBD_ATTR_RWAKEUP_Msk; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void) rhport; + + USBD_EP_T *ep = ep_entry(p_endpoint_desc->bEndpointAddress, true); + TU_ASSERT(ep); + + /* mine the data for the information we need */ + int const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + int const size = tu_edpt_packet_size(p_endpoint_desc); + tusb_xfer_type_t const type = (tusb_xfer_type_t) p_endpoint_desc->bmAttributes.xfer; + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* allocate buffer from USB RAM */ + ep->BUFSEG = bufseg_addr; + bufseg_addr += size; + TU_ASSERT(bufseg_addr <= USBD_BUF_SIZE); + + /* construct USB Configuration Register value and then write it */ + uint32_t cfg = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + cfg |= (TUSB_DIR_IN == dir) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT; + if (TUSB_XFER_ISOCHRONOUS == type) + cfg |= USBD_CFG_TYPE_ISO; + ep->CFG = cfg; + + /* make a note of the endpoint size */ + xfer->max_packet_size = size; + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void) rhport; + + /* mine the data for the information we need */ + tusb_dir_t dir = tu_edpt_dir(ep_addr); + USBD_EP_T *ep = ep_entry(ep_addr, false); + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* store away the information we'll needing now and later */ + xfer->data_ptr = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->in_remaining_bytes = total_bytes; + xfer->total_bytes = total_bytes; + + /* for the first of one or more EP0_IN packets in a message, the first must be DATA1 */ + if ( (0x80 == ep_addr) && !active_ep0_xfer ) ep->CFG |= USBD_CFG_DSQ_SYNC_Msk; + + if (TUSB_DIR_IN == dir) + { + dcd_in_xfer(xfer, ep); + } + else + { + xfer->out_bytes_so_far = 0; + ep->MXPLD = xfer->max_packet_size; + } + + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + + /* mine the data for the information we need */ + tusb_dir_t dir = tu_edpt_dir(ep_addr); + USBD_EP_T *ep = ep_entry(ep_addr, false); + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* store away the information we'll needing now and later */ + xfer->data_ptr = NULL; // Indicates a FIFO shall be used + xfer->ff = ff; + xfer->in_remaining_bytes = total_bytes; + xfer->total_bytes = total_bytes; + + if (TUSB_DIR_IN == dir) + { + dcd_in_xfer(xfer, ep); + } + else + { + xfer->out_bytes_so_far = 0; + ep->MXPLD = xfer->max_packet_size; + } + + return true; +} +#endif + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + USBD_EP_T *ep = ep_entry(ep_addr, false); + ep->CFGP |= USBD_CFGP_SSTALL_Msk; +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + USBD_EP_T *ep = ep_entry(ep_addr, false); + ep->CFG |= USBD_CFG_CSTALL_Msk; +} + +void dcd_int_handler(uint8_t rhport) +{ + (void) rhport; + + uint32_t status = USBD->INTSTS; + uint32_t state = USBD->ATTR & 0xf; + + if(status & USBD_INTSTS_FLDET_STS_Msk) + { + if(USBD->FLDET & USBD_FLDET_FLDET_Msk) + { + /* USB connect */ + USBD->ATTR |= USBD_ATTR_USB_EN_Msk | USBD_ATTR_PHY_EN_Msk; + } + else + { + /* USB disconnect */ + USBD->ATTR &= ~USBD_ATTR_USB_EN_Msk; + } + } + + if(status & USBD_INTSTS_BUS_STS_Msk) + { + if(state & USBD_STATE_USBRST) + { + /* USB bus reset */ + USBD->ATTR |= USBD_ATTR_USB_EN_Msk | USBD_ATTR_PHY_EN_Msk; + + bus_reset(); + dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); + } + + if(state & USBD_STATE_SUSPEND) + { + /* Enable USB but disable PHY */ + USBD->ATTR &= ~USBD_ATTR_PHY_EN_Msk; + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + + if(state & USBD_STATE_RESUME) + { + /* Enable USB and enable PHY */ + USBD->ATTR |= USBD_ATTR_USB_EN_Msk | USBD_ATTR_PHY_EN_Msk; + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + } + + if(status & USBD_INTSTS_SETUP_Msk) + { + /* clear the data ready flag of control endpoints */ + USBD->EP[PERIPH_EP0].CFGP |= USBD_CFGP_CLRRDY_Msk; + USBD->EP[PERIPH_EP1].CFGP |= USBD_CFGP_CLRRDY_Msk; + + /* get SETUP packet from USB buffer */ + dcd_event_setup_received(0, (uint8_t *)USBD_BUF_BASE, true); + } + + if(status & USBD_INTSTS_USB_STS_Msk) + { + if (status & (1UL << USBD_INTSTS_EPEVT_Pos)) /* PERIPH_EP0 (EP0_IN) event: this is treated separately from the rest */ + { + /* given ACK from host has happened, we can now set the address (if not already done) */ + if((USBD->FADDR != assigned_address) && (USBD->FADDR == 0)) USBD->FADDR = assigned_address; + + uint16_t const available_bytes = USBD->EP[PERIPH_EP0].MXPLD; + + active_ep0_xfer = (available_bytes == xfer_table[PERIPH_EP0].max_packet_size); + + dcd_event_xfer_complete(0, 0x80, available_bytes, XFER_RESULT_SUCCESS, true); + } + + /* service PERIPH_EP1 through PERIPH_EP7 */ + enum ep_enum ep_index; + uint32_t mask; + struct xfer_ctl_t *xfer; + USBD_EP_T *ep; + for (ep_index = PERIPH_EP1, mask = (2UL << USBD_INTSTS_EPEVT_Pos), xfer = &xfer_table[PERIPH_EP1], ep = &USBD->EP[PERIPH_EP1]; ep_index < PERIPH_MAX_EP; ep_index++, mask <<= 1, xfer++, ep++) + { + if(status & mask) + { + USBD->INTSTS = mask; + + uint16_t const available_bytes = ep->MXPLD; + uint8_t const ep_addr = decode_ep_addr(ep); + bool const out_ep = !(ep_addr & TUSB_DIR_IN_MASK); + + if (out_ep) + { + /* copy the data from the PC to the previously provided buffer */ +#if 0 // // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_write_n(xfer->ff, (const void *) (USBD_BUF_BASE + ep->BUFSEG), available_bytes); + } + else +#endif + { + // USB SRAM seems to only support byte access and memcpy could possibly do it by words + usb_memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes); + xfer->data_ptr += available_bytes; + } + + xfer->out_bytes_so_far += available_bytes; + + /* when the transfer is finished, alert TinyUSB; otherwise, accept more data */ + if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) ) + dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); + else + ep->MXPLD = xfer->max_packet_size; + } + else + { + /* update the bookkeeping to reflect the data that has now been sent to the PC */ + xfer->in_remaining_bytes -= available_bytes; + + xfer->data_ptr += available_bytes; + + /* if more data to send, send it; otherwise, alert TinyUSB that we've finished */ + if (xfer->in_remaining_bytes) + dcd_in_xfer(xfer, ep); + else + dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); + } + } + } + } + + /* acknowledge all interrupts */ + USBD->INTSTS = status & enabled_irqs; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + usb_detach(); +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + usb_attach(); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc121/dcd_nuc121.c b/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc121/dcd_nuc121.c new file mode 100644 index 0000000..88d514b --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -0,0 +1,554 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Peter Lawrence + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* + Theory of operation: + + The NUC121/NUC125/NUC126 USBD peripheral has eight "EP"s, but each is simplex, + so two collectively (peripheral nomenclature of "EP0" and "EP1") are needed to + implement USB EP0. PERIPH_EP0 and PERIPH_EP1 are used by this driver for + EP0_IN and EP0_OUT respectively. This leaves up to six for user usage. +*/ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && ( (CFG_TUSB_MCU == OPT_MCU_NUC121) || (CFG_TUSB_MCU == OPT_MCU_NUC126) ) + +#include "device/dcd.h" +#include "NuMicro.h" + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#ifndef USE_SOF +# define USE_SOF 0 +#endif + +/* allocation of USBD RAM for Setup, EP0_IN, and and EP_OUT */ +#define PERIPH_SETUP_BUF_BASE 0 +#define PERIPH_SETUP_BUF_LEN 8 +#define PERIPH_EP0_BUF_BASE (PERIPH_SETUP_BUF_BASE + PERIPH_SETUP_BUF_LEN) +#define PERIPH_EP0_BUF_LEN CFG_TUD_ENDPOINT0_SIZE +#define PERIPH_EP1_BUF_BASE (PERIPH_EP0_BUF_BASE + PERIPH_EP0_BUF_LEN) +#define PERIPH_EP1_BUF_LEN CFG_TUD_ENDPOINT0_SIZE +#define PERIPH_EP2_BUF_BASE (PERIPH_EP1_BUF_BASE + PERIPH_EP1_BUF_LEN) + +/* rather important info unfortunately not provided by device include files: how much there is */ +#define USBD_BUF_SIZE ((CFG_TUSB_MCU == OPT_MCU_NUC121) ? 768 : 512) + +enum ep_enum +{ + PERIPH_EP0 = 0, + PERIPH_EP1 = 1, + PERIPH_EP2 = 2, + PERIPH_EP3 = 3, + PERIPH_EP4 = 4, + PERIPH_EP5 = 5, + PERIPH_EP6 = 6, + PERIPH_EP7 = 7, + PERIPH_MAX_EP, +}; + +/* reset by dcd_init(), this is used by dcd_edpt_open() to assign USBD peripheral buffer addresses */ +static uint32_t bufseg_addr; + +/* used by dcd_edpt_xfer() and the ISR to reset the data sync (DATA0/DATA1) in an EP0_IN transfer */ +static bool active_ep0_xfer; + +/* RAM table needed to track ongoing transfers performed by dcd_edpt_xfer(), dcd_in_xfer(), and the ISR */ +static struct xfer_ctl_t +{ + uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */ + // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API + union { + uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */ + uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */ + }; + uint16_t max_packet_size; /* needed since device driver only finds out this at runtime */ + uint16_t total_bytes; /* quantity needed to pass as argument to dcd_event_xfer_complete() (for IN endpoints) */ +} xfer_table[PERIPH_MAX_EP]; + +/* + local helper functions +*/ + +static void usb_attach(void) +{ + USBD->SE0 &= ~USBD_SE0_SE0_Msk; +} + +static void usb_detach(void) +{ + USBD->SE0 |= USBD_SE0_SE0_Msk; +} + +static inline void usb_memcpy(uint8_t *dest, uint8_t *src, uint16_t size) +{ + while(size--) *dest++ = *src++; +} + +static void usb_control_send_zlp(void) +{ + USBD->EP[PERIPH_EP0].CFG |= USBD_CFG_DSQSYNC_Msk; + USBD->EP[PERIPH_EP0].MXPLD = 0; +} + +/* reconstruct ep_addr from particular USB Configuration Register */ +static uint8_t decode_ep_addr(USBD_EP_T *ep) +{ + uint8_t ep_addr = ep->CFG & USBD_CFG_EPNUM_Msk; + if ( USBD_CFG_EPMODE_IN == (ep->CFG & USBD_CFG_STATE_Msk) ) + ep_addr |= TUSB_DIR_IN_MASK; + return ep_addr; +} + +/* map 8-bit ep_addr into peripheral endpoint index (PERIPH_EP0...) */ +static USBD_EP_T *ep_entry(uint8_t ep_addr, bool add) +{ + USBD_EP_T *ep; + enum ep_enum ep_index; + + for (ep_index = PERIPH_EP0, ep = USBD->EP; ep_index < PERIPH_MAX_EP; ep_index++, ep++) + { + if (add) + { + /* take first peripheral endpoint that is unused */ + if (0 == (ep->CFG & USBD_CFG_STATE_Msk)) return ep; + } + else + { + /* find a peripheral endpoint that matches ep_addr */ + uint8_t candidate_ep_addr = decode_ep_addr(ep); + if (candidate_ep_addr == ep_addr) return ep; + } + } + + return NULL; +} + +/* perform an IN endpoint transfer; this is called by dcd_edpt_xfer() and the ISR */ +static void dcd_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) +{ + uint16_t bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size); + +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_read_n(xfer->ff, (void *) (USBD_BUF_BASE + ep->BUFSEG), bytes_now); + } + else +#endif + { + // USB SRAM seems to only support byte access and memcpy could possibly do it by words + usb_memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now); + } + + ep->MXPLD = bytes_now; +} + +/* called by dcd_init() as well as by the ISR during a USB bus reset */ +static void bus_reset(void) +{ + USBD->STBUFSEG = PERIPH_SETUP_BUF_BASE; + + for (enum ep_enum ep_index = PERIPH_EP0; ep_index < PERIPH_MAX_EP; ep_index++) + { + USBD->EP[ep_index].CFG = 0; + USBD->EP[ep_index].CFGP = 0; + } + + /* allocate the default EP0 endpoints */ + + USBD->EP[PERIPH_EP0].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_IN; + USBD->EP[PERIPH_EP0].BUFSEG = PERIPH_EP0_BUF_BASE; + xfer_table[PERIPH_EP0].max_packet_size = PERIPH_EP0_BUF_LEN; + + USBD->EP[PERIPH_EP1].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_OUT; + USBD->EP[PERIPH_EP1].BUFSEG = PERIPH_EP1_BUF_BASE; + xfer_table[PERIPH_EP1].max_packet_size = PERIPH_EP1_BUF_LEN; + + /* USB RAM beyond what we've allocated above is available to the user */ + bufseg_addr = PERIPH_EP2_BUF_BASE; + + /* Reset USB device address */ + USBD->FADDR = 0; + + /* reset EP0_IN flag */ + active_ep0_xfer = false; +} + +/* centralized location for USBD interrupt enable bit mask */ +enum { + ENABLED_IRQS = USBD_INTSTS_VBDETIF_Msk | USBD_INTSTS_BUSIF_Msk | USBD_INTSTS_SETUP_Msk | + USBD_INTSTS_USBIF_Msk | (USE_SOF ? USBD_INTSTS_SOFIF_Msk : 0) +}; + +/* + NUC121/NUC125/NUC126 TinyUSB API driver implementation +*/ + +void dcd_init(uint8_t rhport) +{ + (void) rhport; + +#ifdef SUPPORT_LPM + USBD->ATTR = 0x7D0 | USBD_LPMACK; +#else + USBD->ATTR = 0x7D0; +#endif + + usb_detach(); + + bus_reset(); + + usb_attach(); + + USBD->INTSTS = ENABLED_IRQS; + USBD->INTEN = ENABLED_IRQS; +} + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USBD_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USBD_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + (void) dev_addr; + usb_control_send_zlp(); /* SET_ADDRESS is the one exception where TinyUSB doesn't use dcd_edpt_xfer() to generate a ZLP */ + + // DCD can only set address after status for this request is complete. + // do it at dcd_edpt0_status_complete() +} + +static void remote_wakeup_delay(void) +{ + // try to delay for 1 ms + uint32_t count = SystemCoreClock / 1000; + while(count--) __NOP(); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + // Enable PHY before sending Resume('K') state + USBD->ATTR |= USBD_ATTR_PHYEN_Msk; + USBD->ATTR |= USBD_ATTR_RWAKEUP_Msk; + + // Per specs: remote wakeup signal bit must be clear within 1-15ms + remote_wakeup_delay(); + USBD->ATTR &=~USBD_ATTR_RWAKEUP_Msk; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void) rhport; + + USBD_EP_T *ep = ep_entry(p_endpoint_desc->bEndpointAddress, true); + TU_ASSERT(ep); + + /* mine the data for the information we need */ + int const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + int const size = tu_edpt_packet_size(p_endpoint_desc); + tusb_xfer_type_t const type = (tusb_xfer_type_t) p_endpoint_desc->bmAttributes.xfer; + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* allocate buffer from USB RAM */ + ep->BUFSEG = bufseg_addr; + bufseg_addr += size; + TU_ASSERT(bufseg_addr <= USBD_BUF_SIZE); + + /* construct USB Configuration Register value and then write it */ + uint32_t cfg = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + cfg |= (TUSB_DIR_IN == dir) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT; + if (TUSB_XFER_ISOCHRONOUS == type) + cfg |= USBD_CFG_TYPE_ISO; + ep->CFG = cfg; + + /* make a note of the endpoint size */ + xfer->max_packet_size = size; + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void) rhport; + + /* mine the data for the information we need */ + tusb_dir_t dir = tu_edpt_dir(ep_addr); + USBD_EP_T *ep = ep_entry(ep_addr, false); + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* store away the information we'll needing now and later */ + xfer->data_ptr = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->in_remaining_bytes = total_bytes; + xfer->total_bytes = total_bytes; + + /* for the first of one or more EP0_IN packets in a message, the first must be DATA1 */ + if ( (0x80 == ep_addr) && !active_ep0_xfer ) ep->CFG |= USBD_CFG_DSQSYNC_Msk; + + if (TUSB_DIR_IN == dir) + { + dcd_in_xfer(xfer, ep); + } + else + { + xfer->out_bytes_so_far = 0; + ep->MXPLD = xfer->max_packet_size; + } + + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + + /* mine the data for the information we need */ + tusb_dir_t dir = tu_edpt_dir(ep_addr); + USBD_EP_T *ep = ep_entry(ep_addr, false); + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* store away the information we'll needing now and later */ + xfer->data_ptr = NULL; // Indicates a FIFO shall be used + xfer->ff = ff; + xfer->in_remaining_bytes = total_bytes; + xfer->total_bytes = total_bytes; + + if (TUSB_DIR_IN == dir) + { + dcd_in_xfer(xfer, ep); + } + else + { + xfer->out_bytes_so_far = 0; + ep->MXPLD = xfer->max_packet_size; + } + + return true; +} +#endif + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + USBD_EP_T *ep = ep_entry(ep_addr, false); + ep->CFGP |= USBD_CFGP_SSTALL_Msk; +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + USBD_EP_T *ep = ep_entry(ep_addr, false); + ep->CFG = (ep->CFG & ~USBD_CFG_DSQSYNC_Msk) | USBD_CFG_CSTALL_Msk; +} + +void dcd_int_handler(uint8_t rhport) +{ + (void) rhport; + + // Mask non-enabled irqs, ex. SOF + uint32_t status = USBD->INTSTS & (ENABLED_IRQS | 0xffffff00); + +#ifdef SUPPORT_LPM + uint32_t state = USBD->ATTR & 0x300f; +#else + uint32_t state = USBD->ATTR & 0xf; +#endif + + if(status & USBD_INTSTS_VBDETIF_Msk) + { + if(USBD->VBUSDET & USBD_VBUSDET_VBUSDET_Msk) + { + /* USB connect */ + USBD->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; + } + else + { + /* USB disconnect */ + USBD->ATTR &= ~USBD_ATTR_USBEN_Msk; + } + } + + if(status & USBD_INTSTS_BUSIF_Msk) + { + if(state & USBD_ATTR_USBRST_Msk) + { + /* USB bus reset */ + USBD->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; + + bus_reset(); + + dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); + } + + if(state & USBD_ATTR_SUSPEND_Msk) + { + /* Enable USB but disable PHY */ + USBD->ATTR &= ~USBD_ATTR_PHYEN_Msk; + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + + if(state & USBD_ATTR_RESUME_Msk) + { + /* Enable USB and enable PHY */ + USBD->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + } + + if(status & USBD_INTSTS_SETUP_Msk) + { + /* clear the data ready flag of control endpoints */ + USBD->EP[PERIPH_EP0].CFGP |= USBD_CFGP_CLRRDY_Msk; + USBD->EP[PERIPH_EP1].CFGP |= USBD_CFGP_CLRRDY_Msk; + + /* get SETUP packet from USB buffer */ + dcd_event_setup_received(0, (uint8_t *)USBD_BUF_BASE, true); + } + + if(status & USBD_INTSTS_USBIF_Msk) + { + if (status & USBD_INTSTS_EPEVT0_Msk) /* PERIPH_EP0 (EP0_IN) event: this is treated separately from the rest */ + { + uint16_t const available_bytes = USBD->EP[PERIPH_EP0].MXPLD; + + active_ep0_xfer = (available_bytes == xfer_table[PERIPH_EP0].max_packet_size); + + dcd_event_xfer_complete(0, 0x80, available_bytes, XFER_RESULT_SUCCESS, true); + } + + /* service PERIPH_EP1 through PERIPH_EP7 */ + enum ep_enum ep_index; + uint32_t mask; + struct xfer_ctl_t *xfer; + USBD_EP_T *ep; + for (ep_index = PERIPH_EP1, mask = USBD_INTSTS_EPEVT1_Msk, xfer = &xfer_table[PERIPH_EP1], ep = &USBD->EP[PERIPH_EP1]; ep_index <= PERIPH_EP7; ep_index++, mask <<= 1, xfer++, ep++) + { + if(status & mask) + { + USBD->INTSTS = mask; + + uint16_t const available_bytes = ep->MXPLD; + uint8_t const ep_addr = decode_ep_addr(ep); + bool const out_ep = !(ep_addr & TUSB_DIR_IN_MASK); + + if (out_ep) + { + /* copy the data from the PC to the previously provided buffer */ +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_write_n(xfer->ff, (const void *) (USBD_BUF_BASE + ep->BUFSEG), available_bytes); + } + else +#endif + { + // USB SRAM seems to only support byte access and memcpy could possibly do it by words + usb_memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes); + xfer->data_ptr += available_bytes; + } + + xfer->out_bytes_so_far += available_bytes; + + /* when the transfer is finished, alert TinyUSB; otherwise, accept more data */ + if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) ) + dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); + else + ep->MXPLD = xfer->max_packet_size; + } + else + { + /* update the bookkeeping to reflect the data that has now been sent to the PC */ + xfer->in_remaining_bytes -= available_bytes; + xfer->data_ptr += available_bytes; + + /* if more data to send, send it; otherwise, alert TinyUSB that we've finished */ + if (xfer->in_remaining_bytes) + dcd_in_xfer(xfer, ep); + else + dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); + } + } + } + } + + if(status & USBD_INTSTS_SOFIF_Msk) + { + /* Start-Of-Frame event */ + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } + + /* acknowledge all interrupts */ + USBD->INTSTS = status & ENABLED_IRQS; +} + +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS ) + { + uint8_t const dev_addr = (uint8_t) request->wValue; + + // Setting new address after the whole request is complete + USBD->FADDR = dev_addr; + } +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + usb_detach(); +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + usb_attach(); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc505/dcd_nuc505.c b/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc505/dcd_nuc505.c new file mode 100644 index 0000000..4989775 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nuvoton/nuc505/dcd_nuc505.c @@ -0,0 +1,723 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Peter Lawrence + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* + Theory of operation: + + The NUC505 USBD peripheral has twelve "EP"s, where each is simplex, in addition + to dedicated support for the control endpoint (EP0). The non-user endpoints + are referred to as "user" EPs in this code, and follow the datasheet + nomenclature of EPA through EPL. +*/ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC505) + +#include "device/dcd.h" +#include "NUC505Series.h" + +/* + * The DMA functionality of the USBD peripheral does not appear to succeed with + * transfer lengths that are longer (> 64 bytes) and are not a multiple of 4. + * Keep disabled for now. + */ +#define USE_DMA 0 + +/* rather important info unfortunately not provided by device include files */ +#define USBD_BUF_SIZE 2048 /* how much USB buffer space there is */ +#define USBD_MAX_DMA_LEN 0x1000 /* max bytes that can be DMAed at one time */ + +enum ep_enum +{ + PERIPH_EPA = 0, + PERIPH_EPB = 1, + PERIPH_EPC = 2, + PERIPH_EPD = 3, + PERIPH_EPE = 4, + PERIPH_EPF = 5, + PERIPH_EPG = 6, + PERIPH_EPH = 7, + PERIPH_EPI = 8, + PERIPH_EPJ = 9, + PERIPH_EPK = 10, + PERIPH_EPL = 11, + PERIPH_MAX_EP, +}; + +static const uint8_t epcfg_eptype_table[] = +{ + [TUSB_XFER_CONTROL] = 0, /* won't happen, since control EPs have dedicated registers */ + [TUSB_XFER_ISOCHRONOUS] = 3 << USBD_EPCFG_EPTYPE_Pos, + [TUSB_XFER_BULK] = 1 << USBD_EPCFG_EPTYPE_Pos, + [TUSB_XFER_INTERRUPT] = 2 << USBD_EPCFG_EPTYPE_Pos, +}; + +static const uint8_t eprspctl_eptype_table[] = +{ + [TUSB_XFER_CONTROL] = 0, /* won't happen, since control EPs have dedicated registers */ + [TUSB_XFER_ISOCHRONOUS] = 2 << USBD_EPRSPCTL_MODE_Pos, /* Fly Mode */ + [TUSB_XFER_BULK] = 0 << USBD_EPRSPCTL_MODE_Pos, /* Auto-Validate Mode */ + [TUSB_XFER_INTERRUPT] = 1 << USBD_EPRSPCTL_MODE_Pos, /* Manual-Validate Mode */ +}; + +/* set by dcd_set_address() */ +static volatile uint8_t assigned_address; + +/* reset by bus_reset(), this is used by dcd_edpt_open() to assign USBD peripheral buffer addresses */ +static uint32_t bufseg_addr; + +/* RAM table needed to track ongoing transfers performed by dcd_edpt_xfer(), dcd_userEP_in_xfer(), and the ISR */ +static struct xfer_ctl_t +{ + uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */ + // tu_fifo_t* ff; // TODO support dcd_edpt_xfer_fifo API + union { + uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */ + uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */ + }; + uint16_t max_packet_size; /* needed since device driver only finds out this at runtime */ + uint16_t total_bytes; /* quantity needed to pass as argument to dcd_event_xfer_complete() (for IN endpoints) */ + uint8_t ep_addr; + bool dma_requested; +} xfer_table[PERIPH_MAX_EP]; + +/* in addition to xfer_table, additional bespoke bookkeeping is maintained for control EP0 IN */ +static struct +{ + uint8_t *data_ptr; + uint16_t in_remaining_bytes; + uint16_t total_bytes; +} ctrl_in_xfer; + +static volatile struct xfer_ctl_t *current_dma_xfer; + + +/* + local helper functions +*/ + +static void usb_attach(void) +{ + USBD->PHYCTL |= USBD_PHYCTL_DPPUEN_Msk; +} + +static void usb_detach(void) +{ + USBD->PHYCTL &= ~USBD_PHYCTL_DPPUEN_Msk; +} + +static void usb_control_send_zlp(void) +{ + USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk; + USBD->CEPCTL = 0; /* clear NAKCLR bit */ + USBD->CEPINTEN = USBD_CEPINTEN_STSDONEIEN_Msk; +} + +/* map 8-bit ep_addr into peripheral endpoint index (PERIPH_EPA...) */ +static USBD_EP_T *ep_entry(uint8_t ep_addr, bool add) +{ + USBD_EP_T *ep; + enum ep_enum ep_index; + struct xfer_ctl_t *xfer; + + for (ep_index = PERIPH_EPA, xfer = &xfer_table[PERIPH_EPA], ep = USBD->EP; + ep_index < PERIPH_MAX_EP; + ep_index++, xfer++, ep++) + { + if (add) + { + /* take first peripheral endpoint that is unused */ + if (0 == (ep->EPCFG & USBD_EPCFG_EPEN_Msk)) return ep; + } + else + { + /* find a peripheral endpoint that matches ep_addr */ + if (xfer->ep_addr == ep_addr) return ep; + } + } + + return NULL; +} + +/* perform a non-control IN endpoint transfer; this is called by the ISR */ +static void dcd_userEP_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) +{ + uint16_t const bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size); + + /* precompute what amount of data will be left */ + xfer->in_remaining_bytes -= bytes_now; + + /* + if there will be no more data to send, we replace the BUFEMPTYIF EP interrupt with TXPKIF; + that way, we alert TinyUSB as soon as this last packet has been sent + */ + if (0 == xfer->in_remaining_bytes) + { + ep->EPINTSTS = USBD_EPINTSTS_TXPKIF_Msk; + ep->EPINTEN = USBD_EPINTEN_TXPKIEN_Msk; + } + + /* provided buffers are thankfully 32-bit aligned, allowing most data to be transfered as 32-bit */ +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) (&ep->EPDAT_BYTE), bytes_now); + } + else +#endif + { + uint16_t countdown = bytes_now; + while (countdown > 3) + { + uint32_t u32; + memcpy(&u32, xfer->data_ptr, 4); + + ep->EPDAT = u32; + xfer->data_ptr += 4; countdown -= 4; + } + + while (countdown--) ep->EPDAT_BYTE = *xfer->data_ptr++; + } + + /* for short packets, we must nudge the peripheral to say 'that's all folks' */ + if (bytes_now != xfer->max_packet_size) ep->EPRSPCTL = USBD_EPRSPCTL_SHORTTXEN_Msk; +} + +/* called by dcd_init() as well as by the ISR during a USB bus reset */ +static void bus_reset(void) +{ + for (enum ep_enum ep_index = PERIPH_EPA; ep_index < PERIPH_MAX_EP; ep_index++) + { + USBD->EP[ep_index].EPCFG = 0; + xfer_table[ep_index].dma_requested = false; + } + + USBD->DMACNT = 0; + USBD->DMACTL = USBD_DMACTL_DMARST_Msk; + USBD->DMACTL = 0; + + /* allocate the default EP0 endpoints */ + + USBD->CEPBUFSTART = 0; + USBD->CEPBUFEND = 0 + CFG_TUD_ENDPOINT0_SIZE - 1; + + /* USB RAM beyond what we've allocated above is available to the user */ + bufseg_addr = CFG_TUD_ENDPOINT0_SIZE; + + /* Reset USB device address */ + USBD->FADDR = 0; + + current_dma_xfer = NULL; +} + +#if USE_DMA +/* this must only be called by the ISR; it does its best to share the single DMA engine across all user EPs (IN and OUT) */ +static void service_dma(void) +{ + if (current_dma_xfer) + return; + + enum ep_enum ep_index; + struct xfer_ctl_t *xfer; + USBD_EP_T *ep; + + for (ep_index = PERIPH_EPA, xfer = &xfer_table[PERIPH_EPA], ep = &USBD->EP[PERIPH_EPA]; ep_index < PERIPH_MAX_EP; ep_index++, xfer++, ep++) + { + uint16_t const available_bytes = ep->EPDATCNT & USBD_EPDATCNT_DATCNT_Msk; + + if (!xfer->dma_requested || !available_bytes) + continue; + + /* + instruct DMA to copy the data from the PC to the previously provided buffer + when the bus interrupt DMADONEIEN subsequently fires, the transfer will have finished + */ + USBD->DMACTL = xfer->ep_addr & USBD_DMACTL_EPNUM_Msk; + USBD->DMAADDR = (uint32_t)xfer->data_ptr; + USBD->DMACNT = available_bytes; + USBD->BUSINTSTS = USBD_BUSINTSTS_DMADONEIF_Msk; + xfer->out_bytes_so_far += available_bytes; + current_dma_xfer = xfer; + USBD->DMACTL |= USBD_DMACTL_DMAEN_Msk; + + return; + } +} +#endif + +/* centralized location for USBD interrupt enable bit masks */ +static const uint32_t enabled_irqs = USBD_GINTEN_USBIEN_Msk | \ + USBD_GINTEN_EPAIEN_Msk | USBD_GINTEN_EPBIEN_Msk | USBD_GINTEN_EPCIEN_Msk | USBD_GINTEN_EPDIEN_Msk | USBD_GINTEN_EPEIEN_Msk | USBD_GINTEN_EPFIEN_Msk | \ + USBD_GINTEN_EPGIEN_Msk | USBD_GINTEN_EPHIEN_Msk | USBD_GINTEN_EPIIEN_Msk | USBD_GINTEN_EPJIEN_Msk | USBD_GINTEN_EPKIEN_Msk | USBD_GINTEN_EPLIEN_Msk | \ + USBD_GINTEN_CEPIEN_Msk; + +/* + NUC505 TinyUSB API driver implementation +*/ + +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + /* configure interrupts in their initial state; BUSINTEN and CEPINTEN will be subsequently and dynamically re-written as needed */ + USBD->GINTEN = enabled_irqs; + USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_VBUSDETIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk; + USBD->CEPINTEN = 0; + + bus_reset(); + + usb_attach(); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USBD_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USBD_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + usb_control_send_zlp(); /* SET_ADDRESS is the one exception where TinyUSB doesn't use dcd_edpt_xfer() to generate a ZLP */ + assigned_address = dev_addr; +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + USBD->OPER |= USBD_OPER_RESUMEEN_Msk; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void) rhport; + + USBD_EP_T *ep = ep_entry(p_endpoint_desc->bEndpointAddress, true); + TU_ASSERT(ep); + + /* mine the data for the information we need */ + int const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + int const size = tu_edpt_packet_size(p_endpoint_desc); + tusb_xfer_type_t const type = p_endpoint_desc->bmAttributes.xfer; + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* allocate buffer from USB RAM */ + ep->EPBUFSTART = bufseg_addr; + bufseg_addr += size; + ep->EPBUFEND = bufseg_addr - 1; + TU_ASSERT(bufseg_addr <= USBD_BUF_SIZE); + + ep->EPMPS = size; + + ep->EPRSPCTL = USB_EP_RSPCTL_FLUSH | eprspctl_eptype_table[type]; + + /* construct USB Configuration Register value and then write it */ + uint32_t cfg = (uint32_t)tu_edpt_number(p_endpoint_desc->bEndpointAddress) << USBD_EPCFG_EPNUM_Pos; + if (TUSB_DIR_IN == dir) + cfg |= USBD_EPCFG_EPDIR_Msk; + cfg |= epcfg_eptype_table[type] | USBD_EPCFG_EPEN_Msk; + ep->EPCFG = cfg; + + /* make a note of the endpoint particulars */ + xfer->max_packet_size = size; + xfer->ep_addr = p_endpoint_desc->bEndpointAddress; + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void) rhport; + + if (0x80 == ep_addr) /* control EP0 IN */ + { + if (total_bytes) + { + USBD->CEPCTL = USBD_CEPCTL_FLUSH_Msk; + ctrl_in_xfer.data_ptr = buffer; + ctrl_in_xfer.in_remaining_bytes = total_bytes; + ctrl_in_xfer.total_bytes = total_bytes; + USBD->CEPINTSTS = USBD_CEPINTSTS_INTKIF_Msk; + USBD->CEPINTEN = USBD_CEPINTEN_INTKIEN_Msk; + } + else + { + usb_control_send_zlp(); + } + } + else if (0x00 == ep_addr) /* control EP0 OUT */ + { + if (total_bytes) + { + /* if TinyUSB is asking for EP0 OUT data, it is almost certainly already in the buffer */ + while (total_bytes < USBD->CEPRXCNT); + for (int count = 0; count < total_bytes; count++) + *buffer++ = USBD->CEPDAT_BYTE; + + dcd_event_xfer_complete(0, ep_addr, total_bytes, XFER_RESULT_SUCCESS, true); + } + } + else + { + /* mine the data for the information we need */ + tusb_dir_t dir = tu_edpt_dir(ep_addr); + USBD_EP_T *ep = ep_entry(ep_addr, false); + TU_ASSERT(ep); + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* store away the information we'll needing now and later */ + xfer->data_ptr = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->in_remaining_bytes = total_bytes; + xfer->total_bytes = total_bytes; + + if (TUSB_DIR_IN == dir) + { + ep->EPINTEN = USBD_EPINTEN_BUFEMPTYIEN_Msk; + } + else + { + xfer->out_bytes_so_far = 0; + ep->EPINTEN = USBD_EPINTEN_RXPKIEN_Msk; + } + } + + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + + TU_ASSERT(0x80 != ep_addr && 0x00 != ep_addr); // Must not be used for control stuff + + /* mine the data for the information we need */ + tusb_dir_t dir = tu_edpt_dir(ep_addr); + USBD_EP_T *ep = ep_entry(ep_addr, false); + struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; + + /* store away the information we'll needing now and later */ + xfer->data_ptr = NULL; // Indicates a FIFO shall be used + xfer->ff = ff; + xfer->in_remaining_bytes = total_bytes; + xfer->total_bytes = total_bytes; + + if (TUSB_DIR_IN == dir) + { + ep->EPINTEN = USBD_EPINTEN_BUFEMPTYIEN_Msk; + } + else + { + xfer->out_bytes_so_far = 0; + ep->EPINTEN = USBD_EPINTEN_RXPKIEN_Msk; + } + + return true; +} +#endif + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + if (tu_edpt_number(ep_addr)) + { + USBD_EP_T *ep = ep_entry(ep_addr, false); + TU_ASSERT(ep, ); + ep->EPRSPCTL = (ep->EPRSPCTL & 0xf7) | USBD_EPRSPCTL_HALT_Msk; + } + else + { + USBD->CEPCTL = USBD_CEPCTL_STALLEN_Msk; + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + if (tu_edpt_number(ep_addr)) + { + USBD_EP_T *ep = ep_entry(ep_addr, false); + TU_ASSERT(ep, ); + ep->EPRSPCTL = USBD_EPRSPCTL_TOGGLE_Msk; + } +} + +void dcd_int_handler(uint8_t rhport) +{ + (void) rhport; + + uint32_t status = USBD->GINTSTS; + + /* USB interrupt */ + if (status & USBD_GINTSTS_USBIF_Msk) + { + uint32_t bus_state = USBD->BUSINTSTS; + + if (bus_state & USBD_BUSINTSTS_SOFIF_Msk) + { + /* Start-Of-Frame event */ + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } + + if (bus_state & USBD_BUSINTSTS_RSTIF_Msk) + { + bus_reset(); + + USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk; + USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_SUSPENDIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk; + USBD->CEPINTSTS = 0x1ffc; + + tusb_speed_t speed = (USBD->OPER & USBD_OPER_CURSPD_Msk) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; + dcd_event_bus_reset(0, speed, true); + } + + if (bus_state & USBD_BUSINTSTS_RESUMEIF_Msk) + { + USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_SUSPENDIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk; + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + + if (bus_state & USBD_BUSINTSTS_SUSPENDIF_Msk) + { + USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk; + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + + if (bus_state & USBD_BUSINTSTS_HISPDIF_Msk) + { + USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk; + } + + if (bus_state & USBD_BUSINTSTS_DMADONEIF_Msk) + { +#if USE_DMA + if (current_dma_xfer) + { + current_dma_xfer->dma_requested = false; + + uint16_t available_bytes = USBD->DMACNT & USBD_DMACNT_DMACNT_Msk; + + /* if the most recent DMA finishes the transfer, alert TinyUSB; otherwise, the next RXPKIF/INTKIF endpoint interrupt will prompt the next DMA */ + if ( (current_dma_xfer->total_bytes == current_dma_xfer->out_bytes_so_far) || (available_bytes < current_dma_xfer->max_packet_size) ) + { + dcd_event_xfer_complete(0, current_dma_xfer->ep_addr, current_dma_xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); + } + + current_dma_xfer = NULL; + service_dma(); + } +#endif + } + + if (bus_state & USBD_BUSINTSTS_VBUSDETIF_Msk) + { + if (USBD->PHYCTL & USBD_PHYCTL_VBUSDET_Msk) + { + /* USB connect */ + USBD->PHYCTL |= USBD_PHYCTL_PHYEN_Msk | USBD_PHYCTL_DPPUEN_Msk; + } + else + { + /* USB disconnect */ + USBD->PHYCTL &= ~USBD_PHYCTL_DPPUEN_Msk; + } + } + + USBD->BUSINTSTS = bus_state & (USBD_BUSINTSTS_SOFIF_Msk | USBD_BUSINTSTS_RSTIF_Msk | USBD_BUSINTSTS_RESUMEIF_Msk | USBD_BUSINTSTS_SUSPENDIF_Msk | USBD_BUSINTSTS_HISPDIF_Msk | USBD_BUSINTSTS_DMADONEIF_Msk | USBD_BUSINTSTS_PHYCLKVLDIF_Msk | USBD_BUSINTSTS_VBUSDETIF_Msk); + } + + if (status & USBD_GINTSTS_CEPIF_Msk) + { + uint32_t cep_state = USBD->CEPINTSTS & USBD->CEPINTEN; + + if (cep_state & USBD_CEPINTSTS_SETUPPKIF_Msk) + { + /* get SETUP packet from USB buffer */ + uint8_t setup_packet[8]; + setup_packet[0] = (uint8_t)(USBD->SETUP1_0 >> 0); + setup_packet[1] = (uint8_t)(USBD->SETUP1_0 >> 8); + setup_packet[2] = (uint8_t)(USBD->SETUP3_2 >> 0); + setup_packet[3] = (uint8_t)(USBD->SETUP3_2 >> 8); + setup_packet[4] = (uint8_t)(USBD->SETUP5_4 >> 0); + setup_packet[5] = (uint8_t)(USBD->SETUP5_4 >> 8); + setup_packet[6] = (uint8_t)(USBD->SETUP7_6 >> 0); + setup_packet[7] = (uint8_t)(USBD->SETUP7_6 >> 8); + dcd_event_setup_received(0, setup_packet, true); + } + else if (cep_state & USBD_CEPINTSTS_INTKIF_Msk) + { + USBD->CEPINTSTS = USBD_CEPINTSTS_TXPKIF_Msk; + + if (!(cep_state & USBD_CEPINTSTS_STSDONEIF_Msk)) + { + USBD->CEPINTEN = USBD_CEPINTEN_TXPKIEN_Msk; + uint16_t bytes_now = tu_min16(ctrl_in_xfer.in_remaining_bytes, CFG_TUD_ENDPOINT0_SIZE); + for (int count = 0; count < bytes_now; count++) + USBD->CEPDAT_BYTE = *ctrl_in_xfer.data_ptr++; + ctrl_in_xfer.in_remaining_bytes -= bytes_now; + USBD_START_CEP_IN(bytes_now); + } + else + { + USBD->CEPINTEN = USBD_CEPINTEN_TXPKIEN_Msk | USBD_CEPINTEN_STSDONEIEN_Msk; + } + } + else if (cep_state & USBD_CEPINTSTS_TXPKIF_Msk) + { + USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk; + USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR); + + /* alert TinyUSB that the EP0 IN transfer has finished */ + if ( (0 == ctrl_in_xfer.in_remaining_bytes) || (0 == ctrl_in_xfer.total_bytes) ) + dcd_event_xfer_complete(0, 0x80, ctrl_in_xfer.total_bytes, XFER_RESULT_SUCCESS, true); + + if (ctrl_in_xfer.in_remaining_bytes) + { + USBD->CEPINTSTS = USBD_CEPINTSTS_INTKIF_Msk; + USBD->CEPINTEN = USBD_CEPINTEN_INTKIEN_Msk; + } + else + { + /* TinyUSB does its own fragmentation and ZLP for EP0; a transfer of zero means a ZLP */ + if (0 == ctrl_in_xfer.total_bytes) USBD->CEPCTL = USBD_CEPCTL_ZEROLEN_Msk; + + USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk; + USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk | USBD_CEPINTEN_STSDONEIEN_Msk; + } + } + else if (cep_state & USBD_CEPINTSTS_STSDONEIF_Msk) + { + /* given ACK from host has happened, we can now set the address (if not already done) */ + if((USBD->FADDR != assigned_address) && (USBD->FADDR == 0)) + { + USBD->FADDR = assigned_address; + + for (enum ep_enum ep_index = PERIPH_EPA; ep_index < PERIPH_MAX_EP; ep_index++) + { + if (USBD->EP[ep_index].EPCFG & USBD_EPCFG_EPEN_Msk) USBD->EP[ep_index].EPRSPCTL = USBD_EPRSPCTL_TOGGLE_Msk; + } + } + + USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk; + } + + USBD->CEPINTSTS = cep_state; + + return; + } + + if (status & (USBD_GINTSTS_EPAIF_Msk | USBD_GINTSTS_EPBIF_Msk | USBD_GINTSTS_EPCIF_Msk | USBD_GINTSTS_EPDIF_Msk | USBD_GINTSTS_EPEIF_Msk | USBD_GINTSTS_EPFIF_Msk | USBD_GINTSTS_EPGIF_Msk | USBD_GINTSTS_EPHIF_Msk | USBD_GINTSTS_EPIIF_Msk | USBD_GINTSTS_EPJIF_Msk | USBD_GINTSTS_EPKIF_Msk | USBD_GINTSTS_EPLIF_Msk)) + { + /* service PERIPH_EPA through PERIPH_EPL */ + enum ep_enum ep_index; + uint32_t mask; + struct xfer_ctl_t *xfer; + USBD_EP_T *ep; + for (ep_index = PERIPH_EPA, mask = USBD_GINTSTS_EPAIF_Msk, xfer = &xfer_table[PERIPH_EPA], ep = &USBD->EP[PERIPH_EPA]; ep_index < PERIPH_MAX_EP; ep_index++, mask <<= 1, xfer++, ep++) + { + if(status & mask) + { + uint8_t const ep_addr = xfer->ep_addr; + bool const out_ep = !(ep_addr & TUSB_DIR_IN_MASK); + uint32_t ep_state = ep->EPINTSTS & ep->EPINTEN; + + if (out_ep) + { +#if USE_DMA + xfer->dma_requested = true; + service_dma(); +#else + uint16_t const available_bytes = ep->EPDATCNT & USBD_EPDATCNT_DATCNT_Msk; + /* copy the data from the PC to the previously provided buffer */ +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) &ep->EPDAT_BYTE, tu_min16(available_bytes, xfer->total_bytes - xfer->out_bytes_so_far)); + } + else +#endif + { + for (int count = 0; (count < available_bytes) && (xfer->out_bytes_so_far < xfer->total_bytes); count++, xfer->out_bytes_so_far++) + { + *xfer->data_ptr++ = ep->EPDAT_BYTE; + } + } + + /* when the transfer is finished, alert TinyUSB; otherwise, continue accepting more data */ + if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) ) + { + dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); + } +#endif + + } + else if (ep_state & USBD_EPINTSTS_BUFEMPTYIF_Msk) + { + /* send any remaining data */ + dcd_userEP_in_xfer(xfer, ep); + } + else if (ep_state & USBD_EPINTSTS_TXPKIF_Msk) + { + /* alert TinyUSB that we've finished */ + dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); + ep->EPINTEN = 0; + } + + ep->EPINTSTS = ep_state; + } + } + } +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + usb_detach(); +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + usb_attach(); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/khci/dcd_khci.c b/circuitpython/lib/tinyusb/src/portable/nxp/khci/dcd_khci.c new file mode 100644 index 0000000..4c77371 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/khci/dcd_khci.c @@ -0,0 +1,557 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Koji Kitayama + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && ( \ + ( CFG_TUSB_MCU == OPT_MCU_MKL25ZXX ) || ( CFG_TUSB_MCU == OPT_MCU_K32L2BXX ) \ + ) + +#include "fsl_device_registers.h" +#define KHCI USB0 + +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +enum { + TOK_PID_OUT = 0x1u, + TOK_PID_IN = 0x9u, + TOK_PID_SETUP = 0xDu, +}; + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t head; + struct { + union { + struct { + uint16_t : 2; + __IO uint16_t tok_pid : 4; + uint16_t data : 1; + __IO uint16_t own : 1; + uint16_t : 8; + }; + struct { + uint16_t : 2; + uint16_t bdt_stall : 1; + uint16_t dts : 1; + uint16_t ninc : 1; + uint16_t keep : 1; + uint16_t : 10; + }; + }; + __IO uint16_t bc : 10; + uint16_t : 6; + }; + }; + uint8_t *addr; +}buffer_descriptor_t; + +TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t state; + struct { + uint32_t max_packet_size :11; + uint32_t : 5; + uint32_t odd : 1; + uint32_t :15; + }; + }; + uint16_t length; + uint16_t remaining; +}endpoint_state_t; + +TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); + +typedef struct +{ + union { + /* [#EP][OUT,IN][EVEN,ODD] */ + buffer_descriptor_t bdt[16][2][2]; + uint16_t bda[512]; + }; + TU_ATTR_ALIGNED(4) union { + endpoint_state_t endpoint[16][2]; + endpoint_state_t endpoint_unified[16 * 2]; + }; + uint8_t setup_packet[8]; + uint8_t addr; +}dcd_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +// BDT(Buffer Descriptor Table) must be 256-byte aligned +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd; + +TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" ); + +static void prepare_next_setup_packet(uint8_t rhport) +{ + const unsigned out_odd = _dcd.endpoint[0][0].odd; + const unsigned in_odd = _dcd.endpoint[0][1].odd; + TU_ASSERT(0 == _dcd.bdt[0][0][out_odd].own, ); + + _dcd.bdt[0][0][out_odd].data = 0; + _dcd.bdt[0][0][out_odd ^ 1].data = 1; + _dcd.bdt[0][1][in_odd].data = 1; + _dcd.bdt[0][1][in_odd ^ 1].data = 0; + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), + _dcd.setup_packet, sizeof(_dcd.setup_packet)); +} + +static void process_stall(uint8_t rhport) +{ + for (int i = 0; i < 16; ++i) { + unsigned const endpt = KHCI->ENDPOINT[i].ENDPT; + + if (endpt & USB_ENDPT_EPSTALL_MASK) { + // prepare next setup if endpoint0 + if ( i == 0 ) prepare_next_setup_packet(rhport); + + // clear stall bit + KHCI->ENDPOINT[i].ENDPT = endpt & ~USB_ENDPT_EPSTALL_MASK; + } + } +} + +static void process_tokdne(uint8_t rhport) +{ + const unsigned s = KHCI->STAT; + KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ + + uint8_t const epnum = (s >> USB_STAT_ENDP_SHIFT); + uint8_t const dir = (s & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT; + unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; + + buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; + endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; + + /* fetch pid before discarded by the next steps */ + const unsigned pid = bd->tok_pid; + + /* reset values for a next transfer */ + bd->bdt_stall = 0; + bd->dts = 1; + bd->ninc = 0; + bd->keep = 0; + /* update the odd variable to prepare for the next transfer */ + ep->odd = odd ^ 1; + if (pid == TOK_PID_SETUP) { + dcd_event_setup_received(rhport, bd->addr, true); + KHCI->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + return; + } + + const unsigned bc = bd->bc; + const unsigned remaining = ep->remaining - bc; + if (remaining && bc == ep->max_packet_size) { + /* continue the transferring consecutive data */ + ep->remaining = remaining; + const int next_remaining = remaining - ep->max_packet_size; + if (next_remaining > 0) { + /* prepare to the after next transfer */ + bd->addr += ep->max_packet_size * 2; + bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; + __DSB(); + bd->own = 1; /* the own bit must set after addr */ + } + return; + } + const unsigned length = ep->length; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(epnum, dir), + length - remaining, XFER_RESULT_SUCCESS, true); + if (0 == epnum && 0 == length) { + /* After completion a ZLP of control transfer, + * it prepares for the next steup transfer. */ + if (_dcd.addr) { + /* When the transfer was the SetAddress, + * the device address should be updated here. */ + KHCI->ADDR = _dcd.addr; + _dcd.addr = 0; + } + prepare_next_setup_packet(rhport); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + KHCI->CTL |= USB_CTL_ODDRST_MASK; + KHCI->ADDR = 0; + KHCI->INTEN = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_SLEEPEN_MASK | + USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; + + KHCI->ENDPOINT[0].ENDPT = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; + for (unsigned i = 1; i < 16; ++i) { + KHCI->ENDPOINT[i].ENDPT = 0; + } + buffer_descriptor_t *bd = _dcd.bdt[0][0]; + for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { + bd->head = 0; + } + const endpoint_state_t ep0 = { + .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, + .odd = 0, + .length = 0, + .remaining = 0, + }; + _dcd.endpoint[0][0] = ep0; + _dcd.endpoint[0][1] = ep0; + tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0])); + _dcd.addr = 0; + prepare_next_setup_packet(rhport); + KHCI->CTL &= ~USB_CTL_ODDRST_MASK; + dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); +} + +static void process_bus_sleep(uint8_t rhport) +{ + // Enable resume & disable suspend interrupt + const unsigned inten = KHCI->INTEN; + + KHCI->INTEN = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK; + KHCI->USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK; + KHCI->USBCTRL |= USB_USBCTRL_SUSP_MASK; + + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); +} + +static void process_bus_resume(uint8_t rhport) +{ + // Enable suspend & disable resume interrupt + const unsigned inten = KHCI->INTEN; + + KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; // will also clear USB_USBTRC0_USB_RESUME_INT_MASK + KHCI->USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK; + KHCI->INTEN = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; + + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); +} + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; + while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); + + tu_memclr(&_dcd, sizeof(_dcd)); + KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ + KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); + KHCI->BDTPAGE2 = (uint8_t)((uintptr_t)_dcd.bdt >> 16); + KHCI->BDTPAGE3 = (uint8_t)((uintptr_t)_dcd.bdt >> 24); + + KHCI->INTEN = USB_INTEN_USBRSTEN_MASK; + + dcd_connect(rhport); + NVIC_ClearPendingIRQ(USB0_IRQn); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB0_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB0_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + _dcd.addr = dev_addr & 0x7F; + /* Response with status first before changing device address */ + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + KHCI->CTL |= USB_CTL_RESUME_MASK; + + unsigned cnt = SystemCoreClock / 1000; + while (cnt--) __NOP(); + + KHCI->CTL &= ~USB_CTL_RESUME_MASK; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + KHCI->USBCTRL = 0; + KHCI->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; + KHCI->CTL |= USB_CTL_USBENSOFEN_MASK; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + KHCI->CTL = 0; + KHCI->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + const unsigned odd = ep->odd; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + + /* No support for control transfer */ + TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL)); + + ep->max_packet_size = tu_edpt_packet_size(ep_desc); + unsigned val = USB_ENDPT_EPCTLDIS_MASK; + val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK: 0; + val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; + KHCI->ENDPOINT[epn].ENDPT |= val; + + if (xfer != TUSB_XFER_ISOCHRONOUS) { + bd[odd].dts = 1; + bd[odd].data = 0; + bd[odd ^ 1].dts = 1; + bd[odd ^ 1].data = 1; + } + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + (void) rhport; + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + for (unsigned i = 1; i < 16; ++i) { + KHCI->ENDPOINT[i].ENDPT = 0; + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); + buffer_descriptor_t *bd = _dcd.bdt[1][0]; + for (unsigned i = 2; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { + bd->head = 0; + } + endpoint_state_t *ep = &_dcd.endpoint[1][0]; + for (unsigned i = 2; i < sizeof(_dcd.endpoint)/sizeof(*ep); ++i, ++ep) { + /* Clear except the odd */ + ep->max_packet_size = 0; + ep->length = 0; + ep->remaining = 0; + } +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + const unsigned msk = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + KHCI->ENDPOINT[epn].ENDPT &= ~msk; + ep->max_packet_size = 0; + ep->length = 0; + ep->remaining = 0; + bd[0].head = 0; + bd[1].head = 0; + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) +{ + (void) rhport; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; + TU_ASSERT(0 == bd->own); + + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + + ep->length = total_bytes; + ep->remaining = total_bytes; + + const unsigned mps = ep->max_packet_size; + if (total_bytes > mps) { + buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; + /* When total_bytes is greater than the max packet size, + * it prepares to the next transfer to avoid NAK in advance. */ + next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; + next->addr = buffer + mps; + next->own = 1; + } + bd->bc = total_bytes >= mps ? mps: total_bytes; + bd->addr = buffer; + __DSB(); + bd->own = 1; /* This bit must be set last */ + + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + const unsigned epn = tu_edpt_number(ep_addr); + + if (0 == epn) { + KHCI->ENDPOINT[epn].ENDPT |= USB_ENDPT_EPSTALL_MASK; + } else { + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned odd = _dcd.endpoint[epn][dir].odd; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][odd]; + TU_ASSERT(0 == bd->own,); + + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + + bd->bdt_stall = 1; + __DSB(); + bd->own = 1; /* This bit must be set last */ + + if (ie) NVIC_EnableIRQ(USB0_IRQn); + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + const unsigned epn = tu_edpt_number(ep_addr); + TU_VERIFY(epn,); + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned odd = _dcd.endpoint[epn][dir].odd; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + TU_VERIFY(bd[odd].own,); + + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + + bd[odd].own = 0; + __DSB(); + + // clear stall + bd[odd].bdt_stall = 0; + + // Reset data toggle + bd[odd ].data = 0; + bd[odd ^ 1].data = 1; + + // We already cleared this in ISR, but just clear it here to be safe + const unsigned endpt = KHCI->ENDPOINT[epn].ENDPT; + if (endpt & USB_ENDPT_EPSTALL_MASK) { + KHCI->ENDPOINT[epn].ENDPT = endpt & ~USB_ENDPT_EPSTALL_MASK; + } + + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void dcd_int_handler(uint8_t rhport) +{ + uint32_t is = KHCI->ISTAT; + uint32_t msk = KHCI->INTEN; + + // clear non-enabled interrupts + KHCI->ISTAT = is & ~msk; + is &= msk; + + if (is & USB_ISTAT_ERROR_MASK) { + /* TODO: */ + uint32_t es = KHCI->ERRSTAT; + KHCI->ERRSTAT = es; + KHCI->ISTAT = is; /* discard any pending events */ + } + + if (is & USB_ISTAT_USBRST_MASK) { + KHCI->ISTAT = is; /* discard any pending events */ + process_bus_reset(rhport); + } + + if (is & USB_ISTAT_SLEEP_MASK) { + // TU_LOG2("Suspend: "); TU_LOG2_HEX(is); + + // Note Host usually has extra delay after bus reset (without SOF), which could falsely + // detected as Sleep event. Though usbd has debouncing logic so we are good + KHCI->ISTAT = USB_ISTAT_SLEEP_MASK; + process_bus_sleep(rhport); + } + +#if 0 // ISTAT_RESUME never trigger, probably for host mode ? + if (is & USB_ISTAT_RESUME_MASK) { + // TU_LOG2("ISTAT Resume: "); TU_LOG2_HEX(is); + KHCI->ISTAT = USB_ISTAT_RESUME_MASK; + process_bus_resume(rhport); + } +#endif + + if (KHCI->USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) { + // TU_LOG2("USBTRC0 Resume: "); TU_LOG2_HEX(is); TU_LOG2_HEX(KHCI->USBTRC0); + process_bus_resume(rhport); + } + + if (is & USB_ISTAT_SOFTOK_MASK) { + KHCI->ISTAT = USB_ISTAT_SOFTOK_MASK; + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + + if (is & USB_ISTAT_STALL_MASK) { + KHCI->ISTAT = USB_ISTAT_STALL_MASK; + process_stall(rhport); + } + + if (is & USB_ISTAT_TOKDNE_MASK) { + process_tokdne(rhport); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/khci/hcd_khci.c b/circuitpython/lib/tinyusb/src/portable/nxp/khci/hcd_khci.c new file mode 100644 index 0000000..0f5fa62 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/khci/hcd_khci.c @@ -0,0 +1,626 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji Kitayama + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && ( \ + ( CFG_TUSB_MCU == OPT_MCU_MKL25ZXX ) || ( CFG_TUSB_MCU == OPT_MCU_K32L2BXX ) \ + ) + +#include "fsl_device_registers.h" +#define KHCI USB0 + +#include "host/hcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +enum { + TOK_PID_OUT = 0x1u, + TOK_PID_IN = 0x9u, + TOK_PID_SETUP = 0xDu, + TOK_PID_DATA0 = 0x3u, + TOK_PID_DATA1 = 0xbu, + TOK_PID_ACK = 0x2u, + TOK_PID_STALL = 0xeu, + TOK_PID_NAK = 0xau, + TOK_PID_BUSTO = 0x0u, + TOK_PID_ERR = 0xfu, +}; + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t head; + struct { + union { + struct { + uint16_t : 2; + __IO uint16_t tok_pid : 4; + uint16_t data : 1; + __IO uint16_t own : 1; + uint16_t : 8; + }; + struct { + uint16_t : 2; + uint16_t bdt_stall : 1; + uint16_t dts : 1; + uint16_t ninc : 1; + uint16_t keep : 1; + uint16_t : 10; + }; + }; + __IO uint16_t bc : 10; + uint16_t : 6; + }; + }; + uint8_t *addr; +}buffer_descriptor_t; + +TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t state; + struct { + uint32_t pipenum:16; + uint32_t odd : 1; + uint32_t : 0; + }; + }; + uint8_t *buffer; + uint16_t length; + uint16_t remaining; +} endpoint_state_t; + +typedef struct TU_ATTR_PACKED +{ + uint8_t dev_addr; + uint8_t ep_addr; + uint16_t max_packet_size; + union { + uint8_t flags; + struct { + uint8_t data : 1; + uint8_t xfer : 2; + uint8_t : 0; + }; + }; + uint8_t *buffer; + uint16_t length; + uint16_t remaining; +} pipe_state_t; + + +typedef struct +{ + union { + /* [OUT,IN][EVEN,ODD] */ + buffer_descriptor_t bdt[2][2]; + uint16_t bda[2*2]; + }; + endpoint_state_t endpoint[2]; + pipe_state_t pipe[CFG_TUH_ENDPOINT_MAX * 2]; + uint32_t in_progress; /* Bitmap. Each bit indicates that a transfer of the corresponding pipe is in progress */ + uint32_t pending; /* Bitmap. Each bit indicates that a transfer of the corresponding pipe will be resume the next frame */ + bool need_reset; /* The device has not been reset after connection. */ +} hcd_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +// BDT(Buffer Descriptor Table) must be 256-byte aligned +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static hcd_data_t _hcd; +//CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _rx_buf[1024]; + +int find_pipe(uint8_t dev_addr, uint8_t ep_addr) +{ + /* Find the target pipe */ + int num; + for (num = 0; num < CFG_TUH_ENDPOINT_MAX * 2; ++num) { + pipe_state_t *p = &_hcd.pipe[num]; + if ((p->dev_addr == dev_addr) && (p->ep_addr == ep_addr)) + return num; + } + return -1; +} + +static int prepare_packets(int pipenum) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + unsigned const dir_tx = tu_edpt_dir(pipe->ep_addr) ? 0 : 1; + endpoint_state_t *ep = &_hcd.endpoint[dir_tx]; + unsigned const odd = ep->odd; + buffer_descriptor_t *bd = _hcd.bdt[dir_tx]; + TU_ASSERT(0 == bd[odd].own, -1); + + // TU_LOG1(" %p dir %d odd %d data %d\n", &bd[odd], dir_tx, odd, pipe->data); + + ep->pipenum = pipenum; + + bd[odd ].data = pipe->data; + bd[odd ^ 1].data = pipe->data ^ 1; + bd[odd ^ 1].own = 0; + /* reset values for a next transfer */ + + int num_tokens = 0; /* The number of prepared packets */ + unsigned const mps = pipe->max_packet_size; + unsigned const rem = pipe->remaining; + if (rem > mps) { + /* When total_bytes is greater than the max packet size, + * it prepares to the next transfer to avoid NAK in advance. */ + bd[odd ^ 1].bc = rem >= 2 * mps ? mps: rem - mps; + bd[odd ^ 1].addr = pipe->buffer + mps; + bd[odd ^ 1].own = 1; + if (dir_tx) ++num_tokens; + } + bd[odd].bc = rem >= mps ? mps: rem; + bd[odd].addr = pipe->buffer; + __DSB(); + bd[odd].own = 1; /* This bit must be set last */ + ++num_tokens; + return num_tokens; +} + +static int select_next_pipenum(int pipenum) +{ + unsigned wip = _hcd.in_progress & ~_hcd.pending; + if (!wip) return -1; + unsigned msk = TU_GENMASK(31, pipenum); + int next = __builtin_ctz(wip & msk); + if (next) return next; + msk = TU_GENMASK(pipenum, 0); + next = __builtin_ctz(wip & msk); + return next; +} + +/* When transfer is completed, return true. */ +static bool continue_transfer(int pipenum, buffer_descriptor_t *bd) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + unsigned const bc = bd->bc; + unsigned const rem = pipe->remaining - bc; + + pipe->remaining = rem; + if (rem && bc == pipe->max_packet_size) { + int const next_rem = rem - pipe->max_packet_size; + if (next_rem > 0) { + /* Prepare to the after next transfer */ + bd->addr += pipe->max_packet_size * 2; + bd->bc = next_rem > pipe->max_packet_size ? pipe->max_packet_size: next_rem; + __DSB(); + bd->own = 1; /* This bit must be set last */ + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = KHCI->TOKEN; /* Queue the same token as the last */ + } else if (TUSB_DIR_IN == tu_edpt_dir(pipe->ep_addr)) { /* IN */ + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = KHCI->TOKEN; + } + return true; + } + pipe->data = bd->data ^ 1; + return false; +} + +static bool resume_transfer(int pipenum) +{ + int num_tokens = prepare_packets(pipenum); + TU_ASSERT(0 <= num_tokens); + + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + + unsigned flags = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; + flags |= USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; + switch (pipe->xfer) { + case TUSB_XFER_CONTROL: + flags |= USB_ENDPT_EPHSHK_MASK; + break; + case TUSB_XFER_ISOCHRONOUS: + flags |= USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK; + break; + default: + flags |= USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK; + break; + } + // TU_LOG1(" resume pipenum %d flags %x\n", pipenum, flags); + + KHCI->ENDPOINT[0].ENDPT = flags; + KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | pipe->dev_addr; + + unsigned const token = tu_edpt_number(pipe->ep_addr) | + ((tu_edpt_dir(pipe->ep_addr) ? TOK_PID_IN: TOK_PID_OUT) << USB_TOKEN_TOKENPID_SHIFT); + do { + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = token; + } while (--num_tokens); + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return true; +} + +static void suspend_transfer(int pipenum, buffer_descriptor_t *bd) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + pipe->buffer = bd->addr; + pipe->data = bd->data ^ 1; + if ((TUSB_XFER_INTERRUPT == pipe->xfer) || + (TUSB_XFER_BULK == pipe->xfer)) { + _hcd.pending |= TU_BIT(pipenum); + KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK; + } +} + +static void process_tokdne(uint8_t rhport) +{ + (void)rhport; + const unsigned s = KHCI->STAT; + KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ + uint8_t const dir_in = (s & USB_STAT_TX_MASK) ? TUSB_DIR_OUT: TUSB_DIR_IN; + unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; + + buffer_descriptor_t *bd = (buffer_descriptor_t *)&_hcd.bda[s]; + endpoint_state_t *ep = &_hcd.endpoint[s >> 3]; + + /* fetch status before discarded by the next steps */ + const unsigned pid = bd->tok_pid; + + /* reset values for a next transfer */ + bd->bdt_stall = 0; + bd->dts = 1; + bd->ninc = 0; + bd->keep = 0; + /* Update the odd variable to prepare for the next transfer */ + ep->odd = odd ^ 1; + + int pipenum = ep->pipenum; + int next_pipenum; + // TU_LOG1("TOKDNE %x PID %x pipe %d\n", s, pid, pipenum); + + xfer_result_t result; + switch (pid) { + default: + if (continue_transfer(pipenum, bd)) + return; + result = XFER_RESULT_SUCCESS; + break; + case TOK_PID_NAK: + suspend_transfer(pipenum, bd); + next_pipenum = select_next_pipenum(pipenum); + if (0 <= next_pipenum) + resume_transfer(next_pipenum); + return; + case TOK_PID_STALL: + result = XFER_RESULT_STALLED; + break; + case TOK_PID_ERR: /* mismatch toggle bit */ + case TOK_PID_BUSTO: + result = XFER_RESULT_FAILED; + break; + } + _hcd.in_progress &= ~TU_BIT(pipenum); + pipe_state_t *pipe = &_hcd.pipe[ep->pipenum]; + hcd_event_xfer_complete(pipe->dev_addr, + tu_edpt_addr(KHCI->TOKEN & USB_TOKEN_TOKENENDPT_MASK, dir_in), + pipe->length - pipe->remaining, + result, true); + next_pipenum = select_next_pipenum(pipenum); + if (0 <= next_pipenum) + resume_transfer(next_pipenum); +} + +static void process_attach(uint8_t rhport) +{ + unsigned ctl = KHCI->CTL; + if (!(ctl & USB_CTL_JSTATE_MASK)) { + /* The attached device is a low speed device. */ + KHCI->ADDR = USB_ADDR_LSEN_MASK; + KHCI->ENDPOINT[0].ENDPT = USB_ENDPT_HOSTWOHUB_MASK; + } + hcd_event_device_attach(rhport, true); +} + +static void process_bus_reset(uint8_t rhport) +{ + KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; + KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK; + KHCI->ADDR = 0; + KHCI->ENDPOINT[0].ENDPT = 0; + + hcd_event_device_remove(rhport, true); + + _hcd.in_progress = 0; + _hcd.pending = 0; + buffer_descriptor_t *bd = &_hcd.bdt[0][0]; + for (unsigned i = 0; i < 2; ++i, ++bd) { + bd->head = 0; + } +} + +/*------------------------------------------------------------------*/ +/* Host API + *------------------------------------------------------------------*/ +bool hcd_init(uint8_t rhport) +{ + (void)rhport; + + KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; + while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); + + tu_memclr(&_hcd, sizeof(_hcd)); + KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ + KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)_hcd.bdt >> 8); + KHCI->BDTPAGE2 = (uint8_t)((uintptr_t)_hcd.bdt >> 16); + KHCI->BDTPAGE3 = (uint8_t)((uintptr_t)_hcd.bdt >> 24); + + KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + KHCI->CTL |= USB_CTL_ODDRST_MASK; + for (unsigned i = 0; i < 16; ++i) { + KHCI->ENDPOINT[i].ENDPT = 0; + } + KHCI->CTL &= ~USB_CTL_ODDRST_MASK; + + KHCI->SOFTHLD = 74; /* for 64-byte packets */ + // KHCI->SOFTHLD = 144; /* for low speed 8-byte packets */ + KHCI->CTL = USB_CTL_HOSTMODEEN_MASK | USB_CTL_SE0_MASK; + KHCI->USBCTRL = USB_USBCTRL_PDE_MASK; + + NVIC_ClearPendingIRQ(USB0_IRQn); + KHCI->INTEN = USB_INTEN_ATTACHEN_MASK | USB_INTEN_TOKDNEEN_MASK | + USB_INTEN_USBRSTEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; + KHCI->ERREN = 0xff; + + return true; +} + +void hcd_int_enable(uint8_t rhport) +{ + (void)rhport; + NVIC_EnableIRQ(USB0_IRQn); +} + +void hcd_int_disable(uint8_t rhport) +{ + (void)rhport; + NVIC_DisableIRQ(USB0_IRQn); +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void)rhport; + /* The device must be reset at least once after connection + * in order to start the frame counter. */ + if (_hcd.need_reset) hcd_port_reset(rhport); + uint32_t frmnum = KHCI->FRMNUML; + frmnum |= KHCI->FRMNUMH << 8u; + return frmnum; +} + +/*--------------------------------------------------------------------+ + * Port API + *--------------------------------------------------------------------+ */ +bool hcd_port_connect_status(uint8_t rhport) +{ + (void)rhport; + if (KHCI->ISTAT & USB_ISTAT_ATTACH_MASK) + return true; + return false; +} + +void hcd_port_reset(uint8_t rhport) +{ + (void)rhport; + KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK; + KHCI->CTL |= USB_CTL_RESET_MASK; + unsigned cnt = SystemCoreClock / 100; + while (cnt--) __NOP(); + KHCI->CTL &= ~USB_CTL_RESET_MASK; + KHCI->CTL |= USB_CTL_USBENSOFEN_MASK; + _hcd.need_reset = false; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + (void)rhport; + tusb_speed_t speed = TUSB_SPEED_FULL; + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + if (KHCI->ADDR & USB_ADDR_LSEN_MASK) + speed = TUSB_SPEED_LOW; + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return speed; +} + +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + pipe_state_t *p = &_hcd.pipe[0]; + pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2]; + for (;p != end; ++p) { + if (p->dev_addr == dev_addr) + tu_memclr(p, sizeof(*p)); + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void)rhport; + // TU_LOG1("SETUP %u\n", dev_addr); + TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(0))); + + int pipenum = find_pipe(dev_addr, 0); + if (pipenum < 0) return false; + + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + pipe[0].data = 0; + pipe[0].buffer = (uint8_t*)(uintptr_t)setup_packet; + pipe[0].length = 8; + pipe[0].remaining = 8; + pipe[1].data = 1; + + if (1 != prepare_packets(pipenum)) + return false; + + _hcd.in_progress |= TU_BIT(pipenum); + + unsigned hostwohub = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; + KHCI->ENDPOINT[0].ENDPT = hostwohub | + USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; + KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = (TOK_PID_SETUP << USB_TOKEN_TOKENPID_SHIFT); + return true; +} + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void)rhport; + uint8_t const ep_addr = ep_desc->bEndpointAddress; + // TU_LOG1("O %u %x\n", dev_addr, ep_addr); + /* Find a free pipe */ + pipe_state_t *p = &_hcd.pipe[0]; + pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2]; + if (dev_addr || ep_addr) { + p += 2; + for (; p < end && (p->dev_addr || p->ep_addr); ++p) ; + if (p == end) return false; + } + p->dev_addr = dev_addr; + p->ep_addr = ep_addr; + p->max_packet_size = ep_desc->wMaxPacketSize; + p->xfer = ep_desc->bmAttributes.xfer; + p->data = 0; + if (!ep_addr) { + /* Open one more pipe for Control IN transfer */ + TU_ASSERT(TUSB_XFER_CONTROL == p->xfer); + pipe_state_t *q = p + 1; + TU_ASSERT(!q->dev_addr && !q->ep_addr); + q->dev_addr = dev_addr; + q->ep_addr = tu_edpt_addr(0, TUSB_DIR_IN); + q->max_packet_size = ep_desc->wMaxPacketSize; + q->xfer = ep_desc->bmAttributes.xfer; + q->data = 1; + } + return true; +} + +/* The address of buffer must be aligned to 4 byte boundary. And it must be at least 4 bytes long. + * DMA writes data in 4 byte unit */ +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) +{ + (void)rhport; + // TU_LOG1("X %u %x %x %d\n", dev_addr, ep_addr, (uintptr_t)buffer, buflen); + + int pipenum = find_pipe(dev_addr, ep_addr); + TU_ASSERT(0 <= pipenum); + + TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(pipenum))); + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + pipe->buffer = buffer; + pipe->length = buflen; + pipe->remaining = buflen; + _hcd.in_progress |= TU_BIT(pipenum); + _hcd.pending |= TU_BIT(pipenum); /* Send at the next Frame */ + KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK; + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return true; +} + +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + if (!tu_edpt_number(ep_addr)) return true; + int num = find_pipe(dev_addr, ep_addr); + if (num < 0) return false; + pipe_state_t *p = &_hcd.pipe[num]; + p->data = 0; /* Reset data toggle */ + return true; +} + +/*--------------------------------------------------------------------+ + * ISR + *--------------------------------------------------------------------+*/ +void hcd_int_handler(uint8_t rhport) +{ + uint32_t is = KHCI->ISTAT; + uint32_t msk = KHCI->INTEN; + + // TU_LOG1("S %lx\n", is); + + /* clear disabled interrupts */ + KHCI->ISTAT = (is & ~msk & ~USB_ISTAT_TOKDNE_MASK) | USB_ISTAT_SOFTOK_MASK; + is &= msk; + + if (is & USB_ISTAT_ERROR_MASK) { + unsigned err = KHCI->ERRSTAT; + if (err) { + TU_LOG1(" ERR %x\n", err); + KHCI->ERRSTAT = err; + } else { + KHCI->INTEN &= ~USB_ISTAT_ERROR_MASK; + } + } + + if (is & USB_ISTAT_USBRST_MASK) { + KHCI->INTEN = (msk & ~USB_INTEN_USBRSTEN_MASK) | USB_INTEN_ATTACHEN_MASK; + process_bus_reset(rhport); + return; + } + if (is & USB_ISTAT_ATTACH_MASK) { + KHCI->INTEN = (msk & ~USB_INTEN_ATTACHEN_MASK) | USB_INTEN_USBRSTEN_MASK; + _hcd.need_reset = true; + process_attach(rhport); + return; + } + if (is & USB_ISTAT_STALL_MASK) { + KHCI->ISTAT = USB_ISTAT_STALL_MASK; + } + if (is & USB_ISTAT_SOFTOK_MASK) { + msk &= ~USB_ISTAT_SOFTOK_MASK; + KHCI->INTEN = msk; + if (_hcd.pending) { + int pipenum = __builtin_ctz(_hcd.pending); + _hcd.pending = 0; + if (!(is & USB_ISTAT_TOKDNE_MASK)) + resume_transfer(pipenum); + } + } + if (is & USB_ISTAT_TOKDNE_MASK) { + process_tokdne(rhport); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/dcd_lpc17_40.c new file mode 100644 index 0000000..d2cce2d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -0,0 +1,589 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) + +#include "device/dcd.h" +#include "dcd_lpc17_40.h" +#include "chip.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +#define DCD_ENDPOINT_MAX 32 + +typedef struct TU_ATTR_ALIGNED(4) +{ + //------------- Word 0 -------------// + uint32_t next; + + //------------- Word 1 -------------// + uint16_t atle_mode : 2; // 00: normal, 01: ATLE (auto length extraction) + uint16_t next_valid : 1; + uint16_t : 1; ///< reserved + uint16_t isochronous : 1; // is an iso endpoint + uint16_t max_packet_size : 11; + + volatile uint16_t buflen; // bytes for non-iso, number of packets for iso endpoint + + //------------- Word 2 -------------// + volatile uint32_t buffer; + + //------------- Word 3 -------------// + volatile uint16_t retired : 1; // initialized to zero + volatile uint16_t status : 4; + volatile uint16_t iso_last_packet_valid : 1; + volatile uint16_t atle_lsb_extracted : 1; // used in ATLE mode + volatile uint16_t atle_msb_extracted : 1; // used in ATLE mode + volatile uint16_t atle_mess_len_position : 6; // used in ATLE mode + uint16_t : 2; + + volatile uint16_t present_count; // For non-iso : The number of bytes transferred by the DMA engine + // For iso : number of packets + + //------------- Word 4 -------------// + // uint32_t iso_packet_size_addr; // iso only, can be omitted for non-iso +}dma_desc_t; + +TU_VERIFY_STATIC( sizeof(dma_desc_t) == 16, "size is not correct"); // TODO not support ISO for now + +typedef struct +{ + // must be 128 byte aligned + volatile dma_desc_t* udca[DCD_ENDPOINT_MAX]; + + // TODO DMA does not support control transfer (0-1 are not used, offset to reduce memory) + dma_desc_t dd[DCD_ENDPOINT_MAX]; + + struct + { + uint8_t* out_buffer; + uint8_t out_bytes; + volatile bool out_received; // indicate if data is already received in endpoint + + uint8_t in_bytes; + } control; + +} dcd_data_t; + +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd; + + +//--------------------------------------------------------------------+ +// SIE Command +//--------------------------------------------------------------------+ +static void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data) +{ + LPC_USB->DevIntClr = (DEV_INT_COMMAND_CODE_EMPTY_MASK | DEV_INT_COMMAND_DATA_FULL_MASK); + LPC_USB->CmdCode = (phase << 8) | (code_data << 16); + + uint32_t const wait_flag = (phase == SIE_CMDPHASE_READ) ? DEV_INT_COMMAND_DATA_FULL_MASK : DEV_INT_COMMAND_CODE_EMPTY_MASK; + while ((LPC_USB->DevIntSt & wait_flag) == 0) {} + + LPC_USB->DevIntClr = wait_flag; +} + +static void sie_write (uint8_t cmd_code, uint8_t data_len, uint8_t data) +{ + sie_cmd_code(SIE_CMDPHASE_COMMAND, cmd_code); + + if (data_len) + { + sie_cmd_code(SIE_CMDPHASE_WRITE, data); + } +} + +static uint8_t sie_read (uint8_t cmd_code) +{ + sie_cmd_code(SIE_CMDPHASE_COMMAND , cmd_code); + sie_cmd_code(SIE_CMDPHASE_READ , cmd_code); + return (uint8_t) LPC_USB->CmdData; +} + +//--------------------------------------------------------------------+ +// PIPE HELPER +//--------------------------------------------------------------------+ +static inline uint8_t ep_addr2idx(uint8_t ep_addr) +{ + return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0); +} + +static void set_ep_size(uint8_t ep_id, uint16_t max_packet_size) +{ + // follows example in 11.10.4.2 + LPC_USB->ReEp |= TU_BIT(ep_id); + LPC_USB->EpInd = ep_id; // select index before setting packet size + LPC_USB->MaxPSize = max_packet_size; + + while ((LPC_USB->DevIntSt & DEV_INT_ENDPOINT_REALIZED_MASK) == 0) {} + LPC_USB->DevIntClr = DEV_INT_ENDPOINT_REALIZED_MASK; +} + + +//--------------------------------------------------------------------+ +// CONTROLLER API +//--------------------------------------------------------------------+ +static void bus_reset(void) +{ + // step 7 : slave mode set up + LPC_USB->EpIntClr = 0xFFFFFFFF; // clear all pending interrupt + LPC_USB->DevIntClr = 0xFFFFFFFF; // clear all pending interrupt + LPC_USB->EpIntEn = 0x03UL; // control endpoint cannot use DMA, non-control all use DMA + LPC_USB->EpIntPri = 0x03UL; // fast for control endpoint + + // step 8 : DMA set up + LPC_USB->EpDMADis = 0xFFFFFFFF; // firstly disable all dma + LPC_USB->DMARClr = 0xFFFFFFFF; // clear all pending interrupt + LPC_USB->EoTIntClr = 0xFFFFFFFF; + LPC_USB->NDDRIntClr = 0xFFFFFFFF; + LPC_USB->SysErrIntClr = 0xFFFFFFFF; + + tu_memclr(&_dcd, sizeof(dcd_data_t)); +} + +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + //------------- user manual 11.13 usb device controller initialization -------------// + // step 6 : set up control endpoint + set_ep_size(0, CFG_TUD_ENDPOINT0_SIZE); + set_ep_size(1, CFG_TUD_ENDPOINT0_SIZE); + + bus_reset(); + + LPC_USB->DevIntEn = (DEV_INT_DEVICE_STATUS_MASK | DEV_INT_ENDPOINT_FAST_MASK | DEV_INT_ENDPOINT_SLOW_MASK | DEV_INT_ERROR_MASK); + LPC_USB->UDCAH = (uint32_t) _dcd.udca; + LPC_USB->DMAIntEn = (DMA_INT_END_OF_XFER_MASK /*| DMA_INT_NEW_DD_REQUEST_MASK*/ | DMA_INT_ERROR_MASK); + + dcd_connect(rhport); + + // Clear pending IRQ + NVIC_ClearPendingIRQ(USB_IRQn); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + // Response with status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + sie_write(SIE_CMDCODE_SET_ADDRESS, 1, 0x80 | dev_addr); // 7th bit is : device_enable + + // Also Set Configure Device to enable non-control endpoint response + sie_write(SIE_CMDCODE_CONFIGURE_DEVICE, 1, 1); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, SIE_DEV_STATUS_CONNECT_STATUS_MASK); +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 0); +} + +//--------------------------------------------------------------------+ +// CONTROL HELPER +//--------------------------------------------------------------------+ +static inline uint8_t byte2dword(uint8_t bytes) +{ + return (bytes + 3) / 4; // length in dwords +} + +static void control_ep_write(void const * buffer, uint8_t len) +{ + uint32_t const * buf32 = (uint32_t const *) buffer; + + LPC_USB->Ctrl = USBCTRL_WRITE_ENABLE_MASK; // logical endpoint = 0 + LPC_USB->TxPLen = (uint32_t) len; + + for (uint8_t count = 0; count < byte2dword(len); count++) + { + LPC_USB->TxData = *buf32; // NOTE: cortex M3 have no problem with alignment + buf32++; + } + + LPC_USB->Ctrl = 0; + + // select control IN & validate the endpoint + sie_write(SIE_CMDCODE_ENDPOINT_SELECT+1, 0, 0); + sie_write(SIE_CMDCODE_BUFFER_VALIDATE , 0, 0); +} + +static uint8_t control_ep_read(void * buffer, uint8_t len) +{ + LPC_USB->Ctrl = USBCTRL_READ_ENABLE_MASK; // logical endpoint = 0 + while ((LPC_USB->RxPLen & USBRXPLEN_PACKET_READY_MASK) == 0) {} // TODO blocking, should have timeout + + len = tu_min8(len, (uint8_t) (LPC_USB->RxPLen & USBRXPLEN_PACKET_LENGTH_MASK) ); + uint32_t *buf32 = (uint32_t*) buffer; + + for (uint8_t count=0; count < byte2dword(len); count++) + { + *buf32 = LPC_USB->RxData; + buf32++; + } + + LPC_USB->Ctrl = 0; + + // select control OUT & clear the endpoint + sie_write(SIE_CMDCODE_ENDPOINT_SELECT+0, 0, 0); + sie_write(SIE_CMDCODE_BUFFER_CLEAR , 0, 0); + + return len; +} + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const ep_id = ep_addr2idx(p_endpoint_desc->bEndpointAddress); + + // Endpoint type is fixed to endpoint number + // 1: interrupt, 2: Bulk, 3: Iso and so on + switch ( p_endpoint_desc->bmAttributes.xfer ) + { + case TUSB_XFER_INTERRUPT: + TU_ASSERT((epnum % 3) == 1); + break; + + case TUSB_XFER_BULK: + TU_ASSERT((epnum % 3) == 2 || (epnum == 15)); + break; + + case TUSB_XFER_ISOCHRONOUS: + TU_ASSERT((epnum % 3) == 0 && (epnum != 0) && (epnum != 15)); + break; + + default: + break; + } + + //------------- Realize Endpoint with Max Packet Size -------------// + const uint16_t ep_size = tu_edpt_packet_size(p_endpoint_desc); + set_ep_size(ep_id, ep_size); + + //------------- first DD prepare -------------// + dma_desc_t* const dd = &_dcd.dd[ep_id]; + tu_memclr(dd, sizeof(dma_desc_t)); + + dd->isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) ? 1 : 0; + dd->max_packet_size = ep_size; + dd->retired = 1; // invalid at first + + sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS + ep_id, 1, 0); // clear all endpoint status + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + if ( tu_edpt_number(ep_addr) == 0 ) + { + sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK); + }else + { + uint8_t ep_id = ep_addr2idx( ep_addr ); + sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, SIE_SET_ENDPOINT_STALLED_MASK); + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + uint8_t ep_id = ep_addr2idx(ep_addr); + + sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, 0); +} + +static bool control_xact(uint8_t rhport, uint8_t dir, uint8_t * buffer, uint8_t len) +{ + (void) rhport; + + if ( dir ) + { + _dcd.control.in_bytes = len; + control_ep_write(buffer, len); + }else + { + if ( _dcd.control.out_received ) + { + // Already received the DATA OUT packet + _dcd.control.out_received = false; + _dcd.control.out_buffer = NULL; + _dcd.control.out_bytes = 0; + + uint8_t received = control_ep_read(buffer, len); + dcd_event_xfer_complete(0, 0, received, XFER_RESULT_SUCCESS, true); + }else + { + _dcd.control.out_buffer = buffer; + _dcd.control.out_bytes = len; + } + } + + return true; +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) +{ + // Control transfer is not DMA support, and must be done in slave mode + if ( tu_edpt_number(ep_addr) == 0 ) + { + return control_xact(rhport, tu_edpt_dir(ep_addr), buffer, (uint8_t) total_bytes); + } + else + { + uint8_t ep_id = ep_addr2idx(ep_addr); + dma_desc_t* dd = &_dcd.dd[ep_id]; + + // Prepare DMA descriptor + // Isochronous & max packet size must be preserved, Other fields of dd should be clear + uint16_t const ep_size = dd->max_packet_size; + uint8_t is_iso = dd->isochronous; + + tu_memclr(dd, sizeof(dma_desc_t)); + dd->isochronous = is_iso; + dd->max_packet_size = ep_size; + dd->buffer = (uint32_t) buffer; + dd->buflen = total_bytes; + + _dcd.udca[ep_id] = dd; + + if ( ep_id % 2 ) + { + // Clear EP interrupt before Enable DMA + LPC_USB->EpIntEn &= ~TU_BIT(ep_id); + LPC_USB->EpDMAEn = TU_BIT(ep_id); + + // endpoint IN need to actively raise DMA request + LPC_USB->DMARSet = TU_BIT(ep_id); + }else + { + // Enable DMA + LPC_USB->EpDMAEn = TU_BIT(ep_id); + } + + return true; + } +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ + +// handle control xfer (slave mode) +static void control_xfer_isr(uint8_t rhport, uint32_t ep_int_status) +{ + // Control out complete + if ( ep_int_status & TU_BIT(0) ) + { + bool is_setup = sie_read(SIE_CMDCODE_ENDPOINT_SELECT+0) & SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK; + + LPC_USB->EpIntClr = TU_BIT(0); + + if (is_setup) + { + uint8_t setup_packet[8]; + control_ep_read(setup_packet, 8); // TODO read before clear setup above + + dcd_event_setup_received(rhport, setup_packet, true); + } + else if ( _dcd.control.out_buffer ) + { + // software queued transfer previously + uint8_t received = control_ep_read(_dcd.control.out_buffer, _dcd.control.out_bytes); + + _dcd.control.out_buffer = NULL; + _dcd.control.out_bytes = 0; + + dcd_event_xfer_complete(rhport, 0, received, XFER_RESULT_SUCCESS, true); + }else + { + // hardware auto ack packet -> mark as received + _dcd.control.out_received = true; + } + } + + // Control In complete + if ( ep_int_status & TU_BIT(1) ) + { + LPC_USB->EpIntClr = TU_BIT(1); + dcd_event_xfer_complete(rhport, TUSB_DIR_IN_MASK, _dcd.control.in_bytes, XFER_RESULT_SUCCESS, true); + } +} + +// handle bus event signal +static void bus_event_isr(uint8_t rhport) +{ + uint8_t const dev_status = sie_read(SIE_CMDCODE_DEVICE_STATUS); + if (dev_status & SIE_DEV_STATUS_RESET_MASK) + { + bus_reset(); + dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); + } + + if (dev_status & SIE_DEV_STATUS_CONNECT_CHANGE_MASK) + { + // device is disconnected, require using VBUS (P1_30) + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + + if (dev_status & SIE_DEV_STATUS_SUSPEND_CHANGE_MASK) + { + if (dev_status & SIE_DEV_STATUS_SUSPEND_MASK) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + else + { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + } +} + +// Helper to complete a DMA descriptor for non-control transfer +static void dd_complete_isr(uint8_t rhport, uint8_t ep_id) +{ + dma_desc_t* const dd = &_dcd.dd[ep_id]; + uint8_t result = (dd->status == DD_STATUS_NORMAL || dd->status == DD_STATUS_DATA_UNDERUN) ? XFER_RESULT_SUCCESS : XFER_RESULT_FAILED; + uint8_t const ep_addr = (ep_id / 2) | ((ep_id & 0x01) ? TUSB_DIR_IN_MASK : 0); + + dcd_event_xfer_complete(rhport, ep_addr, dd->present_count, result, true); +} + +// main USB IRQ handler +void dcd_int_handler(uint8_t rhport) +{ + uint32_t const dev_int_status = LPC_USB->DevIntSt & LPC_USB->DevIntEn; + LPC_USB->DevIntClr = dev_int_status;// Acknowledge handled interrupt + + // Bus event + if (dev_int_status & DEV_INT_DEVICE_STATUS_MASK) + { + bus_event_isr(rhport); + } + + // Endpoint interrupt + uint32_t const ep_int_status = LPC_USB->EpIntSt & LPC_USB->EpIntEn; + + // Control Endpoint are fast + if (dev_int_status & DEV_INT_ENDPOINT_FAST_MASK) + { + // Note clear USBEpIntClr will also clear the setup received bit --> clear after handle setup packet + // Only clear USBEpIntClr 1 endpoint each, and should wait for CDFULL bit set + control_xfer_isr(rhport, ep_int_status); + } + + // non-control IN are slow + if (dev_int_status & DEV_INT_ENDPOINT_SLOW_MASK) + { + for ( uint8_t ep_id = 3; ep_id < DCD_ENDPOINT_MAX; ep_id += 2 ) + { + if ( tu_bit_test(ep_int_status, ep_id) ) + { + LPC_USB->EpIntClr = TU_BIT(ep_id); + + // Clear Ep interrupt for next DMA + LPC_USB->EpIntEn &= ~TU_BIT(ep_id); + + dd_complete_isr(rhport, ep_id); + } + } + } + + // DMA transfer complete (RAM <-> EP) for Non-Control + // OUT: USB transfer is fully complete + // IN : UBS transfer is still on-going -> enable EpIntEn to know when it is complete + uint32_t const dma_int_status = LPC_USB->DMAIntSt & LPC_USB->DMAIntEn; + if (dma_int_status & DMA_INT_END_OF_XFER_MASK) + { + uint32_t const eot = LPC_USB->EoTIntSt; + LPC_USB->EoTIntClr = eot; // acknowledge interrupt source + + for ( uint8_t ep_id = 2; ep_id < DCD_ENDPOINT_MAX; ep_id++ ) + { + if ( tu_bit_test(eot, ep_id) ) + { + if ( ep_id & 0x01 ) + { + // IN enable EpInt for end of usb transfer + LPC_USB->EpIntEn |= TU_BIT(ep_id); + }else + { + // OUT + dd_complete_isr(rhport, ep_id); + } + } + } + } + + // Errors + if ( (dev_int_status & DEV_INT_ERROR_MASK) || (dma_int_status & DMA_INT_ERROR_MASK) ) + { + uint32_t error_status = sie_read(SIE_CMDCODE_READ_ERROR_STATUS); + (void) error_status; + TU_BREAKPOINT(); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/dcd_lpc17_40.h b/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/dcd_lpc17_40.h new file mode 100644 index 0000000..07daa32 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/dcd_lpc17_40.h @@ -0,0 +1,152 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_DCD_LPC17_40_H_ +#define _TUSB_DCD_LPC17_40_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Register Interface +//--------------------------------------------------------------------+ + +//------------- USB Interrupt USBIntSt -------------// +//enum { +// DCD_USB_REQ_LOW_PRIO_MASK = TU_BIT(0), +// DCD_USB_REQ_HIGH_PRIO_MASK = TU_BIT(1), +// DCD_USB_REQ_DMA_MASK = TU_BIT(2), +// DCD_USB_REQ_NEED_CLOCK_MASK = TU_BIT(8), +// DCD_USB_REQ_ENABLE_MASK = TU_BIT(31) +//}; + +//------------- Device Interrupt USBDevInt -------------// +enum { + DEV_INT_FRAME_MASK = TU_BIT(0), + DEV_INT_ENDPOINT_FAST_MASK = TU_BIT(1), + DEV_INT_ENDPOINT_SLOW_MASK = TU_BIT(2), + DEV_INT_DEVICE_STATUS_MASK = TU_BIT(3), + DEV_INT_COMMAND_CODE_EMPTY_MASK = TU_BIT(4), + DEV_INT_COMMAND_DATA_FULL_MASK = TU_BIT(5), + DEV_INT_RX_ENDPOINT_PACKET_MASK = TU_BIT(6), + DEV_INT_TX_ENDPOINT_PACKET_MASK = TU_BIT(7), + DEV_INT_ENDPOINT_REALIZED_MASK = TU_BIT(8), + DEV_INT_ERROR_MASK = TU_BIT(9) +}; + +//------------- DMA Interrupt USBDMAInt-------------// +enum { + DMA_INT_END_OF_XFER_MASK = TU_BIT(0), + DMA_INT_NEW_DD_REQUEST_MASK = TU_BIT(1), + DMA_INT_ERROR_MASK = TU_BIT(2) +}; + +//------------- USBCtrl -------------// +enum { + USBCTRL_READ_ENABLE_MASK = TU_BIT(0), + USBCTRL_WRITE_ENABLE_MASK = TU_BIT(1), +}; + +//------------- USBRxPLen -------------// +enum { + USBRXPLEN_PACKET_LENGTH_MASK = (TU_BIT(10)-1), + USBRXPLEN_DATA_VALID_MASK = TU_BIT(10), + USBRXPLEN_PACKET_READY_MASK = TU_BIT(11), +}; + +//------------- SIE Command Code -------------// +typedef enum +{ + SIE_CMDPHASE_WRITE = 1, + SIE_CMDPHASE_READ = 2, + SIE_CMDPHASE_COMMAND = 5 +} sie_cmdphase_t; + +enum { + // device commands + SIE_CMDCODE_SET_ADDRESS = 0xd0, + SIE_CMDCODE_CONFIGURE_DEVICE = 0xd8, + SIE_CMDCODE_SET_MODE = 0xf3, + SIE_CMDCODE_READ_FRAME_NUMBER = 0xf5, + SIE_CMDCODE_READ_TEST_REGISTER = 0xfd, + SIE_CMDCODE_DEVICE_STATUS = 0xfe, + SIE_CMDCODE_GET_ERROR = 0xff, + SIE_CMDCODE_READ_ERROR_STATUS = 0xfb, + + // endpoint commands + SIE_CMDCODE_ENDPOINT_SELECT = 0x00, // + endpoint index + SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT = 0x40, // + endpoint index, should use USBEpIntClr instead + SIE_CMDCODE_ENDPOINT_SET_STATUS = 0x40, // + endpoint index + SIE_CMDCODE_BUFFER_CLEAR = 0xf2, + SIE_CMDCODE_BUFFER_VALIDATE = 0xfa +}; + +//------------- SIE Device Status (get/set from SIE_CMDCODE_DEVICE_STATUS) -------------// +enum { + SIE_DEV_STATUS_CONNECT_STATUS_MASK = TU_BIT(0), + SIE_DEV_STATUS_CONNECT_CHANGE_MASK = TU_BIT(1), + SIE_DEV_STATUS_SUSPEND_MASK = TU_BIT(2), + SIE_DEV_STATUS_SUSPEND_CHANGE_MASK = TU_BIT(3), + SIE_DEV_STATUS_RESET_MASK = TU_BIT(4) +}; + +//------------- SIE Select Endpoint Command -------------// +enum { + SIE_SELECT_ENDPOINT_FULL_EMPTY_MASK = TU_BIT(0), // 0: empty, 1 full. IN endpoint checks empty, OUT endpoint check full + SIE_SELECT_ENDPOINT_STALL_MASK = TU_BIT(1), + SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK = TU_BIT(2), // clear by SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT + SIE_SELECT_ENDPOINT_PACKET_OVERWRITTEN_MASK = TU_BIT(3), // previous packet is overwritten by a SETUP packet + SIE_SELECT_ENDPOINT_NAK_MASK = TU_BIT(4), // last packet response is NAK (auto clear by an ACK) + SIE_SELECT_ENDPOINT_BUFFER1_FULL_MASK = TU_BIT(5), + SIE_SELECT_ENDPOINT_BUFFER2_FULL_MASK = TU_BIT(6) +}; + +typedef enum +{ + SIE_SET_ENDPOINT_STALLED_MASK = TU_BIT(0), + SIE_SET_ENDPOINT_DISABLED_MASK = TU_BIT(5), + SIE_SET_ENDPOINT_RATE_FEEDBACK_MASK = TU_BIT(6), + SIE_SET_ENDPOINT_CONDITION_STALLED_MASK = TU_BIT(7), +}sie_endpoint_set_status_mask_t; + +//------------- DMA Descriptor Status -------------// +enum { + DD_STATUS_NOT_SERVICED = 0, + DD_STATUS_BEING_SERVICED, + DD_STATUS_NORMAL, + DD_STATUS_DATA_UNDERUN, // short packet + DD_STATUS_DATA_OVERRUN, + DD_STATUS_SYSTEM_ERROR +}; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/hcd_lpc17_40.c b/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/hcd_lpc17_40.c new file mode 100644 index 0000000..ad9ed59 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/lpc17_40/hcd_lpc17_40.c @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) + +#include "chip.h" + +void hcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB_IRQn); +} + +void hcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_IRQn); +} + +#endif + diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/circuitpython/lib/tinyusb/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c new file mode 100644 index 0000000..55d872d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -0,0 +1,543 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +/* Since 2012 starting with LPC11uxx, NXP start to use common USB Device Controller with code name LPC IP3511 + * for almost their new MCUs. Currently supported and tested families are + * - LPC11U68, LPC11U37 + * - LPC1347 + * - LPC51U68 + * - LPC54114 + * - LPC55s69 + */ +#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_LPC11UXX || \ + CFG_TUSB_MCU == OPT_MCU_LPC13XX || \ + CFG_TUSB_MCU == OPT_MCU_LPC15XX || \ + CFG_TUSB_MCU == OPT_MCU_LPC51UXX || \ + CFG_TUSB_MCU == OPT_MCU_LPC54XXX || \ + CFG_TUSB_MCU == OPT_MCU_LPC55XX) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ + +#if CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13XX || CFG_TUSB_MCU == OPT_MCU_LPC15XX + // LPCOpen + #include "chip.h" +#else + // SDK + #include "fsl_device_registers.h" + #define INCLUDE_FSL_DEVICE_REGISTERS +#endif + +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// IP3511 Registers +//--------------------------------------------------------------------+ + +typedef struct { + __IO uint32_t DEVCMDSTAT; // Device Command/Status register, offset: 0x0 + __I uint32_t INFO; // Info register, offset: 0x4 + __IO uint32_t EPLISTSTART; // EP Command/Status List start address, offset: 0x8 + __IO uint32_t DATABUFSTART; // Data buffer start address, offset: 0xC + __IO uint32_t LPM; // Link Power Management register, offset: 0x10 + __IO uint32_t EPSKIP; // Endpoint skip, offset: 0x14 + __IO uint32_t EPINUSE; // Endpoint Buffer in use, offset: 0x18 + __IO uint32_t EPBUFCFG; // Endpoint Buffer Configuration register, offset: 0x1C + __IO uint32_t INTSTAT; // interrupt status register, offset: 0x20 + __IO uint32_t INTEN; // interrupt enable register, offset: 0x24 + __IO uint32_t INTSETSTAT; // set interrupt status register, offset: 0x28 + uint8_t RESERVED_0[8]; + __I uint32_t EPTOGGLE; // Endpoint toggle register, offset: 0x34 +} dcd_registers_t; + +// Max nbytes for each control/bulk/interrupt transfer +enum { + NBYTES_CBI_FULLSPEED_MAX = 64, + NBYTES_CBI_HIGHSPEED_MAX = 32767 // can be up to all 15-bit, but only tested with 4096 +}; + +enum { + INT_SOF_MASK = TU_BIT(30), + INT_DEVICE_STATUS_MASK = TU_BIT(31) +}; + +enum { + CMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1, + CMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ), + CMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ), + CMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), // reflect the soft-connect only, does not reflect the actual attached state + CMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17), + // 23-22 is link speed (only available for HighSpeed port) + CMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24), + CMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25), + CMDSTAT_RESET_CHANGE_MASK = TU_BIT(26), + CMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28), +}; + +enum { + CMDSTAT_SPEED_SHIFT = 22 +}; + +//--------------------------------------------------------------------+ +// Endpoint Command/Status List +//--------------------------------------------------------------------+ + +// Endpoint Command/Status +typedef union TU_ATTR_PACKED +{ + // Full and High speed has different bit layout for buffer_offset and nbytes + + // Buffer (aligned 64) = DATABUFSTART [31:22] | buffer_offset [21:6] + volatile struct { + uint32_t offset : 16; + uint32_t nbytes : 10; + uint32_t TU_RESERVED : 6; + } buffer_fs; + + // Buffer (aligned 64) = USB_RAM [31:17] | buffer_offset [16:6] + volatile struct { + uint32_t offset : 11 ; + uint32_t nbytes : 15 ; + uint32_t TU_RESERVED : 6 ; + } buffer_hs; + + volatile struct { + uint32_t TU_RESERVED : 26; + uint32_t is_iso : 1 ; + uint32_t toggle_mode : 1 ; + uint32_t toggle_reset : 1 ; + uint32_t stall : 1 ; + uint32_t disable : 1 ; + uint32_t active : 1 ; + }; +}ep_cmd_sts_t; + +TU_VERIFY_STATIC( sizeof(ep_cmd_sts_t) == 4, "size is not correct" ); + +// Software transfer management +typedef struct +{ + uint16_t total_bytes; + uint16_t xferred_bytes; + + uint16_t nbytes; + + // prevent unaligned access on Highspeed port on USB_SRAM + uint16_t TU_RESERVED; +}xfer_dma_t; + +// Absolute max of endpoints pairs for all port +// - 11 13 15 51 54 has 5x2 endpoints +// - 55 usb0 (FS) has 5x2 endpoints, usb1 (HS) has 6x2 endpoints +#define MAX_EP_PAIRS 6 + +// NOTE data will be transferred as soon as dcd get request by dcd_pipe(_queue)_xfer using double buffering. +// current_td is used to keep track of number of remaining & xferred bytes of the current request. +typedef struct +{ + // 256 byte aligned, 2 for double buffer (not used) + // Each cmd_sts can only transfer up to DMA_NBYTES_MAX bytes each + ep_cmd_sts_t ep[2*MAX_EP_PAIRS][2]; + xfer_dma_t dma[2*MAX_EP_PAIRS]; + + TU_ATTR_ALIGNED(64) uint8_t setup_packet[8]; +}dcd_data_t; + +// EP list must be 256-byte aligned +// Some MCU controller may require this variable to be placed in specific SRAM region. +// For example: LPC55s69 port1 Highspeed must be USB_RAM (0x40100000) +// Use CFG_TUSB_MEM_SECTION to place it accordingly. +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd; + +//--------------------------------------------------------------------+ +// Multiple Controllers +//--------------------------------------------------------------------+ + +typedef struct +{ + dcd_registers_t* regs; // registers + const tusb_speed_t max_speed; // max link speed + const IRQn_Type irqnum; // IRQ number + const uint8_t ep_pairs; // Max bi-directional Endpoints +}dcd_controller_t; + +#ifdef INCLUDE_FSL_DEVICE_REGISTERS + +static const dcd_controller_t _dcd_controller[] = +{ + { .regs = (dcd_registers_t*) USB0_BASE , .max_speed = TUSB_SPEED_FULL, .irqnum = USB0_IRQn, .ep_pairs = FSL_FEATURE_USB_EP_NUM }, + #if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT + { .regs = (dcd_registers_t*) USBHSD_BASE, .max_speed = TUSB_SPEED_HIGH, .irqnum = USB1_IRQn, .ep_pairs = FSL_FEATURE_USBHSD_EP_NUM } + #endif +}; + +#else + +static const dcd_controller_t _dcd_controller[] = +{ + { .regs = (dcd_registers_t*) LPC_USB0_BASE, .max_speed = TUSB_SPEED_FULL, .irqnum = USB0_IRQn, .ep_pairs = 5 }, +}; + +#endif + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +static inline uint16_t get_buf_offset(void const * buffer) +{ + uint32_t addr = (uint32_t) buffer; + TU_ASSERT( (addr & 0x3f) == 0, 0 ); + return ( (addr >> 6) & 0xFFFFUL ) ; +} + +static inline uint8_t ep_addr2id(uint8_t ep_addr) +{ + return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0); +} + +//--------------------------------------------------------------------+ +// CONTROLLER API +//--------------------------------------------------------------------+ +void dcd_init(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + dcd_reg->EPLISTSTART = (uint32_t) _dcd.ep; + dcd_reg->DATABUFSTART = tu_align((uint32_t) &_dcd, TU_BIT(22)); // 22-bit alignment + dcd_reg->INTSTAT |= dcd_reg->INTSTAT; // clear all pending interrupt + dcd_reg->INTEN = INT_DEVICE_STATUS_MASK; + dcd_reg->DEVCMDSTAT |= CMDSTAT_DEVICE_ENABLE_MASK | CMDSTAT_DEVICE_CONNECT_MASK | + CMDSTAT_RESET_CHANGE_MASK | CMDSTAT_CONNECT_CHANGE_MASK | CMDSTAT_SUSPEND_CHANGE_MASK; + + NVIC_ClearPendingIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + // Response with status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_ADDR_MASK; + dcd_reg->DEVCMDSTAT |= dev_addr; +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; +} + +void dcd_connect(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->DEVCMDSTAT |= CMDSTAT_DEVICE_CONNECT_MASK; +} + +void dcd_disconnect(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_CONNECT_MASK; +} + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + // TODO cannot able to STALL Control OUT endpoint !!!!! FIXME try some walk-around + uint8_t const ep_id = ep_addr2id(ep_addr); + _dcd.ep[ep_id][0].stall = 1; +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const ep_id = ep_addr2id(ep_addr); + + _dcd.ep[ep_id][0].stall = 0; + _dcd.ep[ep_id][0].toggle_reset = 1; + _dcd.ep[ep_id][0].toggle_mode = 0; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void) rhport; + + // TODO not support ISO yet + TU_VERIFY(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); + + //------------- Prepare Queue Head -------------// + uint8_t ep_id = ep_addr2id(p_endpoint_desc->bEndpointAddress); + + // Check if endpoint is available + TU_ASSERT( _dcd.ep[ep_id][0].disable && _dcd.ep[ep_id][1].disable ); + + tu_memclr(_dcd.ep[ep_id], 2*sizeof(ep_cmd_sts_t)); + _dcd.ep[ep_id][0].is_iso = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + + // Enable EP interrupt + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->INTEN |= TU_BIT(ep_id); + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +static void prepare_setup_packet(uint8_t rhport) +{ + if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) + { + _dcd.ep[0][1].buffer_fs.offset = get_buf_offset(_dcd.setup_packet);; + }else + { + _dcd.ep[0][1].buffer_hs.offset = get_buf_offset(_dcd.setup_packet);; + } +} + +static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) +{ + uint16_t nbytes; + + if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) + { + // TODO ISO FullSpeed can have up to 1023 bytes + nbytes = tu_min16(total_bytes, NBYTES_CBI_FULLSPEED_MAX); + _dcd.ep[ep_id][0].buffer_fs.offset = buf_offset; + _dcd.ep[ep_id][0].buffer_fs.nbytes = nbytes; + }else + { + nbytes = tu_min16(total_bytes, NBYTES_CBI_HIGHSPEED_MAX); + _dcd.ep[ep_id][0].buffer_hs.offset = buf_offset; + _dcd.ep[ep_id][0].buffer_hs.nbytes = nbytes; + } + + _dcd.dma[ep_id].nbytes = nbytes; + + _dcd.ep[ep_id][0].active = 1; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const ep_id = ep_addr2id(ep_addr); + + tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); + _dcd.dma[ep_id].total_bytes = total_bytes; + + prepare_ep_xfer(rhport, ep_id, get_buf_offset(buffer), total_bytes); + + return true; +} + +//--------------------------------------------------------------------+ +// IRQ +//--------------------------------------------------------------------+ +static void bus_reset(uint8_t rhport) +{ + tu_memclr(&_dcd, sizeof(dcd_data_t)); + + // disable all non-control endpoints on bus reset + for(uint8_t ep_id = 2; ep_id < 2*MAX_EP_PAIRS; ep_id++) + { + _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; + } + + prepare_setup_packet(rhport); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + dcd_reg->EPINUSE = 0; + dcd_reg->EPBUFCFG = 0; + dcd_reg->EPSKIP = 0xFFFFFFFF; + + dcd_reg->INTSTAT = dcd_reg->INTSTAT; // clear all pending interrupt + dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt + dcd_reg->INTEN = INT_DEVICE_STATUS_MASK | TU_BIT(0) | TU_BIT(1); // enable device status & control endpoints +} + +static void process_xfer_isr(uint8_t rhport, uint32_t int_status) +{ + uint8_t const max_ep = 2*_dcd_controller[rhport].ep_pairs; + + for(uint8_t ep_id = 0; ep_id < max_ep; ep_id++ ) + { + if ( tu_bit_test(int_status, ep_id) ) + { + ep_cmd_sts_t * ep_cs = &_dcd.ep[ep_id][0]; + xfer_dma_t* xfer_dma = &_dcd.dma[ep_id]; + + if ( ep_id == 0 || ep_id == 1) + { + // For control endpoint, we need to manually clear Active bit + ep_cs->active = 0; + } + + uint16_t buf_offset; + uint16_t buf_nbytes; + + if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL) + { + buf_offset = ep_cs->buffer_fs.offset; + buf_nbytes = ep_cs->buffer_fs.nbytes; + }else + { + buf_offset = ep_cs->buffer_hs.offset; + buf_nbytes = ep_cs->buffer_hs.nbytes; + } + + xfer_dma->xferred_bytes += xfer_dma->nbytes - buf_nbytes; + + if ( (buf_nbytes == 0) && (xfer_dma->total_bytes > xfer_dma->xferred_bytes) ) + { + // There is more data to transfer + // buff_offset has been already increased by hw to correct value for next transfer + prepare_ep_xfer(rhport, ep_id, buf_offset, xfer_dma->total_bytes - xfer_dma->xferred_bytes); + } + else + { + // for detecting ZLP + xfer_dma->total_bytes = xfer_dma->xferred_bytes; + + uint8_t const ep_addr = tu_edpt_addr(ep_id / 2, ep_id & 0x01); + + // TODO no way determine if the transfer is failed or not + dcd_event_xfer_complete(rhport, ep_addr, xfer_dma->xferred_bytes, XFER_RESULT_SUCCESS, true); + } + } + } +} + +void dcd_int_handler(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + uint32_t const cmd_stat = dcd_reg->DEVCMDSTAT; + + uint32_t int_status = dcd_reg->INTSTAT & dcd_reg->INTEN; + dcd_reg->INTSTAT = int_status; // Acknowledge handled interrupt + + if (int_status == 0) return; + + //------------- Device Status -------------// + if ( int_status & INT_DEVICE_STATUS_MASK ) + { + dcd_reg->DEVCMDSTAT |= CMDSTAT_RESET_CHANGE_MASK | CMDSTAT_CONNECT_CHANGE_MASK | CMDSTAT_SUSPEND_CHANGE_MASK; + + if ( cmd_stat & CMDSTAT_RESET_CHANGE_MASK) // bus reset + { + bus_reset(rhport); + + tusb_speed_t speed = TUSB_SPEED_FULL; + + if (_dcd_controller[rhport].max_speed == TUSB_SPEED_HIGH) + { + // 0 : reserved, 1 : full, 2 : high, 3: super + if ( 2 == ((cmd_stat >> CMDSTAT_SPEED_SHIFT) & 0x3UL) ) + { + speed= TUSB_SPEED_HIGH; + } + } + + dcd_event_bus_reset(rhport, speed, true); + } + + if (cmd_stat & CMDSTAT_CONNECT_CHANGE_MASK) + { + // device disconnect + if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK) + { + // debouncing as this can be set when device is powering + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + } + + // TODO support suspend & resume + if (cmd_stat & CMDSTAT_SUSPEND_CHANGE_MASK) + { + if (cmd_stat & CMDSTAT_DEVICE_SUSPEND_MASK) + { // suspend signal, bus idle for more than 3ms + // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. + if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + } + } +// else +// { // resume signal +// dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); +// } +// } + } + + // Setup Receive + if ( tu_bit_test(int_status, 0) && (cmd_stat & CMDSTAT_SETUP_RECEIVED_MASK) ) + { + // Follow UM flowchart to clear Active & Stall on both Control IN/OUT endpoints + _dcd.ep[0][0].active = _dcd.ep[1][0].active = 0; + _dcd.ep[0][0].stall = _dcd.ep[1][0].stall = 0; + + dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK; + + dcd_event_setup_received(rhport, _dcd.setup_packet, true); + + // keep waiting for next setup + prepare_setup_packet(rhport); + + // clear bit0 + int_status = tu_bit_clear(int_status, 0); + } + + // Endpoint transfer complete interrupt + process_xfer_isr(rhport, int_status); +} + +#endif + diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/common_transdimension.h b/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/common_transdimension.h new file mode 100644 index 0000000..69074de --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/common_transdimension.h @@ -0,0 +1,136 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef COMMON_TRANSDIMENSION_H_ +#define COMMON_TRANSDIMENSION_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// USBCMD +enum { + USBCMD_RUN_STOP = TU_BIT(0), + USBCMD_RESET = TU_BIT(1), + USBCMD_SETUP_TRIPWIRE = TU_BIT(13), + USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD +// Interrupt Threshold bit 23:16 +}; + +// PORTSC1 +#define PORTSC1_PORT_SPEED_POS 26 + +enum { + PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0), + PORTSC1_FORCE_PORT_RESUME = TU_BIT(6), + PORTSC1_SUSPEND = TU_BIT(7), + PORTSC1_FORCE_FULL_SPEED = TU_BIT(24), + PORTSC1_PORT_SPEED = TU_BIT(26) | TU_BIT(27) +}; + +// OTGSC +enum { + OTGSC_VBUS_DISCHARGE = TU_BIT(0), + OTGSC_VBUS_CHARGE = TU_BIT(1), +// OTGSC_HWASSIST_AUTORESET = TU_BIT(2), + OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode + OTGSC_DATA_PULSING = TU_BIT(4), + OTGSC_ID_PULLUP = TU_BIT(5), +// OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6), +// OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7), + OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device + OTGSC_A_VBUS_VALID = TU_BIT(9), + OTGSC_A_SESSION_VALID = TU_BIT(10), + OTGSC_B_SESSION_VALID = TU_BIT(11), + OTGSC_B_SESSION_END = TU_BIT(12), + OTGSC_1MS_TOGGLE = TU_BIT(13), + OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14), +}; + +// USBMode +enum { + USBMODE_CM_DEVICE = 2, + USBMODE_CM_HOST = 3, + + USBMODE_SLOM = TU_BIT(3), + USBMODE_SDIS = TU_BIT(4), + + USBMODE_VBUS_POWER_SELECT = TU_BIT(5), // Need to be enabled for LPC18XX/43XX in host mode +}; + +// Device Registers +typedef struct +{ + //------------- ID + HW Parameter Registers-------------// + __I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX + + //------------- Capability Registers-------------// + __I uint8_t CAPLENGTH; ///< Capability Registers Length + __I uint8_t TU_RESERVED[1]; + __I uint16_t HCIVERSION; ///< Host Controller Interface Version + + __I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters + __I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters + __I uint32_t TU_RESERVED[5]; + + __I uint16_t DCIVERSION; ///< Device Controller Interface Version + __I uint8_t TU_RESERVED[2]; + + __I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters + __I uint32_t TU_RESERVED[6]; + + //------------- Operational Registers -------------// + __IO uint32_t USBCMD; ///< USB Command Register + __IO uint32_t USBSTS; ///< USB Status Register + __IO uint32_t USBINTR; ///< Interrupt Enable Register + __IO uint32_t FRINDEX; ///< USB Frame Index + __I uint32_t TU_RESERVED; + __IO uint32_t DEVICEADDR; ///< Device Address + __IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address + __I uint32_t TU_RESERVED; + __IO uint32_t BURSTSIZE; ///< Programmable Burst Size + __IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning + uint32_t TU_RESERVED[4]; + __IO uint32_t ENDPTNAK; ///< Endpoint NAK + __IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable + __I uint32_t TU_RESERVED; + __IO uint32_t PORTSC1; ///< Port Status & Control + __I uint32_t TU_RESERVED[7]; + __IO uint32_t OTGSC; ///< On-The-Go Status & control + __IO uint32_t USBMODE; ///< USB Device Mode + __IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status + __IO uint32_t ENDPTPRIME; ///< Endpoint Prime + __IO uint32_t ENDPTFLUSH; ///< Endpoint Flush + __I uint32_t ENDPTSTAT; ///< Endpoint Status + __IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete + __IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 +} dcd_registers_t, hcd_registers_t; + +#ifdef __cplusplus + } +#endif + +#endif /* COMMON_TRANSDIMENSION_H_ */ diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c b/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c new file mode 100644 index 0000000..108baf9 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c @@ -0,0 +1,664 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + +#warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #include "fsl_device_registers.h" + #define INCLUDE_FSL_DEVICE_REGISTERS +#else + // LPCOpen for 18xx & 43xx + #include "chip.h" +#endif + +#include "common/tusb_common.h" +#include "device/dcd.h" +#include "common_transdimension.h" + +#if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 + #define CleanInvalidateDCache_by_Addr SCB_CleanInvalidateDCache_by_Addr +#else + #define CleanInvalidateDCache_by_Addr(_addr, _dsize) +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// ENDPTCTRL +enum { + ENDPTCTRL_STALL = TU_BIT(0), + ENDPTCTRL_TOGGLE_INHIBIT = TU_BIT(5), // used for test only + ENDPTCTRL_TOGGLE_RESET = TU_BIT(6), + ENDPTCTRL_ENABLE = TU_BIT(7) +}; + +enum { + ENDPTCTRL_TYPE_POS = 2, // Endpoint type is 2-bit field +}; + +// USBSTS, USBINTR +enum { + INTR_USB = TU_BIT(0), + INTR_ERROR = TU_BIT(1), + INTR_PORT_CHANGE = TU_BIT(2), + INTR_RESET = TU_BIT(6), + INTR_SOF = TU_BIT(7), + INTR_SUSPEND = TU_BIT(8), + INTR_NAK = TU_BIT(16) +}; + +// Queue Transfer Descriptor +typedef struct +{ + // Word 0: Next QTD Pointer + uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed + + // Word 1: qTQ Token + uint32_t : 3 ; + volatile uint32_t xact_err : 1 ; + uint32_t : 1 ; + volatile uint32_t buffer_err : 1 ; + volatile uint32_t halted : 1 ; + volatile uint32_t active : 1 ; + uint32_t : 2 ; + uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. + uint32_t : 3 ; + uint32_t int_on_complete : 1 ; + volatile uint32_t total_bytes : 15 ; + uint32_t : 1 ; + + // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page + uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous + + //--------------------------------------------------------------------+ + // TD is 32 bytes aligned but occupies only 28 bytes + // Therefore there are 4 bytes padding that we can use. + //--------------------------------------------------------------------+ + uint16_t expected_bytes; + uint8_t reserved[2]; +} dcd_qtd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); + +// Queue Head +typedef struct +{ + // Word 0: Capabilities and Characteristics + uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. + uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. + uint32_t max_packet_size : 11 ; ///< Endpoint's wMaxPacketSize + uint32_t : 2 ; + uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multipleâ€. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. + uint32_t iso_mult : 2 ; ///< + + // Word 1: Current qTD Pointer + volatile uint32_t qtd_addr; + + // Word 2-9: Transfer Overlay + volatile dcd_qtd_t qtd_overlay; + + // Word 10-11: Setup request (control OUT only) + volatile tusb_control_request_t setup_request; + + //--------------------------------------------------------------------+ + // QHD is 64 bytes aligned but occupies only 48 bytes + // Therefore there are 16 bytes padding that we can use. + //--------------------------------------------------------------------+ + tu_fifo_t * ff; + uint8_t reserved[12]; +} dcd_qhd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); + +//--------------------------------------------------------------------+ +// Variables +//--------------------------------------------------------------------+ + +typedef struct +{ + dcd_registers_t* regs; // registers + const IRQn_Type irqnum; // IRQ number + const uint8_t ep_count; // Max bi-directional Endpoints +}dcd_controller_t; + +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + static const dcd_controller_t _dcd_controller[] = + { + // RT1010 and RT1020 only has 1 USB controller + #if FSL_FEATURE_SOC_USBHS_COUNT == 1 + { .regs = (dcd_registers_t*) USB_BASE , .irqnum = USB_OTG1_IRQn, .ep_count = 8 } + #else + { .regs = (dcd_registers_t*) USB1_BASE, .irqnum = USB_OTG1_IRQn, .ep_count = 8 }, + { .regs = (dcd_registers_t*) USB2_BASE, .irqnum = USB_OTG2_IRQn, .ep_count = 8 } + #endif + }; + +#else + static const dcd_controller_t _dcd_controller[] = + { + { .regs = (dcd_registers_t*) LPC_USB0_BASE, .irqnum = USB0_IRQn, .ep_count = 6 }, + { .regs = (dcd_registers_t*) LPC_USB1_BASE, .irqnum = USB1_IRQn, .ep_count = 4 } + }; +#endif + +#define QTD_NEXT_INVALID 0x01 + +typedef struct { + // Must be at 2K alignment + // Each endpoint with direction (IN/OUT) occupies a queue head + // for portability, TinyUSB only queue 1 TD for each Qhd + dcd_qhd_t qhd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(64); + dcd_qtd_t qtd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32); +}dcd_data_t; + +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048) +static dcd_data_t _dcd_data; + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +/// follows LPC43xx User Manual 23.10.3 +static void bus_reset(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + // The reset value for all endpoint types is the control endpoint. If one endpoint + // direction is enabled and the paired endpoint of opposite direction is disabled, then the + // endpoint type of the unused direction must be changed from the control type to any other + // type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior + // for the data PID tracking on the active endpoint. + for( uint8_t i=1; i < _dcd_controller[rhport].ep_count; i++) + { + dcd_reg->ENDPTCTRL[i] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); + } + + //------------- Clear All Registers -------------// + dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK; + dcd_reg->ENDPTNAKEN = 0; + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE; + + while (dcd_reg->ENDPTPRIME) {} + dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; + while (dcd_reg->ENDPTFLUSH) {} + + // read reset bit in portsc + + //------------- Queue Head & Queue TD -------------// + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// + _dcd_data.qhd[0][0].zero_length_termination = _dcd_data.qhd[0][1].zero_length_termination = 1; + _dcd_data.qhd[0][0].max_packet_size = _dcd_data.qhd[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; + _dcd_data.qhd[0][0].qtd_overlay.next = _dcd_data.qhd[0][1].qtd_overlay.next = QTD_NEXT_INVALID; + + _dcd_data.qhd[0][0].int_on_setup = 1; // OUT only +} + +void dcd_init(uint8_t rhport) +{ + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + // Reset controller + dcd_reg->USBCMD |= USBCMD_RESET; + while( dcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, must be set immediately after reset + dcd_reg->USBMODE = USBMODE_CM_DEVICE; + dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION; + +#if !TUD_OPT_HIGH_SPEED + dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; +#endif + + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_SUSPEND; + + dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 + dcd_reg->USBCMD |= USBCMD_RUN_STOP; // Connect +} + +void dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + // Response with status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->PORTSC1 |= PORTSC1_FORCE_PORT_RESUME; +} + +void dcd_connect(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->USBCMD |= USBCMD_RUN_STOP; +} + +void dcd_disconnect(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; +} + +//--------------------------------------------------------------------+ +// HELPER +//--------------------------------------------------------------------+ + +static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) +{ + // Force the CPU to flush the buffer. We increase the size by 31 because the call aligns the + // address to 32-byte boundaries. Buffer must be word aligned + CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) data_ptr, 4), total_bytes + 31); + + tu_memclr(p_qtd, sizeof(dcd_qtd_t)); + + p_qtd->next = QTD_NEXT_INVALID; + p_qtd->active = 1; + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + p_qtd->int_on_complete = true; + + if (data_ptr != NULL) + { + p_qtd->buffer[0] = (uint32_t) data_ptr; + + uint32_t const bufend = p_qtd->buffer[0] + total_bytes; + for(uint8_t i=1; i<5; i++) + { + uint32_t const next_page = tu_align4k( p_qtd->buffer[i-1] ) + 4096; + if ( bufend <= next_page ) break; + + p_qtd->buffer[i] = next_page; + + // TODO page[1] FRAME_N for ISO transfer + } + } +} + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); + + // flush to abort any primed buffer + dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // data toggle also need to be reset + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); + dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + + // Must not exceed max endpoint number + TU_ASSERT( epnum < _dcd_controller[rhport].ep_count ); + + //------------- Prepare Queue Head -------------// + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + tu_memclr(p_qhd, sizeof(dcd_qhd_t)); + + p_qhd->zero_length_termination = 1; + p_qhd->max_packet_size = tu_edpt_packet_size(p_endpoint_desc); + if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) + { + p_qhd->iso_mult = 1; + } + + p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; + + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + // Enable EP Control + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + uint32_t const epctrl = (p_endpoint_desc->bmAttributes.xfer << ENDPTCTRL_TYPE_POS) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET; + + if ( dir == TUSB_DIR_OUT ) + { + dcd_reg->ENDPTCTRL[epnum] = (dcd_reg->ENDPTCTRL[epnum] & 0xFFFF0000u) | epctrl; + }else + { + dcd_reg->ENDPTCTRL[epnum] = (dcd_reg->ENDPTCTRL[epnum] & 0x0000FFFFu) | (epctrl << 16); + } + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + // Disable all non-control endpoints + for( uint8_t epnum=1; epnum < _dcd_controller[rhport].ep_count; epnum++) + { + _dcd_data.qhd[epnum][TUSB_DIR_OUT].qtd_overlay.halted = 1; + _dcd_data.qhd[epnum][TUSB_DIR_IN ].qtd_overlay.halted = 1; + + dcd_reg->ENDPTFLUSH = TU_BIT(epnum) | TU_BIT(epnum+16); + dcd_reg->ENDPTCTRL[epnum] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); + } +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + _dcd_data.qhd[epnum][dir].qtd_overlay.halted = 1; + + // Flush EP + uint32_t const flush_mask = TU_BIT(epnum + (dir ? 16 : 0)); + dcd_reg->ENDPTFLUSH = flush_mask; + while(dcd_reg->ENDPTFLUSH & flush_mask); + + // Clear EP enable + dcd_reg->ENDPTCTRL[epnum] &=~(ENDPTCTRL_ENABLE << (dir ? 16 : 0)); +} + +static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir]; + + p_qhd->qtd_overlay.halted = false; // clear any previous error + p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd + + // flush cache + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + if ( epnum == 0 ) + { + // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism + // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out + while(dcd_reg->ENDPTSETUPSTAT & TU_BIT(0)) {} + } + + // start transfer + dcd_reg->ENDPTPRIME = TU_BIT(epnum + (dir ? 16 : 0)); +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir]; + + // Prepare qtd + qtd_init(p_qtd, buffer, total_bytes); + + // Start qhd transfer + p_qhd->ff = NULL; + qhd_start_xfer(rhport, epnum, dir); + + return true; +} + +// fifo has to be aligned to 4k boundary +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[epnum][dir]; + + tu_fifo_buffer_info_t fifo_info; + + if (dir) + { + tu_fifo_get_read_info(ff, &fifo_info); + } else + { + tu_fifo_get_write_info(ff, &fifo_info); + } + + if ( fifo_info.len_lin >= total_bytes ) + { + // Linear length is enough for this transfer + qtd_init(p_qtd, fifo_info.ptr_lin, total_bytes); + } + else + { + // linear part is not enough + + // prepare TD up to linear length + qtd_init(p_qtd, fifo_info.ptr_lin, fifo_info.len_lin); + + if ( !tu_offset4k((uint32_t) fifo_info.ptr_wrap) && !tu_offset4k(tu_fifo_depth(ff)) ) + { + // If buffer is aligned to 4K & buffer size is multiple of 4K + // We can make use of buffer page array to also combine the linear + wrapped length + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + + for(uint8_t i = 1, page = 0; i < 5; i++) + { + // pick up buffer array where linear ends + if (p_qtd->buffer[i] == 0) + { + p_qtd->buffer[i] = (uint32_t) fifo_info.ptr_wrap + 4096 * page; + page++; + } + } + + CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_wrap, 4), total_bytes - fifo_info.len_wrap + 31); + } + else + { + // TODO we may need to carry the wrapped length after the linear part complete + // for now only transfer up to linear part + } + } + + // Start qhd transfer + p_qhd->ff = ff; + qhd_start_xfer(rhport, epnum, dir); + + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ + +static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir) +{ + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[epnum][dir]; + + uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : + ( p_qtd->xact_err || p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; + + if ( result != XFER_RESULT_SUCCESS ) + { + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + // flush to abort error buffer + dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); + } + + uint16_t const xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes; + + if (p_qhd->ff) + { + if (dir == TUSB_DIR_IN) + { + tu_fifo_advance_read_pointer(p_qhd->ff, xferred_bytes); + } else + { + tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes); + } + } + + // only number of bytes in the IOC qtd + dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), xferred_bytes, result, true); +} + +void dcd_int_handler(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + uint32_t const int_enable = dcd_reg->USBINTR; + uint32_t const int_status = dcd_reg->USBSTS & int_enable; + dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt + + // disabled interrupt sources + if (int_status == 0) return; + + // Set if the port controller enters the full or high-speed operational state. + // either from Bus Reset or Suspended state + if (int_status & INTR_PORT_CHANGE) + { + // TU_LOG2("PortChange %08lx\r\n", dcd_reg->PORTSC1); + + // Reset interrupt is not enabled, we manually check if Port Change is due + // to connection / disconnection + if ( dcd_reg->USBSTS & INTR_RESET ) + { + dcd_reg->USBSTS = INTR_RESET; + + if (dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) + { + uint32_t const speed = (dcd_reg->PORTSC1 & PORTSC1_PORT_SPEED) >> PORTSC1_PORT_SPEED_POS; + bus_reset(rhport); + dcd_event_bus_reset(rhport, (tusb_speed_t) speed, true); + }else + { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + } + else + { + // Triggered by resuming from suspended state + if ( !(dcd_reg->PORTSC1 & PORTSC1_SUSPEND) ) + { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + } + } + + if (int_status & INTR_SUSPEND) + { + // TU_LOG2("Suspend %08lx\r\n", dcd_reg->PORTSC1); + + if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) + { + // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. + // Skip suspend event if we are not addressed + if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + } + } + + if (int_status & INTR_USB) + { + // Make sure we read the latest version of _dcd_data. + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE; + dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge + + if (dcd_reg->ENDPTSETUPSTAT) + { + //------------- Set up Received -------------// + // 23.10.10.2 Operational model for setup transfers + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + + dcd_event_setup_received(rhport, (uint8_t*)(uintptr_t) &_dcd_data.qhd[0][0].setup_request, true); + } + + // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set + // nothing to do, we will submit xfer as error to usbd + // if (int_status & INTR_ERROR) { } + + if ( edpt_complete ) + { + for(uint8_t epnum = 0; epnum < TUP_DCD_ENDPOINT_MAX; epnum++) + { + if ( tu_bit_test(edpt_complete, epnum) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_OUT); + if ( tu_bit_test(edpt_complete, epnum+16) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN); + } + } + } + + if (int_status & INTR_SOF) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/hcd_transdimension.c b/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/hcd_transdimension.c new file mode 100644 index 0000000..2d08309 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/nxp/transdimension/hcd_transdimension.c @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +// NXP Trans-Dimension USB IP implement EHCI for host functionality + +#if CFG_TUH_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + +#warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #include "fsl_device_registers.h" +#else + // LPCOpen for 18xx & 43xx + #include "chip.h" +#endif + +#include "common/tusb_common.h" +#include "common_transdimension.h" +#include "portable/ehci/ehci_api.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// TODO can be merged with dcd_controller_t +typedef struct +{ + uint32_t regs_base; // registers base + const IRQn_Type irqnum; // IRQ number +}hcd_controller_t; + +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + static const hcd_controller_t _hcd_controller[] = + { + // RT1010 and RT1020 only has 1 USB controller + #if FSL_FEATURE_SOC_USBHS_COUNT == 1 + { .regs_base = USB_BASE , .irqnum = USB_OTG1_IRQn } + #else + { .regs_base = USB1_BASE, .irqnum = USB_OTG1_IRQn }, + { .regs_base = USB2_BASE, .irqnum = USB_OTG2_IRQn } + #endif + }; + +#else + static const hcd_controller_t _hcd_controller[] = + { + { .regs_base = LPC_USB0_BASE, .irqnum = USB0_IRQn }, + { .regs_base = LPC_USB1_BASE, .irqnum = USB1_IRQn } + }; +#endif + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +bool hcd_init(uint8_t rhport) +{ + hcd_registers_t* hcd_reg = (hcd_registers_t*) _hcd_controller[rhport].regs_base; + + // Reset controller + hcd_reg->USBCMD |= USBCMD_RESET; + while( hcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, must be set immediately after reset +#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX + // LPC18XX/43XX need to set VBUS Power Select to HIGH + // RHPORT1 is fullspeed only (need external PHY for Highspeed) + hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT; + if (rhport == 1) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; +#else + hcd_reg->USBMODE = USBMODE_CM_HOST; +#endif + + // FIXME force full speed, still have issue with Highspeed enumeration + hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; + + return ehci_init(rhport, (uint32_t) &hcd_reg->CAPLENGTH, (uint32_t) &hcd_reg->USBCMD); +} + +void hcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(_hcd_controller[rhport].irqnum); +} + +void hcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(_hcd_controller[rhport].irqnum); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/ohci/ohci.c b/circuitpython/lib/tinyusb/src/portable/ohci/ohci.c new file mode 100644 index 0000000..e093822 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/ohci/ohci.c @@ -0,0 +1,657 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && defined(TUP_USBIP_OHCI) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "osal/osal.h" + +#include "host/hcd.h" +#include "ohci.h" + +// TODO remove +#include "chip.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +#define OHCI_REG ((ohci_registers_t *) LPC_USB_BASE) + +enum { + OHCI_CONTROL_FUNCSTATE_RESET = 0, + OHCI_CONTROL_FUNCSTATE_RESUME, + OHCI_CONTROL_FUNCSTATE_OPERATIONAL, + OHCI_CONTROL_FUNCSTATE_SUSPEND +}; + +enum { + OHCI_CONTROL_CONTROL_BULK_RATIO = 3, ///< This specifies the service ratio between Control and Bulk EDs. 0 = 1:1, 3 = 4:1 + OHCI_CONTROL_LIST_PERIODIC_ENABLE_MASK = TU_BIT(2), + OHCI_CONTROL_LIST_ISOCHRONOUS_ENABLE_MASK = TU_BIT(3), + OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK = TU_BIT(4), + OHCI_CONTROL_LIST_BULK_ENABLE_MASK = TU_BIT(5), +}; + +enum { + OHCI_FMINTERVAL_FI = 0x2EDF, // 7.3.1 nominal (reset) value + OHCI_FMINTERVAL_FSMPS = (6*(OHCI_FMINTERVAL_FI-210)) / 7, // 5.4 calculated based on maximum overhead + bit stuffing +}; + +enum { + OHCI_PERIODIC_START = 0x3E67 +}; + +enum { + OHCI_INT_SCHEDULING_OVERUN_MASK = TU_BIT(0), + OHCI_INT_WRITEBACK_DONEHEAD_MASK = TU_BIT(1), + OHCI_INT_SOF_MASK = TU_BIT(2), + OHCI_INT_RESUME_DETECTED_MASK = TU_BIT(3), + OHCI_INT_UNRECOVERABLE_ERROR_MASK = TU_BIT(4), + OHCI_INT_FRAME_OVERFLOW_MASK = TU_BIT(5), + OHCI_INT_RHPORT_STATUS_CHANGE_MASK = TU_BIT(6), + + OHCI_INT_OWNERSHIP_CHANGE_MASK = TU_BIT(30), + OHCI_INT_MASTER_ENABLE_MASK = TU_BIT(31), +}; + +enum { + RHPORT_CURRENT_CONNECT_STATUS_MASK = TU_BIT(0), + RHPORT_PORT_ENABLE_STATUS_MASK = TU_BIT(1), + RHPORT_PORT_SUSPEND_STATUS_MASK = TU_BIT(2), + RHPORT_PORT_OVER_CURRENT_INDICATOR_MASK = TU_BIT(3), + RHPORT_PORT_RESET_STATUS_MASK = TU_BIT(4), ///< write '1' to reset port + + RHPORT_PORT_POWER_STATUS_MASK = TU_BIT(8), + RHPORT_LOW_SPEED_DEVICE_ATTACHED_MASK = TU_BIT(9), + + RHPORT_CONNECT_STATUS_CHANGE_MASK = TU_BIT(16), + RHPORT_PORT_ENABLE_CHANGE_MASK = TU_BIT(17), + RHPORT_PORT_SUSPEND_CHANGE_MASK = TU_BIT(18), + RHPORT_OVER_CURRENT_CHANGE_MASK = TU_BIT(19), + RHPORT_PORT_RESET_CHANGE_MASK = TU_BIT(20), + + RHPORT_ALL_CHANGE_MASK = RHPORT_CONNECT_STATUS_CHANGE_MASK | RHPORT_PORT_ENABLE_CHANGE_MASK | + RHPORT_PORT_SUSPEND_CHANGE_MASK | RHPORT_OVER_CURRENT_CHANGE_MASK | RHPORT_PORT_RESET_CHANGE_MASK +}; + +enum { + OHCI_CCODE_NO_ERROR = 0, + OHCI_CCODE_CRC = 1, + OHCI_CCODE_BIT_STUFFING = 2, + OHCI_CCODE_DATA_TOGGLE_MISMATCH = 3, + OHCI_CCODE_STALL = 4, + OHCI_CCODE_DEVICE_NOT_RESPONDING = 5, + OHCI_CCODE_PID_CHECK_FAILURE = 6, + OHCI_CCODE_UNEXPECTED_PID = 7, + OHCI_CCODE_DATA_OVERRUN = 8, + OHCI_CCODE_DATA_UNDERRUN = 9, + OHCI_CCODE_BUFFER_OVERRUN = 12, + OHCI_CCODE_BUFFER_UNDERRUN = 13, + OHCI_CCODE_NOT_ACCESSED = 14, +}; + +enum { + OHCI_INT_ON_COMPLETE_YES = 0, + OHCI_INT_ON_COMPLETE_NO = TU_BIN8(111) +}; + +enum { + GTD_DT_TOGGLE_CARRY = 0, + GTD_DT_DATA0 = TU_BIT(1) | 0, + GTD_DT_DATA1 = TU_BIT(1) | 1, +}; + +enum { + PID_SETUP = 0, + PID_OUT, + PID_IN, +}; + +enum { + PID_FROM_TD = 0, +}; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static ohci_data_t ohci_data; + +static ohci_ed_t * const p_ed_head[] = +{ + [TUSB_XFER_CONTROL] = &ohci_data.control[0].ed, + [TUSB_XFER_BULK ] = &ohci_data.bulk_head_ed, + [TUSB_XFER_INTERRUPT] = &ohci_data.period_head_ed, + [TUSB_XFER_ISOCHRONOUS] = NULL // TODO Isochronous +}; + +static void ed_list_insert(ohci_ed_t * p_pre, ohci_ed_t * p_ed); +static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr); + +//--------------------------------------------------------------------+ +// USBH-HCD API +//--------------------------------------------------------------------+ +// Initialization according to 5.1.1.4 +bool hcd_init(uint8_t rhport) +{ + (void) rhport; + + //------------- Data Structure init -------------// + tu_memclr(&ohci_data, sizeof(ohci_data_t)); + for(uint8_t i=0; i<32; i++) + { // assign all interrupt pointes to period head ed + ohci_data.hcca.interrupt_table[i] = (uint32_t) &ohci_data.period_head_ed; + } + + ohci_data.control[0].ed.skip = 1; + ohci_data.bulk_head_ed.skip = 1; + ohci_data.period_head_ed.skip = 1; + + // reset controller + OHCI_REG->command_status_bit.controller_reset = 1; + while( OHCI_REG->command_status_bit.controller_reset ) {} // should not take longer than 10 us + + //------------- init ohci registers -------------// + OHCI_REG->control_head_ed = (uint32_t) &ohci_data.control[0].ed; + OHCI_REG->bulk_head_ed = (uint32_t) &ohci_data.bulk_head_ed; + OHCI_REG->hcca = (uint32_t) &ohci_data.hcca; + + OHCI_REG->interrupt_disable = OHCI_REG->interrupt_enable; // disable all interrupts + OHCI_REG->interrupt_status = OHCI_REG->interrupt_status; // clear current set bits + OHCI_REG->interrupt_enable = OHCI_INT_WRITEBACK_DONEHEAD_MASK | OHCI_INT_RESUME_DETECTED_MASK | + OHCI_INT_UNRECOVERABLE_ERROR_MASK | OHCI_INT_FRAME_OVERFLOW_MASK | OHCI_INT_RHPORT_STATUS_CHANGE_MASK | + OHCI_INT_MASTER_ENABLE_MASK; + + OHCI_REG->control |= OHCI_CONTROL_CONTROL_BULK_RATIO | OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK | + OHCI_CONTROL_LIST_BULK_ENABLE_MASK | OHCI_CONTROL_LIST_PERIODIC_ENABLE_MASK; // TODO Isochronous + + OHCI_REG->frame_interval = (OHCI_FMINTERVAL_FSMPS << 16) | OHCI_FMINTERVAL_FI; + OHCI_REG->periodic_start = (OHCI_FMINTERVAL_FI * 9) / 10; // Periodic start is 90% of frame interval + + OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_OPERATIONAL; // make HC's state to operational state TODO use this to suspend (save power) + OHCI_REG->rh_status_bit.local_power_status_change = 1; // set global power for ports + + return true; +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void) rhport; + return (ohci_data.frame_number_hi << 16) | OHCI_REG->frame_number; +} + + +//--------------------------------------------------------------------+ +// PORT API +//--------------------------------------------------------------------+ +void hcd_port_reset(uint8_t hostid) +{ + (void) hostid; + OHCI_REG->rhport_status[0] = RHPORT_PORT_RESET_STATUS_MASK; +} + +bool hcd_port_connect_status(uint8_t hostid) +{ + (void) hostid; + return OHCI_REG->rhport_status_bit[0].current_connect_status; +} + +tusb_speed_t hcd_port_speed_get(uint8_t hostid) +{ + (void) hostid; + return OHCI_REG->rhport_status_bit[0].low_speed_device_attached ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; +} + +// endpoints are tied to an address, which only reclaim after a long delay when enumerating +// thus there is no need to make sure ED is not in HC's cahed as it will not for sure +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + // TODO OHCI + (void) rhport; + + // addr0 serves as static head --> only set skip bit + if ( dev_addr == 0 ) + { + ohci_data.control[0].ed.skip = 1; + }else + { + // remove control + ed_list_remove_by_addr( p_ed_head[TUSB_XFER_CONTROL], dev_addr); + + // remove bulk + ed_list_remove_by_addr(p_ed_head[TUSB_XFER_BULK], dev_addr); + + // remove interrupt + ed_list_remove_by_addr(p_ed_head[TUSB_XFER_INTERRUPT], dev_addr); + + // TODO remove ISO + } +} + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// List Helper +//--------------------------------------------------------------------+ +static inline tusb_xfer_type_t ed_get_xfer_type(ohci_ed_t const * const p_ed) +{ + return (p_ed->ep_number == 0 ) ? TUSB_XFER_CONTROL : + (p_ed->is_iso ) ? TUSB_XFER_ISOCHRONOUS : + (p_ed->is_interrupt_xfer) ? TUSB_XFER_INTERRUPT : TUSB_XFER_BULK; +} + +static void ed_init(ohci_ed_t *p_ed, uint8_t dev_addr, uint16_t ep_size, uint8_t ep_addr, uint8_t xfer_type, uint8_t interval) +{ + (void) interval; + + // address 0 is used as async head, which always on the list --> cannot be cleared + if (dev_addr != 0) + { + tu_memclr(p_ed, sizeof(ohci_ed_t)); + } + + hcd_devtree_info_t devtree_info; + hcd_devtree_get_info(dev_addr, &devtree_info); + + p_ed->dev_addr = dev_addr; + p_ed->ep_number = ep_addr & 0x0F; + p_ed->pid = (xfer_type == TUSB_XFER_CONTROL) ? PID_FROM_TD : (tu_edpt_dir(ep_addr) ? PID_IN : PID_OUT); + p_ed->speed = devtree_info.speed; + p_ed->is_iso = (xfer_type == TUSB_XFER_ISOCHRONOUS) ? 1 : 0; + p_ed->max_packet_size = ep_size; + + p_ed->used = 1; + p_ed->is_interrupt_xfer = (xfer_type == TUSB_XFER_INTERRUPT ? 1 : 0); +} + +static void gtd_init(ohci_gtd_t* p_td, uint8_t* data_ptr, uint16_t total_bytes) +{ + tu_memclr(p_td, sizeof(ohci_gtd_t)); + + p_td->used = 1; + p_td->expected_bytes = total_bytes; + + p_td->buffer_rounding = 1; // less than queued length is not a error + p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO; + p_td->condition_code = OHCI_CCODE_NOT_ACCESSED; + + p_td->current_buffer_pointer = data_ptr; + p_td->buffer_end = total_bytes ? (data_ptr + total_bytes-1) : data_ptr; +} + +static ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr) +{ + if ( tu_edpt_number(ep_addr) == 0 ) return &ohci_data.control[dev_addr].ed; + + ohci_ed_t* ed_pool = ohci_data.ed_pool; + + for(uint32_t i=0; inext = p_pre->next; + p_pre->next = (uint32_t) p_ed; +} + +static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr) +{ + ohci_ed_t* p_prev = p_head; + + while( p_prev->next ) + { + ohci_ed_t* ed = (ohci_ed_t*) p_prev->next; + + if (ed->dev_addr == dev_addr) + { + // unlink ed + p_prev->next = ed->next; + + // point the removed ED's next pointer to list head to make sure HC can always safely move away from this ED + ed->next = (uint32_t) p_head; + ed->used = 0; + } + + // check next valid since we could remove it + if (p_prev->next) p_prev = (ohci_ed_t*) p_prev->next; + } +} + +static ohci_gtd_t * gtd_find_free(void) +{ + for(uint8_t i=0; i < GTD_MAX; i++) + { + if ( !ohci_data.gtd_pool[i].used ) return &ohci_data.gtd_pool[i]; + } + + return NULL; +} + +static void td_insert_to_ed(ohci_ed_t* p_ed, ohci_gtd_t * p_gtd) +{ + // tail is always NULL + if ( tu_align16(p_ed->td_head.address) == 0 ) + { // TD queue is empty --> head = TD + p_ed->td_head.address |= (uint32_t) p_gtd; + } + else + { // TODO currently only support queue up to 2 TD each endpoint at a time + ((ohci_gtd_t*) tu_align16(p_ed->td_head.address))->next = (uint32_t) p_gtd; + } +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + // TODO iso support + TU_ASSERT(ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); + + //------------- Prepare Queue Head -------------// + ohci_ed_t * p_ed; + + if ( ep_desc->bEndpointAddress == 0 ) + { + p_ed = &ohci_data.control[dev_addr].ed; + }else + { + p_ed = ed_find_free(); + } + TU_ASSERT(p_ed); + + ed_init( p_ed, dev_addr, tu_edpt_packet_size(ep_desc), ep_desc->bEndpointAddress, + ep_desc->bmAttributes.xfer, ep_desc->bInterval ); + + // control of dev0 is used as static async head + if ( dev_addr == 0 ) + { + p_ed->skip = 0; // only need to clear skip bit + return true; + } + + ed_list_insert( p_ed_head[ep_desc->bmAttributes.xfer], p_ed ); + + return true; +} + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void) rhport; + + ohci_ed_t* ed = &ohci_data.control[dev_addr].ed; + ohci_gtd_t *qtd = &ohci_data.control[dev_addr].gtd; + + gtd_init(qtd, (uint8_t*) setup_packet, 8); + qtd->index = dev_addr; + qtd->pid = PID_SETUP; + qtd->data_toggle = GTD_DT_DATA0; + qtd->delay_interrupt = 0; + + //------------- Attach TDs list to Control Endpoint -------------// + ed->td_head.address = (uint32_t) qtd; + + OHCI_REG->command_status_bit.control_list_filled = 1; + + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if ( epnum == 0 ) + { + ohci_ed_t* ed = &ohci_data.control[dev_addr].ed; + ohci_gtd_t* gtd = &ohci_data.control[dev_addr].gtd; + + gtd_init(gtd, buffer, buflen); + + gtd->index = dev_addr; + gtd->pid = dir ? PID_IN : PID_OUT; + gtd->data_toggle = GTD_DT_DATA1; // Both Data and Ack stage start with DATA1 + gtd->delay_interrupt = 0; + + ed->td_head.address = (uint32_t) gtd; + + OHCI_REG->command_status_bit.control_list_filled = 1; + }else + { + ohci_ed_t * ed = ed_from_addr(dev_addr, ep_addr); + ohci_gtd_t* gtd = gtd_find_free(); + + TU_ASSERT(gtd); + + gtd_init(gtd, buffer, buflen); + gtd->index = ed-ohci_data.ed_pool; + gtd->delay_interrupt = 0; + + td_insert_to_ed(ed, gtd); + + tusb_xfer_type_t xfer_type = ed_get_xfer_type( ed_from_addr(dev_addr, ep_addr) ); + if (TUSB_XFER_BULK == xfer_type) OHCI_REG->command_status_bit.bulk_list_filled = 1; + } + + return true; +} + +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr); + + p_ed->is_stalled = 0; + p_ed->td_tail &= 0x0Ful; // set tail pointer back to NULL + + p_ed->td_head.toggle = 0; // reset data toggle + p_ed->td_head.halted = 0; + + if ( TUSB_XFER_BULK == ed_get_xfer_type(p_ed) ) OHCI_REG->command_status_bit.bulk_list_filled = 1; + + return true; +} + + +//--------------------------------------------------------------------+ +// OHCI Interrupt Handler +//--------------------------------------------------------------------+ +static ohci_td_item_t* list_reverse(ohci_td_item_t* td_head) +{ + ohci_td_item_t* td_reverse_head = NULL; + + while(td_head != NULL) + { + uint32_t next = td_head->next; + + // make current's item become reverse's first item + td_head->next = (uint32_t) td_reverse_head; + td_reverse_head = td_head; + + td_head = (ohci_td_item_t*) next; // advance to next item + } + + return td_reverse_head; +} + +static inline bool gtd_is_control(ohci_gtd_t const * const p_qtd) +{ + return ((uint32_t) p_qtd) < ((uint32_t) ohci_data.gtd_pool); // check ohci_data_t for memory layout +} + +static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const * const p_qtd) +{ + if ( gtd_is_control(p_qtd) ) + { + return &ohci_data.control[p_qtd->index].ed; + }else + { + return &ohci_data.ed_pool[p_qtd->index]; + } +} + +static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer) +{ + // 5.2.9 OHCI sample code + + // CBP is 0 mean all data is transferred + if (current_buffer == 0) return 0; + + return (tu_align4k(buffer_end ^ current_buffer) ? 0x1000 : 0) + + tu_offset4k(buffer_end) - tu_offset4k(current_buffer) + 1; +} + +static void done_queue_isr(uint8_t hostid) +{ + (void) hostid; + + // done head is written in reversed order of completion --> need to reverse the done queue first + ohci_td_item_t* td_head = list_reverse ( (ohci_td_item_t*) tu_align16(ohci_data.hcca.done_head) ); + + while( td_head != NULL ) + { + // TODO check if td_head is iso td + //------------- Non ISO transfer -------------// + ohci_gtd_t * const qtd = (ohci_gtd_t *) td_head; + xfer_result_t const event = (qtd->condition_code == OHCI_CCODE_NO_ERROR) ? XFER_RESULT_SUCCESS : + (qtd->condition_code == OHCI_CCODE_STALL) ? XFER_RESULT_STALLED : XFER_RESULT_FAILED; + + qtd->used = 0; // free TD + if ( (qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS) ) + { + ohci_ed_t * const ed = gtd_get_ed(qtd); + + uint32_t const xferred_bytes = qtd->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer); + + // NOTE Assuming the current list is BULK and there is no other EDs in the list has queued TDs. + // When there is a error resulting this ED is halted, and this EP still has other queued TD + // --> the Bulk list only has this halted EP queueing TDs (remaining) + // --> Bulk list will be considered as not empty by HC !!! while there is no attempt transaction on this list + // --> HC will not process Control list (due to service ratio when Bulk list not empty) + // To walk-around this, the halted ED will have TailP = HeadP (empty list condition), when clearing halt + // the TailP must be set back to NULL for processing remaining TDs + if ((event != XFER_RESULT_SUCCESS)) + { + ed->td_tail &= 0x0Ful; + ed->td_tail |= tu_align16(ed->td_head.address); // mark halted EP as empty queue + if ( event == XFER_RESULT_STALLED ) ed->is_stalled = 1; + } + + uint8_t dir = (ed->ep_number == 0) ? (qtd->pid == PID_IN) : (ed->pid == PID_IN); + + hcd_event_xfer_complete(ed->dev_addr, tu_edpt_addr(ed->ep_number, dir), xferred_bytes, event, true); + } + + td_head = (ohci_td_item_t*) td_head->next; + } +} + +void hcd_int_handler(uint8_t hostid) +{ + uint32_t const int_en = OHCI_REG->interrupt_enable; + uint32_t const int_status = OHCI_REG->interrupt_status & int_en; + + if (int_status == 0) return; + + // Frame number overflow + if ( int_status & OHCI_INT_FRAME_OVERFLOW_MASK ) + { + ohci_data.frame_number_hi++; + } + + //------------- RootHub status -------------// + if ( int_status & OHCI_INT_RHPORT_STATUS_CHANGE_MASK ) + { + uint32_t const rhport_status = OHCI_REG->rhport_status[0] & RHPORT_ALL_CHANGE_MASK; + + // TODO dual port is not yet supported + if ( rhport_status & RHPORT_CONNECT_STATUS_CHANGE_MASK ) + { + // TODO check if remote wake-up + if ( OHCI_REG->rhport_status_bit[0].current_connect_status ) + { + // TODO reset port immediately, without this controller will got 2-3 (debouncing connection status change) + OHCI_REG->rhport_status[0] = RHPORT_PORT_RESET_STATUS_MASK; + hcd_event_device_attach(hostid, true); + }else + { + hcd_event_device_remove(hostid, true); + } + } + + if ( rhport_status & RHPORT_PORT_SUSPEND_CHANGE_MASK) + { + + } + + OHCI_REG->rhport_status[0] = rhport_status; // acknowledge all interrupt + } + + //------------- Transfer Complete -------------// + if (int_status & OHCI_INT_WRITEBACK_DONEHEAD_MASK) + { + done_queue_isr(hostid); + } + + OHCI_REG->interrupt_status = int_status; // Acknowledge handled interrupt +} +//--------------------------------------------------------------------+ +// HELPER +//--------------------------------------------------------------------+ + + +#endif + diff --git a/circuitpython/lib/tinyusb/src/portable/ohci/ohci.h b/circuitpython/lib/tinyusb/src/portable/ohci/ohci.h new file mode 100644 index 0000000..9fc954c --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/ohci/ohci.h @@ -0,0 +1,278 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OHCI_H_ +#define _TUSB_OHCI_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// OHCI CONFIGURATION & CONSTANTS +//--------------------------------------------------------------------+ +#define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enalbed +#define OHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS) + +// TODO merge OHCI with EHCI +enum { + OHCI_MAX_ITD = 4 +}; + +#define ED_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX) +#define GTD_MAX ED_MAX + +//--------------------------------------------------------------------+ +// OHCI Data Structure +//--------------------------------------------------------------------+ +typedef struct { + uint32_t interrupt_table[32]; + volatile uint16_t frame_number; + volatile uint16_t frame_pad; + volatile uint32_t done_head; + uint8_t reserved[116+4]; // TODO try to make use of this area if possible, extra 4 byte to make the whole struct size = 256 +}ohci_hcca_t; // TU_ATTR_ALIGNED(256) + +TU_VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" ); + +typedef struct { + uint32_t reserved[2]; + volatile uint32_t next; + uint32_t reserved2; +}ohci_td_item_t; + +typedef struct TU_ATTR_ALIGNED(16) +{ + // Word 0 + uint32_t used : 1; + uint32_t index : 4; // endpoint index the td belongs to, or device address in case of control xfer + uint32_t expected_bytes : 13; // TODO available for hcd + + uint32_t buffer_rounding : 1; + uint32_t pid : 2; + uint32_t delay_interrupt : 3; + volatile uint32_t data_toggle : 2; + volatile uint32_t error_count : 2; + volatile uint32_t condition_code : 4; + + // Word 1 + volatile uint8_t* current_buffer_pointer; + + // Word 2 : next TD + volatile uint32_t next; + + // Word 3 + uint8_t* buffer_end; +} ohci_gtd_t; + +TU_VERIFY_STATIC( sizeof(ohci_gtd_t) == 16, "size is not correct" ); + +typedef struct TU_ATTR_ALIGNED(16) +{ + // Word 0 + uint32_t dev_addr : 7; + uint32_t ep_number : 4; + uint32_t pid : 2; + uint32_t speed : 1; + uint32_t skip : 1; + uint32_t is_iso : 1; + uint32_t max_packet_size : 11; + // HCD: make use of 5 reserved bits + uint32_t used : 1; + uint32_t is_interrupt_xfer : 1; + uint32_t is_stalled : 1; + uint32_t : 2; + + // Word 1 + uint32_t td_tail; + + // Word 2 + volatile union { + uint32_t address; + struct { + uint32_t halted : 1; + uint32_t toggle : 1; + uint32_t : 30; + }; + }td_head; + + // Word 3: next ED + uint32_t next; +} ohci_ed_t; + +TU_VERIFY_STATIC( sizeof(ohci_ed_t) == 16, "size is not correct" ); + +typedef struct TU_ATTR_ALIGNED(32) +{ + /*---------- Word 1 ----------*/ + uint32_t starting_frame : 16; + uint32_t : 5; // can be used + uint32_t delay_interrupt : 3; + uint32_t frame_count : 3; + uint32_t : 1; // can be used + volatile uint32_t condition_code : 4; + + /*---------- Word 2 ----------*/ + uint32_t buffer_page0; // 12 lsb bits can be used + + /*---------- Word 3 ----------*/ + volatile uint32_t next; + + /*---------- Word 4 ----------*/ + uint32_t buffer_end; + + /*---------- Word 5-8 ----------*/ + volatile uint16_t offset_packetstatus[8]; +} ochi_itd_t; + +TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" ); + +// structure with member alignment required from large to small +typedef struct TU_ATTR_ALIGNED(256) +{ + ohci_hcca_t hcca; + + ohci_ed_t bulk_head_ed; // static bulk head (dummy) + ohci_ed_t period_head_ed; // static periodic list head (dummy) + + // control endpoints has reserved resources + struct { + ohci_ed_t ed; + ohci_gtd_t gtd; + }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; + + // ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32 + ohci_ed_t ed_pool[ED_MAX]; + ohci_gtd_t gtd_pool[GTD_MAX]; + + volatile uint16_t frame_number_hi; + +} ohci_data_t; + +//--------------------------------------------------------------------+ +// OHCI Operational Register +//--------------------------------------------------------------------+ + + +//--------------------------------------------------------------------+ +// OHCI Data Organization +//--------------------------------------------------------------------+ +typedef volatile struct +{ + uint32_t revision; + + union { + uint32_t control; + struct { + uint32_t control_bulk_service_ratio : 2; + uint32_t periodic_list_enable : 1; + uint32_t isochronous_enable : 1; + uint32_t control_list_enable : 1; + uint32_t bulk_list_enable : 1; + uint32_t hc_functional_state : 2; + uint32_t interrupt_routing : 1; + uint32_t remote_wakeup_connected : 1; + uint32_t remote_wakeup_enale : 1; + uint32_t TU_RESERVED : 21; + }control_bit; + }; + + union { + uint32_t command_status; + struct { + uint32_t controller_reset : 1; + uint32_t control_list_filled : 1; + uint32_t bulk_list_filled : 1; + uint32_t ownership_change_request : 1; + uint32_t : 12; + uint32_t scheduling_overrun_count : 2; + }command_status_bit; + }; + + uint32_t interrupt_status; + uint32_t interrupt_enable; + uint32_t interrupt_disable; + + uint32_t hcca; + uint32_t period_current_ed; + uint32_t control_head_ed; + uint32_t control_current_ed; + uint32_t bulk_head_ed; + uint32_t bulk_current_ed; + uint32_t done_head; + + uint32_t frame_interval; + uint32_t frame_remaining; + uint32_t frame_number; + uint32_t periodic_start; + uint32_t lowspeed_threshold; + + uint32_t rh_descriptorA; + uint32_t rh_descriptorB; + + union { + uint32_t rh_status; + struct { + uint32_t local_power_status : 1; // read Local Power Status; write: Clear Global Power + uint32_t over_current_indicator : 1; + uint32_t : 13; + uint32_t device_remote_wakeup_enable : 1; + uint32_t local_power_status_change : 1; + uint32_t over_current_indicator_change : 1; + uint32_t : 13; + uint32_t clear_remote_wakeup_enable : 1; + }rh_status_bit; + }; + + union { + uint32_t rhport_status[2]; // TODO NXP OHCI controller only has 2 ports + struct { + uint32_t current_connect_status : 1; + uint32_t port_enable_status : 1; + uint32_t port_suspend_status : 1; + uint32_t port_over_current_indicator : 1; + uint32_t port_reset_status : 1; + uint32_t : 3; + uint32_t port_power_status : 1; + uint32_t low_speed_device_attached : 1; + uint32_t : 6; + uint32_t connect_status_change : 1; + uint32_t port_enable_status_change : 1; + uint32_t port_suspend_status_change : 1; + uint32_t port_over_current_indicator_change : 1; + uint32_t port_reset_status_change : 1; + uint32_t TU_RESERVED : 11; + }rhport_status_bit[2]; + }; +}ohci_registers_t; + +TU_VERIFY_STATIC( sizeof(ohci_registers_t) == 0x5c, "size is not correct"); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OHCI_H_ */ diff --git a/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c new file mode 100644 index 0000000..9158227 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -0,0 +1,510 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040 + +#include "pico.h" +#include "rp2040_usb.h" + +#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX +#include "pico/fix/rp2040_usb_device_enumeration.h" +#endif + +#include "device/dcd.h" + +// Current implementation force vbus detection as always present, causing device think it is always plugged into host. +// Therefore it cannot detect disconnect event, mistaken it as suspend. +// Note: won't work if change to 0 (for now) +#define FORCE_VBUS_DETECT 1 + +/*------------------------------------------------------------------*/ +/* Low level controller + *------------------------------------------------------------------*/ + +#define usb_hw_set hw_set_alias(usb_hw) +#define usb_hw_clear hw_clear_alias(usb_hw) + +// Init these in dcd_init +static uint8_t *next_buffer_ptr; + +// USB_MAX_ENDPOINTS Endpoints, direction TUSB_DIR_OUT for out and TUSB_DIR_IN for in. +static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]; + +static inline struct hw_endpoint *hw_endpoint_get_by_num(uint8_t num, tusb_dir_t dir) +{ + return &hw_endpoints[num][dir]; +} + +static struct hw_endpoint *hw_endpoint_get_by_addr(uint8_t ep_addr) +{ + uint8_t num = tu_edpt_number(ep_addr); + tusb_dir_t dir = tu_edpt_dir(ep_addr); + return hw_endpoint_get_by_num(num, dir); +} + +static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) +{ + // size must be multiple of 64 + uint size = tu_div_ceil(ep->wMaxPacketSize, 64) * 64u; + + // double buffered Bulk endpoint + if ( transfer_type == TUSB_XFER_BULK ) + { + size *= 2u; + } + + ep->hw_data_buf = next_buffer_ptr; + next_buffer_ptr += size; + + assert(((uintptr_t )next_buffer_ptr & 0b111111u) == 0); + uint dpram_offset = hw_data_offset(ep->hw_data_buf); + hard_assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); + + pico_info(" Alloced %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); + + // Fill in endpoint control register with buffer offset + uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; + + *ep->endpoint_control = reg; +} + +static void _hw_endpoint_close(struct hw_endpoint *ep) +{ + // Clear hardware registers and then zero the struct + // Clears endpoint enable + *ep->endpoint_control = 0; + // Clears buffer available, etc + *ep->buffer_control = 0; + // Clear any endpoint state + memset(ep, 0, sizeof(struct hw_endpoint)); + + // Reclaim buffer space if all endpoints are closed + bool reclaim_buffers = true; + for ( uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++ ) + { + if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL || hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) + { + reclaim_buffers = false; + break; + } + } + if (reclaim_buffers) + { + next_buffer_ptr = &usb_dpram->epx_data[0]; + } +} + +static void hw_endpoint_close(uint8_t ep_addr) +{ + struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + _hw_endpoint_close(ep); +} + +static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) +{ + struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + + const uint8_t num = tu_edpt_number(ep_addr); + const tusb_dir_t dir = tu_edpt_dir(ep_addr); + + ep->ep_addr = ep_addr; + + // For device, IN is a tx transfer and OUT is an rx transfer + ep->rx = (dir == TUSB_DIR_OUT); + + ep->next_pid = 0u; + ep->wMaxPacketSize = wMaxPacketSize; + ep->transfer_type = transfer_type; + + // Every endpoint has a buffer control register in dpram + if ( dir == TUSB_DIR_IN ) + { + ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].in; + } + else + { + ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].out; + } + + // Clear existing buffer control state + *ep->buffer_control = 0; + + if ( num == 0 ) + { + // EP0 has no endpoint control register because the buffer offsets are fixed + ep->endpoint_control = NULL; + + // Buffer offset is fixed (also double buffered) + ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0]; + } + else + { + // Set the endpoint control register (starts at EP1, hence num-1) + if ( dir == TUSB_DIR_IN ) + { + ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].in; + } + else + { + ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].out; + } + + // alloc a buffer and fill in endpoint control register + _hw_endpoint_alloc(ep, transfer_type); + } +} + +static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + hw_endpoint_xfer_start(ep, buffer, total_bytes); +} + +static void hw_handle_buff_status(void) +{ + uint32_t remaining_buffers = usb_hw->buf_status; + pico_trace("buf_status = 0x%08x\n", remaining_buffers); + uint bit = 1u; + for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) + { + if (remaining_buffers & bit) + { + // clear this in advance + usb_hw_clear->buf_status = bit; + + // IN transfer for even i, OUT transfer for odd i + struct hw_endpoint *ep = hw_endpoint_get_by_num(i >> 1u, !(i & 1u)); + + // Continue xfer + bool done = hw_endpoint_xfer_continue(ep); + if (done) + { + // Notify + dcd_event_xfer_complete(0, ep->ep_addr, ep->xferred_len, XFER_RESULT_SUCCESS, true); + hw_endpoint_reset_transfer(ep); + } + remaining_buffers &= ~bit; + } + bit <<= 1u; + } +} + +static void reset_ep0_pid(void) +{ + // If we have finished this transfer on EP0 set pid back to 1 for next + // setup transfer. Also clear a stall in case + uint8_t addrs[] = {0x0, 0x80}; + for (uint i = 0 ; i < TU_ARRAY_SIZE(addrs); i++) + { + struct hw_endpoint *ep = hw_endpoint_get_by_addr(addrs[i]); + ep->next_pid = 1u; + } +} + +static void reset_non_control_endpoints(void) +{ + // Disable all non-control + for ( uint8_t i = 0; i < USB_MAX_ENDPOINTS-1; i++ ) + { + usb_dpram->ep_ctrl[i].in = 0; + usb_dpram->ep_ctrl[i].out = 0; + } + + // clear non-control hw endpoints + tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2*sizeof(hw_endpoint_t)); + + // reclaim buffer space + next_buffer_ptr = &usb_dpram->epx_data[0]; +} + +static void dcd_rp2040_irq(void) +{ + uint32_t const status = usb_hw->ints; + uint32_t handled = 0; + + // xfer events are handled before setup req. So if a transfer completes immediately + // before closing the EP, the events will be delivered in same order. + if (status & USB_INTS_BUFF_STATUS_BITS) + { + handled |= USB_INTS_BUFF_STATUS_BITS; + hw_handle_buff_status(); + } + + if (status & USB_INTS_SETUP_REQ_BITS) + { + handled |= USB_INTS_SETUP_REQ_BITS; + uint8_t const *setup = (uint8_t const *)&usb_dpram->setup_packet; + + // reset pid to both 1 (data and ack) + reset_ep0_pid(); + + // Pass setup packet to tiny usb + dcd_event_setup_received(0, setup, true); + usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS; + } + +#if FORCE_VBUS_DETECT == 0 + // Since we force VBUS detect On, device will always think it is connected and + // couldn't distinguish between disconnect and suspend + if (status & USB_INTS_DEV_CONN_DIS_BITS) + { + handled |= USB_INTS_DEV_CONN_DIS_BITS; + + if ( usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS ) + { + // Connected: nothing to do + }else + { + // Disconnected + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); + } + + usb_hw_clear->sie_status = USB_SIE_STATUS_CONNECTED_BITS; + } +#endif + + // SE0 for 2.5 us or more (will last at least 10ms) + if (status & USB_INTS_BUS_RESET_BITS) + { + pico_trace("BUS RESET\n"); + + handled |= USB_INTS_BUS_RESET_BITS; + + usb_hw->dev_addr_ctrl = 0; + reset_non_control_endpoints(); + dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); + usb_hw_clear->sie_status = USB_SIE_STATUS_BUS_RESET_BITS; + +#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX + // Only run enumeration walk-around if pull up is enabled + if ( usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS ) rp2040_usb_device_enumeration_fix(); +#endif + } + + /* Note from pico datasheet 4.1.2.6.4 (v1.2) + * If you enable the suspend interrupt, it is likely you will see a suspend interrupt when + * the device is first connected but the bus is idle. The bus can be idle for a few ms before + * the host begins sending start of frame packets. You will also see a suspend interrupt + * when the device is disconnected if you do not have a VBUS detect circuit connected. This is + * because without VBUS detection, it is impossible to tell the difference between + * being disconnected and suspended. + */ + if (status & USB_INTS_DEV_SUSPEND_BITS) + { + handled |= USB_INTS_DEV_SUSPEND_BITS; + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + usb_hw_clear->sie_status = USB_SIE_STATUS_SUSPENDED_BITS; + } + + if (status & USB_INTS_DEV_RESUME_FROM_HOST_BITS) + { + handled |= USB_INTS_DEV_RESUME_FROM_HOST_BITS; + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + usb_hw_clear->sie_status = USB_SIE_STATUS_RESUME_BITS; + } + + if (status ^ handled) + { + panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled)); + } +} + +#define USB_INTS_ERROR_BITS ( \ + USB_INTS_ERROR_DATA_SEQ_BITS | \ + USB_INTS_ERROR_BIT_STUFF_BITS | \ + USB_INTS_ERROR_CRC_BITS | \ + USB_INTS_ERROR_RX_OVERFLOW_BITS | \ + USB_INTS_ERROR_RX_TIMEOUT_BITS) + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ + +void dcd_init (uint8_t rhport) +{ + assert(rhport == 0); + + // Reset hardware to default state + rp2040_usb_init(); + +#if FORCE_VBUS_DETECT + // Force VBUS detect so the device thinks it is plugged into a host + usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; +#endif + + irq_set_exclusive_handler(USBCTRL_IRQ, dcd_rp2040_irq); + + // Init control endpoints + tu_memclr(hw_endpoints[0], 2*sizeof(hw_endpoint_t)); + hw_endpoint_init(0x0, 64, TUSB_XFER_CONTROL); + hw_endpoint_init(0x80, 64, TUSB_XFER_CONTROL); + + // Init non-control endpoints + reset_non_control_endpoints(); + + // Initializes the USB peripheral for device mode and enables it. + // Don't need to enable the pull up here. Force VBUS + usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS; + + // Enable individual controller IRQS here. Processor interrupt enable will be used + // for the global interrupt enable... + // Note: Force VBUS detect cause disconnection not detectable + usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS; + usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS | + USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS | + (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS); + + dcd_connect(rhport); +} + +void dcd_int_enable(__unused uint8_t rhport) +{ + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, true); +} + +void dcd_int_disable(__unused uint8_t rhport) +{ + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, false); +} + +void dcd_set_address (__unused uint8_t rhport, __unused uint8_t dev_addr) +{ + assert(rhport == 0); + + // Can't set device address in hardware until status xfer has complete + // Send 0len complete response on EP0 IN + hw_endpoint_xfer(0x80, NULL, 0); +} + +void dcd_remote_wakeup(__unused uint8_t rhport) +{ + pico_info("dcd_remote_wakeup %d\n", rhport); + assert(rhport == 0); + usb_hw_set->sie_ctrl = USB_SIE_CTRL_RESUME_BITS; +} + +// disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(__unused uint8_t rhport) +{ + (void) rhport; + usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; +} + +// connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(__unused uint8_t rhport) +{ + (void) rhport; + usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; +} + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + + if ( request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS ) + { + usb_hw->dev_addr_ctrl = (uint8_t) request->wValue; + } +} + +bool dcd_edpt_open (__unused uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + assert(rhport == 0); + hw_endpoint_init(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer); + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + + // may need to use EP Abort + reset_non_control_endpoints(); +} + +bool dcd_edpt_xfer(__unused uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + assert(rhport == 0); + hw_endpoint_xfer(ep_addr, buffer, total_bytes); + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + if ( tu_edpt_number(ep_addr) == 0 ) + { + // A stall on EP0 has to be armed so it can be cleared on the next setup packet + usb_hw_set->ep_stall_arm = (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS; + } + + struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + + // stall and clear current pending buffer + // may need to use EP_ABORT + _hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_STALL); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + if (tu_edpt_number(ep_addr)) + { + struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + + // clear stall also reset toggle to DATA0, ready for next transfer + ep->next_pid = 0; + _hw_endpoint_buffer_control_clear_mask32(ep, USB_BUF_CTRL_STALL); + } +} + +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + pico_trace("dcd_edpt_close %02x\n", ep_addr); + hw_endpoint_close(ep_addr); +} + +void dcd_int_handler(uint8_t rhport) +{ + (void) rhport; + dcd_rp2040_irq(); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/hcd_rp2040.c new file mode 100644 index 0000000..234bea2 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -0,0 +1,582 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * Copyright (c) 2021 Ha Thach (tinyusb.org) for Double Buffered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040 + +#include "pico.h" +#include "rp2040_usb.h" + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "osal/osal.h" + +#include "host/hcd.h" +#include "host/usbh.h" + +#define ROOT_PORT 0 + +//--------------------------------------------------------------------+ +// Low level rp2040 controller functions +//--------------------------------------------------------------------+ + +#ifndef PICO_USB_HOST_INTERRUPT_ENDPOINTS +#define PICO_USB_HOST_INTERRUPT_ENDPOINTS (USB_MAX_ENDPOINTS - 1) +#endif +static_assert(PICO_USB_HOST_INTERRUPT_ENDPOINTS <= USB_MAX_ENDPOINTS, ""); + +// Host mode uses one shared endpoint register for non-interrupt endpoint +static struct hw_endpoint ep_pool[1 + PICO_USB_HOST_INTERRUPT_ENDPOINTS]; +#define epx (ep_pool[0]) + +#define usb_hw_set hw_set_alias(usb_hw) +#define usb_hw_clear hw_clear_alias(usb_hw) + +// Flags we set by default in sie_ctrl (we add other bits on top) +enum { + SIE_CTRL_BASE = USB_SIE_CTRL_SOF_EN_BITS | USB_SIE_CTRL_KEEP_ALIVE_EN_BITS | + USB_SIE_CTRL_PULLDOWN_EN_BITS | USB_SIE_CTRL_EP0_INT_1BUF_BITS +}; + +static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) +{ + uint8_t num = tu_edpt_number(ep_addr); + if ( num == 0 ) return &epx; + + for ( uint32_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++ ) + { + struct hw_endpoint *ep = &ep_pool[i]; + if ( ep->configured && (ep->dev_addr == dev_addr) && (ep->ep_addr == ep_addr) ) return ep; + } + + return NULL; +} + +static inline uint8_t dev_speed(void) +{ + return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB; +} + +static bool need_pre(uint8_t dev_addr) +{ + // If this device is different to the speed of the root device + // (i.e. is a low speed device on a full speed hub) then need pre + return hcd_port_speed_get(0) != tuh_speed_get(dev_addr); +} + +static void hw_xfer_complete(struct hw_endpoint *ep, xfer_result_t xfer_result) +{ + // Mark transfer as done before we tell the tinyusb stack + uint8_t dev_addr = ep->dev_addr; + uint8_t ep_addr = ep->ep_addr; + uint xferred_len = ep->xferred_len; + hw_endpoint_reset_transfer(ep); + hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); +} + +static void _handle_buff_status_bit(uint bit, struct hw_endpoint *ep) +{ + usb_hw_clear->buf_status = bit; + bool done = hw_endpoint_xfer_continue(ep); + if (done) + { + hw_xfer_complete(ep, XFER_RESULT_SUCCESS); + } +} + +static void hw_handle_buff_status(void) +{ + uint32_t remaining_buffers = usb_hw->buf_status; + pico_trace("buf_status 0x%08x\n", remaining_buffers); + + // Check EPX first + uint bit = 0b1; + if (remaining_buffers & bit) + { + remaining_buffers &= ~bit; + struct hw_endpoint *ep = &epx; + + uint32_t ep_ctrl = *ep->endpoint_control; + if (ep_ctrl & EP_CTRL_DOUBLE_BUFFERED_BITS) + { + TU_LOG(3, "Double Buffered: "); + }else + { + TU_LOG(3, "Single Buffered: "); + } + TU_LOG_HEX(3, ep_ctrl); + + _handle_buff_status_bit(bit, ep); + } + + // Check interrupt endpoints + for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++) + { + // EPX is bit 0 + // IEP1 is bit 2 + // IEP2 is bit 4 + // IEP3 is bit 6 + // etc + bit = 1 << (i*2); + + if (remaining_buffers & bit) + { + remaining_buffers &= ~bit; + _handle_buff_status_bit(bit, &ep_pool[i]); + } + } + + if (remaining_buffers) + { + panic("Unhandled buffer %d\n", remaining_buffers); + } +} + +static void hw_trans_complete(void) +{ + if (usb_hw->sie_ctrl & USB_SIE_CTRL_SEND_SETUP_BITS) + { + pico_trace("Sent setup packet\n"); + struct hw_endpoint *ep = &epx; + assert(ep->active); + hw_xfer_complete(ep, XFER_RESULT_SUCCESS); + } + else + { + // Don't care. Will handle this in buff status + return; + } +} + +static void hcd_rp2040_irq(void) +{ + uint32_t status = usb_hw->ints; + uint32_t handled = 0; + + if (status & USB_INTS_HOST_CONN_DIS_BITS) + { + handled |= USB_INTS_HOST_CONN_DIS_BITS; + + if (dev_speed()) + { + hcd_event_device_attach(ROOT_PORT, true); + } + else + { + hcd_event_device_remove(ROOT_PORT, true); + } + + // Clear speed change interrupt + usb_hw_clear->sie_status = USB_SIE_STATUS_SPEED_BITS; + } + + if (status & USB_INTS_BUFF_STATUS_BITS) + { + handled |= USB_INTS_BUFF_STATUS_BITS; + TU_LOG(2, "Buffer complete\n"); + hw_handle_buff_status(); + } + + if (status & USB_INTS_TRANS_COMPLETE_BITS) + { + handled |= USB_INTS_TRANS_COMPLETE_BITS; + usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS; + TU_LOG(2, "Transfer complete\n"); + hw_trans_complete(); + } + + if (status & USB_INTS_STALL_BITS) + { + // We have rx'd a stall from the device + pico_trace("Stall REC\n"); + handled |= USB_INTS_STALL_BITS; + usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS; + hw_xfer_complete(&epx, XFER_RESULT_STALLED); + } + + if (status & USB_INTS_ERROR_RX_TIMEOUT_BITS) + { + handled |= USB_INTS_ERROR_RX_TIMEOUT_BITS; + usb_hw_clear->sie_status = USB_SIE_STATUS_RX_TIMEOUT_BITS; + } + + if (status & USB_INTS_ERROR_DATA_SEQ_BITS) + { + usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS; + TU_LOG(3, " Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(*epx.buffer_control), tu_u32_high16(*epx.buffer_control)); + panic("Data Seq Error \n"); + } + + if (status ^ handled) + { + panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled)); + } +} + +static struct hw_endpoint *_next_free_interrupt_ep(void) +{ + struct hw_endpoint *ep = NULL; + for (uint i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) + { + ep = &ep_pool[i]; + if (!ep->configured) + { + // Will be configured by _hw_endpoint_init / _hw_endpoint_allocate + ep->interrupt_num = i - 1; + return ep; + } + } + return ep; +} + +static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) +{ + struct hw_endpoint *ep = NULL; + + if (transfer_type == TUSB_XFER_INTERRUPT) + { + ep = _next_free_interrupt_ep(); + pico_info("Allocate interrupt ep %d\n", ep->interrupt_num); + assert(ep); + ep->buffer_control = &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; + ep->endpoint_control = &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; + // 0 for epx (double buffered): TODO increase to 1024 for ISO + // 2x64 for intep0 + // 3x64 for intep1 + // etc + ep->hw_data_buf = &usbh_dpram->epx_data[64 * (ep->interrupt_num + 2)]; + } + else + { + ep = &epx; + ep->buffer_control = &usbh_dpram->epx_buf_ctrl; + ep->endpoint_control = &usbh_dpram->epx_ctrl; + ep->hw_data_buf = &usbh_dpram->epx_data[0]; + } + + return ep; +} + +static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval) +{ + // Already has data buffer, endpoint control, and buffer control allocated at this point + assert(ep->endpoint_control); + assert(ep->buffer_control); + assert(ep->hw_data_buf); + + uint8_t const num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); + + ep->ep_addr = ep_addr; + ep->dev_addr = dev_addr; + + // For host, IN to host == RX, anything else rx == false + ep->rx = (dir == TUSB_DIR_IN); + + // Response to a setup packet on EP0 starts with pid of 1 + ep->next_pid = (num == 0 ? 1u : 0u); + ep->wMaxPacketSize = wMaxPacketSize; + ep->transfer_type = transfer_type; + + pico_trace("hw_endpoint_init dev %d ep %d %s xfer %d\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->transfer_type); + pico_trace("dev %d ep %d %s setup buffer @ 0x%p\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->hw_data_buf); + uint dpram_offset = hw_data_offset(ep->hw_data_buf); + // Bits 0-5 should be 0 + assert(!(dpram_offset & 0b111111)); + + // Fill in endpoint control register with buffer offset + uint32_t ep_reg = EP_CTRL_ENABLE_BITS + | EP_CTRL_INTERRUPT_PER_BUFFER + | (ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) + | dpram_offset; + ep_reg |= bmInterval ? (bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB : 0; + *ep->endpoint_control = ep_reg; + pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); + ep->configured = true; + + if (bmInterval) + { + // This is an interrupt endpoint + // so need to set up interrupt endpoint address control register with: + // device address + // endpoint number / direction + // preamble + uint32_t reg = dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB); + + if (dir == TUSB_DIR_OUT) + { + reg |= USB_ADDR_ENDP1_INTEP_DIR_BITS; + } + + if (need_pre(dev_addr)) + { + reg |= USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS; + } + usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = reg; + + // Finally, enable interrupt that endpoint + usb_hw_set->int_ep_ctrl = 1 << (ep->interrupt_num + 1); + + // If it's an interrupt endpoint we need to set up the buffer control + // register + } +} + +//--------------------------------------------------------------------+ +// HCD API +//--------------------------------------------------------------------+ +bool hcd_init(uint8_t rhport) +{ + pico_trace("hcd_init %d\n", rhport); + assert(rhport == 0); + + // Reset any previous state + rp2040_usb_init(); + + // Force VBUS detect to always present, for now we assume vbus is always provided (without using VBUS En) + usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; + + irq_set_exclusive_handler(USBCTRL_IRQ, hcd_rp2040_irq); + + // clear epx and interrupt eps + memset(&ep_pool, 0, sizeof(ep_pool)); + + // Enable in host mode with SOF / Keep alive on + usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS; + usb_hw->sie_ctrl = SIE_CTRL_BASE; + usb_hw->inte = USB_INTE_BUFF_STATUS_BITS | + USB_INTE_HOST_CONN_DIS_BITS | + USB_INTE_HOST_RESUME_BITS | + USB_INTE_STALL_BITS | + USB_INTE_TRANS_COMPLETE_BITS | + USB_INTE_ERROR_RX_TIMEOUT_BITS | + USB_INTE_ERROR_DATA_SEQ_BITS ; + + return true; +} + +void hcd_port_reset(uint8_t rhport) +{ + pico_trace("hcd_port_reset\n"); + assert(rhport == 0); + // TODO: Nothing to do here yet. Perhaps need to reset some state? +} + +bool hcd_port_connect_status(uint8_t rhport) +{ + pico_trace("hcd_port_connect_status\n"); + assert(rhport == 0); + return usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + assert(rhport == 0); + // TODO: Should enumval this register + switch (dev_speed()) + { + case 1: + return TUSB_SPEED_LOW; + case 2: + return TUSB_SPEED_FULL; + default: + panic("Invalid speed\n"); + return TUSB_SPEED_INVALID; + } +} + +// Close all opened endpoint belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + pico_trace("hcd_device_close %d\n", dev_addr); + (void) rhport; + + if (dev_addr == 0) return; + + for (size_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) + { + hw_endpoint_t* ep = &ep_pool[i]; + + if (ep->dev_addr == dev_addr && ep->configured) + { + // in case it is an interrupt endpoint, disable it + usb_hw_clear->int_ep_ctrl = (1 << (ep->interrupt_num + 1)); + usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = 0; + + // unconfigure the endpoint + ep->configured = false; + *ep->endpoint_control = 0; + *ep->buffer_control = 0; + hw_endpoint_reset_transfer(ep); + } + } +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void) rhport; + return usb_hw->sof_rd; +} + +void hcd_int_enable(uint8_t rhport) +{ + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, true); +} + +void hcd_int_disable(uint8_t rhport) +{ + // todo we should check this is disabling from the correct core; note currently this is never called + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, false); +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + pico_trace("hcd_edpt_open dev_addr %d, ep_addr %d\n", dev_addr, ep_desc->bEndpointAddress); + + // Allocated differently based on if it's an interrupt endpoint or not + struct hw_endpoint *ep = _hw_endpoint_allocate(ep_desc->bmAttributes.xfer); + + _hw_endpoint_init(ep, + dev_addr, + ep_desc->bEndpointAddress, + tu_edpt_packet_size(ep_desc), + ep_desc->bmAttributes.xfer, + ep_desc->bInterval); + + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) +{ + (void) rhport; + + pico_trace("hcd_edpt_xfer dev_addr %d, ep_addr 0x%x, len %d\n", dev_addr, ep_addr, buflen); + + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const ep_dir = tu_edpt_dir(ep_addr); + + // Get appropriate ep. Either EPX or interrupt endpoint + struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); + assert(ep); + + // Control endpoint can change direction 0x00 <-> 0x80 + if ( ep_addr != ep->ep_addr ) + { + assert(ep_num == 0); + + // Direction has flipped on endpoint control so re init it but with same properties + _hw_endpoint_init(ep, dev_addr, ep_addr, ep->wMaxPacketSize, ep->transfer_type, 0); + } + + // If a normal transfer (non-interrupt) then initiate using + // sie ctrl registers. Otherwise interrupt ep registers should + // already be configured + if (ep == &epx) { + hw_endpoint_xfer_start(ep, buffer, buflen); + + // That has set up buffer control, endpoint control etc + // for host we have to initiate the transfer + usb_hw->dev_addr_ctrl = dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB); + + uint32_t flags = USB_SIE_CTRL_START_TRANS_BITS | SIE_CTRL_BASE | + (ep_dir ? USB_SIE_CTRL_RECEIVE_DATA_BITS : USB_SIE_CTRL_SEND_DATA_BITS); + // Set pre if we are a low speed device on full speed hub + flags |= need_pre(dev_addr) ? USB_SIE_CTRL_PREAMBLE_EN_BITS : 0; + + usb_hw->sie_ctrl = flags; + }else + { + hw_endpoint_xfer_start(ep, buffer, buflen); + } + + return true; +} + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void) rhport; + + // Copy data into setup packet buffer + memcpy((void*)&usbh_dpram->setup_packet[0], setup_packet, 8); + + // Configure EP0 struct with setup info for the trans complete + struct hw_endpoint *ep = _hw_endpoint_allocate(0); + + // EP0 out + _hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); + assert(ep->configured); + + ep->remaining_len = 8; + ep->active = true; + + // Set device address + usb_hw->dev_addr_ctrl = dev_addr; + + // Set pre if we are a low speed device on full speed hub + uint32_t const flags = SIE_CTRL_BASE | USB_SIE_CTRL_SEND_SETUP_BITS | USB_SIE_CTRL_START_TRANS_BITS | + (need_pre(dev_addr) ? USB_SIE_CTRL_PREAMBLE_EN_BITS : 0); + + usb_hw->sie_ctrl = flags; + + return true; +} + + +//bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) +//{ +// // EPX is shared, so multiple device addresses and endpoint addresses share that +// // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own +// // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint +// // on that device +// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr); +// struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); +// assert(ep); +// bool busy = ep->active; +// pico_trace("busy == %d\n", busy); +// return busy; +//} + +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + (void) dev_addr; + (void) ep_addr; + + panic("hcd_clear_stall"); + return true; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c b/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c new file mode 100644 index 0000000..9c3e5d0 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -0,0 +1,327 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * Copyright (c) 2021 Ha Thach (tinyusb.org) for Double Buffered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 + +#include +#include "rp2040_usb.h" + +// Direction strings for debug +const char *ep_dir_string[] = { + "out", + "in", +}; + +static inline void _hw_endpoint_lock_update(__unused struct hw_endpoint * ep, __unused int delta) { + // todo add critsec as necessary to prevent issues between worker and IRQ... + // note that this is perhaps as simple as disabling IRQs because it would make + // sense to have worker and IRQ on same core, however I think using critsec is about equivalent. +} + +static void _hw_endpoint_xfer_sync(struct hw_endpoint *ep); +static void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep); + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +void rp2040_usb_init(void) +{ + // Reset usb controller + reset_block(RESETS_RESET_USBCTRL_BITS); + unreset_block_wait(RESETS_RESET_USBCTRL_BITS); + + // Clear any previous state just in case + // TODO Suppress warning array-bounds with gcc11 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" + memset(usb_hw, 0, sizeof(*usb_hw)); + memset(usb_dpram, 0, sizeof(*usb_dpram)); +#pragma GCC diagnostic pop + + // Mux the controller to the onboard usb phy + usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS; +} + +void hw_endpoint_reset_transfer(struct hw_endpoint *ep) +{ + ep->active = false; + ep->remaining_len = 0; + ep->xferred_len = 0; + ep->user_buf = 0; +} + +void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { + uint32_t value = 0; + if (and_mask) { + value = *ep->buffer_control & and_mask; + } + if (or_mask) { + value |= or_mask; + if (or_mask & USB_BUF_CTRL_AVAIL) { + if (*ep->buffer_control & USB_BUF_CTRL_AVAIL) { + panic("ep %d %s was already available", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + } + *ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL; + // 12 cycle delay.. (should be good for 48*12Mhz = 576Mhz) + // Don't need delay in host mode as host is in charge +#if !CFG_TUH_ENABLED + __asm volatile ( + "b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1:\n" + : : : "memory"); +#endif + } + } + *ep->buffer_control = value; +} + +// prepare buffer, return buffer control +static uint32_t prepare_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) +{ + uint16_t const buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize); + ep->remaining_len = (uint16_t)(ep->remaining_len - buflen); + + uint32_t buf_ctrl = buflen | USB_BUF_CTRL_AVAIL; + + // PID + buf_ctrl |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID; + ep->next_pid ^= 1u; + + if ( !ep->rx ) + { + // Copy data from user buffer to hw buffer + memcpy(ep->hw_data_buf + buf_id*64, ep->user_buf, buflen); + ep->user_buf += buflen; + + // Mark as full + buf_ctrl |= USB_BUF_CTRL_FULL; + } + + // Is this the last buffer? Only really matters for host mode. Will trigger + // the trans complete irq but also stop it polling. We only really care about + // trans complete for setup packets being sent + if (ep->remaining_len == 0) + { + buf_ctrl |= USB_BUF_CTRL_LAST; + } + + if (buf_id) buf_ctrl = buf_ctrl << 16; + + return buf_ctrl; +} + +// Prepare buffer control register value +static void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep) +{ + uint32_t ep_ctrl = *ep->endpoint_control; + + // always compute and start with buffer 0 + uint32_t buf_ctrl = prepare_ep_buffer(ep, 0) | USB_BUF_CTRL_SEL; + + // For now: skip double buffered for Device mode, OUT endpoint since + // host could send < 64 bytes and cause short packet on buffer0 + // NOTE this could happen to Host mode IN endpoint + bool const force_single = !(usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) && !tu_edpt_dir(ep->ep_addr); + + if(ep->remaining_len && !force_single) + { + // Use buffer 1 (double buffered) if there is still data + // TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt) + + buf_ctrl |= prepare_ep_buffer(ep, 1); + + // Set endpoint control double buffered bit if needed + ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER; + ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER; + }else + { + // Single buffered since 1 is enough + ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); + ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; + } + + *ep->endpoint_control = ep_ctrl; + + TU_LOG(3, " Prepare BufCtrl: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); + + // Finally, write to buffer_control which will trigger the transfer + // the next time the controller polls this dpram address + _hw_endpoint_buffer_control_set_value32(ep, buf_ctrl); +} + +void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len) +{ + _hw_endpoint_lock_update(ep, 1); + + if ( ep->active ) + { + // TODO: Is this acceptable for interrupt packets? + TU_LOG(1, "WARN: starting new transfer on already active ep %d %s\n", tu_edpt_number(ep->ep_addr), + ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + + hw_endpoint_reset_transfer(ep); + } + + // Fill in info now that we're kicking off the hw + ep->remaining_len = total_len; + ep->xferred_len = 0; + ep->active = true; + ep->user_buf = buffer; + + _hw_endpoint_start_next_buffer(ep); + _hw_endpoint_lock_update(ep, -1); +} + +// sync endpoint buffer and return transferred bytes +static uint16_t sync_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) +{ + uint32_t buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); + if (buf_id) buf_ctrl = buf_ctrl >> 16; + + uint16_t xferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK; + + if ( !ep->rx ) + { + // We are continuing a transfer here. If we are TX, we have successfully + // sent some data can increase the length we have sent + assert(!(buf_ctrl & USB_BUF_CTRL_FULL)); + + ep->xferred_len = (uint16_t)(ep->xferred_len + xferred_bytes); + }else + { + // If we have received some data, so can increase the length + // we have received AFTER we have copied it to the user buffer at the appropriate offset + assert(buf_ctrl & USB_BUF_CTRL_FULL); + + memcpy(ep->user_buf, ep->hw_data_buf + buf_id*64, xferred_bytes); + ep->xferred_len = (uint16_t)(ep->xferred_len + xferred_bytes); + ep->user_buf += xferred_bytes; + } + + // Short packet + if (xferred_bytes < ep->wMaxPacketSize) + { + pico_trace(" Short packet on buffer %d with %u bytes\n", buf_id, xferred_bytes); + // Reduce total length as this is last packet + ep->remaining_len = 0; + } + + return xferred_bytes; +} + +static void _hw_endpoint_xfer_sync (struct hw_endpoint *ep) +{ + // Update hw endpoint struct with info from hardware + // after a buff status interrupt + + uint32_t __unused buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); + TU_LOG(3, " Sync BufCtrl: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); + + // always sync buffer 0 + uint16_t buf0_bytes = sync_ep_buffer(ep, 0); + + // sync buffer 1 if double buffered + if ( (*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS ) + { + if (buf0_bytes == ep->wMaxPacketSize) + { + // sync buffer 1 if not short packet + sync_ep_buffer(ep, 1); + }else + { + // short packet on buffer 0 + // TODO couldn't figure out how to handle this case which happen with net_lwip_webserver example + // At this time (currently trigger per 2 buffer), the buffer1 is probably filled with data from + // the next transfer (not current one). For now we disable double buffered for device OUT + // NOTE this could happen to Host IN +#if 0 + uint8_t const ep_num = tu_edpt_number(ep->ep_addr); + uint8_t const dir = (uint8_t) tu_edpt_dir(ep->ep_addr); + uint8_t const ep_id = 2*ep_num + (dir ? 0 : 1); + + // abort queued transfer on buffer 1 + usb_hw->abort |= TU_BIT(ep_id); + + while ( !(usb_hw->abort_done & TU_BIT(ep_id)) ) {} + + uint32_t ep_ctrl = *ep->endpoint_control; + ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); + ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; + + _hw_endpoint_buffer_control_set_value32(ep, 0); + + usb_hw->abort &= ~TU_BIT(ep_id); + + TU_LOG(3, "----SHORT PACKET buffer0 on EP %02X:\r\n", ep->ep_addr); + TU_LOG(3, " BufCtrl: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); +#endif + } + } +} + +// Returns true if transfer is complete +bool hw_endpoint_xfer_continue(struct hw_endpoint *ep) +{ + _hw_endpoint_lock_update(ep, 1); + // Part way through a transfer + if (!ep->active) + { + panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + } + + // Update EP struct from hardware state + _hw_endpoint_xfer_sync(ep); + + // Now we have synced our state with the hardware. Is there more data to transfer? + // If we are done then notify tinyusb + if (ep->remaining_len == 0) + { + pico_trace("Completed transfer of %d bytes on ep %d %s\n", + ep->xferred_len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + // Notify caller we are done so it can notify the tinyusb stack + _hw_endpoint_lock_update(ep, -1); + return true; + } + else + { + _hw_endpoint_start_next_buffer(ep); + } + + _hw_endpoint_lock_update(ep, -1); + // More work to do + return false; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.h b/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.h new file mode 100644 index 0000000..da1933d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -0,0 +1,96 @@ +#ifndef RP2040_COMMON_H_ +#define RP2040_COMMON_H_ + +#if defined(RP2040_USB_HOST_MODE) && defined(RP2040_USB_DEVICE_MODE) +#error TinyUSB device and host mode not supported at the same time +#endif + +#include "common/tusb_common.h" + +#include "pico.h" +#include "hardware/structs/usb.h" +#include "hardware/irq.h" +#include "hardware/resets.h" + +#if defined(PICO_RP2040_USB_DEVICE_ENUMERATION_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX) +#define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX PICO_RP2040_USB_DEVICE_ENUMERATION_FIX +#endif + + +#define pico_info(...) TU_LOG(2, __VA_ARGS__) +#define pico_trace(...) TU_LOG(3, __VA_ARGS__) + +// Hardware information per endpoint +typedef struct hw_endpoint +{ + // Is this a valid struct + bool configured; + + // Transfer direction (i.e. IN is rx for host but tx for device) + // allows us to common up transfer functions + bool rx; + + uint8_t ep_addr; + uint8_t next_pid; + + // Endpoint control register + io_rw_32 *endpoint_control; + + // Buffer control register + io_rw_32 *buffer_control; + + // Buffer pointer in usb dpram + uint8_t *hw_data_buf; + + // Current transfer information + bool active; + uint16_t remaining_len; + uint16_t xferred_len; + + // User buffer in main memory + uint8_t *user_buf; + + // Data needed from EP descriptor + uint16_t wMaxPacketSize; + + // Interrupt, bulk, etc + uint8_t transfer_type; + +#if CFG_TUH_ENABLED + // Only needed for host + uint8_t dev_addr; + + // If interrupt endpoint + uint8_t interrupt_num; +#endif +} hw_endpoint_t; + +void rp2040_usb_init(void); + +void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len); +bool hw_endpoint_xfer_continue(struct hw_endpoint *ep); +void hw_endpoint_reset_transfer(struct hw_endpoint *ep); + +void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask); +static inline uint32_t _hw_endpoint_buffer_control_get_value32(struct hw_endpoint *ep) { + return *ep->buffer_control; +} +static inline void _hw_endpoint_buffer_control_set_value32(struct hw_endpoint *ep, uint32_t value) { + return _hw_endpoint_buffer_control_update32(ep, 0, value); +} +static inline void _hw_endpoint_buffer_control_set_mask32(struct hw_endpoint *ep, uint32_t value) { + return _hw_endpoint_buffer_control_update32(ep, ~value, value); +} +static inline void _hw_endpoint_buffer_control_clear_mask32(struct hw_endpoint *ep, uint32_t value) { + return _hw_endpoint_buffer_control_update32(ep, ~value, 0); +} + +static inline uintptr_t hw_data_offset(uint8_t *buf) +{ + // Remove usb base from buffer pointer + return (uintptr_t)buf ^ (uintptr_t)usb_dpram; +} + +extern const char *ep_dir_string[]; + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/renesas/usba/dcd_usba.c b/circuitpython/lib/tinyusb/src/portable/renesas/usba/dcd_usba.c new file mode 100644 index 0000000..330f653 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/renesas/usba/dcd_usba.c @@ -0,0 +1,907 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Koji Kitayama + * Portions copyrighted (c) 2021 Roland Winistoerfer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#define USE_SOF 0 + +#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \ + CFG_TUSB_MCU == OPT_MCU_RX65X || \ + CFG_TUSB_MCU == OPT_MCU_RX72N ) +#include "device/dcd.h" +#include "iodefine.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ +#define SYSTEM_PRCR_PRC1 (1<<1) +#define SYSTEM_PRCR_PRKEY (0xA5u<<8) + +#define USB_FIFOSEL_TX ((uint16_t)(1u<<5)) +#define USB_FIFOSEL_BIGEND ((uint16_t)(1u<<8)) +#define USB_FIFOSEL_MBW_8 ((uint16_t)(0u<<10)) +#define USB_FIFOSEL_MBW_16 ((uint16_t)(1u<<10)) +#define USB_IS0_CTSQ ((uint16_t)(7u)) +#define USB_IS0_DVSQ ((uint16_t)(7u<<4)) +#define USB_IS0_VALID ((uint16_t)(1u<<3)) +#define USB_IS0_BRDY ((uint16_t)(1u<<8)) +#define USB_IS0_NRDY ((uint16_t)(1u<<9)) +#define USB_IS0_BEMP ((uint16_t)(1u<<10)) +#define USB_IS0_CTRT ((uint16_t)(1u<<11)) +#define USB_IS0_DVST ((uint16_t)(1u<<12)) +#define USB_IS0_SOFR ((uint16_t)(1u<<13)) +#define USB_IS0_RESM ((uint16_t)(1u<<14)) +#define USB_IS0_VBINT ((uint16_t)(1u<<15)) +#define USB_IS1_SACK ((uint16_t)(1u<<4)) +#define USB_IS1_SIGN ((uint16_t)(1u<<5)) +#define USB_IS1_EOFERR ((uint16_t)(1u<<6)) +#define USB_IS1_ATTCH ((uint16_t)(1u<<11)) +#define USB_IS1_DTCH ((uint16_t)(1u<<12)) +#define USB_IS1_BCHG ((uint16_t)(1u<<14)) +#define USB_IS1_OVRCR ((uint16_t)(1u<<15)) + +#define USB_IS0_CTSQ_MSK (7u) +#define USB_IS0_CTSQ_SETUP (1u) +#define USB_IS0_DVSQ_DEF (1u<<4) +#define USB_IS0_DVSQ_ADDR (2u<<4) +#define USB_IS0_DVSQ_SUSP0 (4u<<4) +#define USB_IS0_DVSQ_SUSP1 (5u<<4) +#define USB_IS0_DVSQ_SUSP2 (6u<<4) +#define USB_IS0_DVSQ_SUSP3 (7u<<4) + +#define USB_PIPECTR_PID_NAK (0u) +#define USB_PIPECTR_PID_BUF (1u) +#define USB_PIPECTR_PID_STALL (2u) +#define USB_PIPECTR_CCPL (1u<<2) +#define USB_PIPECTR_SQMON (1u<<6) +#define USB_PIPECTR_SQCLR (1u<<8) +#define USB_PIPECTR_ACLRM (1u<<9) +#define USB_PIPECTR_INBUFM (1u<<14) +#define USB_PIPECTR_BSTS (1u<<15) + +#define USB_FIFOCTR_DTLN (0x1FF) +#define USB_FIFOCTR_FRDY (1u<<13) +#define USB_FIFOCTR_BCLR (1u<<14) +#define USB_FIFOCTR_BVAL (1u<<15) + +#define USB_PIPECFG_SHTNAK (1u<<7) +#define USB_PIPECFG_DBLB (1u<<9) +#define USB_PIPECFG_BULK (1u<<14) +#define USB_PIPECFG_ISO (3u<<14) +#define USB_PIPECFG_INT (2u<<14) + +#define FIFO_REQ_CLR (1u) +#define FIFO_COMPLETE (1u<<1) + +// Start of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN + +typedef struct { + union { + struct { + uint16_t : 8; + uint16_t TRCLR: 1; + uint16_t TRENB: 1; + uint16_t : 0; + }; + uint16_t TRE; + }; + uint16_t TRN; +} reg_pipetre_t; + +typedef union { + struct { + volatile uint16_t u8: 8; + volatile uint16_t : 0; + }; + volatile uint16_t u16; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ + struct { + uint32_t ep : 8; /* an assigned endpoint address */ + uint32_t ff : 1; /* `buf` is TU_FUFO or POD */ + uint32_t : 0; + }; +} pipe_state_t; + +TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_BIT_FIELD_ORDER_END + +typedef struct +{ + pipe_state_t pipe[10]; + uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ +} dcd_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static dcd_data_t _dcd; + +static uint32_t disable_interrupt(void) +{ + uint32_t pswi; +#if defined(__CCRX__) + pswi = get_psw() & 0x010000; + clrpsw_i(); +#else + pswi = __builtin_rx_mvfc(0) & 0x010000; + __builtin_rx_clrpsw('I'); +#endif + return pswi; +} + +static void enable_interrupt(uint32_t pswi) +{ +#if defined(__CCRX__) + set_psw(get_psw() | pswi); +#else + __builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi); +#endif +} + +static unsigned find_pipe(unsigned xfer) +{ + switch (xfer) { + case TUSB_XFER_ISOCHRONOUS: + for (int i = 1; i <= 2; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + break; + case TUSB_XFER_BULK: + for (int i = 3; i <= 5; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + for (int i = 1; i <= 1; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + break; + case TUSB_XFER_INTERRUPT: + for (int i = 6; i <= 9; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + break; + default: + /* No support for control transfer */ + break; + } + return 0; +} + +static volatile uint16_t* get_pipectr(unsigned num) +{ + volatile uint16_t *ctr = NULL; + if (num) { + ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD; + ctr += num - 1; + } else { + ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD; + } + return ctr; +} + +static volatile reg_pipetre_t* get_pipetre(unsigned num) +{ + volatile reg_pipetre_t* tre = NULL; + if ((1 <= num) && (num <= 5)) { + tre = (volatile reg_pipetre_t*)&USB0.PIPE1TRE.WORD; + tre += num - 1; + } + return tre; +} + +static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) +{ + (void)rhport; + volatile uint16_t *ctr = NULL; + const unsigned epn = tu_edpt_number(ep_addr); + if (epn) { + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned num = _dcd.ep[dir][epn]; + if (num) { + ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD; + ctr += num - 1; + } + } else { + ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD; + } + return ctr; +} + +static unsigned edpt0_max_packet_size(void) +{ + return USB0.DCPMAXP.BIT.MXPS; +} + +static unsigned edpt_max_packet_size(unsigned num) +{ + USB0.PIPESEL.WORD = num; + return USB0.PIPEMAXP.WORD; +} + +static inline void pipe_wait_for_ready(unsigned num) +{ + while (USB0.D0FIFOSEL.BIT.CURPIPE != num) ; + while (!USB0.D0FIFOCTR.BIT.FRDY) ; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*) fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 2) { + reg->u16 = *(const uint16_t *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(const uint8_t *)addr; + ++addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + uint8_t *p = (uint8_t*)buf; + volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */ + while (len--) *p++ = *reg; +} + +static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) +{ + static const struct { + void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); + void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); + void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); + } ops[] = { + /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, + /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, + }; + tu_fifo_buffer_info_t info; + ops[dir].tu_fifo_get_info(f, &info); + unsigned total_len = len; + len = TU_MIN(total_len, info.len_lin); + ops[dir].pipe_read_write(info.ptr_lin, fifo, len); + unsigned rem = total_len - len; + if (rem) { + len = TU_MIN(rem, info.len_wrap); + ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); + rem -= len; + } + ops[dir].tu_fifo_advance(f, total_len - rem); +} + +static bool pipe0_xfer_in(void) +{ + pipe_state_t *pipe = &_dcd.pipe[0]; + const unsigned rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + const unsigned mps = edpt0_max_packet_size(); + const unsigned len = TU_MIN(mps, rem); + void *buf = pipe->buf; + if (len) { + if (pipe->ff) { + pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&USB0.CFIFO.WORD, len, TUSB_DIR_IN); + } else { + pipe_write_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + } + if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL; + pipe->remaining = rem - len; + return false; +} + +static bool pipe0_xfer_out(void) +{ + pipe_state_t *pipe = &_dcd.pipe[0]; + const unsigned rem = pipe->remaining; + + const unsigned mps = edpt0_max_packet_size(); + const unsigned vld = USB0.CFIFOCTR.BIT.DTLN; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + if (pipe->ff) { + pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&USB0.CFIFO.WORD, len, TUSB_DIR_OUT); + } else { + pipe_read_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + } + if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR; + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return true; + } + return false; +} + +static bool pipe_xfer_in(unsigned num) +{ + pipe_state_t *pipe = &_dcd.pipe[num]; + const unsigned rem = pipe->remaining; + + if (!rem) { + pipe->buf = NULL; + return true; + } + + USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0); + const unsigned mps = edpt_max_packet_size(num); + pipe_wait_for_ready(num); + const unsigned len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + if (pipe->ff) { + pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&USB0.D0FIFO.WORD, len, TUSB_DIR_IN); + } else { + pipe_write_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + } + if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; + return false; +} + +static bool pipe_xfer_out(unsigned num) +{ + pipe_state_t *pipe = &_dcd.pipe[num]; + const unsigned rem = pipe->remaining; + + USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_8; + const unsigned mps = edpt_max_packet_size(num); + pipe_wait_for_ready(num); + const unsigned vld = USB0.D0FIFOCTR.BIT.DTLN; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + if (pipe->ff) { + pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&USB0.D0FIFO.WORD, len, TUSB_DIR_OUT); + } else { + pipe_read_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + } + if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BCLR; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + return false; +} + +static void process_setup_packet(uint8_t rhport) +{ + uint16_t setup_packet[4]; + if (0 == (USB0.INTSTS0.WORD & USB_IS0_VALID)) return; + USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR; + setup_packet[0] = tu_le16toh(USB0.USBREQ.WORD); + setup_packet[1] = USB0.USBVAL; + setup_packet[2] = USB0.USBINDX; + setup_packet[3] = USB0.USBLENG; + USB0.INTSTS0.WORD = ~USB_IS0_VALID; + dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet[0], true); +} + +static void process_status_completion(uint8_t rhport) +{ + uint8_t ep_addr; + /* Check the data stage direction */ + if (USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX) { + /* IN transfer. */ + ep_addr = tu_edpt_addr(0, TUSB_DIR_IN); + } else { + /* OUT transfer. */ + ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT); + } + dcd_event_xfer_complete(rhport, ep_addr, 0, XFER_RESULT_SUCCESS, true); +} + +static bool process_pipe0_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +{ + /* configure fifo direction and access unit settings */ + if (ep_addr) { /* IN, 2 bytes */ + USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0); + while (!(USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX)) ; + } else { /* OUT, a byte */ + USB0.CFIFOSEL.WORD = USB_FIFOSEL_MBW_8; + while (USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX) ; + } + + pipe_state_t *pipe = &_dcd.pipe[0]; + pipe->ff = buffer_type; + pipe->length = total_bytes; + pipe->remaining = total_bytes; + if (total_bytes) { + pipe->buf = buffer; + if (ep_addr) { /* IN */ + TU_ASSERT(USB0.DCPCTR.BIT.BSTS && (USB0.USBREQ.WORD & 0x80)); + pipe0_xfer_in(); + } + USB0.DCPCTR.WORD = USB_PIPECTR_PID_BUF; + } else { + /* ZLP */ + pipe->buf = NULL; + USB0.DCPCTR.WORD = USB_PIPECTR_CCPL | USB_PIPECTR_PID_BUF; + } + return true; +} + +static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +{ + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned num = _dcd.ep[dir][epn]; + + TU_ASSERT(num); + + pipe_state_t *pipe = &_dcd.pipe[num]; + pipe->ff = buffer_type; + pipe->buf = buffer; + pipe->length = total_bytes; + pipe->remaining = total_bytes; + if (dir) { /* IN */ + if (total_bytes) { + pipe_xfer_in(num); + } else { /* ZLP */ + USB0.D0FIFOSEL.WORD = num; + pipe_wait_for_ready(num); + USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + } + } else { +#if defined(__CCRX__) + __evenaccess volatile reg_pipetre_t *pt = get_pipetre(num); +#else + volatile reg_pipetre_t *pt = get_pipetre(num); +#endif + if (pt) { + const unsigned mps = edpt_max_packet_size(num); + volatile uint16_t *ctr = get_pipectr(num); + if (*ctr & 0x3) *ctr = USB_PIPECTR_PID_NAK; + pt->TRE = TU_BIT(8); + pt->TRN = (total_bytes + mps - 1) / mps; + pt->TRENB = 1; + *ctr = USB_PIPECTR_PID_BUF; + } + } + // TU_LOG1("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type); + return true; +} + +static bool process_edpt_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +{ + const unsigned epn = tu_edpt_number(ep_addr); + if (0 == epn) { + return process_pipe0_xfer(buffer_type, ep_addr, buffer, total_bytes); + } else { + return process_pipe_xfer(buffer_type, ep_addr, buffer, total_bytes); + } +} + +static void process_pipe0_bemp(uint8_t rhport) +{ + bool completed = pipe0_xfer_in(); + if (completed) { + pipe_state_t *pipe = &_dcd.pipe[0]; + dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN), + pipe->length, XFER_RESULT_SUCCESS, true); + } +} + +static void process_pipe_brdy(uint8_t rhport, unsigned num) +{ + pipe_state_t *pipe = &_dcd.pipe[num]; + const unsigned dir = tu_edpt_dir(pipe->ep); + bool completed; + + if (dir) { /* IN */ + completed = pipe_xfer_in(num); + } else { + if (num) { + completed = pipe_xfer_out(num); + } else { + completed = pipe0_xfer_out(); + } + } + if (completed) { + dcd_event_xfer_complete(rhport, pipe->ep, + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + // TU_LOG1("C %d %d\r\n", num, pipe->length - pipe->remaining); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + USB0.BEMPENB.WORD = 1; + USB0.BRDYENB.WORD = 1; + USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + USB0.D1FIFOSEL.WORD = 0; + while (USB0.D1FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t)(&USB0.PIPE1CTR.WORD)); + volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t)(&USB0.PIPE1TRE.WORD)); + for (int i = 1; i <= 5; ++i) { + USB0.PIPESEL.WORD = i; + USB0.PIPECFG.WORD = 0; + *ctr = USB_PIPECTR_ACLRM; + *ctr = 0; + ++ctr; + *tre = TU_BIT(8); + tre += 2; + } + for (int i = 6; i <= 9; ++i) { + USB0.PIPESEL.WORD = i; + USB0.PIPECFG.WORD = 0; + *ctr = USB_PIPECTR_ACLRM; + *ctr = 0; + ++ctr; + } + tu_varclr(&_dcd); + dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); +} + +static void process_set_address(uint8_t rhport) +{ + const uint32_t addr = USB0.USBADDR.BIT.USBADDR; + if (!addr) return; + const tusb_control_request_t setup_packet = { +#if defined(__CCRX__) + .bmRequestType = { 0 }, /* Note: CCRX needs the braces over this struct member */ +#else + .bmRequestType = 0, +#endif + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = addr, + .wIndex = 0, + .wLength = 0, + }; + dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet, true); +} + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + (void)rhport; + /* Enable USB0 */ + uint32_t pswi = disable_interrupt(); + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; + MSTP(USB0) = 0; + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; + enable_interrupt(pswi); + USB0.SYSCFG.BIT.SCKE = 1; + while (!USB0.SYSCFG.BIT.SCKE) ; + USB0.SYSCFG.BIT.DRPD = 0; + USB0.SYSCFG.BIT.DCFM = 0; + USB0.SYSCFG.BIT.USBE = 1; + + USB.DPUSR0R.BIT.FIXPHY0 = 0u; /* USB0 Transceiver Output fixed */ +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + USB0.PHYSLEW.LONG = 0x5; + IR(PERIB, INTB185) = 0; +#else + IR(USB0, USBI0) = 0; +#endif + + /* Setup default control pipe */ + USB0.DCPMAXP.BIT.MXPS = 64; + USB0.INTENB0.WORD = USB_IS0_VBINT | USB_IS0_BRDY | USB_IS0_BEMP | + USB_IS0_DVST | USB_IS0_CTRT | (USE_SOF ? USB_IS0_SOFR: 0) | USB_IS0_RESM; + USB0.BEMPENB.WORD = 1; + USB0.BRDYENB.WORD = 1; + + if (USB0.INTSTS0.BIT.VBSTS) { + dcd_connect(rhport); + } +} + +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + IEN(PERIB, INTB185) = 1; +#else + IEN(USB0, USBI0) = 1; +#endif +} + +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + IEN(PERIB, INTB185) = 0; +#else + IEN(USB0, USBI0) = 0; +#endif +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + (void)dev_addr; +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + USB0.DVSTCTR0.BIT.WKUP = 1; +} + +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + USB0.SYSCFG.BIT.DPRPU = 1; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + USB0.SYSCFG.BIT.DPRPU = 0; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void)rhport; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + + const unsigned mps = tu_edpt_packet_size(ep_desc); + if (xfer == TUSB_XFER_ISOCHRONOUS && mps > 256) { + /* USBa supports up to 256 bytes */ + return false; + } + + const unsigned num = find_pipe(xfer); + if (!num) return false; + _dcd.pipe[num].ep = ep_addr; + _dcd.ep[dir][epn] = num; + + /* setup pipe */ + dcd_int_disable(rhport); + USB0.PIPESEL.WORD = num; + USB0.PIPEMAXP.WORD = mps; + volatile uint16_t *ctr = get_pipectr(num); + *ctr = USB_PIPECTR_ACLRM | USB_PIPECTR_SQCLR; + *ctr = 0; + unsigned cfg = (dir << 4) | epn; + if (xfer == TUSB_XFER_BULK) { + cfg |= (USB_PIPECFG_BULK | USB_PIPECFG_SHTNAK | USB_PIPECFG_DBLB); + } else if (xfer == TUSB_XFER_INTERRUPT) { + cfg |= USB_PIPECFG_INT; + } else { + cfg |= (USB_PIPECFG_ISO | USB_PIPECFG_DBLB); + } + USB0.PIPECFG.WORD = cfg; + USB0.BRDYSTS.WORD = 0x1FFu ^ TU_BIT(num); + USB0.BRDYENB.WORD |= TU_BIT(num); + if (dir || (xfer != TUSB_XFER_BULK)) { + *ctr = USB_PIPECTR_PID_BUF; + } + // TU_LOG1("O %d %x %x\r\n", USB0.PIPESEL.WORD, USB0.PIPECFG.WORD, USB0.PIPEMAXP.WORD); + dcd_int_enable(rhport); + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + unsigned i = TU_ARRAY_SIZE(_dcd.pipe); + dcd_int_disable(rhport); + while (--i) { /* Close all pipes except 0 */ + const unsigned ep_addr = _dcd.pipe[i].ep; + if (!ep_addr) continue; + dcd_edpt_close(rhport, ep_addr); + } + dcd_int_enable(rhport); +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned num = _dcd.ep[dir][epn]; + + USB0.BRDYENB.WORD &= ~TU_BIT(num); + volatile uint16_t *ctr = get_pipectr(num); + *ctr = 0; + USB0.PIPESEL.WORD = num; + USB0.PIPECFG.WORD = 0; + _dcd.pipe[num].ep = 0; + _dcd.ep[dir][epn] = 0; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) +{ + bool r; + dcd_int_disable(rhport); + r = process_edpt_xfer(0, ep_addr, buffer, total_bytes); + dcd_int_enable(rhport); + return r; +} + +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 + TU_ASSERT(ff->item_size == 1); + bool r; + dcd_int_disable(rhport); + r = process_edpt_xfer(1, ep_addr, ff, total_bytes); + dcd_int_enable(rhport); + return r; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr); + if (!ctr) return; + dcd_int_disable(rhport); + const uint32_t pid = *ctr & 0x3; + *ctr = pid | USB_PIPECTR_PID_STALL; + *ctr = USB_PIPECTR_PID_STALL; + dcd_int_enable(rhport); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr); + if (!ctr) return; + dcd_int_disable(rhport); + *ctr = USB_PIPECTR_SQCLR; + + if (tu_edpt_dir(ep_addr)) { /* IN */ + *ctr = USB_PIPECTR_PID_BUF; + } else { + const unsigned num = _dcd.ep[0][tu_edpt_number(ep_addr)]; + USB0.PIPESEL.WORD = num; + if (USB0.PIPECFG.BIT.TYPE != 1) { + *ctr = USB_PIPECTR_PID_BUF; + } + } + dcd_int_enable(rhport); +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void dcd_int_handler(uint8_t rhport) +{ + (void)rhport; + + unsigned is0 = USB0.INTSTS0.WORD; + /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ + USB0.INTSTS0.WORD = ~((USB_IS0_CTRT | USB_IS0_DVST | USB_IS0_SOFR | USB_IS0_RESM | USB_IS0_VBINT) & is0) | USB_IS0_VALID; + if (is0 & USB_IS0_VBINT) { + if (USB0.INTSTS0.BIT.VBSTS) { + dcd_connect(rhport); + } else { + dcd_disconnect(rhport); + } + } + if (is0 & USB_IS0_RESM) { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); +#if (0==USE_SOF) + USB0.INTENB0.BIT.SOFE = 0; +#endif + } + if ((is0 & USB_IS0_SOFR) && USB0.INTENB0.BIT.SOFE) { + // USBD will exit suspended mode when SOF event is received + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); +#if (0==USE_SOF) + USB0.INTENB0.BIT.SOFE = 0; +#endif + } + if (is0 & USB_IS0_DVST) { + switch (is0 & USB_IS0_DVSQ) { + case USB_IS0_DVSQ_DEF: + process_bus_reset(rhport); + break; + case USB_IS0_DVSQ_ADDR: + process_set_address(rhport); + break; + case USB_IS0_DVSQ_SUSP0: + case USB_IS0_DVSQ_SUSP1: + case USB_IS0_DVSQ_SUSP2: + case USB_IS0_DVSQ_SUSP3: + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); +#if (0==USE_SOF) + USB0.INTENB0.BIT.SOFE = 1; +#endif + default: + break; + } + } + if (is0 & USB_IS0_CTRT) { + if (is0 & USB_IS0_CTSQ_SETUP) { + /* A setup packet has been received. */ + process_setup_packet(rhport); + } else if (0 == (is0 & USB_IS0_CTSQ_MSK)) { + /* A ZLP has been sent/received. */ + process_status_completion(rhport); + } + } + if (is0 & USB_IS0_BEMP) { + const unsigned s = USB0.BEMPSTS.WORD; + USB0.BEMPSTS.WORD = 0; + if (s & 1) { + process_pipe0_bemp(rhport); + } + } + if (is0 & USB_IS0_BRDY) { + const unsigned m = USB0.BRDYENB.WORD; + unsigned s = USB0.BRDYSTS.WORD & m; + /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ + USB0.BRDYSTS.WORD = ~s; + while (s) { +#if defined(__CCRX__) + static const int Mod37BitPosition[] = { + -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, + 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, + 20, 8, 19, 18 + }; + + const unsigned num = Mod37BitPosition[(-s & s) % 37]; +#else + const unsigned num = __builtin_ctz(s); +#endif + process_pipe_brdy(rhport, num); + s &= ~TU_BIT(num); + } + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/renesas/usba/hcd_usba.c b/circuitpython/lib/tinyusb/src/portable/renesas/usba/hcd_usba.c new file mode 100644 index 0000000..ebb6823 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/renesas/usba/hcd_usba.c @@ -0,0 +1,870 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji Kitayama + * Portions copyrighted (c) 2021 Roland Winistoerfer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \ + CFG_TUSB_MCU == OPT_MCU_RX65X || \ + CFG_TUSB_MCU == OPT_MCU_RX72N ) +#include "host/hcd.h" +#include "iodefine.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ +#define SYSTEM_PRCR_PRC1 (1<<1) +#define SYSTEM_PRCR_PRKEY (0xA5u<<8) + +#define USB_DVSTCTR0_LOW (1u) +#define USB_DVSTCTR0_FULL (2u) + +#define USB_FIFOSEL_TX ((uint16_t)(1u<<5)) +#define USB_FIFOSEL_BIGEND ((uint16_t)(1u<<8)) +#define USB_FIFOSEL_MBW_8 ((uint16_t)(0u<<10)) +#define USB_FIFOSEL_MBW_16 ((uint16_t)(1u<<10)) +#define USB_IS0_CTSQ ((uint16_t)(7u)) +#define USB_IS0_DVSQ ((uint16_t)(7u<<4)) +#define USB_IS0_VALID ((uint16_t)(1u<<3)) +#define USB_IS0_BRDY ((uint16_t)(1u<<8)) +#define USB_IS0_NRDY ((uint16_t)(1u<<9)) +#define USB_IS0_BEMP ((uint16_t)(1u<<10)) +#define USB_IS0_CTRT ((uint16_t)(1u<<11)) +#define USB_IS0_DVST ((uint16_t)(1u<<12)) +#define USB_IS0_SOFR ((uint16_t)(1u<<13)) +#define USB_IS0_RESM ((uint16_t)(1u<<14)) +#define USB_IS0_VBINT ((uint16_t)(1u<<15)) +#define USB_IS1_SACK ((uint16_t)(1u<<4)) +#define USB_IS1_SIGN ((uint16_t)(1u<<5)) +#define USB_IS1_EOFERR ((uint16_t)(1u<<6)) +#define USB_IS1_ATTCH ((uint16_t)(1u<<11)) +#define USB_IS1_DTCH ((uint16_t)(1u<<12)) +#define USB_IS1_BCHG ((uint16_t)(1u<<14)) +#define USB_IS1_OVRCR ((uint16_t)(1u<<15)) + +#define USB_IS0_CTSQ_MSK (7u) +#define USB_IS0_CTSQ_SETUP (1u) +#define USB_IS0_DVSQ_DEF (1u<<4) +#define USB_IS0_DVSQ_ADDR (2u<<4) +#define USB_IS0_DVSQ_SUSP0 (4u<<4) +#define USB_IS0_DVSQ_SUSP1 (5u<<4) +#define USB_IS0_DVSQ_SUSP2 (6u<<4) +#define USB_IS0_DVSQ_SUSP3 (7u<<4) + +#define USB_PIPECTR_PID_MSK (3u) +#define USB_PIPECTR_PID_NAK (0u) +#define USB_PIPECTR_PID_BUF (1u) +#define USB_PIPECTR_PID_STALL (2u) +#define USB_PIPECTR_CCPL (1u<<2) +#define USB_PIPECTR_SQMON (1u<<6) +#define USB_PIPECTR_SQCLR (1u<<8) +#define USB_PIPECTR_ACLRM (1u<<9) +#define USB_PIPECTR_INBUFM (1u<<14) +#define USB_PIPECTR_BSTS (1u<<15) + +#define USB_FIFOCTR_DTLN (0x1FF) +#define USB_FIFOCTR_FRDY (1u<<13) +#define USB_FIFOCTR_BCLR (1u<<14) +#define USB_FIFOCTR_BVAL (1u<<15) + +#define USB_PIPECFG_SHTNAK (1u<<7) +#define USB_PIPECFG_DBLB (1u<<9) +#define USB_PIPECFG_BULK (1u<<14) +#define USB_PIPECFG_ISO (3u<<14) +#define USB_PIPECFG_INT (2u<<14) + +#define USB_DEVADD_LOW (1u<<6) +#define USB_DEVADD_FULL (2u<<6) + +#define FIFO_REQ_CLR (1u) +#define FIFO_COMPLETE (1u<<1) + +// Start of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN + +typedef struct { + union { + struct { + uint16_t : 8; + uint16_t TRCLR: 1; + uint16_t TRENB: 1; + uint16_t : 0; + }; + uint16_t TRE; + }; + uint16_t TRN; +} reg_pipetre_t; + +typedef union { + struct { + volatile uint16_t u8: 8; + volatile uint16_t : 0; + }; + volatile uint16_t u16; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ + struct { + uint32_t ep : 8; /* an assigned endpoint address */ + uint32_t dev : 8; /* an assigned device address */ + uint32_t ff : 1; /* `buf` is TU_FUFO or POD */ + uint32_t : 0; + }; +} pipe_state_t; + +TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_BIT_FIELD_ORDER_END + +typedef struct +{ + bool need_reset; /* The device has not been reset after connection. */ + pipe_state_t pipe[10]; + uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */ + uint8_t ctl_mps[5]; /* EP0 max packet size for each device */ +} hcd_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static hcd_data_t _hcd; + +static uint32_t disable_interrupt(void) +{ + uint32_t pswi; +#if defined(__CCRX__) + pswi = get_psw() & 0x010000; + clrpsw_i(); +#else + pswi = __builtin_rx_mvfc(0) & 0x010000; + __builtin_rx_clrpsw('I'); +#endif + return pswi; +} + +static void enable_interrupt(uint32_t pswi) +{ +#if defined(__CCRX__) + set_psw(get_psw() | pswi); +#else + __builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi); +#endif +} + +static unsigned find_pipe(unsigned xfer) +{ + switch (xfer) { + case TUSB_XFER_ISOCHRONOUS: + for (int i = 1; i <= 2; ++i) { + if (0 == _hcd.pipe[i].ep) return i; + } + break; + case TUSB_XFER_BULK: + for (int i = 3; i <= 5; ++i) { + if (0 == _hcd.pipe[i].ep) return i; + } + for (int i = 1; i <= 1; ++i) { + if (0 == _hcd.pipe[i].ep) return i; + } + break; + case TUSB_XFER_INTERRUPT: + for (int i = 6; i <= 9; ++i) { + if (0 == _hcd.pipe[i].ep) return i; + } + break; + default: + /* No support for control transfer */ + break; + } + return 0; +} + +static volatile uint16_t* get_pipectr(unsigned num) +{ + volatile uint16_t *ctr = NULL; + if (num) { + ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD; + ctr += num - 1; + } else { + ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD; + } + return ctr; +} + +static volatile reg_pipetre_t* get_pipetre(unsigned num) +{ + volatile reg_pipetre_t* tre = NULL; + if ((1 <= num) && (num <= 5)) { + tre = (volatile reg_pipetre_t*)&USB0.PIPE1TRE.WORD; + tre += num - 1; + } + return tre; +} + +static volatile uint16_t* addr_to_pipectr(uint8_t dev_addr, unsigned ep_addr) +{ + volatile uint16_t *ctr = NULL; + const unsigned epn = tu_edpt_number(ep_addr); + if (epn) { + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned num = _hcd.ep[dev_addr][dir_in][epn - 1]; + if (num) { + ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD; + ctr += num - 1; + } + } else { + ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD; + } + return ctr; +} + +static unsigned edpt0_max_packet_size(void) +{ + return USB0.DCPMAXP.BIT.MXPS; +} + +static unsigned edpt_max_packet_size(unsigned num) +{ + USB0.PIPESEL.WORD = num; + return USB0.PIPEMAXP.BIT.MXPS; +} + +static inline void pipe_wait_for_ready(unsigned num) +{ + while (USB0.D0FIFOSEL.BIT.CURPIPE != num) ; + while (!USB0.D0FIFOCTR.BIT.FRDY) ; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 2) { + reg->u16 = *(const uint16_t *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(const uint8_t *)addr; + ++addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + uint8_t *p = (uint8_t*)buf; + volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */ + while (len--) *p++ = *reg; +} + +static bool pipe0_xfer_in(void) +{ + pipe_state_t *pipe = &_hcd.pipe[0]; + const unsigned rem = pipe->remaining; + + const unsigned mps = edpt0_max_packet_size(); + const unsigned vld = USB0.CFIFOCTR.BIT.DTLN; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK; + pipe_read_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR; + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return true; + } + USB0.DCPCTR.WORD = USB_PIPECTR_PID_BUF; + return false; +} + +static bool pipe0_xfer_out(void) +{ + pipe_state_t *pipe = &_hcd.pipe[0]; + const unsigned rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + const unsigned mps = edpt0_max_packet_size(); + const unsigned len = TU_MIN(mps, rem); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL; + pipe->remaining = rem - len; + return false; +} + +static bool pipe_xfer_in(unsigned num) +{ + pipe_state_t *pipe = &_hcd.pipe[num]; + const unsigned rem = pipe->remaining; + + USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_8; + const unsigned mps = edpt_max_packet_size(num); + pipe_wait_for_ready(num); + const unsigned vld = USB0.D0FIFOCTR.BIT.DTLN; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + pipe_read_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BCLR; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + return false; +} + +static bool pipe_xfer_out(unsigned num) +{ + pipe_state_t *pipe = &_hcd.pipe[num]; + const unsigned rem = pipe->remaining; + + if (!rem) { + pipe->buf = NULL; + return true; + } + + USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0); + const unsigned mps = edpt_max_packet_size(num); + pipe_wait_for_ready(num); + const unsigned len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; + return false; +} + +static bool process_pipe0_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +{ + (void)dev_addr; + const unsigned dir_in = tu_edpt_dir(ep_addr); + + /* configure fifo direction and access unit settings */ + if (dir_in) { /* IN, a byte */ + USB0.CFIFOSEL.WORD = USB_FIFOSEL_MBW_8; + while (USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX) ; + } else { /* OUT, 2 bytes */ + USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0); + while (!(USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX)) ; + } + + pipe_state_t *pipe = &_hcd.pipe[0]; + pipe->ep = ep_addr; + pipe->length = buflen; + pipe->remaining = buflen; + if (buflen) { + pipe->buf = buffer; + if (!dir_in) { /* OUT */ + TU_ASSERT(USB0.DCPCTR.BIT.BSTS && (USB0.USBREQ.WORD & 0x80)); + pipe0_xfer_out(); + } + } else { /* ZLP */ + pipe->buf = NULL; + if (!dir_in) { /* OUT */ + USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL; + } + if (dir_in == USB0.DCPCFG.BIT.DIR) { + TU_ASSERT(USB_PIPECTR_PID_NAK == USB0.DCPCTR.BIT.PID); + USB0.DCPCTR.BIT.SQSET = 1; + USB0.DCPCFG.BIT.DIR = dir_in ^ 1; + } + } + USB0.DCPCTR.WORD = USB_PIPECTR_PID_BUF; + return true; +} + +static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +{ + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned num = _hcd.ep[dev_addr - 1][dir_in][epn - 1]; + + TU_ASSERT(num); + + pipe_state_t *pipe = &_hcd.pipe[num]; + pipe->buf = buffer; + pipe->length = buflen; + pipe->remaining = buflen; + if (!dir_in) { /* OUT */ + if (buflen) { + pipe_xfer_out(num); + } else { /* ZLP */ + USB0.D0FIFOSEL.WORD = num; + pipe_wait_for_ready(num); + USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + } + } else { + volatile uint16_t *ctr = get_pipectr(num); + volatile reg_pipetre_t *pt = get_pipetre(num); + if (pt) { + const unsigned mps = edpt_max_packet_size(num); + if (*ctr & 0x3) *ctr = USB_PIPECTR_PID_NAK; + pt->TRE = TU_BIT(8); + pt->TRN = (buflen + mps - 1) / mps; + pt->TRENB = 1; + } + *ctr = USB_PIPECTR_PID_BUF; + } + return true; +} + +static bool process_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +{ + const unsigned epn = tu_edpt_number(ep_addr); + if (0 == epn) { + return process_pipe0_xfer(dev_addr, ep_addr, buffer, buflen); + } else { + return process_pipe_xfer(dev_addr, ep_addr, buffer, buflen); + } +} + +static void process_pipe0_bemp(uint8_t rhport) +{ + (void)rhport; + bool completed = pipe0_xfer_out(); + if (completed) { + pipe_state_t *pipe = &_hcd.pipe[0]; + hcd_event_xfer_complete(pipe->dev, + tu_edpt_addr(0, TUSB_DIR_OUT), + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_pipe_nrdy(uint8_t rhport, unsigned num) +{ + (void)rhport; + unsigned result; + uint16_t volatile *ctr = get_pipectr(num); + // TU_LOG1("NRDY %d %x\n", num, *ctr); + switch (*ctr & USB_PIPECTR_PID_MSK) { + default: return; + case USB_PIPECTR_PID_STALL: result = XFER_RESULT_STALLED; break; + case USB_PIPECTR_PID_NAK: result = XFER_RESULT_FAILED; break; + } + pipe_state_t *pipe = &_hcd.pipe[num]; + hcd_event_xfer_complete(pipe->dev, pipe->ep, + pipe->length - pipe->remaining, + result, true); +} + +static void process_pipe_brdy(uint8_t rhport, unsigned num) +{ + (void)rhport; + pipe_state_t *pipe = &_hcd.pipe[num]; + const unsigned dir_in = tu_edpt_dir(pipe->ep); + bool completed; + + if (dir_in) { /* IN */ + if (num) { + completed = pipe_xfer_in(num); + } else { + completed = pipe0_xfer_in(); + } + } else { + completed = pipe_xfer_out(num); + } + if (completed) { + hcd_event_xfer_complete(pipe->dev, pipe->ep, + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + // TU_LOG1("C %d %d\r\n", num, pipe->length - pipe->remaining); + } +} + + +/*------------------------------------------------------------------*/ +/* Host API + *------------------------------------------------------------------*/ +bool hcd_init(uint8_t rhport) +{ + (void)rhport; + /* Enable USB0 */ + uint32_t pswi = disable_interrupt(); + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; + MSTP(USB0) = 0; + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; + enable_interrupt(pswi); + USB0.SYSCFG.BIT.SCKE = 1; + while (!USB0.SYSCFG.BIT.SCKE) ; + USB0.SYSCFG.BIT.DPRPU = 0; + USB0.SYSCFG.BIT.DRPD = 0; + USB0.SYSCFG.BIT.DCFM = 1; + + USB0.DVSTCTR0.BIT.VBUSEN = 1; + + USB0.SYSCFG.BIT.DRPD = 1; + for (volatile int i = 0; i < 30000; ++i) ; + USB0.SYSCFG.BIT.USBE = 1; + + USB.DPUSR0R.BIT.FIXPHY0 = 0u; /* USB0 Transceiver Output fixed */ +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + USB0.PHYSLEW.LONG = 0x5; + IR(PERIB, INTB185) = 0; +#else + IR(USB0, USBI0) = 0; +#endif + + /* Setup default control pipe */ + USB0.DCPCFG.WORD = USB_PIPECFG_SHTNAK; + USB0.DCPMAXP.WORD = 64; + USB0.INTENB0.WORD = USB_IS0_BRDY | USB_IS0_NRDY | USB_IS0_BEMP; + USB0.INTENB1.WORD = USB_IS1_SACK | USB_IS1_SIGN | + USB_IS1_ATTCH | USB_IS1_DTCH; + USB0.BEMPENB.WORD = 1; + USB0.NRDYENB.WORD = 1; + USB0.BRDYENB.WORD = 1; + return true; +} + +void hcd_int_enable(uint8_t rhport) +{ + (void)rhport; +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + IEN(PERIB, INTB185) = 1; +#else + IEN(USB0, USBI0) = 1; +#endif +} + +void hcd_int_disable(uint8_t rhport) +{ + (void)rhport; +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + IEN(PERIB, INTB185) = 0; +#else + IEN(USB0, USBI0) = 0; +#endif +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void)rhport; + /* The device must be reset at least once after connection + * in order to start the frame counter. */ + if (_hcd.need_reset) hcd_port_reset(rhport); + return USB0.FRMNUM.BIT.FRNM; +} + +/*--------------------------------------------------------------------+ + * Port API + *--------------------------------------------------------------------+*/ +bool hcd_port_connect_status(uint8_t rhport) +{ + (void)rhport; + return USB0.INTSTS1.BIT.ATTCH ? true: false; +} + +void hcd_port_reset(uint8_t rhport) +{ + USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK; + while (USB0.DCPCTR.BIT.PBUSY) ; + hcd_int_disable(rhport); + USB0.DVSTCTR0.BIT.UACT = 0; + if (USB0.DCPCTR.BIT.SUREQ) + USB0.DCPCTR.BIT.SUREQCLR = 1; + hcd_int_enable(rhport); + /* Reset should be asserted 10-20ms. */ + USB0.DVSTCTR0.BIT.USBRST = 1; + for (volatile int i = 0; i < 2400000; ++i) ; + USB0.DVSTCTR0.BIT.USBRST = 0; + USB0.DVSTCTR0.BIT.UACT = 1; + _hcd.need_reset = false; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + (void)rhport; + switch (USB0.DVSTCTR0.BIT.RHST) { + default: return TUSB_SPEED_INVALID; + case USB_DVSTCTR0_FULL: return TUSB_SPEED_FULL; + case USB_DVSTCTR0_LOW: return TUSB_SPEED_LOW; + } +} + +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + uint16_t volatile *ctr; + TU_ASSERT(dev_addr < 6,); /* USBa can only handle addresses from 0 to 5. */ + if (!dev_addr) return; + _hcd.ctl_mps[dev_addr] = 0; + uint8_t *ep = &_hcd.ep[dev_addr - 1][0][0]; + for (int i = 0; i < 2 * 15; ++i, ++ep) { + unsigned num = *ep; + if (!num || dev_addr != _hcd.pipe[num].dev) continue; + + ctr = (uint16_t volatile*)&USB0.PIPE1CTR.WORD + num - 1; + *ctr = 0; + USB0.NRDYENB.WORD &= ~TU_BIT(num); + USB0.BRDYENB.WORD &= ~TU_BIT(num); + USB0.PIPESEL.WORD = num; + USB0.PIPECFG.WORD = 0; + USB0.PIPEMAXP.WORD = 0; + + _hcd.pipe[num].ep = 0; + _hcd.pipe[num].dev = 0; + *ep = 0; + } +} + +/*--------------------------------------------------------------------+ + * Endpoints API + *--------------------------------------------------------------------+*/ +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void)rhport; + // TU_LOG1("S %d %x\n", dev_addr, USB0.DCPCTR.WORD); + + TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ + TU_ASSERT(0 == USB0.DCPCTR.BIT.SUREQ); + + USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK; + + _hcd.pipe[0].buf = NULL; + _hcd.pipe[0].length = 8; + _hcd.pipe[0].remaining = 0; + _hcd.pipe[0].dev = dev_addr; + + while (USB0.DCPCTR.BIT.PBUSY) ; + USB0.DCPMAXP.WORD = (dev_addr << 12) | _hcd.ctl_mps[dev_addr]; + + /* Set direction in advance for DATA stage */ + uint8_t const bmRequesttype = setup_packet[0]; + USB0.DCPCFG.BIT.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1; + + uint16_t const* p = (uint16_t const*)(uintptr_t)&setup_packet[0]; + USB0.USBREQ.WORD = tu_htole16(p[0]); + USB0.USBVAL = p[1]; + USB0.USBINDX = p[2]; + USB0.USBLENG = p[3]; + + USB0.DCPCTR.BIT.SUREQ = 1; + return true; +} + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void)rhport; + TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned mps = tu_edpt_packet_size(ep_desc); + if (0 == epn) { + USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK; + hcd_devtree_info_t devtree; + hcd_devtree_get_info(dev_addr, &devtree); + uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t)&USB0.DEVADD0.WORD; + devadd += dev_addr; + while (USB0.DCPCTR.BIT.PBUSY) ; + USB0.DCPMAXP.WORD = (dev_addr << 12) | mps; + *devadd = (TUSB_SPEED_FULL == devtree.speed) ? USB_DEVADD_FULL : USB_DEVADD_LOW; + _hcd.ctl_mps[dev_addr] = mps; + return true; + } + + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + if (xfer == TUSB_XFER_ISOCHRONOUS && mps > 256) { + /* USBa supports up to 256 bytes */ + return false; + } + const unsigned num = find_pipe(xfer); + if (!num) return false; + _hcd.pipe[num].dev = dev_addr; + _hcd.pipe[num].ep = ep_addr; + _hcd.ep[dev_addr - 1][dir_in][epn - 1] = num; + + /* setup pipe */ + hcd_int_disable(rhport); + USB0.PIPESEL.WORD = num; + USB0.PIPEMAXP.WORD = (dev_addr << 12) | mps; + volatile uint16_t *ctr = get_pipectr(num); + *ctr = USB_PIPECTR_ACLRM | USB_PIPECTR_SQCLR; + *ctr = 0; + unsigned cfg = ((1 ^ dir_in) << 4) | epn; + if (xfer == TUSB_XFER_BULK) { + cfg |= USB_PIPECFG_BULK | USB_PIPECFG_SHTNAK | USB_PIPECFG_DBLB; + } else if (xfer == TUSB_XFER_INTERRUPT) { + cfg |= USB_PIPECFG_INT; + } else { + cfg |= USB_PIPECFG_ISO | USB_PIPECFG_DBLB; + } + USB0.PIPECFG.WORD = cfg; + USB0.BRDYSTS.WORD = 0x1FFu ^ TU_BIT(num); + USB0.NRDYENB.WORD |= TU_BIT(num); + USB0.BRDYENB.WORD |= TU_BIT(num); + if (!dir_in) { + *ctr = USB_PIPECTR_PID_BUF; + } + hcd_int_enable(rhport); + + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + bool r; + hcd_int_disable(rhport); + // TU_LOG1("X %d %x %u\n", dev_addr, ep_addr, buflen); + r = process_edpt_xfer(dev_addr, ep_addr, buffer, buflen); + hcd_int_enable(rhport); + return r; +} + +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + uint16_t volatile *ctr = addr_to_pipectr(dev_addr, ep_addr); + TU_ASSERT(ctr); + + const uint32_t pid = *ctr & 0x3; + if (pid & 2) { + *ctr = pid & 2; + *ctr = 0; + } + *ctr = USB_PIPECTR_SQCLR; + unsigned const epn = tu_edpt_number(ep_addr); + if (!epn) return true; + + if (!tu_edpt_dir(ep_addr)) { /* OUT */ + *ctr = USB_PIPECTR_PID_BUF; + } + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void hcd_int_handler(uint8_t rhport) +{ + (void)rhport; +#if defined(__CCRX__) + static const int Mod37BitPosition[] = { + -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, + 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, + 20, 8, 19, 18}; +#endif + + unsigned is1 = USB0.INTSTS1.WORD; + unsigned is0 = USB0.INTSTS0.WORD; + /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ + USB0.INTSTS1.WORD = ~((USB_IS1_SACK | USB_IS1_SIGN | USB_IS1_ATTCH | USB_IS1_DTCH) & is1); + USB0.INTSTS0.WORD = ~((USB_IS0_BRDY | USB_IS0_NRDY | USB_IS0_BEMP) & is0); + // TU_LOG1("IS %04x %04x\n", is0, is1); + is1 &= USB0.INTENB1.WORD; + is0 &= USB0.INTENB0.WORD; + + if (is1 & USB_IS1_SACK) { + /* Set DATA1 in advance for the next transfer. */ + USB0.DCPCTR.BIT.SQSET = 1; + hcd_event_xfer_complete(USB0.DCPMAXP.BIT.DEVSEL, + tu_edpt_addr(0, TUSB_DIR_OUT), + 8, XFER_RESULT_SUCCESS, true); + } + if (is1 & USB_IS1_SIGN) { + hcd_event_xfer_complete(USB0.DCPMAXP.BIT.DEVSEL, + tu_edpt_addr(0, TUSB_DIR_OUT), + 8, XFER_RESULT_FAILED, true); + } + if (is1 & USB_IS1_ATTCH) { + USB0.DVSTCTR0.BIT.UACT = 1; + _hcd.need_reset = true; + USB0.INTENB1.WORD = (USB0.INTENB1.WORD & ~USB_IS1_ATTCH) | USB_IS1_DTCH; + hcd_event_device_attach(rhport, true); + } + if (is1 & USB_IS1_DTCH) { + USB0.DVSTCTR0.BIT.UACT = 0; + if (USB0.DCPCTR.BIT.SUREQ) + USB0.DCPCTR.BIT.SUREQCLR = 1; + USB0.INTENB1.WORD = (USB0.INTENB1.WORD & ~USB_IS1_DTCH) | USB_IS1_ATTCH; + hcd_event_device_remove(rhport, true); + } + + if (is0 & USB_IS0_BEMP) { + const unsigned s = USB0.BEMPSTS.WORD; + USB0.BEMPSTS.WORD = 0; + if (s & 1) { + process_pipe0_bemp(rhport); + } + } + if (is0 & USB_IS0_NRDY) { + const unsigned m = USB0.NRDYENB.WORD; + unsigned s = USB0.NRDYSTS.WORD & m; + USB0.NRDYSTS.WORD = ~s; + while (s) { +#if defined(__CCRX__) + const unsigned num = Mod37BitPosition[(-s & s) % 37]; +#else + const unsigned num = __builtin_ctz(s); +#endif + process_pipe_nrdy(rhport, num); + s &= ~TU_BIT(num); + } + } + if (is0 & USB_IS0_BRDY) { + const unsigned m = USB0.BRDYENB.WORD; + unsigned s = USB0.BRDYSTS.WORD & m; + /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ + USB0.BRDYSTS.WORD = ~s; + while (s) { +#if defined(__CCRX__) + const unsigned num = Mod37BitPosition[(-s & s) % 37]; +#else + const unsigned num = __builtin_ctz(s); +#endif + process_pipe_brdy(rhport, num); + s &= ~TU_BIT(num); + } + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/sony/cxd56/dcd_cxd56.c b/circuitpython/lib/tinyusb/src/portable/sony/cxd56/dcd_cxd56.c new file mode 100644 index 0000000..fbea03b --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/sony/cxd56/dcd_cxd56.c @@ -0,0 +1,417 @@ +/* + * The MIT License (MIT) + * + * Copyright 2019 Sony Semiconductor Solutions Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_CXD56 + +#include +#include +#include + +#include "device/dcd.h" +#include "device/usbd_pvt.h" + +#define CXD56_EPNUM (7) +#define CXD56_SETUP_QUEUE_DEPTH (4) +#define CXD56_MAX_DATA_OUT_SIZE (64) + +OSAL_QUEUE_DEF(usbd_int_set, _setup_queue_def, CXD56_SETUP_QUEUE_DEPTH, struct usb_ctrlreq_s); + +struct usbdcd_driver_s +{ + struct usbdevclass_driver_s usbdevclass_driver; + FAR struct usbdev_ep_s *ep[CXD56_EPNUM]; + FAR struct usbdev_req_s *req[CXD56_EPNUM]; + osal_queue_t setup_queue; + bool setup_processed; + FAR uint8_t dataout[CXD56_MAX_DATA_OUT_SIZE]; + size_t outlen; +}; + +static struct usbdcd_driver_s usbdcd_driver; +static struct usbdev_s *usbdev; + +static int _dcd_bind (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static void _dcd_unbind (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static int _dcd_setup (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, + FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen); +static void _dcd_disconnect (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static void _dcd_suspend (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static void _dcd_resume (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); + +static const struct usbdevclass_driverops_s g_driverops = +{ + _dcd_bind, /* bind */ + _dcd_unbind, /* unbind */ + _dcd_setup, /* setup */ + _dcd_disconnect, /* disconnect */ + _dcd_suspend, /* suspend */ + _dcd_resume, /* resume */ +}; + +static void usbdcd_ep0incomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + (void) ep; + + uint8_t ep_addr = (uint32_t)req->priv; + + if (req->result || req->xfrd != req->len) + { + if (req->len) + { + dcd_event_xfer_complete(0, ep_addr, req->xfrd, XFER_RESULT_SUCCESS, true); + } + } + else + { + if (req->xfrd) + { + dcd_event_xfer_complete(0, ep_addr, req->xfrd, XFER_RESULT_SUCCESS, true); + } + } +} + +static int _dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +{ + (void) driver; + + usbdev = dev; + usbdcd_driver.ep[0] = dev->ep0; + + usbdcd_driver.req[0] = EP_ALLOCREQ(usbdcd_driver.ep[0]); + if (usbdcd_driver.req[0] != NULL) + { + usbdcd_driver.req[0]->len = 64; + usbdcd_driver.req[0]->buf = EP_ALLOCBUFFER(usbdcd_driver.ep[0], 64); + if (!usbdcd_driver.req[0]->buf) + { + EP_FREEREQ(usbdcd_driver.ep[0], usbdcd_driver.req[0]); + usbdcd_driver.req[0] = NULL; + } + } + + usbdcd_driver.req[0]->callback = usbdcd_ep0incomplete; + + DEV_CONNECT(dev); + return 0; +} + +static void _dcd_unbind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +{ + (void) driver; + (void) dev; +} + +static int _dcd_setup(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, + FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen) +{ + (void) driver; + (void) dev; + + if (usbdcd_driver.setup_processed) + { + usbdcd_driver.setup_processed = false; + dcd_event_setup_received(0, (uint8_t const *) ctrl, true); + } + else + { + osal_queue_send(usbdcd_driver.setup_queue, ctrl, true); + } + + if (outlen > 0 && outlen <= CXD56_MAX_DATA_OUT_SIZE) + { + memcpy(usbdcd_driver.dataout, dataout, outlen); + usbdcd_driver.outlen = outlen; + } + + return 0; +} + +static void _dcd_disconnect(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +{ + (void) driver; + + tusb_speed_t speed; + + switch (dev->speed) + { + case USB_SPEED_LOW: + speed = TUSB_SPEED_LOW; + break; + case USB_SPEED_FULL: + speed = TUSB_SPEED_FULL; + break; + case USB_SPEED_HIGH: + speed = TUSB_SPEED_HIGH; + break; + default: + speed = TUSB_SPEED_HIGH; + break; + } + + dcd_event_bus_reset(0, speed, true); + DEV_CONNECT(dev); +} + +static void _dcd_suspend(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +{ + (void) driver; + (void) dev; + + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); +} + +static void _dcd_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +{ + (void) driver; + (void) dev; + + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); +} + +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + usbdcd_driver.usbdevclass_driver.speed = USB_SPEED_HIGH; + usbdcd_driver.usbdevclass_driver.ops = &g_driverops; + usbdcd_driver.setup_processed = true; + usbdcd_driver.setup_queue = osal_queue_create(&_setup_queue_def); + + usbdev_register(&usbdcd_driver.usbdevclass_driver); +} + +// Enable device interrupt +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + + up_enable_irq(CXD56_IRQ_USB_INT); +} + +// Disable device interrupt +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + + up_disable_irq(CXD56_IRQ_USB_INT); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + (void) dev_addr; +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + DEV_WAKEUP(usbdev); +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + DEV_CONNECT(usbdev); +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + DEV_DISCONNECT(usbdev); +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) +{ + (void) rhport; + + uint8_t epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + uint8_t xfrtype = 0; + uint16_t const ep_mps = tu_edpt_packet_size(p_endpoint_desc); + + struct usb_epdesc_s epdesc; + + if (epnum >= CXD56_EPNUM) + { + return false; + } + + switch (p_endpoint_desc->bmAttributes.xfer) + { + case 1: + xfrtype = USB_EP_ATTR_XFER_ISOC; + break; + case 2: + xfrtype = USB_EP_ATTR_XFER_BULK; + break; + case 3: + xfrtype = USB_EP_ATTR_XFER_INT; + break; + } + + usbdcd_driver.ep[epnum] = DEV_ALLOCEP(usbdev, epnum, dir == TUSB_DIR_IN, xfrtype); + if (usbdcd_driver.ep[epnum] == NULL) + { + return false; + } + + usbdcd_driver.req[epnum] = NULL; + usbdcd_driver.req[epnum] = EP_ALLOCREQ(usbdcd_driver.ep[epnum]); + if (usbdcd_driver.req[epnum] != NULL) + { + usbdcd_driver.req[epnum]->len = ep_mps; + } + else + { + return false; + } + + usbdcd_driver.req[epnum]->callback = usbdcd_ep0incomplete; + + epdesc.len = p_endpoint_desc->bLength; + epdesc.type = p_endpoint_desc->bDescriptorType; + epdesc.addr = p_endpoint_desc->bEndpointAddress; + epdesc.attr = xfrtype; + epdesc.mxpacketsize[0] = LSBYTE(ep_mps); + epdesc.mxpacketsize[1] = MSBYTE(ep_mps); + epdesc.interval = p_endpoint_desc->bInterval; + + if (EP_CONFIGURE(usbdcd_driver.ep[epnum], &epdesc, false) < 0) + { + return false; + } + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void) rhport; + + bool ret = true; + uint8_t epnum = tu_edpt_number(ep_addr); + + if (epnum >= CXD56_EPNUM) + { + return false; + } + + if (epnum == 0) + { + if (total_bytes == 0) + { + usbdcd_driver.setup_processed = true; + dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, false); + } + else if (ep_addr == 0x00 && total_bytes == usbdcd_driver.outlen) + { + memcpy(buffer, usbdcd_driver.dataout, usbdcd_driver.outlen); + dcd_event_xfer_complete(0, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); + usbdcd_driver.outlen = 0; + } + else + { + usbdcd_driver.req[epnum]->len = total_bytes; + usbdcd_driver.req[epnum]->priv = (void *)((uint32_t)ep_addr); + usbdcd_driver.req[epnum]->flags = total_bytes < usbdcd_driver.ep[epnum]->maxpacket ? USBDEV_REQFLAGS_NULLPKT : 0; + usbdcd_driver.req[epnum]->buf = buffer; + + if (EP_SUBMIT(usbdcd_driver.ep[epnum], usbdcd_driver.req[epnum]) < 0) + { + ret = false; + } + } + + struct usb_ctrlreq_s ctrl; + + if (usbdcd_driver.setup_processed) + { + if (osal_queue_receive(usbdcd_driver.setup_queue, &ctrl)) + { + usbdcd_driver.setup_processed = false; + dcd_event_setup_received(0, (uint8_t *)&ctrl, false); + } + } + } + else + { + usbdcd_driver.req[epnum]->len = total_bytes; + usbdcd_driver.req[epnum]->priv = (void *)((uint32_t)ep_addr); + usbdcd_driver.req[epnum]->flags = total_bytes < usbdcd_driver.ep[epnum]->maxpacket ? USBDEV_REQFLAGS_NULLPKT : 0; + usbdcd_driver.req[epnum]->buf = buffer; + + if (EP_SUBMIT(usbdcd_driver.ep[epnum], usbdcd_driver.req[epnum]) < 0) + { + ret = false; + } + } + + return ret; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t epnum = tu_edpt_number(ep_addr); + + if (epnum >= CXD56_EPNUM) + { + return; + } + + EP_STALL(usbdcd_driver.ep[epnum]); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t epnum = tu_edpt_number(ep_addr); + + if (epnum >= CXD56_EPNUM) + { + return; + } + + EP_RESUME(usbdcd_driver.ep[epnum]); +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/circuitpython/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c new file mode 100644 index 0000000..4fd1891 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -0,0 +1,1154 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Nathan Conrad + * + * Portions: + * Copyright (c) 2016 STMicroelectronics + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/********************************************** + * This driver has been tested with the following MCUs: + * - F070, F072, L053, F042F6 + * + * It also should work with minimal changes for any ST MCU with an "USB A"/"PCD"/"HCD" peripheral. This + * covers: + * + * F04x, F072, F078, 070x6/B 1024 byte buffer + * F102, F103 512 byte buffer; no internal D+ pull-up (maybe many more changes?) + * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up + * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up + * L0x2, L0x3 1024 byte buffer + * L1 512 byte buffer + * L4x2, L4x3 1024 byte buffer + * + * To use this driver, you must: + * - If you are using a device with crystal-less USB, set up the clock recovery system (CRS) + * - Remap pins to be D+/D- on devices that they are shared (for example: F042Fx) + * - This is different to the normal "alternate function" GPIO interface, needs to go through SYSCFG->CFGRx register + * - Enable USB clock; Perhaps use __HAL_RCC_USB_CLK_ENABLE(); + * - (Optionally configure GPIO HAL to tell it the USB driver is using the USB pins) + * - call tusb_init(); + * - periodically call tusb_task(); + * + * Assumptions of the driver: + * - You are not using CAN (it must share the packet buffer) + * - APB clock is >= 10 MHz + * - On some boards, series resistors are required, but not on others. + * - On some boards, D+ pull up resistor (1.5kohm) is required, but not on others. + * - You don't have long-running interrupts; some USB packets must be quickly responded to. + * - You have the ST CMSIS library linked into the project. HAL is not used. + * + * Current driver limitations (i.e., a list of features for you to add): + * - STALL handled, but not tested. + * - Does it work? No clue. + * - All EP BTABLE buffers are created based on max packet size of first EP opened with that address. + * - No isochronous endpoints + * - Endpoint index is the ID of the endpoint + * - This means that priority is given to endpoints with lower ID numbers + * - Code is mixing up EP IX with EP ID. Everywhere. + * - Packet buffer memory is copied in the interrupt. + * - This is better for performance, but means interrupts are disabled for longer + * - DMA may be the best choice, but it could also be pushed to the USBD task. + * - No double-buffering + * - No DMA + * - Minimal error handling + * - Perhaps error interrupts should be reported to the stack, or cause a device reset? + * - Assumes a single USB peripheral; I think that no hardware has multiple so this is fine. + * - Add a callback for enabling/disabling the D+ PU on devices without an internal PU. + * - F3 models use three separate interrupts. I think we could only use the LP interrupt for + * everything? However, the interrupts are configurable so the DisableInt and EnableInt + * below functions could be adjusting the wrong interrupts (if they had been reconfigured) + * - LPM is not used correctly, or at all? + * + * USB documentation and Reference implementations + * - STM32 Reference manuals + * - STM32 USB Hardware Guidelines AN4879 + * + * - STM32 HAL (much of this driver is based on this) + * - libopencm3/lib/stm32/common/st_usbfs_core.c + * - Keil USB Device http://www.keil.com/pack/doc/mw/USB/html/group__usbd.html + * + * - YouTube OpenTechLab 011; https://www.youtube.com/watch?v=4FOkJLp_PUw + * + * Advantages over HAL driver: + * - Tiny (saves RAM, assumes a single USB peripheral) + * + * Notes: + * - The buffer table is allocated as endpoints are opened. The allocation is only + * cleared when the device is reset. This may be bad if the USB device needs + * to be reconfigured. + */ + +#include "tusb_option.h" + +#if defined(STM32F102x6) || defined(STM32F102xB) || \ + defined(STM32F103x6) || defined(STM32F103xB) || \ + defined(STM32F103xE) || defined(STM32F103xG) +#define STM32F1_FSDEV +#endif + +#if CFG_TUD_ENABLED && \ + ( TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F3, OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32G4, OPT_MCU_STM32WB) || \ + (TU_CHECK_MCU(OPT_MCU_STM32F1) && defined(STM32F1_FSDEV)) \ + ) + +// In order to reduce the dependance on HAL, we undefine this. +// Some definitions are copied to our private include file. +#undef USE_HAL_DRIVER + +#include "device/dcd.h" +#include "portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h" + + +/***************************************************** + * Configuration + *****************************************************/ + +// HW supports max of 8 bidirectional endpoints, but this can be reduced to save RAM +// (8u here would mean 8 IN and 8 OUT) +#ifndef MAX_EP_COUNT +# define MAX_EP_COUNT 8U +#endif + +// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it +// Both of these MUST be a multiple of 2, and are in byte units. +#ifndef DCD_STM32_BTABLE_BASE +# define DCD_STM32_BTABLE_BASE 0U +#endif + +#ifndef DCD_STM32_BTABLE_LENGTH +# define DCD_STM32_BTABLE_LENGTH (PMA_LENGTH - DCD_STM32_BTABLE_BASE) +#endif + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#ifndef USE_SOF +# define USE_SOF 0 +#endif + +/*************************************************** + * Checks, structs, defines, function definitions, etc. + */ + +TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware"); + +TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_LENGTH))<=(PMA_LENGTH), + "BTABLE does not fit in PMA RAM"); + +TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); + +// One of these for every EP IN & OUT, uses a bit of RAM.... +typedef struct +{ + uint8_t * buffer; + // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API + uint16_t total_len; + uint16_t queued_len; + uint16_t pma_ptr; + uint8_t max_packet_size; + uint8_t pma_alloc_size; +} xfer_ctl_t; + +static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; + +static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t epnum, uint32_t dir) +{ + return &xfer_status[epnum][dir]; +} + +static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; + +static uint8_t remoteWakeCountdown; // When wake is requested + +// into the stack. +static void dcd_handle_bus_reset(void); +static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix); +static void dcd_ep_ctr_handler(void); + +// PMA allocation/access +static uint8_t open_ep_count; +static uint16_t ep_buf_ptr; ///< Points to first free memory location +static void dcd_pma_alloc_reset(void); +static uint16_t dcd_pma_alloc(uint8_t ep_addr, size_t length); +static void dcd_pma_free(uint8_t ep_addr); +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes); +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes); + +//static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes); +//static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes); + +// Using a function due to better type checks +// This seems better than having to do type casts everywhere else +static inline void reg16_clear_bits(__IO uint16_t *reg, uint16_t mask) { + *reg = (uint16_t)(*reg & ~mask); +} + +// Bits in ISTR are cleared upon writing 0 +static inline void clear_istr_bits(uint16_t mask) { + USB->ISTR = ~mask; +} + +void dcd_init (uint8_t rhport) +{ + /* Clocks should already be enabled */ + /* Use __HAL_RCC_USB_CLK_ENABLE(); to enable the clocks before calling this function */ + + /* The RM mentions to use a special ordering of PDWN and FRES, but this isn't done in HAL. + * Here, the RM is followed. */ + + for(uint32_t i = 0; i<200; i++) // should be a few us + { + asm("NOP"); + } + // Perform USB peripheral reset + USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; + for(uint32_t i = 0; i<200; i++) // should be a few us + { + asm("NOP"); + } + reg16_clear_bits(&USB->CNTR, USB_CNTR_PDWN);// Remove powerdown + // Wait startup time, for F042 and F070, this is <= 1 us. + for(uint32_t i = 0; i<200; i++) // should be a few us + { + asm("NOP"); + } + USB->CNTR = 0; // Enable USB + + USB->BTABLE = DCD_STM32_BTABLE_BASE; + + USB->ISTR = 0; // Clear pending interrupts + + // Reset endpoints to disabled + for(uint32_t i=0; iCNTR |= USB_CNTR_RESETM | (USE_SOF ? USB_CNTR_SOFM : 0) | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + dcd_handle_bus_reset(); + + // Enable pull-up if supported + if ( dcd_connect ) dcd_connect(rhport); +} + +// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. +#if defined(USB_BCDR_DPPU) + +// Disable internal D+ PU +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB->BCDR &= ~(USB_BCDR_DPPU); +} + +// Enable internal D+ PU +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + USB->BCDR |= USB_BCDR_DPPU; +} + +#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151 +// Disable internal D+ PU +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU); +} + +// Enable internal D+ PU +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + SYSCFG->PMC |= SYSCFG_PMC_USB_PU; +} +#endif + +// Enable device interrupt +void dcd_int_enable (uint8_t rhport) +{ + (void)rhport; + // Member here forces write to RAM before allowing ISR to execute + __DSB(); + __ISB(); +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 + NVIC_EnableIRQ(USB_IRQn); + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 + NVIC_EnableIRQ(USB_LP_IRQn); + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 + // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from + // shared USB/CAN IRQs to separate CAN and USB IRQs. + // This dynamically checks if this remap is active to enable the right IRQs. + #ifdef SYSCFG_CFGR1_USB_IT_RMP + if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) + { + NVIC_EnableIRQ(USB_HP_IRQn); + NVIC_EnableIRQ(USB_LP_IRQn); + NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); + } + else + #endif + { + NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); + NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); + NVIC_EnableIRQ(USBWakeUp_IRQn); + } +#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 + NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn); + NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_EnableIRQ(USBWakeUp_IRQn); + +#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 + NVIC_EnableIRQ(USB_HP_IRQn); + NVIC_EnableIRQ(USB_LP_IRQn); + NVIC_EnableIRQ(USBWakeUp_IRQn); + +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + NVIC_EnableIRQ(USB_HP_IRQn); + NVIC_EnableIRQ(USB_LP_IRQn); + +#else + #error Unknown arch in USB driver +#endif +} + +// Disable device interrupt +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 + NVIC_DisableIRQ(USB_IRQn); +#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 + NVIC_DisableIRQ(USB_LP_IRQn); +#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 + // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from + // shared USB/CAN IRQs to separate CAN and USB IRQs. + // This dynamically checks if this remap is active to disable the right IRQs. + #ifdef SYSCFG_CFGR1_USB_IT_RMP + if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) + { + NVIC_DisableIRQ(USB_HP_IRQn); + NVIC_DisableIRQ(USB_LP_IRQn); + NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); + } + else + #endif + { + NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn); + NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn); + NVIC_DisableIRQ(USBWakeUp_IRQn); + } +#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 + NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); + NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_DisableIRQ(USBWakeUp_IRQn); + +#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 + NVIC_DisableIRQ(USB_HP_IRQn); + NVIC_DisableIRQ(USB_LP_IRQn); + NVIC_DisableIRQ(USBWakeUp_IRQn); + +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + NVIC_DisableIRQ(USB_HP_IRQn); + NVIC_DisableIRQ(USB_LP_IRQn); + +#else + #error Unknown arch in USB driver +#endif + + // CMSIS has a membar after disabling interrupts +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + (void) dev_addr; + + // Respond with status + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + // DCD can only set address after status for this request is complete. + // do it at dcd_edpt0_status_complete() +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + USB->CNTR |= (uint16_t) USB_CNTR_RESUME; + remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. +} + +static const tusb_desc_endpoint_t ep0OUT_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x00, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 +}; + +static const tusb_desc_endpoint_t ep0IN_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x80, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 +}; + +static void dcd_handle_bus_reset(void) +{ + //__IO uint16_t * const epreg = &(EPREG(0)); + USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag + + // Clear all EPREG (or maybe this is automatic? I'm not sure) + for(uint32_t i=0; iDADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. +} + +// Handle CTR interrupt for the TX/IN direction +// +// Upon call, (wIstr & USB_ISTR_DIR) == 0U +static void dcd_ep_ctr_tx_handler(uint32_t wIstr) +{ + uint32_t EPindex = wIstr & USB_ISTR_EP_ID; + uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); + + // Verify the CTR_TX bit is set. This was in the ST Micro code, + // but I'm not sure it's actually necessary? + if((wEPRegVal & USB_EP_CTR_TX) == 0U) + { + return; + } + + /* clear int flag */ + pcd_clear_tx_ep_ctr(USB, EPindex); + + xfer_ctl_t * xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_IN); + if((xfer->total_len != xfer->queued_len)) /* TX not complete */ + { + dcd_transmit_packet(xfer, EPindex); + } + else /* TX Complete */ + { + dcd_event_xfer_complete(0, (uint8_t)(0x80 + EPindex), xfer->total_len, XFER_RESULT_SUCCESS, true); + } +} + +// Handle CTR interrupt for the RX/OUT direction +// +// Upon call, (wIstr & USB_ISTR_DIR) == 0U +static void dcd_ep_ctr_rx_handler(uint32_t wIstr) +{ + uint32_t EPindex = wIstr & USB_ISTR_EP_ID; + uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); + uint32_t count = pcd_get_ep_rx_cnt(USB,EPindex); + + xfer_ctl_t *xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_OUT); + + // Verify the CTR_RX bit is set. This was in the ST Micro code, + // but I'm not sure it's actually necessary? + if((wEPRegVal & USB_EP_CTR_RX) == 0U) + { + return; + } + + if((EPindex == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) /* Setup packet */ + { + // The setup_received function uses memcpy, so this must first copy the setup data into + // user memory, to allow for the 32-bit access that memcpy performs. + uint8_t userMemBuf[8]; + /* Get SETUP Packet*/ + if(count == 8) // Setup packet should always be 8 bytes. If not, ignore it, and try again. + { + // Must reset EP to NAK (in case it had been stalling) (though, maybe too late here) + pcd_set_ep_rx_status(USB,0u,USB_EP_RX_NAK); + pcd_set_ep_tx_status(USB,0u,USB_EP_TX_NAK); + dcd_read_packet_memory(userMemBuf, *pcd_ep_rx_address_ptr(USB,EPindex), 8); + dcd_event_setup_received(0, (uint8_t*)userMemBuf, true); + } + } + else + { + // Clear RX CTR interrupt flag + if(EPindex != 0u) + { + pcd_clear_rx_ep_ctr(USB, EPindex); + } + + if (count != 0U) + { +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + dcd_read_packet_memory_ff(xfer->ff, *pcd_ep_rx_address_ptr(USB,EPindex), count); + } + else +#endif + { + dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), *pcd_ep_rx_address_ptr(USB,EPindex), count); + } + + xfer->queued_len = (uint16_t)(xfer->queued_len + count); + } + + if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) + { + /* RX COMPLETE */ + dcd_event_xfer_complete(0, EPindex, xfer->queued_len, XFER_RESULT_SUCCESS, true); + // Though the host could still send, we don't know. + // Does the bulk pipe need to be reset to valid to allow for a ZLP? + } + else + { + uint32_t remaining = (uint32_t)xfer->total_len - (uint32_t)xfer->queued_len; + if(remaining >= xfer->max_packet_size) { + pcd_set_ep_rx_cnt(USB, EPindex,xfer->max_packet_size); + } else { + pcd_set_ep_rx_cnt(USB, EPindex,remaining); + } + pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); + } + } + + // For EP0, prepare to receive another SETUP packet. + // Clear CTR last so that a new packet does not overwrite the packing being read. + // (Based on the docs, it seems SETUP will always be accepted after CTR is cleared) + if(EPindex == 0u) + { + // Always be prepared for a status packet... + pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); + pcd_clear_rx_ep_ctr(USB, EPindex); + } +} + +static void dcd_ep_ctr_handler(void) +{ + uint32_t wIstr; + + /* stay in loop while pending interrupts */ + while (((wIstr = USB->ISTR) & USB_ISTR_CTR) != 0U) + { + + if ((wIstr & USB_ISTR_DIR) == 0U) /* TX/IN */ + { + dcd_ep_ctr_tx_handler(wIstr); + } + else /* RX/OUT*/ + { + dcd_ep_ctr_rx_handler(wIstr); + } + } +} + +void dcd_int_handler(uint8_t rhport) { + + (void) rhport; + + uint32_t int_status = USB->ISTR; + //const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP + // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; + // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) + + // The ST driver loops here on the CTR bit, but that loop has been moved into the + // dcd_ep_ctr_handler(), so less need to loop here. The other interrupts shouldn't + // be triggered repeatedly. + + if(int_status & USB_ISTR_RESET) { + // USBRST is start of reset. + clear_istr_bits(USB_ISTR_RESET); + dcd_handle_bus_reset(); + dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); + return; // Don't do the rest of the things here; perhaps they've been cleared? + } + + if (int_status & USB_ISTR_CTR) + { + /* servicing of the endpoint correct transfer interrupt */ + /* clear of the CTR flag into the sub */ + dcd_ep_ctr_handler(); + } + + if (int_status & USB_ISTR_WKUP) + { + reg16_clear_bits(&USB->CNTR, USB_CNTR_LPMODE); + reg16_clear_bits(&USB->CNTR, USB_CNTR_FSUSP); + clear_istr_bits(USB_ISTR_WKUP); + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + + if (int_status & USB_ISTR_SUSP) + { + /* Suspend is asserted for both suspend and unplug events. without Vbus monitoring, + * these events cannot be differentiated, so we only trigger suspend. */ + + /* Force low-power mode in the macrocell */ + USB->CNTR |= USB_CNTR_FSUSP; + USB->CNTR |= USB_CNTR_LPMODE; + + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + clear_istr_bits(USB_ISTR_SUSP); + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + +#if USE_SOF + if(int_status & USB_ISTR_SOF) { + clear_istr_bits(USB_ISTR_SOF); + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } +#endif + + if(int_status & USB_ISTR_ESOF) { + if(remoteWakeCountdown == 1u) + { + USB->CNTR &= (uint16_t)(~USB_CNTR_RESUME); + } + if(remoteWakeCountdown > 0u) + { + remoteWakeCountdown--; + } + clear_istr_bits(USB_ISTR_ESOF); + } +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS ) + { + uint8_t const dev_addr = (uint8_t) request->wValue; + + // Setting new address after the whole request is complete + reg16_clear_bits(&USB->DADDR, USB_DADDR_ADD); + USB->DADDR = (uint16_t)(USB->DADDR | dev_addr); // leave the enable bit set + } +} + +static void dcd_pma_alloc_reset(void) +{ + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each) + //TU_LOG2("dcd_pma_alloc_reset()\r\n"); + for(uint32_t i=0; ipma_alloc_size = 0U; + xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_alloc_size = 0U; + xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_ptr = 0U; + xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_ptr = 0U; + } +} + +/*** + * Allocate a section of PMA + * + * If the EP number has already been allocated, and the new allocation + * is larger than the old allocation, then this will fail with a TU_ASSERT. + * (This is done to simplify the code. More complicated algorithms could be used) + * + * During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually. + */ +static uint16_t dcd_pma_alloc(uint8_t ep_addr, size_t length) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t* epXferCtl = xfer_ctl_ptr(epnum,dir); + + if(epXferCtl->pma_alloc_size != 0U) + { + //TU_LOG2("dcd_pma_alloc(%x,%x)=%x (cached)\r\n",ep_addr,length,epXferCtl->pma_ptr); + // Previously allocated + TU_ASSERT(length <= epXferCtl->pma_alloc_size, 0xFFFF); // Verify no larger than previous alloc + return epXferCtl->pma_ptr; + } + + uint16_t addr = ep_buf_ptr; + ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer + + // Verify no overflow + TU_ASSERT(ep_buf_ptr <= PMA_LENGTH, 0xFFFF); + + epXferCtl->pma_ptr = addr; + epXferCtl->pma_alloc_size = length; + //TU_LOG2("dcd_pma_alloc(%x,%x)=%x\r\n",ep_addr,length,addr); + + return addr; +} + +/*** + * Free a block of PMA space + */ +static void dcd_pma_free(uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // Presently, this should never be called for EP0 IN/OUT + TU_ASSERT(open_ep_count > 2, /**/); + TU_ASSERT(xfer_ctl_ptr(epnum,dir)->max_packet_size != 0, /**/); + open_ep_count--; + + // If count is 2, only EP0 should be open, so allocations can be mostly reset. + + if(open_ep_count == 2) + { + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT + 2*CFG_TUD_ENDPOINT0_SIZE; // 8 bytes per endpoint (two TX and two RX words, each), and EP0 + + // Skip EP0 + for(uint32_t i=1; ipma_alloc_size = 0U; + xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_alloc_size = 0U; + xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_ptr = 0U; + xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_ptr = 0U; + } + } +} + +// The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers, +// so I'm using the #define from HAL here, instead. + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void)rhport; + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + const uint16_t epMaxPktSize = tu_edpt_packet_size(p_endpoint_desc); + uint16_t pma_addr; + uint32_t wType; + + // Isochronous not supported (yet), and some other driver assumptions. + TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); + TU_ASSERT(epnum < MAX_EP_COUNT); + + // Set type + switch(p_endpoint_desc->bmAttributes.xfer) { + case TUSB_XFER_CONTROL: + wType = USB_EP_CONTROL; + break; +#if (0) + case TUSB_XFER_ISOCHRONOUS: // FIXME: Not yet supported + wType = USB_EP_ISOCHRONOUS; + break; +#endif + + case TUSB_XFER_BULK: + wType = USB_EP_CONTROL; + break; + + case TUSB_XFER_INTERRUPT: + wType = USB_EP_INTERRUPT; + break; + + default: + TU_ASSERT(false); + } + + pcd_set_eptype(USB, epnum, wType); + pcd_set_ep_address(USB, epnum, epnum); + // Be normal, for now, instead of only accepting zero-byte packets (on control endpoint) + // or being double-buffered (bulk endpoints) + pcd_clear_ep_kind(USB,0); + + pma_addr = dcd_pma_alloc(p_endpoint_desc->bEndpointAddress, epMaxPktSize); + + if(dir == TUSB_DIR_IN) + { + *pcd_ep_tx_address_ptr(USB, epnum) = pma_addr; + pcd_set_ep_tx_cnt(USB, epnum, epMaxPktSize); + pcd_clear_tx_dtog(USB, epnum); + pcd_set_ep_tx_status(USB,epnum,USB_EP_TX_NAK); + } + else + { + *pcd_ep_rx_address_ptr(USB, epnum) = pma_addr; + pcd_set_ep_rx_cnt(USB, epnum, epMaxPktSize); + pcd_clear_rx_dtog(USB, epnum); + pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_NAK); + } + + xfer_ctl_ptr(epnum, dir)->max_packet_size = epMaxPktSize; + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +/** + * Close an endpoint. + * + * This function may be called with interrupts enabled or disabled. + * + * This also clears transfers in progress, should there be any. + */ +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + uint32_t const epnum = tu_edpt_number(ep_addr); + uint32_t const dir = tu_edpt_dir(ep_addr); + + if(dir == TUSB_DIR_IN) + { + pcd_set_ep_tx_status(USB,epnum,USB_EP_TX_DIS); + } + else + { + pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_DIS); + } + + dcd_pma_free(ep_addr); +} + +// Currently, single-buffered, and only 64 bytes at a time (max) + +static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) +{ + uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); + + if(len > xfer->max_packet_size) // max packet size for FS transfer + { + len = xfer->max_packet_size; + } + uint16_t oldAddr = *pcd_ep_tx_address_ptr(USB,ep_ix); + +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + dcd_write_packet_memory_ff(xfer->ff, oldAddr, len); + } + else +#endif + { + dcd_write_packet_memory(oldAddr, &(xfer->buffer[xfer->queued_len]), len); + } + xfer->queued_len = (uint16_t)(xfer->queued_len + len); + + pcd_set_ep_tx_cnt(USB,ep_ix,len); + pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = xfer_ctl_ptr(epnum,dir); + + xfer->buffer = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->total_len = total_bytes; + xfer->queued_len = 0; + + if ( dir == TUSB_DIR_OUT ) + { + // A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid + // buffer for the control endpoint. + if (epnum == 0 && buffer == NULL) + { + xfer->buffer = (uint8_t*)_setup_packet; + } + if(total_bytes > xfer->max_packet_size) + { + pcd_set_ep_rx_cnt(USB,epnum,xfer->max_packet_size); + } else { + pcd_set_ep_rx_cnt(USB,epnum,total_bytes); + } + pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID); + } + else // IN + { + dcd_transmit_packet(xfer,epnum); + } + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = xfer_ctl_ptr(epnum,dir); + + xfer->buffer = NULL; + // xfer->ff = ff; // TODO support dcd_edpt_xfer_fifo API + xfer->total_len = total_bytes; + xfer->queued_len = 0; + + if ( dir == TUSB_DIR_OUT ) + { + if(total_bytes > xfer->max_packet_size) + { + pcd_set_ep_rx_cnt(USB,epnum,xfer->max_packet_size); + } else { + pcd_set_ep_rx_cnt(USB,epnum,total_bytes); + } + pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID); + } + else // IN + { + dcd_transmit_packet(xfer,epnum); + } + return true; +} +#endif + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + + if (ep_addr & 0x80) + { // IN + pcd_set_ep_tx_status(USB, ep_addr & 0x7F, USB_EP_TX_STALL); + } + else + { // OUT + pcd_set_ep_rx_status(USB, ep_addr, USB_EP_RX_STALL); + } +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + + if (ep_addr & 0x80) + { // IN + ep_addr &= 0x7F; + + pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_NAK); + + /* Reset to DATA0 if clearing stall condition. */ + pcd_clear_tx_dtog(USB,ep_addr); + } + else + { // OUT + /* Reset to DATA0 if clearing stall condition. */ + pcd_clear_rx_dtog(USB,ep_addr); + + pcd_set_ep_rx_status(USB,ep_addr, USB_EP_RX_NAK); + } +} + +// Packet buffer access can only be 8- or 16-bit. +/** + * @brief Copy a buffer from user memory area to packet memory area (PMA). + * This uses byte-access for user memory (so support non-aligned buffers) + * and 16-bit access for packet memory. + * @param dst, byte address in PMA; must be 16-bit aligned + * @param src pointer to user memory area. + * @param wPMABufAddr address into PMA. + * @param wNBytes no. of bytes to be copied. + * @retval None + */ +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes) +{ + uint32_t n = ((uint32_t)wNBytes + 1U) >> 1U; + uint32_t i; + uint16_t temp1, temp2; + const uint8_t * srcVal; + + // The GCC optimizer will combine access to 32-bit sizes if we let it. Force + // it volatile so that it won't do that. + __IO uint16_t *pdwVal; + + srcVal = src; + pdwVal = &pma[PMA_STRIDE*(dst>>1)]; + + for (i = n; i != 0; i--) + { + temp1 = (uint16_t) *srcVal; + srcVal++; + temp2 = temp1 | ((uint16_t)((uint16_t) ((*srcVal) << 8U))) ; + *pdwVal = temp2; + pdwVal += PMA_STRIDE; + srcVal++; + } + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +/** + * @brief Copy from FIFO to packet memory area (PMA). + * Uses byte-access of system memory and 16-bit access of packet memory + * @param wNBytes no. of bytes to be copied. + * @retval None + */ + +// THIS FUNCTION IS UNTESTED + +static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes) +{ + // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies + // Check for first linear part + void * src; + uint16_t len = tu_fifo_get_linear_read_info(ff, 0, &src, wNBytes); // We want to read from the FIFO - THIS FUNCTION CHANGED!!! + TU_VERIFY(len && dcd_write_packet_memory(dst, src, len)); // and write it into the PMA + tu_fifo_advance_read_pointer(ff, len); + + // Check for wrapped part + if (len < wNBytes) + { + // Get remaining wrapped length + uint16_t len2 = tu_fifo_get_linear_read_info(ff, 0, &src, wNBytes - len); + TU_VERIFY(len2); + + // Update destination pointer + dst += len; + + // Since PMA is accessed 16-bit wise we need to handle the case when a 16 bit value was split + if (len % 2) // If len is uneven there is a byte left to copy + { + // Since PMA can accessed only 16 bit-wise we copy the last byte again + tu_fifo_backward_read_pointer(ff, 1); // Move one byte back and copy two bytes for the PMA + tu_fifo_read_n(ff, (void *) &pma[PMA_STRIDE*(dst>>1)], 2); // Since EP FIFOs must be of item size 1 this is safe to do + dst++; + len2--; + } + + TU_VERIFY(dcd_write_packet_memory(dst, src, len2)); + tu_fifo_advance_write_pointer(ff, len2); + } + + return true; +} +#endif + +/** + * @brief Copy a buffer from packet memory area (PMA) to user memory area. + * Uses byte-access of system memory and 16-bit access of packet memory + * @param wNBytes no. of bytes to be copied. + * @retval None + */ +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes) +{ + uint32_t n = (uint32_t)wNBytes >> 1U; + uint32_t i; + // The GCC optimizer will combine access to 32-bit sizes if we let it. Force + // it volatile so that it won't do that. + __IO const uint16_t *pdwVal; + uint32_t temp; + + pdwVal = &pma[PMA_STRIDE*(src>>1)]; + uint8_t *dstVal = (uint8_t*)dst; + + for (i = n; i != 0U; i--) + { + temp = *pdwVal; + pdwVal += PMA_STRIDE; + *dstVal++ = ((temp >> 0) & 0xFF); + *dstVal++ = ((temp >> 8) & 0xFF); + } + + if (wNBytes % 2) + { + temp = *pdwVal; + pdwVal += PMA_STRIDE; + *dstVal++ = ((temp >> 0) & 0xFF); + } + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +/** + * @brief Copy a buffer from user packet memory area (PMA) to FIFO. + * Uses byte-access of system memory and 16-bit access of packet memory + * @param wNBytes no. of bytes to be copied. + * @retval None + */ + +// THIS FUNCTION IS UNTESTED + +static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes) +{ + // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies + // Check for first linear part + void * dst; + uint16_t len = tu_fifo_get_linear_write_info(ff, 0, &dst, wNBytes); // THIS FUNCTION CHANGED!!!! + TU_VERIFY(len && dcd_read_packet_memory(dst, src, len)); + tu_fifo_advance_write_pointer(ff, len); + + // Check for wrapped part + if (len < wNBytes) + { + // Get remaining wrapped length + uint16_t len2 = tu_fifo_get_linear_write_info(ff, 0, &dst, wNBytes - len); + TU_VERIFY(len2); + + // Update source pointer + src += len; + + // Since PMA is accessed 16-bit wise we need to handle the case when a 16 bit value was split + if (len % 2) // If len is uneven there is a byte left to copy + { + uint32_t temp = pma[PMA_STRIDE*(src>>1)]; + *((uint8_t *)dst++) = ((temp >> 8) & 0xFF); + src++; + len2--; + } + + TU_VERIFY(dcd_read_packet_memory(dst, src, len2)); + tu_fifo_advance_write_pointer(ff, len2); + } + + return true; +} + +#endif + +#endif + diff --git a/circuitpython/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/circuitpython/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h new file mode 100644 index 0000000..bffae45 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -0,0 +1,422 @@ +/** + ****************************************************************************** + * @file dcd_stm32f0_pvt_st.h + * @brief DCD utilities from ST code + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2016 STMicroelectronics

+ *

© parts COPYRIGHT(c) N Conrad

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of STMicroelectronics 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 HOLDER 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. + * + **********/ + +// This file contains source copied from ST's HAL, and thus should have their copyright statement. + +// PMA_LENGTH is PMA buffer size in bytes. +// On 512-byte devices, access with a stride of two words (use every other 16-bit address) +// On 1024-byte devices, access with a stride of one word (use every 16-bit address) + +#ifndef PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ +#define PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ + +#if defined(STM32F042x6) || \ + defined(STM32F070x6) || defined(STM32F070xB) || \ + defined(STM32F072xB) || \ + defined(STM32F078xx) + #include "stm32f0xx.h" + #define PMA_LENGTH (1024u) + // F0x2 models are crystal-less + // All have internal D+ pull-up + // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support + // PMA dedicated to USB (no sharing with CAN) + +#elif defined(STM32F1_FSDEV) + #include "stm32f1xx.h" + #define PMA_LENGTH (512u) + // NO internal Pull-ups + // *B, and *C: 2 x 16 bits/word + + // F1 names this differently from the rest + #define USB_CNTR_LPMODE USB_CNTR_LP_MODE + +#elif defined(STM32F302xB) || defined(STM32F302xC) || \ + defined(STM32F303xB) || defined(STM32F303xC) || \ + defined(STM32F373xC) + #include "stm32f3xx.h" + #define PMA_LENGTH (512u) + // NO internal Pull-ups + // *B, and *C: 1 x 16 bits/word + // PMA dedicated to USB (no sharing with CAN) + +#elif defined(STM32F302x6) || defined(STM32F302x8) || \ + defined(STM32F302xD) || defined(STM32F302xE) || \ + defined(STM32F303xD) || defined(STM32F303xE) + #include "stm32f3xx.h" + #define PMA_LENGTH (1024u) + // NO internal Pull-ups + // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support + // When CAN clock is enabled, USB can use first 768 bytes ONLY. + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L0 + #include "stm32l0xx.h" + #define PMA_LENGTH (1024u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 + #include "stm32l1xx.h" + #define PMA_LENGTH (512u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 + #include "stm32g4xx.h" + #define PMA_LENGTH (1024u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + #include "stm32wbxx.h" + #define PMA_LENGTH (1024u) + /* ST provided header has incorrect value */ + #undef USB_PMAADDR + #define USB_PMAADDR USB1_PMAADDR + +#else + #error You are using an untested or unimplemented STM32 variant. Please update the driver. + // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 +#endif + +// For purposes of accessing the packet +#if ((PMA_LENGTH) == 512u) + #define PMA_STRIDE (2u) +#elif ((PMA_LENGTH) == 1024u) + #define PMA_STRIDE (1u) +#endif + +// And for type-safety create a new macro for the volatile address of PMAADDR +// The compiler should warn us if we cast it to a non-volatile type? +// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) +static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; + +// prototypes +static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum); +static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum); +static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wRegValue); + + +/* SetENDPOINT */ +static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wRegValue) +{ + __O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpNum*2u); + *reg = (uint16_t)wRegValue; +} + +/* GetENDPOINT */ +static inline uint16_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpNum) { + __I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpNum*2u); + return *reg; +} + +static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wType) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= (uint32_t)USB_EP_T_MASK; + regVal |= wType; + regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high + pcd_set_endpoint(USBx, bEpNum, regVal); +} + +static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EP_T_FIELD; + return regVal; +} +/** + * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPREG_MASK; + regVal &= ~USB_EP_CTR_RX; + regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0) + pcd_set_endpoint(USBx, bEpNum, regVal); +} +static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPREG_MASK; + regVal &= ~USB_EP_CTR_TX; + regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) + pcd_set_endpoint(USBx, bEpNum,regVal); +} +/** + * @brief gets counter of the tx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval Counter value + */ +static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpNum) +{ + __I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpNum); + return *regPtr & 0x3ffU; +} + +static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpNum) +{ + __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpNum); + return *regPtr & 0x3ffU; +} + +/** + * @brief Sets counter of rx buffer with no. of blocks. + * @param dwReg Register + * @param wCount Counter. + * @param wNBlocks no. of Blocks. + * @retval None + */ + +static inline void pcd_set_ep_cnt_rx_reg(__O uint16_t * pdwReg, size_t wCount) { + uint32_t wNBlocks; + if(wCount > 62u) + { + wNBlocks = wCount >> 5u; + if((wCount & 0x1fU) == 0u) + { + wNBlocks--; + } + wNBlocks = wNBlocks << 10u; + wNBlocks |= 0x8000u; // Mark block size as 32byte + *pdwReg = (uint16_t)wNBlocks; + } + else + { + wNBlocks = wCount >> 1u; + if((wCount & 0x1U) != 0u) + { + wNBlocks++; + } + *pdwReg = (uint16_t)((wNBlocks) << 10u); + } +} + + +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param bAddr Address. + * @retval None + */ +static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t bAddr) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPREG_MASK; + regVal |= bAddr; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum,regVal); +} + +static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) +{ + size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; + total_word_offset *= PMA_STRIDE; + return &(pma[total_word_offset]); +} + +// Pointers to the PMA table entries (using the ARM address space) +static inline __IO uint16_t* pcd_ep_tx_address_ptr(USB_TypeDef * USBx, uint32_t bEpNum) +{ + return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 0u); +} +static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum) +{ + return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 1u); +} + +static inline __IO uint16_t* pcd_ep_rx_address_ptr(USB_TypeDef * USBx, uint32_t bEpNum) +{ + return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 2u); +} + +static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum) +{ + return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 3u); +} + +static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) +{ + *pcd_ep_tx_cnt_ptr(USBx, bEpNum) = (uint16_t)wCount; +} + +static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) +{ + __IO uint16_t *pdwReg = pcd_ep_rx_cnt_ptr((USBx),(bEpNum)); + pcd_set_ep_cnt_rx_reg(pdwReg, wCount); +} + +/** + * @brief sets the status for tx transfer (bits STAT_TX[1:0]). + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wState new state + * @retval None + */ +static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wState) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPTX_DTOGMASK; + + /* toggle first bit ? */ + if((USB_EPTX_DTOG1 & (wState))!= 0U) + { + regVal ^= USB_EPTX_DTOG1; + } + /* toggle second bit ? */ + if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) + { + regVal ^= USB_EPTX_DTOG2; + } + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} /* pcd_set_ep_tx_status */ + +/** + * @brief sets the status for rx transfer (bits STAT_TX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wState new state + * @retval None + */ + +static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wState) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPRX_DTOGMASK; + + /* toggle first bit ? */ + if((USB_EPRX_DTOG1 & wState)!= 0U) + { + regVal ^= USB_EPRX_DTOG1; + } + /* toggle second bit ? */ + if((USB_EPRX_DTOG2 & wState)!= 0U) + { + regVal ^= USB_EPRX_DTOG2; + } + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} /* pcd_set_ep_rx_status */ + +static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + return (regVal & USB_EPRX_STAT) >> (12u); +} /* pcd_get_ep_rx_status */ + + +/** + * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} + +static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} + +/** + * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ + +static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + if((regVal & USB_EP_DTOG_RX) != 0) + { + pcd_rx_dtog(USBx,bEpNum); + } +} + +static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + if((regVal & USB_EP_DTOG_TX) != 0) + { + pcd_tx_dtog(USBx,bEpNum); + } +} + +/** + * @brief set & clear EP_KIND bit. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ + +static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal |= USB_EP_KIND; + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} +static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpNum) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPKIND_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} + +// This checks if the device has "LPM" +#if defined(USB_ISTR_L1REQ) +#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) +#else +#define USB_ISTR_L1REQ_FORCED ((uint16_t)0x0000U) +#endif + +#define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \ + USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) + +// Number of endpoints in hardware +#define STFSDEV_EP_COUNT (8u) + +#endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */ diff --git a/circuitpython/lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c b/circuitpython/lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c new file mode 100644 index 0000000..d7f6593 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c @@ -0,0 +1,1233 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2020 Jan Duempelmann + * Copyright (c) 2020 Reinhard Panhuber + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#define USE_SOF 0 + +#if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ + defined (STM32F107xB) || defined (STM32F107xC) +#define STM32F1_SYNOPSYS +#endif + +#if defined (STM32L475xx) || defined (STM32L476xx) || \ + defined (STM32L485xx) || defined (STM32L486xx) || defined (STM32L496xx) || \ + defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ + defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) +#define STM32L4_SYNOPSYS +#endif + +#if CFG_TUD_ENABLED && \ + ( (CFG_TUSB_MCU == OPT_MCU_STM32F1 && defined(STM32F1_SYNOPSYS)) || \ + CFG_TUSB_MCU == OPT_MCU_STM32F2 || \ + CFG_TUSB_MCU == OPT_MCU_STM32F4 || \ + CFG_TUSB_MCU == OPT_MCU_STM32F7 || \ + CFG_TUSB_MCU == OPT_MCU_STM32H7 || \ + (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS) || \ + CFG_TUSB_MCU == OPT_MCU_GD32VF103 ) \ + ) + +// EP_MAX : Max number of bi-directional endpoints including EP0 +// EP_FIFO_SIZE : Size of dedicated USB SRAM +#if CFG_TUSB_MCU == OPT_MCU_STM32F1 +#include "stm32f1xx.h" +#define EP_MAX_FS 4 +#define EP_FIFO_SIZE_FS 1280 + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F2 +#include "stm32f2xx.h" +#define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS +#define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F4 +#include "stm32f4xx.h" +#define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS +#define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE +#define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS +#define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H7 +#include "stm32h7xx.h" +#define EP_MAX_FS 9 +#define EP_FIFO_SIZE_FS 4096 +#define EP_MAX_HS 9 +#define EP_FIFO_SIZE_HS 4096 + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F7 +#include "stm32f7xx.h" +#define EP_MAX_FS 6 +#define EP_FIFO_SIZE_FS 1280 +#define EP_MAX_HS 9 +#define EP_FIFO_SIZE_HS 4096 + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 +#include "stm32l4xx.h" +#define EP_MAX_FS 6 +#define EP_FIFO_SIZE_FS 1280 + +#elif CFG_TUSB_MCU == OPT_MCU_GD32VF103 +#include "synopsys_common.h" + +// for remote wakeup delay +#define __NOP() __asm volatile ("nop") + +// These numbers are the same for the whole GD32VF103 family. +#define OTG_FS_IRQn 86 +#define EP_MAX_FS 4 +#define EP_FIFO_SIZE_FS 1280 + +// The GD32VF103 is a RISC-V MCU, which implements the ECLIC Core-Local +// Interrupt Controller by Nuclei. It is nearly API compatible to the +// NVIC used by ARM MCUs. +#define ECLIC_INTERRUPT_ENABLE_BASE 0xD2001001UL + +#define NVIC_EnableIRQ __eclic_enable_interrupt +#define NVIC_DisableIRQ __eclic_disable_interrupt + +static inline void __eclic_enable_interrupt (uint32_t irq) { + *(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 1; +} + +static inline void __eclic_disable_interrupt (uint32_t irq){ + *(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 0; +} + +#else +#error "Unsupported MCUs" +#endif + +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +// On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS +#if TUD_OPT_RHPORT == 0 +#define EP_MAX EP_MAX_FS +#define EP_FIFO_SIZE EP_FIFO_SIZE_FS +#define RHPORT_REGS_BASE USB_OTG_FS_PERIPH_BASE +#define RHPORT_IRQn OTG_FS_IRQn + +#else +#define EP_MAX EP_MAX_HS +#define EP_FIFO_SIZE EP_FIFO_SIZE_HS +#define RHPORT_REGS_BASE USB_OTG_HS_PERIPH_BASE +#define RHPORT_IRQn OTG_HS_IRQn + +#endif + +#define GLOBAL_BASE(_port) ((USB_OTG_GlobalTypeDef*) RHPORT_REGS_BASE) +#define DEVICE_BASE(_port) (USB_OTG_DeviceTypeDef *) (RHPORT_REGS_BASE + USB_OTG_DEVICE_BASE) +#define OUT_EP_BASE(_port) (USB_OTG_OUTEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_OUT_ENDPOINT_BASE) +#define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_IN_ENDPOINT_BASE) +#define FIFO_BASE(_port, _x) ((volatile uint32_t *) (RHPORT_REGS_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) + +enum +{ + DCD_HIGH_SPEED = 0, // Highspeed mode + DCD_FULL_SPEED_USE_HS = 1, // Full speed in Highspeed port (probably with internal PHY) + DCD_FULL_SPEED = 3, // Full speed with internal PHY +}; + +static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; + +typedef struct { + uint8_t * buffer; + tu_fifo_t * ff; + uint16_t total_len; + uint16_t max_size; + uint8_t interval; +} xfer_ctl_t; + +typedef volatile uint32_t * usb_fifo_t; + +xfer_ctl_t xfer_status[EP_MAX][2]; +#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] + +// EP0 transfers are limited to 1 packet - larger sizes has to be split +static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type + +// TX FIFO RAM allocation so far in words - RX FIFO size is readily available from usb_otg->GRXFSIZ +static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) +static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) + +// Calculate the RX FIFO size according to recommendations from reference manual +static inline uint16_t calc_rx_ff_size(uint16_t ep_size) +{ + return 15 + 2*(ep_size/4) + 2*EP_MAX; +} + +static void update_grxfsiz(uint8_t rhport) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + + // Determine largest EP size for RX FIFO + uint16_t max_epsize = 0; + for (uint8_t epnum = 0; epnum < EP_MAX; epnum++) + { + max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size); + } + + // Update size of RX FIFO + usb_otg->GRXFSIZ = calc_rx_ff_size(max_epsize); +} + +// Setup the control endpoint 0. +static void bus_reset(uint8_t rhport) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + tu_memclr(xfer_status, sizeof(xfer_status)); + _out_ep_closed = false; + + // clear device address + dev->DCFG &= ~USB_OTG_DCFG_DAD_Msk; + + // 1. NAK for all OUT endpoints + for(uint8_t n = 0; n < EP_MAX; n++) { + out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK; + } + + // 2. Un-mask interrupt bits + dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos); + dev->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM; + dev->DIEPMSK = USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM; + + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start. + // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located + // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard + // configuration done below. + // + // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed. + // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a + // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually + // opened when the host sends an additional command: setInterface. At this point in time + // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size + // an additional memory + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO 0 | + // --------------- (320 or 1024) - 16 + // | IN FIFO 1 | + // --------------- (320 or 1024) - 16 - x + // | . . . . | + // --------------- (320 or 1024) - 16 - x - y - ... - z + // | IN FIFO MAX | + // --------------- + // | FREE | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): + // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN + // + // - All EP OUT shared a unique OUT FIFO which uses + // - 13 for setup packets + control words (up to 3 setup packets). + // - 1 for global NAK (not required/used here). + // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" + // - 2 for each used OUT endpoint + // + // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum + // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x EP_MAX = 47 + 2 x EP_MAX + // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x EP_MAX = 271 + 2 x EP_MAX + // + // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge + // of the overall picture yet. We will use the worst scenario: largest possible + EP_MAX + // + // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO + // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to + // overwrite this. + + usb_otg->GRXFSIZ = calc_rx_ff_size(TUD_OPT_HIGH_SPEED ? 512 : 64); + + _allocated_fifo_words_tx = 16; + + // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) + usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); + + // Fixed control EP0 size to 64 bytes + in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos); + xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64; + + out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); + + usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; +} + +// Set turn-around timeout according to link speed +extern uint32_t SystemCoreClock; +static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) +{ + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; + + if ( speed == TUSB_SPEED_HIGH ) + { + // Use fixed 0x09 for Highspeed + usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); + } + else + { + // Turnaround timeout depends on the MCU clock + uint32_t turnaround; + + if ( SystemCoreClock >= 32000000U ) + turnaround = 0x6U; + else if ( SystemCoreClock >= 27500000U ) + turnaround = 0x7U; + else if ( SystemCoreClock >= 24000000U ) + turnaround = 0x8U; + else if ( SystemCoreClock >= 21800000U ) + turnaround = 0x9U; + else if ( SystemCoreClock >= 20000000U ) + turnaround = 0xAU; + else if ( SystemCoreClock >= 18500000U ) + turnaround = 0xBU; + else if ( SystemCoreClock >= 17200000U ) + turnaround = 0xCU; + else if ( SystemCoreClock >= 16000000U ) + turnaround = 0xDU; + else if ( SystemCoreClock >= 15000000U ) + turnaround = 0xEU; + else + turnaround = 0xFU; + + // Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz + usb_otg->GUSBCFG |= (turnaround << USB_OTG_GUSBCFG_TRDT_Pos); + } +} + +static tusb_speed_t get_speed(uint8_t rhport) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; + return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; +} + +static void set_speed(uint8_t rhport, tusb_speed_t speed) +{ + uint32_t bitvalue; + + if ( rhport == 1 ) + { + bitvalue = ((TUSB_SPEED_HIGH == speed) ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS); + } + else + { + bitvalue = DCD_FULL_SPEED; + } + + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + + // Clear and set speed bits + dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); + dev->DCFG |= (bitvalue << USB_OTG_DCFG_DSPD_Pos); +} + +#if defined(USB_HS_PHYC) +static bool USB_HS_PHYCInit(void) +{ + USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE; + + // Enable LDO: Note STM32F72/3xx Reference Manual rev 3 June 2018 incorrectly defined this bit as Disabled !! + usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; + + // Wait until LDO ready + while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {} + + uint32_t phyc_pll = 0; + + // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS + switch ( HSE_VALUE ) + { + case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break; + case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break; + case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break; + case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break; + case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break; + case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header + default: + TU_ASSERT(0); + } + usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll; + + // Control the tuning interface of the High Speed PHY + // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver + usb_hs_phyc->USB_HS_PHYC_TUNE |= 0x00000F13U; + + // Enable PLL internal PHY + usb_hs_phyc->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; + + // Original ST code has 2 ms delay for PLL stabilization. + // Primitive test shows that more than 10 USB un/replug cycle showed no error with enumeration + + return true; +} +#endif + +static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) +{ + (void) rhport; + + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + // EP0 is limited to one packet each xfer + // We use multiple transaction of xfer->max_size length to get a whole transfer done + if(epnum == 0) { + xfer_ctl_t * const xfer = XFER_CTL_BASE(epnum, dir); + total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); + ep0_pending[dir] -= total_bytes; + } + + // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. + if(dir == TUSB_DIR_IN) { + // A full IN transfer (multiple packets, possibly) triggers XFRC. + in_ep[epnum].DIEPTSIZ = (num_packets << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | + ((total_bytes << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) & USB_OTG_DIEPTSIZ_XFRSIZ_Msk); + + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK; + // For ISO endpoint set correct odd/even bit for next frame. + if ((in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP) == USB_OTG_DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) + { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos)); + in_ep[epnum].DIEPCTL |= (odd_frame_now ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DIEPCTL_SODDFRM_Msk); + } + // Enable fifo empty interrupt only if there are something to put in the fifo. + if(total_bytes != 0) { + dev->DIEPEMPMSK |= (1 << epnum); + } + } else { + // A full OUT transfer (multiple packets, possibly) triggers XFRC. + out_ep[epnum].DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT_Msk | USB_OTG_DOEPTSIZ_XFRSIZ); + out_ep[epnum].DOEPTSIZ |= (num_packets << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | + ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk); + + out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; + if ((out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP) == USB_OTG_DOEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) + { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos)); + out_ep[epnum].DOEPCTL |= (odd_frame_now ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DOEPCTL_SODDFRM_Msk); + } + } +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init (uint8_t rhport) +{ + // Programming model begins in the last section of the chapter on the USB + // peripheral in each Reference Manual. + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + + // No HNP/SRP (no OTG support), program timeout later. + if ( rhport == 1 ) + { + // On selected MCUs HS port1 can be used with external PHY via ULPI interface +#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED + // deactivate internal PHY + usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; + + // Init The UTMI Interface + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); + + // Select default internal VBUS Indicator and Drive for ULPI + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); +#else + usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; +#endif + +#if defined(USB_HS_PHYC) + // Highspeed with embedded UTMI PHYC + + // Select UTMI Interface + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL; + usb_otg->GCCFG |= USB_OTG_GCCFG_PHYHSEN; + + // Enables control of a High Speed USB PHY + USB_HS_PHYCInit(); +#endif + } else + { + // Enable internal PHY + usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; + } + + // Reset core after selecting PHY + // Wait AHB IDLE, reset then wait until it is cleared + while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U) {} + usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; + while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST) {} + + // Restart PHY clock + *((volatile uint32_t *)(RHPORT_REGS_BASE + USB_OTG_PCGCCTL_BASE)) = 0; + + // Clear all interrupts + usb_otg->GINTSTS |= usb_otg->GINTSTS; + + // Required as part of core initialization. + // TODO: How should mode mismatch be handled? It will cause + // the core to stop working/require reset. + usb_otg->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; + + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + + // If USB host misbehaves during status portion of control xfer + // (non zero-length packet), send STALL back and discard. + dev->DCFG |= USB_OTG_DCFG_NZLSOHSK; + + set_speed(rhport, TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL); + + // Enable internal USB transceiver, unless using HS core (port 1) with external PHY. + if (!(rhport == 1 && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED))) usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; + + usb_otg->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | + USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | + USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); + + // Enable global interrupt + usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; + + dcd_connect(rhport); +} + +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(RHPORT_IRQn); +} + +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(RHPORT_IRQn); +} + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + dev->DCFG = (dev->DCFG & ~USB_OTG_DCFG_DAD_Msk) | (dev_addr << USB_OTG_DCFG_DAD_Pos); + + // Response with status after changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +static void remote_wakeup_delay(void) +{ + // try to delay for 1 ms + uint32_t count = SystemCoreClock / 1000; + while ( count-- ) + { + __NOP(); + } +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + + // set remote wakeup + dev->DCTL |= USB_OTG_DCTL_RWUSIG; + + // enable SOF to detect bus resume + usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; + usb_otg->GINTMSK |= USB_OTG_GINTMSK_SOFM; + + // Per specs: remote wakeup signal bit must be clear within 1-15ms + remote_wakeup_delay(); + + dev->DCTL &= ~USB_OTG_DCTL_RWUSIG; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + dev->DCTL &= ~USB_OTG_DCTL_SDIS; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + dev->DCTL |= USB_OTG_DCTL_SDIS; +} + + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + TU_ASSERT(epnum < EP_MAX); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); + xfer->interval = desc_edpt->bInterval; + + uint16_t const fifo_size = (xfer->max_size + 3) / 4; // Round up to next full word + + if(dir == TUSB_DIR_OUT) + { + // Calculate required size of RX FIFO + uint16_t const sz = calc_rx_ff_size(4*fifo_size); + + // If size_rx needs to be extended check if possible and if so enlarge it + if (usb_otg->GRXFSIZ < sz) + { + TU_ASSERT(sz + _allocated_fifo_words_tx <= EP_FIFO_SIZE/4); + + // Enlarge RX FIFO + usb_otg->GRXFSIZ = sz; + } + + out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) | + (desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos) | + (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << USB_OTG_DOEPCTL_MPSIZ_Pos); + + dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum)); + } + else + { + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO 0 | + // --------------- (320 or 1024) - 16 + // | IN FIFO 1 | + // --------------- (320 or 1024) - 16 - x + // | . . . . | + // --------------- (320 or 1024) - 16 - x - y - ... - z + // | IN FIFO MAX | + // --------------- + // | FREE | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // In FIFO is allocated by following rules: + // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". + + // Check if free space is available + TU_ASSERT(_allocated_fifo_words_tx + fifo_size + usb_otg->GRXFSIZ <= EP_FIFO_SIZE/4); + + _allocated_fifo_words_tx += fifo_size; + + TU_LOG(2, " Allocated %u bytes at offset %u", fifo_size*4, EP_FIFO_SIZE-_allocated_fifo_words_tx*4); + + // DIEPTXF starts at FIFO #1. + // Both TXFD and TXSA are in unit of 32-bit words. + usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); + + in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) | + (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) | + (desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) | + (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << USB_OTG_DIEPCTL_MPSIZ_Pos); + + dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum)); + } + + return true; +} + +// Close all non-control endpoints, cancel all pending transfers if any. +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + +// USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + // Disable non-control interrupt + dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos); + + for(uint8_t n = 1; n < EP_MAX; n++) + { + // disable OUT endpoint + out_ep[n].DOEPCTL = 0; + xfer_status[n][TUSB_DIR_OUT].max_size = 0; + + // disable IN endpoint + in_ep[n].DIEPCTL = 0; + xfer_status[n][TUSB_DIR_IN].max_size = 0; + } + + // reset allocated fifo IN + _allocated_fifo_words_tx = 16; +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + xfer->ff = NULL; + xfer->total_len = total_bytes; + + // EP0 can only handle one packet + if(epnum == 0) { + ep0_pending[dir] = total_bytes; + // Schedule the first transaction for EP0 transfer + edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]); + return true; + } + + uint16_t num_packets = (total_bytes / xfer->max_size); + uint16_t const short_packet_size = total_bytes % xfer->max_size; + + // Zero-size packet is special case. + if(short_packet_size > 0 || (total_bytes == 0)) { + num_packets++; + } + + // Schedule packets to be sent within interrupt + edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); + + return true; +} + +// The number of bytes has to be given explicitly to allow more flexible control of how many +// bytes should be written and second to keep the return value free to give back a boolean +// success message. If total_bytes is too big, the FIFO will copy only what is available +// into the USB buffer! +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 + TU_ASSERT(ff->item_size == 1); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = NULL; + xfer->ff = ff; + xfer->total_len = total_bytes; + + uint16_t num_packets = (total_bytes / xfer->max_size); + uint16_t const short_packet_size = total_bytes % xfer->max_size; + + // Zero-size packet is special case. + if(short_packet_size > 0 || (total_bytes == 0)) num_packets++; + + // Schedule packets to be sent within interrupt + edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); + + return true; +} + +static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall) +{ + (void) rhport; + + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if(dir == TUSB_DIR_IN) { + // Only disable currently enabled non-control endpoint + if ( (epnum == 0) || !(in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPENA) ){ + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK | (stall ? USB_OTG_DIEPCTL_STALL : 0); + } else { + // Stop transmitting packets and NAK IN xfers. + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK; + while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_INEPNE) == 0); + + // Disable the endpoint. + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPDIS | (stall ? USB_OTG_DIEPCTL_STALL : 0); + while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_EPDISD_Msk) == 0); + in_ep[epnum].DIEPINT = USB_OTG_DIEPINT_EPDISD; + } + + // Flush the FIFO, and wait until we have confirmed it cleared. + usb_otg->GRSTCTL |= (epnum << USB_OTG_GRSTCTL_TXFNUM_Pos); + usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_TXFFLSH; + while((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH_Msk) != 0); + } else { + // Only disable currently enabled non-control endpoint + if ( (epnum == 0) || !(out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPENA) ){ + out_ep[epnum].DOEPCTL |= stall ? USB_OTG_DOEPCTL_STALL : 0; + } else { + // Asserting GONAK is required to STALL an OUT endpoint. + // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt + // anyway, and it can't be cleared by user code. If this while loop never + // finishes, we have bigger problems than just the stack. + dev->DCTL |= USB_OTG_DCTL_SGONAK; + while((usb_otg->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF_Msk) == 0); + + // Ditto here- disable the endpoint. + out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPDIS | (stall ? USB_OTG_DOEPCTL_STALL : 0); + while((out_ep[epnum].DOEPINT & USB_OTG_DOEPINT_EPDISD_Msk) == 0); + out_ep[epnum].DOEPINT = USB_OTG_DOEPINT_EPDISD; + + // Allow other OUT endpoints to keep receiving. + dev->DCTL |= USB_OTG_DCTL_CGONAK; + } + } +} + +/** + * Close an endpoint. + */ +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +{ + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_edpt_disable(rhport, ep_addr, false); + + // Update max_size + xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation + + if (dir == TUSB_DIR_IN) + { + uint16_t const fifo_size = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXFD_Msk) >> USB_OTG_DIEPTXF_INEPTXFD_Pos; + uint16_t const fifo_start = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXSA_Msk) >> USB_OTG_DIEPTXF_INEPTXSA_Pos; + // For now only the last opened endpoint can be closed without fuss. + TU_ASSERT(fifo_start == EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,); + _allocated_fifo_words_tx -= fifo_size; + } + else + { + _out_ep_closed = true; // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty + } +} + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + dcd_edpt_disable(rhport, ep_addr, true); +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // Clear stall and reset data toggle + if(dir == TUSB_DIR_IN) { + in_ep[epnum].DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + } else { + out_ep[epnum].DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; + out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + } +} + +/*------------------------------------------------------------------*/ + +// Read a single data packet from receive FIFO +static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len) +{ + (void) rhport; + + usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); + + // Reading full available 32 bit words from fifo + uint16_t full_words = len >> 2; + for(uint16_t i = 0; i < full_words; i++) { + uint32_t tmp = *rx_fifo; + dst[0] = tmp & 0x000000FF; + dst[1] = (tmp & 0x0000FF00) >> 8; + dst[2] = (tmp & 0x00FF0000) >> 16; + dst[3] = (tmp & 0xFF000000) >> 24; + dst += 4; + } + + // Read the remaining 1-3 bytes from fifo + uint8_t bytes_rem = len & 0x03; + if(bytes_rem != 0) { + uint32_t tmp = *rx_fifo; + dst[0] = tmp & 0x000000FF; + if(bytes_rem > 1) { + dst[1] = (tmp & 0x0000FF00) >> 8; + } + if(bytes_rem > 2) { + dst[2] = (tmp & 0x00FF0000) >> 16; + } + } +} + +// Write a single data packet to EPIN FIFO +static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, uint16_t len) +{ + (void) rhport; + + usb_fifo_t tx_fifo = FIFO_BASE(rhport, fifo_num); + + // Pushing full available 32 bit words to fifo + uint16_t full_words = len >> 2; + for(uint16_t i = 0; i < full_words; i++){ + *tx_fifo = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0]; + src += 4; + } + + // Write the remaining 1-3 bytes into fifo + uint8_t bytes_rem = len & 0x03; + if(bytes_rem){ + uint32_t tmp_word = 0; + tmp_word |= src[0]; + if(bytes_rem > 1){ + tmp_word |= src[1] << 8; + } + if(bytes_rem > 2){ + tmp_word |= src[2] << 16; + } + *tx_fifo = tmp_word; + } +} + +static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) { + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); + + // Pop control word off FIFO + uint32_t ctl_word = usb_otg->GRXSTSP; + uint8_t pktsts = (ctl_word & USB_OTG_GRXSTSP_PKTSTS_Msk) >> USB_OTG_GRXSTSP_PKTSTS_Pos; + uint8_t epnum = (ctl_word & USB_OTG_GRXSTSP_EPNUM_Msk) >> USB_OTG_GRXSTSP_EPNUM_Pos; + uint16_t bcnt = (ctl_word & USB_OTG_GRXSTSP_BCNT_Msk) >> USB_OTG_GRXSTSP_BCNT_Pos; + + switch(pktsts) { + case 0x01: // Global OUT NAK (Interrupt) + break; + + case 0x02: // Out packet recvd + { + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + + // Read packet off RxFIFO + if (xfer->ff) + { + // Ring buffer + tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *)(uintptr_t) rx_fifo, bcnt); + } + else + { + // Linear buffer + read_fifo_packet(rhport, xfer->buffer, bcnt); + + // Increment pointer to xfer data + xfer->buffer += bcnt; + } + + // Truncate transfer length in case of short packet + if(bcnt < xfer->max_size) { + xfer->total_len -= (out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos; + if(epnum == 0) { + xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; + ep0_pending[TUSB_DIR_OUT] = 0; + } + } + } + break; + + case 0x03: // Out packet done (Interrupt) + break; + + case 0x04: // Setup packet done (Interrupt) + out_ep[epnum].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); + break; + + case 0x06: // Setup packet recvd + // We can receive up to three setup packets in succession, but + // only the last one is valid. + _setup_packet[0] = (* rx_fifo); + _setup_packet[1] = (* rx_fifo); + break; + + default: // Invalid + TU_BREAKPOINT(); + break; + } +} + +static void handle_epout_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTypeDef * out_ep) { + // DAINT for a given EP clears when DOEPINTx is cleared. + // OEPINT will be cleared when DAINT's out bits are cleared. + for(uint8_t n = 0; n < EP_MAX; n++) { + xfer_ctl_t * xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); + + if(dev->DAINT & (1 << (USB_OTG_DAINT_OEPINT_Pos + n))) { + // SETUP packet Setup Phase done. + if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_STUP) { + out_ep[n].DOEPINT = USB_OTG_DOEPINT_STUP; + dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true); + } + + // OUT XFER complete + if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_XFRC) { + out_ep[n].DOEPINT = USB_OTG_DOEPINT_XFRC; + + // EP0 can only handle one packet + if((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + } + } +} + +static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointTypeDef * in_ep) { + // DAINT for a given EP clears when DIEPINTx is cleared. + // IEPINT will be cleared when DAINT's out bits are cleared. + for ( uint8_t n = 0; n < EP_MAX; n++ ) + { + xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_IN); + + if ( dev->DAINT & (1 << (USB_OTG_DAINT_IEPINT_Pos + n)) ) + { + // IN XFER complete (entire xfer). + if ( in_ep[n].DIEPINT & USB_OTG_DIEPINT_XFRC ) + { + in_ep[n].DIEPINT = USB_OTG_DIEPINT_XFRC; + + // EP0 can only handle one packet + if((n == 0) && ep0_pending[TUSB_DIR_IN]) { + // Schedule another packet to be transmitted. + edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); + } else { + dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + + // XFER FIFO empty + if ( (in_ep[n].DIEPINT & USB_OTG_DIEPINT_TXFE) && (dev->DIEPEMPMSK & (1 << n)) ) + { + // DIEPINT's TXFE bit is read-only, software cannot clear it. + // It will only be cleared by hardware when written bytes is more than + // - 64 bytes or + // - Half of TX FIFO size (configured by DIEPTXF) + + uint16_t remaining_packets = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_PKTCNT_Msk) >> USB_OTG_DIEPTSIZ_PKTCNT_Pos; + + // Process every single packet (only whole packets can be written to fifo) + for(uint16_t i = 0; i < remaining_packets; i++) + { + uint16_t const remaining_bytes = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos; + + // Packet can not be larger than ep max size + uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size); + + // It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current + // EP has to be checked if the buffer can take another WHOLE packet + if(packet_size > ((in_ep[n].DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV_Msk) << 2)) break; + + // Push packet to Tx-FIFO + if (xfer->ff) + { + usb_fifo_t tx_fifo = FIFO_BASE(rhport, n); + tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *)(uintptr_t) tx_fifo, packet_size); + } + else + { + write_fifo_packet(rhport, n, xfer->buffer, packet_size); + + // Increment pointer to xfer data + xfer->buffer += packet_size; + } + } + + // Turn off TXFE if all bytes are written. + if (((in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos) == 0) + { + dev->DIEPEMPMSK &= ~(1 << n); + } + } + } + } +} + +void dcd_int_handler(uint8_t rhport) +{ + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + uint32_t const int_status = usb_otg->GINTSTS & usb_otg->GINTMSK; + + if(int_status & USB_OTG_GINTSTS_USBRST) + { + // USBRST is start of reset. + usb_otg->GINTSTS = USB_OTG_GINTSTS_USBRST; + bus_reset(rhport); + } + + if(int_status & USB_OTG_GINTSTS_ENUMDNE) + { + // ENUMDNE is the end of reset where speed of the link is detected + + usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; + + tusb_speed_t const speed = get_speed(rhport); + + set_turnaround(usb_otg, speed); + dcd_event_bus_reset(rhport, speed, true); + } + + if(int_status & USB_OTG_GINTSTS_USBSUSP) + { + usb_otg->GINTSTS = USB_OTG_GINTSTS_USBSUSP; + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + if(int_status & USB_OTG_GINTSTS_WKUINT) + { + usb_otg->GINTSTS = USB_OTG_GINTSTS_WKUINT; + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + + // TODO check USB_OTG_GINTSTS_DISCINT for disconnect detection + // if(int_status & USB_OTG_GINTSTS_DISCINT) + + if(int_status & USB_OTG_GINTSTS_OTGINT) + { + // OTG INT bit is read-only + uint32_t const otg_int = usb_otg->GOTGINT; + + if (otg_int & USB_OTG_GOTGINT_SEDET) + { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + + usb_otg->GOTGINT = otg_int; + } + + if(int_status & USB_OTG_GINTSTS_SOF) + { + usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; + + // Disable SOF interrupt since currently only used for remote wakeup detection + usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_SOFM; + + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + + // RxFIFO non-empty interrupt handling. + if(int_status & USB_OTG_GINTSTS_RXFLVL) + { + // RXFLVL bit is read-only + + // Mask out RXFLVL while reading data from FIFO + usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; + + // Loop until all available packets were handled + do + { + handle_rxflvl_ints(rhport, out_ep); + } while(usb_otg->GINTSTS & USB_OTG_GINTSTS_RXFLVL); + + // Manage RX FIFO size + if (_out_ep_closed) + { + update_grxfsiz(rhport); + + // Disable flag + _out_ep_closed = false; + } + + usb_otg->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; + } + + // OUT endpoint interrupt handling. + if(int_status & USB_OTG_GINTSTS_OEPINT) + { + // OEPINT is read-only + handle_epout_ints(rhport, dev, out_ep); + } + + // IN endpoint interrupt handling. + if(int_status & USB_OTG_GINTSTS_IEPINT) + { + // IEPINT bit read-only + handle_epin_ints(rhport, dev, in_ep); + } + + // // Check for Incomplete isochronous IN transfer + // if(int_status & USB_OTG_GINTSTS_IISOIXFR) { + // printf(" IISOIXFR!\r\n"); + //// TU_LOG2(" IISOIXFR!\r\n"); + // } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/st/synopsys/synopsys_common.h b/circuitpython/lib/tinyusb/src/portable/st/synopsys/synopsys_common.h new file mode 100644 index 0000000..6f0602f --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/st/synopsys/synopsys_common.h @@ -0,0 +1,1465 @@ +/** + ****************************************************************************** + * @file synopsys_common.h + * @author MCD Application Team + * @brief CMSIS Cortex-M3 Device USB OTG peripheral Header File. + * This file contains the USB OTG peripheral register's definitions, bits + * definitions and memory mapping for STM32F1xx devices. + * + * This file contains: + * - Data structures and the address mapping for the USB OTG peripheral + * - The Peripheral's registers declarations and bits definition + * - Macros to access the peripheral's registers hardware + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#include "stdint.h" + +#pragma once + +#ifdef __cplusplus + #define __I volatile +#else + #define __I volatile const +#endif +#define __O volatile +#define __IO volatile +#define __IM volatile const +#define __OM volatile +#define __IOM volatile + +/** + * @brief __USB_OTG_Core_register + */ + +typedef struct +{ + __IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register Address offset: 000h */ + __IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register Address offset: 004h */ + __IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register Address offset: 008h */ + __IO uint32_t GUSBCFG; /*!< Core USB Configuration Register Address offset: 00Ch */ + __IO uint32_t GRSTCTL; /*!< Core Reset Register Address offset: 010h */ + __IO uint32_t GINTSTS; /*!< Core Interrupt Register Address offset: 014h */ + __IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register Address offset: 018h */ + __IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register Address offset: 01Ch */ + __IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register Address offset: 020h */ + __IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register Address offset: 024h */ + __IO uint32_t DIEPTXF0_HNPTXFSIZ; /*!< EP0 / Non Periodic Tx FIFO Size Register Address offset: 028h */ + __IO uint32_t HNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg Address offset: 02Ch */ + uint32_t Reserved30[2]; /*!< Reserved 030h*/ + __IO uint32_t GCCFG; /*!< General Purpose IO Register Address offset: 038h */ + __IO uint32_t CID; /*!< User ID Register Address offset: 03Ch */ + uint32_t Reserved40[48]; /*!< Reserved 040h-0FFh */ + __IO uint32_t HPTXFSIZ; /*!< Host Periodic Tx FIFO Size Reg Address offset: 100h */ + __IO uint32_t DIEPTXF[0x0F]; /*!< dev Periodic Transmit FIFO Address offset: 0x104 */ +} USB_OTG_GlobalTypeDef; + +/** + * @brief __device_Registers + */ + +typedef struct +{ + __IO uint32_t DCFG; /*!< dev Configuration Register Address offset: 800h*/ + __IO uint32_t DCTL; /*!< dev Control Register Address offset: 804h*/ + __IO uint32_t DSTS; /*!< dev Status Register (RO) Address offset: 808h*/ + uint32_t Reserved0C; /*!< Reserved 80Ch*/ + __IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask Address offset: 810h*/ + __IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask Address offset: 814h*/ + __IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg Address offset: 818h*/ + __IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask Address offset: 81Ch*/ + uint32_t Reserved20; /*!< Reserved 820h*/ + uint32_t Reserved9; /*!< Reserved 824h*/ + __IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register Address offset: 828h*/ + __IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register Address offset: 82Ch*/ + __IO uint32_t DTHRCTL; /*!< dev thr Address offset: 830h*/ + __IO uint32_t DIEPEMPMSK; /*!< dev empty msk Address offset: 834h*/ + __IO uint32_t DEACHINT; /*!< dedicated EP interrupt Address offset: 838h*/ + __IO uint32_t DEACHMSK; /*!< dedicated EP msk Address offset: 83Ch*/ + uint32_t Reserved40; /*!< dedicated EP mask Address offset: 840h*/ + __IO uint32_t DINEP1MSK; /*!< dedicated EP mask Address offset: 844h*/ + uint32_t Reserved44[15]; /*!< Reserved 844-87Ch*/ + __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk Address offset: 884h*/ +} USB_OTG_DeviceTypeDef; + +/** + * @brief __IN_Endpoint-Specific_Register + */ + +typedef struct +{ + __IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/ + uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h*/ + __IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/ + uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch*/ + __IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/ + __IO uint32_t DIEPDMA; /*!< IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/ + __IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/ + uint32_t Reserved18; /*!< Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/ +} USB_OTG_INEndpointTypeDef; + +/** + * @brief __OUT_Endpoint-Specific_Registers + */ + +typedef struct +{ + __IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ + uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h*/ + __IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ + uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch*/ + __IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ + __IO uint32_t DOEPDMA; /*!< dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ + uint32_t Reserved18[2]; /*!< Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ +} USB_OTG_OUTEndpointTypeDef; + +/** + * @brief __Host_Mode_Register_Structures + */ + +typedef struct +{ + __IO uint32_t HCFG; /*!< Host Configuration Register 400h*/ + __IO uint32_t HFIR; /*!< Host Frame Interval Register 404h*/ + __IO uint32_t HFNUM; /*!< Host Frame Nbr/Frame Remaining 408h*/ + uint32_t Reserved40C; /*!< Reserved 40Ch*/ + __IO uint32_t HPTXSTS; /*!< Host Periodic Tx FIFO/ Queue Status 410h*/ + __IO uint32_t HAINT; /*!< Host All Channels Interrupt Register 414h*/ + __IO uint32_t HAINTMSK; /*!< Host All Channels Interrupt Mask 418h*/ +} USB_OTG_HostTypeDef; + +/** + * @brief __Host_Channel_Specific_Registers + */ + +typedef struct +{ + __IO uint32_t HCCHAR; + __IO uint32_t HCSPLT; + __IO uint32_t HCINT; + __IO uint32_t HCINTMSK; + __IO uint32_t HCTSIZ; + __IO uint32_t HCDMA; + uint32_t Reserved[2]; +} USB_OTG_HostChannelTypeDef; + +/*!< USB registers base address */ +#define USB_OTG_FS_PERIPH_BASE 0x50000000UL + +#define USB_OTG_GLOBAL_BASE 0x00000000UL +#define USB_OTG_DEVICE_BASE 0x00000800UL +#define USB_OTG_IN_ENDPOINT_BASE 0x00000900UL +#define USB_OTG_OUT_ENDPOINT_BASE 0x00000B00UL +#define USB_OTG_EP_REG_SIZE 0x00000020UL +#define USB_OTG_HOST_BASE 0x00000400UL +#define USB_OTG_HOST_PORT_BASE 0x00000440UL +#define USB_OTG_HOST_CHANNEL_BASE 0x00000500UL +#define USB_OTG_HOST_CHANNEL_SIZE 0x00000020UL +#define USB_OTG_PCGCCTL_BASE 0x00000E00UL +#define USB_OTG_FIFO_BASE 0x00001000UL +#define USB_OTG_FIFO_SIZE 0x00001000UL + +/******************************************************************************/ +/* */ +/* USB_OTG */ +/* */ +/******************************************************************************/ +/******************** Bit definition for USB_OTG_GOTGCTL register ***********/ +#define USB_OTG_GOTGCTL_SRQSCS_Pos (0U) +#define USB_OTG_GOTGCTL_SRQSCS_Msk (0x1UL << USB_OTG_GOTGCTL_SRQSCS_Pos) /*!< 0x00000001 */ +#define USB_OTG_GOTGCTL_SRQSCS USB_OTG_GOTGCTL_SRQSCS_Msk /*!< Session request success */ +#define USB_OTG_GOTGCTL_SRQ_Pos (1U) +#define USB_OTG_GOTGCTL_SRQ_Msk (0x1UL << USB_OTG_GOTGCTL_SRQ_Pos) /*!< 0x00000002 */ +#define USB_OTG_GOTGCTL_SRQ USB_OTG_GOTGCTL_SRQ_Msk /*!< Session request */ +#define USB_OTG_GOTGCTL_HNGSCS_Pos (8U) +#define USB_OTG_GOTGCTL_HNGSCS_Msk (0x1UL << USB_OTG_GOTGCTL_HNGSCS_Pos) /*!< 0x00000100 */ +#define USB_OTG_GOTGCTL_HNGSCS USB_OTG_GOTGCTL_HNGSCS_Msk /*!< Host set HNP enable */ +#define USB_OTG_GOTGCTL_HNPRQ_Pos (9U) +#define USB_OTG_GOTGCTL_HNPRQ_Msk (0x1UL << USB_OTG_GOTGCTL_HNPRQ_Pos) /*!< 0x00000200 */ +#define USB_OTG_GOTGCTL_HNPRQ USB_OTG_GOTGCTL_HNPRQ_Msk /*!< HNP request */ +#define USB_OTG_GOTGCTL_HSHNPEN_Pos (10U) +#define USB_OTG_GOTGCTL_HSHNPEN_Msk (0x1UL << USB_OTG_GOTGCTL_HSHNPEN_Pos) /*!< 0x00000400 */ +#define USB_OTG_GOTGCTL_HSHNPEN USB_OTG_GOTGCTL_HSHNPEN_Msk /*!< Host set HNP enable */ +#define USB_OTG_GOTGCTL_DHNPEN_Pos (11U) +#define USB_OTG_GOTGCTL_DHNPEN_Msk (0x1UL << USB_OTG_GOTGCTL_DHNPEN_Pos) /*!< 0x00000800 */ +#define USB_OTG_GOTGCTL_DHNPEN USB_OTG_GOTGCTL_DHNPEN_Msk /*!< Device HNP enabled */ +#define USB_OTG_GOTGCTL_CIDSTS_Pos (16U) +#define USB_OTG_GOTGCTL_CIDSTS_Msk (0x1UL << USB_OTG_GOTGCTL_CIDSTS_Pos) /*!< 0x00010000 */ +#define USB_OTG_GOTGCTL_CIDSTS USB_OTG_GOTGCTL_CIDSTS_Msk /*!< Connector ID status */ +#define USB_OTG_GOTGCTL_DBCT_Pos (17U) +#define USB_OTG_GOTGCTL_DBCT_Msk (0x1UL << USB_OTG_GOTGCTL_DBCT_Pos) /*!< 0x00020000 */ +#define USB_OTG_GOTGCTL_DBCT USB_OTG_GOTGCTL_DBCT_Msk /*!< Long/short debounce time */ +#define USB_OTG_GOTGCTL_ASVLD_Pos (18U) +#define USB_OTG_GOTGCTL_ASVLD_Msk (0x1UL << USB_OTG_GOTGCTL_ASVLD_Pos) /*!< 0x00040000 */ +#define USB_OTG_GOTGCTL_ASVLD USB_OTG_GOTGCTL_ASVLD_Msk /*!< A-session valid */ +#define USB_OTG_GOTGCTL_BSVLD_Pos (19U) +#define USB_OTG_GOTGCTL_BSVLD_Msk (0x1UL << USB_OTG_GOTGCTL_BSVLD_Pos) /*!< 0x00080000 */ +#define USB_OTG_GOTGCTL_BSVLD USB_OTG_GOTGCTL_BSVLD_Msk /*!< B-session valid */ + +/******************** Bit definition for USB_OTG_HCFG register ********************/ + +#define USB_OTG_HCFG_FSLSPCS_Pos (0U) +#define USB_OTG_HCFG_FSLSPCS_Msk (0x3UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000003 */ +#define USB_OTG_HCFG_FSLSPCS USB_OTG_HCFG_FSLSPCS_Msk /*!< FS/LS PHY clock select */ +#define USB_OTG_HCFG_FSLSPCS_0 (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */ +#define USB_OTG_HCFG_FSLSPCS_1 (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */ +#define USB_OTG_HCFG_FSLSS_Pos (2U) +#define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */ +#define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */ + +/******************** Bit definition for USB_OTG_DCFG register ********************/ + +#define USB_OTG_DCFG_DSPD_Pos (0U) +#define USB_OTG_DCFG_DSPD_Msk (0x3UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000003 */ +#define USB_OTG_DCFG_DSPD USB_OTG_DCFG_DSPD_Msk /*!< Device speed */ +#define USB_OTG_DCFG_DSPD_0 (0x1UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000001 */ +#define USB_OTG_DCFG_DSPD_1 (0x2UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000002 */ +#define USB_OTG_DCFG_NZLSOHSK_Pos (2U) +#define USB_OTG_DCFG_NZLSOHSK_Msk (0x1UL << USB_OTG_DCFG_NZLSOHSK_Pos) /*!< 0x00000004 */ +#define USB_OTG_DCFG_NZLSOHSK USB_OTG_DCFG_NZLSOHSK_Msk /*!< Nonzero-length status OUT handshake */ + +#define USB_OTG_DCFG_DAD_Pos (4U) +#define USB_OTG_DCFG_DAD_Msk (0x7FUL << USB_OTG_DCFG_DAD_Pos) /*!< 0x000007F0 */ +#define USB_OTG_DCFG_DAD USB_OTG_DCFG_DAD_Msk /*!< Device address */ +#define USB_OTG_DCFG_DAD_0 (0x01UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000010 */ +#define USB_OTG_DCFG_DAD_1 (0x02UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000020 */ +#define USB_OTG_DCFG_DAD_2 (0x04UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000040 */ +#define USB_OTG_DCFG_DAD_3 (0x08UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000080 */ +#define USB_OTG_DCFG_DAD_4 (0x10UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000100 */ +#define USB_OTG_DCFG_DAD_5 (0x20UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000200 */ +#define USB_OTG_DCFG_DAD_6 (0x40UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000400 */ + +#define USB_OTG_DCFG_PFIVL_Pos (11U) +#define USB_OTG_DCFG_PFIVL_Msk (0x3UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001800 */ +#define USB_OTG_DCFG_PFIVL USB_OTG_DCFG_PFIVL_Msk /*!< Periodic (micro)frame interval */ +#define USB_OTG_DCFG_PFIVL_0 (0x1UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00000800 */ +#define USB_OTG_DCFG_PFIVL_1 (0x2UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001000 */ + +#define USB_OTG_DCFG_PERSCHIVL_Pos (24U) +#define USB_OTG_DCFG_PERSCHIVL_Msk (0x3UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x03000000 */ +#define USB_OTG_DCFG_PERSCHIVL USB_OTG_DCFG_PERSCHIVL_Msk /*!< Periodic scheduling interval */ +#define USB_OTG_DCFG_PERSCHIVL_0 (0x1UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x01000000 */ +#define USB_OTG_DCFG_PERSCHIVL_1 (0x2UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x02000000 */ + +/******************** Bit definition for USB_OTG_PCGCR register ********************/ +#define USB_OTG_PCGCR_STPPCLK_Pos (0U) +#define USB_OTG_PCGCR_STPPCLK_Msk (0x1UL << USB_OTG_PCGCR_STPPCLK_Pos) /*!< 0x00000001 */ +#define USB_OTG_PCGCR_STPPCLK USB_OTG_PCGCR_STPPCLK_Msk /*!< Stop PHY clock */ +#define USB_OTG_PCGCR_GATEHCLK_Pos (1U) +#define USB_OTG_PCGCR_GATEHCLK_Msk (0x1UL << USB_OTG_PCGCR_GATEHCLK_Pos) /*!< 0x00000002 */ +#define USB_OTG_PCGCR_GATEHCLK USB_OTG_PCGCR_GATEHCLK_Msk /*!< Gate HCLK */ +#define USB_OTG_PCGCR_PHYSUSP_Pos (4U) +#define USB_OTG_PCGCR_PHYSUSP_Msk (0x1UL << USB_OTG_PCGCR_PHYSUSP_Pos) /*!< 0x00000010 */ +#define USB_OTG_PCGCR_PHYSUSP USB_OTG_PCGCR_PHYSUSP_Msk /*!< PHY suspended */ + +/******************** Bit definition for USB_OTG_GOTGINT register ********************/ +#define USB_OTG_GOTGINT_SEDET_Pos (2U) +#define USB_OTG_GOTGINT_SEDET_Msk (0x1UL << USB_OTG_GOTGINT_SEDET_Pos) /*!< 0x00000004 */ +#define USB_OTG_GOTGINT_SEDET USB_OTG_GOTGINT_SEDET_Msk /*!< Session end detected */ +#define USB_OTG_GOTGINT_SRSSCHG_Pos (8U) +#define USB_OTG_GOTGINT_SRSSCHG_Msk (0x1UL << USB_OTG_GOTGINT_SRSSCHG_Pos) /*!< 0x00000100 */ +#define USB_OTG_GOTGINT_SRSSCHG USB_OTG_GOTGINT_SRSSCHG_Msk /*!< Session request success status change */ +#define USB_OTG_GOTGINT_HNSSCHG_Pos (9U) +#define USB_OTG_GOTGINT_HNSSCHG_Msk (0x1UL << USB_OTG_GOTGINT_HNSSCHG_Pos) /*!< 0x00000200 */ +#define USB_OTG_GOTGINT_HNSSCHG USB_OTG_GOTGINT_HNSSCHG_Msk /*!< Host negotiation success status change */ +#define USB_OTG_GOTGINT_HNGDET_Pos (17U) +#define USB_OTG_GOTGINT_HNGDET_Msk (0x1UL << USB_OTG_GOTGINT_HNGDET_Pos) /*!< 0x00020000 */ +#define USB_OTG_GOTGINT_HNGDET USB_OTG_GOTGINT_HNGDET_Msk /*!< Host negotiation detected */ +#define USB_OTG_GOTGINT_ADTOCHG_Pos (18U) +#define USB_OTG_GOTGINT_ADTOCHG_Msk (0x1UL << USB_OTG_GOTGINT_ADTOCHG_Pos) /*!< 0x00040000 */ +#define USB_OTG_GOTGINT_ADTOCHG USB_OTG_GOTGINT_ADTOCHG_Msk /*!< A-device timeout change */ +#define USB_OTG_GOTGINT_DBCDNE_Pos (19U) +#define USB_OTG_GOTGINT_DBCDNE_Msk (0x1UL << USB_OTG_GOTGINT_DBCDNE_Pos) /*!< 0x00080000 */ +#define USB_OTG_GOTGINT_DBCDNE USB_OTG_GOTGINT_DBCDNE_Msk /*!< Debounce done */ + +/******************** Bit definition for USB_OTG_DCTL register ********************/ +#define USB_OTG_DCTL_RWUSIG_Pos (0U) +#define USB_OTG_DCTL_RWUSIG_Msk (0x1UL << USB_OTG_DCTL_RWUSIG_Pos) /*!< 0x00000001 */ +#define USB_OTG_DCTL_RWUSIG USB_OTG_DCTL_RWUSIG_Msk /*!< Remote wakeup signaling */ +#define USB_OTG_DCTL_SDIS_Pos (1U) +#define USB_OTG_DCTL_SDIS_Msk (0x1UL << USB_OTG_DCTL_SDIS_Pos) /*!< 0x00000002 */ +#define USB_OTG_DCTL_SDIS USB_OTG_DCTL_SDIS_Msk /*!< Soft disconnect */ +#define USB_OTG_DCTL_GINSTS_Pos (2U) +#define USB_OTG_DCTL_GINSTS_Msk (0x1UL << USB_OTG_DCTL_GINSTS_Pos) /*!< 0x00000004 */ +#define USB_OTG_DCTL_GINSTS USB_OTG_DCTL_GINSTS_Msk /*!< Global IN NAK status */ +#define USB_OTG_DCTL_GONSTS_Pos (3U) +#define USB_OTG_DCTL_GONSTS_Msk (0x1UL << USB_OTG_DCTL_GONSTS_Pos) /*!< 0x00000008 */ +#define USB_OTG_DCTL_GONSTS USB_OTG_DCTL_GONSTS_Msk /*!< Global OUT NAK status */ + +#define USB_OTG_DCTL_TCTL_Pos (4U) +#define USB_OTG_DCTL_TCTL_Msk (0x7UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000070 */ +#define USB_OTG_DCTL_TCTL USB_OTG_DCTL_TCTL_Msk /*!< Test control */ +#define USB_OTG_DCTL_TCTL_0 (0x1UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000010 */ +#define USB_OTG_DCTL_TCTL_1 (0x2UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000020 */ +#define USB_OTG_DCTL_TCTL_2 (0x4UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000040 */ +#define USB_OTG_DCTL_SGINAK_Pos (7U) +#define USB_OTG_DCTL_SGINAK_Msk (0x1UL << USB_OTG_DCTL_SGINAK_Pos) /*!< 0x00000080 */ +#define USB_OTG_DCTL_SGINAK USB_OTG_DCTL_SGINAK_Msk /*!< Set global IN NAK */ +#define USB_OTG_DCTL_CGINAK_Pos (8U) +#define USB_OTG_DCTL_CGINAK_Msk (0x1UL << USB_OTG_DCTL_CGINAK_Pos) /*!< 0x00000100 */ +#define USB_OTG_DCTL_CGINAK USB_OTG_DCTL_CGINAK_Msk /*!< Clear global IN NAK */ +#define USB_OTG_DCTL_SGONAK_Pos (9U) +#define USB_OTG_DCTL_SGONAK_Msk (0x1UL << USB_OTG_DCTL_SGONAK_Pos) /*!< 0x00000200 */ +#define USB_OTG_DCTL_SGONAK USB_OTG_DCTL_SGONAK_Msk /*!< Set global OUT NAK */ +#define USB_OTG_DCTL_CGONAK_Pos (10U) +#define USB_OTG_DCTL_CGONAK_Msk (0x1UL << USB_OTG_DCTL_CGONAK_Pos) /*!< 0x00000400 */ +#define USB_OTG_DCTL_CGONAK USB_OTG_DCTL_CGONAK_Msk /*!< Clear global OUT NAK */ +#define USB_OTG_DCTL_POPRGDNE_Pos (11U) +#define USB_OTG_DCTL_POPRGDNE_Msk (0x1UL << USB_OTG_DCTL_POPRGDNE_Pos) /*!< 0x00000800 */ +#define USB_OTG_DCTL_POPRGDNE USB_OTG_DCTL_POPRGDNE_Msk /*!< Power-on programming done */ + +/******************** Bit definition for USB_OTG_HFIR register ********************/ +#define USB_OTG_HFIR_FRIVL_Pos (0U) +#define USB_OTG_HFIR_FRIVL_Msk (0xFFFFUL << USB_OTG_HFIR_FRIVL_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HFIR_FRIVL USB_OTG_HFIR_FRIVL_Msk /*!< Frame interval */ + +/******************** Bit definition for USB_OTG_HFNUM register ********************/ +#define USB_OTG_HFNUM_FRNUM_Pos (0U) +#define USB_OTG_HFNUM_FRNUM_Msk (0xFFFFUL << USB_OTG_HFNUM_FRNUM_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HFNUM_FRNUM USB_OTG_HFNUM_FRNUM_Msk /*!< Frame number */ +#define USB_OTG_HFNUM_FTREM_Pos (16U) +#define USB_OTG_HFNUM_FTREM_Msk (0xFFFFUL << USB_OTG_HFNUM_FTREM_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_HFNUM_FTREM USB_OTG_HFNUM_FTREM_Msk /*!< Frame time remaining */ + +/******************** Bit definition for USB_OTG_DSTS register ********************/ +#define USB_OTG_DSTS_SUSPSTS_Pos (0U) +#define USB_OTG_DSTS_SUSPSTS_Msk (0x1UL << USB_OTG_DSTS_SUSPSTS_Pos) /*!< 0x00000001 */ +#define USB_OTG_DSTS_SUSPSTS USB_OTG_DSTS_SUSPSTS_Msk /*!< Suspend status */ + +#define USB_OTG_DSTS_ENUMSPD_Pos (1U) +#define USB_OTG_DSTS_ENUMSPD_Msk (0x3UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000006 */ +#define USB_OTG_DSTS_ENUMSPD USB_OTG_DSTS_ENUMSPD_Msk /*!< Enumerated speed */ +#define USB_OTG_DSTS_ENUMSPD_0 (0x1UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000002 */ +#define USB_OTG_DSTS_ENUMSPD_1 (0x2UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000004 */ +#define USB_OTG_DSTS_EERR_Pos (3U) +#define USB_OTG_DSTS_EERR_Msk (0x1UL << USB_OTG_DSTS_EERR_Pos) /*!< 0x00000008 */ +#define USB_OTG_DSTS_EERR USB_OTG_DSTS_EERR_Msk /*!< Erratic error */ +#define USB_OTG_DSTS_FNSOF_Pos (8U) +#define USB_OTG_DSTS_FNSOF_Msk (0x3FFFUL << USB_OTG_DSTS_FNSOF_Pos) /*!< 0x003FFF00 */ +#define USB_OTG_DSTS_FNSOF USB_OTG_DSTS_FNSOF_Msk /*!< Frame number of the received SOF */ + +/******************** Bit definition for USB_OTG_GAHBCFG register ********************/ +#define USB_OTG_GAHBCFG_GINT_Pos (0U) +#define USB_OTG_GAHBCFG_GINT_Msk (0x1UL << USB_OTG_GAHBCFG_GINT_Pos) /*!< 0x00000001 */ +#define USB_OTG_GAHBCFG_GINT USB_OTG_GAHBCFG_GINT_Msk /*!< Global interrupt mask */ +#define USB_OTG_GAHBCFG_HBSTLEN_Pos (1U) +#define USB_OTG_GAHBCFG_HBSTLEN_Msk (0xFUL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< 0x0000001E */ +#define USB_OTG_GAHBCFG_HBSTLEN USB_OTG_GAHBCFG_HBSTLEN_Msk /*!< Burst length/type */ +#define USB_OTG_GAHBCFG_HBSTLEN_0 (0x0UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< Single */ +#define USB_OTG_GAHBCFG_HBSTLEN_1 (0x1UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR */ +#define USB_OTG_GAHBCFG_HBSTLEN_2 (0x3UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR4 */ +#define USB_OTG_GAHBCFG_HBSTLEN_3 (0x5UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR8 */ +#define USB_OTG_GAHBCFG_HBSTLEN_4 (0x7UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR16 */ +#define USB_OTG_GAHBCFG_DMAEN_Pos (5U) +#define USB_OTG_GAHBCFG_DMAEN_Msk (0x1UL << USB_OTG_GAHBCFG_DMAEN_Pos) /*!< 0x00000020 */ +#define USB_OTG_GAHBCFG_DMAEN USB_OTG_GAHBCFG_DMAEN_Msk /*!< DMA enable */ +#define USB_OTG_GAHBCFG_TXFELVL_Pos (7U) +#define USB_OTG_GAHBCFG_TXFELVL_Msk (0x1UL << USB_OTG_GAHBCFG_TXFELVL_Pos) /*!< 0x00000080 */ +#define USB_OTG_GAHBCFG_TXFELVL USB_OTG_GAHBCFG_TXFELVL_Msk /*!< TxFIFO empty level */ +#define USB_OTG_GAHBCFG_PTXFELVL_Pos (8U) +#define USB_OTG_GAHBCFG_PTXFELVL_Msk (0x1UL << USB_OTG_GAHBCFG_PTXFELVL_Pos) /*!< 0x00000100 */ +#define USB_OTG_GAHBCFG_PTXFELVL USB_OTG_GAHBCFG_PTXFELVL_Msk /*!< Periodic TxFIFO empty level */ + +/******************** Bit definition for USB_OTG_GUSBCFG register ********************/ + +#define USB_OTG_GUSBCFG_TOCAL_Pos (0U) +#define USB_OTG_GUSBCFG_TOCAL_Msk (0x7UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000007 */ +#define USB_OTG_GUSBCFG_TOCAL USB_OTG_GUSBCFG_TOCAL_Msk /*!< FS timeout calibration */ +#define USB_OTG_GUSBCFG_TOCAL_0 (0x1UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000001 */ +#define USB_OTG_GUSBCFG_TOCAL_1 (0x2UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000002 */ +#define USB_OTG_GUSBCFG_TOCAL_2 (0x4UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000004 */ +#define USB_OTG_GUSBCFG_PHYSEL_Pos (6U) +#define USB_OTG_GUSBCFG_PHYSEL_Msk (0x1UL << USB_OTG_GUSBCFG_PHYSEL_Pos) /*!< 0x00000040 */ +#define USB_OTG_GUSBCFG_PHYSEL USB_OTG_GUSBCFG_PHYSEL_Msk /*!< USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */ +#define USB_OTG_GUSBCFG_SRPCAP_Pos (8U) +#define USB_OTG_GUSBCFG_SRPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_SRPCAP_Pos) /*!< 0x00000100 */ +#define USB_OTG_GUSBCFG_SRPCAP USB_OTG_GUSBCFG_SRPCAP_Msk /*!< SRP-capable */ +#define USB_OTG_GUSBCFG_HNPCAP_Pos (9U) +#define USB_OTG_GUSBCFG_HNPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_HNPCAP_Pos) /*!< 0x00000200 */ +#define USB_OTG_GUSBCFG_HNPCAP USB_OTG_GUSBCFG_HNPCAP_Msk /*!< HNP-capable */ +#define USB_OTG_GUSBCFG_TRDT_Pos (10U) +#define USB_OTG_GUSBCFG_TRDT_Msk (0xFUL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00003C00 */ +#define USB_OTG_GUSBCFG_TRDT USB_OTG_GUSBCFG_TRDT_Msk /*!< USB turnaround time */ +#define USB_OTG_GUSBCFG_TRDT_0 (0x1UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000400 */ +#define USB_OTG_GUSBCFG_TRDT_1 (0x2UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000800 */ +#define USB_OTG_GUSBCFG_TRDT_2 (0x4UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00001000 */ +#define USB_OTG_GUSBCFG_TRDT_3 (0x8UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00002000 */ +#define USB_OTG_GUSBCFG_PHYLPCS_Pos (15U) +#define USB_OTG_GUSBCFG_PHYLPCS_Msk (0x1UL << USB_OTG_GUSBCFG_PHYLPCS_Pos) /*!< 0x00008000 */ +#define USB_OTG_GUSBCFG_PHYLPCS USB_OTG_GUSBCFG_PHYLPCS_Msk /*!< PHY Low-power clock select */ +#define USB_OTG_GUSBCFG_ULPIFSLS_Pos (17U) +#define USB_OTG_GUSBCFG_ULPIFSLS_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIFSLS_Pos) /*!< 0x00020000 */ +#define USB_OTG_GUSBCFG_ULPIFSLS USB_OTG_GUSBCFG_ULPIFSLS_Msk /*!< ULPI FS/LS select */ +#define USB_OTG_GUSBCFG_ULPIAR_Pos (18U) +#define USB_OTG_GUSBCFG_ULPIAR_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIAR_Pos) /*!< 0x00040000 */ +#define USB_OTG_GUSBCFG_ULPIAR USB_OTG_GUSBCFG_ULPIAR_Msk /*!< ULPI Auto-resume */ +#define USB_OTG_GUSBCFG_ULPICSM_Pos (19U) +#define USB_OTG_GUSBCFG_ULPICSM_Msk (0x1UL << USB_OTG_GUSBCFG_ULPICSM_Pos) /*!< 0x00080000 */ +#define USB_OTG_GUSBCFG_ULPICSM USB_OTG_GUSBCFG_ULPICSM_Msk /*!< ULPI Clock SuspendM */ +#define USB_OTG_GUSBCFG_ULPIEVBUSD_Pos (20U) +#define USB_OTG_GUSBCFG_ULPIEVBUSD_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSD_Pos) /*!< 0x00100000 */ +#define USB_OTG_GUSBCFG_ULPIEVBUSD USB_OTG_GUSBCFG_ULPIEVBUSD_Msk /*!< ULPI External VBUS Drive */ +#define USB_OTG_GUSBCFG_ULPIEVBUSI_Pos (21U) +#define USB_OTG_GUSBCFG_ULPIEVBUSI_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSI_Pos) /*!< 0x00200000 */ +#define USB_OTG_GUSBCFG_ULPIEVBUSI USB_OTG_GUSBCFG_ULPIEVBUSI_Msk /*!< ULPI external VBUS indicator */ +#define USB_OTG_GUSBCFG_TSDPS_Pos (22U) +#define USB_OTG_GUSBCFG_TSDPS_Msk (0x1UL << USB_OTG_GUSBCFG_TSDPS_Pos) /*!< 0x00400000 */ +#define USB_OTG_GUSBCFG_TSDPS USB_OTG_GUSBCFG_TSDPS_Msk /*!< TermSel DLine pulsing selection */ +#define USB_OTG_GUSBCFG_PCCI_Pos (23U) +#define USB_OTG_GUSBCFG_PCCI_Msk (0x1UL << USB_OTG_GUSBCFG_PCCI_Pos) /*!< 0x00800000 */ +#define USB_OTG_GUSBCFG_PCCI USB_OTG_GUSBCFG_PCCI_Msk /*!< Indicator complement */ +#define USB_OTG_GUSBCFG_PTCI_Pos (24U) +#define USB_OTG_GUSBCFG_PTCI_Msk (0x1UL << USB_OTG_GUSBCFG_PTCI_Pos) /*!< 0x01000000 */ +#define USB_OTG_GUSBCFG_PTCI USB_OTG_GUSBCFG_PTCI_Msk /*!< Indicator pass through */ +#define USB_OTG_GUSBCFG_ULPIIPD_Pos (25U) +#define USB_OTG_GUSBCFG_ULPIIPD_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIIPD_Pos) /*!< 0x02000000 */ +#define USB_OTG_GUSBCFG_ULPIIPD USB_OTG_GUSBCFG_ULPIIPD_Msk /*!< ULPI interface protect disable */ +#define USB_OTG_GUSBCFG_FHMOD_Pos (29U) +#define USB_OTG_GUSBCFG_FHMOD_Msk (0x1UL << USB_OTG_GUSBCFG_FHMOD_Pos) /*!< 0x20000000 */ +#define USB_OTG_GUSBCFG_FHMOD USB_OTG_GUSBCFG_FHMOD_Msk /*!< Forced host mode */ +#define USB_OTG_GUSBCFG_FDMOD_Pos (30U) +#define USB_OTG_GUSBCFG_FDMOD_Msk (0x1UL << USB_OTG_GUSBCFG_FDMOD_Pos) /*!< 0x40000000 */ +#define USB_OTG_GUSBCFG_FDMOD USB_OTG_GUSBCFG_FDMOD_Msk /*!< Forced peripheral mode */ +#define USB_OTG_GUSBCFG_CTXPKT_Pos (31U) +#define USB_OTG_GUSBCFG_CTXPKT_Msk (0x1UL << USB_OTG_GUSBCFG_CTXPKT_Pos) /*!< 0x80000000 */ +#define USB_OTG_GUSBCFG_CTXPKT USB_OTG_GUSBCFG_CTXPKT_Msk /*!< Corrupt Tx packet */ + +/******************** Bit definition for USB_OTG_GRSTCTL register ********************/ +#define USB_OTG_GRSTCTL_CSRST_Pos (0U) +#define USB_OTG_GRSTCTL_CSRST_Msk (0x1UL << USB_OTG_GRSTCTL_CSRST_Pos) /*!< 0x00000001 */ +#define USB_OTG_GRSTCTL_CSRST USB_OTG_GRSTCTL_CSRST_Msk /*!< Core soft reset */ +#define USB_OTG_GRSTCTL_HSRST_Pos (1U) +#define USB_OTG_GRSTCTL_HSRST_Msk (0x1UL << USB_OTG_GRSTCTL_HSRST_Pos) /*!< 0x00000002 */ +#define USB_OTG_GRSTCTL_HSRST USB_OTG_GRSTCTL_HSRST_Msk /*!< HCLK soft reset */ +#define USB_OTG_GRSTCTL_FCRST_Pos (2U) +#define USB_OTG_GRSTCTL_FCRST_Msk (0x1UL << USB_OTG_GRSTCTL_FCRST_Pos) /*!< 0x00000004 */ +#define USB_OTG_GRSTCTL_FCRST USB_OTG_GRSTCTL_FCRST_Msk /*!< Host frame counter reset */ +#define USB_OTG_GRSTCTL_RXFFLSH_Pos (4U) +#define USB_OTG_GRSTCTL_RXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_RXFFLSH_Pos) /*!< 0x00000010 */ +#define USB_OTG_GRSTCTL_RXFFLSH USB_OTG_GRSTCTL_RXFFLSH_Msk /*!< RxFIFO flush */ +#define USB_OTG_GRSTCTL_TXFFLSH_Pos (5U) +#define USB_OTG_GRSTCTL_TXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_TXFFLSH_Pos) /*!< 0x00000020 */ +#define USB_OTG_GRSTCTL_TXFFLSH USB_OTG_GRSTCTL_TXFFLSH_Msk /*!< TxFIFO flush */ + + +#define USB_OTG_GRSTCTL_TXFNUM_Pos (6U) +#define USB_OTG_GRSTCTL_TXFNUM_Msk (0x1FUL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x000007C0 */ +#define USB_OTG_GRSTCTL_TXFNUM USB_OTG_GRSTCTL_TXFNUM_Msk /*!< TxFIFO number */ +#define USB_OTG_GRSTCTL_TXFNUM_0 (0x01UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000040 */ +#define USB_OTG_GRSTCTL_TXFNUM_1 (0x02UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000080 */ +#define USB_OTG_GRSTCTL_TXFNUM_2 (0x04UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000100 */ +#define USB_OTG_GRSTCTL_TXFNUM_3 (0x08UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000200 */ +#define USB_OTG_GRSTCTL_TXFNUM_4 (0x10UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000400 */ +#define USB_OTG_GRSTCTL_DMAREQ_Pos (30U) +#define USB_OTG_GRSTCTL_DMAREQ_Msk (0x1UL << USB_OTG_GRSTCTL_DMAREQ_Pos) /*!< 0x40000000 */ +#define USB_OTG_GRSTCTL_DMAREQ USB_OTG_GRSTCTL_DMAREQ_Msk /*!< DMA request signal */ +#define USB_OTG_GRSTCTL_AHBIDL_Pos (31U) +#define USB_OTG_GRSTCTL_AHBIDL_Msk (0x1UL << USB_OTG_GRSTCTL_AHBIDL_Pos) /*!< 0x80000000 */ +#define USB_OTG_GRSTCTL_AHBIDL USB_OTG_GRSTCTL_AHBIDL_Msk /*!< AHB master idle */ + +/******************** Bit definition for USB_OTG_DIEPMSK register ********************/ +#define USB_OTG_DIEPMSK_XFRCM_Pos (0U) +#define USB_OTG_DIEPMSK_XFRCM_Msk (0x1UL << USB_OTG_DIEPMSK_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_DIEPMSK_XFRCM USB_OTG_DIEPMSK_XFRCM_Msk /*!< Transfer completed interrupt mask */ +#define USB_OTG_DIEPMSK_EPDM_Pos (1U) +#define USB_OTG_DIEPMSK_EPDM_Msk (0x1UL << USB_OTG_DIEPMSK_EPDM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DIEPMSK_EPDM USB_OTG_DIEPMSK_EPDM_Msk /*!< Endpoint disabled interrupt mask */ +#define USB_OTG_DIEPMSK_TOM_Pos (3U) +#define USB_OTG_DIEPMSK_TOM_Msk (0x1UL << USB_OTG_DIEPMSK_TOM_Pos) /*!< 0x00000008 */ +#define USB_OTG_DIEPMSK_TOM USB_OTG_DIEPMSK_TOM_Msk /*!< Timeout condition mask (nonisochronous endpoints) */ +#define USB_OTG_DIEPMSK_ITTXFEMSK_Pos (4U) +#define USB_OTG_DIEPMSK_ITTXFEMSK_Msk (0x1UL << USB_OTG_DIEPMSK_ITTXFEMSK_Pos) /*!< 0x00000010 */ +#define USB_OTG_DIEPMSK_ITTXFEMSK USB_OTG_DIEPMSK_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ +#define USB_OTG_DIEPMSK_INEPNMM_Pos (5U) +#define USB_OTG_DIEPMSK_INEPNMM_Msk (0x1UL << USB_OTG_DIEPMSK_INEPNMM_Pos) /*!< 0x00000020 */ +#define USB_OTG_DIEPMSK_INEPNMM USB_OTG_DIEPMSK_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ +#define USB_OTG_DIEPMSK_INEPNEM_Pos (6U) +#define USB_OTG_DIEPMSK_INEPNEM_Msk (0x1UL << USB_OTG_DIEPMSK_INEPNEM_Pos) /*!< 0x00000040 */ +#define USB_OTG_DIEPMSK_INEPNEM USB_OTG_DIEPMSK_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ +#define USB_OTG_DIEPMSK_TXFURM_Pos (8U) +#define USB_OTG_DIEPMSK_TXFURM_Msk (0x1UL << USB_OTG_DIEPMSK_TXFURM_Pos) /*!< 0x00000100 */ +#define USB_OTG_DIEPMSK_TXFURM USB_OTG_DIEPMSK_TXFURM_Msk /*!< FIFO underrun mask */ +#define USB_OTG_DIEPMSK_BIM_Pos (9U) +#define USB_OTG_DIEPMSK_BIM_Msk (0x1UL << USB_OTG_DIEPMSK_BIM_Pos) /*!< 0x00000200 */ +#define USB_OTG_DIEPMSK_BIM USB_OTG_DIEPMSK_BIM_Msk /*!< BNA interrupt mask */ + +/******************** Bit definition for USB_OTG_HPTXSTS register ********************/ +#define USB_OTG_HPTXSTS_PTXFSAVL_Pos (0U) +#define USB_OTG_HPTXSTS_PTXFSAVL_Msk (0xFFFFUL << USB_OTG_HPTXSTS_PTXFSAVL_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HPTXSTS_PTXFSAVL USB_OTG_HPTXSTS_PTXFSAVL_Msk /*!< Periodic transmit data FIFO space available */ +#define USB_OTG_HPTXSTS_PTXQSAV_Pos (16U) +#define USB_OTG_HPTXSTS_PTXQSAV_Msk (0xFFUL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00FF0000 */ +#define USB_OTG_HPTXSTS_PTXQSAV USB_OTG_HPTXSTS_PTXQSAV_Msk /*!< Periodic transmit request queue space available */ +#define USB_OTG_HPTXSTS_PTXQSAV_0 (0x01UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00010000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_1 (0x02UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00020000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_2 (0x04UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00040000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_3 (0x08UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00080000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_4 (0x10UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00100000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_5 (0x20UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00200000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_6 (0x40UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00400000 */ +#define USB_OTG_HPTXSTS_PTXQSAV_7 (0x80UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00800000 */ + +#define USB_OTG_HPTXSTS_PTXQTOP_Pos (24U) +#define USB_OTG_HPTXSTS_PTXQTOP_Msk (0xFFUL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0xFF000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP USB_OTG_HPTXSTS_PTXQTOP_Msk /*!< Top of the periodic transmit request queue */ +#define USB_OTG_HPTXSTS_PTXQTOP_0 (0x01UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x01000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_1 (0x02UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x02000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_2 (0x04UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x04000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_3 (0x08UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x08000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_4 (0x10UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x10000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_5 (0x20UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x20000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_6 (0x40UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x40000000 */ +#define USB_OTG_HPTXSTS_PTXQTOP_7 (0x80UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x80000000 */ + +/******************** Bit definition for USB_OTG_HAINT register ********************/ +#define USB_OTG_HAINT_HAINT_Pos (0U) +#define USB_OTG_HAINT_HAINT_Msk (0xFFFFUL << USB_OTG_HAINT_HAINT_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HAINT_HAINT USB_OTG_HAINT_HAINT_Msk /*!< Channel interrupts */ + +/******************** Bit definition for USB_OTG_DOEPMSK register ********************/ +#define USB_OTG_DOEPMSK_XFRCM_Pos (0U) +#define USB_OTG_DOEPMSK_XFRCM_Msk (0x1UL << USB_OTG_DOEPMSK_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_DOEPMSK_XFRCM USB_OTG_DOEPMSK_XFRCM_Msk /*!< Transfer completed interrupt mask */ +#define USB_OTG_DOEPMSK_EPDM_Pos (1U) +#define USB_OTG_DOEPMSK_EPDM_Msk (0x1UL << USB_OTG_DOEPMSK_EPDM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DOEPMSK_EPDM USB_OTG_DOEPMSK_EPDM_Msk /*!< Endpoint disabled interrupt mask */ +#define USB_OTG_DOEPMSK_AHBERRM_Pos (2U) +#define USB_OTG_DOEPMSK_AHBERRM_Msk (0x1UL << USB_OTG_DOEPMSK_AHBERRM_Pos) /*!< 0x00000004 */ +#define USB_OTG_DOEPMSK_AHBERRM USB_OTG_DOEPMSK_AHBERRM_Msk /*!< OUT transaction AHB Error interrupt mask */ +#define USB_OTG_DOEPMSK_STUPM_Pos (3U) +#define USB_OTG_DOEPMSK_STUPM_Msk (0x1UL << USB_OTG_DOEPMSK_STUPM_Pos) /*!< 0x00000008 */ +#define USB_OTG_DOEPMSK_STUPM USB_OTG_DOEPMSK_STUPM_Msk /*!< SETUP phase done mask */ +#define USB_OTG_DOEPMSK_OTEPDM_Pos (4U) +#define USB_OTG_DOEPMSK_OTEPDM_Msk (0x1UL << USB_OTG_DOEPMSK_OTEPDM_Pos) /*!< 0x00000010 */ +#define USB_OTG_DOEPMSK_OTEPDM USB_OTG_DOEPMSK_OTEPDM_Msk /*!< OUT token received when endpoint disabled mask */ +#define USB_OTG_DOEPMSK_OTEPSPRM_Pos (5U) +#define USB_OTG_DOEPMSK_OTEPSPRM_Msk (0x1UL << USB_OTG_DOEPMSK_OTEPSPRM_Pos) /*!< 0x00000020 */ +#define USB_OTG_DOEPMSK_OTEPSPRM USB_OTG_DOEPMSK_OTEPSPRM_Msk /*!< Status Phase Received mask */ +#define USB_OTG_DOEPMSK_B2BSTUP_Pos (6U) +#define USB_OTG_DOEPMSK_B2BSTUP_Msk (0x1UL << USB_OTG_DOEPMSK_B2BSTUP_Pos) /*!< 0x00000040 */ +#define USB_OTG_DOEPMSK_B2BSTUP USB_OTG_DOEPMSK_B2BSTUP_Msk /*!< Back-to-back SETUP packets received mask */ +#define USB_OTG_DOEPMSK_OPEM_Pos (8U) +#define USB_OTG_DOEPMSK_OPEM_Msk (0x1UL << USB_OTG_DOEPMSK_OPEM_Pos) /*!< 0x00000100 */ +#define USB_OTG_DOEPMSK_OPEM USB_OTG_DOEPMSK_OPEM_Msk /*!< OUT packet error mask */ +#define USB_OTG_DOEPMSK_BOIM_Pos (9U) +#define USB_OTG_DOEPMSK_BOIM_Msk (0x1UL << USB_OTG_DOEPMSK_BOIM_Pos) /*!< 0x00000200 */ +#define USB_OTG_DOEPMSK_BOIM USB_OTG_DOEPMSK_BOIM_Msk /*!< BNA interrupt mask */ +#define USB_OTG_DOEPMSK_BERRM_Pos (12U) +#define USB_OTG_DOEPMSK_BERRM_Msk (0x1UL << USB_OTG_DOEPMSK_BERRM_Pos) /*!< 0x00001000 */ +#define USB_OTG_DOEPMSK_BERRM USB_OTG_DOEPMSK_BERRM_Msk /*!< Babble error interrupt mask */ +#define USB_OTG_DOEPMSK_NAKM_Pos (13U) +#define USB_OTG_DOEPMSK_NAKM_Msk (0x1UL << USB_OTG_DOEPMSK_NAKM_Pos) /*!< 0x00002000 */ +#define USB_OTG_DOEPMSK_NAKM USB_OTG_DOEPMSK_NAKM_Msk /*!< OUT Packet NAK interrupt mask */ +#define USB_OTG_DOEPMSK_NYETM_Pos (14U) +#define USB_OTG_DOEPMSK_NYETM_Msk (0x1UL << USB_OTG_DOEPMSK_NYETM_Pos) /*!< 0x00004000 */ +#define USB_OTG_DOEPMSK_NYETM USB_OTG_DOEPMSK_NYETM_Msk /*!< NYET interrupt mask */ +/******************** Bit definition for USB_OTG_GINTSTS register ********************/ +#define USB_OTG_GINTSTS_CMOD_Pos (0U) +#define USB_OTG_GINTSTS_CMOD_Msk (0x1UL << USB_OTG_GINTSTS_CMOD_Pos) /*!< 0x00000001 */ +#define USB_OTG_GINTSTS_CMOD USB_OTG_GINTSTS_CMOD_Msk /*!< Current mode of operation */ +#define USB_OTG_GINTSTS_MMIS_Pos (1U) +#define USB_OTG_GINTSTS_MMIS_Msk (0x1UL << USB_OTG_GINTSTS_MMIS_Pos) /*!< 0x00000002 */ +#define USB_OTG_GINTSTS_MMIS USB_OTG_GINTSTS_MMIS_Msk /*!< Mode mismatch interrupt */ +#define USB_OTG_GINTSTS_OTGINT_Pos (2U) +#define USB_OTG_GINTSTS_OTGINT_Msk (0x1UL << USB_OTG_GINTSTS_OTGINT_Pos) /*!< 0x00000004 */ +#define USB_OTG_GINTSTS_OTGINT USB_OTG_GINTSTS_OTGINT_Msk /*!< OTG interrupt */ +#define USB_OTG_GINTSTS_SOF_Pos (3U) +#define USB_OTG_GINTSTS_SOF_Msk (0x1UL << USB_OTG_GINTSTS_SOF_Pos) /*!< 0x00000008 */ +#define USB_OTG_GINTSTS_SOF USB_OTG_GINTSTS_SOF_Msk /*!< Start of frame */ +#define USB_OTG_GINTSTS_RXFLVL_Pos (4U) +#define USB_OTG_GINTSTS_RXFLVL_Msk (0x1UL << USB_OTG_GINTSTS_RXFLVL_Pos) /*!< 0x00000010 */ +#define USB_OTG_GINTSTS_RXFLVL USB_OTG_GINTSTS_RXFLVL_Msk /*!< RxFIFO nonempty */ +#define USB_OTG_GINTSTS_NPTXFE_Pos (5U) +#define USB_OTG_GINTSTS_NPTXFE_Msk (0x1UL << USB_OTG_GINTSTS_NPTXFE_Pos) /*!< 0x00000020 */ +#define USB_OTG_GINTSTS_NPTXFE USB_OTG_GINTSTS_NPTXFE_Msk /*!< Nonperiodic TxFIFO empty */ +#define USB_OTG_GINTSTS_GINAKEFF_Pos (6U) +#define USB_OTG_GINTSTS_GINAKEFF_Msk (0x1UL << USB_OTG_GINTSTS_GINAKEFF_Pos) /*!< 0x00000040 */ +#define USB_OTG_GINTSTS_GINAKEFF USB_OTG_GINTSTS_GINAKEFF_Msk /*!< Global IN nonperiodic NAK effective */ +#define USB_OTG_GINTSTS_BOUTNAKEFF_Pos (7U) +#define USB_OTG_GINTSTS_BOUTNAKEFF_Msk (0x1UL << USB_OTG_GINTSTS_BOUTNAKEFF_Pos) /*!< 0x00000080 */ +#define USB_OTG_GINTSTS_BOUTNAKEFF USB_OTG_GINTSTS_BOUTNAKEFF_Msk /*!< Global OUT NAK effective */ +#define USB_OTG_GINTSTS_ESUSP_Pos (10U) +#define USB_OTG_GINTSTS_ESUSP_Msk (0x1UL << USB_OTG_GINTSTS_ESUSP_Pos) /*!< 0x00000400 */ +#define USB_OTG_GINTSTS_ESUSP USB_OTG_GINTSTS_ESUSP_Msk /*!< Early suspend */ +#define USB_OTG_GINTSTS_USBSUSP_Pos (11U) +#define USB_OTG_GINTSTS_USBSUSP_Msk (0x1UL << USB_OTG_GINTSTS_USBSUSP_Pos) /*!< 0x00000800 */ +#define USB_OTG_GINTSTS_USBSUSP USB_OTG_GINTSTS_USBSUSP_Msk /*!< USB suspend */ +#define USB_OTG_GINTSTS_USBRST_Pos (12U) +#define USB_OTG_GINTSTS_USBRST_Msk (0x1UL << USB_OTG_GINTSTS_USBRST_Pos) /*!< 0x00001000 */ +#define USB_OTG_GINTSTS_USBRST USB_OTG_GINTSTS_USBRST_Msk /*!< USB reset */ +#define USB_OTG_GINTSTS_ENUMDNE_Pos (13U) +#define USB_OTG_GINTSTS_ENUMDNE_Msk (0x1UL << USB_OTG_GINTSTS_ENUMDNE_Pos) /*!< 0x00002000 */ +#define USB_OTG_GINTSTS_ENUMDNE USB_OTG_GINTSTS_ENUMDNE_Msk /*!< Enumeration done */ +#define USB_OTG_GINTSTS_ISOODRP_Pos (14U) +#define USB_OTG_GINTSTS_ISOODRP_Msk (0x1UL << USB_OTG_GINTSTS_ISOODRP_Pos) /*!< 0x00004000 */ +#define USB_OTG_GINTSTS_ISOODRP USB_OTG_GINTSTS_ISOODRP_Msk /*!< Isochronous OUT packet dropped interrupt */ +#define USB_OTG_GINTSTS_EOPF_Pos (15U) +#define USB_OTG_GINTSTS_EOPF_Msk (0x1UL << USB_OTG_GINTSTS_EOPF_Pos) /*!< 0x00008000 */ +#define USB_OTG_GINTSTS_EOPF USB_OTG_GINTSTS_EOPF_Msk /*!< End of periodic frame interrupt */ +#define USB_OTG_GINTSTS_IEPINT_Pos (18U) +#define USB_OTG_GINTSTS_IEPINT_Msk (0x1UL << USB_OTG_GINTSTS_IEPINT_Pos) /*!< 0x00040000 */ +#define USB_OTG_GINTSTS_IEPINT USB_OTG_GINTSTS_IEPINT_Msk /*!< IN endpoint interrupt */ +#define USB_OTG_GINTSTS_OEPINT_Pos (19U) +#define USB_OTG_GINTSTS_OEPINT_Msk (0x1UL << USB_OTG_GINTSTS_OEPINT_Pos) /*!< 0x00080000 */ +#define USB_OTG_GINTSTS_OEPINT USB_OTG_GINTSTS_OEPINT_Msk /*!< OUT endpoint interrupt */ +#define USB_OTG_GINTSTS_IISOIXFR_Pos (20U) +#define USB_OTG_GINTSTS_IISOIXFR_Msk (0x1UL << USB_OTG_GINTSTS_IISOIXFR_Pos) /*!< 0x00100000 */ +#define USB_OTG_GINTSTS_IISOIXFR USB_OTG_GINTSTS_IISOIXFR_Msk /*!< Incomplete isochronous IN transfer */ +#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos (21U) +#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk (0x1UL << USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos) /*!< 0x00200000 */ +#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk /*!< Incomplete periodic transfer */ +#define USB_OTG_GINTSTS_DATAFSUSP_Pos (22U) +#define USB_OTG_GINTSTS_DATAFSUSP_Msk (0x1UL << USB_OTG_GINTSTS_DATAFSUSP_Pos) /*!< 0x00400000 */ +#define USB_OTG_GINTSTS_DATAFSUSP USB_OTG_GINTSTS_DATAFSUSP_Msk /*!< Data fetch suspended */ +#define USB_OTG_GINTSTS_HPRTINT_Pos (24U) +#define USB_OTG_GINTSTS_HPRTINT_Msk (0x1UL << USB_OTG_GINTSTS_HPRTINT_Pos) /*!< 0x01000000 */ +#define USB_OTG_GINTSTS_HPRTINT USB_OTG_GINTSTS_HPRTINT_Msk /*!< Host port interrupt */ +#define USB_OTG_GINTSTS_HCINT_Pos (25U) +#define USB_OTG_GINTSTS_HCINT_Msk (0x1UL << USB_OTG_GINTSTS_HCINT_Pos) /*!< 0x02000000 */ +#define USB_OTG_GINTSTS_HCINT USB_OTG_GINTSTS_HCINT_Msk /*!< Host channels interrupt */ +#define USB_OTG_GINTSTS_PTXFE_Pos (26U) +#define USB_OTG_GINTSTS_PTXFE_Msk (0x1UL << USB_OTG_GINTSTS_PTXFE_Pos) /*!< 0x04000000 */ +#define USB_OTG_GINTSTS_PTXFE USB_OTG_GINTSTS_PTXFE_Msk /*!< Periodic TxFIFO empty */ +#define USB_OTG_GINTSTS_CIDSCHG_Pos (28U) +#define USB_OTG_GINTSTS_CIDSCHG_Msk (0x1UL << USB_OTG_GINTSTS_CIDSCHG_Pos) /*!< 0x10000000 */ +#define USB_OTG_GINTSTS_CIDSCHG USB_OTG_GINTSTS_CIDSCHG_Msk /*!< Connector ID status change */ +#define USB_OTG_GINTSTS_DISCINT_Pos (29U) +#define USB_OTG_GINTSTS_DISCINT_Msk (0x1UL << USB_OTG_GINTSTS_DISCINT_Pos) /*!< 0x20000000 */ +#define USB_OTG_GINTSTS_DISCINT USB_OTG_GINTSTS_DISCINT_Msk /*!< Disconnect detected interrupt */ +#define USB_OTG_GINTSTS_SRQINT_Pos (30U) +#define USB_OTG_GINTSTS_SRQINT_Msk (0x1UL << USB_OTG_GINTSTS_SRQINT_Pos) /*!< 0x40000000 */ +#define USB_OTG_GINTSTS_SRQINT USB_OTG_GINTSTS_SRQINT_Msk /*!< Session request/new session detected interrupt */ +#define USB_OTG_GINTSTS_WKUINT_Pos (31U) +#define USB_OTG_GINTSTS_WKUINT_Msk (0x1UL << USB_OTG_GINTSTS_WKUINT_Pos) /*!< 0x80000000 */ +#define USB_OTG_GINTSTS_WKUINT USB_OTG_GINTSTS_WKUINT_Msk /*!< Resume/remote wakeup detected interrupt */ + +/******************** Bit definition for USB_OTG_GINTMSK register ********************/ +#define USB_OTG_GINTMSK_MMISM_Pos (1U) +#define USB_OTG_GINTMSK_MMISM_Msk (0x1UL << USB_OTG_GINTMSK_MMISM_Pos) /*!< 0x00000002 */ +#define USB_OTG_GINTMSK_MMISM USB_OTG_GINTMSK_MMISM_Msk /*!< Mode mismatch interrupt mask */ +#define USB_OTG_GINTMSK_OTGINT_Pos (2U) +#define USB_OTG_GINTMSK_OTGINT_Msk (0x1UL << USB_OTG_GINTMSK_OTGINT_Pos) /*!< 0x00000004 */ +#define USB_OTG_GINTMSK_OTGINT USB_OTG_GINTMSK_OTGINT_Msk /*!< OTG interrupt mask */ +#define USB_OTG_GINTMSK_SOFM_Pos (3U) +#define USB_OTG_GINTMSK_SOFM_Msk (0x1UL << USB_OTG_GINTMSK_SOFM_Pos) /*!< 0x00000008 */ +#define USB_OTG_GINTMSK_SOFM USB_OTG_GINTMSK_SOFM_Msk /*!< Start of frame mask */ +#define USB_OTG_GINTMSK_RXFLVLM_Pos (4U) +#define USB_OTG_GINTMSK_RXFLVLM_Msk (0x1UL << USB_OTG_GINTMSK_RXFLVLM_Pos) /*!< 0x00000010 */ +#define USB_OTG_GINTMSK_RXFLVLM USB_OTG_GINTMSK_RXFLVLM_Msk /*!< Receive FIFO nonempty mask */ +#define USB_OTG_GINTMSK_NPTXFEM_Pos (5U) +#define USB_OTG_GINTMSK_NPTXFEM_Msk (0x1UL << USB_OTG_GINTMSK_NPTXFEM_Pos) /*!< 0x00000020 */ +#define USB_OTG_GINTMSK_NPTXFEM USB_OTG_GINTMSK_NPTXFEM_Msk /*!< Nonperiodic TxFIFO empty mask */ +#define USB_OTG_GINTMSK_GINAKEFFM_Pos (6U) +#define USB_OTG_GINTMSK_GINAKEFFM_Msk (0x1UL << USB_OTG_GINTMSK_GINAKEFFM_Pos) /*!< 0x00000040 */ +#define USB_OTG_GINTMSK_GINAKEFFM USB_OTG_GINTMSK_GINAKEFFM_Msk /*!< Global nonperiodic IN NAK effective mask */ +#define USB_OTG_GINTMSK_GONAKEFFM_Pos (7U) +#define USB_OTG_GINTMSK_GONAKEFFM_Msk (0x1UL << USB_OTG_GINTMSK_GONAKEFFM_Pos) /*!< 0x00000080 */ +#define USB_OTG_GINTMSK_GONAKEFFM USB_OTG_GINTMSK_GONAKEFFM_Msk /*!< Global OUT NAK effective mask */ +#define USB_OTG_GINTMSK_ESUSPM_Pos (10U) +#define USB_OTG_GINTMSK_ESUSPM_Msk (0x1UL << USB_OTG_GINTMSK_ESUSPM_Pos) /*!< 0x00000400 */ +#define USB_OTG_GINTMSK_ESUSPM USB_OTG_GINTMSK_ESUSPM_Msk /*!< Early suspend mask */ +#define USB_OTG_GINTMSK_USBSUSPM_Pos (11U) +#define USB_OTG_GINTMSK_USBSUSPM_Msk (0x1UL << USB_OTG_GINTMSK_USBSUSPM_Pos) /*!< 0x00000800 */ +#define USB_OTG_GINTMSK_USBSUSPM USB_OTG_GINTMSK_USBSUSPM_Msk /*!< USB suspend mask */ +#define USB_OTG_GINTMSK_USBRST_Pos (12U) +#define USB_OTG_GINTMSK_USBRST_Msk (0x1UL << USB_OTG_GINTMSK_USBRST_Pos) /*!< 0x00001000 */ +#define USB_OTG_GINTMSK_USBRST USB_OTG_GINTMSK_USBRST_Msk /*!< USB reset mask */ +#define USB_OTG_GINTMSK_ENUMDNEM_Pos (13U) +#define USB_OTG_GINTMSK_ENUMDNEM_Msk (0x1UL << USB_OTG_GINTMSK_ENUMDNEM_Pos) /*!< 0x00002000 */ +#define USB_OTG_GINTMSK_ENUMDNEM USB_OTG_GINTMSK_ENUMDNEM_Msk /*!< Enumeration done mask */ +#define USB_OTG_GINTMSK_ISOODRPM_Pos (14U) +#define USB_OTG_GINTMSK_ISOODRPM_Msk (0x1UL << USB_OTG_GINTMSK_ISOODRPM_Pos) /*!< 0x00004000 */ +#define USB_OTG_GINTMSK_ISOODRPM USB_OTG_GINTMSK_ISOODRPM_Msk /*!< Isochronous OUT packet dropped interrupt mask */ +#define USB_OTG_GINTMSK_EOPFM_Pos (15U) +#define USB_OTG_GINTMSK_EOPFM_Msk (0x1UL << USB_OTG_GINTMSK_EOPFM_Pos) /*!< 0x00008000 */ +#define USB_OTG_GINTMSK_EOPFM USB_OTG_GINTMSK_EOPFM_Msk /*!< End of periodic frame interrupt mask */ +#define USB_OTG_GINTMSK_EPMISM_Pos (17U) +#define USB_OTG_GINTMSK_EPMISM_Msk (0x1UL << USB_OTG_GINTMSK_EPMISM_Pos) /*!< 0x00020000 */ +#define USB_OTG_GINTMSK_EPMISM USB_OTG_GINTMSK_EPMISM_Msk /*!< Endpoint mismatch interrupt mask */ +#define USB_OTG_GINTMSK_IEPINT_Pos (18U) +#define USB_OTG_GINTMSK_IEPINT_Msk (0x1UL << USB_OTG_GINTMSK_IEPINT_Pos) /*!< 0x00040000 */ +#define USB_OTG_GINTMSK_IEPINT USB_OTG_GINTMSK_IEPINT_Msk /*!< IN endpoints interrupt mask */ +#define USB_OTG_GINTMSK_OEPINT_Pos (19U) +#define USB_OTG_GINTMSK_OEPINT_Msk (0x1UL << USB_OTG_GINTMSK_OEPINT_Pos) /*!< 0x00080000 */ +#define USB_OTG_GINTMSK_OEPINT USB_OTG_GINTMSK_OEPINT_Msk /*!< OUT endpoints interrupt mask */ +#define USB_OTG_GINTMSK_IISOIXFRM_Pos (20U) +#define USB_OTG_GINTMSK_IISOIXFRM_Msk (0x1UL << USB_OTG_GINTMSK_IISOIXFRM_Pos) /*!< 0x00100000 */ +#define USB_OTG_GINTMSK_IISOIXFRM USB_OTG_GINTMSK_IISOIXFRM_Msk /*!< Incomplete isochronous IN transfer mask */ +#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos (21U) +#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk (0x1UL << USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos) /*!< 0x00200000 */ +#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk /*!< Incomplete periodic transfer mask */ +#define USB_OTG_GINTMSK_FSUSPM_Pos (22U) +#define USB_OTG_GINTMSK_FSUSPM_Msk (0x1UL << USB_OTG_GINTMSK_FSUSPM_Pos) /*!< 0x00400000 */ +#define USB_OTG_GINTMSK_FSUSPM USB_OTG_GINTMSK_FSUSPM_Msk /*!< Data fetch suspended mask */ +#define USB_OTG_GINTMSK_PRTIM_Pos (24U) +#define USB_OTG_GINTMSK_PRTIM_Msk (0x1UL << USB_OTG_GINTMSK_PRTIM_Pos) /*!< 0x01000000 */ +#define USB_OTG_GINTMSK_PRTIM USB_OTG_GINTMSK_PRTIM_Msk /*!< Host port interrupt mask */ +#define USB_OTG_GINTMSK_HCIM_Pos (25U) +#define USB_OTG_GINTMSK_HCIM_Msk (0x1UL << USB_OTG_GINTMSK_HCIM_Pos) /*!< 0x02000000 */ +#define USB_OTG_GINTMSK_HCIM USB_OTG_GINTMSK_HCIM_Msk /*!< Host channels interrupt mask */ +#define USB_OTG_GINTMSK_PTXFEM_Pos (26U) +#define USB_OTG_GINTMSK_PTXFEM_Msk (0x1UL << USB_OTG_GINTMSK_PTXFEM_Pos) /*!< 0x04000000 */ +#define USB_OTG_GINTMSK_PTXFEM USB_OTG_GINTMSK_PTXFEM_Msk /*!< Periodic TxFIFO empty mask */ +#define USB_OTG_GINTMSK_CIDSCHGM_Pos (28U) +#define USB_OTG_GINTMSK_CIDSCHGM_Msk (0x1UL << USB_OTG_GINTMSK_CIDSCHGM_Pos) /*!< 0x10000000 */ +#define USB_OTG_GINTMSK_CIDSCHGM USB_OTG_GINTMSK_CIDSCHGM_Msk /*!< Connector ID status change mask */ +#define USB_OTG_GINTMSK_DISCINT_Pos (29U) +#define USB_OTG_GINTMSK_DISCINT_Msk (0x1UL << USB_OTG_GINTMSK_DISCINT_Pos) /*!< 0x20000000 */ +#define USB_OTG_GINTMSK_DISCINT USB_OTG_GINTMSK_DISCINT_Msk /*!< Disconnect detected interrupt mask */ +#define USB_OTG_GINTMSK_SRQIM_Pos (30U) +#define USB_OTG_GINTMSK_SRQIM_Msk (0x1UL << USB_OTG_GINTMSK_SRQIM_Pos) /*!< 0x40000000 */ +#define USB_OTG_GINTMSK_SRQIM USB_OTG_GINTMSK_SRQIM_Msk /*!< Session request/new session detected interrupt mask */ +#define USB_OTG_GINTMSK_WUIM_Pos (31U) +#define USB_OTG_GINTMSK_WUIM_Msk (0x1UL << USB_OTG_GINTMSK_WUIM_Pos) /*!< 0x80000000 */ +#define USB_OTG_GINTMSK_WUIM USB_OTG_GINTMSK_WUIM_Msk /*!< Resume/remote wakeup detected interrupt mask */ + +/******************** Bit definition for USB_OTG_DAINT register ********************/ +#define USB_OTG_DAINT_IEPINT_Pos (0U) +#define USB_OTG_DAINT_IEPINT_Msk (0xFFFFUL << USB_OTG_DAINT_IEPINT_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DAINT_IEPINT USB_OTG_DAINT_IEPINT_Msk /*!< IN endpoint interrupt bits */ +#define USB_OTG_DAINT_OEPINT_Pos (16U) +#define USB_OTG_DAINT_OEPINT_Msk (0xFFFFUL << USB_OTG_DAINT_OEPINT_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_DAINT_OEPINT USB_OTG_DAINT_OEPINT_Msk /*!< OUT endpoint interrupt bits */ + +/******************** Bit definition for USB_OTG_HAINTMSK register ********************/ +#define USB_OTG_HAINTMSK_HAINTM_Pos (0U) +#define USB_OTG_HAINTMSK_HAINTM_Msk (0xFFFFUL << USB_OTG_HAINTMSK_HAINTM_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HAINTMSK_HAINTM USB_OTG_HAINTMSK_HAINTM_Msk /*!< Channel interrupt mask */ + +/******************** Bit definition for USB_OTG_GRXSTSP register ********************/ +#define USB_OTG_GRXSTSP_EPNUM_Pos (0U) +#define USB_OTG_GRXSTSP_EPNUM_Msk (0xFUL << USB_OTG_GRXSTSP_EPNUM_Pos) /*!< 0x0000000F */ +#define USB_OTG_GRXSTSP_EPNUM USB_OTG_GRXSTSP_EPNUM_Msk /*!< IN EP interrupt mask bits */ +#define USB_OTG_GRXSTSP_BCNT_Pos (4U) +#define USB_OTG_GRXSTSP_BCNT_Msk (0x7FFUL << USB_OTG_GRXSTSP_BCNT_Pos) /*!< 0x00007FF0 */ +#define USB_OTG_GRXSTSP_BCNT USB_OTG_GRXSTSP_BCNT_Msk /*!< OUT EP interrupt mask bits */ +#define USB_OTG_GRXSTSP_DPID_Pos (15U) +#define USB_OTG_GRXSTSP_DPID_Msk (0x3UL << USB_OTG_GRXSTSP_DPID_Pos) /*!< 0x00018000 */ +#define USB_OTG_GRXSTSP_DPID USB_OTG_GRXSTSP_DPID_Msk /*!< OUT EP interrupt mask bits */ +#define USB_OTG_GRXSTSP_PKTSTS_Pos (17U) +#define USB_OTG_GRXSTSP_PKTSTS_Msk (0xFUL << USB_OTG_GRXSTSP_PKTSTS_Pos) /*!< 0x001E0000 */ +#define USB_OTG_GRXSTSP_PKTSTS USB_OTG_GRXSTSP_PKTSTS_Msk /*!< OUT EP interrupt mask bits */ + +/******************** Bit definition for USB_OTG_DAINTMSK register ********************/ +#define USB_OTG_DAINTMSK_IEPM_Pos (0U) +#define USB_OTG_DAINTMSK_IEPM_Msk (0xFFFFUL << USB_OTG_DAINTMSK_IEPM_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DAINTMSK_IEPM USB_OTG_DAINTMSK_IEPM_Msk /*!< IN EP interrupt mask bits */ +#define USB_OTG_DAINTMSK_OEPM_Pos (16U) +#define USB_OTG_DAINTMSK_OEPM_Msk (0xFFFFUL << USB_OTG_DAINTMSK_OEPM_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_DAINTMSK_OEPM USB_OTG_DAINTMSK_OEPM_Msk /*!< OUT EP interrupt mask bits */ + +/******************** Bit definition for USB_OTG_GRXFSIZ register ********************/ +#define USB_OTG_GRXFSIZ_RXFD_Pos (0U) +#define USB_OTG_GRXFSIZ_RXFD_Msk (0xFFFFUL << USB_OTG_GRXFSIZ_RXFD_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_GRXFSIZ_RXFD USB_OTG_GRXFSIZ_RXFD_Msk /*!< RxFIFO depth */ + +/******************** Bit definition for USB_OTG_DVBUSDIS register ********************/ +#define USB_OTG_DVBUSDIS_VBUSDT_Pos (0U) +#define USB_OTG_DVBUSDIS_VBUSDT_Msk (0xFFFFUL << USB_OTG_DVBUSDIS_VBUSDT_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DVBUSDIS_VBUSDT USB_OTG_DVBUSDIS_VBUSDT_Msk /*!< Device VBUS discharge time */ + +/******************** Bit definition for OTG register ********************/ +#define USB_OTG_NPTXFSA_Pos (0U) +#define USB_OTG_NPTXFSA_Msk (0xFFFFUL << USB_OTG_NPTXFSA_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_NPTXFSA USB_OTG_NPTXFSA_Msk /*!< Nonperiodic transmit RAM start address */ +#define USB_OTG_NPTXFD_Pos (16U) +#define USB_OTG_NPTXFD_Msk (0xFFFFUL << USB_OTG_NPTXFD_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_NPTXFD USB_OTG_NPTXFD_Msk /*!< Nonperiodic TxFIFO depth */ +#define USB_OTG_TX0FSA_Pos (0U) +#define USB_OTG_TX0FSA_Msk (0xFFFFUL << USB_OTG_TX0FSA_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_TX0FSA USB_OTG_TX0FSA_Msk /*!< Endpoint 0 transmit RAM start address */ +#define USB_OTG_TX0FD_Pos (16U) +#define USB_OTG_TX0FD_Msk (0xFFFFUL << USB_OTG_TX0FD_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_TX0FD USB_OTG_TX0FD_Msk /*!< Endpoint 0 TxFIFO depth */ + +/******************** Bit definition for USB_OTG_DVBUSPULSE register ********************/ +#define USB_OTG_DVBUSPULSE_DVBUSP_Pos (0U) +#define USB_OTG_DVBUSPULSE_DVBUSP_Msk (0xFFFUL << USB_OTG_DVBUSPULSE_DVBUSP_Pos) /*!< 0x00000FFF */ +#define USB_OTG_DVBUSPULSE_DVBUSP USB_OTG_DVBUSPULSE_DVBUSP_Msk /*!< Device VBUS pulsing time */ + +/******************** Bit definition for USB_OTG_GNPTXSTS register ********************/ +#define USB_OTG_GNPTXSTS_NPTXFSAV_Pos (0U) +#define USB_OTG_GNPTXSTS_NPTXFSAV_Msk (0xFFFFUL << USB_OTG_GNPTXSTS_NPTXFSAV_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_GNPTXSTS_NPTXFSAV USB_OTG_GNPTXSTS_NPTXFSAV_Msk /*!< Nonperiodic TxFIFO space available */ + +#define USB_OTG_GNPTXSTS_NPTQXSAV_Pos (16U) +#define USB_OTG_GNPTXSTS_NPTQXSAV_Msk (0xFFUL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00FF0000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV USB_OTG_GNPTXSTS_NPTQXSAV_Msk /*!< Nonperiodic transmit request queue space available */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_0 (0x01UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00010000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_1 (0x02UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00020000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_2 (0x04UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00040000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_3 (0x08UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00080000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_4 (0x10UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00100000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_5 (0x20UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00200000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_6 (0x40UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00400000 */ +#define USB_OTG_GNPTXSTS_NPTQXSAV_7 (0x80UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00800000 */ + +#define USB_OTG_GNPTXSTS_NPTXQTOP_Pos (24U) +#define USB_OTG_GNPTXSTS_NPTXQTOP_Msk (0x7FUL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x7F000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP USB_OTG_GNPTXSTS_NPTXQTOP_Msk /*!< Top of the nonperiodic transmit request queue */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_0 (0x01UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x01000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_1 (0x02UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x02000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_2 (0x04UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x04000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_3 (0x08UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x08000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_4 (0x10UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x10000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_5 (0x20UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x20000000 */ +#define USB_OTG_GNPTXSTS_NPTXQTOP_6 (0x40UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for USB_OTG_DTHRCTL register ********************/ +#define USB_OTG_DTHRCTL_NONISOTHREN_Pos (0U) +#define USB_OTG_DTHRCTL_NONISOTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_NONISOTHREN_Pos) /*!< 0x00000001 */ +#define USB_OTG_DTHRCTL_NONISOTHREN USB_OTG_DTHRCTL_NONISOTHREN_Msk /*!< Nonisochronous IN endpoints threshold enable */ +#define USB_OTG_DTHRCTL_ISOTHREN_Pos (1U) +#define USB_OTG_DTHRCTL_ISOTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_ISOTHREN_Pos) /*!< 0x00000002 */ +#define USB_OTG_DTHRCTL_ISOTHREN USB_OTG_DTHRCTL_ISOTHREN_Msk /*!< ISO IN endpoint threshold enable */ + +#define USB_OTG_DTHRCTL_TXTHRLEN_Pos (2U) +#define USB_OTG_DTHRCTL_TXTHRLEN_Msk (0x1FFUL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x000007FC */ +#define USB_OTG_DTHRCTL_TXTHRLEN USB_OTG_DTHRCTL_TXTHRLEN_Msk /*!< Transmit threshold length */ +#define USB_OTG_DTHRCTL_TXTHRLEN_0 (0x001UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000004 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_1 (0x002UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000008 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_2 (0x004UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000010 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_3 (0x008UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000020 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_4 (0x010UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000040 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_5 (0x020UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000080 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_6 (0x040UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000100 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_7 (0x080UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000200 */ +#define USB_OTG_DTHRCTL_TXTHRLEN_8 (0x100UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000400 */ +#define USB_OTG_DTHRCTL_RXTHREN_Pos (16U) +#define USB_OTG_DTHRCTL_RXTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_RXTHREN_Pos) /*!< 0x00010000 */ +#define USB_OTG_DTHRCTL_RXTHREN USB_OTG_DTHRCTL_RXTHREN_Msk /*!< Receive threshold enable */ + +#define USB_OTG_DTHRCTL_RXTHRLEN_Pos (17U) +#define USB_OTG_DTHRCTL_RXTHRLEN_Msk (0x1FFUL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x03FE0000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN USB_OTG_DTHRCTL_RXTHRLEN_Msk /*!< Receive threshold length */ +#define USB_OTG_DTHRCTL_RXTHRLEN_0 (0x001UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00020000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_1 (0x002UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00040000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_2 (0x004UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00080000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_3 (0x008UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00100000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_4 (0x010UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00200000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_5 (0x020UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00400000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_6 (0x040UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00800000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_7 (0x080UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x01000000 */ +#define USB_OTG_DTHRCTL_RXTHRLEN_8 (0x100UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x02000000 */ +#define USB_OTG_DTHRCTL_ARPEN_Pos (27U) +#define USB_OTG_DTHRCTL_ARPEN_Msk (0x1UL << USB_OTG_DTHRCTL_ARPEN_Pos) /*!< 0x08000000 */ +#define USB_OTG_DTHRCTL_ARPEN USB_OTG_DTHRCTL_ARPEN_Msk /*!< Arbiter parking enable */ + +/******************** Bit definition for USB_OTG_DIEPEMPMSK register ********************/ +#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos (0U) +#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk (0xFFFFUL << USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DIEPEMPMSK_INEPTXFEM USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk /*!< IN EP Tx FIFO empty interrupt mask bits */ + +/******************** Bit definition for USB_OTG_DEACHINT register ********************/ +#define USB_OTG_DEACHINT_IEP1INT_Pos (1U) +#define USB_OTG_DEACHINT_IEP1INT_Msk (0x1UL << USB_OTG_DEACHINT_IEP1INT_Pos) /*!< 0x00000002 */ +#define USB_OTG_DEACHINT_IEP1INT USB_OTG_DEACHINT_IEP1INT_Msk /*!< IN endpoint 1interrupt bit */ +#define USB_OTG_DEACHINT_OEP1INT_Pos (17U) +#define USB_OTG_DEACHINT_OEP1INT_Msk (0x1UL << USB_OTG_DEACHINT_OEP1INT_Pos) /*!< 0x00020000 */ +#define USB_OTG_DEACHINT_OEP1INT USB_OTG_DEACHINT_OEP1INT_Msk /*!< OUT endpoint 1 interrupt bit */ + +/******************** Bit definition for USB_OTG_GCCFG register ********************/ +#define USB_OTG_GCCFG_PWRDWN_Pos (16U) +#define USB_OTG_GCCFG_PWRDWN_Msk (0x1UL << USB_OTG_GCCFG_PWRDWN_Pos) /*!< 0x00010000 */ +#define USB_OTG_GCCFG_PWRDWN USB_OTG_GCCFG_PWRDWN_Msk /*!< Power down */ +#define USB_OTG_GCCFG_VBUSASEN_Pos (18U) +#define USB_OTG_GCCFG_VBUSASEN_Msk (0x1UL << USB_OTG_GCCFG_VBUSASEN_Pos) /*!< 0x00040000 */ +#define USB_OTG_GCCFG_VBUSASEN USB_OTG_GCCFG_VBUSASEN_Msk /*!< Enable the VBUS sensing device */ +#define USB_OTG_GCCFG_VBUSBSEN_Pos (19U) +#define USB_OTG_GCCFG_VBUSBSEN_Msk (0x1UL << USB_OTG_GCCFG_VBUSBSEN_Pos) /*!< 0x00080000 */ +#define USB_OTG_GCCFG_VBUSBSEN USB_OTG_GCCFG_VBUSBSEN_Msk /*!< Enable the VBUS sensing device */ +#define USB_OTG_GCCFG_SOFOUTEN_Pos (20U) +#define USB_OTG_GCCFG_SOFOUTEN_Msk (0x1UL << USB_OTG_GCCFG_SOFOUTEN_Pos) /*!< 0x00100000 */ +#define USB_OTG_GCCFG_SOFOUTEN USB_OTG_GCCFG_SOFOUTEN_Msk /*!< SOF output enable */ + +/******************** Bit definition for USB_OTG_DEACHINTMSK register ********************/ +#define USB_OTG_DEACHINTMSK_IEP1INTM_Pos (1U) +#define USB_OTG_DEACHINTMSK_IEP1INTM_Msk (0x1UL << USB_OTG_DEACHINTMSK_IEP1INTM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DEACHINTMSK_IEP1INTM USB_OTG_DEACHINTMSK_IEP1INTM_Msk /*!< IN Endpoint 1 interrupt mask bit */ +#define USB_OTG_DEACHINTMSK_OEP1INTM_Pos (17U) +#define USB_OTG_DEACHINTMSK_OEP1INTM_Msk (0x1UL << USB_OTG_DEACHINTMSK_OEP1INTM_Pos) /*!< 0x00020000 */ +#define USB_OTG_DEACHINTMSK_OEP1INTM USB_OTG_DEACHINTMSK_OEP1INTM_Msk /*!< OUT Endpoint 1 interrupt mask bit */ + +/******************** Bit definition for USB_OTG_CID register ********************/ +#define USB_OTG_CID_PRODUCT_ID_Pos (0U) +#define USB_OTG_CID_PRODUCT_ID_Msk (0xFFFFFFFFUL << USB_OTG_CID_PRODUCT_ID_Pos) /*!< 0xFFFFFFFF */ +#define USB_OTG_CID_PRODUCT_ID USB_OTG_CID_PRODUCT_ID_Msk /*!< Product ID field */ + +/******************** Bit definition for USB_OTG_DIEPEACHMSK1 register ********************/ +#define USB_OTG_DIEPEACHMSK1_XFRCM_Pos (0U) +#define USB_OTG_DIEPEACHMSK1_XFRCM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_DIEPEACHMSK1_XFRCM USB_OTG_DIEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */ +#define USB_OTG_DIEPEACHMSK1_EPDM_Pos (1U) +#define USB_OTG_DIEPEACHMSK1_EPDM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DIEPEACHMSK1_EPDM USB_OTG_DIEPEACHMSK1_EPDM_Msk /*!< Endpoint disabled interrupt mask */ +#define USB_OTG_DIEPEACHMSK1_TOM_Pos (3U) +#define USB_OTG_DIEPEACHMSK1_TOM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */ +#define USB_OTG_DIEPEACHMSK1_TOM USB_OTG_DIEPEACHMSK1_TOM_Msk /*!< Timeout condition mask (nonisochronous endpoints) */ +#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos (4U) +#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */ +#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ +#define USB_OTG_DIEPEACHMSK1_INEPNMM_Pos (5U) +#define USB_OTG_DIEPEACHMSK1_INEPNMM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */ +#define USB_OTG_DIEPEACHMSK1_INEPNMM USB_OTG_DIEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ +#define USB_OTG_DIEPEACHMSK1_INEPNEM_Pos (6U) +#define USB_OTG_DIEPEACHMSK1_INEPNEM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */ +#define USB_OTG_DIEPEACHMSK1_INEPNEM USB_OTG_DIEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ +#define USB_OTG_DIEPEACHMSK1_TXFURM_Pos (8U) +#define USB_OTG_DIEPEACHMSK1_TXFURM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */ +#define USB_OTG_DIEPEACHMSK1_TXFURM USB_OTG_DIEPEACHMSK1_TXFURM_Msk /*!< FIFO underrun mask */ +#define USB_OTG_DIEPEACHMSK1_BIM_Pos (9U) +#define USB_OTG_DIEPEACHMSK1_BIM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */ +#define USB_OTG_DIEPEACHMSK1_BIM USB_OTG_DIEPEACHMSK1_BIM_Msk /*!< BNA interrupt mask */ +#define USB_OTG_DIEPEACHMSK1_NAKM_Pos (13U) +#define USB_OTG_DIEPEACHMSK1_NAKM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */ +#define USB_OTG_DIEPEACHMSK1_NAKM USB_OTG_DIEPEACHMSK1_NAKM_Msk /*!< NAK interrupt mask */ + +/******************** Bit definition for USB_OTG_HPRT register ********************/ +#define USB_OTG_HPRT_PCSTS_Pos (0U) +#define USB_OTG_HPRT_PCSTS_Msk (0x1UL << USB_OTG_HPRT_PCSTS_Pos) /*!< 0x00000001 */ +#define USB_OTG_HPRT_PCSTS USB_OTG_HPRT_PCSTS_Msk /*!< Port connect status */ +#define USB_OTG_HPRT_PCDET_Pos (1U) +#define USB_OTG_HPRT_PCDET_Msk (0x1UL << USB_OTG_HPRT_PCDET_Pos) /*!< 0x00000002 */ +#define USB_OTG_HPRT_PCDET USB_OTG_HPRT_PCDET_Msk /*!< Port connect detected */ +#define USB_OTG_HPRT_PENA_Pos (2U) +#define USB_OTG_HPRT_PENA_Msk (0x1UL << USB_OTG_HPRT_PENA_Pos) /*!< 0x00000004 */ +#define USB_OTG_HPRT_PENA USB_OTG_HPRT_PENA_Msk /*!< Port enable */ +#define USB_OTG_HPRT_PENCHNG_Pos (3U) +#define USB_OTG_HPRT_PENCHNG_Msk (0x1UL << USB_OTG_HPRT_PENCHNG_Pos) /*!< 0x00000008 */ +#define USB_OTG_HPRT_PENCHNG USB_OTG_HPRT_PENCHNG_Msk /*!< Port enable/disable change */ +#define USB_OTG_HPRT_POCA_Pos (4U) +#define USB_OTG_HPRT_POCA_Msk (0x1UL << USB_OTG_HPRT_POCA_Pos) /*!< 0x00000010 */ +#define USB_OTG_HPRT_POCA USB_OTG_HPRT_POCA_Msk /*!< Port overcurrent active */ +#define USB_OTG_HPRT_POCCHNG_Pos (5U) +#define USB_OTG_HPRT_POCCHNG_Msk (0x1UL << USB_OTG_HPRT_POCCHNG_Pos) /*!< 0x00000020 */ +#define USB_OTG_HPRT_POCCHNG USB_OTG_HPRT_POCCHNG_Msk /*!< Port overcurrent change */ +#define USB_OTG_HPRT_PRES_Pos (6U) +#define USB_OTG_HPRT_PRES_Msk (0x1UL << USB_OTG_HPRT_PRES_Pos) /*!< 0x00000040 */ +#define USB_OTG_HPRT_PRES USB_OTG_HPRT_PRES_Msk /*!< Port resume */ +#define USB_OTG_HPRT_PSUSP_Pos (7U) +#define USB_OTG_HPRT_PSUSP_Msk (0x1UL << USB_OTG_HPRT_PSUSP_Pos) /*!< 0x00000080 */ +#define USB_OTG_HPRT_PSUSP USB_OTG_HPRT_PSUSP_Msk /*!< Port suspend */ +#define USB_OTG_HPRT_PRST_Pos (8U) +#define USB_OTG_HPRT_PRST_Msk (0x1UL << USB_OTG_HPRT_PRST_Pos) /*!< 0x00000100 */ +#define USB_OTG_HPRT_PRST USB_OTG_HPRT_PRST_Msk /*!< Port reset */ + +#define USB_OTG_HPRT_PLSTS_Pos (10U) +#define USB_OTG_HPRT_PLSTS_Msk (0x3UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000C00 */ +#define USB_OTG_HPRT_PLSTS USB_OTG_HPRT_PLSTS_Msk /*!< Port line status */ +#define USB_OTG_HPRT_PLSTS_0 (0x1UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000400 */ +#define USB_OTG_HPRT_PLSTS_1 (0x2UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000800 */ +#define USB_OTG_HPRT_PPWR_Pos (12U) +#define USB_OTG_HPRT_PPWR_Msk (0x1UL << USB_OTG_HPRT_PPWR_Pos) /*!< 0x00001000 */ +#define USB_OTG_HPRT_PPWR USB_OTG_HPRT_PPWR_Msk /*!< Port power */ + +#define USB_OTG_HPRT_PTCTL_Pos (13U) +#define USB_OTG_HPRT_PTCTL_Msk (0xFUL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x0001E000 */ +#define USB_OTG_HPRT_PTCTL USB_OTG_HPRT_PTCTL_Msk /*!< Port test control */ +#define USB_OTG_HPRT_PTCTL_0 (0x1UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00002000 */ +#define USB_OTG_HPRT_PTCTL_1 (0x2UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00004000 */ +#define USB_OTG_HPRT_PTCTL_2 (0x4UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00008000 */ +#define USB_OTG_HPRT_PTCTL_3 (0x8UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00010000 */ + +#define USB_OTG_HPRT_PSPD_Pos (17U) +#define USB_OTG_HPRT_PSPD_Msk (0x3UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00060000 */ +#define USB_OTG_HPRT_PSPD USB_OTG_HPRT_PSPD_Msk /*!< Port speed */ +#define USB_OTG_HPRT_PSPD_0 (0x1UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00020000 */ +#define USB_OTG_HPRT_PSPD_1 (0x2UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00040000 */ + +/******************** Bit definition for USB_OTG_DOEPEACHMSK1 register ********************/ +#define USB_OTG_DOEPEACHMSK1_XFRCM_Pos (0U) +#define USB_OTG_DOEPEACHMSK1_XFRCM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_DOEPEACHMSK1_XFRCM USB_OTG_DOEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_EPDM_Pos (1U) +#define USB_OTG_DOEPEACHMSK1_EPDM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */ +#define USB_OTG_DOEPEACHMSK1_EPDM USB_OTG_DOEPEACHMSK1_EPDM_Msk /*!< Endpoint disabled interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_TOM_Pos (3U) +#define USB_OTG_DOEPEACHMSK1_TOM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */ +#define USB_OTG_DOEPEACHMSK1_TOM USB_OTG_DOEPEACHMSK1_TOM_Msk /*!< Timeout condition mask */ +#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos (4U) +#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */ +#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ +#define USB_OTG_DOEPEACHMSK1_INEPNMM_Pos (5U) +#define USB_OTG_DOEPEACHMSK1_INEPNMM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */ +#define USB_OTG_DOEPEACHMSK1_INEPNMM USB_OTG_DOEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ +#define USB_OTG_DOEPEACHMSK1_INEPNEM_Pos (6U) +#define USB_OTG_DOEPEACHMSK1_INEPNEM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */ +#define USB_OTG_DOEPEACHMSK1_INEPNEM USB_OTG_DOEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ +#define USB_OTG_DOEPEACHMSK1_TXFURM_Pos (8U) +#define USB_OTG_DOEPEACHMSK1_TXFURM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */ +#define USB_OTG_DOEPEACHMSK1_TXFURM USB_OTG_DOEPEACHMSK1_TXFURM_Msk /*!< OUT packet error mask */ +#define USB_OTG_DOEPEACHMSK1_BIM_Pos (9U) +#define USB_OTG_DOEPEACHMSK1_BIM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */ +#define USB_OTG_DOEPEACHMSK1_BIM USB_OTG_DOEPEACHMSK1_BIM_Msk /*!< BNA interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_BERRM_Pos (12U) +#define USB_OTG_DOEPEACHMSK1_BERRM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_BERRM_Pos) /*!< 0x00001000 */ +#define USB_OTG_DOEPEACHMSK1_BERRM USB_OTG_DOEPEACHMSK1_BERRM_Msk /*!< Bubble error interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_NAKM_Pos (13U) +#define USB_OTG_DOEPEACHMSK1_NAKM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */ +#define USB_OTG_DOEPEACHMSK1_NAKM USB_OTG_DOEPEACHMSK1_NAKM_Msk /*!< NAK interrupt mask */ +#define USB_OTG_DOEPEACHMSK1_NYETM_Pos (14U) +#define USB_OTG_DOEPEACHMSK1_NYETM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_NYETM_Pos) /*!< 0x00004000 */ +#define USB_OTG_DOEPEACHMSK1_NYETM USB_OTG_DOEPEACHMSK1_NYETM_Msk /*!< NYET interrupt mask */ + +/******************** Bit definition for USB_OTG_HPTXFSIZ register ********************/ +#define USB_OTG_HPTXFSIZ_PTXSA_Pos (0U) +#define USB_OTG_HPTXFSIZ_PTXSA_Msk (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXSA_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_HPTXFSIZ_PTXSA USB_OTG_HPTXFSIZ_PTXSA_Msk /*!< Host periodic TxFIFO start address */ +#define USB_OTG_HPTXFSIZ_PTXFD_Pos (16U) +#define USB_OTG_HPTXFSIZ_PTXFD_Msk (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXFD_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_HPTXFSIZ_PTXFD USB_OTG_HPTXFSIZ_PTXFD_Msk /*!< Host periodic TxFIFO depth */ + +/******************** Bit definition for USB_OTG_DIEPCTL register ********************/ +#define USB_OTG_DIEPCTL_MPSIZ_Pos (0U) +#define USB_OTG_DIEPCTL_MPSIZ_Msk (0x7FFUL << USB_OTG_DIEPCTL_MPSIZ_Pos) /*!< 0x000007FF */ +#define USB_OTG_DIEPCTL_MPSIZ USB_OTG_DIEPCTL_MPSIZ_Msk /*!< Maximum packet size */ +#define USB_OTG_DIEPCTL_USBAEP_Pos (15U) +#define USB_OTG_DIEPCTL_USBAEP_Msk (0x1UL << USB_OTG_DIEPCTL_USBAEP_Pos) /*!< 0x00008000 */ +#define USB_OTG_DIEPCTL_USBAEP USB_OTG_DIEPCTL_USBAEP_Msk /*!< USB active endpoint */ +#define USB_OTG_DIEPCTL_EONUM_DPID_Pos (16U) +#define USB_OTG_DIEPCTL_EONUM_DPID_Msk (0x1UL << USB_OTG_DIEPCTL_EONUM_DPID_Pos) /*!< 0x00010000 */ +#define USB_OTG_DIEPCTL_EONUM_DPID USB_OTG_DIEPCTL_EONUM_DPID_Msk /*!< Even/odd frame */ +#define USB_OTG_DIEPCTL_NAKSTS_Pos (17U) +#define USB_OTG_DIEPCTL_NAKSTS_Msk (0x1UL << USB_OTG_DIEPCTL_NAKSTS_Pos) /*!< 0x00020000 */ +#define USB_OTG_DIEPCTL_NAKSTS USB_OTG_DIEPCTL_NAKSTS_Msk /*!< NAK status */ + +#define USB_OTG_DIEPCTL_EPTYP_Pos (18U) +#define USB_OTG_DIEPCTL_EPTYP_Msk (0x3UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x000C0000 */ +#define USB_OTG_DIEPCTL_EPTYP USB_OTG_DIEPCTL_EPTYP_Msk /*!< Endpoint type */ +#define USB_OTG_DIEPCTL_EPTYP_0 (0x1UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00040000 */ +#define USB_OTG_DIEPCTL_EPTYP_1 (0x2UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00080000 */ +#define USB_OTG_DIEPCTL_STALL_Pos (21U) +#define USB_OTG_DIEPCTL_STALL_Msk (0x1UL << USB_OTG_DIEPCTL_STALL_Pos) /*!< 0x00200000 */ +#define USB_OTG_DIEPCTL_STALL USB_OTG_DIEPCTL_STALL_Msk /*!< STALL handshake */ + +#define USB_OTG_DIEPCTL_TXFNUM_Pos (22U) +#define USB_OTG_DIEPCTL_TXFNUM_Msk (0xFUL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x03C00000 */ +#define USB_OTG_DIEPCTL_TXFNUM USB_OTG_DIEPCTL_TXFNUM_Msk /*!< TxFIFO number */ +#define USB_OTG_DIEPCTL_TXFNUM_0 (0x1UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00400000 */ +#define USB_OTG_DIEPCTL_TXFNUM_1 (0x2UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00800000 */ +#define USB_OTG_DIEPCTL_TXFNUM_2 (0x4UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x01000000 */ +#define USB_OTG_DIEPCTL_TXFNUM_3 (0x8UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x02000000 */ +#define USB_OTG_DIEPCTL_CNAK_Pos (26U) +#define USB_OTG_DIEPCTL_CNAK_Msk (0x1UL << USB_OTG_DIEPCTL_CNAK_Pos) /*!< 0x04000000 */ +#define USB_OTG_DIEPCTL_CNAK USB_OTG_DIEPCTL_CNAK_Msk /*!< Clear NAK */ +#define USB_OTG_DIEPCTL_SNAK_Pos (27U) +#define USB_OTG_DIEPCTL_SNAK_Msk (0x1UL << USB_OTG_DIEPCTL_SNAK_Pos) /*!< 0x08000000 */ +#define USB_OTG_DIEPCTL_SNAK USB_OTG_DIEPCTL_SNAK_Msk /*!< Set NAK */ +#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos (28U) +#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos) /*!< 0x10000000 */ +#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk /*!< Set DATA0 PID */ +#define USB_OTG_DIEPCTL_SODDFRM_Pos (29U) +#define USB_OTG_DIEPCTL_SODDFRM_Msk (0x1UL << USB_OTG_DIEPCTL_SODDFRM_Pos) /*!< 0x20000000 */ +#define USB_OTG_DIEPCTL_SODDFRM USB_OTG_DIEPCTL_SODDFRM_Msk /*!< Set odd frame */ +#define USB_OTG_DIEPCTL_EPDIS_Pos (30U) +#define USB_OTG_DIEPCTL_EPDIS_Msk (0x1UL << USB_OTG_DIEPCTL_EPDIS_Pos) /*!< 0x40000000 */ +#define USB_OTG_DIEPCTL_EPDIS USB_OTG_DIEPCTL_EPDIS_Msk /*!< Endpoint disable */ +#define USB_OTG_DIEPCTL_EPENA_Pos (31U) +#define USB_OTG_DIEPCTL_EPENA_Msk (0x1UL << USB_OTG_DIEPCTL_EPENA_Pos) /*!< 0x80000000 */ +#define USB_OTG_DIEPCTL_EPENA USB_OTG_DIEPCTL_EPENA_Msk /*!< Endpoint enable */ + +/******************** Bit definition for USB_OTG_HCCHAR register ********************/ +#define USB_OTG_HCCHAR_MPSIZ_Pos (0U) +#define USB_OTG_HCCHAR_MPSIZ_Msk (0x7FFUL << USB_OTG_HCCHAR_MPSIZ_Pos) /*!< 0x000007FF */ +#define USB_OTG_HCCHAR_MPSIZ USB_OTG_HCCHAR_MPSIZ_Msk /*!< Maximum packet size */ + +#define USB_OTG_HCCHAR_EPNUM_Pos (11U) +#define USB_OTG_HCCHAR_EPNUM_Msk (0xFUL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00007800 */ +#define USB_OTG_HCCHAR_EPNUM USB_OTG_HCCHAR_EPNUM_Msk /*!< Endpoint number */ +#define USB_OTG_HCCHAR_EPNUM_0 (0x1UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00000800 */ +#define USB_OTG_HCCHAR_EPNUM_1 (0x2UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00001000 */ +#define USB_OTG_HCCHAR_EPNUM_2 (0x4UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00002000 */ +#define USB_OTG_HCCHAR_EPNUM_3 (0x8UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00004000 */ +#define USB_OTG_HCCHAR_EPDIR_Pos (15U) +#define USB_OTG_HCCHAR_EPDIR_Msk (0x1UL << USB_OTG_HCCHAR_EPDIR_Pos) /*!< 0x00008000 */ +#define USB_OTG_HCCHAR_EPDIR USB_OTG_HCCHAR_EPDIR_Msk /*!< Endpoint direction */ +#define USB_OTG_HCCHAR_LSDEV_Pos (17U) +#define USB_OTG_HCCHAR_LSDEV_Msk (0x1UL << USB_OTG_HCCHAR_LSDEV_Pos) /*!< 0x00020000 */ +#define USB_OTG_HCCHAR_LSDEV USB_OTG_HCCHAR_LSDEV_Msk /*!< Low-speed device */ + +#define USB_OTG_HCCHAR_EPTYP_Pos (18U) +#define USB_OTG_HCCHAR_EPTYP_Msk (0x3UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x000C0000 */ +#define USB_OTG_HCCHAR_EPTYP USB_OTG_HCCHAR_EPTYP_Msk /*!< Endpoint type */ +#define USB_OTG_HCCHAR_EPTYP_0 (0x1UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00040000 */ +#define USB_OTG_HCCHAR_EPTYP_1 (0x2UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00080000 */ + +#define USB_OTG_HCCHAR_MC_Pos (20U) +#define USB_OTG_HCCHAR_MC_Msk (0x3UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00300000 */ +#define USB_OTG_HCCHAR_MC USB_OTG_HCCHAR_MC_Msk /*!< Multi Count (MC) / Error Count (EC) */ +#define USB_OTG_HCCHAR_MC_0 (0x1UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00100000 */ +#define USB_OTG_HCCHAR_MC_1 (0x2UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00200000 */ + +#define USB_OTG_HCCHAR_DAD_Pos (22U) +#define USB_OTG_HCCHAR_DAD_Msk (0x7FUL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x1FC00000 */ +#define USB_OTG_HCCHAR_DAD USB_OTG_HCCHAR_DAD_Msk /*!< Device address */ +#define USB_OTG_HCCHAR_DAD_0 (0x01UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00400000 */ +#define USB_OTG_HCCHAR_DAD_1 (0x02UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00800000 */ +#define USB_OTG_HCCHAR_DAD_2 (0x04UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x01000000 */ +#define USB_OTG_HCCHAR_DAD_3 (0x08UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x02000000 */ +#define USB_OTG_HCCHAR_DAD_4 (0x10UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x04000000 */ +#define USB_OTG_HCCHAR_DAD_5 (0x20UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x08000000 */ +#define USB_OTG_HCCHAR_DAD_6 (0x40UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x10000000 */ +#define USB_OTG_HCCHAR_ODDFRM_Pos (29U) +#define USB_OTG_HCCHAR_ODDFRM_Msk (0x1UL << USB_OTG_HCCHAR_ODDFRM_Pos) /*!< 0x20000000 */ +#define USB_OTG_HCCHAR_ODDFRM USB_OTG_HCCHAR_ODDFRM_Msk /*!< Odd frame */ +#define USB_OTG_HCCHAR_CHDIS_Pos (30U) +#define USB_OTG_HCCHAR_CHDIS_Msk (0x1UL << USB_OTG_HCCHAR_CHDIS_Pos) /*!< 0x40000000 */ +#define USB_OTG_HCCHAR_CHDIS USB_OTG_HCCHAR_CHDIS_Msk /*!< Channel disable */ +#define USB_OTG_HCCHAR_CHENA_Pos (31U) +#define USB_OTG_HCCHAR_CHENA_Msk (0x1UL << USB_OTG_HCCHAR_CHENA_Pos) /*!< 0x80000000 */ +#define USB_OTG_HCCHAR_CHENA USB_OTG_HCCHAR_CHENA_Msk /*!< Channel enable */ + +/******************** Bit definition for USB_OTG_HCSPLT register ********************/ + +#define USB_OTG_HCSPLT_PRTADDR_Pos (0U) +#define USB_OTG_HCSPLT_PRTADDR_Msk (0x7FUL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x0000007F */ +#define USB_OTG_HCSPLT_PRTADDR USB_OTG_HCSPLT_PRTADDR_Msk /*!< Port address */ +#define USB_OTG_HCSPLT_PRTADDR_0 (0x01UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000001 */ +#define USB_OTG_HCSPLT_PRTADDR_1 (0x02UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000002 */ +#define USB_OTG_HCSPLT_PRTADDR_2 (0x04UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000004 */ +#define USB_OTG_HCSPLT_PRTADDR_3 (0x08UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000008 */ +#define USB_OTG_HCSPLT_PRTADDR_4 (0x10UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000010 */ +#define USB_OTG_HCSPLT_PRTADDR_5 (0x20UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000020 */ +#define USB_OTG_HCSPLT_PRTADDR_6 (0x40UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000040 */ + +#define USB_OTG_HCSPLT_HUBADDR_Pos (7U) +#define USB_OTG_HCSPLT_HUBADDR_Msk (0x7FUL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00003F80 */ +#define USB_OTG_HCSPLT_HUBADDR USB_OTG_HCSPLT_HUBADDR_Msk /*!< Hub address */ +#define USB_OTG_HCSPLT_HUBADDR_0 (0x01UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000080 */ +#define USB_OTG_HCSPLT_HUBADDR_1 (0x02UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000100 */ +#define USB_OTG_HCSPLT_HUBADDR_2 (0x04UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000200 */ +#define USB_OTG_HCSPLT_HUBADDR_3 (0x08UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000400 */ +#define USB_OTG_HCSPLT_HUBADDR_4 (0x10UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000800 */ +#define USB_OTG_HCSPLT_HUBADDR_5 (0x20UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00001000 */ +#define USB_OTG_HCSPLT_HUBADDR_6 (0x40UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00002000 */ + +#define USB_OTG_HCSPLT_XACTPOS_Pos (14U) +#define USB_OTG_HCSPLT_XACTPOS_Msk (0x3UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x0000C000 */ +#define USB_OTG_HCSPLT_XACTPOS USB_OTG_HCSPLT_XACTPOS_Msk /*!< XACTPOS */ +#define USB_OTG_HCSPLT_XACTPOS_0 (0x1UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00004000 */ +#define USB_OTG_HCSPLT_XACTPOS_1 (0x2UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00008000 */ +#define USB_OTG_HCSPLT_COMPLSPLT_Pos (16U) +#define USB_OTG_HCSPLT_COMPLSPLT_Msk (0x1UL << USB_OTG_HCSPLT_COMPLSPLT_Pos) /*!< 0x00010000 */ +#define USB_OTG_HCSPLT_COMPLSPLT USB_OTG_HCSPLT_COMPLSPLT_Msk /*!< Do complete split */ +#define USB_OTG_HCSPLT_SPLITEN_Pos (31U) +#define USB_OTG_HCSPLT_SPLITEN_Msk (0x1UL << USB_OTG_HCSPLT_SPLITEN_Pos) /*!< 0x80000000 */ +#define USB_OTG_HCSPLT_SPLITEN USB_OTG_HCSPLT_SPLITEN_Msk /*!< Split enable */ + +/******************** Bit definition for USB_OTG_HCINT register ********************/ +#define USB_OTG_HCINT_XFRC_Pos (0U) +#define USB_OTG_HCINT_XFRC_Msk (0x1UL << USB_OTG_HCINT_XFRC_Pos) /*!< 0x00000001 */ +#define USB_OTG_HCINT_XFRC USB_OTG_HCINT_XFRC_Msk /*!< Transfer completed */ +#define USB_OTG_HCINT_CHH_Pos (1U) +#define USB_OTG_HCINT_CHH_Msk (0x1UL << USB_OTG_HCINT_CHH_Pos) /*!< 0x00000002 */ +#define USB_OTG_HCINT_CHH USB_OTG_HCINT_CHH_Msk /*!< Channel halted */ +#define USB_OTG_HCINT_AHBERR_Pos (2U) +#define USB_OTG_HCINT_AHBERR_Msk (0x1UL << USB_OTG_HCINT_AHBERR_Pos) /*!< 0x00000004 */ +#define USB_OTG_HCINT_AHBERR USB_OTG_HCINT_AHBERR_Msk /*!< AHB error */ +#define USB_OTG_HCINT_STALL_Pos (3U) +#define USB_OTG_HCINT_STALL_Msk (0x1UL << USB_OTG_HCINT_STALL_Pos) /*!< 0x00000008 */ +#define USB_OTG_HCINT_STALL USB_OTG_HCINT_STALL_Msk /*!< STALL response received interrupt */ +#define USB_OTG_HCINT_NAK_Pos (4U) +#define USB_OTG_HCINT_NAK_Msk (0x1UL << USB_OTG_HCINT_NAK_Pos) /*!< 0x00000010 */ +#define USB_OTG_HCINT_NAK USB_OTG_HCINT_NAK_Msk /*!< NAK response received interrupt */ +#define USB_OTG_HCINT_ACK_Pos (5U) +#define USB_OTG_HCINT_ACK_Msk (0x1UL << USB_OTG_HCINT_ACK_Pos) /*!< 0x00000020 */ +#define USB_OTG_HCINT_ACK USB_OTG_HCINT_ACK_Msk /*!< ACK response received/transmitted interrupt */ +#define USB_OTG_HCINT_NYET_Pos (6U) +#define USB_OTG_HCINT_NYET_Msk (0x1UL << USB_OTG_HCINT_NYET_Pos) /*!< 0x00000040 */ +#define USB_OTG_HCINT_NYET USB_OTG_HCINT_NYET_Msk /*!< Response received interrupt */ +#define USB_OTG_HCINT_TXERR_Pos (7U) +#define USB_OTG_HCINT_TXERR_Msk (0x1UL << USB_OTG_HCINT_TXERR_Pos) /*!< 0x00000080 */ +#define USB_OTG_HCINT_TXERR USB_OTG_HCINT_TXERR_Msk /*!< Transaction error */ +#define USB_OTG_HCINT_BBERR_Pos (8U) +#define USB_OTG_HCINT_BBERR_Msk (0x1UL << USB_OTG_HCINT_BBERR_Pos) /*!< 0x00000100 */ +#define USB_OTG_HCINT_BBERR USB_OTG_HCINT_BBERR_Msk /*!< Babble error */ +#define USB_OTG_HCINT_FRMOR_Pos (9U) +#define USB_OTG_HCINT_FRMOR_Msk (0x1UL << USB_OTG_HCINT_FRMOR_Pos) /*!< 0x00000200 */ +#define USB_OTG_HCINT_FRMOR USB_OTG_HCINT_FRMOR_Msk /*!< Frame overrun */ +#define USB_OTG_HCINT_DTERR_Pos (10U) +#define USB_OTG_HCINT_DTERR_Msk (0x1UL << USB_OTG_HCINT_DTERR_Pos) /*!< 0x00000400 */ +#define USB_OTG_HCINT_DTERR USB_OTG_HCINT_DTERR_Msk /*!< Data toggle error */ + +/******************** Bit definition for USB_OTG_DIEPINT register ********************/ +#define USB_OTG_DIEPINT_XFRC_Pos (0U) +#define USB_OTG_DIEPINT_XFRC_Msk (0x1UL << USB_OTG_DIEPINT_XFRC_Pos) /*!< 0x00000001 */ +#define USB_OTG_DIEPINT_XFRC USB_OTG_DIEPINT_XFRC_Msk /*!< Transfer completed interrupt */ +#define USB_OTG_DIEPINT_EPDISD_Pos (1U) +#define USB_OTG_DIEPINT_EPDISD_Msk (0x1UL << USB_OTG_DIEPINT_EPDISD_Pos) /*!< 0x00000002 */ +#define USB_OTG_DIEPINT_EPDISD USB_OTG_DIEPINT_EPDISD_Msk /*!< Endpoint disabled interrupt */ +#define USB_OTG_DIEPINT_AHBERR_Pos (2U) +#define USB_OTG_DIEPINT_AHBERR_Msk (0x1UL << USB_OTG_DIEPINT_AHBERR_Pos) /*!< 0x00000004 */ +#define USB_OTG_DIEPINT_AHBERR USB_OTG_DIEPINT_AHBERR_Msk /*!< AHB Error (AHBErr) during an IN transaction */ +#define USB_OTG_DIEPINT_TOC_Pos (3U) +#define USB_OTG_DIEPINT_TOC_Msk (0x1UL << USB_OTG_DIEPINT_TOC_Pos) /*!< 0x00000008 */ +#define USB_OTG_DIEPINT_TOC USB_OTG_DIEPINT_TOC_Msk /*!< Timeout condition */ +#define USB_OTG_DIEPINT_ITTXFE_Pos (4U) +#define USB_OTG_DIEPINT_ITTXFE_Msk (0x1UL << USB_OTG_DIEPINT_ITTXFE_Pos) /*!< 0x00000010 */ +#define USB_OTG_DIEPINT_ITTXFE USB_OTG_DIEPINT_ITTXFE_Msk /*!< IN token received when TxFIFO is empty */ +#define USB_OTG_DIEPINT_INEPNM_Pos (5U) +#define USB_OTG_DIEPINT_INEPNM_Msk (0x1UL << USB_OTG_DIEPINT_INEPNM_Pos) /*!< 0x00000004 */ +#define USB_OTG_DIEPINT_INEPNM USB_OTG_DIEPINT_INEPNM_Msk /*!< IN token received with EP mismatch */ +#define USB_OTG_DIEPINT_INEPNE_Pos (6U) +#define USB_OTG_DIEPINT_INEPNE_Msk (0x1UL << USB_OTG_DIEPINT_INEPNE_Pos) /*!< 0x00000040 */ +#define USB_OTG_DIEPINT_INEPNE USB_OTG_DIEPINT_INEPNE_Msk /*!< IN endpoint NAK effective */ +#define USB_OTG_DIEPINT_TXFE_Pos (7U) +#define USB_OTG_DIEPINT_TXFE_Msk (0x1UL << USB_OTG_DIEPINT_TXFE_Pos) /*!< 0x00000080 */ +#define USB_OTG_DIEPINT_TXFE USB_OTG_DIEPINT_TXFE_Msk /*!< Transmit FIFO empty */ +#define USB_OTG_DIEPINT_TXFIFOUDRN_Pos (8U) +#define USB_OTG_DIEPINT_TXFIFOUDRN_Msk (0x1UL << USB_OTG_DIEPINT_TXFIFOUDRN_Pos) /*!< 0x00000100 */ +#define USB_OTG_DIEPINT_TXFIFOUDRN USB_OTG_DIEPINT_TXFIFOUDRN_Msk /*!< Transmit Fifo Underrun */ +#define USB_OTG_DIEPINT_BNA_Pos (9U) +#define USB_OTG_DIEPINT_BNA_Msk (0x1UL << USB_OTG_DIEPINT_BNA_Pos) /*!< 0x00000200 */ +#define USB_OTG_DIEPINT_BNA USB_OTG_DIEPINT_BNA_Msk /*!< Buffer not available interrupt */ +#define USB_OTG_DIEPINT_PKTDRPSTS_Pos (11U) +#define USB_OTG_DIEPINT_PKTDRPSTS_Msk (0x1UL << USB_OTG_DIEPINT_PKTDRPSTS_Pos) /*!< 0x00000800 */ +#define USB_OTG_DIEPINT_PKTDRPSTS USB_OTG_DIEPINT_PKTDRPSTS_Msk /*!< Packet dropped status */ +#define USB_OTG_DIEPINT_BERR_Pos (12U) +#define USB_OTG_DIEPINT_BERR_Msk (0x1UL << USB_OTG_DIEPINT_BERR_Pos) /*!< 0x00001000 */ +#define USB_OTG_DIEPINT_BERR USB_OTG_DIEPINT_BERR_Msk /*!< Babble error interrupt */ +#define USB_OTG_DIEPINT_NAK_Pos (13U) +#define USB_OTG_DIEPINT_NAK_Msk (0x1UL << USB_OTG_DIEPINT_NAK_Pos) /*!< 0x00002000 */ +#define USB_OTG_DIEPINT_NAK USB_OTG_DIEPINT_NAK_Msk /*!< NAK interrupt */ + +/******************** Bit definition for USB_OTG_HCINTMSK register ********************/ +#define USB_OTG_HCINTMSK_XFRCM_Pos (0U) +#define USB_OTG_HCINTMSK_XFRCM_Msk (0x1UL << USB_OTG_HCINTMSK_XFRCM_Pos) /*!< 0x00000001 */ +#define USB_OTG_HCINTMSK_XFRCM USB_OTG_HCINTMSK_XFRCM_Msk /*!< Transfer completed mask */ +#define USB_OTG_HCINTMSK_CHHM_Pos (1U) +#define USB_OTG_HCINTMSK_CHHM_Msk (0x1UL << USB_OTG_HCINTMSK_CHHM_Pos) /*!< 0x00000002 */ +#define USB_OTG_HCINTMSK_CHHM USB_OTG_HCINTMSK_CHHM_Msk /*!< Channel halted mask */ +#define USB_OTG_HCINTMSK_AHBERR_Pos (2U) +#define USB_OTG_HCINTMSK_AHBERR_Msk (0x1UL << USB_OTG_HCINTMSK_AHBERR_Pos) /*!< 0x00000004 */ +#define USB_OTG_HCINTMSK_AHBERR USB_OTG_HCINTMSK_AHBERR_Msk /*!< AHB error */ +#define USB_OTG_HCINTMSK_STALLM_Pos (3U) +#define USB_OTG_HCINTMSK_STALLM_Msk (0x1UL << USB_OTG_HCINTMSK_STALLM_Pos) /*!< 0x00000008 */ +#define USB_OTG_HCINTMSK_STALLM USB_OTG_HCINTMSK_STALLM_Msk /*!< STALL response received interrupt mask */ +#define USB_OTG_HCINTMSK_NAKM_Pos (4U) +#define USB_OTG_HCINTMSK_NAKM_Msk (0x1UL << USB_OTG_HCINTMSK_NAKM_Pos) /*!< 0x00000010 */ +#define USB_OTG_HCINTMSK_NAKM USB_OTG_HCINTMSK_NAKM_Msk /*!< NAK response received interrupt mask */ +#define USB_OTG_HCINTMSK_ACKM_Pos (5U) +#define USB_OTG_HCINTMSK_ACKM_Msk (0x1UL << USB_OTG_HCINTMSK_ACKM_Pos) /*!< 0x00000020 */ +#define USB_OTG_HCINTMSK_ACKM USB_OTG_HCINTMSK_ACKM_Msk /*!< ACK response received/transmitted interrupt mask */ +#define USB_OTG_HCINTMSK_NYET_Pos (6U) +#define USB_OTG_HCINTMSK_NYET_Msk (0x1UL << USB_OTG_HCINTMSK_NYET_Pos) /*!< 0x00000040 */ +#define USB_OTG_HCINTMSK_NYET USB_OTG_HCINTMSK_NYET_Msk /*!< response received interrupt mask */ +#define USB_OTG_HCINTMSK_TXERRM_Pos (7U) +#define USB_OTG_HCINTMSK_TXERRM_Msk (0x1UL << USB_OTG_HCINTMSK_TXERRM_Pos) /*!< 0x00000080 */ +#define USB_OTG_HCINTMSK_TXERRM USB_OTG_HCINTMSK_TXERRM_Msk /*!< Transaction error mask */ +#define USB_OTG_HCINTMSK_BBERRM_Pos (8U) +#define USB_OTG_HCINTMSK_BBERRM_Msk (0x1UL << USB_OTG_HCINTMSK_BBERRM_Pos) /*!< 0x00000100 */ +#define USB_OTG_HCINTMSK_BBERRM USB_OTG_HCINTMSK_BBERRM_Msk /*!< Babble error mask */ +#define USB_OTG_HCINTMSK_FRMORM_Pos (9U) +#define USB_OTG_HCINTMSK_FRMORM_Msk (0x1UL << USB_OTG_HCINTMSK_FRMORM_Pos) /*!< 0x00000200 */ +#define USB_OTG_HCINTMSK_FRMORM USB_OTG_HCINTMSK_FRMORM_Msk /*!< Frame overrun mask */ +#define USB_OTG_HCINTMSK_DTERRM_Pos (10U) +#define USB_OTG_HCINTMSK_DTERRM_Msk (0x1UL << USB_OTG_HCINTMSK_DTERRM_Pos) /*!< 0x00000400 */ +#define USB_OTG_HCINTMSK_DTERRM USB_OTG_HCINTMSK_DTERRM_Msk /*!< Data toggle error mask */ + +/******************** Bit definition for USB_OTG_DIEPTSIZ register ********************/ + +#define USB_OTG_DIEPTSIZ_XFRSIZ_Pos (0U) +#define USB_OTG_DIEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */ +#define USB_OTG_DIEPTSIZ_XFRSIZ USB_OTG_DIEPTSIZ_XFRSIZ_Msk /*!< Transfer size */ +#define USB_OTG_DIEPTSIZ_PKTCNT_Pos (19U) +#define USB_OTG_DIEPTSIZ_PKTCNT_Msk (0x3FFUL << USB_OTG_DIEPTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */ +#define USB_OTG_DIEPTSIZ_PKTCNT USB_OTG_DIEPTSIZ_PKTCNT_Msk /*!< Packet count */ +#define USB_OTG_DIEPTSIZ_MULCNT_Pos (29U) +#define USB_OTG_DIEPTSIZ_MULCNT_Msk (0x3UL << USB_OTG_DIEPTSIZ_MULCNT_Pos) /*!< 0x60000000 */ +#define USB_OTG_DIEPTSIZ_MULCNT USB_OTG_DIEPTSIZ_MULCNT_Msk /*!< Packet count */ +/******************** Bit definition for USB_OTG_HCTSIZ register ********************/ +#define USB_OTG_HCTSIZ_XFRSIZ_Pos (0U) +#define USB_OTG_HCTSIZ_XFRSIZ_Msk (0x7FFFFUL << USB_OTG_HCTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */ +#define USB_OTG_HCTSIZ_XFRSIZ USB_OTG_HCTSIZ_XFRSIZ_Msk /*!< Transfer size */ +#define USB_OTG_HCTSIZ_PKTCNT_Pos (19U) +#define USB_OTG_HCTSIZ_PKTCNT_Msk (0x3FFUL << USB_OTG_HCTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */ +#define USB_OTG_HCTSIZ_PKTCNT USB_OTG_HCTSIZ_PKTCNT_Msk /*!< Packet count */ +#define USB_OTG_HCTSIZ_DOPING_Pos (31U) +#define USB_OTG_HCTSIZ_DOPING_Msk (0x1UL << USB_OTG_HCTSIZ_DOPING_Pos) /*!< 0x80000000 */ +#define USB_OTG_HCTSIZ_DOPING USB_OTG_HCTSIZ_DOPING_Msk /*!< Do PING */ +#define USB_OTG_HCTSIZ_DPID_Pos (29U) +#define USB_OTG_HCTSIZ_DPID_Msk (0x3UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x60000000 */ +#define USB_OTG_HCTSIZ_DPID USB_OTG_HCTSIZ_DPID_Msk /*!< Data PID */ +#define USB_OTG_HCTSIZ_DPID_0 (0x1UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x20000000 */ +#define USB_OTG_HCTSIZ_DPID_1 (0x2UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for USB_OTG_DIEPDMA register ********************/ +#define USB_OTG_DIEPDMA_DMAADDR_Pos (0U) +#define USB_OTG_DIEPDMA_DMAADDR_Msk (0xFFFFFFFFUL << USB_OTG_DIEPDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */ +#define USB_OTG_DIEPDMA_DMAADDR USB_OTG_DIEPDMA_DMAADDR_Msk /*!< DMA address */ + +/******************** Bit definition for USB_OTG_HCDMA register ********************/ +#define USB_OTG_HCDMA_DMAADDR_Pos (0U) +#define USB_OTG_HCDMA_DMAADDR_Msk (0xFFFFFFFFUL << USB_OTG_HCDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */ +#define USB_OTG_HCDMA_DMAADDR USB_OTG_HCDMA_DMAADDR_Msk /*!< DMA address */ + +/******************** Bit definition for USB_OTG_DTXFSTS register ********************/ +#define USB_OTG_DTXFSTS_INEPTFSAV_Pos (0U) +#define USB_OTG_DTXFSTS_INEPTFSAV_Msk (0xFFFFUL << USB_OTG_DTXFSTS_INEPTFSAV_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DTXFSTS_INEPTFSAV USB_OTG_DTXFSTS_INEPTFSAV_Msk /*!< IN endpoint TxFIFO space available */ + +/******************** Bit definition for USB_OTG_DIEPTXF register ********************/ +#define USB_OTG_DIEPTXF_INEPTXSA_Pos (0U) +#define USB_OTG_DIEPTXF_INEPTXSA_Msk (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXSA_Pos) /*!< 0x0000FFFF */ +#define USB_OTG_DIEPTXF_INEPTXSA USB_OTG_DIEPTXF_INEPTXSA_Msk /*!< IN endpoint FIFOx transmit RAM start address */ +#define USB_OTG_DIEPTXF_INEPTXFD_Pos (16U) +#define USB_OTG_DIEPTXF_INEPTXFD_Msk (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXFD_Pos) /*!< 0xFFFF0000 */ +#define USB_OTG_DIEPTXF_INEPTXFD USB_OTG_DIEPTXF_INEPTXFD_Msk /*!< IN endpoint TxFIFO depth */ + +/******************** Bit definition for USB_OTG_DOEPCTL register ********************/ + +#define USB_OTG_DOEPCTL_MPSIZ_Pos (0U) +#define USB_OTG_DOEPCTL_MPSIZ_Msk (0x7FFUL << USB_OTG_DOEPCTL_MPSIZ_Pos) /*!< 0x000007FF */ +#define USB_OTG_DOEPCTL_MPSIZ USB_OTG_DOEPCTL_MPSIZ_Msk /*!< Maximum packet size */ /*! +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_F1C100S + +#include "osal/osal.h" +#include +#include +#include "musb_def.h" +#include "bsp/board.h" + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + + +#define REQUEST_TYPE_INVALID (0xFFu) + +typedef struct { + uint_fast16_t beg; /* offset of including first element */ + uint_fast16_t end; /* offset of excluding the last element */ +} free_block_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ +} pipe_state_t; + +typedef struct +{ + tusb_control_request_t setup_packet; + uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ + int8_t status_out; + pipe_state_t pipe0; + pipe_state_t pipe[2][7]; /* pipe[direction][endpoint number - 1] */ + uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ +} dcd_data_t; + +/*------------------------------------------------------------------ + * SUNXI FUNCTION + *------------------------------------------------------------------*/ + +static void usb_phy_write(int addr, int data, int len) +{ + int j = 0, usbc_bit = 0; + void *dest = (void *)USBC_REG_CSR(USBC0_BASE); + + usbc_bit = 1 << (0 * 2); + for (j = 0; j < len; j++) + { + /* set the bit address to be written */ + USBC_ClrBit_Mask_l(dest, 0xff << 8); + USBC_SetBit_Mask_l(dest, (addr + j) << 8); + + USBC_ClrBit_Mask_l(dest, usbc_bit); + /* set data bit */ + if (data & 0x1) + USBC_SetBit_Mask_l(dest, 1 << 7); + else + USBC_ClrBit_Mask_l(dest, 1 << 7); + + USBC_SetBit_Mask_l(dest, usbc_bit); + + USBC_ClrBit_Mask_l(dest, usbc_bit); + + data >>= 1; + } +} + +static void delay_ms(uint32_t ms) +{ +#if CFG_TUSB_OS == OPT_OS_NONE + int now = board_millis(); + while (board_millis() - now <= ms) asm("nop"); +#else + osal_task_delay(ms); +#endif +} + +static void USBC_HardwareReset(void) +{ + // Reset phy and controller + USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); + USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); + delay_ms(2); + + USBC_REG_set_bit_l(USBPHY_CLK_GAT_BIT, USBPHY_CLK_REG); + USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); + + USBC_REG_set_bit_l(BUS_CLK_USB_BIT, BUS_CLK_GATE0_REG); + USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); +} + +static void USBC_PhyConfig(void) +{ + /* Regulation 45 ohms */ + usb_phy_write(0x0c, 0x01, 1); + + /* adjust PHY's magnitude and rate */ + usb_phy_write(0x20, 0x14, 5); + + /* threshold adjustment disconnect */ + usb_phy_write(0x2a, 3, 2); + + return; +} + +static void USBC_ConfigFIFO_Base(void) +{ + u32 reg_value; + + /* config usb fifo, 8kb mode */ + reg_value = USBC_Readl(SUNXI_SRAMC_BASE + 0x04); + reg_value &= ~(0x03 << 0); + reg_value |= (1 << 0); + USBC_Writel(reg_value, SUNXI_SRAMC_BASE + 0x04); +} + +static unsigned int USBC_WakeUp_ClearChangeDetect(unsigned int reg_val) +{ + unsigned int temp = reg_val; + /* vbus, id, dpdm, these bit is set 1 to clear, so we clear these bit when operate other bits */ + temp &= ~(1 << USBC_BP_ISCR_VBUS_CHANGE_DETECT); + temp &= ~(1 << USBC_BP_ISCR_ID_CHANGE_DETECT); + temp &= ~(1 << USBC_BP_ISCR_DPDM_CHANGE_DETECT); + + return temp; +} + +static void USBC_EnableDpDmPullUp(void) +{ + u32 reg_val = USBC_Readl(USBC_REG_ISCR(USBC0_BASE)); + reg_val |= (1 << USBC_BP_ISCR_DPDM_PULLUP_EN); + reg_val |= 3<beg) || (cur->end <= addr)); ++cur) ; + return cur; +} + +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) +{ + free_block_t *p = find_containing_block(blks, blks + num, addr); + TU_ASSERT(p != blks + num, -2); + if (p->beg == addr) { + /* Shrink block */ + p->beg = addr + size; + if (p->beg != p->end) return 0; + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } else { + /* Split into 2 blocks */ + free_block_t tmp = { + .beg = addr + size, + .end = p->end + }; + p->end = addr; + if (p->beg == p->end) { + if (tmp.beg != tmp.end) { + *p = tmp; + return 0; + } + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } + if (tmp.beg == tmp.end) return 0; + blks[num] = tmp; + return 1; + } +} + +static inline unsigned free_block_size(free_block_t const *blk) +{ + return blk->end - blk->beg; +} + +#if 0 +static inline void print_block_list(free_block_t const *blk, unsigned num) +{ + TU_LOG1("*************\n"); + for (unsigned i = 0; i < num; ++i) { + TU_LOG1(" Blk%u %u %u\n", i, blk->beg, blk->end); + ++blk; + } +} +#else +#define print_block_list(a,b) +#endif + +#if CFG_TUSB_MCU == OPT_MCU_F1C100S +#define USB_FIFO_SIZE_KB 4 +#else +#error "Unsupported MCU" +#endif + +static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) +{ + free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; + unsigned num_blocks = 1; + /* Backup current EP to restore later */ + u8 backup_ep = USBC_GetActiveEp(); + + /* Initialize free memory block list */ + free_blocks[0].beg = 64 / 8; + free_blocks[0].end = (USB_FIFO_SIZE_KB << 10) / 8; /* 2KiB / 8 bytes */ + for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + uint_fast16_t addr; + int num; + USBC_SelectActiveEp(i); + addr = USBC_Readw(USBC_REG_TXFIFOAD(USBC0_BASE)); + if (addr) { + unsigned sz = USBC_Readb(USBC_REG_TXFIFOSZ(USBC0_BASE)); + unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + addr = USBC_Readw(USBC_REG_RXFIFOAD(USBC0_BASE)); + if (addr) { + unsigned sz = USBC_Readb(USBC_REG_RXFIFOSZ(USBC0_BASE)); + unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + } + print_block_list(free_blocks, num_blocks); + + USBC_SelectActiveEp(backup_ep); + + /* Find the best fit memory block */ + uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; + free_block_t const *min = NULL; + uint_fast16_t min_sz = 0xFFFFu; + free_block_t const *end = &free_blocks[num_blocks]; + for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { + uint_fast16_t sz = free_block_size(cur); + if (sz < size_in_8byte_unit) continue; + if (size_in_8byte_unit == sz) return cur->beg; + if (sz < min_sz) min = cur; + } + TU_ASSERT(min, 0); + return min->beg; +} + +static void pipe_write_packet(void *buff, volatile void *fifo, unsigned cnt) +{ + u32 len = 0; + u32 i32 = 0; + u32 i8 = 0; + u8 *buf8 = 0; + u32 *buf32 = 0; + + //--<1>-- adjust data + buf32 = buff; + len = cnt; + + i32 = len >> 2; + i8 = len & 0x03; + + //--<2>-- deal with 4byte part + while (i32--) { + USBC_Writel(*buf32++, fifo); + } + + //--<3>-- deal with no 4byte part + buf8 = (u8 *)buf32; + while (i8--) { + USBC_Writeb(*buf8++, fifo); + } +} + +static void pipe_read_packet(void *buff, volatile void *fifo, unsigned cnt) +{ + u32 len = 0; + u32 i32 = 0; + u32 i8 = 0; + u8 *buf8 = 0; + u32 *buf32 = 0; + + //--<1>-- adjust data + buf32 = buff; + len = cnt; + + i32 = len >> 2; + i8 = len & 0x03; + + //--<2>-- deal with 4byte part + while (i32--) { + *buf32++ = USBC_Readl(fifo); + } + + //--<3>-- deal with no 4byte part + buf8 = (u8 *)buf32; + while (i8--) { + *buf8++ = USBC_Readb(fifo); + } +} + +static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) +{ + static const struct { + void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); + void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); + void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); + } ops[] = { + /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, + /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, + }; + tu_fifo_buffer_info_t info; + ops[dir].tu_fifo_get_info(f, &info); + unsigned total_len = len; + len = TU_MIN(total_len, info.len_lin); + ops[dir].pipe_read_write(info.ptr_lin, fifo, len); + unsigned rem = total_len - len; + if (rem) { + len = TU_MIN(rem, info.len_wrap); + ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); + rem -= len; + } + ops[dir].tu_fifo_advance(f, total_len - rem); +} + +/*------------------------------------------------------------------ + * TRANSFER FUNCTION DECLARATION + *------------------------------------------------------------------*/ + +static void process_setup_packet(uint8_t rhport) +{ + uint32_t *p = (uint32_t*)&_dcd.setup_packet; + p[0] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); + p[1] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); + + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); + + const unsigned len = _dcd.setup_packet.wLength; + _dcd.remaining_ctrl = len; + const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); + /* Clear RX FIFO and reverse the transaction direction */ + if (len && dir_in) __USBC_Dev_ep0_ReadDataHalf(); +} + +static bool handle_xfer_in(uint_fast8_t ep_addr) +{ + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + const unsigned rem = pipe->remaining; + + if (!rem) { + pipe->buf = NULL; + return true; + } + + const unsigned mps = USBC_Readw(USBC_REG_TXMAXP(USBC0_BASE)); + const unsigned len = TU_MIN(mps, rem); + uint8_t *buf = pipe->buf; + // TU_LOG1(" %p mps %d len %d rem %d\n", buf, mps, len, rem); + if (len) { + volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_IN); + } else { + pipe_write_packet(buf, addr, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + __USBC_Dev_Tx_WriteDataComplete(); + // TU_LOG1(" TXCSRL%d = %x %d\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); + return false; +} + +static bool handle_xfer_out(uint_fast8_t ep_addr) +{ + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + // TU_LOG1(" RXCSRL%d = %x\n", epnum_minus1 + 1, regs->RXCSRL); + + TU_ASSERT(__USBC_Dev_Rx_IsReadDataReady()); + + const unsigned mps = USBC_Readw(USBC_REG_RXMAXP(USBC0_BASE)); + const unsigned rem = pipe->remaining; + const unsigned vld = USBC_Readw(USBC_REG_RXCOUNT(USBC0_BASE)); + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + uint8_t *buf = pipe->buf; + if (len) { + volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_OUT); + } else { + pipe_read_packet(buf, addr, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + __USBC_Dev_Rx_ReadDataComplete(); + return false; +} + +static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned dir_in = tu_edpt_dir(ep_addr); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; + pipe->buf = buffer; + pipe->length = total_bytes; + pipe->remaining = total_bytes; + + USBC_SelectActiveEp(tu_edpt_number(ep_addr)); + + if (dir_in) { + handle_xfer_in(ep_addr); + } else { + if (__USBC_Dev_Rx_IsReadDataReady()) + __USBC_Dev_Rx_ReadDataComplete(); + } + return true; +} + +static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ + + const unsigned req = _dcd.setup_packet.bmRequestType; + TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); + + USBC_SelectActiveEp(0); + + if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { + /* STATUS OUT stage. + * MUSB controller automatically handles STATUS OUT packets without + * software helps. We do not have to do anything. And STATUS stage + * may have already finished and received the next setup packet + * without calling this function, so we have no choice but to + * invoke the callback function of status packet here. */ + // TU_LOG1(" STATUS OUT CSRL0 = %x\n", CSRL0); + _dcd.status_out = 0; + if (req == REQUEST_TYPE_INVALID) { + dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); + } else { + /* The next setup packet has already been received, it aborts + * invoking callback function to avoid confusing TUSB stack. */ + TU_LOG1("Drop CONTROL_STAGE_ACK\n"); + } + return true; + } + const unsigned dir_in = tu_edpt_dir(ep_addr); + if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ + TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); + const unsigned rem = _dcd.remaining_ctrl; + const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); + if (dir_in) { + pipe_write_packet(buffer, (volatile void*) USBC_REG_EPFIFO0(USBC0_BASE), len); + + _dcd.pipe0.buf = buffer + len; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = 0; + + _dcd.remaining_ctrl = rem - len; + if ((len < 64) || (rem == len)) { + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ + _dcd.status_out = 1; + /* Flush TX FIFO and reverse the transaction direction. */ + __USBC_Dev_ep0_WriteDataComplete(); + } else { + __USBC_Dev_ep0_WriteDataHalf(); + } + // TU_LOG1(" IN CSRL0 = %x\n", CSRL0); + } else { + // TU_LOG1(" OUT CSRL0 = %x\n", CSRL0); + _dcd.pipe0.buf = buffer; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = len; + __USBC_Dev_ep0_ReadDataHalf(); + } + } else if (dir_in) { + // TU_LOG1(" STATUS IN CSRL0 = %x\n", CSRL0); + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO and reverse the transaction direction */ + __USBC_Dev_ep0_ReadDataComplete(); + } + return true; +} + +static void process_ep0(uint8_t rhport) +{ + USBC_SelectActiveEp(0); + uint_fast8_t csrl = USBC_Readw(USBC_REG_CSR0(USBC0_BASE)); + + // TU_LOG1(" EP0 CSRL0 = %x\n", csrl); + + if (csrl & USB_CSRL0_STALLED) { + /* Returned STALL packet to HOST. */ + __USBC_Dev_ep0_ClearStall(); + return; + } + + unsigned req = _dcd.setup_packet.bmRequestType; + if (csrl & USB_CSRL0_SETEND) { + // TU_LOG1(" ABORT by the next packets\n"); + USBC_Dev_Ctrl_ClearSetupEnd(); + if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { + /* DATA stage was aborted by receiving STATUS or SETUP packet. */ + _dcd.pipe0.buf = NULL; + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + req & TUSB_DIR_IN_MASK, + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + req = REQUEST_TYPE_INVALID; + if (!(csrl & USB_CSRL0_RXRDY)) return; /* Received SETUP packet */ + } + + if (csrl & USB_CSRL0_RXRDY) { + /* Received SETUP or DATA OUT packet */ + if (req == REQUEST_TYPE_INVALID) { + /* SETUP */ + TU_ASSERT(sizeof(tusb_control_request_t) == USBC_Readw(USBC_REG_COUNT0(USBC0_BASE)),); + process_setup_packet(rhport); + return; + } + if (_dcd.pipe0.buf) { + /* DATA OUT */ + const unsigned vld = USBC_Readw(USBC_REG_COUNT0(USBC0_BASE)); + const unsigned rem = _dcd.pipe0.remaining; + const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); + pipe_read_packet(_dcd.pipe0.buf, (volatile void*)USBC_REG_EPFIFO0(USBC0_BASE), len); + + _dcd.pipe0.remaining = rem - len; + _dcd.remaining_ctrl -= len; + + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_OUT), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + return; + } + + /* When CSRL0 is zero, it means that completion of sending a any length packet + * or receiving a zero length packet. */ + if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { + /* STATUS IN */ + if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { + /* The address must be changed on completion of the control transfer. */ + USBC_Dev_SetAddress((uint8_t)_dcd.setup_packet.wValue); + } + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + return; + } + if (_dcd.pipe0.buf) { + /* DATA IN */ + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) +{ + bool completed; + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned epn = tu_edpt_number(ep_addr); + + USBC_SelectActiveEp(epn); + + if (dir_in) { + // TU_LOG1(" TXCSRL%d = %x\n", epn_minus1 + 1, regs->TXCSRL); + if (__USBC_Dev_Tx_IsEpStall()) { + __USBC_Dev_Tx_ClearStall(); + return; + } + completed = handle_xfer_in(ep_addr); + } else { + // TU_LOG1(" RXCSRL%d = %x\n", epn_minus1 + 1, regs->RXCSRL); + if (__USBC_Dev_Rx_IsEpStall()) { + __USBC_Dev_Rx_ClearStall(); + return; + } + completed = handle_xfer_out(ep_addr); + } + + if (completed) { + pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; + dcd_event_xfer_complete(rhport, ep_addr, + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), + * a control transfer state is SETUP or STATUS stage. */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.status_out = 0; + /* When pipe0.buf has not NULL, DATA stage works in progress. */ + _dcd.pipe0.buf = NULL; + + USBC_Writew(1, USBC_REG_INTTxE(USBC0_BASE)); /* Enable only EP0 */ + USBC_Writew(0, USBC_REG_INTRxE(USBC0_BASE)); + + dcd_event_bus_reset(rhport, USBC_Dev_QueryTransferMode(), true); +} + +/*------------------------------------------------------------------ + * Device API + *------------------------------------------------------------------*/ + +static void usb_isr_handler(void) { + dcd_int_handler(0); +} + +void dcd_init(uint8_t rhport) +{ + dcd_disconnect(rhport); + USBC_HardwareReset(); + USBC_PhyConfig(); + USBC_ConfigFIFO_Base(); + USBC_EnableDpDmPullUp(); + USBC_ForceIdToHigh(); // Force device mode + USBC_ForceVbusValidToHigh(); + USBC_SelectBus(USBC_IO_TYPE_PIO, 0, 0); + dcd_edpt_close_all(rhport); + + #if TUD_OPT_HIGH_SPEED + USBC_REG_set_bit_b(USBC_BP_POWER_D_HIGH_SPEED_EN, USBC_REG_PCTL(USBC0_BASE)); + #else + USBC_REG_clear_bit_b(USBC_BP_POWER_D_HIGH_SPEED_EN, USBC_REG_PCTL(USBC0_BASE)); + #endif + + USBC_Writeb((1 << USBC_BP_INTUSBE_EN_SUSPEND) + | (1 << USBC_BP_INTUSBE_EN_RESUME) + | (1 << USBC_BP_INTUSBE_EN_RESET) + | (1 << USBC_BP_INTUSBE_EN_SOF) + | (1 << USBC_BP_INTUSBE_EN_DISCONNECT) + , USBC_REG_INTUSBE(USBC0_BASE)); + f1c100s_intc_clear_pend(F1C100S_IRQ_USBOTG); + f1c100s_intc_set_isr(F1C100S_IRQ_USBOTG, usb_isr_handler); + + dcd_connect(rhport); +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + USBC_REG_set_bit_b(USBC_BP_POWER_D_SOFT_CONNECT, USBC_REG_PCTL(USBC0_BASE)); +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + USBC_REG_clear_bit_b(USBC_BP_POWER_D_SOFT_CONNECT, USBC_REG_PCTL(USBC0_BASE)); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + f1c100s_intc_enable_irq(F1C100S_IRQ_USBOTG); +} + +static void musb_int_mask(void) +{ + f1c100s_intc_mask_irq(F1C100S_IRQ_USBOTG); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + f1c100s_intc_disable_irq(F1C100S_IRQ_USBOTG); +} + +static void musb_int_unmask(void) +{ + f1c100s_intc_unmask_irq(F1C100S_IRQ_USBOTG); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + (void)dev_addr; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO to return ACK. */ + USBC_SelectActiveEp(0); + __USBC_Dev_ep0_ReadDataComplete(); +} + +// Wake up host +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + USBC_REG_set_bit_b(USBC_BP_POWER_D_RESUME, USBC_REG_PCTL(USBC0_BASE)); + delay_ms(10); + USBC_REG_clear_bit_b(USBC_BP_POWER_D_RESUME, USBC_REG_PCTL(USBC0_BASE)); +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +#ifndef __ARMCC_VERSION +#define __clz __builtin_clz +#endif + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + uint16_t reg_val; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + const unsigned mps = tu_edpt_packet_size(ep_desc); + + TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + musb_int_mask(); + + // volatile hw_endpoint_t *regs = edpt_regs(epn - 1); + USBC_SelectActiveEp(epn); + if (dir_in) { + USBC_Writew(mps, USBC_REG_TXMAXP(USBC0_BASE)); + + reg_val = (1 << USBC_BP_TXCSR_D_MODE) + | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO) + | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE); + if (xfer == TUSB_XFER_ISOCHRONOUS) + reg_val |= (1 << USBC_BP_TXCSR_D_ISO); + USBC_Writew(reg_val, USBC_REG_TXCSR(USBC0_BASE)); + + USBC_INT_EnableTxEp(epn); + } else { + USBC_Writew(mps, USBC_REG_RXMAXP(USBC0_BASE)); + + reg_val = (1 << USBC_BP_RXCSR_D_FLUSH_FIFO) + | (1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE); + if (xfer == TUSB_XFER_ISOCHRONOUS) + reg_val |= (1 << USBC_BP_RXCSR_D_ISO); + USBC_Writew(reg_val, USBC_REG_RXCSR(USBC0_BASE)); + + USBC_INT_EnableRxEp(epn); + } + + /* Setup FIFO */ + int size_in_log2_minus3 = 28 - TU_MIN(28, __clz((uint32_t)mps)); + if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; + unsigned addr = find_free_memory(size_in_log2_minus3); + TU_ASSERT(addr); + + if (dir_in) { + USBC_Writew(addr, USBC_REG_TXFIFOAD(USBC0_BASE)); + USBC_Writeb(size_in_log2_minus3, USBC_REG_TXFIFOSZ(USBC0_BASE)); + } else { + USBC_Writew(addr, USBC_REG_RXFIFOAD(USBC0_BASE)); + USBC_Writeb(size_in_log2_minus3, USBC_REG_RXFIFOSZ(USBC0_BASE)); + } + + musb_int_unmask(); + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + (void) rhport; + musb_int_mask(); + USBC_Writew(1, USBC_REG_INTTxE(USBC0_BASE)); /* Enable only EP0 */ + USBC_Writew(0, USBC_REG_INTRxE(USBC0_BASE)); + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + USBC_SelectActiveEp(i); + USBC_Writew(0, USBC_REG_TXMAXP(USBC0_BASE)); + USBC_Writew((1 << USBC_BP_TXCSR_D_MODE) | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO), + USBC_REG_TXCSR(USBC0_BASE)); + + USBC_Writew(0, USBC_REG_RXMAXP(USBC0_BASE)); + USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO), + USBC_REG_RXCSR(USBC0_BASE)); + + USBC_Writew(0, USBC_REG_TXFIFOAD(USBC0_BASE)); + USBC_Writeb(0, USBC_REG_TXFIFOSZ(USBC0_BASE)); + USBC_Writew(0, USBC_REG_RXFIFOAD(USBC0_BASE)); + USBC_Writeb(0, USBC_REG_RXFIFOSZ(USBC0_BASE)); + } + musb_int_unmask(); +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + unsigned const dir_in = tu_edpt_dir(ep_addr); + + musb_int_mask(); + USBC_SelectActiveEp(epn); + if (dir_in) { + USBC_INT_DisableTxEp(epn); + USBC_Writew(0, USBC_REG_TXMAXP(USBC0_BASE)); + USBC_Writew((1 << USBC_BP_TXCSR_D_MODE) | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO), + USBC_REG_TXCSR(USBC0_BASE)); + + USBC_Writew(0, USBC_REG_TXFIFOAD(USBC0_BASE)); + USBC_Writeb(0, USBC_REG_TXFIFOSZ(USBC0_BASE)); + } else { + USBC_INT_DisableRxEp(epn); + USBC_Writew(0, USBC_REG_RXMAXP(USBC0_BASE)); + USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO), + USBC_REG_RXCSR(USBC0_BASE)); + + USBC_Writew(0, USBC_REG_RXFIFOAD(USBC0_BASE)); + USBC_Writeb(0, USBC_REG_RXFIFOSZ(USBC0_BASE)); + } + musb_int_unmask(); +} + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + unsigned const epnum = tu_edpt_number(ep_addr); + musb_int_mask(); + + if (epnum) { + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); + } else { + ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); + } + musb_int_unmask(); + return ret; +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + unsigned const epnum = tu_edpt_number(ep_addr); + TU_ASSERT(epnum); + + musb_int_mask(); + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); + musb_int_unmask(); + + return ret; +} + +// Stall endpoint +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + musb_int_mask(); + USBC_SelectActiveEp(epn); + if (0 == epn) { + if (!ep_addr) { /* Ignore EP80 */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.pipe0.buf = NULL; + __USBC_Dev_ep0_SendStall(); + } + } else { + if (tu_edpt_dir(ep_addr)) { /* IN */ + __USBC_Dev_Tx_SendStall(); + } else { /* OUT */ + TU_ASSERT(!__USBC_Dev_Rx_IsReadDataReady(),); + __USBC_Dev_Rx_SendStall(); + } + } + musb_int_unmask(); +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + musb_int_mask(); + USBC_SelectActiveEp(epn); + if (0 != epn) { + if (tu_edpt_dir(ep_addr)) { /* IN */ + __USBC_Dev_Tx_ClearStall(); + } else { /* OUT */ + __USBC_Dev_Rx_ClearStall(); + } + } + musb_int_unmask(); +} + + +void dcd_int_handler(uint8_t rhport) +{ + uint8_t is; + uint16_t txis, rxis; + + is = USBC_Readb(USBC_REG_INTUSB(USBC0_BASE)); /* read interrupt status */ + txis = USBC_Readw(USBC_REG_INTTx(USBC0_BASE)); /* read interrupt status */ + rxis = USBC_Readw(USBC_REG_INTRx(USBC0_BASE)); /* read interrupt status */ + + is &= USBC_Readb(USBC_REG_INTUSBE(USBC0_BASE)); /* ignore disabled interrupts */ + USBC_Writeb(is, USBC_REG_INTUSB(USBC0_BASE)); /* sunxi musb requires a write to interrupt register to clear */ + if (is & USBC_INTUSB_DISCONNECT) { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + if (is & USBC_INTUSB_SOF) { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + if (is & USBC_INTUSB_RESET) { + /* ep0 FADDR must be 0 when (re)entering peripheral mode */ + USBC_SelectActiveEp(0); + USBC_Dev_SetAddress(0); + process_bus_reset(rhport); + } + if (is & USBC_INTUSB_RESUME) { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + if (is & USBC_INTUSB_SUSPEND) { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + txis &= USBC_Readw(USBC_REG_INTTxE(USBC0_BASE)); + USBC_Writew(txis, USBC_REG_INTTx(USBC0_BASE)); + if (txis & USBC_INTTx_FLAG_EP0) { + process_ep0(rhport); + txis &= ~TU_BIT(0); + } + while (txis) { + unsigned const num = __builtin_ctz(txis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); + txis &= ~TU_BIT(num); + } + + rxis &= USBC_Readw(USBC_REG_INTRxE(USBC0_BASE)); + USBC_Writew(rxis, USBC_REG_INTRx(USBC0_BASE)); + while (rxis) { + unsigned const num = __builtin_ctz(rxis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); + rxis &= ~TU_BIT(num); + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/sunxi/musb_def.h b/circuitpython/lib/tinyusb/src/portable/sunxi/musb_def.h new file mode 100644 index 0000000..602b4f1 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/sunxi/musb_def.h @@ -0,0 +1,643 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * Copyright (c) 2021 Tian Yunhao (t123yh) + * Copyright (c) 2021 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MUSB_DEF +#define _TUSB_MUSB_DEF + + +#define USBC_Readb(reg) (*(volatile unsigned char *)(reg)) +#define USBC_Readw(reg) (*(volatile unsigned short *)(reg)) +#define USBC_Readl(reg) (*(volatile unsigned long *)(reg)) + +#define USBC_Writeb(value, reg) (*(volatile unsigned char *)(reg) = (value)) +#define USBC_Writew(value, reg) (*(volatile unsigned short *)(reg) = (value)) +#define USBC_Writel(value, reg) (*(volatile unsigned long *)(reg) = (value)) + + +#define USBC_SetBit_Mask_b(reg,mask) do { \ + unsigned char _r = USBC_Readb(reg); \ + _r |= (unsigned char)(mask); \ + USBC_Writeb(_r,reg); \ + }while(0) +#define USBC_SetBit_Mask_w(reg,mask) do { \ + unsigned short _r = USBC_Readw(reg); \ + _r |= (unsigned short)(mask); \ + USBC_Writew(_r,reg); \ + }while(0) +#define USBC_SetBit_Mask_l(reg,mask) do { \ + unsigned int _r = USBC_Readl(reg); \ + _r |= (unsigned int)(mask); \ + USBC_Writel(_r,reg); \ + }while(0) + + +#define USBC_ClrBit_Mask_b(reg,mask) do { \ + unsigned char _r = USBC_Readb(reg); \ + _r &= (~(unsigned char)(mask)); \ + USBC_Writeb(_r,reg); \ + }while(0); +#define USBC_ClrBit_Mask_w(reg,mask) do { \ + unsigned short _r = USBC_Readw(reg); \ + _r &= (~(unsigned short)(mask)); \ + USBC_Writew(_r,reg); \ + }while(0) +#define USBC_ClrBit_Mask_l(reg,mask) do { \ + unsigned int _r = USBC_Readl(reg); \ + _r &= (~(unsigned int)(mask)); \ + USBC_Writel(_r,reg); \ + }while(0) +#define USBC_REG_test_bit_b(bp, reg) (USBC_Readb(reg) & (1 << (bp))) +#define USBC_REG_test_bit_w(bp, reg) (USBC_Readw(reg) & (1 << (bp))) +#define USBC_REG_test_bit_l(bp, reg) (USBC_Readl(reg) & (1 << (bp))) + +#define USBC_REG_set_bit_b(bp, reg) (USBC_Writeb((USBC_Readb(reg) | (1 << (bp))) , (reg))) +#define USBC_REG_set_bit_w(bp, reg) (USBC_Writew((USBC_Readw(reg) | (1 << (bp))) , (reg))) +#define USBC_REG_set_bit_l(bp, reg) (USBC_Writel((USBC_Readl(reg) | (1 << (bp))) , (reg))) + +#define USBC_REG_clear_bit_b(bp, reg) (USBC_Writeb((USBC_Readb(reg) & (~ (1 << (bp)))) , (reg))) +#define USBC_REG_clear_bit_w(bp, reg) (USBC_Writew((USBC_Readw(reg) & (~ (1 << (bp)))) , (reg))) +#define USBC_REG_clear_bit_l(bp, reg) (USBC_Writel((USBC_Readl(reg) & (~ (1 << (bp)))) , (reg))) + +#define SW_UDC_EPNUMS 3 + +#define SUNXI_SRAMC_BASE 0x01c00000 +//--------------------------------------------------------------- +// reg base +//--------------------------------------------------------------- +#define USBC0_BASE 0x01c13000 +#define USBC1_BASE 0x01c14000 +#define USBC2_BASE 0x01c1E000 + +//Some reg whithin musb +#define USBPHY_CLK_REG 0x01c200CC +#define USBPHY_CLK_RST_BIT 0 +#define USBPHY_CLK_GAT_BIT 1 + +#define BUS_CLK_RST_REG 0x01c202c0 //Bus Clock Reset Register Bit24 : USB CLK RST +#define BUS_RST_USB_BIT 24 + +#define BUS_CLK_GATE0_REG 0x01c20060 //Bus Clock Gating Register Bit24 : USB CLK GATE 0: Mask 1 : Pass +#define BUS_CLK_USB_BIT 24 + +//#define USB_INTR + +#define NDMA_CFG_REG +//----------------------------------------------------------------------- +// musb reg offset +//----------------------------------------------------------------------- + +#define USBC_REG_o_FADDR 0x0098 +#define USBC_REG_o_PCTL 0x0040 +#define USBC_REG_o_INTTx 0x0044 +#define USBC_REG_o_INTRx 0x0046 +#define USBC_REG_o_INTTxE 0x0048 +#define USBC_REG_o_INTRxE 0x004A +#define USBC_REG_o_INTUSB 0x004C +#define USBC_REG_o_INTUSBE 0x0050 +#define USBC_REG_o_FRNUM 0x0054 +#define USBC_REG_o_EPIND 0x0042 +#define USBC_REG_o_TMCTL 0x007C + +#define USBC_REG_o_TXMAXP 0x0080 +#define USBC_REG_o_CSR0 0x0082 +#define USBC_REG_o_TXCSR 0x0082 +#define USBC_REG_o_RXMAXP 0x0084 +#define USBC_REG_o_RXCSR 0x0086 +#define USBC_REG_o_COUNT0 0x0088 +#define USBC_REG_o_RXCOUNT 0x0088 +#define USBC_REG_o_EP0TYPE 0x008C +#define USBC_REG_o_TXTYPE 0x008C +#define USBC_REG_o_NAKLIMIT0 0x008D +#define USBC_REG_o_TXINTERVAL 0x008D +#define USBC_REG_o_RXTYPE 0x008E +#define USBC_REG_o_RXINTERVAL 0x008F + +//#define USBC_REG_o_CONFIGDATA 0x001F // + +#define USBC_REG_o_EPFIFO0 0x0000 +#define USBC_REG_o_EPFIFO1 0x0004 +#define USBC_REG_o_EPFIFO2 0x0008 +#define USBC_REG_o_EPFIFO3 0x000C +#define USBC_REG_o_EPFIFO4 0x0010 +#define USBC_REG_o_EPFIFO5 0x0014 +#define USBC_REG_o_EPFIFOx(n) (0x0000 + (n<<2)) + +#define USBC_REG_o_DEVCTL 0x0041 + +#define USBC_REG_o_TXFIFOSZ 0x0090 +#define USBC_REG_o_RXFIFOSZ 0x0094 +#define USBC_REG_o_TXFIFOAD 0x0092 +#define USBC_REG_o_RXFIFOAD 0x0096 + +#define USBC_REG_o_VEND0 0x0043 +#define USBC_REG_o_VEND1 0x007D +#define USBC_REG_o_VEND3 0x007E + +//#define USBC_REG_o_PHYCTL 0x006C +#define USBC_REG_o_EPINFO 0x0078 +#define USBC_REG_o_RAMINFO 0x0079 +#define USBC_REG_o_LINKINFO 0x007A +#define USBC_REG_o_VPLEN 0x007B +#define USBC_REG_o_HSEOF 0x007C +#define USBC_REG_o_FSEOF 0x007D +#define USBC_REG_o_LSEOF 0x007E + +//new +#define USBC_REG_o_FADDR0 0x0098 +#define USBC_REG_o_HADDR0 0x009A +#define USBC_REG_o_HPORT0 0x009B +#define USBC_REG_o_TXFADDRx 0x0098 +#define USBC_REG_o_TXHADDRx 0x009A +#define USBC_REG_o_TXHPORTx 0x009B +#define USBC_REG_o_RXFADDRx 0x009C +#define USBC_REG_o_RXHADDRx 0x009E +#define USBC_REG_o_RXHPORTx 0x009F + + +#define USBC_REG_o_RPCOUNT 0x008A + +//new +#define USBC_REG_o_ISCR 0x0400 +#define USBC_REG_o_PHYCTL 0x0404 +#define USBC_REG_o_PHYBIST 0x0408 +#define USBC_REG_o_PHYTUNE 0x040c + +#define USBC_REG_o_CSR 0x0410 + +#define USBC_REG_o_PMU_IRQ 0x0800 + +//----------------------------------------------------------------------- +// registers +//----------------------------------------------------------------------- + +#define USBC_REG_FADDR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FADDR ) +#define USBC_REG_PCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PCTL ) +#define USBC_REG_INTTx(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTTx ) +#define USBC_REG_INTRx(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTRx ) +#define USBC_REG_INTTxE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTTxE ) +#define USBC_REG_INTRxE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTRxE ) +#define USBC_REG_INTUSB(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTUSB ) +#define USBC_REG_INTUSBE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTUSBE ) +#define USBC_REG_FRNUM(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FRNUM ) +#define USBC_REG_EPIND(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPIND ) +#define USBC_REG_TMCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TMCTL ) +#define USBC_REG_TXMAXP(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXMAXP ) + +#define USBC_REG_CSR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CSR0 ) +#define USBC_REG_TXCSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXCSR ) + +#define USBC_REG_RXMAXP(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXMAXP ) +#define USBC_REG_RXCSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXCSR ) + +#define USBC_REG_COUNT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_COUNT0 ) +#define USBC_REG_RXCOUNT(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXCOUNT ) + +#define USBC_REG_EP0TYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EP0TYPE ) +#define USBC_REG_TXTYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXTYPE ) + +#define USBC_REG_NAKLIMIT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_NAKLIMIT0 ) +#define USBC_REG_TXINTERVAL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXINTERVAL ) + +#define USBC_REG_RXTYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXTYPE ) +#define USBC_REG_RXINTERVAL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXINTERVAL ) +//#define USBC_REG_CONFIGDATA(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CONFIGDATA ) +#define USBC_REG_EPFIFO0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO0 ) +#define USBC_REG_EPFIFO1(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO1 ) +#define USBC_REG_EPFIFO2(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO2 ) +#define USBC_REG_EPFIFO3(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO3 ) +#define USBC_REG_EPFIFO4(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO4 ) +#define USBC_REG_EPFIFO5(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO5 ) +#define USBC_REG_EPFIFOx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_EPFIFOx(n) ) +#define USBC_REG_DEVCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_DEVCTL ) +#define USBC_REG_TXFIFOSZ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXFIFOSZ ) +#define USBC_REG_RXFIFOSZ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXFIFOSZ ) +#define USBC_REG_TXFIFOAD(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXFIFOAD ) +#define USBC_REG_RXFIFOAD(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXFIFOAD ) +#define USBC_REG_VEND0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VEND0 ) +#define USBC_REG_VEND1(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VEND1 ) +#define USBC_REG_EPINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPINFO ) +#define USBC_REG_RAMINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RAMINFO ) +#define USBC_REG_LINKINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_LINKINFO ) +#define USBC_REG_VPLEN(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VPLEN ) +#define USBC_REG_HSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HSEOF ) +#define USBC_REG_FSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FSEOF ) +#define USBC_REG_LSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_LSEOF ) + +#define USBC_REG_FADDR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FADDR0 ) +#define USBC_REG_HADDR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HADDR0 ) +#define USBC_REG_HPORT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HPORT0 ) + +#define USBC_REG_TXFADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXFADDRx ) +#define USBC_REG_TXHADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXHADDRx ) +#define USBC_REG_TXHPORTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXHPORTx ) +#define USBC_REG_RXFADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXFADDRx ) +#define USBC_REG_RXHADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXHADDRx ) +#define USBC_REG_RXHPORTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXHPORTx ) + +#define USBC_REG_RPCOUNTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RPCOUNT ) + +#define USBC_REG_ISCR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_ISCR ) +#define USBC_REG_PHYCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYCTL ) +#define USBC_REG_PHYBIST(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYBIST ) +#define USBC_REG_PHYTUNE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYTUNE ) +#define USBC_REG_PMU_IRQ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PMU_IRQ ) +#define USBC_REG_CSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CSR) +//----------------------------------------------------------------------- +// bit position +//----------------------------------------------------------------------- + +/* USB Power Control for Host only */ +#define USBC_BP_POWER_H_HIGH_SPEED_EN 5 +#define USBC_BP_POWER_H_HIGH_SPEED_FLAG 4 +#define USBC_BP_POWER_H_RESET 3 +#define USBC_BP_POWER_H_RESUME 2 +#define USBC_BP_POWER_H_SUSPEND 1 +#define USBC_BP_POWER_H_SUEPEND_EN 0 + +/* USB Power Control for device only */ +#define USBC_BP_POWER_D_ISO_UPDATE_EN 7 +#define USBC_BP_POWER_D_SOFT_CONNECT 6 +#define USBC_BP_POWER_D_HIGH_SPEED_EN 5 +#define USBC_BP_POWER_D_HIGH_SPEED_FLAG 4 +#define USBC_BP_POWER_D_RESET_FLAG 3 +#define USBC_BP_POWER_D_RESUME 2 +#define USBC_BP_POWER_D_SUSPEND 1 +#define USBC_BP_POWER_D_ENABLE_SUSPENDM 0 + +/* interrupt flags for ep0 and the Tx ep1~4 */ +#define USBC_BP_INTTx_FLAG_EP5 5 +#define USBC_BP_INTTx_FLAG_EP4 4 +#define USBC_BP_INTTx_FLAG_EP3 3 +#define USBC_BP_INTTx_FLAG_EP2 2 +#define USBC_BP_INTTx_FLAG_EP1 1 +#define USBC_BP_INTTx_FLAG_EP0 0 + +/* interrupt flags for Rx ep1~4 */ +#define USBC_BP_INTRx_FLAG_EP5 5 +#define USBC_BP_INTRx_FLAG_EP4 4 +#define USBC_BP_INTRx_FLAG_EP3 3 +#define USBC_BP_INTRx_FLAG_EP2 2 +#define USBC_BP_INTRx_FLAG_EP1 1 + +/* interrupt enable for Tx ep0~4 */ +#define USBC_BP_INTTxE_EN_EP5 5 +#define USBC_BP_INTTxE_EN_EP4 4 +#define USBC_BP_INTTxE_EN_EP3 3 +#define USBC_BP_INTTxE_EN_EP2 2 +#define USBC_BP_INTTxE_EN_EP1 1 +#define USBC_BP_INTTxE_EN_EP0 0 + +/* interrupt enable for Rx ep1~4 */ +#define USBC_BP_INTRxE_EN_EP5 5 +#define USBC_BP_INTRxE_EN_EP4 4 +#define USBC_BP_INTRxE_EN_EP3 3 +#define USBC_BP_INTRxE_EN_EP2 2 +#define USBC_BP_INTRxE_EN_EP1 1 + +/* USB interrupt */ +#define USBC_BP_INTUSB_VBUS_ERROR 7 +#define USBC_BP_INTUSB_SESSION_REQ 6 +#define USBC_BP_INTUSB_DISCONNECT 5 +#define USBC_BP_INTUSB_CONNECT 4 +#define USBC_BP_INTUSB_SOF 3 +#define USBC_BP_INTUSB_RESET 2 +#define USBC_BP_INTUSB_RESUME 1 +#define USBC_BP_INTUSB_SUSPEND 0 + +/* USB interrupt enable */ +#define USBC_BP_INTUSBE_EN_VBUS_ERROR 7 +#define USBC_BP_INTUSBE_EN_SESSION_REQ 6 +#define USBC_BP_INTUSBE_EN_DISCONNECT 5 +#define USBC_BP_INTUSBE_EN_CONNECT 4 +#define USBC_BP_INTUSBE_EN_SOF 3 +#define USBC_BP_INTUSBE_EN_RESET 2 +#define USBC_BP_INTUSBE_EN_RESUME 1 +#define USBC_BP_INTUSBE_EN_SUSPEND 0 + +/* Test Mode Control */ +#define USBC_BP_TMCTL_FORCE_HOST 7 +#define USBC_BP_TMCTL_FIFO_ACCESS 6 +#define USBC_BP_TMCTL_FORCE_FS 5 +#define USBC_BP_TMCTL_FORCE_HS 4 +#define USBC_BP_TMCTL_TEST_PACKET 3 +#define USBC_BP_TMCTL_TEST_K 2 +#define USBC_BP_TMCTL_TEST_J 1 +#define USBC_BP_TMCTL_TEST_SE0_NAK 0 + +/* Tx Max packet */ +#define USBC_BP_TXMAXP_PACKET_COUNT 11 +#define USBC_BP_TXMAXP_MAXIMUM_PAYLOAD 0 + +/* Control and Status Register for ep0 for Host only */ +#define USBC_BP_CSR0_H_DisPing 11 +#define USBC_BP_CSR0_H_FlushFIFO 8 +#define USBC_BP_CSR0_H_NAK_Timeout 7 +#define USBC_BP_CSR0_H_StatusPkt 6 +#define USBC_BP_CSR0_H_ReqPkt 5 +#define USBC_BP_CSR0_H_Error 4 +#define USBC_BP_CSR0_H_SetupPkt 3 +#define USBC_BP_CSR0_H_RxStall 2 +#define USBC_BP_CSR0_H_TxPkRdy 1 +#define USBC_BP_CSR0_H_RxPkRdy 0 + +/* Control and Status Register for ep0 for device only */ +#define USBC_BP_CSR0_D_FLUSH_FIFO 8 +#define USBC_BP_CSR0_D_SERVICED_SETUP_END 7 +#define USBC_BP_CSR0_D_SERVICED_RX_PKT_READY 6 +#define USBC_BP_CSR0_D_SEND_STALL 5 +#define USBC_BP_CSR0_D_SETUP_END 4 +#define USBC_BP_CSR0_D_DATA_END 3 +#define USBC_BP_CSR0_D_SENT_STALL 2 +#define USBC_BP_CSR0_D_TX_PKT_READY 1 +#define USBC_BP_CSR0_D_RX_PKT_READY 0 + +/* Tx ep Control and Status Register for Host only */ +#define USBC_BP_TXCSR_H_AUTOSET 15 +#define USBC_BP_TXCSR_H_RESERVED 14 +#define USBC_BP_TXCSR_H_MODE 13 +#define USBC_BP_TXCSR_H_DMA_REQ_EN 12 +#define USBC_BP_TXCSR_H_FORCE_DATA_TOGGLE 11 +#define USBC_BP_TXCSR_H_DMA_REQ_MODE 10 +#define USBC_BP_TXCSR_H_NAK_TIMEOUT 7 +#define USBC_BP_TXCSR_H_CLEAR_DATA_TOGGLE 6 +#define USBC_BP_TXCSR_H_TX_STALL 5 +#define USBC_BP_TXCSR_H_FLUSH_FIFO 3 +#define USBC_BP_TXCSR_H_ERROR 2 +#define USBC_BP_TXCSR_H_FIFO_NOT_EMPTY 1 +#define USBC_BP_TXCSR_H_TX_READY 0 + +/* Tx ep Control and Status Register for Device only */ +#define USBC_BP_TXCSR_D_AUTOSET 15 +#define USBC_BP_TXCSR_D_ISO 14 +#define USBC_BP_TXCSR_D_MODE 13 +#define USBC_BP_TXCSR_D_DMA_REQ_EN 12 +#define USBC_BP_TXCSR_D_FORCE_DATA_TOGGLE 11 +#define USBC_BP_TXCSR_D_DMA_REQ_MODE 10 +#define USBC_BP_TXCSR_D_INCOMPLETE 7 +#define USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE 6 +#define USBC_BP_TXCSR_D_SENT_STALL 5 +#define USBC_BP_TXCSR_D_SEND_STALL 4 +#define USBC_BP_TXCSR_D_FLUSH_FIFO 3 +#define USBC_BP_TXCSR_D_UNDER_RUN 2 +#define USBC_BP_TXCSR_D_FIFO_NOT_EMPTY 1 +#define USBC_BP_TXCSR_D_TX_READY 0 + +/* Rx Max Packet */ +#define USBC_BP_RXMAXP_PACKET_COUNT 11 +#define USBC_BP_RXMAXP_MAXIMUM_PAYLOAD 0 + +/* Rx ep Control and Status Register for Host only */ +#define USBC_BP_RXCSR_H_AUTO_CLEAR 15 +#define USBC_BP_RXCSR_H_AUTO_REQ 14 +#define USBC_BP_RXCSR_H_DMA_REQ_EN 13 +#define USBC_BP_RXCSR_H_PID_ERROR 12 +#define USBC_BP_RXCSR_H_DMA_REQ_MODE 11 + +#define USBC_BP_RXCSR_H_INCOMPLETE 8 +#define USBC_BP_RXCSR_H_CLEAR_DATA_TOGGLE 7 +#define USBC_BP_RXCSR_H_RX_STALL 6 +#define USBC_BP_RXCSR_H_REQ_PACKET 5 +#define USBC_BP_RXCSR_H_FLUSH_FIFO 4 +#define USBC_BP_RXCSR_H_NAK_TIMEOUT 3 +#define USBC_BP_RXCSR_H_ERROR 2 +#define USBC_BP_RXCSR_H_FIFO_FULL 1 +#define USBC_BP_RXCSR_H_RX_PKT_READY 0 + +/* Rx ep Control and Status Register for Device only */ +#define USBC_BP_RXCSR_D_AUTO_CLEAR 15 +#define USBC_BP_RXCSR_D_ISO 14 +#define USBC_BP_RXCSR_D_DMA_REQ_EN 13 +#define USBC_BP_RXCSR_D_DISABLE_NYET 12 +#define USBC_BP_RXCSR_D_DMA_REQ_MODE 11 + +#define USBC_BP_RXCSR_D_INCOMPLETE 8 +#define USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE 7 +#define USBC_BP_RXCSR_D_SENT_STALL 6 +#define USBC_BP_RXCSR_D_SEND_STALL 5 +#define USBC_BP_RXCSR_D_FLUSH_FIFO 4 +#define USBC_BP_RXCSR_D_DATA_ERROR 3 +#define USBC_BP_RXCSR_D_OVERRUN 2 +#define USBC_BP_RXCSR_D_FIFO_FULL 1 +#define USBC_BP_RXCSR_D_RX_PKT_READY 0 + +/* Tx Type Register for host only */ +#define USBC_BP_TXTYPE_SPEED 6 //new +#define USBC_BP_TXTYPE_PROROCOL 4 +#define USBC_BP_TXTYPE_TARGET_EP_NUM 0 + +/* Rx Type Register for host only */ +#define USBC_BP_RXTYPE_SPEED 6 //new +#define USBC_BP_RXTYPE_PROROCOL 4 +#define USBC_BP_RXTYPE_TARGET_EP_NUM 0 + +/* Core Configueation */ +#define USBC_BP_CONFIGDATA_MPRXE 7 +#define USBC_BP_CONFIGDATA_MPTXE 6 +#define USBC_BP_CONFIGDATA_BIGENDIAN 5 +#define USBC_BP_CONFIGDATA_HBRXE 4 +#define USBC_BP_CONFIGDATA_HBTXE 3 +#define USBC_BP_CONFIGDATA_DYNFIFO_SIZING 2 +#define USBC_BP_CONFIGDATA_SOFTCONE 1 +#define USBC_BP_CONFIGDATA_UTMI_DATAWIDTH 0 + +/* OTG Device Control */ +#define USBC_BP_DEVCTL_B_DEVICE 7 +#define USBC_BP_DEVCTL_FS_DEV 6 +#define USBC_BP_DEVCTL_LS_DEV 5 + +#define USBC_BP_DEVCTL_VBUS 3 +#define USBC_BP_DEVCTL_HOST_MODE 2 +#define USBC_BP_DEVCTL_HOST_REQ 1 +#define USBC_BP_DEVCTL_SESSION 0 + +/* Tx EP FIFO size control */ +#define USBC_BP_TXFIFOSZ_DPB 4 +#define USBC_BP_TXFIFOSZ_SZ 0 + +/* Rx EP FIFO size control */ +#define USBC_BP_RXFIFOSZ_DPB 4 +#define USBC_BP_RXFIFOSZ_SZ 0 + +/* vendor0 */ +#define USBC_BP_VEND0_DRQ_SEL 1 +#define USBC_BP_VEND0_BUS_SEL 0 + +/* hub address */ +#define USBC_BP_HADDR_MULTI_TT 7 + +/* Interface Status and Control */ +#define USBC_BP_ISCR_VBUS_VALID_FROM_DATA 30 +#define USBC_BP_ISCR_VBUS_VALID_FROM_VBUS 29 +#define USBC_BP_ISCR_EXT_ID_STATUS 28 +#define USBC_BP_ISCR_EXT_DM_STATUS 27 +#define USBC_BP_ISCR_EXT_DP_STATUS 26 +#define USBC_BP_ISCR_MERGED_VBUS_STATUS 25 +#define USBC_BP_ISCR_MERGED_ID_STATUS 24 + +#define USBC_BP_ISCR_ID_PULLUP_EN 17 +#define USBC_BP_ISCR_DPDM_PULLUP_EN 16 +#define USBC_BP_ISCR_FORCE_ID 14 +#define USBC_BP_ISCR_FORCE_VBUS_VALID 12 +#define USBC_BP_ISCR_VBUS_VALID_SRC 10 + +#define USBC_BP_ISCR_HOSC_EN 7 +#define USBC_BP_ISCR_VBUS_CHANGE_DETECT 6 +#define USBC_BP_ISCR_ID_CHANGE_DETECT 5 +#define USBC_BP_ISCR_DPDM_CHANGE_DETECT 4 +#define USBC_BP_ISCR_IRQ_ENABLE 3 +#define USBC_BP_ISCR_VBUS_CHANGE_DETECT_EN 2 +#define USBC_BP_ISCR_ID_CHANGE_DETECT_EN 1 +#define USBC_BP_ISCR_DPDM_CHANGE_DETECT_EN 0 + + +#define SUNXI_EHCI_AHB_ICHR8_EN (1 << 10) +#define SUNXI_EHCI_AHB_INCR4_BURST_EN (1 << 9) +#define SUNXI_EHCI_AHB_INCRX_ALIGN_EN (1 << 8) +#define SUNXI_EHCI_ULPI_BYPASS_EN (1 << 0) +//----------------------------------------------------------------------- +// �Զ��� +//----------------------------------------------------------------------- + +/* usb��Դ���� */ +#define USBC_MAX_CTL_NUM 1 +#define USBC_MAX_EP_NUM 3 //ep0~2, ep�ĸ��� +#define USBC_MAX_FIFO_SIZE (2 * 1024) + +/* usb OTG mode */ +#define USBC_OTG_HOST 0 +#define USBC_OTG_DEVICE 1 + +/* usb device type */ +#define USBC_DEVICE_HSDEV 0 +#define USBC_DEVICE_FSDEV 1 +#define USBC_DEVICE_LSDEV 2 + +/* usb transfer type */ +#define USBC_TS_TYPE_IDLE 0 +#define USBC_TS_TYPE_CTRL 1 +#define USBC_TS_TYPE_ISO 2 +#define USBC_TS_TYPE_INT 3 +#define USBC_TS_TYPE_BULK 4 + +/* usb transfer mode */ +#define USBC_TS_MODE_UNKOWN 0 +#define USBC_TS_MODE_LS 1 +#define USBC_TS_MODE_FS 2 +#define USBC_TS_MODE_HS 3 + +/* usb Vbus status */ +#define USBC_VBUS_STATUS_BELOW_SESSIONEND 0 +#define USBC_VBUS_STATUS_ABOVE_SESSIONEND_BELOW_AVALID 1 +#define USBC_VBUS_STATUS_ABOVE_AVALID_BELOW_VBUSVALID 2 +#define USBC_VBUS_STATUS_ABOVE_VBUSVALID 3 + +/* usb io type */ +#define USBC_IO_TYPE_PIO 0 +#define USBC_IO_TYPE_DMA 1 + +/* usb ep type */ +#define USBC_EP_TYPE_IDLE 0 +#define USBC_EP_TYPE_EP0 1 +#define USBC_EP_TYPE_TX 2 +#define USBC_EP_TYPE_RX 3 + +/* usb id type */ +#define USBC_ID_TYPE_DISABLE 0 +#define USBC_ID_TYPE_HOST 1 +#define USBC_ID_TYPE_DEVICE 2 + +/* usb vbus valid type */ +#define USBC_VBUS_TYPE_DISABLE 0 +#define USBC_VBUS_TYPE_LOW 1 +#define USBC_VBUS_TYPE_HIGH 2 + +/* usb a valid source */ +#define USBC_A_VALID_SOURCE_UTMI_AVALID 0 +#define USBC_A_VALID_SOURCE_UTMI_VBUS 1 + +/* usb device switch */ +#define USBC_DEVICE_SWITCH_OFF 0 +#define USBC_DEVICE_SWITCH_ON 1 + +/* usb fifo config mode */ +#define USBC_FIFO_MODE_4K 0 +#define USBC_FIFO_MODE_8K 1 + +/* + ************************************************** + * usb interrupt mask + * + ************************************************** + */ + +/* interrupt flags for ep0 and the Tx ep1~4 */ +#define USBC_INTTx_FLAG_EP5 (1 << USBC_BP_INTTx_FLAG_EP5) +#define USBC_INTTx_FLAG_EP4 (1 << USBC_BP_INTTx_FLAG_EP4) +#define USBC_INTTx_FLAG_EP3 (1 << USBC_BP_INTTx_FLAG_EP3) +#define USBC_INTTx_FLAG_EP2 (1 << USBC_BP_INTTx_FLAG_EP2) +#define USBC_INTTx_FLAG_EP1 (1 << USBC_BP_INTTx_FLAG_EP1) +#define USBC_INTTx_FLAG_EP0 (1 << USBC_BP_INTTx_FLAG_EP0) + +/* interrupt flags for Rx ep1~4 */ +#define USBC_INTRx_FLAG_EP5 (1 << USBC_BP_INTRx_FLAG_EP5) +#define USBC_INTRx_FLAG_EP4 (1 << USBC_BP_INTRx_FLAG_EP4) +#define USBC_INTRx_FLAG_EP3 (1 << USBC_BP_INTRx_FLAG_EP3) +#define USBC_INTRx_FLAG_EP2 (1 << USBC_BP_INTRx_FLAG_EP2) +#define USBC_INTRx_FLAG_EP1 (1 << USBC_BP_INTRx_FLAG_EP1) + +/* USB interrupt */ +#define USBC_INTUSB_VBUS_ERROR (1 << USBC_BP_INTUSB_VBUS_ERROR) +#define USBC_INTUSB_SESSION_REQ (1 << USBC_BP_INTUSB_SESSION_REQ) +#define USBC_INTUSB_DISCONNECT (1 << USBC_BP_INTUSB_DISCONNECT) +#define USBC_INTUSB_CONNECT (1 << USBC_BP_INTUSB_CONNECT) +#define USBC_INTUSB_SOF (1 << USBC_BP_INTUSB_SOF) +#define USBC_INTUSB_RESET (1 << USBC_BP_INTUSB_RESET) +#define USBC_INTUSB_RESUME (1 << USBC_BP_INTUSB_RESUME) +#define USBC_INTUSB_SUSPEND (1 << USBC_BP_INTUSB_SUSPEND) + +#define USB_CSRL0_NAKTO 0x00000080 // NAK Timeout +#define USB_CSRL0_SETENDC 0x00000080 // Setup End Clear +#define USB_CSRL0_STATUS 0x00000040 // STATUS Packet +#define USB_CSRL0_RXRDYC 0x00000040 // RXRDY Clear +#define USB_CSRL0_REQPKT 0x00000020 // Request Packet +#define USB_CSRL0_STALL 0x00000020 // Send Stall +#define USB_CSRL0_SETEND 0x00000010 // Setup End +#define USB_CSRL0_ERROR 0x00000010 // Error +#define USB_CSRL0_DATAEND 0x00000008 // Data End +#define USB_CSRL0_SETUP 0x00000008 // Setup Packet +#define USB_CSRL0_STALLED 0x00000004 // Endpoint Stalled +#define USB_CSRL0_TXRDY 0x00000002 // Transmit Packet Ready +#define USB_CSRL0_RXRDY 0x00000001 // Receive Packet Ready + +#define USB_RXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support +#define USB_RXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size + +#define USB_TXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support +#define USB_TXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c new file mode 100644 index 0000000..c71f38d --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -0,0 +1,1307 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 William D. Jones + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2020 Jan Duempelmann + * Copyright (c) 2020 Reinhard Panhuber + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2) + +#include "device/dcd.h" +#include "dwc2_type.h" + +#if defined(TUP_USBIP_DWC2_STM32) + #include "dwc2_stm32.h" +#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + #include "dwc2_esp32.h" +#elif TU_CHECK_MCU(OPT_MCU_GD32VF103) + #include "dwc2_gd32.h" +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) + #include "dwc2_bcm.h" +#elif TU_CHECK_MCU(OPT_MCU_EFM32GG) + #include "dwc2_efm32.h" +#elif TU_CHECK_MCU(OPT_MCU_XMC4000) + #include "dwc2_xmc.h" +#else + #error "Unsupported MCUs" +#endif + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +// DWC2 registers +#define DWC2_REG(_port) ((dwc2_regs_t*) DWC2_REG_BASE) + +// Debug level for DWC2 +#define DWC2_DEBUG 2 + +#ifndef dcache_clean +#define dcache_clean(_addr, _size) +#endif + +#ifndef dcache_invalidate +#define dcache_invalidate(_addr, _size) +#endif + +#ifndef dcache_clean_invalidate +#define dcache_clean_invalidate(_addr, _size) +#endif + + +static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; + +typedef struct { + uint8_t * buffer; + tu_fifo_t * ff; + uint16_t total_len; + uint16_t max_size; + uint8_t interval; +} xfer_ctl_t; + +static xfer_ctl_t xfer_status[DWC2_EP_MAX][2]; +#define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir]) + +// EP0 transfers are limited to 1 packet - larger sizes has to be split +static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type + +// TX FIFO RAM allocation so far in words - RX FIFO size is readily available from dwc2->grxfsiz +static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) +static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) + +// Calculate the RX FIFO size according to recommendations from reference manual +static inline uint16_t calc_rx_ff_size(uint16_t ep_size) +{ + return 15 + 2*(ep_size/4) + 2*DWC2_EP_MAX; +} + +static void update_grxfsiz(uint8_t rhport) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + // Determine largest EP size for RX FIFO + uint16_t max_epsize = 0; + for (uint8_t epnum = 0; epnum < DWC2_EP_MAX; epnum++) + { + max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size); + } + + // Update size of RX FIFO + dwc2->grxfsiz = calc_rx_ff_size(max_epsize); +} + +// Setup the control endpoint 0. +static void bus_reset(uint8_t rhport) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + tu_memclr(xfer_status, sizeof(xfer_status)); + _out_ep_closed = false; + + // clear device address + dwc2->dcfg &= ~DCFG_DAD_Msk; + + // 1. NAK for all OUT endpoints + for ( uint8_t n = 0; n < DWC2_EP_MAX; n++ ) + { + dwc2->epout[n].doepctl |= DOEPCTL_SNAK; + } + + // 2. Set up interrupt mask + dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); + dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; + dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; + + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start. + // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located + // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard + // configuration done below. + // + // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed. + // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a + // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually + // opened when the host sends an additional command: setInterface. At this point in time + // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size + // an additional memory + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO 0 | + // --------------- (320 or 1024) - 16 + // | IN FIFO 1 | + // --------------- (320 or 1024) - 16 - x + // | . . . . | + // --------------- (320 or 1024) - 16 - x - y - ... - z + // | IN FIFO MAX | + // --------------- + // | FREE | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): + // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN + // + // - All EP OUT shared a unique OUT FIFO which uses + // - 13 for setup packets + control words (up to 3 setup packets). + // - 1 for global NAK (not required/used here). + // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" + // - 2 for each used OUT endpoint + // + // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum + // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x DWC2_EP_MAX = 47 + 2 x DWC2_EP_MAX + // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x DWC2_EP_MAX = 271 + 2 x DWC2_EP_MAX + // + // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge + // of the overall picture yet. We will use the worst scenario: largest possible + DWC2_EP_MAX + // + // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO + // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to + // overwrite this. + + dwc2->grxfsiz = calc_rx_ff_size(TUD_OPT_HIGH_SPEED ? 512 : 64); + + _allocated_fifo_words_tx = 16; + + // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) + dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); + + // Fixed control EP0 size to 64 bytes + dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); + xfer_status[0][TUSB_DIR_OUT].max_size = 64; + xfer_status[0][TUSB_DIR_IN ].max_size = 64; + + dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); + + dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; +} + +static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + // EP0 is limited to one packet each xfer + // We use multiple transaction of xfer->max_size length to get a whole transfer done + if ( epnum == 0 ) + { + xfer_ctl_t *const xfer = XFER_CTL_BASE(epnum, dir); + total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); + ep0_pending[dir] -= total_bytes; + } + + // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. + if ( dir == TUSB_DIR_IN ) + { + dwc2_epin_t* epin = dwc2->epin; + + // A full IN transfer (multiple packets, possibly) triggers XFRC. + epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | + ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); + + epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + + // For ISO endpoint set correct odd/even bit for next frame. + if ( (epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1 ) + { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); + epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + } + // Enable fifo empty interrupt only if there are something to put in the fifo. + if ( total_bytes != 0 ) + { + dwc2->diepempmsk |= (1 << epnum); + } + } + else + { + dwc2_epout_t* epout = dwc2->epout; + + // A full OUT transfer (multiple packets, possibly) triggers XFRC. + epout[epnum].doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ); + epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | + ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); + + epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; + if ( (epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && + XFER_CTL_BASE(epnum, dir)->interval == 1 ) + { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); + epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); + } + } +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +#if CFG_TUSB_DEBUG >= DWC2_DEBUG +void print_dwc2_info(dwc2_regs_t * dwc2) +{ + dwc2_ghwcfg2_t const * hw_cfg2 = &dwc2->ghwcfg2_bm; + dwc2_ghwcfg3_t const * hw_cfg3 = &dwc2->ghwcfg3_bm; + dwc2_ghwcfg4_t const * hw_cfg4 = &dwc2->ghwcfg4_bm; + +// TU_LOG_HEX(DWC2_DEBUG, dwc2->gotgctl); +// TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg); +// TU_LOG_HEX(DWC2_DEBUG, dwc2->dcfg); + TU_LOG_HEX(DWC2_DEBUG, dwc2->guid); + TU_LOG_HEX(DWC2_DEBUG, dwc2->gsnpsid); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg1); + + // HW configure 2 + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg2); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->op_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->arch ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->point2point ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->hs_phy_type ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->fs_phy_type ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->num_dev_ep ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->num_host_ch ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->period_channel_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->enable_dynamic_fifo ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->mul_cpu_int ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->nperiod_tx_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->host_period_tx_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->dev_token_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->otg_enable_ic_usb ); + + // HW configure 3 + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg3); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->xfer_size_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->packet_size_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->i2c_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->vendor_ctrl_itf ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->optional_feature_removed ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->synch_reset ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_adp_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_enable_hsic ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->battery_charger_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->lpm_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->total_fifo_size ); + + // HW configure 4 + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg4); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->num_dev_period_in_ep ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->power_optimized ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->ahb_freq_min ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->hibernation ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->service_interval_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->ipg_isoc_en ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->acg_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->utmi_phy_data_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dev_ctrl_ep_num ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->iddg_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->vbus_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->a_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->b_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dedicated_fifos ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->num_dev_in_eps ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dma_desc_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dma_dynamic ); +} +#endif + +static void reset_core(dwc2_regs_t * dwc2) +{ + // reset core + dwc2->grstctl |= GRSTCTL_CSRST; + + // wait for reset bit is cleared + // TODO version 4.20a should wait for RESET DONE mask + while (dwc2->grstctl & GRSTCTL_CSRST) { } + + // wait for AHB master IDLE + while ( !(dwc2->grstctl & GRSTCTL_AHBIDL) ) { } + + // wait for device mode ? +} + +static bool phy_hs_supported(dwc2_regs_t * dwc2) +{ + // note: esp32 incorrect report its hs_phy_type as utmi + return TUD_OPT_HIGH_SPEED && dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; +} + +static void phy_fs_init(dwc2_regs_t * dwc2) +{ + TU_LOG(DWC2_DEBUG, "Fullspeed PHY init\r\n"); + + // Select FS PHY + dwc2->gusbcfg |= GUSBCFG_PHYSEL; + + // MCU specific PHY init before reset + dwc2_phy_init(dwc2, HS_PHY_TYPE_NONE); + + // Reset core after selecting PHY + reset_core(dwc2); + + // USB turnaround time is critical for certification where long cables and 5-Hubs are used. + // So if you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, + // these bits can be programmed to a larger value. Default is 5 + dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); + + // MCU specific PHY update post reset + dwc2_phy_update(dwc2, HS_PHY_TYPE_NONE); + + // set max speed + dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); +} + +static void phy_hs_init(dwc2_regs_t * dwc2) +{ + uint32_t gusbcfg = dwc2->gusbcfg; + + // De-select FS PHY + gusbcfg &= ~GUSBCFG_PHYSEL; + + if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) + { + TU_LOG(DWC2_DEBUG, "Highspeed ULPI PHY init\r\n"); + + // Select ULPI + gusbcfg |= GUSBCFG_ULPI_UTMI_SEL; + + // ULPI 8-bit interface, single data rate + gusbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL); + + // default internal VBUS Indicator and Drive + gusbcfg &= ~(GUSBCFG_ULPIEVBUSD | GUSBCFG_ULPIEVBUSI); + + // Disable FS/LS ULPI + gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM); + }else + { + TU_LOG(DWC2_DEBUG, "Highspeed UTMI+ PHY init\r\n"); + + // Select UTMI+ with 8-bit interface + gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); + + // Set 16-bit interface if supported + if (dwc2->ghwcfg4_bm.utmi_phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; + } + + // Apply config + dwc2->gusbcfg = gusbcfg; + + // mcu specific phy init + dwc2_phy_init(dwc2, dwc2->ghwcfg2_bm.hs_phy_type); + + // Reset core after selecting PHY + reset_core(dwc2); + + // Set turn-around, must after core reset otherwise it will be clear + // - 9 if using 8-bit PHY interface + // - 5 if using 16-bit PHY interface + gusbcfg &= ~GUSBCFG_TRDT_Msk; + gusbcfg |= (dwc2->ghwcfg4_bm.utmi_phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; + dwc2->gusbcfg = gusbcfg; + + // MCU specific PHY update post reset + dwc2_phy_update(dwc2, dwc2->ghwcfg2_bm.hs_phy_type); + + // Set max speed + uint32_t dcfg = dwc2->dcfg; + dcfg &= ~DCFG_DSPD_Msk; + dcfg |= DCFG_DSPD_HS << DCFG_DSPD_Pos; + + // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required + // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) + if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) dcfg |= DCFG_XCVRDLY; + + dwc2->dcfg = dcfg; +} + +static bool check_dwc2(dwc2_regs_t * dwc2) +{ +#if CFG_TUSB_DEBUG >= DWC2_DEBUG + print_dwc2_info(dwc2); +#endif + + // For some reasons: GD32VF103 snpsid and all hwcfg register are always zero (skip it) +#if !TU_CHECK_MCU(OPT_MCU_GD32VF103) + uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; + TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID); +#endif + + return true; +} + +void dcd_init (uint8_t rhport) +{ + // Programming model begins in the last section of the chapter on the USB + // peripheral in each Reference Manual. + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + // Check Synopsys ID register, failed if controller clock/power is not enabled + TU_VERIFY(check_dwc2(dwc2), ); + + dcd_disconnect(rhport); + + // max number of endpoints & total_fifo_size are: + // hw_cfg2->num_dev_ep, hw_cfg2->total_fifo_size + + if( phy_hs_supported(dwc2) ) + { + // Highspeed + phy_hs_init(dwc2); + }else + { + // core does not support highspeed or hs-phy is not present + phy_fs_init(dwc2); + } + + // Restart PHY clock + dwc2->pcgctl &= ~(PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE); + + /* Set HS/FS Timeout Calibration to 7 (max available value). + * The number of PHY clocks that the application programs in + * this field is added to the high/full speed interpacket timeout + * duration in the core to account for any additional delays + * introduced by the PHY. This can be required, because the delay + * introduced by the PHY in generating the linestate condition + * can vary from one PHY to another. + */ + dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); + + // Force device mode + dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; + + // Clear A override, force B Valid + dwc2->gotgctl = (dwc2->gotgctl & ~GOTGCTL_AVALOEN) | GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL; + + // If USB host misbehaves during status portion of control xfer + // (non zero-length packet), send STALL back and discard. + dwc2->dcfg |= DCFG_NZLSOHSK; + + // Clear all interrupts + dwc2->gintsts |= dwc2->gintsts; + dwc2->gotgint |= dwc2->gotgint; + + // Required as part of core initialization. + // TODO: How should mode mismatch be handled? It will cause + // the core to stop working/require reset. + dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_MMISM | GINTMSK_RXFLVLM | + GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; + + // Enable global interrupt + dwc2->gahbcfg |= GAHBCFG_GINT; + + // make sure we are in device mode +// TU_ASSERT(!(dwc2->gintsts & GINTSTS_CMOD), ); + +// TU_LOG_HEX(DWC2_DEBUG, dwc2->gotgctl); +// TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg); +// TU_LOG_HEX(DWC2_DEBUG, dwc2->dcfg); +// TU_LOG_HEX(DWC2_DEBUG, dwc2->gahbcfg); + + dcd_connect(rhport); +} + +void dcd_int_enable (uint8_t rhport) +{ + dwc2_dcd_int_enable(rhport); +} + +void dcd_int_disable (uint8_t rhport) +{ + dwc2_dcd_int_disable(rhport); +} + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2->dcfg = (dwc2->dcfg & ~DCFG_DAD_Msk) | (dev_addr << DCFG_DAD_Pos); + + // Response with status after changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + // set remote wakeup + dwc2->dctl |= DCTL_RWUSIG; + + // enable SOF to detect bus resume + dwc2->gintsts = GINTSTS_SOF; + dwc2->gintmsk |= GINTMSK_SOFM; + + // Per specs: remote wakeup signal bit must be clear within 1-15ms + dwc2_remote_wakeup_delay(); + + dwc2->dctl &= ~DCTL_RWUSIG; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2->dctl &= ~DCTL_SDIS; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2->dctl |= DCTL_SDIS; +} + + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + TU_ASSERT(epnum < DWC2_EP_MAX); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); + xfer->interval = desc_edpt->bInterval; + + uint16_t const fifo_size = tu_div_ceil(xfer->max_size, 4); + + if(dir == TUSB_DIR_OUT) + { + // Calculate required size of RX FIFO + uint16_t const sz = calc_rx_ff_size(4*fifo_size); + + // If size_rx needs to be extended check if possible and if so enlarge it + if (dwc2->grxfsiz < sz) + { + TU_ASSERT(sz + _allocated_fifo_words_tx <= DWC2_EP_FIFO_SIZE/4); + + // Enlarge RX FIFO + dwc2->grxfsiz = sz; + } + + dwc2->epout[epnum].doepctl |= (1 << DOEPCTL_USBAEP_Pos) | + (desc_edpt->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | + (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << DOEPCTL_MPSIZ_Pos); + + dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); + } + else + { + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO 0 | + // --------------- (320 or 1024) - 16 + // | IN FIFO 1 | + // --------------- (320 or 1024) - 16 - x + // | . . . . | + // --------------- (320 or 1024) - 16 - x - y - ... - z + // | IN FIFO MAX | + // --------------- + // | FREE | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // In FIFO is allocated by following rules: + // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". + + // Check if free space is available + TU_ASSERT(_allocated_fifo_words_tx + fifo_size + dwc2->grxfsiz <= DWC2_EP_FIFO_SIZE/4); + + _allocated_fifo_words_tx += fifo_size; + + TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %u", fifo_size*4, DWC2_EP_FIFO_SIZE-_allocated_fifo_words_tx*4); + + // DIEPTXF starts at FIFO #1. + // Both TXFD and TXSA are in unit of 32-bit words. + dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); + + dwc2->epin[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) | + (epnum << DIEPCTL_TXFNUM_Pos) | + (desc_edpt->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) | + (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << DIEPCTL_MPSIZ_Pos); + + dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); + } + + return true; +} + +// Close all non-control endpoints, cancel all pending transfers if any. +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + // Disable non-control interrupt + dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); + + for(uint8_t n = 1; n < DWC2_EP_MAX; n++) + { + // disable OUT endpoint + dwc2->epout[n].doepctl = 0; + xfer_status[n][TUSB_DIR_OUT].max_size = 0; + + // disable IN endpoint + dwc2->epin[n].diepctl = 0; + xfer_status[n][TUSB_DIR_IN].max_size = 0; + } + + // reset allocated fifo IN + _allocated_fifo_words_tx = 16; +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + xfer->ff = NULL; + xfer->total_len = total_bytes; + + // EP0 can only handle one packet + if(epnum == 0) + { + ep0_pending[dir] = total_bytes; + + // Schedule the first transaction for EP0 transfer + edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]); + } + else + { + uint16_t num_packets = (total_bytes / xfer->max_size); + uint16_t const short_packet_size = total_bytes % xfer->max_size; + + // Zero-size packet is special case. + if ( (short_packet_size > 0) || (total_bytes == 0) ) num_packets++; + + // Schedule packets to be sent within interrupt + edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); + } + + return true; +} + +// The number of bytes has to be given explicitly to allow more flexible control of how many +// bytes should be written and second to keep the return value free to give back a boolean +// success message. If total_bytes is too big, the FIFO will copy only what is available +// into the USB buffer! +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 + TU_ASSERT(ff->item_size == 1); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = NULL; + xfer->ff = ff; + xfer->total_len = total_bytes; + + uint16_t num_packets = (total_bytes / xfer->max_size); + uint16_t const short_packet_size = total_bytes % xfer->max_size; + + // Zero-size packet is special case. + if ( short_packet_size > 0 || (total_bytes == 0) ) num_packets++; + + // Schedule packets to be sent within interrupt + edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); + + return true; +} + +static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall) +{ + (void) rhport; + + dwc2_regs_t *dwc2 = DWC2_REG(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if ( dir == TUSB_DIR_IN ) + { + dwc2_epin_t* epin = dwc2->epin; + + // Only disable currently enabled non-control endpoint + if ( (epnum == 0) || !(epin[epnum].diepctl & DIEPCTL_EPENA) ) + { + epin[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); + } + else + { + // Stop transmitting packets and NAK IN xfers. + epin[epnum].diepctl |= DIEPCTL_SNAK; + while ( (epin[epnum].diepint & DIEPINT_INEPNE) == 0 ) {} + + // Disable the endpoint. + epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); + while ( (epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0 ) {} + + epin[epnum].diepint = DIEPINT_EPDISD; + } + + // Flush the FIFO, and wait until we have confirmed it cleared. + dwc2->grstctl |= (epnum << GRSTCTL_TXFNUM_Pos); + dwc2->grstctl |= GRSTCTL_TXFFLSH; + while ( (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) != 0 ) {} + } + else + { + dwc2_epout_t* epout = dwc2->epout; + + // Only disable currently enabled non-control endpoint + if ( (epnum == 0) || !(epout[epnum].doepctl & DOEPCTL_EPENA) ) + { + epout[epnum].doepctl |= stall ? DOEPCTL_STALL : 0; + } + else + { + // Asserting GONAK is required to STALL an OUT endpoint. + // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt + // anyway, and it can't be cleared by user code. If this while loop never + // finishes, we have bigger problems than just the stack. + dwc2->dctl |= DCTL_SGONAK; + while ( (dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0 ) {} + + // Ditto here- disable the endpoint. + epout[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); + while ( (epout[epnum].doepint & DOEPINT_EPDISD_Msk) == 0 ) {} + + epout[epnum].doepint = DOEPINT_EPDISD; + + // Allow other OUT endpoints to keep receiving. + dwc2->dctl |= DCTL_CGONAK; + } + } +} + +/** + * Close an endpoint. + */ +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +{ + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_edpt_disable(rhport, ep_addr, false); + + // Update max_size + xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation + + if (dir == TUSB_DIR_IN) + { + uint16_t const fifo_size = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXFD_Msk) >> DIEPTXF_INEPTXFD_Pos; + uint16_t const fifo_start = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXSA_Msk) >> DIEPTXF_INEPTXSA_Pos; + // For now only the last opened endpoint can be closed without fuss. + TU_ASSERT(fifo_start == DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,); + _allocated_fifo_words_tx -= fifo_size; + } + else + { + _out_ep_closed = true; // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty + } +} + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + dcd_edpt_disable(rhport, ep_addr, true); +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // Clear stall and reset data toggle + if ( dir == TUSB_DIR_IN ) + { + dwc2->epin[epnum].diepctl &= ~DIEPCTL_STALL; + dwc2->epin[epnum].diepctl |= DIEPCTL_SD0PID_SEVNFRM; + } + else + { + dwc2->epout[epnum].doepctl &= ~DOEPCTL_STALL; + dwc2->epout[epnum].doepctl |= DOEPCTL_SD0PID_SEVNFRM; + } +} + +/*------------------------------------------------------------------*/ + +// Read a single data packet from receive FIFO +static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + volatile const uint32_t * rx_fifo = dwc2->fifo[0]; + + // Reading full available 32 bit words from fifo + uint16_t full_words = len >> 2; + while(full_words--) + { + tu_unaligned_write32(dst, *rx_fifo); + dst += 4; + } + + // Read the remaining 1-3 bytes from fifo + uint8_t const bytes_rem = len & 0x03; + if ( bytes_rem != 0 ) + { + uint32_t const tmp = *rx_fifo; + dst[0] = tu_u32_byte0(tmp); + if ( bytes_rem > 1 ) dst[1] = tu_u32_byte1(tmp); + if ( bytes_rem > 2 ) dst[2] = tu_u32_byte2(tmp); + } +} + +// Write a single data packet to EPIN FIFO +static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const * src, uint16_t len) +{ + (void) rhport; + + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + volatile uint32_t * tx_fifo = dwc2->fifo[fifo_num]; + + // Pushing full available 32 bit words to fifo + uint16_t full_words = len >> 2; + while(full_words--) + { + *tx_fifo = tu_unaligned_read32(src); + src += 4; + } + + // Write the remaining 1-3 bytes into fifo + uint8_t const bytes_rem = len & 0x03; + if ( bytes_rem ) + { + uint32_t tmp_word = src[0]; + if ( bytes_rem > 1 ) tmp_word |= (src[1] << 8); + if ( bytes_rem > 2 ) tmp_word |= (src[2] << 16); + + *tx_fifo = tmp_word; + } +} + +static void handle_rxflvl_irq(uint8_t rhport) +{ + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + volatile uint32_t const * rx_fifo = dwc2->fifo[0]; + + // Pop control word off FIFO + uint32_t const ctl_word = dwc2->grxstsp; + uint8_t const pktsts = (ctl_word & GRXSTSP_PKTSTS_Msk ) >> GRXSTSP_PKTSTS_Pos; + uint8_t const epnum = (ctl_word & GRXSTSP_EPNUM_Msk ) >> GRXSTSP_EPNUM_Pos; + uint16_t const bcnt = (ctl_word & GRXSTSP_BCNT_Msk ) >> GRXSTSP_BCNT_Pos; + + dwc2_epout_t* epout = &dwc2->epout[epnum]; + +//#if CFG_TUSB_DEBUG >= DWC2_DEBUG +// const char * pktsts_str[] = +// { +// "ASSERT", "Global NAK (ISR)", "Out Data Received", "Out Transfer Complete (ISR)", +// "Setup Complete (ISR)", "ASSERT", "Setup Data Received" +// }; +// TU_LOG_LOCATION(); +// TU_LOG(DWC2_DEBUG, " EP %02X, Byte Count %u, %s\r\n", epnum, bcnt, pktsts_str[pktsts]); +// TU_LOG(DWC2_DEBUG, " daint = %08lX, doepint = %04X\r\n", (unsigned long) dwc2->daint, (unsigned int) epout->doepint); +//#endif + + switch ( pktsts ) + { + // Global OUT NAK: do nothign + case GRXSTS_PKTSTS_GLOBALOUTNAK: break; + + case GRXSTS_PKTSTS_SETUPRX: + // Setup packet received + + // We can receive up to three setup packets in succession, but + // only the last one is valid. + _setup_packet[0] = (*rx_fifo); + _setup_packet[1] = (*rx_fifo); + break; + + case GRXSTS_PKTSTS_SETUPDONE: + // Setup packet done (Interrupt) + epout->doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); + break; + + case GRXSTS_PKTSTS_OUTRX: + { + // Out packet received + xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + + // Read packet off RxFIFO + if ( xfer->ff ) + { + // Ring buffer + tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, bcnt); + } + else + { + // Linear buffer + read_fifo_packet(rhport, xfer->buffer, bcnt); + + // Increment pointer to xfer data + xfer->buffer += bcnt; + } + + // Truncate transfer length in case of short packet + if ( bcnt < xfer->max_size ) + { + xfer->total_len -= (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; + if ( epnum == 0 ) + { + xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; + ep0_pending[TUSB_DIR_OUT] = 0; + } + } + } + break; + + // Out packet done (Interrupt) + case GRXSTS_PKTSTS_OUTDONE: + // Occurred on STM32L47 with dwc2 version 3.10a but not found on other version like 2.80a or 3.30a + // May (or not) be 3.10a specific feature/bug or depending on MCU configuration + // XFRC complete is additionally generated when + // - setup packet is received + // - complete the data stage of control write is complete + if ((epnum == 0) && (bcnt == 0) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) + { + uint32_t doepint = epout->doepint; + + if (doepint & (DOEPINT_STPKTRX | DOEPINT_OTEPSPR)) + { + // skip this "no-data" transfer complete event + // Note: STPKTRX will be clear later by setup received handler + uint32_t clear_flags = DOEPINT_XFRC; + + if (doepint & DOEPINT_OTEPSPR) clear_flags |= DOEPINT_OTEPSPR; + + epout->doepint = clear_flags; + + // TU_LOG(DWC2_DEBUG, " FIX extra transfer complete on setup/data compete\r\n"); + } + } + break; + + default: // Invalid + TU_BREAKPOINT(); + break; + } +} + +static void handle_epout_irq (uint8_t rhport) +{ + dwc2_regs_t *dwc2 = DWC2_REG(rhport); + + // DAINT for a given EP clears when DOEPINTx is cleared. + // OEPINT will be cleared when DAINT's out bits are cleared. + for ( uint8_t n = 0; n < DWC2_EP_MAX; n++ ) + { + if ( dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n) ) + { + dwc2_epout_t* epout = &dwc2->epout[n]; + + uint32_t const doepint = epout->doepint; + + // SETUP packet Setup Phase done. + if ( doepint & DOEPINT_STUP ) + { + uint32_t clear_flag = DOEPINT_STUP; + + // STPKTRX is only available for version from 3_00a + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) + { + clear_flag |= DOEPINT_STPKTRX; + } + + epout->doepint = clear_flag; + dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); + } + + // OUT XFER complete + if ( epout->doepint & DOEPINT_XFRC ) + { + epout->doepint = DOEPINT_XFRC; + + xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); + + // EP0 can only handle one packet + if ( (n == 0) && ep0_pending[TUSB_DIR_OUT] ) + { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } + else + { + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + } + } +} + +static void handle_epin_irq (uint8_t rhport) +{ + dwc2_regs_t *dwc2 = DWC2_REG(rhport); + dwc2_epin_t* epin = dwc2->epin; + + // DAINT for a given EP clears when DIEPINTx is cleared. + // IEPINT will be cleared when DAINT's out bits are cleared. + for ( uint8_t n = 0; n < DWC2_EP_MAX; n++ ) + { + if ( dwc2->daint & TU_BIT(DAINT_IEPINT_Pos + n) ) + { + // IN XFER complete (entire xfer). + xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_IN); + + if ( epin[n].diepint & DIEPINT_XFRC ) + { + epin[n].diepint = DIEPINT_XFRC; + + // EP0 can only handle one packet + if ( (n == 0) && ep0_pending[TUSB_DIR_IN] ) + { + // Schedule another packet to be transmitted. + edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); + } + else + { + dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + + // XFER FIFO empty + if ( (epin[n].diepint & DIEPINT_TXFE) && (dwc2->diepempmsk & (1 << n)) ) + { + // diepint's TXFE bit is read-only, software cannot clear it. + // It will only be cleared by hardware when written bytes is more than + // - 64 bytes or + // - Half of TX FIFO size (configured by DIEPTXF) + + uint16_t remaining_packets = (epin[n].dieptsiz & DIEPTSIZ_PKTCNT_Msk) >> DIEPTSIZ_PKTCNT_Pos; + + // Process every single packet (only whole packets can be written to fifo) + for ( uint16_t i = 0; i < remaining_packets; i++ ) + { + uint16_t const remaining_bytes = (epin[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos; + + // Packet can not be larger than ep max size + uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size); + + // It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current + // EP has to be checked if the buffer can take another WHOLE packet + if ( packet_size > ((epin[n].dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2) ) break; + + // Push packet to Tx-FIFO + if ( xfer->ff ) + { + volatile uint32_t *tx_fifo = dwc2->fifo[n]; + tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*) (uintptr_t) tx_fifo, packet_size); + } + else + { + write_fifo_packet(rhport, n, xfer->buffer, packet_size); + + // Increment pointer to xfer data + xfer->buffer += packet_size; + } + } + + // Turn off TXFE if all bytes are written. + if ( ((epin[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos) == 0 ) + { + dwc2->diepempmsk &= ~(1 << n); + } + } + } + } +} + +void dcd_int_handler(uint8_t rhport) +{ + dwc2_regs_t *dwc2 = DWC2_REG(rhport); + + uint32_t const int_status = dwc2->gintsts & dwc2->gintmsk; + + if(int_status & GINTSTS_USBRST) + { + // USBRST is start of reset. + dwc2->gintsts = GINTSTS_USBRST; + bus_reset(rhport); + } + + if(int_status & GINTSTS_ENUMDNE) + { + // ENUMDNE is the end of reset where speed of the link is detected + + dwc2->gintsts = GINTSTS_ENUMDNE; + + tusb_speed_t speed; + switch ((dwc2->dsts & DSTS_ENUMSPD_Msk) >> DSTS_ENUMSPD_Pos) + { + case DSTS_ENUMSPD_HS: + speed = TUSB_SPEED_HIGH; + break; + + case DSTS_ENUMSPD_LS: + speed = TUSB_SPEED_LOW; + break; + + case DSTS_ENUMSPD_FS_HSPHY: + case DSTS_ENUMSPD_FS: + default: + speed = TUSB_SPEED_FULL; + break; + } + + dcd_event_bus_reset(rhport, speed, true); + } + + if(int_status & GINTSTS_USBSUSP) + { + dwc2->gintsts = GINTSTS_USBSUSP; + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + if(int_status & GINTSTS_WKUINT) + { + dwc2->gintsts = GINTSTS_WKUINT; + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + + // TODO check GINTSTS_DISCINT for disconnect detection + // if(int_status & GINTSTS_DISCINT) + + if(int_status & GINTSTS_OTGINT) + { + // OTG INT bit is read-only + uint32_t const otg_int = dwc2->gotgint; + + if (otg_int & GOTGINT_SEDET) + { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + + dwc2->gotgint = otg_int; + } + + if(int_status & GINTSTS_SOF) + { + dwc2->gotgint = GINTSTS_SOF; + + // Disable SOF interrupt since currently only used for remote wakeup detection + dwc2->gintmsk &= ~GINTMSK_SOFM; + + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + + // RxFIFO non-empty interrupt handling. + if(int_status & GINTSTS_RXFLVL) + { + // RXFLVL bit is read-only + + // Mask out RXFLVL while reading data from FIFO + dwc2->gintmsk &= ~GINTMSK_RXFLVLM; + + // Loop until all available packets were handled + do + { + handle_rxflvl_irq(rhport); + } while(dwc2->gotgint & GINTSTS_RXFLVL); + + // Manage RX FIFO size + if (_out_ep_closed) + { + update_grxfsiz(rhport); + + // Disable flag + _out_ep_closed = false; + } + + dwc2->gintmsk |= GINTMSK_RXFLVLM; + } + + // OUT endpoint interrupt handling. + if(int_status & GINTSTS_OEPINT) + { + // OEPINT is read-only, clear using DOEPINTn + handle_epout_irq(rhport); + } + + // IN endpoint interrupt handling. + if(int_status & GINTSTS_IEPINT) + { + // IEPINT bit read-only, clear using DIEPINTn + handle_epin_irq(rhport); + } + + // // Check for Incomplete isochronous IN transfer + // if(int_status & GINTSTS_IISOIXFR) { + // printf(" IISOIXFR!\r\n"); + //// TU_LOG(DWC2_DEBUG, " IISOIXFR!\r\n"); + // } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_bcm.h b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_bcm.h new file mode 100644 index 0000000..14194e7 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -0,0 +1,88 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_DWC2_BCM_H_ +#define _TUSB_DWC2_BCM_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "broadcom/defines.h" +#include "broadcom/interrupts.h" +#include "broadcom/caches.h" + +#define DWC2_REG_BASE USB_OTG_GLOBAL_BASE +#define DWC2_EP_MAX 8 +#define DWC2_EP_FIFO_SIZE 4096 + +#define dcache_clean(_addr, _size) data_clean(_addr, _size) +#define dcache_invalidate(_addr, _size) data_invalidate(_addr, _size) +#define dcache_clean_invalidate(_addr, _size) data_clean_and_invalidate(_addr, _size) + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + BP_EnableIRQ(USB_IRQn); +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + BP_DisableIRQ(USB_IRQn); +} + +static inline void dwc2_remote_wakeup_delay(void) +{ + // try to delay for 1 ms + // TODO implement later +} + +// MCU specific PHY init, called BEFORE core reset +static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // nothing to do +} + +// MCU specific PHY update, it is called AFTER init() and core reset +static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // nothing to do +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_efm32.h b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_efm32.h new file mode 100644 index 0000000..ee4c3c7 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_efm32.h @@ -0,0 +1,87 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Rafael Silva (@perigoso) + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _DWC2_EFM32_H_ +#define _DWC2_EFM32_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "em_device.h" + +// EFM32 has custom control register before DWC registers +#define DWC2_REG_BASE (USB_BASE + offsetof(USB_TypeDef, GOTGCTL)) +#define DWC2_EP_MAX 7 +#define DWC2_EP_FIFO_SIZE 2048 + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB_IRQn); +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_IRQn); +} + +static inline void dwc2_remote_wakeup_delay(void) +{ + // try to delay for 1 ms +// uint32_t count = SystemCoreClock / 1000; +// while ( count-- ) __NOP(); +} + +// MCU specific PHY init, called BEFORE core reset +static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // Enable PHY + USB->ROUTE = USB_ROUTE_PHYPEN; +} + +// MCU specific PHY update, it is called AFTER init() and core reset +static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // EFM32 Manual: turn around must be 5 (reset & default value) + // dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_esp32.h b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_esp32.h new file mode 100644 index 0000000..78da277 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -0,0 +1,94 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef _DWC2_ESP32_H_ +#define _DWC2_ESP32_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "esp_intr_alloc.h" +#include "soc/periph_defs.h" +//#include "soc/usb_periph.h" + +#define DWC2_REG_BASE 0x60080000UL +#define DWC2_EP_MAX 5 // USB_OUT_EP_NUM +#define DWC2_EP_FIFO_SIZE 1024 + +// #define EP_FIFO_NUM 5 + +static intr_handle_t usb_ih; + +static void dcd_int_handler_wrap(void* arg) +{ + (void) arg; + dcd_int_handler(0); +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_enable (uint8_t rhport) +{ + (void) rhport; + esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih); +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + esp_intr_free(usb_ih); +} + +static inline void dwc2_remote_wakeup_delay(void) +{ + vTaskDelay(pdMS_TO_TICKS(1)); +} + +// MCU specific PHY init, called BEFORE core reset +static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // nothing to do +} + +// MCU specific PHY update, it is called AFTER init() and core reset +static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // nothing to do +} + +#ifdef __cplusplus +} +#endif + +#endif /* _DWC2_ESP32_H_ */ diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_gd32.h b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_gd32.h new file mode 100644 index 0000000..f8fa01e --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_gd32.h @@ -0,0 +1,100 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef DWC2_GD32_H_ +#define DWC2_GD32_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define DWC2_REG_BASE 0x50000000UL +#define DWC2_EP_MAX 4 +#define DWC2_EP_FIFO_SIZE 1280 +#define RHPORT_IRQn 86 + +extern uint32_t SystemCoreClock; + +// The GD32VF103 is a RISC-V MCU, which implements the ECLIC Core-Local +// Interrupt Controller by Nuclei. It is nearly API compatible to the +// NVIC used by ARM MCUs. +#define ECLIC_INTERRUPT_ENABLE_BASE 0xD2001001UL + +TU_ATTR_ALWAYS_INLINE +static inline void __eclic_enable_interrupt (uint32_t irq) { + *(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 1; +} + +TU_ATTR_ALWAYS_INLINE +static inline void __eclic_disable_interrupt (uint32_t irq){ + *(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 0; +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + __eclic_enable_interrupt(RHPORT_IRQn); +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + __eclic_disable_interrupt(RHPORT_IRQn); +} + +static inline void dwc2_remote_wakeup_delay(void) +{ + // try to delay for 1 ms + uint32_t count = SystemCoreClock / 1000; + while ( count-- ) __asm volatile ("nop"); +} + +// MCU specific PHY init, called BEFORE core reset +static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // nothing to do +} + +// MCU specific PHY update, it is called AFTER init() and core reset +static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // nothing to do +} + +#ifdef __cplusplus +} +#endif + +#endif /* DWC2_GD32_H_ */ diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_stm32.h b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_stm32.h new file mode 100644 index 0000000..469045a --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -0,0 +1,205 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _DWC2_STM32_H_ +#define _DWC2_STM32_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// EP_MAX : Max number of bi-directional endpoints including EP0 +// EP_FIFO_SIZE : Size of dedicated USB SRAM +#if CFG_TUSB_MCU == OPT_MCU_STM32F1 + #include "stm32f1xx.h" + #define EP_MAX_FS 4 + #define EP_FIFO_SIZE_FS 1280 + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F2 + #include "stm32f2xx.h" + #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS + #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F4 + #include "stm32f4xx.h" + #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS + #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE + #define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS + #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H7 + #include "stm32h7xx.h" + #define EP_MAX_FS 9 + #define EP_FIFO_SIZE_FS 4096 + #define EP_MAX_HS 9 + #define EP_FIFO_SIZE_HS 4096 + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F7 + #include "stm32f7xx.h" + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #define EP_MAX_HS 9 + #define EP_FIFO_SIZE_HS 4096 + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 + #include "stm32l4xx.h" + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + +#else + #error "Unsupported MCUs" +#endif + +// On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS +#if TUD_OPT_RHPORT == 0 + #define DWC2_REG_BASE USB_OTG_FS_PERIPH_BASE + #define DWC2_EP_MAX EP_MAX_FS + #define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_FS + #define RHPORT_IRQn OTG_FS_IRQn + +#else + #define DWC2_REG_BASE USB_OTG_HS_PERIPH_BASE + #define DWC2_EP_MAX EP_MAX_HS + #define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_HS + #define RHPORT_IRQn OTG_HS_IRQn + +#endif + +extern uint32_t SystemCoreClock; + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(RHPORT_IRQn); +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(RHPORT_IRQn); +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_remote_wakeup_delay(void) +{ + // try to delay for 1 ms + uint32_t count = SystemCoreClock / 1000; + while ( count-- ) __NOP(); +} + +// MCU specific PHY init, called BEFORE core reset +static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + if ( hs_phy_type == HS_PHY_TYPE_NONE ) + { + // Enable on-chip FS PHY + dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN; + }else + { + // Disable FS PHY + dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; + + // Enable on-chip HS PHY + if (hs_phy_type == HS_PHY_TYPE_UTMI || hs_phy_type == HS_PHY_TYPE_UTMI_ULPI) + { +#ifdef USB_HS_PHYC + // Enable UTMI HS PHY + dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN; + + // Enable LDO + USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; + + // Wait until LDO ready + while ( 0 == (USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {} + + uint32_t phyc_pll = 0; + + // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS + switch ( HSE_VALUE ) + { + case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break; + case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break; + case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break; + case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break; + case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break; + case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header + default: + TU_ASSERT(false, ); + } + USB_HS_PHYC->USB_HS_PHYC_PLL = phyc_pll; + + // Control the tuning interface of the High Speed PHY + // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver for F7 + USB_HS_PHYC->USB_HS_PHYC_TUNE |= 0x00000F13U; + + // Enable PLL internal PHY + USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; +#endif + } + } +} + +// MCU specific PHY update, it is called AFTER init() and core reset +static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + // used to set turnaround time for fullspeed, nothing to do in highspeed mode + if ( hs_phy_type == HS_PHY_TYPE_NONE ) + { + // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual + uint32_t turnaround; + + if ( SystemCoreClock >= 32000000u ) + turnaround = 0x6u; + else if ( SystemCoreClock >= 27500000u ) + turnaround = 0x7u; + else if ( SystemCoreClock >= 24000000u ) + turnaround = 0x8u; + else if ( SystemCoreClock >= 21800000u ) + turnaround = 0x9u; + else if ( SystemCoreClock >= 20000000u ) + turnaround = 0xAu; + else if ( SystemCoreClock >= 18500000u ) + turnaround = 0xBu; + else if ( SystemCoreClock >= 17200000u ) + turnaround = 0xCu; + else if ( SystemCoreClock >= 16000000u ) + turnaround = 0xDu; + else if ( SystemCoreClock >= 15000000u ) + turnaround = 0xEu; + else + turnaround = 0xFu; + + dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos); + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* _DWC2_STM32_H_ */ diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_type.h b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_type.h new file mode 100644 index 0000000..7fa2028 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_type.h @@ -0,0 +1,1730 @@ +/** + * @author MCD Application Team + * Ha Thach (tinyusb.org) + * + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + */ + +#ifndef _TUSB_DWC2_TYPES_H_ +#define _TUSB_DWC2_TYPES_H_ + +#include "stdint.h" + +/* DWC OTG HW Release versions */ +#define DWC2_CORE_REV_2_71a 0x4f54271a +#define DWC2_CORE_REV_2_72a 0x4f54272a +#define DWC2_CORE_REV_2_80a 0x4f54280a +#define DWC2_CORE_REV_2_90a 0x4f54290a +#define DWC2_CORE_REV_2_91a 0x4f54291a +#define DWC2_CORE_REV_2_92a 0x4f54292a +#define DWC2_CORE_REV_2_94a 0x4f54294a +#define DWC2_CORE_REV_3_00a 0x4f54300a +#define DWC2_CORE_REV_3_10a 0x4f54310a +#define DWC2_CORE_REV_4_00a 0x4f54400a +#define DWC2_CORE_REV_4_20a 0x4f54420a +#define DWC2_FS_IOT_REV_1_00a 0x5531100a +#define DWC2_HS_IOT_REV_1_00a 0x5532100a +#define DWC2_CORE_REV_MASK 0x0000ffff + +/* DWC OTG HW Core ID */ +#define DWC2_OTG_ID 0x4f540000 +#define DWC2_FS_IOT_ID 0x55310000 +#define DWC2_HS_IOT_ID 0x55320000 + +#ifdef __cplusplus + extern "C" { +#endif + +#if 0 +// HS PHY +typedef struct +{ + volatile uint32_t HS_PHYC_PLL; // This register is used to control the PLL of the HS PHY. 000h */ + volatile uint32_t Reserved04; // Reserved 004h */ + volatile uint32_t Reserved08; // Reserved 008h */ + volatile uint32_t HS_PHYC_TUNE; // This register is used to control the tuning interface of the High Speed PHY. 00Ch */ + volatile uint32_t Reserved10; // Reserved 010h */ + volatile uint32_t Reserved14; // Reserved 014h */ + volatile uint32_t HS_PHYC_LDO; // This register is used to control the regulator (LDO). 018h */ +} HS_PHYC_GlobalTypeDef; +#endif + +enum { + HS_PHY_TYPE_NONE = 0 , // not supported + HS_PHY_TYPE_UTMI , // internal PHY (mostly) + HS_PHY_TYPE_ULPI , // external PHY + HS_PHY_TYPE_UTMI_ULPI , +}; + +enum { + FS_PHY_TYPE_NONE = 0, // not supported + FS_PHY_TYPE_DEDICATED, + FS_PHY_TYPE_UTMI, + FS_PHY_TYPE_ULPI, +}; + +typedef struct TU_ATTR_PACKED +{ + uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP + uint32_t arch : 2; // 0: slave-only | 1: External DMA | 2: Internal DMA | 3: others + uint32_t point2point : 1; // 0: support hub and split | 1: no hub, no split + uint32_t hs_phy_type : 2; // 0: not supported | 1: UTMI+ | 2: ULPI | 3: UTMI+ and ULPI + uint32_t fs_phy_type : 2; // 0: not supported | 1: dedicated | 2: UTMI+ | 3: ULPI + uint32_t num_dev_ep : 4; // Number of device endpoints (not including EP0) + uint32_t num_host_ch : 4; // Number of host channel + uint32_t period_channel_support : 1; // Support Periodic OUT Host Channel + uint32_t enable_dynamic_fifo : 1; // Dynamic FIFO Sizing Enabled + uint32_t mul_cpu_int : 1; // Multi-Processor Interrupt Enabled + uint32_t reserved21 : 1; + uint32_t nperiod_tx_q_depth : 2; // Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 + uint32_t host_period_tx_q_depth : 2; // Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 + uint32_t dev_token_q_depth : 5; // Device IN token sequence learning queue depth: 0-30 + uint32_t otg_enable_ic_usb : 1; // IC_USB mode specified for mode of operation +} dwc2_ghwcfg2_t; + +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg2_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED +{ + uint32_t xfer_size_width : 4; // Transfer size counter in bits = 11 + n (max 19 bits) + uint32_t packet_size_width : 3; // Packet size counter in bits = 4 + n (max 10 bits) + uint32_t otg_enable : 1; // 1 is OTG capable + uint32_t i2c_enable : 1; // I2C interface is available + uint32_t vendor_ctrl_itf : 1; // Vendor control interface is available + uint32_t optional_feature_removed : 1; // remove User ID, GPIO, SOF toggle & counter + uint32_t synch_reset : 1; // 0: async reset | 1: synch reset + uint32_t otg_adp_support : 1; // ADP logic is present along with HSOTG controller + uint32_t otg_enable_hsic : 1; // 1: HSIC-capable with shared UTMI PHY interface | 0: non-HSIC + uint32_t battery_charger_support : 1; // support battery charger + uint32_t lpm_mode : 1; // LPC mode + uint32_t total_fifo_size : 16; // DFIFO depth value in terms of 32-bit words +}dwc2_ghwcfg3_t; + +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED +{ + uint32_t num_dev_period_in_ep : 4; // Number of Device Periodic IN Endpoints + uint32_t power_optimized : 1; // Partial Power Down Enabled + uint32_t ahb_freq_min : 1; // 1: minimum of AHB frequency is less than 60 MHz + uint32_t hibernation : 1; // Hibernation feature is enabled + uint32_t reserved7 : 3; + uint32_t service_interval_mode : 1; // Service Interval supported + uint32_t ipg_isoc_en : 1; // IPG ISOC supported + uint32_t acg_enable : 1; // ACG enabled + uint32_t reserved13 : 1; + uint32_t utmi_phy_data_width : 2; // 0: 8 bits | 1: 16 bits | 2: 8/16 software selectable + uint32_t dev_ctrl_ep_num : 4; // Number of Device control endpoints in addition to EP0 + uint32_t iddg_filter_enabled : 1; + uint32_t vbus_valid_filter_enabled : 1; + uint32_t a_valid_filter_enabled : 1; + uint32_t b_valid_filter_enabled : 1; + uint32_t dedicated_fifos : 1; // Dedicated tx fifo for device IN Endpoint is enabled + uint32_t num_dev_in_eps : 4; // Number of Device IN Endpoints including EP0 + uint32_t dma_desc_enable : 1; // scatter/gather DMA configuration + uint32_t dma_dynamic : 1; // Dynamic scatter/gather DMA +}dwc2_ghwcfg4_t; + +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg4_t) == 4, "incorrect size"); + +// Host Channel +typedef struct +{ + volatile uint32_t hcchar; // 500 + 20*ch Host Channel Characteristics + volatile uint32_t hcsplt; // 504 + 20*ch Host Channel Split Control + volatile uint32_t hcint; // 508 + 20*ch Host Channel Interrupt + volatile uint32_t hcintmsk; // 50C + 20*ch Host Channel Interrupt Mask + volatile uint32_t hctsiz; // 510 + 20*ch Host Channel Transfer Size + volatile uint32_t hcdma; // 514 + 20*ch Host Channel DMA Address + uint32_t reserved518; // 518 + 20*ch + volatile uint32_t hcdmab; // 51C + 20*ch Host Channel DMA Address +} dwc2_channel_t; + +// Endpoint IN +typedef struct +{ + volatile uint32_t diepctl; // 900 + 20*ep Device IN Endpoint Control + uint32_t reserved04; // 904 + volatile uint32_t diepint; // 908 + 20*ep Device IN Endpoint Interrupt + uint32_t reserved0c; // 90C + volatile uint32_t dieptsiz; // 910 + 20*ep Device IN Endpoint Transfer Size + volatile uint32_t diepdma; // 914 + 20*ep Device IN Endpoint DMA Address + volatile uint32_t dtxfsts; // 918 + 20*ep Device IN Endpoint Tx FIFO Status + uint32_t reserved1c; // 91C +} dwc2_epin_t; + +// Endpoint OUT +typedef struct +{ + volatile uint32_t doepctl; // B00 + 20*ep Device OUT Endpoint Control + uint32_t reserved04; // B04 + volatile uint32_t doepint; // B08 + 20*ep Device OUT Endpoint Interrupt + uint32_t reserved0c; // B0C + volatile uint32_t doeptsiz; // B10 + 20*ep Device OUT Endpoint Transfer Size + volatile uint32_t doepdma; // B14 + 20*ep Device OUT Endpoint DMA Address + uint32_t reserved18[2]; // B18..B1C +} dwc2_epout_t; + +typedef struct +{ + //------------- Core Global -------------// + volatile uint32_t gotgctl; // 000 OTG Control and Status + volatile uint32_t gotgint; // 004 OTG Interrupt + volatile uint32_t gahbcfg; // 008 AHB Configuration + volatile uint32_t gusbcfg; // 00c USB Configuration + volatile uint32_t grstctl; // 010 Reset + volatile uint32_t gintsts; // 014 Interrupt + volatile uint32_t gintmsk; // 018 Interrupt Mask + volatile uint32_t grxstsr; // 01c Receive Status Debug Read + volatile uint32_t grxstsp; // 020 Receive Status Read/Pop + volatile uint32_t grxfsiz; // 024 Receive FIFO Size +union { + volatile uint32_t dieptxf0; // 028 EP0 Tx FIFO Size + volatile uint32_t gnptxfsiz; // 028 Non-periodic Transmit FIFO Size +}; + volatile uint32_t gnptxsts; // 02c Non-periodic Transmit FIFO/Queue Status + volatile uint32_t gi2cctl; // 030 I2C Address + volatile uint32_t gpvndctl; // 034 PHY Vendor Control +union { + volatile uint32_t ggpio; // 038 General Purpose IO + volatile uint32_t stm32_gccfg; // 038 STM32 General Core Configuration +}; + volatile uint32_t guid; // 03C User (Application programmable) ID + volatile uint32_t gsnpsid; // 040 Synopsys ID + Release version + volatile uint32_t ghwcfg1; // 044 User Hardware Configuration1: endpoint dir (2 bit per ep) +union { + volatile uint32_t ghwcfg2; // 048 User Hardware Configuration2 + dwc2_ghwcfg2_t ghwcfg2_bm; +}; +union { + volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 + dwc2_ghwcfg3_t ghwcfg3_bm; +}; +union { + volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 + dwc2_ghwcfg4_t ghwcfg4_bm; +}; + volatile uint32_t glpmcfg; // 054 Core LPM Configuration + volatile uint32_t gpwrdn; // 058 Power Down + volatile uint32_t gdfifocfg; // 05C DFIFO Software Configuration + volatile uint32_t gadpctl; // 060 ADP Timer, Control and Status + uint32_t reserved64[39]; // 064..0FF + volatile uint32_t hptxfsiz; // 100 Host Periodic Tx FIFO Size + volatile uint32_t dieptxf[15]; // 104..13C Device Periodic Transmit FIFO Size + uint32_t reserved140[176]; // 140..3FF + + //------------- Host -------------// + volatile uint32_t hcfg; // 400 Host Configuration + volatile uint32_t hfir; // 404 Host Frame Interval + volatile uint32_t hfnum; // 408 Host Frame Number / Frame Remaining + uint32_t reserved40c; // 40C + volatile uint32_t hptxsts; // 410 Host Periodic TX FIFO / Queue Status + volatile uint32_t haint; // 414 Host All Channels Interrupt + volatile uint32_t haintmsk; // 418 Host All Channels Interrupt Mask + volatile uint32_t hflbaddr; // 41C Host Frame List Base Address + uint32_t reserved420[8]; // 420..43F + volatile uint32_t hprt; // 440 Host Port Control and Status + uint32_t reserved444[47]; // 444..4FF + + //------------- Host Channel -------------// + dwc2_channel_t channel[16]; // 500..6FF Host Channels 0-15 + uint32_t reserved700[64]; // 700..7FF + + //------------- Device -------------// + volatile uint32_t dcfg; // 800 Device Configuration + volatile uint32_t dctl; // 804 Device Control + volatile uint32_t dsts; // 808 Device Status (RO) + uint32_t reserved80c; // 80C + volatile uint32_t diepmsk; // 810 Device IN Endpoint Interrupt Mask + volatile uint32_t doepmsk; // 814 Device OUT Endpoint Interrupt Mask + volatile uint32_t daint; // 818 Device All Endpoints Interrupt + volatile uint32_t daintmsk; // 81C Device All Endpoints Interrupt Mask + volatile uint32_t dtknqr1; // 820 Device IN token sequence learning queue read1 + volatile uint32_t dtknqr2; // 824 Device IN token sequence learning queue read2 + volatile uint32_t dvbusdis; // 828 Device VBUS Discharge Time + volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time + volatile uint32_t dthrctl; // 830 Device threshold Control + volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask + volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt + volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk + volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask + volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask + uint32_t reserved8c0[16]; // 8C0..8FF + + //------------- Device Endpoint -------------// + dwc2_epin_t epin[16]; // 900..AFF IN Endpoints + dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints + uint32_t reservedd00[64]; // D00..DFF + + //------------- Power Clock -------------// + volatile uint32_t pcgctl; // E00 Power and Clock Gating Control + volatile uint32_t pcgctl1; // E04 + uint32_t reservede08[126]; // E08..FFF + + //------------- FIFOs -------------// + // Word-accessed only using first pointer since it auto shift + volatile uint32_t fifo[16][0x400]; // 1000..FFFF Endpoint FIFO +} dwc2_regs_t; + +TU_VERIFY_STATIC(offsetof(dwc2_regs_t, hcfg ) == 0x0400, "incorrect size"); +TU_VERIFY_STATIC(offsetof(dwc2_regs_t, channel) == 0x0500, "incorrect size"); +TU_VERIFY_STATIC(offsetof(dwc2_regs_t, dcfg ) == 0x0800, "incorrect size"); +TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epin ) == 0x0900, "incorrect size"); +TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epout ) == 0x0B00, "incorrect size"); +TU_VERIFY_STATIC(offsetof(dwc2_regs_t, pcgctl ) == 0x0E00, "incorrect size"); +TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); + +//--------------------------------------------------------------------+ +// Register Bit Definitions +//--------------------------------------------------------------------+ + +/******************** Bit definition for GOTGCTL register ********************/ +#define GOTGCTL_SRQSCS_Pos (0U) +#define GOTGCTL_SRQSCS_Msk (0x1UL << GOTGCTL_SRQSCS_Pos) // 0x00000001 */ +#define GOTGCTL_SRQSCS GOTGCTL_SRQSCS_Msk // Session request success */ +#define GOTGCTL_SRQ_Pos (1U) +#define GOTGCTL_SRQ_Msk (0x1UL << GOTGCTL_SRQ_Pos) // 0x00000002 */ +#define GOTGCTL_SRQ GOTGCTL_SRQ_Msk // Session request */ +#define GOTGCTL_VBVALOEN_Pos (2U) +#define GOTGCTL_VBVALOEN_Msk (0x1UL << GOTGCTL_VBVALOEN_Pos) // 0x00000004 */ +#define GOTGCTL_VBVALOEN GOTGCTL_VBVALOEN_Msk // VBUS valid override enable */ +#define GOTGCTL_VBVALOVAL_Pos (3U) +#define GOTGCTL_VBVALOVAL_Msk (0x1UL << GOTGCTL_VBVALOVAL_Pos) // 0x00000008 */ +#define GOTGCTL_VBVALOVAL GOTGCTL_VBVALOVAL_Msk // VBUS valid override value */ +#define GOTGCTL_AVALOEN_Pos (4U) +#define GOTGCTL_AVALOEN_Msk (0x1UL << GOTGCTL_AVALOEN_Pos) // 0x00000010 */ +#define GOTGCTL_AVALOEN GOTGCTL_AVALOEN_Msk // A-peripheral session valid override enable */ +#define GOTGCTL_AVALOVAL_Pos (5U) +#define GOTGCTL_AVALOVAL_Msk (0x1UL << GOTGCTL_AVALOVAL_Pos) // 0x00000020 */ +#define GOTGCTL_AVALOVAL GOTGCTL_AVALOVAL_Msk // A-peripheral session valid override value */ +#define GOTGCTL_BVALOEN_Pos (6U) +#define GOTGCTL_BVALOEN_Msk (0x1UL << GOTGCTL_BVALOEN_Pos) // 0x00000040 */ +#define GOTGCTL_BVALOEN GOTGCTL_BVALOEN_Msk // B-peripheral session valid override enable */ +#define GOTGCTL_BVALOVAL_Pos (7U) +#define GOTGCTL_BVALOVAL_Msk (0x1UL << GOTGCTL_BVALOVAL_Pos) // 0x00000080 */ +#define GOTGCTL_BVALOVAL GOTGCTL_BVALOVAL_Msk // B-peripheral session valid override value */ +#define GOTGCTL_HNGSCS_Pos (8U) +#define GOTGCTL_HNGSCS_Msk (0x1UL << GOTGCTL_HNGSCS_Pos) // 0x00000100 */ +#define GOTGCTL_HNGSCS GOTGCTL_HNGSCS_Msk // Host set HNP enable */ +#define GOTGCTL_HNPRQ_Pos (9U) +#define GOTGCTL_HNPRQ_Msk (0x1UL << GOTGCTL_HNPRQ_Pos) // 0x00000200 */ +#define GOTGCTL_HNPRQ GOTGCTL_HNPRQ_Msk // HNP request */ +#define GOTGCTL_HSHNPEN_Pos (10U) +#define GOTGCTL_HSHNPEN_Msk (0x1UL << GOTGCTL_HSHNPEN_Pos) // 0x00000400 */ +#define GOTGCTL_HSHNPEN GOTGCTL_HSHNPEN_Msk // Host set HNP enable */ +#define GOTGCTL_DHNPEN_Pos (11U) +#define GOTGCTL_DHNPEN_Msk (0x1UL << GOTGCTL_DHNPEN_Pos) // 0x00000800 */ +#define GOTGCTL_DHNPEN GOTGCTL_DHNPEN_Msk // Device HNP enabled */ +#define GOTGCTL_EHEN_Pos (12U) +#define GOTGCTL_EHEN_Msk (0x1UL << GOTGCTL_EHEN_Pos) // 0x00001000 */ +#define GOTGCTL_EHEN GOTGCTL_EHEN_Msk // Embedded host enable */ +#define GOTGCTL_CIDSTS_Pos (16U) +#define GOTGCTL_CIDSTS_Msk (0x1UL << GOTGCTL_CIDSTS_Pos) // 0x00010000 */ +#define GOTGCTL_CIDSTS GOTGCTL_CIDSTS_Msk // Connector ID status */ +#define GOTGCTL_DBCT_Pos (17U) +#define GOTGCTL_DBCT_Msk (0x1UL << GOTGCTL_DBCT_Pos) // 0x00020000 */ +#define GOTGCTL_DBCT GOTGCTL_DBCT_Msk // Long/short debounce time */ +#define GOTGCTL_ASVLD_Pos (18U) +#define GOTGCTL_ASVLD_Msk (0x1UL << GOTGCTL_ASVLD_Pos) // 0x00040000 */ +#define GOTGCTL_ASVLD GOTGCTL_ASVLD_Msk // A-session valid */ +#define GOTGCTL_BSESVLD_Pos (19U) +#define GOTGCTL_BSESVLD_Msk (0x1UL << GOTGCTL_BSESVLD_Pos) // 0x00080000 */ +#define GOTGCTL_BSESVLD GOTGCTL_BSESVLD_Msk // B-session valid */ +#define GOTGCTL_OTGVER_Pos (20U) +#define GOTGCTL_OTGVER_Msk (0x1UL << GOTGCTL_OTGVER_Pos) // 0x00100000 */ +#define GOTGCTL_OTGVER GOTGCTL_OTGVER_Msk // OTG version */ + +/******************** Bit definition for HCFG register ********************/ +#define HCFG_FSLSPCS_Pos (0U) +#define HCFG_FSLSPCS_Msk (0x3UL << HCFG_FSLSPCS_Pos) // 0x00000003 */ +#define HCFG_FSLSPCS HCFG_FSLSPCS_Msk // FS/LS PHY clock select */ +#define HCFG_FSLSPCS_0 (0x1UL << HCFG_FSLSPCS_Pos) // 0x00000001 */ +#define HCFG_FSLSPCS_1 (0x2UL << HCFG_FSLSPCS_Pos) // 0x00000002 */ +#define HCFG_FSLSS_Pos (2U) +#define HCFG_FSLSS_Msk (0x1UL << HCFG_FSLSS_Pos) // 0x00000004 */ +#define HCFG_FSLSS HCFG_FSLSS_Msk // FS- and LS-only support */ + +/******************** Bit definition for PCGCR register ********************/ +#define PCGCR_STPPCLK_Pos (0U) +#define PCGCR_STPPCLK_Msk (0x1UL << PCGCR_STPPCLK_Pos) // 0x00000001 */ +#define PCGCR_STPPCLK PCGCR_STPPCLK_Msk // Stop PHY clock */ +#define PCGCR_GATEHCLK_Pos (1U) +#define PCGCR_GATEHCLK_Msk (0x1UL << PCGCR_GATEHCLK_Pos) // 0x00000002 */ +#define PCGCR_GATEHCLK PCGCR_GATEHCLK_Msk // Gate HCLK */ +#define PCGCR_PHYSUSP_Pos (4U) +#define PCGCR_PHYSUSP_Msk (0x1UL << PCGCR_PHYSUSP_Pos) // 0x00000010 */ +#define PCGCR_PHYSUSP PCGCR_PHYSUSP_Msk // PHY suspended */ + +/******************** Bit definition for GOTGINT register ********************/ +#define GOTGINT_SEDET_Pos (2U) +#define GOTGINT_SEDET_Msk (0x1UL << GOTGINT_SEDET_Pos) // 0x00000004 */ +#define GOTGINT_SEDET GOTGINT_SEDET_Msk // Session end detected */ +#define GOTGINT_SRSSCHG_Pos (8U) +#define GOTGINT_SRSSCHG_Msk (0x1UL << GOTGINT_SRSSCHG_Pos) // 0x00000100 */ +#define GOTGINT_SRSSCHG GOTGINT_SRSSCHG_Msk // Session request success status change */ +#define GOTGINT_HNSSCHG_Pos (9U) +#define GOTGINT_HNSSCHG_Msk (0x1UL << GOTGINT_HNSSCHG_Pos) // 0x00000200 */ +#define GOTGINT_HNSSCHG GOTGINT_HNSSCHG_Msk // Host negotiation success status change */ +#define GOTGINT_HNGDET_Pos (17U) +#define GOTGINT_HNGDET_Msk (0x1UL << GOTGINT_HNGDET_Pos) // 0x00020000 */ +#define GOTGINT_HNGDET GOTGINT_HNGDET_Msk // Host negotiation detected */ +#define GOTGINT_ADTOCHG_Pos (18U) +#define GOTGINT_ADTOCHG_Msk (0x1UL << GOTGINT_ADTOCHG_Pos) // 0x00040000 */ +#define GOTGINT_ADTOCHG GOTGINT_ADTOCHG_Msk // A-device timeout change */ +#define GOTGINT_DBCDNE_Pos (19U) +#define GOTGINT_DBCDNE_Msk (0x1UL << GOTGINT_DBCDNE_Pos) // 0x00080000 */ +#define GOTGINT_DBCDNE GOTGINT_DBCDNE_Msk // Debounce done */ +#define GOTGINT_IDCHNG_Pos (20U) +#define GOTGINT_IDCHNG_Msk (0x1UL << GOTGINT_IDCHNG_Pos) // 0x00100000 */ +#define GOTGINT_IDCHNG GOTGINT_IDCHNG_Msk // Change in ID pin input value */ + +/******************** Bit definition for DCFG register ********************/ +#define DCFG_DSPD_Pos (0U) +#define DCFG_DSPD_Msk (0x3UL << DCFG_DSPD_Pos) // 0x00000003 +#define DCFG_DSPD_HS 0 // Highspeed +#define DCFG_DSPD_FS_HSPHY 1 // Fullspeed on HS PHY +#define DCFG_DSPD_LS 2 // Lowspeed +#define DCFG_DSPD_FS 3 // Fullspeed on FS PHY + +#define DCFG_NZLSOHSK_Pos (2U) +#define DCFG_NZLSOHSK_Msk (0x1UL << DCFG_NZLSOHSK_Pos) // 0x00000004 */ +#define DCFG_NZLSOHSK DCFG_NZLSOHSK_Msk // Nonzero-length status OUT handshake */ + +#define DCFG_DAD_Pos (4U) +#define DCFG_DAD_Msk (0x7FUL << DCFG_DAD_Pos) // 0x000007F0 */ +#define DCFG_DAD DCFG_DAD_Msk // Device address */ +#define DCFG_DAD_0 (0x01UL << DCFG_DAD_Pos) // 0x00000010 */ +#define DCFG_DAD_1 (0x02UL << DCFG_DAD_Pos) // 0x00000020 */ +#define DCFG_DAD_2 (0x04UL << DCFG_DAD_Pos) // 0x00000040 */ +#define DCFG_DAD_3 (0x08UL << DCFG_DAD_Pos) // 0x00000080 */ +#define DCFG_DAD_4 (0x10UL << DCFG_DAD_Pos) // 0x00000100 */ +#define DCFG_DAD_5 (0x20UL << DCFG_DAD_Pos) // 0x00000200 */ +#define DCFG_DAD_6 (0x40UL << DCFG_DAD_Pos) // 0x00000400 */ + +#define DCFG_PFIVL_Pos (11U) +#define DCFG_PFIVL_Msk (0x3UL << DCFG_PFIVL_Pos) // 0x00001800 */ +#define DCFG_PFIVL DCFG_PFIVL_Msk // Periodic (micro)frame interval */ +#define DCFG_PFIVL_0 (0x1UL << DCFG_PFIVL_Pos) // 0x00000800 */ +#define DCFG_PFIVL_1 (0x2UL << DCFG_PFIVL_Pos) // 0x00001000 */ + +#define DCFG_XCVRDLY_Pos (14U) +#define DCFG_XCVRDLY_Msk (0x1UL << DCFG_XCVRDLY_Pos) /*!< 0x00004000 */ +#define DCFG_XCVRDLY DCFG_XCVRDLY_Msk // Enables delay between xcvr_sel and txvalid during device chirp + +#define DCFG_PERSCHIVL_Pos (24U) +#define DCFG_PERSCHIVL_Msk (0x3UL << DCFG_PERSCHIVL_Pos) // 0x03000000 */ +#define DCFG_PERSCHIVL DCFG_PERSCHIVL_Msk // Periodic scheduling interval */ +#define DCFG_PERSCHIVL_0 (0x1UL << DCFG_PERSCHIVL_Pos) // 0x01000000 */ +#define DCFG_PERSCHIVL_1 (0x2UL << DCFG_PERSCHIVL_Pos) // 0x02000000 */ + +/******************** Bit definition for DCTL register ********************/ +#define DCTL_RWUSIG_Pos (0U) +#define DCTL_RWUSIG_Msk (0x1UL << DCTL_RWUSIG_Pos) // 0x00000001 */ +#define DCTL_RWUSIG DCTL_RWUSIG_Msk // Remote wakeup signaling */ +#define DCTL_SDIS_Pos (1U) +#define DCTL_SDIS_Msk (0x1UL << DCTL_SDIS_Pos) // 0x00000002 */ +#define DCTL_SDIS DCTL_SDIS_Msk // Soft disconnect */ +#define DCTL_GINSTS_Pos (2U) +#define DCTL_GINSTS_Msk (0x1UL << DCTL_GINSTS_Pos) // 0x00000004 */ +#define DCTL_GINSTS DCTL_GINSTS_Msk // Global IN NAK status */ +#define DCTL_GONSTS_Pos (3U) +#define DCTL_GONSTS_Msk (0x1UL << DCTL_GONSTS_Pos) // 0x00000008 */ +#define DCTL_GONSTS DCTL_GONSTS_Msk // Global OUT NAK status */ + +#define DCTL_TCTL_Pos (4U) +#define DCTL_TCTL_Msk (0x7UL << DCTL_TCTL_Pos) // 0x00000070 */ +#define DCTL_TCTL DCTL_TCTL_Msk // Test control */ +#define DCTL_TCTL_0 (0x1UL << DCTL_TCTL_Pos) // 0x00000010 */ +#define DCTL_TCTL_1 (0x2UL << DCTL_TCTL_Pos) // 0x00000020 */ +#define DCTL_TCTL_2 (0x4UL << DCTL_TCTL_Pos) // 0x00000040 */ +#define DCTL_SGINAK_Pos (7U) +#define DCTL_SGINAK_Msk (0x1UL << DCTL_SGINAK_Pos) // 0x00000080 */ +#define DCTL_SGINAK DCTL_SGINAK_Msk // Set global IN NAK */ +#define DCTL_CGINAK_Pos (8U) +#define DCTL_CGINAK_Msk (0x1UL << DCTL_CGINAK_Pos) // 0x00000100 */ +#define DCTL_CGINAK DCTL_CGINAK_Msk // Clear global IN NAK */ +#define DCTL_SGONAK_Pos (9U) +#define DCTL_SGONAK_Msk (0x1UL << DCTL_SGONAK_Pos) // 0x00000200 */ +#define DCTL_SGONAK DCTL_SGONAK_Msk // Set global OUT NAK */ +#define DCTL_CGONAK_Pos (10U) +#define DCTL_CGONAK_Msk (0x1UL << DCTL_CGONAK_Pos) // 0x00000400 */ +#define DCTL_CGONAK DCTL_CGONAK_Msk // Clear global OUT NAK */ +#define DCTL_POPRGDNE_Pos (11U) +#define DCTL_POPRGDNE_Msk (0x1UL << DCTL_POPRGDNE_Pos) // 0x00000800 */ +#define DCTL_POPRGDNE DCTL_POPRGDNE_Msk // Power-on programming done */ + +/******************** Bit definition for HFIR register ********************/ +#define HFIR_FRIVL_Pos (0U) +#define HFIR_FRIVL_Msk (0xFFFFUL << HFIR_FRIVL_Pos) // 0x0000FFFF */ +#define HFIR_FRIVL HFIR_FRIVL_Msk // Frame interval */ + +/******************** Bit definition for HFNUM register ********************/ +#define HFNUM_FRNUM_Pos (0U) +#define HFNUM_FRNUM_Msk (0xFFFFUL << HFNUM_FRNUM_Pos) // 0x0000FFFF */ +#define HFNUM_FRNUM HFNUM_FRNUM_Msk // Frame number */ +#define HFNUM_FTREM_Pos (16U) +#define HFNUM_FTREM_Msk (0xFFFFUL << HFNUM_FTREM_Pos) // 0xFFFF0000 */ +#define HFNUM_FTREM HFNUM_FTREM_Msk // Frame time remaining */ + +/******************** Bit definition for DSTS register ********************/ +#define DSTS_SUSPSTS_Pos (0U) +#define DSTS_SUSPSTS_Msk (0x1UL << DSTS_SUSPSTS_Pos) // 0x00000001 */ +#define DSTS_SUSPSTS DSTS_SUSPSTS_Msk // Suspend status */ +#define DSTS_ENUMSPD_Pos (1U) +#define DSTS_ENUMSPD_Msk (0x3UL << DSTS_ENUMSPD_Pos) // 0x00000006 */ +#define DSTS_ENUMSPD DSTS_ENUMSPD_Msk // Enumerated speed */ +#define DSTS_ENUMSPD_HS 0 // Highspeed +#define DSTS_ENUMSPD_FS_HSPHY 1 // Fullspeed on HS PHY +#define DSTS_ENUMSPD_LS 2 // Lowspeed +#define DSTS_ENUMSPD_FS 3 // Fullspeed on FS PHY + + +#define DSTS_EERR_Pos (3U) +#define DSTS_EERR_Msk (0x1UL << DSTS_EERR_Pos) // 0x00000008 */ +#define DSTS_EERR DSTS_EERR_Msk // Erratic error */ +#define DSTS_FNSOF_Pos (8U) +#define DSTS_FNSOF_Msk (0x3FFFUL << DSTS_FNSOF_Pos) // 0x003FFF00 */ +#define DSTS_FNSOF DSTS_FNSOF_Msk // Frame number of the received SOF */ + +/******************** Bit definition for GAHBCFG register ********************/ +#define GAHBCFG_GINT_Pos (0U) +#define GAHBCFG_GINT_Msk (0x1UL << GAHBCFG_GINT_Pos) // 0x00000001 */ +#define GAHBCFG_GINT GAHBCFG_GINT_Msk // Global interrupt mask */ +#define GAHBCFG_HBSTLEN_Pos (1U) +#define GAHBCFG_HBSTLEN_Msk (0xFUL << GAHBCFG_HBSTLEN_Pos) // 0x0000001E */ +#define GAHBCFG_HBSTLEN GAHBCFG_HBSTLEN_Msk // Burst length/type */ +#define GAHBCFG_HBSTLEN_0 (0x0UL << GAHBCFG_HBSTLEN_Pos) // Single */ +#define GAHBCFG_HBSTLEN_1 (0x1UL << GAHBCFG_HBSTLEN_Pos) // INCR */ +#define GAHBCFG_HBSTLEN_2 (0x3UL << GAHBCFG_HBSTLEN_Pos) // INCR4 */ +#define GAHBCFG_HBSTLEN_3 (0x5UL << GAHBCFG_HBSTLEN_Pos) // INCR8 */ +#define GAHBCFG_HBSTLEN_4 (0x7UL << GAHBCFG_HBSTLEN_Pos) // INCR16 */ +#define GAHBCFG_DMAEN_Pos (5U) +#define GAHBCFG_DMAEN_Msk (0x1UL << GAHBCFG_DMAEN_Pos) // 0x00000020 */ +#define GAHBCFG_DMAEN GAHBCFG_DMAEN_Msk // DMA enable */ +#define GAHBCFG_TXFELVL_Pos (7U) +#define GAHBCFG_TXFELVL_Msk (0x1UL << GAHBCFG_TXFELVL_Pos) // 0x00000080 */ +#define GAHBCFG_TXFELVL GAHBCFG_TXFELVL_Msk // TxFIFO empty level */ +#define GAHBCFG_PTXFELVL_Pos (8U) +#define GAHBCFG_PTXFELVL_Msk (0x1UL << GAHBCFG_PTXFELVL_Pos) // 0x00000100 */ +#define GAHBCFG_PTXFELVL GAHBCFG_PTXFELVL_Msk // Periodic TxFIFO empty level */ + +#define GSNPSID_ID_MASK TU_GENMASK(31, 16) + +/******************** Bit definition for GUSBCFG register ********************/ +#define GUSBCFG_TOCAL_Pos (0U) +#define GUSBCFG_TOCAL_Msk (0x7UL << GUSBCFG_TOCAL_Pos) // 0x00000007 */ +#define GUSBCFG_TOCAL GUSBCFG_TOCAL_Msk // FS timeout calibration */ +#define GUSBCFG_PHYIF16_Pos (3U) +#define GUSBCFG_PHYIF16_Msk (0x1UL << GUSBCFG_PHYIF16_Pos) // 0x00000008 */ +#define GUSBCFG_PHYIF16 GUSBCFG_PHYIF16_Msk // PHY Interface (PHYIf) */ +#define GUSBCFG_ULPI_UTMI_SEL_Pos (4U) +#define GUSBCFG_ULPI_UTMI_SEL_Msk (0x1UL << GUSBCFG_ULPI_UTMI_SEL_Pos) // 0x00000010 */ +#define GUSBCFG_ULPI_UTMI_SEL GUSBCFG_ULPI_UTMI_SEL_Msk // ULPI or UTMI+ Select (ULPI_UTMI_Sel) */ +#define GUSBCFG_PHYSEL_Pos (6U) +#define GUSBCFG_PHYSEL_Msk (0x1UL << GUSBCFG_PHYSEL_Pos) // 0x00000040 */ +#define GUSBCFG_PHYSEL GUSBCFG_PHYSEL_Msk // USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */ +#define GUSBCFG_DDRSEL TU_BIT(7) // Single Data Rate (SDR) or Double Data Rate (DDR) or ULPI interface. +#define GUSBCFG_SRPCAP_Pos (8U) +#define GUSBCFG_SRPCAP_Msk (0x1UL << GUSBCFG_SRPCAP_Pos) // 0x00000100 */ +#define GUSBCFG_SRPCAP GUSBCFG_SRPCAP_Msk // SRP-capable */ +#define GUSBCFG_HNPCAP_Pos (9U) +#define GUSBCFG_HNPCAP_Msk (0x1UL << GUSBCFG_HNPCAP_Pos) // 0x00000200 */ +#define GUSBCFG_HNPCAP GUSBCFG_HNPCAP_Msk // HNP-capable */ +#define GUSBCFG_TRDT_Pos (10U) +#define GUSBCFG_TRDT_Msk (0xFUL << GUSBCFG_TRDT_Pos) // 0x00003C00 */ +#define GUSBCFG_TRDT GUSBCFG_TRDT_Msk // USB turnaround time */ +#define GUSBCFG_PHYLPCS_Pos (15U) +#define GUSBCFG_PHYLPCS_Msk (0x1UL << GUSBCFG_PHYLPCS_Pos) // 0x00008000 */ +#define GUSBCFG_PHYLPCS GUSBCFG_PHYLPCS_Msk // PHY Low-power clock select */ +#define GUSBCFG_ULPIFSLS_Pos (17U) +#define GUSBCFG_ULPIFSLS_Msk (0x1UL << GUSBCFG_ULPIFSLS_Pos) // 0x00020000 */ +#define GUSBCFG_ULPIFSLS GUSBCFG_ULPIFSLS_Msk // ULPI FS/LS select */ +#define GUSBCFG_ULPIAR_Pos (18U) +#define GUSBCFG_ULPIAR_Msk (0x1UL << GUSBCFG_ULPIAR_Pos) // 0x00040000 */ +#define GUSBCFG_ULPIAR GUSBCFG_ULPIAR_Msk // ULPI Auto-resume */ +#define GUSBCFG_ULPICSM_Pos (19U) +#define GUSBCFG_ULPICSM_Msk (0x1UL << GUSBCFG_ULPICSM_Pos) // 0x00080000 */ +#define GUSBCFG_ULPICSM GUSBCFG_ULPICSM_Msk // ULPI Clock SuspendM */ +#define GUSBCFG_ULPIEVBUSD_Pos (20U) +#define GUSBCFG_ULPIEVBUSD_Msk (0x1UL << GUSBCFG_ULPIEVBUSD_Pos) // 0x00100000 */ +#define GUSBCFG_ULPIEVBUSD GUSBCFG_ULPIEVBUSD_Msk // ULPI External VBUS Drive */ +#define GUSBCFG_ULPIEVBUSI_Pos (21U) +#define GUSBCFG_ULPIEVBUSI_Msk (0x1UL << GUSBCFG_ULPIEVBUSI_Pos) // 0x00200000 */ +#define GUSBCFG_ULPIEVBUSI GUSBCFG_ULPIEVBUSI_Msk // ULPI external VBUS indicator */ +#define GUSBCFG_TSDPS_Pos (22U) +#define GUSBCFG_TSDPS_Msk (0x1UL << GUSBCFG_TSDPS_Pos) // 0x00400000 */ +#define GUSBCFG_TSDPS GUSBCFG_TSDPS_Msk // TermSel DLine pulsing selection */ +#define GUSBCFG_PCCI_Pos (23U) +#define GUSBCFG_PCCI_Msk (0x1UL << GUSBCFG_PCCI_Pos) // 0x00800000 */ +#define GUSBCFG_PCCI GUSBCFG_PCCI_Msk // Indicator complement */ +#define GUSBCFG_PTCI_Pos (24U) +#define GUSBCFG_PTCI_Msk (0x1UL << GUSBCFG_PTCI_Pos) // 0x01000000 */ +#define GUSBCFG_PTCI GUSBCFG_PTCI_Msk // Indicator pass through */ +#define GUSBCFG_ULPIIPD_Pos (25U) +#define GUSBCFG_ULPIIPD_Msk (0x1UL << GUSBCFG_ULPIIPD_Pos) // 0x02000000 */ +#define GUSBCFG_ULPIIPD GUSBCFG_ULPIIPD_Msk // ULPI interface protect disable */ +#define GUSBCFG_FHMOD_Pos (29U) +#define GUSBCFG_FHMOD_Msk (0x1UL << GUSBCFG_FHMOD_Pos) // 0x20000000 */ +#define GUSBCFG_FHMOD GUSBCFG_FHMOD_Msk // Forced host mode */ +#define GUSBCFG_FDMOD_Pos (30U) +#define GUSBCFG_FDMOD_Msk (0x1UL << GUSBCFG_FDMOD_Pos) // 0x40000000 */ +#define GUSBCFG_FDMOD GUSBCFG_FDMOD_Msk // Forced peripheral mode */ +#define GUSBCFG_CTXPKT_Pos (31U) +#define GUSBCFG_CTXPKT_Msk (0x1UL << GUSBCFG_CTXPKT_Pos) // 0x80000000 */ +#define GUSBCFG_CTXPKT GUSBCFG_CTXPKT_Msk // Corrupt Tx packet */ + +/******************** Bit definition for GRSTCTL register ********************/ +#define GRSTCTL_CSRST_Pos (0U) +#define GRSTCTL_CSRST_Msk (0x1UL << GRSTCTL_CSRST_Pos) // 0x00000001 */ +#define GRSTCTL_CSRST GRSTCTL_CSRST_Msk // Core soft reset */ +#define GRSTCTL_HSRST_Pos (1U) +#define GRSTCTL_HSRST_Msk (0x1UL << GRSTCTL_HSRST_Pos) // 0x00000002 */ +#define GRSTCTL_HSRST GRSTCTL_HSRST_Msk // HCLK soft reset */ +#define GRSTCTL_FCRST_Pos (2U) +#define GRSTCTL_FCRST_Msk (0x1UL << GRSTCTL_FCRST_Pos) // 0x00000004 */ +#define GRSTCTL_FCRST GRSTCTL_FCRST_Msk // Host frame counter reset */ +#define GRSTCTL_RXFFLSH_Pos (4U) +#define GRSTCTL_RXFFLSH_Msk (0x1UL << GRSTCTL_RXFFLSH_Pos) // 0x00000010 */ +#define GRSTCTL_RXFFLSH GRSTCTL_RXFFLSH_Msk // RxFIFO flush */ +#define GRSTCTL_TXFFLSH_Pos (5U) +#define GRSTCTL_TXFFLSH_Msk (0x1UL << GRSTCTL_TXFFLSH_Pos) // 0x00000020 */ +#define GRSTCTL_TXFFLSH GRSTCTL_TXFFLSH_Msk // TxFIFO flush */ +#define GRSTCTL_TXFNUM_Pos (6U) +#define GRSTCTL_TXFNUM_Msk (0x1FUL << GRSTCTL_TXFNUM_Pos) // 0x000007C0 */ +#define GRSTCTL_TXFNUM GRSTCTL_TXFNUM_Msk // TxFIFO number */ +#define GRSTCTL_TXFNUM_0 (0x01UL << GRSTCTL_TXFNUM_Pos) // 0x00000040 */ +#define GRSTCTL_TXFNUM_1 (0x02UL << GRSTCTL_TXFNUM_Pos) // 0x00000080 */ +#define GRSTCTL_TXFNUM_2 (0x04UL << GRSTCTL_TXFNUM_Pos) // 0x00000100 */ +#define GRSTCTL_TXFNUM_3 (0x08UL << GRSTCTL_TXFNUM_Pos) // 0x00000200 */ +#define GRSTCTL_TXFNUM_4 (0x10UL << GRSTCTL_TXFNUM_Pos) // 0x00000400 */ +#define GRSTCTL_CSFTRST_DONE_Pos (29) +#define GRSTCTL_CSFTRST_DONE (1u << GRSTCTL_CSFTRST_DONE_Pos) // Reset Done, only available from v4.20a +#define GRSTCTL_DMAREQ_Pos (30U) +#define GRSTCTL_DMAREQ_Msk (0x1UL << GRSTCTL_DMAREQ_Pos) // 0x40000000 */ +#define GRSTCTL_DMAREQ GRSTCTL_DMAREQ_Msk // DMA request signal */ +#define GRSTCTL_AHBIDL_Pos (31U) +#define GRSTCTL_AHBIDL_Msk (0x1UL << GRSTCTL_AHBIDL_Pos) // 0x80000000 */ +#define GRSTCTL_AHBIDL GRSTCTL_AHBIDL_Msk // AHB master idle */ + +/******************** Bit definition for DIEPMSK register ********************/ +#define DIEPMSK_XFRCM_Pos (0U) +#define DIEPMSK_XFRCM_Msk (0x1UL << DIEPMSK_XFRCM_Pos) // 0x00000001 */ +#define DIEPMSK_XFRCM DIEPMSK_XFRCM_Msk // Transfer completed interrupt mask */ +#define DIEPMSK_EPDM_Pos (1U) +#define DIEPMSK_EPDM_Msk (0x1UL << DIEPMSK_EPDM_Pos) // 0x00000002 */ +#define DIEPMSK_EPDM DIEPMSK_EPDM_Msk // Endpoint disabled interrupt mask */ +#define DIEPMSK_TOM_Pos (3U) +#define DIEPMSK_TOM_Msk (0x1UL << DIEPMSK_TOM_Pos) // 0x00000008 */ +#define DIEPMSK_TOM DIEPMSK_TOM_Msk // Timeout condition mask (nonisochronous endpoints) */ +#define DIEPMSK_ITTXFEMSK_Pos (4U) +#define DIEPMSK_ITTXFEMSK_Msk (0x1UL << DIEPMSK_ITTXFEMSK_Pos) // 0x00000010 */ +#define DIEPMSK_ITTXFEMSK DIEPMSK_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask */ +#define DIEPMSK_INEPNMM_Pos (5U) +#define DIEPMSK_INEPNMM_Msk (0x1UL << DIEPMSK_INEPNMM_Pos) // 0x00000020 */ +#define DIEPMSK_INEPNMM DIEPMSK_INEPNMM_Msk // IN token received with EP mismatch mask */ +#define DIEPMSK_INEPNEM_Pos (6U) +#define DIEPMSK_INEPNEM_Msk (0x1UL << DIEPMSK_INEPNEM_Pos) // 0x00000040 */ +#define DIEPMSK_INEPNEM DIEPMSK_INEPNEM_Msk // IN endpoint NAK effective mask */ +#define DIEPMSK_TXFURM_Pos (8U) +#define DIEPMSK_TXFURM_Msk (0x1UL << DIEPMSK_TXFURM_Pos) // 0x00000100 */ +#define DIEPMSK_TXFURM DIEPMSK_TXFURM_Msk // FIFO underrun mask */ +#define DIEPMSK_BIM_Pos (9U) +#define DIEPMSK_BIM_Msk (0x1UL << DIEPMSK_BIM_Pos) // 0x00000200 */ +#define DIEPMSK_BIM DIEPMSK_BIM_Msk // BNA interrupt mask */ + +/******************** Bit definition for HPTXSTS register ********************/ +#define HPTXSTS_PTXFSAVL_Pos (0U) +#define HPTXSTS_PTXFSAVL_Msk (0xFFFFUL << HPTXSTS_PTXFSAVL_Pos) // 0x0000FFFF */ +#define HPTXSTS_PTXFSAVL HPTXSTS_PTXFSAVL_Msk // Periodic transmit data FIFO space available */ +#define HPTXSTS_PTXQSAV_Pos (16U) +#define HPTXSTS_PTXQSAV_Msk (0xFFUL << HPTXSTS_PTXQSAV_Pos) // 0x00FF0000 */ +#define HPTXSTS_PTXQSAV HPTXSTS_PTXQSAV_Msk // Periodic transmit request queue space available */ +#define HPTXSTS_PTXQSAV_0 (0x01UL << HPTXSTS_PTXQSAV_Pos) // 0x00010000 */ +#define HPTXSTS_PTXQSAV_1 (0x02UL << HPTXSTS_PTXQSAV_Pos) // 0x00020000 */ +#define HPTXSTS_PTXQSAV_2 (0x04UL << HPTXSTS_PTXQSAV_Pos) // 0x00040000 */ +#define HPTXSTS_PTXQSAV_3 (0x08UL << HPTXSTS_PTXQSAV_Pos) // 0x00080000 */ +#define HPTXSTS_PTXQSAV_4 (0x10UL << HPTXSTS_PTXQSAV_Pos) // 0x00100000 */ +#define HPTXSTS_PTXQSAV_5 (0x20UL << HPTXSTS_PTXQSAV_Pos) // 0x00200000 */ +#define HPTXSTS_PTXQSAV_6 (0x40UL << HPTXSTS_PTXQSAV_Pos) // 0x00400000 */ +#define HPTXSTS_PTXQSAV_7 (0x80UL << HPTXSTS_PTXQSAV_Pos) // 0x00800000 */ + +#define HPTXSTS_PTXQTOP_Pos (24U) +#define HPTXSTS_PTXQTOP_Msk (0xFFUL << HPTXSTS_PTXQTOP_Pos) // 0xFF000000 */ +#define HPTXSTS_PTXQTOP HPTXSTS_PTXQTOP_Msk // Top of the periodic transmit request queue */ +#define HPTXSTS_PTXQTOP_0 (0x01UL << HPTXSTS_PTXQTOP_Pos) // 0x01000000 */ +#define HPTXSTS_PTXQTOP_1 (0x02UL << HPTXSTS_PTXQTOP_Pos) // 0x02000000 */ +#define HPTXSTS_PTXQTOP_2 (0x04UL << HPTXSTS_PTXQTOP_Pos) // 0x04000000 */ +#define HPTXSTS_PTXQTOP_3 (0x08UL << HPTXSTS_PTXQTOP_Pos) // 0x08000000 */ +#define HPTXSTS_PTXQTOP_4 (0x10UL << HPTXSTS_PTXQTOP_Pos) // 0x10000000 */ +#define HPTXSTS_PTXQTOP_5 (0x20UL << HPTXSTS_PTXQTOP_Pos) // 0x20000000 */ +#define HPTXSTS_PTXQTOP_6 (0x40UL << HPTXSTS_PTXQTOP_Pos) // 0x40000000 */ +#define HPTXSTS_PTXQTOP_7 (0x80UL << HPTXSTS_PTXQTOP_Pos) // 0x80000000 */ + +/******************** Bit definition for HAINT register ********************/ +#define HAINT_HAINT_Pos (0U) +#define HAINT_HAINT_Msk (0xFFFFUL << HAINT_HAINT_Pos) // 0x0000FFFF */ +#define HAINT_HAINT HAINT_HAINT_Msk // Channel interrupts */ + +/******************** Bit definition for DOEPMSK register ********************/ +#define DOEPMSK_XFRCM_Pos (0U) +#define DOEPMSK_XFRCM_Msk (0x1UL << DOEPMSK_XFRCM_Pos) // 0x00000001 */ +#define DOEPMSK_XFRCM DOEPMSK_XFRCM_Msk // Transfer completed interrupt mask */ +#define DOEPMSK_EPDM_Pos (1U) +#define DOEPMSK_EPDM_Msk (0x1UL << DOEPMSK_EPDM_Pos) // 0x00000002 */ +#define DOEPMSK_EPDM DOEPMSK_EPDM_Msk // Endpoint disabled interrupt mask */ +#define DOEPMSK_AHBERRM_Pos (2U) +#define DOEPMSK_AHBERRM_Msk (0x1UL << DOEPMSK_AHBERRM_Pos) // 0x00000004 */ +#define DOEPMSK_AHBERRM DOEPMSK_AHBERRM_Msk // OUT transaction AHB Error interrupt mask */ +#define DOEPMSK_STUPM_Pos (3U) +#define DOEPMSK_STUPM_Msk (0x1UL << DOEPMSK_STUPM_Pos) // 0x00000008 */ +#define DOEPMSK_STUPM DOEPMSK_STUPM_Msk // SETUP phase done mask */ +#define DOEPMSK_OTEPDM_Pos (4U) +#define DOEPMSK_OTEPDM_Msk (0x1UL << DOEPMSK_OTEPDM_Pos) // 0x00000010 */ +#define DOEPMSK_OTEPDM DOEPMSK_OTEPDM_Msk // OUT token received when endpoint disabled mask */ +#define DOEPMSK_OTEPSPRM_Pos (5U) +#define DOEPMSK_OTEPSPRM_Msk (0x1UL << DOEPMSK_OTEPSPRM_Pos) // 0x00000020 */ +#define DOEPMSK_OTEPSPRM DOEPMSK_OTEPSPRM_Msk // Status Phase Received mask */ +#define DOEPMSK_B2BSTUP_Pos (6U) +#define DOEPMSK_B2BSTUP_Msk (0x1UL << DOEPMSK_B2BSTUP_Pos) // 0x00000040 */ +#define DOEPMSK_B2BSTUP DOEPMSK_B2BSTUP_Msk // Back-to-back SETUP packets received mask */ +#define DOEPMSK_OPEM_Pos (8U) +#define DOEPMSK_OPEM_Msk (0x1UL << DOEPMSK_OPEM_Pos) // 0x00000100 */ +#define DOEPMSK_OPEM DOEPMSK_OPEM_Msk // OUT packet error mask */ +#define DOEPMSK_BOIM_Pos (9U) +#define DOEPMSK_BOIM_Msk (0x1UL << DOEPMSK_BOIM_Pos) // 0x00000200 */ +#define DOEPMSK_BOIM DOEPMSK_BOIM_Msk // BNA interrupt mask */ +#define DOEPMSK_BERRM_Pos (12U) +#define DOEPMSK_BERRM_Msk (0x1UL << DOEPMSK_BERRM_Pos) // 0x00001000 */ +#define DOEPMSK_BERRM DOEPMSK_BERRM_Msk // Babble error interrupt mask */ +#define DOEPMSK_NAKM_Pos (13U) +#define DOEPMSK_NAKM_Msk (0x1UL << DOEPMSK_NAKM_Pos) // 0x00002000 */ +#define DOEPMSK_NAKM DOEPMSK_NAKM_Msk // OUT Packet NAK interrupt mask */ +#define DOEPMSK_NYETM_Pos (14U) +#define DOEPMSK_NYETM_Msk (0x1UL << DOEPMSK_NYETM_Pos) // 0x00004000 */ +#define DOEPMSK_NYETM DOEPMSK_NYETM_Msk // NYET interrupt mask */ + +/******************** Bit definition for GINTSTS register ********************/ +#define GINTSTS_CMOD_Pos (0U) +#define GINTSTS_CMOD_Msk (0x1UL << GINTSTS_CMOD_Pos) // 0x00000001 */ +#define GINTSTS_CMOD GINTSTS_CMOD_Msk // Current mode of operation */ +#define GINTSTS_MMIS_Pos (1U) +#define GINTSTS_MMIS_Msk (0x1UL << GINTSTS_MMIS_Pos) // 0x00000002 */ +#define GINTSTS_MMIS GINTSTS_MMIS_Msk // Mode mismatch interrupt */ +#define GINTSTS_OTGINT_Pos (2U) +#define GINTSTS_OTGINT_Msk (0x1UL << GINTSTS_OTGINT_Pos) // 0x00000004 */ +#define GINTSTS_OTGINT GINTSTS_OTGINT_Msk // OTG interrupt */ +#define GINTSTS_SOF_Pos (3U) +#define GINTSTS_SOF_Msk (0x1UL << GINTSTS_SOF_Pos) // 0x00000008 */ +#define GINTSTS_SOF GINTSTS_SOF_Msk // Start of frame */ +#define GINTSTS_RXFLVL_Pos (4U) +#define GINTSTS_RXFLVL_Msk (0x1UL << GINTSTS_RXFLVL_Pos) // 0x00000010 */ +#define GINTSTS_RXFLVL GINTSTS_RXFLVL_Msk // RxFIFO nonempty */ +#define GINTSTS_NPTXFE_Pos (5U) +#define GINTSTS_NPTXFE_Msk (0x1UL << GINTSTS_NPTXFE_Pos) // 0x00000020 */ +#define GINTSTS_NPTXFE GINTSTS_NPTXFE_Msk // Nonperiodic TxFIFO empty */ +#define GINTSTS_GINAKEFF_Pos (6U) +#define GINTSTS_GINAKEFF_Msk (0x1UL << GINTSTS_GINAKEFF_Pos) // 0x00000040 */ +#define GINTSTS_GINAKEFF GINTSTS_GINAKEFF_Msk // Global IN nonperiodic NAK effective */ +#define GINTSTS_BOUTNAKEFF_Pos (7U) +#define GINTSTS_BOUTNAKEFF_Msk (0x1UL << GINTSTS_BOUTNAKEFF_Pos) // 0x00000080 */ +#define GINTSTS_BOUTNAKEFF GINTSTS_BOUTNAKEFF_Msk // Global OUT NAK effective */ +#define GINTSTS_ESUSP_Pos (10U) +#define GINTSTS_ESUSP_Msk (0x1UL << GINTSTS_ESUSP_Pos) // 0x00000400 */ +#define GINTSTS_ESUSP GINTSTS_ESUSP_Msk // Early suspend */ +#define GINTSTS_USBSUSP_Pos (11U) +#define GINTSTS_USBSUSP_Msk (0x1UL << GINTSTS_USBSUSP_Pos) // 0x00000800 */ +#define GINTSTS_USBSUSP GINTSTS_USBSUSP_Msk // USB suspend */ +#define GINTSTS_USBRST_Pos (12U) +#define GINTSTS_USBRST_Msk (0x1UL << GINTSTS_USBRST_Pos) // 0x00001000 */ +#define GINTSTS_USBRST GINTSTS_USBRST_Msk // USB reset */ +#define GINTSTS_ENUMDNE_Pos (13U) +#define GINTSTS_ENUMDNE_Msk (0x1UL << GINTSTS_ENUMDNE_Pos) // 0x00002000 */ +#define GINTSTS_ENUMDNE GINTSTS_ENUMDNE_Msk // Enumeration done */ +#define GINTSTS_ISOODRP_Pos (14U) +#define GINTSTS_ISOODRP_Msk (0x1UL << GINTSTS_ISOODRP_Pos) // 0x00004000 */ +#define GINTSTS_ISOODRP GINTSTS_ISOODRP_Msk // Isochronous OUT packet dropped interrupt */ +#define GINTSTS_EOPF_Pos (15U) +#define GINTSTS_EOPF_Msk (0x1UL << GINTSTS_EOPF_Pos) // 0x00008000 */ +#define GINTSTS_EOPF GINTSTS_EOPF_Msk // End of periodic frame interrupt */ +#define GINTSTS_IEPINT_Pos (18U) +#define GINTSTS_IEPINT_Msk (0x1UL << GINTSTS_IEPINT_Pos) // 0x00040000 */ +#define GINTSTS_IEPINT GINTSTS_IEPINT_Msk // IN endpoint interrupt */ +#define GINTSTS_OEPINT_Pos (19U) +#define GINTSTS_OEPINT_Msk (0x1UL << GINTSTS_OEPINT_Pos) // 0x00080000 */ +#define GINTSTS_OEPINT GINTSTS_OEPINT_Msk // OUT endpoint interrupt */ +#define GINTSTS_IISOIXFR_Pos (20U) +#define GINTSTS_IISOIXFR_Msk (0x1UL << GINTSTS_IISOIXFR_Pos) // 0x00100000 */ +#define GINTSTS_IISOIXFR GINTSTS_IISOIXFR_Msk // Incomplete isochronous IN transfer */ +#define GINTSTS_PXFR_INCOMPISOOUT_Pos (21U) +#define GINTSTS_PXFR_INCOMPISOOUT_Msk (0x1UL << GINTSTS_PXFR_INCOMPISOOUT_Pos) // 0x00200000 */ +#define GINTSTS_PXFR_INCOMPISOOUT GINTSTS_PXFR_INCOMPISOOUT_Msk // Incomplete periodic transfer */ +#define GINTSTS_DATAFSUSP_Pos (22U) +#define GINTSTS_DATAFSUSP_Msk (0x1UL << GINTSTS_DATAFSUSP_Pos) // 0x00400000 */ +#define GINTSTS_DATAFSUSP GINTSTS_DATAFSUSP_Msk // Data fetch suspended */ +#define GINTSTS_RSTDET_Pos (23U) +#define GINTSTS_RSTDET_Msk (0x1UL << GINTSTS_RSTDET_Pos) // 0x00800000 */ +#define GINTSTS_RSTDET GINTSTS_RSTDET_Msk // Reset detected interrupt */ +#define GINTSTS_HPRTINT_Pos (24U) +#define GINTSTS_HPRTINT_Msk (0x1UL << GINTSTS_HPRTINT_Pos) // 0x01000000 */ +#define GINTSTS_HPRTINT GINTSTS_HPRTINT_Msk // Host port interrupt */ +#define GINTSTS_HCINT_Pos (25U) +#define GINTSTS_HCINT_Msk (0x1UL << GINTSTS_HCINT_Pos) // 0x02000000 */ +#define GINTSTS_HCINT GINTSTS_HCINT_Msk // Host channels interrupt */ +#define GINTSTS_PTXFE_Pos (26U) +#define GINTSTS_PTXFE_Msk (0x1UL << GINTSTS_PTXFE_Pos) // 0x04000000 */ +#define GINTSTS_PTXFE GINTSTS_PTXFE_Msk // Periodic TxFIFO empty */ +#define GINTSTS_LPMINT_Pos (27U) +#define GINTSTS_LPMINT_Msk (0x1UL << GINTSTS_LPMINT_Pos) // 0x08000000 */ +#define GINTSTS_LPMINT GINTSTS_LPMINT_Msk // LPM interrupt */ +#define GINTSTS_CIDSCHG_Pos (28U) +#define GINTSTS_CIDSCHG_Msk (0x1UL << GINTSTS_CIDSCHG_Pos) // 0x10000000 */ +#define GINTSTS_CIDSCHG GINTSTS_CIDSCHG_Msk // Connector ID status change */ +#define GINTSTS_DISCINT_Pos (29U) +#define GINTSTS_DISCINT_Msk (0x1UL << GINTSTS_DISCINT_Pos) // 0x20000000 */ +#define GINTSTS_DISCINT GINTSTS_DISCINT_Msk // Disconnect detected interrupt */ +#define GINTSTS_SRQINT_Pos (30U) +#define GINTSTS_SRQINT_Msk (0x1UL << GINTSTS_SRQINT_Pos) // 0x40000000 */ +#define GINTSTS_SRQINT GINTSTS_SRQINT_Msk // Session request/new session detected interrupt */ +#define GINTSTS_WKUINT_Pos (31U) +#define GINTSTS_WKUINT_Msk (0x1UL << GINTSTS_WKUINT_Pos) // 0x80000000 */ +#define GINTSTS_WKUINT GINTSTS_WKUINT_Msk // Resume/remote wakeup detected interrupt */ + +/******************** Bit definition for GINTMSK register ********************/ +#define GINTMSK_MMISM_Pos (1U) +#define GINTMSK_MMISM_Msk (0x1UL << GINTMSK_MMISM_Pos) // 0x00000002 */ +#define GINTMSK_MMISM GINTMSK_MMISM_Msk // Mode mismatch interrupt mask */ +#define GINTMSK_OTGINT_Pos (2U) +#define GINTMSK_OTGINT_Msk (0x1UL << GINTMSK_OTGINT_Pos) // 0x00000004 */ +#define GINTMSK_OTGINT GINTMSK_OTGINT_Msk // OTG interrupt mask */ +#define GINTMSK_SOFM_Pos (3U) +#define GINTMSK_SOFM_Msk (0x1UL << GINTMSK_SOFM_Pos) // 0x00000008 */ +#define GINTMSK_SOFM GINTMSK_SOFM_Msk // Start of frame mask */ +#define GINTMSK_RXFLVLM_Pos (4U) +#define GINTMSK_RXFLVLM_Msk (0x1UL << GINTMSK_RXFLVLM_Pos) // 0x00000010 */ +#define GINTMSK_RXFLVLM GINTMSK_RXFLVLM_Msk // Receive FIFO nonempty mask */ +#define GINTMSK_NPTXFEM_Pos (5U) +#define GINTMSK_NPTXFEM_Msk (0x1UL << GINTMSK_NPTXFEM_Pos) // 0x00000020 */ +#define GINTMSK_NPTXFEM GINTMSK_NPTXFEM_Msk // Nonperiodic TxFIFO empty mask */ +#define GINTMSK_GINAKEFFM_Pos (6U) +#define GINTMSK_GINAKEFFM_Msk (0x1UL << GINTMSK_GINAKEFFM_Pos) // 0x00000040 */ +#define GINTMSK_GINAKEFFM GINTMSK_GINAKEFFM_Msk // Global nonperiodic IN NAK effective mask */ +#define GINTMSK_GONAKEFFM_Pos (7U) +#define GINTMSK_GONAKEFFM_Msk (0x1UL << GINTMSK_GONAKEFFM_Pos) // 0x00000080 */ +#define GINTMSK_GONAKEFFM GINTMSK_GONAKEFFM_Msk // Global OUT NAK effective mask */ +#define GINTMSK_ESUSPM_Pos (10U) +#define GINTMSK_ESUSPM_Msk (0x1UL << GINTMSK_ESUSPM_Pos) // 0x00000400 */ +#define GINTMSK_ESUSPM GINTMSK_ESUSPM_Msk // Early suspend mask */ +#define GINTMSK_USBSUSPM_Pos (11U) +#define GINTMSK_USBSUSPM_Msk (0x1UL << GINTMSK_USBSUSPM_Pos) // 0x00000800 */ +#define GINTMSK_USBSUSPM GINTMSK_USBSUSPM_Msk // USB suspend mask */ +#define GINTMSK_USBRST_Pos (12U) +#define GINTMSK_USBRST_Msk (0x1UL << GINTMSK_USBRST_Pos) // 0x00001000 */ +#define GINTMSK_USBRST GINTMSK_USBRST_Msk // USB reset mask */ +#define GINTMSK_ENUMDNEM_Pos (13U) +#define GINTMSK_ENUMDNEM_Msk (0x1UL << GINTMSK_ENUMDNEM_Pos) // 0x00002000 */ +#define GINTMSK_ENUMDNEM GINTMSK_ENUMDNEM_Msk // Enumeration done mask */ +#define GINTMSK_ISOODRPM_Pos (14U) +#define GINTMSK_ISOODRPM_Msk (0x1UL << GINTMSK_ISOODRPM_Pos) // 0x00004000 */ +#define GINTMSK_ISOODRPM GINTMSK_ISOODRPM_Msk // Isochronous OUT packet dropped interrupt mask */ +#define GINTMSK_EOPFM_Pos (15U) +#define GINTMSK_EOPFM_Msk (0x1UL << GINTMSK_EOPFM_Pos) // 0x00008000 */ +#define GINTMSK_EOPFM GINTMSK_EOPFM_Msk // End of periodic frame interrupt mask */ +#define GINTMSK_EPMISM_Pos (17U) +#define GINTMSK_EPMISM_Msk (0x1UL << GINTMSK_EPMISM_Pos) // 0x00020000 */ +#define GINTMSK_EPMISM GINTMSK_EPMISM_Msk // Endpoint mismatch interrupt mask */ +#define GINTMSK_IEPINT_Pos (18U) +#define GINTMSK_IEPINT_Msk (0x1UL << GINTMSK_IEPINT_Pos) // 0x00040000 */ +#define GINTMSK_IEPINT GINTMSK_IEPINT_Msk // IN endpoints interrupt mask */ +#define GINTMSK_OEPINT_Pos (19U) +#define GINTMSK_OEPINT_Msk (0x1UL << GINTMSK_OEPINT_Pos) // 0x00080000 */ +#define GINTMSK_OEPINT GINTMSK_OEPINT_Msk // OUT endpoints interrupt mask */ +#define GINTMSK_IISOIXFRM_Pos (20U) +#define GINTMSK_IISOIXFRM_Msk (0x1UL << GINTMSK_IISOIXFRM_Pos) // 0x00100000 */ +#define GINTMSK_IISOIXFRM GINTMSK_IISOIXFRM_Msk // Incomplete isochronous IN transfer mask */ +#define GINTMSK_PXFRM_IISOOXFRM_Pos (21U) +#define GINTMSK_PXFRM_IISOOXFRM_Msk (0x1UL << GINTMSK_PXFRM_IISOOXFRM_Pos) // 0x00200000 */ +#define GINTMSK_PXFRM_IISOOXFRM GINTMSK_PXFRM_IISOOXFRM_Msk // Incomplete periodic transfer mask */ +#define GINTMSK_FSUSPM_Pos (22U) +#define GINTMSK_FSUSPM_Msk (0x1UL << GINTMSK_FSUSPM_Pos) // 0x00400000 */ +#define GINTMSK_FSUSPM GINTMSK_FSUSPM_Msk // Data fetch suspended mask */ +#define GINTMSK_RSTDEM_Pos (23U) +#define GINTMSK_RSTDEM_Msk (0x1UL << GINTMSK_RSTDEM_Pos) // 0x00800000 */ +#define GINTMSK_RSTDEM GINTMSK_RSTDEM_Msk // Reset detected interrupt mask */ +#define GINTMSK_PRTIM_Pos (24U) +#define GINTMSK_PRTIM_Msk (0x1UL << GINTMSK_PRTIM_Pos) // 0x01000000 */ +#define GINTMSK_PRTIM GINTMSK_PRTIM_Msk // Host port interrupt mask */ +#define GINTMSK_HCIM_Pos (25U) +#define GINTMSK_HCIM_Msk (0x1UL << GINTMSK_HCIM_Pos) // 0x02000000 */ +#define GINTMSK_HCIM GINTMSK_HCIM_Msk // Host channels interrupt mask */ +#define GINTMSK_PTXFEM_Pos (26U) +#define GINTMSK_PTXFEM_Msk (0x1UL << GINTMSK_PTXFEM_Pos) // 0x04000000 */ +#define GINTMSK_PTXFEM GINTMSK_PTXFEM_Msk // Periodic TxFIFO empty mask */ +#define GINTMSK_LPMINTM_Pos (27U) +#define GINTMSK_LPMINTM_Msk (0x1UL << GINTMSK_LPMINTM_Pos) // 0x08000000 */ +#define GINTMSK_LPMINTM GINTMSK_LPMINTM_Msk // LPM interrupt Mask */ +#define GINTMSK_CIDSCHGM_Pos (28U) +#define GINTMSK_CIDSCHGM_Msk (0x1UL << GINTMSK_CIDSCHGM_Pos) // 0x10000000 */ +#define GINTMSK_CIDSCHGM GINTMSK_CIDSCHGM_Msk // Connector ID status change mask */ +#define GINTMSK_DISCINT_Pos (29U) +#define GINTMSK_DISCINT_Msk (0x1UL << GINTMSK_DISCINT_Pos) // 0x20000000 */ +#define GINTMSK_DISCINT GINTMSK_DISCINT_Msk // Disconnect detected interrupt mask */ +#define GINTMSK_SRQIM_Pos (30U) +#define GINTMSK_SRQIM_Msk (0x1UL << GINTMSK_SRQIM_Pos) // 0x40000000 */ +#define GINTMSK_SRQIM GINTMSK_SRQIM_Msk // Session request/new session detected interrupt mask */ +#define GINTMSK_WUIM_Pos (31U) +#define GINTMSK_WUIM_Msk (0x1UL << GINTMSK_WUIM_Pos) // 0x80000000 */ +#define GINTMSK_WUIM GINTMSK_WUIM_Msk // Resume/remote wakeup detected interrupt mask */ + +/******************** Bit definition for DAINT register ********************/ +#define DAINT_IEPINT_Pos (0U) +#define DAINT_IEPINT_Msk (0xFFFFUL << DAINT_IEPINT_Pos) // 0x0000FFFF */ +#define DAINT_IEPINT DAINT_IEPINT_Msk // IN endpoint interrupt bits */ +#define DAINT_OEPINT_Pos (16U) +#define DAINT_OEPINT_Msk (0xFFFFUL << DAINT_OEPINT_Pos) // 0xFFFF0000 */ +#define DAINT_OEPINT DAINT_OEPINT_Msk // OUT endpoint interrupt bits */ + +/******************** Bit definition for HAINTMSK register ********************/ +#define HAINTMSK_HAINTM_Pos (0U) +#define HAINTMSK_HAINTM_Msk (0xFFFFUL << HAINTMSK_HAINTM_Pos) // 0x0000FFFF */ +#define HAINTMSK_HAINTM HAINTMSK_HAINTM_Msk // Channel interrupt mask */ + +/******************** Bit definition for GRXSTSP register ********************/ +#define GRXSTSP_EPNUM_Pos (0U) +#define GRXSTSP_EPNUM_Msk (0xFUL << GRXSTSP_EPNUM_Pos) // 0x0000000F */ +#define GRXSTSP_EPNUM GRXSTSP_EPNUM_Msk // IN EP interrupt mask bits */ +#define GRXSTSP_BCNT_Pos (4U) +#define GRXSTSP_BCNT_Msk (0x7FFUL << GRXSTSP_BCNT_Pos) // 0x00007FF0 */ +#define GRXSTSP_BCNT GRXSTSP_BCNT_Msk // OUT EP interrupt mask bits */ +#define GRXSTSP_DPID_Pos (15U) +#define GRXSTSP_DPID_Msk (0x3UL << GRXSTSP_DPID_Pos) // 0x00018000 */ +#define GRXSTSP_DPID GRXSTSP_DPID_Msk // OUT EP interrupt mask bits */ +#define GRXSTSP_PKTSTS_Pos (17U) +#define GRXSTSP_PKTSTS_Msk (0xFUL << GRXSTSP_PKTSTS_Pos) // 0x001E0000 */ +#define GRXSTSP_PKTSTS GRXSTSP_PKTSTS_Msk // OUT EP interrupt mask bits */ + +#define GRXSTS_PKTSTS_GLOBALOUTNAK 1 +#define GRXSTS_PKTSTS_OUTRX 2 +#define GRXSTS_PKTSTS_HCHIN 2 +#define GRXSTS_PKTSTS_OUTDONE 3 +#define GRXSTS_PKTSTS_HCHIN_XFER_COMP 3 +#define GRXSTS_PKTSTS_SETUPDONE 4 +#define GRXSTS_PKTSTS_DATATOGGLEERR 5 +#define GRXSTS_PKTSTS_SETUPRX 6 +#define GRXSTS_PKTSTS_HCHHALTED 7 + + +/******************** Bit definition for DAINTMSK register ********************/ +#define DAINTMSK_IEPM_Pos (0U) +#define DAINTMSK_IEPM_Msk (0xFFFFUL << DAINTMSK_IEPM_Pos) // 0x0000FFFF */ +#define DAINTMSK_IEPM DAINTMSK_IEPM_Msk // IN EP interrupt mask bits */ +#define DAINTMSK_OEPM_Pos (16U) +#define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000 */ +#define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits */ + +#if 0 +/******************** Bit definition for OTG register ********************/ +#define CHNUM_Pos (0U) +#define CHNUM_Msk (0xFUL << CHNUM_Pos) // 0x0000000F */ +#define CHNUM CHNUM_Msk // Channel number */ +#define CHNUM_0 (0x1UL << CHNUM_Pos) // 0x00000001 */ +#define CHNUM_1 (0x2UL << CHNUM_Pos) // 0x00000002 */ +#define CHNUM_2 (0x4UL << CHNUM_Pos) // 0x00000004 */ +#define CHNUM_3 (0x8UL << CHNUM_Pos) // 0x00000008 */ +#define BCNT_Pos (4U) +#define BCNT_Msk (0x7FFUL << BCNT_Pos) // 0x00007FF0 */ +#define BCNT BCNT_Msk // Byte count */ + +#define DPID_Pos (15U) +#define DPID_Msk (0x3UL << DPID_Pos) // 0x00018000 */ +#define DPID DPID_Msk // Data PID */ +#define DPID_0 (0x1UL << DPID_Pos) // 0x00008000 */ +#define DPID_1 (0x2UL << DPID_Pos) // 0x00010000 */ + +#define PKTSTS_Pos (17U) +#define PKTSTS_Msk (0xFUL << PKTSTS_Pos) // 0x001E0000 */ +#define PKTSTS PKTSTS_Msk // Packet status */ +#define PKTSTS_0 (0x1UL << PKTSTS_Pos) // 0x00020000 */ +#define PKTSTS_1 (0x2UL << PKTSTS_Pos) // 0x00040000 */ +#define PKTSTS_2 (0x4UL << PKTSTS_Pos) // 0x00080000 */ +#define PKTSTS_3 (0x8UL << PKTSTS_Pos) // 0x00100000 */ + +#define EPNUM_Pos (0U) +#define EPNUM_Msk (0xFUL << EPNUM_Pos) // 0x0000000F */ +#define EPNUM EPNUM_Msk // Endpoint number */ +#define EPNUM_0 (0x1UL << EPNUM_Pos) // 0x00000001 */ +#define EPNUM_1 (0x2UL << EPNUM_Pos) // 0x00000002 */ +#define EPNUM_2 (0x4UL << EPNUM_Pos) // 0x00000004 */ +#define EPNUM_3 (0x8UL << EPNUM_Pos) // 0x00000008 */ + +#define FRMNUM_Pos (21U) +#define FRMNUM_Msk (0xFUL << FRMNUM_Pos) // 0x01E00000 */ +#define FRMNUM FRMNUM_Msk // Frame number */ +#define FRMNUM_0 (0x1UL << FRMNUM_Pos) // 0x00200000 */ +#define FRMNUM_1 (0x2UL << FRMNUM_Pos) // 0x00400000 */ +#define FRMNUM_2 (0x4UL << FRMNUM_Pos) // 0x00800000 */ +#define FRMNUM_3 (0x8UL << FRMNUM_Pos) // 0x01000000 */ +#endif + +/******************** Bit definition for GRXFSIZ register ********************/ +#define GRXFSIZ_RXFD_Pos (0U) +#define GRXFSIZ_RXFD_Msk (0xFFFFUL << GRXFSIZ_RXFD_Pos) // 0x0000FFFF */ +#define GRXFSIZ_RXFD GRXFSIZ_RXFD_Msk // RxFIFO depth */ + +/******************** Bit definition for DVBUSDIS register ********************/ +#define DVBUSDIS_VBUSDT_Pos (0U) +#define DVBUSDIS_VBUSDT_Msk (0xFFFFUL << DVBUSDIS_VBUSDT_Pos) // 0x0000FFFF */ +#define DVBUSDIS_VBUSDT DVBUSDIS_VBUSDT_Msk // Device VBUS discharge time */ + +/******************** Bit definition for OTG register ********************/ +#define GNPTXFSIZ_NPTXFSA_Pos (0U) +#define GNPTXFSIZ_NPTXFSA_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFSA_Pos) // 0x0000FFFF */ +#define GNPTXFSIZ_NPTXFSA GNPTXFSIZ_NPTXFSA_Msk // Nonperiodic transmit RAM start address */ +#define GNPTXFSIZ_NPTXFD_Pos (16U) +#define GNPTXFSIZ_NPTXFD_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFD_Pos) // 0xFFFF0000 */ +#define GNPTXFSIZ_NPTXFD GNPTXFSIZ_NPTXFD_Msk // Nonperiodic TxFIFO depth */ +#define DIEPTXF0_TX0FSA_Pos (0U) +#define DIEPTXF0_TX0FSA_Msk (0xFFFFUL << DIEPTXF0_TX0FSA_Pos) // 0x0000FFFF */ +#define DIEPTXF0_TX0FSA DIEPTXF0_TX0FSA_Msk // Endpoint 0 transmit RAM start address */ +#define DIEPTXF0_TX0FD_Pos (16U) +#define DIEPTXF0_TX0FD_Msk (0xFFFFUL << DIEPTXF0_TX0FD_Pos) // 0xFFFF0000 */ +#define DIEPTXF0_TX0FD DIEPTXF0_TX0FD_Msk // Endpoint 0 TxFIFO depth */ + +/******************** Bit definition for DVBUSPULSE register ********************/ +#define DVBUSPULSE_DVBUSP_Pos (0U) +#define DVBUSPULSE_DVBUSP_Msk (0xFFFUL << DVBUSPULSE_DVBUSP_Pos) // 0x00000FFF */ +#define DVBUSPULSE_DVBUSP DVBUSPULSE_DVBUSP_Msk // Device VBUS pulsing time */ + +/******************** Bit definition for GNPTXSTS register ********************/ +#define GNPTXSTS_NPTXFSAV_Pos (0U) +#define GNPTXSTS_NPTXFSAV_Msk (0xFFFFUL << GNPTXSTS_NPTXFSAV_Pos) // 0x0000FFFF */ +#define GNPTXSTS_NPTXFSAV GNPTXSTS_NPTXFSAV_Msk // Nonperiodic TxFIFO space available */ + +#define GNPTXSTS_NPTQXSAV_Pos (16U) +#define GNPTXSTS_NPTQXSAV_Msk (0xFFUL << GNPTXSTS_NPTQXSAV_Pos) // 0x00FF0000 */ +#define GNPTXSTS_NPTQXSAV GNPTXSTS_NPTQXSAV_Msk // Nonperiodic transmit request queue space available */ +#define GNPTXSTS_NPTQXSAV_0 (0x01UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00010000 */ +#define GNPTXSTS_NPTQXSAV_1 (0x02UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00020000 */ +#define GNPTXSTS_NPTQXSAV_2 (0x04UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00040000 */ +#define GNPTXSTS_NPTQXSAV_3 (0x08UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00080000 */ +#define GNPTXSTS_NPTQXSAV_4 (0x10UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00100000 */ +#define GNPTXSTS_NPTQXSAV_5 (0x20UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00200000 */ +#define GNPTXSTS_NPTQXSAV_6 (0x40UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00400000 */ +#define GNPTXSTS_NPTQXSAV_7 (0x80UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00800000 */ + +#define GNPTXSTS_NPTXQTOP_Pos (24U) +#define GNPTXSTS_NPTXQTOP_Msk (0x7FUL << GNPTXSTS_NPTXQTOP_Pos) // 0x7F000000 */ +#define GNPTXSTS_NPTXQTOP GNPTXSTS_NPTXQTOP_Msk // Top of the nonperiodic transmit request queue */ +#define GNPTXSTS_NPTXQTOP_0 (0x01UL << GNPTXSTS_NPTXQTOP_Pos) // 0x01000000 */ +#define GNPTXSTS_NPTXQTOP_1 (0x02UL << GNPTXSTS_NPTXQTOP_Pos) // 0x02000000 */ +#define GNPTXSTS_NPTXQTOP_2 (0x04UL << GNPTXSTS_NPTXQTOP_Pos) // 0x04000000 */ +#define GNPTXSTS_NPTXQTOP_3 (0x08UL << GNPTXSTS_NPTXQTOP_Pos) // 0x08000000 */ +#define GNPTXSTS_NPTXQTOP_4 (0x10UL << GNPTXSTS_NPTXQTOP_Pos) // 0x10000000 */ +#define GNPTXSTS_NPTXQTOP_5 (0x20UL << GNPTXSTS_NPTXQTOP_Pos) // 0x20000000 */ +#define GNPTXSTS_NPTXQTOP_6 (0x40UL << GNPTXSTS_NPTXQTOP_Pos) // 0x40000000 */ + +/******************** Bit definition for DTHRCTL register ********************/ +#define DTHRCTL_NONISOTHREN_Pos (0U) +#define DTHRCTL_NONISOTHREN_Msk (0x1UL << DTHRCTL_NONISOTHREN_Pos) // 0x00000001 */ +#define DTHRCTL_NONISOTHREN DTHRCTL_NONISOTHREN_Msk // Nonisochronous IN endpoints threshold enable */ +#define DTHRCTL_ISOTHREN_Pos (1U) +#define DTHRCTL_ISOTHREN_Msk (0x1UL << DTHRCTL_ISOTHREN_Pos) // 0x00000002 */ +#define DTHRCTL_ISOTHREN DTHRCTL_ISOTHREN_Msk // ISO IN endpoint threshold enable */ + +#define DTHRCTL_TXTHRLEN_Pos (2U) +#define DTHRCTL_TXTHRLEN_Msk (0x1FFUL << DTHRCTL_TXTHRLEN_Pos) // 0x000007FC */ +#define DTHRCTL_TXTHRLEN DTHRCTL_TXTHRLEN_Msk // Transmit threshold length */ +#define DTHRCTL_TXTHRLEN_0 (0x001UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000004 */ +#define DTHRCTL_TXTHRLEN_1 (0x002UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000008 */ +#define DTHRCTL_TXTHRLEN_2 (0x004UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000010 */ +#define DTHRCTL_TXTHRLEN_3 (0x008UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000020 */ +#define DTHRCTL_TXTHRLEN_4 (0x010UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000040 */ +#define DTHRCTL_TXTHRLEN_5 (0x020UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000080 */ +#define DTHRCTL_TXTHRLEN_6 (0x040UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000100 */ +#define DTHRCTL_TXTHRLEN_7 (0x080UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000200 */ +#define DTHRCTL_TXTHRLEN_8 (0x100UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000400 */ +#define DTHRCTL_RXTHREN_Pos (16U) +#define DTHRCTL_RXTHREN_Msk (0x1UL << DTHRCTL_RXTHREN_Pos) // 0x00010000 */ +#define DTHRCTL_RXTHREN DTHRCTL_RXTHREN_Msk // Receive threshold enable */ + +#define DTHRCTL_RXTHRLEN_Pos (17U) +#define DTHRCTL_RXTHRLEN_Msk (0x1FFUL << DTHRCTL_RXTHRLEN_Pos) // 0x03FE0000 */ +#define DTHRCTL_RXTHRLEN DTHRCTL_RXTHRLEN_Msk // Receive threshold length */ +#define DTHRCTL_RXTHRLEN_0 (0x001UL << DTHRCTL_RXTHRLEN_Pos) // 0x00020000 */ +#define DTHRCTL_RXTHRLEN_1 (0x002UL << DTHRCTL_RXTHRLEN_Pos) // 0x00040000 */ +#define DTHRCTL_RXTHRLEN_2 (0x004UL << DTHRCTL_RXTHRLEN_Pos) // 0x00080000 */ +#define DTHRCTL_RXTHRLEN_3 (0x008UL << DTHRCTL_RXTHRLEN_Pos) // 0x00100000 */ +#define DTHRCTL_RXTHRLEN_4 (0x010UL << DTHRCTL_RXTHRLEN_Pos) // 0x00200000 */ +#define DTHRCTL_RXTHRLEN_5 (0x020UL << DTHRCTL_RXTHRLEN_Pos) // 0x00400000 */ +#define DTHRCTL_RXTHRLEN_6 (0x040UL << DTHRCTL_RXTHRLEN_Pos) // 0x00800000 */ +#define DTHRCTL_RXTHRLEN_7 (0x080UL << DTHRCTL_RXTHRLEN_Pos) // 0x01000000 */ +#define DTHRCTL_RXTHRLEN_8 (0x100UL << DTHRCTL_RXTHRLEN_Pos) // 0x02000000 */ +#define DTHRCTL_ARPEN_Pos (27U) +#define DTHRCTL_ARPEN_Msk (0x1UL << DTHRCTL_ARPEN_Pos) // 0x08000000 */ +#define DTHRCTL_ARPEN DTHRCTL_ARPEN_Msk // Arbiter parking enable */ + +/******************** Bit definition for DIEPEMPMSK register ********************/ +#define DIEPEMPMSK_INEPTXFEM_Pos (0U) +#define DIEPEMPMSK_INEPTXFEM_Msk (0xFFFFUL << DIEPEMPMSK_INEPTXFEM_Pos) // 0x0000FFFF */ +#define DIEPEMPMSK_INEPTXFEM DIEPEMPMSK_INEPTXFEM_Msk // IN EP Tx FIFO empty interrupt mask bits */ + +/******************** Bit definition for DEACHINT register ********************/ +#define DEACHINT_IEP1INT_Pos (1U) +#define DEACHINT_IEP1INT_Msk (0x1UL << DEACHINT_IEP1INT_Pos) // 0x00000002 */ +#define DEACHINT_IEP1INT DEACHINT_IEP1INT_Msk // IN endpoint 1interrupt bit */ +#define DEACHINT_OEP1INT_Pos (17U) +#define DEACHINT_OEP1INT_Msk (0x1UL << DEACHINT_OEP1INT_Pos) // 0x00020000 */ +#define DEACHINT_OEP1INT DEACHINT_OEP1INT_Msk // OUT endpoint 1 interrupt bit */ + +/******************** Bit definition for GCCFG register ********************/ +#define STM32_GCCFG_DCDET_Pos (0U) +#define STM32_GCCFG_DCDET_Msk (0x1UL << STM32_GCCFG_DCDET_Pos) // 0x00000001 */ +#define STM32_GCCFG_DCDET STM32_GCCFG_DCDET_Msk // Data contact detection (DCD) status */ +#define STM32_GCCFG_PDET_Pos (1U) +#define STM32_GCCFG_PDET_Msk (0x1UL << STM32_GCCFG_PDET_Pos) // 0x00000002 */ +#define STM32_GCCFG_PDET STM32_GCCFG_PDET_Msk // Primary detection (PD) status */ +#define STM32_GCCFG_SDET_Pos (2U) +#define STM32_GCCFG_SDET_Msk (0x1UL << STM32_GCCFG_SDET_Pos) // 0x00000004 */ +#define STM32_GCCFG_SDET STM32_GCCFG_SDET_Msk // Secondary detection (SD) status */ +#define STM32_GCCFG_PS2DET_Pos (3U) +#define STM32_GCCFG_PS2DET_Msk (0x1UL << STM32_GCCFG_PS2DET_Pos) // 0x00000008 */ +#define STM32_GCCFG_PS2DET STM32_GCCFG_PS2DET_Msk // DM pull-up detection status */ +#define STM32_GCCFG_PWRDWN_Pos (16U) +#define STM32_GCCFG_PWRDWN_Msk (0x1UL << STM32_GCCFG_PWRDWN_Pos) // 0x00010000 */ +#define STM32_GCCFG_PWRDWN STM32_GCCFG_PWRDWN_Msk // Power down */ +#define STM32_GCCFG_BCDEN_Pos (17U) +#define STM32_GCCFG_BCDEN_Msk (0x1UL << STM32_GCCFG_BCDEN_Pos) // 0x00020000 */ +#define STM32_GCCFG_BCDEN STM32_GCCFG_BCDEN_Msk // Battery charging detector (BCD) enable */ +#define STM32_GCCFG_DCDEN_Pos (18U) +#define STM32_GCCFG_DCDEN_Msk (0x1UL << STM32_GCCFG_DCDEN_Pos) // 0x00040000 */ +#define STM32_GCCFG_DCDEN STM32_GCCFG_DCDEN_Msk // Data contact detection (DCD) mode enable*/ +#define STM32_GCCFG_PDEN_Pos (19U) +#define STM32_GCCFG_PDEN_Msk (0x1UL << STM32_GCCFG_PDEN_Pos) // 0x00080000 */ +#define STM32_GCCFG_PDEN STM32_GCCFG_PDEN_Msk // Primary detection (PD) mode enable*/ +#define STM32_GCCFG_SDEN_Pos (20U) +#define STM32_GCCFG_SDEN_Msk (0x1UL << STM32_GCCFG_SDEN_Pos) // 0x00100000 */ +#define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (SD) mode enable */ +#define STM32_GCCFG_VBDEN_Pos (21U) +#define STM32_GCCFG_VBDEN_Msk (0x1UL << STM32_GCCFG_VBDEN_Pos) // 0x00200000 */ +#define STM32_GCCFG_VBDEN STM32_GCCFG_VBDEN_Msk // VBUS mode enable */ +#define STM32_GCCFG_OTGIDEN_Pos (22U) +#define STM32_GCCFG_OTGIDEN_Msk (0x1UL << STM32_GCCFG_OTGIDEN_Pos) // 0x00400000 */ +#define STM32_GCCFG_OTGIDEN STM32_GCCFG_OTGIDEN_Msk // OTG Id enable */ +#define STM32_GCCFG_PHYHSEN_Pos (23U) +#define STM32_GCCFG_PHYHSEN_Msk (0x1UL << STM32_GCCFG_PHYHSEN_Pos) // 0x00800000 */ +#define STM32_GCCFG_PHYHSEN STM32_GCCFG_PHYHSEN_Msk // HS PHY enable */ + +/******************** Bit definition for DEACHINTMSK register ********************/ +#define DEACHINTMSK_IEP1INTM_Pos (1U) +#define DEACHINTMSK_IEP1INTM_Msk (0x1UL << DEACHINTMSK_IEP1INTM_Pos) // 0x00000002 */ +#define DEACHINTMSK_IEP1INTM DEACHINTMSK_IEP1INTM_Msk // IN Endpoint 1 interrupt mask bit */ +#define DEACHINTMSK_OEP1INTM_Pos (17U) +#define DEACHINTMSK_OEP1INTM_Msk (0x1UL << DEACHINTMSK_OEP1INTM_Pos) // 0x00020000 */ +#define DEACHINTMSK_OEP1INTM DEACHINTMSK_OEP1INTM_Msk // OUT Endpoint 1 interrupt mask bit */ + +/******************** Bit definition for CID register ********************/ +#define CID_PRODUCT_ID_Pos (0U) +#define CID_PRODUCT_ID_Msk (0xFFFFFFFFUL << CID_PRODUCT_ID_Pos) // 0xFFFFFFFF */ +#define CID_PRODUCT_ID CID_PRODUCT_ID_Msk // Product ID field */ + +/******************** Bit definition for GLPMCFG register ********************/ +#define GLPMCFG_LPMEN_Pos (0U) +#define GLPMCFG_LPMEN_Msk (0x1UL << GLPMCFG_LPMEN_Pos) // 0x00000001 */ +#define GLPMCFG_LPMEN GLPMCFG_LPMEN_Msk // LPM support enable */ +#define GLPMCFG_LPMACK_Pos (1U) +#define GLPMCFG_LPMACK_Msk (0x1UL << GLPMCFG_LPMACK_Pos) // 0x00000002 */ +#define GLPMCFG_LPMACK GLPMCFG_LPMACK_Msk // LPM Token acknowledge enable */ +#define GLPMCFG_BESL_Pos (2U) +#define GLPMCFG_BESL_Msk (0xFUL << GLPMCFG_BESL_Pos) // 0x0000003C */ +#define GLPMCFG_BESL GLPMCFG_BESL_Msk // BESL value received with last ACKed LPM Token */ +#define GLPMCFG_REMWAKE_Pos (6U) +#define GLPMCFG_REMWAKE_Msk (0x1UL << GLPMCFG_REMWAKE_Pos) // 0x00000040 */ +#define GLPMCFG_REMWAKE GLPMCFG_REMWAKE_Msk // bRemoteWake value received with last ACKed LPM Token */ +#define GLPMCFG_L1SSEN_Pos (7U) +#define GLPMCFG_L1SSEN_Msk (0x1UL << GLPMCFG_L1SSEN_Pos) // 0x00000080 */ +#define GLPMCFG_L1SSEN GLPMCFG_L1SSEN_Msk // L1 shallow sleep enable */ +#define GLPMCFG_BESLTHRS_Pos (8U) +#define GLPMCFG_BESLTHRS_Msk (0xFUL << GLPMCFG_BESLTHRS_Pos) // 0x00000F00 */ +#define GLPMCFG_BESLTHRS GLPMCFG_BESLTHRS_Msk // BESL threshold */ +#define GLPMCFG_L1DSEN_Pos (12U) +#define GLPMCFG_L1DSEN_Msk (0x1UL << GLPMCFG_L1DSEN_Pos) // 0x00001000 */ +#define GLPMCFG_L1DSEN GLPMCFG_L1DSEN_Msk // L1 deep sleep enable */ +#define GLPMCFG_LPMRSP_Pos (13U) +#define GLPMCFG_LPMRSP_Msk (0x3UL << GLPMCFG_LPMRSP_Pos) // 0x00006000 */ +#define GLPMCFG_LPMRSP GLPMCFG_LPMRSP_Msk // LPM response */ +#define GLPMCFG_SLPSTS_Pos (15U) +#define GLPMCFG_SLPSTS_Msk (0x1UL << GLPMCFG_SLPSTS_Pos) // 0x00008000 */ +#define GLPMCFG_SLPSTS GLPMCFG_SLPSTS_Msk // Port sleep status */ +#define GLPMCFG_L1RSMOK_Pos (16U) +#define GLPMCFG_L1RSMOK_Msk (0x1UL << GLPMCFG_L1RSMOK_Pos) // 0x00010000 */ +#define GLPMCFG_L1RSMOK GLPMCFG_L1RSMOK_Msk // Sleep State Resume OK */ +#define GLPMCFG_LPMCHIDX_Pos (17U) +#define GLPMCFG_LPMCHIDX_Msk (0xFUL << GLPMCFG_LPMCHIDX_Pos) // 0x001E0000 */ +#define GLPMCFG_LPMCHIDX GLPMCFG_LPMCHIDX_Msk // LPM Channel Index */ +#define GLPMCFG_LPMRCNT_Pos (21U) +#define GLPMCFG_LPMRCNT_Msk (0x7UL << GLPMCFG_LPMRCNT_Pos) // 0x00E00000 */ +#define GLPMCFG_LPMRCNT GLPMCFG_LPMRCNT_Msk // LPM retry count */ +#define GLPMCFG_SNDLPM_Pos (24U) +#define GLPMCFG_SNDLPM_Msk (0x1UL << GLPMCFG_SNDLPM_Pos) // 0x01000000 */ +#define GLPMCFG_SNDLPM GLPMCFG_SNDLPM_Msk // Send LPM transaction */ +#define GLPMCFG_LPMRCNTSTS_Pos (25U) +#define GLPMCFG_LPMRCNTSTS_Msk (0x7UL << GLPMCFG_LPMRCNTSTS_Pos) // 0x0E000000 */ +#define GLPMCFG_LPMRCNTSTS GLPMCFG_LPMRCNTSTS_Msk // LPM retry count status */ +#define GLPMCFG_ENBESL_Pos (28U) +#define GLPMCFG_ENBESL_Msk (0x1UL << GLPMCFG_ENBESL_Pos) // 0x10000000 */ +#define GLPMCFG_ENBESL GLPMCFG_ENBESL_Msk // Enable best effort service latency */ + +/******************** Bit definition for DIEPEACHMSK1 register ********************/ +#define DIEPEACHMSK1_XFRCM_Pos (0U) +#define DIEPEACHMSK1_XFRCM_Msk (0x1UL << DIEPEACHMSK1_XFRCM_Pos) // 0x00000001 */ +#define DIEPEACHMSK1_XFRCM DIEPEACHMSK1_XFRCM_Msk // Transfer completed interrupt mask */ +#define DIEPEACHMSK1_EPDM_Pos (1U) +#define DIEPEACHMSK1_EPDM_Msk (0x1UL << DIEPEACHMSK1_EPDM_Pos) // 0x00000002 */ +#define DIEPEACHMSK1_EPDM DIEPEACHMSK1_EPDM_Msk // Endpoint disabled interrupt mask */ +#define DIEPEACHMSK1_TOM_Pos (3U) +#define DIEPEACHMSK1_TOM_Msk (0x1UL << DIEPEACHMSK1_TOM_Pos) // 0x00000008 */ +#define DIEPEACHMSK1_TOM DIEPEACHMSK1_TOM_Msk // Timeout condition mask (nonisochronous endpoints) */ +#define DIEPEACHMSK1_ITTXFEMSK_Pos (4U) +#define DIEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << DIEPEACHMSK1_ITTXFEMSK_Pos) // 0x00000010 */ +#define DIEPEACHMSK1_ITTXFEMSK DIEPEACHMSK1_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask */ +#define DIEPEACHMSK1_INEPNMM_Pos (5U) +#define DIEPEACHMSK1_INEPNMM_Msk (0x1UL << DIEPEACHMSK1_INEPNMM_Pos) // 0x00000020 */ +#define DIEPEACHMSK1_INEPNMM DIEPEACHMSK1_INEPNMM_Msk // IN token received with EP mismatch mask */ +#define DIEPEACHMSK1_INEPNEM_Pos (6U) +#define DIEPEACHMSK1_INEPNEM_Msk (0x1UL << DIEPEACHMSK1_INEPNEM_Pos) // 0x00000040 */ +#define DIEPEACHMSK1_INEPNEM DIEPEACHMSK1_INEPNEM_Msk // IN endpoint NAK effective mask */ +#define DIEPEACHMSK1_TXFURM_Pos (8U) +#define DIEPEACHMSK1_TXFURM_Msk (0x1UL << DIEPEACHMSK1_TXFURM_Pos) // 0x00000100 */ +#define DIEPEACHMSK1_TXFURM DIEPEACHMSK1_TXFURM_Msk // FIFO underrun mask */ +#define DIEPEACHMSK1_BIM_Pos (9U) +#define DIEPEACHMSK1_BIM_Msk (0x1UL << DIEPEACHMSK1_BIM_Pos) // 0x00000200 */ +#define DIEPEACHMSK1_BIM DIEPEACHMSK1_BIM_Msk // BNA interrupt mask */ +#define DIEPEACHMSK1_NAKM_Pos (13U) +#define DIEPEACHMSK1_NAKM_Msk (0x1UL << DIEPEACHMSK1_NAKM_Pos) // 0x00002000 */ +#define DIEPEACHMSK1_NAKM DIEPEACHMSK1_NAKM_Msk // NAK interrupt mask */ + +/******************** Bit definition for HPRT register ********************/ +#define HPRT_PCSTS_Pos (0U) +#define HPRT_PCSTS_Msk (0x1UL << HPRT_PCSTS_Pos) // 0x00000001 */ +#define HPRT_PCSTS HPRT_PCSTS_Msk // Port connect status */ +#define HPRT_PCDET_Pos (1U) +#define HPRT_PCDET_Msk (0x1UL << HPRT_PCDET_Pos) // 0x00000002 */ +#define HPRT_PCDET HPRT_PCDET_Msk // Port connect detected */ +#define HPRT_PENA_Pos (2U) +#define HPRT_PENA_Msk (0x1UL << HPRT_PENA_Pos) // 0x00000004 */ +#define HPRT_PENA HPRT_PENA_Msk // Port enable */ +#define HPRT_PENCHNG_Pos (3U) +#define HPRT_PENCHNG_Msk (0x1UL << HPRT_PENCHNG_Pos) // 0x00000008 */ +#define HPRT_PENCHNG HPRT_PENCHNG_Msk // Port enable/disable change */ +#define HPRT_POCA_Pos (4U) +#define HPRT_POCA_Msk (0x1UL << HPRT_POCA_Pos) // 0x00000010 */ +#define HPRT_POCA HPRT_POCA_Msk // Port overcurrent active */ +#define HPRT_POCCHNG_Pos (5U) +#define HPRT_POCCHNG_Msk (0x1UL << HPRT_POCCHNG_Pos) // 0x00000020 */ +#define HPRT_POCCHNG HPRT_POCCHNG_Msk // Port overcurrent change */ +#define HPRT_PRES_Pos (6U) +#define HPRT_PRES_Msk (0x1UL << HPRT_PRES_Pos) // 0x00000040 */ +#define HPRT_PRES HPRT_PRES_Msk // Port resume */ +#define HPRT_PSUSP_Pos (7U) +#define HPRT_PSUSP_Msk (0x1UL << HPRT_PSUSP_Pos) // 0x00000080 */ +#define HPRT_PSUSP HPRT_PSUSP_Msk // Port suspend */ +#define HPRT_PRST_Pos (8U) +#define HPRT_PRST_Msk (0x1UL << HPRT_PRST_Pos) // 0x00000100 */ +#define HPRT_PRST HPRT_PRST_Msk // Port reset */ + +#define HPRT_PLSTS_Pos (10U) +#define HPRT_PLSTS_Msk (0x3UL << HPRT_PLSTS_Pos) // 0x00000C00 */ +#define HPRT_PLSTS HPRT_PLSTS_Msk // Port line status */ +#define HPRT_PLSTS_0 (0x1UL << HPRT_PLSTS_Pos) // 0x00000400 */ +#define HPRT_PLSTS_1 (0x2UL << HPRT_PLSTS_Pos) // 0x00000800 */ +#define HPRT_PPWR_Pos (12U) +#define HPRT_PPWR_Msk (0x1UL << HPRT_PPWR_Pos) // 0x00001000 */ +#define HPRT_PPWR HPRT_PPWR_Msk // Port power */ + +#define HPRT_PTCTL_Pos (13U) +#define HPRT_PTCTL_Msk (0xFUL << HPRT_PTCTL_Pos) // 0x0001E000 */ +#define HPRT_PTCTL HPRT_PTCTL_Msk // Port test control */ +#define HPRT_PTCTL_0 (0x1UL << HPRT_PTCTL_Pos) // 0x00002000 */ +#define HPRT_PTCTL_1 (0x2UL << HPRT_PTCTL_Pos) // 0x00004000 */ +#define HPRT_PTCTL_2 (0x4UL << HPRT_PTCTL_Pos) // 0x00008000 */ +#define HPRT_PTCTL_3 (0x8UL << HPRT_PTCTL_Pos) // 0x00010000 */ + +#define HPRT_PSPD_Pos (17U) +#define HPRT_PSPD_Msk (0x3UL << HPRT_PSPD_Pos) // 0x00060000 */ +#define HPRT_PSPD HPRT_PSPD_Msk // Port speed */ +#define HPRT_PSPD_0 (0x1UL << HPRT_PSPD_Pos) // 0x00020000 */ +#define HPRT_PSPD_1 (0x2UL << HPRT_PSPD_Pos) // 0x00040000 */ + +/******************** Bit definition for DOEPEACHMSK1 register ********************/ +#define DOEPEACHMSK1_XFRCM_Pos (0U) +#define DOEPEACHMSK1_XFRCM_Msk (0x1UL << DOEPEACHMSK1_XFRCM_Pos) // 0x00000001 */ +#define DOEPEACHMSK1_XFRCM DOEPEACHMSK1_XFRCM_Msk // Transfer completed interrupt mask */ +#define DOEPEACHMSK1_EPDM_Pos (1U) +#define DOEPEACHMSK1_EPDM_Msk (0x1UL << DOEPEACHMSK1_EPDM_Pos) // 0x00000002 */ +#define DOEPEACHMSK1_EPDM DOEPEACHMSK1_EPDM_Msk // Endpoint disabled interrupt mask */ +#define DOEPEACHMSK1_TOM_Pos (3U) +#define DOEPEACHMSK1_TOM_Msk (0x1UL << DOEPEACHMSK1_TOM_Pos) // 0x00000008 */ +#define DOEPEACHMSK1_TOM DOEPEACHMSK1_TOM_Msk // Timeout condition mask */ +#define DOEPEACHMSK1_ITTXFEMSK_Pos (4U) +#define DOEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << DOEPEACHMSK1_ITTXFEMSK_Pos) // 0x00000010 */ +#define DOEPEACHMSK1_ITTXFEMSK DOEPEACHMSK1_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask */ +#define DOEPEACHMSK1_INEPNMM_Pos (5U) +#define DOEPEACHMSK1_INEPNMM_Msk (0x1UL << DOEPEACHMSK1_INEPNMM_Pos) // 0x00000020 */ +#define DOEPEACHMSK1_INEPNMM DOEPEACHMSK1_INEPNMM_Msk // IN token received with EP mismatch mask */ +#define DOEPEACHMSK1_INEPNEM_Pos (6U) +#define DOEPEACHMSK1_INEPNEM_Msk (0x1UL << DOEPEACHMSK1_INEPNEM_Pos) // 0x00000040 */ +#define DOEPEACHMSK1_INEPNEM DOEPEACHMSK1_INEPNEM_Msk // IN endpoint NAK effective mask */ +#define DOEPEACHMSK1_TXFURM_Pos (8U) +#define DOEPEACHMSK1_TXFURM_Msk (0x1UL << DOEPEACHMSK1_TXFURM_Pos) // 0x00000100 */ +#define DOEPEACHMSK1_TXFURM DOEPEACHMSK1_TXFURM_Msk // OUT packet error mask */ +#define DOEPEACHMSK1_BIM_Pos (9U) +#define DOEPEACHMSK1_BIM_Msk (0x1UL << DOEPEACHMSK1_BIM_Pos) // 0x00000200 */ +#define DOEPEACHMSK1_BIM DOEPEACHMSK1_BIM_Msk // BNA interrupt mask */ +#define DOEPEACHMSK1_BERRM_Pos (12U) +#define DOEPEACHMSK1_BERRM_Msk (0x1UL << DOEPEACHMSK1_BERRM_Pos) // 0x00001000 */ +#define DOEPEACHMSK1_BERRM DOEPEACHMSK1_BERRM_Msk // Bubble error interrupt mask */ +#define DOEPEACHMSK1_NAKM_Pos (13U) +#define DOEPEACHMSK1_NAKM_Msk (0x1UL << DOEPEACHMSK1_NAKM_Pos) // 0x00002000 */ +#define DOEPEACHMSK1_NAKM DOEPEACHMSK1_NAKM_Msk // NAK interrupt mask */ +#define DOEPEACHMSK1_NYETM_Pos (14U) +#define DOEPEACHMSK1_NYETM_Msk (0x1UL << DOEPEACHMSK1_NYETM_Pos) // 0x00004000 */ +#define DOEPEACHMSK1_NYETM DOEPEACHMSK1_NYETM_Msk // NYET interrupt mask */ + +/******************** Bit definition for HPTXFSIZ register ********************/ +#define HPTXFSIZ_PTXSA_Pos (0U) +#define HPTXFSIZ_PTXSA_Msk (0xFFFFUL << HPTXFSIZ_PTXSA_Pos) // 0x0000FFFF */ +#define HPTXFSIZ_PTXSA HPTXFSIZ_PTXSA_Msk // Host periodic TxFIFO start address */ +#define HPTXFSIZ_PTXFD_Pos (16U) +#define HPTXFSIZ_PTXFD_Msk (0xFFFFUL << HPTXFSIZ_PTXFD_Pos) // 0xFFFF0000 */ +#define HPTXFSIZ_PTXFD HPTXFSIZ_PTXFD_Msk // Host periodic TxFIFO depth */ + +/******************** Bit definition for DIEPCTL register ********************/ +#define DIEPCTL_MPSIZ_Pos (0U) +#define DIEPCTL_MPSIZ_Msk (0x7FFUL << DIEPCTL_MPSIZ_Pos) // 0x000007FF */ +#define DIEPCTL_MPSIZ DIEPCTL_MPSIZ_Msk // Maximum packet size */ +#define DIEPCTL_USBAEP_Pos (15U) +#define DIEPCTL_USBAEP_Msk (0x1UL << DIEPCTL_USBAEP_Pos) // 0x00008000 */ +#define DIEPCTL_USBAEP DIEPCTL_USBAEP_Msk // USB active endpoint */ +#define DIEPCTL_EONUM_DPID_Pos (16U) +#define DIEPCTL_EONUM_DPID_Msk (0x1UL << DIEPCTL_EONUM_DPID_Pos) // 0x00010000 */ +#define DIEPCTL_EONUM_DPID DIEPCTL_EONUM_DPID_Msk // Even/odd frame */ +#define DIEPCTL_NAKSTS_Pos (17U) +#define DIEPCTL_NAKSTS_Msk (0x1UL << DIEPCTL_NAKSTS_Pos) // 0x00020000 */ +#define DIEPCTL_NAKSTS DIEPCTL_NAKSTS_Msk // NAK status */ + +#define DIEPCTL_EPTYP_Pos (18U) +#define DIEPCTL_EPTYP_Msk (0x3UL << DIEPCTL_EPTYP_Pos) // 0x000C0000 */ +#define DIEPCTL_EPTYP DIEPCTL_EPTYP_Msk // Endpoint type */ +#define DIEPCTL_EPTYP_0 (0x1UL << DIEPCTL_EPTYP_Pos) // 0x00040000 */ +#define DIEPCTL_EPTYP_1 (0x2UL << DIEPCTL_EPTYP_Pos) // 0x00080000 */ +#define DIEPCTL_STALL_Pos (21U) +#define DIEPCTL_STALL_Msk (0x1UL << DIEPCTL_STALL_Pos) // 0x00200000 */ +#define DIEPCTL_STALL DIEPCTL_STALL_Msk // STALL handshake */ + +#define DIEPCTL_TXFNUM_Pos (22U) +#define DIEPCTL_TXFNUM_Msk (0xFUL << DIEPCTL_TXFNUM_Pos) // 0x03C00000 */ +#define DIEPCTL_TXFNUM DIEPCTL_TXFNUM_Msk // TxFIFO number */ +#define DIEPCTL_TXFNUM_0 (0x1UL << DIEPCTL_TXFNUM_Pos) // 0x00400000 */ +#define DIEPCTL_TXFNUM_1 (0x2UL << DIEPCTL_TXFNUM_Pos) // 0x00800000 */ +#define DIEPCTL_TXFNUM_2 (0x4UL << DIEPCTL_TXFNUM_Pos) // 0x01000000 */ +#define DIEPCTL_TXFNUM_3 (0x8UL << DIEPCTL_TXFNUM_Pos) // 0x02000000 */ +#define DIEPCTL_CNAK_Pos (26U) +#define DIEPCTL_CNAK_Msk (0x1UL << DIEPCTL_CNAK_Pos) // 0x04000000 */ +#define DIEPCTL_CNAK DIEPCTL_CNAK_Msk // Clear NAK */ +#define DIEPCTL_SNAK_Pos (27U) +#define DIEPCTL_SNAK_Msk (0x1UL << DIEPCTL_SNAK_Pos) // 0x08000000 */ +#define DIEPCTL_SNAK DIEPCTL_SNAK_Msk // Set NAK */ +#define DIEPCTL_SD0PID_SEVNFRM_Pos (28U) +#define DIEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << DIEPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 */ +#define DIEPCTL_SD0PID_SEVNFRM DIEPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID */ +#define DIEPCTL_SODDFRM_Pos (29U) +#define DIEPCTL_SODDFRM_Msk (0x1UL << DIEPCTL_SODDFRM_Pos) // 0x20000000 */ +#define DIEPCTL_SODDFRM DIEPCTL_SODDFRM_Msk // Set odd frame */ +#define DIEPCTL_EPDIS_Pos (30U) +#define DIEPCTL_EPDIS_Msk (0x1UL << DIEPCTL_EPDIS_Pos) // 0x40000000 */ +#define DIEPCTL_EPDIS DIEPCTL_EPDIS_Msk // Endpoint disable */ +#define DIEPCTL_EPENA_Pos (31U) +#define DIEPCTL_EPENA_Msk (0x1UL << DIEPCTL_EPENA_Pos) // 0x80000000 */ +#define DIEPCTL_EPENA DIEPCTL_EPENA_Msk // Endpoint enable */ + +/******************** Bit definition for HCCHAR register ********************/ +#define HCCHAR_MPSIZ_Pos (0U) +#define HCCHAR_MPSIZ_Msk (0x7FFUL << HCCHAR_MPSIZ_Pos) // 0x000007FF */ +#define HCCHAR_MPSIZ HCCHAR_MPSIZ_Msk // Maximum packet size */ + +#define HCCHAR_EPNUM_Pos (11U) +#define HCCHAR_EPNUM_Msk (0xFUL << HCCHAR_EPNUM_Pos) // 0x00007800 */ +#define HCCHAR_EPNUM HCCHAR_EPNUM_Msk // Endpoint number */ +#define HCCHAR_EPNUM_0 (0x1UL << HCCHAR_EPNUM_Pos) // 0x00000800 */ +#define HCCHAR_EPNUM_1 (0x2UL << HCCHAR_EPNUM_Pos) // 0x00001000 */ +#define HCCHAR_EPNUM_2 (0x4UL << HCCHAR_EPNUM_Pos) // 0x00002000 */ +#define HCCHAR_EPNUM_3 (0x8UL << HCCHAR_EPNUM_Pos) // 0x00004000 */ +#define HCCHAR_EPDIR_Pos (15U) +#define HCCHAR_EPDIR_Msk (0x1UL << HCCHAR_EPDIR_Pos) // 0x00008000 */ +#define HCCHAR_EPDIR HCCHAR_EPDIR_Msk // Endpoint direction */ +#define HCCHAR_LSDEV_Pos (17U) +#define HCCHAR_LSDEV_Msk (0x1UL << HCCHAR_LSDEV_Pos) // 0x00020000 */ +#define HCCHAR_LSDEV HCCHAR_LSDEV_Msk // Low-speed device */ + +#define HCCHAR_EPTYP_Pos (18U) +#define HCCHAR_EPTYP_Msk (0x3UL << HCCHAR_EPTYP_Pos) // 0x000C0000 */ +#define HCCHAR_EPTYP HCCHAR_EPTYP_Msk // Endpoint type */ +#define HCCHAR_EPTYP_0 (0x1UL << HCCHAR_EPTYP_Pos) // 0x00040000 */ +#define HCCHAR_EPTYP_1 (0x2UL << HCCHAR_EPTYP_Pos) // 0x00080000 */ + +#define HCCHAR_MC_Pos (20U) +#define HCCHAR_MC_Msk (0x3UL << HCCHAR_MC_Pos) // 0x00300000 */ +#define HCCHAR_MC HCCHAR_MC_Msk // Multi Count (MC) / Error Count (EC) */ +#define HCCHAR_MC_0 (0x1UL << HCCHAR_MC_Pos) // 0x00100000 */ +#define HCCHAR_MC_1 (0x2UL << HCCHAR_MC_Pos) // 0x00200000 */ + +#define HCCHAR_DAD_Pos (22U) +#define HCCHAR_DAD_Msk (0x7FUL << HCCHAR_DAD_Pos) // 0x1FC00000 */ +#define HCCHAR_DAD HCCHAR_DAD_Msk // Device address */ +#define HCCHAR_DAD_0 (0x01UL << HCCHAR_DAD_Pos) // 0x00400000 */ +#define HCCHAR_DAD_1 (0x02UL << HCCHAR_DAD_Pos) // 0x00800000 */ +#define HCCHAR_DAD_2 (0x04UL << HCCHAR_DAD_Pos) // 0x01000000 */ +#define HCCHAR_DAD_3 (0x08UL << HCCHAR_DAD_Pos) // 0x02000000 */ +#define HCCHAR_DAD_4 (0x10UL << HCCHAR_DAD_Pos) // 0x04000000 */ +#define HCCHAR_DAD_5 (0x20UL << HCCHAR_DAD_Pos) // 0x08000000 */ +#define HCCHAR_DAD_6 (0x40UL << HCCHAR_DAD_Pos) // 0x10000000 */ +#define HCCHAR_ODDFRM_Pos (29U) +#define HCCHAR_ODDFRM_Msk (0x1UL << HCCHAR_ODDFRM_Pos) // 0x20000000 */ +#define HCCHAR_ODDFRM HCCHAR_ODDFRM_Msk // Odd frame */ +#define HCCHAR_CHDIS_Pos (30U) +#define HCCHAR_CHDIS_Msk (0x1UL << HCCHAR_CHDIS_Pos) // 0x40000000 */ +#define HCCHAR_CHDIS HCCHAR_CHDIS_Msk // Channel disable */ +#define HCCHAR_CHENA_Pos (31U) +#define HCCHAR_CHENA_Msk (0x1UL << HCCHAR_CHENA_Pos) // 0x80000000 */ +#define HCCHAR_CHENA HCCHAR_CHENA_Msk // Channel enable */ + +/******************** Bit definition for HCSPLT register ********************/ + +#define HCSPLT_PRTADDR_Pos (0U) +#define HCSPLT_PRTADDR_Msk (0x7FUL << HCSPLT_PRTADDR_Pos) // 0x0000007F */ +#define HCSPLT_PRTADDR HCSPLT_PRTADDR_Msk // Port address */ +#define HCSPLT_PRTADDR_0 (0x01UL << HCSPLT_PRTADDR_Pos) // 0x00000001 */ +#define HCSPLT_PRTADDR_1 (0x02UL << HCSPLT_PRTADDR_Pos) // 0x00000002 */ +#define HCSPLT_PRTADDR_2 (0x04UL << HCSPLT_PRTADDR_Pos) // 0x00000004 */ +#define HCSPLT_PRTADDR_3 (0x08UL << HCSPLT_PRTADDR_Pos) // 0x00000008 */ +#define HCSPLT_PRTADDR_4 (0x10UL << HCSPLT_PRTADDR_Pos) // 0x00000010 */ +#define HCSPLT_PRTADDR_5 (0x20UL << HCSPLT_PRTADDR_Pos) // 0x00000020 */ +#define HCSPLT_PRTADDR_6 (0x40UL << HCSPLT_PRTADDR_Pos) // 0x00000040 */ + +#define HCSPLT_HUBADDR_Pos (7U) +#define HCSPLT_HUBADDR_Msk (0x7FUL << HCSPLT_HUBADDR_Pos) // 0x00003F80 */ +#define HCSPLT_HUBADDR HCSPLT_HUBADDR_Msk // Hub address */ +#define HCSPLT_HUBADDR_0 (0x01UL << HCSPLT_HUBADDR_Pos) // 0x00000080 */ +#define HCSPLT_HUBADDR_1 (0x02UL << HCSPLT_HUBADDR_Pos) // 0x00000100 */ +#define HCSPLT_HUBADDR_2 (0x04UL << HCSPLT_HUBADDR_Pos) // 0x00000200 */ +#define HCSPLT_HUBADDR_3 (0x08UL << HCSPLT_HUBADDR_Pos) // 0x00000400 */ +#define HCSPLT_HUBADDR_4 (0x10UL << HCSPLT_HUBADDR_Pos) // 0x00000800 */ +#define HCSPLT_HUBADDR_5 (0x20UL << HCSPLT_HUBADDR_Pos) // 0x00001000 */ +#define HCSPLT_HUBADDR_6 (0x40UL << HCSPLT_HUBADDR_Pos) // 0x00002000 */ + +#define HCSPLT_XACTPOS_Pos (14U) +#define HCSPLT_XACTPOS_Msk (0x3UL << HCSPLT_XACTPOS_Pos) // 0x0000C000 */ +#define HCSPLT_XACTPOS HCSPLT_XACTPOS_Msk // XACTPOS */ +#define HCSPLT_XACTPOS_0 (0x1UL << HCSPLT_XACTPOS_Pos) // 0x00004000 */ +#define HCSPLT_XACTPOS_1 (0x2UL << HCSPLT_XACTPOS_Pos) // 0x00008000 */ +#define HCSPLT_COMPLSPLT_Pos (16U) +#define HCSPLT_COMPLSPLT_Msk (0x1UL << HCSPLT_COMPLSPLT_Pos) // 0x00010000 */ +#define HCSPLT_COMPLSPLT HCSPLT_COMPLSPLT_Msk // Do complete split */ +#define HCSPLT_SPLITEN_Pos (31U) +#define HCSPLT_SPLITEN_Msk (0x1UL << HCSPLT_SPLITEN_Pos) // 0x80000000 */ +#define HCSPLT_SPLITEN HCSPLT_SPLITEN_Msk // Split enable */ + +/******************** Bit definition for HCINT register ********************/ +#define HCINT_XFRC_Pos (0U) +#define HCINT_XFRC_Msk (0x1UL << HCINT_XFRC_Pos) // 0x00000001 */ +#define HCINT_XFRC HCINT_XFRC_Msk // Transfer completed */ +#define HCINT_CHH_Pos (1U) +#define HCINT_CHH_Msk (0x1UL << HCINT_CHH_Pos) // 0x00000002 */ +#define HCINT_CHH HCINT_CHH_Msk // Channel halted */ +#define HCINT_AHBERR_Pos (2U) +#define HCINT_AHBERR_Msk (0x1UL << HCINT_AHBERR_Pos) // 0x00000004 */ +#define HCINT_AHBERR HCINT_AHBERR_Msk // AHB error */ +#define HCINT_STALL_Pos (3U) +#define HCINT_STALL_Msk (0x1UL << HCINT_STALL_Pos) // 0x00000008 */ +#define HCINT_STALL HCINT_STALL_Msk // STALL response received interrupt */ +#define HCINT_NAK_Pos (4U) +#define HCINT_NAK_Msk (0x1UL << HCINT_NAK_Pos) // 0x00000010 */ +#define HCINT_NAK HCINT_NAK_Msk // NAK response received interrupt */ +#define HCINT_ACK_Pos (5U) +#define HCINT_ACK_Msk (0x1UL << HCINT_ACK_Pos) // 0x00000020 */ +#define HCINT_ACK HCINT_ACK_Msk // ACK response received/transmitted interrupt */ +#define HCINT_NYET_Pos (6U) +#define HCINT_NYET_Msk (0x1UL << HCINT_NYET_Pos) // 0x00000040 */ +#define HCINT_NYET HCINT_NYET_Msk // Response received interrupt */ +#define HCINT_TXERR_Pos (7U) +#define HCINT_TXERR_Msk (0x1UL << HCINT_TXERR_Pos) // 0x00000080 */ +#define HCINT_TXERR HCINT_TXERR_Msk // Transaction error */ +#define HCINT_BBERR_Pos (8U) +#define HCINT_BBERR_Msk (0x1UL << HCINT_BBERR_Pos) // 0x00000100 */ +#define HCINT_BBERR HCINT_BBERR_Msk // Babble error */ +#define HCINT_FRMOR_Pos (9U) +#define HCINT_FRMOR_Msk (0x1UL << HCINT_FRMOR_Pos) // 0x00000200 */ +#define HCINT_FRMOR HCINT_FRMOR_Msk // Frame overrun */ +#define HCINT_DTERR_Pos (10U) +#define HCINT_DTERR_Msk (0x1UL << HCINT_DTERR_Pos) // 0x00000400 */ +#define HCINT_DTERR HCINT_DTERR_Msk // Data toggle error */ + +/******************** Bit definition for DIEPINT register ********************/ +#define DIEPINT_XFRC_Pos (0U) +#define DIEPINT_XFRC_Msk (0x1UL << DIEPINT_XFRC_Pos) // 0x00000001 */ +#define DIEPINT_XFRC DIEPINT_XFRC_Msk // Transfer completed interrupt */ +#define DIEPINT_EPDISD_Pos (1U) +#define DIEPINT_EPDISD_Msk (0x1UL << DIEPINT_EPDISD_Pos) // 0x00000002 */ +#define DIEPINT_EPDISD DIEPINT_EPDISD_Msk // Endpoint disabled interrupt */ +#define DIEPINT_AHBERR_Pos (2U) +#define DIEPINT_AHBERR_Msk (0x1UL << DIEPINT_AHBERR_Pos) // 0x00000004 */ +#define DIEPINT_AHBERR DIEPINT_AHBERR_Msk // AHB Error (AHBErr) during an IN transaction */ +#define DIEPINT_TOC_Pos (3U) +#define DIEPINT_TOC_Msk (0x1UL << DIEPINT_TOC_Pos) // 0x00000008 */ +#define DIEPINT_TOC DIEPINT_TOC_Msk // Timeout condition */ +#define DIEPINT_ITTXFE_Pos (4U) +#define DIEPINT_ITTXFE_Msk (0x1UL << DIEPINT_ITTXFE_Pos) // 0x00000010 */ +#define DIEPINT_ITTXFE DIEPINT_ITTXFE_Msk // IN token received when TxFIFO is empty */ +#define DIEPINT_INEPNM_Pos (5U) +#define DIEPINT_INEPNM_Msk (0x1UL << DIEPINT_INEPNM_Pos) // 0x00000020 */ +#define DIEPINT_INEPNM DIEPINT_INEPNM_Msk // IN token received with EP mismatch */ +#define DIEPINT_INEPNE_Pos (6U) +#define DIEPINT_INEPNE_Msk (0x1UL << DIEPINT_INEPNE_Pos) // 0x00000040 */ +#define DIEPINT_INEPNE DIEPINT_INEPNE_Msk // IN endpoint NAK effective */ +#define DIEPINT_TXFE_Pos (7U) +#define DIEPINT_TXFE_Msk (0x1UL << DIEPINT_TXFE_Pos) // 0x00000080 */ +#define DIEPINT_TXFE DIEPINT_TXFE_Msk // Transmit FIFO empty */ +#define DIEPINT_TXFIFOUDRN_Pos (8U) +#define DIEPINT_TXFIFOUDRN_Msk (0x1UL << DIEPINT_TXFIFOUDRN_Pos) // 0x00000100 */ +#define DIEPINT_TXFIFOUDRN DIEPINT_TXFIFOUDRN_Msk // Transmit Fifo Underrun */ +#define DIEPINT_BNA_Pos (9U) +#define DIEPINT_BNA_Msk (0x1UL << DIEPINT_BNA_Pos) // 0x00000200 */ +#define DIEPINT_BNA DIEPINT_BNA_Msk // Buffer not available interrupt */ +#define DIEPINT_PKTDRPSTS_Pos (11U) +#define DIEPINT_PKTDRPSTS_Msk (0x1UL << DIEPINT_PKTDRPSTS_Pos) // 0x00000800 */ +#define DIEPINT_PKTDRPSTS DIEPINT_PKTDRPSTS_Msk // Packet dropped status */ +#define DIEPINT_BERR_Pos (12U) +#define DIEPINT_BERR_Msk (0x1UL << DIEPINT_BERR_Pos) // 0x00001000 */ +#define DIEPINT_BERR DIEPINT_BERR_Msk // Babble error interrupt */ +#define DIEPINT_NAK_Pos (13U) +#define DIEPINT_NAK_Msk (0x1UL << DIEPINT_NAK_Pos) // 0x00002000 */ +#define DIEPINT_NAK DIEPINT_NAK_Msk // NAK interrupt */ + +/******************** Bit definition for HCINTMSK register ********************/ +#define HCINTMSK_XFRCM_Pos (0U) +#define HCINTMSK_XFRCM_Msk (0x1UL << HCINTMSK_XFRCM_Pos) // 0x00000001 */ +#define HCINTMSK_XFRCM HCINTMSK_XFRCM_Msk // Transfer completed mask */ +#define HCINTMSK_CHHM_Pos (1U) +#define HCINTMSK_CHHM_Msk (0x1UL << HCINTMSK_CHHM_Pos) // 0x00000002 */ +#define HCINTMSK_CHHM HCINTMSK_CHHM_Msk // Channel halted mask */ +#define HCINTMSK_AHBERR_Pos (2U) +#define HCINTMSK_AHBERR_Msk (0x1UL << HCINTMSK_AHBERR_Pos) // 0x00000004 */ +#define HCINTMSK_AHBERR HCINTMSK_AHBERR_Msk // AHB error */ +#define HCINTMSK_STALLM_Pos (3U) +#define HCINTMSK_STALLM_Msk (0x1UL << HCINTMSK_STALLM_Pos) // 0x00000008 */ +#define HCINTMSK_STALLM HCINTMSK_STALLM_Msk // STALL response received interrupt mask */ +#define HCINTMSK_NAKM_Pos (4U) +#define HCINTMSK_NAKM_Msk (0x1UL << HCINTMSK_NAKM_Pos) // 0x00000010 */ +#define HCINTMSK_NAKM HCINTMSK_NAKM_Msk // NAK response received interrupt mask */ +#define HCINTMSK_ACKM_Pos (5U) +#define HCINTMSK_ACKM_Msk (0x1UL << HCINTMSK_ACKM_Pos) // 0x00000020 */ +#define HCINTMSK_ACKM HCINTMSK_ACKM_Msk // ACK response received/transmitted interrupt mask */ +#define HCINTMSK_NYET_Pos (6U) +#define HCINTMSK_NYET_Msk (0x1UL << HCINTMSK_NYET_Pos) // 0x00000040 */ +#define HCINTMSK_NYET HCINTMSK_NYET_Msk // response received interrupt mask */ +#define HCINTMSK_TXERRM_Pos (7U) +#define HCINTMSK_TXERRM_Msk (0x1UL << HCINTMSK_TXERRM_Pos) // 0x00000080 */ +#define HCINTMSK_TXERRM HCINTMSK_TXERRM_Msk // Transaction error mask */ +#define HCINTMSK_BBERRM_Pos (8U) +#define HCINTMSK_BBERRM_Msk (0x1UL << HCINTMSK_BBERRM_Pos) // 0x00000100 */ +#define HCINTMSK_BBERRM HCINTMSK_BBERRM_Msk // Babble error mask */ +#define HCINTMSK_FRMORM_Pos (9U) +#define HCINTMSK_FRMORM_Msk (0x1UL << HCINTMSK_FRMORM_Pos) // 0x00000200 */ +#define HCINTMSK_FRMORM HCINTMSK_FRMORM_Msk // Frame overrun mask */ +#define HCINTMSK_DTERRM_Pos (10U) +#define HCINTMSK_DTERRM_Msk (0x1UL << HCINTMSK_DTERRM_Pos) // 0x00000400 */ +#define HCINTMSK_DTERRM HCINTMSK_DTERRM_Msk // Data toggle error mask */ + +/******************** Bit definition for DIEPTSIZ register ********************/ + +#define DIEPTSIZ_XFRSIZ_Pos (0U) +#define DIEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << DIEPTSIZ_XFRSIZ_Pos) // 0x0007FFFF */ +#define DIEPTSIZ_XFRSIZ DIEPTSIZ_XFRSIZ_Msk // Transfer size */ +#define DIEPTSIZ_PKTCNT_Pos (19U) +#define DIEPTSIZ_PKTCNT_Msk (0x3FFUL << DIEPTSIZ_PKTCNT_Pos) // 0x1FF80000 */ +#define DIEPTSIZ_PKTCNT DIEPTSIZ_PKTCNT_Msk // Packet count */ +#define DIEPTSIZ_MULCNT_Pos (29U) +#define DIEPTSIZ_MULCNT_Msk (0x3UL << DIEPTSIZ_MULCNT_Pos) // 0x60000000 */ +#define DIEPTSIZ_MULCNT DIEPTSIZ_MULCNT_Msk // Packet count */ + /******************** Bit definition for HCTSIZ register ********************/ +#define HCTSIZ_XFRSIZ_Pos (0U) +#define HCTSIZ_XFRSIZ_Msk (0x7FFFFUL << HCTSIZ_XFRSIZ_Pos) // 0x0007FFFF */ +#define HCTSIZ_XFRSIZ HCTSIZ_XFRSIZ_Msk // Transfer size */ +#define HCTSIZ_PKTCNT_Pos (19U) +#define HCTSIZ_PKTCNT_Msk (0x3FFUL << HCTSIZ_PKTCNT_Pos) // 0x1FF80000 */ +#define HCTSIZ_PKTCNT HCTSIZ_PKTCNT_Msk // Packet count */ +#define HCTSIZ_DOPING_Pos (31U) +#define HCTSIZ_DOPING_Msk (0x1UL << HCTSIZ_DOPING_Pos) // 0x80000000 */ +#define HCTSIZ_DOPING HCTSIZ_DOPING_Msk // Do PING */ +#define HCTSIZ_DPID_Pos (29U) +#define HCTSIZ_DPID_Msk (0x3UL << HCTSIZ_DPID_Pos) // 0x60000000 */ +#define HCTSIZ_DPID HCTSIZ_DPID_Msk // Data PID */ +#define HCTSIZ_DPID_0 (0x1UL << HCTSIZ_DPID_Pos) // 0x20000000 */ +#define HCTSIZ_DPID_1 (0x2UL << HCTSIZ_DPID_Pos) // 0x40000000 */ + +/******************** Bit definition for DIEPDMA register ********************/ +#define DIEPDMA_DMAADDR_Pos (0U) +#define DIEPDMA_DMAADDR_Msk (0xFFFFFFFFUL << DIEPDMA_DMAADDR_Pos) // 0xFFFFFFFF */ +#define DIEPDMA_DMAADDR DIEPDMA_DMAADDR_Msk // DMA address */ + +/******************** Bit definition for HCDMA register ********************/ +#define HCDMA_DMAADDR_Pos (0U) +#define HCDMA_DMAADDR_Msk (0xFFFFFFFFUL << HCDMA_DMAADDR_Pos) // 0xFFFFFFFF */ +#define HCDMA_DMAADDR HCDMA_DMAADDR_Msk // DMA address */ + + /******************** Bit definition for DTXFSTS register ********************/ +#define DTXFSTS_INEPTFSAV_Pos (0U) +#define DTXFSTS_INEPTFSAV_Msk (0xFFFFUL << DTXFSTS_INEPTFSAV_Pos) // 0x0000FFFF */ +#define DTXFSTS_INEPTFSAV DTXFSTS_INEPTFSAV_Msk // IN endpoint TxFIFO space available */ + + /******************** Bit definition for DIEPTXF register ********************/ +#define DIEPTXF_INEPTXSA_Pos (0U) +#define DIEPTXF_INEPTXSA_Msk (0xFFFFUL << DIEPTXF_INEPTXSA_Pos) // 0x0000FFFF */ +#define DIEPTXF_INEPTXSA DIEPTXF_INEPTXSA_Msk // IN endpoint FIFOx transmit RAM start address */ +#define DIEPTXF_INEPTXFD_Pos (16U) +#define DIEPTXF_INEPTXFD_Msk (0xFFFFUL << DIEPTXF_INEPTXFD_Pos) // 0xFFFF0000 */ +#define DIEPTXF_INEPTXFD DIEPTXF_INEPTXFD_Msk // IN endpoint TxFIFO depth */ + +/******************** Bit definition for DOEPCTL register ********************/ +#define DOEPCTL_MPSIZ_Pos (0U) +#define DOEPCTL_MPSIZ_Msk (0x7FFUL << DOEPCTL_MPSIZ_Pos) // 0x000007FF */ +#define DOEPCTL_MPSIZ DOEPCTL_MPSIZ_Msk // Maximum packet size */ //Bit 1 */ +#define DOEPCTL_USBAEP_Pos (15U) +#define DOEPCTL_USBAEP_Msk (0x1UL << DOEPCTL_USBAEP_Pos) // 0x00008000 */ +#define DOEPCTL_USBAEP DOEPCTL_USBAEP_Msk // USB active endpoint */ +#define DOEPCTL_NAKSTS_Pos (17U) +#define DOEPCTL_NAKSTS_Msk (0x1UL << DOEPCTL_NAKSTS_Pos) // 0x00020000 */ +#define DOEPCTL_NAKSTS DOEPCTL_NAKSTS_Msk // NAK status */ +#define DOEPCTL_SD0PID_SEVNFRM_Pos (28U) +#define DOEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << DOEPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 */ +#define DOEPCTL_SD0PID_SEVNFRM DOEPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID */ +#define DOEPCTL_SODDFRM_Pos (29U) +#define DOEPCTL_SODDFRM_Msk (0x1UL << DOEPCTL_SODDFRM_Pos) // 0x20000000 */ +#define DOEPCTL_SODDFRM DOEPCTL_SODDFRM_Msk // Set odd frame */ +#define DOEPCTL_EPTYP_Pos (18U) +#define DOEPCTL_EPTYP_Msk (0x3UL << DOEPCTL_EPTYP_Pos) // 0x000C0000 */ +#define DOEPCTL_EPTYP DOEPCTL_EPTYP_Msk // Endpoint type */ +#define DOEPCTL_EPTYP_0 (0x1UL << DOEPCTL_EPTYP_Pos) // 0x00040000 */ +#define DOEPCTL_EPTYP_1 (0x2UL << DOEPCTL_EPTYP_Pos) // 0x00080000 */ +#define DOEPCTL_SNPM_Pos (20U) +#define DOEPCTL_SNPM_Msk (0x1UL << DOEPCTL_SNPM_Pos) // 0x00100000 */ +#define DOEPCTL_SNPM DOEPCTL_SNPM_Msk // Snoop mode */ +#define DOEPCTL_STALL_Pos (21U) +#define DOEPCTL_STALL_Msk (0x1UL << DOEPCTL_STALL_Pos) // 0x00200000 */ +#define DOEPCTL_STALL DOEPCTL_STALL_Msk // STALL handshake */ +#define DOEPCTL_CNAK_Pos (26U) +#define DOEPCTL_CNAK_Msk (0x1UL << DOEPCTL_CNAK_Pos) // 0x04000000 */ +#define DOEPCTL_CNAK DOEPCTL_CNAK_Msk // Clear NAK */ +#define DOEPCTL_SNAK_Pos (27U) +#define DOEPCTL_SNAK_Msk (0x1UL << DOEPCTL_SNAK_Pos) // 0x08000000 */ +#define DOEPCTL_SNAK DOEPCTL_SNAK_Msk // Set NAK */ +#define DOEPCTL_EPDIS_Pos (30U) +#define DOEPCTL_EPDIS_Msk (0x1UL << DOEPCTL_EPDIS_Pos) // 0x40000000 */ +#define DOEPCTL_EPDIS DOEPCTL_EPDIS_Msk // Endpoint disable */ +#define DOEPCTL_EPENA_Pos (31U) +#define DOEPCTL_EPENA_Msk (0x1UL << DOEPCTL_EPENA_Pos) // 0x80000000 */ +#define DOEPCTL_EPENA DOEPCTL_EPENA_Msk // Endpoint enable */ + +/******************** Bit definition for DOEPINT register ********************/ +#define DOEPINT_XFRC_Pos (0U) +#define DOEPINT_XFRC_Msk (0x1UL << DOEPINT_XFRC_Pos) // 0x00000001 */ +#define DOEPINT_XFRC DOEPINT_XFRC_Msk // Transfer completed interrupt */ +#define DOEPINT_EPDISD_Pos (1U) +#define DOEPINT_EPDISD_Msk (0x1UL << DOEPINT_EPDISD_Pos) // 0x00000002 */ +#define DOEPINT_EPDISD DOEPINT_EPDISD_Msk // Endpoint disabled interrupt */ +#define DOEPINT_AHBERR_Pos (2U) +#define DOEPINT_AHBERR_Msk (0x1UL << DOEPINT_AHBERR_Pos) // 0x00000004 */ +#define DOEPINT_AHBERR DOEPINT_AHBERR_Msk // AHB Error (AHBErr) during an OUT transaction */ +#define DOEPINT_STUP_Pos (3U) +#define DOEPINT_STUP_Msk (0x1UL << DOEPINT_STUP_Pos) // 0x00000008 */ +#define DOEPINT_STUP DOEPINT_STUP_Msk // SETUP phase done */ +#define DOEPINT_OTEPDIS_Pos (4U) +#define DOEPINT_OTEPDIS_Msk (0x1UL << DOEPINT_OTEPDIS_Pos) // 0x00000010 */ +#define DOEPINT_OTEPDIS DOEPINT_OTEPDIS_Msk // OUT token received when endpoint disabled */ +#define DOEPINT_OTEPSPR_Pos (5U) +#define DOEPINT_OTEPSPR_Msk (0x1UL << DOEPINT_OTEPSPR_Pos) // 0x00000020 */ +#define DOEPINT_OTEPSPR DOEPINT_OTEPSPR_Msk // Status Phase Received For Control Write */ +#define DOEPINT_B2BSTUP_Pos (6U) +#define DOEPINT_B2BSTUP_Msk (0x1UL << DOEPINT_B2BSTUP_Pos) // 0x00000040 */ +#define DOEPINT_B2BSTUP DOEPINT_B2BSTUP_Msk // Back-to-back SETUP packets received */ +#define DOEPINT_OUTPKTERR_Pos (8U) +#define DOEPINT_OUTPKTERR_Msk (0x1UL << DOEPINT_OUTPKTERR_Pos) // 0x00000100 */ +#define DOEPINT_OUTPKTERR DOEPINT_OUTPKTERR_Msk // OUT packet error */ +#define DOEPINT_NAK_Pos (13U) +#define DOEPINT_NAK_Msk (0x1UL << DOEPINT_NAK_Pos) // 0x00002000 */ +#define DOEPINT_NAK DOEPINT_NAK_Msk // NAK Packet is transmitted by the device */ +#define DOEPINT_NYET_Pos (14U) +#define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000 */ +#define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt */ +#define DOEPINT_STPKTRX_Pos (15U) +#define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000 */ +#define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received */ + +/******************** Bit definition for DOEPTSIZ register ********************/ +#define DOEPTSIZ_XFRSIZ_Pos (0U) +#define DOEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << DOEPTSIZ_XFRSIZ_Pos) // 0x0007FFFF */ +#define DOEPTSIZ_XFRSIZ DOEPTSIZ_XFRSIZ_Msk // Transfer size */ +#define DOEPTSIZ_PKTCNT_Pos (19U) +#define DOEPTSIZ_PKTCNT_Msk (0x3FFUL << DOEPTSIZ_PKTCNT_Pos) // 0x1FF80000 */ +#define DOEPTSIZ_PKTCNT DOEPTSIZ_PKTCNT_Msk // Packet count */ + +#define DOEPTSIZ_STUPCNT_Pos (29U) +#define DOEPTSIZ_STUPCNT_Msk (0x3UL << DOEPTSIZ_STUPCNT_Pos) // 0x60000000 */ +#define DOEPTSIZ_STUPCNT DOEPTSIZ_STUPCNT_Msk // SETUP packet count */ +#define DOEPTSIZ_STUPCNT_0 (0x1UL << DOEPTSIZ_STUPCNT_Pos) // 0x20000000 */ +#define DOEPTSIZ_STUPCNT_1 (0x2UL << DOEPTSIZ_STUPCNT_Pos) // 0x40000000 */ + +/******************** Bit definition for PCGCTL register ********************/ +#define PCGCTL_IF_DEV_MODE TU_BIT(31) +#define PCGCTL_P2HD_PRT_SPD_MASK (0x3ul << 29) +#define PCGCTL_P2HD_PRT_SPD_SHIFT 29 +#define PCGCTL_P2HD_DEV_ENUM_SPD_MASK (0x3ul << 27) +#define PCGCTL_P2HD_DEV_ENUM_SPD_SHIFT 27 +#define PCGCTL_MAC_DEV_ADDR_MASK (0x7ful << 20) +#define PCGCTL_MAC_DEV_ADDR_SHIFT 20 +#define PCGCTL_MAX_TERMSEL TU_BIT(19) +#define PCGCTL_MAX_XCVRSELECT_MASK (0x3ul << 17) +#define PCGCTL_MAX_XCVRSELECT_SHIFT 17 +#define PCGCTL_PORT_POWER TU_BIT(16) +#define PCGCTL_PRT_CLK_SEL_MASK (0x3ul << 14) +#define PCGCTL_PRT_CLK_SEL_SHIFT 14 +#define PCGCTL_ESS_REG_RESTORED TU_BIT(13) +#define PCGCTL_EXTND_HIBER_SWITCH TU_BIT(12) +#define PCGCTL_EXTND_HIBER_PWRCLMP TU_BIT(11) +#define PCGCTL_ENBL_EXTND_HIBER TU_BIT(10) +#define PCGCTL_RESTOREMODE TU_BIT(9) +#define PCGCTL_RESETAFTSUSP TU_BIT(8) +#define PCGCTL_DEEP_SLEEP TU_BIT(7) +#define PCGCTL_PHY_IN_SLEEP TU_BIT(6) +#define PCGCTL_ENBL_SLEEP_GATING TU_BIT(5) +#define PCGCTL_RSTPDWNMODULE TU_BIT(3) +#define PCGCTL_PWRCLMP TU_BIT(2) +#define PCGCTL_GATEHCLK TU_BIT(1) +#define PCGCTL_STOPPCLK TU_BIT(0) + +#define PCGCTL1_TIMER (0x3ul << 1) +#define PCGCTL1_GATEEN TU_BIT(0) + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_xmc.h b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_xmc.h new file mode 100644 index 0000000..4e6bebb --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/dwc2_xmc.h @@ -0,0 +1,87 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Rafael Silva (@perigoso) + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _DWC2_XMC_H_ +#define _DWC2_XMC_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "xmc_device.h" + +// XMC has custom control register before DWC registers +#define DWC2_REG_BASE USB0_BASE +#define DWC2_EP_MAX 7 +#define DWC2_EP_FIFO_SIZE 2048 + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB0_0_IRQn); +} + +TU_ATTR_ALWAYS_INLINE +static inline void dwc2_dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB0_0_IRQn); +} + +static inline void dwc2_remote_wakeup_delay(void) +{ + // try to delay for 1 ms +// uint32_t count = SystemCoreClock / 1000; +// while ( count-- ) __NOP(); +} + +// MCU specific PHY init, called BEFORE core reset +static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // Enable PHY + //USB->ROUTE = USB_ROUTE_PHYPEN; +} + +// MCU specific PHY update, it is called AFTER init() and core reset +static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) +{ + (void) dwc2; + (void) hs_phy_type; + + // XMC Manual: turn around must be 5 (reset & default value) + // dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/hwcfg_list.md b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/hwcfg_list.md new file mode 100644 index 0000000..b5590da --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/synopsys/dwc2/hwcfg_list.md @@ -0,0 +1,777 @@ +# DWC2 Hardware Configuration Registers + +## Broadcom BCM2711 (Pi4) + +dwc2->guid = 2708A000 +dwc2->gsnpsid = 4F54280A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 228DDD50 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 2 +hw_cfg2->point2point = 0 +hw_cfg2->hs_phy_type = 1 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 7 +hw_cfg2->num_host_ch = 7 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 0 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = FF000E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 0 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 0 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 0 +hw_cfg3->lpm_mode = 0 +hw_cfg3->total_fifo_size = 4080 + +dwc2->ghwcfg4 = 1FF00020 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 0 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 0 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 15 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## EFM32GG FS + +dwc2->guid = 0 +dwc2->gsnpsid = 4F54330A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 228F5910 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 2 +hw_cfg2->point2point = 0 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 6 +hw_cfg2->num_host_ch = 13 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 0 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 1F204E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 0 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 1 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 0 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 0 +hw_cfg3->lpm_mode = 0 +hw_cfg3->total_fifo_size = 498 + +dwc2->ghwcfg4 = 1BF08030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 2 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 13 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## ESP32-S2 Fullspeed + +dwc2->guid = 0 +dwc2->gsnpsid = 4F54400A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 224DD930 +hw_cfg2->op_mode = 2 +hw_cfg2->arch = 3 +hw_cfg2->point2point = 0 +hw_cfg2->hs_phy_type = 1 +hw_cfg2->fs_phy_type = 2 +hw_cfg2->num_dev_ep = 6 +hw_cfg2->num_host_ch = 9 +hw_cfg2->period_channel_support = 0 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 1 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 22 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = C804B5 +hw_cfg3->xfer_size_width = 10 +hw_cfg3->packet_size_width = 5 +hw_cfg3->otg_enable = 0 +hw_cfg3->i2c_enable = 0 +hw_cfg3->vendor_ctrl_itf = 1 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 1 +hw_cfg3->otg_adp_support = 1 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 1 +hw_cfg3->lpm_mode = 0 +hw_cfg3->total_fifo_size = 23130 + +dwc2->ghwcfg4 = D3F0A030 +hw_cfg4->num_dev_period_in_ep = 10 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 0 +hw_cfg4->hibernation = 1 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 1 +hw_cfg4->acg_enable = 1 +hw_cfg4->utmi_phy_data_width = 1 +hw_cfg4->dev_ctrl_ep_num = 10 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 0 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 0 +hw_cfg4->dedicated_fifos = 0 +hw_cfg4->num_dev_in_eps = 13 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 1 + +## STM32F407 and STM32F207 + +STM32F407 and STM32F207 are exactly the same + +### STM32F407 Fullspeed + +dwc2->guid = 1200 +dwc2->gsnpsid = 4F54281A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229DCD20 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 0 +hw_cfg2->point2point = 1 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 3 +hw_cfg2->num_host_ch = 7 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 20001E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 1 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 0 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 0 +hw_cfg3->lpm_mode = 0 +hw_cfg3->total_fifo_size = 512 + +dwc2->ghwcfg4 = FF08030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 2 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 7 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +### STM32F407 Highspeed + +dwc2->guid = 1100 +dwc2->gsnpsid = 4F54281A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229ED590 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 2 +hw_cfg2->point2point = 0 +hw_cfg2->hs_phy_type = 2 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 5 +hw_cfg2->num_host_ch = 11 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 3F403E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 1 +hw_cfg3->vendor_ctrl_itf = 1 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 0 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 0 +hw_cfg3->lpm_mode = 0 +hw_cfg3->total_fifo_size = 1012 + +dwc2->ghwcfg4 = 17F00030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 0 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 11 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## STM32F411 Fullspeed + +dwc2->guid = 1200 +dwc2->gsnpsid = 4F54281A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229DCD20 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 0 +hw_cfg2->point2point = 1 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 3 +hw_cfg2->num_host_ch = 7 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 20001E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 1 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 0 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 0 +hw_cfg3->lpm_mode = 0 +hw_cfg3->total_fifo_size = 512 + +dwc2->ghwcfg4 = FF08030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 2 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 7 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## STM32F412 FS + +dwc2->guid = 2000 +dwc2->gsnpsid = 4F54320A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229ED520 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 0 +hw_cfg2->point2point = 1 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 5 +hw_cfg2->num_host_ch = 11 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 200D1E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 1 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 1 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 1 +hw_cfg3->lpm_mode = 1 +hw_cfg3->total_fifo_size = 512 + +dwc2->ghwcfg4 = 17F08030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 2 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 11 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## STM32F723 + +### STM32F723 HighSpeed + +dwc2->guid = 3100 +dwc2->gsnpsid = 4F54330A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229FE1D0 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 2 +hw_cfg2->point2point = 0 +hw_cfg2->hs_phy_type = 3 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 8 +hw_cfg2->num_host_ch = 15 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 3EED2E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 0 +hw_cfg3->vendor_ctrl_itf = 1 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 1 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 1 +hw_cfg3->lpm_mode = 1 +hw_cfg3->total_fifo_size = 1006 + +dwc2->ghwcfg4 = 23F00030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 0 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 1 +hw_cfg4->dma_desc_enable = 1 +hw_cfg4->dma_dynamic = 0 + +### STM32F723 Fullspeed + +dwc2->guid = 3000 +dwc2->gsnpsid = 4F54330A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229ED520 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 0 +hw_cfg2->point2point = 1 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 5 +hw_cfg2->num_host_ch = 11 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 200D1E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 1 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 1 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 1 +hw_cfg3->lpm_mode = 1 +hw_cfg3->total_fifo_size = 512 + +dwc2->ghwcfg4 = 17F08030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 2 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 11 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## STM32F767 FS + +dwc2->guid = 2000 +dwc2->gsnpsid = 4F54320A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229ED520 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 0 +hw_cfg2->point2point = 1 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 5 +hw_cfg2->num_host_ch = 11 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 200D1E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 1 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 1 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 1 +hw_cfg3->lpm_mode = 1 +hw_cfg3->total_fifo_size = 512 + +dwc2->ghwcfg4 = 17F08030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 2 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 11 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## STM32H743 (both cores HS) + +dwc2->guid = 2300 +dwc2->gsnpsid = 4F54330A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229FE190 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 2 +hw_cfg2->point2point = 0 +hw_cfg2->hs_phy_type = 2 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 8 +hw_cfg2->num_host_ch = 15 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 3B8D2E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 0 +hw_cfg3->vendor_ctrl_itf = 1 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 1 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 1 +hw_cfg3->lpm_mode = 1 +hw_cfg3->total_fifo_size = 952 + +dwc2->ghwcfg4 = E3F00030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 0 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 1 +hw_cfg4->dma_desc_enable = 1 +hw_cfg4->dma_dynamic = 1 + +## STM32L476 FS + +dwc2->guid = 2000 +dwc2->gsnpsid = 4F54310A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 229ED520 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 0 +hw_cfg2->point2point = 1 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 5 +hw_cfg2->num_host_ch = 11 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 1 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 200D1E8 +hw_cfg3->xfer_size_width = 8 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 1 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 1 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 1 +hw_cfg3->lpm_mode = 1 +hw_cfg3->total_fifo_size = 512 + +dwc2->ghwcfg4 = 17F08030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 2 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 11 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## GD32VF103 Fullspeed + +dwc2->guid = 1000 +dwc2->gsnpsid = 0 +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 0 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 0 +hw_cfg2->point2point = 0 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 0 +hw_cfg2->num_dev_ep = 0 +hw_cfg2->num_host_ch = 0 +hw_cfg2->period_channel_support = 0 +hw_cfg2->enable_dynamic_fifo = 0 +hw_cfg2->mul_cpu_int = 0 +hw_cfg2->nperiod_tx_q_depth = 0 +hw_cfg2->host_period_tx_q_depth = 0 +hw_cfg2->dev_token_q_depth = 0 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 0 +hw_cfg3->xfer_size_width = 0 +hw_cfg3->packet_size_width = 0 +hw_cfg3->otg_enable = 0 +hw_cfg3->i2c_enable = 0 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 0 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 0 +hw_cfg3->lpm_mode = 0 +hw_cfg3->total_fifo_size = 0 + +dwc2->ghwcfg4 = 0 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 0 +hw_cfg4->ahb_freq_min = 0 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 0 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 0 +hw_cfg4->vbus_valid_filter_enabled = 0 +hw_cfg4->a_valid_filter_enabled = 0 +hw_cfg4->b_valid_filter_enabled = 0 +hw_cfg4->dedicated_fifos = 0 +hw_cfg4->num_dev_in_eps = 0 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 0 + +## XMC4500 + +dwc2->guid = AEC000 +dwc2->gsnpsid = 4F54292A +dwc2->ghwcfg1 = 0 + +dwc2->ghwcfg2 = 228F5930 +hw_cfg2->op_mode = 0 +hw_cfg2->arch = 2 +hw_cfg2->point2point = 1 +hw_cfg2->hs_phy_type = 0 +hw_cfg2->fs_phy_type = 1 +hw_cfg2->num_dev_ep = 6 +hw_cfg2->num_host_ch = 13 +hw_cfg2->period_channel_support = 1 +hw_cfg2->enable_dynamic_fifo = 1 +hw_cfg2->mul_cpu_int = 0 +hw_cfg2->nperiod_tx_q_depth = 2 +hw_cfg2->host_period_tx_q_depth = 2 +hw_cfg2->dev_token_q_depth = 8 +hw_cfg2->otg_enable_ic_usb = 0 + +dwc2->ghwcfg3 = 27A01E5 +hw_cfg3->xfer_size_width = 5 +hw_cfg3->packet_size_width = 6 +hw_cfg3->otg_enable = 1 +hw_cfg3->i2c_enable = 1 +hw_cfg3->vendor_ctrl_itf = 0 +hw_cfg3->optional_feature_removed = 0 +hw_cfg3->synch_reset = 0 +hw_cfg3->otg_adp_support = 0 +hw_cfg3->otg_enable_hsic = 0 +hw_cfg3->battery_charger_support = 0 +hw_cfg3->lpm_mode = 0 +hw_cfg3->total_fifo_size = 634 + +dwc2->ghwcfg4 = DBF08030 +hw_cfg4->num_dev_period_in_ep = 0 +hw_cfg4->power_optimized = 1 +hw_cfg4->ahb_freq_min = 1 +hw_cfg4->hibernation = 0 +hw_cfg4->service_interval_mode = 0 +hw_cfg4->ipg_isoc_en = 0 +hw_cfg4->acg_enable = 0 +hw_cfg4->utmi_phy_data_width = 2 +hw_cfg4->dev_ctrl_ep_num = 0 +hw_cfg4->iddg_filter_enabled = 1 +hw_cfg4->vbus_valid_filter_enabled = 1 +hw_cfg4->a_valid_filter_enabled = 1 +hw_cfg4->b_valid_filter_enabled = 1 +hw_cfg4->dedicated_fifos = 1 +hw_cfg4->num_dev_in_eps = 13 +hw_cfg4->dma_desc_enable = 0 +hw_cfg4->dma_dynamic = 1 diff --git a/circuitpython/lib/tinyusb/src/portable/template/dcd_template.c b/circuitpython/lib/tinyusb/src/portable/template/dcd_template.c new file mode 100644 index 0000000..9773693 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/template/dcd_template.c @@ -0,0 +1,136 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUSB_MCU == OPT_MCU_NONE + +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ + +// Initialize controller to device mode +void dcd_init (uint8_t rhport) +{ + (void) rhport; +} + +// Enable device interrupt +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; +} + +// Disable device interrupt +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + (void) dev_addr; +} + +// Wake up host +void dcd_remote_wakeup (uint8_t rhport) +{ + (void) rhport; +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + (void) ep_desc; + return false; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; +} + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + (void) ep_addr; + (void) buffer; + (void) total_bytes; + return false; +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + (void) ep_addr; + (void) ff; + (void) total_bytes; + return false; +} + +// Stall endpoint +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + (void) ep_addr; +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + (void) ep_addr; +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/circuitpython/lib/tinyusb/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c new file mode 100644 index 0000000..c3b3b24 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -0,0 +1,699 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2020 William D. Jones + * Copyright (c) 2019-2020 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MSP430x5xx ) + +#include "msp430.h" +#include "device/dcd.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +// usbpllir_mirror and usbmaintl_mirror can be added later if needed. +static volatile uint16_t usbiepie_mirror = 0; +static volatile uint16_t usboepie_mirror = 0; +static volatile uint8_t usbie_mirror = 0; +static volatile uint16_t usbpwrctl_mirror = 0; +static bool in_isr = false; + +uint8_t _setup_packet[8]; + +// Xfer control +typedef struct +{ + uint8_t * buffer; + // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API + uint16_t total_len; + uint16_t queued_len; + uint16_t max_size; + bool short_packet; +} xfer_ctl_t; + +xfer_ctl_t xfer_status[8][2]; +#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] + +// Accessing endpoint regs +typedef volatile uint8_t * ep_regs_t; + +typedef enum +{ + CNF = 0, + BBAX = 1, + BCTX = 2, + BBAY = 5, + BCTY = 6, + SIZXY = 7 +} ep_regs_index_t; + +#define EP_REGS(epnum, dir) ((ep_regs_t) ((uintptr_t)&USBOEPCNF_1 + 64*dir + 8*(epnum - 1))) + +static void bus_reset(void) +{ + // Hardcoded into the USB core. + xfer_status[0][TUSB_DIR_OUT].max_size = 8; + xfer_status[0][TUSB_DIR_IN].max_size = 8; + + USBKEYPID = USBKEY; + + // Enable the control EP 0. Also enable Indication Enable- a guard flag + // separate from the Interrupt Enable mask. + USBOEPCNF_0 |= (UBME | USBIIE); + USBIEPCNF_0 |= (UBME | USBIIE); + + // Enable interrupts for this endpoint. + USBOEPIE |= BIT0; + USBIEPIE |= BIT0; + + // Clear NAK until a setup packet is received. + USBOEPCNT_0 &= ~NAK; + USBIEPCNT_0 &= ~NAK; + + USBCTL |= FEN; // Enable responding to packets. + + // Dedicated buffers in hardware for SETUP and EP0, no setup needed. + // Now safe to respond to SETUP packets. + USBIE |= SETUPIE; + + USBKEYPID = 0; +} + + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init (uint8_t rhport) +{ + (void) rhport; + + USBKEYPID = USBKEY; + + // Enable the module (required to write config regs)! + USBCNF |= USB_EN; + + // Reset used interrupts + USBOEPIE = 0; + USBIEPIE = 0; + USBIE = 0; + USBOEPIFG = 0; + USBIEPIFG = 0; + USBIFG = 0; + USBPWRCTL &= ~(VUOVLIE | VBONIE | VBOFFIE | VUOVLIFG | VBONIFG | VBOFFIFG); + usboepie_mirror = 0; + usbiepie_mirror = 0; + usbie_mirror = 0; + usbpwrctl_mirror = 0; + + USBVECINT = 0; + + // Enable reset and wait for it before continuing. + USBIE |= RSTRIE; + + // Enable pullup. + USBCNF |= PUR_EN; + + USBKEYPID = 0; +} + +// There is no "USB peripheral interrupt disable" bit on MSP430, so we have +// to save the relevant registers individually. +// WARNING: Unlike the ARM/NVIC routines, these functions are _not_ idempotent +// if you modified the registers saved in between calls so they don't match +// the mirrors; mirrors will be updated to reflect most recent register +// contents. +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; + + __bic_SR_register(GIE); // Unlikely to be called in ISR, but let's be safe. + // Also, this cleanly disables all USB interrupts + // atomically from application's POV. + + // This guard is required because tinyusb can enable interrupts without + // having disabled them first. + if(in_isr) + { + USBOEPIE = usboepie_mirror; + USBIEPIE = usbiepie_mirror; + USBIE = usbie_mirror; + USBPWRCTL |= usbpwrctl_mirror; + } + + in_isr = false; + __bis_SR_register(GIE); +} + +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; + + __bic_SR_register(GIE); + usboepie_mirror = USBOEPIE; + usbiepie_mirror = USBIEPIE; + usbie_mirror = USBIE; + usbpwrctl_mirror = (USBPWRCTL & (VUOVLIE | VBONIE | VBOFFIE)); + USBOEPIE = 0; + USBIEPIE = 0; + USBIE = 0; + USBPWRCTL &= ~(VUOVLIE | VBONIE | VBOFFIE); + in_isr = true; + __bis_SR_register(GIE); +} + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + + USBFUNADR = dev_addr; + + // Response with status after changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; +} + +void dcd_connect(uint8_t rhport) +{ + dcd_int_disable(rhport); + + USBKEYPID = USBKEY; + USBCNF |= PUR_EN; // Enable pullup. + USBKEYPID = 0; + + dcd_int_enable(rhport); +} + +void dcd_disconnect(uint8_t rhport) +{ + dcd_int_disable(rhport); + + USBKEYPID = USBKEY; + USBCNF &= ~PUR_EN; // Disable pullup. + USBKEYPID = 0; + + dcd_int_enable(rhport); +} + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + // Unsupported endpoint numbers or type (Iso not supported. Control + // not supported on nonzero endpoints). + if( (epnum > 7) || \ + (desc_edpt->bmAttributes.xfer == 0) || \ + (desc_edpt->bmAttributes.xfer == 1)) { + return false; + } + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); + + // Buffer allocation scheme: + // For simplicity, only single buffer for now, since tinyusb currently waits + // for an xfer to complete before scheduling another one. This means only + // the X buffer is used. + // + // 1904 bytes are available, the max endpoint size supported on msp430 is + // 64 bytes. This is enough RAM for all 14 endpoints enabled _with_ double + // bufferring (64*14*2 = 1792 bytes). Extra RAM exists for triple and higher + // order bufferring, which must be maintained in software. + // + // For simplicity, each endpoint gets a hardcoded 64 byte chunk (regardless + // of actual wMaxPacketSize) whose start address is the following: + // addr = 128 * (epnum - 1) + 64 * dir. + // + // Double buffering equation: + // x_addr = 256 * (epnum - 1) + 128 * dir + // y_addr = x_addr + 64 + // Address is right-shifted by 3 to fit into 8 bits. + + uint8_t buf_base = (128 * (epnum - 1) + 64 * dir) >> 3; + + // IN and OUT EP registers have the same structure. + ep_regs_t ep_regs = EP_REGS(epnum, dir); + + // FIXME: I was able to get into a situation where OUT EP 3 would stall + // while debugging, despite stall code never being called. It appears + // these registers don't get cleared on reset, being part of RAM. + // Investigate and see if I can duplicate. + // Also, DBUF got set on OUT EP 2 while debugging. Only OUT EPs seem to be + // affected at this time. USB RAM directly precedes main RAM; perhaps I'm + // overwriting registers via buffer overflow w/ my debugging code? + ep_regs[SIZXY] = tu_edpt_packet_size(desc_edpt); + ep_regs[BCTX] |= NAK; + ep_regs[BBAX] = buf_base; + ep_regs[CNF] &= ~(TOGGLE | STALL | DBUF); // ISO xfers not supported on + // MSP430, so no need to gate DATA0/1 and frame + // behavior. Clear stall and double buffer bit as + // well- see above comment. + ep_regs[CNF] |= (UBME | USBIIE); + + USBKEYPID = USBKEY; + if(dir == TUSB_DIR_OUT) + { + USBOEPIE |= (1 << epnum); + } + else + { + USBIEPIE |= (1 << epnum); + } + USBKEYPID = 0; + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->short_packet = false; + + if(epnum == 0) + { + if(dir == TUSB_DIR_OUT) + { + // Interrupt will notify us when data was received. + USBCTL &= ~DIR; + USBOEPCNT_0 &= ~NAK; + } + else + { + // Kickstart the IN packet handler by queuing initial data and calling + // the ISR to transmit the first packet. + // Interrupt only fires on completed xfer. + USBCTL |= DIR; + USBIEPIFG |= BIT0; + } + } + else + { + ep_regs_t ep_regs = EP_REGS(epnum, dir); + + if(dir == TUSB_DIR_OUT) + { + ep_regs[BCTX] &= ~NAK; + } + else + { + USBIEPIFG |= (1 << epnum); + } + } + + return true; +} + +#if 0 // TODO support dcd_edpt_xfer_fifo API +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = NULL; + xfer->ff = ff; + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->short_packet = false; + + ep_regs_t ep_regs = EP_REGS(epnum, dir); + + if(dir == TUSB_DIR_OUT) + { + ep_regs[BCTX] &= ~NAK; + } + else + { + USBIEPIFG |= (1 << epnum); + } + + return true; +} +#endif + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if(epnum == 0) + { + if(dir == TUSB_DIR_OUT) + { + USBOEPCNT_0 |= NAK; + USBOEPCNF_0 |= STALL; + } + else + { + USBIEPCNT_0 |= NAK; + USBIEPCNF_0 |= STALL; + } + } + else + { + ep_regs_t ep_regs = EP_REGS(epnum, dir); + ep_regs[CNF] |= STALL; + } +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if(epnum == 0) + { + if(dir == TUSB_DIR_OUT) + { + USBOEPCNF_0 &= ~STALL; + } + else + { + USBIEPCNF_0 &= ~STALL; + } + } + else + { + ep_regs_t ep_regs = EP_REGS(epnum, dir); + // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt + // and bulk endpoints. + ep_regs[CNF] &= ~(STALL + TOGGLE); + } +} + +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + (void) request; + + // FIXME: Per manual, we should be clearing the NAK bits of EP0 after the + // Status Phase of a control xfer is done, in preparation of another possible + // SETUP packet. However, from my own testing, SETUP packets _are_ correctly + // handled by the USB core without clearing the NAKs. + // + // Right now, clearing NAKs in this callbacks causes a direction mismatch + // between host and device on EP0. Figure out why and come back to this. + // USBOEPCNT_0 &= ~NAK; + // USBIEPCNT_0 &= ~NAK; +} + +/*------------------------------------------------------------------*/ + +static void receive_packet(uint8_t ep_num) +{ + xfer_ctl_t * xfer = XFER_CTL_BASE(ep_num, TUSB_DIR_OUT); + ep_regs_t ep_regs = EP_REGS(ep_num, TUSB_DIR_OUT); + uint8_t xfer_size; + + if(ep_num == 0) + { + xfer_size = USBOEPCNT_0 & 0x0F; + } + else + { + xfer_size = ep_regs[BCTX] & 0x7F; + } + + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t to_recv_size; + + if(remaining <= xfer->max_size) { + // Avoid buffer overflow. + to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; + } else { + // Room for full packet, choose recv_size based on what the microcontroller + // claims. + to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; + } + +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + volatile uint8_t * ep_buf = (ep_num == 0) ? &USBOEP0BUF : (&USBSTABUFF + (ep_regs[BBAX] << 3)); + tu_fifo_write_n(xfer->ff, (const void *) ep_buf, to_recv_size); + } + else +#endif + { + uint8_t * base = (xfer->buffer + xfer->queued_len); + + if(ep_num == 0) + { + volatile uint8_t * ep0out_buf = &USBOEP0BUF; + for(uint16_t i = 0; i < to_recv_size; i++) + { + base[i] = ep0out_buf[i]; + } + } + else + { + volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3); + for(uint16_t i = 0; i < to_recv_size ; i++) + { + base[i] = ep_buf[i]; + } + } + } + + xfer->queued_len += xfer_size; + + xfer->short_packet = (xfer_size < xfer->max_size); + if((xfer->total_len == xfer->queued_len) || xfer->short_packet) + { + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } + else + { + // Schedule to receive another packet. + if(ep_num == 0) + { + USBOEPCNT_0 &= ~NAK; + } + else + { + ep_regs[BCTX] &= ~NAK; + } + } +} + +static void transmit_packet(uint8_t ep_num) +{ + xfer_ctl_t * xfer = XFER_CTL_BASE(ep_num, TUSB_DIR_IN); + + // First, determine whether we should even send a packet or finish + // up the xfer. + bool zlp = (xfer->total_len == 0); // By necessity, xfer->total_len will + // equal xfer->queued_len for ZLPs. + // Of course a ZLP is a short packet. + if((!zlp && (xfer->total_len == xfer->queued_len)) || xfer->short_packet) + { + dcd_event_xfer_complete(0, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len, XFER_RESULT_SUCCESS, true); + return; + } + + // Then actually commit to transmit a packet. + uint8_t * base = (xfer->buffer + xfer->queued_len); + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint8_t xfer_size = (xfer->max_size < xfer->total_len) ? xfer->max_size : remaining; + + xfer->queued_len += xfer_size; + if(xfer_size < xfer->max_size) + { + // Next "xfer complete interrupt", the transfer will end. + xfer->short_packet = true; + } + + if(ep_num == 0) + { + volatile uint8_t * ep0in_buf = &USBIEP0BUF; + for(uint16_t i = 0; i < xfer_size; i++) + { + ep0in_buf[i] = base[i]; + } + + USBIEPCNT_0 = (USBIEPCNT_0 & 0xF0) + xfer_size; + USBIEPCNT_0 &= ~NAK; + } + else + { + ep_regs_t ep_regs = EP_REGS(ep_num, TUSB_DIR_IN); + volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3); + +#if 0 // TODO support dcd_edpt_xfer_fifo API + if (xfer->ff) + { + tu_fifo_read_n(xfer->ff, (void *) ep_buf, xfer_size); + } + else +#endif + { + for(int i = 0; i < xfer_size; i++) + { + ep_buf[i] = base[i]; + } + } + + ep_regs[BCTX] = (ep_regs[BCTX] & 0x80) + (xfer_size & 0x7F); + ep_regs[BCTX] &= ~NAK; + } +} + +static void handle_setup_packet(void) +{ + volatile uint8_t * setup_buf = &USBSUBLK; + + for(int i = 0; i < 8; i++) + { + _setup_packet[i] = setup_buf[i]; + } + + // Clearing SETUPIFG by reading USBVECINT does not set NAK, so now that we + // have a SETUP packet, force NAKs until tinyusb can handle the SETUP + // packet and prepare for a new xfer. + USBIEPCNT_0 |= NAK; + USBOEPCNT_0 |= NAK; + dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); +} + +void dcd_int_handler(uint8_t rhport) +{ + (void) rhport; + + // Setup is special- reading USBVECINT to handle setup packets is done to + // stop hardware-generated NAKs on EP0. + uint8_t setup_status = USBIFG & SETUPIFG; + + if(setup_status) + { + handle_setup_packet(); + } + + uint16_t curr_vector = USBVECINT; + + switch(curr_vector) + { + case USBVECINT_RSTR: + bus_reset(); + dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); + break; + + // Clear the (hardware-enforced) NAK on EP 0 after a SETUP packet + // is received. At this point, even though the hardware is no longer + // forcing NAKs, the EP0 NAK bits should still be set to avoid + // sending/receiving data before tinyusb is ready. + // + // Furthermore, it's possible for the hardware to STALL in the middle of + // a control xfer if the EP0 NAK bits aren't set properly. + // See: https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/845259 + // From my testing, if all of the following hold: + // * OUT EP0 NAK is cleared. + // * IN EP0 NAK is set. + // * DIR bit in USBCTL is clear. + // and an IN packet is received on EP0, the USB core will STALL. Setting + // both EP0 NAKs manually when a SETUP packet is received, as is done + // in handle_setup_packet(), avoids meeting STALL conditions. + // + // TODO: Figure out/explain why the STALL condition can be reached in the + // first place. When I first noticed the STALL, the only two places I + // touched the NAK bits were in dcd_edpt_xfer() and to _set_ (sic) them in + // bus_reset(). SETUP packet handling should've been unaffected. + case USBVECINT_SETUP_PACKET_RECEIVED: + break; + + case USBVECINT_INPUT_ENDPOINT0: + transmit_packet(0); + break; + + case USBVECINT_OUTPUT_ENDPOINT0: + receive_packet(0); + break; + + case USBVECINT_INPUT_ENDPOINT1: + case USBVECINT_INPUT_ENDPOINT2: + case USBVECINT_INPUT_ENDPOINT3: + case USBVECINT_INPUT_ENDPOINT4: + case USBVECINT_INPUT_ENDPOINT5: + case USBVECINT_INPUT_ENDPOINT6: + case USBVECINT_INPUT_ENDPOINT7: + { + uint8_t ep = ((curr_vector - USBVECINT_INPUT_ENDPOINT1) >> 1) + 1; + transmit_packet(ep); + } + break; + + case USBVECINT_OUTPUT_ENDPOINT1: + case USBVECINT_OUTPUT_ENDPOINT2: + case USBVECINT_OUTPUT_ENDPOINT3: + case USBVECINT_OUTPUT_ENDPOINT4: + case USBVECINT_OUTPUT_ENDPOINT5: + case USBVECINT_OUTPUT_ENDPOINT6: + case USBVECINT_OUTPUT_ENDPOINT7: + { + uint8_t ep = ((curr_vector - USBVECINT_OUTPUT_ENDPOINT1) >> 1) + 1; + receive_packet(ep); + } + break; + + default: + while(true); + break; + } + +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.c b/circuitpython/lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.c new file mode 100644 index 0000000..dfadfdc --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.c @@ -0,0 +1,649 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) + +#ifndef DEBUG +#define DEBUG 0 +#endif + +#ifndef LOG_USB +#define LOG_USB 0 +#endif + +#include "device/dcd.h" +#include "dcd_eptri.h" +#include "csr.h" +#include "irq.h" +void fomu_error(uint32_t line); + +#if LOG_USB +struct usb_log { + uint8_t ep_num; + uint8_t size; + uint8_t data[66]; +}; +__attribute__((used)) +struct usb_log usb_log[128]; +__attribute__((used)) +uint8_t usb_log_offset; + +struct xfer_log { + uint8_t ep_num; + uint16_t size; +}; +__attribute__((used)) +struct xfer_log xfer_log[64]; +__attribute__((used)) +uint8_t xfer_log_offset; + +__attribute__((used)) +struct xfer_log queue_log[64]; +__attribute__((used)) +uint8_t queue_log_offset; +#endif + +//--------------------------------------------------------------------+ +// SIE Command +//--------------------------------------------------------------------+ + +#define EP_SIZE 64 + +uint16_t volatile rx_buffer_offset[16]; +uint8_t* volatile rx_buffer[16]; +uint16_t volatile rx_buffer_max[16]; + +volatile uint8_t tx_ep; +volatile bool tx_active; +volatile uint16_t tx_buffer_offset[16]; +uint8_t* volatile tx_buffer[16]; +volatile uint16_t tx_buffer_max[16]; +volatile uint8_t reset_count; + +#if DEBUG +__attribute__((used)) uint8_t volatile * last_tx_buffer; +__attribute__((used)) volatile uint8_t last_tx_ep; +uint8_t setup_packet_bfr[10]; +#endif + +//--------------------------------------------------------------------+ +// PIPE HELPER +//--------------------------------------------------------------------+ + +static bool advance_tx_ep(void) { + // Move on to the next transmit buffer in a round-robin manner + uint8_t prev_tx_ep = tx_ep; + for (tx_ep = (tx_ep + 1) & 0xf; tx_ep != prev_tx_ep; tx_ep = ((tx_ep + 1) & 0xf)) { + if (tx_buffer[tx_ep]) + return true; + } + if (!tx_buffer[tx_ep]) + return false; + return true; +} + +#if LOG_USB +void xfer_log_append(uint8_t ep_num, uint16_t sz) { + xfer_log[xfer_log_offset].ep_num = ep_num; + xfer_log[xfer_log_offset].size = sz; + xfer_log_offset++; + if (xfer_log_offset >= sizeof(xfer_log)/sizeof(*xfer_log)) + xfer_log_offset = 0; +} + +void queue_log_append(uint8_t ep_num, uint16_t sz) { + queue_log[queue_log_offset].ep_num = ep_num; + queue_log[queue_log_offset].size = sz; + queue_log_offset++; + if (queue_log_offset >= sizeof(queue_log)/sizeof(*queue_log)) + queue_log_offset = 0; +} +#endif + +static void tx_more_data(void) { + // Send more data + uint8_t added_bytes; + for (added_bytes = 0; (added_bytes < EP_SIZE) && (tx_buffer_offset[tx_ep] < tx_buffer_max[tx_ep]); added_bytes++) { +#if LOG_USB + usb_log[usb_log_offset].data[added_bytes] = tx_buffer[tx_ep][tx_buffer_offset[tx_ep]]; +#endif + usb_in_data_write(tx_buffer[tx_ep][tx_buffer_offset[tx_ep]++]); + } + +#if LOG_USB + usb_log[usb_log_offset].ep_num = tu_edpt_addr(tx_ep, TUSB_DIR_IN); + usb_log[usb_log_offset].size = added_bytes; + usb_log_offset++; + if (usb_log_offset >= sizeof(usb_log)/sizeof(*usb_log)) + usb_log_offset = 0; +#endif + + // Updating the epno queues the data + usb_in_ctrl_write(tx_ep & 0xf); +} + +static void process_tx(void) { +#if DEBUG + // If the system isn't idle, then something is very wrong. + uint8_t in_status = usb_in_status_read(); + if (!(in_status & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET))) + fomu_error(__LINE__); +#endif + + // If the buffer is now empty, search for the next buffer to fill. + if (!tx_buffer[tx_ep]) { + if (advance_tx_ep()) + tx_more_data(); + else + tx_active = false; + return; + } + + if (tx_buffer_offset[tx_ep] >= tx_buffer_max[tx_ep]) { +#if DEBUG + last_tx_buffer = tx_buffer[tx_ep]; + last_tx_ep = tx_ep; +#endif + tx_buffer[tx_ep] = NULL; + uint16_t xferred_bytes = tx_buffer_max[tx_ep]; + uint8_t xferred_ep = tx_ep; + + if (!advance_tx_ep()) + tx_active = false; +#if LOG_USB + xfer_log_append(tu_edpt_addr(xferred_ep, TUSB_DIR_IN), xferred_bytes); +#endif + dcd_event_xfer_complete(0, tu_edpt_addr(xferred_ep, TUSB_DIR_IN), xferred_bytes, XFER_RESULT_SUCCESS, true); + if (!tx_active) + return; + } + + tx_more_data(); + return; +} + +static void process_rx(void) { + uint8_t out_status = usb_out_status_read(); +#if DEBUG + // If the OUT handler is still waiting to send, don't do anything. + if (!(out_status & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET))) + fomu_error(__LINE__); + // return; +#endif + uint8_t rx_ep = (out_status >> CSR_USB_OUT_STATUS_EPNO_OFFSET) & 0xf; + + // If the destination buffer doesn't exist, don't drain the hardware + // fifo. Note that this can cause deadlocks if the host is waiting + // on some other endpoint's data! +#if DEBUG + if (rx_buffer[rx_ep] == NULL) { + fomu_error(__LINE__); + return; + } +#endif + + // Drain the FIFO into the destination buffer + uint32_t total_read = 0; + uint32_t current_offset = rx_buffer_offset[rx_ep]; +#if DEBUG + uint8_t test_buffer[256]; + memset(test_buffer, 0, sizeof(test_buffer)); + if (current_offset > rx_buffer_max[rx_ep]) + fomu_error(__LINE__); +#endif +#if LOG_USB + usb_log[usb_log_offset].ep_num = tu_edpt_addr(rx_ep, TUSB_DIR_OUT); + usb_log[usb_log_offset].size = 0; +#endif + while (usb_out_status_read() & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET)) { + uint8_t c = usb_out_data_read(); +#if DEBUG + test_buffer[total_read] = c; +#endif + total_read++; + if (current_offset < rx_buffer_max[rx_ep]) { +#if LOG_USB + usb_log[usb_log_offset].data[usb_log[usb_log_offset].size++] = c; +#endif + if (rx_buffer[rx_ep] != (volatile uint8_t *)0xffffffff) + rx_buffer[rx_ep][current_offset++] = c; + } + } +#if LOG_USB + usb_log_offset++; + if (usb_log_offset >= sizeof(usb_log)/sizeof(*usb_log)) + usb_log_offset = 0; +#endif +#if DEBUG + if (total_read > 66) + fomu_error(__LINE__); + if (total_read < 2) + total_read = 2; + // fomu_error(__LINE__); +#endif + + // Strip off the CRC16 + rx_buffer_offset[rx_ep] += (total_read - 2); + if (rx_buffer_offset[rx_ep] > rx_buffer_max[rx_ep]) + rx_buffer_offset[rx_ep] = rx_buffer_max[rx_ep]; + + // If there's no more data, complete the transfer to tinyusb + if ((rx_buffer_max[rx_ep] == rx_buffer_offset[rx_ep]) + // ZLP with less than the total amount of data + || ((total_read == 2) && ((rx_buffer_offset[rx_ep] & 63) == 0)) + // Short read, but not a full packet + || (((rx_buffer_offset[rx_ep] & 63) != 0) && (total_read < 66))) { +#if DEBUG + if (rx_buffer[rx_ep] == NULL) + fomu_error(__LINE__); +#endif + + // Free up this buffer. + rx_buffer[rx_ep] = NULL; + uint16_t len = rx_buffer_offset[rx_ep]; + +#if DEBUG + // Validate that all enabled endpoints have buffers, + // and no disabled endpoints have buffers. + uint16_t ep_en_mask = usb_out_enable_status_read(); + int i; + for (i = 0; i < 16; i++) { + if ((!!(ep_en_mask & (1 << i))) ^ (!!(rx_buffer[i]))) { + uint8_t new_status = usb_out_status_read(); + // Another IRQ came in while we were processing, so ignore this endpoint. + if ((new_status & 0x20) && ((new_status & 0xf) == i)) + continue; + fomu_error(__LINE__); + } + } +#endif +#if LOG_USB + xfer_log_append(tu_edpt_addr(rx_ep, TUSB_DIR_OUT), len); +#endif + dcd_event_xfer_complete(0, tu_edpt_addr(rx_ep, TUSB_DIR_OUT), len, XFER_RESULT_SUCCESS, true); + } + else { + // If there's more data, re-enable data reception on this endpoint + usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | rx_ep); + } + + // Now that the buffer is drained, clear the pending IRQ. + usb_out_ev_pending_write(usb_out_ev_pending_read()); +} + +//--------------------------------------------------------------------+ +// CONTROLLER API +//--------------------------------------------------------------------+ + +static void dcd_reset(void) +{ + reset_count++; + usb_setup_ev_enable_write(0); + usb_in_ev_enable_write(0); + usb_out_ev_enable_write(0); + + usb_address_write(0); + + // Reset all three FIFO handlers + usb_setup_ctrl_write(1 << CSR_USB_SETUP_CTRL_RESET_OFFSET); + usb_in_ctrl_write(1 << CSR_USB_IN_CTRL_RESET_OFFSET); + usb_out_ctrl_write(1 << CSR_USB_OUT_CTRL_RESET_OFFSET); + + memset((void *)(uintptr_t) rx_buffer, 0, sizeof(rx_buffer)); + memset((void *)(uintptr_t) rx_buffer_max, 0, sizeof(rx_buffer_max)); + memset((void *)(uintptr_t) rx_buffer_offset, 0, sizeof(rx_buffer_offset)); + + memset((void *)(uintptr_t) tx_buffer, 0, sizeof(tx_buffer)); + memset((void *)(uintptr_t) tx_buffer_max, 0, sizeof(tx_buffer_max)); + memset((void *)(uintptr_t) tx_buffer_offset, 0, sizeof(tx_buffer_offset)); + tx_ep = 0; + tx_active = false; + + // Enable all event handlers and clear their contents + usb_setup_ev_pending_write(0xff); + usb_in_ev_pending_write(0xff); + usb_out_ev_pending_write(0xff); + usb_in_ev_enable_write(1); + usb_out_ev_enable_write(1); + usb_setup_ev_enable_write(3); + + dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); +} + +// Initializes the USB peripheral for device mode and enables it. +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + usb_pullup_out_write(0); + + // Enable all event handlers and clear their contents + usb_setup_ev_pending_write(usb_setup_ev_pending_read()); + usb_in_ev_pending_write(usb_in_ev_pending_read()); + usb_out_ev_pending_write(usb_out_ev_pending_read()); + usb_in_ev_enable_write(1); + usb_out_ev_enable_write(1); + usb_setup_ev_enable_write(3); + + // Turn on the external pullup + usb_pullup_out_write(1); +} + +// Enables or disables the USB device interrupt(s). May be used to +// prevent concurrency issues when mutating data structures shared +// between main code and the interrupt handler. +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + irq_setmask(irq_getmask() | (1 << USB_INTERRUPT)); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + irq_setmask(irq_getmask() & ~(1 << USB_INTERRUPT)); +} + +// Called when the device is given a new bus address. +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + // Respond with ACK status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + // Wait for the response packet to get sent + while (tx_active) + ; + + // Activate the new address + usb_address_write(dev_addr); +} + +// Called to remote wake up host when suspended (e.g hid keyboard) +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + usb_pullup_out_write(1); +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + usb_pullup_out_write(0); +} + + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void) rhport; + uint8_t ep_num = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t ep_dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + + if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) + return false; // Not supported + + if (ep_dir == TUSB_DIR_OUT) { + rx_buffer_offset[ep_num] = 0; + rx_buffer_max[ep_num] = 0; + rx_buffer[ep_num] = NULL; + } + + else if (ep_dir == TUSB_DIR_IN) { + tx_buffer_offset[ep_num] = 0; + tx_buffer_max[ep_num] = 0; + tx_buffer[ep_num] = NULL; + } + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + // TODO implement dcd_edpt_close_all() +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) { + uint8_t enable = 0; + if (rx_buffer[ep_addr]) + enable = 1; + usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr)); + } + else + usb_in_ctrl_write((1 << CSR_USB_IN_CTRL_STALL_OFFSET) | tu_edpt_number(ep_addr)); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) { + uint8_t enable = 0; + if (rx_buffer[ep_addr]) + enable = 1; + usb_out_ctrl_write((0 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr)); + } + // IN endpoints will get unstalled when more data is written. +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) +{ + (void)rhport; + uint8_t ep_num = tu_edpt_number(ep_addr); + uint8_t ep_dir = tu_edpt_dir(ep_addr); + TU_ASSERT(ep_num < 16); + + // Give a nonzero buffer when we transmit 0 bytes, so that the + // system doesn't think the endpoint is idle. + if ((buffer == NULL) && (total_bytes == 0)) { + buffer = (uint8_t *)0xffffffff; + } + + TU_ASSERT(buffer != NULL); + + if (ep_dir == TUSB_DIR_IN) { + // Wait for the tx pipe to free up + uint8_t previous_reset_count = reset_count; + // Continue until the buffer is empty, the system is idle, and the fifo is empty. + while (tx_buffer[ep_num] != NULL) + ; + + dcd_int_disable(0); +#if LOG_USB + queue_log_append(ep_addr, total_bytes); +#endif + // If a reset happens while we're waiting, abort the transfer + if (previous_reset_count != reset_count) + return true; + + TU_ASSERT(tx_buffer[ep_num] == NULL); + tx_buffer_offset[ep_num] = 0; + tx_buffer_max[ep_num] = total_bytes; + tx_buffer[ep_num] = buffer; + + // If the current buffer is NULL, then that means the tx logic is idle. + // Update the tx_ep to point to our endpoint number and queue the data. + // Otherwise, let it be and it'll get picked up after the next transfer + // finishes. + if (!tx_active) { + tx_ep = ep_num; + tx_active = true; + tx_more_data(); + } + dcd_int_enable(0); + } + + else if (ep_dir == TUSB_DIR_OUT) { + while (rx_buffer[ep_num] != NULL) + ; + + TU_ASSERT(rx_buffer[ep_num] == NULL); + dcd_int_disable(0); +#if LOG_USB + queue_log_append(ep_addr, total_bytes); +#endif + rx_buffer[ep_num] = buffer; + rx_buffer_offset[ep_num] = 0; + rx_buffer_max[ep_num] = total_bytes; + + // Enable receiving on this particular endpoint + usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | ep_num); +#if DEBUG + uint16_t ep_en_mask = usb_out_enable_status_read(); + int i; + for (i = 0; i < 16; i++) { + if ((!!(ep_en_mask & (1 << i))) ^ (!!(rx_buffer[i]))) { + if (rx_buffer[i] && usb_out_ev_pending_read() && (usb_out_status_read() & 0xf) == i) + continue; + fomu_error(__LINE__); + } + } +#endif + dcd_int_enable(0); + } + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ + +static void handle_out(void) +{ + // An "OUT" transaction just completed so we have new data. + // (But only if we can accept the data) +#if DEBUG + if (!usb_out_ev_pending_read()) + fomu_error(__LINE__); + if (!usb_out_ev_enable_read()) + fomu_error(__LINE__); +#endif + process_rx(); +} + +static void handle_in(void) +{ +#if DEBUG + if (!usb_in_ev_pending_read()) + fomu_error(__LINE__); + if (!usb_in_ev_enable_read()) + fomu_error(__LINE__); +#endif + usb_in_ev_pending_write(usb_in_ev_pending_read()); + process_tx(); +} + +static void handle_reset(void) +{ +#if DEBUG + uint8_t setup_pending = usb_setup_ev_pending_read() & usb_setup_ev_enable_read(); + if (!(setup_pending & 2)) + fomu_error(__LINE__); +#endif + usb_setup_ev_pending_write(2); + + // This event means a bus reset occurred. Reset everything, and + // abandon any further processing. + dcd_reset(); +} + +static void handle_setup(void) +{ +#if !DEBUG + uint8_t setup_packet_bfr[10]; +#endif + +#if DEBUG + uint8_t setup_pending = usb_setup_ev_pending_read() & usb_setup_ev_enable_read(); + if (!(setup_pending & 1)) + fomu_error(__LINE__); +#endif + + // We got a SETUP packet. Copy it to the setup buffer and clear + // the "pending" bit. + // Setup packets are always 8 bytes, plus two bytes of crc16. + uint32_t setup_length = 0; + +#if DEBUG + if (!(usb_setup_status_read() & (1 << CSR_USB_SETUP_STATUS_HAVE_OFFSET))) + fomu_error(__LINE__); +#endif + + while (usb_setup_status_read() & (1 << CSR_USB_SETUP_STATUS_HAVE_OFFSET)) { + uint8_t c = usb_setup_data_read(); + if (setup_length < sizeof(setup_packet_bfr)) + setup_packet_bfr[setup_length] = c; + setup_length++; + } + + // If we have 10 bytes, that's a full SETUP packet plus CRC16. + // Otherwise, it was an RX error. + if (setup_length == 10) { + dcd_event_setup_received(0, setup_packet_bfr, true); + } +#if DEBUG + else { + fomu_error(__LINE__); + } +#endif + + usb_setup_ev_pending_write(1); +} +void dcd_int_handler(uint8_t rhport) +{ + (void)rhport; + uint8_t next_ev; + while ((next_ev = usb_next_ev_read())) { + switch (next_ev) { + case 1 << CSR_USB_NEXT_EV_IN_OFFSET: + handle_in(); + break; + case 1 << CSR_USB_NEXT_EV_OUT_OFFSET: + handle_out(); + break; + case 1 << CSR_USB_NEXT_EV_SETUP_OFFSET: + handle_setup(); + break; + case 1 << CSR_USB_NEXT_EV_RESET_OFFSET: + handle_reset(); + break; + } + } +} + +#endif diff --git a/circuitpython/lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.h b/circuitpython/lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.h new file mode 100644 index 0000000..0fa6ecc --- /dev/null +++ b/circuitpython/lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.h @@ -0,0 +1,39 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_DCD_VALENTYUSB_EPTRI_H_ +#define _TUSB_DCD_VALENTYUSB_EPTRI_H_ + +#include "common/tusb_common.h" +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_DCD_VALENTYUSB_EPTRI_H_ */ diff --git a/circuitpython/lib/tinyusb/src/tusb.c b/circuitpython/lib/tinyusb/src/tusb.c new file mode 100644 index 0000000..a302210 --- /dev/null +++ b/circuitpython/lib/tinyusb/src/tusb.c @@ -0,0 +1,247 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED || CFG_TUD_ENABLED + +#include "tusb.h" + +// TODO clean up +#if CFG_TUD_ENABLED +#include "device/usbd_pvt.h" +#endif + +bool tusb_init(void) +{ +#if CFG_TUD_ENABLED + TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); // init device stack +#endif + +#if CFG_TUH_ENABLED + TU_ASSERT( tuh_init(TUH_OPT_RHPORT) ); // init host stack +#endif + + return true; +} + +bool tusb_inited(void) +{ + bool ret = false; + +#if CFG_TUD_ENABLED + ret = ret || tud_inited(); +#endif + +#if CFG_TUH_ENABLED + ret = ret || tuh_inited(); +#endif + + return ret; +} + +//--------------------------------------------------------------------+ +// Internal Helper for both Host and Device stack +//--------------------------------------------------------------------+ + +bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed) +{ + uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep); + TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size); + + switch (desc_ep->bmAttributes.xfer) + { + case TUSB_XFER_ISOCHRONOUS: + { + uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023); + TU_ASSERT(max_packet_size <= spec_size); + } + break; + + case TUSB_XFER_BULK: + if (speed == TUSB_SPEED_HIGH) + { + // Bulk highspeed must be EXACTLY 512 + TU_ASSERT(max_packet_size == 512); + }else + { + // TODO Bulk fullspeed can only be 8, 16, 32, 64 + TU_ASSERT(max_packet_size <= 64); + } + break; + + case TUSB_XFER_INTERRUPT: + { + uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64); + TU_ASSERT(max_packet_size <= spec_size); + } + break; + + default: return false; + } + + return true; +} + +void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, uint8_t driver_id) +{ + uint8_t const* p_desc = (uint8_t const*) desc_itf; + uint8_t const* desc_end = p_desc + desc_len; + + while( p_desc < desc_end ) + { + if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) + { + uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; + + TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id); + ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id; + } + + p_desc = tu_desc_next(p_desc); + } +} + +uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) +{ + uint8_t const* p_desc = (uint8_t const*) desc_itf; + uint16_t len = 0; + + while (itf_count--) + { + // Next on interface desc + len += tu_desc_len(desc_itf); + p_desc = tu_desc_next(p_desc); + + while (len < max_len) + { + // return on IAD regardless of itf count + if ( tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len; + + if ( (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && + ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0 ) + { + break; + } + + len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + } + + return len; +} + +/*------------------------------------------------------------------*/ +/* Debug + *------------------------------------------------------------------*/ +#if CFG_TUSB_DEBUG +#include + +char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) }; + +char const* const tusb_speed_str[] = { "Full", "Low", "High" }; + +static void dump_str_line(uint8_t const* buf, uint16_t count) +{ + tu_printf(" |"); + + // each line is 16 bytes + for(uint16_t i=0; i 64 + #error Control Endpoint Max Packet Size cannot be larger than 64 +#endif + +#endif /* _TUSB_OPTION_H_ */ + +/** @} */ diff --git a/circuitpython/lib/tinyusb/test/ceedling b/circuitpython/lib/tinyusb/test/ceedling new file mode 100644 index 0000000..5393085 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/ceedling @@ -0,0 +1,3 @@ +#!/bin/bash + +ruby vendor/ceedling/bin/ceedling $* diff --git a/circuitpython/lib/tinyusb/test/project.yml b/circuitpython/lib/tinyusb/test/project.yml new file mode 100644 index 0000000..dc4a9cb --- /dev/null +++ b/circuitpython/lib/tinyusb/test/project.yml @@ -0,0 +1,106 @@ +--- + +# Notes: +# Sample project C code is not presently written to produce a release artifact. +# As such, release build options are disabled. +# This sample, therefore, only demonstrates running a collection of unit tests. + +:project: + :use_exceptions: TRUE + :use_mocks: TRUE + :use_test_preprocessor: TRUE + :use_auxiliary_dependencies: TRUE + :use_deep_dependencies: TRUE + :build_root: _build +# :release_build: TRUE + :test_file_prefix: test_ + :which_ceedling: vendor/ceedling + :default_tasks: + - test:all + +#:test_build: +# :use_assembly: TRUE + +#:release_build: +# :output: MyApp.out +# :use_assembly: FALSE + +:environment: + +:extension: + :executable: .out + +:paths: + :test: + - +:test/** + - -:test/support + :source: + - ../src/** + :support: + - test/support + +:defines: + # in order to add common defines: + # 1) remove the trailing [] from the :common: section + # 2) add entries to the :common: section (e.g. :test: has TEST defined) + :common: &common_defines + - _UNITY_TEST_ + :test: + - *common_defines + :test_preprocess: + - *common_defines + +:cmock: + :mock_prefix: mock_ + :when_no_prototypes: :warn + :enforce_strict_ordering: TRUE + :plugins: + - :ignore + - :ignore_arg + - :return_thru_ptr + - :callback + - :array + :treat_as: + uint8: HEX8 + uint16: HEX16 + uint32: UINT32 + int8: INT8 + bool: UINT8 + +# Add -gcov to the plugins list to make sure of the gcov plugin +# You will need to have gcov and gcovr both installed to make it work. +# For more information on these options, see docs in plugins/gcov +:gcov: + :html_report: TRUE + :html_report_type: detailed + :html_medium_threshold: 75 + :html_high_threshold: 90 + :xml_report: FALSE + +#:tools: +# Ceedling defaults to using gcc for compiling, linking, etc. +# As [:tools] is blank, gcc will be used (so long as it's in your system path) +# See documentation to configure a given toolchain for use + +# LIBRARIES +# These libraries are automatically injected into the build process. Those specified as +# common will be used in all types of builds. Otherwise, libraries can be injected in just +# tests or releases. These options are MERGED with the options in supplemental yaml files. +:libraries: + :placement: :end + :flag: "${1}" # or "-L ${1}" for example + :common: &common_libraries [] + :test: + - *common_libraries + :release: + - *common_libraries + +:plugins: + :load_paths: + - vendor/ceedling/plugins + :enabled: + - stdout_pretty_tests_report + - module_generator + - raw_output_report + - colour_report +... diff --git a/circuitpython/lib/tinyusb/test/test/device/msc/test_msc_device.c b/circuitpython/lib/tinyusb/test/test/device/msc/test_msc_device.c new file mode 100644 index 0000000..00bb86c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/test/device/msc/test_msc_device.c @@ -0,0 +1,273 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + + +#include "unity.h" + +// Files to test +#include "tusb_fifo.h" +#include "tusb.h" +#include "usbd.h" +TEST_FILE("usbd_control.c") +TEST_FILE("msc_device.c") + +// Mock File +#include "mock_dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +enum +{ + EDPT_CTRL_OUT = 0x00, + EDPT_CTRL_IN = 0x80, + + EDPT_MSC_OUT = 0x01, + EDPT_MSC_IN = 0x81, +}; + +uint8_t const rhport = 0; + +enum +{ + ITF_NUM_MSC, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN) + +uint8_t const data_desc_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), +}; + +tusb_control_request_t const request_set_configuration = +{ + .bmRequestType = 0x00, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = 1, + .wIndex = 0, + .wLength = 0 +}; + +uint8_t const* desc_configuration; + + +enum +{ + DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount + DISK_BLOCK_SIZE = 512 +}; + +uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE]; + +// Invoked when received SCSI_CMD_INQUIRY +// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively +void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) +{ + (void) lun; + + const char vid[] = "TinyUSB"; + const char pid[] = "Mass Storage"; + const char rev[] = "1.0"; + + memcpy(vendor_id , vid, strlen(vid)); + memcpy(product_id , pid, strlen(pid)); + memcpy(product_rev, rev, strlen(rev)); +} + +// Invoked when received Test Unit Ready command. +// return true allowing host to read/write this LUN e.g SD card inserted +bool tud_msc_test_unit_ready_cb(uint8_t lun) +{ + (void) lun; + + return true; // RAM disk is always ready +} + +// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size +// Application update block count and block size +void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) +{ + (void) lun; + + *block_count = DISK_BLOCK_NUM; + *block_size = DISK_BLOCK_SIZE; +} + +// Invoked when received Start Stop Unit command +// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage +// - Start = 1 : active mode, if load_eject = 1 : load disk storage +bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) +{ + (void) lun; + (void) power_condition; + + return true; +} + +// Callback invoked when received READ10 command. +// Copy disk's data to buffer (up to bufsize) and return number of copied bytes. +int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) +{ + (void) lun; + + uint8_t const* addr = msc_disk[lba] + offset; + memcpy(buffer, addr, bufsize); + + return bufsize; +} + +// Callback invoked when received WRITE10 command. +// Process data in buffer to disk's storage and return number of written bytes +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) +{ + (void) lun; + + uint8_t* addr = msc_disk[lba] + offset; + memcpy(addr, buffer, bufsize); + + return bufsize; +} + +// Callback invoked when received an SCSI command not in built-in list below +// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE +// - READ10 and WRITE10 has their own callbacks +int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) +{ + // read10 & write10 has their own callback and MUST not be handled here + + void const* response = NULL; + uint16_t resplen = 0; + + return resplen; +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +uint8_t const * tud_descriptor_device_cb(void) +{ + return NULL; +} + +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + return desc_configuration; +} + +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + (void) langid; + + return NULL; +} + +void setUp(void) +{ + dcd_int_disable_Ignore(); + dcd_int_enable_Ignore(); + + if ( !tusb_inited() ) + { + dcd_init_Expect(rhport); + tusb_init(); + } + + dcd_event_bus_reset(rhport, TUSB_SPEED_HIGH, false); + tud_task(); +} + +void tearDown(void) +{ +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +void test_msc(void) +{ + // Read 1 LBA = 0, Block count = 1 + msc_cbw_t cbw_read10 = + { + .signature = MSC_CBW_SIGNATURE, + .tag = 0xCAFECAFE, + .total_bytes = 512, + .lun = 0, + .dir = TUSB_DIR_IN_MASK, + .cmd_len = sizeof(scsi_read10_t) + }; + + scsi_read10_t cmd_read10 = + { + .cmd_code = SCSI_CMD_READ_10, + .lba = tu_htonl(0), + .block_count = tu_htons(1) + }; + + memcpy(cbw_read10.command, &cmd_read10, cbw_read10.cmd_len); + + desc_configuration = data_desc_configuration; + uint8_t const* desc_ep = tu_desc_next(tu_desc_next(desc_configuration)); + + dcd_event_setup_received(rhport, (uint8_t*) &request_set_configuration, false); + + // open endpoints + dcd_edpt_open_ExpectAndReturn(rhport, (tusb_desc_endpoint_t const *) desc_ep, true); + dcd_edpt_open_ExpectAndReturn(rhport, (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep), true); + + // Prepare SCSI command + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_OUT, NULL, sizeof(msc_cbw_t), true); + dcd_edpt_xfer_IgnoreArg_buffer(); + dcd_edpt_xfer_ReturnMemThruPtr_buffer( (uint8_t*) &cbw_read10, sizeof(msc_cbw_t)); + + // command received + dcd_event_xfer_complete(rhport, EDPT_MSC_OUT, sizeof(msc_cbw_t), 0, true); + + // control status + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_IN, NULL, 0, true); + + // SCSI Data transfer + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_IN, NULL, 512, true); + dcd_edpt_xfer_IgnoreArg_buffer(); + dcd_event_xfer_complete(rhport, EDPT_MSC_IN, 512, 0, true); // complete + + // SCSI Status + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_IN, NULL, 13, true); + dcd_edpt_xfer_IgnoreArg_buffer(); + dcd_event_xfer_complete(rhport, EDPT_MSC_IN, 13, 0, true); + + // Prepare for next command + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_OUT, NULL, sizeof(msc_cbw_t), true); + dcd_edpt_xfer_IgnoreArg_buffer(); + + tud_task(); +} diff --git a/circuitpython/lib/tinyusb/test/test/device/usbd/test_usbd.c b/circuitpython/lib/tinyusb/test/test/device/usbd/test_usbd.c new file mode 100644 index 0000000..c90383b --- /dev/null +++ b/circuitpython/lib/tinyusb/test/test/device/usbd/test_usbd.c @@ -0,0 +1,243 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, Ha Thach (tinyusb.org) + * + * 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 "unity.h" + +// Files to test +#include "tusb_fifo.h" +#include "tusb.h" +#include "usbd.h" +TEST_FILE("usbd_control.c") + +// Mock File +#include "mock_dcd.h" +#include "mock_msc_device.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +enum +{ + EDPT_CTRL_OUT = 0x00, + EDPT_CTRL_IN = 0x80 +}; + +uint8_t const rhport = 0; + +tusb_desc_device_t const data_desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = 0xCafe, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +uint8_t const data_desc_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, 0, 0, TUD_CONFIG_DESC_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), +}; + +tusb_control_request_t const req_get_desc_device = +{ + .bmRequestType = 0x80, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = (TUSB_DESC_DEVICE << 8), + .wIndex = 0x0000, + .wLength = 64 +}; + +tusb_control_request_t const req_get_desc_configuration = +{ + .bmRequestType = 0x80, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = (TUSB_DESC_CONFIGURATION << 8), + .wIndex = 0x0000, + .wLength = 256 +}; + +uint8_t const* desc_device; +uint8_t const* desc_configuration; + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +uint8_t const * tud_descriptor_device_cb(void) +{ + return desc_device; +} + +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + return desc_configuration; +} + +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + (void) langid; + + return NULL; +} + +void setUp(void) +{ + dcd_int_disable_Ignore(); + dcd_int_enable_Ignore(); + + if ( !tusb_inited() ) + { + mscd_init_Expect(); + dcd_init_Expect(rhport); + tusb_init(); + } +} + +void tearDown(void) +{ +} + +//--------------------------------------------------------------------+ +// Get Descriptor +//--------------------------------------------------------------------+ + +//------------- Device -------------// +void test_usbd_get_device_descriptor(void) +{ + desc_device = (uint8_t const *) &data_desc_device; + dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_device, false); + + // data + dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, 0x80, (uint8_t*)&data_desc_device, sizeof(tusb_desc_device_t), sizeof(tusb_desc_device_t), true); + dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, sizeof(tusb_desc_device_t), 0, false); + + // status + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_OUT, NULL, 0, true); + dcd_event_xfer_complete(rhport, EDPT_CTRL_OUT, 0, 0, false); + dcd_edpt0_status_complete_ExpectWithArray(rhport, &req_get_desc_device, 1); + + tud_task(); +} + +void test_usbd_get_device_descriptor_null(void) +{ + desc_device = NULL; + + dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_device, false); + + dcd_edpt_stall_Expect(rhport, EDPT_CTRL_OUT); + dcd_edpt_stall_Expect(rhport, EDPT_CTRL_IN); + + tud_task(); +} + +//------------- Configuration -------------// + +void test_usbd_get_configuration_descriptor(void) +{ + desc_configuration = data_desc_configuration; + uint16_t total_len = ((tusb_desc_configuration_t const*) data_desc_configuration)->wTotalLength; + + dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_configuration, false); + + // data + dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, 0x80, (uint8_t*) data_desc_configuration, total_len, total_len, true); + dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, total_len, 0, false); + + // status + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_OUT, NULL, 0, true); + dcd_event_xfer_complete(rhport, EDPT_CTRL_OUT, 0, 0, false); + dcd_edpt0_status_complete_ExpectWithArray(rhport, &req_get_desc_configuration, 1); + + tud_task(); +} + +void test_usbd_get_configuration_descriptor_null(void) +{ + desc_configuration = NULL; + dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_configuration, false); + + dcd_edpt_stall_Expect(rhport, EDPT_CTRL_OUT); + dcd_edpt_stall_Expect(rhport, EDPT_CTRL_IN); + + tud_task(); +} + +//--------------------------------------------------------------------+ +// Control ZLP +//--------------------------------------------------------------------+ + +void test_usbd_control_in_zlp(void) +{ + // 128 byte total len, with EP0 size = 64, and request length = 256 + // ZLP must be return + uint8_t zlp_desc_configuration[CFG_TUD_ENDPOINT0_SIZE*2] = + { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, 0, 0, CFG_TUD_ENDPOINT0_SIZE*2, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + }; + + desc_configuration = zlp_desc_configuration; + + // request, then 1st, 2nd xact + ZLP + status + dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_configuration, false); + + // 1st transaction + dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, EDPT_CTRL_IN, + zlp_desc_configuration, CFG_TUD_ENDPOINT0_SIZE, CFG_TUD_ENDPOINT0_SIZE, true); + dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, CFG_TUD_ENDPOINT0_SIZE, 0, false); + + // 2nd transaction + dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, EDPT_CTRL_IN, + zlp_desc_configuration + CFG_TUD_ENDPOINT0_SIZE, CFG_TUD_ENDPOINT0_SIZE, CFG_TUD_ENDPOINT0_SIZE, true); + dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, CFG_TUD_ENDPOINT0_SIZE, 0, false); + + // Expect Zero length Packet + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_IN, NULL, 0, true); + dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, 0, 0, false); + + // Status + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_OUT, NULL, 0, true); + dcd_event_xfer_complete(rhport, EDPT_CTRL_OUT, 0, 0, false); + dcd_edpt0_status_complete_ExpectWithArray(rhport, &req_get_desc_configuration, 1); + + tud_task(); +} diff --git a/circuitpython/lib/tinyusb/test/test/support/tusb_config.h b/circuitpython/lib/tinyusb/test/test/support/tusb_config.h new file mode 100644 index 0000000..0455f93 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/test/support/tusb_config.h @@ -0,0 +1,106 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +// testing framework +#include "unity.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + //#error CFG_TUSB_MCU must be defined + #define CFG_TUSB_MCU OPT_MCU_NRF5X +#endif + +#ifndef CFG_TUSB_RHPORT0_MODE +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#endif + +#define CFG_TUSB_OS OPT_OS_NONE + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUD_TASK_QUEUE_SZ 100 +#define CFG_TUD_ENDPOINT0_SIZE 64 + +//------------- CLASS -------------// +//#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 1 +//#define CFG_TUD_HID 0 +//#define CFG_TUD_MIDI 0 +//#define CFG_TUD_VENDOR 0 + +//------------- CDC -------------// + +// FIFO size of CDC TX and RX +#define CFG_TUD_CDC_RX_BUFSIZE 512 +#define CFG_TUD_CDC_TX_BUFSIZE 512 + +//------------- MSC -------------// + +// Buffer size of Device Mass storage +#define CFG_TUD_MSC_BUFSIZE 512 + +//------------- HID -------------// + +// Should be sufficient to hold ID (if any) + Data +#define CFG_TUD_HID_EP_BUFSIZE 64 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/circuitpython/lib/tinyusb/test/test/test_fifo.c b/circuitpython/lib/tinyusb/test/test/test_fifo.c new file mode 100644 index 0000000..0a5f4d3 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/test/test_fifo.c @@ -0,0 +1,318 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include +#include "unity.h" +#include "tusb_fifo.h" + +#define FIFO_SIZE 10 +TU_FIFO_DEF(tu_ff, FIFO_SIZE, uint8_t, false); +tu_fifo_t* ff = &tu_ff; +tu_fifo_buffer_info_t info; + +void setUp(void) +{ + tu_fifo_clear(ff); + memset(&info, 0, sizeof(tu_fifo_buffer_info_t)); +} + +void tearDown(void) +{ +} + +//--------------------------------------------------------------------+ +// Tests +//--------------------------------------------------------------------+ +void test_normal(void) +{ + for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &i); + + for(uint8_t i=0; i < FIFO_SIZE; i++) + { + uint8_t c; + tu_fifo_read(ff, &c); + TEST_ASSERT_EQUAL(i, c); + } +} + +void test_item_size(void) +{ + TU_FIFO_DEF(ff4, FIFO_SIZE, uint32_t, false); + tu_fifo_clear(&ff4); + + uint32_t data[20]; + for(uint32_t i=0; i 4 + rd_count = tu_fifo_read_n(&ff4, rd, 5); + TEST_ASSERT_EQUAL( 5, rd_count ); + TEST_ASSERT_EQUAL_UINT32_ARRAY( data, rd, rd_count ); // 0 -> 4 + + tu_fifo_write_n(&ff4, data+10, 5); + + // read 5 -> 14 + rd_count = tu_fifo_read_n(&ff4, rd, 10); + TEST_ASSERT_EQUAL( 10, rd_count ); + TEST_ASSERT_EQUAL_UINT32_ARRAY( data+5, rd, rd_count ); // 5 -> 14 +} + +void test_read_n(void) +{ + // prepare data + uint8_t data[20]; + for(int i=0; i 4 + rd_count = tu_fifo_read_n(ff, rd, 5); + TEST_ASSERT_EQUAL( 5, rd_count ); + TEST_ASSERT_EQUAL_MEMORY( data, rd, rd_count ); // 0 -> 4 + + // case 2: Read index + count > depth + // write 10, 11, 12 + tu_fifo_write(ff, data+10); + tu_fifo_write(ff, data+11); + tu_fifo_write(ff, data+12); + + rd_count = tu_fifo_read_n(ff, rd, 7); + TEST_ASSERT_EQUAL( 7, rd_count ); + + TEST_ASSERT_EQUAL_MEMORY( data+5, rd, rd_count ); // 5 -> 11 + + // Should only read until empty + TEST_ASSERT_EQUAL( 1, tu_fifo_read_n(ff, rd, 100) ); +} + +void test_write_n(void) +{ + // prepare data + uint8_t data[20]; + for(int i=0; i 4 + + // case 2: wr + count > depth + tu_fifo_write_n(ff, data+8, 6); // wr = 3, count = 9 + + for(rd_count=0; rd_count<7; rd_count++) tu_fifo_read(ff, rd+rd_count); // wr = 3, count = 2 + + TEST_ASSERT_EQUAL_MEMORY( data+5, rd, rd_count); // 5 -> 11 + + TEST_ASSERT_EQUAL(2, tu_fifo_count(ff)); +} + +void test_peek(void) +{ + uint8_t temp; + + temp = 10; tu_fifo_write(ff, &temp); + temp = 20; tu_fifo_write(ff, &temp); + temp = 30; tu_fifo_write(ff, &temp); + + temp = 0; + + tu_fifo_peek(ff, &temp); + TEST_ASSERT_EQUAL(10, temp); + + tu_fifo_read(ff, &temp); + tu_fifo_read(ff, &temp); + + tu_fifo_peek(ff, &temp); + TEST_ASSERT_EQUAL(30, temp); +} + +void test_get_read_info_when_no_wrap() +{ + uint8_t ch = 1; + + // write 6 items + for(uint8_t i=0; i < 6; i++) tu_fifo_write(ff, &ch); + + // read 2 items + tu_fifo_read(ff, &ch); + tu_fifo_read(ff, &ch); + + tu_fifo_get_read_info(ff, &info); + + TEST_ASSERT_EQUAL(4, info.len_lin); + TEST_ASSERT_EQUAL(0, info.len_wrap); + + TEST_ASSERT_EQUAL_PTR(ff->buffer+2, info.ptr_lin); + TEST_ASSERT_NULL(info.ptr_wrap); +} + +void test_get_read_info_when_wrapped() +{ + uint8_t ch = 1; + + // make fifo full + for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &ch); + + // read 6 items + for(uint8_t i=0; i < 6; i++) tu_fifo_read(ff, &ch); + + // write 2 items + tu_fifo_write(ff, &ch); + tu_fifo_write(ff, &ch); + + tu_fifo_get_read_info(ff, &info); + + TEST_ASSERT_EQUAL(FIFO_SIZE-6, info.len_lin); + TEST_ASSERT_EQUAL(2, info.len_wrap); + + TEST_ASSERT_EQUAL_PTR(ff->buffer+6, info.ptr_lin); + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap); +} + +void test_get_write_info_when_no_wrap() +{ + uint8_t ch = 1; + + // write 2 items + tu_fifo_write(ff, &ch); + tu_fifo_write(ff, &ch); + + tu_fifo_get_write_info(ff, &info); + + TEST_ASSERT_EQUAL(FIFO_SIZE-2, info.len_lin); + TEST_ASSERT_EQUAL(0, info.len_wrap); + + TEST_ASSERT_EQUAL_PTR(ff->buffer+2, info .ptr_lin); + // application should check len instead of ptr. + // TEST_ASSERT_NULL(info.ptr_wrap); +} + +void test_get_write_info_when_wrapped() +{ + uint8_t ch = 1; + + // write 6 items + for(uint8_t i=0; i < 6; i++) tu_fifo_write(ff, &ch); + + // read 2 items + tu_fifo_read(ff, &ch); + tu_fifo_read(ff, &ch); + + tu_fifo_get_write_info(ff, &info); + + TEST_ASSERT_EQUAL(FIFO_SIZE-6, info.len_lin); + TEST_ASSERT_EQUAL(2, info.len_wrap); + + TEST_ASSERT_EQUAL_PTR(ff->buffer+6, info .ptr_lin); + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap); +} + +void test_empty(void) +{ + uint8_t temp; + TEST_ASSERT_TRUE(tu_fifo_empty(ff)); + + // read info + tu_fifo_get_read_info(ff, &info); + + TEST_ASSERT_EQUAL(0, info.len_lin); + TEST_ASSERT_EQUAL(0, info.len_wrap); + + TEST_ASSERT_NULL(info.ptr_lin); + TEST_ASSERT_NULL(info.ptr_wrap); + + // write info + tu_fifo_get_write_info(ff, &info); + + TEST_ASSERT_EQUAL(FIFO_SIZE, info.len_lin); + TEST_ASSERT_EQUAL(0, info.len_wrap); + + TEST_ASSERT_EQUAL_PTR(ff->buffer, info .ptr_lin); + // application should check len instead of ptr. + // TEST_ASSERT_NULL(info.ptr_wrap); + + // write 1 then re-check empty + tu_fifo_write(ff, &temp); + TEST_ASSERT_FALSE(tu_fifo_empty(ff)); +} + +void test_full(void) +{ + TEST_ASSERT_FALSE(tu_fifo_full(ff)); + + for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &i); + + TEST_ASSERT_TRUE(tu_fifo_full(ff)); + + // read info + tu_fifo_get_read_info(ff, &info); + + TEST_ASSERT_EQUAL(FIFO_SIZE, info.len_lin); + TEST_ASSERT_EQUAL(0, info.len_wrap); + + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_lin); + // skip this, application must check len instead of buffer + // TEST_ASSERT_NULL(info.ptr_wrap); + + // write info +} + +void test_rd_idx_wrap() +{ + tu_fifo_t ff10; + uint8_t buf[10]; + uint8_t dst[10]; + + tu_fifo_config(&ff10, buf, 10, 1, 1); + + uint16_t n; + + ff10.wr_idx = 6; + ff10.rd_idx = 15; + + n = tu_fifo_read_n(&ff10, dst, 4); + TEST_ASSERT_EQUAL(n, 4); + TEST_ASSERT_EQUAL(ff10.rd_idx, 0); + n = tu_fifo_read_n(&ff10, dst, 4); + TEST_ASSERT_EQUAL(n, 4); + TEST_ASSERT_EQUAL(ff10.rd_idx, 4); + n = tu_fifo_read_n(&ff10, dst, 4); + TEST_ASSERT_EQUAL(n, 2); + TEST_ASSERT_EQUAL(ff10.rd_idx, 6); +} \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/bin/ceedling b/circuitpython/lib/tinyusb/test/vendor/ceedling/bin/ceedling new file mode 100644 index 0000000..fa09959 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/bin/ceedling @@ -0,0 +1,337 @@ +#!/usr/bin/env ruby + +#these are always used +require 'rubygems' +require 'fileutils' + +# Check for the main project file (either the one defined in the ENV or the default) +main_filepath = ENV['CEEDLING_MAIN_PROJECT_FILE'] +project_found = (!main_filepath.nil? && File.exists?(main_filepath)) +if (!project_found) + main_filepath = "project.yml" + project_found = File.exists?(main_filepath) +end + +def is_windows? + return ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) if defined?(RbConfig) + return ((Config::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) +end + +unless (project_found) +#===================================== We Do Not Have A Project ================================================ + + puts "Welcome to Ceedling!" + require 'thor' + + def here + File.dirname(__FILE__) + "/.." + end + + class CeedlingTasks < Thor + include Thor::Actions + + desc "new PROJECT_NAME", "create a new ceedling project" + method_option :docs, :type => :boolean, :default => false, :desc => "Add docs in project vendor directory" + method_option :local, :type => :boolean, :default => false, :desc => "Create a copy of Ceedling in the project vendor directory" + method_option :gitignore, :type => :boolean, :default => false, :desc => "Create a gitignore file for ignoring ceedling generated files" + method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files" + method_option :noconfigs, :type => :boolean, :default => false + + #deprecated: + method_option :no_docs, :type => :boolean, :default => false + method_option :nodocs, :type => :boolean, :default => false + method_option :as_gem, :type => :boolean, :default => false + method_option :asgem, :type => :boolean, :default => false + method_option :with_ignore, :type => :boolean, :default => false + method_option :withignore, :type => :boolean, :default => false + def new(name, silent = false) + copy_assets_and_create_structure(name, silent, false, options) + end + + desc "upgrade PROJECT_NAME", "upgrade ceedling for a project (not req'd if gem used)" + method_option :docs, :type => :boolean, :default => false, :desc => "Add docs in project vendor directory" + method_option :local, :type => :boolean, :default => false, :desc => "Create a copy of Ceedling in the project vendor directory" + method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files" + method_option :noconfigs, :type => :boolean, :default => false + + #deprecated: + method_option :no_docs, :type => :boolean, :default => false + method_option :nodocs, :type => :boolean, :default => false + def upgrade(name, silent = false) + copy_assets_and_create_structure(name, silent, true, options || {:upgrade => true}) + end + + no_commands do + def copy_assets_and_create_structure(name, silent=false, force=false, options = {}) + + puts "WARNING: --no_docs deprecated. It is now the default. Specify -docs if you want docs installed." if (options[:no_docs] || options[:nodocs]) + puts "WARNING: --as_gem deprecated. It is now the default. Specify -local if you want ceedling installed to this project." if (options[:as_gem] || options[:asgem]) + puts "WARNING: --with_ignore deprecated. It is now called -gitignore" if (options[:with_ignore] || options[:with_ignore]) + + use_docs = options[:docs] || false + use_configs = !(options[:no_configs] || options[:noconfigs] || false) + use_gem = !(options[:local]) + use_ignore = options[:gitignore] || false + is_upgrade = options[:upgrade] || false + + ceedling_path = File.join(name, 'vendor', 'ceedling') + source_path = File.join(name, 'src') + test_path = File.join(name, 'test') + test_support_path = File.join(name, 'test/support') + + # If it's not an upgrade, make sure we have the paths we expect + if (!is_upgrade) + [source_path, test_path, test_support_path].each do |d| + FileUtils.mkdir_p d + end + end + + # Genarate gitkeep in test support path + FileUtils.touch(File.join(test_support_path, '.gitkeep')) + + # If documentation requested, create a place to dump them and do so + if use_docs + doc_path = File.join(ceedling_path, 'docs') + FileUtils.mkdir_p doc_path + + in_doc_path = lambda {|f| File.join(doc_path, f)} + + doc_files = [ + 'docs/CeedlingPacket.md', + 'vendor/c_exception/docs/CException.md', + 'vendor/cmock/docs/CMock_Summary.md', + 'vendor/unity/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf', + 'vendor/unity/docs/UnityAssertionsReference.md', + 'vendor/unity/docs/UnityConfigurationGuide.md', + 'vendor/unity/docs/UnityGettingStartedGuide.md', + 'vendor/unity/docs/UnityHelperScriptsGuide.md', + 'vendor/unity/docs/ThrowTheSwitchCodingStandard.md', + ] + + doc_files.each do |f| + copy_file(f, in_doc_path.call(File.basename(f)), :force => force) + end + end + + # If installed locally to project, copy ceedling, unity, cmock, & supports to vendor + unless use_gem + FileUtils.mkdir_p ceedling_path + + #copy full folders from ceedling gem into project + %w{plugins lib bin}.map do |f| + {:src => f, :dst => File.join(ceedling_path, f)} + end.each do |f| + directory(f[:src], f[:dst], :force => force) + end + + # mark ceedling as an executable + File.chmod(0755, File.join(ceedling_path, 'bin', 'ceedling')) unless is_windows? + + #copy necessary subcomponents from ceedling gem into project + sub_components = [ + {:src => 'vendor/c_exception/lib/', :dst => 'vendor/c_exception/lib'}, + {:src => 'vendor/cmock/config/', :dst => 'vendor/cmock/config'}, + {:src => 'vendor/cmock/lib/', :dst => 'vendor/cmock/lib'}, + {:src => 'vendor/cmock/src/', :dst => 'vendor/cmock/src'}, + {:src => 'vendor/deep_merge/lib/', :dst => 'vendor/deep_merge/lib'}, + {:src => 'vendor/diy/lib', :dst => 'vendor/diy/lib'}, + {:src => 'vendor/unity/auto/', :dst => 'vendor/unity/auto'}, + {:src => 'vendor/unity/src/', :dst => 'vendor/unity/src'}, + ] + + sub_components.each do |c| + directory(c[:src], File.join(ceedling_path, c[:dst]), :force => force) + end + end + + # We're copying in a configuration file if we haven't said not to + if (use_configs) + if use_gem + copy_file(File.join('assets', 'project_as_gem.yml'), File.join(name, 'project.yml'), :force => force) + else + copy_file(File.join('assets', 'project_with_guts.yml'), File.join(name, 'project.yml'), :force => force) + if is_windows? + copy_file(File.join('assets', 'ceedling.cmd'), File.join(name, 'ceedling.cmd'), :force => force) + else + copy_file(File.join('assets', 'ceedling'), File.join(name, 'ceedling'), :force => force) + File.chmod(0755, File.join(name, 'ceedling')) + end + end + end + + # Copy the gitignore file if requested + if (use_ignore) + copy_file(File.join('assets', 'default_gitignore'), File.join(name, '.gitignore'), :force => force) + end + + unless silent + puts "\n" + puts "Project '#{name}' #{force ? "upgraded" : "created"}!" + puts " - Tool documentation is located in vendor/ceedling/docs" if use_docs + puts " - Execute 'ceedling help' to view available test & build tasks" + puts '' + end + end + end + + desc "examples", "list available example projects" + def examples() + puts "Available sample projects:" + FileUtils.cd(File.join(here, "examples")) do + Dir["*"].each {|proj| puts " #{proj}"} + end + end + + desc "example PROJ_NAME [DEST]", "new specified example project (in DEST, if specified)" + def example(proj_name, dest=nil) + if dest.nil? then dest = proj_name end + + copy_assets_and_create_structure(dest, true, false, {:local=>true, :docs=>true}) + + dest_src = File.join(dest,'src') + dest_test = File.join(dest,'test') + dest_project = File.join(dest,'project.yml') + + directory "examples/#{proj_name}/src", dest_src + directory "examples/#{proj_name}/test", dest_test + remove_file dest_project + copy_file "examples/#{proj_name}/project.yml", dest_project + + puts "\n" + puts "Example project '#{proj_name}' created!" + puts " - Tool documentation is located in vendor/ceedling/docs" + puts " - Execute 'ceedling help' to view available test & build tasks" + puts '' + end + + desc "version", "return the version of the tools installed" + def version() + require 'ceedling/version.rb' + puts " Ceedling:: #{Ceedling::Version::CEEDLING}" + puts " CMock:: #{Ceedling::Version::CMOCK}" + puts " Unity:: #{Ceedling::Version::UNITY}" + puts " CException:: #{Ceedling::Version::CEXCEPTION}" + end + end + + if (ARGV[0] =~ /^\-T$/) + puts "\n(No Project Detected, Therefore Showing Options to Create Projects)" + CeedlingTasks.tasks.each_pair do |k,v| + puts v.usage.ljust(25,' ') + v.description + end + puts "\n" + else + CeedlingTasks.source_root here + CeedlingTasks.start + end + +#===================================== We Have A Project Already ================================================ +else + require 'yaml' + require 'rbconfig' + + #determine platform + platform = begin + case(RbConfig::CONFIG['host_os']) + when /mswin|mingw|cygwin/i + :mswin + when /darwin/ + :osx + else + :linux + end + rescue + :linux + end + + #create our default meta-runner option set + options = { + :pretest => nil, + :args => [], + :add_path => [], + :path_connector => (platform == :mswin) ? ";" : ":", + :graceful_fail => false, + :which_ceedling => (Dir.exists?("vendor/ceedling") ? "vendor/ceedling" : 'gem'), + :default_tasks => [ 'test:all' ], + :list_tasks => false + } + + #guess that we need a special script file first if it exists + if (platform == :mswin) + options[:pretest] = File.exists?("#{ platform.to_s }_setup.bat") ? "#{ platform.to_s }_setup.bat" : nil + else + options[:pretest] = File.exists?("#{ platform.to_s }_setup.sh") ? "source #{ platform.to_s }_setup.sh" : nil + end + + #merge in project settings if they can be found here + yaml_options = YAML.load_file(main_filepath) + if (yaml_options[:paths]) + options[:add_path] = yaml_options[:paths][:tools] || [] + else + options[:add_path] = [] + end + options[:graceful_fail] = yaml_options[:graceful_fail] if yaml_options[:graceful_fail] + options[:which_ceedling] = yaml_options[:project][:which_ceedling] if (yaml_options[:project] && yaml_options[:project][:which_ceedling]) + options[:default_tasks] = yaml_options[:default_tasks] if yaml_options[:default_tasks] + + #sort through command line options + ARGV.each do |v| + case(v) + when /^(?:new|examples?|templates?)$/ + puts "\nOops. You called ceedling with argument '#{v}'.\n" + + " This is an operation that will create a new project... \n" + + " but it looks like you're already in a project. If you really \n" + + " want to do this, try moving to an empty folder.\n\n" + abort + when /^help$/ + options[:list_tasks] = true + when /^-T$/ + options[:list_tasks] = true + when /^project:(\w+)/ + ENV['CEEDLING_USER_PROJECT_FILE'] = "#{$1}.yml" + else + options[:args].push(v) + end + end + + #add to the path + if (options[:add_path] && !options[:add_path].empty?) + path = ENV["PATH"] + options[:add_path].each do |p| + f = File.expand_path(File.dirname(__FILE__),p) + path = (f + options[:path_connector] + path) unless path.include? f + end + ENV["PATH"] = path + end + + # Load Ceedling (either through the rakefile OR directly) + if (File.exists?("rakefile.rb")) + load 'rakefile.rb' + else + if (options[:which_ceedling] == 'gem') + require 'ceedling' + else + load "#{options[:which_ceedling]}/lib/ceedling.rb" + end + Ceedling.load_project + end + + Rake.application.standard_exception_handling do + if options[:list_tasks] + # Display helpful task list when requested. This required us to dig into Rake internals a bit + Rake.application.define_singleton_method(:name=) {|n| @name = n} + Rake.application.name = 'ceedling' + Rake.application.options.show_tasks = :tasks + Rake.application.options.show_task_pattern = /^(?!.*build).*$/ + Rake.application.display_tasks_and_comments() + else + task :default => options[:default_tasks] + + # Run our Tasks! + Rake.application.collect_command_line_tasks(options[:args]) + Rake.application.top_level + end + end + true +#=================================================================================================================== +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CException.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CException.md new file mode 100644 index 0000000..c371819 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CException.md @@ -0,0 +1,292 @@ + +CException +========== + +CException is a basic exception framework for C, suitable for use in +embedded applications. It provides an exception framework similar in +use to C++, but with much less overhead. + + +CException uses C standard library functions `setjmp` and `longjmp` to +operate. As long as the target system has these two functions defined, +this library should be useable with very little configuration. It +even supports environments where multiple program flows are in use, +such as real-time operating systems. + + +There are about a gabillion exception frameworks using a similar +setjmp/longjmp method out there... and there will probably be more +in the future. Unfortunately, when we started our last embedded +project, all those that existed either (a) did not support multiple +tasks (therefore multiple stacks) or (b) were way more complex than +we really wanted. CException was born. + + +*Why use CException?* + + +0. It's ANSI C, and it beats passing error codes around. +1. You want something simple... CException throws a single id. You can + define those ID's to be whatever you like. You might even choose which + type that number is for your project. But that's as far as it goes. + We weren't interested in passing objects or structs or strings... + just simple error codes. +2. Performance... CException can be configured for single tasking or + multitasking. In single tasking, there is very little overhead past + the setjmp/longjmp calls (which are already fast). In multitasking, + your only additional overhead is the time it takes you to determine + a unique task id 0 - num_tasks. + + +For the latest version, go to [ThrowTheSwitch.org](http://throwtheswitch.org) + + +CONTENTS OF THIS DOCUMENT +========================= + +* Usage +* Limitations +*API +* Configuration +* Testing +* License + + +Usage +----- + +Code that is to be protected are wrapped in `Try { } Catch { }` blocks. +The code directly following the Try call is "protected", meaning that +if any Throws occur, program control is directly transferred to the +start of the Catch block. + + +A numerical exception ID is included with Throw, and is made accessible +from the Catch block. + + +Throws can occur from within function calls (nested as deeply as you +like) or directly from within the function itself. + + + +Limitations +----------- + + +This library was made to be as fast as possible, and provide basic +exception handling. It is not a full-blown exception library. Because +of this, there are a few limitations that should be observed in order +to successfully utilize this library: + +1. Do not directly "return" from within a `Try` block, nor `goto` + into or out of a `Try` block. + + *Why?* + + The `Try` macro allocates some local memory and alters a global + pointer. These are cleaned up at the top of the `Catch` macro. + Gotos and returns would bypass some of these steps, resulting in + memory leaks or unpredictable behavior. + + +2. If (a) you change local (stack) variables within your `Try` block, + AND (b) wish to make use of the updated values after an exception + is thrown, those variables should be made `volatile`. Note that this + is ONLY for locals and ONLY when you need access to them after a + `Throw`. + + *Why?* + + Compilers optimize. There is no way to guarantee that the actual + memory location was updated and not just a register unless the + variable is marked volatile. + + +3. Memory which is `malloc`'d or `new`'d is not automatically released + when an error is thrown. This will sometimes be desirable, and + othertimes may not. It will be the responsibility of the `Catch` + block to perform this kind of cleanup. + + *Why?* + + There's just no easy way to track `malloc`'d memory, etc., without + replacing or wrapping malloc calls or something like that. This + is a light framework, so these options were not desirable. + + + +API +--- + +###Try + +`Try` is a macro which starts a protected block. It MUST be followed by +a pair of braces or a single protected line (similar to an 'if'), +enclosing the data that is to be protected. It **must** be followed by a +`Catch` block (don't worry, you'll get compiler errors to let you know if +you mess any of that up). + + +###Catch(e) + +`Catch` is a macro which ends the `Try` block and starts the error handling +block. The `Catch` block is called if and only if an exception was thrown +while within the `Try` block. This error was thrown by a `Throw` call +somewhere within `Try` (or within a function called within `Try`, or a function +called by a function called within `Try`, etc). + +The single parameter `e` is filled with the error code which was thrown. +This can be used for reporting, conditional cleanup, etc. (or you can just +ignore it if you really want... people ignore return codes all the time, +right?). `e` should be of type `EXCEPTION_T` + + +###Throw(e) + +This is the method of throwing an error. A `Throw` should only occur from within a +protected (`Try` ... `Catch`) block, though it may easily be nested many function +calls deep without an impact on performance or functionality. `Throw` takes +a single argument, which is an exception id which will be passed to `Catch` +as the reason for the error. + +If you wish to rethrow an error, this can be done by calling `Throw(e)` with +the error code you just caught. It **is** valid to throw from a catch block. + + +###ExitTry() + +On rare occasion, you might want to immediately exit your current `Try` block +but **not** treat this as an error. Don't run the `Catch`. Just start executing +from after the `Catch` as if nothing had happened... That's what `ExitTry` is +for. + + +CONFIGURATION +------------- + +CException is a mostly portable library. It has one universal +dependency, and some macros which are required if working in a +multi-tasking environment. + +1. The standard C library setjmp must be available. Since this is part + of the standard library, chances are good that you'll be fine. + +2. If working in a multitasking environment, methods for obtaining an + index into an array of frames and to get the overall number of + id's are required. If the OS supports a method to retrieve Task + ID's, and those Tasks are number 0, 1, 2... you are in an ideal + situation. Otherwise, a more creative mapping function may be + required. Note that this function is likely to be called twice + for each protected block and once during a throw. This is the + only overhead in the system. + + +Exception.h +----------- + +By convention, most projects include `Exception.h` which defines any +further requirements, then calls `CException.h` to do the gruntwork. All +of these are optional. You could directly include `CException.h` if +you wanted and just use the defaults provided. + +* `EXCEPTION_T` + * Set this to the type you want your exception id's to be. Defaults to 'unsigned int'. + +* `EXCEPTION_NONE` + * Set this to a number which will never be an exception id in your system. Defaults to `0x5a5a5a5a`. + +* `EXCEPTION_GET_ID` + * If in a multi-tasking environment, this should be + set to be a call to the function described in #2 above. + Defaults to just return `0` all the time (good for + single tasking environments) + +* `EXCEPTION_NUM_ID` + * If in a multi-tasking environment, this should be set + to the number of ID's required (usually the number of + tasks in the system). Defaults to `1` (for single + tasking environments). + +* `CEXCEPTION_NO_CATCH_HANDLER(id)` + * This macro can be optionally specified. + It allows you to specify code to be called when a Throw + is made outside of `Try` ... `Catch` protection. Consider + this the emergency fallback plan for when something has + gone terribly wrong. + + +You may also want to include any header files which will commonly be +needed by the rest of your application where it uses exception handling +here. For example, OS header files or exception codes would be useful. + + +Finally, there are some hook macros which you can implement to inject +your own target-specific code in particular places. It is a rare instance +where you will need these, but they are here if you need them: + + +* `CEXCEPTION_HOOK_START_TRY` + * called immediately before the Try block + +* `CEXCEPTION_HOOK_HAPPY_TRY` + * called immediately after the Try block if no exception was thrown + +* `CEXCEPTION_HOOK_AFTER_TRY` + * called immediately after the Try block OR before an exception is caught + +* `CEXCEPTION_HOOK_START_CATCH` + * called immediately before the catch + + + +TESTING +------- + + +If you want to validate that CException works with your tools or that +it works with your custom configuration, you may want to run the test +suite. + + +The test suite included makes use of the `Unity` Test Framework. It will +require a native C compiler. The example makefile uses MinGW's gcc. +Modify the makefile to include the proper paths to tools, then run `make` +to compile and run the test application. + +* `C_COMPILER` + * The C compiler to use to perform the tests + +* `C_LIBS` + * The path to the C libraries (including setjmp) + +* `UNITY_DIR` + * The path to the Unity framework (required to run tests) + (get it at [ThrowTheSwitch.org](http://throwtheswitch.org)) + + + +LICENSE +------- + +This software is licensed under the MIT License + +Copyright (c) 2007-2017 Mark VanderVoord + +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. diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CMock_Summary.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CMock_Summary.md new file mode 100644 index 0000000..87f9c00 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CMock_Summary.md @@ -0,0 +1,603 @@ +CMock: A Summary +================ + +*[ThrowTheSwitch.org](http://throwtheswitch.org)* + +*This documentation is released under a Creative Commons 3.0 Attribution Share-Alike License* + + +What Exactly Are We Talking About Here? +--------------------------------------- + +CMock is a nice little tool which takes your header files and creates +a Mock interface for it so that you can more easily unit test modules +that touch other modules. For each function prototype in your +header, like this one: + + int DoesSomething(int a, int b); + + +...you get an automatically generated DoesSomething function +that you can link to instead of your real DoesSomething function. +By using this Mocked version, you can then verify that it receives +the data you want, and make it return whatever data you desire, +make it throw errors when you want, and more... Create these for +everything your latest real module touches, and you're suddenly +in a position of power: You can control and verify every detail +of your latest creation. + +To make that easier, CMock also gives you a bunch of functions +like the ones below, so you can tell that generated DoesSomething +function how to behave for each test: + + void DoesSomething_ExpectAndReturn(int a, int b, int toReturn); + void DoesSomething_ExpectAndThrow(int a, int b, EXCEPTION_T error); + void DoesSomething_StubWithCallback(CMOCK_DoesSomething_CALLBACK YourCallback); + void DoesSomething_IgnoreAndReturn(int toReturn); + + +You can pile a bunch of these back to back, and it remembers what +you wanted to pass when, like so: + + test_CallsDoesSomething_ShouldDoJustThat(void) + { + DoesSomething_ExpectAndReturn(1,2,3); + DoesSomething_ExpectAndReturn(4,5,6); + DoesSomething_ExpectAndThrow(7,8, STATUS_ERROR_OOPS); + + CallsDoesSomething( ); + } + + +This test will call CallsDoesSomething, which is the function +we are testing. We are expecting that function to call DoesSomething +three times. The first time, we check to make sure it's called +as DoesSomething(1, 2) and we'll magically return a 3. The second +time we check for DoesSomething(4, 5) and we'll return a 6. The +third time we verify DoesSomething(7, 8) and we'll throw an error +instead of returning anything. If CallsDoesSomething gets +any of this wrong, it fails the test. It will fail if you didn't +call DoesSomething enough, or too much, or with the wrong arguments, +or in the wrong order. + +CMock is based on Unity, which it uses for all internal testing. +It uses Ruby to do all the main work (versions 2.0.0 and above). + + +Installing +========== + +The first thing you need to do to install CMock is to get yourself +a copy of Ruby. If you're on linux or osx, you probably already +have it. You can prove it by typing the following: + + ruby --version + + +If it replied in a way that implies ignorance, then you're going to +need to install it. You can go to [ruby-lang](https://ruby-lang.org) +to get the latest version. You're also going to need to do that if it +replied with a version that is older than 2.0.0. Go ahead. We'll wait. + +Once you have Ruby, you have three options: + +* Clone the latest [CMock repo on github](https://github.com/ThrowTheSwitch/CMock/) +* Download the latest [CMock zip from github](https://github.com/ThrowTheSwitch/CMock/) +* Install Ceedling (which has it built in!) through your commandline using `gem install ceedling`. + + +Generated Mock Module Summary +============================= + +In addition to the mocks themselves, CMock will generate the +following functions for use in your tests. The expect functions +are always generated. The other functions are only generated +if those plugins are enabled: + + +Expect: +------- + +Your basic staple Expects which will be used for most of your day +to day CMock work. By calling this, you are telling CMock that you +expect that function to be called during your test. It also specifies +which arguments you expect it to be called with, and what return +value you want returned when that happens. You can call this function +multiple times back to back in order to queue up multiple calls. + +* `void func(void)` => `void func_Expect(void)` +* `void func(params)` => `void func_Expect(expected_params)` +* `retval func(void)` => `void func_ExpectAndReturn(retval_to_return)` +* `retval func(params)` => `void func_ExpectAndReturn(expected_params, retval_to_return)` + + +ExpectAnyArgs: +-------------- + +This behaves just like the Expects calls, except that it doesn't really +care what the arguments are that the mock gets called with. It still counts +the number of times the mock is called and it still handles return values +if there are some. + +* `void func(void)` => `void func_ExpectAnyArgs(void)` +* `void func(params)` => `void func_ExpectAnyArgs(void)` +* `retval func(void)` => `void func_ExpectAnyArgsAndReturn(retval_to_return)` +* `retval func(params)` => `void func_ExpectAnyArgsAndReturn(retval_to_return)` + + +Array: +------ + +An ExpectWithArray is another variant of Expect. Like expect, it cares about +the number of times a mock is called, the arguments it is called with, and the +values it is to return. This variant has another feature, though. For anything +that resembles a pointer or array, it breaks the argument into TWO arguments. +The first is the original pointer. The second specify the number of elements +it is to verify of that array. If you specify 1, it'll check one object. If 2, +it'll assume your pointer is pointing at the first of two elements in an array. +If you specify zero elements, it will check just the pointer if +`:smart` mode is configured or fail if `:compare_data` is set. + +* `void func(void)` => (nothing. In fact, an additional function is only generated if the params list contains pointers) +* `void func(ptr * param, other)` => `void func_ExpectWithArray(ptr* param, int param_depth, other)` +* `retval func(void)` => (nothing. In fact, an additional function is only generated if the params list contains pointers) +* `retval func(other, ptr* param)` => `void func_ExpectWithArrayAndReturn(other, ptr* param, int param_depth, retval_to_return)` + + +Ignore: +------- + +Maybe you don't care about the number of times a particular function is called or +the actual arguments it is called with. In that case, you want to use Ignore. Ignore +only needs to be called once per test. It will then ignore any further calls to that +particular mock. The IgnoreAndReturn works similarly, except that it has the added +benefit of knowing what to return when that call happens. If the mock is called more +times than IgnoreAndReturn was called, it will keep returning the last value without +complaint. If it's called less times, it will also ignore that. You SAID you didn't +care how many times it was called, right? + +* `void func(void)` => `void func_Ignore(void)` +* `void func(params)` => `void func_Ignore(void)` +* `retval func(void)` => `void func_IgnoreAndReturn(retval_to_return)` +* `retval func(params)` => `void func_IgnoreAndReturn(retval_to_return)` + + +Ignore Arg: +------------ + +Maybe you overall want to use Expect and its similar variations, but you don't care +what is passed to a particular argument. This is particularly useful when that argument +is a pointer to a value that is supposed to be filled in by the function. You don't want +to use ExpectAnyArgs, because you still care about the other arguments. Instead, before +any of your Expect calls are made, you can call this function. It tells CMock to ignore +a particular argument for the rest of this test, for this mock function. + +* `void func(params)` => `void func_IgnoreArg_paramName(void)` + + +ReturnThruPtr: +-------------- + +Another option which operates on a particular argument of a function is the ReturnThruPtr +plugin. For every argument that resembles a pointer or reference, CMock generates an +instance of this function. Just as the AndReturn functions support injecting one or more +return values into a queue, this function lets you specify one or more return values which +are queued up and copied into the space being pointed at each time the mock is called. + +* `void func(param1)` => `void func_ReturnThruPtr_paramName(val_to_return)` +* => `void func_ReturnArrayThruPtr_paramName(cal_to_return, len)` +* => `void func_ReturnMemThruPtr_paramName(val_to_return, size)` + + +Callback: +--------- + +If all those other options don't work, and you really need to do something custom, you +still have a choice. As soon as you stub a callback in a test, it will call the callback +whenever the mock is encountered and return the retval returned from the callback (if any) +instead of performing the usual expect checks. It can be configured to check the arguments +first (like expects) or just jump directly to the callback. + +* `void func(void)` => `void func_StubWithCallback(CMOCK_func_CALLBACK callback)` +where `CMOCK_func_CALLBACK` looks like: `void func(int NumCalls)` +* `void func(params)` => `void func_StubWithCallback(CMOCK_func_CALLBACK callback)` +where `CMOCK_func_CALLBACK` looks like: `void func(params, int NumCalls)` +* `retval func(void)` => `void func_StubWithCallback(CMOCK_func_CALLBACK callback)` +where `CMOCK_func_CALLBACK` looks like: `retval func(int NumCalls)` +* `retval func(params)` => `void func_StubWithCallback(CMOCK_func_CALLBACK callback)` +where `CMOCK_func_CALLBACK` looks like: `retval func(params, int NumCalls)` + + +Cexception: +----------- + +Finally, if you are using Cexception for error handling, you can use this to throw errors +from inside mocks. Like Expects, it remembers which call was supposed to throw the error, +and it still checks parameters first. + +* `void func(void)` => `void func_ExpectAndThrow(value_to_throw)` +* `void func(params)` => `void func_ExpectAndThrow(expected_params, value_to_throw)` +* `retval func(void)` => `void func_ExpectAndThrow(value_to_throw)` +* `retval func(params)` => `void func_ExpectAndThrow(expected_params, value_to_throw)` + + + +Running CMock +============= + +CMock is a Ruby script and class. You can therefore use it directly +from the command line, or include it in your own scripts or rakefiles. + + +Mocking from the Command Line +----------------------------- + +After unpacking CMock, you will find cmock.rb in the 'lib' directory. +This is the file that you want to run. It takes a list of header files +to be mocked, as well as an optional yaml file for a more detailed +configuration (see config options below). + +For example, this will create three mocks using the configuration +specified in MyConfig.yml: + + ruby cmock.rb -oMyConfig.yml super.h duper.h awesome.h + +And this will create two mocks using the default configuration: + + ruby cmock.rb ../mocking/stuff/is/fun.h ../try/it/yourself.h + + +Mocking From Scripts or Rake +---------------------------- + +CMock can be used directly from your own scripts or from a rakefile. +Start by including cmock.rb, then create an instance of CMock. +When you create your instance, you may initialize it in one of +three ways. + +You may specify nothing, allowing it to run with default settings: + + require 'cmock.rb' + cmock = CMock.new + +You may specify a YAML file containing the configuration options +you desire: + + cmock = CMock.new('../MyConfig.yml') + +You may specify the options explicitly: + + cmock = Cmock.new(:plugins => [:cexception, :ignore], :mock_path => 'my/mocks/') + + +Config Options: +--------------- + +The following configuration options can be specified in the +yaml file or directly when instantiating. + +Passed as Ruby, they look like this: + + { :attributes => [“__funkyâ€, “__intrinsicâ€], :when_ptr => :compare } + +Defined in the yaml file, they look more like this: + + :cmock: + :attributes: + - __funky + - __intrinsic + :when_ptr: :compare + +In all cases, you can just include the things that you want to override +from the defaults. We've tried to specify what the defaults are below. + +* `:attributes`: + These are attributes that CMock should ignore for you for testing + purposes. Custom compiler extensions and externs are handy things to + put here. If your compiler is choking on some extended syntax, this + is often a good place to look. + + * defaults: ['__ramfunc', '__irq', '__fiq', 'register', 'extern'] + * **note:** this option will reinsert these attributes onto the mock's calls. + If that isn't what you are looking for, check out :strippables. + +* `:c_calling_conventions`: + Similarly, CMock may need to understand which C calling conventions + might show up in your codebase. If it encounters something it doesn't + recognize, it's not going to mock it. We have the most common covered, + but there are many compilers out there, and therefore many other options. + + * defaults: ['__stdcall', '__cdecl', '__fastcall'] + * **note:** this option will reinsert these attributes onto the mock's calls. + If that isn't what you are looking for, check out :strippables. + +* `:callback_after_arg_check`: + Tell `:callback` plugin to do the normal argument checking **before** it + calls the callback function by setting this to true. When false, the + callback function is called **instead** of the argument verification. + + * default: false + +* `:callback_include_count`: + Tell `:callback` plugin to include an extra parameter to specify the + number of times the callback has been called. If set to false, the + callback has the same interface as the mocked function. This can be + handy when you're wanting to use callback as a stub. + + * default: true + +* `:cexception_include`: + Tell `:cexception` plugin where to find CException.h... You only need to + define this if it's not in your build path already... which it usually + will be for the purpose of your builds. + + * default: *nil* + +* `:enforce_strict_ordering`: + CMock always enforces the order that you call a particular function, + so if you expect GrabNabber(int size) to be called three times, it + will verify that the sizes are in the order you specified. You might + *also* want to make sure that all different functions are called in a + particular order. If so, set this to true. + + * default: false + +* `:framework`: + Currently the only option is `:unity.` Eventually if we support other + unity test frameworks (or if you write one for us), they'll get added + here. + + : default: :unity + +* `:includes`: + An array of additional include files which should be added to the + mocks. Useful for global types and definitions used in your project. + There are more specific versions if you care WHERE in the mock files + the includes get placed. You can define any or all of these options. + + * `:includes` + * `:includes_h_pre_orig_header` + * `:includes_h_post_orig_header` + * `:includes_c_pre_header` + * `:includes_c_post_header` + * default: nil #for all 5 options + +* `:memcmp_if_unknown`: + C developers create a lot of types, either through typedef or preprocessor + macros. CMock isn't going to automatically know what you were thinking all + the time (though it tries its best). If it comes across a type it doesn't + recognize, you have a choice on how you want it to handle it. It can either + perform a raw memory comparison and report any differences, or it can fail + with a meaningful message. Either way, this feature will only happen after + all other mechanisms have failed (The thing encountered isn't a standard + type. It isn't in the :treat_as list. It isn't in a custom unity_helper). + + * default: true + +* `:mock_path`: + The directory where you would like the mock files generated to be + placed. + + * default: mocks + +* `:mock_prefix`: + The prefix to prepend to your mock files. For example, if it's “Mockâ€, a file + “USART.h†will get a mock called “MockUSART.câ€. This CAN be used with a suffix + at the same time. + + * default: Mock + +* `:mock_suffix`: + The suffix to append to your mock files. For example, it it's "_Mock", a file + "USART.h" will get a mock called "USART_Mock.h". This CAN be used with a prefix + at the same time. + + * default: "" + +* `:plugins`: + An array of which plugins to enable. ':expect' is always active. Also + available currently: + + * `:ignore` + * `:ignore_arg` + * `:expect_any_args` + * `:array` + * `:cexception` + * `:callback` + * `:return_thru_ptr` + +* `:strippables`: + An array containing a list of items to remove from the header + before deciding what should be mocked. This can be something simple + like a compiler extension CMock wouldn't recognize, or could be a + regex to reject certain function name patterns. This is a great way to + get rid of compiler extensions when your test compiler doesn't support + them. For example, use `:strippables: ['(?:functionName\s*\(+.*?\)+)']` + to prevent a function `functionName` from being mocked. By default, it + is ignoring all gcc attribute extensions. + + * default: ['(?:__attribute__\s*\(+.*?\)+)'] + +* `:subdir`: + This is a relative subdirectory for your mocks. Set this to e.g. "sys" in + order to create a mock for `sys/types.h` in `(:mock_path)/sys/`. + + * default: "" + +* `:treat_as`: + The `:treat_as` list is a shortcut for when you have created typedefs + of standard types. Why create a custom unity helper for UINT16 when + the unity function TEST_ASSERT_EQUAL_HEX16 will work just perfectly? + Just add 'UINT16' => 'HEX16' to your list (actually, don't. We already + did that one for you). Maybe you have a type that is a pointer to an + array of unsigned characters? No problem, just add 'UINT8_T*' => + 'HEX8*' + + * NOTE: unlike the other options, your specifications MERGE with the + default list. Therefore, if you want to override something, you must + reassign it to something else (or to *nil* if you don't want it) + + * default: + * 'int': 'INT' + * 'char': 'INT8' + * 'short': 'INT16' + * 'long': 'INT' + * 'int8': 'INT8' + * 'int16': 'INT16' + * 'int32': 'INT' + * 'int8_t': 'INT8' + * 'int16_t': 'INT16' + * 'int32_t': 'INT' + * 'INT8_T': 'INT8' + * 'INT16_T': 'INT16' + * 'INT32_T': 'INT' + * 'bool': 'INT' + * 'bool_t': 'INT' + * 'BOOL': 'INT' + * 'BOOL_T': 'INT' + * 'unsigned int': 'HEX32' + * 'unsigned long': 'HEX32' + * 'uint32': 'HEX32' + * 'uint32_t': 'HEX32' + * 'UINT32': 'HEX32' + * 'UINT32_T': 'HEX32' + * 'void*': 'HEX8_ARRAY' + * 'unsigned short': 'HEX16' + * 'uint16': 'HEX16' + * 'uint16_t': 'HEX16' + * 'UINT16': 'HEX16' + * 'UINT16_T': 'HEX16' + * 'unsigned char': 'HEX8' + * 'uint8': 'HEX8' + * 'uint8_t': 'HEX8' + * 'UINT8': 'HEX8' + * 'UINT8_T': 'HEX8' + * 'char*': 'STRING' + * 'pCHAR': 'STRING' + * 'cstring': 'STRING' + * 'CSTRING': 'STRING' + * 'float': 'FLOAT' + * 'double': 'FLOAT' + +* `:treat_as_void`: + We've seen "fun" legacy systems typedef 'void' with a custom type, + like MY_VOID. Add any instances of those to this list to help CMock + understand how to deal with your code. + + * default: [] + +* `:treat_externs`: + This specifies how you want CMock to handle functions that have been + marked as extern in the header file. Should it mock them? + + * `:include` will mock externed functions + * `:exclude` will ignore externed functions (default). + +* `:unity_helper_path`: + If you have created a header with your own extensions to unity to + handle your own types, you can set this argument to that path. CMock + will then automagically pull in your helpers and use them. The only + trick is that you make sure you follow the naming convention: + `UNITY_TEST_ASSERT_EQUAL_YourType`. If it finds macros of the right + shape that match that pattern, it'll use them. + + * default: [] + +* `:verbosity`: + How loud should CMock be? + + * 0 for errors only + * 1 for errors and warnings + * 2 for normal (default) + * 3 for verbose + +* `:weak`: + When set this to some value, the generated mocks are defined as weak + symbols using the configured format. This allows them to be overridden + in particular tests. + + * Set to '__attribute ((weak))' for weak mocks when using GCC. + * Set to any non-empty string for weak mocks when using IAR. + * default: "" + +* `:when_no_prototypes`: + When you give CMock a header file and ask it to create a mock out of + it, it usually contains function prototypes (otherwise what was the + point?). You can control what happens when this isn't true. You can + set this to `:warn,` `:ignore,` or `:error` + + * default: :warn + +* `:when_ptr`: + You can customize how CMock deals with pointers (c strings result in + string comparisons... we're talking about **other** pointers here). Your + options are `:compare_ptr` to just verify the pointers are the same, + `:compare_data` or `:smart` to verify that the data is the same. + `:compare_data` and `:smart` behaviors will change slightly based on + if you have the array plugin enabled. By default, they compare a + single element of what is being pointed to. So if you have a pointer + to a struct called ORGAN_T, it will compare one ORGAN_T (whatever that + is). + + * default: :smart + +* `:fail_on_unexpected_calls`: + By default, CMock will fail a test if a mock is called without _Expect and _Ignore + called first. While this forces test writers to be more explicit in their expectations, + it can clutter tests with _Expect or _Ignore calls for functions which are not the focus + of the test. While this is a good indicator that this module should be refactored, some + users are not fans of the additional noise. + + Therefore, :fail_on_unexpected_calls can be set to false to force all mocks to start with + the assumption that they are operating as _Ignore unless otherwise specified. + + * default: true + * **note:** + If this option is disabled, the mocked functions will return + a default value (0) when called (and only if they have to return something of course). + + +Compiled Options: +----------------- + +A number of #defines also exist for customizing the cmock experience. +Feel free to pass these into your compiler or whatever is most +convenient. CMock will otherwise do its best to guess what you want +based on other settings, particularly Unity's settings. + +* `CMOCK_MEM_STATIC` or `CMOCK_MEM_DYNAMIC` + Define one of these to determine if you want to dynamically add + memory during tests as required from the heap. If static, you + can control the total footprint of Cmock. If dynamic, you will + need to make sure you make some heap space available for Cmock. + +* `CMOCK_MEM_SIZE` + In static mode this is the total amount of memory you are allocating + to Cmock. In Dynamic mode this is the size of each chunk allocated + at once (larger numbers grab more memory but require less mallocs). + +* `CMOCK_MEM_ALIGN` + The way to align your data to. Not everything is as flexible as + a PC, as most embedded designers know. This defaults to 2, meaning + align to the closest 2^2 -> 4 bytes (32 bits). You can turn off alignment + by setting 0, force alignment to the closest uint16 with 1 or even + to the closest uint64 with 3. + +* `CMOCK_MEM_PTR_AS_INT` + This is used internally to hold pointers... it needs to be big + enough. On most processors a pointer is the same as an unsigned + long... but maybe that's not true for yours? + +* `CMOCK_MEM_INDEX_TYPE` + This needs to be something big enough to point anywhere in Cmock's + memory space... usually it's an unsigned int. + +Examples +======== + +You can look in the [examples directory](/examples/) for a couple of examples on how +you might tool CMock into your build process. You may also want to consider +using [Ceedling](https://throwtheswitch.org/ceedling). Please note that +these examples are meant to show how the build process works. They have +failing tests ON PURPOSE to show what that would look like. Don't be alarmed. ;) + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CeedlingPacket.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CeedlingPacket.md new file mode 100644 index 0000000..88cd020 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/CeedlingPacket.md @@ -0,0 +1,2060 @@ +[All code is copyright © 2010-2012 Ceedling Project +by Mike Karlesky, Mark VanderVoord, and Greg Williams. + +This Documentation Is Released Under a +Creative Commons 3.0 Attribution Share-Alike License] + +What the What? + +Assembling build environments for C projects - especially with +automated unit tests - is a pain. Whether it's Make or Rake or Premake +or what-have-you, set up with an all-purpose build environment +tool is tedious and requires considerable glue code to pull together +the necessary tools and libraries. Ceedling allows you to generate +an entire test and build environment for a C project from a single +YAML configuration file. Ceedling is written in Ruby and works +with the Rake build tool plus other goodness like Unity and CMock +- the unit testing and mocking frameworks for C. Ceedling and +its complementary tools can support the tiniest of embedded +processors, the beefiest 64 bit power houses available, and +everything in between. + +For a build project including unit tests and using the default +toolchain gcc, the configuration file could be as simple as this: + +```yaml +:project: + :build_root: project/build/ + :release_build: TRUE + +:paths: + :test: + - tests/** + :source: + - source/** +``` + +From the command line, to build the release version of your project, +you would simply run `ceedling release`. To run all your unit tests, +you would run `ceedling test:all`. That's it! + +Of course, many more advanced options allow you to configure +your project with a variety of features to meet a variety of needs. +Ceedling can work with practically any command line toolchain +and directory structure – all by way of the configuration file. +Further, because Ceedling piggy backs on Rake, you can add your +own Rake tasks to accomplish project tasks outside of testing +and release builds. A facility for plugins also allows you to +extend Ceedling's capabilities for needs such as custom code +metrics reporting and coverage testing. + +What's with this Name? + +Glad you asked. Ceedling is tailored for unit tested C projects +and is built upon / around Rake (Rake is a Make replacement implemented +in the Ruby scripting language). So, we've got C, our Rake, and +the fertile soil of a build environment in which to grow and tend +your project and its unit tests. Ta da - _Ceedling_. + +What Do You Mean "tailored for unit tested C projects"? + +Well, we like to write unit tests for our C code to make it lean and +mean (that whole [Test-Driven Development][tdd] +thing). Along the way, this style of writing C code spawned two +tools to make the job easier: a unit test framework for C called +_Unity_ and a mocking library called _CMock_. And, though it's +not directly related to testing, a C framework for exception +handling called _CException_ also came along. + +[tdd]: http://en.wikipedia.org/wiki/Test-driven_development + +These tools and frameworks are great, but they require quite +a bit of environment support to pull them all together in a convenient, +usable fashion. We started off with Rakefiles to assemble everything. +These ended up being quite complicated and had to be hand-edited +or created anew for each new project. Ceedling replaces all that +tedium and rework with a configuration file that ties everything +together. + +Though Ceedling is tailored for unit testing, it can also go right ahead +and build your final binary release artifact for you as well. Or, +Ceedling and your tests can live alongside your existing release build +setup. That said, Ceedling is more powerful as a unit test build +environment than it is a general purpose release build environment; +complicated projects including separate bootloaders or multiple library +builds, etc. are not its strong suit. + +Hold on. Back up. Ruby? Rake? YAML? Unity? CMock? CException? + +Seem overwhelming? It's not bad at all, and for the benefits tests +bring us, it's all worth it. + +[Ruby][] is a handy scripting +language like Perl or Python. It's a modern, full featured language +that happens to be quite handy for accomplishing tasks like code +generation or automating one's workflow while developing in +a compiled language such as C. + +[Ruby]: http://www.ruby-lang.org/en/ + +[Rake][] is a utility written in Ruby +for accomplishing dependency tracking and task automation +common to building software. It's a modern, more flexible replacement +for [Make][]). +Rakefiles are Ruby files, but they contain build targets similar +in nature to that of Makefiles (but you can also run Ruby code in +your Rakefile). + +[Rake]: http://rubyrake.org/ +[Make]: http://en.wikipedia.org/wiki/Make_(software) + +[YAML][] is a "human friendly data serialization standard for all +programming languages." It's kinda like a markup language, but don't +call it that. With a YAML library, you can [serialize][] data structures +to and from the file system in a textual, human readable form. Ceedling +uses a serialized data structure as its configuration input. + +[YAML]: http://en.wikipedia.org/wiki/Yaml +[serialize]: http://en.wikipedia.org/wiki/Serialization + +[Unity] is a [unit test framework][test] for C. It provides facilities +for test assertions, executing tests, and collecting / reporting test +results. Unity derives its name from its implementation in a single C +source file (plus two C header files) and from the nature of its +implementation - Unity will build in any C toolchain and is configurable +for even the very minimalist of processors. + +[Unity]: http://github.com/ThrowTheSwitch/Unity +[test]: http://en.wikipedia.org/wiki/Unit_testing + +[CMock] is a tool written in Ruby able to generate entire +[mock functions][mock] in C code from a given C header file. Mock +functions are invaluable in [interaction-based unit testing][ut]. +CMock's generated C code uses Unity. + +[CMock]: http://github.com/ThrowTheSwitch/CMock +[mock]: http://en.wikipedia.org/wiki/Mock_object +[ut]: http://martinfowler.com/articles/mocksArentStubs.html + +[CException] is a C source and header file that provide a simple +[exception mechanism][exn] for C by way of wrapping up the +[setjmp / longjmp][setjmp] standard library calls. Exceptions are a much +cleaner and preferable alternative to managing and passing error codes +up your return call trace. + +[CException]: http://github.com/ThrowTheSwitch/CException +[exn]: http://en.wikipedia.org/wiki/Exception_handling +[setjmp]: http://en.wikipedia.org/wiki/Setjmp.h + +Notes +----- + +* YAML support is included with Ruby - requires no special installation + or configuration. + +* Unity, CMock, and CException are bundled with Ceedling, and + Ceedling is designed to glue them all together for your project + as seamlessly as possible. + + +Installation & Setup: What Exactly Do I Need to Get Started? +------------------------------------------------------------ + +As a [Ruby gem](http://docs.rubygems.org/read/chapter/1): + +1. [Download and install Ruby](http://www.ruby-lang.org/en/downloads/) + +2. Use Ruby's command line gem package manager to install Ceedling: + `gem install ceedling` + (Unity, CMock, and CException come along with Ceedling for free) + +3. Execute Ceedling at command line to create example project + or an empty Ceedling project in your filesystem (executing + `ceedling help` first is, well, helpful). + +Gem install notes: + +1. Steps 1-2 are a one time affair for your local environment. + When steps 1-2 are completed once, only step 3 is needed for + each new project. + + + +General notes: + +1. Certain advanced features of Ceedling rely on gcc and cpp + as preprocessing tools. In most *nix systems, these tools + are already available. For Windows environments, we recommend + the [mingw project](http://www.mingw.org/) (Minimalist + GNU for Windows). This represents an optional, additional + setup / installation step to complement the list above. Upon + installing mingw ensure your system path is updated or set + [:environment][:path] in your `project.yml` file (see + environment section later in this document). + +2. To use a project file name other than the default `project.yml` + or place the project file in a directory other than the one + in which you'll run Rake, create an environment variable + `CEEDLING_MAIN_PROJECT_FILE` with your desired project + file path. + +3. To better understand Rake conventions, Rake execution, + and Rakefiles, consult the [Rake tutorial, examples, and + user guide](http://rubyrake.org/). + +4. When using Ceedling in Windows environments, a test file name may + not include the sequences “patch†or “setupâ€. The Windows Installer + Detection Technology (part of UAC), requires administrator + privileges to execute file names with these strings. + + + +Now What? How Do I Make It GO? +------------------------------ + +We're getting a little ahead of ourselves here, but it's good +context on how to drive this bus. Everything is done via the command +line. We'll cover conventions and how to actually configure +your project in later sections. + +To run tests, build your release artifact, etc., you will be interacting +with Rake on the command line. Ceedling works with Rake to present +you with named tasks that coordinate the file generation and +build steps needed to accomplish something useful. You can also +add your own independent Rake tasks or create plugins to extend +Ceedling (more on this later). + + +* `ceedling [no arguments]`: + + Run the default Rake task (conveniently recognized by the name default + by Rake). Neither Rake nor Ceedling provide a default task. Rake will + abort if run without arguments when no default task is defined. You can + conveniently define a default task in the Rakefile discussed in the + preceding setup & installation section of this document. + +* `ceedling -T`: + + List all available Rake tasks with descriptions (Rake tasks without + descriptions are not listed). -T is a command line switch for Rake and + not the same as tasks that follow. + +* `ceedling --trace`: + + For advanced users troubleshooting a confusing build error, debug + Ceedling or a plugin, --trace provides a stack trace of dependencies + walked during task execution and any Ruby failures along the way. Note + that --trace is a command line switch for Rake and is not the same as + tasks that follow. + +* `ceedling environment`: + + List all configured environment variable names and string values. This + task is helpful in verifying the evaluatio of any Ruby expressions in + the [:environment] section of your config file.`: Note: Ceedling may + set some convenience environment variables by default. + +* `ceedling paths:*`: + + List all paths collected from [:paths] entries in your YAML config + file where * is the name of any section contained in [:paths]. This + task is helpful in verifying the expansion of path wildcards / globs + specified in the [:paths] section of your config file. + +* `ceedling files:assembly` +* `ceedling files:header` +* `ceedling files:source` +* `ceedling files:test` + + List all files and file counts collected from the relevant search + paths specified by the [:paths] entries of your YAML config file. The + files:assembly task will only be available if assembly support is + enabled in the [:release_build] section of your configuration file. + +* `ceedling options:*`: + + Load and merge configuration settings into the main project + configuration. Each task is named after a *.yml file found in the + configured options directory. See documentation for the configuration + setting [:project][:options_path] and for options files in advanced + topics. + +* `ceedling test:all`: + + Run all unit tests (rebuilding anything that's changed along the way). + +* `ceedling test:delta`: + + Run only those unit tests for which the source or test files have + changed (i.e. incremental build). Note: with the + [:project][:use_test_preprocessor] configuration file option set, + runner files are always regenerated limiting the total efficiency this + text execution option can afford. + +* `ceedling test:*`: + + Execute the named test file or the named source file that has an + accompanying test. No path. Examples: ceedling test:foo.c or ceed + test:test_foo.c + +* `ceedling test:pattern[*]`: + + Execute any tests whose name and/or path match the regular expression + pattern (case sensitive). Example: ceedling "test:pattern[(I|i)nit]" will + execute all tests named for initialization testing. Note: quotes may + be necessary around the ceedling parameter to distinguish regex characters + from command line operators. + +* `ceedling test:path[*]`: + + Execute any tests whose path contains the given string (case + sensitive). Example: ceedling test:path[foo/bar] will execute all tests + whose path contains foo/bar. Note: both directory separator characters + / and \ are valid. + +* `ceedling release`: + + Build all source into a release artifact (if the release build option + is configured). + +* `ceedling release:compile:*`: + + Sometimes you just need to compile a single file dagnabit. Example: + ceedling release:compile:foo.c + +* `ceedling release:assemble:*`: + + Sometimes you just need to assemble a single file doggonit. Example: + ceedling release:assemble:foo.s + +* `ceedling module:create[Filename]`: +* `ceedling module:create[Filename]`: + + It's often helpful to create a file automatically. What's better than + that? Creating a source file, a header file, and a corresponding test + file all in one step! + + There are also patterns which can be specified to automatically generate + a bunch of files. Try `ceedling module:create[Poodles,mch]` for example! + + The module generator has several options you can configure. + F.e. Generating the source/header/test file in a subdirectory (by adding when calling module:create). + For more info, refer to the [Module Generator](https://github.com/ThrowTheSwitch/Ceedling/blob/master/docs/CeedlingPacket.md#module-generator) section. + +* `ceedling logging `: + + Enable logging to /logs. Must come before test and release + tasks to log their steps and output. Log names are a concatenation of + project, user, and option files loaded. User and option files are + documented in the advanced topics section of this document. + +* `ceedling verbosity[x] `: + + Change the default verbosity level. [x] ranges from 0 (quiet) to 4 + (obnoxious). Level [3] is the default. The verbosity task must precede + all tasks in the command line list for which output is desired to be + seen. Verbosity settings are generally most meaningful in conjunction + with test and release tasks. + +* `ceedling summary`: + + If plugins are enabled, this task will execute the summary method of + any plugins supporting it. This task is intended to provide a quick + roundup of build artifact metrics without re-running any part of the + build. + +* `ceedling clean`: + + Deletes all toolchain binary artifacts (object files, executables), + test results, and any temporary files. Clean produces no output at the + command line unless verbosity has been set to an appreciable level. + +* `ceedling clobber`: + + Extends clean task's behavior to also remove generated files: test + runners, mocks, preprocessor output. Clobber produces no output at the + command line unless verbosity has been set to an appreciable level. + +To better understand Rake conventions, Rake execution, and +Rakefiles, consult the [Rake tutorial, examples, and user guide][guide]. + +[guide]: http://rubyrake.org/ + +At present, none of Ceedling's commands provide persistence. +That is, they must each be specified at the command line each time +they are needed. For instance, Ceedling's verbosity command +only affects output at the time it's run. + +Individual test and release file tasks +are not listed in `-T` output. Because so many files may be present +it's unwieldy to list them all. + +Multiple rake tasks can be executed at the command line (order +is executed as provided). For example, `ceed +clobber test:all release` will removed all generated files; +build and run all tests; and then build all source - in that order. +If any Rake task fails along the way, execution halts before the +next task. + +The `clobber` task removes certain build directories in the +course of deleting generated files. In general, it's best not +to add to source control any Ceedling generated directories +below the root of your top-level build directory. That is, leave +anything Ceedling & its accompanying tools generate out of source +control (but go ahead and add the top-level build directory that +holds all that stuff). Also, since Ceedling is pretty smart about +what it rebuilds and regenerates, you needn't clobber often. + +Important Conventions +===================== + +Directory Structure, Filenames & Extensions +------------------------------------------- + +Much of Ceedling's functionality is driven by collecting files +matching certain patterns inside the paths it's configured +to search. See the documentation for the [:extensions] section +of your configuration file (found later in this document) to +configure the file extensions Ceedling uses to match and collect +files. Test file naming is covered later in this section. + +Test files and source files must be segregated by directories. +Any directory structure will do. Tests can be held in subdirectories +within source directories, or tests and source directories +can be wholly separated at the top of your project's directory +tree. + +Search Path Order +----------------- + +When Ceedling searches for files (e.g. looking for header files +to mock) or when it provides search paths to any of the default +gcc toolchain executables, it organizes / prioritizes its search +paths. The order is always: test paths, support paths, source +paths, and then include paths. This can be useful, for instance, +in certain testing scenarios where we desire Ceedling or a compiler +to find a stand-in header file in our support directory before +the actual source header file of the same name. + +This convention only holds when Ceedling is using its default +tool configurations and / or when tests are involved. If you define +your own tools in the configuration file (see the [:tools] section +documented later in this here document), you have complete control +over what directories are searched and in what order. Further, +test and support directories are only searched when appropriate. +That is, when running a release build, test and support directories +are not used at all. + +Source Files & Binary Release Artifacts +--------------------------------------- + +Your binary release artifact results from the compilation and +linking of all source files Ceedling finds in the specified source +directories. At present only source files with a single (configurable) +extension are recognized. That is, *.c and *.cc files will not +both be recognized - only one or the other. See the configuration +options and defaults in the documentation for the [:extensions] +sections of your configuration file (found later in this document). + +Test Files & Executable Test Fixtures +------------------------------------- + +Ceedling builds each individual test file with its accompanying +source file(s) into a single, monolithic test fixture executable. +Test files are recognized by a naming convention: a (configurable) +prefix such as "`test_`" in the file name with the same file extension +as used by your C source files. See the configuration options +and defaults in the documentation for the [:project] and [:extensions] +sections of your configuration file (found later in this document). +Depending on your configuration options, Ceedling can recognize +a variety of test file naming patterns in your test search paths. +For example: `test_some_super_functionality.c`, `TestYourSourceFile.cc`, +or `testing_MyAwesomeCode.C` could each be valid test file +names. Note, however, that Ceedling can recognize only one test +file naming convention per project. + +Ceedling knows what files to compile and link into each individual +test executable by way of the #include list contained in each +test file. Any C source files in the configured search directories +that correspond to the header files included in a test file will +be compiled and linked into the resulting test fixture executable. +From this same #include list, Ceedling knows which files to mock +and compile and link into the test executable (if you use mocks +in your tests). That was a lot of clauses and information in a very +few sentences; the example that follows in a bit will make it clearer. + +By naming your test functions according to convention, Ceedling +will extract and collect into a runner C file calls to all your +test case functions. This runner file handles all the execution +minutiae so that your test file can be quite simple and so that +you never forget to wire up a test function to be executed. In this +generated runner lives the `main()` entry point for the resulting +test executable. There are no configuration options for the +naming convention of your test case functions. A test case function +signature must have these three elements: void return, void +parameter list, and the function name prepended with lowercase +"`test`". In other words, a test function signature should look +like this: `void test``[any name you like]``(void)`. + +A commented sample test file follows on the next page. Also, see +the sample project contained in the Ceedling documentation +bundle. + +```c +// test_foo.c ----------------------------------------------- +#include "unity.h" // compile/link in Unity test framework +#include "types.h" // header file with no *.c file -- no compilation/linking +#include "foo.h" // source file foo.c under test +#include "mock_bar.h" // bar.h will be found and mocked as mock_bar.c + compiled/linked in; + // foo.c includes bar.h and uses functions declared in it +#include "mock_baz.h" // baz.h will be found and mocked as mock_baz.c + compiled/linked in + // foo.c includes baz.h and uses functions declared in it + + +void setUp(void) {} // every test file requires this function; + // setUp() is called by the generated runner before each test case function + +void tearDown(void) {} // every test file requires this function; + // tearDown() is called by the generated runner before each test case function + +// a test case function +void test_Foo_Function1_should_Call_Bar_AndGrill(void) +{ + Bar_AndGrill_Expect(); // setup function from mock_bar.c that instructs our + // framework to expect Bar_AndGrill() to be called once + TEST_ASSERT_EQUAL(0xFF, Foo_Function1()); // assertion provided by Unity + // Foo_Function1() calls Bar_AndGrill() & returns a byte +} + +// another test case function +void test_Foo_Function2_should_Call_Baz_Tec(void) +{ + Baz_Tec_ExpectAnd_Return(1); // setup function provided by mock_baz.c that instructs our + // framework to expect Baz_Tec() to be called once and return 1 + TEST_ASSERT_TRUE(Foo_Function2()); // assertion provided by Unity +} + +// end of test_foo.c ---------------------------------------- +``` + +From the test file specified above Ceedling will generate `test_foo_runner.c`; +this runner file will contain `main()` and call both of the example +test case functions. + +The final test executable will be `test_foo.exe` (for Windows +machines or `test_foo.out` for *nix systems - depending on default +or configured file extensions). Based on the #include list above, +the test executable will be the output of the linker having processed +`unity.o`, `foo.o`, `mock_bar.o`, `mock_baz.o`, `test_foo.o`, +and `test_foo_runner.o`. Ceedling finds the files, generates +mocks, generates a runner, compiles all the files, and links +everything into the test executable. Ceedling will then run +the test executable and collect test results from it to be reported +to the developer at the command line. + +For more on the assertions and mocks shown, consult the documentation +for Unity and CMock. + +The Magic of Dependency Tracking +-------------------------------- + +Ceedling is pretty smart in using Rake to build up your project's +dependencies. This means that Ceedling automagically rebuilds +all the appropriate files in your project when necessary: when +your configuration changes, Ceedling or any of the other tools +are updated, or your source or test files change. For instance, +if you modify a header file that is mocked, Ceedling will ensure +that the mock is regenerated and all tests that use that mock are +rebuilt and re-run when you initiate a relevant testing task. +When you see things rebuilding, it's for a good reason. Ceedling +attempts to regenerate and rebuild only what's needed for a given +execution of a task. In the case of large projects, assembling +dependencies and acting upon them can cause some delay in executing +tasks. + +With one exception, the trigger to rebuild or regenerate a file +is always a disparity in timestamps between a target file and +its source - if an input file is newer than its target dependency, +the target is rebuilt or regenerated. For example, if the C source +file from which an object file is compiled is newer than that object +file on disk, recompilation will occur (of course, if no object +file exists on disk, compilation will always occur). The one +exception to this dependency behavior is specific to your input +configuration. Only if your logical configuration changes +will a system-wide rebuild occur. Reorganizing your input configuration +or otherwise updating its file timestamp without modifying +the values within the file will not trigger a rebuild. This behavior +handles the various ways in which your input configuration can +change (discussed later in this document) without having changed +your actual project YAML file. + +Ceedling needs a bit of help to accomplish its magic with deep +dependencies. Shallow dependencies are straightforward: +a mock is dependent on the header file from which it's generated, +a test file is dependent upon the source files it includes (see +the preceding conventions section), etc. Ceedling handles +these "out of the box." Deep dependencies are specifically a +C-related phenomenon and occur as a consequence of include statements +within C source files. Say a source file includes a header file +and that header file in turn includes another header file which +includes still another header file. A change to the deepest header +file should trigger a recompilation of the source file, a relinking +of all the object files comprising a test fixture, and a new execution +of that test fixture. + +Ceedling can handle deep dependencies but only with the help +of a C preprocessor. Ceedling is quite capable, but a full C preprocessor +it ain't. Your project can be configured to use a C preprocessor +or not. Simple projects or large projects constructed so as to +be quite flat in their include structure generally don't need +deep dependency preprocessing - and can enjoy the benefits of +faster execution. Legacy code, on the other hand, will almost +always want to be tested with deep preprocessing enabled. Set +up of the C preprocessor is covered in the documentation for the +[:project] and [:tools] section of the configuration file (later +in this document). Ceedling contains all the configuration +necessary to use the gcc preprocessor by default. That is, as +long as gcc is in your system search path, deep preprocessing +of deep dependencies is available to you by simply enabling it +in your project configuration file. + +Ceedling's Build Output +----------------------- + +Ceedling requires a top-level build directory for all the stuff +that it, the accompanying test tools, and your toolchain generate. +That build directory's location is configured in the [:project] +section of your configuration file (discussed later). There +can be a ton of generated files. By and large, you can live a full +and meaningful life knowing absolutely nothing at all about +the files and directories generated below the root build directory. + +As noted already, it's good practice to add your top-level build +directory to source control but nothing generated beneath it. +You'll spare yourself headache if you let Ceedling delete and +regenerate files and directories in a non-versioned corner +of your project's filesystem beneath the top-level build directory. + +The `artifacts` directory is the one and only directory you may +want to know about beneath the top-level build directory. The +subdirectories beneath `artifacts` will hold your binary release +target output (if your project is configured for release builds) +and will serve as the conventional location for plugin output. +This directory structure was chosen specifically because it +tends to work nicely with Continuous Integration setups that +recognize and list build artifacts for retrieval / download. + +The Almighty Project Configuration File (in Glorious YAML) +---------------------------------------------------------- + +Please consult YAML documentation for the finer points of format +and to understand details of our YAML-based configuration file. +We recommend [Wikipedia's entry on YAML](http://en.wikipedia.org/wiki/Yaml) +for this. A few highlights from that reference page: + +* YAML streams are encoded using the set of printable Unicode + characters, either in UTF-8 or UTF-16 + +* Whitespace indentation is used to denote structure; however + tab characters are never allowed as indentation + +* Comments begin with the number sign ( # ), can start anywhere + on a line, and continue until the end of the line unless enclosed + by quotes + +* List members are denoted by a leading hyphen ( - ) with one member + per line, or enclosed in square brackets ( [ ] ) and separated + by comma space ( , ) + +* Hashes are represented using the colon space ( : ) in the form + key: value, either one per line or enclosed in curly braces + ( { } ) and separated by comma space ( , ) + +* Strings (scalars) are ordinarily unquoted, but may be enclosed + in double-quotes ( " ), or single-quotes ( ' ) + +* YAML requires that colons and commas used as list separators + be followed by a space so that scalar values containing embedded + punctuation can generally be represented without needing + to be enclosed in quotes + +* Repeated nodes are initially denoted by an ampersand ( & ) and + thereafter referenced with an asterisk ( * ) + + +Notes on what follows: + +* Each of the following sections represent top-level entries + in the YAML configuration file. + +* Unless explicitly specified in the configuration file, default + values are used by Ceedling. + +* These three settings, at minimum, must be specified: + * [:project][:build_root] + * [:paths][:source] + * [:paths][:test] + +* As much as is possible, Ceedling validates your settings in + properly formed YAML. + +* Improperly formed YAML will cause a Ruby error when the YAML + is parsed. This is usually accompanied by a complaint with + line and column number pointing into the project file. + +* Certain advanced features rely on gcc and cpp as preprocessing + tools. In most *nix systems, these tools are already available. + For Windows environments, we recommend the [mingw project](http://www.mingw.org/) + (Minimalist GNU for Windows). + +* Ceedling is primarily meant as a build tool to support automated + unit testing. All the heavy lifting is involved there. Creating + a simple binary release build artifact is quite trivial in + comparison. Consequently, most default options and the construction + of Ceedling itself is skewed towards supporting testing though + Ceedling can, of course, build your binary release artifact + as well. Note that complex binary release artifacts (e.g. + application + bootloader or multiple libraries) are beyond + Ceedling's release build ability. + + +Conventions / features of Ceedling-specific YAML: + +* Any second tier setting keys anywhere in YAML whose names end + in `_path` or `_paths` are automagically processed like all + Ceedling-specific paths in the YAML to have consistent directory + separators (i.e. "/") and to take advantage of inline Ruby + string expansion (see [:environment] setting below for further + explanation of string expansion). + + +**Let's Be Careful Out There:** Ceedling performs validation +on the values you set in your configuration file (this assumes +your YAML is correct and will not fail format parsing, of course). +That said, validation is limited to only those settings Ceedling +uses and those that can be reasonably validated. Ceedling does +not limit what can exist within your configuration file. In this +way, you can take full advantage of YAML as well as add sections +and values for use in your own custom plugins (documented later). +The consequence of this is simple but important. A misspelled +configuration section name or value name is unlikely to cause +Ceedling any trouble. Ceedling will happily process that section +or value and simply use the properly spelled default maintained +internally - thus leading to unexpected behavior without warning. + +project: global project settings + + +* `build_root`: + + Top level directory into which generated path structure and files are + placed. Note: this is one of the handful of configuration values that + must be set. The specified path can be absolute or relative to your + working directory. + + **Default**: (none) + +* `use_exceptions`: + + Configures the build environment to make use of CException. Note that + if you do not use exceptions, there's no harm in leaving this as its + default value. + + **Default**: TRUE + +* `use_mocks`: + + Configures the build environment to make use of CMock. Note that if + you do not use mocks, there's no harm in leaving this setting as its + default value. + + **Default**: TRUE + +* `use_test_preprocessor`: + + This option allows Ceedling to work with test files that contain + conditional compilation statements (e.g. #ifdef) and header files you + wish to mock that contain conditional preprocessor statements and/or + macros. + + Ceedling and CMock are advanced tools with sophisticated parsers. + However, they do not include entire C language preprocessors. + Consequently, with this option enabled, Ceedling will use gcc's + preprocessing mode and the cpp preprocessor tool to strip down / + expand test files and headers to their applicable content which can + then be processed by Ceedling and CMock. + + With this option enabled, the gcc & cpp tools must exist in an + accessible system search path and test runner files are always + regenerated. + + **Default**: FALSE + +* `use_deep_dependencies`: + + The base rules and tasks that Ceedling creates using Rake capture most + of the dependencies within a standard project (e.g. when the source + file accompanying a test file changes, the corresponding test fixture + executable will be rebuilt when tests are re-run). However, deep + dependencies cannot be captured this way. If a typedef or macro + changes in a header file three levels of #include statements deep, + this option allows the appropriate incremental build actions to occur + for both test execution and release builds. + + This is accomplished by using the dependencies discovery mode of gcc. + With this option enabled, gcc must exist in an accessible system + search path. + + **Default**: FALSE + +* `generate_deep_dependencies`: + + When `use_deep_dependencies` is set to TRUE, Ceedling will run a separate + build step to generate the deep dependencies. If you are using gcc as your + primary compiler, or another compiler that can generate makefile rules as + a side effect of compilation, then you can set this to FALSE to avoid the + extra build step but still use the deep dependencies data when deciding + which source files to rebuild. + + **Default**: TRUE + +* `test_file_prefix`: + + Ceedling collects test files by convention from within the test file + search paths. The convention includes a unique name prefix and a file + extension matching that of source files. + + Why not simply recognize all files in test directories as test files? + By using the given convention, we have greater flexibility in what we + do with C files in the test directories. + + **Default**: "test_" + +* `options_paths`: + + Just as you may have various build configurations for your source + codebase, you may need variations of your project configuration. + + By specifying options paths, Ceedling will search for other project + YAML files, make command line tasks available (ceedling options:variation + for a variation.yml file), and merge the project configuration of + these option files in with the main project file at runtime. See + advanced topics. + + Note these Rake tasks at the command line - like verbosity or logging + control - must come before the test or release task they are meant to + modify. + + **Default**: [] (empty) + +* `release_build`: + + When enabled, a release Rake task is exposed. This configuration + option requires a corresponding release compiler and linker to be + defined (gcc is used as the default). + + More release configuration options are available in the release_build + section. + + **Default**: FALSE + + +Example `[:project]` YAML blurb + +```yaml +:project: + :build_root: project_awesome/build + :use_exceptions: FALSE + :use_test_preprocessor: TRUE + :use_deep_dependencies: TRUE + :options_paths: + - project/options + - external/shared/options + :release_build: TRUE +``` + +Ceedling is primarily concerned with facilitating the somewhat +complicated mechanics of automating unit tests. The same mechanisms +are easily capable of building a final release binary artifact +(i.e. non test code; the thing that is your final working software +that you execute on target hardware). + + +* `output`: + + The name of your release build binary artifact to be found in /artifacts/release. Ceedling sets the default artifact file + extension to that as is explicitly specified in the [:extensions] + section or as is system specific otherwise. + + **Default**: `project.exe` or `project.out` + +* `use_assembly`: + + If assembly code is present in the source tree, this option causes + Ceedling to create appropriate build directories and use an assembler + tool (default is the GNU tool as - override available in the [:tools] + section. + + **Default**: FALSE + +* `artifacts`: + + By default, Ceedling copies to the /artifacts/release + directory the output of the release linker and (optionally) a map + file. Many toolchains produce other important output files as well. + Adding a file path to this list will cause Ceedling to copy that file + to the artifacts directory. The artifacts directory is helpful for + organizing important build output files and provides a central place + for tools such as Continuous Integration servers to point to build + output. Selectively copying files prevents incidental build cruft from + needlessly appearing in the artifacts directory. Note that inline Ruby + string replacement is available in the artifacts paths (see discussion + in the [:environment] section). + + **Default**: [] (empty) + +Example `[:release_build]` YAML blurb + +```yaml +:release_build: + :output: top_secret.bin + :use_assembly: TRUE + :artifacts: + - build/release/out/c/top_secret.s19 +``` + +**paths**: options controlling search paths for source and header +(and assembly) files + +* `test`: + + All C files containing unit test code. Note: this is one of the + handful of configuration values that must be set. + + **Default**: [] (empty) + +* `source`: + + All C files containing release code (code to be tested). Note: this is + one of the handful of configuration values that must be set. + + **Default**: [] (empty) + +* `support`: + + Any C files you might need to aid your unit testing. For example, on + occasion, you may need to create a header file containing a subset of + function signatures matching those elsewhere in your code (e.g. a + subset of your OS functions, a portion of a library API, etc.). Why? + To provide finer grained control over mock function substitution or + limiting the size of the generated mocks. + + **Default**: [] (empty) + +* `include`: + + Any header files not already in the source search path. Note there's + no practical distinction between this search path and the source + search path; it's merely to provide options or to support any + peculiar source tree organization. + + **Default**: [] (empty) + +* `test_toolchain_include`: + + System header files needed by the test toolchain - should your + compiler be unable to find them, finds the wrong system include search + path, or you need a creative solution to a tricky technical problem. + Note that if you configure your own toolchain in the [:tools] section, + this search path is largely meaningless to you. However, this is a + convenient way to control the system include path should you rely on + the default gcc tools. + + **Default**: [] (empty) + +* `release_toolchain_include`: + + Same as preceding albeit related to the release toolchain. + + **Default**: [] (empty) + +* `` + + Any paths you specify for custom list. List is available to tool + configurations and/or plugins. Note a distinction. The preceding names + are recognized internally to Ceedling and the path lists are used to + build collections of files contained in those paths. A custom list is + just that - a custom list of paths. + +Notes on path grammar within the [:paths] section: + +* Order of search paths listed in [:paths] is preserved when used by an + entry in the [:tools] section + +* Wherever multiple path lists are combined for use Ceedling prioritizes + path groups as follows: + test paths, support paths, source paths, include paths. + + This can be useful, for instance, in certain testing scenarios where + we desire Ceedling or the compiler to find a stand-in header file before + the actual source header file of the same name. + +* Paths: + + 1. can be absolute or relative + + 2. can be singly explicit - a single fully specified path + + 3. can include a glob operator (more on this below) + + 4. can use inline Ruby string replacement (see [:environment] + section for more) + + 5. default as an addition to a specific search list (more on this + in the examples) + + 6. can act to subtract from a glob included in the path list (more + on this in the examples) + + +[Globs](http://ruby.about.com/od/beginningruby/a/dir2.htm) +as used by Ceedling are wildcards for specifying directories +without the need to list each and every required search path. +Ceedling globs operate just as Ruby globs except that they are +limited to matching directories and not files. Glob operators +include the following * ** ? [-] {,} (note: this list is space separated +and not comma separated as commas are used within the bracket +operators). + +* `*`: + + All subdirectories of depth 1 below the parent path and including the + parent path + +* `**`: + + All subdirectories recursively discovered below the parent path and + including the parent path + +* `?`: + + Single alphanumeric character wildcard + +* `[x-y]`: + + Single alphanumeric character as found in the specified range + +* `{x,y}`: + + Single alphanumeric character from the specified list + +Example [:paths] YAML blurbs + +```yaml +:paths: + :source: #together the following comprise all source search paths + - project/source/* #expansion yields all subdirectories of depth 1 plus parent directory + - project/lib #single path + :test: #all test search paths + - project/**/test? #expansion yields any subdirectory found anywhere in the project that + #begins with "test" and contains 5 characters + +:paths: + :source: #all source search paths + - +:project/source/** #all subdirectories recursively discovered plus parent directory + - -:project/source/os/generated #subtract os/generated directory from expansion of above glob + #note that '+:' notation is merely aesthetic; default is to add + + :test: #all test search paths + - project/test/bootloader #explicit, single search paths (searched in the order specified) + - project/test/application + - project/test/utilities + + :custom: #custom path list + - "#{PROJECT_ROOT}/other" #inline Ruby string expansion +``` + +Globs and inline Ruby string expansion can require trial and +error to arrive at your intended results. Use the `ceedling paths:*` +command line options (documented in preceding section) to verify +your settings. + +Ceedling relies on file collections automagically assembled +from paths, globs, and file extensions. File collections greatly +simplify project set up. However, sometimes you need to remove +from or add individual files to those collections. + + +* `test`: + + Modify the collection of unit test C files. + + **Default**: [] (empty) + +* `source`: + + Modify the collection of all source files used in unit test builds and release builds. + + **Default**: [] (empty) + +* `assembly`: + + Modify the (optional) collection of assembly files used in release builds. + + **Default**: [] (empty) + +* `include`: + + Modify the collection of all source header files used in unit test builds (e.g. for mocking) and release builds. + + **Default**: [] (empty) + +* `support`: + + Modify the collection of supporting C files available to unit tests builds. + + **Default**: [] (empty) + + +Note: All path grammar documented in [:paths] section applies +to [:files] path entries - albeit at the file path level and not +the directory level. + +Example [:files] YAML blurb + +```yaml +:files: + :source: + - callbacks/comm.c # entry defaults to file addition + - +:callbacks/comm*.c # add all comm files matching glob pattern + - -:source/board/atm134.c # not our board + :test: + - -:test/io/test_output_manager.c # remove unit tests from test build +``` + +**environment:** inserts environment variables into the shell +instance executing configured tools + +Ceedling creates environment variables from any key / value +pairs in the environment section. Keys become an environment +variable name in uppercase. The values are strings assigned +to those environment variables. These value strings are either +simple string values in YAML or the concatenation of a YAML array. + +Ceedling is able to execute inline Ruby string substitution +code to set environment variables. This evaluation occurs when +the project file is first processed for any environment pair's +value string including the Ruby string substitution pattern +`#{…}`. Note that environment value strings that _begin_ with +this pattern should always be enclosed in quotes. YAML defaults +to processing unquoted text as a string; quoting text is optional. +If an environment pair's value string begins with the Ruby string +substitution pattern, YAML will interpret the string as a Ruby +comment (because of the `#`). Enclosing each environment value +string in quotes is a safe practice. + +[:environment] entries are processed in the configured order +(later entries can reference earlier entries). + +Special case: PATH handling + +In the specific case of specifying an environment key named _path_, +an array of string values will be concatenated with the appropriate +platform-specific path separation character (e.g. ':' on *nix, +';' on Windows). All other instances of environment keys assigned +YAML arrays use simple concatenation. + +Example [:environment] YAML blurb + +```yaml +:environment: + - :license_server: gizmo.intranet #LICENSE_SERVER set with value "gizmo.intranet" + - :license: "#{`license.exe`}" #LICENSE set to string generated from shelling out to + #execute license.exe; note use of enclosing quotes + + - :path: #concatenated with path separator (see special case above) + - Tools/gizmo/bin #prepend existing PATH with gizmo path + - "#{ENV['PATH']}" #pattern #{…} triggers ruby evaluation string substitution + #note: value string must be quoted because of '#' + + - :logfile: system/logs/thingamabob.log #LOGFILE set with path for a log file +``` + +**extension**: configure file name extensions used to collect lists of files searched in [:paths] + +* `header`: + + C header files + + **Default**: .h + +* `source`: + + C code files (whether source or test files) + + **Default**: .c + +* `assembly`: + + Assembly files (contents wholly assembly instructions) + + **Default**: .s + +* `object`: + + Resulting binary output of C code compiler (and assembler) + + **Default**: .o + +* `executable`: + + Binary executable to be loaded and executed upon target hardware + + **Default**: .exe or .out (Win or *nix) + +* `testpass`: + + Test results file (not likely to ever need a new value) + + **Default**: .pass + +* `testfail`: + + Test results file (not likely to ever need a new value) + + **Default**: .fail + +* `dependencies`: + + File containing make-style dependency rules created by gcc preprocessor + + **Default**: .d + + +Example [:extension] YAML blurb + + :extension: + :source: .cc + :executable: .bin + +**defines**: command line defines used in test and release compilation by configured tools + +* `test`: + + Defines needed for testing. Useful for: + + 1. test files containing conditional compilation statements (i.e. + tests active in only certain contexts) + + 2. testing legacy source wherein the isolation of source under test + afforded by Ceedling and its complementary tools leaves certain + symbols unset when source files are compiled in isolation + + **Default**: [] (empty) + +* `test_preprocess`: + + If [:project][:use_test_preprocessor] or + [:project][:use_deep_dependencies] is set and code is structured in a + certain way, the gcc preprocessor may need symbol definitions to + properly preprocess files to extract function signatures for mocking + and extract deep dependencies for incremental builds. + + **Default**: [] (empty) + +* `release`: + + Defines needed for the release build binary artifact. + + **Default**: [] (empty) + +* `release_preprocess`: + + If [:project][:use_deep_dependencies] is set and code is structured in + a certain way, the gcc preprocessor may need symbol definitions to + properly preprocess files for incremental release builds due to deep + dependencies. + + **Default**: [] (empty) + + +Example [:defines] YAML blurb + +```yaml +:defines: + :test: + - UNIT_TESTING #for select cases in source to allow testing with a changed behavior or interface + - OFF=0 + - ON=1 + - FEATURE_X=ON + :source: + - FEATURE_X=ON +``` + + +**libraries**: command line defines used in test and release compilation by configured tools + +Ceedling allows you to pull in specific libraries for the purpose of release and test builds. +It has a few levels of support for this. Start by adding a :libraries main section in your +configuration. In this section, you can optionally have the following subsections: + +* `test`: + + Library files that should be injected into your tests when linking occurs. + These can be specified as either relative or absolute paths. These files MUST + exist when the test attempts to build. + +* `source`: + + Library files that should be injected into your release when linking occurs. These + can be specified as either relative or absolute paths. These files MUST exist when + the release attempts to build UNLESS you are using the subprojects plugin. In that + case, it will attempt to build that library for you as a dynamic dependency. + +* `system`: + + These libraries are assumed to be in the tool path somewhere and shouldn't need to be + specified. The libraries added here will be injected into releases and tests. + +* `flag`: + + This is the method of adding an argument for each library. For example, gcc really likes + it when you specify “-l${1}†+ +Notes: + +* If you've specified your own link step, you are going to want to add ${4} to your argument +list in the place where library files should be added to the command call. For gcc, this is +often the very end. Other tools may vary. + + +**flags**: configure per-file compilation and linking flags + +Ceedling tools (see later [:tools] section) are used to configure +compilation and linking of test and source files. These tool +configurations are a one-size-fits-all approach. Should individual files +require special compilation or linking flags, the settings in the +[:flags] section work in conjunction with tool definitions by way of +argument substitution to achieve this. + +* `release`: + + [:compile] or [:link] flags for release build + +* `test`: + + [:compile] or [:link] flags for test build + +Notes: + +* Ceedling works with the [:release] and [:test] build contexts + as-is; plugins can add additional contexts + +* Only [:compile] and [:link] are recognized operations beneath + a context + +* File specifiers do not include a path or file extension + +* File specifiers are case sensitive (must match original file + name) + +* File specifiers do support regular expressions if encased in quotes + +* '*' is a special (optional) file specifier to provide flags + to all files not otherwise specified + + +Example [:flags] YAML blurb + +```yaml +:flags: + :release: + :compile: + :main: # add '-Wall' to compilation of main.c + - -Wall + :fan: # add '--O2' to compilation of fan.c + - --O2 + :'test_.+': # add '-pedantic' to all test-files + - -pedantic + :*: # add '-foo' to compilation of all files not main.c or fan.c + - -foo + :test: + :compile: + :main: # add '--O1' to compilation of main.c as part of test builds including main.c + - --O1 + :link: + :test_main: # add '--bar --baz' to linking of test_main.exe + - --bar + - --baz +``` + +Ceedling sets values for a subset of CMock settings. All CMock +options are available to be set, but only those options set by +Ceedling in an automated fashion are documented below. See CMock +documentation. + +**cmock**: configure CMock's code generation options and set symbols used to modify CMock's compiled features +Ceedling sets values for a subset of CMock settings. All CMock options are available to be set, but only those options set by Ceedling in an automated fashion are documented below. See CMock documentation. + +* `enforce_strict_ordering`: + + Tests fail if expected call order is not same as source order + + **Default**: TRUE + +* `mock_path`: + + Path for generated mocks + + **Default**: /tests/mocks + +* `defines`: + + List of conditional compilation symbols used to configure CMock's + compiled features. See CMock documentation to understand available + options. No symbols must be set unless defaults are inappropriate for + your specific environment. All symbols are used only by Ceedling to + compile CMock C code; contents of [:defines] are ignored by CMock's + Ruby code when instantiated. + + **Default**: [] (empty) + +* `verbosity`: + + If not set, defaults to Ceedling's verbosity level + +* `plugins`: + + If [:project][:use_exceptions] is enabled, the internal plugins list is pre-populated with 'cexception'. + + Whether or not you have included [:cmock][:plugins] in your + configuration file, Ceedling automatically adds 'cexception' to the + plugin list if exceptions are enabled. To add to the list Ceedling + provides CMock, simply add [:cmock][:plugins] to your configuration + and specify your desired additional plugins. + +* `includes`: + + If [:cmock][:unity_helper] set, pre-populated with unity_helper file + name (no path). + + The [:cmock][:includes] list works identically to the plugins list + above with regard to adding additional files to be inserted within + mocks as #include statements. + + +The last four settings above are directly tied to other Ceedling +settings; hence, why they are listed and explained here. The +first setting above, [:enforce_strict_ordering], defaults +to FALSE within CMock. It is set to TRUE by default in Ceedling +as our way of encouraging you to use strict ordering. It's a teeny +bit more expensive in terms of code generated, test execution +time, and complication in deciphering test failures. However, +it's good practice. And, of course, you can always disable it +by overriding the value in the Ceedling YAML configuration file. + + +**cexception**: configure symbols used to modify CException's compiled features + +* `defines`: + + List of conditional compilation symbols used to configure CException's + features in its source and header files. See CException documentation + to understand available options. No symbols must be set unless the + defaults are inappropriate for your specific environment. + + **Default**: [] (empty) + + +**unity**: configure symbols used to modify Unity's compiled features + +* `defines`: + + List of conditional compilation symbols used to configure Unity's + features in its source and header files. See Unity documentation to + understand available options. No symbols must be set unless the + defaults are inappropriate for your specific environment. Most Unity + defines can be easily configured through the YAML file. + + **Default**: [] (empty) + +Example [:unity] YAML blurbs +```yaml +:unity: #itty bitty processor & toolchain with limited test execution options + :defines: + - UNITY_INT_WIDTH=16 #16 bit processor without support for 32 bit instructions + - UNITY_EXCLUDE_FLOAT #no floating point unit + +:unity: #great big gorilla processor that grunts and scratches + :defines: + - UNITY_SUPPORT_64 #big memory, big counters, big registers + - UNITY_LINE_TYPE=\"unsigned int\" #apparently we're using really long test files, + - UNITY_COUNTER_TYPE=\"unsigned int\" #and we've got a ton of test cases in those test files + - UNITY_FLOAT_TYPE=\"double\" #you betcha +``` + + +Notes on Unity configuration: + +* **Verification** - Ceedling does no verification of your configuration + values. In a properly configured setup, your Unity configuration + values are processed, collected together with any test define symbols + you specify elsewhere, and then passed to your toolchain during test + compilation. Unity's conditional compilation statements, your + toolchain's preprocessor, and/or your toolchain's compiler will + complain appropriately if your specified configuration values are + incorrect, incomplete, or incompatible. + +* **Routing $stdout** - Unity defaults to using `putchar()` in C's + standard library to display test results. For more exotic environments + than a desktop with a terminal (e.g. running tests directly on a + non-PC target), you have options. For example, you could create a + routine that transmits a character via RS232 or USB. Once you have + that routine, you can replace `putchar()` calls in Unity by overriding + the function-like macro `UNITY_OUTPUT_CHAR`. Consult your toolchain + and shell documentation. Eventhough this can also be defined in the YAML file + most shell environments do not handle parentheses as command line arguments + very well. To still be able to add this functionality all necessary + options can be defined in the `unity_config.h`. Unity needs to be told to look for + the `unity_config.h` in the YAML file, though. + +Example [:unity] YAML blurbs +```yaml +:unity: + :defines: + - UNITY_INCLUDE_CONFIG_H +``` + +Example unity_config.h +``` +#ifndef UNITY_CONFIG_H +#define UNITY_CONFIG_H + +#include "uart_output.h" //Helper library for your custom environment + +#define UNITY_INT_WIDTH 16 +#define UNITY_OUTPUT_START() uart_init(F_CPU, BAUD) //Helperfunction to init UART +#define UNITY_OUTPUT_CHAR(a) uart_putchar(a) //Helperfunction to forward char via UART +#define UNITY_OUTPUT_COMPLETE() uart_complete() //Helperfunction to inform that test has ended + +#endif +``` + + +**tools**: a means for representing command line tools for use under +Ceedling's automation framework + +Ceedling requires a variety of tools to work its magic. By default, +the GNU toolchain (gcc, cpp, as) are configured and ready for +use with no additions to the project configuration YAML file. +However, as most work will require a project-specific toolchain, +Ceedling provides a generic means for specifying / overriding +tools. + +* `test_compiler`: + + Compiler for test & source-under-test code + ${1}: input source ${2}: output object ${3}: optional output list ${4}: optional output dependencies file + + **Default**: gcc + +* `test_linker`: + + Linker to generate test fixture executables + ${1}: input objects ${2}: output binary ${3}: optional output map ${4}: optional library list + + **Default**: gcc + +* `test_fixture`: + + Executable test fixture + ${1}: simulator as executable with ${1} as input binary file argument or native test executable + + **Default**: ${1} + +* `test_includes_preprocessor`: + + Extractor of #include statements + ${1}: input source file + + **Default**: cpp + +* `test_file_preprocessor`: + + Preprocessor of test files (macros, conditional compilation statements) + ${1}: input source file ${2}: preprocessed output source file + + **Default**: gcc + +* `test_dependencies_generator`: + + Discovers deep dependencies of source & test (for incremental builds) + ${1}: input source file ${2}: compiled object filepath ${3}: output dependencies file + + **Default**: gcc + +* `release_compiler`: + + Compiler for release source code + ${1}: input source ${2}: output object ${3}: optional output list ${4}: optional output dependencies file + + **Default**: gcc + +* `release_assembler`: + + Assembler for release assembly code + ${1}: input assembly source file ${2}: output object file + + **Default**: as + +* `release_linker`: + + Linker for release source code + ${1}: input objects ${2}: output binary ${3}: optional output map ${4}: optional library list + + **Default**: gcc + +* `release_dependencies_generator`: + + Discovers deep dependencies of source files (for incremental builds) + ${1}: input source file ${2}: compiled object filepath ${3}: output dependencies file + + **Default**: gcc + + +A Ceedling tool has a handful of configurable elements: + +1. [:executable] (required) - Command line executable having + the form of: + +2. [:arguments] (required) - List of command line arguments + and substitutions + +3. [:name] - Simple name (e.g. "nickname") of tool beyond its + executable name (if not explicitly set then Ceedling will + form a name from the tool's YAML entry name) + +4. [:stderr_redirect] - Control of capturing $stderr messages + {:none, :auto, :win, :unix, :tcsh}. + Defaults to :none if unspecified; create a custom entry by + specifying a simple string instead of any of the available + symbols. + +5. [:background_exec] - Control execution as background process + {:none, :auto, :win, :unix}. + Defaults to :none if unspecified. + + +Tool Element Runtime Substitution +--------------------------------- + +To accomplish useful work on multiple files, a configured tool will most +often require that some number of its arguments or even the executable +itself change for each run. Consequently, every tool's argument list and +executable field possess two means for substitution at runtime. Ceedling +provides two kinds of inline Ruby execution and a notation for +populating elements with dynamically gathered values within the build +environment. + +Tool Element Runtime Substitution: Inline Ruby Execution +-------------------------------------------------------- + +In-line Ruby execution works similarly to that demonstrated for the +[:environment] section except that substitution occurs as the tool is +executed and not at the time the configuration file is first scanned. + +* `#{...}`: + + Ruby string substitution pattern wherein the containing string is + expanded to include the string generated by Ruby code between the + braces. Multiple instances of this expansion can occur within a single + tool element entry string. Note that if this string substitution + pattern occurs at the very beginning of a string in the YAML + configuration the entire string should be enclosed in quotes (see the + [:environment] section for further explanation on this point). + +* `{...} `: + + If an entire tool element string is enclosed with braces, it signifies + that Ceedling should execute the Ruby code contained within those + braces. Say you have a collection of paths on disk and some of those + paths include spaces. Further suppose that a single tool that must use + those paths requires those spaces to be escaped, but all other uses of + those paths requires the paths to remain unchanged. You could use this + Ceedling feature to insert Ruby code that iterates those paths and + escapes those spaces in the array as used by the tool of this example. + +Tool Element Runtime Substitution: Notational Substitution +---------------------------------------------------------- + +A Ceedling tool's other form of dynamic substitution relies on a '$' +notation. These '$' operators can exist anywhere in a string and can be +decorated in any way needed. To use a literal '$', escape it as '\\$'. + +* `$`: + + Simple substitution for value(s) globally available within the runtime + (most often a string or an array). + +* `${#}`: + + When a Ceedling tool's command line is expanded from its configured + representation and used within Ceedling Ruby code, certain calls to + that tool will be made with a parameter list of substitution values. + Each numbered substitution corresponds to a position in a parameter + list. Ceedling Ruby code expects that configured compiler and linker + tools will contain ${1} and ${2} replacement arguments. In the case of + a compiler ${1} will be a C code file path, and ${2} will be the file + path of the resulting object file. For a linker ${1} will be an array + of object files to link, and ${2} will be the resulting binary + executable. For an executable test fixture ${1} is either the binary + executable itself (when using a local toolchain such as gcc) or a + binary input file given to a simulator in its arguments. + + +Example [:tools] YAML blurbs + +```yaml +:tools: + :test_compiler: + :executable: compiler #exists in system search path + :name: 'acme test compiler' + :arguments: + - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE #expands to -I search paths + - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR #expands to -I search paths + - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR #expands to all -D defined symbols + - --network-license #simple command line argument + - -optimize-level 4 #simple command line argument + - "#{`args.exe -m acme.prj`}" #in-line ruby sub to shell out & build string of arguments + - -c ${1} #source code input file (Ruby method call param list sub) + - -o ${2} #object file output (Ruby method call param list sub) + :test_linker: + :executable: /programs/acme/bin/linker.exe #absolute file path + :name: 'acme test linker' + :arguments: + - ${1} #list of object files to link (Ruby method call param list sub) + - -l$-lib: #inline yaml array substitution to link in foo-lib and bar-lib + - foo + - bar + - -o ${2} #executable file output (Ruby method call param list sub) + :test_fixture: + :executable: tools/bin/acme_simulator.exe #relative file path to command line simulator + :name: 'acme test fixture' + :stderr_redirect: :win #inform Ceedling what model of $stderr capture to use + :arguments: + - -mem large #simple command line argument + - -f "${1}" #binary executable input file to simulator (Ruby method call param list sub) +``` + +Resulting command line constructions from preceding example [:tools] YAML blurbs + + > compiler -I"/usr/include†-Iâ€project/tests†+ -I"project/tests/support†-Iâ€project/source†-Iâ€project/include†+ -DTEST -DLONG_NAMES -network-license -optimize-level 4 arg-foo + arg-bar arg-baz -c project/source/source.c -o + build/tests/out/source.o + +[notes: (1.) "arg-foo arg-bar arg-baz" is a fabricated example +string collected from $stdout as a result of shell execution +of args.exe +(2.) the -c and -o arguments are +fabricated examples simulating a single compilation step for +a test; ${1} & ${2} are single files] + + > \programs\acme\bin\linker.exe thing.o unity.o + test_thing_runner.o test_thing.o mock_foo.o mock_bar.o -lfoo-lib + -lbar-lib -o build\tests\out\test_thing.exe + +[note: in this scenario ${1} is an array of all the object files +needed to link a test fixture executable] + + > tools\bin\acme_simulator.exe -mem large -f "build\tests\out\test_thing.bin 2>&1†+ +[note: (1.) :executable could have simply been ${1} - if we were compiling +and running native executables instead of cross compiling (2.) we're using +$stderr redirection to allow us to capture simulator error messages to +$stdout for display at the run's conclusion] + + +Notes: + +* The upper case names are Ruby global constants that Ceedling + builds + +* "COLLECTION_" indicates that Ceedling did some work to assemble + the list. For instance, expanding path globs, combining multiple + path globs into a convenient summation, etc. + +* At present, $stderr redirection is primarily used to capture + errors from test fixtures so that they can be displayed at the + conclusion of a test run. For instance, if a simulator detects + a memory access violation or a divide by zero error, this notice + might go unseen in all the output scrolling past in a terminal. + +* The preprocessing tools can each be overridden with non-gcc + equivalents. However, this is an advanced feature not yet + documented and requires that the replacement toolchain conform + to the same conventions used by gcc. + +**Ceedling Collection Used in Compilation**: + +* `COLLECTION_PATHS_TEST`: + + All test paths + +* `COLLECTION_PATHS_SOURCE`: + + All source paths + +* `COLLECTION_PATHS_INCLUDE`: + + All include paths + +* `COLLECTION_PATHS_SUPPORT`: + + All test support paths + +* `COLLECTION_PATHS_SOURCE_AND_INCLUDE`: + + All source and include paths + +* `COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR`: + + All source and include paths + applicable vendor paths (e.g. + CException's source path if exceptions enabled) + +* `COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE`: + + All test toolchain include paths + +* `COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE`: + + All test, source, and include paths + +* `COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR`: + + All test, source, include, and applicable vendor paths (e.g. Unity's + source path plus CMock and CException's source paths if mocks and + exceptions are enabled) + +* `COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE`: + + All release toolchain include paths + +* `COLLECTION_DEFINES_TEST_AND_VENDOR`: + + All symbols specified in [:defines][:test] + symbols defined for + enabled vendor tools - e.g. [:unity][:defines], [:cmock][:defines], + and [:cexception][:defines] + +* `COLLECTION_DEFINES_RELEASE_AND_VENDOR`: + + All symbols specified in [:defines][:release] plus symbols defined by +[:cexception][:defines] if exceptions are ena bled + + +Notes: + +* Other collections exist within Ceedling. However, they are + only useful for advanced features not yet documented. + +* Wherever multiple path lists are combined for use Ceedling prioritizes + path groups as follows: test paths, support paths, source paths, include + paths. + This can be useful, for instance, in certain testing scenarios + where we desire Ceedling or the compiler to find a stand-in header file + before the actual source header file of the same name. + + +**plugins**: Ceedling extensions + +* `load_paths`: + + Base paths to search for plugin subdirectories or extra ruby functionalit + + **Default**: [] (empty) + +* `enabled`: + + List of plugins to be used - a plugin's name is identical to the + subdirectory that contains it (and the name of certain files within + that subdirectory) + + **Default**: [] (empty) + + +Plugins can provide a variety of added functionality to Ceedling. In +general use, it's assumed that at least one reporting plugin will be +used to format test results. However, if no reporting plugins are +specified, Ceedling will print to `$stdout` the (quite readable) raw +test results from all test fixtures executed. + +Example [:plugins] YAML blurb + +```yaml +:plugins: + :load_paths: + - project/tools/ceedling/plugins #home to your collection of plugin directories + - project/support #maybe home to some ruby code your custom plugins share + :enabled: + - stdout_pretty_tests_report #nice test results at your command line + - our_custom_code_metrics_report #maybe you needed line count and complexity metrics, so you + #created a plugin to scan all your code and collect that info +``` + +* `stdout_pretty_tests_report`: + + Prints to $stdout a well-formatted list of ignored and failed tests, + final test counts, and any extraneous output (e.g. printf statements + or simulator memory errors) collected from executing the test + fixtures. Meant to be used with runs at the command line. + +* `stdout_ide_tests_report`: + + Prints to $stdout simple test results formatted such that an IDE + executing test-related Rake tasks can recognize file paths and line + numbers in test failures, etc. Thus, you can click a test result in + your IDE's execution window and jump to the failure (or ignored test) + in your test file (obviously meant to be used with an [IDE like + Eclipse][ide], etc). + + [ide]: http://throwtheswitch.org/white-papers/using-with-ides.html + +* `xml_tests_report`: + + Creates an XML file of test results in the xUnit format (handy for + Continuous Integration build servers or as input to other reporting + tools). Produces a file report.xml in /artifacts/tests. + +* `bullseye`: + + Adds additional Rake tasks to execute tests with the commercial code + coverage tool provided by [Bullseye][]. See readme.txt inside the bullseye + plugin directory for configuration and use instructions. Note: + Bullseye only works with certain compilers and linkers (healthy list + of supported toolchains though). + + [bullseye]: http://www.bullseye.com + +* `gcov`: + + Adds additional Rake tasks to execute tests with the GNU code coverage + tool [gcov][]. See readme.txt inside the gcov directory for configuration + and use instructions. Only works with GNU compiler and linker. + + [gcov]: http://gcc.gnu.org/onlinedocs/gcc/Gcov.html + +* `warnings_report`: + + Scans compiler and linker `$stdout / $stderr` output for the word + 'warning' (case insensitive). All code warnings (or tool warnings) are + logged to a file warnings.log in the appropriate `/artifacts` directory (e.g. test/ for test tasks, `release/` for a + release build, or even `bullseye/` for bullseye runs). + +Module Generator +======================== +Ceedling includes a plugin called module_generator that will create a source, header and test file for you. +There are several possibilities to configure this plugin through your project.yml to suit your project's needs. + +Directory Structure +------------------------------------------- + +The default configuration for directory/project structure is: +```yaml +:module_generator: + :project_root: ./ + :source_root: src/ + :test_root: test/ +``` +You can change these variables in your project.yml file to comply with your project's directory structure. + +If you call `ceedling module:create`, it will create three files: +1. A source file in the source_root +2. A header file in the source_root +3. A test file in the test_root + +If you want your header file to be in another location, +you can specify the ':inc_root:" in your project.yml file: +```yaml +:module_generator: + :inc_root: inc/ +``` +The module_generator will then create the header file in your defined ':inc_root:'. +By default, ':inc_root:' is not defined so the module_generator will use the source_root. + +Sometimes, your project can't be divided into a single src, inc, and test folder. You have several directories +with sources/..., something like this for example: + + - myDriver + - src + - inc + - test + - myOtherDriver + - src + - inc + - test + - ... + +Don't worry, you don't have to manually create the source/header/test files. +The module_generator can accept a path to create a source_root/inc_root/test_root folder with your files: +`ceedling module:create[:]` + +F.e., applied to the above project structure: +`ceedling module:create[myOtherDriver:driver]` +This will make the module_generator run in the subdirectory 'myOtherDriver' and generate the module files +for you in that directory. So, this command will generate the following files: +1. A source file 'driver.c' in /myOtherDriver/ +2. A header file 'driver.h' in /myOtherDriver/ (or if specified) +3. A test file 'test_driver.c' in /myOtherDriver/ + +Naming +------------------------------------------- +By default, the module_generator will generate your files in lowercase. +`ceedling module:create[mydriver]` and `ceedling module:create[myDriver]`(note the uppercase) will generate the same files: +1. mydriver.c +2. mydriver.h +3. test_mydriver.c + +You can configure the module_generator to use a differect naming mechanism through the project.yml: +```yaml +:module_generator: + :naming: "camel" +``` +There are other possibilities as well (bumpy, camel, snake, caps). +Refer to the unity module generator for more info (the unity module generator is used under the hood by module_generator). + +Advanced Topics (Coming) +======================== + +Modifying Your Configuration without Modifying Your Project File: Option Files & User Files +------------------------------------------------------------------------------------------- + +Modifying your project file without modifying your project file + +Debugging and/or printf() +------------------------- + +When you gotta get your hands dirty... + +Ceedling Plays Nice with Others - Using Ceedling for Tests Alongside Another Release Build Setup +------------------------------------------------------------------------------------------------ + +You've got options. + +Adding Handy Rake Tasks for Your Project (without Fancy Pants Custom Plugins) +----------------------------------------------------------------------------- + +Simple as snot. + +Working with Non-Desktop Testing Environments +--------------------------------------------- + +For those crazy platforms lacking command line simulators and for which +cross-compiling on the desktop just ain't gonna get it done. + +Creating Custom Plugins +----------------------- + +Oh boy. This is going to take some explaining. diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/ThrowTheSwitchCodingStandard.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/ThrowTheSwitchCodingStandard.md new file mode 100644 index 0000000..bf4c099 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/ThrowTheSwitchCodingStandard.md @@ -0,0 +1,206 @@ +# ThrowTheSwitch.org Coding Standard + +Hi. Welcome to the coding standard for ThrowTheSwitch.org. For the most part, +we try to follow these standards to unify our contributors' code into a cohesive +unit (puns intended). You might find places where these standards aren't +followed. We're not perfect. Please be polite where you notice these discrepancies +and we'll try to be polite when we notice yours. + +;) + + +## Why Have A Coding Standard? + +Being consistent makes code easier to understand. We've tried to keep +our standard simple because we also believe that we can only expect someone to +follow something that is understandable. Please do your best. + + +## Our Philosophy + +Before we get into details on syntax, let's take a moment to talk about our +vision for these tools. We're C developers and embedded software developers. +These tools are great to test any C code, but catering to embedded software has +made us more tolerant of compiler quirks. There are a LOT of quirky compilers +out there. By quirky I mean "doesn't follow standards because they feel like +they have a license to do as they wish." + +Our philosophy is "support every compiler we can". Most often, this means that +we aim for writing C code that is standards compliant (often C89... that seems +to be a sweet spot that is almost always compatible). But it also means these +tools are tolerant of things that aren't common. Some that aren't even +compliant. There are configuration options to override the size of standard +types. There are configuration options to force Unity to not use certain +standard library functions. A lot of Unity is configurable and we have worked +hard to make it not TOO ugly in the process. + +Similarly, our tools that parse C do their best. They aren't full C parsers +(yet) and, even if they were, they would still have to accept non-standard +additions like gcc extensions or specifying `@0x1000` to force a variable to +compile to a particular location. It's just what we do, because we like +everything to Just Workâ„¢. + +Speaking of having things Just Workâ„¢, that's our second philosophy. By that, we +mean that we do our best to have EVERY configuration option have a logical +default. We believe that if you're working with a simple compiler and target, +you shouldn't need to configure very much... we try to make the tools guess as +much as they can, but give the user the power to override it when it's wrong. + + +## Naming Things + +Let's talk about naming things. Programming is all about naming things. We name +files, functions, variables, and so much more. While we're not always going to +find the best name for something, we actually put a bit of effort into +finding *What Something WANTS to be Called*â„¢. + +When naming things, we follow this hierarchy, the first being the +most important to us (but we do all four when possible): +1. Readable +2. Descriptive +3. Consistent +4. Memorable + + +#### Readable + +We want to read our code. This means we like names and flow that are more +naturally read. We try to avoid double negatives. We try to avoid cryptic +abbreviations (sticking to ones we feel are common). + + +#### Descriptive + +We like descriptive names for things, especially functions and variables. +Finding the right name for something is an important endeavor. You might notice +from poking around our code that this often results in names that are a little +longer than the average. Guilty. We're okay with a bit more typing if it +means our code is easier to understand. + +There are two exceptions to this rule that we also stick to as religiously as +possible: + +First, while we realize hungarian notation (and similar systems for encoding +type information into variable names) is providing a more descriptive name, we +feel that (for the average developer) it takes away from readability and is to be avoided. + +Second, loop counters and other local throw-away variables often have a purpose +which is obvious. There's no need, therefore, to get carried away with complex +naming. We find i, j, and k are better loop counters than loopCounterVar or +whatnot. We only break this rule when we see that more description could improve +understanding of an algorithm. + + +#### Consistent + +We like consistency, but we're not really obsessed with it. We try to name our +configuration macros in a consistent fashion... you'll notice a repeated use of +UNITY_EXCLUDE_BLAH or UNITY_USES_BLAH macros. This helps users avoid having to +remember each macro's details. + + +#### Memorable + +Where ever it doesn't violate the above principles, we try to apply memorable +names. Sometimes this means using something that is simply descriptive, but +often we strive for descriptive AND unique... we like quirky names that stand +out in our memory and are easier to search for. Take a look through the file +names in Ceedling and you'll get a good idea of what we are talking about here. +Why use preprocess when you can use preprocessinator? Or what better describes a +module in charge of invoking tasks during releases than release_invoker? Don't +get carried away. The names are still descriptive and fulfill the above +requirements, but they don't feel stale. + + +## C and C++ Details + +We don't really want to add to the style battles out there. Tabs or spaces? +How many spaces? Where do the braces go? These are age-old questions that will +never be answered... or at least not answered in a way that will make everyone +happy. + +We've decided on our own style preferences. If you'd like to contribute to these +projects (and we hope that you do), then we ask if you do your best to follow +the same. It will only hurt a little. We promise. + + +#### Whitespace + +Our C-style is to use spaces and to use 4 of them per indent level. It's a nice +power-of-2 number that looks decent on a wide-screen. We have no more reason +than that. We break that rule when we have lines that wrap (macros or function +arguments or whatnot). When that happens, we like to indent further to line +things up in nice tidy columns. + +```C + if (stuff_happened) + { + do_something(); + } +``` + + +#### Case + +- Files - all lower case with underscores. +- Variables - all lower case with underscores +- Macros - all caps with underscores. +- Typedefs - all caps with underscores. (also ends with _T). +- Functions - camel cased. Usually named ModuleName_FuncName +- Constants and Globals - camel cased. + + +#### Braces + +The left brace is on the next line after the declaration. The right brace is +directly below that. Everything in between in indented one level. If you're +catching an error and you have a one-line, go ahead and to it on the same line. + +```C + while (blah) + { + //Like so. Even if only one line, we use braces. + } +``` + + +#### Comments + +Do you know what we hate? Old-school C block comments. BUT, we're using them +anyway. As we mentioned, our goal is to support every compiler we can, +especially embedded compilers. There are STILL C compilers out there that only +support old-school block comments. So that is what we're using. We apologize. We +think they are ugly too. + + +## Ruby Details + +Is there really such thing as a Ruby coding standard? Ruby is such a free form +language, it seems almost sacrilegious to suggest that people should comply to +one method! We'll keep it really brief! + + +#### Whitespace + +Our Ruby style is to use spaces and to use 2 of them per indent level. It's a +nice power-of-2 number that really grooves with Ruby's compact style. We have no +more reason than that. We break that rule when we have lines that wrap. When +that happens, we like to indent further to line things up in nice tidy columns. + + +#### Case + +- Files - all lower case with underscores. +- Variables - all lower case with underscores +- Classes, Modules, etc - Camel cased. +- Functions - all lower case with underscores +- Constants - all upper case with underscores + + +## Documentation + +Egad. Really? We use mark down and we like pdf files because they can be made to +look nice while still being portable. Good enough? + + +*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)* diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf new file mode 100644 index 0000000..28f0c32 Binary files /dev/null and b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf differ diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityAssertionsReference.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityAssertionsReference.md new file mode 100644 index 0000000..eb855f3 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityAssertionsReference.md @@ -0,0 +1,779 @@ +# Unity Assertions Reference + +## Background and Overview + +### Super Condensed Version + +- An assertion establishes truth (i.e. boolean True) for a single condition. +Upon boolean False, an assertion stops execution and reports the failure. +- Unity is mainly a rich collection of assertions and the support to gather up +and easily execute those assertions. +- The structure of Unity allows you to easily separate test assertions from +source code in, well, test code. +- Unity's assertions: +- Come in many, many flavors to handle different C types and assertion cases. +- Use context to provide detailed and helpful failure messages. +- Document types, expected values, and basic behavior in your source code for +free. + + +### Unity Is Several Things But Mainly It's Assertions + +One way to think of Unity is simply as a rich collection of assertions you can +use to establish whether your source code behaves the way you think it does. +Unity provides a framework to easily organize and execute those assertions in +test code separate from your source code. + + +### What's an Assertion? + +At their core, assertions are an establishment of truth - boolean truth. Was this +thing equal to that thing? Does that code doohickey have such-and-such property +or not? You get the idea. Assertions are executable code (to appreciate the big +picture on this read up on the difference between +[link:Dynamic Verification and Static Analysis]). A failing assertion stops +execution and reports an error through some appropriate I/O channel (e.g. +stdout, GUI, file, blinky light). + +Fundamentally, for dynamic verification all you need is a single assertion +mechanism. In fact, that's what the [assert() macro in C's standard library](http://en.wikipedia.org/en/wiki/Assert.h) +is for. So why not just use it? Well, we can do far better in the reporting +department. C's `assert()` is pretty dumb as-is and is particularly poor for +handling common data types like arrays, structs, etc. And, without some other +support, it's far too tempting to litter source code with C's `assert()`'s. It's +generally much cleaner, manageable, and more useful to separate test and source +code in the way Unity facilitates. + + +### Unity's Assertions: Helpful Messages _and_ Free Source Code Documentation + +Asserting a simple truth condition is valuable, but using the context of the +assertion is even more valuable. For instance, if you know you're comparing bit +flags and not just integers, then why not use that context to give explicit, +readable, bit-level feedback when an assertion fails? + +That's what Unity's collection of assertions do - capture context to give you +helpful, meaningful assertion failure messages. In fact, the assertions +themselves also serve as executable documentation about types and values in your +source code. So long as your tests remain current with your source and all those +tests pass, you have a detailed, up-to-date view of the intent and mechanisms in +your source code. And due to a wondrous mystery, well-tested code usually tends +to be well designed code. + + +## Assertion Conventions and Configurations + +### Naming and Parameter Conventions + +The convention of assertion parameters generally follows this order: + + TEST_ASSERT_X( {modifiers}, {expected}, actual, {size/count} ) + +The very simplest assertion possible uses only a single "actual" parameter (e.g. +a simple null check). + +"Actual" is the value being tested and unlike the other parameters in an +assertion construction is the only parameter present in all assertion variants. +"Modifiers" are masks, ranges, bit flag specifiers, floating point deltas. +"Expected" is your expected value (duh) to compare to an "actual" value; it's +marked as an optional parameter because some assertions only need a single +"actual" parameter (e.g. null check). +"Size/count" refers to string lengths, number of array elements, etc. + +Many of Unity's assertions are clear duplications in that the same data type +is handled by several assertions. The differences among these are in how failure +messages are presented. For instance, a `_HEX` variant of an assertion prints +the expected and actual values of that assertion formatted as hexadecimal. + + +#### TEST_ASSERT_X_MESSAGE Variants + +_All_ assertions are complemented with a variant that includes a simple string +message as a final parameter. The string you specify is appended to an assertion +failure message in Unity output. + +For brevity, the assertion variants with a message parameter are not listed +below. Just tack on `_MESSAGE` as the final component to any assertion name in +the reference list below and add a string as the final parameter. + +_Example:_ + + TEST_ASSERT_X( {modifiers}, {expected}, actual, {size/count} ) + +becomes messageified like thus... + + TEST_ASSERT_X_MESSAGE( {modifiers}, {expected}, actual, {size/count}, message ) + +Notes: +- The `_MESSAGE` variants intentionally do not support `printf` style formatting + since many embedded projects don't support or avoid `printf` for various reasons. + It is possible to use `sprintf` before the assertion to assemble a complex fail + message, if necessary. +- If you want to output a counter value within an assertion fail message (e.g. from + a loop) , building up an array of results and then using one of the `_ARRAY` + assertions (see below) might be a handy alternative to `sprintf`. + + +#### TEST_ASSERT_X_ARRAY Variants + +Unity provides a collection of assertions for arrays containing a variety of +types. These are documented in the Array section below. These are almost on par +with the `_MESSAGE`variants of Unity's Asserts in that for pretty much any Unity +type assertion you can tack on `_ARRAY` and run assertions on an entire block of +memory. + + TEST_ASSERT_EQUAL_TYPEX_ARRAY( expected, actual, {size/count} ) + +"Expected" is an array itself. +"Size/count" is one or two parameters necessary to establish the number of array +elements and perhaps the length of elements within the array. + +Notes: +- The `_MESSAGE` variant convention still applies here to array assertions. The +`_MESSAGE` variants of the `_ARRAY` assertions have names ending with +`_ARRAY_MESSAGE`. +- Assertions for handling arrays of floating point values are grouped with float +and double assertions (see immediately following section). + + +### TEST_ASSERT_EACH_EQUAL_X Variants + +Unity provides a collection of assertions for arrays containing a variety of +types which can be compared to a single value as well. These are documented in +the Each Equal section below. these are almost on par with the `_MESSAGE` +variants of Unity's Asserts in that for pretty much any Unity type assertion you +can inject _EACH_EQUAL and run assertions on an entire block of memory. + + TEST_ASSERT_EACH_EQUAL_TYPEX( expected, actual, {size/count} ) + +"Expected" is a single value to compare to. +"Actual" is an array where each element will be compared to the expected value. +"Size/count" is one of two parameters necessary to establish the number of array +elements and perhaps the length of elements within the array. + +Notes: +- The `_MESSAGE` variant convention still applies here to Each Equal assertions. +- Assertions for handling Each Equal of floating point values are grouped with +float and double assertions (see immediately following section). + + +### Configuration + +#### Floating Point Support Is Optional + +Support for floating point types is configurable. That is, by defining the +appropriate preprocessor symbols, floats and doubles can be individually enabled +or disabled in Unity code. This is useful for embedded targets with no floating +point math support (i.e. Unity compiles free of errors for fixed point only +platforms). See Unity documentation for specifics. + + +#### Maximum Data Type Width Is Configurable + +Not all targets support 64 bit wide types or even 32 bit wide types. Define the +appropriate preprocessor symbols and Unity will omit all operations from +compilation that exceed the maximum width of your target. See Unity +documentation for specifics. + + +## The Assertions in All Their Blessed Glory + +### Basic Fail and Ignore + +##### `TEST_FAIL()` + +This fella is most often used in special conditions where your test code is +performing logic beyond a simple assertion. That is, in practice, `TEST_FAIL()` +will always be found inside a conditional code block. + +_Examples:_ +- Executing a state machine multiple times that increments a counter your test +code then verifies as a final step. +- Triggering an exception and verifying it (as in Try / Catch / Throw - see the +[CException](https://github.com/ThrowTheSwitch/CException) project). + +##### `TEST_IGNORE()` + +Marks a test case (i.e. function meant to contain test assertions) as ignored. +Usually this is employed as a breadcrumb to come back and implement a test case. +An ignored test case has effects if other assertions are in the enclosing test +case (see Unity documentation for more). + +### Boolean + +##### `TEST_ASSERT (condition)` + +##### `TEST_ASSERT_TRUE (condition)` + +##### `TEST_ASSERT_FALSE (condition)` + +##### `TEST_ASSERT_UNLESS (condition)` + +A simple wording variation on `TEST_ASSERT_FALSE`.The semantics of +`TEST_ASSERT_UNLESS` aid readability in certain test constructions or +conditional statements. + +##### `TEST_ASSERT_NULL (pointer)` + +##### `TEST_ASSERT_NOT_NULL (pointer)` + + +### Signed and Unsigned Integers (of all sizes) + +Large integer sizes can be disabled for build targets that do not support them. +For example, if your target only supports up to 16 bit types, by defining the +appropriate symbols Unity can be configured to omit 32 and 64 bit operations +that would break compilation (see Unity documentation for more). Refer to +Advanced Asserting later in this document for advice on dealing with other word +sizes. + +##### `TEST_ASSERT_EQUAL_INT (expected, actual)` + +##### `TEST_ASSERT_EQUAL_INT8 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_INT16 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_INT32 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_INT64 (expected, actual)` + +##### `TEST_ASSERT_EQUAL (expected, actual)` + +##### `TEST_ASSERT_NOT_EQUAL (expected, actual)` + +##### `TEST_ASSERT_EQUAL_UINT (expected, actual)` + +##### `TEST_ASSERT_EQUAL_UINT8 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_UINT16 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_UINT32 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_UINT64 (expected, actual)` + + +### Unsigned Integers (of all sizes) in Hexadecimal + +All `_HEX` assertions are identical in function to unsigned integer assertions +but produce failure messages with the `expected` and `actual` values formatted +in hexadecimal. Unity output is big endian. + +##### `TEST_ASSERT_EQUAL_HEX (expected, actual)` + +##### `TEST_ASSERT_EQUAL_HEX8 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_HEX16 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_HEX32 (expected, actual)` + +##### `TEST_ASSERT_EQUAL_HEX64 (expected, actual)` + + +### Masked and Bit-level Assertions + +Masked and bit-level assertions produce output formatted in hexadecimal. Unity +output is big endian. + + +##### `TEST_ASSERT_BITS (mask, expected, actual)` + +Only compares the masked (i.e. high) bits of `expected` and `actual` parameters. + + +##### `TEST_ASSERT_BITS_HIGH (mask, actual)` + +Asserts the masked bits of the `actual` parameter are high. + + +##### `TEST_ASSERT_BITS_LOW (mask, actual)` + +Asserts the masked bits of the `actual` parameter are low. + + +##### `TEST_ASSERT_BIT_HIGH (bit, actual)` + +Asserts the specified bit of the `actual` parameter is high. + + +##### `TEST_ASSERT_BIT_LOW (bit, actual)` + +Asserts the specified bit of the `actual` parameter is low. + +### Integer Less Than / Greater Than + +These assertions verify that the `actual` parameter is less than or greater +than `threshold` (exclusive). For example, if the threshold value is 0 for the +greater than assertion will fail if it is 0 or less. + +##### `TEST_ASSERT_GREATER_THAN (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_INT (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_INT8 (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_INT16 (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_INT32 (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_UINT (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_UINT8 (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_UINT16 (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_UINT32 (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_HEX8 (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_HEX16 (threshold, actual)` + +##### `TEST_ASSERT_GREATER_THAN_HEX32 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_INT (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_INT8 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_INT16 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_INT32 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_UINT (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_UINT8 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_UINT16 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_UINT32 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_HEX8 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_HEX16 (threshold, actual)` + +##### `TEST_ASSERT_LESS_THAN_HEX32 (threshold, actual)` + + +### Integer Ranges (of all sizes) + +These assertions verify that the `expected` parameter is within +/- `delta` +(inclusive) of the `actual` parameter. For example, if the expected value is 10 +and the delta is 3 then the assertion will fail for any value outside the range +of 7 - 13. + +##### `TEST_ASSERT_INT_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_INT8_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_INT16_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_INT32_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_INT64_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_UINT_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_UINT8_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_UINT16_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_UINT32_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_UINT64_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_HEX_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_HEX8_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_HEX16_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_HEX32_WITHIN (delta, expected, actual)` + +##### `TEST_ASSERT_HEX64_WITHIN (delta, expected, actual)` + + +### Structs and Strings + +##### `TEST_ASSERT_EQUAL_PTR (expected, actual)` + +Asserts that the pointers point to the same memory location. + + +##### `TEST_ASSERT_EQUAL_STRING (expected, actual)` + +Asserts that the null terminated (`'\0'`)strings are identical. If strings are +of different lengths or any portion of the strings before their terminators +differ, the assertion fails. Two NULL strings (i.e. zero length) are considered +equivalent. + + +##### `TEST_ASSERT_EQUAL_MEMORY (expected, actual, len)` + +Asserts that the contents of the memory specified by the `expected` and `actual` +pointers is identical. The size of the memory blocks in bytes is specified by +the `len` parameter. + + +### Arrays + +`expected` and `actual` parameters are both arrays. `num_elements` specifies the +number of elements in the arrays to compare. + +`_HEX` assertions produce failure messages with expected and actual array +contents formatted in hexadecimal. + +For array of strings comparison behavior, see comments for +`TEST_ASSERT_EQUAL_STRING` in the preceding section. + +Assertions fail upon the first element in the compared arrays found not to +match. Failure messages specify the array index of the failed comparison. + +##### `TEST_ASSERT_EQUAL_INT_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_INT8_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_INT16_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_INT32_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_INT64_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_UINT_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_UINT8_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_UINT16_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_UINT32_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_UINT64_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_HEX_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_HEX8_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_HEX16_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_HEX32_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_HEX64_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_PTR_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_STRING_ARRAY (expected, actual, num_elements)` + +##### `TEST_ASSERT_EQUAL_MEMORY_ARRAY (expected, actual, len, num_elements)` + +`len` is the memory in bytes to be compared at each array element. + + +### Each Equal (Arrays to Single Value) + +`expected` are single values and `actual` are arrays. `num_elements` specifies +the number of elements in the arrays to compare. + +`_HEX` assertions produce failure messages with expected and actual array +contents formatted in hexadecimal. + +Assertions fail upon the first element in the compared arrays found not to +match. Failure messages specify the array index of the failed comparison. + +#### `TEST_ASSERT_EACH_EQUAL_INT (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_INT8 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_INT16 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_INT32 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_INT64 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_UINT (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_UINT8 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_UINT16 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_UINT32 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_UINT64 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_HEX (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_HEX8 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_HEX16 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_HEX32 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_HEX64 (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_PTR (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_STRING (expected, actual, num_elements)` + +#### `TEST_ASSERT_EACH_EQUAL_MEMORY (expected, actual, len, num_elements)` + +`len` is the memory in bytes to be compared at each array element. + + +### Floating Point (If enabled) + +##### `TEST_ASSERT_FLOAT_WITHIN (delta, expected, actual)` + +Asserts that the `actual` value is within +/- `delta` of the `expected` value. +The nature of floating point representation is such that exact evaluations of +equality are not guaranteed. + + +##### `TEST_ASSERT_EQUAL_FLOAT (expected, actual)` + +Asserts that the ?actual?value is "close enough to be considered equal" to the +`expected` value. If you are curious about the details, refer to the Advanced +Asserting section for more details on this. Omitting a user-specified delta in a +floating point assertion is both a shorthand convenience and a requirement of +code generation conventions for CMock. + + +##### `TEST_ASSERT_EQUAL_FLOAT_ARRAY (expected, actual, num_elements)` + +See Array assertion section for details. Note that individual array element +float comparisons are executed using T?EST_ASSERT_EQUAL_FLOAT?.That is, user +specified delta comparison values requires a custom-implemented floating point +array assertion. + + +##### `TEST_ASSERT_FLOAT_IS_INF (actual)` + +Asserts that `actual` parameter is equivalent to positive infinity floating +point representation. + + +##### `TEST_ASSERT_FLOAT_IS_NEG_INF (actual)` + +Asserts that `actual` parameter is equivalent to negative infinity floating +point representation. + + +##### `TEST_ASSERT_FLOAT_IS_NAN (actual)` + +Asserts that `actual` parameter is a Not A Number floating point representation. + + +##### `TEST_ASSERT_FLOAT_IS_DETERMINATE (actual)` + +Asserts that ?actual?parameter is a floating point representation usable for +mathematical operations. That is, the `actual` parameter is neither positive +infinity nor negative infinity nor Not A Number floating point representations. + + +##### `TEST_ASSERT_FLOAT_IS_NOT_INF (actual)` + +Asserts that `actual` parameter is a value other than positive infinity floating +point representation. + + +##### `TEST_ASSERT_FLOAT_IS_NOT_NEG_INF (actual)` + +Asserts that `actual` parameter is a value other than negative infinity floating +point representation. + + +##### `TEST_ASSERT_FLOAT_IS_NOT_NAN (actual)` + +Asserts that `actual` parameter is a value other than Not A Number floating +point representation. + + +##### `TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE (actual)` + +Asserts that `actual` parameter is not usable for mathematical operations. That +is, the `actual` parameter is either positive infinity or negative infinity or +Not A Number floating point representations. + + +### Double (If enabled) + +##### `TEST_ASSERT_DOUBLE_WITHIN (delta, expected, actual)` + +Asserts that the `actual` value is within +/- `delta` of the `expected` value. +The nature of floating point representation is such that exact evaluations of +equality are not guaranteed. + + +##### `TEST_ASSERT_EQUAL_DOUBLE (expected, actual)` + +Asserts that the `actual` value is "close enough to be considered equal" to the +`expected` value. If you are curious about the details, refer to the Advanced +Asserting section for more details. Omitting a user-specified delta in a +floating point assertion is both a shorthand convenience and a requirement of +code generation conventions for CMock. + + +##### `TEST_ASSERT_EQUAL_DOUBLE_ARRAY (expected, actual, num_elements)` + +See Array assertion section for details. Note that individual array element +double comparisons are executed using `TEST_ASSERT_EQUAL_DOUBLE`.That is, user +specified delta comparison values requires a custom implemented double array +assertion. + + +##### `TEST_ASSERT_DOUBLE_IS_INF (actual)` + +Asserts that `actual` parameter is equivalent to positive infinity floating +point representation. + + +##### `TEST_ASSERT_DOUBLE_IS_NEG_INF (actual)` + +Asserts that `actual` parameter is equivalent to negative infinity floating point +representation. + + +##### `TEST_ASSERT_DOUBLE_IS_NAN (actual)` + +Asserts that `actual` parameter is a Not A Number floating point representation. + + +##### `TEST_ASSERT_DOUBLE_IS_DETERMINATE (actual)` + +Asserts that `actual` parameter is a floating point representation usable for +mathematical operations. That is, the ?actual?parameter is neither positive +infinity nor negative infinity nor Not A Number floating point representations. + + +##### `TEST_ASSERT_DOUBLE_IS_NOT_INF (actual)` + +Asserts that `actual` parameter is a value other than positive infinity floating +point representation. + + +##### `TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF (actual)` + +Asserts that `actual` parameter is a value other than negative infinity floating +point representation. + + +##### `TEST_ASSERT_DOUBLE_IS_NOT_NAN (actual)` + +Asserts that `actual` parameter is a value other than Not A Number floating +point representation. + + +##### `TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE (actual)` + +Asserts that `actual` parameter is not usable for mathematical operations. That +is, the `actual` parameter is either positive infinity or negative infinity or +Not A Number floating point representations. + + +## Advanced Asserting: Details On Tricky Assertions + +This section helps you understand how to deal with some of the trickier +assertion situations you may run into. It will give you a glimpse into some of +the under-the-hood details of Unity's assertion mechanisms. If you're one of +those people who likes to know what is going on in the background, read on. If +not, feel free to ignore the rest of this document until you need it. + + +### How do the EQUAL assertions work for FLOAT and DOUBLE? + +As you may know, directly checking for equality between a pair of floats or a +pair of doubles is sloppy at best and an outright no-no at worst. Floating point +values can often be represented in multiple ways, particularly after a series of +operations on a value. Initializing a variable to the value of 2.0 is likely to +result in a floating point representation of 2 x 20,but a series of +mathematical operations might result in a representation of 8 x 2-2 +that also evaluates to a value of 2. At some point repeated operations cause +equality checks to fail. + +So Unity doesn't do direct floating point comparisons for equality. Instead, it +checks if two floating point values are "really close." If you leave Unity +running with defaults, "really close" means "within a significant bit or two." +Under the hood, `TEST_ASSERT_EQUAL_FLOAT` is really `TEST_ASSERT_FLOAT_WITHIN` +with the `delta` parameter calculated on the fly. For single precision, delta is +the expected value multiplied by 0.00001, producing a very small proportional +range around the expected value. + +If you are expecting a value of 20,000.0 the delta is calculated to be 0.2. So +any value between 19,999.8 and 20,000.2 will satisfy the equality check. This +works out to be roughly a single bit of range for a single-precision number, and +that's just about as tight a tolerance as you can reasonably get from a floating +point value. + +So what happens when it's zero? Zero - even more than other floating point +values - can be represented many different ways. It doesn't matter if you have +0 x 20 or 0 x 263.It's still zero, right? Luckily, if you +subtract these values from each other, they will always produce a difference of +zero, which will still fall between 0 plus or minus a delta of 0. So it still +works! + +Double precision floating point numbers use a much smaller multiplier, again +approximating a single bit of error. + +If you don't like these ranges and you want to make your floating point equality +assertions less strict, you can change these multipliers to whatever you like by +defining UNITY_FLOAT_PRECISION and UNITY_DOUBLE_PRECISION. See Unity +documentation for more. + + +### How do we deal with targets with non-standard int sizes? + +It's "fun" that C is a standard where something as fundamental as an integer +varies by target. According to the C standard, an `int` is to be the target's +natural register size, and it should be at least 16-bits and a multiple of a +byte. It also guarantees an order of sizes: + +```C +char <= short <= int <= long <= long long +``` + +Most often, `int` is 32-bits. In many cases in the embedded world, `int` is +16-bits. There are rare microcontrollers out there that have 24-bit integers, +and this remains perfectly standard C. + +To make things even more interesting, there are compilers and targets out there +that have a hard choice to make. What if their natural register size is 10-bits +or 12-bits? Clearly they can't fulfill _both_ the requirement to be at least +16-bits AND the requirement to match the natural register size. In these +situations, they often choose the natural register size, leaving us with +something like this: + +```C +char (8 bit) <= short (12 bit) <= int (12 bit) <= long (16 bit) +``` + +Um... yikes. It's obviously breaking a rule or two... but they had to break SOME +rules, so they made a choice. + +When the C99 standard rolled around, it introduced alternate standard-size types. +It also introduced macros for pulling in MIN/MAX values for your integer types. +It's glorious! Unfortunately, many embedded compilers can't be relied upon to +use the C99 types (Sometimes because they have weird register sizes as described +above. Sometimes because they don't feel like it?). + +A goal of Unity from the beginning was to support every combination of +microcontroller or microprocessor and C compiler. Over time, we've gotten really +close to this. There are a few tricks that you should be aware of, though, if +you're going to do this effectively on some of these more idiosyncratic targets. + +First, when setting up Unity for a new target, you're going to want to pay +special attention to the macros for automatically detecting types +(where available) or manually configuring them yourself. You can get information +on both of these in Unity's documentation. + +What about the times where you suddenly need to deal with something odd, like a +24-bit `int`? The simplest solution is to use the next size up. If you have a +24-bit `int`, configure Unity to use 32-bit integers. If you have a 12-bit +`int`, configure Unity to use 16 bits. There are two ways this is going to +affect you: + +1. When Unity displays errors for you, it's going to pad the upper unused bits +with zeros. +2. You're going to have to be careful of assertions that perform signed +operations, particularly `TEST_ASSERT_INT_WITHIN`.Such assertions might wrap +your `int` in the wrong place, and you could experience false failures. You can +always back down to a simple `TEST_ASSERT` and do the operations yourself. + + +*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)* diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityConfigurationGuide.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityConfigurationGuide.md new file mode 100644 index 0000000..dace20c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityConfigurationGuide.md @@ -0,0 +1,433 @@ +# Unity Configuration Guide + +## C Standards, Compilers and Microcontrollers + +The embedded software world contains its challenges. Compilers support different +revisions of the C Standard. They ignore requirements in places, sometimes to +make the language more usable in some special regard. Sometimes it's to simplify +their support. Sometimes it's due to specific quirks of the microcontroller they +are targeting. Simulators add another dimension to this menagerie. + +Unity is designed to run on almost anything that is targeted by a C compiler. It +would be awesome if this could be done with zero configuration. While there are +some targets that come close to this dream, it is sadly not universal. It is +likely that you are going to need at least a couple of the configuration options +described in this document. + +All of Unity's configuration options are `#defines`. Most of these are simple +definitions. A couple are macros with arguments. They live inside the +unity_internals.h header file. We don't necessarily recommend opening that file +unless you really need to. That file is proof that a cross-platform library is +challenging to build. From a more positive perspective, it is also proof that a +great deal of complexity can be centralized primarily to one place to +provide a more consistent and simple experience elsewhere. + + +### Using These Options + +It doesn't matter if you're using a target-specific compiler and a simulator or +a native compiler. In either case, you've got a couple choices for configuring +these options: + +1. Because these options are specified via C defines, you can pass most of these +options to your compiler through command line compiler flags. Even if you're +using an embedded target that forces you to use their overbearing IDE for all +configuration, there will be a place somewhere in your project to configure +defines for your compiler. +2. You can create a custom `unity_config.h` configuration file (present in your +toolchain's search paths). In this file, you will list definitions and macros +specific to your target. All you must do is define `UNITY_INCLUDE_CONFIG_H` and +Unity will rely on `unity_config.h` for any further definitions it may need. + + +## The Options + +### Integer Types + +If you've been a C developer for long, you probably already know that C's +concept of an integer varies from target to target. The C Standard has rules +about the `int` matching the register size of the target microprocessor. It has +rules about the `int` and how its size relates to other integer types. An `int` +on one target might be 16 bits while on another target it might be 64. There are +more specific types in compilers compliant with C99 or later, but that's +certainly not every compiler you are likely to encounter. Therefore, Unity has a +number of features for helping to adjust itself to match your required integer +sizes. It starts off by trying to do it automatically. + + +##### `UNITY_EXCLUDE_STDINT_H` + +The first thing that Unity does to guess your types is check `stdint.h`. +This file includes defines like `UINT_MAX` that Unity can use to +learn a lot about your system. It's possible you don't want it to do this +(um. why not?) or (more likely) it's possible that your system doesn't +support `stdint.h`. If that's the case, you're going to want to define this. +That way, Unity will know to skip the inclusion of this file and you won't +be left with a compiler error. + +_Example:_ + #define UNITY_EXCLUDE_STDINT_H + + +##### `UNITY_EXCLUDE_LIMITS_H` + +The second attempt to guess your types is to check `limits.h`. Some compilers +that don't support `stdint.h` could include `limits.h` instead. If you don't +want Unity to check this file either, define this to make it skip the inclusion. + +_Example:_ + #define UNITY_EXCLUDE_LIMITS_H + + +If you've disabled both of the automatic options above, you're going to have to +do the configuration yourself. Don't worry. Even this isn't too bad... there are +just a handful of defines that you are going to specify if you don't like the +defaults. + + +##### `UNITY_INT_WIDTH` + +Define this to be the number of bits an `int` takes up on your system. The +default, if not autodetected, is 32 bits. + +_Example:_ + #define UNITY_INT_WIDTH 16 + + +##### `UNITY_LONG_WIDTH` + +Define this to be the number of bits a `long` takes up on your system. The +default, if not autodetected, is 32 bits. This is used to figure out what kind +of 64-bit support your system can handle. Does it need to specify a `long` or a +`long long` to get a 64-bit value. On 16-bit systems, this option is going to be +ignored. + +_Example:_ + #define UNITY_LONG_WIDTH 16 + + +##### `UNITY_POINTER_WIDTH` + +Define this to be the number of bits a pointer takes up on your system. The +default, if not autodetected, is 32-bits. If you're getting ugly compiler +warnings about casting from pointers, this is the one to look at. + +_Example:_ + #define UNITY_POINTER_WIDTH 64 + + +##### `UNITY_SUPPORT_64` + +Unity will automatically include 64-bit support if it auto-detects it, or if +your `int`, `long`, or pointer widths are greater than 32-bits. Define this to +enable 64-bit support if none of the other options already did it for you. There +can be a significant size and speed impact to enabling 64-bit support on small +targets, so don't define it if you don't need it. + +_Example:_ + #define UNITY_SUPPORT_64 + + +### Floating Point Types + +In the embedded world, it's not uncommon for targets to have no support for +floating point operations at all or to have support that is limited to only +single precision. We are able to guess integer sizes on the fly because integers +are always available in at least one size. Floating point, on the other hand, is +sometimes not available at all. Trying to include `float.h` on these platforms +would result in an error. This leaves manual configuration as the only option. + + +##### `UNITY_INCLUDE_FLOAT` + +##### `UNITY_EXCLUDE_FLOAT` + +##### `UNITY_INCLUDE_DOUBLE` + +##### `UNITY_EXCLUDE_DOUBLE` + +By default, Unity guesses that you will want single precision floating point +support, but not double precision. It's easy to change either of these using the +include and exclude options here. You may include neither, either, or both, as +suits your needs. For features that are enabled, the following floating point +options also become available. + +_Example:_ + + //what manner of strange processor is this? + #define UNITY_EXCLUDE_FLOAT + #define UNITY_INCLUDE_DOUBLE + + +##### `UNITY_EXCLUDE_FLOAT_PRINT` + +Unity aims for as small of a footprint as possible and avoids most standard +library calls (some embedded platforms don’t have a standard library!). Because +of this, its routines for printing integer values are minimalist and hand-coded. +Therefore, the display of floating point values during a failure are optional. +By default, Unity will print the actual results of floating point assertion +failure (e.g. â€Expected 4.56 Was 4.68â€). To not include this extra support, you +can use this define to instead respond to a failed assertion with a message like +â€Values Not Within Deltaâ€. If you would like verbose failure messages for floating +point assertions, use these options to give more explicit failure messages. + +_Example:_ + #define UNITY_EXCLUDE_FLOAT_PRINT + + +##### `UNITY_FLOAT_TYPE` + +If enabled, Unity assumes you want your `FLOAT` asserts to compare standard C +floats. If your compiler supports a specialty floating point type, you can +always override this behavior by using this definition. + +_Example:_ + #define UNITY_FLOAT_TYPE float16_t + + +##### `UNITY_DOUBLE_TYPE` + +If enabled, Unity assumes you want your `DOUBLE` asserts to compare standard C +doubles. If you would like to change this, you can specify something else by +using this option. For example, defining `UNITY_DOUBLE_TYPE` to `long double` +could enable gargantuan floating point types on your 64-bit processor instead of +the standard `double`. + +_Example:_ + #define UNITY_DOUBLE_TYPE long double + + +##### `UNITY_FLOAT_PRECISION` + +##### `UNITY_DOUBLE_PRECISION` + +If you look up `UNITY_ASSERT_EQUAL_FLOAT` and `UNITY_ASSERT_EQUAL_DOUBLE` as +documented in the big daddy Unity Assertion Guide, you will learn that they are +not really asserting that two values are equal but rather that two values are +"close enough" to equal. "Close enough" is controlled by these precision +configuration options. If you are working with 32-bit floats and/or 64-bit +doubles (the normal on most processors), you should have no need to change these +options. They are both set to give you approximately 1 significant bit in either +direction. The float precision is 0.00001 while the double is 10-12. +For further details on how this works, see the appendix of the Unity Assertion +Guide. + +_Example:_ + #define UNITY_FLOAT_PRECISION 0.001f + + +### Toolset Customization + +In addition to the options listed above, there are a number of other options +which will come in handy to customize Unity's behavior for your specific +toolchain. It is possible that you may not need to touch any of these... but +certain platforms, particularly those running in simulators, may need to jump +through extra hoops to run properly. These macros will help in those +situations. + + +##### `UNITY_OUTPUT_CHAR(a)` + +##### `UNITY_OUTPUT_FLUSH()` + +##### `UNITY_OUTPUT_START()` + +##### `UNITY_OUTPUT_COMPLETE()` + +By default, Unity prints its results to `stdout` as it runs. This works +perfectly fine in most situations where you are using a native compiler for +testing. It works on some simulators as well so long as they have `stdout` +routed back to the command line. There are times, however, where the simulator +will lack support for dumping results or you will want to route results +elsewhere for other reasons. In these cases, you should define the +`UNITY_OUTPUT_CHAR` macro. This macro accepts a single character at a time (as +an `int`, since this is the parameter type of the standard C `putchar` function +most commonly used). You may replace this with whatever function call you like. + +_Example:_ +Say you are forced to run your test suite on an embedded processor with no +`stdout` option. You decide to route your test result output to a custom serial +`RS232_putc()` function you wrote like thus: + #include "RS232_header.h" + ... + #define UNITY_OUTPUT_CHAR(a) RS232_putc(a) + #define UNITY_OUTPUT_START() RS232_config(115200,1,8,0) + #define UNITY_OUTPUT_FLUSH() RS232_flush() + #define UNITY_OUTPUT_COMPLETE() RS232_close() + +_Note:_ +`UNITY_OUTPUT_FLUSH()` can be set to the standard out flush function simply by +specifying `UNITY_USE_FLUSH_STDOUT`. No other defines are required. + + +##### `UNITY_WEAK_ATTRIBUTE` + +##### `UNITY_WEAK_PRAGMA` + +##### `UNITY_NO_WEAK` + +For some targets, Unity can make the otherwise required setUp() and tearDown() +functions optional. This is a nice convenience for test writers since setUp and +tearDown don’t often actually do anything. If you’re using gcc or clang, this +option is automatically defined for you. Other compilers can also support this +behavior, if they support a C feature called weak functions. A weak function is +a function that is compiled into your executable unless a non-weak version of +the same function is defined elsewhere. If a non-weak version is found, the weak +version is ignored as if it never existed. If your compiler supports this feature, +you can let Unity know by defining UNITY_WEAK_ATTRIBUTE or UNITY_WEAK_PRAGMA as +the function attributes that would need to be applied to identify a function as +weak. If your compiler lacks support for weak functions, you will always need to +define setUp and tearDown functions (though they can be and often will be just +empty). You can also force Unity to NOT use weak functions by defining +UNITY_NO_WEAK. The most common options for this feature are: + +_Example:_ + #define UNITY_WEAK_ATTRIBUTE weak + #define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) + #define UNITY_WEAK_PRAGMA + #define UNITY_NO_WEAK + + +##### `UNITY_PTR_ATTRIBUTE` + +Some compilers require a custom attribute to be assigned to pointers, like +`near` or `far`. In these cases, you can give Unity a safe default for these by +defining this option with the attribute you would like. + +_Example:_ + #define UNITY_PTR_ATTRIBUTE __attribute__((far)) + #define UNITY_PTR_ATTRIBUTE near + + +##### `UNITY_PRINT_EOL` + +By default, Unity outputs \n at the end of each line of output. This is easy +to parse by the scripts, by Ceedling, etc, but it might not be ideal for YOUR +system. Feel free to override this and to make it whatever you wish. + +_Example:_ + #define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\r'); UNITY_OUTPUT_CHAR('\n') } + + + +##### `UNITY_EXCLUDE_DETAILS` + +This is an option for if you absolutely must squeeze every byte of memory out of +your system. Unity stores a set of internal scratchpads which are used to pass +extra detail information around. It's used by systems like CMock in order to +report which function or argument flagged an error. If you're not using CMock and +you're not using these details for other things, then you can exclude them. + +_Example:_ + #define UNITY_EXCLUDE_DETAILS + + + +##### `UNITY_EXCLUDE_SETJMP` + +If your embedded system doesn't support the standard library setjmp, you can +exclude Unity's reliance on this by using this define. This dropped dependence +comes at a price, though. You will be unable to use custom helper functions for +your tests, and you will be unable to use tools like CMock. Very likely, if your +compiler doesn't support setjmp, you wouldn't have had the memory space for those +things anyway, though... so this option exists for those situations. + +_Example:_ + #define UNITY_EXCLUDE_SETJMP + +##### `UNITY_OUTPUT_COLOR` + +If you want to add color using ANSI escape codes you can use this define. +t +_Example:_ + #define UNITY_OUTPUT_COLOR + + + +## Getting Into The Guts + +There will be cases where the options above aren't quite going to get everything +perfect. They are likely sufficient for any situation where you are compiling +and executing your tests with a native toolchain (e.g. clang on Mac). These +options may even get you through the majority of cases encountered in working +with a target simulator run from your local command line. But especially if you +must run your test suite on your target hardware, your Unity configuration will +require special help. This special help will usually reside in one of two +places: the `main()` function or the `RUN_TEST` macro. Let's look at how these +work. + + +##### `main()` + +Each test module is compiled and run on its own, separate from the other test +files in your project. Each test file, therefore, has a `main` function. This +`main` function will need to contain whatever code is necessary to initialize +your system to a workable state. This is particularly true for situations where +you must set up a memory map or initialize a communication channel for the +output of your test results. + +A simple main function looks something like this: + + int main(void) { + UNITY_BEGIN(); + RUN_TEST(test_TheFirst); + RUN_TEST(test_TheSecond); + RUN_TEST(test_TheThird); + return UNITY_END(); + } + +You can see that our main function doesn't bother taking any arguments. For our +most barebones case, we'll never have arguments because we just run all the +tests each time. Instead, we start by calling `UNITY_BEGIN`. We run each test +(in whatever order we wish). Finally, we call `UNITY_END`, returning its return +value (which is the total number of failures). + +It should be easy to see that you can add code before any test cases are run or +after all the test cases have completed. This allows you to do any needed +system-wide setup or teardown that might be required for your special +circumstances. + + +##### `RUN_TEST` + +The `RUN_TEST` macro is called with each test case function. Its job is to +perform whatever setup and teardown is necessary for executing a single test +case function. This includes catching failures, calling the test module's +`setUp()` and `tearDown()` functions, and calling `UnityConcludeTest()`. If +using CMock or test coverage, there will be additional stubs in use here. A +simple minimalist RUN_TEST macro looks something like this: + + #define RUN_TEST(testfunc) \ + UNITY_NEW_TEST(#testfunc) \ + if (TEST_PROTECT()) { \ + setUp(); \ + testfunc(); \ + } \ + if (TEST_PROTECT() && (!TEST_IS_IGNORED)) \ + tearDown(); \ + UnityConcludeTest(); + +So that's quite a macro, huh? It gives you a glimpse of what kind of stuff Unity +has to deal with for every single test case. For each test case, we declare that +it is a new test. Then we run `setUp` and our test function. These are run +within a `TEST_PROTECT` block, the function of which is to handle failures that +occur during the test. Then, assuming our test is still running and hasn't been +ignored, we run `tearDown`. No matter what, our last step is to conclude this +test before moving on to the next. + +Let's say you need to add a call to `fsync` to force all of your output data to +flush to a file after each test. You could easily insert this after your +`UnityConcludeTest` call. Maybe you want to write an xml tag before and after +each result set. Again, you could do this by adding lines to this macro. Updates +to this macro are for the occasions when you need an action before or after +every single test case throughout your entire suite of tests. + + +## Happy Porting + +The defines and macros in this guide should help you port Unity to just about +any C target we can imagine. If you run into a snag or two, don't be afraid of +asking for help on the forums. We love a good challenge! + + +*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)* diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityGettingStartedGuide.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityGettingStartedGuide.md new file mode 100644 index 0000000..5e4427c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityGettingStartedGuide.md @@ -0,0 +1,192 @@ +# Unity - Getting Started + +## Welcome + +Congratulations. You're now the proud owner of your very own pile of bits! What +are you going to do with all these ones and zeros? This document should be able +to help you decide just that. + +Unity is a unit test framework. The goal has been to keep it small and +functional. The core Unity test framework is three files: a single C file and a +couple header files. These team up to provide functions and macros to make +testing easier. + +Unity was designed to be cross-platform. It works hard to stick with C standards +while still providing support for the many embedded C compilers that bend the +rules. Unity has been used with many compilers, including GCC, IAR, Clang, +Green Hills, Microchip, and MS Visual Studio. It's not much work to get it to +work with a new target. + + +### Overview of the Documents + +#### Unity Assertions reference + +This document will guide you through all the assertion options provided by +Unity. This is going to be your unit testing bread and butter. You'll spend more +time with assertions than any other part of Unity. + + +#### Unity Assertions Cheat Sheet + +This document contains an abridged summary of the assertions described in the +previous document. It's perfect for printing and referencing while you +familiarize yourself with Unity's options. + + +#### Unity Configuration Guide + +This document is the one to reference when you are going to use Unity with a new +target or compiler. It'll guide you through the configuration options and will +help you customize your testing experience to meet your needs. + + +#### Unity Helper Scripts + +This document describes the helper scripts that are available for simplifying +your testing workflow. It describes the collection of optional Ruby scripts +included in the auto directory of your Unity installation. Neither Ruby nor +these scripts are necessary for using Unity. They are provided as a convenience +for those who wish to use them. + + +#### Unity License + +What's an open source project without a license file? This brief document +describes the terms you're agreeing to when you use this software. Basically, we +want it to be useful to you in whatever context you want to use it, but please +don't blame us if you run into problems. + + +### Overview of the Folders + +If you have obtained Unity through Github or something similar, you might be +surprised by just how much stuff you suddenly have staring you in the face. +Don't worry, Unity itself is very small. The rest of it is just there to make +your life easier. You can ignore it or use it at your convenience. Here's an +overview of everything in the project. + +- `src` - This is the code you care about! This folder contains a C file and two +header files. These three files _are_ Unity. +- `docs` - You're reading this document, so it's possible you have found your way +into this folder already. This is where all the handy documentation can be +found. +- `examples` - This contains a few examples of using Unity. +- `extras` - These are optional add ons to Unity that are not part of the core +project. If you've reached us through James Grenning's book, you're going to +want to look here. +- `test` - This is how Unity and its scripts are all tested. If you're just using +Unity, you'll likely never need to go in here. If you are the lucky team member +who gets to port Unity to a new toolchain, this is a good place to verify +everything is configured properly. +- `auto` - Here you will find helpful Ruby scripts for simplifying your test +workflow. They are purely optional and are not required to make use of Unity. + + +## How to Create A Test File + +Test files are C files. Most often you will create a single test file for each C +module that you want to test. The test file should include unity.h and the +header for your C module to be tested. + +Next, a test file will include a `setUp()` and `tearDown()` function. The setUp +function can contain anything you would like to run before each test. The +tearDown function can contain anything you would like to run after each test. +Both functions accept no arguments and return nothing. You may leave either or +both of these blank if you have no need for them. If you're using a compiler +that is configured to make these functions optional, you may leave them off +completely. Not sure? Give it a try. If you compiler complains that it can't +find setUp or tearDown when it links, you'll know you need to at least include +an empty function for these. + +The majority of the file will be a series of test functions. Test functions +follow the convention of starting with the word "test_" or "spec_". You don't HAVE +to name them this way, but it makes it clear what functions are tests for other +developers. Also, the automated scripts that come with Unity or Ceedling will default +to looking for test functions to be prefixed this way. Test functions take no arguments +and return nothing. All test accounting is handled internally in Unity. + +Finally, at the bottom of your test file, you will write a `main()` function. +This function will call `UNITY_BEGIN()`, then `RUN_TEST` for each test, and +finally `UNITY_END()`.This is what will actually trigger each of those test +functions to run, so it is important that each function gets its own `RUN_TEST` +call. + +Remembering to add each test to the main function can get to be tedious. If you +enjoy using helper scripts in your build process, you might consider making use +of our handy generate_test_runner.rb script. This will create the main function +and all the calls for you, assuming that you have followed the suggested naming +conventions. In this case, there is no need for you to include the main function +in your test file at all. + +When you're done, your test file will look something like this: + +```C +#include "unity.h" +#include "file_to_test.h" + +void setUp(void) { + // set stuff up here +} + +void tearDown(void) { + // clean stuff up here +} + +void test_function_should_doBlahAndBlah(void) { + //test stuff +} + +void test_function_should_doAlsoDoBlah(void) { + //more test stuff +} + +int main(void) { + UNITY_BEGIN(); + RUN_TEST(test_function_should_doBlahAndBlah); + RUN_TEST(test_function_should_doAlsoDoBlah); + return UNITY_END(); +} +``` + +It's possible that you will need more customization than this, eventually. +For that sort of thing, you're going to want to look at the configuration guide. +This should be enough to get you going, though. + + +## How to Build and Run A Test File + +This is the single biggest challenge to picking up a new unit testing framework, +at least in a language like C or C++. These languages are REALLY good at getting +you "close to the metal" (why is the phrase metal? Wouldn't it be more accurate +to say "close to the silicon"?). While this feature is usually a good thing, it +can make testing more challenging. + +You have two really good options for toolchains. Depending on where you're +coming from, it might surprise you that neither of these options is running the +unit tests on your hardware. +There are many reasons for this, but here's a short version: +- On hardware, you have too many constraints (processing power, memory, etc), +- On hardware, you don't have complete control over all registers, +- On hardware, unit testing is more challenging, +- Unit testing isn't System testing. Keep them separate. + +Instead of running your tests on your actual hardware, most developers choose to +develop them as native applications (using gcc or MSVC for example) or as +applications running on a simulator. Either is a good option. Native apps have +the advantages of being faster and easier to set up. Simulator apps have the +advantage of working with the same compiler as your target application. The +options for configuring these are discussed in the configuration guide. + +To get either to work, you might need to make a few changes to the file +containing your register set (discussed later). + +In either case, a test is built by linking unity, the test file, and the C +file(s) being tested. These files create an executable which can be run as the +test set for that module. Then, this process is repeated for the next test file. +This flexibility of separating tests into individual executables allows us to +much more thoroughly unit test our system and it keeps all the test code out of +our final release! + + +*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)* diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityHelperScriptsGuide.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityHelperScriptsGuide.md new file mode 100644 index 0000000..12d68d3 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/docs/UnityHelperScriptsGuide.md @@ -0,0 +1,260 @@ +# Unity Helper Scripts + +## With a Little Help From Our Friends + +Sometimes what it takes to be a really efficient C programmer is a little non-C. +The Unity project includes a couple of Ruby scripts for making your life just a tad +easier. They are completely optional. If you choose to use them, you'll need a +copy of Ruby, of course. Just install whatever the latest version is, and it is +likely to work. You can find Ruby at [ruby-lang.org](https://ruby-labg.org/). + + +### `generate_test_runner.rb` + +Are you tired of creating your own `main` function in your test file? Do you +keep forgetting to add a `RUN_TEST` call when you add a new test case to your +suite? Do you want to use CMock or other fancy add-ons but don't want to figure +out how to create your own `RUN_TEST` macro? + +Well then we have the perfect script for you! + +The `generate_test_runner` script processes a given test file and automatically +creates a separate test runner file that includes ?main?to execute the test +cases within the scanned test file. All you do then is add the generated runner +to your list of files to be compiled and linked, and presto you're done! + +This script searches your test file for void function signatures having a +function name beginning with "test" or "spec". It treats each of these +functions as a test case and builds up a test suite of them. For example, the +following includes three test cases: + +```C +void testVerifyThatUnityIsAwesomeAndWillMakeYourLifeEasier(void) +{ + ASSERT_TRUE(1); +} +void test_FunctionName_should_WorkProperlyAndReturn8(void) { + ASSERT_EQUAL_INT(8, FunctionName()); +} +void spec_Function_should_DoWhatItIsSupposedToDo(void) { + ASSERT_NOT_NULL(Function(5)); +} +``` + +You can run this script a couple of ways. The first is from the command line: + +```Shell +ruby generate_test_runner.rb TestFile.c NameOfRunner.c +``` + +Alternatively, if you include only the test file parameter, the script will copy +the name of the test file and automatically append "_Runner" to the name of the +generated file. The example immediately below will create TestFile_Runner.c. + +```Shell +ruby generate_test_runner.rb TestFile.c +``` + +You can also add a [YAML](http://www.yaml.org/) file to configure extra options. +Conveniently, this YAML file is of the same format as that used by Unity and +CMock. So if you are using YAML files already, you can simply pass the very same +file into the generator script. + +```Shell +ruby generate_test_runner.rb TestFile.c my_config.yml +``` + +The contents of the YAML file `my_config.yml` could look something like the +example below. If you're wondering what some of these options do, you're going +to love the next section of this document. + +```YAML +:unity: + :includes: + - stdio.h + - microdefs.h + :cexception: 1 + :suit_setup: "blah = malloc(1024);" + :suite_teardown: "free(blah);" +``` + +If you would like to force your generated test runner to include one or more +header files, you can just include those at the command line too. Just make sure +these are _after_ the YAML file, if you are using one: + +```Shell +ruby generate_test_runner.rb TestFile.c my_config.yml extras.h +``` + +Another option, particularly if you are already using Ruby to orchestrate your +builds - or more likely the Ruby-based build tool Rake - is requiring this +script directly. Anything that you would have specified in a YAML file can be +passed to the script as part of a hash. Let's push the exact same requirement +set as we did above but this time through Ruby code directly: + +```Ruby +require "generate_test_runner.rb" +options = { + :includes => ["stdio.h", "microdefs.h"], + :cexception => 1, + :suite_setup => "blah = malloc(1024);", + :suite_teardown => "free(blah);" +} +UnityTestRunnerGenerator.new.run(testfile, runner_name, options) +``` + +If you have multiple files to generate in a build script (such as a Rakefile), +you might want to instantiate a generator object with your options and call it +to generate each runner afterwards. Like thus: + +```Ruby +gen = UnityTestRunnerGenerator.new(options) +test_files.each do |f| + gen.run(f, File.basename(f,'.c')+"Runner.c" +end +``` + +#### Options accepted by generate_test_runner.rb: + +The following options are available when executing `generate_test_runner`. You +may pass these as a Ruby hash directly or specify them in a YAML file, both of +which are described above. In the `examples` directory, Example 3's Rakefile +demonstrates using a Ruby hash. + + +##### `:includes` + +This option specifies an array of file names to be `#include`'d at the top of +your runner C file. You might use it to reference custom types or anything else +universally needed in your generated runners. + + +##### `:suite_setup` + +Define this option with C code to be executed _before any_ test cases are run. + +Alternatively, if your C compiler supports weak symbols, you can leave this +option unset and instead provide a `void suiteSetUp(void)` function in your test +suite. The linker will look for this symbol and fall back to a Unity-provided +stub if it is not found. + + +##### `:suite_teardown` + +Define this option with C code to be executed _after all_ test cases have +finished. An integer variable `num_failures` is available for diagnostics. +The code should end with a `return` statement; the value returned will become +the exit code of `main`. You can normally just return `num_failures`. + +Alternatively, if your C compiler supports weak symbols, you can leave this +option unset and instead provide a `int suiteTearDown(int num_failures)` +function in your test suite. The linker will look for this symbol and fall +back to a Unity-provided stub if it is not found. + + +##### `:enforce_strict_ordering` + +This option should be defined if you have the strict order feature enabled in +CMock (see CMock documentation). This generates extra variables required for +everything to run smoothly. If you provide the same YAML to the generator as +used in CMock's configuration, you've already configured the generator properly. + +##### `:mock_prefix` and `:mock_suffix` + +Unity automatically generates calls to Init, Verify and Destroy for every file +included in the main test file that starts with the given mock prefix and ends +with the given mock suffix, file extension not included. By default, Unity +assumes a `Mock` prefix and no suffix. + +##### `:plugins` + +This option specifies an array of plugins to be used (of course, the array can +contain only a single plugin). This is your opportunity to enable support for +CException support, which will add a check for unhandled exceptions in each +test, reporting a failure if one is detected. To enable this feature using Ruby: + +```Ruby +:plugins => [ :cexception ] +``` + +Or as a yaml file: + +```YAML +:plugins: + -:cexception +``` + +If you are using CMock, it is very likely that you are already passing an array +of plugins to CMock. You can just use the same array here. This script will just +ignore the plugins that don't require additional support. + + +### `unity_test_summary.rb` + +A Unity test file contains one or more test case functions. Each test case can +pass, fail, or be ignored. Each test file is run individually producing results +for its collection of test cases. A given project will almost certainly be +composed of multiple test files. Therefore, the suite of tests is comprised of +one or more test cases spread across one or more test files. This script +aggregates individual test file results to generate a summary of all executed +test cases. The output includes how many tests were run, how many were ignored, +and how many failed. In addition, the output includes a listing of which +specific tests were ignored and failed. A good example of the breadth and +details of these results can be found in the `examples` directory. Intentionally +ignored and failing tests in this project generate corresponding entries in the +summary report. + +If you're interested in other (prettier?) output formats, check into the +Ceedling build tool project (ceedling.sourceforge.net) that works with Unity and +CMock and supports xunit-style xml as well as other goodies. + +This script assumes the existence of files ending with the extensions +`.testpass` and `.testfail`.The contents of these files includes the test +results summary corresponding to each test file executed with the extension set +according to the presence or absence of failures for that test file. The script +searches a specified path for these files, opens each one it finds, parses the +results, and aggregates and prints a summary. Calling it from the command line +looks like this: + +```Shell +ruby unity_test_summary.rb build/test/ +``` + +You can optionally specify a root path as well. This is really helpful when you +are using relative paths in your tools' setup, but you want to pull the summary +into an IDE like Eclipse for clickable shortcuts. + +```Shell +ruby unity_test_summary.rb build/test/ ~/projects/myproject/ +``` + +Or, if you're more of a Windows sort of person: + +```Shell +ruby unity_test_summary.rb build\teat\ C:\projects\myproject\ +``` + +When configured correctly, you'll see a final summary, like so: + +```Shell +-------------------------- +UNITY IGNORED TEST SUMMARY +-------------------------- +blah.c:22:test_sandwiches_should_HaveBreadOnTwoSides:IGNORE + +------------------------- +UNITY FAILED TEST SUMMARY +------------------------- +blah.c:87:test_sandwiches_should_HaveCondiments:FAIL:Expected 1 was 0 +meh.c:38:test_soda_should_BeCalledPop:FAIL:Expected "pop" was "coke" + +-------------------------- +OVERALL UNITY TEST SUMMARY +-------------------------- +45 TOTAL TESTS 2 TOTAL FAILURES 1 IGNORED +``` + +How convenient is that? + + +*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)* diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling.rb new file mode 100644 index 0000000..7f34002 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling.rb @@ -0,0 +1,99 @@ +## +# This module defines the interface for interacting with and loading a project +# with Ceedling. +module Ceedling + ## + # Returns the location where the gem is installed. + # === Return + # _String_ - The location where the gem lives. + def self.location + File.join( File.dirname(__FILE__), '..') + end + + ## + # Return the path to the "built-in" plugins. + # === Return + # _String_ - The path where the default plugins live. + def self.load_path + File.join( self.location, 'plugins') + end + + ## + # Return the path to the Ceedling Rakefile + # === Return + # _String_ + def self.rakefile + File.join( self.location, 'lib', 'ceedling', 'rakefile.rb' ) + end + + ## + # This method selects the project file that Ceedling will use by setting the + # CEEDLING_MAIN_PROJECT_FILE environment variable before loading the ceedling + # rakefile. A path supplied as an argument to this method will override the + # current value of the environment variable. If no path is supplied as an + # argument then the existing value of the environment variable is used. If + # the environment variable has not been set and no argument has been supplied + # then a default path of './project.yml' will be used. + # + # === Arguments + # +options+ _Hash_:: + # A hash containing the options for ceedling. Currently the following + # options are supported: + # * +config+ - The path to the project YAML configuration file. + # * +root+ - The root of the project directory. + # * +prefix+ - A prefix to prepend to plugin names in order to determine the + # corresponding gem name. + # * +plugins+ - The list of ceedling plugins to load + def self.load_project(options = {}) + # Make sure our path to the yaml file is setup + if options.has_key? :config + ENV['CEEDLING_MAIN_PROJECT_FILE'] = options[:config] + elsif ENV['CEEDLING_MAIN_PROJECT_FILE'].nil? + ENV['CEEDLING_MAIN_PROJECT_FILE'] = './project.yml' + end + + # Register the plugins + if options.has_key? :plugins + options[:plugins].each do |plugin| + register_plugin( plugin, options[:prefix] ) + end + end + + # Define the root of the project if specified + Object.const_set('PROJECT_ROOT', options[:root]) if options.has_key? :root + + # Load ceedling + load "#{self.rakefile}" + end + + ## + # Register a plugin for ceedling to use when a project is loaded. This method + # *must* be called prior to calling the _load_project_ method. + # + # This method is intended to be used for loading plugins distributed via the + # RubyGems mechanism. As such, the following gem structure is assumed for + # plugins. + # + # * The gem name must be prefixed with 'ceedling-' followed by the plugin + # name (ex. 'ceedling-bullseye') + # + # * The contents of the plugin must be isntalled into a subdirectory of + # the gem with the same name as the plugin (ex. 'bullseye/') + # + # === Arguments + # +name+ _String_:: The name of the plugin to load. + # +prefix+ _String_:: + # (optional, default = nil) The prefix to use for the full gem name. + def self.register_plugin(name, prefix=nil) + # Figure out the full name of the gem and location + prefix ||= 'ceedling-' + gem_name = prefix + name + gem_dir = Gem::Specification.find_by_name(gem_name).gem_dir() + + # Register the plugin with Ceedling + require 'ceedling/defaults' + DEFAULT_CEEDLING_CONFIG[:plugins][:enabled] << name + DEFAULT_CEEDLING_CONFIG[:plugins][:load_paths] << gem_dir + end +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/build_invoker_utils.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/build_invoker_utils.rb new file mode 100644 index 0000000..b7d57f8 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/build_invoker_utils.rb @@ -0,0 +1,39 @@ +require 'ceedling/constants' + +## +# Utilities for raiser and reporting errors during building. +class BuildInvokerUtils + + constructor :configurator, :streaminator + + ## + # Processes exceptions and tries to display a useful message for the user. + # + # ==== Attriboops...utes + # + # * _exception_: The exception given by a rescue statement. + # * _context_: A symbol representing where in the build the exception + # occurs. + # * _test_build_: A bool to signify if the exception occurred while building + # from test or source. + # + def process_exception(exception, context, test_build=true) + if (exception.message =~ /Don't know how to build task '(.+)'/i) + error_header = "ERROR: Rake could not find file referenced in source" + error_header += " or test" if (test_build) + error_header += ": '#{$1}'. Possible stale dependency." + + @streaminator.stderr_puts( error_header ) + + if (@configurator.project_use_deep_dependencies) + help_message = "Try fixing #include statements or adding missing file. Then run '#{REFRESH_TASK_ROOT}#{context.to_s}' task and try again." + @streaminator.stderr_puts( help_message ) + end + + raise '' + else + raise exception + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cacheinator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cacheinator.rb new file mode 100644 index 0000000..519a4aa --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cacheinator.rb @@ -0,0 +1,47 @@ + +class Cacheinator + + constructor :cacheinator_helper, :file_path_utils, :file_wrapper, :yaml_wrapper + + def cache_test_config(hash) + @yaml_wrapper.dump( @file_path_utils.form_test_build_cache_path( INPUT_CONFIGURATION_CACHE_FILE), hash ) + end + + def cache_release_config(hash) + @yaml_wrapper.dump( @file_path_utils.form_release_build_cache_path( INPUT_CONFIGURATION_CACHE_FILE ), hash ) + end + + + def diff_cached_test_file( filepath ) + cached_filepath = @file_path_utils.form_test_build_cache_path( filepath ) + + if (@file_wrapper.exist?( cached_filepath ) and (!@file_wrapper.compare( filepath, cached_filepath ))) + @file_wrapper.cp(filepath, cached_filepath, {:preserve => false}) + return filepath + elsif (!@file_wrapper.exist?( cached_filepath )) + @file_wrapper.cp(filepath, cached_filepath, {:preserve => false}) + return filepath + end + + return cached_filepath + end + + def diff_cached_test_config?(hash) + cached_filepath = @file_path_utils.form_test_build_cache_path(INPUT_CONFIGURATION_CACHE_FILE) + + return @cacheinator_helper.diff_cached_config?( cached_filepath, hash ) + end + + def diff_cached_test_defines?(files) + cached_filepath = @file_path_utils.form_test_build_cache_path(DEFINES_DEPENDENCY_CACHE_FILE) + + return @cacheinator_helper.diff_cached_defines?( cached_filepath, files ) + end + + def diff_cached_release_config?(hash) + cached_filepath = @file_path_utils.form_release_build_cache_path(INPUT_CONFIGURATION_CACHE_FILE) + + return @cacheinator_helper.diff_cached_config?( cached_filepath, hash ) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cacheinator_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cacheinator_helper.rb new file mode 100644 index 0000000..2a16185 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cacheinator_helper.rb @@ -0,0 +1,31 @@ + +class CacheinatorHelper + + constructor :file_wrapper, :yaml_wrapper + + def diff_cached_config?(cached_filepath, hash) + return true if ( not @file_wrapper.exist?(cached_filepath) ) + return true if ( (@file_wrapper.exist?(cached_filepath)) and (!(@yaml_wrapper.load(cached_filepath) == hash)) ) + return false + end + + def diff_cached_defines?(cached_filepath, files) + current_defines = COLLECTION_DEFINES_TEST_AND_VENDOR.reject(&:empty?) + + current_dependency = Hash[files.collect { |source| [source, current_defines.dup] }] + if not @file_wrapper.exist?(cached_filepath) + @yaml_wrapper.dump(cached_filepath, current_dependency) + return false + end + + dependencies = @yaml_wrapper.load(cached_filepath) + if dependencies.values_at(*current_dependency.keys) != current_dependency.values + dependencies.merge!(current_dependency) + @yaml_wrapper.dump(cached_filepath, dependencies) + return true + end + + return false + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cmock_builder.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cmock_builder.rb new file mode 100644 index 0000000..4a74aa8 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/cmock_builder.rb @@ -0,0 +1,15 @@ +require 'cmock' + +class CmockBuilder + + attr_accessor :cmock + + def setup + @cmock = nil + end + + def manufacture(cmock_config) + @cmock = CMock.new(cmock_config) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator.rb new file mode 100644 index 0000000..b5ad898 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator.rb @@ -0,0 +1,363 @@ +require 'ceedling/defaults' +require 'ceedling/constants' +require 'ceedling/file_path_utils' +require 'deep_merge' + + + +class Configurator + + attr_reader :project_config_hash, :script_plugins, :rake_plugins + attr_accessor :project_logging, :project_debug, :project_verbosity, :sanity_checks + + constructor(:configurator_setup, :configurator_builder, :configurator_plugins, :cmock_builder, :yaml_wrapper, :system_wrapper) do + @project_logging = false + @project_debug = false + @project_verbosity = Verbosity::NORMAL + @sanity_checks = TestResultsSanityChecks::NORMAL + end + + def setup + # special copy of cmock config to provide to cmock for construction + @cmock_config_hash = {} + + # note: project_config_hash is an instance variable so constants and accessors created + # in eval() statements in build() have something of proper scope and persistence to reference + @project_config_hash = {} + @project_config_hash_backup = {} + + @script_plugins = [] + @rake_plugins = [] + end + + + def replace_flattened_config(config) + @project_config_hash.merge!(config) + @configurator_setup.build_constants_and_accessors(@project_config_hash, binding()) + end + + + def store_config + @project_config_hash_backup = @project_config_hash.clone + end + + + def restore_config + @project_config_hash = @project_config_hash_backup + @configurator_setup.build_constants_and_accessors(@project_config_hash, binding()) + end + + + def reset_defaults(config) + [:test_compiler, + :test_linker, + :test_fixture, + :test_includes_preprocessor, + :test_file_preprocessor, + :test_dependencies_generator, + :release_compiler, + :release_assembler, + :release_linker, + :release_dependencies_generator].each do |tool| + config[:tools].delete(tool) if (not (config[:tools][tool].nil?)) + end + end + + + # The default values defined in defaults.rb (eg. DEFAULT_TOOLS_TEST) are populated + # into @param config + def populate_defaults(config) + new_config = DEFAULT_CEEDLING_CONFIG.deep_clone + new_config.deep_merge!(config) + config.replace(new_config) + + @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST ) + @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST_PREPROCESSORS ) if (config[:project][:use_test_preprocessor]) + @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST_DEPENDENCIES ) if (config[:project][:use_deep_dependencies]) + + @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE ) if (config[:project][:release_build]) + @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE_ASSEMBLER ) if (config[:project][:release_build] and config[:release_build][:use_assembly]) + @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE_DEPENDENCIES ) if (config[:project][:release_build] and config[:project][:use_deep_dependencies]) + end + + + def populate_unity_defaults(config) + unity = config[:unity] || {} + @runner_config = unity.merge(@runner_config || config[:test_runner] || {}) + end + + def populate_cmock_defaults(config) + # cmock has its own internal defaults handling, but we need to set these specific values + # so they're present for the build environment to access; + # note: these need to end up in the hash given to initialize cmock for this to be successful + cmock = config[:cmock] || {} + + # yes, we're duplicating the default mock_prefix in cmock, but it's because we need CMOCK_MOCK_PREFIX always available in Ceedling's environment + cmock[:mock_prefix] = 'Mock' if (cmock[:mock_prefix].nil?) + + # just because strict ordering is the way to go + cmock[:enforce_strict_ordering] = true if (cmock[:enforce_strict_ordering].nil?) + + cmock[:mock_path] = File.join(config[:project][:build_root], TESTS_BASE_PATH, 'mocks') if (cmock[:mock_path].nil?) + cmock[:verbosity] = @project_verbosity if (cmock[:verbosity].nil?) + + cmock[:plugins] = [] if (cmock[:plugins].nil?) + cmock[:plugins].map! { |plugin| plugin.to_sym } + cmock[:plugins] << (:cexception) if (!cmock[:plugins].include?(:cexception) and (config[:project][:use_exceptions])) + cmock[:plugins].uniq! + + cmock[:unity_helper] = false if (cmock[:unity_helper].nil?) + + if (cmock[:unity_helper]) + cmock[:unity_helper] = [cmock[:unity_helper]] if cmock[:unity_helper].is_a? String + cmock[:includes] += cmock[:unity_helper].map{|helper| File.basename(helper) } + cmock[:includes].uniq! + end + + @runner_config = cmock.merge(@runner_config || config[:test_runner] || {}) + + @cmock_builder.manufacture(cmock) + end + + + def get_runner_config + @runner_config + end + + + # grab tool names from yaml and insert into tool structures so available for error messages + # set up default values + def tools_setup(config) + config[:tools].each_key do |name| + tool = config[:tools][name] + + # populate name if not given + tool[:name] = name.to_s if (tool[:name].nil?) + + # handle inline ruby string substitution in executable + if (tool[:executable] =~ RUBY_STRING_REPLACEMENT_PATTERN) + tool[:executable].replace(@system_wrapper.module_eval(tool[:executable])) + end + + # populate stderr redirect option + tool[:stderr_redirect] = StdErrRedirect::NONE if (tool[:stderr_redirect].nil?) + + # populate background execution option + tool[:background_exec] = BackgroundExec::NONE if (tool[:background_exec].nil?) + + # populate optional option to control verification of executable in search paths + tool[:optional] = false if (tool[:optional].nil?) + end + end + + + def tools_supplement_arguments(config) + tools_name_prefix = 'tools_' + config[:tools].each_key do |name| + tool = @project_config_hash[(tools_name_prefix + name.to_s).to_sym] + + # smoosh in extra arguments if specified at top-level of config (useful for plugins & default gcc tools) + # arguments are squirted in at _end_ of list + top_level_tool = (tools_name_prefix + name.to_s).to_sym + if (not config[top_level_tool].nil?) + # adding and flattening is not a good idea: might over-flatten if there's array nesting in tool args + tool[:arguments].concat config[top_level_tool][:arguments] + end + end + end + + + def find_and_merge_plugins(config) + # plugins must be loaded before generic path evaluation & magic that happen later; + # perform path magic here as discrete step + config[:plugins][:load_paths].each do |path| + path.replace(@system_wrapper.module_eval(path)) if (path =~ RUBY_STRING_REPLACEMENT_PATTERN) + FilePathUtils::standardize(path) + end + + config[:plugins][:load_paths] << FilePathUtils::standardize(Ceedling.load_path) + config[:plugins][:load_paths].uniq! + + paths_hash = @configurator_plugins.add_load_paths(config) + + @rake_plugins = @configurator_plugins.find_rake_plugins(config, paths_hash) + @script_plugins = @configurator_plugins.find_script_plugins(config, paths_hash) + config_plugins = @configurator_plugins.find_config_plugins(config, paths_hash) + plugin_defaults = @configurator_plugins.find_plugin_defaults(config, paths_hash) + + config_plugins.each do |plugin| + plugin_config = @yaml_wrapper.load(plugin) + config.deep_merge(plugin_config) + end + + plugin_defaults.each do |defaults| + @configurator_builder.populate_defaults( config, @yaml_wrapper.load(defaults) ) + end + + # special plugin setting for results printing + config[:plugins][:display_raw_test_results] = true if (config[:plugins][:display_raw_test_results].nil?) + + paths_hash.each_pair { |name, path| config[:plugins][name] = path } + end + + + def merge_imports(config) + if config[:import] + until config[:import].empty? + path = config[:import].shift + path = @system_wrapper.module_eval(path) if (path =~ RUBY_STRING_REPLACEMENT_PATTERN) + config.deep_merge!(@yaml_wrapper.load(path)) + end + end + config.delete(:import) + end + + + def eval_environment_variables(config) + config[:environment].each do |hash| + key = hash.keys[0] + value = hash[key] + items = [] + + interstitial = ((key == :path) ? File::PATH_SEPARATOR : '') + items = ((value.class == Array) ? hash[key] : [value]) + + items.each { |item| item.replace( @system_wrapper.module_eval( item ) ) if (item =~ RUBY_STRING_REPLACEMENT_PATTERN) } + hash[key] = items.join( interstitial ) + + @system_wrapper.env_set( key.to_s.upcase, hash[key] ) + end + end + + + def eval_paths(config) + # [:plugins]:[load_paths] already handled + + paths = [ # individual paths that don't follow convention processed below + config[:project][:build_root], + config[:release_build][:artifacts]] + + eval_path_list( paths ) + + config[:paths].each_pair { |collection, paths| eval_path_list( paths ) } + + config[:files].each_pair { |collection, files| eval_path_list( files ) } + + # all other paths at secondary hash key level processed by convention: + # ex. [:toplevel][:foo_path] & [:toplevel][:bar_paths] are evaluated + config.each_pair { |parent, child| eval_path_list( collect_path_list( child ) ) } + end + + + def standardize_paths(config) + # [:plugins]:[load_paths] already handled + + paths = [ # individual paths that don't follow convention processed below + config[:project][:build_root], + config[:release_build][:artifacts]] # cmock path in case it was explicitly set in config + + paths.flatten.each { |path| FilePathUtils::standardize( path ) } + + config[:paths].each_pair do |collection, paths| + # ensure that list is an array (i.e. handle case of list being a single string, + # or a multidimensional array) + config[:paths][collection] = [paths].flatten.map{|path| FilePathUtils::standardize( path )} + end + + config[:files].each_pair { |collection, files| files.each{ |path| FilePathUtils::standardize( path ) } } + + config[:tools].each_pair { |tool, config| FilePathUtils::standardize( config[:executable] ) if (config.include? :executable) } + + # all other paths at secondary hash key level processed by convention: + # ex. [:toplevel][:foo_path] & [:toplevel][:bar_paths] are standardized + config.each_pair do |parent, child| + collect_path_list( child ).each { |path| FilePathUtils::standardize( path ) } + end + end + + + def validate(config) + # collect felonies and go straight to jail + raise if (not @configurator_setup.validate_required_sections( config )) + + # collect all misdemeanors, everybody on probation + blotter = [] + blotter << @configurator_setup.validate_required_section_values( config ) + blotter << @configurator_setup.validate_paths( config ) + blotter << @configurator_setup.validate_tools( config ) + blotter << @configurator_setup.validate_plugins( config ) + + raise if (blotter.include?( false )) + end + + + # create constants and accessors (attached to this object) from given hash + def build(config, *keys) + # create flattened & expanded configuration hash + built_config = @configurator_setup.build_project_config( config, @configurator_builder.flattenify( config ) ) + + @project_config_hash = built_config.clone + store_config() + + @configurator_setup.build_constants_and_accessors(built_config, binding()) + + # top-level keys disappear when we flatten, so create global constants & accessors to any specified keys + keys.each do |key| + hash = { key => config[key] } + @configurator_setup.build_constants_and_accessors(hash, binding()) + end + end + + + # add to constants and accessors as post build step + def build_supplement(config_base, config_more) + # merge in our post-build additions to base configuration hash + config_base.deep_merge!( config_more ) + + # flatten our addition hash + config_more_flattened = @configurator_builder.flattenify( config_more ) + + # merge our flattened hash with built hash from previous build + @project_config_hash.deep_merge!( config_more_flattened ) + store_config() + + # create more constants and accessors + @configurator_setup.build_constants_and_accessors(config_more_flattened, binding()) + + # recreate constants & update accessors with new merged, base values + config_more.keys.each do |key| + hash = { key => config_base[key] } + @configurator_setup.build_constants_and_accessors(hash, binding()) + end + end + + + def insert_rake_plugins(plugins) + plugins.each do |plugin| + @project_config_hash[:project_rakefile_component_files] << plugin + end + end + + ### private ### + + private + + def collect_path_list( container ) + paths = [] + container.each_key { |key| paths << container[key] if (key.to_s =~ /_path(s)?$/) } if (container.class == Hash) + return paths.flatten + end + + def eval_path_list( paths ) + if paths.kind_of?(Array) + paths = Array.new(paths) + end + + paths.flatten.each do |path| + path.replace( @system_wrapper.module_eval( path ) ) if (path =~ RUBY_STRING_REPLACEMENT_PATTERN) + end + end + + +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_builder.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_builder.rb new file mode 100644 index 0000000..da8a816 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_builder.rb @@ -0,0 +1,458 @@ +require 'rubygems' +require 'rake' # for ext() method +require 'ceedling/file_path_utils' # for class methods +require 'ceedling/defaults' +require 'ceedling/constants' # for Verbosity constants class & base file paths + + + +class ConfiguratorBuilder + + constructor :file_system_utils, :file_wrapper, :system_wrapper + + + def build_global_constants(config) + config.each_pair do |key, value| + formatted_key = key.to_s.upcase + # undefine global constant if it already exists + Object.send(:remove_const, formatted_key.to_sym) if @system_wrapper.constants_include?(formatted_key) + # create global constant + Object.module_eval("#{formatted_key} = value") + end + end + + + def build_accessor_methods(config, context) + config.each_pair do |key, value| + # fill configurator object with accessor methods + eval("def #{key.to_s.downcase}() return @project_config_hash[:#{key.to_s}] end", context) + end + end + + + # create a flattened hash from the original configuration structure + def flattenify(config) + new_hash = {} + + config.each_key do | parent | + + # gracefully handle empty top-level entries + next if (config[parent].nil?) + + case config[parent] + when Array + config[parent].each do |hash| + key = "#{parent.to_s.downcase}_#{hash.keys[0].to_s.downcase}".to_sym + new_hash[key] = hash[hash.keys[0]] + end + when Hash + config[parent].each_pair do | child, value | + key = "#{parent.to_s.downcase}_#{child.to_s.downcase}".to_sym + new_hash[key] = value + end + # handle entries with no children, only values + else + new_hash["#{parent.to_s.downcase}".to_sym] = config[parent] + end + + end + + return new_hash + end + + + def populate_defaults(config, defaults) + defaults.keys.sort.each do |section| + defaults[section].keys.sort.each do |entry| + config[section] = {} if config[section].nil? + config[section][entry] = defaults[section][entry].deep_clone if (config[section][entry].nil?) + end + end + end + + + def clean(in_hash) + # ensure that include files inserted into test runners have file extensions & proper ones at that + in_hash[:test_runner_includes].map!{|include| include.ext(in_hash[:extension_header])} + end + + + def set_build_paths(in_hash) + out_hash = {} + + project_build_artifacts_root = File.join(in_hash[:project_build_root], 'artifacts') + project_build_tests_root = File.join(in_hash[:project_build_root], TESTS_BASE_PATH) + project_build_release_root = File.join(in_hash[:project_build_root], RELEASE_BASE_PATH) + + paths = [ + [:project_build_artifacts_root, project_build_artifacts_root, true ], + [:project_build_tests_root, project_build_tests_root, true ], + [:project_build_release_root, project_build_release_root, in_hash[:project_release_build] ], + + [:project_test_artifacts_path, File.join(project_build_artifacts_root, TESTS_BASE_PATH), true ], + [:project_test_runners_path, File.join(project_build_tests_root, 'runners'), true ], + [:project_test_results_path, File.join(project_build_tests_root, 'results'), true ], + [:project_test_build_output_path, File.join(project_build_tests_root, 'out'), true ], + [:project_test_build_output_asm_path, File.join(project_build_tests_root, 'out', 'asm'), true ], + [:project_test_build_output_c_path, File.join(project_build_tests_root, 'out', 'c'), true ], + [:project_test_build_cache_path, File.join(project_build_tests_root, 'cache'), true ], + [:project_test_dependencies_path, File.join(project_build_tests_root, 'dependencies'), true ], + + [:project_release_artifacts_path, File.join(project_build_artifacts_root, RELEASE_BASE_PATH), in_hash[:project_release_build] ], + [:project_release_build_cache_path, File.join(project_build_release_root, 'cache'), in_hash[:project_release_build] ], + [:project_release_build_output_path, File.join(project_build_release_root, 'out'), in_hash[:project_release_build] ], + [:project_release_build_output_asm_path, File.join(project_build_release_root, 'out', 'asm'), in_hash[:project_release_build] ], + [:project_release_build_output_c_path, File.join(project_build_release_root, 'out', 'c'), in_hash[:project_release_build] ], + [:project_release_dependencies_path, File.join(project_build_release_root, 'dependencies'), in_hash[:project_release_build] ], + + [:project_log_path, File.join(in_hash[:project_build_root], 'logs'), true ], + [:project_temp_path, File.join(in_hash[:project_build_root], 'temp'), true ], + + [:project_test_preprocess_includes_path, File.join(project_build_tests_root, 'preprocess/includes'), in_hash[:project_use_test_preprocessor] ], + [:project_test_preprocess_files_path, File.join(project_build_tests_root, 'preprocess/files'), in_hash[:project_use_test_preprocessor] ], + ] + + out_hash[:project_build_paths] = [] + + # fetch already set mock path + out_hash[:project_build_paths] << in_hash[:cmock_mock_path] if (in_hash[:project_use_mocks]) + + paths.each do |path| + build_path_name = path[0] + build_path = path[1] + build_path_add_condition = path[2] + + # insert path into build paths if associated with true condition + out_hash[:project_build_paths] << build_path if build_path_add_condition + # set path symbol name and path for each entry in paths array + out_hash[build_path_name] = build_path + end + + return out_hash + end + + + def set_force_build_filepaths(in_hash) + out_hash = {} + + out_hash[:project_test_force_rebuild_filepath] = File.join( in_hash[:project_test_dependencies_path], 'force_build' ) + out_hash[:project_release_force_rebuild_filepath] = File.join( in_hash[:project_release_dependencies_path], 'force_build' ) if (in_hash[:project_release_build]) + + return out_hash + end + + + def set_rakefile_components(in_hash) + out_hash = { + :project_rakefile_component_files => + [File.join(CEEDLING_LIB, 'ceedling', 'tasks_base.rake'), + File.join(CEEDLING_LIB, 'ceedling', 'tasks_filesystem.rake'), + File.join(CEEDLING_LIB, 'ceedling', 'tasks_tests.rake'), + File.join(CEEDLING_LIB, 'ceedling', 'tasks_vendor.rake'), + File.join(CEEDLING_LIB, 'ceedling', 'rules_tests.rake')]} + + out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'ceedling', 'rules_cmock.rake') if (in_hash[:project_use_mocks]) + out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'ceedling', 'rules_preprocess.rake') if (in_hash[:project_use_test_preprocessor]) + out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'ceedling', 'rules_tests_deep_dependencies.rake') if (in_hash[:project_use_deep_dependencies]) + out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'ceedling', 'tasks_tests_deep_dependencies.rake') if (in_hash[:project_use_deep_dependencies]) + + out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'ceedling', 'rules_release_deep_dependencies.rake') if (in_hash[:project_release_build] and in_hash[:project_use_deep_dependencies]) + out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'ceedling', 'rules_release.rake') if (in_hash[:project_release_build]) + out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'ceedling', 'tasks_release_deep_dependencies.rake') if (in_hash[:project_release_build] and in_hash[:project_use_deep_dependencies]) + out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'ceedling', 'tasks_release.rake') if (in_hash[:project_release_build]) + + return out_hash + end + + + def set_release_target(in_hash) + return {} if (not in_hash[:project_release_build]) + + release_target_file = ((in_hash[:release_build_output].nil?) ? (DEFAULT_RELEASE_TARGET_NAME.ext(in_hash[:extension_executable])) : in_hash[:release_build_output]) + release_map_file = ((in_hash[:release_build_output].nil?) ? (DEFAULT_RELEASE_TARGET_NAME.ext(in_hash[:extension_map])) : in_hash[:release_build_output].ext(in_hash[:extension_map])) + + return { + # tempted to make a helper method in file_path_utils? stop right there, pal. you'll introduce a cyclical dependency + :project_release_build_target => File.join(in_hash[:project_build_release_root], release_target_file), + :project_release_build_map => File.join(in_hash[:project_build_release_root], release_map_file) + } + end + + + def collect_project_options(in_hash) + options = [] + + in_hash[:project_options_paths].each do |path| + options << @file_wrapper.directory_listing( File.join(path, '*.yml') ) + end + + return { + :collection_project_options => options.flatten + } + end + + + def expand_all_path_globs(in_hash) + out_hash = {} + path_keys = [] + + in_hash.each_key do |key| + next if (not key.to_s[0..4] == 'paths') + path_keys << key + end + + # sorted to provide assured order of traversal in test calls on mocks + path_keys.sort.each do |key| + out_hash["collection_#{key.to_s}".to_sym] = @file_system_utils.collect_paths( in_hash[key] ) + end + + return out_hash + end + + + def collect_source_and_include_paths(in_hash) + return { + :collection_paths_source_and_include => + ( in_hash[:collection_paths_source] + + in_hash[:collection_paths_include] ).select {|x| File.directory?(x)} + } + end + + + def collect_source_include_vendor_paths(in_hash) + extra_paths = [] + extra_paths << File.join(in_hash[:cexception_vendor_path], CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions]) + + return { + :collection_paths_source_include_vendor => + in_hash[:collection_paths_source_and_include] + + extra_paths + } + end + + + def collect_test_support_source_include_paths(in_hash) + return { + :collection_paths_test_support_source_include => + (in_hash[:collection_paths_test] + + in_hash[:collection_paths_support] + + in_hash[:collection_paths_source] + + in_hash[:collection_paths_include] ).select {|x| File.directory?(x)} + } + end + + + def collect_vendor_paths(in_hash) + return {:collection_paths_vendor => get_vendor_paths(in_hash)} + end + + + def collect_test_support_source_include_vendor_paths(in_hash) + return { + :collection_paths_test_support_source_include_vendor => + in_hash[:collection_paths_test_support_source_include] + + get_vendor_paths(in_hash) + } + end + + + def collect_tests(in_hash) + all_tests = @file_wrapper.instantiate_file_list + + in_hash[:collection_paths_test].each do |path| + all_tests.include( File.join(path, "#{in_hash[:project_test_file_prefix]}*#{in_hash[:extension_source]}") ) + end + + @file_system_utils.revise_file_list( all_tests, in_hash[:files_test] ) + + return {:collection_all_tests => all_tests} + end + + + def collect_assembly(in_hash) + all_assembly = @file_wrapper.instantiate_file_list + + return {:collection_all_assembly => all_assembly} if ((not in_hash[:release_build_use_assembly]) && (not in_hash[:test_build_use_assembly])) + + # Sprinkle in all assembly files we can find in the source folders + in_hash[:collection_paths_source].each do |path| + all_assembly.include( File.join(path, "*#{in_hash[:extension_assembly]}") ) + end + + # Also add all assembly files we can find in the support folders + in_hash[:collection_paths_support].each do |path| + all_assembly.include( File.join(path, "*#{in_hash[:extension_assembly]}") ) + end + + # Also add files that we are explicitly adding via :files:assembly: section + @file_system_utils.revise_file_list( all_assembly, in_hash[:files_assembly] ) + + return {:collection_all_assembly => all_assembly} + end + + + def collect_source(in_hash) + all_source = @file_wrapper.instantiate_file_list + in_hash[:collection_paths_source].each do |path| + if File.exists?(path) and not File.directory?(path) + all_source.include( path ) + else + all_source.include( File.join(path, "*#{in_hash[:extension_source]}") ) + end + end + @file_system_utils.revise_file_list( all_source, in_hash[:files_source] ) + + return {:collection_all_source => all_source} + end + + + def collect_headers(in_hash) + all_headers = @file_wrapper.instantiate_file_list + + paths = + in_hash[:collection_paths_test] + + in_hash[:collection_paths_support] + + in_hash[:collection_paths_source] + + in_hash[:collection_paths_include] + + paths.each do |path| + all_headers.include( File.join(path, "*#{in_hash[:extension_header]}") ) + end + + @file_system_utils.revise_file_list( all_headers, in_hash[:files_include] ) + + return {:collection_all_headers => all_headers} + end + + + def collect_release_existing_compilation_input(in_hash) + release_input = @file_wrapper.instantiate_file_list + + paths = + in_hash[:collection_paths_source] + + in_hash[:collection_paths_include] + + paths << File.join(in_hash[:cexception_vendor_path], CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions]) + + paths.each do |path| + release_input.include( File.join(path, "*#{in_hash[:extension_header]}") ) + if File.exists?(path) and not File.directory?(path) + release_input.include( path ) + else + release_input.include( File.join(path, "*#{in_hash[:extension_source]}") ) + end + end + + @file_system_utils.revise_file_list( release_input, in_hash[:files_source] ) + @file_system_utils.revise_file_list( release_input, in_hash[:files_include] ) + # finding assembly files handled explicitly through other means + + return {:collection_release_existing_compilation_input => release_input} + end + + + def collect_all_existing_compilation_input(in_hash) + all_input = @file_wrapper.instantiate_file_list + + paths = + in_hash[:collection_paths_test] + + in_hash[:collection_paths_support] + + in_hash[:collection_paths_source] + + in_hash[:collection_paths_include] + + [File.join(in_hash[:unity_vendor_path], UNITY_LIB_PATH)] + + paths << File.join(in_hash[:cexception_vendor_path], CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions]) + paths << File.join(in_hash[:cmock_vendor_path], CMOCK_LIB_PATH) if (in_hash[:project_use_mocks]) + + paths.each do |path| + all_input.include( File.join(path, "*#{in_hash[:extension_header]}") ) + if File.exists?(path) and not File.directory?(path) + all_input.include( path ) + else + all_input.include( File.join(path, "*#{in_hash[:extension_source]}") ) + all_input.include( File.join(path, "*#{in_hash[:extension_assembly]}") ) if (defined?(TEST_BUILD_USE_ASSEMBLY) && TEST_BUILD_USE_ASSEMBLY) + end + end + + @file_system_utils.revise_file_list( all_input, in_hash[:files_test] ) + @file_system_utils.revise_file_list( all_input, in_hash[:files_support] ) + @file_system_utils.revise_file_list( all_input, in_hash[:files_source] ) + @file_system_utils.revise_file_list( all_input, in_hash[:files_include] ) + # finding assembly files handled explicitly through other means + + return {:collection_all_existing_compilation_input => all_input} + end + + + def collect_test_and_vendor_defines(in_hash) + test_defines = in_hash[:defines_test].clone + + test_defines.concat(in_hash[:unity_defines]) + test_defines.concat(in_hash[:cmock_defines]) if (in_hash[:project_use_mocks]) + test_defines.concat(in_hash[:cexception_defines]) if (in_hash[:project_use_exceptions]) + + return {:collection_defines_test_and_vendor => test_defines} + end + + + def collect_release_and_vendor_defines(in_hash) + release_defines = in_hash[:defines_release].clone + + release_defines.concat(in_hash[:cexception_defines]) if (in_hash[:project_use_exceptions]) + + return {:collection_defines_release_and_vendor => release_defines} + end + + + def collect_release_artifact_extra_link_objects(in_hash) + objects = [] + + # no build paths here so plugins can remap if necessary (i.e. path mapping happens at runtime) + objects << CEXCEPTION_C_FILE.ext( in_hash[:extension_object] ) if (in_hash[:project_use_exceptions]) + + return {:collection_release_artifact_extra_link_objects => objects} + end + + + def collect_test_fixture_extra_link_objects(in_hash) + # Note: Symbols passed to compiler at command line can change Unity and CException behavior / configuration; + # we also handle those dependencies elsewhere in compilation dependencies + + objects = [UNITY_C_FILE] + + in_hash[:files_support].each { |file| objects << File.basename(file) } + + # we don't include paths here because use of plugins or mixing different compilers may require different build paths + objects << CEXCEPTION_C_FILE if (in_hash[:project_use_exceptions]) + objects << CMOCK_C_FILE if (in_hash[:project_use_mocks]) + + # if we're using mocks & a unity helper is defined & that unity helper includes a source file component (not only a header of macros), + # then link in the unity_helper object file too + if ( in_hash[:project_use_mocks] and in_hash[:cmock_unity_helper] ) + in_hash[:cmock_unity_helper].each do |helper| + if @file_wrapper.exist?(helper.ext(in_hash[:extension_source])) + objects << File.basename(helper) + end + end + end + + # no build paths here so plugins can remap if necessary (i.e. path mapping happens at runtime) + objects.map! { |object| object.ext(in_hash[:extension_object]) } + + return { :collection_test_fixture_extra_link_objects => objects } + end + + + private + + def get_vendor_paths(in_hash) + vendor_paths = [] + vendor_paths << File.join(in_hash[:unity_vendor_path], UNITY_LIB_PATH) + vendor_paths << File.join(in_hash[:cexception_vendor_path], CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions]) + vendor_paths << File.join(in_hash[:cmock_vendor_path], CMOCK_LIB_PATH) if (in_hash[:project_use_mocks]) + vendor_paths << in_hash[:cmock_mock_path] if (in_hash[:project_use_mocks]) + + return vendor_paths + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_plugins.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_plugins.rb new file mode 100644 index 0000000..70ca884 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_plugins.rb @@ -0,0 +1,111 @@ +require 'ceedling/constants' + +class ConfiguratorPlugins + + constructor :stream_wrapper, :file_wrapper, :system_wrapper + attr_reader :rake_plugins, :script_plugins + + def setup + @rake_plugins = [] + @script_plugins = [] + end + + + def add_load_paths(config) + plugin_paths = {} + + config[:plugins][:enabled].each do |plugin| + config[:plugins][:load_paths].each do |root| + path = File.join(root, plugin) + + is_script_plugin = ( not @file_wrapper.directory_listing( File.join( path, 'lib', '*.rb' ) ).empty? ) + is_rake_plugin = ( not @file_wrapper.directory_listing( File.join( path, '*.rake' ) ).empty? ) + + if is_script_plugin or is_rake_plugin + plugin_paths[(plugin + '_path').to_sym] = path + + if is_script_plugin + @system_wrapper.add_load_path( File.join( path, 'lib') ) + end + break + end + end + end + + return plugin_paths + end + + + # gather up and return .rake filepaths that exist on-disk + def find_rake_plugins(config, plugin_paths) + @rake_plugins = [] + plugins_with_path = [] + + config[:plugins][:enabled].each do |plugin| + if path = plugin_paths[(plugin + '_path').to_sym] + rake_plugin_path = File.join(path, "#{plugin}.rake") + if (@file_wrapper.exist?(rake_plugin_path)) + plugins_with_path << rake_plugin_path + @rake_plugins << plugin + end + end + end + + return plugins_with_path + end + + + # gather up and return just names of .rb classes that exist on-disk + def find_script_plugins(config, plugin_paths) + @script_plugins = [] + + config[:plugins][:enabled].each do |plugin| + if path = plugin_paths[(plugin + '_path').to_sym] + script_plugin_path = File.join(path, "lib", "#{plugin}.rb") + + if @file_wrapper.exist?(script_plugin_path) + @script_plugins << plugin + end + end + end + + return @script_plugins + end + + + # gather up and return configuration .yml filepaths that exist on-disk + def find_config_plugins(config, plugin_paths) + plugins_with_path = [] + + config[:plugins][:enabled].each do |plugin| + if path = plugin_paths[(plugin + '_path').to_sym] + config_plugin_path = File.join(path, "config", "#{plugin}.yml") + + if @file_wrapper.exist?(config_plugin_path) + plugins_with_path << config_plugin_path + end + end + end + + return plugins_with_path + end + + + # gather up and return default .yml filepaths that exist on-disk + def find_plugin_defaults(config, plugin_paths) + defaults_with_path = [] + + config[:plugins][:enabled].each do |plugin| + if path = plugin_paths[(plugin + '_path').to_sym] + default_path = File.join(path, 'config', 'defaults.yml') + + if @file_wrapper.exist?(default_path) + defaults_with_path << default_path + end + end + end + + return defaults_with_path + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_setup.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_setup.rb new file mode 100644 index 0000000..1d029b0 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_setup.rb @@ -0,0 +1,127 @@ + +# add sort-ability to symbol so we can order keys array in hash for test-ability +class Symbol + include Comparable + + def <=>(other) + self.to_s <=> other.to_s + end +end + + +class ConfiguratorSetup + + constructor :configurator_builder, :configurator_validator, :configurator_plugins, :stream_wrapper + + + def build_project_config(config, flattened_config) + ### flesh out config + @configurator_builder.clean(flattened_config) + + ### add to hash values we build up from configuration & file system contents + flattened_config.merge!(@configurator_builder.set_build_paths(flattened_config)) + flattened_config.merge!(@configurator_builder.set_force_build_filepaths(flattened_config)) + flattened_config.merge!(@configurator_builder.set_rakefile_components(flattened_config)) + flattened_config.merge!(@configurator_builder.set_release_target(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_project_options(flattened_config)) + + ### iterate through all entries in paths section and expand any & all globs to actual paths + flattened_config.merge!(@configurator_builder.expand_all_path_globs(flattened_config)) + + flattened_config.merge!(@configurator_builder.collect_vendor_paths(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_source_and_include_paths(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_source_include_vendor_paths(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_test_support_source_include_paths(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_test_support_source_include_vendor_paths(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_tests(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_assembly(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_source(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_headers(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_release_existing_compilation_input(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_all_existing_compilation_input(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_test_and_vendor_defines(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_release_and_vendor_defines(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_release_artifact_extra_link_objects(flattened_config)) + flattened_config.merge!(@configurator_builder.collect_test_fixture_extra_link_objects(flattened_config)) + + return flattened_config + end + + + def build_constants_and_accessors(config, context) + @configurator_builder.build_global_constants(config) + @configurator_builder.build_accessor_methods(config, context) + end + + + def validate_required_sections(config) + validation = [] + validation << @configurator_validator.exists?(config, :project) + validation << @configurator_validator.exists?(config, :paths) + + return false if (validation.include?(false)) + return true + end + + def validate_required_section_values(config) + validation = [] + validation << @configurator_validator.exists?(config, :project, :build_root) + validation << @configurator_validator.exists?(config, :paths, :test) + validation << @configurator_validator.exists?(config, :paths, :source) + + return false if (validation.include?(false)) + return true + end + + def validate_paths(config) + validation = [] + + if config[:cmock][:unity_helper] + config[:cmock][:unity_helper].each do |path| + validation << @configurator_validator.validate_filepath_simple( path, :cmock, :unity_helper ) + end + end + + config[:project][:options_paths].each do |path| + validation << @configurator_validator.validate_filepath_simple( path, :project, :options_paths ) + end + + config[:plugins][:load_paths].each do |path| + validation << @configurator_validator.validate_filepath_simple( path, :plugins, :load_paths ) + end + + config[:paths].keys.sort.each do |key| + validation << @configurator_validator.validate_path_list(config, :paths, key) + end + + return false if (validation.include?(false)) + return true + end + + def validate_tools(config) + validation = [] + + config[:tools].keys.sort.each do |key| + validation << @configurator_validator.exists?(config, :tools, key, :executable) + validation << @configurator_validator.validate_executable_filepath(config, :tools, key, :executable) if (not config[:tools][key][:optional]) + validation << @configurator_validator.validate_tool_stderr_redirect(config, :tools, key) + end + + return false if (validation.include?(false)) + return true + end + + def validate_plugins(config) + missing_plugins = + Set.new( config[:plugins][:enabled] ) - + Set.new( @configurator_plugins.rake_plugins ) - + Set.new( @configurator_plugins.script_plugins ) + + missing_plugins.each do |plugin| + @stream_wrapper.stderr_puts("ERROR: Ceedling plugin '#{plugin}' contains no rake or ruby class entry point. (Misspelled or missing files?)") + end + + return ( (missing_plugins.size > 0) ? false : true ) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_validator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_validator.rb new file mode 100644 index 0000000..fc02101 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/configurator_validator.rb @@ -0,0 +1,193 @@ +require 'rubygems' +require 'rake' # for ext() +require 'ceedling/constants' +require 'ceedling/tool_executor' # for argument replacement pattern +require 'ceedling/file_path_utils' # for glob handling class methods + + +class ConfiguratorValidator + + constructor :file_wrapper, :stream_wrapper, :system_wrapper + + # walk into config hash verify existence of data at key depth + def exists?(config, *keys) + hash = retrieve_value(config, keys) + exist = !hash[:value].nil? + + if (not exist) + # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator + @stream_wrapper.stderr_puts("ERROR: Required config file entry #{format_key_sequence(keys, hash[:depth])} does not exist.") + end + + return exist + end + + + # walk into config hash. verify directory path(s) at given key depth + def validate_path_list(config, *keys) + hash = retrieve_value(config, keys) + list = hash[:value] + + # return early if we couldn't walk into hash and find a value + return false if (list.nil?) + + path_list = [] + exist = true + + case list + when String then path_list << list + when Array then path_list = list + end + + path_list.each do |path| + base_path = FilePathUtils::extract_path(path) # lop off add/subtract notation & glob specifiers + + if (not @file_wrapper.exist?(base_path)) + # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator + @stream_wrapper.stderr_puts("ERROR: Config path #{format_key_sequence(keys, hash[:depth])}['#{base_path}'] does not exist on disk.") + exist = false + end + end + + return exist + end + + + # simple path verification + def validate_filepath_simple(path, *keys) + validate_path = path + + if (not @file_wrapper.exist?(validate_path)) + # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator + @stream_wrapper.stderr_puts("ERROR: Config path '#{validate_path}' associated with #{format_key_sequence(keys, keys.size)} does not exist on disk.") + return false + end + + return true + end + + # walk into config hash. verify specified file exists. + def validate_filepath(config, *keys) + hash = retrieve_value(config, keys) + filepath = hash[:value] + + # return early if we couldn't walk into hash and find a value + return false if (filepath.nil?) + + # skip everything if we've got an argument replacement pattern + return true if (filepath =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN) + + if (not @file_wrapper.exist?(filepath)) + + # See if we can deal with it internally. + if GENERATED_DIR_PATH.include?(filepath) + # we already made this directory before let's make it again. + FileUtils.mkdir_p File.join(File.dirname(__FILE__), filepath) + @stream_wrapper.stderr_puts("WARNING: Generated filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk. Recreating") + + else + # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator + @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk.") + return false + end + end + + return true + end + + # walk into config hash. verify specified file exists. + def validate_executable_filepath(config, *keys) + exe_extension = config[:extension][:executable] + hash = retrieve_value(config, keys) + filepath = hash[:value] + + # return early if we couldn't walk into hash and find a value + return false if (filepath.nil?) + + # skip everything if we've got an argument replacement pattern + return true if (filepath =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN) + + # if there's no path included, verify file exists somewhere in system search paths + if (not filepath.include?('/')) + exists = false + + @system_wrapper.search_paths.each do |path| + if (@file_wrapper.exist?( File.join(path, filepath)) ) + exists = true + break + end + + if (@file_wrapper.exist?( (File.join(path, filepath)).ext( exe_extension ) )) + exists = true + break + elsif (@system_wrapper.windows? and @file_wrapper.exist?( (File.join(path, filepath)).ext( EXTENSION_WIN_EXE ) )) + exists = true + break + end + end + + if (not exists) + # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator + @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist in system search paths.") + return false + end + + # if there is a path included, check that explicit filepath exists + else + if (not @file_wrapper.exist?(filepath)) + # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator + @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk.") + return false + end + end + + return true + end + + def validate_tool_stderr_redirect(config, tools, tool) + redirect = config[tools][tool][:stderr_redirect] + if (redirect.class == Symbol) + # map constants and force to array of strings for runtime universality across ruby versions + if (not StdErrRedirect.constants.map{|constant| constant.to_s}.include?(redirect.to_s.upcase)) + error = "ERROR: [:#{tools}][:#{tool}][:stderr_redirect][:#{redirect}] is not a recognized option " + + "{#{StdErrRedirect.constants.map{|constant| ':' + constant.to_s.downcase}.join(', ')}}." + @stream_wrapper.stderr_puts(error) + return false + end + end + + return true + end + + private ######################################### + + + def retrieve_value(config, keys) + value = nil + hash = config + depth = 0 + + # walk into hash & extract value at requested key sequence + keys.each do |symbol| + depth += 1 + if (not hash[symbol].nil?) + hash = hash[symbol] + value = hash + else + value = nil + break + end + end + + return {:value => value, :depth => depth} + end + + + def format_key_sequence(keys, depth) + walked_keys = keys.slice(0, depth) + formatted_keys = walked_keys.map{|key| "[:#{key.to_s}]"} + + return formatted_keys.join + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/constants.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/constants.rb new file mode 100644 index 0000000..993ce8d --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/constants.rb @@ -0,0 +1,97 @@ + +class Verbosity + SILENT = 0 # as silent as possible (though there are some messages that must be spit out) + ERRORS = 1 # only errors + COMPLAIN = 2 # spit out errors and warnings/notices + NORMAL = 3 # errors, warnings/notices, standard status messages + OBNOXIOUS = 4 # all messages including extra verbose output (used for lite debugging / verification) + DEBUG = 5 # special extra verbose output for hardcore debugging +end + + +class TestResultsSanityChecks + NONE = 0 # no sanity checking of test results + NORMAL = 1 # perform non-problematic checks + THOROUGH = 2 # perform checks that require inside knowledge of system workings +end + + +class StdErrRedirect + NONE = :none + AUTO = :auto + WIN = :win + UNIX = :unix + TCSH = :tcsh +end + + +class BackgroundExec + NONE = :none + AUTO = :auto + WIN = :win + UNIX = :unix +end + +unless defined?(PROJECT_ROOT) + PROJECT_ROOT = Dir.pwd() +end + +GENERATED_DIR_PATH = [['vendor', 'ceedling'], 'src', "test", ['test', 'support'], 'build'].each{|p| File.join(*p)} + +EXTENSION_WIN_EXE = '.exe' +EXTENSION_NONWIN_EXE = '.out' + + +CEXCEPTION_ROOT_PATH = 'c_exception' +CEXCEPTION_LIB_PATH = "#{CEXCEPTION_ROOT_PATH}/lib" +CEXCEPTION_C_FILE = 'CException.c' +CEXCEPTION_H_FILE = 'CException.h' + +UNITY_ROOT_PATH = 'unity' +UNITY_LIB_PATH = "#{UNITY_ROOT_PATH}/src" +UNITY_C_FILE = 'unity.c' +UNITY_H_FILE = 'unity.h' +UNITY_INTERNALS_H_FILE = 'unity_internals.h' + +CMOCK_ROOT_PATH = 'cmock' +CMOCK_LIB_PATH = "#{CMOCK_ROOT_PATH}/src" +CMOCK_C_FILE = 'cmock.c' +CMOCK_H_FILE = 'cmock.h' + + +DEFAULT_CEEDLING_MAIN_PROJECT_FILE = 'project.yml' unless defined?(DEFAULT_CEEDLING_MAIN_PROJECT_FILE) # main project file +DEFAULT_CEEDLING_USER_PROJECT_FILE = 'user.yml' unless defined?(DEFAULT_CEEDLING_USER_PROJECT_FILE) # supplemental user config file + +INPUT_CONFIGURATION_CACHE_FILE = 'input.yml' unless defined?(INPUT_CONFIGURATION_CACHE_FILE) # input configuration file dump +DEFINES_DEPENDENCY_CACHE_FILE = 'defines_dependency.yml' unless defined?(DEFINES_DEPENDENCY_CACHE_FILE) # preprocessor definitions for files + +TEST_ROOT_NAME = 'test' unless defined?(TEST_ROOT_NAME) +TEST_TASK_ROOT = TEST_ROOT_NAME + ':' unless defined?(TEST_TASK_ROOT) +TEST_SYM = TEST_ROOT_NAME.to_sym unless defined?(TEST_SYM) + +RELEASE_ROOT_NAME = 'release' unless defined?(RELEASE_ROOT_NAME) +RELEASE_TASK_ROOT = RELEASE_ROOT_NAME + ':' unless defined?(RELEASE_TASK_ROOT) +RELEASE_SYM = RELEASE_ROOT_NAME.to_sym unless defined?(RELEASE_SYM) + +REFRESH_ROOT_NAME = 'refresh' unless defined?(REFRESH_ROOT_NAME) +REFRESH_TASK_ROOT = REFRESH_ROOT_NAME + ':' unless defined?(REFRESH_TASK_ROOT) +REFRESH_SYM = REFRESH_ROOT_NAME.to_sym unless defined?(REFRESH_SYM) + +UTILS_ROOT_NAME = 'utils' unless defined?(UTILS_ROOT_NAME) +UTILS_TASK_ROOT = UTILS_ROOT_NAME + ':' unless defined?(UTILS_TASK_ROOT) +UTILS_SYM = UTILS_ROOT_NAME.to_sym unless defined?(UTILS_SYM) + +OPERATION_COMPILE_SYM = :compile unless defined?(OPERATION_COMPILE_SYM) +OPERATION_ASSEMBLE_SYM = :assemble unless defined?(OPERATION_ASSEMBLE_SYM) +OPERATION_LINK_SYM = :link unless defined?(OPERATION_LINK_SYM) + + +RUBY_STRING_REPLACEMENT_PATTERN = /#\{.+\}/ +RUBY_EVAL_REPLACEMENT_PATTERN = /^\{(.+)\}$/ +TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN = /(\$\{(\d+)\})/ +TEST_STDOUT_STATISTICS_PATTERN = /\n-+\s*(\d+)\s+Tests\s+(\d+)\s+Failures\s+(\d+)\s+Ignored\s+(OK|FAIL)\s*/i + +NULL_FILE_PATH = '/dev/null' + +TESTS_BASE_PATH = TEST_ROOT_NAME +RELEASE_BASE_PATH = RELEASE_ROOT_NAME diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/defaults.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/defaults.rb new file mode 100644 index 0000000..9e391fa --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/defaults.rb @@ -0,0 +1,418 @@ +require 'ceedling/constants' +require 'ceedling/system_wrapper' +require 'ceedling/file_path_utils' + +#this should be defined already, but not always during system specs +CEEDLING_VENDOR = File.expand_path(File.dirname(__FILE__) + '/../../vendor') unless defined? CEEDLING_VENDOR +CEEDLING_PLUGINS = [] unless defined? CEEDLING_PLUGINS + +DEFAULT_TEST_COMPILER_TOOL = { + :executable => FilePathUtils.os_executable_ext('gcc').freeze, + :name => 'default_test_compiler'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze, + {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze, + "-DGNU_COMPILER".freeze, + "-g".freeze, + "-c \"${1}\"".freeze, + "-o \"${2}\"".freeze, + # gcc's list file output options are complex; no use of ${3} parameter in default config + "-MMD".freeze, + "-MF \"${4}\"".freeze, + ].freeze + } + +DEFAULT_TEST_LINKER_TOOL = { + :executable => FilePathUtils.os_executable_ext('gcc').freeze, + :name => 'default_test_linker'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + "\"${1}\"".freeze, + "-o \"${2}\"".freeze, + "".freeze, + "${4}".freeze + ].freeze + } + +DEFAULT_TEST_FIXTURE_TOOL = { + :executable => '${1}'.freeze, + :name => 'default_test_fixture'.freeze, + :stderr_redirect => StdErrRedirect::AUTO.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [].freeze + } + +DEFAULT_TEST_INCLUDES_PREPROCESSOR_TOOL = { + :executable => FilePathUtils.os_executable_ext('gcc').freeze, + :name => 'default_test_includes_preprocessor'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + '-E'.freeze, # OSX clang + '-MM'.freeze, + '-MG'.freeze, + # avoid some possibility of deep system lib header file complications by omitting vendor paths + # if cpp is run on *nix system, escape spaces in paths; if cpp on windows just use the paths collection as is + # {"-I\"$\"" => "{SystemWrapper.windows? ? COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE : COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE.map{|path| path.gsub(\/ \/, \'\\\\ \') }}"}.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze, + {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze, + {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze, + "-DGNU_COMPILER".freeze, # OSX clang + '-w'.freeze, + # '-nostdinc'.freeze, # disabled temporarily due to stdio access violations on OSX + "\"${1}\"".freeze + ].freeze + } + +DEFAULT_TEST_FILE_PREPROCESSOR_TOOL = { + :executable => FilePathUtils.os_executable_ext('gcc').freeze, + :name => 'default_test_file_preprocessor'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + '-E'.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze, + {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze, + {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze, + "-DGNU_COMPILER".freeze, + # '-nostdinc'.freeze, # disabled temporarily due to stdio access violations on OSX + "\"${1}\"".freeze, + "-o \"${2}\"".freeze + ].freeze + } + +# Disable the -MD flag for OSX LLVM Clang, since unsupported +if RUBY_PLATFORM =~ /darwin/ && `gcc --version 2> /dev/null` =~ /Apple LLVM version .* \(clang/m # OSX w/LLVM Clang + MD_FLAG = '' # Clang doesn't support the -MD flag +else + MD_FLAG = '-MD' +end + +DEFAULT_TEST_DEPENDENCIES_GENERATOR_TOOL = { + :executable => FilePathUtils.os_executable_ext('gcc').freeze, + :name => 'default_test_dependencies_generator'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + '-E'.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze, + {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze, + {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze, + "-DGNU_COMPILER".freeze, + "-MT \"${3}\"".freeze, + '-MM'.freeze, + MD_FLAG.freeze, + '-MG'.freeze, + "-MF \"${2}\"".freeze, + "-c \"${1}\"".freeze, + # '-nostdinc'.freeze, + ].freeze + } + +DEFAULT_RELEASE_DEPENDENCIES_GENERATOR_TOOL = { + :executable => FilePathUtils.os_executable_ext('gcc').freeze, + :name => 'default_release_dependencies_generator'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + '-E'.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR'}.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE'}.freeze, + {"-D$" => 'COLLECTION_DEFINES_RELEASE_AND_VENDOR'}.freeze, + {"-D$" => 'DEFINES_RELEASE_PREPROCESS'}.freeze, + "-DGNU_COMPILER".freeze, + "-MT \"${3}\"".freeze, + '-MM'.freeze, + MD_FLAG.freeze, + '-MG'.freeze, + "-MF \"${2}\"".freeze, + "-c \"${1}\"".freeze, + # '-nostdinc'.freeze, + ].freeze + } + + +DEFAULT_RELEASE_COMPILER_TOOL = { + :executable => FilePathUtils.os_executable_ext('gcc').freeze, + :name => 'default_release_compiler'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR'}.freeze, + {"-I\"$\"" => 'COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE'}.freeze, + {"-D$" => 'COLLECTION_DEFINES_RELEASE_AND_VENDOR'}.freeze, + "-DGNU_COMPILER".freeze, + "-c \"${1}\"".freeze, + "-o \"${2}\"".freeze, + # gcc's list file output options are complex; no use of ${3} parameter in default config + "-MMD".freeze, + "-MF \"${4}\"".freeze, + ].freeze + } + +DEFAULT_RELEASE_ASSEMBLER_TOOL = { + :executable => FilePathUtils.os_executable_ext('as').freeze, + :name => 'default_release_assembler'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_AND_INCLUDE'}.freeze, + "\"${1}\"".freeze, + "-o \"${2}\"".freeze, + ].freeze + } + +DEFAULT_RELEASE_LINKER_TOOL = { + :executable => FilePathUtils.os_executable_ext('gcc').freeze, + :name => 'default_release_linker'.freeze, + :stderr_redirect => StdErrRedirect::NONE.freeze, + :background_exec => BackgroundExec::NONE.freeze, + :optional => false.freeze, + :arguments => [ + "\"${1}\"".freeze, + "-o \"${2}\"".freeze, + "".freeze, + "${4}".freeze + ].freeze + } + + +DEFAULT_TOOLS_TEST = { + :tools => { + :test_compiler => DEFAULT_TEST_COMPILER_TOOL, + :test_linker => DEFAULT_TEST_LINKER_TOOL, + :test_fixture => DEFAULT_TEST_FIXTURE_TOOL, + } + } + +DEFAULT_TOOLS_TEST_PREPROCESSORS = { + :tools => { + :test_includes_preprocessor => DEFAULT_TEST_INCLUDES_PREPROCESSOR_TOOL, + :test_file_preprocessor => DEFAULT_TEST_FILE_PREPROCESSOR_TOOL, + } + } + +DEFAULT_TOOLS_TEST_DEPENDENCIES = { + :tools => { + :test_dependencies_generator => DEFAULT_TEST_DEPENDENCIES_GENERATOR_TOOL, + } + } + + +DEFAULT_TOOLS_RELEASE = { + :tools => { + :release_compiler => DEFAULT_RELEASE_COMPILER_TOOL, + :release_linker => DEFAULT_RELEASE_LINKER_TOOL, + } + } + +DEFAULT_TOOLS_RELEASE_ASSEMBLER = { + :tools => { + :release_assembler => DEFAULT_RELEASE_ASSEMBLER_TOOL, + } + } + +DEFAULT_TOOLS_RELEASE_DEPENDENCIES = { + :tools => { + :release_dependencies_generator => DEFAULT_RELEASE_DEPENDENCIES_GENERATOR_TOOL, + } + } + + +DEFAULT_RELEASE_TARGET_NAME = 'project' + +DEFAULT_CEEDLING_CONFIG = { + :project => { + # :build_root must be set by user + :use_exceptions => true, + :use_mocks => true, + :compile_threads => 1, + :test_threads => 1, + :use_test_preprocessor => false, + :use_deep_dependencies => false, + :generate_deep_dependencies => true, # only applicable if use_deep_dependencies is true + :test_file_prefix => 'test_', + :options_paths => [], + :release_build => false, + }, + + :release_build => { + # :output is set while building configuration -- allows smart default system-dependent file extension handling + :use_assembly => false, + :artifacts => [], + }, + + :paths => { + :test => [], # must be populated by user + :source => [], # must be populated by user + :support => [], + :include => [], + :test_toolchain_include => [], + :release_toolchain_include => [], + }, + + :files => { + :test => [], + :source => [], + :assembly => [], + :support => [], + :include => [], + }, + + # unlike other top-level entries, environment's value is an array to preserve order + :environment => [ + # when evaluated, this provides wider text field for rake task comments + {:rake_columns => '120'}, + ], + + :defines => { + :test => [], + :test_preprocess => [], + :release => [], + :release_preprocess => [], + :use_test_definition => false, + }, + + :libraries => { + :test => [], + :test_preprocess => [], + :release => [], + :release_preprocess => [], + }, + + :flags => {}, + + :extension => { + :header => '.h', + :source => '.c', + :assembly => '.s', + :object => '.o', + :executable => ( SystemWrapper.windows? ? EXTENSION_WIN_EXE : EXTENSION_NONWIN_EXE ), + :map => '.map', + :list => '.lst', + :testpass => '.pass', + :testfail => '.fail', + :dependencies => '.d', + }, + + :unity => { + :vendor_path => CEEDLING_VENDOR, + :defines => [] + }, + + :cmock => { + :vendor_path => CEEDLING_VENDOR, + :defines => [], + :includes => [] + }, + + :cexception => { + :vendor_path => CEEDLING_VENDOR, + :defines => [] + }, + + :test_runner => { + :includes => [], + :file_suffix => '_runner', + }, + + # all tools populated while building up config structure + :tools => {}, + + # empty argument lists for default tools + # (these can be overridden in project file to add arguments to tools without totally redefining tools) + :test_compiler => { :arguments => [] }, + :test_linker => { :arguments => [] }, + :test_fixture => { + :arguments => [], + :link_objects => [], # compiled object files to always be linked in (e.g. cmock.o if using mocks) + }, + :test_includes_preprocessor => { :arguments => [] }, + :test_file_preprocessor => { :arguments => [] }, + :test_dependencies_generator => { :arguments => [] }, + :release_compiler => { :arguments => [] }, + :release_linker => { :arguments => [] }, + :release_assembler => { :arguments => [] }, + :release_dependencies_generator => { :arguments => [] }, + + :plugins => { + :load_paths => CEEDLING_PLUGINS, + :enabled => [], + } + }.freeze + + +DEFAULT_TESTS_RESULTS_REPORT_TEMPLATE = %q{ +% ignored = hash[:results][:counts][:ignored] +% failed = hash[:results][:counts][:failed] +% stdout_count = hash[:results][:counts][:stdout] +% header_prepend = ((hash[:header].length > 0) ? "#{hash[:header]}: " : '') +% banner_width = 25 + header_prepend.length # widest message + +% if (stdout_count > 0) +<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'TEST OUTPUT')%> +% hash[:results][:stdout].each do |string| +% string[:collection].each do |item| +<%=string[:source][:path]%><%=File::SEPARATOR%><%=string[:source][:file]%>: "<%=item%>" +% end +% end + +% end +% if (ignored > 0) +<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'IGNORED TEST SUMMARY')%> +% hash[:results][:ignores].each do |ignore| +% ignore[:collection].each do |item| +<%=ignore[:source][:path]%><%=File::SEPARATOR%><%=ignore[:source][:file]%>:<%=item[:line]%>:<%=item[:test]%> +% if (item[:message].length > 0) +: "<%=item[:message]%>" +% else +<%="\n"%> +% end +% end +% end + +% end +% if (failed > 0) +<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'FAILED TEST SUMMARY')%> +% hash[:results][:failures].each do |failure| +% failure[:collection].each do |item| +<%=failure[:source][:path]%><%=File::SEPARATOR%><%=failure[:source][:file]%>:<%=item[:line]%>:<%=item[:test]%> +% if (item[:message].length > 0) +: "<%=item[:message]%>" +% else +<%="\n"%> +% end +% end +% end + +% end +% total_string = hash[:results][:counts][:total].to_s +% format_string = "%#{total_string.length}i" +<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'OVERALL TEST SUMMARY')%> +% if (hash[:results][:counts][:total] > 0) +TESTED: <%=hash[:results][:counts][:total].to_s%> +PASSED: <%=sprintf(format_string, hash[:results][:counts][:passed])%> +FAILED: <%=sprintf(format_string, failed)%> +IGNORED: <%=sprintf(format_string, ignored)%> +% else + +No tests executed. +% end + +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/dependinator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/dependinator.rb new file mode 100644 index 0000000..ebd1237 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/dependinator.rb @@ -0,0 +1,98 @@ + +class Dependinator + + constructor :configurator, :project_config_manager, :test_includes_extractor, :file_path_utils, :rake_wrapper, :file_wrapper + + def touch_force_rebuild_files + @file_wrapper.touch( @configurator.project_test_force_rebuild_filepath ) + @file_wrapper.touch( @configurator.project_release_force_rebuild_filepath ) if (@configurator.project_release_build) + end + + + + def load_release_object_deep_dependencies(dependencies_list) + dependencies_list.each do |dependencies_file| + if File.exists?(dependencies_file) + @rake_wrapper.load_dependencies( dependencies_file ) + end + end + end + + + def enhance_release_file_dependencies(files) + files.each do |filepath| + @rake_wrapper[filepath].enhance( [@configurator.project_release_force_rebuild_filepath] ) if (@project_config_manager.release_config_changed) + end + end + + + + def load_test_object_deep_dependencies(files_list) + dependencies_list = @file_path_utils.form_test_dependencies_filelist(files_list) + dependencies_list.each do |dependencies_file| + if File.exists?(dependencies_file) + @rake_wrapper.load_dependencies(dependencies_file) + end + end + end + + + def enhance_runner_dependencies(runner_filepath) + @rake_wrapper[runner_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) + end + + + def enhance_shallow_include_lists_dependencies(include_lists) + include_lists.each do |include_list_filepath| + @rake_wrapper[include_list_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) + end + end + + + def enhance_preprocesed_file_dependencies(files) + files.each do |filepath| + @rake_wrapper[filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) + end + end + + + def enhance_mock_dependencies(mocks_list) + # if input configuration or ceedling changes, make sure these guys get rebuilt + mocks_list.each do |mock_filepath| + @rake_wrapper[mock_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) + @rake_wrapper[mock_filepath].enhance( @configurator.cmock_unity_helper ) if (@configurator.cmock_unity_helper) + end + end + + + def enhance_dependencies_dependencies(dependencies) + dependencies.each do |dependencies_filepath| + @rake_wrapper[dependencies_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) + end + end + + + def enhance_test_build_object_dependencies(objects) + objects.each do |object_filepath| + @rake_wrapper[object_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) + end + end + + + def enhance_results_dependencies(result_filepath) + @rake_wrapper[result_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) + end + + + def setup_test_executable_dependencies(test, objects) + @rake_wrapper.create_file_task( @file_path_utils.form_test_executable_filepath(test), objects ) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/erb_wrapper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/erb_wrapper.rb new file mode 100644 index 0000000..8d70b6d --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/erb_wrapper.rb @@ -0,0 +1,9 @@ +require 'erb' + +class ErbWrapper + def generate_file(template, data, output_file) + File.open(output_file, "w") do |f| + f << ERB.new(template, 0, "<>").result(binding) + end + end +end \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_finder.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_finder.rb new file mode 100644 index 0000000..53775b7 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_finder.rb @@ -0,0 +1,149 @@ +require 'rubygems' +require 'rake' # for adding ext() method to string +require 'thread' + + +class FileFinder + SEMAPHORE = Mutex.new + + constructor :configurator, :file_finder_helper, :cacheinator, :file_path_utils, :file_wrapper, :yaml_wrapper + + def prepare_search_sources + @all_test_source_and_header_file_collection = + @configurator.collection_all_tests + + @configurator.collection_all_source + + @configurator.collection_all_headers + end + + + def find_header_file(mock_file) + header = File.basename(mock_file).sub(/#{@configurator.cmock_mock_prefix}/, '').ext(@configurator.extension_header) + + found_path = @file_finder_helper.find_file_in_collection(header, @configurator.collection_all_headers, :error) + + return found_path + end + + + def find_header_input_for_mock_file(mock_file) + found_path = find_header_file(mock_file) + mock_input = found_path + + if (@configurator.project_use_test_preprocessor) + mock_input = @cacheinator.diff_cached_test_file( @file_path_utils.form_preprocessed_file_filepath( found_path ) ) + end + + return mock_input + end + + + def find_source_from_test(test, complain) + test_prefix = @configurator.project_test_file_prefix + source_paths = @configurator.collection_all_source + + source = File.basename(test).sub(/#{test_prefix}/, '') + + # we don't blow up if a test file has no corresponding source file + return @file_finder_helper.find_file_in_collection(source, source_paths, complain) + end + + + def find_test_from_runner_path(runner_path) + extension_source = @configurator.extension_source + + test_file = File.basename(runner_path).sub(/#{@configurator.test_runner_file_suffix}#{'\\'+extension_source}/, extension_source) + + found_path = @file_finder_helper.find_file_in_collection(test_file, @configurator.collection_all_tests, :error) + + return found_path + end + + + def find_test_input_for_runner_file(runner_path) + found_path = find_test_from_runner_path(runner_path) + runner_input = found_path + + if (@configurator.project_use_test_preprocessor) + runner_input = @cacheinator.diff_cached_test_file( @file_path_utils.form_preprocessed_file_filepath( found_path ) ) + end + + return runner_input + end + + + def find_test_from_file_path(file_path) + test_file = File.basename(file_path).ext(@configurator.extension_source) + + found_path = @file_finder_helper.find_file_in_collection(test_file, @configurator.collection_all_tests, :error) + + return found_path + end + + + def find_test_or_source_or_header_file(file_path) + file = File.basename(file_path) + return @file_finder_helper.find_file_in_collection(file, @all_test_source_and_header_file_collection, :error) + end + + + def find_compilation_input_file(file_path, complain=:error, release=false) + found_file = nil + + source_file = File.basename(file_path).ext(@configurator.extension_source) + + # We only collect files that already exist when we start up. + # FileLists can produce undesired results for dynamically generated files depending on when they're accessed. + # So collect mocks and runners separately and right now. + + SEMAPHORE.synchronize { + + if (source_file =~ /#{@configurator.test_runner_file_suffix}/) + found_file = + @file_finder_helper.find_file_in_collection( + source_file, + @file_wrapper.directory_listing( File.join(@configurator.project_test_runners_path, '*') ), + complain) + + elsif (@configurator.project_use_mocks and (source_file =~ /#{@configurator.cmock_mock_prefix}/)) + found_file = + @file_finder_helper.find_file_in_collection( + source_file, + @file_wrapper.directory_listing( File.join(@configurator.cmock_mock_path, '*') ), + complain) + + elsif release + found_file = + @file_finder_helper.find_file_in_collection( + source_file, + @configurator.collection_release_existing_compilation_input, + complain) + else + temp_complain = (defined?(TEST_BUILD_USE_ASSEMBLY) && TEST_BUILD_USE_ASSEMBLY) ? :ignore : complain + found_file = + @file_finder_helper.find_file_in_collection( + source_file, + @configurator.collection_all_existing_compilation_input, + temp_complain) + found_file ||= find_assembly_file(file_path, false) if (defined?(TEST_BUILD_USE_ASSEMBLY) && TEST_BUILD_USE_ASSEMBLY) + end + } + return found_file + end + + + def find_source_file(file_path, complain) + source_file = File.basename(file_path).ext(@configurator.extension_source) + return @file_finder_helper.find_file_in_collection(source_file, @configurator.collection_all_source, complain) + end + + + def find_assembly_file(file_path, complain = :error) + assembly_file = File.basename(file_path).ext(@configurator.extension_assembly) + return @file_finder_helper.find_file_in_collection(assembly_file, @configurator.collection_all_assembly, complain) + end + + def find_file_from_list(file_path, file_list, complain) + return @file_finder_helper.find_file_in_collection(file_path, file_list, complain) + end +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_finder_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_finder_helper.rb new file mode 100644 index 0000000..0a31b44 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_finder_helper.rb @@ -0,0 +1,54 @@ +require 'fileutils' +require 'ceedling/constants' # for Verbosity enumeration + +class FileFinderHelper + + constructor :streaminator + + + def find_file_in_collection(file_name, file_list, complain, extra_message="") + file_to_find = nil + + file_list.each do |item| + base_file = File.basename(item) + + # case insensitive comparison + if (base_file.casecmp(file_name) == 0) + # case sensitive check + if (base_file == file_name) + file_to_find = item + break + else + blow_up(file_name, "However, a filename having different capitalization was found: '#{item}'.") + end + end + + end + + case (complain) + when :error then blow_up(file_name, extra_message) if (file_to_find.nil?) + when :warn then gripe(file_name, extra_message) if (file_to_find.nil?) + #when :ignore then + end + + return file_to_find + end + + private + + def blow_up(file_name, extra_message="") + error = "ERROR: Found no file '#{file_name}' in search paths." + error += ' ' if (extra_message.length > 0) + @streaminator.stderr_puts(error + extra_message, Verbosity::ERRORS) + raise + end + + def gripe(file_name, extra_message="") + warning = "WARNING: Found no file '#{file_name}' in search paths." + warning += ' ' if (extra_message.length > 0) + @streaminator.stderr_puts(warning + extra_message, Verbosity::COMPLAIN) + end + +end + + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_path_utils.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_path_utils.rb new file mode 100644 index 0000000..607039f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_path_utils.rb @@ -0,0 +1,200 @@ +require 'rubygems' +require 'rake' # for ext() +require 'fileutils' +require 'ceedling/system_wrapper' + +# global utility methods (for plugins, project files, etc.) +def ceedling_form_filepath(destination_path, original_filepath, new_extension=nil) + filename = File.basename(original_filepath) + filename.replace(filename.ext(new_extension)) if (!new_extension.nil?) + return File.join( destination_path.gsub(/\\/, '/'), filename ) +end + +class FilePathUtils + + GLOB_MATCHER = /[\*\?\{\}\[\]]/ + + constructor :configurator, :file_wrapper + + + ######### class methods ########## + + # standardize path to use '/' path separator & have no trailing path separator + def self.standardize(path) + path.strip! + path.gsub!(/\\/, '/') + path.chomp!('/') + return path + end + + def self.os_executable_ext(executable) + return executable.ext('.exe') if SystemWrapper.windows? + return executable + end + + # extract directory path from between optional add/subtract aggregation modifiers and up to glob specifiers + # note: slightly different than File.dirname in that /files/foo remains /files/foo and does not become /files + def self.extract_path(path) + path = path.sub(/^(\+|-):/, '') + + # find first occurrence of path separator followed by directory glob specifier: *, ?, {, }, [, ] + find_index = (path =~ GLOB_MATCHER) + + # no changes needed (lop off final path separator) + return path.chomp('/') if (find_index.nil?) + + # extract up to first glob specifier + path = path[0..(find_index-1)] + + # lop off everything up to and including final path separator + find_index = path.rindex('/') + return path[0..(find_index-1)] if (not find_index.nil?) + + # return string up to first glob specifier if no path separator found + return path + end + + # return whether the given path is to be aggregated (no aggregation modifier defaults to same as +:) + def self.add_path?(path) + return (path =~ /^-:/).nil? + end + + # get path (and glob) lopping off optional +: / -: prefixed aggregation modifiers + def self.extract_path_no_aggregation_operators(path) + return path.sub(/^(\+|-):/, '') + end + + # all the globs that may be in a path string work fine with one exception; + # to recurse through all subdirectories, the glob is dir/**/** but our paths use + # convention of only dir/** + def self.reform_glob(path) + return path if (path =~ /\/\*\*$/).nil? + return path + '/**' + end + + ######### instance methods ########## + + def form_temp_path(filepath, prefix='') + return File.join( @configurator.project_temp_path, prefix + File.basename(filepath) ) + end + + ### release ### + def form_release_build_cache_path(filepath) + return File.join( @configurator.project_release_build_cache_path, File.basename(filepath) ) + end + + def form_release_dependencies_filepath(filepath) + return File.join( @configurator.project_release_dependencies_path, File.basename(filepath).ext(@configurator.extension_dependencies) ) + end + + def form_release_build_c_object_filepath(filepath) + return File.join( @configurator.project_release_build_output_c_path, File.basename(filepath).ext(@configurator.extension_object) ) + end + + def form_release_build_asm_object_filepath(filepath) + return File.join( @configurator.project_release_build_output_asm_path, File.basename(filepath).ext(@configurator.extension_object) ) + end + + def form_release_build_c_objects_filelist(files) + return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_build_output_c_path}/%n#{@configurator.extension_object}") + end + + def form_release_build_asm_objects_filelist(files) + return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_build_output_asm_path}/%n#{@configurator.extension_object}") + end + + def form_release_build_c_list_filepath(filepath) + return File.join( @configurator.project_release_build_output_c_path, File.basename(filepath).ext(@configurator.extension_list) ) + end + + def form_release_dependencies_filelist(files) + return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_dependencies_path}/%n#{@configurator.extension_dependencies}") + end + + ### tests ### + def form_test_build_cache_path(filepath) + return File.join( @configurator.project_test_build_cache_path, File.basename(filepath) ) + end + + def form_test_dependencies_filepath(filepath) + return File.join( @configurator.project_test_dependencies_path, File.basename(filepath).ext(@configurator.extension_dependencies) ) + end + + def form_pass_results_filepath(filepath) + return File.join( @configurator.project_test_results_path, File.basename(filepath).ext(@configurator.extension_testpass) ) + end + + def form_fail_results_filepath(filepath) + return File.join( @configurator.project_test_results_path, File.basename(filepath).ext(@configurator.extension_testfail) ) + end + + def form_runner_filepath_from_test(filepath) + return File.join( @configurator.project_test_runners_path, File.basename(filepath, @configurator.extension_source)) + @configurator.test_runner_file_suffix + @configurator.extension_source + end + + def form_test_filepath_from_runner(filepath) + return filepath.sub(/#{TEST_RUNNER_FILE_SUFFIX}/, '') + end + + def form_runner_object_filepath_from_test(filepath) + return (form_test_build_c_object_filepath(filepath)).sub(/(#{@configurator.extension_object})$/, "#{@configurator.test_runner_file_suffix}\\1") + end + + def form_test_build_c_object_filepath(filepath) + return File.join( @configurator.project_test_build_output_c_path, File.basename(filepath).ext(@configurator.extension_object) ) + end + + def form_test_build_asm_object_filepath(filepath) + return File.join( @configurator.project_test_build_output_asm_path, File.basename(filepath).ext(@configurator.extension_object) ) + end + + def form_test_executable_filepath(filepath) + return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_executable) ) + end + + def form_test_build_map_filepath(filepath) + return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_map) ) + end + + def form_test_build_list_filepath(filepath) + return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_list) ) + end + + def form_preprocessed_file_filepath(filepath) + return File.join( @configurator.project_test_preprocess_files_path, File.basename(filepath) ) + end + + def form_preprocessed_includes_list_filepath(filepath) + return File.join( @configurator.project_test_preprocess_includes_path, File.basename(filepath) ) + end + + def form_test_build_objects_filelist(sources) + return (@file_wrapper.instantiate_file_list(sources)).pathmap("#{@configurator.project_test_build_output_c_path}/%n#{@configurator.extension_object}") + end + + def form_preprocessed_mockable_headers_filelist(mocks) + list = @file_wrapper.instantiate_file_list(mocks) + headers = list.map do |file| + module_name = File.basename(file).sub(/^#{@configurator.cmock_mock_prefix}/, '').sub(/\.[a-zA-Z]+$/,'') + "#{@configurator.project_test_preprocess_files_path}/#{module_name}#{@configurator.extension_header}" + end + return headers + end + + def form_mocks_source_filelist(mocks) + list = (@file_wrapper.instantiate_file_list(mocks)) + sources = list.map{|file| "#{@configurator.cmock_mock_path}/#{file}#{@configurator.extension_source}"} + return sources + end + + def form_test_dependencies_filelist(files) + list = @file_wrapper.instantiate_file_list(files) + return list.pathmap("#{@configurator.project_test_dependencies_path}/%n#{@configurator.extension_dependencies}") + end + + def form_pass_results_filelist(path, files) + list = @file_wrapper.instantiate_file_list(files) + return list.pathmap("#{path}/%n#{@configurator.extension_testpass}") + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_system_utils.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_system_utils.rb new file mode 100644 index 0000000..97e5856 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_system_utils.rb @@ -0,0 +1,69 @@ +require 'rubygems' +require 'rake' +require 'set' +require 'fileutils' +require 'ceedling/file_path_utils' + + +class FileSystemUtils + + constructor :file_wrapper + + # build up path list from input of one or more strings or arrays of (+/-) paths & globs + def collect_paths(*paths) + raw = [] # all paths and globs + plus = Set.new # all paths to expand and add + minus = Set.new # all paths to remove from plus set + + # assemble all globs and simple paths, reforming our glob notation to ruby globs + paths.each do |paths_container| + case (paths_container) + when String then raw << (FilePathUtils::reform_glob(paths_container)) + when Array then paths_container.each {|path| raw << (FilePathUtils::reform_glob(path))} + else raise "Don't know how to handle #{paths_container.class}" + end + end + + # iterate through each path and glob + raw.each do |path| + + dirs = [] # container for only (expanded) paths + + # if a glob, expand it and slurp up all non-file paths + if path.include?('*') + # grab base directory only if globs are snug up to final path separator + if (path =~ /\/\*+$/) + dirs << FilePathUtils.extract_path(path) + end + + # grab expanded sub-directory globs + expanded = @file_wrapper.directory_listing( FilePathUtils.extract_path_no_aggregation_operators(path) ) + expanded.each do |entry| + dirs << entry if @file_wrapper.directory?(entry) + end + + # else just grab simple path + # note: we could just run this through glob expansion but such an + # approach doesn't handle a path not yet on disk) + else + dirs << FilePathUtils.extract_path_no_aggregation_operators(path) + end + + # add dirs to the appropriate set based on path aggregation modifier if present + FilePathUtils.add_path?(path) ? plus.merge(dirs) : minus.merge(dirs) + end + + return (plus - minus).to_a.uniq + end + + + # given a file list, add to it or remove from it + def revise_file_list(list, revisions) + revisions.each do |revision| + # include or exclude file or glob to file list + file = FilePathUtils.extract_path_no_aggregation_operators( revision ) + FilePathUtils.add_path?(revision) ? list.include(file) : list.exclude(file) + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_system_wrapper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_system_wrapper.rb new file mode 100644 index 0000000..807cbd2 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_system_wrapper.rb @@ -0,0 +1,10 @@ + +class FileSystemWrapper + + def cd(path) + FileUtils.cd path do + yield + end + end + +end \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_wrapper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_wrapper.rb new file mode 100644 index 0000000..1680ca5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/file_wrapper.rb @@ -0,0 +1,83 @@ +require 'rubygems' +require 'rake' # for FileList +require 'fileutils' +require 'ceedling/constants' + + +class FileWrapper + + def get_expanded_path(path) + return File.expand_path(path) + end + + def basename(path, extension=nil) + return File.basename(path, extension) if extension + return File.basename(path) + end + + def exist?(filepath) + return true if (filepath == NULL_FILE_PATH) + return File.exist?(filepath) + end + + def directory?(path) + return File.directory?(path) + end + + def dirname(path) + return File.dirname(path) + end + + def directory_listing(glob) + return Dir.glob(glob, File::FNM_PATHNAME) + end + + def rm_f(filepath, options={}) + FileUtils.rm_f(filepath, options) + end + + def rm_r(filepath, options={}) + FileUtils.rm_r(filepath, options={}) + end + + def cp(source, destination, options={}) + FileUtils.cp(source, destination, options) + end + + def compare(from, to) + return FileUtils.compare_file(from, to) + end + + def open(filepath, flags) + File.open(filepath, flags) do |file| + yield(file) + end + end + + def read(filepath) + return File.read(filepath) + end + + def touch(filepath, options={}) + FileUtils.touch(filepath, options) + end + + def write(filepath, contents, flags='w') + File.open(filepath, flags) do |file| + file.write(contents) + end + end + + def readlines(filepath) + return File.readlines(filepath) + end + + def instantiate_file_list(files=[]) + return FileList.new(files) + end + + def mkdir(folder) + return FileUtils.mkdir_p(folder) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/flaginator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/flaginator.rb new file mode 100644 index 0000000..31d62c4 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/flaginator.rb @@ -0,0 +1,74 @@ +require 'rubygems' +require 'rake' # for ext() +require 'fileutils' +require 'ceedling/constants' + + +# :flags: +# :release: +# :compile: +# :'test_.+' +# - -pedantic # add '-pedantic' to every test file +# :*: # add '-foo' to compilation of all files not main.c +# - -foo +# :main: # add '-Wall' to compilation of main.c +# - -Wall +# :test: +# :link: +# :test_main: # add '--bar --baz' to linking of test_main.exe +# - --bar +# - --baz + +def partition(hash, &predicate) + hash.partition(&predicate).map(&:to_h) +end + +class Flaginator + + constructor :configurator + + def get_flag(hash, file_name) + file_key = file_name.to_sym + + # 1. try literals + literals, magic = partition(hash) { |k, v| k.to_s =~ /^\w+$/ } + return literals[file_key] if literals.include?(file_key) + + any, regex = partition(magic) { |k, v| (k == :'*') || (k == :'.*') } # glob or regex wild card + + # 2. try regexes + find_res = regex.find { |k, v| file_name =~ /^#{k.to_s}$/ } + return find_res[1] if find_res + + # 3. try anything + find_res = any.find { |k, v| file_name =~ /.*/ } + return find_res[1] if find_res + + # 4. well, we've tried + return [] + end + + def flag_down( operation, context, file ) + # create configurator accessor method + accessor = ('flags_' + context.to_s).to_sym + + # create simple filename key from whatever filename provided + file_name = File.basename( file ).ext('') + file_key = File.basename( file ).ext('').to_sym + + # if no entry in configuration for flags for this context, bail out + return [] if not @configurator.respond_to?( accessor ) + + # get flags sub hash associated with this context + flags = @configurator.send( accessor ) + + # if operation not represented in flags hash, bail out + return [] if not flags.include?( operation ) + + # redefine flags to sub hash associated with the operation + flags = flags[operation] + + return get_flag(flags, file_name) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator.rb new file mode 100644 index 0000000..828a0c0 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator.rb @@ -0,0 +1,183 @@ +require 'ceedling/constants' + +class Generator + + constructor :configurator, + :generator_helper, + :preprocessinator, + :cmock_builder, + :generator_test_runner, + :generator_test_results, + :flaginator, + :test_includes_extractor, + :tool_executor, + :file_finder, + :file_path_utils, + :streaminator, + :plugin_manager, + :file_wrapper + + + def generate_shallow_includes_list(context, file) + @streaminator.stdout_puts("Generating include list for #{File.basename(file)}...", Verbosity::NORMAL) + @preprocessinator.preprocess_shallow_includes(file) + end + + def generate_preprocessed_file(context, file) + @streaminator.stdout_puts("Preprocessing #{File.basename(file)}...", Verbosity::NORMAL) + @preprocessinator.preprocess_file(file) + end + + def generate_dependencies_file(tool, context, source, object, dependencies) + @streaminator.stdout_puts("Generating dependencies for #{File.basename(source)}...", Verbosity::NORMAL) + + command = + @tool_executor.build_command_line( + tool, + [], # extra per-file command line parameters + source, + dependencies, + object) + + @tool_executor.exec( command[:line], command[:options] ) + end + + def generate_mock(context, header_filepath) + arg_hash = {:header_file => header_filepath, :context => context} + @plugin_manager.pre_mock_generate( arg_hash ) + + begin + @cmock_builder.cmock.setup_mocks( arg_hash[:header_file] ) + rescue + raise + ensure + @plugin_manager.post_mock_generate( arg_hash ) + end + end + + # test_filepath may be either preprocessed test file or original test file + def generate_test_runner(context, test_filepath, runner_filepath) + arg_hash = {:context => context, :test_file => test_filepath, :runner_file => runner_filepath} + @plugin_manager.pre_runner_generate(arg_hash) + + # collect info we need + module_name = File.basename(arg_hash[:test_file]) + test_cases = @generator_test_runner.find_test_cases( @file_finder.find_test_from_runner_path(runner_filepath) ) + mock_list = @test_includes_extractor.lookup_raw_mock_list(arg_hash[:test_file]) + + @streaminator.stdout_puts("Generating runner for #{module_name}...", Verbosity::NORMAL) + + test_file_includes = [] # Empty list for now, since apparently unused + + # build runner file + begin + @generator_test_runner.generate(module_name, runner_filepath, test_cases, mock_list, test_file_includes) + rescue + raise + ensure + @plugin_manager.post_runner_generate(arg_hash) + end + end + + def generate_object_file(tool, operation, context, source, object, list='', dependencies='') + shell_result = {} + arg_hash = {:tool => tool, :operation => operation, :context => context, :source => source, :object => object, :list => list, :dependencies => dependencies} + @plugin_manager.pre_compile_execute(arg_hash) + + @streaminator.stdout_puts("Compiling #{File.basename(arg_hash[:source])}...", Verbosity::NORMAL) + command = + @tool_executor.build_command_line( arg_hash[:tool], + @flaginator.flag_down( operation, context, source ), + arg_hash[:source], + arg_hash[:object], + arg_hash[:list], + arg_hash[:dependencies]) + + @streaminator.stdout_puts("Command: #{command}", Verbosity::DEBUG) + + begin + shell_result = @tool_executor.exec( command[:line], command[:options] ) + rescue ShellExecutionException => ex + shell_result = ex.shell_result + raise ex + ensure + arg_hash[:shell_result] = shell_result + @plugin_manager.post_compile_execute(arg_hash) + end + end + + def generate_executable_file(tool, context, objects, executable, map='', libraries=[]) + shell_result = {} + arg_hash = { :tool => tool, + :context => context, + :objects => objects, + :executable => executable, + :map => map, + :libraries => libraries + } + + @plugin_manager.pre_link_execute(arg_hash) + + @streaminator.stdout_puts("Linking #{File.basename(arg_hash[:executable])}...", Verbosity::NORMAL) + command = + @tool_executor.build_command_line( arg_hash[:tool], + @flaginator.flag_down( OPERATION_LINK_SYM, context, executable ), + arg_hash[:objects], + arg_hash[:executable], + arg_hash[:map], + arg_hash[:libraries] + ) + @streaminator.stdout_puts("Command: #{command}", Verbosity::DEBUG) + + begin + shell_result = @tool_executor.exec( command[:line], command[:options] ) + rescue ShellExecutionException => ex + notice = "\n" + + "NOTICE: If the linker reports missing symbols, the following may be to blame:\n" + + " 1. Test lacks #include statements corresponding to needed source files.\n" + + " 2. Project search paths do not contain source files corresponding to #include statements in the test.\n" + + if (@configurator.project_use_mocks) + notice += " 3. Test does not #include needed mocks.\n\n" + else + notice += "\n" + end + + @streaminator.stderr_puts(notice, Verbosity::COMPLAIN) + shell_result = ex.shell_result + raise '' + ensure + arg_hash[:shell_result] = shell_result + @plugin_manager.post_link_execute(arg_hash) + end + end + + def generate_test_results(tool, context, executable, result) + arg_hash = {:tool => tool, :context => context, :executable => executable, :result_file => result} + @plugin_manager.pre_test_fixture_execute(arg_hash) + + @streaminator.stdout_puts("Running #{File.basename(arg_hash[:executable])}...", Verbosity::NORMAL) + + # Unity's exit code is equivalent to the number of failed tests, so we tell @tool_executor not to fail out if there are failures + # so that we can run all tests and collect all results + command = @tool_executor.build_command_line(arg_hash[:tool], [], arg_hash[:executable]) + @streaminator.stdout_puts("Command: #{command}", Verbosity::DEBUG) + command[:options][:boom] = false + shell_result = @tool_executor.exec( command[:line], command[:options] ) + + #Don't Let The Failure Count Make Us Believe Things Aren't Working + shell_result[:exit_code] = 0 + @generator_helper.test_results_error_handler(executable, shell_result) + + processed = @generator_test_results.process_and_write_results( shell_result, + arg_hash[:result_file], + @file_finder.find_test_from_file_path(arg_hash[:executable]) ) + + arg_hash[:result_file] = processed[:result_file] + arg_hash[:results] = processed[:results] + arg_hash[:shell_result] = shell_result # for raw output display if no plugins for formatted display + + @plugin_manager.post_test_fixture_execute(arg_hash) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_helper.rb new file mode 100644 index 0000000..3431560 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_helper.rb @@ -0,0 +1,40 @@ +require 'ceedling/constants' + + +class GeneratorHelper + + constructor :streaminator + + + def test_results_error_handler(executable, shell_result) + notice = '' + error = false + + if (shell_result[:output].nil? or shell_result[:output].strip.empty?) + error = true + # mirror style of generic tool_executor failure output + notice = "\n" + + "ERROR: Test executable \"#{File.basename(executable)}\" failed.\n" + + "> Produced no output to $stdout.\n" + elsif ((shell_result[:output] =~ TEST_STDOUT_STATISTICS_PATTERN).nil?) + error = true + # mirror style of generic tool_executor failure output + notice = "\n" + + "ERROR: Test executable \"#{File.basename(executable)}\" failed.\n" + + "> Produced no final test result counts in $stdout:\n" + + "#{shell_result[:output].strip}\n" + end + + if (error) + # since we told the tool executor to ignore the exit code, handle it explicitly here + notice += "> And exited with status: [#{shell_result[:exit_code]}] (count of failed tests).\n" if (shell_result[:exit_code] != nil) + notice += "> And then likely crashed.\n" if (shell_result[:exit_code] == nil) + + notice += "> This is often a symptom of a bad memory access in source or test code.\n\n" + + @streaminator.stderr_puts(notice, Verbosity::COMPLAIN) + raise + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_results.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_results.rb new file mode 100644 index 0000000..1d0c520 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_results.rb @@ -0,0 +1,89 @@ +require 'rubygems' +require 'rake' # for .ext() +require 'ceedling/constants' + +class GeneratorTestResults + + constructor :configurator, :generator_test_results_sanity_checker, :yaml_wrapper + + def process_and_write_results(unity_shell_result, results_file, test_file) + output_file = results_file + + results = get_results_structure + + results[:source][:path] = File.dirname(test_file) + results[:source][:file] = File.basename(test_file) + results[:time] = unity_shell_result[:time] unless unity_shell_result[:time].nil? + + # process test statistics + if (unity_shell_result[:output] =~ TEST_STDOUT_STATISTICS_PATTERN) + results[:counts][:total] = $1.to_i + results[:counts][:failed] = $2.to_i + results[:counts][:ignored] = $3.to_i + results[:counts][:passed] = (results[:counts][:total] - results[:counts][:failed] - results[:counts][:ignored]) + end + + # remove test statistics lines + output_string = unity_shell_result[:output].sub(TEST_STDOUT_STATISTICS_PATTERN, '') + + output_string.lines do |line| + # process unity output + case line + when /(:IGNORE)/ + elements = extract_line_elements(line, results[:source][:file]) + results[:ignores] << elements[0] + results[:stdout] << elements[1] if (!elements[1].nil?) + when /(:PASS$)/ + elements = extract_line_elements(line, results[:source][:file]) + results[:successes] << elements[0] + results[:stdout] << elements[1] if (!elements[1].nil?) + when /(:FAIL)/ + elements = extract_line_elements(line, results[:source][:file]) + results[:failures] << elements[0] + results[:stdout] << elements[1] if (!elements[1].nil?) + else # collect up all other + results[:stdout] << line.chomp + end + end + + @generator_test_results_sanity_checker.verify(results, unity_shell_result[:exit_code]) + + output_file = results_file.ext(@configurator.extension_testfail) if (results[:counts][:failed] > 0) + + @yaml_wrapper.dump(output_file, results) + + return { :result_file => output_file, :result => results } + end + + private + + def get_results_structure + return { + :source => {:path => '', :file => ''}, + :successes => [], + :failures => [], + :ignores => [], + :counts => {:total => 0, :passed => 0, :failed => 0, :ignored => 0}, + :stdout => [], + :time => 0.0 + } + end + + def extract_line_elements(line, filename) + # handle anything preceding filename in line as extra output to be collected + stdout = nil + stdout_regex = /(.+)#{Regexp.escape(filename)}.+/i + + if (line =~ stdout_regex) + stdout = $1.clone + line.sub!(/#{Regexp.escape(stdout)}/, '') + end + + # collect up test results minus and extra output + elements = (line.strip.split(':'))[1..-1] + + return {:test => elements[1], :line => elements[0].to_i, :message => (elements[3..-1].join(':')).strip}, stdout if elements.size >= 3 + return {:test => '???', :line => -1, :message => nil} #fallback safe option. TODO better handling + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_results_sanity_checker.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_results_sanity_checker.rb new file mode 100644 index 0000000..0b51832 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_results_sanity_checker.rb @@ -0,0 +1,65 @@ +require 'rubygems' +require 'rake' # for ext() method +require 'ceedling/constants' + + +class GeneratorTestResultsSanityChecker + + constructor :configurator, :streaminator + + def verify(results, unity_exit_code) + + # do no sanity checking if it's disabled + return if (@configurator.sanity_checks == TestResultsSanityChecks::NONE) + raise "results nil or empty" if results.nil? || results.empty? + + ceedling_ignores_count = results[:ignores].size + ceedling_failures_count = results[:failures].size + ceedling_tests_summation = (ceedling_ignores_count + ceedling_failures_count + results[:successes].size) + + # Exit code handling is not a sanity check that can always be performed because + # command line simulators may or may not pass through Unity's exit code + if (@configurator.sanity_checks >= TestResultsSanityChecks::THOROUGH) + # many platforms limit exit codes to a maximum of 255 + if ((ceedling_failures_count != unity_exit_code) and (unity_exit_code < 255)) + sanity_check_warning(results[:source][:file], "Unity's exit code (#{unity_exit_code}) does not match Ceedling's summation of failed test cases (#{ceedling_failures_count}).") + end + + if ((ceedling_failures_count < 255) and (unity_exit_code == 255)) + sanity_check_warning(results[:source][:file], "Ceedling's summation of failed test cases (#{ceedling_failures_count}) is less than Unity's exit code (255 or more).") + end + end + + if (ceedling_ignores_count != results[:counts][:ignored]) + sanity_check_warning(results[:source][:file], "Unity's final ignore count (#{results[:counts][:ignored]}) does not match Ceedling's summation of ignored test cases (#{ceedling_ignores_count}).") + end + + if (ceedling_failures_count != results[:counts][:failed]) + sanity_check_warning(results[:source][:file], "Unity's final fail count (#{results[:counts][:failed]}) does not match Ceedling's summation of failed test cases (#{ceedling_failures_count}).") + end + + if (ceedling_tests_summation != results[:counts][:total]) + sanity_check_warning(results[:source][:file], "Unity's final test count (#{results[:counts][:total]}) does not match Ceedling's summation of all test cases (#{ceedling_tests_summation}).") + end + + end + + private + + def sanity_check_warning(file, message) + unless defined?(CEEDLING_IGNORE_SANITY_CHECK) + notice = "\n" + + "ERROR: Internal sanity check for test fixture '#{file.ext(@configurator.extension_executable)}' finds that #{message}\n" + + " Possible causes:\n" + + " 1. Your test + source dereferenced a null pointer.\n" + + " 2. Your test + source indexed past the end of a buffer.\n" + + " 3. Your test + source committed a memory access violation.\n" + + " 4. Your test fixture produced an exit code of 0 despite execution ending prematurely.\n" + + " Sanity check failures of test results are usually a symptom of interrupted test execution.\n\n" + + @streaminator.stderr_puts( notice ) + raise + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_runner.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_runner.rb new file mode 100644 index 0000000..6999faf --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/generator_test_runner.rb @@ -0,0 +1,56 @@ + +class GeneratorTestRunner + + constructor :configurator, :file_path_utils, :file_wrapper + + def find_test_cases(test_file) + + #Pull in Unity's Test Runner Generator + require 'generate_test_runner.rb' + @test_runner_generator ||= UnityTestRunnerGenerator.new( @configurator.get_runner_config ) + + if (@configurator.project_use_test_preprocessor) + + #redirect to use the preprocessor file if we're doing that sort of thing + pre_test_file = @file_path_utils.form_preprocessed_file_filepath(test_file) + + #actually look for the tests using Unity's test runner generator + contents = @file_wrapper.read(pre_test_file) + tests_and_line_numbers = @test_runner_generator.find_tests(contents) + @test_runner_generator.find_setup_and_teardown(contents) + + #look up the line numbers in the original file + source_lines = @file_wrapper.read(test_file).split("\n") + source_index = 0; + tests_and_line_numbers.size.times do |i| + source_lines[source_index..-1].each_with_index do |line, index| + if (line =~ /#{tests_and_line_numbers[i][:test]}/) + source_index += index + tests_and_line_numbers[i][:line_number] = source_index + 1 + break + end + end + end + else + #Just look for the tests using Unity's test runner generator + contents = @file_wrapper.read(test_file) + tests_and_line_numbers = @test_runner_generator.find_tests(contents) + @test_runner_generator.find_setup_and_teardown(contents) + end + + return tests_and_line_numbers + end + + def generate(module_name, runner_filepath, test_cases, mock_list, test_file_includes=[]) + require 'generate_test_runner.rb' + + #actually build the test runner using Unity's test runner generator + #(there is no need to use preprocessor here because we've already looked up test cases and are passing them in here) + @test_runner_generator ||= UnityTestRunnerGenerator.new( @configurator.get_runner_config ) + @test_runner_generator.generate( module_name, + runner_filepath, + test_cases, + mock_list, + test_file_includes) + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/loginator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/loginator.rb new file mode 100644 index 0000000..92276e1 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/loginator.rb @@ -0,0 +1,31 @@ + +class Loginator + + constructor :configurator, :project_file_loader, :project_config_manager, :file_wrapper, :system_wrapper + + + def setup_log_filepath + config_files = [] + config_files << @project_file_loader.main_file + config_files << @project_file_loader.user_file + config_files.concat( @project_config_manager.options_files ) + config_files.compact! + config_files.map! { |file| file.ext('') } + + log_name = config_files.join( '_' ) + + @project_log_filepath = File.join( @configurator.project_log_path, log_name.ext('.log') ) + end + + + def log(string, heading=nil) + return if (not @configurator.project_logging) + + output = "\n[#{@system_wrapper.time_now}]" + output += " :: #{heading}" if (not heading.nil?) + output += "\n#{string.strip}\n" + + @file_wrapper.write(@project_log_filepath, output, 'a') + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/makefile.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/makefile.rb new file mode 100644 index 0000000..c3d7496 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/makefile.rb @@ -0,0 +1,46 @@ + +# modified version of Rake's provided make-style dependency loader +# customizations: +# (1) handles windows drives in paths -- colons don't confuse task demarcation +# (2) handles spaces in directory paths + +module Rake + + # Makefile loader to be used with the import file loader. + class MakefileLoader + + # Load the makefile dependencies in +fn+. + def load(fn) + open(fn) do |mf| + lines = mf.read + lines.gsub!(/#[^\n]*\n/m, "") # remove comments + lines.gsub!(/\\\n/, ' ') # string together line continuations into single line + lines.split("\n").each do |line| + process_line(line) + end + end + end + + private + + # Process one logical line of makefile data. + def process_line(line) + # split on presence of task demaractor followed by space (i.e don't get confused by a colon in a win path) + file_tasks, args = line.split(/:\s/) + + return if args.nil? + + # split at non-escaped space boundary between files (i.e. escaped spaces in paths are left alone) + dependents = args.split(/\b\s+/) + # replace escaped spaces and clean up any extra whitespace + dependents.map! { |path| path.gsub(/\\ /, ' ').strip } + + file_tasks.strip.split.each do |file_task| + file file_task => dependents + end + end + end + + # Install the handler + Rake.application.add_loader('mf', MakefileLoader.new) +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/objects.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/objects.yml new file mode 100644 index 0000000..2e2e9b9 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/objects.yml @@ -0,0 +1,310 @@ + +file_wrapper: + +file_system_wrapper: + +stream_wrapper: + +rake_wrapper: + +yaml_wrapper: + +system_wrapper: + +cmock_builder: + +reportinator: + +rake_utils: + compose: + - rake_wrapper + +system_utils: + compose: + - system_wrapper + +file_path_utils: + compose: + - configurator + - file_wrapper + +file_system_utils: + compose: file_wrapper + +project_file_loader: + compose: + - yaml_wrapper + - stream_wrapper + - system_wrapper + - file_wrapper + +project_config_manager: + compose: + - cacheinator + - configurator + - yaml_wrapper + - file_wrapper + +cacheinator: + compose: + - cacheinator_helper + - file_path_utils + - file_wrapper + - yaml_wrapper + +cacheinator_helper: + compose: + - file_wrapper + - yaml_wrapper + +tool_executor: + compose: + - configurator + - tool_executor_helper + - streaminator + - system_wrapper + +tool_executor_helper: + compose: + - streaminator + - system_utils + - system_wrapper + +configurator: + compose: + - configurator_setup + - configurator_plugins + - configurator_builder + - cmock_builder + - yaml_wrapper + - system_wrapper + +configurator_setup: + compose: + - configurator_builder + - configurator_validator + - configurator_plugins + - stream_wrapper + +configurator_plugins: + compose: + - stream_wrapper + - file_wrapper + - system_wrapper + +configurator_validator: + compose: + - file_wrapper + - stream_wrapper + - system_wrapper + +configurator_builder: + compose: + - file_system_utils + - file_wrapper + - system_wrapper + +loginator: + compose: + - configurator + - project_file_loader + - project_config_manager + - file_wrapper + - system_wrapper + +streaminator: + compose: + - streaminator_helper + - verbosinator + - loginator + - stream_wrapper + +streaminator_helper: + +setupinator: + +plugin_builder: + +plugin_manager: + compose: + - configurator + - plugin_manager_helper + - streaminator + - reportinator + - system_wrapper + +plugin_manager_helper: + +plugin_reportinator: + compose: + - plugin_reportinator_helper + - plugin_manager + - reportinator + +plugin_reportinator_helper: + compose: + - configurator + - streaminator + - yaml_wrapper + - file_wrapper + +verbosinator: + compose: configurator + +file_finder: + compose: + - configurator + - file_finder_helper + - cacheinator + - file_path_utils + - file_wrapper + - yaml_wrapper + +file_finder_helper: + compose: streaminator + +test_includes_extractor: + compose: + - configurator + - yaml_wrapper + - file_wrapper + +task_invoker: + compose: + - dependinator + - rake_utils + - rake_wrapper + - project_config_manager + +flaginator: + compose: + - configurator + +generator: + compose: + - configurator + - generator_helper + - preprocessinator + - cmock_builder + - generator_test_runner + - generator_test_results + - flaginator + - test_includes_extractor + - tool_executor + - file_finder + - file_path_utils + - streaminator + - plugin_manager + - file_wrapper + +generator_helper: + compose: + - streaminator + +generator_test_results: + compose: + - configurator + - generator_test_results_sanity_checker + - yaml_wrapper + +generator_test_results_sanity_checker: + compose: + - configurator + - streaminator + +generator_test_runner: + compose: + - configurator + - file_path_utils + - file_wrapper + +dependinator: + compose: + - configurator + - project_config_manager + - test_includes_extractor + - file_path_utils + - rake_wrapper + - file_wrapper + +preprocessinator: + compose: + - preprocessinator_helper + - preprocessinator_includes_handler + - preprocessinator_file_handler + - task_invoker + - file_path_utils + - yaml_wrapper + +preprocessinator_helper: + compose: + - configurator + - test_includes_extractor + - task_invoker + - file_finder + - file_path_utils + +preprocessinator_includes_handler: + compose: + - configurator + - tool_executor + - task_invoker + - file_path_utils + - yaml_wrapper + - file_wrapper + +preprocessinator_file_handler: + compose: + - preprocessinator_extractor + - configurator + - tool_executor + - file_path_utils + - file_wrapper + +preprocessinator_extractor: + +test_invoker: + compose: + - configurator + - test_invoker_helper + - plugin_manager + - streaminator + - preprocessinator + - task_invoker + - dependinator + - project_config_manager + - build_invoker_utils + - file_path_utils + - file_wrapper + +test_invoker_helper: + compose: + - configurator + - task_invoker + - test_includes_extractor + - file_finder + - file_path_utils + - file_wrapper + +release_invoker: + compose: + - configurator + - release_invoker_helper + - build_invoker_utils + - dependinator + - task_invoker + - file_path_utils + - file_wrapper + +release_invoker_helper: + compose: + - configurator + - dependinator + - task_invoker + +build_invoker_utils: + compose: + - configurator + - streaminator + +erb_wrapper: diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/par_map.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/par_map.rb new file mode 100644 index 0000000..98198a2 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/par_map.rb @@ -0,0 +1,19 @@ + + +def par_map(n, things, &block) + queue = Queue.new + things.each { |thing| queue << thing } + threads = (1..n).collect do + Thread.new do + begin + while true + yield queue.pop(true) + end + rescue ThreadError + + end + end + end + threads.each { |t| t.join } +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin.rb new file mode 100644 index 0000000..f20b3a3 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin.rb @@ -0,0 +1,80 @@ + +class String + # reformat a multiline string to have given number of whitespace columns; + # helpful for formatting heredocs + def left_margin(margin=0) + non_whitespace_column = 0 + new_lines = [] + + # find first line with non-whitespace and count left columns of whitespace + self.each_line do |line| + if (line =~ /^\s*\S/) + non_whitespace_column = $&.length - 1 + break + end + end + + # iterate through each line, chopping off leftmost whitespace columns and add back the desired whitespace margin + self.each_line do |line| + columns = [] + margin.times{columns << ' '} + # handle special case of line being narrower than width to be lopped off + if (non_whitespace_column < line.length) + new_lines << "#{columns.join}#{line[non_whitespace_column..-1]}" + else + new_lines << "\n" + end + end + + return new_lines.join + end +end + +class Plugin + attr_reader :name, :environment + attr_accessor :plugin_objects + + def initialize(system_objects, name) + @environment = [] + @ceedling = system_objects + @name = name + self.setup + end + + def setup; end + + # mock generation + def pre_mock_generate(arg_hash); end + def post_mock_generate(arg_hash); end + + # test runner generation + def pre_runner_generate(arg_hash); end + def post_runner_generate(arg_hash); end + + # compilation (test or source) + def pre_compile_execute(arg_hash); end + def post_compile_execute(arg_hash); end + + # linking (test or source) + def pre_link_execute(arg_hash); end + def post_link_execute(arg_hash); end + + # test fixture execution + def pre_test_fixture_execute(arg_hash); end + def post_test_fixture_execute(arg_hash); end + + # test task + def pre_test(test); end + def post_test(test); end + + # release task + def pre_release; end + def post_release; end + + # whole shebang (any use of Ceedling) + def pre_build; end + def post_build; end + + def summary; end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_builder.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_builder.rb new file mode 100644 index 0000000..1269141 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_builder.rb @@ -0,0 +1,53 @@ +require 'ceedling/plugin' + +class PluginBuilder + + attr_accessor :plugin_objects + + def construct_plugin(plugin_name, object_map_yaml, system_objects) + # @streaminator.stdout_puts("Constructing plugin #{plugin_name}...", Verbosity::OBNOXIOUS) + object_map = {} + @plugin_objects = {} + @system_objects = system_objects + + if object_map_yaml + @object_map = YAML.load(object_map_yaml) + @object_map.each_key do |obj| + construct_object(obj) + end + else + raise "Invalid object map for plugin #{plugin_name}!" + end + + return @plugin_objects + end + + private + + def camelize(underscored_name) + return underscored_name.gsub(/(_|^)([a-z0-9])/) {$2.upcase} + end + + def construct_object(obj) + if @plugin_objects[obj].nil? + if @object_map[obj] && @object_map[obj]['compose'] + @object_map[obj]['compose'].each do |dep| + construct_object(dep) + end + end + build_object(obj) + end + end + + def build_object(new_object) + if @plugin_objects[new_object.to_sym].nil? + # @streaminator.stdout_puts("Building plugin object #{new_object}", Verbosity::OBNOXIOUS) + require new_object + class_name = camelize(new_object) + new_instance = eval("#{class_name}.new(@system_objects, class_name.to_s)") + new_instance.plugin_objects = @plugin_objects + @plugin_objects[new_object.to_sym] = new_instance + end + end + +end \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_manager.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_manager.rb new file mode 100644 index 0000000..0468f2f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_manager.rb @@ -0,0 +1,107 @@ +require 'ceedling/constants' + +class PluginManager + + constructor :configurator, :plugin_manager_helper, :streaminator, :reportinator, :system_wrapper + + def setup + @build_fail_registry = [] + @plugin_objects = [] # so we can preserve order + end + + def load_plugin_scripts(script_plugins, system_objects) + environment = [] + + script_plugins.each do |plugin| + # protect against instantiating object multiple times due to processing config multiple times (option files, etc) + next if (@plugin_manager_helper.include?(@plugin_objects, plugin)) + begin + @system_wrapper.require_file( "#{plugin}.rb" ) + object = @plugin_manager_helper.instantiate_plugin_script( camelize(plugin), system_objects, plugin ) + @plugin_objects << object + environment += object.environment + + # add plugins to hash of all system objects + system_objects[plugin.downcase.to_sym] = object + rescue + puts "Exception raised while trying to load plugin: #{plugin}" + raise + end + end + + yield( { :environment => environment } ) if (environment.size > 0) + end + + def plugins_failed? + return (@build_fail_registry.size > 0) + end + + def print_plugin_failures + if (@build_fail_registry.size > 0) + report = @reportinator.generate_banner('BUILD FAILURE SUMMARY') + + @build_fail_registry.each do |failure| + report += "#{' - ' if (@build_fail_registry.size > 1)}#{failure}\n" + end + + report += "\n" + + @streaminator.stderr_puts(report, Verbosity::ERRORS) + end + end + + def register_build_failure(message) + @build_fail_registry << message if (message and not message.empty?) + end + + #### execute all plugin methods #### + + def pre_mock_generate(arg_hash); execute_plugins(:pre_mock_generate, arg_hash); end + def post_mock_generate(arg_hash); execute_plugins(:post_mock_generate, arg_hash); end + + def pre_runner_generate(arg_hash); execute_plugins(:pre_runner_generate, arg_hash); end + def post_runner_generate(arg_hash); execute_plugins(:post_runner_generate, arg_hash); end + + def pre_compile_execute(arg_hash); execute_plugins(:pre_compile_execute, arg_hash); end + def post_compile_execute(arg_hash); execute_plugins(:post_compile_execute, arg_hash); end + + def pre_link_execute(arg_hash); execute_plugins(:pre_link_execute, arg_hash); end + def post_link_execute(arg_hash); execute_plugins(:post_link_execute, arg_hash); end + + def pre_test_fixture_execute(arg_hash); execute_plugins(:pre_test_fixture_execute, arg_hash); end + def post_test_fixture_execute(arg_hash) + # special arbitration: raw test results are printed or taken over by plugins handling the job + @streaminator.stdout_puts(arg_hash[:shell_result][:output]) if (@configurator.plugins_display_raw_test_results) + execute_plugins(:post_test_fixture_execute, arg_hash) + end + + def pre_test(test); execute_plugins(:pre_test, test); end + def post_test(test); execute_plugins(:post_test, test); end + + def pre_release; execute_plugins(:pre_release); end + def post_release; execute_plugins(:post_release); end + + def pre_build; execute_plugins(:pre_build); end + def post_build; execute_plugins(:post_build); end + def post_error; execute_plugins(:post_error); end + + def summary; execute_plugins(:summary); end + + private #################################### + + def camelize(underscored_name) + return underscored_name.gsub(/(_|^)([a-z0-9])/) {$2.upcase} + end + + def execute_plugins(method, *args) + @plugin_objects.each do |plugin| + begin + plugin.send(method, *args) if plugin.respond_to?(method) + rescue + puts "Exception raised in plugin: #{plugin.name}, in method #{method}" + raise + end + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_manager_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_manager_helper.rb new file mode 100644 index 0000000..b18248a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_manager_helper.rb @@ -0,0 +1,19 @@ + +class PluginManagerHelper + + def include?(plugins, name) + include = false + plugins.each do |plugin| + if (plugin.name == name) + include = true + break + end + end + return include + end + + def instantiate_plugin_script(plugin, system_objects, name) + return eval("#{plugin}.new(system_objects, name)") + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_reportinator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_reportinator.rb new file mode 100644 index 0000000..8d83727 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_reportinator.rb @@ -0,0 +1,76 @@ +require 'ceedling/constants' +require 'ceedling/defaults' + +class PluginReportinator + + constructor :plugin_reportinator_helper, :plugin_manager, :reportinator + + def setup + @test_results_template = nil + end + + + def set_system_objects(system_objects) + @plugin_reportinator_helper.ceedling = system_objects + end + + + def fetch_results(results_path, test, options={:boom => false}) + return @plugin_reportinator_helper.fetch_results( File.join(results_path, test), options ) + end + + + def generate_banner(message) + return @reportinator.generate_banner(message) + end + + + def assemble_test_results(results_list, options={:boom => false}) + aggregated_results = get_results_structure + + results_list.each do |result_path| + results = @plugin_reportinator_helper.fetch_results( result_path, options ) + @plugin_reportinator_helper.process_results(aggregated_results, results) + end + + return aggregated_results + end + + + def register_test_results_template(template) + @test_results_template = template if (@test_results_template.nil?) + end + + + def run_test_results_report(hash, verbosity=Verbosity::NORMAL, &block) + run_report( $stdout, + ((@test_results_template.nil?) ? DEFAULT_TESTS_RESULTS_REPORT_TEMPLATE : @test_results_template), + hash, + verbosity, + &block ) + end + + + def run_report(stream, template, hash=nil, verbosity=Verbosity::NORMAL) + failure = nil + failure = yield() if block_given? + + @plugin_manager.register_build_failure( failure ) + + @plugin_reportinator_helper.run_report( stream, template, hash, verbosity ) + end + + private ############################### + + def get_results_structure + return { + :successes => [], + :failures => [], + :ignores => [], + :stdout => [], + :counts => {:total => 0, :passed => 0, :failed => 0, :ignored => 0, :stdout => 0}, + :time => 0.0 + } + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_reportinator_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_reportinator_helper.rb new file mode 100644 index 0000000..322a530 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/plugin_reportinator_helper.rb @@ -0,0 +1,51 @@ +require 'erb' +require 'rubygems' +require 'rake' # for ext() +require 'ceedling/constants' + +class PluginReportinatorHelper + + attr_writer :ceedling + + constructor :configurator, :streaminator, :yaml_wrapper, :file_wrapper + + def fetch_results(results_path, options) + pass_path = File.join(results_path.ext( @configurator.extension_testpass )) + fail_path = File.join(results_path.ext( @configurator.extension_testfail )) + + if (@file_wrapper.exist?(fail_path)) + return @yaml_wrapper.load(fail_path) + elsif (@file_wrapper.exist?(pass_path)) + return @yaml_wrapper.load(pass_path) + else + if (options[:boom]) + @streaminator.stderr_puts("Could find no test results for '#{File.basename(results_path).ext(@configurator.extension_source)}'", Verbosity::ERRORS) + raise + end + end + + return {} + end + + + def process_results(aggregate_results, results) + return if (results.empty?) + aggregate_results[:successes] << { :source => results[:source].clone, :collection => results[:successes].clone } if (results[:successes].size > 0) + aggregate_results[:failures] << { :source => results[:source].clone, :collection => results[:failures].clone } if (results[:failures].size > 0) + aggregate_results[:ignores] << { :source => results[:source].clone, :collection => results[:ignores].clone } if (results[:ignores].size > 0) + aggregate_results[:stdout] << { :source => results[:source].clone, :collection => results[:stdout].clone } if (results[:stdout].size > 0) + aggregate_results[:counts][:total] += results[:counts][:total] + aggregate_results[:counts][:passed] += results[:counts][:passed] + aggregate_results[:counts][:failed] += results[:counts][:failed] + aggregate_results[:counts][:ignored] += results[:counts][:ignored] + aggregate_results[:counts][:stdout] += results[:stdout].size + aggregate_results[:time] += results[:time] + end + + + def run_report(stream, template, hash, verbosity) + output = ERB.new(template, 0, "%<>") + @streaminator.stream_puts(stream, output.result(binding()), verbosity) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator.rb new file mode 100644 index 0000000..f07750d --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator.rb @@ -0,0 +1,42 @@ + +class Preprocessinator + + attr_reader :preprocess_file_proc + + constructor :preprocessinator_helper, :preprocessinator_includes_handler, :preprocessinator_file_handler, :task_invoker, :file_path_utils, :yaml_wrapper + + + def setup + # fashion ourselves callbacks @preprocessinator_helper can use + @preprocess_includes_proc = Proc.new { |filepath| self.preprocess_shallow_includes(filepath) } + @preprocess_file_proc = Proc.new { |filepath| self.preprocess_file(filepath) } + end + + + def preprocess_test_and_invoke_test_mocks(test) + @preprocessinator_helper.preprocess_includes(test, @preprocess_includes_proc) + + mocks_list = @preprocessinator_helper.assemble_mocks_list(test) + + @preprocessinator_helper.preprocess_mockable_headers(mocks_list, @preprocess_file_proc) + + @task_invoker.invoke_test_mocks(mocks_list) + + @preprocessinator_helper.preprocess_test_file(test, @preprocess_file_proc) + + return mocks_list + end + + def preprocess_shallow_includes(filepath) + includes = @preprocessinator_includes_handler.extract_includes(filepath) + + @preprocessinator_includes_handler.write_shallow_includes_list( + @file_path_utils.form_preprocessed_includes_list_filepath(filepath), includes) + end + + def preprocess_file(filepath) + @preprocessinator_includes_handler.invoke_shallow_includes_list(filepath) + @preprocessinator_file_handler.preprocess_file( filepath, @yaml_wrapper.load(@file_path_utils.form_preprocessed_includes_list_filepath(filepath)) ) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_extractor.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_extractor.rb new file mode 100644 index 0000000..49509a8 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_extractor.rb @@ -0,0 +1,30 @@ +class PreprocessinatorExtractor + def extract_base_file_from_preprocessed_expansion(filepath) + # preprocessing by way of toolchain preprocessor expands macros, eliminates + # comments, strips out #ifdef code, etc. however, it also expands in place + # each #include'd file. so, we must extract only the lines of the file + # that belong to the file originally preprocessed + + # iterate through all lines and alternate between extract and ignore modes + # all lines between a '#'line containing file name of our filepath and the + # next '#'line should be extracted + + base_name = File.basename(filepath) + not_pragma = /^#(?!pragma\b)/ # preprocessor directive that's not a #pragma + pattern = /^#.*(\s|\/|\\|\")#{Regexp.escape(base_name)}/ + found_file = false # have we found the file we care about? + + lines = [] + File.readlines(filepath).each do |line| + if found_file and not line =~ not_pragma + lines << line + else + found_file = false + end + + found_file = true if line =~ pattern + end + + return lines + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_file_handler.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_file_handler.rb new file mode 100644 index 0000000..b6b5efb --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_file_handler.rb @@ -0,0 +1,21 @@ + + +class PreprocessinatorFileHandler + + constructor :preprocessinator_extractor, :configurator, :tool_executor, :file_path_utils, :file_wrapper + + + def preprocess_file(filepath, includes) + preprocessed_filepath = @file_path_utils.form_preprocessed_file_filepath(filepath) + + command = @tool_executor.build_command_line(@configurator.tools_test_file_preprocessor, [], filepath, preprocessed_filepath) + @tool_executor.exec(command[:line], command[:options]) + + contents = @preprocessinator_extractor.extract_base_file_from_preprocessed_expansion(preprocessed_filepath) + + includes.each{|include| contents.unshift("#include \"#{include}\"")} + + @file_wrapper.write(preprocessed_filepath, contents.join("\n")) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_helper.rb new file mode 100644 index 0000000..1419a56 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_helper.rb @@ -0,0 +1,46 @@ + + +class PreprocessinatorHelper + + constructor :configurator, :test_includes_extractor, :task_invoker, :file_finder, :file_path_utils + + + def preprocess_includes(test, preprocess_includes_proc) + if (@configurator.project_use_test_preprocessor) + preprocessed_includes_list = @file_path_utils.form_preprocessed_includes_list_filepath(test) + preprocess_includes_proc.call( @file_finder.find_test_from_file_path(preprocessed_includes_list) ) + @test_includes_extractor.parse_includes_list(preprocessed_includes_list) + else + @test_includes_extractor.parse_test_file(test) + end + end + + def assemble_mocks_list(test) + return @file_path_utils.form_mocks_source_filelist( @test_includes_extractor.lookup_raw_mock_list(test) ) + end + + def preprocess_mockable_headers(mock_list, preprocess_file_proc) + if (@configurator.project_use_test_preprocessor) + preprocess_files_smartly( + @file_path_utils.form_preprocessed_mockable_headers_filelist(mock_list), + preprocess_file_proc ) { |file| @file_finder.find_header_file(file) } + end + end + + def preprocess_test_file(test, preprocess_file_proc) + return if (!@configurator.project_use_test_preprocessor) + + preprocess_file_proc.call(test) + end + + private ############################ + + def preprocess_files_smartly(file_list, preprocess_file_proc) + if (@configurator.project_use_deep_dependencies) + @task_invoker.invoke_test_preprocessed_files(file_list) + else + file_list.each { |file| preprocess_file_proc.call( yield(file) ) } + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_includes_handler.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_includes_handler.rb new file mode 100644 index 0000000..703c84f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/preprocessinator_includes_handler.rb @@ -0,0 +1,181 @@ + + +class PreprocessinatorIncludesHandler + + constructor :configurator, :tool_executor, :task_invoker, :file_path_utils, :yaml_wrapper, :file_wrapper + @@makefile_cache = {} + + # shallow includes: only those headers a source file explicitly includes + + def invoke_shallow_includes_list(filepath) + @task_invoker.invoke_test_shallow_include_lists( [@file_path_utils.form_preprocessed_includes_list_filepath(filepath)] ) + end + + ## + # Ask the preprocessor for a make-style dependency rule of only the headers + # the source file immediately includes. + # + # === Arguments + # +filepath+ _String_:: Path to the test file to process. + # + # === Return + # _String_:: The text of the dependency rule generated by the preprocessor. + def form_shallow_dependencies_rule(filepath) + if @@makefile_cache.has_key?(filepath) + return @@makefile_cache[filepath] + end + # change filename (prefix of '_') to prevent preprocessor from finding + # include files in temp directory containing file it's scanning + temp_filepath = @file_path_utils.form_temp_path(filepath, '_') + + # read the file and replace all include statements with a decorated version + # (decorating the names creates file names that don't exist, thus preventing + # the preprocessor from snaking out and discovering the entire include path + # that winds through the code). The decorated filenames indicate files that + # are included directly by the test file. + contents = @file_wrapper.read(filepath) + + if !contents.valid_encoding? + contents = contents.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8') + end + + contents.gsub!( /^\s*#include\s+[\"<]\s*(\S+)\s*[\">]/, "#include \"\\1\"\n#include \"@@@@\\1\"" ) + contents.gsub!( /^\s*TEST_FILE\(\s*\"\s*(\S+)\s*\"\s*\)/, "#include \"\\1\"\n#include \"@@@@\\1\"") + @file_wrapper.write( temp_filepath, contents ) + + # extract the make-style dependency rule telling the preprocessor to + # ignore the fact that it can't find the included files + command = @tool_executor.build_command_line(@configurator.tools_test_includes_preprocessor, [], temp_filepath) + shell_result = @tool_executor.exec(command[:line], command[:options]) + + @@makefile_cache[filepath] = shell_result[:output] + return shell_result[:output] + end + + ## + # Extract the headers that are directly included by a source file using the + # provided, annotated Make dependency rule. + # + # === Arguments + # +filepath+ _String_:: C source or header file to extract includes for. + # + # === Return + # _Array_ of _String_:: Array of the direct dependencies for the source file. + def extract_includes(filepath) + to_process = [filepath] + ignore_list = [] + list = [] + + include_paths = @configurator.project_config_hash[:collection_paths_include] + include_paths = [] if include_paths.nil? + include_paths.map! {|path| File.expand_path(path)} + + while to_process.length > 0 + target = to_process.shift() + ignore_list << target + # puts "[HELL] Processing: \t\t#{target}" + new_deps, new_to_process = extract_includes_helper(target, include_paths, ignore_list) + list += new_deps + to_process += new_to_process + if (!@configurator.project_config_hash.has_key?(:project_auto_link_deep_dependencies) or + !@configurator.project_config_hash[:project_auto_link_deep_dependencies]) + break + else + list = list.uniq() + to_process = to_process.uniq() + end + end + + return list + end + + def extract_includes_helper(filepath, include_paths, ignore_list) + # Extract the dependencies from the make rule + hdr_ext = @configurator.extension_header + make_rule = self.form_shallow_dependencies_rule(filepath) + dependencies = make_rule.split.find_all {|path| path.end_with?(hdr_ext) }.uniq + dependencies.map! {|hdr| hdr.gsub('\\','/') } + + # Separate the real files form the annotated ones and remove the '@@@@' + annotated_headers, real_headers = dependencies.partition {|hdr| hdr =~ /^@@@@/ } + annotated_headers.map! {|hdr| hdr.gsub('@@@@','') } + # Matching annotated_headers values against real_headers to ensure that + # annotated_headers contain full path entries (as returned by make rule) + annotated_headers.map! {|hdr| real_headers.find {|real_hdr| !real_hdr.match(/(.*\/)?#{Regexp.escape(hdr)}/).nil? } } + annotated_headers = annotated_headers.compact + + # Find which of our annotated headers are "real" dependencies. This is + # intended to weed out dependencies that have been removed due to build + # options defined in the project yaml and/or in the headers themselves. + list = annotated_headers.find_all do |annotated_header| + # find the index of the "real" include that matches the annotated one. + idx = real_headers.find_index do |real_header| + real_header =~ /^(.*\/)?#{Regexp.escape(annotated_header)}$/ + end + # If we found a real include, delete it from the array and return it, + # otherwise return nil. Since nil is falsy this has the effect of making + # find_all return only the annotated headers for which a real include was + # found/deleted + idx ? real_headers.delete_at(idx) : nil + end.compact + + # Extract direct dependencies that were also added + src_ext = @configurator.extension_source + sdependencies = make_rule.split.find_all {|path| path.end_with?(src_ext) }.uniq + sdependencies.map! {|hdr| hdr.gsub('\\','/') } + list += sdependencies + + to_process = [] + + if @configurator.project_config_hash.has_key?(:project_auto_link_deep_dependencies) && @configurator.project_config_hash[:project_auto_link_deep_dependencies] + # Creating list of mocks + mocks = annotated_headers.find_all do |annotated_header| + File.basename(annotated_header) =~ /^#{@configurator.project_config_hash[:cmock_mock_prefix]}.*$/ + end.compact + + # Creating list of headers that should be recursively pre-processed + # Skipping mocks and unity.h + headers_to_deep_link = annotated_headers.select do |annotated_header| + !(mocks.include? annotated_header) and (annotated_header.match(/^(.*\/)?unity\.h$/).nil?) + end + headers_to_deep_link.map! {|hdr| File.expand_path(hdr)} + + mocks.each do |mock| + dirname = File.dirname(mock) + #basename = File.basename(mock).delete_prefix(@configurator.project_config_hash[:cmock_mock_prefix]) + basename = File.basename(mock).sub(@configurator.project_config_hash[:cmock_mock_prefix], '') + if dirname != "." + ignore_list << File.join(dirname, basename) + else + ignore_list << basename + end + end.compact + + # Filtering list of final includes to only include mocks and anything that is NOT in the ignore_list + list = list.select do |item| + mocks.include? item or !(ignore_list.any? { |ignore_item| !item.match(/^(.*\/)?#{Regexp.escape(ignore_item)}$/).nil? }) + end + + headers_to_deep_link.each do |hdr| + if (ignore_list.none? {|ignore_header| hdr.match(/^(.*\/)?#{Regexp.escape(ignore_header)}$/)} and + include_paths.none? {|include_path| hdr =~ /^#{include_path}\.*/}) + if File.exist?(hdr) + to_process << hdr + #source_file = hdr.delete_suffix(hdr_ext) + src_ext + source_file = hdr.chomp(hdr_ext) + src_ext + if source_file != hdr and File.exist?(source_file) + to_process << source_file + end + end + end + end + end + + return list, to_process + + end + + def write_shallow_includes_list(filepath, list) + @yaml_wrapper.dump(filepath, list) + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/project_config_manager.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/project_config_manager.rb new file mode 100644 index 0000000..31f7e3a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/project_config_manager.rb @@ -0,0 +1,46 @@ +require 'ceedling/constants' + + +class ProjectConfigManager + + attr_reader :options_files, :release_config_changed, :test_config_changed, :test_defines_changed + attr_accessor :config_hash + + constructor :cacheinator, :configurator, :yaml_wrapper, :file_wrapper + + + def setup + @options_files = [] + @release_config_changed = false + @test_config_changed = false + @test_defines_changed = false + end + + + def merge_options(config_hash, option_filepath) + @options_files << File.basename( option_filepath ) + config_hash.deep_merge!( @yaml_wrapper.load( option_filepath ) ) + end + + + + def process_release_config_change + # has project configuration changed since last release build + @release_config_changed = @cacheinator.diff_cached_release_config?( @config_hash ) + end + + + def process_test_config_change + # has project configuration changed since last test build + @test_config_changed = @cacheinator.diff_cached_test_config?( @config_hash ) + end + + def process_test_defines_change(files) + # has definitions changed since last test build + @test_defines_changed = @cacheinator.diff_cached_test_defines?( files ) + if @test_defines_changed + # update timestamp for rake task prerequisites + @file_wrapper.touch( @configurator.project_test_force_rebuild_filepath ) + end + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/project_file_loader.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/project_file_loader.rb new file mode 100644 index 0000000..bf5dcd4 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/project_file_loader.rb @@ -0,0 +1,99 @@ +require 'ceedling/constants' + + +class ProjectFileLoader + + attr_reader :main_file, :user_file + + constructor :yaml_wrapper, :stream_wrapper, :system_wrapper, :file_wrapper + + def setup + @main_file = nil + @mixin_files = [] + @user_file = nil + + @main_project_filepath = '' + @mixin_project_filepaths = [] + @user_project_filepath = '' + end + + + def find_project_files + # first go hunting for optional user project file by looking for environment variable and then default location on disk + user_filepath = @system_wrapper.env_get('CEEDLING_USER_PROJECT_FILE') + + if ( not user_filepath.nil? and @file_wrapper.exist?(user_filepath) ) + @user_project_filepath = user_filepath + elsif (@file_wrapper.exist?(DEFAULT_CEEDLING_USER_PROJECT_FILE)) + @user_project_filepath = DEFAULT_CEEDLING_USER_PROJECT_FILE + end + + # next check for mixin project files by looking for environment variable + mixin_filepaths = @system_wrapper.env_get('CEEDLING_MIXIN_PROJECT_FILES') + if ( not mixin_filepaths.nil? ) + mixin_filepaths.split(File::PATH_SEPARATOR).each do |filepath| + if ( @file_wrapper.exist?(filepath) ) + @mixin_project_filepaths.push(filepath) + end + end + end + + # next check for main project file by looking for environment variable and then default location on disk; + # blow up if we don't find this guy -- like, he's so totally important + main_filepath = @system_wrapper.env_get('CEEDLING_MAIN_PROJECT_FILE') + + if ( not main_filepath.nil? and @file_wrapper.exist?(main_filepath) ) + @main_project_filepath = main_filepath + elsif (@file_wrapper.exist?(DEFAULT_CEEDLING_MAIN_PROJECT_FILE)) + @main_project_filepath = DEFAULT_CEEDLING_MAIN_PROJECT_FILE + else + # no verbosity checking since this is lowest level reporting anyhow & + # verbosity checking depends on configurator which in turns needs this class (circular dependency) + @stream_wrapper.stderr_puts('Found no Ceedling project file (*.yml)') + raise + end + + @main_file = File.basename( @main_project_filepath ) + @mixin_project_filepaths.each do |filepath| + @mixin_files.push(File.basename( filepath )) + end + @user_file = File.basename( @user_project_filepath ) if ( not @user_project_filepath.empty? ) + end + + def yaml_merger(y1, y2) + o1 = y1 + y2.each_pair do |k,v| + if o1[k].nil? + o1[k] = v + else + if (o1[k].instance_of? Hash) + o1[k] = yaml_merger(o1[k], v) + elsif (o1[k].instance_of? Array) + o1[k] += v + else + o1[k] = v + end + end + end + return o1 + end + + def load_project_config + config_hash = @yaml_wrapper.load(@main_project_filepath) + + # if there are mixin project files, then use them + @mixin_project_filepaths.each do |filepath| + mixin = @yaml_wrapper.load(filepath) + config_hash = yaml_merger( config_hash, mixin ) + end + + # if there's a user project file, then use it + if ( not @user_project_filepath.empty? ) + user_hash = @yaml_wrapper.load(@user_project_filepath) + config_hash = yaml_merger( config_hash, user_hash ) + end + + return config_hash + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rake_utils.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rake_utils.rb new file mode 100644 index 0000000..3f667c8 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rake_utils.rb @@ -0,0 +1,17 @@ + +class RakeUtils + + constructor :rake_wrapper + + def task_invoked?(task_regex) + task_invoked = false + @rake_wrapper.task_list.each do |task| + if ((task.already_invoked) and (task.to_s =~ task_regex)) + task_invoked = true + break + end + end + return task_invoked + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rake_wrapper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rake_wrapper.rb new file mode 100644 index 0000000..15e4796 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rake_wrapper.rb @@ -0,0 +1,33 @@ +require 'rubygems' +require 'rake' +require 'ceedling/makefile' # our replacement for rake's make-style dependency loader + +include Rake::DSL if defined?(Rake::DSL) + +class Rake::Task + attr_reader :already_invoked +end + +class RakeWrapper + + def initialize + @makefile_loader = Rake::MakefileLoader.new # use our custom replacement noted above + end + + def [](task) + return Rake::Task[task] + end + + def task_list + return Rake::Task.tasks + end + + def create_file_task(file_task, dependencies) + file(file_task => dependencies) + end + + def load_dependencies(dependencies_path) + @makefile_loader.load(dependencies_path) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rakefile.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rakefile.rb new file mode 100644 index 0000000..37001ba --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rakefile.rb @@ -0,0 +1,86 @@ +require 'fileutils' + +# get directory containing this here file, back up one directory, and expand to full path +CEEDLING_ROOT = File.expand_path(File.dirname(__FILE__) + '/../..') +CEEDLING_LIB = File.join(CEEDLING_ROOT, 'lib') +CEEDLING_VENDOR = File.join(CEEDLING_ROOT, 'vendor') +CEEDLING_RELEASE = File.join(CEEDLING_ROOT, 'release') + +$LOAD_PATH.unshift( CEEDLING_LIB ) +$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'unity/auto') ) +$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'diy/lib') ) +$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'cmock/lib') ) +$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'deep_merge/lib') ) + +require 'rake' + +#Let's make sure we remember the task descriptions in case we need them +Rake::TaskManager.record_task_metadata = true + +require 'diy' +require 'constructor' + +require 'ceedling/constants' +require 'ceedling/target_loader' + + +# construct all our objects +# ensure load path contains all libraries needed first +lib_ceedling_load_path_temp = File.join(CEEDLING_LIB, 'ceedling') +$LOAD_PATH.unshift( lib_ceedling_load_path_temp ) +@ceedling = DIY::Context.from_yaml( File.read( File.join(lib_ceedling_load_path_temp, 'objects.yml') ) ) +@ceedling.build_everything +# now that all objects are built, delete 'lib/ceedling' from load path +$LOAD_PATH.delete(lib_ceedling_load_path_temp) +# one-stop shopping for all our setup and such after construction +@ceedling[:setupinator].ceedling = @ceedling + +project_config = + begin + cfg = @ceedling[:setupinator].load_project_files + TargetLoader.inspect(cfg, ENV['TARGET']) + rescue TargetLoader::NoTargets + cfg + rescue TargetLoader::RequestReload + @ceedling[:setupinator].load_project_files + end + +@ceedling[:setupinator].do_setup( project_config ) + + +# tell all our plugins we're about to do something +@ceedling[:plugin_manager].pre_build + +# load rakefile component files (*.rake) +PROJECT_RAKEFILE_COMPONENT_FILES.each { |component| load(component) } + +# tell rake to shut up by default (overridden in verbosity / debug tasks as appropriate) +verbose(false) + + +# end block always executed following rake run +END { + $stdout.flush unless $stdout.nil? + $stderr.flush unless $stderr.nil? + + # cache our input configurations to use in comparison upon next execution + @ceedling[:cacheinator].cache_test_config( @ceedling[:setupinator].config_hash ) if (@ceedling[:task_invoker].test_invoked?) + @ceedling[:cacheinator].cache_release_config( @ceedling[:setupinator].config_hash ) if (@ceedling[:task_invoker].release_invoked?) + + # delete all temp files unless we're in debug mode + if (not @ceedling[:configurator].project_debug) + @ceedling[:file_wrapper].rm_f( @ceedling[:file_wrapper].directory_listing( File.join(@ceedling[:configurator].project_temp_path, '*') )) + end + + # only perform these final steps if we got here without runtime exceptions or errors + if (@ceedling[:system_wrapper].ruby_success) + + # tell all our plugins the build is done and process results + @ceedling[:plugin_manager].post_build + @ceedling[:plugin_manager].print_plugin_failures + exit(1) if (@ceedling[:plugin_manager].plugins_failed? && !@ceedling[:setupinator].config_hash[:graceful_fail]) + else + puts "ERROR: Ceedling Failed" + @ceedling[:plugin_manager].post_error + end +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/release_invoker.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/release_invoker.rb new file mode 100644 index 0000000..5bfb6cd --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/release_invoker.rb @@ -0,0 +1,73 @@ +require 'ceedling/constants' + + +class ReleaseInvoker + + constructor :configurator, :release_invoker_helper, :build_invoker_utils, :dependinator, :task_invoker, :file_path_utils, :file_wrapper + + + def setup_and_invoke_c_objects( c_files ) + objects = @file_path_utils.form_release_build_c_objects_filelist( c_files ) + + begin + @release_invoker_helper.process_deep_dependencies( @file_path_utils.form_release_dependencies_filelist( c_files ) ) + + @dependinator.enhance_release_file_dependencies( objects ) + @task_invoker.invoke_release_objects( objects ) + rescue => e + @build_invoker_utils.process_exception( e, RELEASE_SYM, false ) + end + + return objects + end + + + def setup_and_invoke_asm_objects( asm_files ) + objects = @file_path_utils.form_release_build_asm_objects_filelist( asm_files ) + + begin + @dependinator.enhance_release_file_dependencies( objects ) + @task_invoker.invoke_release_objects( objects ) + rescue => e + @build_invoker_utils.process_exception( e, RELEASE_SYM, false ) + end + + return objects + end + + + def refresh_c_deep_dependencies + return if (not @configurator.project_use_deep_dependencies) + + @file_wrapper.rm_f( + @file_wrapper.directory_listing( + File.join( @configurator.project_release_dependencies_path, '*' + @configurator.extension_dependencies ) ) ) + + @release_invoker_helper.process_deep_dependencies( + @file_path_utils.form_release_dependencies_filelist( + @configurator.collection_all_source ) ) + end + + + def artifactinate( *files ) + files.flatten.each do |file| + @file_wrapper.cp( file, @configurator.project_release_artifacts_path ) if @file_wrapper.exist?( file ) + end + end + + def convert_libraries_to_arguments(libraries) + args = (libraries || []) + ((defined? LIBRARIES_SYSTEM) ? LIBRARIES_SYSTEM : []) + if (defined? LIBRARIES_FLAG) + args.map! {|v| LIBRARIES_FLAG.gsub(/\$\{1\}/, v) } + end + return args + end + + def sort_objects_and_libraries(both) + extension = "\\" + ((defined? EXTENSION_SUBPROJECTS) ? EXTENSION_SUBPROJECTS : ".LIBRARY") + sorted_objects = both.group_by {|v| v.match(/.+#{extension}$/) ? :libraries : :objects } + libraries = sorted_objects[:libraries] || [] + objects = sorted_objects[:objects] || [] + return objects, libraries + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/release_invoker_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/release_invoker_helper.rb new file mode 100644 index 0000000..f83a2a5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/release_invoker_helper.rb @@ -0,0 +1,19 @@ + + +class ReleaseInvokerHelper + + constructor :configurator, :dependinator, :task_invoker + + + def process_deep_dependencies(dependencies_list) + return if (not @configurator.project_use_deep_dependencies) + + if @configurator.project_generate_deep_dependencies + @dependinator.enhance_release_file_dependencies( dependencies_list ) + @task_invoker.invoke_release_dependencies_files( dependencies_list ) + end + + @dependinator.load_release_object_deep_dependencies( dependencies_list ) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/reportinator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/reportinator.rb new file mode 100644 index 0000000..0f583d0 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/reportinator.rb @@ -0,0 +1,26 @@ +## +# Pretifies reports +class Reportinator + + ## + # Generates a banner for a message based on the length of the message or a + # given width. + # ==== Attributes + # + # * _message_: The message to put. + # * _width_: The width of the message. If nil the size of the banner is + # determined by the length of the message. + # + # ==== Examples + # + # rp = Reportinator.new + # rp.generate_banner("Hello world!") => "------------\nHello world!\n------------\n" + # rp.generate_banner("Hello world!", 3) => "---\nHello world!\n---\n" + # + # + def generate_banner(message, width=nil) + dash_count = ((width.nil?) ? message.strip.length : width) + return "#{'-' * dash_count}\n#{message}\n#{'-' * dash_count}\n" + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_cmock.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_cmock.rake new file mode 100644 index 0000000..70ddcbc --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_cmock.rake @@ -0,0 +1,9 @@ + + +rule(/#{CMOCK_MOCK_PREFIX}[^\/\\]+#{'\\'+EXTENSION_SOURCE}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_header_input_for_mock_file(task_name) + end + ]) do |mock| + @ceedling[:generator].generate_mock(TEST_SYM, mock.source) +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_preprocess.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_preprocess.rake new file mode 100644 index 0000000..c291112 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_preprocess.rake @@ -0,0 +1,26 @@ + + +# invocations against this rule should only happen when enhanced dependencies are enabled; +# otherwise, dependency tracking will be too shallow and preprocessed files could intermittently +# fail to be updated when they actually need to be. +rule(/#{PROJECT_TEST_PREPROCESS_FILES_PATH}\/.+/ => [ + proc do |task_name| + @ceedling[:file_finder].find_test_or_source_or_header_file(task_name) + end + ]) do |file| + if (not @ceedling[:configurator].project_use_deep_dependencies) + raise 'ERROR: Ceedling preprocessing rule invoked though neccessary auxiliary dependency support not enabled.' + end + @ceedling[:generator].generate_preprocessed_file(TEST_SYM, file.source) +end + + +# invocations against this rule can always happen as there are no deeper dependencies to consider +rule(/#{PROJECT_TEST_PREPROCESS_INCLUDES_PATH}\/.+/ => [ + proc do |task_name| + @ceedling[:file_finder].find_test_or_source_or_header_file(task_name) + end + ]) do |file| + @ceedling[:generator].generate_shallow_includes_list(TEST_SYM, file.source) +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_release.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_release.rake new file mode 100644 index 0000000..ae39a76 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_release.rake @@ -0,0 +1,86 @@ + +RELEASE_COMPILE_TASK_ROOT = RELEASE_TASK_ROOT + 'compile:' unless defined?(RELEASE_COMPILE_TASK_ROOT) +RELEASE_ASSEMBLE_TASK_ROOT = RELEASE_TASK_ROOT + 'assemble:' unless defined?(RELEASE_ASSEMBLE_TASK_ROOT) + + +if (RELEASE_BUILD_USE_ASSEMBLY) +rule(/#{PROJECT_RELEASE_BUILD_OUTPUT_ASM_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_assembly_file(task_name) + end + ]) do |object| + @ceedling[:generator].generate_object_file( + TOOLS_RELEASE_ASSEMBLER, + OPERATION_ASSEMBLE_SYM, + RELEASE_SYM, + object.source, + object.name ) +end +end + + +rule(/#{PROJECT_RELEASE_BUILD_OUTPUT_C_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_compilation_input_file(task_name, :error, true) + end + ]) do |object| + @ceedling[:generator].generate_object_file( + TOOLS_RELEASE_COMPILER, + OPERATION_COMPILE_SYM, + RELEASE_SYM, + object.source, + object.name, + @ceedling[:file_path_utils].form_release_build_c_list_filepath( object.name ), + @ceedling[:file_path_utils].form_release_dependencies_filepath( object.name ) ) +end + + +rule(/#{PROJECT_RELEASE_BUILD_TARGET}/) do |bin_file| + objects, libraries = @ceedling[:release_invoker].sort_objects_and_libraries(bin_file.prerequisites) + tool = TOOLS_RELEASE_LINKER.clone + lib_args = @ceedling[:release_invoker].convert_libraries_to_arguments(libraries) + map_file = @ceedling[:configurator].project_release_build_map + @ceedling[:generator].generate_executable_file( + tool, + RELEASE_SYM, + objects, + bin_file.name, + map_file, + lib_args ) + @ceedling[:release_invoker].artifactinate( bin_file.name, map_file, @ceedling[:configurator].release_build_artifacts ) +end + + +namespace RELEASE_SYM do + # use rules to increase efficiency for large projects (instead of iterating through all sources and creating defined tasks) + + namespace :compile do + rule(/^#{RELEASE_COMPILE_TASK_ROOT}\S+#{'\\'+EXTENSION_SOURCE}$/ => [ # compile task names by regex + proc do |task_name| + source = task_name.sub(/#{RELEASE_COMPILE_TASK_ROOT}/, '') + @ceedling[:file_finder].find_source_file(source, :error) + end + ]) do |compile| + @ceedling[:rake_wrapper][:directories].invoke + @ceedling[:project_config_manager].process_release_config_change + @ceedling[:release_invoker].setup_and_invoke_c_objects( [compile.source] ) + end + end + + if (RELEASE_BUILD_USE_ASSEMBLY) + namespace :assemble do + rule(/^#{RELEASE_ASSEMBLE_TASK_ROOT}\S+#{'\\'+EXTENSION_ASSEMBLY}$/ => [ # assemble task names by regex + proc do |task_name| + source = task_name.sub(/#{RELEASE_ASSEMBLE_TASK_ROOT}/, '') + @ceedling[:file_finder].find_assembly_file(source) + end + ]) do |assemble| + @ceedling[:rake_wrapper][:directories].invoke + @ceedling[:project_config_manager].process_release_config_change + @ceedling[:release_invoker].setup_and_invoke_asm_objects( [assemble.source] ) + end + end + end + +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_release_deep_dependencies.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_release_deep_dependencies.rake new file mode 100644 index 0000000..9550783 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_release_deep_dependencies.rake @@ -0,0 +1,15 @@ + + +rule(/#{PROJECT_RELEASE_DEPENDENCIES_PATH}\/#{'.+\\'+EXTENSION_DEPENDENCIES}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_compilation_input_file(task_name, :error, true) + end + ]) do |dep| + @ceedling[:generator].generate_dependencies_file( + TOOLS_RELEASE_DEPENDENCIES_GENERATOR, + RELEASE_SYM, + dep.source, + @ceedling[:file_path_utils].form_release_build_c_object_filepath(dep.source), + dep.name) +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_tests.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_tests.rake new file mode 100644 index 0000000..2b8f7af --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_tests.rake @@ -0,0 +1,74 @@ + + +rule(/#{PROJECT_TEST_FILE_PREFIX}#{'.+'+TEST_RUNNER_FILE_SUFFIX}#{'\\'+EXTENSION_SOURCE}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_test_input_for_runner_file(task_name) + end + ]) do |runner| + @ceedling[:generator].generate_test_runner(TEST_SYM, runner.source, runner.name) +end + +rule(/#{PROJECT_TEST_BUILD_OUTPUT_C_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_compilation_input_file(task_name) + end + ]) do |object| + if (File.basename(object.source) =~ /#{EXTENSION_SOURCE}$/) + @ceedling[:generator].generate_object_file( + TOOLS_TEST_COMPILER, + OPERATION_COMPILE_SYM, + TEST_SYM, + object.source, + object.name, + @ceedling[:file_path_utils].form_test_build_list_filepath( object.name ), + @ceedling[:file_path_utils].form_test_dependencies_filepath( object.name )) + elsif (defined?(TEST_BUILD_USE_ASSEMBLY) && TEST_BUILD_USE_ASSEMBLY) + @ceedling[:generator].generate_object_file( + TOOLS_TEST_ASSEMBLER, + OPERATION_ASSEMBLE_SYM, + TEST_SYM, + object.source, + object.name ) + end +end + + +rule(/#{PROJECT_TEST_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_EXECUTABLE}$/) do |bin_file| + + lib_args = @ceedling[:test_invoker].convert_libraries_to_arguments() + + @ceedling[:generator].generate_executable_file( + TOOLS_TEST_LINKER, + TEST_SYM, + bin_file.prerequisites, + bin_file.name, + @ceedling[:file_path_utils].form_test_build_map_filepath( bin_file.name ), + lib_args ) +end + + +rule(/#{PROJECT_TEST_RESULTS_PATH}\/#{'.+\\'+EXTENSION_TESTPASS}$/ => [ + proc do |task_name| + @ceedling[:file_path_utils].form_test_executable_filepath(task_name) + end + ]) do |test_result| + @ceedling[:generator].generate_test_results(TOOLS_TEST_FIXTURE, TEST_SYM, test_result.source, test_result.name) +end + + +namespace TEST_SYM do + # use rules to increase efficiency for large projects (instead of iterating through all sources and creating defined tasks) + + rule(/^#{TEST_TASK_ROOT}\S+$/ => [ # test task names by regex + proc do |task_name| + test = task_name.sub(/#{TEST_TASK_ROOT}/, '') + test = "#{PROJECT_TEST_FILE_PREFIX}#{test}" if not (test.start_with?(PROJECT_TEST_FILE_PREFIX)) + @ceedling[:file_finder].find_test_from_file_path(test) + end + ]) do |test| + @ceedling[:rake_wrapper][:directories].reenable if @ceedling[:task_invoker].first_run == false && @ceedling[:project_config_manager].test_defines_changed + @ceedling[:rake_wrapper][:directories].invoke + @ceedling[:test_invoker].setup_and_invoke([test.source]) + end +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_tests_deep_dependencies.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_tests_deep_dependencies.rake new file mode 100644 index 0000000..7175ee3 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/rules_tests_deep_dependencies.rake @@ -0,0 +1,15 @@ + + +rule(/#{PROJECT_TEST_DEPENDENCIES_PATH}\/#{'.+\\'+EXTENSION_DEPENDENCIES}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_compilation_input_file(task_name) + end + ]) do |dep| + @ceedling[:generator].generate_dependencies_file( + TOOLS_TEST_DEPENDENCIES_GENERATOR, + TEST_SYM, + dep.source, + @ceedling[:file_path_utils].form_test_build_c_object_filepath(dep.source), + dep.name) +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/setupinator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/setupinator.rb new file mode 100644 index 0000000..8347b42 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/setupinator.rb @@ -0,0 +1,53 @@ + +class Setupinator + + attr_reader :config_hash + attr_writer :ceedling + + def setup + @ceedling = {} + @config_hash = {} + end + + def load_project_files + @ceedling[:project_file_loader].find_project_files + return @ceedling[:project_file_loader].load_project_config + end + + def do_setup(config_hash) + @config_hash = config_hash + + # load up all the constants and accessors our rake files, objects, & external scripts will need; + # note: configurator modifies the cmock section of the hash with a couple defaults to tie + # project together - the modified hash is used to build cmock object + @ceedling[:configurator].populate_defaults( config_hash ) + @ceedling[:configurator].populate_unity_defaults( config_hash ) + @ceedling[:configurator].populate_cmock_defaults( config_hash ) + @ceedling[:configurator].find_and_merge_plugins( config_hash ) + @ceedling[:configurator].merge_imports( config_hash ) + @ceedling[:configurator].tools_setup( config_hash ) + @ceedling[:configurator].eval_environment_variables( config_hash ) + @ceedling[:configurator].eval_paths( config_hash ) + @ceedling[:configurator].standardize_paths( config_hash ) + @ceedling[:configurator].validate( config_hash ) + @ceedling[:configurator].build( config_hash, :environment ) + + @ceedling[:configurator].insert_rake_plugins( @ceedling[:configurator].rake_plugins ) + @ceedling[:configurator].tools_supplement_arguments( config_hash ) + + # merge in any environment variables plugins specify, after the main build + @ceedling[:plugin_manager].load_plugin_scripts( @ceedling[:configurator].script_plugins, @ceedling ) do |env| + @ceedling[:configurator].eval_environment_variables( env ) + @ceedling[:configurator].build_supplement( config_hash, env ) + end + + @ceedling[:plugin_reportinator].set_system_objects( @ceedling ) + @ceedling[:file_finder].prepare_search_sources + @ceedling[:loginator].setup_log_filepath + @ceedling[:project_config_manager].config_hash = config_hash + end + + def reset_defaults(config_hash) + @ceedling[:configurator].reset_defaults( config_hash ) + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/stream_wrapper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/stream_wrapper.rb new file mode 100644 index 0000000..7e16052 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/stream_wrapper.rb @@ -0,0 +1,28 @@ + +class StreamWrapper + + def stdout_override(&fnc) + @stdout_overide_fnc = fnc + end + + def stdout_puts(string) + if @stdout_overide_fnc + @stdout_overide_fnc.call(string) + else + $stdout.puts(string) + end + end + + def stdout_flush + $stdout.flush + end + + def stderr_puts(string) + $stderr.puts(string) + end + + def stderr_flush + $stderr.flush + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/streaminator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/streaminator.rb new file mode 100644 index 0000000..b8dcd07 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/streaminator.rb @@ -0,0 +1,40 @@ +require 'ceedling/constants' + +class Streaminator + + constructor :streaminator_helper, :verbosinator, :loginator, :stream_wrapper + + # for those objects for whom the configurator has already been instantiated, + # Streaminator is a convenience object for handling verbosity and writing to the std streams + + def stdout_puts(string, verbosity=Verbosity::NORMAL) + if (@verbosinator.should_output?(verbosity)) + @stream_wrapper.stdout_puts(string) + @stream_wrapper.stdout_flush + end + + # write to log as though Verbosity::OBNOXIOUS + @loginator.log( string, @streaminator_helper.extract_name($stdout) ) + end + + def stderr_puts(string, verbosity=Verbosity::NORMAL) + if (@verbosinator.should_output?(verbosity)) + @stream_wrapper.stderr_puts(string) + @stream_wrapper.stderr_flush + end + + # write to log as though Verbosity::OBNOXIOUS + @loginator.log( string, @streaminator_helper.extract_name($stderr) ) + end + + def stream_puts(stream, string, verbosity=Verbosity::NORMAL) + if (@verbosinator.should_output?(verbosity)) + stream.puts(string) + stream.flush + end + + # write to log as though Verbosity::OBNOXIOUS + @loginator.log( string, @streaminator_helper.extract_name(stream) ) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/streaminator_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/streaminator_helper.rb new file mode 100644 index 0000000..9fb5cc0 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/streaminator_helper.rb @@ -0,0 +1,15 @@ + +class StreaminatorHelper + + def extract_name(stream) + name = case (stream.fileno) + when 0 then '#' + when 1 then '#' + when 2 then '#' + else stream.inspect + end + + return name + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/system_utils.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/system_utils.rb new file mode 100644 index 0000000..477aba4 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/system_utils.rb @@ -0,0 +1,37 @@ + +class Object + def deep_clone + Marshal::load(Marshal.dump(self)) + end +end + + +## +# Class containing system utility funcions. +class SystemUtils + + constructor :system_wrapper + + ## + # Sets up the class. + def setup + @tcsh_shell = nil + end + + ## + # Checks the system shell to see if it a tcsh shell. + def tcsh_shell? + # once run a single time, return state determined at that execution + return @tcsh_shell if not @tcsh_shell.nil? + + result = @system_wrapper.shell_backticks('echo $version') + + if ((result[:exit_code] == 0) and (result[:output].strip =~ /^tcsh/)) + @tcsh_shell = true + else + @tcsh_shell = false + end + + return @tcsh_shell + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/system_wrapper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/system_wrapper.rb new file mode 100644 index 0000000..2b0f1ed --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/system_wrapper.rb @@ -0,0 +1,80 @@ +require 'rbconfig' + +class SystemWrapper + + # static method for use in defaults + def self.windows? + return ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) if defined?(RbConfig) + return ((Config::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) + end + + # class method so as to be mockable for tests + def windows? + return SystemWrapper.windows? + end + + def module_eval(string) + return Object.module_eval("\"" + string + "\"") + end + + def eval(string) + return eval(string) + end + + def search_paths + return ENV['PATH'].split(File::PATH_SEPARATOR) + end + + def cmdline_args + return ARGV + end + + def env_set(name, value) + ENV[name] = value + end + + def env_get(name) + return ENV[name] + end + + def time_now + return Time.now.asctime + end + + def shell_backticks(command, boom = true) + retval = `#{command}`.freeze + $exit_code = ($?.exitstatus).freeze if boom + return { + :output => retval.freeze, + :exit_code => ($?.exitstatus).freeze + } + end + + def shell_system(command, boom = true) + system( command ) + $exit_code = ($?.exitstatus).freeze if boom + return { + :output => "".freeze, + :exit_code => ($?.exitstatus).freeze + } + end + + def add_load_path(path) + $LOAD_PATH.unshift(path) + end + + def require_file(path) + require(path) + end + + def ruby_success + # We are successful if we've never had an exit code that went boom (either because it's empty or it was 0) + return ($exit_code.nil? || ($exit_code == 0)) && ($!.nil? || $!.is_a?(SystemExit) && $!.success?) + end + + def constants_include?(item) + # forcing to strings provides consistency across Ruby versions + return Object.constants.map{|constant| constant.to_s}.include?(item.to_s) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/target_loader.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/target_loader.rb new file mode 100644 index 0000000..7fbc095 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/target_loader.rb @@ -0,0 +1,38 @@ +module TargetLoader + class NoTargets < Exception; end + class NoDirectory < Exception; end + class NoDefault < Exception; end + class NoSuchTarget < Exception; end + + class RequestReload < Exception; end + + def self.inspect(config, target_name=nil) + unless config[:targets] + raise NoTargets + end + + targets = config[:targets] + unless targets[:targets_directory] + raise NoDirectory.new("No targets directory specified.") + end + unless targets[:default_target] + raise NoDefault.new("No default target specified.") + end + + target_path = lambda {|name| File.join(targets[:targets_directory], name + ".yml")} + + target = if target_name + target_path.call(target_name) + else + target_path.call(targets[:default_target]) + end + + unless File.exists? target + raise NoSuchTarget.new("No such target: #{target}") + end + + ENV['CEEDLING_MAIN_PROJECT_FILE'] = target + + raise RequestReload + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/task_invoker.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/task_invoker.rb new file mode 100644 index 0000000..642695c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/task_invoker.rb @@ -0,0 +1,117 @@ +require 'ceedling/par_map' + +class TaskInvoker + + attr_accessor :first_run + + constructor :dependinator, :rake_utils, :rake_wrapper, :project_config_manager + + def setup + @test_regexs = [/^#{TEST_ROOT_NAME}:/] + @release_regexs = [/^#{RELEASE_ROOT_NAME}(:|$)/] + @first_run = true + end + + def add_test_task_regex(regex) + @test_regexs << regex + end + + def add_release_task_regex(regex) + @release_regexs << regex + end + + def test_invoked? + invoked = false + + @test_regexs.each do |regex| + invoked = true if (@rake_utils.task_invoked?(regex)) + break if invoked + end + + return invoked + end + + def release_invoked? + invoked = false + + @release_regexs.each do |regex| + invoked = true if (@rake_utils.task_invoked?(regex)) + break if invoked + end + + return invoked + end + + def invoked?(regex) + return @rake_utils.task_invoked?(regex) + end + + + def invoke_test_mocks(mocks) + @dependinator.enhance_mock_dependencies( mocks ) + mocks.each { |mock| + @rake_wrapper[mock].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[mock].invoke + } + end + + def invoke_test_runner(runner) + @dependinator.enhance_runner_dependencies( runner ) + @rake_wrapper[runner].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[runner].invoke + end + + def invoke_test_shallow_include_lists(files) + @dependinator.enhance_shallow_include_lists_dependencies( files ) + par_map(PROJECT_COMPILE_THREADS, files) do |file| + @rake_wrapper[file].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[file].invoke + end + end + + def invoke_test_preprocessed_files(files) + @dependinator.enhance_preprocesed_file_dependencies( files ) + par_map(PROJECT_COMPILE_THREADS, files) do |file| + @rake_wrapper[file].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[file].invoke + end + end + + def invoke_test_dependencies_files(files) + @dependinator.enhance_dependencies_dependencies( files ) + par_map(PROJECT_COMPILE_THREADS, files) do |file| + @rake_wrapper[file].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[file].invoke + end + end + + def invoke_test_objects(objects) + par_map(PROJECT_COMPILE_THREADS, objects) do |object| + @rake_wrapper[object].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[object].invoke + end + end + + def invoke_test_executable(file) + @rake_wrapper[file].invoke + end + + def invoke_test_results(result) + @dependinator.enhance_results_dependencies( result ) + @rake_wrapper[result].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[result].invoke + end + + def invoke_release_dependencies_files(files) + par_map(PROJECT_COMPILE_THREADS, files) do |file| + @rake_wrapper[file].invoke + end + end + + def invoke_release_objects(objects) + par_map(PROJECT_COMPILE_THREADS, objects) do |object| + @rake_wrapper[object].invoke + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_base.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_base.rake new file mode 100644 index 0000000..8c82530 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_base.rake @@ -0,0 +1,111 @@ +require 'ceedling/constants' +require 'ceedling/file_path_utils' +require 'ceedling/version' + +desc "Display build environment version info." +task :version do + puts " Ceedling:: #{Ceedling::Version::CEEDLING}" + + [ + ['CException', File.join( CEEDLING_VENDOR, CEXCEPTION_ROOT_PATH)], + [' CMock', File.join( CEEDLING_VENDOR, CMOCK_ROOT_PATH)], + [' Unity', File.join( CEEDLING_VENDOR, UNITY_ROOT_PATH)], + ].each do |tool| + name = tool[0] + base_path = tool[1] + + version_string = begin + @ceedling[:file_wrapper].read( File.join(base_path, 'release', 'version.info') ).strip + rescue + "UNKNOWN" + end + build_string = begin + @ceedling[:file_wrapper].read( File.join(base_path, 'release', 'build.info') ).strip + rescue + "UNKNOWN" + end + puts "#{name}:: #{version_string.empty? ? '#.#.' : (version_string + '.')}#{build_string.empty? ? '?' : build_string}" + end +end + +desc "Set verbose output (silent:[#{Verbosity::SILENT}] - obnoxious:[#{Verbosity::OBNOXIOUS}])." +task :verbosity, :level do |t, args| + verbosity_level = args.level.to_i + + if (PROJECT_USE_MOCKS) + # don't store verbosity level in setupinator's config hash, use a copy; + # otherwise, the input configuration will change and trigger entire project rebuilds + hash = @ceedling[:setupinator].config_hash[:cmock].clone + hash[:verbosity] = verbosity_level + + @ceedling[:cmock_builder].manufacture( hash ) + end + + @ceedling[:configurator].project_verbosity = verbosity_level + + # control rake's verbosity with new setting + verbose( ((verbosity_level >= Verbosity::OBNOXIOUS) ? true : false) ) +end + +desc "Enable logging" +task :logging do + @ceedling[:configurator].project_logging = true +end + +# non advertised debug task +task :debug do + Rake::Task[:verbosity].invoke(Verbosity::DEBUG) + Rake.application.options.trace = true + @ceedling[:configurator].project_debug = true +end + +# non advertised sanity checking task +task :sanity_checks, :level do |t, args| + check_level = args.level.to_i + @ceedling[:configurator].sanity_checks = check_level +end + +# list expanded environment variables +if (not ENVIRONMENT.empty?) +desc "List all configured environment variables." +task :environment do + env_list = [] + ENVIRONMENT.each do |env| + env.each_key do |key| + name = key.to_s.upcase + env_list.push(" - #{name}: \"#{env[key]}\"") + end + end + env_list.sort.each do |env_line| + puts env_line + end +end +end + +namespace :options do + + COLLECTION_PROJECT_OPTIONS.each do |option_path| + option = File.basename(option_path, '.yml') + + desc "Merge #{option} project options." + task option.downcase.to_sym do + hash = @ceedling[:project_config_manager].merge_options( @ceedling[:setupinator].config_hash, option_path ) + @ceedling[:setupinator].do_setup( hash ) + if @ceedling[:configurator].project_release_build + load(File.join(CEEDLING_LIB, 'ceedling', 'rules_release.rake')) + end + end + end + +end + + +# do not present task if there's no plugins +if (not PLUGINS_ENABLED.empty?) +desc "Execute plugin result summaries (no build triggering)." +task :summary do + @ceedling[:plugin_manager].summary + puts "\nNOTE: Summaries may be out of date with project sources.\n\n" +end +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_filesystem.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_filesystem.rake new file mode 100644 index 0000000..58fa651 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_filesystem.rake @@ -0,0 +1,103 @@ + +# rather than require 'rake/clean' & try to override, we replicate for finer control +CLEAN = Rake::FileList["**/*~", "**/*.bak"] +CLOBBER = Rake::FileList.new + +CLEAN.clear_exclude.exclude { |fn| fn.pathmap("%f") == 'core' && File.directory?(fn) } + +CLEAN.include(File.join(PROJECT_TEST_BUILD_OUTPUT_PATH, '*')) +CLEAN.include(File.join(PROJECT_TEST_RESULTS_PATH, '*')) +CLEAN.include(File.join(PROJECT_TEST_DEPENDENCIES_PATH, '*')) +CLEAN.include(File.join(PROJECT_BUILD_RELEASE_ROOT, '*.*')) +CLEAN.include(File.join(PROJECT_RELEASE_BUILD_OUTPUT_PATH, '*')) +CLEAN.include(File.join(PROJECT_RELEASE_DEPENDENCIES_PATH, '*')) + +CLOBBER.include(File.join(PROJECT_BUILD_ARTIFACTS_ROOT, '**/*')) +CLOBBER.include(File.join(PROJECT_BUILD_TESTS_ROOT, '**/*')) +CLOBBER.include(File.join(PROJECT_BUILD_RELEASE_ROOT, '**/*')) +CLOBBER.include(File.join(PROJECT_LOG_PATH, '**/*')) +CLOBBER.include(File.join(PROJECT_TEMP_PATH, '**/*')) + +# just in case they're using git, let's make sure we allow them to preserved the build directory if desired. +CLOBBER.exclude(File.join(TESTS_BASE_PATH), '**/.gitkeep') + +# because of cmock config, mock path can optionally exist apart from standard test build paths +CLOBBER.include(File.join(CMOCK_MOCK_PATH, '*')) + +REMOVE_FILE_PROC = Proc.new { |fn| rm_r fn rescue nil } + +# redefine clean so we can override how it advertises itself +desc "Delete all build artifacts and temporary products." +task(:clean) do + # because :clean is a prerequisite for :clobber, intelligently display the progress message + if (not @ceedling[:task_invoker].invoked?(/^clobber$/)) + @ceedling[:streaminator].stdout_puts("\nCleaning build artifacts...\n(For large projects, this task may take a long time to complete)\n\n") + end + begin + CLEAN.each { |fn| REMOVE_FILE_PROC.call(fn) } + rescue + end +end + +# redefine clobber so we can override how it advertises itself +desc "Delete all generated files (and build artifacts)." +task(:clobber => [:clean]) do + @ceedling[:streaminator].stdout_puts("\nClobbering all generated files...\n(For large projects, this task may take a long time to complete)\n\n") + begin + CLOBBER.each { |fn| REMOVE_FILE_PROC.call(fn) } + rescue + end +end + + +PROJECT_BUILD_PATHS.each { |path| directory(path) } + +# create directories that hold build output and generated files & touching rebuild dependency sources +task(:directories => PROJECT_BUILD_PATHS) { @ceedling[:dependinator].touch_force_rebuild_files } + + +# list paths discovered at load time +namespace :paths do + + paths = @ceedling[:setupinator].config_hash[:paths] + paths.each_key do |section| + name = section.to_s.downcase + path_list = Object.const_get("COLLECTION_PATHS_#{name.upcase}") + + if (path_list.size != 0) + desc "List all collected #{name} paths." + task(name.to_sym) { puts "#{name} paths:"; path_list.sort.each {|path| puts " - #{path}" } } + end + end + +end + + +# list files & file counts discovered at load time +namespace :files do + + categories = [ + ['test', COLLECTION_ALL_TESTS], + ['source', COLLECTION_ALL_SOURCE], + ['header', COLLECTION_ALL_HEADERS] + ] + + using_assembly = (defined?(TEST_BUILD_USE_ASSEMBLY) && TEST_BUILD_USE_ASSEMBLY) || + (defined?(RELEASE_BUILD_USE_ASSEMBLY) && RELEASE_BUILD_USE_ASSEMBLY) + categories << ['assembly', COLLECTION_ALL_ASSEMBLY] if using_assembly + + categories.each do |category| + name = category[0] + collection = category[1] + + desc "List all collected #{name} files." + task(name.to_sym) do + puts "#{name} files:" + collection.sort.each { |filepath| puts " - #{filepath}" } + puts "file count: #{collection.size}" + end + end + +end + + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_release.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_release.rake new file mode 100644 index 0000000..b313b2f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_release.rake @@ -0,0 +1,30 @@ +require 'ceedling/constants' +require 'ceedling/file_path_utils' + + +desc "Build release target." +task RELEASE_SYM => [:directories] do + header = "Release build '#{File.basename(PROJECT_RELEASE_BUILD_TARGET)}'" + @ceedling[:streaminator].stdout_puts("\n\n#{header}\n#{'-' * header.length}") + + begin + @ceedling[:plugin_manager].pre_release + + core_objects = [] + extra_objects = @ceedling[:file_path_utils].form_release_build_c_objects_filelist( COLLECTION_RELEASE_ARTIFACT_EXTRA_LINK_OBJECTS ) + + @ceedling[:project_config_manager].process_release_config_change + core_objects.concat( @ceedling[:release_invoker].setup_and_invoke_c_objects( COLLECTION_ALL_SOURCE ) ) + + # if assembler use isn't enabled, COLLECTION_ALL_ASSEMBLY is empty array & nothing happens + core_objects.concat( @ceedling[:release_invoker].setup_and_invoke_asm_objects( COLLECTION_ALL_ASSEMBLY ) ) + + # if we're using libraries, we need to add those to our collection as well + library_objects = (defined? LIBRARIES_RELEASE && !LIBRARIES_RELEASE.empty?) ? LIBRARIES_RELEASE.flatten.compact : [] + file( PROJECT_RELEASE_BUILD_TARGET => (core_objects + extra_objects + library_objects) ) + Rake::Task[PROJECT_RELEASE_BUILD_TARGET].invoke + ensure + @ceedling[:plugin_manager].post_release + end +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_release_deep_dependencies.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_release_deep_dependencies.rake new file mode 100644 index 0000000..db2be5f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_release_deep_dependencies.rake @@ -0,0 +1,9 @@ +require 'ceedling/constants' + +namespace REFRESH_SYM do + + task RELEASE_SYM do + @ceedling[:release_invoker].refresh_c_deep_dependencies + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_tests.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_tests.rake new file mode 100644 index 0000000..5d09c1a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_tests.rake @@ -0,0 +1,60 @@ +require 'ceedling/constants' + +task :test => [:directories] do + Rake.application['test:all'].invoke +end + +namespace TEST_SYM do + + desc "Run all unit tests (also just 'test' works)." + task :all => [:directories] do + @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS) + end + + desc "Run single test ([*] real test or source file name, no path)." + task :* do + message = "\nOops! '#{TEST_ROOT_NAME}:*' isn't a real task. " + + "Use a real test or source file name (no path) in place of the wildcard.\n" + + "Example: rake #{TEST_ROOT_NAME}:foo.c\n\n" + + @ceedling[:streaminator].stdout_puts( message ) + end + + desc "Run tests for changed files." + task :delta => [:directories] do + @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, TEST_SYM, {:force_run => false}) + end + + desc "Just build tests without running." + task :build_only => [:directories] do + @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, TEST_SYM, {:build_only => true}) + end + + desc "Run tests by matching regular expression pattern." + task :pattern, [:regex] => [:directories] do |t, args| + matches = [] + + COLLECTION_ALL_TESTS.each { |test| matches << test if (test =~ /#{args.regex}/) } + + if (matches.size > 0) + @ceedling[:test_invoker].setup_and_invoke(matches, TEST_SYM, {:force_run => false}) + else + @ceedling[:streaminator].stdout_puts("\nFound no tests matching pattern /#{args.regex}/.") + end + end + + desc "Run tests whose test path contains [dir] or [dir] substring." + task :path, [:dir] => [:directories] do |t, args| + matches = [] + + COLLECTION_ALL_TESTS.each { |test| matches << test if File.dirname(test).include?(args.dir.gsub(/\\/, '/')) } + + if (matches.size > 0) + @ceedling[:test_invoker].setup_and_invoke(matches, TEST_SYM, {:force_run => false}) + else + @ceedling[:streaminator].stdout_puts("\nFound no tests including the given path or path component.") + end + end + +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_tests_deep_dependencies.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_tests_deep_dependencies.rake new file mode 100644 index 0000000..f899407 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_tests_deep_dependencies.rake @@ -0,0 +1,9 @@ +require 'ceedling/constants' + +namespace REFRESH_SYM do + + task TEST_SYM do + @ceedling[:test_invoker].refresh_deep_dependencies + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_vendor.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_vendor.rake new file mode 100644 index 0000000..63c2ca5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tasks_vendor.rake @@ -0,0 +1,35 @@ +require 'ceedling/constants' +require 'ceedling/file_path_utils' + +# create file dependencies to ensure C-based components of vendor tools are recompiled when they are updated with new versions +# forming these explicitly rather than depend on auxiliary dependencies so all scenarios are explicitly covered + +file( @ceedling[:file_path_utils].form_test_build_c_object_filepath( UNITY_C_FILE ) => [ + File.join( UNITY_VENDOR_PATH, UNITY_LIB_PATH, UNITY_C_FILE ), + File.join( UNITY_VENDOR_PATH, UNITY_LIB_PATH, UNITY_H_FILE ), + File.join( UNITY_VENDOR_PATH, UNITY_LIB_PATH, UNITY_INTERNALS_H_FILE ) ] + ) + + +if (PROJECT_USE_MOCKS) +file( @ceedling[:file_path_utils].form_test_build_c_object_filepath( CMOCK_C_FILE ) => [ + File.join( CMOCK_VENDOR_PATH, CMOCK_LIB_PATH, CMOCK_C_FILE ), + File.join( CMOCK_VENDOR_PATH, CMOCK_LIB_PATH, CMOCK_H_FILE ) ] + ) +end + + +if (PROJECT_USE_EXCEPTIONS) +file( @ceedling[:file_path_utils].form_test_build_c_object_filepath( CEXCEPTION_C_FILE ) => [ + File.join( CEXCEPTION_VENDOR_PATH, CEXCEPTION_LIB_PATH, CEXCEPTION_C_FILE ), + File.join( CEXCEPTION_VENDOR_PATH, CEXCEPTION_LIB_PATH, CEXCEPTION_H_FILE ) ] + ) +end + + +if (PROJECT_USE_EXCEPTIONS and PROJECT_RELEASE_BUILD) +file( @ceedling[:file_path_utils].form_release_build_c_object_filepath( CEXCEPTION_C_FILE ) => [ + File.join( CEXCEPTION_VENDOR_PATH, CEXCEPTION_LIB_PATH, CEXCEPTION_C_FILE ), + File.join( CEXCEPTION_VENDOR_PATH, CEXCEPTION_LIB_PATH, CEXCEPTION_H_FILE ) ] + ) +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_includes_extractor.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_includes_extractor.rb new file mode 100644 index 0000000..50cc7c0 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_includes_extractor.rb @@ -0,0 +1,85 @@ + +class TestIncludesExtractor + + constructor :configurator, :yaml_wrapper, :file_wrapper + + def setup + @includes = {} + @mocks = {} + end + + + # for includes_list file, slurp up array from yaml file and sort & store includes + def parse_includes_list(includes_list) + gather_and_store_includes( includes_list, @yaml_wrapper.load(includes_list) ) + end + + # open, scan for, and sort & store includes of test file + def parse_test_file(test) + gather_and_store_includes( test, extract_from_file(test) ) + end + + # mocks with no file extension + def lookup_raw_mock_list(test) + file_key = form_file_key(test) + return [] if @mocks[file_key].nil? + return @mocks[file_key] + end + + # includes with file extension + def lookup_includes_list(file) + file_key = form_file_key(file) + return [] if (@includes[file_key]).nil? + return @includes[file_key] + end + + private ################################# + + def form_file_key(filepath) + return File.basename(filepath).to_sym + end + + def extract_from_file(file) + includes = [] + header_extension = @configurator.extension_header + + contents = @file_wrapper.read(file) + + # remove line comments + contents = contents.gsub(/\/\/.*$/, '') + # remove block comments + contents = contents.gsub(/\/\*.*?\*\//m, '') + + contents.split("\n").each do |line| + # look for include statement + scan_results = line.scan(/#include\s+\"\s*(.+#{'\\'+header_extension})\s*\"/) + + includes << scan_results[0][0] if (scan_results.size > 0) + + # look for TEST_FILE statement + scan_results = line.scan(/TEST_FILE\(\s*\"\s*(.+\.\w+)\s*\"\s*\)/) + + includes << scan_results[0][0] if (scan_results.size > 0) + end + + return includes.uniq + end + + def gather_and_store_includes(file, includes) + mock_prefix = @configurator.cmock_mock_prefix + header_extension = @configurator.extension_header + file_key = form_file_key(file) + @mocks[file_key] = [] + + # add includes to lookup hash + @includes[file_key] = includes + + includes.each do |include_file| + # check if include is a mock + scan_results = include_file.scan(/(#{mock_prefix}.+)#{'\\'+header_extension}/) + # add mock to lookup hash + @mocks[file_key] << scan_results[0][0] if (scan_results.size > 0) + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_invoker.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_invoker.rb new file mode 100644 index 0000000..652cb31 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_invoker.rb @@ -0,0 +1,188 @@ +require 'ceedling/constants' + + +class TestInvoker + + attr_reader :sources, :tests, :mocks + + constructor :configurator, + :test_invoker_helper, + :plugin_manager, + :streaminator, + :preprocessinator, + :task_invoker, + :dependinator, + :project_config_manager, + :build_invoker_utils, + :file_path_utils, + :file_wrapper + + def setup + @sources = [] + @tests = [] + @mocks = [] + end + + def get_test_definition_str(test) + return "-D" + File.basename(test, File.extname(test)).upcase.sub(/@.*$/, "") + end + + def get_tools_compilers + tools_compilers = Hash.new + tools_compilers["for unit test"] = TOOLS_TEST_COMPILER if defined? TOOLS_TEST_COMPILER + tools_compilers["for gcov"] = TOOLS_GCOV_COMPILER if defined? TOOLS_GCOV_COMPILER + return tools_compilers + end + + def add_test_definition(test) + test_definition_str = get_test_definition_str(test) + get_tools_compilers.each do |tools_compiler_key, tools_compiler_value| + tools_compiler_value[:arguments].push("-D#{File.basename(test, ".*").strip.upcase.sub(/@.*$/, "")}") + @streaminator.stdout_puts("Add the definition value in the build option #{tools_compiler_value[:arguments][-1]} #{tools_compiler_key}", Verbosity::OBNOXIOUS) + end + end + + def delete_test_definition(test) + test_definition_str = get_test_definition_str(test) + get_tools_compilers.each do |tools_compiler_key, tools_compiler_value| + num_options = tools_compiler_value[:arguments].size + @streaminator.stdout_puts("Delete the definition value in the build option #{tools_compiler_value[:arguments][-1]} #{tools_compiler_key}", Verbosity::OBNOXIOUS) + tools_compiler_value[:arguments].delete_if{|i| i == test_definition_str} + if num_options > tools_compiler_value[:arguments].size + 1 + @streaminator.stderr_puts("WARNING: duplicated test definition.") + end + end + end + + # Convert libraries configuration form YAML configuration + # into a string that can be given to the compiler. + def convert_libraries_to_arguments() + if @configurator.project_config_hash.has_key?(:libraries_test) + lib_args = @configurator.project_config_hash[:libraries_test] + lib_args.flatten! + lib_flag = @configurator.project_config_hash[:libraries_flag] + lib_args.map! {|v| lib_flag.gsub(/\$\{1\}/, v) } if (defined? lib_flag) + return lib_args + end + end + + + def setup_and_invoke(tests, context=TEST_SYM, options={:force_run => true, :build_only => false}) + + @tests = tests + + @project_config_manager.process_test_config_change + + @tests.each do |test| + # announce beginning of test run + header = "Test '#{File.basename(test)}'" + @streaminator.stdout_puts("\n\n#{header}\n#{'-' * header.length}") + + begin + @plugin_manager.pre_test( test ) + test_name ="#{File.basename(test)}".chomp('.c') + def_test_key="defines_#{test_name.downcase}" + + # Re-define the project out path and pre-processor defines. + if @configurator.project_config_hash.has_key?(def_test_key.to_sym) + @project_config_manager.test_config_changed + defs_bkp = Array.new(COLLECTION_DEFINES_TEST_AND_VENDOR) + printf " ************** Specific test definitions for #{test_name} !!! \n" + tst_defs_cfg = @configurator.project_config_hash[def_test_key.to_sym] + + orig_path = @configurator.project_test_build_output_path + @configurator.project_config_hash[:project_test_build_output_path] = File.join(@configurator.project_test_build_output_path, test_name) + @file_wrapper.mkdir(@configurator.project_test_build_output_path) + COLLECTION_DEFINES_TEST_AND_VENDOR.replace(tst_defs_cfg) + # printf " * new defines = #{COLLECTION_DEFINES_TEST_AND_VENDOR}\n" + end + + # collect up test fixture pieces & parts + runner = @file_path_utils.form_runner_filepath_from_test( test ) + mock_list = @preprocessinator.preprocess_test_and_invoke_test_mocks( test ) + sources = @test_invoker_helper.extract_sources( test ) + extras = @configurator.collection_test_fixture_extra_link_objects + core = [test] + mock_list + sources + objects = @file_path_utils.form_test_build_objects_filelist( [runner] + core + extras ) + results_pass = @file_path_utils.form_pass_results_filepath( test ) + results_fail = @file_path_utils.form_fail_results_filepath( test ) + + @project_config_manager.process_test_defines_change(sources) + + # add the definition value in the build option for the unit test + if @configurator.defines_use_test_definition + add_test_definition(test) + end + + # clean results files so we have a missing file with which to kick off rake's dependency rules + @test_invoker_helper.clean_results( {:pass => results_pass, :fail => results_fail}, options ) + + # load up auxiliary dependencies so deep changes cause rebuilding appropriately + @test_invoker_helper.process_deep_dependencies( core ) do |dependencies_list| + @dependinator.load_test_object_deep_dependencies( dependencies_list ) + end + + # tell rake to create test runner if needed + @task_invoker.invoke_test_runner( runner ) + + # enhance object file dependencies to capture externalities influencing regeneration + @dependinator.enhance_test_build_object_dependencies( objects ) + + # associate object files with executable + @dependinator.setup_test_executable_dependencies( test, objects ) + + # build test objects + @task_invoker.invoke_test_objects( objects ) + + # if the option build_only has been specified, build only the executable + # but don't run the test + if (options[:build_only]) + executable = @file_path_utils.form_test_executable_filepath( test ) + @task_invoker.invoke_test_executable( executable ) + else + # 3, 2, 1... launch + @task_invoker.invoke_test_results( results_pass ) + end + rescue => e + @build_invoker_utils.process_exception( e, context ) + ensure + # delete the definition value in the build option for the unit test + if @configurator.defines_use_test_definition + delete_test_definition(test) + end + @plugin_manager.post_test( test ) + # restore the project test defines + if @configurator.project_config_hash.has_key?(def_test_key.to_sym) + # @configurator.project_config_hash[:defines_test] = + COLLECTION_DEFINES_TEST_AND_VENDOR.replace(defs_bkp) + # printf " ---- Restored defines at #{defs_bkp}" + @configurator.project_config_hash[:project_test_build_output_path] = orig_path + printf " ************** Restored defines and build path\n" + end + end + + # store away what's been processed + @mocks.concat( mock_list ) + @sources.concat( sources ) + + @task_invoker.first_run = false + end + + # post-process collected mock list + @mocks.uniq! + + # post-process collected sources list + @sources.uniq! + end + + + def refresh_deep_dependencies + @file_wrapper.rm_f( + @file_wrapper.directory_listing( + File.join( @configurator.project_test_dependencies_path, '*' + @configurator.extension_dependencies ) ) ) + + @test_invoker_helper.process_deep_dependencies( + @configurator.collection_all_tests + @configurator.collection_all_source ) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_invoker_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_invoker_helper.rb new file mode 100644 index 0000000..b0a223f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/test_invoker_helper.rb @@ -0,0 +1,32 @@ + +class TestInvokerHelper + + constructor :configurator, :task_invoker, :test_includes_extractor, :file_finder, :file_path_utils, :file_wrapper + + def clean_results(results, options) + @file_wrapper.rm_f( results[:fail] ) + @file_wrapper.rm_f( results[:pass] ) if (options[:force_run]) + end + + def process_deep_dependencies(files) + return if (not @configurator.project_use_deep_dependencies) + + dependencies_list = @file_path_utils.form_test_dependencies_filelist( files ) + + if @configurator.project_generate_deep_dependencies + @task_invoker.invoke_test_dependencies_files( dependencies_list ) + end + + yield( dependencies_list ) if block_given? + end + + def extract_sources(test) + sources = [] + includes = @test_includes_extractor.lookup_includes_list(test) + + includes.each { |include| sources << @file_finder.find_compilation_input_file(include, :ignore) } + + return sources.compact + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tool_executor.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tool_executor.rb new file mode 100644 index 0000000..0ab5ddc --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tool_executor.rb @@ -0,0 +1,229 @@ +require 'ceedling/constants' +require 'benchmark' + +class ShellExecutionException < RuntimeError + attr_reader :shell_result + def initialize(shell_result) + @shell_result = shell_result + end +end + +class ToolExecutor + + constructor :configurator, :tool_executor_helper, :streaminator, :system_wrapper + + def setup + @tool_name = '' + @executable = '' + end + + # build up a command line from yaml provided config + + # @param extra_params is an array of parameters to append to executable + def build_command_line(tool_config, extra_params, *args) + @tool_name = tool_config[:name] + @executable = tool_config[:executable] + + command = {} + + # basic premise is to iterate top to bottom through arguments using '$' as + # a string replacement indicator to expand globals or inline yaml arrays + # into command line arguments via substitution strings + # executable must be quoted if it includes spaces (common on windows) + executable = @tool_executor_helper.osify_path_separators( expandify_element(@executable, *args) ) + executable = "\"#{executable}\"" if executable.include?(' ') + command[:line] = [ + executable, + extra_params.join(' ').strip, + build_arguments(tool_config[:arguments], *args), + ].reject{|s| s.nil? || s.empty?}.join(' ').strip + + command[:options] = { + :stderr_redirect => @tool_executor_helper.stderr_redirection(tool_config, @configurator.project_logging), + :background_exec => tool_config[:background_exec] + } + + return command + end + + + # shell out, execute command, and return response + def exec(command, options={}, args=[]) + options[:boom] = true if (options[:boom].nil?) + options[:stderr_redirect] = StdErrRedirect::NONE if (options[:stderr_redirect].nil?) + options[:background_exec] = BackgroundExec::NONE if (options[:background_exec].nil?) + # build command line + command_line = [ + @tool_executor_helper.background_exec_cmdline_prepend( options ), + command.strip, + args, + @tool_executor_helper.stderr_redirect_cmdline_append( options ), + @tool_executor_helper.background_exec_cmdline_append( options ), + ].flatten.compact.join(' ') + + @streaminator.stderr_puts("Verbose: #{__method__.to_s}(): #{command_line}", Verbosity::DEBUG) + + shell_result = {} + + # depending on background exec option, we shell out differently + time = Benchmark.realtime do + if (options[:background_exec] != BackgroundExec::NONE) + shell_result = @system_wrapper.shell_system( command_line, options[:boom] ) + else + shell_result = @system_wrapper.shell_backticks( command_line, options[:boom] ) + end + end + shell_result[:time] = time + + #scrub the string for illegal output + unless shell_result[:output].nil? + shell_result[:output] = shell_result[:output].scrub if "".respond_to?(:scrub) + shell_result[:output].gsub!(/\033\[\d\dm/,'') + end + + @tool_executor_helper.print_happy_results( command_line, shell_result, options[:boom] ) + @tool_executor_helper.print_error_results( command_line, shell_result, options[:boom] ) + + # go boom if exit code isn't 0 (but in some cases we don't want a non-0 exit code to raise) + raise ShellExecutionException.new(shell_result) if ((shell_result[:exit_code] != 0) and options[:boom]) + + return shell_result + end + + + private ############################# + + + def build_arguments(config, *args) + build_string = '' + + return nil if (config.nil?) + + # iterate through each argument + + # the yaml blob array needs to be flattened so that yaml substitution + # is handled correctly, since it creates a nested array when an anchor is + # dereferenced + config.flatten.each do |element| + argument = '' + + case(element) + # if we find a simple string then look for string replacement operators + # and expand with the parameters in this method's argument list + when String then argument = expandify_element(element, *args) + # if we find a hash, then we grab the key as a substitution string and expand the + # hash's value(s) within that substitution string + when Hash then argument = dehashify_argument_elements(element) + end + + build_string.concat("#{argument} ") if (argument.length > 0) + end + + build_string.strip! + return build_string if (build_string.length > 0) + return nil + end + + + # handle simple text string argument & argument array string replacement operators + def expandify_element(element, *args) + match = // + to_process = nil + args_index = 0 + + # handle ${#} input replacement + if (element =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN) + args_index = ($2.to_i - 1) + + if (args.nil? or args[args_index].nil?) + @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' expected valid argument data to accompany replacement operator #{$1}.", Verbosity::ERRORS) + raise + end + + match = /#{Regexp.escape($1)}/ + to_process = args[args_index] + end + + # simple string argument: replace escaped '\$' and strip + element.sub!(/\\\$/, '$') + element.strip! + + # handle inline ruby execution + if (element =~ RUBY_EVAL_REPLACEMENT_PATTERN) + element.replace(eval($1)) + end + + build_string = '' + + # handle array or anything else passed into method to be expanded in place of replacement operators + case (to_process) + when Array then to_process.each {|value| build_string.concat( "#{element.sub(match, value.to_s)} " ) } if (to_process.size > 0) + else build_string.concat( element.sub(match, to_process.to_s) ) + end + + # handle inline ruby string substitution + if (build_string =~ RUBY_STRING_REPLACEMENT_PATTERN) + build_string.replace(@system_wrapper.module_eval(build_string)) + end + + return build_string.strip + end + + + # handle argument hash: keys are substitution strings, values are data to be expanded within substitution strings + def dehashify_argument_elements(hash) + build_string = '' + elements = [] + + # grab the substitution string (hash key) + substitution = hash.keys[0].to_s + # grab the string(s) to squirt into the substitution string (hash value) + expand = hash[hash.keys[0]] + + if (expand.nil?) + @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' could not expand nil elements for substitution string '#{substitution}'.", Verbosity::ERRORS) + raise + end + + # array-ify expansion input if only a single string + expansion = ((expand.class == String) ? [expand] : expand) + + expansion.each do |item| + # code eval substitution + if (item =~ RUBY_EVAL_REPLACEMENT_PATTERN) + elements << eval($1) + # string eval substitution + elsif (item =~ RUBY_STRING_REPLACEMENT_PATTERN) + elements << @system_wrapper.module_eval(item) + # global constants + elsif (@system_wrapper.constants_include?(item)) + const = Object.const_get(item) + if (const.nil?) + @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' found constant '#{item}' to be nil.", Verbosity::ERRORS) + raise + else + elements << const + end + elsif (item.class == Array) + elements << item + elsif (item.class == String) + @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' cannot expand nonexistent value '#{item}' for substitution string '#{substitution}'.", Verbosity::ERRORS) + raise + else + @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' cannot expand value having type '#{item.class}' for substitution string '#{substitution}'.", Verbosity::ERRORS) + raise + end + end + + # expand elements (whether string or array) into substitution string & replace escaped '\$' + elements.flatten! + elements.each do |element| + build_string.concat( substitution.sub(/([^\\]*)\$/, "\\1#{element}") ) # don't replace escaped '\$' but allow us to replace just a lonesome '$' + build_string.gsub!(/\\\$/, '$') + build_string.concat(' ') + end + + return build_string.strip + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tool_executor_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tool_executor_helper.rb new file mode 100644 index 0000000..de4cafe --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/tool_executor_helper.rb @@ -0,0 +1,164 @@ +require 'ceedling/constants' # for Verbosity enumeration & $stderr redirect enumeration + +## +# Helper functions for the tool executor +class ToolExecutorHelper + + constructor :streaminator, :system_utils, :system_wrapper + + ## + # Returns the stderr redirection based on the config and logging. + # ==== Attributes + # + # * _tool_config_: A hash containing config information. + # * _logging_: A boolean representing if logging is enabled or not. + # + def stderr_redirection(tool_config, logging) + # if there's no logging enabled, return :stderr_redirect unmodified + return tool_config[:stderr_redirect] if (not logging) + + # if there is logging enabled but the redirect is a custom value (not enum), return the custom string + return tool_config[:stderr_redirect] if (tool_config[:stderr_redirect].class == String) + + # if logging is enabled but there's no custom string, return the AUTO enumeration so $stderr goes into the log + return StdErrRedirect::AUTO + end + + + ## + # Returns the background execution prepend based on the config. + # ==== Attributes + # + # * _tool_config_: A hash containing config information. + # + def background_exec_cmdline_prepend(tool_config) + return nil if (tool_config.nil? || tool_config[:background_exec].nil?) + + config_exec = tool_config[:background_exec] + + if ((config_exec == BackgroundExec::AUTO) and (@system_wrapper.windows?)) + return 'start' + end + + if (config_exec == BackgroundExec::WIN) + return 'start' + end + + return nil + end + + + ## + # Modifies an executables path based on platform. + # ==== Attributes + # + # * _executable_: The executable's path. + # + def osify_path_separators(executable) + return executable.gsub(/\//, '\\') if (@system_wrapper.windows?) + return executable + end + + ## + # Returns the stderr redirect append based on the config. + # ==== Attributes + # + # * _tool_config_: A hash containing config information. + # + def stderr_redirect_cmdline_append(tool_config) + return nil if (tool_config.nil? || tool_config[:stderr_redirect].nil?) + + config_redirect = tool_config[:stderr_redirect] + redirect = StdErrRedirect::NONE + + if (config_redirect == StdErrRedirect::AUTO) + if (@system_wrapper.windows?) + redirect = StdErrRedirect::WIN + elsif (@system_utils.tcsh_shell?) + redirect = StdErrRedirect::TCSH + else + redirect = StdErrRedirect::UNIX + end + end + + case redirect + # we may need more complicated processing after some learning with various environments + when StdErrRedirect::NONE then nil + when StdErrRedirect::WIN then '2>&1' + when StdErrRedirect::UNIX then '2>&1' + when StdErrRedirect::TCSH then '|&' + else redirect.to_s + end + end + + ## + # Returns the background execution append based on the config. + # ==== Attributes + # + # * _tool_config_: A hash containing config information. + # + def background_exec_cmdline_append(tool_config) + return nil if (tool_config.nil? || tool_config[:background_exec].nil?) + + config_exec = tool_config[:background_exec] + + # if :auto & windows, then we already prepended 'start' and should append nothing + return nil if ((config_exec == BackgroundExec::AUTO) and (@system_wrapper.windows?)) + + # if :auto & not windows, then we append standard '&' + return '&' if ((config_exec == BackgroundExec::AUTO) and (not @system_wrapper.windows?)) + + # if explicitly Unix, then append '&' + return '&' if (config_exec == BackgroundExec::UNIX) + + # * _command_str_: A hash containing config information. + # all other cases, including :none, :win, & anything unrecognized, append nothing + return nil + end + + ## + # Outputs success results if command succeeded and we have verbosity cranked up. + # ==== Attributes + # + # * _command_str_: The command ran. + # * _shell_results_: The outputs of the command including exit code and + # output. + # * _boom_: A boolean representing if a non zero result is erroneous. + # + def print_happy_results(command_str, shell_result, boom=true) + if ((shell_result[:exit_code] == 0) or ((shell_result[:exit_code] != 0) and not boom)) + output = "> Shell executed command:\n" + output += "'#{command_str}'\n" + output += "> Produced output:\n" if (not shell_result[:output].empty?) + output += "#{shell_result[:output].strip}\n" if (not shell_result[:output].empty?) + output += "> And exited with status: [#{shell_result[:exit_code]}].\n" if (shell_result[:exit_code] != 0) + output += "\n" + + @streaminator.stdout_puts(output, Verbosity::OBNOXIOUS) + end + end + + ## + # Outputs failures results if command failed and we have verbosity set to minimum error level. + # ==== Attributes + # + # * _command_str_: The command ran. + # * _shell_results_: The outputs of the command including exit code and + # output. + # * _boom_: A boolean representing if a non zero result is erroneous. + # + def print_error_results(command_str, shell_result, boom=true) + if ((shell_result[:exit_code] != 0) and boom) + output = "ERROR: Shell command failed.\n" + output += "> Shell executed command:\n" + output += "'#{command_str}'\n" + output += "> Produced output:\n" if (not shell_result[:output].empty?) + output += "#{shell_result[:output].strip}\n" if (not shell_result[:output].empty?) + output += "> And exited with status: [#{shell_result[:exit_code]}].\n" if (shell_result[:exit_code] != nil) + output += "> And then likely crashed.\n" if (shell_result[:exit_code] == nil) + output += "\n" + + @streaminator.stderr_puts(output, Verbosity::ERRORS) + end + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/verbosinator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/verbosinator.rb new file mode 100644 index 0000000..e8ed38d --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/verbosinator.rb @@ -0,0 +1,10 @@ + +class Verbosinator + + constructor :configurator + + def should_output?(level) + return (level <= @configurator.project_verbosity) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/version.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/version.rb new file mode 100644 index 0000000..ba917df --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/version.rb @@ -0,0 +1,36 @@ + +# @private +module Ceedling + module Version + # Check for local or global version of vendor directory in order to look up versions + { + "CEXCEPTION" => File.join("vendor","c_exception","lib","CException.h"), + "CMOCK" => File.join("vendor","cmock","src","cmock.h"), + "UNITY" => File.join("vendor","unity","src","unity.h"), + }.each_pair do |name, path| + filename = if (File.exist?(File.join("..","..",path))) + File.join("..","..",path) + elsif (File.exist?(File.join(File.dirname(__FILE__),"..","..",path))) + File.join(File.dirname(__FILE__),"..","..",path) + else + eval "#{name} = 'unknown'" + continue + end + + # Actually look up the versions + a = [0,0,0] + File.readlines(filename) do |line| + ["VERSION_MAJOR", "VERSION_MINOR", "VERSION_BUILD"].each_with_index do |field, i| + m = line.match(/#{name}_#{field}\s+(\d+)/) + a[i] = m[1] unless (m.nil?) + end + end + + # Make a constant from each, so that we can use it elsewhere + eval "#{name} = '#{a.join(".")}'" + end + + GEM = "0.29.0" + CEEDLING = GEM + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/version.rb.erb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/version.rb.erb new file mode 100644 index 0000000..a31e3ab --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/version.rb.erb @@ -0,0 +1,15 @@ +# @private +module Ceedling + module Version + # @private + GEM = "0.27.0" + # @private + CEEDLING = "<%= versions["CEEDLING"] %>" + # @private + CEXCEPTION = "<%= versions["CEXCEPTION"] %>" + # @private + CMOCK = "<%= versions["CMOCK"] %>" + # @private + UNITY = "<%= versions["UNITY"] %>" + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/yaml_wrapper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/yaml_wrapper.rb new file mode 100644 index 0000000..00ece51 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/lib/ceedling/yaml_wrapper.rb @@ -0,0 +1,17 @@ +require 'yaml' +require 'erb' + + +class YamlWrapper + + def load(filepath) + return YAML.load(ERB.new(File.read(filepath)).result) + end + + def dump(filepath, structure) + File.open(filepath, 'w') do |output| + YAML.dump(structure, output) + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/beep/README.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/beep/README.md new file mode 100644 index 0000000..e59d881 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/beep/README.md @@ -0,0 +1,22 @@ +ceedling-beep +============= + +This is a simple plugin that just beeps at the end of a build and/or test sequence. Are you getting too distracted surfing +the internet, chatting with coworkers, or swordfighting while it's building or testing? The friendly beep will let you know +it's time to pay attention again. + +This plugin has very few configuration options. At this time it can beep on completion of a task and/or on an error condition. +For each of these, you can configure the method that it should beep. + +``` +:tools: + :beep_on_done: :bell + :beep_on_error: :bell +``` + +Each of these have the following options: + + - :bell - this option uses the ASCII bell character out stdout + - :speaker_test - this uses the linux speaker-test command if installed + +Very likely, we'll be adding to this list if people find this to be useful. diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/beep/lib/beep.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/beep/lib/beep.rb new file mode 100644 index 0000000..6a6d01a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/beep/lib/beep.rb @@ -0,0 +1,40 @@ +require 'ceedling/plugin' +require 'ceedling/constants' + +class Beep < Plugin + + attr_reader :config + + def setup + @config = { + :on_done => ((defined? TOOLS_BEEP_ON_DONE) ? TOOLS_BEEP_ON_DONE : :bell ), + :on_error => ((defined? TOOLS_BEEP_ON_ERROR) ? TOOLS_BEEP_ON_ERROR : :bell ), + } + end + + def post_build + beep @config[:on_done] + end + + def post_error + beep @config[:on_error] + end + + private + + def beep(method = :none) + case method + when :bell + if (SystemWrapper.windows?) + puts "echo '\007'" + else + puts "echo -ne '\007'" + end + when :speaker_test + `speaker-test -t sine -f 1000 -l 1` + else + #do nothing with illegal or :none + end + end +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/assets/template.erb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/assets/template.erb new file mode 100644 index 0000000..504f855 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/assets/template.erb @@ -0,0 +1,15 @@ +% function_string = hash[:coverage][:functions].to_s +% branch_string = hash[:coverage][:branches].to_s +% format_string = "%#{[function_string.length, branch_string.length].max}i" +<%=@ceedling[:plugin_reportinator].generate_banner("#{hash[:header]}: CODE COVERAGE SUMMARY")%> +% if (!hash[:coverage][:functions].nil?) +FUNCTIONS: <%=sprintf(format_string, hash[:coverage][:functions])%>% +% else +FUNCTIONS: none +% end +% if (!hash[:coverage][:branches].nil?) +BRANCHES: <%=sprintf(format_string, hash[:coverage][:branches])%>% +% else +BRANCHES: none +% end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/bullseye.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/bullseye.rake new file mode 100644 index 0000000..a7bbebe --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/bullseye.rake @@ -0,0 +1,169 @@ +directory(BULLSEYE_BUILD_OUTPUT_PATH) +directory(BULLSEYE_RESULTS_PATH) +directory(BULLSEYE_ARTIFACTS_PATH) +directory(BULLSEYE_DEPENDENCIES_PATH) + +CLEAN.include(File.join(BULLSEYE_BUILD_OUTPUT_PATH, '*')) +CLEAN.include(File.join(BULLSEYE_RESULTS_PATH, '*')) +CLEAN.include(File.join(BULLSEYE_DEPENDENCIES_PATH, '*')) + +CLOBBER.include(File.join(BULLSEYE_BUILD_PATH, '**/*')) +PLUGINS_BULLSEYE_LIB_PATH = 'C:\\tools\\BullseyeCoverage\\lib' if not defined?(PLUGINS_BULLSEYE_LIB_PATH) + +rule(/#{BULLSEYE_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_compilation_input_file(task_name) + end + ]) do |object| + + if File.basename(object.source) =~ /^(#{PROJECT_TEST_FILE_PREFIX}|#{CMOCK_MOCK_PREFIX}|#{BULLSEYE_IGNORE_SOURCES.join('|')})/i + @ceedling[:generator].generate_object_file( + TOOLS_BULLSEYE_COMPILER, + OPERATION_COMPILE_SYM, + BULLSEYE_SYM, + object.source, + object.name, + @ceedling[:file_path_utils].form_test_build_list_filepath(object.name) + ) + else + @ceedling[BULLSEYE_SYM].generate_coverage_object_file(object.source, object.name) + end + +end + +rule(/#{BULLSEYE_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_EXECUTABLE}$/) do |bin_file| + @ceedling[:generator].generate_executable_file( + TOOLS_BULLSEYE_LINKER, + BULLSEYE_SYM, + bin_file.prerequisites, + bin_file.name, + @ceedling[:file_path_utils].form_test_build_map_filepath(bin_file.name) + ) +end + +rule(/#{BULLSEYE_RESULTS_PATH}\/#{'.+\\'+EXTENSION_TESTPASS}$/ => [ + proc do |task_name| + @ceedling[:file_path_utils].form_test_executable_filepath(task_name) + end + ]) do |test_result| + @ceedling[:generator].generate_test_results(TOOLS_BULLSEYE_FIXTURE, BULLSEYE_SYM, test_result.source, test_result.name) +end + +rule(/#{BULLSEYE_DEPENDENCIES_PATH}\/#{'.+\\'+EXTENSION_DEPENDENCIES}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_compilation_input_file(task_name) + end + ]) do |dep| + @ceedling[:generator].generate_dependencies_file( + TOOLS_TEST_DEPENDENCIES_GENERATOR, + BULLSEYE_SYM, + dep.source, + File.join(BULLSEYE_BUILD_OUTPUT_PATH, File.basename(dep.source).ext(EXTENSION_OBJECT) ), + dep.name + ) +end + +task :directories => [BULLSEYE_BUILD_OUTPUT_PATH, BULLSEYE_RESULTS_PATH, BULLSEYE_DEPENDENCIES_PATH, BULLSEYE_ARTIFACTS_PATH] + +namespace BULLSEYE_SYM do + task source_coverage: COLLECTION_ALL_SOURCE.pathmap("#{BULLSEYE_BUILD_OUTPUT_PATH}/%n#{@ceedling[:configurator].extension_object}") + + desc 'Run code coverage for all tests' + task all: [:directories] do + @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config) + @ceedling[BULLSEYE_SYM].enableBullseye(true) + @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, BULLSEYE_SYM) + @ceedling[:configurator].restore_config + end + + desc "Run single test w/ coverage ([*] real test or source file name, no path)." + task :* do + message = "\nOops! '#{BULLSEYE_ROOT_NAME}:*' isn't a real task. " + + "Use a real test or source file name (no path) in place of the wildcard.\n" + + "Example: rake #{BULLSEYE_ROOT_NAME}:foo.c\n\n" + + @ceedling[:streaminator].stdout_puts( message ) + end + + desc 'Run tests by matching regular expression pattern.' + task :pattern, [:regex] => [:directories] do |_t, args| + matches = [] + + COLLECTION_ALL_TESTS.each do |test| + matches << test if test =~ /#{args.regex}/ + end + + if !matches.empty? + @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config) + @ceedling[BULLSEYE_SYM].enableBullseye(true) + @ceedling[:test_invoker].setup_and_invoke(matches, BULLSEYE_SYM, force_run: false) + @ceedling[:configurator].restore_config + else + @ceedling[:streaminator].stdout_puts("\nFound no tests matching pattern /#{args.regex}/.") + end + end + + desc 'Run tests whose test path contains [dir] or [dir] substring.' + task :path, [:dir] => [:directories] do |_t, args| + matches = [] + + COLLECTION_ALL_TESTS.each do |test| + matches << test if File.dirname(test).include?(args.dir.tr('\\', '/')) + end + + if !matches.empty? + @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config) + @ceedling[BULLSEYE_SYM].enableBullseye(true) + @ceedling[:test_invoker].setup_and_invoke(matches, BULLSEYE_SYM, force_run: false) + @ceedling[:configurator].restore_config + else + @ceedling[:streaminator].stdout_puts("\nFound no tests including the given path or path component.") + end + end + + desc 'Run code coverage for changed files' + task delta: [:directories] do + @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config) + @ceedling[BULLSEYE_SYM].enableBullseye(true) + @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, BULLSEYE_SYM, {:force_run => false}) + @ceedling[:configurator].restore_config + end + + # use a rule to increase efficiency for large projects + # bullseye test tasks by regex + rule(/^#{BULLSEYE_TASK_ROOT}\S+$/ => [ + proc do |task_name| + test = task_name.sub(/#{BULLSEYE_TASK_ROOT}/, '') + test = "#{PROJECT_TEST_FILE_PREFIX}#{test}" unless test.start_with?(PROJECT_TEST_FILE_PREFIX) + @ceedling[:file_finder].find_test_from_file_path(test) + end + ]) do |test| + @ceedling[:rake_wrapper][:directories].invoke + @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config) + @ceedling[BULLSEYE_SYM].enableBullseye(true) + @ceedling[:test_invoker].setup_and_invoke([test.source], BULLSEYE_SYM) + @ceedling[:configurator].restore_config + end + +end + +if PROJECT_USE_DEEP_DEPENDENCIES +namespace REFRESH_SYM do + task BULLSEYE_SYM do + @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config) + @ceedling[BULLSEYE_SYM].enableBullseye(true) + @ceedling[:test_invoker].refresh_deep_dependencies + @ceedling[:configurator].restore_config + end +end +end + +namespace UTILS_SYM do + + desc "Open Bullseye code coverage browser" + task BULLSEYE_SYM do + command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_BROWSER, []) + @ceedling[:tool_executor].exec(command[:line], command[:options]) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/config/defaults.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/config/defaults.yml new file mode 100644 index 0000000..ed261d8 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/config/defaults.yml @@ -0,0 +1,57 @@ +--- + +:bullseye: + :auto_license: TRUE +:plugins: + :bullseye_lib_path: [] +:paths: + :bullseye_toolchain_include: [] + +:tools: + :bullseye_instrumentation: + :executable: covc + :arguments: + - '--file $': ENVIRONMENT_COVFILE + - -q + - ${1} + :bullseye_compiler: + :executable: gcc + :arguments: + - -g + - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + - -I"$": COLLECTION_PATHS_BULLSEYE_TOOLCHAIN_INCLUDE + - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR + - -DBULLSEYE_COMPILER + - -c "${1}" + - -o "${2}" + :bullseye_linker: + :executable: gcc + :arguments: + - ${1} + - -o ${2} + - -L$: PLUGINS_BULLSEYE_LIB_PATH + - -lcov + :bullseye_fixture: + :executable: ${1} + :bullseye_report_covsrc: + :executable: covsrc + :arguments: + - '--file $': ENVIRONMENT_COVFILE + - -q + - -w140 + :bullseye_report_covfn: + :executable: covfn + :stderr_redirect: :auto + :arguments: + - '--file $': ENVIRONMENT_COVFILE + - --width 120 + - --no-source + - '"${1}"' + :bullseye_browser: + :executable: CoverageBrowser + :background_exec: :auto + :optional: TRUE + :arguments: + - '"$"': ENVIRONMENT_COVFILE + +... diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/lib/bullseye.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/lib/bullseye.rb new file mode 100644 index 0000000..ffa444a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/lib/bullseye.rb @@ -0,0 +1,194 @@ +require 'ceedling/plugin' +require 'ceedling/constants' + +BULLSEYE_ROOT_NAME = 'bullseye' +BULLSEYE_TASK_ROOT = BULLSEYE_ROOT_NAME + ':' +BULLSEYE_SYM = BULLSEYE_ROOT_NAME.to_sym + +BULLSEYE_BUILD_PATH = "#{PROJECT_BUILD_ROOT}/#{BULLSEYE_ROOT_NAME}" +BULLSEYE_BUILD_OUTPUT_PATH = "#{BULLSEYE_BUILD_PATH}/out" +BULLSEYE_RESULTS_PATH = "#{BULLSEYE_BUILD_PATH}/results" +BULLSEYE_DEPENDENCIES_PATH = "#{BULLSEYE_BUILD_PATH}/dependencies" +BULLSEYE_ARTIFACTS_PATH = "#{PROJECT_BUILD_ARTIFACTS_ROOT}/#{BULLSEYE_ROOT_NAME}" + +BULLSEYE_IGNORE_SOURCES = ['unity', 'cmock', 'cexception'] + + +class Bullseye < Plugin + + def setup + @result_list = [] + @environment = [ {:covfile => File.join( BULLSEYE_ARTIFACTS_PATH, 'test.cov' )} ] + @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + @coverage_template_all = @ceedling[:file_wrapper].read(File.join(@plugin_root, 'assets/template.erb')) + end + + def config + { + :project_test_build_output_path => BULLSEYE_BUILD_OUTPUT_PATH, + :project_test_results_path => BULLSEYE_RESULTS_PATH, + :project_test_dependencies_path => BULLSEYE_DEPENDENCIES_PATH, + :defines_test => DEFINES_TEST + ['CODE_COVERAGE'], + :collection_defines_test_and_vendor => COLLECTION_DEFINES_TEST_AND_VENDOR + ['CODE_COVERAGE'] + } + end + + def generate_coverage_object_file(source, object) + arg_hash = {:tool => TOOLS_BULLSEYE_INSTRUMENTATION, :context => BULLSEYE_SYM, :source => source, :object => object} + @ceedling[:plugin_manager].pre_compile_execute(arg_hash) + + @ceedling[:streaminator].stdout_puts("Compiling #{File.basename(source)} with coverage...") + compile_command = + @ceedling[:tool_executor].build_command_line( + TOOLS_BULLSEYE_COMPILER, + @ceedling[:flaginator].flag_down( OPERATION_COMPILE_SYM, BULLSEYE_SYM, source ), + source, + object, + @ceedling[:file_path_utils].form_test_build_list_filepath( object ) ) + coverage_command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_INSTRUMENTATION, [], compile_command[:line] ) + + shell_result = @ceedling[:tool_executor].exec( coverage_command[:line], coverage_command[:options] ) + + arg_hash[:shell_result] = shell_result + @ceedling[:plugin_manager].post_compile_execute(arg_hash) + end + + def post_test_fixture_execute(arg_hash) + result_file = arg_hash[:result_file] + + if ((result_file =~ /#{BULLSEYE_RESULTS_PATH}/) and (not @result_list.include?(result_file))) + @result_list << arg_hash[:result_file] + end + end + + def post_build + return if (not @ceedling[:task_invoker].invoked?(/^#{BULLSEYE_TASK_ROOT}/)) + + # test results + results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list) + hash = { + :header => BULLSEYE_ROOT_NAME.upcase, + :results => results + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) do + message = '' + message = 'Unit test failures.' if (results[:counts][:failed] > 0) + message + end + + # coverage results + return if (verify_coverage_file() == false) + if (@ceedling[:task_invoker].invoked?(/^#{BULLSEYE_TASK_ROOT}(all|delta)/)) + command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_REPORT_COVSRC, []) + shell_result = @ceedling[:tool_executor].exec(command[:line], command[:options]) + report_coverage_results_all(shell_result[:output]) + else + report_per_function_coverage_results(@ceedling[:test_invoker].sources) + end + end + + def summary + return if (verify_coverage_file() == false) + result_list = @ceedling[:file_path_utils].form_pass_results_filelist( BULLSEYE_RESULTS_PATH, COLLECTION_ALL_TESTS ) + + # test results + # get test results for only those tests in our configuration and of those only tests with results on disk + hash = { + :header => BULLSEYE_ROOT_NAME.upcase, + :results => @ceedling[:plugin_reportinator].assemble_test_results(result_list, {:boom => false}) + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) + + # coverage results + command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_REPORT_COVSRC) + shell_result = @ceedling[:tool_executor].exec(command[:line], command[:options]) + report_coverage_results_all(shell_result[:output]) + end + + def enableBullseye(enable) + if BULLSEYE_AUTO_LICENSE + if (enable) + args = ['push', 'on'] + @ceedling[:streaminator].stdout_puts("Enabling Bullseye") + else + args = ['pop'] + @ceedling[:streaminator].stdout_puts("Reverting Bullseye to previous state") + end + + args.each do |arg| + command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_BUILD_ENABLE_DISABLE, [], arg) + shell_result = @ceedling[:tool_executor].exec(command[:line], command[:options]) + end + + end + end + + private ################################### + + def report_coverage_results_all(coverage) + results = { + :header => BULLSEYE_ROOT_NAME.upcase, + :coverage => { + :functions => nil, + :branches => nil + } + } + + if (coverage =~ /^Total.*?=\s+([0-9]+)\%/) + results[:coverage][:functions] = $1.to_i + end + + if (coverage =~ /^Total.*=\s+([0-9]+)\%\s*$/) + results[:coverage][:branches] = $1.to_i + end + + @ceedling[:plugin_reportinator].run_report($stdout, @coverage_template_all, results) + end + + def report_per_function_coverage_results(sources) + banner = @ceedling[:plugin_reportinator].generate_banner( "#{BULLSEYE_ROOT_NAME.upcase}: CODE COVERAGE SUMMARY" ) + @ceedling[:streaminator].stdout_puts "\n" + banner + + coverage_sources = sources.clone + coverage_sources.delete_if {|item| item =~ /#{CMOCK_MOCK_PREFIX}.+#{EXTENSION_SOURCE}$/} + coverage_sources.delete_if {|item| item =~ /#{BULLSEYE_IGNORE_SOURCES.join('|')}#{EXTENSION_SOURCE}$/} + + coverage_sources.each do |source| + command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_REPORT_COVFN, [], source) + shell_results = @ceedling[:tool_executor].exec(command[:line], command[:options]) + coverage_results = shell_results[:output].deep_clone + coverage_results.sub!(/.*\n.*\n/,'') # Remove the Bullseye tool banner + if (coverage_results =~ /warning cov814: report is empty/) + coverage_results = "WARNING: #{source} contains no coverage data!\n\n" + @ceedling[:streaminator].stdout_puts(coverage_results, Verbosity::COMPLAIN) + else + coverage_results += "\n" + @ceedling[:streaminator].stdout_puts(coverage_results) + end + end + end + + def verify_coverage_file + exist = @ceedling[:file_wrapper].exist?( ENVIRONMENT_COVFILE ) + + if (!exist) + banner = @ceedling[:plugin_reportinator].generate_banner( "#{BULLSEYE_ROOT_NAME.upcase}: CODE COVERAGE SUMMARY" ) + @ceedling[:streaminator].stdout_puts "\n" + banner + "\nNo coverage file.\n\n" + end + + return exist + end + +end + + +# end blocks always executed following rake run +END { + # cache our input configurations to use in comparison upon next execution + if (@ceedling[:task_invoker].invoked?(/^#{BULLSEYE_TASK_ROOT}/)) + @ceedling[:cacheinator].cache_test_config( @ceedling[:setupinator].config_hash ) + @ceedling[BULLSEYE_SYM].enableBullseye(false) + end +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/readme.txt b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/bullseye/readme.txt new file mode 100644 index 0000000..e69de29 diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/colour_report/lib/colour_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/colour_report/lib/colour_report.rb new file mode 100644 index 0000000..1211eab --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/colour_report/lib/colour_report.rb @@ -0,0 +1,16 @@ +require 'ceedling/plugin' +require 'ceedling/streaminator' +require 'ceedling/constants' + +class ColourReport < Plugin + + def setup + @ceedling[:stream_wrapper].stdout_override(&ColourReport.method(:colour_stdout)) + end + + def self.colour_stdout(string) + require 'colour_reporter.rb' + report string + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/command_hooks/README.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/command_hooks/README.md new file mode 100644 index 0000000..8ac64af --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/command_hooks/README.md @@ -0,0 +1,53 @@ +ceedling-command-hooks +====================== + +Plugin for easily calling command line tools at various points in the build process + +Define any of these sections in :tools: to provide additional hooks to be called on demand: + +``` + :pre_mock_generate + :post_mock_generate + :pre_runner_generate + :post_runner_generate + :pre_compile_execute + :post_compile_execute + :pre_link_execute + :post_link_execute + :pre_test_fixture_execute + :pre_test + :post_test + :pre_release + :post_release + :pre_build + :post_build +``` + +Each of these tools can support an :executable string and an :arguments list, like so: + +``` +:tools: + :post_link_execute: + :executable: objcopy.exe + :arguments: + - ${1} #This is replaced with the executable name + - output.srec + - --strip-all +``` + +You may also specify an array of executables to be called in a particular place, like so: + +``` +:tools: + :post_test: + - :executable: echo + :arguments: "${1} was glorious!" + - :executable: echo + :arguments: + - it kinda made me cry a little. + - you? +``` + +Please note that it varies which arguments are being parsed down to the +hooks. For now see `command_hooks.rb` to figure out which suits you best. +Happy Tweaking! diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/command_hooks/lib/command_hooks.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/command_hooks/lib/command_hooks.rb new file mode 100644 index 0000000..4bf8b53 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/command_hooks/lib/command_hooks.rb @@ -0,0 +1,92 @@ +require 'ceedling/plugin' +require 'ceedling/constants' +class CommandHooks < Plugin + + attr_reader :config + + def setup + @config = { + :pre_mock_generate => ((defined? TOOLS_PRE_MOCK_GENERATE) ? TOOLS_PRE_MOCK_GENERATE : nil ), + :post_mock_generate => ((defined? TOOLS_POST_MOCK_GENERATE) ? TOOLS_POST_MOCK_GENERATE : nil ), + :pre_runner_generate => ((defined? TOOLS_PRE_RUNNER_GENERATE) ? TOOLS_PRE_RUNNER_GENERATE : nil ), + :post_runner_generate => ((defined? TOOLS_POST_RUNNER_GENERATE) ? TOOLS_POST_RUNNER_GENERATE : nil ), + :pre_compile_execute => ((defined? TOOLS_PRE_COMPILE_EXECUTE) ? TOOLS_PRE_COMPILE_EXECUTE : nil ), + :post_compile_execute => ((defined? TOOLS_POST_COMPILE_EXECUTE) ? TOOLS_POST_COMPILE_EXECUTE : nil ), + :pre_link_execute => ((defined? TOOLS_PRE_LINK_EXECUTE) ? TOOLS_PRE_LINK_EXECUTE : nil ), + :post_link_execute => ((defined? TOOLS_POST_LINK_EXECUTE) ? TOOLS_POST_LINK_EXECUTE : nil ), + :pre_test_fixture_execute => ((defined? TOOLS_PRE_TEST_FIXTURE_EXECUTE) ? TOOLS_PRE_TEST_FIXTURE_EXECUTE : nil ), + :post_test_fixture_execute => ((defined? TOOLS_POST_TEST_FIXTURE_EXECUTE) ? TOOLS_POST_TEST_FIXTURE_EXECUTE : nil ), + :pre_test => ((defined? TOOLS_PRE_TEST) ? TOOLS_PRE_TEST : nil ), + :post_test => ((defined? TOOLS_POST_TEST) ? TOOLS_POST_TEST : nil ), + :pre_release => ((defined? TOOLS_PRE_RELEASE) ? TOOLS_PRE_RELEASE : nil ), + :post_release => ((defined? TOOLS_POST_RELEASE) ? TOOLS_POST_RELEASE : nil ), + :pre_build => ((defined? TOOLS_PRE_BUILD) ? TOOLS_PRE_BUILD : nil ), + :post_build => ((defined? TOOLS_POST_BUILD) ? TOOLS_POST_BUILD : nil ), + :post_error => ((defined? TOOLS_POST_ERROR) ? TOOLS_POST_ERROR : nil ), + } + @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + end + + def pre_mock_generate(arg_hash); run_hook(:pre_mock_generate, arg_hash[:header_file] ); end + def post_mock_generate(arg_hash); run_hook(:post_mock_generate, arg_hash[:header_file] ); end + def pre_runner_generate(arg_hash); run_hook(:pre_runner_generate, arg_hash[:source ] ); end + def post_runner_generate(arg_hash); run_hook(:post_runner_generate, arg_hash[:runner_file] ); end + def pre_compile_execute(arg_hash); run_hook(:pre_compile_execute, arg_hash[:source_file] ); end + def post_compile_execute(arg_hash); run_hook(:post_compile_execute, arg_hash[:object_file] ); end + def pre_link_execute(arg_hash); run_hook(:pre_link_execute, arg_hash[:executable] ); end + def post_link_execute(arg_hash); run_hook(:post_link_execute, arg_hash[:executable] ); end + def pre_test_fixture_execute(arg_hash); run_hook(:pre_test_fixture_execute, arg_hash[:executable] ); end + def post_test_fixture_execute(arg_hash); run_hook(:post_test_fixture_execute, arg_hash[:executable] ); end + def pre_test(test); run_hook(:pre_test, test ); end + def post_test(test); run_hook(:post_test, test ); end + def pre_release; run_hook(:pre_release ); end + def post_release; run_hook(:post_release ); end + def pre_build; run_hook(:pre_build ); end + def post_build; run_hook(:post_build ); end + def post_error; run_hook(:post_error ); end + + private + + ## + # Run a hook if its available. + # + # :args: + # - hook: Name of the hook to run + # - name: Name of file (default: "") + # + # :return: + # shell_result. + # + def run_hook_step(hook, name="") + if (hook[:executable]) + # Handle argument replacemant ({$1}), and get commandline + cmd = @ceedling[:tool_executor].build_command_line( hook, [], name ) + shell_result = @ceedling[:tool_executor].exec(cmd[:line], cmd[:options]) + end + end + + ## + # Run a hook if its available. + # + # If __which_hook__ is an array, run each of them sequentially. + # + # :args: + # - which_hook: Name of the hook to run + # - name: Name of file + # + def run_hook(which_hook, name="") + if (@config[which_hook]) + @ceedling[:streaminator].stdout_puts("Running Hook #{which_hook}...", Verbosity::NORMAL) + if (@config[which_hook].is_a? Array) + @config[which_hook].each do |hook| + run_hook_step(hook, name) + end + elsif (@config[which_hook].is_a? Hash) + run_hook_step( @config[which_hook], name ) + else + @ceedling[:streaminator].stdout_puts("Hook #{which_hook} was poorly formed", Verbosity::COMPLAINT) + end + end + end +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/README.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/README.md new file mode 100644 index 0000000..8042775 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/README.md @@ -0,0 +1,250 @@ +# A Fake Function Framework Plug-in for Ceedling + +This is a plug-in for [Ceedling](https://github.com/ThrowTheSwitch/Ceedling) to use the [Fake Function Framework](https://github.com/meekrosoft/fff) for mocking instead of CMock. + +Using fff provides less strict mocking than CMock, and allows for more loosely-coupled tests. +And, when tests fail -- since you get the actual line number of the failure -- it's a lot easier to figure out what went wrong. + +## Installing the plug-in + +To use the plugin you need to 1) get the contents of this repo and 2) configure your project to use it. + +### Get the source + +The easiest way to get the source is to just clone this repo into the Ceedling plugin folder for your existing Ceedling project. +(Don't have a Ceedling project already? [Here are instructions to create one.](http://www.electronvector.com/blog/try-embedded-test-driven-development-right-now-with-ceedling)) +From within `/vendor/ceedling/plugins`, run: + +`git clone https://github.com/ElectronVector/fake_function_framework.git` + +This will create a new folder named `fake_function_framework` in the plugins folder. + +### Enable the plug-in. + +The plug-in is enabled from within your project.yml file. + +In the `:plugins` configuration, add `fake_function_framework` to the list of enabled plugins: + +```yaml +:plugins: + :load_paths: + - vendor/ceedling/plugins + :enabled: + - stdout_pretty_tests_report + - module_generator + - fake_function_framework +``` +*Note that you could put the plugin source in some other loaction. +In that case you'd need to add a new path the `:load_paths`.* + +## How to use it + +You use fff with Ceedling the same way you used to use CMock. +Modules can still be generated with the default module generator: `rake module:create[my_module]`. +If you want to "mock" `some_module.h` in your tests, just `#include "mock_some_module.h"`. +This creates a fake function for each of the functions defined in `some_module.h`. + +The name of each fake is the original function name with an appended `_fake`. +For example, if we're generating fakes for a stack module with `push` and `pop` functions, we would have the fakes `push_fake` and `pop_fake`. +These fakes are linked into our test executable so that any time our unit under test calls `push` or `pop` our fakes are called instead. + +Each of these fakes is actually a structure containing information about how the function was called, and what it might return. +We can use Unity to inspect these fakes in our tests, and verify the interactions of our units. +There is also a global structure named `fff` which we can use to check the sequence of calls. + +The fakes can also be configured to return particular values, so you can exercise the unit under test however you want. + +The examples below explain how to use fff to test a variety of module interactions. +Each example uses fakes for a "display" module, created from a display.h file with `#include "mock_display.h"`. The `display.h` file must exist and must contain the prototypes for the functions to be faked. + +### Test that a function was called once + +```c +void +test_whenTheDeviceIsReset_thenTheStatusLedIsTurnedOff() +{ + // When + event_deviceReset(); + + // Then + TEST_ASSERT_EQUAL(1, display_turnOffStatusLed_fake.call_count); +} +``` + +### Test that a function was NOT called + +```c +void +test_whenThePowerReadingIsLessThan5_thenTheStatusLedIsNotTurnedOn(void) +{ + // When + event_powerReadingUpdate(4); + + // Then + TEST_ASSERT_EQUAL(0, display_turnOnStatusLed_fake.call_count); +} +``` + +## Test that a single function was called with the correct argument + +```c +void +test_whenTheVolumeKnobIsMaxed_thenVolumeDisplayIsSetTo11(void) +{ + // When + event_volumeKnobMaxed(); + + // Then + TEST_ASSERT_EQUAL(1, display_setVolume_fake.call_count); + TEST_ASSERT_EQUAL(11, display_setVolume_fake.arg0_val); +} +``` + +## Test that calls are made in a particular sequence + +```c +void +test_whenTheModeSelectButtonIsPressed_thenTheDisplayModeIsCycled(void) +{ + // When + event_modeSelectButtonPressed(); + event_modeSelectButtonPressed(); + event_modeSelectButtonPressed(); + + // Then + TEST_ASSERT_EQUAL_PTR((void*)display_setModeToMinimum, fff.call_history[0]); + TEST_ASSERT_EQUAL_PTR((void*)display_setModeToMaximum, fff.call_history[1]); + TEST_ASSERT_EQUAL_PTR((void*)display_setModeToAverage, fff.call_history[2]); +} +``` + +## Fake a return value from a function + +```c +void +test_givenTheDisplayHasAnError_whenTheDeviceIsPoweredOn_thenTheDisplayIsPoweredDown(void) +{ + // Given + display_isError_fake.return_val = true; + + // When + event_devicePoweredOn(); + + // Then + TEST_ASSERT_EQUAL(1, display_powerDown_fake.call_count); +} +``` + +## Fake a function with a value returned by reference + +```c +void +test_givenTheUserHasTypedSleep_whenItIsTimeToCheckTheKeyboard_theDisplayIsPoweredDown(void) +{ + // Given + char mockedEntry[] = "sleep"; + void return_mock_value(char * entry, int length) + { + if (length > strlen(mockedEntry)) + { + strncpy(entry, mockedEntry, length); + } + } + display_getKeyboardEntry_fake.custom_fake = return_mock_value; + + // When + event_keyboardCheckTimerExpired(); + + // Then + TEST_ASSERT_EQUAL(1, display_powerDown_fake.call_count); +} +``` + +## Fake a function with a function pointer parameter + +``` +void +test_givenNewDataIsAvailable_whenTheDisplayHasUpdated_thenTheEventIsComplete(void) +{ + // A mock function for capturing the callback handler function pointer. + void(*registeredCallback)(void) = 0; + void mock_display_updateData(int data, void(*callback)(void)) + { + //Save the callback function. + registeredCallback = callback; + } + display_updateData_fake.custom_fake = mock_display_updateData; + + // Given + event_newDataAvailable(10); + + // When + if (registeredCallback != 0) + { + registeredCallback(); + } + + // Then + TEST_ASSERT_EQUAL(true, eventProcessor_isLastEventComplete()); +} +``` + +## Helper macros + +For convenience, there are also some helper macros that create new Unity-style asserts: + +- `TEST_ASSERT_CALLED(function)`: Asserts that a function was called once. +- `TEST_ASSERT_NOT_CALLED(function)`: Asserts that a function was never called. +- `TEST_ASSERT_CALLED_TIMES(times, function)`: Asserts that a function was called a particular number of times. +- `TEST_ASSERT_CALLED_IN_ORDER(order, function)`: Asserts that a function was called in a particular order. + +Here's how you might use one of these instead of simply checking the call_count value: + +```c +void +test_whenTheDeviceIsReset_thenTheStatusLedIsTurnedOff() +{ + // When + event_deviceReset(); + + // Then + // This how to directly use fff... + TEST_ASSERT_EQUAL(1, display_turnOffStatusLed_fake.call_count); + // ...and this is how to use the helper macro. + TEST_ASSERT_CALLED(display_turnOffStatusLed); +} +``` + +## Test setup + +All of the fake functions, and any fff global state are all reset automatically between each test. + +## CMock configuration + +Use still use some of the CMock configuration options for setting things like the mock prefix, and for including additional header files in the mock files. + +```yaml +:cmock: + :mock_prefix: mock_ + :includes: + - + :includes_h_pre_orig_header: + - + :includes_h_post_orig_header: + - + :includes_c_pre_header: + - + :includes_c_post_header: +``` + +## Running the tests + +There are unit and integration tests for the plug-in itself. +These are run with the default `rake` task. +The integration test runs the tests for the example project in examples/fff_example. +For the integration tests to succeed, this repository must be placed in a Ceedling tree in the plugins folder. + +## More examples + +There is an example project in examples/fff_example. +It shows how to use the plug-in with some full-size examples. diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/Rakefile b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/Rakefile new file mode 100644 index 0000000..bc55941 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/Rakefile @@ -0,0 +1,19 @@ +require 'rake' +require 'rspec/core/rake_task' + +desc "Run all rspecs" +RSpec::Core::RakeTask.new(:spec) do |t| + t.pattern = Dir.glob('spec/**/*_spec.rb') + t.rspec_opts = '--format documentation' + # t.rspec_opts << ' more options' +end + +desc "Run integration test on example" +task :integration_test do + chdir("./examples/fff_example") do + sh "rake clobber" + sh "rake test:all" + end +end + +task :default => [:spec, :integration_test] \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/project.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/project.yml new file mode 100644 index 0000000..6bda222 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/project.yml @@ -0,0 +1,71 @@ +--- + +# Notes: +# Sample project C code is not presently written to produce a release artifact. +# As such, release build options are disabled. +# This sample, therefore, only demonstrates running a collection of unit tests. + +:project: + :use_exceptions: FALSE + :use_test_preprocessor: TRUE + :use_auxiliary_dependencies: TRUE + :build_root: build +# :release_build: TRUE + :test_file_prefix: test_ + +#:release_build: +# :output: MyApp.out +# :use_assembly: FALSE + +:environment: + +:extension: + :executable: .out + +:paths: + :test: + - +:test/** + :source: + - src/** + :support: + +:defines: + # in order to add common defines: + # 1) remove the trailing [] from the :common: section + # 2) add entries to the :common: section (e.g. :test: has TEST defined) + :commmon: &common_defines [] + :test: + - *common_defines + - TEST + :test_preprocess: + - *common_defines + - TEST + +:cmock: + :mock_prefix: mock_ + :when_no_prototypes: :warn + :enforce_strict_ordering: TRUE + :plugins: + - :ignore + - :callback + :treat_as: + uint8: HEX8 + uint16: HEX16 + uint32: UINT32 + int8: INT8 + bool: UINT8 + +#:tools: +# Ceedling defaults to using gcc for compiling, linking, etc. +# As [:tools] is blank, gcc will be used (so long as it's in your system path) +# See documentation to configure a given toolchain for use + +:plugins: + :load_paths: + # This change from the default is for running Ceedling out of another folder. + - ../../../../plugins + :enabled: + - stdout_pretty_tests_report + - module_generator + - fake_function_framework +... diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/rakefile.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/rakefile.rb new file mode 100644 index 0000000..e484d5f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/rakefile.rb @@ -0,0 +1,7 @@ +# This change from the default is for running Ceedling out of another folder. +PROJECT_CEEDLING_ROOT = "../../../.." +load "#{PROJECT_CEEDLING_ROOT}/lib/ceedling.rb" + +Ceedling.load_project + +task :default => %w[ test:all release ] diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.c new file mode 100644 index 0000000..6a40323 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.c @@ -0,0 +1 @@ +#include "bar.h" diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.h new file mode 100644 index 0000000..febc586 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.h @@ -0,0 +1,14 @@ +#ifndef bar_H +#define bar_H + +#include "custom_types.h" + +void bar_turn_on(void); +void bar_print_message(const char * message); +void bar_print_message_formatted(const char * format, ...); +void bar_numbers(int one, int two, char three); +void bar_const_test(const char * a, char * const b, const int c); +custom_t bar_needs_custom_type(void); +const char * bar_return_const_ptr(int one); + +#endif // bar_H diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/custom_types.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/custom_types.h new file mode 100644 index 0000000..b426b32 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/custom_types.h @@ -0,0 +1,6 @@ +#ifndef custom_types_H +#define custom_types_H + +typedef int custom_t; + +#endif diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.c new file mode 100644 index 0000000..2f03449 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.c @@ -0,0 +1,7 @@ +#include +#include "display.h" + +void display_turnOffStatusLed(void) +{ + printf("Display: Status LED off"); +} \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.h new file mode 100644 index 0000000..def2996 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.h @@ -0,0 +1,16 @@ +#include + +void display_turnOffStatusLed(void); +void display_turnOnStatusLed(void); +void display_setVolume(int level); +void display_setModeToMinimum(void); +void display_setModeToMaximum(void); +void display_setModeToAverage(void); +bool display_isError(void); +void display_powerDown(void); +void display_updateData(int data, void(*updateCompleteCallback)(void)); + +/* + The entry is returned (up to `length` bytes) in the provided `entry` buffer. +*/ +void display_getKeyboardEntry(char * entry, int length); diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.c new file mode 100644 index 0000000..916a923 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.c @@ -0,0 +1,93 @@ +/* + This module implements some business logic to test. + + Signal events by calling the functions on the module. +*/ + +#include +#include +#include "event_processor.h" +#include "display.h" + +void event_deviceReset(void) +{ + //printf ("Device reset\n"); + display_turnOffStatusLed(); +} + +void event_volumeKnobMaxed(void) +{ + display_setVolume(11); +} + +void event_powerReadingUpdate(int powerReading) +{ + if (powerReading >= 5) + { + display_turnOnStatusLed(); + } +} + +void event_modeSelectButtonPressed(void) +{ + static int mode = 0; + + if (mode == 0) + { + display_setModeToMinimum(); + mode++; + } + else if (mode == 1) + { + display_setModeToMaximum(); + mode++; + } + else if (mode == 2) + { + display_setModeToAverage(); + mode++; + } + else + { + mode = 0; + } +} + +void event_devicePoweredOn(void) +{ + if (display_isError()) + { + display_powerDown(); + } +} + +void event_keyboardCheckTimerExpired(void) +{ + char userEntry[100]; + + display_getKeyboardEntry(userEntry, 100); + + if (strcmp(userEntry, "sleep") == 0) + { + display_powerDown(); + } +} + +static bool event_lastComplete = false; + +/* Function called when the display update is complete. */ +static void displayUpdateComplete(void) +{ + event_lastComplete = true; +} + +void event_newDataAvailable(int data) +{ + event_lastComplete = false; + display_updateData(data, displayUpdateComplete); +} + +bool eventProcessor_isLastEventComplete(void) +{ + return event_lastComplete; +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.h new file mode 100644 index 0000000..a79e68c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.h @@ -0,0 +1,11 @@ +#include + +void event_deviceReset(void); +void event_volumeKnobMaxed(void); +void event_powerReadingUpdate(int powerReading); +void event_modeSelectButtonPressed(void); +void event_devicePoweredOn(void); +void event_keyboardCheckTimerExpired(void); +void event_newDataAvailable(int data); + +bool eventProcessor_isLastEventComplete(void); diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.c new file mode 100644 index 0000000..c05b115 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.c @@ -0,0 +1,16 @@ +#include "foo.h" +#include "bar.h" +#include "subfolder/zzz.h" + +void foo_turn_on(void) { + bar_turn_on(); + zzz_sleep(1, "sleepy"); +} + +void foo_print_message(const char * message) { + bar_print_message(message); +} + +void foo_print_special_message(void) { + bar_print_message_formatted("The numbers are %d, %d and %d", 1, 2, 3); +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.h new file mode 100644 index 0000000..3fea699 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.h @@ -0,0 +1,8 @@ +#ifndef foo_H +#define foo_H + +void foo_turn_on(void); +void foo_print_message(const char * message); +void foo_print_special_message(void); + +#endif // foo_H diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.c new file mode 100644 index 0000000..85f370e --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.c @@ -0,0 +1 @@ +#include "zzz.h" diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.h new file mode 100644 index 0000000..32c5294 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.h @@ -0,0 +1,6 @@ +#ifndef zzz_H +#define zzz_H + +int zzz_sleep(int time, char * name); + +#endif // zzz_H diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_event_processor.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_event_processor.c new file mode 100644 index 0000000..9f99944 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_event_processor.c @@ -0,0 +1,155 @@ +#include "unity.h" +#include "event_processor.h" +#include "mock_display.h" +#include + +void setUp (void) +{ +} + +void tearDown (void) +{ +} +/* + Test that a single function was called. +*/ +void +test_whenTheDeviceIsReset_thenTheStatusLedIsTurnedOff() +{ + // When + event_deviceReset(); + + // Then + TEST_ASSERT_EQUAL(1, display_turnOffStatusLed_fake.call_count); + // or use the helper macro... + TEST_ASSERT_CALLED(display_turnOffStatusLed); +} + +/* + Test that a single function is NOT called. +*/ +void +test_whenThePowerReadingIsLessThan5_thenTheStatusLedIsNotTurnedOn(void) +{ + // When + event_powerReadingUpdate(4); + + // Then + TEST_ASSERT_EQUAL(0, display_turnOnStatusLed_fake.call_count); + // or use the helper macro... + TEST_ASSERT_NOT_CALLED(display_turnOffStatusLed); +} + +/* + Test that a single function was called with the correct arugment. +*/ +void +test_whenTheVolumeKnobIsMaxed_thenVolumeDisplayIsSetTo11(void) +{ + // When + event_volumeKnobMaxed(); + + // Then + TEST_ASSERT_EQUAL(1, display_setVolume_fake.call_count); + // or use the helper macro... + TEST_ASSERT_CALLED(display_setVolume); + TEST_ASSERT_EQUAL(11, display_setVolume_fake.arg0_val); +} + +/* + Test a sequence of calls. +*/ + +void +test_whenTheModeSelectButtonIsPressed_thenTheDisplayModeIsCycled(void) +{ + // When + event_modeSelectButtonPressed(); + event_modeSelectButtonPressed(); + event_modeSelectButtonPressed(); + + // Then + TEST_ASSERT_EQUAL_PTR((void *)display_setModeToMinimum, fff.call_history[0]); + TEST_ASSERT_EQUAL_PTR((void *)display_setModeToMaximum, fff.call_history[1]); + TEST_ASSERT_EQUAL_PTR((void *)display_setModeToAverage, fff.call_history[2]); + // or use the helper macros... + TEST_ASSERT_CALLED_IN_ORDER(0, display_setModeToMinimum); + TEST_ASSERT_CALLED_IN_ORDER(1, display_setModeToMaximum); + TEST_ASSERT_CALLED_IN_ORDER(2, display_setModeToAverage); +} + +/* + Mock a return value from a function. +*/ +void +test_givenTheDisplayHasAnError_whenTheDeviceIsPoweredOn_thenTheDisplayIsPoweredDown(void) +{ + // Given + display_isError_fake.return_val = true; + + // When + event_devicePoweredOn(); + + // Then + TEST_ASSERT_EQUAL(1, display_powerDown_fake.call_count); + // or use the helper macro... + TEST_ASSERT_CALLED(display_powerDown); +} + +/* + Mock a sequence of calls with return values. +*/ + +/* + Mocking a function with a value returned by reference. +*/ +void +test_givenTheUserHasTypedSleep_whenItIsTimeToCheckTheKeyboard_theDisplayIsPoweredDown(void) +{ + // Given + char mockedEntry[] = "sleep"; + void return_mock_value(char * entry, int length) + { + if (length > strlen(mockedEntry)) + { + strncpy(entry, mockedEntry, length); + } + } + display_getKeyboardEntry_fake.custom_fake = return_mock_value; + + // When + event_keyboardCheckTimerExpired(); + + // Then + TEST_ASSERT_EQUAL(1, display_powerDown_fake.call_count); + // or use the helper macro... + TEST_ASSERT_CALLED(display_powerDown); +} + +/* + Mock a function with a function pointer parameter. +*/ +void +test_givenNewDataIsAvailable_whenTheDisplayHasUpdated_thenTheEventIsComplete(void) +{ + // A mock function for capturing the callback handler function pointer. + void(*registeredCallback)(void) = 0; + void mock_display_updateData(int data, void(*callback)(void)) + { + //Save the callback function. + registeredCallback = callback; + } + display_updateData_fake.custom_fake = mock_display_updateData; + + // Given + event_newDataAvailable(10); + + // When + if (registeredCallback != 0) + { + registeredCallback(); + } + + // Then + TEST_ASSERT_EQUAL(true, eventProcessor_isLastEventComplete()); +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_foo.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_foo.c new file mode 100644 index 0000000..12dd61a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_foo.c @@ -0,0 +1,47 @@ +#include "unity.h" +#include "foo.h" +#include "mock_bar.h" +#include "mock_zzz.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_foo(void) +{ + //When + foo_turn_on(); + + //Then + TEST_ASSERT_EQUAL(1, bar_turn_on_fake.call_count); + TEST_ASSERT_EQUAL(1, zzz_sleep_fake.call_count); + TEST_ASSERT_EQUAL_STRING("sleepy", zzz_sleep_fake.arg1_val); +} + +void test_foo_again(void) +{ + //When + foo_turn_on(); + + //Then + TEST_ASSERT_EQUAL(1, bar_turn_on_fake.call_count); +} + +void test_foo_mock_with_const(void) +{ + foo_print_message("123"); + + TEST_ASSERT_EQUAL(1, bar_print_message_fake.call_count); + TEST_ASSERT_EQUAL_STRING("123", bar_print_message_fake.arg0_val); +} + +void test_foo_mock_with_variable_args(void) +{ + foo_print_special_message(); + TEST_ASSERT_EQUAL(1, bar_print_message_formatted_fake.call_count); + TEST_ASSERT_EQUAL_STRING("The numbers are %d, %d and %d", bar_print_message_formatted_fake.arg0_val); +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb new file mode 100644 index 0000000..51a90b3 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb @@ -0,0 +1,87 @@ +require 'ceedling/plugin' +require 'fff_mock_generator' + +class FakeFunctionFramework < Plugin + + # Set up Ceedling to use this plugin. + def setup + # Get the location of this plugin. + @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + puts "Using fake function framework (fff)..." + + # Switch out the cmock_builder with our own. + @ceedling[:cmock_builder].cmock = FffMockGeneratorForCMock.new(@ceedling[:setupinator].config_hash[:cmock]) + + # Add the path to fff.h to the include paths. + COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR << "#{@plugin_root}/vendor/fff" + COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR << "#{@plugin_root}/src" + end + + def post_runner_generate(arg_hash) + # After the test runner file has been created, append the FFF globals + # definition to the end of the test runner. These globals will be shared by + # all mocks linked into the test. + File.open(arg_hash[:runner_file], 'a') do |f| + f.puts + f.puts "//=======Defintions of FFF variables=====" + f.puts %{#include "fff.h"} + f.puts "DEFINE_FFF_GLOBALS;" + end + end + +end # class FakeFunctionFramework + +class FffMockGeneratorForCMock + + def initialize(options=nil) + @cm_config = CMockConfig.new(options) + @cm_parser = CMockHeaderParser.new(@cm_config) + @silent = (@cm_config.verbosity < 2) + + # These are the additional files to include in the mock files. + @includes_h_pre_orig_header = (@cm_config.includes || @cm_config.includes_h_pre_orig_header || []).map{|h| h =~ /" + output.puts %{#include "fff.h"} + output.puts %{#include "#{mock_name}.h"} + end + + def self.write_function_definitions(parsed_header, output) + write_function_macros("DEFINE", parsed_header, output) + end + + def self.write_control_function_definitions(mock_name, parsed_header, output) + output.puts "void #{mock_name}_Init(void)" + output.puts "{" + # In the init function, reset the FFF globals. These are used for things + # like the call history. + output.puts " FFF_RESET_HISTORY();" + + # Also, reset all of the fakes. + if parsed_header[:functions] + parsed_header[:functions].each do |function| + output.puts " RESET_FAKE(#{function[:name]})" + end + end + output.puts "}" + output.puts "void #{mock_name}_Verify(void)" + output.puts "{" + output.puts "}" + output.puts "void #{mock_name}_Destroy(void)" + output.puts "{" + output.puts "}" + end + +# Shared functions. + + def self.write_extra_includes(includes, output) + if includes + includes.each {|inc| output.puts "#include #{inc}\n"} + end + end + + def self.write_function_macros(macro_type, parsed_header, output) + return unless parsed_header.key?(:functions) + parsed_header[:functions].each do |function| + name = function[:name] + return_type = function[:return][:type] + if function.has_key? :modifier + # Prepend any modifier. If there isn't one, trim any leading whitespace. + return_type = "#{function[:modifier]} #{return_type}".lstrip + end + arg_count = function[:args].size + + # Check for variable arguments. + var_arg_suffix = "" + if function[:var_arg] + # If there are are variable arguments, then we need to add this argument + # to the count, update the suffix that will get added to the macro. + arg_count += 1 + var_arg_suffix = "_VARARG" + end + + # Generate the correct macro. + if return_type == 'void' + output.print "#{macro_type}_FAKE_VOID_FUNC#{arg_count}#{var_arg_suffix}(#{name}" + else + output.print "#{macro_type}_FAKE_VALUE_FUNC#{arg_count}#{var_arg_suffix}(#{return_type}, #{name}" + end + + # Append each argument type. + function[:args].each do |arg| + output.print ", " + if arg[:const?] + output.print "const " + end + output.print "#{arg[:type]}" + end + + # If this argument list ends with a variable argument, add it here at the end. + if function[:var_arg] + output.print ", ..." + end + + # Close the declaration. + output.puts ");" + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_header_generator_spec.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_header_generator_spec.rb new file mode 100644 index 0000000..e6ac11d --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_header_generator_spec.rb @@ -0,0 +1,304 @@ +require 'stringio' +require 'fff_mock_generator.rb' +require 'header_generator.rb' + +# Test the contents of the .h file created for the mock. +describe "FffMockGenerator.create_mock_header" do + + context "when there is nothing to mock," do + let(:mock_header) { + parsed_header = {} + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated header file starts with an opening include guard" do + expect(mock_header).to start_with( + "#ifndef mock_display_H\n" + + "#define mock_display_H") + end + it "then the generated file ends with a closing include guard" do + expect(mock_header).to end_with( + "#endif // mock_display_H\n") + end + it "then the generated file includes the fff header" do + expect(mock_header).to include( + %{#include "fff.h"\n}) + end + it "then the generated file has a prototype for the init function" do + expect(mock_header).to include( + "void mock_display_Init(void);") + end + it "then the generated file has a prototype for the verify function" do + expect(mock_header).to include( + "void mock_display_Verify(void);") + end + it "then the generated file has a prototype for the destroy function" do + expect(mock_header).to include( + "void mock_display_Destroy(void);") + end + end + + context "when there is a function with no args and a void return," do + let(:mock_header) { + parsed_header = create_cmock_style_parsed_header( + [{:name => 'display_turnOffStatusLed', :return_type => 'void'}]) + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated header file starts with an opening include guard" do + expect(mock_header).to start_with( + "#ifndef mock_display_H\n" + + "#define mock_display_H") + end + it "then the generated header file contains a fake function declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VOID_FUNC0(display_turnOffStatusLed);" + ) + end + it "then the generated file ends with a closing include guard" do + expect(mock_header).to end_with( + "#endif // mock_display_H\n") + end + end + + context "when there is a function with no args and a bool return," do + let(:mock_header) { + parsed_header = create_cmock_style_parsed_header( + [{:name => 'display_isError', :return_type => 'bool'}]) + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the fake function declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VALUE_FUNC0(bool, display_isError);" + ) + end + end + + context "when there is a function with no args and an int return," do + let(:mock_header) { + parsed_header = create_cmock_style_parsed_header( + [{:name => 'display_isError', :return_type => 'int'}]) + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the fake function declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VALUE_FUNC0(int, display_isError);" + ) + end + end + + context "when there is a function with args and a void return," do + let(:mock_header) { + parsed_header = create_cmock_style_parsed_header( + [{:name => 'display_setVolume', :return_type => 'void', :args => ['int']}]) + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the fake function declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VOID_FUNC1(display_setVolume, int);" + ) + end + end + + context "when there is a function with args and a value return," do + let(:mock_header) { + parsed_header = create_cmock_style_parsed_header( + [{:name => 'a_function', :return_type => 'int', :args => ['char *']}]) + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the fake function declaration" do + expect(mock_header).to include( + "FAKE_VALUE_FUNC1(int, a_function, char *);" + ) + end + end + + context "when there is a function with many args and a void return," do + let(:mock_header) { + parsed_header = create_cmock_style_parsed_header( + [{:name => 'a_function', :return_type => 'void', + :args => ['int', 'char *', 'int', 'int', 'bool', 'applesauce']}]) + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the fake function declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VOID_FUNC6(a_function, int, char *, int, int, bool, applesauce);" + ) + end + end + + context "when there are multiple functions," do + let(:mock_header) { + parsed_header = create_cmock_style_parsed_header( + [ {:name => 'a_function', :return_type => 'int', :args => ['char *']}, + {:name => 'another_function', :return_type => 'void'}, + {:name => 'three', :return_type => 'bool', :args => ['float', 'int']} + ]) + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the first fake function declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VALUE_FUNC1(int, a_function, char *);" + ) + end + it "then the generated file contains the second fake function declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VOID_FUNC0(another_function);" + ) + end + it "then the generated file contains the third fake function declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VALUE_FUNC2(bool, three, float, int);" + ) + end + end + + context "when there is a typedef," do + let(:mock_header) { + parsed_header = create_cmock_style_parsed_header( + nil, ["typedef void (*displayCompleteCallback) (void);"]) + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the typedef" do + expect(mock_header).to include( + "typedef void (*displayCompleteCallback) (void);" + ) + end + end + + context "when there is a void function with variable arguments" do + let(:mock_header){ + parsed_header = {} + parsed_header[:functions] = [{ + :name => "function_with_var_args", + :return => {:type => "void"}, + :var_arg => "...", + :args => [{:type => 'char *'}] + }] + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the vararg declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VOID_FUNC2_VARARG(function_with_var_args, char *, ...)" + ) + end + end + + context "when there is a function with a return value and variable arguments" do + let(:mock_header){ + parsed_header = {} + parsed_header[:functions] = [{ + :name => "function_with_var_args", + :return => {:type => "int"}, + :var_arg => "...", + :args => [{:type => 'char *'}] + }] + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the vararg declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VALUE_FUNC2_VARARG(int, function_with_var_args, char *, ...)" + ) + end + end + + context "when there is a void function with variable arguments and " + + "additional arguments" do + let(:mock_header){ + parsed_header = {} + parsed_header[:functions] = [{ + :name => "function_with_var_args", + :return => {:type => "void"}, + :var_arg => "...", + :args => [{:type => 'char *'}, {:type => 'int'}] + }] + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the vararg declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VOID_FUNC3_VARARG(function_with_var_args, char *, int, ...)" + ) + end + end + + context "when there is a function with a pointer to a const value" do + let(:mock_header){ + parsed_header = {} + parsed_header[:functions] = [{ + :name => "const_test_function", + :return => {:type => "void"}, + :args => [{:type => "char *", :name => "a", :ptr? => false, :const? => true}, + {:type => "char *", :name => "b", :ptr? => false, :const? => false}] + }] + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the correct const argument in the declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VOID_FUNC2(const_test_function, const char *, char *)" + ) + end + end + + context "when there is a function that returns a const pointer" do + let(:mock_header){ + parsed_header = {} + parsed_header[:functions] = [{ + :name => "return_const_pointer_test_function", + :modifier => "const", + :return => {:type => "char *" }, + :args => [{:type => "int", :name => "a"}] + }] + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the correct const return value in the declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VALUE_FUNC1(const char *, return_const_pointer_test_function, int)" + ) + end + end + + context "when there is a function that returns a const int" do + let(:mock_header){ + parsed_header = {} + parsed_header[:functions] = [{ + :name => "return_const_int_test_function", + :modifier => "const", + :return => {:type => "int" }, + :args => [] + }] + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header) + } + it "then the generated file contains the correct const return value in the declaration" do + expect(mock_header).to include( + "DECLARE_FAKE_VALUE_FUNC0(const int, return_const_int_test_function)" + ) + end + end + + context "when there are pre-includes" do + let(:mock_header) { + parsed_header = {} + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header, + [%{"another_header.h"}]) + } + it "then they are included before the other files" do + expect(mock_header).to include( + %{#include "another_header.h"\n} + + %{#include "fff.h"} + ) + end + end + + context "when there are post-includes" do + let(:mock_header) { + parsed_header = {} + FffMockGenerator.create_mock_header("display", "mock_display", parsed_header, + nil, [%{"another_header.h"}]) + } + it "then they are included after the other files" do + expect(mock_header).to include( + %{#include "display.h"\n} + + %{#include "another_header.h"\n} + ) + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_source_generator_spec.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_source_generator_spec.rb new file mode 100644 index 0000000..364f852 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_source_generator_spec.rb @@ -0,0 +1,149 @@ +require 'stringio' +require 'fff_mock_generator.rb' + +# Test the contents of the .c file created for the mock. +describe "FffMockGenerator.create_mock_source" do + + context "when there is nothing to mock," do + let(:mock_source) { + parsed_header = {} + FffMockGenerator.create_mock_source("mock_my_module", parsed_header) + } + it "then the generated file includes the fff header" do + expect(mock_source).to include( + # fff.h also requires including string.h + %{#include \n} + + %{#include "fff.h"} + ) + end + it "then the generated file includes the mock header" do + expect(mock_source).to include( + %{#include "mock_my_module.h"\n} + ) + end + it "then the generated file defines the init function" do + expect(mock_source).to include( + "void mock_my_module_Init(void)\n" + + "{\n" + + " FFF_RESET_HISTORY();\n" + + "}" + ) + end + it "then the generated file defines the verify function" do + expect(mock_source).to include( + "void mock_my_module_Verify(void)\n" + + "{\n" + + "}" + ) + end + it "then the generated file defines the destroy function" do + expect(mock_source).to include( + "void mock_my_module_Destroy(void)\n" + + "{\n" + + "}" + ) + end + end + + context "when there are multiple functions," do + let(:mock_source) { + parsed_header = create_cmock_style_parsed_header( + [ {:name => 'a_function', :return_type => 'int', :args => ['char *']}, + {:name => 'another_function', :return_type => 'void'}, + {:name => 'three', :return_type => 'bool', :args => ['float', 'int']} + ]) + FffMockGenerator.create_mock_source("mock_display", parsed_header) + } + it "then the generated file contains the first fake function definition" do + expect(mock_source).to include( + "DEFINE_FAKE_VALUE_FUNC1(int, a_function, char *);" + ) + end + it "then the generated file contains the second fake function definition" do + expect(mock_source).to include( + "DEFINE_FAKE_VOID_FUNC0(another_function);" + ) + end + it "then the generated file contains the third fake function definition" do + expect(mock_source).to include( + "DEFINE_FAKE_VALUE_FUNC2(bool, three, float, int);" + ) + end + it "then the init function resets all of the fakes" do + expect(mock_source).to include( + "void mock_display_Init(void)\n" + + "{\n" + + " FFF_RESET_HISTORY();\n" + + " RESET_FAKE(a_function)\n" + + " RESET_FAKE(another_function)\n" + + " RESET_FAKE(three)\n" + + "}" + ) + end + end + + context "when there is a void function with variable arguments and " + + "additional arguments" do + let(:mock_source){ + parsed_header = {} + parsed_header[:functions] = [{ + :name => "function_with_var_args", + :return => {:type => "void"}, + :var_arg => "...", + :args => [{:type => 'char *'}, {:type => 'int'}] + }] + FffMockGenerator.create_mock_source("mock_display", parsed_header) + } + it "then the generated file contains the vararg definition" do + expect(mock_source).to include( + "DEFINE_FAKE_VOID_FUNC3_VARARG(function_with_var_args, char *, int, ...)" + ) + end + end + + context "when there is a function with a pointer to a const value" do + let(:mock_source){ + parsed_header = {} + parsed_header[:functions] = [{ + :name => "const_test_function", + :return => {:type => "void"}, + :args => [{:type => "char *", :name => "a", :ptr? => false, :const? => true}, + {:type => "char *", :name => "b", :ptr? => false, :const? => false}] + }] + FffMockGenerator.create_mock_source("mock_display", parsed_header) + } + it "then the generated file contains the correct const argument in the declaration" do + expect(mock_source).to include( + "DEFINE_FAKE_VOID_FUNC2(const_test_function, const char *, char *)" + ) + end + end + + context "when there are pre-includes" do + let(:mock_source) { + parsed_source = {} + FffMockGenerator.create_mock_source("mock_display", parsed_source, + [%{"another_header.h"}]) + } + it "then they are included before the other files" do + expect(mock_source).to include( + %{#include "another_header.h"\n} + + %{#include } + ) + end + end + + context "when there are post-includes" do + let(:mock_source) { + parsed_source = {} + FffMockGenerator.create_mock_source("mock_display", parsed_source, + nil, [%{"another_header.h"}]) + } + it "then they are included before the other files" do + expect(mock_source).to include( + %{#include "mock_display.h"\n} + + %{#include "another_header.h"\n} + ) + end + end +end \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/header_generator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/header_generator.rb new file mode 100644 index 0000000..cda2784 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/header_generator.rb @@ -0,0 +1,51 @@ +# Create a CMock-style parsed header hash. This the type of hash created by +# CMock when parsing header files for automock generation. It contains all of +# includes, typedefs and functions (with return types and arguments) parsed from +# the header file. +def create_cmock_style_parsed_header(functions, typedefs = nil) + parsed_header = { + :includes => nil, + :functions => [], + :typedefs => [] + } + + # Add the typedefs. + if typedefs + typedefs.each do |typedef| + parsed_header[:typedefs] << typedef + end + end + + # Add the functions. + if functions + functions.each do |function| + # Build the array of arguments. + args = [] + if function.key?(:args) + function[:args].each do |arg| + args << { + :type => arg + } + end + end + parsed_header[:functions] << { + :name => function[:name], + :modifier => "", + :return => { + :type => function[:return_type], + :name => "cmock_to_return", + :ptr? => false, + :const? => false, + :str => "void cmock_to_return", + :void? => true + }, + :var_arg => nil, + :args_string => "void", + :args => args, + :args_call => "", + :contains_ptr? => false + } + end + end + parsed_header +end \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/spec_helper.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/spec_helper.rb new file mode 100644 index 0000000..25dc80a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/spec_helper.rb @@ -0,0 +1,96 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/src/fff_unity_helper.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/src/fff_unity_helper.h new file mode 100644 index 0000000..de3db44 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/src/fff_unity_helper.h @@ -0,0 +1,33 @@ +#ifndef fff_unity_helper_H +#define fff_unity_helper_H + +/* + FFF helper macros for Unity. +*/ + +/* + Fail if the function was not called the expected number of times. +*/ +#define TEST_ASSERT_CALLED_TIMES(times_, function_) \ + TEST_ASSERT_EQUAL_MESSAGE(times_, \ + function_ ## _fake.call_count, \ + "Function " #function_ " called the incorrect number of times.") +/* + Fail if the function was not called exactly once. +*/ +#define TEST_ASSERT_CALLED(function_) TEST_ASSERT_CALLED_TIMES(1, function_) + +/* + Fail if the function was called 1 or more times. +*/ +#define TEST_ASSERT_NOT_CALLED(function_) TEST_ASSERT_CALLED_TIMES(0, function_) + +/* + Fail if the function was not called in this particular order. +*/ +#define TEST_ASSERT_CALLED_IN_ORDER(order_, function_) \ + TEST_ASSERT_EQUAL_PTR_MESSAGE((void *) function_, \ + fff.call_history[order_], \ + "Function " #function_ " not called in order " #order_ ) + +#endif \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/README.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/README.md new file mode 100644 index 0000000..096ffa1 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/README.md @@ -0,0 +1,101 @@ +ceedling-gcov +============= + +# Plugin Overview + +Plugin for integrating GNU GCov code coverage tool into Ceedling projects. +Currently only designed for the gcov command (like LCOV for example). In the +future we could configure this to work with other code coverage tools. + +This plugin currently uses `gcovr` to generate HTML and/or XML reports as a +utility. The normal gcov plugin _must_ be run first for this report to generate. + +## Installation + +Gcovr can be installed via pip like so: + +``` +pip install gcovr +``` + +## Configuration + +The gcov plugin supports configuration options via your `project.yml` provided +by Ceedling. + +Generation of HTML reports may be enabled or disabled with the following +config. Set to `true` to enable or set to `false` to disable. + +``` +:gcov: + :html_report: true +``` + +Generation of XML reports may be enabled or disabled with the following +config. Set to `true` to enable or set to `false` to disable. + +``` +:gcov: + :xml_report: true +``` + +There are two types of gcovr HTML reports that can be configured in your +`project.yml`. To create a basic HTML report, with only the overall file +information, use the following config. + +``` +:gcov: + :html_report_type: basic +``` + +To create a detailed HTML report, with line by line breakdown of the +coverage, use the following config. + +``` +:gcov: + :html_report_type: detailed +``` + +There are a number of options to control which files are considered part of +the coverage report. Most often, we only care about coverage on our source code, and not +on tests or automatically generated mocks, runners, etc. However, there are times +where this isn't true... or there are times where we've moved ceedling's directory +structure so that the project file isn't at the root of the project anymore. In these +cases, you may need to tweak the following: + +``` +:gcov: + :report_root: "." + :report_exclude: "^build|^vendor|^test|^support" + :report_include: "^src" +``` + +One important note about html_report_root: gcovr will only take a single root folder, unlike +Ceedling's ability to take as many as you like. So you will need to choose a folder which is +a superset of ALL the folders you want, and then use the include or exclude options to set up +patterns of files to pay attention to or ignore. It's not ideal, but it works. + +Finally, there are a number of settings which can be specified in order to adjust the +default behaviors of gcov: + +``` +:gcov: + :html_medium_threshold: 75 + :html_high_threshold: 90 + :fail_under_line: 30 + :fail_under_branch: 30 +``` + +These HTML and XML reports will be found in `build/artifacts/gcov`. + +## Example Usage + +``` +ceedling gcov:all utils:gcov +``` + +## To-Do list + +- Generate overall report (combined statistics from all files with coverage) +- Generate coverage output files +- Easier option override for better customisation diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/assets/template.erb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/assets/template.erb new file mode 100644 index 0000000..5e5a174 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/assets/template.erb @@ -0,0 +1,15 @@ +% function_string = hash[:coverage][:functions].to_s +% branch_string = hash[:coverage][:branches].to_s +% format_string = "%#{[function_string.length, branch_string.length].max}i" +<%=@ceedling[:plugin_reportinator].generate_banner("#{GCOV_ROOT_NAME.upcase}: CODE COVERAGE SUMMARY")%> +% if (!hash[:coverage][:functions].nil?) +FUNCTIONS: <%=sprintf(format_string, hash[:coverage][:functions])%>% +% else +FUNCTIONS: none +% end +% if (!hash[:coverage][:branches].nil?) +BRANCHES: <%=sprintf(format_string, hash[:coverage][:branches])%>% +% else +BRANCHES: none +% end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/config/defaults.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/config/defaults.yml new file mode 100644 index 0000000..13bac55 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/config/defaults.yml @@ -0,0 +1,73 @@ +--- + +:tools: + :gcov_compiler: + :executable: gcc + :arguments: + - -g + - -fprofile-arcs + - -ftest-coverage + - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE + - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR + - -DGCOV_COMPILER + - -DCODE_COVERAGE + - -c "${1}" + - -o "${2}" + :gcov_linker: + :executable: gcc + :arguments: + - -fprofile-arcs + - -ftest-coverage + - ${1} + - -o ${2} + - ${3} + :gcov_fixture: + :executable: ${1} + :gcov_report: + :executable: gcov + :arguments: + - -n + - -p + - -b + - -o "$": GCOV_BUILD_OUTPUT_PATH + - "\"${1}\"" + :gcov_post_report: + :executable: gcovr + :optional: TRUE + :arguments: + - -p + - -b + - ${1} + - --html + - -o GcovCoverageResults.html + :gcov_post_report_basic: + :executable: gcovr + :optional: TRUE + :arguments: + - -p + - -b + - ${1} + - --html + - -o "$": GCOV_ARTIFACTS_FILE + :gcov_post_report_advanced: + :executable: gcovr + :optional: TRUE + :arguments: + - -p + - -b + - ${1} + - --html + - --html-details + - -o "$": GCOV_ARTIFACTS_FILE + :gcov_post_report_xml: + :executable: gcovr + :optional: TRUE + :arguments: + - -p + - -b + - ${1} + - --xml + - -o "$": GCOV_ARTIFACTS_FILE_XML + +... diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/gcov.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/gcov.rake new file mode 100644 index 0000000..3acab85 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/gcov.rake @@ -0,0 +1,220 @@ +directory(GCOV_BUILD_OUTPUT_PATH) +directory(GCOV_RESULTS_PATH) +directory(GCOV_ARTIFACTS_PATH) +directory(GCOV_DEPENDENCIES_PATH) + +CLEAN.include(File.join(GCOV_BUILD_OUTPUT_PATH, '*')) +CLEAN.include(File.join(GCOV_RESULTS_PATH, '*')) +CLEAN.include(File.join(GCOV_ARTIFACTS_PATH, '*')) +CLEAN.include(File.join(GCOV_DEPENDENCIES_PATH, '*')) + +CLOBBER.include(File.join(GCOV_BUILD_PATH, '**/*')) + +rule(/#{GCOV_BUILD_OUTPUT_PATH}\/#{'.+\\' + EXTENSION_OBJECT}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_compilation_input_file(task_name) + end + ]) do |object| + + if File.basename(object.source) =~ /^(#{PROJECT_TEST_FILE_PREFIX}|#{CMOCK_MOCK_PREFIX}|#{GCOV_IGNORE_SOURCES.join('|')})/i + @ceedling[:generator].generate_object_file( + TOOLS_GCOV_COMPILER, + OPERATION_COMPILE_SYM, + GCOV_SYM, + object.source, + object.name, + @ceedling[:file_path_utils].form_test_build_list_filepath(object.name) + ) + else + @ceedling[GCOV_SYM].generate_coverage_object_file(object.source, object.name) + end +end + +rule(/#{GCOV_BUILD_OUTPUT_PATH}\/#{'.+\\' + EXTENSION_EXECUTABLE}$/) do |bin_file| + lib_args = @ceedling[:test_invoker].convert_libraries_to_arguments() + + @ceedling[:generator].generate_executable_file( + TOOLS_GCOV_LINKER, + GCOV_SYM, + bin_file.prerequisites, + bin_file.name, + lib_args, + @ceedling[:file_path_utils].form_test_build_map_filepath(bin_file.name) + ) +end + +rule(/#{GCOV_RESULTS_PATH}\/#{'.+\\' + EXTENSION_TESTPASS}$/ => [ + proc do |task_name| + @ceedling[:file_path_utils].form_test_executable_filepath(task_name) + end + ]) do |test_result| + @ceedling[:generator].generate_test_results(TOOLS_GCOV_FIXTURE, GCOV_SYM, test_result.source, test_result.name) +end + +rule(/#{GCOV_DEPENDENCIES_PATH}\/#{'.+\\' + EXTENSION_DEPENDENCIES}$/ => [ + proc do |task_name| + @ceedling[:file_finder].find_compilation_input_file(task_name) + end + ]) do |dep| + @ceedling[:generator].generate_dependencies_file( + TOOLS_TEST_DEPENDENCIES_GENERATOR, + GCOV_SYM, + dep.source, + File.join(GCOV_BUILD_OUTPUT_PATH, File.basename(dep.source).ext(EXTENSION_OBJECT)), + dep.name + ) +end + +task directories: [GCOV_BUILD_OUTPUT_PATH, GCOV_RESULTS_PATH, GCOV_DEPENDENCIES_PATH, GCOV_ARTIFACTS_PATH] + +namespace GCOV_SYM do + task source_coverage: COLLECTION_ALL_SOURCE.pathmap("#{GCOV_BUILD_OUTPUT_PATH}/%n#{@ceedling[:configurator].extension_object}") + + desc 'Run code coverage for all tests' + task all: [:directories] do + @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config) + @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, GCOV_SYM) + @ceedling[:configurator].restore_config + end + + desc 'Run single test w/ coverage ([*] real test or source file name, no path).' + task :* do + message = "\nOops! '#{GCOV_ROOT_NAME}:*' isn't a real task. " \ + "Use a real test or source file name (no path) in place of the wildcard.\n" \ + "Example: rake #{GCOV_ROOT_NAME}:foo.c\n\n" + + @ceedling[:streaminator].stdout_puts(message) + end + + desc 'Run tests by matching regular expression pattern.' + task :pattern, [:regex] => [:directories] do |_t, args| + matches = [] + + COLLECTION_ALL_TESTS.each do |test| + matches << test if test =~ /#{args.regex}/ + end + + if !matches.empty? + @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config) + @ceedling[:test_invoker].setup_and_invoke(matches, GCOV_SYM, force_run: false) + @ceedling[:configurator].restore_config + else + @ceedling[:streaminator].stdout_puts("\nFound no tests matching pattern /#{args.regex}/.") + end + end + + desc 'Run tests whose test path contains [dir] or [dir] substring.' + task :path, [:dir] => [:directories] do |_t, args| + matches = [] + + COLLECTION_ALL_TESTS.each do |test| + matches << test if File.dirname(test).include?(args.dir.tr('\\', '/')) + end + + if !matches.empty? + @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config) + @ceedling[:test_invoker].setup_and_invoke(matches, GCOV_SYM, force_run: false) + @ceedling[:configurator].restore_config + else + @ceedling[:streaminator].stdout_puts("\nFound no tests including the given path or path component.") + end + end + + desc 'Run code coverage for changed files' + task delta: [:directories] do + @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config) + @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, GCOV_SYM, force_run: false) + @ceedling[:configurator].restore_config + end + + # use a rule to increase efficiency for large projects + # gcov test tasks by regex + rule(/^#{GCOV_TASK_ROOT}\S+$/ => [ + proc do |task_name| + test = task_name.sub(/#{GCOV_TASK_ROOT}/, '') + test = "#{PROJECT_TEST_FILE_PREFIX}#{test}" unless test.start_with?(PROJECT_TEST_FILE_PREFIX) + @ceedling[:file_finder].find_test_from_file_path(test) + end + ]) do |test| + @ceedling[:rake_wrapper][:directories].invoke + @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config) + @ceedling[:test_invoker].setup_and_invoke([test.source], GCOV_SYM) + @ceedling[:configurator].restore_config + end +end + +if PROJECT_USE_DEEP_DEPENDENCIES + namespace REFRESH_SYM do + task GCOV_SYM do + @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config) + @ceedling[:test_invoker].refresh_deep_dependencies + @ceedling[:configurator].restore_config + end + end +end + +namespace UTILS_SYM do + def gcov_args_builder(opts) + args = "" + args += "-r \"#{opts[:gcov_report_root] || '.'}\" " + args += "-f \"#{opts[:gcov_report_include]}\" " unless opts[:gcov_report_include].nil? + args += "-e \"#{opts[:gcov_report_exclude] || GCOV_FILTER_EXCLUDE}\" " + [ :gcov_fail_under_line, :gcov_fail_under_branch, :gcov_html_medium_threshold, :gcov_html_high_threshold].each do |opt| + args += "--#{opt.to_s.gsub('_','-').sub(/:?gcov-/,'')} #{opts[opt]} " unless opts[opt].nil? + end + return args + end + + desc 'Create gcov code coverage html report (must run ceedling gcov first)' + task GCOV_SYM do + + if !File.directory? GCOV_ARTIFACTS_PATH + FileUtils.mkdir_p GCOV_ARTIFACTS_PATH + end + + args = gcov_args_builder(@ceedling[:configurator].project_config_hash) + + if @ceedling[:configurator].project_config_hash[:gcov_html_report].nil? + puts "In your project.yml, define: \n\n:gcov:\n :html_report:\n\n to true or false to refine this feature." + puts "For now, assumimg you want an html report generated." + html_enabled = true + else + html_enabled = @ceedling[:configurator].project_config_hash[:gcov_html_report] + end + + if @ceedling[:configurator].project_config_hash[:gcov_xml_report].nil? + puts "In your project.yml, define: \n\n:gcov:\n :xml_report:\n\n to true or false to refine this feature." + puts "For now, assumimg you do not want an xml report generated." + xml_enabled = false + else + xml_enabled = @ceedling[:configurator].project_config_hash[:gcov_xml_report] + end + + if html_enabled + if @ceedling[:configurator].project_config_hash[:gcov_html_report_type] == 'basic' + puts "Creating a basic html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_BASIC, [], args) + @ceedling[:tool_executor].exec(command[:line], command[:options]) + elsif @ceedling[:configurator].project_config_hash[:gcov_html_report_type] == 'detailed' + puts "Creating a detailed html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_ADVANCED, [], args) + @ceedling[:tool_executor].exec(command[:line], command[:options]) + + else + puts "In your project.yml, define: \n\n:gcov:\n :html_report_type:\n\n to basic or detailed to refine this feature." + puts "For now, just creating basic." + puts "Creating a basic html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_BASIC, [], args) + @ceedling[:tool_executor].exec(command[:line], command[:options]) + end + end + + if xml_enabled + puts "Creating an xml report of gcov results in #{GCOV_ARTIFACTS_FILE_XML}..." + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_XML, [], filter) + @ceedling[:tool_executor].exec(command[:line], command[:options]) + end + + puts "Done." + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/lib/gcov.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/lib/gcov.rb new file mode 100644 index 0000000..15a1b4c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/lib/gcov.rb @@ -0,0 +1,113 @@ +require 'ceedling/plugin' +require 'ceedling/constants' +require 'gcov_constants' + +class Gcov < Plugin + attr_reader :config + + def setup + @result_list = [] + + @config = { + project_test_build_output_path: GCOV_BUILD_OUTPUT_PATH, + project_test_build_output_c_path: GCOV_BUILD_OUTPUT_PATH, + project_test_results_path: GCOV_RESULTS_PATH, + project_test_dependencies_path: GCOV_DEPENDENCIES_PATH, + defines_test: DEFINES_TEST + ['CODE_COVERAGE'], + gcov_html_report_filter: GCOV_FILTER_EXCLUDE + } + + @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + @coverage_template_all = @ceedling[:file_wrapper].read(File.join(@plugin_root, 'assets/template.erb')) + end + + def generate_coverage_object_file(source, object) + lib_args = @ceedling[:test_invoker].convert_libraries_to_arguments() + compile_command = + @ceedling[:tool_executor].build_command_line( + TOOLS_GCOV_COMPILER, + @ceedling[:flaginator].flag_down(OPERATION_COMPILE_SYM, GCOV_SYM, source), + source, + object, + @ceedling[:file_path_utils].form_test_build_list_filepath(object), + lib_args + ) + @ceedling[:streaminator].stdout_puts("Compiling #{File.basename(source)} with coverage...") + @ceedling[:tool_executor].exec(compile_command[:line], compile_command[:options]) + end + + def post_test_fixture_execute(arg_hash) + result_file = arg_hash[:result_file] + + if (result_file =~ /#{GCOV_RESULTS_PATH}/) && !@result_list.include?(result_file) + @result_list << arg_hash[:result_file] + end + end + + def post_build + return unless @ceedling[:task_invoker].invoked?(/^#{GCOV_TASK_ROOT}/) + + # test results + results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list) + hash = { + header: GCOV_ROOT_NAME.upcase, + results: results + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) do + message = '' + message = 'Unit test failures.' if results[:counts][:failed] > 0 + message + end + + report_per_file_coverage_results(@ceedling[:test_invoker].sources) + end + + def summary + result_list = @ceedling[:file_path_utils].form_pass_results_filelist(GCOV_RESULTS_PATH, COLLECTION_ALL_TESTS) + + # test results + # get test results for only those tests in our configuration and of those only tests with results on disk + hash = { + header: GCOV_ROOT_NAME.upcase, + results: @ceedling[:plugin_reportinator].assemble_test_results(result_list, boom: false) + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) + end + + private ################################### + + def report_per_file_coverage_results(sources) + banner = @ceedling[:plugin_reportinator].generate_banner "#{GCOV_ROOT_NAME.upcase}: CODE COVERAGE SUMMARY" + @ceedling[:streaminator].stdout_puts "\n" + banner + + coverage_sources = sources.clone + coverage_sources.delete_if { |item| item =~ /#{CMOCK_MOCK_PREFIX}.+#{EXTENSION_SOURCE}$/ } + coverage_sources.delete_if { |item| item =~ /#{GCOV_IGNORE_SOURCES.join('|')}#{EXTENSION_SOURCE}$/ } + + coverage_sources.each do |source| + basename = File.basename(source) + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_REPORT, [], [basename]) + shell_results = @ceedling[:tool_executor].exec(command[:line], command[:options]) + coverage_results = shell_results[:output] + + if coverage_results.strip =~ /(File\s+'#{Regexp.escape(source)}'.+$)/m + report = Regexp.last_match(1).lines.to_a[1..-1].map { |line| basename + ' ' + line }.join('') + @ceedling[:streaminator].stdout_puts(report + "\n\n") + end + end + + COLLECTION_ALL_SOURCE.each do |source| + unless coverage_sources.include?(source) + @ceedling[:streaminator].stdout_puts("Could not find coverage results for " + source + "\n") + end + end + end +end + +# end blocks always executed following rake run +END { + # cache our input configurations to use in comparison upon next execution + @ceedling[:cacheinator].cache_test_config(@ceedling[:setupinator].config_hash) if @ceedling[:task_invoker].invoked?(/^#{GCOV_TASK_ROOT}/) +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/lib/gcov_constants.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/lib/gcov_constants.rb new file mode 100644 index 0000000..539d46f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/gcov/lib/gcov_constants.rb @@ -0,0 +1,19 @@ + +GCOV_ROOT_NAME = 'gcov'.freeze +GCOV_TASK_ROOT = GCOV_ROOT_NAME + ':' +GCOV_SYM = GCOV_ROOT_NAME.to_sym + +GCOV_BUILD_PATH = File.join(PROJECT_BUILD_ROOT, GCOV_ROOT_NAME) +GCOV_BUILD_OUTPUT_PATH = File.join(GCOV_BUILD_PATH, "out") +GCOV_RESULTS_PATH = File.join(GCOV_BUILD_PATH, "results") +GCOV_DEPENDENCIES_PATH = File.join(GCOV_BUILD_PATH, "dependencies") +GCOV_ARTIFACTS_PATH = File.join(PROJECT_BUILD_ARTIFACTS_ROOT, GCOV_ROOT_NAME) + +GCOV_ARTIFACTS_FILE = File.join(GCOV_ARTIFACTS_PATH, "GcovCoverageResults.html") +GCOV_ARTIFACTS_FILE_XML = File.join(GCOV_ARTIFACTS_PATH, "GcovCoverageResults.xml") + +GCOV_IGNORE_SOURCES = %w(unity cmock cexception).freeze + +GCOV_FILTER_EXCLUDE = '^vendor.*|^build.*|^test.*|^lib.*' + + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/junit_tests_report/README.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/junit_tests_report/README.md new file mode 100644 index 0000000..1259fd6 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/junit_tests_report/README.md @@ -0,0 +1,36 @@ +junit_tests_report +==================== + +## Overview + +The junit_tests_report plugin creates an XML file of test results in JUnit +format, which is handy for Continuous Integration build servers or as input +into other reporting tools. The XML file is output to the appropriate +`/artifacts/` directory (e.g. `artifacts/test/` for test tasks, +`artifacts/gcov/` for gcov, or `artifacts/bullseye/` for bullseye runs). + +## Setup + +Enable the plugin in your project.yml by adding `junit_tests_report` +to the list of enabled plugins. + +``` YAML +:plugins: + :enabled: + - junit_tests_report +``` + +## Configuration + +Optionally configure the output / artifact filename in your project.yml with +the `artifact_filename` configuration option. The default filename is +`report.xml`. + +You can also configure the path that this artifact is stored. This can be done +by setting `path`. The default is that it will be placed in a subfolder under +the `build` directory. + +``` YAML +:junit_tests_report: + :artifact_filename: report_junit.xml +``` diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/junit_tests_report/lib/junit_tests_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/junit_tests_report/lib/junit_tests_report.rb new file mode 100644 index 0000000..a777d07 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/junit_tests_report/lib/junit_tests_report.rb @@ -0,0 +1,129 @@ +require 'ceedling/plugin' +require 'ceedling/constants' + +class JunitTestsReport < Plugin + + def setup + @results_list = {} + @test_counter = 0 + @time_result = [] + end + + def post_test_fixture_execute(arg_hash) + context = arg_hash[:context] + + @results_list[context] = [] if (@results_list[context].nil?) + + @results_list[context] << arg_hash[:result_file] + @time_result << arg_hash[:shell_result][:time] + + end + + def post_build + @results_list.each_key do |context| + results = @ceedling[:plugin_reportinator].assemble_test_results(@results_list[context]) + + artifact_filename = @ceedling[:configurator].project_config_hash[:junit_tests_report_artifact_filename] || 'report.xml' + artifact_fullpath = @ceedling[:configurator].project_config_hash[:junit_tests_report_path] || File.join(PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s) + file_path = File.join(artifact_fullpath, artifact_filename) + + @ceedling[:file_wrapper].open( file_path, 'w' ) do |f| + @testsuite_counter = 0 + @testcase_counter = 0 + suites = reorganise_results( results ) + + write_header( results, f ) + suites.each{|suite| write_suite( suite, f ) } + write_footer( f ) + end + end + end + + private + + def write_header( results, stream ) + results[:counts][:time] = @time_result.reduce(0, :+) + stream.puts '' + stream.puts('' % results[:counts]) + end + + def write_footer( stream ) + stream.puts '' + end + + def reorganise_results( results ) + # Reorganise the output by test suite instead of by result + suites = Hash.new{ |h,k| h[k] = {collection: [], total: 0, success: 0, failed: 0, ignored: 0, stdout: []} } + results[:successes].each do |result| + source = result[:source] + name = source[:file].sub(/\..{1,4}$/, "") + suites[name][:collection] += result[:collection].map{|test| test.merge(result: :success)} + suites[name][:total] += result[:collection].length + suites[name][:success] += result[:collection].length + end + results[:failures].each do |result| + source = result[:source] + name = source[:file].sub(/\..{1,4}$/, "") + suites[name][:collection] += result[:collection].map{|test| test.merge(result: :failed)} + suites[name][:total] += result[:collection].length + suites[name][:failed] += result[:collection].length + end + results[:ignores].each do |result| + source = result[:source] + name = source[:file].sub(/\..{1,4}$/, "") + suites[name][:collection] += result[:collection].map{|test| test.merge(result: :ignored)} + suites[name][:total] += result[:collection].length + suites[name][:ignored] += result[:collection].length + end + results[:stdout].each do |result| + source = result[:source] + name = source[:file].sub(/\..{1,4}$/, "") + suites[name][:stdout] += result[:collection] + end + suites.map{|name, data| data.merge(name: name) } + end + + def write_suite( suite, stream ) + suite[:time] = @time_result.shift + stream.puts(' ' % suite) + + suite[:collection].each do |test| + write_test( test, stream ) + end + + unless suite[:stdout].empty? + stream.puts(' ') + suite[:stdout].each do |line| + line.gsub!(/&/, '&') + line.gsub!(//, '>') + line.gsub!(/"/, '"') + line.gsub!(/'/, ''') + stream.puts(line) + end + stream.puts(' ') + end + + stream.puts(' ') + end + + def write_test( test, stream ) + test[:test].gsub!('"', '"') + case test[:result] + when :success + stream.puts(' ' % test) + when :failed + stream.puts(' ' % test) + if test[:message].empty? + stream.puts(' ') + else + stream.puts(' ' % test[:message]) + end + stream.puts(' ') + when :ignored + stream.puts(' ' % test) + stream.puts(' ') + stream.puts(' ') + end + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/config/module_generator.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/config/module_generator.yml new file mode 100644 index 0000000..cdb2da2 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/config/module_generator.yml @@ -0,0 +1,4 @@ +:module_generator: + :project_root: ./ + :source_root: src/ + :test_root: test/ \ No newline at end of file diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/lib/module_generator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/lib/module_generator.rb new file mode 100644 index 0000000..b2fac00 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/lib/module_generator.rb @@ -0,0 +1,70 @@ +require 'ceedling/plugin' +require 'ceedling/constants' +require 'erb' +require 'fileutils' + +class ModuleGenerator < Plugin + + attr_reader :config + + def create(module_name, optz={}) + + require "generate_module.rb" #From Unity Scripts + + if ((!optz.nil?) && (optz[:destroy])) + UnityModuleGenerator.new( divine_options(optz) ).destroy(module_name) + else + UnityModuleGenerator.new( divine_options(optz) ).generate(module_name) + end + end + + private + + def divine_options(optz={}) + unity_generator_options = + { + :path_src => ((defined? MODULE_GENERATOR_SOURCE_ROOT ) ? MODULE_GENERATOR_SOURCE_ROOT.gsub('\\', '/').sub(/^\//, '').sub(/\/$/, '') : "src" ), + :path_inc => ((defined? MODULE_GENERATOR_INC_ROOT ) ? + MODULE_GENERATOR_INC_ROOT.gsub('\\', '/').sub(/^\//, '').sub(/\/$/, '') + : (defined? MODULE_GENERATOR_SOURCE_ROOT ) ? + MODULE_GENERATOR_SOURCE_ROOT.gsub('\\', '/').sub(/^\//, '').sub(/\/$/, '') + : "src" ), + :path_tst => ((defined? MODULE_GENERATOR_TEST_ROOT ) ? MODULE_GENERATOR_TEST_ROOT.gsub( '\\', '/').sub(/^\//, '').sub(/\/$/, '') : "test" ), + :pattern => optz[:pattern], + :test_prefix => ((defined? PROJECT_TEST_FILE_PREFIX ) ? PROJECT_TEST_FILE_PREFIX : "Test" ), + :mock_prefix => ((defined? CMOCK_MOCK_PREFIX ) ? CMOCK_MOCK_PREFIX : "Mock" ), + :includes => ((defined? MODULE_GENERATOR_INCLUDES ) ? MODULE_GENERATOR_INCLUDES : {} ), + :boilerplates => ((defined? MODULE_GENERATOR_BOILERPLATES) ? MODULE_GENERATOR_BOILERPLATES : {} ), + :naming => ((defined? MODULE_GENERATOR_NAMING ) ? MODULE_GENERATOR_NAMING : nil ), + :update_svn => ((defined? MODULE_GENERATOR_UPDATE_SVN ) ? MODULE_GENERATOR_UPDATE_SVN : false ), + } + + # Read Boilerplate template file. + if (defined? MODULE_GENERATOR_BOILERPLATE_FILES) + + bf = MODULE_GENERATOR_BOILERPLATE_FILES + + if !bf[:src].nil? && File.exists?(bf[:src]) + unity_generator_options[:boilerplates][:src] = File.read(bf[:src]) + end + + if !bf[:inc].nil? && File.exists?(bf[:inc]) + unity_generator_options[:boilerplates][:inc] = File.read(bf[:inc]) + end + + if !bf[:tst].nil? && File.exists?(bf[:tst]) + unity_generator_options[:boilerplates][:tst] = File.read(bf[:tst]) + end + end + + # If using "create[:]" option from command line. + unless optz[:module_root_path].to_s.empty? + unity_generator_options[:path_src] = File.join(optz[:module_root_path], unity_generator_options[:path_src]) + unity_generator_options[:path_inc] = File.join(optz[:module_root_path], unity_generator_options[:path_inc]) + unity_generator_options[:path_tst] = File.join(optz[:module_root_path], unity_generator_options[:path_tst]) + end + + return unity_generator_options + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/module_generator.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/module_generator.rake new file mode 100644 index 0000000..e88e346 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/module_generator/module_generator.rake @@ -0,0 +1,47 @@ + +namespace :module do + module_root_separator = ":" + + desc "Generate module (source, header and test files)" + task :create, :module_path do |t, args| + files = [args[:module_path]] + (args.extras || []) + optz = { :module_root_path => "" } + ["dh", "dih", "mch", "mvp", "src", "test"].each do |pat| + p = files.delete(pat) + optz[:pattern] = p unless p.nil? + end + files.each do |v| + module_root_path, module_name = v.split(module_root_separator, 2) + if module_name + optz[:module_root_path] = module_root_path + v = module_name + end + if (v =~ /^test_?/i) + # If the name of the file starts with test, automatically treat it as one + @ceedling[:module_generator].create(v.sub(/^test_?/i,''), optz.merge({:pattern => 'test'})) + else + # Otherwise, go through the normal procedure + @ceedling[:module_generator].create(v, optz) + end + end + end + + desc "Destroy module (source, header and test files)" + task :destroy, :module_path do |t, args| + files = [args[:module_path]] + (args.extras || []) + optz = { :destroy => true, :module_root_path => "" } + ["dh", "dih", "mch", "mvp", "src", "test"].each do |pat| + p = files.delete(pat) + optz[:pattern] = p unless p.nil? + end + files.each do |v| + module_root_path, module_name = v.split(module_root_separator, 2) + if module_name + optz[:module_root_path] = module_root_path + v = module_name + end + @ceedling[:module_generator].create(v, optz) + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/raw_output_report/lib/raw_output_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/raw_output_report/lib/raw_output_report.rb new file mode 100644 index 0000000..014e677 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/raw_output_report/lib/raw_output_report.rb @@ -0,0 +1,41 @@ +require 'ceedling/plugin' +require 'ceedling/constants' + +class RawOutputReport < Plugin + def setup + @log_paths = {} + end + + def post_test_fixture_execute(arg_hash) + output = strip_output(arg_hash[:shell_result][:output]) + write_raw_output_log(arg_hash, output) + end + + private + + def strip_output(raw_output) + output = "" + raw_output.each_line do |line| + next if line =~ /^\n$/ + next if line =~ /^.*:\d+:.*:(IGNORE|PASS|FAIL)/ + return output if line =~/^-----------------------\n$/ + output << line + end + end + def write_raw_output_log(arg_hash, output) + logging = generate_log_path(arg_hash) + @ceedling[:file_wrapper].write(logging[:path], output , logging[:flags]) unless logging.nil? + end + + def generate_log_path(arg_hash) + f_name = File.basename(arg_hash[:result_file], '.pass') + base_path = File.join(PROJECT_BUILD_ARTIFACTS_ROOT, arg_hash[:context].to_s) + file_path = File.join(base_path, f_name + '.log') + + if @ceedling[:file_wrapper].exist?(base_path) + return { path: file_path, flags: 'w' } + end + + nil + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/assets/template.erb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/assets/template.erb new file mode 100644 index 0000000..fb8e3b1 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/assets/template.erb @@ -0,0 +1,84 @@ +% ignored = hash[:results][:counts][:ignored] +% failed = hash[:results][:counts][:failed] +% stdout_count = hash[:results][:counts][:stdout] +% header_prepend = ((hash[:header].length > 0) ? "#{hash[:header]}: " : '') +% banner_width = 25 + header_prepend.length # widest message +% results = {} +% hash[:results][:successes].each do |testresult| +% results[ testresult[:source][:file] ] = testresult[:collection] +% results[ testresult[:source][:file] ].length.times do |i| +% results[ testresult[:source][:file] ][i][:pass] = true +% end +% end +% hash[:results][:ignores].each do |testresult| +% if (results[ testresult[:source][:file] ].nil?) +% results[ testresult[:source][:file] ] = testresult[:collection] +% else +% results[ testresult[:source][:file] ] += testresult[:collection] +% end +% results[ testresult[:source][:file] ].length.times do |i| +% results[ testresult[:source][:file] ][i][:pass] = true +% end +% end +% hash[:results][:failures].each do |testresult| +% if (results[ testresult[:source][:file] ].nil?) +% results[ testresult[:source][:file] ] = testresult[:collection] +% else +% results[ testresult[:source][:file] ] += testresult[:collection] +% end +% end + + +[==========] Running <%=hash[:results][:counts][:total].to_s%> tests from <%=results.length.to_s%> test cases. +[----------] Global test environment set-up. +% results.each_pair do |modulename, moduledetails| +[----------] <%=moduledetails.length.to_s%> tests from <%=modulename%> +% moduledetails.each do |item| +[ RUN ] <%=modulename%>.<%=item[:test]%> +% if (not item[:pass]) +% if (not item[:message].empty?) +<%=modulename%>(<%=item[:line]%>): error: <%=item[:message]%> + +% m = item[:message].match(/Expected\s+(.*)\s+Was\s+([^\.]*)\./) +% if m.nil? + Actual: FALSE + Expected: TRUE +% else + Actual: <%=m[2]%> + Expected: <%=m[1]%> +% end +% else +<%=modulename%>(<%=item[:line]%>): fail: <%=item[:message]%> + Actual: FALSE + Expected: TRUE +% end +[ FAILED ] <%=modulename%>.<%=item[:test]%> (0 ms) +% else +[ OK ] <%=modulename%>.<%=item[:test]%> (0 ms) +% end +% end +[----------] <%=moduledetails.length.to_s%> tests from <%=modulename%> (0 ms total) +% end + +% if (hash[:results][:counts][:total] > 0) +[----------] Global test environment tear-down. +[==========] <%=hash[:results][:counts][:total].to_s%> tests from <%=hash[:results][:stdout].length.to_s%> test cases ran. +[ PASSED ] <%=hash[:results][:counts][:passed].to_s%> tests. +% if (failed == 0) +[ FAILED ] 0 tests. + + 0 FAILED TESTS +% else +[ FAILED ] <%=failed.to_s%> tests, listed below: +% hash[:results][:failures].each do |failure| +% failure[:collection].each do |item| +[ FAILED ] <%=failure[:source][:file]%>.<%=item[:test]%> +% end +% end +% end + + <%=failed.to_s%> FAILED TESTS +% else + +No tests executed. +% end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/assets/template.erb copy b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/assets/template.erb copy new file mode 100644 index 0000000..a90f495 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/assets/template.erb copy @@ -0,0 +1,59 @@ +% ignored = hash[:results][:counts][:ignored] +% failed = hash[:results][:counts][:failed] +% stdout_count = hash[:results][:counts][:stdout] +% header_prepend = ((hash[:header].length > 0) ? "#{hash[:header]}: " : '') +% banner_width = 25 + header_prepend.length # widest message + + +% if (stdout_count > 0) +[==========] Running <%=hash[:results][:counts][:total].to_s%> tests from <%=hash[:results][:stdout].length.to_s%> test cases. +[----------] Global test environment set-up. +% end +% if (failed > 0) +% hash[:results][:failures].each do |failure| +[----------] <%=failure[:collection].length.to_s%> tests from <%=failure[:source][:file]%> +% failure[:collection].each do |item| +[ RUN ] <%=failure[:source][:file]%>.<%=item[:test]%> +% if (not item[:message].empty?) +<%=failure[:source][:file]%>(<%=item[:line]%>): error: <%=item[:message]%> + +% m = item[:message].match(/Expected\s+(.*)\s+Was\s+([^\.]*)\./) +% if m.nil? + Actual: FALSE + Expected: TRUE +% else + Actual: <%=m[2]%> + Expected: <%=m[1]%> +% end +% else +<%=failure[:source][:file]%>(<%=item[:line]%>): fail: <%=item[:message]%> + Actual: FALSE + Expected: TRUE +% end +[ FAILED ] <%=failure[:source][:file]%>.<%=item[:test]%> (0 ms) +% end +[----------] <%=failure[:collection].length.to_s%> tests from <%=failure[:source][:file]%> (0 ms total) +% end +% end +% if (hash[:results][:counts][:total] > 0) +[----------] Global test environment tear-down. +[==========] <%=hash[:results][:counts][:total].to_s%> tests from <%=hash[:results][:stdout].length.to_s%> test cases ran. +[ PASSED ] <%=hash[:results][:counts][:passed].to_s%> tests. +% if (failed == 0) +[ FAILED ] 0 tests. + + 0 FAILED TESTS +% else +[ FAILED ] <%=failed.to_s%> tests, listed below: +% hash[:results][:failures].each do |failure| +% failure[:collection].each do |item| +[ FAILED ] <%=failure[:source][:file]%>.<%=item[:test]%> +% end +% end + + <%=failed.to_s%> FAILED TESTS +% end +% else + +No tests executed. +% end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/config/stdout_gtestlike_tests_report.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/config/stdout_gtestlike_tests_report.yml new file mode 100644 index 0000000..c25acf5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/config/stdout_gtestlike_tests_report.yml @@ -0,0 +1,4 @@ +--- +:plugins: + # tell Ceedling we got results display taken care of + :display_raw_test_results: FALSE diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/lib/stdout_gtestlike_tests_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/lib/stdout_gtestlike_tests_report.rb new file mode 100644 index 0000000..a51438a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_gtestlike_tests_report/lib/stdout_gtestlike_tests_report.rb @@ -0,0 +1,43 @@ +require 'ceedling/plugin' +require 'ceedling/defaults' + +class StdoutGtestlikeTestsReport < Plugin + + def setup + @result_list = [] + @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + template = @ceedling[:file_wrapper].read(File.join(@plugin_root, 'assets/template.erb')) + @ceedling[:plugin_reportinator].register_test_results_template( template ) + end + + def post_test_fixture_execute(arg_hash) + return if not (arg_hash[:context] == TEST_SYM) + + @result_list << arg_hash[:result_file] + end + + def post_build + return if not (@ceedling[:task_invoker].test_invoked?) + + results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list) + hash = { + :header => '', + :results => results + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) + end + + def summary + result_list = @ceedling[:file_path_utils].form_pass_results_filelist( PROJECT_TEST_RESULTS_PATH, COLLECTION_ALL_TESTS ) + + # get test results for only those tests in our configuration and of those only tests with results on disk + hash = { + :header => '', + :results => @ceedling[:plugin_reportinator].assemble_test_results(result_list, {:boom => false}) + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_ide_tests_report/config/stdout_ide_tests_report.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_ide_tests_report/config/stdout_ide_tests_report.yml new file mode 100644 index 0000000..c25acf5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_ide_tests_report/config/stdout_ide_tests_report.yml @@ -0,0 +1,4 @@ +--- +:plugins: + # tell Ceedling we got results display taken care of + :display_raw_test_results: FALSE diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_ide_tests_report/lib/stdout_ide_tests_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_ide_tests_report/lib/stdout_ide_tests_report.rb new file mode 100644 index 0000000..48b3e81 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_ide_tests_report/lib/stdout_ide_tests_report.rb @@ -0,0 +1,44 @@ +require 'ceedling/plugin' +require 'ceedling/defaults' + +class StdoutIdeTestsReport < Plugin + + def setup + @result_list = [] + end + + def post_test_fixture_execute(arg_hash) + return if not (arg_hash[:context] == TEST_SYM) + + @result_list << arg_hash[:result_file] + end + + def post_build + return if (not @ceedling[:task_invoker].test_invoked?) + + results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list) + hash = { + :header => '', + :results => results + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) do + message = '' + message = 'Unit test failures.' if (hash[:results][:counts][:failed] > 0) + message + end + end + + def summary + result_list = @ceedling[:file_path_utils].form_pass_results_filelist( PROJECT_TEST_RESULTS_PATH, COLLECTION_ALL_TESTS ) + + # get test results for only those tests in our configuration and of those only tests with results on disk + hash = { + :header => '', + :results => @ceedling[:plugin_reportinator].assemble_test_results(result_list, {:boom => false}) + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/assets/template.erb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/assets/template.erb new file mode 100644 index 0000000..52b29f7 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/assets/template.erb @@ -0,0 +1,59 @@ +% ignored = hash[:results][:counts][:ignored] +% failed = hash[:results][:counts][:failed] +% stdout_count = hash[:results][:counts][:stdout] +% header_prepend = ((hash[:header].length > 0) ? "#{hash[:header]}: " : '') +% banner_width = 25 + header_prepend.length # widest message + +% if (stdout_count > 0) +<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'TEST OUTPUT')%> +% hash[:results][:stdout].each do |string| +[<%=string[:source][:file]%>] +% string[:collection].each do |item| + - "<%=item%>" +% end + +% end +% end +% if (ignored > 0) +<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'IGNORED TEST SUMMARY')%> +% hash[:results][:ignores].each do |ignore| +[<%=ignore[:source][:file]%>] +% ignore[:collection].each do |item| + Test: <%=item[:test]%> +% if (not item[:message].empty?) + At line (<%=item[:line]%>): "<%=item[:message]%>" +% else + At line (<%=item[:line]%>) +% end + +% end +% end +% end +% if (failed > 0) +<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'FAILED TEST SUMMARY')%> +% hash[:results][:failures].each do |failure| +[<%=failure[:source][:file]%>] +% failure[:collection].each do |item| + Test: <%=item[:test]%> +% if (not item[:message].empty?) + At line (<%=item[:line]%>): "<%=item[:message]%>" +% else + At line (<%=item[:line]%>) +% end + +% end +% end +% end +% total_string = hash[:results][:counts][:total].to_s +% format_string = "%#{total_string.length}i" +<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'OVERALL TEST SUMMARY')%> +% if (hash[:results][:counts][:total] > 0) +TESTED: <%=hash[:results][:counts][:total].to_s%> +PASSED: <%=sprintf(format_string, hash[:results][:counts][:passed])%> +FAILED: <%=sprintf(format_string, failed)%> +IGNORED: <%=sprintf(format_string, ignored)%> +% else + +No tests executed. +% end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/config/stdout_pretty_tests_report.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/config/stdout_pretty_tests_report.yml new file mode 100644 index 0000000..c25acf5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/config/stdout_pretty_tests_report.yml @@ -0,0 +1,4 @@ +--- +:plugins: + # tell Ceedling we got results display taken care of + :display_raw_test_results: FALSE diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/lib/stdout_pretty_tests_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/lib/stdout_pretty_tests_report.rb new file mode 100644 index 0000000..018388f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/stdout_pretty_tests_report/lib/stdout_pretty_tests_report.rb @@ -0,0 +1,47 @@ +require 'ceedling/plugin' +require 'ceedling/defaults' + +class StdoutPrettyTestsReport < Plugin + + def setup + @result_list = [] + @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + template = @ceedling[:file_wrapper].read(File.join(@plugin_root, 'assets/template.erb')) + @ceedling[:plugin_reportinator].register_test_results_template( template ) + end + + def post_test_fixture_execute(arg_hash) + return if not (arg_hash[:context] == TEST_SYM) + + @result_list << arg_hash[:result_file] + end + + def post_build + return if not (@ceedling[:task_invoker].test_invoked?) + + results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list) + hash = { + :header => '', + :results => results + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) do + message = '' + message = 'Unit test failures.' if (results[:counts][:failed] > 0) + message + end + end + + def summary + result_list = @ceedling[:file_path_utils].form_pass_results_filelist( PROJECT_TEST_RESULTS_PATH, COLLECTION_ALL_TESTS ) + + # get test results for only those tests in our configuration and of those only tests with results on disk + hash = { + :header => '', + :results => @ceedling[:plugin_reportinator].assemble_test_results(result_list, {:boom => false}) + } + + @ceedling[:plugin_reportinator].run_test_results_report(hash) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/README.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/README.md new file mode 100644 index 0000000..e51a4e6 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/README.md @@ -0,0 +1,63 @@ +ceedling-subprojects +==================== + +Plugin for supporting subprojects that are built as static libraries. It continues to support +dependency tracking, without getting confused between your main project files and your +subproject files. It accepts different compiler flags and linker flags, allowing you to +optimize for your situation. + +First, you're going to want to add the extension to your list of known extensions: + +``` +:extension: + :subprojects: '.a' +``` + +Define a new section called :subprojects. There, you can list as many subprojects +as you may need under the :paths key. For each, you specify a unique place to build +and a unique name. + +``` +:subprojects: + :paths: + - :name: libprojectA + :source: + - ./subprojectA/first/dir + - ./subprojectA/second/dir + :include: + - ./subprojectA/include/dir + :build_root: ./subprojectA/build/dir + :defines: + - DEFINE_JUST_FOR_THIS_FILE + - AND_ANOTHER + - :name: libprojectB + :source: + - ./subprojectB/only/dir + :include: + - ./subprojectB/first/include/dir + - ./subprojectB/second/include/dir + :build_root: ./subprojectB/build/dir + :defines: [] #none for this one +``` + +You can specify the compiler and linker, just as you would a release build: + +``` +:tools: + :subprojects_compiler: + :executable: gcc + :arguments: + - -g + - -I"$": COLLECTION_PATHS_SUBPROJECTS + - -D$: COLLECTION_DEFINES_SUBPROJECTS + - -c "${1}" + - -o "${2}" + :subprojects_linker: + :executable: ar + :arguments: + - rcs + - ${2} + - ${1} +``` + +That's all there is to it! Happy Hacking! diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/config/defaults.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/config/defaults.yml new file mode 100644 index 0000000..1045a59 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/config/defaults.yml @@ -0,0 +1,33 @@ +--- +#:extension: +# :subprojects: '.a' + +:subprojects: + :paths: [] +# - :name: subprojectA +# :source: +# - ./first/subproject/dir +# - ./second/subproject/dir +# :include: +# - ./first/include/dir +# :build_root: ./subproject/build/dir +# :defines: +# - FIRST_DEFINE + +:tools: + :subprojects_compiler: + :executable: gcc + :arguments: + - -g + - -I"$": COLLECTION_PATHS_SUBPROJECTS + - -D$: COLLECTION_DEFINES_SUBPROJECTS + - -c "${1}" + - -o "${2}" + :subprojects_linker: + :executable: ar + :arguments: + - rcs + - ${2} + - ${1} + +... diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/lib/subprojects.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/lib/subprojects.rb new file mode 100644 index 0000000..1f5d4c2 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/lib/subprojects.rb @@ -0,0 +1,92 @@ +require 'ceedling/plugin' +require 'ceedling/constants' + +SUBPROJECTS_ROOT_NAME = 'subprojects' +SUBPROJECTS_TASK_ROOT = SUBPROJECTS_ROOT_NAME + ':' +SUBPROJECTS_SYM = SUBPROJECTS_ROOT_NAME.to_sym + +class Subprojects < Plugin + + def setup + @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Add to the test paths + SUBPROJECTS_PATHS.each do |subproj| + subproj[:source].each do |path| + COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR << path + end + subproj[:include].each do |path| + COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR << path + end + end + + #gather information about the subprojects + @subprojects = {} + @subproject_lookup_by_path = {} + SUBPROJECTS_PATHS.each do |subproj| + @subprojects[ subproj[:name] ] = subproj.clone + @subprojects[ subproj[:name] ][:c] = [] + @subprojects[ subproj[:name] ][:asm] = [] + subproj[:source].each do |path| + search_path = "#{path[-1].match(/\\|\//) ? path : "#{path}/"}*#{EXTENSION_SOURCE}" + @subprojects[ subproj[:name] ][:c] += Dir[search_path] + if (EXTENSION_ASSEMBLY && !EXTENSION_ASSEMBLY.empty?) + search_path = "#{path[-1].match(/\\|\//) ? path : "#{path}/"}*#{EXTENSION_ASSEMBLY}" + @subprojects[ subproj[:name] ][:asm] += Dir[search_path] + end + end + @subproject_lookup_by_path[ subproj[:build_root] ] = subproj[:name] + end + end + + def find_my_project( c_file, file_type = :c ) + @subprojects.each_pair do |subprojname, subproj| + return subprojname if (subproj[file_type].include?(c_file)) + end + end + + def find_my_paths( c_file, file_type = :c ) + @subprojects.each_pair do |subprojname, subproj| + return (subproj[:source] + (subproj[:include] || [])) if (subproj[file_type].include?(c_file)) + end + return [] + end + + def find_my_defines( c_file, file_type = :c ) + @subprojects.each_pair do |subprojname, subproj| + return (subproj[:defines] || []) if (subproj[file_type].include?(c_file)) + end + return [] + end + + def list_all_object_files_for_subproject( lib_name ) + subproj = File.basename(lib_name, EXTENSION_SUBPROJECTS) + objpath = "#{@subprojects[subproj][:build_root]}/out/c" + bbb = @subprojects[subproj][:c].map{|f| "#{objpath}/#{File.basename(f,EXTENSION_SOURCE)}#{EXTENSION_OBJECT}" } + bbb + end + + def find_library_source_file_for_object( obj_name ) + cname = "#{File.basename(obj_name, EXTENSION_OBJECT)}#{EXTENSION_SOURCE}" + dname = File.dirname(obj_name)[0..-7] + pname = @subproject_lookup_by_path[dname] + return @ceedling[:file_finder].find_file_from_list(cname, @subprojects[pname][:c], :error) + end + + def find_library_assembly_file_for_object( obj_name ) + cname = "#{File.basename(obj_name, EXTENSION_OBJECT)}#{EXTENSION_ASEMBLY}" + dname = File.dirname(obj_name)[0..-7] + pname = @subproject_lookup_by_path[dname] + return @ceedling[:file_finder].find_file_from_list(cname, @subprojects[pname][:asm], :error) + end + + def replace_constant(constant, new_value) + Object.send(:remove_const, constant.to_sym) if (Object.const_defined? constant) + Object.const_set(constant, new_value) + end + +end + +# end blocks always executed following rake run +END { +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/subprojects.rake b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/subprojects.rake new file mode 100644 index 0000000..0025c3e --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/subprojects/subprojects.rake @@ -0,0 +1,78 @@ + + +SUBPROJECTS_PATHS.each do |subproj| + + subproj_source = subproj[:source] + subproj_include = subproj[:include] + subproj_name = subproj[:name] + subproj_build_root = subproj[:build_root] + subproj_build_out = "#{subproj[:build_root]}/out" + subproj_build_c = "#{subproj[:build_root]}/out/c" + subproj_build_asm = "#{subproj[:build_root]}/out/asm" + subproj_directories = [ subproj_build_root, subproj_build_out, subproj_build_c, subproj_build_asm ] + + subproj_directories.each do |subdir| + directory(subdir) + end + + CLEAN.include(File.join(subproj_build_root, '*')) + CLEAN.include(File.join(subproj_build_out, '*')) + + CLOBBER.include(File.join(subproj_build_root, '**/*')) + + # Add a rule for building the actual static library from our object files + rule(/#{subproj_build_root}#{'.+\\'+EXTENSION_SUBPROJECTS}$/ => [ + proc do |task_name| + @ceedling[SUBPROJECTS_SYM].list_all_object_files_for_subproject(task_name) + end + ]) do |bin_file| + @ceedling[:generator].generate_executable_file( + TOOLS_SUBPROJECTS_LINKER, + SUBPROJECTS_SYM, + bin_file.prerequisites, + bin_file.name, + @ceedling[:file_path_utils].form_test_build_map_filepath(bin_file.name)) + end + + # Add a rule for building object files from assembly files to link into a library + if (RELEASE_BUILD_USE_ASSEMBLY) + rule(/#{subproj_build_asm}#{'.+\\'+EXTENSION_OBJECT}$/ => [ + proc do |task_name| + @ceedling[SUBPROJECTS_SYM].find_library_assembly_file_for_object(task_name) + end + ]) do |object| + @ceedling[SUBPROJECTS_SYM].replace_constant(:COLLECTION_PATHS_SUBPROJECTS, @ceedling[SUBPROJECTS_SYM].find_my_paths(object.source, :asm)) + @ceedling[SUBPROJECTS_SYM].replace_constant(:COLLECTION_DEFINES_SUBPROJECTS, @ceedling[SUBPROJECTS_SYM].find_my_defines(object.source, :asm)) + @ceedling[:generator].generate_object_file( + TOOLS_SUBPROJECTS_ASSEMBLER, + OPERATION_ASSEMBLE_SYM, + SUBPROJECTS_SYM, + object.source, + object.name ) + end + end + + # Add a rule for building object files from C files to link into a library + rule(/#{subproj_build_c}#{'.+\\'+EXTENSION_OBJECT}$/ => [ + proc do |task_name| + @ceedling[SUBPROJECTS_SYM].find_library_source_file_for_object(task_name) + end + ]) do |object| + @ceedling[SUBPROJECTS_SYM].replace_constant(:COLLECTION_PATHS_SUBPROJECTS, @ceedling[SUBPROJECTS_SYM].find_my_paths(object.source, :c)) + @ceedling[SUBPROJECTS_SYM].replace_constant(:COLLECTION_DEFINES_SUBPROJECTS, @ceedling[SUBPROJECTS_SYM].find_my_defines(object.source, :c)) + @ceedling[:generator].generate_object_file( + TOOLS_SUBPROJECTS_COMPILER, + OPERATION_COMPILE_SYM, + SUBPROJECTS_SYM, + object.source, + object.name, + @ceedling[:file_path_utils].form_release_build_c_list_filepath( object.name ) ) + end + + # Add the subdirectories involved to our list of those that should be autogenerated + task :directories => subproj_directories.clone + + # Finally, add the static library to our RELEASE build dependency list + task RELEASE_SYM => ["#{subproj_build_root}/#{subproj_name}#{EXTENSION_SUBPROJECTS}"] +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/teamcity_tests_report/config/teamcity_tests_report.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/teamcity_tests_report/config/teamcity_tests_report.yml new file mode 100644 index 0000000..c25acf5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/teamcity_tests_report/config/teamcity_tests_report.yml @@ -0,0 +1,4 @@ +--- +:plugins: + # tell Ceedling we got results display taken care of + :display_raw_test_results: FALSE diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/teamcity_tests_report/lib/teamcity_tests_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/teamcity_tests_report/lib/teamcity_tests_report.rb new file mode 100644 index 0000000..33d8548 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/teamcity_tests_report/lib/teamcity_tests_report.rb @@ -0,0 +1,57 @@ +require 'ceedling/plugin' +require 'ceedling/defaults' + +class TeamcityTestsReport < Plugin + + def setup + @suite_started = nil + @output_enabled = !defined?(TEAMCITY_BUILD) || TEAMCITY_BUILD + end + + def escape(string) + string.gsub(/['|\[\]]/, '|\0').gsub('\r', '|r').gsub('\n', '|n') + end + + def pre_test(test) + teamcity_message "testSuiteStarted name='#{File.basename(test, '.c')}'" + @suite_started = Time.now + end + + def post_test(test) + teamcity_message "testSuiteFinished name='#{File.basename(test, '.c')}'" + end + + def post_test_fixture_execute(arg_hash) + duration = (Time.now - @suite_started) * 1000 + results = @ceedling[:plugin_reportinator].assemble_test_results([arg_hash[:result_file]]) + avg_duration = (duration / [1, results[:counts][:passed] + results[:counts][:failed]].max).round + + results[:successes].each do |success| + success[:collection].each do |test| + teamcity_message "testStarted name='#{test[:test]}'" + teamcity_message "testFinished name='#{test[:test]}' duration='#{avg_duration}'" + end + end + + results[:failures].each do |failure| + failure[:collection].each do |test| + teamcity_message "testStarted name='#{test[:test]}'" + teamcity_message "testFailed name='#{test[:test]}' message='#{escape(test[:message])}' details='File: #{failure[:source][:path]}/#{failure[:source][:file]} Line: #{test[:line]}'" + teamcity_message "testFinished name='#{test[:test]}' duration='#{avg_duration}'" + end + end + + results[:ignores].each do |failure| + failure[:collection].each do |test| + teamcity_message "testIgnored name='#{test[:test]}' message='#{escape(test[:message])}'" + end + end + + # We ignore stdout + end + + def teamcity_message(content) + puts "##teamcity[#{content}]" unless !@output_enabled + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/warnings_report/lib/warnings_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/warnings_report/lib/warnings_report.rb new file mode 100644 index 0000000..d4f43fb --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/warnings_report/lib/warnings_report.rb @@ -0,0 +1,69 @@ +require 'ceedling/plugin' +require 'ceedling/constants' + +class WarningsReport < Plugin + def setup + @stderr_redirect = nil + @log_paths = {} + end + + def pre_compile_execute(arg_hash) + # at beginning of compile, override tool's stderr_redirect so we can parse $stderr + $stdout + set_stderr_redirect(arg_hash) + end + + def post_compile_execute(arg_hash) + # after compilation, grab output for parsing/logging, restore stderr_redirect, log warning if it exists + output = arg_hash[:shell_result][:output] + restore_stderr_redirect(arg_hash) + write_warning_log(arg_hash[:context], output) + end + + def pre_link_execute(arg_hash) + # at beginning of link, override tool's stderr_redirect so we can parse $stderr + $stdout + set_stderr_redirect(arg_hash) + end + + def post_link_execute(arg_hash) + # after linking, grab output for parsing/logging, restore stderr_redirect, log warning if it exists + output = arg_hash[:shell_result][:output] + restore_stderr_redirect(arg_hash) + write_warning_log(arg_hash[:context], output) + end + + private + + def set_stderr_redirect(hash) + @stderr_redirect = hash[:tool][:stderr_redirect] + hash[:tool][:stderr_redirect] = StdErrRedirect::AUTO + end + + def restore_stderr_redirect(hash) + hash[:tool][:stderr_redirect] = @stderr_redirect + end + + def write_warning_log(context, output) + # if $stderr/$stdout contain "warning", log it + if output =~ /warning/i + # generate a log path & file io write flags + logging = generate_log_path(context) + @ceedling[:file_wrapper].write(logging[:path], output + "\n", logging[:flags]) unless logging.nil? + end + end + + def generate_log_path(context) + # if path has already been generated, return it & 'append' file io flags (append to log) + return { path: @log_paths[context], flags: 'a' } unless @log_paths[context].nil? + + # first time through, generate path & 'write' file io flags (create new log) + base_path = File.join(PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s) + file_path = File.join(base_path, 'warnings.log') + + if @ceedling[:file_wrapper].exist?(base_path) + @log_paths[context] = file_path + return { path: file_path, flags: 'w' } + end + + nil + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/xml_tests_report/README.md b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/xml_tests_report/README.md new file mode 100644 index 0000000..ce81ead --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/xml_tests_report/README.md @@ -0,0 +1,36 @@ +xml_tests_report +==================== + +## Overview + +The xml_tests_report plugin creates an XML file of test results in xUnit +format, which is handy for Continuous Integration build servers or as input +into other reporting tools. The XML file is output to the appropriate +`/artifacts/` directory (e.g. `artifacts/test/` for test tasks, +`artifacts/gcov/` for gcov, or `artifacts/bullseye/` for bullseye runs). + +## Setup + +Enable the plugin in your project.yml by adding `xml_tests_report` to the list +of enabled plugins. + +``` YAML +:plugins: + :enabled: + - xml_tests_report +``` + +## Configuration + +Optionally configure the output / artifact filename in your project.yml with +the `artifact_filename` configuration option. The default filename is +`report.xml`. + +You can also configure the path that this artifact is stored. This can be done +by setting `path`. The default is that it will be placed in a subfolder under +the `build` directory. + +``` YAML +:xml_tests_report: + :artifact_filename: report_xunit.xml +``` diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/xml_tests_report/lib/xml_tests_report.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/xml_tests_report/lib/xml_tests_report.rb new file mode 100644 index 0000000..ed4e996 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/plugins/xml_tests_report/lib/xml_tests_report.rb @@ -0,0 +1,110 @@ +require 'ceedling/plugin' +require 'ceedling/constants' + +class XmlTestsReport < Plugin + def setup + @results_list = {} + @test_counter = 0 + end + + def post_test_fixture_execute(arg_hash) + context = arg_hash[:context] + + @results_list[context] = [] if @results_list[context].nil? + + @results_list[context] << arg_hash[:result_file] + end + + def post_build + @results_list.each_key do |context| + results = @ceedling[:plugin_reportinator].assemble_test_results(@results_list[context]) + + artifact_filename = @ceedling[:configurator].project_config_hash[:xml_tests_report_artifact_filename] || 'report.xml' + artifact_fullpath = @ceedling[:configurator].project_config_hash[:xml_tests_report_path] || File.join(PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s) + file_path = File.join(artifact_fullpath, artifact_filename) + + @ceedling[:file_wrapper].open(file_path, 'w') do |f| + @test_counter = 1 + write_results(results, f) + end + end + end + + private + + def write_results(results, stream) + write_header(stream) + write_failures(results[:failures], stream) + write_tests(results[:successes], stream, 'SuccessfulTests') + write_tests(results[:ignores], stream, 'IgnoredTests') + write_statistics(results[:counts], stream) + write_footer(stream) + end + + def write_header(stream) + stream.puts "" + stream.puts '' + end + + def write_failures(results, stream) + if results.size.zero? + stream.puts "\t" + return + end + + stream.puts "\t" + + results.each do |result| + result[:collection].each do |item| + filename = File.join(result[:source][:path], result[:source][:file]) + + stream.puts "\t\t" + stream.puts "\t\t\t#{filename}::#{item[:test]}" + stream.puts "\t\t\tAssertion" + stream.puts "\t\t\t" + stream.puts "\t\t\t\t#{filename}" + stream.puts "\t\t\t\t#{item[:line]}" + stream.puts "\t\t\t" + stream.puts "\t\t\t#{item[:message]}" + stream.puts "\t\t" + @test_counter += 1 + end + end + + stream.puts "\t" + end + + def write_tests(results, stream, tag) + if results.size.zero? + stream.puts "\t<#{tag}/>" + return + end + + stream.puts "\t<#{tag}>" + + results.each do |result| + result[:collection].each do |item| + stream.puts "\t\t" + stream.puts "\t\t\t#{File.join(result[:source][:path], result[:source][:file])}::#{item[:test]}" + stream.puts "\t\t" + @test_counter += 1 + end + end + + stream.puts "\t" + end + + def write_statistics(counts, stream) + stream.puts "\t" + stream.puts "\t\t#{counts[:total]}" + stream.puts "\t\t#{counts[:ignored]}" + stream.puts "\t\t#{counts[:failed]}" + stream.puts "\t\t0" + stream.puts "\t\t#{counts[:failed]}" + stream.puts "\t" + end + + def write_footer(stream) + stream.puts '' + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/lib/CException.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/lib/CException.c new file mode 100644 index 0000000..fdff8f4 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/lib/CException.c @@ -0,0 +1,46 @@ +#include "CException.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +volatile CEXCEPTION_FRAME_T CExceptionFrames[CEXCEPTION_NUM_ID] = {{ 0 }}; +#pragma GCC diagnostic pop + +//------------------------------------------------------------------------------------------ +// Throw +//------------------------------------------------------------------------------------------ +void Throw(CEXCEPTION_T ExceptionID) +{ + unsigned int MY_ID = CEXCEPTION_GET_ID; + CExceptionFrames[MY_ID].Exception = ExceptionID; + if (CExceptionFrames[MY_ID].pFrame) + { + longjmp(*CExceptionFrames[MY_ID].pFrame, 1); + } + CEXCEPTION_NO_CATCH_HANDLER(ExceptionID); +} + +//------------------------------------------------------------------------------------------ +// Explanation of what it's all for: +//------------------------------------------------------------------------------------------ +/* +#define Try + { <- give us some local scope. most compilers are happy with this + jmp_buf *PrevFrame, NewFrame; <- prev frame points to the last try block's frame. new frame gets created on stack for this Try block + unsigned int MY_ID = CEXCEPTION_GET_ID; <- look up this task's id for use in frame array. always 0 if single-tasking + PrevFrame = CExceptionFrames[CEXCEPTION_GET_ID].pFrame; <- set pointer to point at old frame (which array is currently pointing at) + CExceptionFrames[MY_ID].pFrame = &NewFrame; <- set array to point at my new frame instead, now + CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- initialize my exception id to be NONE + if (setjmp(NewFrame) == 0) { <- do setjmp. it returns 1 if longjump called, otherwise 0 + if (&PrevFrame) <- this is here to force proper scoping. it requires braces or a single line to be but after Try, otherwise won't compile. This is always true at this point. + +#define Catch(e) + else { } <- this also forces proper scoping. Without this they could stick their own 'else' in and it would get ugly + CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- no errors happened, so just set the exception id to NONE (in case it was corrupted) + } + else <- an exception occurred + { e = CExceptionFrames[MY_ID].Exception; e=e;} <- assign the caught exception id to the variable passed in. + CExceptionFrames[MY_ID].pFrame = PrevFrame; <- make the pointer in the array point at the previous frame again, as if NewFrame never existed. + } <- finish off that local scope we created to have our own variables + if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE) <- start the actual 'catch' processing if we have an exception id saved away + */ + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/lib/CException.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/lib/CException.h new file mode 100644 index 0000000..78f2f94 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/lib/CException.h @@ -0,0 +1,115 @@ +#ifndef _CEXCEPTION_H +#define _CEXCEPTION_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#define CEXCEPTION_VERSION_MAJOR 1 +#define CEXCEPTION_VERSION_MINOR 3 +#define CEXCEPTION_VERSION_BUILD 2 +#define CEXCEPTION_VERSION ((CEXCEPTION_VERSION_MAJOR << 16) | (CEXCEPTION_VERSION_MINOR << 8) | CEXCEPTION_VERSION_BUILD) + +//To Use CException, you have a number of options: +//1. Just include it and run with the defaults +//2. Define any of the following symbols at the command line to override them +//3. Include a header file before CException.h everywhere which defines any of these +//4. Create an Exception.h in your path, and just define EXCEPTION_USE_CONFIG_FILE first + +#ifdef CEXCEPTION_USE_CONFIG_FILE +#include "CExceptionConfig.h" +#endif + +//This is the value to assign when there isn't an exception +#ifndef CEXCEPTION_NONE +#define CEXCEPTION_NONE (0x5A5A5A5A) +#endif + +//This is number of exception stacks to keep track of (one per task) +#ifndef CEXCEPTION_NUM_ID +#define CEXCEPTION_NUM_ID (1) //there is only the one stack by default +#endif + +//This is the method of getting the current exception stack index (0 if only one stack) +#ifndef CEXCEPTION_GET_ID +#define CEXCEPTION_GET_ID (0) //use the first index always because there is only one anyway +#endif + +//The type to use to store the exception values. +#ifndef CEXCEPTION_T +#define CEXCEPTION_T unsigned int +#endif + +//This is an optional special handler for when there is no global Catch +#ifndef CEXCEPTION_NO_CATCH_HANDLER +#define CEXCEPTION_NO_CATCH_HANDLER(id) +#endif + +//These hooks allow you to inject custom code into places, particularly useful for saving and restoring additional state +#ifndef CEXCEPTION_HOOK_START_TRY +#define CEXCEPTION_HOOK_START_TRY +#endif +#ifndef CEXCEPTION_HOOK_HAPPY_TRY +#define CEXCEPTION_HOOK_HAPPY_TRY +#endif +#ifndef CEXCEPTION_HOOK_AFTER_TRY +#define CEXCEPTION_HOOK_AFTER_TRY +#endif +#ifndef CEXCEPTION_HOOK_START_CATCH +#define CEXCEPTION_HOOK_START_CATCH +#endif + +//exception frame structures +typedef struct { + jmp_buf* pFrame; + CEXCEPTION_T volatile Exception; +} CEXCEPTION_FRAME_T; + +//actual root frame storage (only one if single-tasking) +extern volatile CEXCEPTION_FRAME_T CExceptionFrames[]; + +//Try (see C file for explanation) +#define Try \ + { \ + jmp_buf *PrevFrame, NewFrame; \ + unsigned int MY_ID = CEXCEPTION_GET_ID; \ + PrevFrame = CExceptionFrames[MY_ID].pFrame; \ + CExceptionFrames[MY_ID].pFrame = (jmp_buf*)(&NewFrame); \ + CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \ + CEXCEPTION_HOOK_START_TRY; \ + if (setjmp(NewFrame) == 0) { \ + if (1) + +//Catch (see C file for explanation) +#define Catch(e) \ + else { } \ + CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \ + CEXCEPTION_HOOK_HAPPY_TRY; \ + } \ + else \ + { \ + e = CExceptionFrames[MY_ID].Exception; \ + (void)e; \ + CEXCEPTION_HOOK_START_CATCH; \ + } \ + CExceptionFrames[MY_ID].pFrame = PrevFrame; \ + CEXCEPTION_HOOK_AFTER_TRY; \ + } \ + if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE) + +//Throw an Error +void Throw(CEXCEPTION_T ExceptionID); + +//Just exit the Try block and skip the Catch. +#define ExitTry() Throw(CEXCEPTION_NONE) + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif // _CEXCEPTION_H diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/release/build.info b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/release/build.info new file mode 100644 index 0000000..0cd525d --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/release/build.info @@ -0,0 +1,2 @@ +18 + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/release/version.info b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/release/version.info new file mode 100644 index 0000000..1527a8d --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/c_exception/release/version.info @@ -0,0 +1,2 @@ +1.3.1 + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/config/production_environment.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/config/production_environment.rb new file mode 100644 index 0000000..915582b --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/config/production_environment.rb @@ -0,0 +1,14 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +# Setup our load path: +[ + 'lib', +].each do |dir| + $LOAD_PATH.unshift( File.join( File.expand_path(File.dirname(__FILE__)) + '/../', dir) ) +end + + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/config/test_environment.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/config/test_environment.rb new file mode 100644 index 0000000..fe1ed81 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/config/test_environment.rb @@ -0,0 +1,16 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +# Setup our load path: +[ + './lib', + './vendor/behaviors/lib', + './vendor/hardmock/lib', + './vendor/unity/auto/', + './test/system/' +].each do |dir| + $LOAD_PATH.unshift( File.join( File.expand_path(File.dirname(__FILE__) + "/../"), dir) ) +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock.rb new file mode 100644 index 0000000..8243ce5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock.rb @@ -0,0 +1,86 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +[ "../config/production_environment", + "cmock_header_parser", + "cmock_generator", + "cmock_file_writer", + "cmock_config", + "cmock_plugin_manager", + "cmock_generator_utils", + "cmock_unityhelper_parser"].each {|req| require "#{File.expand_path(File.dirname(__FILE__))}/#{req}"} + +class CMock + + def initialize(options=nil) + cm_config = CMockConfig.new(options) + cm_unityhelper = CMockUnityHelperParser.new(cm_config) + cm_writer = CMockFileWriter.new(cm_config) + cm_gen_utils = CMockGeneratorUtils.new(cm_config, {:unity_helper => cm_unityhelper}) + cm_gen_plugins = CMockPluginManager.new(cm_config, cm_gen_utils) + @cm_parser = CMockHeaderParser.new(cm_config) + @cm_generator = CMockGenerator.new(cm_config, cm_writer, cm_gen_utils, cm_gen_plugins) + @silent = (cm_config.verbosity < 2) + end + + def setup_mocks(files) + [files].flatten.each do |src| + generate_mock src + end + end + + private ############################### + + def generate_mock(src) + name = File.basename(src, '.h') + puts "Creating mock for #{name}..." unless @silent + @cm_generator.create_mock(name, @cm_parser.parse(name, File.read(src))) + end +end + +def option_maker(options, key, val) + options = options || {} + options[key.to_sym] = + if val.chr == ":" + val[1..-1].to_sym + elsif val.include? ";" + val.split(';') + elsif val == 'true' + true + elsif val == 'false' + false + elsif val =~ /^\d+$/ + val.to_i + else + val + end + options +end + + # Command Line Support ############################### + +if ($0 == __FILE__) + usage = "usage: ruby #{__FILE__} (-oOptionsFile) File(s)ToMock" + + if (!ARGV[0]) + puts usage + exit 1 + end + + options = {} + filelist = [] + ARGV.each do |arg| + if (arg =~ /^-o\"?([a-zA-Z0-9._\\\/:\s]+)\"?/) + options.merge! CMockConfig.load_config_file_from_yaml( arg.gsub(/^-o/,'') ) + elsif (arg =~ /^--([a-zA-Z0-9._\\\/:\s]+)=\"?([a-zA-Z0-9._\-\\\/:\s\;]+)\"?/) + options = option_maker(options, $1, $2) + else + filelist << arg + end + end + + CMock.new(options).setup_mocks(filelist) +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_config.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_config.rb new file mode 100644 index 0000000..b21b61e --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_config.rb @@ -0,0 +1,153 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockConfig + + CMockDefaultOptions = + { + :framework => :unity, + :mock_path => 'mocks', + :mock_prefix => 'Mock', + :mock_suffix => '', + :weak => '', + :subdir => nil, + :plugins => [], + :strippables => ['(?:__attribute__\s*\(+.*?\)+)'], + :attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'], + :c_calling_conventions => ['__stdcall', '__cdecl', '__fastcall'], + :enforce_strict_ordering => false, + :fail_on_unexpected_calls => true, + :unity_helper_path => false, + :treat_as => {}, + :treat_as_array => {}, + :treat_as_void => [], + :memcmp_if_unknown => true, + :when_no_prototypes => :warn, #the options being :ignore, :warn, or :error + :when_ptr => :compare_data, #the options being :compare_ptr, :compare_data, or :smart + :verbosity => 2, #the options being 0 errors only, 1 warnings and errors, 2 normal info, 3 verbose + :treat_externs => :exclude, #the options being :include or :exclude + :callback_include_count => true, + :callback_after_arg_check => false, + :includes => nil, + :includes_h_pre_orig_header => nil, + :includes_h_post_orig_header => nil, + :includes_c_pre_header => nil, + :includes_c_post_header => nil, + :orig_header_include_fmt => "#include \"%s\"", + :array_size_type => [], + :array_size_name => 'size|len', + } + + def initialize(options=nil) + case(options) + when NilClass then options = CMockDefaultOptions.clone + when String then options = CMockDefaultOptions.clone.merge(load_config_file_from_yaml(options)) + when Hash then options = CMockDefaultOptions.clone.merge(options) + else raise "If you specify arguments, it should be a filename or a hash of options" + end + + #do some quick type verification + [:plugins, :attributes, :treat_as_void].each do |opt| + unless (options[opt].class == Array) + options[opt] = [] + puts "WARNING: :#{opt.to_s} should be an array." unless (options[:verbosity] < 1) + end + end + [:includes, :includes_h_pre_orig_header, :includes_h_post_orig_header, :includes_c_pre_header, :includes_c_post_header].each do |opt| + unless (options[opt].nil? or (options[opt].class == Array)) + options[opt] = [] + puts "WARNING: :#{opt.to_s} should be an array." unless (options[:verbosity] < 1) + end + end + options[:unity_helper_path] ||= options[:unity_helper] + options[:unity_helper_path] = [options[:unity_helper_path]] if options[:unity_helper_path].is_a? String + options[:includes_c_post_header] = ((options[:includes_c_post_header] || []) + (options[:unity_helper_path] || [])).uniq + options[:plugins].compact! + options[:plugins].map! {|p| p.to_sym} + @options = options + + treat_as_map = standard_treat_as_map()#.clone + treat_as_map.merge!(@options[:treat_as]) + @options[:treat_as] = treat_as_map + + @options.each_key do |key| + unless methods.include?(key) + eval("def #{key.to_s}() return @options[:#{key.to_s}] end") + end + end + end + + def load_config_file_from_yaml yaml_filename + self.class.load_config_file_from_yaml yaml_filename + end + + def self.load_config_file_from_yaml yaml_filename + require 'yaml' + require 'fileutils' + YAML.load_file(yaml_filename)[:cmock] + end + + def set_path(path) + @src_path = path + end + + def load_unity_helper + return nil unless (@options[:unity_helper_path]) + + return @options[:unity_helper_path].inject("") do |unity_helper, filename| + unity_helper + "\n" + File.new(filename).read + end + end + + def standard_treat_as_map + { + 'int' => 'INT', + 'char' => 'INT8', + 'short' => 'INT16', + 'long' => 'INT', + 'int8' => 'INT8', + 'int16' => 'INT16', + 'int32' => 'INT', + 'int8_t' => 'INT8', + 'int16_t' => 'INT16', + 'int32_t' => 'INT', + 'INT8_T' => 'INT8', + 'INT16_T' => 'INT16', + 'INT32_T' => 'INT', + 'bool' => 'INT', + 'bool_t' => 'INT', + 'BOOL' => 'INT', + 'BOOL_T' => 'INT', + 'unsigned int' => 'HEX32', + 'unsigned long' => 'HEX32', + 'uint32' => 'HEX32', + 'uint32_t' => 'HEX32', + 'UINT32' => 'HEX32', + 'UINT32_T' => 'HEX32', + 'void*' => 'HEX8_ARRAY', + 'void const*' => 'HEX8_ARRAY', + 'const void*' => 'HEX8_ARRAY', + 'unsigned short' => 'HEX16', + 'uint16' => 'HEX16', + 'uint16_t' => 'HEX16', + 'UINT16' => 'HEX16', + 'UINT16_T' => 'HEX16', + 'unsigned char' => 'HEX8', + 'uint8' => 'HEX8', + 'uint8_t' => 'HEX8', + 'UINT8' => 'HEX8', + 'UINT8_T' => 'HEX8', + 'char*' => 'STRING', + 'char const*' => 'STRING', + 'const char*' => 'STRING', + 'pCHAR' => 'STRING', + 'cstring' => 'STRING', + 'CSTRING' => 'STRING', + 'float' => 'FLOAT', + 'double' => 'FLOAT' + } + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb new file mode 100644 index 0000000..d2d954c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb @@ -0,0 +1,44 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockFileWriter + + attr_reader :config + + def initialize(config) + @config = config + end + + def create_subdir(subdir) + if !Dir.exists?("#{@config.mock_path}/") + require 'fileutils' + FileUtils.mkdir_p "#{@config.mock_path}/" + end + if subdir && !Dir.exists?("#{@config.mock_path}/#{subdir+'/' if subdir}") + require 'fileutils' + FileUtils.mkdir_p "#{@config.mock_path}/#{subdir+'/' if subdir}" + end + end + + def create_file(filename, subdir) + raise "Where's the block of data to create?" unless block_given? + full_file_name_temp = "#{@config.mock_path}/#{subdir+'/' if subdir}#{filename}.new" + full_file_name_done = "#{@config.mock_path}/#{subdir+'/' if subdir}#{filename}" + File.open(full_file_name_temp, 'w') do |file| + yield(file, filename) + end + update_file(full_file_name_done, full_file_name_temp) + end + + private ################################### + + def update_file(dest, src) + require 'fileutils' + FileUtils.rm(dest) if (File.exist?(dest)) + FileUtils.cp(src, dest) + FileUtils.rm(src) + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb new file mode 100644 index 0000000..42725a6 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb @@ -0,0 +1,268 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockGenerator + + attr_accessor :config, :file_writer, :module_name, :clean_mock_name, :mock_name, :utils, :plugins, :weak, :ordered + + def initialize(config, file_writer, utils, plugins) + @file_writer = file_writer + @utils = utils + @plugins = plugins + @config = config + @prefix = @config.mock_prefix + @suffix = @config.mock_suffix + @weak = @config.weak + @ordered = @config.enforce_strict_ordering + @framework = @config.framework.to_s + @fail_on_unexpected_calls = @config.fail_on_unexpected_calls + + @subdir = @config.subdir + + @includes_h_pre_orig_header = (@config.includes || @config.includes_h_pre_orig_header || []).map{|h| h =~ / 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" + file << "#pragma GCC diagnostic push\n" + file << "#endif\n" + file << "#if !defined(__clang__)\n" + file << "#pragma GCC diagnostic ignored \"-Wpragmas\"\n" + file << "#endif\n" + file << "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n" + file << "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n" + file << "#endif\n" + file << "\n" + end + + def create_typedefs(file, typedefs) + file << "\n" + typedefs.each {|typedef| file << "#{typedef}\n" } + file << "\n\n" + end + + def create_mock_header_service_call_declarations(file) + file << "void #{@clean_mock_name}_Init(void);\n" + file << "void #{@clean_mock_name}_Destroy(void);\n" + file << "void #{@clean_mock_name}_Verify(void);\n\n" + end + + def create_mock_header_footer(header) + header << "\n" + header << "#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" + header << "#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" + header << "#pragma GCC diagnostic pop\n" + header << "#endif\n" + header << "#endif\n" + header << "\n" + header << "#endif\n" + end + + def create_source_header_section(file, filename, functions) + header_file = (@subdir ? @subdir + '/' : '') + filename.gsub(".c",".h") + file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" + file << "#include \n" + file << "#include \n" + file << "#include \n" + file << "#include \"cmock.h\"\n" + @includes_c_pre_header.each {|inc| file << "#include #{inc}\n"} + file << "#include \"#{header_file}\"\n" + @includes_c_post_header.each {|inc| file << "#include #{inc}\n"} + file << "\n" + strs = [] + functions.each do |func| + strs << func[:name] + func[:args].each {|arg| strs << arg[:name] } + end + strs.uniq.sort.each do |str| + file << "static const char* CMockString_#{str} = \"#{str}\";\n" + end + file << "\n" + end + + def create_instance_structure(file, functions) + functions.each do |function| + file << "typedef struct _CMOCK_#{function[:name]}_CALL_INSTANCE\n{\n" + file << " UNITY_LINE_TYPE LineNumber;\n" + file << @plugins.run(:instance_typedefs, function) + file << "\n} CMOCK_#{function[:name]}_CALL_INSTANCE;\n\n" + end + file << "static struct #{@clean_mock_name}Instance\n{\n" + if (functions.size == 0) + file << " unsigned char placeHolder;\n" + end + functions.each do |function| + file << @plugins.run(:instance_structure, function) + file << " CMOCK_MEM_INDEX_TYPE #{function[:name]}_CallInstance;\n" + end + file << "} Mock;\n\n" + end + + def create_extern_declarations(file) + file << "extern jmp_buf AbortFrame;\n" + if (@ordered) + file << "extern int GlobalExpectCount;\n" + file << "extern int GlobalVerifyOrder;\n" + end + file << "\n" + end + + def create_mock_verify_function(file, functions) + file << "void #{@clean_mock_name}_Verify(void)\n{\n" + verifications = functions.collect do |function| + v = @plugins.run(:mock_verify, function) + v.empty? ? v : [" call_instance = Mock.#{function[:name]}_CallInstance;\n", v] + end.join + unless verifications.empty? + file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" + file << " CMOCK_MEM_INDEX_TYPE call_instance;\n" + file << verifications + end + file << "}\n\n" + end + + def create_mock_init_function(file) + file << "void #{@clean_mock_name}_Init(void)\n{\n" + file << " #{@clean_mock_name}_Destroy();\n" + file << "}\n\n" + end + + def create_mock_destroy_function(file, functions) + file << "void #{@clean_mock_name}_Destroy(void)\n{\n" + file << " CMock_Guts_MemFreeAll();\n" + file << " memset(&Mock, 0, sizeof(Mock));\n" + file << functions.collect {|function| @plugins.run(:mock_destroy, function)}.join + + unless (@fail_on_unexpected_calls) + file << functions.collect {|function| @plugins.run(:mock_ignore, function)}.join + end + + if (@ordered) + file << " GlobalExpectCount = 0;\n" + file << " GlobalVerifyOrder = 0;\n" + end + file << "}\n\n" + end + + def create_mock_implementation(file, function) + # prepare return value and arguments + function_mod_and_rettype = (function[:modifier].empty? ? '' : "#{function[:modifier]} ") + + (function[:return][:type]) + + (function[:c_calling_convention] ? " #{function[:c_calling_convention]}" : '') + args_string = function[:args_string] + args_string += (", " + function[:var_arg]) unless (function[:var_arg].nil?) + + # Create mock function + if (not @weak.empty?) + file << "#if defined (__IAR_SYSTEMS_ICC__)\n" + file << "#pragma weak #{function[:name]}\n" + file << "#else\n" + file << "#{function_mod_and_rettype} #{function[:name]}(#{args_string}) #{weak};\n" + file << "#endif\n\n" + end + file << "#{function_mod_and_rettype} #{function[:name]}(#{args_string})\n" + file << "{\n" + file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" + file << " CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance;\n" + file << " UNITY_SET_DETAIL(CMockString_#{function[:name]});\n" + file << " cmock_call_instance = (CMOCK_#{function[:name]}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.#{function[:name]}_CallInstance);\n" + file << " Mock.#{function[:name]}_CallInstance = CMock_Guts_MemNext(Mock.#{function[:name]}_CallInstance);\n" + file << @plugins.run(:mock_implementation_precheck, function) + file << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore);\n" + file << " cmock_line = cmock_call_instance->LineNumber;\n" + if (@ordered) + file << " if (cmock_call_instance->CallOrder > ++GlobalVerifyOrder)\n" + file << " UNITY_TEST_FAIL(cmock_line, CMockStringCalledEarly);\n" + file << " if (cmock_call_instance->CallOrder < GlobalVerifyOrder)\n" + file << " UNITY_TEST_FAIL(cmock_line, CMockStringCalledLate);\n" + end + file << @plugins.run(:mock_implementation, function) + file << " UNITY_CLR_DETAILS();\n" + file << " return cmock_call_instance->ReturnVal;\n" unless (function[:return][:void?]) + file << "}\n\n" + end + + def create_mock_interfaces(file, function) + file << @utils.code_add_argument_loader(function) + file << @plugins.run(:mock_interfaces, function) + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_array.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_array.rb new file mode 100644 index 0000000..3b73708 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_array.rb @@ -0,0 +1,63 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockGeneratorPluginArray + + attr_reader :priority + attr_accessor :config, :utils, :unity_helper, :ordered + def initialize(config, utils) + @config = config + @ptr_handling = @config.when_ptr + @ordered = @config.enforce_strict_ordering + @utils = utils + @unity_helper = @utils.helpers[:unity_helper] + @priority = 8 + end + + def instance_typedefs(function) + function[:args].inject("") do |all, arg| + (arg[:ptr?]) ? all + " int Expected_#{arg[:name]}_Depth;\n" : all + end + end + + def mock_function_declarations(function) + return nil unless function[:contains_ptr?] + args_call = function[:args].map{|m| m[:ptr?] ? "#{m[:name]}, #{m[:name]}_Depth" : "#{m[:name]}"}.join(', ') + args_string = function[:args].map do |m| + type = @utils.arg_type_with_const(m) + m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}" + end.join(', ') + if (function[:return][:void?]) + return "#define #{function[:name]}_ExpectWithArray(#{args_call}) #{function[:name]}_CMockExpectWithArray(__LINE__, #{args_call})\n" + + "void #{function[:name]}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string});\n" + else + return "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call}, cmock_retval) #{function[:name]}_CMockExpectWithArrayAndReturn(__LINE__, #{args_call}, cmock_retval)\n" + + "void #{function[:name]}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]});\n" + end + end + + def mock_interfaces(function) + return nil unless function[:contains_ptr?] + lines = [] + func_name = function[:name] + args_string = function[:args].map do |m| + type = @utils.arg_type_with_const(m) + m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}" + end.join(', ') + call_string = function[:args].map{|m| m[:ptr?] ? "#{m[:name]}, #{m[:name]}_Depth" : m[:name]}.join(', ') + if (function[:return][:void?]) + lines << "void #{func_name}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string})\n" + else + lines << "void #{func_name}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]})\n" + end + lines << "{\n" + lines << @utils.code_add_base_expectation(func_name) + lines << " CMockExpectParameters_#{func_name}(cmock_call_instance, #{call_string});\n" + lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n" unless (function[:return][:void?]) + lines << "}\n\n" + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb new file mode 100644 index 0000000..564e0ac --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb @@ -0,0 +1,88 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockGeneratorPluginCallback + + attr_accessor :include_count + attr_reader :priority + attr_reader :config, :utils + + def initialize(config, utils) + @config = config + @utils = utils + @priority = 6 + + @include_count = @config.callback_include_count + end + + def instance_structure(function) + func_name = function[:name] + " int #{func_name}_CallbackBool;\n" \ + " CMOCK_#{func_name}_CALLBACK #{func_name}_CallbackFunctionPointer;\n" \ + " int #{func_name}_CallbackCalls;\n" + end + + def mock_function_declarations(function) + func_name = function[:name] + return_type = function[:return][:type] + action = @config.callback_after_arg_check ? 'AddCallback' : 'Stub' + style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) + styles = [ "void", "int cmock_num_calls", function[:args_string], "#{function[:args_string]}, int cmock_num_calls" ] + "typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{styles[style]});\n" \ + "void #{func_name}_AddCallback(CMOCK_#{func_name}_CALLBACK Callback);\n" \ + "void #{func_name}_Stub(CMOCK_#{func_name}_CALLBACK Callback);\n" \ + "#define #{func_name}_StubWithCallback #{func_name}_#{action}\n" + end + + def generate_call(function) + args = function[:args].map { |m| m[:name] } + args << "Mock.#{function[:name]}_CallbackCalls++" if @include_count + "Mock.#{function[:name]}_CallbackFunctionPointer(#{args.join(', ')})" + end + + def mock_implementation(function) + " if (Mock.#{function[:name]}_CallbackFunctionPointer != NULL)\n {\n" + + if function[:return][:void?] + " #{generate_call(function)};\n }\n" + else + " cmock_call_instance->ReturnVal = #{generate_call(function)};\n }\n" + end + end + + def mock_implementation_precheck(function) + " if (!Mock.#{function[:name]}_CallbackBool &&\n" \ + " Mock.#{function[:name]}_CallbackFunctionPointer != NULL)\n {\n" + + if function[:return][:void?] + " #{generate_call(function)};\n" \ + " UNITY_CLR_DETAILS();\n" \ + " return;\n }\n" + else + " #{function[:return][:type]} ret = #{generate_call(function)};\n" \ + " UNITY_CLR_DETAILS();\n" \ + " return ret;\n }\n" + end + end + + def mock_interfaces(function) + func_name = function[:name] + has_ignore = @config.plugins.include? :ignore + lines = "" + lines << "void #{func_name}_AddCallback(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" + lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if has_ignore + lines << " Mock.#{func_name}_CallbackBool = (int)1;\n" + lines << " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n" + lines << "void #{func_name}_Stub(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" + lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if has_ignore + lines << " Mock.#{func_name}_CallbackBool = (int)0;\n" + lines << " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n" + end + + def mock_verify(function) + func_name = function[:name] + " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n call_instance = CMOCK_GUTS_NONE;\n" + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_cexception.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_cexception.rb new file mode 100644 index 0000000..39d36d6 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_cexception.rb @@ -0,0 +1,51 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockGeneratorPluginCexception + + attr_reader :priority + attr_reader :config, :utils + + def initialize(config, utils) + @config = config + @utils = utils + @priority = 7 + end + + def include_files + return "#include \"CException.h\"\n" + end + + def instance_typedefs(function) + " CEXCEPTION_T ExceptionToThrow;\n" + end + + def mock_function_declarations(function) + if (function[:args_string] == "void") + return "#define #{function[:name]}_ExpectAndThrow(cmock_to_throw) #{function[:name]}_CMockExpectAndThrow(__LINE__, cmock_to_throw)\n" + + "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, CEXCEPTION_T cmock_to_throw);\n" + else + return "#define #{function[:name]}_ExpectAndThrow(#{function[:args_call]}, cmock_to_throw) #{function[:name]}_CMockExpectAndThrow(__LINE__, #{function[:args_call]}, cmock_to_throw)\n" + + "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, CEXCEPTION_T cmock_to_throw);\n" + end + end + + def mock_implementation(function) + " if (cmock_call_instance->ExceptionToThrow != CEXCEPTION_NONE)\n {\n" + + " UNITY_CLR_DETAILS();\n" + + " Throw(cmock_call_instance->ExceptionToThrow);\n }\n" + end + + def mock_interfaces(function) + arg_insert = (function[:args_string] == "void") ? "" : "#{function[:args_string]}, " + [ "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{arg_insert}CEXCEPTION_T cmock_to_throw)\n{\n", + @utils.code_add_base_expectation(function[:name]), + @utils.code_call_argument_loader(function), + " cmock_call_instance->ExceptionToThrow = cmock_to_throw;\n", + "}\n\n" ].join + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb new file mode 100644 index 0000000..dcf96f2 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb @@ -0,0 +1,103 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockGeneratorPluginExpect + + attr_reader :priority + attr_accessor :config, :utils, :unity_helper, :ordered + + def initialize(config, utils) + @config = config + @ptr_handling = @config.when_ptr + @ordered = @config.enforce_strict_ordering + @utils = utils + @unity_helper = @utils.helpers[:unity_helper] + @priority = 5 + + if (@config.plugins.include? :expect_any_args) + alias :mock_implementation :mock_implementation_might_check_args + else + alias :mock_implementation :mock_implementation_always_check_args + end + end + + def instance_typedefs(function) + lines = "" + lines << " #{function[:return][:type]} ReturnVal;\n" unless (function[:return][:void?]) + lines << " int CallOrder;\n" if (@ordered) + function[:args].each do |arg| + lines << " #{arg[:type]} Expected_#{arg[:name]};\n" + end + lines + end + + def mock_function_declarations(function) + if (function[:args].empty?) + if (function[:return][:void?]) + return "#define #{function[:name]}_Expect() #{function[:name]}_CMockExpect(__LINE__)\n" + + "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line);\n" + else + return "#define #{function[:name]}_ExpectAndReturn(cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, cmock_retval)\n" + + "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" + end + else + if (function[:return][:void?]) + return "#define #{function[:name]}_Expect(#{function[:args_call]}) #{function[:name]}_CMockExpect(__LINE__, #{function[:args_call]})\n" + + "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]});\n" + else + return "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, #{function[:args_call]}, cmock_retval)\n" + + "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]});\n" + end + end + end + + def mock_implementation_always_check_args(function) + lines = "" + function[:args].each do |arg| + lines << @utils.code_verify_an_arg_expectation(function, arg) + end + lines + end + + def mock_implementation_might_check_args(function) + return "" if (function[:args].empty?) + lines = " if (!cmock_call_instance->ExpectAnyArgsBool)\n {\n" + function[:args].each do |arg| + lines << @utils.code_verify_an_arg_expectation(function, arg) + end + lines << " }\n" + lines + end + + def mock_interfaces(function) + lines = "" + func_name = function[:name] + if (function[:return][:void?]) + if (function[:args_string] == "void") + lines << "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line)\n{\n" + else + lines << "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]})\n{\n" + end + else + if (function[:args_string] == "void") + lines << "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n" + else + lines << "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]})\n{\n" + end + end + lines << @utils.code_add_base_expectation(func_name) + lines << @utils.code_call_argument_loader(function) + lines << @utils.code_assign_argument_quickly("cmock_call_instance->ReturnVal", function[:return]) unless (function[:return][:void?]) + lines << "}\n\n" + end + + def mock_verify(function) + " UNITY_SET_DETAIL(CMockString_#{function[:name]});\n" + + " UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == call_instance, cmock_line, CMockStringCalledLess);\n" + + " UNITY_CLR_DETAILS();\n" + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect_any_args.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect_any_args.rb new file mode 100644 index 0000000..0c1c74e --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect_any_args.rb @@ -0,0 +1,53 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockGeneratorPluginExpectAnyArgs + + attr_reader :priority + attr_reader :config, :utils + + def initialize(config, utils) + @config = config + @utils = utils + @priority = 3 + end + + def instance_typedefs(function) + " int ExpectAnyArgsBool;\n" + end + + def mock_function_declarations(function) + unless (function[:args].empty?) + if (function[:return][:void?]) + return "#define #{function[:name]}_ExpectAnyArgs() #{function[:name]}_CMockExpectAnyArgs(__LINE__)\n" + + "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line);\n" + else + return "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) #{function[:name]}_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval)\n" + + "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" + end + else + "" + end + end + + def mock_interfaces(function) + lines = "" + unless (function[:args].empty?) + if (function[:return][:void?]) + lines << "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line)\n{\n" + else + lines << "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n" + end + lines << @utils.code_add_base_expectation(function[:name], true) + unless (function[:return][:void?]) + lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n" + end + lines << " cmock_call_instance->ExpectAnyArgsBool = (int)1;\n" + lines << "}\n\n" + end + return lines + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb new file mode 100644 index 0000000..8f31967 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb @@ -0,0 +1,75 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockGeneratorPluginIgnore + + attr_reader :priority + attr_reader :config, :utils + + def initialize(config, utils) + @config = config + @utils = utils + @priority = 2 + end + + def instance_structure(function) + if (function[:return][:void?]) + " int #{function[:name]}_IgnoreBool;\n" + else + " int #{function[:name]}_IgnoreBool;\n #{function[:return][:type]} #{function[:name]}_FinalReturn;\n" + end + end + + def mock_function_declarations(function) + if (function[:return][:void?]) + return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" + + "void #{function[:name]}_CMockIgnore(void);\n" + else + return "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n" + + "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" + end + end + + def mock_implementation_precheck(function) + lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n" + lines << " UNITY_CLR_DETAILS();\n" + if (function[:return][:void?]) + lines << " return;\n }\n" + else + retval = function[:return].merge( { :name => "cmock_call_instance->ReturnVal"} ) + lines << " if (cmock_call_instance == NULL)\n return Mock.#{function[:name]}_FinalReturn;\n" + lines << " " + @utils.code_assign_argument_quickly("Mock.#{function[:name]}_FinalReturn", retval) unless (retval[:void?]) + lines << " return cmock_call_instance->ReturnVal;\n }\n" + end + lines + end + + def mock_interfaces(function) + lines = "" + if (function[:return][:void?]) + lines << "void #{function[:name]}_CMockIgnore(void)\n{\n" + else + lines << "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n" + end + if (!function[:return][:void?]) + lines << @utils.code_add_base_expectation(function[:name], false) + end + unless (function[:return][:void?]) + lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n" + end + lines << " Mock.#{function[:name]}_IgnoreBool = (int)1;\n" + lines << "}\n\n" + end + + def mock_ignore(function) + " Mock.#{function[:name]}_IgnoreBool = (int) 1;\n" + end + + def mock_verify(function) + func_name = function[:name] + " if (Mock.#{func_name}_IgnoreBool)\n call_instance = CMOCK_GUTS_NONE;\n" + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore_arg.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore_arg.rb new file mode 100644 index 0000000..ef40e50 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore_arg.rb @@ -0,0 +1,42 @@ +class CMockGeneratorPluginIgnoreArg + attr_reader :priority + attr_accessor :utils + + def initialize(config, utils) + @utils = utils + @priority = 10 + end + + def instance_typedefs(function) + lines = "" + function[:args].each do |arg| + lines << " int IgnoreArg_#{arg[:name]};\n" + end + lines + end + + def mock_function_declarations(function) + lines = "" + function[:args].each do |arg| + lines << "#define #{function[:name]}_IgnoreArg_#{arg[:name]}()" + lines << " #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(__LINE__)\n" + lines << "void #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line);\n" + end + lines + end + + def mock_interfaces(function) + lines = [] + func_name = function[:name] + function[:args].each do |arg| + lines << "void #{func_name}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line)\n" + lines << "{\n" + lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " + + "(CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n" + lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp);\n" + lines << " cmock_call_instance->IgnoreArg_#{arg[:name]} = 1;\n" + lines << "}\n\n" + end + lines + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb new file mode 100644 index 0000000..1c1af06 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb @@ -0,0 +1,79 @@ +class CMockGeneratorPluginReturnThruPtr + attr_reader :priority + attr_accessor :utils + + def initialize(config, utils) + @utils = utils + @priority = 9 + end + + def instance_typedefs(function) + lines = "" + function[:args].each do |arg| + if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) + lines << " int ReturnThruPtr_#{arg[:name]}_Used;\n" + lines << " #{arg[:type]} ReturnThruPtr_#{arg[:name]}_Val;\n" + lines << " int ReturnThruPtr_#{arg[:name]}_Size;\n" + end + end + lines + end + + def mock_function_declarations(function) + lines = "" + function[:args].each do |arg| + if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) + lines << "#define #{function[:name]}_ReturnThruPtr_#{arg[:name]}(#{arg[:name]})" + # If the pointer type actually contains an asterisk, we can do sizeof the type (super safe), otherwise + # we need to do a sizeof the dereferenced pointer (which could be a problem if give the wrong size + if (arg[:type][-1] == '*') + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(#{arg[:type][0..-2]}))\n" + else + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n" + end + lines << "#define #{function[:name]}_ReturnArrayThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_len)" + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, (int)(cmock_len * (int)sizeof(*#{arg[:name]})))\n" + lines << "#define #{function[:name]}_ReturnMemThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_size)" + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_size)\n" + lines << "void #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg[:name]}, int cmock_size);\n" + end + end + lines + end + + def mock_interfaces(function) + lines = [] + func_name = function[:name] + function[:args].each do |arg| + arg_name = arg[:name] + if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) + lines << "void #{func_name}_CMockReturnMemThruPtr_#{arg_name}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg_name}, int cmock_size)\n" + lines << "{\n" + lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " + + "(CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n" + lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringPtrPreExp);\n" + lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Used = 1;\n" + lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Val = #{arg_name};\n" + lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Size = cmock_size;\n" + lines << "}\n\n" + end + end + lines + end + + def mock_implementation(function) + lines = [] + function[:args].each do |arg| + arg_name = arg[:name] + if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) + lines << " if (cmock_call_instance->ReturnThruPtr_#{arg_name}_Used)\n" + lines << " {\n" + lines << " UNITY_TEST_ASSERT_NOT_NULL(#{arg_name}, cmock_line, CMockStringPtrIsNULL);\n" + lines << " memcpy((void*)#{arg_name}, (void*)cmock_call_instance->ReturnThruPtr_#{arg_name}_Val,\n" + lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Size);\n" + lines << " }\n" + end + end + lines + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb new file mode 100644 index 0000000..994e85c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb @@ -0,0 +1,253 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockGeneratorUtils + + attr_accessor :config, :helpers, :ordered, :ptr_handling, :arrays, :cexception + + def initialize(config, helpers={}) + @config = config + @ptr_handling = @config.when_ptr + @ordered = @config.enforce_strict_ordering + @arrays = @config.plugins.include? :array + @cexception = @config.plugins.include? :cexception + @expect_any = @config.plugins.include? :expect_any_args + @return_thru_ptr = @config.plugins.include? :return_thru_ptr + @ignore_arg = @config.plugins.include? :ignore_arg + @ignore = @config.plugins.include? :ignore + @treat_as = @config.treat_as + @helpers = helpers + end + + def self.arg_type_with_const(arg) + # Restore any "const" that was removed in header parsing + if arg[:type].include?('*') + arg[:const_ptr?] ? "#{arg[:type]} const" : arg[:type] + else + arg[:const?] ? "const #{arg[:type]}" : arg[:type] + end + end + + def arg_type_with_const(arg) + self.class.arg_type_with_const(arg) + end + + def code_verify_an_arg_expectation(function, arg) + if (@arrays) + case(@ptr_handling) + when :smart then code_verify_an_arg_expectation_with_smart_arrays(function, arg) + when :compare_data then code_verify_an_arg_expectation_with_normal_arrays(function, arg) + when :compare_ptr then raise "ERROR: the array plugin doesn't enjoy working with :compare_ptr only. Disable one option." + end + else + code_verify_an_arg_expectation_with_no_arrays(function, arg) + end + end + + def code_add_base_expectation(func_name, global_ordering_supported=true) + lines = " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_#{func_name}_CALL_INSTANCE));\n" + lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n" + lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);\n" + lines << " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n" + lines << " Mock.#{func_name}_CallInstance = CMock_Guts_MemChain(Mock.#{func_name}_CallInstance, cmock_guts_index);\n" + lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if (@ignore) + lines << " cmock_call_instance->LineNumber = cmock_line;\n" + lines << " cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" if (@ordered and global_ordering_supported) + lines << " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" if (@cexception) + lines << " cmock_call_instance->ExpectAnyArgsBool = (int)0;\n" if (@expect_any) + lines + end + + def code_add_an_arg_expectation(arg, depth=1) + lines = code_assign_argument_quickly("cmock_call_instance->Expected_#{arg[:name]}", arg) + lines << " cmock_call_instance->Expected_#{arg[:name]}_Depth = #{arg[:name]}_Depth;\n" if (@arrays and (depth.class == String)) + lines << " cmock_call_instance->IgnoreArg_#{arg[:name]} = 0;\n" if (@ignore_arg) + lines << " cmock_call_instance->ReturnThruPtr_#{arg[:name]}_Used = 0;\n" if (@return_thru_ptr and ptr_or_str?(arg[:type]) and not arg[:const?]) + lines + end + + def code_assign_argument_quickly(dest, arg) + if (arg[:ptr?] or @treat_as.include?(arg[:type])) + " #{dest} = #{arg[:name]};\n" + else + assert_expr = "sizeof(#{arg[:name]}) == sizeof(#{arg[:type]}) ? 1 : -1" + comment = "/* add #{arg[:type]} to :treat_as_array if this causes an error */" + " memcpy((void*)(&#{dest}), (void*)(&#{arg[:name]}),\n" + + " sizeof(#{arg[:type]}[#{assert_expr}])); #{comment}\n" + end + end + + def code_add_argument_loader(function) + if (function[:args_string] != "void") + if (@arrays) + args_string = function[:args].map do |m| + type = arg_type_with_const(m) + m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}" + end.join(', ') + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string});\n" + + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string})\n{\n" + + function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg, (arg[:ptr?] ? "#{arg[:name]}_Depth" : 1) ) } + + "}\n\n" + else + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]});\n" + + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]})\n{\n" + + function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg) } + + "}\n\n" + end + else + "" + end + end + + def code_call_argument_loader(function) + if (function[:args_string] != "void") + args = function[:args].map do |m| + if (@arrays and m[:ptr?] and not m[:array_data?]) + "#{m[:name]}, 1" + elsif (@arrays and m[:array_size?]) + "#{m[:name]}, #{m[:name]}" + else + m[:name] + end + end + " CMockExpectParameters_#{function[:name]}(cmock_call_instance, #{args.join(', ')});\n" + else + "" + end + end + + def ptr_or_str?(arg_type) + return (arg_type.include? '*' or + @treat_as.fetch(arg_type, "").include? '*') + end + + #private ###################### + + def lookup_expect_type(function, arg) + c_type = arg[:type] + arg_name = arg[:name] + expected = "cmock_call_instance->Expected_#{arg_name}" + ignore = "cmock_call_instance->IgnoreArg_#{arg_name}" + unity_func = if ((arg[:ptr?]) and ((c_type =~ /\*\*/) or (@ptr_handling == :compare_ptr))) + ['UNITY_TEST_ASSERT_EQUAL_PTR', ''] + else + (@helpers.nil? or @helpers[:unity_helper].nil?) ? ["UNITY_TEST_ASSERT_EQUAL",''] : @helpers[:unity_helper].get_helper(c_type) + end + return c_type, arg_name, expected, ignore, unity_func[0], unity_func[1] + end + + def code_verify_an_arg_expectation_with_no_arrays(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg) + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" + lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" + case(unity_func) + when "UNITY_TEST_ASSERT_EQUAL_MEMORY" + c_type_local = c_type.gsub(/\*$/,'') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" + when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" + if (pre == '&') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch); }\n" + end + when /_ARRAY/ + if (pre == '&') + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, CMockStringMismatch); }\n" + end + else + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" + end + lines << " }\n" + lines + end + + def code_verify_an_arg_expectation_with_normal_arrays(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg) + depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1 + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" + lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" + lines << " if (#{pre}#{expected} != #{pre}#{arg_name}) {\n" + case(unity_func) + when "UNITY_TEST_ASSERT_EQUAL_MEMORY" + c_type_local = c_type.gsub(/\*$/,'') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" + when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" + if (pre == '&') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n" + end + when /_ARRAY/ + if (pre == '&') + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n" + end + else + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" + end + lines << " }\n }\n" + lines + end + + def code_verify_an_arg_expectation_with_smart_arrays(function, arg) + c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg) + depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1 + lines = "" + lines << " if (!#{ignore})\n" if @ignore_arg + lines << " {\n" + lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" + lines << " if (#{pre}#{expected} != #{pre}#{arg_name}) {\n" + case(unity_func) + when "UNITY_TEST_ASSERT_EQUAL_MEMORY" + c_type_local = c_type.gsub(/\*$/,'') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n" + when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY" + if (pre == '&') + lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : "") + lines << " else\n" + lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n" + end + when /_ARRAY/ + if (pre == '&') + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch);\n" + else + lines << " if (#{pre}#{expected} == NULL)\n" + lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n" + lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : "") + lines << " else\n" + lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n" + end + else + lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" + end + lines << " }\n }\n" + lines + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb new file mode 100644 index 0000000..0cf1947 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb @@ -0,0 +1,364 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockHeaderParser + + attr_accessor :funcs, :c_attr_noconst, :c_attributes, :treat_as_void, :treat_externs + + def initialize(cfg) + @funcs = [] + @c_strippables = cfg.strippables + @c_attr_noconst = cfg.attributes.uniq - ['const'] + @c_attributes = ['const'] + c_attr_noconst + @c_calling_conventions = cfg.c_calling_conventions.uniq + @treat_as_array = cfg.treat_as_array + @treat_as_void = (['void'] + cfg.treat_as_void).uniq + @declaration_parse_matcher = /([\w\s\*\(\),\[\]]+??)\(([\w\s\*\(\),\.\[\]+-]*)\)$/m + @standards = (['int','short','char','long','unsigned','signed'] + cfg.treat_as.keys).uniq + @array_size_name = cfg.array_size_name + @array_size_type = (['int', 'size_t'] + cfg.array_size_type).uniq + @when_no_prototypes = cfg.when_no_prototypes + @local_as_void = @treat_as_void + @verbosity = cfg.verbosity + @treat_externs = cfg.treat_externs + @c_strippables += ['extern'] if (@treat_externs == :include) #we'll need to remove the attribute if we're allowing externs + end + + def parse(name, source) + @module_name = name.gsub(/\W/,'') + @typedefs = [] + @funcs = [] + function_names = [] + + parse_functions( import_source(source) ).map do |decl| + func = parse_declaration(decl) + unless (function_names.include? func[:name]) + @funcs << func + function_names << func[:name] + end + end + + { :includes => nil, + :functions => @funcs, + :typedefs => @typedefs + } + end + + private if $ThisIsOnlyATest.nil? ################ + + def import_source(source) + + # let's clean up the encoding in case they've done anything weird with the characters we might find + source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil) + + # void must be void for cmock _ExpectAndReturn calls to process properly, not some weird typedef which equates to void + # to a certain extent, this action assumes we're chewing on pre-processed header files, otherwise we'll most likely just get stuff from @treat_as_void + @local_as_void = @treat_as_void + void_types = source.scan(/typedef\s+(?:\(\s*)?void(?:\s*\))?\s+([\w]+)\s*;/) + if void_types + @local_as_void += void_types.flatten.uniq.compact + end + + # smush multiline macros into single line (checking for continuation character at end of line '\') + source.gsub!(/\s*\\\s*/m, ' ') + + #remove comments (block and line, in three steps to ensure correct precedence) + source.gsub!(/(? 1) + #we assign a string first because (no joke) if Ruby 1.9.3 sees this line as a regex, it will crash. + r = "\\{([^\\{\\}]*|\\g<0>)*\\}" + source.gsub!(/#{r}/m, '{ }') + else + while source.gsub!(/\{[^\{\}]*\{[^\{\}]*\}[^\{\}]*\}/m, '{ }') + end + end + + # remove function definitions by stripping off the arguments right now + source.gsub!(/\([^\)]*\)\s*\{[^\}]*\}/m, ";") + + #drop extra white space to make the rest go faster + source.gsub!(/^\s+/, '') # remove extra white space from beginning of line + source.gsub!(/\s+$/, '') # remove extra white space from end of line + source.gsub!(/\s*\(\s*/, '(') # remove extra white space from before left parens + source.gsub!(/\s*\)\s*/, ')') # remove extra white space from before right parens + source.gsub!(/\s+/, ' ') # remove remaining extra white space + + #split lines on semicolons and remove things that are obviously not what we are looking for + src_lines = source.split(/\s*;\s*/).uniq + src_lines.delete_if {|line| line.strip.length == 0} # remove blank lines + src_lines.delete_if {|line| !(line =~ /[\w\s\*]+\(+\s*\*[\*\s]*[\w\s]+(?:\[[\w\s]*\]\s*)+\)+\s*\((?:[\w\s\*]*,?)*\s*\)/).nil?} #remove function pointer arrays + if (@treat_externs == :include) + src_lines.delete_if {|line| !(line =~ /(?:^|\s+)(?:inline)\s+/).nil?} # remove inline functions + else + src_lines.delete_if {|line| !(line =~ /(?:^|\s+)(?:extern|inline)\s+/).nil?} # remove inline and extern functions + end + src_lines.delete_if {|line| line.empty? } #drop empty lines + end + + def parse_functions(source) + funcs = [] + source.each {|line| funcs << line.strip.gsub(/\s+/, ' ') if (line =~ @declaration_parse_matcher)} + if funcs.empty? + case @when_no_prototypes + when :error + raise "ERROR: No function prototypes found!" + when :warn + puts "WARNING: No function prototypes found!" unless (@verbosity < 1) + end + end + return funcs + end + + def parse_type_and_name(arg) + # Split up words and remove known attributes. For pointer types, make sure + # to remove 'const' only when it applies to the pointer itself, not when it + # applies to the type pointed to. For non-pointer types, remove any + # occurrence of 'const'. + arg.gsub!(/(\w)\*/,'\1 *') # pull asterisks away from preceding word + arg.gsub!(/\*(\w)/,'* \1') # pull asterisks away from following word + arg_array = arg.split + arg_info = divine_ptr_and_const(arg) + arg_info[:name] = arg_array[-1] + + attributes = arg.include?('*') ? @c_attr_noconst : @c_attributes + attr_array = [] + type_array = [] + + arg_array[0..-2].each do |word| + if attributes.include?(word) + attr_array << word + elsif @c_calling_conventions.include?(word) + arg_info[:c_calling_convention] = word + else + type_array << word + end + end + + if arg_info[:const_ptr?] + attr_array << 'const' + type_array.delete_at(type_array.rindex('const')) + end + + arg_info[:modifier] = attr_array.join(' ') + arg_info[:type] = type_array.join(' ').gsub(/\s+\*/,'*') # remove space before asterisks + return arg_info + end + + def parse_args(arg_list) + args = [] + arg_list.split(',').each do |arg| + arg.strip! + return args if (arg =~ /^\s*((\.\.\.)|(void))\s*$/) # we're done if we reach void by itself or ... + + arg_info = parse_type_and_name(arg) + arg_info.delete(:modifier) # don't care about this + arg_info.delete(:c_calling_convention) # don't care about this + + # in C, array arguments implicitly degrade to pointers + # make the translation explicit here to simplify later logic + if @treat_as_array[arg_info[:type]] and not arg_info[:ptr?] then + arg_info[:type] = "#{@treat_as_array[arg_info[:type]]}*" + arg_info[:type] = "const #{arg_info[:type]}" if arg_info[:const?] + arg_info[:ptr?] = true + end + + args << arg_info + end + + # Try to find array pair in parameters following this pattern : * , <@array_size_type> <@array_size_name> + args.each_with_index {|val, index| + next_index = index + 1 + if (args.length > next_index) + if (val[:ptr?] == true and args[next_index][:name].match(@array_size_name) and @array_size_type.include?(args[next_index][:type])) + val[:array_data?] = true + args[next_index][:array_size?] = true + end + end + } + + return args + end + + def divine_ptr(arg) + return false unless arg.include? '*' + # treat "const char *" and similar as a string, not a pointer + return false if /(^|\s)(const\s+)?char(\s+const)?\s*\*(?!.*\*)/ =~ arg + return true + end + + def divine_const(arg) + # a non-pointer arg containing "const" is a constant + # an arg containing "const" before the last * is a pointer to a constant + return ( arg.include?('*') ? (/(^|\s|\*)const(\s(\w|\s)*)?\*(?!.*\*)/ =~ arg) + : (/(^|\s)const(\s|$)/ =~ arg) ) ? true : false + end + + def divine_ptr_and_const(arg) + divination = {} + + divination[:ptr?] = divine_ptr(arg) + divination[:const?] = divine_const(arg) + + # an arg containing "const" after the last * is a constant pointer + divination[:const_ptr?] = (/\*(?!.*\*)\s*const(\s|$)/ =~ arg) ? true : false + + return divination + end + + def clean_args(arg_list) + if ((@local_as_void.include?(arg_list.strip)) or (arg_list.empty?)) + return 'void' + else + c=0 + arg_list.gsub!(/(\w+)(?:\s*\[\s*\(*[\s\w+-]*\)*\s*\])+/,'*\1') # magically turn brackets into asterisks, also match for parentheses that come from macros + arg_list.gsub!(/\s+\*/,'*') # remove space to place asterisks with type (where they belong) + arg_list.gsub!(/\*(\w)/,'* \1') # pull asterisks away from arg to place asterisks with type (where they belong) + + #scan argument list for function pointers and replace them with custom types + arg_list.gsub!(/([\w\s\*]+)\(+\s*\*[\*\s]*([\w\s]*)\s*\)+\s*\(((?:[\w\s\*]*,?)*)\s*\)*/) do |m| + + functype = "cmock_#{@module_name}_func_ptr#{@typedefs.size + 1}" + funcret = $1.strip + funcname = $2.strip + funcargs = $3.strip + funconst = '' + if (funcname.include? 'const') + funcname.gsub!('const','').strip! + funconst = 'const ' + end + @typedefs << "typedef #{funcret}(*#{functype})(#{funcargs});" + funcname = "cmock_arg#{c+=1}" if (funcname.empty?) + "#{functype} #{funconst}#{funcname}" + end + + #automatically name unnamed arguments (those that only had a type) + arg_list.split(/\s*,\s*/).map { |arg| + parts = (arg.split - ['struct', 'union', 'enum', 'const', 'const*']) + if ((parts.size < 2) or (parts[-1][-1].chr == '*') or (@standards.include?(parts[-1]))) + "#{arg} cmock_arg#{c+=1}" + else + arg + end + }.join(', ') + end + end + + def parse_declaration(declaration) + decl = {} + + regex_match = @declaration_parse_matcher.match(declaration) + raise "Failed parsing function declaration: '#{declaration}'" if regex_match.nil? + + #grab argument list + args = regex_match[2].strip + + #process function attributes, return type, and name + parsed = parse_type_and_name(regex_match[1]) + + decl[:name] = parsed[:name] + decl[:modifier] = parsed[:modifier] + unless parsed[:c_calling_convention].nil? + decl[:c_calling_convention] = parsed[:c_calling_convention] + end + + rettype = parsed[:type] + rettype = 'void' if (@local_as_void.include?(rettype.strip)) + decl[:return] = { :type => rettype, + :name => 'cmock_to_return', + :str => "#{rettype} cmock_to_return", + :void? => (rettype == 'void'), + :ptr? => parsed[:ptr?], + :const? => parsed[:const?], + :const_ptr? => parsed[:const_ptr?] + } + + #remove default argument statements from mock definitions + args.gsub!(/=\s*[a-zA-Z0-9_\.]+\s*/, ' ') + + #check for var args + if (args =~ /\.\.\./) + decl[:var_arg] = args.match( /[\w\s]*\.\.\./ ).to_s.strip + if (args =~ /\,[\w\s]*\.\.\./) + args = args.gsub!(/\,[\w\s]*\.\.\./,'') + else + args = 'void' + end + else + decl[:var_arg] = nil + end + args = clean_args(args) + decl[:args_string] = args + decl[:args] = parse_args(args) + decl[:args_call] = decl[:args].map{|a| a[:name]}.join(', ') + decl[:contains_ptr?] = decl[:args].inject(false) {|ptr, arg| arg[:ptr?] ? true : ptr } + + if (decl[:return][:type].nil? or decl[:name].nil? or decl[:args].nil? or + decl[:return][:type].empty? or decl[:name].empty?) + raise "Failed Parsing Declaration Prototype!\n" + + " declaration: '#{declaration}'\n" + + " modifier: '#{decl[:modifier]}'\n" + + " return: #{prototype_inspect_hash(decl[:return])}\n" + + " function: '#{decl[:name]}'\n" + + " args: #{prototype_inspect_array_of_hashes(decl[:args])}\n" + end + + return decl + end + + def prototype_inspect_hash(hash) + pairs = [] + hash.each_pair { |name, value| pairs << ":#{name} => #{"'" if (value.class == String)}#{value}#{"'" if (value.class == String)}" } + return "{#{pairs.join(', ')}}" + end + + def prototype_inspect_array_of_hashes(array) + hashes = [] + array.each { |hash| hashes << prototype_inspect_hash(hash) } + case (array.size) + when 0 + return "[]" + when 1 + return "[#{hashes[0]}]" + else + return "[\n #{hashes.join("\n ")}\n ]\n" + end + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb new file mode 100644 index 0000000..cc5ced2 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb @@ -0,0 +1,55 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require 'thread' + +class CMockPluginManager + + attr_accessor :plugins + + def initialize(config, utils) + @plugins = [] + plugins_to_load = [:expect, config.plugins].flatten.uniq.compact + plugins_to_load.each do |plugin| + plugin_name = plugin.to_s + object_name = "CMockGeneratorPlugin" + camelize(plugin_name) + self.class.plugin_require_mutex.synchronize { load_plugin(plugin_name, object_name, config, utils) } + end + @plugins.sort! {|a,b| a.priority <=> b.priority } + end + + def run(method, args=nil) + if args.nil? + return @plugins.collect{ |plugin| plugin.send(method) if plugin.respond_to?(method) }.flatten.join + else + return @plugins.collect{ |plugin| plugin.send(method, args) if plugin.respond_to?(method) }.flatten.join + end + end + + def camelize(lower_case_and_underscored_word) + lower_case_and_underscored_word.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase } + end + + private + + def self.plugin_require_mutex + @mutex ||= Mutex.new + end + + def load_plugin(plugin_name, object_name, config, utils) + begin + unless (Object.const_defined? object_name) + file_name = "#{File.expand_path(File.dirname(__FILE__))}/cmock_generator_plugin_#{plugin_name.downcase}.rb" + require file_name + end + class_name = Object.const_get(object_name) + @plugins << class_name.new(config, utils) + rescue + file_name = "#{File.expand_path(File.dirname(__FILE__))}/cmock_generator_plugin_#{plugin_name.downcase}.rb" + raise "ERROR: CMock unable to load plugin '#{plugin_name}' '#{object_name}' #{file_name}" + end + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_unityhelper_parser.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_unityhelper_parser.rb new file mode 100644 index 0000000..c22db7a --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/lib/cmock_unityhelper_parser.rb @@ -0,0 +1,75 @@ +# ========================================== +# CMock Project - Automatic Mock Generation for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class CMockUnityHelperParser + + attr_accessor :c_types + + def initialize(config) + @config = config + @fallback = @config.plugins.include?(:array) ? 'UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY' : 'UNITY_TEST_ASSERT_EQUAL_MEMORY' + @c_types = map_C_types.merge(import_source) + end + + def get_helper(ctype) + lookup = ctype.gsub(/(?:^|(\S?)(\s*)|(\W))const(?:$|(\s*)(\S)|(\W))/,'\1\3\5\6').strip.gsub(/\s+/,'_') + return [@c_types[lookup], ''] if (@c_types[lookup]) + if (lookup =~ /\*$/) + lookup = lookup.gsub(/\*$/,'') + return [@c_types[lookup], '*'] if (@c_types[lookup]) + else + lookup = lookup + '*' + return [@c_types[lookup], '&'] if (@c_types[lookup]) + end + return ['UNITY_TEST_ASSERT_EQUAL_PTR', ''] if (ctype =~ /cmock_\w+_ptr\d+/) + raise("Don't know how to test #{ctype} and memory tests are disabled!") unless @config.memcmp_if_unknown + return (lookup =~ /\*$/) ? [@fallback, '&'] : [@fallback, ''] + end + + private ########################### + + def map_C_types + c_types = {} + @config.treat_as.each_pair do |ctype, expecttype| + c_type = ctype.gsub(/\s+/,'_') + if (expecttype =~ /\*/) + c_types[c_type] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype.gsub(/\*/,'')}_ARRAY" + else + c_types[c_type] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype}" + c_types[c_type+'*'] ||= "UNITY_TEST_ASSERT_EQUAL_#{expecttype}_ARRAY" + end + end + c_types + end + + def import_source + source = @config.load_unity_helper + return {} if source.nil? + c_types = {} + source = source.gsub(/\/\/.*$/, '') #remove line comments + source = source.gsub(/\/\*.*?\*\//m, '') #remove block comments + + #scan for comparison helpers + match_regex = Regexp.new('^\s*#define\s+(UNITY_TEST_ASSERT_EQUAL_(\w+))\s*\(' + Array.new(4,'\s*\w+\s*').join(',') + '\)') + pairs = source.scan(match_regex).flatten.compact + (pairs.size/2).times do |i| + expect = pairs[i*2] + ctype = pairs[(i*2)+1] + c_types[ctype] = expect unless expect.include?("_ARRAY") + end + + #scan for array variants of those helpers + match_regex = Regexp.new('^\s*#define\s+(UNITY_TEST_ASSERT_EQUAL_(\w+_ARRAY))\s*\(' + Array.new(5,'\s*\w+\s*').join(',') + '\)') + pairs = source.scan(match_regex).flatten.compact + (pairs.size/2).times do |i| + expect = pairs[i*2] + ctype = pairs[(i*2)+1] + c_types[ctype.gsub('_ARRAY','*')] = expect + end + + c_types + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/release/build.info b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/release/build.info new file mode 100644 index 0000000..a62fe11 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/release/build.info @@ -0,0 +1,2 @@ +217 + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/release/version.info b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/release/version.info new file mode 100644 index 0000000..1b6799f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/release/version.info @@ -0,0 +1,2 @@ +2.4.6 + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock.c new file mode 100644 index 0000000..5e5cb6c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock.c @@ -0,0 +1,216 @@ +/* ========================================== + CMock Project - Automatic Mock Generation for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include "cmock.h" + +//public constants to be used by mocks +const char* CMockStringOutOfMemory = "CMock has run out of memory. Please allocate more."; +const char* CMockStringCalledMore = "Called more times than expected."; +const char* CMockStringCalledLess = "Called fewer times than expected."; +const char* CMockStringCalledEarly = "Called earlier than expected."; +const char* CMockStringCalledLate = "Called later than expected."; +const char* CMockStringCallOrder = "Called out of order."; +const char* CMockStringIgnPreExp = "IgnoreArg called before Expect."; +const char* CMockStringPtrPreExp = "ReturnThruPtr called before Expect."; +const char* CMockStringPtrIsNULL = "Pointer is NULL."; +const char* CMockStringExpNULL = "Expected NULL."; +const char* CMockStringMismatch = "Function called with unexpected argument value."; + +//private variables +#ifdef CMOCK_MEM_DYNAMIC +static unsigned char* CMock_Guts_Buffer = NULL; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; +#else +static unsigned char CMock_Guts_Buffer[CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE]; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; +#endif + +//------------------------------------------------------- +// CMock_Guts_MemNew +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size) +{ + CMOCK_MEM_INDEX_TYPE index; + + //verify arguments valid (we must be allocating space for at least 1 byte, and the existing chain must be in memory somewhere) + if (size < 1) + return CMOCK_GUTS_NONE; + + //verify we have enough room + size = size + CMOCK_MEM_INDEX_SIZE; + if (size & CMOCK_MEM_ALIGN_MASK) + size = (size + CMOCK_MEM_ALIGN_MASK) & ~CMOCK_MEM_ALIGN_MASK; + if ((CMock_Guts_BufferSize - CMock_Guts_FreePtr) < size) + { +#ifndef CMOCK_MEM_DYNAMIC + return CMOCK_GUTS_NONE; // nothing we can do; our static buffer is out of memory +#else + // our dynamic buffer does not have enough room; request more via realloc() + CMOCK_MEM_INDEX_TYPE new_buffersize = CMock_Guts_BufferSize + CMOCK_MEM_SIZE + size; + unsigned char* new_buffer = realloc(CMock_Guts_Buffer, (size_t)new_buffersize); + if (new_buffer == NULL) + return CMOCK_GUTS_NONE; // realloc() failed; out of memory + CMock_Guts_Buffer = new_buffer; + CMock_Guts_BufferSize = new_buffersize; +#endif + } + + //determine where we're putting this new block, and init its pointer to be the end of the line + index = CMock_Guts_FreePtr + CMOCK_MEM_INDEX_SIZE; + *(CMOCK_MEM_INDEX_TYPE*)(&CMock_Guts_Buffer[CMock_Guts_FreePtr]) = CMOCK_GUTS_NONE; + CMock_Guts_FreePtr += size; + + return index; +} + +//------------------------------------------------------- +// CMock_Guts_MemChain +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index) +{ + CMOCK_MEM_INDEX_TYPE index; + void* root; + void* obj; + void* next; + + if (root_index == CMOCK_GUTS_NONE) + { + //if there is no root currently, we return this object as the root of the chain + return obj_index; + } + else + { + //reject illegal nodes + if ((root_index < CMOCK_MEM_ALIGN_SIZE) || (root_index >= CMock_Guts_FreePtr)) + { + return CMOCK_GUTS_NONE; + } + if ((obj_index < CMOCK_MEM_ALIGN_SIZE) || (obj_index >= CMock_Guts_FreePtr)) + { + return CMOCK_GUTS_NONE; + } + + root = (void*)(&CMock_Guts_Buffer[root_index]); + obj = (void*)(&CMock_Guts_Buffer[obj_index]); + + //find the end of the existing chain and add us + next = root; + do { + index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE); + if (index >= CMock_Guts_FreePtr) + return CMOCK_GUTS_NONE; + if (index > 0) + next = (void*)(&CMock_Guts_Buffer[index]); + } while (index > 0); + *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE) = (CMOCK_MEM_INDEX_TYPE)((CMOCK_MEM_PTR_AS_INT)obj - (CMOCK_MEM_PTR_AS_INT)CMock_Guts_Buffer); + return root_index; + } +} + +//------------------------------------------------------- +// CMock_Guts_MemNext +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index) +{ + CMOCK_MEM_INDEX_TYPE index; + void* previous_item; + + //There is nothing "next" if the pointer isn't from our buffer + if ((previous_item_index < CMOCK_MEM_ALIGN_SIZE) || (previous_item_index >= CMock_Guts_FreePtr)) + return CMOCK_GUTS_NONE; + previous_item = (void*)(&CMock_Guts_Buffer[previous_item_index]); + + //if the pointer is good, then use it to look up the next index + //(we know the first element always goes in zero, so NEXT must always be > 1) + index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)previous_item - CMOCK_MEM_INDEX_SIZE); + if ((index > 1) && (index < CMock_Guts_FreePtr)) + return index; + else + return CMOCK_GUTS_NONE; +} + +//------------------------------------------------------- +// CMock_Guts_MemEndOfChain +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) +{ + CMOCK_MEM_INDEX_TYPE index = root_index; + CMOCK_MEM_INDEX_TYPE next_index; + + for (next_index = root_index; + next_index != CMOCK_GUTS_NONE; + next_index = CMock_Guts_MemNext(index)) + { + index = next_index; + } + + return index; +} + +//------------------------------------------------------- +// CMock_GetAddressFor +//------------------------------------------------------- +void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) +{ + if ((index >= CMOCK_MEM_ALIGN_SIZE) && (index < CMock_Guts_FreePtr)) + { + return (void*)(&CMock_Guts_Buffer[index]); + } + else + { + return NULL; + } +} + +//------------------------------------------------------- +// CMock_Guts_MemBytesCapacity +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) +{ + return (sizeof(CMock_Guts_Buffer) - CMOCK_MEM_ALIGN_SIZE); +} + +//------------------------------------------------------- +// CMock_Guts_MemBytesFree +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void) +{ + return CMock_Guts_BufferSize - CMock_Guts_FreePtr; +} + +//------------------------------------------------------- +// CMock_Guts_MemBytesUsed +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void) +{ + return CMock_Guts_FreePtr - CMOCK_MEM_ALIGN_SIZE; +} + +//------------------------------------------------------- +// CMock_Guts_MemFreeAll +//------------------------------------------------------- +void CMock_Guts_MemFreeAll(void) +{ + CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; //skip the very beginning +} + +//------------------------------------------------------- +// CMock_Guts_MemFreeFinal +//------------------------------------------------------- +void CMock_Guts_MemFreeFinal(void) +{ + CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; +#ifdef CMOCK_MEM_DYNAMIC + if (CMock_Guts_Buffer) + { + free(CMock_Guts_Buffer); + CMock_Guts_Buffer = NULL; + } +#endif +} + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock.h new file mode 100644 index 0000000..e96546d --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock.h @@ -0,0 +1,40 @@ +/* ========================================== + CMock Project - Automatic Mock Generation for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef CMOCK_FRAMEWORK_H +#define CMOCK_FRAMEWORK_H + +#include "cmock_internals.h" + +#define CMOCK_VERSION_MAJOR 2 +#define CMOCK_VERSION_MINOR 5 +#define CMOCK_VERSION_BUILD 0 +#define CMOCK_VERSION ((CMOCK_VERSION_MAJOR << 16) | (CMOCK_VERSION_MINOR << 8) | CMOCK_VERSION_BUILD) + +//should be big enough to index full range of CMOCK_MEM_MAX +#ifndef CMOCK_MEM_INDEX_TYPE +#define CMOCK_MEM_INDEX_TYPE unsigned int +#endif + +#define CMOCK_GUTS_NONE (0) + +//------------------------------------------------------- +// Memory API +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index); + +void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index); + +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void); +void CMock_Guts_MemFreeAll(void); +void CMock_Guts_MemFreeFinal(void); + +#endif //CMOCK_FRAMEWORK diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock_internals.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock_internals.h new file mode 100644 index 0000000..ae2e496 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/cmock_internals.h @@ -0,0 +1,91 @@ +/* ========================================== + CMock Project - Automatic Mock Generation for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef CMOCK_FRAMEWORK_INTERNALS_H +#define CMOCK_FRAMEWORK_INTERNALS_H + +#include "unity.h" + +//These are constants that the generated mocks have access to +extern const char* CMockStringOutOfMemory; +extern const char* CMockStringCalledMore; +extern const char* CMockStringCalledLess; +extern const char* CMockStringCalledEarly; +extern const char* CMockStringCalledLate; +extern const char* CMockStringCallOrder; +extern const char* CMockStringIgnPreExp; +extern const char* CMockStringPtrPreExp; +extern const char* CMockStringPtrIsNULL; +extern const char* CMockStringExpNULL; +extern const char* CMockStringMismatch; + +//define CMOCK_MEM_DYNAMIC to grab memory as needed with malloc +//when you do that, CMOCK_MEM_SIZE is used for incremental size instead of total +#ifdef CMOCK_MEM_STATIC +#undef CMOCK_MEM_DYNAMIC +#endif + +#ifdef CMOCK_MEM_DYNAMIC +#include +#endif + +//this is used internally during pointer arithmetic. make sure this type is the same size as the target's pointer type +#ifndef CMOCK_MEM_PTR_AS_INT +#ifdef UNITY_POINTER_WIDTH +#ifdef UNITY_INT_WIDTH +#if UNITY_POINTER_WIDTH == UNITY_INT_WIDTH +#define CMOCK_MEM_PTR_AS_INT unsigned int +#endif +#endif +#endif +#endif + +#ifndef CMOCK_MEM_PTR_AS_INT +#ifdef UNITY_POINTER_WIDTH +#ifdef UNITY_LONG_WIDTH +#if UNITY_POINTER_WIDTH == UNITY_LONG_WIDTH +#define CMOCK_MEM_PTR_AS_INT unsigned long +#endif +#if UNITY_POINTER_WIDTH > UNITY_LONG_WIDTH +#define CMOCK_MEM_PTR_AS_INT unsigned long long +#endif +#endif +#endif +#endif + +#ifndef CMOCK_MEM_PTR_AS_INT +#define CMOCK_MEM_PTR_AS_INT unsigned long +#endif + +//0 for no alignment, 1 for 16-bit, 2 for 32-bit, 3 for 64-bit +#ifndef CMOCK_MEM_ALIGN + #ifdef UNITY_LONG_WIDTH + #if (UNITY_LONG_WIDTH == 16) + #define CMOCK_MEM_ALIGN (1) + #elif (UNITY_LONG_WIDTH == 32) + #define CMOCK_MEM_ALIGN (2) + #elif (UNITY_LONG_WIDTH == 64) + #define CMOCK_MEM_ALIGN (3) + #else + #define CMOCK_MEM_ALIGN (2) + #endif + #else + #define CMOCK_MEM_ALIGN (2) + #endif +#endif + +//amount of memory to allow cmock to use in its internal heap +#ifndef CMOCK_MEM_SIZE +#define CMOCK_MEM_SIZE (32768) +#endif + +//automatically calculated defs for easier reading +#define CMOCK_MEM_ALIGN_SIZE (CMOCK_MEM_INDEX_TYPE)(1u << CMOCK_MEM_ALIGN) +#define CMOCK_MEM_ALIGN_MASK (CMOCK_MEM_INDEX_TYPE)(CMOCK_MEM_ALIGN_SIZE - 1) +#define CMOCK_MEM_INDEX_SIZE (CMOCK_MEM_INDEX_TYPE)(CMOCK_MEM_PTR_AS_INT)((sizeof(CMOCK_MEM_INDEX_TYPE) > CMOCK_MEM_ALIGN_SIZE) ? sizeof(CMOCK_MEM_INDEX_TYPE) : CMOCK_MEM_ALIGN_SIZE) + + +#endif //CMOCK_FRAMEWORK_INTERNALS diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/meson.build b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/meson.build new file mode 100644 index 0000000..e375e81 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/cmock/src/meson.build @@ -0,0 +1,17 @@ +################################################################################### +# # +# NAME: meson.build # +# # +# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. # +# WRITTEN BY: Michael Brockus. # +# # +# License: MIT # +# # +################################################################################### + +cmock_dir = include_directories('.') + +cmock_lib = static_library(meson.project_name(), + sources: ['cmock.c'], + dependencies: [unity_dep], + include_directories: cmock_dir) diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/deep_merge/lib/deep_merge.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/deep_merge/lib/deep_merge.rb new file mode 100644 index 0000000..4c4b761 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/deep_merge/lib/deep_merge.rb @@ -0,0 +1,211 @@ +module DeepMerge + + MAJOR_VERSION = 0 + MINOR_VERSION = 1 + FIX_VERSION = 0 + VERSION = "#{MAJOR_VERSION}.#{MINOR_VERSION}.#{FIX_VERSION}" + + class InvalidParameter < StandardError; end + + DEFAULT_FIELD_KNOCKOUT_PREFIX = '--' + + module DeepMergeHash + # ko_hash_merge! will merge and knockout elements prefixed with DEFAULT_FIELD_KNOCKOUT_PREFIX + def ko_deep_merge!(source, options = {}) + default_opts = {:knockout_prefix => "--", :preserve_unmergeables => false} + DeepMerge::deep_merge!(source, self, default_opts.merge(options)) + end + + # deep_merge! will merge and overwrite any unmergeables in destination hash + def deep_merge!(source, options = {}) + default_opts = {:preserve_unmergeables => false} + DeepMerge::deep_merge!(source, self, default_opts.merge(options)) + end + + # deep_merge will merge and skip any unmergeables in destination hash + def deep_merge(source, options = {}) + default_opts = {:preserve_unmergeables => true} + DeepMerge::deep_merge!(source, self, default_opts.merge(options)) + end + + end # DeepMergeHashExt + + # Deep Merge core documentation. + # deep_merge! method permits merging of arbitrary child elements. The two top level + # elements must be hashes. These hashes can contain unlimited (to stack limit) levels + # of child elements. These child elements to not have to be of the same types. + # Where child elements are of the same type, deep_merge will attempt to merge them together. + # Where child elements are not of the same type, deep_merge will skip or optionally overwrite + # the destination element with the contents of the source element at that level. + # So if you have two hashes like this: + # source = {:x => [1,2,3], :y => 2} + # dest = {:x => [4,5,'6'], :y => [7,8,9]} + # dest.deep_merge!(source) + # Results: {:x => [1,2,3,4,5,'6'], :y => 2} + # By default, "deep_merge!" will overwrite any unmergeables and merge everything else. + # To avoid this, use "deep_merge" (no bang/exclamation mark) + # + # Options: + # Options are specified in the last parameter passed, which should be in hash format: + # hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '--'}) + # :preserve_unmergeables DEFAULT: false + # Set to true to skip any unmergeable elements from source + # :knockout_prefix DEFAULT: nil + # Set to string value to signify prefix which deletes elements from existing element + # :sort_merged_arrays DEFAULT: false + # Set to true to sort all arrays that are merged together + # :unpack_arrays DEFAULT: nil + # Set to string value to run "Array::join" then "String::split" against all arrays + # :merge_debug DEFAULT: false + # Set to true to get console output of merge process for debugging + # + # Selected Options Details: + # :knockout_prefix => The purpose of this is to provide a way to remove elements + # from existing Hash by specifying them in a special way in incoming hash + # source = {:x => ['--1', '2']} + # dest = {:x => ['1', '3']} + # dest.ko_deep_merge!(source) + # Results: {:x => ['2','3']} + # Additionally, if the knockout_prefix is passed alone as a string, it will cause + # the entire element to be removed: + # source = {:x => '--'} + # dest = {:x => [1,2,3]} + # dest.ko_deep_merge!(source) + # Results: {:x => ""} + # :unpack_arrays => The purpose of this is to permit compound elements to be passed + # in as strings and to be converted into discrete array elements + # irsource = {:x => ['1,2,3', '4']} + # dest = {:x => ['5','6','7,8']} + # dest.deep_merge!(source, {:unpack_arrays => ','}) + # Results: {:x => ['1','2','3','4','5','6','7','8'} + # Why: If receiving data from an HTML form, this makes it easy for a checkbox + # to pass multiple values from within a single HTML element + # + # There are many tests for this library - and you can learn more about the features + # and usages of deep_merge! by just browsing the test examples + def DeepMerge.deep_merge!(source, dest, options = {}) + # turn on this line for stdout debugging text + merge_debug = options[:merge_debug] || false + overwrite_unmergeable = !options[:preserve_unmergeables] + knockout_prefix = options[:knockout_prefix] || nil + if knockout_prefix == "" then raise InvalidParameter, "knockout_prefix cannot be an empty string in deep_merge!"; end + if knockout_prefix && !overwrite_unmergeable then raise InvalidParameter, "overwrite_unmergeable must be true if knockout_prefix is specified in deep_merge!"; end + # if present: we will split and join arrays on this char before merging + array_split_char = options[:unpack_arrays] || false + # request that we sort together any arrays when they are merged + sort_merged_arrays = options[:sort_merged_arrays] || false + di = options[:debug_indent] || '' + # do nothing if source is nil + if source.nil? || (source.respond_to?(:blank?) && source.blank?) then return dest; end + # if dest doesn't exist, then simply copy source to it + if dest.nil? && overwrite_unmergeable then dest = source; return dest; end + + puts "#{di}Source class: #{source.class.inspect} :: Dest class: #{dest.class.inspect}" if merge_debug + if source.kind_of?(Hash) + puts "#{di}Hashes: #{source.inspect} :: #{dest.inspect}" if merge_debug + source.each do |src_key, src_value| + if dest.kind_of?(Hash) + puts "#{di} looping: #{src_key.inspect} => #{src_value.inspect} :: #{dest.inspect}" if merge_debug + if not dest[src_key].nil? + puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug + dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + ' ')) + else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!) + puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug + # note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others) + begin + src_dup = src_value.dup # we dup src_value if possible because we're going to merge into it (since dest is empty) + rescue TypeError + src_dup = src_value + end + dest[src_key] = deep_merge!(src_value, src_dup, options.merge(:debug_indent => di + ' ')) + end + else # dest isn't a hash, so we overwrite it completely (if permitted) + if overwrite_unmergeable + puts "#{di} overwriting dest: #{src_key.inspect} => #{src_value.inspect} -over-> #{dest.inspect}" if merge_debug + dest = overwrite_unmergeables(source, dest, options) + end + end + end + elsif source.kind_of?(Array) + puts "#{di}Arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug + # if we are instructed, join/split any source arrays before processing + if array_split_char + puts "#{di} split/join on source: #{source.inspect}" if merge_debug + source = source.join(array_split_char).split(array_split_char) + if dest.kind_of?(Array) then dest = dest.join(array_split_char).split(array_split_char); end + end + # if there's a naked knockout_prefix in source, that means we are to truncate dest + if source.index(knockout_prefix) then dest = clear_or_nil(dest); source.delete(knockout_prefix); end + if dest.kind_of?(Array) + if knockout_prefix + print "#{di} knocking out: " if merge_debug + # remove knockout prefix items from both source and dest + source.delete_if do |ko_item| + retval = false + item = ko_item.respond_to?(:gsub) ? ko_item.gsub(%r{^#{knockout_prefix}}, "") : ko_item + if item != ko_item + print "#{ko_item} - " if merge_debug + dest.delete(item) + dest.delete(ko_item) + retval = true + end + retval + end + puts if merge_debug + end + puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug + dest = dest | source + if sort_merged_arrays then dest.sort!; end + elsif overwrite_unmergeable + puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug + dest = overwrite_unmergeables(source, dest, options) + end + else # src_hash is not an array or hash, so we'll have to overwrite dest + puts "#{di}Others: #{source.inspect} :: #{dest.inspect}" if merge_debug + dest = overwrite_unmergeables(source, dest, options) + end + puts "#{di}Returning #{dest.inspect}" if merge_debug + dest + end # deep_merge! + + # allows deep_merge! to uniformly handle overwriting of unmergeable entities + def DeepMerge::overwrite_unmergeables(source, dest, options) + merge_debug = options[:merge_debug] || false + overwrite_unmergeable = !options[:preserve_unmergeables] + knockout_prefix = options[:knockout_prefix] || false + di = options[:debug_indent] || '' + if knockout_prefix && overwrite_unmergeable + if source.kind_of?(String) # remove knockout string from source before overwriting dest + src_tmp = source.gsub(%r{^#{knockout_prefix}},"") + elsif source.kind_of?(Array) # remove all knockout elements before overwriting dest + src_tmp = source.delete_if {|ko_item| ko_item.kind_of?(String) && ko_item.match(%r{^#{knockout_prefix}}) } + else + src_tmp = source + end + if src_tmp == source # if we didn't find a knockout_prefix then we just overwrite dest + puts "#{di}#{src_tmp.inspect} -over-> #{dest.inspect}" if merge_debug + dest = src_tmp + else # if we do find a knockout_prefix, then we just delete dest + puts "#{di}\"\" -over-> #{dest.inspect}" if merge_debug + dest = "" + end + elsif overwrite_unmergeable + dest = source + end + dest + end + + def DeepMerge::clear_or_nil(obj) + if obj.respond_to?(:clear) + obj.clear + else + obj = nil + end + obj + end + +end # module DeepMerge + +class Hash + include DeepMerge::DeepMergeHash +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/diy/lib/diy.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/diy/lib/diy.rb new file mode 100644 index 0000000..581afc7 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/diy/lib/diy.rb @@ -0,0 +1,403 @@ +require 'diy/factory.rb' +require 'yaml' +require 'set' + +module DIY #:nodoc:# + VERSION = '1.1.2' + class Context + + class << self + # Enable / disable automatic requiring of libraries. Default: true + attr_accessor :auto_require + end + @auto_require = true + + # Accepts a Hash defining the object context (usually loaded from objects.yml), and an additional + # Hash containing objects to inject into the context. + def initialize(context_hash, extra_inputs={}) + raise "Nil context hash" unless context_hash + raise "Need a hash" unless context_hash.kind_of?(Hash) + [ "[]", "keys" ].each do |mname| + unless extra_inputs.respond_to?(mname) + raise "Extra inputs must respond to hash-like [] operator and methods #keys and #each" + end + end + + # store extra inputs + if extra_inputs.kind_of?(Hash) + @extra_inputs= {} + extra_inputs.each { |k,v| @extra_inputs[k.to_s] = v } # smooth out the names + else + @extra_inputs = extra_inputs + end + + collect_object_and_subcontext_defs context_hash + + # init the cache + @cache = {} + @cache['this_context'] = self + end + + + # Convenience: create a new DIY::Context by loading from a String (or open file handle.) + def self.from_yaml(io_or_string, extra_inputs={}) + raise "nil input to YAML" unless io_or_string + Context.new(YAML.load(io_or_string), extra_inputs) + end + + # Convenience: create a new DIY::Context by loading from the named file. + def self.from_file(fname, extra_inputs={}) + raise "nil file name" unless fname + self.from_yaml(File.read(fname), extra_inputs) + end + + # Return a reference to the object named. If necessary, the object will + # be instantiated on first use. If the object is non-singleton, a new + # object will be produced each time. + def get_object(obj_name) + key = obj_name.to_s + obj = @cache[key] + unless obj + if extra_inputs_has(key) + obj = @extra_inputs[key] + else + case @defs[key] + when MethodDef + obj = construct_method(key) + when FactoryDef + obj = construct_factory(key) + @cache[key] = obj + else + obj = construct_object(key) + @cache[key] = obj if @defs[key].singleton? + end + end + end + obj + end + alias :[] :get_object + + # Inject a named object into the Context. This must be done before the Context has instantiated the + # object in question. + def set_object(obj_name,obj) + key = obj_name.to_s + raise "object '#{key}' already exists in context" if @cache.keys.include?(key) + @cache[key] = obj + end + alias :[]= :set_object + + # Provide a listing of object names + def keys + (@defs.keys.to_set + @extra_inputs.keys.to_set).to_a + end + + # Instantiate and yield the named subcontext + def within(sub_context_name) + # Find the subcontext definitaion: + context_def = @sub_context_defs[sub_context_name.to_s] + raise "No sub-context named #{sub_context_name}" unless context_def + # Instantiate a new context using self as parent: + context = Context.new( context_def, self ) + + yield context + end + + # Returns true if the context contains an object with the given name + def contains_object(obj_name) + key = obj_name.to_s + @defs.keys.member?(key) or extra_inputs_has(key) + end + + # Every top level object in the Context is instantiated. This is especially useful for + # systems that have "floating observers"... objects that are never directly accessed, who + # would thus never be instantiated by coincedence. This does not build any subcontexts + # that may exist. + def build_everything + @defs.keys.each { |k| self[k] } + end + alias :build_all :build_everything + alias :preinstantiate_singletons :build_everything + + private + + def collect_object_and_subcontext_defs(context_hash) + @defs = {} + @sub_context_defs = {} + get_defs_from context_hash + end + + def get_defs_from(hash, namespace=nil) + hash.each do |name,info| + # we modify the info hash below so it's important to have a new + # instance to play with + info = info.dup if info + + # see if we are building a factory + if info and info.has_key?('builds') + unless info.has_key?('auto_require') + info['auto_require'] = self.class.auto_require + end + + if namespace + info['builds'] = namespace.build_classname(info['builds']) + end + @defs[name] = FactoryDef.new({:name => name, + :target => info['builds'], + :library => info['library'], + :auto_require => info['auto_require']}) + next + end + + name = name.to_s + case name + when /^\+/ + # subcontext + @sub_context_defs[name.gsub(/^\+/,'')] = info + + when /^using_namespace/ + # namespace: use a module(s) prefix for the classname of contained object defs + # NOTE: namespacing is NOT scope... it's just a convenient way to setup class names for a group of objects. + get_defs_from info, parse_namespace(name) + when /^method\s/ + key_name = name.gsub(/^method\s/, "") + @defs[key_name] = MethodDef.new(:name => key_name, + :object => info['object'], + :method => info['method'], + :attach => info['attach']) + else + # Normal object def + info ||= {} + if extra_inputs_has(name) + raise ConstructionError.new(name, "Object definition conflicts with parent context") + end + unless info.has_key?('auto_require') + info['auto_require'] = self.class.auto_require + end + if namespace + if info['class'] + info['class'] = namespace.build_classname(info['class']) + else + info['class'] = namespace.build_classname(name) + end + end + + @defs[name] = ObjectDef.new(:name => name, :info => info) + + end + end + end + + def construct_method(key) + method_definition = @defs[key] + object = get_object(method_definition.object) + method = object.method(method_definition.method) + + unless method_definition.attach.nil? + instance_var_name = "@__diy_#{method_definition.object}" + + method_definition.attach.each do |object_key| + get_object(object_key).instance_eval do + instance_variable_set(instance_var_name, object) + eval %|def #{key}(*args) + #{instance_var_name}.#{method_definition.method}(*args) + end| + end + end + end + + return method + rescue Exception => oops + build_and_raise_construction_error(key, oops) + end + + def construct_object(key) + # Find the object definition + obj_def = @defs[key] + raise "No object definition for '#{key}'" unless obj_def + # If object def mentions a library, load it + require obj_def.library if obj_def.library + + # Resolve all components for the object + arg_hash = {} + obj_def.components.each do |name,value| + case value + when Lookup + arg_hash[name.to_sym] = get_object(value.name) + when StringValue + arg_hash[name.to_sym] = value.literal_value + else + raise "Cannot cope with component definition '#{value.inspect}'" + end + end + # Get a reference to the class for the object + big_c = get_class_for_name_with_module_delimeters(obj_def.class_name) + # Make and return the instance + if obj_def.use_class_directly? + return big_c + elsif arg_hash.keys.size > 0 + return big_c.new(arg_hash) + else + return big_c.new + end + rescue Exception => oops + build_and_raise_construction_error(key, oops) + end + + def build_and_raise_construction_error(key, oops) + cerr = ConstructionError.new(key,oops) + cerr.set_backtrace(oops.backtrace) + raise cerr + end + + def get_class_for_name_with_module_delimeters(class_name) + class_name.split(/::/).inject(Object) do |mod,const_name| mod.const_get(const_name) end + end + + def extra_inputs_has(key) + if key.nil? or key.strip == '' + raise ArgumentError.new("Cannot lookup objects with nil keys") + end + @extra_inputs.keys.member?(key) or @extra_inputs.keys.member?(key.to_sym) + end + + def parse_namespace(str) + Namespace.new(str) + end + end + + class Namespace #:nodoc:# + def initialize(str) + # 'using_namespace Animal Reptile' + parts = str.split(/\s+/) + raise "Namespace definitions must begin with 'using_namespace'" unless parts[0] == 'using_namespace' + parts.shift + + if parts.length > 0 and parts[0] =~ /::/ + parts = parts[0].split(/::/) + end + + raise NamespaceError, "Namespace needs to indicate a module" if parts.empty? + + @module_nest = parts + end + + def build_classname(name) + [ @module_nest, Infl.camelize(name) ].flatten.join("::") + end + end + + class Lookup #:nodoc: + attr_reader :name + def initialize(obj_name) + @name = obj_name + end + end + + class MethodDef #:nodoc: + attr_accessor :name, :object, :method, :attach + + def initialize(opts) + @name, @object, @method, @attach = opts[:name], opts[:object], opts[:method], opts[:attach] + end + end + + class ObjectDef #:nodoc: + attr_accessor :name, :class_name, :library, :components + def initialize(opts) + name = opts[:name] + raise "Can't make an ObjectDef without a name" if name.nil? + + info = opts[:info] || {} + info = info.clone + + @components = {} + + # Object name + @name = name + + # Class name + @class_name = info.delete 'class' + @class_name ||= info.delete 'type' + @class_name ||= Infl.camelize(@name) + + # Auto Require + @auto_require = info.delete 'auto_require' + + # Library + @library = info.delete 'library' + @library ||= info.delete 'lib' + @library ||= Infl.underscore(@class_name) if @auto_require + + # Use Class Directly + @use_class_directly = info.delete 'use_class_directly' + + # Auto-compose + compose = info.delete 'compose' + if compose + case compose + when Array + auto_names = compose.map { |x| x.to_s } + when String + auto_names = compose.split(',').map { |x| x.to_s.strip } + when Symbol + auto_names = [ compose.to_s ] + else + raise "Cannot auto compose object #{@name}, bad 'compose' format: #{compose.inspect}" + end + end + auto_names ||= [] + auto_names.each do |cname| + @components[cname] = Lookup.new(cname) + end + + # Singleton status + if info['singleton'].nil? + @singleton = true + else + @singleton = info['singleton'] + end + info.delete 'singleton' + + # Remaining keys + info.each do |key,val| + @components[key.to_s] = Lookup.new(val.to_s) + end + + end + + def singleton? + @singleton + end + + def use_class_directly? + @use_class_directly == true + end + + end + + class ConstructionError < RuntimeError #:nodoc:# + def initialize(object_name, cause=nil) + object_name = object_name + cause = cause + m = "Failed to construct '#{object_name}'" + if cause + m << "\n ...caused by:\n >>> #{cause}" + end + super m + end + end + + class NamespaceError < RuntimeError #:nodoc:# + end + + module Infl #:nodoc:# + # Ganked this from Inflector: + def self.camelize(lower_case_and_underscored_word) + lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase } + end + # Ganked this from Inflector: + def self.underscore(camel_cased_word) + camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase + end + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/diy/lib/diy/factory.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/diy/lib/diy/factory.rb new file mode 100644 index 0000000..d2566c5 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/diy/lib/diy/factory.rb @@ -0,0 +1,36 @@ +module DIY #:nodoc:# + class FactoryDef #:nodoc: + attr_accessor :name, :target, :class_name, :library + + def initialize(opts) + @name, @target, @library, @auto_require = + opts[:name], opts[:target], opts[:library], opts[:auto_require] + + @class_name = Infl.camelize(@target) + @library ||= Infl.underscore(@class_name) if @auto_require + end + end + + class Context + def construct_factory(key) + factory_def = @defs[key] +# puts "requiring #{factory_def.library}" + require factory_def.library if factory_def.library + + big_c = get_class_for_name_with_module_delimeters(factory_def.class_name) + + FactoryFactory.new(big_c) + end + end + + class FactoryFactory + def initialize(clazz) + @class_to_create = clazz + end + + def create(*args) + @class_to_create.new(*args) + end + end +end + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/colour_prompt.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/colour_prompt.rb new file mode 100644 index 0000000..85cbfd8 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/colour_prompt.rb @@ -0,0 +1,119 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +if RUBY_PLATFORM =~ /(win|w)32$/ + begin + require 'Win32API' + rescue LoadError + puts 'ERROR! "Win32API" library not found' + puts '"Win32API" is required for colour on a windows machine' + puts ' try => "gem install Win32API" on the command line' + puts + end + # puts + # puts 'Windows Environment Detected...' + # puts 'Win32API Library Found.' + # puts +end + +class ColourCommandLine + def initialize + return unless RUBY_PLATFORM =~ /(win|w)32$/ + + get_std_handle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L') + @set_console_txt_attrb = + Win32API.new('kernel32', 'SetConsoleTextAttribute', %w[L N], 'I') + @hout = get_std_handle.call(-11) + end + + def change_to(new_colour) + if RUBY_PLATFORM =~ /(win|w)32$/ + @set_console_txt_attrb.call(@hout, win32_colour(new_colour)) + else + "\033[30;#{posix_colour(new_colour)};22m" + end + end + + def win32_colour(colour) + case colour + when :black then 0 + when :dark_blue then 1 + when :dark_green then 2 + when :dark_cyan then 3 + when :dark_red then 4 + when :dark_purple then 5 + when :dark_yellow, :narrative then 6 + when :default_white, :default, :dark_white then 7 + when :silver then 8 + when :blue then 9 + when :green, :success then 10 + when :cyan, :output then 11 + when :red, :failure then 12 + when :purple then 13 + when :yellow then 14 + when :white then 15 + else + 0 + end + end + + def posix_colour(colour) + # ANSI Escape Codes - Foreground colors + # | Code | Color | + # | 39 | Default foreground color | + # | 30 | Black | + # | 31 | Red | + # | 32 | Green | + # | 33 | Yellow | + # | 34 | Blue | + # | 35 | Magenta | + # | 36 | Cyan | + # | 37 | Light gray | + # | 90 | Dark gray | + # | 91 | Light red | + # | 92 | Light green | + # | 93 | Light yellow | + # | 94 | Light blue | + # | 95 | Light magenta | + # | 96 | Light cyan | + # | 97 | White | + + case colour + when :black then 30 + when :red, :failure then 31 + when :green, :success then 32 + when :yellow then 33 + when :blue, :narrative then 34 + when :purple, :magenta then 35 + when :cyan, :output then 36 + when :white, :default_white then 37 + when :default then 39 + else + 39 + end + end + + def out_c(mode, colour, str) + case RUBY_PLATFORM + when /(win|w)32$/ + change_to(colour) + $stdout.puts str if mode == :puts + $stdout.print str if mode == :print + change_to(:default_white) + else + $stdout.puts("#{change_to(colour)}#{str}\033[0m") if mode == :puts + $stdout.print("#{change_to(colour)}#{str}\033[0m") if mode == :print + end + end +end + +def colour_puts(role, str) + ColourCommandLine.new.out_c(:puts, role, str) +end + +def colour_print(role, str) + ColourCommandLine.new.out_c(:print, role, str) +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/colour_reporter.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/colour_reporter.rb new file mode 100644 index 0000000..1c3bc21 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/colour_reporter.rb @@ -0,0 +1,39 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require_relative 'colour_prompt' + +$colour_output = true + +def report(message) + if !$colour_output + $stdout.puts(message) + else + message = message.join('\n') if message.class == Array + message.each_line do |line| + line.chomp! + colour = case line + when /(?:total\s+)?tests:?\s+(\d+)\s+(?:total\s+)?failures:?\s+\d+\s+Ignored:?/i + Regexp.last_match(1).to_i.zero? ? :green : :red + when /PASS/ + :green + when /^OK$/ + :green + when /(?:FAIL|ERROR)/ + :red + when /IGNORE/ + :yellow + when /^(?:Creating|Compiling|Linking)/ + :white + else + :silver + end + colour_puts(colour, line) + end + end + $stdout.flush + $stderr.flush +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_config.yml b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_config.yml new file mode 100644 index 0000000..4a5e474 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_config.yml @@ -0,0 +1,36 @@ +#this is a sample configuration file for generate_module +#you would use it by calling generate_module with the -ygenerate_config.yml option +#files like this are useful for customizing generate_module to your environment +:generate_module: + :defaults: + #these defaults are used in place of any missing options at the command line + :path_src: ../src/ + :path_inc: ../src/ + :path_tst: ../test/ + :update_svn: true + :includes: + #use [] for no additional includes, otherwise list the includes on separate lines + :src: + - Defs.h + - Board.h + :inc: [] + :tst: + - Defs.h + - Board.h + - Exception.h + :boilerplates: + #these are inserted at the top of generated files. + #just comment out or remove if not desired. + #use %1$s where you would like the file name to appear (path/extension not included) + :src: | + //------------------------------------------- + // %1$s.c + //------------------------------------------- + :inc: | + //------------------------------------------- + // %1$s.h + //------------------------------------------- + :tst: | + //------------------------------------------- + // Test%1$s.c : Units tests for %1$s.c + //------------------------------------------- diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_module.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_module.rb new file mode 100644 index 0000000..eb2cebd --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_module.rb @@ -0,0 +1,309 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +# This script creates all the files with start code necessary for a new module. +# A simple module only requires a source file, header file, and test file. +# Triad modules require a source, header, and test file for each triad type (like model, conductor, and hardware). + +require 'rubygems' +require 'fileutils' +require 'pathname' + +# TEMPLATE_TST +TEMPLATE_TST ||= '#include "unity.h" + +%2$s#include "%1$s.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_%1$s_NeedToImplement(void) +{ + TEST_IGNORE_MESSAGE("Need to Implement %1$s"); +} +'.freeze + +# TEMPLATE_SRC +TEMPLATE_SRC ||= '%2$s#include "%1$s.h" +'.freeze + +# TEMPLATE_INC +TEMPLATE_INC ||= '#ifndef %3$s_H +#define %3$s_H +%2$s + +#endif // %3$s_H +'.freeze + +class UnityModuleGenerator + ############################ + def initialize(options = nil) + @options = UnityModuleGenerator.default_options + case options + when NilClass then @options + when String then @options.merge!(UnityModuleGenerator.grab_config(options)) + when Hash then @options.merge!(options) + else raise 'If you specify arguments, it should be a filename or a hash of options' + end + + # Create default file paths if none were provided + @options[:path_src] = "#{__dir__}/../src/" if @options[:path_src].nil? + @options[:path_inc] = @options[:path_src] if @options[:path_inc].nil? + @options[:path_tst] = "#{__dir__}/../test/" if @options[:path_tst].nil? + @options[:path_src] += '/' unless @options[:path_src][-1] == 47 + @options[:path_inc] += '/' unless @options[:path_inc][-1] == 47 + @options[:path_tst] += '/' unless @options[:path_tst][-1] == 47 + + # Built in patterns + @patterns = { + 'src' => { + '' => { inc: [] } + }, + 'test' => { + '' => { inc: [] } + }, + 'dh' => { + 'Driver' => { inc: [create_filename('%1$s', 'Hardware.h')] }, + 'Hardware' => { inc: [] } + }, + 'dih' => { + 'Driver' => { inc: [create_filename('%1$s', 'Hardware.h'), create_filename('%1$s', 'Interrupt.h')] }, + 'Interrupt' => { inc: [create_filename('%1$s', 'Hardware.h')] }, + 'Hardware' => { inc: [] } + }, + 'mch' => { + 'Model' => { inc: [] }, + 'Conductor' => { inc: [create_filename('%1$s', 'Model.h'), create_filename('%1$s', 'Hardware.h')] }, + 'Hardware' => { inc: [] } + }, + 'mvp' => { + 'Model' => { inc: [] }, + 'Presenter' => { inc: [create_filename('%1$s', 'Model.h'), create_filename('%1$s', 'View.h')] }, + 'View' => { inc: [] } + } + } + end + + ############################ + def self.default_options + { + pattern: 'src', + includes: { + src: [], + inc: [], + tst: [] + }, + update_svn: false, + boilerplates: {}, + test_prefix: 'Test', + mock_prefix: 'Mock' + } + end + + ############################ + def self.grab_config(config_file) + options = default_options + unless config_file.nil? || config_file.empty? + require 'yaml' + yaml_guts = YAML.load_file(config_file) + options.merge!(yaml_guts[:unity] || yaml_guts[:cmock]) + raise "No :unity or :cmock section found in #{config_file}" unless options + end + options + end + + ############################ + def files_to_operate_on(module_name, pattern = nil) + # strip any leading path information from the module name and save for later + subfolder = File.dirname(module_name) + module_name = File.basename(module_name) + + # create triad definition + prefix = @options[:test_prefix] || 'Test' + triad = [{ ext: '.c', path: @options[:path_src], prefix: '', template: TEMPLATE_SRC, inc: :src, boilerplate: @options[:boilerplates][:src] }, + { ext: '.h', path: @options[:path_inc], prefix: '', template: TEMPLATE_INC, inc: :inc, boilerplate: @options[:boilerplates][:inc] }, + { ext: '.c', path: @options[:path_tst], prefix: prefix, template: TEMPLATE_TST, inc: :tst, boilerplate: @options[:boilerplates][:tst] }] + + # prepare the pattern for use + pattern = (pattern || @options[:pattern] || 'src').downcase + patterns = @patterns[pattern] + raise "ERROR: The design pattern '#{pattern}' specified isn't one that I recognize!" if patterns.nil? + + # single file patterns (currently just 'test') can reject the other parts of the triad + triad.select! { |v| v[:inc] == :tst } if pattern == 'test' + + # Assemble the path/names of the files we need to work with. + files = [] + triad.each do |cfg| + patterns.each_pair do |pattern_file, pattern_traits| + submodule_name = create_filename(module_name, pattern_file) + filename = cfg[:prefix] + submodule_name + cfg[:ext] + files << { + path: (Pathname.new("#{cfg[:path]}#{subfolder}") + filename).cleanpath, + name: submodule_name, + template: cfg[:template], + boilerplate: cfg[:boilerplate], + includes: case (cfg[:inc]) + when :src then (@options[:includes][:src] || []) | (pattern_traits[:inc].map { |f| format(f, module_name) }) + when :inc then (@options[:includes][:inc] || []) + when :tst then (@options[:includes][:tst] || []) | (pattern_traits[:inc].map { |f| format("#{@options[:mock_prefix]}#{f}", module_name) }) + end + } + end + end + + files + end + + ############################ + def create_filename(part1, part2 = '') + if part2.empty? + case (@options[:naming]) + when 'bumpy' then part1 + when 'camel' then part1 + when 'snake' then part1.downcase + when 'caps' then part1.upcase + else part1 + end + else + case (@options[:naming]) + when 'bumpy' then part1 + part2 + when 'camel' then part1 + part2 + when 'snake' then part1.downcase + '_' + part2.downcase + when 'caps' then part1.upcase + '_' + part2.upcase + else part1 + '_' + part2 + end + end + end + + ############################ + def generate(module_name, pattern = nil) + files = files_to_operate_on(module_name, pattern) + + # Abort if all of the module files already exist + all_files_exist = true + files.each do |file| + all_files_exist = false unless File.exist?(file[:path]) + end + raise "ERROR: File #{files[0][:name]} already exists. Exiting." if all_files_exist + + # Create Source Modules + files.each_with_index do |file, _i| + # If this file already exists, don't overwrite it. + if File.exist?(file[:path]) + puts "File #{file[:path]} already exists!" + next + end + # Create the path first if necessary. + FileUtils.mkdir_p(File.dirname(file[:path]), verbose: false) + File.open(file[:path], 'w') do |f| + f.write("#{file[:boilerplate]}\n" % [file[:name]]) unless file[:boilerplate].nil? + f.write(file[:template] % [file[:name], + file[:includes].map { |ff| "#include \"#{ff}\"\n" }.join, + file[:name].upcase]) + end + if @options[:update_svn] + `svn add \"#{file[:path]}\"` + if $!.exitstatus.zero? + puts "File #{file[:path]} created and added to source control" + else + puts "File #{file[:path]} created but FAILED adding to source control!" + end + else + puts "File #{file[:path]} created" + end + end + puts 'Generate Complete' + end + + ############################ + def destroy(module_name, pattern = nil) + files_to_operate_on(module_name, pattern).each do |filespec| + file = filespec[:path] + if File.exist?(file) + if @options[:update_svn] + `svn delete \"#{file}\" --force` + puts "File #{file} deleted and removed from source control" + else + FileUtils.remove(file) + puts "File #{file} deleted" + end + else + puts "File #{file} does not exist so cannot be removed." + end + end + puts 'Destroy Complete' + end +end + +############################ +# Handle As Command Line If Called That Way +if $0 == __FILE__ + destroy = false + options = {} + module_name = nil + + # Parse the command line parameters. + ARGV.each do |arg| + case arg + when /^-d/ then destroy = true + when /^-u/ then options[:update_svn] = true + when /^-p\"?(\w+)\"?/ then options[:pattern] = Regexp.last_match(1) + when /^-s\"?(.+)\"?/ then options[:path_src] = Regexp.last_match(1) + when /^-i\"?(.+)\"?/ then options[:path_inc] = Regexp.last_match(1) + when /^-t\"?(.+)\"?/ then options[:path_tst] = Regexp.last_match(1) + when /^-n\"?(.+)\"?/ then options[:naming] = Regexp.last_match(1) + when /^-y\"?(.+)\"?/ then options = UnityModuleGenerator.grab_config(Regexp.last_match(1)) + when /^(\w+)/ + raise "ERROR: You can't have more than one Module name specified!" unless module_name.nil? + + module_name = arg + when /^-(h|-help)/ + ARGV = [].freeze + else + raise "ERROR: Unknown option specified '#{arg}'" + end + end + + unless ARGV[0] + puts ["\nGENERATE MODULE\n-------- ------", + "\nUsage: ruby generate_module [options] module_name", + " -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)", + " -s\"../src\" sets the path to output source to '../src' (DEFAULT ../src)", + " -t\"C:/test\" sets the path to output source to 'C:/test' (DEFAULT ../test)", + ' -p"MCH" sets the output pattern to MCH.', + ' dh - driver hardware.', + ' dih - driver interrupt hardware.', + ' mch - model conductor hardware.', + ' mvp - model view presenter.', + ' src - just a source module, header and test. (DEFAULT)', + ' test - just a test file.', + ' -d destroy module instead of creating it.', + ' -n"camel" sets the file naming convention.', + ' bumpy - BumpyCaseFilenames.', + ' camel - camelCaseFilenames.', + ' snake - snake_case_filenames.', + ' caps - CAPS_CASE_FILENAMES.', + ' -u update subversion too (requires subversion command line)', + ' -y"my.yml" selects a different yaml config file for module generation', + ''].join("\n") + exit + end + + raise 'ERROR: You must have a Module name specified! (use option -h for help)' if module_name.nil? + + if destroy + UnityModuleGenerator.new(options).destroy(module_name) + else + UnityModuleGenerator.new(options).generate(module_name) + end + +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb new file mode 100644 index 0000000..5053210 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb @@ -0,0 +1,495 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +class UnityTestRunnerGenerator + def initialize(options = nil) + @options = UnityTestRunnerGenerator.default_options + case options + when NilClass + @options + when String + @options.merge!(UnityTestRunnerGenerator.grab_config(options)) + when Hash + # Check if some of these have been specified + @options[:has_setup] = !options[:setup_name].nil? + @options[:has_teardown] = !options[:teardown_name].nil? + @options[:has_suite_setup] = !options[:suite_setup].nil? + @options[:has_suite_teardown] = !options[:suite_teardown].nil? + @options.merge!(options) + else + raise 'If you specify arguments, it should be a filename or a hash of options' + end + require_relative 'type_sanitizer' + end + + def self.default_options + { + includes: [], + defines: [], + plugins: [], + framework: :unity, + test_prefix: 'test|spec|should', + mock_prefix: 'Mock', + mock_suffix: '', + setup_name: 'setUp', + teardown_name: 'tearDown', + test_reset_name: 'resetTest', + test_verify_name: 'verifyTest', + main_name: 'main', # set to :auto to automatically generate each time + main_export_decl: '', + cmdline_args: false, + omit_begin_end: false, + use_param_tests: false + } + end + + def self.grab_config(config_file) + options = default_options + unless config_file.nil? || config_file.empty? + require 'yaml' + yaml_guts = YAML.load_file(config_file) + options.merge!(yaml_guts[:unity] || yaml_guts[:cmock]) + raise "No :unity or :cmock section found in #{config_file}" unless options + end + options + end + + def run(input_file, output_file, options = nil) + @options.merge!(options) unless options.nil? + + # pull required data from source file + source = File.read(input_file) + source = source.force_encoding('ISO-8859-1').encode('utf-8', replace: nil) + tests = find_tests(source) + headers = find_includes(source) + testfile_includes = (headers[:local] + headers[:system]) + used_mocks = find_mocks(testfile_includes) + testfile_includes = (testfile_includes - used_mocks) + testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ } + find_setup_and_teardown(source) + + # build runner file + generate(input_file, output_file, tests, used_mocks, testfile_includes) + + # determine which files were used to return them + all_files_used = [input_file, output_file] + all_files_used += testfile_includes.map { |filename| filename + '.c' } unless testfile_includes.empty? + all_files_used += @options[:includes] unless @options[:includes].empty? + all_files_used += headers[:linkonly] unless headers[:linkonly].empty? + all_files_used.uniq + end + + def generate(input_file, output_file, tests, used_mocks, testfile_includes) + File.open(output_file, 'w') do |output| + create_header(output, used_mocks, testfile_includes) + create_externs(output, tests, used_mocks) + create_mock_management(output, used_mocks) + create_setup(output) + create_teardown(output) + create_suite_setup(output) + create_suite_teardown(output) + create_reset(output) + create_run_test(output) + create_args_wrappers(output, tests) + create_main(output, input_file, tests, used_mocks) + end + + return unless @options[:header_file] && !@options[:header_file].empty? + + File.open(@options[:header_file], 'w') do |output| + create_h_file(output, @options[:header_file], tests, testfile_includes, used_mocks) + end + end + + def find_tests(source) + tests_and_line_numbers = [] + + # contains characters which will be substituted from within strings, doing + # this prevents these characters from interferring with scrubbers + # @ is not a valid C character, so there should be no clashes with files genuinely containing these markers + substring_subs = { '{' => '@co@', '}' => '@cc@', ';' => '@ss@', '/' => '@fs@' } + substring_re = Regexp.union(substring_subs.keys) + substring_unsubs = substring_subs.invert # the inverse map will be used to fix the strings afterwords + substring_unsubs['@quote@'] = '\\"' + substring_unsubs['@apos@'] = '\\\'' + substring_unre = Regexp.union(substring_unsubs.keys) + source_scrubbed = source.clone + source_scrubbed = source_scrubbed.gsub(/\\"/, '@quote@') # hide escaped quotes to allow capture of the full string/char + source_scrubbed = source_scrubbed.gsub(/\\'/, '@apos@') # hide escaped apostrophes to allow capture of the full string/char + source_scrubbed = source_scrubbed.gsub(/("[^"\n]*")|('[^'\n]*')/) { |s| s.gsub(substring_re, substring_subs) } # temporarily hide problematic characters within strings + source_scrubbed = source_scrubbed.gsub(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks + source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments + source_scrubbed = source_scrubbed.gsub(/\/\/.*$/, '') # remove line comments (all that remain) + lines = source_scrubbed.split(/(^\s*\#.*$) | (;|\{|\}) /x) # Treat preprocessor directives as a logical line. Match ;, {, and } as end of lines + .map { |line| line.gsub(substring_unre, substring_unsubs) } # unhide the problematic characters previously removed + + lines.each_with_index do |line, _index| + # find tests + next unless line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/m + + arguments = Regexp.last_match(1) + name = Regexp.last_match(2) + call = Regexp.last_match(3) + params = Regexp.last_match(4) + args = nil + + if @options[:use_param_tests] && !arguments.empty? + args = [] + arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) { |a| args << a[0] } + end + + tests_and_line_numbers << { test: name, args: args, call: call, params: params, line_number: 0 } + end + + tests_and_line_numbers.uniq! { |v| v[:test] } + + # determine line numbers and create tests to run + source_lines = source.split("\n") + source_index = 0 + tests_and_line_numbers.size.times do |i| + source_lines[source_index..-1].each_with_index do |line, index| + next unless line =~ /\s+#{tests_and_line_numbers[i][:test]}(?:\s|\()/ + + source_index += index + tests_and_line_numbers[i][:line_number] = source_index + 1 + break + end + end + + tests_and_line_numbers + end + + def find_includes(source) + # remove comments (block and line, in three steps to ensure correct precedence) + source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks + source.gsub!(/\/\*.*?\*\//m, '') # remove block comments + source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain) + + # parse out includes + includes = { + local: source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten, + system: source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" }, + linkonly: source.scan(/^TEST_FILE\(\s*\"\s*(.+)\.[cC]\w*\s*\"/).flatten + } + includes + end + + def find_mocks(includes) + mock_headers = [] + includes.each do |include_path| + include_file = File.basename(include_path) + mock_headers << include_path if include_file =~ /^#{@options[:mock_prefix]}.*#{@options[:mock_suffix]}$/i + end + mock_headers + end + + def find_setup_and_teardown(source) + @options[:has_setup] = source =~ /void\s+#{@options[:setup_name]}\s*\(/ + @options[:has_teardown] = source =~ /void\s+#{@options[:teardown_name]}\s*\(/ + @options[:has_suite_setup] ||= (source =~ /void\s+suiteSetUp\s*\(/) + @options[:has_suite_teardown] ||= (source =~ /void\s+suiteTearDown\s*\(/) + end + + def create_header(output, mocks, testfile_includes = []) + output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */') + output.puts("\n/*=======Automagically Detected Files To Include=====*/") + output.puts("#include \"#{@options[:framework]}.h\"") + output.puts('#include "cmock.h"') unless mocks.empty? + if @options[:defines] && !@options[:defines].empty? + @options[:defines].each { |d| output.puts("#ifndef #{d}\n#define #{d}\n#endif /* #{d} */") } + end + if @options[:header_file] && !@options[:header_file].empty? + output.puts("#include \"#{File.basename(@options[:header_file])}\"") + else + @options[:includes].flatten.uniq.compact.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}") + end + testfile_includes.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}") + end + end + mocks.each do |mock| + output.puts("#include \"#{mock.gsub('.h', '')}.h\"") + end + output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception) + + return unless @options[:enforce_strict_ordering] + + output.puts('') + output.puts('int GlobalExpectCount;') + output.puts('int GlobalVerifyOrder;') + output.puts('char* GlobalOrderError;') + end + + def create_externs(output, tests, _mocks) + output.puts("\n/*=======External Functions This Runner Calls=====*/") + output.puts("extern void #{@options[:setup_name]}(void);") + output.puts("extern void #{@options[:teardown_name]}(void);") + output.puts("\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif") if @options[:externc] + tests.each do |test| + output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});") + end + output.puts("#ifdef __cplusplus\n}\n#endif") if @options[:externc] + output.puts('') + end + + def create_mock_management(output, mock_headers) + output.puts("\n/*=======Mock Management=====*/") + output.puts('static void CMock_Init(void)') + output.puts('{') + + if @options[:enforce_strict_ordering] + output.puts(' GlobalExpectCount = 0;') + output.puts(' GlobalVerifyOrder = 0;') + output.puts(' GlobalOrderError = NULL;') + end + + mocks = mock_headers.map { |mock| File.basename(mock) } + mocks.each do |mock| + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Init();") + end + output.puts("}\n") + + output.puts('static void CMock_Verify(void)') + output.puts('{') + mocks.each do |mock| + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Verify();") + end + output.puts("}\n") + + output.puts('static void CMock_Destroy(void)') + output.puts('{') + mocks.each do |mock| + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Destroy();") + end + output.puts("}\n") + end + + def create_setup(output) + return if @options[:has_setup] + + output.puts("\n/*=======Setup (stub)=====*/") + output.puts("void #{@options[:setup_name]}(void) {}") + end + + def create_teardown(output) + return if @options[:has_teardown] + + output.puts("\n/*=======Teardown (stub)=====*/") + output.puts("void #{@options[:teardown_name]}(void) {}") + end + + def create_suite_setup(output) + return if @options[:suite_setup].nil? + + output.puts("\n/*=======Suite Setup=====*/") + output.puts('void suiteSetUp(void)') + output.puts('{') + output.puts(@options[:suite_setup]) + output.puts('}') + end + + def create_suite_teardown(output) + return if @options[:suite_teardown].nil? + + output.puts("\n/*=======Suite Teardown=====*/") + output.puts('int suiteTearDown(int num_failures)') + output.puts('{') + output.puts(@options[:suite_teardown]) + output.puts('}') + end + + def create_reset(output) + output.puts("\n/*=======Test Reset Options=====*/") + output.puts("void #{@options[:test_reset_name]}(void);") + output.puts("void #{@options[:test_reset_name]}(void)") + output.puts('{') + output.puts(" #{@options[:teardown_name]}();") + output.puts(' CMock_Verify();') + output.puts(' CMock_Destroy();') + output.puts(' CMock_Init();') + output.puts(" #{@options[:setup_name]}();") + output.puts('}') + output.puts("void #{@options[:test_verify_name]}(void);") + output.puts("void #{@options[:test_verify_name]}(void)") + output.puts('{') + output.puts(' CMock_Verify();') + output.puts('}') + end + + def create_run_test(output) + require 'erb' + template = ERB.new(File.read(File.join(__dir__, 'run_test.erb'))) + output.puts(template.result(binding)) + end + + def create_args_wrappers(output, tests) + return unless @options[:use_param_tests] + + output.puts("\n/*=======Parameterized Test Wrappers=====*/") + tests.each do |test| + next if test[:args].nil? || test[:args].empty? + + test[:args].each.with_index(1) do |args, idx| + output.puts("static void runner_args#{idx}_#{test[:test]}(void)") + output.puts('{') + output.puts(" #{test[:test]}(#{args});") + output.puts("}\n") + end + end + end + + def create_main(output, filename, tests, used_mocks) + output.puts("\n\n/*=======MAIN=====*/") + main_name = @options[:main_name].to_sym == :auto ? "main_#{filename.gsub('.c', '')}" : (@options[:main_name]).to_s + if @options[:cmdline_args] + if main_name != 'main' + output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv);") + end + output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv)") + output.puts('{') + output.puts(' int parse_status = UnityParseOptions(argc, argv);') + output.puts(' if (parse_status != 0)') + output.puts(' {') + output.puts(' if (parse_status < 0)') + output.puts(' {') + output.puts(" UnityPrint(\"#{filename.gsub('.c', '')}.\");") + output.puts(' UNITY_PRINT_EOL();') + tests.each do |test| + if (!@options[:use_param_tests]) || test[:args].nil? || test[:args].empty? + output.puts(" UnityPrint(\" #{test[:test]}\");") + output.puts(' UNITY_PRINT_EOL();') + else + test[:args].each do |args| + output.puts(" UnityPrint(\" #{test[:test]}(#{args})\");") + output.puts(' UNITY_PRINT_EOL();') + end + end + end + output.puts(' return 0;') + output.puts(' }') + output.puts(' return parse_status;') + output.puts(' }') + else + main_return = @options[:omit_begin_end] ? 'void' : 'int' + if main_name != 'main' + output.puts("#{@options[:main_export_decl]} #{main_return} #{main_name}(void);") + end + output.puts("#{main_return} #{main_name}(void)") + output.puts('{') + end + output.puts(' suiteSetUp();') if @options[:has_suite_setup] + if @options[:omit_begin_end] + output.puts(" UnitySetTestFile(\"#{filename.gsub(/\\/, '\\\\\\')}\");") + else + output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");") + end + tests.each do |test| + if (!@options[:use_param_tests]) || test[:args].nil? || test[:args].empty? + output.puts(" run_test(#{test[:test]}, \"#{test[:test]}\", #{test[:line_number]});") + else + test[:args].each.with_index(1) do |args, idx| + wrapper = "runner_args#{idx}_#{test[:test]}" + testname = "#{test[:test]}(#{args})".dump + output.puts(" run_test(#{wrapper}, #{testname}, #{test[:line_number]});") + end + end + end + output.puts + output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty? + if @options[:has_suite_teardown] + if @options[:omit_begin_end] + output.puts(' (void) suite_teardown(0);') + else + output.puts(' return suiteTearDown(UnityEnd());') + end + else + output.puts(' return UnityEnd();') if not @options[:omit_begin_end] + end + output.puts('}') + end + + def create_h_file(output, filename, tests, testfile_includes, used_mocks) + filename = File.basename(filename).gsub(/[-\/\\\.\,\s]/, '_').upcase + output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */') + output.puts("#ifndef _#{filename}") + output.puts("#define _#{filename}\n\n") + output.puts("#include \"#{@options[:framework]}.h\"") + output.puts('#include "cmock.h"') unless used_mocks.empty? + @options[:includes].flatten.uniq.compact.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}") + end + testfile_includes.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}") + end + output.puts "\n" + tests.each do |test| + if test[:params].nil? || test[:params].empty? + output.puts("void #{test[:test]}(void);") + else + output.puts("void #{test[:test]}(#{test[:params]});") + end + end + output.puts("#endif\n\n") + end +end + +if $0 == __FILE__ + options = { includes: [] } + + # parse out all the options first (these will all be removed as we go) + ARGV.reject! do |arg| + case arg + when '-cexception' + options[:plugins] = [:cexception] + true + when /\.*\.ya?ml/ + options = UnityTestRunnerGenerator.grab_config(arg) + true + when /--(\w+)=\"?(.*)\"?/ + options[Regexp.last_match(1).to_sym] = Regexp.last_match(2) + true + when /\.*\.h/ + options[:includes] << arg + true + else false + end + end + + # make sure there is at least one parameter left (the input file) + unless ARGV[0] + puts ["\nusage: ruby #{__FILE__} (files) (options) input_test_file (output)", + "\n input_test_file - this is the C file you want to create a runner for", + ' output - this is the name of the runner file to generate', + ' defaults to (input_test_file)_Runner', + ' files:', + ' *.yml / *.yaml - loads configuration from here in :unity or :cmock', + ' *.h - header files are added as #includes in runner', + ' options:', + ' -cexception - include cexception support', + ' -externc - add extern "C" for cpp support', + ' --setup_name="" - redefine setUp func name to something else', + ' --teardown_name="" - redefine tearDown func name to something else', + ' --main_name="" - redefine main func name to something else', + ' --test_prefix="" - redefine test prefix from default test|spec|should', + ' --test_reset_name="" - redefine resetTest func name to something else', + ' --test_verify_name="" - redefine verifyTest func name to something else', + ' --suite_setup="" - code to execute for setup of entire suite', + ' --suite_teardown="" - code to execute for teardown of entire suite', + ' --use_param_tests=1 - enable parameterized tests (disabled by default)', + ' --omit_begin_end=1 - omit calls to UnityBegin and UnityEnd (disabled by default)', + ' --header_file="" - path/name of test header file to generate too'].join("\n") + exit 1 + end + + # create the default test runner name if not specified + ARGV[1] = ARGV[0].gsub('.c', '_Runner.c') unless ARGV[1] + + UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1]) +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/parse_output.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/parse_output.rb new file mode 100644 index 0000000..d72c6e8 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/parse_output.rb @@ -0,0 +1,322 @@ +#============================================================ +# Author: John Theofanopoulos +# A simple parser. Takes the output files generated during the +# build process and extracts information relating to the tests. +# +# Notes: +# To capture an output file under VS builds use the following: +# devenv [build instructions] > Output.txt & type Output.txt +# +# To capture an output file under Linux builds use the following: +# make | tee Output.txt +# +# This script can handle the following output formats: +# - normal output (raw unity) +# - fixture output (unity_fixture.h/.c) +# - fixture output with verbose flag set ("-v") +# +# To use this parser use the following command +# ruby parseOutput.rb [options] [file] +# options: -xml : produce a JUnit compatible XML file +# file: file to scan for results +#============================================================ + +# Parser class for handling the input file +class ParseOutput + def initialize + # internal data + @class_name_idx = 0 + @path_delim = nil + + # xml output related + @xml_out = false + @array_list = false + + # current suite name and statistics + @test_suite = nil + @total_tests = 0 + @test_passed = 0 + @test_failed = 0 + @test_ignored = 0 + end + + # Set the flag to indicate if there will be an XML output file or not + def set_xml_output + @xml_out = true + end + + # If write our output to XML + def write_xml_output + output = File.open('report.xml', 'w') + output << "\n" + @array_list.each do |item| + output << item << "\n" + end + end + + # Pushes the suite info as xml to the array list, which will be written later + def push_xml_output_suite_info + # Insert opening tag at front + heading = '' + @array_list.insert(0, heading) + # Push back the closing tag + @array_list.push '' + end + + # Pushes xml output data to the array list, which will be written later + def push_xml_output_passed(test_name) + @array_list.push ' ' + end + + # Pushes xml output data to the array list, which will be written later + def push_xml_output_failed(test_name, reason) + @array_list.push ' ' + @array_list.push ' ' + reason + '' + @array_list.push ' ' + end + + # Pushes xml output data to the array list, which will be written later + def push_xml_output_ignored(test_name, reason) + @array_list.push ' ' + @array_list.push ' ' + reason + '' + @array_list.push ' ' + end + + # This function will try and determine when the suite is changed. This is + # is the name that gets added to the classname parameter. + def test_suite_verify(test_suite_name) + # Split the path name + test_name = test_suite_name.split(@path_delim) + + # Remove the extension and extract the base_name + base_name = test_name[test_name.size - 1].split('.')[0] + + # Return if the test suite hasn't changed + return unless base_name.to_s != @test_suite.to_s + + @test_suite = base_name + printf "New Test: %s\n", @test_suite + end + + # Prepares the line for verbose fixture output ("-v") + def prepare_fixture_line(line) + line = line.sub('IGNORE_TEST(', '') + line = line.sub('TEST(', '') + line = line.sub(')', ',') + line = line.chomp + array = line.split(',') + array.map { |x| x.to_s.lstrip.chomp } + end + + # Test was flagged as having passed so format the output. + # This is using the Unity fixture output and not the original Unity output. + def test_passed_unity_fixture(array) + class_name = array[0] + test_name = array[1] + test_suite_verify(class_name) + printf "%-40s PASS\n", test_name + + push_xml_output_passed(test_name) if @xml_out + end + + # Test was flagged as having failed so format the output. + # This is using the Unity fixture output and not the original Unity output. + def test_failed_unity_fixture(array) + class_name = array[0] + test_name = array[1] + test_suite_verify(class_name) + reason_array = array[2].split(':') + reason = reason_array[-1].lstrip.chomp + ' at line: ' + reason_array[-4] + + printf "%-40s FAILED\n", test_name + + push_xml_output_failed(test_name, reason) if @xml_out + end + + # Test was flagged as being ignored so format the output. + # This is using the Unity fixture output and not the original Unity output. + def test_ignored_unity_fixture(array) + class_name = array[0] + test_name = array[1] + reason = 'No reason given' + if array.size > 2 + reason_array = array[2].split(':') + tmp_reason = reason_array[-1].lstrip.chomp + reason = tmp_reason == 'IGNORE' ? 'No reason given' : tmp_reason + end + test_suite_verify(class_name) + printf "%-40s IGNORED\n", test_name + + push_xml_output_ignored(test_name, reason) if @xml_out + end + + # Test was flagged as having passed so format the output + def test_passed(array) + last_item = array.length - 1 + test_name = array[last_item - 1] + test_suite_verify(array[@class_name_idx]) + printf "%-40s PASS\n", test_name + + return unless @xml_out + + push_xml_output_passed(test_name) if @xml_out + end + + # Test was flagged as having failed so format the line + def test_failed(array) + last_item = array.length - 1 + test_name = array[last_item - 2] + reason = array[last_item].chomp.lstrip + ' at line: ' + array[last_item - 3] + class_name = array[@class_name_idx] + + if test_name.start_with? 'TEST(' + array2 = test_name.split(' ') + + test_suite = array2[0].sub('TEST(', '') + test_suite = test_suite.sub(',', '') + class_name = test_suite + + test_name = array2[1].sub(')', '') + end + + test_suite_verify(class_name) + printf "%-40s FAILED\n", test_name + + push_xml_output_failed(test_name, reason) if @xml_out + end + + # Test was flagged as being ignored so format the output + def test_ignored(array) + last_item = array.length - 1 + test_name = array[last_item - 2] + reason = array[last_item].chomp.lstrip + class_name = array[@class_name_idx] + + if test_name.start_with? 'TEST(' + array2 = test_name.split(' ') + + test_suite = array2[0].sub('TEST(', '') + test_suite = test_suite.sub(',', '') + class_name = test_suite + + test_name = array2[1].sub(')', '') + end + + test_suite_verify(class_name) + printf "%-40s IGNORED\n", test_name + + push_xml_output_ignored(test_name, reason) if @xml_out + end + + # Adjusts the os specific members according to the current path style + # (Windows or Unix based) + def detect_os_specifics(line) + if line.include? '\\' + # Windows X:\Y\Z + @class_name_idx = 1 + @path_delim = '\\' + else + # Unix Based /X/Y/Z + @class_name_idx = 0 + @path_delim = '/' + end + end + + # Main function used to parse the file that was captured. + def process(file_name) + @array_list = [] + + puts 'Parsing file: ' + file_name + + @test_passed = 0 + @test_failed = 0 + @test_ignored = 0 + puts '' + puts '=================== RESULTS =====================' + puts '' + File.open(file_name).each do |line| + # Typical test lines look like these: + # ---------------------------------------------------- + # 1. normal output: + # /.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0 + # /.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented + # /.c:115:test_tc5100_initCanVoidPtrs:PASS + # + # 2. fixture output + # /.c:63:TEST(, ):FAIL: Expected 0x00001234 Was 0x00005A5A + # /.c:36:TEST(, ):IGNORE + # Note: "PASS" information won't be generated in this mode + # + # 3. fixture output with verbose information ("-v") + # TEST()/:168::FAIL: Expected 0x8D Was 0x8C + # TEST(, )/:22::IGNORE: This Test Was Ignored On Purpose + # IGNORE_TEST() + # TEST() PASS + # + # Note: Where path is different on Unix vs Windows devices (Windows leads with a drive letter)! + detect_os_specifics(line) + line_array = line.split(':') + + # If we were able to split the line then we can look to see if any of our target words + # were found. Case is important. + next unless (line_array.size >= 4) || (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(') + + # check if the output is fixture output (with verbose flag "-v") + if (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(') + line_array = prepare_fixture_line(line) + if line.include? ' PASS' + test_passed_unity_fixture(line_array) + @test_passed += 1 + elsif line.include? 'FAIL' + test_failed_unity_fixture(line_array) + @test_failed += 1 + elsif line.include? 'IGNORE' + test_ignored_unity_fixture(line_array) + @test_ignored += 1 + end + # normal output / fixture output (without verbose "-v") + elsif line.include? ':PASS' + test_passed(line_array) + @test_passed += 1 + elsif line.include? ':FAIL' + test_failed(line_array) + @test_failed += 1 + elsif line.include? ':IGNORE:' + test_ignored(line_array) + @test_ignored += 1 + elsif line.include? ':IGNORE' + line_array.push('No reason given') + test_ignored(line_array) + @test_ignored += 1 + end + @total_tests = @test_passed + @test_failed + @test_ignored + end + puts '' + puts '=================== SUMMARY =====================' + puts '' + puts 'Tests Passed : ' + @test_passed.to_s + puts 'Tests Failed : ' + @test_failed.to_s + puts 'Tests Ignored : ' + @test_ignored.to_s + + return unless @xml_out + + # push information about the suite + push_xml_output_suite_info + # write xml output file + write_xml_output + end +end + +# If the command line has no values in, used a default value of Output.txt +parse_my_file = ParseOutput.new + +if ARGV.size >= 1 + ARGV.each do |arg| + if arg == '-xml' + parse_my_file.set_xml_output + else + parse_my_file.process(arg) + break + end + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/run_test.erb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/run_test.erb new file mode 100644 index 0000000..3d3b6d1 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/run_test.erb @@ -0,0 +1,36 @@ +/*=======Test Runner Used To Run Each Test=====*/ +static void run_test(UnityTestFunction func, const char* name, int line_num) +{ + Unity.CurrentTestName = name; + Unity.CurrentTestLineNumber = line_num; +#ifdef UNITY_USE_COMMAND_LINE_ARGS + if (!UnityTestMatches()) + return; +#endif + Unity.NumberOfTests++; + UNITY_CLR_DETAILS(); + UNITY_EXEC_TIME_START(); + CMock_Init(); + if (TEST_PROTECT()) + { +<% if @options[:plugins].include?(:cexception) %> + CEXCEPTION_T e; + Try { +<% end %> + <%= @options[:setup_name] %>(); + func(); +<% if @options[:plugins].include?(:cexception) %> + } Catch(e) { + TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!"); + } +<% end %> + } + if (TEST_PROTECT()) + { + <%= @options[:teardown_name] %>(); + CMock_Verify(); + } + CMock_Destroy(); + UNITY_EXEC_TIME_STOP(); + UnityConcludeTest(); +} diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/stylize_as_junit.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/stylize_as_junit.rb new file mode 100644 index 0000000..e01f791 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/stylize_as_junit.rb @@ -0,0 +1,251 @@ +#!/usr/bin/ruby +# +# unity_to_junit.rb +# +require 'fileutils' +require 'optparse' +require 'ostruct' +require 'set' + +require 'pp' + +VERSION = 1.0 + +class ArgvParser + # + # Return a structure describing the options. + # + def self.parse(args) + # The options specified on the command line will be collected in *options*. + # We set default values here. + options = OpenStruct.new + options.results_dir = '.' + options.root_path = '.' + options.out_file = 'results.xml' + + opts = OptionParser.new do |o| + o.banner = 'Usage: unity_to_junit.rb [options]' + + o.separator '' + o.separator 'Specific options:' + + o.on('-r', '--results ', 'Look for Unity Results files here.') do |results| + # puts "results #{results}" + options.results_dir = results + end + + o.on('-p', '--root_path ', 'Prepend this path to files in results.') do |root_path| + options.root_path = root_path + end + + o.on('-o', '--output ', 'XML file to generate.') do |out_file| + # puts "out_file: #{out_file}" + options.out_file = out_file + end + + o.separator '' + o.separator 'Common options:' + + # No argument, shows at tail. This will print an options summary. + o.on_tail('-h', '--help', 'Show this message') do + puts o + exit + end + + # Another typical switch to print the version. + o.on_tail('--version', 'Show version') do + puts "unity_to_junit.rb version #{VERSION}" + exit + end + end + + opts.parse!(args) + options + end +end + +class UnityToJUnit + include FileUtils::Verbose + attr_reader :report, :total_tests, :failures, :ignored + attr_writer :targets, :root, :out_file + + def initialize + @report = '' + @unit_name = '' + end + + def run + # Clean up result file names + results = @targets.map { |target| target.tr('\\', '/') } + # puts "Output File: #{@out_file}" + f = File.new(@out_file, 'w') + write_xml_header(f) + write_suites_header(f) + results.each do |result_file| + lines = File.readlines(result_file).map(&:chomp) + + raise "Empty test result file: #{result_file}" if lines.empty? + + result_output = get_details(result_file, lines) + tests, failures, ignored = parse_test_summary(lines) + result_output[:counts][:total] = tests + result_output[:counts][:failed] = failures + result_output[:counts][:ignored] = ignored + result_output[:counts][:passed] = (result_output[:counts][:total] - result_output[:counts][:failed] - result_output[:counts][:ignored]) + + # use line[0] from the test output to get the test_file path and name + test_file_str = lines[0].tr('\\', '/') + test_file_str = test_file_str.split(':') + test_file = if test_file_str.length < 2 + result_file + else + test_file_str[0] + ':' + test_file_str[1] + end + result_output[:source][:path] = File.dirname(test_file) + result_output[:source][:file] = File.basename(test_file) + + # save result_output + @unit_name = File.basename(test_file, '.*') + + write_suite_header(result_output[:counts], f) + write_failures(result_output, f) + write_tests(result_output, f) + write_ignored(result_output, f) + write_suite_footer(f) + end + write_suites_footer(f) + f.close + end + + def usage(err_msg = nil) + puts "\nERROR: " + puts err_msg if err_msg + puts 'Usage: unity_to_junit.rb [options]' + puts '' + puts 'Specific options:' + puts ' -r, --results Look for Unity Results files here.' + puts ' -p, --root_path Prepend this path to files in results.' + puts ' -o, --output XML file to generate.' + puts '' + puts 'Common options:' + puts ' -h, --help Show this message' + puts ' --version Show version' + + exit 1 + end + + protected + + def get_details(_result_file, lines) + results = results_structure + lines.each do |line| + line = line.tr('\\', '/') + _src_file, src_line, test_name, status, msg = line.split(/:/) + case status + when 'IGNORE' then results[:ignores] << { test: test_name, line: src_line, message: msg } + when 'FAIL' then results[:failures] << { test: test_name, line: src_line, message: msg } + when 'PASS' then results[:successes] << { test: test_name, line: src_line, message: msg } + end + end + results + end + + def parse_test_summary(summary) + raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } + + [Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i] + end + + private + + def results_structure + { + source: { path: '', file: '' }, + successes: [], + failures: [], + ignores: [], + counts: { total: 0, passed: 0, failed: 0, ignored: 0 }, + stdout: [] + } + end + + def write_xml_header(stream) + stream.puts "" + end + + def write_suites_header(stream) + stream.puts '' + end + + def write_suite_header(counts, stream) + stream.puts "\t" + end + + def write_failures(results, stream) + result = results[:failures] + result.each do |item| + filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*')) + stream.puts "\t\t" + stream.puts "\t\t\t" + stream.puts "\t\t\t [File] #{filename} [Line] #{item[:line]} " + stream.puts "\t\t" + end + end + + def write_tests(results, stream) + result = results[:successes] + result.each do |item| + stream.puts "\t\t" + end + end + + def write_ignored(results, stream) + result = results[:ignores] + result.each do |item| + filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*')) + puts "Writing ignored tests for test harness: #{filename}" + stream.puts "\t\t" + stream.puts "\t\t\t" + stream.puts "\t\t\t [File] #{filename} [Line] #{item[:line]} " + stream.puts "\t\t" + end + end + + def write_suite_footer(stream) + stream.puts "\t" + end + + def write_suites_footer(stream) + stream.puts '' + end +end + +if $0 == __FILE__ + # parse out the command options + options = ArgvParser.parse(ARGV) + + # create an instance to work with + utj = UnityToJUnit.new + begin + # look in the specified or current directory for result files + targets = "#{options.results_dir.tr('\\', '/')}**/*.test*" + + results = Dir[targets] + + raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty? + + utj.targets = results + + # set the root path + utj.root = options.root_path + + # set the output XML file name + # puts "Output File from options: #{options.out_file}" + utj.out_file = options.out_file + + # run the summarizer + puts utj.run + rescue StandardError => e + utj.usage e.message + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/test_file_filter.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/test_file_filter.rb new file mode 100644 index 0000000..5c3a79f --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/test_file_filter.rb @@ -0,0 +1,25 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require'yaml' + +module RakefileHelpers + class TestFileFilter + def initialize(all_files = false) + @all_files = all_files + + return unless @all_files + return unless File.exist?('test_file_filter.yml') + + filters = YAML.load_file('test_file_filter.yml') + @all_files = filters[:all_files] + @only_files = filters[:only_files] + @exclude_files = filters[:exclude_files] + end + + attr_accessor :all_files, :only_files, :exclude_files + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/type_sanitizer.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/type_sanitizer.rb new file mode 100644 index 0000000..dafb882 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/type_sanitizer.rb @@ -0,0 +1,6 @@ +module TypeSanitizer + def self.sanitize_c_identifier(unsanitized) + # convert filename to valid C identifier by replacing invalid chars with '_' + unsanitized.gsub(/[-\/\\\.\,\s]/, '_') + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py new file mode 100644 index 0000000..00c0da8 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py @@ -0,0 +1,139 @@ +#! python3 +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de +# [Released under MIT License. Please refer to license.txt for details] +# Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams +# ========================================== +import sys +import os +import re +from glob import glob + +class UnityTestSummary: + def __init__(self): + self.report = '' + self.total_tests = 0 + self.failures = 0 + self.ignored = 0 + + def run(self): + # Clean up result file names + results = [] + for target in self.targets: + results.append(target.replace('\\', '/')) + + # Dig through each result file, looking for details on pass/fail: + failure_output = [] + ignore_output = [] + + for result_file in results: + lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) + if len(lines) == 0: + raise Exception("Empty test result file: %s" % result_file) + + details = self.get_details(result_file, lines) + failures = details['failures'] + ignores = details['ignores'] + if len(failures) > 0: failure_output.append('\n'.join(failures)) + if len(ignores) > 0: ignore_output.append('n'.join(ignores)) + tests,failures,ignored = self.parse_test_summary('\n'.join(lines)) + self.total_tests += tests + self.failures += failures + self.ignored += ignored + + if self.ignored > 0: + self.report += "\n" + self.report += "--------------------------\n" + self.report += "UNITY IGNORED TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += "\n".join(ignore_output) + + if self.failures > 0: + self.report += "\n" + self.report += "--------------------------\n" + self.report += "UNITY FAILED TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += '\n'.join(failure_output) + + self.report += "\n" + self.report += "--------------------------\n" + self.report += "OVERALL UNITY TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored) + self.report += "\n" + + return self.report + + def set_targets(self, target_array): + self.targets = target_array + + def set_root_path(self, path): + self.root = path + + def usage(self, err_msg=None): + print("\nERROR: ") + if err_msg: + print(err_msg) + print("\nUsage: unity_test_summary.py result_file_directory/ root_path/") + print(" result_file_directory - The location of your results files.") + print(" Defaults to current directory if not specified.") + print(" Should end in / if specified.") + print(" root_path - Helpful for producing more verbose output if using relative paths.") + sys.exit(1) + + def get_details(self, result_file, lines): + results = { 'failures': [], 'ignores': [], 'successes': [] } + for line in lines: + parts = line.split(':') + if len(parts) == 5: + src_file,src_line,test_name,status,msg = parts + elif len(parts) == 4: + src_file,src_line,test_name,status = parts + msg = '' + else: + continue + if len(self.root) > 0: + line_out = "%s%s" % (self.root, line) + else: + line_out = line + if status == 'IGNORE': + results['ignores'].append(line_out) + elif status == 'FAIL': + results['failures'].append(line_out) + elif status == 'PASS': + results['successes'].append(line_out) + return results + + def parse_test_summary(self, summary): + m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary) + if not m: + raise Exception("Couldn't parse test results: %s" % summary) + + return int(m.group(1)), int(m.group(2)), int(m.group(3)) + + +if __name__ == '__main__': + uts = UnityTestSummary() + try: + #look in the specified or current directory for result files + if len(sys.argv) > 1: + targets_dir = sys.argv[1] + else: + targets_dir = './' + targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '**/*.test*', recursive=True))) + if len(targets) == 0: + raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) + uts.set_targets(targets) + + #set the root path + if len(sys.argv) > 2: + root_path = sys.argv[2] + else: + root_path = os.path.split(__file__)[0] + uts.set_root_path(root_path) + + #run the summarizer + print(uts.run()) + except Exception as e: + uts.usage(e) diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb new file mode 100644 index 0000000..b3fe8a6 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb @@ -0,0 +1,135 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +# !/usr/bin/ruby +# +# unity_test_summary.rb +# +require 'fileutils' +require 'set' + +class UnityTestSummary + include FileUtils::Verbose + + attr_reader :report, :total_tests, :failures, :ignored + attr_writer :targets, :root + + def initialize(_opts = {}) + @report = '' + @total_tests = 0 + @failures = 0 + @ignored = 0 + end + + def run + # Clean up result file names + results = @targets.map { |target| target.tr('\\', '/') } + + # Dig through each result file, looking for details on pass/fail: + failure_output = [] + ignore_output = [] + + results.each do |result_file| + lines = File.readlines(result_file).map(&:chomp) + + raise "Empty test result file: #{result_file}" if lines.empty? + + output = get_details(result_file, lines) + failure_output << output[:failures] unless output[:failures].empty? + ignore_output << output[:ignores] unless output[:ignores].empty? + tests, failures, ignored = parse_test_summary(lines) + @total_tests += tests + @failures += failures + @ignored += ignored + end + + if @ignored > 0 + @report += "\n" + @report += "--------------------------\n" + @report += "UNITY IGNORED TEST SUMMARY\n" + @report += "--------------------------\n" + @report += ignore_output.flatten.join("\n") + end + + if @failures > 0 + @report += "\n" + @report += "--------------------------\n" + @report += "UNITY FAILED TEST SUMMARY\n" + @report += "--------------------------\n" + @report += failure_output.flatten.join("\n") + end + + @report += "\n" + @report += "--------------------------\n" + @report += "OVERALL UNITY TEST SUMMARY\n" + @report += "--------------------------\n" + @report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n" + @report += "\n" + end + + def usage(err_msg = nil) + puts "\nERROR: " + puts err_msg if err_msg + puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/" + puts ' result_file_directory - The location of your results files.' + puts ' Defaults to current directory if not specified.' + puts ' Should end in / if specified.' + puts ' root_path - Helpful for producing more verbose output if using relative paths.' + exit 1 + end + + protected + + def get_details(_result_file, lines) + results = { failures: [], ignores: [], successes: [] } + lines.each do |line| + _src_file, _src_line, _test_name, status, _msg = line.split(/:/) + line_out = (@root && (@root != 0) ? "#{@root}#{line}" : line).gsub(/\//, '\\') + case status + when 'IGNORE' then results[:ignores] << line_out + when 'FAIL' then results[:failures] << line_out + when 'PASS' then results[:successes] << line_out + end + end + results + end + + def parse_test_summary(summary) + raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } + + [Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i] + end +end + +if $0 == __FILE__ + + # parse out the command options + opts, args = ARGV.partition { |v| v =~ /^--\w+/ } + opts.map! { |v| v[2..-1].to_sym } + + # create an instance to work with + uts = UnityTestSummary.new(opts) + + begin + # look in the specified or current directory for result files + args[0] ||= './' + targets = "#{ARGV[0].tr('\\', '/')}**/*.test*" + results = Dir[targets] + + raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty? + + uts.targets = results + + # set the root path + args[1] ||= Dir.pwd + '/' + uts.root = ARGV[1] + + # run the summarizer + puts uts.run + rescue StandardError => e + uts.usage e.message + end +end diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py new file mode 100644 index 0000000..71dd568 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py @@ -0,0 +1,146 @@ +import sys +import os +from glob import glob + +from pyparsing import * +from junit_xml import TestSuite, TestCase + + +class UnityTestSummary: + def __init__(self): + self.report = '' + self.total_tests = 0 + self.failures = 0 + self.ignored = 0 + self.targets = 0 + self.root = None + self.test_suites = dict() + + def run(self): + # Clean up result file names + results = [] + for target in self.targets: + results.append(target.replace('\\', '/')) + + # Dig through each result file, looking for details on pass/fail: + for result_file in results: + lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) + if len(lines) == 0: + raise Exception("Empty test result file: %s" % result_file) + + # define an expression for your file reference + entry_one = Combine( + oneOf(list(alphas)) + ':/' + + Word(alphanums + '_-./')) + + entry_two = Word(printables + ' ', excludeChars=':') + entry = entry_one | entry_two + + delimiter = Literal(':').suppress() + tc_result_line = Group(entry.setResultsName('tc_file_name') + delimiter + entry.setResultsName( + 'tc_line_nr') + delimiter + entry.setResultsName('tc_name') + delimiter + entry.setResultsName( + 'tc_status') + Optional( + delimiter + entry.setResultsName('tc_msg'))).setResultsName("tc_line") + + eol = LineEnd().suppress() + sol = LineStart().suppress() + blank_line = sol + eol + + tc_summary_line = Group(Word(nums).setResultsName("num_of_tests") + "Tests" + Word(nums).setResultsName( + "num_of_fail") + "Failures" + Word(nums).setResultsName("num_of_ignore") + "Ignored").setResultsName( + "tc_summary") + tc_end_line = Or(Literal("FAIL"), Literal('Ok')).setResultsName("tc_result") + + # run it and see... + pp1 = tc_result_line | Optional(tc_summary_line | tc_end_line) + pp1.ignore(blank_line | OneOrMore("-")) + + result = list() + for l in lines: + result.append((pp1.parseString(l)).asDict()) + # delete empty results + result = filter(None, result) + + tc_list = list() + for r in result: + if 'tc_line' in r: + tmp_tc_line = r['tc_line'] + + # get only the file name which will be used as the classname + file_name = tmp_tc_line['tc_file_name'].split('\\').pop().split('/').pop().rsplit('.', 1)[0] + tmp_tc = TestCase(name=tmp_tc_line['tc_name'], classname=file_name) + if 'tc_status' in tmp_tc_line: + if str(tmp_tc_line['tc_status']) == 'IGNORE': + if 'tc_msg' in tmp_tc_line: + tmp_tc.add_skipped_info(message=tmp_tc_line['tc_msg'], + output=r'[File]={0}, [Line]={1}'.format( + tmp_tc_line['tc_file_name'], tmp_tc_line['tc_line_nr'])) + else: + tmp_tc.add_skipped_info(message=" ") + elif str(tmp_tc_line['tc_status']) == 'FAIL': + if 'tc_msg' in tmp_tc_line: + tmp_tc.add_failure_info(message=tmp_tc_line['tc_msg'], + output=r'[File]={0}, [Line]={1}'.format( + tmp_tc_line['tc_file_name'], tmp_tc_line['tc_line_nr'])) + else: + tmp_tc.add_failure_info(message=" ") + + tc_list.append((str(result_file), tmp_tc)) + + for k, v in tc_list: + try: + self.test_suites[k].append(v) + except KeyError: + self.test_suites[k] = [v] + ts = [] + for suite_name in self.test_suites: + ts.append(TestSuite(suite_name, self.test_suites[suite_name])) + + with open('result.xml', 'w') as f: + TestSuite.to_file(f, ts, prettyprint='True', encoding='utf-8') + + return self.report + + def set_targets(self, target_array): + self.targets = target_array + + def set_root_path(self, path): + self.root = path + + @staticmethod + def usage(err_msg=None): + print("\nERROR: ") + if err_msg: + print(err_msg) + print("\nUsage: unity_test_summary.py result_file_directory/ root_path/") + print(" result_file_directory - The location of your results files.") + print(" Defaults to current directory if not specified.") + print(" Should end in / if specified.") + print(" root_path - Helpful for producing more verbose output if using relative paths.") + sys.exit(1) + + +if __name__ == '__main__': + uts = UnityTestSummary() + try: + # look in the specified or current directory for result files + if len(sys.argv) > 1: + targets_dir = sys.argv[1] + else: + targets_dir = './' + targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) + if len(targets) == 0: + raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) + uts.set_targets(targets) + + # set the root path + if len(sys.argv) > 2: + root_path = sys.argv[2] + else: + root_path = os.path.split(__file__)[0] + uts.set_root_path(root_path) + + # run the summarizer + print(uts.run()) + except Exception as e: + UnityTestSummary.usage(e) diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/release/build.info b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/release/build.info new file mode 100644 index 0000000..56d5912 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/release/build.info @@ -0,0 +1,2 @@ +122 + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/release/version.info b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/release/version.info new file mode 100644 index 0000000..cf12b30 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/release/version.info @@ -0,0 +1,2 @@ +2.4.3 + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/CMakeLists.txt b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/CMakeLists.txt new file mode 100644 index 0000000..c747cb0 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/CMakeLists.txt @@ -0,0 +1,22 @@ +################################################################################### +# # +# NAME: CMakeLists.txt # +# # +# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. # +# WRITTEN BY: Michael Brockus. # +# # +# License: MIT # +# # +################################################################################### +cmake_minimum_required(VERSION 3.0 FATAL_ERROR) + + +add_library(unity STATIC "unity.c") + +install(TARGETS unity EXPORT unityConfig + ARCHIVE DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_LIBDIR}") + + diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/meson.build b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/meson.build new file mode 100644 index 0000000..f5e0146 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/meson.build @@ -0,0 +1,16 @@ +################################################################################### +# # +# NAME: meson.build # +# # +# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. # +# WRITTEN BY: Michael Brockus. # +# # +# License: MIT # +# # +################################################################################### + +unity_dir = include_directories('.') + +unity_lib = static_library(meson.project_name(), + sources: ['unity.c'], + include_directories: unity_dir) diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity.c b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity.c new file mode 100644 index 0000000..c7be02c --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity.c @@ -0,0 +1,2085 @@ +/* ========================================================================= + Unity Project - A Test Framework for C + Copyright (c) 2007-19 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +============================================================================ */ + +#include "unity.h" +#include + +#ifdef AVR +#include +#else +#define PROGMEM +#endif + +/* If omitted from header, declare overrideable prototypes here so they're ready for use */ +#ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION +void UNITY_OUTPUT_CHAR(int); +#endif + +/* Helpful macros for us to use here in Assert functions */ +#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } +#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } +#define RETURN_IF_FAIL_OR_IGNORE if (Unity.CurrentTestFailed || Unity.CurrentTestIgnored) return + +struct UNITY_STORAGE_T Unity; + +#ifdef UNITY_OUTPUT_COLOR +const char PROGMEM UnityStrOk[] = "\033[42mOK\033[00m"; +const char PROGMEM UnityStrPass[] = "\033[42mPASS\033[00m"; +const char PROGMEM UnityStrFail[] = "\033[41mFAIL\033[00m"; +const char PROGMEM UnityStrIgnore[] = "\033[43mIGNORE\033[00m"; +#else +const char PROGMEM UnityStrOk[] = "OK"; +const char PROGMEM UnityStrPass[] = "PASS"; +const char PROGMEM UnityStrFail[] = "FAIL"; +const char PROGMEM UnityStrIgnore[] = "IGNORE"; +#endif +static const char PROGMEM UnityStrNull[] = "NULL"; +static const char PROGMEM UnityStrSpacer[] = ". "; +static const char PROGMEM UnityStrExpected[] = " Expected "; +static const char PROGMEM UnityStrWas[] = " Was "; +static const char PROGMEM UnityStrGt[] = " to be greater than "; +static const char PROGMEM UnityStrLt[] = " to be less than "; +static const char PROGMEM UnityStrOrEqual[] = "or equal to "; +static const char PROGMEM UnityStrElement[] = " Element "; +static const char PROGMEM UnityStrByte[] = " Byte "; +static const char PROGMEM UnityStrMemory[] = " Memory Mismatch."; +static const char PROGMEM UnityStrDelta[] = " Values Not Within Delta "; +static const char PROGMEM UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; +static const char PROGMEM UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; +static const char PROGMEM UnityStrNullPointerForActual[] = " Actual pointer was NULL"; +#ifndef UNITY_EXCLUDE_FLOAT +static const char PROGMEM UnityStrNot[] = "Not "; +static const char PROGMEM UnityStrInf[] = "Infinity"; +static const char PROGMEM UnityStrNegInf[] = "Negative Infinity"; +static const char PROGMEM UnityStrNaN[] = "NaN"; +static const char PROGMEM UnityStrDet[] = "Determinate"; +static const char PROGMEM UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; +#endif +const char PROGMEM UnityStrErrShorthand[] = "Unity Shorthand Support Disabled"; +const char PROGMEM UnityStrErrFloat[] = "Unity Floating Point Disabled"; +const char PROGMEM UnityStrErrDouble[] = "Unity Double Precision Disabled"; +const char PROGMEM UnityStrErr64[] = "Unity 64-bit Support Disabled"; +static const char PROGMEM UnityStrBreaker[] = "-----------------------"; +static const char PROGMEM UnityStrResultsTests[] = " Tests "; +static const char PROGMEM UnityStrResultsFailures[] = " Failures "; +static const char PROGMEM UnityStrResultsIgnored[] = " Ignored "; +static const char PROGMEM UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; +static const char PROGMEM UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; + +/*----------------------------------------------- + * Pretty Printers & Test Result Output Handlers + *-----------------------------------------------*/ + +/*-----------------------------------------------*/ +/* Local helper function to print characters. */ +static void UnityPrintChar(const char* pch) +{ + /* printable characters plus CR & LF are printed */ + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + /* write escaped carriage returns */ + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)*pch, 2); + } +} + +/*-----------------------------------------------*/ +/* Local helper function to print ANSI escape strings e.g. "\033[42m". */ +#ifdef UNITY_OUTPUT_COLOR +static UNITY_UINT UnityPrintAnsiEscapeString(const char* string) +{ + const char* pch = string; + UNITY_UINT count = 0; + + while (*pch && (*pch != 'm')) + { + UNITY_OUTPUT_CHAR(*pch); + pch++; + count++; + } + UNITY_OUTPUT_CHAR('m'); + count++; + + return count; +} +#endif + +/*-----------------------------------------------*/ +void UnityPrint(const char* string) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch) + { +#ifdef UNITY_OUTPUT_COLOR + /* print ANSI escape code */ + if ((*pch == 27) && (*(pch + 1) == '[')) + { + pch += UnityPrintAnsiEscapeString(pch); + continue; + } +#endif + UnityPrintChar(pch); + pch++; + } + } +} + +/*-----------------------------------------------*/ +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +void UnityPrintFormatted(const char* format, ...) +{ + const char* pch = format; + va_list va; + va_start(va, format); + + if (pch != NULL) + { + while (*pch) + { + /* format identification character */ + if (*pch == '%') + { + pch++; + + if (pch != NULL) + { + switch (*pch) + { + case 'd': + case 'i': + { + const int number = va_arg(va, int); + UnityPrintNumber((UNITY_INT)number); + break; + } +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + case 'f': + case 'g': + { + const double number = va_arg(va, double); + UnityPrintFloat((UNITY_DOUBLE)number); + break; + } +#endif + case 'u': + { + const unsigned int number = va_arg(va, unsigned int); + UnityPrintNumberUnsigned((UNITY_UINT)number); + break; + } + case 'b': + { + const unsigned int number = va_arg(va, unsigned int); + const UNITY_UINT mask = (UNITY_UINT)0 - (UNITY_UINT)1; + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('b'); + UnityPrintMask(mask, (UNITY_UINT)number); + break; + } + case 'x': + case 'X': + case 'p': + { + const unsigned int number = va_arg(va, unsigned int); + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, 8); + break; + } + case 'c': + { + const int ch = va_arg(va, int); + UnityPrintChar((const char *)&ch); + break; + } + case 's': + { + const char * string = va_arg(va, const char *); + UnityPrint(string); + break; + } + case '%': + { + UnityPrintChar(pch); + break; + } + default: + { + /* print the unknown format character */ + UNITY_OUTPUT_CHAR('%'); + UnityPrintChar(pch); + break; + } + } + } + } +#ifdef UNITY_OUTPUT_COLOR + /* print ANSI escape code */ + else if ((*pch == 27) && (*(pch + 1) == '[')) + { + pch += UnityPrintAnsiEscapeString(pch); + continue; + } +#endif + else if (*pch == '\n') + { + UNITY_PRINT_EOL(); + } + else + { + UnityPrintChar(pch); + } + + pch++; + } + } + + va_end(va); +} +#endif /* ! UNITY_INCLUDE_PRINT_FORMATTED */ + +/*-----------------------------------------------*/ +void UnityPrintLen(const char* string, const UNITY_UINT32 length) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch && ((UNITY_UINT32)(pch - string) < length)) + { + /* printable characters plus CR & LF are printed */ + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + /* write escaped carriage returns */ + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)*pch, 2); + } + pch++; + } + } +} + +/*-----------------------------------------------*/ +void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style) +{ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (style == UNITY_DISPLAY_STYLE_CHAR) + { + /* printable characters plus CR & LF are printed */ + UNITY_OUTPUT_CHAR('\''); + if ((number <= 126) && (number >= 32)) + { + UNITY_OUTPUT_CHAR((int)number); + } + /* write escaped carriage returns */ + else if (number == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (number == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, 2); + } + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrintNumber(number); + } + } + else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) + { + UnityPrintNumberUnsigned((UNITY_UINT)number); + } + else + { + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2)); + } +} + +/*-----------------------------------------------*/ +void UnityPrintNumber(const UNITY_INT number_to_print) +{ + UNITY_UINT number = (UNITY_UINT)number_to_print; + + if (number_to_print < 0) + { + /* A negative number, including MIN negative */ + UNITY_OUTPUT_CHAR('-'); + number = (~number) + 1; + } + UnityPrintNumberUnsigned(number); +} + +/*----------------------------------------------- + * basically do an itoa using as little ram as possible */ +void UnityPrintNumberUnsigned(const UNITY_UINT number) +{ + UNITY_UINT divisor = 1; + + /* figure out initial divisor */ + while (number / divisor > 9) + { + divisor *= 10; + } + + /* now mod and print, then divide divisor */ + do + { + UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); + divisor /= 10; + } while (divisor > 0); +} + +/*-----------------------------------------------*/ +void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print) +{ + int nibble; + char nibbles = nibbles_to_print; + + if ((unsigned)nibbles > UNITY_MAX_NIBBLES) + { + nibbles = UNITY_MAX_NIBBLES; + } + + while (nibbles > 0) + { + nibbles--; + nibble = (int)(number >> (nibbles * 4)) & 0x0F; + if (nibble <= 9) + { + UNITY_OUTPUT_CHAR((char)('0' + nibble)); + } + else + { + UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); + } + } +} + +/*-----------------------------------------------*/ +void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number) +{ + UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1); + UNITY_INT32 i; + + for (i = 0; i < UNITY_INT_WIDTH; i++) + { + if (current_bit & mask) + { + if (current_bit & number) + { + UNITY_OUTPUT_CHAR('1'); + } + else + { + UNITY_OUTPUT_CHAR('0'); + } + } + else + { + UNITY_OUTPUT_CHAR('X'); + } + current_bit = current_bit >> 1; + } +} + +/*-----------------------------------------------*/ +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +/* + * This function prints a floating-point value in a format similar to + * printf("%.7g") on a single-precision machine or printf("%.9g") on a + * double-precision machine. The 7th digit won't always be totally correct + * in single-precision operation (for that level of accuracy, a more + * complicated algorithm would be needed). + */ +void UnityPrintFloat(const UNITY_DOUBLE input_number) +{ +#ifdef UNITY_INCLUDE_DOUBLE + static const int sig_digits = 9; + static const UNITY_INT32 min_scaled = 100000000; + static const UNITY_INT32 max_scaled = 1000000000; +#else + static const int sig_digits = 7; + static const UNITY_INT32 min_scaled = 1000000; + static const UNITY_INT32 max_scaled = 10000000; +#endif + + UNITY_DOUBLE number = input_number; + + /* print minus sign (does not handle negative zero) */ + if (number < 0.0f) + { + UNITY_OUTPUT_CHAR('-'); + number = -number; + } + + /* handle zero, NaN, and +/- infinity */ + if (number == 0.0f) + { + UnityPrint("0"); + } + else if (isnan(number)) + { + UnityPrint("nan"); + } + else if (isinf(number)) + { + UnityPrint("inf"); + } + else + { + UNITY_INT32 n_int = 0, n; + int exponent = 0; + int decimals, digits; + char buf[16] = {0}; + + /* + * Scale up or down by powers of 10. To minimize rounding error, + * start with a factor/divisor of 10^10, which is the largest + * power of 10 that can be represented exactly. Finally, compute + * (exactly) the remaining power of 10 and perform one more + * multiplication or division. + */ + if (number < 1.0f) + { + UNITY_DOUBLE factor = 1.0f; + + while (number < (UNITY_DOUBLE)max_scaled / 1e10f) { number *= 1e10f; exponent -= 10; } + while (number * factor < (UNITY_DOUBLE)min_scaled) { factor *= 10.0f; exponent--; } + + number *= factor; + } + else if (number > (UNITY_DOUBLE)max_scaled) + { + UNITY_DOUBLE divisor = 1.0f; + + while (number > (UNITY_DOUBLE)min_scaled * 1e10f) { number /= 1e10f; exponent += 10; } + while (number / divisor > (UNITY_DOUBLE)max_scaled) { divisor *= 10.0f; exponent++; } + + number /= divisor; + } + else + { + /* + * In this range, we can split off the integer part before + * doing any multiplications. This reduces rounding error by + * freeing up significant bits in the fractional part. + */ + UNITY_DOUBLE factor = 1.0f; + n_int = (UNITY_INT32)number; + number -= (UNITY_DOUBLE)n_int; + + while (n_int < min_scaled) { n_int *= 10; factor *= 10.0f; exponent--; } + + number *= factor; + } + + /* round to nearest integer */ + n = ((UNITY_INT32)(number + number) + 1) / 2; + +#ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO + /* round to even if exactly between two integers */ + if ((n & 1) && (((UNITY_DOUBLE)n - number) == 0.5f)) + n--; +#endif + + n += n_int; + + if (n >= max_scaled) + { + n = min_scaled; + exponent++; + } + + /* determine where to place decimal point */ + decimals = ((exponent <= 0) && (exponent >= -(sig_digits + 3))) ? (-exponent) : (sig_digits - 1); + exponent += decimals; + + /* truncate trailing zeroes after decimal point */ + while ((decimals > 0) && ((n % 10) == 0)) + { + n /= 10; + decimals--; + } + + /* build up buffer in reverse order */ + digits = 0; + while ((n != 0) || (digits < (decimals + 1))) + { + buf[digits++] = (char)('0' + n % 10); + n /= 10; + } + while (digits > 0) + { + if (digits == decimals) { UNITY_OUTPUT_CHAR('.'); } + UNITY_OUTPUT_CHAR(buf[--digits]); + } + + /* print exponent if needed */ + if (exponent != 0) + { + UNITY_OUTPUT_CHAR('e'); + + if (exponent < 0) + { + UNITY_OUTPUT_CHAR('-'); + exponent = -exponent; + } + else + { + UNITY_OUTPUT_CHAR('+'); + } + + digits = 0; + while ((exponent != 0) || (digits < 2)) + { + buf[digits++] = (char)('0' + exponent % 10); + exponent /= 10; + } + while (digits > 0) + { + UNITY_OUTPUT_CHAR(buf[--digits]); + } + } + } +} +#endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */ + +/*-----------------------------------------------*/ +static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) +{ +#ifdef UNITY_OUTPUT_FOR_ECLIPSE + UNITY_OUTPUT_CHAR('('); + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((UNITY_INT)line); + UNITY_OUTPUT_CHAR(')'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#else +#ifdef UNITY_OUTPUT_FOR_IAR_WORKBENCH + UnityPrint("'); + UnityPrint(Unity.CurrentTestName); + UnityPrint(" "); +#else +#ifdef UNITY_OUTPUT_FOR_QT_CREATOR + UnityPrint("file://"); + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((UNITY_INT)line); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#else + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((UNITY_INT)line); + UNITY_OUTPUT_CHAR(':'); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#endif +#endif +#endif +} + +/*-----------------------------------------------*/ +static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) +{ + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrFail); + UNITY_OUTPUT_CHAR(':'); +} + +/*-----------------------------------------------*/ +void UnityConcludeTest(void) +{ + if (Unity.CurrentTestIgnored) + { + Unity.TestIgnores++; + } + else if (!Unity.CurrentTestFailed) + { + UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); + UnityPrint(UnityStrPass); + } + else + { + Unity.TestFailures++; + } + + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + UNITY_PRINT_EXEC_TIME(); + UNITY_PRINT_EOL(); + UNITY_FLUSH_CALL(); +} + +/*-----------------------------------------------*/ +static void UnityAddMsgIfSpecified(const char* msg) +{ + if (msg) + { + UnityPrint(UnityStrSpacer); +#ifndef UNITY_EXCLUDE_DETAILS + if (Unity.CurrentDetail1) + { + UnityPrint(UnityStrDetail1Name); + UnityPrint(Unity.CurrentDetail1); + if (Unity.CurrentDetail2) + { + UnityPrint(UnityStrDetail2Name); + UnityPrint(Unity.CurrentDetail2); + } + UnityPrint(UnityStrSpacer); + } +#endif + UnityPrint(msg); + } +} + +/*-----------------------------------------------*/ +static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(expected); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(actual); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + +/*-----------------------------------------------*/ +static void UnityPrintExpectedAndActualStringsLen(const char* expected, + const char* actual, + const UNITY_UINT32 length) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrintLen(expected, length); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrintLen(actual, length); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + +/*----------------------------------------------- + * Assertion & Control Helpers + *-----------------------------------------------*/ + +/*-----------------------------------------------*/ +static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_LINE_TYPE lineNumber, + const char* msg) +{ + /* Both are NULL or same pointer */ + if (expected == actual) { return 0; } + + /* print and return true if just expected is NULL */ + if (expected == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForExpected); + UnityAddMsgIfSpecified(msg); + return 1; + } + + /* print and return true if just actual is NULL */ + if (actual == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForActual); + UnityAddMsgIfSpecified(msg); + return 1; + } + + return 0; /* return false if neither is NULL */ +} + +/*----------------------------------------------- + * Assertion Functions + *-----------------------------------------------*/ + +/*-----------------------------------------------*/ +void UnityAssertBits(const UNITY_INT mask, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if ((mask & expected) != (mask & actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected); + UnityPrint(UnityStrWas); + UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualNumber(const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if (expected != actual) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, + const UNITY_INT actual, + const UNITY_COMPARISON_T compare, + const char *msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + int failed = 0; + RETURN_IF_FAIL_OR_IGNORE; + + if ((threshold == actual) && (compare & UNITY_EQUAL_TO)) { return; } + if ((threshold == actual)) { failed = 1; } + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if ((actual > threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } + if ((actual < threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } + } + else /* UINT or HEX */ + { + if (((UNITY_UINT)actual > (UNITY_UINT)threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } + if (((UNITY_UINT)actual < (UNITY_UINT)threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } + } + + if (failed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(actual, style); + if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); } + if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); } + if (compare & UNITY_EQUAL_TO) { UnityPrint(UnityStrOrEqual); } + UnityPrintNumberByStyle(threshold, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#define UnityPrintPointlessAndBail() \ +{ \ + UnityTestResultsFailBegin(lineNumber); \ + UnityPrint(UnityStrPointless); \ + UnityAddMsgIfSpecified(msg); \ + UNITY_FAIL_AND_BAIL; } + +/*-----------------------------------------------*/ +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + unsigned int length = style & 0xF; + unsigned int increment = 0; + + RETURN_IF_FAIL_OR_IGNORE; + + if (num_elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while ((elements > 0) && (elements--)) + { + UNITY_INT expect_val; + UNITY_INT actual_val; + + switch (length) + { + case 1: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; + increment = sizeof(UNITY_INT8); + break; + + case 2: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; + increment = sizeof(UNITY_INT16); + break; + +#ifdef UNITY_SUPPORT_64 + case 8: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; + increment = sizeof(UNITY_INT64); + break; +#endif + + default: /* default is length 4 bytes */ + case 4: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; + increment = sizeof(UNITY_INT32); + length = 4; + break; + } + + if (expect_val != actual_val) + { + if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) + { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ + UNITY_INT mask = 1; + mask = (mask << 8 * length) - 1; + expect_val &= mask; + actual_val &= mask; + } + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expect_val, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual_val, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + /* Walk through array by incrementing the pointers */ + if (flags == UNITY_ARRAY_TO_ARRAY) + { + expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); + } + actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); + } +} + +/*-----------------------------------------------*/ +#ifndef UNITY_EXCLUDE_FLOAT +/* Wrap this define in a function with variable types as float or double */ +#define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \ + if (isinf(expected) && isinf(actual) && (((expected) < 0) == ((actual) < 0))) return 1; \ + if (UNITY_NAN_CHECK) return 1; \ + (diff) = (actual) - (expected); \ + if ((diff) < 0) (diff) = -(diff); \ + if ((delta) < 0) (delta) = -(delta); \ + return !(isnan(diff) || isinf(diff) || ((diff) > (delta))) + /* This first part of this condition will catch any NaN or Infinite values */ +#ifndef UNITY_NAN_NOT_EQUAL_NAN + #define UNITY_NAN_CHECK isnan(expected) && isnan(actual) +#else + #define UNITY_NAN_CHECK 0 +#endif + +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ + { \ + UnityPrint(UnityStrExpected); \ + UnityPrintFloat(expected); \ + UnityPrint(UnityStrWas); \ + UnityPrintFloat(actual); } +#else + #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ + UnityPrint(UnityStrDelta) +#endif /* UNITY_EXCLUDE_FLOAT_PRINT */ + +/*-----------------------------------------------*/ +static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual) +{ + UNITY_FLOAT diff; + UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); +} + +/*-----------------------------------------------*/ +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual; + + RETURN_IF_FAIL_OR_IGNORE; + + if (elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while (elements--) + { + if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + if (flags == UNITY_ARRAY_TO_ARRAY) + { + ptr_expected++; + } + ptr_actual++; + } +} + +/*-----------------------------------------------*/ +void UnityAssertFloatsWithin(const UNITY_FLOAT delta, + const UNITY_FLOAT expected, + const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + RETURN_IF_FAIL_OR_IGNORE; + + + if (!UnityFloatsWithin(delta, expected, actual)) + { + UnityTestResultsFailBegin(lineNumber); + UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertFloatSpecial(const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; + UNITY_INT should_be_trait = ((UNITY_INT)style & 1); + UNITY_INT is_trait = !should_be_trait; + UNITY_INT trait_index = (UNITY_INT)(style >> 1); + + RETURN_IF_FAIL_OR_IGNORE; + + switch (style) + { + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = isinf(actual) && (actual > 0); + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = isinf(actual) && (actual < 0); + break; + + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = isnan(actual) ? 1 : 0; + break; + + case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ + case UNITY_FLOAT_IS_NOT_DET: + is_trait = !isinf(actual) && !isnan(actual); + break; + + default: + trait_index = 0; + trait_names[0] = UnityStrInvalidFloatTrait; + break; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + { + UnityPrint(UnityStrNot); + } + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + UnityPrintFloat((UNITY_DOUBLE)actual); +#else + if (should_be_trait) + { + UnityPrint(UnityStrNot); + } + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#endif /* not UNITY_EXCLUDE_FLOAT */ + +/*-----------------------------------------------*/ +#ifndef UNITY_EXCLUDE_DOUBLE +static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual) +{ + UNITY_DOUBLE diff; + UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); +} + +/*-----------------------------------------------*/ +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual; + + RETURN_IF_FAIL_OR_IGNORE; + + if (elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while (elements--) + { + if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + if (flags == UNITY_ARRAY_TO_ARRAY) + { + ptr_expected++; + } + ptr_actual++; + } +} + +/*-----------------------------------------------*/ +void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, + const UNITY_DOUBLE expected, + const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if (!UnityDoublesWithin(delta, expected, actual)) + { + UnityTestResultsFailBegin(lineNumber); + UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; + UNITY_INT should_be_trait = ((UNITY_INT)style & 1); + UNITY_INT is_trait = !should_be_trait; + UNITY_INT trait_index = (UNITY_INT)(style >> 1); + + RETURN_IF_FAIL_OR_IGNORE; + + switch (style) + { + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = isinf(actual) && (actual > 0); + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = isinf(actual) && (actual < 0); + break; + + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = isnan(actual) ? 1 : 0; + break; + + case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ + case UNITY_FLOAT_IS_NOT_DET: + is_trait = !isinf(actual) && !isnan(actual); + break; + + default: + trait_index = 0; + trait_names[0] = UnityStrInvalidFloatTrait; + break; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + { + UnityPrint(UnityStrNot); + } + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + UnityPrintFloat(actual); +#else + if (should_be_trait) + { + UnityPrint(UnityStrNot); + } + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#endif /* not UNITY_EXCLUDE_DOUBLE */ + +/*-----------------------------------------------*/ +void UnityAssertNumbersWithin(const UNITY_UINT delta, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (actual > expected) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); + } + } + else + { + if ((UNITY_UINT)actual > (UNITY_UINT)expected) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrDelta); + UnityPrintNumberByStyle((UNITY_INT)delta, style); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, + UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + unsigned int length = style & 0xF; + unsigned int increment = 0; + + RETURN_IF_FAIL_OR_IGNORE; + + if (num_elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while ((elements > 0) && (elements--)) + { + UNITY_INT expect_val; + UNITY_INT actual_val; + + switch (length) + { + case 1: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; + increment = sizeof(UNITY_INT8); + break; + + case 2: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; + increment = sizeof(UNITY_INT16); + break; + +#ifdef UNITY_SUPPORT_64 + case 8: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; + increment = sizeof(UNITY_INT64); + break; +#endif + + default: /* default is length 4 bytes */ + case 4: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; + increment = sizeof(UNITY_INT32); + length = 4; + break; + } + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (actual_val > expect_val) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); + } + } + else + { + if ((UNITY_UINT)actual_val > (UNITY_UINT)expect_val) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); + } + } + + if (Unity.CurrentTestFailed) + { + if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) + { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ + UNITY_INT mask = 1; + mask = (mask << 8 * length) - 1; + expect_val &= mask; + actual_val &= mask; + } + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrDelta); + UnityPrintNumberByStyle((UNITY_INT)delta, style); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expect_val, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual_val, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + /* Walk through array by incrementing the pointers */ + if (flags == UNITY_ARRAY_TO_ARRAY) + { + expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); + } + actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_UINT32 i; + + RETURN_IF_FAIL_OR_IGNORE; + + /* if both pointers not null compare the strings */ + if (expected && actual) + { + for (i = 0; expected[i] || actual[i]; i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* handle case of one pointers being null (if both null, test should pass) */ + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStrings(expected, actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const UNITY_UINT32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_UINT32 i; + + RETURN_IF_FAIL_OR_IGNORE; + + /* if both pointers not null compare the strings */ + if (expected && actual) + { + for (i = 0; (i < length) && (expected[i] || actual[i]); i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* handle case of one pointers being null (if both null, test should pass) */ + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStringsLen(expected, actual, length); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected, + const char** actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 i = 0; + UNITY_UINT32 j = 0; + const char* expd = NULL; + const char* act = NULL; + + RETURN_IF_FAIL_OR_IGNORE; + + /* if no elements, it's an error */ + if (num_elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if ((const void*)expected == (const void*)actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + if (flags != UNITY_ARRAY_TO_ARRAY) + { + expd = (const char*)expected; + } + + do + { + act = actual[j]; + if (flags == UNITY_ARRAY_TO_ARRAY) + { + expd = ((const char* const*)expected)[j]; + } + + /* if both pointers not null compare the strings */ + if (expd && act) + { + for (i = 0; expd[i] || act[i]; i++) + { + if (expd[i] != act[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* handle case of one pointers being null (if both null, test should pass) */ + if (expd != act) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(j); + } + UnityPrintExpectedAndActualStrings(expd, act); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + } while (++j < num_elements); +} + +/*-----------------------------------------------*/ +void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 length, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags) +{ + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; + UNITY_UINT32 elements = num_elements; + UNITY_UINT32 bytes; + + RETURN_IF_FAIL_OR_IGNORE; + + if ((elements == 0) || (length == 0)) + { + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while (elements--) + { + bytes = length; + while (bytes--) + { + if (*ptr_exp != *ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrMemory); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + } + UnityPrint(UnityStrByte); + UnityPrintNumberUnsigned(length - bytes - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp++; + ptr_act++; + } + if (flags == UNITY_ARRAY_TO_VAL) + { + ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; + } + } +} + +/*-----------------------------------------------*/ + +static union +{ + UNITY_INT8 i8; + UNITY_INT16 i16; + UNITY_INT32 i32; +#ifdef UNITY_SUPPORT_64 + UNITY_INT64 i64; +#endif +#ifndef UNITY_EXCLUDE_FLOAT + float f; +#endif +#ifndef UNITY_EXCLUDE_DOUBLE + double d; +#endif +} UnityQuickCompare; + +UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size) +{ + switch(size) + { + case 1: + UnityQuickCompare.i8 = (UNITY_INT8)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8); + + case 2: + UnityQuickCompare.i16 = (UNITY_INT16)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16); + +#ifdef UNITY_SUPPORT_64 + case 8: + UnityQuickCompare.i64 = (UNITY_INT64)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64); +#endif + + default: /* 4 bytes */ + UnityQuickCompare.i32 = (UNITY_INT32)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32); + } +} + +#ifndef UNITY_EXCLUDE_FLOAT +/*-----------------------------------------------*/ +UNITY_INTERNAL_PTR UnityFloatToPtr(const float num) +{ + UnityQuickCompare.f = num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f); +} +#endif + +#ifndef UNITY_EXCLUDE_DOUBLE +/*-----------------------------------------------*/ +UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num) +{ + UnityQuickCompare.d = num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d); +} +#endif + +/*----------------------------------------------- + * Control Functions + *-----------------------------------------------*/ + +/*-----------------------------------------------*/ +void UnityFail(const char* msg, const UNITY_LINE_TYPE line) +{ + RETURN_IF_FAIL_OR_IGNORE; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrFail); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + +#ifndef UNITY_EXCLUDE_DETAILS + if (Unity.CurrentDetail1) + { + UnityPrint(UnityStrDetail1Name); + UnityPrint(Unity.CurrentDetail1); + if (Unity.CurrentDetail2) + { + UnityPrint(UnityStrDetail2Name); + UnityPrint(Unity.CurrentDetail2); + } + UnityPrint(UnityStrSpacer); + } +#endif + if (msg[0] != ' ') + { + UNITY_OUTPUT_CHAR(' '); + } + UnityPrint(msg); + } + + UNITY_FAIL_AND_BAIL; +} + +/*-----------------------------------------------*/ +void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) +{ + RETURN_IF_FAIL_OR_IGNORE; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrIgnore); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(msg); + } + UNITY_IGNORE_AND_BAIL; +} + +/*-----------------------------------------------*/ +void UnityMessage(const char* msg, const UNITY_LINE_TYPE line) +{ + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint("INFO"); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(msg); + } + UNITY_PRINT_EOL(); +} + +/*-----------------------------------------------*/ +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) +{ + Unity.CurrentTestName = FuncName; + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; + Unity.NumberOfTests++; + UNITY_CLR_DETAILS(); + UNITY_EXEC_TIME_START(); + if (TEST_PROTECT()) + { + setUp(); + Func(); + } + if (TEST_PROTECT()) + { + tearDown(); + } + UNITY_EXEC_TIME_STOP(); + UnityConcludeTest(); +} + +/*-----------------------------------------------*/ +void UnitySetTestFile(const char* filename) +{ + Unity.TestFile = filename; +} + +/*-----------------------------------------------*/ +void UnityBegin(const char* filename) +{ + Unity.TestFile = filename; + Unity.CurrentTestName = NULL; + Unity.CurrentTestLineNumber = 0; + Unity.NumberOfTests = 0; + Unity.TestFailures = 0; + Unity.TestIgnores = 0; + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + + UNITY_CLR_DETAILS(); + UNITY_OUTPUT_START(); +} + +/*-----------------------------------------------*/ +int UnityEnd(void) +{ + UNITY_PRINT_EOL(); + UnityPrint(UnityStrBreaker); + UNITY_PRINT_EOL(); + UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests)); + UnityPrint(UnityStrResultsTests); + UnityPrintNumber((UNITY_INT)(Unity.TestFailures)); + UnityPrint(UnityStrResultsFailures); + UnityPrintNumber((UNITY_INT)(Unity.TestIgnores)); + UnityPrint(UnityStrResultsIgnored); + UNITY_PRINT_EOL(); + if (Unity.TestFailures == 0U) + { + UnityPrint(UnityStrOk); + } + else + { + UnityPrint(UnityStrFail); +#ifdef UNITY_DIFFERENTIATE_FINAL_FAIL + UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D'); +#endif + } + UNITY_PRINT_EOL(); + UNITY_FLUSH_CALL(); + UNITY_OUTPUT_COMPLETE(); + return (int)(Unity.TestFailures); +} + +/*----------------------------------------------- + * Command Line Argument Support + *-----------------------------------------------*/ +#ifdef UNITY_USE_COMMAND_LINE_ARGS + +char* UnityOptionIncludeNamed = NULL; +char* UnityOptionExcludeNamed = NULL; +int UnityVerbosity = 1; + +/*-----------------------------------------------*/ +int UnityParseOptions(int argc, char** argv) +{ + int i; + UnityOptionIncludeNamed = NULL; + UnityOptionExcludeNamed = NULL; + + for (i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'l': /* list tests */ + return -1; + case 'n': /* include tests with name including this string */ + case 'f': /* an alias for -n */ + if (argv[i][2] == '=') + { + UnityOptionIncludeNamed = &argv[i][3]; + } + else if (++i < argc) + { + UnityOptionIncludeNamed = argv[i]; + } + else + { + UnityPrint("ERROR: No Test String to Include Matches For"); + UNITY_PRINT_EOL(); + return 1; + } + break; + case 'q': /* quiet */ + UnityVerbosity = 0; + break; + case 'v': /* verbose */ + UnityVerbosity = 2; + break; + case 'x': /* exclude tests with name including this string */ + if (argv[i][2] == '=') + { + UnityOptionExcludeNamed = &argv[i][3]; + } + else if (++i < argc) + { + UnityOptionExcludeNamed = argv[i]; + } + else + { + UnityPrint("ERROR: No Test String to Exclude Matches For"); + UNITY_PRINT_EOL(); + return 1; + } + break; + default: + UnityPrint("ERROR: Unknown Option "); + UNITY_OUTPUT_CHAR(argv[i][1]); + UNITY_PRINT_EOL(); + return 1; + } + } + } + + return 0; +} + +/*-----------------------------------------------*/ +int IsStringInBiggerString(const char* longstring, const char* shortstring) +{ + const char* lptr = longstring; + const char* sptr = shortstring; + const char* lnext = lptr; + + if (*sptr == '*') + { + return 1; + } + + while (*lptr) + { + lnext = lptr + 1; + + /* If they current bytes match, go on to the next bytes */ + while (*lptr && *sptr && (*lptr == *sptr)) + { + lptr++; + sptr++; + + /* We're done if we match the entire string or up to a wildcard */ + if (*sptr == '*') + return 1; + if (*sptr == ',') + return 1; + if (*sptr == '"') + return 1; + if (*sptr == '\'') + return 1; + if (*sptr == ':') + return 2; + if (*sptr == 0) + return 1; + } + + /* Otherwise we start in the long pointer 1 character further and try again */ + lptr = lnext; + sptr = shortstring; + } + + return 0; +} + +/*-----------------------------------------------*/ +int UnityStringArgumentMatches(const char* str) +{ + int retval; + const char* ptr1; + const char* ptr2; + const char* ptrf; + + /* Go through the options and get the substrings for matching one at a time */ + ptr1 = str; + while (ptr1[0] != 0) + { + if ((ptr1[0] == '"') || (ptr1[0] == '\'')) + { + ptr1++; + } + + /* look for the start of the next partial */ + ptr2 = ptr1; + ptrf = 0; + do + { + ptr2++; + if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')) + { + ptrf = &ptr2[1]; + } + } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); + + while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ','))) + { + ptr2++; + } + + /* done if complete filename match */ + retval = IsStringInBiggerString(Unity.TestFile, ptr1); + if (retval == 1) + { + return retval; + } + + /* done if testname match after filename partial match */ + if ((retval == 2) && (ptrf != 0)) + { + if (IsStringInBiggerString(Unity.CurrentTestName, ptrf)) + { + return 1; + } + } + + /* done if complete testname match */ + if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) + { + return 1; + } + + ptr1 = ptr2; + } + + /* we couldn't find a match for any substrings */ + return 0; +} + +/*-----------------------------------------------*/ +int UnityTestMatches(void) +{ + /* Check if this test name matches the included test pattern */ + int retval; + if (UnityOptionIncludeNamed) + { + retval = UnityStringArgumentMatches(UnityOptionIncludeNamed); + } + else + { + retval = 1; + } + + /* Check if this test name matches the excluded test pattern */ + if (UnityOptionExcludeNamed) + { + if (UnityStringArgumentMatches(UnityOptionExcludeNamed)) + { + retval = 0; + } + } + + return retval; +} + +#endif /* UNITY_USE_COMMAND_LINE_ARGS */ +/*-----------------------------------------------*/ diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity.h new file mode 100644 index 0000000..34d7f93 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity.h @@ -0,0 +1,617 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-19 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FRAMEWORK_H +#define UNITY_FRAMEWORK_H +#define UNITY + +#define UNITY_VERSION_MAJOR 2 +#define UNITY_VERSION_MINOR 5 +#define UNITY_VERSION_BUILD 0 +#define UNITY_VERSION ((UNITY_VERSION_MAJOR << 16) | (UNITY_VERSION_MINOR << 8) | UNITY_VERSION_BUILD) + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "unity_internals.h" + +/*------------------------------------------------------- + * Test Setup / Teardown + *-------------------------------------------------------*/ + +/* These functions are intended to be called before and after each test. + * If using unity directly, these will need to be provided for each test + * executable built. If you are using the test runner generator and/or + * Ceedling, these are optional. */ +void setUp(void); +void tearDown(void); + +/* These functions are intended to be called at the beginning and end of an + * entire test suite. suiteTearDown() is passed the number of tests that + * failed, and its return value becomes the exit code of main(). If using + * Unity directly, you're in charge of calling these if they are desired. + * If using Ceedling or the test runner generator, these will be called + * automatically if they exist. */ +void suiteSetUp(void); +int suiteTearDown(int num_failures); + +/*------------------------------------------------------- + * Test Reset and Verify + *-------------------------------------------------------*/ + +/* These functions are intended to be called before during tests in order + * to support complex test loops, etc. Both are NOT built into Unity. Instead + * the test runner generator will create them. resetTest will run teardown and + * setup again, verifying any end-of-test needs between. verifyTest will only + * run the verification. */ +void resetTest(void); +void verifyTest(void); + +/*------------------------------------------------------- + * Configuration Options + *------------------------------------------------------- + * All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. + + * Integers/longs/pointers + * - Unity attempts to automatically discover your integer sizes + * - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in + * - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in + * - If you cannot use the automatic methods above, you can force Unity by using these options: + * - define UNITY_SUPPORT_64 + * - set UNITY_INT_WIDTH + * - set UNITY_LONG_WIDTH + * - set UNITY_POINTER_WIDTH + + * Floats + * - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons + * - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT + * - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats + * - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons + * - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) + * - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE + * - define UNITY_DOUBLE_TYPE to specify something other than double + * - define UNITY_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors + + * Output + * - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired + * - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure + + * Optimization + * - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge + * - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. + + * Test Cases + * - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script + + * Parameterized Tests + * - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing + + * Tests with Arguments + * - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity + + *------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message)) +#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) +#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message)) +#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) +#define TEST_MESSAGE(message) UnityMessage((message), __LINE__) +#define TEST_ONLY() + +/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails. + * This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */ +#define TEST_PASS() TEST_ABORT() +#define TEST_PASS_MESSAGE(message) do { UnityMessage((message), __LINE__); TEST_ABORT(); } while(0) + +/* This macro does nothing, but it is useful for build tools (like Ceedling) to make use of this to figure out + * which files should be linked to in order to perform a test. Use it like TEST_FILE("sandwiches.c") */ +#define TEST_FILE(a) + +/*------------------------------------------------------- + * Test Asserts (simple) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") +#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") +#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") +#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") +#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") +#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_size_t(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_CHAR(expected, actual) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, NULL) + +/* Integer Greater Than/ Less Than (of all sizes) */ +#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_size_t_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_CHAR_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, NULL) + +/* Integer Array Ranges (of all sizes) */ +#define TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_size_t_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) + + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_size_t_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) + +/* Arrays Compared To Single Value */ +#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_size_t(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, NULL) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/* Shorthand */ +#ifdef UNITY_SHORTHAND_AS_OLD +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#endif +#ifdef UNITY_SHORTHAND_AS_INT +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_MEM +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_RAW +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, " Expected Equal") +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#endif +#ifdef UNITY_SHORTHAND_AS_NONE +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif + +/*------------------------------------------------------- + * Test Asserts (with additional messages) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message)) +#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message)) + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_size_t_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_CHAR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, (message)) + +/* Integer Greater Than/ Less Than (of all sizes) */ +#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message)) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_size_t_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_CHAR_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, (message)) + +/* Integer Array Ranges (of all sizes) */ +#define TEST_ASSERT_INT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_size_t_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_CHAR_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) + + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message)) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_size_t_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_CHAR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) + +/* Arrays Compared To Single Value*/ +#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_size_t_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_CHAR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, (message)) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* Shorthand */ +#ifdef UNITY_SHORTHAND_AS_OLD +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) +#endif +#ifdef UNITY_SHORTHAND_AS_INT +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_MEM +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_RAW +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message) +#endif +#ifdef UNITY_SHORTHAND_AS_NONE +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif + +/* end of UNITY_FRAMEWORK_H */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity_internals.h b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity_internals.h new file mode 100644 index 0000000..a9a7ea2 --- /dev/null +++ b/circuitpython/lib/tinyusb/test/vendor/ceedling/vendor/unity/src/unity_internals.h @@ -0,0 +1,1002 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-19 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_INTERNALS_H +#define UNITY_INTERNALS_H + +#ifdef UNITY_INCLUDE_CONFIG_H +#include "unity_config.h" +#endif + +#ifndef UNITY_EXCLUDE_SETJMP_H +#include +#endif + +#ifndef UNITY_EXCLUDE_MATH_H +#include +#endif + +#ifndef UNITY_EXCLUDE_STDDEF_H +#include +#endif + +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +#include +#endif + +/* Unity Attempts to Auto-Detect Integer Types + * Attempt 1: UINT_MAX, ULONG_MAX in , or default to 32 bits + * Attempt 2: UINTPTR_MAX in , or default to same size as long + * The user may override any of these derived constants: + * UNITY_INT_WIDTH, UNITY_LONG_WIDTH, UNITY_POINTER_WIDTH */ +#ifndef UNITY_EXCLUDE_STDINT_H +#include +#endif + +#ifndef UNITY_EXCLUDE_LIMITS_H +#include +#endif + +/*------------------------------------------------------- + * Guess Widths If Not Specified + *-------------------------------------------------------*/ + +/* Determine the size of an int, if not already specified. + * We cannot use sizeof(int), because it is not yet defined + * at this stage in the translation of the C program. + * Also sizeof(int) does return the size in addressable units on all platforms, + * which may not necessarily be the size in bytes. + * Therefore, infer it from UINT_MAX if possible. */ +#ifndef UNITY_INT_WIDTH + #ifdef UINT_MAX + #if (UINT_MAX == 0xFFFF) + #define UNITY_INT_WIDTH (16) + #elif (UINT_MAX == 0xFFFFFFFF) + #define UNITY_INT_WIDTH (32) + #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_INT_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_INT_WIDTH (32) + #endif /* UINT_MAX */ +#endif + +/* Determine the size of a long, if not already specified. */ +#ifndef UNITY_LONG_WIDTH + #ifdef ULONG_MAX + #if (ULONG_MAX == 0xFFFF) + #define UNITY_LONG_WIDTH (16) + #elif (ULONG_MAX == 0xFFFFFFFF) + #define UNITY_LONG_WIDTH (32) + #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_LONG_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_LONG_WIDTH (32) + #endif /* ULONG_MAX */ +#endif + +/* Determine the size of a pointer, if not already specified. */ +#ifndef UNITY_POINTER_WIDTH + #ifdef UINTPTR_MAX + #if (UINTPTR_MAX <= 0xFFFF) + #define UNITY_POINTER_WIDTH (16) + #elif (UINTPTR_MAX <= 0xFFFFFFFF) + #define UNITY_POINTER_WIDTH (32) + #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) + #define UNITY_POINTER_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH + #endif /* UINTPTR_MAX */ +#endif + +/*------------------------------------------------------- + * Int Support (Define types based on detected sizes) + *-------------------------------------------------------*/ + +#if (UNITY_INT_WIDTH == 32) + typedef unsigned char UNITY_UINT8; + typedef unsigned short UNITY_UINT16; + typedef unsigned int UNITY_UINT32; + typedef signed char UNITY_INT8; + typedef signed short UNITY_INT16; + typedef signed int UNITY_INT32; +#elif (UNITY_INT_WIDTH == 16) + typedef unsigned char UNITY_UINT8; + typedef unsigned int UNITY_UINT16; + typedef unsigned long UNITY_UINT32; + typedef signed char UNITY_INT8; + typedef signed int UNITY_INT16; + typedef signed long UNITY_INT32; +#else + #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) +#endif + +/*------------------------------------------------------- + * 64-bit Support + *-------------------------------------------------------*/ + +/* Auto-detect 64 Bit Support */ +#ifndef UNITY_SUPPORT_64 + #if UNITY_LONG_WIDTH == 64 || UNITY_POINTER_WIDTH == 64 + #define UNITY_SUPPORT_64 + #endif +#endif + +/* 64-Bit Support Dependent Configuration */ +#ifndef UNITY_SUPPORT_64 + /* No 64-bit Support */ + typedef UNITY_UINT32 UNITY_UINT; + typedef UNITY_INT32 UNITY_INT; + #define UNITY_MAX_NIBBLES (8) /* Maximum number of nibbles in a UNITY_(U)INT */ +#else + /* 64-bit Support */ + #if (UNITY_LONG_WIDTH == 32) + typedef unsigned long long UNITY_UINT64; + typedef signed long long UNITY_INT64; + #elif (UNITY_LONG_WIDTH == 64) + typedef unsigned long UNITY_UINT64; + typedef signed long UNITY_INT64; + #else + #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) + #endif + typedef UNITY_UINT64 UNITY_UINT; + typedef UNITY_INT64 UNITY_INT; + #define UNITY_MAX_NIBBLES (16) /* Maximum number of nibbles in a UNITY_(U)INT */ +#endif + +/*------------------------------------------------------- + * Pointer Support + *-------------------------------------------------------*/ + +#if (UNITY_POINTER_WIDTH == 32) + #define UNITY_PTR_TO_INT UNITY_INT32 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 +#elif (UNITY_POINTER_WIDTH == 64) + #define UNITY_PTR_TO_INT UNITY_INT64 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 +#elif (UNITY_POINTER_WIDTH == 16) + #define UNITY_PTR_TO_INT UNITY_INT16 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 +#else + #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) +#endif + +#ifndef UNITY_PTR_ATTRIBUTE + #define UNITY_PTR_ATTRIBUTE +#endif + +#ifndef UNITY_INTERNAL_PTR + #define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* +#endif + +/*------------------------------------------------------- + * Float Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_FLOAT + +/* No Floating Point Support */ +#ifndef UNITY_EXCLUDE_DOUBLE +#define UNITY_EXCLUDE_DOUBLE /* Remove double when excluding float support */ +#endif +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +#define UNITY_EXCLUDE_FLOAT_PRINT +#endif + +#else + +/* Floating Point Support */ +#ifndef UNITY_FLOAT_PRECISION +#define UNITY_FLOAT_PRECISION (0.00001f) +#endif +#ifndef UNITY_FLOAT_TYPE +#define UNITY_FLOAT_TYPE float +#endif +typedef UNITY_FLOAT_TYPE UNITY_FLOAT; + +/* isinf & isnan macros should be provided by math.h */ +#ifndef isinf +/* The value of Inf - Inf is NaN */ +#define isinf(n) (isnan((n) - (n)) && !isnan(n)) +#endif + +#ifndef isnan +/* NaN is the only floating point value that does NOT equal itself. + * Therefore if n != n, then it is NaN. */ +#define isnan(n) ((n != n) ? 1 : 0) +#endif + +#endif + +/*------------------------------------------------------- + * Double Float Support + *-------------------------------------------------------*/ + +/* unlike float, we DON'T include by default */ +#if defined(UNITY_EXCLUDE_DOUBLE) || !defined(UNITY_INCLUDE_DOUBLE) + + /* No Floating Point Support */ + #ifndef UNITY_EXCLUDE_DOUBLE + #define UNITY_EXCLUDE_DOUBLE + #else + #undef UNITY_INCLUDE_DOUBLE + #endif + + #ifndef UNITY_EXCLUDE_FLOAT + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_FLOAT UNITY_DOUBLE; + /* For parameter in UnityPrintFloat(UNITY_DOUBLE), which aliases to double or float */ + #endif + +#else + + /* Double Floating Point Support */ + #ifndef UNITY_DOUBLE_PRECISION + #define UNITY_DOUBLE_PRECISION (1e-12) + #endif + + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_DOUBLE_TYPE UNITY_DOUBLE; + +#endif + +/*------------------------------------------------------- + * Output Method: stdout (DEFAULT) + *-------------------------------------------------------*/ +#ifndef UNITY_OUTPUT_CHAR + /* Default to using putchar, which is defined in stdio.h */ + #include + #define UNITY_OUTPUT_CHAR(a) (void)putchar(a) +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifdef UNITY_OUTPUT_CHAR_HEADER_DECLARATION + extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION; + #endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH + #ifdef UNITY_USE_FLUSH_STDOUT + /* We want to use the stdout flush utility */ + #include + #define UNITY_OUTPUT_FLUSH() (void)fflush(stdout) + #else + /* We've specified nothing, therefore flush should just be ignored */ + #define UNITY_OUTPUT_FLUSH() + #endif +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifdef UNITY_OUTPUT_FLUSH_HEADER_DECLARATION + extern void UNITY_OUTPUT_FLUSH_HEADER_DECLARATION; + #endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH +#define UNITY_FLUSH_CALL() +#else +#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH() +#endif + +#ifndef UNITY_PRINT_EOL +#define UNITY_PRINT_EOL() UNITY_OUTPUT_CHAR('\n') +#endif + +#ifndef UNITY_OUTPUT_START +#define UNITY_OUTPUT_START() +#endif + +#ifndef UNITY_OUTPUT_COMPLETE +#define UNITY_OUTPUT_COMPLETE() +#endif + +#ifdef UNITY_INCLUDE_EXEC_TIME + #if !defined(UNITY_EXEC_TIME_START) && \ + !defined(UNITY_EXEC_TIME_STOP) && \ + !defined(UNITY_PRINT_EXEC_TIME) && \ + !defined(UNITY_TIME_TYPE) + /* If none any of these macros are defined then try to provide a default implementation */ + + #if defined(UNITY_CLOCK_MS) + /* This is a simple way to get a default implementation on platforms that support getting a millisecond counter */ + #define UNITY_TIME_TYPE UNITY_UINT + #define UNITY_EXEC_TIME_START() Unity.CurrentTestStartTime = UNITY_CLOCK_MS() + #define UNITY_EXEC_TIME_STOP() Unity.CurrentTestStopTime = UNITY_CLOCK_MS() + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = (Unity.CurrentTestStopTime - Unity.CurrentTestStartTime); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #elif defined(_WIN32) + #include + #define UNITY_TIME_TYPE clock_t + #define UNITY_GET_TIME(t) t = (clock_t)((clock() * 1000) / CLOCKS_PER_SEC) + #define UNITY_EXEC_TIME_START() UNITY_GET_TIME(Unity.CurrentTestStartTime) + #define UNITY_EXEC_TIME_STOP() UNITY_GET_TIME(Unity.CurrentTestStopTime) + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = (Unity.CurrentTestStopTime - Unity.CurrentTestStartTime); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #elif defined(__unix__) + #include + #define UNITY_TIME_TYPE struct timespec + #define UNITY_GET_TIME(t) clock_gettime(CLOCK_MONOTONIC, &t) + #define UNITY_EXEC_TIME_START() UNITY_GET_TIME(Unity.CurrentTestStartTime) + #define UNITY_EXEC_TIME_STOP() UNITY_GET_TIME(Unity.CurrentTestStopTime) + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = ((Unity.CurrentTestStopTime.tv_sec - Unity.CurrentTestStartTime.tv_sec) * 1000L); \ + execTimeMs += ((Unity.CurrentTestStopTime.tv_nsec - Unity.CurrentTestStartTime.tv_nsec) / 1000000L); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #endif + #endif +#endif + +#ifndef UNITY_EXEC_TIME_START +#define UNITY_EXEC_TIME_START() do{}while(0) +#endif + +#ifndef UNITY_EXEC_TIME_STOP +#define UNITY_EXEC_TIME_STOP() do{}while(0) +#endif + +#ifndef UNITY_TIME_TYPE +#define UNITY_TIME_TYPE UNITY_UINT +#endif + +#ifndef UNITY_PRINT_EXEC_TIME +#define UNITY_PRINT_EXEC_TIME() do{}while(0) +#endif + +/*------------------------------------------------------- + * Footprint + *-------------------------------------------------------*/ + +#ifndef UNITY_LINE_TYPE +#define UNITY_LINE_TYPE UNITY_UINT +#endif + +#ifndef UNITY_COUNTER_TYPE +#define UNITY_COUNTER_TYPE UNITY_UINT +#endif + +/*------------------------------------------------------- + * Internal Structs Needed + *-------------------------------------------------------*/ + +typedef void (*UnityTestFunction)(void); + +#define UNITY_DISPLAY_RANGE_INT (0x10) +#define UNITY_DISPLAY_RANGE_UINT (0x20) +#define UNITY_DISPLAY_RANGE_HEX (0x40) +#define UNITY_DISPLAY_RANGE_CHAR (0x80) + +typedef enum +{ + UNITY_DISPLAY_STYLE_INT = (UNITY_INT_WIDTH / 8) + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, +#endif + + UNITY_DISPLAY_STYLE_UINT = (UNITY_INT_WIDTH / 8) + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, +#endif + + UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, +#endif + + UNITY_DISPLAY_STYLE_CHAR = 1 + UNITY_DISPLAY_RANGE_CHAR + UNITY_DISPLAY_RANGE_INT, + + UNITY_DISPLAY_STYLE_UNKNOWN +} UNITY_DISPLAY_STYLE_T; + +typedef enum +{ + UNITY_WITHIN = 0x0, + UNITY_EQUAL_TO = 0x1, + UNITY_GREATER_THAN = 0x2, + UNITY_GREATER_OR_EQUAL = 0x2 + UNITY_EQUAL_TO, + UNITY_SMALLER_THAN = 0x4, + UNITY_SMALLER_OR_EQUAL = 0x4 + UNITY_EQUAL_TO, + UNITY_UNKNOWN +} UNITY_COMPARISON_T; + +#ifndef UNITY_EXCLUDE_FLOAT +typedef enum UNITY_FLOAT_TRAIT +{ + UNITY_FLOAT_IS_NOT_INF = 0, + UNITY_FLOAT_IS_INF, + UNITY_FLOAT_IS_NOT_NEG_INF, + UNITY_FLOAT_IS_NEG_INF, + UNITY_FLOAT_IS_NOT_NAN, + UNITY_FLOAT_IS_NAN, + UNITY_FLOAT_IS_NOT_DET, + UNITY_FLOAT_IS_DET, + UNITY_FLOAT_INVALID_TRAIT +} UNITY_FLOAT_TRAIT_T; +#endif + +typedef enum +{ + UNITY_ARRAY_TO_VAL = 0, + UNITY_ARRAY_TO_ARRAY, + UNITY_ARRAY_UNKNOWN +} UNITY_FLAGS_T; + +struct UNITY_STORAGE_T +{ + const char* TestFile; + const char* CurrentTestName; +#ifndef UNITY_EXCLUDE_DETAILS + const char* CurrentDetail1; + const char* CurrentDetail2; +#endif + UNITY_LINE_TYPE CurrentTestLineNumber; + UNITY_COUNTER_TYPE NumberOfTests; + UNITY_COUNTER_TYPE TestFailures; + UNITY_COUNTER_TYPE TestIgnores; + UNITY_COUNTER_TYPE CurrentTestFailed; + UNITY_COUNTER_TYPE CurrentTestIgnored; +#ifdef UNITY_INCLUDE_EXEC_TIME + UNITY_TIME_TYPE CurrentTestStartTime; + UNITY_TIME_TYPE CurrentTestStopTime; +#endif +#ifndef UNITY_EXCLUDE_SETJMP_H + jmp_buf AbortFrame; +#endif +}; + +extern struct UNITY_STORAGE_T Unity; + +/*------------------------------------------------------- + * Test Suite Management + *-------------------------------------------------------*/ + +void UnityBegin(const char* filename); +int UnityEnd(void); +void UnitySetTestFile(const char* filename); +void UnityConcludeTest(void); +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); + +/*------------------------------------------------------- + * Details Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_DETAILS +#define UNITY_CLR_DETAILS() +#define UNITY_SET_DETAIL(d1) +#define UNITY_SET_DETAILS(d1,d2) +#else +#define UNITY_CLR_DETAILS() { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } +#define UNITY_SET_DETAIL(d1) { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = 0; } +#define UNITY_SET_DETAILS(d1,d2) { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = (d2); } + +#ifndef UNITY_DETAIL1_NAME +#define UNITY_DETAIL1_NAME "Function" +#endif + +#ifndef UNITY_DETAIL2_NAME +#define UNITY_DETAIL2_NAME "Argument" +#endif +#endif + +/*------------------------------------------------------- + * Test Output + *-------------------------------------------------------*/ + +void UnityPrint(const char* string); + +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +void UnityPrintFormatted(const char* format, ...); +#endif + +void UnityPrintLen(const char* string, const UNITY_UINT32 length); +void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number); +void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style); +void UnityPrintNumber(const UNITY_INT number_to_print); +void UnityPrintNumberUnsigned(const UNITY_UINT number); +void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print); + +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +void UnityPrintFloat(const UNITY_DOUBLE input_number); +#endif + +/*------------------------------------------------------- + * Test Assertion Functions + *------------------------------------------------------- + * Use the macros below this section instead of calling + * these directly. The macros have a consistent naming + * convention and will pull in file and line information + * for you. */ + +void UnityAssertEqualNumber(const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, + const UNITY_INT actual, + const UNITY_COMPARISON_T compare, + const char *msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags); + +void UnityAssertBits(const UNITY_INT mask, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const UNITY_UINT32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringArray( UNITY_INTERNAL_PTR expected, + const char** actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 length, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertNumbersWithin(const UNITY_UINT delta, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, + UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags); + +void UnityFail(const char* message, const UNITY_LINE_TYPE line); +void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); +void UnityMessage(const char* message, const UNITY_LINE_TYPE line); + +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertFloatsWithin(const UNITY_FLOAT delta, + const UNITY_FLOAT expected, + const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertFloatSpecial(const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, + const UNITY_DOUBLE expected, + const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +/*------------------------------------------------------- + * Helpers + *-------------------------------------------------------*/ + +UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size); +#ifndef UNITY_EXCLUDE_FLOAT +UNITY_INTERNAL_PTR UnityFloatToPtr(const float num); +#endif +#ifndef UNITY_EXCLUDE_DOUBLE +UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num); +#endif + +/*------------------------------------------------------- + * Error Strings We Might Need + *-------------------------------------------------------*/ + +extern const char UnityStrOk[]; +extern const char UnityStrPass[]; +extern const char UnityStrFail[]; +extern const char UnityStrIgnore[]; + +extern const char UnityStrErrFloat[]; +extern const char UnityStrErrDouble[]; +extern const char UnityStrErr64[]; +extern const char UnityStrErrShorthand[]; + +/*------------------------------------------------------- + * Test Running Macros + *-------------------------------------------------------*/ + +#ifndef UNITY_EXCLUDE_SETJMP_H +#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0) +#define TEST_ABORT() longjmp(Unity.AbortFrame, 1) +#else +#define TEST_PROTECT() 1 +#define TEST_ABORT() return +#endif + +/* This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) */ +#ifndef RUN_TEST +#ifdef __STDC_VERSION__ +#if __STDC_VERSION__ >= 199901L +#define UNITY_SUPPORT_VARIADIC_MACROS +#endif +#endif +#ifdef UNITY_SUPPORT_VARIADIC_MACROS +#define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) +#define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) +#define RUN_TEST_FIRST_HELPER(first, ...) (first), #first +#define RUN_TEST_SECOND(...) RUN_TEST_SECOND_HELPER(__VA_ARGS__, __LINE__, throwaway) +#define RUN_TEST_SECOND_HELPER(first, second, ...) (second) +#endif +#endif + +/* If we can't do the tricky version, we'll just have to require them to always include the line number */ +#ifndef RUN_TEST +#ifdef CMOCK +#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) +#else +#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) +#endif +#endif + +#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) +#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) +#define UNITY_NEW_TEST(a) \ + Unity.CurrentTestName = (a); \ + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ + Unity.NumberOfTests++; + +#ifndef UNITY_BEGIN +#define UNITY_BEGIN() UnityBegin(__FILE__) +#endif + +#ifndef UNITY_END +#define UNITY_END() UnityEnd() +#endif + +#ifndef UNITY_SHORTHAND_AS_INT +#ifndef UNITY_SHORTHAND_AS_MEM +#ifndef UNITY_SHORTHAND_AS_NONE +#ifndef UNITY_SHORTHAND_AS_RAW +#define UNITY_SHORTHAND_AS_OLD +#endif +#endif +#endif +#endif + +/*----------------------------------------------- + * Command Line Argument Support + *-----------------------------------------------*/ + +#ifdef UNITY_USE_COMMAND_LINE_ARGS +int UnityParseOptions(int argc, char** argv); +int UnityTestMatches(void); +#endif + +/*------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)(line)) + +/*------------------------------------------------------- + * Test Asserts + *-------------------------------------------------------*/ + +#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), (message));} +#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)(line), (message)) + +#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_EQUAL_CHAR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) +#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((UNITY_INT)(mask), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line)) + +#define UNITY_TEST_ASSERT_GREATER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 ) (threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16) (threshold), (UNITY_INT)(UNITY_INT16) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32) (threshold), (UNITY_INT)(UNITY_INT32) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 ) (threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin( (delta), (UNITY_INT) (expected), (UNITY_INT) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 ) (expected), (UNITY_INT)(UNITY_INT8 ) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_INT16) (expected), (UNITY_INT)(UNITY_INT16) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_INT32) (expected), (UNITY_INT)(UNITY_INT32) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin( (delta), (UNITY_INT) (expected), (UNITY_INT) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_CHAR_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 ) (expected), (UNITY_INT)(UNITY_INT8 ) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin( (delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin( (delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin( (UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_ARRAY) + + +#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_PTR_TO_INT)(expected), (UNITY_PTR_TO_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) +#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (UNITY_UINT32)(len), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), 1, (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) + +#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_ARRAY) + +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), (UNITY_INT_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), (UNITY_INT_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT16)(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT32)(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_PTR_TO_INT) (expected), (UNITY_POINTER_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_VAL) + +#ifdef UNITY_SUPPORT_64 +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY) +#else +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#endif + +#ifdef UNITY_EXCLUDE_FLOAT +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#else +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((UNITY_FLOAT)(delta), (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((UNITY_FLOAT)(expected) * (UNITY_FLOAT)UNITY_FLOAT_PRECISION, (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((UNITY_FLOAT*)(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray(UnityFloatToPtr(expected), (UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +#ifdef UNITY_EXCLUDE_DOUBLE +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#else +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((UNITY_DOUBLE*)(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray(UnityDoubleToPtr(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +/* End of UNITY_INTERNALS_H */ +#endif diff --git a/circuitpython/lib/tinyusb/tools/build_board.py b/circuitpython/lib/tinyusb/tools/build_board.py new file mode 100644 index 0000000..b2a80c6 --- /dev/null +++ b/circuitpython/lib/tinyusb/tools/build_board.py @@ -0,0 +1,100 @@ +import os +import glob +import sys +import subprocess +import time + +import build_utils + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" +SKIPPED = "\033[33mskipped\033[0m" + +success_count = 0 +fail_count = 0 +skip_count = 0 +exit_status = 0 + +total_time = time.monotonic() + +build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' +build_separator = '-' * 106 + +def filter_with_input(mylist): + if len(sys.argv) > 1: + input_args = list(set(mylist).intersection(sys.argv)) + if len(input_args) > 0: + mylist[:] = input_args + +# If examples are not specified in arguments, build all +all_examples = [] +for entry in os.scandir("examples/device"): + if entry.is_dir(): + all_examples.append("device/" + entry.name) +for entry in os.scandir("examples/host"): + if entry.is_dir(): + all_examples.append("host/" + entry.name) +filter_with_input(all_examples) +all_examples.sort() + +# If boards are not specified in arguments, build all +all_boards = [] +for entry in os.scandir("hw/bsp"): + if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): + all_boards.append(entry.name) +filter_with_input(all_boards) +all_boards.sort() + +def build_board(example, board): + global success_count, fail_count, skip_count, exit_status + start_time = time.monotonic() + flash_size = "-" + sram_size = "-" + + # Check if board is skipped + if build_utils.skip_example(example, board): + success = SKIPPED + skip_count += 1 + print(build_format.format(example, board, success, '-', flash_size, sram_size)) + else: + subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + if build_result.returncode == 0: + success = SUCCEEDED + success_count += 1 + (flash_size, sram_size) = build_size(example, board) + else: + exit_status = build_result.returncode + success = FAILED + fail_count += 1 + + build_duration = time.monotonic() - start_time + print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) + + if build_result.returncode != 0: + print(build_result.stdout.decode("utf-8")) + +def build_size(example, board): + #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) + elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) + size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + size_list = size_output.split('\n')[1].split('\t') + flash_size = int(size_list[0]) + sram_size = int(size_list[1]) + int(size_list[2]) + return (flash_size, sram_size) + +print(build_separator) +print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + +for example in all_examples: + print(build_separator) + for board in all_boards: + build_board(example, board) + +total_time = time.monotonic() - total_time +print(build_separator) +print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) +print(build_separator) + +sys.exit(exit_status) diff --git a/circuitpython/lib/tinyusb/tools/build_esp32sx.py b/circuitpython/lib/tinyusb/tools/build_esp32sx.py new file mode 100644 index 0000000..2947a0a --- /dev/null +++ b/circuitpython/lib/tinyusb/tools/build_esp32sx.py @@ -0,0 +1,101 @@ +import os +import glob +import sys +import subprocess +import time + +import build_utils + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" +SKIPPED = "\033[33mskipped\033[0m" + +success_count = 0 +fail_count = 0 +skip_count = 0 +exit_status = 0 + +total_time = time.monotonic() + +build_format = '| {:23} | {:30} | {:18} | {:7} | {:6} | {:6} |' +build_separator = '-' * 100 + +def filter_with_input(mylist): + if len(sys.argv) > 1: + input_args = list(set(mylist).intersection(sys.argv)) + if len(input_args) > 0: + mylist[:] = input_args + +# Build all examples if not specified +all_examples = [] +for entry in os.scandir("examples/device"): + # Only includes example with CMakeLists.txt for esp32s, and skip board_test to speed up ci + if entry.is_dir() and os.path.exists(entry.path + "/sdkconfig.defaults") and entry.name != 'board_test': + all_examples.append(entry.name) +filter_with_input(all_examples) +all_examples.sort() + +# Build all boards if not specified +all_boards = [] +for entry in os.scandir("hw/bsp/esp32s2/boards"): + if entry.is_dir(): + all_boards.append(entry.name) +for entry in os.scandir("hw/bsp/esp32s3/boards"): + if entry.is_dir(): + all_boards.append(entry.name) +filter_with_input(all_boards) +all_boards.sort() + +def build_board(example, board): + global success_count, fail_count, skip_count, exit_status + start_time = time.monotonic() + flash_size = "-" + sram_size = "-" + + # Check if board is skipped + if build_utils.skip_example(example, board): + success = SKIPPED + skip_count += 1 + print(build_format.format(example, board, success, '-', flash_size, sram_size)) + else: + subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + build_result = subprocess.run("make -j -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + if build_result.returncode == 0: + success = SUCCEEDED + success_count += 1 + (flash_size, sram_size) = build_size(example, board) + else: + exit_status = build_result.returncode + success = FAILED + fail_count += 1 + + build_duration = time.monotonic() - start_time + print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) + + if build_result.returncode != 0: + print(build_result.stdout.decode("utf-8")) + +def build_size(example, board): + #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) + elf_file = 'examples/device/{}/_build/{}/*.elf'.format(example, board) + size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + size_list = size_output.split('\n')[1].split('\t') + flash_size = int(size_list[0]) + sram_size = int(size_list[1]) + int(size_list[2]) + return (flash_size, sram_size) + +print(build_separator) +print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) +print(build_separator) + +for example in all_examples: + for board in all_boards: + build_board(example, board) + +total_time = time.monotonic() - total_time +print(build_separator) +print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) +print(build_separator) + +sys.exit(exit_status) diff --git a/circuitpython/lib/tinyusb/tools/build_family.py b/circuitpython/lib/tinyusb/tools/build_family.py new file mode 100644 index 0000000..4094d07 --- /dev/null +++ b/circuitpython/lib/tinyusb/tools/build_family.py @@ -0,0 +1,113 @@ +import os +import glob +import sys +import subprocess +import time + +import build_utils + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" +SKIPPED = "\033[33mskipped\033[0m" + +success_count = 0 +fail_count = 0 +skip_count = 0 +exit_status = 0 + +total_time = time.monotonic() + +build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' +build_separator = '-' * 106 + +def filter_with_input(mylist): + if len(sys.argv) > 1: + input_args = list(set(mylist).intersection(sys.argv)) + if len(input_args) > 0: + mylist[:] = input_args + +# If examples are not specified in arguments, build all +all_examples = [] +for entry in os.scandir("examples/device"): + if entry.is_dir(): + all_examples.append("device/" + entry.name) +for entry in os.scandir("examples/host"): + if entry.is_dir(): + all_examples.append("host/" + entry.name) +filter_with_input(all_examples) +all_examples.sort() + +# If family are not specified in arguments, build all +all_families = [] +for entry in os.scandir("hw/bsp"): + if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name not in ("esp32s2", "esp32s3"): + all_families.append(entry.name) + +filter_with_input(all_families) +all_families.sort() + +def build_family(example, family): + all_boards = [] + for entry in os.scandir("hw/bsp/{}/boards".format(family)): + if entry.is_dir(): + all_boards.append(entry.name) + filter_with_input(all_boards) + all_boards.sort() + + for board in all_boards: + build_board(example, board) + +def build_board(example, board): + global success_count, fail_count, skip_count, exit_status + start_time = time.monotonic() + flash_size = "-" + sram_size = "-" + + # Check if board is skipped + if build_utils.skip_example(example, board): + success = SKIPPED + skip_count += 1 + print(build_format.format(example, board, success, '-', flash_size, sram_size)) + else: + #subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + if build_result.returncode == 0: + success = SUCCEEDED + success_count += 1 + (flash_size, sram_size) = build_size(example, board) + subprocess.run("make -j -C examples/{} BOARD={} copy-artifact".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + else: + exit_status = build_result.returncode + success = FAILED + fail_count += 1 + + build_duration = time.monotonic() - start_time + print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) + + if build_result.returncode != 0: + print(build_result.stdout.decode("utf-8")) + +def build_size(example, board): + #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) + elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) + size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + size_list = size_output.split('\n')[1].split('\t') + flash_size = int(size_list[0]) + sram_size = int(size_list[1]) + int(size_list[2]) + return (flash_size, sram_size) + +print(build_separator) +print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + +for example in all_examples: + print(build_separator) + for family in all_families: + build_family(example, family) + +total_time = time.monotonic() - total_time +print(build_separator) +print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) +print(build_separator) + +sys.exit(exit_status) diff --git a/circuitpython/lib/tinyusb/tools/build_utils.py b/circuitpython/lib/tinyusb/tools/build_utils.py new file mode 100644 index 0000000..299fffa --- /dev/null +++ b/circuitpython/lib/tinyusb/tools/build_utils.py @@ -0,0 +1,61 @@ +import pathlib + +def skip_example(example, board): + ex_dir = pathlib.Path('examples/') / example + bsp = pathlib.Path("hw/bsp") + + board_dir = list(bsp.glob("*/boards/" + board)) + if not board_dir: + # Skip unknown boards + return True + + board_dir = list(board_dir)[0] + + family_dir = board_dir.parent.parent + family = family_dir.name + + # family CMake + family_mk = family_dir / "family.cmake" + + # family.mk + if not family_mk.exists(): + family_mk = family_dir / "family.mk" + + mk_contents = family_mk.read_text() + + # Find the mcu + if "CFG_TUSB_MCU=OPT_MCU_" not in mk_contents: + board_mk = board_dir / "board.cmake" + if not board_mk.exists(): + board_mk = board_dir / "board.mk" + + mk_contents = board_mk.read_text() + + for token in mk_contents.split(): + if "CFG_TUSB_MCU=OPT_MCU_" in token: + # Strip " because cmake files has them. + token = token.strip("\"") + _, opt_mcu = token.split("=") + mcu = opt_mcu[len("OPT_MCU_"):] + + # Skip all OPT_MCU_NONE these are WIP port + if mcu == "NONE": + return True + + skip_file = ex_dir / "skip.txt" + only_file = ex_dir / "only.txt" + + if skip_file.exists() and only_file.exists(): + raise RuntimeError("Only have a skip or only file. Not both.") + elif skip_file.exists(): + skips = skip_file.read_text().split() + return ("mcu:" + mcu in skips or + "board:" + board in skips or + "family:" + family in skips) + elif only_file.exists(): + onlys = only_file.read_text().split() + return not ("mcu:" + mcu in onlys or + "board:" + board in onlys or + "family:" + family in onlys) + + return False diff --git a/circuitpython/lib/tinyusb/tools/iar_gen.py b/circuitpython/lib/tinyusb/tools/iar_gen.py new file mode 100644 index 0000000..73c8b29 --- /dev/null +++ b/circuitpython/lib/tinyusb/tools/iar_gen.py @@ -0,0 +1,51 @@ +#!/usr/bin/python3 + +import os +import xml.dom.minidom as XML + +# Read base configuration +base = "" +with open("iar_template.ipcf") as f: + base = f.read() + +# Enumerate all device/host examples +dir_1 = os.listdir("../examples") +for dir_2 in dir_1: + if os.path.isdir("../examples/{}".format(dir_2)): + print(dir_2) + examples = os.listdir("../examples/{}".format(dir_2)) + for example in examples: + if os.path.isdir("../examples/{}/{}".format(dir_2, example)): + print("../examples/{}/{}".format(dir_2, example)) + conf = XML.parseString(base) + files = conf.getElementsByTagName("files")[0] + inc = conf.getElementsByTagName("includePath")[0] + # Add bsp inc + path = conf.createElement('path') + path_txt = conf.createTextNode("$TUSB_DIR$/hw") + path.appendChild(path_txt) + inc.appendChild(path) + # Add board.c/.h + grp = conf.createElement('group') + grp.setAttribute("name", "bsp") + path = conf.createElement('path') + path_txt = conf.createTextNode("$TUSB_DIR$/hw/bsp/board.c") + path.appendChild(path_txt) + grp.appendChild(path) + files.appendChild(grp) + # Add example's .c/.h + grp = conf.createElement('group') + grp.setAttribute("name", "example") + for file in os.listdir("../examples/{}/{}/src".format(dir_2, example)): + if file.endswith(".c") or file.endswith(".h"): + path = conf.createElement('path') + path.setAttribute("copyTo", "$PROJ_DIR$/{}".format(file)) + path_txt = conf.createTextNode("$TUSB_DIR$/examples/{0}/{1}/src/{2}".format(dir_2, example, file)) + path.appendChild(path_txt) + grp.appendChild(path) + files.appendChild(grp) + cfg_str = conf.toprettyxml() + cfg_str = '\n'.join([s for s in cfg_str.splitlines() if s.strip()]) + #print(cfg_str) + with open("../examples/{0}/{1}/iar_{1}.ipcf".format(dir_2, example), 'w') as f: + f.write(cfg_str) diff --git a/circuitpython/lib/tinyusb/tools/iar_template.ipcf b/circuitpython/lib/tinyusb/tools/iar_template.ipcf new file mode 100644 index 0000000..ba54fe0 --- /dev/null +++ b/circuitpython/lib/tinyusb/tools/iar_template.ipcf @@ -0,0 +1,145 @@ + + + + + $TUSB_DIR$/src + $TUSB_DIR$/lib/SEGGER_RTT/RTT + $PROJ_DIR$ + + + + $TUSB_DIR$/src/device/usbd.c + $TUSB_DIR$/src/device/usbd_control.c + + + $TUSB_DIR$/src/common/tusb_fifo.c + + + $TUSB_DIR$/src/class/audio/audio_device.c + + + $TUSB_DIR$/src/class/bth/bth_device.c + + + $TUSB_DIR$/src/class/cdc/cdc_device.c + $TUSB_DIR$/src/class/cdc/cdc_host.c + $TUSB_DIR$/src/class/cdc/cdc_rndis_host.c + + + $TUSB_DIR$/src/class/dfu/dfu_device.c + $TUSB_DIR$/src/class/dfu/dfu_rt_device.c + + + $TUSB_DIR$/src/class/hid/hid_device.c + $TUSB_DIR$/src/class/hid/hid_host.c + + + $TUSB_DIR$/src/class/midi/midi_device.c + + + $TUSB_DIR$/src/class/msc/msc_device.c + $TUSB_DIR$/src/class/msc/msc_host.c + + + $TUSB_DIR$/src/class/net/ecm_rndis_device.c + $TUSB_DIR$/src/class/net/ncm_device.c + + + $TUSB_DIR$/src/class/usbtmc/usbtmc_device.c + + + $TUSB_DIR$/src/class/vendor/vendor_device.c + $TUSB_DIR$/src/class/vendor/vendor_host.c + + + $TUSB_DIR$/src/tusb.c + + + $TUSB_DIR$/src/host/hub.c + $TUSB_DIR$/src/host/usbh.c + $TUSB_DIR$/src/host/usbh_control.c + + + $TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c + + + $TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c + + + $TUSB_DIR$/src/portable/ehci/ehci.c + + + $TUSB_DIR$/src/portable/espressif/esp32sx/dcd_esp32sx.c + + + $TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c + + + $TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c + + + $TUSB_DIR$/src/portable/microchip/samg/dcd_samg.c + + + $TUSB_DIR$/src/portable/microchip/samx7x/dcd_samx7x.c + + + $TUSB_DIR$/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c + + + $TUSB_DIR$/src/portable/nordic/nrf5x/dcd_nrf5x.c + + + $TUSB_DIR$/src/portable/nuvoton/nuc120/dcd_nuc120.c + + + $TUSB_DIR$/src/portable/nuvoton/nuc121/dcd_nuc121.c + + + $TUSB_DIR$/src/portable/nuvoton/nuc505/dcd_nuc505.c + + + $TUSB_DIR$/src/portable/nxp/khci/dcd_khci.c + + + $TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.c + $TUSB_DIR$/src/portable/nxp/lpc17_40/hcd_lpc17_40.c + + + $TUSB_DIR$/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c + + + $TUSB_DIR$/src/portable/nxp/transdimension/dcd_transdimension.c + $TUSB_DIR$/src/portable/nxp/transdimension/hcd_transdimension.c + + + $TUSB_DIR$/src/portable/ohci/ohci.c + + + $TUSB_DIR$/src/portable/raspberrypi/rp2040/dcd_rp2040.c + $TUSB_DIR$/src/portable/raspberrypi/rp2040/hcd_rp2040.c + $TUSB_DIR$/src/portable/raspberrypi/rp2040/rp2040_usb.c + + + $TUSB_DIR$/src/portable/renesas/usba/dcd_usba.c + + + $TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c + + + $TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + + + $TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c + + + $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.c + + + $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.c + $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c + $TUSB_DIR$/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c + + + + diff --git a/circuitpython/lib/tinyusb/tools/mksunxi.py b/circuitpython/lib/tinyusb/tools/mksunxi.py new file mode 100644 index 0000000..04786f4 --- /dev/null +++ b/circuitpython/lib/tinyusb/tools/mksunxi.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +import sys +import struct + +def align(num, alignment): + if num % alignment != 0: + num += (alignment - num % alignment) + return num + + +def process_file(input, output): + with open(input, 'rb') as fin: + content = bytearray(fin.read()) + + align_value = 512 + padded_length = align(len(content), align_value) + # pad file to actual length + content += b'\x00' * (padded_length - len(content)) + + struct_format = '> 16; + + 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; +} diff --git a/circuitpython/lib/uzlib/crc32.c b/circuitpython/lib/uzlib/crc32.c new file mode 100644 index 0000000..e24c643 --- /dev/null +++ b/circuitpython/lib/uzlib/crc32.c @@ -0,0 +1,63 @@ +/* + * CRC32 checksum + * + * Copyright (c) 1998-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. + */ + +/* + * CRC32 algorithm taken from the zlib source, which is + * Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + */ + +#include "tinf.h" + +static const unsigned int tinf_crc32tab[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, + 0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, + 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, + 0xbdbdf21c +}; + +/* crc is previous value for incremental computation, 0xffffffff initially */ +uint32_t uzlib_crc32(const void *data, unsigned int length, uint32_t crc) +{ + const unsigned char *buf = (const unsigned char *)data; + unsigned int i; + + for (i = 0; i < length; ++i) + { + crc ^= buf[i]; + crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4); + crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4); + } + + // return value suitable for passing in next time, for final value invert it + return crc/* ^ 0xffffffff*/; +} diff --git a/circuitpython/lib/uzlib/defl_static.h b/circuitpython/lib/uzlib/defl_static.h new file mode 100644 index 0000000..292734d --- /dev/null +++ b/circuitpython/lib/uzlib/defl_static.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) uzlib authors + * + * 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. + */ + +/* This files contains type declaration and prototypes for defl_static.c. + They may be altered/distinct from the originals used in PuTTY source + code. */ + +struct Outbuf { + unsigned char *outbuf; + int outlen, outsize; + unsigned long outbits; + int noutbits; + int comp_disabled; +}; + +void outbits(struct Outbuf *out, unsigned long bits, int nbits); +void zlib_start_block(struct Outbuf *ctx); +void zlib_finish_block(struct Outbuf *ctx); +void zlib_literal(struct Outbuf *ectx, unsigned char c); +void zlib_match(struct Outbuf *ectx, int distance, int len); diff --git a/circuitpython/lib/uzlib/tinf.h b/circuitpython/lib/uzlib/tinf.h new file mode 100644 index 0000000..ae6e1c4 --- /dev/null +++ b/circuitpython/lib/uzlib/tinf.h @@ -0,0 +1,3 @@ +/* Compatibility header for the original tinf lib/older versions of uzlib. + Note: may be removed in the future, please migrate to uzlib.h. */ +#include "uzlib.h" diff --git a/circuitpython/lib/uzlib/tinf_compat.h b/circuitpython/lib/uzlib/tinf_compat.h new file mode 100644 index 0000000..f763804 --- /dev/null +++ b/circuitpython/lib/uzlib/tinf_compat.h @@ -0,0 +1,9 @@ +/* This header contains compatibility defines for the original tinf API + and uzlib 2.x and below API. These defines are deprecated and going + to be removed in the future, so applications should migrate to new + uzlib API. */ +#define TINF_DATA struct uzlib_uncomp + +#define destSize dest_size +#define destStart dest_start +#define readSource source_read_cb diff --git a/circuitpython/lib/uzlib/tinfgzip.c b/circuitpython/lib/uzlib/tinfgzip.c new file mode 100644 index 0000000..22b000d --- /dev/null +++ b/circuitpython/lib/uzlib/tinfgzip.c @@ -0,0 +1,110 @@ +/* + * 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-2018 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" + +#define FTEXT 1 +#define FHCRC 2 +#define FEXTRA 4 +#define FNAME 8 +#define FCOMMENT 16 + +void tinf_skip_bytes(TINF_DATA *d, int num); +uint16_t tinf_get_uint16(TINF_DATA *d); + +void tinf_skip_bytes(TINF_DATA *d, int num) +{ + while (num--) uzlib_get_byte(d); +} + +uint16_t tinf_get_uint16(TINF_DATA *d) +{ + unsigned int v = uzlib_get_byte(d); + v = (uzlib_get_byte(d) << 8) | v; + return v; +} + +int uzlib_gzip_parse_header(TINF_DATA *d) +{ + unsigned char flg; + + /* -- check format -- */ + + /* check id bytes */ + if (uzlib_get_byte(d) != 0x1f || uzlib_get_byte(d) != 0x8b) return TINF_DATA_ERROR; + + /* check method is deflate */ + if (uzlib_get_byte(d) != 8) return TINF_DATA_ERROR; + + /* get flag byte */ + flg = uzlib_get_byte(d); + + /* check that reserved bits are zero */ + if (flg & 0xe0) return TINF_DATA_ERROR; + + /* -- find start of compressed data -- */ + + /* skip rest of base header of 10 bytes */ + tinf_skip_bytes(d, 6); + + /* skip extra data if present */ + if (flg & FEXTRA) + { + unsigned int xlen = tinf_get_uint16(d); + tinf_skip_bytes(d, xlen); + } + + /* skip file name if present */ + if (flg & FNAME) { while (uzlib_get_byte(d)); } + + /* skip file comment if present */ + if (flg & FCOMMENT) { while (uzlib_get_byte(d)); } + + /* check header crc if present */ + if (flg & FHCRC) + { + /*unsigned int hcrc =*/ tinf_get_uint16(d); + + // TODO: Check! +// if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff)) +// return TINF_DATA_ERROR; + } + + /* initialize for crc32 checksum */ + d->checksum_type = TINF_CHKSUM_CRC; + d->checksum = ~0; + + return TINF_OK; +} diff --git a/circuitpython/lib/uzlib/tinflate.c b/circuitpython/lib/uzlib/tinflate.c new file mode 100644 index 0000000..045952c --- /dev/null +++ b/circuitpython/lib/uzlib/tinflate.c @@ -0,0 +1,659 @@ +/* + * 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-2018 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 +#include "tinf.h" + +#define UZLIB_DUMP_ARRAY(heading, arr, size) \ + { \ + printf("%s", heading); \ + for (int i = 0; i < size; ++i) { \ + printf(" %d", (arr)[i]); \ + } \ + printf("\n"); \ + } + +uint32_t tinf_get_le_uint32(TINF_DATA *d); +uint32_t tinf_get_be_uint32(TINF_DATA *d); + +/* --------------------------------------------------- * + * -- 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 -- * + * ----------------------- */ + +#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]]++; + + #if UZLIB_CONF_DEBUG_LOG >= 2 + UZLIB_DUMP_ARRAY("codelen counts:", t->table, TINF_ARRAY_SIZE(t->table)); + #endif + + /* In the lengths array, 0 means unused code. So, t->table[0] now contains + number of unused codes. But table's purpose is to contain # of codes of + particular length, and there're 0 codes of length 0. */ + 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]; + } + + #if UZLIB_CONF_DEBUG_LOG >= 2 + UZLIB_DUMP_ARRAY("codelen offsets:", offs, TINF_ARRAY_SIZE(offs)); + #endif + + /* 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 -- * + * ---------------------- */ + +unsigned char uzlib_get_byte(TINF_DATA *d) +{ + /* If end of source buffer is not reached, return next byte from source + buffer. */ + if (d->source < d->source_limit) { + return *d->source++; + } + + /* Otherwise if there's callback and we haven't seen EOF yet, try to + read next byte using it. (Note: the callback can also update ->source + and ->source_limit). */ + if (d->readSource && !d->eof) { + int val = d->readSource(d); + if (val >= 0) { + return (unsigned char)val; + } + } + + /* Otherwise, we hit EOF (either from ->readSource() or from exhaustion + of the buffer), and it will be "sticky", i.e. further calls to this + function will end up here too. */ + d->eof = true; + + return 0; +} + +uint32_t tinf_get_le_uint32(TINF_DATA *d) +{ + uint32_t val = 0; + int i; + for (i = 4; i--;) { + val = val >> 8 | ((uint32_t)uzlib_get_byte(d)) << 24; + } + return val; +} + +uint32_t tinf_get_be_uint32(TINF_DATA *d) +{ + uint32_t val = 0; + int i; + for (i = 4; i--;) { + val = val << 8 | uzlib_get_byte(d); + } + return val; +} + +/* 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 = uzlib_get_byte(d); + 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); + + if (++len == TINF_ARRAY_SIZE(t->table)) { + return TINF_DATA_ERROR; + } + + sum += t->table[len]; + cur -= t->table[len]; + + } while (cur >= 0); + + sum += cur; + #if UZLIB_CONF_PARANOID_CHECKS + if (sum < 0 || sum >= TINF_ARRAY_SIZE(t->trans)) { + return TINF_DATA_ERROR; + } + #endif + + return t->trans[sum]; +} + +/* given a data stream, decode dynamic trees from it */ +static int tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt) +{ + /* code lengths for 288 literal/len symbols and 32 dist symbols */ + unsigned char lengths[288+32]; + unsigned int hlit, hdist, hclen, hlimit; + 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 */ + hlimit = hlit + hdist; + for (num = 0; num < hlimit; ) + { + int sym = tinf_decode_symbol(d, lt); + unsigned char fill_value = 0; + int lbits, lbase = 3; + + /* error decoding */ + if (sym < 0) return sym; + + switch (sym) + { + case 16: + /* copy previous code length 3-6 times (read 2 bits) */ + if (num == 0) return TINF_DATA_ERROR; + fill_value = lengths[num - 1]; + lbits = 2; + break; + case 17: + /* repeat code length 0 for 3-10 times (read 3 bits) */ + lbits = 3; + break; + case 18: + /* repeat code length 0 for 11-138 times (read 7 bits) */ + lbits = 7; + lbase = 11; + break; + default: + /* values 0-15 represent the actual code lengths */ + lengths[num++] = sym; + /* continue the for loop */ + continue; + } + + /* special code length 16-18 are handled here */ + length = tinf_read_bits(d, lbits, lbase); + if (num + length > hlimit) return TINF_DATA_ERROR; + for (; length; --length) + { + lengths[num++] = fill_value; + } + } + + #if UZLIB_CONF_DEBUG_LOG >= 2 + printf("lit code lengths (%d):", hlit); + UZLIB_DUMP_ARRAY("", lengths, hlit); + printf("dist code lengths (%d):", hdist); + UZLIB_DUMP_ARRAY("", lengths + hlit, hdist); + #endif + + #if UZLIB_CONF_PARANOID_CHECKS + /* Check that there's "end of block" symbol */ + if (lengths[256] == 0) { + return TINF_DATA_ERROR; + } + #endif + + /* build dynamic trees */ + tinf_build_tree(lt, lengths, hlit); + tinf_build_tree(dt, lengths + hlit, hdist); + + return TINF_OK; +} + +/* ----------------------------- * + * -- block inflate functions -- * + * ----------------------------- */ + +/* given a stream and two trees, inflate next byte of output */ +static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt) +{ + if (d->curlen == 0) { + unsigned int offs; + int dist; + int sym = tinf_decode_symbol(d, lt); + //printf("huff sym: %02x\n", sym); + + if (d->eof) { + return TINF_DATA_ERROR; + } + + /* literal byte */ + if (sym < 256) { + TINF_PUT(d, sym); + return TINF_OK; + } + + /* end of block */ + if (sym == 256) { + return TINF_DONE; + } + + /* substring from sliding dictionary */ + sym -= 257; + if (sym >= 29) { + return TINF_DATA_ERROR; + } + + /* possibly get more bits from length code */ + d->curlen = tinf_read_bits(d, length_bits[sym], length_base[sym]); + + dist = tinf_decode_symbol(d, dt); + if (dist >= 30) { + return TINF_DATA_ERROR; + } + + /* possibly get more bits from distance code */ + offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]); + + /* calculate and validate actual LZ offset to use */ + if (d->dict_ring) { + if (offs > d->dict_size) { + return TINF_DICT_ERROR; + } + /* Note: unlike full-dest-in-memory case below, we don't + try to catch offset which points to not yet filled + part of the dictionary here. Doing so would require + keeping another variable to track "filled in" size + of the dictionary. Appearance of such an offset cannot + lead to accessing memory outside of the dictionary + buffer, and clients which don't want to leak unrelated + information, should explicitly initialize dictionary + buffer passed to uzlib. */ + + d->lzOff = d->dict_idx - offs; + if (d->lzOff < 0) { + d->lzOff += d->dict_size; + } + } else { + /* catch trying to point before the start of dest buffer */ + if (offs > (unsigned int)(d->dest - d->destStart)) { + return TINF_DATA_ERROR; + } + d->lzOff = -offs; + } + } + + /* copy next byte from dict substring */ + if (d->dict_ring) { + TINF_PUT(d, d->dict_ring[d->lzOff]); + if ((unsigned)++d->lzOff == d->dict_size) { + d->lzOff = 0; + } + } else { + d->dest[0] = d->dest[d->lzOff]; + d->dest++; + } + d->curlen--; + return TINF_OK; +} + +/* inflate next byte from uncompressed block of data */ +static int tinf_inflate_uncompressed_block(TINF_DATA *d) +{ + if (d->curlen == 0) { + unsigned int length, invlength; + + /* get length */ + length = uzlib_get_byte(d); + length += 256 * uzlib_get_byte(d); + /* get one's complement of length */ + invlength = uzlib_get_byte(d); + invlength += 256 * uzlib_get_byte(d); + /* check length */ + if (length != (~invlength & 0x0000ffff)) return TINF_DATA_ERROR; + + /* increment length to properly return TINF_DONE below, without + producing data at the same time */ + d->curlen = length + 1; + + /* make sure we start next block on a byte boundary */ + d->bitcount = 0; + } + + if (--d->curlen == 0) { + return TINF_DONE; + } + + unsigned char c = uzlib_get_byte(d); + TINF_PUT(d, c); + return TINF_OK; +} + +/* ---------------------- * + * -- public functions -- * + * ---------------------- */ + +/* initialize global (static) data */ +void uzlib_init(void) +{ +#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 +} + +/* initialize decompression structure */ +void uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen) +{ + d->eof = 0; + d->bitcount = 0; + d->bfinal = 0; + d->btype = -1; + d->dict_size = dictLen; + d->dict_ring = dict; + d->dict_idx = 0; + d->curlen = 0; +} + +/* inflate next output bytes from compressed stream */ +int uzlib_uncompress(TINF_DATA *d) +{ + do { + int res; + + /* start a new block */ + if (d->btype == -1) { +next_blk: + /* read final block flag */ + d->bfinal = tinf_getbit(d); + /* read block type (2 bits) */ + d->btype = tinf_read_bits(d, 2, 0); + + #if UZLIB_CONF_DEBUG_LOG >= 1 + printf("Started new block: type=%d final=%d\n", d->btype, d->bfinal); + #endif + + if (d->btype == 1) { + /* build fixed huffman trees */ + tinf_build_fixed_trees(&d->ltree, &d->dtree); + } else if (d->btype == 2) { + /* decode trees from stream */ + res = tinf_decode_trees(d, &d->ltree, &d->dtree); + if (res != TINF_OK) { + return res; + } + } + } + + /* process current block */ + switch (d->btype) + { + case 0: + /* decompress uncompressed block */ + res = tinf_inflate_uncompressed_block(d); + break; + case 1: + case 2: + /* decompress block with fixed/dynamic huffman trees */ + /* trees were decoded previously, so it's the same routine for both */ + res = tinf_inflate_block_data(d, &d->ltree, &d->dtree); + break; + default: + return TINF_DATA_ERROR; + } + + if (res == TINF_DONE && !d->bfinal) { + /* the block has ended (without producing more data), but we + can't return without data, so start procesing next block */ + goto next_blk; + } + + if (res != TINF_OK) { + return res; + } + + } while (d->dest < d->dest_limit); + + return TINF_OK; +} + +/* inflate next output bytes from compressed stream, updating + checksum, and at the end of stream, verify it */ +int uzlib_uncompress_chksum(TINF_DATA *d) +{ + int res; + unsigned char *data = d->dest; + + res = uzlib_uncompress(d); + + if (res < 0) return res; + + switch (d->checksum_type) { + + case TINF_CHKSUM_ADLER: + d->checksum = uzlib_adler32(data, d->dest - data, d->checksum); + break; + + case TINF_CHKSUM_CRC: + d->checksum = uzlib_crc32(data, d->dest - data, d->checksum); + break; + } + + if (res == TINF_DONE) { + unsigned int val; + + switch (d->checksum_type) { + + case TINF_CHKSUM_ADLER: + val = tinf_get_be_uint32(d); + if (d->checksum != val) { + return TINF_CHKSUM_ERROR; + } + break; + + case TINF_CHKSUM_CRC: + val = tinf_get_le_uint32(d); + if (~d->checksum != val) { + return TINF_CHKSUM_ERROR; + } + // Uncompressed size. TODO: Check + val = tinf_get_le_uint32(d); + break; + } + } + + return res; +} diff --git a/circuitpython/lib/uzlib/tinfzlib.c b/circuitpython/lib/uzlib/tinfzlib.c new file mode 100644 index 0000000..5cb8852 --- /dev/null +++ b/circuitpython/lib/uzlib/tinfzlib.c @@ -0,0 +1,66 @@ +/* + * 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-2018 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" + +int uzlib_zlib_parse_header(TINF_DATA *d) +{ + unsigned char cmf, flg; + + /* -- get header bytes -- */ + + cmf = uzlib_get_byte(d); + flg = uzlib_get_byte(d); + + /* -- 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; + + /* initialize for adler32 checksum */ + d->checksum_type = TINF_CHKSUM_ADLER; + d->checksum = 1; + + return cmf >> 4; +} diff --git a/circuitpython/lib/uzlib/uzlib.h b/circuitpython/lib/uzlib/uzlib.h new file mode 100644 index 0000000..7d89495 --- /dev/null +++ b/circuitpython/lib/uzlib/uzlib.h @@ -0,0 +1,171 @@ +/* + * 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-2018 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. + */ + +#ifndef UZLIB_H_INCLUDED +#define UZLIB_H_INCLUDED + +#include +#include +#include + +#include "defl_static.h" + +#include "uzlib_conf.h" +#if UZLIB_CONF_DEBUG_LOG +#include +#endif + +/* calling convention */ +#ifndef TINFCC + #ifdef __WATCOMC__ + #define TINFCC __cdecl + #else + #define TINFCC + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* ok status, more data produced */ +#define TINF_OK 0 +/* end of compressed stream reached */ +#define TINF_DONE 1 +#define TINF_DATA_ERROR (-3) +#define TINF_CHKSUM_ERROR (-4) +#define TINF_DICT_ERROR (-5) + +/* checksum types */ +#define TINF_CHKSUM_NONE 0 +#define TINF_CHKSUM_ADLER 1 +#define TINF_CHKSUM_CRC 2 + +/* helper macros */ +#define TINF_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*(arr))) + +/* data structures */ + +typedef struct { + unsigned short table[16]; /* table of code length counts */ + unsigned short trans[288]; /* code -> symbol translation table */ +} TINF_TREE; + +struct uzlib_uncomp { + /* Point to the CircuitPython object that owns this decompression stream */ + void *self; + /* Pointer to the next byte in the input buffer */ + const unsigned char *source; + /* Pointer to the next byte past the input buffer (source_limit = source + len) */ + const unsigned char *source_limit; + /* If source_limit == NULL, or source >= source_limit, this function + will be used to read next byte from source stream. The function may + also return -1 in case of EOF (or irrecoverable error). Note that + besides returning the next byte, it may also update source and + source_limit fields, thus allowing for buffered operation. */ + int (*source_read_cb)(struct uzlib_uncomp *uncomp); + + unsigned int tag; + unsigned int bitcount; + + /* Destination (output) buffer start */ + unsigned char *dest_start; + /* Current pointer in dest buffer */ + unsigned char *dest; + /* Pointer past the end of the dest buffer, similar to source_limit */ + unsigned char *dest_limit; + + /* Accumulating checksum */ + unsigned int checksum; + char checksum_type; + bool eof; + + int btype; + int bfinal; + unsigned int curlen; + int lzOff; + unsigned char *dict_ring; + unsigned int dict_size; + unsigned int dict_idx; + + TINF_TREE ltree; /* dynamic length/symbol tree */ + TINF_TREE dtree; /* dynamic distance tree */ +}; + +#include "tinf_compat.h" + +#define TINF_PUT(d, c) \ + { \ + *d->dest++ = c; \ + if (d->dict_ring) { d->dict_ring[d->dict_idx++] = c; if (d->dict_idx == d->dict_size) d->dict_idx = 0; } \ + } + +unsigned char TINFCC uzlib_get_byte(TINF_DATA *d); + +/* Decompression API */ + +void TINFCC uzlib_init(void); +void TINFCC uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen); +int TINFCC uzlib_uncompress(TINF_DATA *d); +int TINFCC uzlib_uncompress_chksum(TINF_DATA *d); + +int TINFCC uzlib_zlib_parse_header(TINF_DATA *d); +int TINFCC uzlib_gzip_parse_header(TINF_DATA *d); + +/* Compression API */ + +typedef const uint8_t *uzlib_hash_entry_t; + +struct uzlib_comp { + struct Outbuf out; + + uzlib_hash_entry_t *hash_table; + unsigned int hash_bits; + unsigned int dict_size; +}; + +void TINFCC uzlib_compress(struct uzlib_comp *c, const uint8_t *src, unsigned slen); + +/* Checksum API */ + +/* prev_sum is previous value for incremental computation, 1 initially */ +uint32_t TINFCC uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum); +/* crc is previous value for incremental computation, 0xffffffff initially */ +uint32_t TINFCC uzlib_crc32(const void *data, unsigned int length, uint32_t crc); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UZLIB_H_INCLUDED */ diff --git a/circuitpython/lib/uzlib/uzlib_conf.h b/circuitpython/lib/uzlib/uzlib_conf.h new file mode 100644 index 0000000..d6c9407 --- /dev/null +++ b/circuitpython/lib/uzlib/uzlib_conf.h @@ -0,0 +1,22 @@ +/* + * uzlib - tiny deflate/inflate library (deflate, gzip, zlib) + * + * Copyright (c) 2014-2018 by Paul Sokolovsky + */ + +#ifndef UZLIB_CONF_H_INCLUDED +#define UZLIB_CONF_H_INCLUDED + +#ifndef UZLIB_CONF_DEBUG_LOG +/* Debug logging level 0, 1, 2, etc. */ +#define UZLIB_CONF_DEBUG_LOG 0 +#endif + +#ifndef UZLIB_CONF_PARANOID_CHECKS +/* Perform extra checks on the input stream, even if they aren't proven + to be strictly required (== lack of them wasn't proven to lead to + crashes). */ +#define UZLIB_CONF_PARANOID_CHECKS 0 +#endif + +#endif /* UZLIB_CONF_H_INCLUDED */ -- cgit v1.2.3